summaryrefslogblamecommitdiffstats
path: root/private/ntos/boot/lib/bllog.c
blob: ef6efa55e81d46564b510005c1de5579e55809ff (plain) (tree)






























































































































































































































































































                                                                                                   
/*++

Copyright (c) 1995  Microsoft Corporation

Module Name:

    blprint.c

Abstract:

    This module implements the OS loader debug logging routines.

Author:

    Chuck Lenzmeier (chuckl) 2-Nov-1995

Revision History:

--*/

#include "bldr.h"
#include <stdio.h>

#if DBG

ULONG BlLogFileId = (ULONG)-1;
ULONG BlLogActiveTargets = 0;

VOID
BlLogInitialize (
    ULONG LogfileDeviceId
    )
{
    ARC_STATUS Status;

    BlLogActiveTargets = 0;

    if (BlLoaderBlock->LoadOptions != NULL) {

        if (strstr(BlLoaderBlock->LoadOptions,"DBGDISPLAY") != NULL) {
            BlLogActiveTargets |= LOG_DISPLAY;
        }

        if (strstr(BlLoaderBlock->LoadOptions,"DBGLOG") != NULL) {
            Status = BlOpen(LogfileDeviceId, "\\LDRDBG.LOG", ArcSupersedeReadWrite, &BlLogFileId);
            if (Status == 0) {
                BlLogActiveTargets |= LOG_LOGFILE;
            }
        }
    }

    BlLogArcDescriptors(LOG_ALL);
    BlLogMemoryDescriptors(LOG_ALL_W);

    return;
}

VOID
BlLogTerminate (
    VOID
    )
{
    BlLogMemoryDescriptors(LOG_ALL);
    if ((BlLogActiveTargets & LOG_DISPLAY) != 0) {
        BlLogWaitForKeystroke();
    }
    if ((BlLogActiveTargets & LOG_LOGFILE) != 0) {
        BlClose(BlLogFileId);
    }

    BlLogActiveTargets = 0;

    return;
}

VOID
BlLogPrint (
    ULONG Targets,
    PCHAR Format,
    ...
    )
{
    va_list arglist;
    int count;
    UCHAR buffer[79];
    ULONG activeTargets;

    activeTargets = Targets & BlLogActiveTargets;

    if (activeTargets != 0) {

        va_start(arglist, Format);

        count = _vsnprintf(buffer, sizeof(buffer), Format, arglist);
        if (count != -1) {
            RtlFillMemory(&buffer[count], sizeof(buffer)-count-2, ' ');
        }
        count = sizeof(buffer);
        buffer[count-2] = '\r';
        buffer[count-1] = '\n';

        if ((activeTargets & LOG_LOGFILE) != 0) {
            BlWrite(BlLogFileId, buffer, count, &count);
        }

        if ((activeTargets & LOG_DISPLAY) != 0) {
            ArcWrite(ARC_CONSOLE_OUTPUT, buffer, count, &count);
            if ((Targets & LOG_WAIT) != 0) {
                BlLogWaitForKeystroke();
            }
        }
    }

    return;
}

VOID
BlLogArcDescriptors (
    ULONG Targets
    )
{
    PMEMORY_DESCRIPTOR CurrentDescriptor;
    ULONG activeTargets;

    activeTargets = Targets & BlLogActiveTargets;

    if (activeTargets != 0) {

        BlLog((activeTargets,"***** ARC Memory List *****"));

        CurrentDescriptor = NULL;
        while ((CurrentDescriptor = ArcGetMemoryDescriptor(CurrentDescriptor)) != NULL) {
            BlLog((activeTargets,
                   "Descriptor %8x:  Type %8x  Base %8x  Pages %8x",
                   CurrentDescriptor,
                   (USHORT)(CurrentDescriptor->MemoryType),
                   CurrentDescriptor->BasePage,
                   CurrentDescriptor->PageCount));
        }

        //BlLog((activeTargets,"***************************"));

        if (((activeTargets & LOG_DISPLAY) != 0) && ((Targets & LOG_WAIT) != 0)) {
            BlLogWaitForKeystroke();
        }
    }

    return;
}

