Exemplo n.º 1
0
void __init prom_meminit(void)
{
	struct linux_mdesc *p;

#ifdef DEBUG
	int i = 0;

	printk("ARCS MEMORY DESCRIPTOR dump:\n");
	p = ArcGetMemoryDescriptor(PROM_NULL_MDESC);
	while(p) {
		printk("[%d,%p]: base<%08lx> pages<%08lx> type<%s>\n",
		       i, p, p->base, p->pages, mtypes(p->type));
		p = ArcGetMemoryDescriptor(p);
		i++;
	}
#endif

	p = PROM_NULL_MDESC;
	while ((p = ArcGetMemoryDescriptor(p))) {
		unsigned long base, size;
		long type;

		base = p->base << ARC_PAGE_SHIFT;
		size = p->pages << ARC_PAGE_SHIFT;
		type = prom_memtype_classify(p->type);

		add_memory_region(base, size, type);
	}
}
Exemplo n.º 2
0
ARC_STATUS
JnFsAllocateDescriptor(
    IN ULONG MemoryType,
    IN ULONG PageCount,
    OUT PULONG ActualBase
    )
/*++

Routine Description:


    This attempts to find a free section of memory of the requested size
    and type.  It does *not* update the memory descriptor list to reflect a
    successful allocation.

Arguments:

    MemoryType		The type of memory requested.

    PageCount		The number of pages requested.

    ActualBase		A pointer to a variable that receives the base
    			page number of the found section.

Return Value:

    ESUCCESS is returned if the memory descriptor is found.
    ENOMEM if not.
--*/

