41 added + 32 removed + 5 modified, total 78 files
reactos
diff -u -r1.266 -r1.267
--- Makefile 1 Dec 2004 16:07:57 -0000 1.266
+++ Makefile 3 Dec 2004 20:10:40 -0000 1.267
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.266 2004/12/01 16:07:57 greatlrd Exp $
+# $Id: Makefile,v 1.267 2004/12/03 20:10:40 gvg Exp $
#
# Global makefile
#
@@ -27,7 +27,7 @@
# Hardware Abstraction Layers
# halx86
-HALS = halx86
+HALS = halx86/up halx86/mp
# Bus drivers
# acpi isapnp pci
reactos/hal/halx86
diff -N .cvsignore
--- .cvsignore 28 Jun 2003 23:10:02 -0000 1.5
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,7 +0,0 @@
-*.d
-*.dll
-*.coff
-*.a
-*.o
-*.sym
-*.map
reactos/hal/halx86
diff -N Makefile
--- Makefile 28 Nov 2004 01:30:01 -0000 1.15
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,101 +0,0 @@
-# $Id: Makefile,v 1.15 2004/11/28 01:30:01 hbirr Exp $
-
-PATH_TO_TOP = ../..
-
-default: all
-
-#
-# Build configuration
-#
-include $(PATH_TO_TOP)/rules.mak
-
-#
-# Global configuration
-#
-include $(TOOLS_PATH)/config.mk
-
-TARGET_BOOTSTRAP = yes
-
-TARGET_TYPE = hal
-
-TARGET_BASENAME = hal
-
-TARGET_DEFNAME = ../hal/hal
-
-TARGET_ASFLAGS = -I$(PATH_TO_TOP)/include -I$(PATH_TO_TOP)/ntoskrnl/include -D__ASM__
-
-TARGET_CFLAGS = -I./include -I$(PATH_TO_TOP)/ntoskrnl/include -Wall -Werror
-
-# require os code to explicitly request A/W version of structs/functions
-TARGET_CFLAGS += -D_DISABLE_TIDENTS
-
-
-TARGET_NAME_UP = halx86up
-
-TARGET_NAME_MP = halx86mp
-
-ifeq ($(MP), 1)
-TARGET_NAME = $(TARGET_NAME_MP)
-else
-TARGET_NAME = $(TARGET_NAME_UP)
-endif
-
-HAL_OBJECTS = \
- adapter.o \
- beep.o \
- bus.o \
- display.o \
- dma.o \
- drive.o \
- enum.o \
- fmutex.o \
- halinit.o \
- isa.o \
- kdbg.o \
- mca.o \
- misc.o \
- mp.o \
- pci.o \
- portio.o \
- reboot.o \
- spinlock.o \
- sysbus.o \
- sysinfo.o \
- time.o \
- timer.o
-
- #pwroff.o
-
-HAL_UP = \
- $(HAL_OBJECTS) \
- irql.o
-
-HAL_MP = \
- $(HAL_OBJECTS) \
- apic.o \
- mpsirql.o \
- mpsboot.o \
- mps.o
-
-ifeq ($(MP), 1)
-DEP_OBJECTS := $(HAL_MP)
-else
-DEP_OBJECTS := $(HAL_UP)
-endif
-
-TARGET_OBJECTS := $(DEP_OBJECTS) $(PATH_TO_TOP)/include/roscfg.h
-
-# Note: Must be = and not := since $(DEP_FILES) is assigned a value below
-TARGET_CLEAN = $(DEP_FILES) *.o *.dll
-
-#
-# Helper makefile
-#
-include $(TOOLS_PATH)/helper.mk
-
-#
-# Include automatic dependancy tracking
-#
-include $(TOOLS_PATH)/depend.mk
-
-# EOF
reactos/hal/halx86
diff -N adapter.c
--- adapter.c 24 Nov 2004 17:54:38 -0000 1.14
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,679 +0,0 @@
-/* $Id: adapter.c,v 1.14 2004/11/24 17:54:38 navaraf Exp $
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: hal/x86/adapter.c (from ntoskrnl/io/adapter.c)
- * PURPOSE: DMA handling
- * PROGRAMMERS: David Welch (welch@mcmail.com)
- * Vizzini (vizzini@plasmic.com)
- * UPDATE HISTORY:
- * Created 22/05/98
- * 18-Oct-2003 Vizzini DMA support modifications
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ddk/ntddk.h>
-#include <ddk/iotypes.h>
-#define NDEBUG
-#include <internal/debug.h>
-#include <hal.h>
-
-/* FUNCTIONS *****************************************************************/
-
-/* NOTE: IoAllocateAdapterChannel in NTOSKRNL.EXE */
-
-
-NTSTATUS STDCALL
-HalAllocateAdapterChannel(
- PADAPTER_OBJECT AdapterObject,
- PWAIT_CONTEXT_BLOCK WaitContextBlock,
- ULONG NumberOfMapRegisters,
- PDRIVER_CONTROL ExecutionRoutine)
-/*
- * FUNCTION: Sets up an ADAPTER_OBJECT with map registers
- * ARGUMENTS:
- * - AdapterObject: pointer to an ADAPTER_OBJECT to set up
- * - WaitContextBlock: Context block to be used with ExecutionRoutine
- * - NumberOfMapRegisters: number of map registers requested
- * - ExecutionRoutine: callback to call when map registers are allocated
- * RETURNS:
- * STATUS_INSUFFICIENT_RESOURCES if map registers cannot be allocated
- * STATUS_SUCCESS in all other cases, including if the callbacak had
- * to be queued for later delivery
- * NOTES:
- * - the ADAPTER_OBJECT struct is undocumented; please make copious
- * notes in hal.h if anything is changed or improved since there is
- * no other documentation for this data structure
- * BUGS:
- * - it's possible that some of this code is in the wrong place
- * - there are many unhandled cases
- */
-{
- LARGE_INTEGER MinAddress;
- LARGE_INTEGER MaxAddress;
- LARGE_INTEGER BoundryAddressMultiple;
- IO_ALLOCATION_ACTION Retval;
-
- ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
-
- /*
- FIXME: return STATUS_INSUFFICIENT_RESOURCES if the NumberOfMapRegisters
- requested is larger than the value returned by IoGetDmaAdapter.
- */
-
- /* set up the wait context block in case we can't run right away */
- WaitContextBlock->DeviceRoutine = ExecutionRoutine;
- WaitContextBlock->NumberOfMapRegisters = NumberOfMapRegisters;
-
- /* returns true if queued, else returns false and sets the queue to busy */
- if(KeInsertDeviceQueue(&AdapterObject->ChannelWaitQueue, &WaitContextBlock->WaitQueueEntry))
- return STATUS_SUCCESS;
-
- /* 24-bit max address due to 16-bit dma controllers */
- MinAddress.QuadPart = 0x0000000;
- MaxAddress.QuadPart = 0x1000000;
- BoundryAddressMultiple.QuadPart = 0;
-
- /* why 64K alignment? */
- /*
- * X86 lacks map registers, so for now, we allocate a contiguous
- * block of physical memory <16MB and copy all DMA buffers into
- * that. This can be optimized.
- *
- * FIXME: We propably shouldn't allocate the memory here for common
- * buffer transfers. See a comment in IoMapTransfer about common buffer
- * support.
- */
- AdapterObject->MapRegisterBase = MmAllocateContiguousAlignedMemory(
- NumberOfMapRegisters * PAGE_SIZE,
- MinAddress,
- MaxAddress,
- BoundryAddressMultiple,
- MmCached,
- 0x10000 );
-
- if(!AdapterObject->MapRegisterBase)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- AdapterObject->CommittedMapRegisters = NumberOfMapRegisters;
-
- /* call the client's AdapterControl callback with its map registers and context */
- Retval = ExecutionRoutine(WaitContextBlock->DeviceObject, WaitContextBlock->CurrentIrp,
- AdapterObject->MapRegisterBase, WaitContextBlock->DeviceContext);
-
- /*
- * KeepObject: don't free any resources; the ADAPTER_OBJECT is still in use
- * and the caller will call IoFreeAdapterChannel later
- *
- * DeallocateObject: Deallocate the map registers and release the ADAPTER_OBJECT
- * so someone else can use it
- *
- * DeallocateObjectKeepRegisters: release the ADAPTER_OBJECT but hang on to
- * the map registers. The client will later call IoFreeMapRegisters.
- *
- * NOTE - IoFreeAdapterChannel runs the queue, so it must be called
- * unless the adapter object is not to be freed.
- */
- if( Retval == DeallocateObject )
- IoFreeAdapterChannel(AdapterObject);
- else if(Retval == DeallocateObjectKeepRegisters)
- {
- /* don't free the allocated map registers - this is what IoFreeAdapterChannel checks */
- AdapterObject->CommittedMapRegisters = 0;
- IoFreeAdapterChannel(AdapterObject);
- }
-
- /*
- * if we don't call IoFreeAdapterChannel, the next device won't get de-queued,
- * which is what we want.
- */
-
- return STATUS_SUCCESS;
-}
-
-
-BOOLEAN
-HalpGrowMapBuffers(
- IN PADAPTER_OBJECT AdapterObject,
- IN ULONG SizeOfMapBuffers)
-/*
- * FUNCTION: Allocate initial, or additional, map buffers for IO adapters.
- * ARGUMENTS:
- * AdapterObject: DMA adapter to allocate buffers for.
- * SizeOfMapBuffers: Size of the map buffers to allocate
- * NOTES:
- * - Needs to be tested...
- */
-{
- //ULONG PagesToAllocate = BYTES_TO_PAGES(SizeOfMapBuffers);
-
- /* TODO: Allocation */
-
- return TRUE;
-}
-
-PADAPTER_OBJECT STDCALL
-HalpAllocateAdapterEx(
- ULONG NumberOfMapRegisters,
- BOOLEAN IsMaster,
- BOOLEAN Dma32BitAddresses)
-/*
- * FUNCTION: Allocates an ADAPTER_OBJECT, optionally creates the Master Adapter.
- * ARGUMENTS:
- * - NumberOfMapRegisters: Number of map registers to allocate
- * - IsMaster: Wether this is a Master Device or not
- * - Dma32BitAddresses: Wether 32-bit Addresses are supported
- * RETURNS:
- * - Pointer to Adapter Object, or NULL if failure.
- * BUGS:
- * - Some stuff is unhandled/incomplete
- */
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- ULONG ObjectSize;
- ULONG BitmapSize;
- NTSTATUS Status;
- ULONG AllowedMapRegisters = 64;
- PADAPTER_OBJECT AdapterObject;
- HANDLE Handle;
-
- /* Allocate the Master Adapter if we haven't already
- but make sure we're not asked to do it now, and also check if we need it */
- if ((MasterAdapter == NULL) && (!IsMaster) && (NumberOfMapRegisters)) {
-
- /* Allocate and Save */
- DPRINT("Allocating the Master Adapter Object\n");
- MasterAdapter = HalpAllocateAdapterEx(NumberOfMapRegisters,
- TRUE,
- Dma32BitAddresses);
-
- /* Cancel on Failure */
- DPRINT("Checking if Master Adapter was allocated properly\n");
- if (!MasterAdapter) return NULL;
- }
-
- /* Initialize the Object Attributes for the Adapter Object */
- InitializeObjectAttributes(&ObjectAttributes,
- NULL,
- OBJ_PERMANENT,
- NULL,
- NULL);
-
- /* Check if this is the Master Adapter, in which case we need to allocate the bitmap */
- if (IsMaster) {
- /* Size due to the Bitmap + Bytes in the Bitmap Buffer (8 bytes, 64 bits)*/
- BitmapSize = sizeof(RTL_BITMAP) + AllowedMapRegisters / 8;
-
- /* We will put the Bitmap Buffer after the Adapter Object for simplicity */
- ObjectSize = sizeof(ADAPTER_OBJECT) + BitmapSize;
- } else {
- ObjectSize = sizeof(ADAPTER_OBJECT);
- }
-
- /* Create and Allocate the Object */
- DPRINT("Creating the Object\n");
- Status = ObCreateObject(KernelMode,
- IoAdapterObjectType,
- &ObjectAttributes,
- KernelMode,
- NULL,
- ObjectSize,
- 0,
- 0,
- (PVOID)&AdapterObject);
-
- if (!NT_SUCCESS(Status)) return NULL;
-
- /* Add a Reference */
- DPRINT("Referencing the Object\n");
- Status = ObReferenceObjectByPointer(AdapterObject,
- FILE_READ_DATA | FILE_WRITE_DATA,
- IoAdapterObjectType,
- KernelMode);
-
- if (!NT_SUCCESS(Status)) return NULL;
-
- /* It's a Valid Object, so now we can play with the memory */
- RtlZeroMemory(AdapterObject, sizeof(ADAPTER_OBJECT));
-
- /* Insert it into the Object Table */
- DPRINT("Inserting the Object\n");
- Status = ObInsertObject(AdapterObject,
- NULL,
- FILE_READ_DATA | FILE_WRITE_DATA,
- 0,
- NULL,
- &Handle);
-
- if (!NT_SUCCESS(Status)) return NULL;
-
- /* We don't want the handle */
- NtClose(Handle);
-
- /* Set up the Adapter Object fields */
- AdapterObject->MapRegistersPerChannel = 1;
-
- /* Set the Master if needed (master only needed if we use Map Registers) */
- if (NumberOfMapRegisters) AdapterObject->MasterAdapter = MasterAdapter;
-
- /* Initalize the Channel Wait queue, which every adapter has */
- DPRINT("Initializing the Device Queue of the Object\n");
- KeInitializeDeviceQueue(&AdapterObject->ChannelWaitQueue);
-
- /* Initialize the SpinLock, Queue and Bitmap, which are kept in the Master Adapter only */
- if (IsMaster) {
-
- DPRINT("Initializing the Master Adapter Stuff\n");
- KeInitializeSpinLock(&AdapterObject->SpinLock);
- InitializeListHead(&AdapterObject->AdapterQueue);
-
- /* As said previously, we put them here for simplicity */
- AdapterObject->MapRegisters = (PVOID)(AdapterObject + 1);
-
- /* Set up Bitmap */
- RtlInitializeBitMap(AdapterObject->MapRegisters,
- (PULONG)(AdapterObject->MapRegisters + 1),
- AllowedMapRegisters);
-
- /* Reset the Bitmap */
- RtlSetAllBits(AdapterObject->MapRegisters);
- AdapterObject->NumberOfMapRegisters = 0;
- AdapterObject->CommittedMapRegisters = 0;
-
- /* Allocate Memory for the Map Registers */
- AdapterObject->MapRegisterBase = ExAllocatePool(NonPagedPool,
- AllowedMapRegisters * sizeof(DWORD));
-
- /* Clear them */
- RtlZeroMemory(AdapterObject->MapRegisterBase, AllowedMapRegisters * sizeof(DWORD));
-
- /* Allocate the contigous memory */
- DPRINT("Allocating Buffers\n");
- HalpGrowMapBuffers(AdapterObject, 0x1000000);
- }
-
- DPRINT("Adapter Object allocated\n");
- return AdapterObject;
-}
-
-
-BOOLEAN STDCALL
-IoFlushAdapterBuffers (
- PADAPTER_OBJECT AdapterObject,
- PMDL Mdl,
- PVOID MapRegisterBase,
- PVOID CurrentVa,
- ULONG Length,
- BOOLEAN WriteToDevice)
-/*
- * FUNCTION: flush any data remaining in the dma controller's memory into the host memory
- * ARGUMENTS:
- * AdapterObject: the adapter object to flush
- * Mdl: original MDL to flush data into
- * MapRegisterBase: map register base that was just used by IoMapTransfer, etc
- * CurrentVa: offset into Mdl to be flushed into, same as was passed to IoMapTransfer
- * Length: length of the buffer to be flushed into
- * WriteToDevice: True if it's a write, False if it's a read
- * RETURNS:
- * TRUE in all cases
- * NOTES:
- * - This copies data from the map register-backed buffer to the user's target buffer.
- * Data is not in the user buffer until this is called.
- * - This is only meaningful on a read operation. Return immediately for a write.
- */
-{
- ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
-
- /* this can happen if the card supports scatter/gather */
- if(!MapRegisterBase)
- return TRUE;
-
- /* mask out (disable) the dma channel */
- if (AdapterObject->AdapterNumber == 1) {
-
- /* Set this for Ease */
- PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
-
- /* Set Channel */
- WRITE_PORT_UCHAR(&DmaControl1->SingleMask, AdapterObject->ChannelNumber | DMA_SETMASK);
- } else {
- /* Set this for Ease */
- PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
-
- /* Set Channel */
- WRITE_PORT_UCHAR(&DmaControl2->SingleMask, (AdapterObject->ChannelNumber - 4) | DMA_SETMASK);
- }
-
- if(WriteToDevice)
- return TRUE;
-
- memcpy(
- (PVOID)((DWORD)MmGetSystemAddressForMdl( Mdl ) + (DWORD)CurrentVa - (DWORD)MmGetMdlVirtualAddress( Mdl )),
- MapRegisterBase, Length );
-
- return TRUE;
-}
-
-
-VOID STDCALL
-IoFreeAdapterChannel (PADAPTER_OBJECT AdapterObject)
-/*
- * FUNCTION: frees DMA resources allocated by IoAllocateAdapterChannel
- * ARGUMENTS:
- * AdapterObject: Adapter object with resources to free
- * NOTES:
- * - This function releases the DMA adapter and optionally the map registers
- * - After releasing the adapter, it checks the adapter's queue and runs
- * each queued device object in series until the queue is empty
- * - This is the only way the device queue is emptied.
- */
-{
- LARGE_INTEGER MaxAddress;
- LARGE_INTEGER MinAddress;
- LARGE_INTEGER BoundryAddressMultiple;
- PWAIT_CONTEXT_BLOCK WaitContextBlock;
- IO_ALLOCATION_ACTION Retval;
-
- while(1)
- {
- /* To keep map registers, call here with the following set to 0 */
- if(AdapterObject->CommittedMapRegisters)
- IoFreeMapRegisters(AdapterObject, AdapterObject->MapRegisterBase, AdapterObject->CommittedMapRegisters);
-
- if(!(WaitContextBlock = (PWAIT_CONTEXT_BLOCK)KeRemoveDeviceQueue(&AdapterObject->ChannelWaitQueue)))
- break;
-
- /*
- * the following should really be done elsewhere since this
- * function really can't return an error code. FIXME.
- */
-
- /* 24-bit max address due to 16-bit dma controllers */
- MinAddress.QuadPart = 0x0000000;
- MaxAddress.QuadPart = 0x1000000;
- BoundryAddressMultiple.QuadPart = 0;
-
- AdapterObject->MapRegisterBase = MmAllocateContiguousAlignedMemory(
- WaitContextBlock->NumberOfMapRegisters * PAGE_SIZE,
- MinAddress,
- MaxAddress,
- BoundryAddressMultiple,
- MmCached,
- 0x10000 );
-
- if(!AdapterObject->MapRegisterBase)
- return;
-
- /* call the adapter control routine */
- Retval = ((PDRIVER_CONTROL)WaitContextBlock->DeviceRoutine)(WaitContextBlock->DeviceObject, WaitContextBlock->CurrentIrp,
- AdapterObject->MapRegisterBase, WaitContextBlock->DeviceContext);
-
- if(Retval == KeepObject)
- {
- /* we're done until the caller manually calls IoFreeAdapterChannel */
- break;
- }
- else if(Retval == DeallocateObjectKeepRegisters)
- {
- /* hide the map registers so they aren't deallocated next time around */
- AdapterObject->CommittedMapRegisters = 0;
- }
- }
-}
-
-
-VOID STDCALL
-IoFreeMapRegisters (
- IN PADAPTER_OBJECT AdapterObject,
- IN PVOID MapRegisterBase,
- IN ULONG NumberOfMapRegisters)
-/*
- * FUNCTION: free map registers reserved by the system for a DMA
- * ARGUMENTS:
- * AdapterObject: dma adapter to free map registers on
- * MapRegisterBase: hadle to map registers to free
- * NumberOfRegisters: number of map registers to be freed
- * NOTES:
- * - XXX real windows has a funky interdependence between IoFreeMapRegisters
- * and IoFreeAdapterChannel
- * BUGS:
- * - needs to be improved to use a real map register implementation
- */
-{
- if( AdapterObject->CommittedMapRegisters )
- {
- MmFreeContiguousMemory(AdapterObject->MapRegisterBase);
- AdapterObject->MapRegisterBase = 0;
- }
-}
-
-
-PHYSICAL_ADDRESS STDCALL
-IoMapTransfer (
- IN PADAPTER_OBJECT AdapterObject,
- IN PMDL Mdl,
- IN PVOID MapRegisterBase,
- IN PVOID CurrentVa,
- IN OUT PULONG Length,
- IN BOOLEAN WriteToDevice)
-/*
- * FUNCTION: map a dma for transfer and do the dma if it's a slave
- * ARGUMENTS:
- * AdapterObject: adapter object to do the dma on. busmaster may pass NULL.
- * Mdl: locked-down user buffer to DMA in to or out of
- * MapRegisterBase: handle to map registers to use for this dma. allways NULL
- * when doing s/g.
- * CurrentVa: index into Mdl to transfer into/out of
- * Length: length of transfer in/out. Only modified on out when doing s/g.
- * WriteToDevice: TRUE if it's an output dma, FALSE otherwise
- * RETURNS:
- * If a busmaster: A logical address that can be used to program a dma controller
- * Otherwise: nothing meaningful
- * NOTES:
- * - This function does a copyover to contiguous memory <16MB
- * - If it's a slave transfer, this function actually performs it.
- * BUGS:
- * - If the controller supports scatter/gather, the copyover should not happen
- */
-{
- PHYSICAL_ADDRESS Address;
- KIRQL OldIrql;
- UCHAR Mode;
-
-#if defined(__GNUC__)
- Address.QuadPart = 0ULL;
-#else
- Address.QuadPart = 0;
-#endif
-
- /* Isa System (slave) DMA? */
- if (MapRegisterBase && !AdapterObject->MasterDevice)
- {
-
- KeAcquireSpinLock(&AdapterObject->SpinLock, &OldIrql);
-
- /*
- * FIXME: Handle case when doing common-buffer System DMA. In this case,
- * the buffer described by MDL is already phys. contiguous and below
- * 16 mega. Driver makes a one-shot call to IoMapTransfer during init.
- * to program controller with the common-buffer.
- *
- * UPDATE: Common buffer support is in place, but it's not done in a
- * clean way. We use the buffer passed by the MDL in case that the
- * adapter object is marked as auto initialize. I'm not sure if this
- * is correct and if not, how to do it properly. Note that it's also
- * possible to allocate the common buffer with different adapter object
- * and IoMapTransfer must still work in this case. Eventually this should
- * be cleaned up somehow or at least this comment modified to reflect
- * the reality.
- * -- Filip Navara, 19/07/2004
- */
-
- /* Get the mode for easier coding */
- Mode = AdapterObject->AdapterMode;
-
- /* if it is a write to the device, copy the caller buffer to the low buffer */
- if ((WriteToDevice) && !((PDMA_MODE)&Mode)->AutoInitialize)
- {
- memcpy(MapRegisterBase,
- (char*)MmGetSystemAddressForMdl(Mdl) + ((ULONG)CurrentVa - (ULONG)MmGetMdlVirtualAddress(Mdl)),
- *Length );
- }
-
- /* Writer Adapter Mode, transfer type */
- ((PDMA_MODE)&Mode)->TransferType = (WriteToDevice ? WRITE_TRANSFER : READ_TRANSFER);
-
- // program up the dma controller, and return
- if (!((PDMA_MODE)&Mode)->AutoInitialize) {
- Address = MmGetPhysicalAddress( MapRegisterBase );
- } else {
- Address = MmGetPhysicalAddress( CurrentVa );
- }
-
- /* 16-bit DMA has a shifted length */
- if (AdapterObject->Width16Bits) *Length = (*Length >> 1);
-
- /* Make the Transfer */
- if (AdapterObject->AdapterNumber == 1) {
-
- PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa; /* For Writing Less Code */
-
- /* Reset Register */
- WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
-
- /* Set the Mode */
- WRITE_PORT_UCHAR(&DmaControl1->Mode, (UCHAR)(Mode));
-
- /* Set the Page Register (apparently always 0 for us if I trust the previous comment) */
- WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0);
- WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0);
-
- /* Set the Length */
- WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
- (UCHAR)((*Length) - 1));
- WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
- (UCHAR)((*Length) - 1) >> 8);
-
- /* Unmask the Channel */
- WRITE_PORT_UCHAR(&DmaControl1->SingleMask, AdapterObject->ChannelNumber | DMA_CLEARMASK);
- } else {
- PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa; /* For Writing Less Code */
-
- /* Reset Register */
- WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
-
- /* Set the Mode */
- WRITE_PORT_UCHAR(&DmaControl2->Mode, (UCHAR)(Mode));
-
- /* Set the Page Register (apparently always 0 for us if I trust the previous comment) */
- WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0);
- WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0);
-
- /* Set the Length */
- WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
- (UCHAR)((*Length) - 1));
- WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
- (UCHAR)((*Length) - 1) >> 8);
-
- /* Unmask the Channel */
- WRITE_PORT_UCHAR(&DmaControl2->SingleMask, AdapterObject->ChannelNumber | DMA_CLEARMASK);
- }
-
- /* Release Spinlock */
- KeReleaseSpinLock(&AdapterObject->SpinLock, OldIrql);
-
- /*
- NOTE: Return value should be ignored when doing System DMA.
- Maybe return some more obvious invalid address here (thou returning
- MapRegisterBase is also wrong;-)to catch invalid use?
- */
- Address.QuadPart = (ULONG)MapRegisterBase;
- return Address;
- }
-
-
- /*
- Busmaster with s/g support?
- NOTE: old docs allowed busmasters to pass a NULL Adapter. In this case, MapRegisterBase
- being NULL is used to detect a s/g busmaster.
- */
- if ((!AdapterObject && !MapRegisterBase) ||
- (AdapterObject && AdapterObject->MasterDevice && AdapterObject->ScatterGather))
- {
- /*
- Just return the passed VA's corresponding phys. address.
- Update length to the number of phys. contiguous bytes found.
- */
-
- PULONG MdlPages;
- ULONG MdlPageIndex, PhysContiguousLen;
- ULONG PhysAddress;
-
- MdlPages = (PULONG)(Mdl + 1);
-
- /* Get VA's corresponding mdl phys. page index */
- MdlPageIndex = ((ULONG)CurrentVa - (ULONG)Mdl->StartVa) / PAGE_SIZE;
-
- /* Get phys. page containing the VA */
- PhysAddress = MdlPages[MdlPageIndex];
-
- PhysContiguousLen = PAGE_SIZE - BYTE_OFFSET(CurrentVa);
-
- /* VA to map may span several contiguous phys. pages (unlikely) */
- while (PhysContiguousLen < *Length &&
- MdlPages[MdlPageIndex++] + PAGE_SIZE == MdlPages[MdlPageIndex])
- {
- /*
- Note that allways adding PAGE_SIZE may make PhysContiguousLen greater
- than Length if buffer doesn't end on page boundary. Take this
- into consideration below.
- */
- PhysContiguousLen += PAGE_SIZE;
- }
-
- if (PhysContiguousLen < *Length)
- {
- *Length = PhysContiguousLen;
- }
-
- //add offset to phys. page address
- Address.QuadPart = PhysAddress + BYTE_OFFSET(CurrentVa);
- return Address;
- }
-
-
- /*
- Busmaster without s/g support?
- NOTE: old docs allowed busmasters to pass a NULL Adapter. In this case, MapRegisterBase
- not being NULL is used to detect a non s/g busmaster.
- */
- if ((!AdapterObject && MapRegisterBase) ||
- (AdapterObject && AdapterObject->MasterDevice && !AdapterObject->ScatterGather))
- {
- /*
- NOTE: Busmasters doing common-buffer DMA shouldn't call IoMapTransfer, but I don't
- know if it's illegal... Maybe figure out what to do in this case...
- */
-
- if( WriteToDevice )
- {
- memcpy(MapRegisterBase,
- (char*)MmGetSystemAddressForMdl(Mdl) + ((ULONG)CurrentVa - (ULONG)MmGetMdlVirtualAddress(Mdl)),
- *Length );
- }
-
- return MmGetPhysicalAddress(MapRegisterBase);
- }
-
- DPRINT("IoMapTransfer: Unsupported operation\n");
- KEBUGCHECK(0);
- return Address;
-}
-
-
-/* EOF */
-
-
-
-
reactos/hal/halx86
diff -N apic.c
--- apic.c 28 Nov 2004 01:30:01 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,853 +0,0 @@
-/*
- * ReactOS kernel
- * Copyright (C) 2004 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/* $Id: apic.c,v 1.1 2004/11/28 01:30:01 hbirr Exp $
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: hal/halx86/apic.c
- * PURPOSE:
- * PROGRAMMER:
- */
-
-#include <roscfg.h>
-#include <ddk/ntddk.h>
-
-#include <hal.h>
-#include <halirq.h>
-#include <mps.h>
-#include <apic.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-BOOLEAN VerifyLocalAPIC(VOID);
-VOID APICCalibrateTimer(ULONG CPU);
-
-extern VOID MpsTimerInterrupt(VOID);
-extern VOID MpsErrorInterrupt(VOID);
-extern VOID MpsSpuriousInterrupt(VOID);
-extern VOID MpsIpiInterrupt(VOID);
-
-extern ULONG APICMode; /* APIC mode at startup */
-extern PULONG BIOSBase; /* Virtual address of BIOS data segment */
-extern PULONG CommonBase; /* Virtual address of common area */
-extern ULONG BootCPU; /* Bootstrap processor */
-extern ULONG OnlineCPUs; /* Bitmask of online CPUs */
-
-extern CHAR *APstart, *APend;
-extern VOID (*APflush)(VOID);
-
-#define CMOS_READ(address) ({ \
- WRITE_PORT_UCHAR((PUCHAR)0x70, address)); \
- READ_PORT_UCHAR((PUCHAR)0x71)); \
-})
-
-#define CMOS_WRITE(address, value) ({ \
- WRITE_PORT_UCHAR((PUCHAR)0x70, address); \
- WRITE_PORT_UCHAR((PUCHAR)0x71, value); \
-})
-
-#define BIOS_AREA 0x0
-#define COMMON_AREA 0x2000
-
-
-extern CPU_INFO CPUMap[MAX_CPU]; /* Map of all CPUs in the system */
-
-PULONG APICBase = (PULONG)APIC_DEFAULT_BASE; /* Virtual address of local APIC */
-
-/* For debugging */
-ULONG lastregr[MAX_CPU];
-ULONG lastvalr[MAX_CPU];
-ULONG lastregw[MAX_CPU];
-ULONG lastvalw[MAX_CPU];
-
-ULONG APICGetMaxLVT(VOID)
-{
- ULONG tmp, ver, maxlvt;
-
- tmp = APICRead(APIC_VER);
- ver = GET_APIC_VERSION(tmp);
- /* 82489DXs do not report # of LVT entries. */
- maxlvt = APIC_INTEGRATED(ver) ? GET_APIC_MAXLVT(tmp) : 2;
-
- return maxlvt;
-}
-
-VOID APICClear(VOID)
-{
- ULONG tmp, maxlvt;
-
- maxlvt = APICGetMaxLVT();
-
- /*
- * Careful: we have to set masks only first to deassert
- * any level-triggered sources.
- */
-
- if (maxlvt >= 3)
- {
- tmp = ERROR_VECTOR;
- APICWrite(APIC_LVT3, tmp | APIC_LVT3_MASKED);
- }
-
- tmp = APICRead(APIC_LVTT);
- APICWrite(APIC_LVTT, tmp | APIC_LVT_MASKED);
-
- tmp = APICRead(APIC_LINT0);
- APICWrite(APIC_LINT0, tmp | APIC_LVT_MASKED);
-
- tmp = APICRead(APIC_LINT1);
- APICWrite(APIC_LINT1, tmp | APIC_LVT_MASKED);
-
- if (maxlvt >= 4)
- {
- tmp = APICRead(APIC_LVTPC);
- APICWrite(APIC_LVTPC, tmp | APIC_LVT_MASKED);
- }
-#if 0
- if (maxlvt >= 5)
- {
- tmp = APICRead(APIC_LVTTHMR);
- APICWrite(APIC_LVTTHMR, tmp | APIC_LVT_MASKED);
- }
-#endif
- /*
- * Clean APIC state for other OSs:
- */
- APICWrite(APIC_LVTT, APIC_LVT_MASKED);
- APICWrite(APIC_LINT0, APIC_LVT_MASKED);
- APICWrite(APIC_LINT1, APIC_LVT_MASKED);
-
- if (maxlvt >= 3)
- {
- APICWrite(APIC_LVT3, APIC_LVT3_MASKED);
- }
-
- if (maxlvt >= 4)
- {
- APICWrite(APIC_LVTPC, APIC_LVT_MASKED);
- }
-#if 0
- if (maxlvt >= 5)
- {
- APICWrite(APIC_LVTTHMR, APIC_LVT_MASKED);
- }
-#endif
-}
-
-/* Enable symetric I/O mode ie. connect the BSP's local APIC to INT and NMI lines */
-VOID EnableSMPMode(VOID)
-{
- /*
- * Do not trust the local APIC being empty at bootup.
- */
- APICClear();
-
- WRITE_PORT_UCHAR((PUCHAR)0x22, 0x70);
- WRITE_PORT_UCHAR((PUCHAR)0x23, 0x01);
-}
-
-/* Disable symetric I/O mode ie. go to PIC mode */
-inline VOID DisableSMPMode(VOID)
-{
- /*
- * Put the board back into PIC mode (has an effect
- * only on certain older boards). Note that APIC
- * interrupts, including IPIs, won't work beyond
- * this point! The only exception are INIT IPIs.
- */
- WRITE_PORT_UCHAR((PUCHAR)0x22, 0x70);
- WRITE_PORT_UCHAR((PUCHAR)0x23, 0x00);
-}
-
-VOID DumpESR(VOID)
-{
- ULONG tmp;
-
- if (APICGetMaxLVT() > 3)
- {
- APICWrite(APIC_ESR, 0);
- }
- tmp = APICRead(APIC_ESR);
- DbgPrint("ESR %08x\n", tmp);
-}
-
-
-VOID APICDisable(VOID)
-{
- ULONG tmp;
-
- APICClear();
-
- /*
- * Disable APIC (implies clearing of registers for 82489DX!).
- */
- tmp = APICRead(APIC_SIVR);
- tmp &= ~APIC_SIVR_ENABLE;
- APICWrite(APIC_SIVR, tmp);
-}
-
-VOID HaliInitBSP(VOID)
-{
- PUSHORT ps;
- static BOOLEAN BSPInitialized = FALSE;
-
- /* Only initialize the BSP once */
- if (BSPInitialized)
- {
- KEBUGCHECK(0);
- return;
- }
-
- BSPInitialized = TRUE;
-
- DPRINT("APIC is mapped at 0x%X\n", APICBase);
-
- if (VerifyLocalAPIC())
- {
- DPRINT("APIC found\n");
- }
- else
- {
- DPRINT("No APIC found\n");
- KEBUGCHECK(0);
- }
-
- if (APICMode == amPIC)
- {
- EnableSMPMode();
- }
-
- APICSetup();
-
- /* BIOS data segment */
- BIOSBase = (PULONG)BIOS_AREA;
-
- /* Area for communicating with the APs */
- CommonBase = (PULONG)COMMON_AREA;
-
- /* Copy bootstrap code to common area */
- memcpy((PVOID)((ULONG)CommonBase + PAGE_SIZE),
- &APstart,
- (ULONG)&APend - (ULONG)&APstart + 1);
-
- /* Set shutdown code */
- CMOS_WRITE(0xF, 0xA);
-
- /* Set warm reset vector */
- ps = (PUSHORT)((ULONG)BIOSBase + 0x467);
- *ps = (COMMON_AREA + PAGE_SIZE) & 0xF;
-
- ps = (PUSHORT)((ULONG)BIOSBase + 0x469);
- *ps = (COMMON_AREA + PAGE_SIZE) >> 4;
-
- /* Calibrate APIC timer */
- APICCalibrateTimer(BootCPU);
-}
-
-volatile inline ULONG _APICRead(ULONG Offset)
-{
- PULONG p;
-
- p = (PULONG)((ULONG)APICBase + Offset);
- return *p;
-}
-
-#if 0
-inline VOID APICWrite(ULONG Offset,
- ULONG Value)
-{
- PULONG p;
-
- p = (PULONG)((ULONG)APICBase + Offset);
-
- *p = Value;
-}
-#else
-inline VOID APICWrite(ULONG Offset,
- ULONG Value)
-{
- PULONG p;
- ULONG CPU = (_APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
-
- lastregw[CPU] = Offset;
- lastvalw[CPU] = Value;
-
- p = (PULONG)((ULONG)APICBase + Offset);
-
- *p = Value;
-}
-#endif
-
-
-#if 0
-volatile inline ULONG APICRead(ULONG Offset)
-{
- PULONG p;
-
- p = (PULONG)((ULONG)APICBase + Offset);
- return *p;
-}
-#else
-volatile inline ULONG APICRead(ULONG Offset)
-{
- PULONG p;
- ULONG CPU = (_APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
-
- lastregr[CPU] = Offset;
- lastvalr[CPU] = 0;
-
- p = (PULONG)((ULONG)APICBase + Offset);
-
- lastvalr[CPU] = *p;
- return lastvalr[CPU];
-}
-#endif
-
-inline VOID APICSendEOI(VOID)
-{
- // Send the EOI
- APICWrite(APIC_EOI, 0);
-}
-
-static VOID APICDumpBit(ULONG base)
-{
- ULONG v, i, j;
-
- DbgPrint("0123456789abcdef0123456789abcdef\n");
- for (i = 0; i < 8; i++)
- {
- v = APICRead(base + i*0x10);
- for (j = 0; j < 32; j++)
- {
- if (v & (1<<j))
- DbgPrint("1");
- else
- DbgPrint("0");
- }
- DbgPrint("\n");
- }
-}
-
-
-VOID APICDump(VOID)
-/*
- * Dump the contents of the local APIC registers
- */
-{
- ULONG v, ver, maxlvt;
- ULONG r1, r2, w1, w2;
- ULONG CPU = ThisCPU();;
-
-
-
- r1 = lastregr[CPU];
- r2 = lastvalr[CPU];
- w1 = lastregw[CPU];
- w2 = lastvalw[CPU];
-
- DbgPrint("\nPrinting local APIC contents on CPU(%d):\n", ThisCPU());
- v = APICRead(APIC_ID);
- DbgPrint("... ID : %08x (%01x) ", v, GET_APIC_ID(v));
- v = APICRead(APIC_VER);
- DbgPrint("... VERSION: %08x\n", v);
- ver = GET_APIC_VERSION(v);
- maxlvt = APICGetMaxLVT();
-
- v = APICRead(APIC_TPR);
- DbgPrint("... TPR : %08x (%02x)", v, v & ~0);
-
- if (APIC_INTEGRATED(ver))
- {
- /* !82489DX */
- v = APICRead(APIC_APR);
- DbgPrint("... APR : %08x (%02x)\n", v, v & ~0);
- v = APICRead(APIC_PPR);
- DbgPrint("... PPR : %08x\n", v);
- }
-
- v = APICRead(APIC_EOI);
- DbgPrint("... EOI : %08x ! ", v);
- v = APICRead(APIC_LDR);
- DbgPrint("... LDR : %08x\n", v);
- v = APICRead(APIC_DFR);
- DbgPrint("... DFR : %08x ! ", v);
- v = APICRead(APIC_SIVR);
- DbgPrint("... SIVR : %08x\n", v);
-
- if (0)
- {
- DbgPrint("... ISR field:\n");
- APICDumpBit(APIC_ISR);
- DbgPrint("... TMR field:\n");
- APICDumpBit(APIC_TMR);
- DbgPrint("... IRR field:\n");
- APICDumpBit(APIC_IRR);
- }
-
- if (APIC_INTEGRATED(ver))
- {
- /* !82489DX */
- if (maxlvt > 3)
- {
- /* Due to the Pentium erratum 3AP. */
- APICWrite(APIC_ESR, 0);
- }
- v = APICRead(APIC_ESR);
- DbgPrint("... ESR : %08x\n", v);
- }
-
- v = APICRead(APIC_ICR0);
- DbgPrint("... ICR0 : %08x ! ", v);
- v = APICRead(APIC_ICR1);
- DbgPrint("... ICR1 : %08x ! ", v);
-
- v = APICRead(APIC_LVTT);
- DbgPrint("... LVTT : %08x\n", v);
-
- if (maxlvt > 3)
- {
- /* PC is LVT#4. */
- v = APICRead(APIC_LVTPC);
- DbgPrint("... LVTPC : %08x ! ", v);
- }
- v = APICRead(APIC_LINT0);
- DbgPrint("... LINT0 : %08x ! ", v);
- v = APICRead(APIC_LINT1);
- DbgPrint("... LINT1 : %08x\n", v);
-
- if (maxlvt > 2)
- {
- v = APICRead(APIC_LVT3);
- DbgPrint("... LVT3 : %08x\n", v);
- }
-
- v = APICRead(APIC_ICRT);
- DbgPrint("... ICRT : %08x ! ", v);
- v = APICRead(APIC_CCRT);
- DbgPrint("... CCCT : %08x ! ", v);
- v = APICRead(APIC_TDCR);
- DbgPrint("... TDCR : %08x\n", v);
- DbgPrint("\n");
- DbgPrint("Last register read (offset): 0x%08X\n", r1);
- DbgPrint("Last register read (value): 0x%08X\n", r2);
- DbgPrint("Last register written (offset): 0x%08X\n", w1);
- DbgPrint("Last register written (value): 0x%08X\n", w2);
- DbgPrint("\n");
-}
-
-BOOLEAN VerifyLocalAPIC(VOID)
-{
- UINT reg0, reg1;
- CHECKPOINT1;
- /* The version register is read-only in a real APIC */
- reg0 = APICRead(APIC_VER);
- DPRINT1("Getting VERSION: %x\n", reg0);
- APICWrite(APIC_VER, reg0 ^ APIC_VER_MASK);
- reg1 = APICRead(APIC_VER);
- DPRINT1("Getting VERSION: %x\n", reg1);
-
- /*
- * The two version reads above should print the same
- * numbers. If the second one is different, then we
- * poke at a non-APIC.
- */
-
- if (reg1 != reg0)
- {
- return FALSE;
- }
-
- /*
- * Check if the version looks reasonably.
- */
- reg1 = GET_APIC_VERSION(reg0);
- if (reg1 == 0x00 || reg1 == 0xff)
- {
- return FALSE;
- }
- reg1 = APICGetMaxLVT();
- if (reg1 < 0x02 || reg1 == 0xff)
- {
- return FALSE;
- }
-
- /*
- * The ID register is read/write in a real APIC.
- */
- reg0 = APICRead(APIC_ID);
- DPRINT1("Getting ID: %x\n", reg0);
- APICWrite(APIC_ID, reg0 ^ APIC_ID_MASK);
- reg1 = APICRead(APIC_ID);
- DPRINT1("Getting ID: %x\n", reg1);
- APICWrite(APIC_ID, reg0);
- if (reg1 != (reg0 ^ APIC_ID_MASK))
- {
- return FALSE;
- }
-
- return TRUE;
-}
-
-VOID APICSendIPI(ULONG Target, ULONG Mode)
-{
- ULONG tmp, i, flags;
-
- /* save flags and disable interrupts */
- Ki386SaveFlags(flags);
- Ki386DisableInterrupts();
-
- /* Wait up to 100ms for the APIC to become ready */
- for (i = 0; i < 10000; i++)
- {
- tmp = APICRead(APIC_ICR0);
- /* Check Delivery Status */
- if ((tmp & APIC_ICR0_DS) == 0)
- break;
- KeStallExecutionProcessor(10);
- }
-
- if (i == 10000)
- {
- DPRINT1("CPU(%d) Previous IPI was not delivered after 100ms.\n", ThisCPU());
- }
-
- /* Setup the APIC to deliver the IPI */
- DPRINT("%08x %x\n", SET_APIC_DEST_FIELD(Target), Target);
- APICWrite(APIC_ICR1, SET_APIC_DEST_FIELD(Target));
-
- if (Target == APIC_TARGET_SELF)
- {
- Mode |= APIC_ICR0_DESTS_SELF;
- }
- else if (Target == APIC_TARGET_ALL)
- {
- Mode |= APIC_ICR0_DESTS_ALL;
- }
- else if (Target == APIC_TARGET_ALL_BUT_SELF)
- {
- Mode |= APIC_ICR0_DESTS_ALL_BUT_SELF;
- }
- else
- {
- Mode |= APIC_ICR0_DESTS_FIELD;
- }
-
- /* Now, fire off the IPI */
- APICWrite(APIC_ICR0, Mode);
-
- /* Wait up to 100ms for the APIC to become ready */
- for (i = 0; i < 10000; i++)
- {
- tmp = APICRead(APIC_ICR0);
- /* Check Delivery Status */
- if ((tmp & APIC_ICR0_DS) == 0)
- break;
- KeStallExecutionProcessor(10);
- }
-
- if (i == 10000)
- {
- DPRINT1("CPU(%d) Current IPI was not delivered after 100ms.\n", ThisCPU());
- }
- Ki386RestoreFlags(flags);
-}
-
-VOID APICSetup(VOID)
-{
- ULONG CPU, tmp;
-
- CPU = ThisCPU();
-
-// APICDump();
-
- DPRINT1("CPU%d:\n", CPU);
- DPRINT1(" Physical APIC id: %d\n", GET_APIC_ID(APICRead(APIC_ID)));
- DPRINT1(" Logical APIC id: %d\n", GET_APIC_LOGICAL_ID(APICRead(APIC_LDR)));
- DPRINT1("%08x %08x %08x\n", APICRead(APIC_ID), APICRead(APIC_LDR), APICRead(APIC_DFR));
-
- /*
- * Intel recommends to set DFR, LDR and TPR before enabling
- * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
- * document number 292116). So here it goes...
- */
-
- /*
- * Put the APIC into flat delivery mode.
- * Must be "all ones" explicitly for 82489DX.
- */
- APICWrite(APIC_DFR, 0xFFFFFFFF);
-
- /*
- * Set up the logical destination ID.
- */
- tmp = APICRead(APIC_LDR);
- tmp &= ~APIC_LDR_MASK;
- /*
- * FIXME:
- * This works only up to 8 CPU's
- */
- tmp |= (1 << (KeGetCurrentProcessorNumber() + 24));
- APICWrite(APIC_LDR, tmp);
-
-
- DPRINT1("CPU%d:\n", CPU);
- DPRINT1(" Physical APIC id: %d\n", GET_APIC_ID(APICRead(APIC_ID)));
- DPRINT1(" Logical APIC id: %d\n", GET_APIC_LOGICAL_ID(APICRead(APIC_LDR)));
- DPRINT1("%08x %08x %08x\n", APICRead(APIC_ID), APICRead(APIC_LDR), APICRead(APIC_DFR));
- DPRINT1("%d\n", CPUMap[CPU].APICId);
-
- /* Accept only higher interrupts */
- APICWrite(APIC_TPR, 0xef);
-
- /* Enable local APIC */
- tmp = APICRead(APIC_SIVR);
- tmp &= ~0xff;
- tmp |= APIC_SIVR_ENABLE;
-
-#if 0
- tmp &= ~APIC_SIVR_FOCUS;
-#else
- tmp |= APIC_SIVR_FOCUS;
-#endif
-
- /* Set spurious interrupt vector */
- tmp |= SPURIOUS_VECTOR;
- APICWrite(APIC_SIVR, tmp);
-
- /*
- * Set up LVT0, LVT1:
- *
- * set up through-local-APIC on the BP's LINT0. This is not
- * strictly necessery in pure symmetric-IO mode, but sometimes
- * we delegate interrupts to the 8259A.
- */
- tmp = APICRead(APIC_LINT0) & APIC_LVT_MASKED;
- if (CPU == BootCPU && (APICMode == amPIC || !tmp))
- {
- tmp = APIC_DM_EXTINT;
- DPRINT1("enabled ExtINT on CPU#%d\n", CPU);
- }
- else
- {
- tmp = APIC_DM_EXTINT | APIC_LVT_MASKED;
- DPRINT1("masked ExtINT on CPU#%d\n", CPU);
- }
- APICWrite(APIC_LINT0, tmp);
-
-
- /*
- * Only the BSP should see the LINT1 NMI signal, obviously.
- */
- if (CPU == BootCPU)
- {
- tmp = APIC_DM_NMI;
- }
- else
- {
- tmp = APIC_DM_NMI | APIC_LVT_MASKED;
- }
- if (!APIC_INTEGRATED(CPUMap[CPU].APICVersion))
- {
- /* 82489DX */
- tmp |= APIC_LVT_LEVEL_TRIGGER;
- }
- APICWrite(APIC_LINT1, tmp);
-
- if (APIC_INTEGRATED(CPUMap[CPU].APICVersion))
- {
- /* !82489DX */
- if (APICGetMaxLVT() > 3)
- {
- /* Due to the Pentium erratum 3AP */
- APICWrite(APIC_ESR, 0);
- }
-
- tmp = APICRead(APIC_ESR);
- DPRINT("ESR value before enabling vector: 0x%X\n", tmp);
-
- /* Enable sending errors */
- tmp = ERROR_VECTOR;
- APICWrite(APIC_LVT3, tmp);
-
- /*
- * Spec says clear errors after enabling vector
- */
- if (APICGetMaxLVT() > 3)
- {
- APICWrite(APIC_ESR, 0);
- }
- tmp = APICRead(APIC_ESR);
- DPRINT("ESR value after enabling vector: 0x%X\n", tmp);
- }
-}
-
-VOID APICSyncArbIDs(VOID)
-{
- ULONG i, tmp;
-
- /* Wait up to 100ms for the APIC to become ready */
- for (i = 0; i < 10000; i++)
- {
- tmp = APICRead(APIC_ICR0);
- /* Check Delivery Status */
- if ((tmp & APIC_ICR0_DS) == 0)
- break;
- KeStallExecutionProcessor(10);
- }
-
- if (i == 10000)
- {
- DPRINT("CPU(%d) APIC busy for 100ms.\n", ThisCPU());
- }
-
- DPRINT("Synchronizing Arb IDs.\n");
- APICWrite(APIC_ICR0, APIC_ICR0_DESTS_ALL | APIC_ICR0_LEVEL | APIC_DM_INIT);
-}
-
-VOID MpsErrorHandler(VOID)
-{
- ULONG tmp1, tmp2;
-
- APICDump();
-
- tmp1 = APICRead(APIC_ESR);
- APICWrite(APIC_ESR, 0);
- tmp2 = APICRead(APIC_ESR);
- DPRINT1("APIC error on CPU(%d) ESR(%x)(%x)\n", ThisCPU(), tmp1, tmp2);
-
- /*
- * Acknowledge the interrupt
- */
- APICSendEOI();
-
- /* Here is what the APIC error bits mean:
- * 0: Send CS error
- * 1: Receive CS error
- * 2: Send accept error
- * 3: Receive accept error
- * 4: Reserved
- * 5: Send illegal vector
- * 6: Received illegal vector
- * 7: Illegal register address
- */
- DPRINT1("APIC error on CPU(%d) ESR(%x)(%x)\n", ThisCPU(), tmp1, tmp2);
- for (;;);
-}
-
-VOID MpsSpuriousHandler(VOID)
-{
- ULONG tmp;
-
- DPRINT1("Spurious interrupt on CPU(%d)\n", ThisCPU());
-
- tmp = APICRead(APIC_ISR + ((SPURIOUS_VECTOR & ~0x1f) >> 1));
- if (tmp & (1 << (SPURIOUS_VECTOR & 0x1f)))
- {
- APICSendEOI();
- return;
- }
-#if 0
- /* No need to send EOI here */
- APICDump();
-#endif
-}
-
-VOID MpsIpiHandler(VOID)
-{
- KIRQL oldIrql;
-
- HalBeginSystemInterrupt(IPI_VECTOR,
- VECTOR2IRQL(IPI_VECTOR),
- &oldIrql);
- Ki386EnableInterrupts();
-#if 0
- DbgPrint("(%s:%d) MpsIpiHandler on CPU%d, current irql is %d\n",
- __FILE__,__LINE__, KeGetCurrentProcessorNumber(), KeGetCurrentIrql());
-#endif
-
- KiIpiServiceRoutine(NULL, NULL);
-
-#if 0
- DbgPrint("(%s:%d) MpsIpiHandler on CPU%d done\n", __FILE__,__LINE__, KeGetCurrentProcessorNumber());
-#endif
-
- Ki386DisableInterrupts();
- HalEndSystemInterrupt(oldIrql, 0);
-}
-
-VOID
-MpsIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame,
- PKTRAP_FRAME TrapFrame)
-{
- TrapFrame->Gs = (USHORT)IrqTrapFrame->Gs;
- TrapFrame->Fs = (USHORT)IrqTrapFrame->Fs;
- TrapFrame->Es = (USHORT)IrqTrapFrame->Es;
- TrapFrame->Ds = (USHORT)IrqTrapFrame->Ds;
- TrapFrame->Eax = IrqTrapFrame->Eax;
- TrapFrame->Ecx = IrqTrapFrame->Ecx;
- TrapFrame->Edx = IrqTrapFrame->Edx;
- TrapFrame->Ebx = IrqTrapFrame->Ebx;
- TrapFrame->Esp = IrqTrapFrame->Esp;
- TrapFrame->Ebp = IrqTrapFrame->Ebp;
- TrapFrame->Esi = IrqTrapFrame->Esi;
- TrapFrame->Edi = IrqTrapFrame->Edi;
- TrapFrame->Eip = IrqTrapFrame->Eip;
- TrapFrame->Cs = IrqTrapFrame->Cs;
- TrapFrame->Eflags = IrqTrapFrame->Eflags;
-}
-
-VOID
-MpsTimerHandler(ULONG Vector, PKIRQ_TRAPFRAME Trapframe)
-{
- KIRQL oldIrql;
- KTRAP_FRAME KernelTrapFrame;
-#if 0
- ULONG CPU;
- static ULONG Count[MAX_CPU] = {0,};
-#endif
- HalBeginSystemInterrupt(LOCAL_TIMER_VECTOR,
- VECTOR2IRQL(LOCAL_TIMER_VECTOR),
- &oldIrql);
- Ki386EnableInterrupts();
-
-#if 0
- CPU = ThisCPU();
- if ((Count[CPU] % 100) == 0)
- {
- DbgPrint("(%s:%d) MpsTimerHandler on CPU%d, irql = %d, epi = %x, KPCR = %x\n", __FILE__, __LINE__, CPU, oldIrql,Trapframe->Eip, KeGetCurrentKPCR());
- }
- Count[CPU]++;
-#endif
-
- MpsIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame);
- if (KeGetCurrentProcessorNumber() == 0)
- {
- KeUpdateSystemTime(&KernelTrapFrame, oldIrql);
- }
- else
- {
- KeUpdateRunTime(&KernelTrapFrame, oldIrql);
- }
-
- Ki386DisableInterrupts();
- HalEndSystemInterrupt (oldIrql, 0);
-}
-
-/* EOF */
reactos/hal/halx86
diff -N beep.c
--- beep.c 20 Jul 2004 21:25:36 -0000 1.5
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,79 +0,0 @@
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/x86/beep.c
- * PURPOSE: Speaker function (it's only one)
- * PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
- * UPDATE HISTORY:
- * Created 31/01/99
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ddk/ntddk.h>
-#include <hal.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-
-/* CONSTANTS *****************************************************************/
-
-#define TIMER2 0x42
-#define TIMER3 0x43
-#define PORT_B 0x61
-#define CLOCKFREQ 1193167
-
-
-/* FUNCTIONS *****************************************************************/
-/*
- * FUNCTION: Beeps the speaker.
- * ARGUMENTS:
- * Frequency = If 0, the speaker will be switched off, otherwise
- * the speaker beeps with the specified frequency.
- */
-
-BOOLEAN
-STDCALL
-HalMakeBeep (
- ULONG Frequency
- )
-{
- UCHAR b;
- ULONG flags;
-
- /* save flags and disable interrupts */
- Ki386SaveFlags(flags);
- Ki386DisableInterrupts();
-
- /* speaker off */
- b = READ_PORT_UCHAR((PUCHAR)PORT_B);
- WRITE_PORT_UCHAR((PUCHAR)PORT_B, (UCHAR)(b & 0xFC));
-
- if (Frequency)
- {
- DWORD Divider = CLOCKFREQ / Frequency;
-
- if (Divider > 0x10000)
- {
- /* restore flags */
- Ki386RestoreFlags(flags);
-
- return FALSE;
- }
-
- /* set timer divider */
- WRITE_PORT_UCHAR((PUCHAR)TIMER3, 0xB6);
- WRITE_PORT_UCHAR((PUCHAR)TIMER2, (UCHAR)(Divider & 0xFF));
- WRITE_PORT_UCHAR((PUCHAR)TIMER2, (UCHAR)((Divider>>8) & 0xFF));
-
- /* speaker on */
- WRITE_PORT_UCHAR((PUCHAR)PORT_B, (UCHAR)(READ_PORT_UCHAR((PUCHAR)PORT_B) | 0x03));
- }
-
- /* restore flags */
- Ki386RestoreFlags(flags);
-
- return TRUE;
-}
-
reactos/hal/halx86
diff -N bus.c
--- bus.c 28 Dec 2003 22:38:09 -0000 1.7
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,532 +0,0 @@
-/* $Id: bus.c,v 1.7 2003/12/28 22:38:09 fireball Exp $
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/x86/bus.c
- * PURPOSE: Bus functions
- * PROGRAMMER: David Welch (welch@mcmail.com)
- * UPDATE HISTORY:
- * Created 22/05/98
- *
- *
- * TODO:
- * - Add bus handler functions for all busses
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ddk/ntddk.h>
-#include <hal.h>
-#include <bus.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-/* GLOBALS *******************************************************************/
-
-#define TAG_BUS TAG('B', 'U', 'S', 'H')
-
-KSPIN_LOCK HalpBusHandlerSpinLock = {0,};
-LIST_ENTRY HalpBusHandlerList;
-
-
-/* FUNCTIONS *****************************************************************/
-
-static NTSTATUS STDCALL
-HalpNoAdjustResourceList(PBUS_HANDLER BusHandler,
- ULONG BusNumber,
- PCM_RESOURCE_LIST Resources)
-{
- return STATUS_UNSUCCESSFUL;
-}
-
-
-static NTSTATUS STDCALL
-HalpNoAssignSlotResources(PBUS_HANDLER BusHandler,
- ULONG BusNumber,
- PUNICODE_STRING RegistryPath,
- PUNICODE_STRING DriverClassName,
- PDRIVER_OBJECT DriverObject,
- PDEVICE_OBJECT DeviceObject,
- ULONG SlotNumber,
- PCM_RESOURCE_LIST *AllocatedResources)
-{
- return STATUS_NOT_SUPPORTED;
-}
-
-
-static ULONG STDCALL
-HalpNoBusData(PBUS_HANDLER BusHandler,
- ULONG BusNumber,
- ULONG SlotNumber,
- PVOID Buffer,
- ULONG Offset,
- ULONG Length)
-{
- return 0;
-}
-
-
-static ULONG STDCALL
-HalpNoGetInterruptVector(PBUS_HANDLER BusHandler,
- ULONG BusNumber,
- ULONG BusInterruptLevel,
- ULONG BusInterruptVector,
- PKIRQL Irql,
- PKAFFINITY Affinity)
-{
- return 0;
-}
-
-
-static ULONG STDCALL
-HalpNoTranslateBusAddress(PBUS_HANDLER BusHandler,
- ULONG BusNumber,
- PHYSICAL_ADDRESS BusAddress,
- PULONG AddressSpace,
- PPHYSICAL_ADDRESS TranslatedAddress)
-{
- return 0;
-}
-
-
-PBUS_HANDLER
-HalpAllocateBusHandler(INTERFACE_TYPE InterfaceType,
- BUS_DATA_TYPE BusDataType,
- ULONG BusNumber)
-{
- PBUS_HANDLER BusHandler = NULL;
-
- DPRINT("HalpAllocateBusHandler()\n");
-
- BusHandler = ExAllocatePoolWithTag(NonPagedPool,
- sizeof(BUS_HANDLER),
- TAG_BUS);
- if (BusHandler == NULL)
- return NULL;
-
- RtlZeroMemory(BusHandler,
- sizeof(BUS_HANDLER));
-
- InsertTailList(&HalpBusHandlerList,
- &BusHandler->Entry);
-
- BusHandler->InterfaceType = InterfaceType;
- BusHandler->BusDataType = BusDataType;
- BusHandler->BusNumber = BusNumber;
-
- /* initialize default bus handler functions */
- BusHandler->GetBusData = HalpNoBusData;
- BusHandler->SetBusData = HalpNoBusData;
- BusHandler->AdjustResourceList = HalpNoAdjustResourceList;
- BusHandler->AssignSlotResources = HalpNoAssignSlotResources;
- BusHandler->GetInterruptVector = HalpNoGetInterruptVector;
- BusHandler->TranslateBusAddress = HalpNoTranslateBusAddress;
-
- /* any more ?? */
-
- DPRINT("HalpAllocateBusHandler() done\n");
-
- return BusHandler;
-}
-
-
-VOID
-HalpInitBusHandlers(VOID)
-{
- PBUS_HANDLER BusHandler;
-
- /* General preparations */
- KeInitializeSpinLock(&HalpBusHandlerSpinLock);
- InitializeListHead(&HalpBusHandlerList);
-
- /* Initialize hal dispatch tables */
- HalQuerySystemInformation = HalpQuerySystemInformation;
-
-#if 0
- HalSetSystemInformation = HalpSetSystemInformation;
-
- HalQueryBusSlots = HalpQueryBusSlots;
-#endif
-
- /* Add system bus handler */
- BusHandler = HalpAllocateBusHandler(Internal,
- ConfigurationSpaceUndefined,
- 0);
- if (BusHandler == NULL)
- return;
- BusHandler->GetInterruptVector =
- (pGetInterruptVector)HalpGetSystemInterruptVector;
- BusHandler->TranslateBusAddress =
- (pTranslateBusAddress)HalpTranslateSystemBusAddress;
-
- /* Add cmos bus handler */
- BusHandler = HalpAllocateBusHandler(InterfaceTypeUndefined,
- Cmos,
- 0);
- if (BusHandler == NULL)
- return;
- BusHandler->GetBusData = (pGetSetBusData)HalpGetCmosData;
- BusHandler->SetBusData = (pGetSetBusData)HalpSetCmosData;
-
- /* Add isa bus handler */
- BusHandler = HalpAllocateBusHandler(Isa,
- ConfigurationSpaceUndefined,
- 0);
- if (BusHandler == NULL)
- return;
-
- BusHandler->GetInterruptVector =
- (pGetInterruptVector)HalpGetIsaInterruptVector;
- BusHandler->TranslateBusAddress =
- (pTranslateBusAddress)HalpTranslateIsaBusAddress;
-
- /* Add MicroChannel bus handler */
- BusHandler = HalpAllocateBusHandler(MicroChannel,
- Pos,
- 0);
- if (BusHandler == NULL)
- return;
-
- BusHandler->GetBusData = (pGetSetBusData)HalpGetMicroChannelData;
-}
-
-
-PBUS_HANDLER FASTCALL
-HaliHandlerForBus(INTERFACE_TYPE InterfaceType,
- ULONG BusNumber)
-{
- PBUS_HANDLER BusHandler;
- PLIST_ENTRY CurrentEntry;
- KIRQL OldIrql;
-
- KeAcquireSpinLock(&HalpBusHandlerSpinLock,
- &OldIrql);
-
- CurrentEntry = HalpBusHandlerList.Flink;
- while (CurrentEntry != &HalpBusHandlerList)
- {
- BusHandler = (PBUS_HANDLER)CurrentEntry;
- if (BusHandler->InterfaceType == InterfaceType &&
- BusHandler->BusNumber == BusNumber)
- {
- KeReleaseSpinLock(&HalpBusHandlerSpinLock,
- OldIrql);
- return BusHandler;
- }
- CurrentEntry = CurrentEntry->Flink;
- }
- KeReleaseSpinLock(&HalpBusHandlerSpinLock,
- OldIrql);
-
- return NULL;
-}
-
-
-PBUS_HANDLER FASTCALL
-HaliHandlerForConfigSpace(BUS_DATA_TYPE BusDataType,
- ULONG BusNumber)
-{
- PBUS_HANDLER BusHandler;
- PLIST_ENTRY CurrentEntry;
- KIRQL OldIrql;
-
- KeAcquireSpinLock(&HalpBusHandlerSpinLock,
- &OldIrql);
-
- CurrentEntry = HalpBusHandlerList.Flink;
- while (CurrentEntry != &HalpBusHandlerList)
- {
- BusHandler = (PBUS_HANDLER)CurrentEntry;
- if (BusHandler->BusDataType == BusDataType &&
- BusHandler->BusNumber == BusNumber)
- {
- KeReleaseSpinLock(&HalpBusHandlerSpinLock,
- OldIrql);
- return BusHandler;
- }
- CurrentEntry = CurrentEntry->Flink;
- }
- KeReleaseSpinLock(&HalpBusHandlerSpinLock,
- OldIrql);
-
- return NULL;
-}
-
-
-PBUS_HANDLER FASTCALL
-HaliReferenceHandlerForBus(INTERFACE_TYPE InterfaceType,
- ULONG BusNumber)
-{
- PBUS_HANDLER BusHandler;
- PLIST_ENTRY CurrentEntry;
- KIRQL OldIrql;
-
- KeAcquireSpinLock(&HalpBusHandlerSpinLock,
- &OldIrql);
-
- CurrentEntry = HalpBusHandlerList.Flink;
- while (CurrentEntry != &HalpBusHandlerList)
- {
- BusHandler = (PBUS_HANDLER)CurrentEntry;
- if (BusHandler->InterfaceType == InterfaceType &&
- BusHandler->BusNumber == BusNumber)
- {
- BusHandler->RefCount++;
- KeReleaseSpinLock(&HalpBusHandlerSpinLock,
- OldIrql);
- return BusHandler;
- }
- CurrentEntry = CurrentEntry->Flink;
- }
- KeReleaseSpinLock(&HalpBusHandlerSpinLock,
- OldIrql);
-
- return NULL;
-}
-
-
-PBUS_HANDLER FASTCALL
-HaliReferenceHandlerForConfigSpace(BUS_DATA_TYPE BusDataType,
- ULONG BusNumber)
-{
- PBUS_HANDLER BusHandler;
- PLIST_ENTRY CurrentEntry;
- KIRQL OldIrql;
-
- KeAcquireSpinLock(&HalpBusHandlerSpinLock,
- &OldIrql);
-
- CurrentEntry = HalpBusHandlerList.Flink;
- while (CurrentEntry != &HalpBusHandlerList)
- {
- BusHandler = (PBUS_HANDLER)CurrentEntry;
- if (BusHandler->BusDataType == BusDataType &&
- BusHandler->BusNumber == BusNumber)
- {
- BusHandler->RefCount++;
- KeReleaseSpinLock(&HalpBusHandlerSpinLock,
- OldIrql);
- return BusHandler;
- }
- CurrentEntry = CurrentEntry->Flink;
- }
- KeReleaseSpinLock(&HalpBusHandlerSpinLock,
- OldIrql);
-
- return NULL;
-}
-
-
-VOID FASTCALL
-HaliDereferenceBusHandler(PBUS_HANDLER BusHandler)
-{
- KIRQL OldIrql;
-
- KeAcquireSpinLock(&HalpBusHandlerSpinLock,
- &OldIrql);
- BusHandler->RefCount--;
- KeReleaseSpinLock(&HalpBusHandlerSpinLock,
- OldIrql);
-}
-
-
-NTSTATUS STDCALL
-HalAdjustResourceList(PCM_RESOURCE_LIST Resources)
-{
- PBUS_HANDLER BusHandler;
- NTSTATUS Status;
-
- BusHandler = HaliReferenceHandlerForBus(Resources->List[0].InterfaceType,
- Resources->List[0].BusNumber);
- if (BusHandler == NULL)
- return STATUS_SUCCESS;
-
- Status = BusHandler->AdjustResourceList(BusHandler,
- Resources->List[0].BusNumber,
- Resources);
- HaliDereferenceBusHandler (BusHandler);
-
- return Status;
-}
-
-
-NTSTATUS STDCALL
-HalAssignSlotResources(PUNICODE_STRING RegistryPath,
- PUNICODE_STRING DriverClassName,
- PDRIVER_OBJECT DriverObject,
- PDEVICE_OBJECT DeviceObject,
- INTERFACE_TYPE BusType,
- ULONG BusNumber,
- ULONG SlotNumber,
- PCM_RESOURCE_LIST *AllocatedResources)
-{
- PBUS_HANDLER BusHandler;
- NTSTATUS Status;
-
- BusHandler = HaliReferenceHandlerForBus(BusType,
- BusNumber);
- if (BusHandler == NULL)
- return STATUS_NOT_FOUND;
-
- Status = BusHandler->AssignSlotResources(BusHandler,
- BusNumber,
- RegistryPath,
- DriverClassName,
- DriverObject,
- DeviceObject,
- SlotNumber,
- AllocatedResources);
-
- HaliDereferenceBusHandler(BusHandler);
-
- return Status;
-}
-
-
-ULONG STDCALL
-HalGetBusData(BUS_DATA_TYPE BusDataType,
- ULONG BusNumber,
- ULONG SlotNumber,
- PVOID Buffer,
- ULONG Length)
-{
- return (HalGetBusDataByOffset(BusDataType,
- BusNumber,
- SlotNumber,
- Buffer,
- 0,
- Length));
-}
-
-
-ULONG STDCALL
-HalGetBusDataByOffset(BUS_DATA_TYPE BusDataType,
- ULONG BusNumber,
- ULONG SlotNumber,
- PVOID Buffer,
- ULONG Offset,
- ULONG Length)
-{
- PBUS_HANDLER BusHandler;
- ULONG Result;
-
- BusHandler = HaliReferenceHandlerForConfigSpace(BusDataType,
- BusNumber);
- if (BusHandler == NULL)
- return 0;
-
- Result = BusHandler->GetBusData(BusHandler,
- BusNumber,
- SlotNumber,
- Buffer,
- Offset,
- Length);
-
- HaliDereferenceBusHandler (BusHandler);
-
- return Result;
-}
-
-
-ULONG STDCALL
-HalGetInterruptVector(INTERFACE_TYPE InterfaceType,
- ULONG BusNumber,
- ULONG BusInterruptLevel,
- ULONG BusInterruptVector,
- PKIRQL Irql,
- PKAFFINITY Affinity)
-{
- PBUS_HANDLER BusHandler;
- ULONG Result;
-
- BusHandler = HaliReferenceHandlerForBus(InterfaceType,
- BusNumber);
- if (BusHandler == NULL)
- return 0;
-
- Result = BusHandler->GetInterruptVector(BusHandler,
- BusNumber,
- BusInterruptLevel,
- BusInterruptVector,
- Irql,
- Affinity);
-
- HaliDereferenceBusHandler(BusHandler);
-
- return Result;
-}
-
-
-ULONG STDCALL
-HalSetBusData(BUS_DATA_TYPE BusDataType,
- ULONG BusNumber,
- ULONG SlotNumber,
- PVOID Buffer,
- ULONG Length)
-{
- return (HalSetBusDataByOffset(BusDataType,
- BusNumber,
- SlotNumber,
- Buffer,
- 0,
- Length));
-}
-
-
-ULONG STDCALL
-HalSetBusDataByOffset(BUS_DATA_TYPE BusDataType,
- ULONG BusNumber,
- ULONG SlotNumber,
- PVOID Buffer,
- ULONG Offset,
- ULONG Length)
-{
- PBUS_HANDLER BusHandler;
- ULONG Result;
-
- BusHandler = HaliReferenceHandlerForConfigSpace(BusDataType,
- BusNumber);
- if (BusHandler == NULL)
- return 0;
-
- Result = BusHandler->SetBusData(BusHandler,
- BusNumber,
- SlotNumber,
- Buffer,
- Offset,
- Length);
-
- HaliDereferenceBusHandler(BusHandler);
-
- return Result;
-}
-
-
-BOOLEAN STDCALL
-HalTranslateBusAddress(INTERFACE_TYPE InterfaceType,
- ULONG BusNumber,
- PHYSICAL_ADDRESS BusAddress,
- PULONG AddressSpace,
- PPHYSICAL_ADDRESS TranslatedAddress)
-{
- PBUS_HANDLER BusHandler;
- BOOLEAN Result;
-
- BusHandler = HaliReferenceHandlerForBus(InterfaceType,
- BusNumber);
- if (BusHandler == NULL)
- return FALSE;
-
- Result = (BOOLEAN)BusHandler->TranslateBusAddress(BusHandler,
- BusNumber,
- BusAddress,
- AddressSpace,
- TranslatedAddress);
-
- HaliDereferenceBusHandler(BusHandler);
-
- return Result;
-}
-
-/* EOF */
reactos/hal/halx86
diff -N display.c
--- display.c 31 Oct 2004 19:45:16 -0000 1.18
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,790 +0,0 @@
-/*
- * ReactOS kernel
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/* $Id: display.c,v 1.18 2004/10/31 19:45:16 ekohl Exp $
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/x86/display.c
- * PURPOSE: Blue screen display
- * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
- * UPDATE HISTORY:
- * Created 08/10/99
- */
-
-/*
- * Portions of this code are from the XFree86 Project and available from the
- * following license:
- *
- * Copyright (C) 1994-2003 The XFree86 Project, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
- * NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the XFree86 Project shall
- * not be used in advertising or otherwise to promote the sale, use or other
- * dealings in this Software without prior written authorization from the
- * XFree86 Project.
-*/
-
-/* DISPLAY OWNERSHIP
- *
- * So, who owns the physical display and is allowed to write to it?
- *
- * In MS NT, upon boot HAL owns the display. Somewhere in the boot
- * sequence (haven't figured out exactly where or by who), some
- * component calls HalAcquireDisplayOwnership. From that moment on,
- * the display is owned by that component and is switched to graphics
- * mode. The display is not supposed to return to text mode, except
- * in case of a bug check. The bug check will call HalDisplayString
- * to output a string to the text screen. HAL will notice that it
- * currently doesn't own the display and will re-take ownership, by
- * calling the callback function passed to HalAcquireDisplayOwnership.
- * After the bugcheck, execution is halted. So, under NT, the only
- * possible sequence of display modes is text mode -> graphics mode ->
- * text mode (the latter hopefully happening very infrequently).
- *
- * Things are a little bit different in the current state of ReactOS.
- * We want to have a functional interactive text mode. We should be
- * able to switch from text mode to graphics mode when a GUI app is
- * started and switch back to text mode when it's finished. Then, when
- * another GUI app is started, another switch to and from graphics mode
- * is possible. Also, when the system bugchecks in graphics mode we want
- * to switch back to text mode to show the registers and stack trace.
- * Last but not least, HalDisplayString is used a lot more in ReactOS,
- * e.g. to print debug messages when the /DEBUGPORT=SCREEN boot option
- * is present.
- * 3 Components are involved in Reactos: HAL, BLUE.SYS and VIDEOPRT.SYS.
- * As in NT, on boot HAL owns the display. When entering the text mode
- * command interpreter, BLUE.SYS kicks in. It will write directly to the
- * screen, more or less behind HALs back.
- * When a GUI app is started, WIN32K.SYS will open the DISPLAY device.
- * This open call will end up in VIDEOPRT.SYS. That component will then
- * take ownership of the display by calling HalAcquireDisplayOwnership.
- * When the GUI app terminates (WIN32K.SYS will close the DISPLAY device),
- * we want to give ownership of the display back to HAL. Using the
- * standard exported HAL functions, that's a bit of a problem, because
- * there is no function defined to do that. In NT, this is handled by
- * HalDisplayString, but that solution isn't satisfactory in ReactOS,
- * because HalDisplayString is (in some cases) also used to output debug
- * messages. If we do it the NT way, the first debug message output while
- * in graphics mode would switch the display back to text mode.
- * So, instead, if HalDisplayString detects that HAL doesn't have ownership
- * of the display, it doesn't do anything.
- * To return ownership to HAL, a new function is exported,
- * HalReleaseDisplayOwnership. This function is called by the DISPLAY
- * device Close routine in VIDEOPRT.SYS. It is also called at the beginning
- * of a bug check, so HalDisplayString is activated again.
- * Now, while the display is in graphics mode (not owned by HAL), BLUE.SYS
- * should also refrain from writing to the screen buffer. The text mode
- * screen buffer might overlap the graphics mode screen buffer, so changing
- * something in the text mode buffer might mess up the graphics screen. To
- * allow BLUE.SYS to detect if HAL owns the display, another new function is
- * exported, HalQueryDisplayOwnership. BLUE.SYS will call this function to
- * check if it's allowed to touch the text mode buffer.
- *
- * In an ideal world, when HAL takes ownership of the display, it should set
- * up the CRT using real-mode (actually V86 mode, but who cares) INT 0x10
- * calls. Unfortunately, this will require HAL to setup a real-mode interrupt
- * table etc. So, we chickened out of that by having the loader set up the
- * display before switching to protected mode. If HAL is given back ownership
- * after a GUI app terminates, the INT 0x10 calls are made by VIDEOPRT.SYS,
- * since there is already support for them via the VideoPortInt10 routine.
- */
-
-#include <ddk/ntddk.h>
-#include <hal.h>
-
-#define SCREEN_SYNCHRONIZATION
-
-#define VGA_AC_INDEX 0x3c0
-#define VGA_AC_READ 0x3c1
-#define VGA_AC_WRITE 0x3c0
-
-#define VGA_MISC_WRITE 0x3c2
-
-#define VGA_SEQ_INDEX 0x3c4
-#define VGA_SEQ_DATA 0x3c5
-
-#define VGA_DAC_MASK 0x3c6
-#define VGA_DAC_READ_INDEX 0x3c7
-#define VGA_DAC_WRITE_INDEX 0x3c8
-#define VGA_DAC_DATA 0x3c9
-#define VGA_FEATURE_READ 0x3ca
-#define VGA_MISC_READ 0x3cc
-
-#define VGA_GC_INDEX 0x3ce
-#define VGA_GC_DATA 0x3cf
-
-#define VGA_CRTC_INDEX 0x3d4
-#define VGA_CRTC_DATA 0x3d5
-
-#define VGA_INSTAT_READ 0x3da
-
-#define VGA_SEQ_NUM_REGISTERS 5
-#define VGA_CRTC_NUM_REGISTERS 25
-#define VGA_GC_NUM_REGISTERS 9
-#define VGA_AC_NUM_REGISTERS 21
-
-#define CRTC_COLUMNS 0x01
-#define CRTC_OVERFLOW 0x07
-#define CRTC_ROWS 0x12
-#define CRTC_SCANLINES 0x09
-
-#define CRTC_CURHI 0x0e
-#define CRTC_CURLO 0x0f
-
-
-#define CHAR_ATTRIBUTE_BLACK 0x00 /* black on black */
-#define CHAR_ATTRIBUTE 0x17 /* grey on blue */
-
-#define FONT_AMOUNT (8*8192)
-
-/* VARIABLES ****************************************************************/
-
-static ULONG CursorX = 0; /* Cursor Position */
-static ULONG CursorY = 0;
-static ULONG SizeX = 80; /* Display size */
-static ULONG SizeY = 25;
-
-static BOOLEAN DisplayInitialized = FALSE;
-static BOOLEAN HalOwnsDisplay = TRUE;
-
-static PUSHORT VideoBuffer = NULL;
-static PUCHAR GraphVideoBuffer = NULL;
-
-static PHAL_RESET_DISPLAY_PARAMETERS HalResetDisplayParameters = NULL;
-
-static UCHAR SavedTextPalette[768];
-static UCHAR SavedTextMiscOutReg;
-static UCHAR SavedTextCrtcReg[VGA_CRTC_NUM_REGISTERS];
-static UCHAR SavedTextAcReg[VGA_AC_NUM_REGISTERS];
-static UCHAR SavedTextGcReg[VGA_GC_NUM_REGISTERS];
-static UCHAR SavedTextSeqReg[VGA_SEQ_NUM_REGISTERS];
-static UCHAR SavedTextFont[2][FONT_AMOUNT];
-static BOOLEAN TextPaletteEnabled = FALSE;
-
-/* PRIVATE FUNCTIONS *********************************************************/
-
-VOID FASTCALL
-HalClearDisplay (UCHAR CharAttribute)
-{
- WORD *ptr = (WORD*)VideoBuffer;
- ULONG i;
-
- for (i = 0; i < SizeX * SizeY; i++, ptr++)
- *ptr = ((CharAttribute << 8) + ' ');
-
- CursorX = 0;
- CursorY = 0;
-}
-
-
-/* STATIC FUNCTIONS *********************************************************/
-
-VOID STATIC
-HalScrollDisplay (VOID)
-{
- PUSHORT ptr;
- int i;
-
- ptr = VideoBuffer + SizeX;
- RtlMoveMemory(VideoBuffer,
- ptr,
- SizeX * (SizeY - 1) * 2);
-
- ptr = VideoBuffer + (SizeX * (SizeY - 1));
- for (i = 0; i < (int)SizeX; i++, ptr++)
- {
- *ptr = (CHAR_ATTRIBUTE << 8) + ' ';
- }
-}
-
-VOID STATIC FASTCALL
-HalPutCharacter (CHAR Character)
-{
- PUSHORT ptr;
-
- ptr = VideoBuffer + ((CursorY * SizeX) + CursorX);
- *ptr = (CHAR_ATTRIBUTE << 8) + Character;
-}
-
-VOID STATIC
-HalDisablePalette(VOID)
-{
- (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
- WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, 0x20);
- TextPaletteEnabled = FALSE;
-}
-
-VOID STATIC
-HalEnablePalette(VOID)
-{
- (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
- WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, 0x00);
- TextPaletteEnabled = TRUE;
-}
-
-UCHAR STATIC FASTCALL
-HalReadGc(ULONG Index)
-{
- WRITE_PORT_UCHAR((PUCHAR)VGA_GC_INDEX, (UCHAR)Index);
- return(READ_PORT_UCHAR((PUCHAR)VGA_GC_DATA));
-}
-
-VOID STATIC FASTCALL
-HalWriteGc(ULONG Index, UCHAR Value)
-{
- WRITE_PORT_UCHAR((PUCHAR)VGA_GC_INDEX, (UCHAR)Index);
- WRITE_PORT_UCHAR((PUCHAR)VGA_GC_DATA, Value);
-}
-
-UCHAR STATIC FASTCALL
-HalReadSeq(ULONG Index)
-{
- WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_INDEX, (UCHAR)Index);
- return(READ_PORT_UCHAR((PUCHAR)VGA_SEQ_DATA));
-}
-
-VOID STATIC FASTCALL
-HalWriteSeq(ULONG Index, UCHAR Value)
-{
- WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_INDEX, (UCHAR)Index);
- WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_DATA, Value);
-}
-
-VOID STATIC FASTCALL
-HalWriteAc(ULONG Index, UCHAR Value)
-{
- if (TextPaletteEnabled)
- {
- Index &= ~0x20;
- }
- else
- {
- Index |= 0x20;
- }
- (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
- WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, (UCHAR)Index);
- WRITE_PORT_UCHAR((PUCHAR)VGA_AC_WRITE, Value);
-}
-
-UCHAR STATIC FASTCALL
-HalReadAc(ULONG Index)
-{
- if (TextPaletteEnabled)
- {
- Index &= ~0x20;
- }
- else
- {
- Index |= 0x20;
- }
- (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
- WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, (UCHAR)Index);
- return(READ_PORT_UCHAR((PUCHAR)VGA_AC_READ));
-}
-
-VOID STATIC FASTCALL
-HalWriteCrtc(ULONG Index, UCHAR Value)
-{
- WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, (UCHAR)Index);
- WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, Value);
-}
-
-UCHAR STATIC FASTCALL
-HalReadCrtc(ULONG Index)
-{
- WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, (UCHAR)Index);
- return(READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA));
-}
-
-VOID STATIC FASTCALL
-HalResetSeq(BOOLEAN Start)
-{
- if (Start)
- {
- HalWriteSeq(0x00, 0x01);
- }
- else
- {
- HalWriteSeq(0x00, 0x03);
- }
-}
-
-VOID STATIC FASTCALL
-HalBlankScreen(BOOLEAN On)
-{
- UCHAR Scrn;
-
- Scrn = HalReadSeq(0x01);
-
- if (On)
- {
- Scrn &= ~0x20;
- }
- else
- {
- Scrn |= 0x20;
- }
-
- HalResetSeq(TRUE);
- HalWriteSeq(0x01, Scrn);
- HalResetSeq(FALSE);
-}
-
-VOID STATIC
-HalSaveFont(VOID)
-{
- UCHAR Attr10;
- UCHAR MiscOut, Gc4, Gc5, Gc6, Seq2, Seq4;
- ULONG i;
-
- /* Check if we are already in graphics mode. */
- Attr10 = HalReadAc(0x10);
- if (Attr10 & 0x01)
- {
- return;
- }
-
- /* Save registers. */
- MiscOut = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ);
- Gc4 = HalReadGc(0x04);
- Gc5 = HalReadGc(0x05);
- Gc6 = HalReadGc(0x06);
- Seq2 = HalReadSeq(0x02);
- Seq4 = HalReadSeq(0x04);
-
- /* Force colour mode. */
- WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, (UCHAR)(MiscOut | 0x01));
-
- HalBlankScreen(FALSE);
-
- for (i = 0; i < 2; i++)
- {
- /* Save font 1 */
- HalWriteSeq(0x02, (UCHAR)(0x04 << i)); /* Write to plane 2 or 3 */
- HalWriteSeq(0x04, 0x06); /* Enable plane graphics. */
- HalWriteGc(0x04, (UCHAR)(0x02 + i)); /* Read plane 2 or 3 */
- HalWriteGc(0x05, 0x00); /* Write mode 0; read mode 0 */
- HalWriteGc(0x06, 0x05); /* Set graphics. */
- memcpy(SavedTextFont[i], GraphVideoBuffer, FONT_AMOUNT);
- }
-
- /* Restore registers. */
- HalWriteAc(0x10, Attr10);
- HalWriteSeq(0x02, Seq2);
- HalWriteSeq(0x04, Seq4);
- HalWriteGc(0x04, Gc4);
- HalWriteGc(0x05, Gc5);
- HalWriteGc(0x06, Gc6);
- WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, MiscOut);
-
- HalBlankScreen(TRUE);
-}
-
-VOID STATIC
-HalSaveMode(VOID)
-{
- ULONG i;
-
- SavedTextMiscOutReg = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ);
-
- for (i = 0; i < VGA_CRTC_NUM_REGISTERS; i++)
- {
- SavedTextCrtcReg[i] = HalReadCrtc(i);
- }
-
- HalEnablePalette();
- for (i = 0; i < VGA_AC_NUM_REGISTERS; i++)
- {
- SavedTextAcReg[i] = HalReadAc(i);
- }
- HalDisablePalette();
-
- for (i = 0; i < VGA_GC_NUM_REGISTERS; i++)
- {
- SavedTextGcReg[i] = HalReadGc(i);
- }
-
- for (i = 0; i < VGA_SEQ_NUM_REGISTERS; i++)
- {
- SavedTextSeqReg[i] = HalReadSeq(i);
- }
-}
-
-VOID STATIC
-HalDacDelay(VOID)
-{
- (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
- (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
-}
-
-VOID STATIC
-HalSavePalette(VOID)
-{
- ULONG i;
- WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_MASK, 0xFF);
- WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_READ_INDEX, 0x00);
- for (i = 0; i < 768; i++)
- {
- SavedTextPalette[i] = READ_PORT_UCHAR((PUCHAR)VGA_DAC_DATA);
- HalDacDelay();
- }
-}
-
-VOID STATIC
-HalRestoreFont(VOID)
-{
- UCHAR MiscOut, Attr10, Gc1, Gc3, Gc4, Gc5, Gc6, Gc8;
- UCHAR Seq2, Seq4;
- ULONG i;
-
- /* Save registers. */
- MiscOut = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ);
- Attr10 = HalReadAc(0x10);
- Gc1 = HalReadGc(0x01);
- Gc3 = HalReadGc(0x03);
- Gc4 = HalReadGc(0x04);
- Gc5 = HalReadGc(0x05);
- Gc6 = HalReadGc(0x06);
- Gc8 = HalReadGc(0x08);
- Seq2 = HalReadSeq(0x02);
- Seq4 = HalReadSeq(0x04);
-
- /* Force into colour mode. */
- WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, (UCHAR)(MiscOut | 0x10));
-
- HalBlankScreen(FALSE);
-
- HalWriteGc(0x03, 0x00); /* Don't rotate; write unmodified. */
- HalWriteGc(0x08, 0xFF); /* Write all bits. */
- HalWriteGc(0x01, 0x00); /* All planes from CPU. */
-
- for (i = 0; i < 2; i++)
- {
- HalWriteSeq(0x02, (UCHAR)(0x04 << i)); /* Write to plane 2 or 3 */
- HalWriteSeq(0x04, 0x06); /* Enable plane graphics. */
- HalWriteGc(0x04, (UCHAR)(0x02 + i)); /* Read plane 2 or 3 */
- HalWriteGc(0x05, 0x00); /* Write mode 0; read mode 0. */
- HalWriteGc(0x06, 0x05); /* Set graphics. */
- memcpy(GraphVideoBuffer, SavedTextFont[i], FONT_AMOUNT);
- }
-
- HalBlankScreen(TRUE);
-
- /* Restore registers. */
- WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, MiscOut);
- HalWriteAc(0x10, Attr10);
- HalWriteGc(0x01, Gc1);
- HalWriteGc(0x03, Gc3);
- HalWriteGc(0x04, Gc4);
- HalWriteGc(0x05, Gc5);
- HalWriteGc(0x06, Gc6);
- HalWriteGc(0x08, Gc8);
- HalWriteSeq(0x02, Seq2);
- HalWriteSeq(0x04, Seq4);
-}
-
-VOID STATIC
-HalRestoreMode(VOID)
-{
- ULONG i;
-
- WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, SavedTextMiscOutReg);
-
- for (i = 1; i < VGA_SEQ_NUM_REGISTERS; i++)
- {
- HalWriteSeq(i, SavedTextSeqReg[i]);
- }
-
- /* Unlock CRTC registers 0-7 */
- HalWriteCrtc(17, (UCHAR)(SavedTextCrtcReg[17] & ~0x80));
-
- for (i = 0; i < VGA_CRTC_NUM_REGISTERS; i++)
- {
- HalWriteCrtc(i, SavedTextCrtcReg[i]);
- }
-
- for (i = 0; i < VGA_GC_NUM_REGISTERS; i++)
- {
- HalWriteGc(i, SavedTextGcReg[i]);
- }
-
- HalEnablePalette();
- for (i = 0; i < VGA_AC_NUM_REGISTERS; i++)
- {
- HalWriteAc(i, SavedTextAcReg[i]);
- }
- HalDisablePalette();
-}
-
-VOID STATIC
-HalRestorePalette(VOID)
-{
- ULONG i;
- WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_MASK, 0xFF);
- WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_WRITE_INDEX, 0x00);
- for (i = 0; i < 768; i++)
- {
- WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_DATA, SavedTextPalette[i]);
- HalDacDelay();
- }
- HalDisablePalette();
-}
-
-/* PRIVATE FUNCTIONS ********************************************************/
-
-VOID FASTCALL
-HalInitializeDisplay (PLOADER_PARAMETER_BLOCK LoaderBlock)
-/*
- * FUNCTION: Initalize the display
- * ARGUMENTS:
- * InitParameters = Parameters setup by the boot loader
- */
-{
- if (DisplayInitialized == FALSE)
- {
- ULONG ScanLines;
- ULONG Data;
-
- VideoBuffer = (PUSHORT)(0xff3b8000);
- GraphVideoBuffer = (PUCHAR)(0xff3a0000);
-
- /* Set cursor position */
-// CursorX = LoaderBlock->cursorx;
-// CursorY = LoaderBlock->cursory;
- CursorX = 0;
- CursorY = 0;
-
- /* read screen size from the crtc */
- /* FIXME: screen size should be read from the boot parameters */
- WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_COLUMNS);
- SizeX = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA) + 1;
- WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_ROWS);
- SizeY = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA);
- WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_OVERFLOW);
- Data = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA);
- SizeY |= (((Data & 0x02) << 7) | ((Data & 0x40) << 3));
- SizeY++;
- WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_SCANLINES);
- ScanLines = (READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA) & 0x1F) + 1;
- SizeY = SizeY / ScanLines;
-
-#ifdef BOCHS_30ROWS
- SizeY=30;
-#endif
- HalClearDisplay(CHAR_ATTRIBUTE_BLACK);
-
- DisplayInitialized = TRUE;
-
- /*
- Save the VGA state at this point so we can restore it on a bugcheck.
- */
- HalSavePalette();
- HalSaveMode();
- HalSaveFont();
- }
-}
-
-
-/* PUBLIC FUNCTIONS *********************************************************/
-
-VOID STDCALL
-HalReleaseDisplayOwnership(VOID)
-/*
- * FUNCTION: Release ownership of display back to HAL
- */
-{
- if (HalResetDisplayParameters == NULL)
- return;
-
- if (HalOwnsDisplay == TRUE)
- return;
-
- if (!HalResetDisplayParameters(SizeX, SizeY))
- {
- HalRestoreMode();
- HalRestoreFont();
- HalRestorePalette();
- }
- HalOwnsDisplay = TRUE;
- HalClearDisplay(CHAR_ATTRIBUTE);
-}
-
-
-VOID STDCALL
-HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters)
-/*
- * FUNCTION:
- * ARGUMENTS:
- * ResetDisplayParameters = Pointer to a driver specific
- * reset routine.
- */
-{
- HalOwnsDisplay = FALSE;
- HalResetDisplayParameters = ResetDisplayParameters;
-}
-
-VOID STDCALL
-HalDisplayString(IN PCH String)
-/*
- * FUNCTION: Switches the screen to HAL console mode (BSOD) if not there
- * already and displays a string
- * ARGUMENT:
- * string = ASCII string to display
- * NOTE: Use with care because there is no support for returning from BSOD
- * mode
- */
-{
- PCH pch;
-#ifdef SCREEN_SYNCHRONIZATION
- int offset;
-#endif
- static KSPIN_LOCK Lock;
- KIRQL OldIrql;
- ULONG Flags;
-
- /* See comment at top of file */
- if (!HalOwnsDisplay)
- {
- return;
- }
-
- pch = String;
-
- OldIrql = KfRaiseIrql(HIGH_LEVEL);
- KiAcquireSpinLock(&Lock);
-
- Ki386SaveFlags(Flags);
- Ki386DisableInterrupts();
-
-
-#if 0
- if (HalOwnsDisplay == FALSE)
- {
- HalReleaseDisplayOwnership();
- }
-#endif
-
-#ifdef SCREEN_SYNCHRONIZATION
- WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURHI);
- offset = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA)<<8;
- WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURLO);
- offset += READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA);
-
- CursorY = offset / SizeX;
- CursorX = offset % SizeX;
-#endif
-
- while (*pch != 0)
- {
- if (*pch == '\n')
- {
- CursorY++;
- CursorX = 0;
- }
- else if (*pch == '\b')
- {
- if (CursorX > 0)
- {
- CursorX--;
- }
- }
- else if (*pch != '\r')
- {
- HalPutCharacter (*pch);
- CursorX++;
-
- if (CursorX >= SizeX)
- {
- CursorY++;
- CursorX = 0;
- }
- }
-
- if (CursorY >= SizeY)
- {
- HalScrollDisplay ();
- CursorY = SizeY - 1;
- }
-
- pch++;
- }
-
-#ifdef SCREEN_SYNCHRONIZATION
- offset = (CursorY * SizeX) + CursorX;
-
- WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURLO);
- WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, (UCHAR)(offset & 0xff));
- WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURHI);
- WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, (UCHAR)((offset >> 8) & 0xff));
-#endif
- Ki386RestoreFlags(Flags);
-
- KiReleaseSpinLock(&Lock);
- KfLowerIrql(OldIrql);
-}
-
-VOID STDCALL
-HalQueryDisplayParameters(OUT PULONG DispSizeX,
- OUT PULONG DispSizeY,
- OUT PULONG CursorPosX,
- OUT PULONG CursorPosY)
-{
- if (DispSizeX)
- *DispSizeX = SizeX;
- if (DispSizeY)
- *DispSizeY = SizeY;
- if (CursorPosX)
- *CursorPosX = CursorX;
- if (CursorPosY)
- *CursorPosY = CursorY;
-}
-
-
-VOID STDCALL
-HalSetDisplayParameters(IN ULONG CursorPosX,
- IN ULONG CursorPosY)
-{
- CursorX = (CursorPosX < SizeX) ? CursorPosX : SizeX - 1;
- CursorY = (CursorPosY < SizeY) ? CursorPosY : SizeY - 1;
-}
-
-
-BOOLEAN STDCALL
-HalQueryDisplayOwnership(VOID)
-{
- return !HalOwnsDisplay;
-}
-
-/* EOF */
reactos/hal/halx86
diff -N dma.c
--- dma.c 21 Nov 2004 21:53:06 -0000 1.10
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,445 +0,0 @@
-/* $Id: dma.c,v 1.10 2004/11/21 21:53:06 ion Exp $
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/x86/dma.c
- * PURPOSE: DMA functions
- * PROGRAMMERS: David Welch (welch@mcmail.com)
- * UPDATE HISTORY:
- * Created 22/05/98
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ddk/ntddk.h>
-#define NDEBUG
-#include <internal/debug.h>
-#include <hal.h>
-
-/* Adapters for each channel */
-PADAPTER_OBJECT HalpEisaAdapter[8];
-
-/* FUNCTIONS *****************************************************************/
-
-VOID
-HalpInitDma (VOID)
-{
- /* TODO: Initialize the first Map Buffer */
-}
-
-PVOID STDCALL
-HalAllocateCommonBuffer (PADAPTER_OBJECT AdapterObject,
- ULONG Length,
- PPHYSICAL_ADDRESS LogicalAddress,
- BOOLEAN CacheEnabled)
-/*
- * FUNCTION: Allocates memory that is visible to both the processor(s) and
- * a dma device
- * ARGUMENTS:
- * AdapterObject = Adapter object representing the bus master or
- * system dma controller
- * Length = Number of bytes to allocate
- * LogicalAddress = Logical address the driver can use to access the
- * buffer
- * CacheEnabled = Specifies if the memory can be cached
- * RETURNS: The base virtual address of the memory allocated
- * NULL on failure
- * NOTES:
- * CacheEnabled is ignored - it's all cache-disabled (like in NT)
- * UPDATE: It's not ignored now. If that's wrong just modify the
- * CacheEnabled comparsion below.
- */
-{
- PHYSICAL_ADDRESS LowestAddress, HighestAddress, BoundryAddressMultiple;
- PVOID BaseAddress;
-
- LowestAddress.QuadPart = 0;
- BoundryAddressMultiple.QuadPart = 0;
- HighestAddress.u.HighPart = 0;
- if ((AdapterObject->Dma32BitAddresses) && (AdapterObject->MasterDevice)) {
- HighestAddress.u.LowPart = 0xFFFFFFFF; /* 32Bit: 4GB address range */
- } else {
- HighestAddress.u.LowPart = 0x00FFFFFF; /* 24Bit: 16MB address range */
- }
-
- BaseAddress = MmAllocateContiguousAlignedMemory(
- Length,
- LowestAddress,
- HighestAddress,
- BoundryAddressMultiple,
- CacheEnabled ? MmCached : MmNonCached,
- 0x10000 );
- if (!BaseAddress)
- return 0;
-
- *LogicalAddress = MmGetPhysicalAddress(BaseAddress);
-
- return BaseAddress;
-}
-
-BOOLEAN STDCALL
-HalFlushCommonBuffer (ULONG Unknown1,
- ULONG Unknown2,
- ULONG Unknown3,
- ULONG Unknown4,
- ULONG Unknown5,
- ULONG Unknown6,
- ULONG Unknown7,
- ULONG Unknown8)
-{
- return TRUE;
-}
-
-VOID STDCALL
-HalFreeCommonBuffer (PADAPTER_OBJECT AdapterObject,
- ULONG Length,
- PHYSICAL_ADDRESS LogicalAddress,
- PVOID VirtualAddress,
- BOOLEAN CacheEnabled)
-{
- MmFreeContiguousMemory(VirtualAddress);
-}
-
-PADAPTER_OBJECT STDCALL
-HalGetAdapter (PDEVICE_DESCRIPTION DeviceDescription,
- PULONG NumberOfMapRegisters)
-/*
- * FUNCTION: Returns a pointer to an adapter object for the DMA device
- * defined in the device description structure
- * ARGUMENTS:
- * DeviceDescription = Structure describing the attributes of the device
- * NumberOfMapRegisters (OUT) = Returns the maximum number of map
- * registers the device driver can
- * allocate for DMA transfer operations
- * RETURNS: The allocated adapter object on success
- * NULL on failure
- * TODO:
- * Testing
- */
-{
- PADAPTER_OBJECT AdapterObject;
- DWORD ChannelSelect;
- DWORD Controller;
- ULONG MaximumLength;
- BOOLEAN ChannelSetup;
-
- DPRINT("Entered Function\n");
-
- /* Validate parameters in device description, and return a pointer to
- the adapter object for the requested dma channel */
- if(DeviceDescription->Version != DEVICE_DESCRIPTION_VERSION) {
- DPRINT("Invalid Adapter version!\n");
- return NULL;
- }
-
- DPRINT("Checking Interface Type: %x \n", DeviceDescription->InterfaceType);
- if (DeviceDescription->InterfaceType == PCIBus) {
- if (DeviceDescription->Master == FALSE) {
- DPRINT("Invalid request!\n");
- return NULL;
- }
- ChannelSetup = FALSE;
- }
-
- /* There are only 8 DMA channels on ISA, so any request above this
- should not get any channel setup */
- if (DeviceDescription->DmaChannel >= 8) {
- ChannelSetup = FALSE;
- }
-
- /* Channel 4 is Reserved for Chaining, so you cant use it */
- if (DeviceDescription->DmaChannel == 4 && ChannelSetup) {
- DPRINT("Invalid request!\n");
- return NULL;
- }
-
- /* Devices that support Scatter/Gather do not need Map Registers */
- if (DeviceDescription->ScatterGather &&
- (DeviceDescription->InterfaceType == Eisa ||
- DeviceDescription->InterfaceType == PCIBus)) {
- *NumberOfMapRegisters = 0;
- }
-
- /* Check if Extended DMA is available (we're just going to do a random read/write
- I picked Channel 2 because it's the first Channel in the Register */
- WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaController1Pages.Channel2), 0x2A);
- if (READ_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaController1Pages.Channel2)) == 0x2A) {
- HalpEisaDma = TRUE;
- }
-
- /* Find out how many Map Registers we need */
- DPRINT("Setting up Adapter Settings!\n");
- MaximumLength = DeviceDescription->MaximumLength & 0x7FFFFFFF;
- *NumberOfMapRegisters = BYTES_TO_PAGES(MaximumLength) + 1;
-
- /* Set the Channel Selection */
- ChannelSelect = DeviceDescription->DmaChannel & 0x03;
-
- /* Get the Controller Setup */
- Controller = (DeviceDescription->DmaChannel & 0x04) ? 1 : 2;
-
- /* Get the Adapter Object */
- if (HalpEisaAdapter[DeviceDescription->DmaChannel] != NULL) {
-
- /* Already allocated, return it */
- DPRINT("Getting an Adapter Object from the Cache\n");
- AdapterObject = HalpEisaAdapter[DeviceDescription->DmaChannel];
-
- /* Do we need more Map Registers this time? */
- if ((AdapterObject->NeedsMapRegisters) &&
- (*NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel)) {
- AdapterObject->MapRegistersPerChannel = *NumberOfMapRegisters;
- }
-
- } else {
-
- /* We have to allocate a new object! How exciting! */
- DPRINT("Allocating a new Adapter Object\n");
- AdapterObject = HalpAllocateAdapterEx(*NumberOfMapRegisters,
- FALSE,
- DeviceDescription->Dma32BitAddresses);
-
- if (AdapterObject == NULL) return NULL;
-
- HalpEisaAdapter[DeviceDescription->DmaChannel] = AdapterObject;
-
- if (!*NumberOfMapRegisters) {
- /* Easy case, no Map Registers needed */
- AdapterObject->NeedsMapRegisters = FALSE;
-
- /* If you're the master, you get all you want */
- if (DeviceDescription->Master) {
- AdapterObject->MapRegistersPerChannel= *NumberOfMapRegisters;
- } else {
- AdapterObject->MapRegistersPerChannel = 1;
- }
- } else {
- /* We Desire Registers */
- AdapterObject->NeedsMapRegisters = TRUE;
-
- /* The registers you want */
- AdapterObject->MapRegistersPerChannel = *NumberOfMapRegisters;
-
- /* Increase commitment */
- MasterAdapter->CommittedMapRegisters += *NumberOfMapRegisters;
- }
- }
-
- /* Set up DMA Structure */
- if (Controller == 1) {
- AdapterObject->AdapterBaseVa = (PVOID)FIELD_OFFSET(EISA_CONTROL, DmaController1);
- } else {
- AdapterObject->AdapterBaseVa = (PVOID)FIELD_OFFSET(EISA_CONTROL, DmaController2);
- }
-
- /* Set up Some Adapter Data */
- DPRINT("Setting up an Adapter Object\n");
- AdapterObject->IgnoreCount = DeviceDescription->IgnoreCount;
- AdapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses;
- AdapterObject->Dma64BitAddresses = DeviceDescription->Dma64BitAddresses;
- AdapterObject->ScatterGather = DeviceDescription->ScatterGather;
- AdapterObject->MasterDevice = DeviceDescription->Master;
- if (DeviceDescription->InterfaceType != PCIBus) AdapterObject->LegacyAdapter = TRUE;
-
- /* Everything below is not required if we don't need a channel */
- if (!ChannelSetup) {
- DPRINT("Retuning Adapter Object without Channel Setup\n");
- return AdapterObject;
- }
-
- AdapterObject->ChannelNumber = ChannelSelect;
-
-
- /* Set up the Page Port */
- if (Controller == 1) {
- switch (ChannelSelect) {
-
- case 0:
- AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel0));
- break;
- case 1:
- AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel1));
- break;
- case 2:
- AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel2));
- break;
- case 3:
- AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel3));
- break;
- }
-
- /* Set Controller Number */
- AdapterObject->AdapterNumber = 1;
- } else {
- switch (ChannelSelect) {
-
- case 1:
- AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel5));
- break;
- case 2:
- AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel6));
- break;
- case 3:
- AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel7));
- break;
- }
-
- /* Set Controller Number */
- AdapterObject->AdapterNumber = 2;
- }
-
- /* Set up the Extended Register */
- if (HalpEisaDma) {
- DMA_EXTENDED_MODE ExtendedMode;
-
- ExtendedMode.ChannelNumber = ChannelSelect;
-
- switch (DeviceDescription->DmaSpeed) {
-
- case Compatible:
- ExtendedMode.TimingMode = COMPATIBLE_TIMING;
- break;
-
- case TypeA:
- ExtendedMode.TimingMode = TYPE_A_TIMING;
- break;
-
- case TypeB:
- ExtendedMode.TimingMode = TYPE_B_TIMING;
- break;
-
- case TypeC:
- ExtendedMode.TimingMode = BURST_TIMING;
- break;
-
- default:
- return NULL;
- }
-
- switch (DeviceDescription->DmaWidth) {
-
- case Width8Bits:
- ExtendedMode.TransferSize = B_8BITS;
- break;
-
- case Width16Bits:
- ExtendedMode.TransferSize = B_16BITS;
- break;
-
- case Width32Bits:
- ExtendedMode.TransferSize = B_32BITS;
- break;
-
- default:
- return NULL;
- }
-
- if (Controller == 1) {
- WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaExtendedMode1),
- *((PUCHAR)&ExtendedMode));
- } else {
- WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaExtendedMode2),
- *((PUCHAR)&ExtendedMode));
- }
- }
- /* Do 8/16-bit validation */
- DPRINT("Validating an Adapter Object\n");
- if (!DeviceDescription->Master) {
- if ((DeviceDescription->DmaWidth == Width8Bits) && (Controller != 1)) {
- return NULL; /* 8-bit is only avalable on Controller 1 */
- } else if (DeviceDescription->DmaWidth == Width16Bits) {
- if (Controller != 2) {
- return NULL; /* 16-bit is only avalable on Controller 2 */
- } else {
- AdapterObject->Width16Bits = TRUE;
- }
- }
- }
- UCHAR DmaMode;
- DPRINT("Final DMA Request Mode Setting of the Adapter Object\n");
- /* Set the DMA Request Modes */
- if (DeviceDescription->Master) {
- /* This is a cascade request */
- ((PDMA_MODE)&DmaMode)->RequestMode = CASCADE_REQUEST_MODE;
-
- /* Send the request */
- if (AdapterObject->AdapterNumber == 1) {
- /* Set the Request Data */
- WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterObject->AdapterBaseVa)->Mode,
- AdapterObject->AdapterMode);
-
- /* Unmask DMA Channel */
- WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterObject->AdapterBaseVa)->SingleMask,
- AdapterObject->ChannelNumber | DMA_CLEARMASK);
- } else {
- /* Set the Request Data */
- WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterObject->AdapterBaseVa)->Mode,
- AdapterObject->AdapterMode);
-
- /* Unmask DMA Channel */
- WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterObject->AdapterBaseVa)->SingleMask,
- AdapterObject->ChannelNumber | DMA_CLEARMASK);
- }
- } else if (DeviceDescription->DemandMode) {
- /* This is a Demand request */
- ((PDMA_MODE)&DmaMode)->RequestMode = DEMAND_REQUEST_MODE;
- } else {
- /* Normal Request */
- ((PDMA_MODE)&DmaMode)->RequestMode = SINGLE_REQUEST_MODE;
- }
-
- /* Auto Initialize Enabled or Not*/
- ((PDMA_MODE)&DmaMode)->AutoInitialize = DeviceDescription->AutoInitialize;
- AdapterObject->AdapterMode = DmaMode;
- return AdapterObject;
-}
-
-ULONG STDCALL
-HalReadDmaCounter (PADAPTER_OBJECT AdapterObject)
-{
- KIRQL OldIrql;
- ULONG Count;
-
- KeAcquireSpinLock(&AdapterObject->MasterAdapter->SpinLock, &OldIrql);
-
- /* Send the Request to the specific controller */
- if (AdapterObject->AdapterNumber == 1) {
-
- /* Set this for Ease */
- PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
-
- /* Send Reset */
- WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
-
- /* Read Count */
- Count = READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
- [AdapterObject->ChannelNumber].DmaBaseCount);
- Count |= READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
- [AdapterObject->ChannelNumber].DmaBaseCount) << 8;
-
- } else {
-
- /* Set this for Ease */
- PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
-
- /* Send Reset */
- WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
-
- /* Read Count */
- Count = READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
- [AdapterObject->ChannelNumber].DmaBaseCount);
- Count |= READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
- [AdapterObject->ChannelNumber].DmaBaseCount) << 8;
- }
-
- /* Play around with the count (add bias and multiply by 2 if 16-bit DMA) */
- Count ++;
- if (AdapterObject->Width16Bits) Count *=2 ;
-
- KeReleaseSpinLock(&AdapterObject->MasterAdapter->SpinLock, OldIrql);
-
- /* Return it */
- return Count;
-}
-
-/* EOF */
reactos/hal/halx86
diff -N drive.c
--- drive.c 26 Feb 2003 14:14:03 -0000 1.4
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,31 +0,0 @@
-/* $Id: drive.c,v 1.4 2003/02/26 14:14:03 ekohl Exp $
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: hal/x86/drive.c
- * PURPOSE: Drive letter assignment
- * PROGRAMMER:
- * UPDATE HISTORY:
- * 2000-03-25
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ddk/ntddk.h>
-#include <internal/debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-VOID STDCALL
-IoAssignDriveLetters(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
- IN PSTRING NtDeviceName,
- OUT PUCHAR NtSystemPath,
- OUT PSTRING NtSystemPathString)
-{
- HalIoAssignDriveLetters(LoaderBlock,
- NtDeviceName,
- NtSystemPath,
- NtSystemPathString);
-}
-
-/* EOF */
reactos/hal/halx86
diff -N enum.c
--- enum.c 8 Sep 2002 10:22:24 -0000 1.5
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,25 +0,0 @@
-/* $Id: enum.c,v 1.5 2002/09/08 10:22:24 chorns Exp $
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/x86/enum.c
- * PURPOSE: Motherboard device enumerator
- * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
- * UPDATE HISTORY:
- * Created 01/05/2001
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ddk/ntddk.h>
-#include <roscfg.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-VOID
-HalpStartEnumerator (VOID)
-{
-}
-
-/* EOF */
reactos/hal/halx86
diff -N fmutex.c
--- fmutex.c 8 Sep 2002 10:22:24 -0000 1.5
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,53 +0,0 @@
-/* $Id: fmutex.c,v 1.5 2002/09/08 10:22:24 chorns Exp $
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/x86/fmutex.c
- * PURPOSE: Implements fast mutexes
- * PROGRAMMER: David Welch (welch@cwcom.net)
- * Eric Kohl (ekohl@rz-online.de)
- * UPDATE HISTORY:
- * Created 09/06/2000
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ddk/ntddk.h>
-
-#include <internal/debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-VOID FASTCALL
-ExAcquireFastMutex (PFAST_MUTEX FastMutex)
-{
- KeEnterCriticalRegion();
- ExAcquireFastMutexUnsafe(FastMutex);
-}
-
-
-VOID FASTCALL
-ExReleaseFastMutex (PFAST_MUTEX FastMutex)
-{
- ExReleaseFastMutexUnsafe(FastMutex);
- KeLeaveCriticalRegion();
-}
-
-
-BOOLEAN FASTCALL
-ExTryToAcquireFastMutex (PFAST_MUTEX FastMutex)
-{
- KeEnterCriticalRegion();
- if (InterlockedExchange(&FastMutex->Count, 0) == 1)
- {
- FastMutex->Owner = KeGetCurrentThread();
- return(TRUE);
- }
- else
- {
- KeLeaveCriticalRegion();
- return(FALSE);
- }
-}
-
-/* EOF */
reactos/hal/halx86
diff -N halinit.c
--- halinit.c 28 Nov 2004 01:30:01 -0000 1.10
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,82 +0,0 @@
-/* $Id: halinit.c,v 1.10 2004/11/28 01:30:01 hbirr Exp $
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/x86/halinit.c
- * PURPOSE: Initalize the x86 hal
- * PROGRAMMER: David Welch (welch@cwcom.net)
- * UPDATE HISTORY:
- * 11/06/98: Created
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ddk/ntddk.h>
-#include <roscfg.h>
-#include <hal.h>
-
-#ifdef MP
-#include <mps.h>
-#endif /* MP */
-
-#define NDEBUG
-#include <internal/debug.h>
-
-/* GLOBALS *****************************************************************/
-
-PVOID HalpZeroPageMapping = NULL;
-
-/* FUNCTIONS ***************************************************************/
-
-NTSTATUS
-STDCALL
-DriverEntry(
- PDRIVER_OBJECT DriverObject,
- PUNICODE_STRING RegistryPath)
-{
- return STATUS_SUCCESS;
-}
-
-BOOLEAN STDCALL
-HalInitSystem (ULONG BootPhase,
- PLOADER_PARAMETER_BLOCK LoaderBlock)
-{
- if (BootPhase == 0)
- {
- /* Initialize display and make the screen black */
- HalInitializeDisplay (LoaderBlock);
-
-#ifdef MP
-
- HalpInitMPS();
-
-#else
-
- HalpInitPICs();
-
- /* Setup busy waiting */
- HalpCalibrateStallExecution();
-
-#endif /* MP */
-
- }
- else if (BootPhase == 1)
- {
- HalpInitBusHandlers();
- HalpInitDma();
-
- /* Enumerate the devices on the motherboard */
- HalpStartEnumerator();
- }
- else if (BootPhase == 2)
- {
- /* Go to blue screen */
- HalClearDisplay (0x17); /* grey on blue */
-
- HalpZeroPageMapping = MmMapIoSpace((LARGE_INTEGER)0LL, PAGE_SIZE, MmNonCached);
- }
-
- return TRUE;
-}
-
-/* EOF */
reactos/hal/halx86
diff -N halx86mp.rc
--- halx86mp.rc 16 Oct 2004 20:27:29 -0000 1.5
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,5 +0,0 @@
-#define REACTOS_VERSION_DLL
-#define REACTOS_STR_FILE_DESCRIPTION "X86 Multiprocessor Hardware Abstraction Layer\0"
-#define REACTOS_STR_INTERNAL_NAME "halx86mp\0"
-#define REACTOS_STR_ORIGINAL_FILENAME "halx86mp.dll\0"
-#include <reactos/version.rc>
reactos/hal/halx86
diff -N halx86up.rc
--- halx86up.rc 16 Oct 2004 20:27:29 -0000 1.5
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,5 +0,0 @@
-#define REACTOS_VERSION_DLL
-#define REACTOS_STR_FILE_DESCRIPTION "X86 Uniprocessor Hardware Abstraction Layer\0"
-#define REACTOS_STR_INTERNAL_NAME "halx86up\0"
-#define REACTOS_STR_ORIGINAL_FILENAME "halx86up.dll\0"
-#include <reactos/version.rc>
reactos/hal/halx86
diff -N irql.c
--- irql.c 21 Nov 2004 21:53:06 -0000 1.22
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,480 +0,0 @@
-/* $Id: irql.c,v 1.22 2004/11/21 21:53:06 ion Exp $
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/x86/irql.c
- * PURPOSE: Implements IRQLs
- * PROGRAMMER: David Welch (welch@cwcom.net)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <roscfg.h>
-#include <ddk/ntddk.h>
-#include <internal/ps.h>
-#include <ntos/minmax.h>
-#include <hal.h>
-#include <halirq.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-/* GLOBALS ******************************************************************/
-
-/*
- * FIXME: Use EISA_CONTROL STRUCTURE INSTEAD OF HARD-CODED OFFSETS
-*/
-
-typedef union
-{
- USHORT both;
- struct
- {
- BYTE master;
- BYTE slave;
- };
-}
-PIC_MASK;
-
-/*
- * PURPOSE: - Mask for HalEnableSystemInterrupt and HalDisableSystemInterrupt
- * - At startup enable timer and cascade
- */
-#if defined(__GNUC__)
-static PIC_MASK pic_mask = {.both = 0xFFFA};
-#else
-static PIC_MASK pic_mask = { 0xFFFA };
-#endif
-
-
-/*
- * PURPOSE: Mask for disabling of acknowledged interrupts
- */
-#if defined(__GNUC__)
-static PIC_MASK pic_mask_intr = {.both = 0x0000};
-#else
-static PIC_MASK pic_mask_intr = { 0 };
-#endif
-
-static ULONG HalpPendingInterruptCount[NR_IRQS];
-
-#define DIRQL_TO_IRQ(x) (PROFILE_LEVEL - x)
-#define IRQ_TO_DIRQL(x) (PROFILE_LEVEL - x)
-
-VOID STDCALL
-KiInterruptDispatch2 (ULONG Irq, KIRQL old_level);
-
-/* FUNCTIONS ****************************************************************/
-
-KIRQL STDCALL KeGetCurrentIrql (VOID)
-/*
- * PURPOSE: Returns the current irq level
- * RETURNS: The current irq level
- */
-{
- return(KeGetCurrentKPCR()->Irql);
-}
-
-VOID HalpInitPICs(VOID)
-{
- memset(HalpPendingInterruptCount, 0, sizeof(HalpPendingInterruptCount));
-
- /* Initialization sequence */
- WRITE_PORT_UCHAR((PUCHAR)0x20, 0x11);
- WRITE_PORT_UCHAR((PUCHAR)0xa0, 0x11);
- /* Start of hardware irqs (0x24) */
- WRITE_PORT_UCHAR((PUCHAR)0x21, IRQ_BASE);
- WRITE_PORT_UCHAR((PUCHAR)0xa1, IRQ_BASE + 8);
- /* 8259-1 is master */
- WRITE_PORT_UCHAR((PUCHAR)0x21, 0x4);
- /* 8259-2 is slave */
- WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x2);
- /* 8086 mode */
- WRITE_PORT_UCHAR((PUCHAR)0x21, 0x1);
- WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x1);
- /* Enable interrupts */
- WRITE_PORT_UCHAR((PUCHAR)0x21, pic_mask.master);
- WRITE_PORT_UCHAR((PUCHAR)0xa1, pic_mask.slave);
-
- /* We can now enable interrupts */
- Ki386EnableInterrupts();
-}
-
-VOID HalpEndSystemInterrupt(KIRQL Irql)
-/*
- * FUNCTION: Enable all irqs with higher priority.
- */
-{
- ULONG flags;
- const USHORT mask[] =
- {
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0xc000, 0xe000, 0xf000,
- 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80, 0xffc0, 0xffe0, 0xfff0,
- 0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
- };
-
- /* Interrupts should be disable while enabling irqs of both pics */
- Ki386SaveFlags(flags);
- Ki386DisableInterrupts();
-
- pic_mask_intr.both &= mask[Irql];
- WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master));
- WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
-
- /* restore flags */
- Ki386RestoreFlags(flags);
-}
-
-VOID STATIC
-HalpExecuteIrqs(KIRQL NewIrql)
-{
- ULONG IrqLimit, i;
-
- IrqLimit = min(PROFILE_LEVEL - NewIrql, NR_IRQS);
-
- /*
- * For each irq if there have been any deferred interrupts then now
- * dispatch them.
- */
- for (i = 0; i < IrqLimit; i++)
- {
- if (HalpPendingInterruptCount[i] > 0)
- {
- KeGetCurrentKPCR()->Irql = (KIRQL)IRQ_TO_DIRQL(i);
-
- while (HalpPendingInterruptCount[i] > 0)
- {
- /*
- * For each deferred interrupt execute all the handlers at DIRQL.
- */
- HalpPendingInterruptCount[i]--;
- KiInterruptDispatch2(i + IRQ_BASE, NewIrql);
- }
- KeGetCurrentKPCR()->Irql--;
- HalpEndSystemInterrupt(KeGetCurrentKPCR()->Irql);
- }
- }
-
-}
-
-VOID STATIC
-HalpLowerIrql(KIRQL NewIrql)
-{
- if (NewIrql >= PROFILE_LEVEL)
- {
- KeGetCurrentKPCR()->Irql = NewIrql;
- return;
- }
- HalpExecuteIrqs(NewIrql);
- if (NewIrql >= DISPATCH_LEVEL)
- {
- KeGetCurrentKPCR()->Irql = NewIrql;
- return;
- }
- KeGetCurrentKPCR()->Irql = DISPATCH_LEVEL;
- if (KeGetCurrentKPCR()->HalReserved[HAL_DPC_REQUEST])
- {
- KeGetCurrentKPCR()->HalReserved[HAL_DPC_REQUEST] = FALSE;
- KiDispatchInterrupt();
- }
- KeGetCurrentKPCR()->Irql = APC_LEVEL;
- if (NewIrql == APC_LEVEL)
- {
- return;
- }
- if (KeGetCurrentThread() != NULL &&
- KeGetCurrentThread()->ApcState.KernelApcPending)
- {
- KiDeliverApc(KernelMode, NULL, NULL);
- }
- KeGetCurrentKPCR()->Irql = PASSIVE_LEVEL;
-}
-
-/**********************************************************************
- * NAME EXPORTED
- * KfLowerIrql
- *
- * DESCRIPTION
- * Restores the irq level on the current processor
- *
- * ARGUMENTS
- * NewIrql = Irql to lower to
- *
- * RETURN VALUE
- * None
- *
- * NOTES
- * Uses fastcall convention
- */
-VOID FASTCALL
-KfLowerIrql (KIRQL NewIrql)
-{
- DPRINT("KfLowerIrql(NewIrql %d)\n", NewIrql);
-
- if (NewIrql > KeGetCurrentKPCR()->Irql)
- {
- DbgPrint ("(%s:%d) NewIrql %x CurrentIrql %x\n",
- __FILE__, __LINE__, NewIrql, KeGetCurrentKPCR()->Irql);
- KEBUGCHECK(0);
- for(;;);
- }
-
- HalpLowerIrql(NewIrql);
-}
-
-
-/**********************************************************************
- * NAME EXPORTED
- * KeLowerIrql
- *
- * DESCRIPTION
- * Restores the irq level on the current processor
- *
- * ARGUMENTS
- * NewIrql = Irql to lower to
- *
- * RETURN VALUE
- * None
- *
- * NOTES
- */
-
-VOID STDCALL
-KeLowerIrql (KIRQL NewIrql)
-{
- KfLowerIrql (NewIrql);
-}
-
-
-/**********************************************************************
- * NAME EXPORTED
- * KfRaiseIrql
- *
- * DESCRIPTION
- * Raises the hardware priority (irql)
- *
- * ARGUMENTS
- * NewIrql = Irql to raise to
- *
- * RETURN VALUE
- * previous irq level
- *
- * NOTES
- * Uses fastcall convention
- */
-
-KIRQL FASTCALL
-KfRaiseIrql (KIRQL NewIrql)
-{
- KIRQL OldIrql;
-
- DPRINT("KfRaiseIrql(NewIrql %d)\n", NewIrql);
-
- if (NewIrql < KeGetCurrentKPCR()->Irql)
- {
- DbgPrint ("%s:%d CurrentIrql %x NewIrql %x\n",
- __FILE__,__LINE__,KeGetCurrentKPCR()->Irql,NewIrql);
- KEBUGCHECK (0);
- for(;;);
- }
-
- OldIrql = KeGetCurrentKPCR()->Irql;
- KeGetCurrentKPCR()->Irql = NewIrql;
- return OldIrql;
-}
-
-
-/**********************************************************************
- * NAME EXPORTED
- * KeRaiseIrql
- *
- * DESCRIPTION
- * Raises the hardware priority (irql)
- *
- * ARGUMENTS
- * NewIrql = Irql to raise to
- * OldIrql (OUT) = Caller supplied storage for the previous irql
- *
- * RETURN VALUE
- * None
- *
- * NOTES
- * Calls KfRaiseIrql
- */
-VOID STDCALL
-KeRaiseIrql (KIRQL NewIrql,
- PKIRQL OldIrql)
-{
- *OldIrql = KfRaiseIrql (NewIrql);
-}
-
-
-/**********************************************************************
- * NAME EXPORTED
- * KeRaiseIrqlToDpcLevel
- *
- * DESCRIPTION
- * Raises the hardware priority (irql) to DISPATCH level
- *
- * ARGUMENTS
- * None
- *
- * RETURN VALUE
- * Previous irq level
- *
- * NOTES
- * Calls KfRaiseIrql
- */
-
-KIRQL STDCALL
-KeRaiseIrqlToDpcLevel (VOID)
-{
- return KfRaiseIrql (DISPATCH_LEVEL);
-}
-
-
-/**********************************************************************
- * NAME EXPORTED
- * KeRaiseIrqlToSynchLevel
- *
- * DESCRIPTION
- * Raises the hardware priority (irql) to CLOCK2 level
- *
- * ARGUMENTS
- * None
- *
- * RETURN VALUE
- * Previous irq level
- *
- * NOTES
- * Calls KfRaiseIrql
- */
-
-KIRQL STDCALL
-KeRaiseIrqlToSynchLevel (VOID)
-{
- return KfRaiseIrql (CLOCK2_LEVEL);
-}
-
-
-BOOLEAN STDCALL
-HalBeginSystemInterrupt (ULONG Vector,
- KIRQL Irql,
- PKIRQL OldIrql)
-{
- ULONG irq;
- if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
- {
- return(FALSE);
- }
- irq = Vector - IRQ_BASE;
- pic_mask_intr.both |= ((1 << irq) & 0xfffe); // do not disable the timer interrupt
-
- if (irq < 8)
- {
- WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master));
- WRITE_PORT_UCHAR((PUCHAR)0x20, 0x20);
- }
- else
- {
- WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
- /* Send EOI to the PICs */
- WRITE_PORT_UCHAR((PUCHAR)0x20,0x20);
- WRITE_PORT_UCHAR((PUCHAR)0xa0,0x20);
- }
-
- if (KeGetCurrentKPCR()->Irql >= Irql)
- {
- HalpPendingInterruptCount[irq]++;
- return(FALSE);
- }
- *OldIrql = KeGetCurrentKPCR()->Irql;
- KeGetCurrentKPCR()->Irql = Irql;
-
- return(TRUE);
-}
-
-
-VOID STDCALL HalEndSystemInterrupt (KIRQL Irql, ULONG Unknown2)
-/*
- * FUNCTION: Finish a system interrupt and restore the specified irq level.
- */
-{
- HalpLowerIrql(Irql);
- HalpEndSystemInterrupt(Irql);
-}
-
-BOOLEAN
-STDCALL
-HalDisableSystemInterrupt(
- ULONG Vector,
- KIRQL Irql)
-{
- ULONG irq;
-
- if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
- return FALSE;
-
- irq = Vector - IRQ_BASE;
- pic_mask.both |= (1 << irq);
- if (irq < 8)
- {
- WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.slave));
- }
- else
- {
- WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
- }
-
- return TRUE;
-}
-
-
-BOOLEAN
-STDCALL
-HalEnableSystemInterrupt(
- ULONG Vector,
- KIRQL Irql,
- KINTERRUPT_MODE InterruptMode)
-{
- ULONG irq;
-
- if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
- return FALSE;
-
- irq = Vector - IRQ_BASE;
- pic_mask.both &= ~(1 << irq);
- if (irq < 8)
- {
- WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master));
- }
- else
- {
- WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
- }
-
- return TRUE;
-}
-
-
-VOID FASTCALL
-HalRequestSoftwareInterrupt(
- IN KIRQL Request)
-{
- switch (Request)
- {
- case APC_LEVEL:
- KeGetCurrentKPCR()->HalReserved[HAL_APC_REQUEST] = TRUE;
- break;
-
- case DISPATCH_LEVEL:
- KeGetCurrentKPCR()->HalReserved[HAL_DPC_REQUEST] = TRUE;
- break;
-
- default:
- KEBUGCHECK(0);
- }
-}
-
-/* EOF */
reactos/hal/halx86
diff -N isa.c
--- isa.c 1 Nov 2004 14:37:19 -0000 1.7
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,79 +0,0 @@
-/* $Id: isa.c,v 1.7 2004/11/01 14:37:19 hbirr Exp $
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/isa.c
- * PURPOSE: Interfaces to the ISA bus
- * PROGRAMMER: David Welch (welch@mcmail.com)
- * UPDATE HISTORY:
- * 05/06/98: Created
- */
-
-/* INCLUDES ***************************************************************/
-
-#include <roscfg.h>
-#include <ddk/ntddk.h>
-#include <bus.h>
-#include <halirq.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-BOOL HalIsaProbe(VOID)
-/*
- * FUNCTION: Probes for an ISA bus
- * RETURNS: True if detected
- * NOTE: Since ISA is the default we are called last and always return
- * true
- */
-{
- DbgPrint("Assuming ISA bus\n");
-
- /*
- * Probe for plug and play support
- */
- return(TRUE);
-}
-
-
-BOOLEAN STDCALL
-HalpTranslateIsaBusAddress(PBUS_HANDLER BusHandler,
- ULONG BusNumber,
- PHYSICAL_ADDRESS BusAddress,
- PULONG AddressSpace,
- PPHYSICAL_ADDRESS TranslatedAddress)
-{
- BOOLEAN Result;
-
- Result = HalTranslateBusAddress(PCIBus,
- BusNumber,
- BusAddress,
- AddressSpace,
- TranslatedAddress);
- if (Result != FALSE)
- return Result;
-
- Result = HalTranslateBusAddress(Internal,
- BusNumber,
- BusAddress,
- AddressSpace,
- TranslatedAddress);
- return Result;
-}
-
-ULONG STDCALL
-HalpGetIsaInterruptVector(PVOID BusHandler,
- ULONG BusNumber,
- ULONG BusInterruptLevel,
- ULONG BusInterruptVector,
- PKIRQL Irql,
- PKAFFINITY Affinity)
-{
- ULONG Vector = IRQ2VECTOR(BusInterruptVector);
- *Irql = VECTOR2IRQL(Vector);
- *Affinity = 0xFFFFFFFF;
- return Vector;
-}
-/* EOF */
reactos/hal/halx86
diff -N kdbg.c
--- kdbg.c 29 Apr 2004 17:06:21 -0000 1.8
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,548 +0,0 @@
-/* $Id: kdbg.c,v 1.8 2004/04/29 17:06:21 navaraf Exp $
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/x86/kdbg.c
- * PURPOSE: Serial i/o functions for the kernel debugger.
- * PROGRAMMER: Emanuele Aliberti
- * Eric Kohl
- * UPDATE HISTORY:
- * Created 05/09/99
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ddk/ntddk.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-
-#define DEFAULT_BAUD_RATE 19200
-
-
-/* MACROS *******************************************************************/
-
-#define SER_RBR(x) ((x)+0)
-#define SER_THR(x) ((x)+0)
-#define SER_DLL(x) ((x)+0)
-#define SER_IER(x) ((x)+1)
-#define SR_IER_ERDA 0x01
-#define SR_IER_ETHRE 0x02
-#define SR_IER_ERLSI 0x04
-#define SR_IER_EMS 0x08
-#define SR_IER_ALL 0x0F
-#define SER_DLM(x) ((x)+1)
-#define SER_IIR(x) ((x)+2)
-#define SER_FCR(x) ((x)+2)
-#define SR_FCR_ENABLE_FIFO 0x01
-#define SR_FCR_CLEAR_RCVR 0x02
-#define SR_FCR_CLEAR_XMIT 0x04
-#define SER_LCR(x) ((x)+3)
-#define SR_LCR_CS5 0x00
-#define SR_LCR_CS6 0x01
-#define SR_LCR_CS7 0x02
-#define SR_LCR_CS8 0x03
-#define SR_LCR_ST1 0x00
-#define SR_LCR_ST2 0x04
-#define SR_LCR_PNO 0x00
-#define SR_LCR_POD 0x08
-#define SR_LCR_PEV 0x18
-#define SR_LCR_PMK 0x28
-#define SR_LCR_PSP 0x38
-#define SR_LCR_BRK 0x40
-#define SR_LCR_DLAB 0x80
-#define SER_MCR(x) ((x)+4)
-#define SR_MCR_DTR 0x01
-#define SR_MCR_RTS 0x02
-#define SR_MCR_OUT1 0x04
-#define SR_MCR_OUT2 0x08
-#define SR_MCR_LOOP 0x10
-#define SER_LSR(x) ((x)+5)
-#define SR_LSR_DR 0x01
-#define SR_LSR_TBE 0x20
-#define SER_MSR(x) ((x)+6)
-#define SR_MSR_CTS 0x10
-#define SR_MSR_DSR 0x20
-#define SER_SCR(x) ((x)+7)
-
-
-/* GLOBAL VARIABLES *********************************************************/
-
-ULONG EXPORTED KdComPortInUse = 0;
-
-
-/* STATIC VARIABLES *********************************************************/
-
-static ULONG ComPort = 0;
-static ULONG BaudRate = 0;
-static PUCHAR PortBase = (PUCHAR)0;
-
-/* The com port must only be initialized once! */
-static BOOLEAN PortInitialized = FALSE;
-
-
-/* STATIC FUNCTIONS *********************************************************/
-
-static BOOLEAN
-KdpDoesComPortExist (PUCHAR BaseAddress)
-{
- BOOLEAN found;
- BYTE mcr;
- BYTE msr;
-
- found = FALSE;
-
- /* save Modem Control Register (MCR) */
- mcr = READ_PORT_UCHAR (SER_MCR(BaseAddress));
-
- /* enable loop mode (set Bit 4 of the MCR) */
- WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x10);
-
- /* clear all modem output bits */
- WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x10);
-
- /* read the Modem Status Register */
- msr = READ_PORT_UCHAR (SER_MSR(BaseAddress));
-
- /*
- * the upper nibble of the MSR (modem output bits) must be
- * equal to the lower nibble of the MCR (modem input bits)
- */
- if ((msr & 0xF0) == 0x00)
- {
- /* set all modem output bits */
- WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x1F);
-
- /* read the Modem Status Register */
- msr = READ_PORT_UCHAR (SER_MSR(BaseAddress));
-
- /*
- * the upper nibble of the MSR (modem output bits) must be
- * equal to the lower nibble of the MCR (modem input bits)
- */
- if ((msr & 0xF0) == 0xF0)
- {
- /*
- * setup a resonable state for the port:
- * enable fifo and clear recieve/transmit buffers
- */
- WRITE_PORT_UCHAR (SER_FCR(BaseAddress),
- (SR_FCR_ENABLE_FIFO | SR_FCR_CLEAR_RCVR | SR_FCR_CLEAR_XMIT));
- WRITE_PORT_UCHAR (SER_FCR(BaseAddress), 0);
- READ_PORT_UCHAR (SER_RBR(BaseAddress));
- WRITE_PORT_UCHAR (SER_IER(BaseAddress), 0);
- found = TRUE;
- }
- }
-
- /* restore MCR */
- WRITE_PORT_UCHAR (SER_MCR(BaseAddress), mcr);
-
- return (found);
-}
-
-
-/* FUNCTIONS ****************************************************************/
-
-/* HAL.KdPortInitialize */
-BOOLEAN
-STDCALL
-KdPortInitialize (
- PKD_PORT_INFORMATION PortInformation,
- DWORD Unknown1,
- DWORD Unknown2
- )
-{
- ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
- char buffer[80];
- ULONG divisor;
- BYTE lcr;
-
- if (PortInitialized == FALSE)
- {
- if (PortInformation->BaudRate != 0)
- {
- BaudRate = PortInformation->BaudRate;
- }
- else
- {
- BaudRate = DEFAULT_BAUD_RATE;
- }
-
- if (PortInformation->ComPort == 0)
- {
- if (KdpDoesComPortExist ((PUCHAR)BaseArray[2]))
- {
- PortBase = (PUCHAR)BaseArray[2];
- ComPort = 2;
- PortInformation->BaseAddress = (ULONG)PortBase;
- PortInformation->ComPort = ComPort;
-#ifndef NDEBUG
- sprintf (buffer,
- "\nSerial port COM%ld found at 0x%lx\n",
- ComPort,
- (ULONG)PortBase);
- HalDisplayString (buffer);
-#endif /* NDEBUG */
- }
- else if (KdpDoesComPortExist ((PUCHAR)BaseArray[1]))
- {
- PortBase = (PUCHAR)BaseArray[1];
- ComPort = 1;
- PortInformation->BaseAddress = (ULONG)PortBase;
- PortInformation->ComPort = ComPort;
-#ifndef NDEBUG
- sprintf (buffer,
- "\nSerial port COM%ld found at 0x%lx\n",
- ComPort,
- (ULONG)PortBase);
- HalDisplayString (buffer);
-#endif /* NDEBUG */
- }
- else
- {
- sprintf (buffer,
- "\nKernel Debugger: No COM port found!!!\n\n");
- HalDisplayString (buffer);
- return FALSE;
- }
- }
- else
- {
- if (KdpDoesComPortExist ((PUCHAR)BaseArray[PortInformation->ComPort]))
- {
- PortBase = (PUCHAR)BaseArray[PortInformation->ComPort];
- ComPort = PortInformation->ComPort;
- PortInformation->BaseAddress = (ULONG)PortBase;
-#ifndef NDEBUG
- sprintf (buffer,
- "\nSerial port COM%ld found at 0x%lx\n",
- ComPort,
- (ULONG)PortBase);
- HalDisplayString (buffer);
-#endif /* NDEBUG */
- }
- else
- {
- sprintf (buffer,
- "\nKernel Debugger: No serial port found!!!\n\n");
- HalDisplayString (buffer);
- return FALSE;
- }
- }
-
- PortInitialized = TRUE;
- }
-
- /*
- * set baud rate and data format (8N1)
- */
-
- /* turn on DTR and RTS */
- WRITE_PORT_UCHAR (SER_MCR(PortBase), SR_MCR_DTR | SR_MCR_RTS);
-
- /* set DLAB */
- lcr = READ_PORT_UCHAR (SER_LCR(PortBase)) | SR_LCR_DLAB;
- WRITE_PORT_UCHAR (SER_LCR(PortBase), lcr);
-
- /* set baud rate */
- divisor = 115200 / BaudRate;
- WRITE_PORT_UCHAR (SER_DLL(PortBase), (UCHAR)(divisor & 0xff));
- WRITE_PORT_UCHAR (SER_DLM(PortBase), (UCHAR)((divisor >> 8) & 0xff));
-
- /* reset DLAB and set 8N1 format */
- WRITE_PORT_UCHAR (SER_LCR(PortBase),
- SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO);
-
- /* read junk out of the RBR */
- lcr = READ_PORT_UCHAR (SER_RBR(PortBase));
-
- /*
- * set global info
- */
- KdComPortInUse = (ULONG)PortBase;
-
- /*
- * print message to blue screen
- */
- sprintf (buffer,
- "\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
- ComPort,
- (ULONG)PortBase,
- BaudRate);
-
- HalDisplayString (buffer);
-
- return TRUE;
-}
-
-
-/* HAL.KdPortInitializeEx */
-BOOLEAN
-STDCALL
-KdPortInitializeEx (
- PKD_PORT_INFORMATION PortInformation,
- DWORD Unknown1,
- DWORD Unknown2
- )
-{
- ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
- PUCHAR ComPortBase;
- char buffer[80];
- ULONG divisor;
- BYTE lcr;
-
- if (PortInformation->BaudRate == 0)
- {
- PortInformation->BaudRate = DEFAULT_BAUD_RATE;
- }
-
- if (PortInformation->ComPort == 0)
- {
- return FALSE;
- }
- else
- {
- if (KdpDoesComPortExist ((PUCHAR)BaseArray[PortInformation->ComPort]))
- {
- ComPortBase = (PUCHAR)BaseArray[PortInformation->ComPort];
- PortInformation->BaseAddress = (ULONG)ComPortBase;
-#ifndef NDEBUG
- sprintf (buffer,
- "\nSerial port COM%ld found at 0x%lx\n",
- PortInformation->ComPort,
- (ULONG)ComPortBase];
- HalDisplayString (buffer);
-#endif /* NDEBUG */
- }
- else
- {
- sprintf (buffer,
- "\nKernel Debugger: Serial port not found!!!\n\n");
- HalDisplayString (buffer);
- return FALSE;
- }
- }
-
- /*
- * set baud rate and data format (8N1)
- */
-
- /* turn on DTR and RTS */
- WRITE_PORT_UCHAR (SER_MCR(ComPortBase), SR_MCR_DTR | SR_MCR_RTS);
-
- /* set DLAB */
- lcr = READ_PORT_UCHAR (SER_LCR(ComPortBase)) | SR_LCR_DLAB;
- WRITE_PORT_UCHAR (SER_LCR(ComPortBase), lcr);
-
- /* set baud rate */
- divisor = 115200 / PortInformation->BaudRate;
- WRITE_PORT_UCHAR (SER_DLL(ComPortBase), (UCHAR)(divisor & 0xff));
- WRITE_PORT_UCHAR (SER_DLM(ComPortBase), (UCHAR)((divisor >> 8) & 0xff));
-
- /* reset DLAB and set 8N1 format */
- WRITE_PORT_UCHAR (SER_LCR(ComPortBase),
- SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO);
-
- /* read junk out of the RBR */
- lcr = READ_PORT_UCHAR (SER_RBR(ComPortBase));
-
-#ifndef NDEBUG
-
- /*
- * print message to blue screen
- */
- sprintf (buffer,
- "\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
- PortInformation->ComPort,
- (ULONG)ComPortBase,
- PortInformation->BaudRate);
-
- HalDisplayString (buffer);
-
-#endif /* NDEBUG */
-
- return TRUE;
-}
-
-
-/* HAL.KdPortGetByte */
-BOOLEAN
-STDCALL
-KdPortGetByte (
- PUCHAR ByteRecieved
- )
-{
- if (PortInitialized == FALSE)
- return FALSE;
-
- if ((READ_PORT_UCHAR (SER_LSR(PortBase)) & SR_LSR_DR))
- {
- *ByteRecieved = READ_PORT_UCHAR (SER_RBR(PortBase));
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-/* HAL.KdPortGetByteEx */
-BOOLEAN
-STDCALL
-KdPortGetByteEx (
- PKD_PORT_INFORMATION PortInformation,
- PUCHAR ByteRecieved
- )
-{
- PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
-
- if ((READ_PORT_UCHAR (SER_LSR(ComPortBase)) & SR_LSR_DR))
- {
- *ByteRecieved = READ_PORT_UCHAR (SER_RBR(ComPortBase));
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-/* HAL.KdPortPollByte */
-BOOLEAN
-STDCALL
-KdPortPollByte (
- PUCHAR ByteRecieved
- )
-{
- if (PortInitialized == FALSE)
- return FALSE;
-
- while ((READ_PORT_UCHAR (SER_LSR(PortBase)) & SR_LSR_DR) == 0)
- ;
-
- *ByteRecieved = READ_PORT_UCHAR (SER_RBR(PortBase));
-
- return TRUE;
-}
-
-
-/* HAL.KdPortPollByteEx */
-BOOLEAN
-STDCALL
-KdPortPollByteEx (
- PKD_PORT_INFORMATION PortInformation,
- PUCHAR ByteRecieved
- )
-{
- PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
-
- while ((READ_PORT_UCHAR (SER_LSR(ComPortBase)) & SR_LSR_DR) == 0)
- ;
-
- *ByteRecieved = READ_PORT_UCHAR (SER_RBR(ComPortBase));
-
- return TRUE;
-}
-
-
-
-
-/* HAL.KdPortPutByte */
-VOID
-STDCALL
-KdPortPutByte (
- UCHAR ByteToSend
- )
-{
- if (PortInitialized == FALSE)
- return;
-
- while ((READ_PORT_UCHAR (SER_LSR(PortBase)) & SR_LSR_TBE) == 0)
- ;
-
- WRITE_PORT_UCHAR (SER_THR(PortBase), ByteToSend);
-}
-
-/* HAL.KdPortPutByteEx */
-VOID
-STDCALL
-KdPortPutByteEx (
- PKD_PORT_INFORMATION PortInformation,
- UCHAR ByteToSend
- )
-{
- PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
-
- while ((READ_PORT_UCHAR (SER_LSR(ComPortBase)) & SR_LSR_TBE) == 0)
- ;
-
- WRITE_PORT_UCHAR (SER_THR(ComPortBase), ByteToSend);
-}
-
-
-/* HAL.KdPortRestore */
-VOID
-STDCALL
-KdPortRestore (
- VOID
- )
-{
-}
-
-
-/* HAL.KdPortSave */
-VOID
-STDCALL
-KdPortSave (
- VOID
- )
-{
-}
-
-
-/* HAL.KdPortDisableInterrupts */
-BOOLEAN
-STDCALL
-KdPortDisableInterrupts()
-{
- UCHAR ch;
-
- if (PortInitialized == FALSE)
- return FALSE;
-
- ch = READ_PORT_UCHAR (SER_MCR (PortBase));
- ch &= (~(SR_MCR_OUT1 | SR_MCR_OUT2));
- WRITE_PORT_UCHAR (SER_MCR (PortBase), ch);
-
- ch = READ_PORT_UCHAR (SER_IER (PortBase));
- ch &= (~SR_IER_ALL);
- WRITE_PORT_UCHAR (SER_IER (PortBase), ch);
-
- return TRUE;
-}
-
-
-/* HAL.KdPortEnableInterrupts */
-BOOLEAN
-STDCALL
-KdPortEnableInterrupts()
-{
- UCHAR ch;
-
- if (PortInitialized == FALSE)
- return FALSE;
-
- ch = READ_PORT_UCHAR (SER_IER (PortBase));
- ch &= (~SR_IER_ALL);
- ch |= SR_IER_ERDA;
- WRITE_PORT_UCHAR (SER_IER (PortBase), ch);
-
- ch = READ_PORT_UCHAR (SER_MCR (PortBase));
- ch &= (~SR_MCR_LOOP);
- ch |= (SR_MCR_OUT1 | SR_MCR_OUT2);
- WRITE_PORT_UCHAR (SER_MCR (PortBase), ch);
-
- return TRUE;
-}
-
-/* EOF */
reactos/hal/halx86
diff -N mca.c
--- mca.c 28 Dec 2003 22:38:09 -0000 1.3
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,82 +0,0 @@
-/*
- * ReactOS kernel
- * Copyright (C) 2002 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/* $Id: mca.c,v 1.3 2003/12/28 22:38:09 fireball Exp $
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: hal/halx86/mca.c
- * PURPOSE: Interfaces to the MicroChannel bus
- * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
- */
-
-/*
- * TODO:
- * What Adapter ID is read from an empty slot?
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ddk/ntddk.h>
-#include <bus.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-
-/* FUNCTIONS ****************************************************************/
-
-ULONG STDCALL
-HalpGetMicroChannelData(PBUS_HANDLER BusHandler,
- ULONG BusNumber,
- ULONG SlotNumber,
- PVOID Buffer,
- ULONG Offset,
- ULONG Length)
-{
- PCM_MCA_POS_DATA PosData = (PCM_MCA_POS_DATA)Buffer;
-
- DPRINT("HalpGetMicroChannelData() called.\n");
- DPRINT(" BusNumber %lu\n", BusNumber);
- DPRINT(" SlotNumber %lu\n", SlotNumber);
- DPRINT(" Offset 0x%lx\n", Offset);
- DPRINT(" Length 0x%lx\n", Length);
-
- if ((BusNumber != 0) ||
- (SlotNumber == 0) || (SlotNumber > 8) ||
- (Length < sizeof(CM_MCA_POS_DATA)))
- return(0);
-
- /* Enter Setup-Mode for given slot */
- WRITE_PORT_UCHAR((PUCHAR)0x96, (UCHAR)(((UCHAR)(SlotNumber - 1) & 0x07) | 0x08));
-
- /* Read POS data */
- PosData->AdapterId = (READ_PORT_UCHAR((PUCHAR)0x101) << 8) +
- READ_PORT_UCHAR((PUCHAR)0x100);
- PosData->PosData1 = READ_PORT_UCHAR((PUCHAR)0x102);
- PosData->PosData2 = READ_PORT_UCHAR((PUCHAR)0x103);
- PosData->PosData3 = READ_PORT_UCHAR((PUCHAR)0x104);
- PosData->PosData4 = READ_PORT_UCHAR((PUCHAR)0x105);
-
- /* Leave Setup-Mode for given slot */
- WRITE_PORT_UCHAR((PUCHAR)0x96, (UCHAR)((UCHAR)(SlotNumber - 1) & 0x07));
-
- return(sizeof(CM_MCA_POS_DATA));
-}
-
-/* EOF */
reactos/hal/halx86
diff -N misc.c
--- misc.c 28 Nov 2004 01:30:01 -0000 1.8
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,109 +0,0 @@
-/* $Id: misc.c,v 1.8 2004/11/28 01:30:01 hbirr Exp $
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/x86/misc.c
- * PURPOSE: Miscellaneous hardware functions
- * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <roscfg.h>
-#include <ddk/ntddk.h>
-#include <hal.h>
-
-#ifdef MP
-#include <apic.h>
-#endif
-
-#define NDEBUG
-#include <internal/debug.h>
-
-/* FUNCTIONS ****************************************************************/
-
-#ifdef MP
-
-VOID
-HaliReconfigurePciInterrupts(VOID);
-
-#endif
-
-VOID STDCALL
-HalHandleNMI(ULONG Unused)
-{
- UCHAR ucStatus;
-
- ucStatus = READ_PORT_UCHAR((PUCHAR) 0x61);
-
- HalDisplayString ("\n*** Hardware Malfunction\n\n");
- HalDisplayString ("Call your hardware vendor for support\n\n");
-
- if (ucStatus & 0x80)
- HalDisplayString ("NMI: Parity Check / Memory Parity Error\n");
-
- if (ucStatus & 0x40)
- HalDisplayString ("NMI: Channel Check / IOCHK\n");
-
- HalDisplayString ("\n*** The system has halted ***\n");
- KeEnterKernelDebugger ();
-}
-
-
-VOID STDCALL
-HalProcessorIdle(VOID)
-{
-#if 1
- Ki386EnableInterrupts();
- Ki386HaltProcessor();
-#else
-
-#endif
-}
-
-VOID STDCALL
-HalRequestIpi(ULONG ProcessorNo)
-{
- DPRINT("HalRequestIpi(ProcessorNo %d)\n", ProcessorNo);
-#ifdef MP
- APICSendIPI(1 << ProcessorNo,
- IPI_VECTOR|APIC_ICR0_LEVEL_DEASSERT|APIC_ICR0_DESTM);
-#endif
-}
-
-ULONG FASTCALL
-HalSystemVectorDispatchEntry (
- ULONG Unknown1,
- ULONG Unknown2,
- ULONG Unknown3
- )
-{
- return 0;
-}
-
-
-VOID STDCALL
-KeFlushWriteBuffer(VOID)
-{
- return;
-}
-
-
-VOID STDCALL
-HalReportResourceUsage(VOID)
-{
- /*
- * FIXME: Report all resources used by hal.
- * Calls IoReportHalResourceUsage()
- */
-
- /* Initialize PCI bus. */
- HalpInitPciBus ();
-#ifdef MP
-
- HaliReconfigurePciInterrupts();
-#endif
-
-}
-
-/* EOF */
reactos/hal/halx86
diff -N mp.c
--- mp.c 28 Nov 2004 01:30:01 -0000 1.12
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,1842 +0,0 @@
-/* $Id: mp.c,v 1.12 2004/11/28 01:30:01 hbirr Exp $
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/x86/mp.c
- * PURPOSE: Intel MultiProcessor specification support
- * PROGRAMMER: David Welch (welch@cwcom.net)
- * Casper S. Hornstrup (chorns@users.sourceforge.net)
- * NOTES: Parts adapted from linux SMP code
- * UPDATE HISTORY:
- * 22/05/1998 DW Created
- * 12/04/2001 CSH Added MultiProcessor specification support
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <roscfg.h>
-#include <ddk/ntddk.h>
-
-
-#ifdef MP
-
-#include <hal.h>
-#include <halirq.h>
-#include <mps.h>
-#include <apic.h>
-
-#include <internal/ntoskrnl.h>
-#include <internal/i386/segment.h>
-#include <internal/ke.h>
-#include <internal/ps.h>
-
-#endif
-
-#define NDEBUG
-#include <internal/debug.h>
-
-#ifdef MP
-
-
-/*
- Address of area to be used for communication between Application
- Processors (APs) and the BootStrap Processor (BSP)
- */
-#define COMMON_AREA 0x2000
-
-#define BIOS_AREA 0x0
-
-typedef struct __attribute__((packed)) _COMMON_AREA_INFO
-{
- ULONG Stack; /* Location of AP stack */
- ULONG Debug[16]; /* For debugging */
-} COMMON_AREA_INFO, *PCOMMON_AREA_INFO;
-
-CPU_INFO CPUMap[MAX_CPU]; /* Map of all CPUs in the system */
-ULONG CPUCount; /* Total number of CPUs */
-ULONG OnlineCPUs; /* Bitmask of online CPUs */
-
-UCHAR BUSMap[MAX_BUS]; /* Map of all buses in the system */
-UCHAR PCIBUSMap[MAX_BUS]; /* Map of all PCI buses in the system */
-
-IOAPIC_INFO IOAPICMap[MAX_IOAPIC]; /* Map of all I/O APICs in the system */
-ULONG IOAPICCount; /* Number of I/O APICs in the system */
-
-MP_CONFIGURATION_INTSRC IRQMap[MAX_IRQ_SOURCE]; /* Map of all IRQs */
-ULONG IRQVectorMap[MAX_IRQ_SOURCE]; /* IRQ to vector map */
-ULONG IrqPinMap[MAX_IRQ_SOURCE]; /* IRQ to Pin map */
-ULONG IrqApicMap[MAX_IRQ_SOURCE];
-ULONG IRQCount; /* Number of IRQs */
-
-ULONG APICMode; /* APIC mode at startup */
-ULONG BootCPU; /* Bootstrap processor */
-PULONG BIOSBase; /* Virtual address of BIOS data segment */
-PULONG CommonBase; /* Virtual address of common area */
-
-extern CHAR *APstart, *APend;
-extern VOID (*APflush)(VOID);
-
-extern VOID MpsTimerInterrupt(VOID);
-extern VOID MpsErrorInterrupt(VOID);
-extern VOID MpsSpuriousInterrupt(VOID);
-extern VOID MpsIpiInterrupt(VOID);
-
-#define CMOS_READ(address) ({ \
- WRITE_PORT_UCHAR((PUCHAR)0x70, address)); \
- READ_PORT_UCHAR((PUCHAR)0x71)); \
-})
-
-#define CMOS_WRITE(address, value) ({ \
- WRITE_PORT_UCHAR((PUCHAR)0x70, address); \
- WRITE_PORT_UCHAR((PUCHAR)0x71, value); \
-})
-
-#endif /* MP */
-
-
-
-/* FUNCTIONS *****************************************************************/
-
-#ifdef MP
-
-/* Functions for handling 8259A PICs */
-
-VOID Disable8259AIrq(ULONG irq)
-{
- ULONG tmp;
-
- if (irq >= 8)
- {
- tmp = READ_PORT_UCHAR((PUCHAR)0xA1);
- tmp |= (1 << (irq - 8));
- WRITE_PORT_UCHAR((PUCHAR)0xA1, tmp);
- }
- else
- {
- tmp = READ_PORT_UCHAR((PUCHAR)0x21);
- tmp |= (1 << irq);
- WRITE_PORT_UCHAR((PUCHAR)0x21, tmp);
- }
-}
-
-
-VOID Enable8259AIrq(ULONG irq)
-{
- ULONG tmp;
-
- if (irq >= 8)
- {
- tmp = READ_PORT_UCHAR((PUCHAR)0xA1);
- tmp &= ~(1 << (irq - 8));
- WRITE_PORT_UCHAR((PUCHAR)0xA1, tmp);
- }
- else
- {
- tmp = READ_PORT_UCHAR((PUCHAR)0x21);
- tmp &= ~(1 << irq);
- WRITE_PORT_UCHAR((PUCHAR)0x21, tmp);
- }
-}
-
-
-/* Functions for handling I/O APICs */
-
-volatile ULONG IOAPICRead(ULONG Apic, ULONG Offset)
-{
- PULONG Base;
-
- Base = (PULONG)IOAPICMap[Apic].ApicAddress;
- *Base = Offset;
- return *((PULONG)((ULONG)Base + IOAPIC_IOWIN));
-}
-
-VOID IOAPICWrite(ULONG Apic, ULONG Offset, ULONG Value)
-{
- PULONG Base;
-
- Base = (PULONG)IOAPICMap[Apic].ApicAddress;
- *Base = Offset;
- *((PULONG)((ULONG)Base + IOAPIC_IOWIN)) = Value;
-}
-
-
-VOID IOAPICClearPin(ULONG Apic, ULONG Pin)
-{
- IOAPIC_ROUTE_ENTRY Entry;
-
- DPRINT("IOAPICClearPin(Apic %d, Pin %d\n", Apic, Pin);
- /*
- * Disable it in the IO-APIC irq-routing table
- */
- memset(&Entry, 0, sizeof(Entry));
- Entry.mask = 1;
-
- IOAPICWrite(Apic, IOAPIC_REDTBL + 2 * Pin, *(((PULONG)&Entry) + 0));
- IOAPICWrite(Apic, IOAPIC_REDTBL + 1 + 2 * Pin, *(((PULONG)&Entry) + 1));
-}
-
-static VOID IOAPICClear(ULONG Apic)
-{
- ULONG Pin;
-
- for (Pin = 0; Pin < /*IOAPICMap[Apic].EntryCount*/24; Pin++)
- {
- IOAPICClearPin(Apic, Pin);
- }
-}
-
-static VOID IOAPICClearAll(VOID)
-{
- ULONG Apic;
-
- for (Apic = 0; Apic < IOAPICCount; Apic++)
- {
- IOAPICClear(Apic);
- }
-}
-
-/* This is performance critical and should probably be done in assembler */
-VOID IOAPICMaskIrq(ULONG Irq)
-{
- IOAPIC_ROUTE_ENTRY Entry;
- ULONG Apic = IrqApicMap[Irq];
-
-
- *((PULONG)&Entry) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq);
- Entry.mask = 1;
- IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq, *((PULONG)&Entry));
-}
-
-
-/* This is performance critical and should probably be done in assembler */
-VOID IOAPICUnmaskIrq(ULONG Irq)
-{
- IOAPIC_ROUTE_ENTRY Entry;
- ULONG Apic = IrqApicMap[Irq];
-
- *((PULONG)&Entry) = IOAPICRead(Apic, IOAPIC_REDTBL+2*IrqPinMap[Irq]);
- Entry.mask = 0;
- IOAPICWrite(Apic, IOAPIC_REDTBL+2*IrqPinMap[Irq], *((PULONG)&Entry));
-}
-
-static VOID
-IOAPICSetupIds(VOID)
-{
- ULONG tmp, apic, i;
- UCHAR old_id;
-
- /*
- * Set the IOAPIC ID to the value stored in the MPC table.
- */
- for (apic = 0; apic < IOAPICCount; apic++)
- {
-
- /* Read the register 0 value */
- tmp = IOAPICRead(apic, IOAPIC_ID);
-
- old_id = IOAPICMap[apic].ApicId;
-
- if (IOAPICMap[apic].ApicId >= 0xf)
- {
- DPRINT1("BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
- apic, IOAPICMap[apic].ApicId);
- DPRINT1("... fixing up to %d. (tell your hw vendor)\n",
- GET_IOAPIC_ID(tmp));
- IOAPICMap[apic].ApicId = GET_IOAPIC_ID(tmp);
- }
-
- /*
- * We need to adjust the IRQ routing table
- * if the ID changed.
- */
- if (old_id != IOAPICMap[apic].ApicId)
- {
- for (i = 0; i < IRQCount; i++)
- {
- if (IRQMap[i].DstApicId == old_id)
- {
- IRQMap[i].DstApicId = IOAPICMap[apic].ApicId;
- }
- }
- }
-
- /*
- * Read the right value from the MPC table and
- * write it into the ID register.
- */
- DPRINT("Changing IO-APIC physical APIC ID to %d\n",
- IOAPICMap[apic].ApicId);
-
- tmp &= ~IOAPIC_ID_MASK;
- tmp |= SET_IOAPIC_ID(IOAPICMap[apic].ApicId);
-
- IOAPICWrite(apic, IOAPIC_ID, tmp);
-
- /*
- * Sanity check
- */
- tmp = IOAPICRead(apic, 0);
- if (GET_IOAPIC_ID(tmp) != IOAPICMap[apic].ApicId)
- {
- DPRINT1("Could not set I/O APIC ID!\n");
- KEBUGCHECK(0);
- }
- }
-}
-
-
-/*
- * EISA Edge/Level control register, ELCR
- */
-static ULONG EISA_ELCR(ULONG irq)
-{
- if (irq < 16)
- {
- PUCHAR port = (PUCHAR)(0x4d0 + (irq >> 3));
- return (READ_PORT_UCHAR(port) >> (irq & 7)) & 1;
- }
- DPRINT("Broken MPtable reports ISA irq %d\n", irq);
- return 0;
-}
-
-/* EISA interrupts are always polarity zero and can be edge or level
- * trigger depending on the ELCR value. If an interrupt is listed as
- * EISA conforming in the MP table, that means its trigger type must
- * be read in from the ELCR */
-
-#define default_EISA_trigger(idx) (EISA_ELCR(IRQMap[idx].SrcBusIrq))
-#define default_EISA_polarity(idx) (0)
-
-/* ISA interrupts are always polarity zero edge triggered,
- * when listed as conforming in the MP table. */
-
-#define default_ISA_trigger(idx) (0)
-#define default_ISA_polarity(idx) (0)
-
-/* PCI interrupts are always polarity one level triggered,
- * when listed as conforming in the MP table. */
-
-#define default_PCI_trigger(idx) (1)
-#define default_PCI_polarity(idx) (1)
-
-/* MCA interrupts are always polarity zero level triggered,
- * when listed as conforming in the MP table. */
-
-#define default_MCA_trigger(idx) (1)
-#define default_MCA_polarity(idx) (0)
-
-static ULONG IRQPolarity(ULONG idx)
-{
- ULONG bus = IRQMap[idx].SrcBusId;
- ULONG polarity;
-
- /*
- * Determine IRQ line polarity (high active or low active):
- */
- switch (IRQMap[idx].IrqFlag & 3)
- {
- case 0: /* conforms, ie. bus-type dependent polarity */
- {
- switch (BUSMap[bus])
- {
- case MP_BUS_ISA: /* ISA pin */
- {
- polarity = default_ISA_polarity(idx);
- break;
- }
- case MP_BUS_EISA: /* EISA pin */
- {
- polarity = default_EISA_polarity(idx);
- break;
- }
- case MP_BUS_PCI: /* PCI pin */
- {
- polarity = default_PCI_polarity(idx);
- break;
- }
- case MP_BUS_MCA: /* MCA pin */
- {
- polarity = default_MCA_polarity(idx);
- break;
- }
- default:
- {
- DPRINT("Broken BIOS!!\n");
- polarity = 1;
- break;
- }
- }
- break;
- }
- case 1: /* high active */
- {
- polarity = 0;
- break;
- }
- case 2: /* reserved */
- {
- DPRINT("Broken BIOS!!\n");
- polarity = 1;
- break;
- }
- case 3: /* low active */
- {
- polarity = 1;
- break;
- }
- default: /* invalid */
- {
- DPRINT("Broken BIOS!!\n");
- polarity = 1;
- break;
- }
- }
- return polarity;
-}
-
-static ULONG IRQTrigger(ULONG idx)
-{
- ULONG bus = IRQMap[idx].SrcBusId;
- ULONG trigger;
-
- /*
- * Determine IRQ trigger mode (edge or level sensitive):
- */
- switch ((IRQMap[idx].IrqFlag >> 2) & 3)
- {
- case 0: /* conforms, ie. bus-type dependent */
- {
- switch (BUSMap[bus])
- {
- case MP_BUS_ISA: /* ISA pin */
- {
- trigger = default_ISA_trigger(idx);
- break;
- }
- case MP_BUS_EISA: /* EISA pin */
- {
- trigger = default_EISA_trigger(idx);
- break;
- }
- case MP_BUS_PCI: /* PCI pin */
- {
- trigger = default_PCI_trigger(idx);
- break;
- }
- case MP_BUS_MCA: /* MCA pin */
- {
- trigger = default_MCA_trigger(idx);
- break;
- }
- default:
- {
- DPRINT("Broken BIOS!!\n");
- trigger = 1;
- break;
- }
- }
- break;
- }
- case 1: /* edge */
- {
- trigger = 0;
- break;
- }
- case 2: /* reserved */
- {
- DPRINT("Broken BIOS!!\n");
- trigger = 1;
- break;
- }
- case 3: /* level */
- {
- trigger = 1;
- break;
- }
- default: /* invalid */
- {
- DPRINT("Broken BIOS!!\n");
- trigger = 0;
- break;
- }
- }
- return trigger;
-}
-
-
-static ULONG Pin2Irq(ULONG idx,
- ULONG apic,
- ULONG pin)
-{
- ULONG irq, i;
- ULONG bus = IRQMap[idx].SrcBusId;
-
- /*
- * Debugging check, we are in big trouble if this message pops up!
- */
- if (IRQMap[idx].DstApicInt != pin) {
- DPRINT("broken BIOS or MPTABLE parser, ayiee!!\n");
- }
-
- switch (BUSMap[bus])
- {
- case MP_BUS_ISA: /* ISA pin */
- case MP_BUS_EISA:
- case MP_BUS_MCA:
- {
- irq = IRQMap[idx].SrcBusIrq;
- break;
- }
- case MP_BUS_PCI: /* PCI pin */
- {
- /*
- * PCI IRQs are mapped in order
- */
- i = irq = 0;
- while (i < apic)
- irq += IOAPICMap[i++].EntryCount;
- irq += pin;
- break;
- }
- default:
- {
- DPRINT("Unknown bus type %d.\n",bus);
- irq = 0;
- break;
- }
- }
-
- return irq;
-}
-
-
-/*
- * Rough estimation of how many shared IRQs there are, can
- * be changed anytime.
- */
-#define MAX_PLUS_SHARED_IRQS PIC_IRQS
-#define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + PIC_IRQS)
-
-/*
- * This is performance-critical, we want to do it O(1)
- *
- * the indexing order of this array favors 1:1 mappings
- * between pins and IRQs.
- */
-
-static struct irq_pin_list {
- ULONG apic, pin, next;
-} irq_2_pin[PIN_MAP_SIZE];
-
-/*
- * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
- * shared ISA-space IRQs, so we have to support them. We are super
- * fast in the common case, and fast for shared ISA-space IRQs.
- */
-static VOID AddPinToIrq(ULONG irq,
- ULONG apic,
- ULONG pin)
-{
- static ULONG first_free_entry = PIC_IRQS;
- struct irq_pin_list *entry = irq_2_pin + irq;
-
- while (entry->next)
- {
- entry = irq_2_pin + entry->next;
- }
-
- if (entry->pin != -1)
- {
- entry->next = first_free_entry;
- entry = irq_2_pin + entry->next;
- if (++first_free_entry >= PIN_MAP_SIZE)
- {
- DPRINT1("Ohh no!");
- KEBUGCHECK(0);
- }
- }
- entry->apic = apic;
- entry->pin = pin;
-}
-
-
-/*
- * Find the IRQ entry number of a certain pin.
- */
-static ULONG IOAPICGetIrqEntry(ULONG apic,
- ULONG pin,
- ULONG type)
-{
- ULONG i;
-
- for (i = 0; i < IRQCount; i++)
- {
- if (IRQMap[i].IrqType == type &&
- (IRQMap[i].DstApicId == IOAPICMap[apic].ApicId || IRQMap[i].DstApicId == MP_APIC_ALL) &&
- IRQMap[i].DstApicInt == pin)
- {
- return i;
- }
- }
- return -1;
-}
-
-
-static ULONG AssignIrqVector(ULONG irq)
-{
-#if 0
- static ULONG current_vector = FIRST_DEVICE_VECTOR, vector_offset = 0;
-#endif
- ULONG vector;
- /* There may already have been assigned a vector for this IRQ */
- vector = IRQVectorMap[irq];
- if (vector > 0)
- {
- return vector;
- }
-#if 0
- if (current_vector > FIRST_SYSTEM_VECTOR) {
- vector_offset++;
- current_vector = FIRST_DEVICE_VECTOR + vector_offset;
- } else if (current_vector == FIRST_SYSTEM_VECTOR) {
- DPRINT1("Ran out of interrupt sources!");
- KEBUGCHECK(0);
- }
-
- vector = current_vector;
- IRQVectorMap[irq] = vector;
- current_vector += 8;
- return vector;
-#else
- vector = IRQ2VECTOR(irq);
- IRQVectorMap[irq] = vector;
- return vector;
-#endif
-}
-
-
-VOID IOAPICSetupIrqs(VOID)
-{
- IOAPIC_ROUTE_ENTRY entry;
- ULONG apic, pin, idx, irq, first_notcon = 1, vector;
-
- DPRINT("Init IO_APIC IRQs\n");
-
- for (apic = 0; apic < IOAPICCount; apic++)
- {
- for (pin = 0; pin < IOAPICMap[apic].EntryCount; pin++)
- {
- /*
- * add it to the IO-APIC irq-routing table
- */
- memset(&entry,0,sizeof(entry));
-
- entry.delivery_mode = APIC_DM_LOWEST;
- entry.dest_mode = 1; /* logical delivery */
- entry.mask = 1; /* disable IRQ */
-#if 0
- /*
- * FIXME:
- * Some drivers are not able to deal with more than one cpu.
- */
- entry.dest.logical.logical_dest = OnlineCPUs;
-#else
- entry.dest.logical.logical_dest = 1 << 0;
-#endif
- idx = IOAPICGetIrqEntry(apic,pin,INT_VECTORED);
- if (idx == -1)
- {
- if (first_notcon)
- {
- DPRINT(" IO-APIC (apicid-pin) %d-%d\n", IOAPICMap[apic].ApicId, pin);
- first_notcon = 0;
- }
- else
- {
- DPRINT(", %d-%d\n", IOAPICMap[apic].ApicId, pin);
- }
- continue;
- }
-
- entry.trigger = IRQTrigger(idx);
- entry.polarity = IRQPolarity(idx);
-
- if (entry.trigger)
- {
- entry.trigger = 1;
- entry.mask = 1; // disable
-#if 0
- entry.dest.logical.logical_dest = OnlineCPUs;
-#else
- entry.dest.logical.logical_dest = 1 << 0;
-#endif
- }
-
- irq = Pin2Irq(idx, apic, pin);
- AddPinToIrq(irq, apic, pin);
-
- vector = AssignIrqVector(irq);
- entry.vector = vector;
-
- DPRINT("vector 0x%.08x assigned to irq 0x%.02x\n", vector, irq);
-
- if (irq == 0)
- {
- /* Mask timer IRQ */
- entry.mask = 1;
- }
-
- if ((apic == 0) && (irq < 16))
- {
- Disable8259AIrq(irq);
- }
- IOAPICWrite(apic, IOAPIC_REDTBL+2*pin+1, *(((PULONG)&entry)+1));
- IOAPICWrite(apic, IOAPIC_REDTBL+2*pin, *(((PULONG)&entry)+0));
-
- IrqPinMap[irq] = pin;
- IrqApicMap[irq] = apic;
-
- DPRINT("Vector %x, Pin %x, Irq %x\n", vector, pin, irq);
- }
- }
-}
-
-
-static VOID IOAPICEnable(VOID)
-{
- ULONG i, tmp;
-
- for (i = 0; i < PIN_MAP_SIZE; i++)
- {
- irq_2_pin[i].pin = -1;
- irq_2_pin[i].next = 0;
- }
-
- /*
- * The number of IO-APIC IRQ registers (== #pins):
- */
- for (i = 0; i < IOAPICCount; i++)
- {
- tmp = IOAPICRead(i, IOAPIC_VER);
- IOAPICMap[i].EntryCount = GET_IOAPIC_MRE(tmp) + 1;
- }
-
- /*
- * Do not trust the IO-APIC being empty at bootup
- */
- IOAPICClearAll();
-}
-
-#if 0
-static VOID IOAPICDisable(VOID)
-{
- /*
- * Clear the IO-APIC before rebooting
- */
- IOAPICClearAll();
- APICDisable();
-}
-#endif
-
-
-static VOID IOAPICSetup(VOID)
-{
- IOAPICEnable();
- IOAPICSetupIds();
- APICSyncArbIDs();
- IOAPICSetupIrqs();
-}
-
-
-VOID IOAPICDump(VOID)
-{
- ULONG apic, i;
- ULONG reg0, reg1, reg2=0;
-
- DbgPrint("Number of MP IRQ sources: %d.\n", IRQCount);
- for (i = 0; i < IOAPICCount; i++)
- {
- DbgPrint("Number of IO-APIC #%d registers: %d.\n",
- IOAPICMap[i].ApicId,
- IOAPICMap[i].EntryCount);
- }
-
- /*
- * We are a bit conservative about what we expect. We have to
- * know about every hardware change ASAP.
- */
- DbgPrint("Testing the IO APIC.......................\n");
-
- for (apic = 0; apic < IOAPICCount; apic++)
- {
- reg0 = IOAPICRead(apic, IOAPIC_ID);
- reg1 = IOAPICRead(apic, IOAPIC_VER);
- if (GET_IOAPIC_VERSION(reg1) >= 0x10)
- {
- reg2 = IOAPICRead(apic, IOAPIC_ARB);
- }
-
- DbgPrint("\n");
- DbgPrint("IO APIC #%d......\n", IOAPICMap[apic].ApicId);
- DbgPrint(".... register #00: %08X\n", reg0);
- DbgPrint("....... : physical APIC id: %02X\n", GET_IOAPIC_ID(reg0));
- if (reg0 & 0xF0FFFFFF)
- {
- DbgPrint(" WARNING: Unexpected IO-APIC\n");
- }
-
- DbgPrint(".... register #01: %08X\n", reg1);
- i = GET_IOAPIC_MRE(reg1);
-
- DbgPrint("....... : max redirection entries: %04X\n", i);
- if ((i != 0x0f) && /* older (Neptune) boards */
- (i != 0x17) && /* typical ISA+PCI boards */
- (i != 0x1b) && /* Compaq Proliant boards */
- (i != 0x1f) && /* dual Xeon boards */
- (i != 0x22) && /* bigger Xeon boards */
- (i != 0x2E) &&
- (i != 0x3F))
- {
- DbgPrint(" WARNING: Unexpected IO-APIC\n");
- }
-
- i = GET_IOAPIC_VERSION(reg1);
- DbgPrint("....... : IO APIC version: %04X\n", i);
- if ((i != 0x01) && /* 82489DX IO-APICs */
- (i != 0x10) && /* oldest IO-APICs */
- (i != 0x11) && /* Pentium/Pro IO-APICs */
- (i != 0x13)) /* Xeon IO-APICs */
- {
- DbgPrint(" WARNING: Unexpected IO-APIC\n");
- }
-
- if (reg1 & 0xFF00FF00)
- {
- DbgPrint(" WARNING: Unexpected IO-APIC\n");
- }
-
- if (GET_IOAPIC_VERSION(reg1) >= 0x10)
- {
- DbgPrint(".... register #02: %08X\n", reg2);
- DbgPrint("....... : arbitration: %02X\n",
- GET_IOAPIC_ARB(reg2));
- if (reg2 & 0xF0FFFFFF)
- {
- DbgPrint(" WARNING: Unexpected IO-APIC\n");
- }
- }
-
- DbgPrint(".... IRQ redirection table:\n");
- DbgPrint(" NR Log Phy Mask Trig IRR Pol"
- " Stat Dest Deli Vect: \n");
-
- for (i = 0; i <= GET_IOAPIC_MRE(reg1); i++)
- {
- IOAPIC_ROUTE_ENTRY entry;
-
- *(((PULONG)&entry)+0) = IOAPICRead(apic, 0x10+i*2);
- *(((PULONG)&entry)+1) = IOAPICRead(apic, 0x11+i*2);
-
- DbgPrint(" %02x %03X %02X ",
- i,
- entry.dest.logical.logical_dest,
- entry.dest.physical.physical_dest);
-
- DbgPrint("%C %C %1d %C %C %C %03X %02X\n",
- (entry.mask == 0) ? 'U' : 'M', // Unmasked/masked
- (entry.trigger == 0) ? 'E' : 'L', // Edge/level sensitive
- entry.irr,
- (entry.polarity == 0) ? 'H' : 'L', // Active high/active low
- (entry.delivery_status == 0) ? 'I' : 'S', // Idle / send pending
- (entry.dest_mode == 0) ? 'P' : 'L', // Physical logical
- entry.delivery_mode,
- entry.vector);
- }
- }
- DbgPrint("IRQ to pin mappings:\n");
- for (i = 0; i < PIC_IRQS; i++)
- {
- struct irq_pin_list *entry = irq_2_pin + i;
- if (entry->pin < 0)
- {
- continue;
- }
- DbgPrint("IRQ%d ", i);
- for (;;)
- {
- DbgPrint("-> %d", entry->pin);
- if (!entry->next)
- {
- break;
- }
- entry = irq_2_pin + entry->next;
- }
- if (i % 2)
- {
- DbgPrint("\n");
- }
- else
- {
- DbgPrint(" ");
- }
- }
-
- DbgPrint(".................................... done.\n");
-}
-
-
-
-/* Functions for handling local APICs */
-
-ULONG Read8254Timer(VOID)
-{
- ULONG Count;
-
- WRITE_PORT_UCHAR((PUCHAR)0x43, 0x00);
- Count = READ_PORT_UCHAR((PUCHAR)0x40);
- Count |= READ_PORT_UCHAR((PUCHAR)0x40) << 8;
-
- return Count;
-}
-
-VOID WaitFor8254Wraparound(VOID)
-{
- ULONG CurCount, PrevCount = ~0;
- LONG Delta;
-
- CurCount = Read8254Timer();
- do
- {
- PrevCount = CurCount;
- CurCount = Read8254Timer();
- Delta = CurCount - PrevCount;
-
- /*
- * This limit for delta seems arbitrary, but it isn't, it's
- * slightly above the level of error a buggy Mercury/Neptune
- * chipset timer can cause.
- */
-
- }
- while (Delta < 300);
-}
-
-#define HZ (100)
-#define APIC_DIVISOR (16)
-
-VOID APICSetupLVTT(ULONG ClockTicks)
-{
- ULONG tmp;
-
- tmp = GET_APIC_VERSION(APICRead(APIC_VER));
- if (!APIC_INTEGRATED(tmp))
- {
- tmp = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) | APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;;
- }
- else
- {
- /* Periodic timer */
- tmp = APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;;
- }
- APICWrite(APIC_LVTT, tmp);
-
- tmp = APICRead(APIC_TDCR);
- tmp &= ~(APIC_TDCR_1 | APIC_TIMER_BASE_DIV);
- tmp |= APIC_TDCR_16;
- APICWrite(APIC_TDCR, tmp);
- APICWrite(APIC_ICRT, ClockTicks / APIC_DIVISOR);
-}
-
-
-VOID APICCalibrateTimer(ULONG CPU)
-{
- ULARGE_INTEGER t1, t2;
- LONG tt1, tt2;
-
- DPRINT("Calibrating APIC timer for CPU %d\n", CPU);
-
- APICSetupLVTT(1000000000);
-
- /*
- * The timer chip counts down to zero. Let's wait
- * for a wraparound to start exact measurement:
- * (the current tick might have been already half done)
- */
- WaitFor8254Wraparound();
-
- /*
- * We wrapped around just now. Let's start
- */
- ReadPentiumClock(&t1);
- tt1 = APICRead(APIC_CCRT);
-
- WaitFor8254Wraparound();
-
-
- tt2 = APICRead(APIC_CCRT);
- ReadPentiumClock(&t2);
-
- CPUMap[CPU].BusSpeed = (HZ * (long)(tt1 - tt2) * APIC_DIVISOR);
- CPUMap[CPU].CoreSpeed = (HZ * (t2.QuadPart - t1.QuadPart));
-
- /* Setup timer for normal operation */
-// APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 100); // 100ns
- APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 10000); // 10ms
-// APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 100000); // 100ms
-
- DPRINT("CPU clock speed is %ld.%04ld MHz.\n",
- CPUMap[CPU].CoreSpeed/1000000,
- CPUMap[CPU].CoreSpeed%1000000);
-
- DPRINT("Host bus clock speed is %ld.%04ld MHz.\n",
- CPUMap[CPU].BusSpeed/1000000,
- CPUMap[CPU].BusSpeed%1000000);
-}
-
-VOID
[truncated at 1000 lines; 846 more skipped]
reactos/hal/halx86
diff -N mps.S
--- mps.S 28 Nov 2004 01:30:01 -0000 1.4
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,109 +0,0 @@
-/* $Id: mps.S,v 1.4 2004/11/28 01:30:01 hbirr Exp $
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/x86/mps.S
- * PURPOSE: Intel MultiProcessor specification support
- * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
- * UPDATE HISTORY:
- * Created 12/04/2001
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <internal/i386/segment.h>
-
-/* FUNCTIONS *****************************************************************/
-
-#define BEFORE \
- cld; \
- pusha; \
- pushl %ds; \
- pushl %es; \
- pushl %fs; \
- pushl %gs; \
- movl $(KERNEL_DS), %eax; \
- movl %eax, %ds; \
- movl %eax, %es; \
- movl %eax, %gs; \
- movl $(PCR_SELECTOR), %eax; \
- movl %eax, %fs;
-
-#define AFTER \
- popl %gs; \
- popl %fs; \
- popl %es; \
- popl %ds; \
- popa;
-
-.global _MpsIpiInterrupt
-_MpsIpiInterrupt:
- /* Save registers */
- BEFORE
-
- /* Call the C handler */
- call _MpsIpiHandler
-
- /* Return to the caller */
- AFTER
- iret
-
-
-.globl _MpsErrorInterrupt
-_MpsErrorInterrupt:
- /* Save registers */
- BEFORE
-
- /* Call the C handler */
- call _MpsErrorHandler
-
- /* Return to the caller */
- AFTER
- iret
-
-
-.globl _MpsSpuriousInterrupt
-_MpsSpuriousInterrupt:
- /* Save registers */
- BEFORE
-
- /* Call the C handler */
- call _MpsSpuriousHandler
-
- /* Return to the caller */
- AFTER
- iret
-
-.global _MpsTimerInterrupt
-_MpsTimerInterrupt:
- cld
- pusha
- movl $0xef,%ebx
- pushl %ds
- pushl %es
- pushl %fs
- pushl %gs
- movl $0xceafbeef,%eax
- pushl %eax
- movl $(KERNEL_DS),%eax
- movl %eax,%ds
- movl %eax,%es
- movl %eax,%gs
- movl $(PCR_SELECTOR),%eax
- movl %eax,%fs
- pushl %esp
- pushl %ebx
- call _MpsTimerHandler
- popl %eax
- popl %eax
- popl %eax
- popl %gs
- popl %fs
- popl %es
- popl %ds
- popa
- iret
-
-
-
-/* EOF */
reactos/hal/halx86
diff -N mpsboot.asm
--- mpsboot.asm 21 Aug 2001 20:18:27 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,106 +0,0 @@
-;
-; COPYRIGHT: See COPYING in the top level directory
-; PROJECT: ReactOS kernel
-; FILE: ntoskrnl/hal/x86/mpsboot.c
-; PURPOSE: Bootstrap code for application processors
-; PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
-; UPDATE HISTORY:
-; Created 12/04/2001
-;
-
-;
-; Memory map at this stage is:
-; 0x2000 Location of our stack
-; 0x3000 Startup code for the APs (this code)
-;
-
-;
-; Base address of common area for BSP and APs
-;
-LOAD_BASE equ 00200000h
-
-;
-; Magic value to be put in EAX when multiboot.S is called as part of the
-; application processor initialization process
-;
-AP_MAGIC equ 12481020h
-
-;
-; Segment selectors
-;
-%define KERNEL_CS (0x8)
-%define KERNEL_DS (0x10)
-
-section .text
-
-global _APstart
-global _APend
-
-; 16 bit code
-BITS 16
-
-_APstart:
- cli ; Just in case
-
- xor ax, ax
- mov ds, ax
- mov ss, ax
-
- mov eax, 3000h + APgdt - _APstart
- lgdt [eax]
-
- mov eax, cr0
- or eax, 00010001h ; Turn on protected mode and write protection
- mov cr0, eax
-
- db 0eah
- dw 3000h + flush - _APstart, KERNEL_CS
-
-; 32 bit code
-BITS 32
-
-flush:
- mov ax, KERNEL_DS
- mov ds, ax
- mov es, ax
- mov fs, ax
- mov gs, ax
- mov ss, ax
-
- ; Setup a stack for the AP
- mov eax, 2000h
- mov eax, [eax]
- mov esp, eax
-
- ; Jump to start of the kernel with AP magic in eax
- mov eax, AP_MAGIC
- jmp dword KERNEL_CS:(LOAD_BASE + 0x1000)
-
- ; Never get here
-
-
-; Temporary GDT descriptor for the APs
-
-APgdt:
-; Limit
- dw (3*8)-1
-; Base
- dd 3000h + gdt - _APstart
-
-gdt:
- dw 0x0 ; Null descriptor
- dw 0x0
- dw 0x0
- dw 0x0
-
- dw 0xffff ; Kernel code descriptor
- dw 0x0000
- dw 0x9a00
- dw 0x00cf
-
- dw 0xffff ; Kernel data descriptor
- dw 0x0000
- dw 0x9200
- dw 0x00cf
-
-_APend:
reactos/hal/halx86
diff -N mpsirql.c
--- mpsirql.c 28 Nov 2004 01:30:01 -0000 1.12
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,401 +0,0 @@
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/x86/mpsirql.c
- * PURPOSE: Implements IRQLs for multiprocessor systems
- * PROGRAMMERS: David Welch (welch@cwcom.net)
- * Casper S. Hornstrup (chorns@users.sourceforge.net)
- * UPDATE HISTORY:
- * 12/04/2001 CSH Created
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <roscfg.h>
-#include <ddk/ntddk.h>
-#include <internal/ke.h>
-#include <internal/ps.h>
-#include <ntos/minmax.h>
-#include <halirq.h>
-#include <hal.h>
-#include <mps.h>
-#include <apic.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-/* GLOBALS ******************************************************************/;
-
-
-/* FUNCTIONS ****************************************************************/
-
-KIRQL STDCALL KeGetCurrentIrql (VOID)
-/*
- * PURPOSE: Returns the current irq level
- * RETURNS: The current irq level
- */
-{
- KIRQL irql;
- ULONG Flags;
-
- Ki386SaveFlags(Flags);
- Ki386DisableInterrupts();
-
- irql = Ki386ReadFsByte(offsetof(KPCR, Irql));
- if (irql > HIGH_LEVEL)
- {
- DPRINT1 ("CurrentIrql %x\n", irql);
- KEBUGCHECK (0);
- }
- if (Flags & X86_EFLAGS_IF)
- {
- Ki386EnableInterrupts();
- }
- return irql;
-}
-
-
-VOID KeSetCurrentIrql (KIRQL NewIrql)
-/*
- * PURPOSE: Sets the current irq level without taking any action
- */
-{
- ULONG Flags;
- if (NewIrql > HIGH_LEVEL)
- {
- DPRINT1 ("NewIrql %x\n", NewIrql);
- KEBUGCHECK (0);
- }
- Ki386SaveFlags(Flags);
- Ki386DisableInterrupts();
- Ki386WriteFsByte(offsetof(KPCR, Irql), NewIrql);
- if (Flags & X86_EFLAGS_IF)
- {
- Ki386EnableInterrupts();
- }
-}
-
-VOID
-HalpLowerIrql(KIRQL NewIrql, BOOL FromHalEndSystemInterrupt)
-{
- ULONG Flags;
- if (NewIrql >= DISPATCH_LEVEL)
- {
- KeSetCurrentIrql (NewIrql);
- APICWrite(APIC_TPR, IRQL2TPR (NewIrql) & APIC_TPR_PRI);
- return;
- }
- Ki386SaveFlags(Flags);
- if (KeGetCurrentIrql() > APC_LEVEL)
- {
- KeSetCurrentIrql (DISPATCH_LEVEL);
- APICWrite(APIC_TPR, IRQL2TPR (DISPATCH_LEVEL) & APIC_TPR_PRI);
- if (FromHalEndSystemInterrupt || Ki386ReadFsByte(offsetof(KPCR, HalReserved[HAL_DPC_REQUEST])))
- {
- Ki386WriteFsByte(offsetof(KPCR, HalReserved[HAL_DPC_REQUEST]), 0);
- Ki386EnableInterrupts();
- KiDispatchInterrupt();
- if (!(Flags & X86_EFLAGS_IF))
- {
- Ki386DisableInterrupts();
- }
- }
- KeSetCurrentIrql (APC_LEVEL);
- }
- if (NewIrql == APC_LEVEL)
- {
- return;
- }
- if (KeGetCurrentThread () != NULL &&
- KeGetCurrentThread ()->ApcState.KernelApcPending)
- {
- Ki386EnableInterrupts();
- KiDeliverApc(KernelMode, NULL, NULL);
- if (!(Flags & X86_EFLAGS_IF))
- {
- Ki386DisableInterrupts();
- }
- }
- KeSetCurrentIrql (PASSIVE_LEVEL);
-}
-
-
-/**********************************************************************
- * NAME EXPORTED
- * KfLowerIrql
- *
- * DESCRIPTION
- * Restores the irq level on the current processor
- *
- * ARGUMENTS
- * NewIrql = Irql to lower to
- *
- * RETURN VALUE
- * None
- *
- * NOTES
- * Uses fastcall convention
- */
-VOID FASTCALL
-KfLowerIrql (KIRQL NewIrql)
-{
- KIRQL oldIrql = KeGetCurrentIrql();
- if (NewIrql > oldIrql)
- {
- DPRINT1 ("NewIrql %x CurrentIrql %x\n", NewIrql, oldIrql);
- KEBUGCHECK (0);
- }
- HalpLowerIrql (NewIrql, FALSE);
-}
-
-
-/**********************************************************************
- * NAME EXPORTED
- * KeLowerIrql
- *
- * DESCRIPTION
- * Restores the irq level on the current processor
- *
- * ARGUMENTS
- * NewIrql = Irql to lower to
- *
- * RETURN VALUE
- * None
- *
- * NOTES
- */
-
-VOID STDCALL
-KeLowerIrql (KIRQL NewIrql)
-{
- KfLowerIrql (NewIrql);
-}
-
-
-/**********************************************************************
- * NAME EXPORTED
- * KfRaiseIrql
- *
- * DESCRIPTION
- * Raises the hardware priority (irql)
- *
- * ARGUMENTS
- * NewIrql = Irql to raise to
- *
- * RETURN VALUE
- * previous irq level
- *
- * NOTES
- * Uses fastcall convention
- */
-
-KIRQL FASTCALL
-KfRaiseIrql (KIRQL NewIrql)
-{
- KIRQL OldIrql;
- ULONG Flags;
-
- Ki386SaveFlags(Flags);
- Ki386DisableInterrupts();
-
- OldIrql = KeGetCurrentIrql ();
-
- if (NewIrql < OldIrql)
- {
- DPRINT1 ("CurrentIrql %x NewIrql %x\n", KeGetCurrentIrql (), NewIrql);
- KEBUGCHECK (0);
- }
-
-
- if (NewIrql > DISPATCH_LEVEL)
- {
- APICWrite (APIC_TPR, IRQL2TPR(NewIrql) & APIC_TPR_PRI);
- }
- KeSetCurrentIrql (NewIrql);
- if (Flags & X86_EFLAGS_IF)
- {
- Ki386EnableInterrupts();
- }
-
- return OldIrql;
-}
-
-
-/**********************************************************************
- * NAME EXPORTED
- * KeRaiseIrql
- *
- * DESCRIPTION
- * Raises the hardware priority (irql)
- *
- * ARGUMENTS
- * NewIrql = Irql to raise to
- * OldIrql (OUT) = Caller supplied storage for the previous irql
- *
- * RETURN VALUE
- * None
- *
- * NOTES
- * Calls KfRaiseIrql
- */
-VOID STDCALL
-KeRaiseIrql (KIRQL NewIrql,
- PKIRQL OldIrql)
-{
- *OldIrql = KfRaiseIrql (NewIrql);
-}
-
-
-/**********************************************************************
- * NAME EXPORTED
- * KeRaiseIrqlToDpcLevel
- *
- * DESCRIPTION
- * Raises the hardware priority (irql) to DISPATCH level
- *
- * ARGUMENTS
- * None
- *
- * RETURN VALUE
- * Previous irq level
- *
- * NOTES
- * Calls KfRaiseIrql
- */
-
-KIRQL STDCALL
-KeRaiseIrqlToDpcLevel (VOID)
-{
- return KfRaiseIrql (DISPATCH_LEVEL);
-}
-
-
-/**********************************************************************
- * NAME EXPORTED
- * KeRaiseIrqlToSynchLevel
- *
- * DESCRIPTION
- * Raises the hardware priority (irql) to CLOCK2 level
- *
- * ARGUMENTS
- * None
- *
- * RETURN VALUE
- * Previous irq level
- *
- * NOTES
- * Calls KfRaiseIrql
- */
-
-KIRQL STDCALL
-KeRaiseIrqlToSynchLevel (VOID)
-{
- return KfRaiseIrql (CLOCK2_LEVEL);
-}
-
-
-BOOLEAN STDCALL
-HalBeginSystemInterrupt (ULONG Vector,
- KIRQL Irql,
- PKIRQL OldIrql)
-{
- ULONG Flags;
- DPRINT("Vector (0x%X) Irql (0x%X)\n", Vector, Irql);
-
- if (KeGetCurrentIrql () >= Irql)
- {
- DPRINT1("current irql %d, new irql %d\n", KeGetCurrentIrql(), Irql);
- KEBUGCHECK(0);
- }
-
- Ki386SaveFlags(Flags);
- if (Flags & X86_EFLAGS_IF)
- {
- DPRINT1("HalBeginSystemInterrupt was called with interrupt's enabled\n");
- KEBUGCHECK(0);
- }
- APICWrite (APIC_TPR, IRQL2TPR (Irql) & APIC_TPR_PRI);
- *OldIrql = KeGetCurrentIrql ();
- KeSetCurrentIrql (Irql);
- return(TRUE);
-}
-
-
-VOID STDCALL
-HalEndSystemInterrupt (KIRQL Irql,
- ULONG Unknown2)
-/*
- * FUNCTION: Finish a system interrupt and restore the specified irq level.
- */
-{
- ULONG Flags;
- Ki386SaveFlags(Flags);
-
- if (Flags & X86_EFLAGS_IF)
- {
- DPRINT1("HalEndSystemInterrupt was called with interrupt's enabled\n");
- KEBUGCHECK(0);
- }
- APICSendEOI();
- HalpLowerIrql (Irql, TRUE);
-}
-
-BOOLEAN STDCALL
-HalDisableSystemInterrupt (ULONG Vector,
- KIRQL Irql)
-{
- ULONG irq;
-
- DPRINT ("Vector (0x%X)\n", Vector);
-
- if (Vector < FIRST_DEVICE_VECTOR ||
- Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS)
- {
- DPRINT1("Not a device interrupt, vector=%x\n", Vector);
- return FALSE;
- }
-
- irq = VECTOR2IRQ (Vector);
- IOAPICMaskIrq (irq);
-
- return TRUE;
-}
-
-
-BOOLEAN STDCALL
-HalEnableSystemInterrupt (ULONG Vector,
- KIRQL Irql,
- KINTERRUPT_MODE InterruptMode)
-{
- ULONG irq;
-
- if (Vector < FIRST_DEVICE_VECTOR ||
- Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS)
- {
- DPRINT("Not a device interrupt\n");
- return FALSE;
- }
-
- irq = VECTOR2IRQ (Vector);
- IOAPICUnmaskIrq (irq);
-
- return TRUE;
-}
-
-VOID FASTCALL
-HalRequestSoftwareInterrupt(IN KIRQL Request)
-{
- switch (Request)
- {
- case APC_LEVEL:
- Ki386WriteFsByte(offsetof(KPCR, HalReserved[HAL_APC_REQUEST]), 1);
- break;
-
- case DISPATCH_LEVEL:
- Ki386WriteFsByte(offsetof(KPCR, HalReserved[HAL_DPC_REQUEST]), 1);
- break;
-
- default:
- KEBUGCHECK(0);
- }
-}
reactos/hal/halx86
diff -N pci.c
--- pci.c 15 Nov 2004 09:18:19 -0000 1.14
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,804 +0,0 @@
-/* $Id: pci.c,v 1.14 2004/11/15 09:18:19 ekohl Exp $
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/x86/pci.c
- * PURPOSE: Interfaces to the PCI bus
- * PROGRAMMER: David Welch (welch@mcmail.com)
- * Eric Kohl (ekohl@rz-online.de)
- * UPDATE HISTORY:
- * 05/06/1998: Created
- * 17/08/2000: Added preliminary pci bus scanner
- * 13/06/2001: Implemented access to pci configuration space
- */
-
-/*
- * NOTES: Sections copied from the Linux pci support
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <roscfg.h>
-#include <ddk/ntddk.h>
-#include <bus.h>
-#include <halirq.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-
-/* MACROS ******************************************************************/
-
-/* FIXME These are also defined in drivers/bus/pci/pcidef.h.
- Maybe put PCI definitions in a central include file??? */
-
-/* access type 1 macros */
-#define CONFIG_CMD(bus, dev_fn, where) \
- (0x80000000 | (((ULONG)(bus)) << 16) | (((dev_fn) & 0x1F) << 11) | (((dev_fn) & 0xE0) << 3) | ((where) & ~3))
-
-/* access type 2 macros */
-#define IOADDR(dev_fn, where) \
- (0xC000 | (((dev_fn) & 0x1F) << 8) | (where))
-#define FUNC(dev_fn) \
- ((((dev_fn) & 0xE0) >> 4) | 0xf0)
-
-#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */
-#define PCI_BASE_ADDRESS_SPACE_IO 0x01
-#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
-#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
-#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */
-#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */
-#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
-#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */
-#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)
-#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL)
-/* bit 1 is reserved if address_space = 1 */
-
-
-/* GLOBALS ******************************************************************/
-
-#define TAG_PCI TAG('P', 'C', 'I', 'H')
-
-static ULONG BusConfigType = 0; /* undetermined config type */
-static KSPIN_LOCK PciLock;
-
-/* FUNCTIONS ****************************************************************/
-
-static NTSTATUS
-ReadPciConfigUchar(UCHAR Bus,
- UCHAR Slot,
- UCHAR Offset,
- PUCHAR Value)
-{
- KIRQL oldIrql;
-
- switch (BusConfigType)
- {
- case 1:
- KeAcquireSpinLock(&PciLock, &oldIrql);
- WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
- *Value = READ_PORT_UCHAR((PUCHAR)0xCFC + (Offset & 3));
- KeReleaseSpinLock(&PciLock, oldIrql);
- return STATUS_SUCCESS;
-
- case 2:
- KeAcquireSpinLock(&PciLock, &oldIrql);
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
- WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
- *Value = READ_PORT_UCHAR((PUCHAR)(IOADDR(Slot, Offset)));
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
- KeReleaseSpinLock(&PciLock, oldIrql);
- return STATUS_SUCCESS;
- }
- return STATUS_UNSUCCESSFUL;
-}
-
-
-static NTSTATUS
-ReadPciConfigUshort(UCHAR Bus,
- UCHAR Slot,
- UCHAR Offset,
- PUSHORT Value)
-{
- KIRQL oldIrql;
-
- if ((Offset & 1) != 0)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- switch (BusConfigType)
- {
- case 1:
- KeAcquireSpinLock(&PciLock, &oldIrql);
- WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
- *Value = READ_PORT_USHORT((PUSHORT)0xCFC + (Offset & 2));
- KeReleaseSpinLock(&PciLock, oldIrql);
- return STATUS_SUCCESS;
-
- case 2:
- KeAcquireSpinLock(&PciLock, &oldIrql);
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
- WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
- *Value = READ_PORT_USHORT((PUSHORT)(IOADDR(Slot, Offset)));
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
- KeReleaseSpinLock(&PciLock, oldIrql);
- return STATUS_SUCCESS;
- }
- return STATUS_UNSUCCESSFUL;
-}
-
-
-static NTSTATUS
-ReadPciConfigUlong(UCHAR Bus,
- UCHAR Slot,
- UCHAR Offset,
- PULONG Value)
-{
- KIRQL oldIrql;
-
- if ((Offset & 3) != 0)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- switch (BusConfigType)
- {
- case 1:
- KeAcquireSpinLock(&PciLock, &oldIrql);
- WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
- *Value = READ_PORT_ULONG((PULONG)0xCFC);
- KeReleaseSpinLock(&PciLock, oldIrql);
- return STATUS_SUCCESS;
-
- case 2:
- KeAcquireSpinLock(&PciLock, &oldIrql);
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
- WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
- *Value = READ_PORT_ULONG((PULONG)(IOADDR(Slot, Offset)));
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
- KeReleaseSpinLock(&PciLock, oldIrql);
- return STATUS_SUCCESS;
- }
- return STATUS_UNSUCCESSFUL;
-}
-
-
-static NTSTATUS
-WritePciConfigUchar(UCHAR Bus,
- UCHAR Slot,
- UCHAR Offset,
- UCHAR Value)
-{
- KIRQL oldIrql;
-
- switch (BusConfigType)
- {
- case 1:
- KeAcquireSpinLock(&PciLock, &oldIrql);
- WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
- WRITE_PORT_UCHAR((PUCHAR)0xCFC + (Offset&3), Value);
- KeReleaseSpinLock(&PciLock, oldIrql);
- return STATUS_SUCCESS;
-
- case 2:
- KeAcquireSpinLock(&PciLock, &oldIrql);
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
- WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
- WRITE_PORT_UCHAR((PUCHAR)(IOADDR(Slot,Offset)), Value);
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
- KeReleaseSpinLock(&PciLock, oldIrql);
- return STATUS_SUCCESS;
- }
- return STATUS_UNSUCCESSFUL;
-}
-
-
-static NTSTATUS
-WritePciConfigUshort(UCHAR Bus,
- UCHAR Slot,
- UCHAR Offset,
- USHORT Value)
-{
- KIRQL oldIrql;
-
- if ((Offset & 1) != 0)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- switch (BusConfigType)
- {
- case 1:
- KeAcquireSpinLock(&PciLock, &oldIrql);
- WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
- WRITE_PORT_USHORT((PUSHORT)0xCFC + (Offset & 2), Value);
- KeReleaseSpinLock(&PciLock, oldIrql);
- return STATUS_SUCCESS;
-
- case 2:
- KeAcquireSpinLock(&PciLock, &oldIrql);
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
- WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
- WRITE_PORT_USHORT((PUSHORT)(IOADDR(Slot, Offset)), Value);
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
- KeReleaseSpinLock(&PciLock, oldIrql);
- return STATUS_SUCCESS;
- }
- return STATUS_UNSUCCESSFUL;
-}
-
-
-static NTSTATUS
-WritePciConfigUlong(UCHAR Bus,
- UCHAR Slot,
- UCHAR Offset,
- ULONG Value)
-{
- KIRQL oldIrql;
-
- if ((Offset & 3) != 0)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- switch (BusConfigType)
- {
- case 1:
- KeAcquireSpinLock(&PciLock, &oldIrql);
- WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
- WRITE_PORT_ULONG((PULONG)0xCFC, Value);
- KeReleaseSpinLock(&PciLock, oldIrql);
- return STATUS_SUCCESS;
-
- case 2:
- KeAcquireSpinLock(&PciLock, &oldIrql);
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
- WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
- WRITE_PORT_ULONG((PULONG)(IOADDR(Slot, Offset)), Value);
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
- KeReleaseSpinLock(&PciLock, oldIrql);
- return STATUS_SUCCESS;
- }
- return STATUS_UNSUCCESSFUL;
-}
-
-
-static ULONG STDCALL
-HalpGetPciData(PBUS_HANDLER BusHandler,
- ULONG BusNumber,
- ULONG SlotNumber,
- PVOID Buffer,
- ULONG Offset,
- ULONG Length)
-{
- PVOID Ptr = Buffer;
- ULONG Address = Offset;
- ULONG Len = Length;
- ULONG Vendor;
- UCHAR HeaderType;
-
- DPRINT("HalpGetPciData() called.\n");
- DPRINT(" BusNumber %lu\n", BusNumber);
- DPRINT(" SlotNumber %lu\n", SlotNumber);
- DPRINT(" Offset 0x%lx\n", Offset);
- DPRINT(" Length 0x%lx\n", Length);
-
- if ((Length == 0) || (BusConfigType == 0))
- return 0;
-
- ReadPciConfigUlong((UCHAR)BusNumber,
- (UCHAR)(SlotNumber & 0x1F),
- 0x00,
- &Vendor);
- /* some broken boards return 0 if a slot is empty: */
- if (Vendor == 0xFFFFFFFF || Vendor == 0)
- {
- if (BusNumber == 0 && Offset == 0 && Length >= 2)
- {
- *(PUSHORT)Buffer = PCI_INVALID_VENDORID;
- return 2;
- }
- return 0;
- }
-
- /* 0E=PCI_HEADER_TYPE */
- ReadPciConfigUchar((UCHAR)BusNumber,
- (UCHAR)(SlotNumber & 0x1F),
- 0x0E,
- &HeaderType);
- if (((HeaderType & PCI_MULTIFUNCTION) == 0) && ((SlotNumber & 0xE0) != 0))
- {
- if (Offset == 0 && Length >= 2)
- {
- *(PUSHORT)Buffer = PCI_INVALID_VENDORID;
- return 2;
- }
- return 0;
- }
- ReadPciConfigUlong((UCHAR)BusNumber,
- (UCHAR)SlotNumber,
- 0x00,
- &Vendor);
- /* some broken boards return 0 if a slot is empty: */
- if (Vendor == 0xFFFFFFFF || Vendor == 0)
- {
- if (BusNumber == 0 && Offset == 0 && Length >= 2)
- {
- *(PUSHORT)Buffer = PCI_INVALID_VENDORID;
- return 2;
- }
- return 0;
- }
-
- if ((Address & 1) && (Len >= 1))
- {
- ReadPciConfigUchar((UCHAR)BusNumber,
- (UCHAR)SlotNumber,
- (UCHAR)Address,
- Ptr);
- Ptr = (char*)Ptr + 1;
- Address++;
- Len--;
- }
-
- if ((Address & 2) && (Len >= 2))
- {
- ReadPciConfigUshort((UCHAR)BusNumber,
- (UCHAR)SlotNumber,
- (UCHAR)Address,
- Ptr);
- Ptr = (char*)Ptr + 2;
- Address += 2;
- Len -= 2;
- }
-
- while (Len >= 4)
- {
- ReadPciConfigUlong((UCHAR)BusNumber,
- (UCHAR)SlotNumber,
- (UCHAR)Address,
- Ptr);
- Ptr = (char*)Ptr + 4;
- Address += 4;
- Len -= 4;
- }
-
- if (Len >= 2)
- {
- ReadPciConfigUshort((UCHAR)BusNumber,
- (UCHAR)SlotNumber,
- (UCHAR)Address,
- Ptr);
- Ptr = (char*)Ptr + 2;
- Address += 2;
- Len -= 2;
- }
-
- if (Len >= 1)
- {
- ReadPciConfigUchar((UCHAR)BusNumber,
- (UCHAR)SlotNumber,
- (UCHAR)Address,
- Ptr);
- Ptr = (char*)Ptr + 1;
- Address++;
- Len--;
- }
-
- return Length - Len;
-}
-
-
-static ULONG STDCALL
-HalpSetPciData(PBUS_HANDLER BusHandler,
- ULONG BusNumber,
- ULONG SlotNumber,
- PVOID Buffer,
- ULONG Offset,
- ULONG Length)
-{
- PVOID Ptr = Buffer;
- ULONG Address = Offset;
- ULONG Len = Length;
- ULONG Vendor;
- UCHAR HeaderType;
-
- DPRINT("HalpSetPciData() called.\n");
- DPRINT(" BusNumber %lu\n", BusNumber);
- DPRINT(" SlotNumber %lu\n", SlotNumber);
- DPRINT(" Offset 0x%lx\n", Offset);
- DPRINT(" Length 0x%lx\n", Length);
-
- if ((Length == 0) || (BusConfigType == 0))
- return 0;
-
- ReadPciConfigUlong((UCHAR)BusNumber,
- (UCHAR)(SlotNumber & 0x1F),
- 0x00,
- &Vendor);
- /* some broken boards return 0 if a slot is empty: */
- if (Vendor == 0xFFFFFFFF || Vendor == 0)
- return 0;
-
-
- /* 0E=PCI_HEADER_TYPE */
- ReadPciConfigUchar((UCHAR)BusNumber,
- (UCHAR)(SlotNumber & 0x1F),
- 0x0E,
- &HeaderType);
- if (((HeaderType & PCI_MULTIFUNCTION) == 0) && ((SlotNumber & 0xE0) != 0))
- return 0;
-
- ReadPciConfigUlong((UCHAR)BusNumber,
- (UCHAR)SlotNumber,
- 0x00,
- &Vendor);
- /* some broken boards return 0 if a slot is empty: */
- if (Vendor == 0xFFFFFFFF || Vendor == 0)
- return 0;
-
- if ((Address & 1) && (Len >= 1))
- {
- WritePciConfigUchar((UCHAR)BusNumber,
- (UCHAR)SlotNumber,
- (UCHAR)Address,
- *(PUCHAR)Ptr);
- Ptr = (char*)Ptr + 1;
- Address++;
- Len--;
- }
-
- if ((Address & 2) && (Len >= 2))
- {
- WritePciConfigUshort((UCHAR)BusNumber,
- (UCHAR)SlotNumber,
- (UCHAR)Address,
- *(PUSHORT)Ptr);
- Ptr = (char*)Ptr + 2;
- Address += 2;
- Len -= 2;
- }
-
- while (Len >= 4)
- {
- WritePciConfigUlong((UCHAR)BusNumber,
- (UCHAR)SlotNumber,
- (UCHAR)Address,
- *(PULONG)Ptr);
- Ptr = (char*)Ptr + 4;
- Address += 4;
- Len -= 4;
- }
-
- if (Len >= 2)
- {
- WritePciConfigUshort((UCHAR)BusNumber,
- (UCHAR)SlotNumber,
- (UCHAR)Address,
- *(PUSHORT)Ptr);
- Ptr = (char*)Ptr + 2;
- Address += 2;
- Len -= 2;
- }
-
- if (Len >= 1)
- {
- WritePciConfigUchar((UCHAR)BusNumber,
- (UCHAR)SlotNumber,
- (UCHAR)Address,
- *(PUCHAR)Ptr);
- Ptr = (char*)Ptr + 1;
- Address++;
- Len--;
- }
-
- return Length - Len;
-}
-
-
-static ULONG
-GetBusConfigType(VOID)
-{
- ULONG Value;
- KIRQL oldIrql;
-
- DPRINT("GetBusConfigType() called\n");
-
- KeAcquireSpinLock(&PciLock, &oldIrql);
-
- DPRINT("Checking configuration type 1:");
- WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x01);
- Value = READ_PORT_ULONG((PULONG)0xCF8);
- WRITE_PORT_ULONG((PULONG)0xCF8, 0x80000000);
- if (READ_PORT_ULONG((PULONG)0xCF8) == 0x80000000)
- {
- WRITE_PORT_ULONG((PULONG)0xCF8, Value);
- KeReleaseSpinLock(&PciLock, oldIrql);
- DPRINT(" Success!\n");
- return 1;
- }
- WRITE_PORT_ULONG((PULONG)0xCF8, Value);
- DPRINT(" Unsuccessful!\n");
-
- DPRINT("Checking configuration type 2:");
- WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x00);
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0x00);
- WRITE_PORT_UCHAR((PUCHAR)0xCFA, 0x00);
- if (READ_PORT_UCHAR((PUCHAR)0xCF8) == 0x00 &&
- READ_PORT_UCHAR((PUCHAR)0xCFB) == 0x00)
- {
- KeReleaseSpinLock(&PciLock, oldIrql);
- DPRINT(" Success!\n");
- return 2;
- }
- KeReleaseSpinLock(&PciLock, oldIrql);
- DPRINT(" Unsuccessful!\n");
-
- DPRINT("No pci bus found!\n");
- return 0;
-}
-
-
-static ULONG STDCALL
-HalpGetPciInterruptVector(PVOID BusHandler,
- ULONG BusNumber,
- ULONG BusInterruptLevel,
- ULONG BusInterruptVector,
- PKIRQL Irql,
- PKAFFINITY Affinity)
-{
- ULONG Vector = IRQ2VECTOR(BusInterruptVector);
- *Irql = VECTOR2IRQL(Vector);
- *Affinity = 0xFFFFFFFF;
- return Vector;
-}
-
-static BOOLEAN STDCALL
-HalpTranslatePciAddress(PBUS_HANDLER BusHandler,
- ULONG BusNumber,
- PHYSICAL_ADDRESS BusAddress,
- PULONG AddressSpace,
- PPHYSICAL_ADDRESS TranslatedAddress)
-{
- if (*AddressSpace == 0)
- {
- /* memory space */
-
- }
- else if (*AddressSpace == 1)
- {
- /* io space */
-
- }
- else
- {
- /* other */
- return FALSE;
- }
-
- TranslatedAddress->QuadPart = BusAddress.QuadPart;
-
- return TRUE;
-}
-
-/*
- * Find the extent of a PCI decode..
- */
-static ULONG STDCALL
-PciSize(ULONG Base, ULONG Mask)
-{
- ULONG Size = Mask & Base; /* Find the significant bits */
- Size = Size & ~(Size - 1); /* Get the lowest of them to find the decode size */
- return Size;
-}
-
-static NTSTATUS STDCALL
-HalpAssignPciSlotResources(IN PBUS_HANDLER BusHandler,
- IN ULONG BusNumber,
- IN PUNICODE_STRING RegistryPath,
- IN PUNICODE_STRING DriverClassName,
- IN PDRIVER_OBJECT DriverObject,
- IN PDEVICE_OBJECT DeviceObject,
- IN ULONG SlotNumber,
- IN OUT PCM_RESOURCE_LIST *AllocatedResources)
-{
- ULONG DataSize;
- PCI_COMMON_CONFIG PciConfig;
- UINT Address;
- UINT ResourceCount;
- ULONG Size[PCI_TYPE0_ADDRESSES];
- NTSTATUS Status = STATUS_SUCCESS;
- UCHAR Offset;
- PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
-
- /* FIXME: Should handle 64-bit addresses */
-
- DataSize = HalpGetPciData(BusHandler,
- BusNumber,
- SlotNumber,
- &PciConfig,
- 0,
- PCI_COMMON_HDR_LENGTH);
- if (PCI_COMMON_HDR_LENGTH != DataSize)
- {
- return STATUS_UNSUCCESSFUL;
- }
-
- /* Read the PCI configuration space for the device and store base address and
- size information in temporary storage. Count the number of valid base addresses */
- ResourceCount = 0;
- for (Address = 0; Address < PCI_TYPE0_ADDRESSES; Address++)
- {
- if (0xffffffff == PciConfig.u.type0.BaseAddresses[Address])
- {
- PciConfig.u.type0.BaseAddresses[Address] = 0;
- }
- if (0 != PciConfig.u.type0.BaseAddresses[Address])
- {
- ResourceCount++;
- Offset = offsetof(PCI_COMMON_CONFIG, u.type0.BaseAddresses[Address]);
- Status = WritePciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber, Offset, 0xffffffff);
- if (! NT_SUCCESS(Status))
- {
- WritePciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber, Offset,
- PciConfig.u.type0.BaseAddresses[Address]);
- return Status;
- }
- Status = ReadPciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber,
- Offset, Size + Address);
- if (! NT_SUCCESS(Status))
- {
- WritePciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber, Offset,
- PciConfig.u.type0.BaseAddresses[Address]);
- return Status;
- }
- Status = WritePciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber, Offset,
- PciConfig.u.type0.BaseAddresses[Address]);
- if (! NT_SUCCESS(Status))
- {
- return Status;
- }
- }
- }
-
- if (0 != PciConfig.u.type0.InterruptLine)
- {
- ResourceCount++;
- }
-
- /* Allocate output buffer and initialize */
- *AllocatedResources = ExAllocatePoolWithTag(PagedPool,
- sizeof(CM_RESOURCE_LIST) +
- (ResourceCount - 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR),
- TAG_PCI);
- if (NULL == *AllocatedResources)
- {
- return STATUS_NO_MEMORY;
- }
- (*AllocatedResources)->Count = 1;
- (*AllocatedResources)->List[0].InterfaceType = PCIBus;
- (*AllocatedResources)->List[0].BusNumber = BusNumber;
- (*AllocatedResources)->List[0].PartialResourceList.Version = 1;
- (*AllocatedResources)->List[0].PartialResourceList.Revision = 1;
- (*AllocatedResources)->List[0].PartialResourceList.Count = ResourceCount;
- Descriptor = (*AllocatedResources)->List[0].PartialResourceList.PartialDescriptors;
-
- /* Store configuration information */
- for (Address = 0; Address < PCI_TYPE0_ADDRESSES; Address++)
- {
- if (0 != PciConfig.u.type0.BaseAddresses[Address])
- {
- if (PCI_BASE_ADDRESS_SPACE_MEMORY ==
- (PciConfig.u.type0.BaseAddresses[Address] & PCI_BASE_ADDRESS_SPACE))
- {
- Descriptor->Type = CmResourceTypeMemory;
- Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; /* FIXME I have no idea... */
- Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE; /* FIXME Just a guess */
- Descriptor->u.Memory.Start.QuadPart = (PciConfig.u.type0.BaseAddresses[Address] & PCI_BASE_ADDRESS_MEM_MASK);
- Descriptor->u.Memory.Length = PciSize(Size[Address], PCI_BASE_ADDRESS_MEM_MASK);
- }
- else if (PCI_BASE_ADDRESS_SPACE_IO ==
- (PciConfig.u.type0.BaseAddresses[Address] & PCI_BASE_ADDRESS_SPACE))
- {
- Descriptor->Type = CmResourceTypePort;
- Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; /* FIXME I have no idea... */
- Descriptor->Flags = CM_RESOURCE_PORT_IO; /* FIXME Just a guess */
- Descriptor->u.Port.Start.QuadPart = PciConfig.u.type0.BaseAddresses[Address] &= PCI_BASE_ADDRESS_IO_MASK;
- Descriptor->u.Port.Length = PciSize(Size[Address], PCI_BASE_ADDRESS_IO_MASK & 0xffff);
- }
- else
- {
- ASSERT(FALSE);
- return STATUS_UNSUCCESSFUL;
- }
- Descriptor++;
- }
- }
-
- if (0 != PciConfig.u.type0.InterruptLine)
- {
- Descriptor->Type = CmResourceTypeInterrupt;
- Descriptor->ShareDisposition = CmResourceShareShared; /* FIXME Just a guess */
- Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE; /* FIXME Just a guess */
- Descriptor->u.Interrupt.Level = PciConfig.u.type0.InterruptLine;
- Descriptor->u.Interrupt.Vector = PciConfig.u.type0.InterruptLine;
- Descriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
-
- Descriptor++;
- }
-
- ASSERT(Descriptor == (*AllocatedResources)->List[0].PartialResourceList.PartialDescriptors + ResourceCount);
-
- /* FIXME: Should store the resources in the registry resource map */
-
- return Status;
-}
-
-
-VOID
-HalpInitPciBus(VOID)
-{
- PBUS_HANDLER BusHandler;
-
- DPRINT("HalpInitPciBus() called.\n");
-
- KeInitializeSpinLock (&PciLock);
-
- BusConfigType = GetBusConfigType();
- if (BusConfigType == 0)
- return;
-
- DPRINT("Bus configuration %lu used\n", BusConfigType);
-
- /* pci bus (bus 0) handler */
- BusHandler = HalpAllocateBusHandler(PCIBus,
- PCIConfiguration,
- 0);
- BusHandler->GetBusData = (pGetSetBusData)HalpGetPciData;
- BusHandler->SetBusData = (pGetSetBusData)HalpSetPciData;
- BusHandler->GetInterruptVector =
- (pGetInterruptVector)HalpGetPciInterruptVector;
- BusHandler->TranslateBusAddress =
- (pTranslateBusAddress)HalpTranslatePciAddress;
-// BusHandler->AdjustResourceList =
-// (pGetSetBusData)HalpAdjustPciResourceList;
- BusHandler->AssignSlotResources =
- (pAssignSlotResources)HalpAssignPciSlotResources;
-
-
- /* agp bus (bus 1) handler */
- BusHandler = HalpAllocateBusHandler(PCIBus,
- PCIConfiguration,
- 1);
- BusHandler->GetBusData = (pGetSetBusData)HalpGetPciData;
- BusHandler->SetBusData = (pGetSetBusData)HalpSetPciData;
- BusHandler->GetInterruptVector =
- (pGetInterruptVector)HalpGetPciInterruptVector;
- BusHandler->TranslateBusAddress =
- (pTranslateBusAddress)HalpTranslatePciAddress;
-// BusHandler->AdjustResourceList =
-// (pGetSetBusData)HalpAdjustPciResourceList;
- BusHandler->AssignSlotResources =
- (pAssignSlotResources)HalpAssignPciSlotResources;
-
-
- /* PCI bus (bus 2) handler */
- BusHandler = HalpAllocateBusHandler(PCIBus,
- PCIConfiguration,
- 2);
- BusHandler->GetBusData = (pGetSetBusData)HalpGetPciData;
- BusHandler->SetBusData = (pGetSetBusData)HalpSetPciData;
- BusHandler->GetInterruptVector =
- (pGetInterruptVector)HalpGetPciInterruptVector;
- BusHandler->TranslateBusAddress =
- (pTranslateBusAddress)HalpTranslatePciAddress;
-// BusHandler->AdjustResourceList =
-// (pGetSetBusData)HalpAdjustPciResourceList;
- BusHandler->AssignSlotResources =
- (pAssignSlotResources)HalpAssignPciSlotResources;
-
- DPRINT("HalpInitPciBus() finished.\n");
-}
-
-/* EOF */
reactos/hal/halx86
diff -N portio.c
--- portio.c 28 Dec 2003 22:38:09 -0000 1.4
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,342 +0,0 @@
-/* $Id: portio.c,v 1.4 2003/12/28 22:38:09 fireball Exp $
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/x86/portio.c
- * PURPOSE: Port I/O functions
- * PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
- * UPDATE HISTORY:
- * Created 18/10/99
- */
-
-#include <ddk/ntddk.h>
-
-
-/* FUNCTIONS ****************************************************************/
-
-/*
- * This file contains the definitions for the x86 IO instructions
- * inb/inw/inl/outb/outw/outl and the "string versions" of the same
- * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
- * versions of the single-IO instructions (inb_p/inw_p/..).
- *
- * This file is not meant to be obfuscating: it's just complicated
- * to (a) handle it all in a way that makes gcc able to optimize it
- * as well as possible and (b) trying to avoid writing the same thing
- * over and over again with slight variations and possibly making a
- * mistake somewhere.
- */
-
-/*
- * Thanks to James van Artsdalen for a better timing-fix than
- * the two short jumps: using outb's to a nonexistent port seems
- * to guarantee better timings even on fast machines.
- *
- * On the other hand, I'd like to be sure of a non-existent port:
- * I feel a bit unsafe about using 0x80 (should be safe, though)
- *
- * Linus
- */
-
-#if defined(__GNUC__)
-
-#ifdef SLOW_IO_BY_JUMPING
-#define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
-#else
-#define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
-#endif
-
-#elif defined(_MSC_VER)
-
-#ifdef SLOW_IO_BY_JUMPING
-#define __SLOW_DOWN_IO __asm jmp 1f __asm jmp 1f 1f:
-#else
-#define __SLOW_DOWN_IO __asm out 0x80, al
-#endif
-
-#else
-#error Unknown compiler for inline assembler
-#endif
-
-
-#ifdef REALLY_SLOW_IO
-#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
-#else
-#define SLOW_DOWN_IO __SLOW_DOWN_IO
-#endif
-
-VOID STDCALL
-READ_PORT_BUFFER_UCHAR (PUCHAR Port,
- PUCHAR Buffer,
- ULONG Count)
-{
-#if defined(__GNUC__)
- __asm__ __volatile__ ("cld ; rep ; insb\n\t"
- : "=D" (Buffer), "=c" (Count)
- : "d" (Port),"0" (Buffer),"1" (Count));
-#elif defined(_MSC_VER)
- __asm
- {
- mov edx, Port
- mov edi, Buffer
- mov ecx, Count
- cld
- rep ins byte ptr[edi], dx
- }
-#else
-#error Unknown compiler for inline assembler
-#endif
-}
-
-VOID STDCALL
-READ_PORT_BUFFER_USHORT (PUSHORT Port,
- PUSHORT Buffer,
- ULONG Count)
-{
-#if defined(__GNUC__)
- __asm__ __volatile__ ("cld ; rep ; insw"
- : "=D" (Buffer), "=c" (Count)
- : "d" (Port),"0" (Buffer),"1" (Count));
-#elif defined(_MSC_VER)
- __asm
- {
- mov edx, Port
- mov edi, Buffer
- mov ecx, Count
- cld
- rep ins word ptr[edi], dx
- }
-#else
-#error Unknown compiler for inline assembler
-#endif
-}
-
-VOID STDCALL
-READ_PORT_BUFFER_ULONG (PULONG Port,
- PULONG Buffer,
- ULONG Count)
-{
-#if defined(__GNUC__)
- __asm__ __volatile__ ("cld ; rep ; insl"
- : "=D" (Buffer), "=c" (Count)
- : "d" (Port),"0" (Buffer),"1" (Count));
-#elif defined(_MSC_VER)
- __asm
- {
- mov edx, Port
- mov edi, Buffer
- mov ecx, Count
- cld
- rep ins dword ptr[edi], dx
- }
-#else
-#error Unknown compiler for inline assembler
-#endif
-}
-
-UCHAR STDCALL
-READ_PORT_UCHAR (PUCHAR Port)
-{
- UCHAR Value;
-
-#if defined(__GNUC__)
- __asm__("inb %w1, %0\n\t"
- : "=a" (Value)
- : "d" (Port));
-#elif defined(_MSC_VER)
- __asm
- {
- mov edx, Port
- in al, dx
- mov Value, al
- }
-#else
-#error Unknown compiler for inline assembler
-#endif
-
- SLOW_DOWN_IO;
- return(Value);
-}
-
-USHORT STDCALL
-READ_PORT_USHORT (PUSHORT Port)
-{
- USHORT Value;
-
-#if defined(__GNUC__)
- __asm__("inw %w1, %0\n\t"
- : "=a" (Value)
- : "d" (Port));
-#elif defined(_MSC_VER)
- __asm
- {
- mov edx, Port
- in ax, dx
- mov Value, ax
- }
-#else
-#error Unknown compiler for inline assembler
-#endif
- SLOW_DOWN_IO;
- return(Value);
-}
-
-ULONG STDCALL
-READ_PORT_ULONG (PULONG Port)
-{
- ULONG Value;
-
-#if defined(__GNUC__)
- __asm__("inl %w1, %0\n\t"
- : "=a" (Value)
- : "d" (Port));
-#elif defined(_MSC_VER)
- __asm
- {
- mov edx, Port
- in eax, dx
- mov Value, eax
- }
-#else
-#error Unknown compiler for inline assembler
-#endif
- SLOW_DOWN_IO;
- return(Value);
-}
-
-VOID STDCALL
-WRITE_PORT_BUFFER_UCHAR (PUCHAR Port,
- PUCHAR Buffer,
- ULONG Count)
-{
-#if defined(__GNUC__)
- __asm__ __volatile__ ("cld ; rep ; outsb"
- : "=S" (Buffer), "=c" (Count)
- : "d" (Port),"0" (Buffer),"1" (Count));
-#elif defined(_MSC_VER)
- __asm
- {
- mov edx, Port
- mov esi, Buffer
- mov ecx, Count
- cld
- rep outs
- }
-#else
-#error Unknown compiler for inline assembler
-#endif
-}
-
-VOID STDCALL
-WRITE_PORT_BUFFER_USHORT (PUSHORT Port,
- PUSHORT Buffer,
- ULONG Count)
-{
-#if defined(__GNUC__)
- __asm__ __volatile__ ("cld ; rep ; outsw"
- : "=S" (Buffer), "=c" (Count)
- : "d" (Port),"0" (Buffer),"1" (Count));
-#elif defined(_MSC_VER)
- __asm
- {
- mov edx, Port
- mov esi, Buffer
- mov ecx, Count
- cld
- rep outsw
- }
-#else
-#error Unknown compiler for inline assembler
-#endif
-}
-
-VOID STDCALL
-WRITE_PORT_BUFFER_ULONG (PULONG Port,
- PULONG Buffer,
- ULONG Count)
-{
-#if defined(__GNUC__)
- __asm__ __volatile__ ("cld ; rep ; outsl"
- : "=S" (Buffer), "=c" (Count)
- : "d" (Port),"0" (Buffer),"1" (Count));
-#elif defined(_MSC_VER)
- __asm
- {
- mov edx, Port
- mov esi, Buffer
- mov ecx, Count
- cld
- rep outsd
- }
-#else
-#error Unknown compiler for inline assembler
-#endif
-}
-
-VOID STDCALL
-WRITE_PORT_UCHAR (PUCHAR Port,
- UCHAR Value)
-{
-#if defined(__GNUC__)
- __asm__("outb %0, %w1\n\t"
- :
- : "a" (Value),
- "d" (Port));
-#elif defined(_MSC_VER)
- __asm
- {
- mov edx, Port
- mov al, Value
- out dx,al
- }
-#else
-#error Unknown compiler for inline assembler
-#endif
- SLOW_DOWN_IO;
-}
-
-VOID STDCALL
-WRITE_PORT_USHORT (PUSHORT Port,
- USHORT Value)
-{
-#if defined(__GNUC__)
- __asm__("outw %0, %w1\n\t"
- :
- : "a" (Value),
- "d" (Port));
-#elif defined(_MSC_VER)
- __asm
- {
- mov edx, Port
- mov ax, Value
- out dx,ax
- }
-#else
-#error Unknown compiler for inline assembler
-#endif
- SLOW_DOWN_IO;
-}
-
-VOID STDCALL
-WRITE_PORT_ULONG (PULONG Port,
- ULONG Value)
-{
-#if defined(__GNUC__)
- __asm__("outl %0, %w1\n\t"
- :
- : "a" (Value),
- "d" (Port));
-#elif defined(_MSC_VER)
- __asm
- {
- mov edx, Port
- mov eax, Value
- out dx,eax
- }
-#else
-#error Unknown compiler for inline assembler
-#endif
- SLOW_DOWN_IO;
-}
-
-/* EOF */
reactos/hal/halx86
diff -N pwroff.c
--- pwroff.c 28 Dec 2003 22:38:09 -0000 1.4
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,121 +0,0 @@
-/* $Id: pwroff.c,v 1.4 2003/12/28 22:38:09 fireball Exp $
- *
- * FILE : reactos/hal/x86/apm.c
- * DESCRIPTION: Turn CPU off...
- * PROJECT : ReactOS Operating System
- * AUTHOR : D. Lindauer (July 11 1997)
- * NOTE : This program is public domain
- * REVISIONS :
- * 1999-12-26
- */
-
-#define APM_FUNCTION_AVAILABLE 0x5300
-#define APM_FUNCTION_CONNREAL 0x5301
-#define APM_FUNCTION_POWEROFF 0x5307
-#define APM_FUNCTION_ENABLECPU 0x530d
-#define APM_FUNCTION_ENABLEAPM 0x530e
-
-#define APM_DEVICE_BIOS 0
-#define APM_DEVICE_ALL 1
-
-#define APM_MODE_DISABLE 0
-#define APM_MODE_ENABLE 1
-
-
-
-#if defined(__GNUC__)
-
-nopm db 'No power management functionality',10,13,'$'
-errmsg db 'Power management error',10,13,'$'
-wrongver db 'Need APM version 1.1 or better',10,13,'$'
-;
-; Entry point
-;
-go:
- mov dx,offset nopm
- jc error
- cmp ax,101h ; See if version 1.1 or greater
- mov dx,offset wrongver
- jc error
-
- mov [ver],ax
- mov ax,5301h ; Do a real mode connection
- mov bx,0 ; device = BIOS
- int 15h
- jnc noconerr
-
- cmp ah,2 ; Pass if already connected
- mov dx,offset errmsg ; else error
- jnz error
-noconerr:
- mov ax,530eh ; Enable latest version of APM
- mov bx,0 ; device = BIOS
- mov cx,[ver] ; version
- int 15h
- mov dx,offset errmsg
- jc error
-
- mov ax,530dh ; Now engage and enable CPU management
- mov bx,1 ; device = all
- mov cx,1 ; enable
- int 15h
- mov dx,offset errmsg
- jc error
-
- mov ax,530fh
- mov bx,1 ; device = ALL
- mov cx,1 ; enable
- int 15h
- mov dx,offset errmsg
- jc error
-
- mov dx,offset errmsg
-error:
- call print
- mov ax,4c01h
- int 21h
- int 3
- end start
-
-
-BOOLEAN
-ApmCall (
- DWORD Function,
- DWORD Device,
- DWORD Mode
- )
-{
- /* AX <== Function */
- /* BX <== Device */
- /* CX <== Mode */
- __asm__("int 21\n"); /* 0x15 */
-}
-
-#elif defined(_MSC_VER)
-#else
-#error Unknown compiler for inline assembler
-#endif
-
-
-BOOLEAN
-HalPowerOff (VOID)
-{
- ApmCall (
- APM_FUNCTION_AVAILABLE,
- APM_DEVICE_BIOS,
- 0
- );
- ApmCall (
- APM_FUNCTION_ENABLEAPM,
- );
- /* Shutdown CPU */
- ApmCall (
- APM_FUNCTION_POWEROFF,
- APM_DEVICE_ALL,
- 3
- );
- return TRUE;
-}
-
-
-/* EOF */
reactos/hal/halx86
diff -N reboot.c
--- reboot.c 20 Jul 2004 21:25:36 -0000 1.7
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,72 +0,0 @@
-/* $Id: reboot.c,v 1.7 2004/07/20 21:25:36 hbirr Exp $
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/x86/reboot.c
- * PURPOSE: Reboot functions.
- * PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
- * UPDATE HISTORY:
- * Created 11/10/99
- */
-
-
-#include <ddk/ntddk.h>
-#include <hal.h>
-
-
-static VOID
-HalReboot (VOID)
-{
- char data;
- extern PVOID HalpZeroPageMapping;
-
- /* enable warm reboot */
- ((PUCHAR)HalpZeroPageMapping)[0x472] = 0x34;
- ((PUCHAR)HalpZeroPageMapping)[0x473] = 0x12;
-
- /* disable interrupts */
- Ki386DisableInterrupts();
-
-
- /* disable periodic interrupt (RTC) */
- WRITE_PORT_UCHAR((PUCHAR)0x70, 0x0b);
- data = READ_PORT_UCHAR((PUCHAR)0x71);
- WRITE_PORT_UCHAR((PUCHAR)0x71, (UCHAR)(data & 0xbf));
-
- /* */
- WRITE_PORT_UCHAR((PUCHAR)0x70, 0x0a);
- data = READ_PORT_UCHAR((PUCHAR)0x71);
- WRITE_PORT_UCHAR((PUCHAR)0x71, (UCHAR)((data & 0xf0) | 0x06));
-
- /* */
- WRITE_PORT_UCHAR((PUCHAR)0x70, 0x15);
-
- /* generate RESET signal via keyboard controller */
- WRITE_PORT_UCHAR((PUCHAR)0x64, 0xfe);
-
- /* stop the processor */
-#if 1
- Ki386HaltProcessor();
- for(;;);
-#endif
-}
-
-
-VOID STDCALL
-HalReturnToFirmware (
- ULONG Action
- )
-{
- if (Action == FIRMWARE_HALT)
- {
- DbgPrint ("HalReturnToFirmware called!\n");
- DbgBreakPoint ();
- }
- else if (Action == FIRMWARE_REBOOT)
- {
- HalReleaseDisplayOwnership();
- HalReboot ();
- }
-}
-
-/* EOF */
reactos/hal/halx86
diff -N spinlock.c
--- spinlock.c 22 Oct 2004 20:08:22 -0000 1.9
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,101 +0,0 @@
-/* $Id: spinlock.c,v 1.9 2004/10/22 20:08:22 ekohl Exp $
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/x86/spinlock.c
- * PURPOSE: Implements spinlocks
- * PROGRAMMER: David Welch (welch@cwcom.net)
- * Eric Kohl (ekohl@rz-online.de)
- * UPDATE HISTORY:
- * 09/06/2000 Created
- */
-
-/*
- * NOTE: On a uniprocessor machine spinlocks are implemented by raising
- * the irq level
- */
-
-/* INCLUDES ****************************************************************/
-
-#include <ddk/ntddk.h>
-
-#include <internal/debug.h>
-
-/* FUNCTIONS ***************************************************************/
-
-VOID STDCALL
-KeAcquireSpinLock (
- PKSPIN_LOCK SpinLock,
- PKIRQL OldIrql
- )
-/*
- * FUNCTION: Acquires a spinlock
- * ARGUMENTS:
- * SpinLock = Spinlock to acquire
- * OldIrql (OUT) = Caller supplied storage for the previous irql
- */
-{
- *OldIrql = KfAcquireSpinLock(SpinLock);
-}
-
-KIRQL FASTCALL
-KeAcquireSpinLockRaiseToSynch (
- PKSPIN_LOCK SpinLock
- )
-{
- KIRQL OldIrql;
-
- OldIrql = KfRaiseIrql(SYNCH_LEVEL);
- KiAcquireSpinLock(SpinLock);
-
- return OldIrql;
-}
-
-VOID STDCALL
-KeReleaseSpinLock (
- PKSPIN_LOCK SpinLock,
- KIRQL NewIrql
- )
-/*
- * FUNCTION: Releases a spinlock
- * ARGUMENTS:
- * SpinLock = Spinlock to release
- * NewIrql = Irql level before acquiring the spinlock
- */
-{
- KfReleaseSpinLock(SpinLock, NewIrql);
-}
-
-KIRQL FASTCALL
-KfAcquireSpinLock (
- PKSPIN_LOCK SpinLock
- )
-{
- KIRQL OldIrql;
-
- ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
-
- OldIrql = KfRaiseIrql(DISPATCH_LEVEL);
- KiAcquireSpinLock(SpinLock);
-
- return OldIrql;
-}
-
-VOID FASTCALL
-KfReleaseSpinLock (
- PKSPIN_LOCK SpinLock,
- KIRQL NewIrql
- )
-/*
- * FUNCTION: Releases a spinlock
- * ARGUMENTS:
- * SpinLock = Spinlock to release
- * NewIrql = Irql level before acquiring the spinlock
- */
-{
- ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL || KeGetCurrentIrql() == SYNCH_LEVEL);
- KiReleaseSpinLock(SpinLock);
- KfLowerIrql(NewIrql);
-}
-
-/* EOF */
reactos/hal/halx86
diff -N sysbus.c
--- sysbus.c 1 Nov 2004 14:37:19 -0000 1.7
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,70 +0,0 @@
-/* $Id: sysbus.c,v 1.7 2004/11/01 14:37:19 hbirr Exp $
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/sysbus.c
- * PURPOSE: System bus handler functions
- * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
- * UPDATE HISTORY:
- * 09/04/2000 Created
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <roscfg.h>
-#include <ddk/ntddk.h>
-#include <bus.h>
-#include <halirq.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-
-/* FUNCTIONS ****************************************************************/
-
-ULONG STDCALL
-HalpGetSystemInterruptVector(PVOID BusHandler,
- ULONG BusNumber,
- ULONG BusInterruptLevel,
- ULONG BusInterruptVector,
- PKIRQL Irql,
- PKAFFINITY Affinity)
-{
- ULONG Vector = IRQ2VECTOR(BusInterruptVector);
- *Irql = VECTOR2IRQL(Vector);
- *Affinity = 0xFFFFFFFF;
- return Vector;
-}
-
-
-BOOLEAN STDCALL
-HalpTranslateSystemBusAddress(PBUS_HANDLER BusHandler,
- ULONG BusNumber,
- PHYSICAL_ADDRESS BusAddress,
- PULONG AddressSpace,
- PPHYSICAL_ADDRESS TranslatedAddress)
-{
- ULONG BaseAddress = 0;
-
- if (*AddressSpace == 0)
- {
- /* memory space */
-
- }
- else if (*AddressSpace == 1)
- {
- /* io space */
-
- }
- else
- {
- /* other */
- return FALSE;
- }
-
- TranslatedAddress->QuadPart = BusAddress.QuadPart + BaseAddress;
-
- return TRUE;
-}
-
-/* EOF */
reactos/hal/halx86
diff -N sysinfo.c
--- sysinfo.c 26 Feb 2003 14:14:03 -0000 1.4
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,76 +0,0 @@
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/x86/sysinfo.c
- * PURPOSE: Getting system information
- * PROGRAMMER: David Welch (welch@mcmail.com)
- * UPDATE HISTORY:
- * Created 22/05/98
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ddk/ntddk.h>
-#include <hal.h>
-#include <bus.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-
-/* FUNCTIONS ****************************************************************/
-
-NTSTATUS STDCALL
-HalpQuerySystemInformation(IN HAL_QUERY_INFORMATION_CLASS InformationClass,
- IN ULONG BufferSize,
- IN OUT PVOID Buffer,
- OUT PULONG ReturnedLength)
-{
- ULONG DataLength;
- NTSTATUS Status;
-
- DPRINT1("HalpQuerySystemInformation() called\n");
-
- *ReturnedLength = 0;
-
- DataLength = 0;
-
- switch(InformationClass)
- {
-#if 0
- case HalInstalledBusInformation:
- Status = HalpQueryBusInformation(BufferSize,
- Buffer,
- ReturnedLength);
- break;
-#endif
-
- default:
- DataLength = 0;
- Status = STATUS_INVALID_LEVEL;
- break;
- }
-
- if (DataLength != 0)
- {
- if (DataLength > BufferSize)
- DataLength = BufferSize;
-
-// RtlCopyMemory();
-
- *ReturnedLength = DataLength;
- }
-
- return(Status);
-}
-
-
-#if 0
-NTSTATUS
-HalpSetSystemInformation(VOID)
-{
- UNIMPLEMENTED;
-}
-#endif
-
-/* EOF */
reactos/hal/halx86
diff -N time.c
--- time.c 20 Jul 2004 21:25:36 -0000 1.6
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,359 +0,0 @@
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/x86/time.c
- * PURPOSE: Getting time information
- * UPDATE HISTORY:
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ddk/ntddk.h>
-#include <string.h>
-#include <hal.h>
-#include <bus.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-/* MACROS and CONSTANTS ******************************************************/
-
-/* macro BCD_INT : convert bcd to int */
-#define BCD_INT(bcd) (((bcd & 0xf0) >> 4) * 10 + (bcd &0x0f))
-
-/* macro INT_BCD : convert int to bcd */
-#define INT_BCD(int) (((int / 10) << 4) + (int % 10))
-
-
-#define RTC_REGISTER_A 0x0A
-#define RTC_REG_A_UIP 0x80 /* Update In Progress bit */
-
-#define RTC_REGISTER_B 0x0B
-
-#define RTC_REGISTER_CENTURY 0x32
-
-/* GLOBALS ******************************************************************/
-
-static KSPIN_LOCK CmosLock = {0};
-
-/* FUNCTIONS *****************************************************************/
-
-
-static UCHAR
-HalpQueryCMOS(UCHAR Reg)
-{
- UCHAR Val;
- ULONG Flags;
-
- Reg |= 0x80;
-
- /* save flags and disable interrupts */
- Ki386SaveFlags(Flags);
- Ki386DisableInterrupts();
-
- WRITE_PORT_UCHAR((PUCHAR)0x70, Reg);
- Val = READ_PORT_UCHAR((PUCHAR)0x71);
- WRITE_PORT_UCHAR((PUCHAR)0x70, 0);
-
- /* restore flags */
- Ki386RestoreFlags(Flags);
-
- return(Val);
-}
-
-
-static VOID
-HalpSetCMOS(UCHAR Reg,
- UCHAR Val)
-{
- ULONG Flags;
-
- Reg |= 0x80;
-
- /* save flags and disable interrupts */
- Ki386SaveFlags(Flags);
- Ki386DisableInterrupts();
-
- WRITE_PORT_UCHAR((PUCHAR)0x70, Reg);
- WRITE_PORT_UCHAR((PUCHAR)0x71, Val);
- WRITE_PORT_UCHAR((PUCHAR)0x70, 0);
-
- /* restore flags */
- Ki386RestoreFlags(Flags);
-}
-
-
-static UCHAR
-HalpQueryECMOS(USHORT Reg)
-{
- UCHAR Val;
- ULONG Flags;
-
- /* save flags and disable interrupts */
- Ki386SaveFlags(Flags);
- Ki386DisableInterrupts();
-
- WRITE_PORT_UCHAR((PUCHAR)0x74, (UCHAR)(Reg & 0x00FF));
- WRITE_PORT_UCHAR((PUCHAR)0x75, (UCHAR)(Reg>>8));
- Val = READ_PORT_UCHAR((PUCHAR)0x76);
-
- /* restore flags */
- Ki386RestoreFlags(Flags);
-
- return(Val);
-}
-
-
-static VOID
-HalpSetECMOS(USHORT Reg,
- UCHAR Val)
-{
- ULONG Flags;
-
- /* save flags and disable interrupts */
- Ki386SaveFlags(Flags);
- Ki386DisableInterrupts();
-
- WRITE_PORT_UCHAR((PUCHAR)0x74, (UCHAR)(Reg & 0x00FF));
- WRITE_PORT_UCHAR((PUCHAR)0x75, (UCHAR)(Reg>>8));
- WRITE_PORT_UCHAR((PUCHAR)0x76, Val);
-
- /* restore flags */
- Ki386RestoreFlags(Flags);
-}
-
-
-VOID STDCALL
-HalQueryRealTimeClock(PTIME_FIELDS Time)
-{
- KIRQL oldIrql;
-
- KeAcquireSpinLock(&CmosLock, &oldIrql);
-
- /* check 'Update In Progress' bit */
- while (HalpQueryCMOS (RTC_REGISTER_A) & RTC_REG_A_UIP);
-
- Time->Second = BCD_INT(HalpQueryCMOS (0));
- Time->Minute = BCD_INT(HalpQueryCMOS (2));
- Time->Hour = BCD_INT(HalpQueryCMOS (4));
- Time->Weekday = BCD_INT(HalpQueryCMOS (6));
- Time->Day = BCD_INT(HalpQueryCMOS (7));
- Time->Month = BCD_INT(HalpQueryCMOS (8));
- Time->Year = BCD_INT(HalpQueryCMOS (9));
-
- if (Time->Year > 80)
- Time->Year += 1900;
- else
- Time->Year += 2000;
-
-#if 0
- /* Century */
- Time->Year += BCD_INT(HalpQueryCMOS (RTC_REGISTER_CENTURY)) * 100;
-#endif
-
- KeReleaseSpinLock(&CmosLock, oldIrql);
-
-#ifndef NDEBUG
- DbgPrint ("HalQueryRealTimeClock() %d:%d:%d %d/%d/%d\n",
- Time->Hour,
- Time->Minute,
- Time->Second,
- Time->Day,
- Time->Month,
- Time->Year
- );
-#endif
-
- Time->Milliseconds = 0;
-}
-
-
-VOID STDCALL
-HalSetRealTimeClock(PTIME_FIELDS Time)
-{
- KIRQL oldIrql;
-
- KeAcquireSpinLock(&CmosLock, &oldIrql);
-
- /* check 'Update In Progress' bit */
- while (HalpQueryCMOS (RTC_REGISTER_A) & RTC_REG_A_UIP);
-
- HalpSetCMOS (0, (UCHAR)INT_BCD(Time->Second));
- HalpSetCMOS (2, (UCHAR)INT_BCD(Time->Minute));
- HalpSetCMOS (4, (UCHAR)INT_BCD(Time->Hour));
- HalpSetCMOS (6, (UCHAR)INT_BCD(Time->Weekday));
- HalpSetCMOS (7, (UCHAR)INT_BCD(Time->Day));
- HalpSetCMOS (8, (UCHAR)INT_BCD(Time->Month));
- HalpSetCMOS (9, (UCHAR)INT_BCD(Time->Year % 100));
-
-#if 0
- /* Century */
- HalpSetCMOS (RTC_REGISTER_CENTURY, INT_BCD(Time->Year / 100));
-#endif
- KeReleaseSpinLock(&CmosLock, oldIrql);
-
-}
-
-
-BOOLEAN STDCALL
-HalGetEnvironmentVariable(PCH Name,
- PCH Value,
- USHORT ValueLength)
-{
- KIRQL oldIrql;
-
-
- if (_stricmp(Name, "LastKnownGood") != 0)
- {
- return FALSE;
- }
-
- KeAcquireSpinLock(&CmosLock, &oldIrql);
- if (HalpQueryCMOS(RTC_REGISTER_B) & 0x01)
- {
- strncpy(Value, "FALSE", ValueLength);
- }
- else
- {
- strncpy(Value, "TRUE", ValueLength);
- }
- KeReleaseSpinLock(&CmosLock, oldIrql);
-
- return TRUE;
-}
-
-
-BOOLEAN STDCALL
-HalSetEnvironmentVariable(PCH Name,
- PCH Value)
-{
- UCHAR Val;
- KIRQL oldIrql;
- BOOLEAN result = TRUE;
-
- if (_stricmp(Name, "LastKnownGood") != 0)
- return FALSE;
-
- KeAcquireSpinLock(&CmosLock, &oldIrql);
-
- Val = HalpQueryCMOS(RTC_REGISTER_B);
-
- if (_stricmp(Value, "TRUE") == 0)
- HalpSetCMOS(RTC_REGISTER_B, (UCHAR)(Val | 0x01));
- else if (_stricmp(Value, "FALSE") == 0)
- HalpSetCMOS(RTC_REGISTER_B, (UCHAR)(Val & ~0x01));
- else
- result = FALSE;
-
- KeReleaseSpinLock(&CmosLock, oldIrql);
-
- return result;
-}
-
-
-ULONG STDCALL
-HalpGetCmosData(PBUS_HANDLER BusHandler,
- ULONG BusNumber,
- ULONG SlotNumber,
- PVOID Buffer,
- ULONG Offset,
- ULONG Length)
-{
- PUCHAR Ptr = Buffer;
- ULONG Address = SlotNumber;
- ULONG Len = Length;
- KIRQL oldIrql;
-
- DPRINT("HalpGetCmosData() called.\n");
- DPRINT(" BusNumber %lu\n", BusNumber);
- DPRINT(" SlotNumber %lu\n", SlotNumber);
- DPRINT(" Offset 0x%lx\n", Offset);
- DPRINT(" Length 0x%lx\n", Length);
-
- if (Length == 0)
- return 0;
-
- if (BusNumber == 0)
- {
- /* CMOS */
- KeAcquireSpinLock(&CmosLock, &oldIrql);
- while ((Len > 0) && (Address < 0x100))
- {
- *Ptr = HalpQueryCMOS((UCHAR)Address);
- Ptr = Ptr + 1;
- Address++;
- Len--;
- }
- KeReleaseSpinLock(&CmosLock, oldIrql);
- }
- else if (BusNumber == 1)
- {
- /* Extended CMOS */
- KeAcquireSpinLock(&CmosLock, &oldIrql);
- while ((Len > 0) && (Address < 0x1000))
- {
- *Ptr = HalpQueryECMOS((USHORT)Address);
- Ptr = Ptr + 1;
- Address++;
- Len--;
- }
- KeReleaseSpinLock(&CmosLock, oldIrql);
- }
-
- return(Length - Len);
-}
-
-
-ULONG STDCALL
-HalpSetCmosData(PBUS_HANDLER BusHandler,
- ULONG BusNumber,
- ULONG SlotNumber,
- PVOID Buffer,
- ULONG Offset,
- ULONG Length)
-{
- PUCHAR Ptr = (PUCHAR)Buffer;
- ULONG Address = SlotNumber;
- ULONG Len = Length;
- KIRQL oldIrql;
-
- DPRINT("HalpSetCmosData() called.\n");
- DPRINT(" BusNumber %lu\n", BusNumber);
- DPRINT(" SlotNumber %lu\n", SlotNumber);
- DPRINT(" Offset 0x%lx\n", Offset);
- DPRINT(" Length 0x%lx\n", Length);
-
- if (Length == 0)
- return 0;
-
- if (BusNumber == 0)
- {
- /* CMOS */
- KeAcquireSpinLock(&CmosLock, &oldIrql);
- while ((Len > 0) && (Address < 0x100))
- {
- HalpSetCMOS((UCHAR)Address, *Ptr);
- Ptr = Ptr + 1;
- Address++;
- Len--;
- }
- KeReleaseSpinLock(&CmosLock, oldIrql);
- }
- else if (BusNumber == 1)
- {
- /* Extended CMOS */
- KeAcquireSpinLock(&CmosLock, &oldIrql);
- while ((Len > 0) && (Address < 0x1000))
- {
- HalpSetECMOS((USHORT)Address, *Ptr);
- Ptr = Ptr + 1;
- Address++;
- Len--;
- }
- KeReleaseSpinLock(&CmosLock, oldIrql);
- }
-
- return(Length - Len);
-}
-
-/* EOF */
reactos/hal/halx86
diff -N timer.c
--- timer.c 28 Nov 2004 01:30:01 -0000 1.8
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,367 +0,0 @@
-/*
- * ReactOS kernel
- * Copyright (C) 2000 David Welch <welch@cwcom.net>
- * Copyright (C) 1999 Gareth Owen <gaz@athene.co.uk>, Ramon von Handel
- * Copyright (C) 1991, 1992 Linus Torvalds
- *
- * This software is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this software; see the file COPYING. If not, write
- * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
- * MA 02139, USA.
- *
- */
-/* $Id: timer.c,v 1.8 2004/11/28 01:30:01 hbirr Exp $
- *
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/x86/udelay.c
- * PURPOSE: Busy waiting
- * PROGRAMMER: David Welch (david.welch@seh.ox.ac.uk)
- * UPDATE HISTORY:
- * 06/11/99 Created
- */
-
-/* INCLUDES ***************************************************************/
-
-#include <roscfg.h>
-#include <ddk/ntddk.h>
-#include <internal/ps.h>
-#include <hal.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-/* GLOBALS ******************************************************************/
-
-static unsigned int delay_count = 1;
-
-#define TMR_CTRL 0x43 /* I/O for control */
-#define TMR_CNT0 0x40 /* I/O for counter 0 */
-#define TMR_CNT1 0x41 /* I/O for counter 1 */
-#define TMR_CNT2 0x42 /* I/O for counter 2 */
-
-#define TMR_SC0 0 /* Select channel 0 */
-#define TMR_SC1 0x40 /* Select channel 1 */
-#define TMR_SC2 0x80 /* Select channel 2 */
-
-#define TMR_LOW 0x10 /* RW low byte only */
-#define TMR_HIGH 0x20 /* RW high byte only */
-#define TMR_BOTH 0x30 /* RW both bytes */
-
-#define TMR_MD0 0 /* Mode 0 */
-#define TMR_MD1 0x2 /* Mode 1 */
-#define TMR_MD2 0x4 /* Mode 2 */
-#define TMR_MD3 0x6 /* Mode 3 */
-#define TMR_MD4 0x8 /* Mode 4 */
-#define TMR_MD5 0xA /* Mode 5 */
-
-#define TMR_BCD 1 /* BCD mode */
-
-#define TMR_LATCH 0 /* Latch command */
-
-#define TMR_READ 0xF0 /* Read command */
-#define TMR_CNT 0x20 /* CNT bit (Active low, subtract it) */
-#define TMR_STAT 0x10 /* Status bit (Active low, subtract it) */
-#define TMR_CH2 0x8 /* Channel 2 bit */
-#define TMR_CH1 0x4 /* Channel 1 bit */
-#define TMR_CH0 0x2 /* Channel 0 bit */
-
-#define MILLISEC 10 /* Number of millisec between interrupts */
-#define HZ (1000 / MILLISEC) /* Number of interrupts per second */
-#define CLOCK_TICK_RATE 1193182 /* Clock frequency of the timer chip */
-#define LATCH (CLOCK_TICK_RATE / HZ) /* Count to program into the timer chip */
-#define PRECISION 8 /* Number of bits to calibrate for delay loop */
-
-static BOOLEAN UdelayCalibrated = FALSE;
-
-/* FUNCTIONS **************************************************************/
-
-/*
- * NOTE: This function MUST NOT be optimized by the compiler!
- * If it is, it obviously will not delay AT ALL, and the system
- * will appear completely frozen at boot since
- * HalpCalibrateStallExecution will never return.
- * There are three options to stop optimization:
- * 1. Use a volatile automatic variable. Making it delay quite a bit
- * due to memory accesses, and keeping the code portable. However,
- * as this involves memory access it depends on both the CPU cache,
- * e.g. if the stack used is already in a cache line or not, and
- * whether or not we're MP. If MP, another CPU could (probably would)
- * also access RAM at the same time - making the delay imprecise.
- * 2. Use compiler-specific #pragma's to disable optimization.
- * 3. Use inline assembly, making it equally unportable as #2.
- * For supported compilers we use inline assembler. For the others,
- * portable plain C.
- */
-VOID STDCALL
-__KeStallExecutionProcessor(ULONG Loops)
-{
- if (!Loops)
- {
- return;
- }
-#if defined(__GNUC__)
- __asm__ __volatile__ (
- "mov %0, %%eax\n"
- "ROSL1: dec %%eax\n"
- "jnz ROSL1" : : "d" (Loops));
-
-#elif defined(_MSC_VER)
- __asm mov eax, Loops
-ROSL1:
- __asm dec eax
- __asm jnz ROSL1
-#else
- volatile unsigned int target = Loops;
- unsigned int i;
- for (i=0; i<target;i++);
-#endif
-}
-
-VOID STDCALL KeStallExecutionProcessor(ULONG Microseconds)
-{
- PKPCR Pcr = KeGetCurrentKPCR();
-
- if (Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC)
- {
- LARGE_INTEGER EndCount, CurrentCount;
- Ki386RdTSC(EndCount);
- EndCount.QuadPart += Microseconds * (ULONGLONG)Pcr->PrcbData.MHz;
- do
- {
- Ki386RdTSC(CurrentCount);
- }
- while (CurrentCount.QuadPart < EndCount.QuadPart);
- }
- else
- {
- __KeStallExecutionProcessor((Pcr->StallScaleFactor*Microseconds)/1000);
- }
-}
-
-static ULONG Read8254Timer(VOID)
-{
- ULONG Count;
- ULONG flags;
-
- /* save flags and disable interrupts */
- Ki386SaveFlags(flags);
- Ki386DisableInterrupts();
-
- WRITE_PORT_UCHAR((PUCHAR) TMR_CTRL, TMR_SC0 | TMR_LATCH);
- Count = READ_PORT_UCHAR((PUCHAR) TMR_CNT0);
- Count |= READ_PORT_UCHAR((PUCHAR) TMR_CNT0) << 8;
-
- /* restore flags */
- Ki386RestoreFlags(flags);
-
- return Count;
-}
-
-
-static VOID WaitFor8254Wraparound(VOID)
-{
- ULONG CurCount, PrevCount = ~0;
- LONG Delta;
-
- CurCount = Read8254Timer();
-
- do
- {
- PrevCount = CurCount;
- CurCount = Read8254Timer();
- Delta = CurCount - PrevCount;
-
- /*
- * This limit for delta seems arbitrary, but it isn't, it's
- * slightly above the level of error a buggy Mercury/Neptune
- * chipset timer can cause.
- */
-
- }
- while (Delta < 300);
-}
-
-VOID HalpCalibrateStallExecution(VOID)
-{
- ULONG i;
- ULONG calib_bit;
- ULONG CurCount;
- PKPCR Pcr;
- LARGE_INTEGER StartCount, EndCount;
-
- if (UdelayCalibrated)
- {
- return;
- }
-
- UdelayCalibrated = TRUE;
- Pcr = KeGetCurrentKPCR();
-
- /* Initialise timer interrupt with MILLISEC ms interval */
- WRITE_PORT_UCHAR((PUCHAR) TMR_CTRL, TMR_SC0 | TMR_BOTH | TMR_MD2); /* binary, mode 2, LSB/MSB, ch 0 */
- WRITE_PORT_UCHAR((PUCHAR) TMR_CNT0, LATCH & 0xff); /* LSB */
- WRITE_PORT_UCHAR((PUCHAR) TMR_CNT0, LATCH >> 8); /* MSB */
-
- if (Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC)
- {
-
- WaitFor8254Wraparound();
- Ki386RdTSC(StartCount);
-
- WaitFor8254Wraparound();
- Ki386RdTSC(EndCount);
-
- Pcr->PrcbData.MHz = (ULONG)(EndCount.QuadPart - StartCount.QuadPart) / 10000;
- DPRINT("%dMHz\n", Pcr->PrcbData.MHz);
- return;
-
- }
-
- DbgPrint("Calibrating delay loop... [");
-
- /* Stage 1: Coarse calibration */
-
- WaitFor8254Wraparound();
-
- delay_count = 1;
-
- do
- {
- delay_count <<= 1; /* Next delay count to try */
-
- WaitFor8254Wraparound();
-
- __KeStallExecutionProcessor(delay_count); /* Do the delay */
-
- CurCount = Read8254Timer();
- }
- while (CurCount > LATCH / 2);
-
- delay_count >>= 1; /* Get bottom value for delay */
-
- /* Stage 2: Fine calibration */
- DbgPrint("delay_count: %d", delay_count);
-
- calib_bit = delay_count; /* Which bit are we going to test */
-
- for (i = 0; i < PRECISION; i++)
- {
- calib_bit >>= 1; /* Next bit to calibrate */
- if (!calib_bit)
- {
- break; /* If we have done all bits, stop */
- }
-
- delay_count |= calib_bit; /* Set the bit in delay_count */
-
- WaitFor8254Wraparound();
-
- __KeStallExecutionProcessor(delay_count); /* Do the delay */
-
- CurCount = Read8254Timer();
- if (CurCount <= LATCH / 2) /* If a tick has passed, turn the */
- { /* calibrated bit back off */
- delay_count &= ~calib_bit;
- }
- }
-
- /* We're finished: Do the finishing touches */
-
- delay_count /= (MILLISEC / 2); /* Calculate delay_count for 1ms */
-
- DbgPrint("]\n");
- DbgPrint("delay_count: %d\n", delay_count);
- DbgPrint("CPU speed: %d\n", delay_count / 250);
-#if 0
- DbgPrint("About to start delay loop test\n");
- DbgPrint("Waiting for five minutes...");
- for (i = 0; i < (5*60*1000*20); i++)
- {
- KeStallExecutionProcessor(50);
- }
- DbgPrint("finished\n");
- for(;;);
-#endif
-}
-
-
-VOID STDCALL
-HalCalibratePerformanceCounter(ULONG Count)
-{
- ULONG flags;
-
- /* save flags and disable interrupts */
- Ki386SaveFlags(flags);
- Ki386DisableInterrupts();
-
- __KeStallExecutionProcessor(Count);
-
- /* restore flags */
- Ki386RestoreFlags(flags);
-}
-
-
-LARGE_INTEGER STDCALL
-KeQueryPerformanceCounter(PLARGE_INTEGER PerformanceFreq)
-/*
- * FUNCTION: Queries the finest grained running count available in the system
- * ARGUMENTS:
- * PerformanceFreq (OUT) = The routine stores the number of
- * performance counter ticks per second here
- * RETURNS: The number of performance counter ticks since boot
- */
-{
- PKPCR Pcr;
- LARGE_INTEGER Value;
- ULONG Flags;
-
- Ki386SaveFlags(Flags);
- Ki386DisableInterrupts();
-
- Pcr = KeGetCurrentKPCR();
-
- if (Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC)
- {
- Ki386RestoreFlags(Flags);
- if (NULL != PerformanceFreq)
- {
- PerformanceFreq->QuadPart = Pcr->PrcbData.MHz * (ULONGLONG)1000000;
- }
- Ki386RdTSC(Value);
- }
- else
- {
- LARGE_INTEGER TicksOld;
- LARGE_INTEGER TicksNew;
- ULONG CountsLeft;
-
- Ki386RestoreFlags(Flags);
-
- if (NULL != PerformanceFreq)
- {
- PerformanceFreq->QuadPart = CLOCK_TICK_RATE;
- }
-
- do
- {
- KeQueryTickCount(&TicksOld);
- CountsLeft = Read8254Timer();
- Value.QuadPart = TicksOld.QuadPart * LATCH + (LATCH - CountsLeft);
- KeQueryTickCount(&TicksNew);
- }
- while (TicksOld.QuadPart != TicksNew.QuadPart);
- }
- return Value;
-}
-
-/* EOF */
reactos/hal/halx86/generic
diff -N adapter.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ adapter.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,679 @@
+/* $Id: adapter.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/x86/adapter.c (from ntoskrnl/io/adapter.c)
+ * PURPOSE: DMA handling
+ * PROGRAMMERS: David Welch (welch@mcmail.com)
+ * Vizzini (vizzini@plasmic.com)
+ * UPDATE HISTORY:
+ * Created 22/05/98
+ * 18-Oct-2003 Vizzini DMA support modifications
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <ddk/iotypes.h>
+#define NDEBUG
+#include <internal/debug.h>
+#include <hal.h>
+
+/* FUNCTIONS *****************************************************************/
+
+/* NOTE: IoAllocateAdapterChannel in NTOSKRNL.EXE */
+
+
+NTSTATUS STDCALL
+HalAllocateAdapterChannel(
+ PADAPTER_OBJECT AdapterObject,
+ PWAIT_CONTEXT_BLOCK WaitContextBlock,
+ ULONG NumberOfMapRegisters,
+ PDRIVER_CONTROL ExecutionRoutine)
+/*
+ * FUNCTION: Sets up an ADAPTER_OBJECT with map registers
+ * ARGUMENTS:
+ * - AdapterObject: pointer to an ADAPTER_OBJECT to set up
+ * - WaitContextBlock: Context block to be used with ExecutionRoutine
+ * - NumberOfMapRegisters: number of map registers requested
+ * - ExecutionRoutine: callback to call when map registers are allocated
+ * RETURNS:
+ * STATUS_INSUFFICIENT_RESOURCES if map registers cannot be allocated
+ * STATUS_SUCCESS in all other cases, including if the callbacak had
+ * to be queued for later delivery
+ * NOTES:
+ * - the ADAPTER_OBJECT struct is undocumented; please make copious
+ * notes in hal.h if anything is changed or improved since there is
+ * no other documentation for this data structure
+ * BUGS:
+ * - it's possible that some of this code is in the wrong place
+ * - there are many unhandled cases
+ */
+{
+ LARGE_INTEGER MinAddress;
+ LARGE_INTEGER MaxAddress;
+ LARGE_INTEGER BoundryAddressMultiple;
+ IO_ALLOCATION_ACTION Retval;
+
+ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+
+ /*
+ FIXME: return STATUS_INSUFFICIENT_RESOURCES if the NumberOfMapRegisters
+ requested is larger than the value returned by IoGetDmaAdapter.
+ */
+
+ /* set up the wait context block in case we can't run right away */
+ WaitContextBlock->DeviceRoutine = ExecutionRoutine;
+ WaitContextBlock->NumberOfMapRegisters = NumberOfMapRegisters;
+
+ /* returns true if queued, else returns false and sets the queue to busy */
+ if(KeInsertDeviceQueue(&AdapterObject->ChannelWaitQueue, &WaitContextBlock->WaitQueueEntry))
+ return STATUS_SUCCESS;
+
+ /* 24-bit max address due to 16-bit dma controllers */
+ MinAddress.QuadPart = 0x0000000;
+ MaxAddress.QuadPart = 0x1000000;
+ BoundryAddressMultiple.QuadPart = 0;
+
+ /* why 64K alignment? */
+ /*
+ * X86 lacks map registers, so for now, we allocate a contiguous
+ * block of physical memory <16MB and copy all DMA buffers into
+ * that. This can be optimized.
+ *
+ * FIXME: We propably shouldn't allocate the memory here for common
+ * buffer transfers. See a comment in IoMapTransfer about common buffer
+ * support.
+ */
+ AdapterObject->MapRegisterBase = MmAllocateContiguousAlignedMemory(
+ NumberOfMapRegisters * PAGE_SIZE,
+ MinAddress,
+ MaxAddress,
+ BoundryAddressMultiple,
+ MmCached,
+ 0x10000 );
+
+ if(!AdapterObject->MapRegisterBase)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ AdapterObject->CommittedMapRegisters = NumberOfMapRegisters;
+
+ /* call the client's AdapterControl callback with its map registers and context */
+ Retval = ExecutionRoutine(WaitContextBlock->DeviceObject, WaitContextBlock->CurrentIrp,
+ AdapterObject->MapRegisterBase, WaitContextBlock->DeviceContext);
+
+ /*
+ * KeepObject: don't free any resources; the ADAPTER_OBJECT is still in use
+ * and the caller will call IoFreeAdapterChannel later
+ *
+ * DeallocateObject: Deallocate the map registers and release the ADAPTER_OBJECT
+ * so someone else can use it
+ *
+ * DeallocateObjectKeepRegisters: release the ADAPTER_OBJECT but hang on to
+ * the map registers. The client will later call IoFreeMapRegisters.
+ *
+ * NOTE - IoFreeAdapterChannel runs the queue, so it must be called
+ * unless the adapter object is not to be freed.
+ */
+ if( Retval == DeallocateObject )
+ IoFreeAdapterChannel(AdapterObject);
+ else if(Retval == DeallocateObjectKeepRegisters)
+ {
+ /* don't free the allocated map registers - this is what IoFreeAdapterChannel checks */
+ AdapterObject->CommittedMapRegisters = 0;
+ IoFreeAdapterChannel(AdapterObject);
+ }
+
+ /*
+ * if we don't call IoFreeAdapterChannel, the next device won't get de-queued,
+ * which is what we want.
+ */
+
+ return STATUS_SUCCESS;
+}
+
+
+BOOLEAN
+HalpGrowMapBuffers(
+ IN PADAPTER_OBJECT AdapterObject,
+ IN ULONG SizeOfMapBuffers)
+/*
+ * FUNCTION: Allocate initial, or additional, map buffers for IO adapters.
+ * ARGUMENTS:
+ * AdapterObject: DMA adapter to allocate buffers for.
+ * SizeOfMapBuffers: Size of the map buffers to allocate
+ * NOTES:
+ * - Needs to be tested...
+ */
+{
+ //ULONG PagesToAllocate = BYTES_TO_PAGES(SizeOfMapBuffers);
+
+ /* TODO: Allocation */
+
+ return TRUE;
+}
+
+PADAPTER_OBJECT STDCALL
+HalpAllocateAdapterEx(
+ ULONG NumberOfMapRegisters,
+ BOOLEAN IsMaster,
+ BOOLEAN Dma32BitAddresses)
+/*
+ * FUNCTION: Allocates an ADAPTER_OBJECT, optionally creates the Master Adapter.
+ * ARGUMENTS:
+ * - NumberOfMapRegisters: Number of map registers to allocate
+ * - IsMaster: Wether this is a Master Device or not
+ * - Dma32BitAddresses: Wether 32-bit Addresses are supported
+ * RETURNS:
+ * - Pointer to Adapter Object, or NULL if failure.
+ * BUGS:
+ * - Some stuff is unhandled/incomplete
+ */
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ ULONG ObjectSize;
+ ULONG BitmapSize;
+ NTSTATUS Status;
+ ULONG AllowedMapRegisters = 64;
+ PADAPTER_OBJECT AdapterObject;
+ HANDLE Handle;
+
+ /* Allocate the Master Adapter if we haven't already
+ but make sure we're not asked to do it now, and also check if we need it */
+ if ((MasterAdapter == NULL) && (!IsMaster) && (NumberOfMapRegisters)) {
+
+ /* Allocate and Save */
+ DPRINT("Allocating the Master Adapter Object\n");
+ MasterAdapter = HalpAllocateAdapterEx(NumberOfMapRegisters,
+ TRUE,
+ Dma32BitAddresses);
+
+ /* Cancel on Failure */
+ DPRINT("Checking if Master Adapter was allocated properly\n");
+ if (!MasterAdapter) return NULL;
+ }
+
+ /* Initialize the Object Attributes for the Adapter Object */
+ InitializeObjectAttributes(&ObjectAttributes,
+ NULL,
+ OBJ_PERMANENT,
+ NULL,
+ NULL);
+
+ /* Check if this is the Master Adapter, in which case we need to allocate the bitmap */
+ if (IsMaster) {
+ /* Size due to the Bitmap + Bytes in the Bitmap Buffer (8 bytes, 64 bits)*/
+ BitmapSize = sizeof(RTL_BITMAP) + AllowedMapRegisters / 8;
+
+ /* We will put the Bitmap Buffer after the Adapter Object for simplicity */
+ ObjectSize = sizeof(ADAPTER_OBJECT) + BitmapSize;
+ } else {
+ ObjectSize = sizeof(ADAPTER_OBJECT);
+ }
+
+ /* Create and Allocate the Object */
+ DPRINT("Creating the Object\n");
+ Status = ObCreateObject(KernelMode,
+ IoAdapterObjectType,
+ &ObjectAttributes,
+ KernelMode,
+ NULL,
+ ObjectSize,
+ 0,
+ 0,
+ (PVOID)&AdapterObject);
+
+ if (!NT_SUCCESS(Status)) return NULL;
+
+ /* Add a Reference */
+ DPRINT("Referencing the Object\n");
+ Status = ObReferenceObjectByPointer(AdapterObject,
+ FILE_READ_DATA | FILE_WRITE_DATA,
+ IoAdapterObjectType,
+ KernelMode);
+
+ if (!NT_SUCCESS(Status)) return NULL;
+
+ /* It's a Valid Object, so now we can play with the memory */
+ RtlZeroMemory(AdapterObject, sizeof(ADAPTER_OBJECT));
+
+ /* Insert it into the Object Table */
+ DPRINT("Inserting the Object\n");
+ Status = ObInsertObject(AdapterObject,
+ NULL,
+ FILE_READ_DATA | FILE_WRITE_DATA,
+ 0,
+ NULL,
+ &Handle);
+
+ if (!NT_SUCCESS(Status)) return NULL;
+
+ /* We don't want the handle */
+ NtClose(Handle);
+
+ /* Set up the Adapter Object fields */
+ AdapterObject->MapRegistersPerChannel = 1;
+
+ /* Set the Master if needed (master only needed if we use Map Registers) */
+ if (NumberOfMapRegisters) AdapterObject->MasterAdapter = MasterAdapter;
+
+ /* Initalize the Channel Wait queue, which every adapter has */
+ DPRINT("Initializing the Device Queue of the Object\n");
+ KeInitializeDeviceQueue(&AdapterObject->ChannelWaitQueue);
+
+ /* Initialize the SpinLock, Queue and Bitmap, which are kept in the Master Adapter only */
+ if (IsMaster) {
+
+ DPRINT("Initializing the Master Adapter Stuff\n");
+ KeInitializeSpinLock(&AdapterObject->SpinLock);
+ InitializeListHead(&AdapterObject->AdapterQueue);
+
+ /* As said previously, we put them here for simplicity */
+ AdapterObject->MapRegisters = (PVOID)(AdapterObject + 1);
+
+ /* Set up Bitmap */
+ RtlInitializeBitMap(AdapterObject->MapRegisters,
+ (PULONG)(AdapterObject->MapRegisters + 1),
+ AllowedMapRegisters);
+
+ /* Reset the Bitmap */
+ RtlSetAllBits(AdapterObject->MapRegisters);
+ AdapterObject->NumberOfMapRegisters = 0;
+ AdapterObject->CommittedMapRegisters = 0;
+
+ /* Allocate Memory for the Map Registers */
+ AdapterObject->MapRegisterBase = ExAllocatePool(NonPagedPool,
+ AllowedMapRegisters * sizeof(DWORD));
+
+ /* Clear them */
+ RtlZeroMemory(AdapterObject->MapRegisterBase, AllowedMapRegisters * sizeof(DWORD));
+
+ /* Allocate the contigous memory */
+ DPRINT("Allocating Buffers\n");
+ HalpGrowMapBuffers(AdapterObject, 0x1000000);
+ }
+
+ DPRINT("Adapter Object allocated\n");
+ return AdapterObject;
+}
+
+
+BOOLEAN STDCALL
+IoFlushAdapterBuffers (
+ PADAPTER_OBJECT AdapterObject,
+ PMDL Mdl,
+ PVOID MapRegisterBase,
+ PVOID CurrentVa,
+ ULONG Length,
+ BOOLEAN WriteToDevice)
+/*
+ * FUNCTION: flush any data remaining in the dma controller's memory into the host memory
+ * ARGUMENTS:
+ * AdapterObject: the adapter object to flush
+ * Mdl: original MDL to flush data into
+ * MapRegisterBase: map register base that was just used by IoMapTransfer, etc
+ * CurrentVa: offset into Mdl to be flushed into, same as was passed to IoMapTransfer
+ * Length: length of the buffer to be flushed into
+ * WriteToDevice: True if it's a write, False if it's a read
+ * RETURNS:
+ * TRUE in all cases
+ * NOTES:
+ * - This copies data from the map register-backed buffer to the user's target buffer.
+ * Data is not in the user buffer until this is called.
+ * - This is only meaningful on a read operation. Return immediately for a write.
+ */
+{
+ ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+
+ /* this can happen if the card supports scatter/gather */
+ if(!MapRegisterBase)
+ return TRUE;
+
+ /* mask out (disable) the dma channel */
+ if (AdapterObject->AdapterNumber == 1) {
+
+ /* Set this for Ease */
+ PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
+
+ /* Set Channel */
+ WRITE_PORT_UCHAR(&DmaControl1->SingleMask, AdapterObject->ChannelNumber | DMA_SETMASK);
+ } else {
+ /* Set this for Ease */
+ PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
+
+ /* Set Channel */
+ WRITE_PORT_UCHAR(&DmaControl2->SingleMask, (AdapterObject->ChannelNumber - 4) | DMA_SETMASK);
+ }
+
+ if(WriteToDevice)
+ return TRUE;
+
+ memcpy(
+ (PVOID)((DWORD)MmGetSystemAddressForMdl( Mdl ) + (DWORD)CurrentVa - (DWORD)MmGetMdlVirtualAddress( Mdl )),
+ MapRegisterBase, Length );
+
+ return TRUE;
+}
+
+
+VOID STDCALL
+IoFreeAdapterChannel (PADAPTER_OBJECT AdapterObject)
+/*
+ * FUNCTION: frees DMA resources allocated by IoAllocateAdapterChannel
+ * ARGUMENTS:
+ * AdapterObject: Adapter object with resources to free
+ * NOTES:
+ * - This function releases the DMA adapter and optionally the map registers
+ * - After releasing the adapter, it checks the adapter's queue and runs
+ * each queued device object in series until the queue is empty
+ * - This is the only way the device queue is emptied.
+ */
+{
+ LARGE_INTEGER MaxAddress;
+ LARGE_INTEGER MinAddress;
+ LARGE_INTEGER BoundryAddressMultiple;
+ PWAIT_CONTEXT_BLOCK WaitContextBlock;
+ IO_ALLOCATION_ACTION Retval;
+
+ while(1)
+ {
+ /* To keep map registers, call here with the following set to 0 */
+ if(AdapterObject->CommittedMapRegisters)
+ IoFreeMapRegisters(AdapterObject, AdapterObject->MapRegisterBase, AdapterObject->CommittedMapRegisters);
+
+ if(!(WaitContextBlock = (PWAIT_CONTEXT_BLOCK)KeRemoveDeviceQueue(&AdapterObject->ChannelWaitQueue)))
+ break;
+
+ /*
+ * the following should really be done elsewhere since this
+ * function really can't return an error code. FIXME.
+ */
+
+ /* 24-bit max address due to 16-bit dma controllers */
+ MinAddress.QuadPart = 0x0000000;
+ MaxAddress.QuadPart = 0x1000000;
+ BoundryAddressMultiple.QuadPart = 0;
+
+ AdapterObject->MapRegisterBase = MmAllocateContiguousAlignedMemory(
+ WaitContextBlock->NumberOfMapRegisters * PAGE_SIZE,
+ MinAddress,
+ MaxAddress,
+ BoundryAddressMultiple,
+ MmCached,
+ 0x10000 );
+
+ if(!AdapterObject->MapRegisterBase)
+ return;
+
+ /* call the adapter control routine */
+ Retval = ((PDRIVER_CONTROL)WaitContextBlock->DeviceRoutine)(WaitContextBlock->DeviceObject, WaitContextBlock->CurrentIrp,
+ AdapterObject->MapRegisterBase, WaitContextBlock->DeviceContext);
+
+ if(Retval == KeepObject)
+ {
+ /* we're done until the caller manually calls IoFreeAdapterChannel */
+ break;
+ }
+ else if(Retval == DeallocateObjectKeepRegisters)
+ {
+ /* hide the map registers so they aren't deallocated next time around */
+ AdapterObject->CommittedMapRegisters = 0;
+ }
+ }
+}
+
+
+VOID STDCALL
+IoFreeMapRegisters (
+ IN PADAPTER_OBJECT AdapterObject,
+ IN PVOID MapRegisterBase,
+ IN ULONG NumberOfMapRegisters)
+/*
+ * FUNCTION: free map registers reserved by the system for a DMA
+ * ARGUMENTS:
+ * AdapterObject: dma adapter to free map registers on
+ * MapRegisterBase: hadle to map registers to free
+ * NumberOfRegisters: number of map registers to be freed
+ * NOTES:
+ * - XXX real windows has a funky interdependence between IoFreeMapRegisters
+ * and IoFreeAdapterChannel
+ * BUGS:
+ * - needs to be improved to use a real map register implementation
+ */
+{
+ if( AdapterObject->CommittedMapRegisters )
+ {
+ MmFreeContiguousMemory(AdapterObject->MapRegisterBase);
+ AdapterObject->MapRegisterBase = 0;
+ }
+}
+
+
+PHYSICAL_ADDRESS STDCALL
+IoMapTransfer (
+ IN PADAPTER_OBJECT AdapterObject,
+ IN PMDL Mdl,
+ IN PVOID MapRegisterBase,
+ IN PVOID CurrentVa,
+ IN OUT PULONG Length,
+ IN BOOLEAN WriteToDevice)
+/*
+ * FUNCTION: map a dma for transfer and do the dma if it's a slave
+ * ARGUMENTS:
+ * AdapterObject: adapter object to do the dma on. busmaster may pass NULL.
+ * Mdl: locked-down user buffer to DMA in to or out of
+ * MapRegisterBase: handle to map registers to use for this dma. allways NULL
+ * when doing s/g.
+ * CurrentVa: index into Mdl to transfer into/out of
+ * Length: length of transfer in/out. Only modified on out when doing s/g.
+ * WriteToDevice: TRUE if it's an output dma, FALSE otherwise
+ * RETURNS:
+ * If a busmaster: A logical address that can be used to program a dma controller
+ * Otherwise: nothing meaningful
+ * NOTES:
+ * - This function does a copyover to contiguous memory <16MB
+ * - If it's a slave transfer, this function actually performs it.
+ * BUGS:
+ * - If the controller supports scatter/gather, the copyover should not happen
+ */
+{
+ PHYSICAL_ADDRESS Address;
+ KIRQL OldIrql;
+ UCHAR Mode;
+
+#if defined(__GNUC__)
+ Address.QuadPart = 0ULL;
+#else
+ Address.QuadPart = 0;
+#endif
+
+ /* Isa System (slave) DMA? */
+ if (MapRegisterBase && !AdapterObject->MasterDevice)
+ {
+
+ KeAcquireSpinLock(&AdapterObject->SpinLock, &OldIrql);
+
+ /*
+ * FIXME: Handle case when doing common-buffer System DMA. In this case,
+ * the buffer described by MDL is already phys. contiguous and below
+ * 16 mega. Driver makes a one-shot call to IoMapTransfer during init.
+ * to program controller with the common-buffer.
+ *
+ * UPDATE: Common buffer support is in place, but it's not done in a
+ * clean way. We use the buffer passed by the MDL in case that the
+ * adapter object is marked as auto initialize. I'm not sure if this
+ * is correct and if not, how to do it properly. Note that it's also
+ * possible to allocate the common buffer with different adapter object
+ * and IoMapTransfer must still work in this case. Eventually this should
+ * be cleaned up somehow or at least this comment modified to reflect
+ * the reality.
+ * -- Filip Navara, 19/07/2004
+ */
+
+ /* Get the mode for easier coding */
+ Mode = AdapterObject->AdapterMode;
+
+ /* if it is a write to the device, copy the caller buffer to the low buffer */
+ if ((WriteToDevice) && !((PDMA_MODE)&Mode)->AutoInitialize)
+ {
+ memcpy(MapRegisterBase,
+ (char*)MmGetSystemAddressForMdl(Mdl) + ((ULONG)CurrentVa - (ULONG)MmGetMdlVirtualAddress(Mdl)),
+ *Length );
+ }
+
+ /* Writer Adapter Mode, transfer type */
+ ((PDMA_MODE)&Mode)->TransferType = (WriteToDevice ? WRITE_TRANSFER : READ_TRANSFER);
+
+ // program up the dma controller, and return
+ if (!((PDMA_MODE)&Mode)->AutoInitialize) {
+ Address = MmGetPhysicalAddress( MapRegisterBase );
+ } else {
+ Address = MmGetPhysicalAddress( CurrentVa );
+ }
+
+ /* 16-bit DMA has a shifted length */
+ if (AdapterObject->Width16Bits) *Length = (*Length >> 1);
+
+ /* Make the Transfer */
+ if (AdapterObject->AdapterNumber == 1) {
+
+ PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa; /* For Writing Less Code */
+
+ /* Reset Register */
+ WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
+
+ /* Set the Mode */
+ WRITE_PORT_UCHAR(&DmaControl1->Mode, (UCHAR)(Mode));
+
+ /* Set the Page Register (apparently always 0 for us if I trust the previous comment) */
+ WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0);
+ WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0);
+
+ /* Set the Length */
+ WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
+ (UCHAR)((*Length) - 1));
+ WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
+ (UCHAR)((*Length) - 1) >> 8);
+
+ /* Unmask the Channel */
+ WRITE_PORT_UCHAR(&DmaControl1->SingleMask, AdapterObject->ChannelNumber | DMA_CLEARMASK);
+ } else {
+ PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa; /* For Writing Less Code */
+
+ /* Reset Register */
+ WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
+
+ /* Set the Mode */
+ WRITE_PORT_UCHAR(&DmaControl2->Mode, (UCHAR)(Mode));
+
+ /* Set the Page Register (apparently always 0 for us if I trust the previous comment) */
+ WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0);
+ WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0);
+
+ /* Set the Length */
+ WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
+ (UCHAR)((*Length) - 1));
+ WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
+ (UCHAR)((*Length) - 1) >> 8);
+
+ /* Unmask the Channel */
+ WRITE_PORT_UCHAR(&DmaControl2->SingleMask, AdapterObject->ChannelNumber | DMA_CLEARMASK);
+ }
+
+ /* Release Spinlock */
+ KeReleaseSpinLock(&AdapterObject->SpinLock, OldIrql);
+
+ /*
+ NOTE: Return value should be ignored when doing System DMA.
+ Maybe return some more obvious invalid address here (thou returning
+ MapRegisterBase is also wrong;-)to catch invalid use?
+ */
+ Address.QuadPart = (ULONG)MapRegisterBase;
+ return Address;
+ }
+
+
+ /*
+ Busmaster with s/g support?
+ NOTE: old docs allowed busmasters to pass a NULL Adapter. In this case, MapRegisterBase
+ being NULL is used to detect a s/g busmaster.
+ */
+ if ((!AdapterObject && !MapRegisterBase) ||
+ (AdapterObject && AdapterObject->MasterDevice && AdapterObject->ScatterGather))
+ {
+ /*
+ Just return the passed VA's corresponding phys. address.
+ Update length to the number of phys. contiguous bytes found.
+ */
+
+ PULONG MdlPages;
+ ULONG MdlPageIndex, PhysContiguousLen;
+ ULONG PhysAddress;
+
+ MdlPages = (PULONG)(Mdl + 1);
+
+ /* Get VA's corresponding mdl phys. page index */
+ MdlPageIndex = ((ULONG)CurrentVa - (ULONG)Mdl->StartVa) / PAGE_SIZE;
+
+ /* Get phys. page containing the VA */
+ PhysAddress = MdlPages[MdlPageIndex];
+
+ PhysContiguousLen = PAGE_SIZE - BYTE_OFFSET(CurrentVa);
+
+ /* VA to map may span several contiguous phys. pages (unlikely) */
+ while (PhysContiguousLen < *Length &&
+ MdlPages[MdlPageIndex++] + PAGE_SIZE == MdlPages[MdlPageIndex])
+ {
+ /*
+ Note that allways adding PAGE_SIZE may make PhysContiguousLen greater
+ than Length if buffer doesn't end on page boundary. Take this
+ into consideration below.
+ */
+ PhysContiguousLen += PAGE_SIZE;
+ }
+
+ if (PhysContiguousLen < *Length)
+ {
+ *Length = PhysContiguousLen;
+ }
+
+ //add offset to phys. page address
+ Address.QuadPart = PhysAddress + BYTE_OFFSET(CurrentVa);
+ return Address;
+ }
+
+
+ /*
+ Busmaster without s/g support?
+ NOTE: old docs allowed busmasters to pass a NULL Adapter. In this case, MapRegisterBase
+ not being NULL is used to detect a non s/g busmaster.
+ */
+ if ((!AdapterObject && MapRegisterBase) ||
+ (AdapterObject && AdapterObject->MasterDevice && !AdapterObject->ScatterGather))
+ {
+ /*
+ NOTE: Busmasters doing common-buffer DMA shouldn't call IoMapTransfer, but I don't
+ know if it's illegal... Maybe figure out what to do in this case...
+ */
+
+ if( WriteToDevice )
+ {
+ memcpy(MapRegisterBase,
+ (char*)MmGetSystemAddressForMdl(Mdl) + ((ULONG)CurrentVa - (ULONG)MmGetMdlVirtualAddress(Mdl)),
+ *Length );
+ }
+
+ return MmGetPhysicalAddress(MapRegisterBase);
+ }
+
+ DPRINT("IoMapTransfer: Unsupported operation\n");
+ KEBUGCHECK(0);
+ return Address;
+}
+
+
+/* EOF */
+
+
+
+
reactos/hal/halx86/generic
diff -N beep.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ beep.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,79 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/beep.c
+ * PURPOSE: Speaker function (it's only one)
+ * PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ * UPDATE HISTORY:
+ * Created 31/01/99
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/* CONSTANTS *****************************************************************/
+
+#define TIMER2 0x42
+#define TIMER3 0x43
+#define PORT_B 0x61
+#define CLOCKFREQ 1193167
+
+
+/* FUNCTIONS *****************************************************************/
+/*
+ * FUNCTION: Beeps the speaker.
+ * ARGUMENTS:
+ * Frequency = If 0, the speaker will be switched off, otherwise
+ * the speaker beeps with the specified frequency.
+ */
+
+BOOLEAN
+STDCALL
+HalMakeBeep (
+ ULONG Frequency
+ )
+{
+ UCHAR b;
+ ULONG flags;
+
+ /* save flags and disable interrupts */
+ Ki386SaveFlags(flags);
+ Ki386DisableInterrupts();
+
+ /* speaker off */
+ b = READ_PORT_UCHAR((PUCHAR)PORT_B);
+ WRITE_PORT_UCHAR((PUCHAR)PORT_B, (UCHAR)(b & 0xFC));
+
+ if (Frequency)
+ {
+ DWORD Divider = CLOCKFREQ / Frequency;
+
+ if (Divider > 0x10000)
+ {
+ /* restore flags */
+ Ki386RestoreFlags(flags);
+
+ return FALSE;
+ }
+
+ /* set timer divider */
+ WRITE_PORT_UCHAR((PUCHAR)TIMER3, 0xB6);
+ WRITE_PORT_UCHAR((PUCHAR)TIMER2, (UCHAR)(Divider & 0xFF));
+ WRITE_PORT_UCHAR((PUCHAR)TIMER2, (UCHAR)((Divider>>8) & 0xFF));
+
+ /* speaker on */
+ WRITE_PORT_UCHAR((PUCHAR)PORT_B, (UCHAR)(READ_PORT_UCHAR((PUCHAR)PORT_B) | 0x03));
+ }
+
+ /* restore flags */
+ Ki386RestoreFlags(flags);
+
+ return TRUE;
+}
+
reactos/hal/halx86/generic
diff -N bus.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ bus.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,532 @@
+/* $Id: bus.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/bus.c
+ * PURPOSE: Bus functions
+ * PROGRAMMER: David Welch (welch@mcmail.com)
+ * UPDATE HISTORY:
+ * Created 22/05/98
+ *
+ *
+ * TODO:
+ * - Add bus handler functions for all busses
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include <bus.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS *******************************************************************/
+
+#define TAG_BUS TAG('B', 'U', 'S', 'H')
+
+KSPIN_LOCK HalpBusHandlerSpinLock = {0,};
+LIST_ENTRY HalpBusHandlerList;
+
+
+/* FUNCTIONS *****************************************************************/
+
+static NTSTATUS STDCALL
+HalpNoAdjustResourceList(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ PCM_RESOURCE_LIST Resources)
+{
+ return STATUS_UNSUCCESSFUL;
+}
+
+
+static NTSTATUS STDCALL
+HalpNoAssignSlotResources(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ PUNICODE_STRING RegistryPath,
+ PUNICODE_STRING DriverClassName,
+ PDRIVER_OBJECT DriverObject,
+ PDEVICE_OBJECT DeviceObject,
+ ULONG SlotNumber,
+ PCM_RESOURCE_LIST *AllocatedResources)
+{
+ return STATUS_NOT_SUPPORTED;
+}
+
+
+static ULONG STDCALL
+HalpNoBusData(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length)
+{
+ return 0;
+}
+
+
+static ULONG STDCALL
+HalpNoGetInterruptVector(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ ULONG BusInterruptLevel,
+ ULONG BusInterruptVector,
+ PKIRQL Irql,
+ PKAFFINITY Affinity)
+{
+ return 0;
+}
+
+
+static ULONG STDCALL
+HalpNoTranslateBusAddress(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ PHYSICAL_ADDRESS BusAddress,
+ PULONG AddressSpace,
+ PPHYSICAL_ADDRESS TranslatedAddress)
+{
+ return 0;
+}
+
+
+PBUS_HANDLER
+HalpAllocateBusHandler(INTERFACE_TYPE InterfaceType,
+ BUS_DATA_TYPE BusDataType,
+ ULONG BusNumber)
+{
+ PBUS_HANDLER BusHandler = NULL;
+
+ DPRINT("HalpAllocateBusHandler()\n");
+
+ BusHandler = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(BUS_HANDLER),
+ TAG_BUS);
+ if (BusHandler == NULL)
+ return NULL;
+
+ RtlZeroMemory(BusHandler,
+ sizeof(BUS_HANDLER));
+
+ InsertTailList(&HalpBusHandlerList,
+ &BusHandler->Entry);
+
+ BusHandler->InterfaceType = InterfaceType;
+ BusHandler->BusDataType = BusDataType;
+ BusHandler->BusNumber = BusNumber;
+
+ /* initialize default bus handler functions */
+ BusHandler->GetBusData = HalpNoBusData;
+ BusHandler->SetBusData = HalpNoBusData;
+ BusHandler->AdjustResourceList = HalpNoAdjustResourceList;
+ BusHandler->AssignSlotResources = HalpNoAssignSlotResources;
+ BusHandler->GetInterruptVector = HalpNoGetInterruptVector;
+ BusHandler->TranslateBusAddress = HalpNoTranslateBusAddress;
+
+ /* any more ?? */
+
+ DPRINT("HalpAllocateBusHandler() done\n");
+
+ return BusHandler;
+}
+
+
+VOID
+HalpInitBusHandlers(VOID)
+{
+ PBUS_HANDLER BusHandler;
+
+ /* General preparations */
+ KeInitializeSpinLock(&HalpBusHandlerSpinLock);
+ InitializeListHead(&HalpBusHandlerList);
+
+ /* Initialize hal dispatch tables */
+ HalQuerySystemInformation = HalpQuerySystemInformation;
+
+#if 0
+ HalSetSystemInformation = HalpSetSystemInformation;
+
+ HalQueryBusSlots = HalpQueryBusSlots;
+#endif
+
+ /* Add system bus handler */
+ BusHandler = HalpAllocateBusHandler(Internal,
+ ConfigurationSpaceUndefined,
+ 0);
+ if (BusHandler == NULL)
+ return;
+ BusHandler->GetInterruptVector =
+ (pGetInterruptVector)HalpGetSystemInterruptVector;
+ BusHandler->TranslateBusAddress =
+ (pTranslateBusAddress)HalpTranslateSystemBusAddress;
+
+ /* Add cmos bus handler */
+ BusHandler = HalpAllocateBusHandler(InterfaceTypeUndefined,
+ Cmos,
+ 0);
+ if (BusHandler == NULL)
+ return;
+ BusHandler->GetBusData = (pGetSetBusData)HalpGetCmosData;
+ BusHandler->SetBusData = (pGetSetBusData)HalpSetCmosData;
+
+ /* Add isa bus handler */
+ BusHandler = HalpAllocateBusHandler(Isa,
+ ConfigurationSpaceUndefined,
+ 0);
+ if (BusHandler == NULL)
+ return;
+
+ BusHandler->GetInterruptVector =
+ (pGetInterruptVector)HalpGetIsaInterruptVector;
+ BusHandler->TranslateBusAddress =
+ (pTranslateBusAddress)HalpTranslateIsaBusAddress;
+
+ /* Add MicroChannel bus handler */
+ BusHandler = HalpAllocateBusHandler(MicroChannel,
+ Pos,
+ 0);
+ if (BusHandler == NULL)
+ return;
+
+ BusHandler->GetBusData = (pGetSetBusData)HalpGetMicroChannelData;
+}
+
+
+PBUS_HANDLER FASTCALL
+HaliHandlerForBus(INTERFACE_TYPE InterfaceType,
+ ULONG BusNumber)
+{
+ PBUS_HANDLER BusHandler;
+ PLIST_ENTRY CurrentEntry;
+ KIRQL OldIrql;
+
+ KeAcquireSpinLock(&HalpBusHandlerSpinLock,
+ &OldIrql);
+
+ CurrentEntry = HalpBusHandlerList.Flink;
+ while (CurrentEntry != &HalpBusHandlerList)
+ {
+ BusHandler = (PBUS_HANDLER)CurrentEntry;
+ if (BusHandler->InterfaceType == InterfaceType &&
+ BusHandler->BusNumber == BusNumber)
+ {
+ KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+ OldIrql);
+ return BusHandler;
+ }
+ CurrentEntry = CurrentEntry->Flink;
+ }
+ KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+ OldIrql);
+
+ return NULL;
+}
+
+
+PBUS_HANDLER FASTCALL
+HaliHandlerForConfigSpace(BUS_DATA_TYPE BusDataType,
+ ULONG BusNumber)
+{
+ PBUS_HANDLER BusHandler;
+ PLIST_ENTRY CurrentEntry;
+ KIRQL OldIrql;
+
+ KeAcquireSpinLock(&HalpBusHandlerSpinLock,
+ &OldIrql);
+
+ CurrentEntry = HalpBusHandlerList.Flink;
+ while (CurrentEntry != &HalpBusHandlerList)
+ {
+ BusHandler = (PBUS_HANDLER)CurrentEntry;
+ if (BusHandler->BusDataType == BusDataType &&
+ BusHandler->BusNumber == BusNumber)
+ {
+ KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+ OldIrql);
+ return BusHandler;
+ }
+ CurrentEntry = CurrentEntry->Flink;
+ }
+ KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+ OldIrql);
+
+ return NULL;
+}
+
+
+PBUS_HANDLER FASTCALL
+HaliReferenceHandlerForBus(INTERFACE_TYPE InterfaceType,
+ ULONG BusNumber)
+{
+ PBUS_HANDLER BusHandler;
+ PLIST_ENTRY CurrentEntry;
+ KIRQL OldIrql;
+
+ KeAcquireSpinLock(&HalpBusHandlerSpinLock,
+ &OldIrql);
+
+ CurrentEntry = HalpBusHandlerList.Flink;
+ while (CurrentEntry != &HalpBusHandlerList)
+ {
+ BusHandler = (PBUS_HANDLER)CurrentEntry;
+ if (BusHandler->InterfaceType == InterfaceType &&
+ BusHandler->BusNumber == BusNumber)
+ {
+ BusHandler->RefCount++;
+ KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+ OldIrql);
+ return BusHandler;
+ }
+ CurrentEntry = CurrentEntry->Flink;
+ }
+ KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+ OldIrql);
+
+ return NULL;
+}
+
+
+PBUS_HANDLER FASTCALL
+HaliReferenceHandlerForConfigSpace(BUS_DATA_TYPE BusDataType,
+ ULONG BusNumber)
+{
+ PBUS_HANDLER BusHandler;
+ PLIST_ENTRY CurrentEntry;
+ KIRQL OldIrql;
+
+ KeAcquireSpinLock(&HalpBusHandlerSpinLock,
+ &OldIrql);
+
+ CurrentEntry = HalpBusHandlerList.Flink;
+ while (CurrentEntry != &HalpBusHandlerList)
+ {
+ BusHandler = (PBUS_HANDLER)CurrentEntry;
+ if (BusHandler->BusDataType == BusDataType &&
+ BusHandler->BusNumber == BusNumber)
+ {
+ BusHandler->RefCount++;
+ KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+ OldIrql);
+ return BusHandler;
+ }
+ CurrentEntry = CurrentEntry->Flink;
+ }
+ KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+ OldIrql);
+
+ return NULL;
+}
+
+
+VOID FASTCALL
+HaliDereferenceBusHandler(PBUS_HANDLER BusHandler)
+{
+ KIRQL OldIrql;
+
+ KeAcquireSpinLock(&HalpBusHandlerSpinLock,
+ &OldIrql);
+ BusHandler->RefCount--;
+ KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+ OldIrql);
+}
+
+
+NTSTATUS STDCALL
+HalAdjustResourceList(PCM_RESOURCE_LIST Resources)
+{
+ PBUS_HANDLER BusHandler;
+ NTSTATUS Status;
+
+ BusHandler = HaliReferenceHandlerForBus(Resources->List[0].InterfaceType,
+ Resources->List[0].BusNumber);
+ if (BusHandler == NULL)
+ return STATUS_SUCCESS;
+
+ Status = BusHandler->AdjustResourceList(BusHandler,
+ Resources->List[0].BusNumber,
+ Resources);
+ HaliDereferenceBusHandler (BusHandler);
+
+ return Status;
+}
+
+
+NTSTATUS STDCALL
+HalAssignSlotResources(PUNICODE_STRING RegistryPath,
+ PUNICODE_STRING DriverClassName,
+ PDRIVER_OBJECT DriverObject,
+ PDEVICE_OBJECT DeviceObject,
+ INTERFACE_TYPE BusType,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PCM_RESOURCE_LIST *AllocatedResources)
+{
+ PBUS_HANDLER BusHandler;
+ NTSTATUS Status;
+
+ BusHandler = HaliReferenceHandlerForBus(BusType,
+ BusNumber);
+ if (BusHandler == NULL)
+ return STATUS_NOT_FOUND;
+
+ Status = BusHandler->AssignSlotResources(BusHandler,
+ BusNumber,
+ RegistryPath,
+ DriverClassName,
+ DriverObject,
+ DeviceObject,
+ SlotNumber,
+ AllocatedResources);
+
+ HaliDereferenceBusHandler(BusHandler);
+
+ return Status;
+}
+
+
+ULONG STDCALL
+HalGetBusData(BUS_DATA_TYPE BusDataType,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Length)
+{
+ return (HalGetBusDataByOffset(BusDataType,
+ BusNumber,
+ SlotNumber,
+ Buffer,
+ 0,
+ Length));
+}
+
+
+ULONG STDCALL
+HalGetBusDataByOffset(BUS_DATA_TYPE BusDataType,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length)
+{
+ PBUS_HANDLER BusHandler;
+ ULONG Result;
+
+ BusHandler = HaliReferenceHandlerForConfigSpace(BusDataType,
+ BusNumber);
+ if (BusHandler == NULL)
+ return 0;
+
+ Result = BusHandler->GetBusData(BusHandler,
+ BusNumber,
+ SlotNumber,
+ Buffer,
+ Offset,
+ Length);
+
+ HaliDereferenceBusHandler (BusHandler);
+
+ return Result;
+}
+
+
+ULONG STDCALL
+HalGetInterruptVector(INTERFACE_TYPE InterfaceType,
+ ULONG BusNumber,
+ ULONG BusInterruptLevel,
+ ULONG BusInterruptVector,
+ PKIRQL Irql,
+ PKAFFINITY Affinity)
+{
+ PBUS_HANDLER BusHandler;
+ ULONG Result;
+
+ BusHandler = HaliReferenceHandlerForBus(InterfaceType,
+ BusNumber);
+ if (BusHandler == NULL)
+ return 0;
+
+ Result = BusHandler->GetInterruptVector(BusHandler,
+ BusNumber,
+ BusInterruptLevel,
+ BusInterruptVector,
+ Irql,
+ Affinity);
+
+ HaliDereferenceBusHandler(BusHandler);
+
+ return Result;
+}
+
+
+ULONG STDCALL
+HalSetBusData(BUS_DATA_TYPE BusDataType,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Length)
+{
+ return (HalSetBusDataByOffset(BusDataType,
+ BusNumber,
+ SlotNumber,
+ Buffer,
+ 0,
+ Length));
+}
+
+
+ULONG STDCALL
+HalSetBusDataByOffset(BUS_DATA_TYPE BusDataType,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length)
+{
+ PBUS_HANDLER BusHandler;
+ ULONG Result;
+
+ BusHandler = HaliReferenceHandlerForConfigSpace(BusDataType,
+ BusNumber);
+ if (BusHandler == NULL)
+ return 0;
+
+ Result = BusHandler->SetBusData(BusHandler,
+ BusNumber,
+ SlotNumber,
+ Buffer,
+ Offset,
+ Length);
+
+ HaliDereferenceBusHandler(BusHandler);
+
+ return Result;
+}
+
+
+BOOLEAN STDCALL
+HalTranslateBusAddress(INTERFACE_TYPE InterfaceType,
+ ULONG BusNumber,
+ PHYSICAL_ADDRESS BusAddress,
+ PULONG AddressSpace,
+ PPHYSICAL_ADDRESS TranslatedAddress)
+{
+ PBUS_HANDLER BusHandler;
+ BOOLEAN Result;
+
+ BusHandler = HaliReferenceHandlerForBus(InterfaceType,
+ BusNumber);
+ if (BusHandler == NULL)
+ return FALSE;
+
+ Result = (BOOLEAN)BusHandler->TranslateBusAddress(BusHandler,
+ BusNumber,
+ BusAddress,
+ AddressSpace,
+ TranslatedAddress);
+
+ HaliDereferenceBusHandler(BusHandler);
+
+ return Result;
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N display.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ display.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,790 @@
+/*
+ * ReactOS kernel
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 ReactOS Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id: display.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/display.c
+ * PURPOSE: Blue screen display
+ * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ * UPDATE HISTORY:
+ * Created 08/10/99
+ */
+
+/*
+ * Portions of this code are from the XFree86 Project and available from the
+ * following license:
+ *
+ * Copyright (C) 1994-2003 The XFree86 Project, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
+ * NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the XFree86 Project shall
+ * not be used in advertising or otherwise to promote the sale, use or other
+ * dealings in this Software without prior written authorization from the
+ * XFree86 Project.
+*/
+
+/* DISPLAY OWNERSHIP
+ *
+ * So, who owns the physical display and is allowed to write to it?
+ *
+ * In MS NT, upon boot HAL owns the display. Somewhere in the boot
+ * sequence (haven't figured out exactly where or by who), some
+ * component calls HalAcquireDisplayOwnership. From that moment on,
+ * the display is owned by that component and is switched to graphics
+ * mode. The display is not supposed to return to text mode, except
+ * in case of a bug check. The bug check will call HalDisplayString
+ * to output a string to the text screen. HAL will notice that it
+ * currently doesn't own the display and will re-take ownership, by
+ * calling the callback function passed to HalAcquireDisplayOwnership.
+ * After the bugcheck, execution is halted. So, under NT, the only
+ * possible sequence of display modes is text mode -> graphics mode ->
+ * text mode (the latter hopefully happening very infrequently).
+ *
+ * Things are a little bit different in the current state of ReactOS.
+ * We want to have a functional interactive text mode. We should be
+ * able to switch from text mode to graphics mode when a GUI app is
+ * started and switch back to text mode when it's finished. Then, when
+ * another GUI app is started, another switch to and from graphics mode
+ * is possible. Also, when the system bugchecks in graphics mode we want
+ * to switch back to text mode to show the registers and stack trace.
+ * Last but not least, HalDisplayString is used a lot more in ReactOS,
+ * e.g. to print debug messages when the /DEBUGPORT=SCREEN boot option
+ * is present.
+ * 3 Components are involved in Reactos: HAL, BLUE.SYS and VIDEOPRT.SYS.
+ * As in NT, on boot HAL owns the display. When entering the text mode
+ * command interpreter, BLUE.SYS kicks in. It will write directly to the
+ * screen, more or less behind HALs back.
+ * When a GUI app is started, WIN32K.SYS will open the DISPLAY device.
+ * This open call will end up in VIDEOPRT.SYS. That component will then
+ * take ownership of the display by calling HalAcquireDisplayOwnership.
+ * When the GUI app terminates (WIN32K.SYS will close the DISPLAY device),
+ * we want to give ownership of the display back to HAL. Using the
+ * standard exported HAL functions, that's a bit of a problem, because
+ * there is no function defined to do that. In NT, this is handled by
+ * HalDisplayString, but that solution isn't satisfactory in ReactOS,
+ * because HalDisplayString is (in some cases) also used to output debug
+ * messages. If we do it the NT way, the first debug message output while
+ * in graphics mode would switch the display back to text mode.
+ * So, instead, if HalDisplayString detects that HAL doesn't have ownership
+ * of the display, it doesn't do anything.
+ * To return ownership to HAL, a new function is exported,
+ * HalReleaseDisplayOwnership. This function is called by the DISPLAY
+ * device Close routine in VIDEOPRT.SYS. It is also called at the beginning
+ * of a bug check, so HalDisplayString is activated again.
+ * Now, while the display is in graphics mode (not owned by HAL), BLUE.SYS
+ * should also refrain from writing to the screen buffer. The text mode
+ * screen buffer might overlap the graphics mode screen buffer, so changing
+ * something in the text mode buffer might mess up the graphics screen. To
+ * allow BLUE.SYS to detect if HAL owns the display, another new function is
+ * exported, HalQueryDisplayOwnership. BLUE.SYS will call this function to
+ * check if it's allowed to touch the text mode buffer.
+ *
+ * In an ideal world, when HAL takes ownership of the display, it should set
+ * up the CRT using real-mode (actually V86 mode, but who cares) INT 0x10
+ * calls. Unfortunately, this will require HAL to setup a real-mode interrupt
+ * table etc. So, we chickened out of that by having the loader set up the
+ * display before switching to protected mode. If HAL is given back ownership
+ * after a GUI app terminates, the INT 0x10 calls are made by VIDEOPRT.SYS,
+ * since there is already support for them via the VideoPortInt10 routine.
+ */
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define SCREEN_SYNCHRONIZATION
+
+#define VGA_AC_INDEX 0x3c0
+#define VGA_AC_READ 0x3c1
+#define VGA_AC_WRITE 0x3c0
+
+#define VGA_MISC_WRITE 0x3c2
+
+#define VGA_SEQ_INDEX 0x3c4
+#define VGA_SEQ_DATA 0x3c5
+
+#define VGA_DAC_MASK 0x3c6
+#define VGA_DAC_READ_INDEX 0x3c7
+#define VGA_DAC_WRITE_INDEX 0x3c8
+#define VGA_DAC_DATA 0x3c9
+#define VGA_FEATURE_READ 0x3ca
+#define VGA_MISC_READ 0x3cc
+
+#define VGA_GC_INDEX 0x3ce
+#define VGA_GC_DATA 0x3cf
+
+#define VGA_CRTC_INDEX 0x3d4
+#define VGA_CRTC_DATA 0x3d5
+
+#define VGA_INSTAT_READ 0x3da
+
+#define VGA_SEQ_NUM_REGISTERS 5
+#define VGA_CRTC_NUM_REGISTERS 25
+#define VGA_GC_NUM_REGISTERS 9
+#define VGA_AC_NUM_REGISTERS 21
+
+#define CRTC_COLUMNS 0x01
+#define CRTC_OVERFLOW 0x07
+#define CRTC_ROWS 0x12
+#define CRTC_SCANLINES 0x09
+
+#define CRTC_CURHI 0x0e
+#define CRTC_CURLO 0x0f
+
+
+#define CHAR_ATTRIBUTE_BLACK 0x00 /* black on black */
+#define CHAR_ATTRIBUTE 0x17 /* grey on blue */
+
+#define FONT_AMOUNT (8*8192)
+
+/* VARIABLES ****************************************************************/
+
+static ULONG CursorX = 0; /* Cursor Position */
+static ULONG CursorY = 0;
+static ULONG SizeX = 80; /* Display size */
+static ULONG SizeY = 25;
+
+static BOOLEAN DisplayInitialized = FALSE;
+static BOOLEAN HalOwnsDisplay = TRUE;
+
+static PUSHORT VideoBuffer = NULL;
+static PUCHAR GraphVideoBuffer = NULL;
+
+static PHAL_RESET_DISPLAY_PARAMETERS HalResetDisplayParameters = NULL;
+
+static UCHAR SavedTextPalette[768];
+static UCHAR SavedTextMiscOutReg;
+static UCHAR SavedTextCrtcReg[VGA_CRTC_NUM_REGISTERS];
+static UCHAR SavedTextAcReg[VGA_AC_NUM_REGISTERS];
+static UCHAR SavedTextGcReg[VGA_GC_NUM_REGISTERS];
+static UCHAR SavedTextSeqReg[VGA_SEQ_NUM_REGISTERS];
+static UCHAR SavedTextFont[2][FONT_AMOUNT];
+static BOOLEAN TextPaletteEnabled = FALSE;
+
+/* PRIVATE FUNCTIONS *********************************************************/
+
+VOID FASTCALL
+HalClearDisplay (UCHAR CharAttribute)
+{
+ WORD *ptr = (WORD*)VideoBuffer;
+ ULONG i;
+
+ for (i = 0; i < SizeX * SizeY; i++, ptr++)
+ *ptr = ((CharAttribute << 8) + ' ');
+
+ CursorX = 0;
+ CursorY = 0;
+}
+
+
+/* STATIC FUNCTIONS *********************************************************/
+
+VOID STATIC
+HalScrollDisplay (VOID)
+{
+ PUSHORT ptr;
+ int i;
+
+ ptr = VideoBuffer + SizeX;
+ RtlMoveMemory(VideoBuffer,
+ ptr,
+ SizeX * (SizeY - 1) * 2);
+
+ ptr = VideoBuffer + (SizeX * (SizeY - 1));
+ for (i = 0; i < (int)SizeX; i++, ptr++)
+ {
+ *ptr = (CHAR_ATTRIBUTE << 8) + ' ';
+ }
+}
+
+VOID STATIC FASTCALL
+HalPutCharacter (CHAR Character)
+{
+ PUSHORT ptr;
+
+ ptr = VideoBuffer + ((CursorY * SizeX) + CursorX);
+ *ptr = (CHAR_ATTRIBUTE << 8) + Character;
+}
+
+VOID STATIC
+HalDisablePalette(VOID)
+{
+ (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, 0x20);
+ TextPaletteEnabled = FALSE;
+}
+
+VOID STATIC
+HalEnablePalette(VOID)
+{
+ (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, 0x00);
+ TextPaletteEnabled = TRUE;
+}
+
+UCHAR STATIC FASTCALL
+HalReadGc(ULONG Index)
+{
+ WRITE_PORT_UCHAR((PUCHAR)VGA_GC_INDEX, (UCHAR)Index);
+ return(READ_PORT_UCHAR((PUCHAR)VGA_GC_DATA));
+}
+
+VOID STATIC FASTCALL
+HalWriteGc(ULONG Index, UCHAR Value)
+{
+ WRITE_PORT_UCHAR((PUCHAR)VGA_GC_INDEX, (UCHAR)Index);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_GC_DATA, Value);
+}
+
+UCHAR STATIC FASTCALL
+HalReadSeq(ULONG Index)
+{
+ WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_INDEX, (UCHAR)Index);
+ return(READ_PORT_UCHAR((PUCHAR)VGA_SEQ_DATA));
+}
+
+VOID STATIC FASTCALL
+HalWriteSeq(ULONG Index, UCHAR Value)
+{
+ WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_INDEX, (UCHAR)Index);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_DATA, Value);
+}
+
+VOID STATIC FASTCALL
+HalWriteAc(ULONG Index, UCHAR Value)
+{
+ if (TextPaletteEnabled)
+ {
+ Index &= ~0x20;
+ }
+ else
+ {
+ Index |= 0x20;
+ }
+ (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, (UCHAR)Index);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_AC_WRITE, Value);
+}
+
+UCHAR STATIC FASTCALL
+HalReadAc(ULONG Index)
+{
+ if (TextPaletteEnabled)
+ {
+ Index &= ~0x20;
+ }
+ else
+ {
+ Index |= 0x20;
+ }
+ (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, (UCHAR)Index);
+ return(READ_PORT_UCHAR((PUCHAR)VGA_AC_READ));
+}
+
+VOID STATIC FASTCALL
+HalWriteCrtc(ULONG Index, UCHAR Value)
+{
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, (UCHAR)Index);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, Value);
+}
+
+UCHAR STATIC FASTCALL
+HalReadCrtc(ULONG Index)
+{
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, (UCHAR)Index);
+ return(READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA));
+}
+
+VOID STATIC FASTCALL
+HalResetSeq(BOOLEAN Start)
+{
+ if (Start)
+ {
+ HalWriteSeq(0x00, 0x01);
+ }
+ else
+ {
+ HalWriteSeq(0x00, 0x03);
+ }
+}
+
+VOID STATIC FASTCALL
+HalBlankScreen(BOOLEAN On)
+{
+ UCHAR Scrn;
+
+ Scrn = HalReadSeq(0x01);
+
+ if (On)
+ {
+ Scrn &= ~0x20;
+ }
+ else
+ {
+ Scrn |= 0x20;
+ }
+
+ HalResetSeq(TRUE);
+ HalWriteSeq(0x01, Scrn);
+ HalResetSeq(FALSE);
+}
+
+VOID STATIC
+HalSaveFont(VOID)
+{
+ UCHAR Attr10;
+ UCHAR MiscOut, Gc4, Gc5, Gc6, Seq2, Seq4;
+ ULONG i;
+
+ /* Check if we are already in graphics mode. */
+ Attr10 = HalReadAc(0x10);
+ if (Attr10 & 0x01)
+ {
+ return;
+ }
+
+ /* Save registers. */
+ MiscOut = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ);
+ Gc4 = HalReadGc(0x04);
+ Gc5 = HalReadGc(0x05);
+ Gc6 = HalReadGc(0x06);
+ Seq2 = HalReadSeq(0x02);
+ Seq4 = HalReadSeq(0x04);
+
+ /* Force colour mode. */
+ WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, (UCHAR)(MiscOut | 0x01));
+
+ HalBlankScreen(FALSE);
+
+ for (i = 0; i < 2; i++)
+ {
+ /* Save font 1 */
+ HalWriteSeq(0x02, (UCHAR)(0x04 << i)); /* Write to plane 2 or 3 */
+ HalWriteSeq(0x04, 0x06); /* Enable plane graphics. */
+ HalWriteGc(0x04, (UCHAR)(0x02 + i)); /* Read plane 2 or 3 */
+ HalWriteGc(0x05, 0x00); /* Write mode 0; read mode 0 */
+ HalWriteGc(0x06, 0x05); /* Set graphics. */
+ memcpy(SavedTextFont[i], GraphVideoBuffer, FONT_AMOUNT);
+ }
+
+ /* Restore registers. */
+ HalWriteAc(0x10, Attr10);
+ HalWriteSeq(0x02, Seq2);
+ HalWriteSeq(0x04, Seq4);
+ HalWriteGc(0x04, Gc4);
+ HalWriteGc(0x05, Gc5);
+ HalWriteGc(0x06, Gc6);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, MiscOut);
+
+ HalBlankScreen(TRUE);
+}
+
+VOID STATIC
+HalSaveMode(VOID)
+{
+ ULONG i;
+
+ SavedTextMiscOutReg = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ);
+
+ for (i = 0; i < VGA_CRTC_NUM_REGISTERS; i++)
+ {
+ SavedTextCrtcReg[i] = HalReadCrtc(i);
+ }
+
+ HalEnablePalette();
+ for (i = 0; i < VGA_AC_NUM_REGISTERS; i++)
+ {
+ SavedTextAcReg[i] = HalReadAc(i);
+ }
+ HalDisablePalette();
+
+ for (i = 0; i < VGA_GC_NUM_REGISTERS; i++)
+ {
+ SavedTextGcReg[i] = HalReadGc(i);
+ }
+
+ for (i = 0; i < VGA_SEQ_NUM_REGISTERS; i++)
+ {
+ SavedTextSeqReg[i] = HalReadSeq(i);
+ }
+}
+
+VOID STATIC
+HalDacDelay(VOID)
+{
+ (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+ (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+}
+
+VOID STATIC
+HalSavePalette(VOID)
+{
+ ULONG i;
+ WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_MASK, 0xFF);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_READ_INDEX, 0x00);
+ for (i = 0; i < 768; i++)
+ {
+ SavedTextPalette[i] = READ_PORT_UCHAR((PUCHAR)VGA_DAC_DATA);
+ HalDacDelay();
+ }
+}
+
+VOID STATIC
+HalRestoreFont(VOID)
+{
+ UCHAR MiscOut, Attr10, Gc1, Gc3, Gc4, Gc5, Gc6, Gc8;
+ UCHAR Seq2, Seq4;
+ ULONG i;
+
+ /* Save registers. */
+ MiscOut = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ);
+ Attr10 = HalReadAc(0x10);
+ Gc1 = HalReadGc(0x01);
+ Gc3 = HalReadGc(0x03);
+ Gc4 = HalReadGc(0x04);
+ Gc5 = HalReadGc(0x05);
+ Gc6 = HalReadGc(0x06);
+ Gc8 = HalReadGc(0x08);
+ Seq2 = HalReadSeq(0x02);
+ Seq4 = HalReadSeq(0x04);
+
+ /* Force into colour mode. */
+ WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, (UCHAR)(MiscOut | 0x10));
+
+ HalBlankScreen(FALSE);
+
+ HalWriteGc(0x03, 0x00); /* Don't rotate; write unmodified. */
+ HalWriteGc(0x08, 0xFF); /* Write all bits. */
+ HalWriteGc(0x01, 0x00); /* All planes from CPU. */
+
+ for (i = 0; i < 2; i++)
+ {
+ HalWriteSeq(0x02, (UCHAR)(0x04 << i)); /* Write to plane 2 or 3 */
+ HalWriteSeq(0x04, 0x06); /* Enable plane graphics. */
+ HalWriteGc(0x04, (UCHAR)(0x02 + i)); /* Read plane 2 or 3 */
+ HalWriteGc(0x05, 0x00); /* Write mode 0; read mode 0. */
+ HalWriteGc(0x06, 0x05); /* Set graphics. */
+ memcpy(GraphVideoBuffer, SavedTextFont[i], FONT_AMOUNT);
+ }
+
+ HalBlankScreen(TRUE);
+
+ /* Restore registers. */
+ WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, MiscOut);
+ HalWriteAc(0x10, Attr10);
+ HalWriteGc(0x01, Gc1);
+ HalWriteGc(0x03, Gc3);
+ HalWriteGc(0x04, Gc4);
+ HalWriteGc(0x05, Gc5);
+ HalWriteGc(0x06, Gc6);
+ HalWriteGc(0x08, Gc8);
+ HalWriteSeq(0x02, Seq2);
+ HalWriteSeq(0x04, Seq4);
+}
+
+VOID STATIC
+HalRestoreMode(VOID)
+{
+ ULONG i;
+
+ WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, SavedTextMiscOutReg);
+
+ for (i = 1; i < VGA_SEQ_NUM_REGISTERS; i++)
+ {
+ HalWriteSeq(i, SavedTextSeqReg[i]);
+ }
+
+ /* Unlock CRTC registers 0-7 */
+ HalWriteCrtc(17, (UCHAR)(SavedTextCrtcReg[17] & ~0x80));
+
+ for (i = 0; i < VGA_CRTC_NUM_REGISTERS; i++)
+ {
+ HalWriteCrtc(i, SavedTextCrtcReg[i]);
+ }
+
+ for (i = 0; i < VGA_GC_NUM_REGISTERS; i++)
+ {
+ HalWriteGc(i, SavedTextGcReg[i]);
+ }
+
+ HalEnablePalette();
+ for (i = 0; i < VGA_AC_NUM_REGISTERS; i++)
+ {
+ HalWriteAc(i, SavedTextAcReg[i]);
+ }
+ HalDisablePalette();
+}
+
+VOID STATIC
+HalRestorePalette(VOID)
+{
+ ULONG i;
+ WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_MASK, 0xFF);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_WRITE_INDEX, 0x00);
+ for (i = 0; i < 768; i++)
+ {
+ WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_DATA, SavedTextPalette[i]);
+ HalDacDelay();
+ }
+ HalDisablePalette();
+}
+
+/* PRIVATE FUNCTIONS ********************************************************/
+
+VOID FASTCALL
+HalInitializeDisplay (PLOADER_PARAMETER_BLOCK LoaderBlock)
+/*
+ * FUNCTION: Initalize the display
+ * ARGUMENTS:
+ * InitParameters = Parameters setup by the boot loader
+ */
+{
+ if (DisplayInitialized == FALSE)
+ {
+ ULONG ScanLines;
+ ULONG Data;
+
+ VideoBuffer = (PUSHORT)(0xff3b8000);
+ GraphVideoBuffer = (PUCHAR)(0xff3a0000);
+
+ /* Set cursor position */
+// CursorX = LoaderBlock->cursorx;
+// CursorY = LoaderBlock->cursory;
+ CursorX = 0;
+ CursorY = 0;
+
+ /* read screen size from the crtc */
+ /* FIXME: screen size should be read from the boot parameters */
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_COLUMNS);
+ SizeX = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA) + 1;
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_ROWS);
+ SizeY = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_OVERFLOW);
+ Data = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA);
+ SizeY |= (((Data & 0x02) << 7) | ((Data & 0x40) << 3));
+ SizeY++;
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_SCANLINES);
+ ScanLines = (READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA) & 0x1F) + 1;
+ SizeY = SizeY / ScanLines;
+
+#ifdef BOCHS_30ROWS
+ SizeY=30;
+#endif
+ HalClearDisplay(CHAR_ATTRIBUTE_BLACK);
+
+ DisplayInitialized = TRUE;
+
+ /*
+ Save the VGA state at this point so we can restore it on a bugcheck.
+ */
+ HalSavePalette();
+ HalSaveMode();
+ HalSaveFont();
+ }
+}
+
+
+/* PUBLIC FUNCTIONS *********************************************************/
+
+VOID STDCALL
+HalReleaseDisplayOwnership(VOID)
+/*
+ * FUNCTION: Release ownership of display back to HAL
+ */
+{
+ if (HalResetDisplayParameters == NULL)
+ return;
+
+ if (HalOwnsDisplay == TRUE)
+ return;
+
+ if (!HalResetDisplayParameters(SizeX, SizeY))
+ {
+ HalRestoreMode();
+ HalRestoreFont();
+ HalRestorePalette();
+ }
+ HalOwnsDisplay = TRUE;
+ HalClearDisplay(CHAR_ATTRIBUTE);
+}
+
+
+VOID STDCALL
+HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters)
+/*
+ * FUNCTION:
+ * ARGUMENTS:
+ * ResetDisplayParameters = Pointer to a driver specific
+ * reset routine.
+ */
+{
+ HalOwnsDisplay = FALSE;
+ HalResetDisplayParameters = ResetDisplayParameters;
+}
+
+VOID STDCALL
+HalDisplayString(IN PCH String)
+/*
+ * FUNCTION: Switches the screen to HAL console mode (BSOD) if not there
+ * already and displays a string
+ * ARGUMENT:
+ * string = ASCII string to display
+ * NOTE: Use with care because there is no support for returning from BSOD
+ * mode
+ */
+{
+ PCH pch;
+#ifdef SCREEN_SYNCHRONIZATION
+ int offset;
+#endif
+ static KSPIN_LOCK Lock;
+ KIRQL OldIrql;
+ ULONG Flags;
+
+ /* See comment at top of file */
+ if (!HalOwnsDisplay)
+ {
+ return;
+ }
+
+ pch = String;
+
+ OldIrql = KfRaiseIrql(HIGH_LEVEL);
+ KiAcquireSpinLock(&Lock);
+
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+
+
+#if 0
+ if (HalOwnsDisplay == FALSE)
+ {
+ HalReleaseDisplayOwnership();
+ }
+#endif
+
+#ifdef SCREEN_SYNCHRONIZATION
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURHI);
+ offset = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA)<<8;
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURLO);
+ offset += READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA);
+
+ CursorY = offset / SizeX;
+ CursorX = offset % SizeX;
+#endif
+
+ while (*pch != 0)
+ {
+ if (*pch == '\n')
+ {
+ CursorY++;
+ CursorX = 0;
+ }
+ else if (*pch == '\b')
+ {
+ if (CursorX > 0)
+ {
+ CursorX--;
+ }
+ }
+ else if (*pch != '\r')
+ {
+ HalPutCharacter (*pch);
+ CursorX++;
+
+ if (CursorX >= SizeX)
+ {
+ CursorY++;
+ CursorX = 0;
+ }
+ }
+
+ if (CursorY >= SizeY)
+ {
+ HalScrollDisplay ();
+ CursorY = SizeY - 1;
+ }
+
+ pch++;
+ }
+
+#ifdef SCREEN_SYNCHRONIZATION
+ offset = (CursorY * SizeX) + CursorX;
+
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURLO);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, (UCHAR)(offset & 0xff));
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURHI);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, (UCHAR)((offset >> 8) & 0xff));
+#endif
+ Ki386RestoreFlags(Flags);
+
+ KiReleaseSpinLock(&Lock);
+ KfLowerIrql(OldIrql);
+}
+
+VOID STDCALL
+HalQueryDisplayParameters(OUT PULONG DispSizeX,
+ OUT PULONG DispSizeY,
+ OUT PULONG CursorPosX,
+ OUT PULONG CursorPosY)
+{
+ if (DispSizeX)
+ *DispSizeX = SizeX;
+ if (DispSizeY)
+ *DispSizeY = SizeY;
+ if (CursorPosX)
+ *CursorPosX = CursorX;
+ if (CursorPosY)
+ *CursorPosY = CursorY;
+}
+
+
+VOID STDCALL
+HalSetDisplayParameters(IN ULONG CursorPosX,
+ IN ULONG CursorPosY)
+{
+ CursorX = (CursorPosX < SizeX) ? CursorPosX : SizeX - 1;
+ CursorY = (CursorPosY < SizeY) ? CursorPosY : SizeY - 1;
+}
+
+
+BOOLEAN STDCALL
+HalQueryDisplayOwnership(VOID)
+{
+ return !HalOwnsDisplay;
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N dma.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dma.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,445 @@
+/* $Id: dma.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/dma.c
+ * PURPOSE: DMA functions
+ * PROGRAMMERS: David Welch (welch@mcmail.com)
+ * UPDATE HISTORY:
+ * Created 22/05/98
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#define NDEBUG
+#include <internal/debug.h>
+#include <hal.h>
+
+/* Adapters for each channel */
+PADAPTER_OBJECT HalpEisaAdapter[8];
+
+/* FUNCTIONS *****************************************************************/
+
+VOID
+HalpInitDma (VOID)
+{
+ /* TODO: Initialize the first Map Buffer */
+}
+
+PVOID STDCALL
+HalAllocateCommonBuffer (PADAPTER_OBJECT AdapterObject,
+ ULONG Length,
+ PPHYSICAL_ADDRESS LogicalAddress,
+ BOOLEAN CacheEnabled)
+/*
+ * FUNCTION: Allocates memory that is visible to both the processor(s) and
+ * a dma device
+ * ARGUMENTS:
+ * AdapterObject = Adapter object representing the bus master or
+ * system dma controller
+ * Length = Number of bytes to allocate
+ * LogicalAddress = Logical address the driver can use to access the
+ * buffer
+ * CacheEnabled = Specifies if the memory can be cached
+ * RETURNS: The base virtual address of the memory allocated
+ * NULL on failure
+ * NOTES:
+ * CacheEnabled is ignored - it's all cache-disabled (like in NT)
+ * UPDATE: It's not ignored now. If that's wrong just modify the
+ * CacheEnabled comparsion below.
+ */
+{
+ PHYSICAL_ADDRESS LowestAddress, HighestAddress, BoundryAddressMultiple;
+ PVOID BaseAddress;
+
+ LowestAddress.QuadPart = 0;
+ BoundryAddressMultiple.QuadPart = 0;
+ HighestAddress.u.HighPart = 0;
+ if ((AdapterObject->Dma32BitAddresses) && (AdapterObject->MasterDevice)) {
+ HighestAddress.u.LowPart = 0xFFFFFFFF; /* 32Bit: 4GB address range */
+ } else {
+ HighestAddress.u.LowPart = 0x00FFFFFF; /* 24Bit: 16MB address range */
+ }
+
+ BaseAddress = MmAllocateContiguousAlignedMemory(
+ Length,
+ LowestAddress,
+ HighestAddress,
+ BoundryAddressMultiple,
+ CacheEnabled ? MmCached : MmNonCached,
+ 0x10000 );
+ if (!BaseAddress)
+ return 0;
+
+ *LogicalAddress = MmGetPhysicalAddress(BaseAddress);
+
+ return BaseAddress;
+}
+
+BOOLEAN STDCALL
+HalFlushCommonBuffer (ULONG Unknown1,
+ ULONG Unknown2,
+ ULONG Unknown3,
+ ULONG Unknown4,
+ ULONG Unknown5,
+ ULONG Unknown6,
+ ULONG Unknown7,
+ ULONG Unknown8)
+{
+ return TRUE;
+}
+
+VOID STDCALL
+HalFreeCommonBuffer (PADAPTER_OBJECT AdapterObject,
+ ULONG Length,
+ PHYSICAL_ADDRESS LogicalAddress,
+ PVOID VirtualAddress,
+ BOOLEAN CacheEnabled)
+{
+ MmFreeContiguousMemory(VirtualAddress);
+}
+
+PADAPTER_OBJECT STDCALL
+HalGetAdapter (PDEVICE_DESCRIPTION DeviceDescription,
+ PULONG NumberOfMapRegisters)
+/*
+ * FUNCTION: Returns a pointer to an adapter object for the DMA device
+ * defined in the device description structure
+ * ARGUMENTS:
+ * DeviceDescription = Structure describing the attributes of the device
+ * NumberOfMapRegisters (OUT) = Returns the maximum number of map
+ * registers the device driver can
+ * allocate for DMA transfer operations
+ * RETURNS: The allocated adapter object on success
+ * NULL on failure
+ * TODO:
+ * Testing
+ */
+{
+ PADAPTER_OBJECT AdapterObject;
+ DWORD ChannelSelect;
+ DWORD Controller;
+ ULONG MaximumLength;
+ BOOLEAN ChannelSetup;
+
+ DPRINT("Entered Function\n");
+
+ /* Validate parameters in device description, and return a pointer to
+ the adapter object for the requested dma channel */
+ if(DeviceDescription->Version != DEVICE_DESCRIPTION_VERSION) {
+ DPRINT("Invalid Adapter version!\n");
+ return NULL;
+ }
+
+ DPRINT("Checking Interface Type: %x \n", DeviceDescription->InterfaceType);
+ if (DeviceDescription->InterfaceType == PCIBus) {
+ if (DeviceDescription->Master == FALSE) {
+ DPRINT("Invalid request!\n");
+ return NULL;
+ }
+ ChannelSetup = FALSE;
+ }
+
+ /* There are only 8 DMA channels on ISA, so any request above this
+ should not get any channel setup */
+ if (DeviceDescription->DmaChannel >= 8) {
+ ChannelSetup = FALSE;
+ }
+
+ /* Channel 4 is Reserved for Chaining, so you cant use it */
+ if (DeviceDescription->DmaChannel == 4 && ChannelSetup) {
+ DPRINT("Invalid request!\n");
+ return NULL;
+ }
+
+ /* Devices that support Scatter/Gather do not need Map Registers */
+ if (DeviceDescription->ScatterGather &&
+ (DeviceDescription->InterfaceType == Eisa ||
+ DeviceDescription->InterfaceType == PCIBus)) {
+ *NumberOfMapRegisters = 0;
+ }
+
+ /* Check if Extended DMA is available (we're just going to do a random read/write
+ I picked Channel 2 because it's the first Channel in the Register */
+ WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaController1Pages.Channel2), 0x2A);
+ if (READ_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaController1Pages.Channel2)) == 0x2A) {
+ HalpEisaDma = TRUE;
+ }
+
+ /* Find out how many Map Registers we need */
+ DPRINT("Setting up Adapter Settings!\n");
+ MaximumLength = DeviceDescription->MaximumLength & 0x7FFFFFFF;
+ *NumberOfMapRegisters = BYTES_TO_PAGES(MaximumLength) + 1;
+
+ /* Set the Channel Selection */
+ ChannelSelect = DeviceDescription->DmaChannel & 0x03;
+
+ /* Get the Controller Setup */
+ Controller = (DeviceDescription->DmaChannel & 0x04) ? 1 : 2;
+
+ /* Get the Adapter Object */
+ if (HalpEisaAdapter[DeviceDescription->DmaChannel] != NULL) {
+
+ /* Already allocated, return it */
+ DPRINT("Getting an Adapter Object from the Cache\n");
+ AdapterObject = HalpEisaAdapter[DeviceDescription->DmaChannel];
+
+ /* Do we need more Map Registers this time? */
+ if ((AdapterObject->NeedsMapRegisters) &&
+ (*NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel)) {
+ AdapterObject->MapRegistersPerChannel = *NumberOfMapRegisters;
+ }
+
+ } else {
+
+ /* We have to allocate a new object! How exciting! */
+ DPRINT("Allocating a new Adapter Object\n");
+ AdapterObject = HalpAllocateAdapterEx(*NumberOfMapRegisters,
+ FALSE,
+ DeviceDescription->Dma32BitAddresses);
+
+ if (AdapterObject == NULL) return NULL;
+
+ HalpEisaAdapter[DeviceDescription->DmaChannel] = AdapterObject;
+
+ if (!*NumberOfMapRegisters) {
+ /* Easy case, no Map Registers needed */
+ AdapterObject->NeedsMapRegisters = FALSE;
+
+ /* If you're the master, you get all you want */
+ if (DeviceDescription->Master) {
+ AdapterObject->MapRegistersPerChannel= *NumberOfMapRegisters;
+ } else {
+ AdapterObject->MapRegistersPerChannel = 1;
+ }
+ } else {
+ /* We Desire Registers */
+ AdapterObject->NeedsMapRegisters = TRUE;
+
+ /* The registers you want */
+ AdapterObject->MapRegistersPerChannel = *NumberOfMapRegisters;
+
+ /* Increase commitment */
+ MasterAdapter->CommittedMapRegisters += *NumberOfMapRegisters;
+ }
+ }
+
+ /* Set up DMA Structure */
+ if (Controller == 1) {
+ AdapterObject->AdapterBaseVa = (PVOID)FIELD_OFFSET(EISA_CONTROL, DmaController1);
+ } else {
+ AdapterObject->AdapterBaseVa = (PVOID)FIELD_OFFSET(EISA_CONTROL, DmaController2);
+ }
+
+ /* Set up Some Adapter Data */
+ DPRINT("Setting up an Adapter Object\n");
+ AdapterObject->IgnoreCount = DeviceDescription->IgnoreCount;
+ AdapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses;
+ AdapterObject->Dma64BitAddresses = DeviceDescription->Dma64BitAddresses;
+ AdapterObject->ScatterGather = DeviceDescription->ScatterGather;
+ AdapterObject->MasterDevice = DeviceDescription->Master;
+ if (DeviceDescription->InterfaceType != PCIBus) AdapterObject->LegacyAdapter = TRUE;
+
+ /* Everything below is not required if we don't need a channel */
+ if (!ChannelSetup) {
+ DPRINT("Retuning Adapter Object without Channel Setup\n");
+ return AdapterObject;
+ }
+
+ AdapterObject->ChannelNumber = ChannelSelect;
+
+
+ /* Set up the Page Port */
+ if (Controller == 1) {
+ switch (ChannelSelect) {
+
+ case 0:
+ AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel0));
+ break;
+ case 1:
+ AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel1));
+ break;
+ case 2:
+ AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel2));
+ break;
+ case 3:
+ AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel3));
+ break;
+ }
+
+ /* Set Controller Number */
+ AdapterObject->AdapterNumber = 1;
+ } else {
+ switch (ChannelSelect) {
+
+ case 1:
+ AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel5));
+ break;
+ case 2:
+ AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel6));
+ break;
+ case 3:
+ AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel7));
+ break;
+ }
+
+ /* Set Controller Number */
+ AdapterObject->AdapterNumber = 2;
+ }
+
+ /* Set up the Extended Register */
+ if (HalpEisaDma) {
+ DMA_EXTENDED_MODE ExtendedMode;
+
+ ExtendedMode.ChannelNumber = ChannelSelect;
+
+ switch (DeviceDescription->DmaSpeed) {
+
+ case Compatible:
+ ExtendedMode.TimingMode = COMPATIBLE_TIMING;
+ break;
+
+ case TypeA:
+ ExtendedMode.TimingMode = TYPE_A_TIMING;
+ break;
+
+ case TypeB:
+ ExtendedMode.TimingMode = TYPE_B_TIMING;
+ break;
+
+ case TypeC:
+ ExtendedMode.TimingMode = BURST_TIMING;
+ break;
+
+ default:
+ return NULL;
+ }
+
+ switch (DeviceDescription->DmaWidth) {
+
+ case Width8Bits:
+ ExtendedMode.TransferSize = B_8BITS;
+ break;
+
+ case Width16Bits:
+ ExtendedMode.TransferSize = B_16BITS;
+ break;
+
+ case Width32Bits:
+ ExtendedMode.TransferSize = B_32BITS;
+ break;
+
+ default:
+ return NULL;
+ }
+
+ if (Controller == 1) {
+ WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaExtendedMode1),
+ *((PUCHAR)&ExtendedMode));
+ } else {
+ WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaExtendedMode2),
+ *((PUCHAR)&ExtendedMode));
+ }
+ }
+ /* Do 8/16-bit validation */
+ DPRINT("Validating an Adapter Object\n");
+ if (!DeviceDescription->Master) {
+ if ((DeviceDescription->DmaWidth == Width8Bits) && (Controller != 1)) {
+ return NULL; /* 8-bit is only avalable on Controller 1 */
+ } else if (DeviceDescription->DmaWidth == Width16Bits) {
+ if (Controller != 2) {
+ return NULL; /* 16-bit is only avalable on Controller 2 */
+ } else {
+ AdapterObject->Width16Bits = TRUE;
+ }
+ }
+ }
+ UCHAR DmaMode;
+ DPRINT("Final DMA Request Mode Setting of the Adapter Object\n");
+ /* Set the DMA Request Modes */
+ if (DeviceDescription->Master) {
+ /* This is a cascade request */
+ ((PDMA_MODE)&DmaMode)->RequestMode = CASCADE_REQUEST_MODE;
+
+ /* Send the request */
+ if (AdapterObject->AdapterNumber == 1) {
+ /* Set the Request Data */
+ WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterObject->AdapterBaseVa)->Mode,
+ AdapterObject->AdapterMode);
+
+ /* Unmask DMA Channel */
+ WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterObject->AdapterBaseVa)->SingleMask,
+ AdapterObject->ChannelNumber | DMA_CLEARMASK);
+ } else {
+ /* Set the Request Data */
+ WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterObject->AdapterBaseVa)->Mode,
+ AdapterObject->AdapterMode);
+
+ /* Unmask DMA Channel */
+ WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterObject->AdapterBaseVa)->SingleMask,
+ AdapterObject->ChannelNumber | DMA_CLEARMASK);
+ }
+ } else if (DeviceDescription->DemandMode) {
+ /* This is a Demand request */
+ ((PDMA_MODE)&DmaMode)->RequestMode = DEMAND_REQUEST_MODE;
+ } else {
+ /* Normal Request */
+ ((PDMA_MODE)&DmaMode)->RequestMode = SINGLE_REQUEST_MODE;
+ }
+
+ /* Auto Initialize Enabled or Not*/
+ ((PDMA_MODE)&DmaMode)->AutoInitialize = DeviceDescription->AutoInitialize;
+ AdapterObject->AdapterMode = DmaMode;
+ return AdapterObject;
+}
+
+ULONG STDCALL
+HalReadDmaCounter (PADAPTER_OBJECT AdapterObject)
+{
+ KIRQL OldIrql;
+ ULONG Count;
+
+ KeAcquireSpinLock(&AdapterObject->MasterAdapter->SpinLock, &OldIrql);
+
+ /* Send the Request to the specific controller */
+ if (AdapterObject->AdapterNumber == 1) {
+
+ /* Set this for Ease */
+ PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
+
+ /* Send Reset */
+ WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
+
+ /* Read Count */
+ Count = READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
+ [AdapterObject->ChannelNumber].DmaBaseCount);
+ Count |= READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
+ [AdapterObject->ChannelNumber].DmaBaseCount) << 8;
+
+ } else {
+
+ /* Set this for Ease */
+ PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
+
+ /* Send Reset */
+ WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
+
+ /* Read Count */
+ Count = READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
+ [AdapterObject->ChannelNumber].DmaBaseCount);
+ Count |= READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
+ [AdapterObject->ChannelNumber].DmaBaseCount) << 8;
+ }
+
+ /* Play around with the count (add bias and multiply by 2 if 16-bit DMA) */
+ Count ++;
+ if (AdapterObject->Width16Bits) Count *=2 ;
+
+ KeReleaseSpinLock(&AdapterObject->MasterAdapter->SpinLock, OldIrql);
+
+ /* Return it */
+ return Count;
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N drive.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ drive.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,31 @@
+/* $Id: drive.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/x86/drive.c
+ * PURPOSE: Drive letter assignment
+ * PROGRAMMER:
+ * UPDATE HISTORY:
+ * 2000-03-25
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+VOID STDCALL
+IoAssignDriveLetters(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+ IN PSTRING NtDeviceName,
+ OUT PUCHAR NtSystemPath,
+ OUT PSTRING NtSystemPathString)
+{
+ HalIoAssignDriveLetters(LoaderBlock,
+ NtDeviceName,
+ NtSystemPath,
+ NtSystemPathString);
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N enum.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ enum.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,24 @@
+/* $Id: enum.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/enum.c
+ * PURPOSE: Motherboard device enumerator
+ * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * UPDATE HISTORY:
+ * Created 01/05/2001
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+VOID
+HalpStartEnumerator (VOID)
+{
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N fmutex.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ fmutex.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,53 @@
+/* $Id: fmutex.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/fmutex.c
+ * PURPOSE: Implements fast mutexes
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * Eric Kohl (ekohl@rz-online.de)
+ * UPDATE HISTORY:
+ * Created 09/06/2000
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+
+#include <internal/debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+VOID FASTCALL
+ExAcquireFastMutex (PFAST_MUTEX FastMutex)
+{
+ KeEnterCriticalRegion();
+ ExAcquireFastMutexUnsafe(FastMutex);
+}
+
+
+VOID FASTCALL
+ExReleaseFastMutex (PFAST_MUTEX FastMutex)
+{
+ ExReleaseFastMutexUnsafe(FastMutex);
+ KeLeaveCriticalRegion();
+}
+
+
+BOOLEAN FASTCALL
+ExTryToAcquireFastMutex (PFAST_MUTEX FastMutex)
+{
+ KeEnterCriticalRegion();
+ if (InterlockedExchange(&FastMutex->Count, 0) == 1)
+ {
+ FastMutex->Owner = KeGetCurrentThread();
+ return(TRUE);
+ }
+ else
+ {
+ KeLeaveCriticalRegion();
+ return(FALSE);
+ }
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N halinit.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ halinit.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,65 @@
+/* $Id: halinit.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/halinit.c
+ * PURPOSE: Initalize the x86 hal
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ * 11/06/98: Created
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS *****************************************************************/
+
+PVOID HalpZeroPageMapping = NULL;
+
+/* FUNCTIONS ***************************************************************/
+
+NTSTATUS
+STDCALL
+DriverEntry(
+ PDRIVER_OBJECT DriverObject,
+ PUNICODE_STRING RegistryPath)
+{
+ return STATUS_SUCCESS;
+}
+
+BOOLEAN STDCALL
+HalInitSystem (ULONG BootPhase,
+ PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+ if (BootPhase == 0)
+ {
+ /* Initialize display and make the screen black */
+ HalInitializeDisplay (LoaderBlock);
+
+ HalpInitPhase0();
+ }
+ else if (BootPhase == 1)
+ {
+ HalpInitBusHandlers();
+ HalpInitDma();
+
+ /* Enumerate the devices on the motherboard */
+ HalpStartEnumerator();
+ }
+ else if (BootPhase == 2)
+ {
+ /* Go to blue screen */
+ HalClearDisplay (0x17); /* grey on blue */
+
+ HalpZeroPageMapping = MmMapIoSpace((LARGE_INTEGER)0LL, PAGE_SIZE, MmNonCached);
+ }
+
+ return TRUE;
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N ipi.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ipi.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,26 @@
+/* $Id: ipi.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/generic/ipi.c
+ * PURPOSE: Miscellaneous hardware functions
+ * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ****************************************************************/
+
+VOID STDCALL
+HalRequestIpi(ULONG ProcessorNo)
+{
+ DPRINT("HalRequestIpi(ProcessorNo %d)\n", ProcessorNo);
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N irql.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ irql.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,479 @@
+/* $Id: irql.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/irql.c
+ * PURPOSE: Implements IRQLs
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ps.h>
+#include <ntos/minmax.h>
+#include <hal.h>
+#include <halirq.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS ******************************************************************/
+
+/*
+ * FIXME: Use EISA_CONTROL STRUCTURE INSTEAD OF HARD-CODED OFFSETS
+*/
+
+typedef union
+{
+ USHORT both;
+ struct
+ {
+ BYTE master;
+ BYTE slave;
+ };
+}
+PIC_MASK;
+
+/*
+ * PURPOSE: - Mask for HalEnableSystemInterrupt and HalDisableSystemInterrupt
+ * - At startup enable timer and cascade
+ */
+#if defined(__GNUC__)
+static PIC_MASK pic_mask = {.both = 0xFFFA};
+#else
+static PIC_MASK pic_mask = { 0xFFFA };
+#endif
+
+
+/*
+ * PURPOSE: Mask for disabling of acknowledged interrupts
+ */
+#if defined(__GNUC__)
+static PIC_MASK pic_mask_intr = {.both = 0x0000};
+#else
+static PIC_MASK pic_mask_intr = { 0 };
+#endif
+
+static ULONG HalpPendingInterruptCount[NR_IRQS];
+
+#define DIRQL_TO_IRQ(x) (PROFILE_LEVEL - x)
+#define IRQ_TO_DIRQL(x) (PROFILE_LEVEL - x)
+
+VOID STDCALL
+KiInterruptDispatch2 (ULONG Irq, KIRQL old_level);
+
+/* FUNCTIONS ****************************************************************/
+
+KIRQL STDCALL KeGetCurrentIrql (VOID)
+/*
+ * PURPOSE: Returns the current irq level
+ * RETURNS: The current irq level
+ */
+{
+ return(KeGetCurrentKPCR()->Irql);
+}
+
+VOID HalpInitPICs(VOID)
+{
+ memset(HalpPendingInterruptCount, 0, sizeof(HalpPendingInterruptCount));
+
+ /* Initialization sequence */
+ WRITE_PORT_UCHAR((PUCHAR)0x20, 0x11);
+ WRITE_PORT_UCHAR((PUCHAR)0xa0, 0x11);
+ /* Start of hardware irqs (0x24) */
+ WRITE_PORT_UCHAR((PUCHAR)0x21, IRQ_BASE);
+ WRITE_PORT_UCHAR((PUCHAR)0xa1, IRQ_BASE + 8);
+ /* 8259-1 is master */
+ WRITE_PORT_UCHAR((PUCHAR)0x21, 0x4);
+ /* 8259-2 is slave */
+ WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x2);
+ /* 8086 mode */
+ WRITE_PORT_UCHAR((PUCHAR)0x21, 0x1);
+ WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x1);
+ /* Enable interrupts */
+ WRITE_PORT_UCHAR((PUCHAR)0x21, pic_mask.master);
+ WRITE_PORT_UCHAR((PUCHAR)0xa1, pic_mask.slave);
+
+ /* We can now enable interrupts */
+ Ki386EnableInterrupts();
+}
+
+VOID HalpEndSystemInterrupt(KIRQL Irql)
+/*
+ * FUNCTION: Enable all irqs with higher priority.
+ */
+{
+ ULONG flags;
+ const USHORT mask[] =
+ {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0xc000, 0xe000, 0xf000,
+ 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80, 0xffc0, 0xffe0, 0xfff0,
+ 0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ };
+
+ /* Interrupts should be disable while enabling irqs of both pics */
+ Ki386SaveFlags(flags);
+ Ki386DisableInterrupts();
+
+ pic_mask_intr.both &= mask[Irql];
+ WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master));
+ WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
+
+ /* restore flags */
+ Ki386RestoreFlags(flags);
+}
+
+VOID STATIC
+HalpExecuteIrqs(KIRQL NewIrql)
+{
+ ULONG IrqLimit, i;
+
+ IrqLimit = min(PROFILE_LEVEL - NewIrql, NR_IRQS);
+
+ /*
+ * For each irq if there have been any deferred interrupts then now
+ * dispatch them.
+ */
+ for (i = 0; i < IrqLimit; i++)
+ {
+ if (HalpPendingInterruptCount[i] > 0)
+ {
+ KeGetCurrentKPCR()->Irql = (KIRQL)IRQ_TO_DIRQL(i);
+
+ while (HalpPendingInterruptCount[i] > 0)
+ {
+ /*
+ * For each deferred interrupt execute all the handlers at DIRQL.
+ */
+ HalpPendingInterruptCount[i]--;
+ KiInterruptDispatch2(i + IRQ_BASE, NewIrql);
+ }
+ KeGetCurrentKPCR()->Irql--;
+ HalpEndSystemInterrupt(KeGetCurrentKPCR()->Irql);
+ }
+ }
+
+}
+
+VOID STATIC
+HalpLowerIrql(KIRQL NewIrql)
+{
+ if (NewIrql >= PROFILE_LEVEL)
+ {
+ KeGetCurrentKPCR()->Irql = NewIrql;
+ return;
+ }
+ HalpExecuteIrqs(NewIrql);
+ if (NewIrql >= DISPATCH_LEVEL)
+ {
+ KeGetCurrentKPCR()->Irql = NewIrql;
+ return;
+ }
+ KeGetCurrentKPCR()->Irql = DISPATCH_LEVEL;
+ if (KeGetCurrentKPCR()->HalReserved[HAL_DPC_REQUEST])
+ {
+ KeGetCurrentKPCR()->HalReserved[HAL_DPC_REQUEST] = FALSE;
+ KiDispatchInterrupt();
+ }
+ KeGetCurrentKPCR()->Irql = APC_LEVEL;
+ if (NewIrql == APC_LEVEL)
+ {
+ return;
+ }
+ if (KeGetCurrentThread() != NULL &&
+ KeGetCurrentThread()->ApcState.KernelApcPending)
+ {
+ KiDeliverApc(KernelMode, NULL, NULL);
+ }
+ KeGetCurrentKPCR()->Irql = PASSIVE_LEVEL;
+}
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KfLowerIrql
+ *
+ * DESCRIPTION
+ * Restores the irq level on the current processor
+ *
+ * ARGUMENTS
+ * NewIrql = Irql to lower to
+ *
+ * RETURN VALUE
+ * None
+ *
+ * NOTES
+ * Uses fastcall convention
+ */
+VOID FASTCALL
+KfLowerIrql (KIRQL NewIrql)
+{
+ DPRINT("KfLowerIrql(NewIrql %d)\n", NewIrql);
+
+ if (NewIrql > KeGetCurrentKPCR()->Irql)
+ {
+ DbgPrint ("(%s:%d) NewIrql %x CurrentIrql %x\n",
+ __FILE__, __LINE__, NewIrql, KeGetCurrentKPCR()->Irql);
+ KEBUGCHECK(0);
+ for(;;);
+ }
+
+ HalpLowerIrql(NewIrql);
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KeLowerIrql
+ *
+ * DESCRIPTION
+ * Restores the irq level on the current processor
+ *
+ * ARGUMENTS
+ * NewIrql = Irql to lower to
+ *
+ * RETURN VALUE
+ * None
+ *
+ * NOTES
+ */
+
+VOID STDCALL
+KeLowerIrql (KIRQL NewIrql)
+{
+ KfLowerIrql (NewIrql);
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KfRaiseIrql
+ *
+ * DESCRIPTION
+ * Raises the hardware priority (irql)
+ *
+ * ARGUMENTS
+ * NewIrql = Irql to raise to
+ *
+ * RETURN VALUE
+ * previous irq level
+ *
+ * NOTES
+ * Uses fastcall convention
+ */
+
+KIRQL FASTCALL
+KfRaiseIrql (KIRQL NewIrql)
+{
+ KIRQL OldIrql;
+
+ DPRINT("KfRaiseIrql(NewIrql %d)\n", NewIrql);
+
+ if (NewIrql < KeGetCurrentKPCR()->Irql)
+ {
+ DbgPrint ("%s:%d CurrentIrql %x NewIrql %x\n",
+ __FILE__,__LINE__,KeGetCurrentKPCR()->Irql,NewIrql);
+ KEBUGCHECK (0);
+ for(;;);
+ }
+
+ OldIrql = KeGetCurrentKPCR()->Irql;
+ KeGetCurrentKPCR()->Irql = NewIrql;
+ return OldIrql;
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KeRaiseIrql
+ *
+ * DESCRIPTION
+ * Raises the hardware priority (irql)
+ *
+ * ARGUMENTS
+ * NewIrql = Irql to raise to
+ * OldIrql (OUT) = Caller supplied storage for the previous irql
+ *
+ * RETURN VALUE
+ * None
+ *
+ * NOTES
+ * Calls KfRaiseIrql
+ */
+VOID STDCALL
+KeRaiseIrql (KIRQL NewIrql,
+ PKIRQL OldIrql)
+{
+ *OldIrql = KfRaiseIrql (NewIrql);
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KeRaiseIrqlToDpcLevel
+ *
+ * DESCRIPTION
+ * Raises the hardware priority (irql) to DISPATCH level
+ *
+ * ARGUMENTS
+ * None
+ *
+ * RETURN VALUE
+ * Previous irq level
+ *
+ * NOTES
+ * Calls KfRaiseIrql
+ */
+
+KIRQL STDCALL
+KeRaiseIrqlToDpcLevel (VOID)
+{
+ return KfRaiseIrql (DISPATCH_LEVEL);
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KeRaiseIrqlToSynchLevel
+ *
+ * DESCRIPTION
+ * Raises the hardware priority (irql) to CLOCK2 level
+ *
+ * ARGUMENTS
+ * None
+ *
+ * RETURN VALUE
+ * Previous irq level
+ *
+ * NOTES
+ * Calls KfRaiseIrql
+ */
+
+KIRQL STDCALL
+KeRaiseIrqlToSynchLevel (VOID)
+{
+ return KfRaiseIrql (CLOCK2_LEVEL);
+}
+
+
+BOOLEAN STDCALL
+HalBeginSystemInterrupt (ULONG Vector,
+ KIRQL Irql,
+ PKIRQL OldIrql)
+{
+ ULONG irq;
+ if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
+ {
+ return(FALSE);
+ }
+ irq = Vector - IRQ_BASE;
+ pic_mask_intr.both |= ((1 << irq) & 0xfffe); // do not disable the timer interrupt
+
+ if (irq < 8)
+ {
+ WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master));
+ WRITE_PORT_UCHAR((PUCHAR)0x20, 0x20);
+ }
+ else
+ {
+ WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
+ /* Send EOI to the PICs */
+ WRITE_PORT_UCHAR((PUCHAR)0x20,0x20);
+ WRITE_PORT_UCHAR((PUCHAR)0xa0,0x20);
+ }
+
+ if (KeGetCurrentKPCR()->Irql >= Irql)
+ {
+ HalpPendingInterruptCount[irq]++;
+ return(FALSE);
+ }
+ *OldIrql = KeGetCurrentKPCR()->Irql;
+ KeGetCurrentKPCR()->Irql = Irql;
+
+ return(TRUE);
+}
+
+
+VOID STDCALL HalEndSystemInterrupt (KIRQL Irql, ULONG Unknown2)
+/*
+ * FUNCTION: Finish a system interrupt and restore the specified irq level.
+ */
+{
+ HalpLowerIrql(Irql);
+ HalpEndSystemInterrupt(Irql);
+}
+
+BOOLEAN
+STDCALL
+HalDisableSystemInterrupt(
+ ULONG Vector,
+ KIRQL Irql)
+{
+ ULONG irq;
+
+ if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
+ return FALSE;
+
+ irq = Vector - IRQ_BASE;
+ pic_mask.both |= (1 << irq);
+ if (irq < 8)
+ {
+ WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.slave));
+ }
+ else
+ {
+ WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
+ }
+
+ return TRUE;
+}
+
+
+BOOLEAN
+STDCALL
+HalEnableSystemInterrupt(
+ ULONG Vector,
+ KIRQL Irql,
+ KINTERRUPT_MODE InterruptMode)
+{
+ ULONG irq;
+
+ if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
+ return FALSE;
+
+ irq = Vector - IRQ_BASE;
+ pic_mask.both &= ~(1 << irq);
+ if (irq < 8)
+ {
+ WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master));
+ }
+ else
+ {
+ WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
+ }
+
+ return TRUE;
+}
+
+
+VOID FASTCALL
+HalRequestSoftwareInterrupt(
+ IN KIRQL Request)
+{
+ switch (Request)
+ {
+ case APC_LEVEL:
+ KeGetCurrentKPCR()->HalReserved[HAL_APC_REQUEST] = TRUE;
+ break;
+
+ case DISPATCH_LEVEL:
+ KeGetCurrentKPCR()->HalReserved[HAL_DPC_REQUEST] = TRUE;
+ break;
+
+ default:
+ KEBUGCHECK(0);
+ }
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N isa.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ isa.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,78 @@
+/* $Id: isa.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/isa.c
+ * PURPOSE: Interfaces to the ISA bus
+ * PROGRAMMER: David Welch (welch@mcmail.com)
+ * UPDATE HISTORY:
+ * 05/06/98: Created
+ */
+
+/* INCLUDES ***************************************************************/
+
+#include <ddk/ntddk.h>
+#include <bus.h>
+#include <halirq.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+BOOL HalIsaProbe(VOID)
+/*
+ * FUNCTION: Probes for an ISA bus
+ * RETURNS: True if detected
+ * NOTE: Since ISA is the default we are called last and always return
+ * true
+ */
+{
+ DbgPrint("Assuming ISA bus\n");
+
+ /*
+ * Probe for plug and play support
+ */
+ return(TRUE);
+}
+
+
+BOOLEAN STDCALL
+HalpTranslateIsaBusAddress(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ PHYSICAL_ADDRESS BusAddress,
+ PULONG AddressSpace,
+ PPHYSICAL_ADDRESS TranslatedAddress)
+{
+ BOOLEAN Result;
+
+ Result = HalTranslateBusAddress(PCIBus,
+ BusNumber,
+ BusAddress,
+ AddressSpace,
+ TranslatedAddress);
+ if (Result != FALSE)
+ return Result;
+
+ Result = HalTranslateBusAddress(Internal,
+ BusNumber,
+ BusAddress,
+ AddressSpace,
+ TranslatedAddress);
+ return Result;
+}
+
+ULONG STDCALL
+HalpGetIsaInterruptVector(PVOID BusHandler,
+ ULONG BusNumber,
+ ULONG BusInterruptLevel,
+ ULONG BusInterruptVector,
+ PKIRQL Irql,
+ PKAFFINITY Affinity)
+{
+ ULONG Vector = IRQ2VECTOR(BusInterruptVector);
+ *Irql = VECTOR2IRQL(Vector);
+ *Affinity = 0xFFFFFFFF;
+ return Vector;
+}
+/* EOF */
reactos/hal/halx86/generic
diff -N kdbg.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ kdbg.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,548 @@
+/* $Id: kdbg.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/kdbg.c
+ * PURPOSE: Serial i/o functions for the kernel debugger.
+ * PROGRAMMER: Emanuele Aliberti
+ * Eric Kohl
+ * UPDATE HISTORY:
+ * Created 05/09/99
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+#define DEFAULT_BAUD_RATE 19200
+
+
+/* MACROS *******************************************************************/
+
+#define SER_RBR(x) ((x)+0)
+#define SER_THR(x) ((x)+0)
+#define SER_DLL(x) ((x)+0)
+#define SER_IER(x) ((x)+1)
+#define SR_IER_ERDA 0x01
+#define SR_IER_ETHRE 0x02
+#define SR_IER_ERLSI 0x04
+#define SR_IER_EMS 0x08
+#define SR_IER_ALL 0x0F
+#define SER_DLM(x) ((x)+1)
+#define SER_IIR(x) ((x)+2)
+#define SER_FCR(x) ((x)+2)
+#define SR_FCR_ENABLE_FIFO 0x01
+#define SR_FCR_CLEAR_RCVR 0x02
+#define SR_FCR_CLEAR_XMIT 0x04
+#define SER_LCR(x) ((x)+3)
+#define SR_LCR_CS5 0x00
+#define SR_LCR_CS6 0x01
+#define SR_LCR_CS7 0x02
+#define SR_LCR_CS8 0x03
+#define SR_LCR_ST1 0x00
+#define SR_LCR_ST2 0x04
+#define SR_LCR_PNO 0x00
+#define SR_LCR_POD 0x08
+#define SR_LCR_PEV 0x18
+#define SR_LCR_PMK 0x28
+#define SR_LCR_PSP 0x38
+#define SR_LCR_BRK 0x40
+#define SR_LCR_DLAB 0x80
+#define SER_MCR(x) ((x)+4)
+#define SR_MCR_DTR 0x01
+#define SR_MCR_RTS 0x02
+#define SR_MCR_OUT1 0x04
+#define SR_MCR_OUT2 0x08
+#define SR_MCR_LOOP 0x10
+#define SER_LSR(x) ((x)+5)
+#define SR_LSR_DR 0x01
+#define SR_LSR_TBE 0x20
+#define SER_MSR(x) ((x)+6)
+#define SR_MSR_CTS 0x10
+#define SR_MSR_DSR 0x20
+#define SER_SCR(x) ((x)+7)
+
+
+/* GLOBAL VARIABLES *********************************************************/
+
+ULONG EXPORTED KdComPortInUse = 0;
+
+
+/* STATIC VARIABLES *********************************************************/
+
+static ULONG ComPort = 0;
+static ULONG BaudRate = 0;
+static PUCHAR PortBase = (PUCHAR)0;
+
+/* The com port must only be initialized once! */
+static BOOLEAN PortInitialized = FALSE;
+
+
+/* STATIC FUNCTIONS *********************************************************/
+
+static BOOLEAN
+KdpDoesComPortExist (PUCHAR BaseAddress)
+{
+ BOOLEAN found;
+ BYTE mcr;
+ BYTE msr;
+
+ found = FALSE;
+
+ /* save Modem Control Register (MCR) */
+ mcr = READ_PORT_UCHAR (SER_MCR(BaseAddress));
+
+ /* enable loop mode (set Bit 4 of the MCR) */
+ WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x10);
+
+ /* clear all modem output bits */
+ WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x10);
+
+ /* read the Modem Status Register */
+ msr = READ_PORT_UCHAR (SER_MSR(BaseAddress));
+
+ /*
+ * the upper nibble of the MSR (modem output bits) must be
+ * equal to the lower nibble of the MCR (modem input bits)
+ */
+ if ((msr & 0xF0) == 0x00)
+ {
+ /* set all modem output bits */
+ WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x1F);
+
+ /* read the Modem Status Register */
+ msr = READ_PORT_UCHAR (SER_MSR(BaseAddress));
+
+ /*
+ * the upper nibble of the MSR (modem output bits) must be
+ * equal to the lower nibble of the MCR (modem input bits)
+ */
+ if ((msr & 0xF0) == 0xF0)
+ {
+ /*
+ * setup a resonable state for the port:
+ * enable fifo and clear recieve/transmit buffers
+ */
+ WRITE_PORT_UCHAR (SER_FCR(BaseAddress),
+ (SR_FCR_ENABLE_FIFO | SR_FCR_CLEAR_RCVR | SR_FCR_CLEAR_XMIT));
+ WRITE_PORT_UCHAR (SER_FCR(BaseAddress), 0);
+ READ_PORT_UCHAR (SER_RBR(BaseAddress));
+ WRITE_PORT_UCHAR (SER_IER(BaseAddress), 0);
+ found = TRUE;
+ }
+ }
+
+ /* restore MCR */
+ WRITE_PORT_UCHAR (SER_MCR(BaseAddress), mcr);
+
+ return (found);
+}
+
+
+/* FUNCTIONS ****************************************************************/
+
+/* HAL.KdPortInitialize */
+BOOLEAN
+STDCALL
+KdPortInitialize (
+ PKD_PORT_INFORMATION PortInformation,
+ DWORD Unknown1,
+ DWORD Unknown2
+ )
+{
+ ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
+ char buffer[80];
+ ULONG divisor;
+ BYTE lcr;
+
+ if (PortInitialized == FALSE)
+ {
+ if (PortInformation->BaudRate != 0)
+ {
+ BaudRate = PortInformation->BaudRate;
+ }
+ else
+ {
+ BaudRate = DEFAULT_BAUD_RATE;
+ }
+
+ if (PortInformation->ComPort == 0)
+ {
+ if (KdpDoesComPortExist ((PUCHAR)BaseArray[2]))
+ {
+ PortBase = (PUCHAR)BaseArray[2];
+ ComPort = 2;
+ PortInformation->BaseAddress = (ULONG)PortBase;
+ PortInformation->ComPort = ComPort;
+#ifndef NDEBUG
+ sprintf (buffer,
+ "\nSerial port COM%ld found at 0x%lx\n",
+ ComPort,
+ (ULONG)PortBase);
+ HalDisplayString (buffer);
+#endif /* NDEBUG */
+ }
+ else if (KdpDoesComPortExist ((PUCHAR)BaseArray[1]))
+ {
+ PortBase = (PUCHAR)BaseArray[1];
+ ComPort = 1;
+ PortInformation->BaseAddress = (ULONG)PortBase;
+ PortInformation->ComPort = ComPort;
+#ifndef NDEBUG
+ sprintf (buffer,
+ "\nSerial port COM%ld found at 0x%lx\n",
+ ComPort,
+ (ULONG)PortBase);
+ HalDisplayString (buffer);
+#endif /* NDEBUG */
+ }
+ else
+ {
+ sprintf (buffer,
+ "\nKernel Debugger: No COM port found!!!\n\n");
+ HalDisplayString (buffer);
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (KdpDoesComPortExist ((PUCHAR)BaseArray[PortInformation->ComPort]))
+ {
+ PortBase = (PUCHAR)BaseArray[PortInformation->ComPort];
+ ComPort = PortInformation->ComPort;
+ PortInformation->BaseAddress = (ULONG)PortBase;
+#ifndef NDEBUG
+ sprintf (buffer,
+ "\nSerial port COM%ld found at 0x%lx\n",
+ ComPort,
+ (ULONG)PortBase);
+ HalDisplayString (buffer);
+#endif /* NDEBUG */
+ }
+ else
+ {
+ sprintf (buffer,
+ "\nKernel Debugger: No serial port found!!!\n\n");
+ HalDisplayString (buffer);
+ return FALSE;
+ }
+ }
+
+ PortInitialized = TRUE;
+ }
+
+ /*
+ * set baud rate and data format (8N1)
+ */
+
+ /* turn on DTR and RTS */
+ WRITE_PORT_UCHAR (SER_MCR(PortBase), SR_MCR_DTR | SR_MCR_RTS);
+
+ /* set DLAB */
+ lcr = READ_PORT_UCHAR (SER_LCR(PortBase)) | SR_LCR_DLAB;
+ WRITE_PORT_UCHAR (SER_LCR(PortBase), lcr);
+
+ /* set baud rate */
+ divisor = 115200 / BaudRate;
+ WRITE_PORT_UCHAR (SER_DLL(PortBase), (UCHAR)(divisor & 0xff));
+ WRITE_PORT_UCHAR (SER_DLM(PortBase), (UCHAR)((divisor >> 8) & 0xff));
+
+ /* reset DLAB and set 8N1 format */
+ WRITE_PORT_UCHAR (SER_LCR(PortBase),
+ SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO);
+
+ /* read junk out of the RBR */
+ lcr = READ_PORT_UCHAR (SER_RBR(PortBase));
+
+ /*
+ * set global info
+ */
+ KdComPortInUse = (ULONG)PortBase;
+
+ /*
+ * print message to blue screen
+ */
+ sprintf (buffer,
+ "\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
+ ComPort,
+ (ULONG)PortBase,
+ BaudRate);
+
+ HalDisplayString (buffer);
+
+ return TRUE;
+}
+
+
+/* HAL.KdPortInitializeEx */
+BOOLEAN
+STDCALL
+KdPortInitializeEx (
+ PKD_PORT_INFORMATION PortInformation,
+ DWORD Unknown1,
+ DWORD Unknown2
+ )
+{
+ ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
+ PUCHAR ComPortBase;
+ char buffer[80];
+ ULONG divisor;
+ BYTE lcr;
+
+ if (PortInformation->BaudRate == 0)
+ {
+ PortInformation->BaudRate = DEFAULT_BAUD_RATE;
+ }
+
+ if (PortInformation->ComPort == 0)
+ {
+ return FALSE;
+ }
+ else
+ {
+ if (KdpDoesComPortExist ((PUCHAR)BaseArray[PortInformation->ComPort]))
+ {
+ ComPortBase = (PUCHAR)BaseArray[PortInformation->ComPort];
+ PortInformation->BaseAddress = (ULONG)ComPortBase;
+#ifndef NDEBUG
+ sprintf (buffer,
+ "\nSerial port COM%ld found at 0x%lx\n",
+ PortInformation->ComPort,
+ (ULONG)ComPortBase];
+ HalDisplayString (buffer);
+#endif /* NDEBUG */
+ }
+ else
+ {
+ sprintf (buffer,
+ "\nKernel Debugger: Serial port not found!!!\n\n");
+ HalDisplayString (buffer);
+ return FALSE;
+ }
+ }
+
+ /*
+ * set baud rate and data format (8N1)
+ */
+
+ /* turn on DTR and RTS */
+ WRITE_PORT_UCHAR (SER_MCR(ComPortBase), SR_MCR_DTR | SR_MCR_RTS);
+
+ /* set DLAB */
+ lcr = READ_PORT_UCHAR (SER_LCR(ComPortBase)) | SR_LCR_DLAB;
+ WRITE_PORT_UCHAR (SER_LCR(ComPortBase), lcr);
+
+ /* set baud rate */
+ divisor = 115200 / PortInformation->BaudRate;
+ WRITE_PORT_UCHAR (SER_DLL(ComPortBase), (UCHAR)(divisor & 0xff));
+ WRITE_PORT_UCHAR (SER_DLM(ComPortBase), (UCHAR)((divisor >> 8) & 0xff));
+
+ /* reset DLAB and set 8N1 format */
+ WRITE_PORT_UCHAR (SER_LCR(ComPortBase),
+ SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO);
+
+ /* read junk out of the RBR */
+ lcr = READ_PORT_UCHAR (SER_RBR(ComPortBase));
+
+#ifndef NDEBUG
+
+ /*
+ * print message to blue screen
+ */
+ sprintf (buffer,
+ "\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
+ PortInformation->ComPort,
+ (ULONG)ComPortBase,
+ PortInformation->BaudRate);
+
+ HalDisplayString (buffer);
+
+#endif /* NDEBUG */
+
+ return TRUE;
+}
+
+
+/* HAL.KdPortGetByte */
+BOOLEAN
+STDCALL
+KdPortGetByte (
+ PUCHAR ByteRecieved
+ )
+{
+ if (PortInitialized == FALSE)
+ return FALSE;
+
+ if ((READ_PORT_UCHAR (SER_LSR(PortBase)) & SR_LSR_DR))
+ {
+ *ByteRecieved = READ_PORT_UCHAR (SER_RBR(PortBase));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/* HAL.KdPortGetByteEx */
+BOOLEAN
+STDCALL
+KdPortGetByteEx (
+ PKD_PORT_INFORMATION PortInformation,
+ PUCHAR ByteRecieved
+ )
+{
+ PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
+
+ if ((READ_PORT_UCHAR (SER_LSR(ComPortBase)) & SR_LSR_DR))
+ {
+ *ByteRecieved = READ_PORT_UCHAR (SER_RBR(ComPortBase));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/* HAL.KdPortPollByte */
+BOOLEAN
+STDCALL
+KdPortPollByte (
+ PUCHAR ByteRecieved
+ )
+{
+ if (PortInitialized == FALSE)
+ return FALSE;
+
+ while ((READ_PORT_UCHAR (SER_LSR(PortBase)) & SR_LSR_DR) == 0)
+ ;
+
+ *ByteRecieved = READ_PORT_UCHAR (SER_RBR(PortBase));
+
+ return TRUE;
+}
+
+
+/* HAL.KdPortPollByteEx */
+BOOLEAN
+STDCALL
+KdPortPollByteEx (
+ PKD_PORT_INFORMATION PortInformation,
+ PUCHAR ByteRecieved
+ )
+{
+ PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
+
+ while ((READ_PORT_UCHAR (SER_LSR(ComPortBase)) & SR_LSR_DR) == 0)
+ ;
+
+ *ByteRecieved = READ_PORT_UCHAR (SER_RBR(ComPortBase));
+
+ return TRUE;
+}
+
+
+
+
+/* HAL.KdPortPutByte */
+VOID
+STDCALL
+KdPortPutByte (
+ UCHAR ByteToSend
+ )
+{
+ if (PortInitialized == FALSE)
+ return;
+
+ while ((READ_PORT_UCHAR (SER_LSR(PortBase)) & SR_LSR_TBE) == 0)
+ ;
+
+ WRITE_PORT_UCHAR (SER_THR(PortBase), ByteToSend);
+}
+
+/* HAL.KdPortPutByteEx */
+VOID
+STDCALL
+KdPortPutByteEx (
+ PKD_PORT_INFORMATION PortInformation,
+ UCHAR ByteToSend
+ )
+{
+ PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
+
+ while ((READ_PORT_UCHAR (SER_LSR(ComPortBase)) & SR_LSR_TBE) == 0)
+ ;
+
+ WRITE_PORT_UCHAR (SER_THR(ComPortBase), ByteToSend);
+}
+
+
+/* HAL.KdPortRestore */
+VOID
+STDCALL
+KdPortRestore (
+ VOID
+ )
+{
+}
+
+
+/* HAL.KdPortSave */
+VOID
+STDCALL
+KdPortSave (
+ VOID
+ )
+{
+}
+
+
+/* HAL.KdPortDisableInterrupts */
+BOOLEAN
+STDCALL
+KdPortDisableInterrupts()
+{
+ UCHAR ch;
+
+ if (PortInitialized == FALSE)
+ return FALSE;
+
+ ch = READ_PORT_UCHAR (SER_MCR (PortBase));
+ ch &= (~(SR_MCR_OUT1 | SR_MCR_OUT2));
+ WRITE_PORT_UCHAR (SER_MCR (PortBase), ch);
+
+ ch = READ_PORT_UCHAR (SER_IER (PortBase));
+ ch &= (~SR_IER_ALL);
+ WRITE_PORT_UCHAR (SER_IER (PortBase), ch);
+
+ return TRUE;
+}
+
+
+/* HAL.KdPortEnableInterrupts */
+BOOLEAN
+STDCALL
+KdPortEnableInterrupts()
+{
+ UCHAR ch;
+
+ if (PortInitialized == FALSE)
+ return FALSE;
+
+ ch = READ_PORT_UCHAR (SER_IER (PortBase));
+ ch &= (~SR_IER_ALL);
+ ch |= SR_IER_ERDA;
+ WRITE_PORT_UCHAR (SER_IER (PortBase), ch);
+
+ ch = READ_PORT_UCHAR (SER_MCR (PortBase));
+ ch &= (~SR_MCR_LOOP);
+ ch |= (SR_MCR_OUT1 | SR_MCR_OUT2);
+ WRITE_PORT_UCHAR (SER_MCR (PortBase), ch);
+
+ return TRUE;
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N mca.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ mca.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,82 @@
+/*
+ * ReactOS kernel
+ * Copyright (C) 2002 ReactOS Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id: mca.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/mca.c
+ * PURPOSE: Interfaces to the MicroChannel bus
+ * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ */
+
+/*
+ * TODO:
+ * What Adapter ID is read from an empty slot?
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <bus.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/* FUNCTIONS ****************************************************************/
+
+ULONG STDCALL
+HalpGetMicroChannelData(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length)
+{
+ PCM_MCA_POS_DATA PosData = (PCM_MCA_POS_DATA)Buffer;
+
+ DPRINT("HalpGetMicroChannelData() called.\n");
+ DPRINT(" BusNumber %lu\n", BusNumber);
+ DPRINT(" SlotNumber %lu\n", SlotNumber);
+ DPRINT(" Offset 0x%lx\n", Offset);
+ DPRINT(" Length 0x%lx\n", Length);
+
+ if ((BusNumber != 0) ||
+ (SlotNumber == 0) || (SlotNumber > 8) ||
+ (Length < sizeof(CM_MCA_POS_DATA)))
+ return(0);
+
+ /* Enter Setup-Mode for given slot */
+ WRITE_PORT_UCHAR((PUCHAR)0x96, (UCHAR)(((UCHAR)(SlotNumber - 1) & 0x07) | 0x08));
+
+ /* Read POS data */
+ PosData->AdapterId = (READ_PORT_UCHAR((PUCHAR)0x101) << 8) +
+ READ_PORT_UCHAR((PUCHAR)0x100);
+ PosData->PosData1 = READ_PORT_UCHAR((PUCHAR)0x102);
+ PosData->PosData2 = READ_PORT_UCHAR((PUCHAR)0x103);
+ PosData->PosData3 = READ_PORT_UCHAR((PUCHAR)0x104);
+ PosData->PosData4 = READ_PORT_UCHAR((PUCHAR)0x105);
+
+ /* Leave Setup-Mode for given slot */
+ WRITE_PORT_UCHAR((PUCHAR)0x96, (UCHAR)((UCHAR)(SlotNumber - 1) & 0x07));
+
+ return(sizeof(CM_MCA_POS_DATA));
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N misc.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ misc.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,69 @@
+/* $Id: misc.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/misc.c
+ * PURPOSE: Miscellaneous hardware functions
+ * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ****************************************************************/
+
+VOID STDCALL
+HalHandleNMI(ULONG Unused)
+{
+ UCHAR ucStatus;
+
+ ucStatus = READ_PORT_UCHAR((PUCHAR) 0x61);
+
+ HalDisplayString ("\n*** Hardware Malfunction\n\n");
+ HalDisplayString ("Call your hardware vendor for support\n\n");
+
+ if (ucStatus & 0x80)
+ HalDisplayString ("NMI: Parity Check / Memory Parity Error\n");
+
+ if (ucStatus & 0x40)
+ HalDisplayString ("NMI: Channel Check / IOCHK\n");
+
+ HalDisplayString ("\n*** The system has halted ***\n");
+ KeEnterKernelDebugger ();
+}
+
+
+VOID STDCALL
+HalProcessorIdle(VOID)
+{
+#if 1
+ Ki386EnableInterrupts();
+ Ki386HaltProcessor();
+#else
+
+#endif
+}
+
+ULONG FASTCALL
+HalSystemVectorDispatchEntry (
+ ULONG Unknown1,
+ ULONG Unknown2,
+ ULONG Unknown3
+ )
+{
+ return 0;
+}
+
+
+VOID STDCALL
+KeFlushWriteBuffer(VOID)
+{
+ return;
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N pci.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ pci.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,803 @@
+/* $Id: pci.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/pci.c
+ * PURPOSE: Interfaces to the PCI bus
+ * PROGRAMMER: David Welch (welch@mcmail.com)
+ * Eric Kohl (ekohl@rz-online.de)
+ * UPDATE HISTORY:
+ * 05/06/1998: Created
+ * 17/08/2000: Added preliminary pci bus scanner
+ * 13/06/2001: Implemented access to pci configuration space
+ */
+
+/*
+ * NOTES: Sections copied from the Linux pci support
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <bus.h>
+#include <halirq.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/* MACROS ******************************************************************/
+
+/* FIXME These are also defined in drivers/bus/pci/pcidef.h.
+ Maybe put PCI definitions in a central include file??? */
+
+/* access type 1 macros */
+#define CONFIG_CMD(bus, dev_fn, where) \
+ (0x80000000 | (((ULONG)(bus)) << 16) | (((dev_fn) & 0x1F) << 11) | (((dev_fn) & 0xE0) << 3) | ((where) & ~3))
+
+/* access type 2 macros */
+#define IOADDR(dev_fn, where) \
+ (0xC000 | (((dev_fn) & 0x1F) << 8) | (where))
+#define FUNC(dev_fn) \
+ ((((dev_fn) & 0xE0) >> 4) | 0xf0)
+
+#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */
+#define PCI_BASE_ADDRESS_SPACE_IO 0x01
+#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
+#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
+#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */
+#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */
+#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
+#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */
+#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)
+#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL)
+/* bit 1 is reserved if address_space = 1 */
+
+
+/* GLOBALS ******************************************************************/
+
+#define TAG_PCI TAG('P', 'C', 'I', 'H')
+
+static ULONG BusConfigType = 0; /* undetermined config type */
+static KSPIN_LOCK PciLock;
+
+/* FUNCTIONS ****************************************************************/
+
+static NTSTATUS
+ReadPciConfigUchar(UCHAR Bus,
+ UCHAR Slot,
+ UCHAR Offset,
+ PUCHAR Value)
+{
+ KIRQL oldIrql;
+
+ switch (BusConfigType)
+ {
+ case 1:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
+ *Value = READ_PORT_UCHAR((PUCHAR)0xCFC + (Offset & 3));
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+
+ case 2:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
+ WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
+ *Value = READ_PORT_UCHAR((PUCHAR)(IOADDR(Slot, Offset)));
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+
+static NTSTATUS
+ReadPciConfigUshort(UCHAR Bus,
+ UCHAR Slot,
+ UCHAR Offset,
+ PUSHORT Value)
+{
+ KIRQL oldIrql;
+
+ if ((Offset & 1) != 0)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ switch (BusConfigType)
+ {
+ case 1:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
+ *Value = READ_PORT_USHORT((PUSHORT)0xCFC + (Offset & 2));
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+
+ case 2:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
+ WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
+ *Value = READ_PORT_USHORT((PUSHORT)(IOADDR(Slot, Offset)));
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+
+static NTSTATUS
+ReadPciConfigUlong(UCHAR Bus,
+ UCHAR Slot,
+ UCHAR Offset,
+ PULONG Value)
+{
+ KIRQL oldIrql;
+
+ if ((Offset & 3) != 0)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ switch (BusConfigType)
+ {
+ case 1:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
+ *Value = READ_PORT_ULONG((PULONG)0xCFC);
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+
+ case 2:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
+ WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
+ *Value = READ_PORT_ULONG((PULONG)(IOADDR(Slot, Offset)));
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+
+static NTSTATUS
+WritePciConfigUchar(UCHAR Bus,
+ UCHAR Slot,
+ UCHAR Offset,
+ UCHAR Value)
+{
+ KIRQL oldIrql;
+
+ switch (BusConfigType)
+ {
+ case 1:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
+ WRITE_PORT_UCHAR((PUCHAR)0xCFC + (Offset&3), Value);
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+
+ case 2:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
+ WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
+ WRITE_PORT_UCHAR((PUCHAR)(IOADDR(Slot,Offset)), Value);
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+
+static NTSTATUS
+WritePciConfigUshort(UCHAR Bus,
+ UCHAR Slot,
+ UCHAR Offset,
+ USHORT Value)
+{
+ KIRQL oldIrql;
+
+ if ((Offset & 1) != 0)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ switch (BusConfigType)
+ {
+ case 1:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
+ WRITE_PORT_USHORT((PUSHORT)0xCFC + (Offset & 2), Value);
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+
+ case 2:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
+ WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
+ WRITE_PORT_USHORT((PUSHORT)(IOADDR(Slot, Offset)), Value);
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+
+static NTSTATUS
+WritePciConfigUlong(UCHAR Bus,
+ UCHAR Slot,
+ UCHAR Offset,
+ ULONG Value)
+{
+ KIRQL oldIrql;
+
+ if ((Offset & 3) != 0)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ switch (BusConfigType)
+ {
+ case 1:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
+ WRITE_PORT_ULONG((PULONG)0xCFC, Value);
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+
+ case 2:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
+ WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
+ WRITE_PORT_ULONG((PULONG)(IOADDR(Slot, Offset)), Value);
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+
+static ULONG STDCALL
+HalpGetPciData(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length)
+{
+ PVOID Ptr = Buffer;
+ ULONG Address = Offset;
+ ULONG Len = Length;
+ ULONG Vendor;
+ UCHAR HeaderType;
+
+ DPRINT("HalpGetPciData() called.\n");
+ DPRINT(" BusNumber %lu\n", BusNumber);
+ DPRINT(" SlotNumber %lu\n", SlotNumber);
+ DPRINT(" Offset 0x%lx\n", Offset);
+ DPRINT(" Length 0x%lx\n", Length);
+
+ if ((Length == 0) || (BusConfigType == 0))
+ return 0;
+
+ ReadPciConfigUlong((UCHAR)BusNumber,
+ (UCHAR)(SlotNumber & 0x1F),
+ 0x00,
+ &Vendor);
+ /* some broken boards return 0 if a slot is empty: */
+ if (Vendor == 0xFFFFFFFF || Vendor == 0)
+ {
+ if (BusNumber == 0 && Offset == 0 && Length >= 2)
+ {
+ *(PUSHORT)Buffer = PCI_INVALID_VENDORID;
+ return 2;
+ }
+ return 0;
+ }
+
+ /* 0E=PCI_HEADER_TYPE */
+ ReadPciConfigUchar((UCHAR)BusNumber,
+ (UCHAR)(SlotNumber & 0x1F),
+ 0x0E,
+ &HeaderType);
+ if (((HeaderType & PCI_MULTIFUNCTION) == 0) && ((SlotNumber & 0xE0) != 0))
+ {
+ if (Offset == 0 && Length >= 2)
+ {
+ *(PUSHORT)Buffer = PCI_INVALID_VENDORID;
+ return 2;
+ }
+ return 0;
+ }
+ ReadPciConfigUlong((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ 0x00,
+ &Vendor);
+ /* some broken boards return 0 if a slot is empty: */
+ if (Vendor == 0xFFFFFFFF || Vendor == 0)
+ {
+ if (BusNumber == 0 && Offset == 0 && Length >= 2)
+ {
+ *(PUSHORT)Buffer = PCI_INVALID_VENDORID;
+ return 2;
+ }
+ return 0;
+ }
+
+ if ((Address & 1) && (Len >= 1))
+ {
+ ReadPciConfigUchar((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ (UCHAR)Address,
+ Ptr);
+ Ptr = (char*)Ptr + 1;
+ Address++;
+ Len--;
+ }
+
+ if ((Address & 2) && (Len >= 2))
+ {
+ ReadPciConfigUshort((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ (UCHAR)Address,
+ Ptr);
+ Ptr = (char*)Ptr + 2;
+ Address += 2;
+ Len -= 2;
+ }
+
+ while (Len >= 4)
+ {
+ ReadPciConfigUlong((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ (UCHAR)Address,
+ Ptr);
+ Ptr = (char*)Ptr + 4;
+ Address += 4;
+ Len -= 4;
+ }
+
+ if (Len >= 2)
+ {
+ ReadPciConfigUshort((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ (UCHAR)Address,
+ Ptr);
+ Ptr = (char*)Ptr + 2;
+ Address += 2;
+ Len -= 2;
+ }
+
+ if (Len >= 1)
+ {
+ ReadPciConfigUchar((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ (UCHAR)Address,
+ Ptr);
+ Ptr = (char*)Ptr + 1;
+ Address++;
+ Len--;
+ }
+
+ return Length - Len;
+}
+
+
+static ULONG STDCALL
+HalpSetPciData(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length)
+{
+ PVOID Ptr = Buffer;
+ ULONG Address = Offset;
+ ULONG Len = Length;
+ ULONG Vendor;
+ UCHAR HeaderType;
+
+ DPRINT("HalpSetPciData() called.\n");
+ DPRINT(" BusNumber %lu\n", BusNumber);
+ DPRINT(" SlotNumber %lu\n", SlotNumber);
+ DPRINT(" Offset 0x%lx\n", Offset);
+ DPRINT(" Length 0x%lx\n", Length);
+
+ if ((Length == 0) || (BusConfigType == 0))
+ return 0;
+
+ ReadPciConfigUlong((UCHAR)BusNumber,
+ (UCHAR)(SlotNumber & 0x1F),
+ 0x00,
+ &Vendor);
+ /* some broken boards return 0 if a slot is empty: */
+ if (Vendor == 0xFFFFFFFF || Vendor == 0)
+ return 0;
+
+
+ /* 0E=PCI_HEADER_TYPE */
+ ReadPciConfigUchar((UCHAR)BusNumber,
+ (UCHAR)(SlotNumber & 0x1F),
+ 0x0E,
+ &HeaderType);
+ if (((HeaderType & PCI_MULTIFUNCTION) == 0) && ((SlotNumber & 0xE0) != 0))
+ return 0;
+
+ ReadPciConfigUlong((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ 0x00,
+ &Vendor);
+ /* some broken boards return 0 if a slot is empty: */
+ if (Vendor == 0xFFFFFFFF || Vendor == 0)
+ return 0;
+
+ if ((Address & 1) && (Len >= 1))
+ {
+ WritePciConfigUchar((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ (UCHAR)Address,
+ *(PUCHAR)Ptr);
+ Ptr = (char*)Ptr + 1;
+ Address++;
+ Len--;
+ }
+
+ if ((Address & 2) && (Len >= 2))
+ {
+ WritePciConfigUshort((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ (UCHAR)Address,
+ *(PUSHORT)Ptr);
+ Ptr = (char*)Ptr + 2;
+ Address += 2;
+ Len -= 2;
+ }
+
+ while (Len >= 4)
+ {
+ WritePciConfigUlong((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ (UCHAR)Address,
+ *(PULONG)Ptr);
+ Ptr = (char*)Ptr + 4;
+ Address += 4;
+ Len -= 4;
+ }
+
+ if (Len >= 2)
+ {
+ WritePciConfigUshort((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ (UCHAR)Address,
+ *(PUSHORT)Ptr);
+ Ptr = (char*)Ptr + 2;
+ Address += 2;
+ Len -= 2;
+ }
+
+ if (Len >= 1)
+ {
+ WritePciConfigUchar((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ (UCHAR)Address,
+ *(PUCHAR)Ptr);
+ Ptr = (char*)Ptr + 1;
+ Address++;
+ Len--;
+ }
+
+ return Length - Len;
+}
+
+
+static ULONG
+GetBusConfigType(VOID)
+{
+ ULONG Value;
+ KIRQL oldIrql;
+
+ DPRINT("GetBusConfigType() called\n");
+
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+
+ DPRINT("Checking configuration type 1:");
+ WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x01);
+ Value = READ_PORT_ULONG((PULONG)0xCF8);
+ WRITE_PORT_ULONG((PULONG)0xCF8, 0x80000000);
+ if (READ_PORT_ULONG((PULONG)0xCF8) == 0x80000000)
+ {
+ WRITE_PORT_ULONG((PULONG)0xCF8, Value);
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ DPRINT(" Success!\n");
+ return 1;
+ }
+ WRITE_PORT_ULONG((PULONG)0xCF8, Value);
+ DPRINT(" Unsuccessful!\n");
+
+ DPRINT("Checking configuration type 2:");
+ WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x00);
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0x00);
+ WRITE_PORT_UCHAR((PUCHAR)0xCFA, 0x00);
+ if (READ_PORT_UCHAR((PUCHAR)0xCF8) == 0x00 &&
+ READ_PORT_UCHAR((PUCHAR)0xCFB) == 0x00)
+ {
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ DPRINT(" Success!\n");
+ return 2;
+ }
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ DPRINT(" Unsuccessful!\n");
+
+ DPRINT("No pci bus found!\n");
+ return 0;
+}
+
+
+static ULONG STDCALL
+HalpGetPciInterruptVector(PVOID BusHandler,
+ ULONG BusNumber,
+ ULONG BusInterruptLevel,
+ ULONG BusInterruptVector,
+ PKIRQL Irql,
+ PKAFFINITY Affinity)
+{
+ ULONG Vector = IRQ2VECTOR(BusInterruptVector);
+ *Irql = VECTOR2IRQL(Vector);
+ *Affinity = 0xFFFFFFFF;
+ return Vector;
+}
+
+static BOOLEAN STDCALL
+HalpTranslatePciAddress(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ PHYSICAL_ADDRESS BusAddress,
+ PULONG AddressSpace,
+ PPHYSICAL_ADDRESS TranslatedAddress)
+{
+ if (*AddressSpace == 0)
+ {
+ /* memory space */
+
+ }
+ else if (*AddressSpace == 1)
+ {
+ /* io space */
+
+ }
+ else
+ {
+ /* other */
+ return FALSE;
+ }
+
+ TranslatedAddress->QuadPart = BusAddress.QuadPart;
+
+ return TRUE;
+}
+
+/*
+ * Find the extent of a PCI decode..
+ */
+static ULONG STDCALL
+PciSize(ULONG Base, ULONG Mask)
+{
+ ULONG Size = Mask & Base; /* Find the significant bits */
+ Size = Size & ~(Size - 1); /* Get the lowest of them to find the decode size */
+ return Size;
+}
+
+static NTSTATUS STDCALL
+HalpAssignPciSlotResources(IN PBUS_HANDLER BusHandler,
+ IN ULONG BusNumber,
+ IN PUNICODE_STRING RegistryPath,
+ IN PUNICODE_STRING DriverClassName,
+ IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG SlotNumber,
+ IN OUT PCM_RESOURCE_LIST *AllocatedResources)
+{
+ ULONG DataSize;
+ PCI_COMMON_CONFIG PciConfig;
+ UINT Address;
+ UINT ResourceCount;
+ ULONG Size[PCI_TYPE0_ADDRESSES];
+ NTSTATUS Status = STATUS_SUCCESS;
+ UCHAR Offset;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
+
+ /* FIXME: Should handle 64-bit addresses */
+
+ DataSize = HalpGetPciData(BusHandler,
+ BusNumber,
+ SlotNumber,
+ &PciConfig,
+ 0,
+ PCI_COMMON_HDR_LENGTH);
+ if (PCI_COMMON_HDR_LENGTH != DataSize)
+ {
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Read the PCI configuration space for the device and store base address and
+ size information in temporary storage. Count the number of valid base addresses */
+ ResourceCount = 0;
+ for (Address = 0; Address < PCI_TYPE0_ADDRESSES; Address++)
+ {
+ if (0xffffffff == PciConfig.u.type0.BaseAddresses[Address])
+ {
+ PciConfig.u.type0.BaseAddresses[Address] = 0;
+ }
+ if (0 != PciConfig.u.type0.BaseAddresses[Address])
+ {
+ ResourceCount++;
+ Offset = offsetof(PCI_COMMON_CONFIG, u.type0.BaseAddresses[Address]);
+ Status = WritePciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber, Offset, 0xffffffff);
+ if (! NT_SUCCESS(Status))
+ {
+ WritePciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber, Offset,
+ PciConfig.u.type0.BaseAddresses[Address]);
+ return Status;
+ }
+ Status = ReadPciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber,
+ Offset, Size + Address);
+ if (! NT_SUCCESS(Status))
+ {
+ WritePciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber, Offset,
+ PciConfig.u.type0.BaseAddresses[Address]);
+ return Status;
+ }
+ Status = WritePciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber, Offset,
+ PciConfig.u.type0.BaseAddresses[Address]);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+ }
+
+ if (0 != PciConfig.u.type0.InterruptLine)
+ {
+ ResourceCount++;
+ }
+
+ /* Allocate output buffer and initialize */
+ *AllocatedResources = ExAllocatePoolWithTag(PagedPool,
+ sizeof(CM_RESOURCE_LIST) +
+ (ResourceCount - 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR),
+ TAG_PCI);
+ if (NULL == *AllocatedResources)
+ {
+ return STATUS_NO_MEMORY;
+ }
+ (*AllocatedResources)->Count = 1;
+ (*AllocatedResources)->List[0].InterfaceType = PCIBus;
+ (*AllocatedResources)->List[0].BusNumber = BusNumber;
+ (*AllocatedResources)->List[0].PartialResourceList.Version = 1;
+ (*AllocatedResources)->List[0].PartialResourceList.Revision = 1;
+ (*AllocatedResources)->List[0].PartialResourceList.Count = ResourceCount;
+ Descriptor = (*AllocatedResources)->List[0].PartialResourceList.PartialDescriptors;
+
+ /* Store configuration information */
+ for (Address = 0; Address < PCI_TYPE0_ADDRESSES; Address++)
+ {
+ if (0 != PciConfig.u.type0.BaseAddresses[Address])
+ {
+ if (PCI_BASE_ADDRESS_SPACE_MEMORY ==
+ (PciConfig.u.type0.BaseAddresses[Address] & PCI_BASE_ADDRESS_SPACE))
+ {
+ Descriptor->Type = CmResourceTypeMemory;
+ Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; /* FIXME I have no idea... */
+ Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE; /* FIXME Just a guess */
+ Descriptor->u.Memory.Start.QuadPart = (PciConfig.u.type0.BaseAddresses[Address] & PCI_BASE_ADDRESS_MEM_MASK);
+ Descriptor->u.Memory.Length = PciSize(Size[Address], PCI_BASE_ADDRESS_MEM_MASK);
+ }
+ else if (PCI_BASE_ADDRESS_SPACE_IO ==
+ (PciConfig.u.type0.BaseAddresses[Address] & PCI_BASE_ADDRESS_SPACE))
+ {
+ Descriptor->Type = CmResourceTypePort;
+ Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; /* FIXME I have no idea... */
+ Descriptor->Flags = CM_RESOURCE_PORT_IO; /* FIXME Just a guess */
+ Descriptor->u.Port.Start.QuadPart = PciConfig.u.type0.BaseAddresses[Address] &= PCI_BASE_ADDRESS_IO_MASK;
+ Descriptor->u.Port.Length = PciSize(Size[Address], PCI_BASE_ADDRESS_IO_MASK & 0xffff);
+ }
+ else
+ {
+ ASSERT(FALSE);
+ return STATUS_UNSUCCESSFUL;
+ }
+ Descriptor++;
+ }
+ }
+
+ if (0 != PciConfig.u.type0.InterruptLine)
+ {
+ Descriptor->Type = CmResourceTypeInterrupt;
+ Descriptor->ShareDisposition = CmResourceShareShared; /* FIXME Just a guess */
+ Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE; /* FIXME Just a guess */
+ Descriptor->u.Interrupt.Level = PciConfig.u.type0.InterruptLine;
+ Descriptor->u.Interrupt.Vector = PciConfig.u.type0.InterruptLine;
+ Descriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
+
+ Descriptor++;
+ }
+
+ ASSERT(Descriptor == (*AllocatedResources)->List[0].PartialResourceList.PartialDescriptors + ResourceCount);
+
+ /* FIXME: Should store the resources in the registry resource map */
+
+ return Status;
+}
+
+
+VOID
+HalpInitPciBus(VOID)
+{
+ PBUS_HANDLER BusHandler;
+
+ DPRINT("HalpInitPciBus() called.\n");
+
+ KeInitializeSpinLock (&PciLock);
+
+ BusConfigType = GetBusConfigType();
+ if (BusConfigType == 0)
+ return;
+
+ DPRINT("Bus configuration %lu used\n", BusConfigType);
+
+ /* pci bus (bus 0) handler */
+ BusHandler = HalpAllocateBusHandler(PCIBus,
+ PCIConfiguration,
+ 0);
+ BusHandler->GetBusData = (pGetSetBusData)HalpGetPciData;
+ BusHandler->SetBusData = (pGetSetBusData)HalpSetPciData;
+ BusHandler->GetInterruptVector =
+ (pGetInterruptVector)HalpGetPciInterruptVector;
+ BusHandler->TranslateBusAddress =
+ (pTranslateBusAddress)HalpTranslatePciAddress;
+// BusHandler->AdjustResourceList =
+// (pGetSetBusData)HalpAdjustPciResourceList;
+ BusHandler->AssignSlotResources =
+ (pAssignSlotResources)HalpAssignPciSlotResources;
+
+
+ /* agp bus (bus 1) handler */
+ BusHandler = HalpAllocateBusHandler(PCIBus,
+ PCIConfiguration,
+ 1);
+ BusHandler->GetBusData = (pGetSetBusData)HalpGetPciData;
+ BusHandler->SetBusData = (pGetSetBusData)HalpSetPciData;
+ BusHandler->GetInterruptVector =
+ (pGetInterruptVector)HalpGetPciInterruptVector;
+ BusHandler->TranslateBusAddress =
+ (pTranslateBusAddress)HalpTranslatePciAddress;
+// BusHandler->AdjustResourceList =
+// (pGetSetBusData)HalpAdjustPciResourceList;
+ BusHandler->AssignSlotResources =
+ (pAssignSlotResources)HalpAssignPciSlotResources;
+
+
+ /* PCI bus (bus 2) handler */
+ BusHandler = HalpAllocateBusHandler(PCIBus,
+ PCIConfiguration,
+ 2);
+ BusHandler->GetBusData = (pGetSetBusData)HalpGetPciData;
+ BusHandler->SetBusData = (pGetSetBusData)HalpSetPciData;
+ BusHandler->GetInterruptVector =
+ (pGetInterruptVector)HalpGetPciInterruptVector;
+ BusHandler->TranslateBusAddress =
+ (pTranslateBusAddress)HalpTranslatePciAddress;
+// BusHandler->AdjustResourceList =
+// (pGetSetBusData)HalpAdjustPciResourceList;
+ BusHandler->AssignSlotResources =
+ (pAssignSlotResources)HalpAssignPciSlotResources;
+
+ DPRINT("HalpInitPciBus() finished.\n");
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N portio.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ portio.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,342 @@
+/* $Id: portio.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/portio.c
+ * PURPOSE: Port I/O functions
+ * PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ * UPDATE HISTORY:
+ * Created 18/10/99
+ */
+
+#include <ddk/ntddk.h>
+
+
+/* FUNCTIONS ****************************************************************/
+
+/*
+ * This file contains the definitions for the x86 IO instructions
+ * inb/inw/inl/outb/outw/outl and the "string versions" of the same
+ * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
+ * versions of the single-IO instructions (inb_p/inw_p/..).
+ *
+ * This file is not meant to be obfuscating: it's just complicated
+ * to (a) handle it all in a way that makes gcc able to optimize it
+ * as well as possible and (b) trying to avoid writing the same thing
+ * over and over again with slight variations and possibly making a
+ * mistake somewhere.
+ */
+
+/*
+ * Thanks to James van Artsdalen for a better timing-fix than
+ * the two short jumps: using outb's to a nonexistent port seems
+ * to guarantee better timings even on fast machines.
+ *
+ * On the other hand, I'd like to be sure of a non-existent port:
+ * I feel a bit unsafe about using 0x80 (should be safe, though)
+ *
+ * Linus
+ */
+
+#if defined(__GNUC__)
+
+#ifdef SLOW_IO_BY_JUMPING
+#define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
+#else
+#define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
+#endif
+
+#elif defined(_MSC_VER)
+
+#ifdef SLOW_IO_BY_JUMPING
+#define __SLOW_DOWN_IO __asm jmp 1f __asm jmp 1f 1f:
+#else
+#define __SLOW_DOWN_IO __asm out 0x80, al
+#endif
+
+#else
+#error Unknown compiler for inline assembler
+#endif
+
+
+#ifdef REALLY_SLOW_IO
+#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
+#else
+#define SLOW_DOWN_IO __SLOW_DOWN_IO
+#endif
+
+VOID STDCALL
+READ_PORT_BUFFER_UCHAR (PUCHAR Port,
+ PUCHAR Buffer,
+ ULONG Count)
+{
+#if defined(__GNUC__)
+ __asm__ __volatile__ ("cld ; rep ; insb\n\t"
+ : "=D" (Buffer), "=c" (Count)
+ : "d" (Port),"0" (Buffer),"1" (Count));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ mov edi, Buffer
+ mov ecx, Count
+ cld
+ rep ins byte ptr[edi], dx
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+}
+
+VOID STDCALL
+READ_PORT_BUFFER_USHORT (PUSHORT Port,
+ PUSHORT Buffer,
+ ULONG Count)
+{
+#if defined(__GNUC__)
+ __asm__ __volatile__ ("cld ; rep ; insw"
+ : "=D" (Buffer), "=c" (Count)
+ : "d" (Port),"0" (Buffer),"1" (Count));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ mov edi, Buffer
+ mov ecx, Count
+ cld
+ rep ins word ptr[edi], dx
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+}
+
+VOID STDCALL
+READ_PORT_BUFFER_ULONG (PULONG Port,
+ PULONG Buffer,
+ ULONG Count)
+{
+#if defined(__GNUC__)
+ __asm__ __volatile__ ("cld ; rep ; insl"
+ : "=D" (Buffer), "=c" (Count)
+ : "d" (Port),"0" (Buffer),"1" (Count));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ mov edi, Buffer
+ mov ecx, Count
+ cld
+ rep ins dword ptr[edi], dx
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+}
+
+UCHAR STDCALL
+READ_PORT_UCHAR (PUCHAR Port)
+{
+ UCHAR Value;
+
+#if defined(__GNUC__)
+ __asm__("inb %w1, %0\n\t"
+ : "=a" (Value)
+ : "d" (Port));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ in al, dx
+ mov Value, al
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+
+ SLOW_DOWN_IO;
+ return(Value);
+}
+
+USHORT STDCALL
+READ_PORT_USHORT (PUSHORT Port)
+{
+ USHORT Value;
+
+#if defined(__GNUC__)
+ __asm__("inw %w1, %0\n\t"
+ : "=a" (Value)
+ : "d" (Port));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ in ax, dx
+ mov Value, ax
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+ SLOW_DOWN_IO;
+ return(Value);
+}
+
+ULONG STDCALL
+READ_PORT_ULONG (PULONG Port)
+{
+ ULONG Value;
+
+#if defined(__GNUC__)
+ __asm__("inl %w1, %0\n\t"
+ : "=a" (Value)
+ : "d" (Port));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ in eax, dx
+ mov Value, eax
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+ SLOW_DOWN_IO;
+ return(Value);
+}
+
+VOID STDCALL
+WRITE_PORT_BUFFER_UCHAR (PUCHAR Port,
+ PUCHAR Buffer,
+ ULONG Count)
+{
+#if defined(__GNUC__)
+ __asm__ __volatile__ ("cld ; rep ; outsb"
+ : "=S" (Buffer), "=c" (Count)
+ : "d" (Port),"0" (Buffer),"1" (Count));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ mov esi, Buffer
+ mov ecx, Count
+ cld
+ rep outs
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+}
+
+VOID STDCALL
+WRITE_PORT_BUFFER_USHORT (PUSHORT Port,
+ PUSHORT Buffer,
+ ULONG Count)
+{
+#if defined(__GNUC__)
+ __asm__ __volatile__ ("cld ; rep ; outsw"
+ : "=S" (Buffer), "=c" (Count)
+ : "d" (Port),"0" (Buffer),"1" (Count));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ mov esi, Buffer
+ mov ecx, Count
+ cld
+ rep outsw
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+}
+
+VOID STDCALL
+WRITE_PORT_BUFFER_ULONG (PULONG Port,
+ PULONG Buffer,
+ ULONG Count)
+{
+#if defined(__GNUC__)
+ __asm__ __volatile__ ("cld ; rep ; outsl"
+ : "=S" (Buffer), "=c" (Count)
+ : "d" (Port),"0" (Buffer),"1" (Count));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ mov esi, Buffer
+ mov ecx, Count
+ cld
+ rep outsd
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+}
+
+VOID STDCALL
+WRITE_PORT_UCHAR (PUCHAR Port,
+ UCHAR Value)
+{
+#if defined(__GNUC__)
+ __asm__("outb %0, %w1\n\t"
+ :
+ : "a" (Value),
+ "d" (Port));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ mov al, Value
+ out dx,al
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+ SLOW_DOWN_IO;
+}
+
+VOID STDCALL
+WRITE_PORT_USHORT (PUSHORT Port,
+ USHORT Value)
+{
+#if defined(__GNUC__)
+ __asm__("outw %0, %w1\n\t"
+ :
+ : "a" (Value),
+ "d" (Port));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ mov ax, Value
+ out dx,ax
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+ SLOW_DOWN_IO;
+}
+
+VOID STDCALL
+WRITE_PORT_ULONG (PULONG Port,
+ ULONG Value)
+{
+#if defined(__GNUC__)
+ __asm__("outl %0, %w1\n\t"
+ :
+ : "a" (Value),
+ "d" (Port));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ mov eax, Value
+ out dx,eax
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+ SLOW_DOWN_IO;
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N processor.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ processor.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,50 @@
+/* $Id: processor.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/generic/processor.c
+ * PURPOSE: Intel MultiProcessor specification support
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * NOTES: Parts adapted from linux SMP code
+ * UPDATE HISTORY:
+ * 22/05/1998 DW Created
+ * 12/04/2001 CSH Added MultiProcessor specification support
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/* FUNCTIONS *****************************************************************/
+
+VOID STDCALL
+HalInitializeProcessor(ULONG ProcessorNumber,
+ PVOID /*PLOADER_PARAMETER_BLOCK*/ LoaderBlock)
+{
+ DPRINT("HalInitializeProcessor(%x %x)\n", ProcessorNumber, LoaderBlock);
+}
+
+BOOLEAN STDCALL
+HalAllProcessorsStarted (VOID)
+{
+ DPRINT("HalAllProcessorsStarted()\n");
+
+ return TRUE;
+}
+
+BOOLEAN STDCALL
+HalStartNextProcessor(ULONG Unknown1,
+ ULONG ProcessorStack)
+{
+ DPRINT("HalStartNextProcessor(%x %x)\n", ProcessorNumber, ProcessorStack);
+
+ return TRUE;
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N pwroff.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ pwroff.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,121 @@
+/* $Id: pwroff.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * FILE : reactos/hal/x86/apm.c
+ * DESCRIPTION: Turn CPU off...
+ * PROJECT : ReactOS Operating System
+ * AUTHOR : D. Lindauer (July 11 1997)
+ * NOTE : This program is public domain
+ * REVISIONS :
+ * 1999-12-26
+ */
+
+#define APM_FUNCTION_AVAILABLE 0x5300
+#define APM_FUNCTION_CONNREAL 0x5301
+#define APM_FUNCTION_POWEROFF 0x5307
+#define APM_FUNCTION_ENABLECPU 0x530d
+#define APM_FUNCTION_ENABLEAPM 0x530e
+
+#define APM_DEVICE_BIOS 0
+#define APM_DEVICE_ALL 1
+
+#define APM_MODE_DISABLE 0
+#define APM_MODE_ENABLE 1
+
+
+
+#if defined(__GNUC__)
+
+nopm db 'No power management functionality',10,13,'$'
+errmsg db 'Power management error',10,13,'$'
+wrongver db 'Need APM version 1.1 or better',10,13,'$'
+;
+; Entry point
+;
+go:
+ mov dx,offset nopm
+ jc error
+ cmp ax,101h ; See if version 1.1 or greater
+ mov dx,offset wrongver
+ jc error
+
+ mov [ver],ax
+ mov ax,5301h ; Do a real mode connection
+ mov bx,0 ; device = BIOS
+ int 15h
+ jnc noconerr
+
+ cmp ah,2 ; Pass if already connected
+ mov dx,offset errmsg ; else error
+ jnz error
+noconerr:
+ mov ax,530eh ; Enable latest version of APM
+ mov bx,0 ; device = BIOS
+ mov cx,[ver] ; version
+ int 15h
+ mov dx,offset errmsg
+ jc error
+
+ mov ax,530dh ; Now engage and enable CPU management
+ mov bx,1 ; device = all
+ mov cx,1 ; enable
+ int 15h
+ mov dx,offset errmsg
+ jc error
+
+ mov ax,530fh
+ mov bx,1 ; device = ALL
+ mov cx,1 ; enable
+ int 15h
+ mov dx,offset errmsg
+ jc error
+
+ mov dx,offset errmsg
+error:
+ call print
+ mov ax,4c01h
+ int 21h
+ int 3
+ end start
+
+
+BOOLEAN
+ApmCall (
+ DWORD Function,
+ DWORD Device,
+ DWORD Mode
+ )
+{
+ /* AX <== Function */
+ /* BX <== Device */
+ /* CX <== Mode */
+ __asm__("int 21\n"); /* 0x15 */
+}
+
+#elif defined(_MSC_VER)
+#else
+#error Unknown compiler for inline assembler
+#endif
+
+
+BOOLEAN
+HalPowerOff (VOID)
+{
+ ApmCall (
+ APM_FUNCTION_AVAILABLE,
+ APM_DEVICE_BIOS,
+ 0
+ );
+ ApmCall (
+ APM_FUNCTION_ENABLEAPM,
+ );
+ /* Shutdown CPU */
+ ApmCall (
+ APM_FUNCTION_POWEROFF,
+ APM_DEVICE_ALL,
+ 3
+ );
+ return TRUE;
+}
+
+
+/* EOF */
reactos/hal/halx86/generic
diff -N reboot.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ reboot.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,72 @@
+/* $Id: reboot.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/reboot.c
+ * PURPOSE: Reboot functions.
+ * PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ * UPDATE HISTORY:
+ * Created 11/10/99
+ */
+
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+
+static VOID
+HalReboot (VOID)
+{
+ char data;
+ extern PVOID HalpZeroPageMapping;
+
+ /* enable warm reboot */
+ ((PUCHAR)HalpZeroPageMapping)[0x472] = 0x34;
+ ((PUCHAR)HalpZeroPageMapping)[0x473] = 0x12;
+
+ /* disable interrupts */
+ Ki386DisableInterrupts();
+
+
+ /* disable periodic interrupt (RTC) */
+ WRITE_PORT_UCHAR((PUCHAR)0x70, 0x0b);
+ data = READ_PORT_UCHAR((PUCHAR)0x71);
+ WRITE_PORT_UCHAR((PUCHAR)0x71, (UCHAR)(data & 0xbf));
+
+ /* */
+ WRITE_PORT_UCHAR((PUCHAR)0x70, 0x0a);
+ data = READ_PORT_UCHAR((PUCHAR)0x71);
+ WRITE_PORT_UCHAR((PUCHAR)0x71, (UCHAR)((data & 0xf0) | 0x06));
+
+ /* */
+ WRITE_PORT_UCHAR((PUCHAR)0x70, 0x15);
+
+ /* generate RESET signal via keyboard controller */
+ WRITE_PORT_UCHAR((PUCHAR)0x64, 0xfe);
+
+ /* stop the processor */
+#if 1
+ Ki386HaltProcessor();
+ for(;;);
+#endif
+}
+
+
+VOID STDCALL
+HalReturnToFirmware (
+ ULONG Action
+ )
+{
+ if (Action == FIRMWARE_HALT)
+ {
+ DbgPrint ("HalReturnToFirmware called!\n");
+ DbgBreakPoint ();
+ }
+ else if (Action == FIRMWARE_REBOOT)
+ {
+ HalReleaseDisplayOwnership();
+ HalReboot ();
+ }
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N resource.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ resource.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,32 @@
+/* $Id: resource.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/generic/resource.c
+ * PURPOSE: Miscellaneous resource functions
+ * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ****************************************************************/
+
+VOID STDCALL
+HalReportResourceUsage(VOID)
+{
+ /*
+ * FIXME: Report all resources used by hal.
+ * Calls IoReportHalResourceUsage()
+ */
+
+ /* Initialize PCI bus. */
+ HalpInitPciBus ();
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N spinlock.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ spinlock.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,101 @@
+/* $Id: spinlock.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/spinlock.c
+ * PURPOSE: Implements spinlocks
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * Eric Kohl (ekohl@rz-online.de)
+ * UPDATE HISTORY:
+ * 09/06/2000 Created
+ */
+
+/*
+ * NOTE: On a uniprocessor machine spinlocks are implemented by raising
+ * the irq level
+ */
+
+/* INCLUDES ****************************************************************/
+
+#include <ddk/ntddk.h>
+
+#include <internal/debug.h>
+
+/* FUNCTIONS ***************************************************************/
+
+VOID STDCALL
+KeAcquireSpinLock (
+ PKSPIN_LOCK SpinLock,
+ PKIRQL OldIrql
+ )
+/*
+ * FUNCTION: Acquires a spinlock
+ * ARGUMENTS:
+ * SpinLock = Spinlock to acquire
+ * OldIrql (OUT) = Caller supplied storage for the previous irql
+ */
+{
+ *OldIrql = KfAcquireSpinLock(SpinLock);
+}
+
+KIRQL FASTCALL
+KeAcquireSpinLockRaiseToSynch (
+ PKSPIN_LOCK SpinLock
+ )
+{
+ KIRQL OldIrql;
+
+ OldIrql = KfRaiseIrql(SYNCH_LEVEL);
+ KiAcquireSpinLock(SpinLock);
+
+ return OldIrql;
+}
+
+VOID STDCALL
+KeReleaseSpinLock (
+ PKSPIN_LOCK SpinLock,
+ KIRQL NewIrql
+ )
+/*
+ * FUNCTION: Releases a spinlock
+ * ARGUMENTS:
+ * SpinLock = Spinlock to release
+ * NewIrql = Irql level before acquiring the spinlock
+ */
+{
+ KfReleaseSpinLock(SpinLock, NewIrql);
+}
+
+KIRQL FASTCALL
+KfAcquireSpinLock (
+ PKSPIN_LOCK SpinLock
+ )
+{
+ KIRQL OldIrql;
+
+ ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+
+ OldIrql = KfRaiseIrql(DISPATCH_LEVEL);
+ KiAcquireSpinLock(SpinLock);
+
+ return OldIrql;
+}
+
+VOID FASTCALL
+KfReleaseSpinLock (
+ PKSPIN_LOCK SpinLock,
+ KIRQL NewIrql
+ )
+/*
+ * FUNCTION: Releases a spinlock
+ * ARGUMENTS:
+ * SpinLock = Spinlock to release
+ * NewIrql = Irql level before acquiring the spinlock
+ */
+{
+ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL || KeGetCurrentIrql() == SYNCH_LEVEL);
+ KiReleaseSpinLock(SpinLock);
+ KfLowerIrql(NewIrql);
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N sysbus.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sysbus.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,69 @@
+/* $Id: sysbus.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/sysbus.c
+ * PURPOSE: System bus handler functions
+ * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ * UPDATE HISTORY:
+ * 09/04/2000 Created
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <bus.h>
+#include <halirq.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/* FUNCTIONS ****************************************************************/
+
+ULONG STDCALL
+HalpGetSystemInterruptVector(PVOID BusHandler,
+ ULONG BusNumber,
+ ULONG BusInterruptLevel,
+ ULONG BusInterruptVector,
+ PKIRQL Irql,
+ PKAFFINITY Affinity)
+{
+ ULONG Vector = IRQ2VECTOR(BusInterruptVector);
+ *Irql = VECTOR2IRQL(Vector);
+ *Affinity = 0xFFFFFFFF;
+ return Vector;
+}
+
+
+BOOLEAN STDCALL
+HalpTranslateSystemBusAddress(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ PHYSICAL_ADDRESS BusAddress,
+ PULONG AddressSpace,
+ PPHYSICAL_ADDRESS TranslatedAddress)
+{
+ ULONG BaseAddress = 0;
+
+ if (*AddressSpace == 0)
+ {
+ /* memory space */
+
+ }
+ else if (*AddressSpace == 1)
+ {
+ /* io space */
+
+ }
+ else
+ {
+ /* other */
+ return FALSE;
+ }
+
+ TranslatedAddress->QuadPart = BusAddress.QuadPart + BaseAddress;
+
+ return TRUE;
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N sysinfo.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sysinfo.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,76 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/sysinfo.c
+ * PURPOSE: Getting system information
+ * PROGRAMMER: David Welch (welch@mcmail.com)
+ * UPDATE HISTORY:
+ * Created 22/05/98
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include <bus.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/* FUNCTIONS ****************************************************************/
+
+NTSTATUS STDCALL
+HalpQuerySystemInformation(IN HAL_QUERY_INFORMATION_CLASS InformationClass,
+ IN ULONG BufferSize,
+ IN OUT PVOID Buffer,
+ OUT PULONG ReturnedLength)
+{
+ ULONG DataLength;
+ NTSTATUS Status;
+
+ DPRINT1("HalpQuerySystemInformation() called\n");
+
+ *ReturnedLength = 0;
+
+ DataLength = 0;
+
+ switch(InformationClass)
+ {
+#if 0
+ case HalInstalledBusInformation:
+ Status = HalpQueryBusInformation(BufferSize,
+ Buffer,
+ ReturnedLength);
+ break;
+#endif
+
+ default:
+ DataLength = 0;
+ Status = STATUS_INVALID_LEVEL;
+ break;
+ }
+
+ if (DataLength != 0)
+ {
+ if (DataLength > BufferSize)
+ DataLength = BufferSize;
+
+// RtlCopyMemory();
+
+ *ReturnedLength = DataLength;
+ }
+
+ return(Status);
+}
+
+
+#if 0
+NTSTATUS
+HalpSetSystemInformation(VOID)
+{
+ UNIMPLEMENTED;
+}
+#endif
+
+/* EOF */
reactos/hal/halx86/generic
diff -N time.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ time.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,359 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/time.c
+ * PURPOSE: Getting time information
+ * UPDATE HISTORY:
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <string.h>
+#include <hal.h>
+#include <bus.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* MACROS and CONSTANTS ******************************************************/
+
+/* macro BCD_INT : convert bcd to int */
+#define BCD_INT(bcd) (((bcd & 0xf0) >> 4) * 10 + (bcd &0x0f))
+
+/* macro INT_BCD : convert int to bcd */
+#define INT_BCD(int) (((int / 10) << 4) + (int % 10))
+
+
+#define RTC_REGISTER_A 0x0A
+#define RTC_REG_A_UIP 0x80 /* Update In Progress bit */
+
+#define RTC_REGISTER_B 0x0B
+
+#define RTC_REGISTER_CENTURY 0x32
+
+/* GLOBALS ******************************************************************/
+
+static KSPIN_LOCK CmosLock = {0};
+
+/* FUNCTIONS *****************************************************************/
+
+
+static UCHAR
+HalpQueryCMOS(UCHAR Reg)
+{
+ UCHAR Val;
+ ULONG Flags;
+
+ Reg |= 0x80;
+
+ /* save flags and disable interrupts */
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+
+ WRITE_PORT_UCHAR((PUCHAR)0x70, Reg);
+ Val = READ_PORT_UCHAR((PUCHAR)0x71);
+ WRITE_PORT_UCHAR((PUCHAR)0x70, 0);
+
+ /* restore flags */
+ Ki386RestoreFlags(Flags);
+
+ return(Val);
+}
+
+
+static VOID
+HalpSetCMOS(UCHAR Reg,
+ UCHAR Val)
+{
+ ULONG Flags;
+
+ Reg |= 0x80;
+
+ /* save flags and disable interrupts */
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+
+ WRITE_PORT_UCHAR((PUCHAR)0x70, Reg);
+ WRITE_PORT_UCHAR((PUCHAR)0x71, Val);
+ WRITE_PORT_UCHAR((PUCHAR)0x70, 0);
+
+ /* restore flags */
+ Ki386RestoreFlags(Flags);
+}
+
+
+static UCHAR
+HalpQueryECMOS(USHORT Reg)
+{
+ UCHAR Val;
+ ULONG Flags;
+
+ /* save flags and disable interrupts */
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+
+ WRITE_PORT_UCHAR((PUCHAR)0x74, (UCHAR)(Reg & 0x00FF));
+ WRITE_PORT_UCHAR((PUCHAR)0x75, (UCHAR)(Reg>>8));
+ Val = READ_PORT_UCHAR((PUCHAR)0x76);
+
+ /* restore flags */
+ Ki386RestoreFlags(Flags);
+
+ return(Val);
+}
+
+
+static VOID
+HalpSetECMOS(USHORT Reg,
+ UCHAR Val)
+{
+ ULONG Flags;
+
+ /* save flags and disable interrupts */
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+
+ WRITE_PORT_UCHAR((PUCHAR)0x74, (UCHAR)(Reg & 0x00FF));
+ WRITE_PORT_UCHAR((PUCHAR)0x75, (UCHAR)(Reg>>8));
+ WRITE_PORT_UCHAR((PUCHAR)0x76, Val);
+
+ /* restore flags */
+ Ki386RestoreFlags(Flags);
+}
+
+
+VOID STDCALL
+HalQueryRealTimeClock(PTIME_FIELDS Time)
+{
+ KIRQL oldIrql;
+
+ KeAcquireSpinLock(&CmosLock, &oldIrql);
+
+ /* check 'Update In Progress' bit */
+ while (HalpQueryCMOS (RTC_REGISTER_A) & RTC_REG_A_UIP);
+
+ Time->Second = BCD_INT(HalpQueryCMOS (0));
+ Time->Minute = BCD_INT(HalpQueryCMOS (2));
+ Time->Hour = BCD_INT(HalpQueryCMOS (4));
+ Time->Weekday = BCD_INT(HalpQueryCMOS (6));
+ Time->Day = BCD_INT(HalpQueryCMOS (7));
+ Time->Month = BCD_INT(HalpQueryCMOS (8));
+ Time->Year = BCD_INT(HalpQueryCMOS (9));
+
+ if (Time->Year > 80)
+ Time->Year += 1900;
+ else
+ Time->Year += 2000;
+
+#if 0
+ /* Century */
+ Time->Year += BCD_INT(HalpQueryCMOS (RTC_REGISTER_CENTURY)) * 100;
+#endif
+
+ KeReleaseSpinLock(&CmosLock, oldIrql);
+
+#ifndef NDEBUG
+ DbgPrint ("HalQueryRealTimeClock() %d:%d:%d %d/%d/%d\n",
+ Time->Hour,
+ Time->Minute,
+ Time->Second,
+ Time->Day,
+ Time->Month,
+ Time->Year
+ );
+#endif
+
+ Time->Milliseconds = 0;
+}
+
+
+VOID STDCALL
+HalSetRealTimeClock(PTIME_FIELDS Time)
+{
+ KIRQL oldIrql;
+
+ KeAcquireSpinLock(&CmosLock, &oldIrql);
+
+ /* check 'Update In Progress' bit */
+ while (HalpQueryCMOS (RTC_REGISTER_A) & RTC_REG_A_UIP);
+
+ HalpSetCMOS (0, (UCHAR)INT_BCD(Time->Second));
+ HalpSetCMOS (2, (UCHAR)INT_BCD(Time->Minute));
+ HalpSetCMOS (4, (UCHAR)INT_BCD(Time->Hour));
+ HalpSetCMOS (6, (UCHAR)INT_BCD(Time->Weekday));
+ HalpSetCMOS (7, (UCHAR)INT_BCD(Time->Day));
+ HalpSetCMOS (8, (UCHAR)INT_BCD(Time->Month));
+ HalpSetCMOS (9, (UCHAR)INT_BCD(Time->Year % 100));
+
+#if 0
+ /* Century */
+ HalpSetCMOS (RTC_REGISTER_CENTURY, INT_BCD(Time->Year / 100));
+#endif
+ KeReleaseSpinLock(&CmosLock, oldIrql);
+
+}
+
+
+BOOLEAN STDCALL
+HalGetEnvironmentVariable(PCH Name,
+ PCH Value,
+ USHORT ValueLength)
+{
+ KIRQL oldIrql;
+
+
+ if (_stricmp(Name, "LastKnownGood") != 0)
+ {
+ return FALSE;
+ }
+
+ KeAcquireSpinLock(&CmosLock, &oldIrql);
+ if (HalpQueryCMOS(RTC_REGISTER_B) & 0x01)
+ {
+ strncpy(Value, "FALSE", ValueLength);
+ }
+ else
+ {
+ strncpy(Value, "TRUE", ValueLength);
+ }
+ KeReleaseSpinLock(&CmosLock, oldIrql);
+
+ return TRUE;
+}
+
+
+BOOLEAN STDCALL
+HalSetEnvironmentVariable(PCH Name,
+ PCH Value)
+{
+ UCHAR Val;
+ KIRQL oldIrql;
+ BOOLEAN result = TRUE;
+
+ if (_stricmp(Name, "LastKnownGood") != 0)
+ return FALSE;
+
+ KeAcquireSpinLock(&CmosLock, &oldIrql);
+
+ Val = HalpQueryCMOS(RTC_REGISTER_B);
+
+ if (_stricmp(Value, "TRUE") == 0)
+ HalpSetCMOS(RTC_REGISTER_B, (UCHAR)(Val | 0x01));
+ else if (_stricmp(Value, "FALSE") == 0)
+ HalpSetCMOS(RTC_REGISTER_B, (UCHAR)(Val & ~0x01));
+ else
+ result = FALSE;
+
+ KeReleaseSpinLock(&CmosLock, oldIrql);
+
+ return result;
+}
+
+
+ULONG STDCALL
+HalpGetCmosData(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length)
+{
+ PUCHAR Ptr = Buffer;
+ ULONG Address = SlotNumber;
+ ULONG Len = Length;
+ KIRQL oldIrql;
+
+ DPRINT("HalpGetCmosData() called.\n");
+ DPRINT(" BusNumber %lu\n", BusNumber);
+ DPRINT(" SlotNumber %lu\n", SlotNumber);
+ DPRINT(" Offset 0x%lx\n", Offset);
+ DPRINT(" Length 0x%lx\n", Length);
+
+ if (Length == 0)
+ return 0;
+
+ if (BusNumber == 0)
+ {
+ /* CMOS */
+ KeAcquireSpinLock(&CmosLock, &oldIrql);
+ while ((Len > 0) && (Address < 0x100))
+ {
+ *Ptr = HalpQueryCMOS((UCHAR)Address);
+ Ptr = Ptr + 1;
+ Address++;
+ Len--;
+ }
+ KeReleaseSpinLock(&CmosLock, oldIrql);
+ }
+ else if (BusNumber == 1)
+ {
+ /* Extended CMOS */
+ KeAcquireSpinLock(&CmosLock, &oldIrql);
+ while ((Len > 0) && (Address < 0x1000))
+ {
+ *Ptr = HalpQueryECMOS((USHORT)Address);
+ Ptr = Ptr + 1;
+ Address++;
+ Len--;
+ }
+ KeReleaseSpinLock(&CmosLock, oldIrql);
+ }
+
+ return(Length - Len);
+}
+
+
+ULONG STDCALL
+HalpSetCmosData(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length)
+{
+ PUCHAR Ptr = (PUCHAR)Buffer;
+ ULONG Address = SlotNumber;
+ ULONG Len = Length;
+ KIRQL oldIrql;
+
+ DPRINT("HalpSetCmosData() called.\n");
+ DPRINT(" BusNumber %lu\n", BusNumber);
+ DPRINT(" SlotNumber %lu\n", SlotNumber);
+ DPRINT(" Offset 0x%lx\n", Offset);
+ DPRINT(" Length 0x%lx\n", Length);
+
+ if (Length == 0)
+ return 0;
+
+ if (BusNumber == 0)
+ {
+ /* CMOS */
+ KeAcquireSpinLock(&CmosLock, &oldIrql);
+ while ((Len > 0) && (Address < 0x100))
+ {
+ HalpSetCMOS((UCHAR)Address, *Ptr);
+ Ptr = Ptr + 1;
+ Address++;
+ Len--;
+ }
+ KeReleaseSpinLock(&CmosLock, oldIrql);
+ }
+ else if (BusNumber == 1)
+ {
+ /* Extended CMOS */
+ KeAcquireSpinLock(&CmosLock, &oldIrql);
+ while ((Len > 0) && (Address < 0x1000))
+ {
+ HalpSetECMOS((USHORT)Address, *Ptr);
+ Ptr = Ptr + 1;
+ Address++;
+ Len--;
+ }
+ KeReleaseSpinLock(&CmosLock, oldIrql);
+ }
+
+ return(Length - Len);
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N timer.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ timer.c 3 Dec 2004 20:10:43 -0000 1.1
@@ -0,0 +1,366 @@
+/*
+ * ReactOS kernel
+ * Copyright (C) 2000 David Welch <welch@cwcom.net>
+ * Copyright (C) 1999 Gareth Owen <gaz@athene.co.uk>, Ramon von Handel
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ * This software is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING. If not, write
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ * MA 02139, USA.
+ *
+ */
+/* $Id: timer.c,v 1.1 2004/12/03 20:10:43 gvg Exp $
+ *
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/udelay.c
+ * PURPOSE: Busy waiting
+ * PROGRAMMER: David Welch (david.welch@seh.ox.ac.uk)
+ * UPDATE HISTORY:
+ * 06/11/99 Created
+ */
+
+/* INCLUDES ***************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ps.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS ******************************************************************/
+
+static unsigned int delay_count = 1;
+
+#define TMR_CTRL 0x43 /* I/O for control */
+#define TMR_CNT0 0x40 /* I/O for counter 0 */
+#define TMR_CNT1 0x41 /* I/O for counter 1 */
+#define TMR_CNT2 0x42 /* I/O for counter 2 */
+
+#define TMR_SC0 0 /* Select channel 0 */
+#define TMR_SC1 0x40 /* Select channel 1 */
+#define TMR_SC2 0x80 /* Select channel 2 */
+
+#define TMR_LOW 0x10 /* RW low byte only */
+#define TMR_HIGH 0x20 /* RW high byte only */
+#define TMR_BOTH 0x30 /* RW both bytes */
+
+#define TMR_MD0 0 /* Mode 0 */
+#define TMR_MD1 0x2 /* Mode 1 */
+#define TMR_MD2 0x4 /* Mode 2 */
+#define TMR_MD3 0x6 /* Mode 3 */
+#define TMR_MD4 0x8 /* Mode 4 */
+#define TMR_MD5 0xA /* Mode 5 */
+
+#define TMR_BCD 1 /* BCD mode */
+
+#define TMR_LATCH 0 /* Latch command */
+
+#define TMR_READ 0xF0 /* Read command */
+#define TMR_CNT 0x20 /* CNT bit (Active low, subtract it) */
+#define TMR_STAT 0x10 /* Status bit (Active low, subtract it) */
+#define TMR_CH2 0x8 /* Channel 2 bit */
+#define TMR_CH1 0x4 /* Channel 1 bit */
+#define TMR_CH0 0x2 /* Channel 0 bit */
+
+#define MILLISEC 10 /* Number of millisec between interrupts */
+#define HZ (1000 / MILLISEC) /* Number of interrupts per second */
+#define CLOCK_TICK_RATE 1193182 /* Clock frequency of the timer chip */
+#define LATCH (CLOCK_TICK_RATE / HZ) /* Count to program into the timer chip */
+#define PRECISION 8 /* Number of bits to calibrate for delay loop */
+
+static BOOLEAN UdelayCalibrated = FALSE;
+
+/* FUNCTIONS **************************************************************/
+
+/*
+ * NOTE: This function MUST NOT be optimized by the compiler!
+ * If it is, it obviously will not delay AT ALL, and the system
+ * will appear completely frozen at boot since
+ * HalpCalibrateStallExecution will never return.
+ * There are three options to stop optimization:
+ * 1. Use a volatile automatic variable. Making it delay quite a bit
+ * due to memory accesses, and keeping the code portable. However,
+ * as this involves memory access it depends on both the CPU cache,
+ * e.g. if the stack used is already in a cache line or not, and
+ * whether or not we're MP. If MP, another CPU could (probably would)
+ * also access RAM at the same time - making the delay imprecise.
+ * 2. Use compiler-specific #pragma's to disable optimization.
+ * 3. Use inline assembly, making it equally unportable as #2.
+ * For supported compilers we use inline assembler. For the others,
+ * portable plain C.
+ */
+VOID STDCALL
+__KeStallExecutionProcessor(ULONG Loops)
+{
+ if (!Loops)
+ {
+ return;
+ }
+#if defined(__GNUC__)
+ __asm__ __volatile__ (
+ "mov %0, %%eax\n"
+ "ROSL1: dec %%eax\n"
+ "jnz ROSL1" : : "d" (Loops));
+
+#elif defined(_MSC_VER)
+ __asm mov eax, Loops
+ROSL1:
+ __asm dec eax
+ __asm jnz ROSL1
+#else
+ volatile unsigned int target = Loops;
+ unsigned int i;
+ for (i=0; i<target;i++);
+#endif
+}
+
+VOID STDCALL KeStallExecutionProcessor(ULONG Microseconds)
+{
+ PKPCR Pcr = KeGetCurrentKPCR();
+
+ if (Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC)
+ {
+ LARGE_INTEGER EndCount, CurrentCount;
+ Ki386RdTSC(EndCount);
+ EndCount.QuadPart += Microseconds * (ULONGLONG)Pcr->PrcbData.MHz;
+ do
+ {
+ Ki386RdTSC(CurrentCount);
+ }
+ while (CurrentCount.QuadPart < EndCount.QuadPart);
+ }
+ else
+ {
+ __KeStallExecutionProcessor((Pcr->StallScaleFactor*Microseconds)/1000);
+ }
+}
+
+static ULONG Read8254Timer(VOID)
+{
+ ULONG Count;
+ ULONG flags;
+
+ /* save flags and disable interrupts */
+ Ki386SaveFlags(flags);
+ Ki386DisableInterrupts();
+
+ WRITE_PORT_UCHAR((PUCHAR) TMR_CTRL, TMR_SC0 | TMR_LATCH);
+ Count = READ_PORT_UCHAR((PUCHAR) TMR_CNT0);
+ Count |= READ_PORT_UCHAR((PUCHAR) TMR_CNT0) << 8;
+
+ /* restore flags */
+ Ki386RestoreFlags(flags);
+
+ return Count;
+}
+
+
+static VOID WaitFor8254Wraparound(VOID)
+{
+ ULONG CurCount, PrevCount = ~0;
+ LONG Delta;
+
+ CurCount = Read8254Timer();
+
+ do
+ {
+ PrevCount = CurCount;
+ CurCount = Read8254Timer();
+ Delta = CurCount - PrevCount;
+
+ /*
+ * This limit for delta seems arbitrary, but it isn't, it's
+ * slightly above the level of error a buggy Mercury/Neptune
+ * chipset timer can cause.
+ */
+
+ }
+ while (Delta < 300);
+}
+
+VOID HalpCalibrateStallExecution(VOID)
+{
+ ULONG i;
+ ULONG calib_bit;
+ ULONG CurCount;
+ PKPCR Pcr;
+ LARGE_INTEGER StartCount, EndCount;
+
+ if (UdelayCalibrated)
+ {
+ return;
+ }
+
+ UdelayCalibrated = TRUE;
+ Pcr = KeGetCurrentKPCR();
+
+ /* Initialise timer interrupt with MILLISEC ms interval */
+ WRITE_PORT_UCHAR((PUCHAR) TMR_CTRL, TMR_SC0 | TMR_BOTH | TMR_MD2); /* binary, mode 2, LSB/MSB, ch 0 */
+ WRITE_PORT_UCHAR((PUCHAR) TMR_CNT0, LATCH & 0xff); /* LSB */
+ WRITE_PORT_UCHAR((PUCHAR) TMR_CNT0, LATCH >> 8); /* MSB */
+
+ if (Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC)
+ {
+
+ WaitFor8254Wraparound();
+ Ki386RdTSC(StartCount);
+
+ WaitFor8254Wraparound();
+ Ki386RdTSC(EndCount);
+
+ Pcr->PrcbData.MHz = (ULONG)(EndCount.QuadPart - StartCount.QuadPart) / 10000;
+ DPRINT("%dMHz\n", Pcr->PrcbData.MHz);
+ return;
+
+ }
+
+ DbgPrint("Calibrating delay loop... [");
+
+ /* Stage 1: Coarse calibration */
+
+ WaitFor8254Wraparound();
+
+ delay_count = 1;
+
+ do
+ {
+ delay_count <<= 1; /* Next delay count to try */
+
+ WaitFor8254Wraparound();
+
+ __KeStallExecutionProcessor(delay_count); /* Do the delay */
+
+ CurCount = Read8254Timer();
+ }
+ while (CurCount > LATCH / 2);
+
+ delay_count >>= 1; /* Get bottom value for delay */
+
+ /* Stage 2: Fine calibration */
+ DbgPrint("delay_count: %d", delay_count);
+
+ calib_bit = delay_count; /* Which bit are we going to test */
+
+ for (i = 0; i < PRECISION; i++)
+ {
+ calib_bit >>= 1; /* Next bit to calibrate */
+ if (!calib_bit)
+ {
+ break; /* If we have done all bits, stop */
+ }
+
+ delay_count |= calib_bit; /* Set the bit in delay_count */
+
+ WaitFor8254Wraparound();
+
+ __KeStallExecutionProcessor(delay_count); /* Do the delay */
+
+ CurCount = Read8254Timer();
+ if (CurCount <= LATCH / 2) /* If a tick has passed, turn the */
+ { /* calibrated bit back off */
+ delay_count &= ~calib_bit;
+ }
+ }
+
+ /* We're finished: Do the finishing touches */
+
+ delay_count /= (MILLISEC / 2); /* Calculate delay_count for 1ms */
+
+ DbgPrint("]\n");
+ DbgPrint("delay_count: %d\n", delay_count);
+ DbgPrint("CPU speed: %d\n", delay_count / 250);
+#if 0
+ DbgPrint("About to start delay loop test\n");
+ DbgPrint("Waiting for five minutes...");
+ for (i = 0; i < (5*60*1000*20); i++)
+ {
+ KeStallExecutionProcessor(50);
+ }
+ DbgPrint("finished\n");
+ for(;;);
+#endif
+}
+
+
+VOID STDCALL
+HalCalibratePerformanceCounter(ULONG Count)
+{
+ ULONG flags;
+
+ /* save flags and disable interrupts */
+ Ki386SaveFlags(flags);
+ Ki386DisableInterrupts();
+
+ __KeStallExecutionProcessor(Count);
+
+ /* restore flags */
+ Ki386RestoreFlags(flags);
+}
+
+
+LARGE_INTEGER STDCALL
+KeQueryPerformanceCounter(PLARGE_INTEGER PerformanceFreq)
+/*
+ * FUNCTION: Queries the finest grained running count available in the system
+ * ARGUMENTS:
+ * PerformanceFreq (OUT) = The routine stores the number of
+ * performance counter ticks per second here
+ * RETURNS: The number of performance counter ticks since boot
+ */
+{
+ PKPCR Pcr;
+ LARGE_INTEGER Value;
+ ULONG Flags;
+
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+
+ Pcr = KeGetCurrentKPCR();
+
+ if (Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC)
+ {
+ Ki386RestoreFlags(Flags);
+ if (NULL != PerformanceFreq)
+ {
+ PerformanceFreq->QuadPart = Pcr->PrcbData.MHz * (ULONGLONG)1000000;
+ }
+ Ki386RdTSC(Value);
+ }
+ else
+ {
+ LARGE_INTEGER TicksOld;
+ LARGE_INTEGER TicksNew;
+ ULONG CountsLeft;
+
+ Ki386RestoreFlags(Flags);
+
+ if (NULL != PerformanceFreq)
+ {
+ PerformanceFreq->QuadPart = CLOCK_TICK_RATE;
+ }
+
+ do
+ {
+ KeQueryTickCount(&TicksOld);
+ CountsLeft = Read8254Timer();
+ Value.QuadPart = TicksOld.QuadPart * LATCH + (LATCH - CountsLeft);
+ KeQueryTickCount(&TicksNew);
+ }
+ while (TicksOld.QuadPart != TicksNew.QuadPart);
+ }
+ return Value;
+}
+
+/* EOF */
reactos/hal/halx86/include
diff -u -r1.15 -r1.16
--- hal.h 21 Nov 2004 21:53:07 -0000 1.15
+++ hal.h 3 Dec 2004 20:10:44 -0000 1.16
@@ -33,6 +33,9 @@
/* dma.c */
VOID HalpInitDma (VOID);
+/* Non-generic initialization */
+VOID HalpInitPhase0 (VOID);
+
/* DMA Page Register Structure
080 DMA RESERVED
081 DMA Page Register (channel 2)
reactos/hal/halx86/mp
diff -N .cvsignore
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ .cvsignore 3 Dec 2004 20:10:44 -0000 1.1
@@ -0,0 +1,7 @@
+*.d
+*.dll
+*.coff
+*.a
+*.o
+*.sym
+*.map
reactos/hal/halx86/mp
diff -N Makefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Makefile 3 Dec 2004 20:10:44 -0000 1.1
@@ -0,0 +1,90 @@
+# $Id: Makefile,v 1.1 2004/12/03 20:10:44 gvg Exp $
+
+PATH_TO_TOP = ../../..
+
+VPATH = ../generic
+
+default: all
+
+#
+# Build configuration
+#
+include $(PATH_TO_TOP)/rules.mak
+
+#
+# Global configuration
+#
+include $(TOOLS_PATH)/config.mk
+
+TARGET_TYPE = hal
+
+TARGET_DEFNAME = ../../hal/hal
+
+TARGET_ASFLAGS = -I$(PATH_TO_TOP)/include -I$(PATH_TO_TOP)/ntoskrnl/include -D__ASM__ -DMP
+
+TARGET_CFLAGS = -I../include -I$(PATH_TO_TOP)/ntoskrnl/include -Wall -Werror -DMP
+
+# require os code to explicitly request A/W version of structs/functions
+TARGET_CFLAGS += -D_DISABLE_TIDENTS
+
+TARGET_NAME = halmp
+
+ifneq ($(MP), 1)
+TARGET_INSTALL = no
+else
+TARGET_BOOTSTRAP = yes
+endif
+
+GENERIC_OBJECTS = \
+ adapter.o \
+ beep.o \
+ bus.o \
+ display.o \
+ dma.o \
+ drive.o \
+ enum.o \
+ fmutex.o \
+ halinit.o \
+ isa.o \
+ kdbg.o \
+ mca.o \
+ misc.o \
+ pci.o \
+ portio.o \
+ reboot.o \
+ spinlock.o \
+ sysbus.o \
+ sysinfo.o \
+ time.o \
+ timer.o
+
+MP_OBJECTS = \
+ apic.o \
+ halinit_mp.o \
+ ipi_mp.o \
+ mpsirql.o \
+ mpsboot.o \
+ mps.o \
+ processor_mp.o \
+ resource_mp.o
+
+HAL_OBJECTS = $(GENERIC_OBJECTS) $(MP_OBJECTS)
+
+DEP_OBJECTS := $(HAL_OBJECTS)
+
+TARGET_OBJECTS := $(DEP_OBJECTS) $(PATH_TO_TOP)/include/roscfg.h
+
+# Note: Must be = and not := since $(DEP_FILES) is assigned a value below
+TARGET_CLEAN = $(DEP_FILES) *.o *.dll
+
+#
+# Helper makefile
+#
+include $(TOOLS_PATH)/helper.mk
+
+#
+# Include automatic dependancy tracking
+#
+include $(TOOLS_PATH)/depend.mk
+
+# EOF
reactos/hal/halx86/mp
diff -N apic.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ apic.c 3 Dec 2004 20:10:44 -0000 1.1
@@ -0,0 +1,853 @@
+/*
+ * ReactOS kernel
+ * Copyright (C) 2004 ReactOS Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id: apic.c,v 1.1 2004/12/03 20:10:44 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/apic.c
+ * PURPOSE:
+ * PROGRAMMER:
+ */
+
+#include <ddk/ntddk.h>
+#include <internal/i386/ps.h>
+
+#include <hal.h>
+#include <halirq.h>
+#include <mps.h>
+#include <apic.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+BOOLEAN VerifyLocalAPIC(VOID);
+VOID APICCalibrateTimer(ULONG CPU);
+
+extern VOID MpsTimerInterrupt(VOID);
+extern VOID MpsErrorInterrupt(VOID);
+extern VOID MpsSpuriousInterrupt(VOID);
+extern VOID MpsIpiInterrupt(VOID);
+
+extern ULONG APICMode; /* APIC mode at startup */
+extern PULONG BIOSBase; /* Virtual address of BIOS data segment */
+extern PULONG CommonBase; /* Virtual address of common area */
+extern ULONG BootCPU; /* Bootstrap processor */
+extern ULONG OnlineCPUs; /* Bitmask of online CPUs */
+
+extern CHAR *APstart, *APend;
+extern VOID (*APflush)(VOID);
+
+#define CMOS_READ(address) ({ \
+ WRITE_PORT_UCHAR((PUCHAR)0x70, address)); \
+ READ_PORT_UCHAR((PUCHAR)0x71)); \
+})
+
+#define CMOS_WRITE(address, value) ({ \
+ WRITE_PORT_UCHAR((PUCHAR)0x70, address); \
+ WRITE_PORT_UCHAR((PUCHAR)0x71, value); \
+})
+
+#define BIOS_AREA 0x0
+#define COMMON_AREA 0x2000
+
+
+extern CPU_INFO CPUMap[MAX_CPU]; /* Map of all CPUs in the system */
+
+PULONG APICBase = (PULONG)APIC_DEFAULT_BASE; /* Virtual address of local APIC */
+
+/* For debugging */
+ULONG lastregr[MAX_CPU];
+ULONG lastvalr[MAX_CPU];
+ULONG lastregw[MAX_CPU];
+ULONG lastvalw[MAX_CPU];
+
+ULONG APICGetMaxLVT(VOID)
+{
+ ULONG tmp, ver, maxlvt;
+
+ tmp = APICRead(APIC_VER);
+ ver = GET_APIC_VERSION(tmp);
+ /* 82489DXs do not report # of LVT entries. */
+ maxlvt = APIC_INTEGRATED(ver) ? GET_APIC_MAXLVT(tmp) : 2;
+
+ return maxlvt;
+}
+
+VOID APICClear(VOID)
+{
+ ULONG tmp, maxlvt;
+
+ maxlvt = APICGetMaxLVT();
+
+ /*
+ * Careful: we have to set masks only first to deassert
+ * any level-triggered sources.
+ */
+
+ if (maxlvt >= 3)
+ {
+ tmp = ERROR_VECTOR;
+ APICWrite(APIC_LVT3, tmp | APIC_LVT3_MASKED);
+ }
+
+ tmp = APICRead(APIC_LVTT);
+ APICWrite(APIC_LVTT, tmp | APIC_LVT_MASKED);
+
+ tmp = APICRead(APIC_LINT0);
+ APICWrite(APIC_LINT0, tmp | APIC_LVT_MASKED);
+
+ tmp = APICRead(APIC_LINT1);
+ APICWrite(APIC_LINT1, tmp | APIC_LVT_MASKED);
+
+ if (maxlvt >= 4)
+ {
+ tmp = APICRead(APIC_LVTPC);
+ APICWrite(APIC_LVTPC, tmp | APIC_LVT_MASKED);
+ }
+#if 0
+ if (maxlvt >= 5)
+ {
+ tmp = APICRead(APIC_LVTTHMR);
+ APICWrite(APIC_LVTTHMR, tmp | APIC_LVT_MASKED);
+ }
+#endif
+ /*
+ * Clean APIC state for other OSs:
+ */
+ APICWrite(APIC_LVTT, APIC_LVT_MASKED);
+ APICWrite(APIC_LINT0, APIC_LVT_MASKED);
+ APICWrite(APIC_LINT1, APIC_LVT_MASKED);
+
+ if (maxlvt >= 3)
+ {
+ APICWrite(APIC_LVT3, APIC_LVT3_MASKED);
+ }
+
+ if (maxlvt >= 4)
+ {
+ APICWrite(APIC_LVTPC, APIC_LVT_MASKED);
+ }
+#if 0
+ if (maxlvt >= 5)
+ {
+ APICWrite(APIC_LVTTHMR, APIC_LVT_MASKED);
+ }
+#endif
+}
+
+/* Enable symetric I/O mode ie. connect the BSP's local APIC to INT and NMI lines */
+VOID EnableSMPMode(VOID)
+{
+ /*
+ * Do not trust the local APIC being empty at bootup.
+ */
+ APICClear();
+
+ WRITE_PORT_UCHAR((PUCHAR)0x22, 0x70);
+ WRITE_PORT_UCHAR((PUCHAR)0x23, 0x01);
+}
+
+/* Disable symetric I/O mode ie. go to PIC mode */
+inline VOID DisableSMPMode(VOID)
+{
+ /*
+ * Put the board back into PIC mode (has an effect
+ * only on certain older boards). Note that APIC
+ * interrupts, including IPIs, won't work beyond
+ * this point! The only exception are INIT IPIs.
+ */
+ WRITE_PORT_UCHAR((PUCHAR)0x22, 0x70);
+ WRITE_PORT_UCHAR((PUCHAR)0x23, 0x00);
+}
+
+VOID DumpESR(VOID)
+{
+ ULONG tmp;
+
+ if (APICGetMaxLVT() > 3)
+ {
+ APICWrite(APIC_ESR, 0);
+ }
+ tmp = APICRead(APIC_ESR);
+ DbgPrint("ESR %08x\n", tmp);
+}
+
+
+VOID APICDisable(VOID)
+{
+ ULONG tmp;
+
+ APICClear();
+
+ /*
+ * Disable APIC (implies clearing of registers for 82489DX!).
+ */
+ tmp = APICRead(APIC_SIVR);
+ tmp &= ~APIC_SIVR_ENABLE;
+ APICWrite(APIC_SIVR, tmp);
+}
+
+VOID HaliInitBSP(VOID)
+{
+ PUSHORT ps;
+ static BOOLEAN BSPInitialized = FALSE;
+
+ /* Only initialize the BSP once */
+ if (BSPInitialized)
+ {
+ KEBUGCHECK(0);
+ return;
+ }
+
+ BSPInitialized = TRUE;
+
+ DPRINT("APIC is mapped at 0x%X\n", APICBase);
+
+ if (VerifyLocalAPIC())
+ {
+ DPRINT("APIC found\n");
+ }
+ else
+ {
+ DPRINT("No APIC found\n");
+ KEBUGCHECK(0);
+ }
+
+ if (APICMode == amPIC)
+ {
+ EnableSMPMode();
+ }
+
+ APICSetup();
+
+ /* BIOS data segment */
+ BIOSBase = (PULONG)BIOS_AREA;
+
+ /* Area for communicating with the APs */
+ CommonBase = (PULONG)COMMON_AREA;
+
+ /* Copy bootstrap code to common area */
+ memcpy((PVOID)((ULONG)CommonBase + PAGE_SIZE),
+ &APstart,
+ (ULONG)&APend - (ULONG)&APstart + 1);
+
+ /* Set shutdown code */
+ CMOS_WRITE(0xF, 0xA);
+
+ /* Set warm reset vector */
+ ps = (PUSHORT)((ULONG)BIOSBase + 0x467);
+ *ps = (COMMON_AREA + PAGE_SIZE) & 0xF;
+
+ ps = (PUSHORT)((ULONG)BIOSBase + 0x469);
+ *ps = (COMMON_AREA + PAGE_SIZE) >> 4;
+
+ /* Calibrate APIC timer */
+ APICCalibrateTimer(BootCPU);
+}
+
+volatile inline ULONG _APICRead(ULONG Offset)
+{
+ PULONG p;
+
+ p = (PULONG)((ULONG)APICBase + Offset);
+ return *p;
+}
+
+#if 0
+inline VOID APICWrite(ULONG Offset,
+ ULONG Value)
+{
+ PULONG p;
+
+ p = (PULONG)((ULONG)APICBase + Offset);
+
+ *p = Value;
+}
+#else
+inline VOID APICWrite(ULONG Offset,
+ ULONG Value)
+{
+ PULONG p;
+ ULONG CPU = (_APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
+
+ lastregw[CPU] = Offset;
+ lastvalw[CPU] = Value;
+
+ p = (PULONG)((ULONG)APICBase + Offset);
+
+ *p = Value;
+}
+#endif
+
+
+#if 0
+volatile inline ULONG APICRead(ULONG Offset)
+{
+ PULONG p;
+
+ p = (PULONG)((ULONG)APICBase + Offset);
+ return *p;
+}
+#else
+volatile inline ULONG APICRead(ULONG Offset)
+{
+ PULONG p;
+ ULONG CPU = (_APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
+
+ lastregr[CPU] = Offset;
+ lastvalr[CPU] = 0;
+
+ p = (PULONG)((ULONG)APICBase + Offset);
+
+ lastvalr[CPU] = *p;
+ return lastvalr[CPU];
+}
+#endif
+
+inline VOID APICSendEOI(VOID)
+{
+ // Send the EOI
+ APICWrite(APIC_EOI, 0);
+}
+
+static VOID APICDumpBit(ULONG base)
+{
+ ULONG v, i, j;
+
+ DbgPrint("0123456789abcdef0123456789abcdef\n");
+ for (i = 0; i < 8; i++)
+ {
+ v = APICRead(base + i*0x10);
+ for (j = 0; j < 32; j++)
+ {
+ if (v & (1<<j))
+ DbgPrint("1");
+ else
+ DbgPrint("0");
+ }
+ DbgPrint("\n");
+ }
+}
+
+
+VOID APICDump(VOID)
+/*
+ * Dump the contents of the local APIC registers
+ */
+{
+ ULONG v, ver, maxlvt;
+ ULONG r1, r2, w1, w2;
+ ULONG CPU = ThisCPU();;
+
+
+
+ r1 = lastregr[CPU];
+ r2 = lastvalr[CPU];
+ w1 = lastregw[CPU];
+ w2 = lastvalw[CPU];
+
+ DbgPrint("\nPrinting local APIC contents on CPU(%d):\n", ThisCPU());
+ v = APICRead(APIC_ID);
+ DbgPrint("... ID : %08x (%01x) ", v, GET_APIC_ID(v));
+ v = APICRead(APIC_VER);
+ DbgPrint("... VERSION: %08x\n", v);
+ ver = GET_APIC_VERSION(v);
+ maxlvt = APICGetMaxLVT();
+
+ v = APICRead(APIC_TPR);
+ DbgPrint("... TPR : %08x (%02x)", v, v & ~0);
+
+ if (APIC_INTEGRATED(ver))
+ {
+ /* !82489DX */
+ v = APICRead(APIC_APR);
+ DbgPrint("... APR : %08x (%02x)\n", v, v & ~0);
+ v = APICRead(APIC_PPR);
+ DbgPrint("... PPR : %08x\n", v);
+ }
+
+ v = APICRead(APIC_EOI);
+ DbgPrint("... EOI : %08x ! ", v);
+ v = APICRead(APIC_LDR);
+ DbgPrint("... LDR : %08x\n", v);
+ v = APICRead(APIC_DFR);
+ DbgPrint("... DFR : %08x ! ", v);
+ v = APICRead(APIC_SIVR);
+ DbgPrint("... SIVR : %08x\n", v);
+
+ if (0)
+ {
+ DbgPrint("... ISR field:\n");
+ APICDumpBit(APIC_ISR);
+ DbgPrint("... TMR field:\n");
+ APICDumpBit(APIC_TMR);
+ DbgPrint("... IRR field:\n");
+ APICDumpBit(APIC_IRR);
+ }
+
+ if (APIC_INTEGRATED(ver))
+ {
+ /* !82489DX */
+ if (maxlvt > 3)
+ {
+ /* Due to the Pentium erratum 3AP. */
+ APICWrite(APIC_ESR, 0);
+ }
+ v = APICRead(APIC_ESR);
+ DbgPrint("... ESR : %08x\n", v);
+ }
+
+ v = APICRead(APIC_ICR0);
+ DbgPrint("... ICR0 : %08x ! ", v);
+ v = APICRead(APIC_ICR1);
+ DbgPrint("... ICR1 : %08x ! ", v);
+
+ v = APICRead(APIC_LVTT);
+ DbgPrint("... LVTT : %08x\n", v);
+
+ if (maxlvt > 3)
+ {
+ /* PC is LVT#4. */
+ v = APICRead(APIC_LVTPC);
+ DbgPrint("... LVTPC : %08x ! ", v);
+ }
+ v = APICRead(APIC_LINT0);
+ DbgPrint("... LINT0 : %08x ! ", v);
+ v = APICRead(APIC_LINT1);
+ DbgPrint("... LINT1 : %08x\n", v);
+
+ if (maxlvt > 2)
+ {
+ v = APICRead(APIC_LVT3);
+ DbgPrint("... LVT3 : %08x\n", v);
+ }
+
+ v = APICRead(APIC_ICRT);
+ DbgPrint("... ICRT : %08x ! ", v);
+ v = APICRead(APIC_CCRT);
+ DbgPrint("... CCCT : %08x ! ", v);
+ v = APICRead(APIC_TDCR);
+ DbgPrint("... TDCR : %08x\n", v);
+ DbgPrint("\n");
+ DbgPrint("Last register read (offset): 0x%08X\n", r1);
+ DbgPrint("Last register read (value): 0x%08X\n", r2);
+ DbgPrint("Last register written (offset): 0x%08X\n", w1);
+ DbgPrint("Last register written (value): 0x%08X\n", w2);
+ DbgPrint("\n");
+}
+
+BOOLEAN VerifyLocalAPIC(VOID)
+{
+ UINT reg0, reg1;
+ CHECKPOINT1;
+ /* The version register is read-only in a real APIC */
+ reg0 = APICRead(APIC_VER);
+ DPRINT1("Getting VERSION: %x\n", reg0);
+ APICWrite(APIC_VER, reg0 ^ APIC_VER_MASK);
+ reg1 = APICRead(APIC_VER);
+ DPRINT1("Getting VERSION: %x\n", reg1);
+
+ /*
+ * The two version reads above should print the same
+ * numbers. If the second one is different, then we
+ * poke at a non-APIC.
+ */
+
+ if (reg1 != reg0)
+ {
+ return FALSE;
+ }
+
+ /*
+ * Check if the version looks reasonably.
+ */
+ reg1 = GET_APIC_VERSION(reg0);
+ if (reg1 == 0x00 || reg1 == 0xff)
+ {
+ return FALSE;
+ }
+ reg1 = APICGetMaxLVT();
+ if (reg1 < 0x02 || reg1 == 0xff)
+ {
+ return FALSE;
+ }
+
+ /*
+ * The ID register is read/write in a real APIC.
+ */
+ reg0 = APICRead(APIC_ID);
+ DPRINT1("Getting ID: %x\n", reg0);
+ APICWrite(APIC_ID, reg0 ^ APIC_ID_MASK);
+ reg1 = APICRead(APIC_ID);
+ DPRINT1("Getting ID: %x\n", reg1);
+ APICWrite(APIC_ID, reg0);
+ if (reg1 != (reg0 ^ APIC_ID_MASK))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+VOID APICSendIPI(ULONG Target, ULONG Mode)
+{
+ ULONG tmp, i, flags;
+
+ /* save flags and disable interrupts */
+ Ki386SaveFlags(flags);
+ Ki386DisableInterrupts();
+
+ /* Wait up to 100ms for the APIC to become ready */
+ for (i = 0; i < 10000; i++)
+ {
+ tmp = APICRead(APIC_ICR0);
+ /* Check Delivery Status */
+ if ((tmp & APIC_ICR0_DS) == 0)
+ break;
+ KeStallExecutionProcessor(10);
+ }
+
+ if (i == 10000)
+ {
+ DPRINT1("CPU(%d) Previous IPI was not delivered after 100ms.\n", ThisCPU());
+ }
+
+ /* Setup the APIC to deliver the IPI */
+ DPRINT("%08x %x\n", SET_APIC_DEST_FIELD(Target), Target);
+ APICWrite(APIC_ICR1, SET_APIC_DEST_FIELD(Target));
+
+ if (Target == APIC_TARGET_SELF)
+ {
+ Mode |= APIC_ICR0_DESTS_SELF;
+ }
+ else if (Target == APIC_TARGET_ALL)
+ {
+ Mode |= APIC_ICR0_DESTS_ALL;
+ }
+ else if (Target == APIC_TARGET_ALL_BUT_SELF)
+ {
+ Mode |= APIC_ICR0_DESTS_ALL_BUT_SELF;
+ }
+ else
+ {
+ Mode |= APIC_ICR0_DESTS_FIELD;
+ }
+
+ /* Now, fire off the IPI */
+ APICWrite(APIC_ICR0, Mode);
+
+ /* Wait up to 100ms for the APIC to become ready */
+ for (i = 0; i < 10000; i++)
+ {
+ tmp = APICRead(APIC_ICR0);
+ /* Check Delivery Status */
+ if ((tmp & APIC_ICR0_DS) == 0)
+ break;
+ KeStallExecutionProcessor(10);
+ }
+
+ if (i == 10000)
+ {
+ DPRINT1("CPU(%d) Current IPI was not delivered after 100ms.\n", ThisCPU());
+ }
+ Ki386RestoreFlags(flags);
+}
+
+VOID APICSetup(VOID)
+{
+ ULONG CPU, tmp;
+
+ CPU = ThisCPU();
+
+// APICDump();
+
+ DPRINT1("CPU%d:\n", CPU);
+ DPRINT1(" Physical APIC id: %d\n", GET_APIC_ID(APICRead(APIC_ID)));
+ DPRINT1(" Logical APIC id: %d\n", GET_APIC_LOGICAL_ID(APICRead(APIC_LDR)));
+ DPRINT1("%08x %08x %08x\n", APICRead(APIC_ID), APICRead(APIC_LDR), APICRead(APIC_DFR));
+
+ /*
+ * Intel recommends to set DFR, LDR and TPR before enabling
+ * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
+ * document number 292116). So here it goes...
+ */
+
+ /*
+ * Put the APIC into flat delivery mode.
+ * Must be "all ones" explicitly for 82489DX.
+ */
+ APICWrite(APIC_DFR, 0xFFFFFFFF);
+
+ /*
+ * Set up the logical destination ID.
+ */
+ tmp = APICRead(APIC_LDR);
+ tmp &= ~APIC_LDR_MASK;
+ /*
+ * FIXME:
+ * This works only up to 8 CPU's
+ */
+ tmp |= (1 << (KeGetCurrentProcessorNumber() + 24));
+ APICWrite(APIC_LDR, tmp);
+
+
+ DPRINT1("CPU%d:\n", CPU);
+ DPRINT1(" Physical APIC id: %d\n", GET_APIC_ID(APICRead(APIC_ID)));
+ DPRINT1(" Logical APIC id: %d\n", GET_APIC_LOGICAL_ID(APICRead(APIC_LDR)));
+ DPRINT1("%08x %08x %08x\n", APICRead(APIC_ID), APICRead(APIC_LDR), APICRead(APIC_DFR));
+ DPRINT1("%d\n", CPUMap[CPU].APICId);
+
+ /* Accept only higher interrupts */
+ APICWrite(APIC_TPR, 0xef);
+
+ /* Enable local APIC */
+ tmp = APICRead(APIC_SIVR);
+ tmp &= ~0xff;
+ tmp |= APIC_SIVR_ENABLE;
+
+#if 0
+ tmp &= ~APIC_SIVR_FOCUS;
+#else
+ tmp |= APIC_SIVR_FOCUS;
+#endif
+
+ /* Set spurious interrupt vector */
+ tmp |= SPURIOUS_VECTOR;
+ APICWrite(APIC_SIVR, tmp);
+
+ /*
+ * Set up LVT0, LVT1:
+ *
+ * set up through-local-APIC on the BP's LINT0. This is not
+ * strictly necessery in pure symmetric-IO mode, but sometimes
+ * we delegate interrupts to the 8259A.
+ */
+ tmp = APICRead(APIC_LINT0) & APIC_LVT_MASKED;
+ if (CPU == BootCPU && (APICMode == amPIC || !tmp))
+ {
+ tmp = APIC_DM_EXTINT;
+ DPRINT1("enabled ExtINT on CPU#%d\n", CPU);
+ }
+ else
+ {
+ tmp = APIC_DM_EXTINT | APIC_LVT_MASKED;
+ DPRINT1("masked ExtINT on CPU#%d\n", CPU);
+ }
+ APICWrite(APIC_LINT0, tmp);
+
+
+ /*
+ * Only the BSP should see the LINT1 NMI signal, obviously.
+ */
+ if (CPU == BootCPU)
+ {
+ tmp = APIC_DM_NMI;
+ }
+ else
+ {
+ tmp = APIC_DM_NMI | APIC_LVT_MASKED;
+ }
+ if (!APIC_INTEGRATED(CPUMap[CPU].APICVersion))
+ {
+ /* 82489DX */
+ tmp |= APIC_LVT_LEVEL_TRIGGER;
+ }
+ APICWrite(APIC_LINT1, tmp);
+
+ if (APIC_INTEGRATED(CPUMap[CPU].APICVersion))
+ {
+ /* !82489DX */
+ if (APICGetMaxLVT() > 3)
+ {
+ /* Due to the Pentium erratum 3AP */
+ APICWrite(APIC_ESR, 0);
+ }
+
+ tmp = APICRead(APIC_ESR);
+ DPRINT("ESR value before enabling vector: 0x%X\n", tmp);
+
+ /* Enable sending errors */
+ tmp = ERROR_VECTOR;
+ APICWrite(APIC_LVT3, tmp);
+
+ /*
+ * Spec says clear errors after enabling vector
+ */
+ if (APICGetMaxLVT() > 3)
+ {
+ APICWrite(APIC_ESR, 0);
+ }
+ tmp = APICRead(APIC_ESR);
+ DPRINT("ESR value after enabling vector: 0x%X\n", tmp);
+ }
+}
+
+VOID APICSyncArbIDs(VOID)
+{
+ ULONG i, tmp;
+
+ /* Wait up to 100ms for the APIC to become ready */
+ for (i = 0; i < 10000; i++)
+ {
+ tmp = APICRead(APIC_ICR0);
+ /* Check Delivery Status */
+ if ((tmp & APIC_ICR0_DS) == 0)
+ break;
+ KeStallExecutionProcessor(10);
+ }
+
+ if (i == 10000)
+ {
+ DPRINT("CPU(%d) APIC busy for 100ms.\n", ThisCPU());
+ }
+
+ DPRINT("Synchronizing Arb IDs.\n");
+ APICWrite(APIC_ICR0, APIC_ICR0_DESTS_ALL | APIC_ICR0_LEVEL | APIC_DM_INIT);
+}
+
+VOID MpsErrorHandler(VOID)
+{
+ ULONG tmp1, tmp2;
+
+ APICDump();
+
+ tmp1 = APICRead(APIC_ESR);
+ APICWrite(APIC_ESR, 0);
+ tmp2 = APICRead(APIC_ESR);
+ DPRINT1("APIC error on CPU(%d) ESR(%x)(%x)\n", ThisCPU(), tmp1, tmp2);
+
+ /*
+ * Acknowledge the interrupt
+ */
+ APICSendEOI();
+
+ /* Here is what the APIC error bits mean:
+ * 0: Send CS error
+ * 1: Receive CS error
+ * 2: Send accept error
+ * 3: Receive accept error
+ * 4: Reserved
+ * 5: Send illegal vector
+ * 6: Received illegal vector
+ * 7: Illegal register address
+ */
+ DPRINT1("APIC error on CPU(%d) ESR(%x)(%x)\n", ThisCPU(), tmp1, tmp2);
+ for (;;);
+}
+
+VOID MpsSpuriousHandler(VOID)
+{
+ ULONG tmp;
+
+ DPRINT1("Spurious interrupt on CPU(%d)\n", ThisCPU());
+
+ tmp = APICRead(APIC_ISR + ((SPURIOUS_VECTOR & ~0x1f) >> 1));
+ if (tmp & (1 << (SPURIOUS_VECTOR & 0x1f)))
+ {
+ APICSendEOI();
+ return;
+ }
+#if 0
+ /* No need to send EOI here */
+ APICDump();
+#endif
+}
+
+VOID MpsIpiHandler(VOID)
+{
+ KIRQL oldIrql;
+
+ HalBeginSystemInterrupt(IPI_VECTOR,
+ VECTOR2IRQL(IPI_VECTOR),
+ &oldIrql);
+ Ki386EnableInterrupts();
+#if 0
+ DbgPrint("(%s:%d) MpsIpiHandler on CPU%d, current irql is %d\n",
+ __FILE__,__LINE__, KeGetCurrentProcessorNumber(), KeGetCurrentIrql());
+#endif
+
+ KiIpiServiceRoutine(NULL, NULL);
+
+#if 0
+ DbgPrint("(%s:%d) MpsIpiHandler on CPU%d done\n", __FILE__,__LINE__, KeGetCurrentProcessorNumber());
+#endif
+
+ Ki386DisableInterrupts();
+ HalEndSystemInterrupt(oldIrql, 0);
+}
+
+VOID
+MpsIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame,
+ PKTRAP_FRAME TrapFrame)
+{
+ TrapFrame->Gs = (USHORT)IrqTrapFrame->Gs;
+ TrapFrame->Fs = (USHORT)IrqTrapFrame->Fs;
+ TrapFrame->Es = (USHORT)IrqTrapFrame->Es;
+ TrapFrame->Ds = (USHORT)IrqTrapFrame->Ds;
+ TrapFrame->Eax = IrqTrapFrame->Eax;
+ TrapFrame->Ecx = IrqTrapFrame->Ecx;
+ TrapFrame->Edx = IrqTrapFrame->Edx;
+ TrapFrame->Ebx = IrqTrapFrame->Ebx;
+ TrapFrame->Esp = IrqTrapFrame->Esp;
+ TrapFrame->Ebp = IrqTrapFrame->Ebp;
+ TrapFrame->Esi = IrqTrapFrame->Esi;
+ TrapFrame->Edi = IrqTrapFrame->Edi;
+ TrapFrame->Eip = IrqTrapFrame->Eip;
+ TrapFrame->Cs = IrqTrapFrame->Cs;
+ TrapFrame->Eflags = IrqTrapFrame->Eflags;
+}
+
+VOID
+MpsTimerHandler(ULONG Vector, PKIRQ_TRAPFRAME Trapframe)
+{
+ KIRQL oldIrql;
+ KTRAP_FRAME KernelTrapFrame;
+#if 0
+ ULONG CPU;
+ static ULONG Count[MAX_CPU] = {0,};
+#endif
+ HalBeginSystemInterrupt(LOCAL_TIMER_VECTOR,
+ VECTOR2IRQL(LOCAL_TIMER_VECTOR),
+ &oldIrql);
+ Ki386EnableInterrupts();
+
+#if 0
+ CPU = ThisCPU();
+ if ((Count[CPU] % 100) == 0)
+ {
+ DbgPrint("(%s:%d) MpsTimerHandler on CPU%d, irql = %d, epi = %x, KPCR = %x\n", __FILE__, __LINE__, CPU, oldIrql,Trapframe->Eip, KeGetCurrentKPCR());
+ }
+ Count[CPU]++;
+#endif
+
+ MpsIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame);
+ if (KeGetCurrentProcessorNumber() == 0)
+ {
+ KeUpdateSystemTime(&KernelTrapFrame, oldIrql);
+ }
+ else
+ {
+ KeUpdateRunTime(&KernelTrapFrame, oldIrql);
+ }
+
+ Ki386DisableInterrupts();
+ HalEndSystemInterrupt (oldIrql, 0);
+}
+
+/* EOF */
reactos/hal/halx86/mp
diff -N halinit_mp.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ halinit_mp.c 3 Dec 2004 20:10:44 -0000 1.1
@@ -0,0 +1,29 @@
+/* $Id: halinit_mp.c,v 1.1 2004/12/03 20:10:44 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/halinit.c
+ * PURPOSE: Initalize the x86 hal
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ * 11/06/98: Created
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include <mps.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ***************************************************************/
+
+VOID
+HalpInitPhase0(VOID)
+{
+ HalpInitMPS();
+}
+
+/* EOF */
reactos/hal/halx86/mp
diff -N halmp.rc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ halmp.rc 3 Dec 2004 20:10:44 -0000 1.1
@@ -0,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION "X86 Multiprocessor Hardware Abstraction Layer\0"
+#define REACTOS_STR_INTERNAL_NAME "halx86mp\0"
+#define REACTOS_STR_ORIGINAL_FILENAME "halx86mp.dll\0"
+#include <reactos/version.rc>
reactos/hal/halx86/mp
diff -N ipi_mp.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ipi_mp.c 3 Dec 2004 20:10:44 -0000 1.1
@@ -0,0 +1,29 @@
+/* $Id: ipi_mp.c,v 1.1 2004/12/03 20:10:44 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/mp/ipi_mp.c
+ * PURPOSE: IPI functions for MP
+ * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include <apic.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ****************************************************************/
+
+VOID STDCALL
+HalRequestIpi(ULONG ProcessorNo)
+{
+ DPRINT("HalRequestIpi(ProcessorNo %d)\n", ProcessorNo);
+ APICSendIPI(1 << ProcessorNo,
+ IPI_VECTOR|APIC_ICR0_LEVEL_DEASSERT|APIC_ICR0_DESTM);
+}
+
+/* EOF */
reactos/hal/halx86/mp
diff -N mps.S
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ mps.S 3 Dec 2004 20:10:44 -0000 1.1
@@ -0,0 +1,109 @@
+/* $Id: mps.S,v 1.1 2004/12/03 20:10:44 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/mps.S
+ * PURPOSE: Intel MultiProcessor specification support
+ * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * UPDATE HISTORY:
+ * Created 12/04/2001
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <internal/i386/segment.h>
+
+/* FUNCTIONS *****************************************************************/
+
+#define BEFORE \
+ cld; \
+ pusha; \
+ pushl %ds; \
+ pushl %es; \
+ pushl %fs; \
+ pushl %gs; \
+ movl $(KERNEL_DS), %eax; \
+ movl %eax, %ds; \
+ movl %eax, %es; \
+ movl %eax, %gs; \
+ movl $(PCR_SELECTOR), %eax; \
+ movl %eax, %fs;
+
+#define AFTER \
+ popl %gs; \
+ popl %fs; \
+ popl %es; \
+ popl %ds; \
+ popa;
+
+.global _MpsIpiInterrupt
+_MpsIpiInterrupt:
+ /* Save registers */
+ BEFORE
+
+ /* Call the C handler */
+ call _MpsIpiHandler
+
+ /* Return to the caller */
+ AFTER
+ iret
+
+
+.globl _MpsErrorInterrupt
+_MpsErrorInterrupt:
+ /* Save registers */
+ BEFORE
+
+ /* Call the C handler */
+ call _MpsErrorHandler
+
+ /* Return to the caller */
+ AFTER
+ iret
+
+
+.globl _MpsSpuriousInterrupt
+_MpsSpuriousInterrupt:
+ /* Save registers */
+ BEFORE
+
+ /* Call the C handler */
+ call _MpsSpuriousHandler
+
+ /* Return to the caller */
+ AFTER
+ iret
+
+.global _MpsTimerInterrupt
+_MpsTimerInterrupt:
+ cld
+ pusha
+ movl $0xef,%ebx
+ pushl %ds
+ pushl %es
+ pushl %fs
+ pushl %gs
+ movl $0xceafbeef,%eax
+ pushl %eax
+ movl $(KERNEL_DS),%eax
+ movl %eax,%ds
+ movl %eax,%es
+ movl %eax,%gs
+ movl $(PCR_SELECTOR),%eax
+ movl %eax,%fs
+ pushl %esp
+ pushl %ebx
+ call _MpsTimerHandler
+ popl %eax
+ popl %eax
+ popl %eax
+ popl %gs
+ popl %fs
+ popl %es
+ popl %ds
+ popa
+ iret
+
+
+
+/* EOF */
reactos/hal/halx86/mp
diff -N mpsboot.asm
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ mpsboot.asm 3 Dec 2004 20:10:44 -0000 1.1
@@ -0,0 +1,106 @@
+;
+; COPYRIGHT: See COPYING in the top level directory
+; PROJECT: ReactOS kernel
+; FILE: ntoskrnl/hal/x86/mpsboot.c
+; PURPOSE: Bootstrap code for application processors
+; PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
+; UPDATE HISTORY:
+; Created 12/04/2001
+;
+
+;
+; Memory map at this stage is:
+; 0x2000 Location of our stack
+; 0x3000 Startup code for the APs (this code)
+;
+
+;
+; Base address of common area for BSP and APs
+;
+LOAD_BASE equ 00200000h
+
+;
+; Magic value to be put in EAX when multiboot.S is called as part of the
+; application processor initialization process
+;
+AP_MAGIC equ 12481020h
+
+;
+; Segment selectors
+;
+%define KERNEL_CS (0x8)
+%define KERNEL_DS (0x10)
+
+section .text
+
+global _APstart
+global _APend
+
+; 16 bit code
+BITS 16
+
+_APstart:
+ cli ; Just in case
+
+ xor ax, ax
+ mov ds, ax
+ mov ss, ax
+
+ mov eax, 3000h + APgdt - _APstart
+ lgdt [eax]
+
+ mov eax, cr0
+ or eax, 00010001h ; Turn on protected mode and write protection
+ mov cr0, eax
+
+ db 0eah
+ dw 3000h + flush - _APstart, KERNEL_CS
+
+; 32 bit code
+BITS 32
+
+flush:
+ mov ax, KERNEL_DS
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ ; Setup a stack for the AP
+ mov eax, 2000h
+ mov eax, [eax]
+ mov esp, eax
+
+ ; Jump to start of the kernel with AP magic in eax
+ mov eax, AP_MAGIC
+ jmp dword KERNEL_CS:(LOAD_BASE + 0x1000)
+
+ ; Never get here
+
+
+; Temporary GDT descriptor for the APs
+
+APgdt:
+; Limit
+ dw (3*8)-1
+; Base
+ dd 3000h + gdt - _APstart
+
+gdt:
+ dw 0x0 ; Null descriptor
+ dw 0x0
+ dw 0x0
+ dw 0x0
+
+ dw 0xffff ; Kernel code descriptor
+ dw 0x0000
+ dw 0x9a00
+ dw 0x00cf
+
+ dw 0xffff ; Kernel data descriptor
+ dw 0x0000
+ dw 0x9200
+ dw 0x00cf
+
+_APend:
reactos/hal/halx86/mp
diff -N mpsirql.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ mpsirql.c 3 Dec 2004 20:10:44 -0000 1.1
@@ -0,0 +1,400 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/mpsirql.c
+ * PURPOSE: Implements IRQLs for multiprocessor systems
+ * PROGRAMMERS: David Welch (welch@cwcom.net)
+ * Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * UPDATE HISTORY:
+ * 12/04/2001 CSH Created
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ke.h>
+#include <internal/ps.h>
+#include <ntos/minmax.h>
+#include <halirq.h>
+#include <hal.h>
+#include <mps.h>
+#include <apic.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS ******************************************************************/;
+
+
+/* FUNCTIONS ****************************************************************/
+
+KIRQL STDCALL KeGetCurrentIrql (VOID)
+/*
+ * PURPOSE: Returns the current irq level
+ * RETURNS: The current irq level
+ */
+{
+ KIRQL irql;
+ ULONG Flags;
+
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+
+ irql = Ki386ReadFsByte(offsetof(KPCR, Irql));
+ if (irql > HIGH_LEVEL)
+ {
+ DPRINT1 ("CurrentIrql %x\n", irql);
+ KEBUGCHECK (0);
+ }
+ if (Flags & X86_EFLAGS_IF)
+ {
+ Ki386EnableInterrupts();
+ }
+ return irql;
+}
+
+
+VOID KeSetCurrentIrql (KIRQL NewIrql)
+/*
+ * PURPOSE: Sets the current irq level without taking any action
+ */
+{
+ ULONG Flags;
+ if (NewIrql > HIGH_LEVEL)
+ {
+ DPRINT1 ("NewIrql %x\n", NewIrql);
+ KEBUGCHECK (0);
+ }
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+ Ki386WriteFsByte(offsetof(KPCR, Irql), NewIrql);
+ if (Flags & X86_EFLAGS_IF)
+ {
+ Ki386EnableInterrupts();
+ }
+}
+
+VOID
+HalpLowerIrql(KIRQL NewIrql, BOOL FromHalEndSystemInterrupt)
+{
+ ULONG Flags;
+ if (NewIrql >= DISPATCH_LEVEL)
+ {
+ KeSetCurrentIrql (NewIrql);
+ APICWrite(APIC_TPR, IRQL2TPR (NewIrql) & APIC_TPR_PRI);
+ return;
+ }
+ Ki386SaveFlags(Flags);
+ if (KeGetCurrentIrql() > APC_LEVEL)
+ {
+ KeSetCurrentIrql (DISPATCH_LEVEL);
+ APICWrite(APIC_TPR, IRQL2TPR (DISPATCH_LEVEL) & APIC_TPR_PRI);
+ if (FromHalEndSystemInterrupt || Ki386ReadFsByte(offsetof(KPCR, HalReserved[HAL_DPC_REQUEST])))
+ {
+ Ki386WriteFsByte(offsetof(KPCR, HalReserved[HAL_DPC_REQUEST]), 0);
+ Ki386EnableInterrupts();
+ KiDispatchInterrupt();
+ if (!(Flags & X86_EFLAGS_IF))
+ {
+ Ki386DisableInterrupts();
+ }
+ }
+ KeSetCurrentIrql (APC_LEVEL);
+ }
+ if (NewIrql == APC_LEVEL)
+ {
+ return;
+ }
+ if (KeGetCurrentThread () != NULL &&
+ KeGetCurrentThread ()->ApcState.KernelApcPending)
+ {
+ Ki386EnableInterrupts();
+ KiDeliverApc(KernelMode, NULL, NULL);
+ if (!(Flags & X86_EFLAGS_IF))
+ {
+ Ki386DisableInterrupts();
+ }
+ }
+ KeSetCurrentIrql (PASSIVE_LEVEL);
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KfLowerIrql
+ *
+ * DESCRIPTION
+ * Restores the irq level on the current processor
+ *
+ * ARGUMENTS
+ * NewIrql = Irql to lower to
+ *
+ * RETURN VALUE
+ * None
+ *
+ * NOTES
+ * Uses fastcall convention
+ */
+VOID FASTCALL
+KfLowerIrql (KIRQL NewIrql)
+{
+ KIRQL oldIrql = KeGetCurrentIrql();
+ if (NewIrql > oldIrql)
+ {
+ DPRINT1 ("NewIrql %x CurrentIrql %x\n", NewIrql, oldIrql);
+ KEBUGCHECK (0);
+ }
+ HalpLowerIrql (NewIrql, FALSE);
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KeLowerIrql
+ *
+ * DESCRIPTION
+ * Restores the irq level on the current processor
+ *
+ * ARGUMENTS
+ * NewIrql = Irql to lower to
+ *
+ * RETURN VALUE
+ * None
+ *
+ * NOTES
+ */
+
+VOID STDCALL
+KeLowerIrql (KIRQL NewIrql)
+{
+ KfLowerIrql (NewIrql);
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KfRaiseIrql
+ *
+ * DESCRIPTION
+ * Raises the hardware priority (irql)
+ *
+ * ARGUMENTS
+ * NewIrql = Irql to raise to
+ *
+ * RETURN VALUE
+ * previous irq level
+ *
+ * NOTES
+ * Uses fastcall convention
+ */
+
+KIRQL FASTCALL
+KfRaiseIrql (KIRQL NewIrql)
+{
+ KIRQL OldIrql;
+ ULONG Flags;
+
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+
+ OldIrql = KeGetCurrentIrql ();
+
+ if (NewIrql < OldIrql)
+ {
+ DPRINT1 ("CurrentIrql %x NewIrql %x\n", KeGetCurrentIrql (), NewIrql);
+ KEBUGCHECK (0);
+ }
+
+
+ if (NewIrql > DISPATCH_LEVEL)
+ {
+ APICWrite (APIC_TPR, IRQL2TPR(NewIrql) & APIC_TPR_PRI);
+ }
+ KeSetCurrentIrql (NewIrql);
+ if (Flags & X86_EFLAGS_IF)
+ {
+ Ki386EnableInterrupts();
+ }
+
+ return OldIrql;
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KeRaiseIrql
+ *
+ * DESCRIPTION
+ * Raises the hardware priority (irql)
+ *
+ * ARGUMENTS
+ * NewIrql = Irql to raise to
+ * OldIrql (OUT) = Caller supplied storage for the previous irql
+ *
+ * RETURN VALUE
+ * None
+ *
+ * NOTES
+ * Calls KfRaiseIrql
+ */
+VOID STDCALL
+KeRaiseIrql (KIRQL NewIrql,
+ PKIRQL OldIrql)
+{
+ *OldIrql = KfRaiseIrql (NewIrql);
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KeRaiseIrqlToDpcLevel
+ *
+ * DESCRIPTION
+ * Raises the hardware priority (irql) to DISPATCH level
+ *
+ * ARGUMENTS
+ * None
+ *
+ * RETURN VALUE
+ * Previous irq level
+ *
+ * NOTES
+ * Calls KfRaiseIrql
+ */
+
+KIRQL STDCALL
+KeRaiseIrqlToDpcLevel (VOID)
+{
+ return KfRaiseIrql (DISPATCH_LEVEL);
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KeRaiseIrqlToSynchLevel
+ *
+ * DESCRIPTION
+ * Raises the hardware priority (irql) to CLOCK2 level
+ *
+ * ARGUMENTS
+ * None
+ *
+ * RETURN VALUE
+ * Previous irq level
+ *
+ * NOTES
+ * Calls KfRaiseIrql
+ */
+
+KIRQL STDCALL
+KeRaiseIrqlToSynchLevel (VOID)
+{
+ return KfRaiseIrql (CLOCK2_LEVEL);
+}
+
+
+BOOLEAN STDCALL
+HalBeginSystemInterrupt (ULONG Vector,
+ KIRQL Irql,
+ PKIRQL OldIrql)
+{
+ ULONG Flags;
+ DPRINT("Vector (0x%X) Irql (0x%X)\n", Vector, Irql);
+
+ if (KeGetCurrentIrql () >= Irql)
+ {
+ DPRINT1("current irql %d, new irql %d\n", KeGetCurrentIrql(), Irql);
+ KEBUGCHECK(0);
+ }
+
+ Ki386SaveFlags(Flags);
+ if (Flags & X86_EFLAGS_IF)
+ {
+ DPRINT1("HalBeginSystemInterrupt was called with interrupt's enabled\n");
+ KEBUGCHECK(0);
+ }
+ APICWrite (APIC_TPR, IRQL2TPR (Irql) & APIC_TPR_PRI);
+ *OldIrql = KeGetCurrentIrql ();
+ KeSetCurrentIrql (Irql);
+ return(TRUE);
+}
+
+
+VOID STDCALL
+HalEndSystemInterrupt (KIRQL Irql,
+ ULONG Unknown2)
+/*
+ * FUNCTION: Finish a system interrupt and restore the specified irq level.
+ */
+{
+ ULONG Flags;
+ Ki386SaveFlags(Flags);
+
+ if (Flags & X86_EFLAGS_IF)
+ {
+ DPRINT1("HalEndSystemInterrupt was called with interrupt's enabled\n");
+ KEBUGCHECK(0);
+ }
+ APICSendEOI();
+ HalpLowerIrql (Irql, TRUE);
+}
+
+BOOLEAN STDCALL
+HalDisableSystemInterrupt (ULONG Vector,
+ KIRQL Irql)
+{
+ ULONG irq;
+
+ DPRINT ("Vector (0x%X)\n", Vector);
+
+ if (Vector < FIRST_DEVICE_VECTOR ||
+ Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS)
+ {
+ DPRINT1("Not a device interrupt, vector=%x\n", Vector);
+ return FALSE;
+ }
+
+ irq = VECTOR2IRQ (Vector);
+ IOAPICMaskIrq (irq);
+
+ return TRUE;
+}
+
+
+BOOLEAN STDCALL
+HalEnableSystemInterrupt (ULONG Vector,
+ KIRQL Irql,
+ KINTERRUPT_MODE InterruptMode)
+{
+ ULONG irq;
+
+ if (Vector < FIRST_DEVICE_VECTOR ||
+ Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS)
+ {
+ DPRINT("Not a device interrupt\n");
+ return FALSE;
+ }
+
+ irq = VECTOR2IRQ (Vector);
+ IOAPICUnmaskIrq (irq);
+
+ return TRUE;
+}
+
+VOID FASTCALL
+HalRequestSoftwareInterrupt(IN KIRQL Request)
+{
+ switch (Request)
+ {
+ case APC_LEVEL:
+ Ki386WriteFsByte(offsetof(KPCR, HalReserved[HAL_APC_REQUEST]), 1);
+ break;
+
+ case DISPATCH_LEVEL:
+ Ki386WriteFsByte(offsetof(KPCR, HalReserved[HAL_DPC_REQUEST]), 1);
+ break;
+
+ default:
+ KEBUGCHECK(0);
+ }
+}
reactos/hal/halx86/mp
diff -N processor_mp.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ processor_mp.c 3 Dec 2004 20:10:44 -0000 1.1
@@ -0,0 +1,1807 @@
+/* $Id: processor_mp.c,v 1.1 2004/12/03 20:10:44 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/mp/processor_mp.c
+ * PURPOSE: Intel MultiProcessor specification support
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * NOTES: Parts adapted from linux SMP code
+ * UPDATE HISTORY:
+ * 22/05/1998 DW Created
+ * 12/04/2001 CSH Added MultiProcessor specification support
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include <halirq.h>
+#include <mps.h>
+#include <apic.h>
+
+#include <internal/ntoskrnl.h>
+#include <internal/i386/segment.h>
+#include <internal/ke.h>
+#include <internal/ps.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/*
+ Address of area to be used for communication between Application
+ Processors (APs) and the BootStrap Processor (BSP)
+ */
+#define COMMON_AREA 0x2000
+
+#define BIOS_AREA 0x0
+
+typedef struct __attribute__((packed)) _COMMON_AREA_INFO
+{
+ ULONG Stack; /* Location of AP stack */
+ ULONG Debug[16]; /* For debugging */
+} COMMON_AREA_INFO, *PCOMMON_AREA_INFO;
+
+CPU_INFO CPUMap[MAX_CPU]; /* Map of all CPUs in the system */
+ULONG CPUCount; /* Total number of CPUs */
+ULONG OnlineCPUs; /* Bitmask of online CPUs */
+
+UCHAR BUSMap[MAX_BUS]; /* Map of all buses in the system */
+UCHAR PCIBUSMap[MAX_BUS]; /* Map of all PCI buses in the system */
+
+IOAPIC_INFO IOAPICMap[MAX_IOAPIC]; /* Map of all I/O APICs in the system */
+ULONG IOAPICCount; /* Number of I/O APICs in the system */
+
+MP_CONFIGURATION_INTSRC IRQMap[MAX_IRQ_SOURCE]; /* Map of all IRQs */
+ULONG IRQVectorMap[MAX_IRQ_SOURCE]; /* IRQ to vector map */
+ULONG IrqPinMap[MAX_IRQ_SOURCE]; /* IRQ to Pin map */
+ULONG IrqApicMap[MAX_IRQ_SOURCE];
+ULONG IRQCount; /* Number of IRQs */
+
+ULONG APICMode; /* APIC mode at startup */
+ULONG BootCPU; /* Bootstrap processor */
+PULONG BIOSBase; /* Virtual address of BIOS data segment */
+PULONG CommonBase; /* Virtual address of common area */
+
+extern CHAR *APstart, *APend;
+extern VOID (*APflush)(VOID);
+
+extern VOID MpsTimerInterrupt(VOID);
+extern VOID MpsErrorInterrupt(VOID);
+extern VOID MpsSpuriousInterrupt(VOID);
+extern VOID MpsIpiInterrupt(VOID);
+
+#define CMOS_READ(address) ({ \
+ WRITE_PORT_UCHAR((PUCHAR)0x70, address)); \
+ READ_PORT_UCHAR((PUCHAR)0x71)); \
+})
+
+#define CMOS_WRITE(address, value) ({ \
+ WRITE_PORT_UCHAR((PUCHAR)0x70, address); \
+ WRITE_PORT_UCHAR((PUCHAR)0x71, value); \
+})
+
+
+/* FUNCTIONS *****************************************************************/
+
+/* Functions for handling 8259A PICs */
+
+VOID Disable8259AIrq(ULONG irq)
+{
+ ULONG tmp;
+
+ if (irq >= 8)
+ {
+ tmp = READ_PORT_UCHAR((PUCHAR)0xA1);
+ tmp |= (1 << (irq - 8));
+ WRITE_PORT_UCHAR((PUCHAR)0xA1, tmp);
+ }
+ else
+ {
+ tmp = READ_PORT_UCHAR((PUCHAR)0x21);
+ tmp |= (1 << irq);
+ WRITE_PORT_UCHAR((PUCHAR)0x21, tmp);
+ }
+}
+
+
+VOID Enable8259AIrq(ULONG irq)
+{
+ ULONG tmp;
+
+ if (irq >= 8)
+ {
+ tmp = READ_PORT_UCHAR((PUCHAR)0xA1);
+ tmp &= ~(1 << (irq - 8));
+ WRITE_PORT_UCHAR((PUCHAR)0xA1, tmp);
+ }
+ else
+ {
+ tmp = READ_PORT_UCHAR((PUCHAR)0x21);
+ tmp &= ~(1 << irq);
+ WRITE_PORT_UCHAR((PUCHAR)0x21, tmp);
+ }
+}
+
+
+/* Functions for handling I/O APICs */
+
+volatile ULONG IOAPICRead(ULONG Apic, ULONG Offset)
+{
+ PULONG Base;
+
+ Base = (PULONG)IOAPICMap[Apic].ApicAddress;
+ *Base = Offset;
+ return *((PULONG)((ULONG)Base + IOAPIC_IOWIN));
+}
+
+VOID IOAPICWrite(ULONG Apic, ULONG Offset, ULONG Value)
+{
+ PULONG Base;
+
+ Base = (PULONG)IOAPICMap[Apic].ApicAddress;
+ *Base = Offset;
+ *((PULONG)((ULONG)Base + IOAPIC_IOWIN)) = Value;
+}
+
+
+VOID IOAPICClearPin(ULONG Apic, ULONG Pin)
+{
+ IOAPIC_ROUTE_ENTRY Entry;
+
+ DPRINT("IOAPICClearPin(Apic %d, Pin %d\n", Apic, Pin);
+ /*
+ * Disable it in the IO-APIC irq-routing table
+ */
+ memset(&Entry, 0, sizeof(Entry));
+ Entry.mask = 1;
+
+ IOAPICWrite(Apic, IOAPIC_REDTBL + 2 * Pin, *(((PULONG)&Entry) + 0));
+ IOAPICWrite(Apic, IOAPIC_REDTBL + 1 + 2 * Pin, *(((PULONG)&Entry) + 1));
+}
+
+static VOID IOAPICClear(ULONG Apic)
+{
+ ULONG Pin;
+
+ for (Pin = 0; Pin < /*IOAPICMap[Apic].EntryCount*/24; Pin++)
+ {
+ IOAPICClearPin(Apic, Pin);
+ }
+}
+
+static VOID IOAPICClearAll(VOID)
+{
+ ULONG Apic;
+
+ for (Apic = 0; Apic < IOAPICCount; Apic++)
+ {
+ IOAPICClear(Apic);
+ }
+}
+
+/* This is performance critical and should probably be done in assembler */
+VOID IOAPICMaskIrq(ULONG Irq)
+{
+ IOAPIC_ROUTE_ENTRY Entry;
+ ULONG Apic = IrqApicMap[Irq];
+
+
+ *((PULONG)&Entry) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq);
+ Entry.mask = 1;
+ IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq, *((PULONG)&Entry));
+}
+
+
+/* This is performance critical and should probably be done in assembler */
+VOID IOAPICUnmaskIrq(ULONG Irq)
+{
+ IOAPIC_ROUTE_ENTRY Entry;
+ ULONG Apic = IrqApicMap[Irq];
+
+ *((PULONG)&Entry) = IOAPICRead(Apic, IOAPIC_REDTBL+2*IrqPinMap[Irq]);
+ Entry.mask = 0;
+ IOAPICWrite(Apic, IOAPIC_REDTBL+2*IrqPinMap[Irq], *((PULONG)&Entry));
+}
+
+static VOID
+IOAPICSetupIds(VOID)
+{
+ ULONG tmp, apic, i;
+ UCHAR old_id;
+
+ /*
+ * Set the IOAPIC ID to the value stored in the MPC table.
+ */
+ for (apic = 0; apic < IOAPICCount; apic++)
+ {
+
+ /* Read the register 0 value */
+ tmp = IOAPICRead(apic, IOAPIC_ID);
+
+ old_id = IOAPICMap[apic].ApicId;
+
+ if (IOAPICMap[apic].ApicId >= 0xf)
+ {
+ DPRINT1("BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
+ apic, IOAPICMap[apic].ApicId);
+ DPRINT1("... fixing up to %d. (tell your hw vendor)\n",
+ GET_IOAPIC_ID(tmp));
+ IOAPICMap[apic].ApicId = GET_IOAPIC_ID(tmp);
+ }
+
+ /*
+ * We need to adjust the IRQ routing table
+ * if the ID changed.
+ */
+ if (old_id != IOAPICMap[apic].ApicId)
+ {
+ for (i = 0; i < IRQCount; i++)
+ {
+ if (IRQMap[i].DstApicId == old_id)
+ {
+ IRQMap[i].DstApicId = IOAPICMap[apic].ApicId;
+ }
+ }
+ }
+
+ /*
+ * Read the right value from the MPC table and
+ * write it into the ID register.
+ */
+ DPRINT("Changing IO-APIC physical APIC ID to %d\n",
+ IOAPICMap[apic].ApicId);
+
+ tmp &= ~IOAPIC_ID_MASK;
+ tmp |= SET_IOAPIC_ID(IOAPICMap[apic].ApicId);
+
+ IOAPICWrite(apic, IOAPIC_ID, tmp);
+
+ /*
+ * Sanity check
+ */
+ tmp = IOAPICRead(apic, 0);
+ if (GET_IOAPIC_ID(tmp) != IOAPICMap[apic].ApicId)
+ {
+ DPRINT1("Could not set I/O APIC ID!\n");
+ KEBUGCHECK(0);
+ }
+ }
+}
+
+
+/*
+ * EISA Edge/Level control register, ELCR
+ */
+static ULONG EISA_ELCR(ULONG irq)
+{
+ if (irq < 16)
+ {
+ PUCHAR port = (PUCHAR)(0x4d0 + (irq >> 3));
+ return (READ_PORT_UCHAR(port) >> (irq & 7)) & 1;
+ }
+ DPRINT("Broken MPtable reports ISA irq %d\n", irq);
+ return 0;
+}
+
+/* EISA interrupts are always polarity zero and can be edge or level
+ * trigger depending on the ELCR value. If an interrupt is listed as
+ * EISA conforming in the MP table, that means its trigger type must
+ * be read in from the ELCR */
+
+#define default_EISA_trigger(idx) (EISA_ELCR(IRQMap[idx].SrcBusIrq))
+#define default_EISA_polarity(idx) (0)
+
+/* ISA interrupts are always polarity zero edge triggered,
+ * when listed as conforming in the MP table. */
+
+#define default_ISA_trigger(idx) (0)
+#define default_ISA_polarity(idx) (0)
+
+/* PCI interrupts are always polarity one level triggered,
+ * when listed as conforming in the MP table. */
+
+#define default_PCI_trigger(idx) (1)
+#define default_PCI_polarity(idx) (1)
+
+/* MCA interrupts are always polarity zero level triggered,
+ * when listed as conforming in the MP table. */
+
+#define default_MCA_trigger(idx) (1)
+#define default_MCA_polarity(idx) (0)
+
+static ULONG IRQPolarity(ULONG idx)
+{
+ ULONG bus = IRQMap[idx].SrcBusId;
+ ULONG polarity;
+
+ /*
+ * Determine IRQ line polarity (high active or low active):
+ */
+ switch (IRQMap[idx].IrqFlag & 3)
+ {
+ case 0: /* conforms, ie. bus-type dependent polarity */
+ {
+ switch (BUSMap[bus])
+ {
+ case MP_BUS_ISA: /* ISA pin */
+ {
+ polarity = default_ISA_polarity(idx);
+ break;
+ }
+ case MP_BUS_EISA: /* EISA pin */
+ {
+ polarity = default_EISA_polarity(idx);
+ break;
+ }
+ case MP_BUS_PCI: /* PCI pin */
+ {
+ polarity = default_PCI_polarity(idx);
+ break;
+ }
+ case MP_BUS_MCA: /* MCA pin */
+ {
+ polarity = default_MCA_polarity(idx);
+ break;
+ }
+ default:
+ {
+ DPRINT("Broken BIOS!!\n");
+ polarity = 1;
+ break;
+ }
+ }
+ break;
+ }
+ case 1: /* high active */
+ {
+ polarity = 0;
+ break;
+ }
+ case 2: /* reserved */
+ {
+ DPRINT("Broken BIOS!!\n");
+ polarity = 1;
+ break;
+ }
+ case 3: /* low active */
+ {
+ polarity = 1;
+ break;
+ }
+ default: /* invalid */
+ {
+ DPRINT("Broken BIOS!!\n");
+ polarity = 1;
+ break;
+ }
+ }
+ return polarity;
+}
+
+static ULONG IRQTrigger(ULONG idx)
+{
+ ULONG bus = IRQMap[idx].SrcBusId;
+ ULONG trigger;
+
+ /*
+ * Determine IRQ trigger mode (edge or level sensitive):
+ */
+ switch ((IRQMap[idx].IrqFlag >> 2) & 3)
+ {
+ case 0: /* conforms, ie. bus-type dependent */
+ {
+ switch (BUSMap[bus])
+ {
+ case MP_BUS_ISA: /* ISA pin */
+ {
+ trigger = default_ISA_trigger(idx);
+ break;
+ }
+ case MP_BUS_EISA: /* EISA pin */
+ {
+ trigger = default_EISA_trigger(idx);
+ break;
+ }
+ case MP_BUS_PCI: /* PCI pin */
+ {
+ trigger = default_PCI_trigger(idx);
+ break;
+ }
+ case MP_BUS_MCA: /* MCA pin */
+ {
+ trigger = default_MCA_trigger(idx);
+ break;
+ }
+ default:
+ {
+ DPRINT("Broken BIOS!!\n");
+ trigger = 1;
+ break;
+ }
+ }
+ break;
+ }
+ case 1: /* edge */
+ {
+ trigger = 0;
+ break;
+ }
+ case 2: /* reserved */
+ {
+ DPRINT("Broken BIOS!!\n");
+ trigger = 1;
+ break;
+ }
+ case 3: /* level */
+ {
+ trigger = 1;
+ break;
+ }
+ default: /* invalid */
+ {
+ DPRINT("Broken BIOS!!\n");
+ trigger = 0;
+ break;
+ }
+ }
+ return trigger;
+}
+
+
+static ULONG Pin2Irq(ULONG idx,
+ ULONG apic,
+ ULONG pin)
+{
+ ULONG irq, i;
+ ULONG bus = IRQMap[idx].SrcBusId;
+
+ /*
+ * Debugging check, we are in big trouble if this message pops up!
+ */
+ if (IRQMap[idx].DstApicInt != pin) {
+ DPRINT("broken BIOS or MPTABLE parser, ayiee!!\n");
+ }
+
+ switch (BUSMap[bus])
+ {
+ case MP_BUS_ISA: /* ISA pin */
+ case MP_BUS_EISA:
+ case MP_BUS_MCA:
+ {
+ irq = IRQMap[idx].SrcBusIrq;
+ break;
+ }
+ case MP_BUS_PCI: /* PCI pin */
+ {
+ /*
+ * PCI IRQs are mapped in order
+ */
+ i = irq = 0;
+ while (i < apic)
+ irq += IOAPICMap[i++].EntryCount;
+ irq += pin;
+ break;
+ }
+ default:
+ {
+ DPRINT("Unknown bus type %d.\n",bus);
+ irq = 0;
+ break;
+ }
+ }
+
+ return irq;
+}
+
+
+/*
+ * Rough estimation of how many shared IRQs there are, can
+ * be changed anytime.
+ */
+#define MAX_PLUS_SHARED_IRQS PIC_IRQS
+#define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + PIC_IRQS)
+
+/*
+ * This is performance-critical, we want to do it O(1)
+ *
+ * the indexing order of this array favors 1:1 mappings
+ * between pins and IRQs.
+ */
+
+static struct irq_pin_list {
+ ULONG apic, pin, next;
+} irq_2_pin[PIN_MAP_SIZE];
+
+/*
+ * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
+ * shared ISA-space IRQs, so we have to support them. We are super
+ * fast in the common case, and fast for shared ISA-space IRQs.
+ */
+static VOID AddPinToIrq(ULONG irq,
+ ULONG apic,
+ ULONG pin)
+{
+ static ULONG first_free_entry = PIC_IRQS;
+ struct irq_pin_list *entry = irq_2_pin + irq;
+
+ while (entry->next)
+ {
+ entry = irq_2_pin + entry->next;
+ }
+
+ if (entry->pin != -1)
+ {
+ entry->next = first_free_entry;
+ entry = irq_2_pin + entry->next;
+ if (++first_free_entry >= PIN_MAP_SIZE)
+ {
+ DPRINT1("Ohh no!");
+ KEBUGCHECK(0);
+ }
+ }
+ entry->apic = apic;
+ entry->pin = pin;
+}
+
+
+/*
+ * Find the IRQ entry number of a certain pin.
+ */
+static ULONG IOAPICGetIrqEntry(ULONG apic,
+ ULONG pin,
+ ULONG type)
+{
+ ULONG i;
+
+ for (i = 0; i < IRQCount; i++)
+ {
+ if (IRQMap[i].IrqType == type &&
+ (IRQMap[i].DstApicId == IOAPICMap[apic].ApicId || IRQMap[i].DstApicId == MP_APIC_ALL) &&
+ IRQMap[i].DstApicInt == pin)
+ {
+ return i;
+ }
+ }
+ return -1;
+}
+
+
+static ULONG AssignIrqVector(ULONG irq)
+{
+#if 0
+ static ULONG current_vector = FIRST_DEVICE_VECTOR, vector_offset = 0;
+#endif
+ ULONG vector;
+ /* There may already have been assigned a vector for this IRQ */
+ vector = IRQVectorMap[irq];
+ if (vector > 0)
+ {
+ return vector;
+ }
+#if 0
+ if (current_vector > FIRST_SYSTEM_VECTOR) {
+ vector_offset++;
+ current_vector = FIRST_DEVICE_VECTOR + vector_offset;
+ } else if (current_vector == FIRST_SYSTEM_VECTOR) {
+ DPRINT1("Ran out of interrupt sources!");
+ KEBUGCHECK(0);
+ }
+
+ vector = current_vector;
+ IRQVectorMap[irq] = vector;
+ current_vector += 8;
+ return vector;
+#else
+ vector = IRQ2VECTOR(irq);
+ IRQVectorMap[irq] = vector;
+ return vector;
+#endif
+}
+
+
+VOID IOAPICSetupIrqs(VOID)
+{
+ IOAPIC_ROUTE_ENTRY entry;
+ ULONG apic, pin, idx, irq, first_notcon = 1, vector;
+
+ DPRINT("Init IO_APIC IRQs\n");
+
+ for (apic = 0; apic < IOAPICCount; apic++)
+ {
+ for (pin = 0; pin < IOAPICMap[apic].EntryCount; pin++)
+ {
+ /*
+ * add it to the IO-APIC irq-routing table
+ */
+ memset(&entry,0,sizeof(entry));
+
+ entry.delivery_mode = APIC_DM_LOWEST;
+ entry.dest_mode = 1; /* logical delivery */
+ entry.mask = 1; /* disable IRQ */
+#if 0
+ /*
+ * FIXME:
+ * Some drivers are not able to deal with more than one cpu.
+ */
+ entry.dest.logical.logical_dest = OnlineCPUs;
+#else
+ entry.dest.logical.logical_dest = 1 << 0;
+#endif
+ idx = IOAPICGetIrqEntry(apic,pin,INT_VECTORED);
+ if (idx == -1)
+ {
+ if (first_notcon)
+ {
+ DPRINT(" IO-APIC (apicid-pin) %d-%d\n", IOAPICMap[apic].ApicId, pin);
+ first_notcon = 0;
+ }
+ else
+ {
+ DPRINT(", %d-%d\n", IOAPICMap[apic].ApicId, pin);
+ }
+ continue;
+ }
+
+ entry.trigger = IRQTrigger(idx);
+ entry.polarity = IRQPolarity(idx);
+
+ if (entry.trigger)
+ {
+ entry.trigger = 1;
+ entry.mask = 1; // disable
+#if 0
+ entry.dest.logical.logical_dest = OnlineCPUs;
+#else
+ entry.dest.logical.logical_dest = 1 << 0;
+#endif
+ }
+
+ irq = Pin2Irq(idx, apic, pin);
+ AddPinToIrq(irq, apic, pin);
+
+ vector = AssignIrqVector(irq);
+ entry.vector = vector;
+
+ DPRINT("vector 0x%.08x assigned to irq 0x%.02x\n", vector, irq);
+
+ if (irq == 0)
+ {
+ /* Mask timer IRQ */
+ entry.mask = 1;
+ }
+
+ if ((apic == 0) && (irq < 16))
+ {
+ Disable8259AIrq(irq);
+ }
+ IOAPICWrite(apic, IOAPIC_REDTBL+2*pin+1, *(((PULONG)&entry)+1));
+ IOAPICWrite(apic, IOAPIC_REDTBL+2*pin, *(((PULONG)&entry)+0));
+
+ IrqPinMap[irq] = pin;
+ IrqApicMap[irq] = apic;
+
+ DPRINT("Vector %x, Pin %x, Irq %x\n", vector, pin, irq);
+ }
+ }
+}
+
+
+static VOID IOAPICEnable(VOID)
+{
+ ULONG i, tmp;
+
+ for (i = 0; i < PIN_MAP_SIZE; i++)
+ {
+ irq_2_pin[i].pin = -1;
+ irq_2_pin[i].next = 0;
+ }
+
+ /*
+ * The number of IO-APIC IRQ registers (== #pins):
+ */
+ for (i = 0; i < IOAPICCount; i++)
+ {
+ tmp = IOAPICRead(i, IOAPIC_VER);
+ IOAPICMap[i].EntryCount = GET_IOAPIC_MRE(tmp) + 1;
+ }
+
+ /*
+ * Do not trust the IO-APIC being empty at bootup
+ */
+ IOAPICClearAll();
+}
+
+#if 0
+static VOID IOAPICDisable(VOID)
+{
+ /*
+ * Clear the IO-APIC before rebooting
+ */
+ IOAPICClearAll();
+ APICDisable();
+}
+#endif
+
+
+static VOID IOAPICSetup(VOID)
+{
+ IOAPICEnable();
+ IOAPICSetupIds();
+ APICSyncArbIDs();
+ IOAPICSetupIrqs();
+}
+
+
+VOID IOAPICDump(VOID)
+{
+ ULONG apic, i;
+ ULONG reg0, reg1, reg2=0;
+
+ DbgPrint("Number of MP IRQ sources: %d.\n", IRQCount);
+ for (i = 0; i < IOAPICCount; i++)
+ {
+ DbgPrint("Number of IO-APIC #%d registers: %d.\n",
+ IOAPICMap[i].ApicId,
+ IOAPICMap[i].EntryCount);
+ }
+
+ /*
+ * We are a bit conservative about what we expect. We have to
+ * know about every hardware change ASAP.
+ */
+ DbgPrint("Testing the IO APIC.......................\n");
+
+ for (apic = 0; apic < IOAPICCount; apic++)
+ {
+ reg0 = IOAPICRead(apic, IOAPIC_ID);
+ reg1 = IOAPICRead(apic, IOAPIC_VER);
+ if (GET_IOAPIC_VERSION(reg1) >= 0x10)
+ {
+ reg2 = IOAPICRead(apic, IOAPIC_ARB);
+ }
+
+ DbgPrint("\n");
+ DbgPrint("IO APIC #%d......\n", IOAPICMap[apic].ApicId);
+ DbgPrint(".... register #00: %08X\n", reg0);
+ DbgPrint("....... : physical APIC id: %02X\n", GET_IOAPIC_ID(reg0));
+ if (reg0 & 0xF0FFFFFF)
+ {
+ DbgPrint(" WARNING: Unexpected IO-APIC\n");
+ }
+
+ DbgPrint(".... register #01: %08X\n", reg1);
+ i = GET_IOAPIC_MRE(reg1);
+
+ DbgPrint("....... : max redirection entries: %04X\n", i);
+ if ((i != 0x0f) && /* older (Neptune) boards */
+ (i != 0x17) && /* typical ISA+PCI boards */
+ (i != 0x1b) && /* Compaq Proliant boards */
+ (i != 0x1f) && /* dual Xeon boards */
+ (i != 0x22) && /* bigger Xeon boards */
+ (i != 0x2E) &&
+ (i != 0x3F))
+ {
+ DbgPrint(" WARNING: Unexpected IO-APIC\n");
+ }
+
+ i = GET_IOAPIC_VERSION(reg1);
+ DbgPrint("....... : IO APIC version: %04X\n", i);
+ if ((i != 0x01) && /* 82489DX IO-APICs */
+ (i != 0x10) && /* oldest IO-APICs */
+ (i != 0x11) && /* Pentium/Pro IO-APICs */
+ (i != 0x13)) /* Xeon IO-APICs */
+ {
+ DbgPrint(" WARNING: Unexpected IO-APIC\n");
+ }
+
+ if (reg1 & 0xFF00FF00)
+ {
+ DbgPrint(" WARNING: Unexpected IO-APIC\n");
+ }
+
+ if (GET_IOAPIC_VERSION(reg1) >= 0x10)
+ {
+ DbgPrint(".... register #02: %08X\n", reg2);
+ DbgPrint("....... : arbitration: %02X\n",
+ GET_IOAPIC_ARB(reg2));
+ if (reg2 & 0xF0FFFFFF)
+ {
+ DbgPrint(" WARNING: Unexpected IO-APIC\n");
+ }
+ }
+
+ DbgPrint(".... IRQ redirection table:\n");
+ DbgPrint(" NR Log Phy Mask Trig IRR Pol"
+ " Stat Dest Deli Vect: \n");
+
+ for (i = 0; i <= GET_IOAPIC_MRE(reg1); i++)
+ {
+ IOAPIC_ROUTE_ENTRY entry;
+
+ *(((PULONG)&entry)+0) = IOAPICRead(apic, 0x10+i*2);
+ *(((PULONG)&entry)+1) = IOAPICRead(apic, 0x11+i*2);
+
+ DbgPrint(" %02x %03X %02X ",
+ i,
+ entry.dest.logical.logical_dest,
+ entry.dest.physical.physical_dest);
+
+ DbgPrint("%C %C %1d %C %C %C %03X %02X\n",
+ (entry.mask == 0) ? 'U' : 'M', // Unmasked/masked
+ (entry.trigger == 0) ? 'E' : 'L', // Edge/level sensitive
+ entry.irr,
+ (entry.polarity == 0) ? 'H' : 'L', // Active high/active low
+ (entry.delivery_status == 0) ? 'I' : 'S', // Idle / send pending
+ (entry.dest_mode == 0) ? 'P' : 'L', // Physical logical
+ entry.delivery_mode,
+ entry.vector);
+ }
+ }
+ DbgPrint("IRQ to pin mappings:\n");
+ for (i = 0; i < PIC_IRQS; i++)
+ {
+ struct irq_pin_list *entry = irq_2_pin + i;
+ if (entry->pin < 0)
+ {
+ continue;
+ }
+ DbgPrint("IRQ%d ", i);
+ for (;;)
+ {
+ DbgPrint("-> %d", entry->pin);
+ if (!entry->next)
+ {
+ break;
+ }
+ entry = irq_2_pin + entry->next;
+ }
+ if (i % 2)
+ {
+ DbgPrint("\n");
+ }
+ else
+ {
+ DbgPrint(" ");
+ }
+ }
+
+ DbgPrint(".................................... done.\n");
+}
+
+
+
+/* Functions for handling local APICs */
+
+ULONG Read8254Timer(VOID)
+{
+ ULONG Count;
+
+ WRITE_PORT_UCHAR((PUCHAR)0x43, 0x00);
+ Count = READ_PORT_UCHAR((PUCHAR)0x40);
+ Count |= READ_PORT_UCHAR((PUCHAR)0x40) << 8;
+
+ return Count;
+}
+
+VOID WaitFor8254Wraparound(VOID)
+{
+ ULONG CurCount, PrevCount = ~0;
+ LONG Delta;
+
+ CurCount = Read8254Timer();
+ do
+ {
+ PrevCount = CurCount;
+ CurCount = Read8254Timer();
+ Delta = CurCount - PrevCount;
+
+ /*
+ * This limit for delta seems arbitrary, but it isn't, it's
+ * slightly above the level of error a buggy Mercury/Neptune
+ * chipset timer can cause.
+ */
+
+ }
+ while (Delta < 300);
+}
+
+#define HZ (100)
+#define APIC_DIVISOR (16)
+
+VOID APICSetupLVTT(ULONG ClockTicks)
+{
+ ULONG tmp;
+
+ tmp = GET_APIC_VERSION(APICRead(APIC_VER));
+ if (!APIC_INTEGRATED(tmp))
+ {
+ tmp = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) | APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;;
+ }
+ else
+ {
+ /* Periodic timer */
+ tmp = APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;;
+ }
+ APICWrite(APIC_LVTT, tmp);
+
+ tmp = APICRead(APIC_TDCR);
+ tmp &= ~(APIC_TDCR_1 | APIC_TIMER_BASE_DIV);
+ tmp |= APIC_TDCR_16;
+ APICWrite(APIC_TDCR, tmp);
+ APICWrite(APIC_ICRT, ClockTicks / APIC_DIVISOR);
+}
+
+
+VOID APICCalibrateTimer(ULONG CPU)
+{
+ ULARGE_INTEGER t1, t2;
+ LONG tt1, tt2;
+
+ DPRINT("Calibrating APIC timer for CPU %d\n", CPU);
+
+ APICSetupLVTT(1000000000);
+
+ /*
+ * The timer chip counts down to zero. Let's wait
+ * for a wraparound to start exact measurement:
+ * (the current tick might have been already half done)
+ */
+ WaitFor8254Wraparound();
+
+ /*
+ * We wrapped around just now. Let's start
+ */
+ ReadPentiumClock(&t1);
+ tt1 = APICRead(APIC_CCRT);
+
+ WaitFor8254Wraparound();
+
+
+ tt2 = APICRead(APIC_CCRT);
+ ReadPentiumClock(&t2);
+
+ CPUMap[CPU].BusSpeed = (HZ * (long)(tt1 - tt2) * APIC_DIVISOR);
+ CPUMap[CPU].CoreSpeed = (HZ * (t2.QuadPart - t1.QuadPart));
+
+ /* Setup timer for normal operation */
+// APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 100); // 100ns
+ APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 10000); // 10ms
+// APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 100000); // 100ms
+
+ DPRINT("CPU clock speed is %ld.%04ld MHz.\n",
+ CPUMap[CPU].CoreSpeed/1000000,
+ CPUMap[CPU].CoreSpeed%1000000);
+
+ DPRINT("Host bus clock speed is %ld.%04ld MHz.\n",
+ CPUMap[CPU].BusSpeed/1000000,
+ CPUMap[CPU].BusSpeed%1000000);
+}
+
+VOID
+SetInterruptGate(ULONG index, ULONG address)
+{
+ IDT_DESCRIPTOR *idt;
+
+ idt = (IDT_DESCRIPTOR*)((ULONG)KeGetCurrentKPCR()->IDT + index * sizeof(IDT_DESCRIPTOR));
+ idt->a = (((ULONG)address)&0xffff) + (KERNEL_CS << 16);
+ idt->b = 0x8e00 + (((ULONG)address)&0xffff0000);
+}
+
+VOID STDCALL
+HalInitializeProcessor(ULONG ProcessorNumber,
+ PVOID /*PLOADER_PARAMETER_BLOCK*/ LoaderBlock)
+{
+ ULONG CPU;
+
[truncated at 1000 lines; 811 more skipped]
reactos/hal/halx86/mp
diff -N resource_mp.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ resource_mp.c 3 Dec 2004 20:10:44 -0000 1.1
@@ -0,0 +1,38 @@
+/* $Id: resource_mp.c,v 1.1 2004/12/03 20:10:44 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/mp/resource_mp.c
+ * PURPOSE: Miscellaneous resource functions for MP
+ * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ****************************************************************/
+
+VOID
+HaliReconfigurePciInterrupts(VOID);
+
+
+VOID STDCALL
+HalReportResourceUsage(VOID)
+{
+ /*
+ * FIXME: Report all resources used by hal.
+ * Calls IoReportHalResourceUsage()
+ */
+
+ /* Initialize PCI bus. */
+ HalpInitPciBus ();
+
+ HaliReconfigurePciInterrupts();
+}
+
+/* EOF */
reactos/hal/halx86/up
diff -N .cvsignore
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ .cvsignore 3 Dec 2004 20:10:44 -0000 1.1
@@ -0,0 +1,7 @@
+*.d
+*.dll
+*.coff
+*.a
+*.o
+*.sym
+*.map
reactos/hal/halx86/up
diff -N Makefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Makefile 3 Dec 2004 20:10:45 -0000 1.1
@@ -0,0 +1,89 @@
+# $Id: Makefile,v 1.1 2004/12/03 20:10:45 gvg Exp $
+
+PATH_TO_TOP = ../../..
+
+VPATH = ../generic
+
+default: all
+
+#
+# Build configuration
+#
+include $(PATH_TO_TOP)/rules.mak
+
+#
+# Global configuration
+#
+include $(TOOLS_PATH)/config.mk
+
+TARGET_BOOTSTRAP = yes
+
+TARGET_TYPE = hal
+
+TARGET_DEFNAME = ../../hal/hal
+
+TARGET_ASFLAGS = -I$(PATH_TO_TOP)/include -I$(PATH_TO_TOP)/ntoskrnl/include -D__ASM__ -DUP
+
+TARGET_CFLAGS = -I../include -I$(PATH_TO_TOP)/ntoskrnl/include -Wall -Werror -DUP
+
+# require os code to explicitly request A/W version of structs/functions
+TARGET_CFLAGS += -D_DISABLE_TIDENTS
+
+TARGET_NAME = halup
+
+ifeq ($(MP), 1)
+TARGET_INSTALL = no
+else
+TARGET_BOOTSTRAP = yes
+endif
+
+GENERIC_OBJECTS = \
+ adapter.o \
+ beep.o \
+ bus.o \
+ display.o \
+ dma.o \
+ drive.o \
+ enum.o \
+ fmutex.o \
+ halinit.o \
+ ipi.o \
+ irql.o \
+ isa.o \
+ kdbg.o \
+ mca.o \
+ misc.o \
+ pci.o \
+ portio.o \
+ processor.o \
+ reboot.o \
+ resource.o \
+ spinlock.o \
+ sysbus.o \
+ sysinfo.o \
+ time.o \
+ timer.o
+
+UP_OBJECTS = \
+ halinit_up.o
+
+HAL_OBJECTS = $(GENERIC_OBJECTS) $(UP_OBJECTS)
+
+DEP_OBJECTS := $(HAL_OBJECTS)
+
+TARGET_OBJECTS := $(DEP_OBJECTS) $(PATH_TO_TOP)/include/roscfg.h
+
+# Note: Must be = and not := since $(DEP_FILES) is assigned a value below
+TARGET_CLEAN = $(DEP_FILES) *.o *.dll
+
+#
+# Helper makefile
+#
+include $(TOOLS_PATH)/helper.mk
+
+#
+# Include automatic dependancy tracking
+#
+include $(TOOLS_PATH)/depend.mk
+
+# EOF
reactos/hal/halx86/up
diff -N halinit_up.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ halinit_up.c 3 Dec 2004 20:10:45 -0000 1.1
@@ -0,0 +1,31 @@
+/* $Id: halinit_up.c,v 1.1 2004/12/03 20:10:45 gvg Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/halinit.c
+ * PURPOSE: Initalize the x86 hal
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ * 11/06/98: Created
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ***************************************************************/
+
+VOID
+HalpInitPhase0(VOID)
+{
+ HalpInitPICs();
+
+ /* Setup busy waiting */
+ HalpCalibrateStallExecution();
+}
+
+/* EOF */
reactos/hal/halx86/up
diff -N halup.rc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ halup.rc 3 Dec 2004 20:10:45 -0000 1.1
@@ -0,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION "X86 Uniprocessor Hardware Abstraction Layer\0"
+#define REACTOS_STR_INTERNAL_NAME "halup\0"
+#define REACTOS_STR_ORIGINAL_FILENAME "halup.dll\0"
+#include <reactos/version.rc>
reactos/include/ddk
diff -u -r1.48 -r1.49
--- kefuncs.h 11 Nov 2004 22:23:51 -0000 1.48
+++ kefuncs.h 3 Dec 2004 20:10:45 -0000 1.49
@@ -111,7 +111,7 @@
KIRQL STDCALL KeGetCurrentIrql (VOID);
#ifndef __USE_W32API
-ULONG KeGetCurrentProcessorNumber(VOID);
+#define KeGetCurrentProcessorNumber() (KeGetCurrentKPCR()->ProcessorNumber)
ULONG KeGetDcacheFillSize(VOID);
ULONG STDCALL KeGetPreviousMode (VOID);
#endif
reactos/tools
diff -u -r1.95 -r1.96
--- helper.mk 20 Nov 2004 17:48:38 -0000 1.95
+++ helper.mk 3 Dec 2004 20:10:45 -0000 1.96
@@ -1,4 +1,4 @@
-# $Id: helper.mk,v 1.95 2004/11/20 17:48:38 chorns Exp $
+# $Id: helper.mk,v 1.96 2004/12/03 20:10:45 gvg Exp $
#
# Helper makefile for ReactOS modules
# Variables this makefile accepts:
@@ -51,6 +51,7 @@
# $TARGET_BOOTSTRAP = Whether this file is needed to bootstrap the installation (no,yes) (optional)
# $TARGET_BOOTSTRAP_NAME = Name on the installation medium (optional)
# $TARGET_REGTESTS = This module has regression tests (no,yes) (optional)
+# $TARGET_INSTALL = Install the file (no,yes) (optional)
# $SUBDIRS = Subdirs in which to run make (optional)
include $(PATH_TO_TOP)/config
@@ -276,6 +277,8 @@
MK_BOOTCDDIR := .
MK_DISTDIR := dlls
MK_RES_BASE := $(TARGET_NAME)
+ MK_INSTALL_BASENAME := hal
+ MK_INSTALL_FULLNAME := hal.dll
endif
ifeq ($(TARGET_TYPE),bootpgm)
@@ -374,7 +377,6 @@
TARGET_OBJECTS := _rtstub.o _regtests.o $(TARGET_OBJECTS)
endif
-
# can be overidden with $(CXX) for linkage of c++ executables
LD_CC = $(CC)
@@ -689,6 +691,19 @@
MK_REGTESTS_CLEAN :=
endif
+ifeq ($(TARGET_INSTALL),)
+ MK_INSTALL := yes
+else
+ MK_INSTALL := $(TARGET_INSTALL)
+endif
+
+ifeq ($(MK_INSTALL_BASENAME),)
+ MK_INSTALL_BASENAME := $(MK_BASENAME)
+endif
+ifeq ($(MK_INSTALL_FULLNAME),)
+ MK_INSTALL_FULLNAME := $(MK_FULLNAME)
+endif
+
ifeq ($(MK_IMPLIBONLY),yes)
TARGET_CLEAN += $(MK_IMPLIBPATH)/$(MK_IMPLIB_FULLNAME)
@@ -963,6 +978,8 @@
# Don't install import libraries
+forceinstall:
+
install:
bootcd:
@@ -973,23 +990,35 @@
# Don't install static libraries
ifeq ($(MK_MODE),static)
+forceinstall:
+
install:
bootcd:
else # MK_MODE
+ifneq ($(MK_INSTALL),no)
+
+install: forceinstall
+
+else # MK_INSTALL
+
+install:
+
+endif # MK_INSTALL
+
ifeq ($(INSTALL_SYMBOLS),yes)
-install: $(SUBDIRS:%=%_install) $(MK_FULLNAME) $(MK_BASENAME).sym
- -$(CP) $(MK_FULLNAME) $(INSTALL_DIR)/$(MK_INSTALLDIR)/$(MK_FULLNAME)
- -$(CP) $(MK_BASENAME).sym $(INSTALL_DIR)/symbols/$(MK_BASENAME).sym
+forceinstall: $(SUBDIRS:%=%_install) $(MK_FULLNAME) $(MK_BASENAME).sym
+ -$(CP) $(MK_FULLNAME) $(INSTALL_DIR)/$(MK_INSTALLDIR)/$(MK_INSTALL_FULLNAME)
+ -$(CP) $(MK_BASENAME).sym $(INSTALL_DIR)/symbols/$(MK_INSTALL_BASENAME).sym
@echo $(MK_FULLNAME) was successfully installed.
else # INSTALL_SYMBOLS
-install: $(SUBDIRS:%=%_install) $(MK_FULLNAME)
- -$(CP) $(MK_FULLNAME) $(INSTALL_DIR)/$(MK_INSTALLDIR)/$(MK_FULLNAME)
+forceinstall: $(SUBDIRS:%=%_install) $(MK_FULLNAME)
+ -$(CP) $(MK_FULLNAME) $(INSTALL_DIR)/$(MK_INSTALLDIR)/$(MK_INSTALL_FULLNAME)
endif # INSTALL_SYMBOLS
reactos/tools
diff -u -r1.5 -r1.6
--- mkconfig.c 27 Sep 2004 04:32:52 -0000 1.5
+++ mkconfig.c 3 Dec 2004 20:10:45 -0000 1.6
@@ -102,11 +102,20 @@
include_tests = 0;
for (i = 2; i < argc; i++)
{
- if (strcmp(argv[i], "REGTESTS") == 0)
+ if (strcmp(argv[i], "REGTESTS") == 0)
{
include_tests = 1;
}
- s = s + sprintf(s, "#define %s\n", argv[i]);
+ if (strcmp(argv[i], "MP") == 0 || strcmp(argv[i], "UP") == 0)
+ {
+ s = s + sprintf(s, "#if ! defined(MP) && ! defined(UP)\n");
+ s = s + sprintf(s, "#define %s\n", argv[i]);
+ s = s + sprintf(s, "#endif /* ! defined(MP) && ! defined(UP) */\n");
+ }
+ else
+ {
+ s = s + sprintf(s, "#define %s\n", argv[i]);
+ }
strcat(config, argv[i]);
if (i != (argc - 1))
{
CVSspam 0.2.8