mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 19:26:32 +00:00
Hal stubs. Build halppc.
svn path=/branches/powerpc/; revision=25335
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
<directory name="generic">
|
||||
<xi:include href="generic/generic.rbuild" />
|
||||
</directory>
|
||||
<directory name="up">
|
||||
<xi:include href="up/halup.rbuild" />
|
||||
</directory>
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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 ([email protected])
|
||||
* UPDATE HISTORY:
|
||||
* Created 31/01/99
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
#define NDEBUG
|
||||
#include <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
|
||||
)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,529 @@
|
||||
/* $Id: bus.c 23907 2006-09-04 05:52:23Z arty $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/hal/x86/bus.c
|
||||
* PURPOSE: Bus functions
|
||||
* PROGRAMMER: David Welch ([email protected])
|
||||
* UPDATE HISTORY:
|
||||
* Created 22/05/98
|
||||
*
|
||||
*
|
||||
* TODO:
|
||||
* - Add bus handler functions for all busses
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
#define NDEBUG
|
||||
#include <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 */
|
||||
@@ -0,0 +1,796 @@
|
||||
/*
|
||||
* 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 23907 2006-09-04 05:52:23Z arty $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/hal/x86/display.c
|
||||
* PURPOSE: Blue screen display
|
||||
* PROGRAMMER: Eric Kohl ([email protected])
|
||||
* 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 <hal.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
#define SCREEN_SYNCHRONIZATION
|
||||
|
||||
#define VGA_GRAPH_MEM 0xa0000
|
||||
#define VGA_CHAR_MEM 0xb8000
|
||||
#define VGA_END_MEM 0xbffff
|
||||
|
||||
#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 (PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
/*
|
||||
* FUNCTION: Initalize the display
|
||||
* ARGUMENTS:
|
||||
* InitParameters = Parameters setup by the boot loader
|
||||
*/
|
||||
{
|
||||
PHYSICAL_ADDRESS PhysBuffer;
|
||||
|
||||
if (! DisplayInitialized)
|
||||
{
|
||||
ULONG ScanLines;
|
||||
ULONG Data;
|
||||
|
||||
PhysBuffer.u.HighPart = 0;
|
||||
PhysBuffer.u.LowPart = VGA_GRAPH_MEM;
|
||||
GraphVideoBuffer = MmMapIoSpace(PhysBuffer, VGA_END_MEM - VGA_GRAPH_MEM + 1, MmNonCached);
|
||||
if (NULL == GraphVideoBuffer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
VideoBuffer = (PUSHORT) (GraphVideoBuffer + (VGA_CHAR_MEM - VGA_GRAPH_MEM));
|
||||
|
||||
/* 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 || ! DisplayInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pch = String;
|
||||
|
||||
OldIrql = KfRaiseIrql(HIGH_LEVEL);
|
||||
KiAcquireSpinLock(&Lock);
|
||||
|
||||
Ki386SaveFlags(Flags);
|
||||
Ki386DisableInterrupts();
|
||||
|
||||
#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 */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,33 @@
|
||||
/* $Id: drive.c 23907 2006-09-04 05:52:23Z arty $
|
||||
*
|
||||
* 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 <hal.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID STDCALL
|
||||
IoAssignDriveLetters(IN struct _LOADER_PARAMETER_BLOCK *LoaderBlock,
|
||||
IN PSTRING NtDeviceName,
|
||||
OUT PUCHAR NtSystemPath,
|
||||
OUT PSTRING NtSystemPathString)
|
||||
{
|
||||
/* FIXME FIXME FIXME FUCK SOMEONE FIXME*/
|
||||
HalIoAssignDriveLetters(NULL,
|
||||
NtDeviceName,
|
||||
NtSystemPath,
|
||||
NtSystemPathString);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,23 @@
|
||||
/* $Id: enum.c 23907 2006-09-04 05:52:23Z arty $
|
||||
*
|
||||
* 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 ([email protected])
|
||||
* UPDATE HISTORY:
|
||||
* Created 01/05/2001
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
VOID
|
||||
HalpStartEnumerator (VOID)
|
||||
{
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS HAL
|
||||
* FILE: ntoskrnl/hal/x86/fmutex.c
|
||||
* PURPOSE: Deprecated HAL Fast Mutex
|
||||
* PROGRAMMERS: Alex Ionescu ([email protected])
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE: Even HAL itself has #defines to use the Exi* APIs inside NTOSKRNL.
|
||||
* These are only exported here for compatibility with really old
|
||||
* drivers. Also note that in theory, these can be made much faster
|
||||
* by using assembly and inlining all the operations, including
|
||||
* raising and lowering irql.
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#undef ExAcquireFastMutex
|
||||
#undef ExReleaseFastMutex
|
||||
#undef ExTryToAcquireFastMutex
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
ExAcquireFastMutex(PFAST_MUTEX FastMutex)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
|
||||
/* Raise IRQL to APC */
|
||||
OldIrql = KfRaiseIrql(APC_LEVEL);
|
||||
|
||||
/* Decrease the count */
|
||||
if (InterlockedDecrement(&FastMutex->Count))
|
||||
{
|
||||
/* Someone is still holding it, use slow path */
|
||||
FastMutex->Contention++;
|
||||
KeWaitForSingleObject(&FastMutex->Gate,
|
||||
WrExecutive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* Set the owner and IRQL */
|
||||
FastMutex->Owner = KeGetCurrentThread();
|
||||
FastMutex->OldIrql = OldIrql;
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
ExReleaseFastMutex(PFAST_MUTEX FastMutex)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
|
||||
/* Erase the owner */
|
||||
FastMutex->Owner = (PVOID)1;
|
||||
OldIrql = FastMutex->OldIrql;
|
||||
|
||||
/* Increase the count */
|
||||
if (InterlockedIncrement(&FastMutex->Count) <= 0)
|
||||
{
|
||||
/* Someone was waiting for it, signal the waiter */
|
||||
KeSetEventBoostPriority(&FastMutex->Gate, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
/* Lower IRQL back */
|
||||
KfLowerIrql(OldIrql);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
FASTCALL
|
||||
ExTryToAcquireFastMutex(PFAST_MUTEX FastMutex)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
|
||||
/* Raise to APC_LEVEL */
|
||||
OldIrql = KfRaiseIrql(APC_LEVEL);
|
||||
|
||||
/* Check if we can quickly acquire it */
|
||||
if (InterlockedCompareExchange(&FastMutex->Count, 0, 1) == 1)
|
||||
{
|
||||
/* We have, set us as owners */
|
||||
FastMutex->Owner = KeGetCurrentThread();
|
||||
FastMutex->OldIrql = OldIrql;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Acquire attempt failed */
|
||||
KfLowerIrql(OldIrql);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,26 @@
|
||||
<module name="halppc_generic" type="objectlibrary">
|
||||
<include base="hal_generic">../include</include>
|
||||
<include base="ntoskrnl">include</include>
|
||||
<define name="_DISABLE_TIDENTS" />
|
||||
<define name="__USE_W32API" />
|
||||
<define name="_NTHAL_" />
|
||||
<file>beep.c</file>
|
||||
<file>bus.c</file>
|
||||
<file>dma.c</file>
|
||||
<file>drive.c</file>
|
||||
<file>enum.c</file>
|
||||
<file>fmutex.c</file>
|
||||
<file>halinit.c</file>
|
||||
<file>isa.c</file>
|
||||
<file>kdbg.c</file>
|
||||
<file>mca.c</file>
|
||||
<file>misc.c</file>
|
||||
<file>pci.c</file>
|
||||
<file>portio.c</file>
|
||||
<file>reboot.c</file>
|
||||
<file>sysbus.c</file>
|
||||
<file>sysinfo.c</file>
|
||||
<file>time.c</file>
|
||||
<file>timer.c</file>
|
||||
<pch>../include/hal.h</pch>
|
||||
</module>
|
||||
@@ -0,0 +1,69 @@
|
||||
/* $Id: halinit.c 23907 2006-09-04 05:52:23Z arty $
|
||||
*
|
||||
* 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 ([email protected])
|
||||
* UPDATE HISTORY:
|
||||
* 11/06/98: Created
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* GLOBALS *****************************************************************/
|
||||
|
||||
PVOID HalpZeroPageMapping = NULL;
|
||||
HALP_HOOKS HalpHooks;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
RtlZeroMemory(&HalpHooks, sizeof(HALP_HOOKS));
|
||||
HalpInitPhase0((PROS_LOADER_PARAMETER_BLOCK)LoaderBlock);
|
||||
}
|
||||
else if (BootPhase == 1)
|
||||
{
|
||||
/* Initialize the clock interrupt */
|
||||
//HalpInitPhase1();
|
||||
|
||||
/* Initialize display and make the screen black */
|
||||
HalInitializeDisplay ((PROS_LOADER_PARAMETER_BLOCK)LoaderBlock);
|
||||
HalpInitBusHandlers();
|
||||
HalpInitDma();
|
||||
|
||||
/* Enumerate the devices on the motherboard */
|
||||
HalpStartEnumerator();
|
||||
}
|
||||
else if (BootPhase == 2)
|
||||
{
|
||||
PHYSICAL_ADDRESS Null = {{0}};
|
||||
|
||||
/* Go to blue screen */
|
||||
HalClearDisplay (0x17); /* grey on blue */
|
||||
|
||||
HalpZeroPageMapping = MmMapIoSpace(Null, PAGE_SIZE, MmNonCached);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,24 @@
|
||||
/* $Id: ipi.c 23907 2006-09-04 05:52:23Z arty $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: hal/halx86/generic/ipi.c
|
||||
* PURPOSE: Miscellaneous hardware functions
|
||||
* PROGRAMMER: Eric Kohl ([email protected])
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
VOID STDCALL
|
||||
HalRequestIpi(ULONG ProcessorNo)
|
||||
{
|
||||
DPRINT("HalRequestIpi(ProcessorNo %lu)\n", ProcessorNo);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,631 @@
|
||||
/*
|
||||
* FILE: hal/halx86/generic/irql.S
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PURPOSE: Software, System and Hardware IRQ Management
|
||||
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <asm.h>
|
||||
#include <internal/i386/asmmacro.S>
|
||||
.intel_syntax noprefix
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
PICInitTable:
|
||||
|
||||
/* Master PIC */
|
||||
.short 0x20 /* Port */
|
||||
.byte 0x11 /* Edge,, cascade, CAI 8, ICW4 */
|
||||
.byte PRIMARY_VECTOR_BASE /* Base */
|
||||
.byte 4 /* IRQ 4 connected to slave */
|
||||
.byte 1 /* Non buffered, not nested, 8086 */
|
||||
|
||||
/* Slave PIC */
|
||||
.short 0xA0 /* Port */
|
||||
.byte 0x11 /* Edge, cascade, CAI 8, ICW4 */
|
||||
.byte PRIMARY_VECTOR_BASE + 8 /* Base */
|
||||
.byte 2 /* Slave ID: Slave 2 */
|
||||
.byte 1 /* Non buffered, not nested, 8086 */
|
||||
|
||||
/* End of initialization table */
|
||||
.short 0
|
||||
|
||||
KiI8259MaskTable:
|
||||
.long 0 /* IRQL 0 */
|
||||
.long 0 /* IRQL 1 */
|
||||
.long 0 /* IRQL 2 */
|
||||
.long 0 /* IRQL 3 */
|
||||
.long 0xFF800000 /* IRQL 4 */
|
||||
.long 0xFFC00000 /* IRQL 5 */
|
||||
.long 0xFFE00000 /* IRQL 6 */
|
||||
.long 0xFFF00000 /* IRQL 7 */
|
||||
.long 0xFFF80000 /* IRQL 8 */
|
||||
.long 0xFFFC0000 /* IRQL 9 */
|
||||
.long 0xFFFE0000 /* IRQL 10 */
|
||||
.long 0xFFFF0000 /* IRQL 11 */
|
||||
.long 0xFFFF8000 /* IRQL 12 */
|
||||
.long 0xFFFFC000 /* IRQL 13 */
|
||||
.long 0xFFFFE000 /* IRQL 14 */
|
||||
.long 0xFFFFF000 /* IRQL 15 */
|
||||
.long 0xFFFFF800 /* IRQL 16 */
|
||||
.long 0xFFFFFC00 /* IRQL 17 */
|
||||
.long 0xFFFFFE00 /* IRQL 18 */
|
||||
.long 0xFFFFFE00 /* IRQL 19 */
|
||||
.long 0xFFFFFE80 /* IRQL 20 */
|
||||
.long 0xFFFFFEC0 /* IRQL 21 */
|
||||
.long 0xFFFFFEE0 /* IRQL 22 */
|
||||
.long 0xFFFFFEF0 /* IRQL 23 */
|
||||
.long 0xFFFFFEF8 /* IRQL 24 */
|
||||
.long 0xFFFFFEF8 /* IRQL 25 */
|
||||
.long 0xFFFFFEFA /* IRQL 26 */
|
||||
.long 0xFFFFFFFA /* IRQL 27 */
|
||||
.long 0xFFFFFFFB /* IRQL 28 */
|
||||
.long 0xFFFFFFFB /* IRQL 29 */
|
||||
.long 0xFFFFFFFB /* IRQL 30 */
|
||||
.long 0xFFFFFFFB /* IRQL 31 */
|
||||
|
||||
HalpSysIntHandler:
|
||||
.rept 8
|
||||
.long GenericIRQ /* IRQ 0-7 */
|
||||
.endr
|
||||
.long IRQ7 /* IRQ 7 */
|
||||
.rept 8
|
||||
.long GenericIRQ /* IRQ 8-15 */
|
||||
.endr
|
||||
.long IRQ15 /* IRQ 15 */
|
||||
.rept 20
|
||||
.long GenericIRQ /* IRQ 16-35 */
|
||||
.endr
|
||||
|
||||
SoftIntByteTable:
|
||||
.byte PASSIVE_LEVEL /* IRR 0 */
|
||||
.byte PASSIVE_LEVEL /* IRR 1 */
|
||||
.byte APC_LEVEL /* IRR 2 */
|
||||
.byte APC_LEVEL /* IRR 3 */
|
||||
.byte DISPATCH_LEVEL /* IRR 4 */
|
||||
.byte DISPATCH_LEVEL /* IRR 5 */
|
||||
.byte DISPATCH_LEVEL /* IRR 6 */
|
||||
.byte DISPATCH_LEVEL /* IRR 7 */
|
||||
|
||||
SoftIntHandlerTable:
|
||||
.long _KiUnexpectedInterrupt /* PASSIVE_LEVEL */
|
||||
.long _HalpApcInterrupt /* APC_LEVEL */
|
||||
.long _HalpDispatchInterrupt /* DISPATCH_LEVEL */
|
||||
|
||||
SoftIntHandlerTable2:
|
||||
.long _KiUnexpectedInterrupt /* PASSIVE_LEVEL */
|
||||
.long _HalpApcInterrupt2ndEntry /* APC_LEVEL */
|
||||
.long _HalpDispatchInterrupt2ndEntry /* DISPATCH_LEVEL */
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
.globl _HalpInitPICs@0
|
||||
.func HalpInitPICs@0
|
||||
_HalpInitPICs@0:
|
||||
|
||||
/* Save ESI and disable interrupts */
|
||||
push esi
|
||||
pushf
|
||||
cli
|
||||
|
||||
/* Read the init table */
|
||||
lea esi, PICInitTable
|
||||
lodsw
|
||||
|
||||
InitLoop:
|
||||
|
||||
/* Put the port in EDX */
|
||||
movzx edx, ax
|
||||
|
||||
/* Initialize the PIC, using a delay for each command */
|
||||
outsb
|
||||
jmp $+2
|
||||
inc edx
|
||||
outsb
|
||||
jmp $+2
|
||||
outsb
|
||||
jmp $+2
|
||||
outsb
|
||||
jmp $+2
|
||||
|
||||
/* Mask all interrupts */
|
||||
mov al, 0xFF
|
||||
out dx, al
|
||||
|
||||
/* Check if we're done, otherwise initialize next PIC */
|
||||
lodsw
|
||||
cmp ax, 0
|
||||
jnz InitLoop
|
||||
|
||||
/* Restore interrupts and return */
|
||||
or dword ptr [esp], EFLAGS_INTERRUPT_MASK
|
||||
popf
|
||||
pop esi
|
||||
ret
|
||||
.endfunc
|
||||
|
||||
.globl @HalRequestSoftwareInterrupt@4
|
||||
.func @HalRequestSoftwareInterrupt@4
|
||||
_@HalRequestSoftwareInterrupt@4:
|
||||
@HalRequestSoftwareInterrupt@4:
|
||||
|
||||
/* Get IRR mask */
|
||||
mov eax, 1
|
||||
shl eax, cl
|
||||
|
||||
/* Disable interrupts */
|
||||
pushf
|
||||
cli
|
||||
|
||||
/* Set IRR and get IRQL */
|
||||
or [fs:KPCR_IRR], eax
|
||||
mov cl, [fs:KPCR_IRQL]
|
||||
|
||||
/* Get software IRR mask */
|
||||
mov eax, [fs:KPCR_IRR]
|
||||
and eax, 3
|
||||
|
||||
/* Get highest pending software interrupt and check if it's higher */
|
||||
xor edx, edx
|
||||
mov dl, SoftIntByteTable[eax]
|
||||
cmp dl, cl
|
||||
jbe AfterCall
|
||||
|
||||
/* Call the pending interrupt */
|
||||
call SoftIntHandlerTable[edx*4]
|
||||
|
||||
AfterCall:
|
||||
|
||||
/* Retore interrupts and return */
|
||||
popf
|
||||
ret
|
||||
.endfunc
|
||||
|
||||
.globl _HalDisableSystemInterrupt@8
|
||||
.func HalDisableSystemInterrupt@8
|
||||
_HalDisableSystemInterrupt@8:
|
||||
|
||||
/* Convert to vector */
|
||||
movzx ecx, byte ptr [esp+4]
|
||||
sub ecx, PRIMARY_VECTOR_BASE
|
||||
|
||||
/* Disable interrupts and set the new IDR */
|
||||
mov edx, 1
|
||||
shl edx, cl
|
||||
cli
|
||||
or [fs:KPCR_IDR], edx
|
||||
|
||||
/* Get the current mask */
|
||||
xor eax, eax
|
||||
in al, 0xA1
|
||||
shl eax, 8
|
||||
in al, 0x21
|
||||
|
||||
/* Mask off the interrupt and write the new mask */
|
||||
or eax, edx
|
||||
out 0x21, al
|
||||
shr eax, 8
|
||||
out 0xA1, al
|
||||
|
||||
/* Return with interrupts enabled */
|
||||
in al, 0xA1
|
||||
sti
|
||||
ret 8
|
||||
.endfunc
|
||||
|
||||
.globl _HalEnableSystemInterrupt@12
|
||||
.func HalEnableSystemInterrupt@12
|
||||
_HalEnableSystemInterrupt@12:
|
||||
|
||||
/* Get the vector and validate it */
|
||||
movzx ecx, byte ptr [esp+4]
|
||||
sub ecx, PRIMARY_VECTOR_BASE
|
||||
jb Invalid
|
||||
cmp ecx, CLOCK2_LEVEL
|
||||
jnb Invalid
|
||||
|
||||
/* Get the current PCI Edge/Level control registers */
|
||||
mov edx, 0x4D1
|
||||
in al, dx
|
||||
shl ax, 8
|
||||
mov eax, 0x4D0
|
||||
in al, dx
|
||||
mov dx, 1
|
||||
shl dx, cl
|
||||
|
||||
/* Check if this is a latched interrupt */
|
||||
cmp dword ptr [esp+12], 0
|
||||
jnz Latched
|
||||
|
||||
/* Use OR for edge interrupt */
|
||||
or ax, dx
|
||||
jmp AfterMask
|
||||
Latched:
|
||||
|
||||
/* Mask it out for level interrupt */
|
||||
not dx
|
||||
and ax, dx
|
||||
|
||||
AfterMask:
|
||||
|
||||
/* Set the PCI Edge/Level control registers */
|
||||
mov edx, 0x4D0
|
||||
out dx, al
|
||||
shr ax, 8
|
||||
mov edx, 0x4D1
|
||||
out dx, al
|
||||
|
||||
/* Calculate the new IDR */
|
||||
mov eax, 1
|
||||
shl eax, cl
|
||||
not eax
|
||||
cli
|
||||
and [fs:KPCR_IDR], eax
|
||||
|
||||
/* Get the current IRQL and mask the IRQs in the PIC */
|
||||
movzx eax, byte ptr [fs:KPCR_IRQL]
|
||||
mov eax, KiI8259MaskTable[eax*4]
|
||||
or eax, [fs:KPCR_IDR]
|
||||
out 0x21, al
|
||||
shr eax, 8
|
||||
out 0xA1, al
|
||||
|
||||
/* Enable interrupts and return TRUE */
|
||||
sti
|
||||
mov eax, 1
|
||||
ret 12
|
||||
|
||||
Invalid:
|
||||
|
||||
/* Fail, invalid IRQ */
|
||||
xor eax, eax
|
||||
ret 12
|
||||
.endfunc
|
||||
|
||||
.globl _HalBeginSystemInterrupt@12
|
||||
.func HalBeginSystemInterrupt@12
|
||||
_HalBeginSystemInterrupt@12:
|
||||
|
||||
/* Convert to IRQ and call the handler */
|
||||
mov edx, [esp+8]
|
||||
sub edx, PRIMARY_VECTOR_BASE
|
||||
jmp HalpSysIntHandler[edx*4]
|
||||
|
||||
IRQ15:
|
||||
/* This is IRQ 15, check if it's spurious */
|
||||
mov al, 0xB
|
||||
out 0xA0, al
|
||||
in al, 0xA0
|
||||
test al, 0x80
|
||||
jnz GenericIRQ
|
||||
|
||||
/* Cascaded interrupt... dismiss it and return FALSE */
|
||||
mov al, 0x62
|
||||
out 0x20, al
|
||||
mov eax, 0
|
||||
ret 12
|
||||
|
||||
IRQ7:
|
||||
/* This is IRQ 7, check if it's spurious */
|
||||
mov al, 0xB
|
||||
out 0x20, al
|
||||
in al, 0x20
|
||||
test al, 0x80
|
||||
jnz GenericIRQ
|
||||
|
||||
/* It is, return FALSE */
|
||||
mov eax, 0
|
||||
ret 12
|
||||
|
||||
GenericIRQ:
|
||||
/* Return the current IRQL */
|
||||
mov eax, [esp+12]
|
||||
movzx ecx, byte ptr [fs:KPCR_IRQL]
|
||||
mov [eax], cl
|
||||
|
||||
/* Set the new IRQL */
|
||||
movzx eax, byte ptr [esp+4]
|
||||
mov [fs:KPCR_IRQL], al
|
||||
|
||||
/* Set IRQ mask in the PIC */
|
||||
mov eax, KiI8259MaskTable[eax*4]
|
||||
or eax, [fs:KPCR_IDR]
|
||||
out 0x21, al
|
||||
shr eax, 8
|
||||
out 0xA1, al
|
||||
|
||||
/* Check to which PIC the EOI was sent */
|
||||
mov eax, edx
|
||||
cmp eax, 8
|
||||
jnb Pic1
|
||||
|
||||
/* Write mask to master PIC */
|
||||
or al, 0x60
|
||||
out 0x20, al
|
||||
jmp DoneBegin
|
||||
|
||||
Pic1:
|
||||
/* Write mask to slave PIC */
|
||||
mov al, 0x20
|
||||
out 0xA0, al
|
||||
mov al, 0x62
|
||||
out 0x20, al
|
||||
|
||||
DoneBegin:
|
||||
/* Enable interrupts and return TRUE */
|
||||
in al, 0x21
|
||||
sti
|
||||
mov eax, 1
|
||||
ret 12
|
||||
.endfunc
|
||||
|
||||
.globl _HalEndSystemInterrupt@8
|
||||
.func HalEndSystemInterrupt@8
|
||||
_HalEndSystemInterrupt@8:
|
||||
|
||||
/* Get the IRQL and check if it's a software interrupt */
|
||||
movzx ecx, byte ptr [esp+4]
|
||||
cmp byte ptr [fs:KPCR_IRQL], DISPATCH_LEVEL
|
||||
jbe SkipMask2
|
||||
|
||||
/* Hardware interrupt, mask the appropriate IRQs in the PIC */
|
||||
mov eax, KiI8259MaskTable[ecx*4]
|
||||
or eax, [fs:KPCR_IDR]
|
||||
out 0x21, al
|
||||
shr eax, 8
|
||||
out 0xA1, al
|
||||
|
||||
SkipMask2:
|
||||
|
||||
/* Set IRQL and check if there are pending software interrupts */
|
||||
mov [fs:KPCR_IRQL], cl
|
||||
mov eax, [fs:KPCR_IRR]
|
||||
mov al, SoftIntByteTable[eax]
|
||||
cmp al, cl
|
||||
ja DoCall
|
||||
ret 8
|
||||
|
||||
DoCall:
|
||||
|
||||
/* There are pending software interrupts, call their handlers */
|
||||
add esp, 12
|
||||
jmp SoftIntHandlerTable2[eax*4]
|
||||
.endfunc
|
||||
|
||||
.globl @KfLowerIrql@4
|
||||
.func @KfLowerIrql@4
|
||||
_@KfLowerIrql@4:
|
||||
@KfLowerIrql@4:
|
||||
|
||||
/* Save flags since we'll disable interrupts */
|
||||
pushf
|
||||
|
||||
/* Disable interrupts and check if IRQL is below DISPATCH_LEVEL */
|
||||
movzx ecx, cl
|
||||
cmp byte ptr [fs:KPCR_IRQL], DISPATCH_LEVEL
|
||||
cli
|
||||
jbe SkipMask
|
||||
|
||||
/* Clear interrupt masks since there's a pending hardware interrupt */
|
||||
mov eax, KiI8259MaskTable[ecx*4]
|
||||
or eax, [fs:KPCR_IDR]
|
||||
out 0x21, al
|
||||
shr eax, 8
|
||||
out 0xA1, al
|
||||
|
||||
SkipMask:
|
||||
|
||||
/* Set the new IRQL and check if there's a pending software interrupt */
|
||||
mov [fs:KPCR_IRQL], cl
|
||||
mov eax, [fs:KPCR_IRR]
|
||||
mov al, SoftIntByteTable[eax]
|
||||
cmp al, cl
|
||||
jbe DoCall3
|
||||
|
||||
/* There is, call it */
|
||||
call SoftIntHandlerTable[eax*4]
|
||||
|
||||
DoCall3:
|
||||
|
||||
/* Restore interrupts and return */
|
||||
popf
|
||||
ret
|
||||
.endfunc
|
||||
|
||||
.globl @KfRaiseIrql@4
|
||||
.func @KfRaiseIrql@4
|
||||
_@KfRaiseIrql@4:
|
||||
@KfRaiseIrql@4:
|
||||
|
||||
/* Get the IRQL and check if it's Software level only */
|
||||
xor eax, eax
|
||||
mov al, [fs:KPCR_IRQL]
|
||||
movzx ecx, cl
|
||||
cmp cl, DISPATCH_LEVEL
|
||||
jbe SetIrql
|
||||
|
||||
/* Save the current IRQL */
|
||||
mov edx, eax
|
||||
|
||||
/* It's a hardware IRQL, so disable interrupts */
|
||||
pushf
|
||||
cli
|
||||
|
||||
/* Set the new IRQL */
|
||||
mov [fs:KPCR_IRQL], cl
|
||||
|
||||
/* Mask the interrupts in the PIC */
|
||||
mov eax, KiI8259MaskTable[ecx*4]
|
||||
or eax, [fs:KPCR_IDR]
|
||||
out 0x21, al
|
||||
shr eax, 8
|
||||
out 0xA1, al
|
||||
|
||||
/* Restore interrupts and return old IRQL */
|
||||
popf
|
||||
mov eax, edx
|
||||
ret
|
||||
|
||||
SetIrql:
|
||||
|
||||
/* Set the IRQL and return */
|
||||
mov [fs:KPCR_IRQL], cl
|
||||
ret
|
||||
.endfunc
|
||||
|
||||
.globl _KeGetCurrentIrql@0
|
||||
.func KeGetCurrentIrql@0
|
||||
_KeGetCurrentIrql@0:
|
||||
|
||||
/* Return the IRQL */
|
||||
movzx eax, word ptr [fs:KPCR_IRQL]
|
||||
ret
|
||||
.endfunc
|
||||
|
||||
.globl _KeRaiseIrqlToDpcLevel@0
|
||||
.func KeRaiseIrqlToDpcLevel@0
|
||||
_KeRaiseIrqlToDpcLevel@0:
|
||||
|
||||
/* Get the current IRQL */
|
||||
xor eax, eax
|
||||
mov al, [fs:KPCR_IRQL]
|
||||
|
||||
/* Set DISPATCH_LEVEL */
|
||||
mov byte ptr [fs:KPCR_IRQL], DISPATCH_LEVEL
|
||||
ret
|
||||
.endfunc
|
||||
|
||||
.globl _KeRaiseIrqlToSynchLevel@0
|
||||
.func KeRaiseIrqlToSynchLevel@0
|
||||
_KeRaiseIrqlToSynchLevel@0:
|
||||
|
||||
/* Disable interrupts */
|
||||
pushf
|
||||
cli
|
||||
|
||||
/* Mask out interrupts */
|
||||
mov eax, KiI8259MaskTable[DISPATCH_LEVEL*4]
|
||||
or eax, [fs:KPCR_IDR]
|
||||
out 0x21, al
|
||||
shr eax, 8
|
||||
out 0xA1, al
|
||||
|
||||
/* Return the old IRQL, enable interrupts and set to DISPATCH */
|
||||
mov al, [fs:KPCR_IRQL]
|
||||
mov byte ptr [fs:KPCR_IRQL], DISPATCH_LEVEL
|
||||
popf
|
||||
ret
|
||||
.endfunc
|
||||
|
||||
.globl _HalpApcInterrupt
|
||||
.func HalpApcInterrupt
|
||||
_HalpApcInterrupt:
|
||||
|
||||
/* Create fake interrupt stack */
|
||||
pop eax
|
||||
pushf
|
||||
push cs
|
||||
push eax
|
||||
|
||||
/* Enter interrupt */
|
||||
INT_PROLOG hapc, DoPushFakeErrorCode
|
||||
.endfunc
|
||||
|
||||
.globl _HalpApcInterrupt2ndEntry
|
||||
.func HalpApcInterrupt2ndEntry
|
||||
_HalpApcInterrupt2ndEntry:
|
||||
|
||||
/* Save current IRQL and set to APC level */
|
||||
push [fs:KPCR_IRQL]
|
||||
mov byte ptr [fs:KPCR_IRQL], APC_LEVEL
|
||||
and dword ptr [fs:KPCR_IRR], ~(1 << APC_LEVEL)
|
||||
|
||||
/* Enable interrupts and check if we came from User/V86 mode */
|
||||
sti
|
||||
mov eax, [ebp+KTRAP_FRAME_CS]
|
||||
and eax, MODE_MASK
|
||||
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
|
||||
jz DeliverApc
|
||||
|
||||
/* Set user mode delivery */
|
||||
or eax, UserMode
|
||||
|
||||
DeliverApc:
|
||||
|
||||
/* Deliver the APCs */
|
||||
push ebp
|
||||
push 0
|
||||
push eax
|
||||
call _KiDeliverApc@12
|
||||
|
||||
/* Disable interrupts and end it */
|
||||
cli
|
||||
call _HalpEndSoftwareInterrupt@4
|
||||
jmp _Kei386EoiHelper@0
|
||||
.endfunc
|
||||
|
||||
.globl _HalpDispatchInterrupt
|
||||
.func HalpDispatchInterrupt
|
||||
_HalpDispatchInterrupt:
|
||||
|
||||
/* Create fake interrupt stack */
|
||||
pop eax
|
||||
pushf
|
||||
push cs
|
||||
push eax
|
||||
|
||||
/* Enter interrupt */
|
||||
INT_PROLOG hapc, DoPushFakeErrorCode
|
||||
.endfunc
|
||||
|
||||
.globl _HalpDispatchInterrupt2ndEntry
|
||||
.func HalpDispatchInterrupt2ndEntry
|
||||
_HalpDispatchInterrupt2ndEntry:
|
||||
|
||||
/* Save current IRQL and set to DPC level */
|
||||
push [fs:KPCR_IRQL]
|
||||
mov byte ptr [fs:KPCR_IRQL], DISPATCH_LEVEL
|
||||
and dword ptr [fs:KPCR_IRR], ~(1 << DISPATCH_LEVEL)
|
||||
|
||||
/* Enable interrupts and let the kernel handle this */
|
||||
sti
|
||||
call _KiDispatchInterrupt@0
|
||||
|
||||
/* Disable interrupts and end it */
|
||||
cli
|
||||
call _HalpEndSoftwareInterrupt@4
|
||||
jmp _Kei386EoiHelper@0
|
||||
.endfunc
|
||||
|
||||
.globl _HalpEndSoftwareInterrupt@4
|
||||
.func HalpEndSoftwareInterrupt@4
|
||||
_HalpEndSoftwareInterrupt@4:
|
||||
|
||||
/* Get the IRQL and check if we're in the software region */
|
||||
movzx ecx, byte ptr [esp+4]
|
||||
cmp byte ptr [fs:KPCR_IRQL], DISPATCH_LEVEL
|
||||
jbe SoftwareInt
|
||||
|
||||
/* Set the right mask in the PIC for the hardware IRQ */
|
||||
mov eax, KiI8259MaskTable[ecx*4]
|
||||
or eax, [fs:KPCR_IDR]
|
||||
out 0x21, al
|
||||
shr eax, 8
|
||||
out 0xA1, al
|
||||
|
||||
SoftwareInt:
|
||||
/* Check if there are pending software interrupts */
|
||||
mov [fs:KPCR_IRQL], cl
|
||||
mov eax, [fs:KPCR_IRR]
|
||||
mov al, SoftIntByteTable[eax]
|
||||
cmp al, cl
|
||||
ja DoCall2
|
||||
ret 4
|
||||
|
||||
DoCall2:
|
||||
/* There are pending softwate interrupts, call their handlers */
|
||||
add esp, 8
|
||||
jmp SoftIntHandlerTable2[eax*4]
|
||||
.endfunc
|
||||
@@ -0,0 +1,425 @@
|
||||
/* $Id$
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/hal/x86/irql.c
|
||||
* PURPOSE: Implements IRQLs
|
||||
* PROGRAMMER: David Welch ([email protected])
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
#define NDEBUG
|
||||
#include <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 ****************************************************************/
|
||||
|
||||
#undef KeGetCurrentIrql
|
||||
KIRQL STDCALL KeGetCurrentIrql (VOID)
|
||||
/*
|
||||
* PURPOSE: Returns the current irq level
|
||||
* RETURNS: The current irq level
|
||||
*/
|
||||
{
|
||||
return(KeGetPcr()->Irql);
|
||||
}
|
||||
|
||||
VOID NTAPI 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)
|
||||
{
|
||||
KeGetPcr()->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);
|
||||
}
|
||||
KeGetPcr()->Irql--;
|
||||
HalpEndSystemInterrupt(KeGetPcr()->Irql);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
VOID STATIC
|
||||
HalpLowerIrql(KIRQL NewIrql)
|
||||
{
|
||||
if (NewIrql >= PROFILE_LEVEL)
|
||||
{
|
||||
KeGetPcr()->Irql = NewIrql;
|
||||
return;
|
||||
}
|
||||
HalpExecuteIrqs(NewIrql);
|
||||
if (NewIrql >= DISPATCH_LEVEL)
|
||||
{
|
||||
KeGetPcr()->Irql = NewIrql;
|
||||
return;
|
||||
}
|
||||
KeGetPcr()->Irql = DISPATCH_LEVEL;
|
||||
if (((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST])
|
||||
{
|
||||
((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST] = FALSE;
|
||||
KiDispatchInterrupt();
|
||||
}
|
||||
KeGetPcr()->Irql = APC_LEVEL;
|
||||
if (NewIrql == APC_LEVEL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (KeGetCurrentThread() != NULL &&
|
||||
KeGetCurrentThread()->ApcState.KernelApcPending)
|
||||
{
|
||||
KiDeliverApc(KernelMode, NULL, NULL);
|
||||
}
|
||||
KeGetPcr()->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 > KeGetPcr()->Irql)
|
||||
{
|
||||
DbgPrint ("(%s:%d) NewIrql %x CurrentIrql %x\n",
|
||||
__FILE__, __LINE__, NewIrql, KeGetPcr()->Irql);
|
||||
KEBUGCHECK(0);
|
||||
for(;;);
|
||||
}
|
||||
|
||||
HalpLowerIrql(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 < KeGetPcr()->Irql)
|
||||
{
|
||||
DbgPrint ("%s:%d CurrentIrql %x NewIrql %x\n",
|
||||
__FILE__,__LINE__,KeGetPcr()->Irql,NewIrql);
|
||||
KEBUGCHECK (0);
|
||||
for(;;);
|
||||
}
|
||||
|
||||
OldIrql = KeGetPcr()->Irql;
|
||||
KeGetPcr()->Irql = NewIrql;
|
||||
return OldIrql;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* 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 (KIRQL Irql,
|
||||
ULONG Vector,
|
||||
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 (KeGetPcr()->Irql >= Irql)
|
||||
{
|
||||
HalpPendingInterruptCount[irq]++;
|
||||
return(FALSE);
|
||||
}
|
||||
*OldIrql = KeGetPcr()->Irql;
|
||||
KeGetPcr()->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:
|
||||
((PKIPCR)KeGetPcr())->HalReserved[HAL_APC_REQUEST] = TRUE;
|
||||
break;
|
||||
|
||||
case DISPATCH_LEVEL:
|
||||
((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST] = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,75 @@
|
||||
/* $Id: isa.c 23907 2006-09-04 05:52:23Z arty $
|
||||
*
|
||||
* 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 ([email protected])
|
||||
* UPDATE HISTORY:
|
||||
* 05/06/98: Created
|
||||
*/
|
||||
|
||||
/* INCLUDES ***************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
BOOLEAN 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 */
|
||||
@@ -0,0 +1,547 @@
|
||||
/* $Id: kdbg.c 23907 2006-09-04 05:52:23Z arty $
|
||||
*
|
||||
* 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 <hal.h>
|
||||
#define NDEBUG
|
||||
#include <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 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;
|
||||
UCHAR mcr;
|
||||
UCHAR 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,
|
||||
ULONG Unknown1,
|
||||
ULONG Unknown2
|
||||
)
|
||||
{
|
||||
ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
|
||||
char buffer[80];
|
||||
ULONG divisor;
|
||||
UCHAR 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,
|
||||
ULONG Unknown1,
|
||||
ULONG Unknown2
|
||||
)
|
||||
{
|
||||
ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
|
||||
PUCHAR ComPortBase;
|
||||
char buffer[80];
|
||||
ULONG divisor;
|
||||
UCHAR 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 */
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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 23907 2006-09-04 05:52:23Z arty $
|
||||
*
|
||||
* 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 ([email protected])
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* What Adapter ID is read from an empty slot?
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
#define NDEBUG
|
||||
#include <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 */
|
||||
@@ -0,0 +1,72 @@
|
||||
/* $Id: misc.c 23907 2006-09-04 05:52:23Z arty $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/hal/x86/misc.c
|
||||
* PURPOSE: Miscellaneous hardware functions
|
||||
* PROGRAMMER: Eric Kohl ([email protected])
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
PVOID STDCALL
|
||||
HalAllocateCrashDumpRegisters(IN PADAPTER_OBJECT AdapterObject,
|
||||
IN OUT PULONG NumberOfMapRegisters)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
VOID STDCALL
|
||||
HalHandleNMI(PVOID NmiInfo)
|
||||
{
|
||||
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)
|
||||
{
|
||||
// XXX Learn to use PSL_POW for this.
|
||||
}
|
||||
|
||||
ULONG FASTCALL
|
||||
HalSystemVectorDispatchEntry (
|
||||
ULONG Unknown1,
|
||||
ULONG Unknown2,
|
||||
ULONG Unknown3
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
VOID STDCALL
|
||||
KeFlushWriteBuffer(VOID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,812 @@
|
||||
/* $Id: pci.c 23907 2006-09-04 05:52:23Z arty $
|
||||
*
|
||||
* 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 ([email protected])
|
||||
* Eric Kohl ([email protected])
|
||||
* 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 <hal.h>
|
||||
#define NDEBUG
|
||||
#include <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;
|
||||
SIZE_T Address;
|
||||
SIZE_T 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 = FIELD_OFFSET(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;
|
||||
if (NULL != HalpHooks.InitPciBus)
|
||||
{
|
||||
HalpHooks.InitPciBus(0, BusHandler);
|
||||
}
|
||||
|
||||
|
||||
/* 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;
|
||||
if (NULL != HalpHooks.InitPciBus)
|
||||
{
|
||||
HalpHooks.InitPciBus(1, BusHandler);
|
||||
}
|
||||
|
||||
|
||||
/* 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;
|
||||
if (NULL != HalpHooks.InitPciBus)
|
||||
{
|
||||
HalpHooks.InitPciBus(2, BusHandler);
|
||||
}
|
||||
|
||||
DPRINT("HalpInitPciBus() finished.\n");
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,289 @@
|
||||
/* $Id: portio.c 23907 2006-09-04 05:52:23Z arty $
|
||||
*
|
||||
* 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 ([email protected])
|
||||
* UPDATE HISTORY:
|
||||
* Created 18/10/99
|
||||
*/
|
||||
|
||||
#include <hal.h>
|
||||
#define NDEBUG
|
||||
#include <debug.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
|
||||
|
||||
extern int GetPhysByte(int Addr);
|
||||
extern void SetPhysByte(int Addr, int Val);
|
||||
extern int GetPhysWord(int Addr);
|
||||
extern void SetPhysWord(int Addr, int Val);
|
||||
extern int GetPhys(int Addr);
|
||||
extern void SetPhys(int Addr, int Val);
|
||||
|
||||
__asm__("\t.globl GetPhys\n"
|
||||
"GetPhys:\t\n"
|
||||
"mflr 0\n\t"
|
||||
"stwu 0,-16(1)\n\t"
|
||||
"mfmsr 5\n\t"
|
||||
"xori 3,3,4\n\t" /* Undo effects of LE without swapping */
|
||||
"andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
|
||||
"mtmsr 6\n\t"
|
||||
"isync\n\t"
|
||||
"sync\n\t"
|
||||
"lwz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
|
||||
"mtmsr 5\n\t"
|
||||
"isync\n\t"
|
||||
"sync\n\t"
|
||||
"lwz 0,0(1)\n\t"
|
||||
"addi 1,1,16\n\t"
|
||||
"mtlr 0\n\t"
|
||||
"blr"
|
||||
);
|
||||
|
||||
__asm__("\t.globl GetPhysWord\n"
|
||||
"GetPhysWord:\t\n"
|
||||
"mflr 0\n\t"
|
||||
"stwu 0,-16(1)\n\t"
|
||||
"mfmsr 5\n\t"
|
||||
"xori 3,3,6\n\t" /* Undo effects of LE without swapping */
|
||||
"andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
|
||||
"mtmsr 6\n\t"
|
||||
"isync\n\t"
|
||||
"sync\n\t"
|
||||
"lhz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
|
||||
"mtmsr 5\n\t"
|
||||
"isync\n\t"
|
||||
"sync\n\t"
|
||||
"lwz 0,0(1)\n\t"
|
||||
"addi 1,1,16\n\t"
|
||||
"mtlr 0\n\t"
|
||||
"blr"
|
||||
);
|
||||
|
||||
__asm__("\t.globl GetPhysByte\n"
|
||||
"GetPhysByte:\t\n"
|
||||
"mflr 0\n\t"
|
||||
"stwu 0,-16(1)\n\t"
|
||||
"mfmsr 5\n\t"
|
||||
"xori 3,3,7\n\t" /* Undo effects of LE without swapping */
|
||||
"andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
|
||||
"mtmsr 6\n\t"
|
||||
"isync\n\t"
|
||||
"sync\n\t"
|
||||
"lbz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
|
||||
"mtmsr 5\n\t"
|
||||
"isync\n\t"
|
||||
"sync\n\t"
|
||||
"lwz 0,0(1)\n\t"
|
||||
"addi 1,1,16\n\t"
|
||||
"mtlr 0\n\t"
|
||||
"blr"
|
||||
);
|
||||
|
||||
__asm__("\t.globl SetPhys\n"
|
||||
"SetPhys:\t\n"
|
||||
"mflr 0\n\t"
|
||||
"stwu 0,-16(1)\n\t"
|
||||
"mfmsr 5\n\t"
|
||||
"xori 3,3,4\n\t" /* Undo effects of LE without swapping */
|
||||
"andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
|
||||
"mtmsr 6\n\t"
|
||||
"sync\n\t"
|
||||
"eieio\n\t"
|
||||
"stw 4,0(3)\n\t" /* Set actual value at phys addr r3 */
|
||||
"dcbst 0,3\n\t"
|
||||
"mtmsr 5\n\t"
|
||||
"sync\n\t"
|
||||
"eieio\n\t"
|
||||
"mr 3,4\n\t"
|
||||
"lwz 0,0(1)\n\t"
|
||||
"addi 1,1,16\n\t"
|
||||
"mtlr 0\n\t"
|
||||
"blr"
|
||||
);
|
||||
|
||||
__asm__("\t.globl SetPhysWord\n"
|
||||
"SetPhysWord:\t\n"
|
||||
"mflr 0\n\t"
|
||||
"stwu 0,-16(1)\n\t"
|
||||
"mfmsr 5\n\t"
|
||||
"xori 3,3,6\n\t" /* Undo effects of LE without swapping */
|
||||
"andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
|
||||
"mtmsr 6\n\t"
|
||||
"sync\n\t"
|
||||
"eieio\n\t"
|
||||
"sth 4,0(3)\n\t" /* Set actual value at phys addr r3 */
|
||||
"dcbst 0,3\n\t"
|
||||
"mtmsr 5\n\t"
|
||||
"sync\n\t"
|
||||
"eieio\n\t"
|
||||
"mr 3,4\n\t"
|
||||
"lwz 0,0(1)\n\t"
|
||||
"addi 1,1,16\n\t"
|
||||
"mtlr 0\n\t"
|
||||
"blr"
|
||||
);
|
||||
|
||||
__asm__("\t.globl SetPhysByte\n"
|
||||
"SetPhysByte:\t\n"
|
||||
"mflr 0\n\t"
|
||||
"stwu 0,-16(1)\n\t"
|
||||
"mfmsr 5\n\t"
|
||||
"xori 3,3,7\n\t" /* Undo effects of LE without swapping */
|
||||
"andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
|
||||
"mtmsr 6\n\t"
|
||||
"sync\n\t"
|
||||
"eieio\n\t"
|
||||
"stb 4,0(3)\n\t" /* Set actual value at phys addr r3 */
|
||||
"dcbst 0,3\n\t"
|
||||
"mtmsr 5\n\t"
|
||||
"sync\n\t"
|
||||
"eieio\n\t"
|
||||
"mr 3,4\n\t"
|
||||
"lwz 0,0(1)\n\t"
|
||||
"addi 1,1,16\n\t"
|
||||
"mtlr 0\n\t"
|
||||
"blr"
|
||||
);
|
||||
|
||||
VOID STDCALL
|
||||
READ_PORT_BUFFER_UCHAR (PUCHAR Port,
|
||||
PUCHAR Buffer,
|
||||
ULONG Count)
|
||||
{
|
||||
while(Count--) { *Buffer++ = GetPhysByte((ULONG)Port); }
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
READ_PORT_BUFFER_USHORT (PUSHORT Port,
|
||||
PUSHORT Buffer,
|
||||
ULONG Count)
|
||||
{
|
||||
while(Count--) { *Buffer++ = GetPhysWord((ULONG)Port); }
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
READ_PORT_BUFFER_ULONG (PULONG Port,
|
||||
PULONG Buffer,
|
||||
ULONG Count)
|
||||
{
|
||||
while(Count--) { *Buffer++ = GetPhys((ULONG)Port); }
|
||||
}
|
||||
|
||||
UCHAR STDCALL
|
||||
READ_PORT_UCHAR (PUCHAR Port)
|
||||
{
|
||||
return GetPhys((ULONG)Port);
|
||||
}
|
||||
|
||||
USHORT STDCALL
|
||||
READ_PORT_USHORT (PUSHORT Port)
|
||||
{
|
||||
return GetPhysWord((ULONG)Port);
|
||||
}
|
||||
|
||||
ULONG STDCALL
|
||||
READ_PORT_ULONG (PULONG Port)
|
||||
{
|
||||
return GetPhys((ULONG)Port);
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
WRITE_PORT_BUFFER_UCHAR (PUCHAR Port,
|
||||
PUCHAR Buffer,
|
||||
ULONG Count)
|
||||
{
|
||||
while(Count--) { SetPhysByte((ULONG)Port, *Buffer++); }
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
WRITE_PORT_BUFFER_USHORT (PUSHORT Port,
|
||||
PUSHORT Buffer,
|
||||
ULONG Count)
|
||||
{
|
||||
while(Count--) { SetPhysWord((ULONG)Port, *Buffer++); }
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
WRITE_PORT_BUFFER_ULONG (PULONG Port,
|
||||
PULONG Buffer,
|
||||
ULONG Count)
|
||||
{
|
||||
while(Count--) { SetPhys((ULONG)Port, *Buffer++); }
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
WRITE_PORT_UCHAR (PUCHAR Port,
|
||||
UCHAR Value)
|
||||
{
|
||||
SetPhysByte((ULONG)Port, Value);
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
WRITE_PORT_USHORT (PUSHORT Port,
|
||||
USHORT Value)
|
||||
{
|
||||
SetPhysWord((ULONG)Port, Value);
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
WRITE_PORT_ULONG (PULONG Port,
|
||||
ULONG Value)
|
||||
{
|
||||
SetPhys((ULONG)Port, Value);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,50 @@
|
||||
/* $Id: processor.c 23907 2006-09-04 05:52:23Z arty $
|
||||
*
|
||||
* 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 ([email protected])
|
||||
* Casper S. Hornstrup ([email protected])
|
||||
* NOTES: Parts adapted from linux SMP code
|
||||
* UPDATE HISTORY:
|
||||
* 22/05/1998 DW Created
|
||||
* 12/04/2001 CSH Added MultiProcessor specification support
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID STDCALL
|
||||
HalInitializeProcessor(ULONG ProcessorNumber,
|
||||
PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
DPRINT("HalInitializeProcessor(%lu %p)\n", ProcessorNumber, LoaderBlock);
|
||||
/* Set default IDR */
|
||||
KeGetPcr()->IDR = 0xFFFFFFFB;
|
||||
KeGetPcr()->StallScaleFactor = INITIAL_STALL_COUNT;
|
||||
}
|
||||
|
||||
BOOLEAN STDCALL
|
||||
HalAllProcessorsStarted (VOID)
|
||||
{
|
||||
DPRINT("HalAllProcessorsStarted()\n");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN STDCALL
|
||||
HalStartNextProcessor(ULONG Unknown1,
|
||||
ULONG ProcessorStack)
|
||||
{
|
||||
DPRINT("HalStartNextProcessor(0x%lx 0x%lx)\n", Unknown1, ProcessorStack);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,121 @@
|
||||
/* $Id: pwroff.c 23907 2006-09-04 05:52:23Z arty $
|
||||
*
|
||||
* 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 */
|
||||
@@ -0,0 +1,41 @@
|
||||
/* $Id: reboot.c 23907 2006-09-04 05:52:23Z arty $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/hal/x86/reboot.c
|
||||
* PURPOSE: Reboot functions.
|
||||
* PROGRAMMER: Eric Kohl ([email protected])
|
||||
* UPDATE HISTORY:
|
||||
* Created 11/10/99
|
||||
*/
|
||||
|
||||
#include <hal.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
typedef void (*void_fun)();
|
||||
static VOID
|
||||
HalReboot (VOID)
|
||||
{
|
||||
void_fun reset_vector = (void_fun)0xfff00100;
|
||||
reset_vector();
|
||||
}
|
||||
|
||||
|
||||
VOID STDCALL
|
||||
HalReturnToFirmware (
|
||||
FIRMWARE_REENTRY Action
|
||||
)
|
||||
{
|
||||
if (Action == HalHaltRoutine)
|
||||
{
|
||||
DbgPrint ("HalReturnToFirmware called!\n");
|
||||
DbgBreakPoint ();
|
||||
}
|
||||
else if (Action == HalRebootRoutine)
|
||||
{
|
||||
HalReboot ();
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,31 @@
|
||||
/* $Id: resource.c 23907 2006-09-04 05:52:23Z arty $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: hal/halx86/generic/resource.c
|
||||
* PURPOSE: Miscellaneous resource functions
|
||||
* PROGRAMMER: Eric Kohl ([email protected])
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
VOID STDCALL
|
||||
HalReportResourceUsage(VOID)
|
||||
{
|
||||
/*
|
||||
* FIXME: Report all resources used by hal.
|
||||
* Calls IoReportHalResourceUsage()
|
||||
*/
|
||||
|
||||
/* Initialize PCI bus. */
|
||||
HalpInitPciBus ();
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/hal/halx86/up/spinlock.c
|
||||
* PURPOSE: Implements spinlocks
|
||||
* PROGRAMMER: Alex Ionescu ([email protected])
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#undef KeAcquireSpinLock
|
||||
#undef KeReleaseSpinLock
|
||||
#undef KeLowerIrql
|
||||
#undef KeRaiseIrql
|
||||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
KeLowerIrql(KIRQL NewIrql)
|
||||
{
|
||||
/* Call the fastcall function */
|
||||
KfLowerIrql(NewIrql);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
KeRaiseIrql(KIRQL NewIrql,
|
||||
PKIRQL OldIrql)
|
||||
{
|
||||
/* Call the fastcall function */
|
||||
*OldIrql = KfRaiseIrql(NewIrql);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
KeAcquireSpinLock(PKSPIN_LOCK SpinLock,
|
||||
PKIRQL OldIrql)
|
||||
{
|
||||
/* Call the fastcall function */
|
||||
*OldIrql = KfAcquireSpinLock(SpinLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
KIRQL
|
||||
FASTCALL
|
||||
KeAcquireSpinLockRaiseToSynch(PKSPIN_LOCK SpinLock)
|
||||
{
|
||||
/* Simply raise to dispatch */
|
||||
return KfRaiseIrql(DISPATCH_LEVEL);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
KeReleaseSpinLock(PKSPIN_LOCK SpinLock,
|
||||
KIRQL NewIrql)
|
||||
{
|
||||
/* Call the fastcall function */
|
||||
KfReleaseSpinLock(SpinLock, NewIrql);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
KIRQL
|
||||
FASTCALL
|
||||
KfAcquireSpinLock(PKSPIN_LOCK SpinLock)
|
||||
{
|
||||
/* Simply raise to dispatch */
|
||||
return KfRaiseIrql(DISPATCH_LEVEL);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
FASTCALL
|
||||
KfReleaseSpinLock(PKSPIN_LOCK SpinLock,
|
||||
KIRQL OldIrql)
|
||||
{
|
||||
/* Simply lower IRQL back */
|
||||
KfLowerIrql(OldIrql);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
KIRQL
|
||||
FASTCALL
|
||||
KeAcquireQueuedSpinLock(IN PKLOCK_QUEUE_HANDLE LockHandle)
|
||||
{
|
||||
/* Simply raise to dispatch */
|
||||
return KfRaiseIrql(DISPATCH_LEVEL);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
KIRQL
|
||||
FASTCALL
|
||||
KeAcquireQueuedSpinLockRaiseToSynch(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
|
||||
{
|
||||
/* Simply raise to dispatch */
|
||||
return KfRaiseIrql(DISPATCH_LEVEL);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
FASTCALL
|
||||
KeAcquireInStackQueuedSpinLock(IN PKSPIN_LOCK SpinLock,
|
||||
IN PKLOCK_QUEUE_HANDLE LockHandle)
|
||||
{
|
||||
/* Simply raise to dispatch */
|
||||
LockHandle->OldIrql = KfRaiseIrql(DISPATCH_LEVEL);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
FASTCALL
|
||||
KeReleaseQueuedSpinLock(IN PKLOCK_QUEUE_HANDLE LockHandle,
|
||||
IN KIRQL OldIrql)
|
||||
{
|
||||
/* Simply lower IRQL back */
|
||||
KfLowerIrql(OldIrql);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
FASTCALL
|
||||
KeReleaseInStackQueuedSpinLock(IN PKLOCK_QUEUE_HANDLE LockHandle)
|
||||
{
|
||||
/* Simply lower IRQL back */
|
||||
KfLowerIrql(LockHandle->OldIrql);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOLEAN
|
||||
FASTCALL
|
||||
KeTryToAcquireQueuedSpinLockRaiseToSynch(IN PKLOCK_QUEUE_HANDLE LockHandle,
|
||||
IN PKIRQL OldIrql)
|
||||
{
|
||||
/* Simply raise to dispatch */
|
||||
*OldIrql = KfRaiseIrql(DISPATCH_LEVEL);
|
||||
|
||||
/* Always return true on UP Machines */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOLEAN
|
||||
FASTCALL
|
||||
KeTryToAcquireQueuedSpinLock(IN PKLOCK_QUEUE_HANDLE LockHandle,
|
||||
IN PKIRQL OldIrql)
|
||||
{
|
||||
/* Simply raise to dispatch */
|
||||
*OldIrql = KfRaiseIrql(DISPATCH_LEVEL);
|
||||
|
||||
/* Always return true on UP Machines */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,66 @@
|
||||
/* $Id: sysbus.c 23907 2006-09-04 05:52:23Z arty $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/hal/sysbus.c
|
||||
* PURPOSE: System bus handler functions
|
||||
* PROGRAMMER: Eric Kohl ([email protected])
|
||||
* UPDATE HISTORY:
|
||||
* 09/04/2000 Created
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
#define NDEBUG
|
||||
#include <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 */
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/hal/x86/sysinfo.c
|
||||
* PURPOSE: Getting system information
|
||||
* PROGRAMMER: David Welch ([email protected])
|
||||
* UPDATE HISTORY:
|
||||
* Created 22/05/98
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
#define NDEBUG
|
||||
#include <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 */
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* FILE: hal/halx86/generic/timer.S
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PURPOSE: System Timer Interrupt and Management
|
||||
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <asm.h>
|
||||
#include <internal/i386/asmmacro.S>
|
||||
.intel_syntax noprefix
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
.globl _HalpClockInterrupt@0
|
||||
.func HalpClockInterrupt@0
|
||||
_HalpClockInterrupt@0:
|
||||
|
||||
/* Enter trap */
|
||||
INT_PROLOG Hci, DoPushFakeErrorCode
|
||||
|
||||
/* Push vector and make stack for IRQL */
|
||||
push 0x30
|
||||
sub esp, 4
|
||||
|
||||
/* Begin the interrupt */
|
||||
push esp
|
||||
push 0x30
|
||||
push CLOCK2_LEVEL
|
||||
call _HalBeginSystemInterrupt@12
|
||||
|
||||
/* Check if it's spurious */
|
||||
or al, al
|
||||
jz Spurious
|
||||
|
||||
/* Do a tick */
|
||||
mov eax, 100000
|
||||
jmp _KeUpdateSystemTime@0
|
||||
|
||||
Spurious:
|
||||
|
||||
/* Exit the interrupt */
|
||||
add esp, 8
|
||||
mov esi, $
|
||||
jmp _Kei386EoiHelper@0
|
||||
.endfunc
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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 <hal.h>
|
||||
#define NDEBUG
|
||||
#include <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 ******************************************************************/
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
BOOLEAN STDCALL
|
||||
HalQueryRealTimeClock(PTIME_FIELDS Time)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
VOID STDCALL
|
||||
HalSetRealTimeClock(PTIME_FIELDS Time)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN STDCALL
|
||||
HalGetEnvironmentVariable(PCH Name,
|
||||
USHORT ValueLength,
|
||||
PCH Value)
|
||||
{
|
||||
strncpy(Value, "TRUE", ValueLength);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN STDCALL
|
||||
HalSetEnvironmentVariable(PCH Name,
|
||||
PCH Value)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
ULONG STDCALL
|
||||
HalpGetCmosData(PBUS_HANDLER BusHandler,
|
||||
ULONG BusNumber,
|
||||
ULONG SlotNumber,
|
||||
PVOID Buffer,
|
||||
ULONG Offset,
|
||||
ULONG Length)
|
||||
{
|
||||
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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ULONG STDCALL
|
||||
HalpSetCmosData(PBUS_HANDLER BusHandler,
|
||||
ULONG BusNumber,
|
||||
ULONG SlotNumber,
|
||||
PVOID Buffer,
|
||||
ULONG Offset,
|
||||
ULONG Length)
|
||||
{
|
||||
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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 2000 David Welch <[email protected]>
|
||||
* Copyright (C) 1999 Gareth Owen <[email protected]>, 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 23907 2006-09-04 05:52:23Z arty $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/hal/x86/udelay.c
|
||||
* PURPOSE: Busy waiting
|
||||
* PROGRAMMER: David Welch ([email protected])
|
||||
* UPDATE HISTORY:
|
||||
* 06/11/99 Created
|
||||
*/
|
||||
|
||||
/* INCLUDES ***************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* GLOBALS ******************************************************************/
|
||||
|
||||
#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 **************************************************************/
|
||||
|
||||
static BOOLEAN PPCGetEEBit()
|
||||
{
|
||||
ULONG Msr;
|
||||
__asm__("mfmsr %0" : "=r" (Msr));
|
||||
return (Msr & 0x8000) != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
DECLSPEC_NOINLINE VOID STDCALL
|
||||
__KeStallExecutionProcessor(ULONG Loops)
|
||||
{
|
||||
ULONG DecInit, DecCount;
|
||||
if (!Loops)
|
||||
{
|
||||
return;
|
||||
}
|
||||
__asm__("mfdec %0" : "=r" (DecInit));
|
||||
do {
|
||||
__asm__("mfdec %0" : "=r" (DecCount));
|
||||
} while((DecCount - DecInit) < Loops);
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
KeStallExecutionProcessor(ULONG Microseconds)
|
||||
{
|
||||
PKIPCR Pcr = (PKIPCR)KeGetPcr();
|
||||
LARGE_INTEGER EndCount, CurrentCount;
|
||||
ULONG NewCount;
|
||||
__asm__("mfdec %0" : "=r" (NewCount));
|
||||
EndCount.QuadPart = NewCount + Microseconds * (ULONGLONG)Pcr->Prcb->MHz;
|
||||
do
|
||||
{
|
||||
__asm__("mfdec %0" : "=r" (NewCount));
|
||||
if(NewCount < CurrentCount.LowPart)
|
||||
CurrentCount.HighPart++;
|
||||
CurrentCount.LowPart = NewCount;
|
||||
}
|
||||
while (CurrentCount.QuadPart < EndCount.QuadPart);
|
||||
}
|
||||
|
||||
VOID HalpCalibrateStallExecution(VOID)
|
||||
{
|
||||
PKIPCR Pcr;
|
||||
|
||||
if (UdelayCalibrated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UdelayCalibrated = TRUE;
|
||||
Pcr = (PKIPCR)KeGetPcr();
|
||||
|
||||
// XXX arty FIXME
|
||||
/* Pcr->Prcb.MHz = (ULONG)(EndCount.QuadPart - StartCount.QuadPart) / 10000; */
|
||||
Pcr->Prcb->MHz = 300;
|
||||
DPRINT1("%luMHz\n", Pcr->Prcb->MHz);
|
||||
}
|
||||
|
||||
|
||||
VOID STDCALL
|
||||
HalCalibratePerformanceCounter(ULONG Count)
|
||||
{
|
||||
BOOLEAN InterruptsEnabled = PPCGetEEBit();
|
||||
|
||||
/* save flags and disable interrupts */
|
||||
_disable();
|
||||
|
||||
__KeStallExecutionProcessor(Count);
|
||||
|
||||
/* restore flags */
|
||||
if(InterruptsEnabled)
|
||||
_enable();
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
*/
|
||||
{
|
||||
PKIPCR Pcr;
|
||||
LARGE_INTEGER Value;
|
||||
BOOLEAN InterruptsEnabled = PPCGetEEBit();
|
||||
|
||||
_disable();
|
||||
|
||||
Pcr = (PKIPCR)KeGetPcr();
|
||||
|
||||
if (NULL != PerformanceFreq)
|
||||
{
|
||||
PerformanceFreq->QuadPart = Pcr->Prcb->MHz * (ULONGLONG)1000000;
|
||||
}
|
||||
__asm__("mfdec %0" : "=r" (Value.LowPart));
|
||||
|
||||
if(InterruptsEnabled)
|
||||
_enable();
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __INTERNAL_HAL_APIC_H
|
||||
#define __INTERNAL_HAL_APIC_H
|
||||
|
||||
#define APIC_DEFAULT_BASE 0xFEE00000 /* Default Local APIC Base Register Address */
|
||||
|
||||
/* APIC Register Address Map */
|
||||
#define APIC_ID 0x0020 /* Local APIC ID Register (R/W) */
|
||||
#define APIC_VER 0x0030 /* Local APIC Version Register (R) */
|
||||
#define APIC_TPR 0x0080 /* Task Priority Register (R/W) */
|
||||
#define APIC_APR 0x0090 /* Arbitration Priority Register (R) */
|
||||
#define APIC_PPR 0x00A0 /* Processor Priority Register (R) */
|
||||
#define APIC_EOI 0x00B0 /* EOI Register (W) */
|
||||
#define APIC_LDR 0x00D0 /* Logical Destination Register (R/W) */
|
||||
#define APIC_DFR 0x00E0 /* Destination Format Register (0-27 R, 28-31 R/W) */
|
||||
#define APIC_SIVR 0x00F0 /* Spurious Interrupt Vector Register (0-3 R, 4-9 R/W) */
|
||||
#define APIC_ISR 0x0100 /* Interrupt Service Register 0-255 (R) */
|
||||
#define APIC_TMR 0x0180 /* Trigger Mode Register 0-255 (R) */
|
||||
#define APIC_IRR 0x0200 /* Interrupt Request Register 0-255 (r) */
|
||||
#define APIC_ESR 0x0280 /* Error Status Register (R) */
|
||||
#define APIC_ICR0 0x0300 /* Interrupt Command Register 0-31 (R/W) */
|
||||
#define APIC_ICR1 0x0310 /* Interrupt Command Register 32-63 (R/W) */
|
||||
#define APIC_LVTT 0x0320 /* Local Vector Table (Timer) (R/W) */
|
||||
#define APIC_LVTTHMR 0x0330
|
||||
#define APIC_LVTPC 0x0340 /* Performance Counter LVT (R/W) */
|
||||
#define APIC_LINT0 0x0350 /* Local Vector Table (LINT0) (R/W) */
|
||||
#define APIC_LINT1 0x0360 /* Local Vector Table (LINT1) (R/W) */
|
||||
#define APIC_LVT3 0x0370 /* Local Vector Table (Error) (R/W) */
|
||||
#define APIC_ICRT 0x0380 /* Initial Count Register for Timer (R/W) */
|
||||
#define APIC_CCRT 0x0390 /* Current Count Register for Timer (R) */
|
||||
#define APIC_TDCR 0x03E0 /* Timer Divide Configuration Register (R/W) */
|
||||
|
||||
#define APIC_ID_MASK (0xF << 24)
|
||||
#define GET_APIC_ID(x) (((x) & APIC_ID_MASK) >> 24)
|
||||
#define GET_APIC_LOGICAL_ID(x) (((x)>>24)&0xFF)
|
||||
#define APIC_VER_MASK 0xFF00FF
|
||||
#define GET_APIC_VERSION(x) ((x) & 0xFF)
|
||||
#define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFF)
|
||||
|
||||
#define APIC_TPR_PRI 0xFF
|
||||
#define APIC_TPR_INT 0xF0
|
||||
#define APIC_TPR_SUB 0xF
|
||||
#define APIC_TPR_MAX 0xFF /* Maximum priority */
|
||||
#define APIC_TPR_MIN 0x20 /* Minimum priority */
|
||||
|
||||
#define APIC_LDR_MASK (0xFF << 24)
|
||||
|
||||
#define APIC_SIVR_ENABLE (0x1 << 8)
|
||||
#define APIC_SIVR_FOCUS (0x1 << 9)
|
||||
|
||||
#define APIC_ESR_MASK (0xFE << 0) /* Error Mask */
|
||||
|
||||
#define APIC_ICR0_VECTOR (0xFF << 0) /* Vector */
|
||||
#define APIC_ICR0_DM (0x7 << 8) /* Delivery Mode */
|
||||
#define APIC_ICR0_DESTM (0x1 << 11) /* Destination Mode */
|
||||
#define APIC_ICR0_DS (0x1 << 12) /* Delivery Status */
|
||||
#define APIC_ICR0_LEVEL (0x1 << 14) /* Level */
|
||||
#define APIC_ICR0_TM (0x1 << 15) /* Trigger Mode */
|
||||
#define APIC_ICR0_DESTS (0x3 << 18) /* Destination Shorthand */
|
||||
|
||||
/* Delivery Modes */
|
||||
#define APIC_DM_FIXED (0x0 << 8)
|
||||
#define APIC_DM_LOWEST (0x1 << 8)
|
||||
#define APIC_DM_SMI (0x2 << 8)
|
||||
#define APIC_DM_REMRD (0x3 << 8)
|
||||
#define APIC_DM_NMI (0x4 << 8)
|
||||
#define APIC_DM_INIT (0x5 << 8)
|
||||
#define APIC_DM_STARTUP (0x6 << 8)
|
||||
#define APIC_DM_EXTINT (0x7 << 8)
|
||||
#define GET_APIC_DELIVERY_MODE(x) (((x) >> 8) & 0x7)
|
||||
#define SET_APIC_DELIVERY_MODE(x,y) (((x) & ~0x700) | ((y) << 8))
|
||||
|
||||
/* Destination Shorthand values */
|
||||
#define APIC_ICR0_DESTS_FIELD (0x0 << 0)
|
||||
#define APIC_ICR0_DESTS_SELF (0x1 << 18)
|
||||
#define APIC_ICR0_DESTS_ALL (0x2 << 18)
|
||||
#define APIC_ICR0_DESTS_ALL_BUT_SELF (0x3 << 18)
|
||||
|
||||
#define APIC_ICR0_LEVEL_DEASSERT (0x0 << 14) /* Deassert level */
|
||||
#define APIC_ICR0_LEVEL_ASSERT (0x1 << 14) /* Assert level */
|
||||
|
||||
#define GET_APIC_DEST_FIELD(x) (((x) >> 24) & 0xFF)
|
||||
#define SET_APIC_DEST_FIELD(x) (((x) & 0xFF) << 24)
|
||||
|
||||
#define GET_APIC_TIMER_BASE(x) (((x) >> 18) & 0x3)
|
||||
#define SET_APIC_TIMER_BASE(x) ((x) << 18)
|
||||
#define APIC_TIMER_BASE_CLKIN 0x0
|
||||
#define APIC_TIMER_BASE_TMBASE 0x1
|
||||
#define APIC_TIMER_BASE_DIV 0x2
|
||||
|
||||
#define APIC_LVT_VECTOR (0xFF << 0) /* Vector */
|
||||
#define APIC_LVT_DS (0x1 << 12) /* Delivery Status */
|
||||
#define APIC_LVT_REMOTE_IRR (0x1 << 14) /* Remote IRR */
|
||||
#define APIC_LVT_LEVEL_TRIGGER (0x1 << 15) /* Lvel Triggered */
|
||||
#define APIC_LVT_MASKED (0x1 << 16) /* Mask */
|
||||
#define APIC_LVT_PERIODIC (0x1 << 17) /* Timer Mode */
|
||||
|
||||
#define APIC_LVT3_DM (0x7 << 8)
|
||||
#define APIC_LVT3_IIPP (0x1 << 13)
|
||||
#define APIC_LVT3_TM (0x1 << 15)
|
||||
#define APIC_LVT3_MASKED (0x1 << 16)
|
||||
#define APIC_LVT3_OS (0x1 << 17)
|
||||
|
||||
#define APIC_TDCR_TMBASE (0x1 << 2)
|
||||
#define APIC_TDCR_MASK 0x0F
|
||||
#define APIC_TDCR_2 0x00
|
||||
#define APIC_TDCR_4 0x01
|
||||
#define APIC_TDCR_8 0x02
|
||||
#define APIC_TDCR_16 0x03
|
||||
#define APIC_TDCR_32 0x08
|
||||
#define APIC_TDCR_64 0x09
|
||||
#define APIC_TDCR_128 0x0A
|
||||
#define APIC_TDCR_1 0x0B
|
||||
|
||||
#define APIC_LVT_VECTOR (0xFF << 0) /* Vector */
|
||||
#define APIC_LVT_DS (0x1 << 12) /* Delivery Status */
|
||||
#define APIC_LVT_REMOTE_IRR (0x1 << 14) /* Remote IRR */
|
||||
#define APIC_LVT_LEVEL_TRIGGER (0x1 << 15) /* Lvel Triggered */
|
||||
#define APIC_LVT_MASKED (0x1 << 16) /* Mask */
|
||||
#define APIC_LVT_PERIODIC (0x1 << 17) /* Timer Mode */
|
||||
|
||||
#define APIC_LVT3_DM (0x7 << 8)
|
||||
#define APIC_LVT3_IIPP (0x1 << 13)
|
||||
#define APIC_LVT3_TM (0x1 << 15)
|
||||
#define APIC_LVT3_MASKED (0x1 << 16)
|
||||
#define APIC_LVT3_OS (0x1 << 17)
|
||||
|
||||
#define APIC_TDCR_TMBASE (0x1 << 2)
|
||||
#define APIC_TDCR_MASK 0x0F
|
||||
#define APIC_TDCR_2 0x00
|
||||
#define APIC_TDCR_4 0x01
|
||||
#define APIC_TDCR_8 0x02
|
||||
#define APIC_TDCR_16 0x03
|
||||
#define APIC_TDCR_32 0x08
|
||||
#define APIC_TDCR_64 0x09
|
||||
#define APIC_TDCR_128 0x0A
|
||||
#define APIC_TDCR_1 0x0B
|
||||
|
||||
#define APIC_TARGET_SELF 0x100
|
||||
#define APIC_TARGET_ALL 0x200
|
||||
#define APIC_TARGET_ALL_BUT_SELF 0x300
|
||||
|
||||
#define APIC_INTEGRATED(version) (version & 0xF0)
|
||||
|
||||
typedef enum {
|
||||
amPIC = 0, /* IMCR and PIC compatibility mode */
|
||||
amVWIRE /* Virtual Wire compatibility mode */
|
||||
} APIC_MODE;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define MAX_CPU 32
|
||||
#else
|
||||
#define MAX_CPU 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local APIC timer IRQ vector is on a different priority level,
|
||||
* to work around the 'lost local interrupt if more than 2 IRQ
|
||||
* sources per level' errata.
|
||||
*/
|
||||
#define LOCAL_TIMER_VECTOR 0xEF
|
||||
|
||||
#define IPI_VECTOR 0xFB
|
||||
#define ERROR_VECTOR 0xFE
|
||||
#define SPURIOUS_VECTOR 0xFF /* Must be 0xXF */
|
||||
|
||||
/* CPU flags */
|
||||
#define CPU_USABLE 0x01 /* 1 if the CPU is usable (ie. can be used) */
|
||||
#define CPU_ENABLED 0x02 /* 1 if the CPU is enabled */
|
||||
#define CPU_BSP 0x04 /* 1 if the CPU is the bootstrap processor */
|
||||
#define CPU_TSC 0x08 /* 1 if the CPU has a time stamp counter */
|
||||
|
||||
typedef struct _CPU_INFO
|
||||
{
|
||||
UCHAR Flags; /* CPU flags */
|
||||
UCHAR APICId; /* Local APIC ID */
|
||||
UCHAR APICVersion; /* Local APIC version */
|
||||
// UCHAR MaxLVT; /* Number of LVT registers */
|
||||
ULONG BusSpeed; /* BUS speed */
|
||||
ULONG CoreSpeed; /* Core speed */
|
||||
UCHAR Padding[16-12]; /* Padding to 16-byte */
|
||||
} CPU_INFO, *PCPU_INFO;
|
||||
|
||||
extern ULONG CPUCount; /* Total number of CPUs */
|
||||
extern ULONG BootCPU; /* Bootstrap processor */
|
||||
extern ULONG OnlineCPUs; /* Bitmask of online CPUs */
|
||||
extern CPU_INFO CPUMap[MAX_CPU]; /* Map of all CPUs in the system */
|
||||
|
||||
/* Prototypes */
|
||||
|
||||
__inline VOID APICWrite(ULONG Offset, ULONG Value);
|
||||
__inline ULONG APICRead(ULONG Offset);
|
||||
VOID APICSendIPI(ULONG Target, ULONG Mode);
|
||||
VOID APICSetup(VOID);
|
||||
VOID HaliInitBSP(VOID);
|
||||
VOID APICSyncArbIDs(VOID);
|
||||
__inline VOID APICSendEOI(VOID);
|
||||
VOID APICCalibrateTimer(ULONG CPU);
|
||||
VOID HaliStartApplicationProcessor(ULONG Cpu, ULONG Stack);
|
||||
|
||||
static __inline ULONG ThisCPU(VOID)
|
||||
{
|
||||
return (APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* EOF */
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __INTERNAL_HAL_BUS_H
|
||||
#define __INTERNAL_HAL_BUS_H
|
||||
|
||||
|
||||
typedef NTSTATUS
|
||||
(STDCALL *pAdjustResourceList)(IN PBUS_HANDLER BusHandler,
|
||||
IN ULONG BusNumber,
|
||||
IN OUT PCM_RESOURCE_LIST Resources);
|
||||
|
||||
typedef NTSTATUS
|
||||
(STDCALL *pAssignSlotResources)(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);
|
||||
|
||||
typedef ULONG
|
||||
(STDCALL *pGetSetBusData)(IN PBUS_HANDLER BusHandler,
|
||||
IN ULONG BusNumber,
|
||||
IN ULONG SlotNumber,
|
||||
OUT PVOID Buffer,
|
||||
IN ULONG Offset,
|
||||
IN ULONG Length);
|
||||
|
||||
typedef ULONG
|
||||
(STDCALL *pGetInterruptVector)(IN PBUS_HANDLER BusHandler,
|
||||
IN ULONG BusNumber,
|
||||
IN ULONG BusInterruptLevel,
|
||||
IN ULONG BusInterruptVector,
|
||||
OUT PKIRQL Irql,
|
||||
OUT PKAFFINITY Affinity);
|
||||
|
||||
typedef ULONG
|
||||
(STDCALL *pTranslateBusAddress)(IN PBUS_HANDLER BusHandler,
|
||||
IN ULONG BusNumber,
|
||||
IN PHYSICAL_ADDRESS BusAddress,
|
||||
IN OUT PULONG AddressSpace,
|
||||
OUT PPHYSICAL_ADDRESS TranslatedAddress);
|
||||
|
||||
typedef struct _BUS_HANDLER
|
||||
{
|
||||
LIST_ENTRY Entry;
|
||||
INTERFACE_TYPE InterfaceType;
|
||||
BUS_DATA_TYPE BusDataType;
|
||||
ULONG BusNumber;
|
||||
ULONG RefCount;
|
||||
|
||||
pGetSetBusData GetBusData;
|
||||
pGetSetBusData SetBusData;
|
||||
pAdjustResourceList AdjustResourceList;
|
||||
pAssignSlotResources AssignSlotResources;
|
||||
pGetInterruptVector GetInterruptVector;
|
||||
pTranslateBusAddress TranslateBusAddress;
|
||||
} BUS_HANDLER;
|
||||
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/* bus.c */
|
||||
PBUS_HANDLER
|
||||
HalpAllocateBusHandler(INTERFACE_TYPE InterfaceType,
|
||||
BUS_DATA_TYPE BusDataType,
|
||||
ULONG BusNumber);
|
||||
|
||||
/* sysbus.h */
|
||||
ULONG STDCALL
|
||||
HalpGetSystemInterruptVector(PVOID BusHandler,
|
||||
ULONG BusNumber,
|
||||
ULONG BusInterruptLevel,
|
||||
ULONG BusInterruptVector,
|
||||
PKIRQL Irql,
|
||||
PKAFFINITY Affinity);
|
||||
|
||||
BOOLEAN STDCALL
|
||||
HalpTranslateSystemBusAddress(PBUS_HANDLER BusHandler,
|
||||
ULONG BusNumber,
|
||||
PHYSICAL_ADDRESS BusAddress,
|
||||
PULONG AddressSpace,
|
||||
PPHYSICAL_ADDRESS TranslatedAddress);
|
||||
|
||||
/* isa.c */
|
||||
ULONG STDCALL
|
||||
HalpGetIsaInterruptVector(PVOID BusHandler,
|
||||
ULONG BusNumber,
|
||||
ULONG BusInterruptLevel,
|
||||
ULONG BusInterruptVector,
|
||||
PKIRQL Irql,
|
||||
PKAFFINITY Affinity);
|
||||
|
||||
BOOLEAN STDCALL
|
||||
HalpTranslateIsaBusAddress(PBUS_HANDLER BusHandler,
|
||||
ULONG BusNumber,
|
||||
PHYSICAL_ADDRESS BusAddress,
|
||||
PULONG AddressSpace,
|
||||
PPHYSICAL_ADDRESS TranslatedAddress);
|
||||
|
||||
/* time.c */
|
||||
ULONG STDCALL
|
||||
HalpGetCmosData(PBUS_HANDLER BusHandler,
|
||||
ULONG BusNumber,
|
||||
ULONG SlotNumber,
|
||||
PVOID Buffer,
|
||||
ULONG Offset,
|
||||
ULONG Length);
|
||||
|
||||
ULONG STDCALL
|
||||
HalpSetCmosData(PBUS_HANDLER BusHandler,
|
||||
ULONG BusNumber,
|
||||
ULONG SlotNumber,
|
||||
PVOID Buffer,
|
||||
ULONG Offset,
|
||||
ULONG Length);
|
||||
|
||||
/* mca.h */
|
||||
ULONG STDCALL
|
||||
HalpGetMicroChannelData(PBUS_HANDLER BusHandler,
|
||||
ULONG BusNumber,
|
||||
ULONG SlotNumber,
|
||||
PVOID Buffer,
|
||||
ULONG Offset,
|
||||
ULONG Length);
|
||||
|
||||
#endif /* __INTERNAL_HAL_BUS_H */
|
||||
|
||||
/* EOF */
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Hardware Abstraction Layer
|
||||
* FILE: hal/halx86/include/hal.h
|
||||
* PURPOSE: HAL Header
|
||||
* PROGRAMMER: Alex Ionescu ([email protected])
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
/* C Headers */
|
||||
#include <stdio.h>
|
||||
|
||||
/* IFS/DDK/NDK Headers */
|
||||
#include <ntifs.h>
|
||||
#include <ntddk.h>
|
||||
#include <arc/arc.h>
|
||||
#include <iotypes.h>
|
||||
#include <kefuncs.h>
|
||||
#include <halfuncs.h>
|
||||
#include <rosldr.h>
|
||||
|
||||
#define KPCR_BASE 0xFF000000 // HACK!
|
||||
|
||||
/* Internal HAL Headers */
|
||||
#include "apic.h"
|
||||
#include "bus.h"
|
||||
#include "halirq.h"
|
||||
#include "haldma.h"
|
||||
#include "halp.h"
|
||||
#include "mps.h"
|
||||
#include "ioapic.h"
|
||||
|
||||
/* Helper Header */
|
||||
#include <reactos/helper.h>
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,383 @@
|
||||
#ifndef HALDMA_H
|
||||
#define HALDMA_H
|
||||
|
||||
/*
|
||||
* DMA Page Register Structure
|
||||
* 080 DMA RESERVED
|
||||
* 081 DMA Page Register (channel 2)
|
||||
* 082 DMA Page Register (channel 3)
|
||||
* 083 DMA Page Register (channel 1)
|
||||
* 084 DMA RESERVED
|
||||
* 085 DMA RESERVED
|
||||
* 086 DMA RESERVED
|
||||
* 087 DMA Page Register (channel 0)
|
||||
* 088 DMA RESERVED
|
||||
* 089 PS/2-DMA Page Register (channel 6)
|
||||
* 08A PS/2-DMA Page Register (channel 7)
|
||||
* 08B PS/2-DMA Page Register (channel 5)
|
||||
* 08C PS/2-DMA RESERVED
|
||||
* 08D PS/2-DMA RESERVED
|
||||
* 08E PS/2-DMA RESERVED
|
||||
* 08F PS/2-DMA Page Register (channel 4)
|
||||
*/
|
||||
|
||||
typedef struct _DMA_PAGE
|
||||
{
|
||||
UCHAR Reserved1;
|
||||
UCHAR Channel2;
|
||||
UCHAR Channel3;
|
||||
UCHAR Channel1;
|
||||
UCHAR Reserved2[3];
|
||||
UCHAR Channel0;
|
||||
UCHAR Reserved3;
|
||||
UCHAR Channel6;
|
||||
UCHAR Channel7;
|
||||
UCHAR Channel5;
|
||||
UCHAR Reserved4[3];
|
||||
UCHAR Channel4;
|
||||
} DMA_PAGE, *PDMA_PAGE;
|
||||
|
||||
/*
|
||||
* DMA Channel Mask Register Structure
|
||||
*
|
||||
* MSB LSB
|
||||
* x x x x x x x x
|
||||
* ------------------- - -----
|
||||
* | | | 00 - Select channel 0 mask bit
|
||||
* | | \---- 01 - Select channel 1 mask bit
|
||||
* | | 10 - Select channel 2 mask bit
|
||||
* | | 11 - Select channel 3 mask bit
|
||||
* | |
|
||||
* | \---------- 0 - Clear mask bit
|
||||
* | 1 - Set mask bit
|
||||
* |
|
||||
* \----------------------- xx - Reserved
|
||||
*/
|
||||
|
||||
typedef struct _DMA_CHANNEL_MASK
|
||||
{
|
||||
UCHAR Channel: 2;
|
||||
UCHAR SetMask: 1;
|
||||
UCHAR Reserved: 5;
|
||||
} DMA_CHANNEL_MASK, *PDMA_CHANNEL_MASK;
|
||||
|
||||
/*
|
||||
* DMA Mask Register Structure
|
||||
*
|
||||
* MSB LSB
|
||||
* x x x x x x x x
|
||||
* \---/ - - ----- -----
|
||||
* | | | | | 00 - Channel 0 select
|
||||
* | | | | \---- 01 - Channel 1 select
|
||||
* | | | | 10 - Channel 2 select
|
||||
* | | | | 11 - Channel 3 select
|
||||
* | | | |
|
||||
* | | | | 00 - Verify transfer
|
||||
* | | | \------------ 01 - Write transfer
|
||||
* | | | 10 - Read transfer
|
||||
* | | |
|
||||
* | | \-------------------- 0 - Autoinitialized
|
||||
* | | 1 - Non-autoinitialized
|
||||
* | |
|
||||
* | \------------------------ 0 - Address increment select
|
||||
* |
|
||||
* | 00 - Demand mode
|
||||
* \------------------------------ 01 - Single mode
|
||||
* 10 - Block mode
|
||||
* 11 - Cascade mode
|
||||
*/
|
||||
|
||||
typedef union _DMA_MODE
|
||||
{
|
||||
struct
|
||||
{
|
||||
UCHAR Channel: 2;
|
||||
UCHAR TransferType: 2;
|
||||
UCHAR AutoInitialize: 1;
|
||||
UCHAR AddressDecrement: 1;
|
||||
UCHAR RequestMode: 2;
|
||||
};
|
||||
UCHAR Byte;
|
||||
} DMA_MODE, *PDMA_MODE;
|
||||
|
||||
/*
|
||||
* DMA Extended Mode Register Structure
|
||||
*
|
||||
* MSB LSB
|
||||
* x x x x x x x x
|
||||
* - - ----- ----- -----
|
||||
* | | | | | 00 - Channel 0 select
|
||||
* | | | | \---- 01 - Channel 1 select
|
||||
* | | | | 10 - Channel 2 select
|
||||
* | | | | 11 - Channel 3 select
|
||||
* | | | |
|
||||
* | | | | 00 - 8-bit I/O, by bytes
|
||||
* | | | \------------ 01 - 16-bit I/O, by words, address shifted
|
||||
* | | | 10 - 32-bit I/O, by bytes
|
||||
* | | | 11 - 16-bit I/O, by bytes
|
||||
* | | |
|
||||
* | | \---------------------- 00 - Compatible
|
||||
* | | 01 - Type A
|
||||
* | | 10 - Type B
|
||||
* | | 11 - Burst
|
||||
* | |
|
||||
* | \---------------------------- 0 - Terminal Count is Output
|
||||
* |
|
||||
* \---------------------------------0 - Disable Stop Register
|
||||
* 1 - Enable Stop Register
|
||||
*/
|
||||
|
||||
typedef union _DMA_EXTENDED_MODE
|
||||
{
|
||||
struct
|
||||
{
|
||||
UCHAR ChannelNumber: 2;
|
||||
UCHAR TransferSize: 2;
|
||||
UCHAR TimingMode: 2;
|
||||
UCHAR TerminalCountIsOutput: 1;
|
||||
UCHAR EnableStopRegister: 1;
|
||||
};
|
||||
UCHAR Byte;
|
||||
} DMA_EXTENDED_MODE, *PDMA_EXTENDED_MODE;
|
||||
|
||||
/* DMA Extended Mode Register Transfer Sizes */
|
||||
#define B_8BITS 0
|
||||
#define W_16BITS 1
|
||||
#define B_32BITS 2
|
||||
#define B_16BITS 3
|
||||
|
||||
/* DMA Extended Mode Register Timing */
|
||||
#define COMPATIBLE_TIMING 0
|
||||
#define TYPE_A_TIMING 1
|
||||
#define TYPE_B_TIMING 2
|
||||
#define BURST_TIMING 3
|
||||
|
||||
/* Channel Stop Registers for each Channel */
|
||||
typedef struct _DMA_CHANNEL_STOP
|
||||
{
|
||||
UCHAR ChannelLow;
|
||||
UCHAR ChannelMid;
|
||||
UCHAR ChannelHigh;
|
||||
UCHAR Reserved;
|
||||
} DMA_CHANNEL_STOP, *PDMA_CHANNEL_STOP;
|
||||
|
||||
/* Transfer Types */
|
||||
#define VERIFY_TRANSFER 0x00
|
||||
#define READ_TRANSFER 0x01
|
||||
#define WRITE_TRANSFER 0x02
|
||||
|
||||
/* Request Modes */
|
||||
#define DEMAND_REQUEST_MODE 0x00
|
||||
#define SINGLE_REQUEST_MODE 0x01
|
||||
#define BLOCK_REQUEST_MODE 0x02
|
||||
#define CASCADE_REQUEST_MODE 0x03
|
||||
|
||||
#define DMA_SETMASK 4
|
||||
#define DMA_CLEARMASK 0
|
||||
#define DMA_READ 4
|
||||
#define DMA_WRITE 8
|
||||
#define DMA_SINGLE_TRANSFER 0x40
|
||||
#define DMA_AUTO_INIT 0x10
|
||||
|
||||
typedef struct _DMA1_ADDRESS_COUNT
|
||||
{
|
||||
UCHAR DmaBaseAddress;
|
||||
UCHAR DmaBaseCount;
|
||||
} DMA1_ADDRESS_COUNT, *PDMA1_ADDRESS_COUNT;
|
||||
|
||||
typedef struct _DMA2_ADDRESS_COUNT
|
||||
{
|
||||
UCHAR DmaBaseAddress;
|
||||
UCHAR Reserved1;
|
||||
UCHAR DmaBaseCount;
|
||||
UCHAR Reserved2;
|
||||
} DMA2_ADDRESS_COUNT, *PDMA2_ADDRESS_COUNT;
|
||||
|
||||
typedef struct _DMA1_CONTROL
|
||||
{
|
||||
DMA1_ADDRESS_COUNT DmaAddressCount[4];
|
||||
UCHAR DmaStatus;
|
||||
UCHAR DmaRequest;
|
||||
UCHAR SingleMask;
|
||||
UCHAR Mode;
|
||||
UCHAR ClearBytePointer;
|
||||
UCHAR MasterClear;
|
||||
UCHAR ClearMask;
|
||||
UCHAR AllMask;
|
||||
} DMA1_CONTROL, *PDMA1_CONTROL;
|
||||
|
||||
typedef struct _DMA2_CONTROL
|
||||
{
|
||||
DMA2_ADDRESS_COUNT DmaAddressCount[4];
|
||||
UCHAR DmaStatus;
|
||||
UCHAR Reserved1;
|
||||
UCHAR DmaRequest;
|
||||
UCHAR Reserved2;
|
||||
UCHAR SingleMask;
|
||||
UCHAR Reserved3;
|
||||
UCHAR Mode;
|
||||
UCHAR Reserved4;
|
||||
UCHAR ClearBytePointer;
|
||||
UCHAR Reserved5;
|
||||
UCHAR MasterClear;
|
||||
UCHAR Reserved6;
|
||||
UCHAR ClearMask;
|
||||
UCHAR Reserved7;
|
||||
UCHAR AllMask;
|
||||
UCHAR Reserved8;
|
||||
} DMA2_CONTROL, *PDMA2_CONTROL;
|
||||
|
||||
/* This structure defines the I/O Map of the 82537 controller. */
|
||||
typedef struct _EISA_CONTROL
|
||||
{
|
||||
/* DMA Controller 1 */
|
||||
DMA1_CONTROL DmaController1; /* 00h-0Fh */
|
||||
UCHAR Reserved1[16]; /* 0Fh-1Fh */
|
||||
|
||||
/* Interrupt Controller 1 (PIC) */
|
||||
UCHAR Pic1Operation; /* 20h */
|
||||
UCHAR Pic1Interrupt; /* 21h */
|
||||
UCHAR Reserved2[30]; /* 22h-3Fh */
|
||||
|
||||
/* Timer */
|
||||
UCHAR TimerCounter; /* 40h */
|
||||
UCHAR TimerMemoryRefresh; /* 41h */
|
||||
UCHAR Speaker; /* 42h */
|
||||
UCHAR TimerOperation; /* 43h */
|
||||
UCHAR TimerMisc; /* 44h */
|
||||
UCHAR Reserved3[2]; /* 45-46h */
|
||||
UCHAR TimerCounterControl; /* 47h */
|
||||
UCHAR TimerFailSafeCounter; /* 48h */
|
||||
UCHAR Reserved4; /* 49h */
|
||||
UCHAR TimerCounter2; /* 4Ah */
|
||||
UCHAR TimerOperation2; /* 4Bh */
|
||||
UCHAR Reserved5[20]; /* 4Ch-5Fh */
|
||||
|
||||
/* NMI / Keyboard / RTC */
|
||||
UCHAR Keyboard; /* 60h */
|
||||
UCHAR NmiStatus; /* 61h */
|
||||
UCHAR Reserved6[14]; /* 62h-6Fh */
|
||||
UCHAR NmiEnable; /* 70h */
|
||||
UCHAR Reserved7[15]; /* 71h-7Fh */
|
||||
|
||||
/* DMA Page Registers Controller 1 */
|
||||
DMA_PAGE DmaController1Pages; /* 80h-8Fh */
|
||||
UCHAR Reserved8[16]; /* 90h-9Fh */
|
||||
|
||||
/* Interrupt Controller 2 (PIC) */
|
||||
UCHAR Pic2Operation; /* 0A0h */
|
||||
UCHAR Pic2Interrupt; /* 0A1h */
|
||||
UCHAR Reserved9[30]; /* 0A2h-0BFh */
|
||||
|
||||
/* DMA Controller 2 */
|
||||
DMA1_CONTROL DmaController2; /* 0C0h-0CFh */
|
||||
|
||||
/* System Reserved Ports */
|
||||
UCHAR SystemReserved[816]; /* 0D0h-3FFh */
|
||||
|
||||
/* Extended DMA Registers, Controller 1 */
|
||||
UCHAR DmaHighByteCount1[8]; /* 400h-407h */
|
||||
UCHAR Reserved10[2]; /* 408h-409h */
|
||||
UCHAR DmaChainMode1; /* 40Ah */
|
||||
UCHAR DmaExtendedMode1; /* 40Bh */
|
||||
UCHAR DmaBufferControl; /* 40Ch */
|
||||
UCHAR Reserved11[84]; /* 40Dh-460h */
|
||||
UCHAR ExtendedNmiControl; /* 461h */
|
||||
UCHAR NmiCommand; /* 462h */
|
||||
UCHAR Reserved12; /* 463h */
|
||||
UCHAR BusMaster; /* 464h */
|
||||
UCHAR Reserved13[27]; /* 465h-47Fh */
|
||||
|
||||
/* DMA Page Registers Controller 2 */
|
||||
DMA_PAGE DmaController2Pages; /* 480h-48Fh */
|
||||
UCHAR Reserved14[48]; /* 490h-4BFh */
|
||||
|
||||
/* Extended DMA Registers, Controller 2 */
|
||||
UCHAR DmaHighByteCount2[16]; /* 4C0h-4CFh */
|
||||
|
||||
/* Edge/Level Control Registers */
|
||||
UCHAR Pic1EdgeLevel; /* 4D0h */
|
||||
UCHAR Pic2EdgeLevel; /* 4D1h */
|
||||
UCHAR Reserved15[2]; /* 4D2h-4D3h */
|
||||
|
||||
/* Extended DMA Registers, Controller 2 */
|
||||
UCHAR DmaChainMode2; /* 4D4h */
|
||||
UCHAR Reserved16; /* 4D5h */
|
||||
UCHAR DmaExtendedMode2; /* 4D6h */
|
||||
UCHAR Reserved17[9]; /* 4D7h-4DFh */
|
||||
|
||||
/* DMA Stop Registers */
|
||||
DMA_CHANNEL_STOP DmaChannelStop[8]; /* 4E0h-4FFh */
|
||||
} EISA_CONTROL, *PEISA_CONTROL;
|
||||
|
||||
typedef struct _ROS_MAP_REGISTER_ENTRY
|
||||
{
|
||||
PVOID VirtualAddress;
|
||||
PHYSICAL_ADDRESS PhysicalAddress;
|
||||
ULONG Counter;
|
||||
} ROS_MAP_REGISTER_ENTRY, *PROS_MAP_REGISTER_ENTRY;
|
||||
|
||||
struct _ADAPTER_OBJECT {
|
||||
/*
|
||||
* New style DMA object definition. The fact that it is at the beginning
|
||||
* of the ADAPTER_OBJECT structure allows us to easily implement the
|
||||
* fallback implementation of IoGetDmaAdapter.
|
||||
*/
|
||||
DMA_ADAPTER DmaHeader;
|
||||
|
||||
/*
|
||||
* For normal adapter objects pointer to master adapter that takes care
|
||||
* of channel allocation. For master adapter set to NULL.
|
||||
*/
|
||||
struct _ADAPTER_OBJECT *MasterAdapter;
|
||||
|
||||
ULONG MapRegistersPerChannel;
|
||||
PVOID AdapterBaseVa;
|
||||
PROS_MAP_REGISTER_ENTRY MapRegisterBase;
|
||||
|
||||
ULONG NumberOfMapRegisters;
|
||||
ULONG CommittedMapRegisters;
|
||||
|
||||
PWAIT_CONTEXT_BLOCK CurrentWcb;
|
||||
KDEVICE_QUEUE ChannelWaitQueue;
|
||||
PKDEVICE_QUEUE RegisterWaitQueue;
|
||||
LIST_ENTRY AdapterQueue;
|
||||
KSPIN_LOCK SpinLock;
|
||||
PRTL_BITMAP MapRegisters;
|
||||
PUCHAR PagePort;
|
||||
UCHAR ChannelNumber;
|
||||
UCHAR AdapterNumber;
|
||||
USHORT DmaPortAddress;
|
||||
DMA_MODE AdapterMode;
|
||||
BOOLEAN NeedsMapRegisters;
|
||||
BOOLEAN MasterDevice;
|
||||
BOOLEAN Width16Bits;
|
||||
BOOLEAN ScatterGather;
|
||||
BOOLEAN IgnoreCount;
|
||||
BOOLEAN Dma32BitAddresses;
|
||||
BOOLEAN Dma64BitAddresses;
|
||||
LIST_ENTRY AdapterList;
|
||||
} ADAPTER_OBJECT;
|
||||
|
||||
typedef struct _GROW_WORK_ITEM {
|
||||
WORK_QUEUE_ITEM WorkQueueItem;
|
||||
PADAPTER_OBJECT AdapterObject;
|
||||
ULONG NumberOfMapRegisters;
|
||||
} GROW_WORK_ITEM, *PGROW_WORK_ITEM;
|
||||
|
||||
#define MAP_BASE_SW_SG 1
|
||||
|
||||
PADAPTER_OBJECT STDCALL
|
||||
HalpDmaAllocateMasterAdapter(VOID);
|
||||
|
||||
PDMA_ADAPTER STDCALL
|
||||
HalpGetDmaAdapter(
|
||||
IN PVOID Context,
|
||||
IN PDEVICE_DESCRIPTION DeviceDescription,
|
||||
OUT PULONG NumberOfMapRegisters);
|
||||
|
||||
ULONG STDCALL
|
||||
HalpDmaGetDmaAlignment(
|
||||
PADAPTER_OBJECT AdapterObject);
|
||||
|
||||
#endif /* HALDMA_H */
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* $Id: halirq.h 23907 2006-09-04 05:52:23Z arty $
|
||||
*/
|
||||
|
||||
#ifndef __INCLUDE_HAL_HALIRQ
|
||||
#define __INCLUDE_HAL_HALIRQ
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
#define FIRST_DEVICE_VECTOR (0x30)
|
||||
#define FIRST_SYSTEM_VECTOR (0xef)
|
||||
|
||||
#define IRQ_BASE FIRST_DEVICE_VECTOR
|
||||
#define NR_IRQS (FIRST_SYSTEM_VECTOR - FIRST_DEVICE_VECTOR)
|
||||
|
||||
/*
|
||||
* FIXME:
|
||||
* This does not work if we have more than 24 IRQs (ie. more than one I/O APIC)
|
||||
*/
|
||||
#define VECTOR2IRQ(vector) (23 - (vector - IRQ_BASE) / 8)
|
||||
#define VECTOR2IRQL(vector) (PROFILE_LEVEL - VECTOR2IRQ(vector))
|
||||
#define IRQ2VECTOR(irq) (((23 - (irq)) * 8) + FIRST_DEVICE_VECTOR)
|
||||
|
||||
#else
|
||||
|
||||
#define IRQ_BASE (0x30)
|
||||
#define NR_IRQS (16)
|
||||
|
||||
#define VECTOR2IRQ(vector) ((vector) - IRQ_BASE)
|
||||
#define VECTOR2IRQL(vector) (PROFILE_LEVEL - VECTOR2IRQ(vector))
|
||||
#define IRQ2VECTOR(irq) ((irq) + IRQ_BASE)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __INCLUDE_HAL_HALIRQ */
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __INTERNAL_HAL_HAL_H
|
||||
#define __INTERNAL_HAL_HAL_H
|
||||
|
||||
#define HAL_APC_REQUEST 0
|
||||
#define HAL_DPC_REQUEST 1
|
||||
|
||||
//
|
||||
// Kernel Debugger Port Definition
|
||||
//
|
||||
typedef struct _KD_PORT_INFORMATION
|
||||
{
|
||||
ULONG ComPort;
|
||||
ULONG BaudRate;
|
||||
ULONG BaseAddress;
|
||||
} KD_PORT_INFORMATION, *PKD_PORT_INFORMATION;
|
||||
|
||||
/* display.c */
|
||||
VOID FASTCALL HalInitializeDisplay (struct _ROS_LOADER_PARAMETER_BLOCK *LoaderBlock);
|
||||
VOID FASTCALL HalClearDisplay (UCHAR CharAttribute);
|
||||
|
||||
/* adapter.c */
|
||||
PADAPTER_OBJECT STDCALL HalpAllocateAdapterEx(ULONG NumberOfMapRegisters,BOOLEAN IsMaster, BOOLEAN Dma32BitAddresses);
|
||||
|
||||
/* bus.c */
|
||||
VOID HalpInitBusHandlers (VOID);
|
||||
|
||||
/* irql.c */
|
||||
VOID NTAPI HalpInitPICs(VOID);
|
||||
|
||||
/* udelay.c */
|
||||
VOID HalpCalibrateStallExecution(VOID);
|
||||
|
||||
/* pci.c */
|
||||
VOID HalpInitPciBus (VOID);
|
||||
|
||||
/* enum.c */
|
||||
VOID HalpStartEnumerator (VOID);
|
||||
|
||||
/* dma.c */
|
||||
VOID HalpInitDma (VOID);
|
||||
|
||||
/* mem.c */
|
||||
PVOID HalpMapPhysMemory(ULONG PhysAddr, ULONG Size);
|
||||
|
||||
/* Non-generic initialization */
|
||||
VOID HalpInitPhase0 (PROS_LOADER_PARAMETER_BLOCK LoaderBlock);
|
||||
VOID HalpInitPhase1(VOID);
|
||||
VOID NTAPI HalpClockInterrupt(VOID);
|
||||
|
||||
/* sysinfo.c */
|
||||
NTSTATUS STDCALL
|
||||
HalpQuerySystemInformation(IN HAL_QUERY_INFORMATION_CLASS InformationClass,
|
||||
IN ULONG BufferSize,
|
||||
IN OUT PVOID Buffer,
|
||||
OUT PULONG ReturnedLength);
|
||||
|
||||
/* Non-standard functions */
|
||||
VOID STDCALL
|
||||
HalReleaseDisplayOwnership();
|
||||
|
||||
BOOLEAN STDCALL
|
||||
HalQueryDisplayOwnership();
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define Ki386SaveFlags(x) __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */)
|
||||
#define Ki386RestoreFlags(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
|
||||
#define Ki386DisableInterrupts() __asm__ __volatile__("cli\n\t")
|
||||
#define Ki386EnableInterrupts() __asm__ __volatile__("sti\n\t")
|
||||
#define Ki386HaltProcessor() __asm__ __volatile__("hlt\n\t")
|
||||
#define Ki386RdTSC(x) __asm__ __volatile__("rdtsc\n\t" : "=A" (x.u.LowPart), "=d" (x.u.HighPart))
|
||||
#define Ki386Rdmsr(msr,val1,val2) __asm__ __volatile__("rdmsr" : "=a" (val1), "=d" (val2) : "c" (msr))
|
||||
#define Ki386Wrmsr(msr,val1,val2) __asm__ __volatile__("wrmsr" : /* no outputs */ : "c" (msr), "a" (val1), "d" (val2))
|
||||
#define Ki386ReadFsByte(offset,x) __asm__ __volatile__("movb %%fs:%c1,%0" : "=q" (x) : "i" (offset))
|
||||
#define Ki386WriteFsByte(offset,x) __asm__ __volatile__("movb %0,%%fs:%c1" : : "q" ((UCHAR)x), "i" (offset))
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
#define Ki386SaveFlags(x) __asm pushfd __asm pop x;
|
||||
#define Ki386RestoreFlags(x) __asm push x __asm popfd;
|
||||
#define Ki386DisableInterrupts() __asm cli
|
||||
#define Ki386EnableInterrupts() __asm sti
|
||||
#define Ki386HaltProcessor() __asm hlt
|
||||
#else
|
||||
#error Unknown compiler for inline assembler
|
||||
#endif
|
||||
|
||||
typedef struct tagHALP_HOOKS
|
||||
{
|
||||
void (*InitPciBus)(ULONG BusNumber, PBUS_HANDLER BusHandler);
|
||||
} HALP_HOOKS, *PHALP_HOOKS;
|
||||
|
||||
extern HALP_HOOKS HalpHooks;
|
||||
|
||||
#endif /* __INTERNAL_HAL_HAL_H */
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __INTERNAL_HAL_IOAPIC_H
|
||||
#define __INTERNAL_HAL_IOAPIC_H
|
||||
|
||||
/* I/O APIC Register Address Map */
|
||||
#define IOAPIC_IOREGSEL 0x0000 /* I/O Register Select (index) (R/W) */
|
||||
#define IOAPIC_IOWIN 0x0010 /* I/O window (data) (R/W) */
|
||||
|
||||
#define IOAPIC_ID 0x0000 /* IO APIC ID (R/W) */
|
||||
#define IOAPIC_VER 0x0001 /* IO APIC Version (R) */
|
||||
#define IOAPIC_ARB 0x0002 /* IO APIC Arbitration ID (R) */
|
||||
#define IOAPIC_REDTBL 0x0010 /* Redirection Table (0-23 64-bit registers) (R/W) */
|
||||
|
||||
#define IOAPIC_ID_MASK (0xF << 24)
|
||||
#define GET_IOAPIC_ID(x) (((x) & IOAPIC_ID_MASK) >> 24)
|
||||
#define SET_IOAPIC_ID(x) ((x) << 24)
|
||||
|
||||
#define IOAPIC_VER_MASK (0xFF)
|
||||
#define GET_IOAPIC_VERSION(x) (((x) & IOAPIC_VER_MASK))
|
||||
#define IOAPIC_MRE_MASK (0xFF << 16) /* Maximum Redirection Entry */
|
||||
#define GET_IOAPIC_MRE(x) (((x) & IOAPIC_MRE_MASK) >> 16)
|
||||
|
||||
#define IOAPIC_ARB_MASK (0xF << 24)
|
||||
#define GET_IOAPIC_ARB(x) (((x) & IOAPIC_ARB_MASK) >> 24)
|
||||
|
||||
#define IOAPIC_TBL_DELMOD (0x7 << 10) /* Delivery Mode (see APIC_DM_*) */
|
||||
#define IOAPIC_TBL_DM (0x1 << 11) /* Destination Mode */
|
||||
#define IOAPIC_TBL_DS (0x1 << 12) /* Delivery Status */
|
||||
#define IOAPIC_TBL_INTPOL (0x1 << 13) /* Interrupt Input Pin Polarity */
|
||||
#define IOAPIC_TBL_RIRR (0x1 << 14) /* Remote IRR */
|
||||
#define IOAPIC_TBL_TM (0x1 << 15) /* Trigger Mode */
|
||||
#define IOAPIC_TBL_IM (0x1 << 16) /* Interrupt Mask */
|
||||
#define IOAPIC_TBL_DF0 (0xF << 56) /* Destination Field (physical mode) */
|
||||
#define IOAPIC_TBL_DF1 (0xFF<< 56) /* Destination Field (logical mode) */
|
||||
#define IOAPIC_TBL_VECTOR (0xFF << 0) /* Vector (10h - FEh) */
|
||||
|
||||
#include <pshpack1.h>
|
||||
typedef struct _IOAPIC_ROUTE_ENTRY {
|
||||
ULONG vector : 8,
|
||||
delivery_mode : 3, /* 000: FIXED
|
||||
* 001: lowest priority
|
||||
* 111: ExtINT
|
||||
*/
|
||||
dest_mode : 1, /* 0: physical, 1: logical */
|
||||
delivery_status : 1,
|
||||
polarity : 1,
|
||||
irr : 1,
|
||||
trigger : 1, /* 0: edge, 1: level */
|
||||
mask : 1, /* 0: enabled, 1: disabled */
|
||||
__reserved_2 : 15;
|
||||
|
||||
union {
|
||||
struct {
|
||||
ULONG __reserved_1 : 24,
|
||||
physical_dest : 4,
|
||||
__reserved_2 : 4;
|
||||
} physical;
|
||||
struct {
|
||||
ULONG __reserved_1 : 24,
|
||||
logical_dest : 8;
|
||||
} logical;
|
||||
} dest;
|
||||
} IOAPIC_ROUTE_ENTRY, *PIOAPIC_ROUTE_ENTRY;
|
||||
#include <poppack.h>
|
||||
|
||||
typedef struct _IOAPIC_INFO
|
||||
{
|
||||
ULONG ApicId; /* APIC ID */
|
||||
ULONG ApicVersion; /* APIC version */
|
||||
ULONG ApicAddress; /* APIC address */
|
||||
ULONG EntryCount; /* Number of redirection entries */
|
||||
} IOAPIC_INFO, *PIOAPIC_INFO;
|
||||
|
||||
#define IOAPIC_DEFAULT_BASE 0xFEC00000 /* Default I/O APIC Base Register Address */
|
||||
|
||||
extern ULONG IRQCount; /* Number of IRQs */
|
||||
extern UCHAR BUSMap[MAX_BUS]; /* Map of all buses in the system */
|
||||
extern UCHAR PCIBUSMap[MAX_BUS]; /* Map of all PCI buses in the system */
|
||||
extern IOAPIC_INFO IOAPICMap[MAX_IOAPIC]; /* Map of all I/O APICs in the system */
|
||||
extern ULONG IOAPICCount; /* Number of I/O APICs in the system */
|
||||
extern ULONG APICMode; /* APIC mode at startup */
|
||||
extern MP_CONFIGURATION_INTSRC IRQMap[MAX_IRQ_SOURCE]; /* Map of all IRQs */
|
||||
|
||||
VOID IOAPICSetupIrqs(VOID);
|
||||
VOID IOAPICEnable(VOID);
|
||||
VOID IOAPICSetupIds(VOID);
|
||||
VOID IOAPICMaskIrq(ULONG Irq);
|
||||
VOID IOAPICUnmaskIrq(ULONG Irq);
|
||||
|
||||
VOID HaliReconfigurePciInterrupts(VOID);
|
||||
|
||||
/* For debugging */
|
||||
VOID IOAPICDump(VOID);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* EOF */
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
#ifndef __INCLUDE_HAL_MPS
|
||||
#define __INCLUDE_HAL_MPS
|
||||
|
||||
/*
|
||||
* FIXME: This does not work if we have more than 24 IRQs (ie. more than one
|
||||
* I/O APIC)
|
||||
*/
|
||||
#define IRQL2VECTOR(irql) (IRQ2VECTOR(PROFILE_LEVEL - (irql)))
|
||||
|
||||
#define IRQL2TPR(irql) ((irql) >= IPI_LEVEL ? IPI_VECTOR : ((irql) >= PROFILE_LEVEL ? LOCAL_TIMER_VECTOR : ((irql) > DISPATCH_LEVEL ? IRQL2VECTOR(irql) : 0)))
|
||||
|
||||
typedef struct _KIRQ_TRAPFRAME
|
||||
{
|
||||
ULONG Magic;
|
||||
ULONG Gs;
|
||||
ULONG Fs;
|
||||
ULONG Es;
|
||||
ULONG Ds;
|
||||
ULONG Eax;
|
||||
ULONG Ecx;
|
||||
ULONG Edx;
|
||||
ULONG Ebx;
|
||||
ULONG Esp;
|
||||
ULONG Ebp;
|
||||
ULONG Esi;
|
||||
ULONG Edi;
|
||||
ULONG Eip;
|
||||
ULONG Cs;
|
||||
ULONG Eflags;
|
||||
} KIRQ_TRAPFRAME, *PKIRQ_TRAPFRAME;
|
||||
|
||||
#if 0
|
||||
/* This values are defined in halirql.h */
|
||||
#define FIRST_DEVICE_VECTOR 0x30
|
||||
#define FIRST_SYSTEM_VECTOR 0xEF
|
||||
#endif
|
||||
|
||||
#define NUMBER_DEVICE_VECTORS (FIRST_SYSTEM_VECTOR - FIRST_DEVICE_VECTOR)
|
||||
|
||||
|
||||
/* MP Floating Pointer Structure */
|
||||
#define MPF_SIGNATURE (('_' << 24) | ('P' << 16) | ('M' << 8) | '_')
|
||||
|
||||
#include <pshpack1.h>
|
||||
typedef struct _MP_FLOATING_POINTER
|
||||
{
|
||||
ULONG Signature; /* _MP_ */
|
||||
ULONG Address; /* Physical Address Pointer (0 means no configuration table exist) */
|
||||
UCHAR Length; /* Structure length in 16-byte paragraphs */
|
||||
UCHAR Specification; /* Specification revision */
|
||||
UCHAR Checksum; /* Checksum */
|
||||
UCHAR Feature1; /* MP System Configuration Type */
|
||||
UCHAR Feature2; /* Bit 7 set for IMCR|PIC */
|
||||
UCHAR Feature3; /* Unused (0) */
|
||||
UCHAR Feature4; /* Unused (0) */
|
||||
UCHAR Feature5; /* Unused (0) */
|
||||
} MP_FLOATING_POINTER, *PMP_FLOATING_POINTER;
|
||||
|
||||
|
||||
#define FEATURE2_IMCRP 0x80
|
||||
|
||||
/* MP Configuration Table Header */
|
||||
#define MPC_SIGNATURE (('P' << 24) | ('M' << 16) | ('C' << 8) | 'P')
|
||||
|
||||
typedef struct _MP_CONFIGURATION_TABLE
|
||||
{
|
||||
ULONG Signature; /* PCMP */
|
||||
USHORT Length; /* Size of configuration table */
|
||||
CHAR Specification; /* Specification Revision */
|
||||
CHAR Checksum; /* Checksum */
|
||||
CHAR Oem[8]; /* OEM ID */
|
||||
CHAR ProductId[12]; /* Product ID */
|
||||
ULONG OemTable; /* 0 if not present */
|
||||
USHORT OemTableSize; /* 0 if not present */
|
||||
USHORT EntryCount; /* Number of entries */
|
||||
ULONG LocalAPICAddress; /* Local APIC address */
|
||||
USHORT ExtTableLength; /* Extended Table Length */
|
||||
UCHAR ExtTableChecksum; /* Extended Table Checksum */
|
||||
UCHAR Reserved; /* Reserved */
|
||||
} MP_CONFIGURATION_TABLE, *PMP_CONFIGURATION_TABLE;
|
||||
|
||||
/* MP Configuration Table Entries */
|
||||
#define MPCTE_PROCESSOR 0 /* One entry per processor */
|
||||
#define MPCTE_BUS 1 /* One entry per bus */
|
||||
#define MPCTE_IOAPIC 2 /* One entry per I/O APIC */
|
||||
#define MPCTE_INTSRC 3 /* One entry per bus interrupt source */
|
||||
#define MPCTE_LINTSRC 4 /* One entry per system interrupt source */
|
||||
|
||||
|
||||
typedef struct _MP_CONFIGURATION_PROCESSOR
|
||||
{
|
||||
UCHAR Type; /* 0 */
|
||||
UCHAR ApicId; /* Local APIC ID for the processor */
|
||||
UCHAR ApicVersion; /* Local APIC version */
|
||||
UCHAR CpuFlags; /* CPU flags */
|
||||
ULONG CpuSignature; /* CPU signature */
|
||||
ULONG FeatureFlags; /* CPUID feature value */
|
||||
ULONG Reserved[2]; /* Reserved (0) */
|
||||
} MP_CONFIGURATION_PROCESSOR, *PMP_CONFIGURATION_PROCESSOR;
|
||||
|
||||
|
||||
|
||||
typedef struct _MP_CONFIGURATION_BUS
|
||||
{
|
||||
UCHAR Type; /* 1 */
|
||||
UCHAR BusId; /* Bus ID */
|
||||
CHAR BusType[6]; /* Bus type */
|
||||
} MP_CONFIGURATION_BUS, *PMP_CONFIGURATION_BUS;
|
||||
|
||||
#define MAX_BUS 32
|
||||
|
||||
#define MP_BUS_ISA 1
|
||||
#define MP_BUS_EISA 2
|
||||
#define MP_BUS_PCI 3
|
||||
#define MP_BUS_MCA 4
|
||||
|
||||
#define BUSTYPE_EISA "EISA"
|
||||
#define BUSTYPE_ISA "ISA"
|
||||
#define BUSTYPE_INTERN "INTERN" /* Internal BUS */
|
||||
#define BUSTYPE_MCA "MCA"
|
||||
#define BUSTYPE_VL "VL" /* Local bus */
|
||||
#define BUSTYPE_PCI "PCI"
|
||||
#define BUSTYPE_PCMCIA "PCMCIA"
|
||||
#define BUSTYPE_CBUS "CBUS"
|
||||
#define BUSTYPE_CBUSII "CBUSII"
|
||||
#define BUSTYPE_FUTURE "FUTURE"
|
||||
#define BUSTYPE_MBI "MBI"
|
||||
#define BUSTYPE_MBII "MBII"
|
||||
#define BUSTYPE_MPI "MPI"
|
||||
#define BUSTYPE_MPSA "MPSA"
|
||||
#define BUSTYPE_NUBUS "NUBUS"
|
||||
#define BUSTYPE_TC "TC"
|
||||
#define BUSTYPE_VME "VME"
|
||||
#define BUSTYPE_XPRESS "XPRESS"
|
||||
|
||||
|
||||
typedef struct _MP_CONFIGURATION_IOAPIC
|
||||
{
|
||||
UCHAR Type; /* 2 */
|
||||
UCHAR ApicId; /* I/O APIC ID */
|
||||
UCHAR ApicVersion; /* I/O APIC version */
|
||||
UCHAR ApicFlags; /* I/O APIC flags */
|
||||
ULONG ApicAddress; /* I/O APIC base address */
|
||||
} MP_CONFIGURATION_IOAPIC, *PMP_CONFIGURATION_IOAPIC;
|
||||
|
||||
#define MAX_IOAPIC 2
|
||||
|
||||
#define MP_IOAPIC_USABLE 0x01
|
||||
|
||||
|
||||
typedef struct _MP_CONFIGURATION_INTSRC
|
||||
{
|
||||
UCHAR Type; /* 3 */
|
||||
UCHAR IrqType; /* Interrupt type */
|
||||
USHORT IrqFlag; /* Interrupt flags */
|
||||
UCHAR SrcBusId; /* Source bus ID */
|
||||
UCHAR SrcBusIrq; /* Source bus interrupt */
|
||||
UCHAR DstApicId; /* Destination APIC ID */
|
||||
UCHAR DstApicInt; /* Destination interrupt */
|
||||
} MP_CONFIGURATION_INTSRC, *PMP_CONFIGURATION_INTSRC;
|
||||
|
||||
#define MAX_IRQ_SOURCE 128
|
||||
|
||||
#define INT_VECTORED 0
|
||||
#define INT_NMI 1
|
||||
#define INT_SMI 2
|
||||
#define INT_EXTINT 3
|
||||
|
||||
#define IRQDIR_DEFAULT 0
|
||||
#define IRQDIR_HIGH 1
|
||||
#define IRQDIR_LOW 3
|
||||
|
||||
|
||||
typedef struct _MP_CONFIGURATION_INTLOCAL
|
||||
{
|
||||
UCHAR Type; /* 4 */
|
||||
UCHAR IrqType; /* Interrupt type */
|
||||
USHORT IrqFlag; /* Interrupt flags */
|
||||
UCHAR SrcBusId; /* Source bus ID */
|
||||
UCHAR SrcBusIrq; /* Source bus interrupt */
|
||||
UCHAR DstApicId; /* Destination local APIC ID */
|
||||
UCHAR DstApicLInt; /* Destination local APIC interrupt */
|
||||
} MP_CONFIGURATION_INTLOCAL, *PMP_CONFIGURATION_INTLOCAL;
|
||||
#include <poppack.h>
|
||||
|
||||
#define MP_APIC_ALL 0xFF
|
||||
|
||||
#define CPU_FLAG_ENABLED 1 /* Processor is available */
|
||||
#define CPU_FLAG_BSP 2 /* Processor is the bootstrap processor */
|
||||
|
||||
#define CPU_STEPPING_MASK 0x0F
|
||||
#define CPU_MODEL_MASK 0xF0
|
||||
#define CPU_FAMILY_MASK 0xF00
|
||||
|
||||
#define PIC_IRQS 16
|
||||
|
||||
/* Prototypes */
|
||||
|
||||
VOID HalpInitMPS(VOID);
|
||||
|
||||
|
||||
#endif /* __INCLUDE_HAL_MPS */
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,35 @@
|
||||
/* $Id: halinit_up.c 23907 2006-09-04 05:52:23Z arty $
|
||||
*
|
||||
* 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 ([email protected])
|
||||
* UPDATE HISTORY:
|
||||
* 11/06/98: Created
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
VOID
|
||||
HalpInitPhase0(PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
HalpInitPICs();
|
||||
|
||||
/* Setup busy waiting */
|
||||
HalpCalibrateStallExecution();
|
||||
}
|
||||
|
||||
VOID
|
||||
HalpInitPhase1(VOID)
|
||||
{
|
||||
/* Nothing for now */
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,12 @@
|
||||
<module name="halppc_up" type="kernelmodedll">
|
||||
<importlibrary definition="../../hal/hal.def" />
|
||||
<bootstrap base="reactos" nameoncd="hal.dll" />
|
||||
<include base="hal_generic">../include</include>
|
||||
<include base="ntoskrnl">include</include>
|
||||
<define name="_DISABLE_TIDENTS" />
|
||||
<define name="__USE_W32API" />
|
||||
<define name="_NTHAL_" />
|
||||
<library>halppc_generic</library>
|
||||
<file>halinit_up.c</file>
|
||||
<file>halup.rc</file>
|
||||
</module>
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user