{

    PMEMORY_DESCRIPTOR MemoryDescriptor;
    ULONG MemoryBase;
    ARC_STATUS ReturnStatus = ENOMEM;
    
    //
    // Find a memory descriptor of the right size
    //

    MemoryDescriptor = ArcGetMemoryDescriptor(NULL);

    while (MemoryDescriptor != NULL) {
	if ((MemoryDescriptor->MemoryType == MemoryType) &&
	    (MemoryDescriptor->PageCount >= PageCount)) {
	    MemoryBase = MemoryDescriptor->BasePage;
	    ReturnStatus = ESUCCESS;
	    break;
	}
	MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor);
    }

    *ActualBase = MemoryBase;

    return ReturnStatus;
}
Exemplo n.º 3
0
BOOLEAN MmInitializeMemoryManager(VOID)
{
#if DBG
    const FREELDR_MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
#endif

    TRACE("Initializing Memory Manager.\n");

    /* Check the freeldr binary */
    MmCheckFreeldrImageFile();

    BiosMemoryMap = MachVtbl.GetMemoryMap(&BiosMemoryMapEntryCount);

#if DBG
    // Dump the system memory map
    TRACE("System Memory Map (Base Address, Length, Type):\n");
    while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
    {
        TRACE("%x\t %x\t %s\n",
            MemoryDescriptor->BasePage * MM_PAGE_SIZE,
            MemoryDescriptor->PageCount * MM_PAGE_SIZE,
            MmGetSystemMemoryMapTypeString(MemoryDescriptor->MemoryType));
    }
#endif

    // Find address for the page lookup table
    TotalPagesInLookupTable = MmGetAddressablePageCountIncludingHoles();
    PageLookupTableAddress = MmFindLocationForPageLookupTable(TotalPagesInLookupTable);
    LastFreePageHint = MmHighestPhysicalPage;

    if (PageLookupTableAddress == 0)
    {
        // If we get here then we probably couldn't
        // find a contiguous chunk of memory big
        // enough to hold the page lookup table
        printf("Error initializing memory manager!\n");
        return FALSE;
    }

    // Initialize the page lookup table
    MmInitPageLookupTable(PageLookupTableAddress, TotalPagesInLookupTable);

    MmUpdateLastFreePageHint(PageLookupTableAddress, TotalPagesInLookupTable);

    FreePagesInLookupTable = MmCountFreePagesInLookupTable(PageLookupTableAddress,
                                                        TotalPagesInLookupTable);

    MmInitializeHeap(PageLookupTableAddress);

    TRACE("Memory Manager initialized. 0x%x pages available.\n", FreePagesInLookupTable);


    return TRUE;
}
Exemplo n.º 4
0
VOID MmInitPageLookupTable(PVOID PageLookupTable, PFN_NUMBER TotalPageCount)
{
    const FREELDR_MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
    PFN_NUMBER PageLookupTableStartPage;
    PFN_NUMBER PageLookupTablePageCount;

    TRACE("MmInitPageLookupTable()\n");

    // Mark every page as allocated initially
    // We will go through and mark pages again according to the memory map
    // But this will mark any holes not described in the map as allocated
    MmMarkPagesInLookupTable(PageLookupTable, MmLowestPhysicalPage, TotalPageCount, LoaderFirmwarePermanent);

    // Parse the whole memory map
    while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
    {
        // Mark used pages in the lookup table

        if (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount <= TotalPageCount)
        {
            TRACE("Marking pages 0x%lx-0x%lx as type %s\n",
                  MemoryDescriptor->BasePage,
                  MemoryDescriptor->BasePage + MemoryDescriptor->PageCount,
                  MmGetSystemMemoryMapTypeString(MemoryDescriptor->MemoryType));
            MmMarkPagesInLookupTable(PageLookupTable,
                                     MemoryDescriptor->BasePage,
                                     MemoryDescriptor->PageCount,
                                     MemoryDescriptor->MemoryType);
        }
        else
            TRACE("Ignoring pages 0x%lx-0x%lx (%s)\n",
                  MemoryDescriptor->BasePage,
                  MemoryDescriptor->BasePage + MemoryDescriptor->PageCount,
                  MmGetSystemMemoryMapTypeString(MemoryDescriptor->MemoryType));
    }

    // Mark the pages that the lookup table occupies as reserved
    PageLookupTableStartPage = MmGetPageNumberFromAddress(PageLookupTable);
    PageLookupTablePageCount = MmGetPageNumberFromAddress((PVOID)((ULONG_PTR)PageLookupTable + ROUND_UP(TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM), MM_PAGE_SIZE))) - PageLookupTableStartPage;
    TRACE("Marking the page lookup table pages as reserved StartPage: 0x%x PageCount: 0x%x\n", PageLookupTableStartPage, PageLookupTablePageCount);
    MmMarkPagesInLookupTable(PageLookupTable, PageLookupTableStartPage, PageLookupTablePageCount, LoaderFirmwareTemporary);
}
Exemplo n.º 5
0
PFN_NUMBER MmGetAddressablePageCountIncludingHoles(VOID)
{
    const FREELDR_MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
    PFN_NUMBER PageCount;

    //
    // Go through the whole memory map to get max address
    //
    while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
    {
        //
        // Check if we got a higher end page address
        //
        if (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount > MmHighestPhysicalPage)
        {
            //
            // Yes, remember it if this is real memory
            //
            if (MemoryDescriptor->MemoryType == LoaderFree)
                MmHighestPhysicalPage = MemoryDescriptor->BasePage + MemoryDescriptor->PageCount;
        }

        //
        // Check if we got a higher (usable) start page address
        //
        if (MemoryDescriptor->BasePage < MmLowestPhysicalPage)
        {
            //
            // Yes, remember it if this is real memory
            //
            MmLowestPhysicalPage = MemoryDescriptor->BasePage;
        }
    }

    TRACE("lo/hi %lx %lx\n", MmLowestPhysicalPage, MmHighestPhysicalPage);
    PageCount = MmHighestPhysicalPage - MmLowestPhysicalPage;
    TRACE("MmGetAddressablePageCountIncludingHoles() returning 0x%x\n", PageCount);
    return PageCount;
}
Exemplo n.º 6
0
PVOID MmFindLocationForPageLookupTable(PFN_NUMBER TotalPageCount)
{
    const FREELDR_MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
    SIZE_T PageLookupTableSize;
    PFN_NUMBER PageLookupTablePages;
    PFN_NUMBER PageLookupTableStartPage = 0;
    PVOID PageLookupTableMemAddress = NULL;

    // Calculate how much pages we need to keep the page lookup table
    PageLookupTableSize = TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM);
    PageLookupTablePages = PageLookupTableSize / MM_PAGE_SIZE;

    // Search the highest memory block big enough to contain lookup table
    while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
    {
        // Continue, if memory is not free
        if (MemoryDescriptor->MemoryType != LoaderFree) continue;

        // Continue, if the block is not big enough?
        if (MemoryDescriptor->PageCount < PageLookupTablePages) continue;

        // Continue, if it is not at a higher address than previous address
        if (MemoryDescriptor->BasePage < PageLookupTableStartPage) continue;

        // Continue, if the address is too high
        if (MemoryDescriptor->BasePage >= MM_MAX_PAGE) continue;

        // Memory block is more suitable than the previous one
        PageLookupTableStartPage = MemoryDescriptor->BasePage;
        PageLookupTableMemAddress = (PVOID)((ULONG_PTR)
            (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount) * MM_PAGE_SIZE
            - PageLookupTableSize);
    }

    TRACE("MmFindLocationForPageLookupTable() returning 0x%x\n", PageLookupTableMemAddress);

    return PageLookupTableMemAddress;
}
Exemplo n.º 7
0
VOID MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount)
{
    const MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
    TYPE_OF_MEMORY MemoryMapPageAllocated;
    ULONG PageLookupTableStartPage;
    ULONG PageLookupTablePageCount;

    TRACE("MmInitPageLookupTable()\n");

    //
    // Mark every page as allocated initially
    // We will go through and mark pages again according to the memory map
    // But this will mark any holes not described in the map as allocated
    //
    MmMarkPagesInLookupTable(PageLookupTable, MmLowestPhysicalPage, TotalPageCount, LoaderFirmwarePermanent);

    //
    // Parse the whole memory map
    //
    while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
    {
        //
        // Convert ARC memory type to loader memory type
        //
        switch (MemoryDescriptor->MemoryType)
        {
            case MemoryFree:
            {
                //
                // Allocatable memory
                //
                MemoryMapPageAllocated = LoaderFree;
                break;
            }
            case MemoryFirmwarePermanent:
            {
                //
                // Firmware permanent memory
                //
                MemoryMapPageAllocated = LoaderFirmwarePermanent;
                break;
            }
            case MemoryFirmwareTemporary:
            {
                //
                // Firmware temporary memory
                //
                MemoryMapPageAllocated = LoaderFirmwareTemporary;
                break;
            }
            case MemoryLoadedProgram:
            {
                //
                // Bootloader code
                //
                MemoryMapPageAllocated = LoaderLoadedProgram;
                break;
            }
            case MemorySpecialMemory:
            {
                //
                // OS Loader Stack
                //
                MemoryMapPageAllocated = LoaderOsloaderStack;
                break;
            }
            default:
            {
                //
                // Put something sensible here, which won't be overwritten
                //
                MemoryMapPageAllocated = LoaderSpecialMemory;
                break;
            }
        }

        //
        // Mark used pages in the lookup table
        //
        TRACE("Marking pages as type %d: StartPage: %d PageCount: %d\n", MemoryMapPageAllocated, MemoryDescriptor->BasePage, MemoryDescriptor->PageCount);
        MmMarkPagesInLookupTable(PageLookupTable, MemoryDescriptor->BasePage, MemoryDescriptor->PageCount, MemoryMapPageAllocated);
    }

    //
    // Mark the pages that the lookup table occupies as reserved
    //
    PageLookupTableStartPage = MmGetPageNumberFromAddress(PageLookupTable);
    PageLookupTablePageCount = MmGetPageNumberFromAddress((PVOID)((ULONG_PTR)PageLookupTable + ROUND_UP(TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM), MM_PAGE_SIZE))) - PageLookupTableStartPage;
    TRACE("Marking the page lookup table pages as reserved StartPage: %d PageCount: %d\n", PageLookupTableStartPage, PageLookupTablePageCount);
    MmMarkPagesInLookupTable(PageLookupTable, PageLookupTableStartPage, PageLookupTablePageCount, LoaderFirmwareTemporary);
}
Exemplo n.º 8
0
PVOID MmFindLocationForPageLookupTable(ULONG TotalPageCount)
{
    const MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
    ULONG PageLookupTableSize;
    ULONG PageLookupTablePages;
    ULONG PageLookupTableStartPage = 0;
    PVOID PageLookupTableMemAddress = NULL;

    //
    // Calculate how much pages we need to keep the page lookup table
    //
    PageLookupTableSize = TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM);
    PageLookupTablePages = PageLookupTableSize / MM_PAGE_SIZE;

    //
    // Search the highest memory block big enough to contain lookup table
    //
    while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
    {
        //
        // Is it suitable memory?
        //
        if (MemoryDescriptor->MemoryType != MemoryFree)
        {
            //
            // No. Process next descriptor
            //
            continue;
        }

        //
        // Is the block big enough?
        //
        if (MemoryDescriptor->PageCount < PageLookupTablePages)
        {
            //
            // No. Process next descriptor
            //
            continue;
        }

        //
        // Is it at a higher address than previous suitable address?
        //
        if (MemoryDescriptor->BasePage < PageLookupTableStartPage)
        {
            //
            // No. Process next descriptor
            //
            continue;
        }

        //
        // Can we use this address?
        //
        if (MemoryDescriptor->BasePage >= MM_MAX_PAGE)
        {
            //
            // No. Process next descriptor
            //
            continue;
        }

        //
        // Memory block is more suitable than the previous one
        //
        PageLookupTableStartPage = MemoryDescriptor->BasePage;
        PageLookupTableMemAddress = (PVOID)((ULONG_PTR)
            (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount) * MM_PAGE_SIZE
            - PageLookupTableSize);
    }

    TRACE("MmFindLocationForPageLookupTable() returning 0x%x\n", PageLookupTableMemAddress);

    return PageLookupTableMemAddress;
}
Exemplo n.º 9
0
ARC_STATUS
AlMemoryInitialize (
    ULONG StackPages,
    ULONG HeapPages
    )