VOID
BlLogMemoryDescriptors (
    ULONG Targets
    )
{
    PLIST_ENTRY CurrentLink;
    PMEMORY_ALLOCATION_DESCRIPTOR CurrentDescriptor;
    ULONG Index;
    ULONG ExpectedIndex;
    ULONG ExpectedBase;
    ULONG FoundIndex;
    PMEMORY_ALLOCATION_DESCRIPTOR FoundDescriptor;
    TYPE_OF_MEMORY LastType;
    ULONG FreeBlocks = 0;
    ULONG FreePages = 0;
    ULONG LargestFree = 0;

    ULONG activeTargets;

    activeTargets = Targets & BlLogActiveTargets;

    if (activeTargets != 0) {

        BlLog((activeTargets,"***** System Memory List *****"));

        ExpectedIndex = 0;
        ExpectedBase = 0;
        LastType = (ULONG)-1;

        do {
            Index = 0;
            FoundDescriptor = NULL;
            CurrentLink = BlLoaderBlock->MemoryDescriptorListHead.Flink;

            while (CurrentLink != &BlLoaderBlock->MemoryDescriptorListHead) {

                CurrentDescriptor = (PMEMORY_ALLOCATION_DESCRIPTOR)CurrentLink;
                if (CurrentDescriptor->BasePage == ExpectedBase) {
                    if ((FoundDescriptor != NULL) && (FoundDescriptor->BasePage == ExpectedBase)) {
                        BlLog((activeTargets,
                               "ACK! Found multiple descriptors with base %x: %x and %x",
                               ExpectedBase,
                               FoundDescriptor,
                               CurrentDescriptor));
                    } else {
                        FoundDescriptor = CurrentDescriptor;
                        FoundIndex = Index;
                    }
                } else if (CurrentDescriptor->BasePage > ExpectedBase) {
                    if ((FoundDescriptor == NULL) ||
                        (CurrentDescriptor->BasePage < FoundDescriptor->BasePage)) {
                        FoundDescriptor = CurrentDescriptor;
                        FoundIndex = Index;
                    }
                }

                CurrentLink = CurrentLink->Flink;
                Index++;
            }

            if (FoundDescriptor != NULL) {

                if (FoundDescriptor->BasePage != ExpectedBase) {
                    BlLog((activeTargets,
                           "     ACK! MISSING MEMORY! ACK!  Base %8x  Pages %8x",
                           ExpectedBase,
                           FoundDescriptor->BasePage - ExpectedBase));
                }
                BlLog((activeTargets,
                       "%c%c%2d Descriptor %8x:  Type %8x  Base %8x  Pages %8x",
                       FoundDescriptor->MemoryType == LastType ? '^' : ' ',
                       FoundIndex == ExpectedIndex ? ' ' : '*',
                       FoundIndex,
                       FoundDescriptor,
                       (USHORT)(FoundDescriptor->MemoryType),
                       FoundDescriptor->BasePage,
                       FoundDescriptor->PageCount));

                if (FoundIndex == ExpectedIndex) {
                    ExpectedIndex++;
                }
                ExpectedBase = FoundDescriptor->BasePage + FoundDescriptor->PageCount;

                LastType = FoundDescriptor->MemoryType;
                if (LastType != MemoryFree) {
                    LastType = (ULONG)-1;
                } else {
                    FreeBlocks++;
                    FreePages += FoundDescriptor->PageCount;
                    if (FoundDescriptor->PageCount > LargestFree) {
                        LargestFree = FoundDescriptor->PageCount;
                    }
                }
            }

        } while ( FoundDescriptor != NULL );

        BlLog((activeTargets,
               "Total free blocks %2d, free pages %4x, largest free %4x",
               FreeBlocks,
               FreePages,
               LargestFree));

        //BlLog((activeTargets,"******************************"));

        if (((activeTargets & LOG_DISPLAY) != 0) && ((Targets & LOG_WAIT) != 0)) {
            BlLogWaitForKeystroke();
        }
    }

    return;
}

VOID
BlLogWaitForKeystroke (
    VOID
    )
{
    UCHAR Key=0;
    ULONG Count;

    if ((BlLogActiveTargets & LOG_DISPLAY) != 0) {
        do {
            if (ArcGetReadStatus(ARC_CONSOLE_INPUT) == ESUCCESS) {
                ArcRead(ARC_CONSOLE_INPUT,
                        &Key,
                        sizeof(Key),
                        &Count);
                break;
            }
        } while ( TRUE );
    }

    return;
}

#endif // DBG