Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

504 lines
14 KiB

/*++
Copyright (c) 1991 - 2001 Microsoft Corporation
Module Name:
### ## # ## ##### #### ### ##### #### ##### #####
## # ## ### ## ## ## ## ## # ## ## ## # ## ## ## ##
### ## ### ## ## ## ## ### ## ## ## ## ## ## ##
### ## # # ## ## ## ## ### ## ## ## ## ## ## ##
### ### ### ## ## ## ### ##### ## ##### #####
# ## ### ### ## ## ## # ## ## ## ## # ## ##
### ## ## ##### #### ### ## ## #### ## ##
Abstract:
This module contains the entire implementation of
the local display miniport for the ServerWorks
CSB5 server chip set.
Author:
Wesley Witt (wesw) 1-Oct-2001
Environment:
Kernel mode only.
Notes:
--*/
#include "swdisp.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT,DriverEntry)
#endif
NTSTATUS
SaDispHwInitialize(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID DeviceExtensionIn,
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResources,
IN ULONG PartialResourceCount
)
/*++
Routine Description:
This routine is the driver's entry point, called by the I/O system
to load the driver. The driver's entry points are initialized and
a mutex to control paging is initialized.
In DBG mode, this routine also examines the registry for special
debug parameters.
Arguments:
DeviceObject - Miniport's device object
Irp - Current IRP in progress
DeviceExtensionIn - Miniport's device extension
PartialResources - List of resources that are assigned to the miniport
PartialResourceCount - Number of assigned resources
Return Value:
NT status code
--*/
{
ULONG i;
PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION) DeviceExtensionIn;
PCM_PARTIAL_RESOURCE_DESCRIPTOR Resource = NULL;
for (i=0; i<PartialResourceCount; i++) {
if (PartialResources[i].Type == CmResourceTypeMemory) {
Resource = &PartialResources[i];
break;
}
}
if (Resource == NULL) {
REPORT_ERROR( SA_DEVICE_DISPLAY, "Missing memory resource", STATUS_UNSUCCESSFUL );
return STATUS_UNSUCCESSFUL;
}
DeviceExtension->VideoMemBase = (PUCHAR) SaPortGetVirtualAddress(
DeviceExtension,
Resource->u.Memory.Start,
Resource->u.Memory.Length
);
if (DeviceExtension->VideoMemBase == NULL) {
REPORT_ERROR( SA_DEVICE_DISPLAY, "SaPortGetVirtualAddress failed", STATUS_NO_MEMORY );
return STATUS_NO_MEMORY;
}
return STATUS_SUCCESS;
}
NTSTATUS
SaDispDeviceIoctl(
IN PVOID DeviceExtension,
IN PIRP Irp,
IN PVOID FsContext,
IN ULONG FunctionCode,
IN PVOID InputBuffer,
IN ULONG InputBufferLength,
IN PVOID OutputBuffer,
IN ULONG OutputBufferLength
)
/*++
Routine Description:
This routine processes the device control requests for the
local display miniport.
Arguments:
DeviceExtension - Miniport's device extension
FunctionCode - Device control function code
InputBuffer - Pointer to the user's input buffer
InputBufferLength - Length in bytes of the input buffer
OutputBuffer - Pointer to the user's output buffer
OutputBufferLength - Length in bytes of the output buffer
Return Value:
NT status code.
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
PSA_DISPLAY_CAPS DeviceCaps;
switch (FunctionCode) {
case FUNC_SA_GET_VERSION:
*((PULONG)OutputBuffer) = SA_INTERFACE_VERSION;
break;
case FUNC_SA_GET_CAPABILITIES:
DeviceCaps = (PSA_DISPLAY_CAPS)OutputBuffer;
DeviceCaps->SizeOfStruct = sizeof(SA_DISPLAY_CAPS);
DeviceCaps->DisplayType = SA_DISPLAY_TYPE_BIT_MAPPED_LCD;
DeviceCaps->CharacterSet = SA_DISPLAY_CHAR_ASCII;
DeviceCaps->DisplayHeight = DISPLAY_HEIGHT;
DeviceCaps->DisplayWidth = DISPLAY_WIDTH;
break;
default:
Status = STATUS_NOT_SUPPORTED;
REPORT_ERROR( SA_DEVICE_DISPLAY, "Unsupported device control", Status );
break;
}
return Status;
}
UCHAR TestMask[128] =
{
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01
};
ULONG
TransformBitmap(
PUCHAR Bits,
ULONG Width,
ULONG Height,
PUCHAR NewBits
)
/*++
Routine Description:
The TransformBitmap() function morphs the input bitmap from a
normal bitmap that has it's pixel bits organized as sequential
bits starting from coord (0,0) through (n,n). The bits are
in a stream that proceed from column to column and row to row.
The transformation accomplished by this function changes the bitmap
into one that has it's bits organized in pages, lines, and columns.
Each page is a unit of 8 lines and is organized as follows:
---------------------------------------------------------
|Columns
---------------------------------------------------------
| 1| 2| 3| 4| 5| 6| 7| 8| 9|10|11|12|13|14|15|16| ...128
---------------------------------------------------------
Line #1 | | | | | | | | | | | | | | | | | ...
|--------------------------------------------------------
Line #2 | | | | | | | | | | | | | | | | | ...
|--------------------------------------------------------
Line #3 | | | | | | | | | | | | | | | | | ...
|--------------------------------------------------------
Line #4 | | | | | | | | | | | | | | | | | ...
|--------------------------------------------------------
Line #5 | | | | | | | | | | | | | | | | | ...
|--------------------------------------------------------
Line #6 | | | | | | | | | | | | | | | | | ...
|--------------------------------------------------------
Line #7 | | | | | | | | | | | | | | | | | ...
|--------------------------------------------------------
Line #8 | | | | | | | | | | | | | | | | | ...
|--------------------------------------------------------
The bytes that comprise the bitmap correspond to the columns in the
page, so there are 128 bytes per page. If the first byte of the
transformed bitmap is 0x46 then the pixels in column 1 of lines 2,6,&7
are illuminated by the display.
Arguments:
Bits - Input bits that are to be transformed
Width - Width of the bitmap in pixels
Height - Height of the bitmap in pixels
NewBits - Buffer to hold the newly transformed bitmap
Return Value:
NT status code.
--*/
{
ULONG i,j,k,line,idx,mask,coli;
UCHAR byte;
ULONG padBytes;
ULONG byteWidth;
ULONG NewSize = 0;
//
// Compute the pad bytes. It is assumed
// that the data width of the input bitmap
// is dword aliged long.
//
if (((Width % 32) == 0) || ((Width % 32) > 24)) {
padBytes = 0;
} else if ((Width % 32) <= 8) {
padBytes = 3;
} else if ((Width % 32) <= 16) {
padBytes = 2;
} else {
padBytes = 1;
}
//
// Compute the realy byte width
// based on the pad bytes.
//
byteWidth = (Width / 8) + padBytes;
if (Width % 8) {
byteWidth += 1;
}
//
// Loop through the input bitmap and
// create a new, morphed bitmap.
//
for (i=0; i<DISPLAY_PAGES; i++) {
//
// starting line number for this page
//
line = i * DISPLAY_LINES_PER_PAGE;
//
// This handles the case where the
// input bitmap is not as tall as the display.
//
if (line >= Height) {
break;
}
//
// loop over the bits for this column
//
for (j=0; j<Width; j++) {
//
// Reset the new byte value to a zero state
//
byte = 0;
//
// Compute the column index as the
// current column number divided by 8 (width of a byte)
//
coli = j >> 3;
//
// Compute the mask that is used to test the
// bit in the input bitmap.
//
mask = TestMask[j];
//
// Process the bits in all this pages's lines
// for the current column.
//
for (k=0; k<DISPLAY_LINES_PER_PAGE; k++) {
if ((k + line) >= Height) {
break;
}
//
// index the byte that contains this pixel
//
idx = (((k + line) * byteWidth)) + coli;
//
// set the bit
//
if (Bits[idx] & mask) {
byte = byte | (1 << k);
}
}
//
// Save the new byte in the bitmap
//
*NewBits = byte;
NewBits += 1;
NewSize += 1;
}
}
return NewSize;
}
NTSTATUS
SaDispWrite(
IN PVOID DeviceExtensionIn,
IN PIRP Irp,
IN PVOID FsContext,
IN LONGLONG StartingOffset,
IN PVOID DataBuffer,
IN ULONG DataBufferLength
)
/*++
Routine Description:
This routine processes the write request for the local display miniport.
Arguments:
DeviceExtensionIn - Miniport's device extension
StartingOffset - Starting offset for the I/O
DataBuffer - Pointer to the data buffer
DataBufferLength - Length of the data buffer in bytes
Return Value:
NT status code.
--*/
{
NTSTATUS Status;
PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION) DeviceExtensionIn;
PSA_DISPLAY_SHOW_MESSAGE SaDisplay = (PSA_DISPLAY_SHOW_MESSAGE)DataBuffer;
UCHAR i,j;
PUCHAR NewBits = NULL;
PUCHAR byte;
ULONG Pages;
ULONG NewSize;
UNREFERENCED_PARAMETER(StartingOffset);
if (SaDisplay->Width > DISPLAY_WIDTH || SaDisplay->Height > DISPLAY_HEIGHT) {
REPORT_ERROR( SA_DEVICE_DISPLAY, "Bitmap size is too large\n", STATUS_INVALID_PARAMETER );
return STATUS_INVALID_PARAMETER;
}
NewBits = (PUCHAR) SaPortAllocatePool( DeviceExtension, MAX_BITMAP_SIZE );
if (NewBits == NULL) {
REPORT_ERROR( SA_DEVICE_DISPLAY, "Failed to allocate pool\n", MAX_BITMAP_SIZE );
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory( NewBits, MAX_BITMAP_SIZE );
NewSize = TransformBitmap(
SaDisplay->Bits,
SaDisplay->Width,
SaDisplay->Height,
NewBits
);
if (NewSize == 0) {
SaPortFreePool( DeviceExtension, NewBits );
REPORT_ERROR( SA_DEVICE_DISPLAY, "Failed to transform the bitmap\n", STATUS_UNSUCCESSFUL );
return STATUS_UNSUCCESSFUL;
}
Pages = SaDisplay->Height / DISPLAY_LINES_PER_PAGE;
if (SaDisplay->Height % DISPLAY_LINES_PER_PAGE) {
Pages += 1;
}
for (i=0,byte=NewBits; i<Pages; i++) {
SetDisplayPage( DeviceExtension->VideoMemBase, i );
for (j=0; j<SaDisplay->Width; j++) {
SetDisplayColumnAddress( DeviceExtension->VideoMemBase, j );
SetDisplayData( DeviceExtension->VideoMemBase, *byte );
byte += 1;
}
}
SaPortFreePool( DeviceExtension, NewBits );
return STATUS_SUCCESS;
}
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
This routine is the driver's entry point, called by the I/O system
to load the driver. The driver's entry points are initialized and
a mutex to control paging is initialized.
In DBG mode, this routine also examines the registry for special
debug parameters.
Arguments:
DriverObject - a pointer to the object that represents this device
driver.
RegistryPath - a pointer to this driver's key in the Services tree.
Return Value:
STATUS_SUCCESS
--*/
{
NTSTATUS Status;
SAPORT_INITIALIZATION_DATA SaPortInitData;
RtlZeroMemory( &SaPortInitData, sizeof(SAPORT_INITIALIZATION_DATA) );
SaPortInitData.StructSize = sizeof(SAPORT_INITIALIZATION_DATA);
SaPortInitData.DeviceType = SA_DEVICE_DISPLAY;
SaPortInitData.HwInitialize = SaDispHwInitialize;
SaPortInitData.Write = SaDispWrite;
SaPortInitData.DeviceIoctl = SaDispDeviceIoctl;
SaPortInitData.DeviceExtensionSize = sizeof(DEVICE_EXTENSION);
Status = SaPortInitialize( DriverObject, RegistryPath, &SaPortInitData );
if (!NT_SUCCESS(Status)) {
REPORT_ERROR( SA_DEVICE_DISPLAY, "SaPortInitialize failed\n", Status );
return Status;
}
return STATUS_SUCCESS;
}