You can subscribe to this list here.
2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(48) |
Oct
(45) |
Nov
(1) |
Dec
(3) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2008 |
Jan
(5) |
Feb
(17) |
Mar
(41) |
Apr
(70) |
May
(29) |
Jun
(36) |
Jul
(36) |
Aug
(28) |
Sep
(3) |
Oct
(2) |
Nov
(1) |
Dec
|
2009 |
Jan
(5) |
Feb
(5) |
Mar
(16) |
Apr
(3) |
May
(2) |
Jun
(2) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2010 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
(1) |
Dec
|
2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(3) |
Sep
(1) |
Oct
(1) |
Nov
|
Dec
|
2012 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(2) |
Sep
|
Oct
|
Nov
|
Dec
|
2016 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Dilip S. <nmd...@gm...> - 2016-04-02 21:13:37
|
Sent from my mobile phone. Plz excuse the typos.m |
From: <sam...@us...> - 2011-09-13 02:23:30
|
Revision: 371 http://aceos.svn.sourceforge.net/aceos/?rev=371&view=rev Author: samueldotj Date: 2011-09-13 02:23:23 +0000 (Tue, 13 Sep 2011) Log Message: ----------- Added partial support for copy on write. Modified ELF load method to load and relocate image into current address space. Rather loading into different address space. The reason for this is loading into different process address space is hard. Currently this method compatible with load driver files however it breaks loading any applications which will be fixed once fork() is implemented correctly. Modified Paths: -------------- src/include/kernel/mm/pmem.h src/include/kernel/mm/virtual_page.h src/include/kernel/mm/vm.h src/include/kernel/pm/elf.h src/include/stdlib.h src/kernel/i386/bios.c src/kernel/i386/mm/pmem.c src/kernel/i386/processor.c src/kernel/iom/driver.c src/kernel/ipc/message_queue.c src/kernel/main.c src/kernel/mm/virtual_page.c src/kernel/mm/vm.c src/kernel/mm/vm_descriptor.c src/kernel/mm/vm_unit.c src/kernel/pm/elf.c src/kernel/pm/task.c src/kernel/pm/thread.c src/kernel/syscall/file.c Modified: src/include/kernel/mm/pmem.h =================================================================== --- src/include/kernel/mm/pmem.h 2011-08-31 09:03:50 UTC (rev 370) +++ src/include/kernel/mm/pmem.h 2011-09-13 02:23:23 UTC (rev 371) @@ -73,6 +73,8 @@ ERROR_CODE MapVirtualAddressRange(PHYSICAL_MAP_PTR pmap, UINT32 va, UINT32 size, UINT32 protection); +ERROR_CODE MarkPageForCOW(VIRTUAL_PAGE_PTR vp); + VA_STATUS GetVirtualRangeStatus(VADDR va, UINT32 size); VA_STATUS TranslatePaFromVa(VADDR va, VADDR * pa); Modified: src/include/kernel/mm/virtual_page.h =================================================================== --- src/include/kernel/mm/virtual_page.h 2011-08-31 09:03:50 UTC (rev 370) +++ src/include/kernel/mm/virtual_page.h 2011-09-13 02:23:23 UTC (rev 371) @@ -29,8 +29,10 @@ busy:1, /*! if set page is busy due to IO*/ error:1, /*! if set a page error occurred during last IO*/ reserved; +#ifdef DOIT_LATER union { +#endif /*the following structure is used when the page in FREE state*/ struct { @@ -38,13 +40,15 @@ AVL_TREE_D free_tree; /*! this is starting of a free physical range*/ UINT32 free_size; /*! size of the free range in page units*/ }; + /*the following structure is used when the page is in USE state*/ struct { LIST lru_list; /*! LRU List - active/inactive link*/ - + VA_MAP_PTR va_map_list; /*! list of VAs associated with this page*/ }; + /*the following structure is used when the page is controlled by ubc*/ struct { @@ -54,8 +58,10 @@ BYTE loaded:1, /*! set to 1 if the page is loaded from file*/ modified:1; /*! set to 1 if the page is modified after load*/ }ubc_info; +#if DOIT_LATER }; - +#endif + UINT16 copy_on_write; /*! No of processes sharing this page*/ UINT16 wire_count; /*! Total wire count*/ Modified: src/include/kernel/mm/vm.h =================================================================== --- src/include/kernel/mm/vm.h 2011-08-31 09:03:50 UTC (rev 370) +++ src/include/kernel/mm/vm.h 2011-09-13 02:23:23 UTC (rev 371) @@ -50,11 +50,11 @@ typedef enum { - VM_UNIT_TYPE_KERNEL=1, /*kernel mapping*/ - VM_UNIT_TYPE_ANONYMOUS, - VM_UNIT_TYPE_FILE_MAPPED, - VM_UNIT_TYPE_STACK, - VM_UNIT_TYPE_PTE + VM_UNIT_TYPE_KERNEL=1, /*kernel wired memory*/ + VM_UNIT_TYPE_ANONYMOUS, /*zero filled initially and backed by swap*/ + VM_UNIT_TYPE_FILE_MAPPED, /*loaded from file and backed by file*/ + VM_UNIT_TYPE_STACK, /*zero filled initially and backed by swap*/ + VM_UNIT_TYPE_PTE /*UNIT containing all pages of page tables itself*/ }VM_UNIT_TYPE; typedef enum @@ -130,14 +130,14 @@ VM_UNIT_TYPE type; /*! type - text, code, heap...*/ VM_UNIT_FLAG flag; /*! flag - shared, private....*/ - UINT32 size; /*! total size of this unit*/ + size_t size; /*! total size of this unit*/ SPIN_LOCK vtop_lock; /*! lock to protect array and page_count*/ VM_VTOP_PTR vtop_array; /*! pointer to the virtual page array*/ int page_count; /*! total pages in memory*/ VNODE_PTR vnode; /*! pointer to vnode, if this unit backed by a file/swap*/ - UINT32 offset; /*! offset in the file*/ + offset_t offset; /*! offset in the file*/ LIST units_in_vnode_list;/*! all the vmunits corresponds to a vm unit are linked through this list*/ }; @@ -210,20 +210,24 @@ void PrintVmDescriptors(VIRTUAL_MAP_PTR vmap); VM_UNIT_PTR CreateVmUnit(VM_UNIT_TYPE type, VM_UNIT_FLAG flag, UINT32 size); +VM_UNIT_PTR CopyVmUnit(VM_UNIT_PTR unit, VADDR start, VADDR end); void SetVmUnitPage(VM_UNIT_PTR unit, VIRTUAL_PAGE_PTR vp, UINT32 vtop_index); ERROR_CODE AllocateVirtualMemory(VIRTUAL_MAP_PTR vmap, VADDR * va_ptr, VADDR preferred_start, UINT32 size, UINT32 protection, UINT32 flags, VM_UNIT_PTR unit); -ERROR_CODE FreeVirtualMemory(VIRTUAL_MAP_PTR vmap, VADDR va, UINT32 size, UINT32 flags); +ERROR_CODE FreeVirtualMemory(VIRTUAL_MAP_PTR vmap, VADDR va, size_t size, UINT32 flags); ERROR_CODE MapViewOfFile(int file_id, VADDR * va, UINT32 protection, UINT32 file_offset, UINT32 size, UINT32 preferred_start, UINT32 flags); +ERROR_CODE ReadFileIntoAddressSpace(int file_id, offset_t offset, size_t size, VIRTUAL_MAP_PTR virtual_map, VADDR *preferred_va, size_t dest_size, UINT32 protection, UINT32 flags); -ERROR_CODE CopyVirtualAddressRange(VIRTUAL_MAP_PTR src_vmap, VADDR src_va, UINT32 src_size, VIRTUAL_MAP_PTR dest_vmap, VADDR *dest_preferred_va, UINT32 dest_size, UINT32 protection); +ERROR_CODE CopyVirtualAddressRange(VIRTUAL_MAP_PTR src_vmap, VADDR src_va, UINT32 src_size, VIRTUAL_MAP_PTR dest_vmap, VADDR *dest_preferred_va, UINT32 dest_size, UINT32 protection, UINT32 flags); VADDR MapPhysicalMemory(VIRTUAL_MAP_PTR vmap, UINT32 pa, UINT32 size, VADDR preferred_va, UINT32 protection); +void AddVmunitToVnodeList(VNODE_PTR vnode, VM_UNIT_PTR unit, offset_t offset); + ERROR_CODE CopyFromUserSpace(void * user_va, void * kernel_va, size_t length); ERROR_CODE CopyToUserSpace(void * user_va, void * kernel_va, size_t length); -VIRTUAL_MAP_PTR GetCurrentVirtualMap(); +inline VIRTUAL_MAP_PTR GetCurrentVirtualMap(); ERROR_CODE MemoryFaultHandler(UINT32 va, int is_user_mode, int access_type); int VirtualMapCacheConstructor(void * buffer); Modified: src/include/kernel/pm/elf.h =================================================================== --- src/include/kernel/pm/elf.h 2011-08-31 09:03:50 UTC (rev 370) +++ src/include/kernel/pm/elf.h 2011-09-13 02:23:23 UTC (rev 371) @@ -1554,7 +1554,7 @@ extern char * kernel_string_table; extern UINT32 kernel_string_table_size; -ERROR_CODE LoadElfImage(ELF_HEADER_PTR file_header, VIRTUAL_MAP_PTR virtual_map, char * start_symbol_name, VADDR * start_entry); +ERROR_CODE LoadElfImage(char *elf_file_path, char * start_symbol_name, VADDR * start_entry); char * FindKernelSymbolByAddress(VADDR address, int * offset); Modified: src/include/stdlib.h =================================================================== --- src/include/stdlib.h 2011-08-31 09:03:50 UTC (rev 370) +++ src/include/stdlib.h 2011-09-13 02:23:23 UTC (rev 371) @@ -10,6 +10,11 @@ #define _SIZE_T_DEFINED #endif +#ifndef _OFFSET_T_DEFINED + typedef unsigned int offset_t; + #define _SIZE_T_DEFINED +#endif + #ifndef NULL #define NULL 0 #endif Modified: src/kernel/i386/bios.c =================================================================== --- src/kernel/i386/bios.c 2011-08-31 09:03:50 UTC (rev 370) +++ src/kernel/i386/bios.c 2011-09-13 02:23:23 UTC (rev 371) @@ -45,7 +45,7 @@ program[0] = interrupt<<8 | 0xCD; program[1] = 0x13<<8 | 0xCD; - AllocateVirtualMemory( GetCurrentVirtualMap(), &va, 0, PAGE_SIZE, PROT_READ|PROT_WRITE, 0, NULL ); + AllocateVirtualMemory( GetCurrentVirtualMap(), &va, 0, PAGE_SIZE, PROT_READ|PROT_WRITE, VM_UNIT_FLAG_PRIVATE, NULL ); memmove( (void *)va,(void *) program, sizeof(program) ); task = CreateTask((char *)va, IMAGE_TYPE_BIN_PROGRAM, TASK_CREATION_FLAG_NO_THREAD, &entry_point, NULL, NULL); if ( task == NULL ) Modified: src/kernel/i386/mm/pmem.c =================================================================== --- src/kernel/i386/mm/pmem.c 2011-08-31 09:03:50 UTC (rev 370) +++ src/kernel/i386/mm/pmem.c 2011-09-13 02:23:23 UTC (rev 371) @@ -47,7 +47,7 @@ pmap->virtual_map = vmap; /*allocate page directory from kernel map*/ - if ( AllocateVirtualMemory(&kernel_map, (VADDR*) &pmap->page_directory, 0, PAGE_SIZE, PROT_READ|PROT_WRITE, 0, NULL) != ERROR_SUCCESS ) + if ( AllocateVirtualMemory(&kernel_map, (VADDR*) &pmap->page_directory, 0, PAGE_SIZE, PROT_READ|PROT_WRITE, VM_UNIT_FLAG_PRIVATE, NULL) != ERROR_SUCCESS ) { FreeBuffer( pmap, &physical_map_cache ); return NULL; @@ -136,7 +136,19 @@ /*if somebody else created this mapping return*/ if ( mapped_pte->page_pfn == pfn ) { - /*! \todo - handle protection change here*/ + if ( protection & PROT_WRITE ) + { + /*! \todo - an assert for write == 0 is requried here ?*/ + mapped_pte->write = 1; + + } + else + { + /*! \todo - an assert for write == 1 is requried here ?*/ + mapped_pte->write = 0; + } + + asm volatile("invlpg (%%eax)" : : "a" (va)); goto finish; } else @@ -363,6 +375,33 @@ return VA_READABLE; } +ERROR_CODE MarkPageForCOW(VIRTUAL_PAGE_PTR vp) +{ + LIST_PTR map_list; + + KTRACE("vp %p\n", vp); + assert(vp); + + vp->copy_on_write++; + + if (vp->va_map_list != NULL) + { + LIST_FOR_EACH(map_list, &vp->va_map_list->list) + { + VA_MAP_PTR va_map; + + va_map = STRUCT_ADDRESS_FROM_MEMBER(map_list, VA_MAP, list); + /* Mark the mapping as read-only*/ + //CreatePhysicalMapping(va_map->physical_map, va_map->va, vp->physical_address, PROT_READ); + if (va_map->physical_map == GetCurrentVirtualMap()->physical_map) + { + CreatePhysicalMapping(va_map->physical_map, va_map->va, vp->physical_address, PROT_READ); + } + } + } + + return ERROR_SUCCESS; +} /*! Internal function used to initialize the physical map structure*/ int PhysicalMapCacheConstructor( void *buffer) Modified: src/kernel/i386/processor.c =================================================================== --- src/kernel/i386/processor.c 2011-08-31 09:03:50 UTC (rev 370) +++ src/kernel/i386/processor.c 2011-09-13 02:23:23 UTC (rev 371) @@ -158,7 +158,7 @@ panic("PA not available for starting secondary CPU\n"); /*reserve kernel virtual address*/ - if ( AllocateVirtualMemory(&kernel_map, &va, 0, size, 0, 0, NULL) != ERROR_SUCCESS ) + if ( AllocateVirtualMemory(&kernel_map, &va, 0, size, 0, VM_UNIT_FLAG_PRIVATE, NULL) != ERROR_SUCCESS ) panic("VA not available for starting secondary CPU\n"); /*create va to pa mapping*/ Modified: src/kernel/iom/driver.c =================================================================== --- src/kernel/iom/driver.c 2011-08-31 09:03:50 UTC (rev 370) +++ src/kernel/iom/driver.c 2011-09-13 02:23:23 UTC (rev 371) @@ -20,9 +20,6 @@ DRIVER_OBJECT_PTR LoadDriver(char * device_id) { char driver_file_name[MAX_FILE_NAME], driver_file_path[MAX_FILE_PATH]="/boot/drivers/"; - VADDR driver_start_address; - int file_id; - long file_size; DRIVER_OBJECT_PTR driver_object; ERROR_CODE (*DriverEntry)(DRIVER_OBJECT_PTR pDriverObject); ERROR_CODE err; @@ -52,17 +49,7 @@ strcat( driver_file_path, driver_file_name ); kprintf("Loading %s: ", driver_file_path); - err = OpenFile(&kernel_task, driver_file_path, VFS_ACCESS_TYPE_READ, OPEN_EXISTING, &file_id); - if ( err != ERROR_SUCCESS ) - goto error; - err = GetFileSize(&kernel_task, file_id, &file_size); - if ( err != ERROR_SUCCESS ) - goto error; - file_size = PAGE_ALIGN_UP(file_size); - err = MapViewOfFile(file_id, &driver_start_address, PROT_READ, 0, file_size, 0, 0); - if ( err != ERROR_SUCCESS ) - goto error; - err = LoadElfImage( (void *) driver_start_address, &kernel_map, "DriverEntry", (void *)&DriverEntry ); + err = LoadElfImage( driver_file_path, "DriverEntry", (void *)&DriverEntry ); if ( err != ERROR_SUCCESS || DriverEntry == NULL ) goto error; driver_object = AllocateBuffer( &driver_object_cache, CACHE_ALLOC_SLEEP ); Modified: src/kernel/ipc/message_queue.c =================================================================== --- src/kernel/ipc/message_queue.c 2011-08-31 09:03:50 UTC (rev 370) +++ src/kernel/ipc/message_queue.c 2011-09-13 02:23:23 UTC (rev 371) @@ -335,7 +335,7 @@ if(IPR_ARGUMENT_ADDRESS == NULL || !IS_PAGE_ALIGNED((long)IPR_ARGUMENT_ADDRESS) || IPC_ARGUMENT_LENGTH <= 0 || !IS_PAGE_ALIGNED(IPC_ARGUMENT_LENGTH)) return ERROR_INVALID_PARAMETER; copy_va = (VADDR)IPR_ARGUMENT_ADDRESS; - ret = CopyVirtualAddressRange( GetCurrentVirtualMap(), (VADDR)IPR_ARGUMENT_ADDRESS, IPC_ARGUMENT_LENGTH, target_task->virtual_map, ©_va, IPC_ARGUMENT_LENGTH, PROT_READ ); + ret = CopyVirtualAddressRange(GetCurrentVirtualMap(), (VADDR)IPR_ARGUMENT_ADDRESS, IPC_ARGUMENT_LENGTH, target_task->virtual_map, ©_va, IPC_ARGUMENT_LENGTH, PROT_READ, VM_UNIT_FLAG_PRIVATE); if( ret != ERROR_SUCCESS ) return ret; Modified: src/kernel/main.c =================================================================== --- src/kernel/main.c 2011-08-31 09:03:50 UTC (rev 370) +++ src/kernel/main.c 2011-09-13 02:23:23 UTC (rev 371) @@ -92,12 +92,12 @@ SetupSystemCallHandler(); //InitGraphicsConsole(); - + + kprintf("Kernel initialization complete - Loading shell\n"); + CreateTask("/boot/app/hello.exe", IMAGE_TYPE_ELF_FILE, TASK_CREATION_FLAG_NONE, NULL, "hello.exe", "TEST=TS"); CreateTask("/boot/app/bash", IMAGE_TYPE_ELF_FILE, TASK_CREATION_FLAG_NONE, NULL, "bash -i", "ees=33"); - kprintf("Kernel initialization complete\n"); - ExitThread(); } Modified: src/kernel/mm/virtual_page.c =================================================================== --- src/kernel/mm/virtual_page.c 2011-08-31 09:03:50 UTC (rev 370) +++ src/kernel/mm/virtual_page.c 2011-09-13 02:23:23 UTC (rev 371) @@ -73,6 +73,7 @@ memset(vp, 0, sizeof( VIRTUAL_PAGE ) ); InitSpinLock( &vp->lock ); + InitList( &vp->lru_list ); InitAvlTreeNode( VP_AVL_TREE(vp), TRUE ); @@ -445,20 +446,13 @@ VIRTUAL_PAGE_PTR PhysicalToVirtualPage(UINT32 physical_address) { int i,j; - int debug=0; -retry: - for(i=0; i<memory_area_count; i++ ) { PHYSICAL_MEMORY_REGION_PTR pmr; for(j=0;j<memory_areas[i].physical_memory_regions_count;j++) { pmr = &memory_areas[i].physical_memory_regions[j]; - if ( debug ) - { - KTRACE("%p - %p : %p\n", pmr->start_physical_address, pmr->end_physical_address, physical_address); - } if ( physical_address >= pmr->start_physical_address && physical_address < pmr->end_physical_address ) { UINT32 index; @@ -469,13 +463,9 @@ } } } - if ( !debug ) - { - debug++; - KTRACE("PA not managed\n"); - goto retry; - } + KTRACE("PA not managed 0x%x\n", physical_address); + return NULL; } Modified: src/kernel/mm/vm.c =================================================================== --- src/kernel/mm/vm.c 2011-08-31 09:03:50 UTC (rev 370) +++ src/kernel/mm/vm.c 2011-09-13 02:23:23 UTC (rev 371) @@ -181,12 +181,13 @@ } vd = GetVmDescriptor(vmap, va, 1); assert ( vd != NULL ); - assert( va >= vd->start && va <= vd->end ); + assert( va >= vd->start && va <= PAGE_ALIGN_UP(vd->end) ); vtop_index = ((va - vd->start) / PAGE_SIZE) + (vd->offset_in_unit/PAGE_SIZE); assert( vtop_index <= (vd->unit->size/PAGE_SIZE) ); for(i=0; i<size;i+=PAGE_SIZE ) { + vp = PhysicalToVirtualPage(pa+i); if (GetCurrentVirtualMap() == vmap) { if ( CreatePhysicalMapping(vmap->physical_map, va+i, pa+i, protection) != ERROR_SUCCESS ) @@ -194,11 +195,15 @@ FreeVirtualMemory(vmap, va, size, 0); return NULL; } + if (vp != NULL) + { + vd->unit->page_count++; + vd->unit->vtop_array[vtop_index+(i/PAGE_SIZE)].vpage = (VIRTUAL_PAGE_PTR) ( ((VADDR)vp) | 1 ); + } } else { /* if the PA is managed then create a lazy mapping */ - vp = PhysicalToVirtualPage(pa+i); if (vp == NULL) { panic("Request to map unmanaged page in different task map - Use kvm driver for that purpose"); @@ -272,18 +277,25 @@ /*create new vm_unit if unit is not provided*/ if ( unit == NULL ) { - unit = CreateVmUnit(VM_UNIT_TYPE_ANONYMOUS, VM_UNIT_FLAG_SHARED, size); + unit = CreateVmUnit(VM_UNIT_TYPE_ANONYMOUS, flags, size); } + else if (flags & VM_UNIT_FLAG_PRIVATE) + { + /*Mark all pages for COW and create new unit*/ + unit = CopyVmUnit(unit, 0, size); + assert(unit != NULL); + } /*link map, descriptor and unit*/ CreateVmDescriptor(vmap, start, start+size-1, unit, prot); + * (va_ptr) = start; return ERROR_SUCCESS; } /*! Free the already allocated virtual memory range */ -ERROR_CODE FreeVirtualMemory(VIRTUAL_MAP_PTR vmap, VADDR va, UINT32 size, UINT32 flags) +ERROR_CODE FreeVirtualMemory(VIRTUAL_MAP_PTR vmap, VADDR va, size_t size, UINT32 flags) { ERROR_CODE ret; UINT32 rem_va; @@ -309,7 +321,7 @@ * \param dest_size - Size of the new allocation in destination map. It can be greater than src_size in that case, the remaining space will be zeroed. * \param protection - protection for the new mapping */ -ERROR_CODE CopyVirtualAddressRange(VIRTUAL_MAP_PTR src_vmap, VADDR src_va, UINT32 src_size, VIRTUAL_MAP_PTR dest_vmap, VADDR *dest_preferred_va, UINT32 dest_size, UINT32 protection) +ERROR_CODE CopyVirtualAddressRange(VIRTUAL_MAP_PTR src_vmap, VADDR src_va, UINT32 src_size, VIRTUAL_MAP_PTR dest_vmap, VADDR *dest_preferred_va, UINT32 dest_size, UINT32 protection, UINT32 flags) { VM_DESCRIPTOR_PTR src_vd, dest_vd; VM_UNIT_PTR unit=NULL; @@ -317,8 +329,8 @@ ERROR_CODE ret; VADDR org_src_size, org_dest_size, size; - assert( src_size <= dest_size ); - + assert(src_size <= dest_size); + /*preserve the passed sizes*/ org_src_size = src_size; org_dest_size = dest_size; @@ -340,7 +352,7 @@ return ERROR_INVALID_PARAMETER; /*allocate virtaul address range and map the same vm unit*/ - ret = AllocateVirtualMemory(dest_vmap, &va, *dest_preferred_va, src_size, protection, 0, unit); + ret = AllocateVirtualMemory(dest_vmap, &va, *dest_preferred_va, src_size, protection, flags, unit); if ( ret != ERROR_SUCCESS ) return ret; @@ -357,7 +369,7 @@ size = dest_size - src_size; assert( size > 0 ); /*we cant use the same unit as backing object - allocate virtaul address range with ZEROFILL unit*/ - ret = AllocateVirtualMemory(dest_vmap, &second_va, PAGE_ALIGN_UP(va+src_size), size, protection, 0, NULL); + ret = AllocateVirtualMemory(dest_vmap, &second_va, PAGE_ALIGN_UP(va+src_size), size, protection, VM_UNIT_FLAG_PRIVATE, NULL); if ( ret != ERROR_SUCCESS ) { FreeVirtualMemory(dest_vmap, va, src_size, 0); @@ -384,6 +396,25 @@ return thread->task->virtual_map; } +void AddVmunitToVnodeList(VNODE_PTR vnode, VM_UNIT_PTR unit, offset_t offset) +{ + assert(vnode != NULL && unit != NULL); + + unit->offset = offset; + unit->vnode = vnode; + SpinLock(&vnode->lock); + if ( vnode->unit_head == NULL ) + { + vnode->unit_head = unit; + } + else + { + AddToList( &vnode->unit_head->units_in_vnode_list, &unit->units_in_vnode_list ); + } + vnode->reference_count++; + SpinUnlock(&vnode->lock); +} + /*! Maps a view of a file mapping into the address space of a calling process \param file_id - opened file number \param va - resulting mapped va @@ -440,15 +471,7 @@ if( unit == NULL) { unit = CreateVmUnit(VM_UNIT_TYPE_FILE_MAPPED, VM_UNIT_FLAG_SHARED, size); - unit->offset = file_offset; - unit->vnode = vnode; - SpinLock(&vnode->lock); - if ( vnode->unit_head == NULL ) - vnode->unit_head = unit; - else - AddToList( &vnode->unit_head->units_in_vnode_list, &unit->units_in_vnode_list ); - vnode->reference_count++; - SpinUnlock(&vnode->lock); + AddVmunitToVnodeList(vnode, unit, file_offset); } assert ( unit->vnode == vnode ); @@ -537,8 +560,6 @@ return ERROR_NOT_FOUND; } - //assert( va >= vd->start && va <= vd->end ); - vtop_index = ((va - vd->start) / PAGE_SIZE) + (vd->offset_in_unit/PAGE_SIZE); assert( vtop_index <= (vd->unit->size/PAGE_SIZE) ); @@ -558,7 +579,7 @@ assert( IS_PAGE_ALIGNED(file_offset) ); vp = GetVnodePage(vd->unit->vnode, file_offset); assert(vp!=NULL); - } + } else { /*anonymous memory allocate memory and zero fill*/ @@ -584,7 +605,7 @@ if( zero_fill ) { /*zero fill a anon page*/ - memset( (void *) aligned_va, 0, PAGE_SIZE); + memset((void *)aligned_va, 0, PAGE_SIZE); } #if 0 /* The following might look good but wont work - because files are loaded into a single page and shared by multiple descriptors(using a single vmunit) Modified: src/kernel/mm/vm_descriptor.c =================================================================== --- src/kernel/mm/vm_descriptor.c 2011-08-31 09:03:50 UTC (rev 370) +++ src/kernel/mm/vm_descriptor.c 2011-09-13 02:23:23 UTC (rev 371) @@ -73,12 +73,14 @@ { VM_DESCRIPTOR_PTR vd; + assert( PAGE_ALIGN_UP(end-start) <= PAGE_ALIGN_UP(vm_unit->size) ); + SpinLock(&vmap->lock); vmap->reference_count++; SpinUnlock(&vmap->lock); start = PAGE_ALIGN(start); - end = PAGE_ALIGN_UP(end)-1; + //end = PAGE_ALIGN_UP(end)-1; vd = (VM_DESCRIPTOR_PTR)kmalloc(sizeof(VM_DESCRIPTOR), KMEM_NO_FAIL); //vd = AllocateBuffer( &vm_descriptor_cache, 0 ); @@ -203,7 +205,7 @@ size = PAGE_ALIGN_UP(a->size)-1; a->previous_descriptor_va_end = PAGE_ALIGN_UP(a->previous_descriptor_va_end); /*check whether the hole has "preferred" start and required size*/ - if ( RANGE_WITH_IN_RANGE( a->previous_descriptor_va_end, descriptor->start, va_start, va_end ) ) + if ( RANGE_WITH_IN_RANGE( PAGE_ALIGN_UP(a->previous_descriptor_va_end), PAGE_ALIGN(descriptor->start), va_start, va_end ) ) { /*update the result with correct address*/ a->result = va_start; @@ -252,10 +254,10 @@ d1 = STRUCT_ADDRESS_FROM_MEMBER(node1, VM_DESCRIPTOR, tree_node.bintree); d2 = STRUCT_ADDRESS_FROM_MEMBER(node2, VM_DESCRIPTOR, tree_node.bintree); - if( d1->start <= d2->start && d1->end >= d2->end ) + if( PAGE_ALIGN(d1->start) <= PAGE_ALIGN(d2->start) && PAGE_ALIGN_UP(d1->end)-1 >= d2->end ) return EQUAL; - if ( d1->start > d2->start ) + if ( PAGE_ALIGN(d1->start) > PAGE_ALIGN(d2->start) ) return LESS_THAN; else return GREATER_THAN; Modified: src/kernel/mm/vm_unit.c =================================================================== --- src/kernel/mm/vm_unit.c 2011-08-31 09:03:50 UTC (rev 370) +++ src/kernel/mm/vm_unit.c 2011-09-13 02:23:23 UTC (rev 371) @@ -6,6 +6,8 @@ #include <ds/avl_tree.h> #include <kernel/mm/vm.h> #include <kernel/mm/kmem.h> +#include <kernel/mm/pmem.h> +#include <kernel/debug.h> /*! Initializes the given VM unit \param unit - pointer to vm unit @@ -76,9 +78,45 @@ void SetVmUnitPage(VM_UNIT_PTR unit, VIRTUAL_PAGE_PTR vp, UINT32 vtop_index) { - assert( unit != NULL ); - assert( vtop_index <= unit->size / PAGE_SIZE ); + assert(unit != NULL); + assert(vtop_index <= (unit->size / PAGE_SIZE)); + assert(vp != NULL); unit->page_count++; unit->vtop_array[vtop_index].vpage = (VIRTUAL_PAGE_PTR) ( ((VADDR)vp) | 1 ); } + +VM_UNIT_PTR CopyVmUnit(VM_UNIT_PTR unit, VADDR start, VADDR end) +{ + VM_UNIT_PTR new_unit; + UINT32 new_size; + int i, total_pages, old_start_index; + + new_size = end - start; + + assert(unit != NULL); + assert(start < unit->size && IS_PAGE_ALIGNED(start)); + assert(end <= unit->size && IS_PAGE_ALIGNED(end)); + assert(new_size != 0 && new_size <= unit->size); + + new_unit = CreateVmUnit(unit->type, 0, new_size); + + total_pages = new_size / PAGE_SIZE; + old_start_index = start/PAGE_SIZE; + for(i = 0; i < total_pages; i++) + { + new_unit->vtop_array[i].vpage = unit->vtop_array[old_start_index+i].vpage; + if (new_unit->vtop_array[i].in_memory) + { + new_unit->page_count++; + MarkPageForCOW( (VIRTUAL_PAGE_PTR)(((VADDR)new_unit->vtop_array[i].vpage) & ~1)); + } + } + if (new_unit->vnode) + { + AddVmunitToVnodeList(new_unit->vnode, new_unit, unit->offset + start); + } + + return new_unit; + +} Modified: src/kernel/pm/elf.c =================================================================== --- src/kernel/pm/elf.c 2011-08-31 09:03:50 UTC (rev 370) +++ src/kernel/pm/elf.c 2011-09-13 02:23:23 UTC (rev 371) @@ -7,7 +7,7 @@ #include <kernel/pm/elf.h> static ERROR_CODE LoadElfSegments(ELF_HEADER_PTR file_header, char * string_table, VIRTUAL_MAP_PTR virtual_map); -static ERROR_CODE LoadElfSegmentIntoMap(ELF_PROGRAM_HEADER_PTR program_header, char *segment_start, VIRTUAL_MAP_PTR virtual_map); +static ERROR_CODE LoadElfSegmentIntoMap(ELF_PROGRAM_HEADER_PTR program_header, char * segment_start, VIRTUAL_MAP_PTR virtual_map); static ERROR_CODE LoadElfSections(ELF_HEADER_PTR file_header, char * string_table, VIRTUAL_MAP_PTR virtual_map, VADDR * section_loaded_va); static ERROR_CODE LoadElfSectionIntoMap(ELF_SECTION_HEADER_PTR section_header, VADDR section_data_offset, VIRTUAL_MAP_PTR virtual_map, VADDR * section_loaded_va); static ERROR_CODE RelocateSection(ELF_SECTION_HEADER_PTR section_header, ELF_SYMBOL_PTR symbol_table, int relocation_section_index, char * string_table, VADDR relocation_entries, VADDR * section_loaded_va); @@ -20,42 +20,78 @@ static void RelocateI386Field(ELF32_RELOCATION_PTR rp, VADDR symbol_value, VADDR base_va, int type); #endif -/*! Loads an ELF image into the given virtual map +/*! Loads an ELF image into the current virtual map \param file_header - virtual address where the elf file resides + \param file_id - elf file id \param virtual_map - the elf sections will be loaded into this virtual map \param start_symbol_name - program's first function to start \param start_entry - if start_symbol_name is not null then the symbol will be searched in the symbol table and if found its loaded VA will be updated here. This function is just a wrapper LoadElfSections(). It just performs some sanity checks and give calls LoadElfSections() */ -ERROR_CODE LoadElfImage(ELF_HEADER_PTR file_header, VIRTUAL_MAP_PTR virtual_map, char * start_symbol_name, VADDR * start_entry) +ERROR_CODE LoadElfImage(char *elf_file_path, char * start_symbol_name, VADDR * start_entry) { ELF_SECTION_HEADER_PTR string_section_header = NULL; char * string_table = NULL; VADDR * section_loaded_va = NULL; /*holds array of virtual addresses, where the sections are loaded into the virtual map*/ + long file_size; + int i, file_id; + ELF_HEADER_PTR file_header = NULL; + VIRTUAL_MAP_PTR virtual_map; ERROR_CODE err = ERROR_NOT_SUPPORTED; - int i; + virtual_map = GetCurrentVirtualMap(); + + err = OpenFile(GetCurrentTask(), elf_file_path, VFS_ACCESS_TYPE_READ, OPEN_EXISTING, &file_id); + if ( err != ERROR_SUCCESS ) + { + return err; + } + err = GetFileSize(&kernel_task, file_id, &file_size); + if ( err != ERROR_SUCCESS ) + { + goto done; + } + + file_size = PAGE_ALIGN_UP(file_size); + err = MapViewOfFile(file_id, (void *)&file_header, PROT_READ, 0, file_size, 0, 0); + if ( err != ERROR_SUCCESS ) + { + goto done; + } + assert(file_header != NULL); /*check for correct file type and machine type*/ if( file_header->e_ident[EI_MAGIC0] != ELFMAGIC0 || file_header->e_ident[EI_MAGIC1] != ELFMAGIC1 || file_header->e_ident[EI_MAGIC2] != ELFMAGIC2 || file_header->e_ident[EI_MAGIC3] != ELFMAGIC3 ) - return ERROR_INVALID_FORMAT; + { + err = ERROR_INVALID_FORMAT; + goto done; + } #if ARCH == i386 if( file_header->e_ident[EI_CLASS] != ELFCLASS32 || file_header->e_ident[EI_DATA] != ELFDATA2LSB ) - return ERROR_INVALID_FORMAT; + { + err = ERROR_INVALID_FORMAT; + goto done; + } #endif if ( file_header->e_type == ET_NONE ) - return ERROR_NOT_SUPPORTED; + { + err = ERROR_NOT_SUPPORTED; + goto done; + } /* Allocate memory to hold the virtual addresses where sections will be loaded. The last entry is used for common section(SHN_COMMON). */ section_loaded_va = (VADDR *) kmalloc( sizeof(VADDR) * file_header->e_shnum+1, 0 ); if ( section_loaded_va == NULL ) - return ERROR_NOT_ENOUGH_MEMORY; + { + err = ERROR_NOT_ENOUGH_MEMORY; + goto done; + } for(i=0; i<=file_header->e_shnum; i++) section_loaded_va[i] = NULL; @@ -65,13 +101,16 @@ string_section_header = (ELF_SECTION_HEADER_PTR)( (VADDR)file_header + file_header->e_shoff + (file_header->e_shstrndx*file_header->e_shentsize) ); /*just make sure we have correct section type*/ if ( string_section_header->sh_type != SHT_STRTAB ) - return ERROR_INVALID_FORMAT; + { + err = ERROR_INVALID_FORMAT; + goto done; + } string_table = (char *)file_header + string_section_header->sh_offset; } /*if program header present load all segments*/ - if ( file_header->e_phoff != 0 ) + if ( file_header->e_phoff != 0 ) { /*load the elf section and relocate it */ err = LoadElfSegments(file_header, string_table, virtual_map); @@ -97,9 +136,19 @@ *start_entry = file_header->e_entry; } - kfree( section_loaded_va ); +done: + if ( section_loaded_va != NULL ) + { + kfree( section_loaded_va ); + } + if (file_header != NULL) + { + FreeVirtualMemory(virtual_map, (VADDR)file_header, file_size, 0); + } + CloseFile(GetCurrentTask(), file_id); return err; } + static ERROR_CODE LoadElfSegments(ELF_HEADER_PTR file_header, char * string_table, VIRTUAL_MAP_PTR virtual_map) { ELF_PROGRAM_HEADER_PTR first_program_header, program_header; @@ -118,7 +167,7 @@ } else { - ret = LoadElfSegmentIntoMap(program_header, ((char *)file_header)+program_header->p_offset, virtual_map ); + ret = LoadElfSegmentIntoMap(program_header, ((char *)file_header)+program_header->p_offset, virtual_map); if ( ret != ERROR_SUCCESS ) return ret; } @@ -126,6 +175,7 @@ return ret; } + static ERROR_CODE LoadElfSegmentIntoMap(ELF_PROGRAM_HEADER_PTR program_header, char * segment_start, VIRTUAL_MAP_PTR virtual_map) { ERROR_CODE ret = ERROR_SUCCESS; @@ -149,7 +199,10 @@ /*if the segment is loadable - map it into the address space*/ if ( program_header->p_type == PT_LOAD ) { - ret = CopyVirtualAddressRange( GetCurrentVirtualMap(), (VADDR)segment_start, program_header->p_filesz, virtual_map, &preferred_va, program_header->p_memsz, protection ); + assert( program_header->p_memsz >= program_header->p_filesz); + ret = AllocateVirtualMemory(virtual_map, &preferred_va, program_header->p_vaddr, program_header->p_memsz, protection, VM_UNIT_FLAG_PRIVATE, NULL); + assert( preferred_va == program_header->p_vaddr); + memcpy((void *)preferred_va, segment_start, program_header->p_filesz); } else { @@ -158,11 +211,13 @@ if ( size == 0 ) size = PAGE_SIZE; /* \todo - ensure we load into preferred address else do the relocation...*/ - ret = AllocateVirtualMemory( virtual_map, &preferred_va, program_header->p_vaddr, size, protection, 0, NULL ); + ret = AllocateVirtualMemory(virtual_map, &preferred_va, program_header->p_vaddr, size, protection, VM_UNIT_FLAG_PRIVATE, NULL); + assert( preferred_va == program_header->p_vaddr); } return ret; } + /*! Loads ELF sections into given virtual map and fixes the relocations \param file_header - virtual address where the elf file resides \param string_table - string table for the elf section names @@ -200,7 +255,7 @@ symbol_table_size = section_header->sh_size; common_size += GetElfCommonSectionSize( symbol_table, symbol_table_size ); } - ret = LoadElfSectionIntoMap(section_header, (VADDR)file_header+section_header->sh_offset, virtual_map, §ion_loaded_va[i]); + ret = LoadElfSectionIntoMap(section_header, ((VADDR)file_header)+section_header->sh_offset, virtual_map, §ion_loaded_va[i]); if ( ret != ERROR_SUCCESS ) return ret; } @@ -208,7 +263,7 @@ if( common_size != 0 ) { /*allocate memory*/ - ret = AllocateVirtualMemory( virtual_map, §ion_loaded_va[file_header->e_shnum], 0, PAGE_ALIGN_UP(common_size), PROT_READ | PROT_WRITE, 0, NULL ); + ret = AllocateVirtualMemory( virtual_map, §ion_loaded_va[file_header->e_shnum], 0, PAGE_ALIGN_UP(common_size), PROT_READ | PROT_WRITE, VM_UNIT_FLAG_PRIVATE, NULL ); if ( ret != ERROR_SUCCESS ) return ret; /*Update the symbols*/ @@ -238,6 +293,7 @@ return ret; } + /*! Loads a given ELF section into a Virtual Map and returns the loaded virtual address in section_loaded_va Sections are loaded only if the section has SHF_ALLOC otherwise just ERROR_SUCCESS will returned without loading and section_loaded_va will set to NULL \param section_header - section header @@ -272,12 +328,13 @@ VADDR size = section_header->sh_size; if ( size == 0 ) size = PAGE_SIZE; - ret = AllocateVirtualMemory( virtual_map, section_loaded_va, section_header->sh_addr, size, protection, 0, NULL ); + ret = AllocateVirtualMemory(virtual_map, section_loaded_va, section_header->sh_addr, size, protection, VM_UNIT_FLAG_PRIVATE, NULL); } else if( section_header->sh_size > 0 ) { /*copy section data only if the source section has some data to copy*/ - ret = CopyVirtualAddressRange( GetCurrentVirtualMap(), section_data_offset, section_header->sh_size, virtual_map, section_loaded_va, section_header->sh_size, protection); + ret = AllocateVirtualMemory(virtual_map, section_loaded_va, *section_loaded_va, section_header->sh_size, protection, VM_UNIT_FLAG_PRIVATE, NULL); + memcpy((void *)*section_loaded_va, (void *)section_data_offset, section_header->sh_size); } if (ret != ERROR_SUCCESS) @@ -523,6 +580,7 @@ #endif } } + return ERROR_SUCCESS; } Modified: src/kernel/pm/task.c =================================================================== --- src/kernel/pm/task.c 2011-08-31 09:03:50 UTC (rev 370) +++ src/kernel/pm/task.c 2011-09-13 02:23:23 UTC (rev 371) @@ -77,26 +77,26 @@ if( image_type == IMAGE_TYPE_ELF_FILE || image_type == IMAGE_TYPE_BIN_FILE) { - /*map the executable in kernel address space*/ - err = OpenFile(&kernel_task, exe_file_path, VFS_ACCESS_TYPE_READ, OPEN_EXISTING, &file_id); - if ( err != ERROR_SUCCESS ) - goto error; - err = GetFileSize(&kernel_task, file_id, &file_size); - if ( err != ERROR_SUCCESS ) - goto error; - file_size = PAGE_ALIGN_UP(file_size); - err = MapViewOfFile(file_id, &start_address, PROT_READ, 0, file_size, 0, 0); - if ( err != ERROR_SUCCESS ) - goto error; /*load the image into address space*/ switch( image_type ) { case IMAGE_TYPE_ELF_FILE: - err = LoadElfImage( (ELF_HEADER_PTR)start_address, task->virtual_map, NULL, (void *)&main_entry ); + err = LoadElfImage(exe_file_path , NULL, (void *)&main_entry); break; case IMAGE_TYPE_BIN_FILE: + /*map the executable in kernel address space*/ + err = OpenFile(GetCurrentTask(), exe_file_path, VFS_ACCESS_TYPE_READ, OPEN_EXISTING, &file_id); + if ( err != ERROR_SUCCESS ) + goto error; + err = GetFileSize(GetCurrentTask(), file_id, &file_size); + if ( err != ERROR_SUCCESS ) + goto error; + file_size = PAGE_ALIGN_UP(file_size); + err = MapViewOfFile(file_id, &start_address, PROT_READ, 0, file_size, 0, 0); + if ( err != ERROR_SUCCESS ) + goto error; main_entry = (void *)(PAGE_SIZE*2); - err = CopyVirtualAddressRange( GetCurrentVirtualMap(), start_address, file_size, task->virtual_map, (VADDR *)&main_entry, file_size, PROT_READ | PROT_WRITE ); + err = CopyVirtualAddressRange( GetCurrentVirtualMap(), start_address, file_size, task->virtual_map, (VADDR *)&main_entry, file_size, PROT_READ | PROT_WRITE, VM_UNIT_FLAG_PRIVATE); break; case IMAGE_TYPE_BIN_PROGRAM: /*just to avoid gcc warning - this case wont come because it is filtered in the "if" condition*/ @@ -109,7 +109,7 @@ else if ( image_type == IMAGE_TYPE_BIN_PROGRAM ) { main_entry = (void *)(PAGE_SIZE*20); - err = CopyVirtualAddressRange( GetCurrentVirtualMap(), (VADDR)exe_file_path, PAGE_SIZE, task->virtual_map, (VADDR *)&main_entry, PAGE_SIZE, PROT_READ | PROT_WRITE ); + err = CopyVirtualAddressRange( GetCurrentVirtualMap(), (VADDR)exe_file_path, PAGE_SIZE, task->virtual_map, (VADDR *)&main_entry, PAGE_SIZE, PROT_READ | PROT_WRITE, VM_UNIT_FLAG_PRIVATE); } else panic("Invalid image type"); @@ -121,7 +121,7 @@ /*create main thread if needed*/ if ( creation_flag != TASK_CREATION_FLAG_NO_THREAD ) { - CreateThread( task, main_entry, SCHED_PRI_MID, FALSE, NULL); + CreateThread(task, main_entry, SCHED_PRI_MID, FALSE, NULL); } /*upate thread entry point*/ Modified: src/kernel/pm/thread.c =================================================================== --- src/kernel/pm/thread.c 2011-08-31 09:03:50 UTC (rev 370) +++ src/kernel/pm/thread.c 2011-09-13 02:23:23 UTC (rev 371) @@ -64,14 +64,14 @@ else { /*create user stack*/ - if ( AllocateVirtualMemory( task->virtual_map, &user_stack, 0, USER_STACK_SIZE, PROT_WRITE|PROT_READ, 0, NULL ) != ERROR_SUCCESS ) + if ( AllocateVirtualMemory( task->virtual_map, &user_stack, 0, USER_STACK_SIZE, PROT_WRITE|PROT_READ, VM_UNIT_FLAG_PRIVATE, NULL ) != ERROR_SUCCESS ) { KTRACE("User stack allocation failed"); return NULL; } /*allocate a page for scratch*/ - AllocateVirtualMemory( task->virtual_map, (VADDR *)&thread_container->thread.user_scratch, 0, PAGE_SIZE, PROT_READ|PROT_WRITE, 0, NULL ); + AllocateVirtualMemory( task->virtual_map, (VADDR *)&thread_container->thread.user_scratch, 0, PAGE_SIZE, PROT_READ|PROT_WRITE, VM_UNIT_FLAG_PRIVATE, NULL ); /*should we need assert here?*/ assert( thread_container->thread.user_scratch != NULL ); } Modified: src/kernel/syscall/file.c =================================================================== --- src/kernel/syscall/file.c 2011-08-31 09:03:50 UTC (rev 370) +++ src/kernel/syscall/file.c 2011-09-13 02:23:23 UTC (rev 371) @@ -39,6 +39,9 @@ KTRACE("%s %x\n", path, oflag); ret = OpenFile( GetCurrentTask(), path, access, flag, (int *)retval ); + if (strcmp(path, "/device/console")== 0 ) + return 0; + KTRACE("%s\n", ERROR_CODE_AS_STRING(ret)); if ( ret == ERROR_SUCCESS ) return 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sam...@us...> - 2011-08-31 09:03:56
|
Revision: 370 http://aceos.svn.sourceforge.net/aceos/?rev=370&view=rev Author: samueldotj Date: 2011-08-31 09:03:50 +0000 (Wed, 31 Aug 2011) Log Message: ----------- During boot kernel page table entries was allocated from memory area and then those memory spaces were marked unmanaged. This creates problem later(kernel page table entries cant be lazy mapped to applications) to avoid this now it is becomes part of managed memory. Modified Paths: -------------- src/include/ace.h src/include/kernel/mm/pmem.h src/include/kernel/mm/virtual_page.h src/kernel/i386/mm/pmem.c src/kernel/i386/mm/pmem_init.c src/kernel/mm/virtual_page.c src/kernel/mm/vm.c Modified: src/include/ace.h =================================================================== --- src/include/ace.h 2011-08-31 03:52:28 UTC (rev 369) +++ src/include/ace.h 2011-08-31 09:03:50 UTC (rev 370) @@ -56,6 +56,9 @@ GREATER_THAN=1 }COMPARISION_RESULT; +#define KB (1024) +#define MB (1024*KB) +#define GB (1024*MB) +#define TB (1024ULL*GB) + #endif - - Modified: src/include/kernel/mm/pmem.h =================================================================== --- src/include/kernel/mm/pmem.h 2011-08-31 03:52:28 UTC (rev 369) +++ src/include/kernel/mm/pmem.h 2011-08-31 09:03:50 UTC (rev 370) @@ -35,6 +35,7 @@ VIRTUAL_PAGE_PTR virtual_page_array; /*! virtual address of virutal page array for this region*/ UINT32 virtual_page_count; /*! total virtual pages in this region*/ + UINT32 virtual_pages_used_for_booting; /*! Pages used during booting - used for kernel page tables*/ UINT32 type; /*! type of this region - usable, reserved, etc*/ Modified: src/include/kernel/mm/virtual_page.h =================================================================== --- src/include/kernel/mm/virtual_page.h 2011-08-31 03:52:28 UTC (rev 369) +++ src/include/kernel/mm/virtual_page.h 2011-08-31 09:03:50 UTC (rev 370) @@ -79,7 +79,7 @@ VIRTUAL_PAGE_RANGE_TYPE_BELOW_16MB, }; -UINT32 InitVirtualPageArray(VIRTUAL_PAGE_PTR vpa, UINT32 page_count, UINT32 start_physical_address); +UINT32 InitVirtualPageArray(VIRTUAL_PAGE_PTR vpa, UINT32 page_count, UINT32 free_count, UINT32 start_physical_address); VIRTUAL_PAGE_PTR AllocateVirtualPages(int pages, enum VIRTUAL_PAGE_RANGE_TYPE vp_range_type); UINT32 FreeVirtualPages(VIRTUAL_PAGE_PTR vp, int pages); Modified: src/kernel/i386/mm/pmem.c =================================================================== --- src/kernel/i386/mm/pmem.c 2011-08-31 03:52:28 UTC (rev 369) +++ src/kernel/i386/mm/pmem.c 2011-08-31 09:03:50 UTC (rev 370) @@ -79,12 +79,28 @@ void MapKernelPageTableEntries() { + VM_DESCRIPTOR_PTR vd; + VIRTUAL_PAGE_PTR vp; UINT32 size; + int i; - size = PAGE_SIZE * 1024; - /*map page tables*/ + size = PAGE_SIZE * KB; + /* map page tables */ kernel_pte_vm_unit = CreateVmUnit(VM_UNIT_TYPE_PTE, VM_UNIT_FLAG_PRIVATE, size); - CreateVmDescriptor(&kernel_map, PT_SELF_MAP_ADDRESS, PT_SELF_MAP_ADDRESS + size, kernel_pte_vm_unit, &protection_kernel_write); + vd = CreateVmDescriptor(&kernel_map, PT_SELF_MAP_ADDRESS, PT_SELF_MAP_ADDRESS + size, kernel_pte_vm_unit, &protection_kernel_write); + assert(vd != NULL); + + /* Map all the PT pages created during boot time. */ + for(i=0;i<4;i++) { + PAGE_DIRECTORY_ENTRY pde; + + pde = kernel_page_directory[PT_SELF_MAP_INDEX + i]; + if (pde.present) { + vp = PhysicalToVirtualPage(PFN_TO_PA(pde.page_table_pfn)); + assert(vp != NULL); + SetVmUnitPage(vd->unit, vp, i); + } + } } /*! Fills page table entry for a given VA. This function makes the corresponding VA to point to PA by filling PTEs. @@ -233,16 +249,6 @@ return ERROR_SUCCESS; } -/*! allocates a page for page table use*/ -static UINT32 AllocatePageTable() -{ - VIRTUAL_PAGE_PTR vp; - - vp = AllocateVirtualPages(1, VIRTUAL_PAGE_RANGE_TYPE_NORMAL); - - assert ( vp != NULL ); - return vp->physical_address; -} /*! creates page table for a given VA. \param pmap - physical map for which va mapping should be created \param va - virtual address @@ -273,8 +279,11 @@ vp = AllocateVirtualPages(1, VIRTUAL_PAGE_RANGE_TYPE_NORMAL); assert ( vp != NULL ); vd = GetVmDescriptor(pmap->virtual_map, va, 1); - vtop_index = ((va - vd->start) / PAGE_SIZE) + (vd->offset_in_unit/PAGE_SIZE); - SetVmUnitPage(vd->unit, vp, vtop_index); + if ( vd ) + { + vtop_index = ((va - vd->start) / PAGE_SIZE) + (vd->offset_in_unit/PAGE_SIZE); + SetVmUnitPage(vd->unit, vp, vtop_index); + } pa = vp->physical_address; @@ -287,6 +296,8 @@ memset( (void *) page_table_va, 0, PAGE_SIZE); asm volatile("invlpg (%%eax)" : : "a" (page_table_va)); + + /* \todo - Initiate IPI to other CPUs to start flush TLB */ } /*! Reports the given virtual address range's status - readable/writeable or mapping not exists \param va - virtual address @@ -368,4 +379,3 @@ PhysicalMapCacheConstructor(buffer); return 0; } - Modified: src/kernel/i386/mm/pmem_init.c =================================================================== --- src/kernel/i386/mm/pmem_init.c 2011-08-31 03:52:28 UTC (rev 369) +++ src/kernel/i386/mm/pmem_init.c 2011-08-31 09:03:50 UTC (rev 370) @@ -181,6 +181,7 @@ pmr_pa->end_physical_address = pmr_pa->start_physical_address + memory_map_array[i].length_low; pmr_pa->virtual_page_array = NULL; pmr_pa->virtual_page_count = 0; + pmr_pa->virtual_pages_used_for_booting = 0; pmr_pa->type = memory_map_array[i].type; ma_pa->physical_memory_regions_count++; @@ -259,7 +260,7 @@ MEMORY_AREA_PTR ma_pa; ma_pa = (MEMORY_AREA_PTR)BOOT_ADDRESS( memory_areas ); - for(i=ma_pa->physical_memory_regions_count-1; i >= 0 ; i--) + for(i=ma_pa->physical_memory_regions_count-1; i >= 0 ;i--) { PHYSICAL_MEMORY_REGION_PTR pmr_pa; void * pa; @@ -268,13 +269,11 @@ /*if the region has enough free space allocate and return*/ if ( pmr_pa->type == PMEM_TYPE_AVAILABLE && (pmr_pa->end_physical_address - pmr_pa->start_physical_address) > PAGE_SIZE ) { - /*get the last page*/ - pa = (void *)(pmr_pa->end_physical_address-PAGE_SIZE); - - /*adjust the region*/ - pmr_pa->end_physical_address = (UINT32)pa; - pmr_pa->virtual_page_count--; - + /*get the last free page*/ + pa = (void *)(pmr_pa->end_physical_address - PAGE_SIZE - (pmr_pa->virtual_pages_used_for_booting * PAGE_SIZE)); + + pmr_pa->virtual_pages_used_for_booting++; + memset(pa, 0, PAGE_SIZE); return pa; @@ -282,6 +281,7 @@ } /*panic if we dont find a free physical page- however we cant call panic() because we havent boot yet so just halt*/ asm("cli;hlt"); + return NULL; } @@ -487,7 +487,7 @@ if ( pmr->type == PMEM_TYPE_AVAILABLE ) { - vm_data.total_memory_pages += InitVirtualPageArray(pmr->virtual_page_array, pmr->virtual_page_count, pmr->start_physical_address); + vm_data.total_memory_pages += InitVirtualPageArray(pmr->virtual_page_array, pmr->virtual_page_count, pmr->virtual_page_count - pmr->virtual_pages_used_for_booting, pmr->start_physical_address); } } } Modified: src/kernel/mm/virtual_page.c =================================================================== --- src/kernel/mm/virtual_page.c 2011-08-31 03:52:28 UTC (rev 369) +++ src/kernel/mm/virtual_page.c 2011-08-31 09:03:50 UTC (rev 370) @@ -39,7 +39,7 @@ \param start_physical_address - starting physical address of the first virtual page \return Returns how many pages added to virtual page array */ -UINT32 InitVirtualPageArray(VIRTUAL_PAGE_PTR vpa, UINT32 page_count, UINT32 start_physical_address) +UINT32 InitVirtualPageArray(VIRTUAL_PAGE_PTR vpa, UINT32 page_count, UINT32 free_count, UINT32 start_physical_address) { int i; AVL_TREE_PTR * vp_current_free_tree, * vp_prev_free_tree = NULL; @@ -55,7 +55,7 @@ } } /*Adding a page to Tree/list involves operations on other pages also, so do this after initializing a page*/ - for(i=0; i<page_count ;i++) + for(i=0; i<free_count ;i++) { vp_current_free_tree = GetVirtualPageFreeTreeFromPage( &vpa[i] ); AddVirtualPageToVmFreeTree( &vpa[i], vp_prev_free_tree == vp_current_free_tree); @@ -463,8 +463,9 @@ { UINT32 index; index = (physical_address - pmr->start_physical_address)/PAGE_SIZE; - assert ( index <= pmr->virtual_page_count ); - return &pmr->virtual_page_array[index]; + if ( index <= pmr->virtual_page_count ) { + return &pmr->virtual_page_array[index]; + } } } } Modified: src/kernel/mm/vm.c =================================================================== --- src/kernel/mm/vm.c 2011-08-31 03:52:28 UTC (rev 369) +++ src/kernel/mm/vm.c 2011-08-31 09:03:50 UTC (rev 370) @@ -50,6 +50,7 @@ vm_data.total_free_pages = 0; /*complete physical memory initialization*/ + kernel_map.physical_map = &kernel_physical_map; InitPhysicalMemoryManagerPhaseII(); kprintf("Total memory: %d KB (PAGE_SIZE %d)\n", (vm_data.total_memory_pages * PAGE_SIZE) / (1024), PAGE_SIZE ); @@ -100,7 +101,6 @@ VM_UNIT_PTR vm_unit; VM_DESCRIPTOR_PTR vd; - kernel_map.physical_map = &kernel_physical_map; kernel_map.start = kernel_reserve_range.code_va_start; kernel_map.end = kernel_reserve_range.kmem_va_end; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sam...@us...> - 2011-08-31 03:52:35
|
Revision: 369 http://aceos.svn.sourceforge.net/aceos/?rev=369&view=rev Author: samueldotj Date: 2011-08-31 03:52:28 +0000 (Wed, 31 Aug 2011) Log Message: ----------- Problem: Page table was not mapped using vm descriptors causing problem handling page fault because of PTE to crash. How PTE access can cause page fault? 1) Kernel causes a page fault(kva) while servicing an application(system call). This would result in fixing kernel part of page directory entry in that application's pmap. 2) After that another application runs causes page fault in same kva. Now page fault handler will create a new zero filled page for that kva and associate it with application's pmap. 3) This leads two applications having two different PA for a single kernel VA which is completely wrong. Fix: Map all page table entries using vm descriptors. The PTE mapping kernel space is mapped by single vm unit. So they share the pages. Modified Paths: -------------- src/include/kernel/acpi/platform/acace.h src/include/kernel/mm/pmem.h src/include/kernel/mm/vm.h src/kernel/i386/debug/serial.c src/kernel/i386/exception.c src/kernel/i386/mm/pmem.c src/kernel/i386/mm/pmem_init.c src/kernel/main.c src/kernel/mm/vm.c src/kernel/mm/vm_descriptor.c src/kernel/mm/vm_unit.c Modified: src/include/kernel/acpi/platform/acace.h =================================================================== --- src/include/kernel/acpi/platform/acace.h 2011-08-26 14:13:45 UTC (rev 368) +++ src/include/kernel/acpi/platform/acace.h 2011-08-31 03:52:28 UTC (rev 369) @@ -148,7 +148,7 @@ #define ACPI_SPINLOCK SPIN_LOCK_PTR typedef UINT32 FILE; -#define vfprintf(file, fmt, args) _doprint( fmt, kprintf_putc, file, args) +#define vfprintf(file, fmt, args) _doprint( fmt, ktrace_putc, file, args) #define ACPI_FLUSH_CPU_CACHE() FlushCpuCache(TRUE); #else /* !__KERNELBUILT__ */ Modified: src/include/kernel/mm/pmem.h =================================================================== --- src/include/kernel/mm/pmem.h 2011-08-26 14:13:45 UTC (rev 368) +++ src/include/kernel/mm/pmem.h 2011-08-31 03:52:28 UTC (rev 369) @@ -65,6 +65,8 @@ void InitPhysicalMemoryManagerPhaseII(); void CompletePhysicalMemoryManagerInit(); +void MapKernelPageTableEntries(); + ERROR_CODE CreatePhysicalMapping(PHYSICAL_MAP_PTR pmap, UINT32 va, UINT32 pa, UINT32 protection); ERROR_CODE RemovePhysicalMapping(PHYSICAL_MAP_PTR pmap, UINT32 va); Modified: src/include/kernel/mm/vm.h =================================================================== --- src/include/kernel/mm/vm.h 2011-08-26 14:13:45 UTC (rev 368) +++ src/include/kernel/mm/vm.h 2011-08-31 03:52:28 UTC (rev 369) @@ -53,7 +53,8 @@ VM_UNIT_TYPE_KERNEL=1, /*kernel mapping*/ VM_UNIT_TYPE_ANONYMOUS, VM_UNIT_TYPE_FILE_MAPPED, - VM_UNIT_TYPE_STACK + VM_UNIT_TYPE_STACK, + VM_UNIT_TYPE_PTE }VM_UNIT_TYPE; typedef enum @@ -206,8 +207,10 @@ VM_DESCRIPTOR_PTR CreateVmDescriptor(VIRTUAL_MAP_PTR vmap, VADDR start, VADDR end, VM_UNIT_PTR vm_unit, VM_PROTECTION_PTR protection); VM_DESCRIPTOR_PTR GetVmDescriptor(VIRTUAL_MAP_PTR vmap, VADDR va, UINT32 size); void * FindFreeVmRange(VIRTUAL_MAP_PTR vmap, VADDR start, UINT32 size, UINT32 option); +void PrintVmDescriptors(VIRTUAL_MAP_PTR vmap); VM_UNIT_PTR CreateVmUnit(VM_UNIT_TYPE type, VM_UNIT_FLAG flag, UINT32 size); +void SetVmUnitPage(VM_UNIT_PTR unit, VIRTUAL_PAGE_PTR vp, UINT32 vtop_index); ERROR_CODE AllocateVirtualMemory(VIRTUAL_MAP_PTR vmap, VADDR * va_ptr, VADDR preferred_start, UINT32 size, UINT32 protection, UINT32 flags, VM_UNIT_PTR unit); ERROR_CODE FreeVirtualMemory(VIRTUAL_MAP_PTR vmap, VADDR va, UINT32 size, UINT32 flags); Modified: src/kernel/i386/debug/serial.c =================================================================== --- src/kernel/i386/debug/serial.c 2011-08-26 14:13:45 UTC (rev 368) +++ src/kernel/i386/debug/serial.c 2011-08-31 03:52:28 UTC (rev 369) @@ -20,7 +20,7 @@ #define UART_DIVISOR_LATCH_LOW 0 #define UART_DIVISOR_LATCH_HIGH 1 -#define UART_RW_TIMEOUT 100 +#define UART_RW_TIMEOUT 10000 #define MAX_SERIAL_PORTS 4 int LegacySerialPorts[MAX_SERIAL_PORTS]={0x3F8, 0x2F8, 0x3E8, 0x2E8}; Modified: src/kernel/i386/exception.c =================================================================== --- src/kernel/i386/exception.c 2011-08-26 14:13:45 UTC (rev 368) +++ src/kernel/i386/exception.c 2011-08-31 03:52:28 UTC (rev 369) @@ -11,6 +11,7 @@ #include <kernel/pm/elf.h> #include <kernel/pm/thread.h> #include <kernel/i386/i386.h> +#include <kernel/pm/pm_types.h> /*max depth of page faults inside page fault*/ #define MAX_SERIAL_PAGE_FAULTS 2 @@ -119,11 +120,11 @@ { VADDR new_va; va = PAGE_ALIGN(va); - new_va = MapPhysicalMemory( GetCurrentVirtualMap(), va, PAGE_SIZE, va, PROT_READ | PROT_WRITE ); + new_va = MapPhysicalMemory( GetCurrentVirtualMap(), va, PAGE_SIZE, va, PROT_READ | PROT_WRITE); if ( new_va != va ) { FreeVirtualMemory(GetCurrentVirtualMap(), va, PAGE_SIZE, 0); - CreatePhysicalMapping(GetCurrentVirtualMap()->physical_map, va, va, PROT_READ | PROT_WRITE ); + CreatePhysicalMapping(GetCurrentVirtualMap()->physical_map, va, va, PROT_READ | PROT_WRITE); } goto done; } @@ -211,11 +212,11 @@ /*create translations for all things that we might touch*/ if( TranslatePaFromVa((UINT32)ivt, &pa) == VA_NOT_EXISTS ) - CreatePhysicalMapping( GetCurrentVirtualMap()->physical_map, (UINT32)ivt, (UINT32)ivt, PROT_READ|PROT_WRITE ); + CreatePhysicalMapping( GetCurrentVirtualMap()->physical_map, (UINT32)ivt, (UINT32)ivt, PROT_READ | PROT_WRITE); if( TranslatePaFromVa((UINT32)stack, &pa) == VA_NOT_EXISTS ) - CreatePhysicalMapping( GetCurrentVirtualMap()->physical_map, (UINT32)stack, (UINT32)stack, PROT_READ|PROT_WRITE ); + CreatePhysicalMapping( GetCurrentVirtualMap()->physical_map, (UINT32)stack, (UINT32)stack, PROT_READ | PROT_WRITE); if( TranslatePaFromVa((UINT32)stack32, &pa) == VA_NOT_EXISTS ) - CreatePhysicalMapping( GetCurrentVirtualMap()->physical_map, (UINT32)stack32, (UINT32)stack32, PROT_READ|PROT_WRITE ); + CreatePhysicalMapping( GetCurrentVirtualMap()->physical_map, (UINT32)stack32, (UINT32)stack32, PROT_READ | PROT_WRITE); while (TRUE) { Modified: src/kernel/i386/mm/pmem.c =================================================================== --- src/kernel/i386/mm/pmem.c 2011-08-26 14:13:45 UTC (rev 368) +++ src/kernel/i386/mm/pmem.c 2011-08-31 03:52:28 UTC (rev 369) @@ -12,6 +12,8 @@ #include <kernel/mm/pmem.h> #include <kernel/i386/pmem.h> +VM_UNIT_PTR kernel_pte_vm_unit=NULL; + /*! Checks whether the given VA is kernel VA or user VA*/ #define IS_KERNEL_ADDRESS(va) (va >= KERNEL_VIRTUAL_ADDRESS_START) @@ -34,7 +36,10 @@ PHYSICAL_MAP_PTR CreatePhysicalMap(VIRTUAL_MAP_PTR vmap) { PHYSICAL_MAP_PTR pmap; + VADDR pte_va_start; UINT32 page_dir_pa; + UINT32 pte_va_size; + VM_UNIT_PTR user_pte_vm_unit; pmap = AllocateBuffer( &physical_map_cache, CACHE_ALLOC_SLEEP ); if ( pmap == NULL ) @@ -52,12 +57,36 @@ /*set the self mapping*/ if ( TranslatePaFromVa( (VADDR )pmap->page_directory, &page_dir_pa ) == VA_NOT_EXISTS ) + { panic("pagedirectory is not in memory"); + } + pmap->page_directory[PT_SELF_MAP_INDEX].all = (page_dir_pa | KERNEL_PTE_FLAG); + /*Create vmdescriptor for user PageTable VAs*/ + pte_va_size = PAGE_SIZE * 754; + pte_va_start = PT_SELF_MAP_ADDRESS; + user_pte_vm_unit = CreateVmUnit(VM_UNIT_TYPE_PTE, VM_UNIT_FLAG_PRIVATE, pte_va_size); + CreateVmDescriptor(vmap, pte_va_start, pte_va_start + pte_va_size, user_pte_vm_unit, &protection_kernel_write); + + /*Create vmdescriptor for user PageTable VAs*/ + pte_va_start = PT_SELF_MAP_ADDRESS + pte_va_start; + pte_va_size = PAGE_SIZE * 260; + CreateVmDescriptor(vmap, pte_va_start, pte_va_start + pte_va_size, kernel_pte_vm_unit, &protection_kernel_write); + return pmap; } +void MapKernelPageTableEntries() +{ + UINT32 size; + + size = PAGE_SIZE * 1024; + /*map page tables*/ + kernel_pte_vm_unit = CreateVmUnit(VM_UNIT_TYPE_PTE, VM_UNIT_FLAG_PRIVATE, size); + CreateVmDescriptor(&kernel_map, PT_SELF_MAP_ADDRESS, PT_SELF_MAP_ADDRESS + size, kernel_pte_vm_unit, &protection_kernel_write); +} + /*! Fills page table entry for a given VA. This function makes the corresponding VA to point to PA by filling PTEs. this function can be also called to change the protection. \param pmap - physical map @@ -224,7 +253,13 @@ PAGE_DIRECTORY_ENTRY_PTR page_dir; VADDR page_table_va; UINT32 pa; + VIRTUAL_PAGE_PTR vp; + VM_DESCRIPTOR_PTR vd; + UINT32 vtop_index; + assert(GetCurrentVirtualMap()->physical_map == pmap); + assert(GetCurrentVirtualMap() == pmap->virtual_map); + page_dir = pmap->page_directory; pd_index = PAGE_DIRECTORY_ENTRY_INDEX(va); @@ -235,8 +270,14 @@ } /*allocate page table*/ - pa = AllocatePageTable(); + vp = AllocateVirtualPages(1, VIRTUAL_PAGE_RANGE_TYPE_NORMAL); + assert ( vp != NULL ); + vd = GetVmDescriptor(pmap->virtual_map, va, 1); + vtop_index = ((va - vd->start) / PAGE_SIZE) + (vd->offset_in_unit/PAGE_SIZE); + SetVmUnitPage(vd->unit, vp, vtop_index); + pa = vp->physical_address; + /*enter pde*/ page_dir[pd_index].all = pa | USER_PDE_FLAG; Modified: src/kernel/i386/mm/pmem_init.c =================================================================== --- src/kernel/i386/mm/pmem_init.c 2011-08-26 14:13:45 UTC (rev 368) +++ src/kernel/i386/mm/pmem_init.c 2011-08-31 03:52:28 UTC (rev 369) @@ -472,6 +472,7 @@ /*initialize the kernel physical map*/ InitSpinLock( &kernel_physical_map.lock ); kernel_physical_map.page_directory = kernel_page_directory; + kernel_physical_map.virtual_map = &kernel_map; /*initialize the virtual page array*/ for(i=0; i<memory_area_count; i++ ) Modified: src/kernel/main.c =================================================================== --- src/kernel/main.c 2011-08-26 14:13:45 UTC (rev 368) +++ src/kernel/main.c 2011-08-31 03:52:28 UTC (rev 369) @@ -93,7 +93,7 @@ //InitGraphicsConsole(); - //CreateTask("/boot/app/hello.exe", IMAGE_TYPE_ELF_FILE, TASK_CREATION_FLAG_NONE, NULL, "hello.exe", "TEST=TS"); + CreateTask("/boot/app/hello.exe", IMAGE_TYPE_ELF_FILE, TASK_CREATION_FLAG_NONE, NULL, "hello.exe", "TEST=TS"); CreateTask("/boot/app/bash", IMAGE_TYPE_ELF_FILE, TASK_CREATION_FLAG_NONE, NULL, "bash -i", "ees=33"); Modified: src/kernel/mm/vm.c =================================================================== --- src/kernel/mm/vm.c 2011-08-26 14:13:45 UTC (rev 368) +++ src/kernel/mm/vm.c 2011-08-31 03:52:28 UTC (rev 369) @@ -24,7 +24,6 @@ VM_PROTECTION protection_all_write = {1,1,1,1}; VM_PROTECTION protection_all_read = {0,1,0,1}; - KERNEL_RESERVE_RANGE kernel_reserve_range; /*from kernel.ld*/ @@ -87,7 +86,7 @@ MapKernel(); /*map kmem*/ - vm_unit = CreateVmUnit( VM_UNIT_TYPE_KERNEL, VM_UNIT_FLAG_PRIVATE, kernel_reserve_range.kmem_va_end - kernel_reserve_range.kmem_va_start); + vm_unit = CreateVmUnit(VM_UNIT_TYPE_KERNEL, VM_UNIT_FLAG_PRIVATE, kernel_reserve_range.kmem_va_end - kernel_reserve_range.kmem_va_start); CreateVmDescriptor(&kernel_map, kernel_reserve_range.kmem_va_start, kernel_reserve_range.kmem_va_end, vm_unit, &protection_kernel_write); } @@ -135,6 +134,8 @@ vd = CreateVmDescriptor(&kernel_map, kernel_reserve_range.string_va_start, kernel_reserve_range.string_va_end, vm_unit, &protection_kernel_write); InitKernelDescriptorVtoP(vd, kernel_reserve_range.string_va_start, kernel_reserve_range.string_va_end, kernel_reserve_range.string_pa_start ); } + + MapKernelPageTableEntries(); return ERROR_SUCCESS; } @@ -519,6 +520,7 @@ if ( is_user_mode ) { kprintf("User VA %p not found - kill it\n", va); + PrintVmDescriptors(virtual_map); /*\todo - kill the process*/ return ERROR_NOT_FOUND; } @@ -530,6 +532,7 @@ goto retry; } kprintf("Kernel memory fault - va = %p virtual_map = %p\n", va, virtual_map); + PrintVmDescriptors(virtual_map); /*! if the faulting va is kernel va and the kernel map doesnt have descriptor panic*/ return ERROR_NOT_FOUND; } @@ -547,7 +550,7 @@ else { /*if the page is backed by file, get it from file system*/ - if( vd->unit->type == VM_UNIT_TYPE_FILE_MAPPED ) + if ( vd->unit->type == VM_UNIT_TYPE_FILE_MAPPED ) { UINT32 file_offset; assert(vd->unit->vnode!=NULL); @@ -573,8 +576,7 @@ panic("Kernel resource shortage"); } } - vd->unit->page_count++; - vd->unit->vtop_array[vtop_index].vpage = (VIRTUAL_PAGE_PTR) ( ((VADDR)vp) | 1 ); + SetVmUnitPage(vd->unit, vp, vtop_index); } CreatePhysicalMapping(virtual_map->physical_map, va, vp->physical_address, vd->protection); Modified: src/kernel/mm/vm_descriptor.c =================================================================== --- src/kernel/mm/vm_descriptor.c 2011-08-26 14:13:45 UTC (rev 368) +++ src/kernel/mm/vm_descriptor.c 2011-08-31 03:52:28 UTC (rev 369) @@ -26,6 +26,7 @@ static COMPARISION_RESULT compare_vm_descriptor(struct binary_tree * node1, struct binary_tree * node2); static void * FindVaRange(VM_DESCRIPTOR_PTR descriptor_ptr, VADDR start, UINT32 size, int top_down_search, VADDR last_va_end); static int enumerate_descriptor_callback(AVL_TREE_PTR node, void * arg); +static int enumerate_printvmdescriptor_callback(AVL_TREE_PTR node, void * arg); CACHE vm_descriptor_cache; @@ -161,8 +162,10 @@ search_descriptor.end = search_descriptor.start + size-1; ret = SearchAvlTree(vmap->descriptors, &(search_descriptor.tree_node), compare_vm_descriptor_with_va); if ( ret ) - vm_descriptor = STRUCT_ADDRESS_FROM_MEMBER( ret, VM_DESCRIPTOR, tree_node ); - + { + vm_descriptor = STRUCT_ADDRESS_FROM_MEMBER( ret, VM_DESCRIPTOR, tree_node ); + } + return vm_descriptor; } @@ -275,3 +278,22 @@ return 0; } +/*! Print all vm descriptor associated with a vmmap + \param vmap - vmap to print +*/ +void PrintVmDescriptors(VIRTUAL_MAP_PTR vmap) +{ + EnumerateAvlTree(vmap->descriptors, enumerate_printvmdescriptor_callback, NULL); +} + +/*! Enumerator - call back function used by PrintVmDescriptors() + \param node - AVL tree node(vm descriptor) +*/ +static int enumerate_printvmdescriptor_callback(AVL_TREE_PTR node, void * arg) +{ + VM_DESCRIPTOR_PTR descriptor = STRUCT_ADDRESS_FROM_MEMBER(node, VM_DESCRIPTOR, tree_node); + + kprintf("%p - %p %p %c 0x%x\n", descriptor->start, descriptor->end, descriptor->unit, (descriptor->protection & PROT_WRITE ? 'W' : (descriptor->protection & PROT_READ ? 'R' : 'N')), descriptor->offset_in_unit ); + + return 0; +} Modified: src/kernel/mm/vm_unit.c =================================================================== --- src/kernel/mm/vm_unit.c 2011-08-26 14:13:45 UTC (rev 368) +++ src/kernel/mm/vm_unit.c 2011-08-31 03:52:28 UTC (rev 369) @@ -73,3 +73,12 @@ /*\todo remove the pages here*/ } } + +void SetVmUnitPage(VM_UNIT_PTR unit, VIRTUAL_PAGE_PTR vp, UINT32 vtop_index) +{ + assert( unit != NULL ); + assert( vtop_index <= unit->size / PAGE_SIZE ); + + unit->page_count++; + unit->vtop_array[vtop_index].vpage = (VIRTUAL_PAGE_PTR) ( ((VADDR)vp) | 1 ); +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sam...@us...> - 2011-08-26 14:13:54
|
Revision: 368 http://aceos.svn.sourceforge.net/aceos/?rev=368&view=rev Author: samueldotj Date: 2011-08-26 14:13:45 +0000 (Fri, 26 Aug 2011) Log Message: ----------- Committing a few long pending patches: Added bash to bootcd image All device drivers will by default use DO_BUFFERED_IO Added skeleton of console driver.c Added timeout handling in reading/writing on UART Added ReadWriteDevice Fixed a bug in MapPhysicalMemory Modified Paths: -------------- scripts/create_bootcd.sh src/drivers/acpi/acpi.c src/drivers/pci/pci.c src/drivers/ps2keyboard/keyboard.c src/drivers/wscript_build src/include/kernel/debug.h src/include/kernel/iom/devfs.h src/include/kernel/iom/iom.h src/include/kernel/mm/vm.h src/include/kernel/pm/task.h src/include/kernel/pm/thread.h src/include/kernel/vfs/vfs.h src/kernel/driver_id.txt src/kernel/i386/debug/ktrace.c src/kernel/i386/debug/serial.c src/kernel/i386/mm/pmem.c src/kernel/i386/mm/pmem_init.c src/kernel/iom/devfs.c src/kernel/iom/driver.c src/kernel/iom/iom.c src/kernel/iom/irp.c src/kernel/iom/rootbus.c src/kernel/kprintf.c src/kernel/ktrace.c src/kernel/main.c src/kernel/mm/virtual_page.c src/kernel/mm/vm.c src/kernel/mm/vm_descriptor.c src/kernel/pm/elf.c src/kernel/pm/task.c src/kernel/pm/thread.c src/kernel/syscall/file.c src/kernel/syscall/terminal.c src/kernel/syscall/time.c src/kernel/vfs/boot_fs.c src/kernel/vfs/ubc.c src/kernel/vfs/vfs.c src/kernel/vfs/vnode.c src/kernel/wait_event.c Added Paths: ----------- src/drivers/console/ src/drivers/console/console.c Modified: scripts/create_bootcd.sh =================================================================== --- scripts/create_bootcd.sh 2009-06-10 10:50:58 UTC (rev 367) +++ scripts/create_bootcd.sh 2011-08-26 14:13:45 UTC (rev 368) @@ -16,9 +16,11 @@ mkdir -p $BUILD_DIR/bootfs/app mkdir -p $BUILD_DIR/bootfs/drivers cp $ACE_ROOT/src/kernel/driver_id.txt $BUILD_DIR/bootfs +cp /usr/src/build-bash/bash $BUILD_DIR/bootfs/app cp $BUILD_DIR/app/hello.exe $BUILD_DIR/bootfs/app cp $BUILD_DIR/drivers/pci_bus.sys $BUILD_DIR/bootfs/drivers cp $BUILD_DIR/drivers/acpi.sys $BUILD_DIR/bootfs/drivers +cp $BUILD_DIR/drivers/console.sys $BUILD_DIR/bootfs/drivers cp $BUILD_DIR/drivers/ps2keyboard.sys $BUILD_DIR/bootfs/drivers cd $BUILD_DIR/bootfs tar --gzip -cf $ISO_DIR/boot_modules.mod.gz . Modified: src/drivers/acpi/acpi.c =================================================================== --- src/drivers/acpi/acpi.c 2009-06-10 10:50:58 UTC (rev 367) +++ src/drivers/acpi/acpi.c 2011-08-26 14:13:45 UTC (rev 368) @@ -28,7 +28,7 @@ { DEVICE_OBJECT_PTR device_object; ERROR_CODE err; - err = CreateDevice(pDriverObject, sizeof(ACPI_BUS_DEVICE_EXTENSION), &device_object, NULL); + err = CreateDevice(pDriverObject, sizeof(ACPI_BUS_DEVICE_EXTENSION), &device_object, "ACPI", DO_BUFFERED_IO); if( err != ERROR_SUCCESS ) return err; InvalidateDeviceRelations(device_object, DEVICE_RELATIONS_TYPE_BUS_RELATION); @@ -67,7 +67,7 @@ if ( ret == AE_OK && dev_info_ptr->Valid & ACPI_VALID_HID ) { DEVICE_OBJECT_PTR child_device_object; - if ( CreateDevice(arg->device_object->driver_object, sizeof(ACPI_BUS_DEVICE_EXTENSION), &child_device_object, NULL) == ERROR_SUCCESS ) + if ( CreateDevice(arg->device_object->driver_object, sizeof(ACPI_BUS_DEVICE_EXTENSION), &child_device_object, NULL, DO_BUFFERED_IO) == ERROR_SUCCESS ) { ACPI_BUS_DEVICE_EXTENSION_PTR device_ext=child_device_object->device_extension; device_ext->handle = ObjHandle; Added: src/drivers/console/console.c =================================================================== --- src/drivers/console/console.c (rev 0) +++ src/drivers/console/console.c 2011-08-26 14:13:45 UTC (rev 368) @@ -0,0 +1,81 @@ +/*! + \file drivers/console/console.c + \brief i386 console driver - keyboard and text mode video +*/ +#include <ace.h> +#include <string.h> +#include <kernel/io.h> +#include <kernel/error.h> +#include <kernel/iom/iom.h> +#include <kernel/interrupt.h> +#include <kernel/debug.h> + + +static ERROR_CODE AddDevice(DRIVER_OBJECT_PTR drv_obj, DEVICE_OBJECT_PTR parent_dev_obj); +static ERROR_CODE MajorFunctionPnP(DEVICE_OBJECT_PTR dev_obj, IRP_PTR irp); +static ERROR_CODE MajorFunctionRead(DEVICE_OBJECT_PTR dev_obj, IRP_PTR irp); +static ERROR_CODE MajorFunctionWrite(DEVICE_OBJECT_PTR dev_obj, IRP_PTR irp); + +/*! Entry point - called during driver initialization + * \param drv_obj Driver object pointer which should be initialised + * Returns standard error code. + */ +ERROR_CODE DriverEntry(DRIVER_OBJECT_PTR drv_obj) +{ + KPRINTF("called"); + strcpy( drv_obj->driver_name, "console" ); + drv_obj->driver_extension = NULL; + drv_obj->fn.AddDevice = AddDevice; + drv_obj->fn.MajorFunctions[IRP_MJ_READ] = MajorFunctionRead; + drv_obj->fn.MajorFunctions[IRP_MJ_WRITE] = MajorFunctionWrite; + drv_obj->fn.MajorFunctions[IRP_MJ_PNP] = MajorFunctionPnP; + + KTRACE("called"); + + return ERROR_SUCCESS; +} + +/*! + * \brief Adds a new device to the device hierarchy and binds the device with the given driver. + * \param drv_obj Driver object to which the new device must be associated. + * \param parent_dev_obj Device object's parent pointer. + * Returns a standard error code + */ +static ERROR_CODE AddDevice(DRIVER_OBJECT_PTR drv_obj, DEVICE_OBJECT_PTR parent_dev_obj) +{ + DEVICE_OBJECT_PTR dev_obj; + ERROR_CODE err; + + err = CreateDevice(drv_obj, 0, &dev_obj, "Console", DO_BUFFERED_IO); + KTRACE("console device object %p\n", dev_obj); + if( err != ERROR_SUCCESS ) + return err; + + /* Now establish the hierarchy between parent_dev_obj and dev_obj */ + (void)AttachDeviceToDeviceStack(dev_obj, parent_dev_obj); + + return ERROR_SUCCESS; +} + +/*! Function to handle all Plug and play activities associated with keyboard. + * \param dev_obj Device for which request is made. + * \param irp Interrupt request packet pointer containing user request details + * Returns SUCCESS if request can be processed or else suitable failure code is returned. + */ +static ERROR_CODE MajorFunctionPnP(DEVICE_OBJECT_PTR dev_obj, IRP_PTR irp) +{ + KTRACE("PNP func called"); + return ERROR_SUCCESS; +} + +static ERROR_CODE MajorFunctionRead(DEVICE_OBJECT_PTR dev_obj, IRP_PTR irp) +{ + KTRACE("Read called"); + return ERROR_SUCCESS; +} +static ERROR_CODE MajorFunctionWrite(DEVICE_OBJECT_PTR dev_obj, IRP_PTR irp) +{ + KTRACE("Write called"); + return ERROR_SUCCESS; +} + Modified: src/drivers/pci/pci.c =================================================================== --- src/drivers/pci/pci.c 2009-06-10 10:50:58 UTC (rev 367) +++ src/drivers/pci/pci.c 2011-08-26 14:13:45 UTC (rev 368) @@ -98,7 +98,7 @@ { DEVICE_OBJECT_PTR device_object; ERROR_CODE err; - err = CreateDevice(pDriverObject, sizeof(PCI_BUS_DEVICE_EXTENSION), &device_object, NULL); + err = CreateDevice(pDriverObject, sizeof(PCI_BUS_DEVICE_EXTENSION), &device_object, "pci_bus", DO_BUFFERED_IO ); if( err != ERROR_SUCCESS ) return err; InvalidateDeviceRelations(device_object, DEVICE_RELATIONS_TYPE_BUS_RELATION); @@ -134,7 +134,7 @@ char *class_name, *subclass_name, *prog_if_name; get_pci_class_string(pci_conf.base_class_code, pci_conf.sub_class_code, pci_conf.programming_interface, &class_name, &subclass_name, &prog_if_name ); //kprintf("%x %x %s %s %s\n", pci_conf.vendor_id, pci_conf.device_id, class_name, subclass_name, prog_if_name ); - if ( CreateDevice(pDeviceObject->driver_object, sizeof(PCI_BUS_DEVICE_EXTENSION), &child_device_object, NULL) == ERROR_SUCCESS ) + if ( CreateDevice(pDeviceObject->driver_object, sizeof(PCI_BUS_DEVICE_EXTENSION), &child_device_object, NULL, DO_BUFFERED_IO) == ERROR_SUCCESS ) { PCI_BUS_DEVICE_EXTENSION_PTR device_ext=child_device_object->device_extension; memcpy(&device_ext->pci_conf, &pci_conf, sizeof(PCI_CONFIGURATION_SPACE) ); Modified: src/drivers/ps2keyboard/keyboard.c =================================================================== --- src/drivers/ps2keyboard/keyboard.c 2009-06-10 10:50:58 UTC (rev 367) +++ src/drivers/ps2keyboard/keyboard.c 2011-08-26 14:13:45 UTC (rev 368) @@ -142,7 +142,7 @@ DEVICE_OBJECT_PTR dev_obj; ERROR_CODE err; - err = CreateDevice(drv_obj, 0, &dev_obj, NULL); + err = CreateDevice(drv_obj, 0, &dev_obj, "keyboard", DO_BUFFERED_IO); if( err != ERROR_SUCCESS ) return err; Modified: src/drivers/wscript_build =================================================================== --- src/drivers/wscript_build 2009-06-10 10:50:58 UTC (rev 367) +++ src/drivers/wscript_build 2011-08-26 14:13:45 UTC (rev 368) @@ -17,3 +17,8 @@ ps2keyboard = bld.new_task_gen('cc', 'program', target='ps2keyboard', name='ps2keyboard', install_path=None, includes=include_dirs, uselib='DRIVER' ) ps2keyboard.env['program_PATTERN'] = '%s.sys' ps2keyboard.find_sources_in_dirs('ps2keyboard') + +#build console driver +console = bld.new_task_gen('cc', 'program', target='console', name='console', install_path=None, includes=include_dirs, uselib='DRIVER' ) +console.env['program_PATTERN'] = '%s.sys' +console.find_sources_in_dirs('console') Modified: src/include/kernel/debug.h =================================================================== --- src/include/kernel/debug.h 2009-06-10 10:50:58 UTC (rev 367) +++ src/include/kernel/debug.h 2011-08-26 14:13:45 UTC (rev 368) @@ -17,15 +17,15 @@ #ifdef __KERNEL_TRACE__ #define KTRACE( ... ) \ - ktrace("%s:%d:%s(): ", __FILE__ , __LINE__,__PRETTY_FUNCTION__ ); \ - ktrace( __VA_ARGS__ ); + ktrace("%s:%d:%s(): ", __FILE__, __LINE__, __PRETTY_FUNCTION__); \ + ktrace(__VA_ARGS__); #else #define KTRACE( ... ) #endif #define KPRINTF( ... ) \ - kprintf("%s:%d: ", __PRETTY_FUNCTION__ , __LINE__ ); \ - kprintf( __VA_ARGS__ ); + kprintf("%s:%d: ", __PRETTY_FUNCTION__ , __LINE__); \ + kprintf(__VA_ARGS__); #ifdef __cplusplus extern "C" { Modified: src/include/kernel/iom/devfs.h =================================================================== --- src/include/kernel/iom/devfs.h 2009-06-10 10:50:58 UTC (rev 367) +++ src/include/kernel/iom/devfs.h 2011-08-26 14:13:45 UTC (rev 368) @@ -30,6 +30,7 @@ #endif ERROR_CODE CreateDeviceNode(const char * filename, DEVICE_OBJECT_PTR device); +ERROR_CODE ReadWriteDevice(DEVICE_OBJECT_PTR device_object, void * user_buffer, long offset, long length, int is_write, int * result_count, IO_COMPLETION_ROUTINE completion_rountine, void * completion_rountine_context); #ifdef __cplusplus } Modified: src/include/kernel/iom/iom.h =================================================================== --- src/include/kernel/iom/iom.h 2009-06-10 10:50:58 UTC (rev 367) +++ src/include/kernel/iom/iom.h 2011-08-26 14:13:45 UTC (rev 368) @@ -22,6 +22,21 @@ typedef enum { + DO_BUFFERED_IO = 1, + DO_DIRECT_IO = 2, + DO_NEITHER_IO = 4, +}DO_FLAG; + + +typedef enum +{ + IRP_COMPLETION_INVOKE_ON_SUCCESS=1, + IRP_COMPLETION_INVOKE_ON_ERROR=2, + IRP_COMPLETION_INVOKE_ON_CANCEL=4, +}IRP_COMPLETION_INVOKE; + +typedef enum +{ IRP_MJ_CREATE = 0, IRP_MJ_CLOSE, IRP_MJ_READ, @@ -89,13 +104,13 @@ struct driver_functions { - ERROR_CODE (*DriverEntry)(DRIVER_OBJECT_PTR pDriverObject); /*! Called to initialize a driver - called only once*/ - ERROR_CODE (*DriverUnload)(DRIVER_OBJECT_PTR pDriverObject); /*! Called to destroy driver - called during driver exit*/ + ERROR_CODE (*DriverEntry)(DRIVER_OBJECT_PTR pDriverObject); /*! Called to initialize a driver - called only once*/ + ERROR_CODE (*DriverUnload)(DRIVER_OBJECT_PTR pDriverObject); /*! Called to destroy driver - called during driver exit*/ + + ERROR_CODE (*AddDevice)(DRIVER_OBJECT_PTR pDriverObject, DEVICE_OBJECT_PTR pPdo); /*! When a appropriate device is found this function is called*/ - ERROR_CODE (*AddDevice)(DRIVER_OBJECT_PTR pDriverObject, DEVICE_OBJECT_PTR pPdo); /*! When a appropriate device is found this function is called*/ - - ERROR_CODE (*StartIo)(DEVICE_OBJECT_PTR pDeviceObject, IRP_PTR pIrp); /*! Called to start IO on a device*/ - ERROR_CODE (*MajorFunctions[IRP_MJ_MAXIMUM_FUNCTION]) (DEVICE_OBJECT_PTR pDeviceObject, IRP_PTR pIrp); /*! Various functions supported by the device*/ + ERROR_CODE (*StartIo)(DEVICE_OBJECT_PTR pDeviceObject, IRP_PTR pIrp); /*! Called to start IO on a device*/ + ERROR_CODE (*MajorFunctions[IRP_MJ_MAXIMUM_FUNCTION]) (DEVICE_OBJECT_PTR pDeviceObject, IRP_PTR pIrp); /*! Various functions supported by the device*/ }; struct driver_object @@ -118,6 +133,8 @@ SPIN_LOCK lock; /*! For mp sync*/ int reference_count; /*! For garbage collection*/ + UINT32 flags; /*! flags of object - buffered io/direct io etc*/ + DEVICE_OBJECT_PTR parent_device; /*! parent device - may be bus device*/ LIST sibilings_list; /*! list of devices that are created by the same parent*/ DEVICE_OBJECT_PTR child_device; /*! pointer to the first child*/ @@ -138,7 +155,13 @@ struct irp { UINT32 flags; - + + /*addresses used during read, write and ioctl calls + * \todo - try to put the following things in a union*/ + void * user_buffer; /*! user buffer address - driver has to take care of locking and translating the page to kernel address - valid in DO_NEITHER_IO*/ + void * mdl_address; /*! memory page descriptor list - iom will lock user buffer and create a list of pages associated with the buffer - valid in DO_DIRECT_IO*/ + void * system_buffer; /*! system buffer address - iom will allocate kernel memory and copy the user buffer content here - valid in DO_BUFFERED_IO */ + IO_STATUS_BLOCK io_status; /*! Status of the IRP*/ BYTE stack_count; /*! Total IO_STACK associated with this IRP*/ @@ -164,8 +187,8 @@ }create; struct { - UINT32 length; - UINT32 byte_offset; + UINT32 length; /*! length of data to read/write*/ + UINT32 byte_offset; /*! offset to start the read/write*/ }read_write; struct { @@ -175,15 +198,15 @@ }device_io_control; struct { - DEVICE_RELATION_TYPE type; + DEVICE_RELATION_TYPE type; /*! input from iom - type of relation to reterive - currenly it is only bus*/ }query_device_relations; struct { - QUERY_ID_TYPE id_type; + QUERY_ID_TYPE id_type; /*! input from iom - id to reterive - hardware, instance*/ }query_id; struct { - DEVICE_CAPABILITIES_PTR device_capabilities; + DEVICE_CAPABILITIES_PTR device_capabilities; /*! output from driver - capability of the device*/ }capabilities; }parameters; @@ -191,6 +214,7 @@ IO_COMPLETION_ROUTINE completion_routine; /*! Completion routine registered by the driver*/ void * context; /*! Context to passed driver completion routine*/ + IRP_COMPLETION_INVOKE invoke_on; /*! when to invoke the completion routine*/ }; struct device_capabilities{ @@ -205,21 +229,21 @@ struct { - UINT32 device_d1:1; /*! Specifies whether the device hardware supports the D1 power state.*/ - UINT32 device_d2:1; /*! Specifies whether the device hardware supports the D2 power state.*/ - UINT32 wake_from_d0:1; /*! Specifies whether the device can respond to an external wake signal while in the D0 state.*/ - UINT32 wake_from_d1:1; /*! Specifies whether the device can respond to an external wake signal while in the D1 state.*/ - UINT32 wake_from_d2:1; /*! Specifies whether the device can respond to an external wake signal while in the D2 state.*/ - UINT32 wake_from_d3:1; /*! Specifies whether the device can respond to an external wake signal while in the D3 state.*/ - UINT32 d1_latency; - UINT32 d2_latency; - UINT32 d3_latency; + UINT32 device_d1:1; /*! Specifies whether the device hardware supports the D1 power state.*/ + UINT32 device_d2:1; /*! Specifies whether the device hardware supports the D2 power state.*/ + UINT32 wake_from_d0:1; /*! Specifies whether the device can respond to an external wake signal while in the D0 state.*/ + UINT32 wake_from_d1:1; /*! Specifies whether the device can respond to an external wake signal while in the D1 state.*/ + UINT32 wake_from_d2:1; /*! Specifies whether the device can respond to an external wake signal while in the D2 state.*/ + UINT32 wake_from_d3:1; /*! Specifies whether the device can respond to an external wake signal while in the D3 state.*/ + UINT32 d1_latency; + UINT32 d2_latency; + UINT32 d3_latency; }power; }; struct device_relations{ - UINT32 count; - DEVICE_OBJECT_PTR objects[0]; + UINT32 count; /*! total number of devices in the objects array*/ + DEVICE_OBJECT_PTR objects[0]; /*! array of child device objects*/ }; extern DEVICE_OBJECT_PTR root_bus_device_object; @@ -230,7 +254,7 @@ void InitIoManager(); -ERROR_CODE CreateDevice(DRIVER_OBJECT_PTR driver_object, UINT32 device_extension_size, DEVICE_OBJECT_PTR * device_object, char * device_name); +ERROR_CODE CreateDevice(DRIVER_OBJECT_PTR driver_object, UINT32 device_extension_size, DEVICE_OBJECT_PTR * device_object, char * device_name, UINT32 flag); DEVICE_OBJECT_PTR AttachDeviceToDeviceStack(DEVICE_OBJECT_PTR source_device, DEVICE_OBJECT_PTR target_device); void InvalidateDeviceRelations(DEVICE_OBJECT_PTR device_object, DEVICE_RELATION_TYPE type); @@ -238,6 +262,8 @@ IO_STACK_LOCATION_PTR GetCurrentIrpStackLocation(IRP_PTR Irp); inline void FillIoStack(IO_STACK_LOCATION_PTR io_stack, BYTE major_function, BYTE minor_function, DEVICE_OBJECT_PTR device_object, IO_COMPLETION_ROUTINE completion_routine, void * context); +ERROR_CODE SetIrpCompletionRoutine(IRP_PTR irp, IO_COMPLETION_ROUTINE completion_routine, void * context, IRP_COMPLETION_INVOKE invoke_on); + IRP_PTR AllocateIrp(BYTE stack_size); void ReuseIrp(IRP_PTR irp, ERROR_CODE error_code); void FreeIrp(IRP_PTR irp); Modified: src/include/kernel/mm/vm.h =================================================================== --- src/include/kernel/mm/vm.h 2009-06-10 10:50:58 UTC (rev 367) +++ src/include/kernel/mm/vm.h 2011-08-26 14:13:45 UTC (rev 368) @@ -115,7 +115,7 @@ VADDR offset_in_unit; /*! starting offset in the vm unit*/ - VM_PROTECTION protection; /*! protection for this range*/ + UINT32 protection; /*! protection for this range*/ VM_UNIT_PTR unit; /*! pointer to the vm_unit*/ }; @@ -188,6 +188,8 @@ extern VM_PROTECTION protection_kernel_read; extern VM_PROTECTION protection_user_write; extern VM_PROTECTION protection_user_read; +extern VM_PROTECTION protection_all_write; +extern VM_PROTECTION protection_all_read; extern CACHE virtual_map_cache; extern CACHE vm_descriptor_cache; @@ -215,6 +217,9 @@ VADDR MapPhysicalMemory(VIRTUAL_MAP_PTR vmap, UINT32 pa, UINT32 size, VADDR preferred_va, UINT32 protection); +ERROR_CODE CopyFromUserSpace(void * user_va, void * kernel_va, size_t length); +ERROR_CODE CopyToUserSpace(void * user_va, void * kernel_va, size_t length); + VIRTUAL_MAP_PTR GetCurrentVirtualMap(); ERROR_CODE MemoryFaultHandler(UINT32 va, int is_user_mode, int access_type); Modified: src/include/kernel/pm/task.h =================================================================== --- src/include/kernel/pm/task.h 2009-06-10 10:50:58 UTC (rev 367) +++ src/include/kernel/pm/task.h 2011-08-26 14:13:45 UTC (rev 368) @@ -45,8 +45,6 @@ char * kva_environment; /*! kernel virtual address of process environment*/ char * uva_environment; /*! user virtual address of environment - once user va is created kva will be freed*/ - - char * user_scratch; /*! temporary memory to copy kernel content to user*/ }; typedef enum Modified: src/include/kernel/pm/thread.h =================================================================== --- src/include/kernel/pm/thread.h 2009-06-10 10:50:58 UTC (rev 367) +++ src/include/kernel/pm/thread.h 2011-08-26 14:13:45 UTC (rev 368) @@ -67,6 +67,8 @@ MESSAGE_BUFFER ipc_reply_message; /*! buffer to receive reply data*/ void * arch_data; /*! architecture depended data*/ + + char * user_scratch; /*! temporary user-mode mapped address to copy kernel content to user*/ }; /* Modified: src/include/kernel/vfs/vfs.h =================================================================== --- src/include/kernel/vfs/vfs.h 2009-06-10 10:50:58 UTC (rev 367) +++ src/include/kernel/vfs/vfs.h 2011-08-26 14:13:45 UTC (rev 368) @@ -52,8 +52,8 @@ VFS_IPC_GET_FILE_STAT_PATH, /*Ask FS to return file info for given filename. fs_data NULL NULL file path sizeof(file_path) */ VFS_IPC_GET_FILE_STAT_INODE, /*Ask FS to return file info for given vnode. fs_data inode NULL NULL NULL */ VFS_IPC_GET_DIR_ENTRIES, /*Ask FS to return dire entries for given dir. fs_data NULL NULL dir entry param sizeof(dir entry param)*/ - VFS_IPC_READ_FILE, - VFS_IPC_WRITE_FILE, + VFS_IPC_READ_FILE, /*Ask FS to read a file content. fs_data inode offset buffer size */ + VFS_IPC_WRITE_FILE, /*Ask FS to read a file content. fs_data inode offset buffer size */ VFS_IPC_MAP_FILE_PAGE, /*Ask FS to copy file conteent at given va fs_data inode file offset virtual address length of data to copy*/ VFS_IPC_DELETE_FILE, VFS_IPC_MOVE, @@ -140,7 +140,7 @@ UINT32 umask; /*! default permission for new file - set by umask call*/ VNODE_PTR working_directory; /*! current working directory*/ OPEN_FILE_INFO open_file_info[MAX_OPEN_FILE]; /*! max files per process*/ - char bitmap[MAX_OPEN_FILE/8]; /*! bitmap to maintain free open file info*/ + char bitmap[MAX_OPEN_FILE/BITS_PER_BYTE];/*! bitmap to maintain free open file info*/ }; /*! FS fills this datastructures and returns to VFS during VFS_FILE_STAT ipc*/ @@ -216,13 +216,12 @@ ERROR_CODE UnmountFileSystem(char * mount_path); MOUNTED_FILE_SYSTEM_PTR GetMount(char * mount_path); -ERROR_CODE OpenFile(char * file_path, VFS_ACCESS_TYPE access, VFS_OPEN_FLAG open_flag, int * file_id); -ERROR_CODE GetFileSize(int file_id, long * result); -ERROR_CODE CloseFile(int file_id); +ERROR_CODE OpenFile(TASK_PTR task, char * file_path, VFS_ACCESS_TYPE access, VFS_OPEN_FLAG open_flag, int * file_id); +ERROR_CODE GetFileSize(TASK_PTR task, int file_id, long * result); +ERROR_CODE CloseFile(TASK_PTR task, int file_id); ERROR_CODE ReadDirectory(char * directory_path, FILE_STAT_PARAM_PTR buffer, int max_entries, int * total_entries); -ERROR_CODE OpenFile(char * file_path, VFS_ACCESS_TYPE access, VFS_OPEN_FLAG open_flag, int * file_id); -ERROR_CODE CloseFile(int file_id); +ERROR_CODE ReadWriteFile(int file_id, long count, void * buffer, int is_write, UINT32 * result); ERROR_CODE GetVfsMessage(MESSAGE_QUEUE_PTR message_queue, UINT32 wait_time, MESSAGE_TYPE_PTR type, IPC_ARG_TYPE_PTR arg1, IPC_ARG_TYPE_PTR arg2, IPC_ARG_TYPE_PTR arg3, IPC_ARG_TYPE_PTR arg4, IPC_ARG_TYPE_PTR arg5, IPC_ARG_TYPE_PTR arg6); Modified: src/kernel/driver_id.txt =================================================================== --- src/kernel/driver_id.txt 2009-06-10 10:50:58 UTC (rev 367) +++ src/kernel/driver_id.txt 2011-08-26 14:13:45 UTC (rev 368) @@ -2,6 +2,7 @@ #root bus device ids acpi acpi.sys +console console.sys #pnp device ids PNP0A03 pci_bus.sys Modified: src/kernel/i386/debug/ktrace.c =================================================================== --- src/kernel/i386/debug/ktrace.c 2009-06-10 10:50:58 UTC (rev 367) +++ src/kernel/i386/debug/ktrace.c 2011-08-26 14:13:45 UTC (rev 368) @@ -8,9 +8,10 @@ #include <kernel/i386/serial.h> #include <kernel/i386/parallel.h> #include <kernel/i386/vga_text.h> +#include <kernel/mm/pmem.h> #include <kernel/pm/elf.h> -#define KTRACE_PRINT_PARALLEL +//#define KTRACE_PRINT_PARALLEL #define KTRACE_PRINT_SERIAL //#define KTRACE_PRINT_VGA @@ -76,9 +77,12 @@ unsigned int * arguments, eip; int offset; char * func; - if( (UINT32)ebp < PAGE_SIZE || ebp[0] < PAGE_SIZE || ebp[1] < PAGE_SIZE) + if( (UINT32)ebp < PAGE_SIZE || ebp[0] < PAGE_SIZE || ebp[1] < PAGE_SIZE) { return; - + } + if ( TranslatePaFromVa(ebp[0], NULL) == VA_NOT_EXISTS) { + return; + } eip = ebp[1]; /* Unwind to previous stack frame*/ ebp = (unsigned int *)(ebp[0]); Modified: src/kernel/i386/debug/serial.c =================================================================== --- src/kernel/i386/debug/serial.c 2009-06-10 10:50:58 UTC (rev 367) +++ src/kernel/i386/debug/serial.c 2011-08-26 14:13:45 UTC (rev 368) @@ -20,6 +20,8 @@ #define UART_DIVISOR_LATCH_LOW 0 #define UART_DIVISOR_LATCH_HIGH 1 +#define UART_RW_TIMEOUT 100 + #define MAX_SERIAL_PORTS 4 int LegacySerialPorts[MAX_SERIAL_PORTS]={0x3F8, 0x2F8, 0x3E8, 0x2E8}; @@ -67,7 +69,10 @@ /*! Receives and returns a character from the given serial port*/ char SerialReadCharacter(UINT16 wIOBase) { - while (1) + UINT32 timeout; + + timeout = 0; + while (timeout < UART_RW_TIMEOUT) { /*read line status register*/ BYTE in = _inp( wIOBase + UART_LSR ); @@ -76,13 +81,18 @@ { return _inp( wIOBase ); } + timeout++; } + return 0; } /*! Sends the given character to the given serial port*/ void SerialWriteCharacter(UINT16 wIOBase, char ch) { - while (1) + UINT32 timeout; + + timeout = 0; + while (timeout < UART_RW_TIMEOUT) { /*read line status register*/ BYTE in = _inp( wIOBase + UART_LSR ); @@ -92,5 +102,6 @@ _outp( wIOBase, ch ); return; } + timeout++; } } Modified: src/kernel/i386/mm/pmem.c =================================================================== --- src/kernel/i386/mm/pmem.c 2009-06-10 10:50:58 UTC (rev 367) +++ src/kernel/i386/mm/pmem.c 2011-08-26 14:13:45 UTC (rev 368) @@ -76,19 +76,16 @@ assert( pmap != NULL ); - mapped_pte = PT_SELF_MAP_PAGE_TABLE1_PTE(va); - if ( IS_KERNEL_ADDRESS(va) ) - pte.all = KERNEL_PTE_FLAG; - else - pte.all = USER_PTE_FLAG; - - pte.page_pfn = pfn; - + /* VA of PDE */ mapped_pde = &pmap->page_directory[PAGE_DIRECTORY_ENTRY_INDEX(va)]; /*create page table if not present*/ if ( !mapped_pde->present ) + { CreatePageTable( pmap, va ); - + } + + /* VA of PTE */ + mapped_pte = PT_SELF_MAP_PAGE_TABLE1_PTE(va); if ( mapped_pte->present ) { /*if somebody else created this mapping return*/ @@ -107,9 +104,28 @@ { //now mapping should present for the page table assert( mapped_pde->present ); + assert( protection != NULL ); + + /* Set fields in PTE */ + pte.all = 0; + pte.present = 1; + pte.page_pfn = pfn; + if ( protection & PROT_WRITE ) + { + pte.write = 1; + } + if ( IS_KERNEL_ADDRESS(va) ) + { + pte.global = 1; + } else + { + pte.user = 1; + } + + /* Update the page table */ mapped_pte->all = pte.all; + asm volatile("invlpg (%%eax)" : : "a" (va)); } - finish: return ERROR_SUCCESS; @@ -213,12 +229,14 @@ pd_index = PAGE_DIRECTORY_ENTRY_INDEX(va); /*if page table already present do nothing*/ - if ( page_dir[ pd_index ].present ) + if ( page_dir[pd_index].present ) + { return; + } /*allocate page table*/ pa = AllocatePageTable(); - + /*enter pde*/ page_dir[pd_index].all = pa | USER_PDE_FLAG; @@ -226,6 +244,8 @@ page_table_va = PT_SELF_MAP_PAGE_TABLE1(va); assert( page_table_va != NULL ); memset( (void *) page_table_va, 0, PAGE_SIZE); + + asm volatile("invlpg (%%eax)" : : "a" (page_table_va)); } /*! Reports the given virtual address range's status - readable/writeable or mapping not exists \param va - virtual address @@ -272,6 +292,7 @@ { PAGE_DIRECTORY_ENTRY_PTR pde; PAGE_TABLE_ENTRY_PTR pte; + pde = PT_SELF_MAP_PAGE_DIRECTORY_PTR(va); if ( !pde->present ) return VA_NOT_EXISTS; @@ -279,9 +300,14 @@ if ( !pte->present ) return VA_NOT_EXISTS; - *pa = PFN_TO_PA( pte->page_pfn ); + if (pa) + { + *pa = PFN_TO_PA( pte->page_pfn ); + } if ( pte->write ) + { return VA_WRITEABLE; + } return VA_READABLE; } Modified: src/kernel/i386/mm/pmem_init.c =================================================================== --- src/kernel/i386/mm/pmem_init.c 2009-06-10 10:50:58 UTC (rev 367) +++ src/kernel/i386/mm/pmem_init.c 2011-08-26 14:13:45 UTC (rev 368) @@ -20,7 +20,7 @@ static UINT32 InitMemoryArea(MEMORY_AREA_PTR ma_pa, MULTIBOOT_MEMORY_MAP_PTR memory_map_array, int memory_map_count); static void * GetFreePhysicalPage(); static void InitKernelPageDirectory(); -static void EnterKernelPageTableEntry(UINT32 va, UINT32 pa); +static void EnterKernelPageTableEntry(UINT32 va, UINT32 pa, UINT32 prot); /*the following contains where kernel code/data physical address start and end*/ UINT32 kernel_physical_address_start=KERNEL_PHYSICAL_ADDRESS_LOAD, kernel_physical_address_end=0; @@ -325,9 +325,9 @@ do { /*identity map*/ - EnterKernelPageTableEntry(physical_address, physical_address); + EnterKernelPageTableEntry(physical_address, physical_address, PROT_READ | PROT_WRITE); /*kernel code/data and also below 0 MB mapping*/ - EnterKernelPageTableEntry(va, physical_address); + EnterKernelPageTableEntry(va, physical_address, PROT_READ | PROT_WRITE); physical_address += PAGE_SIZE; va += PAGE_SIZE; }while( physical_address < end_physical_address ); @@ -341,7 +341,7 @@ *((VADDR *)BOOT_ADDRESS( &kernel_reserve_range.module_va_start ) ) = va; do { - EnterKernelPageTableEntry(va, physical_address); + EnterKernelPageTableEntry(va, physical_address, PROT_READ); physical_address += PAGE_SIZE; va += PAGE_SIZE; }while( physical_address < end_physical_address ); @@ -361,7 +361,7 @@ end_physical_address = PAGE_ALIGN_UP( * ((UINT32 *)BOOT_ADDRESS ( &kernel_reserve_range.symbol_pa_end ) ) ); do { - EnterKernelPageTableEntry(va, physical_address); + EnterKernelPageTableEntry(va, physical_address, PROT_READ); physical_address += PAGE_SIZE; va += PAGE_SIZE; }while( physical_address < end_physical_address ); @@ -380,7 +380,7 @@ end_physical_address = PAGE_ALIGN_UP( *((UINT32 *)BOOT_ADDRESS( &kernel_reserve_range.string_pa_end)) ); do { - EnterKernelPageTableEntry(va, physical_address); + EnterKernelPageTableEntry(va, physical_address, PROT_READ); physical_address += PAGE_SIZE; va += PAGE_SIZE; }while( physical_address < end_physical_address ); @@ -401,7 +401,7 @@ pmr_pa->virtual_page_array = (VIRTUAL_PAGE_PTR)va; do { - EnterKernelPageTableEntry( va, physical_address); + EnterKernelPageTableEntry( va, physical_address, PROT_READ | PROT_WRITE); physical_address += PAGE_SIZE; va += PAGE_SIZE; }while( physical_address < ( end_address ) ); @@ -425,7 +425,7 @@ \param va - virtual address for which translation needs to be added \param pa - physical address needs to be filled */ -static void EnterKernelPageTableEntry(UINT32 va, UINT32 pa) +static void EnterKernelPageTableEntry(UINT32 va, UINT32 pa, UINT32 prot) { int pd_index, pt_index; PAGE_TABLE_ENTRY_PTR page_table; @@ -442,7 +442,10 @@ page_table = (PAGE_TABLE_ENTRY_PTR) pa; /*enter pde*/ - k_page_dir[pd_index].all = KERNEL_PTE_FLAG; + k_page_dir[pd_index].present = 1; + k_page_dir[pd_index].global = 1; + if (prot & PROT_WRITE) + k_page_dir[pd_index].write = 1; k_page_dir[pd_index].page_table_pfn = PA_TO_PFN(pa); } else @@ -474,11 +477,11 @@ for(i=0; i<memory_area_count; i++ ) { int j; - kprintf("System map: START END PAGES TYPE\n"); + ktrace("System map: START END PAGES TYPE\n"); for(j=0; j<memory_areas[i].physical_memory_regions_count; j++ ) { PHYSICAL_MEMORY_REGION_PTR pmr = &memory_areas[i].physical_memory_regions[j]; - kprintf(" %9p %9p %9d %10s\n", pmr->start_physical_address, pmr->end_physical_address, pmr->virtual_page_count, + ktrace(" %9p %9p %9d %10s\n", pmr->start_physical_address, pmr->end_physical_address, pmr->virtual_page_count, pmr->type == PMEM_TYPE_AVAILABLE ? "Available" : pmr->type == PMEM_TYPE_ACPI_RECLAIM ? "ACPI Reclaim" : pmr->type == PMEM_TYPE_ACPI_NVS ? "ACPI NVS" : "Reserved" ); if ( pmr->type == PMEM_TYPE_AVAILABLE ) Modified: src/kernel/iom/devfs.c =================================================================== --- src/kernel/iom/devfs.c 2009-06-10 10:50:58 UTC (rev 367) +++ src/kernel/iom/devfs.c 2011-08-26 14:13:45 UTC (rev 368) @@ -50,6 +50,8 @@ int current_index; /*! current index into file_stat param array*/ int max_entries; /*! max entries in the file_stat param*/ + char * file_name; /*! file name to search*/ + int result; /*! result of the enum operation*/ }DEVFS_DIRENTRY_PARAM, * DEVFS_DIRENTRY_PARAM_PTR; @@ -70,7 +72,9 @@ /*initialize cache object of devfs*/ if( InitCache(&devfs_cache, sizeof(DEVFS_METADATA), DEVFS_CACHE_FREE_SLABS_THRESHOLD, DEVFS_CACHE_MIN_BUFFERS, DEVFS_CACHE_MAX_SLABS, DevFsCacheConstructor, DevFsCacheDestructor) ) + { panic("InitDevFs - cache init failed"); + } InitMessageQueue( &device_fs_message_queue ); @@ -106,13 +110,16 @@ { err = GetVfsMessage(&device_fs_message_queue, DEV_FS_TIME_OUT, &type, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6 ); if ( err == ERROR_SUCCESS ) + { ProcessVfsMessage( type, (VFS_IPC)arg1, arg2, arg3, arg4, arg5, arg6 ); + } else - kprintf( "devfs IPC message receive error : %d\n", err ); - + { + KTRACE( "devfs IPC message receive error : %d\n", err ); + } /*!\todo - process unregister/shutdown request and exit this thread*/ } - kprintf( "Exiting devfs\n" ); + KTRACE( "Exiting devfs\n" ); } /*! Processes a VFS message and take neccessary action(reply to the VFS) @@ -125,6 +132,8 @@ FILE_STAT_PARAM_PTR de; int total_entries=0; DIRECTORY_ENTRY_PARAM_PTR de_param; + ERROR_CODE ret; + int is_write=0, result_count=0; switch ( vfs_id ) { @@ -159,8 +168,17 @@ break; case VFS_IPC_GET_FILE_STAT_INODE: + break; + case VFS_IPC_WRITE_FILE: + is_write = 1; case VFS_IPC_READ_FILE: - case VFS_IPC_WRITE_FILE: + assert( message_type == MESSAGE_TYPE_VALUE ); + ret = ReadWriteDevice( (DEVICE_OBJECT_PTR) arg2, arg5, (long)arg4, (long)arg6, is_write, &result_count, NULL, NULL); + if( ret == ERROR_SUCCESS ) + ReplyToLastMessage( MESSAGE_TYPE_VALUE, (IPC_ARG_TYPE)VFS_RETURN_CODE_SUCCESS, (IPC_ARG_TYPE)result_count, NULL, NULL, NULL, NULL ); + else + ReplyToLastMessage( MESSAGE_TYPE_VALUE, (IPC_ARG_TYPE)VFS_RETURN_CODE_NOT_FOUND, NULL, NULL, NULL, NULL, NULL ); + break; case VFS_IPC_MAP_FILE_PAGE: case VFS_IPC_DELETE_FILE: case VFS_IPC_MOVE: @@ -171,6 +189,104 @@ } } +/*! Completion routine to perform a synchronous operation + * */ +UINT32 ReadWriteDeviceCompletionRoutine(DEVICE_OBJECT_PTR device_object, IRP_PTR irp, void * context) +{ + assert(context != NULL ); + WakeUpEvent( context, WAIT_EVENT_WAKE_UP_ALL); + return 0; +} + +/*! Read/write devfs file + * \param device_object - device object of the /dev/xxx file + * \param user_buffer - buffer + * \param length - number of bytes to read/write + * \param offset - offset in the file + * \param is_write - if non-zero writes(copy from buffer to device) else read (from device to buffer) + * \param result_count - output - total number of bytes read/written + * \param completion_rountine - if non-zero performs a asynchronous operations and calls the given completion routine once the IRP is finished + * \param completion_rountine_context - argument to pass to the completion_rountine + * */ +ERROR_CODE ReadWriteDevice(DEVICE_OBJECT_PTR device_object, void * user_buffer, long offset, long length, int is_write, int * result_count, IO_COMPLETION_ROUTINE completion_rountine, void * completion_rountine_context) +{ + IRP_PTR irp; + IRP_MJ op; + WAIT_EVENT_PTR wait_event, wait_queue=NULL; + ERROR_CODE ret = ERROR_SUCCESS; + + assert( device_object != NULL ); + assert( result_count != NULL ); + + if ( is_write ) + op = IRP_MJ_WRITE; + else + op = IRP_MJ_READ; + + /*allocate a irp and fill the values*/ + irp = AllocateIrp( device_object->stack_count ); + FillIoStack( irp->current_stack_location, op, 0, device_object, NULL, NULL); + irp->current_stack_location->parameters.read_write.byte_offset = offset; + irp->current_stack_location->parameters.read_write.length = length; + /*setup the buffers based on buffering mode*/ + if( device_object->flags & DO_BUFFERED_IO ) + { + irp->system_buffer = kmalloc(length, 0); + if( irp->system_buffer==NULL ) + { + ret = ERROR_NOT_ENOUGH_MEMORY; + goto done; + } + /*if it is a write copy from user buffer*/ + if( is_write ) + { + ret = CopyFromUserSpace( user_buffer, irp->system_buffer, length ); + if ( ret != ERROR_SUCCESS ) + goto done; + } + } + else + panic("Only buffered IO is supported for now!"); + + /*if the caller didnt give a completion routine, perform a sync operation*/ + if( completion_rountine == NULL ) + { + /*create a completion event and wait for it, this event will be triggered by the completion_rountine */ + wait_event = AddToEventQueue( &wait_queue ); + SetIrpCompletionRoutine( irp, ReadWriteDeviceCompletionRoutine, wait_event, IRP_COMPLETION_INVOKE_ON_SUCCESS | IRP_COMPLETION_INVOKE_ON_ERROR | IRP_COMPLETION_INVOKE_ON_CANCEL ); + } + else + SetIrpCompletionRoutine( irp, completion_rountine, completion_rountine_context, IRP_COMPLETION_INVOKE_ON_SUCCESS | IRP_COMPLETION_INVOKE_ON_ERROR | IRP_COMPLETION_INVOKE_ON_CANCEL ); + + /*call the driver*/ + CallDriver(device_object, irp); + /*\todo - what about pending?*/ + if ( irp->io_status.status != ERROR_SUCCESS ) + { + ret = irp->io_status.status; + goto done; + } + + /*wait for the event*/ + if( completion_rountine == NULL ) + { + WaitForEvent(wait_event, 0); + } + + /*number of bytes read/written*/ + *result_count = (int)irp->io_status.information; + + /*if buffered mode and read operation then copy back the data to user*/ + if( device_object->flags & DO_BUFFERED_IO && !is_write ) + { + ret = CopyToUserSpace( user_buffer, irp->system_buffer, *result_count ); + } + +done: + FreeIrp( irp ); + return ret; +} + /*! Creates a special device file under /device * \param filename - file name to create under /device folder * \param device - device object associated @@ -220,9 +336,10 @@ result = kmalloc( sizeof(FILE_STAT_PARAM)*total_directory_entries, 0 ); if ( result == NULL ) return NULL; - + param.file_stat = result; param.max_entries = max_entries; + param.file_name = file_name; EnumerateAvlTree(devfs_root, enumerate_devfs_tree_callback, ¶m); /*if no entry is reterived free the memory and return null*/ @@ -270,12 +387,18 @@ assert( param->current_index < param->max_entries ); + /*if file name is not matching continue enumeration*/ + if( param->file_name && strcmp(param->file_name, dm->name)!=0 ) + { + return 0; + } + fstat_param = ¶m->file_stat[ param->current_index ]; param->current_index++; /*fill the entry*/ strcpy( fstat_param->name, dm->name ); - fstat_param->inode = 0; + fstat_param->inode = (UINT32)dm->device; fstat_param->file_size = 0; fstat_param->mode = 0; fstat_param->fs_data = dm->device; @@ -288,7 +411,6 @@ return 0; } - /*! Internal function used to initialize the devfs metadata structure*/ int DevFsCacheConstructor( void *buffer) { Modified: src/kernel/iom/driver.c =================================================================== --- src/kernel/iom/driver.c 2009-06-10 10:50:58 UTC (rev 367) +++ src/kernel/iom/driver.c 2011-08-26 14:13:45 UTC (rev 368) @@ -8,6 +8,7 @@ #include <kernel/debug.h> #include <kernel/mm/kmem.h> #include <kernel/pm/elf.h> +#include <kernel/pm/task.h> #include <kernel/iom/iom.h> #include <kernel/vfs/vfs.h> @@ -51,10 +52,10 @@ strcat( driver_file_path, driver_file_name ); kprintf("Loading %s: ", driver_file_path); - err = OpenFile(driver_file_path, VFS_ACCESS_TYPE_READ, OPEN_EXISTING, &file_id); + err = OpenFile(&kernel_task, driver_file_path, VFS_ACCESS_TYPE_READ, OPEN_EXISTING, &file_id); if ( err != ERROR_SUCCESS ) goto error; - err = GetFileSize(file_id, &file_size); + err = GetFileSize(&kernel_task, file_id, &file_size); if ( err != ERROR_SUCCESS ) goto error; file_size = PAGE_ALIGN_UP(file_size); @@ -109,11 +110,11 @@ buffer[0]=0; - err = OpenFile(driver_id_database, VFS_ACCESS_TYPE_READ, OPEN_EXISTING, &file_id); + err = OpenFile( &kernel_task, driver_id_database, VFS_ACCESS_TYPE_READ, OPEN_EXISTING, &file_id); if ( err != ERROR_SUCCESS ) goto done; - err = GetFileSize(file_id, &file_size); + err = GetFileSize(&kernel_task, file_id, &file_size); if ( err != ERROR_SUCCESS ) goto done; @@ -163,6 +164,6 @@ done: /* \todo - release the mapping */ - CloseFile(file_id); + CloseFile(&kernel_task, file_id); return err; } Modified: src/kernel/iom/iom.c =================================================================== --- src/kernel/iom/iom.c 2009-06-10 10:50:58 UTC (rev 367) +++ src/kernel/iom/iom.c 2011-08-26 14:13:45 UTC (rev 368) @@ -6,23 +6,24 @@ #include <string.h> #include <ctype.h> #include <kernel/debug.h> +#include <kernel/mm/vm.h> #include <kernel/mm/kmem.h> #include <kernel/pm/elf.h> #include <kernel/iom/iom.h> #include <kernel/vfs/vfs.h> #include <kernel/iom/devfs.h> -#define DEVICE_OBJECT_CACHE_FREE_SLABS_THRESHOLD 10 -#define DEVICE_OBJECT_CACHE_MIN_BUFFERS 10 -#define DEVICE_OBJECT_CACHE_MAX_SLABS 10 +#define DEVICE_OBJECT_CACHE_FREE_SLABS_THRESHOLD 50 +#define DEVICE_OBJECT_CACHE_MIN_BUFFERS 50 +#define DEVICE_OBJECT_CACHE_MAX_SLABS 1000 -#define DRIVER_OBJECT_CACHE_FREE_SLABS_THRESHOLD 5 -#define DRIVER_OBJECT_CACHE_MIN_BUFFERS 5 -#define DRIVER_OBJECT_CACHE_MAX_SLABS 5 +#define DRIVER_OBJECT_CACHE_FREE_SLABS_THRESHOLD 10 +#define DRIVER_OBJECT_CACHE_MIN_BUFFERS 10 +#define DRIVER_OBJECT_CACHE_MAX_SLABS 100 #define IRP_CACHE_FREE_SLABS_THRESHOLD 50 #define IRP_CACHE_MIN_BUFFERS 50 -#define IRP_CACHE_MAX_SLABS 50 +#define IRP_CACHE_MAX_SLABS 1000 /*! List of drivers loaded into the kernel address space */ LIST_PTR driver_list_head = NULL; @@ -66,15 +67,14 @@ /*load root bus driver and call the DriverEntry*/ root_bus = LoadRootBusDriver() ; - + /*this is the first driver loaded into the kernel and it is never unloaded*/ driver_list_head = &root_bus->driver_list; - RootBusDriverEntry( root_bus ); /*create device object for root bus*/ - CreateDevice(root_bus_driver_object, 0, &root_bus_device_object, NULL); - + CreateDevice(root_bus_driver_object, 0, &root_bus_device_object, NULL, DO_BUFFERED_IO); + /*force the io manager to enumerate the buses on root bus*/ InvalidateDeviceRelations(root_bus_device_object, DEVICE_RELATIONS_TYPE_BUS_RELATION); } @@ -98,7 +98,7 @@ \param device_object - pointer to device object - io manager updates this pointer with the newly created device object \param device_name - optional - device file name - it will be placed under /device/xxxx - applications use this file to communicate with the driver */ -ERROR_CODE CreateDevice(DRIVER_OBJECT_PTR driver_object, UINT32 device_extension_size, DEVICE_OBJECT_PTR * device_object, char * device_name) +ERROR_CODE CreateDevice(DRIVER_OBJECT_PTR driver_object, UINT32 device_extension_size, DEVICE_OBJECT_PTR * device_object, char * device_name, UINT32 flag) { DEVICE_OBJECT_PTR dob; assert( device_object != NULL ); @@ -122,9 +122,16 @@ ERROR_CODE ret; ret = CreateDeviceNode(device_name, dob); /*\todo - do we need to care about CreateDeviceNode return status?*/ - } + } + /*\todo - validate the flag*/ + dob->flags = flag; + *device_object = dob; + + /*force the io manager to enumerate child devices */ + //InvalidateDeviceRelations(dob, DEVICE_RELATIONS_TYPE_BUS_RELATION); + return ERROR_SUCCESS; } @@ -170,7 +177,7 @@ if( type == DEVICE_RELATIONS_TYPE_BUS_RELATION ) { /*todo - build existing device relations*/ - + /*send query relation irp to the driver*/ irp = AllocateIrp( device_object->stack_count ); FillIoStack( irp->current_stack_location, IRP_MJ_PNP, IRP_MN_QUERY_DEVICE_RELATIONS, device_object, NULL, NULL); @@ -183,7 +190,6 @@ for(i=0; i<dr->count; i++) { /*\todo - if the device is not new - continue*/ - /*send query id irp for each new device to the driver*/ ReuseIrp( irp, ERROR_NOT_SUPPORTED ); FillIoStack( irp->current_stack_location, IRP_MJ_PNP, IRP_MN_QUERY_ID, dr->objects[i], NULL, NULL ); @@ -200,6 +206,10 @@ /*free driver id*/ kfree( irp->io_status.information ); } + else + { + KTRACE("BUS_QUERY_DEVICE_ID failed\n"); + } } /*free the device relation struture*/ kfree( dr ); @@ -208,6 +218,26 @@ FreeIrp(irp); } +/*! Set a completion routine a lower level driver completes the IRP + * \param irp + * \param completion_routine - routine to call + * \param context - argument to pass to the completion routine + * \param invoke_on_success - call on success + * \param invoke_on_error - call on error + * \param invoke_on_cancel - call on cancel + * */ +ERROR_CODE SetIrpCompletionRoutine(IRP_PTR irp, IO_COMPLETION_ROUTINE completion_routine, void * context, IRP_COMPLETION_INVOKE invoke_on) +{ + assert( irp != NULL ); + assert( irp->current_stack_location != NULL ); + + irp->current_stack_location->completion_routine = completion_routine; + irp->current_stack_location->context = context; + irp->current_stack_location->invoke_on = invoke_on; + + return ERROR_SUCCESS; +} + /*! Dispatches a call to driver based on the given Irp \param device_object - device object \param irp - irp @@ -217,7 +247,9 @@ assert( device_object != NULL ); assert( irp != NULL ); + //KTRACE("CallDriver %p %s %s\n", device_object, device_object->driver_object->driver_name, FindKernelSymbolByAddress( device_object->driver_object->fn.MajorFunctions[irp->current_stack_location->major_function], NULL) ); device_object->driver_object->fn.MajorFunctions[irp->current_stack_location->major_function](device_object, irp); + return ERROR_SUCCESS; } Modified: src/kernel/iom/irp.c =================================================================== --- src/kernel/iom/irp.c 2009-06-10 10:50:58 UTC (rev 367) +++ src/kernel/iom/irp.c 2011-08-26 14:13:45 UTC (rev 368) @@ -13,6 +13,9 @@ extern CACHE irp_cache; +int IrpCacheConstructor( void * buffer); +int IrpCacheDestructor( void * buffer); + /*! Allocates a Irp for the use of driver \param stack_size - number of stacks assoicated with this irp \return irp Modified: src/kernel/iom/rootbus.c =================================================================== --- src/kernel/iom/rootbus.c 2009-06-10 10:50:58 UTC (rev 367) +++ src/kernel/iom/rootbus.c 2011-08-26 14:13:45 UTC (rev 368) @@ -41,29 +41,47 @@ static DEVICE_RELATIONS_PTR CreateRootBusDevices(DEVICE_OBJECT_PTR pDeviceObject) { DEVICE_RELATIONS_PTR dr; - DEVICE_OBJECT_PTR acpi_device_object; + DEVICE_OBJECT_PTR acpi_device_object, console_device_object; ROOTBUS_DEVICE_EXTENSION_PTR ext; ERROR_CODE err; /*allocate memory for device relation struction*/ - dr = kmalloc( SIZEOF_DEVICE_RELATIONS(1), 0 ); + dr = kmalloc( SIZEOF_DEVICE_RELATIONS(2), 0 ); if ( dr == NULL ) + { panic("Unable to create Root bus devices"); + } /*create device object for acpi bus*/ - err = CreateDevice( pDeviceObject->driver_object, sizeof(ROOTBUS_DEVICE_EXTENSION), &acpi_device_object, ACPI_BUS_NAME ); + err = CreateDevice( pDeviceObject->driver_object, sizeof(ROOTBUS_DEVICE_EXTENSION), &acpi_device_object, ACPI_BUS_NAME, DO_BUFFERED_IO ); if ( err != ERROR_SUCCESS ) + { panic("Unable to create ACPI bus device"); + } /*put rootbus specific info to device extension structure*/ ext = (ROOTBUS_DEVICE_EXTENSION_PTR)acpi_device_object->device_extension; strcpy( ext->name, ACPI_BUS_NAME ); /*attach the acpi device to root bus device io stack*/ AttachDeviceToDeviceStack(acpi_device_object, pDeviceObject); + + /*create device object for acpi bus*/ + err = CreateDevice( pDeviceObject->driver_object, sizeof(ROOTBUS_DEVICE_EXTENSION), &console_device_object, "console_root", DO_BUFFERED_IO ); + if ( err != ERROR_SUCCESS ) + { + panic("Unable to create console device"); + } + + /*put rootbus specific info to device extension structure*/ + ext = (ROOTBUS_DEVICE_EXTENSION_PTR)console_device_object->device_extension; + strcpy( ext->name, "console" ); + /*attach the console device to root bus device io stack*/ + AttachDeviceToDeviceStack(console_device_object, pDeviceObject); /*put the device object in the device relations structure*/ - dr->count = 1; + dr->count = 2; dr->objects[0] = acpi_device_object; + dr->objects[1] = console_device_object; return dr; } @@ -80,7 +98,9 @@ { /*create real bus drivers only once(local buses cant be unplugged)*/ if ( pIrp->io_status.information == NULL ) + { pIrp->io_status.information = CreateRootBusDevices(pDeviceObject); + } pIrp->io_status.status = ERROR_SUCCESS; } else Modified: src/kernel/kprintf.c =================================================================== --- src/kernel/kprintf.c 2009-06-10 10:50:58 UTC (rev 367) +++ src/kernel/kprintf.c 2011-08-26 14:13:45 UTC (rev 368) @@ -4,6 +4,7 @@ */ #include <ace.h> #include <stdlib.h> +#include <kernel/debug.h> #include <kernel/printf.h> #include <kernel/mm/kmem.h> @@ -29,6 +30,9 @@ */ int kprintf(const char *fmt, ...) { + #ifdef __KERNEL_TRACE__ + _doprint( fmt, ktrace_putc, NULL, (va_list) ((&fmt)+1)); + #endif return _doprint( fmt, kprintf_putc, NULL, (va_list) ((&fmt)+1)); } /*! prints formatted string in a string buffer Modified: src/kernel/ktrace.c =================================================================== --- src/kernel/ktrace.c 2009-06-10 10:50:58 UTC (rev 367) +++ src/kernel/ktrace.c 2011-08-26 14:13:45 UTC (rev 368) @@ -8,7 +8,7 @@ #include <kernel/arch.h> #include <kernel/printf.h> -#define MAX_STACK_FRAMES 10 +#define MAX_STACK_FRAMES 50 /*! function pointer is used by the ktrace() to write characters */ @@ -27,7 +27,7 @@ void _assert(const char *msg, const char *file, int line) { kprintf("Assertion failed at %s:%d::[%s]\n", file, line, msg); - panic(NULL); + panic("Assert failed"); } /*! Halts the system after printing the given message @@ -36,10 +36,14 @@ { static int panic=0; panic++; - if( message ) + if( message ) + { kprintf("panic() : %s\n", message); + } /*!avoid stack trace if we are already panicing*/ if( panic <=1 ) + { PrintStackTrace(MAX_STACK_FRAMES); + } ArchShutdown(); } Modified: src/kernel/main.c =================================================================== --- src/kernel/main.c 2009-06-10 10:50:58 UTC (rev 367) +++ src/kernel/main.c 2011-08-26 14:13:45 UTC (rev 368) @@ -91,11 +91,11 @@ /* Installl system call handler */ SetupSystemCallHandler(); - InitGraphicsConsole(); + //InitGraphicsConsole(); //CreateTask("/boot/app/hello.exe", IMAGE_TYPE_ELF_FILE, TASK_CREATION_FLAG_NONE, NULL, "hello.exe", "TEST=TS"); - //CreateTask("/boot/app/bash", "bash -i test1", "TEST=TSsss NOTHING=WELE EEKEKEK=EEEE ees=33"); + CreateTask("/boot/app/bash", IMAGE_TYPE_ELF_FILE, TASK_CREATION_FLAG_NONE, NULL, "bash -i", "ees=33"); kprintf("Kernel initialization complete\n"); Modified: src/kernel/mm/virtual_page.c =================================================================== --- src/kernel/mm/virtual_page.c 2009-06-10 10:50:58 UTC (rev 367) +++ src/kernel/mm/virtual_page.c 2011-08-26 14:13:45 UTC (rev 368) @@ -446,6 +446,7 @@ { int i,j; int debug=0; + retry: for(i=0; i<memory_area_count; i++ ) @@ -455,7 +456,9 @@ { pmr = &memory_areas[i].physical_memory_regions[j]; if ( debug ) - kprintf("%p - %p : %p\n", pmr->start_physical_address, pmr->end_physical_address, physical_address); + { + KTRACE("%p - %p : %p\n", pmr->start_physical_address, pmr->end_physical_address, physical_address); + } if ( physical_address >= pmr->start_physical_address && physical_address < pmr->end_physical_address ) { UINT32 index; @@ -468,9 +471,10 @@ if ( !debug ) { debug++; + KTRACE("PA not managed\n"); goto retry; } - panic("PhysicalToVirtualPage not found"); + return NULL; } Modified: src/kernel/mm/vm.c =================================================================== --- src/kernel/mm/vm.c 2009-06-10 10:50:58 UTC (rev 367) +++ src/kernel/mm/vm.c 2011-08-26 14:13:45 UTC (rev 368) @@ -21,7 +21,10 @@ VM_PROTECTION protection_kernel_read = {0,0,0,1}; VM_PROTECTION protection_user_write = {1,1,0,0}; VM_PROTECTION protection_user_read = {0,1,0,0}; +VM_PROTECTION protection_all_write = {1,1,1,1}; +VM_PROTECTION protection_all_read = {0,1,0,1}; + KERNEL_RESERVE_RANGE kernel_reserve_range; /*from kernel.ld*/ @@ -103,26 +106,26 @@ kernel_map.end = kernel_reserve_range.kmem_va_end; /*map kernel code*/ - vm_unit = CreateVmUnit( VM_UNIT_TYPE_KERNEL, VM_UNIT_FLAG_PRIVATE, kernel_reserve_range.code_va_end - kernel_reserve_range.code_va_start); - InitVmDescriptor( &kernel_static_code_descriptor, &kernel_map, kernel_reserve_range.code_va_start, kernel_reserve_range.code_va_end, vm_unit, &protection_kernel_read); + vm_unit = CreateVmUnit(VM_UNIT_TYPE_KERNEL, VM_UNIT_FLAG_PRIVATE, kernel_reserve_range.code_va_end - kernel_reserve_range.code_va_start); + InitVmDescriptor(&kernel_static_code_descriptor, &kernel_map, kernel_reserve_range.code_va_start, kernel_reserve_range.code_va_end, vm_unit, &protection_kernel_read); InitKernelDescriptorVtoP(&kernel_static_code_descriptor, kernel_reserve_range.code_va_start, kernel_reserve_range.code_va_end, kernel_reserve_range.code_pa_start); /*map kernel data*/ - vm_unit = CreateVmUnit( VM_UNIT_TYPE_KERNEL, VM_UNIT_FLAG_PRIVATE, kernel_reserve_range.data_va_end - kernel_reserve_range.data_va_start); - InitVmDescriptor( &kernel_static_data_descriptor, &kernel_map, kernel_reserve_range.data_va_start, kernel_reserve_range.data_va_end, vm_unit, &protection_kernel_write); + vm_unit = CreateVmUnit(VM_UNIT_TYPE_KERNEL, VM_UNIT_FLAG_PRIVATE, kernel_reserve_range.data_va_end - kernel_reserve_range.data_va_start); + InitVmDescriptor(&kernel_static_data_descriptor, &kernel_map, kernel_reserve_range.data_va_start, kernel_reserve_range.data_va_end, vm_unit, &protection_kernel_write); InitKernelDescriptorVtoP(&kernel_static_data_descriptor, kernel_reserve_range.data_va_start, kernel_reserve_range.data_va_end, kernel_reserve_range.data_pa_start); /*map modules*/ - vm_unit = CreateVmUnit( VM_UNIT_TYPE_KERNEL, VM_UNIT_FLAG_SHARED, kernel_reserve_range.module_va_end - kernel_reserve_range.module_va_start ); + vm_unit = CreateVmUnit(VM_UNIT_TYPE_KERNEL, VM_UNIT_FLAG_SHARED, kernel_reserve_range.module_va_end - kernel_reserve_range.module_va_start); vd = CreateVmDescriptor(&kernel_map, kernel_reserve_range.module_va_start, kernel_reserve_range.module_va_end, vm_unit, &protection_kernel_write); - InitKernelDescriptorVtoP(vd, kernel_reserve_range.module_va_start, kernel_reserve_range.module_va_end, kernel_reserve_range.module_pa_start ); + InitKernelDescriptorVtoP(vd, kernel_reserve_range.module_va_start, kernel_reserve_range.module_va_end, kernel_reserve_range.module_pa_start); /*map symbol table*/ if ( kernel_reserve_range.symbol_pa_start ) { - vm_unit = CreateVmUnit( VM_UNIT_TYPE_KERNEL, VM_UNIT_FLAG_PRIVATE, kernel_reserve_range.symbol_va_end - kernel_reserve_range.symbol_va_start ); + vm_unit = CreateVmUnit(VM_UNIT_TYPE_KERNEL, VM_UNIT_FLAG_PRIVATE, kernel_reserve_range.symbol_va_end - kernel_reserve_range.symbol_va_start); vd = CreateVmDescriptor(&kernel_map, kernel_reserve_range.symbol_va_start, kernel_reserve_range.symbol_va_end, vm_unit, &protection_kernel_write); - InitKernelDescriptorVtoP(vd, kernel_reserve_range.symbol_va_start, kernel_reserve_range.symbol_va_end, kernel_reserve_range.symbol_pa_start ); + InitKernelDescriptorVtoP(vd, kernel_reserve_range.symbol_va_start, kernel_reserve_range.symbol_va_end, kernel_reserve_range.symbol_pa_start); } /*map string table*/ @@ -164,19 +167,45 @@ VADDR MapPhysicalMemory(VIRTUAL_MAP_PTR vmap, UINT32 pa, UINT32 size, VADDR preferred_va, UINT32 protection) { VADDR va; - UINT32 i; - + UINT32 i, vtop_index; + VM_DESCRIPTOR_PTR vd; + VIRTUAL_PAGE_PTR vp = NULL; + + assert(pa != 0); size = PAGE_ALIGN_UP(size); pa = PAGE_ALIGN(pa); if ( AllocateVirtualMemory( vmap, &va, preferred_va, size, protection, 0, NULL) != ERROR_SUCCESS ) + { return NULL; + } + vd = GetVmDescriptor(vmap, va, 1); + assert ( vd != NULL ); + assert( va >= vd->start && va <= vd->end ); + vtop_index = ((va - vd->start) / PAGE_SIZE) + (vd->offset_in_unit/PAGE_SIZE); + assert( vtop_index <= (vd->unit->size/PAGE_SIZE) ); + for(i=0; i<size;i+=PAGE_SIZE ) { - if ( CreatePhysicalMapping(vmap->physical_map, va+i, pa+i, 0) != ERROR_SUCCESS ) + if (GetCurrentVirtualMap() == vmap) { - FreeVirtualMemory(vmap, va, size, 0); - return NULL; + if ( CreatePhysicalMapping(vmap->physical_map, va+i, pa+i, protection) != ERROR_SUCCESS ) + { + FreeVirtualMemory(vmap, va, size, 0); + return NULL; + } } + else + { + /* if the PA is managed then create a lazy mapping */ + vp = PhysicalToVirtualPage(pa+i); + if (vp == NULL) + { + panic("Request to map unmanaged page in different task map - Use kvm driver for that purpose"); + } + + vd->unit->page_count++; + vd->unit->vtop_array[vtop_index+(i/PAGE_SIZE)].vpage = (VIRTUAL_PAGE_PTR) ( ((VADDR)vp) | 1 ); + } } return va; } @@ -211,19 +240,26 @@ SpinLock(&vmap->lock); /*find a free vm range in the current virtual map*/ start = (VADDR)FindFreeVmRange(vmap, preferred_start, size, VA_RANGE_SEARCH_FROM_TOP); - KTRACE("start %p\n", start); if ( start == NULL ) { kprintf("AllocateVirtualMemory(%d) - No memory range available \n", size); SpinUnlock(&vmap->lock); return ERROR_NOT_ENOUGH_MEMORY; } + /*adjust the virtual map end + * \todo - is this neccessary?*/ if ( vmap->end < start + size ) vmap->end = start + size; SpinUnlock(&vmap->lock); + /*get the protection*/ if ( vmap == &kernel_map ) - prot = &protection_kernel_write; + { + if ( protection & PROT_WRITE ) + prot = &protection_kernel_write; + else + prot = &protection_kernel_read; + } else { if ( protection & PROT_WRITE ) @@ -305,15 +341,14 @@ /*allocate virtaul address range and map the same vm unit*/ ret = AllocateVirtualMemory(dest_vmap, &va, *dest_preferred_va, src_size, protection, 0, unit); if ( ret != ERROR_SUCCESS ) - return ret; - + return ret; /*set the offset in descriptor of the newly allocated va*/ dest_vd = GetVmDescriptor(dest_vmap, va, src_size); assert( dest_vd != NULL ); dest_vd->offset_in_unit = unit_offset; dest_vd->end = dest_vd->start + va_difference + org_src_size; - + /*do we need a zerofilling section after the mapping?*/ if ( dest_size > src_size ) { @@ -333,7 +368,6 @@ /*although we cant protect the caller using the entire page, we should return where the actual data starts*/ *dest_preferred_va = va + va_difference; - return ERROR_SUCCESS; } @@ -368,7 +402,9 @@ assert( va ); vnode = GetVnodeFromFile(file_id); - assert(vnode != NULL); + /*if vnode not found it could be either because the file_id is wrong or some resource shortage*/ + if( vnode == NULL ) + return ERROR_INVALID_PARAMETER; if( file_offset!=0 && IS_PAGE_ALIGNED(file_offset) ) if( !IS_PAGE_ALIGNED(size) ) @@ -430,6 +466,30 @@ return ERROR_SUCCESS; } +/*! Copy data from user space to kernel space(any user faults are handled and returned as failure) + * \param user_va - user virtual address + * \param kernel_va - kernel virtual address + * \param length - size of the virtual address range to copy + * */ +ERROR_CODE CopyFromUserSpace(void * user_va, void * kernel_va, size_t length) +{ + /*\todo - write proper code*/ + memmove( kernel_va, user_va, length ); + return ERROR_SUCCESS; +} + +/*! Copy data from kernel to user space(any user faults are handled and returned as failure) + * \param user_va - user virtual address + * \param kernel_va - kernel virtual address + * \param leng... [truncated message content] |
From: QYPE <no-...@qy...> - 2010-11-18 20:09:40
|
Bonjour , jean marie bourbon vous invite à l'événement " vos repas de fin d annee au restaurant l entree des artistes " qui aura lieu le 18.11.2010, 20:17 : " C'est un magnifique restaurant romantique et insolite qui dispose d'un bar à Vins de qualité ainsi que d'une terrasse ensoleillée dans une impasse pavée du quartier de la Gaieté Montparnasse. Situé à 300 m de la Gare Montparnasse, à 50 m des plus grands théâtre comme le Gaîté Montparnasse, Rive gauche et le Bobino au calme de l'animation de la rue de la Gaîté. Le restaurant dispose d'environ 60 places dont 20 en terrasse l'été. Le Chef vous propose de déguster une cuisine inventive française réalisée essentiellement avec des produits frais du marché. mail bourbonjmàyahoo.fr L'Entrée des Artistes propose un endroit idéal pour un dîner entre amis ou un dîner en amoureux dans une ambiance cosy et apaisante. resa 0143272334 www.resto-lentreedesartistes.com " Pour en savoir plus sur cet événement et répondre à l'invitation, cliquez ici: http://www.qype.fr/events/501976 Pour en savoir plus sur jean marie bourbon, cliquez ici: http://www.qype.fr/people/bourbonjm A très bientôt, L'Equipe Qype. ------------------------------------------------------------------------------------------------------------ http://www.qype.fr - Trouvez. Partagez |
From: QYPE <no-...@qy...> - 2010-10-29 10:57:27
|
Bonjour , bourbonjm vous invite à l'événement " vos repas de fin d anneé au restaurant tout le monde en parle " qui aura lieu le 03.11.2010, 12:20 : " Privatisation - Soirée privée - Soirée d'entreprise Le restaurant offre un espace privilégié pour une location de salle un événement privé, institutionnel ou festif : soirée privée, dîner d'entreprise, conférence, séminaire, location de salle… Le restaurant accueille jusqu'à 200 personnes en déjeuner/dîner assis et 300 personnes en cocktail. Avec l'arrivée des beaux jours, les invités profiteront d'une terrasse de 250m² pour un cocktail avec vue sur Paris ! Pour un événement festif, le Tout le monde en parle propose un concept événementiel « all inclusive », comprenant : cocktails, restauration, spectacle et Club. Plus d'infos (lien vers page Evénements privés).Location de salle pour tous vos évènements !! Restaurant Tout le monde en parle… en terrasse tel 01404708909 www.restaurant-tlmp.fr resto-montparnasse.com email res...@ya... " Pour en savoir plus sur cet événement et répondre à l'invitation, cliquez ici: http://www.qype.fr/events/499423 Pour en savoir plus sur bourbonjm, cliquez ici: http://www.qype.fr/people/bourbonjm A très bientôt, L'Equipe Qype. ------------------------------------------------------------------------------------------------------------ http://www.qype.fr - Trouvez. Partagez |
From: <sam...@us...> - 2009-06-10 10:51:01
|
Revision: 367 http://aceos.svn.sourceforge.net/aceos/?rev=367&view=rev Author: samueldotj Date: 2009-06-10 10:50:58 +0000 (Wed, 10 Jun 2009) Log Message: ----------- Added support for V86 mode Added basic code for setting graphics mode using VESA Added WaitForThread() - This function can be used to wait for an another thread to finish its execution Modified MapPhysicalMemory() to take additional parameters - Preferred Start VA and Protection Modified CreateTask() to load binary files and binary program in the memory Split i386/arch.c into processor.c, interrupt.c and arch.c Fixed a bug in vm_descriptor.c where AVL tree key comparison was done in a wrong way. Modified Paths: -------------- src/include/kernel/arch.h src/include/kernel/i386/exception.h src/include/kernel/mm/vm.h src/include/kernel/pm/pm_types.h src/include/kernel/pm/task.h src/include/kernel/pm/thread.h src/include/kernel/processor.h src/kernel/acpi/osacexf.c src/kernel/i386/arch.c src/kernel/i386/exception.c src/kernel/i386/gdt.c src/kernel/i386/interrupt_stub.asm src/kernel/i386/mm/pmem.c src/kernel/i386/mm/pmem_init.c src/kernel/i386/pm/thread.c src/kernel/i386/tss.c src/kernel/iom/devfs.c src/kernel/ipc/message_queue.c src/kernel/ktrace.c src/kernel/main.c src/kernel/mm/vm.c src/kernel/mm/vm_descriptor.c src/kernel/pm/scheduler.c src/kernel/pm/task.c src/kernel/pm/thread.c src/kernel/vfs/boot_fs.c src/kernel/wscript_build Added Paths: ----------- src/include/kernel/i386/i386.h src/kernel/i386/bios.c src/kernel/i386/interrupt.c src/kernel/i386/processor.c src/kernel/i386/vesa/ src/kernel/i386/vesa/vbe.h src/kernel/i386/vesa/vesa.c Modified: src/include/kernel/arch.h =================================================================== --- src/include/kernel/arch.h 2009-06-09 17:03:41 UTC (rev 366) +++ src/include/kernel/arch.h 2009-06-10 10:50:58 UTC (rev 367) @@ -45,6 +45,8 @@ void PrintStackTrace(unsigned int max_frames); +int InitGraphicsConsole(); + extern UINT16 master_processor_id; extern UINT32 cpu_frequency; Modified: src/include/kernel/i386/exception.h =================================================================== --- src/include/kernel/i386/exception.h 2009-06-09 17:03:41 UTC (rev 366) +++ src/include/kernel/i386/exception.h 2009-06-10 10:50:58 UTC (rev 367) @@ -21,6 +21,18 @@ typedef struct regs REGS, *REGS_PTR; +/*! virtual 86 mode stack frame after a exception/interrupt*/ +struct regs_v86 +{ + REGS reg; /*! regular context saved by exception/interrupt handlers*/ + struct + { + UINT32 es, ds, fs, gs; + }v86; /*! segment registers also pushed by the x86 processors automatically*/ +}__attribute__((packed)); + +typedef struct regs_v86 REGS_V86, * REGS_V86_PTR; + /*! i386 specific Page fault error code*/ typedef union pf_error_code { @@ -54,5 +66,6 @@ void SetupExceptionHandlers(); void ExceptionHandler(REGS_PTR reg); void DoubleFaultHandler(); +int GeneralProtectionFaultHandlerForV86Mode(REGS_V86_PTR reg); #endif Added: src/include/kernel/i386/i386.h =================================================================== --- src/include/kernel/i386/i386.h (rev 0) +++ src/include/kernel/i386/i386.h 2009-06-10 10:50:58 UTC (rev 367) @@ -0,0 +1,58 @@ +/*! + \file kernel/i386/i386.h + \brief i386 architecture specific structure and function declarations +*/ + +#ifndef I386_H +#define I386_H + +#include <ace.h> +#include <kernel/i386/vga_text.h> +#include <kernel/i386/gdt.h> +#include <kernel/i386/idt.h> +#include <kernel/i386/exception.h> +#include <kernel/i386/pmem.h> +#include <kernel/i386/cpuid.h> +#include <kernel/i386/apic.h> +#include <kernel/i386/ioapic.h> +#include <kernel/i386/processor.h> + +/*! various eflag register values */ +#define EFLAG_RESERVED_BIT ( 1<<1 ) +#define EFLAG_VM86 ( 1<<17 ) +#define EFLAG_VIF ( 1<<19 ) +#define EFLAG_IF ( 1<<9 ) +#define EFLAG_IOPL0 ( 0 ) +#define EFLAG_IOPL1 ( 1<<12 ) +#define EFLAG_IOPL2 ( 2<<12 ) +#define EFLAG_IOPL3 ( 3<<12 ) + +/*! task initial eflag value */ +#define EFLAG_VALUE ( EFLAG_RESERVED_BIT | EFLAG_IF | EFLAG_IOPL3 ) + +/* segment:offset pair */ +typedef UINT32 FARPTR; + +/* Make a FARPTR from a segment and an offset */ +#define MK_FP(seg, off) ((FARPTR) (((UINT32) (seg) << 16) | (UINT16) (off))) +/* Extract the segment part of a FARPTR */ +#define FP_SEG(fp) (((FARPTR) fp) >> 16) +/* Extract the offset part of a FARPTR */ +#define FP_OFF(fp) (((FARPTR) fp) & 0xffff) +/* Convert a segment:offset pair to a linear address */ +#define FP_TO_LINEAR(seg, off) ((void*) ((((UINT16) (seg)) << 4) + ((UINT16) (off)))) + +typedef struct thread_i386 +{ + UINT32 is_v86:1, /*! set if this thread is a v86 mode thread*/ + eflag_if:1; /*! interrupt enable bit in eflag - updated only for v86*/ + + void (*interrupt_handler)(REGS_PTR reg); /*! v86 interrupt handler for this thread*/ + + REGS_V86 input_regs; /*! input values passed to this thread*/ +}THREAD_I386, * THREAD_I386_PTR; + +UINT32 I386LinearToFp(UINT32 ptr); +REGS_V86_PTR CallBiosIsr(BYTE interrupt, REGS_V86_PTR input); + +#endif Modified: src/include/kernel/mm/vm.h =================================================================== --- src/include/kernel/mm/vm.h 2009-06-09 17:03:41 UTC (rev 366) +++ src/include/kernel/mm/vm.h 2009-06-10 10:50:58 UTC (rev 367) @@ -21,7 +21,7 @@ #define KERNEL_MAP_START_VA (0xC0000000) #define KERNEL_MAP_END_VA ((UINT32)-1) - #define USER_MAP_START_VA (1024*1024) + #define USER_MAP_START_VA (PAGE_SIZE) #define USER_MAP_END_VA (KERNEL_MAP_START_VA-1) #endif @@ -213,7 +213,7 @@ ERROR_CODE CopyVirtualAddressRange(VIRTUAL_MAP_PTR src_vmap, VADDR src_va, UINT32 src_size, VIRTUAL_MAP_PTR dest_vmap, VADDR *dest_preferred_va, UINT32 dest_size, UINT32 protection); -VADDR MapPhysicalMemory(VIRTUAL_MAP_PTR vmap, UINT32 pa, UINT32 size); +VADDR MapPhysicalMemory(VIRTUAL_MAP_PTR vmap, UINT32 pa, UINT32 size, VADDR preferred_va, UINT32 protection); VIRTUAL_MAP_PTR GetCurrentVirtualMap(); ERROR_CODE MemoryFaultHandler(UINT32 va, int is_user_mode, int access_type); Modified: src/include/kernel/pm/pm_types.h =================================================================== --- src/include/kernel/pm/pm_types.h 2009-06-09 17:03:41 UTC (rev 366) +++ src/include/kernel/pm/pm_types.h 2009-06-10 10:50:58 UTC (rev 367) @@ -7,6 +7,7 @@ typedef struct task TASK, * TASK_PTR; typedef struct thread THREAD, * THREAD_PTR; +typedef struct thread_container THREAD_CONTAINER, * THREAD_CONTAINER_PTR; typedef struct pid_info PID_INFO, * PID_INFO_PTR; typedef struct wait_event WAIT_EVENT, *WAIT_EVENT_PTR; Modified: src/include/kernel/pm/task.h =================================================================== --- src/include/kernel/pm/task.h 2009-06-09 17:03:41 UTC (rev 366) +++ src/include/kernel/pm/task.h 2009-06-10 10:50:58 UTC (rev 367) @@ -14,6 +14,7 @@ #include <kernel/vfs/vfs.h> #include <kernel/mm/kmem.h> #include <kernel/pm/pm_types.h> +#include <kernel/pm/thread.h> /*\todo remove these macros and put it as tunable*/ #define TASK_CACHE_FREE_SLABS_THRESHOLD 100 @@ -48,6 +49,20 @@ char * user_scratch; /*! temporary memory to copy kernel content to user*/ }; +typedef enum +{ + IMAGE_TYPE_ELF_FILE, /*! Load an image from a file and the file is of type ELF*/ + IMAGE_TYPE_BIN_FILE, /*! Load an image from a file and the file is of type plain binary*/ + IMAGE_TYPE_BIN_PROGRAM /*! Load an image from memory and it is of type plain binary*/ +}IMAGE_TYPE; + +typedef enum +{ + TASK_CREATION_FLAG_NONE, /*! Normal - no special flag*/ + TASK_CREATION_FLAG_NO_THREAD, /*! Dont create a thread*/ + TASK_CREATION_FLAG_SUSPEND_THREAD /*! Create a thread in suspended mode*/ +}TASK_CREATION_FLAG; + extern CACHE task_cache; extern TASK kernel_task; @@ -59,7 +74,7 @@ int TaskCacheDestructor(void * buffer); void InitKernelTask(); -TASK_PTR CreateTask(char * exe_file_path, char * command_line, char * environment); +TASK_PTR CreateTask(char * exe_file_path, IMAGE_TYPE image_type, UINT32 creation_flag, VADDR * entry_point, char * command_line, char * environment); inline TASK_PTR GetCurrentTask(); TASK_PTR PidToTask(int pid); Modified: src/include/kernel/pm/thread.h =================================================================== --- src/include/kernel/pm/thread.h 2009-06-09 17:03:41 UTC (rev 366) +++ src/include/kernel/pm/thread.h 2009-06-10 10:50:58 UTC (rev 367) @@ -52,6 +52,8 @@ UINT8 time_slice; /*! Time quantum for which the thread can be run */ PRIORITY_QUEUE_PTR priority_queue; /*! Pointer to priority queue in either of active or dormant ready queue */ SCHEDULER_CLASS_LEVELS priority; /*! External priority assigned by the user. This is used to select one of the scheduler classes */ + + WAIT_EVENT_PTR thread_event; /*! Wait for this thread to finish*/ /* Timeout queue */ TIMEOUT_QUEUE timeout_queue; @@ -63,6 +65,8 @@ THREAD_PTR ipc_reply_to_thread; /*! Last message came from which thread(ie to which thread i have to reply)*/ WAIT_EVENT_PTR ipc_reply_event; /*! Waitevent to wait to receive message(reply)*/ MESSAGE_BUFFER ipc_reply_message; /*! buffer to receive reply data*/ + + void * arch_data; /*! architecture depended data*/ }; /* @@ -74,13 +78,13 @@ ------- Page Align Kernel Stack */ -typedef struct thread_container +struct thread_container { THREAD thread; __attribute__ ((aligned ( PAGE_SIZE ))) BYTE * kernel_stack_pointer; BYTE guard_page[PAGE_SIZE] __attribute__ ((aligned ( PAGE_SIZE ))); BYTE kernel_stack[KERNEL_STACK_SIZE] __attribute__ ((aligned ( PAGE_SIZE ))); -}THREAD_CONTAINER, * THREAD_CONTAINER_PTR; +}; extern CACHE thread_cache; @@ -94,7 +98,7 @@ inline BYTE * GetKernelStackPointer(); THREAD_PTR GetCurrentThread(); -THREAD_CONTAINER_PTR CreateThread(TASK_PTR task, void * start_address, SCHEDULER_PRIORITY_LEVELS priority_class, BYTE is_kernel_thread); +THREAD_CONTAINER_PTR CreateThread(TASK_PTR task, void * start_address, SCHEDULER_PRIORITY_LEVELS priority_class, BYTE is_kernel_thread, VADDR arch_arg); void ExitThread(); void FreeThread(THREAD_PTR thread ); void PauseThread(); @@ -102,9 +106,11 @@ void InitBootThread(int boot_processor_id); -void FillThreadContext(THREAD_CONTAINER_PTR thread_container, void * start_address, BYTE is_kernel_thread, VADDR user_stack); +void FillThreadContext(THREAD_CONTAINER_PTR thread_container, void * start_address, BYTE is_kernel_thread, VADDR user_stack, VADDR arch_arg); void SwitchContext(THREAD_CONTAINER_PTR thread_container); +ERROR_CODE WaitForThread(THREAD_PTR thread, int wait_time); + #ifdef __cplusplus } #endif Modified: src/include/kernel/processor.h =================================================================== --- src/include/kernel/processor.h 2009-06-09 17:03:41 UTC (rev 366) +++ src/include/kernel/processor.h 2009-06-10 10:50:58 UTC (rev 367) @@ -12,7 +12,7 @@ #include <ace.h> typedef struct processor *PROCESSOR_PTR; -#include <kernel/pm/task.h> +#include <kernel/pm/pm_types.h> #include <kernel/pm/scheduler.h> #ifdef CONFIG_SMP Modified: src/kernel/acpi/osacexf.c =================================================================== --- src/kernel/acpi/osacexf.c 2009-06-09 17:03:41 UTC (rev 366) +++ src/kernel/acpi/osacexf.c 2009-06-10 10:50:58 UTC (rev 367) @@ -379,7 +379,7 @@ ACPI_PHYSICAL_ADDRESS where, ACPI_SIZE length) { - VADDR va = MapPhysicalMemory( &kernel_map, where, length ); + VADDR va = MapPhysicalMemory( &kernel_map, where, length, 0, PROT_READ | PROT_WRITE ); if ( va ) return (ACPI_TO_POINTER ((ACPI_NATIVE_UINT) (va + where-PAGE_ALIGN(where)) )); else Modified: src/kernel/i386/arch.c =================================================================== --- src/kernel/i386/arch.c 2009-06-09 17:03:41 UTC (rev 366) +++ src/kernel/i386/arch.c 2009-06-10 10:50:58 UTC (rev 367) @@ -6,32 +6,13 @@ #include <kernel/arch.h> #include <kernel/parameter.h> #include <kernel/pm/thread.h> -#include <kernel/i386/vga_text.h> -#include <kernel/i386/gdt.h> -#include <kernel/i386/idt.h> -#include <kernel/i386/exception.h> -#include <kernel/i386/pmem.h> -#include <kernel/i386/cpuid.h> -#include <kernel/i386/apic.h> -#include <kernel/i386/ioapic.h> -#include <kernel/i386/processor.h> +#include <kernel/i386/i386.h> -static int use_pic_8259 = 0; - +extern void InitInterruptControllers(); extern void Start8254Timer(UINT32 frequency); extern void SetupInterruptStubs(); -extern UINT32 trampoline_data, trampoline_end; +extern inline UINT64 rdtsc(); -static void InitInterruptControllers(); - -PROCESSOR_I386 processor_i386[MAX_PROCESSORS]; -UINT16 master_processor_id = 0; - -/*! CPU frequency - Ace requires all the processor to run at the same frequency - This variable should populated during init. -*/ -UINT32 cpu_frequency = 0; - void kprint_vga(void * arg, char ch) { VgaPrintCharacter(ch); @@ -54,28 +35,6 @@ InitKtrace(); } -/*! ReaD Time Stamp Counter - * Reads the current processor time stamp using the rdtsc instruction. - * cpuid instruction is used to serialize the read operation. - * \return current processor time stamap - */ -inline UINT64 rdtsc() -{ - UINT32 lo, hi; - /* - * cpuid will serialize the following rdtsc with respect to all other - * instructions the processor may be handling. - */ - __asm__ __volatile__ ( - "xorl %%eax, %%eax\n" - "cpuid\n" - "rdtsc\n" - : "=a" (lo), "=d" (hi) - : - : "%ebx", "%ecx"); - return (UINT64)hi << 32 | lo; -} - /*! Initializes i386 specific data structures This function is called after InitVm() so it is safe to use kmalloc and other vm functions @@ -92,7 +51,7 @@ master_processor_id = cpuid.feature._.apic_id; /* create a va to pa mapping for LAPIC address*/ - lapic_base_address = (IA32_APIC_BASE_MSR_PTR) MapPhysicalMemory(&kernel_map, LAPIC_BASE_MSR_START, LAPIC_MEMORY_MAP_SIZE ); + lapic_base_address = (IA32_APIC_BASE_MSR_PTR) MapPhysicalMemory(&kernel_map, LAPIC_BASE_MSR_START, LAPIC_MEMORY_MAP_SIZE, 0, PROT_READ|PROT_WRITE ); /*intialize master cpu's LACPI*/ InitLAPIC(); @@ -128,265 +87,3 @@ /* Load TSS so that we can switch to user mode*/ LoadTss(); } - -/*! returns the current processor's LAPIC id - \todo - implement this without CPUID to avoid performance issues -*/ -UINT16 GetCurrentProcessorId() -{ - CPUID_INFO cpuid_info; - LoadCpuIdInfo( &cpuid_info ); - - return cpuid_info.feature._.apic_id; -} - -/*! First function called from asm stub when a Secondary CPU starts -*/ -void SecondaryCpuStart() -{ - CPUID_INFO cpuid; - int processor_id; - - /* inform master CPU that I started*/ - count_running_processors++; - - /* execute cpuid and load the data structure*/ - LoadCpuIdInfo( &cpuid ); - processor_id = cpuid.feature._.apic_id; - memcpy( &processor_i386[processor_id].cpuid, &cpuid, sizeof(CPUID_INFO) ); - - /* initalize the boot thread*/ - InitBootThread( processor_id ); - - /* initialize the lapic*/ - InitLAPIC(); - - /*! enable interrupts*/ - asm volatile("sti"); - - /* Install interrupt handler for the LAPIC timer*/ - InstallInterruptHandler( LOCAL_TIMER_VECTOR_NUMBER-32, LapicTimerHandler, 0); - - /* Load TSS so that we can switch to user mode*/ - LoadTss(); - - /* Start the architecture depended timer for secondary processor - to enable scheduler */ - StartTimer(SCHEDULER_DEFAULT_QUANTUM, TRUE); - - kprintf("Secondary CPU %d is started\n", processor_id); - - ExitThread(); -} -/*! Create a thread with appropriate real mode code to start a secondary CPU - \return Physical address of the stack of the thread. This stack contains real mode code to start. -*/ -static UINT32 CreateSecondaryCPUStartThread() -{ - VADDR va; - VIRTUAL_PAGE_PTR vp; - int i, stack_page_index, size = PAGE_ALIGN_UP( sizeof(THREAD_CONTAINER) ); - - /*allocate contiguous physical pages*/ - if ( (vp = AllocateVirtualPages( size/PAGE_SIZE , VIRTUAL_PAGE_RANGE_TYPE_BELOW_1MB)) == NULL ) - panic("PA not available for starting secondary CPU\n"); - - /*reserve kernel virtual address*/ - if ( AllocateVirtualMemory(&kernel_map, &va, 0, size, 0, 0, NULL) != ERROR_SUCCESS ) - panic("VA not available for starting secondary CPU\n"); - - /*create va to pa mapping*/ - for (i=0;i<size/PAGE_SIZE;i++) - { - if ( CreatePhysicalMapping(kernel_map.physical_map, va+(i*PAGE_SIZE), VP_TO_PHYS(vp+i), 0) != ERROR_SUCCESS ) - panic("VA to PA mapping failed\n"); - } - - /*copy the 16 bit real mode code to the kernel stack page*/ - memcpy( &((THREAD_CONTAINER_PTR)va)->kernel_stack, (void *)&trampoline_data, ((UINT32)&trampoline_end)-((UINT32)&trampoline_data)); - - stack_page_index = OFFSET_OF_MEMBER(THREAD_CONTAINER, kernel_stack) / PAGE_SIZE; - /*return the physical address of the stack*/ - return VP_TO_PHYS(vp+stack_page_index); -} - -/*! Initialize interrupt controllers -*/ -static void InitInterruptControllers() -{ - ACPI_TABLE_MADT *madt_ptr; - ACPI_SUBTABLE_HEADER *sub_header, *table_end; - ACPI_STATUS result; - int i; - - /* disable all interrupts*/ - asm volatile("cli"); - - memset(interrupt_handlers, 0, sizeof(interrupt_handlers)); - - /*! Initialize the PIC*/ - InitPic(PIC_STARTING_VECTOR_NUMBER); - /*initialize the legacy IRQ to interrupt mapping table*/ - for(i=0;i<16;i++) - legacy_irq_redirection_table[i]=i; - - count_ioapic = 0; - - /*! try to read APIC table*/ - result = AcpiGetTable ("APIC", 1, (ACPI_TABLE_HEADER**)(&madt_ptr)); - if ( result == AE_OK ) - { - kprintf("LAPIC Address %p [%s]\n", madt_ptr->Address, madt_ptr->Flags&1 ? "APIC and Dual 8259 Support" : "Only APIC" ); - /* if the machine has both 8259 and IOAPIC support disable the 8259*/ - if ( madt_ptr->Flags & 1 ) - use_pic_8259 = 0; - - sub_header = (ACPI_SUBTABLE_HEADER *) ( ((UINT32)madt_ptr) + sizeof(ACPI_TABLE_MADT) ); - table_end = (ACPI_SUBTABLE_HEADER *) ( ((UINT32)madt_ptr) + madt_ptr->Header.Length ); - - while ( sub_header < table_end ) - { - if ( sub_header->Type == ACPI_MADT_TYPE_IO_APIC ) - { - ACPI_MADT_IO_APIC *p = ( ACPI_MADT_IO_APIC * ) sub_header; - kprintf("IOAPIC ID %d IOAPIC Physical Address = %p GlobalIRQBase %d\n", p->Id, p->Address, p->GlobalIrqBase); - - /*!initialize IOAPIC structures*/ - ioapic[count_ioapic].ioapic_id = p->Id; - ioapic[count_ioapic].end_irq = ioapic[count_ioapic].start_irq = p->GlobalIrqBase; - ioapic[count_ioapic].base_physical_address = (void *) p->Address; - ioapic[count_ioapic].base_virtual_address = (void *) MapPhysicalMemory(&kernel_map, p->Address, PAGE_SIZE); - - /*! initialize the ioapic chip and get total irq supported*/ - ioapic[count_ioapic].end_irq += InitIoApic(ioapic[count_ioapic].base_virtual_address, ioapic[count_ioapic].start_irq+IOAPIC_STARTING_VECTOR_NUMBER); - - count_ioapic++; - } - else if ( sub_header->Type == ACPI_MADT_TYPE_INTERRUPT_OVERRIDE ) - { - ACPI_MADT_INTERRUPT_OVERRIDE * override = (ACPI_MADT_INTERRUPT_OVERRIDE *)sub_header; - legacy_irq_redirection_table[override->SourceIrq] = override->GlobalIrq; - } - else - { - /* if found someother structure just print the type for debugging*/ - if ( sub_header->Type != ACPI_MADT_TYPE_LOCAL_APIC ) - kprintf("ACPI MADT Structure type %d is not yet implemented\n", sub_header->Type); - } - - sub_header = (ACPI_SUBTABLE_HEADER *) ( ((UINT32)sub_header) + sub_header->Length ); - } - } - else - { - #ifdef CONFIG_SMP - kprintf("AcpiGetTable() failed Code=%d, assuming uniprocessor and using 8259 PIC\n", result); - #endif - use_pic_8259 = 1; - } - - /*! disable PIC if we dont need it*/ - if ( !use_pic_8259 ) - MaskPic(); - - /*! enable interrupts*/ - asm volatile("sti"); -} - -void SendEndOfInterrupt(int int_no) -{ - if ( use_pic_8259 ) - SendEndOfInterruptTo8259(int_no); - else - SendEndOfInterruptToLapic(int_no); -} - -/*! Initializes the Secondary processors and IOAPIC - - 1) Read the ACPI tables to processor count and their ids - 2) While reading the table start processors if LAPIC ids are found - This is done here beacause ACPI spec says, processor initialization should be done in the same order as they appear in the APIC table - 3) If IOAPIC id is found during the table read store it. -*/ -void InitSecondaryProcessors() -{ - ACPI_TABLE_MADT *madt_ptr; - ACPI_SUBTABLE_HEADER *sub_header, *table_end; - ACPI_STATUS result; - - /*only master is running now*/ - count_running_processors = 1; - - /*! try to read APIC table*/ - result = AcpiGetTable ("APIC", 1, (ACPI_TABLE_HEADER**)(&madt_ptr)); - if ( result == AE_OK ) - { - sub_header = (ACPI_SUBTABLE_HEADER *) ( ((UINT32)madt_ptr) + sizeof(ACPI_TABLE_MADT) ); - table_end = (ACPI_SUBTABLE_HEADER *) ( ((UINT32)madt_ptr) + madt_ptr->Header.Length ); - - while ( sub_header < table_end ) - { - if ( sub_header->Type == ACPI_MADT_TYPE_LOCAL_APIC ) - { - ACPI_MADT_LOCAL_APIC *p = ( ACPI_MADT_LOCAL_APIC * ) sub_header; - if ( (p->LapicFlags & 1) && (p->Id < MAX_PROCESSORS) ) - { - processor[p->ProcessorId].state = ( (p->LapicFlags & 1) ? (PROCESSOR_STATE_ONLINE) : (PROCESSOR_STATE_OFFLINE) ); - processor_i386[p->ProcessorId].apic_id = p->Id; - /*master processor is already running, so dont try to start it again*/ - if ( processor_i386[p->ProcessorId].apic_id != master_processor_id ) - { - UINT32 pa = CreateSecondaryCPUStartThread(); - kprintf("Starting secondary processor (ID %d LAPIC %d) \n", p->ProcessorId, p->Id ); - StartProcessor( processor_i386[p->ProcessorId].apic_id, pa ); - } - } - else - { - kprintf("CPU %d (APIC id %d state %d) cant added to the processor array\n", p->ProcessorId, p->Id, p->LapicFlags); - } - } - sub_header = (ACPI_SUBTABLE_HEADER *) ( ((UINT32)sub_header) + sub_header->Length ); - } - } -} - -/*! Halt the processor until external interrupt comes*/ -void ArchHalt() -{ - asm("hlt"); -} - -/*! Take the cpu to offline - \todo implementation needed using acpi -*/ -void ArchShutdown() -{ - asm("cli;hlt"); -} - -/*! Flushes the currently executing CPU's cache - \note use it care fully to avoid performance impact -*/ -void FlushCpuCache(BOOLEAN write_back) -{ - if ( write_back ) - asm volatile ("wbinvd"); - else - asm volatile ("invd"); -} -/*! Invalidates all the tlb in the CPU -*/ -void InvalidateAllTlb() -{ - /*there is no instruction to clear all TLB in i386, so just rewrite the cr3 - which will clear all the TLBs */ - asm volatile("mov %%cr3, %%eax;\ - mov %%eax, %%cr3" - :); -} -/*! Invalidates the tlb for a given va in the CPU -*/ -void InvalidateTlb(void * va) -{ - asm volatile("invlpg (%%eax)" : : "a" (va) ); -} Added: src/kernel/i386/bios.c =================================================================== --- src/kernel/i386/bios.c (rev 0) +++ src/kernel/i386/bios.c 2009-06-10 10:50:58 UTC (rev 367) @@ -0,0 +1,85 @@ +/*! + \file kernel/i386/bios.c + \brief Functions to call BIOS 16bit code from protected mode using v86 mode +*/ + +#include <ace.h> +#include <kernel/debug.h> +#include <kernel/arch.h> +#include <kernel/pm/pm_types.h> +#include <kernel/pm/task.h> +#include <kernel/pm/thread.h> +#include <kernel/i386/i386.h> + +/*! register content of last v86 thread which made int21 */ +REGS_V86 last_v86_thread_context; + +/*! Handles interrupts 21 raised from a v86 thread + For now just terminate the thread after collecting the register information. +*/ +void BiosInt21Handler(REGS_PTR reg) +{ + REGS_V86_PTR v86_reg = (REGS_V86_PTR) reg; + memmove( &last_v86_thread_context, v86_reg, sizeof(REGS_V86) ); + ExitThread(); +} + +/*! Call 16bit BIOS interrupts from 32bit code + \param interrupt - interrupt number to invoke + \param input - register values for v86 mode + \return register value during the exit of the v86 mode thread +*/ +REGS_V86_PTR CallBiosIsr(BYTE interrupt, REGS_V86_PTR input) +{ + THREAD_I386 arg; + VADDR entry_point; + TASK_PTR task; + UINT32 va=NULL; + UINT16 program[2]; + THREAD_CONTAINER_PTR thread_container; + + /*Dynamically create a 16bit program + 1) INT interrupt - to invoke the given ISR + 2) INT 13 - to collect the register values and terminate + opcode for INT instruction is 0xCD*/ + program[0] = interrupt<<8 | 0xCD; + program[1] = 0x13<<8 | 0xCD; + + AllocateVirtualMemory( GetCurrentVirtualMap(), &va, 0, PAGE_SIZE, PROT_READ|PROT_WRITE, 0, NULL ); + memmove( (void *)va,(void *) program, sizeof(program) ); + task = CreateTask((char *)va, IMAGE_TYPE_BIN_PROGRAM, TASK_CREATION_FLAG_NO_THREAD, &entry_point, NULL, NULL); + if ( task == NULL ) + { + KTRACE("Failed to create task"); + return NULL; + } + + memset( &arg, 0, sizeof(arg) ); + /*create v86 thread*/ + arg.is_v86 = 1; + arg.interrupt_handler = BiosInt21Handler; + /*copy any register values given as input*/ + if( input != NULL ) + memmove( &arg.input_regs, input, sizeof(REGS_V86) ); + + thread_container = CreateThread(task, (void *)I386LinearToFp(entry_point), SCHED_PRI_HIGH, FALSE, (VADDR)&arg); + if( thread_container == NULL ) + { + KTRACE("Failed to create thread"); + return NULL; + } + /*wait for the thread to terminate*/ + WaitForThread( &thread_container->thread, 0 ); + FreeThread( &thread_container->thread ); + + return &last_v86_thread_context; +} + +/*! Converts given 32bit linear address to 16bit far pointer(segment:offset)*/ +UINT32 I386LinearToFp(UINT32 ptr) +{ + unsigned seg, off; + off = ptr & 0xf; + seg = ( ptr - ( ptr & 0xf)) / 16; + return MK_FP(seg, off); +} Modified: src/kernel/i386/exception.c =================================================================== --- src/kernel/i386/exception.c 2009-06-09 17:03:41 UTC (rev 366) +++ src/kernel/i386/exception.c 2009-06-10 10:50:58 UTC (rev 367) @@ -5,12 +5,12 @@ #include <ace.h> #include <kernel/mm/vm.h> -#include <kernel/i386/idt.h> -#include <kernel/i386/exception.h> #include <kernel/debug.h> #include <kernel/arch.h> #include <kernel/error.h> #include <kernel/pm/elf.h> +#include <kernel/pm/thread.h> +#include <kernel/i386/i386.h> /*max depth of page faults inside page fault*/ #define MAX_SERIAL_PAGE_FAULTS 2 @@ -57,18 +57,27 @@ #define REG_FORMAT "0x%08x\t" #define SEG_FORMAT "0x%02x" -#define PRINT_REGS(reg)\ - {\ - int offset;\ - char * func;\ - kprintf("eax="REG_FORMAT"ebx="REG_FORMAT"ecx="REG_FORMAT"edx="REG_FORMAT"\n", reg->eax, reg->ebx, reg->ecx, reg->edx);\ - kprintf("esi="REG_FORMAT"edi="REG_FORMAT"ebp="REG_FORMAT"esp="REG_FORMAT"\n", reg->esi, reg->edi, reg->ebp, reg->esp);\ - kprintf("cs:eip="SEG_FORMAT":"REG_FORMAT"[user stack ss:esp="SEG_FORMAT":"REG_FORMAT"]\n", reg->cs, reg->eip, reg->ss, reg->useresp);\ - kprintf("ds="SEG_FORMAT" es="SEG_FORMAT" gs="SEG_FORMAT" fs="SEG_FORMAT" eflags=0x%X err=0x%X\n", reg->ds, reg->es, reg->gs, reg->fs, reg->eflags, reg->error_code);\ - kprintf("cr0="REG_FORMAT" cr1="REG_FORMAT" cr2="REG_FORMAT" cr3="REG_FORMAT"\n", reg->cr0, reg->cr1, reg->cr2, reg->cr3);\ - func = FindKernelSymbolByAddress(reg->eip, &offset);\ - kprintf("Fault at %s+%p\n", func, offset);\ +static inline void PrintRegisterValues(REGS_PTR reg) +{ + kprintf("eax="REG_FORMAT"ebx="REG_FORMAT"ecx="REG_FORMAT"edx="REG_FORMAT"\n", reg->eax, reg->ebx, reg->ecx, reg->edx); + kprintf("esi="REG_FORMAT"edi="REG_FORMAT"ebp="REG_FORMAT"esp="REG_FORMAT"\n", reg->esi, reg->edi, reg->ebp, reg->esp); + kprintf("cr0="REG_FORMAT"cr1="REG_FORMAT"cr2="REG_FORMAT"cr3="REG_FORMAT"\n", reg->cr0, reg->cr1, reg->cr2, reg->cr3); + kprintf("ds="SEG_FORMAT" es="SEG_FORMAT" gs="SEG_FORMAT" fs="SEG_FORMAT" eflags=0x%X err=0x%X\n", reg->ds, reg->es, reg->gs, reg->fs, reg->eflags, reg->error_code); + kprintf("cs:eip="SEG_FORMAT":"REG_FORMAT" user ss:esp="SEG_FORMAT":"REG_FORMAT"\n", reg->cs, reg->eip, reg->ss, reg->useresp); + if( reg->eflags & EFLAG_VM86 ) + { + REGS_V86_PTR v86_reg = (REGS_V86_PTR)reg; + /*if v86 thread print v86 specific segment registers also*/ + kprintf("V86 ds="SEG_FORMAT" es="SEG_FORMAT" gs="SEG_FORMAT" fs="SEG_FORMAT"\n", v86_reg->v86.ds, v86_reg->v86.es, v86_reg->v86.gs, v86_reg->v86.fs ); } + else + { + int offset; + char * func; + func = FindKernelSymbolByAddress(reg->eip, &offset); + kprintf("Fault at %s+%p\n", func, offset); + } +} /*! All of our Exception handling Interrupt Service Routines will point to this function. * This will tell us what exception has happened. @@ -77,7 +86,7 @@ { kprintf("######### Unhandled Exception [%s] - No [%d]########\n", exception_messages[reg->int_no], reg->int_no); /*now print some useful info from regs structure for debugging*/ - PRINT_REGS( reg ); + PrintRegisterValues( reg ); kprintf("System Halted!\n"); ArchShutdown(); } @@ -85,20 +94,43 @@ /*! i386 specific page fault handler*/ void PageFaultHandler(REGS_PTR reg) { + VIRTUAL_MAP_PTR virtual_map; + VADDR va; PF_ERROR_CODE err; static int inside_page_fault; + + va = reg->cr2; err.all = reg->error_code; + virtual_map = GetCurrentVirtualMap(); + /*page fault can happen while handling a page fault but not more than MAX_SERIAL_PAGE_FAULTS*/ if ( inside_page_fault > MAX_SERIAL_PAGE_FAULTS ) { - PRINT_REGS(reg); + PrintRegisterValues(reg); panic("Inside page fault"); } - inside_page_fault++; - if ( MemoryFaultHandler( reg->cr2, err.user, err.write ) != ERROR_SUCCESS ) + + /*for v86 tasks identity map first 1mb*/ + if( reg->eflags & EFLAG_VM86 ) { + if( va < (1024*1024) && GetVmDescriptor(virtual_map, va, PAGE_SIZE) == NULL ) + { + VADDR new_va; + va = PAGE_ALIGN(va); + new_va = MapPhysicalMemory( GetCurrentVirtualMap(), va, PAGE_SIZE, va, PROT_READ | PROT_WRITE ); + if ( new_va != va ) + { + FreeVirtualMemory(GetCurrentVirtualMap(), va, PAGE_SIZE, 0); + CreatePhysicalMapping(GetCurrentVirtualMap()->physical_map, va, va, PROT_READ | PROT_WRITE ); + } + goto done; + } + } + /*let the vm to handle the fault*/ + if ( MemoryFaultHandler( va, err.user, err.write ) != ERROR_SUCCESS ) + { if ( err.rsvd ) kprintf( "Page fault - RESERVED BIT SET\n"); else @@ -108,27 +140,37 @@ err.write ? "write" : "read", err.present ? "protection failure" : "page not present"); - PRINT_REGS(reg); + PrintRegisterValues(reg); panic("Page fault not handled."); ArchShutdown(); } + +done: inside_page_fault--; } /*! General Protection fault handler - \todo - Add code to just terminate the current task and not to panic */ void GeneralProtectionFaultHandler(REGS_PTR reg) { GPF_ERROR_CODE err; err.all = reg->error_code; + if( reg->eflags & EFLAG_VM86 ) + { + if ( GeneralProtectionFaultHandlerForV86Mode( (REGS_V86_PTR) reg) == TRUE ) + { + return; + } + } + + /*! \todo - Add code to just terminate the current task and not to panic*/ kprintf("General Protection Fault:%s %s descriptor table (index - %d)\n", err.ext ? "External event" : "", err.idt ? "Interrupt" : err.ti ? "Local" : "Global", err.segment_selector_index); - PRINT_REGS(reg); - ArchShutdown(); + PrintRegisterValues(reg); + ArchShutdown(); } /*! Double fault handler @@ -138,3 +180,153 @@ { panic("Double fault: System halted!"); } + +#define VALID_FLAGS 0xDFF +/*! General Protection Handler for virtual 8086 mode + Credit goes to Mobius OS +*/ +int GeneralProtectionFaultHandlerForV86Mode(REGS_V86_PTR v86_reg) +{ + BYTE *ip; + UINT16 *stack, *ivt; + UINT32 *stack32, pa; + int is_operand32, is_address32; + THREAD_PTR thread; + THREAD_I386_PTR i386_thread; + REGS_PTR reg; + + thread = GetCurrentThread(); + assert( thread != NULL ); + i386_thread = (THREAD_I386_PTR)thread->arch_data; + assert( i386_thread != NULL ); + assert( i386_thread->is_v86==1 ); + + reg = &v86_reg->reg; + + ip = FP_TO_LINEAR(reg->cs, reg->eip); + ivt = (UINT16 *) 0; + stack = (UINT16 *) FP_TO_LINEAR(reg->ss, reg->useresp); + stack32 = (UINT32 *) stack; + is_operand32 = is_address32 = FALSE; + + /*create translations for all things that we might touch*/ + if( TranslatePaFromVa((UINT32)ivt, &pa) == VA_NOT_EXISTS ) + CreatePhysicalMapping( GetCurrentVirtualMap()->physical_map, (UINT32)ivt, (UINT32)ivt, PROT_READ|PROT_WRITE ); + if( TranslatePaFromVa((UINT32)stack, &pa) == VA_NOT_EXISTS ) + CreatePhysicalMapping( GetCurrentVirtualMap()->physical_map, (UINT32)stack, (UINT32)stack, PROT_READ|PROT_WRITE ); + if( TranslatePaFromVa((UINT32)stack32, &pa) == VA_NOT_EXISTS ) + CreatePhysicalMapping( GetCurrentVirtualMap()->physical_map, (UINT32)stack32, (UINT32)stack32, PROT_READ|PROT_WRITE ); + + while (TRUE) + { + switch (ip[0]) + { + case 0x66: /* O32 */ + is_operand32 = TRUE; + ip++; + reg->eip = (UINT16 ) (reg->eip + 1); + break; + + case 0x67: /* A32 */ + is_address32 = TRUE; + ip++; + reg->eip = (UINT16 ) (reg->eip + 1); + break; + + case 0x9c: /* PUSHF */ + if (is_operand32) + { + reg->useresp = ((reg->useresp & 0xffff) - 4) & 0xffff; + stack32--; + stack32[0] = reg->eflags & VALID_FLAGS; + + if (i386_thread->eflag_if) + stack32[0] |= EFLAG_IF; + else + stack32[0] &= ~EFLAG_IF; + } + else + { + reg->useresp = ((reg->useresp & 0xffff) - 2) & 0xffff; + stack--; + stack[0] = (UINT16 ) reg->eflags; + + if (i386_thread->eflag_if) + stack[0] |= EFLAG_IF; + else + stack[0] &= ~EFLAG_IF; + } + + reg->eip = (UINT16 ) (reg->eip + 1); + return TRUE; + + case 0x9d: /* POPF */ + if (is_operand32) + { + reg->eflags = EFLAG_VM86 | (stack32[0] & VALID_FLAGS); + i386_thread->eflag_if = (stack32[0] & EFLAG_IF) != 0; + reg->useresp = ((reg->useresp & 0xffff) + 4) & 0xffff; + } + else + { + reg->eflags = EFLAG_VM86 | stack[0]; + i386_thread->eflag_if = (stack[0] & EFLAG_IF) != 0; + reg->useresp = ((reg->useresp & 0xffff) + 2) & 0xffff; + } + + reg->eip = (UINT16 ) (reg->eip + 1); + return TRUE; + + case 0xcd: /* INT n */ + switch (ip[1]) + { + case 0x13: + i386_thread->interrupt_handler(reg); + reg->eip = (UINT16 ) (reg->eip + 2); + return TRUE; + + default: + stack -= 3; + reg->useresp = ((reg->useresp & 0xffff) - 6) & 0xffff; + stack[0] = (UINT16 ) (reg->eip + 2); + stack[1] = reg->cs; + stack[2] = (UINT16 ) reg->eflags; + + if (i386_thread->eflag_if) + stack[2] |= EFLAG_IF; + else + stack[2] &= ~EFLAG_IF; + + reg->cs = ivt[ip[1] * 2 + 1]; + reg->eip = ivt[ip[1] * 2]; + return TRUE; + } + break; + + case 0xcf: /* IRET */ + reg->eip = stack[0]; + reg->cs = stack[1]; + reg->eflags = EFLAG_VIF | EFLAG_IF | EFLAG_VM86 | stack[2]; + i386_thread->eflag_if = (stack[2] & EFLAG_IF) != 0; + + reg->useresp = ((reg->useresp & 0xffff) + 6) & 0xffff; + return TRUE; + + case 0xfa: /* CLI */ + i386_thread->eflag_if = FALSE; + reg->eip = (UINT16 ) (reg->eip + 1); + return TRUE; + + case 0xfb: /* STI */ + i386_thread->eflag_if = TRUE; + reg->eip = (UINT16 ) (reg->eip + 1); + return TRUE; + + default: + kprintf("virtual86 - unhandled opcode 0x%x\n", ip[0]); + reg->eip = (UINT16 ) (reg->eip + 1); + return TRUE; + } + } + return FALSE; +} Modified: src/kernel/i386/gdt.c =================================================================== --- src/kernel/i386/gdt.c 2009-06-09 17:03:41 UTC (rev 366) +++ src/kernel/i386/gdt.c 2009-06-10 10:50:58 UTC (rev 367) @@ -10,11 +10,11 @@ struct gdt_entry gdt[GDT_ENTRIES] = { /*seglow, baselow, base mid, type, S, DPL, P, seghigh, AVL, 0, D, G, base_high*/ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0xFFFF, 0, 0, 10, 1, 0, 1, 0xF, 1, 0, 1, 1, 0}, - {0xFFFF, 0, 0, 2, 1, 0, 1, 0xF, 1, 0, 1, 1, 0}, - {0xFFFF, 0, 0, 10, 1, 3, 1, 0xF, 1, 0, 1, 1, 0}, - {0xFFFF, 0, 0, 2, 1, 3, 1, 0xF, 1, 0, 1, 1, 0} + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /*NULL Descriptor*/ + {0xFFFF, 0, 0, 10, 1, 0, 1, 0xF, 1, 0, 1, 1, 0}, /*kernel code segment descriptor*/ + {0xFFFF, 0, 0, 2, 1, 0, 1, 0xF, 1, 0, 1, 1, 0}, /*kernel data segment descriptor*/ + {0xFFFF, 0, 0, 10, 1, 3, 1, 0xF, 1, 0, 1, 1, 0}, /*user code segment descriptor*/ + {0xFFFF, 0, 0, 2, 1, 3, 1, 0xF, 1, 0, 1, 1, 0} /*user data segment descriptor*/ }; /*global descriptor table register*/ Added: src/kernel/i386/interrupt.c =================================================================== --- src/kernel/i386/interrupt.c (rev 0) +++ src/kernel/i386/interrupt.c 2009-06-10 10:50:58 UTC (rev 367) @@ -0,0 +1,105 @@ +/*! + \file kernel/i386/interrupt.c + \brief i386 specific interrupt controller routines. +*/ +#include <ace.h> +#include <kernel/arch.h> +#include <kernel/parameter.h> +#include <kernel/pm/thread.h> +#include <kernel/i386/i386.h> + +static int use_pic_8259 = 0; + +/*! Initialize interrupt controllers +*/ +void InitInterruptControllers() +{ + ACPI_TABLE_MADT *madt_ptr; + ACPI_SUBTABLE_HEADER *sub_header, *table_end; + ACPI_STATUS result; + int i; + + /* disable all interrupts*/ + asm volatile("cli"); + + memset(interrupt_handlers, 0, sizeof(interrupt_handlers)); + + /*! Initialize the PIC*/ + InitPic(PIC_STARTING_VECTOR_NUMBER); + /*initialize the legacy IRQ to interrupt mapping table*/ + for(i=0;i<16;i++) + legacy_irq_redirection_table[i]=i; + + count_ioapic = 0; + + /*! try to read APIC table*/ + result = AcpiGetTable ("APIC", 1, (ACPI_TABLE_HEADER**)(&madt_ptr)); + if ( result == AE_OK ) + { + kprintf("LAPIC Address %p [%s]\n", madt_ptr->Address, madt_ptr->Flags&1 ? "APIC and Dual 8259 Support" : "Only APIC" ); + /* if the machine has both 8259 and IOAPIC support disable the 8259*/ + if ( madt_ptr->Flags & 1 ) + use_pic_8259 = 0; + + sub_header = (ACPI_SUBTABLE_HEADER *) ( ((UINT32)madt_ptr) + sizeof(ACPI_TABLE_MADT) ); + table_end = (ACPI_SUBTABLE_HEADER *) ( ((UINT32)madt_ptr) + madt_ptr->Header.Length ); + + while ( sub_header < table_end ) + { + if ( sub_header->Type == ACPI_MADT_TYPE_IO_APIC ) + { + ACPI_MADT_IO_APIC *p = ( ACPI_MADT_IO_APIC * ) sub_header; + kprintf("IOAPIC ID %d IOAPIC Physical Address = %p GlobalIRQBase %d\n", p->Id, p->Address, p->GlobalIrqBase); + + /*!initialize IOAPIC structures*/ + ioapic[count_ioapic].ioapic_id = p->Id; + ioapic[count_ioapic].end_irq = ioapic[count_ioapic].start_irq = p->GlobalIrqBase; + ioapic[count_ioapic].base_physical_address = (void *) p->Address; + ioapic[count_ioapic].base_virtual_address = (void *) MapPhysicalMemory(&kernel_map, p->Address, PAGE_SIZE, 0, PROT_READ | PROT_WRITE); + + /*! initialize the ioapic chip and get total irq supported*/ + ioapic[count_ioapic].end_irq += InitIoApic(ioapic[count_ioapic].base_virtual_address, ioapic[count_ioapic].start_irq+IOAPIC_STARTING_VECTOR_NUMBER); + + count_ioapic++; + } + else if ( sub_header->Type == ACPI_MADT_TYPE_INTERRUPT_OVERRIDE ) + { + ACPI_MADT_INTERRUPT_OVERRIDE * override = (ACPI_MADT_INTERRUPT_OVERRIDE *)sub_header; + legacy_irq_redirection_table[override->SourceIrq] = override->GlobalIrq; + } + else + { + /* if found someother structure just print the type for debugging*/ + if ( sub_header->Type != ACPI_MADT_TYPE_LOCAL_APIC ) + kprintf("ACPI MADT Structure type %d is not yet implemented\n", sub_header->Type); + } + + sub_header = (ACPI_SUBTABLE_HEADER *) ( ((UINT32)sub_header) + sub_header->Length ); + } + } + else + { + #ifdef CONFIG_SMP + kprintf("AcpiGetTable() failed Code=%d, assuming uniprocessor and using 8259 PIC\n", result); + #endif + use_pic_8259 = 1; + } + + /*! disable PIC if we dont need it*/ + if ( !use_pic_8259 ) + MaskPic(); + + /*! enable interrupts*/ + asm volatile("sti"); +} + +/*! Sends EOI to either 8259 or LAPIC + \param int_no - interrupt number to acknowledge +*/ +void SendEndOfInterrupt(int int_no) +{ + if ( use_pic_8259 ) + SendEndOfInterruptTo8259(int_no); + else + SendEndOfInterruptToLapic(int_no); +} Modified: src/kernel/i386/interrupt_stub.asm =================================================================== --- src/kernel/i386/interrupt_stub.asm 2009-06-09 17:03:41 UTC (rev 366) +++ src/kernel/i386/interrupt_stub.asm 2009-06-10 10:50:58 UTC (rev 367) @@ -59,16 +59,16 @@ %endmacro ReturnFromInterruptContext: - pop eax + add esp, 16 ; Clean up the pushed control registers cr0, cr1, cr2 - add esp, 12 ; Clean up the pushed control registers cr0, cr1, cr2 - pop eax - mov cr3, eax ; Reload the page directory - \todo - check if we are using same page directory if yes skip this for performance gain + pop eax ; Reload the page directory + mov cr3, eax ; \todo - check if we are using same page directory if yes skip this for performance gain pop gs ; Pop segment registers pop fs pop es pop ds + popa ; Pop general purpose registers add esp, 8 ; Pop interrupt number and error code Modified: src/kernel/i386/mm/pmem.c =================================================================== --- src/kernel/i386/mm/pmem.c 2009-06-09 17:03:41 UTC (rev 366) +++ src/kernel/i386/mm/pmem.c 2009-06-10 10:50:58 UTC (rev 367) @@ -99,8 +99,8 @@ } else { - kprintf("VA %p PA %p Existing PA %p\n", va, pa, mapped_pte->page_pfn<<PAGE_SHIFT); - panic("Trying to map over a existing map\n"); + KPRINTF("VA %p PA %p Existing PA %p\n", va, pa, mapped_pte->page_pfn<<PAGE_SHIFT); + panic("Trying to map over an existing map"); } } else @@ -165,7 +165,6 @@ \param pmap - physical map from the which the mapping should be removed \param va - for which virtual address the mapping should be invalidated \return ERROR_CODE - \todo TLB invalidation \note physical map's lock should be taken by the caller */ ERROR_CODE RemovePhysicalMapping(PHYSICAL_MAP_PTR pmap, UINT32 va) Modified: src/kernel/i386/mm/pmem_init.c =================================================================== --- src/kernel/i386/mm/pmem_init.c 2009-06-09 17:03:41 UTC (rev 366) +++ src/kernel/i386/mm/pmem_init.c 2009-06-10 10:50:58 UTC (rev 367) @@ -383,7 +383,7 @@ EnterKernelPageTableEntry(va, physical_address); physical_address += PAGE_SIZE; va += PAGE_SIZE; - }while( physical_address <= end_physical_address ); + }while( physical_address < end_physical_address ); } /*map virtual page array*/ @@ -404,7 +404,7 @@ EnterKernelPageTableEntry( va, physical_address); physical_address += PAGE_SIZE; va += PAGE_SIZE; - }while( physical_address <= ( end_address ) ); + }while( physical_address < ( end_address ) ); } } Modified: src/kernel/i386/pm/thread.c =================================================================== --- src/kernel/i386/pm/thread.c 2009-06-09 17:03:41 UTC (rev 366) +++ src/kernel/i386/pm/thread.c 2009-06-10 10:50:58 UTC (rev 367) @@ -9,13 +9,8 @@ #include <kernel/pm/pm_types.h> #include <kernel/pm/task.h> #include <kernel/pm/thread.h> -#include <kernel/i386/pmem.h> -#include <kernel/i386/exception.h> -#include <kernel/i386/gdt.h> -#include <kernel/i386/ioapic.h> +#include <kernel/i386/i386.h> -#define EFLAG_VALUE 0x202 - /*gets the current kernel stack position*/ #define GET_KERNEL_STACK(kstack) asm volatile("movl %%esp, %0":"=m"(kstack)) @@ -32,43 +27,87 @@ /*! Fills the given thread container with default register values \param thread_container - thread container \param start_address - starting function pointer of the thread + \param is_kernel_thread - if one create kernel mode thread + \param user_stack - stack for user mode part + \param arch_arg - architecture depended argument(arch depended drivers can use - eg v86 mode driver) */ -void FillThreadContext(THREAD_CONTAINER_PTR thread_container, void * start_address, BYTE is_kernel_thread, VADDR user_stack) +void FillThreadContext(THREAD_CONTAINER_PTR thread_container, void * start_address, BYTE is_kernel_thread, VADDR user_stack, VADDR arch_arg) { UINT32 * stack_frame; REGS_PTR regs; UINT32 cr3; + THREAD_I386_PTR i386_thread; + THREAD_I386_PTR i386_arch_arg = (THREAD_I386_PTR)arch_arg; assert( thread_container != NULL ); + /*\todo - remove KMEM_NO_FAIL and handle kmalloc failure case or use cache allocator*/ + i386_thread = kmalloc( sizeof(THREAD_I386), KMEM_NO_FAIL ); + memset( i386_thread, 0, sizeof(THREAD_I386) ); + thread_container->thread.arch_data = i386_thread; + /*build last stackframe and point it to ExitThread*/ stack_frame = (UINT32 *) (thread_container->kernel_stack + sizeof(thread_container->kernel_stack)); stack_frame[-2] = (UINT32)ExitThread; - /*build exception frame*/ - regs = (REGS_PTR)( ((BYTE*)stack_frame) - sizeof(REGS) ); - if ( is_kernel_thread ) + if ( i386_arch_arg && i386_arch_arg->is_v86 ) { - regs->cs = KERNEL_CODE_SELECTOR; - regs->ds = regs->es = regs->gs = regs->fs = regs->ss = KERNEL_DATA_SELECTOR; + REGS_V86_PTR v86_reg; + /*build exception frame*/ + v86_reg = (REGS_V86_PTR)( ((BYTE*)stack_frame) - sizeof(REGS_V86) ); + regs = &v86_reg->reg; + + v86_reg->v86.ds = v86_reg->v86.es = v86_reg->v86.fs = v86_reg->v86.gs = FP_SEG(user_stack); + v86_reg->v86.ds = i386_arch_arg->input_regs.v86.ds; + v86_reg->v86.es = i386_arch_arg->input_regs.v86.es; + v86_reg->v86.fs = i386_arch_arg->input_regs.v86.fs; + v86_reg->v86.gs = i386_arch_arg->input_regs.v86.gs; + + regs->eax = i386_arch_arg->input_regs.reg.eax; + regs->ebx = i386_arch_arg->input_regs.reg.ebx; + regs->ecx = i386_arch_arg->input_regs.reg.ecx; + regs->edx = i386_arch_arg->input_regs.reg.edx; + regs->edi = i386_arch_arg->input_regs.reg.edi; + regs->esi = i386_arch_arg->input_regs.reg.esi; + regs->ebp = i386_arch_arg->input_regs.reg.ebp; + + regs->cs = FP_SEG(start_address); + regs->eip = FP_OFF(start_address); + regs->ds = regs->es = regs->gs = regs->fs = USER_CODE_SELECTOR | USER_PRIVILEGE_LEVEL; + regs->eflags = EFLAG_VALUE | EFLAG_VM86 | EFLAG_VIF | EFLAG_IOPL3; + regs->ss = FP_SEG(user_stack); + regs->useresp = FP_OFF(user_stack); + + i386_thread->is_v86 = 1; + i386_thread->interrupt_handler = i386_arch_arg->interrupt_handler; } else { - regs->cs = USER_CODE_SELECTOR | USER_PRIVILEGE_LEVEL; - regs->ds = regs->es = regs->gs = regs->fs = regs->ss = USER_DATA_SELECTOR | USER_PRIVILEGE_LEVEL; - regs->useresp = user_stack + USER_STACK_SIZE; /*stack grows from top to bottom*/ + /*build exception frame*/ + regs = (REGS_PTR)( ((BYTE*)stack_frame) - sizeof(REGS) ); + + if ( is_kernel_thread ) + { + regs->cs = KERNEL_CODE_SELECTOR; + regs->ds = regs->es = regs->gs = regs->fs = regs->ss = KERNEL_DATA_SELECTOR; + } + else + { + regs->cs = USER_CODE_SELECTOR | USER_PRIVILEGE_LEVEL; + regs->ds = regs->es = regs->gs = regs->fs = regs->ss = USER_DATA_SELECTOR | USER_PRIVILEGE_LEVEL; + regs->useresp = user_stack+USER_STACK_SIZE-1; + } + regs->eip = (UINT32)start_address; + regs->eflags = EFLAG_VALUE; } + + /*! update the stack address*/ + thread_container->kernel_stack_pointer = (BYTE *) (((UINT32)regs) - sizeof(UINT32)); - regs->eip = (UINT32)start_address; - regs->eflags = EFLAG_VALUE; - /*get the physical address of the page directory*/ if( TranslatePaFromVa((VADDR)thread_container->thread.task->virtual_map->physical_map->page_directory, &cr3) == VA_NOT_EXISTS ) panic("page directory has no mapping"); regs->cr3 = cr3; - - /*! update the stack address*/ - thread_container->kernel_stack_pointer = (BYTE *) (((UINT32)regs) - sizeof(UINT32)); } /*! Switches the execution context to the given thread @@ -77,7 +116,6 @@ void SwitchContext(THREAD_CONTAINER_PTR thread_container) { BYTE * esp; - assert( thread_container->kernel_stack_pointer != 0); esp = thread_container->kernel_stack_pointer; /*reset the ring 0 stack pointer*/ Added: src/kernel/i386/processor.c =================================================================== --- src/kernel/i386/processor.c (rev 0) +++ src/kernel/i386/processor.c 2009-06-10 10:50:58 UTC (rev 367) @@ -0,0 +1,218 @@ +/*! + \file kernel/i386/processor.c + \brief x86 processor specific routines +*/ +#include <ace.h> +#include <kernel/arch.h> +#include <kernel/parameter.h> +#include <kernel/pm/thread.h> +#include <kernel/i386/i386.h> + +extern UINT32 trampoline_data, trampoline_end; + +/*! i386 processor information*/ +PROCESSOR_I386 processor_i386[MAX_PROCESSORS]; +/*! master processor id*/ +UINT16 master_processor_id = 0; + +static UINT32 CreateSecondaryCPUStartThread(); + + +/*! CPU frequency - Ace requires all the processor to run at the same frequency + This variable should populated during init. +*/ +UINT32 cpu_frequency = 0; + +/*! ReaD Time Stamp Counter + * Reads the current processor time stamp using the rdtsc instruction. + * cpuid instruction is used to serialize the read operation. + * \return current processor time stamap + */ +inline UINT64 rdtsc() +{ + UINT32 lo, hi; + /* + * cpuid will serialize the following rdtsc with respect to all other + * instructions the processor may be handling. + */ + __asm__ __volatile__ ( + "xorl %%eax, %%eax\n" + "cpuid\n" + "rdtsc\n" + : "=a" (lo), "=d" (hi) + : + : "%ebx", "%ecx"); + return (UINT64)hi << 32 | lo; +} + +/*! returns the current processor's LAPIC id + \todo - implement this without CPUID to avoid performance issues +*/ +UINT16 GetCurrentProcessorId() +{ + CPUID_INFO cpuid_info; + LoadCpuIdInfo( &cpuid_info ); + + return cpuid_info.feature._.apic_id; +} + +/*! Initializes the Secondary processors and IOAPIC + + 1) Read the ACPI tables to processor count and their ids + 2) While reading the table start processors if LAPIC ids are found + This is done here beacause ACPI spec says, processor initialization should be done in the same order as they appear in the APIC table + 3) If IOAPIC id is found during the table read store it. +*/ +void InitSecondaryProcessors() +{ + ACPI_TABLE_MADT *madt_ptr; + ACPI_SUBTABLE_HEADER *sub_header, *table_end; + ACPI_STATUS result; + + /*only master is running now*/ + count_running_processors = 1; + + /*! try to read APIC table*/ + result = AcpiGetTable ("APIC", 1, (ACPI_TABLE_HEADER**)(&madt_ptr)); + if ( result == AE_OK ) + { + sub_header = (ACPI_SUBTABLE_HEADER *) ( ((UINT32)madt_ptr) + sizeof(ACPI_TABLE_MADT) ); + table_end = (ACPI_SUBTABLE_HEADER *) ( ((UINT32)madt_ptr) + madt_ptr->Header.Length ); + + while ( sub_header < table_end ) + { + if ( sub_header->Type == ACPI_MADT_TYPE_LOCAL_APIC ) + { + ACPI_MADT_LOCAL_APIC *p = ( ACPI_MADT_LOCAL_APIC * ) sub_header; + if ( (p->LapicFlags & 1) && (p->Id < MAX_PROCESSORS) ) + { + processor[p->ProcessorId].state = ( (p->LapicFlags & 1) ? (PROCESSOR_STATE_ONLINE) : (PROCESSOR_STATE_OFFLINE) ); + processor_i386[p->ProcessorId].apic_id = p->Id; + /*master processor is already running, so dont try to start it again*/ + if ( processor_i386[p->ProcessorId].apic_id != master_processor_id ) + { + UINT32 pa = CreateSecondaryCPUStartThread(); + kprintf("Starting secondary processor (ID %d LAPIC %d) \n", p->ProcessorId, p->Id ); + StartProcessor( processor_i386[p->ProcessorId].apic_id, pa ); + } + } + else + { + kprintf("CPU %d (APIC id %d state %d) cant added to the processor array\n", p->ProcessorId, p->Id, p->LapicFlags); + } + } + sub_header = (ACPI_SUBTABLE_HEADER *) ( ((UINT32)sub_header) + sub_header->Length ); + } + } +} + +/*! First function called from asm stub when a Secondary CPU starts +*/ +void SecondaryCpuStart() +{ + CPUID_INFO cpuid; + int processor_id; + + /* inform master CPU that I started*/ + count_running_processors++; + + /* execute cpuid and load the data structure*/ + LoadCpuIdInfo( &cpuid ); + processor_id = cpuid.feature._.apic_id; + memcpy( &processor_i386[processor_id].cpuid, &cpuid, sizeof(CPUID_INFO) ); + + /* initalize the boot thread*/ + InitBootThread( processor_id ); + + /* initialize the lapic*/ + InitLAPIC(); + + /*! enable interrupts*/ + asm volatile("sti"); + + /* Install interrupt handler for the LAPIC timer*/ + InstallInterruptHandler( LOCAL_TIMER_VECTOR_NUMBER-32, LapicTimerHandler, 0); + + /* Load TSS so that we can switch to user mode*/ + LoadTss(); + + /* Start the architecture depended timer for secondary processor - to enable scheduler */ + StartTimer(SCHEDULER_DEFAULT_QUANTUM, TRUE); + + kprintf("Secondary CPU %d is started\n", processor_id); + + ExitThread(); +} + +/*! Create a thread with appropriate real mode code to start a secondary CPU + \return Physical address of the stack of the thread. This stack contains real mode code to start. +*/ +static UINT32 CreateSecondaryCPUStartThread() +{ + VADDR va; + VIRTUAL_PAGE_PTR vp; + int i, stack_page_index, size = PAGE_ALIGN_UP( sizeof(THREAD_CONTAINER) ); + + /*allocate contiguous physical pages*/ + if ( (vp = AllocateVirtualPages( size/PAGE_SIZE , VIRTUAL_PAGE_RANGE_TYPE_BELOW_1MB)) == NULL ) + panic("PA not available for starting secondary CPU\n"); + + /*reserve kernel virtual address*/ + if ( AllocateVirtualMemory(&kernel_map, &va, 0, size, 0, 0, NULL) != ERROR_SUCCESS ) + panic("VA not available for starting secondary CPU\n"); + + /*create va to pa mapping*/ + for (i=0;i<size/PAGE_SIZE;i++) + { + if ( CreatePhysicalMapping(kernel_map.physical_map, va+(i*PAGE_SIZE), VP_TO_PHYS(vp+i), 0) != ERROR_SUCCESS ) + panic("VA to PA mapping failed\n"); + } + + /*copy the 16 bit real mode code to the kernel stack page*/ + memcpy( &((THREAD_CONTAINER_PTR)va)->kernel_stack, (void *)&trampoline_data, ((UINT32)&trampoline_end)-((UINT32)&trampoline_data)); + + stack_page_index = OFFSET_OF_MEMBER(THREAD_CONTAINER, kernel_stack) / PAGE_SIZE; + /*return the physical address of the stack*/ + return VP_TO_PHYS(vp+stack_page_index); +} + +/*! Halt the processor until external interrupt comes*/ +void ArchHalt() +{ + asm("hlt"); +} + +/*! Take the cpu to offline + \todo implementation needed using acpi +*/ +void ArchShutdown() +{ + asm("cli;hlt"); +} + +/*! Flushes the currently executing CPU's cache + \note use it care fully to avoid performance impact +*/ +void FlushCpuCache(BOOLEAN write_back) +{ + if ( write_back ) + asm volatile ("wbinvd"); + else + asm volatile ("invd"); +} +/*! Invalidates all the tlb in the CPU +*/ +void InvalidateAllTlb() +{ + /*there is no instruction to clear all TLB in i386, so just rewrite the cr3 + which will clear all the TLBs */ + asm volatile("mov %%cr3, %%eax;\ + mov %%eax, %%cr3" + :); +} +/*! Invalidates the tlb for a given va in the CPU +*/ +void InvalidateTlb(void * va) +{ + asm volatile("invlpg (%%eax)" : : "a" (va) ); +} Modified: src/kernel/i386/tss.c =================================================================== --- src/kernel/i386/tss.c 2009-06-09 17:03:41 UTC (rev 366) +++ src/kernel/i386/tss.c 2009-06-10 10:50:58 UTC (rev 367) @@ -8,10 +8,7 @@ #include <kernel/mm/vm.h> #include <kernel/mm/pmem.h> #include <kernel/mm/virtual_page.h> -#include <kernel/i386/pmem.h> -#include <kernel/i386/gdt.h> -#include <kernel/i386/processor.h> -#include <kernel/i386/tss.h> +#include <kernel/i386/i386.h> /*! task state segment for double fault handling. Double faults are usually happens due to stack corruption, if interrupt gate is used to handle double fault then stack corruption will result in a triple fault causing processor reset. @@ -47,12 +44,12 @@ tss->ds = tss->es = tss->fs = tss->gs = KERNEL_DATA_SELECTOR; tss->ss = tss->ss0 = tss->ss1 = tss->ss2 = KERNEL_DATA_SELECTOR; tss->esp = kernel_stack+PAGE_SIZE; - tss->eflags = 0x202; + tss->eflags = EFLAG_VALUE; if ( TranslatePaFromVa( (VADDR)kernel_map.physical_map->page_directory, (VADDR *)&tss->cr3 ) == VA_NOT_EXISTS ) panic( "kernel page table not present" ); /* set to point beyond the TSS limit */ - tss->iomap = ( UINT16 ) sizeof( TSS )-1; + tss->iomap = (UINT16) sizeof( TSS )+1; } /*! Loads tss register for the current cpu*/ Added: src/kernel/i386/vesa/vbe.h =================================================================== --- src/kernel/i386/vesa/vbe.h (rev 0) +++ src/kernel/i386/vesa/vbe.h 2009-06-10 10:50:58 UTC (rev 367) @@ -0,0 +1,76 @@ +/*! + \file kernel/i386/vesa/vbe.h + \brief VBE data structures +*/ + +#ifndef _VBE_H +#define _VBE_H + +/*! Capabilities of display controller*/ +struct vesa_control_info +{ + unsigned char signature[4]; /*! either VESA or VBE */ + unsigned short version; /*! vesa version level*/ + unsigned long oem_string_ptr; /*! VBE far pointer to OEM string*/ + unsigned char capabilities[4]; /*! capabilitis of the display controller*/ + unsigned long video_mode_ptr; /*! VBE far pointer to video mode list*/ + unsigned short total_memory; /*! Number of 64kb blocks*/ + unsigned short oem_software_revision; /*! VBE implementation software revision*/ + unsigned long oem_vendor_name_ptr; /*! VBE far pointer to OEM vendor name*/ + unsigned long oem_product_name_ptr; /*! VBE far pointer to OEM product name*/ + unsigned long oem_product_rev_ptr; /*! VBE far pointer to OEM product revision*/ + unsigned char reserved[222]; + unsigned char oem_data[256]; +}__attribute__ ((packed)); + +struct vesa_mode_info +{ + unsigned short mode_attributes; + unsigned char wina_attributes; + unsigned char winb_attributes; + unsigned short win_granularity; + unsigned short win_size; + unsigned short wina_segment; + unsigned short winb_segment; + unsigned long win_func_ptr; + unsigned short bytes_per_scanline; /*! Full bytes per logical scan line*/ + unsigned short x_resolution; /*! horizontal resolution*/ + unsigned short y_resolution; /*! vertical resolution*/ + unsigned char x_char_size; /*! character cell width in pixels*/ + unsigned char y_char_size; /*! character cell height in pixels*/ + unsigned char number_of_planes; + unsigned char bits_per_pixel; + unsigned char number_of_banks; + unsigned char memory_model; /*! memory mode type - 00-text mode 04-packed pixel 06-direct color etc*/ + unsigned char bank_size; + unsigned char number_of_image_pages; + unsigned char reserved_page; + unsigned char red_mask_size; + unsigned char red_mask_pos; + unsigned char green_mask_size; + unsigned char green_mask_pos; + unsigned char blue_mask_size; + unsigned char blue_mask_pos; + unsigned char reserved_mask_size; + unsigned char reserved_mask_pos; + unsigned char direct_color_mode_info; + unsigned long physical_base_ptr; + unsigned long linear_bytes_per_scan_line; + unsigned char bank_number_of_images; + unsigned char linear_number_of_images; + unsigned char linear_red_mask_size; + unsigned char linear_red_mask_pos; + unsigned char linear_green_mask_size; + unsigned char linear_green_mask_pos; + unsigned char linear_blue_mask_size; + unsigned char linear_blue_mask_pos; + unsigned char linear_reserved_mask_size; + unsigned char linear_reserved_mask_pos; + unsigned char max_pixel_clock; + unsigned char reserved[189]; +}__attribute__ ((packed)); + +typedef struct vesa_control_info VESA_CONTROL_INFO, * VESA_CONTROL_INFO_PTR; +typedef struct vesa_mode_info VESA_MODE_INFO, * VESA_MODE_INFO_PTR; + +#endif Added: src/kernel/i386/vesa/vesa.c =================================================================== --- src/kernel/i386/vesa/vesa.c (rev 0) +++ src/kernel/i386/vesa/vesa.c 2009-06-10 10:50:58 UTC (rev 367) @@ -0,0 +1,165 @@ +/*! + \file kernel/i386/vesa/vesa.c + \brief vesa vbe graphics mode info gathering and setting +*/ + +#include <ace.h> +#include <string.h> +#include <kernel/debug.h> +#include <kernel/io.h> +#include <kernel/pm/thread.h> +#include <kernel/i386/i386.h> +#include "vbe.h" + +#define VESA_INPUT_GET_CONTROL_INFO 0x4F00 +#define VESA_INPUT_GET_MODE_INFO 0x4F01 +#define VESA_INPUT_SET_MODE 0x4F02 + +#define VESA_OUTPUT_SUCCESS 0x004F +#define VESA_OUTPUT_FAILED 0x014F +#define VESA_OUTPUT_FN_NOT_SUPPORTED 0x024F +#define VESA_OUTPUT_FN_INVALID 0x024F + +/*! Converts the given VESA farpointer (segment, off... [truncated message content] |
From: <sam...@us...> - 2009-06-09 17:03:47
|
Revision: 366 http://aceos.svn.sourceforge.net/aceos/?rev=366&view=rev Author: samueldotj Date: 2009-06-09 17:03:41 +0000 (Tue, 09 Jun 2009) Log Message: ----------- Added initial code for devfs Added primitive code for syscalls Ported Bash 3.2.48 to Ace - still tty support is pending so you can execute a script but cant start it in interactive mode Modified CreateDevice() function to take extra parameters to create device nodes under /device Added KPRINTF macro - same as kprintf, it prints current function+line number also Did code refactoring for iom.c and split the functionality into 3 separate files - driver.c, irp.c and iom.c Added extra fields in Task structure to store commandline, environment variables for a task. Fixed a bug in CopyVirtualAddressRange function - now src_size can be smaller than dest_size the remaining bytes will be zero filled. Fixed a bug in a scheduler - a hang condition is now avoided - PreemptThread will be called even if current_thread==new_therad, but nothing will be done in PreemptThread Modified Paths: -------------- src/drivers/acpi/acpi.c src/drivers/pci/pci.c src/drivers/ps2keyboard/keyboard.c src/include/kernel/debug.h src/include/kernel/iom/iom.h src/include/kernel/ipc.h src/include/kernel/mm/vm.h src/include/kernel/pm/task.h src/include/kernel/vfs/vfs.h src/kernel/i386/arch.c src/kernel/i386/pm/thread.c src/kernel/iom/iom.c src/kernel/iom/rootbus.c src/kernel/ipc/message_queue.c src/kernel/ktrace.c src/kernel/main.c src/kernel/mm/vm.c src/kernel/mm/vm_descriptor.c src/kernel/mm/vm_unit.c src/kernel/pm/elf.c src/kernel/pm/scheduler.c src/kernel/pm/task.c src/kernel/pm/thread.c src/kernel/vfs/boot_fs.c src/kernel/vfs/vfs.c src/kernel/vfs/vnode.c src/kernel/wscript_build toolchain/newlib-1.17.0.patch Added Paths: ----------- src/include/kernel/iom/devfs.h src/include/libc/ src/include/libc/sys/ src/include/libc/sys/errno.h src/include/libc/sys/fcntl.h src/include/libc/sys/stat.h src/include/libc/sys/types.h src/include/libc/sys/utsname.h src/kernel/iom/devfs.c src/kernel/iom/driver.c src/kernel/iom/irp.c src/kernel/syscall/ src/kernel/syscall/entry.c src/kernel/syscall/file.c src/kernel/syscall/memory.c src/kernel/syscall/mount.c src/kernel/syscall/process.c src/kernel/syscall/scheduler.c src/kernel/syscall/signal.c src/kernel/syscall/statfs.c src/kernel/syscall/sys.c src/kernel/syscall/terminal.c src/kernel/syscall/time.c src/kernel/syscall/uname.c toolchain/bash-3.2.48.patch Removed Paths: ------------- src/kernel/system_calls.c Modified: src/drivers/acpi/acpi.c =================================================================== --- src/drivers/acpi/acpi.c 2009-05-22 05:21:12 UTC (rev 365) +++ src/drivers/acpi/acpi.c 2009-06-09 17:03:41 UTC (rev 366) @@ -28,7 +28,7 @@ { DEVICE_OBJECT_PTR device_object; ERROR_CODE err; - err = CreateDevice(pDriverObject, sizeof(ACPI_BUS_DEVICE_EXTENSION), &device_object); + err = CreateDevice(pDriverObject, sizeof(ACPI_BUS_DEVICE_EXTENSION), &device_object, NULL); if( err != ERROR_SUCCESS ) return err; InvalidateDeviceRelations(device_object, DEVICE_RELATIONS_TYPE_BUS_RELATION); @@ -67,7 +67,7 @@ if ( ret == AE_OK && dev_info_ptr->Valid & ACPI_VALID_HID ) { DEVICE_OBJECT_PTR child_device_object; - if ( CreateDevice(arg->device_object->driver_object, sizeof(ACPI_BUS_DEVICE_EXTENSION), &child_device_object) == ERROR_SUCCESS ) + if ( CreateDevice(arg->device_object->driver_object, sizeof(ACPI_BUS_DEVICE_EXTENSION), &child_device_object, NULL) == ERROR_SUCCESS ) { ACPI_BUS_DEVICE_EXTENSION_PTR device_ext=child_device_object->device_extension; device_ext->handle = ObjHandle; Modified: src/drivers/pci/pci.c =================================================================== --- src/drivers/pci/pci.c 2009-05-22 05:21:12 UTC (rev 365) +++ src/drivers/pci/pci.c 2009-06-09 17:03:41 UTC (rev 366) @@ -17,8 +17,8 @@ #define MAX_PCI_FUNCTION_PER_DEVICE 8 #if ARCH==i386 - #define PCI_CONFIG_ADDRESS 0xCF8 - #define PCI_CONFIG_DATA 0xCFC + #define PCI_CONFIG_ADDRESS 0xCF8 + #define PCI_CONFIG_DATA 0xCFC #endif typedef struct pci_bus_device_extension PCI_BUS_DEVICE_EXTENSION, * PCI_BUS_DEVICE_EXTENSION_PTR; @@ -98,7 +98,7 @@ { DEVICE_OBJECT_PTR device_object; ERROR_CODE err; - err = CreateDevice(pDriverObject, sizeof(PCI_BUS_DEVICE_EXTENSION), &device_object); + err = CreateDevice(pDriverObject, sizeof(PCI_BUS_DEVICE_EXTENSION), &device_object, NULL); if( err != ERROR_SUCCESS ) return err; InvalidateDeviceRelations(device_object, DEVICE_RELATIONS_TYPE_BUS_RELATION); @@ -134,7 +134,7 @@ char *class_name, *subclass_name, *prog_if_name; get_pci_class_string(pci_conf.base_class_code, pci_conf.sub_class_code, pci_conf.programming_interface, &class_name, &subclass_name, &prog_if_name ); //kprintf("%x %x %s %s %s\n", pci_conf.vendor_id, pci_conf.device_id, class_name, subclass_name, prog_if_name ); - if ( CreateDevice(pDeviceObject->driver_object, sizeof(PCI_BUS_DEVICE_EXTENSION), &child_device_object) == ERROR_SUCCESS ) + if ( CreateDevice(pDeviceObject->driver_object, sizeof(PCI_BUS_DEVICE_EXTENSION), &child_device_object, NULL) == ERROR_SUCCESS ) { PCI_BUS_DEVICE_EXTENSION_PTR device_ext=child_device_object->device_extension; memcpy(&device_ext->pci_conf, &pci_conf, sizeof(PCI_CONFIGURATION_SPACE) ); Modified: src/drivers/ps2keyboard/keyboard.c =================================================================== --- src/drivers/ps2keyboard/keyboard.c 2009-05-22 05:21:12 UTC (rev 365) +++ src/drivers/ps2keyboard/keyboard.c 2009-06-09 17:03:41 UTC (rev 366) @@ -142,7 +142,7 @@ DEVICE_OBJECT_PTR dev_obj; ERROR_CODE err; - err = CreateDevice(drv_obj, 0, &dev_obj); + err = CreateDevice(drv_obj, 0, &dev_obj, NULL); if( err != ERROR_SUCCESS ) return err; Modified: src/include/kernel/debug.h =================================================================== --- src/include/kernel/debug.h 2009-05-22 05:21:12 UTC (rev 365) +++ src/include/kernel/debug.h 2009-06-09 17:03:41 UTC (rev 366) @@ -23,6 +23,9 @@ #define KTRACE( ... ) #endif +#define KPRINTF( ... ) \ + kprintf("%s:%d: ", __PRETTY_FUNCTION__ , __LINE__ ); \ + kprintf( __VA_ARGS__ ); #ifdef __cplusplus extern "C" { Added: src/include/kernel/iom/devfs.h =================================================================== --- src/include/kernel/iom/devfs.h (rev 0) +++ src/include/kernel/iom/devfs.h 2009-06-09 17:03:41 UTC (rev 366) @@ -0,0 +1,39 @@ +/*! \file kernel/iom/devfs.h + \brief devfs metadata structures +*/ + +#ifndef DEVFS_H +#define DEVFS_H + +#include <ace.h> +#include <ds/avl_tree.h> +#include <ds/list.h> +#include <ds/lrulist.h> +#include <heap/slab_allocator.h> + +/*! maximum length of a special file*/ +#define DEVFS_FILE_NAME_MAX 50 + +/*! a special file's directory entry*/ +typedef struct devfs_metadata +{ + char name[DEVFS_FILE_NAME_MAX]; /*! name of the special file */ + DEVICE_OBJECT_PTR device; /*! device associated with the file*/ + + AVL_TREE tree; /*! tree of files*/ +}DEVFS_METADATA, * DEVFS_METADATA_PTR; + +extern AVL_TREE_PTR devfs_root; + +#ifdef __cplusplus + extern "C" { +#endif + +ERROR_CODE CreateDeviceNode(const char * filename, DEVICE_OBJECT_PTR device); + +#ifdef __cplusplus + } +#endif + +#endif + Modified: src/include/kernel/iom/iom.h =================================================================== --- src/include/kernel/iom/iom.h 2009-05-22 05:21:12 UTC (rev 365) +++ src/include/kernel/iom/iom.h 2009-06-09 17:03:41 UTC (rev 366) @@ -14,8 +14,10 @@ #include <kernel/mm/kmem.h> #include <kernel/vfs/vfs.h> +/*! maximum characters in driver name including spaces*/ #define DRIVER_NAME_MAX 50 +/*! total size in bytes to hold given number of device's device relation object*/ #define SIZEOF_DEVICE_RELATIONS(number_of_pdos) (sizeof(DEVICE_RELATIONS) + ((number_of_pdos) * sizeof(DEVICE_OBJECT)) ) typedef enum @@ -220,7 +222,6 @@ DEVICE_OBJECT_PTR objects[0]; }; - extern DEVICE_OBJECT_PTR root_bus_device_object; extern DRIVER_OBJECT_PTR root_bus_driver_object; @@ -228,17 +229,21 @@ extern CACHE device_object_cache; void InitIoManager(); -ERROR_CODE CreateDevice(DRIVER_OBJECT_PTR driver_object, UINT32 device_extension_size, DEVICE_OBJECT_PTR * device_object); + +ERROR_CODE CreateDevice(DRIVER_OBJECT_PTR driver_object, UINT32 device_extension_size, DEVICE_OBJECT_PTR * device_object, char * device_name); DEVICE_OBJECT_PTR AttachDeviceToDeviceStack(DEVICE_OBJECT_PTR source_device, DEVICE_OBJECT_PTR target_device); +void InvalidateDeviceRelations(DEVICE_OBJECT_PTR device_object, DEVICE_RELATION_TYPE type); + IO_STACK_LOCATION_PTR GetNextIrpStackLocation(IRP_PTR Irp); IO_STACK_LOCATION_PTR GetCurrentIrpStackLocation(IRP_PTR Irp); -void InvalidateDeviceRelations(DEVICE_OBJECT_PTR device_object, DEVICE_RELATION_TYPE type); +inline void FillIoStack(IO_STACK_LOCATION_PTR io_stack, BYTE major_function, BYTE minor_function, DEVICE_OBJECT_PTR device_object, IO_COMPLETION_ROUTINE completion_routine, void * context); + IRP_PTR AllocateIrp(BYTE stack_size); void ReuseIrp(IRP_PTR irp, ERROR_CODE error_code); void FreeIrp(IRP_PTR irp); ERROR_CODE CallDriver(DEVICE_OBJECT_PTR device_object, IRP_PTR irp); -inline void FillIoStack(IO_STACK_LOCATION_PTR io_stack, BYTE major_function, BYTE minor_function, DEVICE_OBJECT_PTR device_object, IO_COMPLETION_ROUTINE completion_routine, void * context); DRIVER_OBJECT_PTR LoadRootBusDriver(); ERROR_CODE RootBusDriverEntry(DRIVER_OBJECT_PTR pDriverObject); + #endif Modified: src/include/kernel/ipc.h =================================================================== --- src/include/kernel/ipc.h 2009-05-22 05:21:12 UTC (rev 365) +++ src/include/kernel/ipc.h 2009-06-09 17:03:41 UTC (rev 366) @@ -23,7 +23,7 @@ MESSAGE_TYPE_REFERENCE, MESSAGE_TYPE_SHARE, MESSAGE_TYPE_SHARE_PA -}MESSAGE_TYPE; +}MESSAGE_TYPE, * MESSAGE_TYPE_PTR; typedef enum { @@ -36,15 +36,19 @@ IPC_ARG_COUNT }IPC_ARG_INDEX; -#define IPC_ARG_ADDRESS IPC_ARG_INDEX_5 -#define IPC_ARG_LENGTH IPC_ARG_INDEX_6 +/*! index of address argument in the IPC message*/ +#define IPC_ADDRESS_ARG_INDEX IPC_ARG_INDEX_5 +/*! index of length argument in the IPC message*/ +#define IPC_LENGTH_ARG_INDEX IPC_ARG_INDEX_6 -#define ipc_arg_address ((void *)arg5) -#define ipc_arg_length ((long)arg6) +/*! alias for IPC address argument*/ +#define IPR_ARGUMENT_ADDRESS ((void *)arg5) +/*! alias for IPC length argument*/ +#define IPC_ARGUMENT_LENGTH ((long)arg6) typedef void * IPC_ARG_TYPE; +typedef IPC_ARG_TYPE * IPC_ARG_TYPE_PTR; - typedef struct message_buffer { LIST message_buffer_queue; /*! link list of message buffers in this message queue*/ Modified: src/include/kernel/mm/vm.h =================================================================== --- src/include/kernel/mm/vm.h 2009-05-22 05:21:12 UTC (rev 365) +++ src/include/kernel/mm/vm.h 2009-06-09 17:03:41 UTC (rev 366) @@ -211,7 +211,7 @@ ERROR_CODE FreeVirtualMemory(VIRTUAL_MAP_PTR vmap, VADDR va, UINT32 size, UINT32 flags); ERROR_CODE MapViewOfFile(int file_id, VADDR * va, UINT32 protection, UINT32 file_offset, UINT32 size, UINT32 preferred_start, UINT32 flags); -ERROR_CODE CopyVirtualAddressRange(VIRTUAL_MAP_PTR src_vmap, VADDR src_va, VIRTUAL_MAP_PTR dest_vmap, VADDR *dest_preferred_va, UINT32 dest_size, UINT32 protection); +ERROR_CODE CopyVirtualAddressRange(VIRTUAL_MAP_PTR src_vmap, VADDR src_va, UINT32 src_size, VIRTUAL_MAP_PTR dest_vmap, VADDR *dest_preferred_va, UINT32 dest_size, UINT32 protection); VADDR MapPhysicalMemory(VIRTUAL_MAP_PTR vmap, UINT32 pa, UINT32 size); Modified: src/include/kernel/pm/task.h =================================================================== --- src/include/kernel/pm/task.h 2009-05-22 05:21:12 UTC (rev 365) +++ src/include/kernel/pm/task.h 2009-06-09 17:03:41 UTC (rev 366) @@ -37,7 +37,15 @@ MESSAGE_QUEUE message_queue[MESSAGE_QUEUES_PER_TASK]; /*! Pointer to message queue containing IPC messages */ - PROCESS_FILE_INFO process_file_info; + PROCESS_FILE_INFO process_file_info; /*! open file info */ + + char * kva_command_line; /*! kernel virtual address of command line*/ + char * uva_command_line; /*! user virtual address of command line - once user va is created kva will be freed*/ + + char * kva_environment; /*! kernel virtual address of process environment*/ + char * uva_environment; /*! user virtual address of environment - once user va is created kva will be freed*/ + + char * user_scratch; /*! temporary memory to copy kernel content to user*/ }; extern CACHE task_cache; @@ -51,7 +59,7 @@ int TaskCacheDestructor(void * buffer); void InitKernelTask(); -TASK_PTR CreateTask(char * exe_file_path); +TASK_PTR CreateTask(char * exe_file_path, char * command_line, char * environment); inline TASK_PTR GetCurrentTask(); TASK_PTR PidToTask(int pid); Modified: src/include/kernel/vfs/vfs.h =================================================================== --- src/include/kernel/vfs/vfs.h 2009-05-22 05:21:12 UTC (rev 365) +++ src/include/kernel/vfs/vfs.h 2009-06-09 17:03:41 UTC (rev 366) @@ -224,6 +224,8 @@ ERROR_CODE OpenFile(char * file_path, VFS_ACCESS_TYPE access, VFS_OPEN_FLAG open_flag, int * file_id); ERROR_CODE CloseFile(int file_id); +ERROR_CODE GetVfsMessage(MESSAGE_QUEUE_PTR message_queue, UINT32 wait_time, MESSAGE_TYPE_PTR type, IPC_ARG_TYPE_PTR arg1, IPC_ARG_TYPE_PTR arg2, IPC_ARG_TYPE_PTR arg3, IPC_ARG_TYPE_PTR arg4, IPC_ARG_TYPE_PTR arg5, IPC_ARG_TYPE_PTR arg6); + #ifdef __cplusplus } #endif Added: src/include/libc/sys/errno.h =================================================================== --- src/include/libc/sys/errno.h (rev 0) +++ src/include/libc/sys/errno.h 2009-06-09 17:03:41 UTC (rev 366) @@ -0,0 +1,131 @@ +/*! User mode error numbers*/ +#ifndef _SYS_ERRNO_H_ +#define _SYS_ERRNO_H_ + +#define EPERM 1 /* Not super-user */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No children */ +#define EAGAIN 11 /* No more processes */ +#define ENOMEM 12 /* Not enough core */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Mount device busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* Too many open files in system */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math arg out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define ENOMSG 35 /* No message of desired type */ +#define EIDRM 36 /* Identifier removed */ +#define ECHRNG 37 /* Channel number out of range */ +#define EL2NSYNC 38 /* Level 2 not synchronized */ +#define EL3HLT 39 /* Level 3 halted */ +#define EL3RST 40 /* Level 3 reset */ +#define ELNRNG 41 /* Link number out of range */ +#define EUNATCH 42 /* Protocol driver not attached */ +#define ENOCSI 43 /* No CSI structure available */ +#define EL2HLT 44 /* Level 2 halted */ +#define EDEADLK 45 /* Deadlock condition */ +#define ENOLCK 46 /* No record locks available */ +#define EBADE 50 /* Invalid exchange */ +#define EBADR 51 /* Invalid request descriptor */ +#define EXFULL 52 /* Exchange full */ +#define ENOANO 53 /* No anode */ +#define EBADRQC 54 /* Invalid request code */ +#define EBADSLT 55 /* Invalid slot */ +#define EDEADLOCK 56 /* File locking deadlock error */ +#define EBFONT 57 /* Bad font file fmt */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data (for no delay io) */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* The object is remote */ +#define ENOLINK 67 /* The link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 74 /* Multihop attempted */ +#define ELBIN 75 /* Inode is remote (not really error) */ +#define EDOTDOT 76 /* Cross mount point (not really error) */ +#define EBADMSG 77 /* Trying to read unreadable message */ +#define EFTYPE 79 /* Inappropriate file type or format */ +#define ENOTUNIQ 80 /* Given log. name not unique */ +#define EBADFD 81 /* f.d. invalid for this operation */ +#define EREMCHG 82 /* Remote address changed */ +#define ELIBACC 83 /* Can't access a needed shared lib */ +#define ELIBBAD 84 /* Accessing a corrupted shared lib */ +#define ELIBSCN 85 /* .lib section in a.out corrupted */ +#define ELIBMAX 86 /* Attempting to link in too many libs */ +#define ELIBEXEC 87 /* Attempting to exec a shared library */ +#define ENOSYS 88 /* Function not implemented */ +#define ENMFILE 89 /* No more files */ +#define ENOTEMPTY 90 /* Directory not empty */ +#define ENAMETOOLONG 91 /* File or path name too long */ +#define ELOOP 92 /* Too many symbolic links */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EAFNOSUPPORT 106 /* Address family not supported by protocol family */ +#define EPROTOTYPE 107 /* Protocol wrong type for socket */ +#define ENOTSOCK 108 /* Socket operation on non-socket */ +#define ENOPROTOOPT 109 /* Protocol not available */ +#define ESHUTDOWN 110 /* Can't send after socket shutdown */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EADDRINUSE 112 /* Address already in use */ +#define ECONNABORTED 113 /* Connection aborted */ +#define ENETUNREACH 114 /* Network is unreachable */ +#define ENETDOWN 115 /* Network interface is not configured */ +#define ETIMEDOUT 116 /* Connection timed out */ +#define EHOSTDOWN 117 /* Host is down */ +#define EHOSTUNREACH 118 /* Host is unreachable */ +#define EINPROGRESS 119 /* Connection already in progress */ +#define EALREADY 120 /* Socket already connected */ +#define EDESTADDRREQ 121 /* Destination address required */ +#define EMSGSIZE 122 /* Message too long */ +#define EPROTONOSUPPORT 123 /* Unknown protocol */ +#define ESOCKTNOSUPPORT 124 /* Socket type not supported */ +#define EADDRNOTAVAIL 125 /* Address not available */ +#define ENETRESET 126 +#define EISCONN 127 /* Socket is already connected */ +#define ENOTCONN 128 /* Socket is not connected */ +#define ETOOMANYREFS 129 +#define EPROCLIM 130 +#define EUSERS 131 +#define EDQUOT 132 +#define ESTALE 133 +#define ENOTSUP 134 /* Not supported */ +#define ENOMEDIUM 135 /* No medium (in tape drive) */ +#define ENOSHARE 136 /* No such host or network path */ +#define ECASECLASH 137 /* Filename exists with different case */ +#define EILSEQ 138 +#define EOVERFLOW 139 /* Value too large for defined data type */ +#define ECANCELED 140 /* Operation canceled */ +#define ENOTRECOVERABLE 141 /* State not recoverable */ +#define EOWNERDEAD 142 /* Previous owner died */ + +#endif Added: src/include/libc/sys/fcntl.h =================================================================== --- src/include/libc/sys/fcntl.h (rev 0) +++ src/include/libc/sys/fcntl.h 2009-06-09 17:03:41 UTC (rev 366) @@ -0,0 +1,157 @@ +#ifndef _SYS_FCNTL_H_ +#define _SYS_FCNTL_H_ + +#define _FOPEN (-1) /* from sys/file.h, kernel use only */ +#define _FREAD 0x0001 /* read enabled */ +#define _FWRITE 0x0002 /* write enabled */ +#define _FAPPEND 0x0008 /* append (writes guaranteed at the end) */ +#define _FMARK 0x0010 /* internal; mark during gc() */ +#define _FDEFER 0x0020 /* internal; defer for next gc pass */ +#define _FASYNC 0x0040 /* signal pgrp when data ready */ +#define _FSHLOCK 0x0080 /* BSD flock() shared lock present */ +#define _FEXLOCK 0x0100 /* BSD flock() exclusive lock present */ +#define _FCREAT 0x0200 /* open with file create */ +#define _FTRUNC 0x0400 /* open with truncation */ +#define _FEXCL 0x0800 /* error on open if file exists */ +#define _FNBIO 0x1000 /* non blocking I/O (sys5 style) */ +#define _FSYNC 0x2000 /* do all writes synchronously */ +#define _FNONBLOCK 0x4000 /* non blocking I/O (POSIX style) */ +#define _FNDELAY _FNONBLOCK /* non blocking I/O (4.2 style) */ +#define _FNOCTTY 0x8000 /* don't assign a ctty on this open */ + +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) + +/* + * Flag values for open(2) and fcntl(2) + * The kernel adds 1 to the open modes to turn it into some + * combination of FREAD and FWRITE. + */ +#define O_RDONLY 0 /* +1 == FREAD */ +#define O_WRONLY 1 /* +1 == FWRITE */ +#define O_RDWR 2 /* +1 == FREAD|FWRITE */ +#define O_APPEND _FAPPEND +#define O_CREAT _FCREAT +#define O_TRUNC _FTRUNC +#define O_EXCL _FEXCL +#define O_SYNC _FSYNC +/* O_NDELAY _FNDELAY set in include/fcntl.h */ +/* O_NDELAY _FNBIO set in include/fcntl.h */ +#define O_NONBLOCK _FNONBLOCK +#define O_NOCTTY _FNOCTTY +/* For machines which care - */ +#if defined (_WIN32) || defined (__CYGWIN__) +#define _FBINARY 0x10000 +#define _FTEXT 0x20000 +#define _FNOINHERIT 0x40000 + +#define O_BINARY _FBINARY +#define O_TEXT _FTEXT +#define O_NOINHERIT _FNOINHERIT + +/* The windows header files define versions with a leading underscore. */ +#define _O_RDONLY O_RDONLY +#define _O_WRONLY O_WRONLY +#define _O_RDWR O_RDWR +#define _O_APPEND O_APPEND +#define _O_CREAT O_CREAT +#define _O_TRUNC O_TRUNC +#define _O_EXCL O_EXCL +#define _O_TEXT O_TEXT +#define _O_BINARY O_BINARY +#define _O_RAW O_BINARY +#define _O_NOINHERIT O_NOINHERIT +#endif + +#ifndef _POSIX_SOURCE + +/* + * Flags that work for fcntl(fd, F_SETFL, FXXXX) + */ +#define FAPPEND _FAPPEND +#define FSYNC _FSYNC +#define FASYNC _FASYNC +#define FNBIO _FNBIO +#define FNONBIO _FNONBLOCK /* XXX fix to be NONBLOCK everywhere */ +#define FNDELAY _FNDELAY + +/* + * Flags that are disallowed for fcntl's (FCNTLCANT); + * used for opens, internal state, or locking. + */ +#define FREAD _FREAD +#define FWRITE _FWRITE +#define FMARK _FMARK +#define FDEFER _FDEFER +#define FSHLOCK _FSHLOCK +#define FEXLOCK _FEXLOCK + +/* + * The rest of the flags, used only for opens + */ +#define FOPEN _FOPEN +#define FCREAT _FCREAT +#define FTRUNC _FTRUNC +#define FEXCL _FEXCL +#define FNOCTTY _FNOCTTY + +#endif /* !_POSIX_SOURCE */ + +/* XXX close on exec request; must match UF_EXCLOSE in user.h */ +#define FD_CLOEXEC 1 /* posix */ + +/* fcntl(2) requests */ +#define F_DUPFD 0 /* Duplicate fildes */ +#define F_GETFD 1 /* Get fildes flags (close on exec) */ +#define F_SETFD 2 /* Set fildes flags (close on exec) */ +#define F_GETFL 3 /* Get file flags */ +#define F_SETFL 4 /* Set file flags */ +#ifndef _POSIX_SOURCE +#define F_GETOWN 5 /* Get owner - for ASYNC */ +#define F_SETOWN 6 /* Set owner - for ASYNC */ +#endif /* !_POSIX_SOURCE */ +#define F_GETLK 7 /* Get record-locking information */ +#define F_SETLK 8 /* Set or Clear a record-lock (Non-Blocking) */ +#define F_SETLKW 9 /* Set or Clear a record-lock (Blocking) */ +#ifndef _POSIX_SOURCE +#define F_RGETLK 10 /* Test a remote lock to see if it is blocked */ +#define F_RSETLK 11 /* Set or unlock a remote lock */ +#define F_CNVT 12 /* Convert a fhandle to an open fd */ +#define F_RSETLKW 13 /* Set or Clear remote record-lock(Blocking) */ +#endif /* !_POSIX_SOURCE */ + +/* fcntl(2) flags (l_type field of flock structure) */ +#define F_RDLCK 1 /* read lock */ +#define F_WRLCK 2 /* write lock */ +#define F_UNLCK 3 /* remove lock(s) */ +#ifndef _POSIX_SOURCE +#define F_UNLKSYS 4 /* remove remote locks for a given system */ +#endif /* !_POSIX_SOURCE */ + +/*#include <sys/stdtypes.h>*/ + +/* file segment locking set data type - information passed to system by user */ +struct flock { + short l_type; /* F_RDLCK, F_WRLCK, or F_UNLCK */ + short l_whence; /* flag to choose starting offset */ + long l_start; /* relative offset, in bytes */ + long l_len; /* length, in bytes; 0 means lock to EOF */ + short l_pid; /* returned with F_GETLK */ + short l_xxx; /* reserved for future use */ +}; + +#ifndef _POSIX_SOURCE +/* extended file segment locking set data type */ +struct eflock { + short l_type; /* F_RDLCK, F_WRLCK, or F_UNLCK */ + short l_whence; /* flag to choose starting offset */ + long l_start; /* relative offset, in bytes */ + long l_len; /* length, in bytes; 0 means lock to EOF */ + short l_pid; /* returned with F_GETLK */ + short l_xxx; /* reserved for future use */ + long l_rpid; /* Remote process id wanting this lock */ + long l_rsys; /* Remote system id wanting this lock */ +}; +#endif /* !_POSIX_SOURCE */ + + +#endif Added: src/include/libc/sys/stat.h =================================================================== --- src/include/libc/sys/stat.h (rev 0) +++ src/include/libc/sys/stat.h 2009-06-09 17:03:41 UTC (rev 366) @@ -0,0 +1,72 @@ +#ifndef _SYS_STAT_H +#define _SYS_STAT_H + +#include <sys/types.h> + +struct stat +{ + dev_t st_dev; /*Device ID of device containing file. */ + ino_t st_ino; /*File serial number. */ + mode_t st_mode; /*Mode of file */ + nlink_t st_nlink; /*Number of hard links to the file. */ + uid_t st_uid; /*User ID of file. */ + gid_t st_gid; /*Group ID of file. */ + + dev_t st_rdev; /*Device ID (if file is character or block special). */ + + off_t st_size; /*For regular files, the file size in bytes. + For symbolic links, the length in bytes of the pathname contained in the symbolic link. + For a shared memory object, the length in bytes. + For a typed memory object, the length in bytes. + For other file types, the use of this field is unspecified. */ + time_t st_atime; /*Time of last access. */ + time_t st_mtime; /*Time of last data modification. */ + time_t st_ctime; /*Time of last status change. */ + + blksize_t st_blksize; /*A file system-specific preferred I/O block size for this object. In some file system types, this may vary from file to file.*/ + blkcnt_t st_blocks; /*Number of blocks allocated for this object.*/ +}; + +/* Traditional mask definitions for st_mode. */ +#define S_IFMT 0170000 /* type of file */ +#define S_IFLNK 0120000 /* symbolic link */ +#define S_IFREG 0100000 /* regular */ +#define S_IFBLK 0060000 /* block special */ +#define S_IFDIR 0040000 /* directory */ +#define S_IFCHR 0020000 /* character special */ +#define S_IFIFO 0010000 /* this is a FIFO */ +#define S_ISUID 0004000 /* set user id on execution */ +#define S_ISGID 0002000 /* set group id on execution */ + /* next is reserved for future use */ +#define S_ISVTX 01000 /* save swapped text even after use */ + +/* POSIX masks for st_mode. */ +#define S_IRWXU 00700 /* owner: rwx------ */ +#define S_IRUSR 00400 /* owner: r-------- */ +#define S_IWUSR 00200 /* owner: -w------- */ +#define S_IXUSR 00100 /* owner: --x------ */ + +#define S_IRWXG 00070 /* group: ---rwx--- */ +#define S_IRGRP 00040 /* group: ---r----- */ +#define S_IWGRP 00020 /* group: ----w---- */ +#define S_IXGRP 00010 /* group: -----x--- */ + +#define S_IRWXO 00007 /* others: ------rwx */ +#define S_IROTH 00004 /* others: ------r-- */ +#define S_IWOTH 00002 /* others: -------w- */ +#define S_IXOTH 00001 /* others: --------x */ + +/* Synonyms for above. */ +#define S_IEXEC S_IXUSR +#define S_IWRITE S_IWUSR +#define S_IREAD S_IRUSR + +/* The following macros test st_mode (from POSIX Sec. 5.6.1.1). */ +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) /* is a reg file */ +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) /* is a directory */ +#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) /* is a char spec */ +#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) /* is a block spec */ +#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) /* is a symlink */ +#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) /* is a pipe/FIFO */ + +#endif Added: src/include/libc/sys/types.h =================================================================== --- src/include/libc/sys/types.h (rev 0) +++ src/include/libc/sys/types.h 2009-06-09 17:03:41 UTC (rev 366) @@ -0,0 +1,117 @@ +#ifndef _SYS_TYPES_H +#define _SYS_TYPES_H + +#if !defined(__time_t_defined) && !defined(_TIME_T) +#define _TIME_T +#define __time_t_defined +typedef _TIME_T_ time_t; +#endif + +#if !defined(__clock_t_defined) && !defined(_CLOCK_T) +#define _CLOCK_T +#define __clock_t_defined +typedef _CLOCK_T_ clock_t; +#endif + +#ifndef _SSIZE_T +#define _SSIZE_T +typedef _ssize_t ssize_t; +#endif + +#ifndef __u_char_defined +#ifdef __GNUC__ +__extension__ typedef long long quad_t; +__extension__ typedef unsigned long long u_quad_t; +#else +typedef struct +{ + long int __val[2]; +} quad_t; +typedef struct +{ + unsigned long __val[2]; +} u_quad_t; +#endif +typedef struct +{ + int __val[2]; +} fsid_t; +#define __u_char_defined +#endif + +typedef int clockid_t; + +# define _SYS_TYPES_FD_SET +# define NBBY 8 /* number of bits in a byte */ +/* + * Select uses bit masks of file descriptors in longs. + * These macros manipulate such bit fields (the filesystem macros use chars). + * FD_SETSIZE may be defined by the user, but the default here + * should be >= NOFILE (param.h). + */ +# ifndef FD_SETSIZE +# define FD_SETSIZE 64 +# endif + +typedef long fd_mask; +# define NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */ +# ifndef howmany +# define howmany(x,y) (((x)+((y)-1))/(y)) +# endif + +typedef struct { + unsigned long fds_bits [(1024/(8 * sizeof(unsigned long)))]; +} __fd_set; + +typedef __fd_set fd_set; + +# define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1L << ((n) % NFDBITS))) +# define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1L << ((n) % NFDBITS))) +# define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1L << ((n) % NFDBITS))) +# define FD_ZERO(p) (__extension__ (void)({ \ + size_t __i; \ + char *__tmp = (char *)p; \ + for (__i = 0; __i < sizeof (*(p)); ++__i) \ + *__tmp++ = 0; \ +})) + +#define __mode_t_defined +#define __gid_t_defined +#define __uid_t_defined +#define __pid_t_defined +#define __ssize_t_defined +#define __key_t_defined +#define __off_t_defined +#define __off64_t_defined + +typedef int dev_t; +typedef int ino_t; +typedef int mode_t; +typedef int caddr_t; +typedef long off_t; +typedef int pid_t; +typedef int uid_t; +typedef int gid_t; +typedef int key_t; +typedef int nlink_t; +typedef long suseconds_t; +typedef long useconds_t; + +typedef long blksize_t; +typedef long blkcnt_t; + +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int u_int; +typedef unsigned long u_long; +typedef unsigned char u_int8_t; +typedef unsigned short u_int16_t; +typedef unsigned long u_int32_t; +typedef unsigned long long u_int64_t; + +typedef u_int32_t __uint32_t; +typedef int32_t __int32_t; +typedef u_int16_t __uint16_t; +typedef int16_t __int16_t; + +#endif Added: src/include/libc/sys/utsname.h =================================================================== --- src/include/libc/sys/utsname.h (rev 0) +++ src/include/libc/sys/utsname.h 2009-06-09 17:03:41 UTC (rev 366) @@ -0,0 +1,23 @@ +#ifndef _SYS_UTSNAME_H +#define _SYS_UTSNAME_H + +#include <ace.h> + +#define UTS_MAX_NAME 50 + +#define UTS_SYSTEM_NAME "Ace" +#define UTS_NODE_NAME "Ace Node" +#define UTS_RELEASE "I" +#define UTS_VERSION "3" +#define UTS_MACHINE "ARCH" + + +struct utsname { + char sysname[UTS_MAX_NAME]; /*! name of this implementation of the operating system*/ + char nodename[UTS_MAX_NAME]; /*! name of this node within an implementation-dependent communications network*/ + char release[UTS_MAX_NAME]; /*! current release level of this implementation*/ + char version[UTS_MAX_NAME]; /*! current version level of this release*/ + char machine[UTS_MAX_NAME]; /*! name of the hardware type on which the system is running*/ +}; + +#endif Modified: src/kernel/i386/arch.c =================================================================== --- src/kernel/i386/arch.c 2009-05-22 05:21:12 UTC (rev 365) +++ src/kernel/i386/arch.c 2009-06-09 17:03:41 UTC (rev 366) @@ -121,7 +121,7 @@ /* Initialize real time clock*/ InitRtc(); - + /*setup double fault handler tss and gdt entries*/ FillTssForDoubleFaultHandler(DoubleFaultHandler); Modified: src/kernel/i386/pm/thread.c =================================================================== --- src/kernel/i386/pm/thread.c 2009-05-22 05:21:12 UTC (rev 365) +++ src/kernel/i386/pm/thread.c 2009-06-09 17:03:41 UTC (rev 366) @@ -56,7 +56,7 @@ { regs->cs = USER_CODE_SELECTOR | USER_PRIVILEGE_LEVEL; regs->ds = regs->es = regs->gs = regs->fs = regs->ss = USER_DATA_SELECTOR | USER_PRIVILEGE_LEVEL; - regs->useresp = user_stack; + regs->useresp = user_stack + USER_STACK_SIZE; /*stack grows from top to bottom*/ } regs->eip = (UINT32)start_address; Added: src/kernel/iom/devfs.c =================================================================== --- src/kernel/iom/devfs.c (rev 0) +++ src/kernel/iom/devfs.c 2009-06-09 17:03:41 UTC (rev 366) @@ -0,0 +1,309 @@ +/*! + \file kernel/iom/devfs.c + \brief Device File system interface - /device +*/ + +#include <ace.h> +#include <string.h> +#include <tar.h> +#include <ds/lrulist.h> +#include <ds/avl_tree.h> +#include <sync/spinlock.h> +#include <kernel/debug.h> +#include <kernel/ipc.h> +#include <kernel/iom/iom.h> +#include <kernel/iom/devfs.h> +#include <kernel/pm/pm_types.h> +#include <kernel/pm/thread.h> +#include <kernel/pm/scheduler.h> +#include <kernel/vfs/vfs.h> + +/*! User friendly name of the device fs*/ +#define DEV_FS_NAME "device fs" +/*! virtual device name*/ +#define DEV_FS_MOUNT_DEVICE "dev_device" +/*! Where to mount device fs*/ +#define DEV_FS_MOUNT_PATH "/device" + +#define DEV_FS_TIME_OUT 5 + +/*! messages passed to device fs is queued up here - It will be processed by device fs thread*/ +MESSAGE_QUEUE device_fs_message_queue; + +/*! root of devfs*/ +AVL_TREE_PTR devfs_root=NULL; + +/*! total device files*/ +static int devfs_total_directory_entries=0; + +/*! cache for devfs metadata*/ +CACHE devfs_cache; + +#define DEVFS_CACHE_FREE_SLABS_THRESHOLD 10 +#define DEVFS_CACHE_MIN_BUFFERS 20 +#define DEVFS_CACHE_MAX_SLABS 30 + +/*! used as argument to avl tree enumerate function of dev node tree*/ +typedef struct devfs_direntry_param +{ + FILE_STAT_PARAM_PTR file_stat; /*! starting address of file_stat param array*/ + int current_index; /*! current index into file_stat param array*/ + int max_entries; /*! max entries in the file_stat param*/ + + int result; /*! result of the enum operation*/ +}DEVFS_DIRENTRY_PARAM, * DEVFS_DIRENTRY_PARAM_PTR; + +static void DevFsMessageReceiver(); +static void ProcessVfsMessage( MESSAGE_TYPE message_type, VFS_IPC vfs_id, IPC_ARG_TYPE arg2, IPC_ARG_TYPE arg3, IPC_ARG_TYPE arg4, IPC_ARG_TYPE arg5, IPC_ARG_TYPE arg6 ); +static FILE_STAT_PARAM_PTR GetDirectoryEntries(void * fs_data, int inode, char * file_name, int max_entries, int * total_entries); +int enumerate_devfs_tree_callback(AVL_TREE_PTR node, void * arg); + +static COMPARISION_RESULT compare_dev_node_name(struct binary_tree * node1, struct binary_tree * node2); +int DevFsCacheConstructor( void *buffer); +int DevFsCacheDestructor( void *buffer); + +/*! Registers the device file system and mounts /device mount point +*/ +void InitDevFs() +{ + ERROR_CODE ret; + + /*initialize cache object of devfs*/ + if( InitCache(&devfs_cache, sizeof(DEVFS_METADATA), DEVFS_CACHE_FREE_SLABS_THRESHOLD, DEVFS_CACHE_MIN_BUFFERS, DEVFS_CACHE_MAX_SLABS, DevFsCacheConstructor, DevFsCacheDestructor) ) + panic("InitDevFs - cache init failed"); + + InitMessageQueue( &device_fs_message_queue ); + + /*Create a receiver thread*/ + CreateThread( &kernel_task, DevFsMessageReceiver, SCHED_CLASS_HIGH, TRUE ); + + /*register device file system*/ + ret = RegisterFileSystem( DEV_FS_NAME, &device_fs_message_queue ); + if ( ret != ERROR_SUCCESS ) + { + KPRINTF("%s\n", ERROR_CODE_AS_STRING(ret) ); + panic( "devfs registeration failed" ); + } + /*mount boot fs on a virtual device*/ + ret = MountFileSystem( DEV_FS_NAME, DEV_FS_MOUNT_DEVICE, DEV_FS_MOUNT_PATH ); + if ( ret != ERROR_SUCCESS ) + { + KPRINTF("%s\n", ERROR_CODE_AS_STRING(ret) ); + panic( "devfs mount failed" ); + } +} + +/*! DevFs thread + * Processes VFS requests from VFS server and fulfills the requests + */ +static void DevFsMessageReceiver() +{ + ERROR_CODE err; + MESSAGE_TYPE type; + IPC_ARG_TYPE arg1, arg2, arg3, arg4, arg5, arg6; + + while ( 1 ) + { + err = GetVfsMessage(&device_fs_message_queue, DEV_FS_TIME_OUT, &type, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6 ); + if ( err == ERROR_SUCCESS ) + ProcessVfsMessage( type, (VFS_IPC)arg1, arg2, arg3, arg4, arg5, arg6 ); + else + kprintf( "devfs IPC message receive error : %d\n", err ); + + /*!\todo - process unregister/shutdown request and exit this thread*/ + } + kprintf( "Exiting devfs\n" ); +} + +/*! Processes a VFS message and take neccessary action(reply to the VFS) + * \param message_type - message queue message type - value/reference/shared etc + * \param vfs_id - VFS message type - mount/unmount/read/write etc + * \param arg2-6 - Arguments to the message + * */ +static void ProcessVfsMessage( MESSAGE_TYPE message_type, VFS_IPC vfs_id, IPC_ARG_TYPE arg2, IPC_ARG_TYPE arg3, IPC_ARG_TYPE arg4, IPC_ARG_TYPE arg5, IPC_ARG_TYPE arg6 ) +{ + FILE_STAT_PARAM_PTR de; + int total_entries=0; + DIRECTORY_ENTRY_PARAM_PTR de_param; + + switch ( vfs_id ) + { + case VFS_IPC_MOUNT: + assert( message_type== MESSAGE_TYPE_REFERENCE ); + assert( IPR_ARGUMENT_ADDRESS != NULL ); + /*devfs supports mounting only one device*/ + if ( strcmp(IPR_ARGUMENT_ADDRESS, DEV_FS_MOUNT_DEVICE) == 0 ) + ReplyToLastMessage( MESSAGE_TYPE_VALUE, (IPC_ARG_TYPE)VFS_RETURN_CODE_SUCCESS, NULL, NULL, NULL, NULL, NULL ); + else + ReplyToLastMessage( MESSAGE_TYPE_VALUE, (IPC_ARG_TYPE)VFS_RETURN_CODE_INVALID_PARAMETER, NULL, NULL, NULL, NULL, NULL ); + break; + case VFS_IPC_UNMOUNT: + ReplyToLastMessage( MESSAGE_TYPE_VALUE, (IPC_ARG_TYPE)VFS_RETURN_CODE_OPERATION_NOT_SUPPORTED, NULL, NULL, NULL, NULL, NULL ); + break; + case VFS_IPC_GET_DIR_ENTRIES: + assert( message_type == MESSAGE_TYPE_REFERENCE ); + de_param = (DIRECTORY_ENTRY_PARAM_PTR )IPR_ARGUMENT_ADDRESS; + de = GetDirectoryEntries( arg2, -1, NULL, de_param->max_entries, &total_entries); + if( total_entries > 0 ) + ReplyToLastMessage( MESSAGE_TYPE_REFERENCE, (IPC_ARG_TYPE)VFS_RETURN_CODE_SUCCESS, (IPC_ARG_TYPE)total_entries, NULL, NULL, de, (IPC_ARG_TYPE) (sizeof(FILE_STAT_PARAM)*total_entries)); + else + ReplyToLastMessage( MESSAGE_TYPE_VALUE, (IPC_ARG_TYPE)VFS_RETURN_CODE_NOT_FOUND, NULL, NULL, NULL, NULL, NULL ); + break; + case VFS_IPC_GET_FILE_STAT_PATH: + assert( message_type == MESSAGE_TYPE_REFERENCE ); + de = GetDirectoryEntries( arg2, -1, IPR_ARGUMENT_ADDRESS, 1, NULL ); + if( de ) + ReplyToLastMessage( MESSAGE_TYPE_REFERENCE, (IPC_ARG_TYPE)VFS_RETURN_CODE_SUCCESS, (IPC_ARG_TYPE)1, NULL, NULL, de, (IPC_ARG_TYPE) sizeof(FILE_STAT_PARAM)); + else + ReplyToLastMessage( MESSAGE_TYPE_VALUE, (IPC_ARG_TYPE)VFS_RETURN_CODE_NOT_FOUND, NULL, NULL, NULL, NULL, NULL ); + break; + + case VFS_IPC_GET_FILE_STAT_INODE: + case VFS_IPC_READ_FILE: + case VFS_IPC_WRITE_FILE: + case VFS_IPC_MAP_FILE_PAGE: + case VFS_IPC_DELETE_FILE: + case VFS_IPC_MOVE: + case VFS_IPC_CREATE_SOFT_LINK: + case VFS_IPC_CREATE_HARD_LINK: + ReplyToLastMessage( MESSAGE_TYPE_VALUE, (IPC_ARG_TYPE)VFS_RETURN_CODE_INVALID_PARAMETER, NULL, NULL, NULL, NULL, NULL ); + break; + } +} + +/*! Creates a special device file under /device + * \param filename - file name to create under /device folder + * \param device - device object associated + * */ +ERROR_CODE CreateDeviceNode(const char * filename, DEVICE_OBJECT_PTR device) +{ + DEVFS_METADATA_PTR dp=NULL; + + assert(device != NULL); + + if( filename == NULL || strlen(filename) > DEVFS_FILE_NAME_MAX-1 ) + return ERROR_INVALID_PARAMETER; + + dp = AllocateBuffer(&devfs_cache, 0); + if ( dp == NULL ) + return ERROR_NOT_ENOUGH_MEMORY; + + strcpy( dp->name, filename ); + if ( InsertNodeIntoAvlTree(&devfs_root, &dp->tree, 0, compare_dev_node_name ) != 0 ) + return ERROR_INVALID_PARAMETER; + + dp->device = device; + + devfs_total_directory_entries++; + + return ERROR_SUCCESS; +} + +/*! Returns the directory entries for a given directory + \param fs_data - fs provided data for the directory during open file if any + \param inode - inode of the file else -1 + \param file_name - name of the file else NULL + \param max_entries - maximum entries required + \param total_entries - output - total entries in the array + \return Array of directory entries +*/ +static FILE_STAT_PARAM_PTR GetDirectoryEntries(void * fs_data, int inode, char * file_name, int max_entries, int * total_entries) +{ + int total_directory_entries = devfs_total_directory_entries; + FILE_STAT_PARAM_PTR result=NULL; + DEVFS_DIRENTRY_PARAM param={0}; + + if ( total_entries ) + * total_entries = 0; + if ( max_entries < total_directory_entries) + total_directory_entries = max_entries; + result = kmalloc( sizeof(FILE_STAT_PARAM)*total_directory_entries, 0 ); + if ( result == NULL ) + return NULL; + + param.file_stat = result; + param.max_entries = max_entries; + EnumerateAvlTree(devfs_root, enumerate_devfs_tree_callback, ¶m); + + /*if no entry is reterived free the memory and return null*/ + if( param.current_index == 0 ) + { + kfree( result ); + return NULL; + } + + if ( total_entries ) + * total_entries = param.current_index; + + return result; +} + +/*! Searches the vm descriptor AVL tree for a particular VA range*/ +static COMPARISION_RESULT compare_dev_node_name(struct binary_tree * node1, struct binary_tree * node2) +{ + DEVFS_METADATA_PTR d1, d2; + int result; + assert( node1 != NULL ); + assert( node2 != NULL ); + + d1 = STRUCT_ADDRESS_FROM_MEMBER(node1, DEVFS_METADATA, tree.bintree); + d2 = STRUCT_ADDRESS_FROM_MEMBER(node2, DEVFS_METADATA, tree.bintree); + + result = strcmp( d1->name, d2->name ); + if( result == 0 ) + return EQUAL; + else if ( result > 0 ) + return GREATER_THAN; + else + return LESS_THAN; +} + +/*! Enumerates devfs tree and fills the FILE_STAT_PARAM for each node*/ +int enumerate_devfs_tree_callback(AVL_TREE_PTR node, void * arg) +{ + DEVFS_METADATA_PTR dm; + DEVFS_DIRENTRY_PARAM_PTR param; + FILE_STAT_PARAM_PTR fstat_param; + + dm = STRUCT_ADDRESS_FROM_MEMBER(node, DEVFS_METADATA, tree); + param = (DEVFS_DIRENTRY_PARAM_PTR)arg; + + assert( param->current_index < param->max_entries ); + + fstat_param = ¶m->file_stat[ param->current_index ]; + param->current_index++; + + /*fill the entry*/ + strcpy( fstat_param->name, dm->name ); + fstat_param->inode = 0; + fstat_param->file_size = 0; + fstat_param->mode = 0; + fstat_param->fs_data = dm->device; + + /*if no more free slot available break enumeration*/ + if ( param->current_index == param->max_entries ) + return 1; + + /*continue enumeration*/ + return 0; +} + + +/*! Internal function used to initialize the devfs metadata structure*/ +int DevFsCacheConstructor( void *buffer) +{ + DEVFS_METADATA_PTR dp = (DEVFS_METADATA_PTR) buffer; + + dp->name[0]=0; + InitAvlTreeNode( &dp->tree, 0 ); + + return 0; +} + +/*! Internal function used to clear the devfs metadata structure*/ +int DevFsCacheDestructor( void *buffer) +{ + DevFsCacheConstructor( buffer ); + return 0; +} + Added: src/kernel/iom/driver.c =================================================================== --- src/kernel/iom/driver.c (rev 0) +++ src/kernel/iom/driver.c 2009-06-09 17:03:41 UTC (rev 366) @@ -0,0 +1,168 @@ +/*! + \file kernel/iom/driver.c + \brief driver loand and unloading routines. +*/ +#include <ace.h> +#include <string.h> +#include <ctype.h> +#include <kernel/debug.h> +#include <kernel/mm/kmem.h> +#include <kernel/pm/elf.h> +#include <kernel/iom/iom.h> +#include <kernel/vfs/vfs.h> + +extern LIST_PTR driver_list_head; + +ERROR_CODE FindDriverFile(char * device_id, char * buffer, int buf_length); + +/*! Loads a driver*/ +DRIVER_OBJECT_PTR LoadDriver(char * device_id) +{ + char driver_file_name[MAX_FILE_NAME], driver_file_path[MAX_FILE_PATH]="/boot/drivers/"; + VADDR driver_start_address; + int file_id; + long file_size; + DRIVER_OBJECT_PTR driver_object; + ERROR_CODE (*DriverEntry)(DRIVER_OBJECT_PTR pDriverObject); + ERROR_CODE err; + LIST_PTR node; + + err = FindDriverFile(device_id, driver_file_name, sizeof(driver_file_name)); + ktrace("Driver for id %s : ", device_id); + if ( err == ERROR_SUCCESS ) + ktrace("%s\n", driver_file_name); + else + { + ktrace("%s\n", ERROR_CODE_AS_STRING(err) ); + return NULL; + } + + /*check whether the driver is already loaded*/ + LIST_FOR_EACH(node, driver_list_head) + { + driver_object = STRUCT_ADDRESS_FROM_MEMBER( node, DRIVER_OBJECT, driver_list ); + if ( strcmp( driver_file_name, driver_object->driver_file_name )==0 ) + { + ktrace("Driver already loaded %s\n", driver_object->driver_file_name); + return driver_object; + } + + } + strcat( driver_file_path, driver_file_name ); + kprintf("Loading %s: ", driver_file_path); + + err = OpenFile(driver_file_path, VFS_ACCESS_TYPE_READ, OPEN_EXISTING, &file_id); + if ( err != ERROR_SUCCESS ) + goto error; + err = GetFileSize(file_id, &file_size); + if ( err != ERROR_SUCCESS ) + goto error; + file_size = PAGE_ALIGN_UP(file_size); + err = MapViewOfFile(file_id, &driver_start_address, PROT_READ, 0, file_size, 0, 0); + if ( err != ERROR_SUCCESS ) + goto error; + err = LoadElfImage( (void *) driver_start_address, &kernel_map, "DriverEntry", (void *)&DriverEntry ); + if ( err != ERROR_SUCCESS || DriverEntry == NULL ) + goto error; + driver_object = AllocateBuffer( &driver_object_cache, CACHE_ALLOC_SLEEP ); + if ( driver_object == NULL ) + { + err = ERROR_NOT_ENOUGH_MEMORY; + goto error; + } + + strcpy( driver_object->driver_file_name, driver_file_name); + err = DriverEntry( driver_object ); + if ( err != ERROR_SUCCESS ) + goto error; + + /*add the driver to the driver list*/ + AddToList( driver_list_head, &driver_object->driver_list ); + kprintf("success\n"); + return driver_object; + +error: + kprintf("%s\n", ERROR_CODE_AS_STRING(err) ); + return NULL; + +} + +#define SKIP_WHITE_SPACES while( i<file_size && isspace(va[i]) ) i++; + + +/*! Finds suitable driver for the given id and returns its full path in the given buffer + \param device_id - device identification string + \param buffer - buffer to place the driver path + \param buf_length - buffer size +*/ +ERROR_CODE FindDriverFile(char * device_id, char * buffer, int buf_length) +{ + ERROR_CODE err; + int file_id,i=0; + long file_size; + char driver_id_database[] = "/boot/driver_id.txt"; + char * va; + + assert(device_id != NULL ); + assert(buffer != NULL ); + assert(buf_length > 0); + + buffer[0]=0; + + err = OpenFile(driver_id_database, VFS_ACCESS_TYPE_READ, OPEN_EXISTING, &file_id); + if ( err != ERROR_SUCCESS ) + goto done; + + err = GetFileSize(file_id, &file_size); + if ( err != ERROR_SUCCESS ) + goto done; + + err = MapViewOfFile(file_id, (VADDR *) &va, PROT_READ, 0, file_size, 0, 0); + if ( err != ERROR_SUCCESS ) + goto done; + + err=ERROR_NOT_FOUND; + /*read the file and try to find the driver file name*/ + while(i<file_size) + { + char driver_device_id[100]; + SKIP_WHITE_SPACES; + + /*if the line not starting with comment character process it*/ + if( va[i]!='#' ) + { + int j=0; + + /*copy the driver id*/ + while( i<file_size && j<sizeof(driver_device_id)-1 && !isspace(va[i]) ) + driver_device_id[j++] = va[i++]; + driver_device_id[j]=0; + + /*if user didnt provide driver file name break*/ + if ( va[i] != ' ' && va[i] != '\t' ) + break; + + SKIP_WHITE_SPACES; + + if( strcmp(driver_device_id, device_id) == 0 ) + { + /*copy driver file name*/ + j=0; + while( i<file_size && j<buf_length-1 && !isspace(va[i]) ) + buffer[j++] = va[i++]; + + buffer[j]=0; + err = ERROR_SUCCESS; + break; + } + } + /*skip till end of line*/ + while( i<file_size && va[i]!='\n') i++; + } + +done: + /* \todo - release the mapping */ + + CloseFile(file_id); + return err; +} Modified: src/kernel/iom/iom.c =================================================================== --- src/kernel/iom/iom.c 2009-05-22 05:21:12 UTC (rev 365) +++ src/kernel/iom/iom.c 2009-06-09 17:03:41 UTC (rev 366) @@ -10,6 +10,7 @@ #include <kernel/pm/elf.h> #include <kernel/iom/iom.h> #include <kernel/vfs/vfs.h> +#include <kernel/iom/devfs.h> #define DEVICE_OBJECT_CACHE_FREE_SLABS_THRESHOLD 10 #define DEVICE_OBJECT_CACHE_MIN_BUFFERS 10 @@ -23,8 +24,6 @@ #define IRP_CACHE_MIN_BUFFERS 50 #define IRP_CACHE_MAX_SLABS 50 -static ERROR_CODE DummyMajorFunction(DEVICE_OBJECT_PTR pDeviceObject, IRP_PTR pIrp); - /*! List of drivers loaded into the kernel address space */ LIST_PTR driver_list_head = NULL; @@ -34,74 +33,25 @@ /*! cache for irps*/ CACHE irp_cache; -static DRIVER_OBJECT_PTR LoadDriver(char * device_id); -static ERROR_CODE FindDriverFile(char * device_id, char * buffer, int buf_length); +extern DRIVER_OBJECT_PTR LoadDriver(char * device_id); +extern ERROR_CODE FindDriverFile(char * device_id, char * buffer, int buf_length); +static ERROR_CODE DummyMajorFunction(DEVICE_OBJECT_PTR pDeviceObject, IRP_PTR pIrp); +int DriverObjectCacheConstructor( void * buffer); +int DriverObjectCacheDestructor( void *buffer); +int DeviceObjectCacheConstructor( void *buffer); +int DeviceObjectCacheDestructor( void *buffer); +int IrpCacheConstructor( void * buffer); +int IrpCacheDestructor( void * buffer); -/*! Internal function used to initialize the driver object structure*/ -int DriverObjectCacheConstructor( void * buffer) -{ - int i; - DRIVER_OBJECT_PTR dop = (DRIVER_OBJECT_PTR) buffer; - - memset(dop, 0, sizeof(DRIVER_OBJECT) ); +extern void InitDevFs(); - InitList( &dop->driver_list ); - InitSpinLock( &dop->lock ); - for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++) - dop->fn.MajorFunctions[i] = DummyMajorFunction; - - return 0; -} -/*! Internal function used to clear the driver object structure*/ -int DriverObjectCacheDestructor( void *buffer) -{ - DriverObjectCacheConstructor( buffer ); - return 0; -} -/*! Internal function used to initialize the device object structure*/ -int DeviceObjectCacheConstructor( void *buffer) -{ - DEVICE_OBJECT_PTR dop = (DEVICE_OBJECT_PTR) buffer; - - memset(buffer, 0, sizeof(DEVICE_OBJECT) ); - - InitSpinLock( &dop->lock ); - InitList( &dop->sibilings_list ); - InitList( &dop->device_object_list ); - - dop->stack_count = 1; - - return 0; -} -/*! Internal function used to clear the device object structure*/ -int DeviceObjectCacheDestructor( void *buffer) -{ - DeviceObjectCacheConstructor( buffer ); - return 0; -} - -/*! Internal function used to initialize the IRP structure*/ -int IrpCacheConstructor( void * buffer) -{ - memset(buffer, 0, sizeof(IRP) ); - - return 0; -} - -/*! Internal function used to initialize the IRP structure*/ -int IrpCacheDestructor( void * buffer) -{ - IrpCacheConstructor(buffer); - - return 0; -} - /*! Initialize IO manager and start required boot drivers*/ void InitIoManager() { DRIVER_OBJECT_PTR root_bus; + /*initialize cache objects for io manager*/ if( InitCache(&driver_object_cache, sizeof(DRIVER_OBJECT), DRIVER_OBJECT_CACHE_FREE_SLABS_THRESHOLD, DRIVER_OBJECT_CACHE_MIN_BUFFERS, DRIVER_OBJECT_CACHE_MAX_SLABS, DriverObjectCacheConstructor, DriverObjectCacheDestructor) ) panic("InitIoManager - Driver object cache init failed"); @@ -110,6 +60,9 @@ if( InitCache(&irp_cache, sizeof(IRP), IRP_CACHE_FREE_SLABS_THRESHOLD, IRP_CACHE_MIN_BUFFERS, IRP_CACHE_MAX_SLABS, IrpCacheConstructor, IrpCacheDestructor) ) panic("InitIoManager - IRP cache init failed"); + + /*initialize dev fs*/ + InitDevFs(); /*load root bus driver and call the DriverEntry*/ root_bus = LoadRootBusDriver() ; @@ -120,7 +73,7 @@ RootBusDriverEntry( root_bus ); /*create device object for root bus*/ - CreateDevice(root_bus_driver_object, 0, &root_bus_device_object); + CreateDevice(root_bus_driver_object, 0, &root_bus_device_object, NULL); /*force the io manager to enumerate the buses on root bus*/ InvalidateDeviceRelations(root_bus_device_object, DEVICE_RELATIONS_TYPE_BUS_RELATION); @@ -139,30 +92,13 @@ return ERROR_NOT_SUPPORTED; } -/*! Returns the current IO Stack location associated with the given IRP - \param irp - interrupt request packet - \return Current IO stack location on the given irp -*/ -IO_STACK_LOCATION_PTR GetCurrentIrpStackLocation(IRP_PTR Irp) -{ - return Irp->current_stack_location; -} - -/*! Returns the next lower level IO Stack location associated with the given IRP - \param irp - interrupt request packet - \return Next IO stack loation on the given irp. -*/ -IO_STACK_LOCATION_PTR GetNextIrpStackLocation(IRP_PTR Irp) -{ - assert( Irp->current_stack >0 && Irp->current_stack < Irp->stack_count ); - return Irp->current_stack_location-1; -} /*! Creates a device object for use by the driver \param driver_object - caller's driver object - this is used by io manager to link the created device with the driver \param device_extension_size - size of the device_externsion - io manager allocates this much byte in the device_object \param device_object - pointer to device object - io manager updates this pointer with the newly created device object + \param device_name - optional - device file name - it will be placed under /device/xxxx - applications use this file to communicate with the driver */ -ERROR_CODE CreateDevice(DRIVER_OBJECT_PTR driver_object, UINT32 device_extension_size, DEVICE_OBJECT_PTR * device_object) +ERROR_CODE CreateDevice(DRIVER_OBJECT_PTR driver_object, UINT32 device_extension_size, DEVICE_OBJECT_PTR * device_object, char * device_name) { DEVICE_OBJECT_PTR dob; assert( device_object != NULL ); @@ -179,6 +115,14 @@ driver_object->device_object_head = dob; else AddToListTail( &driver_object->device_object_head->device_object_list, &dob->device_object_list ); + + /*create a device file if name is provided*/ + if ( device_name ) + { + ERROR_CODE ret; + ret = CreateDeviceNode(device_name, dob); + /*\todo - do we need to care about CreateDeviceNode return status?*/ + } *device_object = dob; return ERROR_SUCCESS; @@ -264,59 +208,6 @@ FreeIrp(irp); } -/*! Allocates a Irp for the use of driver - \param stack_size - number of stacks assoicated with this irp - \return irp -*/ -IRP_PTR AllocateIrp(BYTE stack_size) -{ - IRP_PTR irp; - - assert( stack_size>0 ); - /*! allocate irp and io stack*/ - irp = AllocateBuffer( &irp_cache, CACHE_ALLOC_SLEEP ); - if ( irp == NULL ) - return NULL; - irp->current_stack_location = kmalloc( sizeof(IO_STACK_LOCATION)*stack_size, KMEM_NO_FAIL ); - - irp->stack_count = stack_size; - irp->io_status.status = ERROR_NOT_SUPPORTED; - - return irp; -} - -/*! Frees a irp - \param irp - pointer to irp to be freed -*/ -void FreeIrp(IRP_PTR irp) -{ - assert( irp != NULL ); - - kfree( irp->current_stack_location ); - FreeBuffer( irp, &irp_cache ); -} - -/*! Reuses a already allocated Irp - \param irp - pointer to irp - \param error_code - Io status will be set with this error code -*/ -void ReuseIrp(IRP_PTR irp, ERROR_CODE error_code) -{ - BYTE stack_size; - IO_STACK_LOCATION_PTR io_stack; - - assert( irp != NULL ); - - stack_size = irp->stack_count; - io_stack = irp->current_stack_location; - - IrpCacheConstructor( irp ); - - irp->current_stack_location = io_stack; - irp->stack_count = stack_size; - irp->io_status.status = error_code; -} - /*! Dispatches a call to driver based on the given Irp \param device_object - device object \param irp - irp @@ -330,165 +221,63 @@ return ERROR_SUCCESS; } -/*Helper routine to fill a Io Stack with given information*/ -inline void FillIoStack(IO_STACK_LOCATION_PTR io_stack, BYTE major_function, BYTE minor_function, DEVICE_OBJECT_PTR device_object, IO_COMPLETION_ROUTINE completion_routine, void * context) -{ - assert( io_stack ); - io_stack->major_function = major_function; - io_stack->minor_function = minor_function; - io_stack->device_object = device_object; - io_stack->completion_routine = completion_routine; - io_stack->context = context; -} -/*! Loads a driver*/ -static DRIVER_OBJECT_PTR LoadDriver(char * device_id) +/*! Internal function used to initialize the driver object structure*/ +int DriverObjectCacheConstructor( void * buffer) { - char driver_file_name[MAX_FILE_NAME], driver_file_path[MAX_FILE_PATH]="/boot/drivers/"; - VADDR driver_start_address; - int file_id; - long file_size; - DRIVER_OBJECT_PTR driver_object; - ERROR_CODE (*DriverEntry)(DRIVER_OBJECT_PTR pDriverObject); - ERROR_CODE err; - LIST_PTR node; + int i; + DRIVER_OBJECT_PTR dop = (DRIVER_OBJECT_PTR) buffer; - err = FindDriverFile(device_id, driver_file_name, sizeof(driver_file_name)); - ktrace("Driver for id %s : ", device_id); - if ( err == ERROR_SUCCESS ) - ktrace("%s\n", driver_file_name); - else - { - ktrace("%s\n", ERROR_CODE_AS_STRING(err) ); - return NULL; - } + memset(dop, 0, sizeof(DRIVER_OBJECT) ); - /*check whether the driver is already loaded*/ - LIST_FOR_EACH(node, driver_list_head) - { - driver_object = STRUCT_ADDRESS_FROM_MEMBER( node, DRIVER_OBJECT, driver_list ); - if ( strcmp( driver_file_name, driver_object->driver_file_name )==0 ) - { - ktrace("Driver already loaded %s\n", driver_object->driver_file_name); - return driver_object; - } - - } - strcat( driver_file_path, driver_file_name ); - kprintf("Loading %s: ", driver_file_path); + InitList( &dop->driver_list ); + InitSpinLock( &dop->lock ); + for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++) + dop->fn.MajorFunctions[i] = DummyMajorFunction; - err = OpenFile(driver_file_path, VFS_ACCESS_TYPE_READ, OPEN_EXISTING, &file_id); - if ( err != ERROR_SUCCESS ) - goto error; - err = GetFileSize(file_id, &file_size); - if ( err != ERROR_SUCCESS ) - goto error; - file_size = PAGE_ALIGN_UP(file_size); - err = MapViewOfFile(file_id, &driver_start_address, PROT_READ, 0, file_size, 0, 0); - if ( err != ERROR_SUCCESS ) - goto error; - err = LoadElfImage( (void *) driver_start_address, &kernel_map, "DriverEntry", (void *)&DriverEntry ); - if ( err != ERROR_SUCCESS || DriverEntry == NULL ) - goto error; - driver_object = AllocateBuffer( &driver_object_cache, CACHE_ALLOC_SLEEP ); - if ( driver_object == NULL ) - { - err = ERROR_NOT_ENOUGH_MEMORY; - goto error; - } + return 0; +} +/*! Internal function used to clear the driver object structure*/ +int DriverObjectCacheDestructor( void *buffer) +{ + DriverObjectCacheConstructor( buffer ); + return 0; +} +/*! Internal function used to initialize the device object structure*/ +int DeviceObjectCacheConstructor( void *buffer) +{ + DEVICE_OBJECT_PTR dop = (DEVICE_OBJECT_PTR) buffer; - strcpy( driver_object->driver_file_name, driver_... [truncated message content] |
From: <sam...@us...> - 2009-05-22 05:21:20
|
Revision: 365 http://aceos.svn.sourceforge.net/aceos/?rev=365&view=rev Author: samueldotj Date: 2009-05-22 05:21:12 +0000 (Fri, 22 May 2009) Log Message: ----------- Copied kconfig from Linux Added Paths: ----------- scripts/kconfig/ scripts/kconfig/confdata.c scripts/kconfig/expr.c scripts/kconfig/expr.h scripts/kconfig/lex.zconf.c scripts/kconfig/lkc.h scripts/kconfig/lkc_proto.h scripts/kconfig/lxdialog/ scripts/kconfig/lxdialog/Makefile scripts/kconfig/lxdialog/checklist.c scripts/kconfig/lxdialog/colors.h scripts/kconfig/lxdialog/dialog.h scripts/kconfig/lxdialog/inputbox.c scripts/kconfig/lxdialog/lxdialog.c scripts/kconfig/lxdialog/menubox.c scripts/kconfig/lxdialog/msgbox.c scripts/kconfig/lxdialog/textbox.c scripts/kconfig/lxdialog/util.c scripts/kconfig/lxdialog/yesno.c scripts/kconfig/mconf.c scripts/kconfig/menu.c scripts/kconfig/symbol.c scripts/kconfig/wscript scripts/kconfig/zconf.tab.c scripts/kconfig/zconf.tab.h src/kernel/Kconfig Added: scripts/kconfig/confdata.c =================================================================== --- scripts/kconfig/confdata.c (rev 0) +++ scripts/kconfig/confdata.c 2009-05-22 05:21:12 UTC (rev 365) @@ -0,0 +1,432 @@ +/* + * Copyright (C) 2002 Roman Zippel <zi...@li...> + * Released under the terms of the GNU GPL v2.0. + */ + +#include <sys/stat.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <limits.h> + +#define LKC_DIRECT_LINK +#include "lkc.h" + +const char conf_def_filename[] = ".config"; + +const char conf_defname[] = "arch/$ARCH/defconfig"; + +const char *conf_confnames[] = { + ".config", + "/lib/modules/$UNAME_RELEASE/.config", + "/etc/kernel-config", + "/boot/config-$UNAME_RELEASE", + conf_defname, + NULL, +}; + +static char *conf_expand_value(const char *in) +{ + struct symbol *sym; + const char *src; + static char res_value[SYMBOL_MAXLENGTH]; + char *dst, name[SYMBOL_MAXLENGTH]; + + res_value[0] = 0; + dst = name; + while ((src = strchr(in, '$'))) { + strncat(res_value, in, src - in); + src++; + dst = name; + while (isalnum(*src) || *src == '_') + *dst++ = *src++; + *dst = 0; + sym = sym_lookup(name, 0); + sym_calc_value(sym); + strcat(res_value, sym_get_string_value(sym)); + in = src; + } + strcat(res_value, in); + + return res_value; +} + +char *conf_get_default_confname(void) +{ + struct stat buf; + static char fullname[PATH_MAX+1]; + char *env, *name; + + name = conf_expand_value(conf_defname); + env = getenv(SRCTREE); + if (env) { + sprintf(fullname, "%s/%s", env, name); + if (!stat(fullname, &buf)) + return fullname; + } + return name; +} + +int conf_read(const char *name) +{ + FILE *in = NULL; + char line[1024]; + char *p, *p2; + int lineno = 0; + struct symbol *sym; + struct property *prop; + struct expr *e; + int i; + + if (name) { + in = zconf_fopen(name); + } else { + const char **names = conf_confnames; + while ((name = *names++)) { + name = conf_expand_value(name); + in = zconf_fopen(name); + if (in) { + printf("#\n" + "# using defaults found in %s\n" + "#\n", name); + break; + } + } + } + + if (!in) + return 1; + + for_all_symbols(i, sym) { + sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED; + sym->flags &= ~SYMBOL_VALID; + switch (sym->type) { + case S_INT: + case S_HEX: + case S_STRING: + if (sym->user.val) + free(sym->user.val); + default: + sym->user.val = NULL; + sym->user.tri = no; + } + } + + while (fgets(line, sizeof(line), in)) { + lineno++; + sym = NULL; + switch (line[0]) { + case '#': + if (memcmp(line + 2, "CONFIG_", 7)) + continue; + p = strchr(line + 9, ' '); + if (!p) + continue; + *p++ = 0; + if (strncmp(p, "is not set", 10)) + continue; + sym = sym_find(line + 9); + if (!sym) { + fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 9); + break; + } + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + sym->user.tri = no; + sym->flags &= ~SYMBOL_NEW; + break; + default: + ; + } + break; + case 'C': + if (memcmp(line, "CONFIG_", 7)) + continue; + p = strchr(line + 7, '='); + if (!p) + continue; + *p++ = 0; + p2 = strchr(p, '\n'); + if (p2) + *p2 = 0; + sym = sym_find(line + 7); + if (!sym) { + fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 7); + break; + } + switch (sym->type) { + case S_TRISTATE: + if (p[0] == 'm') { + sym->user.tri = mod; + sym->flags &= ~SYMBOL_NEW; + break; + } + case S_BOOLEAN: + if (p[0] == 'y') { + sym->user.tri = yes; + sym->flags &= ~SYMBOL_NEW; + break; + } + if (p[0] == 'n') { + sym->user.tri = no; + sym->flags &= ~SYMBOL_NEW; + break; + } + break; + case S_STRING: + if (*p++ != '"') + break; + for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) { + if (*p2 == '"') { + *p2 = 0; + break; + } + memmove(p2, p2 + 1, strlen(p2)); + } + if (!p2) { + fprintf(stderr, "%s:%d: invalid string found\n", name, lineno); + exit(1); + } + case S_INT: + case S_HEX: + if (sym_string_valid(sym, p)) { + sym->user.val = strdup(p); + sym->flags &= ~SYMBOL_NEW; + } else { + fprintf(stderr, "%s:%d: symbol value '%s' invalid for %s\n", name, lineno, p, sym->name); + exit(1); + } + break; + default: + ; + } + break; + case '\n': + break; + default: + continue; + } + if (sym && sym_is_choice_value(sym)) { + struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); + switch (sym->user.tri) { + case no: + break; + case mod: + if (cs->user.tri == yes) + /* warn? */; + break; + case yes: + if (cs->user.tri != no) + /* warn? */; + cs->user.val = sym; + break; + } + cs->user.tri = E_OR(cs->user.tri, sym->user.tri); + cs->flags &= ~SYMBOL_NEW; + } + } + fclose(in); + + for_all_symbols(i, sym) { + sym_calc_value(sym); + if (sym_has_value(sym) && !sym_is_choice_value(sym)) { + if (sym->visible == no) + sym->flags |= SYMBOL_NEW; + switch (sym->type) { + case S_STRING: + case S_INT: + case S_HEX: + if (!sym_string_within_range(sym, sym->user.val)) + sym->flags |= SYMBOL_NEW; + default: + break; + } + } + if (!sym_is_choice(sym)) + continue; + prop = sym_get_choice_prop(sym); + for (e = prop->expr; e; e = e->left.expr) + if (e->right.sym->visible != no) + sym->flags |= e->right.sym->flags & SYMBOL_NEW; + } + + sym_change_count = 1; + + return 0; +} + +int conf_write(const char *name) +{ + FILE *out, *out_h; + struct symbol *sym; + struct menu *menu; + const char *basename; + char dirname[128], tmpname[128], newname[128]; + int type, l; + const char *str; + + dirname[0] = 0; + if (name && name[0]) { + char *slash = strrchr(name, '/'); + if (slash) { + int size = slash - name + 1; + memcpy(dirname, name, size); + dirname[size] = 0; + if (slash[1]) + basename = slash + 1; + else + basename = conf_def_filename; + } else + basename = name; + } else + basename = conf_def_filename; + + sprintf(newname, "%s.tmpconfig.%d", dirname, getpid()); + out = fopen(newname, "w"); + if (!out) + return 1; + out_h = NULL; + if (!name) { + out_h = fopen(".tmpconfig.h", "w"); + if (!out_h) + return 1; + } + fprintf(out, "#\n" + "# Automatically generated make config: don't edit\n" + "#\n"); + if (out_h) + fprintf(out_h, "/*\n" + " * Automatically generated C config: don't edit\n" + " */\n" + "#define AUTOCONF_INCLUDED\n"); + + if (!sym_change_count) + sym_clear_all_valid(); + + menu = rootmenu.list; + while (menu) { + sym = menu->sym; + if (!sym) { + if (!menu_is_visible(menu)) + goto next; + str = menu_get_prompt(menu); + fprintf(out, "\n" + "#\n" + "# %s\n" + "#\n", str); + if (out_h) + fprintf(out_h, "\n" + "/*\n" + " * %s\n" + " */\n", str); + } else if (!(sym->flags & SYMBOL_CHOICE)) { + sym_calc_value(sym); + if (!(sym->flags & SYMBOL_WRITE)) + goto next; + sym->flags &= ~SYMBOL_WRITE; + type = sym->type; + if (type == S_TRISTATE) { + sym_calc_value(modules_sym); + if (modules_sym->curr.tri == no) + type = S_BOOLEAN; + } + switch (type) { + case S_BOOLEAN: + case S_TRISTATE: + switch (sym_get_tristate_value(sym)) { + case no: + fprintf(out, "# CONFIG_%s is not set\n", sym->name); + if (out_h) + fprintf(out_h, "#undef CONFIG_%s\n", sym->name); + break; + case mod: + fprintf(out, "CONFIG_%s=m\n", sym->name); + if (out_h) + fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); + break; + case yes: + fprintf(out, "CONFIG_%s=y\n", sym->name); + if (out_h) + fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); + break; + } + break; + case S_STRING: + // fix me + str = sym_get_string_value(sym); + fprintf(out, "CONFIG_%s=\"", sym->name); + if (out_h) + fprintf(out_h, "#define CONFIG_%s \"", sym->name); + do { + l = strcspn(str, "\"\\"); + if (l) { + fwrite(str, l, 1, out); + if (out_h) + fwrite(str, l, 1, out_h); + } + str += l; + while (*str == '\\' || *str == '"') { + fprintf(out, "\\%c", *str); + if (out_h) + fprintf(out_h, "\\%c", *str); + str++; + } + } while (*str); + fputs("\"\n", out); + if (out_h) + fputs("\"\n", out_h); + break; + case S_HEX: + str = sym_get_string_value(sym); + if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { + fprintf(out, "CONFIG_%s=%s\n", sym->name, str); + if (out_h) + fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); + break; + } + case S_INT: + str = sym_get_string_value(sym); + fprintf(out, "CONFIG_%s=%s\n", sym->name, str); + if (out_h) + fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); + break; + } + } + + next: + if (menu->list) { + menu = menu->list; + continue; + } + if (menu->next) + menu = menu->next; + else while ((menu = menu->parent)) { + if (menu->next) { + menu = menu->next; + break; + } + } + } + fclose(out); + if (out_h) { + fclose(out_h); + rename(".tmpconfig.h", "config.h"); + file_write_dep(NULL); + } + if (!name || basename != conf_def_filename) { + if (!name) + name = conf_def_filename; + sprintf(tmpname, "%s.old", name); + rename(name, tmpname); + } + sprintf(tmpname, "%s%s", dirname, basename); + if (rename(newname, tmpname)) + return 1; + + sym_change_count = 0; + + return 0; +} Added: scripts/kconfig/expr.c =================================================================== --- scripts/kconfig/expr.c (rev 0) +++ scripts/kconfig/expr.c 2009-05-22 05:21:12 UTC (rev 365) @@ -0,0 +1,1083 @@ +/* + * Copyright (C) 2002 Roman Zippel <zi...@li...> + * Released under the terms of the GNU GPL v2.0. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define LKC_DIRECT_LINK +#include "lkc.h" + +struct expr *expr_alloc_symbol(struct symbol *sym) +{ + struct expr *e = malloc(sizeof(*e)); + memset(e, 0, sizeof(*e)); + e->type = E_SYMBOL; + e->left.sym = sym; + return e; +} + +struct expr *expr_alloc_one(enum expr_type type, struct expr *ce) +{ + struct expr *e = malloc(sizeof(*e)); + memset(e, 0, sizeof(*e)); + e->type = type; + e->left.expr = ce; + return e; +} + +struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2) +{ + struct expr *e = malloc(sizeof(*e)); + memset(e, 0, sizeof(*e)); + e->type = type; + e->left.expr = e1; + e->right.expr = e2; + return e; +} + +struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2) +{ + struct expr *e = malloc(sizeof(*e)); + memset(e, 0, sizeof(*e)); + e->type = type; + e->left.sym = s1; + e->right.sym = s2; + return e; +} + +struct expr *expr_alloc_and(struct expr *e1, struct expr *e2) +{ + if (!e1) + return e2; + return e2 ? expr_alloc_two(E_AND, e1, e2) : e1; +} + +struct expr *expr_alloc_or(struct expr *e1, struct expr *e2) +{ + if (!e1) + return e2; + return e2 ? expr_alloc_two(E_OR, e1, e2) : e1; +} + +struct expr *expr_copy(struct expr *org) +{ + struct expr *e; + + if (!org) + return NULL; + + e = malloc(sizeof(*org)); + memcpy(e, org, sizeof(*org)); + switch (org->type) { + case E_SYMBOL: + e->left = org->left; + break; + case E_NOT: + e->left.expr = expr_copy(org->left.expr); + break; + case E_EQUAL: + case E_UNEQUAL: + e->left.sym = org->left.sym; + e->right.sym = org->right.sym; + break; + case E_AND: + case E_OR: + case E_CHOICE: + e->left.expr = expr_copy(org->left.expr); + e->right.expr = expr_copy(org->right.expr); + break; + default: + printf("can't copy type %d\n", e->type); + free(e); + e = NULL; + break; + } + + return e; +} + +void expr_free(struct expr *e) +{ + if (!e) + return; + + switch (e->type) { + case E_SYMBOL: + break; + case E_NOT: + expr_free(e->left.expr); + return; + case E_EQUAL: + case E_UNEQUAL: + break; + case E_OR: + case E_AND: + expr_free(e->left.expr); + expr_free(e->right.expr); + break; + default: + printf("how to free type %d?\n", e->type); + break; + } + free(e); +} + +static int trans_count; + +#define e1 (*ep1) +#define e2 (*ep2) + +static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2) +{ + if (e1->type == type) { + __expr_eliminate_eq(type, &e1->left.expr, &e2); + __expr_eliminate_eq(type, &e1->right.expr, &e2); + return; + } + if (e2->type == type) { + __expr_eliminate_eq(type, &e1, &e2->left.expr); + __expr_eliminate_eq(type, &e1, &e2->right.expr); + return; + } + if (e1->type == E_SYMBOL && e2->type == E_SYMBOL && + e1->left.sym == e2->left.sym && (e1->left.sym->flags & (SYMBOL_YES|SYMBOL_NO))) + return; + if (!expr_eq(e1, e2)) + return; + trans_count++; + expr_free(e1); expr_free(e2); + switch (type) { + case E_OR: + e1 = expr_alloc_symbol(&symbol_no); + e2 = expr_alloc_symbol(&symbol_no); + break; + case E_AND: + e1 = expr_alloc_symbol(&symbol_yes); + e2 = expr_alloc_symbol(&symbol_yes); + break; + default: + ; + } +} + +void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) +{ + if (!e1 || !e2) + return; + switch (e1->type) { + case E_OR: + case E_AND: + __expr_eliminate_eq(e1->type, ep1, ep2); + default: + ; + } + if (e1->type != e2->type) switch (e2->type) { + case E_OR: + case E_AND: + __expr_eliminate_eq(e2->type, ep1, ep2); + default: + ; + } + e1 = expr_eliminate_yn(e1); + e2 = expr_eliminate_yn(e2); +} + +#undef e1 +#undef e2 + +int expr_eq(struct expr *e1, struct expr *e2) +{ + int res, old_count; + + if (e1->type != e2->type) + return 0; + switch (e1->type) { + case E_EQUAL: + case E_UNEQUAL: + return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym; + case E_SYMBOL: + return e1->left.sym == e2->left.sym; + case E_NOT: + return expr_eq(e1->left.expr, e2->left.expr); + case E_AND: + case E_OR: + e1 = expr_copy(e1); + e2 = expr_copy(e2); + old_count = trans_count; + expr_eliminate_eq(&e1, &e2); + res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL && + e1->left.sym == e2->left.sym); + expr_free(e1); + expr_free(e2); + trans_count = old_count; + return res; + case E_CHOICE: + case E_RANGE: + case E_NONE: + /* panic */; + } + + print_expr(0, e1, 0); + printf(" = "); + print_expr(0, e2, 0); + printf(" ?\n"); + + return 0; +} + +struct expr *expr_eliminate_yn(struct expr *e) +{ + struct expr *tmp; + + if (e) switch (e->type) { + case E_AND: + e->left.expr = expr_eliminate_yn(e->left.expr); + e->right.expr = expr_eliminate_yn(e->right.expr); + if (e->left.expr->type == E_SYMBOL) { + if (e->left.expr->left.sym == &symbol_no) { + expr_free(e->left.expr); + expr_free(e->right.expr); + e->type = E_SYMBOL; + e->left.sym = &symbol_no; + e->right.expr = NULL; + return e; + } else if (e->left.expr->left.sym == &symbol_yes) { + free(e->left.expr); + tmp = e->right.expr; + *e = *(e->right.expr); + free(tmp); + return e; + } + } + if (e->right.expr->type == E_SYMBOL) { + if (e->right.expr->left.sym == &symbol_no) { + expr_free(e->left.expr); + expr_free(e->right.expr); + e->type = E_SYMBOL; + e->left.sym = &symbol_no; + e->right.expr = NULL; + return e; + } else if (e->right.expr->left.sym == &symbol_yes) { + free(e->right.expr); + tmp = e->left.expr; + *e = *(e->left.expr); + free(tmp); + return e; + } + } + break; + case E_OR: + e->left.expr = expr_eliminate_yn(e->left.expr); + e->right.expr = expr_eliminate_yn(e->right.expr); + if (e->left.expr->type == E_SYMBOL) { + if (e->left.expr->left.sym == &symbol_no) { + free(e->left.expr); + tmp = e->right.expr; + *e = *(e->right.expr); + free(tmp); + return e; + } else if (e->left.expr->left.sym == &symbol_yes) { + expr_free(e->left.expr); + expr_free(e->right.expr); + e->type = E_SYMBOL; + e->left.sym = &symbol_yes; + e->right.expr = NULL; + return e; + } + } + if (e->right.expr->type == E_SYMBOL) { + if (e->right.expr->left.sym == &symbol_no) { + free(e->right.expr); + tmp = e->left.expr; + *e = *(e->left.expr); + free(tmp); + return e; + } else if (e->right.expr->left.sym == &symbol_yes) { + expr_free(e->left.expr); + expr_free(e->right.expr); + e->type = E_SYMBOL; + e->left.sym = &symbol_yes; + e->right.expr = NULL; + return e; + } + } + break; + default: + ; + } + return e; +} + +/* + * bool FOO!=n => FOO + */ +struct expr *expr_trans_bool(struct expr *e) +{ + if (!e) + return NULL; + switch (e->type) { + case E_AND: + case E_OR: + case E_NOT: + e->left.expr = expr_trans_bool(e->left.expr); + e->right.expr = expr_trans_bool(e->right.expr); + break; + case E_UNEQUAL: + // FOO!=n -> FOO + if (e->left.sym->type == S_TRISTATE) { + if (e->right.sym == &symbol_no) { + e->type = E_SYMBOL; + e->right.sym = NULL; + } + } + break; + default: + ; + } + return e; +} + +/* + * e1 || e2 -> ? + */ +struct expr *expr_join_or(struct expr *e1, struct expr *e2) +{ + struct expr *tmp; + struct symbol *sym1, *sym2; + + if (expr_eq(e1, e2)) + return expr_copy(e1); + if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT) + return NULL; + if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT) + return NULL; + if (e1->type == E_NOT) { + tmp = e1->left.expr; + if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL) + return NULL; + sym1 = tmp->left.sym; + } else + sym1 = e1->left.sym; + if (e2->type == E_NOT) { + if (e2->left.expr->type != E_SYMBOL) + return NULL; + sym2 = e2->left.expr->left.sym; + } else + sym2 = e2->left.sym; + if (sym1 != sym2) + return NULL; + if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE) + return NULL; + if (sym1->type == S_TRISTATE) { + if (e1->type == E_EQUAL && e2->type == E_EQUAL && + ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || + (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) { + // (a='y') || (a='m') -> (a!='n') + return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no); + } + if (e1->type == E_EQUAL && e2->type == E_EQUAL && + ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || + (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) { + // (a='y') || (a='n') -> (a!='m') + return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod); + } + if (e1->type == E_EQUAL && e2->type == E_EQUAL && + ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || + (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) { + // (a='m') || (a='n') -> (a!='y') + return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes); + } + } + if (sym1->type == S_BOOLEAN && sym1 == sym2) { + if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) || + (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL)) + return expr_alloc_symbol(&symbol_yes); + } + + printf("optimize "); + print_expr(0, e1, 0); + printf(" || "); + print_expr(0, e2, 0); + printf(" ?\n"); + return NULL; +} + +struct expr *expr_join_and(struct expr *e1, struct expr *e2) +{ + struct expr *tmp; + struct symbol *sym1, *sym2; + + if (expr_eq(e1, e2)) + return expr_copy(e1); + if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT) + return NULL; + if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT) + return NULL; + if (e1->type == E_NOT) { + tmp = e1->left.expr; + if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL) + return NULL; + sym1 = tmp->left.sym; + } else + sym1 = e1->left.sym; + if (e2->type == E_NOT) { + if (e2->left.expr->type != E_SYMBOL) + return NULL; + sym2 = e2->left.expr->left.sym; + } else + sym2 = e2->left.sym; + if (sym1 != sym2) + return NULL; + if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE) + return NULL; + + if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) || + (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes)) + // (a) && (a='y') -> (a='y') + return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); + + if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) || + (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no)) + // (a) && (a!='n') -> (a) + return expr_alloc_symbol(sym1); + + if (sym1->type == S_TRISTATE) { + if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) { + // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' + sym2 = e1->right.sym; + if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) + return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) + : expr_alloc_symbol(&symbol_no); + } + if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) { + // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' + sym2 = e2->right.sym; + if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) + return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) + : expr_alloc_symbol(&symbol_no); + } + if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && + ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || + (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) + // (a!='y') && (a!='n') -> (a='m') + return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod); + + if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && + ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || + (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) + // (a!='y') && (a!='m') -> (a='n') + return expr_alloc_comp(E_EQUAL, sym1, &symbol_no); + + if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && + ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || + (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) + // (a!='m') && (a!='n') -> (a='m') + return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); + + if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) || + (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) || + (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) || + (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes)) + return NULL; + } + printf("optimize "); + print_expr(0, e1, 0); + printf(" && "); + print_expr(0, e2, 0); + printf(" ?\n"); + return NULL; +} + +static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2) +{ +#define e1 (*ep1) +#define e2 (*ep2) + struct expr *tmp; + + if (e1->type == type) { + expr_eliminate_dups1(type, &e1->left.expr, &e2); + expr_eliminate_dups1(type, &e1->right.expr, &e2); + return; + } + if (e2->type == type) { + expr_eliminate_dups1(type, &e1, &e2->left.expr); + expr_eliminate_dups1(type, &e1, &e2->right.expr); + return; + } + if (e1 == e2) + return; + + switch (e1->type) { + case E_OR: case E_AND: + expr_eliminate_dups1(e1->type, &e1, &e1); + default: + ; + } + + switch (type) { + case E_OR: + tmp = expr_join_or(e1, e2); + if (tmp) { + expr_free(e1); expr_free(e2); + e1 = expr_alloc_symbol(&symbol_no); + e2 = tmp; + trans_count++; + } + break; + case E_AND: + tmp = expr_join_and(e1, e2); + if (tmp) { + expr_free(e1); expr_free(e2); + e1 = expr_alloc_symbol(&symbol_yes); + e2 = tmp; + trans_count++; + } + break; + default: + ; + } +#undef e1 +#undef e2 +} + +static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2) +{ +#define e1 (*ep1) +#define e2 (*ep2) + struct expr *tmp, *tmp1, *tmp2; + + if (e1->type == type) { + expr_eliminate_dups2(type, &e1->left.expr, &e2); + expr_eliminate_dups2(type, &e1->right.expr, &e2); + return; + } + if (e2->type == type) { + expr_eliminate_dups2(type, &e1, &e2->left.expr); + expr_eliminate_dups2(type, &e1, &e2->right.expr); + } + if (e1 == e2) + return; + + switch (e1->type) { + case E_OR: + expr_eliminate_dups2(e1->type, &e1, &e1); + // (FOO || BAR) && (!FOO && !BAR) -> n + tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1))); + tmp2 = expr_copy(e2); + tmp = expr_extract_eq_and(&tmp1, &tmp2); + if (expr_is_yes(tmp1)) { + expr_free(e1); + e1 = expr_alloc_symbol(&symbol_no); + trans_count++; + } + expr_free(tmp2); + expr_free(tmp1); + expr_free(tmp); + break; + case E_AND: + expr_eliminate_dups2(e1->type, &e1, &e1); + // (FOO && BAR) || (!FOO || !BAR) -> y + tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1))); + tmp2 = expr_copy(e2); + tmp = expr_extract_eq_or(&tmp1, &tmp2); + if (expr_is_no(tmp1)) { + expr_free(e1); + e1 = expr_alloc_symbol(&symbol_yes); + trans_count++; + } + expr_free(tmp2); + expr_free(tmp1); + expr_free(tmp); + break; + default: + ; + } +#undef e1 +#undef e2 +} + +struct expr *expr_eliminate_dups(struct expr *e) +{ + int oldcount; + if (!e) + return e; + + oldcount = trans_count; + while (1) { + trans_count = 0; + switch (e->type) { + case E_OR: case E_AND: + expr_eliminate_dups1(e->type, &e, &e); + expr_eliminate_dups2(e->type, &e, &e); + default: + ; + } + if (!trans_count) + break; + e = expr_eliminate_yn(e); + } + trans_count = oldcount; + return e; +} + +struct expr *expr_transform(struct expr *e) +{ + struct expr *tmp; + + if (!e) + return NULL; + switch (e->type) { + case E_EQUAL: + case E_UNEQUAL: + case E_SYMBOL: + case E_CHOICE: + break; + default: + e->left.expr = expr_transform(e->left.expr); + e->right.expr = expr_transform(e->right.expr); + } + + switch (e->type) { + case E_EQUAL: + if (e->left.sym->type != S_BOOLEAN) + break; + if (e->right.sym == &symbol_no) { + e->type = E_NOT; + e->left.expr = expr_alloc_symbol(e->left.sym); + e->right.sym = NULL; + break; + } + if (e->right.sym == &symbol_mod) { + printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name); + e->type = E_SYMBOL; + e->left.sym = &symbol_no; + e->right.sym = NULL; + break; + } + if (e->right.sym == &symbol_yes) { + e->type = E_SYMBOL; + e->right.sym = NULL; + break; + } + break; + case E_UNEQUAL: + if (e->left.sym->type != S_BOOLEAN) + break; + if (e->right.sym == &symbol_no) { + e->type = E_SYMBOL; + e->right.sym = NULL; + break; + } + if (e->right.sym == &symbol_mod) { + printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name); + e->type = E_SYMBOL; + e->left.sym = &symbol_yes; + e->right.sym = NULL; + break; + } + if (e->right.sym == &symbol_yes) { + e->type = E_NOT; + e->left.expr = expr_alloc_symbol(e->left.sym); + e->right.sym = NULL; + break; + } + break; + case E_NOT: + switch (e->left.expr->type) { + case E_NOT: + // !!a -> a + tmp = e->left.expr->left.expr; + free(e->left.expr); + free(e); + e = tmp; + e = expr_transform(e); + break; + case E_EQUAL: + case E_UNEQUAL: + // !a='x' -> a!='x' + tmp = e->left.expr; + free(e); + e = tmp; + e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL; + break; + case E_OR: + // !(a || b) -> !a && !b + tmp = e->left.expr; + e->type = E_AND; + e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); + tmp->type = E_NOT; + tmp->right.expr = NULL; + e = expr_transform(e); + break; + case E_AND: + // !(a && b) -> !a || !b + tmp = e->left.expr; + e->type = E_OR; + e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); + tmp->type = E_NOT; + tmp->right.expr = NULL; + e = expr_transform(e); + break; + case E_SYMBOL: + if (e->left.expr->left.sym == &symbol_yes) { + // !'y' -> 'n' + tmp = e->left.expr; + free(e); + e = tmp; + e->type = E_SYMBOL; + e->left.sym = &symbol_no; + break; + } + if (e->left.expr->left.sym == &symbol_mod) { + // !'m' -> 'm' + tmp = e->left.expr; + free(e); + e = tmp; + e->type = E_SYMBOL; + e->left.sym = &symbol_mod; + break; + } + if (e->left.expr->left.sym == &symbol_no) { + // !'n' -> 'y' + tmp = e->left.expr; + free(e); + e = tmp; + e->type = E_SYMBOL; + e->left.sym = &symbol_yes; + break; + } + break; + default: + ; + } + break; + default: + ; + } + return e; +} + +int expr_contains_symbol(struct expr *dep, struct symbol *sym) +{ + if (!dep) + return 0; + + switch (dep->type) { + case E_AND: + case E_OR: + return expr_contains_symbol(dep->left.expr, sym) || + expr_contains_symbol(dep->right.expr, sym); + case E_SYMBOL: + return dep->left.sym == sym; + case E_EQUAL: + case E_UNEQUAL: + return dep->left.sym == sym || + dep->right.sym == sym; + case E_NOT: + return expr_contains_symbol(dep->left.expr, sym); + default: + ; + } + return 0; +} + +bool expr_depends_symbol(struct expr *dep, struct symbol *sym) +{ + if (!dep) + return false; + + switch (dep->type) { + case E_AND: + return expr_depends_symbol(dep->left.expr, sym) || + expr_depends_symbol(dep->right.expr, sym); + case E_SYMBOL: + return dep->left.sym == sym; + case E_EQUAL: + if (dep->left.sym == sym) { + if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod) + return true; + } + break; + case E_UNEQUAL: + if (dep->left.sym == sym) { + if (dep->right.sym == &symbol_no) + return true; + } + break; + default: + ; + } + return false; +} + +struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2) +{ + struct expr *tmp = NULL; + expr_extract_eq(E_AND, &tmp, ep1, ep2); + if (tmp) { + *ep1 = expr_eliminate_yn(*ep1); + *ep2 = expr_eliminate_yn(*ep2); + } + return tmp; +} + +struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2) +{ + struct expr *tmp = NULL; + expr_extract_eq(E_OR, &tmp, ep1, ep2); + if (tmp) { + *ep1 = expr_eliminate_yn(*ep1); + *ep2 = expr_eliminate_yn(*ep2); + } + return tmp; +} + +void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2) +{ +#define e1 (*ep1) +#define e2 (*ep2) + if (e1->type == type) { + expr_extract_eq(type, ep, &e1->left.expr, &e2); + expr_extract_eq(type, ep, &e1->right.expr, &e2); + return; + } + if (e2->type == type) { + expr_extract_eq(type, ep, ep1, &e2->left.expr); + expr_extract_eq(type, ep, ep1, &e2->right.expr); + return; + } + if (expr_eq(e1, e2)) { + *ep = *ep ? expr_alloc_two(type, *ep, e1) : e1; + expr_free(e2); + if (type == E_AND) { + e1 = expr_alloc_symbol(&symbol_yes); + e2 = expr_alloc_symbol(&symbol_yes); + } else if (type == E_OR) { + e1 = expr_alloc_symbol(&symbol_no); + e2 = expr_alloc_symbol(&symbol_no); + } + } +#undef e1 +#undef e2 +} + +struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym) +{ + struct expr *e1, *e2; + + if (!e) { + e = expr_alloc_symbol(sym); + if (type == E_UNEQUAL) + e = expr_alloc_one(E_NOT, e); + return e; + } + switch (e->type) { + case E_AND: + e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym); + e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym); + if (sym == &symbol_yes) + e = expr_alloc_two(E_AND, e1, e2); + if (sym == &symbol_no) + e = expr_alloc_two(E_OR, e1, e2); + if (type == E_UNEQUAL) + e = expr_alloc_one(E_NOT, e); + return e; + case E_OR: + e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym); + e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym); + if (sym == &symbol_yes) + e = expr_alloc_two(E_OR, e1, e2); + if (sym == &symbol_no) + e = expr_alloc_two(E_AND, e1, e2); + if (type == E_UNEQUAL) + e = expr_alloc_one(E_NOT, e); + return e; + case E_NOT: + return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym); + case E_UNEQUAL: + case E_EQUAL: + if (type == E_EQUAL) { + if (sym == &symbol_yes) + return expr_copy(e); + if (sym == &symbol_mod) + return expr_alloc_symbol(&symbol_no); + if (sym == &symbol_no) + return expr_alloc_one(E_NOT, expr_copy(e)); + } else { + if (sym == &symbol_yes) + return expr_alloc_one(E_NOT, expr_copy(e)); + if (sym == &symbol_mod) + return expr_alloc_symbol(&symbol_yes); + if (sym == &symbol_no) + return expr_copy(e); + } + break; + case E_SYMBOL: + return expr_alloc_comp(type, e->left.sym, sym); + case E_CHOICE: + case E_RANGE: + case E_NONE: + /* panic */; + } + return NULL; +} + +tristate expr_calc_value(struct expr *e) +{ + tristate val1, val2; + const char *str1, *str2; + + if (!e) + return yes; + + switch (e->type) { + case E_SYMBOL: + sym_calc_value(e->left.sym); + return e->left.sym->curr.tri; + case E_AND: + val1 = expr_calc_value(e->left.expr); + val2 = expr_calc_value(e->right.expr); + return E_AND(val1, val2); + case E_OR: + val1 = expr_calc_value(e->left.expr); + val2 = expr_calc_value(e->right.expr); + return E_OR(val1, val2); + case E_NOT: + val1 = expr_calc_value(e->left.expr); + return E_NOT(val1); + case E_EQUAL: + sym_calc_value(e->left.sym); + sym_calc_value(e->right.sym); + str1 = sym_get_string_value(e->left.sym); + str2 = sym_get_string_value(e->right.sym); + return !strcmp(str1, str2) ? yes : no; + case E_UNEQUAL: + sym_calc_value(e->left.sym); + sym_calc_value(e->right.sym); + str1 = sym_get_string_value(e->left.sym); + str2 = sym_get_string_value(e->right.sym); + return !strcmp(str1, str2) ? no : yes; + default: + printf("expr_calc_value: %d?\n", e->type); + return no; + } +} + +int expr_compare_type(enum expr_type t1, enum expr_type t2) +{ +#if 0 + return 1; +#else + if (t1 == t2) + return 0; + switch (t1) { + case E_EQUAL: + case E_UNEQUAL: + if (t2 == E_NOT) + return 1; + case E_NOT: + if (t2 == E_AND) + return 1; + case E_AND: + if (t2 == E_OR) + return 1; + case E_OR: + if (t2 == E_CHOICE) + return 1; + case E_CHOICE: + if (t2 == 0) + return 1; + default: + return -1; + } + printf("[%dgt%d?]", t1, t2); + return 0; +#endif +} + +void expr_print(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken) +{ + if (!e) { + fn(data, "y"); + return; + } + + if (expr_compare_type(prevtoken, e->type) > 0) + fn(data, "("); + switch (e->type) { + case E_SYMBOL: + if (e->left.sym->name) + fn(data, e->left.sym->name); + else + fn(data, "<choice>"); + break; + case E_NOT: + fn(data, "!"); + expr_print(e->left.expr, fn, data, E_NOT); + break; + case E_EQUAL: + fn(data, e->left.sym->name); + fn(data, "="); + fn(data, e->right.sym->name); + break; + case E_UNEQUAL: + fn(data, e->left.sym->name); + fn(data, "!="); + fn(data, e->right.sym->name); + break; + case E_OR: + expr_print(e->left.expr, fn, data, E_OR); + fn(data, " || "); + expr_print(e->right.expr, fn, data, E_OR); + break; + case E_AND: + expr_print(e->left.expr, fn, data, E_AND); + fn(data, " && "); + expr_print(e->right.expr, fn, data, E_AND); + break; + case E_CHOICE: + fn(data, e->right.sym->name); + if (e->left.expr) { + fn(data, " ^ "); + expr_print(e->left.expr, fn, data, E_CHOICE); + } + break; + case E_RANGE: + fn(data, "["); + fn(data, e->left.sym->name); + fn(data, " "); + fn(data, e->right.sym->name); + fn(data, "]"); + break; + default: + { + char buf[32]; + sprintf(buf, "<unknown type %d>", e->type); + fn(data, buf); + break; + } + } + if (expr_compare_type(prevtoken, e->type) > 0) + fn(data, ")"); +} + +static void expr_print_file_helper(void *data, const char *str) +{ + fwrite(str, strlen(str), 1, data); +} + +void expr_fprint(struct expr *e, FILE *out) +{ + expr_print(e, expr_print_file_helper, out, E_NONE); +} + +void print_expr(int mask, struct expr *e, int prevtoken) +{ + if (!(cdebug & mask)) + return; + expr_fprint(e, stdout); +} + Added: scripts/kconfig/expr.h =================================================================== --- scripts/kconfig/expr.h (rev 0) +++ scripts/kconfig/expr.h 2009-05-22 05:21:12 UTC (rev 365) @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2002 Roman Zippel <zi...@li...> + * Released under the terms of the GNU GPL v2.0. + */ + +#ifndef EXPR_H +#define EXPR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> +#ifndef __cplusplus +#include <stdbool.h> +#endif + +struct file { + struct file *next; + struct file *parent; + char *name; + int lineno; + int flags; +}; + +#define FILE_BUSY 0x0001 +#define FILE_SCANNED 0x0002 +#define FILE_PRINTED 0x0004 + +typedef enum tristate { + no, mod, yes +} tristate; + +enum expr_type { + E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL, E_RANGE +}; + +union expr_data { + struct expr *expr; + struct symbol *sym; +}; + +struct expr { + enum expr_type type; + union expr_data left, right; +}; + +#define E_OR(dep1, dep2) (((dep1)>(dep2))?(dep1):(dep2)) +#define E_AND(dep1, dep2) (((dep1)<(dep2))?(dep1):(dep2)) +#define E_NOT(dep) (2-(dep)) + +struct expr_value { + struct expr *expr; + tristate tri; +}; + +struct symbol_value { + void *val; + tristate tri; +}; + +enum symbol_type { + S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER +}; + +struct symbol { + struct symbol *next; + char *name; + char *help; + enum symbol_type type; + struct symbol_value curr, user; + tristate visible; + int flags; + struct property *prop; + struct expr *dep, *dep2; + struct expr_value rev_dep; +}; + +#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) + +#define SYMBOL_YES 0x0001 +#define SYMBOL_MOD 0x0002 +#define SYMBOL_NO 0x0004 +#define SYMBOL_CONST 0x0007 +#define SYMBOL_CHECK 0x0008 +#define SYMBOL_CHOICE 0x0010 +#define SYMBOL_CHOICEVAL 0x0020 +#define SYMBOL_PRINTED 0x0040 +#define SYMBOL_VALID 0x0080 +#define SYMBOL_OPTIONAL 0x0100 +#define SYMBOL_WRITE 0x0200 +#define SYMBOL_CHANGED 0x0400 +#define SYMBOL_NEW 0x0800 +#define SYMBOL_AUTO 0x1000 +#define SYMBOL_CHECKED 0x2000 +#define SYMBOL_CHECK_DONE 0x4000 +#define SYMBOL_WARNED 0x8000 + +#define SYMBOL_MAXLENGTH 256 +#define SYMBOL_HASHSIZE 257 +#define SYMBOL_HASHMASK 0xff + +enum prop_type { + P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE, P_SELECT, P_RANGE +}; + +struct property { + struct property *next; + struct symbol *sym; + enum prop_type type; + const char *text; + struct expr_value visible; + struct expr *expr; + struct menu *menu; + struct file *file; + int lineno; +}; + +#define for_all_properties(sym, st, tok) \ + for (st = sym->prop; st; st = st->next) \ + if (st->type == (tok)) +#define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT) +#define for_all_choices(sym, st) for_all_properties(sym, st, P_CHOICE) +#define for_all_prompts(sym, st) \ + for (st = sym->prop; st; st = st->next) \ + if (st->text) + +struct menu { + struct menu *next; + struct menu *parent; + struct menu *list; + struct symbol *sym; + struct property *prompt; + struct expr *dep; + unsigned int flags; + //char *help; + struct file *file; + int lineno; + void *data; +}; + +#define MENU_CHANGED 0x0001 +#define MENU_ROOT 0x0002 + +#ifndef SWIG + +extern struct file *file_list; +extern struct file *current_file; +struct file *lookup_file(const char *name); + +extern struct symbol symbol_yes, symbol_no, symbol_mod; +extern struct symbol *modules_sym; +extern int cdebug; +struct expr *expr_alloc_symbol(struct symbol *sym); +struct expr *expr_alloc_one(enum expr_type type, struct expr *ce); +struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2); +struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2); +struct expr *expr_alloc_and(struct expr *e1, struct expr *e2); +struct expr *expr_alloc_or(struct expr *e1, struct expr *e2); +struct expr *expr_copy(struct expr *org); +void expr_free(struct expr *e); +int expr_eq(struct expr *e1, struct expr *e2); +void expr_eliminate_eq(struct expr **ep1, struct expr **ep2); +tristate expr_calc_value(struct expr *e); +struct expr *expr_eliminate_yn(struct expr *e); +struct expr *expr_trans_bool(struct expr *e); +struct expr *expr_eliminate_dups(struct expr *e); +struct expr *expr_transform(struct expr *e); +int expr_contains_symbol(struct expr *dep, struct symbol *sym); +bool expr_depends_symbol(struct expr *dep, struct symbol *sym); +struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2); +struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2); +void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2); +struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); + +void expr_fprint(struct expr *e, FILE *out); +void print_expr(int mask, struct expr *e, int prevtoken); + +static inline int expr_is_yes(struct expr *e) +{ + return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes); +} + +static inline int expr_is_no(struct expr *e) +{ + return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no); +} +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* EXPR_H */ Added: scripts/kconfig/lex.zconf.c =================================================================== --- scripts/kconfig/lex.zconf.c (rev 0) +++ scripts/kconfig/lex.zconf.c 2009-05-22 05:21:12 UTC (rev 365) @@ -0,0 +1,3689 @@ + +#line 3 "lex.zconf.c" + + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 31 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ + +#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L +#include <inttypes.h> +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE zconfrestart(zconfin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +extern int zconfleng; + +extern FILE *zconfin, *zconfout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up zconftext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up zconftext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef unsigned int yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via zconfrestart()), so that the user can continue scanning by + * just pointing zconfin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when zconftext is formed. */ +static char yy_hold_char; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int zconfleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow zconfwrap()'s to do buffer switches + * instead of setting up a fresh zconfin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void zconfrestart (FILE *input_file ); +void zconf_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE zconf_create_buffer (FILE *file,int size ); +void zconf_delete_buffer (YY_BUFFER_STATE b ); +void zconf_flush_buffer (YY_BUFFER_STATE b ); +void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer ); +void zconfpop_buffer_state (void ); + +static void zconfensure_buffer_stack (void ); +static void zconf_load_buffer_state (void ); +static void zconf_init_buffer (YY_BUFFER_STATE b,FILE *file ); + +#define YY_FLUSH_BUFFER zconf_flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE zconf_scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE zconf_scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE zconf_scan_bytes (yyconst char *bytes,int len ); + +void *zconfalloc (yy_size_t ); +void *zconfrealloc (void *,yy_size_t ); +void zconffree (void * ); + +#define yy_new_buffer zconf_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + zconfensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + zconf_create_buffer(zconfin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + zconfensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + zconf_create_buffer(zconfin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define zconfwrap(n) 1 +#define YY_SKIP_YYWRAP + +typedef unsigned char YY_CHAR; + +FILE *zconfin = (FILE *) 0, *zconfout = (FILE *) 0; + +typedef int yy_state_type; + +extern int zconflineno; + +int zconflineno = 1; + +extern char *zconftext; +#define yytext_ptr zconftext +static yyconst flex_int16_t yy_nxt[][38] = + { + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 + }, + + { + 11, 12, 13, 14, 12, 12, 15, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12 + }, + + { + 11, 12, 13, 14, 12, 12, 15, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12 + }, + + { + 11, 16, 16, 17, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 18, 16, 16, 18, 18, 19, 20, + 21, 22, 18, 18, 23, 24, 18, 25, 18, 26, + 27, 18, 28, 29, 30, 18, 18, 16 + }, + + { + 11, 16, 16, 17, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 18, 16, 16, 18, 18, 19, 20, + 21, 22, 18, 18, 23, 24, 18, 25, 18, 26, + 27, 18, 28, 29, 30, 18, 18, 16 + + }, + + { + 11, 31, 32, 33, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31 + }, + + { + 11, 31, 32, 33, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31 + }, + + { + 11, 34, 34, 35, 34, 36, 34, 34, 36, 34, + 34, 34, 34, 34, 34, 37, 34, 34, 34, 34, + + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34 + }, + + { + 11, 34, 34, 35, 34, 36, 34, 34, 36, 34, + 34, 34, 34, 34, 34, 37, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34 + }, + + { + 11, 38, 38, 39, 40, 41, 42, 43, 41, 44, + 45, 46, 47, 47, 48, 49, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 50, 47, 47, 47, 51, + 47, 47, 47, 47, 47, 47, 47, 52 + + }, + + { + 11, 38, 38, 39, 40, 41, 42, 43, 41, 44, + 45, 46, 47, 47, 48, 49, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 50, 47, 47, 47, 51, + 47, 47, 47, 47, 47, 47, 47, 52 + }, + + { + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, + -11, -11, -11, -11, -11, -11, -11, -11 + }, + + { + 11, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + + -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, + -12, -12, -12, -12, -12, -12, -12, -12 + }, + + { + 11, -13, 53, 54, -13, -13, 55, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13 + }, + + { + 11, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, + -14, -14, -14, -14, -14, -14, -14, -14 + + }, + + { + 11, 56, 56, 57, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56 + }, + + { + 11, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + -16, -16, -16, -16, -16, -16, -16, -16 + }, + + { + 11, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + + -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + -17, -17, -17, -17, -17, -17, -17, -17 + }, + + { + 11, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, 58, -18, -18, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -18 + }, + + { + 11, -19, -19, -19, -19, -19, -19, -19, -19, -19, + -19, -19, -19, 58, -19, -19, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, + 58, 58, 58, 58, 58, 58, 58, -19 + + }, + + { + 11, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, 58, -20, -20, 58, 58, 58, 58, + 58, 58, 58, 58, 60, 58, 58, 58, 58, 61, + 58, 58, 58, 58, 58, 58, 58, -20 + }, + + { + 11, -21, -21, -21, -21, -21, -21, -21, -21, -21, + -21, -21, -21, 58, -21, -21, 58, 58, 58, 58, + 58, 62, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -21 + }, + + { + 11, -22, -22, -22, -22, -22, -22, -22, -22, -22, + -22, -22, -22, 58, -22, -22, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 63, 58, + 58, 58, 58, 58, 58, 58, 58, -22 + }, + + { + 11, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, 58, -23, -23, 58, 58, 58, 58, + 58, 64, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -23 + }, + + { + 11, -24, -24, -24, -24, -24, -24, -24, -24, -24, + -24, -24, -24, 58, -24, -24, 58, 58, 58, 58, + 58, 58, 65, 58, 58, 58, 58, 58, 66, 58, + 58, 58, 58, 58, 58, 58, 58, -24 + + }, + + { + 11, -25, -25, -25, -25, -25, -25, -25, -25, -25, + -25, -25, -25, 58, -25, -25, 58, 67, 58, 58, + 58, 68, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -25 + }, + + { + 11, -26, -26, -26, -26, -26, -26, -26, -26, -26, + -26, -26, -26, 58, -26, -26, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 69, 58, 58, 58, 58, 58, 58, -26 + }, + + { + 11, -27, -27, -27, -27, -27, -27, -27, -27, -27, + -27, -27, -27, 58, -27, -27, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 70, 58, 58, 58, 58, -27 + }, + + { + 11, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, -28, -28, 58, -28, -28, 58, 71, 58, 58, + 58, 72, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, -28 + }, + + { + 11, -29, -29, -29, -29, -29, -29, -29, -29, -29, + -29, -29, -29, 58, -29, -29, 58, 58, 58, 58, + 58, 73, 58, 58, 58, 58, 58, 58, 58, 74, + 58, 58, 58, 58, 75, 58, 58, -29 + + }, + + { + 11, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, 58, -30, -30, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 76, 58, 58, 58, 58, -30 + }, +... [truncated message content] |
From: <sam...@us...> - 2009-05-10 02:36:03
|
Revision: 364 http://aceos.svn.sourceforge.net/aceos/?rev=364&view=rev Author: samueldotj Date: 2009-05-10 02:35:55 +0000 (Sun, 10 May 2009) Log Message: ----------- acpi : 1) Addressed previous commit review comments regarding variable namings 2) Used PNP ids(Hardware IDs) instead of ACPI path to identify devices(otherwise each firmware has its own path, so identifying device is difficult) pci: 1) pci device id will start as "PCI/" instead of "PCI_"(this makes device ids more human readable) pm_types.h: 1) Removed duplicate code vfs.h: 1) Increased timeout value - otherwise they are failing randomly in vmware arch.c: 1) Now ace really halts in idle thread(my contribution to green world) rootbus.c: 1) Rootbus will create only ACPI bus device. The creation of PCI bus device is removed, because pci bus will be present ACPI namespace, so ACPI driver will load it. kmem.c: 1) Added assert for size > 0. If it was there previously it could have save 5-6 hours of mine. vm_unit.c: 1) Fixed calculation for total virtual page required by a unit. Now it is always thread.c: 1) Boot thread is already running, so set its state to THREAD_STATE_RUN boot_fs.c: 1) Printing some messages before panicing is good idea scheduler.c: 1) Avoided a forever loop inside SelectThreadToRun() if both active dormant queue is empty(only idle thread is running) Modified Paths: -------------- src/drivers/acpi/acpi.c src/drivers/pci/pci.c src/include/kernel/pit.h src/include/kernel/pm/pm_types.h src/include/kernel/vfs/vfs.h src/kernel/driver_id.txt src/kernel/i386/arch.c src/kernel/iom/iom.c src/kernel/iom/rootbus.c src/kernel/main.c src/kernel/mm/kmem.c src/kernel/mm/vm.c src/kernel/mm/vm_unit.c src/kernel/pit/pit.c src/kernel/pm/scheduler.c src/kernel/pm/thread.c src/kernel/vfs/boot_fs.c Modified: src/drivers/acpi/acpi.c =================================================================== --- src/drivers/acpi/acpi.c 2009-04-22 13:50:10 UTC (rev 363) +++ src/drivers/acpi/acpi.c 2009-05-10 02:35:55 UTC (rev 364) @@ -11,7 +11,7 @@ #include <kernel/acpi/acpi.h> #include "acpi.h" -static ERROR_CODE MajorFunctionPnp(DEVICE_OBJECT_PTR pDeviceObject, IRP_PTR pIrp); +static ERROR_CODE MajorFunctionPnp(DEVICE_OBJECT_PTR device_object, IRP_PTR irp); static ERROR_CODE AddDevice(DRIVER_OBJECT_PTR pDriverObject, DEVICE_OBJECT_PTR pPdo); /*Entry point - called during driver initialization*/ @@ -40,34 +40,57 @@ ACPI_BUFFER buf; char name[ACPI_DEVICE_NAME_MAX]; ACPI_DEVICE_CALLBACK_ARGUMENT_PTR arg; + ACPI_DEVICE_INFO * dev_info_ptr; + ACPI_STATUS ret; + arg = (ACPI_DEVICE_CALLBACK_ARGUMENT_PTR) Context; + + /*for debugging purpose trace the name of the device*/ buf.Pointer = name; buf.Length = sizeof(name); + if ( AcpiGetName(ObjHandle, ACPI_FULL_PATHNAME, &buf) == AE_OK ) + ktrace("Found device ACPI %s ", name ); - arg = (ACPI_DEVICE_CALLBACK_ARGUMENT_PTR) Context; - if ( AcpiGetName(ObjHandle, ACPI_FULL_PATHNAME, &buf) == AE_OK ) + /*get the required size*/ + buf.Pointer = NULL; + buf.Length = ACPI_ALLOCATE_BUFFER; + ret = AcpiGetObjectInfo(ObjHandle, &buf); + + if ( ret != AE_OK ) + return AE_OK; + + /*get hardware id (HID)*/ + dev_info_ptr = kmalloc(buf.Length, KMEM_NO_FAIL); + buf.Pointer = dev_info_ptr; + ret = AcpiGetObjectInfo(ObjHandle, &buf); + /*if HID is reterived, use it to create a new device*/ + if ( ret == AE_OK && dev_info_ptr->Valid & ACPI_VALID_HID ) { DEVICE_OBJECT_PTR child_device_object; if ( CreateDevice(arg->device_object->driver_object, sizeof(ACPI_BUS_DEVICE_EXTENSION), &child_device_object) == ERROR_SUCCESS ) { ACPI_BUS_DEVICE_EXTENSION_PTR device_ext=child_device_object->device_extension; device_ext->handle = ObjHandle; - memcpy(device_ext->device_name, buf.Pointer, ACPI_DEVICE_NAME_MAX ); + memcpy(device_ext->device_name, dev_info_ptr->HardwareId.Value, ACPI_DEVICE_ID_LENGTH ); AttachDeviceToDeviceStack(child_device_object, arg->device_object); arg->total_devices_found ++; } + ktrace("%s \n", dev_info_ptr->HardwareId.Value); } - + else + ktrace("AcpiGetObjectInfo ret %d valid bits %d\n", ret, dev_info_ptr->Valid ); + kfree(dev_info_ptr); + return AE_OK; } -static ERROR_CODE MajorFunctionPnp(DEVICE_OBJECT_PTR pDeviceObject, IRP_PTR pIrp) +static ERROR_CODE MajorFunctionPnp(DEVICE_OBJECT_PTR device_object, IRP_PTR irp) { ACPI_BUS_DEVICE_EXTENSION_PTR acpi_dev_ext=NULL; - IO_STACK_LOCATION_PTR io_stack = GetCurrentIrpStackLocation(pIrp); + IO_STACK_LOCATION_PTR io_stack = GetCurrentIrpStackLocation(irp); void * return_value; - pIrp->io_status.status = ERROR_NOT_SUPPORTED; - pIrp->io_status.information = NULL; + irp->io_status.status = ERROR_NOT_SUPPORTED; + irp->io_status.information = NULL; switch( io_stack->minor_function ) { case IRP_MN_QUERY_DEVICE_RELATIONS: @@ -78,7 +101,7 @@ ACPI_DEVICE_CALLBACK_ARGUMENT arg; arg.total_devices_found = 0; - arg.device_object = pDeviceObject; + arg.device_object = device_object; AcpiGetDevices(NULL, AcpiGetDeviceCallback, &arg, &return_value); /*put the new device relations list*/ @@ -89,45 +112,45 @@ dr = kmalloc( SIZEOF_DEVICE_RELATIONS(arg.total_devices_found), 0 ); if ( dr == NULL ) { - pIrp->io_status.status = ERROR_NOT_ENOUGH_MEMORY; + irp->io_status.status = ERROR_NOT_ENOUGH_MEMORY; return ERROR_NOT_ENOUGH_MEMORY; } dr->count = arg.total_devices_found; - assert( pDeviceObject->driver_object->device_object_head ); - dr->objects[0] = pDeviceObject->driver_object->device_object_head; - i=0; - LIST_FOR_EACH(cur_node, &pDeviceObject->driver_object->device_object_head->device_object_list ) + assert( device_object->driver_object->device_object_head ); + dr->objects[0] = device_object->driver_object->device_object_head; + i=1; + LIST_FOR_EACH(cur_node, &device_object->driver_object->device_object_head->device_object_list ) { dr->objects[i] = STRUCT_ADDRESS_FROM_MEMBER(cur_node, DEVICE_OBJECT, device_object_list); i++; } /*return success*/ - pIrp->io_status.information = dr; - pIrp->io_status.status = ERROR_SUCCESS; + irp->io_status.information = dr; + irp->io_status.status = ERROR_SUCCESS; return ERROR_SUCCESS; } } break; case IRP_MN_QUERY_ID: - acpi_dev_ext = (ACPI_BUS_DEVICE_EXTENSION_PTR)pDeviceObject->device_extension; + acpi_dev_ext = (ACPI_BUS_DEVICE_EXTENSION_PTR)device_object->device_extension; assert( acpi_dev_ext != NULL ); + irp->io_status.information = NULL; if ( io_stack->parameters.query_id.id_type == BUS_QUERY_DEVICE_ID ) { - pIrp->io_status.information = kmalloc( DRIVER_NAME_MAX, 0 ); - if ( pIrp->io_status.information == NULL ) + irp->io_status.information = kmalloc( DRIVER_NAME_MAX, 0 ); + if ( irp->io_status.information == NULL ) { - pIrp->io_status.status = ERROR_NOT_ENOUGH_MEMORY; + irp->io_status.status = ERROR_NOT_ENOUGH_MEMORY; return ERROR_NOT_ENOUGH_MEMORY; } - sprintf(pIrp->io_status.information, "ACPI/%s", &acpi_dev_ext->device_name[1]); - pIrp->io_status.status = ERROR_SUCCESS; + strcpy(irp->io_status.information, acpi_dev_ext->device_name); + irp->io_status.status = ERROR_SUCCESS; } else if ( io_stack->parameters.query_id.id_type == BUS_QUERY_INSTANCE_ID ) { - pIrp->io_status.information = NULL; - pIrp->io_status.status = ERROR_SUCCESS; + irp->io_status.status = ERROR_SUCCESS; } else return ERROR_NOT_SUPPORTED; Modified: src/drivers/pci/pci.c =================================================================== --- src/drivers/pci/pci.c 2009-04-22 13:50:10 UTC (rev 363) +++ src/drivers/pci/pci.c 2009-05-10 02:35:55 UTC (rev 364) @@ -186,7 +186,7 @@ pIrp->io_status.status = ERROR_NOT_ENOUGH_MEMORY; return ERROR_NOT_ENOUGH_MEMORY; } - sprintf(pIrp->io_status.information, "PCI_VEN_%x&DEV_%x&SUBSYS_%d&REV_%d", + sprintf(pIrp->io_status.information, "PCI/VEN_%X&DEV_%X&SUBSYS_%d&REV_%d", pci_dev_ext->pci_conf.vendor_id, pci_dev_ext->pci_conf.device_id, pci_dev_ext->pci_conf.pci_standard.sub_system_device_id, pci_dev_ext->pci_conf.revision_id); pIrp->io_status.status = ERROR_SUCCESS; } Modified: src/include/kernel/pit.h =================================================================== --- src/include/kernel/pit.h 2009-04-22 13:50:10 UTC (rev 363) +++ src/include/kernel/pit.h 2009-05-10 02:35:55 UTC (rev 364) @@ -3,7 +3,6 @@ \brief Programmable Interval Timer */ - #ifndef _PIT_H_ #define _PIT_H_ Modified: src/include/kernel/pm/pm_types.h =================================================================== --- src/include/kernel/pm/pm_types.h 2009-04-22 13:50:10 UTC (rev 363) +++ src/include/kernel/pm/pm_types.h 2009-05-10 02:35:55 UTC (rev 364) @@ -13,33 +13,3 @@ typedef struct message_queue MESSAGE_QUEUE, *MESSAGE_QUEUE_PTR; #endif -/*! - \file kernel/pm/pm_types.h - \brief all the typedefs of task, thread and ipc -*/ -#ifndef PM_TYPES_H -#define PM_TYPES_H - -typedef struct task TASK, * TASK_PTR; -typedef struct thread THREAD, * THREAD_PTR; -typedef struct pid_info PID_INFO, * PID_INFO_PTR; - -typedef struct wait_event WAIT_EVENT, *WAIT_EVENT_PTR; -typedef struct message_queue MESSAGE_QUEUE, *MESSAGE_QUEUE_PTR; - -#endif -/*! - \file kernel/pm/pm_types.h - \brief all the typedefs of task, thread and ipc -*/ -#ifndef PM_TYPES_H -#define PM_TYPES_H - -typedef struct task TASK, * TASK_PTR; -typedef struct thread THREAD, * THREAD_PTR; -typedef struct pid_info PID_INFO, * PID_INFO_PTR; - -typedef struct wait_event WAIT_EVENT, *WAIT_EVENT_PTR; -typedef struct message_queue MESSAGE_QUEUE, *MESSAGE_QUEUE_PTR; - -#endif Modified: src/include/kernel/vfs/vfs.h =================================================================== --- src/include/kernel/vfs/vfs.h 2009-04-22 13:50:10 UTC (rev 363) +++ src/include/kernel/vfs/vfs.h 2009-05-10 02:35:55 UTC (rev 364) @@ -39,8 +39,8 @@ /*! how many elements in the vnode hash table*/ #define VNODE_HASH_TABLE_SIZE 100 -#define VFS_MOUNT_TIME_OUT 50 -#define VFS_TIME_OUT 50 +#define VFS_MOUNT_TIME_OUT 1000 +#define VFS_TIME_OUT 1000 /*! \todo - move these enums to usr visible include directory*/ typedef enum Modified: src/kernel/driver_id.txt =================================================================== --- src/kernel/driver_id.txt 2009-04-22 13:50:10 UTC (rev 363) +++ src/kernel/driver_id.txt 2009-05-10 02:35:55 UTC (rev 364) @@ -1,8 +1,13 @@ #device_id driver_file_name +#root bus device ids acpi acpi.sys -ACPI/_SB_.PCI0.ISA_.KBD_ ps2keyboard.sys -ACPI/_SB_.PCI0.ISA_.MOU_ ps2mouse.sys -pci_bus pci_bus.sys -PCI_VEN_10ec&DEV_8029&SUBSYS_0&REV_0 pci_rtl8029.sys +#pnp device ids +PNP0A03 pci_bus.sys +PNP0303 ps2keyboard.sys +PNP0F13 ps2mouse.sys +PNP0700 fdd.sys + +#pci device ids +PCI/VEN_10EC&DEV_8029&SUBSYS_0&REV_0 pci_rtl8029.sys Modified: src/kernel/i386/arch.c =================================================================== --- src/kernel/i386/arch.c 2009-04-22 13:50:10 UTC (rev 363) +++ src/kernel/i386/arch.c 2009-05-10 02:35:55 UTC (rev 364) @@ -353,7 +353,7 @@ /*! Halt the processor until external interrupt comes*/ void ArchHalt() { - //asm("hlt"); + asm("hlt"); } /*! Take the cpu to offline Modified: src/kernel/iom/iom.c =================================================================== --- src/kernel/iom/iom.c 2009-04-22 13:50:10 UTC (rev 363) +++ src/kernel/iom/iom.c 2009-05-10 02:35:55 UTC (rev 364) @@ -235,11 +235,11 @@ if ( irp->io_status.status != ERROR_SUCCESS ) goto done; dr = (DEVICE_RELATIONS_PTR)irp->io_status.information; - /**/ + /*loop through the list of devices call drivers of them to add newly found/created devices*/ for(i=0; i<dr->count; i++) { /*\todo - if the device is not new - continue*/ - + /*send query id irp for each new device to the driver*/ ReuseIrp( irp, ERROR_NOT_SUPPORTED ); FillIoStack( irp->current_stack_location, IRP_MJ_PNP, IRP_MN_QUERY_ID, dr->objects[i], NULL, NULL ); @@ -247,7 +247,8 @@ CallDriver( dr->objects[i] , irp); if( irp->io_status.status == ERROR_SUCCESS ) { - DRIVER_OBJECT_PTR driver_object = LoadDriver(irp->io_status.information); + DRIVER_OBJECT_PTR driver_object; + driver_object = LoadDriver(irp->io_status.information); if ( driver_object != NULL ) { driver_object->fn.AddDevice( driver_object, dr->objects[i] ); @@ -413,6 +414,7 @@ } #define SKIP_WHITE_SPACES while( i<file_size && isspace(va[i]) ) i++; + /*! Finds suitable driver for the given id and returns its full path in the given buffer \param device_id - device identification string @@ -451,8 +453,8 @@ { char driver_device_id[100]; SKIP_WHITE_SPACES; - - /*skip comments*/ + + /*if the line not starting with comment character process it*/ if( va[i]!='#' ) { int j=0; Modified: src/kernel/iom/rootbus.c =================================================================== --- src/kernel/iom/rootbus.c 2009-04-22 13:50:10 UTC (rev 363) +++ src/kernel/iom/rootbus.c 2009-05-10 02:35:55 UTC (rev 364) @@ -1,6 +1,6 @@ /*! \file kernel/iom/rootbus.c - \brief Imaginary root bus which connects all legacy(ISA) and local bus(PCI) in the system. + \brief Imaginary root bus - It has only one device - ACPI bus */ #include <ace.h> #include <stdlib.h> @@ -8,7 +8,6 @@ #include <kernel/debug.h> #include <kernel/iom/iom.h> -#define PCI_BUS_NAME "pci_bus" #define ACPI_BUS_NAME "acpi" typedef struct rootbus_device_extension @@ -42,12 +41,12 @@ static DEVICE_RELATIONS_PTR CreateRootBusDevices(DEVICE_OBJECT_PTR pDeviceObject) { DEVICE_RELATIONS_PTR dr; - DEVICE_OBJECT_PTR pci_device_object, acpi_device_object; + DEVICE_OBJECT_PTR acpi_device_object; ROOTBUS_DEVICE_EXTENSION_PTR ext; ERROR_CODE err; /*allocate memory for device relation struction*/ - dr = kmalloc( SIZEOF_DEVICE_RELATIONS(2), 0 ); + dr = kmalloc( SIZEOF_DEVICE_RELATIONS(1), 0 ); if ( dr == NULL ) panic("Unable to create Root bus devices"); @@ -59,24 +58,13 @@ /*put rootbus specific info to device extension structure*/ ext = (ROOTBUS_DEVICE_EXTENSION_PTR)acpi_device_object->device_extension; strcpy( ext->name, ACPI_BUS_NAME ); - /*attach the pci device to root bus device io stack*/ + /*attach the acpi device to root bus device io stack*/ AttachDeviceToDeviceStack(acpi_device_object, pDeviceObject); - /*create device object for pci bus*/ - err = CreateDevice( pDeviceObject->driver_object, sizeof(ROOTBUS_DEVICE_EXTENSION), &pci_device_object ); - if ( err != ERROR_SUCCESS ) - panic("Unable to create PCI bus device"); - /*put rootbus specific info to device extension structure*/ - ext = (ROOTBUS_DEVICE_EXTENSION_PTR)pci_device_object->device_extension; - strcpy( ext->name, PCI_BUS_NAME ); - /*attach the pci device to root bus device io stack*/ - AttachDeviceToDeviceStack(pci_device_object, pDeviceObject); - /*put the device object in the device relations structure*/ - dr->count = 2; + dr->count = 1; dr->objects[0] = acpi_device_object; - dr->objects[1] = pci_device_object; - + return dr; } static ERROR_CODE MajorFunctionPnp(DEVICE_OBJECT_PTR pDeviceObject, IRP_PTR pIrp) Modified: src/kernel/main.c =================================================================== --- src/kernel/main.c 2009-04-22 13:50:10 UTC (rev 363) +++ src/kernel/main.c 2009-05-10 02:35:55 UTC (rev 364) @@ -94,5 +94,5 @@ kprintf("Kernel initialization complete\n"); - ExitThread(); + ExitThread(); } Modified: src/kernel/mm/kmem.c =================================================================== --- src/kernel/mm/kmem.c 2009-04-22 13:50:10 UTC (rev 363) +++ src/kernel/mm/kmem.c 2009-05-10 02:35:55 UTC (rev 364) @@ -124,7 +124,10 @@ */ void * kmalloc(int size, UINT32 flag) { - void * ret = AllocateFromHeap(size); + void * ret; + assert( size > 0 ); + + ret = AllocateFromHeap(size); if ( ret==NULL && (flag & KMEM_NO_FAIL) ) { kprintf("AllocateFromHeap(%d) failed.\n", size); Modified: src/kernel/mm/vm.c =================================================================== --- src/kernel/mm/vm.c 2009-04-22 13:50:10 UTC (rev 363) +++ src/kernel/mm/vm.c 2009-05-10 02:35:55 UTC (rev 364) @@ -393,7 +393,7 @@ UINT32 protection = access_type; VIRTUAL_PAGE_PTR vp = NULL; int zero_fill = FALSE; - + virtual_map = GetCurrentVirtualMap(); if ( virtual_map == NULL ) return ERROR_NOT_FOUND; @@ -412,7 +412,7 @@ kprintf("Kernel memory fault - va = %p virtual_map = %p\n", va, virtual_map); return ERROR_NOT_FOUND; } - + assert( va >= vd->start && va <= vd->end ); vtop_index = ((va - vd->start) / PAGE_SIZE) + (vd->offset_in_unit/PAGE_SIZE); assert( vtop_index <= (vd->unit->size/PAGE_SIZE) ); Modified: src/kernel/mm/vm_unit.c =================================================================== --- src/kernel/mm/vm_unit.c 2009-04-22 13:50:10 UTC (rev 363) +++ src/kernel/mm/vm_unit.c 2009-05-10 02:35:55 UTC (rev 364) @@ -15,9 +15,12 @@ */ void InitVmUnit(VM_UNIT_PTR unit, VM_UNIT_TYPE type, VM_UNIT_FLAG flag, UINT32 size) { - UINT32 total_vtop = size / PAGE_SIZE; + UINT32 total_vtop; assert( unit != NULL ); + /*total virtual pages mapped by this unit*/ + total_vtop = (size / PAGE_SIZE) + (size%PAGE_SIZE?1:0) ; + InitSpinLock( &unit->lock ); unit->reference_count = 0; Modified: src/kernel/pit/pit.c =================================================================== --- src/kernel/pit/pit.c 2009-04-22 13:50:10 UTC (rev 363) +++ src/kernel/pit/pit.c 2009-05-10 02:35:55 UTC (rev 364) @@ -44,8 +44,8 @@ tc->kernel_stack_pointer = (BYTE *) ((UINT32) interrupt_info->regs) - sizeof(UINT32); /*Send EOI to the PIC*/ - SendEndOfInterrupt( interrupt_info->interrupt_number); - + SendEndOfInterrupt( interrupt_info->interrupt_number ); + /*Select new thread to run*/ ScheduleThread( current_thread ); Modified: src/kernel/pm/scheduler.c =================================================================== --- src/kernel/pm/scheduler.c 2009-04-22 13:50:10 UTC (rev 363) +++ src/kernel/pm/scheduler.c 2009-05-10 02:35:55 UTC (rev 364) @@ -103,7 +103,6 @@ } else pqueue->bonus-- ; - } /*! @@ -119,15 +118,21 @@ because scheduler has done with it and it wont access any datastructure associated with it after this line*/ if ( current_thread->state == THREAD_STATE_TERMINATE ) { + assert( new_thread != current_thread ); FreeThread( current_thread ); } - else if ( current_thread->state != THREAD_STATE_WAITING ) + else if ( current_thread->state != THREAD_STATE_WAITING && current_thread != new_thread ) { - AddThreadToSchedulerQueue(current_thread); + assert( new_thread != current_thread ); + AddThreadToSchedulerQueue( current_thread ); } StartTimer(SCHEDULER_DEFAULT_QUANTUM, FALSE); - new_thread->state = THREAD_STATE_RUN; - SwitchContext( STRUCT_ADDRESS_FROM_MEMBER( new_thread, THREAD_CONTAINER, thread ) ); + /*if current thread is already running no need for context switch*/ + if ( current_thread != new_thread ) + { + new_thread->state = THREAD_STATE_RUN; + SwitchContext( STRUCT_ADDRESS_FROM_MEMBER( new_thread, THREAD_CONTAINER, thread ) ); + } } /*! @@ -185,9 +190,8 @@ else { /* If rem_thred was the first element in the queue, then we need to update the head */ - if( pqueue->thread_head == rem_thread ) + if( pqueue->thread_head == rem_thread ) pqueue->thread_head = STRUCT_ADDRESS_FROM_MEMBER( rem_thread->priority_queue_list.next, THREAD, priority_queue_list); - RemoveFromList( &rem_thread->priority_queue_list ); } @@ -246,6 +250,8 @@ PRIORITY_QUEUE_PTR pqueue = NULL; this_processor = GET_CURRENT_PROCESSOR; + if( this_processor->active_ready_queue->mask == 0 && this_processor->dormant_ready_queue->mask == 0 ) + return GetCurrentThread(); retry: mask = GET_MASK_AFTER_HINT(this_processor->active_ready_queue->mask, hint); @@ -261,7 +267,7 @@ if ( mask != 0 ) { SpinLock( &this_processor->lock ); - SWAP( this_processor->active_ready_queue, this_processor->dormant_ready_queue, READY_QUEUE_PTR); + SWAP( this_processor->active_ready_queue, this_processor->dormant_ready_queue, READY_QUEUE_PTR ); SpinUnlock( &this_processor->lock ); } @@ -386,10 +392,9 @@ if ( in_thread == current_thread ) /**Current thread is terminating/suspending - find another thread to run*/ { new_thread = SelectThreadToRun(current_thread->priority_queue->priority); - /*we should have got different thread atleast idle thread*/ + /*we should have got different thread - atleast idle thread*/ assert( new_thread != in_thread ); PreemptThread(new_thread); - /*not reached*/ } else { @@ -402,10 +407,13 @@ else if(in_thread == current_thread) { new_thread = SelectThreadToRun(current_thread->priority_queue->priority); - /*! Since the current priority queue got full quota to run, we should DEPROMOTE it. */ - DecrementSchedulerBonus(current_thread->priority_queue); /*! This will try to decrement the bonus. But if we are the lowest, then decrease the priority of the thread. */ - PreemptThread(new_thread); - /*not reached*/ + /*! if there is no thread, we might get the same thread - example if only idle thread is running it will come here*/ + if ( new_thread != current_thread ) + { + /*! Since the current priority queue got full quota to run, we should DEPROMOTE it. */ + DecrementSchedulerBonus(current_thread->priority_queue); /*! This will try to decrement the bonus. But if we are the lowest, then decrease the priority of the thread. */ + PreemptThread(new_thread); + } } else { Modified: src/kernel/pm/thread.c =================================================================== --- src/kernel/pm/thread.c 2009-04-22 13:50:10 UTC (rev 363) +++ src/kernel/pm/thread.c 2009-05-10 02:35:55 UTC (rev 364) @@ -152,7 +152,7 @@ thread_container->kernel_stack_pointer = (BYTE *)((VADDR)(&thread_container->kernel_stack))+PAGE_SIZE; InitSpinLock( &boot_thread->lock ); - boot_thread->state = THREAD_STATE_NEW; + boot_thread->state = THREAD_STATE_RUN; boot_thread->reference_count = 1; boot_thread->current_processor = p; @@ -166,7 +166,6 @@ It is needed for early boot vm support. And no harm in doing it :)*/ boot_thread->task = &kernel_task; - ScheduleThread( boot_thread ); } /*! Internal function used to initialize the thread structure*/ Modified: src/kernel/vfs/boot_fs.c =================================================================== --- src/kernel/vfs/boot_fs.c 2009-04-22 13:50:10 UTC (rev 363) +++ src/kernel/vfs/boot_fs.c 2009-05-10 02:35:55 UTC (rev 364) @@ -38,17 +38,27 @@ */ void InitBootFs() { + ERROR_CODE ret; + InitMessageQueue( &boot_fs_message_queue ); /*Create a receiver thread*/ CreateThread( &kernel_task, BootFsMessageReceiver, SCHED_CLASS_HIGH, TRUE ); /*register and mount boot file system*/ - if ( RegisterFileSystem( BOOT_FS_NAME, &boot_fs_message_queue ) != ERROR_SUCCESS ) + ret = RegisterFileSystem( BOOT_FS_NAME, &boot_fs_message_queue ); + if ( ret != ERROR_SUCCESS ) + { + kprintf("%s\n", ERROR_CODE_AS_STRING(ret) ); panic( "boot_fs registeration failed" ); - - if ( MountFileSystem( BOOT_FS_NAME, BOOT_FS_MOUNT_DEVICE, BOOT_FS_MOUNT_PATH ) != ERROR_SUCCESS ) + } + + ret = MountFileSystem( BOOT_FS_NAME, BOOT_FS_MOUNT_DEVICE, BOOT_FS_MOUNT_PATH ); + if ( ret != ERROR_SUCCESS ) + { + kprintf("%s\n", ERROR_CODE_AS_STRING(ret) ); panic( "boot_fs mount failed" ); + } bootfs_tar_va = (void *)kernel_reserve_range.module_va_start; bootfs_total_directory_entries = GetDirectoryEntryCountInTar(bootfs_tar_va); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sam...@us...> - 2009-04-22 13:54:14
|
Revision: 363 http://aceos.svn.sourceforge.net/aceos/?rev=363&view=rev Author: samueldotj Date: 2009-04-22 13:50:10 +0000 (Wed, 22 Apr 2009) Log Message: ----------- Added support for common section in elf. Removed some printfs in the keyboard driver Modified Paths: -------------- src/drivers/ps2keyboard/keyboard.c src/drivers/ps2keyboard/keyboard.h src/kernel/mm/vm.c src/kernel/pm/elf.c Modified: src/drivers/ps2keyboard/keyboard.c =================================================================== --- src/drivers/ps2keyboard/keyboard.c 2009-04-21 00:23:08 UTC (rev 362) +++ src/drivers/ps2keyboard/keyboard.c 2009-04-22 13:50:10 UTC (rev 363) @@ -11,6 +11,12 @@ #include <kernel/printf.h> #include "keyboard.h" +KEYBOARD_BUFFER kbd_buf[MAX_KEYBOARD_BUFFER_SIZE]; + +/* These 2 variables are dependent on the size of the macro MAX_KEYBOARD_BUFFER_SIZE */ +int cur_kbd_buf_read_index=0; +int cur_kbd_buf_write_index=0; + /* www.microsoft.com/whdc/archive/scancode.mspx * http://www.osdever.net/bkerndev/Docs/keyboard.htm */ @@ -259,8 +265,7 @@ #define NUM_LOCK_BIT 128 scancode = _inp(KEYBOARD_CONTROLLER_DATA_PORT); - kprintf("scancode %x received from keyboard\n", scancode); - + if(scancode == 0xE0) { key_e0 = 1; @@ -348,7 +353,6 @@ } modifier_keys_only: - kprintf("modifier keys stored.. no ascii; modifier_keys=%d\n", modifier_keys); return ISR_END_PROCESSING; /* Return if scan code is a modifier key */ find_ascii: @@ -396,11 +400,10 @@ return ISR_END_PROCESSING; send_buffer: -kprintf("writing to buffer\n"); /* if ascii_value > 127, then user should check for keycode also. That would show that it's one of NUMERIC keys. */ WriteToKeyboardBuffer(scancode_buffer, keycode, ascii_value); + kprintf("Wrote to keyboard buffer\n"); - kprintf("done: scancode=%s, keycode=%d, ascii_value=%d char=%c\n", scancode_buffer, keycode, ascii_value, ascii_value); return ISR_END_PROCESSING; } Modified: src/drivers/ps2keyboard/keyboard.h =================================================================== --- src/drivers/ps2keyboard/keyboard.h 2009-04-21 00:23:08 UTC (rev 362) +++ src/drivers/ps2keyboard/keyboard.h 2009-04-22 13:50:10 UTC (rev 363) @@ -23,13 +23,6 @@ unsigned char ascii_value; }KEYBOARD_BUFFER, *KEYBOARD_BUFFER_PTR; -KEYBOARD_BUFFER kbd_buf[MAX_KEYBOARD_BUFFER_SIZE]; - -/* These 2 variables are dependent on the size of the macro MAX_KEYBOARD_BUFFER_SIZE */ -int cur_kbd_buf_read_index=0; -int cur_kbd_buf_write_index=0; - - static ERROR_CODE AddDevice(DRIVER_OBJECT_PTR drv_obj, DEVICE_OBJECT_PTR parent_dev_obj); static ERROR_CODE MajorFunctionPnP(DEVICE_OBJECT_PTR dev_obj, IRP_PTR irp); static ERROR_CODE MajorFunctionRead(DEVICE_OBJECT_PTR dev_obj, IRP_PTR irp); Modified: src/kernel/mm/vm.c =================================================================== --- src/kernel/mm/vm.c 2009-04-21 00:23:08 UTC (rev 362) +++ src/kernel/mm/vm.c 2009-04-22 13:50:10 UTC (rev 363) @@ -210,7 +210,7 @@ if ( vmap->end < start + size ) vmap->end = start + size; SpinUnlock(&vmap->lock); - + if ( vmap == &kernel_map ) prot = &protection_kernel_write; else @@ -221,8 +221,8 @@ prot = &protection_user_read; } - /*create new vm_unit(if private mapping)*/ - if ( !unit ) + /*create new vm_unit if unit is not provided*/ + if ( unit == NULL ) { unit = CreateVmUnit(VM_UNIT_TYPE_ANONYMOUS, VM_UNIT_FLAG_SHARED, size); } @@ -456,7 +456,9 @@ CreatePhysicalMapping( virtual_map->physical_map, va, vp->physical_address, protection); if( zero_fill ) + { memset( (void *) PAGE_ALIGN(va), 0, PAGE_SIZE); + } return ERROR_SUCCESS; } Modified: src/kernel/pm/elf.c =================================================================== --- src/kernel/pm/elf.c 2009-04-21 00:23:08 UTC (rev 362) +++ src/kernel/pm/elf.c 2009-04-22 13:50:10 UTC (rev 363) @@ -13,6 +13,8 @@ static ERROR_CODE RelocateSection(ELF_SECTION_HEADER_PTR section_header, ELF_SYMBOL_PTR symbol_table, int relocation_section_index, char * string_table, VADDR relocation_entries, VADDR * section_loaded_va); static VADDR FindSymbolAddress(ELF_HEADER_PTR file_header, char * symbol_name, VADDR * section_loaded_va); static ELF_SYMBOL_PTR FindElfSymbolByName(ELF_SYMBOL_PTR symbol_table, UINT32 symbol_table_size, char * string_table, char * symbol_name); +static UINT32 GetElfCommonSectionSize(ELF_SYMBOL_PTR symbol_table, UINT32 symbol_table_size); +static void UpdateElfCommonSectionSymbols(ELF_SYMBOL_PTR symbol_table, UINT32 symbol_table_size, int common_section_index); #if ARCH == i386 static void RelocateI386Field(ELF32_RELOCATION_PTR rp, VADDR symbol_value, VADDR base_va, int type); @@ -30,7 +32,7 @@ { ELF_SECTION_HEADER_PTR string_section_header = NULL; char * string_table = NULL; - VADDR * section_loaded_va = NULL; + VADDR * section_loaded_va = NULL; /*holds array of virtual addresses, where the sections are loaded into the virtual map*/ ERROR_CODE err = ERROR_NOT_SUPPORTED; int i; @@ -48,12 +50,13 @@ if ( file_header->e_type == ET_NONE ) return ERROR_NOT_SUPPORTED; - - /*section_loaded_va holds address of where the section is loaded into the virtual map*/ - section_loaded_va = (VADDR *) kmalloc( sizeof(VADDR) * file_header->e_shnum, 0 ); + /* Allocate memory to hold the virtual addresses where sections will be loaded. + The last entry is used for common section(SHN_COMMON). + */ + section_loaded_va = (VADDR *) kmalloc( sizeof(VADDR) * file_header->e_shnum+1, 0 ); if ( section_loaded_va == NULL ) return ERROR_NOT_ENOUGH_MEMORY; - for(i=0; i<file_header->e_shnum; i++) + for(i=0; i<=file_header->e_shnum; i++) section_loaded_va[i] = NULL; /*find string table*/ @@ -173,13 +176,19 @@ static ERROR_CODE LoadElfSections(ELF_HEADER_PTR file_header, char * string_table, VIRTUAL_MAP_PTR virtual_map, VADDR * section_loaded_va) { ELF_SECTION_HEADER_PTR first_section_header, section_header; + ELF_SYMBOL_PTR symbol_table=NULL; + UINT32 symbol_table_size=0; ERROR_CODE ret = ERROR_SUCCESS; int i; + UINT32 common_size = 0; /*start of the section header*/ first_section_header = (ELF_SECTION_HEADER_PTR)( (VADDR)file_header + file_header->e_shoff ); - /*first pass - load all the sections into address space*/ + /*first pass - + 1) load all the sections into address space + 2) find common section address space + */ for(i=0, section_header = first_section_header; i<file_header->e_shnum;i++, section_header = (ELF_SECTION_HEADER_PTR) (((VADDR)section_header) + file_header->e_shentsize)) { /*analyze only active sections*/ @@ -188,11 +197,28 @@ section_loaded_va[i] = NULL; continue; } - + /*symbol table section - get the common section size*/ + if ( section_header->sh_type == SHT_SYMTAB ) + { + symbol_table = (ELF_SYMBOL_PTR)((char*)file_header + section_header->sh_offset); + symbol_table_size = section_header->sh_size; + common_size += GetElfCommonSectionSize( symbol_table, symbol_table_size ); + } ret = LoadElfSectionIntoMap(section_header, (VADDR)file_header+section_header->sh_offset, virtual_map, §ion_loaded_va[i]); if ( ret != ERROR_SUCCESS ) return ret; } + /*if common section is present, allocate memory for it and update all common symbols*/ + if( common_size != 0 ) + { + /*allocate memory*/ + ret = AllocateVirtualMemory( virtual_map, §ion_loaded_va[file_header->e_shnum], 0, PAGE_ALIGN_UP(common_size), PROT_READ | PROT_WRITE, 0, NULL ); + if ( ret != ERROR_SUCCESS ) + return ret; + /*Update the symbols*/ + UpdateElfCommonSectionSymbols(symbol_table, symbol_table_size, file_header->e_shnum); + } + /*second pass - relocate */ for(i=0, section_header = first_section_header; i<file_header->e_shnum;i++, section_header = (ELF_SECTION_HEADER_PTR) (((VADDR)section_header) + file_header->e_shentsize)) { @@ -231,9 +257,9 @@ /*be pessimistic*/ * section_loaded_va = NULL; - /*allocate virtual address space if the section occupies space during exeuction*/ + /*allocate virtual address space if the section occupies space during exeuction if( !(section_header->sh_flags & SHF_ALLOC) ) - return ret; + return ret;*/ /*update protection*/ if (section_header->sh_flags & SHF_WRITE) @@ -243,19 +269,20 @@ /*hint the VM our preferred virtual address*/ *section_loaded_va = section_header->sh_addr; - /*copy section data only if the source section has some data to copy*/ - if ( !(section_header->sh_flags & SHT_NOBITS) && (section_header->sh_size > 0) ) + + /*create a new zero filled section if bss*/ + if ( section_header->sh_type == SHT_NOBITS ) { - ret = CopyVirtualAddressRange( GetCurrentVirtualMap(), section_data_offset, virtual_map, section_loaded_va, section_header->sh_size, protection); - } - else - { - /*else create a new zero filled section*/ VADDR size = section_header->sh_size; if ( size == 0 ) size = PAGE_SIZE; ret = AllocateVirtualMemory( virtual_map, section_loaded_va, section_header->sh_addr, size, protection, 0, NULL ); } + else + { + /*copy section data only if the source section has some data to copy*/ + ret = CopyVirtualAddressRange( GetCurrentVirtualMap(), section_data_offset, virtual_map, section_loaded_va, section_header->sh_size, protection); + } return ret; } @@ -376,7 +403,68 @@ return NULL; } -/*! Fixes the relocation entries by walking all the relocation entries and calling architecture specific fixup routines*/ +/*! Returns common section size by summing up all the symbol's size of type common. + \param symbol_table - symbol table to search + \param symbol_table_size - size of the symbol table in bytes + \return size of the common section +*/ +static UINT32 GetElfCommonSectionSize(ELF_SYMBOL_PTR symbol_table, UINT32 symbol_table_size) +{ + UINT32 result = 0; + int i; + for(i=0;i<symbol_table_size/sizeof(ELF_SYMBOL) ;i++) + { + if ( symbol_table[i].st_shndx == SHN_COMMON ) + { + /* In the case of an SHN_COMMON symbol the st_value field holds alignment constraints.*/ + UINT32 boundary; + boundary = symbol_table[i].st_value - 1; + + /* Calculate the next byte boundary.*/ + result = ( result + boundary ) & ~boundary; + result += symbol_table[i].st_size; + } + } + return result; +} + +/*! Update all symbols of type common section with the following values + 1) index of common section + 2) offset + \param symbol_table - symbol table to search + \param symbol_table_size - size of the symbol table in bytes + \param common_section_index - common section index(currently section count+1) +*/ +static void UpdateElfCommonSectionSymbols(ELF_SYMBOL_PTR symbol_table, UINT32 symbol_table_size, int common_section_index) +{ + UINT32 offset = 0; + int i; + for(i=0;i<symbol_table_size/sizeof(ELF_SYMBOL) ;i++) + { + if ( symbol_table[i].st_shndx == SHN_COMMON ) + { + /* In the case of an SHN_COMMON symbol the st_value field holds alignment constraints.*/ + UINT32 boundary; + boundary = symbol_table[i].st_value - 1; + + /* Calculate the next byte boundary.*/ + offset = ( offset + boundary ) & ~boundary; + symbol_table[i].st_shndx = common_section_index; + symbol_table[i].st_value = offset; + offset += symbol_table[i].st_size; + } + } +} + + +/*! Fixes the relocation entries by walking all the relocation entries and calling architecture specific fixup routines + \param section_header - Relocation section header + \param symbol_table - Symbol table associated with the section + \param relocation_section_index - Section to which relocation to be applied + \param string_table - String table associated with the section + \param relocation_entries - array of relocation entries. + \param section_loaded_va - array of virtual addresses where all the sections are loaded +*/ static ERROR_CODE RelocateSection(ELF_SECTION_HEADER_PTR section_header, ELF_SYMBOL_PTR symbol_table, int relocation_section_index, char * string_table, VADDR relocation_entries, VADDR * section_loaded_va) { int i, total_entries; @@ -392,8 +480,10 @@ type = ELF_R_TYPE(rpa->r_info); #if ARCH == i386 /*i386 doesnt support relocation_addend format*/ + KTRACE("section_header->sh_type == SHT_RELA"); return ERROR_INVALID_FORMAT; #endif + assert("Architecture not supported"); } else { @@ -413,15 +503,22 @@ if ( symbol ) symbol_value = symbol->st_value; else + { + KTRACE("Symbol not found %s", &string_table[ symbol_table[sym_index].st_name ] ); return ERROR_SYMBOL_NOT_FOUND; + } } else { symbol_value = section_loaded_va[symbol_table[sym_index].st_shndx] + symbol_table[sym_index].st_value; } #if ARCH == i386 - if ( section_loaded_va[relocation_section_index] != NULL ) - RelocateI386Field(rp, symbol_value, section_loaded_va[relocation_section_index], type); + if ( section_loaded_va[relocation_section_index] == NULL ) + { + kprintf("relocation_section_index=%d\n", relocation_section_index); + panic("section_loaded_va[relocation_section_index] == NULL"); + } + RelocateI386Field(rp, symbol_value, section_loaded_va[relocation_section_index], type); #endif } } @@ -464,10 +561,10 @@ case R_386_RELATIVE: case R_386_GOTPC: case R_386_GOTOFF: - panic("ELF - Unsupported relocation entry type"); + KTRACE("ELF - Unsupported relocation entry type"); break; default: - panic("ELF - Unknown relocation entry type"); + KTRACE("ELF - Unknown relocation entry type"); } } #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sam...@us...> - 2009-04-21 00:23:12
|
Revision: 362 http://aceos.svn.sourceforge.net/aceos/?rev=362&view=rev Author: samueldotj Date: 2009-04-21 00:23:08 +0000 (Tue, 21 Apr 2009) Log Message: ----------- Basic ACPI driver. Dilip's Keyboard driver Modified Paths: -------------- scripts/create_bootcd.sh scripts/q.sh src/drivers/pci/pci.c src/drivers/pci/pci.h src/drivers/wscript_build src/include/ds/lrulist.h src/include/kernel/acpi/actypes.h src/include/kernel/acpi/platform/acace.h src/include/kernel/arch.h src/include/kernel/i386/tss.h src/include/kernel/iom/iom.h src/include/version.sh src/kernel/acpi/osacexf.c src/kernel/driver_id.txt src/kernel/i386/arch.c src/kernel/i386/debug/ktrace.c src/kernel/i386/exception.c src/kernel/i386/start.asm src/kernel/i386/tss.c src/kernel/interrupt.c src/kernel/iom/iom.c src/kernel/iom/rootbus.c src/kernel/ktrace.c src/kernel/main.c src/kernel/pm/scheduler.c src/kernel/pm/thread.c wscript Added Paths: ----------- src/drivers/acpi/ src/drivers/acpi/acpi.c src/drivers/acpi/acpi.h src/drivers/ps2keyboard/ src/drivers/ps2keyboard/keyboard.c src/drivers/ps2keyboard/keyboard.h src/include/kernel/module.h Modified: scripts/create_bootcd.sh =================================================================== --- scripts/create_bootcd.sh 2009-04-08 13:46:15 UTC (rev 361) +++ scripts/create_bootcd.sh 2009-04-21 00:23:08 UTC (rev 362) @@ -18,6 +18,8 @@ cp $ACE_ROOT/src/kernel/driver_id.txt $BUILD_DIR/bootfs cp $BUILD_DIR/app/hello.exe $BUILD_DIR/bootfs/app cp $BUILD_DIR/drivers/pci_bus.sys $BUILD_DIR/bootfs/drivers +cp $BUILD_DIR/drivers/acpi.sys $BUILD_DIR/bootfs/drivers +cp $BUILD_DIR/drivers/ps2keyboard.sys $BUILD_DIR/bootfs/drivers cd $BUILD_DIR/bootfs tar --gzip -cf $ISO_DIR/boot_modules.mod.gz . Modified: scripts/q.sh =================================================================== --- scripts/q.sh 2009-04-08 13:46:15 UTC (rev 361) +++ scripts/q.sh 2009-04-21 00:23:08 UTC (rev 362) @@ -1,11 +1,14 @@ #! /bin/sh + +QEMU=`which qemu` +SCRIPT_PATH=`dirname $0` + if test -z "$QEMU_BIOS_DIR" then - echo "Set the QEMU_BIOS_DIR environment variable. This variable should point to QEMU bios and video bios directory" - exit + QEMU_BIOS_DIR=`dirname $QEMU` + if [ $OSTYPE = cygwin ] ; then + QEMU_BIOS_DIR=`cygpath -a -w $QEMU_BIOS_DIR` + fi fi -SCRIPT_PATH=`dirname $0` -#create_bootcd.sh qemu -L "$QEMU_BIOS_DIR" -M pc -cdrom $SCRIPT_PATH/../build/bootcd.iso -boot d -m 32 -smp 1 -localtime -no-kqemu $* - Added: src/drivers/acpi/acpi.c =================================================================== --- src/drivers/acpi/acpi.c (rev 0) +++ src/drivers/acpi/acpi.c 2009-04-21 00:23:08 UTC (rev 362) @@ -0,0 +1,137 @@ +/*! + \file drivers/acpi/acpi.c + \brief ACPI driver +*/ +#include <ace.h> +#include <stdlib.h> +#include <string.h> +#include <kernel/io.h> +#include <kernel/debug.h> +#include <kernel/iom/iom.h> +#include <kernel/acpi/acpi.h> +#include "acpi.h" + +static ERROR_CODE MajorFunctionPnp(DEVICE_OBJECT_PTR pDeviceObject, IRP_PTR pIrp); +static ERROR_CODE AddDevice(DRIVER_OBJECT_PTR pDriverObject, DEVICE_OBJECT_PTR pPdo); + +/*Entry point - called during driver initialization*/ +ERROR_CODE DriverEntry(DRIVER_OBJECT_PTR pDriverObject) +{ + strcpy( pDriverObject->driver_name, "ACPI" ); + pDriverObject->driver_extension = NULL; + pDriverObject->fn.AddDevice = AddDevice; + pDriverObject->fn.MajorFunctions[IRP_MJ_PNP] = MajorFunctionPnp; + + return ERROR_SUCCESS; +} +static ERROR_CODE AddDevice(DRIVER_OBJECT_PTR pDriverObject, DEVICE_OBJECT_PTR pPdo) +{ + DEVICE_OBJECT_PTR device_object; + ERROR_CODE err; + err = CreateDevice(pDriverObject, sizeof(ACPI_BUS_DEVICE_EXTENSION), &device_object); + if( err != ERROR_SUCCESS ) + return err; + InvalidateDeviceRelations(device_object, DEVICE_RELATIONS_TYPE_BUS_RELATION); + + return ERROR_SUCCESS; +} +ACPI_STATUS AcpiGetDeviceCallback(ACPI_HANDLE ObjHandle, UINT32 NestingLevel, void *Context, void **ReturnValue) +{ + ACPI_BUFFER buf; + char name[ACPI_DEVICE_NAME_MAX]; + ACPI_DEVICE_CALLBACK_ARGUMENT_PTR arg; + + buf.Pointer = name; + buf.Length = sizeof(name); + + arg = (ACPI_DEVICE_CALLBACK_ARGUMENT_PTR) Context; + if ( AcpiGetName(ObjHandle, ACPI_FULL_PATHNAME, &buf) == AE_OK ) + { + DEVICE_OBJECT_PTR child_device_object; + if ( CreateDevice(arg->device_object->driver_object, sizeof(ACPI_BUS_DEVICE_EXTENSION), &child_device_object) == ERROR_SUCCESS ) + { + ACPI_BUS_DEVICE_EXTENSION_PTR device_ext=child_device_object->device_extension; + device_ext->handle = ObjHandle; + memcpy(device_ext->device_name, buf.Pointer, ACPI_DEVICE_NAME_MAX ); + AttachDeviceToDeviceStack(child_device_object, arg->device_object); + arg->total_devices_found ++; + } + } + + return AE_OK; +} +static ERROR_CODE MajorFunctionPnp(DEVICE_OBJECT_PTR pDeviceObject, IRP_PTR pIrp) +{ + ACPI_BUS_DEVICE_EXTENSION_PTR acpi_dev_ext=NULL; + IO_STACK_LOCATION_PTR io_stack = GetCurrentIrpStackLocation(pIrp); + void * return_value; + + pIrp->io_status.status = ERROR_NOT_SUPPORTED; + pIrp->io_status.information = NULL; + switch( io_stack->minor_function ) + { + case IRP_MN_QUERY_DEVICE_RELATIONS: + if ( io_stack->parameters.query_device_relations.type == DEVICE_RELATIONS_TYPE_BUS_RELATION ) + { + int i=0; + DEVICE_RELATIONS_PTR dr; + ACPI_DEVICE_CALLBACK_ARGUMENT arg; + + arg.total_devices_found = 0; + arg.device_object = pDeviceObject; + + AcpiGetDevices(NULL, AcpiGetDeviceCallback, &arg, &return_value); + /*put the new device relations list*/ + if ( arg.total_devices_found > 0 ) + { + LIST_PTR cur_node; + /*allocate memory for device relation struction*/ + dr = kmalloc( SIZEOF_DEVICE_RELATIONS(arg.total_devices_found), 0 ); + if ( dr == NULL ) + { + pIrp->io_status.status = ERROR_NOT_ENOUGH_MEMORY; + return ERROR_NOT_ENOUGH_MEMORY; + } + dr->count = arg.total_devices_found; + assert( pDeviceObject->driver_object->device_object_head ); + dr->objects[0] = pDeviceObject->driver_object->device_object_head; + i=0; + LIST_FOR_EACH(cur_node, &pDeviceObject->driver_object->device_object_head->device_object_list ) + { + dr->objects[i] = STRUCT_ADDRESS_FROM_MEMBER(cur_node, DEVICE_OBJECT, device_object_list); + i++; + } + + /*return success*/ + pIrp->io_status.information = dr; + pIrp->io_status.status = ERROR_SUCCESS; + return ERROR_SUCCESS; + } + } + + break; + case IRP_MN_QUERY_ID: + acpi_dev_ext = (ACPI_BUS_DEVICE_EXTENSION_PTR)pDeviceObject->device_extension; + assert( acpi_dev_ext != NULL ); + if ( io_stack->parameters.query_id.id_type == BUS_QUERY_DEVICE_ID ) + { + pIrp->io_status.information = kmalloc( DRIVER_NAME_MAX, 0 ); + if ( pIrp->io_status.information == NULL ) + { + pIrp->io_status.status = ERROR_NOT_ENOUGH_MEMORY; + return ERROR_NOT_ENOUGH_MEMORY; + } + sprintf(pIrp->io_status.information, "ACPI/%s", &acpi_dev_ext->device_name[1]); + pIrp->io_status.status = ERROR_SUCCESS; + } + else if ( io_stack->parameters.query_id.id_type == BUS_QUERY_INSTANCE_ID ) + { + pIrp->io_status.information = NULL; + pIrp->io_status.status = ERROR_SUCCESS; + } + else + return ERROR_NOT_SUPPORTED; + break; + } + return ERROR_SUCCESS; +} Added: src/drivers/acpi/acpi.h =================================================================== --- src/drivers/acpi/acpi.h (rev 0) +++ src/drivers/acpi/acpi.h 2009-04-21 00:23:08 UTC (rev 362) @@ -0,0 +1,28 @@ +/*! + \file drivers/acpi.h + \brief ACPI related structures and functions +*/ + +#ifndef _ACPI_H +#define _ACPI_H + +#define ACPI_DEVICE_NAME_MAX 50 + +/*! ACPI device extension*/ +struct acpi_bus_device_extension +{ + ACPI_HANDLE handle; /*! ACPI Handle of an object*/ + char device_name[ACPI_DEVICE_NAME_MAX]; /*! full path of an acpi object*/ + int pnp_id; +}; +typedef struct acpi_bus_device_extension ACPI_BUS_DEVICE_EXTENSION, * ACPI_BUS_DEVICE_EXTENSION_PTR; + +/*! argument to AcpiGetDeviceCallback function*/ +struct acpi_device_callback_argument +{ + DEVICE_OBJECT_PTR device_object; /*! ACPI bus device object*/ + int total_devices_found; /*! output - total devices found */ +}; +typedef struct acpi_device_callback_argument ACPI_DEVICE_CALLBACK_ARGUMENT, * ACPI_DEVICE_CALLBACK_ARGUMENT_PTR; + +#endif Modified: src/drivers/pci/pci.c =================================================================== --- src/drivers/pci/pci.c 2009-04-08 13:46:15 UTC (rev 361) +++ src/drivers/pci/pci.c 2009-04-21 00:23:08 UTC (rev 362) @@ -8,6 +8,7 @@ #include <kernel/io.h> #include <kernel/debug.h> #include <kernel/iom/iom.h> +#include <kernel/acpi/acpi.h> #include "pci.h" @@ -144,6 +145,7 @@ } } } + /*put the new device relations list*/ if ( total_devices_found > 0 ) { @@ -161,10 +163,9 @@ i=0; LIST_FOR_EACH(cur_node, &pDeviceObject->driver_object->device_object_head->device_object_list ) { - dr->objects[i] = STRUCT_ADDRESS_FROM_MEMBER(cur_node, DEVICE_OBJECT, device_object_list); - i++; - if ( i>=total_devices_found ) - assert( i<=total_devices_found ); + assert( i<=total_devices_found ); + dr->objects[i] = STRUCT_ADDRESS_FROM_MEMBER(cur_node, DEVICE_OBJECT, device_object_list); + i++; } /*return success*/ @@ -185,7 +186,7 @@ pIrp->io_status.status = ERROR_NOT_ENOUGH_MEMORY; return ERROR_NOT_ENOUGH_MEMORY; } - sprintf(pIrp->io_status.information, "PCI_VEN_%d&DEV_%d&SUBSYS_%d&REV_%d", + sprintf(pIrp->io_status.information, "PCI_VEN_%x&DEV_%x&SUBSYS_%d&REV_%d", pci_dev_ext->pci_conf.vendor_id, pci_dev_ext->pci_conf.device_id, pci_dev_ext->pci_conf.pci_standard.sub_system_device_id, pci_dev_ext->pci_conf.revision_id); pIrp->io_status.status = ERROR_SUCCESS; } @@ -196,6 +197,7 @@ } else return ERROR_NOT_SUPPORTED; + break; } return ERROR_SUCCESS; Modified: src/drivers/pci/pci.h =================================================================== --- src/drivers/pci/pci.h 2009-04-08 13:46:15 UTC (rev 361) +++ src/drivers/pci/pci.h 2009-04-21 00:23:08 UTC (rev 362) @@ -1,8 +1,11 @@ /*! - \file drivers/pci.h + \file drivers/pci/pci.h \brief PCI bus related structures */ +#ifndef _PCI_H +#define _PCI_H + #include <ace.h> typedef struct pci_control_register PCI_CONTROL_REGISTER, * PCI_CONTROL_REGISTER_PTR; @@ -129,3 +132,5 @@ }; int get_pci_class_string(BYTE class_code, BYTE subclass_code, BYTE prog_if_code, char ** class_name, char ** subclass_name, char ** prog_if_name ); + +#endif Added: src/drivers/ps2keyboard/keyboard.c =================================================================== --- src/drivers/ps2keyboard/keyboard.c (rev 0) +++ src/drivers/ps2keyboard/keyboard.c 2009-04-21 00:23:08 UTC (rev 362) @@ -0,0 +1,406 @@ +/*! + \file drivers/keyboard.c + \brief PS/2 keyboard driver for 101-key keyboard +*/ +#include <ace.h> +#include <string.h> +#include <kernel/io.h> +#include <kernel/error.h> +#include <kernel/iom/iom.h> +#include <kernel/interrupt.h> +#include <kernel/printf.h> +#include "keyboard.h" + +/* www.microsoft.com/whdc/archive/scancode.mspx + * http://www.osdever.net/bkerndev/Docs/keyboard.htm + */ +/* This is a scancode table used to layout a standard US keyboard. + * Index with a scan code to get the corresponding ascii value. + * First column contains ascii values or key codes WITHOUT SHIFT key pressed and 2nd column is with SHIFT key pressed. + */ +unsigned char scancode_to_ascii[][2] = +{ + {0, 0}, + {27, 27}, /* Escape */ + {'1', '!'}, + {'2', '@'}, + {'3', '#'}, + {'4', '$'}, + {'5', '%'}, + {'6', '^'}, + {'7', '&'}, + {'8', '*'}, + {'9', '('}, + {'0', ')'}, + {'-', '_'}, + {'=', '+'}, + {'\b', '\b'}, /* Backspace */ + {'\t', '\t'}, /* Tab */ + {'q', 'Q'}, + {'w', 'W'}, + {'e', 'E'}, + {'r', 'R'}, /* 19 */ + {'t', 'T'}, + {'y', 'Y'}, + {'u', 'U'}, + {'i', 'I'}, + {'o', 'O'}, + {'p', 'P'}, + {'[', '{'}, + {']', '}'}, + {'\n', '\n'}, /* Enter 1c*/ + {KEYCODE_LEFT_CTRL, 0}, /* 1d Left ctrl*/ + {'a', 'A'}, + {'s', 'S'}, + {'d', 'D'}, + {'f', 'F'}, + {'g', 'G'}, + {'h', 'H'}, + {'j', 'J'}, + {'k', 'K'}, + {'l', 'L'}, + {';', ':'}, /* 0x27 */ + {'\'','"'}, + {'`', '~'}, /*0x29 is available on US kbd and undefined on international keyboard */ + {KEYCODE_LEFT_SHIFT, 0}, /* Left shift */ + {'\\', '|'}, /* 0x2b not available on US kbd */ + {'z', 'Z'}, + {'x', 'X'}, + {'c', 'C'}, + {'v', 'V'}, + {'b', 'B'}, + {'n', 'N'}, /* 0x31 */ + {'m', 'M'}, + {',', '<'}, + {'.', '>'}, + {'/', '?'}, + {KEYCODE_RIGHT_SHIFT, 0}, /* Right shift */ + {'*', '*'}, /* 0x37 Numeric * */ + {KEYCODE_LEFT_ALT, 0}, /* Left Alt */ + {' ', ' '}, /* Space bar */ + {KEYCODE_CAPS_LOCK, 0}, /* 0x3A Caps lock */ + {KEYCODE_F1, 0}, /* 0x3B - F1 key ... > */ + {KEYCODE_F2, 0}, + {KEYCODE_F3, 0}, + {KEYCODE_F4, 0}, + {KEYCODE_F5, 0}, + {KEYCODE_F6, 0}, + {KEYCODE_F7, 0}, + {KEYCODE_F8, 0}, + {KEYCODE_F9, 0}, + {KEYCODE_F10, 0}, /* < 0x44 F10 */ + {KEYCODE_NUM_LOCK, 0}, /* 0x45 Num lock*/ + {KEYCODE_SCROLL_LOCK, 0}, /* Scroll Lock */ + {KEYCODE_NUMERIC_HOME, '7'}, /* 0x47 Numeric 7 */ + {KEYCODE_NUMERIC_UP_ARROW, '8'}, /* Numeric 8 */ + {KEYCODE_NUMERIC_PAGEUP, '9'}, /* Numeric 9 */ + {'-', '-'}, /* Numeric - */ + {KEYCODE_NUMERIC_LEFT_ARROW, '4'}, /* Numeric 4 */ + {0, '5'}, /* Numeric 5 */ + {KEYCODE_NUMERIC_RIGHT_ARROW, '6'}, /* 0x4D Numeric 6 */ + {'+', '+'}, /* Numeric + */ + {KEYCODE_NUMERIC_END, '1'}, /* Numeric 1 */ + {KEYCODE_NUMERIC_DOWN_ARROW, '2'}, /* 0x50 Numeric 2 */ + {KEYCODE_NUMERIC_PAGEDOWN, '3'}, /* Numeric 3 */ + {KEYCODE_NUMERIC_INSERT, '0'}, /* Numeric 0 */ + {127, '.'} /* 0x53 Numeric DELETE, Numeric . Take care of special case: numlock_DEL, there will be no modifier key for this*/ +}; + +/*! + * \brief Entry point - called during driver initialization + * \param drv_obj Driver object pointer which should be initialised + * Returns standard error code. + */ +ERROR_CODE DriverEntry(DRIVER_OBJECT_PTR drv_obj) +{ + strcpy( drv_obj->driver_name, "Keyboard" ); + drv_obj->driver_extension = NULL; + drv_obj->fn.AddDevice = AddDevice; + drv_obj->fn.MajorFunctions[IRP_MJ_READ] = MajorFunctionRead; + drv_obj->fn.MajorFunctions[IRP_MJ_PNP] = MajorFunctionPnP; + drv_obj->fn.MajorFunctions[IRP_MJ_FLUSH_BUFFERS] = MajorFunctionFlush; + + /* Register keyboard interrupt handler */ + InstallInterruptHandler( KEYBOARD_INTERRUPT_NUMBER, KeyboardInterruptHandler, 0); + return ERROR_SUCCESS; +} + +/*! + * \brief Adds a new device to the device hierarchy and binds the device with the given driver. + * \param drv_obj Driver object to which the new device must be associated. + * \param parent_dev_obj Device object's parent pointer. + * Returns a standard error code + */ +static ERROR_CODE AddDevice(DRIVER_OBJECT_PTR drv_obj, DEVICE_OBJECT_PTR parent_dev_obj) +{ + DEVICE_OBJECT_PTR dev_obj; + ERROR_CODE err; + + err = CreateDevice(drv_obj, 0, &dev_obj); + if( err != ERROR_SUCCESS ) + return err; + + /* Now establish the hierarchy between parent_dev_obj and dev_obj */ + (void)AttachDeviceToDeviceStack(dev_obj, parent_dev_obj); + + return ERROR_SUCCESS; +} + +/*! + * \brief Function to handle all Plug and play activities associated with keyboard. + * \param dev_obj Device for which request is made. + * \param irp Interrupt request packet pointer containing user request details + * Returns SUCCESS if request can be processed or else suitable failure code is returned. + */ +static ERROR_CODE MajorFunctionPnP(DEVICE_OBJECT_PTR dev_obj, IRP_PTR irp) +{ + return ERROR_SUCCESS; +} + +/*! + * \brief Function to handle Read activities activities. + * \param dev_obj Device for which request is made. + * \param irp Interrupt request packet pointer containing user request details + * Returns SUCCESS if request can be processed or else suitable failure code is returned. + */ +static ERROR_CODE MajorFunctionRead(DEVICE_OBJECT_PTR dev_obj, IRP_PTR irp) +{ + unsigned char *scancode, *keycode, *ascii; + + irp->io_status.information = kmalloc(sizeof(KEYBOARD_BUFFER), 0); + if ( irp->io_status.information == NULL ) + { + irp->io_status.status = ERROR_NOT_ENOUGH_MEMORY; + return ERROR_NOT_ENOUGH_MEMORY; + } + scancode = irp->io_status.information; + keycode = scancode + MAX_SCANCODE_BYTES; + ascii = keycode + 1; + return ReadFromKeyboardBuffer(&scancode, keycode, ascii); +} + +/*! + * \brief Read a BYTE from keyboard buffer. + * \param ch Pointer to a BYTE at which the read data has to be placed. + * Returns ERROR_READ_FAULT if there is no data available or else returns ERROR_SUCCESS. + */ +static ERROR_CODE ReadFromKeyboardBuffer(unsigned char **scancode, unsigned char *keycode, unsigned char *ascii_value) +{ + int i; + if(cur_kbd_buf_read_index == cur_kbd_buf_write_index) + return ERROR_READ_FAULT; + + *ascii_value = kbd_buf[cur_kbd_buf_read_index].ascii_value; + *keycode = kbd_buf[cur_kbd_buf_read_index].keycode; + for(i=0; i < MAX_SCANCODE_BYTES; i++) + { + *scancode[i] = kbd_buf[cur_kbd_buf_read_index].scancode[i]; + } + cur_kbd_buf_read_index = (cur_kbd_buf_read_index + 1) % MAX_KEYBOARD_BUFFER_SIZE; + + return ERROR_SUCCESS; +} + +/*! + * \brief Writes a BYTE to keyboard buffer. Called from interrupt handler as soon as data is entered on keyboard. + * \param ch BYTE data which has to be written into the keyboard buffer. + */ + +static void WriteToKeyboardBuffer(unsigned char* scancode, unsigned char keycode, unsigned char ascii_value) +{ + int i; + + kbd_buf[cur_kbd_buf_write_index].ascii_value = ascii_value; + kbd_buf[cur_kbd_buf_write_index].keycode = keycode; + for(i=0; i < MAX_SCANCODE_BYTES; i++) + { + kbd_buf[cur_kbd_buf_write_index].scancode[i] = scancode[i]; + } + + cur_kbd_buf_write_index = (cur_kbd_buf_write_index + 1) % MAX_KEYBOARD_BUFFER_SIZE; + + if(cur_kbd_buf_write_index == cur_kbd_buf_read_index) + cur_kbd_buf_read_index = (cur_kbd_buf_read_index + 1) % MAX_KEYBOARD_BUFFER_SIZE; +} + +/*! + * \brief Resets the keyboard buffer by flushing it. This just resets the read and write pointers to the keyboard buffer. + * \param dev_obj Device for which request is made. + * \param irp Interrupt request packet pointer containing user request details + * Returns SUCCESS if request can be processed or else suitable failure code is returned. + */ +static ERROR_CODE MajorFunctionFlush(DEVICE_OBJECT_PTR dev_obj, IRP_PTR irp) +{ + cur_kbd_buf_read_index = cur_kbd_buf_write_index = 0; + return ERROR_SUCCESS; +} + +/*! + * \brief Handles all interrupts from keyboard device. + * \brief interrupt_info Contains details on this interrupt: number, device, priority level + * \brief arg Contains optional arguments. It's NULL for keyboard device. + */ +static ISR_RETURN_CODE KeyboardInterruptHandler(INTERRUPT_INFO_PTR interrupt_info, void * arg) +{ + unsigned char scancode; + unsigned char ascii_value=0; + static BYTE key_e0=0; + static unsigned char scancode_buffer[MAX_SCANCODE_BYTES]; /*Usage of this variable is incomplete. Somebody do it! */ + char keycode; + int col; + static unsigned char modifier_keys=0; /* bit 0=left SHIFT, 1=right SHIFT, 2=left ALT, 3=right ALT, 4=left CTRL, 5=right CTRL, 6=CAPS lock 7=NUM lock*/ +#define LEFT_SHIFT_BIT 1 +#define RIGHT_SHIFT_BIT 2 +#define LEFT_ALT_BIT 4 +#define RIGHT_ALT_BIT 8 +#define LEFT_CTRL_BIT 16 +#define RIGHT_CTRL_BIT 32 +#define CAPS_LOCK_BIT 64 +#define NUM_LOCK_BIT 128 + + scancode = _inp(KEYBOARD_CONTROLLER_DATA_PORT); + kprintf("scancode %x received from keyboard\n", scancode); + + if(scancode == 0xE0) + { + key_e0 = 1; + return ISR_END_PROCESSING; + } + + if(key_e0 == 1) + { + key_e0 = 0; + /* These scancodes have special meaning, so do not search in scancode_to_ascii table + * This list is not exhaustive. Many other cases are ignored. Ex: LEFT_SHIFT + RIGHT_SHIFT + INSERT = 2A, 36, E0AA EOB6 E052 + * In that case, one has to record what was the previous action with E0... coz we have now made e0=0. + * If there's anybody without any damn work, then scrath this hard. + */ + switch(scancode) + { + case 0x52: keycode = KEYCODE_INSERT; break; + case 0x53: keycode = modifier_keys; ascii_value = 127; break; + case 0x4B: keycode = KEYCODE_LEFT_ARROW; break; + case 0x47: keycode = KEYCODE_HOME; break; + case 0x4F: keycode = KEYCODE_END; break; + case 0x48: keycode = KEYCODE_UP_ARROW; break; + case 0x50: keycode = KEYCODE_DOWN_ARROW; break; + case 0x49: keycode = KEYCODE_PAGEUP; break; + case 0x51: keycode = KEYCODE_PAGEDOWN; break; + case 0x4D: keycode = KEYCODE_RIGHT_ARROW; break; + case 0x5B: keycode = KEYCODE_LEFT_WIN; break; + case 0x5C: keycode = KEYCODE_RIGHT_WIN; break; + case SCANCODE_ENTER: keycode = modifier_keys; ascii_value = '\n'; break; + case SCANCODE_ALT_PRESS: modifier_keys |= RIGHT_ALT_BIT; goto modifier_keys_only; + case SCANCODE_ALT_RELEASE: modifier_keys &= ~(RIGHT_ALT_BIT); goto modifier_keys_only; + case SCANCODE_CTRL_PRESS: modifier_keys |= RIGHT_CTRL_BIT; goto modifier_keys_only; + case SCANCODE_CTRL_RELEASE: modifier_keys &= ~(RIGHT_CTRL_BIT); goto modifier_keys_only; + default: + /* Unknown key typed.. so skip it */ + return ISR_END_PROCESSING; + } + scancode_buffer[0] = scancode; + scancode_buffer[1] = 0xE0; + if(modifier_keys) + scancode_buffer[2] = modifier_keys; + goto send_buffer; + } + + switch(scancode) + { + case SCANCODE_LEFT_SHIFT_PRESS: modifier_keys |= LEFT_SHIFT_BIT; break; + case SCANCODE_LEFT_SHIFT_RELEASE: modifier_keys &= ~(LEFT_SHIFT_BIT); break; + case SCANCODE_RIGHT_SHIFT_PRESS: modifier_keys |= RIGHT_SHIFT_BIT; break; + case SCANCODE_RIGHT_SHIFT_RELEASE: modifier_keys &= ~(RIGHT_SHIFT_BIT);break; + case SCANCODE_ALT_PRESS: + modifier_keys |= LEFT_ALT_BIT; + break; + case SCANCODE_ALT_RELEASE: + modifier_keys &= ~(LEFT_ALT_BIT); + break; + case SCANCODE_CTRL_PRESS: + modifier_keys |= LEFT_CTRL_BIT; + break; + case SCANCODE_CTRL_RELEASE: + modifier_keys &= ~(LEFT_CTRL_BIT); + break; + case SCANCODE_CAPS_LOCK_PRESS: + if(modifier_keys & CAPS_LOCK_BIT) + modifier_keys &= ~(CAPS_LOCK_BIT); + else + modifier_keys |= CAPS_LOCK_BIT; + break; + + case SCANCODE_CAPS_LOCK_RELEASE: + break; + + case SCANCODE_NUM_LOCK_PRESS: + if(modifier_keys & NUM_LOCK_BIT) + modifier_keys &= ~(NUM_LOCK_BIT); + else + modifier_keys |= NUM_LOCK_BIT; + break; + + case SCANCODE_NUM_LOCK_RELEASE: + break; + + default: /* This is not a modifier key, but an ascii key */ + goto find_ascii; + } + +modifier_keys_only: + kprintf("modifier keys stored.. no ascii; modifier_keys=%d\n", modifier_keys); + return ISR_END_PROCESSING; /* Return if scan code is a modifier key */ + +find_ascii: + ascii_value = 0; + keycode = modifier_keys; + + /* Convert scan code to ascii and store it in keyboard buffer. For that select the index(column) into scancode table. */ + if(scancode <= 0x53) + { + if( modifier_keys & LEFT_SHIFT_BIT || (modifier_keys & RIGHT_SHIFT_BIT) ) + { + if (modifier_keys & NUM_LOCK_BIT) + { + if ( scancode==0x37 || (scancode>=0x47 && scancode<=0x53) ) + { + col = 0; + } + else + col = 1; + } + else + col = 1; + } + else + { + if ( (modifier_keys & NUM_LOCK_BIT) && (scancode==0x37 || (scancode>=0x47 && scancode<=0x53) ) ) + col = 1; + else + col = 0; + } + + ascii_value = scancode_to_ascii[scancode][col]; + + if( (modifier_keys & CAPS_LOCK_BIT) && ascii_value >=97 && ascii_value <= 122) /* get the UPPER case */ + { + ascii_value -= 32; + } + else if( (modifier_keys & CAPS_LOCK_BIT) && ascii_value >=65 && ascii_value <= 90) /* get the LOWER case */ + { + ascii_value += 32; + } + + } + else + return ISR_END_PROCESSING; + +send_buffer: +kprintf("writing to buffer\n"); + /* if ascii_value > 127, then user should check for keycode also. That would show that it's one of NUMERIC keys. */ + WriteToKeyboardBuffer(scancode_buffer, keycode, ascii_value); + + kprintf("done: scancode=%s, keycode=%d, ascii_value=%d char=%c\n", scancode_buffer, keycode, ascii_value, ascii_value); + return ISR_END_PROCESSING; +} + Added: src/drivers/ps2keyboard/keyboard.h =================================================================== --- src/drivers/ps2keyboard/keyboard.h (rev 0) +++ src/drivers/ps2keyboard/keyboard.h 2009-04-21 00:23:08 UTC (rev 362) @@ -0,0 +1,112 @@ +/*! + \file drivers/ps2keyboard/keyboard.h + \brief ps2 keyboard structures and function declarations +*/ + +#ifndef _PS2_KEYBOARD_H +#define _PS2_KEYBOARD_H + +#include <ace.h> + +/* If u change this value, the data type of the variables cur_kbd_buf_read_index and cur_kbd_buf_write_index should be suitably modified */ +#define MAX_KEYBOARD_BUFFER_SIZE 256 +#define KEYBOARD_INTERRUPT_NUMBER 1 + +#define KEYBOARD_CONTROLLER_DATA_PORT 0x60 +#define KEYBOARD_CONTROLLER_CONTROL_PORT 0x64 +#define MAX_SCANCODE_BYTES 6 + +typedef struct keyboard_buffer +{ + unsigned char scancode[MAX_SCANCODE_BYTES]; /* Most recent scan code entry will be in 0 */ + unsigned char keycode; + unsigned char ascii_value; +}KEYBOARD_BUFFER, *KEYBOARD_BUFFER_PTR; + +KEYBOARD_BUFFER kbd_buf[MAX_KEYBOARD_BUFFER_SIZE]; + +/* These 2 variables are dependent on the size of the macro MAX_KEYBOARD_BUFFER_SIZE */ +int cur_kbd_buf_read_index=0; +int cur_kbd_buf_write_index=0; + + +static ERROR_CODE AddDevice(DRIVER_OBJECT_PTR drv_obj, DEVICE_OBJECT_PTR parent_dev_obj); +static ERROR_CODE MajorFunctionPnP(DEVICE_OBJECT_PTR dev_obj, IRP_PTR irp); +static ERROR_CODE MajorFunctionRead(DEVICE_OBJECT_PTR dev_obj, IRP_PTR irp); +static ERROR_CODE MajorFunctionFlush(DEVICE_OBJECT_PTR dev_obj, IRP_PTR irp); +static ISR_RETURN_CODE KeyboardInterruptHandler(INTERRUPT_INFO_PTR interrupt_info, void * arg); +static ERROR_CODE ReadFromKeyboardBuffer(unsigned char **scancode, unsigned char *keycode, unsigned char *ascii_value); +static void WriteToKeyboardBuffer(unsigned char* scancode, unsigned char keycode, unsigned char ascii_value); + +#define SCANCODE_LEFT_SHIFT_PRESS 0x2A +#define SCANCODE_LEFT_SHIFT_RELEASE 0xAA + +#define SCANCODE_RIGHT_SHIFT_PRESS 0x36 +#define SCANCODE_RIGHT_SHIFT_RELEASE 0xB6 + +#define SCANCODE_CAPS_LOCK_PRESS 0x3A +#define SCANCODE_CAPS_LOCK_RELEASE 0xBA + +#define SCANCODE_NUM_LOCK_PRESS 0x45 +#define SCANCODE_NUM_LOCK_RELEASE 0xC5 + +#define SCANCODE_ENTER 0x1C + +#define SCANCODE_CTRL_PRESS 0x1D +#define SCANCODE_CTRL_RELEASE 0x9D + +#define SCANCODE_ALT_PRESS 0x38 +#define SCANCODE_ALT_RELEASE 0xB8 + + +enum KEYCODE +{ + /* Keycodes */ + KEYCODE_UP_ARROW = 128, + KEYCODE_DOWN_ARROW, + KEYCODE_LEFT_ARROW, + KEYCODE_RIGHT_ARROW, + KEYCODE_F1, + KEYCODE_F2, + KEYCODE_F3, + KEYCODE_F4, + KEYCODE_F5, + KEYCODE_F6, + KEYCODE_F7, + KEYCODE_F8, + KEYCODE_F9, + KEYCODE_F10, + KEYCODE_F11, + KEYCODE_F12, + KEYCODE_PAUSE_BREAK, + KEYCODE_WIN_START, + KEYCODE_INSERT, + KEYCODE_HOME, + KEYCODE_PAGEUP, + KEYCODE_END, + KEYCODE_PAGEDOWN, + KEYCODE_NUM_LOCK, + KEYCODE_SCROLL_LOCK, + KEYCODE_CAPS_LOCK, + KEYCODE_LEFT_SHIFT, + KEYCODE_RIGHT_SHIFT, + KEYCODE_LEFT_ALT, + KEYCODE_RIGHT_ALT, + KEYCODE_LEFT_CTRL, + KEYCODE_RIGHT_CTRL, + KEYCODE_SYSRQ, + KEYCODE_LEFT_WIN, + KEYCODE_RIGHT_WIN, + KEYCODE_NUMERIC_HOME, + KEYCODE_NUMERIC_UP_ARROW, + KEYCODE_NUMERIC_PAGEUP, + KEYCODE_NUMERIC_LEFT_ARROW, + KEYCODE_NUMERIC_RIGHT_ARROW, + KEYCODE_NUMERIC_END, + KEYCODE_NUMERIC_DOWN_ARROW, + KEYCODE_NUMERIC_PAGEDOWN, + KEYCODE_NUMERIC_INSERT, + KEYCODE_NUMERIC_DELETE //172 +}; + +#endif Modified: src/drivers/wscript_build =================================================================== --- src/drivers/wscript_build 2009-04-08 13:46:15 UTC (rev 361) +++ src/drivers/wscript_build 2009-04-21 00:23:08 UTC (rev 362) @@ -4,6 +4,16 @@ include_dirs = '../include/' #build pci driver -pci = bld.new_task_gen('cc', 'program', target='pci_bus', name='pci', install_path=None, includes=include_dirs, uselib='DRIVER' ) -pci.env['program_PATTERN'] = '%s.sys' -pci.find_sources_in_dirs('pci') +pci_bus = bld.new_task_gen('cc', 'program', target='pci_bus', name='pci_bus', install_path=None, includes=include_dirs, uselib='DRIVER' ) +pci_bus.env['program_PATTERN'] = '%s.sys' +pci_bus.find_sources_in_dirs('pci') + +#build acpi driver +acpi_bus = bld.new_task_gen('cc', 'program', target='acpi', name='acpi_bus', install_path=None, includes=include_dirs, uselib='DRIVER' ) +acpi_bus.env['program_PATTERN'] = '%s.sys' +acpi_bus.find_sources_in_dirs('acpi') + +#build keyboard driver +ps2keyboard = bld.new_task_gen('cc', 'program', target='ps2keyboard', name='ps2keyboard', install_path=None, includes=include_dirs, uselib='DRIVER' ) +ps2keyboard.env['program_PATTERN'] = '%s.sys' +ps2keyboard.find_sources_in_dirs('ps2keyboard') Modified: src/include/ds/lrulist.h =================================================================== --- src/include/ds/lrulist.h 2009-04-08 13:46:15 UTC (rev 361) +++ src/include/ds/lrulist.h 2009-04-21 00:23:08 UTC (rev 362) @@ -40,87 +40,3 @@ #endif #endif -/*! - \file ds/lrulist.h - \brief Least recently used list -*/ - -#ifndef LRU_LIST__H -#define LRU_LIST__H - -#include <stdlib.h> -#include <assert.h> -#include <ds/list.h> -#include <sync/spinlock.h> - -/*! least recently used list*/ -typedef struct lru_list -{ - SPIN_LOCK lock; /*! lock for current_count and list_head*/ - - long maximum_count; /*! maximum nodes allowed*/ - long current_count; /*! current number of nodes in the list*/ - - LIST_PTR (*AllocateNode)(); /*! function pointer to allocate a new node*/ - void (*ReuseNode)(LIST_PTR node);/*! function pointer to reuse a node*/ - void (*FreeNode)(LIST_PTR node); /*! function pointer to free a node*/ - - LIST_PTR list_head; /*! Pointer to starting of the list(most recent)*/ -}LRU_LIST, * LRU_LIST_PTR; - -#ifdef __cplusplus - extern "C" { -#endif - -void InitLruList(LRU_LIST_PTR lru, long maximum_count, LIST_PTR (*AllocateNode)(), void (*ReuseNode)(LIST_PTR node), void (*FreeNode)(LIST_PTR node)); -LIST_PTR AllocateLruNode(LRU_LIST_PTR lru); -void FreeLruNode(LRU_LIST_PTR lru, LIST_PTR node); -void ReferenceLruNode(LRU_LIST_PTR lru, LIST_PTR node); - -#ifdef __cplusplus - } -#endif - -#endif -/*! - \file ds/lrulist.h - \brief Least recently used list -*/ - -#ifndef LRU_LIST__H -#define LRU_LIST__H - -#include <stdlib.h> -#include <assert.h> -#include <ds/list.h> -#include <sync/spinlock.h> - -/*! least recently used list*/ -typedef struct lru_list -{ - SPIN_LOCK lock; /*! lock for current_count and list_head*/ - - long maximum_count; /*! maximum nodes allowed*/ - long current_count; /*! current number of nodes in the list*/ - - LIST_PTR (*AllocateNode)(); /*! function pointer to allocate a new node*/ - void (*ReuseNode)(LIST_PTR node);/*! function pointer to reuse a node*/ - void (*FreeNode)(LIST_PTR node); /*! function pointer to free a node*/ - - LIST_PTR list_head; /*! Pointer to starting of the list(most recent)*/ -}LRU_LIST, * LRU_LIST_PTR; - -#ifdef __cplusplus - extern "C" { -#endif - -void InitLruList(LRU_LIST_PTR lru, long maximum_count, LIST_PTR (*AllocateNode)(), void (*ReuseNode)(LIST_PTR node), void (*FreeNode)(LIST_PTR node)); -LIST_PTR AllocateLruNode(LRU_LIST_PTR lru); -void FreeLruNode(LRU_LIST_PTR lru, LIST_PTR node); -void ReferenceLruNode(LRU_LIST_PTR lru, LIST_PTR node); - -#ifdef __cplusplus - } -#endif - -#endif Modified: src/include/kernel/acpi/actypes.h =================================================================== --- src/include/kernel/acpi/actypes.h 2009-04-08 13:46:15 UTC (rev 361) +++ src/include/kernel/acpi/actypes.h 2009-04-21 00:23:08 UTC (rev 362) @@ -117,6 +117,8 @@ #ifndef __ACTYPES_H__ #define __ACTYPES_H__ +#include <kernel/module.h> + /* acpisrc:StructDefs -- for acpisrc conversion */ /* @@ -344,7 +346,7 @@ * tagged with this macro which can be defined as appropriate for the host. */ #ifndef ACPI_EXPORT_SYMBOL -#define ACPI_EXPORT_SYMBOL(Symbol) +#define ACPI_EXPORT_SYMBOL(Symbol) EXPORT_SYMBOL(Symbol); #endif Modified: src/include/kernel/acpi/platform/acace.h =================================================================== --- src/include/kernel/acpi/platform/acace.h 2009-04-08 13:46:15 UTC (rev 361) +++ src/include/kernel/acpi/platform/acace.h 2009-04-21 00:23:08 UTC (rev 362) @@ -126,8 +126,10 @@ #define ACPI_DEBUG #endif -//#define ACPI_NO_ERROR_MESSAGES +//#define ACPI_DEBUG_OUTPUT +#define ACPI_NO_ERROR_MESSAGES + #ifdef _KERNEL_ #include <ace.h> Modified: src/include/kernel/arch.h =================================================================== --- src/include/kernel/arch.h 2009-04-08 13:46:15 UTC (rev 361) +++ src/include/kernel/arch.h 2009-04-21 00:23:08 UTC (rev 362) @@ -36,6 +36,7 @@ void FlushCpuCache(BOOLEAN write_back); void ArchHalt(); +void ArchShutdown(); void MaskInterrupt(BYTE interrupt_number); Modified: src/include/kernel/i386/tss.h =================================================================== --- src/include/kernel/i386/tss.h 2009-04-08 13:46:15 UTC (rev 361) +++ src/include/kernel/i386/tss.h 2009-04-21 00:23:08 UTC (rev 362) @@ -67,6 +67,6 @@ typedef volatile struct tss TSS, * TSS_PTR; void LoadTss(); -void FillTssForDoubleFaultHandler( void * fault_handler, UINT32 kernel_stack ); +void FillTssForDoubleFaultHandler(void * fault_handler); #endif Modified: src/include/kernel/iom/iom.h =================================================================== --- src/include/kernel/iom/iom.h 2009-04-08 13:46:15 UTC (rev 361) +++ src/include/kernel/iom/iom.h 2009-04-21 00:23:08 UTC (rev 362) @@ -12,6 +12,7 @@ #include <heap/slab_allocator.h> #include <kernel/error.h> #include <kernel/mm/kmem.h> +#include <kernel/vfs/vfs.h> #define DRIVER_NAME_MAX 50 @@ -104,7 +105,7 @@ DEVICE_OBJECT_PTR device_object_head; /*! Head to list of devices this driver handles*/ char driver_name[DRIVER_NAME_MAX]; /*! Human readable name of the driver*/ - char * driver_file_name; /*! File name of the driver - used to find whether a driver is already loaded - once file system is done it should be removed*/ + char driver_file_name[MAX_FILE_NAME]; /*! File name of the driver - used to find whether a driver is already loaded*/ void * driver_extension; /*! Driver specific data*/ DRIVER_FUNCTIONS fn; /*! All the functions supported by the driver*/ Added: src/include/kernel/module.h =================================================================== --- src/include/kernel/module.h (rev 0) +++ src/include/kernel/module.h 2009-04-21 00:23:08 UTC (rev 362) @@ -0,0 +1,17 @@ +#ifndef __MODULE_H +#define __MODULE_H + +struct kernel_symbol +{ + long symbol; + char * name; +}; + +#define __EXPORT_SYMBOL(sym, sec) \ + static const char __kstrtab_##sym[] __attribute__((section(".ksymtab_strings"))) = "";\ + static const struct kernel_symbol __ksymtab_##sym __attribute__((section(".ksymtab" sec), unused)) = { (long)(&sym), (char *)__kstrtab_##sym } + +#define EXPORT_SYMBOL(sym) \ + __EXPORT_SYMBOL(sym, "") + +#endif Modified: src/include/version.sh =================================================================== --- src/include/version.sh 2009-04-08 13:46:15 UTC (rev 361) +++ src/include/version.sh 2009-04-21 00:23:08 UTC (rev 362) @@ -10,10 +10,18 @@ #add one new line to avoid gcc warning message echo "" >> tmp1 -#copy the file only if it is different -cmp tmp1 $1/build.h > tmp -if [ $? -ne 0 ] +if [ -e $1/build.h ] then + #copy the file only if it is different + cmp tmp1 $1/build.h > tmp + if [ $? -ne 0 ] + then + mv tmp1 $1/build.h + fi +else + #just create the file mv tmp1 $1/build.h fi -rm -f tmp tmp1 \ No newline at end of file + +#remove backup files +rm -f tmp tmp1 Modified: src/kernel/acpi/osacexf.c =================================================================== --- src/kernel/acpi/osacexf.c 2009-04-08 13:46:15 UTC (rev 361) +++ src/kernel/acpi/osacexf.c 2009-04-21 00:23:08 UTC (rev 362) @@ -4,6 +4,7 @@ #include <stdlib.h> #include <stdarg.h> #include <ace.h> +#include <sync/spinlock.h> #include <kernel/io.h> #include <kernel/interrupt.h> #include <kernel/mm/vm.h> @@ -426,7 +427,8 @@ AcpiOsAllocate ( ACPI_SIZE size) { - return kmalloc(size, 0); + void * ret = kmalloc(size, 0); + return ret; } @@ -521,8 +523,6 @@ UINT32 Units, UINT16 Timeout) { - - return AE_OK; } @@ -545,8 +545,6 @@ ACPI_HANDLE Handle, UINT32 Units) { - - return AE_OK; } @@ -555,15 +553,18 @@ AcpiOsCreateLock ( ACPI_SPINLOCK *OutHandle) { - - return (AcpiOsCreateSemaphore (1, 1, (ACPI_HANDLE)OutHandle)); + SPIN_LOCK_PTR spinlock = kmalloc( sizeof(SPIN_LOCK), 0); + InitSpinLock(spinlock); + + *((SPIN_LOCK_PTR *)OutHandle) = spinlock; + return AE_OK; } void AcpiOsDeleteLock ( ACPI_SPINLOCK Handle) { - AcpiOsDeleteSemaphore (Handle); + kfree(Handle); } @@ -571,7 +572,7 @@ AcpiOsAcquireLock ( ACPI_SPINLOCK Handle) { - AcpiOsWaitSemaphore (Handle, 1, 0xFFFF); + SpinLock(Handle); return (0); } @@ -581,7 +582,7 @@ ACPI_SPINLOCK Handle, ACPI_CPU_FLAGS Flags) { - AcpiOsSignalSemaphore (Handle, 1); + SpinUnlock(Handle); } ISR_RETURN_CODE AcpiInterruptHandler(INTERRUPT_INFO_PTR interrupt_info, void * arg) @@ -1079,3 +1080,4 @@ } + Modified: src/kernel/driver_id.txt =================================================================== --- src/kernel/driver_id.txt 2009-04-08 13:46:15 UTC (rev 361) +++ src/kernel/driver_id.txt 2009-04-21 00:23:08 UTC (rev 362) @@ -1,9 +1,8 @@ #device_id driver_file_name +acpi acpi.sys +ACPI/_SB_.PCI0.ISA_.KBD_ ps2keyboard.sys +ACPI/_SB_.PCI0.ISA_.MOU_ ps2mouse.sys + pci_bus pci_bus.sys -PCI_VEN_32902&DEV_28672&SUBSYS_0&REV_0 piix3_pci_to_isa_bridge.sys -PCI_VEN_32902&DEV_28688&SUBSYS_0&REV_0 piix3_ata_ide.sys -PCI_VEN_32902&DEV_28947&SUBSYS_0&REV_0 piix4_power_man.sys -PCI_VEN_4332&DEV_32809&SUBSYS_0&REV_0 pci_rtl8029.sys -#PCI_VEN_4115&DEV_184&SUBSYS_0&REV_0 cl_gd5446.sys -PCI_VEN_32902&DEV_4663&SUBSYS_0&REV_2 pci_mem.sys \ No newline at end of file +PCI_VEN_10ec&DEV_8029&SUBSYS_0&REV_0 pci_rtl8029.sys Modified: src/kernel/i386/arch.c =================================================================== --- src/kernel/i386/arch.c 2009-04-08 13:46:15 UTC (rev 361) +++ src/kernel/i386/arch.c 2009-04-21 00:23:08 UTC (rev 362) @@ -85,8 +85,7 @@ { CPUID_INFO cpuid; UINT64 start_time; - UINT32 va; - + /*execute cpuid and load the data structure*/ LoadCpuIdInfo( &cpuid ); memcpy( &processor_i386[cpuid.feature._.apic_id].cpuid, &cpuid, sizeof(CPUID_INFO) ); @@ -123,15 +122,8 @@ /* Initialize real time clock*/ InitRtc(); - /*allocate va for double fault handler stack*/ - if ( AllocateVirtualMemory(&kernel_map, &va, 0, PAGE_SIZE, 0, 0, NULL) != ERROR_SUCCESS ) - panic("Unable to allocate memory for double fault handler stack"); - /*Create va to pa mapping*/ - ((UINT32*)va)[0]=0; - /*! \todo - remove the virtual page from pager*/ - /*setup double fault handler tss and gdt entries*/ - FillTssForDoubleFaultHandler(DoubleFaultHandler, va); + FillTssForDoubleFaultHandler(DoubleFaultHandler); /* Load TSS so that we can switch to user mode*/ LoadTss(); @@ -182,6 +174,8 @@ StartTimer(SCHEDULER_DEFAULT_QUANTUM, TRUE); kprintf("Secondary CPU %d is started\n", processor_id); + + ExitThread(); } /*! Create a thread with appropriate real mode code to start a secondary CPU \return Physical address of the stack of the thread. This stack contains real mode code to start. @@ -206,7 +200,7 @@ if ( CreatePhysicalMapping(kernel_map.physical_map, va+(i*PAGE_SIZE), VP_TO_PHYS(vp+i), 0) != ERROR_SUCCESS ) panic("VA to PA mapping failed\n"); } - + /*copy the 16 bit real mode code to the kernel stack page*/ memcpy( &((THREAD_CONTAINER_PTR)va)->kernel_stack, (void *)&trampoline_data, ((UINT32)&trampoline_end)-((UINT32)&trampoline_data)); @@ -356,11 +350,17 @@ } } -/*! This function should halt the processor after terminating all the processes -\todo implementation needed -*/ +/*! Halt the processor until external interrupt comes*/ void ArchHalt() { + //asm("hlt"); +} + +/*! Take the cpu to offline + \todo implementation needed using acpi +*/ +void ArchShutdown() +{ asm("cli;hlt"); } Modified: src/kernel/i386/debug/ktrace.c =================================================================== --- src/kernel/i386/debug/ktrace.c 2009-04-08 13:46:15 UTC (rev 361) +++ src/kernel/i386/debug/ktrace.c 2009-04-21 00:23:08 UTC (rev 362) @@ -73,12 +73,13 @@ for(frame = 0; frame<max_frames; ++frame) { - unsigned int * arguments, eip = ebp[1]; + unsigned int * arguments, eip; int offset; char * func; - if( ebp[0] < PAGE_SIZE || eip < PAGE_SIZE) + if( (UINT32)ebp < PAGE_SIZE || ebp[0] < PAGE_SIZE || ebp[1] < PAGE_SIZE) return; + eip = ebp[1]; /* Unwind to previous stack frame*/ ebp = (unsigned int *)(ebp[0]); arguments = &ebp[2]; Modified: src/kernel/i386/exception.c =================================================================== --- src/kernel/i386/exception.c 2009-04-08 13:46:15 UTC (rev 361) +++ src/kernel/i386/exception.c 2009-04-21 00:23:08 UTC (rev 362) @@ -12,6 +12,9 @@ #include <kernel/error.h> #include <kernel/pm/elf.h> +/*max depth of page faults inside page fault*/ +#define MAX_SERIAL_PAGE_FAULTS 2 + /* This is a simple string array. It contains the message that corresponds to each and every exception. * We get the correct message by accessing like: exception_message[interrupt_number] */ @@ -76,7 +79,7 @@ /*now print some useful info from regs structure for debugging*/ PRINT_REGS( reg ); kprintf("System Halted!\n"); - ArchHalt(); + ArchShutdown(); } /*! i386 specific page fault handler*/ @@ -85,7 +88,9 @@ PF_ERROR_CODE err; static int inside_page_fault; err.all = reg->error_code; - if ( inside_page_fault ) + + /*page fault can happen while handling a page fault but not more than MAX_SERIAL_PAGE_FAULTS*/ + if ( inside_page_fault > MAX_SERIAL_PAGE_FAULTS ) { PRINT_REGS(reg); panic("Inside page fault"); @@ -105,7 +110,7 @@ PRINT_REGS(reg); panic("Page fault not handled."); - ArchHalt(); + ArchShutdown(); } inside_page_fault--; } @@ -123,7 +128,7 @@ err.segment_selector_index); PRINT_REGS(reg); - ArchHalt(); + ArchShutdown(); } /*! Double fault handler Modified: src/kernel/i386/start.asm =================================================================== --- src/kernel/i386/start.asm 2009-04-08 13:46:15 UTC (rev 361) +++ src/kernel/i386/start.asm 2009-04-21 00:23:08 UTC (rev 362) @@ -81,9 +81,10 @@ call cmain - ;endless loop should not be reached. - jmp $ - + ;should not be reached. +.3: + hlt + jmp .3 ;this function is called by secondary CPUs while starting SecondaryCPUEntry: @@ -116,8 +117,10 @@ call SecondaryCpuStart - ;endless loop should not be reached. - jmp $ + ;should not be reached. +.3: + hlt + jmp .3 [SECTION .bootdata] align PAGE_SIZE Modified: src/kernel/i386/tss.c =================================================================== --- src/kernel/i386/tss.c 2009-04-08 13:46:15 UTC (rev 361) +++ src/kernel/i386/tss.c 2009-04-21 00:23:08 UTC (rev 362) @@ -7,6 +7,7 @@ #include <kernel/debug.h> #include <kernel/mm/vm.h> #include <kernel/mm/pmem.h> +#include <kernel/mm/virtual_page.h> #include <kernel/i386/pmem.h> #include <kernel/i386/gdt.h> #include <kernel/i386/processor.h> @@ -66,9 +67,23 @@ } /*! Setup task gate for double fault handler - \param kernel_stack - kernel stack to be used by double fault + \param fault_handler - double fault handler va */ -void FillTssForDoubleFaultHandler(void * fault_handler, UINT32 kernel_stack ) +void FillTssForDoubleFaultHandler(void * fault_handler) { - FillTss( &double_fault_tss, DOUBLE_FAULT_GDT_INDEX, (UINT32)fault_handler, kernel_stack); + UINT32 va=0, pa=0; + + /*allocate va for double fault handler stack*/ + if ( AllocateVirtualMemory(&kernel_map, &va, 0, PAGE_SIZE, 0, 0, NULL) != ERROR_SUCCESS ) + panic("Unable to allocate memory for double fault handler stack"); + + /*Create va to pa mapping*/ + ((UINT32*)va)[0]=0; + if ( TranslatePaFromVa( (VADDR)va, &pa ) == VA_NOT_EXISTS ) + panic( "Mapping not exist for double fault hanlder" ); + + /*Remove the page from pager*/ + LockVirtualPages( PHYS_TO_VP(pa), 1); + + FillTss( &double_fault_tss, DOUBLE_FAULT_GDT_INDEX, (UINT32)fault_handler, va); } Modified: src/kernel/interrupt.c =================================================================== --- src/kernel/interrupt.c 2009-04-08 13:46:15 UTC (rev 361) +++ src/kernel/interrupt.c 2009-04-21 00:23:08 UTC (rev 362) @@ -72,7 +72,6 @@ handler = &interrupt_handlers[reg->int_no]; interrupt_info.interrupt_number = reg->int_no; /*TODO add code to include other interrupt details also*/ - if ( handler->isr == NULL ) { #ifdef DEBUG_INTERRUPT Modified: src/kernel/iom/iom.c =================================================================== --- src/kernel/iom/iom.c 2009-04-08 13:46:15 UTC (rev 361) +++ src/kernel/iom/iom.c 2009-04-21 00:23:08 UTC (rev 362) @@ -101,7 +101,7 @@ void InitIoManager() { DRIVER_OBJECT_PTR root_bus; - + if( InitCache(&driver_object_cache, sizeof(DRIVER_OBJECT), DRIVER_OBJECT_CACHE_FREE_SLABS_THRESHOLD, DRIVER_OBJECT_CACHE_MIN_BUFFERS, DRIVER_OBJECT_CACHE_MAX_SLABS, DriverObjectCacheConstructor, DriverObjectCacheDestructor) ) panic("InitIoManager - Driver object cache init failed"); @@ -113,17 +113,17 @@ /*load root bus driver and call the DriverEntry*/ root_bus = LoadRootBusDriver() ; - RootBusDriverEntry( root_bus ); /*this is the first driver loaded into the kernel and it is never unloaded*/ driver_list_head = &root_bus->driver_list; - + + RootBusDriverEntry( root_bus ); + /*create device object for root bus*/ CreateDevice(root_bus_driver_object, 0, &root_bus_device_object); /*force the io manager to enumerate the buses on root bus*/ InvalidateDeviceRelations(root_bus_device_object, DEVICE_RELATIONS_TYPE_BUS_RELATION); - } /*! Dummy Major function handler - used to initialize driver object function pointers @@ -353,16 +353,25 @@ LIST_PTR node; err = FindDriverFile(device_id, driver_file_name, sizeof(driver_file_name)); - ktrace("Driver for id %s : %s\n", device_id, driver_file_name); - if ( err != ERROR_SUCCESS ) + ktrace("Driver for id %s : ", device_id); + if ( err == ERROR_SUCCESS ) + ktrace("%s\n", driver_file_name); + else + { + ktrace("%s\n", ERROR_CODE_AS_STRING(err) ); return NULL; + } /*check whether the driver is already loaded*/ LIST_FOR_EACH(node, driver_list_head) { driver_object = STRUCT_ADDRESS_FROM_MEMBER( node, DRIVER_OBJECT, driver_list ); if ( strcmp( driver_file_name, driver_object->driver_file_name )==0 ) + { + ktrace("Driver already loaded %s\n", driver_object->driver_file_name); return driver_object; + } + } strcat( driver_file_path, driver_file_name ); kprintf("Loading %s: ", driver_file_path); @@ -386,14 +395,14 @@ err = ERROR_NOT_ENOUGH_MEMORY; goto error; } - - driver_object->driver_file_name = driver_file_name; + + strcpy( driver_object->driver_file_name, driver_file_name); err = DriverEntry( driver_object ); if ( err != ERROR_SUCCESS ) goto error; /*add the driver to the driver list*/ - AddToListTail( driver_list_head, &driver_object->driver_list ); + AddToList( driver_list_head, &driver_object->driver_list ); kprintf("success\n"); return driver_object; Modified: src/kernel/iom/rootbus.c =================================================================== --- src/kernel/iom/rootbus.c 2009-04-08 13:46:15 UTC (rev 361) +++ src/kernel/iom/rootbus.c 2009-04-21 00:23:08 UTC (rev 362) @@ -5,9 +5,12 @@ #include <ace.h> #include <stdlib.h> #include <string.h> +#include <kernel/debug.h> #include <kernel/iom/iom.h> #define PCI_BUS_NAME "pci_bus" +#define ACPI_BUS_NAME "acpi" + typedef struct rootbus_device_extension { char name[DRIVER_NAME_MAX]; @@ -24,6 +27,7 @@ DRIVER_OBJECT_PTR LoadRootBusDriver() { root_bus_driver_object = AllocateBuffer( &driver_object_cache, CACHE_ALLOC_SLEEP ); + root_bus_driver_object->driver_file_name[0] = 0; return root_bus_driver_object; } @@ -35,9 +39,49 @@ return ERROR_SUCCESS; } +static DEVICE_RELATIONS_PTR CreateRootBusDevices(DEVICE_OBJECT_PTR pDeviceObject) +{ + DEVICE_RELATIONS_PTR dr; + DEVICE_OBJECT_PTR pci_device_object, acpi_device_object; + ROOTBUS_DEVICE_EXTENSION_PTR ext; + ERROR_CODE err; + + /*allocate memory for device relation struction*/ + dr = kmalloc( SIZEOF_DEVICE_RELATIONS(2), 0 ); + if ( dr == NULL ) + panic("Unable to create Root bus devices"); + + /*create device object for acpi bus*/ + err = CreateDevice( pDeviceObject->driver_object, sizeof(ROOTBUS_DEVICE_EXTENSION), &acpi_device_object ); + if ( err != ERROR_SUCCESS ) + panic("Unable to create ACPI bus device"); + + /*put rootbus specific info to device extension structure*/ + ext = (ROOTBUS_DEVICE_EXTENSION_PTR)acpi_device_object->device_extension; + strcpy( ext->name, ACPI_BUS_NAME ); + /*attach the pci device to root bus device io stack*/ + AttachDeviceToDeviceStack(acpi_device_object, pDeviceObject); + + /*create device object for pci bus*/ + err = CreateDevice( pDeviceObject->driver_object, sizeof(ROOTBUS_DEVICE_EXTENSION), &pci_device_object ); + if ( err != ERROR_SUCCESS ) + panic("Unable to create PCI bus device"); + /*put rootbus specific info to device extension structure*/ + ext = (ROOTBUS_DEVICE_EXTENSION_PTR)pci_device_object->device_extension; + strcpy( ext->name, PCI_BUS_NAME ); + /*attach the pci device to root bus device io stack*/ + AttachDeviceToDeviceStack(pci_device_object, pDeviceObject); + + /*put the device object in the device relations structure*/ + dr->count = 2; + dr->objects[0] = acpi_device_object; + dr->objects[1] = pci_device_object; + + return dr; +} static ERROR_CODE MajorFunctionPnp(DEVICE_OBJECT_PTR pDeviceObject, IRP_PTR pIrp) { - ROOTBUS_DEVICE_EXTENSION_PTR pci_bus_do_ext=NULL; + ROOTBUS_DEVICE_EXTENSION_PTR ext=NULL; IO_STACK_LOCATION_PTR io_stack = GetCurrentIrpStackLocation(pIrp); pIrp->io_status.status = ERROR_NOT_SUPPORTED; pIrp->io_status.information = NULL; @@ -48,44 +92,14 @@ { /*create real bus drivers only once(local buses cant be unplugged)*/ if ( pIrp->io_status.information == NULL ) - { - DEVICE_RELATIONS_PTR dr; - DEVICE_OBJECT_PTR pci_bus_do; - ERROR_CODE err; - - /*allocate memory for device relation struction*/ - dr = kmalloc( SIZEOF_DEVICE_RELATIONS(1), 0 ); - if ( dr == NULL ) - { - pIrp->io_status.status = ERROR_NOT_ENOUGH_MEMORY; - return ERROR_NOT_ENOUGH_MEMORY; - } - /*create device object for pci bus*/ - err = CreateDevice( pDeviceObject->driver_object, sizeof(ROOTBUS_DEVICE_EXTENSION), &pci_bus_do ); - if ( err != ERROR_SUCCESS ) - { - kfree( dr ); - pIrp->io_status.status = err; - return err; - } - /*put rootbus specific info to device extension structure*/ - pci_bus_do_ext = (ROOTBUS_DEVICE_EXTENSION_PTR)pci_bus_do->device_extension; - strcpy( pci_bus_do_ext->name, PCI_BUS_NAME ); - /*attach the pci device to root bus device io stack*/ - AttachDeviceToDeviceStack(pci_bus_do, pDeviceObject); - - /*put the device object in the device relations structure*/ - dr->count = 1; - dr->objects[0] = pci_bus_do; - pIrp->io_status.information = dr; - } + pIrp->io_status.information = CreateRootBusDevices(pDeviceObject); pIrp->io_status.status = ERROR_SUCCESS; } else return ERROR_NOT_FOUND; break; case IRP_MN_QUERY_ID: - pci_bus_do_ext = (ROOTBUS_DEVICE_EXTENSION_PTR)pDeviceObject->device_extension; + ext = (ROOTBUS_DEVICE_EXTENSION_PTR)pDeviceObject->device_extension; if ( io_stack->parameters.query_id.id_type == BUS_QUERY_DEVICE_ID ) { pIrp->io_status.information = kmalloc( DRIVER_NAME_MAX, 0 ); @@ -94,7 +108,7 @@ pIrp->io_status.status = ERROR_NOT_ENOUGH_MEMORY; return ERROR_NOT_ENOUGH_MEMORY; } - strcpy( pIrp->io_status.information, pci_bus_do_ext->name); + strcpy( pIrp->io_status.information, ext->name); pIrp->io_status.status = ERROR_SUCCESS; } else if ( io_stack->parameters.query_id.id_type == BUS_QUERY_INSTANCE_ID ) Modified: src/kernel/ktrace.c =================================================================== --- src/kernel/ktrace.c 2009-04-08 13:46:15 UTC (rev 361) +++ src/kernel/ktrace.c 2009-04-21 00:23:08 UTC (rev 362) @@ -27,15 +27,15 @@ void _assert(const char *msg, const char *file, int line) { kprintf("Assertion failed at %s:%d::[%s]\n", file, line, msg); - PrintStackTrace(MAX_STACK_FRAMES); - ArchHalt(); + panic(NULL); } /*! Halts the system after printing the given message */ void panic(char * message) { - kprintf("panic() : %s\n", message); + if( message ) + kprintf("panic() : %s\n", message); PrintStackTrace(MAX_STACK_FRAMES); - ArchHalt(); + ArchShutdown(); } Modified: src/kernel/main.c =================================================================== --- src/kernel/main.c 2009-04-08 13:46:15 UTC (rev 361) +++ src/kernel/main.c 2009-04-21 00:23:08 UTC (rev 362) @@ -16,11 +16,15 @@ #include <kernel/mm/kmem.h> #include <kernel/mm/vm.h> #include <kernel/pm/task.h> +#include <kernel/pm/thread.h> #include <kernel/pm/elf.h> #include <kernel/pm/scheduler.h> #include <kernel/iom/iom.h> #include <kernel/system_call_handler.h> +#include <kernel/module.h> +EXPORT_SYMBOL (AcpiGetName); + /*! ERROR_CODE to string declaration and function defintions*/ AS_STRING_DEC(ERROR_CODE, ENUM_LIST_ERROR_CODE) AS_STRING_FUNC(ERROR_CODE, ENUM_LIST_ERROR_CODE) @@ -52,7 +56,7 @@ /* Read ACPI tables and enable ACPI mode*/ if ( InitACPI() != 0 ) panic("ACPI Initialization failed.\n"); - + /* Initialize architecture depend parts*/ InitArchPhase2(mbi); @@ -88,5 +92,7 @@ CreateTask("/boot/app/hello.exe"); - kprintf("Kernel initialization complete\n"); + kprintf("Kernel initialization complete\n"); + + ExitThread(); } Modified: src/kernel/pm/scheduler.c =================================================================== --- src/kernel/pm/scheduler.c 2009-04-08 13:46:15 UTC (rev 361) +++ src/kernel/pm/scheduler.c 2009-04-21 00:23:08 UTC (rev 362) @@ -273,7 +273,7 @@ /*! get a thread from this queue to run */ run_thread = pqueue->thread_head; - assert(run_thread != NULL); /*! if bit masks are properly updated, then run_thread should not be null at tis point of time. */ + assert(run_thread != NULL); /*! if bit masks are properly updated, then run_thread should not be null*/ RemoveThreadFromSchedulerQueue(run_thread); return run_thread; @@ -288,6 +288,7 @@ { int loop; int hint=0; /*! processor id of an online processor */ + /*! loop through all the processors and see if any processors are not heavily loaded. */ for(loop=0 ; loop < MAX_PROCESSORS ; loop++) { @@ -385,7 +386,8 @@ if ( in_thread == current_thread ) /**Current thread is terminating/suspending - find another thread to run*/ { new_thread = SelectThreadToRun(current_thread->priority_queue->priority); - assert( new_thread != in_thread); + /*we should have got different thread atleast idle thread*/ + assert( new_thread != in_thread ); PreemptThread(new_thread); /*not reached*/ } @@ -477,6 +479,6 @@ { while(1) { - //kprintf("::Idle Thread::"); + ArchHalt(); } } Modified: src/kernel/pm/thread.c =================================================================== --- src/kernel/pm/thread.c 2009-04-08 13:46:15 UTC (rev 361) +++ src/kernel/pm/thread.c 2009-04-21 00:23:08 UTC (rev 362) @@ -154,6 +154,7 @@ InitSpinLock( &boot_thread->lock ); boot_thread->state = THREAD_STATE_NEW; + boot_thread->reference_count = 1; boot_thread->current_processor = p; boot_thread->bind_cpu = boot_processor_id; Modified: wscript =================================================================== --- wscript 2009-04-08 13:46:15 UTC (rev 361) +++ wscript 2009-04-21 00:23:08 UTC (rev 362) @@ -16,12 +16,12 @@ nasm_flags = defines + ' -w+orphan-labels -f elf' -kernel_c_flags = defines + ' -Wall -Wno-multichar -ffreestanding -funsigned-char -fno-leading-underscore -c -fno-stack-protector' +kernel_c_flags = defines + ' -Wall -Wno-multichar -ffreestanding -funsigned-char -fno-leading-underscore -c -fno-stack-protector ' acpi_c_flags = kernel_c_flags + ' -Wno-format ' driver_c_flags = kernel_c_flags app_c_flags = '-Wall ' -kernel_ld_flags = '--gc-sections -Wl,-Map,kernel.map -T ../src/kernel/kernel.ld -nostdlib -nostartfiles ' +kernel_ld_flags = '-Wl,-Map,kernel.map -T ../src/kernel/kernel.ld -nostdlib -nostartfiles -Wl,--no-gc-sections ' driver_ld_flags = '-r -nostdlib -nostartfiles' app_ld_flags = '-Wall ' This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sam...@us...> - 2009-04-08 13:55:14
|
Revision: 361 http://aceos.svn.sourceforge.net/aceos/?rev=361&view=rev Author: samueldotj Date: 2009-04-08 13:46:15 +0000 (Wed, 08 Apr 2009) Log Message: ----------- Implemented basic VFS support Added Bootfs support Modified IPC - message queues to send/receive 6 arguments Added SHARE and SHARE_PA message types in IPC Added LRU list to ds lib Removed boot_module.c and mkmc tool Modified driver loading functionality. Added ERROR_CODE_AS_STRING() function using enum and macro tricks Added support to print stack trace during panic. Converted all files using dos2unix. Modified Paths: -------------- scripts/create_bootcd.sh src/drivers/pci/pci.c src/drivers/pci/pci.h src/include/ace.h src/include/kernel/arch.h src/include/kernel/error.h src/include/kernel/i386/exception.h src/include/kernel/i386/gdt.h src/include/kernel/i386/i386.inc src/include/kernel/i386/idt.h src/include/kernel/i386/processor.h src/include/kernel/i386/tss.h src/include/kernel/ipc.h src/include/kernel/mm/virtual_page.h src/include/kernel/mm/vm.h src/include/kernel/pm/elf.h src/include/kernel/pm/pid.h src/include/kernel/pm/scheduler.h src/include/kernel/pm/task.h src/include/kernel/pm/thread.h src/include/kernel/pm/timeout_queue.h src/include/kernel/printf.h src/include/kernel/wait_event.h src/include/string.h src/kernel/i386/arch.c src/kernel/i386/debug/ktrace.c src/kernel/i386/debug/parallel.c src/kernel/i386/exception.c src/kernel/i386/idt.c src/kernel/i386/interrupt_stub.asm src/kernel/i386/mm/pmem.c src/kernel/i386/mm/pmem_init.c src/kernel/i386/pm/thread.c src/kernel/i386/tss.c src/kernel/iom/iom.c src/kernel/iom/rootbus.c src/kernel/ipc/message_queue.c src/kernel/kprintf.c src/kernel/ktrace.c src/kernel/main.c src/kernel/mm/kmem.c src/kernel/mm/virtual_page.c src/kernel/mm/vm.c src/kernel/mm/vm_descriptor.c src/kernel/mm/vm_unit.c src/kernel/parameter.c src/kernel/pit/pit.c src/kernel/pm/elf.c src/kernel/pm/pid.c src/kernel/pm/scheduler.c src/kernel/pm/task.c src/kernel/pm/thread.c src/kernel/pm/timeout_queue.c src/kernel/spinlock.c src/kernel/system_calls.c src/kernel/wait_event.c src/kernel/wscript_build src/lib/ds/avl_tree.c src/lib/ds/binary_tree.c src/lib/ds/test/testavl.c src/lib/ds/test/testbits.c src/lib/ds/test/testlist.c src/lib/ds/test/testtree.c src/lib/heap/slab_allocator.c src/lib/heap/test/testcommon.c src/lib/heap/test/testheap.c src/lib/heap/test/testslab.c src/lib/string/string_utils.c src/lib/sync/test/testcommon.c src/lib/sync/test/testspin.c wscript Added Paths: ----------- src/include/ds/lrulist.h src/include/enum.h src/include/kernel/pm/pm_types.h src/include/kernel/vfs/ src/include/kernel/vfs/dir_entry.h src/include/kernel/vfs/ubc.h src/include/kernel/vfs/vfs.h src/include/kernel/vfs/vfs_types.h src/include/kernel/vfs/vnode.h src/include/tar.h src/kernel/driver_id.txt src/kernel/vfs/ src/kernel/vfs/boot_fs.c src/kernel/vfs/dir_entry.c src/kernel/vfs/tar.c src/kernel/vfs/ubc.c src/kernel/vfs/vfs.c src/kernel/vfs/vnode.c src/lib/ds/lrulist.c src/lib/ds/test/testlrulist.c src/wscript Removed Paths: ------------- src/include/kernel/module.h src/kernel/boot_module.c src/tools/ Modified: scripts/create_bootcd.sh =================================================================== --- scripts/create_bootcd.sh 2009-03-17 04:37:24 UTC (rev 360) +++ scripts/create_bootcd.sh 2009-04-08 13:46:15 UTC (rev 361) @@ -3,7 +3,6 @@ BUILD_DIR=$1/src/ ACE_ROOT=$BUILD_DIR/../../../ ISO_DIR=$BUILD_DIR/../../iso -TOOLS_DIR=$BUILD_DIR/../../../toolsbuild/default GRUB_BIN=$ACE_ROOT/boot/grub/ #directory clean up and create if needed @@ -11,10 +10,16 @@ mkdir -p $ISO_DIR mkdir -p $ISO_DIR/boot/grub -#create kernel boot module container -rm -f $ISO_DIR/boot_modules.mod -$TOOLS_DIR/mkmc -o $ISO_DIR/boot_modules.mod $BUILD_DIR/app/hello.exe $BUILD_DIR/drivers/pci_bus.sys -gzip $ISO_DIR/boot_modules.mod +#create boot fs +rm -f $ISO_DIR/boot_modules.mod.gz +rm -rf $BUILD_DIR/bootfs +mkdir -p $BUILD_DIR/bootfs/app +mkdir -p $BUILD_DIR/bootfs/drivers +cp $ACE_ROOT/src/kernel/driver_id.txt $BUILD_DIR/bootfs +cp $BUILD_DIR/app/hello.exe $BUILD_DIR/bootfs/app +cp $BUILD_DIR/drivers/pci_bus.sys $BUILD_DIR/bootfs/drivers +cd $BUILD_DIR/bootfs +tar --gzip -cf $ISO_DIR/boot_modules.mod.gz . #copy grub cp $GRUB_BIN/stage2_eltorito $ISO_DIR/boot/grub Modified: src/drivers/pci/pci.c =================================================================== --- src/drivers/pci/pci.c 2009-03-17 04:37:24 UTC (rev 360) +++ src/drivers/pci/pci.c 2009-04-08 13:46:15 UTC (rev 361) @@ -1,202 +1,202 @@ -/*! - \file drivers/pci/pci.c - \brief PCI bus driver -*/ -#include <ace.h> -#include <stdlib.h> -#include <string.h> -#include <kernel/io.h> -#include <kernel/debug.h> -#include <kernel/iom/iom.h> -#include "pci.h" - - -#define MAX_PCI_BUS 0xFF -#define MAX_PCI_DEVICE_PER_BUS 32 -#define MAX_PCI_FUNCTION_PER_DEVICE 8 - -#if ARCH==i386 - #define PCI_CONFIG_ADDRESS 0xCF8 - #define PCI_CONFIG_DATA 0xCFC -#endif - -typedef struct pci_bus_device_extension PCI_BUS_DEVICE_EXTENSION, * PCI_BUS_DEVICE_EXTENSION_PTR; - -struct pci_bus_device_extension -{ - PCI_CONFIGURATION_SPACE pci_conf; -}; - -static ERROR_CODE MajorFunctionPnp(DEVICE_OBJECT_PTR pDeviceObject, IRP_PTR pIrp); -static ERROR_CODE AddDevice(DRIVER_OBJECT_PTR pDriverObject, DEVICE_OBJECT_PTR pPdo); - -static inline unsigned char pci_read_byte(int bus_no, int device_no, int function_no, int offset) -{ - _outpd(PCI_CONFIG_ADDRESS, ((unsigned long) 0x80000000 | (bus_no << 16) | (device_no << 11) | (function_no << 8) | offset)); - return _inp(PCI_CONFIG_DATA); -} - -static inline unsigned short pci_read_word(int bus_no, int device_no, int function_no, int offset) -{ - _outpd(PCI_CONFIG_ADDRESS, ((unsigned long) 0x80000000 | (bus_no << 16) | (device_no << 11) | (function_no << 8) | offset)); - return _inpw(PCI_CONFIG_DATA); -} - -static inline unsigned long pci_read_dword(int bus_no, int device_no, int function_no, int offset) -{ - _outpd(PCI_CONFIG_ADDRESS, ((unsigned long) 0x80000000 | (bus_no << 16) | (device_no << 11) | (function_no << 8) | offset)); - return _inpd(PCI_CONFIG_DATA); -} - -static inline void pci_write_byte(int bus_no, int device_no, int function_no, int offset, unsigned char value) -{ - _outpd(PCI_CONFIG_ADDRESS, ((unsigned long) 0x80000000 | (bus_no << 16) | (device_no << 11) | (function_no << 8) | offset)); - _outp(PCI_CONFIG_DATA, value); -} - -static inline void pci_write_word(int bus_no, int device_no, int function_no, int offset, unsigned short value) -{ - _outpd(PCI_CONFIG_ADDRESS, ((unsigned long) 0x80000000 | (bus_no << 16) | (device_no << 11) | (function_no << 8) | offset)); - _outpw(PCI_CONFIG_DATA, value); -} - -static inline void pci_write_dword(int bus_no, int device_no, int function_no, int offset, unsigned long value) -{ - _outpd(PCI_CONFIG_ADDRESS, ((unsigned long) 0x80000000 | (bus_no << 16) | (device_no << 11) | (function_no << 8) | offset)); - _outpd(PCI_CONFIG_DATA, value); -} - -/*! Reads configuration space of the specified bus, device and function. - \return 0 - on success and pci_conf will be updated with correct values - \return 1 - on failure and pci_conf is not affected -*/ -static int read_pci_configuration_space(BYTE bus_no, BYTE device_no, BYTE function_no, PCI_CONFIGURATION_SPACE_PTR pci_conf) -{ - int offset; - UINT32 * buffer = (UINT32 *)pci_conf; - buffer[0] = pci_read_dword(bus_no, device_no, function_no, 0); - if ( pci_conf->vendor_id == 0 || pci_conf->vendor_id == 0xFFFF ) - return 1; - - for(offset=1; offset<(sizeof(PCI_CONFIGURATION_SPACE)>>2); offset++ ) - buffer[offset] = pci_read_dword(bus_no, device_no, function_no, offset<<2); - return 0; -} - -/*Entry point - called during driver initialization*/ -ERROR_CODE DriverEntry(DRIVER_OBJECT_PTR pDriverObject) -{ - strcpy( pDriverObject->driver_name, "PCI Bus" ); - pDriverObject->driver_extension = NULL; - pDriverObject->fn.AddDevice = AddDevice; - pDriverObject->fn.MajorFunctions[IRP_MJ_PNP] = MajorFunctionPnp; - - return ERROR_SUCCESS; -} -static ERROR_CODE AddDevice(DRIVER_OBJECT_PTR pDriverObject, DEVICE_OBJECT_PTR pPdo) -{ - DEVICE_OBJECT_PTR device_object; - ERROR_CODE err; - err = CreateDevice(pDriverObject, sizeof(PCI_BUS_DEVICE_EXTENSION), &device_object); - if( err != ERROR_SUCCESS ) - return err; - InvalidateDeviceRelations(device_object, DEVICE_RELATIONS_TYPE_BUS_RELATION); - - return ERROR_SUCCESS; -} -static ERROR_CODE MajorFunctionPnp(DEVICE_OBJECT_PTR pDeviceObject, IRP_PTR pIrp) -{ - int bus_no, device_no, function_no; - PCI_BUS_DEVICE_EXTENSION_PTR pci_dev_ext=NULL; - IO_STACK_LOCATION_PTR io_stack = GetCurrentIrpStackLocation(pIrp); - - pIrp->io_status.status = ERROR_NOT_SUPPORTED; - pIrp->io_status.information = NULL; - switch( io_stack->minor_function ) - { - case IRP_MN_QUERY_DEVICE_RELATIONS: - if ( io_stack->parameters.query_device_relations.type == DEVICE_RELATIONS_TYPE_BUS_RELATION ) - { - int i=0, total_devices_found = 0; - DEVICE_RELATIONS_PTR dr; - /*scan pci bus find all the devices attached*/ - for (bus_no=0; bus_no<MAX_PCI_BUS ; bus_no++) - { - for(device_no=0; device_no<MAX_PCI_DEVICE_PER_BUS; device_no++) - { - for(function_no=0; function_no<MAX_PCI_FUNCTION_PER_DEVICE; function_no++) - { - PCI_CONFIGURATION_SPACE pci_conf; - if ( read_pci_configuration_space(bus_no, device_no, function_no, &pci_conf) == 0) - { - DEVICE_OBJECT_PTR child_device_object; - char *class_name, *subclass_name, *prog_if_name; - get_pci_class_string(pci_conf.base_class_code, pci_conf.sub_class_code, pci_conf.programming_interface, &class_name, &subclass_name, &prog_if_name ); - //kprintf("%x %x %s %s %s\n", pci_conf.vendor_id, pci_conf.device_id, class_name, subclass_name, prog_if_name ); - if ( CreateDevice(pDeviceObject->driver_object, sizeof(PCI_BUS_DEVICE_EXTENSION), &child_device_object) == ERROR_SUCCESS ) - { - PCI_BUS_DEVICE_EXTENSION_PTR device_ext=child_device_object->device_extension; - memcpy(&device_ext->pci_conf, &pci_conf, sizeof(PCI_CONFIGURATION_SPACE) ); - AttachDeviceToDeviceStack(child_device_object, pDeviceObject); - total_devices_found ++; - } - } - } - } - } - /*put the new device relations list*/ - if ( total_devices_found > 0 ) - { - LIST_PTR cur_node; - /*allocate memory for device relation struction*/ - dr = kmalloc( SIZEOF_DEVICE_RELATIONS(total_devices_found), 0 ); - if ( dr == NULL ) - { - pIrp->io_status.status = ERROR_NOT_ENOUGH_MEMORY; - return ERROR_NOT_ENOUGH_MEMORY; - } - dr->count = total_devices_found; - assert( pDeviceObject->driver_object->device_object_head ); - dr->objects[0] = pDeviceObject->driver_object->device_object_head; - i=0; - LIST_FOR_EACH(cur_node, &pDeviceObject->driver_object->device_object_head->device_object_list ) - { - dr->objects[i] = STRUCT_ADDRESS_FROM_MEMBER(cur_node, DEVICE_OBJECT, device_object_list); - i++; - if ( i>=total_devices_found ) - assert( i<=total_devices_found ); - } - - /*return success*/ - pIrp->io_status.information = dr; - pIrp->io_status.status = ERROR_SUCCESS; - return ERROR_SUCCESS; - } - } - - break; - case IRP_MN_QUERY_ID: - pci_dev_ext = (PCI_BUS_DEVICE_EXTENSION_PTR)pDeviceObject->device_extension; - if ( io_stack->parameters.query_id.id_type == BUS_QUERY_DEVICE_ID ) - { - pIrp->io_status.information = kmalloc( DRIVER_NAME_MAX, 0 ); - if ( pIrp->io_status.information == NULL ) - { - pIrp->io_status.status = ERROR_NOT_ENOUGH_MEMORY; - return ERROR_NOT_ENOUGH_MEMORY; - } - sprintf(pIrp->io_status.information, "PCI_VEN_%d&DEV_%d&SUBSYS_%d&REV_%d", - pci_dev_ext->pci_conf.vendor_id, pci_dev_ext->pci_conf.device_id, pci_dev_ext->pci_conf.pci_standard.sub_system_device_id, pci_dev_ext->pci_conf.revision_id); - pIrp->io_status.status = ERROR_SUCCESS; - } - else if ( io_stack->parameters.query_id.id_type == BUS_QUERY_INSTANCE_ID ) - { - pIrp->io_status.information = NULL; - pIrp->io_status.status = ERROR_SUCCESS; - } - else - return ERROR_NOT_SUPPORTED; - break; - } - return ERROR_SUCCESS; -} +/*! + \file drivers/pci/pci.c + \brief PCI bus driver +*/ +#include <ace.h> +#include <stdlib.h> +#include <string.h> +#include <kernel/io.h> +#include <kernel/debug.h> +#include <kernel/iom/iom.h> +#include "pci.h" + + +#define MAX_PCI_BUS 0xFF +#define MAX_PCI_DEVICE_PER_BUS 32 +#define MAX_PCI_FUNCTION_PER_DEVICE 8 + +#if ARCH==i386 + #define PCI_CONFIG_ADDRESS 0xCF8 + #define PCI_CONFIG_DATA 0xCFC +#endif + +typedef struct pci_bus_device_extension PCI_BUS_DEVICE_EXTENSION, * PCI_BUS_DEVICE_EXTENSION_PTR; + +struct pci_bus_device_extension +{ + PCI_CONFIGURATION_SPACE pci_conf; +}; + +static ERROR_CODE MajorFunctionPnp(DEVICE_OBJECT_PTR pDeviceObject, IRP_PTR pIrp); +static ERROR_CODE AddDevice(DRIVER_OBJECT_PTR pDriverObject, DEVICE_OBJECT_PTR pPdo); + +static inline unsigned char pci_read_byte(int bus_no, int device_no, int function_no, int offset) +{ + _outpd(PCI_CONFIG_ADDRESS, ((unsigned long) 0x80000000 | (bus_no << 16) | (device_no << 11) | (function_no << 8) | offset)); + return _inp(PCI_CONFIG_DATA); +} + +static inline unsigned short pci_read_word(int bus_no, int device_no, int function_no, int offset) +{ + _outpd(PCI_CONFIG_ADDRESS, ((unsigned long) 0x80000000 | (bus_no << 16) | (device_no << 11) | (function_no << 8) | offset)); + return _inpw(PCI_CONFIG_DATA); +} + +static inline unsigned long pci_read_dword(int bus_no, int device_no, int function_no, int offset) +{ + _outpd(PCI_CONFIG_ADDRESS, ((unsigned long) 0x80000000 | (bus_no << 16) | (device_no << 11) | (function_no << 8) | offset)); + return _inpd(PCI_CONFIG_DATA); +} + +static inline void pci_write_byte(int bus_no, int device_no, int function_no, int offset, unsigned char value) +{ + _outpd(PCI_CONFIG_ADDRESS, ((unsigned long) 0x80000000 | (bus_no << 16) | (device_no << 11) | (function_no << 8) | offset)); + _outp(PCI_CONFIG_DATA, value); +} + +static inline void pci_write_word(int bus_no, int device_no, int function_no, int offset, unsigned short value) +{ + _outpd(PCI_CONFIG_ADDRESS, ((unsigned long) 0x80000000 | (bus_no << 16) | (device_no << 11) | (function_no << 8) | offset)); + _outpw(PCI_CONFIG_DATA, value); +} + +static inline void pci_write_dword(int bus_no, int device_no, int function_no, int offset, unsigned long value) +{ + _outpd(PCI_CONFIG_ADDRESS, ((unsigned long) 0x80000000 | (bus_no << 16) | (device_no << 11) | (function_no << 8) | offset)); + _outpd(PCI_CONFIG_DATA, value); +} + +/*! Reads configuration space of the specified bus, device and function. + \return 0 - on success and pci_conf will be updated with correct values + \return 1 - on failure and pci_conf is not affected +*/ +static int read_pci_configuration_space(BYTE bus_no, BYTE device_no, BYTE function_no, PCI_CONFIGURATION_SPACE_PTR pci_conf) +{ + int offset; + UINT32 * buffer = (UINT32 *)pci_conf; + buffer[0] = pci_read_dword(bus_no, device_no, function_no, 0); + if ( pci_conf->vendor_id == 0 || pci_conf->vendor_id == 0xFFFF ) + return 1; + + for(offset=1; offset<(sizeof(PCI_CONFIGURATION_SPACE)>>2); offset++ ) + buffer[offset] = pci_read_dword(bus_no, device_no, function_no, offset<<2); + return 0; +} + +/*Entry point - called during driver initialization*/ +ERROR_CODE DriverEntry(DRIVER_OBJECT_PTR pDriverObject) +{ + strcpy( pDriverObject->driver_name, "PCI Bus" ); + pDriverObject->driver_extension = NULL; + pDriverObject->fn.AddDevice = AddDevice; + pDriverObject->fn.MajorFunctions[IRP_MJ_PNP] = MajorFunctionPnp; + + return ERROR_SUCCESS; +} +static ERROR_CODE AddDevice(DRIVER_OBJECT_PTR pDriverObject, DEVICE_OBJECT_PTR pPdo) +{ + DEVICE_OBJECT_PTR device_object; + ERROR_CODE err; + err = CreateDevice(pDriverObject, sizeof(PCI_BUS_DEVICE_EXTENSION), &device_object); + if( err != ERROR_SUCCESS ) + return err; + InvalidateDeviceRelations(device_object, DEVICE_RELATIONS_TYPE_BUS_RELATION); + + return ERROR_SUCCESS; +} +static ERROR_CODE MajorFunctionPnp(DEVICE_OBJECT_PTR pDeviceObject, IRP_PTR pIrp) +{ + int bus_no, device_no, function_no; + PCI_BUS_DEVICE_EXTENSION_PTR pci_dev_ext=NULL; + IO_STACK_LOCATION_PTR io_stack = GetCurrentIrpStackLocation(pIrp); + + pIrp->io_status.status = ERROR_NOT_SUPPORTED; + pIrp->io_status.information = NULL; + switch( io_stack->minor_function ) + { + case IRP_MN_QUERY_DEVICE_RELATIONS: + if ( io_stack->parameters.query_device_relations.type == DEVICE_RELATIONS_TYPE_BUS_RELATION ) + { + int i=0, total_devices_found = 0; + DEVICE_RELATIONS_PTR dr; + /*scan pci bus find all the devices attached*/ + for (bus_no=0; bus_no<MAX_PCI_BUS ; bus_no++) + { + for(device_no=0; device_no<MAX_PCI_DEVICE_PER_BUS; device_no++) + { + for(function_no=0; function_no<MAX_PCI_FUNCTION_PER_DEVICE; function_no++) + { + PCI_CONFIGURATION_SPACE pci_conf; + if ( read_pci_configuration_space(bus_no, device_no, function_no, &pci_conf) == 0) + { + DEVICE_OBJECT_PTR child_device_object; + char *class_name, *subclass_name, *prog_if_name; + get_pci_class_string(pci_conf.base_class_code, pci_conf.sub_class_code, pci_conf.programming_interface, &class_name, &subclass_name, &prog_if_name ); + //kprintf("%x %x %s %s %s\n", pci_conf.vendor_id, pci_conf.device_id, class_name, subclass_name, prog_if_name ); + if ( CreateDevice(pDeviceObject->driver_object, sizeof(PCI_BUS_DEVICE_EXTENSION), &child_device_object) == ERROR_SUCCESS ) + { + PCI_BUS_DEVICE_EXTENSION_PTR device_ext=child_device_object->device_extension; + memcpy(&device_ext->pci_conf, &pci_conf, sizeof(PCI_CONFIGURATION_SPACE) ); + AttachDeviceToDeviceStack(child_device_object, pDeviceObject); + total_devices_found ++; + } + } + } + } + } + /*put the new device relations list*/ + if ( total_devices_found > 0 ) + { + LIST_PTR cur_node; + /*allocate memory for device relation struction*/ + dr = kmalloc( SIZEOF_DEVICE_RELATIONS(total_devices_found), 0 ); + if ( dr == NULL ) + { + pIrp->io_status.status = ERROR_NOT_ENOUGH_MEMORY; + return ERROR_NOT_ENOUGH_MEMORY; + } + dr->count = total_devices_found; + assert( pDeviceObject->driver_object->device_object_head ); + dr->objects[0] = pDeviceObject->driver_object->device_object_head; + i=0; + LIST_FOR_EACH(cur_node, &pDeviceObject->driver_object->device_object_head->device_object_list ) + { + dr->objects[i] = STRUCT_ADDRESS_FROM_MEMBER(cur_node, DEVICE_OBJECT, device_object_list); + i++; + if ( i>=total_devices_found ) + assert( i<=total_devices_found ); + } + + /*return success*/ + pIrp->io_status.information = dr; + pIrp->io_status.status = ERROR_SUCCESS; + return ERROR_SUCCESS; + } + } + + break; + case IRP_MN_QUERY_ID: + pci_dev_ext = (PCI_BUS_DEVICE_EXTENSION_PTR)pDeviceObject->device_extension; + if ( io_stack->parameters.query_id.id_type == BUS_QUERY_DEVICE_ID ) + { + pIrp->io_status.information = kmalloc( DRIVER_NAME_MAX, 0 ); + if ( pIrp->io_status.information == NULL ) + { + pIrp->io_status.status = ERROR_NOT_ENOUGH_MEMORY; + return ERROR_NOT_ENOUGH_MEMORY; + } + sprintf(pIrp->io_status.information, "PCI_VEN_%d&DEV_%d&SUBSYS_%d&REV_%d", + pci_dev_ext->pci_conf.vendor_id, pci_dev_ext->pci_conf.device_id, pci_dev_ext->pci_conf.pci_standard.sub_system_device_id, pci_dev_ext->pci_conf.revision_id); + pIrp->io_status.status = ERROR_SUCCESS; + } + else if ( io_stack->parameters.query_id.id_type == BUS_QUERY_INSTANCE_ID ) + { + pIrp->io_status.information = NULL; + pIrp->io_status.status = ERROR_SUCCESS; + } + else + return ERROR_NOT_SUPPORTED; + break; + } + return ERROR_SUCCESS; +} Modified: src/drivers/pci/pci.h =================================================================== --- src/drivers/pci/pci.h 2009-03-17 04:37:24 UTC (rev 360) +++ src/drivers/pci/pci.h 2009-04-08 13:46:15 UTC (rev 361) @@ -1,131 +1,131 @@ -/*! - \file drivers/pci.h - \brief PCI bus related structures -*/ - -#include <ace.h> - -typedef struct pci_control_register PCI_CONTROL_REGISTER, * PCI_CONTROL_REGISTER_PTR; -typedef struct pci_standard PCI_STANDARD, * PCI_STANDARD_PTR; -typedef struct pci_configuration_space PCI_CONFIGURATION_SPACE, * PCI_CONFIGURATION_SPACE_PTR; -typedef struct pci_status_register PCI_STATUS_REGISTER, * PCI_STATUS_REGISTER_PTR; -typedef struct pci_bist PCI_BIST, * PCI_BIST_PTR; -typedef struct pci_base_address_register PCI_BASE_ADDRESS_REGISTER, * PCI_BASE_ADDRESS_REGISTER_PTR; - -/*! pci device command register format*/ -struct pci_control_register -{ - union - { - UINT16 - enable_io_space:1, - enable_memory_space:1, - enable_master_bus:1, - enable_special_cycles:1, - enable_memory_write_and_invalidate:1, - enable_vga_pallete_snoop:1, - enable_parity_error:1, - reserved1:1, - serr:1, - enable_fast_back_to_back:1, - enable_interrupt:1; - UINT16 - all; - }; -}; - -/*! pci device status register format*/ -struct pci_status_register -{ - union - { - UINT16 - reserved1:3, - interrupt_status:1, - capability_list:1, - capable_of_66mhz:1, - reserved2:1, - fast_back_to_back:1, - parity_error:1, - devsel_timing:2, - signaled_target_abort:1, - received_target_abort:1, - received_master_abort:1, - signaled_system_error:1, - detected_parity_error:1; - UINT16 - all; - - }; -}; -/*Built-in Self Test layout*/ -struct pci_bist -{ - BYTE completion_code:4, - reserved:2, - start_bist:1, - bist_capable:1; -}; - -struct pci_base_address_register -{ - union - { - struct - { - UINT32 io_space:1, - type:2, /* 0-32 bit , 2-64bit*/ - prefetchable:1, - base_address:28; - }memory; - struct - { - UINT32 io_space:1, - reserved:1, - base_address:30; - }io; - }; -}; - -/*standard pci bus*/ -struct pci_standard -{ - PCI_BASE_ADDRESS_REGISTER base_address[6]; - UINT32 card_bus_cis; - UINT16 sub_system_vendor_id; - UINT16 sub_system_device_id; - UINT32 expansion_rom_base; - BYTE reserved1; - UINT16 reserved2; - BYTE capability_pointer; - UINT32 reserved3; - BYTE max_lat; - BYTE min_gnt; - BYTE interrupt_pin; - BYTE interrupt_line; - UINT32 device_specific[48]; -}; - -/*! PCI Configuration Space*/ -struct pci_configuration_space -{ - UINT16 vendor_id; /*! manufacturer of the device*/ - UINT16 device_id; /*! This field identifies the particular device.*/ - PCI_CONTROL_REGISTER control_register; /*! control register*/ - PCI_STATUS_REGISTER status_register; /*! Status register*/ - BYTE revision_id; /*! This register specifies a device specific revision identifier*/ - BYTE programming_interface; /*! class code - programming interface*/ - BYTE sub_class_code; /*! class code - sub class*/ - BYTE base_class_code; /*! class code - base class*/ - BYTE cache_line_size; - BYTE latency; - BYTE header_type:7, /*! 0-Standard, 1-PCI Bridge, 2-Cardbus*/ - multifuction_device:1; /*! if set multi function device else single function*/ - PCI_BIST bist; /*! built-in self test*/ - union - { - PCI_STANDARD pci_standard; - }; -}; - -int get_pci_class_string(BYTE class_code, BYTE subclass_code, BYTE prog_if_code, char ** class_name, char ** subclass_name, char ** prog_if_name ); +/*! + \file drivers/pci.h + \brief PCI bus related structures +*/ + +#include <ace.h> + +typedef struct pci_control_register PCI_CONTROL_REGISTER, * PCI_CONTROL_REGISTER_PTR; +typedef struct pci_standard PCI_STANDARD, * PCI_STANDARD_PTR; +typedef struct pci_configuration_space PCI_CONFIGURATION_SPACE, * PCI_CONFIGURATION_SPACE_PTR; +typedef struct pci_status_register PCI_STATUS_REGISTER, * PCI_STATUS_REGISTER_PTR; +typedef struct pci_bist PCI_BIST, * PCI_BIST_PTR; +typedef struct pci_base_address_register PCI_BASE_ADDRESS_REGISTER, * PCI_BASE_ADDRESS_REGISTER_PTR; + +/*! pci device command register format*/ +struct pci_control_register +{ + union + { + UINT16 + enable_io_space:1, + enable_memory_space:1, + enable_master_bus:1, + enable_special_cycles:1, + enable_memory_write_and_invalidate:1, + enable_vga_pallete_snoop:1, + enable_parity_error:1, + reserved1:1, + serr:1, + enable_fast_back_to_back:1, + enable_interrupt:1; + UINT16 + all; + }; +}; + +/*! pci device status register format*/ +struct pci_status_register +{ + union + { + UINT16 + reserved1:3, + interrupt_status:1, + capability_list:1, + capable_of_66mhz:1, + reserved2:1, + fast_back_to_back:1, + parity_error:1, + devsel_timing:2, + signaled_target_abort:1, + received_target_abort:1, + received_master_abort:1, + signaled_system_error:1, + detected_parity_error:1; + UINT16 + all; + + }; +}; +/*Built-in Self Test layout*/ +struct pci_bist +{ + BYTE completion_code:4, + reserved:2, + start_bist:1, + bist_capable:1; +}; + +struct pci_base_address_register +{ + union + { + struct + { + UINT32 io_space:1, + type:2, /* 0-32 bit , 2-64bit*/ + prefetchable:1, + base_address:28; + }memory; + struct + { + UINT32 io_space:1, + reserved:1, + base_address:30; + }io; + }; +}; + +/*standard pci bus*/ +struct pci_standard +{ + PCI_BASE_ADDRESS_REGISTER base_address[6]; + UINT32 card_bus_cis; + UINT16 sub_system_vendor_id; + UINT16 sub_system_device_id; + UINT32 expansion_rom_base; + BYTE reserved1; + UINT16 reserved2; + BYTE capability_pointer; + UINT32 reserved3; + BYTE max_lat; + BYTE min_gnt; + BYTE interrupt_pin; + BYTE interrupt_line; + UINT32 device_specific[48]; +}; + +/*! PCI Configuration Space*/ +struct pci_configuration_space +{ + UINT16 vendor_id; /*! manufacturer of the device*/ + UINT16 device_id; /*! This field identifies the particular device.*/ + PCI_CONTROL_REGISTER control_register; /*! control register*/ + PCI_STATUS_REGISTER status_register; /*! Status register*/ + BYTE revision_id; /*! This register specifies a device specific revision identifier*/ + BYTE programming_interface; /*! class code - programming interface*/ + BYTE sub_class_code; /*! class code - sub class*/ + BYTE base_class_code; /*! class code - base class*/ + BYTE cache_line_size; + BYTE latency; + BYTE header_type:7, /*! 0-Standard, 1-PCI Bridge, 2-Cardbus*/ + multifuction_device:1; /*! if set multi function device else single function*/ + PCI_BIST bist; /*! built-in self test*/ + union + { + PCI_STANDARD pci_standard; + }; +}; + +int get_pci_class_string(BYTE class_code, BYTE subclass_code, BYTE prog_if_code, char ** class_name, char ** subclass_name, char ** prog_if_name ); Modified: src/include/ace.h =================================================================== --- src/include/ace.h 2009-03-17 04:37:24 UTC (rev 360) +++ src/include/ace.h 2009-04-08 13:46:15 UTC (rev 361) @@ -15,22 +15,24 @@ #define FALSE 0 #define TRUE 1 -typedef char CHAR; -typedef signed char INT8; -typedef unsigned char BYTE; -typedef unsigned char UINT8; -typedef BYTE BOOLEAN; +#if ARCH == i386 + typedef char CHAR; + typedef signed char INT8; + typedef unsigned char BYTE; + typedef unsigned char UINT8; + typedef BYTE BOOLEAN; -typedef short INT16; -typedef unsigned short UINT16; + typedef short INT16; + typedef unsigned short UINT16; -typedef long INT32; -typedef unsigned long UINT32; + typedef long INT32; + typedef unsigned long UINT32; -typedef long long INT64; -typedef unsigned long long UINT64; + typedef long long INT64; + typedef unsigned long long UINT64; + + typedef unsigned long WORD; -#if ARCH == i386 typedef UINT32 VADDR; #define BITS_PER_BYTE (8) #define BITS_PER_LONG (32) @@ -56,3 +58,4 @@ #endif + Added: src/include/ds/lrulist.h =================================================================== --- src/include/ds/lrulist.h (rev 0) +++ src/include/ds/lrulist.h 2009-04-08 13:46:15 UTC (rev 361) @@ -0,0 +1,126 @@ +/*! + \file ds/lrulist.h + \brief Least recently used list +*/ + +#ifndef LRU_LIST__H +#define LRU_LIST__H + +#include <stdlib.h> +#include <assert.h> +#include <ds/list.h> +#include <sync/spinlock.h> + +/*! least recently used list*/ +typedef struct lru_list +{ + SPIN_LOCK lock; /*! lock for current_count and list_head*/ + + long maximum_count; /*! maximum nodes allowed*/ + long current_count; /*! current number of nodes in the list*/ + + LIST_PTR (*AllocateNode)(); /*! function pointer to allocate a new node*/ + void (*ReuseNode)(LIST_PTR node);/*! function pointer to reuse a node*/ + void (*FreeNode)(LIST_PTR node); /*! function pointer to free a node*/ + + LIST_PTR list_head; /*! Pointer to starting of the list(most recent)*/ +}LRU_LIST, * LRU_LIST_PTR; + +#ifdef __cplusplus + extern "C" { +#endif + +void InitLruList(LRU_LIST_PTR lru, long maximum_count, LIST_PTR (*AllocateNode)(), void (*ReuseNode)(LIST_PTR node), void (*FreeNode)(LIST_PTR node)); +LIST_PTR AllocateLruNode(LRU_LIST_PTR lru); +void FreeLruNode(LRU_LIST_PTR lru, LIST_PTR node); +void ReferenceLruNode(LRU_LIST_PTR lru, LIST_PTR node); + +#ifdef __cplusplus + } +#endif + +#endif +/*! + \file ds/lrulist.h + \brief Least recently used list +*/ + +#ifndef LRU_LIST__H +#define LRU_LIST__H + +#include <stdlib.h> +#include <assert.h> +#include <ds/list.h> +#include <sync/spinlock.h> + +/*! least recently used list*/ +typedef struct lru_list +{ + SPIN_LOCK lock; /*! lock for current_count and list_head*/ + + long maximum_count; /*! maximum nodes allowed*/ + long current_count; /*! current number of nodes in the list*/ + + LIST_PTR (*AllocateNode)(); /*! function pointer to allocate a new node*/ + void (*ReuseNode)(LIST_PTR node);/*! function pointer to reuse a node*/ + void (*FreeNode)(LIST_PTR node); /*! function pointer to free a node*/ + + LIST_PTR list_head; /*! Pointer to starting of the list(most recent)*/ +}LRU_LIST, * LRU_LIST_PTR; + +#ifdef __cplusplus + extern "C" { +#endif + +void InitLruList(LRU_LIST_PTR lru, long maximum_count, LIST_PTR (*AllocateNode)(), void (*ReuseNode)(LIST_PTR node), void (*FreeNode)(LIST_PTR node)); +LIST_PTR AllocateLruNode(LRU_LIST_PTR lru); +void FreeLruNode(LRU_LIST_PTR lru, LIST_PTR node); +void ReferenceLruNode(LRU_LIST_PTR lru, LIST_PTR node); + +#ifdef __cplusplus + } +#endif + +#endif +/*! + \file ds/lrulist.h + \brief Least recently used list +*/ + +#ifndef LRU_LIST__H +#define LRU_LIST__H + +#include <stdlib.h> +#include <assert.h> +#include <ds/list.h> +#include <sync/spinlock.h> + +/*! least recently used list*/ +typedef struct lru_list +{ + SPIN_LOCK lock; /*! lock for current_count and list_head*/ + + long maximum_count; /*! maximum nodes allowed*/ + long current_count; /*! current number of nodes in the list*/ + + LIST_PTR (*AllocateNode)(); /*! function pointer to allocate a new node*/ + void (*ReuseNode)(LIST_PTR node);/*! function pointer to reuse a node*/ + void (*FreeNode)(LIST_PTR node); /*! function pointer to free a node*/ + + LIST_PTR list_head; /*! Pointer to starting of the list(most recent)*/ +}LRU_LIST, * LRU_LIST_PTR; + +#ifdef __cplusplus + extern "C" { +#endif + +void InitLruList(LRU_LIST_PTR lru, long maximum_count, LIST_PTR (*AllocateNode)(), void (*ReuseNode)(LIST_PTR node), void (*FreeNode)(LIST_PTR node)); +LIST_PTR AllocateLruNode(LRU_LIST_PTR lru); +void FreeLruNode(LRU_LIST_PTR lru, LIST_PTR node); +void ReferenceLruNode(LRU_LIST_PTR lru, LIST_PTR node); + +#ifdef __cplusplus + } +#endif + +#endif Added: src/include/enum.h =================================================================== --- src/include/enum.h (rev 0) +++ src/include/enum.h 2009-04-08 13:46:15 UTC (rev 361) @@ -0,0 +1,38 @@ +/*! \file enum.h + \brief Converts enum values to corresponding string + Copied from http://lists.pilot-link.org/pipermail/pilot-link-devel/2005-April/001344.html +*/ + +#ifndef _ENUM_H +#define _ENUM_H + +#define ENUM_BODY(name, value) \ + name value, +#define AS_STRING_CASE(name, value) \ + case name: return #name; +#define FROM_STRING_CASE(name, value) \ + if (strcmp(str, #name) == 0) { \ + return name; \ + } +#define DEFINE_ENUM(name, list) \ + typedef enum { \ + list(ENUM_BODY) \ + }name; +#define AS_STRING_DEC(name, list) \ + const char* name##_AS_STRING(name n); +#define AS_STRING_FUNC(name, list) \ + const char* name##_AS_STRING(name n) { \ + switch (n) { \ + list(AS_STRING_CASE) \ + default: return ""; \ + } \ + } +#define FROM_STRING_DEC(name, list) \ + name name##FromString(const char* str); +#define FROM_STRING_FUNC(name, list) \ + name name##FromString(const char* str) { \ + list(FROM_STRING_CASE) \ + return 0; \ + } + +#endif Modified: src/include/kernel/arch.h =================================================================== --- src/include/kernel/arch.h 2009-03-17 04:37:24 UTC (rev 360) +++ src/include/kernel/arch.h 2009-04-08 13:46:15 UTC (rev 361) @@ -42,6 +42,8 @@ void StartTimer(UINT32 frequency, BYTE periodic); void StopTimer(); +void PrintStackTrace(unsigned int max_frames); + extern UINT16 master_processor_id; extern UINT32 cpu_frequency; Modified: src/include/kernel/error.h =================================================================== --- src/include/kernel/error.h 2009-03-17 04:37:24 UTC (rev 360) +++ src/include/kernel/error.h 2009-04-08 13:46:15 UTC (rev 361) @@ -7,31 +7,29 @@ #define __ERROR__H #include <ace.h> -typedef enum -{ - ERROR_SUCCESS = 0, +#include <enum.h> - ERROR_NOT_SUPPORTED, - ERROR_INVALID_PARAMETER, +#define ENUM_LIST_ERROR_CODE(_) \ + _(ERROR_SUCCESS,) \ + _(ERROR_NOT_SUPPORTED,) \ + _(ERROR_INVALID_PARAMETER,) \ + _(ERROR_NOT_ENOUGH_MEMORY,) \ + _(ERROR_WRITE_FAULT,) \ + _(ERROR_READ_FAULT,) \ + _(ERROR_LOCK_VIOLATION,) \ + _(ERROR_BUSY,) \ + _(ERROR_RETRY,) \ + _(ERROR_TIMEOUT,) \ + _(ERROR_IO_DEVICE,) \ + _(ERROR_IRQ_BUSY,) \ + _(ERROR_INVALID_FORMAT,) \ + _(ERROR_INVALID_PATH,) \ + _(ERROR_NOT_FOUND,) \ + _(ERROR_SYMBOL_NOT_FOUND,) \ + _(ERROR_RESOURCE_SHORTAGE,) - ERROR_NOT_ENOUGH_MEMORY, - - ERROR_WRITE_FAULT, - ERROR_READ_FAULT, - - ERROR_LOCK_VIOLATION, - - ERROR_BUSY, - ERROR_RETRY, - ERROR_TIMEOUT, - - ERROR_IO_DEVICE, - ERROR_IRQ_BUSY, - - ERROR_INVALID_FORMAT, - ERROR_NOT_FOUND, - - ERROR_SYMBOL_NOT_FOUND -}ERROR_CODE; +DEFINE_ENUM(ERROR_CODE, ENUM_LIST_ERROR_CODE) +const char* ERROR_CODE_AS_STRING(ERROR_CODE n); + #endif Modified: src/include/kernel/i386/exception.h =================================================================== --- src/include/kernel/i386/exception.h 2009-03-17 04:37:24 UTC (rev 360) +++ src/include/kernel/i386/exception.h 2009-04-08 13:46:15 UTC (rev 361) @@ -53,5 +53,6 @@ void SetupExceptionHandlers(); void ExceptionHandler(REGS_PTR reg); +void DoubleFaultHandler(); #endif Modified: src/include/kernel/i386/gdt.h =================================================================== --- src/include/kernel/i386/gdt.h 2009-03-17 04:37:24 UTC (rev 360) +++ src/include/kernel/i386/gdt.h 2009-04-08 13:46:15 UTC (rev 361) @@ -54,9 +54,14 @@ UINT32 base; } __attribute__ ((packed)); -#define STATIC_GDT_ENTRIES 5 -#define GDT_ENTRIES (STATIC_GDT_ENTRIES + MAX_PROCESSORS) +/* Hardcoded - 0-NULL 1-Kernel Code 2-Kernel Data 3-User Code 4-User Data + Runtime - 5-Doublefault TSS +*/ +#define STATIC_GDT_ENTRIES (5+1) +#define GDT_ENTRIES (STATIC_GDT_ENTRIES + MAX_PROCESSORS) +#define DOUBLE_FAULT_GDT_INDEX 5 + /*global descriptor table*/ extern struct gdt_entry gdt[GDT_ENTRIES]; Modified: src/include/kernel/i386/i386.inc =================================================================== --- src/include/kernel/i386/i386.inc 2009-03-17 04:37:24 UTC (rev 360) +++ src/include/kernel/i386/i386.inc 2009-04-08 13:46:15 UTC (rev 361) @@ -14,6 +14,7 @@ KERNEL_CODE_SELECTOR equ 0x8 KERNEL_DATA_SELECTOR equ 0x10 GDT_ENTRIES equ 0x5 +DOUBLE_FAULT_GDT_INDEX equ 0x6 IDT_ENTRIES equ 256 KERNEL_PHYSICAL_ADDRESS equ 0x100000 @@ -32,6 +33,7 @@ USER_PRIVILEGE_LEVEL equ 3 IDT_TYPE_INTERRUPT_GATE equ 0xE +IDT_TYPE_TASK_GATE equ 0x5 EXTERN sbss EXTERN ebss Modified: src/include/kernel/i386/idt.h =================================================================== --- src/include/kernel/i386/idt.h 2009-03-17 04:37:24 UTC (rev 360) +++ src/include/kernel/i386/idt.h 2009-04-08 13:46:15 UTC (rev 361) @@ -36,6 +36,8 @@ void LoadIdt(); void SetIdtGate(BYTE num, UINT32 base, BYTE type, BYTE dpl); +void SetIdtTaskGate(BYTE num, BYTE task_selector, BYTE dpl); #endif + Modified: src/include/kernel/i386/processor.h =================================================================== --- src/include/kernel/i386/processor.h 2009-03-17 04:37:24 UTC (rev 360) +++ src/include/kernel/i386/processor.h 2009-04-08 13:46:15 UTC (rev 361) @@ -1,29 +1,29 @@ -/*! - \file kernel/i386/processor.h - \brief Processor data structure - architecture dependent part - - Architecture depended and independed processor structures are maintained using parallel arrays. - Architecture depended processor structure is declared inside arch/processor.h -*/ - -#ifndef _PROCESSOR_I386_H_ -#define _PROCESSOR_I386_H_ - -#include <ace.h> -#include <kernel/processor.h> -#include <kernel/i386/apic.h> -#include <kernel/i386/cpuid.h> -#include <kernel/i386/tss.h> - -/*! Data structure for architecture independed part of a i386 processor(which supports CPUID and has LAPIC)*/ -typedef struct processor_i386 -{ - CPUID_INFO cpuid; /*! CPUID data returned by the processor*/ - UINT16 apic_id; /*! APIC id of the CPU, we cant use CPUID data until the CPU starts*/ - TSS tss; /*! task state segment for this cpu*/ -}PROCESSOR_I386, *PROCESSOR_I386_PTR; - -/*Processors are indexed by using APIC ID*/ -extern PROCESSOR_I386 processor_i386[MAX_PROCESSORS]; - -#endif +/*! + \file kernel/i386/processor.h + \brief Processor data structure - architecture dependent part + + Architecture depended and independed processor structures are maintained using parallel arrays. + Architecture depended processor structure is declared inside arch/processor.h +*/ + +#ifndef _PROCESSOR_I386_H_ +#define _PROCESSOR_I386_H_ + +#include <ace.h> +#include <kernel/processor.h> +#include <kernel/i386/apic.h> +#include <kernel/i386/cpuid.h> +#include <kernel/i386/tss.h> + +/*! Data structure for architecture independed part of a i386 processor(which supports CPUID and has LAPIC)*/ +typedef struct processor_i386 +{ + CPUID_INFO cpuid; /*! CPUID data returned by the processor*/ + UINT16 apic_id; /*! APIC id of the CPU, we cant use CPUID data until the CPU starts*/ + TSS tss; /*! task state segment for this cpu*/ +}PROCESSOR_I386, *PROCESSOR_I386_PTR; + +/*Processors are indexed by using APIC ID*/ +extern PROCESSOR_I386 processor_i386[MAX_PROCESSORS]; + +#endif Modified: src/include/kernel/i386/tss.h =================================================================== --- src/include/kernel/i386/tss.h 2009-03-17 04:37:24 UTC (rev 360) +++ src/include/kernel/i386/tss.h 2009-04-08 13:46:15 UTC (rev 361) @@ -26,7 +26,7 @@ UINT32 cr3; UINT32 eip; - UINT32 reserved_5; + UINT32 eflags; UINT32 eax; UINT32 ecx; @@ -67,5 +67,6 @@ typedef volatile struct tss TSS, * TSS_PTR; void LoadTss(); +void FillTssForDoubleFaultHandler( void * fault_handler, UINT32 kernel_stack ); #endif Modified: src/include/kernel/ipc.h =================================================================== --- src/include/kernel/ipc.h 2009-03-17 04:37:24 UTC (rev 360) +++ src/include/kernel/ipc.h 2009-04-08 13:46:15 UTC (rev 361) @@ -6,16 +6,14 @@ #ifndef IPC_H #define IPC_H -typedef struct message_queue MESSAGE_QUEUE, *MESSAGE_QUEUE_PTR; - #include <ace.h> #include <ds/list.h> #include <sync/spinlock.h> #include <kernel/system_call_handler.h> #include <kernel/wait_event.h> +#include <kernel/pm/pm_types.h> #define MESSAGE_QUEUE_NO_WAIT -1 -#define MESSAGE_QUEUE_CAN_WAIT 0 extern UINT32 max_message_queue_length; /* System wide tunable to control the size of message queue in task structure */ @@ -23,39 +21,58 @@ { MESSAGE_TYPE_VALUE, MESSAGE_TYPE_REFERENCE, - MESSAGE_TYPE_SKIP + MESSAGE_TYPE_SHARE, + MESSAGE_TYPE_SHARE_PA }MESSAGE_TYPE; -#define ARG_ADDRESS_INDEX 0 -#define ARG_LENGTH_INDEX 1 -#define ARG1_INDEX 2 -#define ARG2_INDEX 3 -#define TOTAL_ARG_COUNT 4 +typedef enum +{ + IPC_ARG_INDEX_1, + IPC_ARG_INDEX_2, + IPC_ARG_INDEX_3, + IPC_ARG_INDEX_4, + IPC_ARG_INDEX_5, + IPC_ARG_INDEX_6, + IPC_ARG_COUNT +}IPC_ARG_INDEX; +#define IPC_ARG_ADDRESS IPC_ARG_INDEX_5 +#define IPC_ARG_LENGTH IPC_ARG_INDEX_6 + +#define ipc_arg_address ((void *)arg5) +#define ipc_arg_length ((long)arg6) + +typedef void * IPC_ARG_TYPE; + + typedef struct message_buffer { - LIST message_buffer_queue; - MESSAGE_TYPE type; - UINT32 args[TOTAL_ARG_COUNT]; + LIST message_buffer_queue; /*! link list of message buffers in this message queue*/ + MESSAGE_TYPE type; /*! type of this message*/ + IPC_ARG_TYPE args[IPC_ARG_COUNT]; /*! argmuents to this message*/ + + THREAD_PTR sender_thread; /*! thread which initiated this message*/ }MESSAGE_BUFFER, *MESSAGE_BUFFER_PTR; struct message_queue { - SPIN_LOCK lock; /*! Lock to guard the entire mesage queue */ - UINT32 buf_count; /*! Number of message buffers that are present in this queue */ - MESSAGE_BUFFER_PTR msg_queue; /*! Pointer to head of the message buffer queue */ - WAIT_EVENT_PTR wait_event_msg_queue; /*! Pointer to wait event queue for message_queue variable */ + SPIN_LOCK lock; /*! Lock to guard the entire mesage queue */ + UINT32 buf_count; /*! Number of message buffers that are present in this queue */ + MESSAGE_BUFFER_PTR msg_queue; /*! Pointer to head of the message buffer queue */ + WAIT_EVENT_PTR wait_event_msg_queue; /*! Pointer to wait event queue for message_queue variable */ SPIN_LOCK wait_event_msg_queue_lock; /*! lock for the wait event */ }; -ERROR_CODE SendMessage(MESSAGE_TYPE type, register unsigned int arg1, register unsigned int arg2, register unsigned int arg3, register unsigned int arg4, UINT32 pid_target_task, UINT8 queue_no, UINT32 wait_time); -ERROR_CODE SendMessageCore(MESSAGE_TYPE type, register unsigned int arg1, register unsigned int arg2, register unsigned int arg3, register unsigned int arg4, MESSAGE_QUEUE_PTR message_queue, UINT32 wait_time); -ERROR_CODE ReceiveMessage(MESSAGE_TYPE type, unsigned int *arg1, unsigned int *arg2, unsigned int *arg3, unsigned int *arg4, UINT8 queue_no, UINT32 wait_time); -ERROR_CODE ReceiveMessageCore(MESSAGE_TYPE type, unsigned int *arg1, unsigned int *arg2, unsigned int *arg3, unsigned int *arg4, MESSAGE_QUEUE_PTR message_queue, UINT32 wait_time); -UINT32 GetTotalMessageCount(MESSAGE_QUEUE_PTR msg_queue); -void SkipMessage(MESSAGE_QUEUE_PTR msg_queue); -ERROR_CODE GetNextMessageInfo(UINT32 *type, UINT32 *length, MESSAGE_QUEUE_PTR msg_queue); +void InitMessageQueue(MESSAGE_QUEUE_PTR message_queue); +ERROR_CODE SendMessage(UINT32 pid_target_task, UINT8 queue_no, MESSAGE_TYPE type, IPC_ARG_TYPE arg1, IPC_ARG_TYPE arg2, IPC_ARG_TYPE arg3, IPC_ARG_TYPE arg4, IPC_ARG_TYPE arg5, IPC_ARG_TYPE arg6, UINT32 wait_time); +ERROR_CODE SendMessageCore(TASK_PTR target_task, MESSAGE_QUEUE_PTR message_queue, MESSAGE_TYPE type, IPC_ARG_TYPE arg1, IPC_ARG_TYPE arg2, IPC_ARG_TYPE arg3, IPC_ARG_TYPE arg4, IPC_ARG_TYPE arg5, IPC_ARG_TYPE arg6, UINT32 wait_time); +ERROR_CODE ReceiveMessage(UINT8 queue_no, IPC_ARG_TYPE arg1, IPC_ARG_TYPE arg2, IPC_ARG_TYPE arg3, IPC_ARG_TYPE arg4, IPC_ARG_TYPE arg5, IPC_ARG_TYPE arg6, UINT32 wait_time); +ERROR_CODE ReceiveMessageCore(MESSAGE_QUEUE_PTR message_queue, IPC_ARG_TYPE arg1, IPC_ARG_TYPE arg2, IPC_ARG_TYPE arg3, IPC_ARG_TYPE arg4, IPC_ARG_TYPE arg5, IPC_ARG_TYPE arg6, UINT32 wait_time); +ERROR_CODE ReplyToLastMessage(MESSAGE_TYPE type, IPC_ARG_TYPE arg1, IPC_ARG_TYPE arg2, IPC_ARG_TYPE arg3, IPC_ARG_TYPE arg4, IPC_ARG_TYPE arg5, IPC_ARG_TYPE arg6); +ERROR_CODE WaitForReply(MESSAGE_TYPE type, IPC_ARG_TYPE arg1, IPC_ARG_TYPE arg2, IPC_ARG_TYPE arg3, IPC_ARG_TYPE arg4, IPC_ARG_TYPE arg5, IPC_ARG_TYPE arg6, int timeout); +void SkipMessage(MESSAGE_QUEUE_PTR msg_queue); +ERROR_CODE GetNextMessageInfo(MESSAGE_QUEUE_PTR message_queue, MESSAGE_TYPE *type, UINT32 *length, int wait_time); #endif Modified: src/include/kernel/mm/virtual_page.h =================================================================== --- src/include/kernel/mm/virtual_page.h 2009-03-17 04:37:24 UTC (rev 360) +++ src/include/kernel/mm/virtual_page.h 2009-04-08 13:46:15 UTC (rev 361) @@ -24,6 +24,7 @@ BYTE free:1, /*! if set page is free list*/ active:1, /*! if set page is in active LRU list*/ + ubc:1, /*! if set page is allocated for file cache*/ bad:1, /*! if set page is bad*/ busy:1, /*! if set page is busy due to IO*/ error:1, /*! if set a page error occurred during last IO*/ @@ -42,12 +43,21 @@ { LIST lru_list; /*! LRU List - active/inactive link*/ - UINT16 copy_on_write; /*! No of processes sharing this page*/ - UINT16 wire_count; /*! Total wire count*/ - VA_MAP_PTR va_map_list; /*! list of VAs associated with this page*/ }; + /*the following structure is used when the page is controlled by ubc*/ + struct + { + AVL_TREE tree; /*! tree of all pages in a vnode - for faster search*/ + VNODE_PTR vnode; /*! back pointer to vnode - neccessary?*/ + VADDR offset; /*! file offset this page maps - key to the above tree*/ + BYTE loaded:1, /*! set to 1 if the page is loaded from file*/ + modified:1; /*! set to 1 if the page is modified after load*/ + }ubc_info; }; + + UINT16 copy_on_write; /*! No of processes sharing this page*/ + UINT16 wire_count; /*! Total wire count*/ UINT32 physical_address; /*Physical address this page managing*/ }__attribute__ ((packed)); Modified: src/include/kernel/mm/vm.h =================================================================== --- src/include/kernel/mm/vm.h 2009-03-17 04:37:24 UTC (rev 360) +++ src/include/kernel/mm/vm.h 2009-04-08 13:46:15 UTC (rev 361) @@ -12,6 +12,7 @@ #include <kernel/error.h> #include <kernel/mm/kmem.h> #include <kernel/mm/vm_types.h> +#include <kernel/vfs/vfs_types.h> #if ARCH == i386 #define PAGE_SIZE 4096 @@ -35,7 +36,7 @@ #define PAGE_MASK ( ~(PAGE_SIZE-1) ) -#define IS_PAGE_ALIGNED(addr) ( !( (addr) & PAGE_MASK ) ) +#define IS_PAGE_ALIGNED(addr) ( !( ((unsigned long)addr) & (PAGE_SIZE-1) ) ) /*! Total number pages required by given size in bytes*/ #define NUMBER_OF_PAGES(size) (PAGE_ALIGN_UP(size) >> PAGE_SHIFT) @@ -47,6 +48,20 @@ #define PROT_WRITE 2 #define PROT_EXECUTE 4 +typedef enum +{ + VM_UNIT_TYPE_KERNEL=1, /*kernel mapping*/ + VM_UNIT_TYPE_ANONYMOUS, + VM_UNIT_TYPE_FILE_MAPPED, + VM_UNIT_TYPE_STACK +}VM_UNIT_TYPE; + +typedef enum +{ + VM_UNIT_FLAG_SHARED=1, + VM_UNIT_FLAG_PRIVATE +}VM_UNIT_FLAG; + /*! structure to contain VM data for a NUMA node*/ struct vm_data { @@ -111,22 +126,27 @@ SPIN_LOCK lock; /*! lock for the entire structure*/ int reference_count; /*! total number of references*/ - UINT32 type; /*! type - text, code, heap...*/ - UINT32 flag; /*! flag - shared, private....*/ + VM_UNIT_TYPE type; /*! type - text, code, heap...*/ + VM_UNIT_FLAG flag; /*! flag - shared, private....*/ UINT32 size; /*! total size of this unit*/ SPIN_LOCK vtop_lock; /*! lock to protect array and page_count*/ VM_VTOP_PTR vtop_array; /*! pointer to the virtual page array*/ int page_count; /*! total pages in memory*/ + + VNODE_PTR vnode; /*! pointer to vnode, if this unit backed by a file/swap*/ + UINT32 offset; /*! offset in the file*/ + LIST units_in_vnode_list;/*! all the vmunits corresponds to a vm unit are linked through this list*/ }; struct vm_vtop { union { - int in_memory; /*! if 1 means it is in memory*/ - VIRTUAL_PAGE_PTR vpage; /*! pointer to the virtual page*/ + int in_memory; /*! if 1 means it is in memory else in filesystem/swap*/ + VIRTUAL_PAGE_PTR vpage; /*! pointer to the virtual page if the page is in memory*/ + VNODE_PTR vnode; /*! pointer to the vnode if the page is in filesystem/swap*/ }; }; @@ -185,10 +205,11 @@ VM_DESCRIPTOR_PTR GetVmDescriptor(VIRTUAL_MAP_PTR vmap, VADDR va, UINT32 size); void * FindFreeVmRange(VIRTUAL_MAP_PTR vmap, VADDR start, UINT32 size, UINT32 option); -VM_UNIT_PTR CreateVmUnit(UINT32 type, UINT32 size); +VM_UNIT_PTR CreateVmUnit(VM_UNIT_TYPE type, VM_UNIT_FLAG flag, UINT32 size); ERROR_CODE AllocateVirtualMemory(VIRTUAL_MAP_PTR vmap, VADDR * va_ptr, VADDR preferred_start, UINT32 size, UINT32 protection, UINT32 flags, VM_UNIT_PTR unit); ERROR_CODE FreeVirtualMemory(VIRTUAL_MAP_PTR vmap, VADDR va, UINT32 size, UINT32 flags); +ERROR_CODE MapViewOfFile(int file_id, VADDR * va, UINT32 protection, UINT32 file_offset, UINT32 size, UINT32 preferred_start, UINT32 flags); ERROR_CODE CopyVirtualAddressRange(VIRTUAL_MAP_PTR src_vmap, VADDR src_va, VIRTUAL_MAP_PTR dest_vmap, VADDR *dest_preferred_va, UINT32 dest_size, UINT32 protection); Deleted: src/include/kernel/module.h =================================================================== --- src/include/kernel/module.h 2009-03-17 04:37:24 UTC (rev 360) +++ src/include/kernel/module.h 2009-04-08 13:46:15 UTC (rev 361) @@ -1,46 +0,0 @@ -/*! - \file kernel/module.h - \brief Contains kernel module container data structure definitions. -*/ - -#ifndef _MODULE_H_ -#define _MODULE_H_ - -#include <ace.h> -#include <kernel/error.h> - -#define KERNEL_MODULE_NAME_MAX 30 - -#define MODULE_MAGIC_NUMBER 0xACE - -struct module_file_header -{ - UINT32 MagicNumber; /*! Identifies Ace kernel module container file - should be 0xACE*/ - int TotalModules; /*! Total number of modules present in this container*/ -}__attribute__ ((packed)); - -typedef struct module_file_header MODULE_FILE_HEADER, * MODULE_FILE_HEADER_PTR; - -struct module_header -{ - char ModuleName[KERNEL_MODULE_NAME_MAX]; /*! Name of the module*/ - UINT32 Size; /*! Size of the module*/ -}__attribute__ ((packed)); - -typedef struct module_header MODULE_HEADER, * MODULE_HEADER_PTR; - -#ifdef __cplusplus - extern "C" { -#endif - -ERROR_CODE InitBootModuleContainer(); -ERROR_CODE LoadBootModule(char * module_name, void ** start_address, UINT32 * size); -ERROR_CODE StartBootModule(void * va, UINT32 size); - -ERROR_CODE LoadBootModules(); - -#ifdef __cplusplus - } -#endif - -#endif Modified: src/include/kernel/pm/elf.h =================================================================== --- src/include/kernel/pm/elf.h 2009-03-17 04:37:24 UTC (rev 360) +++ src/include/kernel/pm/elf.h 2009-04-08 13:46:15 UTC (rev 361) @@ -325,15 +325,10 @@ /*! How to extract and insert information held in the st_info field. */ -#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) -#define ELF32_ST_TYPE(val) ((val) & 0xf) -#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) +#define ELF_ST_BIND(val) (((unsigned char) (val)) >> 4) +#define ELF_ST_TYPE(val) ((val) & 0xf) +#define ELF_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) -/*! Both ELF32_SYMBOL and ELF64_SYMBOL use the same one-byte st_info field. */ -#define ELF64_ST_BIND(val) ELF32_ST_BIND (val) -#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) -#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) - /*! Legal values for ST_BIND subfield of st_info (symbol binding). */ #define STB_LOCAL 0 /*! Local symbol */ @@ -1561,5 +1556,8 @@ ERROR_CODE LoadElfImage(ELF_HEADER_PTR file_header, VIRTUAL_MAP_PTR virtual_map, char * start_symbol_name, VADDR * start_entry); +char * FindKernelSymbolByAddress(VADDR address, int * offset); + #endif /*! elf.h */ + Modified: src/include/kernel/pm/pid.h =================================================================== --- src/include/kernel/pm/pid.h 2009-03-17 04:37:24 UTC (rev 360) +++ src/include/kernel/pm/pid.h 2009-04-08 13:46:15 UTC (rev 361) @@ -1,48 +1,53 @@ -/*! \file include/kernel/pm/pid.h - \brief process id related structures -*/ - -#ifndef _PID_H_ -#define _PID_H_ - -typedef struct pid_info PID_INFO, * PID_INFO_PTR; - -#include <ace.h> -#include <ds/list.h> -#include <ds/avl_tree.h> -#include <kernel/pm/task.h> -#include <kernel/wait_event.h> -/*! maximum process number allowed*/ -#define MAX_PROCESS_ID 0xFFFF - -struct pid_info -{ - int pid; /*! Process Id*/ - TASK_PTR task; /*! associated task*/ - int ppid; /*! Parent Process Id*/ - - int exited; /*! true if the process is exited/terminated*/ - int exit_status; /*! exit status*/ - WAIT_EVENT_PTR wait_event; /*! if somebody want to watch this process dead event, will wait here*/ - - AVL_TREE tree_node; /*! tree of used pids - to find a pid faster*/ - - int free_count; /*! total free pids after this pid*/ - LIST free_list; /*! links all used pids which has free pids next to them*/ - LIST inuse_list; /*! links all used pids regardless whether they have free pids or not*/ -}; - -CACHE pid_cache; /*! cache for pid info*/ - -#ifdef __cplusplus - extern "C" { -#endif - -int PidCacheConstructor(void *buffer); -int PidCacheDestructor(void *buffer); - -#ifdef __cplusplus - } -#endif - -#endif +/*! \file include/kernel/pm/pid.h + \brief process id related structures +*/ + +#ifndef _PID_H_ +#define _PID_H_ + +#include <ace.h> +#include <ds/list.h> +#include <ds/avl_tree.h> +#include <kernel/wait_event.h> +#include <kernel/pm/pm_types.h> +#include <kernel/pm/task.h> + +/*! maximum process number allowed*/ +#define MAX_PROCESS_ID 0xFFFF + +struct pid_info +{ + int pid; /*! Process Id*/ + TASK_PTR task; /*! associated task*/ + int ppid; /*! Parent Process Id*/ + + int exited; /*! true if the process is exited/terminated*/ + int exit_status; /*! exit status*/ + WAIT_EVENT_PTR wait_event; /*! if somebody want to watch this process dead event, will wait here*/ + + AVL_TREE tree_node; /*! tree of used pids - to find a pid faster*/ + + int free_count; /*! total free pids after this pid*/ + LIST free_list; /*! links all used pids which has free pids next to them*/ + LIST inuse_list; /*! links all used pids regardless whether they have free pids or not*/ +}; + +CACHE pid_cache; /*! cache for pid info*/ + +#ifdef __cplusplus + extern "C" { +#endif + +int PidCacheConstructor(void *buffer); +int PidCacheDestructor(void *buffer); + +PID_INFO_PTR InitPid(); + +PID_INFO_PTR AllocatePidInfo(int ppid); +void FreePidInfo(PID_INFO_PTR pid_info); + +#ifdef __cplusplus + } +#endif + +#endif Added: src/include/kernel/pm/pm_types.h =================================================================== --- src/include/kernel/pm/pm_types.h (rev 0) +++ src/include/kernel/pm/pm_types.h 2009-04-08 13:46:15 UTC (rev 361) @@ -0,0 +1,45 @@ +/*! + \file kernel/pm/pm_types.h + \brief all the typedefs of task, thread and ipc +*/ +#ifndef PM_TYPES_H +#define PM_TYPES_H + +typedef struct task TASK, * TASK_PTR; +typedef struct thread THREAD, * THREAD_PTR; +typedef struct pid_info PID_INFO, * PID_INFO_PTR; + +typedef struct wait_event WAIT_EVENT, *WAIT_EVENT_PTR; +typedef struct message_queue MESSAGE_QUEUE, *MESSAGE_QUEUE_PTR; + +#endif +/*! + \file kernel/pm/pm_types.h + \brief all the typedefs of task, thread and ipc +*/ +#ifndef PM_TYPES_H +#define PM_TYPES_H + +typedef struct task TASK, * TASK_PTR; +typedef struct thread THREAD, * THREAD_PTR; +typedef struct pid_info PID_INFO, * PID_INFO_PTR; + +typedef struct wait_event WAIT_EVENT, *WAIT_EVENT_PTR; +typedef struct message_queue MESSAGE_QUEUE, *MESSAGE_QUEUE_PTR; + +#endif +/*! + \file kernel/pm/pm_types.h + \brief all the typedefs of task, thread and ipc +*/ +#ifndef PM_TYPES_H +#define PM_TYPES_H + +typedef struct task TASK, * TASK_PTR; +typedef struct thread THREAD, * THREAD_PTR; +typedef struct pid_info PID_INFO, * PID_INFO_PTR; + +typedef struct wait_event WAIT_EVENT, *WAIT_EVENT_PTR; +typedef struct message_queue MESSAGE_QUEUE, *MESSAGE_QUEUE_PTR; + +#endif Modified: src/include/kernel/pm/scheduler.h =================================================================== --- src/include/kernel/pm/scheduler.h 2009-03-17 04:37:24 UTC (rev 360) +++ src/include/kernel/pm/scheduler.h 2009-04-08 13:46:15 UTC (rev 361) @@ -1,69 +1,69 @@ -/*! \file include/kernel/pm/scheduler.h - \brief scheduler related strcutrues and function declarations -*/ - -#ifndef _SCHEDULER_H_ -#define _SCHEDULER_H_ - -#include <ace.h> - -/*! Default quantum for each thread in milliseconds*/ -#define SCHEDULER_DEFAULT_QUANTUM 1000 - -typedef struct ready_queue * READY_QUEUE_PTR; -typedef struct priority_queue * PRIORITY_QUEUE_PTR; - -typedef enum -{ - SCHED_CLASS_VERY_HIGH, - SCHED_CLASS_HIGH, - SCHED_CLASS_MID, - SCHED_CLASS_LOW, - SCHED_CLASS_VERY_LOW, - - MAX_SCHEDULER_CLASS_LEVELS /* This should be the last element of this enum */ -}SCHEDULER_CLASS_LEVELS; - -typedef enum -{ - SCHED_PRI_VERY_HIGH, - SCHED_PRI_HIGH, - SCHED_PRI_MID, - SCHED_PRI_LOW, - SCHED_PRI_VERY_LOW, - - SCHEDULER_PRIORITY_LEVELS_PER_CLASS /* This should always be the last element in this anon. */ -}SCHEDULER_PRIORITY_LEVELS; - -#include <kernel/pm/task.h> - -#define MAX_SCHEDULER_PRIORITY_LEVELS ( MAX_SCHEDULER_CLASS_LEVELS * SCHEDULER_PRIORITY_LEVELS_PER_CLASS ) -#define DEFAULT_SCHEDULER_PRIORITY ( MAX_SCHEDULER_PRIORITY_LEVELS / 2 ) - -/*! Priority queue structure used by scheduler */ -typedef struct priority_queue -{ - SPIN_LOCK lock; - THREAD_PTR thread_head; /* List of threads in this priority queue */ - INT8 bonus; /* Bonus indicates how active this priority queue is. More active it is, lesser the bonus value. */ - UINT8 time_slice; /* default quantum in milli seconds assigned to threads in this priority queue */ - UINT8 priority; /* Current priority of this queue */ - READY_QUEUE_PTR ready_queue; /* Back pointer to it's ready queue. */ -}PRIORITY_QUEUE; - -typedef struct ready_queue -{ - SPIN_LOCK lock; /*! Lock to protect entire ready queue */ - UINT32 mask; /*! used for quick calculation on which priority queue has threads ready for running. 1 bit for every queue */ - PRIORITY_QUEUE_PTR priority_queue[MAX_SCHEDULER_PRIORITY_LEVELS]; -}READY_QUEUE; - - -INT8 ModifyThreadPriorityInfo(THREAD_PTR thread, SCHEDULER_CLASS_LEVELS sched_class); -SCHEDULER_CLASS_LEVELS GetThreadPriorityInfo(THREAD_PTR my_thread); -void ScheduleThread(THREAD_PTR in_thread); -void InvokeScheduler(); -void InitScheduler(); -ERROR_CODE BindThreadToProcessor(THREAD_PTR thread, int cpu_no); - -#endif +/*! \file include/kernel/pm/scheduler.h + \brief scheduler related strcutrues and function declarations +*/ + +#ifndef _SCHEDULER_H_ +#define _SCHEDULER_H_ + +#include <ace.h> + +/*! Default quantum for each thread in milliseconds*/ +#define SCHEDULER_DEFAULT_QUANTUM 1000 + +typedef struct ready_queue * READY_QUEUE_PTR; +typedef struct priority_queue * PRIORITY_QUEUE_PTR; + +typedef enum +{ + SCHED_CLASS_VERY_HIGH, + SCHED_CLASS_HIGH, + SCHED_CLASS_MID, + SCHED_CLASS_LOW, + SCHED_CLASS_VERY_LOW, + + MAX_SCHEDULER_CLASS_LEVELS /* This should be the last element of this enum */ +}SCHEDULER_CLASS_LEVELS; + +typedef enum +{ + SCHED_PRI_VERY_HIGH, + SCHED_PRI_HIGH, ... [truncated message content] |
From: <sam...@us...> - 2009-03-17 04:37:42
|
Revision: 360 http://aceos.svn.sourceforge.net/aceos/?rev=360&view=rev Author: samueldotj Date: 2009-03-17 04:37:24 +0000 (Tue, 17 Mar 2009) Log Message: ----------- Fixed problem in wscript files Added gpl license and readme files Modified Paths: -------------- scripts/create_bootcd.sh src/app/wscript_build src/kernel/wscript_build src/tools/mc/mkmc.c wscript Added Paths: ----------- gpl-3.0.txt readme.txt src/tools/wscript Added: gpl-3.0.txt =================================================================== --- gpl-3.0.txt (rev 0) +++ gpl-3.0.txt 2009-03-17 04:37:24 UTC (rev 360) @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. Added: readme.txt =================================================================== --- readme.txt (rev 0) +++ readme.txt 2009-03-17 04:37:24 UTC (rev 360) @@ -0,0 +1,12 @@ +Ace OS - Microkernel source. + +License : GPL 3(see gpl-3.0.txt or visit http://www.gnu.org/copyleft/gpl.html) + +Website : http://sourceforge.net/projects/aceos/ +Wiki : https://apps.sourceforge.net/mediawiki/aceos/index.php?title=Main_Page + +Developers: + Samuel Jacob (sam...@gm...) + Dilip Simha (nmd...@gm...) + +Compilation: https://apps.sourceforge.net/mediawiki/aceos/index.php?title=Compile Modified: scripts/create_bootcd.sh =================================================================== --- scripts/create_bootcd.sh 2009-03-13 13:58:36 UTC (rev 359) +++ scripts/create_bootcd.sh 2009-03-17 04:37:24 UTC (rev 360) @@ -3,7 +3,7 @@ BUILD_DIR=$1/src/ ACE_ROOT=$BUILD_DIR/../../../ ISO_DIR=$BUILD_DIR/../../iso -TOOLS_DIR=$ACE_ROOT/src/tools/build/default/ +TOOLS_DIR=$BUILD_DIR/../../../toolsbuild/default GRUB_BIN=$ACE_ROOT/boot/grub/ #directory clean up and create if needed @@ -13,7 +13,7 @@ #create kernel boot module container rm -f $ISO_DIR/boot_modules.mod -$TOOLS_DIR/mc/mkmc -o $ISO_DIR/boot_modules.mod $BUILD_DIR/app/hello.exe $BUILD_DIR/drivers/pci_bus.sys +$TOOLS_DIR/mkmc -o $ISO_DIR/boot_modules.mod $BUILD_DIR/app/hello.exe $BUILD_DIR/drivers/pci_bus.sys gzip $ISO_DIR/boot_modules.mod #copy grub Modified: src/app/wscript_build =================================================================== --- src/app/wscript_build 2009-03-13 13:58:36 UTC (rev 359) +++ src/app/wscript_build 2009-03-17 04:37:24 UTC (rev 360) @@ -3,4 +3,5 @@ include_dirs = Options.options.usr_include #build hello world application hello = bld.new_task_gen('cc', 'program', target='hello', name='hello', install_path=None, includes=include_dirs, uselib='APPLICATION' ) +hello.env['program_PATTERN'] = '%s.exe' hello.find_sources_in_dirs('hello') Modified: src/kernel/wscript_build =================================================================== --- src/kernel/wscript_build 2009-03-13 13:58:36 UTC (rev 359) +++ src/kernel/wscript_build 2009-03-17 04:37:24 UTC (rev 360) @@ -7,7 +7,7 @@ else: arch_source_dirs = '' -source_dirs = '. iom ipc mm pit pm rtc ' + arch_source_dirs +source_dirs = '. mm pm ipc iom pit rtc ' + arch_source_dirs acpi_source_dirs = 'acpi acpi/events acpi/hardware acpi/interpreter/dispatcher acpi/interpreter/executer acpi/interpreter/parser acpi/namespace acpi/resources acpi/tables acpi/utilities ' include_dirs = '../include/' @@ -18,9 +18,6 @@ acpi.find_sources_in_dirs(acpi_source_dirs) # build kernel -#bld.env['program_PATTERN'] = '%s.sys' kernel = bld.new_task_gen('cc', 'program', target='kernel', name='kernel', install_path=None, includes=include_dirs, uselib_local='acpi ds sync string heap', uselib='KERNEL') kernel.env['program_PATTERN'] = '%s.sys' kernel.find_sources_in_dirs(source_dirs) - - Modified: src/tools/mc/mkmc.c =================================================================== --- src/tools/mc/mkmc.c 2009-03-13 13:58:36 UTC (rev 359) +++ src/tools/mc/mkmc.c 2009-03-17 04:37:24 UTC (rev 360) @@ -11,7 +11,6 @@ #include <sys/mman.h> #include <kernel/module.h> -//#include <kernel/mm/vm.h> int verbose = 0; char * output_file_name = "boot_modules.mod"; Added: src/tools/wscript =================================================================== --- src/tools/wscript (rev 0) +++ src/tools/wscript 2009-03-17 04:37:24 UTC (rev 360) @@ -0,0 +1,29 @@ +#!/usr/bin/env python + +import os, Task, Options, Configure, Utils, misc + +Configure.autoconfig = 1 + +VERSION = '3.0.' + os.popen("svn info | grep Revision | cut -f2 -d:").read().strip() +APPNAME = 'AceTools' +srcdir = '.' +blddir = '../../toolsbuild' + +debug_flags = '-gdwarf-2 -g3' + +c_flags = '-Wall ' + +include_dirs = '../include/ /usr/include' + +def configure(conf): + conf.check_tool('gcc misc') + conf.env.append_unique('CCFLAGS', c_flags ) + + if Options.options.build_type == 'debug': + conf.env.append_unique('CCFLAGS', debug_flags) + +def build(bld): + mkmc = bld.new_task_gen('cc', 'program', source='mc/mkmc.c', target='mkmc', name='mkmc', includes=include_dirs, install_path=None, includes=include_dirs, ) + +def set_options(opt): + opt.add_option("--build", action="store", default="debug", help="Build type - release, debug", dest="build_type") Modified: wscript =================================================================== --- wscript 2009-03-13 13:58:36 UTC (rev 359) +++ wscript 2009-03-17 04:37:24 UTC (rev 360) @@ -55,6 +55,7 @@ bld.add_group() bld.new_task_gen( name='bootcd', source='src/kernel/kernel.sys', target='../bootcd.iso', rule='../scripts/create_bootcd.sh ${TGT[0].abspath(env)}' ) + def set_options(opt): opt.add_option("--arch", action="store", default="i386", help="Hardware architecture to build for.(currently only i386)", dest="arch") opt.add_option("--build", action="store", default="debug", help="Build type - release, debug", dest="build_type") This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sam...@us...> - 2009-03-13 13:58:49
|
Revision: 359 http://aceos.svn.sourceforge.net/aceos/?rev=359&view=rev Author: samueldotj Date: 2009-03-13 13:58:36 +0000 (Fri, 13 Mar 2009) Log Message: ----------- Fixed some scripts which were depended on ACE_ROOT environment variable Modified Paths: -------------- scripts/b.sh scripts/bochsrc scripts/create_bootcd.sh scripts/g.sh scripts/q-lance.sh scripts/q-net2k.sh scripts/q-rtl.sh scripts/q.sh src/drivers/wscript_build src/kernel/main.c wscript Modified: scripts/b.sh =================================================================== --- scripts/b.sh 2009-03-13 12:02:11 UTC (rev 358) +++ scripts/b.sh 2009-03-13 13:58:36 UTC (rev 359) @@ -1,8 +1,9 @@ #! /bin/sh #used alias to run bochs +SCRIPT_PATH=`dirname $0` if [ $OSTYPE = cygwin ] ; then - export ACE_ROOT=`cygpath -a -w $ACE_ROOT` + SCRIPT_PATH=`cygpath -a -w $SCRIPT_PATH` fi #create_bootcd.sh -bochs -q -f $ACE_ROOT/img/bochsrc \ No newline at end of file +bochs -q -f $SCRIPT_PATH/bochsrc \ No newline at end of file Modified: scripts/bochsrc =================================================================== --- scripts/bochsrc 2009-03-13 12:02:11 UTC (rev 358) +++ scripts/bochsrc 2009-03-13 13:58:36 UTC (rev 359) @@ -54,4 +54,4 @@ #ata0-master: type=disk, path="$ACE_ROOT/img/c.img", model="ATA_DEV_1", translation=lba #ata0-slave: type=disk, path="$ACE_ROOT/img/d.img", model="Generic IDE 1234", translation=lba -ata1-master: type=cdrom, path="$ACE_ROOT/img/bootcd.iso", status=inserted +ata1-master: type=cdrom, path="build/bootcd.iso", status=inserted Modified: scripts/create_bootcd.sh =================================================================== --- scripts/create_bootcd.sh 2009-03-13 12:02:11 UTC (rev 358) +++ scripts/create_bootcd.sh 2009-03-13 13:58:36 UTC (rev 359) @@ -1,14 +1,10 @@ #! /bin/sh -if test -z "$ACE_ROOT" -then - echo "Set the ACE_ROOT environment variable first" - exit -fi -BUILD_DIR=$ACE_ROOT/build/default/src/ +BUILD_DIR=$1/src/ +ACE_ROOT=$BUILD_DIR/../../../ ISO_DIR=$BUILD_DIR/../../iso TOOLS_DIR=$ACE_ROOT/src/tools/build/default/ -GRUB_BIN=$ACE_ROOT/img/boot/grub/ +GRUB_BIN=$ACE_ROOT/boot/grub/ #directory clean up and create if needed rm -rf $ISO_DIR @@ -17,7 +13,7 @@ #create kernel boot module container rm -f $ISO_DIR/boot_modules.mod -$TOOLS_DIR/mc/mkmc -v -o $ISO_DIR/boot_modules.mod $BUILD_DIR/app/hello.exe $BUILD_DIR/drivers/pci.sys +$TOOLS_DIR/mc/mkmc -o $ISO_DIR/boot_modules.mod $BUILD_DIR/app/hello.exe $BUILD_DIR/drivers/pci_bus.sys gzip $ISO_DIR/boot_modules.mod #copy grub Modified: scripts/g.sh =================================================================== --- scripts/g.sh 2009-03-13 12:02:11 UTC (rev 358) +++ scripts/g.sh 2009-03-13 13:58:36 UTC (rev 359) @@ -1 +1,4 @@ -gdb -q --command=$ACE_ROOT/img/gdb/.gdbinit --directory=$ACE_ROOT/src/kernel --symbols=$ACE_ROOT/obj/kernel.sys \ No newline at end of file +#! /bin/sh + +SCRIPT_PATH=`dirname $0` +gdb -q --command=$SCRIPT_PATH/gdb/.gdbinit --directory=$SCRIPT_PATH/../src/kernel --symbols=$SCRIPT_PATH/../build/default/src/kernel/kernel.sys \ No newline at end of file Modified: scripts/q-lance.sh =================================================================== --- scripts/q-lance.sh 2009-03-13 12:02:11 UTC (rev 358) +++ scripts/q-lance.sh 2009-03-13 13:58:36 UTC (rev 359) @@ -5,8 +5,5 @@ exit fi -if [ $OSTYPE = cygwin ] ; then - export ACE_ROOT=`cygpath -a -w $ACE_ROOT` -fi - -qemu -L "$QEMU_BIOS_DIR" -M pc -m 32 -no-kqemu -hdc c.img -boot n -net nic,model=pcnet,macaddr=52:54:00:12:34:58,vlan=0 -net tap,vlan=0,ifname=tap0 \ No newline at end of file +SCRIPT_PATH=`dirname $0` +qemu -L "$QEMU_BIOS_DIR" -M pc -m 32 -no-kqemu -hdc $SCRIPT_PATH/../build/c.img -boot n -net nic,model=pcnet,macaddr=52:54:00:12:34:58,vlan=0 -net tap,vlan=0,ifname=tap0 \ No newline at end of file Modified: scripts/q-net2k.sh =================================================================== --- scripts/q-net2k.sh 2009-03-13 12:02:11 UTC (rev 358) +++ scripts/q-net2k.sh 2009-03-13 13:58:36 UTC (rev 359) @@ -5,8 +5,5 @@ exit fi -if [ $OSTYPE = cygwin ] ; then - export ACE_ROOT=`cygpath -a -w $ACE_ROOT` -fi - -qemu -L "$QEMU_BIOS_DIR" -M pc -m 32 -no-kqemu -hdc c.img -boot n -net nic,model=ne2k_pci,macaddr=52:54:00:12:34:56,vlan=0 -net tap,vlan=0,ifname=tap0 \ No newline at end of file +SCRIPT_PATH=`dirname $0` +qemu -L "$QEMU_BIOS_DIR" -M pc -m 32 -no-kqemu -hdc $SCRIPT_PATH/../build/c.img -boot n -net nic,model=ne2k_pci,macaddr=52:54:00:12:34:56,vlan=0 -net tap,vlan=0,ifname=tap0 \ No newline at end of file Modified: scripts/q-rtl.sh =================================================================== --- scripts/q-rtl.sh 2009-03-13 12:02:11 UTC (rev 358) +++ scripts/q-rtl.sh 2009-03-13 13:58:36 UTC (rev 359) @@ -4,9 +4,5 @@ echo "Set the QEMU_BIOS_DIR environment variable. This variable should point to QEMU bios and video bios directory" exit fi - -if [ $OSTYPE = cygwin ] ; then - export ACE_ROOT=`cygpath -a -w $ACE_ROOT` -fi - -qemu -L "$QEMU_BIOS_DIR" -M pc -m 32 -no-kqemu -hdc c.img -boot n -net nic,model=rtl8139,macaddr=52:54:00:12:34:57,vlan=0 -net tap,vlan=0,ifname=tap0 \ No newline at end of file +SCRIPT_PATH=`dirname $0` +qemu -L "$QEMU_BIOS_DIR" -M pc -m 32 -no-kqemu -hdc $SCRIPT_PATH/../build/c.img -boot n -net nic,model=rtl8139,macaddr=52:54:00:12:34:57,vlan=0 -net tap,vlan=0,ifname=tap0 \ No newline at end of file Modified: scripts/q.sh =================================================================== --- scripts/q.sh 2009-03-13 12:02:11 UTC (rev 358) +++ scripts/q.sh 2009-03-13 13:58:36 UTC (rev 359) @@ -5,8 +5,7 @@ exit fi -PWD='pwd' -cd $ACE_ROOT/img +SCRIPT_PATH=`dirname $0` #create_bootcd.sh -qemu -L "$QEMU_BIOS_DIR" -M pc -cdrom bootcd.iso -boot d -m 32 -smp 1 -localtime -no-kqemu $* -cd $PWD +qemu -L "$QEMU_BIOS_DIR" -M pc -cdrom $SCRIPT_PATH/../build/bootcd.iso -boot d -m 32 -smp 1 -localtime -no-kqemu $* + Modified: src/drivers/wscript_build =================================================================== --- src/drivers/wscript_build 2009-03-13 12:02:11 UTC (rev 358) +++ src/drivers/wscript_build 2009-03-13 13:58:36 UTC (rev 359) @@ -4,6 +4,6 @@ include_dirs = '../include/' #build pci driver -pci = bld.new_task_gen('cc', 'program', target='pci', name='pci', install_path=None, includes=include_dirs, uselib='DRIVER' ) +pci = bld.new_task_gen('cc', 'program', target='pci_bus', name='pci', install_path=None, includes=include_dirs, uselib='DRIVER' ) pci.env['program_PATTERN'] = '%s.sys' pci.find_sources_in_dirs('pci') Modified: src/kernel/main.c =================================================================== --- src/kernel/main.c 2009-03-13 12:02:11 UTC (rev 358) +++ src/kernel/main.c 2009-03-13 13:58:36 UTC (rev 359) @@ -82,7 +82,7 @@ /* now lets set up system call handler */ SetupSystemCallHandler(); - CreateTask("hello"); + //CreateTask("hello.exe"); kprintf("Kernel initialization complete\n"); } Modified: wscript =================================================================== --- wscript 2009-03-13 12:02:11 UTC (rev 358) +++ wscript 2009-03-13 13:58:36 UTC (rev 359) @@ -53,7 +53,7 @@ bld.add_subdirs('src/drivers') bld.add_subdirs('src/app') bld.add_group() - bld.new_task_gen( name='bootcd', source='src/kernel/kernel.sys', target='../bootcd.iso', rule='../img/create_bootcd.sh' ) + bld.new_task_gen( name='bootcd', source='src/kernel/kernel.sys', target='../bootcd.iso', rule='../scripts/create_bootcd.sh ${TGT[0].abspath(env)}' ) def set_options(opt): opt.add_option("--arch", action="store", default="i386", help="Hardware architecture to build for.(currently only i386)", dest="arch") This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sam...@us...> - 2009-03-13 12:02:19
|
Revision: 358 http://aceos.svn.sourceforge.net/aceos/?rev=358&view=rev Author: samueldotj Date: 2009-03-13 12:02:11 +0000 (Fri, 13 Mar 2009) Log Message: ----------- Moved remotely Added Paths: ----------- boot/ Removed Paths: ------------- scripts/boot/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sam...@us...> - 2009-03-13 11:58:38
|
Revision: 357 http://aceos.svn.sourceforge.net/aceos/?rev=357&view=rev Author: samueldotj Date: 2009-03-13 11:58:23 +0000 (Fri, 13 Mar 2009) Log Message: ----------- Switched to waf and removed all the makefile Modified Paths: -------------- scripts/create_bootcd.sh src/include/kernel/acpi/platform/acace.h src/kernel/i386/interrupt_stub.asm src/kernel/i386/start.asm src/kernel/i386/trampoline.asm Added Paths: ----------- scripts/ src/app/wscript_build src/drivers/wscript_build src/kernel/wscript_build src/lib/wscript_build waf wscript Removed Paths: ------------- img/ make.conf make_app.conf makefile obj/ src/app/makefile src/drivers/makefile src/drivers/pci/makefile src/kernel/acpi/makefile src/kernel/i386/makefile src/kernel/iom/makefile src/kernel/makefile src/kernel/pit/makefile src/kernel/rtc/makefile src/lib/ds/makefile src/lib/ds/test/makefile src/lib/heap/makefile src/lib/heap/test/makefile src/lib/makefile src/lib/string/makefile src/lib/string/test/makefile src/lib/sync/i386/makefile src/lib/sync/makefile src/lib/sync/test/makefile src/makefile src/tools/makefile src/tools/mc/makefile Deleted: make.conf =================================================================== --- make.conf 2009-03-13 06:08:52 UTC (rev 356) +++ make.conf 2009-03-13 11:58:23 UTC (rev 357) @@ -1,46 +0,0 @@ -#make.conf - -ifeq ($(ACE_ROOT),) - ACE_ROOT=$(PWD) -endif - -.SILENT: - -INCLUDE= $(ACE_ROOT)/src/include/ - -OBJ= $(ACE_ROOT)/obj -IMG= $(ACE_ROOT)/img -TOOLS_BIN= $(OBJ)/tools - -ASM= nasm -ASMFLAGS= -w+orphan-labels -f elf -CC= gcc -LD= ld - -ARCH= i386 - -#DEFINES+= -D __DEBUG__ -DEFINES+= -D __KERNEL_BUILT__ -DEBUG_FLAGS= -gdwarf-2 -g3 -#ACPI_DEBUG= $(DEBUG_FLAGS) - -CFLAGS+= -Wall -Wno-multichar $(DEFINES) -nostartfiles -ffreestanding -funsigned-char -fno-leading-underscore -c -fno-stack-protector $(DEBUG_FLAGS) $(CUSTOM_FLAG) - -#LDFLAGS= -verbose - -%.d: %.c - @$(CC) -c -M $< -I$(INCLUDE) $(CFLAGS) > $@ - -%.o: %.c - @$(CC) -c $(abspath $<) -o $@ -I$(INCLUDE) -I./include $(CFLAGS) - -%.d: %.S - @echo -n $(dir $<) > $@ - @$(CC) -c -M $(abspath $<) -I$(INCLUDE) -I./include $(ASFLAGS) > $@ - -%.d: %.asm - @$(ASM) $(DEFINES) -i$(INCLUDE) -M $(abspath $<) -o $(<:.asm=.o) > $@ - -%.o: %.asm - @$(ASM) $(DEFINES) $(ASMFLAGS) -i$(INCLUDE) $(abspath $<) -o $@ - Deleted: make_app.conf =================================================================== --- make_app.conf 2009-03-13 06:08:52 UTC (rev 356) +++ make_app.conf 2009-03-13 11:58:23 UTC (rev 357) @@ -1,44 +0,0 @@ -#make_app.conf - -ifeq ($(ACE_ROOT),) - ACE_ROOT=$(PWD) -endif - -.SILENT: - -LIB_INCLUDE= /usr/cross/i586-pc-aceos/lib/ -INCLUDE= $(ACE_ROOT)/src/include/ - -OBJ= $(ACE_ROOT)/obj -IMG= $(ACE_ROOT)/img -USR_BIN= $(OBJ)/usr/bin/ - -ASM= nasm -ASMFLAGS= -w+orphan-labels -f elf -CC= gcc -LD= ld - -ARCH= i386 - -#DEFINES+= -D __DEBUG__ -DEBUG_FLAGS= -gdwarf-2 -g3 - -CFLAGS+= -Wall -Wno-multichar $(DEFINES) -funsigned-char -fno-leading-underscore -fno-stack-protector -nostdlib -static $(LIB_INCLUDE)/crt0.o $(DEBUG_FLAGS) $(CUSTOM_FLAG) -#LDFLAGS= -verbose - -%.d: %.c - @$(CC) -c -M $< -I$(INCLUDE) $(CFLAGS) > $@ - -%.o: %.c - @$(CC) -c $(abspath $<) -o $@ -I$(INCLUDE) -I./include $(CFLAGS) - -%.d: %.S - @echo -n $(dir $<) > $@ - @$(CC) -c -M $(abspath $<) -I$(INCLUDE) -I./include $(ASFLAGS) > $@ - -%.d: %.asm - @$(ASM) $(DEFINES) -i$(INCLUDE) -M $(abspath $<) -o $(<:.asm=.o) > $@ - -%.o: %.asm - @$(ASM) $(DEFINES) $(ASMFLAGS) -i$(INCLUDE) $(abspath $<) -o $@ - Deleted: makefile =================================================================== --- makefile 2009-03-13 06:08:52 UTC (rev 356) +++ makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,24 +0,0 @@ -#makefile -include make.conf - -ALL_DIRS= src doc - -src: always - make -C src - -doc: always - make -C doc - -kernel: always - make -C src/kernel - -all: always - for dir in $(ALL_DIRS); do make -C $$dir all; done - -clean: always - make -C src clean - -all_clean: always - for dir in $(ALL_DIRS); do make -C $$dir clean; done - -always: Modified: scripts/create_bootcd.sh =================================================================== --- img/create_bootcd.sh 2009-03-07 08:20:55 UTC (rev 353) +++ scripts/create_bootcd.sh 2009-03-13 11:58:23 UTC (rev 357) @@ -5,21 +5,25 @@ exit fi -OBJ=$ACE_ROOT/obj/ -IMG=$ACE_ROOT/img/ -TOOLS_BIN=$ACE_ROOT/obj/tools/ -USR_BIN=$ACE_ROOT/obj/usr/bin/ +BUILD_DIR=$ACE_ROOT/build/default/src/ +ISO_DIR=$BUILD_DIR/../../iso +TOOLS_DIR=$ACE_ROOT/src/tools/build/default/ +GRUB_BIN=$ACE_ROOT/img/boot/grub/ -rm -f $ACE_ROOT/obj/boot_modules.mod.gz +#directory clean up and create if needed +rm -rf $ISO_DIR +mkdir -p $ISO_DIR +mkdir -p $ISO_DIR/boot/grub + #create kernel boot module container -$TOOLS_BIN/mkmc -v -o $OBJ/boot_modules.mod $USR_BIN/hello $OBJ/pci_bus.sys -gzip $OBJ/boot_modules.mod +rm -f $ISO_DIR/boot_modules.mod +$TOOLS_DIR/mc/mkmc -v -o $ISO_DIR/boot_modules.mod $BUILD_DIR/app/hello.exe $BUILD_DIR/drivers/pci.sys +gzip $ISO_DIR/boot_modules.mod -rm -rf $IMG/iso/ -mkdir -p $IMG/iso/boot/grub -cp $IMG/boot/grub/stage2_eltorito $IMG/iso/boot/grub -cp $IMG/boot/grub/menu.lst $IMG/iso/boot/grub -cp $OBJ/kernel.sys $IMG/iso -cp $OBJ/boot_modules.mod.gz $IMG/iso +#copy grub +cp $GRUB_BIN/stage2_eltorito $ISO_DIR/boot/grub +cp $GRUB_BIN/menu.lst $ISO_DIR/boot/grub +cp $BUILD_DIR/kernel/kernel.sys $ISO_DIR -mkisofs -quiet -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o $IMG/bootcd.iso $IMG/iso +#create iso file +mkisofs -quiet -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o $ISO_DIR/../bootcd.iso $ISO_DIR Deleted: src/app/makefile =================================================================== --- src/app/makefile 2009-03-13 06:08:52 UTC (rev 356) +++ src/app/makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,17 +0,0 @@ -#src/app/makefile - -include $(ACE_ROOT)/make_app.conf - -ALL_DIRS= hello - -all: always - @for dir in $(ALL_DIRS); do make -C $$dir; done - -hello: always - @make -C hello - -clean: always - @for dir in $(ALL_DIRS); do make -C $$dir clean; done - -always: - @mkdir -p $(USR_BIN) \ No newline at end of file Added: src/app/wscript_build =================================================================== --- src/app/wscript_build (rev 0) +++ src/app/wscript_build 2009-03-13 11:58:23 UTC (rev 357) @@ -0,0 +1,6 @@ +#! /usr/bin/env python + +include_dirs = Options.options.usr_include +#build hello world application +hello = bld.new_task_gen('cc', 'program', target='hello', name='hello', install_path=None, includes=include_dirs, uselib='APPLICATION' ) +hello.find_sources_in_dirs('hello') Deleted: src/drivers/makefile =================================================================== --- src/drivers/makefile 2009-03-13 06:08:52 UTC (rev 356) +++ src/drivers/makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,18 +0,0 @@ -#src/drivers/makefile - -include $(ACE_ROOT)/make.conf -ALL_DIRS= pci - -all: always - @for dir in $(ALL_DIRS); do make -C $$dir all; done - -pci: always - @make -C pci - -clean: always - @for dir in $(ALL_DIRS); do make -C $$dir clean; done - -all_clean: clean - @for dir in $(ALL_DIRS); do make -C $$dir all_clean; done - -always: Deleted: src/drivers/pci/makefile =================================================================== --- src/drivers/pci/makefile 2009-03-13 06:08:52 UTC (rev 356) +++ src/drivers/pci/makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,26 +0,0 @@ -#src/drivers/pci/makefile - -include $(ACE_ROOT)/make.conf - -TARGET= $(OBJ)/pci_bus.sys -OBJS= $(patsubst %.c,%.o, $(wildcard *.c)) - -#perform partial linking -LD_FLAGS= -r - -all: $(TARGET) - -clean: always - @rm -f $(TARGET) - @rm -f $(OBJS) - -all_clean: clean - @rm -f $(OBJS:.o=.d) - -$(TARGET): $(OBJS) - @$(LD) $(LD_FLAGS) $(OBJS) -o $(TARGET) - -always: - -#create .d files --include $(OBJS:.o=.d) Added: src/drivers/wscript_build =================================================================== --- src/drivers/wscript_build (rev 0) +++ src/drivers/wscript_build 2009-03-13 11:58:23 UTC (rev 357) @@ -0,0 +1,9 @@ +#! /usr/bin/env python + +arch = Options.options.arch +include_dirs = '../include/' + +#build pci driver +pci = bld.new_task_gen('cc', 'program', target='pci', name='pci', install_path=None, includes=include_dirs, uselib='DRIVER' ) +pci.env['program_PATTERN'] = '%s.sys' +pci.find_sources_in_dirs('pci') Modified: src/include/kernel/acpi/platform/acace.h =================================================================== --- src/include/kernel/acpi/platform/acace.h 2009-03-13 06:08:52 UTC (rev 356) +++ src/include/kernel/acpi/platform/acace.h 2009-03-13 11:58:23 UTC (rev 357) @@ -128,7 +128,7 @@ //#define ACPI_NO_ERROR_MESSAGES -#ifdef __KERNEL_BUILT__ +#ifdef _KERNEL_ #include <ace.h> #include <string.h> @@ -154,8 +154,6 @@ #include <stdarg.h> #include <string.h> #include <stdlib.h> -#include <ctype.h> -#include <unistd.h> #ifndef __cdecl #define __cdecl Deleted: src/kernel/acpi/makefile =================================================================== --- src/kernel/acpi/makefile 2009-03-13 06:08:52 UTC (rev 356) +++ src/kernel/acpi/makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,42 +0,0 @@ -#kernel/acpi/makefile - -ifeq ($(ACPI_DEBUG),) - ACPI_DEBUG= -g0 -endif - -CUSTOM_FLAG= -I $(ACE_ROOT)/src/include/kernel/acpi -Wno-format $(ACPI_DEBUG) - -include $(ACE_ROOT)/make.conf - -ALL_DIRS= . debugger events hardware interpreter/dispatcher interpreter/executer namespace interpreter/parser resources tables utilities - -TARGET= $(OBJ)/acpi.a - -OBJS= $(patsubst %.c,%.o,$(wildcard *.c)) \ - $(patsubst %.c,%.o,$(wildcard events/*.c)) \ - $(patsubst %.c,%.o,$(wildcard hardware/*.c)) \ - $(patsubst %.c,%.o,$(wildcard interpreter/dispatcher/*.c)) \ - $(patsubst %.c,%.o,$(wildcard interpreter/executer/*.c)) \ - $(patsubst %.c,%.o,$(wildcard interpreter/parser/*.c)) \ - $(patsubst %.c,%.o,$(wildcard namespace/*.c)) \ - $(patsubst %.c,%.o,$(wildcard resources/*.c)) \ - $(patsubst %.c,%.o,$(wildcard tables/*.c)) \ - $(patsubst %.c,%.o,$(wildcard utilities/*.c)) - -#phony command - all - makes all object -all: $(TARGET) - -clean: always - rm -f $(TARGET) - rm -f $(OBJS) - -all_clean: clean - rm -f $(OBJS:.o=.d) - -always: - -$(TARGET): $(OBJS) - @$(AR) ru $(TARGET) $(OBJS) - -#create .d files --include $(OBJS:.o=.d) Modified: src/kernel/i386/interrupt_stub.asm =================================================================== --- src/kernel/i386/interrupt_stub.asm 2009-03-13 06:08:52 UTC (rev 356) +++ src/kernel/i386/interrupt_stub.asm 2009-03-13 11:58:23 UTC (rev 357) @@ -1,6 +1,6 @@ ; Interrupt and exception stubs -%include "kernel/i386/i386.inc" +%include "/kernel/i386/i386.inc" extern ExceptionHandler extern PageFaultHandler Deleted: src/kernel/i386/makefile =================================================================== --- src/kernel/i386/makefile 2009-03-13 06:08:52 UTC (rev 356) +++ src/kernel/i386/makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,30 +0,0 @@ -#kernel/i386/makefile - -include $(ACE_ROOT)/make.conf - -TARGET= $(OBJ)/arch.a - -ARCH_OBJ= $(patsubst %.c,%.o,$(wildcard *.c)) $(patsubst %.asm,%.o,$(wildcard *.asm)) -MM_OBJ= $(patsubst %.c,%.o,$(wildcard mm/*.c)) $(patsubst %.asm,%.o,$(wildcard mm/*.asm)) -PM_OBJ= $(patsubst %.c,%.o,$(wildcard pm/*.c)) $(patsubst %.asm,%.o,$(wildcard pm/*.asm)) -DEBUG_OBJ= $(patsubst %.c,%.o,$(wildcard debug/*.c)) $(patsubst %.asm,%.o,$(wildcard debug/*.asm)) -PIC_OBJ= $(patsubst %.c,%.o,$(wildcard pic/*.c)) $(patsubst %.asm,%.o,$(wildcard pic/*.asm)) - -OBJS= $(ARCH_OBJ) $(MM_OBJ) $(PM_OBJ) $(DEBUG_OBJ) $(PIC_OBJ) - -all: $(TARGET) - -clean: always - @rm -f $(OBJS) - -#phony - clean - clean including .d files -all_clean: clean - @rm -f $(OBJS:.o=.d) - -$(TARGET): $(OBJS) - @$(AR) ru $(TARGET) $(OBJS) - -always: - -#create .d files --include $(OBJS:.o=.d) Modified: src/kernel/i386/start.asm =================================================================== --- src/kernel/i386/start.asm 2009-03-13 06:08:52 UTC (rev 356) +++ src/kernel/i386/start.asm 2009-03-13 11:58:23 UTC (rev 357) @@ -1,7 +1,7 @@ ;Ace Kernel Startup file ;32bit Kernel gets control from multiboot loader here. -%include "kernel/i386/i386.inc" +%include "/kernel/i386/i386.inc" GLOBAL KernelEntry GLOBAL SecondaryCPUEntry Modified: src/kernel/i386/trampoline.asm =================================================================== --- src/kernel/i386/trampoline.asm 2009-03-13 06:08:52 UTC (rev 356) +++ src/kernel/i386/trampoline.asm 2009-03-13 11:58:23 UTC (rev 357) @@ -2,7 +2,7 @@ ;Copied from Linux source ;Real mode 16 bit code for starting secondary processors. -%include "kernel/i386/i386.inc" +%include "/kernel/i386/i386.inc" EXTERN SecondaryCPUEntry Deleted: src/kernel/iom/makefile =================================================================== --- src/kernel/iom/makefile 2009-03-13 06:08:52 UTC (rev 356) +++ src/kernel/iom/makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,23 +0,0 @@ -#kernel/iom/makefile - -include $(ACE_ROOT)/make.conf - -TARGET= $(OBJ)/iom.a -OBJS= $(patsubst %.c,%.o,$(wildcard *.c)) - -all: $(TARGET) - -clean: always - @rm -f *.o - -#phony - clean - clean including .d files -all_clean: clean - @rm -f *.d - -$(TARGET): $(OBJS) - @$(AR) ru $(TARGET) $(OBJS) - -always: - -#create .d files --include $(OBJS:.o=.d) Deleted: src/kernel/makefile =================================================================== --- src/kernel/makefile 2009-03-13 06:08:52 UTC (rev 356) +++ src/kernel/makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,61 +0,0 @@ -#src/kernel/makefile - -include $(ACE_ROOT)/make.conf - -#clean dirs -CLEAN_DIRS= $(ARCH) iom rtc pit acpi - -#path for the output kernel -TARGET= $(OBJ)/kernel.sys - -#libiraries used bykernel -LIBS= $(OBJ)/libheap.a $(OBJ)/libds.a $(OBJ)/libstring.a $(OBJ)/libsync.a - -#static kernel modules -STATIC_MODS= $(OBJ)/arch.a $(OBJ)/iom.a $(OBJ)/rtc.a $(OBJ)/pit.a $(OBJ)/acpi.a - -#generica kernel object files -KERNEL_OBJ = $(patsubst %.c,%.o,$(wildcard *.c)) $(patsubst %.c,%.o,$(wildcard mm/*.c)) $(patsubst %.c,%.o,$(wildcard pm/*.c)) $(patsubst %.c,%.o,$(wildcard ipc/*.c)) -#phony command - all - makes all object -all: $(TARGET) - -$(OBJ)/arch.a: always - @make -C $(ARCH) - -$(OBJ)/iom.a: always - @make -C iom - -$(OBJ)/rtc.a: always - @make -C rtc - -$(OBJ)/pit.a: always - @make -C pit - -$(OBJ)/acpi.a: - echo -n "Compiling ACPI ..." - @make -C acpi - -kernel_build_number: always - @$(INCLUDE)/version.sh $(INCLUDE) - -#phony commmand - clean - remove all .o in all directories -clean: always - @rm -f $(KERNEL_OBJ) - @for dir in $(CLEAN_DIRS); do make -C $$dir clean; done - @rm -f $(STATIC_MODS) - @rm -f $(TARGET) - -#phony commmand - all_clean - remove all .o and .d in all directories -all_clean: clean - @rm -f $(KERNEL_OBJ:.o=.d) - @for dir in $(CLEAN_DIRS); do make -C $$dir all_clean; done - -#increment the build number, link the kernel and copy the kernel to image file -$(TARGET): kernel_build_number $(KERNEL_OBJ) $(STATIC_MODS) - @$(LD) -T kernel.ld $(LDFLAGS) -Map kernel.map -o $(TARGET) $(KERNEL_OBJ) $(STATIC_MODS) $(LIBS) - @echo "New kernel is at $(TARGET)" - -#include dependency files --include $(KERNEL_OBJ:.o=.d) - -always: Deleted: src/kernel/pit/makefile =================================================================== --- src/kernel/pit/makefile 2009-03-13 06:08:52 UTC (rev 356) +++ src/kernel/pit/makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,24 +0,0 @@ -#kernel/pit/makefile - -include $(ACE_ROOT)/make.conf - -TARGET= $(OBJ)/pit.a -OBJS= $(patsubst %.c,%.o,$(wildcard *.c)) - -all: $(TARGET) - -clean: always - @rm -f $(OBJS) - -#phony - clean - clean including .d files -all_clean: clean - @rm -f $(OBJS:.o=.d) - - -$(TARGET): $(OBJS) - @$(AR) ru $(TARGET) $(OBJS) - -always: - -#create .d files --include $(OBJS:.o=.d) Deleted: src/kernel/rtc/makefile =================================================================== --- src/kernel/rtc/makefile 2009-03-13 06:08:52 UTC (rev 356) +++ src/kernel/rtc/makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,24 +0,0 @@ -#kernel/rtc/makefile - -include $(ACE_ROOT)/make.conf - -TARGET= $(OBJ)/rtc.a -OBJS= $(patsubst %.c,%.o,$(wildcard *.c)) - -all: $(TARGET) - -clean: always - @rm -f *.o - -#phony - clean - clean including .d files -all_clean: clean - @rm -f *.d - - -$(TARGET): $(OBJS) - @$(AR) ru $(TARGET) $(OBJS) - -always: - -#create .d files --include $(OBJS:.o=.d) Added: src/kernel/wscript_build =================================================================== --- src/kernel/wscript_build (rev 0) +++ src/kernel/wscript_build 2009-03-13 11:58:23 UTC (rev 357) @@ -0,0 +1,26 @@ +#! /usr/bin/env python + +arch = Options.options.arch + +if arch == 'i386': + arch_source_dirs = 'i386 i386/debug i386/mm i386/pic i386/pm ' +else: + arch_source_dirs = '' + +source_dirs = '. iom ipc mm pit pm rtc ' + arch_source_dirs +acpi_source_dirs = 'acpi acpi/events acpi/hardware acpi/interpreter/dispatcher acpi/interpreter/executer acpi/interpreter/parser acpi/namespace acpi/resources acpi/tables acpi/utilities ' + +include_dirs = '../include/' +acpi_include_dirs = include_dirs + ' ../include/kernel/acpi/' + +#build acpi +acpi = bld.new_task_gen('cc', 'staticlib', target='acpi', name='acpi', install_path=None, includes=acpi_include_dirs, uselib='ACPI') +acpi.find_sources_in_dirs(acpi_source_dirs) + +# build kernel +#bld.env['program_PATTERN'] = '%s.sys' +kernel = bld.new_task_gen('cc', 'program', target='kernel', name='kernel', install_path=None, includes=include_dirs, uselib_local='acpi ds sync string heap', uselib='KERNEL') +kernel.env['program_PATTERN'] = '%s.sys' +kernel.find_sources_in_dirs(source_dirs) + + Deleted: src/lib/ds/makefile =================================================================== --- src/lib/ds/makefile 2009-03-13 06:08:52 UTC (rev 356) +++ src/lib/ds/makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,31 +0,0 @@ -#lib/ds/makefile - -include $(ACE_ROOT)/make.conf - -#since we might use different cross compiler for Ace, for testing use the host's default compiler. -#CC = /usr/bin/gcc - -#objects for this library -OBJS = $(patsubst %.c,%.o,$(wildcard *.c)) - -#target path -TARGET= $(OBJ)/libds.a - -#phony - all - make target -all: $(TARGET) - -#phony - clean - clean all object files -clean: - @rm -f *.o - @rm -f $(TARGET) - -#phony - clean - clean including .d files -all_clean: clean - @rm -f *.d - -#how to make target -$(TARGET): $(OBJS) - @$(AR) ru $(TARGET) $(OBJS) - -#create .d files --include $(OBJS:.o=.d) Deleted: src/lib/ds/test/makefile =================================================================== --- src/lib/ds/test/makefile 2009-03-13 06:08:52 UTC (rev 356) +++ src/lib/ds/test/makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,44 +0,0 @@ -# File : lib/ds/test makefile -# Author : Samuel Jacob -# Version : 3.0 -# Created : 21-Feb-2008 13:43 -# Last modified : -# Brief : commands supported are: clean testtree testlist - -include $(ACE_ROOT)/make.conf - -#since we might use different cross compiler for Ace, for testing use the host's default compiler. -CC = /usr/bin/gcc - -CFLAGS = -Wall -Wno-multichar -funsigned-char -fno-leading-underscore -I $(INCLUDE) -g - -#phony - all - make target -all: testtree testlist testavl testsort testbits - -#phony - clean - clean all object files -clean: - @rm -f *.d *.o - @rm -f *.exe - -#how to make target -testcommon.o: testcommon.c - $(CC) $(CFLAGS) -c -o testcommon.o testcommon.c - -testtree: testcommon.o testtree.c $(OBJ)/libds.a - $(CC) $(CFLAGS) -L $(OBJ) -o testtree testtree.c testcommon.o -lds - -testlist: testlist.c $(OBJ)/libds.a - $(CC) $(CFLAGS) -L $(OBJ) -o testlist testlist.c -lds - -testavl: testcommon.o testavl.c $(OBJ)/libds.a - $(CC) $(CFLAGS) -L $(OBJ) -o testavl testavl.c testcommon.o -lds - -testsort: testsort.c $(OBJ)/libds.a - $(CC) $(CFLAGS) -L $(OBJ) -o testsort testsort.c -lds - -testbits: testbits.c $(OBJ)/libds.a - $(CC) $(CFLAGS) -L $(OBJ) -o testbits testbits.c -lds - - -#create .d files --include $(OBJS:.o=.d) Deleted: src/lib/heap/makefile =================================================================== --- src/lib/heap/makefile 2009-03-13 06:08:52 UTC (rev 356) +++ src/lib/heap/makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,31 +0,0 @@ -#lib/heap/makefile - -include $(ACE_ROOT)/make.conf - -#since we might use different cross compiler for Ace, for testing use the host's default compiler. -#CC = /usr/bin/gcc - -#objects for this library -OBJS = $(patsubst %.c,%.o,$(wildcard *.c)) - -#target path -TARGET= $(OBJ)/libheap.a - -#phony - all - make target -all: $(TARGET) - -#phony - clean - clean all object files -clean: - @rm -f *.o - @rm -f $(TARGET) - -#phony - clean - clean including .d files -all_clean: clean - @rm -f *.d - -#how to make target -$(TARGET): $(OBJS) - @$(AR) ru $(TARGET) $(OBJS) - -#create .d files --include $(OBJS:.o=.d) Deleted: src/lib/heap/test/makefile =================================================================== --- src/lib/heap/test/makefile 2009-03-13 06:08:52 UTC (rev 356) +++ src/lib/heap/test/makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,37 +0,0 @@ -# File : lib/heap/test makefile -# Author : Samuel Jacob -# Version : 3.0 -# Created : 09-Apr-2008 8:00PM -# Last modified : -# Brief : commands supported are: clean testslab testheap - -include $(ACE_ROOT)/make.conf - -#since we might use different cross compiler for Ace, for testing use the host's default compiler. -CC = /usr/bin/gcc - -CFLAGS = -Wall -Wno-multichar -funsigned-char -fno-leading-underscore -I $(INCLUDE) -g - -#phony - all - make target -all: testslab testheap - -#phony - clean - clean all object files -clean: - @rm -f *.d *.o testslab testheap - @rm -f *.exe - -#how to make target -testcommon.o: testcommon.c - $(CC) $(CFLAGS) -c -o testcommon.o testcommon.c - -leak_detector_c.o: leak_detector_c.c - $(CC) $(CFLAGS) -c -o leak_detector_c.o leak_detector_c.c - -testslab: leak_detector_c.o testcommon.o testslab.c $(OBJ)/libheap.a $(OBJ)/libds.a $(OBJ)/libsync.a - $(CC) $(CFLAGS) -L $(OBJ) -o testslab testslab.c testcommon.o leak_detector_c.o -lheap -lds -lsync - -testheap: leak_detector_c.o testcommon.o testheap.c $(OBJ)/libheap.a $(OBJ)/libds.a $(OBJ)/libsync.a - $(CC) $(CFLAGS) -L $(OBJ) -o testheap testheap.c testcommon.o leak_detector_c.o -lheap -lds -lsync - -#create .d files --include $(OBJS:.o=.d) Deleted: src/lib/makefile =================================================================== --- src/lib/makefile 2009-03-13 06:08:52 UTC (rev 356) +++ src/lib/makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,28 +0,0 @@ -#src/lib/makefile - -include $(ACE_ROOT)/make.conf - -ALL_DIRS= string ds sync heap - -all: always - @for dir in $(ALL_DIRS); do make -C $$dir all; done - -string: always - @make -C string - -ds: always - @make -C ds - -heap: always - @make -C heap - -sync: always - @make -C sync - -clean: always - @for dir in $(ALL_DIRS); do make -C $$dir clean; done - -all_clean: clean - @for dir in $(ALL_DIRS); do make -C $$dir all_clean; done - -always: Deleted: src/lib/string/makefile =================================================================== --- src/lib/string/makefile 2009-03-13 06:08:52 UTC (rev 356) +++ src/lib/string/makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,30 +0,0 @@ -#lib/string/makefile - -include $(ACE_ROOT)/make.conf - -#CC = /usr/bin/gcc - -#objects for this library -OBJS = $(patsubst %.c,%.o,$(wildcard *.c)) - -#target path -TARGET= $(OBJ)/libstring.a - -#phony - all - make target -all: $(TARGET) - -#phony - clean - clean all object files -clean: - @rm -f *.o - @rm -f $(TARGET) - -#phony - clean - clean including .d files -all_clean: clean - @rm -f *.d - -#how to make target -$(TARGET): $(OBJS) - @$(AR) ru $(TARGET) $(OBJS) - -#create .d files --include $(OBJS:.o=.d) Deleted: src/lib/string/test/makefile =================================================================== --- src/lib/string/test/makefile 2009-03-13 06:08:52 UTC (rev 356) +++ src/lib/string/test/makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,29 +0,0 @@ -# File : lib/string/test makefile -# Author : Samuel Jacob -# Version : 1.0 -# Created : 29-Apr-2008 17:10 -# Last modified : -# Brief : commands supported are: clean teststring - -include $(ACE_ROOT)/make.conf - -#since we might use different cross compiler for Ace, for testing use the host's default compiler. -CC = /usr/bin/gcc - -CFLAGS = -Wall -Wno-multichar -funsigned-char -fno-leading-underscore -I $(INCLUDE) - -#phony - all - make target -all: teststring - -#phony - clean - clean all object files -clean: - @rm -f *.d *.o - @rm -f *.exe - -#how to make target -teststring: teststring.c $(OBJ)/libstring.a - $(CC) $(CFLAGS) -L $(OBJ) -o teststring teststring.c -lstring - - -#create .d files --include $(OBJS:.o=.d) Deleted: src/lib/sync/i386/makefile =================================================================== --- src/lib/sync/i386/makefile 2009-03-13 06:08:52 UTC (rev 356) +++ src/lib/sync/i386/makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,7 +0,0 @@ -#lib/sync/i386 - -clean: - @rm -f *.o - -all_clean: clean - @rm -f *.d Deleted: src/lib/sync/makefile =================================================================== --- src/lib/sync/makefile 2009-03-13 06:08:52 UTC (rev 356) +++ src/lib/sync/makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,36 +0,0 @@ -#ds/sync/makefile - -include $(ACE_ROOT)/make.conf - -#clean dirs -CLEAN_DIRS= $(ARCH) - -#target path -TARGET= $(OBJ)/libsync.a - -#individual objects -GENERIC_OBJ = $(patsubst %.c,%.o,$(wildcard *.c)) -ARCH_OBJ = $(patsubst %.c,%.o,$(wildcard $(ARCH)/*.c)) $(patsubst %.asm,%.o,$(wildcard $(ARCH)/*.asm)) - -#all objects for this library -OBJS = $(ARCH_OBJ) $(GENERIC_OBJ) - -#phony - all - make target -all: $(TARGET) - -#phony - clean - clean all object files -clean: - @rm -f *.o - @for dir in $(CLEAN_DIRS); do make -C $$dir clean; done - @rm -f $(TARGET) - -#phony - clean - clean including .d files -all_clean: clean - @rm -f *.d - -#how to make target -$(TARGET): $(OBJS) - @$(AR) ru $(TARGET) $(OBJS) - -#create .d files --include $(OBJS:.o=.d) Deleted: src/lib/sync/test/makefile =================================================================== --- src/lib/sync/test/makefile 2009-03-13 06:08:52 UTC (rev 356) +++ src/lib/sync/test/makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,32 +0,0 @@ -# File : lib/sync/test makefile -# Author : Samuel Jacob -# Version : 3.0 -# Created : 22-Apr-2008 12:30 -# Last modified : -# Brief : commands supported are: clean testspin - -include $(ACE_ROOT)/make.conf - -#since we might use different cross compiler for Ace, for testing use the host's default compiler. -CC = /usr/bin/gcc - -CFLAGS = -Wall -Wno-multichar -funsigned-char -fno-leading-underscore -I $(INCLUDE) - -#phony - all - make target -all: testspin - -#phony - clean - clean all object files -clean: - @rm -f *.d *.o - @rm -f *.exe - -#how to make target -testcommon.o: testcommon.c - $(CC) $(CFLAGS) -c -o testcommon.o testcommon.c - -testspin: testcommon.o testspin.c $(OBJ)/libsync.a - $(CC) $(CFLAGS) -L $(OBJ) -o testspin testspin.c testcommon.o -lsync - - -#create .d files --include $(OBJS:.o=.d) Added: src/lib/wscript_build =================================================================== --- src/lib/wscript_build (rev 0) +++ src/lib/wscript_build 2009-03-13 11:58:23 UTC (rev 357) @@ -0,0 +1,20 @@ +#! /usr/bin/env python + +arch = Options.options.arch +include_dirs = '../include/' + +#build string library +string = bld.new_task_gen('cc', 'staticlib', target='string', name='string', install_path=None, includes=include_dirs) +string.find_sources_in_dirs('string') + +#build ds library +ds = bld.new_task_gen('cc', 'staticlib', target='ds', name='ds', install_path=None, includes=include_dirs) +ds.find_sources_in_dirs('ds') + +#build sync library +sync = bld.new_task_gen('cc', 'staticlib', target='sync', name='sync', install_path=None, includes=include_dirs) +sync.find_sources_in_dirs('sync sync/'+ arch ) + +#build heap library +heap = bld.new_task_gen('cc', 'staticlib', target='heap', name='heap', install_path=None, includes=include_dirs, uselib='ds, sync') +heap.find_sources_in_dirs('heap') Deleted: src/makefile =================================================================== --- src/makefile 2009-03-13 06:08:52 UTC (rev 356) +++ src/makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,27 +0,0 @@ -#src/makefile - -include $(ACE_ROOT)/make.conf -ALL_DIRS= lib drivers tools app kernel - -all: always - #do make all - @for dir in $(ALL_DIRS); do make -C $$dir all; done - #create boot cd - $(ACE_ROOT)/img/create_bootcd.sh - -lib: always - @make -C lib - -kernel: always - @make -C kernel - -tools: always - @make -C tools - -clean: always - @for dir in $(ALL_DIRS); do make -C $$dir clean; done - -all_clean: clean - @for dir in $(ALL_DIRS); do make -C $$dir all_clean; done - -always: Deleted: src/tools/makefile =================================================================== --- src/tools/makefile 2009-03-13 06:08:52 UTC (rev 356) +++ src/tools/makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,16 +0,0 @@ -#rc/tools/makefile - -include $(ACE_ROOT)/make.conf -ALL_DIRS= mc - -all: always - @for dir in $(ALL_DIRS); do make -C $$dir all; done - -clean: always - @for dir in $(ALL_DIRS); do make -C $$dir clean; done - -all_clean: always - @for dir in $(ALL_DIRS); do make -C $$dir all_clean; done - -always: - @mkdir -p $(TOOLS_BIN) Deleted: src/tools/mc/makefile =================================================================== --- src/tools/mc/makefile 2009-03-13 06:08:52 UTC (rev 356) +++ src/tools/mc/makefile 2009-03-13 11:58:23 UTC (rev 357) @@ -1,27 +0,0 @@ -#src/tools/mc/makefile - -include $(ACE_ROOT)/make.conf - -#since we might use different cross compiler for Ace, for testing use the host's default compiler. -CC = /usr/bin/gcc -CFLAGS = -Wall -Wno-multichar -funsigned-char -fno-leading-underscore -I $(INCLUDE) -gdwarf-2 -g3 - -TARGET = $(TOOLS_BIN)/mkmc -OBJS = $(patsubst %.c,%.o,$(wildcard *.c)) - -#phony - all - make target -all: $(TARGET) - -#phony - clean - clean all object files -clean: - @rm -f $(OBJS) *.exe - -all_clean: clean - @rm -f $(OBJS:.o=.d) - -#how to make target -$(TARGET): $(OBJS) - $(CC) $(CFLAGS) -o $(TARGET) mkmc.c - -#create .d files --include $(OBJS:.o=.d) Added: waf =================================================================== --- waf (rev 0) +++ waf 2009-03-13 11:58:23 UTC (rev 357) @@ -0,0 +1,131 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2005-2009 + +""" +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +""" + +import os, sys +if sys.hexversion<0x203000f: raise "Waf requires Python >= 2.3" + +if 'PSYCOWAF' in os.environ: + try:import psyco;psyco.full() + except:pass + +VERSION="1.5.3" +REVISION="e73d623754f2b6bbe230ebe613f8afde" +INSTALL=sys.platform=='win32' and 'c:/temp' or '/usr/local' +C1='#-' +C2='#(' +cwd = os.getcwd() +join = os.path.join + +def err(m): + print ('\033[91mError: %s\033[0m' % m) + sys.exit(1) + +def unpack_wafdir(dir): + f = open(sys.argv[0],'rb') + c = "corrupted waf (%d)" + while 1: + line = f.readline() + if not line: err("run waf-light from a folder containing wafadmin") + if line == '#==>\n': + txt = f.readline() + if not txt: err(c % 1) + if f.readline()!='#<==\n': err(c % 2) + break + if not txt: err(c % 3) + txt = txt[1:-1].replace(C1, '\n').replace(C2, '\r') + + import shutil, tarfile + try: shutil.rmtree(dir) + except OSError: pass + try: os.makedirs(join(dir, 'wafadmin', 'Tools')) + except OSError: err("Cannot unpack waf lib into %s\nMove waf into a writeable directory" % dir) + + os.chdir(dir) + tmp = 't.tbz2' + t = open(tmp,'wb') + t.write(txt) + t.close() + + t = tarfile.open(tmp) + for x in t: t.extract(x) + t.close() + + os.chmod(join('wafadmin','Tools'), 493) + + os.unlink(tmp) + os.chdir(cwd) + +def test(dir): + try: os.stat(join(dir, 'wafadmin')); return os.path.abspath(dir) + except OSError: pass + +def find_lib(): + name = sys.argv[0] + base = os.path.dirname(os.path.abspath(name)) + + #devs use $WAFDIR + w=test(os.environ.get('WAFDIR', '')) + if w: return w + + #waf-light + if name.endswith('waf-light'): + w = test(base) + if w: return w + err("waf-light requires wafadmin -> export WAFDIR=/folder") + + dir = "/lib/waf-%s-%s/" % (VERSION, REVISION) + for i in [INSTALL,'/usr','/usr/local','/opt']: + w = test(i+dir) + if w: return w + + #waf-local + s = '.waf-%s-%s' + if sys.platform == 'win32': s = s[1:] + dir = join(base, s % (VERSION, REVISION)) + w = test(dir) + if w: return w + + #unpack + unpack_wafdir(dir) + return dir + +wafdir = find_lib() +w = join(wafdir, 'wafadmin') +t = join(w, 'Tools') +sys.path = [w, t] + sys.path + +import Scripting +Scripting.prepare(t, cwd, VERSION, wafdir) + +#==> @@ Diff output truncated at 100000 characters. @@ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nmd...@us...> - 2009-03-13 06:09:24
|
Revision: 356 http://aceos.svn.sourceforge.net/aceos/?rev=356&view=rev Author: nmdilipsimha Date: 2009-03-13 06:08:52 +0000 (Fri, 13 Mar 2009) Log Message: ----------- resolved header file conflict. Modified Paths: -------------- src/tools/mc/mkmc.c Modified: src/tools/mc/mkmc.c =================================================================== --- src/tools/mc/mkmc.c 2009-03-12 18:25:55 UTC (rev 355) +++ src/tools/mc/mkmc.c 2009-03-13 06:08:52 UTC (rev 356) @@ -11,11 +11,15 @@ #include <sys/mman.h> #include <kernel/module.h> -#include <kernel/mm/vm.h> +//#include <kernel/mm/vm.h> int verbose = 0; char * output_file_name = "boot_modules.mod"; +/*! aligns a address to page upper boundary*/ +#define PAGE_SIZE 4096 +#define PAGE_ALIGN_UP(addr) ((UINT32)((addr) + PAGE_SIZE - 1) & -PAGE_SIZE) + void PrintUsage(char * executable) { printf("This utility will create module container for Ace kernel.\n"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nmd...@us...> - 2009-03-12 18:26:31
|
Revision: 355 http://aceos.svn.sourceforge.net/aceos/?rev=355&view=rev Author: nmdilipsimha Date: 2009-03-12 18:25:55 +0000 (Thu, 12 Mar 2009) Log Message: ----------- Modifed wait events to handle various options. Modified Paths: -------------- src/include/kernel/ipc.h src/include/kernel/pm/task.h src/include/kernel/wait_event.h src/kernel/ipc/message_queue.c src/kernel/parameter.c Modified: src/include/kernel/ipc.h =================================================================== --- src/include/kernel/ipc.h 2009-03-12 09:54:00 UTC (rev 354) +++ src/include/kernel/ipc.h 2009-03-12 18:25:55 UTC (rev 355) @@ -6,37 +6,56 @@ #ifndef IPC_H #define IPC_H +typedef struct message_queue MESSAGE_QUEUE, *MESSAGE_QUEUE_PTR; + #include <ace.h> #include <ds/list.h> #include <sync/spinlock.h> #include <kernel/system_call_handler.h> +#include <kernel/wait_event.h> #define MESSAGE_QUEUE_NO_WAIT -1 #define MESSAGE_QUEUE_CAN_WAIT 0 extern UINT32 max_message_queue_length; /* System wide tunable to control the size of message queue in task structure */ -enum MESSAGE_BUFFER_TYPE +typedef enum message_type { - MESSAGE_BUFFER_TYPE_VALUE, - MESSAGE_BUFFER_TYPE_BUFFER -}; + MESSAGE_TYPE_VALUE, + MESSAGE_TYPE_REFERENCE, + MESSAGE_TYPE_SKIP +}MESSAGE_TYPE; +#define ARG_ADDRESS_INDEX 0 +#define ARG_LENGTH_INDEX 1 +#define ARG1_INDEX 2 +#define ARG2_INDEX 3 +#define TOTAL_ARG_COUNT 4 typedef struct message_buffer { - LIST message_buffer_queue; - enum MESSAGE_BUFFER_TYPE type; /* type=0 means In VALUE; type=1 means In BUFFER */ - UINT32 args[TOTAL_SYSTEM_CALL_ARGS]; - UINT32 from_pid; + LIST message_buffer_queue; + MESSAGE_TYPE type; + UINT32 args[TOTAL_ARG_COUNT]; }MESSAGE_BUFFER, *MESSAGE_BUFFER_PTR; +struct message_queue +{ + SPIN_LOCK lock; /*! Lock to guard the entire mesage queue */ + UINT32 buf_count; /*! Number of message buffers that are present in this queue */ + MESSAGE_BUFFER_PTR msg_queue; /*! Pointer to head of the message buffer queue */ + WAIT_EVENT_PTR wait_event_msg_queue; /*! Pointer to wait event queue for message_queue variable */ + SPIN_LOCK wait_event_msg_queue_lock; /*! lock for the wait event */ +}; +ERROR_CODE SendMessage(MESSAGE_TYPE type, register unsigned int arg1, register unsigned int arg2, register unsigned int arg3, register unsigned int arg4, UINT32 pid_target_task, UINT8 queue_no, UINT32 wait_time); +ERROR_CODE SendMessageCore(MESSAGE_TYPE type, register unsigned int arg1, register unsigned int arg2, register unsigned int arg3, register unsigned int arg4, MESSAGE_QUEUE_PTR message_queue, UINT32 wait_time); +ERROR_CODE ReceiveMessage(MESSAGE_TYPE type, unsigned int *arg1, unsigned int *arg2, unsigned int *arg3, unsigned int *arg4, UINT8 queue_no, UINT32 wait_time); +ERROR_CODE ReceiveMessageCore(MESSAGE_TYPE type, unsigned int *arg1, unsigned int *arg2, unsigned int *arg3, unsigned int *arg4, MESSAGE_QUEUE_PTR message_queue, UINT32 wait_time); +UINT32 GetTotalMessageCount(MESSAGE_QUEUE_PTR msg_queue); +void SkipMessage(MESSAGE_QUEUE_PTR msg_queue); +ERROR_CODE GetNextMessageInfo(UINT32 *type, UINT32 *length, MESSAGE_QUEUE_PTR msg_queue); -#include <kernel/pm/task.h> -ERROR_CODE SendMessage(MESSAGE_BUFFER_PTR mbuf, UINT32 pid_target_task, UINT8 queue_no, UINT32 wait_time); -ERROR_CODE ReceiveMessage(MESSAGE_BUFFER_PTR mbuf, UINT8 queue_no, UINT32 wait_time); - #endif Modified: src/include/kernel/pm/task.h =================================================================== --- src/include/kernel/pm/task.h 2009-03-12 09:54:00 UTC (rev 354) +++ src/include/kernel/pm/task.h 2009-03-12 18:25:55 UTC (rev 355) @@ -14,7 +14,6 @@ #include <kernel/pm/thread.h> #include <kernel/pm/pid.h> #include <kernel/ipc.h> -#include <kernel/wait_event.h> /*\todo remove these macros and put it as tunable*/ #define TASK_CACHE_FREE_SLABS_THRESHOLD 100 @@ -36,11 +35,7 @@ THREAD_PTR thread_head; /*! threads in the same task */ - SPIN_LOCK message_queue_lock[MESSAGE_QUEUES_PER_TASK]; - MESSAGE_BUFFER_PTR message_queue[MESSAGE_QUEUES_PER_TASK]; /*! Pointer to head of the message buffer queue */ - WAIT_EVENT_PTR wait_event_message_queue[MESSAGE_QUEUES_PER_TASK]; /*! Pointer to wait event queue for message queue variable */ - SPIN_LOCK wait_event_lock[MESSAGE_QUEUES_PER_TASK]; - UINT32 message_queue_length; /*! Number of message buffers that can be present in the queue */ + MESSAGE_QUEUE message_queue[MESSAGE_QUEUES_PER_TASK]; /*! Pointer to message queue containing IPC messages */ }; extern CACHE task_cache; Modified: src/include/kernel/wait_event.h =================================================================== --- src/include/kernel/wait_event.h 2009-03-12 09:54:00 UTC (rev 354) +++ src/include/kernel/wait_event.h 2009-03-12 18:25:55 UTC (rev 355) @@ -10,7 +10,8 @@ #include <ace.h> #include <ds/list.h> -#include <kernel/pm/task.h> +//#include <kernel/pm/task.h> +/* This is to avoid circular dependency in header files. Just don't use THREAD_PTR in this file, but use struct thread* instead. */ #define WAIT_EVENT_WAKE_UP_ALL 1 @@ -19,7 +20,7 @@ struct wait_event { - THREAD_PTR thread; /*Pointer to thread which is waiting on this event */ + struct thread *thread; /*Pointer to thread which is waiting on this event */ BYTE fired; /* Indicates if this event got fired(1) or just got removedi(0) because soe other related event fired */ LIST in_queue; /*List of events in this queue bucket. Each of these events will point to different threads. */ LIST thread_events; /* List of events which belong to same thread */ Modified: src/kernel/ipc/message_queue.c =================================================================== --- src/kernel/ipc/message_queue.c 2009-03-12 09:54:00 UTC (rev 354) +++ src/kernel/ipc/message_queue.c 2009-03-12 18:25:55 UTC (rev 355) @@ -9,21 +9,20 @@ #include <string.h> #include <kernel/debug.h> -UINT32 max_message_queue_length; /* System wide tunable to control the size of message queue in task structure */ +UINT32 max_message_queue_length; /* System wide tunable to control the size of message queue in message_queue structure */ -/*! \brief Sends a message from current task to the task specified. Holds target task's message queue lock accross the life time of function. - * If flag contains NO_WAIT, then this will return with error if queue is full. By default it will wait indefinitely until it places the message on the queue. - * \param mbuf Contains Message buffer. - * \param pid_target_task_task Pid of target task to which the message has to be posted. - * \param queue_no Offset to task->message_queue array. - * \param wait_time Indicates how much time the sender can wait till the message is sent. +/*! \brief Wrapper to SendMessageCore. + * \param type Indicates message type as ByValue or ByReference + * \param arg1 Pointer to data buffer in user space of size atleast *arg2 or arg1(ByValue). + * \param arg2 Length of message that needs to be copied or arg2(ByValue). + * \param arg3 Store to hold optional arg1 or arg3(ByValue) + * \param arg4 Store to hold optional arg2 or arg4(ByValue) + * \param pid_target_task Pid of target task to which the message has to be posted. + * \param queue_no Offset to task->message_queue array. + * \param wait_time Indicates how much time the sender can wait till the message is sent. */ -ERROR_CODE SendMessage(MESSAGE_BUFFER_PTR mbuf, UINT32 pid_target_task, UINT8 queue_no, UINT32 wait_time) +ERROR_CODE SendMessage(MESSAGE_TYPE type, register unsigned int arg1, register unsigned int arg2, register unsigned int arg3, register unsigned int arg4, UINT32 pid_target_task, UINT8 queue_no, UINT32 wait_time) { - MESSAGE_BUFFER_PTR kern_msg_buf; - ERROR_CODE error_ret = ERROR_SUCCESS;; - WAIT_EVENT_PTR my_wait_event; - int loop; TASK_PTR to_task; assert(queue_no < MESSAGE_QUEUES_PER_TASK); @@ -31,136 +30,269 @@ to_task = PidToTask(pid_target_task); if(to_task == NULL) return ERROR_INVALID_PARAMETER; - SpinLock( &(to_task->message_queue_lock[queue_no]) ); + return SendMessageCore(type, arg1, arg2, arg3, arg4, &(to_task->message_queue[queue_no]), wait_time); +} - if( (wait_time == MESSAGE_QUEUE_NO_WAIT) && (to_task->message_queue_length >= max_message_queue_length) ) +/*! \brief Sends a message from current task to the message queue specified. Holds target message queue's lock accross the life time of function. + * If wait_time contains NO_WAIT, then this will return with error if queue is full. By default it will wait indefinitely until it places the message on the queue. + * \param type Indicates message type as ByValue or ByReference + * \param arg1 Pointer to data buffer in user space of size atleast *arg2. + * \param arg2 Length of message that needs to be copied. + * \param arg3 Store to hold optional argument1 + * \param arg4 Store to hold optional argument2 + + * \param message_queue Pointer to target message queue, where the message has to be delivered. + * \param wait_time Indicates how much time the sender can wait till the message is sent. + */ +ERROR_CODE SendMessageCore(MESSAGE_TYPE type, register unsigned int arg1, register unsigned int arg2, register unsigned int arg3, register unsigned int arg4, MESSAGE_QUEUE_PTR message_queue, UINT32 wait_time) +{ + MESSAGE_BUFFER_PTR kern_msg_buf; + ERROR_CODE error_ret = ERROR_SUCCESS;; + WAIT_EVENT_PTR my_wait_event; + UINT32 ret_time; + WAIT_EVENT_PTR wait_queue; + SPIN_LOCK_PTR wait_lock; + + if(message_queue == NULL) + return ERROR_INVALID_PARAMETER; + + SpinLock( &(message_queue->lock) ); + + /*Sending this message depends on queue length and wait time */ + if(message_queue->buf_count >= max_message_queue_length) { - SpinUnlock( &(to_task->lock) ); - return ERROR_NOT_ENOUGH_MEMORY; - } - else if( (wait_time == MESSAGE_QUEUE_CAN_WAIT) && (to_task->message_queue_length >= max_message_queue_length) ) - { - /* Wait for this message queue to become thin */ - my_wait_event = AddToEventQueue( &(to_task->wait_event_message_queue[queue_no]) ); - SpinUnlock( &(to_task->message_queue_lock[queue_no]) ); /* We need to unlock because we block in WaitForEvent */ - WaitForEvent(my_wait_event, wait_time); - SpinLock( &(to_task->message_queue_lock[queue_no]) ); /* take the lock again because we have returned from blocked state */ - assert(my_wait_event->fired == 1); - kfree(my_wait_event); - } + if( wait_time == MESSAGE_QUEUE_NO_WAIT ) + { + SpinUnlock( &(message_queue->lock) ); + return ERROR_NOT_ENOUGH_MEMORY; + } + else if( wait_time != MESSAGE_QUEUE_NO_WAIT ) + { + wait_queue = message_queue->wait_event_msg_queue; + wait_lock = &(message_queue->wait_event_msg_queue_lock); + /* Wait for this message queue to become thin */ + SpinLock( wait_lock ); + my_wait_event = AddToEventQueue( &wait_queue ); + SpinUnlock( wait_lock ); + if(wait_time == MESSAGE_QUEUE_CAN_WAIT) + wait_time = 0; + + SpinUnlock( &(message_queue->lock) ); + ret_time = WaitForEvent(my_wait_event, wait_time); + SpinLock( &(message_queue->lock) ); /* take the lock again because we have returned from blocked state */ + + if(ret_time == 0) /* no event fired and we timeout out */ + { + SpinUnlock( &(message_queue->lock) ); + return ERROR_NOT_ENOUGH_MEMORY; + } + + assert(my_wait_event->fired == 1); + + SpinLock( wait_lock ); + RemoveEventFromQueue( my_wait_event, &wait_queue); + SpinUnlock( wait_lock ); + + kfree(my_wait_event); + } + } kern_msg_buf = (MESSAGE_BUFFER_PTR)kmalloc(sizeof(MESSAGE_BUFFER), KMEM_NO_FAIL); - kern_msg_buf->from_pid = GET_CURRENT_PID(); InitList( &(kern_msg_buf->message_buffer_queue) ); + kern_msg_buf->type = type; - switch( mbuf->type) + switch(type) { - case MESSAGE_BUFFER_TYPE_VALUE: /* In value */ - for(loop=0 ; loop < TOTAL_SYSTEM_CALL_ARGS ; loop++) - kern_msg_buf->args[loop] = mbuf->args[loop]; + case MESSAGE_TYPE_VALUE: /* In value */ + kern_msg_buf->args[0] = arg1; + kern_msg_buf->args[1] = arg2; + kern_msg_buf->args[2] = arg3; + kern_msg_buf->args[3] = arg4; break; - case MESSAGE_BUFFER_TYPE_BUFFER: /* In buffers. Copy the message inside buffer from this user space to target user space */ - /* args[0] will contain start address and args[1] will contain length of the buffer. */ - if(mbuf->args[0] == NULL || mbuf->args[1] < 0 || mbuf->args[1] > PAGE_SIZE) + case MESSAGE_TYPE_REFERENCE: /* In buffers. Copy the message inside buffer from this user space to target user space */ + /* args[0] will contain start address and args[1] will contain length of the buffer. args[2] and args[3] contain optional storage for values */ + if(arg1 == NULL || arg2 < 0 || arg2 > PAGE_SIZE) return ERROR_INVALID_PARAMETER; - kern_msg_buf->args[0] = (UINT32)kmalloc(mbuf->args[1], KMEM_NO_FAIL); - (void)memcpy((void*)kern_msg_buf->args[0], (const void*)(mbuf->args[0]), mbuf->args[1]); + + kern_msg_buf->args[ARG_ADDRESS_INDEX] = (UINT32)kmalloc(arg2, KMEM_NO_FAIL); + (void)memcpy((void*)kern_msg_buf->args[ARG_ADDRESS_INDEX], (const void*)(arg1), arg2); + kern_msg_buf->args[ARG_LENGTH_INDEX] = arg2; + + /* Copy optional values in last 2 arguments */ + kern_msg_buf->args[ARG1_INDEX] = arg3; + kern_msg_buf->args[ARG2_INDEX] = arg4; break; default: return ERROR_INVALID_PARAMETER; } - AddToListTail( &(to_task->message_queue[queue_no]->message_buffer_queue), &(kern_msg_buf->message_buffer_queue) ); - SpinUnlock( &(to_task->lock) ); + if(message_queue->msg_queue == NULL) + message_queue->msg_queue = kern_msg_buf; + else + AddToListTail( &(message_queue->msg_queue->message_buffer_queue), &(kern_msg_buf->message_buffer_queue) ); + + message_queue->buf_count++; + SpinUnlock( &(message_queue->lock) ); return error_ret; } /*! \brief Receives a message present in the tasks's message queue. * Holds task lock accross the life time of function. - * \param mbuf Pointer to an empty message buffer allocated(malloced) by user. This will be loaded with the required message. mbuf->type will be specified from user. depending on this mbuf->args[0] and mbuf->args[1] will also be filled by user. + * \param type Indicates message type as ByValue or ByReference + * \param arg1 Pointer to data buffer in user space of size atleast *arg2. + * \param arg2 Length of message that needs to be copied. + * \param arg3 Store to hold optional argument1 + * \param arg4 Store to hold optional argument2 + * \param queue_no This is the index into message_queue array in task structure. * \param wait_time Time in seconds that the user wants to wait for the message. If 0, then it's non blocking, if -1, it's blocking forever. */ -ERROR_CODE ReceiveMessage(MESSAGE_BUFFER_PTR mbuf, UINT8 queue_no, UINT32 wait_time) +ERROR_CODE ReceiveMessage(MESSAGE_TYPE type, unsigned int *arg1, unsigned int *arg2, unsigned int *arg3, unsigned int *arg4, UINT8 queue_no, UINT32 wait_time) { - MESSAGE_BUFFER_PTR message_queue_ptr; - ERROR_CODE error_ret = ERROR_SUCCESS;; TASK_PTR my_task; - WAIT_EVENT_PTR my_wait_event; - UINT32 ret_timeout, loop; if(queue_no > MESSAGE_QUEUES_PER_TASK) return ERROR_INVALID_PARAMETER; my_task = GetCurrentThread()->task; - SpinLock( &(my_task->message_queue_lock[queue_no]) ); + return ReceiveMessageCore(type, arg1, arg2, arg3, arg4, &(my_task->message_queue[queue_no]), wait_time); +} - message_queue_ptr = my_task->message_queue[queue_no]; - if(wait_time==MESSAGE_QUEUE_CAN_WAIT) /* Wait till the desired message arrives */ +/*! \brief Receives a message present in the tasks's message queue. + * Holds task lock accross the life time of function. + * \param type Indicates message type as ByValue or ByReference + * \param arg1 Pointer to data buffer in user space of size atleast *arg2. + * \param arg2 Length of message that needs to be copied. + * \param arg3 Store to hold optional argument1 + * \param arg4 Store to hold optional argument2 + * \param message_queue Pointer to message queue from where message has to be fetched + * \param wait_time Time in seconds that the user wants to wait for the message. If 0, then it's non blocking, if -1, it's blocking forever. + */ +ERROR_CODE ReceiveMessageCore(MESSAGE_TYPE type, unsigned int *arg1, unsigned int *arg2, unsigned int *arg3, unsigned int *arg4, MESSAGE_QUEUE_PTR message_queue, UINT32 wait_time) +{ + WAIT_EVENT_PTR my_wait_event, wait_queue; + UINT32 ret_time; + MESSAGE_BUFFER_PTR rem_buf; + SPIN_LOCK_PTR wait_lock; + + if(message_queue == NULL) + return ERROR_INVALID_PARAMETER; + + SpinLock( &(message_queue->lock) ); + + if(message_queue->buf_count == 0) { - if(message_queue_ptr == NULL) + if(wait_time == MESSAGE_QUEUE_NO_WAIT) + return ERROR_NOT_FOUND; + else /* Wait till the desired message arrives for time specified in wait_time */ { - SpinUnlock( &(my_task->message_queue_lock[queue_no]) ); - my_wait_event = AddToEventQueue( &(my_task->wait_event_message_queue[queue_no]) ); - WaitForEvent(my_wait_event, 0); /* block forever until some message arrives */ - SpinLock( &(my_task->message_queue_lock[queue_no]) ); /* take the lock after returning from blocked state */ + wait_queue = message_queue->wait_event_msg_queue; + wait_lock = &(message_queue->wait_event_msg_queue_lock); + + SpinLock( wait_lock ); + my_wait_event = AddToEventQueue( &wait_queue ); + SpinUnlock( wait_lock ); + + if(wait_time == MESSAGE_QUEUE_CAN_WAIT) + wait_time = 0; + + SpinUnlock( &(message_queue->lock) ); + ret_time = WaitForEvent(my_wait_event, wait_time); /* Block till wait_time expires or until timer expires */ + SpinLock( &(message_queue->lock) ); + + if(ret_time == 0) /* timeout happened and our event didn't get fired */ + { + SpinUnlock( &(message_queue->lock) ); + return ERROR_NOT_FOUND; + } + + assert(my_wait_event->fired == 1 && message_queue->buf_count > 0); + + SpinLock( wait_lock); + RemoveEventFromQueue(my_wait_event, &wait_queue); + SpinUnlock( wait_lock); + /* we have got the message, so can continue fetching it */ } } - else if(wait_time==MESSAGE_QUEUE_NO_WAIT) - { - if(message_queue_ptr == NULL) - { - SpinUnlock( &(my_task->message_queue_lock[queue_no]) ); - return ERROR_NOT_FOUND; - } - } - else /* wait_time > 0 */ - { - search_queue: - if(message_queue_ptr == NULL) - { - if(wait_time < 0) - { - SpinUnlock( &(my_task->message_queue_lock[queue_no]) ); - return ERROR_NOT_FOUND; /* In case of missed wakeup's from WaitForEvent, wait time will be in -ve */ - } - my_wait_event = AddToEventQueue( &(my_task->wait_event_message_queue[queue_no]) ); - SpinUnlock( &(my_task->message_queue_lock[queue_no]) ); - ret_timeout = WaitForEvent(my_wait_event, wait_time); /* Block till wait_time expires or until any message arrives */ - if(ret_timeout == 0 || my_task->wait_event_message_queue[queue_no] == NULL) /* timeout happened and our event didn't get fired */ - return ERROR_NOT_FOUND; - else if(wait_time-ret_timeout > 0) /* ret_timeout is > 0 and < wait_time and indicates time left in sleep */ - { - assert(my_wait_event->fired == 1); - /* we got here because an even got fired before the timeout happened */ - SpinLock( &(my_task->message_queue_lock[queue_no]) ); - message_queue_ptr = my_task->message_queue[queue_no]; - wait_time -= ret_timeout; - goto search_queue; - } - /* we have got the message, so can continue fetching it */ - SpinLock( &(my_task->message_queue_lock[queue_no]) ); /* take the lock after returning from blocked state */ - } - } + rem_buf = message_queue->msg_queue; + message_queue->buf_count--; + + if(message_queue->buf_count == 0) + message_queue->msg_queue = NULL; + else + message_queue->msg_queue = STRUCT_ADDRESS_FROM_MEMBER((rem_buf->message_buffer_queue).next, MESSAGE_BUFFER, message_buffer_queue); - RemoveFromList( &(message_queue_ptr->message_buffer_queue) ); + RemoveFromList( &(rem_buf->message_buffer_queue) ); - switch(mbuf->type) + switch(type) { - case MESSAGE_BUFFER_TYPE_VALUE: /* In value */ - for(loop=0 ; loop < TOTAL_SYSTEM_CALL_ARGS ; loop++) - mbuf->args[loop] = message_queue_ptr->args[loop]; + case MESSAGE_TYPE_SKIP: + break; + case MESSAGE_TYPE_VALUE: /* In value */ + if(arg1 == NULL || arg2 == NULL || arg3 == NULL || arg4 == NULL) + return ERROR_INVALID_PARAMETER; + + *arg1 = rem_buf->args[0]; + *arg2 = rem_buf->args[1]; + *arg3 = rem_buf->args[2]; + *arg4 = rem_buf->args[3]; break; - case MESSAGE_BUFFER_TYPE_BUFFER: /* In buffers. Copy the message inside buffer from this user space to target user space */ - (void)memcpy((void*)(mbuf->args[0]), (const void*)message_queue_ptr->args[0], mbuf->args[1]); + case MESSAGE_TYPE_REFERENCE: /* In buffers. Copy the message inside buffer from this user space to target user space */ + if(arg1 == NULL || arg2 == NULL || arg3 == NULL || arg4 == NULL || (arg2!=NULL && *arg2 < 0) ) + return ERROR_INVALID_PARAMETER; + + (void)memcpy((void*)(*arg1), (const void*)rem_buf->args[ARG_ADDRESS_INDEX], *arg2); + /* Copy values in last 2 arguments */ + *arg3 = rem_buf->args[ARG1_INDEX]; + *arg4 = rem_buf->args[ARG2_INDEX]; break; } - SpinUnlock( &(my_task->message_queue_lock[queue_no]) ); - return error_ret; + kfree(rem_buf); + SpinUnlock( &(message_queue->lock) ); + return ERROR_SUCCESS; } + +UINT32 GetTotalMessageCount(MESSAGE_QUEUE_PTR msg_queue) +{ + return msg_queue->buf_count; +} + +void SkipMessage(MESSAGE_QUEUE_PTR msg_queue) +{ + ReceiveMessageCore(MESSAGE_TYPE_SKIP, NULL, NULL, NULL, NULL, msg_queue, MESSAGE_QUEUE_NO_WAIT); +} + + +ERROR_CODE GetNextMessageInfo(UINT32 *type, UINT32 *length, MESSAGE_QUEUE_PTR msg_queue) +{ + MESSAGE_BUFFER_PTR my_buf; + + if(msg_queue == NULL) + return ERROR_INVALID_PARAMETER; + + SpinLock( &(msg_queue->lock) ); + + if(msg_queue->buf_count <= 1) + { + SpinUnlock( &(msg_queue->lock) ); + return ERROR_NOT_FOUND; + } + + my_buf = STRUCT_ADDRESS_FROM_MEMBER( (msg_queue->msg_queue->message_buffer_queue).next, MESSAGE_BUFFER, message_buffer_queue ); + if(my_buf == msg_queue->msg_queue) + { + kprintf("message_queue=%p buf_count=%d\n", msg_queue, msg_queue->buf_count); + SpinUnlock( &(msg_queue->lock) ); + panic("GetNextMessageInfo: message queue garbled\n"); + } + + *type = my_buf->type; + *length = my_buf->args[3]; + return ERROR_SUCCESS; +} Modified: src/kernel/parameter.c =================================================================== --- src/kernel/parameter.c 2009-03-12 09:54:00 UTC (rev 354) +++ src/kernel/parameter.c 2009-03-12 18:25:55 UTC (rev 355) @@ -18,11 +18,14 @@ static COMPARISION_RESULT compare_kernel_parameter(char * data1, char * data2); static KERNEL_PARAMETER_PTR FindKernelParameter(char * parameter_name); +extern UINT32 max_message_queue_length; + /*! global kernel parameters*/ static KERNEL_PARAMETER kernel_parameters[] = { {"gdb_port", &sys_gdb_port, UINT32Validator, {0, 0xFFFF, 0}, UINT32Assignor, NULL}, {"kmem_reserved_mem_size", &kmem_reserved_mem_size, UINT32Validator, {0, 1024*1024*1024, 0}, UINT32Assignor, NULL}, - {"limit_pmem", &limit_physical_memory, UINT32Validator, {8, (UINT32)4*1024*1024, 0}, UINT32Assignor, NULL} + {"limit_pmem", &limit_physical_memory, UINT32Validator, {8, (UINT32)4*1024*1024, 0}, UINT32Assignor, NULL}, + {"max_message_queue_length", &max_message_queue_length, UINT32Validator, {0, 1024, 0}, UINT32Assignor, NULL} }; /*! Initializes the kernel parameter*/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nmd...@us...> - 2009-03-12 09:54:14
|
Revision: 354 http://aceos.svn.sourceforge.net/aceos/?rev=354&view=rev Author: nmdilipsimha Date: 2009-03-12 09:54:00 +0000 (Thu, 12 Mar 2009) Log Message: ----------- applied dos2unix to remove unnecessary extra characters. Modified Paths: -------------- src/kernel/iom/iom.c Modified: src/kernel/iom/iom.c =================================================================== --- src/kernel/iom/iom.c 2009-03-07 08:20:55 UTC (rev 353) +++ src/kernel/iom/iom.c 2009-03-12 09:54:00 UTC (rev 354) @@ -1,393 +1,393 @@ -/*! - \file kernel/iom/iom.c - \brief Ace IO Manager. -*/ -#include <ace.h> -#include <string.h> -#include <kernel/debug.h> -#include <kernel/module.h> -#include <kernel/mm/kmem.h> +/*! + \file kernel/iom/iom.c + \brief Ace IO Manager. +*/ +#include <ace.h> +#include <string.h> +#include <kernel/debug.h> +#include <kernel/module.h> +#include <kernel/mm/kmem.h> #include <kernel/pm/elf.h> -#include <kernel/iom/iom.h> - -#define DEVICE_OBJECT_CACHE_FREE_SLABS_THRESHOLD 10 -#define DEVICE_OBJECT_CACHE_MIN_BUFFERS 10 -#define DEVICE_OBJECT_CACHE_MAX_SLABS 10 - -#define DRIVER_OBJECT_CACHE_FREE_SLABS_THRESHOLD 5 -#define DRIVER_OBJECT_CACHE_MIN_BUFFERS 5 -#define DRIVER_OBJECT_CACHE_MAX_SLABS 5 - -#define IRP_CACHE_FREE_SLABS_THRESHOLD 50 -#define IRP_CACHE_MIN_BUFFERS 50 -#define IRP_CACHE_MAX_SLABS 50 - -static ERROR_CODE DummyMajorFunction(DEVICE_OBJECT_PTR pDeviceObject, IRP_PTR pIrp); - -/*! List of drivers loaded into the kernel address space */ -LIST_PTR driver_list_head = NULL; - -/*! cache for driver and device*/ -CACHE driver_object_cache; -CACHE device_object_cache; -/*! cache for irps*/ -CACHE irp_cache; - -static DRIVER_OBJECT_PTR LoadDriver(char * device_id); - -/*! Internal function used to initialize the driver object structure*/ -int DriverObjectCacheConstructor( void * buffer) -{ - int i; - DRIVER_OBJECT_PTR dop = (DRIVER_OBJECT_PTR) buffer; - - memset(dop, 0, sizeof(DRIVER_OBJECT) ); - - InitList( &dop->driver_list ); - InitSpinLock( &dop->lock ); - for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++) - dop->fn.MajorFunctions[i] = DummyMajorFunction; - - return 0; -} -/*! Internal function used to clear the driver object structure*/ -int DriverObjectCacheDestructor( void *buffer) -{ - DriverObjectCacheConstructor( buffer ); - return 0; -} -/*! Internal function used to initialize the device object structure*/ -int DeviceObjectCacheConstructor( void *buffer) -{ - DEVICE_OBJECT_PTR dop = (DEVICE_OBJECT_PTR) buffer; - - memset(buffer, 0, sizeof(DEVICE_OBJECT) ); - - InitSpinLock( &dop->lock ); - InitList( &dop->sibilings_list ); - InitList( &dop->device_object_list ); - - dop->stack_count = 1; - - return 0; -} - -/*! Internal function used to clear the device object structure*/ -int DeviceObjectCacheDestructor( void *buffer) -{ - DeviceObjectCacheConstructor( buffer ); - return 0; -} - -/*! Internal function used to initialize the IRP structure*/ -int IrpCacheConstructor( void * buffer) -{ - memset(buffer, 0, sizeof(IRP) ); - - return 0; -} - -/*! Internal function used to initialize the IRP structure*/ -int IrpCacheDestructor( void * buffer) -{ - IrpCacheConstructor(buffer); - - return 0; -} - -/*! Initialize IO manager and start required boot drivers*/ -void InitIoManager() -{ - DRIVER_OBJECT_PTR root_bus; - - if( InitCache(&driver_object_cache, sizeof(DRIVER_OBJECT), DRIVER_OBJECT_CACHE_FREE_SLABS_THRESHOLD, DRIVER_OBJECT_CACHE_MIN_BUFFERS, DRIVER_OBJECT_CACHE_MAX_SLABS, DriverObjectCacheConstructor, DriverObjectCacheDestructor) ) - panic("InitIoManager - Driver object cache init failed"); - - if( InitCache(&device_object_cache, sizeof(DEVICE_OBJECT), DEVICE_OBJECT_CACHE_FREE_SLABS_THRESHOLD, DEVICE_OBJECT_CACHE_MIN_BUFFERS, DEVICE_OBJECT_CACHE_MAX_SLABS, DeviceObjectCacheConstructor, DeviceObjectCacheDestructor) ) - panic("InitIoManager - Device object cache init failed"); - - if( InitCache(&irp_cache, sizeof(IRP), IRP_CACHE_FREE_SLABS_THRESHOLD, IRP_CACHE_MIN_BUFFERS, IRP_CACHE_MAX_SLABS, IrpCacheConstructor, IrpCacheDestructor) ) - panic("InitIoManager - IRP cache init failed"); - - /*load root bus driver and call the DriverEntry*/ - root_bus = LoadRootBusDriver() ; - RootBusDriverEntry( root_bus ); - - /*this is the first driver loaded into the kernel and it is never unloaded*/ - driver_list_head = &root_bus->driver_list; - - /*create device object for root bus*/ - CreateDevice(root_bus_driver_object, 0, &root_bus_device_object); - - /*force the io manager to enumerate the buses on root bus*/ - InvalidateDeviceRelations(root_bus_device_object, DEVICE_RELATIONS_TYPE_BUS_RELATION); - -} - -/*! Dummy Major function handler - used to initialize driver object function pointers - Just returns failure -*/ -static ERROR_CODE DummyMajorFunction(DEVICE_OBJECT_PTR pDeviceObject, IRP_PTR pIrp) -{ - assert( pDeviceObject != NULL ); - assert( pIrp != NULL ); - - pIrp->io_status.status = ERROR_NOT_SUPPORTED; - - return ERROR_NOT_SUPPORTED; -} - -/*! Returns the current IO Stack location associated with the given IRP - \param irp - interrupt request packet - \return Current IO stack location on the given irp -*/ -IO_STACK_LOCATION_PTR GetCurrentIrpStackLocation(IRP_PTR Irp) -{ - return Irp->current_stack_location; -} - -/*! Returns the next lower level IO Stack location associated with the given IRP - \param irp - interrupt request packet - \return Next IO stack loation on the given irp. -*/ -IO_STACK_LOCATION_PTR GetNextIrpStackLocation(IRP_PTR Irp) -{ - assert( Irp->current_stack >0 && Irp->current_stack < Irp->stack_count ); - return Irp->current_stack_location-1; -} -/*! Creates a device object for use by the driver - \param driver_object - caller's driver object - this is used by io manager to link the created device with the driver - \param device_extension_size - size of the device_externsion - io manager allocates this much byte in the device_object - \param device_object - pointer to device object - io manager updates this pointer with the newly created device object -*/ -ERROR_CODE CreateDevice(DRIVER_OBJECT_PTR driver_object, UINT32 device_extension_size, DEVICE_OBJECT_PTR * device_object) -{ - DEVICE_OBJECT_PTR dob; - assert( device_object != NULL ); - - dob = AllocateBuffer( &device_object_cache, CACHE_ALLOC_SLEEP ); - if ( dob == NULL ) - return ERROR_NOT_ENOUGH_MEMORY; - dob->driver_object = driver_object; - if ( device_extension_size ) - dob->device_extension = kmalloc( device_extension_size, KMEM_NO_FAIL ); - - /*add to the driver's device list*/ - if ( driver_object->device_object_head == NULL ) - driver_object->device_object_head = dob; - else - AddToListTail( &driver_object->device_object_head->device_object_list, &dob->device_object_list ); - - *device_object = dob; - return ERROR_SUCCESS; -} - -/*! Links the given source device to target device at higher level, such that any IRP passed to source device can be passed down to target_device - \param source_device - parent device - \param target_device - child device - \return parent device -*/ -DEVICE_OBJECT_PTR AttachDeviceToDeviceStack(DEVICE_OBJECT_PTR source_device, DEVICE_OBJECT_PTR target_device) -{ - DEVICE_OBJECT_PTR parent_device = target_device; - - assert( source_device->parent_device == NULL ); - - if( target_device->child_device == NULL ) - { - /*if this is the first child, set the child_device pointer*/ - target_device->child_device = source_device; - } - else - { - /*target device already has a one or more child devices, so add this device to the tail*/ - AddToListTail(&target_device->child_device->sibilings_list, &source_device->sibilings_list ); - } - /*set the source device's parent*/ - source_device->parent_device = parent_device; - source_device->stack_count = parent_device->stack_count+1; - return parent_device; -} - -/*! Invalidates the device relations, so that IO manager will Query the driver for new relations - \param device_object - device object on which relations should be invalidates - \param type - type of the invalidation -*/ -void InvalidateDeviceRelations(DEVICE_OBJECT_PTR device_object, DEVICE_RELATION_TYPE type) -{ - DEVICE_RELATIONS_PTR dr; - IRP_PTR irp; - int i; - - assert( device_object!= NULL ); - /*bus relations*/ - if( type == DEVICE_RELATIONS_TYPE_BUS_RELATION ) - { - /*todo - build existing device relations*/ - - /*send query relation irp to the driver*/ - irp = AllocateIrp( device_object->stack_count ); - FillIoStack( irp->current_stack_location, IRP_MJ_PNP, IRP_MN_QUERY_DEVICE_RELATIONS, device_object, NULL, NULL); - irp->current_stack_location->parameters.query_device_relations.type = DEVICE_RELATIONS_TYPE_BUS_RELATION; - CallDriver(device_object, irp); - if ( irp->io_status.status != ERROR_SUCCESS ) - goto done; - dr = (DEVICE_RELATIONS_PTR)irp->io_status.information; - /**/ - for(i=0; i<dr->count; i++) - { - /*\todo - if the device is not new - continue*/ - - /*send query id irp for each new device to the driver*/ - ReuseIrp( irp, ERROR_NOT_SUPPORTED ); - FillIoStack( irp->current_stack_location, IRP_MJ_PNP, IRP_MN_QUERY_ID, dr->objects[i], NULL, NULL ); - irp->current_stack_location->parameters.query_id.id_type = BUS_QUERY_DEVICE_ID; - CallDriver( dr->objects[i] , irp); - if( irp->io_status.status == ERROR_SUCCESS ) - { - DRIVER_OBJECT_PTR driver_object = LoadDriver(irp->io_status.information); - if ( driver_object != NULL ) - { - driver_object->fn.AddDevice( driver_object, dr->objects[i] ); - } - /*free driver id*/ - kfree( irp->io_status.information ); - } - } - /*free the device relation struture*/ - kfree( dr ); - } -done: - FreeIrp(irp); -} - -/*! Allocates a Irp for the use of driver - \param stack_size - number of stacks assoicated with this irp - \return irp -*/ -IRP_PTR AllocateIrp(BYTE stack_size) -{ - IRP_PTR irp; - - assert( stack_size>0 ); - /*! allocate irp and io stack*/ - irp = AllocateBuffer( &irp_cache, CACHE_ALLOC_SLEEP ); - if ( irp == NULL ) - return NULL; - irp->current_stack_location = kmalloc( sizeof(IO_STACK_LOCATION)*stack_size, KMEM_NO_FAIL ); - - irp->stack_count = stack_size; - irp->io_status.status = ERROR_NOT_SUPPORTED; - - return irp; -} - -/*! Frees a irp - \param irp - pointer to irp to be freed -*/ -void FreeIrp(IRP_PTR irp) -{ - assert( irp != NULL ); - - kfree( irp->current_stack_location ); - FreeBuffer( irp, &irp_cache ); -} - -/*! Reuses a already allocated Irp - \param irp - pointer to irp - \param error_code - Io status will be set with this error code -*/ -void ReuseIrp(IRP_PTR irp, ERROR_CODE error_code) -{ - BYTE stack_size; - IO_STACK_LOCATION_PTR io_stack; - - assert( irp != NULL ); - - stack_size = irp->stack_count; - io_stack = irp->current_stack_location; - - IrpCacheConstructor( irp ); - - irp->current_stack_location = io_stack; - irp->stack_count = stack_size; - irp->io_status.status = error_code; -} - -/*! Dispatches a call to driver based on the given Irp - \param device_object - device object - \param irp - irp -*/ -ERROR_CODE CallDriver(DEVICE_OBJECT_PTR device_object, IRP_PTR irp) -{ - assert( device_object != NULL ); - assert( irp != NULL ); - - device_object->driver_object->fn.MajorFunctions[irp->current_stack_location->major_function](device_object, irp); - return ERROR_SUCCESS; -} - -/*Helper routine to fill a Io Stack with given information*/ -inline void FillIoStack(IO_STACK_LOCATION_PTR io_stack, BYTE major_function, BYTE minor_function, DEVICE_OBJECT_PTR device_object, IO_COMPLETION_ROUTINE completion_routine, void * context) -{ - assert( io_stack ); - io_stack->major_function = major_function; - io_stack->minor_function = minor_function; - io_stack->device_object = device_object; - io_stack->completion_routine = completion_routine; - io_stack->context = context; -} - -/*! Loads a driver*/ -static DRIVER_OBJECT_PTR LoadDriver(char * device_id) -{ - char * driver_file_name; - void * driver_start_address; - DRIVER_OBJECT_PTR driver_object; - ERROR_CODE (*DriverEntry)(DRIVER_OBJECT_PTR pDriverObject); - ERROR_CODE err; - LIST_PTR node; - - driver_file_name = kmalloc( strlen(device_id+5), 0); - if ( driver_file_name == NULL ) - return NULL; - strcpy( driver_file_name, device_id ); - strcat( driver_file_name, ".sys"); - - /*check whether the driver is already loaded*/ - LIST_FOR_EACH(node, driver_list_head) - { - driver_object = STRUCT_ADDRESS_FROM_MEMBER( node, DRIVER_OBJECT, driver_list ); - if ( strcmp( driver_file_name, driver_object->driver_file_name )==0 ) - return driver_object; - } - - ktrace("Loading driver %s:", driver_file_name ); - LoadBootModule( driver_file_name, &driver_start_address, NULL ); - if( driver_start_address == NULL ) - { - ktrace(" driver not found. \n"); - return NULL; - } - err = LoadElfImage( driver_start_address, &kernel_map, "DriverEntry", (void *)&DriverEntry ); - if ( err != ERROR_SUCCESS || DriverEntry == NULL ) - { - ktrace(" failed (error - %d)\n", err ); - return NULL; - } - driver_object = AllocateBuffer( &driver_object_cache, CACHE_ALLOC_SLEEP ); - if ( driver_object == NULL ) - return NULL; - - driver_object->driver_file_name = driver_file_name; - err = DriverEntry( driver_object ); - if ( err != ERROR_SUCCESS ) - { - ktrace(" driver intialization failed %d\n", err ); - return NULL; - } - /*add the driver to the driver list*/ - AddToListTail( driver_list_head, &driver_object->driver_list ); - - return driver_object; -} +#include <kernel/iom/iom.h> + +#define DEVICE_OBJECT_CACHE_FREE_SLABS_THRESHOLD 10 +#define DEVICE_OBJECT_CACHE_MIN_BUFFERS 10 +#define DEVICE_OBJECT_CACHE_MAX_SLABS 10 + +#define DRIVER_OBJECT_CACHE_FREE_SLABS_THRESHOLD 5 +#define DRIVER_OBJECT_CACHE_MIN_BUFFERS 5 +#define DRIVER_OBJECT_CACHE_MAX_SLABS 5 + +#define IRP_CACHE_FREE_SLABS_THRESHOLD 50 +#define IRP_CACHE_MIN_BUFFERS 50 +#define IRP_CACHE_MAX_SLABS 50 + +static ERROR_CODE DummyMajorFunction(DEVICE_OBJECT_PTR pDeviceObject, IRP_PTR pIrp); + +/*! List of drivers loaded into the kernel address space */ +LIST_PTR driver_list_head = NULL; + +/*! cache for driver and device*/ +CACHE driver_object_cache; +CACHE device_object_cache; +/*! cache for irps*/ +CACHE irp_cache; + +static DRIVER_OBJECT_PTR LoadDriver(char * device_id); + +/*! Internal function used to initialize the driver object structure*/ +int DriverObjectCacheConstructor( void * buffer) +{ + int i; + DRIVER_OBJECT_PTR dop = (DRIVER_OBJECT_PTR) buffer; + + memset(dop, 0, sizeof(DRIVER_OBJECT) ); + + InitList( &dop->driver_list ); + InitSpinLock( &dop->lock ); + for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++) + dop->fn.MajorFunctions[i] = DummyMajorFunction; + + return 0; +} +/*! Internal function used to clear the driver object structure*/ +int DriverObjectCacheDestructor( void *buffer) +{ + DriverObjectCacheConstructor( buffer ); + return 0; +} +/*! Internal function used to initialize the device object structure*/ +int DeviceObjectCacheConstructor( void *buffer) +{ + DEVICE_OBJECT_PTR dop = (DEVICE_OBJECT_PTR) buffer; + + memset(buffer, 0, sizeof(DEVICE_OBJECT) ); + + InitSpinLock( &dop->lock ); + InitList( &dop->sibilings_list ); + InitList( &dop->device_object_list ); + + dop->stack_count = 1; + + return 0; +} + +/*! Internal function used to clear the device object structure*/ +int DeviceObjectCacheDestructor( void *buffer) +{ + DeviceObjectCacheConstructor( buffer ); + return 0; +} + +/*! Internal function used to initialize the IRP structure*/ +int IrpCacheConstructor( void * buffer) +{ + memset(buffer, 0, sizeof(IRP) ); + + return 0; +} + +/*! Internal function used to initialize the IRP structure*/ +int IrpCacheDestructor( void * buffer) +{ + IrpCacheConstructor(buffer); + + return 0; +} + +/*! Initialize IO manager and start required boot drivers*/ +void InitIoManager() +{ + DRIVER_OBJECT_PTR root_bus; + + if( InitCache(&driver_object_cache, sizeof(DRIVER_OBJECT), DRIVER_OBJECT_CACHE_FREE_SLABS_THRESHOLD, DRIVER_OBJECT_CACHE_MIN_BUFFERS, DRIVER_OBJECT_CACHE_MAX_SLABS, DriverObjectCacheConstructor, DriverObjectCacheDestructor) ) + panic("InitIoManager - Driver object cache init failed"); + + if( InitCache(&device_object_cache, sizeof(DEVICE_OBJECT), DEVICE_OBJECT_CACHE_FREE_SLABS_THRESHOLD, DEVICE_OBJECT_CACHE_MIN_BUFFERS, DEVICE_OBJECT_CACHE_MAX_SLABS, DeviceObjectCacheConstructor, DeviceObjectCacheDestructor) ) + panic("InitIoManager - Device object cache init failed"); + + if( InitCache(&irp_cache, sizeof(IRP), IRP_CACHE_FREE_SLABS_THRESHOLD, IRP_CACHE_MIN_BUFFERS, IRP_CACHE_MAX_SLABS, IrpCacheConstructor, IrpCacheDestructor) ) + panic("InitIoManager - IRP cache init failed"); + + /*load root bus driver and call the DriverEntry*/ + root_bus = LoadRootBusDriver() ; + RootBusDriverEntry( root_bus ); + + /*this is the first driver loaded into the kernel and it is never unloaded*/ + driver_list_head = &root_bus->driver_list; + + /*create device object for root bus*/ + CreateDevice(root_bus_driver_object, 0, &root_bus_device_object); + + /*force the io manager to enumerate the buses on root bus*/ + InvalidateDeviceRelations(root_bus_device_object, DEVICE_RELATIONS_TYPE_BUS_RELATION); + +} + +/*! Dummy Major function handler - used to initialize driver object function pointers + Just returns failure +*/ +static ERROR_CODE DummyMajorFunction(DEVICE_OBJECT_PTR pDeviceObject, IRP_PTR pIrp) +{ + assert( pDeviceObject != NULL ); + assert( pIrp != NULL ); + + pIrp->io_status.status = ERROR_NOT_SUPPORTED; + + return ERROR_NOT_SUPPORTED; +} + +/*! Returns the current IO Stack location associated with the given IRP + \param irp - interrupt request packet + \return Current IO stack location on the given irp +*/ +IO_STACK_LOCATION_PTR GetCurrentIrpStackLocation(IRP_PTR Irp) +{ + return Irp->current_stack_location; +} + +/*! Returns the next lower level IO Stack location associated with the given IRP + \param irp - interrupt request packet + \return Next IO stack loation on the given irp. +*/ +IO_STACK_LOCATION_PTR GetNextIrpStackLocation(IRP_PTR Irp) +{ + assert( Irp->current_stack >0 && Irp->current_stack < Irp->stack_count ); + return Irp->current_stack_location-1; +} +/*! Creates a device object for use by the driver + \param driver_object - caller's driver object - this is used by io manager to link the created device with the driver + \param device_extension_size - size of the device_externsion - io manager allocates this much byte in the device_object + \param device_object - pointer to device object - io manager updates this pointer with the newly created device object +*/ +ERROR_CODE CreateDevice(DRIVER_OBJECT_PTR driver_object, UINT32 device_extension_size, DEVICE_OBJECT_PTR * device_object) +{ + DEVICE_OBJECT_PTR dob; + assert( device_object != NULL ); + + dob = AllocateBuffer( &device_object_cache, CACHE_ALLOC_SLEEP ); + if ( dob == NULL ) + return ERROR_NOT_ENOUGH_MEMORY; + dob->driver_object = driver_object; + if ( device_extension_size ) + dob->device_extension = kmalloc( device_extension_size, KMEM_NO_FAIL ); + + /*add to the driver's device list*/ + if ( driver_object->device_object_head == NULL ) + driver_object->device_object_head = dob; + else + AddToListTail( &driver_object->device_object_head->device_object_list, &dob->device_object_list ); + + *device_object = dob; + return ERROR_SUCCESS; +} + +/*! Links the given source device to target device at higher level, such that any IRP passed to source device can be passed down to target_device + \param source_device - parent device + \param target_device - child device + \return parent device +*/ +DEVICE_OBJECT_PTR AttachDeviceToDeviceStack(DEVICE_OBJECT_PTR source_device, DEVICE_OBJECT_PTR target_device) +{ + DEVICE_OBJECT_PTR parent_device = target_device; + + assert( source_device->parent_device == NULL ); + + if( target_device->child_device == NULL ) + { + /*if this is the first child, set the child_device pointer*/ + target_device->child_device = source_device; + } + else + { + /*target device already has a one or more child devices, so add this device to the tail*/ + AddToListTail(&target_device->child_device->sibilings_list, &source_device->sibilings_list ); + } + /*set the source device's parent*/ + source_device->parent_device = parent_device; + source_device->stack_count = parent_device->stack_count+1; + return parent_device; +} + +/*! Invalidates the device relations, so that IO manager will Query the driver for new relations + \param device_object - device object on which relations should be invalidates + \param type - type of the invalidation +*/ +void InvalidateDeviceRelations(DEVICE_OBJECT_PTR device_object, DEVICE_RELATION_TYPE type) +{ + DEVICE_RELATIONS_PTR dr; + IRP_PTR irp; + int i; + + assert( device_object!= NULL ); + /*bus relations*/ + if( type == DEVICE_RELATIONS_TYPE_BUS_RELATION ) + { + /*todo - build existing device relations*/ + + /*send query relation irp to the driver*/ + irp = AllocateIrp( device_object->stack_count ); + FillIoStack( irp->current_stack_location, IRP_MJ_PNP, IRP_MN_QUERY_DEVICE_RELATIONS, device_object, NULL, NULL); + irp->current_stack_location->parameters.query_device_relations.type = DEVICE_RELATIONS_TYPE_BUS_RELATION; + CallDriver(device_object, irp); + if ( irp->io_status.status != ERROR_SUCCESS ) + goto done; + dr = (DEVICE_RELATIONS_PTR)irp->io_status.information; + /**/ + for(i=0; i<dr->count; i++) + { + /*\todo - if the device is not new - continue*/ + + /*send query id irp for each new device to the driver*/ + ReuseIrp( irp, ERROR_NOT_SUPPORTED ); + FillIoStack( irp->current_stack_location, IRP_MJ_PNP, IRP_MN_QUERY_ID, dr->objects[i], NULL, NULL ); + irp->current_stack_location->parameters.query_id.id_type = BUS_QUERY_DEVICE_ID; + CallDriver( dr->objects[i] , irp); + if( irp->io_status.status == ERROR_SUCCESS ) + { + DRIVER_OBJECT_PTR driver_object = LoadDriver(irp->io_status.information); + if ( driver_object != NULL ) + { + driver_object->fn.AddDevice( driver_object, dr->objects[i] ); + } + /*free driver id*/ + kfree( irp->io_status.information ); + } + } + /*free the device relation struture*/ + kfree( dr ); + } +done: + FreeIrp(irp); +} + +/*! Allocates a Irp for the use of driver + \param stack_size - number of stacks assoicated with this irp + \return irp +*/ +IRP_PTR AllocateIrp(BYTE stack_size) +{ + IRP_PTR irp; + + assert( stack_size>0 ); + /*! allocate irp and io stack*/ + irp = AllocateBuffer( &irp_cache, CACHE_ALLOC_SLEEP ); + if ( irp == NULL ) + return NULL; + irp->current_stack_location = kmalloc( sizeof(IO_STACK_LOCATION)*stack_size, KMEM_NO_FAIL ); + + irp->stack_count = stack_size; + irp->io_status.status = ERROR_NOT_SUPPORTED; + + return irp; +} + +/*! Frees a irp + \param irp - pointer to irp to be freed +*/ +void FreeIrp(IRP_PTR irp) +{ + assert( irp != NULL ); + + kfree( irp->current_stack_location ); + FreeBuffer( irp, &irp_cache ); +} + +/*! Reuses a already allocated Irp + \param irp - pointer to irp + \param error_code - Io status will be set with this error code +*/ +void ReuseIrp(IRP_PTR irp, ERROR_CODE error_code) +{ + BYTE stack_size; + IO_STACK_LOCATION_PTR io_stack; + + assert( irp != NULL ); + + stack_size = irp->stack_count; + io_stack = irp->current_stack_location; + + IrpCacheConstructor( irp ); + + irp->current_stack_location = io_stack; + irp->stack_count = stack_size; + irp->io_status.status = error_code; +} + +/*! Dispatches a call to driver based on the given Irp + \param device_object - device object + \param irp - irp +*/ +ERROR_CODE CallDriver(DEVICE_OBJECT_PTR device_object, IRP_PTR irp) +{ + assert( device_object != NULL ); + assert( irp != NULL ); + + device_object->driver_object->fn.MajorFunctions[irp->current_stack_location->major_function](device_object, irp); + return ERROR_SUCCESS; +} + +/*Helper routine to fill a Io Stack with given information*/ +inline void FillIoStack(IO_STACK_LOCATION_PTR io_stack, BYTE major_function, BYTE minor_function, DEVICE_OBJECT_PTR device_object, IO_COMPLETION_ROUTINE completion_routine, void * context) +{ + assert( io_stack ); + io_stack->major_function = major_function; + io_stack->minor_function = minor_function; + io_stack->device_object = device_object; + io_stack->completion_routine = completion_routine; + io_stack->context = context; +} + +/*! Loads a driver*/ +static DRIVER_OBJECT_PTR LoadDriver(char * device_id) +{ + char * driver_file_name; + void * driver_start_address; + DRIVER_OBJECT_PTR driver_object; + ERROR_CODE (*DriverEntry)(DRIVER_OBJECT_PTR pDriverObject); + ERROR_CODE err; + LIST_PTR node; + + driver_file_name = kmalloc( strlen(device_id+5), 0); + if ( driver_file_name == NULL ) + return NULL; + strcpy( driver_file_name, device_id ); + strcat( driver_file_name, ".sys"); + + /*check whether the driver is already loaded*/ + LIST_FOR_EACH(node, driver_list_head) + { + driver_object = STRUCT_ADDRESS_FROM_MEMBER( node, DRIVER_OBJECT, driver_list ); + if ( strcmp( driver_file_name, driver_object->driver_file_name )==0 ) + return driver_object; + } + + ktrace("Loading driver %s:", driver_file_name ); + LoadBootModule( driver_file_name, &driver_start_address, NULL ); + if( driver_start_address == NULL ) + { + ktrace(" driver not found. \n"); + return NULL; + } + err = LoadElfImage( driver_start_address, &kernel_map, "DriverEntry", (void *)&DriverEntry ); + if ( err != ERROR_SUCCESS || DriverEntry == NULL ) + { + ktrace(" failed (error - %d)\n", err ); + return NULL; + } + driver_object = AllocateBuffer( &driver_object_cache, CACHE_ALLOC_SLEEP ); + if ( driver_object == NULL ) + return NULL; + + driver_object->driver_file_name = driver_file_name; + err = DriverEntry( driver_object ); + if ( err != ERROR_SUCCESS ) + { + ktrace(" driver intialization failed %d\n", err ); + return NULL; + } + /*add the driver to the driver list*/ + AddToListTail( driver_list_head, &driver_object->driver_list ); + + return driver_object; +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sam...@us...> - 2009-03-07 08:21:12
|
Revision: 353 http://aceos.svn.sourceforge.net/aceos/?rev=353&view=rev Author: samueldotj Date: 2009-03-07 08:20:55 +0000 (Sat, 07 Mar 2009) Log Message: ----------- Added missing pid.c for the previous commit Added Paths: ----------- src/kernel/pm/pid.c Added: src/kernel/pm/pid.c =================================================================== --- src/kernel/pm/pid.c (rev 0) +++ src/kernel/pm/pid.c 2009-03-07 08:20:55 UTC (rev 353) @@ -0,0 +1,141 @@ +/*! + \file kernel/pm/pid.c + \brief Process ID management +*/ + +#include <ace.h> +#include <string.h> +#include <ds/avl_tree.h> +#include <sync/spinlock.h> +#include <kernel/debug.h> +#include <kernel/mm/kmem.h> +#include <kernel/pm/pid.h> + +SPIN_LOCK pid_info_lock; /*! lock to protect pid data structures*/ +PID_INFO pid_zero; /*! zero is reserved for kernel, and it is always present*/ +AVL_TREE_PTR pid_root; /*! root of pid avl tree*/ + +/*! internal function - Initializes the PidInfo data; called by slaballocator*/ +int PidCacheConstructor(void *buffer) +{ + PID_INFO_PTR p = (PID_INFO_PTR) buffer; + memset(p, 0, sizeof(PID_INFO) ); + InitAvlTreeNode( &pid_zero.tree_node, 0 ); + InitList( &p->inuse_list ); + InitList( &p->free_list ); + return 0; +} +/*! internal function - Reinitializes the PidInfo data; called by slaballocator +\todo - modify to just reinitialize only required field.*/ +int PidCacheDestructor(void *buffer) +{ + return PidCacheConstructor( buffer ); +} +/*! internal function - compares the given two pid info structures - called by avl tree*/ +COMPARISION_RESULT compare_pid_info(struct binary_tree * node1, struct binary_tree * node2) +{ + int n1, n2; + + assert( node1 != NULL ); + assert( node2 != NULL ); + + n1 = STRUCT_ADDRESS_FROM_MEMBER(STRUCT_ADDRESS_FROM_MEMBER(node1, AVL_TREE, bintree), PID_INFO, tree_node)->pid; + n2 = STRUCT_ADDRESS_FROM_MEMBER(STRUCT_ADDRESS_FROM_MEMBER(node2, AVL_TREE, bintree), PID_INFO, tree_node)->pid; + + if ( n1 < n2 ) + return GREATER_THAN; + else if ( n1 > n2 ) + return LESS_THAN; + else + return EQUAL; +} +/*! Initializes the PID global variables*/ +void InitPid() +{ + InitSpinLock( &pid_info_lock ); + pid_root = NULL; + + PidCacheConstructor( &pid_zero ); + pid_zero.free_count = MAX_PROCESS_ID-1; +} +/*! Allocate PID info structure + \param ppid - parent process id + \return on success - pid info structure + on failure - null +*/ +PID_INFO_PTR AllocatePidInfo(int ppid) +{ + PID_INFO_PTR pid_info, pid_free; + + pid_info = AllocateBuffer(&pid_cache, CACHE_ALLOC_SLEEP); + if ( pid_info == NULL ) + return NULL; + + SpinLock( &pid_info_lock ); + + pid_free = STRUCT_ADDRESS_FROM_MEMBER( pid_zero.free_list.next, PID_INFO, free_list ); + + assert( pid_free != NULL ); + assert( pid_free->free_count > 0 ); + pid_free->free_count--; + + /*use the first available pid*/ + pid_info->pid = pid_free->pid + 1; + pid_info->ppid = ppid; + pid_info->free_count = pid_free->free_count; + if ( pid_free->free_count > 0 ) + AddToList( &pid_free->free_list, &pid_info->free_list ); + RemoveFromList( &pid_free->free_list ); + + /*add to the used pid list*/ + AddToList( &pid_free->inuse_list, &pid_info->inuse_list ); + /*add to the tree*/ + InsertNodeIntoAvlTree( &pid_root, &pid_info->tree_node, 0, compare_pid_info ); + SpinUnlock( &pid_info_lock ); + + return pid_info; +} + +void FreePidInfo(PID_INFO_PTR pid_info) +{ + PID_INFO_PTR prev_used_pid, prev_free_pid; + + assert( pid_info != NULL ); + assert( pid_info != &pid_zero ); + + SpinLock( &pid_info_lock ); + prev_used_pid = STRUCT_ADDRESS_FROM_MEMBER( &pid_info->inuse_list.prev, PID_INFO, inuse_list.prev ); + prev_free_pid = STRUCT_ADDRESS_FROM_MEMBER( &pid_info->free_list.prev, PID_INFO, free_list.prev ); + + /*transfer free pids to previous node*/ + prev_used_pid->free_count = pid_info->free_count + 1; + if ( pid_info->free_count > 0 ) + { + AddToList( &prev_used_pid->free_list, &pid_info->free_list ); + RemoveFromList( &pid_info->free_list ); + } + else + AddToList( &prev_used_pid->free_list, &pid_zero.free_list ); + + RemoveFromList( &pid_info->inuse_list ); + RemoveNodeFromAvlTree( &pid_root, &pid_info->tree_node, 0, compare_pid_info); + SpinUnlock( &pid_info_lock ); + + FreeBuffer( pid_info, &pid_cache ); +} +/*! Finds and returns Task from the given pid + \param pid - process id + \return On success - task + On failure - null +*/ +TASK_PTR PidToTask(int pid) +{ + PID_INFO search_pid; + AVL_TREE_PTR result; + + search_pid.pid = 0; + result = SearchAvlTree( pid_root, &search_pid.tree_node, compare_pid_info ); + if ( result == NULL ) + return NULL; + return STRUCT_ADDRESS_FROM_MEMBER( result, PID_INFO, tree_node )->task; +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sam...@us...> - 2009-03-07 06:54:06
|
Revision: 352 http://aceos.svn.sourceforge.net/aceos/?rev=352&view=rev Author: samueldotj Date: 2009-03-07 06:53:49 +0000 (Sat, 07 Mar 2009) Log Message: ----------- Added Program segment loading in ELF. Added patch files for aceos specific binutils, gcc and newlib. Compressed grub modules(.gz) to save space :). Added EnumerateAvlTree() and EnumerateBinaryTree(). Modified the AvlTree test programs to output graphViz dot files. Added FindVaRange() and fixed some pmem load problems. Modified syscall to use stack instead of cache for storing arguments. Added GPF handler to print more user friendly exception message. Removed driver missing messages. Modified Paths: -------------- img/bochsrc img/boot/grub/menu.lst img/create_bootcd.sh make.conf src/include/ds/avl_tree.h src/include/ds/binary_tree.h src/include/ds/bits.h src/include/heap/slab_allocator.h src/include/kernel/i386/exception.h src/include/kernel/i386/gdt.h src/include/kernel/i386/i386.inc src/include/kernel/i386/idt.h src/include/kernel/i386/pmem.h src/include/kernel/i386/processor.h src/include/kernel/mm/pmem.h src/include/kernel/mm/vm.h src/include/kernel/module.h src/include/kernel/pm/task.h src/include/kernel/system_call_handler.h src/include/kernel/wait_event.h src/kernel/boot_module.c src/kernel/i386/arch.c src/kernel/i386/debug/gdb.c src/kernel/i386/debug/ktrace.c src/kernel/i386/exception.c src/kernel/i386/idt.c src/kernel/i386/interrupt_stub.asm src/kernel/i386/mm/pmem.c src/kernel/i386/mm/pmem_init.c src/kernel/i386/pm/thread.c src/kernel/i386/system_call_handler.c src/kernel/interrupt.c src/kernel/iom/iom.c src/kernel/iom/rootbus.c src/kernel/ipc/message_queue.c src/kernel/main.c src/kernel/makefile src/kernel/mm/kmem.c src/kernel/mm/virtual_map.c src/kernel/mm/vm.c src/kernel/mm/vm_descriptor.c src/kernel/pm/elf.c src/kernel/pm/scheduler.c src/kernel/pm/task.c src/kernel/pm/thread.c src/kernel/pm/timeout_queue.c src/kernel/system_calls.c src/lib/ds/avl_tree.c src/lib/ds/binary_tree.c src/lib/ds/test/testavl.c src/lib/ds/test/testcommon.c src/lib/ds/test/testtree.c src/lib/heap/heap.c src/lib/heap/slab_allocator.c src/makefile src/tools/makefile src/tools/mc/makefile src/tools/mc/mkmc.c Added Paths: ----------- make_app.conf src/app/ src/app/hello/ src/app/hello/hello.c src/app/hello/makefile src/app/makefile src/include/kernel/i386/tss.h src/include/kernel/pm/pid.h src/include/kernel/pm/thread.h src/kernel/i386/tss.c toolchain/ toolchain/binutils-2.19.patch toolchain/gcc-4.2.4.patch toolchain/newlib-1.17.0.patch Modified: img/bochsrc =================================================================== --- img/bochsrc 2009-03-06 18:04:05 UTC (rev 351) +++ img/bochsrc 2009-03-07 06:53:49 UTC (rev 352) @@ -3,7 +3,7 @@ #optromimage1: file=$BXSHARE/gpxe-0.9.3-pci_fefe_efef.rom, address=0xd0000 #no of processors:cores per processor:threads per core -cpu: count=2:1:1, ips=10000000, reset_on_triple_fault=1 +cpu: count=2:1:1, ips=10000000, reset_on_triple_fault=0 megs: 64 vga: extension=none Modified: img/boot/grub/menu.lst =================================================================== --- img/boot/grub/menu.lst 2009-03-06 18:04:05 UTC (rev 351) +++ img/boot/grub/menu.lst 2009-03-07 06:53:49 UTC (rev 352) @@ -2,10 +2,10 @@ timeout 1 title Ace OS 3.0.0 kernel /kernel.sys -module /boot_modules.mod +module /boot_modules.mod.gz boot title Ace OS 3.0.0 (DEBUG) kernel /kernel.sys /gdb_port 0x3f8 -module /boot_modules.mod +module /boot_modules.mod.gz boot Modified: img/create_bootcd.sh =================================================================== --- img/create_bootcd.sh 2009-03-06 18:04:05 UTC (rev 351) +++ img/create_bootcd.sh 2009-03-07 06:53:49 UTC (rev 352) @@ -5,13 +5,21 @@ exit fi +OBJ=$ACE_ROOT/obj/ +IMG=$ACE_ROOT/img/ +TOOLS_BIN=$ACE_ROOT/obj/tools/ +USR_BIN=$ACE_ROOT/obj/usr/bin/ + +rm -f $ACE_ROOT/obj/boot_modules.mod.gz #create kernel boot module container -$ACE_ROOT/obj/mkmc -o $ACE_ROOT/obj/boot_modules.mod $ACE_ROOT/obj/pci_bus.sys +$TOOLS_BIN/mkmc -v -o $OBJ/boot_modules.mod $USR_BIN/hello $OBJ/pci_bus.sys +gzip $OBJ/boot_modules.mod -mkdir -p $ACE_ROOT/img/iso/boot/grub -cp $ACE_ROOT/img/boot/grub/stage2_eltorito $ACE_ROOT/img/iso/boot/grub -cp $ACE_ROOT/img/boot/grub/menu.lst $ACE_ROOT/img/iso/boot/grub -cp $ACE_ROOT/obj/kernel.sys $ACE_ROOT/img/iso/ -cp $ACE_ROOT/obj/boot_modules.mod $ACE_ROOT/img/iso/ +rm -rf $IMG/iso/ +mkdir -p $IMG/iso/boot/grub +cp $IMG/boot/grub/stage2_eltorito $IMG/iso/boot/grub +cp $IMG/boot/grub/menu.lst $IMG/iso/boot/grub +cp $OBJ/kernel.sys $IMG/iso +cp $OBJ/boot_modules.mod.gz $IMG/iso -mkisofs -quiet -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o $ACE_ROOT/img/bootcd.iso $ACE_ROOT/img/iso +mkisofs -quiet -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o $IMG/bootcd.iso $IMG/iso Modified: make.conf =================================================================== --- make.conf 2009-03-06 18:04:05 UTC (rev 351) +++ make.conf 2009-03-07 06:53:49 UTC (rev 352) @@ -10,6 +10,7 @@ OBJ= $(ACE_ROOT)/obj IMG= $(ACE_ROOT)/img +TOOLS_BIN= $(OBJ)/tools ASM= nasm ASMFLAGS= -w+orphan-labels -f elf @@ -24,6 +25,7 @@ #ACPI_DEBUG= $(DEBUG_FLAGS) CFLAGS+= -Wall -Wno-multichar $(DEFINES) -nostartfiles -ffreestanding -funsigned-char -fno-leading-underscore -c -fno-stack-protector $(DEBUG_FLAGS) $(CUSTOM_FLAG) + #LDFLAGS= -verbose %.d: %.c Added: make_app.conf =================================================================== --- make_app.conf (rev 0) +++ make_app.conf 2009-03-07 06:53:49 UTC (rev 352) @@ -0,0 +1,44 @@ +#make_app.conf + +ifeq ($(ACE_ROOT),) + ACE_ROOT=$(PWD) +endif + +.SILENT: + +LIB_INCLUDE= /usr/cross/i586-pc-aceos/lib/ +INCLUDE= $(ACE_ROOT)/src/include/ + +OBJ= $(ACE_ROOT)/obj +IMG= $(ACE_ROOT)/img +USR_BIN= $(OBJ)/usr/bin/ + +ASM= nasm +ASMFLAGS= -w+orphan-labels -f elf +CC= gcc +LD= ld + +ARCH= i386 + +#DEFINES+= -D __DEBUG__ +DEBUG_FLAGS= -gdwarf-2 -g3 + +CFLAGS+= -Wall -Wno-multichar $(DEFINES) -funsigned-char -fno-leading-underscore -fno-stack-protector -nostdlib -static $(LIB_INCLUDE)/crt0.o $(DEBUG_FLAGS) $(CUSTOM_FLAG) +#LDFLAGS= -verbose + +%.d: %.c + @$(CC) -c -M $< -I$(INCLUDE) $(CFLAGS) > $@ + +%.o: %.c + @$(CC) -c $(abspath $<) -o $@ -I$(INCLUDE) -I./include $(CFLAGS) + +%.d: %.S + @echo -n $(dir $<) > $@ + @$(CC) -c -M $(abspath $<) -I$(INCLUDE) -I./include $(ASFLAGS) > $@ + +%.d: %.asm + @$(ASM) $(DEFINES) -i$(INCLUDE) -M $(abspath $<) -o $(<:.asm=.o) > $@ + +%.o: %.asm + @$(ASM) $(DEFINES) $(ASMFLAGS) -i$(INCLUDE) $(abspath $<) -o $@ + Added: src/app/hello/hello.c =================================================================== --- src/app/hello/hello.c (rev 0) +++ src/app/hello/hello.c 2009-03-07 06:53:49 UTC (rev 352) @@ -0,0 +1,6 @@ +#include <stdio.h> +int main() +{ + printf("Hello world from userspace!\n"); + return 0; +} Added: src/app/hello/makefile =================================================================== --- src/app/hello/makefile (rev 0) +++ src/app/hello/makefile 2009-03-07 06:53:49 UTC (rev 352) @@ -0,0 +1,17 @@ +#app/hello/makefile + +include $(ACE_ROOT)/make_app.conf + +TARGET=$(USR_BIN)/hello + +#how to make target +$(TARGET): hello.c + $(CC) $(CFLAGS) -o $(TARGET) hello.c -lc -lm + +#phony - clean - clean all object files +clean: + @rm -f *.d *.o + @rm -f $(TARGET) + +#create .d files +-include $(OBJS:.o=.d) Added: src/app/makefile =================================================================== --- src/app/makefile (rev 0) +++ src/app/makefile 2009-03-07 06:53:49 UTC (rev 352) @@ -0,0 +1,17 @@ +#src/app/makefile + +include $(ACE_ROOT)/make_app.conf + +ALL_DIRS= hello + +all: always + @for dir in $(ALL_DIRS); do make -C $$dir; done + +hello: always + @make -C hello + +clean: always + @for dir in $(ALL_DIRS); do make -C $$dir clean; done + +always: + @mkdir -p $(USR_BIN) \ No newline at end of file Modified: src/include/ds/avl_tree.h =================================================================== --- src/include/ds/avl_tree.h 2009-03-06 18:04:05 UTC (rev 351) +++ src/include/ds/avl_tree.h 2009-03-07 06:53:49 UTC (rev 352) @@ -26,6 +26,7 @@ AVL_TREE_PTR InitAvlTreeNode(AVL_TREE_PTR node, int duplicates_allowed); AVL_TREE_PTR SearchAvlTree(AVL_TREE_PTR start, AVL_TREE_PTR search_node, void * fnCompare); +void EnumerateAvlTree(AVL_TREE_PTR start, int (*fnCallback)(AVL_TREE_PTR, void *), void * arg); int InsertNodeIntoAvlTree(AVL_TREE_PTR *root, AVL_TREE_PTR new_node, int duplicates_allowed, void * fnCompare); int RemoveNodeFromAvlTree(AVL_TREE_PTR *root, AVL_TREE_PTR node, int duplicates_allowed, void * fnCompare); Modified: src/include/ds/binary_tree.h =================================================================== --- src/include/ds/binary_tree.h 2009-03-06 18:04:05 UTC (rev 351) +++ src/include/ds/binary_tree.h 2009-03-07 06:53:49 UTC (rev 352) @@ -57,6 +57,8 @@ #endif BINARY_TREE_PTR SearchBinaryTree(BINARY_TREE_PTR root, BINARY_TREE_PTR search_node, COMPARISION_RESULT (*fnCompare)(BINARY_TREE_PTR, BINARY_TREE_PTR)); +void EnumerateBinaryTree(BINARY_TREE_PTR root, int (*fnCallback)(BINARY_TREE_PTR, void *), void * arg); + int InsertNodeIntoBinaryTree(BINARY_TREE_PTR * root_ptr, BINARY_TREE_PTR new_node, int duplicates_allowed, COMPARISION_RESULT (*fnCompare)(BINARY_TREE_PTR, BINARY_TREE_PTR)); int RemoveNodeFromBinaryTree(BINARY_TREE_PTR node, BINARY_TREE_PTR * leaf_node, BINARY_TREE_PTR * root_ptr, int duplicates_allowed, BINARY_TREE_PTR * sibling_ptr, COMPARISION_RESULT (*fnCompare)(BINARY_TREE_PTR, BINARY_TREE_PTR)); Modified: src/include/ds/bits.h =================================================================== --- src/include/ds/bits.h 2009-03-06 18:04:05 UTC (rev 351) +++ src/include/ds/bits.h 2009-03-07 06:53:49 UTC (rev 352) @@ -22,6 +22,13 @@ x = y; \ y = tmp; \ } + +/*! Evaluvates whether the given "value" is with in the given range */ +#define VALUE_WITH_IN_RANGE( range_start, range_end, value ) ( (value) >= (range_start) && value <= (range_end) ) +/*! Evaluvates whether the given start and end is with in the given range */ +#define RANGE_WITH_IN_RANGE( range_start, range_end, start, end ) \ + ( VALUE_WITH_IN_RANGE(range_start, range_end, start) && VALUE_WITH_IN_RANGE(range_start, range_end, end) ) + inline int FindFirstSetBitInLong(register unsigned long value); inline int GetBitFromBitArray(void * bit_array, UINT32 bit_index); Modified: src/include/heap/slab_allocator.h =================================================================== --- src/include/heap/slab_allocator.h 2009-03-06 18:04:05 UTC (rev 351) +++ src/include/heap/slab_allocator.h 2009-03-07 06:53:49 UTC (rev 352) @@ -13,6 +13,7 @@ #include <sync/spinlock.h> /*flags for cache alloc*/ +#define CACHE_ALLOC_SLEEP 0 #define CACHE_ALLOC_NO_SLEEP 1 /* define this macro to enable statistics */ @@ -121,4 +122,7 @@ /*! gives a page to cache*/ int AddSlabToCache(CACHE_PTR cache_ptr, VADDR slab_start); +/*! wrapper for AddSlabToCache()*/ +int AddMemoryToCache(CACHE_PTR cache_ptr, char * start_address, char * end_address ); + #endif Modified: src/include/kernel/i386/exception.h =================================================================== --- src/include/kernel/i386/exception.h 2009-03-06 18:04:05 UTC (rev 351) +++ src/include/kernel/i386/exception.h 2009-03-07 06:53:49 UTC (rev 352) @@ -36,6 +36,21 @@ }; }PF_ERROR_CODE, * PF_ERROR_CODE_PTR; +/*! i386 specific general protection fault error code*/ +typedef union gpf_error_code +{ + UINT32 all; + struct + { + UINT32 + ext:1, /*if set the exception is because of external event - hardware*/ + idt:1, /*if set the index portion coming from idt, else it is from gdt/ldt */ + ti:1, /*if set the index portion coming from ldt, else it is from gdt*/ + segment_selector_index:13, /*segment / gate selector index*/ + reserved:16; + }; +}GPF_ERROR_CODE, * GPF_ERROR_CODE_PTR; + void SetupExceptionHandlers(); void ExceptionHandler(REGS_PTR reg); Modified: src/include/kernel/i386/gdt.h =================================================================== --- src/include/kernel/i386/gdt.h 2009-03-06 18:04:05 UTC (rev 351) +++ src/include/kernel/i386/gdt.h 2009-03-07 06:53:49 UTC (rev 352) @@ -6,12 +6,18 @@ #ifndef GDT_H #define GDT_H +#include <ace.h> +#include <kernel/i386/processor.h> + #define KERNEL_CODE_SELECTOR 8 #define KERNEL_DATA_SELECTOR 16 #define USER_CODE_SELECTOR 24 #define USER_DATA_SELECTOR 32 +#define KERNEL_PRIVILEGE_LEVEL 0 +#define USER_PRIVILEGE_LEVEL 3 + /*! GDT structure. * Defines a GDT entry. We say packed, because it prevents the compiler from doing things that it thinks is best. * Prevent compiler "optimization" by packing. @@ -48,7 +54,8 @@ UINT32 base; } __attribute__ ((packed)); -#define GDT_ENTRIES 5 +#define STATIC_GDT_ENTRIES 5 +#define GDT_ENTRIES (STATIC_GDT_ENTRIES + MAX_PROCESSORS) /*global descriptor table*/ extern struct gdt_entry gdt[GDT_ENTRIES]; Modified: src/include/kernel/i386/i386.inc =================================================================== --- src/include/kernel/i386/i386.inc 2009-03-06 18:04:05 UTC (rev 351) +++ src/include/kernel/i386/i386.inc 2009-03-07 06:53:49 UTC (rev 352) @@ -28,6 +28,11 @@ KSTACK_SIZE equ PAGE_SIZE +KERNEL_PRIVILEGE_LEVEL equ 0 +USER_PRIVILEGE_LEVEL equ 3 + +IDT_TYPE_INTERRUPT_GATE equ 0xE + EXTERN sbss EXTERN ebss EXTERN kernel_page_directory Modified: src/include/kernel/i386/idt.h =================================================================== --- src/include/kernel/i386/idt.h 2009-03-06 18:04:05 UTC (rev 351) +++ src/include/kernel/i386/idt.h 2009-03-07 06:53:49 UTC (rev 352) @@ -6,18 +6,25 @@ #define _IDT_H_ #include <ace.h> +#include <kernel/i386/gdt.h> /*! Total interrupt descriptor table entries in i386*/ #define IDT_ENTRIES 256 +#define IDT_TYPE_TASK_GATE 5 +#define IDT_TYPE_INTERRUPT_GATE 14 +#define IDT_TYPE_TRAP_GATE 15 + /*! Interrupt Descriptor Entry data structure*/ struct idt_entry { - UINT16 base_low; - UINT16 selector; - BYTE always_zero; - BYTE flags; - UINT16 base_high; + UINT16 base_low; /*base address of interrupt handler*/ + UINT16 selector; /*segment selector for the interrupt handler - always KERNEL_CODE_SELECTOR */ + BYTE always_zero; /*reserved and always zero*/ + BYTE type:5, /*type of the interrupt descriptor*/ + descriptor_privilege_level:2, /*privilege level*/ + present:1; + UINT16 base_high; /*base address of interrupt handler*/ } __attribute__((packed)); /*! Interrupt Descriptor Entry pointer*/ @@ -28,7 +35,7 @@ } __attribute__((packed)); void LoadIdt(); -void SetIdtGate(BYTE num, UINT32 base); +void SetIdtGate(BYTE num, UINT32 base, BYTE type, BYTE dpl); #endif Modified: src/include/kernel/i386/pmem.h =================================================================== --- src/include/kernel/i386/pmem.h 2009-03-06 18:04:05 UTC (rev 351) +++ src/include/kernel/i386/pmem.h 2009-03-07 06:53:49 UTC (rev 352) @@ -17,7 +17,7 @@ /*Page Table Entry flags*/ #define PAGE_PRESENT 1 #define PAGE_READ_WRITE 2 -#define PAGE_SUPERUSER 4 +#define PAGE_USER 4 #define PAGE_WT 8 #define PAGE_CACHE_DISABLE 16 #define PAGE_ACCESSED 32 @@ -26,11 +26,11 @@ #define PAGE_GLOBAL 256 /*! kernel page table entry flag*/ -#define KERNEL_PTE_FLAG (PAGE_PRESENT | PAGE_READ_WRITE | PAGE_SUPERUSER | PAGE_GLOBAL) +#define KERNEL_PTE_FLAG (PAGE_PRESENT | PAGE_READ_WRITE | PAGE_GLOBAL) /*! user page directory entry flag*/ -#define USER_PDE_FLAG (PAGE_PRESENT | PAGE_READ_WRITE | PAGE_SUPERUSER ) +#define USER_PDE_FLAG (PAGE_PRESENT | PAGE_READ_WRITE | PAGE_USER ) /*! user page table entry flag*/ -#define USER_PTE_FLAG (PAGE_PRESENT | PAGE_READ_WRITE ) +#define USER_PTE_FLAG (PAGE_PRESENT | PAGE_READ_WRITE | PAGE_USER ) #define CR3_PAGE_CACHE_DISABLE #define CR3_PAGE_WRITES_TRANSPARENT @@ -88,10 +88,6 @@ /*! Physical address to Page frame number*/ #define PA_TO_PFN(pa) ( ((UINT32)pa) >> PAGE_SHIFT ) -#ifdef __cplusplus - extern "C" { -#endif - typedef struct virtual_address { UINT32 offset:12, @@ -107,7 +103,7 @@ UINT32 present:1, write:1, - supervisior:1, + user:1, write_through:1, cache_disabled:1, accessed:1, @@ -127,7 +123,7 @@ UINT32 present:1, write:1, - supervisior:1, + user:1, write_through:1, cache_disabled:1, accessed:1, @@ -141,15 +137,27 @@ struct physical_map { - SPIN_LOCK lock; - PAGE_DIRECTORY_ENTRY_PTR page_directory; + SPIN_LOCK lock; /*! spinlock for protection*/ + + long locked_page_count; /*! number of locked pages in this map*/ + VIRTUAL_MAP_PTR virtual_map; /*! associated virtual map*/ + + PAGE_DIRECTORY_ENTRY_PTR page_directory; /*! page directory of this map*/ }; extern PAGE_DIRECTORY_ENTRY kernel_page_directory[PAGE_DIRECTORY_ENTRIES] __attribute__ ((aligned (PAGE_SIZE))); extern PHYSICAL_MAP kernel_physical_map; +extern CACHE physical_map_cache; #ifdef __cplusplus + extern "C" { +#endif + +extern int PhysicalMapCacheConstructor( void *buffer); +int PhysicalMapCacheDestructor( void *buffer); + +#ifdef __cplusplus } #endif Modified: src/include/kernel/i386/processor.h =================================================================== --- src/include/kernel/i386/processor.h 2009-03-06 18:04:05 UTC (rev 351) +++ src/include/kernel/i386/processor.h 2009-03-07 06:53:49 UTC (rev 352) @@ -10,16 +10,17 @@ #define _PROCESSOR_I386_H_ #include <ace.h> +#include <kernel/processor.h> #include <kernel/i386/apic.h> -#include <kernel/processor.h> -#include <kernel/i386/processor.h> +#include <kernel/i386/cpuid.h> +#include <kernel/i386/tss.h> /*! Data structure for architecture independed part of a i386 processor(which supports CPUID and has LAPIC)*/ typedef struct processor_i386 { - CPUID_INFO cpuid; /*! CPUID data returned by the processor*/ - UINT16 apic_id; /*! APIC id of the CPU, we cant use CPUID data until the CPU starts*/ - + CPUID_INFO cpuid; /*! CPUID data returned by the processor*/ + UINT16 apic_id; /*! APIC id of the CPU, we cant use CPUID data until the CPU starts*/ + TSS tss; /*! task state segment for this cpu*/ }PROCESSOR_I386, *PROCESSOR_I386_PTR; /*Processors are indexed by using APIC ID*/ Added: src/include/kernel/i386/tss.h =================================================================== --- src/include/kernel/i386/tss.h (rev 0) +++ src/include/kernel/i386/tss.h 2009-03-07 06:53:49 UTC (rev 352) @@ -0,0 +1,71 @@ +/*! + \file kernel/i386/tss.h + \brief Task state segment related data structure definitions and functions +*/ + +#ifndef TSS_H +#define TSS_H + +#include <ace.h> + +struct tss{ + UINT16 link; + UINT16 reserved_1; + + UINT32 esp0; + UINT16 ss0; + UINT16 reserved_2; + + UINT32 esp1; + UINT16 ss1; + UINT16 reserved_3; + + UINT32 esp2; + UINT16 ss2; + UINT16 reserved_4; + + UINT32 cr3; + UINT32 eip; + UINT32 reserved_5; + + UINT32 eax; + UINT32 ecx; + UINT32 edx; + UINT32 ebx; + + UINT32 esp; + UINT32 ebp; + + UINT32 esi; + UINT32 edi; + + UINT16 es; + UINT16 reserved_6; + + UINT16 cs; + UINT16 reserved_7; + + UINT16 ss; + UINT16 reserved_8; + + UINT16 ds; + UINT16 reserved_9; + + UINT16 fs; + UINT16 reserved_10; + + UINT16 gs; + UINT16 reserved_11; + + UINT16 ldt; + UINT16 reserved_12; + + UINT16 trap; + UINT16 iomap; +}__attribute__ ((aligned (8), packed)); + +typedef volatile struct tss TSS, * TSS_PTR; + +void LoadTss(); + +#endif Modified: src/include/kernel/mm/pmem.h =================================================================== --- src/include/kernel/mm/pmem.h 2009-03-06 18:04:05 UTC (rev 351) +++ src/include/kernel/mm/pmem.h 2009-03-07 06:53:49 UTC (rev 352) @@ -59,6 +59,8 @@ extern MEMORY_AREA memory_areas[MAX_MEMORY_AREAS]; extern int memory_area_count; +PHYSICAL_MAP_PTR CreatePhysicalMap(VIRTUAL_MAP_PTR vmap); + void InitPhysicalMemoryManagerPhaseI(unsigned long magic, MULTIBOOT_INFO_PTR mbi); void InitPhysicalMemoryManagerPhaseII(); void CompletePhysicalMemoryManagerInit(); @@ -69,5 +71,6 @@ ERROR_CODE MapVirtualAddressRange(PHYSICAL_MAP_PTR pmap, UINT32 va, UINT32 size, UINT32 protection); VA_STATUS GetVirtualRangeStatus(VADDR va, UINT32 size); +VA_STATUS TranslatePaFromVa(VADDR va, VADDR * pa); #endif Modified: src/include/kernel/mm/vm.h =================================================================== --- src/include/kernel/mm/vm.h 2009-03-06 18:04:05 UTC (rev 351) +++ src/include/kernel/mm/vm.h 2009-03-07 06:53:49 UTC (rev 352) @@ -10,6 +10,7 @@ #include <ds/avl_tree.h> #include <sync/spinlock.h> #include <kernel/error.h> +#include <kernel/mm/kmem.h> #include <kernel/mm/vm_types.h> #if ARCH == i386 @@ -32,6 +33,10 @@ #define PAGE_ALIGN_4MB(addr) ((UINT32)(addr) & -(4096*1024)) #define PAGE_ALIGN_UP_4MB(addr) PAGE_ALIGN_4MB( (addr) + (1024*1024) - 1 ) +#define PAGE_MASK ( ~(PAGE_SIZE-1) ) + +#define IS_PAGE_ALIGNED(addr) ( !( (addr) & PAGE_MASK ) ) + /*! Total number pages required by given size in bytes*/ #define NUMBER_OF_PAGES(size) (PAGE_ALIGN_UP(size) >> PAGE_SHIFT) @@ -164,15 +169,20 @@ extern VM_PROTECTION protection_user_write; extern VM_PROTECTION protection_user_read; +extern CACHE virtual_map_cache; +extern CACHE vm_descriptor_cache; + #ifdef __cplusplus extern "C" { #endif void InitVm(); +VIRTUAL_MAP_PTR CreateVirtualMap(VADDR start, VADDR end); + void InitVmDescriptor(VM_DESCRIPTOR_PTR descriptor, VIRTUAL_MAP_PTR vmap, VADDR start, VADDR end, VM_UNIT_PTR vm_unit, VM_PROTECTION_PTR protection); VM_DESCRIPTOR_PTR CreateVmDescriptor(VIRTUAL_MAP_PTR vmap, VADDR start, VADDR end, VM_UNIT_PTR vm_unit, VM_PROTECTION_PTR protection); -VM_DESCRIPTOR_PTR GetVmDescriptor(VIRTUAL_MAP_PTR vmap, VADDR va); +VM_DESCRIPTOR_PTR GetVmDescriptor(VIRTUAL_MAP_PTR vmap, VADDR va, UINT32 size); void * FindFreeVmRange(VIRTUAL_MAP_PTR vmap, VADDR start, UINT32 size, UINT32 option); VM_UNIT_PTR CreateVmUnit(UINT32 type, UINT32 size); @@ -187,6 +197,11 @@ VIRTUAL_MAP_PTR GetCurrentVirtualMap(); ERROR_CODE MemoryFaultHandler(UINT32 va, int is_user_mode, int access_type); +int VirtualMapCacheConstructor(void * buffer); +int VirtualMapCacheDestructor(void * buffer); +int VmDescriptorCacheConstructor(void * buffer); +int VmDescriptorCacheDestructor(void * buffer); + #ifdef __cplusplus } #endif Modified: src/include/kernel/module.h =================================================================== --- src/include/kernel/module.h 2009-03-06 18:04:05 UTC (rev 351) +++ src/include/kernel/module.h 2009-03-07 06:53:49 UTC (rev 352) @@ -13,18 +13,22 @@ #define MODULE_MAGIC_NUMBER 0xACE -typedef struct module_file_header +struct module_file_header { UINT32 MagicNumber; /*! Identifies Ace kernel module container file - should be 0xACE*/ int TotalModules; /*! Total number of modules present in this container*/ -}MODULE_FILE_HEADER, * MODULE_FILE_HEADER_PTR; +}__attribute__ ((packed)); -typedef struct module_header +typedef struct module_file_header MODULE_FILE_HEADER, * MODULE_FILE_HEADER_PTR; + +struct module_header { char ModuleName[KERNEL_MODULE_NAME_MAX]; /*! Name of the module*/ UINT32 Size; /*! Size of the module*/ -}MODULE_HEADER, * MODULE_HEADER_PTR; +}__attribute__ ((packed)); +typedef struct module_header MODULE_HEADER, * MODULE_HEADER_PTR; + #ifdef __cplusplus extern "C" { #endif Added: src/include/kernel/pm/pid.h =================================================================== --- src/include/kernel/pm/pid.h (rev 0) +++ src/include/kernel/pm/pid.h 2009-03-07 06:53:49 UTC (rev 352) @@ -0,0 +1,48 @@ +/*! \file include/kernel/pm/pid.h + \brief process id related structures +*/ + +#ifndef _PID_H_ +#define _PID_H_ + +typedef struct pid_info PID_INFO, * PID_INFO_PTR; + +#include <ace.h> +#include <ds/list.h> +#include <ds/avl_tree.h> +#include <kernel/pm/task.h> +#include <kernel/wait_event.h> +/*! maximum process number allowed*/ +#define MAX_PROCESS_ID 0xFFFF + +struct pid_info +{ + int pid; /*! Process Id*/ + TASK_PTR task; /*! associated task*/ + int ppid; /*! Parent Process Id*/ + + int exited; /*! true if the process is exited/terminated*/ + int exit_status; /*! exit status*/ + WAIT_EVENT_PTR wait_event; /*! if somebody want to watch this process dead event, will wait here*/ + + AVL_TREE tree_node; /*! tree of used pids - to find a pid faster*/ + + int free_count; /*! total free pids after this pid*/ + LIST free_list; /*! links all used pids which has free pids next to them*/ + LIST inuse_list; /*! links all used pids regardless whether they have free pids or not*/ +}; + +CACHE pid_cache; /*! cache for pid info*/ + +#ifdef __cplusplus + extern "C" { +#endif + +int PidCacheConstructor(void *buffer); +int PidCacheDestructor(void *buffer); + +#ifdef __cplusplus + } +#endif + +#endif Modified: src/include/kernel/pm/task.h =================================================================== --- src/include/kernel/pm/task.h 2009-03-06 18:04:05 UTC (rev 351) +++ src/include/kernel/pm/task.h 2009-03-07 06:53:49 UTC (rev 352) @@ -5,32 +5,33 @@ #ifndef _TASK_H_ #define _TASK_H_ +typedef struct task TASK, * TASK_PTR; #include <ace.h> #include <ds/list.h> #include <sync/spinlock.h> #include <kernel/mm/vm.h> #include <kernel/mm/kmem.h> - -typedef struct thread THREAD, * THREAD_PTR; - -#include <kernel/processor.h> -#include <kernel/pm/scheduler.h> -#include <kernel/pm/timeout_queue.h> - -#define KERNEL_STACK_SIZE (PAGE_SIZE) - -typedef struct task TASK, *TASK_PTR; -/* include ipc.h after defining TASK_PTR because ipc.h uses it */ +#include <kernel/pm/thread.h> +#include <kernel/pm/pid.h> #include <kernel/ipc.h> #include <kernel/wait_event.h> -#define MESSAGE_QUEUES_PER_TASK 5 +/*\todo remove these macros and put it as tunable*/ +#define TASK_CACHE_FREE_SLABS_THRESHOLD 100 +#define TASK_CACHE_MIN_SLABS 10 +#define TASK_CACHE_MAX_SLABS 50 +#define MESSAGE_QUEUES_PER_TASK 5 + +#define GET_CURRENT_PID() GetCurrentTask()->pid_info->pid + struct task { SPIN_LOCK lock; /*! lock for the entire structure */ int reference_count; + PID_INFO_PTR pid_info; + VIRTUAL_MAP_PTR virtual_map; /*! virtual map for this task */ THREAD_PTR thread_head; /*! threads in the same task */ @@ -42,91 +43,22 @@ UINT32 message_queue_length; /*! Number of message buffers that can be present in the queue */ }; -typedef enum -{ - THREAD_STATE_READY = 1, /*! thread is ready to run */ - THREAD_STATE_RUN = 2, /*! thread is running */ - THREAD_STATE_TERMINATE = 3, /*! thread is terminating */ - THREAD_STATE_WAITING = 4, /*! thread is waiting */ - THREAD_STATE_TRANSITION = 5, /*! thread is in transition phase from one state to another */ - THREAD_STATE_EVENT_FIRED = 6, - THREAD_STATE_NEW = 7 -}THREAD_STATE; +extern CACHE task_cache; +extern TASK kernel_task; - -struct thread -{ - SPIN_LOCK lock; /*! lock for the entire structure */ - int reference_count; - - TASK_PTR task; /*! back pointer to task */ - LIST thread_queue; /*! threads in the same task */ - - PROCESSOR_PTR current_processor; /*! Pointer to current processor on which this thread is running */ - PROCESSOR_PTR last_processor; /*! Pointer to the processor on which this thread last ran */ - INT8 bind_cpu; /*! CPU to which the thread is bound to run. -1 value implies thread is not bound */ - - /* scheduler related data */ - THREAD_STATE state; /*! Run State */ - LIST priority_queue_list; /*! List of threads which are in the same priority queue */ - UINT8 time_slice; /*! Time quantum for which the thread can be run */ - PRIORITY_QUEUE_PTR priority_queue; /*! Pointer to priority queue in either of active or dormant ready queue */ - SCHEDULER_CLASS_LEVELS priority; /*! External priority assigned by the user. This is used to select one of the scheduler classes */ - - /* Timeout queue */ - TIMEOUT_QUEUE timeout_queue; - - /* Wait event queue lock */ - SPIN_LOCK wait_event_queue_lock; /*! Anybody accessing any wait events belonging to this structure or count_wait_event_queue variable should take this lock */ -}; - -/* -Thread's execution context in kernel mode - ------- Page Align - Thread structure - ------- Page Align - Guard Page - ------- Page Align - Kernel Stack -*/ -typedef struct thread_container -{ - THREAD thread; __attribute__ ((aligned ( PAGE_SIZE ))) - BYTE * kernel_stack_pointer; - BYTE guard_page[PAGE_SIZE] __attribute__ ((aligned ( PAGE_SIZE ))); - BYTE kernel_stack[KERNEL_STACK_SIZE] __attribute__ ((aligned ( PAGE_SIZE ))); -}THREAD_CONTAINER, * THREAD_CONTAINER_PTR; - -extern CACHE thread_cache; - -#define THREAD_CACHE_FREE_SLABS_THRESHOLD 100 -#define THREAD_CACHE_MIN_SLABS 10 -#define THREAD_CACHE_MAX_SLABS 50 - #ifdef __cplusplus extern "C" { #endif -int ThreadCacheConstructor(void *buffer); -int ThreadCacheDestructor(void *buffer); -inline BYTE * GetKernelStackPointer(); -THREAD_PTR GetCurrentThread(); +int TaskCacheConstructor(void * buffer); +int TaskCacheDestructor(void * buffer); -THREAD_CONTAINER_PTR CreateThread(void * start_address, SCHEDULER_PRIORITY_LEVELS priority_class); -void ExitThread(); -void FreeThread(THREAD_PTR thread ); -void PauseThread(); -void ResumeThread(THREAD_PTR thread); +void InitKernelTask(); +TASK_PTR CreateTask(char * exe_file_path); +inline TASK_PTR GetCurrentTask(); -void InitBootThread(int boot_processor_id); +TASK_PTR PidToTask(int pid); -void FillThreadContext(THREAD_CONTAINER_PTR thread_container, void * start_address); -void SwitchContext(THREAD_CONTAINER_PTR thread_container); - -TASK_PTR PidToTask(UINT32 pid); -UINT32 TaskToPid(TASK_PTR task); -UINT32 GetCurrentPid(void); - #ifdef __cplusplus } #endif Added: src/include/kernel/pm/thread.h =================================================================== --- src/include/kernel/pm/thread.h (rev 0) +++ src/include/kernel/pm/thread.h 2009-03-07 06:53:49 UTC (rev 352) @@ -0,0 +1,107 @@ +/*! \file include/kernel/pm/thread.h + \brief thread and kernel stack related strcutrues and function declarations +*/ + +#ifndef _THREAD_H_ +#define _THREAD_H_ + +typedef struct thread THREAD, * THREAD_PTR; +#include <ace.h> +#include <ds/list.h> +#include <sync/spinlock.h> +#include <kernel/mm/vm.h> +#include <kernel/mm/kmem.h> +#include <kernel/processor.h> +#include <kernel/pm/scheduler.h> +#include <kernel/pm/timeout_queue.h> + +/*\todo remove these macros and put it as tunable*/ +#define THREAD_CACHE_FREE_SLABS_THRESHOLD 100 +#define THREAD_CACHE_MIN_SLABS 10 +#define THREAD_CACHE_MAX_SLABS 50 + +#define KERNEL_STACK_SIZE (PAGE_SIZE) +#define USER_STACK_SIZE (2*PAGE_SIZE) + +typedef enum +{ + THREAD_STATE_READY = 1, /*! thread is ready to run */ + THREAD_STATE_RUN = 2, /*! thread is running */ + THREAD_STATE_TERMINATE = 3, /*! thread is terminating */ + THREAD_STATE_WAITING = 4, /*! thread is waiting */ + THREAD_STATE_TRANSITION = 5, /*! thread is in transition phase from one state to another */ + THREAD_STATE_EVENT_FIRED = 6, + THREAD_STATE_NEW = 7 +}THREAD_STATE; + +struct thread +{ + SPIN_LOCK lock; /*! lock for the entire structure */ + int reference_count; + + TASK_PTR task; /*! back pointer to task */ + LIST thread_queue; /*! threads in the same task */ + + PROCESSOR_PTR current_processor; /*! Pointer to current processor on which this thread is running */ + PROCESSOR_PTR last_processor; /*! Pointer to the processor on which this thread last ran */ + INT8 bind_cpu; /*! CPU to which the thread is bound to run. -1 value implies thread is not bound */ + + /* scheduler related data */ + THREAD_STATE state; /*! Run State */ + LIST priority_queue_list; /*! List of threads which are in the same priority queue */ + UINT8 time_slice; /*! Time quantum for which the thread can be run */ + PRIORITY_QUEUE_PTR priority_queue; /*! Pointer to priority queue in either of active or dormant ready queue */ + SCHEDULER_CLASS_LEVELS priority; /*! External priority assigned by the user. This is used to select one of the scheduler classes */ + + /* Timeout queue */ + TIMEOUT_QUEUE timeout_queue; + + /* Wait event queue lock */ + SPIN_LOCK wait_event_queue_lock; /*! Anybody accessing any wait events belonging to this structure or count_wait_event_queue variable should take this lock */ +}; + +/* +Thread's execution context in kernel mode + ------- Page Align + Thread structure + ------- Page Align + Guard Page + ------- Page Align + Kernel Stack +*/ +typedef struct thread_container +{ + THREAD thread; __attribute__ ((aligned ( PAGE_SIZE ))) + BYTE * kernel_stack_pointer; + BYTE guard_page[PAGE_SIZE] __attribute__ ((aligned ( PAGE_SIZE ))); + BYTE kernel_stack[KERNEL_STACK_SIZE] __attribute__ ((aligned ( PAGE_SIZE ))); +}THREAD_CONTAINER, * THREAD_CONTAINER_PTR; + +extern CACHE thread_cache; + +#ifdef __cplusplus + extern "C" { +#endif + +int ThreadCacheConstructor(void *buffer); +int ThreadCacheDestructor(void *buffer); + +inline BYTE * GetKernelStackPointer(); +THREAD_PTR GetCurrentThread(); + +THREAD_CONTAINER_PTR CreateThread(TASK_PTR task, void * start_address, SCHEDULER_PRIORITY_LEVELS priority_class, BYTE is_kernel_thread); +void ExitThread(); +void FreeThread(THREAD_PTR thread ); +void PauseThread(); +void ResumeThread(THREAD_PTR thread); + +void InitBootThread(int boot_processor_id); + +void FillThreadContext(THREAD_CONTAINER_PTR thread_container, void * start_address, BYTE is_kernel_thread, VADDR user_stack); +void SwitchContext(THREAD_CONTAINER_PTR thread_container); + +#ifdef __cplusplus + } +#endif + +#endif Modified: src/include/kernel/system_call_handler.h =================================================================== --- src/include/kernel/system_call_handler.h 2009-03-06 18:04:05 UTC (rev 351) +++ src/include/kernel/system_call_handler.h 2009-03-07 06:53:49 UTC (rev 352) @@ -25,6 +25,6 @@ int SystemCallCacheConstructor(void *buffer); int SystemCallCacheDestructor(void *buffer); extern const int max_system_calls; -extern ERROR_CODE ( *(system_calls[]) )(SYSTEM_CALL_ARGS_PTR, UINT32*); +extern UINT32 ( *(system_calls[]) )(SYSTEM_CALL_ARGS_PTR, UINT32*); #endif Modified: src/include/kernel/wait_event.h =================================================================== --- src/include/kernel/wait_event.h 2009-03-06 18:04:05 UTC (rev 351) +++ src/include/kernel/wait_event.h 2009-03-07 06:53:49 UTC (rev 352) @@ -6,11 +6,10 @@ #ifndef WAIT_EVENT_H #define WAIT_EVENT_H +typedef struct wait_event WAIT_EVENT, *WAIT_EVENT_PTR; + #include <ace.h> #include <ds/list.h> - - -typedef struct wait_event WAIT_EVENT, *WAIT_EVENT_PTR; #include <kernel/pm/task.h> #define WAIT_EVENT_WAKE_UP_ALL 1 Modified: src/kernel/boot_module.c =================================================================== --- src/kernel/boot_module.c 2009-03-06 18:04:05 UTC (rev 351) +++ src/kernel/boot_module.c 2009-03-07 06:53:49 UTC (rev 352) @@ -39,16 +39,20 @@ ERROR_CODE LoadBootModule(char * module_name, void ** start_address, UINT32 * size) { MODULE_HEADER_PTR module_header = boot_module_header_start; - VADDR module_content_start = (VADDR) ((char *)boot_module_header_start) + ( sizeof(MODULE_HEADER) * total_modules ); + char * module_content_start; int i = 0; + /*module content starts after all the headers*/ + module_content_start = ((char *)boot_module_header_start) + ( sizeof(MODULE_HEADER) * total_modules ); + assert( start_address != NULL ); - + *start_address = NULL; while (i<total_modules) { /*! check the module name*/ if ( strcmp(module_name, module_header->ModuleName ) == 0 ) { + //kprintf("%s %d @%p\n", module_name, module_header->Size, module_content_start); /*! update the result and return success*/ *start_address = (void *)module_content_start; if ( size ) @@ -57,6 +61,8 @@ } i++; module_content_start += module_header->Size; + /*next module*/ + module_header++; } return ERROR_NOT_FOUND; } Modified: src/kernel/i386/arch.c =================================================================== --- src/kernel/i386/arch.c 2009-03-06 18:04:05 UTC (rev 351) +++ src/kernel/i386/arch.c 2009-03-07 06:53:49 UTC (rev 352) @@ -123,6 +123,9 @@ /* Initialize real time clock*/ InitRtc(); + + /* Load TSS so that we can switch to user mode*/ + LoadTss(); } /*! returns the current processor's LAPIC id @@ -162,9 +165,12 @@ /* Install interrupt handler for the LAPIC timer*/ InstallInterruptHandler( LOCAL_TIMER_VECTOR_NUMBER-32, LapicTimerHandler, 0); - + + /* Load TSS so that we can switch to user mode*/ + LoadTss(); + /* Start the architecture depended timer for secondary processor - to enable scheduler */ - //StartTimer(SCHEDULER_DEFAULT_QUANTUM, TRUE); + StartTimer(SCHEDULER_DEFAULT_QUANTUM, TRUE); kprintf("Secondary CPU %d is started\n", processor_id); } Modified: src/kernel/i386/debug/gdb.c =================================================================== --- src/kernel/i386/debug/gdb.c 2009-03-06 18:04:05 UTC (rev 351) +++ src/kernel/i386/debug/gdb.c 2009-03-07 06:53:49 UTC (rev 352) @@ -38,7 +38,7 @@ { /*dont register page fault with gdb*/ if ( exc != 14 ) - SetIdtGate(exc, (UINT32)addr); + SetIdtGate(exc, (UINT32)addr, IDT_TYPE_INTERRUPT_GATE, KERNEL_PRIVILEGE_LEVEL); } /*! Flushes instruction cache*/ Modified: src/kernel/i386/debug/ktrace.c =================================================================== --- src/kernel/i386/debug/ktrace.c 2009-03-06 18:04:05 UTC (rev 351) +++ src/kernel/i386/debug/ktrace.c 2009-03-07 06:53:49 UTC (rev 352) @@ -11,7 +11,7 @@ #define KTRACE_PRINT_PARALLEL #define KTRACE_PRINT_SERIAL -#define KTRACE_PRINT_VGA +//#define KTRACE_PRINT_VGA /*if serial port printing is enabled then register port */ #ifdef KTRACE_PRINT_SERIAL Modified: src/kernel/i386/exception.c =================================================================== --- src/kernel/i386/exception.c 2009-03-06 18:04:05 UTC (rev 351) +++ src/kernel/i386/exception.c 2009-03-07 06:53:49 UTC (rev 352) @@ -82,13 +82,25 @@ if ( err.rsvd ) kprintf( "Page fault - RESERVED BIT SET\n"); else - kprintf("Page fault(code %d): %s page %s attempt and %s fault.\n", + kprintf("Page fault(code %d): %s page %s attempt : %s\n", reg->error_code, err.user ? "User" : "Supervisor" , err.write ? "write" : "read", - err.present ? "protection" : "page not present"); + err.present ? "protection failure" : "page not present"); PRINT_REGS(reg); ArchHalt(); } } +void GeneralProtectionFaultHandler(REGS_PTR reg) +{ + GPF_ERROR_CODE err; + err.all = reg->error_code; + kprintf("General Protection Fault:%s %s descriptor table (index - %d)\n", + err.ext ? "External event" : "", + err.idt ? "Interrupt" : err.ti ? "Local" : "Global", + err.segment_selector_index); + + PRINT_REGS(reg); + ArchHalt(); +} Modified: src/kernel/i386/idt.c =================================================================== --- src/kernel/i386/idt.c 2009-03-06 18:04:05 UTC (rev 351) +++ src/kernel/i386/idt.c 2009-03-07 06:53:49 UTC (rev 352) @@ -15,15 +15,22 @@ /*Interrupt Descriptor Table Register*/ struct idt_ptr idtp; -/* Use this function to set an entry in the IDT.*/ -void SetIdtGate(BYTE num, UINT32 base) +/* ! Sets an entry in interrupt descriptor table + \param num - Interrupt vector number + \param base - Address of the interrrupt handler + \param type - interrupt descriptor type(task gate, interrupt gate or trap gate) + \param dpl - descriptor privilege level (0 or 3) +*/ +void SetIdtGate(BYTE num, UINT32 base, BYTE type, BYTE dpl) { idt[num].base_low = (base & 0xFFFF); idt[num].base_high = ((base>>16) & 0xFFFF); idt[num].selector = KERNEL_CODE_SELECTOR; idt[num].always_zero = 0; - idt[num].flags = 0x8e; + idt[num].present = 1; + idt[num].type = type; + idt[num].descriptor_privilege_level = dpl; } /* Loads the Interrupt Descriptor Table*/ Modified: src/kernel/i386/interrupt_stub.asm =================================================================== --- src/kernel/i386/interrupt_stub.asm 2009-03-06 18:04:05 UTC (rev 351) +++ src/kernel/i386/interrupt_stub.asm 2009-03-07 06:53:49 UTC (rev 352) @@ -4,6 +4,7 @@ extern ExceptionHandler extern PageFaultHandler +extern GeneralProtectionFaultHandler extern InterruptHandler extern SetIdtGate global ReturnFromInterruptContext @@ -57,9 +58,11 @@ %endmacro ReturnFromInterruptContext: - pop eax + pop eax - add esp, 16 ; Clean up the pushed control registers + add esp, 12 ; Clean up the pushed control registers cr0, cr1, cr2 + pop eax + mov cr3, eax pop gs ; Pop segment registers pop fs @@ -74,11 +77,15 @@ ;Install the stub as interrupt gates ;Parameters -%macro SetIdtGateMacro 2 +%macro SetIdtGateMacro 4 + push dword %4 + push dword %3 push dword %1%2 push dword %2 + + call SetIdtGate - add esp, 8 + add esp, 16 %endmacro [SECTION .text] @@ -87,7 +94,9 @@ ;Generate exception stubs %assign i 0 %rep 32 - %if i = 14 + %if i = 13 + IsrStubMacro GeneralProtectionFaultHandler, i + %elif i = 14 IsrStubMacro PageFaultHandler, i %else IsrStubMacro ExceptionHandler, i @@ -105,10 +114,12 @@ SetupExceptionStubs: %assign i 0 %rep 32 - %if i = 14 - SetIdtGateMacro PageFaultHandlerStub, i + %if i = 13 + SetIdtGateMacro GeneralProtectionFaultHandlerStub, i, IDT_TYPE_INTERRUPT_GATE, KERNEL_PRIVILEGE_LEVEL + %elif i = 14 + SetIdtGateMacro PageFaultHandlerStub, i, IDT_TYPE_INTERRUPT_GATE, KERNEL_PRIVILEGE_LEVEL %else - SetIdtGateMacro ExceptionHandlerStub, i + SetIdtGateMacro ExceptionHandlerStub, i, IDT_TYPE_INTERRUPT_GATE, KERNEL_PRIVILEGE_LEVEL %endif %assign i i+1 @@ -118,7 +129,7 @@ SetupInterruptStubs: %assign i 32 %rep 255-32 - SetIdtGateMacro InterruptHandlerStub, i + SetIdtGateMacro InterruptHandlerStub, i, IDT_TYPE_INTERRUPT_GATE, USER_PRIVILEGE_LEVEL %assign i i+1 %endrep Modified: src/kernel/i386/mm/pmem.c =================================================================== --- src/kernel/i386/mm/pmem.c 2009-03-06 18:04:05 UTC (rev 351) +++ src/kernel/i386/mm/pmem.c 2009-03-07 06:53:49 UTC (rev 352) @@ -22,8 +22,41 @@ PAGE_DIRECTORY_ENTRY kernel_page_directory[PAGE_DIRECTORY_ENTRIES] __attribute__ ((aligned (PAGE_SIZE))); PHYSICAL_MAP kernel_physical_map; +CACHE physical_map_cache; + static void CreatePageTable(PHYSICAL_MAP_PTR pmap, UINT32 va ); +/*! Creates a new physical map and allocate page directory for it + \param vmap - Virtual map for which physical map needs to be created + \return on success physical map address + on failure null +*/ +PHYSICAL_MAP_PTR CreatePhysicalMap(VIRTUAL_MAP_PTR vmap) +{ + PHYSICAL_MAP_PTR pmap; + UINT32 page_dir_pa; + + pmap = AllocateBuffer( &physical_map_cache, CACHE_ALLOC_SLEEP ); + if ( pmap == NULL ) + return NULL; + + pmap->virtual_map = vmap; + /*allocate page directory from kernel map*/ + if ( AllocateVirtualMemory(&kernel_map, (VADDR*) &pmap->page_directory, 0, PAGE_SIZE, PROT_READ|PROT_WRITE, 0, NULL) != ERROR_SUCCESS ) + { + FreeBuffer( pmap, &physical_map_cache ); + return NULL; + } + /*copy the kernel page directory*/ + memcpy(pmap->page_directory, kernel_physical_map.page_directory, PAGE_SIZE ); + + /*set the self mapping*/ + if ( TranslatePaFromVa( (VADDR )pmap->page_directory, &page_dir_pa ) == VA_NOT_EXISTS ) + panic("pagedirectory is not in memory"); + pmap->page_directory[PT_SELF_MAP_INDEX].all = (page_dir_pa | KERNEL_PTE_FLAG); + + return pmap; +} /*! Fills page table entry for a given VA. This function makes the corresponding VA to point to PA by filling PTEs. this function can be also called to change the protection. @@ -60,24 +93,23 @@ { /*if somebody else created this mapping return*/ if ( mapped_pte->page_pfn == pfn ) + { + //todo - handle protection change here goto finish; + } else { kprintf("VA %p PA %p Existing PA %p\n", va, pa, mapped_pte->page_pfn<<PAGE_SHIFT); panic("Trying to map over a existing map\n"); } } - - if ( !mapped_pte->present ) + else { //now mapping should present for the page table assert( mapped_pde->present ); mapped_pte->all = pte.all; } - else - { - //todo - handle protection change here - } + finish: return ERROR_SUCCESS; @@ -158,7 +190,10 @@ assert ( vp != NULL ); return vp->physical_address; } -/*! creates page table for a given VA.*/ +/*! creates page table for a given VA. + \param pmap - physical map for which va mapping should be created + \param va - virtual address +*/ static void CreatePageTable(PHYSICAL_MAP_PTR pmap, UINT32 va ) { int pd_index; @@ -177,7 +212,14 @@ page_dir[pd_index].all = pa | USER_PDE_FLAG; } } -/*! Reports the given virtual address range's status*/ +/*! Reports the given virtual address range's status - readable/writeable or mapping not exists + \param va - virtual address + \param size - size of the va range + \return + VA_WRITEABLE if the page is writeable + VA_READABLE if the page is readable + VA_NOT_EXISTS if there is no physical mapping for the given va +*/ VA_STATUS GetVirtualRangeStatus(VADDR va, UINT32 size) { PAGE_DIRECTORY_ENTRY_PTR pde; @@ -202,3 +244,46 @@ return VA_WRITEABLE; return VA_READABLE; } + +/*! Returns Physical address for a given VA by looking inside the page tables + \param va - IN virtual address + \param pa - OUT physical adress + \return + VA_WRITEABLE if the page is writeable + VA_READABLE if the page is readable + VA_NOT_EXISTS if there is no physical mapping for the given va +*/ +VA_STATUS TranslatePaFromVa(VADDR va, VADDR * pa) +{ + PAGE_DIRECTORY_ENTRY_PTR pde; + PAGE_TABLE_ENTRY_PTR pte; + pde = PT_SELF_MAP_PAGE_DIRECTORY_PTR(va); + if ( !pde->present ) + return VA_NOT_EXISTS; + pte = PT_SELF_MAP_PAGE_TABLE1_PTE(va); + if ( !pte->present ) + return VA_NOT_EXISTS; + + *pa = PFN_TO_PA( pte->page_pfn ); + if ( pte->write ) + return VA_WRITEABLE; + return VA_READABLE; +} + + +/*! Internal function used to initialize the physical map structure*/ +int PhysicalMapCacheConstructor( void *buffer) +{ + PHYSICAL_MAP_PTR physical_map = (PHYSICAL_MAP_PTR) buffer; + memset(buffer, 0, sizeof(PHYSICAL_MAP) ); + + InitSpinLock( &physical_map->lock ); + return 0; +} +/*! Internal function used to clear the physical map structure*/ +int PhysicalMapCacheDestructor( void *buffer) +{ + PhysicalMapCacheConstructor(buffer); + return 0; +} + Modified: src/kernel/i386/mm/pmem_init.c =================================================================== --- src/kernel/i386/mm/pmem_init.c 2009-03-06 18:04:05 UTC (rev 351) +++ src/kernel/i386/mm/pmem_init.c 2009-03-07 06:53:49 UTC (rev 352) @@ -23,7 +23,7 @@ static void EnterKernelPageTableEntry(UINT32 va, UINT32 pa); /*the following contains where kernel code/data physical address start and end*/ -VADDR kernel_physical_address_start=KERNEL_PHYSICAL_ADDRESS_LOAD, kernel_physical_address_end=0; +UINT32 kernel_physical_address_start=KERNEL_PHYSICAL_ADDRESS_LOAD, kernel_physical_address_end=0; /*! Initializes memory areas and kernel page directory. * \param magic - magic number passed by multiboot loader @@ -39,15 +39,15 @@ /* get physical address of the memory area - currently no NUMA support for i386*/ *((int *)BOOT_ADDRESS ( &memory_area_count ) ) = 1; - *((VADDR *)BOOT_ADDRESS( &kernel_reserve_range.code_pa_start ) ) = PAGE_ALIGN ( BOOT_ADDRESS(&kernel_code_start) ); - *((VADDR *)BOOT_ADDRESS( &kernel_reserve_range.code_pa_end ) ) = PAGE_ALIGN_UP ( BOOT_ADDRESS(&ebss) ); + *((UINT32 *)BOOT_ADDRESS( &kernel_reserve_range.code_pa_start ) ) = PAGE_ALIGN ( BOOT_ADDRESS(&kernel_code_start) ); + *((UINT32 *)BOOT_ADDRESS( &kernel_reserve_range.code_pa_end ) ) = PAGE_ALIGN_UP ( BOOT_ADDRESS(&ebss) ); /* calculate the address range occupied by kernel modules */ if ( mbi->flags & MB_FLAG_MODS ) { MULTIBOOT_MODULE_PTR mod = (MULTIBOOT_MODULE_PTR)mbi->mods_addr; - * ((VADDR *)BOOT_ADDRESS( &kernel_reserve_range.module_pa_start ) ) = mod->mod_start; - * ((VADDR *)BOOT_ADDRESS( &kernel_reserve_range.module_pa_end ) ) = PAGE_ALIGN_UP( mod->mod_end ); + * ((UINT32 *)BOOT_ADDRESS( &kernel_reserve_range.module_pa_start ) ) = PAGE_ALIGN(mod->mod_start); + * ((UINT32 *)BOOT_ADDRESS( &kernel_reserve_range.module_pa_end ) ) = PAGE_ALIGN_UP( mod->mod_end ); } /* calculate the address range occupied by kernel symbol table*/ if ( mbi->flags & MB_FLAG_ELF ) @@ -78,14 +78,14 @@ /*if symbol table found update it in the global data structure*/ if( symbol_table_header ) { - * ((VADDR *)BOOT_ADDRESS( &kernel_reserve_range.symbol_pa_start ) ) = symbol_table_header->sh_addr; - * ((VADDR *)BOOT_ADDRESS( &kernel_reserve_range.symbol_pa_end ) ) = ((UINT32)symbol_table_header->sh_addr)+symbol_table_header->sh_size; + * ((UINT32 *)BOOT_ADDRESS( &kernel_reserve_range.symbol_pa_start ) ) = symbol_table_header->sh_addr; + * ((UINT32 *)BOOT_ADDRESS( &kernel_reserve_range.symbol_pa_end ) ) = ((UINT32)symbol_table_header->sh_addr)+symbol_table_header->sh_size; } /*if string table found update it in the global data structure*/ if( string_table_header ) { - * ((VADDR *)BOOT_ADDRESS( &kernel_reserve_range.string_pa_start ) ) = string_table_header->sh_addr; - * ((VADDR *)BOOT_ADDRESS( &kernel_reserve_range.string_pa_end ) ) = ((UINT32)string_table_header->sh_addr)+string_table_header->sh_size; + * ((UINT32 *)BOOT_ADDRESS( &kernel_reserve_range.string_pa_start ) ) = string_table_header->sh_addr; + * ((UINT32 *)BOOT_ADDRESS( &kernel_reserve_range.string_pa_end ) ) = ((UINT32)string_table_header->sh_addr)+string_table_header->sh_size; } } /*Initialize the memory area - calculate virtual page array*/ @@ -309,7 +309,7 @@ { int i; UINT32 * k_page_dir = (UINT32 *)BOOT_ADDRESS( kernel_page_directory ); - UINT32 va, physical_address, end_physical_address, module_start, kernel_symbol_table_start, kernel_string_table_start; + UINT32 va, physical_address, end_physical_address, module_start, kernel_symbol_table_start, kernel_symbol_table_size, kernel_string_table_start, kernel_string_table_size; MEMORY_AREA_PTR ma_pa; /*initialize all kernel pages as invalid*/ @@ -333,11 +333,11 @@ }while( physical_address < end_physical_address ); /* Enter mapping for kernel modules*/ - module_start = *((VADDR *)BOOT_ADDRESS( &kernel_reserve_range.module_pa_start)); + module_start = PAGE_ALIGN( *((VADDR *)BOOT_ADDRESS( &kernel_reserve_range.module_pa_start)) ); if ( module_start ) { physical_address = module_start; - end_physical_address = *((VADDR *)BOOT_ADDRESS( &kernel_reserve_range.module_pa_end));; + end_physical_address = PAGE_ALIGN_UP( *((VADDR *)BOOT_ADDRESS( &kernel_reserve_range.module_pa_end)) ); *((VADDR *)BOOT_ADDRESS( &kernel_reserve_range.module_va_start ) ) = va; do { @@ -345,17 +345,20 @@ physical_address += PAGE_SIZE; va += PAGE_SIZE; }while( physical_address < end_physical_address ); - *((VADDR *)BOOT_ADDRESS( &kernel_reserve_range.module_va_end ) ) = va; + *((UINT32 *)BOOT_ADDRESS( &kernel_reserve_range.module_va_end ) ) = va; } /* Enter mapping for kernel symbol table*/ - kernel_symbol_table_start = *((VADDR *)BOOT_ADDRESS( &kernel_reserve_range.symbol_pa_start)); + kernel_symbol_table_start = *((UINT32 *)BOOT_ADDRESS( &kernel_reserve_range.symbol_pa_start)); + kernel_symbol_table_size = *((UINT32 *)BOOT_ADDRESS( &kernel_reserve_range.symbol_pa_end)) - kernel_symbol_table_start; if ( kernel_symbol_table_start ) { - /*kernel symbol table may not page aligned address, so correct va*/ - * ((VADDR *)BOOT_ADDRESS ( &kernel_reserve_range.symbol_va_start ) ) = va + (kernel_symbol_table_start-PAGE_ALIGN(kernel_symbol_table_start)); - * ((UINT32 *)BOOT_ADDRESS ( &kernel_reserve_range.symbol_va_end ) ) += va; + UINT32 corrected_va; + /*symbol table may not page aligned address, so correct va*/ + corrected_va = va + (kernel_symbol_table_start-PAGE_ALIGN(kernel_symbol_table_start)); + * ((UINT32 *)BOOT_ADDRESS ( &kernel_reserve_range.symbol_va_start ) ) = corrected_va; + * ((UINT32 *)BOOT_ADDRESS ( &kernel_reserve_range.symbol_va_end ) ) = corrected_va + kernel_symbol_table_size; physical_address = kernel_symbol_table_start; - end_physical_address = * ((UINT32 *)BOOT_ADDRESS ( &kernel_reserve_range.symbol_pa_end ) ); + end_physical_address = PAGE_ALIGN_UP( * ((UINT32 *)BOOT_ADDRESS ( &kernel_reserve_range.symbol_pa_end ) ) ); do { EnterKernelPageTableEntry(va, physical_address); @@ -364,20 +367,23 @@ }while( physical_address < end_physical_address ); } /* Enter mapping for kernel string table*/ - kernel_string_table_start = *((VADDR *)BOOT_ADDRESS( &kernel_reserve_range.string_pa_start)); + kernel_string_table_start = *((UINT32 *)BOOT_ADDRESS( &kernel_reserve_range.string_pa_start)); + kernel_string_table_size = *((UINT32 *)BOOT_ADDRESS( &kernel_reserve_range.string_pa_end)) - kernel_string_table_start; if ( kernel_string_table_start ) { - /*kernel symbol table may not page aligned address, so correct va*/ - *((VADDR *)BOOT_ADDRESS( &kernel_reserve_range.string_va_start)) = va + (kernel_string_table_start-PAGE_ALIGN(kernel_string_table_start)); - *((VADDR *)BOOT_ADDRESS( &kernel_reserve_range.string_va_end)) += va; + UINT32 corrected_va; + /*string table may not page aligned address, so correct va*/ + corrected_va = va + (kernel_string_table_start-PAGE_ALIGN(kernel_string_table_start)); + *((UINT32 *)BOOT_ADDRESS( &kernel_reserve_range.string_va_start)) = corrected_va; + *((UINT32 *)BOOT_ADDRESS( &kernel_reserve_range.string_va_end)) = corrected_va + kernel_string_table_size; physical_address = kernel_string_table_start; - end_physical_address = *((VADDR *)BOOT_ADDRESS( &kernel_reserve_range.string_pa_end));; + end_physical_address = PAGE_ALIGN_UP( *((UINT32 *)BOOT_ADDRESS( &kernel_reserve_range.string_pa_end)) ); do { EnterKernelPageTableEntry(va, physical_address); physical_address += PAGE_SIZE; va += PAGE_SIZE; - }while( physical_address < end_physical_address ); + }while( physical_address <= end_physical_address ); } /*map virtual page array*/ @@ -403,7 +409,7 @@ } /*Update the kernel free VA start address*/ - *((VADDR *)BOOT_ADDRESS( &kernel_reserve_range.kmem_va_start ) ) = va; + *((UINT32 *)BOOT_ADDRESS( &kernel_reserve_range.kmem_va_start ) ) = va; /*self mapping*/ k_page_dir[PT_SELF_MAP_INDEX] = ((UINT32)k_page_dir) | KERNEL_PTE_FLAG; Modified: src/kernel/i386/pm/thread.c =================================================================== --- src/kernel/i386/pm/thread.c 2009-03-06 18:04:05 UTC (rev 351) +++ src/kernel/i386/pm/thread.c 2009-03-07 06:53:49 UTC (rev 352) @@ -4,7 +4,10 @@ */ #include <ace.h> +#include <kernel/debug.h> +#include <kernel/arch.h> #include <kernel/pm/task.h> +#include <kernel/i386/pmem.h> #include <kernel/i386/exception.h> #include <kernel/i386/gdt.h> #include <kernel/i386/ioapic.h> @@ -28,10 +31,11 @@ \param thread_container - thread container \param start_address - starting function pointer of the thread */ -void FillThreadContext(THREAD_CONTAINER_PTR thread_container, void * start_address) +void FillThreadContext(THREAD_CONTAINER_PTR thread_container, void * start_address, BYTE is_kernel_thread, VADDR user_stack) { UINT32 * stack_frame; REGS_PTR regs; + UINT32 cr3; assert( thread_container != NULL ); @@ -41,11 +45,27 @@ /*build exception frame*/ regs = (REGS_PTR)( ((BYTE*)stack_frame) - sizeof(REGS) ); - regs->cs = KERNEL_CODE_SELECTOR; + if ( is_kernel_thread ) + { + regs->cs = KERNEL_CODE_SELECTOR; + regs->ds = regs->es = regs->gs = regs->fs = regs->ss = KERNEL_DATA_SELECTOR; + } + else + { + regs->cs = USER_CODE_SELECTOR | USER_PRIVILEGE_LEVEL; + regs->ds = regs->es = regs->gs = regs->fs = regs->ss = USER_DATA_SELECTOR | USER_PRIVILEGE_LEVEL; + regs->useresp = user_stack; + } + regs->eip = (UINT32)start_address; - regs->ds = regs->es = regs->gs = regs->fs = regs->ss = KERNEL_DATA_SELECTOR; regs->eflags = EFLAG_VALUE; + /*get the physical address of the page directory*/ + if( TranslatePaFromVa((VADDR)thread_container->thread.task->virtual_map->physical_map->page_directory, &cr3) == VA_NOT_EXISTS ) + panic("page directory has no mapping"); + regs->cr3 = cr3; + + /*! update the stack address*/ thread_container->kernel_stack_pointer = (BYTE *) ((UINT32)regs) - sizeof(UINT32); } @@ -54,6 +74,9 @@ */ void SwitchContext(THREAD_CONTAINER_PTR thread_container) { + /*reset the ring 0 stack pointer*/ + processor_i386[GetCurrentProcessorId()].tss.esp0 = (UINT32)thread_container->kernel_stack_pointer; + asm volatile("movl %%eax, %%esp; jmp *%%ebx" : :"a"( thread_container->kernel_stack_pointer ), Modified: src/kernel/i386/system_call_handler.c =================================================================== --- src/kernel/i386/system_call_handler.c 2009-03-06 18:04:05 UTC (rev 351) +++ src/kernel/i386/system_call_handler.c 2009-03-07 06:53:49 UTC (rev 352) @@ -1,57 +1,53 @@ /*! \file kernel/i386/system_call_handler.c - \brief system call handler implementation + \brief i386 specific system call handler implementation */ #include <ace.h> +#include <ds/bits.h> +#include <kernel/debug.h> #include <kernel/system_call_handler.h> #include <kernel/interrupt.h> #include <kernel/mm/kmem.h> -#include <kernel/debug.h> -#include <heap/slab_allocator.h> #define SYSTEM_CALL_INTERRUPT_NUMBER (0x80-32) -extern int dummy_system_call(SYSTEM_CALL_ARGS_PTR, UINT32*); - -CACHE system_call_cache; - - -/* eax = system call number - * ebx, ecx, edx, esi, edi contains 5 arguments 0-4. +/*! Handles the system call interrupt + \param interrupt_info - passed by the generic ISR code - contains the register state at the time of system call raised + \param arg - not used + \note The following registers are used as input + eax = system call number + ebx, ecx, edx, esi, edi contains 5 arguments 0-4. + The following registers are used as output + eax = return value + ebx = error code */ ISR_RETURN_CODE SystemCallHandler(INTERRUPT_INFO_PTR interrupt_info, void * arg) { int sys_call_no; - UINT32 *sys_ret_val; + SYSTEM_CALL_ARGS sys_call_args; - SYSTEM_CALL_ARGS_PTR sys_call_args; - sys_call_no = interrupt_info->regs->eax; + + if( !VALUE_WITH_IN_RANGE(0, max_system_calls, sys_call_no) ) + { + KTRACE("sys_call_no out of limit %d\n", sys_call_no); + return ISR_END_PROCESSING; + } - if(sys_call_no < 0 || sys_call_no >= max_system_calls) - panic("SystemCallHandler: sys_call_no out of limit\n"); + sys_call_args.args[0] = interrupt_info->regs->ebx; + sys_call_args.args[1] = interrupt_info->regs->ecx; + sys_call_args.args[2] = interrupt_info->regs->edx; + sys_call_args.args[3] = interrupt_info->regs->esi; + sys_call_args.args[4] = interrupt_info->regs->edi; - sys_call_args = AllocateBuffer(&system_call_cache, 0); /* can sleep while memory is being allocated */ - - sys_call_args->args[0] = interrupt_info->regs->ebx; - sys_call_args->args[1] = interrupt_info->regs->ecx; - sys_call_args->args[2] = interrupt_info->regs->edx; - sys_call_args->args[3] = interrupt_info->regs->esi; - sys_call_args->args[4] = interrupt_info->regs->edi; /*now call the required system call*/ - sys_ret_val = &(interrupt_info->regs->eax); - interrupt_info->regs->ebx = (system_calls[sys_call_no])(sys_call_args, sys_ret_val); /* ebx will tell if system call succeeded(0) or not */ + interrupt_info->regs->ebx = (system_calls[sys_call_no])(&sys_call_args, &interrupt_info->regs->eax); /* ebx will tell if system ... [truncated message content] |
From: DilipSimha <nmd...@ni...> - 2009-03-06 18:41:08
|
Hi Akhil, Try accessing it without https. use just http. That should give u unauthorized access. Akhil S wrote: > No, I am not able to access this. It is throwing an error "This > function requires admin access". > Either take out admin access or grant me permission. > > Thanks, > -- > Akhil > > ------------------------------------------------------------------------ > *From:* Sam <sam...@gm...> > *To:* Akhil S <akh...@ya...> > *Cc:* ace...@li... > *Sent:* Friday, March 6, 2009 20:25:11 > *Subject:* Re: [Aceos-developers] Review/Commit Process? > > Are you not able to access > https://apps.sourceforge.net/codestriker/aceos/codestriker.pl?action=create > > > On Fri, Mar 6, 2009 at 5:15 PM, Akhil S <akh...@ya... > <mailto:akh...@ya...>> wrote: > > Hi Sam, > > > > It is not allowing me to create a new case as I dont have admin access. > > > > -- > > Akhil > > > > ________________________________ > > From: Sam <sam...@gm... <mailto:sam...@gm...>> > > To: Akhil S <akh...@ya... <mailto:akh...@ya...>> > > Cc: ace...@li... > <mailto:ace...@li...> > > Sent: Friday, March 6, 2009 15:41:17 > > Subject: Re: [Aceos-developers] Review/Commit Process? > > > > Hi Akhil, > > > > You can upload it for review at > > http://apps.sourceforge.net/codestriker/aceos/codestriker.pl > > Login using your sourceforge username and password. > > Refer http://codestriker.sourceforge.net/x402.html#AEN472 for creating > > a review patch. > > Before uploading do a "make clean" and then "make" and to make sure > > the build was successful without a warning. > > Also make sure, you have update SVN tree as dilip committed lot > > changes few days back. > > > > After the review you can commit. > > > > Sam > > > > On Fri, Mar 6, 2009 at 3:27 PM, Akhil S <akh...@ya... > <mailto:akh...@ya...>> wrote: > >> Hi, > >> > >> Hope you guys are doing well. I am planning to get accustomed to the > >> process > >> of review/check-in of files. I have found a trivial bug. Was > thinking of > >> sending it for review and committing it. Please share the procedure > to do > >> the same. If its lengthy/cumbersome call me. > >> > >> -- > >> Akhil > >> > >> ________________________________ > >> New Email names for you! > >> Get the Email name you've always wanted on the new @ymail and > @rocketmail. > >> Hurry before someone else does! > >> > >> > ------------------------------------------------------------------------------ > >> Open Source Business Conference (OSBC), March 24-25, 2009, San > Francisco, > >> CA > >> -OSBC tackles the biggest issue in open source: Open Sourcing the > >> Enterprise > >> -Strategies to boost innovation and cut costs with open source > >> participation > >> -Receive a $600 discount off the registration fee with the source code: > >> SFAD > >> http://p.sf.net/sfu/XcvMzF8H > >> _______________________________________________ > >> Aceos-developers mailing list > >> Ace...@li... > <mailto:Ace...@li...> > >> https://lists.sourceforge.net/lists/listinfo/aceos-developers > >> > >> > > > > ________________________________ > > New Email names for you! > > Get the Email name you've always wanted on the new @ymail and > @rocketmail. > > Hurry before someone else does! > > ------------------------------------------------------------------------ > New Email addresses available on Yahoo! > <http://sg.rd.yahoo.com/aa/mail/domainchoice/mail/signature/*http://mail.promotions.yahoo.com/newdomains/aa/> > > Get the Email name you've always wanted on the new @ymail and @rocketmail. > Hurry before someone else does! > ------------------------------------------------------------------------ > > ------------------------------------------------------------------------------ > Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA > -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise > -Strategies to boost innovation and cut costs with open source participation > -Receive a $600 discount off the registration fee with the source code: SFAD > http://p.sf.net/sfu/XcvMzF8H > ------------------------------------------------------------------------ > > _______________________________________________ > Aceos-developers mailing list > Ace...@li... > https://lists.sourceforge.net/lists/listinfo/aceos-developers > |
From: <nmd...@us...> - 2009-03-06 18:04:09
|
Revision: 351 http://aceos.svn.sourceforge.net/aceos/?rev=351&view=rev Author: nmdilipsimha Date: 2009-03-06 18:04:05 +0000 (Fri, 06 Mar 2009) Log Message: ----------- Fixed some bugs in wait events and timeout queue. Modified Paths: -------------- src/include/kernel/pm/task.h src/include/kernel/pm/timeout_queue.h src/include/kernel/system_call_handler.h src/include/kernel/wait_event.h src/kernel/i386/system_call_handler.c src/kernel/makefile src/kernel/pm/task.c src/kernel/pm/timeout_queue.c src/kernel/system_calls.c src/kernel/wait_event.c Added Paths: ----------- src/include/kernel/ipc.h src/kernel/ipc/ src/kernel/ipc/message_queue.c Added: src/include/kernel/ipc.h =================================================================== --- src/include/kernel/ipc.h (rev 0) +++ src/include/kernel/ipc.h 2009-03-06 18:04:05 UTC (rev 351) @@ -0,0 +1,42 @@ +/*! + * \file include/kernel/ipc.h + * \brief Contains declarations for IPC methodologies used. + */ + +#ifndef IPC_H +#define IPC_H + +#include <ace.h> +#include <ds/list.h> +#include <sync/spinlock.h> +#include <kernel/system_call_handler.h> + +#define MESSAGE_QUEUE_NO_WAIT -1 +#define MESSAGE_QUEUE_CAN_WAIT 0 + +extern UINT32 max_message_queue_length; /* System wide tunable to control the size of message queue in task structure */ + +enum MESSAGE_BUFFER_TYPE +{ + MESSAGE_BUFFER_TYPE_VALUE, + MESSAGE_BUFFER_TYPE_BUFFER +}; + + +typedef struct message_buffer +{ + LIST message_buffer_queue; + enum MESSAGE_BUFFER_TYPE type; /* type=0 means In VALUE; type=1 means In BUFFER */ + UINT32 args[TOTAL_SYSTEM_CALL_ARGS]; + UINT32 from_pid; +}MESSAGE_BUFFER, *MESSAGE_BUFFER_PTR; + + + + +#include <kernel/pm/task.h> + +ERROR_CODE SendMessage(MESSAGE_BUFFER_PTR mbuf, UINT32 pid_target_task, UINT8 queue_no, UINT32 wait_time); +ERROR_CODE ReceiveMessage(MESSAGE_BUFFER_PTR mbuf, UINT8 queue_no, UINT32 wait_time); + +#endif Modified: src/include/kernel/pm/task.h =================================================================== --- src/include/kernel/pm/task.h 2009-02-27 04:21:19 UTC (rev 350) +++ src/include/kernel/pm/task.h 2009-03-06 18:04:05 UTC (rev 351) @@ -19,16 +19,29 @@ #define KERNEL_STACK_SIZE (PAGE_SIZE) -typedef struct task +typedef struct task TASK, *TASK_PTR; +/* include ipc.h after defining TASK_PTR because ipc.h uses it */ +#include <kernel/ipc.h> +#include <kernel/wait_event.h> + +#define MESSAGE_QUEUES_PER_TASK 5 + +struct task { - SPIN_LOCK lock; /*! lock for the entire structure */ - int reference_count; + SPIN_LOCK lock; /*! lock for the entire structure */ + int reference_count; - VIRTUAL_MAP_PTR virtual_map; /*! virtual map for this task */ + VIRTUAL_MAP_PTR virtual_map; /*! virtual map for this task */ - THREAD_PTR thread_head; /*! threads in the same task */ -}TASK, * TASK_PTR; + THREAD_PTR thread_head; /*! threads in the same task */ + SPIN_LOCK message_queue_lock[MESSAGE_QUEUES_PER_TASK]; + MESSAGE_BUFFER_PTR message_queue[MESSAGE_QUEUES_PER_TASK]; /*! Pointer to head of the message buffer queue */ + WAIT_EVENT_PTR wait_event_message_queue[MESSAGE_QUEUES_PER_TASK]; /*! Pointer to wait event queue for message queue variable */ + SPIN_LOCK wait_event_lock[MESSAGE_QUEUES_PER_TASK]; + UINT32 message_queue_length; /*! Number of message buffers that can be present in the queue */ +}; + typedef enum { THREAD_STATE_READY = 1, /*! thread is ready to run */ @@ -43,7 +56,7 @@ struct thread { - SPIN_LOCK lock; /*! lock for the entire structure */ + SPIN_LOCK lock; /*! lock for the entire structure */ int reference_count; TASK_PTR task; /*! back pointer to task */ @@ -110,6 +123,10 @@ void FillThreadContext(THREAD_CONTAINER_PTR thread_container, void * start_address); void SwitchContext(THREAD_CONTAINER_PTR thread_container); +TASK_PTR PidToTask(UINT32 pid); +UINT32 TaskToPid(TASK_PTR task); +UINT32 GetCurrentPid(void); + #ifdef __cplusplus } #endif Modified: src/include/kernel/pm/timeout_queue.h =================================================================== --- src/include/kernel/pm/timeout_queue.h 2009-02-27 04:21:19 UTC (rev 350) +++ src/include/kernel/pm/timeout_queue.h 2009-03-06 18:04:05 UTC (rev 351) @@ -18,5 +18,6 @@ INT32 Sleep(UINT32 timeout); void ValuateTimeoutQueue(void); +int RemoveFromTimeoutQueue(void); #endif Modified: src/include/kernel/system_call_handler.h =================================================================== --- src/include/kernel/system_call_handler.h 2009-02-27 04:21:19 UTC (rev 350) +++ src/include/kernel/system_call_handler.h 2009-03-06 18:04:05 UTC (rev 351) @@ -13,8 +13,10 @@ #define SYSTEM_CALL_CACHE_MIN_BUFFERS 50 #define SYSTEM_CALL_CACHE_MAX_SLABS 50 +#define TOTAL_SYSTEM_CALL_ARGS 5 + typedef struct system_call_args { - UINT32 arg1, arg2, arg3, arg4, arg5; + UINT32 args[TOTAL_SYSTEM_CALL_ARGS]; }SYSTEM_CALL_ARGS, *SYSTEM_CALL_ARGS_PTR; void SetupSystemCallHandler(void); Modified: src/include/kernel/wait_event.h =================================================================== --- src/include/kernel/wait_event.h 2009-02-27 04:21:19 UTC (rev 350) +++ src/include/kernel/wait_event.h 2009-03-06 18:04:05 UTC (rev 351) @@ -27,7 +27,8 @@ }; WAIT_EVENT_PTR AddToEventQueue(WAIT_EVENT_PTR *wait_queue); -int WaitForEvent(WAIT_EVENT_PTR event, int timeout); +UINT32 WaitForEvent(WAIT_EVENT_PTR event, UINT32 timeout); void WakeUpEvent(WAIT_EVENT_PTR *event, int flag); +void RemoveEventFromQueue(WAIT_EVENT_PTR search_wait_event, WAIT_EVENT_PTR *wait_queue); #endif Modified: src/kernel/i386/system_call_handler.c =================================================================== --- src/kernel/i386/system_call_handler.c 2009-02-27 04:21:19 UTC (rev 350) +++ src/kernel/i386/system_call_handler.c 2009-03-06 18:04:05 UTC (rev 351) @@ -34,11 +34,11 @@ sys_call_args = AllocateBuffer(&system_call_cache, 0); /* can sleep while memory is being allocated */ - sys_call_args->arg1 = interrupt_info->regs->ebx; - sys_call_args->arg2 = interrupt_info->regs->ecx; - sys_call_args->arg3 = interrupt_info->regs->edx; - sys_call_args->arg4 = interrupt_info->regs->esi; - sys_call_args->arg5 = interrupt_info->regs->edi; + sys_call_args->args[0] = interrupt_info->regs->ebx; + sys_call_args->args[1] = interrupt_info->regs->ecx; + sys_call_args->args[2] = interrupt_info->regs->edx; + sys_call_args->args[3] = interrupt_info->regs->esi; + sys_call_args->args[4] = interrupt_info->regs->edi; /*now call the required system call*/ sys_ret_val = &(interrupt_info->regs->eax); interrupt_info->regs->ebx = (system_calls[sys_call_no])(sys_call_args, sys_ret_val); /* ebx will tell if system call succeeded(0) or not */ Added: src/kernel/ipc/message_queue.c =================================================================== --- src/kernel/ipc/message_queue.c (rev 0) +++ src/kernel/ipc/message_queue.c 2009-03-06 18:04:05 UTC (rev 351) @@ -0,0 +1,166 @@ +/*! + * \file kernel/ipc/message_queue.c + * \brief Message queue IPC handling + */ + +#include <ace.h> +#include <kernel/ipc.h> +#include <kernel/pm/task.h> +#include <string.h> +#include <kernel/debug.h> + +UINT32 max_message_queue_length; /* System wide tunable to control the size of message queue in task structure */ + +/*! \brief Sends a message from current task to the task specified. Holds target task's message queue lock accross the life time of function. + * If flag contains NO_WAIT, then this will return with error if queue is full. By default it will wait indefinitely until it places the message on the queue. + * \param mbuf Contains Message buffer. + * \param pid_target_task_task Pid of target task to which the message has to be posted. + * \param queue_no Offset to task->message_queue array. + * \param wait_time Indicates how much time the sender can wait till the message is sent. + */ +ERROR_CODE SendMessage(MESSAGE_BUFFER_PTR mbuf, UINT32 pid_target_task, UINT8 queue_no, UINT32 wait_time) +{ + MESSAGE_BUFFER_PTR kern_msg_buf; + ERROR_CODE error_ret = ERROR_SUCCESS;; + WAIT_EVENT_PTR my_wait_event; + int loop; + TASK_PTR to_task; + + assert(queue_no < MESSAGE_QUEUES_PER_TASK); + + to_task = PidToTask(pid_target_task); + if(to_task == NULL) + return ERROR_INVALID_PARAMETER; + SpinLock( &(to_task->message_queue_lock[queue_no]) ); + + + if( (wait_time == MESSAGE_QUEUE_NO_WAIT) && (to_task->message_queue_length >= max_message_queue_length) ) + { + SpinUnlock( &(to_task->lock) ); + return ERROR_NOT_ENOUGH_MEMORY; + } + else if( (wait_time == MESSAGE_QUEUE_CAN_WAIT) && (to_task->message_queue_length >= max_message_queue_length) ) + { + /* Wait for this message queue to become thin */ + my_wait_event = AddToEventQueue( &(to_task->wait_event_message_queue[queue_no]) ); + SpinUnlock( &(to_task->message_queue_lock[queue_no]) ); /* We need to unlock because we block in WaitForEvent */ + WaitForEvent(my_wait_event, wait_time); + SpinLock( &(to_task->message_queue_lock[queue_no]) ); /* take the lock again because we have returned from blocked state */ + assert(my_wait_event->fired == 1); + kfree(my_wait_event); + } + + + kern_msg_buf = (MESSAGE_BUFFER_PTR)kmalloc(sizeof(MESSAGE_BUFFER), KMEM_NO_FAIL); + kern_msg_buf->from_pid = GetCurrentPid(); + + InitList( &(kern_msg_buf->message_buffer_queue) ); + + switch( mbuf->type) + { + case MESSAGE_BUFFER_TYPE_VALUE: /* In value */ + for(loop=0 ; loop < TOTAL_SYSTEM_CALL_ARGS ; loop++) + kern_msg_buf->args[loop] = mbuf->args[loop]; + break; + case MESSAGE_BUFFER_TYPE_BUFFER: /* In buffers. Copy the message inside buffer from this user space to target user space */ + /* args[0] will contain start address and args[1] will contain length of the buffer. */ + if(mbuf->args[0] == NULL || mbuf->args[1] < 0 || mbuf->args[1] > PAGE_SIZE) + return ERROR_INVALID_PARAMETER; + + kern_msg_buf->args[0] = (UINT32)kmalloc(mbuf->args[1], KMEM_NO_FAIL); + (void)memcpy((void*)kern_msg_buf->args[0], (const void*)(mbuf->args[0]), mbuf->args[1]); + break; + default: + return ERROR_INVALID_PARAMETER; + } + + AddToListTail( &(to_task->message_queue[queue_no]->message_buffer_queue), &(kern_msg_buf->message_buffer_queue) ); + SpinUnlock( &(to_task->lock) ); + return error_ret; +} + +/*! \brief Receives a message present in the tasks's message queue. + * Holds task lock accross the life time of function. + * \param mbuf Pointer to an empty message buffer allocated(malloced) by user. This will be loaded with the required message. mbuf->type will be specified from user. depending on this mbuf->args[0] and mbuf->args[1] will also be filled by user. + * \param wait_time Time in seconds that the user wants to wait for the message. If 0, then it's non blocking, if -1, it's blocking forever. + */ +ERROR_CODE ReceiveMessage(MESSAGE_BUFFER_PTR mbuf, UINT8 queue_no, UINT32 wait_time) +{ + MESSAGE_BUFFER_PTR message_queue_ptr; + ERROR_CODE error_ret = ERROR_SUCCESS;; + TASK_PTR my_task; + WAIT_EVENT_PTR my_wait_event; + UINT32 ret_timeout, loop; + + if(queue_no > MESSAGE_QUEUES_PER_TASK) + return ERROR_INVALID_PARAMETER; + + my_task = GetCurrentThread()->task; + SpinLock( &(my_task->message_queue_lock[queue_no]) ); + + message_queue_ptr = my_task->message_queue[queue_no]; + + if(wait_time==MESSAGE_QUEUE_CAN_WAIT) /* Wait till the desired message arrives */ + { + if(message_queue_ptr == NULL) + { + SpinUnlock( &(my_task->message_queue_lock[queue_no]) ); + my_wait_event = AddToEventQueue( &(my_task->wait_event_message_queue[queue_no]) ); + WaitForEvent(my_wait_event, 0); /* block forever until some message arrives */ + SpinLock( &(my_task->message_queue_lock[queue_no]) ); /* take the lock after returning from blocked state */ + } + } + else if(wait_time==MESSAGE_QUEUE_NO_WAIT) + { + if(message_queue_ptr == NULL) + { + SpinUnlock( &(my_task->message_queue_lock[queue_no]) ); + return ERROR_NOT_FOUND; + } + } + else /* wait_time > 0 */ + { + search_queue: + if(message_queue_ptr == NULL) + { + if(wait_time < 0) + { + SpinUnlock( &(my_task->message_queue_lock[queue_no]) ); + return ERROR_NOT_FOUND; /* In case of missed wakeup's from WaitForEvent, wait time will be in -ve */ + } + + my_wait_event = AddToEventQueue( &(my_task->wait_event_message_queue[queue_no]) ); + SpinUnlock( &(my_task->message_queue_lock[queue_no]) ); + ret_timeout = WaitForEvent(my_wait_event, wait_time); /* Block till wait_time expires or until any message arrives */ + if(ret_timeout == 0 || my_task->wait_event_message_queue[queue_no] == NULL) /* timeout happened and our event didn't get fired */ + return ERROR_NOT_FOUND; + else if(wait_time-ret_timeout > 0) /* ret_timeout is > 0 and < wait_time and indicates time left in sleep */ + { + assert(my_wait_event->fired == 1); + /* we got here because an even got fired before the timeout happened */ + SpinLock( &(my_task->message_queue_lock[queue_no]) ); + message_queue_ptr = my_task->message_queue[queue_no]; + wait_time -= ret_timeout; + goto search_queue; + } + /* we have got the message, so can continue fetching it */ + SpinLock( &(my_task->message_queue_lock[queue_no]) ); /* take the lock after returning from blocked state */ + } + } + + RemoveFromList( &(message_queue_ptr->message_buffer_queue) ); + + switch(mbuf->type) + { + case MESSAGE_BUFFER_TYPE_VALUE: /* In value */ + for(loop=0 ; loop < TOTAL_SYSTEM_CALL_ARGS ; loop++) + mbuf->args[loop] = message_queue_ptr->args[loop]; + break; + case MESSAGE_BUFFER_TYPE_BUFFER: /* In buffers. Copy the message inside buffer from this user space to target user space */ + (void)memcpy((void*)(mbuf->args[0]), (const void*)message_queue_ptr->args[0], mbuf->args[1]); + break; + } + + SpinUnlock( &(my_task->message_queue_lock[queue_no]) ); + return error_ret; +} Modified: src/kernel/makefile =================================================================== --- src/kernel/makefile 2009-02-27 04:21:19 UTC (rev 350) +++ src/kernel/makefile 2009-03-06 18:04:05 UTC (rev 351) @@ -12,11 +12,10 @@ LIBS= $(OBJ)/libheap.a $(OBJ)/libds.a $(OBJ)/libstring.a $(OBJ)/libsync.a #static kernel modules -STATIC_MODS= $(OBJ)/arch.a $(OBJ)/iom.a $(OBJ)/rtc.a $(OBJ)/pit.a $(OBJ)/acpi.a +STATIC_MODS= $(OBJ)/arch.a $(OBJ)/iom.a $(OBJ)/rtc.a $(OBJ)/pit.a $(OBJ)/acpi.a #generica kernel object files -KERNEL_OBJ = $(patsubst %.c,%.o,$(wildcard *.c)) $(patsubst %.c,%.o,$(wildcard mm/*.c)) $(patsubst %.c,%.o,$(wildcard pm/*.c)) - +KERNEL_OBJ = $(patsubst %.c,%.o,$(wildcard *.c)) $(patsubst %.c,%.o,$(wildcard mm/*.c)) $(patsubst %.c,%.o,$(wildcard pm/*.c)) $(patsubst %.c,%.o,$(wildcard ipc/*.c)) #phony command - all - makes all object all: $(TARGET) Modified: src/kernel/pm/task.c =================================================================== --- src/kernel/pm/task.c 2009-02-27 04:21:19 UTC (rev 350) +++ src/kernel/pm/task.c 2009-03-06 18:04:05 UTC (rev 351) @@ -2,3 +2,21 @@ \file task.c \brief */ + +#include <ace.h> +#include <kernel/pm/task.h> + +TASK_PTR PidToTask(UINT32 pid) +{ + return NULL; +} + +UINT32 TaskToPid(TASK_PTR task) +{ + return 0; +} + +UINT32 GetCurrentPid(void) +{ + return TaskToPid( GetCurrentThread()->task ); +} Modified: src/kernel/pm/timeout_queue.c =================================================================== --- src/kernel/pm/timeout_queue.c 2009-02-27 04:21:19 UTC (rev 350) +++ src/kernel/pm/timeout_queue.c 2009-03-06 18:04:05 UTC (rev 351) @@ -9,21 +9,86 @@ #include <kernel/pit.h> volatile TIMEOUT_QUEUE_PTR timeout_queue; +SPIN_LOCK timeout_queue_lock; +/*! Removes the current_thread from the global timeout queue + * Returns 0 if found and removed else returns -1(not found) + */ +int RemoveFromTimeoutQueue(void) +{ + THREAD_PTR wake_me_thread, current_thread; + LIST_PTR temp_list1; + TIMEOUT_QUEUE_PTR temp_queue; + IRQ_PRIORITY_LEVELS my_ipl; + int ret_val = -1; /* 0=FOUND ; -1= NOT FOUND */ + + if(timeout_queue == NULL) + return -1; + + //my_ipl = RaiseInterruptPriorityLevel(IRQ_PRIORITY_LEVELS_TIMER); + SpinLock( &(timeout_queue_lock) ); + + current_thread = GetCurrentThread(); + wake_me_thread = STRUCT_ADDRESS_FROM_MEMBER(timeout_queue, THREAD, timeout_queue); + if(current_thread == wake_me_thread) + { + if( IsListEmpty(&(timeout_queue->queue)) ) /* Only 1 entry.. so just check that out. */ + timeout_queue = NULL; + else + { + temp_queue = STRUCT_ADDRESS_FROM_MEMBER( (timeout_queue->queue).next, TIMEOUT_QUEUE, queue); + RemoveFromList( &(timeout_queue->queue) ); + timeout_queue = temp_queue; + } + + ret_val = 0; + goto final; + } + + /* Need not check the header node again.. continue with the other nodes */ + LIST_FOR_EACH( temp_list1, &(timeout_queue->queue) ) + { + temp_queue = STRUCT_ADDRESS_FROM_MEMBER(temp_list1, TIMEOUT_QUEUE, queue); + + wake_me_thread = STRUCT_ADDRESS_FROM_MEMBER(temp_queue, THREAD, timeout_queue); + if(current_thread == wake_me_thread) + { + RemoveFromList( &(temp_queue->queue) ); + ret_val = 0; + goto final; + } + } + +final: + SpinUnlock( &(timeout_queue_lock) ); + //RestoreInterruptPriorityLevel(my_ipl); + return ret_val; +} + + +/*! + * \brief This is called only from timer handler. + */ void ValuateTimeoutQueue(void) { TIMEOUT_QUEUE_PTR temp_queue; LIST_PTR temp_list1, temp_list2; THREAD_PTR wake_me_thread; - - if(timeout_queue == NULL || timeout_queue->sleep_time > timer_ticks) + + if(timeout_queue == NULL || ( timeout_queue && (timeout_queue->sleep_time > timer_ticks) ) ) return; + /* Raise the ipl to timer, so that timer cannot interrupt and call this function again while we are still in */ + //RaiseInterruptPriorityLevel(IRQ_PRIORITY_LEVELS_TIMER); + SpinLock( &(timeout_queue_lock) ); + if( IsListEmpty(&(timeout_queue->queue)) ) { wake_me_thread = STRUCT_ADDRESS_FROM_MEMBER(timeout_queue, THREAD, timeout_queue); + timeout_queue = NULL; + SpinUnlock( &(timeout_queue_lock) ); + //RestoreInterruptPriorityLevel(my_ipl); ResumeThread(wake_me_thread); - timeout_queue = NULL; return; } @@ -35,8 +100,10 @@ if( IsListEmpty(&(timeout_queue->queue)) ) { wake_me_thread = STRUCT_ADDRESS_FROM_MEMBER(temp_queue, THREAD, timeout_queue); + timeout_queue = NULL; + SpinUnlock( &(timeout_queue_lock) ); + //RestoreInterruptPriorityLevel(my_ipl); ResumeThread(wake_me_thread); - timeout_queue = NULL; return; } @@ -46,10 +113,14 @@ /* Now the header is gone, so update it */ timeout_queue = STRUCT_ADDRESS_FROM_MEMBER(temp_list2, TIMEOUT_QUEUE, queue); } + + SpinUnlock( &(timeout_queue_lock) ); + //RestoreInterruptPriorityLevel(my_ipl); + return; } /*! -\brief Searches timeout queue for an appropriate slot. This queue is sorted in ascending order aking it easy for removal. +\brief Searches timeout queue for an appropriate slot. This queue is sorted in ascending order making it easy for removal. \param find_time time in ticks which is the key to search in the timeout queue returns pointer to a node in timeout queue, which has it's sleep_time just below our find_time */ @@ -84,16 +155,33 @@ static void AddToTimeoutQueue(TIMEOUT_QUEUE_PTR new_object) { TIMEOUT_QUEUE_PTR prev_node; + + assert(new_object->sleep_time >= timer_ticks); + InitList( &(new_object->queue) ); + SpinLock( &(timeout_queue_lock) ); + /* Special case: If we should go in first slot of an existing timeout queue */ + if( timeout_queue && (timeout_queue->sleep_time > new_object->sleep_time) ) + { + LinkLists( &(new_object->queue), &(timeout_queue->queue) ); + timeout_queue = new_object; + SpinUnlock( &(timeout_queue_lock) ); + return; + } + /* Search for the correct slot in timeout_queue to place this new_object*/ prev_node = SearchTimeoutQueue(new_object->sleep_time); if(prev_node == NULL) { timeout_queue = new_object; + SpinUnlock( &(timeout_queue_lock) ); return; } + AddToList( &(prev_node->queue), &(new_object->queue) ); + SpinUnlock( &(timeout_queue_lock) ); + return; } /*! @@ -111,5 +199,6 @@ AddToTimeoutQueue(my_timeout_queue); PauseThread(); + //kprintf("Thread %p Woken from sleep: rem time: %d\n", GetCurrentThread(), my_timeout_queue->sleep_time - timer_ticks); return TICKS_TO_MILLISECONDS( (my_timeout_queue->sleep_time - timer_ticks) ); } Modified: src/kernel/system_calls.c =================================================================== --- src/kernel/system_calls.c 2009-02-27 04:21:19 UTC (rev 350) +++ src/kernel/system_calls.c 2009-03-06 18:04:05 UTC (rev 351) @@ -28,11 +28,11 @@ { kprintf("dummy system call called\n"); kprintf("arg1=%d arg2=%d arg3=%d arg4=%d arg5=%d\n", - sys_call_args->arg1, - sys_call_args->arg2, - sys_call_args->arg3, - sys_call_args->arg4, - sys_call_args->arg5 ); + sys_call_args->args[0], + sys_call_args->args[1], + sys_call_args->args[2], + sys_call_args->args[3], + sys_call_args->args[4] ); *retval = 100; /* This is for user program to interpret */ return ERROR_SUCCESS; /* Success . This is for sys call handler*/ Modified: src/kernel/wait_event.c =================================================================== --- src/kernel/wait_event.c 2009-02-27 04:21:19 UTC (rev 350) +++ src/kernel/wait_event.c 2009-03-06 18:04:05 UTC (rev 351) @@ -6,6 +6,7 @@ #include <ace.h> #include <kernel/wait_event.h> #include <kernel/pm/scheduler.h> +#include <kernel/pm/timeout_queue.h> #include <kernel/interrupt.h> #include <kernel/mm/kmem.h> #include <kernel/debug.h> @@ -29,7 +30,7 @@ *wait_queue = wait_event; else { - AddToList( &((*wait_queue)->in_queue), &(wait_event->in_queue) ); + AddToListTail( &((*wait_queue)->in_queue), &(wait_event->in_queue) ); } return wait_event; @@ -40,21 +41,26 @@ \brief Waits for a particular event to fire until specified timeout. \param event Event on which we have to wait \param timeout Units in milli secobds; If =0, no timeout, block until the event happens; >0, block until either event fires up or the timeout happens. -Returns 0 on success(event happened before timeout.) or -1 on failure(timeout happenned and no event showed up) +Returns >0(remaining time) if event happened before timeout or 0 on failure(timeout happenned and no event showed up) */ -int WaitForEvent(WAIT_EVENT_PTR event, int timeout) +UINT32 WaitForEvent(WAIT_EVENT_PTR event, UINT32 timeout) { int ret_timeout; THREAD_PTR my_thread; assert( event->thread == GetCurrentThread() ); /* This is necessary to avoid rogue threads inducing sleep to innocent threads */ - + if(timeout > 0) /* Wait until the event fires up or the timeout expires */ { ret_timeout = Sleep(timeout); /* This will block for the specified time */ if(ret_timeout > 0) /* We woke up because, some other event finished */ - return 0; + { + /* Removes the registered timeout event from timout queue */ + if (RemoveFromTimeoutQueue() == -1) + panic("timeout queue corrupted\n"); + return ret_timeout; + } else /* Timeout happenned and no event fired up. */ { my_thread = (THREAD_PTR)(event->thread); @@ -65,9 +71,8 @@ event->thread = NULL; SpinUnlock( &(my_thread->wait_event_queue_lock) ); } - return -1; + return 0; } - } else /* Wait until the event fires up */ { @@ -106,20 +111,22 @@ ClearRelatedWaitEvents(temp_wait_event); temp_wait_event->thread = NULL; SpinUnlock( &(thread->wait_event_queue_lock) ); + temp_wait_event->fired = 1; SpinLock( &(thread->lock) ); if(thread->state == THREAD_STATE_RUN) { thread->state = THREAD_STATE_EVENT_FIRED; /* An intermediate state to instruct the thread not to sleep or block */ + //kprintf("special case!! event fired while thread about to sleep\n"); SpinUnlock( &(thread->lock) ); } else { SpinUnlock( &(thread->lock) ); + //kprintf("Event %p waking thread %p\n", temp_wait_event, thread); ResumeThread(thread); } } - temp_wait_event->fired = 1; } temp_wait_event = *event; *event = NULL; /* This is the queue pointer from the structure. The wait_event is still active and should be freed after the thread is woken up*/ @@ -142,23 +149,29 @@ ClearRelatedWaitEvents(temp_wait_event); temp_wait_event->thread = NULL; SpinUnlock( &(thread->wait_event_queue_lock) ); + temp_wait_event->fired = 1; SpinLock( &(thread->lock) ); if(thread->state == THREAD_STATE_RUN) { thread->state = THREAD_STATE_EVENT_FIRED; /* An intermediate state to instruct the thread not to sleep or block */ + //kprintf("special case!! event fired while thread: %p about to sleep\n", thread); SpinUnlock( &(thread->lock) ); } else { SpinUnlock( &(thread->lock) ); + //kprintf("Event %p waking thread %p\n", temp_wait_event, thread); ResumeThread(thread); } } - temp_wait_event->fired = 1; } - +/*! + * \brief Clears related threade events. + * \param event Wait event for which the related thread events are to be cleared + * Note: Only the THREAD pointer in event is made NULL and the event is disengaged from the thread events LIST. + */ static void ClearRelatedWaitEvents(WAIT_EVENT_PTR event) { WAIT_EVENT_PTR temp_wait_event; @@ -167,13 +180,54 @@ head_list = &(event->thread_events); LIST_FOR_EACH_REMOVAL(temp_list1, temp_list2, head_list ) { + if(temp_list1 == head_list) + continue; temp_wait_event = STRUCT_ADDRESS_FROM_MEMBER(temp_list1, WAIT_EVENT, thread_events); RemoveFromList( &(temp_wait_event->thread_events) ); + //kprintf("Event: %p Will not wake up thread: %p\n", temp_wait_event, temp_wait_event->thread); temp_wait_event->thread = NULL; - head_list = temp_list2; + //head_list = temp_list2; } - temp_wait_event = STRUCT_ADDRESS_FROM_MEMBER(head_list, WAIT_EVENT, thread_events); - RemoveFromList( &(temp_wait_event->thread_events) ); - temp_wait_event->thread = NULL; + //temp_wait_event = STRUCT_ADDRESS_FROM_MEMBER(head_list, WAIT_EVENT, thread_events); + //RemoveFromList( &(temp_wait_event->thread_events) ); + //temp_wait_event->thread = NULL; } + + +/*! + * \brief Removes the event from the given queue. This call is done after an related event was fired or if an timeout happened. + * \param wait_event Event that has to be removed. + * \param wait_queue Queue from which the event is to be removed + * NOTE: IN queue lock in the parent structure has to be taken before entering this function. + */ +void RemoveEventFromQueue(WAIT_EVENT_PTR search_wait_event, WAIT_EVENT_PTR *wait_queue) +{ + LIST_PTR temp1; + WAIT_EVENT_PTR temp_event; +// kprintf("remove event=%p from queue=%p\n", search_wait_event, *wait_queue); + + if(*wait_queue == search_wait_event) + { + if( IsListEmpty( &(search_wait_event->in_queue) ) ) + { + // kprintf("queue %p is made NULL\n"); + *wait_queue = NULL; + } + else + RemoveFromList( &((*wait_queue)->in_queue) ); + + return; + } + + LIST_FOR_EACH(temp1, &((*wait_queue)->in_queue) ) + { + temp_event = STRUCT_ADDRESS_FROM_MEMBER(temp1, WAIT_EVENT, in_queue); + if(temp_event == search_wait_event) + { + assert(temp_event->thread == NULL); /* make sure that this event is dormant */ + RemoveFromList( &(temp_event->in_queue) ); + return; + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |