started in on a bunch of memory management code
This commit is contained in:
parent
3609cb2627
commit
54529bc017
19
idl/comrogue/allocator.idl
Normal file
19
idl/comrogue/allocator.idl
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import "comrogue/objectbase.idl";
|
||||||
|
|
||||||
|
/*-------------------
|
||||||
|
* IMalloc interface
|
||||||
|
*-------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
[object, uuid(00000002-0000-0000-C000-000000000046)]
|
||||||
|
interface IMalloc : IUnknown
|
||||||
|
{
|
||||||
|
[unique] typedef IMalloc *PMALLOC;
|
||||||
|
PVOID Alloc([in] SIZE_T cb);
|
||||||
|
PVOID Realloc([in] PVOID pv, [in] SIZE_T cb);
|
||||||
|
void Free([in] PVOID pv);
|
||||||
|
SIZE_T GetSize([in] PVOID pv);
|
||||||
|
INT32 DidAlloc([in] PVOID pv);
|
||||||
|
void HeapMinimize(void);
|
||||||
|
}
|
||||||
|
|
|
@ -49,6 +49,9 @@ interface ICOMROGUETypes
|
||||||
typedef INT32 INT_PTR;
|
typedef INT32 INT_PTR;
|
||||||
typedef UINT32 UINT_PTR;
|
typedef UINT32 UINT_PTR;
|
||||||
|
|
||||||
|
typedef UINT_PTR SIZE_T;
|
||||||
|
typedef INT_PTR SSIZE_T;
|
||||||
|
|
||||||
/* Base pointer type definitions */
|
/* Base pointer type definitions */
|
||||||
typedef INT16 *PINT16;
|
typedef INT16 *PINT16;
|
||||||
typedef UINT16 *PUINT16;
|
typedef UINT16 *PUINT16;
|
||||||
|
|
|
@ -45,6 +45,19 @@ interface IUnknown
|
||||||
UINT32 Release();
|
UINT32 Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------
|
||||||
|
* IClassFactory interface
|
||||||
|
*-------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
[object, uuid(00000001-0000-0000-C000-000000000046), pointer_default(unique)]
|
||||||
|
interface IClassFactory : IUnknown
|
||||||
|
{
|
||||||
|
[unique] typedef IClassFactory *PCLASSFACTORY;
|
||||||
|
HRESULT CreateInstance([in, unique] IUnknown *punkOuter, [in] REFIID riid, [out, iid_is(riid)] PPVOID ppvObject);
|
||||||
|
HRESULT LockServer([in] BOOL fLock);
|
||||||
|
}
|
||||||
|
|
||||||
/*----------------------------
|
/*----------------------------
|
||||||
* IServiceProvider interface
|
* IServiceProvider interface
|
||||||
*----------------------------
|
*----------------------------
|
||||||
|
|
61
include/comrogue/internals/memmgr.h
Normal file
61
include/comrogue/internals/memmgr.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the COMROGUE Operating System for Raspberry Pi
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Eric J. Bowersox / Erbosoft Enterprises
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free for commercial and non-commercial use as long as the following conditions are
|
||||||
|
* adhered to.
|
||||||
|
*
|
||||||
|
* Copyright in this file remains Eric J. Bowersox and/or Erbosoft, and as such any copyright notices
|
||||||
|
* in the code are not to be removed.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
* provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice, this list of conditions and
|
||||||
|
* the following disclaimer.
|
||||||
|
* * 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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
||||||
|
*
|
||||||
|
* "Raspberry Pi" is a trademark of the Raspberry Pi Foundation.
|
||||||
|
*/
|
||||||
|
#ifndef __MEMMGR_H_INCLUDED
|
||||||
|
#define __MEMMGR_H_INCLUDED
|
||||||
|
|
||||||
|
#ifdef __COMROGUE_INTERNALS__
|
||||||
|
|
||||||
|
#ifndef __ASM__
|
||||||
|
|
||||||
|
#include <comrogue/types.h>
|
||||||
|
#include <comrogue/compiler_macros.h>
|
||||||
|
#include <comrogue/internals/mmu.h>
|
||||||
|
#include <comrogue/internals/startup.h>
|
||||||
|
|
||||||
|
CDECL_BEGIN
|
||||||
|
|
||||||
|
/* Page mapping functions */
|
||||||
|
extern PHYSADDR MmGetPhysAddr(PTTB pTTB, KERNADDR vma);
|
||||||
|
extern HRESULT MmDemapPages(PTTB pTTB, KERNADDR vmaBase, UINT32 cpg);
|
||||||
|
extern HRESULT MmMapPages(PTTB pTTB, PHYSADDR paBase, KERNADDR vmaBase, UINT32 cpg, UINT32 uiTableFlags,
|
||||||
|
UINT32 uiPageFlags);
|
||||||
|
|
||||||
|
/* Initialization functions only */
|
||||||
|
extern void _MmInit(PSTARTUP_INFO pstartup);
|
||||||
|
|
||||||
|
CDECL_END
|
||||||
|
|
||||||
|
#endif /* __ASM__ */
|
||||||
|
|
||||||
|
#endif /* __COMROGUE_INTERNALS__ */
|
||||||
|
|
||||||
|
#endif /* __MEMMGR_H_INCLUDED */
|
|
@ -43,6 +43,7 @@
|
||||||
#define SYS_PAGE_SIZE 4096 /* standard page size for normal page */
|
#define SYS_PAGE_SIZE 4096 /* standard page size for normal page */
|
||||||
#define SYS_PAGE_BITS 12 /* log2(SYS_PAGE_SIZE), number of bits in a page address */
|
#define SYS_PAGE_BITS 12 /* log2(SYS_PAGE_SIZE), number of bits in a page address */
|
||||||
#define SYS_TTB0_SIZE 8192 /* TTB0 must be located on this boundary and is this size */
|
#define SYS_TTB0_SIZE 8192 /* TTB0 must be located on this boundary and is this size */
|
||||||
|
#define SYS_TTB0_ENTRIES 2048 /* SYS_TTB0_SIZE/4, number of entries in TTB0 */
|
||||||
#define SYS_TTB1_SIZE 16384 /* TTB1 must be located on this boundary and is this size */
|
#define SYS_TTB1_SIZE 16384 /* TTB1 must be located on this boundary and is this size */
|
||||||
#define SYS_TTB1_ENTRIES 4096 /* SYS_TTB1_SIZE/4, number of entries in TTB1 */
|
#define SYS_TTB1_ENTRIES 4096 /* SYS_TTB1_SIZE/4, number of entries in TTB1 */
|
||||||
#define SYS_TTB_BITS 12 /* log2(SYS_TTB1_SIZE/4), number of bits in a TTB address */
|
#define SYS_TTB_BITS 12 /* log2(SYS_TTB1_SIZE/4), number of bits in a TTB address */
|
||||||
|
@ -124,6 +125,16 @@
|
||||||
#define PGQUERY_SM 0x00000002 /* small page (4K) */
|
#define PGQUERY_SM 0x00000002 /* small page (4K) */
|
||||||
#define PGQUERY_SM_XN 0x00000003 /* small page with Execute-Never set */
|
#define PGQUERY_SM_XN 0x00000003 /* small page with Execute-Never set */
|
||||||
|
|
||||||
|
/* Combinations of flags we use regularly. */
|
||||||
|
#define TTBFLAGS_LIB_CODE TTBPGTBL_ALWAYS
|
||||||
|
#define PGTBLFLAGS_LIB_CODE (PGTBLSM_ALWAYS | PGTBLSM_B | PGTBLSM_C | PGTBLSM_AP10)
|
||||||
|
#define TTBFLAGS_KERNEL_CODE TTBPGTBL_ALWAYS
|
||||||
|
#define PGTBLFLAGS_KERNEL_CODE (PGTBLSM_ALWAYS | PGTBLSM_B | PGTBLSM_C | PGTBLSM_AP01)
|
||||||
|
#define TTBFLAGS_KERNEL_DATA TTBPGTBL_ALWAYS
|
||||||
|
#define PGTBLFLAGS_KERNEL_DATA (PGTBLSM_XN | PGTBLSM_ALWAYS | PGTBLSM_B | PGTBLSM_C | PGTBLSM_AP01)
|
||||||
|
#define TTBFLAGS_MMIO TTBPGTBL_ALWAYS
|
||||||
|
#define PGTBLFLAGS_MMIO (PGTBLSM_ALWAYS | PGTBLSM_AP01)
|
||||||
|
|
||||||
#ifndef __ASM__
|
#ifndef __ASM__
|
||||||
|
|
||||||
/*-------------------------------------------------------
|
/*-------------------------------------------------------
|
||||||
|
@ -224,16 +235,21 @@ typedef struct tagPAGETAB {
|
||||||
|
|
||||||
/* internal structure of a MPDB entry */
|
/* internal structure of a MPDB entry */
|
||||||
typedef struct tagMPDB1 {
|
typedef struct tagMPDB1 {
|
||||||
|
PHYSADDR paPTE; /* PA of page table entry for the page */
|
||||||
unsigned next : 20; /* index of "next" entry in list */
|
unsigned next : 20; /* index of "next" entry in list */
|
||||||
unsigned tag : 12; /* page tag */
|
unsigned tag : 12; /* page tag */
|
||||||
} MPDB1;
|
} MPDB1;
|
||||||
|
|
||||||
/* The MPDB entry itself. */
|
/* The MPDB entry itself. */
|
||||||
typedef union tagMPDB {
|
typedef union tagMPDB {
|
||||||
UINT32 raw; /* raw data */
|
UINT64 raw; /* raw data */
|
||||||
MPDB1 d; /* structured data */
|
MPDB1 d; /* structured data */
|
||||||
} MPDB, *PMPDB;
|
} MPDB, *PMPDB;
|
||||||
|
|
||||||
|
/* Page index macros */
|
||||||
|
#define mmPA2PageIndex(pa) ((pa) >> SYS_PAGE_BITS)
|
||||||
|
#define mmPageIndex2PA(ndx) ((ndx) << SYS_PAGE_BITS)
|
||||||
|
|
||||||
#endif /* __ASM__ */
|
#endif /* __ASM__ */
|
||||||
|
|
||||||
#endif /* __COMROGUE_INTERNALS__ */
|
#endif /* __COMROGUE_INTERNALS__ */
|
||||||
|
|
|
@ -1,3 +1,34 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the COMROGUE Operating System for Raspberry Pi
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Eric J. Bowersox / Erbosoft Enterprises
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free for commercial and non-commercial use as long as the following conditions are
|
||||||
|
* adhered to.
|
||||||
|
*
|
||||||
|
* Copyright in this file remains Eric J. Bowersox and/or Erbosoft, and as such any copyright notices
|
||||||
|
* in the code are not to be removed.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
* provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice, this list of conditions and
|
||||||
|
* the following disclaimer.
|
||||||
|
* * 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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
||||||
|
*
|
||||||
|
* "Raspberry Pi" is a trademark of the Raspberry Pi Foundation.
|
||||||
|
*/
|
||||||
#ifndef __OBJECT_DEFINITION_MACROS_H_INCLUDED
|
#ifndef __OBJECT_DEFINITION_MACROS_H_INCLUDED
|
||||||
#define __OBJECT_DEFINITION_MACROS_H_INCLUDED
|
#define __OBJECT_DEFINITION_MACROS_H_INCLUDED
|
||||||
|
|
||||||
|
@ -28,7 +59,7 @@
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define DEFINE_UUID_TYPE(typ, name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
#define DEFINE_UUID_TYPE(typ, name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||||
EXTERN_C extern const typ GUIDATTR name
|
EXTERN_C extern const typ name
|
||||||
|
|
||||||
#endif /* INITGUID */
|
#endif /* INITGUID */
|
||||||
|
|
||||||
|
@ -61,11 +92,11 @@
|
||||||
#define INHERIT_METHODS(sym) sym
|
#define INHERIT_METHODS(sym) sym
|
||||||
|
|
||||||
#define BEGIN_INTERFACE(typ) \
|
#define BEGIN_INTERFACE(typ) \
|
||||||
|
struct typ ## VTable; \
|
||||||
|
typedef interface tagIf ## typ { const struct typ ## VTable *pVTable; } typ; \
|
||||||
struct typ ## VTable {
|
struct typ ## VTable {
|
||||||
#define BEGIN_INTERFACE_(typ, parent) \
|
#define BEGIN_INTERFACE_(typ, parent) BEGIN_INTERFACE(typ)
|
||||||
struct typ ## VTable {
|
#define END_INTERFACE(typ) };
|
||||||
#define END_INTERFACE(typ) }; \
|
|
||||||
typedef interface typ { const struct typ ## VTable *pVTable; } typ;
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
56
include/comrogue/objhelp.h
Normal file
56
include/comrogue/objhelp.h
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the COMROGUE Operating System for Raspberry Pi
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Eric J. Bowersox / Erbosoft Enterprises
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free for commercial and non-commercial use as long as the following conditions are
|
||||||
|
* adhered to.
|
||||||
|
*
|
||||||
|
* Copyright in this file remains Eric J. Bowersox and/or Erbosoft, and as such any copyright notices
|
||||||
|
* in the code are not to be removed.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
* provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice, this list of conditions and
|
||||||
|
* the following disclaimer.
|
||||||
|
* * 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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
||||||
|
*
|
||||||
|
* "Raspberry Pi" is a trademark of the Raspberry Pi Foundation.
|
||||||
|
*/
|
||||||
|
#ifndef __OBJHELP_H_INCLUDED
|
||||||
|
#define __OBJHELP_H_INCLUDED
|
||||||
|
|
||||||
|
#ifndef __ASM__
|
||||||
|
|
||||||
|
#include <comrogue/compiler_macros.h>
|
||||||
|
#include <comrogue/objectbase.h>
|
||||||
|
#include <comrogue/allocator.h>
|
||||||
|
|
||||||
|
CDECL_BEGIN
|
||||||
|
|
||||||
|
/* QueryInterface helpers */
|
||||||
|
extern HRESULT ObjHlpStandardQueryInterface_IMalloc(IUnknown *pThis, REFIID riid, PPVOID ppvObject);
|
||||||
|
|
||||||
|
/* AddRef/Release helpers */
|
||||||
|
extern UINT32 ObjHlpStaticAddRefRelease(IUnknown *pThis);
|
||||||
|
|
||||||
|
/* Other helpers */
|
||||||
|
extern void ObjHlpDoNothingReturnVoid(IUnknown *pThis);
|
||||||
|
|
||||||
|
CDECL_END
|
||||||
|
|
||||||
|
#endif /* __ASM__ */
|
||||||
|
|
||||||
|
#endif /* __OBJHELP_H_INCLUDED */
|
|
@ -58,6 +58,7 @@
|
||||||
#define FACILITY_ITF 4
|
#define FACILITY_ITF 4
|
||||||
#define FACILITY_COMROGUE 7
|
#define FACILITY_COMROGUE 7
|
||||||
#define FACILITY_STRFORMAT 0x333
|
#define FACILITY_STRFORMAT 0x333
|
||||||
|
#define FACILITY_MEMMGR 0x601
|
||||||
|
|
||||||
#ifndef __ASM__
|
#ifndef __ASM__
|
||||||
|
|
||||||
|
@ -79,19 +80,27 @@
|
||||||
|
|
||||||
#endif /* __ASM__ */
|
#endif /* __ASM__ */
|
||||||
|
|
||||||
#define S_OK SCODE_CAST(0x00000000) /* OK return */
|
/* Basic success codes */
|
||||||
#define S_FALSE SCODE_CAST(0x00000001) /* "False" return */
|
#define S_OK SCODE_CAST(0x00000000) /* OK return */
|
||||||
|
#define S_FALSE SCODE_CAST(0x00000001) /* "False" return */
|
||||||
|
|
||||||
#define E_NOTIMPL SCODE_CAST(0x80000001) /* not implemented */
|
/* Basic error codes */
|
||||||
#define E_OUTOFMEMORY SCODE_CAST(0x80000002) /* out of memory */
|
#define E_NOTIMPL SCODE_CAST(0x80000001) /* not implemented */
|
||||||
#define E_INVALIDARG SCODE_CAST(0x80000003) /* invalid argument */
|
#define E_OUTOFMEMORY SCODE_CAST(0x80000002) /* out of memory */
|
||||||
#define E_NOINTERFACE SCODE_CAST(0x80000004) /* no such interface */
|
#define E_INVALIDARG SCODE_CAST(0x80000003) /* invalid argument */
|
||||||
#define E_POINTER SCODE_CAST(0x80000005) /* invalid pointer */
|
#define E_NOINTERFACE SCODE_CAST(0x80000004) /* no such interface */
|
||||||
#define E_HANDLE SCODE_CAST(0x80000006) /* invalid handle */
|
#define E_POINTER SCODE_CAST(0x80000005) /* invalid pointer */
|
||||||
#define E_ABORT SCODE_CAST(0x80000007) /* aborted operation */
|
#define E_HANDLE SCODE_CAST(0x80000006) /* invalid handle */
|
||||||
#define E_FAIL SCODE_CAST(0x80000008) /* unspecified failure */
|
#define E_ABORT SCODE_CAST(0x80000007) /* aborted operation */
|
||||||
#define E_ACCESSDENIED SCODE_CAST(0x80000009) /* access denied */
|
#define E_FAIL SCODE_CAST(0x80000008) /* unspecified failure */
|
||||||
#define E_PENDING SCODE_CAST(0x8000000A) /* data not yet available */
|
#define E_ACCESSDENIED SCODE_CAST(0x80000009) /* access denied */
|
||||||
#define E_UNEXPECTED SCODE_CAST(0x8000FFFF) /* unexpected error */
|
#define E_PENDING SCODE_CAST(0x8000000A) /* data not yet available */
|
||||||
|
#define E_UNEXPECTED SCODE_CAST(0x8000FFFF) /* unexpected error */
|
||||||
|
|
||||||
|
/* Memory manager error codes */
|
||||||
|
#define MEMMGR_E_NOPGTBL SCODE_CAST(0x86010001) /* no page tables available */
|
||||||
|
#define MEMMGR_E_BADTTBFLG SCODE_CAST(0x86010002) /* bad TTB flags encountered */
|
||||||
|
#define MEMMGR_E_COLLIDED SCODE_CAST(0x86010003) /* memory mapping collided */
|
||||||
|
#define MEMMGR_E_ENDTTB SCODE_CAST(0x86010004) /* tried to "walk off" end of TTB */
|
||||||
|
|
||||||
#endif /* __SCODE_H_INCLUDED */
|
#endif /* __SCODE_H_INCLUDED */
|
||||||
|
|
51
include/comrogue/stdobj.h
Normal file
51
include/comrogue/stdobj.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the COMROGUE Operating System for Raspberry Pi
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Eric J. Bowersox / Erbosoft Enterprises
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free for commercial and non-commercial use as long as the following conditions are
|
||||||
|
* adhered to.
|
||||||
|
*
|
||||||
|
* Copyright in this file remains Eric J. Bowersox and/or Erbosoft, and as such any copyright notices
|
||||||
|
* in the code are not to be removed.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
* provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice, this list of conditions and
|
||||||
|
* the following disclaimer.
|
||||||
|
* * 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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
||||||
|
*
|
||||||
|
* "Raspberry Pi" is a trademark of the Raspberry Pi Foundation.
|
||||||
|
*/
|
||||||
|
#ifndef __STDOBJ_H_INCLUDED
|
||||||
|
#define __STDOBJ_H_INCLUDED
|
||||||
|
|
||||||
|
#ifndef __ASM__
|
||||||
|
|
||||||
|
#include <comrogue/compiler_macros.h>
|
||||||
|
#include <comrogue/object_types.h>
|
||||||
|
|
||||||
|
CDECL_BEGIN
|
||||||
|
|
||||||
|
extern BOOL IsEqualGUID(REFGUID guid1, REFGUID guid2);
|
||||||
|
|
||||||
|
CDECL_END
|
||||||
|
|
||||||
|
#define IsEqualIID(iid1, iid2) IsEqualGUID(iid1, iid2)
|
||||||
|
#define IsEqualCLSID(clsid1, clsid2) IsEqualGUID(clsid1, clsid2)
|
||||||
|
|
||||||
|
#endif /* __ASM__ */
|
||||||
|
|
||||||
|
#endif /* __STDOBJ_H_INCLUDED */
|
|
@ -48,7 +48,9 @@ typedef HRESULT (*PFNFORMAT8)(PPVOID, PCCHAR, UINT32);
|
||||||
|
|
||||||
CDECL_BEGIN
|
CDECL_BEGIN
|
||||||
|
|
||||||
extern PVOID StrCopyMem(PVOID pDest, PCVOID pSrc, INT32 nBytes);
|
extern PVOID StrCopyMem(PVOID pDest, PCVOID pSrc, SSIZE_T cb);
|
||||||
|
extern INT32 StrCompareMem(PCVOID pMem1, PCVOID pMem2, SSIZE_T cb);
|
||||||
|
extern PVOID StrSetMem(PVOID pMem, INT32 ch, SSIZE_T cb);
|
||||||
|
|
||||||
extern BOOL StrIsDigit8(CHAR ch);
|
extern BOOL StrIsDigit8(CHAR ch);
|
||||||
extern INT32 StrLength8(PCSTR psz);
|
extern INT32 StrLength8(PCSTR psz);
|
||||||
|
|
|
@ -48,9 +48,9 @@ AFLAGS = -mcpu=arm1176jzf-s -mfloat-abi=hard
|
||||||
ASM_CPP_FLAGS = $(INCLUDES) $(DEFS) -D__ASM__
|
ASM_CPP_FLAGS = $(INCLUDES) $(DEFS) -D__ASM__
|
||||||
|
|
||||||
PRESTART_OBJS = prestart.o early_trace.o collect_startup.o early_mm.o
|
PRESTART_OBJS = prestart.o early_trace.o collect_startup.o early_mm.o
|
||||||
LIB_OBJS = divide.o qdivrem.o intlib.o str.o strcopymem.o
|
LIB_OBJS = divide.o qdivrem.o intlib.o objhelp.o str.o strcopymem.o strcomparemem.o strsetmem.o lib_guids.o
|
||||||
RES_OBJS = lowlevel.o trace.o
|
RES_OBJS = lowlevel.o trace.o memmgr.o vmmap.o pagealloc.o
|
||||||
INIT_OBJS = start.o kistart.o
|
INIT_OBJS = start.o kistart.o init_heap.o
|
||||||
|
|
||||||
all: kernel.img
|
all: kernel.img
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@ SEG_INIT_CODE static UINT32 make_section_flags(UINT32 uiTableFlags, UINT32 uiPag
|
||||||
* The number of pages that were actually mapped by this function call, or -1 if there was an error in the mapping.
|
* The number of pages that were actually mapped by this function call, or -1 if there was an error in the mapping.
|
||||||
*
|
*
|
||||||
* Side effects:
|
* Side effects:
|
||||||
* May modify the ndxTTB'th entry in the TTB, if it was not previously allocated. May modify the current page
|
* May modify the TTB entry we point to, if it was not previously allocated. May modify the current page
|
||||||
* table that the TTB entry points to, where applicable. If we need to allocate a new page table, may modify the
|
* table that the TTB entry points to, where applicable. If we need to allocate a new page table, may modify the
|
||||||
* global variables g_cpgForPageTables, g_ctblFreeonLastPage, and g_ptblNext.
|
* global variables g_cpgForPageTables, g_ctblFreeonLastPage, and g_ptblNext.
|
||||||
*/
|
*/
|
||||||
|
@ -334,7 +334,7 @@ SEG_INIT_CODE PHYSADDR EMmInit(PSTARTUP_INFO pstartup)
|
||||||
|
|
||||||
/* Allocate space for the Master Page Database but do not initialize it. */
|
/* Allocate space for the Master Page Database but do not initialize it. */
|
||||||
pstartup->paMPDB = paTTB + SYS_TTB1_SIZE;
|
pstartup->paMPDB = paTTB + SYS_TTB1_SIZE;
|
||||||
cbMPDB = pstartup->cpgSystemTotal << 2;
|
cbMPDB = pstartup->cpgSystemTotal << 3; /* 8 bytes per entry */
|
||||||
pstartup->cpgMPDB = cbMPDB >> SYS_PAGE_BITS;
|
pstartup->cpgMPDB = cbMPDB >> SYS_PAGE_BITS;
|
||||||
if (cbMPDB & (SYS_PAGE_SIZE - 1))
|
if (cbMPDB & (SYS_PAGE_SIZE - 1))
|
||||||
{
|
{
|
||||||
|
@ -349,34 +349,32 @@ SEG_INIT_CODE PHYSADDR EMmInit(PSTARTUP_INFO pstartup)
|
||||||
/* Map the "prestart" area (everything below load address, plus prestart code & data) as identity. */
|
/* Map the "prestart" area (everything below load address, plus prestart code & data) as identity. */
|
||||||
VERIFY(map_pages(0, 0, (INT32)(&cpgPrestartTotal), TTBPGTBL_ALWAYS, PGTBLSM_ALWAYS | PGTBLSM_AP01));
|
VERIFY(map_pages(0, 0, (INT32)(&cpgPrestartTotal), TTBPGTBL_ALWAYS, PGTBLSM_ALWAYS | PGTBLSM_AP01));
|
||||||
/* Map the IO area as identity. */
|
/* Map the IO area as identity. */
|
||||||
VERIFY(map_pages(PHYSADDR_IO_BASE, PHYSADDR_IO_BASE, PAGE_COUNT_IO, TTBPGTBL_ALWAYS, PGTBLSM_ALWAYS | PGTBLSM_AP01));
|
VERIFY(map_pages(PHYSADDR_IO_BASE, PHYSADDR_IO_BASE, PAGE_COUNT_IO, TTBFLAGS_MMIO, PGTBLFLAGS_MMIO));
|
||||||
/* Map the library area. */
|
/* Map the library area. */
|
||||||
VERIFY(map_pages((PHYSADDR)(&paLibraryCode), (KERNADDR)(&vmaLibraryCode), (INT32)(&cpgLibraryCode),
|
VERIFY(map_pages((PHYSADDR)(&paLibraryCode), (KERNADDR)(&vmaLibraryCode), (INT32)(&cpgLibraryCode),
|
||||||
TTBPGTBL_ALWAYS, PGTBLSM_ALWAYS | PGTBLSM_B | PGTBLSM_C | PGTBLSM_AP10));
|
TTBFLAGS_LIB_CODE, PGTBLFLAGS_LIB_CODE));
|
||||||
/* Map the kernel code area. */
|
/* Map the kernel code area. */
|
||||||
VERIFY(map_pages((PHYSADDR)(&paKernelCode), (KERNADDR)(&vmaKernelCode), (INT32)(&cpgKernelCode),
|
VERIFY(map_pages((PHYSADDR)(&paKernelCode), (KERNADDR)(&vmaKernelCode), (INT32)(&cpgKernelCode),
|
||||||
TTBPGTBL_ALWAYS, PGTBLSM_ALWAYS | PGTBLSM_B | PGTBLSM_C | PGTBLSM_AP01));
|
TTBFLAGS_KERNEL_CODE, PGTBLFLAGS_KERNEL_CODE));
|
||||||
/* Map the kernel data/BSS area. */
|
/* Map the kernel data/BSS area. */
|
||||||
VERIFY(map_pages((PHYSADDR)(&paKernelData), (KERNADDR)(&vmaKernelData),
|
VERIFY(map_pages((PHYSADDR)(&paKernelData), (KERNADDR)(&vmaKernelData),
|
||||||
(INT32)(&cpgKernelData) + (INT32)(&cpgKernelBss),
|
(INT32)(&cpgKernelData) + (INT32)(&cpgKernelBss), TTBFLAGS_KERNEL_DATA, PGTBLFLAGS_KERNEL_DATA));
|
||||||
TTBPGTBL_ALWAYS, PGTBLSM_XN | PGTBLSM_ALWAYS | PGTBLSM_B | PGTBLSM_C | PGTBLSM_AP01));
|
|
||||||
/* Map the kernel init code area. */
|
/* Map the kernel init code area. */
|
||||||
VERIFY(map_pages((PHYSADDR)(&paInitCode), (KERNADDR)(&vmaInitCode), (INT32)(&cpgInitCode),
|
VERIFY(map_pages((PHYSADDR)(&paInitCode), (KERNADDR)(&vmaInitCode), (INT32)(&cpgInitCode),
|
||||||
TTBPGTBL_ALWAYS, PGTBLSM_ALWAYS | PGTBLSM_B | PGTBLSM_C | PGTBLSM_AP01));
|
TTBFLAGS_KERNEL_CODE, PGTBLFLAGS_KERNEL_CODE));
|
||||||
/* Map the kernel init data/BSS area. */
|
/* Map the kernel init data/BSS area. */
|
||||||
VERIFY(map_pages((PHYSADDR)(&paInitData), (KERNADDR)(&vmaInitData),
|
VERIFY(map_pages((PHYSADDR)(&paInitData), (KERNADDR)(&vmaInitData),
|
||||||
(INT32)(&cpgInitData) + (INT32)(&cpgInitBss),
|
(INT32)(&cpgInitData) + (INT32)(&cpgInitBss), TTBFLAGS_KERNEL_DATA, PGTBLFLAGS_KERNEL_DATA));
|
||||||
TTBPGTBL_ALWAYS, PGTBLSM_XN | PGTBLSM_ALWAYS | PGTBLSM_B | PGTBLSM_C | PGTBLSM_AP01));
|
|
||||||
/* Map the TTB itself. */
|
/* Map the TTB itself. */
|
||||||
pstartup->kaTTB = (KERNADDR)(&vmaFirstFree);
|
pstartup->kaTTB = (KERNADDR)(&vmaFirstFree);
|
||||||
VERIFY(map_pages(paTTB, pstartup->kaTTB, SYS_TTB1_SIZE / SYS_PAGE_SIZE,
|
VERIFY(map_pages(paTTB, pstartup->kaTTB, SYS_TTB1_SIZE / SYS_PAGE_SIZE, TTBFLAGS_KERNEL_DATA,
|
||||||
TTBPGTBL_ALWAYS, PGTBLSM_XN | PGTBLSM_ALWAYS | PGTBLSM_B | PGTBLSM_C | PGTBLSM_AP01));
|
PGTBLFLAGS_KERNEL_DATA));
|
||||||
/* Map the Master Page Database. */
|
/* Map the Master Page Database. */
|
||||||
pstartup->kaMPDB = pstartup->kaTTB + SYS_TTB1_SIZE;
|
pstartup->kaMPDB = pstartup->kaTTB + SYS_TTB1_SIZE;
|
||||||
VERIFY(map_pages(pstartup->paMPDB, pstartup->kaTTB + SYS_TTB1_SIZE, pstartup->cpgMPDB,
|
VERIFY(map_pages(pstartup->paMPDB, pstartup->kaTTB + SYS_TTB1_SIZE, pstartup->cpgMPDB, TTBFLAGS_KERNEL_DATA,
|
||||||
TTBPGTBL_ALWAYS, PGTBLSM_XN | PGTBLSM_ALWAYS | PGTBLSM_B | PGTBLSM_C | PGTBLSM_AP01));
|
PGTBLFLAGS_KERNEL_DATA));
|
||||||
/* Map the IO area into high memory as well. */
|
/* Map the IO area into high memory as well. */
|
||||||
VERIFY(map_pages(PHYSADDR_IO_BASE, VMADDR_IO_BASE, PAGE_COUNT_IO, TTBPGTBL_ALWAYS, PGTBLSM_ALWAYS | PGTBLSM_AP01));
|
VERIFY(map_pages(PHYSADDR_IO_BASE, VMADDR_IO_BASE, PAGE_COUNT_IO, TTBFLAGS_MMIO, PGTBLFLAGS_MMIO));
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* Dump the TTB and page tables to trace output. */
|
/* Dump the TTB and page tables to trace output. */
|
||||||
|
|
308
kernel/init_heap.c
Normal file
308
kernel/init_heap.c
Normal file
|
@ -0,0 +1,308 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the COMROGUE Operating System for Raspberry Pi
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Eric J. Bowersox / Erbosoft Enterprises
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free for commercial and non-commercial use as long as the following conditions are
|
||||||
|
* adhered to.
|
||||||
|
*
|
||||||
|
* Copyright in this file remains Eric J. Bowersox and/or Erbosoft, and as such any copyright notices
|
||||||
|
* in the code are not to be removed.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
* provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice, this list of conditions and
|
||||||
|
* the following disclaimer.
|
||||||
|
* * 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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
||||||
|
*
|
||||||
|
* "Raspberry Pi" is a trademark of the Raspberry Pi Foundation.
|
||||||
|
*/
|
||||||
|
#include <comrogue/types.h>
|
||||||
|
#include <comrogue/str.h>
|
||||||
|
#include <comrogue/allocator.h>
|
||||||
|
#include <comrogue/objhelp.h>
|
||||||
|
#include <comrogue/internals/seg.h>
|
||||||
|
#include "sizes.h"
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------------------------------------------
|
||||||
|
* Initial heap implementation. Since this will only be used by initializer code and freed with the rest
|
||||||
|
* of the initializer code and data, it doesn't need to be very efficient. The implementation is adapted from
|
||||||
|
* the original K&R storage allocator, with modifications to implement the full IMalloc interface.
|
||||||
|
*-------------------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern PCHAR g_pInitHeapBlock; /* pointer to heap init block defined in assembly code */
|
||||||
|
|
||||||
|
typedef union tagBLOCK
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
union tagBLOCK *pNextFree; /* pointer to next free block */
|
||||||
|
SIZE_T cblk; /* size of this free block (in blocks) */
|
||||||
|
} data;
|
||||||
|
INT64 x; /* to force alignment */
|
||||||
|
} BLOCK, *PBLOCK;
|
||||||
|
|
||||||
|
typedef struct tagINITHEAP
|
||||||
|
{
|
||||||
|
IMalloc hdr; /* object header must be first */
|
||||||
|
BLOCK blkBase; /* base "zero" block */
|
||||||
|
PBLOCK pblkLastAlloc; /* last allocated block */
|
||||||
|
} INITHEAP, *PINITHEAP;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocates a block of memory.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pThis = Base interface pointer.
|
||||||
|
* - cb = Size of the memory block to be allocated, in bytes.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* A pointer to the allocated block of memory, or NULL if memory could not be allocated.
|
||||||
|
*/
|
||||||
|
SEG_INIT_CODE static PVOID init_heap_Alloc(IMalloc *pThis, SIZE_T cb)
|
||||||
|
{
|
||||||
|
PINITHEAP pih = (PINITHEAP)pThis;
|
||||||
|
register PBLOCK p, q;
|
||||||
|
register SIZE_T nBlocks = 1 + (cb + sizeof(BLOCK) - 1) / sizeof(BLOCK);
|
||||||
|
|
||||||
|
q = pih->pblkLastAlloc;
|
||||||
|
for (p = q->data.pNextFree; ; q = p, p = p->data.pNextFree)
|
||||||
|
{
|
||||||
|
if (p->data.cblk >= nBlocks)
|
||||||
|
{
|
||||||
|
if (p->data.cblk == nBlocks)
|
||||||
|
q->data.pNextFree = p->data.pNextFree;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->data.cblk -= nBlocks;
|
||||||
|
p += p->data.cblk;
|
||||||
|
p->data.cblk = nBlocks;
|
||||||
|
}
|
||||||
|
pih->pblkLastAlloc = q;
|
||||||
|
return (PVOID)(p + 1);
|
||||||
|
}
|
||||||
|
if (p == pih->pblkLastAlloc)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determines whether this allocator was used to allocate a block of memory.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pThis = Base interface pointer.
|
||||||
|
* - pv = Pointer to the memory block to test. If this parameter is NULL, -1 is returned.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* - 1 = If the memory block was allocated by this allocator.
|
||||||
|
* - 0 = If the memory block was not allocated by this allocator.
|
||||||
|
* - -1 = If this method cannot determine whether the allocator allocated the memory block.
|
||||||
|
*/
|
||||||
|
SEG_INIT_CODE static INT32 init_heap_DidAlloc(IMalloc *pThis, PVOID pv)
|
||||||
|
{
|
||||||
|
register PCHAR p = (PCHAR)pv;
|
||||||
|
if (!pv)
|
||||||
|
return -1; /* not our business */
|
||||||
|
return ((p >= g_pInitHeapBlock) && (p < g_pInitHeapBlock + SIZE_INIT_HEAP)) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Frees a previously allocated block of memory.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pThis = Base interface pointer.
|
||||||
|
* - pv = Pointer to the memory block to be freed. If this parameter is NULL, this method has no effect.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* Nothing.
|
||||||
|
*
|
||||||
|
* Side effects:
|
||||||
|
* After this call, the memory pointed to by pv is invalid and should not be used.
|
||||||
|
*/
|
||||||
|
SEG_INIT_CODE static void init_heap_Free(IMalloc *pThis, PVOID pv)
|
||||||
|
{
|
||||||
|
PINITHEAP pih = (PINITHEAP)pThis;
|
||||||
|
register PBLOCK p, q;
|
||||||
|
|
||||||
|
if (init_heap_DidAlloc(pThis, pv) != 1)
|
||||||
|
return; /* not our business */
|
||||||
|
p = ((PBLOCK)pv) - 1;
|
||||||
|
for (q = pih->pblkLastAlloc; !((p > q) && (p < q->data.pNextFree)); q = q->data.pNextFree)
|
||||||
|
if ((q >= q->data.pNextFree) && ((p > q) || (p < q->data.pNextFree)))
|
||||||
|
break; /* at one end or another */
|
||||||
|
if (p + p->data.cblk == q->data.pNextFree)
|
||||||
|
{
|
||||||
|
/* coalesce block with next (free) block */
|
||||||
|
p->data.cblk += q->data.pNextFree->data.cblk;
|
||||||
|
p->data.pNextFree = q->data.pNextFree->data.pNextFree;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
p->data.pNextFree = q->data.pNextFree; /* chain to next free block */
|
||||||
|
if (q + q->data.cblk == p)
|
||||||
|
{
|
||||||
|
/* coalesce free block with previous (free) block */
|
||||||
|
q->data.cblk += p->data.cblk;
|
||||||
|
q->data.pNextFree = p->data.pNextFree;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
q->data.pNextFree = p; /* chain to previous free block */
|
||||||
|
pih->pblkLastAlloc = q;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Changes the size of a previously allocated block.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pThis = Base interface pointer.
|
||||||
|
* - pv = Pointer to the block of memory to be reallocated. If this parameter is NULL, a block of memory
|
||||||
|
* of size cb is allocated and returned.
|
||||||
|
* - cb = The new size of the memory block to be reallocated, in bytes. If this parameter is 0 and pv is
|
||||||
|
* not NULL, the block of memory pointed to by pv is freed and NULL is returned.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* If pv is not NULL and cb is 0, NULL is always returned. Otherwise, NULL is returned if the block of memory
|
||||||
|
* could not be reallocated, or the pointer to the reallocated block of memory is returned.
|
||||||
|
*/
|
||||||
|
SEG_INIT_CODE static PVOID init_heap_Realloc(IMalloc *pThis, PVOID pv, SIZE_T cb)
|
||||||
|
{
|
||||||
|
PINITHEAP pih = (PINITHEAP)pThis;
|
||||||
|
SIZE_T nBlocksNew, nBlocksExtra;
|
||||||
|
PVOID pNew;
|
||||||
|
register PBLOCK p, pNext, q, qp;
|
||||||
|
|
||||||
|
/* Handle degenerate cases */
|
||||||
|
if (!pv)
|
||||||
|
return init_heap_Alloc(pThis, cb);
|
||||||
|
if (cb == 0)
|
||||||
|
{
|
||||||
|
init_heap_Free(pThis, pv);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (init_heap_DidAlloc(pThis, pv) != 1)
|
||||||
|
return NULL; /* not our business */
|
||||||
|
|
||||||
|
p = ((PBLOCK)pv) - 1;
|
||||||
|
nBlocksNew = 1 + (cb + sizeof(BLOCK) - 1) / sizeof(BLOCK);
|
||||||
|
if (nBlocksNew == p->data.cblk)
|
||||||
|
return pv; /* nothing to do! */
|
||||||
|
|
||||||
|
if (nBlocksNew < p->data.cblk)
|
||||||
|
{ /* shrinking block - chop block in middle and free the upper end */
|
||||||
|
pNext = p + nBlocksNew;
|
||||||
|
pNext->data.cblk = p->data.cblk - nBlocksNew;
|
||||||
|
p->data.cblk = nBlocksNew;
|
||||||
|
init_heap_Free(pThis, (PVOID)(pNext + 1));
|
||||||
|
return pv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* see if next block is free so we can expand in place */
|
||||||
|
nBlocksExtra = nBlocksNew - p->data.cblk;
|
||||||
|
pNext = p + p->data.cblk;
|
||||||
|
qp = pih->pblkLastAlloc;
|
||||||
|
for (q = qp->data.pNextFree; ; qp = q, q = q->data.pNextFree)
|
||||||
|
{
|
||||||
|
if (q == pNext)
|
||||||
|
{
|
||||||
|
if (q->data.cblk < nBlocksExtra)
|
||||||
|
break; /* cannot get enough blocks by combining next free block */
|
||||||
|
qp->data.pNextFree = q->data.pNextFree; /* remove block from free list */
|
||||||
|
if (q->data.cblk == nBlocksExtra)
|
||||||
|
{ /* take it all */
|
||||||
|
pih->pblkLastAlloc = qp->data.pNextFree;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* chop in two, add first block to existing, free second block */
|
||||||
|
pNext += nBlocksExtra;
|
||||||
|
pNext->data.cblk = q->data.cblk - nBlocksExtra;
|
||||||
|
init_heap_Free(pThis, (PVOID)(pNext + 1));
|
||||||
|
}
|
||||||
|
p->data.cblk = nBlocksNew;
|
||||||
|
return pv;
|
||||||
|
}
|
||||||
|
if (q == pih->pblkLastAlloc)
|
||||||
|
break; /* not found */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* last ditch effort: allocate new block and copy old contents in */
|
||||||
|
pNew = init_heap_Alloc(pThis, cb);
|
||||||
|
if (!pNew)
|
||||||
|
return NULL; /* cannot reallocate */
|
||||||
|
StrCopyMem(pv, pNew, (p->data.cblk - 1) * sizeof(BLOCK));
|
||||||
|
init_heap_Free(pThis, pv);
|
||||||
|
return pNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the size of a previously-allocated block of memory.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pThis = Base interface pointer.
|
||||||
|
* - pv = Pointer to the block of memory.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* The size of the allocated block of memory in bytes, which may be greater than the size requested when
|
||||||
|
* it was allocated.
|
||||||
|
*/
|
||||||
|
SEG_INIT_CODE static SIZE_T init_heap_GetSize(IMalloc *pThis, PVOID pv)
|
||||||
|
{
|
||||||
|
register PBLOCK p;
|
||||||
|
|
||||||
|
if (init_heap_DidAlloc(pThis, pv) != 1)
|
||||||
|
return (SIZE_T)(-1); /* not our business */
|
||||||
|
p = ((PBLOCK)pv) - 1;
|
||||||
|
return (p->data.cblk - 1) * sizeof(BLOCK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const SEG_INIT_RODATA struct IMallocVTable vtblInitHeap =
|
||||||
|
{
|
||||||
|
.QueryInterface = ObjHlpStandardQueryInterface_IMalloc,
|
||||||
|
.AddRef = ObjHlpStaticAddRefRelease,
|
||||||
|
.Release = ObjHlpStaticAddRefRelease,
|
||||||
|
.Alloc = init_heap_Alloc,
|
||||||
|
.Realloc = init_heap_Realloc,
|
||||||
|
.Free = init_heap_Free,
|
||||||
|
.GetSize = init_heap_GetSize,
|
||||||
|
.DidAlloc = init_heap_DidAlloc,
|
||||||
|
.HeapMinimize = (void (*)(IMalloc *))ObjHlpDoNothingReturnVoid
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a reference to the initial heap.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* A reference to the initial heap, in the form of a pointer to its IMalloc interface.
|
||||||
|
*/
|
||||||
|
SEG_INIT_CODE IMalloc *_MmGetInitHeap(void)
|
||||||
|
{
|
||||||
|
static SEG_INIT_DATA INITHEAP initheap = { .pblkLastAlloc = NULL };
|
||||||
|
register PBLOCK p;
|
||||||
|
|
||||||
|
if (!(initheap.pblkLastAlloc))
|
||||||
|
{ /* initialize fields of initheap */
|
||||||
|
initheap.hdr.pVTable = &vtblInitHeap;
|
||||||
|
initheap.pblkLastAlloc = initheap.blkBase.data.pNextFree = &(initheap.blkBase);
|
||||||
|
initheap.blkBase.data.cblk = 0;
|
||||||
|
/* add g_pInitHeapBlock as the free block in the heap */
|
||||||
|
p = (PBLOCK)g_pInitHeapBlock;
|
||||||
|
p->data.cblk = SIZE_INIT_HEAP / sizeof(BLOCK);
|
||||||
|
init_heap_Free((IMalloc *)(&initheap), (PVOID)(p + 1));
|
||||||
|
}
|
||||||
|
return (IMalloc *)(&initheap);
|
||||||
|
}
|
50
kernel/lib_guids.c
Normal file
50
kernel/lib_guids.c
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the COMROGUE Operating System for Raspberry Pi
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Eric J. Bowersox / Erbosoft Enterprises
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free for commercial and non-commercial use as long as the following conditions are
|
||||||
|
* adhered to.
|
||||||
|
*
|
||||||
|
* Copyright in this file remains Eric J. Bowersox and/or Erbosoft, and as such any copyright notices
|
||||||
|
* in the code are not to be removed.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
* provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice, this list of conditions and
|
||||||
|
* the following disclaimer.
|
||||||
|
* * 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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
||||||
|
*
|
||||||
|
* "Raspberry Pi" is a trademark of the Raspberry Pi Foundation.
|
||||||
|
*/
|
||||||
|
/*------------------------------------------------------------------------------------------------------
|
||||||
|
* This module defines all the GUIDs as static data that goes into the library segment (i.e. accessible
|
||||||
|
* from both supervisor and user modes). The following definitions MUST be first in this source file,
|
||||||
|
* AND in this order.
|
||||||
|
*------------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include <comrogue/internals/seg.h>
|
||||||
|
#define GUIDATTR SEG_LIB_RODATA
|
||||||
|
#define INITGUID
|
||||||
|
#include <comrogue/object_definition_macros.h>
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------------------------------
|
||||||
|
* Now include all the header files generated from IDL. Try to include them in the order in which
|
||||||
|
* interfaces are defined.
|
||||||
|
*-------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include <comrogue/object_types.h>
|
||||||
|
#include <comrogue/objectbase.h>
|
||||||
|
#include <comrogue/allocator.h>
|
49
kernel/memmgr.c
Normal file
49
kernel/memmgr.c
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the COMROGUE Operating System for Raspberry Pi
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Eric J. Bowersox / Erbosoft Enterprises
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free for commercial and non-commercial use as long as the following conditions are
|
||||||
|
* adhered to.
|
||||||
|
*
|
||||||
|
* Copyright in this file remains Eric J. Bowersox and/or Erbosoft, and as such any copyright notices
|
||||||
|
* in the code are not to be removed.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
* provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice, this list of conditions and
|
||||||
|
* the following disclaimer.
|
||||||
|
* * 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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
||||||
|
*
|
||||||
|
* "Raspberry Pi" is a trademark of the Raspberry Pi Foundation.
|
||||||
|
*/
|
||||||
|
#include <comrogue/types.h>
|
||||||
|
#include <comrogue/internals/seg.h>
|
||||||
|
#include <comrogue/internals/memmgr.h>
|
||||||
|
#include <comrogue/internals/startup.h>
|
||||||
|
|
||||||
|
/*---------------------
|
||||||
|
* Initialization code
|
||||||
|
*---------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void _MmInitVMMap(PSTARTUP_INFO pstartup);
|
||||||
|
extern void _MmInitPageAlloc(PSTARTUP_INFO pstartup);
|
||||||
|
|
||||||
|
SEG_INIT_CODE void _MmInit(PSTARTUP_INFO pstartup)
|
||||||
|
{
|
||||||
|
_MmInitVMMap(pstartup);
|
||||||
|
_MmInitPageAlloc(pstartup);
|
||||||
|
}
|
93
kernel/objhelp.c
Normal file
93
kernel/objhelp.c
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
#include <comrogue/types.h>
|
||||||
|
#include <comrogue/scode.h>
|
||||||
|
#include <comrogue/str.h>
|
||||||
|
#include <comrogue/object_types.h>
|
||||||
|
#include <comrogue/objectbase.h>
|
||||||
|
#include <comrogue/allocator.h>
|
||||||
|
#include <comrogue/stdobj.h>
|
||||||
|
#include <comrogue/objhelp.h>
|
||||||
|
#include <comrogue/internals/seg.h>
|
||||||
|
|
||||||
|
/*--------------------------------------------
|
||||||
|
* Standard object functions (API-type calls)
|
||||||
|
*--------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determines whether two GUID references are equal.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - guid1 = First GUID to compare.
|
||||||
|
* - guid2 = Second GUID to compare.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* TRUE if the GUIDs are equal, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
SEG_LIB_CODE BOOL IsEqualGUID(REFGUID guid1, REFGUID guid2)
|
||||||
|
{
|
||||||
|
return MAKEBOOL(StrCompareMem(guid1, guid2, sizeof(GUID)) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------
|
||||||
|
* Functions to be used in the construction of C interface vtables
|
||||||
|
*-----------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Retrieves pointers to the supported interfaces on an object. Any pointer returned by this method
|
||||||
|
* has AddRef called on it before it returns.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pThis = Base interface pointer.
|
||||||
|
* - riid = The identifier of the interface being requested.
|
||||||
|
* - ppvObject = Address of a pointer variable that receives the interface pointer requested by riid.
|
||||||
|
* On return, *ppvObject contains the requested interface pointer, or NULL if the interface
|
||||||
|
* is not supported.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* - S_OK = If the interface is supported. *ppvObject contains the pointer to the interface.
|
||||||
|
* - E_NOINTERFACE = If the interface is not supported. *ppvObject contains NULL.
|
||||||
|
* - E_POINTER = If ppvObject is NULL.
|
||||||
|
*/
|
||||||
|
/* This macro makes a ObjHlpStandardQueryInterface_IXXX function for any interface directly derived from IUnknown */
|
||||||
|
#define MAKE_BASE_QI(iface) \
|
||||||
|
SEG_LIB_CODE HRESULT ObjHlpStandardQueryInterface_ ## iface (IUnknown *pThis, REFIID riid, PPVOID ppvObject) \
|
||||||
|
{ \
|
||||||
|
if (!ppvObject) return E_POINTER; \
|
||||||
|
*ppvObject = NULL; \
|
||||||
|
if (!IsEqualIID(riid, &IID_ ## iface) && !IsEqualIID(riid, &IID_IUnknown)) \
|
||||||
|
return E_NOINTERFACE; \
|
||||||
|
IUnknown_AddRef(pThis); \
|
||||||
|
*ppvObject = (PVOID)pThis; \
|
||||||
|
return S_OK; \
|
||||||
|
}
|
||||||
|
|
||||||
|
MAKE_BASE_QI(IMalloc)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "Dummy" version of AddRef/Release used for static objects.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pThis = Base interface pointer.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* 1.
|
||||||
|
*/
|
||||||
|
SEG_LIB_CODE UINT32 ObjHlpStaticAddRefRelease(IUnknown *pThis)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Method returning void that does nothing.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pThis = Base interface pointer.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* Nothing.
|
||||||
|
*/
|
||||||
|
SEG_LIB_CODE void ObjHlpDoNothingReturnVoid(IUnknown *pThis)
|
||||||
|
{
|
||||||
|
/* do nothing */
|
||||||
|
}
|
58
kernel/pagealloc.c
Normal file
58
kernel/pagealloc.c
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the COMROGUE Operating System for Raspberry Pi
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Eric J. Bowersox / Erbosoft Enterprises
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free for commercial and non-commercial use as long as the following conditions are
|
||||||
|
* adhered to.
|
||||||
|
*
|
||||||
|
* Copyright in this file remains Eric J. Bowersox and/or Erbosoft, and as such any copyright notices
|
||||||
|
* in the code are not to be removed.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
* provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice, this list of conditions and
|
||||||
|
* the following disclaimer.
|
||||||
|
* * 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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
||||||
|
*
|
||||||
|
* "Raspberry Pi" is a trademark of the Raspberry Pi Foundation.
|
||||||
|
*/
|
||||||
|
#include <comrogue/types.h>
|
||||||
|
#include <comrogue/internals/seg.h>
|
||||||
|
#include <comrogue/internals/mmu.h>
|
||||||
|
#include <comrogue/internals/startup.h>
|
||||||
|
|
||||||
|
/* Lists we keep track of various pages on. */
|
||||||
|
typedef struct tagPAGELIST {
|
||||||
|
UINT32 ndxLast; /* index of last page in list */
|
||||||
|
UINT32 cpg; /* count of pages in list */
|
||||||
|
} PAGELIST, *PPAGELIST;
|
||||||
|
|
||||||
|
/* The Master Page Database */
|
||||||
|
static PMPDB g_pMasterPageDB = NULL;
|
||||||
|
|
||||||
|
/* Individual page lists. */
|
||||||
|
//static PAGELIST g_pglFree = { 0, 0 }; /* pages that are free */
|
||||||
|
//static PAGELIST g_pglZeroed = { 0, 0 }; /* pages that are free and zeroed */
|
||||||
|
//static PAGELIST g_pglStandby = { 0, 0 }; /* pages removed but "in transition" */
|
||||||
|
//static PAGELIST g_pglModified = { 0, 0 }; /* pages removed but "in transition" and modified */
|
||||||
|
//static PAGELIST g_pglBad = { 0, 0 }; /* bad pages */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SEG_INIT_CODE void _MmInitPageAlloc(PSTARTUP_INFO pstartup)
|
||||||
|
{
|
||||||
|
g_pMasterPageDB = (PMPDB)(pstartup->kaMPDB);
|
||||||
|
}
|
43
kernel/sizes.h
Normal file
43
kernel/sizes.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the COMROGUE Operating System for Raspberry Pi
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Eric J. Bowersox / Erbosoft Enterprises
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free for commercial and non-commercial use as long as the following conditions are
|
||||||
|
* adhered to.
|
||||||
|
*
|
||||||
|
* Copyright in this file remains Eric J. Bowersox and/or Erbosoft, and as such any copyright notices
|
||||||
|
* in the code are not to be removed.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
* provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice, this list of conditions and
|
||||||
|
* the following disclaimer.
|
||||||
|
* * 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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
||||||
|
*
|
||||||
|
* "Raspberry Pi" is a trademark of the Raspberry Pi Foundation.
|
||||||
|
*/
|
||||||
|
#ifndef __SIZES_H_INCLUDED
|
||||||
|
#define __SIZES_H_INCLUDED
|
||||||
|
|
||||||
|
/*-----------------------------------
|
||||||
|
* Sizes of internal data structures
|
||||||
|
*-----------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SIZE_INIT_STACK 4096 /* size of the initial stack */
|
||||||
|
#define SIZE_INIT_HEAP 16384 /* size of the initial heap */
|
||||||
|
|
||||||
|
#endif /* __SIZES_H_INCLUDED */
|
|
@ -31,6 +31,7 @@
|
||||||
*/
|
*/
|
||||||
#include <comrogue/internals/layout.h>
|
#include <comrogue/internals/layout.h>
|
||||||
#include <comrogue/internals/sctlr.h>
|
#include <comrogue/internals/sctlr.h>
|
||||||
|
#include "sizes.h"
|
||||||
|
|
||||||
.section ".initHEAD.text"
|
.section ".initHEAD.text"
|
||||||
|
|
||||||
|
@ -112,6 +113,10 @@ COMROGUEStart:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
.section ".init.bss"
|
.section ".init.bss"
|
||||||
|
.balign 8
|
||||||
|
.globl g_pInitHeapBlock
|
||||||
|
g_pInitHeapBlock:
|
||||||
|
.space SIZE_INIT_HEAP
|
||||||
.balign 4
|
.balign 4
|
||||||
.space 4096
|
.space SIZE_INIT_STACK
|
||||||
.initstack:
|
.initstack:
|
||||||
|
|
187
kernel/strcomparemem.S
Normal file
187
kernel/strcomparemem.S
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2003 Wasabi Systems, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Written by Steve C. Woodford for Wasabi Systems, Inc.
|
||||||
|
*
|
||||||
|
* 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. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed for the NetBSD Project by
|
||||||
|
* Wasabi Systems, Inc.
|
||||||
|
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
|
||||||
|
* or promote products derived from this software without specific prior
|
||||||
|
* written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2002 ARM Ltd
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* 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 company may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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.
|
||||||
|
*/
|
||||||
|
/* Taken from FreeBSD memcmp.S, munged by Erbo to COMROGUE standards */
|
||||||
|
.section ".lib.text"
|
||||||
|
|
||||||
|
/* Func: INT32 StrCompareMem(PCVOID pMem1, PCVOID pMem2, SSIZE_T cb); */
|
||||||
|
/*
|
||||||
|
* Compares two memory blocks as bytes, returning a value for comparison between the two.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pMem1 = First block of memory to compare.
|
||||||
|
* - pMem2 = Second block of memory to compare.
|
||||||
|
* - cb = Size of the two memory blocks in bytes.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* 0 if the two memory blocks are the same; a value less than 0 if the memory block pointed to by pMem1 is
|
||||||
|
* less than the one pointed to by pMem2; a value greater than 0 if the memory block pointed to by pMem1 is
|
||||||
|
* greater than the one pointed to by pMem2.
|
||||||
|
*/
|
||||||
|
.globl StrCompareMem
|
||||||
|
StrCompareMem:
|
||||||
|
mov ip, r0
|
||||||
|
cmp r2, #0x06 /* optimized version for 6-byte compares */
|
||||||
|
beq .Lmemcmp_6bytes
|
||||||
|
mov r0, #0x00
|
||||||
|
|
||||||
|
/* Are both addresses aligned the same way? */
|
||||||
|
cmp r2, #0x00
|
||||||
|
eornes r3, ip, r1
|
||||||
|
bxeq lr /* len == 0, or same addresses! */
|
||||||
|
tst r3, #0x03
|
||||||
|
subne r2, r2, #0x01
|
||||||
|
bne .Lmemcmp_bytewise2 /* Badly aligned. Do it the slow way */
|
||||||
|
|
||||||
|
/* Word-align the addresses, if necessary */
|
||||||
|
sub r3, r1, #0x05
|
||||||
|
ands r3, r3, #0x03
|
||||||
|
add r3, r3, r3, lsl #1
|
||||||
|
addne pc, pc, r3, lsl #3
|
||||||
|
nop
|
||||||
|
|
||||||
|
/* Compare up to 3 bytes */
|
||||||
|
ldrb r0, [ip], #0x01
|
||||||
|
ldrb r3, [r1], #0x01
|
||||||
|
subs r0, r0, r3
|
||||||
|
bxne lr
|
||||||
|
subs r2, r2, #0x01
|
||||||
|
bxeq lr
|
||||||
|
|
||||||
|
/* Compare up to 2 bytes */
|
||||||
|
ldrb r0, [ip], #0x01
|
||||||
|
ldrb r3, [r1], #0x01
|
||||||
|
subs r0, r0, r3
|
||||||
|
bxne lr
|
||||||
|
subs r2, r2, #0x01
|
||||||
|
bxeq lr
|
||||||
|
|
||||||
|
/* Compare 1 byte */
|
||||||
|
ldrb r0, [ip], #0x01
|
||||||
|
ldrb r3, [r1], #0x01
|
||||||
|
subs r0, r0, r3
|
||||||
|
bxne lr
|
||||||
|
subs r2, r2, #0x01
|
||||||
|
bxeq lr
|
||||||
|
|
||||||
|
/* Compare 4 bytes at a time, if possible */
|
||||||
|
subs r2, r2, #0x04
|
||||||
|
bcc .Lmemcmp_bytewise
|
||||||
|
.Lmemcmp_word_aligned:
|
||||||
|
ldr r0, [ip], #0x04
|
||||||
|
ldr r3, [r1], #0x04
|
||||||
|
subs r2, r2, #0x04
|
||||||
|
cmpcs r0, r3
|
||||||
|
beq .Lmemcmp_word_aligned
|
||||||
|
sub r0, r0, r3
|
||||||
|
|
||||||
|
/* Correct for extra subtraction, and check if done */
|
||||||
|
adds r2, r2, #0x04
|
||||||
|
cmpeq r0, #0x00 /* If done, did all bytes match? */
|
||||||
|
bxeq lr /* Yup. Just return */
|
||||||
|
|
||||||
|
/* Re-do the final word byte-wise */
|
||||||
|
sub ip, ip, #0x04
|
||||||
|
sub r1, r1, #0x04
|
||||||
|
|
||||||
|
.Lmemcmp_bytewise:
|
||||||
|
add r2, r2, #0x03
|
||||||
|
.Lmemcmp_bytewise2:
|
||||||
|
ldrb r0, [ip], #0x01
|
||||||
|
ldrb r3, [r1], #0x01
|
||||||
|
subs r2, r2, #0x01
|
||||||
|
cmpcs r0, r3
|
||||||
|
beq .Lmemcmp_bytewise2
|
||||||
|
sub r0, r0, r3
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 6 byte compares are very common, thanks to the network stack.
|
||||||
|
* This code is hand-scheduled to reduce the number of stalls for
|
||||||
|
* load results. Everything else being equal, this will be ~32%
|
||||||
|
* faster than a byte-wise memcmp.
|
||||||
|
*/
|
||||||
|
.align 5
|
||||||
|
.Lmemcmp_6bytes:
|
||||||
|
ldrb r3, [r1, #0x00] /* r3 = b2#0 */
|
||||||
|
ldrb r0, [ip, #0x00] /* r0 = b1#0 */
|
||||||
|
ldrb r2, [r1, #0x01] /* r2 = b2#1 */
|
||||||
|
subs r0, r0, r3 /* r0 = b1#0 - b2#0 */
|
||||||
|
ldreqb r3, [ip, #0x01] /* r3 = b1#1 */
|
||||||
|
bxne lr /* Return if mismatch on #0 */
|
||||||
|
subs r0, r3, r2 /* r0 = b1#1 - b2#1 */
|
||||||
|
ldreqb r3, [r1, #0x02] /* r3 = b2#2 */
|
||||||
|
ldreqb r0, [ip, #0x02] /* r0 = b1#2 */
|
||||||
|
bxne lr /* Return if mismatch on #1 */
|
||||||
|
ldrb r2, [r1, #0x03] /* r2 = b2#3 */
|
||||||
|
subs r0, r0, r3 /* r0 = b1#2 - b2#2 */
|
||||||
|
ldreqb r3, [ip, #0x03] /* r3 = b1#3 */
|
||||||
|
bxne lr /* Return if mismatch on #2 */
|
||||||
|
subs r0, r3, r2 /* r0 = b1#3 - b2#3 */
|
||||||
|
ldreqb r3, [r1, #0x04] /* r3 = b2#4 */
|
||||||
|
ldreqb r0, [ip, #0x04] /* r0 = b1#4 */
|
||||||
|
bxne lr /* Return if mismatch on #3 */
|
||||||
|
ldrb r2, [r1, #0x05] /* r2 = b2#5 */
|
||||||
|
subs r0, r0, r3 /* r0 = b1#4 - b2#4 */
|
||||||
|
ldreqb r3, [ip, #0x05] /* r3 = b1#5 */
|
||||||
|
bxne lr /* Return if mismatch on #4 */
|
||||||
|
sub r0, r3, r2 /* r0 = b1#5 - b2#5 */
|
||||||
|
bx lr
|
|
@ -58,14 +58,14 @@
|
||||||
*
|
*
|
||||||
* Apologies for the state of the comments ;-)
|
* Apologies for the state of the comments ;-)
|
||||||
*/
|
*/
|
||||||
/* Func: PVOID StrCopyMem(PVOID pDest, PCVOID pSrc, INT32 nBytes); */
|
/* Func: PVOID StrCopyMem(PVOID pDest, PCVOID pSrc, SSIZE_T cb); */
|
||||||
/*
|
/*
|
||||||
* Copies memory data from one block of memory to another. Assumes the memory blocks do NOT overlap.
|
* Copies memory data from one block of memory to another. Assumes the memory blocks do NOT overlap.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* - pDest = Destination for the copy operation.
|
* - pDest = Destination for the copy operation.
|
||||||
* - pSrc = Source for the copy operation.
|
* - pSrc = Source for the copy operation.
|
||||||
* - nBytes = Number of bytes to be copied.
|
* - cb = Number of bytes to be copied.
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* pDest.
|
* pDest.
|
||||||
|
|
183
kernel/strsetmem.S
Normal file
183
kernel/strsetmem.S
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2003 Wasabi Systems, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Written by Steve C. Woodford for Wasabi Systems, Inc.
|
||||||
|
*
|
||||||
|
* 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. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed for the NetBSD Project by
|
||||||
|
* Wasabi Systems, Inc.
|
||||||
|
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
|
||||||
|
* or promote products derived from this software without specific prior
|
||||||
|
* written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1995 Mark Brinicombe.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* 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. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by Mark Brinicombe.
|
||||||
|
* 4. The name of the company nor the name of the author may 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 OR CONTRIBUTORS 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.
|
||||||
|
*/
|
||||||
|
/* Taken from FreeBSD memset.S, munged by Erbo to COMROGUE standards */
|
||||||
|
.section ".lib.text"
|
||||||
|
|
||||||
|
/* FUNC: PVOID StrSetMem(PVOID pMem, INT32 ch, SSIZE_T cb); */
|
||||||
|
/*
|
||||||
|
* Fills a block of memory with a constant byte value.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pMem = Pointer to the memory block to be filled.
|
||||||
|
* - ch = The constant byte (character) to fill that memory with.
|
||||||
|
* - cb = The size in bytes of the memory block to be filled.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* pMem.
|
||||||
|
*/
|
||||||
|
.globl StrSetMem
|
||||||
|
StrSetMem:
|
||||||
|
and r3, r1, #0xff /* We deal with bytes */
|
||||||
|
mov r1, r2
|
||||||
|
cmp r1, #0x04 /* Do we have less than 4 bytes */
|
||||||
|
mov ip, r0
|
||||||
|
blt .Lmemset_lessthanfour
|
||||||
|
|
||||||
|
/* Ok first we will word align the address */
|
||||||
|
ands r2, ip, #0x03 /* Get the bottom two bits */
|
||||||
|
bne .Lmemset_wordunaligned /* The address is not word aligned */
|
||||||
|
|
||||||
|
/* We are now word aligned */
|
||||||
|
.Lmemset_wordaligned:
|
||||||
|
orr r3, r3, r3, lsl #8 /* Extend value to 16-bits */
|
||||||
|
tst ip, #0x04 /* Quad-align for armv5e */
|
||||||
|
orr r3, r3, r3, lsl #16 /* Extend value to 32-bits */
|
||||||
|
subne r1, r1, #0x04 /* Quad-align if necessary */
|
||||||
|
strne r3, [ip], #0x04
|
||||||
|
cmp r1, #0x10
|
||||||
|
blt .Lmemset_loop4 /* If less than 16 then use words */
|
||||||
|
mov r2, r3 /* Duplicate data */
|
||||||
|
cmp r1, #0x80 /* If < 128 then skip the big loop */
|
||||||
|
blt .Lmemset_loop32
|
||||||
|
|
||||||
|
/* Do 128 bytes at a time */
|
||||||
|
.Lmemset_loop128:
|
||||||
|
subs r1, r1, #0x80
|
||||||
|
strged r2, [ip], #0x08
|
||||||
|
strged r2, [ip], #0x08
|
||||||
|
strged r2, [ip], #0x08
|
||||||
|
strged r2, [ip], #0x08
|
||||||
|
strged r2, [ip], #0x08
|
||||||
|
strged r2, [ip], #0x08
|
||||||
|
strged r2, [ip], #0x08
|
||||||
|
strged r2, [ip], #0x08
|
||||||
|
strged r2, [ip], #0x08
|
||||||
|
strged r2, [ip], #0x08
|
||||||
|
strged r2, [ip], #0x08
|
||||||
|
strged r2, [ip], #0x08
|
||||||
|
strged r2, [ip], #0x08
|
||||||
|
strged r2, [ip], #0x08
|
||||||
|
strged r2, [ip], #0x08
|
||||||
|
strged r2, [ip], #0x08
|
||||||
|
bgt .Lmemset_loop128
|
||||||
|
bxeq lr /* Zero length so just exit */
|
||||||
|
|
||||||
|
add r1, r1, #0x80 /* Adjust for extra sub */
|
||||||
|
|
||||||
|
/* Do 32 bytes at a time */
|
||||||
|
.Lmemset_loop32:
|
||||||
|
subs r1, r1, #0x20
|
||||||
|
strged r2, [ip], #0x08
|
||||||
|
strged r2, [ip], #0x08
|
||||||
|
strged r2, [ip], #0x08
|
||||||
|
strged r2, [ip], #0x08
|
||||||
|
bgt .Lmemset_loop32
|
||||||
|
bxeq lr /* Zero length so just exit */
|
||||||
|
|
||||||
|
adds r1, r1, #0x10 /* Partially adjust for extra sub */
|
||||||
|
|
||||||
|
/* Deal with 16 bytes or more */
|
||||||
|
strged r2, [ip], #0x08
|
||||||
|
strged r2, [ip], #0x08
|
||||||
|
bxeq lr /* Zero length so just exit */
|
||||||
|
|
||||||
|
addlt r1, r1, #0x10 /* Possibly adjust for extra sub */
|
||||||
|
|
||||||
|
/* We have at least 4 bytes so copy as words */
|
||||||
|
.Lmemset_loop4:
|
||||||
|
subs r1, r1, #0x04
|
||||||
|
strge r3, [ip], #0x04
|
||||||
|
bgt .Lmemset_loop4
|
||||||
|
bxeq lr /* Zero length so just exit */
|
||||||
|
|
||||||
|
/* Compensate for 64-bit alignment check */
|
||||||
|
adds r1, r1, #0x04
|
||||||
|
bxeq lr
|
||||||
|
cmp r1, #2
|
||||||
|
|
||||||
|
strb r3, [ip], #0x01 /* Set 1 byte */
|
||||||
|
strgeb r3, [ip], #0x01 /* Set another byte */
|
||||||
|
strgtb r3, [ip] /* and a third */
|
||||||
|
bx lr /* Exit */
|
||||||
|
|
||||||
|
.Lmemset_wordunaligned:
|
||||||
|
rsb r2, r2, #0x004
|
||||||
|
strb r3, [ip], #0x01 /* Set 1 byte */
|
||||||
|
cmp r2, #0x02
|
||||||
|
strgeb r3, [ip], #0x01 /* Set another byte */
|
||||||
|
sub r1, r1, r2
|
||||||
|
strgtb r3, [ip], #0x01 /* and a third */
|
||||||
|
cmp r1, #0x04 /* More than 4 bytes left? */
|
||||||
|
bge .Lmemset_wordaligned /* Yup */
|
||||||
|
|
||||||
|
.Lmemset_lessthanfour:
|
||||||
|
cmp r1, #0x00
|
||||||
|
bxeq lr /* Zero length so exit */
|
||||||
|
strb r3, [ip], #0x01 /* Set 1 byte */
|
||||||
|
cmp r1, #0x02
|
||||||
|
strgeb r3, [ip], #0x01 /* Set another byte */
|
||||||
|
strgtb r3, [ip] /* and a third */
|
||||||
|
bx lr /* Exit */
|
465
kernel/vmmap.c
Normal file
465
kernel/vmmap.c
Normal file
|
@ -0,0 +1,465 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the COMROGUE Operating System for Raspberry Pi
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, Eric J. Bowersox / Erbosoft Enterprises
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free for commercial and non-commercial use as long as the following conditions are
|
||||||
|
* adhered to.
|
||||||
|
*
|
||||||
|
* Copyright in this file remains Eric J. Bowersox and/or Erbosoft, and as such any copyright notices
|
||||||
|
* in the code are not to be removed.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
* provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice, this list of conditions and
|
||||||
|
* the following disclaimer.
|
||||||
|
* * 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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
||||||
|
*
|
||||||
|
* "Raspberry Pi" is a trademark of the Raspberry Pi Foundation.
|
||||||
|
*/
|
||||||
|
#include <comrogue/types.h>
|
||||||
|
#include <comrogue/scode.h>
|
||||||
|
#include <comrogue/internals/seg.h>
|
||||||
|
#include <comrogue/internals/mmu.h>
|
||||||
|
#include <comrogue/internals/memmgr.h>
|
||||||
|
#include <comrogue/internals/startup.h>
|
||||||
|
|
||||||
|
#define NMAPFRAMES 4 /* number of frame mappings */
|
||||||
|
|
||||||
|
static PTTB g_pttb1 = NULL; /* pointer to TTB1 */
|
||||||
|
static KERNADDR g_kaEndFence = 0; /* end fence in kernel addresses, after we reserve some */
|
||||||
|
static KERNADDR g_kaTableMap[NMAPFRAMES] = { 0 }; /* kernel addresses for page table mappings */
|
||||||
|
static PHYSADDR g_paTableMap[NMAPFRAMES] = { 0 }; /* physical addresses for page table mappings */
|
||||||
|
static UINT32 g_refTableMap[NMAPFRAMES] = { 0 }; /* reference counts for table mappings */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Maps a page table's page into kernel memory space where we can examine it.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - paPageTable = Physical address of the page table to map.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* Pointer to the pagetable in kernel memory, or NULL if we weren't able to map it.
|
||||||
|
*
|
||||||
|
* Side effects:
|
||||||
|
* May modify g_paTableMap and g_refTableMap, and may modify TTB1 if we map a page into memory.
|
||||||
|
*/
|
||||||
|
static PPAGETAB map_pagetable(PHYSADDR paPageTable)
|
||||||
|
{
|
||||||
|
PHYSADDR paOfPage = paPageTable & ~(SYS_PAGE_SIZE - 1); /* actual page table page's PA */
|
||||||
|
register UINT32 i; /* loop counter */
|
||||||
|
|
||||||
|
for (i = 0; i < NMAPFRAMES; i++)
|
||||||
|
{
|
||||||
|
if (g_paTableMap[i] == paOfPage)
|
||||||
|
{
|
||||||
|
g_refTableMap[i]++; /* already mapped, return it */
|
||||||
|
goto returnOK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < NMAPFRAMES; i++)
|
||||||
|
{
|
||||||
|
if (!(g_paTableMap[i]))
|
||||||
|
{
|
||||||
|
g_paTableMap[i] = paOfPage; /* claim slot and map into it */
|
||||||
|
g_refTableMap[i] = 1;
|
||||||
|
if (FAILED(MmMapPages(g_pttb1, g_paTableMap[i], g_kaTableMap[i], 1, TTBFLAGS_KERNEL_DATA,
|
||||||
|
PGTBLFLAGS_KERNEL_DATA)))
|
||||||
|
{
|
||||||
|
g_refTableMap[i] = 0;
|
||||||
|
g_paTableMap[i] = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == NMAPFRAMES)
|
||||||
|
return NULL;
|
||||||
|
returnOK:
|
||||||
|
return (PPAGETAB)(g_kaTableMap[i] | (paPageTable & (SYS_PAGE_SIZE - 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Demaps a page table's page from kernel memory space.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - ppgtbl = Pointer to the page table.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* Nothing.
|
||||||
|
*
|
||||||
|
* Side effects:
|
||||||
|
* May modify g_paTableMap and g_refTableMap, and may modify TTB1 if we unmap a page from memory.
|
||||||
|
*/
|
||||||
|
static void demap_pagetable(PPAGETAB ppgtbl)
|
||||||
|
{
|
||||||
|
KERNADDR kaOfPage = ((KERNADDR)ppgtbl) & ~(SYS_PAGE_SIZE - 1);
|
||||||
|
register UINT32 i; /* loop counter */
|
||||||
|
|
||||||
|
for (i = 0; i < NMAPFRAMES; i++)
|
||||||
|
{
|
||||||
|
if (g_kaTableMap[i] == kaOfPage)
|
||||||
|
{
|
||||||
|
if (--g_refTableMap[i] == 0)
|
||||||
|
{
|
||||||
|
MmDemapPages(g_pttb1, g_kaTableMap[i], 1);
|
||||||
|
g_paTableMap[i] = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Resolves a specified TTB to either itself or the global TTB1, depending on whether one was specified
|
||||||
|
* and on the virtual address to be worked with.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pTTB = The specified TTB pointer.
|
||||||
|
* - vma = The base virtual address we're working with.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* The pointer to the selected TTB, which may be the global variable g_pttb1.
|
||||||
|
*/
|
||||||
|
static PTTB resolve_ttb(PTTB pTTB, KERNADDR vma)
|
||||||
|
{
|
||||||
|
if (!pTTB || (vma & 0x80000000))
|
||||||
|
return g_pttb1; /* if no TTB specified or address is out of range for TTB0, use TTB1 */
|
||||||
|
return pTTB;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the physical address corresponding to a virtual memory address.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pTTB = The TTB to resolve the VM address against. If this is NULL or if the address specified
|
||||||
|
* is outside the TTB0 range, the system TTB is used.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* The physical address corresponding to the virtual memory address, or NULL if the address could
|
||||||
|
* not be resolved (is not mapped, or page table could not be mapped).
|
||||||
|
*/
|
||||||
|
PHYSADDR MmGetPhysAddr(PTTB pTTB, KERNADDR vma)
|
||||||
|
{
|
||||||
|
PTTB pTTBEntry = resolve_ttb(pTTB, vma) + mmVMA2TTBIndex(vma);
|
||||||
|
PPAGETAB pTab;
|
||||||
|
PHYSADDR rc;
|
||||||
|
|
||||||
|
if ((pTTBEntry->data & TTBQUERY_MASK) == TTBQUERY_FAULT)
|
||||||
|
return NULL; /* we're not allocated */
|
||||||
|
if (pTTBEntry->data & TTBSEC_ALWAYS)
|
||||||
|
return (pTTBEntry->data & TTBSEC_BASE) | (vma & ~TTBSEC_BASE); /* resolve section address */
|
||||||
|
|
||||||
|
pTab = map_pagetable(pTTBEntry->data & TTBPGTBL_BASE);
|
||||||
|
if (!pTab)
|
||||||
|
return NULL; /* could not map the page table */
|
||||||
|
rc = (pTab->pgtbl[mmVMA2PGTBLIndex(vma)].pg.pgaddr << SYS_PAGE_BITS) | (vma & (SYS_PAGE_SIZE - 1));
|
||||||
|
demap_pagetable(pTab);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deallocates page mapping entries within a single current entry in the TTB.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - pTTBEntry = Pointer to the TTB entry to deallocate in.
|
||||||
|
* - ndxPage = Starting index in the page table of the first entry to deallocate.
|
||||||
|
* - cpg = Count of the number of pages to deallocate. Note that this function will not deallocate more
|
||||||
|
* page mapping entries than remain on the page, as indicated by ndxPage.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* Standard HRESULT success/failure. If the result is successful, the SCODE_CODE of the result will
|
||||||
|
* indicate the number of pages actually deallocated.
|
||||||
|
*
|
||||||
|
* Side effects:
|
||||||
|
* May modify the TTB entry pointed to, and the page table it points to, where applicable. If the
|
||||||
|
* page table is empty after we finish demapping entries, it may be deallocated.
|
||||||
|
*/
|
||||||
|
static HRESULT demap_pages1(PTTB pTTBEntry, UINT32 ndxPage, UINT32 cpg)
|
||||||
|
{
|
||||||
|
UINT32 cpgCurrent; /* number of pages we're mapping */
|
||||||
|
PPAGETAB pTab = NULL; /* pointer to current or new page table */
|
||||||
|
HRESULT hr; /* return from this function */
|
||||||
|
register INT32 i; /* loop counter */
|
||||||
|
|
||||||
|
/* Figure out how many entries we're going to demap. */
|
||||||
|
cpgCurrent = SYS_PGTBL_ENTRIES - ndxPage; /* total free slots on page */
|
||||||
|
if (cpg < cpgCurrent)
|
||||||
|
cpgCurrent = cpg; /* only map up to max requested */
|
||||||
|
hr = MAKE_SCODE(SEVERITY_SUCCESS, FACILITY_MEMMGR, cpgCurrent);
|
||||||
|
|
||||||
|
if ((pTTBEntry->data & TTBSEC_ALWAYS) && (cpgCurrent == SYS_PGTBL_ENTRIES) && (ndxPage == 0))
|
||||||
|
{ /* we can kill off the whole section */
|
||||||
|
pTTBEntry->data = 0;
|
||||||
|
/* TODO: handle TLB and cache */
|
||||||
|
}
|
||||||
|
else if (pTTBEntry->data & TTBPGTBL_ALWAYS)
|
||||||
|
{
|
||||||
|
pTab = map_pagetable(pTTBEntry->data & TTBPGTBL_BASE);
|
||||||
|
if (!pTab)
|
||||||
|
return MEMMGR_E_NOPGTBL;
|
||||||
|
for (i = 0; i<cpgCurrent; i++)
|
||||||
|
{
|
||||||
|
pTab->pgtbl[ndxPage + i].data = 0;
|
||||||
|
pTab->pgaux[ndxPage + i].data = 0;
|
||||||
|
/* TODO: handle TLB and cache */
|
||||||
|
}
|
||||||
|
/* TODO: check to see if page table can be deallocated */
|
||||||
|
demap_pagetable(pTab);
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT MmDemapPages(PTTB pTTB, KERNADDR vmaBase, UINT32 cpg)
|
||||||
|
{
|
||||||
|
PTTB pMyTTB = resolve_ttb(pTTB, vmaBase); /* the TTB we use */
|
||||||
|
UINT32 ndxTTBMax = (pMyTTB == g_pttb1) ? SYS_TTB1_ENTRIES : SYS_TTB0_ENTRIES;
|
||||||
|
UINT32 ndxTTB = mmVMA2TTBIndex(vmaBase); /* TTB entry index */
|
||||||
|
UINT32 ndxPage = mmVMA2PGTBLIndex(vmaBase); /* starting page entry index */
|
||||||
|
UINT32 cpgRemaining = cpg; /* number of pages remaining to demap */
|
||||||
|
HRESULT hr; /* temporary result */
|
||||||
|
|
||||||
|
if ((cpgRemaining > 0) && (ndxPage > 0))
|
||||||
|
{
|
||||||
|
/* We are starting in the middle of a VM page. Demap to the end of the VM page. */
|
||||||
|
hr = demap_pages1(pMyTTB + ndxTTB, ndxPage, cpgRemaining);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
cpgRemaining -= SCODE_CODE(hr);
|
||||||
|
if (++ndxTTB == ndxTTBMax)
|
||||||
|
return MEMMGR_E_ENDTTB;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (cpgRemaining > 0)
|
||||||
|
{
|
||||||
|
hr = demap_pages1(pMyTTB + ndxTTB, 0, cpgRemaining);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
cpgRemaining -= SCODE_CODE(hr);
|
||||||
|
if (++ndxTTB == ndxTTBMax)
|
||||||
|
return MEMMGR_E_ENDTTB;
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Morphs the "flags" bits used for a page table entry in the TTB and for a page entry in the page table
|
||||||
|
* into the "flags" bits used for a section entry in the TTB.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* - uiTableFlags = Flag bits that would be used for a page table entry in the TTB.
|
||||||
|
* - uiPageFlags = Flag bits that would be used for a page entry in the page table.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* The flag bits that would be used for a section entry in the TTB. If a bit or option is set
|
||||||
|
* in either uiTableFlags or uiPageFlags, it will be set in the appropriate place in the result.
|
||||||
|
*/
|
||||||
|
static UINT32 make_section_flags(UINT32 uiTableFlags, UINT32 uiPageFlags)
|
||||||
|
{
|
||||||
|
register UINT32 rc = TTBSEC_ALWAYS;
|
||||||
|
rc |= ((uiTableFlags & TTBPGTBL_PXN) >> 2);
|
||||||
|
rc |= ((uiTableFlags & TTBPGTBL_NS) << 16);
|
||||||
|
rc |= (uiTableFlags & TTBPGTBL_DOM_MASK);
|
||||||
|
rc |= (uiTableFlags & TTBPGTBL_P);
|
||||||
|
rc |= ((uiPageFlags & PGTBLSM_XN) << 4);
|
||||||
|
rc |= (uiPageFlags & PGTBLSM_B);
|
||||||
|
rc |= (uiPageFlags & PGTBLSM_C);
|
||||||
|
rc |= ((uiPageFlags & PGTBLSM_AP) << 6);
|
||||||
|
rc |= ((uiPageFlags & PGTBLSM_TEX) << 6);
|
||||||
|
rc |= ((uiPageFlags & PGTBLSM_APX) << 6);
|
||||||
|
rc |= ((uiPageFlags & PGTBLSM_S) << 6);
|
||||||
|
rc |= ((uiPageFlags & PGTBLSM_NG) << 6);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT map_pages1(PTTB pttbEntry, PHYSADDR paBase, UINT32 ndxPage, UINT32 cpg, UINT32 uiTableFlags,
|
||||||
|
UINT32 uiPageFlags)
|
||||||
|
{
|
||||||
|
UINT32 cpgCurrent; /* number of pages we're mapping */
|
||||||
|
PPAGETAB pTab = NULL; /* pointer to current or new page table */
|
||||||
|
HRESULT hr; /* return from this function */
|
||||||
|
register INT32 i; /* loop counter */
|
||||||
|
|
||||||
|
switch (pttbEntry->data & TTBQUERY_MASK)
|
||||||
|
{
|
||||||
|
case TTBQUERY_FAULT: /* not allocated, allocate a new page table for the slot */
|
||||||
|
/* TODO: allocate something into pTab */
|
||||||
|
if (!pTab)
|
||||||
|
return MEMMGR_E_NOPGTBL;
|
||||||
|
for (i=0; i<SYS_PGTBL_ENTRIES; i++)
|
||||||
|
{
|
||||||
|
pTab->pgtbl[i].data = 0; /* blank out the new page table */
|
||||||
|
pTab->pgaux[i].data = 0;
|
||||||
|
}
|
||||||
|
/* TODO: use physical address of page here */
|
||||||
|
pttbEntry->data = MmGetPhysAddr(g_pttb1, (KERNADDR)pTab) | uiTableFlags; /* poke new entry */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TTBQUERY_PGTBL: /* existing page table */
|
||||||
|
if ((pttbEntry->data & TTBPGTBL_ALLFLAGS) != uiTableFlags)
|
||||||
|
return MEMMGR_E_BADTTBFLG; /* table flags not compatible */
|
||||||
|
pTab = map_pagetable(pttbEntry->data & TTBPGTBL_BASE);
|
||||||
|
if (!pTab)
|
||||||
|
return MEMMGR_E_NOPGTBL; /* could not map the page table */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TTBQUERY_SEC:
|
||||||
|
case TTBQUERY_PXNSEC:
|
||||||
|
/* this is a section, make sure its base address covers this mapping and its flags are compatible */
|
||||||
|
if ((pttbEntry->data & TTBSEC_ALLFLAGS) != make_section_flags(uiTableFlags, uiPageFlags))
|
||||||
|
return MEMMGR_E_BADTTBFLG;
|
||||||
|
if ((pttbEntry->data & TTBSEC_BASE) != (paBase & TTBSEC_BASE))
|
||||||
|
return MEMMGR_E_COLLIDED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Figure out how many entries we're going to map. */
|
||||||
|
cpgCurrent = SYS_PGTBL_ENTRIES - ndxPage; /* total free slots on page */
|
||||||
|
if (cpg < cpgCurrent)
|
||||||
|
cpgCurrent = cpg; /* only map up to max requested */
|
||||||
|
hr = MAKE_SCODE(SEVERITY_SUCCESS, FACILITY_MEMMGR, cpgCurrent);
|
||||||
|
|
||||||
|
if (!(pttbEntry->data & TTBSEC_ALWAYS))
|
||||||
|
{
|
||||||
|
/* fill in entries in the page table */
|
||||||
|
for (i=0; i < cpgCurrent; i++)
|
||||||
|
{
|
||||||
|
if ((pTab->pgtbl[ndxPage + i].data & PGQUERY_MASK) != PGQUERY_FAULT)
|
||||||
|
{
|
||||||
|
while (--i >= 0)
|
||||||
|
{ /* reverse any mapping we've done in this function */
|
||||||
|
pTab->pgtbl[ndxPage + i].data = 0;
|
||||||
|
pTab->pgaux[ndxPage + i].data = 0;
|
||||||
|
}
|
||||||
|
hr = MEMMGR_E_COLLIDED; /* stepping on existing mapping */
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
pTab->pgtbl[ndxPage + i].data = paBase | uiPageFlags;
|
||||||
|
pTab->pgaux[ndxPage + i].data = 0; /* TODO */
|
||||||
|
paBase += SYS_PAGE_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exit:
|
||||||
|
demap_pagetable(pTab);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT MmMapPages(PTTB pTTB, PHYSADDR paBase, KERNADDR vmaBase, UINT32 cpg, UINT32 uiTableFlags,
|
||||||
|
UINT32 uiPageFlags)
|
||||||
|
{
|
||||||
|
PTTB pMyTTB = resolve_ttb(pTTB, vmaBase); /* the TTB we use */
|
||||||
|
UINT32 ndxTTBMax = (pMyTTB == g_pttb1) ? SYS_TTB1_ENTRIES : SYS_TTB0_ENTRIES;
|
||||||
|
UINT32 ndxTTB = mmVMA2TTBIndex(vmaBase); /* TTB entry index */
|
||||||
|
UINT32 ndxPage = mmVMA2PGTBLIndex(vmaBase); /* starting page entry index */
|
||||||
|
UINT32 cpgRemaining = cpg; /* number of pages remaining to map */
|
||||||
|
HRESULT hr; /* temporary result */
|
||||||
|
|
||||||
|
if ((cpgRemaining > 0) && (ndxPage > 0))
|
||||||
|
{
|
||||||
|
/* We are starting in the middle of a VM page. Map to the end of the VM page. */
|
||||||
|
hr = map_pages1(pMyTTB + ndxTTB, paBase, ndxPage, cpgRemaining, uiTableFlags, uiPageFlags);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
cpgRemaining -= SCODE_CODE(hr);
|
||||||
|
paBase += (SCODE_CODE(hr) << SYS_PAGE_BITS);
|
||||||
|
if (++ndxTTB == ndxTTBMax)
|
||||||
|
{
|
||||||
|
hr = MEMMGR_E_ENDTTB;
|
||||||
|
goto errorExit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (cpgRemaining >= SYS_PGTBL_ENTRIES)
|
||||||
|
{
|
||||||
|
/* try to map a whole section's worth at a time */
|
||||||
|
if ((paBase & TTBSEC_BASE) == paBase)
|
||||||
|
{
|
||||||
|
/* paBase is section-aligned now as well, we can use a direct 1Mb section mapping */
|
||||||
|
switch (pMyTTB[ndxTTB].data & TTBQUERY_MASK)
|
||||||
|
{
|
||||||
|
case TTBQUERY_FAULT: /* unmapped - map the section */
|
||||||
|
pMyTTB[ndxTTB].data = paBase | make_section_flags(uiTableFlags, uiPageFlags);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TTBQUERY_PGTBL: /* collided with a page table */
|
||||||
|
hr = MEMMGR_E_COLLIDED;
|
||||||
|
goto errorExit;
|
||||||
|
|
||||||
|
case TTBQUERY_SEC: /* test existing section */
|
||||||
|
case TTBQUERY_PXNSEC:
|
||||||
|
if ((pMyTTB[ndxTTB].data & TTBSEC_ALLFLAGS) != make_section_flags(uiTableFlags, uiPageFlags))
|
||||||
|
{
|
||||||
|
hr = MEMMGR_E_BADTTBFLG;
|
||||||
|
goto errorExit;
|
||||||
|
}
|
||||||
|
if ((pMyTTB[ndxTTB].data & TTBSEC_BASE) != paBase)
|
||||||
|
{
|
||||||
|
hr = MEMMGR_E_COLLIDED;
|
||||||
|
goto errorExit;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* we mapped a whole section worth */
|
||||||
|
hr = MAKE_SCODE(SEVERITY_SUCCESS, FACILITY_MEMMGR, SYS_PGTBL_ENTRIES);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* just map 256 individual pages */
|
||||||
|
hr = map_pages1(pMyTTB + ndxTTB, paBase, 0, cpgRemaining, uiTableFlags, uiPageFlags);
|
||||||
|
if (FAILED(hr))
|
||||||
|
goto errorExit;
|
||||||
|
}
|
||||||
|
/* adjust base physical address, page count, and TTB index */
|
||||||
|
paBase += (SCODE_CODE(hr) << SYS_PAGE_BITS);
|
||||||
|
cpgRemaining -= SCODE_CODE(hr);
|
||||||
|
if (++ndxTTB == ndxTTBMax)
|
||||||
|
{
|
||||||
|
hr = MEMMGR_E_ENDTTB;
|
||||||
|
goto errorExit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cpgRemaining > 0)
|
||||||
|
{
|
||||||
|
/* map the "tail end" onto the next TTB */
|
||||||
|
hr = map_pages1(pMyTTB + ndxTTB, paBase, 0, cpgRemaining, uiTableFlags, uiPageFlags);
|
||||||
|
if (FAILED(hr))
|
||||||
|
goto errorExit;
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
errorExit:
|
||||||
|
/* demap everything we've managed to map thusfar */
|
||||||
|
MmDemapPages(pMyTTB, vmaBase, cpg - cpgRemaining);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------
|
||||||
|
* Initialization code
|
||||||
|
*---------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
SEG_INIT_CODE void _MmInitVMMap(PSTARTUP_INFO pstartup)
|
||||||
|
{
|
||||||
|
UINT32 i; /* loop counter */
|
||||||
|
|
||||||
|
g_pttb1 = (PTTB)(pstartup->kaTTB);
|
||||||
|
g_kaEndFence = pstartup->vmaFirstFree;
|
||||||
|
for (i=0; i<NMAPFRAMES; i++)
|
||||||
|
{
|
||||||
|
g_kaTableMap[i] = g_kaEndFence;
|
||||||
|
g_kaEndFence += SYS_PAGE_SIZE;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user