diff --git a/include/comrogue/objhelp.h b/include/comrogue/objhelp.h index 02ec098..e856b35 100644 --- a/include/comrogue/objhelp.h +++ b/include/comrogue/objhelp.h @@ -36,18 +36,45 @@ #include #include +#include #include #include +/*------------------------------------------------ + * Generic fixed connection point data structure. + *------------------------------------------------ + */ + +typedef struct tagFIXEDCPDATA +{ + IConnectionPoint connectionPointInterface; /* the connection point interface */ + PUNKNOWN punkOuter; /* outer unknown used for reference counts */ + REFIID riidConnection; /* IID of outgoing interface for this connection point */ + IUnknown **ppSlots; /* pointer to actual slots used for connection point storage */ + INT32 ncpSize; /* number of connection points actually connected */ + INT32 ncpCapacity; /* maximum number of connection points connectable */ +} FIXEDCPDATA, *PFIXEDCPDATA; + +/*--------------------- + * Function prototypes + *--------------------- + */ + CDECL_BEGIN /* QueryInterface helpers */ +extern HRESULT ObjHlpStandardQueryInterface_IConnectionPoint(IUnknown *pThis, REFIID riid, PPVOID ppvObject); extern HRESULT ObjHlpStandardQueryInterface_IMalloc(IUnknown *pThis, REFIID riid, PPVOID ppvObject); extern HRESULT ObjHlpStandardQueryInterface_ISequentialStream(IUnknown *pThis, REFIID riid, PPVOID ppvObject); /* AddRef/Release helpers */ extern UINT32 ObjHlpStaticAddRefRelease(IUnknown *pThis); +/* Connection point helpers */ +extern void ObjHlpFixedCpSetup(PFIXEDCPDATA pData, PUNKNOWN punkOuter, REFIID riidConnection, + IUnknown **ppSlots, INT32 nSlots); +extern void ObjHlpFixedCpTeardown(PFIXEDCPDATA pData); + /* Other helpers */ extern void ObjHlpDoNothingReturnVoid(IUnknown *pThis); extern HRESULT ObjHlpNotImplemented(IUnknown *pThis); diff --git a/kernel/lib/Makefile b/kernel/lib/Makefile index 4b05c44..c06c9e9 100644 --- a/kernel/lib/Makefile +++ b/kernel/lib/Makefile @@ -32,7 +32,7 @@ MAKEFLAGS += -rR CRBASEDIR := $(abspath ../..) include $(CRBASEDIR)/armcompile.mk -LIB_OBJS = divide.o qdivrem.o heap_toplevel.o intlib.o objhelp.o rbtree.o str.o \ +LIB_OBJS = divide.o qdivrem.o heap_toplevel.o intlib.o objhelp.o objhelp_fixedcp.o rbtree.o str.o \ strcopymem.o strcomparemem.o strsetmem.o lib_guids.o all: kernel-lib.o diff --git a/kernel/lib/heap_toplevel.c b/kernel/lib/heap_toplevel.c index 3a05854..d9f59ff 100644 --- a/kernel/lib/heap_toplevel.c +++ b/kernel/lib/heap_toplevel.c @@ -34,6 +34,8 @@ */ #include #include +#include +#include #include #include #include @@ -44,12 +46,59 @@ *------------------------ */ -static UINT32 IMalloc_AddRef(IUnknown *pThis) +/* + * Queries for an interface on the heap object. + * + * Parameters: + * - pThis = Pointer to the heap data object (actually its IMalloc interface pointer). + * - riid = Reference to the IID of the interface we want to load. + * - ppvObject = Pointer to the location to receive the new interface pointer. + * + * Returns: + * Standard HRESULT success/failure indicator: + * - S_OK = New interface pointer was returned. + * - E_NOINTERFACE = The object does not support this interface. + * - E_POINTER = The ppvObject pointer is not valid. + */ +static HRESULT malloc_QueryInterface(IUnknown *pThis, REFIID riid, PPVOID ppvObject) +{ + if (!ppvObject) + return E_POINTER; + *ppvObject = NULL; + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IMalloc)) + *ppvObject = pThis; + else if (IsEqualIID(riid, &IID_IConnectionPointContainer)) + *ppvObject = &(((PHEAPDATA)pThis)->cpContainerInterface); + else + return E_NOINTERFACE; + IUnknown_AddRef((IUnknown *)(*ppvObject)); + return S_OK; +} + +/* + * Adds a reference to the heap data object. + * + * Parameters: + * - pThis = Pointer to the heap data object (actually its IMalloc interface pointer). + * + * Returns: + * The new reference count on the object. + */ +static UINT32 malloc_AddRef(IUnknown *pThis) { return ++(((PHEAPDATA)pThis)->uiRefCount); } -static UINT32 IMalloc_Release(IUnknown *pThis) +/* + * Removes a reference from the heap data object. The object is freed when its reference count reaches 0. + * + * Parameters: + * - pThis = Pointer to the heap data object (actually its IMalloc interface pointer). + * + * Returns: + * The new reference count on the object. + */ +static UINT32 malloc_Release(IUnknown *pThis) { PHEAPDATA phd = (PHEAPDATA)pThis; /* pointer to heap data */ UINT32 rc; /* return from this function */ @@ -68,11 +117,48 @@ static UINT32 IMalloc_Release(IUnknown *pThis) return rc; } +static PVOID malloc_Alloc(IMalloc *pThis, SIZE_T cb) +{ + return NULL; /* TODO */ +} + +static PVOID malloc_Realloc(IMalloc *pThis, PVOID pv, SIZE_T cb) +{ + return NULL; /* TODO */ +} + +static void malloc_Free(IMalloc *pThis, PVOID pv) +{ + /* TODO */ +} + +static SIZE_T malloc_GetSize(IMalloc *pThis, PVOID pv) +{ + return -1; /* TODO */ +} + +static INT32 malloc_DidAlloc(IMalloc *pThis, PVOID pv) +{ + return -1; /* TODO */ +} + +static void malloc_HeapMinimize(IMalloc *pThis) +{ + /* TODO */ +} + /* The IMalloc vtable. */ static const SEG_RODATA struct IMallocVTable vtblMalloc = { - .AddRef = IMalloc_AddRef, - .Release = IMalloc_Release + .QueryInterface = malloc_QueryInterface, + .AddRef = malloc_AddRef, + .Release = malloc_Release, + .Alloc = malloc_Alloc, + .Realloc = malloc_Realloc, + .Free = malloc_Free, + .GetSize = malloc_GetSize, + .DidAlloc = malloc_DidAlloc, + .HeapMinimize = malloc_HeapMinimize }; /*------------------------------------------ @@ -83,21 +169,71 @@ static const SEG_RODATA struct IMallocVTable vtblMalloc = /* Quick macro to get the PHEAPDATA from the IConnectionPointContainer pointer */ #define HeapDataPtr(pcpc) (((PBYTE)(pcpc)) - OFFSETOF(HEAPDATA, cpContainerInterface)) -static UINT32 IConnectionPointContainer_AddRef(IUnknown *pThis) +/* + * Queries for an interface on the heap object. + * + * Parameters: + * - pThis = Pointer to the ConnectionPointContainer interface in the heap data object. + * - riid = Reference to the IID of the interface we want to load. + * - ppvObject = Pointer to the location to receive the new interface pointer. + * + * Returns: + * Standard HRESULT success/failure indicator: + * - S_OK = New interface pointer was returned. + * - E_NOINTERFACE = The object does not support this interface. + * - E_POINTER = The ppvObject pointer is not valid. + */ +static HRESULT cpc_QueryInterface(IUnknown *pThis, REFIID riid, PPVOID ppvObject) { - return IMalloc_AddRef((IUnknown *)HeapDataPtr(pThis)); + return malloc_QueryInterface((IUnknown *)HeapDataPtr(pThis), riid, ppvObject); } -static UINT32 IConnectionPointContainer_Release(IUnknown *pThis) +/* + * Adds a reference to the heap data object. + * + * Parameters: + * - pThis = Pointer to the ConnectionPointContainer interface in the heap data object. + * + * Returns: + * The new reference count on the object. + */ +static UINT32 cpc_AddRef(IUnknown *pThis) { - return IMalloc_Release((IUnknown *)HeapDataPtr(pThis)); + return malloc_AddRef((IUnknown *)HeapDataPtr(pThis)); +} + +/* + * Removes a reference from the heap data object. The object is freed when its reference count reaches 0. + * + * Parameters: + * - pThis = Pointer to the ConnectionPointContainer interface in the heap data object. + * + * Returns: + * The new reference count on the object. + */ +static UINT32 cpc_Release(IUnknown *pThis) +{ + return malloc_Release((IUnknown *)HeapDataPtr(pThis)); +} + +static HRESULT cpc_EnumConnectionPoints(IConnectionPointContainer *pThis, IEnumConnectionPoints **ppEnum) +{ + return E_NOTIMPL; /* TODO */ +} + +static HRESULT cpc_FindConnectionPoint(IConnectionPointContainer *pThis, REFIID riid, IConnectionPoint **ppCP) +{ + return E_NOTIMPL; /* TODO */ } /* The IConnectionPointContainer vtable. */ static const SEG_RODATA struct IConnectionPointContainerVTable vtblConnectionPointContainer = { - .AddRef = IConnectionPointContainer_AddRef, - .Release = IConnectionPointContainer_Release + .QueryInterface = cpc_QueryInterface, + .AddRef = cpc_AddRef, + .Release = cpc_Release, + .EnumConnectionPoints = cpc_EnumConnectionPoints, + .FindConnectionPoint = cpc_FindConnectionPoint }; /*------------------------ diff --git a/kernel/lib/objhelp.c b/kernel/lib/objhelp.c index 8ff2552..4f60cb5 100644 --- a/kernel/lib/objhelp.c +++ b/kernel/lib/objhelp.c @@ -93,6 +93,7 @@ HRESULT ObjHlpStandardQueryInterface_ ## iface (IUnknown *pThis, REFIID riid, PP return S_OK; \ } +MAKE_BASE_QI(IConnectionPoint) MAKE_BASE_QI(IMalloc) MAKE_BASE_QI(ISequentialStream) diff --git a/kernel/lib/objhelp_fixedcp.c b/kernel/lib/objhelp_fixedcp.c new file mode 100644 index 0000000..231b215 --- /dev/null +++ b/kernel/lib/objhelp_fixedcp.c @@ -0,0 +1,124 @@ +/* + * 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 +#include +#include +#include +#include + +/*--------------------------------------------- + * IConnectionPoint vtable and implementations + *--------------------------------------------- + */ + +static UINT32 fixedcp_AddRef(IUnknown *pThis) +{ + return IUnknown_AddRef(((PFIXEDCPDATA)pThis)->punkOuter); +} + +static UINT32 fixedcp_Release(IUnknown *pThis) +{ + return IUnknown_Release(((PFIXEDCPDATA)pThis)->punkOuter); +} + +static HRESULT fixedcp_GetConnectionInterface(IConnectionPoint *pThis, IID *pIID) +{ + if (!pIID) + return E_POINTER; + StrCopyMem(pIID, ((PFIXEDCPDATA)pThis)->riidConnection, sizeof(IID)); + return S_OK; +} + +static HRESULT fixedcp_GetConnectionPointContainer(IConnectionPoint *pThis, IConnectionPointContainer *ppCPC) +{ + register HRESULT rc; /* return from underlying QI */ + + rc = IUnknown_QueryInterface(((PFIXEDCPDATA)pThis)->punkOuter, &IID_IConnectionPointContainer, (PPVOID)ppCPC); + if (rc == E_NOINTERFACE) + rc = E_UNEXPECTED; + return rc; +} + +static HRESULT fixedcp_Advise(IConnectionPoint *pThis, IUnknown *punkSink, UINT32 *puiCookie) +{ + return E_NOTIMPL; /* TODO */ +} + +static HRESULT fixedcp_Unadvise(IConnectionPoint *pThis, UINT32 uiCookie) +{ + return E_NOTIMPL; /* TODO */ +} + +static HRESULT fixedcp_EnumConnections(IConnectionPoint *pThis, IEnumConnections **ppEnum) +{ + return E_NOTIMPL; /* TODO */ +} + +/* VTable for the fixed-size connection point implementation. */ +static const SEG_RODATA struct IConnectionPointVTable vtblFixedCP = +{ + .QueryInterface = ObjHlpStandardQueryInterface_IConnectionPoint, + .AddRef = fixedcp_AddRef, + .Release = fixedcp_Release, + .GetConnectionInterface = fixedcp_GetConnectionInterface, + .GetConnectionPointContainer = fixedcp_GetConnectionPointContainer, + .Advise = fixedcp_Advise, + .Unadvise = fixedcp_Unadvise, + .EnumConnections = fixedcp_EnumConnections +}; + +/*----------------------------------------------- + * Connection point setup and teardown functions + *----------------------------------------------- + */ + +void ObjHlpFixedCpSetup(PFIXEDCPDATA pData, PUNKNOWN punkOuter, REFIID riidConnection, + IUnknown **ppSlots, INT32 nSlots) +{ + pData->connectionPointInterface.pVTable = &vtblFixedCP; + pData->punkOuter = punkOuter; + pData->riidConnection = riidConnection; + pData->ppSlots = ppSlots; + pData->ncpSize = 0; + pData->ncpCapacity = nSlots; + StrSetMem(ppSlots, 0, nSlots * sizeof(IUnknown *)); +} + +void ObjHlpFixedCpTeardown(PFIXEDCPDATA pData) +{ + register INT32 i; /* loop counter */ + + for (i = 0; i < pData->ncpCapacity; i++) + if (pData->ppSlots[i]) + IUnknown_Release(pData->ppSlots[i]); + StrSetMem(pData, 0, sizeof(FIXEDCPDATA)); +} diff --git a/kernel/mm/pagealloc.c b/kernel/mm/pagealloc.c index 27c0b48..28c0714 100644 --- a/kernel/mm/pagealloc.c +++ b/kernel/mm/pagealloc.c @@ -84,7 +84,7 @@ static void zero_page(UINT32 ndxPage) ASSERT(SUCCEEDED(hr)); if (SUCCEEDED(hr)) { - StrSetMem(g_kaZero, 0, SYS_PAGE_SIZE); + StrSetMem((PVOID)g_kaZero, 0, SYS_PAGE_SIZE); VERIFY(SUCCEEDED(MmDemapPages(NULL, g_kaZero, 1))); } }