/*++

Routine Description:

    This routine allocates stack space for the OS loader, initializes
    heap storage, and initializes the memory allocation list.

Arguments:

    None.

Return Value:

    ESUCCESS is returned if the initialization is successful. Otherwise,
    ENOMEM is returned.

--*/

{

    PMEMORY_DESCRIPTOR FreeDescriptor;
    PMEMORY_DESCRIPTOR ProgramDescriptor;

    //
    // Find the memory descriptor that describes the allocation for the OS
    // loader itself.
    //

    ProgramDescriptor = NULL;
    while ((ProgramDescriptor = ArcGetMemoryDescriptor(ProgramDescriptor)) != NULL) {
        if (ProgramDescriptor->MemoryType == MemoryLoadedProgram) {
            break;
        }
    }

    //
    // If a loaded program memory descriptor was found, then it must be
    // for the OS loader since that is the only program that can be loaded.
    // If a loaded program memory descriptor was not found, then firmware
    // is not functioning properly and an unsuccessful status is returned.
    //

    if (ProgramDescriptor == NULL) {
        return ENOMEM;
    }

    //
    // Find the free memory descriptor that is just below the loaded
    // program in memory. There should be several megabytes of free
    // memory just preceeding the OS loader.
    //

    FreeDescriptor = NULL;
    while ((FreeDescriptor = ArcGetMemoryDescriptor(FreeDescriptor)) != NULL) {
        if ((FreeDescriptor->MemoryType == MemoryFree) &&
            (FreeDescriptor->PageCount >= (StackPages+HeapPages))) {
            break;
        }
    }

    //
    // If a free memory descriptor was not found that describes the free
    // memory just below the OS loader, then firmware is not functioning
    // properly and an unsuccessful status is returned.
    //

    if (FreeDescriptor == NULL) {
        return ENOMEM;
    }

    //
    // Check to determine if enough free memory is available for the OS
    // loader stack and the heap area. If enough memory is not available,
    // then return an unsuccessful status.
    //

    if (FreeDescriptor->PageCount < (StackPages + HeapPages)) {
        return ENOMEM;
    }

    //
    // Compute the address of the loader heap, initialize the heap
    // allocation variables, and zero the heap memory.
    //

    AlHeapFree = KSEG0_BASE | ((ProgramDescriptor->BasePage -
                (StackPages + HeapPages)) << PAGE_SHIFT);

    AlHeapLimit = AlHeapFree + (HeapPages << PAGE_SHIFT);

    memset((PVOID)AlHeapFree, 0,HeapPages << PAGE_SHIFT);


    //
    // Changed to new heap allocater
    //

    if ((HeapHandle = AlRtCreateHeap
            (
            HEAP_ZERO_EXTRA_MEMORY,
            (PVOID)AlHeapFree,
            HeapPages << PAGE_SHIFT
            ))
            == NULL)
       return ENOMEM;
    else
       return ESUCCESS;

}