mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +00:00
[HALPC98] Add Hardware Abstraction Layer for NEC PC-98 series (#3002)
This commit is contained in:
parent
0c222cfe96
commit
b36018ff26
37 changed files with 1880 additions and 372 deletions
|
@ -226,6 +226,7 @@ pci_up = "Standard PC Uniprocessor"
|
|||
acpi_up = "ACPI PC Uniprocessor"
|
||||
;acpi_mp = "ACPI PC Multiprocessor"
|
||||
xbox = "Original Xbox (x86 based)"
|
||||
pc98_up = "Uniprocessor NEC PC-98"
|
||||
|
||||
[Computer.NTamd64]
|
||||
x64_up = "Standard x64 Uniprocessor"
|
||||
|
@ -237,6 +238,7 @@ pci_up = "PC UP"
|
|||
acpi_up = "ACPI UP"
|
||||
;acpi_mp = "ACPI MP"
|
||||
xbox = "Xbox"
|
||||
pc98_up = "NEC PC-98 UP"
|
||||
|
||||
[Map.Computer.NTamd64]
|
||||
x64_up = "ACPI UP"
|
||||
|
@ -261,6 +263,10 @@ halacpi.dll = 1,,,,,,,2,,,hal.dll,1,2
|
|||
ntoskrnl.exe = 1,,,,,,,2,,,,1,2
|
||||
halxbox.dll = 1,,,,,,,2,,,hal.dll,1,2
|
||||
|
||||
[Files.pc98_up]
|
||||
ntoskrnl.exe = 1,,,,,,,2,,,,1,2
|
||||
halpc98.dll = 1,,,,,,,2,,,hal.dll,1,2
|
||||
|
||||
[Files.x64_up]
|
||||
ntoskrnl.exe = 1,,,,,,,2,,,,1,2
|
||||
hal.dll = 1,,,,,,,2,,,,1,2
|
||||
|
|
|
@ -32,6 +32,14 @@ function(add_hal _halname)
|
|||
target_link_libraries(${_halname} ${_haldata_LIBS})
|
||||
endif()
|
||||
|
||||
if(${_halname} STREQUAL "halpc98")
|
||||
target_compile_definitions(lib_hal_pc98 PRIVATE SARCH_PC98)
|
||||
endif()
|
||||
|
||||
if(${_halname} STREQUAL "halxbox")
|
||||
target_compile_definitions(lib_hal_xbox PRIVATE SARCH_XBOX)
|
||||
endif()
|
||||
|
||||
if(${_halname} STREQUAL "hal")
|
||||
target_link_libraries(${_halname} libcntpr arbiter)
|
||||
else()
|
||||
|
@ -61,14 +69,19 @@ if(ARCH STREQUAL "i386")
|
|||
include(up.cmake)
|
||||
include(pic.cmake)
|
||||
include(xbox.cmake)
|
||||
include(pc98.cmake)
|
||||
add_subdirectory(minihal)
|
||||
|
||||
remove_definitions(-DSARCH_XBOX)
|
||||
remove_definitions(-DSARCH_PC98)
|
||||
|
||||
# hal
|
||||
add_hal(hal SOURCES up/halup.rc COMPONENTS generic legacy up pic)
|
||||
add_hal(halacpi SOURCES acpi/halacpi.rc COMPONENTS generic acpi up pic)
|
||||
add_hal(halapic SOURCES acpi/halacpi.rc COMPONENTS generic legacy up apic)
|
||||
add_hal(halaacpi SOURCES acpi/halacpi.rc COMPONENTS generic acpi up apic)
|
||||
add_hal(halxbox SOURCES xbox/halxbox.rc COMPONENTS xbox up)
|
||||
add_hal(halpc98 SOURCES pc98/halpc98.rc COMPONENTS pc98 up)
|
||||
|
||||
#add_hal(halmps SOURCES up/halup.rc COMPONENTS generic legacy smp pic)
|
||||
#add_hal(halmacpi SOURCES acpi/halacpi.rc COMPONENTS generic acpi smp pic)
|
||||
|
|
|
@ -8,6 +8,7 @@ list(APPEND HAL_GENERIC_SOURCE
|
|||
generic/halinit.c
|
||||
generic/memory.c
|
||||
generic/misc.c
|
||||
generic/nmi.c
|
||||
generic/pic.c
|
||||
generic/reboot.c
|
||||
generic/sysinfo.c
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Hardware Abstraction Layer (HAL)
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: hal/halx86/generic/bios.c
|
||||
* PURPOSE: BIOS Access Routines
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
* Alex Ionescu (alex.ionescu@reactos.org)
|
||||
|
@ -10,8 +9,10 @@
|
|||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
void __cdecl HalpTrap0D();
|
||||
|
@ -645,7 +646,8 @@ BOOLEAN
|
|||
NTAPI
|
||||
HalpBiosDisplayReset(VOID)
|
||||
{
|
||||
#ifdef SARCH_XBOX
|
||||
#if defined(SARCH_XBOX) || defined(SARCH_PC98)
|
||||
/* There is no VGA BIOS on these machine types */
|
||||
return FALSE;
|
||||
#else
|
||||
ULONG Flags;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* PROJECT: ReactOS HAL
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: hal/halx86/generic/cmos.c
|
||||
* PURPOSE: CMOS Access Routines (Real Time Clock and LastKnownGood)
|
||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||
* Eric Kohl
|
||||
|
@ -10,6 +9,7 @@
|
|||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
@ -23,6 +23,7 @@ UCHAR HalpCmosCenturyOffset;
|
|||
|
||||
/* PRIVATE FUNCTIONS *********************************************************/
|
||||
|
||||
_Requires_lock_held_(HalpSystemHardwareLock)
|
||||
UCHAR
|
||||
NTAPI
|
||||
HalpReadCmos(IN UCHAR Reg)
|
||||
|
@ -34,6 +35,7 @@ HalpReadCmos(IN UCHAR Reg)
|
|||
return READ_PORT_UCHAR(CMOS_DATA_PORT);
|
||||
}
|
||||
|
||||
_Requires_lock_held_(HalpSystemHardwareLock)
|
||||
VOID
|
||||
NTAPI
|
||||
HalpWriteCmos(IN UCHAR Reg,
|
||||
|
@ -48,10 +50,11 @@ HalpWriteCmos(IN UCHAR Reg,
|
|||
|
||||
ULONG
|
||||
NTAPI
|
||||
HalpGetCmosData(IN ULONG BusNumber,
|
||||
IN ULONG SlotNumber,
|
||||
IN PVOID Buffer,
|
||||
IN ULONG Length)
|
||||
HalpGetCmosData(
|
||||
_In_ ULONG BusNumber,
|
||||
_In_ ULONG SlotNumber,
|
||||
_Out_writes_bytes_(Length) PVOID Buffer,
|
||||
_In_ ULONG Length)
|
||||
{
|
||||
PUCHAR Ptr = (PUCHAR)Buffer;
|
||||
ULONG Address = SlotNumber;
|
||||
|
@ -173,9 +176,10 @@ HalpInitializeCmos(VOID)
|
|||
*/
|
||||
ARC_STATUS
|
||||
NTAPI
|
||||
HalGetEnvironmentVariable(IN PCH Name,
|
||||
IN USHORT ValueLength,
|
||||
IN PCH Value)
|
||||
HalGetEnvironmentVariable(
|
||||
_In_ PCH Name,
|
||||
_In_ USHORT ValueLength,
|
||||
_Out_writes_z_(ValueLength) PCH Value)
|
||||
{
|
||||
UCHAR Val;
|
||||
|
||||
|
|
|
@ -133,6 +133,24 @@ static DMA_OPERATIONS HalpDmaOperations = {
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
#if defined(SARCH_PC98)
|
||||
/*
|
||||
* Disable I/O for safety.
|
||||
* FIXME: Add support for PC-98 DMA controllers.
|
||||
*/
|
||||
#undef WRITE_PORT_UCHAR
|
||||
#undef READ_PORT_UCHAR
|
||||
|
||||
#define WRITE_PORT_UCHAR(Port, Data) \
|
||||
do { \
|
||||
UNIMPLEMENTED; \
|
||||
(Port); \
|
||||
(Data); \
|
||||
} while (0)
|
||||
|
||||
#define READ_PORT_UCHAR(Port) 0x00
|
||||
#endif
|
||||
|
||||
#ifndef _MINIHAL_
|
||||
INIT_FUNCTION
|
||||
VOID
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Hardware Abstraction Layer (HAL)
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: hal/halx86/generic/misc.c
|
||||
* PURPOSE: NMI, I/O Mapping and x86 Subs
|
||||
* PURPOSE: I/O Mapping and x86 Subs
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
#include <drivers/bootvid/display.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
@ -21,8 +19,6 @@
|
|||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
BOOLEAN HalpNMIInProgress;
|
||||
|
||||
UCHAR HalpSerialLen;
|
||||
CHAR HalpSerialNumber[31];
|
||||
|
||||
|
@ -148,7 +144,7 @@ HalpOpenRegistryKey(IN PHANDLE KeyHandle,
|
|||
/* We're done */
|
||||
return Status;
|
||||
}
|
||||
#endif
|
||||
#endif /* !_MINIHAL_ */
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
|
@ -223,108 +219,6 @@ HalpFlushTLB(VOID)
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
HalHandleNMI(IN PVOID NmiInfo)
|
||||
{
|
||||
#ifndef _MINIHAL_
|
||||
SYSTEM_CONTROL_PORT_B_REGISTER SystemControl;
|
||||
|
||||
//
|
||||
// Don't recurse
|
||||
//
|
||||
if (HalpNMIInProgress++) ERROR_DBGBREAK();
|
||||
|
||||
//
|
||||
// Read the system control register B
|
||||
//
|
||||
SystemControl.Bits = __inbyte(SYSTEM_CONTROL_PORT_B);
|
||||
|
||||
//
|
||||
// Switch to boot video
|
||||
//
|
||||
if (InbvIsBootDriverInstalled())
|
||||
{
|
||||
//
|
||||
// Acquire ownership
|
||||
//
|
||||
InbvAcquireDisplayOwnership();
|
||||
InbvResetDisplay();
|
||||
|
||||
//
|
||||
// Fill the screen
|
||||
//
|
||||
InbvSolidColorFill(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, BV_COLOR_RED);
|
||||
InbvSetScrollRegion(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
|
||||
|
||||
//
|
||||
// Enable text
|
||||
//
|
||||
InbvSetTextColor(BV_COLOR_WHITE);
|
||||
InbvInstallDisplayStringFilter(NULL);
|
||||
InbvEnableDisplayString(TRUE);
|
||||
}
|
||||
|
||||
//
|
||||
// Display NMI failure string
|
||||
//
|
||||
InbvDisplayString("\r\n*** Hardware Malfunction\r\n\r\n");
|
||||
InbvDisplayString("Call your hardware vendor for support\r\n\r\n");
|
||||
|
||||
//
|
||||
// Check for parity error
|
||||
//
|
||||
if (SystemControl.ParityCheck)
|
||||
{
|
||||
//
|
||||
// Display message
|
||||
//
|
||||
InbvDisplayString("NMI: Parity Check / Memory Parity Error\r\n");
|
||||
}
|
||||
|
||||
//
|
||||
// Check for I/O failure
|
||||
//
|
||||
if (SystemControl.ChannelCheck)
|
||||
{
|
||||
//
|
||||
// Display message
|
||||
//
|
||||
InbvDisplayString("NMI: Channel Check / IOCHK\r\n");
|
||||
}
|
||||
|
||||
//
|
||||
// Check for EISA systems
|
||||
//
|
||||
if (HalpBusType == MACHINE_TYPE_EISA)
|
||||
{
|
||||
//
|
||||
// FIXME: Not supported
|
||||
//
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Halt the system
|
||||
//
|
||||
InbvDisplayString("\r\n*** The system has halted ***\r\n");
|
||||
|
||||
|
||||
//
|
||||
// Enter the debugger if possible
|
||||
//
|
||||
KiBugCheckData[0] = (ULONG_PTR)KeServiceDescriptorTable; /* NMI Corruption? */
|
||||
//if (!(KdDebuggerNotPresent) && (KdDebuggerEnabled)) KeEnterKernelDebugger();
|
||||
#endif
|
||||
//
|
||||
// Freeze the system
|
||||
//
|
||||
while (TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
@ -407,5 +301,4 @@ KeReleaseSpinLock(PKSPIN_LOCK SpinLock,
|
|||
KfReleaseSpinLock(SpinLock, NewIrql);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _M_IX86 */
|
||||
|
|
108
hal/halx86/generic/nmi.c
Normal file
108
hal/halx86/generic/nmi.c
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Hardware Abstraction Layer
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* PURPOSE: NMI handling
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
#include <drivers/bootvid/display.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
BOOLEAN HalpNMIInProgress;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
HalHandleNMI(
|
||||
IN PVOID NmiInfo)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(NmiInfo);
|
||||
#ifndef _MINIHAL_
|
||||
SYSTEM_CONTROL_PORT_B_REGISTER SystemControl;
|
||||
|
||||
/* Don't recurse */
|
||||
if (HalpNMIInProgress++)
|
||||
ERROR_DBGBREAK();
|
||||
|
||||
/* Get NMI reason from hardware */
|
||||
#if defined(SARCH_PC98)
|
||||
SystemControl.Bits = __inbyte(PPI_IO_i_PORT_B);
|
||||
#else
|
||||
SystemControl.Bits = __inbyte(SYSTEM_CONTROL_PORT_B);
|
||||
#endif
|
||||
|
||||
/* Switch to boot video */
|
||||
if (InbvIsBootDriverInstalled())
|
||||
{
|
||||
/* Acquire ownership */
|
||||
InbvAcquireDisplayOwnership();
|
||||
InbvResetDisplay();
|
||||
|
||||
/* Fill the screen */
|
||||
InbvSolidColorFill(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, BV_COLOR_RED);
|
||||
InbvSetScrollRegion(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
|
||||
|
||||
/* Enable text */
|
||||
InbvSetTextColor(BV_COLOR_WHITE);
|
||||
InbvInstallDisplayStringFilter(NULL);
|
||||
InbvEnableDisplayString(TRUE);
|
||||
}
|
||||
|
||||
/* Display NMI failure string */
|
||||
InbvDisplayString("\r\n*** Hardware Malfunction\r\n\r\n");
|
||||
InbvDisplayString("Call your hardware vendor for support\r\n\r\n");
|
||||
|
||||
#if defined(SARCH_PC98)
|
||||
/* Check for parity error */
|
||||
if (SystemControl.MemoryParityCheck)
|
||||
{
|
||||
InbvDisplayString("NMI: Parity Check / Memory Parity Error\r\n");
|
||||
}
|
||||
if (SystemControl.ExtendedMemoryParityCheck)
|
||||
{
|
||||
InbvDisplayString("NMI: Parity Check / Extended Memory Parity Error\r\n");
|
||||
}
|
||||
#else
|
||||
/* Check for parity error */
|
||||
if (SystemControl.ParityCheck)
|
||||
{
|
||||
InbvDisplayString("NMI: Parity Check / Memory Parity Error\r\n");
|
||||
}
|
||||
|
||||
/* Check for I/O failure */
|
||||
if (SystemControl.ChannelCheck)
|
||||
{
|
||||
InbvDisplayString("NMI: Channel Check / IOCHK\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check for EISA systems */
|
||||
if (HalpBusType == MACHINE_TYPE_EISA)
|
||||
{
|
||||
/* FIXME: Not supported */
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
/* Halt the system */
|
||||
InbvDisplayString("\r\n*** The system has halted ***\r\n");
|
||||
|
||||
/* Enter the debugger if possible */
|
||||
KiBugCheckData[0] = (ULONG_PTR)KeServiceDescriptorTable; /* NMI Corruption? */
|
||||
//if (!(KdDebuggerNotPresent) && (KdDebuggerEnabled)) KeEnterKernelDebugger();
|
||||
#endif /* !_MINIHAL_ */
|
||||
|
||||
/* Freeze the system */
|
||||
while (TRUE)
|
||||
NOTHING;
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* PROJECT: ReactOS HAL
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: hal/halx86/generic/timer.c
|
||||
* PURPOSE: HAL Timer Routines
|
||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||
* Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||
|
@ -101,6 +100,10 @@ HalpInitializeClock(VOID)
|
|||
|
||||
DPRINT("HalpInitializeClock()\n");
|
||||
|
||||
#if defined(SARCH_PC98)
|
||||
HalpInitializeClockPc98();
|
||||
#endif
|
||||
|
||||
/* Get increment and rollover for the largest time clock ms possible */
|
||||
Increment = HalpRolloverTable[HalpLargestClockMS - 1].Increment;
|
||||
RollOver = (USHORT)HalpRolloverTable[HalpLargestClockMS - 1].RollOver;
|
||||
|
@ -129,7 +132,7 @@ HalpClockInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
|||
KiEnterInterruptTrap(TrapFrame);
|
||||
|
||||
/* Start the interrupt */
|
||||
if (HalBeginSystemInterrupt(CLOCK2_LEVEL, PRIMARY_VECTOR_BASE, &Irql))
|
||||
if (HalBeginSystemInterrupt(CLOCK2_LEVEL, PRIMARY_VECTOR_BASE + PIC_TIMER_IRQ, &Irql))
|
||||
{
|
||||
/* Update the performance counter */
|
||||
HalpPerfCounter.QuadPart += HalpCurrentRollOver;
|
||||
|
@ -170,13 +173,20 @@ HalpProfileInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
|||
KiEnterInterruptTrap(TrapFrame);
|
||||
|
||||
/* Start the interrupt */
|
||||
if (HalBeginSystemInterrupt(PROFILE_LEVEL, PRIMARY_VECTOR_BASE + 8, &Irql))
|
||||
if (HalBeginSystemInterrupt(PROFILE_LEVEL, PRIMARY_VECTOR_BASE + PIC_RTC_IRQ, &Irql))
|
||||
{
|
||||
#if defined(SARCH_PC98)
|
||||
/* Clear the interrupt flag */
|
||||
HalpAcquireCmosSpinLock();
|
||||
(VOID)__inbyte(RTC_IO_i_INTERRUPT_RESET);
|
||||
HalpReleaseCmosSpinLock();
|
||||
#else
|
||||
/* Spin until the interrupt pending bit is clear */
|
||||
HalpAcquireCmosSpinLock();
|
||||
while (HalpReadCmos(RTC_REGISTER_C) & RTC_REG_C_IRQ)
|
||||
;
|
||||
NOTHING;
|
||||
HalpReleaseCmosSpinLock();
|
||||
#endif
|
||||
|
||||
/* If profiling is enabled, call the kernel function */
|
||||
if (!HalpProfilingStopped)
|
||||
|
@ -192,9 +202,9 @@ HalpProfileInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
|||
/* Spurious, just end the interrupt */
|
||||
KiEoiHelper(TrapFrame);
|
||||
}
|
||||
#endif
|
||||
#endif /* !_MINIHAL_ */
|
||||
|
||||
#endif
|
||||
#endif /* _M_IX86 */
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* PROJECT: ReactOS HAL
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: hal/halx86/generic/usage.c
|
||||
* PURPOSE: HAL Resource Report Routines
|
||||
* PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org)
|
||||
*/
|
||||
|
@ -9,6 +8,7 @@
|
|||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
@ -82,6 +82,60 @@ ADDRESS_USAGE HalpDefaultIoSpace =
|
|||
{
|
||||
NULL, CmResourceTypePort, IDT_INTERNAL,
|
||||
{
|
||||
#if defined(SARCH_PC98)
|
||||
/* PIC 1 */
|
||||
{0x00, 1},
|
||||
{0x02, 1},
|
||||
/* PIC 2 */
|
||||
{0x08, 1},
|
||||
{0x0A, 1},
|
||||
/* DMA */
|
||||
{0x01, 1},
|
||||
{0x03, 1},
|
||||
{0x05, 1},
|
||||
{0x07, 1},
|
||||
{0x09, 1},
|
||||
{0x0B, 1},
|
||||
{0x0D, 1},
|
||||
{0x0F, 1},
|
||||
{0x11, 1},
|
||||
{0x13, 1},
|
||||
{0x15, 1},
|
||||
{0x17, 1},
|
||||
{0x19, 1},
|
||||
{0x1B, 1},
|
||||
{0x1D, 1},
|
||||
{0x1F, 1},
|
||||
{0x21, 1},
|
||||
{0x23, 1},
|
||||
{0x25, 1},
|
||||
{0x27, 1},
|
||||
{0x29, 1},
|
||||
{0x2B, 1},
|
||||
{0x2D, 1},
|
||||
{0xE05, 1},
|
||||
{0xE07, 1},
|
||||
{0xE09, 1},
|
||||
{0xE0B, 1},
|
||||
/* RTC */
|
||||
{0x20, 1},
|
||||
{0x22, 1},
|
||||
{0x128, 1},
|
||||
/* System Control */
|
||||
{0x33, 1},
|
||||
{0x37, 1},
|
||||
/* PIT */
|
||||
{0x71, 1},
|
||||
{0x73, 1},
|
||||
{0x75, 1},
|
||||
{0x77, 1},
|
||||
{0x3FD9,1},
|
||||
{0x3FDB,1},
|
||||
{0x3FDD,1},
|
||||
{0x3FDF,1},
|
||||
/* x87 Coprocessor */
|
||||
{0xF8, 8},
|
||||
#else
|
||||
{0x00, 0x20}, /* DMA 1 */
|
||||
{0xC0, 0x20}, /* DMA 2 */
|
||||
{0x80, 0x10}, /* DMA EPAR */
|
||||
|
@ -92,6 +146,7 @@ ADDRESS_USAGE HalpDefaultIoSpace =
|
|||
{0x92, 0x1}, /* System Control Port A */
|
||||
{0x70, 0x2}, /* CMOS */
|
||||
{0xF0, 0x10}, /* x87 Coprocessor */
|
||||
#endif
|
||||
{0xCF8, 0x8}, /* PCI 0 */
|
||||
{0,0},
|
||||
}
|
||||
|
@ -523,7 +578,7 @@ HalpReportResourceUsage(IN PUNICODE_STRING HalName,
|
|||
/* Get the machine's serial number */
|
||||
HalpReportSerialNumber();
|
||||
}
|
||||
#endif
|
||||
#endif /* !_MINIHAL_ */
|
||||
|
||||
INIT_FUNCTION
|
||||
VOID
|
||||
|
@ -614,7 +669,6 @@ HalpGetNMICrashFlag(VOID)
|
|||
ZwClose(Handle);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* !_MINIHAL_ */
|
||||
|
||||
/* EOF */
|
||||
|
||||
|
|
|
@ -411,10 +411,10 @@ HalpGetSystemInterruptVector_Acpi(
|
|||
ULONG
|
||||
NTAPI
|
||||
HalpGetCmosData(
|
||||
IN ULONG BusNumber,
|
||||
IN ULONG SlotNumber,
|
||||
IN PVOID Buffer,
|
||||
IN ULONG Length
|
||||
_In_ ULONG BusNumber,
|
||||
_In_ ULONG SlotNumber,
|
||||
_Out_writes_bytes_(Length) PVOID Buffer,
|
||||
_In_ ULONG Length
|
||||
);
|
||||
|
||||
ULONG
|
||||
|
|
|
@ -59,7 +59,16 @@
|
|||
#include "bus.h"
|
||||
#include "halirq.h"
|
||||
#include "haldma.h"
|
||||
#if defined(SARCH_PC98)
|
||||
#include <drivers/pc98/cpu.h>
|
||||
#include <drivers/pc98/pic.h>
|
||||
#include <drivers/pc98/pit.h>
|
||||
#include <drivers/pc98/rtc.h>
|
||||
#include <drivers/pc98/sysport.h>
|
||||
#include <drivers/pc98/video.h>
|
||||
#else
|
||||
#include "halhw.h"
|
||||
#endif
|
||||
#include "halp.h"
|
||||
#include "mps.h"
|
||||
#include "halacpi.h"
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
//
|
||||
// Video Modes for INT10h AH=00 (in AL)
|
||||
//
|
||||
#define GRAPHICS_MODE_12 0x12 /* 80x30 8x16 640x480 16/256K */
|
||||
#define GRAPHICS_MODE_12 0x12 /* 80x30 8x16 640x480 16/256K */
|
||||
|
||||
#if defined(SARCH_XBOX)
|
||||
//
|
||||
|
@ -152,6 +152,10 @@ typedef union _SYSTEM_CONTROL_PORT_B_REGISTER
|
|||
#define PIC2_CONTROL_PORT 0xA0
|
||||
#define PIC2_DATA_PORT 0xA1
|
||||
|
||||
#define PIC_TIMER_IRQ 0
|
||||
#define PIC_CASCADE_IRQ 2
|
||||
#define PIC_RTC_IRQ 8
|
||||
|
||||
//
|
||||
// Definitions for ICW/OCW Bits
|
||||
//
|
||||
|
@ -304,19 +308,16 @@ typedef union _I8259_OCW3
|
|||
|
||||
typedef union _I8259_ISR
|
||||
{
|
||||
union
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
UCHAR Irq0:1;
|
||||
UCHAR Irq1:1;
|
||||
UCHAR Irq2:1;
|
||||
UCHAR Irq3:1;
|
||||
UCHAR Irq4:1;
|
||||
UCHAR Irq5:1;
|
||||
UCHAR Irq6:1;
|
||||
UCHAR Irq7:1;
|
||||
};
|
||||
UCHAR Irq0:1;
|
||||
UCHAR Irq1:1;
|
||||
UCHAR Irq2:1;
|
||||
UCHAR Irq3:1;
|
||||
UCHAR Irq4:1;
|
||||
UCHAR Irq5:1;
|
||||
UCHAR Irq6:1;
|
||||
UCHAR Irq7:1;
|
||||
};
|
||||
UCHAR Bits;
|
||||
} I8259_ISR, *PI8259_ISR;
|
||||
|
@ -362,15 +363,12 @@ typedef union _EISA_ELCR
|
|||
USHORT Bits;
|
||||
} EISA_ELCR, *PEISA_ELCR;
|
||||
|
||||
typedef struct _PIC_MASK
|
||||
typedef union _PIC_MASK
|
||||
{
|
||||
union
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
UCHAR Master;
|
||||
UCHAR Slave;
|
||||
};
|
||||
USHORT Both;
|
||||
UCHAR Master;
|
||||
UCHAR Slave;
|
||||
};
|
||||
USHORT Both;
|
||||
} PIC_MASK, *PPIC_MASK;
|
||||
|
|
|
@ -378,12 +378,14 @@ HalpInitializeCmos(
|
|||
VOID
|
||||
);
|
||||
|
||||
_Requires_lock_held_(HalpSystemHardwareLock)
|
||||
UCHAR
|
||||
NTAPI
|
||||
HalpReadCmos(
|
||||
IN UCHAR Reg
|
||||
);
|
||||
|
||||
_Requires_lock_held_(HalpSystemHardwareLock)
|
||||
VOID
|
||||
NTAPI
|
||||
HalpWriteCmos(
|
||||
|
@ -394,12 +396,14 @@ HalpWriteCmos(
|
|||
//
|
||||
// Spinlock for protecting CMOS access
|
||||
//
|
||||
_Acquires_lock_(HalpSystemHardwareLock)
|
||||
VOID
|
||||
NTAPI
|
||||
HalpAcquireCmosSpinLock(
|
||||
VOID
|
||||
);
|
||||
|
||||
_Releases_lock_(HalpSystemHardwareLock)
|
||||
VOID
|
||||
NTAPI
|
||||
HalpReleaseCmosSpinLock(
|
||||
|
@ -516,6 +520,30 @@ HalpInitProcessor(
|
|||
IN PLOADER_PARAMETER_BLOCK LoaderBlock
|
||||
);
|
||||
|
||||
#if defined(SARCH_PC98)
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
HalpDismissIrq08(
|
||||
_In_ KIRQL Irql,
|
||||
_In_ ULONG Irq,
|
||||
_Out_ PKIRQL OldIrql
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
HalpDismissIrq08Level(
|
||||
_In_ KIRQL Irql,
|
||||
_In_ ULONG Irq,
|
||||
_Out_ PKIRQL OldIrql
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalpInitializeClockPc98(VOID);
|
||||
|
||||
extern ULONG PIT_FREQUENCY;
|
||||
#endif /* SARCH_PC98 */
|
||||
|
||||
#ifdef _M_AMD64
|
||||
|
||||
VOID
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* PROJECT: ReactOS HAL
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: hal/halx86/legacy/halpcat.c
|
||||
* PURPOSE: HAL Legacy Support Code
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
*/
|
||||
|
@ -9,6 +8,7 @@
|
|||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
@ -28,6 +28,9 @@ BOOLEAN HalDisableFirmwareMapper = FALSE;
|
|||
#if defined(SARCH_XBOX)
|
||||
PWCHAR HalHardwareIdString = L"xbox";
|
||||
PWCHAR HalName = L"Xbox HAL";
|
||||
#elif defined(SARCH_PC98)
|
||||
PWCHAR HalHardwareIdString = L"pc98_up";
|
||||
PWCHAR HalName = L"NEC PC-98 Compatible NESA/C-Bus HAL";
|
||||
#else
|
||||
PWCHAR HalHardwareIdString = L"e_isa_up";
|
||||
PWCHAR HalName = L"PC Compatible Eisa/Isa HAL";
|
||||
|
@ -51,7 +54,7 @@ HalpBuildAddressMap(VOID)
|
|||
{
|
||||
/* FIXME: Inherit ROM blocks from the registry */
|
||||
//HalpInheritROMBlocks();
|
||||
|
||||
|
||||
/* FIXME: Add the ROM blocks to our ranges */
|
||||
//HalpAddROMRanges();
|
||||
}
|
||||
|
|
|
@ -7,16 +7,12 @@ list(APPEND MINI_HAL_SOURCE
|
|||
../legacy/bus/pcibus.c
|
||||
../legacy/bus/sysbus.c
|
||||
../legacy/bussupp.c
|
||||
../generic/beep.c
|
||||
../generic/bios.c
|
||||
../generic/clock.c
|
||||
../generic/cmos.c
|
||||
../generic/dma.c
|
||||
../generic/display.c
|
||||
../generic/drive.c
|
||||
../generic/misc.c
|
||||
../generic/profil.c
|
||||
../generic/reboot.c
|
||||
../generic/nmi.c
|
||||
../generic/spinlock.c
|
||||
../generic/sysinfo.c
|
||||
../generic/timer.c
|
||||
|
@ -26,6 +22,29 @@ list(APPEND MINI_HAL_SOURCE
|
|||
../up/processor.c
|
||||
../include/hal.h)
|
||||
|
||||
if(SARCH STREQUAL "xbox")
|
||||
list(APPEND MINI_HAL_SOURCE
|
||||
../generic/beep.c
|
||||
../generic/cmos.c
|
||||
../generic/profil.c
|
||||
../xbox/clock.c
|
||||
../xbox/reboot.c)
|
||||
elseif(SARCH STREQUAL "pc98")
|
||||
list(APPEND MINI_HAL_SOURCE
|
||||
../pc98/beep.c
|
||||
../pc98/clock.c
|
||||
../pc98/cmos.c
|
||||
../pc98/profil.c
|
||||
../pc98/reboot.c)
|
||||
else()
|
||||
list(APPEND MINI_HAL_SOURCE
|
||||
../generic/beep.c
|
||||
../generic/clock.c
|
||||
../generic/cmos.c
|
||||
../generic/profil.c
|
||||
../generic/reboot.c)
|
||||
endif()
|
||||
|
||||
add_asm_files(mini_hal_asm ../generic/systimer.S)
|
||||
add_library(mini_hal ${MINI_HAL_SOURCE} ${mini_hal_asm})
|
||||
target_compile_definitions(mini_hal PRIVATE _BLDR_ _MINIHAL_)
|
||||
|
|
57
hal/halx86/pc98.cmake
Normal file
57
hal/halx86/pc98.cmake
Normal file
|
@ -0,0 +1,57 @@
|
|||
|
||||
# Generic
|
||||
list(APPEND HAL_PC98_SOURCE
|
||||
pc98/beep.c
|
||||
pc98/clock.c
|
||||
pc98/cmos.c
|
||||
pc98/delay.c
|
||||
pc98/pic.c
|
||||
pc98/profil.c
|
||||
pc98/reboot.c
|
||||
generic/bios.c
|
||||
generic/display.c
|
||||
generic/dma.c
|
||||
generic/drive.c
|
||||
generic/halinit.c
|
||||
generic/memory.c
|
||||
generic/misc.c
|
||||
generic/nmi.c
|
||||
generic/portio.c
|
||||
generic/sysinfo.c
|
||||
generic/usage.c)
|
||||
|
||||
list(APPEND HAL_PC98_ASM_SOURCE
|
||||
generic/v86.S)
|
||||
|
||||
# PIC
|
||||
list(APPEND HAL_PC98_SOURCE
|
||||
pc98/irql.c
|
||||
generic/timer.c
|
||||
up/halinit_up.c
|
||||
up/pic.c)
|
||||
|
||||
list(APPEND HAL_PC98_ASM_SOURCE
|
||||
generic/trap.S
|
||||
up/pic.S)
|
||||
|
||||
# Legacy
|
||||
list(APPEND HAL_PC98_SOURCE
|
||||
legacy/bus/bushndlr.c
|
||||
legacy/bus/cmosbus.c
|
||||
legacy/bus/isabus.c
|
||||
legacy/bus/pcibus.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/pci_classes.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/pci_vendors.c
|
||||
legacy/bus/sysbus.c
|
||||
legacy/bussupp.c
|
||||
legacy/halpnpdd.c
|
||||
legacy/halpcat.c)
|
||||
|
||||
add_asm_files(lib_hal_pc98_asm ${HAL_PC98_ASM_SOURCE})
|
||||
add_object_library(lib_hal_pc98 ${HAL_PC98_SOURCE} ${lib_hal_pc98_asm})
|
||||
add_dependencies(lib_hal_pc98 bugcodes xdk asm)
|
||||
#add_pch(lib_hal_pc98 pc98/halpc98.h)
|
||||
|
||||
if(MSVC)
|
||||
target_link_libraries(lib_hal_pc98)
|
||||
endif()
|
53
hal/halx86/pc98/beep.c
Normal file
53
hal/halx86/pc98/beep.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* PROJECT: NEC PC-98 series HAL
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: Speaker support (beeping)
|
||||
* COPYRIGHT: Copyright 2020 Dmitry Borisov (di.sean@protonmail.com)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
HalMakeBeep(
|
||||
_In_ ULONG Frequency)
|
||||
{
|
||||
TIMER_CONTROL_PORT_REGISTER TimerControl;
|
||||
ULONG Divider;
|
||||
BOOLEAN Success = FALSE;
|
||||
|
||||
HalpAcquireCmosSpinLock();
|
||||
|
||||
__outbyte(PPI_IO_o_CONTROL, PPI_TIMER_1_UNGATE_TO_SPEAKER);
|
||||
|
||||
if (Frequency)
|
||||
{
|
||||
Divider = PIT_FREQUENCY / Frequency;
|
||||
|
||||
if (Divider <= 0x10000)
|
||||
{
|
||||
TimerControl.BcdMode = FALSE;
|
||||
TimerControl.OperatingMode = PitOperatingMode3;
|
||||
TimerControl.Channel = PitChannel1;
|
||||
TimerControl.AccessMode = PitAccessModeLowHigh;
|
||||
__outbyte(TIMER_CONTROL_PORT, TimerControl.Bits);
|
||||
__outbyte(TIMER_CHANNEL1_DATA_PORT, FIRSTBYTE(Divider));
|
||||
__outbyte(TIMER_CHANNEL1_DATA_PORT, SECONDBYTE(Divider));
|
||||
|
||||
__outbyte(PPI_IO_o_CONTROL, PPI_TIMER_1_GATE_TO_SPEAKER);
|
||||
|
||||
Success = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
HalpReleaseCmosSpinLock();
|
||||
|
||||
return Success;
|
||||
}
|
75
hal/halx86/pc98/clock.c
Normal file
75
hal/halx86/pc98/clock.c
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* PROJECT: NEC PC-98 series HAL
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: PIT rollover tables
|
||||
* COPYRIGHT: Copyright 2020 Dmitry Borisov (di.sean@protonmail.com)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
#define LPT_STATUS 0x42
|
||||
#define SYSTEM_CLOCK_8_MHZ 0x20
|
||||
|
||||
ULONG PIT_FREQUENCY;
|
||||
HALP_ROLLOVER HalpRolloverTable[15];
|
||||
|
||||
/* Accuracy is 97.5% */
|
||||
static const HALP_ROLLOVER RolloverTable1[15] =
|
||||
{
|
||||
{1996, 9996}, /* 1 ms */
|
||||
{3993, 19997},
|
||||
{5990, 29998},
|
||||
{7987, 39999},
|
||||
{9984, 50000},
|
||||
{11980, 59996},
|
||||
{13977, 69997},
|
||||
{15974, 79998},
|
||||
{17971, 89999},
|
||||
{19968, 100000},
|
||||
{21964, 109996},
|
||||
{23961, 119997},
|
||||
{25958, 129998},
|
||||
{27955, 139999},
|
||||
{29951, 149995} /* 15 ms */
|
||||
};
|
||||
static const HALP_ROLLOVER RolloverTable2[15] =
|
||||
{
|
||||
{2463, 10022}, /* 1 ms */
|
||||
{4912, 19987},
|
||||
{7376, 30013},
|
||||
{9825, 39978},
|
||||
{12288, 50000},
|
||||
{14751, 60022},
|
||||
{17200, 69987},
|
||||
{19664, 80013},
|
||||
{22113, 89978},
|
||||
{24576, 100000},
|
||||
{27039, 110022},
|
||||
{29488, 119987},
|
||||
{31952, 130013},
|
||||
{34401, 139978},
|
||||
{36864, 150000} /* 15 ms */
|
||||
};
|
||||
|
||||
/* PRIVATE FUNCTIONS *********************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalpInitializeClockPc98(VOID)
|
||||
{
|
||||
/* Obtain system clock value from the parallel port */
|
||||
if (__inbyte(LPT_STATUS) & SYSTEM_CLOCK_8_MHZ)
|
||||
{
|
||||
PIT_FREQUENCY = TIMER_FREQUENCY_1;
|
||||
RtlCopyMemory(HalpRolloverTable, RolloverTable1, sizeof(HALP_ROLLOVER) * 15);
|
||||
}
|
||||
else
|
||||
{
|
||||
PIT_FREQUENCY = TIMER_FREQUENCY_2;
|
||||
RtlCopyMemory(HalpRolloverTable, RolloverTable2, sizeof(HALP_ROLLOVER) * 15);
|
||||
}
|
||||
}
|
322
hal/halx86/pc98/cmos.c
Normal file
322
hal/halx86/pc98/cmos.c
Normal file
|
@ -0,0 +1,322 @@
|
|||
/*
|
||||
* PROJECT: NEC PC-98 series HAL
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: RTC and NVRAM access routines
|
||||
* COPYRIGHT: Copyright 2020 Dmitry Borisov (di.sean@protonmail.com)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#if defined(ALLOC_PRAGMA) && !defined(_MINIHAL_)
|
||||
#pragma alloc_text(INIT, HalpInitializeCmos)
|
||||
#endif
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
/*
|
||||
* The PC-98 hardware maps data from the NVRAM directly into the text video
|
||||
* memory address space. Every fourth byte is a "writable data".
|
||||
*
|
||||
* |0x2FE2|0x2FE3|0x2FE4|0x2FE5|0x2FE6|0x2FE7| .... |0x2FFD|0x2FFE|
|
||||
* | D | | | | D | | .... | | D |
|
||||
*
|
||||
* Most of these bits of the NVRAM are already used. There are some reserved
|
||||
* bits in the 0x3FE6 and 0x3FFE that we can use.
|
||||
*/
|
||||
#define NVRAM_START 0x3FE2
|
||||
#define NVRAM_SIZE 0x1C
|
||||
#define NVRAM_UNUSED_REG 0x14
|
||||
#define NVRAM_UNUSED_BIT 0x80
|
||||
|
||||
static ULONG_PTR MappedNvram;
|
||||
|
||||
/* PRIVATE FUNCTIONS *********************************************************/
|
||||
|
||||
/* Avoid double calls */
|
||||
#undef BCD_INT
|
||||
static UCHAR
|
||||
BCD_INT(
|
||||
_In_ UCHAR Bcd)
|
||||
{
|
||||
return ((Bcd & 0xF0) >> 4) * 10 + (Bcd & 0x0F);
|
||||
}
|
||||
|
||||
static UCHAR
|
||||
NTAPI
|
||||
HalpReadNvram(
|
||||
_In_ UCHAR Register)
|
||||
{
|
||||
return READ_REGISTER_UCHAR((PUCHAR)(MappedNvram + Register));
|
||||
}
|
||||
|
||||
_Requires_lock_held_(HalpSystemHardwareLock)
|
||||
static VOID
|
||||
NTAPI
|
||||
HalpWriteNvram(
|
||||
_In_ UCHAR Register,
|
||||
_In_ UCHAR Value)
|
||||
{
|
||||
__outbyte(GDC1_IO_o_MODE_FLIPFLOP1, GDC1_NVRAM_UNPROTECT);
|
||||
WRITE_REGISTER_UCHAR((PUCHAR)(MappedNvram + Register), Value);
|
||||
__outbyte(GDC1_IO_o_MODE_FLIPFLOP1, GDC1_NVRAM_PROTECT);
|
||||
}
|
||||
|
||||
_Requires_lock_held_(HalpSystemHardwareLock)
|
||||
static UCHAR
|
||||
NTAPI
|
||||
HalpRtcReadByte(VOID)
|
||||
{
|
||||
UCHAR i;
|
||||
UCHAR Byte = 0;
|
||||
|
||||
/* Read byte from single wire bus */
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
Byte |= (__inbyte(PPI_IO_i_PORT_B) & 1) << i;
|
||||
|
||||
__outbyte(RTC_IO_o_DATA, RTC_CLOCK | RTC_CMD_SERIAL_TRANSFER_MODE);
|
||||
KeStallExecutionProcessor(1);
|
||||
|
||||
__outbyte(RTC_IO_o_DATA, RTC_CMD_SERIAL_TRANSFER_MODE);
|
||||
KeStallExecutionProcessor(1);
|
||||
}
|
||||
|
||||
return Byte;
|
||||
}
|
||||
|
||||
_Requires_lock_held_(HalpSystemHardwareLock)
|
||||
static VOID
|
||||
NTAPI
|
||||
HalpRtcWriteBit(
|
||||
_In_ UCHAR Bit)
|
||||
{
|
||||
Bit = (Bit & 1) << 5;
|
||||
|
||||
__outbyte(RTC_IO_o_DATA, Bit | RTC_CMD_SERIAL_TRANSFER_MODE);
|
||||
KeStallExecutionProcessor(1);
|
||||
|
||||
__outbyte(RTC_IO_o_DATA, Bit | RTC_CLOCK | RTC_CMD_SERIAL_TRANSFER_MODE);
|
||||
KeStallExecutionProcessor(1);
|
||||
}
|
||||
|
||||
_Requires_lock_held_(HalpSystemHardwareLock)
|
||||
static VOID
|
||||
NTAPI
|
||||
HalpRtcWriteCommand(
|
||||
_In_ UCHAR Command)
|
||||
{
|
||||
UCHAR i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
HalpRtcWriteBit(Command >> i);
|
||||
|
||||
__outbyte(RTC_IO_o_DATA, RTC_STROBE | RTC_CMD_SERIAL_TRANSFER_MODE);
|
||||
KeStallExecutionProcessor(1);
|
||||
|
||||
__outbyte(RTC_IO_o_DATA, RTC_CMD_SERIAL_TRANSFER_MODE);
|
||||
KeStallExecutionProcessor(1);
|
||||
}
|
||||
|
||||
UCHAR
|
||||
NTAPI
|
||||
HalpReadCmos(
|
||||
_In_ UCHAR Reg)
|
||||
{
|
||||
/* Not supported by hardware */
|
||||
return 0;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalpWriteCmos(
|
||||
_In_ UCHAR Reg,
|
||||
_In_ UCHAR Value)
|
||||
{
|
||||
/* Not supported by hardware */
|
||||
NOTHING;
|
||||
}
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
HalpGetCmosData(
|
||||
_In_ ULONG BusNumber,
|
||||
_In_ ULONG SlotNumber,
|
||||
_Out_writes_bytes_(Length) PVOID Buffer,
|
||||
_In_ ULONG Length)
|
||||
{
|
||||
/* Not supported by hardware */
|
||||
return 0;
|
||||
}
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
HalpSetCmosData(
|
||||
_In_ ULONG BusNumber,
|
||||
_In_ ULONG SlotNumber,
|
||||
_In_reads_bytes_(Length) PVOID Buffer,
|
||||
_In_ ULONG Length)
|
||||
{
|
||||
/* Not supported by hardware */
|
||||
return 0;
|
||||
}
|
||||
|
||||
INIT_FUNCTION
|
||||
VOID
|
||||
NTAPI
|
||||
HalpInitializeCmos(VOID)
|
||||
{
|
||||
PHYSICAL_ADDRESS PhysicalAddress;
|
||||
|
||||
/* TODO: Detect TVRAM address */
|
||||
if (TRUE)
|
||||
PhysicalAddress.QuadPart = VRAM_NORMAL_TEXT + NVRAM_START;
|
||||
else
|
||||
PhysicalAddress.QuadPart = VRAM_HI_RESO_TEXT + NVRAM_START;
|
||||
MappedNvram = (ULONG_PTR)HalpMapPhysicalMemory64(PhysicalAddress, BYTES_TO_PAGES(NVRAM_SIZE));
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS **********************************************************/
|
||||
|
||||
ARC_STATUS
|
||||
NTAPI
|
||||
HalGetEnvironmentVariable(
|
||||
_In_ PCH Name,
|
||||
_In_ USHORT ValueLength,
|
||||
_Out_writes_z_(ValueLength) PCH Value)
|
||||
{
|
||||
UCHAR Val;
|
||||
|
||||
/* Only variable supported on x86 */
|
||||
if (_stricmp(Name, "LastKnownGood"))
|
||||
return ENOENT;
|
||||
|
||||
if (!MappedNvram)
|
||||
return ENOENT;
|
||||
|
||||
HalpAcquireCmosSpinLock();
|
||||
|
||||
Val = HalpReadNvram(NVRAM_UNUSED_REG) & NVRAM_UNUSED_BIT;
|
||||
|
||||
HalpReleaseCmosSpinLock();
|
||||
|
||||
/* Check the flag */
|
||||
if (Val)
|
||||
strncpy(Value, "FALSE", ValueLength);
|
||||
else
|
||||
strncpy(Value, "TRUE", ValueLength);
|
||||
|
||||
return ESUCCESS;
|
||||
}
|
||||
|
||||
ARC_STATUS
|
||||
NTAPI
|
||||
HalSetEnvironmentVariable(
|
||||
_In_ PCH Name,
|
||||
_In_ PCH Value)
|
||||
{
|
||||
UCHAR Val;
|
||||
|
||||
/* Only variable supported on x86 */
|
||||
if (_stricmp(Name, "LastKnownGood"))
|
||||
return ENOMEM;
|
||||
|
||||
if (!MappedNvram)
|
||||
return ENOMEM;
|
||||
|
||||
/* Check if this is true or false */
|
||||
if (!_stricmp(Value, "TRUE"))
|
||||
{
|
||||
HalpAcquireCmosSpinLock();
|
||||
|
||||
Val = HalpReadNvram(NVRAM_UNUSED_REG) | NVRAM_UNUSED_BIT;
|
||||
}
|
||||
else if (!_stricmp(Value, "FALSE"))
|
||||
{
|
||||
HalpAcquireCmosSpinLock();
|
||||
|
||||
Val = HalpReadNvram(NVRAM_UNUSED_REG) & ~NVRAM_UNUSED_BIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Fail */
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
HalpWriteNvram(NVRAM_UNUSED_REG, Val);
|
||||
|
||||
HalpReleaseCmosSpinLock();
|
||||
|
||||
return ESUCCESS;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
HalQueryRealTimeClock(
|
||||
_Out_ PTIME_FIELDS Time)
|
||||
{
|
||||
UCHAR Temp;
|
||||
|
||||
HalpAcquireCmosSpinLock();
|
||||
|
||||
HalpRtcWriteCommand(RTC_CMD_TIME_READ);
|
||||
HalpRtcWriteCommand(RTC_CMD_REGISTER_SHIFT);
|
||||
KeStallExecutionProcessor(19);
|
||||
|
||||
/* Set the time data */
|
||||
Time->Second = BCD_INT(HalpRtcReadByte());
|
||||
Time->Minute = BCD_INT(HalpRtcReadByte());
|
||||
Time->Hour = BCD_INT(HalpRtcReadByte());
|
||||
Time->Day = BCD_INT(HalpRtcReadByte());
|
||||
Temp = HalpRtcReadByte();
|
||||
Time->Weekday = Temp & 0x0F;
|
||||
Time->Month = Temp >> 4;
|
||||
Time->Year = BCD_INT(HalpRtcReadByte());
|
||||
Time->Milliseconds = 0;
|
||||
|
||||
Time->Year += (Time->Year >= 80) ? 1900 : 2000;
|
||||
|
||||
HalpRtcWriteCommand(RTC_CMD_REGISTER_HOLD);
|
||||
|
||||
HalpReleaseCmosSpinLock();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
HalSetRealTimeClock(
|
||||
_In_ PTIME_FIELDS Time)
|
||||
{
|
||||
UCHAR i, j;
|
||||
UCHAR SysTime[6];
|
||||
|
||||
HalpAcquireCmosSpinLock();
|
||||
|
||||
HalpRtcWriteCommand(RTC_CMD_REGISTER_SHIFT);
|
||||
|
||||
SysTime[0] = INT_BCD(Time->Second);
|
||||
SysTime[1] = INT_BCD(Time->Minute);
|
||||
SysTime[2] = INT_BCD(Time->Hour);
|
||||
SysTime[3] = INT_BCD(Time->Day);
|
||||
SysTime[4] = (Time->Month << 4) | (Time->Weekday & 0x0F);
|
||||
SysTime[5] = INT_BCD(Time->Year % 100);
|
||||
|
||||
/* Write time fields to RTC */
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
for (j = 0; j < 8; j++)
|
||||
HalpRtcWriteBit(SysTime[i] >> j);
|
||||
}
|
||||
|
||||
HalpRtcWriteCommand(RTC_CMD_TIME_SET_COUNTER_HOLD);
|
||||
HalpRtcWriteCommand(RTC_CMD_REGISTER_HOLD);
|
||||
|
||||
HalpReleaseCmosSpinLock();
|
||||
|
||||
return TRUE;
|
||||
}
|
39
hal/halx86/pc98/delay.c
Normal file
39
hal/halx86/pc98/delay.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* PROJECT: NEC PC-98 series HAL
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: Delay routines
|
||||
* COPYRIGHT: Copyright 2020 Dmitry Borisov (di.sean@protonmail.com)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* PRIVATE FUNCTIONS *********************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalpCalibrateStallExecution(VOID)
|
||||
{
|
||||
/* FIXME */
|
||||
NOTHING;
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS **********************************************************/
|
||||
|
||||
#ifndef _MINIHAL_
|
||||
VOID
|
||||
NTAPI
|
||||
KeStallExecutionProcessor(
|
||||
_In_ ULONG MicroSeconds)
|
||||
{
|
||||
while (MicroSeconds--)
|
||||
{
|
||||
/* FIXME: Use stall factor */
|
||||
WRITE_PORT_UCHAR((PUCHAR)CPU_IO_o_ARTIC_DELAY, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
9
hal/halx86/pc98/halpc98.rc
Normal file
9
hal/halx86/pc98/halpc98.rc
Normal file
|
@ -0,0 +1,9 @@
|
|||
#define REACTOS_VERSION_DLL
|
||||
#if defined(CONFIG_SMP)
|
||||
// #define REACTOS_STR_FILE_DESCRIPTION "NEC PC-98 series Multiprocessor Hardware Abstraction Layer"
|
||||
#else
|
||||
#define REACTOS_STR_FILE_DESCRIPTION "NEC PC-98 series Uniprocessor Hardware Abstraction Layer"
|
||||
#endif
|
||||
#define REACTOS_STR_INTERNAL_NAME "halpc98"
|
||||
#define REACTOS_STR_ORIGINAL_FILENAME "halpc98.dll"
|
||||
#include <reactos/version.rc>
|
121
hal/halx86/pc98/irql.c
Normal file
121
hal/halx86/pc98/irql.c
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* PROJECT: NEC PC-98 series HAL
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: IRQL mapping
|
||||
* COPYRIGHT: Copyright 2020 Dmitry Borisov (di.sean@protonmail.com)
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
/* This table contains the static x86 PIC mapping between IRQLs and IRQs */
|
||||
ULONG KiI8259MaskTable[32] =
|
||||
{
|
||||
/*
|
||||
* See comments of the PC/AT version.
|
||||
*/
|
||||
0b00000000000000000000000000000000, /* IRQL 0 */
|
||||
0b00000000000000000000000000000000, /* IRQL 1 */
|
||||
0b00000000000000000000000000000000, /* IRQL 2 */
|
||||
0b00000000000000000000000000000000, /* IRQL 3 */
|
||||
0b11111111100000000000000000000000, /* IRQL 4 */
|
||||
0b11111111110000000000000000000000, /* IRQL 5 */
|
||||
0b11111111111000000000000000000000, /* IRQL 6 */
|
||||
0b11111111111100000000000000000000, /* IRQL 7 */
|
||||
0b11111111111110000000000000000000, /* IRQL 8 */
|
||||
0b11111111111111000000000000000000, /* IRQL 9 */
|
||||
0b11111111111111100000000000000000, /* IRQL 10 */
|
||||
0b11111111111111110000000000000000, /* IRQL 11 */
|
||||
|
||||
/*
|
||||
* Okay, now we're finally starting to mask off IRQs on the slave PIC, from
|
||||
* IRQ15 to IRQ8. Note that the output of INT of RTC is connected to the IR7.
|
||||
* We need to keep this IRQ unmasked, so we can ensure profiling the whole system.
|
||||
*/
|
||||
0b11111111111111110000000000000000, /* IRQL 12 */
|
||||
0b11111111111111110100000000000000, /* IRQL 13 */
|
||||
0b11111111111111110110000000000000, /* IRQL 14 */
|
||||
0b11111111111111110111000000000000, /* IRQL 15 */
|
||||
0b11111111111111110111100000000000, /* IRQL 16 */
|
||||
0b11111111111111110111110000000000, /* IRQL 17 */
|
||||
0b11111111111111110111111000000000, /* IRQL 18 */
|
||||
0b11111111111111110111111000000000, /* IRQL 19 */
|
||||
|
||||
/*
|
||||
* Now we mask off the IRQs on the master. Since IRQL 19 we have 0 "droplet".
|
||||
* It's the cascade IRQ that we use to bridge the slave PIC with the master PIC.
|
||||
*/
|
||||
0b11111111111111110111111100000000, /* IRQL 20 */
|
||||
0b11111111111111110111111101000000, /* IRQL 21 */
|
||||
0b11111111111111110111111101100000, /* IRQL 22 */
|
||||
0b11111111111111110111111101110000, /* IRQL 23 */
|
||||
0b11111111111111110111111101111000, /* IRQL 24 */
|
||||
0b11111111111111110111111101111100, /* IRQL 25 */
|
||||
0b11111111111111110111111101111110, /* IRQL 26 */
|
||||
0b11111111111111111111111101111110, /* IRQL 27 */
|
||||
|
||||
/*
|
||||
* See comments of the PC/AT version.
|
||||
*/
|
||||
0b11111111111111111111111101111111, /* IRQL 28 */
|
||||
0b11111111111111111111111101111111, /* IRQL 29 */
|
||||
0b11111111111111111111111101111111, /* IRQL 30 */
|
||||
0b11111111111111111111111101111111 /* IRQL 31 */
|
||||
};
|
||||
|
||||
/* This table indicates which IRQs, if pending, can preempt a given IRQL level */
|
||||
ULONG FindHigherIrqlMask[32] =
|
||||
{
|
||||
/*
|
||||
* See comments of the PC/AT version.
|
||||
*/
|
||||
0b11111111111111111111111111111110, /* IRQL 0 */
|
||||
0b11111111111111111111111111111100, /* IRQL 1 */
|
||||
0b11111111111111111111111111111000, /* IRQL 2 */
|
||||
0b11111111111111111111111111110000, /* IRQL 3 */
|
||||
0b00000111111111111111111111110000, /* IRQL 4 */
|
||||
0b00000011111111111111111111110000, /* IRQL 5 */
|
||||
0b00000001111111111111111111110000, /* IRQL 6 */
|
||||
0b00000000111111111111111111110000, /* IRQL 7 */
|
||||
0b00000000011111111111111111110000, /* IRQL 8 */
|
||||
0b00000000001111111111111111110000, /* IRQL 9 */
|
||||
0b00000000000111111111111111110000, /* IRQL 10 */
|
||||
|
||||
/*
|
||||
* Now we start progressivly limiting which slave PIC interrupts have the
|
||||
* right to preempt us at each level. The RTC timer used for profiling,
|
||||
* so it will always preempt until we reach PROFILE_LEVEL.
|
||||
*/
|
||||
0b00000000000011111111111111110000, /* IRQL 11 */
|
||||
0b00000000000011111111111111110000, /* IRQL 12 */
|
||||
0b00000000000010111111111111110000, /* IRQL 13 */
|
||||
0b00000000000010011111111111110000, /* IRQL 14 */
|
||||
0b00000000000010001111111111110000, /* IRQL 15 */
|
||||
0b00000000000010000111111111110000, /* IRQL 16 */
|
||||
0b00000000000010000011111111110000, /* IRQL 17 */
|
||||
0b00000000000010000001111111110000, /* IRQL 18 */
|
||||
0b00000000000010000001111111110000, /* IRQL 19 */
|
||||
|
||||
/*
|
||||
* Now with IRQs on the master PIC.
|
||||
*/
|
||||
0b00000000000010000000011111110000, /* IRQL 20 */
|
||||
0b00000000000010000000001111110000, /* IRQL 21 */
|
||||
0b00000000000010000000000111110000, /* IRQL 22 */
|
||||
0b00000000000010000000000011110000, /* IRQL 23 */
|
||||
0b00000000000010000000000001110000, /* IRQL 24 */
|
||||
0b00000000000010000000000000110000, /* IRQL 25 */
|
||||
0b00000000000010000000000000010000, /* IRQL 26 */
|
||||
|
||||
/*
|
||||
* See comments of the PC/AT version.
|
||||
*/
|
||||
0b00000000000000000000000000010000, /* IRQL 27 */
|
||||
0b00000000000000000000000000000000, /* IRQL 28 */
|
||||
0b00000000000000000000000000000000, /* IRQL 29 */
|
||||
0b00000000000000000000000000000000, /* IRQL 30 */
|
||||
0b00000000000000000000000000000000 /* IRQL 31 */
|
||||
};
|
105
hal/halx86/pc98/pic.c
Normal file
105
hal/halx86/pc98/pic.c
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* PROJECT: NEC PC-98 series HAL
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: PIC initialization
|
||||
* COPYRIGHT: Copyright 2020 Dmitry Borisov (di.sean@protonmail.com)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
|
||||
/* PRIVATE FUNCTIONS *********************************************************/
|
||||
|
||||
static VOID
|
||||
HalpIoWait(VOID)
|
||||
{
|
||||
UCHAR i;
|
||||
|
||||
/*
|
||||
* Give the old PICs enough time to react to commands.
|
||||
* (KeStallExecutionProcessor is not available at this stage)
|
||||
*/
|
||||
for (i = 0; i < 6; i++)
|
||||
__outbyte(CPU_IO_o_ARTIC_DELAY, 0);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalpInitializeLegacyPICs(VOID)
|
||||
{
|
||||
I8259_ICW1 Icw1;
|
||||
I8259_ICW2 Icw2;
|
||||
I8259_ICW3 Icw3;
|
||||
I8259_ICW4 Icw4;
|
||||
|
||||
ASSERT(!(__readeflags() & EFLAGS_INTERRUPT_MASK));
|
||||
|
||||
/* Initialize ICW1 for master, interval 8, edge-triggered mode with ICW4 */
|
||||
Icw1.NeedIcw4 = TRUE;
|
||||
Icw1.OperatingMode = Cascade;
|
||||
Icw1.Interval = Interval8;
|
||||
Icw1.InterruptMode = EdgeTriggered;
|
||||
Icw1.Init = TRUE;
|
||||
Icw1.InterruptVectorAddress = 0;
|
||||
__outbyte(PIC1_CONTROL_PORT, Icw1.Bits);
|
||||
HalpIoWait();
|
||||
|
||||
/* ICW2 - interrupt vector offset */
|
||||
Icw2.Bits = PRIMARY_VECTOR_BASE;
|
||||
__outbyte(PIC1_DATA_PORT, Icw2.Bits);
|
||||
HalpIoWait();
|
||||
|
||||
/* Connect slave to cascade IRQ */
|
||||
Icw3.Bits = 0;
|
||||
Icw3.SlaveIrq7 = TRUE;
|
||||
__outbyte(PIC1_DATA_PORT, Icw3.Bits);
|
||||
HalpIoWait();
|
||||
|
||||
/* Enable 8086 mode, non-automatic EOI, buffered mode, special fully nested mode */
|
||||
Icw4.SystemMode = New8086Mode;
|
||||
Icw4.EoiMode = NormalEoi;
|
||||
Icw4.BufferedMode = BufferedMaster;
|
||||
Icw4.SpecialFullyNestedMode = TRUE;
|
||||
Icw4.Reserved = 0;
|
||||
__outbyte(PIC1_DATA_PORT, Icw4.Bits);
|
||||
HalpIoWait();
|
||||
|
||||
/* Mask all interrupts */
|
||||
__outbyte(PIC1_DATA_PORT, 0xFF);
|
||||
HalpIoWait();
|
||||
|
||||
/* Initialize ICW1 for slave, interval 8, edge-triggered mode with ICW4 */
|
||||
Icw1.NeedIcw4 = TRUE;
|
||||
Icw1.InterruptMode = EdgeTriggered;
|
||||
Icw1.OperatingMode = Cascade;
|
||||
Icw1.Interval = Interval8;
|
||||
Icw1.Init = TRUE;
|
||||
Icw1.InterruptVectorAddress = 0; /* This is only used in MCS80/85 mode */
|
||||
__outbyte(PIC2_CONTROL_PORT, Icw1.Bits);
|
||||
HalpIoWait();
|
||||
|
||||
/* Set interrupt vector base */
|
||||
Icw2.Bits = PRIMARY_VECTOR_BASE + 8;
|
||||
__outbyte(PIC2_DATA_PORT, Icw2.Bits);
|
||||
HalpIoWait();
|
||||
|
||||
/* Slave ID */
|
||||
Icw3.Bits = 0;
|
||||
Icw3.SlaveId = PIC_CASCADE_IRQ;
|
||||
__outbyte(PIC2_DATA_PORT, Icw3.Bits);
|
||||
HalpIoWait();
|
||||
|
||||
/* Enable 8086 mode, non-automatic EOI, buffered mode, non special fully nested mode */
|
||||
Icw4.SystemMode = New8086Mode;
|
||||
Icw4.EoiMode = NormalEoi;
|
||||
Icw4.BufferedMode = BufferedSlave;
|
||||
Icw4.SpecialFullyNestedMode = FALSE;
|
||||
Icw4.Reserved = 0;
|
||||
__outbyte(PIC2_DATA_PORT, Icw4.Bits);
|
||||
HalpIoWait();
|
||||
|
||||
/* Mask all interrupts */
|
||||
__outbyte(PIC2_DATA_PORT, 0xFF);
|
||||
HalpIoWait();
|
||||
}
|
74
hal/halx86/pc98/profil.c
Normal file
74
hal/halx86/pc98/profil.c
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* PROJECT: NEC PC-98 series HAL
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: System Profiling
|
||||
* COPYRIGHT: Copyright 2020 Dmitry Borisov (di.sean@protonmail.com)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
BOOLEAN HalpProfilingStopped = TRUE;
|
||||
UCHAR HalpProfileRate = 3;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalStopProfileInterrupt(
|
||||
_In_ KPROFILE_SOURCE ProfileSource)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ProfileSource);
|
||||
|
||||
HalpAcquireCmosSpinLock();
|
||||
|
||||
/* Clear the interrupt flag */
|
||||
(VOID)__inbyte(RTC_IO_i_INTERRUPT_RESET);
|
||||
|
||||
HalpProfilingStopped = TRUE;
|
||||
|
||||
HalpReleaseCmosSpinLock();
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalStartProfileInterrupt(
|
||||
_In_ KPROFILE_SOURCE ProfileSource)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ProfileSource);
|
||||
|
||||
HalpProfilingStopped = FALSE;
|
||||
|
||||
HalpAcquireCmosSpinLock();
|
||||
|
||||
/* Configure the clock divisor for generating periodic interrupts */
|
||||
__outbyte(RTC_IO_o_INT_CLOCK_DIVISOR, HalpProfileRate | 0x80);
|
||||
|
||||
HalpReleaseCmosSpinLock();
|
||||
}
|
||||
|
||||
ULONG_PTR
|
||||
NTAPI
|
||||
HalSetProfileInterval(
|
||||
_In_ ULONG_PTR Interval)
|
||||
{
|
||||
/*
|
||||
* FIXME:
|
||||
* 1) What is the maximum and minimum interrupt frequency for the RTC?
|
||||
* 2) Find the maximum possible clock divisor value.
|
||||
*/
|
||||
UNIMPLEMENTED;
|
||||
|
||||
/* Update interval */
|
||||
if (!HalpProfilingStopped)
|
||||
HalStartProfileInterrupt(0);
|
||||
|
||||
/* For now... */
|
||||
return Interval;
|
||||
}
|
75
hal/halx86/pc98/reboot.c
Normal file
75
hal/halx86/pc98/reboot.c
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* PROJECT: NEC PC-98 series HAL
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: Reboot routine
|
||||
* COPYRIGHT: Copyright 2020 Dmitry Borisov (di.sean@protonmail.com)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* PRIVATE FUNCTIONS *********************************************************/
|
||||
|
||||
static VOID
|
||||
DECLSPEC_NORETURN
|
||||
NTAPI
|
||||
HalpFreezeSystem(VOID)
|
||||
{
|
||||
HaliHaltSystem();
|
||||
|
||||
while (TRUE)
|
||||
NOTHING;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalpReboot(VOID)
|
||||
{
|
||||
/* Disable interrupts */
|
||||
_disable();
|
||||
|
||||
/* Flush write buffers */
|
||||
KeFlushWriteBuffer();
|
||||
|
||||
/* Send the reset command */
|
||||
WRITE_PORT_UCHAR((PUCHAR)PPI_IO_o_CONTROL, PPI_SHUTDOWN_0_ENABLE);
|
||||
WRITE_PORT_UCHAR((PUCHAR)PPI_IO_o_CONTROL, PPI_SHUTDOWN_1_ENABLE);
|
||||
WRITE_PORT_UCHAR((PUCHAR)CPU_IO_o_RESET, 0);
|
||||
|
||||
/* Halt the CPU */
|
||||
__halt();
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS **********************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalReturnToFirmware(
|
||||
_In_ FIRMWARE_REENTRY Action)
|
||||
{
|
||||
switch (Action)
|
||||
{
|
||||
case HalPowerDownRoutine:
|
||||
HalpFreezeSystem();
|
||||
|
||||
case HalHaltRoutine:
|
||||
case HalRebootRoutine:
|
||||
#ifndef _MINIHAL_
|
||||
/* Acquire the display */
|
||||
InbvAcquireDisplayOwnership();
|
||||
#endif
|
||||
|
||||
/* Call the internal reboot function */
|
||||
HalpReboot();
|
||||
|
||||
/* Anything else */
|
||||
default:
|
||||
/* Print message and break */
|
||||
DbgPrint("HalReturnToFirmware called!\n");
|
||||
DbgBreakPoint();
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ list(APPEND HAL_PIC_SOURCE
|
|||
generic/profil.c
|
||||
generic/timer.c
|
||||
up/halinit_up.c
|
||||
up/irql.c
|
||||
up/pic.c)
|
||||
|
||||
add_asm_files(lib_hal_pic_asm ${HAL_PIC_ASM_SOURCE})
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: hal/halx86/up/halinit_up.c
|
||||
* PURPOSE: Initialize the x86 hal
|
||||
* PROGRAMMER: David Welch (welch@cwcom.net)
|
||||
* UPDATE HISTORY:
|
||||
* 11/06/98: Created
|
||||
* PROJECT: ReactOS Hardware Abstraction Layer
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: Initialize the x86 HAL
|
||||
* COPYRIGHT: Copyright 1998 David Welch (welch@cwcom.net)
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
@ -27,7 +25,7 @@ HalpInitProcessor(
|
|||
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
/* Set default IDR */
|
||||
KeGetPcr()->IDR = 0xFFFFFFFB;
|
||||
KeGetPcr()->IDR = 0xFFFFFFFF & ~(1 << PIC_CASCADE_IRQ);
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -39,18 +37,18 @@ HalpInitPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
|||
VOID
|
||||
HalpInitPhase1(VOID)
|
||||
{
|
||||
/* Enable IRQ 0 */
|
||||
/* Enable timer interrupt handler */
|
||||
HalpEnableInterruptHandler(IDT_DEVICE,
|
||||
0,
|
||||
PRIMARY_VECTOR_BASE,
|
||||
PRIMARY_VECTOR_BASE + PIC_TIMER_IRQ,
|
||||
CLOCK2_LEVEL,
|
||||
HalpClockInterrupt,
|
||||
Latched);
|
||||
|
||||
/* Enable IRQ 8 */
|
||||
/* Enable RTC interrupt handler */
|
||||
HalpEnableInterruptHandler(IDT_DEVICE,
|
||||
0,
|
||||
PRIMARY_VECTOR_BASE + 8,
|
||||
PRIMARY_VECTOR_BASE + PIC_RTC_IRQ,
|
||||
PROFILE_LEVEL,
|
||||
HalpProfileInterrupt,
|
||||
Latched);
|
||||
|
|
163
hal/halx86/up/irql.c
Normal file
163
hal/halx86/up/irql.c
Normal file
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Hardware Abstraction Layer
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* PURPOSE: IRQL mapping
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
/* This table contains the static x86 PIC mapping between IRQLs and IRQs */
|
||||
ULONG KiI8259MaskTable[32] =
|
||||
{
|
||||
/*
|
||||
* It Device IRQLs only start at 4 or higher, so these are just software
|
||||
* IRQLs that don't really change anything on the hardware
|
||||
*/
|
||||
0b00000000000000000000000000000000, /* IRQL 0 */
|
||||
0b00000000000000000000000000000000, /* IRQL 1 */
|
||||
0b00000000000000000000000000000000, /* IRQL 2 */
|
||||
0b00000000000000000000000000000000, /* IRQL 3 */
|
||||
|
||||
/*
|
||||
* These next IRQLs are actually useless from the PIC perspective, because
|
||||
* with only 2 PICs, the mask you can send them is only 8 bits each, for 16
|
||||
* bits total, so these IRQLs are masking off a phantom PIC.
|
||||
*/
|
||||
0b11111111100000000000000000000000, /* IRQL 4 */
|
||||
0b11111111110000000000000000000000, /* IRQL 5 */
|
||||
0b11111111111000000000000000000000, /* IRQL 6 */
|
||||
0b11111111111100000000000000000000, /* IRQL 7 */
|
||||
0b11111111111110000000000000000000, /* IRQL 8 */
|
||||
0b11111111111111000000000000000000, /* IRQL 9 */
|
||||
0b11111111111111100000000000000000, /* IRQL 10 */
|
||||
0b11111111111111110000000000000000, /* IRQL 11 */
|
||||
|
||||
/*
|
||||
* Okay, now we're finally starting to mask off IRQs on the slave PIC, from
|
||||
* IRQ15 to IRQ8. This means the higher-level IRQs get less priority in the
|
||||
* IRQL sense.
|
||||
*/
|
||||
0b11111111111111111000000000000000, /* IRQL 12 */
|
||||
0b11111111111111111100000000000000, /* IRQL 13 */
|
||||
0b11111111111111111110000000000000, /* IRQL 14 */
|
||||
0b11111111111111111111000000000000, /* IRQL 15 */
|
||||
0b11111111111111111111100000000000, /* IRQL 16 */
|
||||
0b11111111111111111111110000000000, /* IRQL 17 */
|
||||
0b11111111111111111111111000000000, /* IRQL 18 */
|
||||
0b11111111111111111111111000000000, /* IRQL 19 */
|
||||
|
||||
/*
|
||||
* Now we mask off the IRQs on the master. Notice the 0 "droplet"? You might
|
||||
* have also seen that IRQL 18 and 19 are essentially equal as far as the
|
||||
* PIC is concerned. That bit is actually IRQ8, which happens to be the RTC.
|
||||
* The RTC will keep firing as long as we don't reach PROFILE_LEVEL which
|
||||
* actually kills it. The RTC clock (unlike the system clock) is used by the
|
||||
* profiling APIs in the HAL, so that explains the logic.
|
||||
*/
|
||||
0b11111111111111111111111010000000, /* IRQL 20 */
|
||||
0b11111111111111111111111011000000, /* IRQL 21 */
|
||||
0b11111111111111111111111011100000, /* IRQL 22 */
|
||||
0b11111111111111111111111011110000, /* IRQL 23 */
|
||||
0b11111111111111111111111011111000, /* IRQL 24 */
|
||||
0b11111111111111111111111011111000, /* IRQL 25 */
|
||||
0b11111111111111111111111011111010, /* IRQL 26 */
|
||||
0b11111111111111111111111111111010, /* IRQL 27 */
|
||||
|
||||
/*
|
||||
* IRQL 24 and 25 are actually identical, so IRQL 28 is actually the last
|
||||
* IRQL to modify a bit on the master PIC. It happens to modify the very
|
||||
* last of the IRQs, IRQ0, which corresponds to the system clock interval
|
||||
* timer that keeps track of time (the Windows heartbeat). We only want to
|
||||
* turn this off at a high-enough IRQL, which is why IRQLs 24 and 25 are the
|
||||
* same to give this guy a chance to come up higher. Note that IRQL 28 is
|
||||
* called CLOCK2_LEVEL, which explains the usage we just explained.
|
||||
*/
|
||||
0b11111111111111111111111111111011, /* IRQL 28 */
|
||||
|
||||
/*
|
||||
* We have finished off with the PIC so there's nothing left to mask at the
|
||||
* level of these IRQLs, making them only logical IRQLs on x86 machines.
|
||||
* Note that we have another 0 "droplet" you might've caught since IRQL 26.
|
||||
* In this case, it's the 2nd bit that never gets turned off, which is IRQ2,
|
||||
* the cascade IRQ that we use to bridge the slave PIC with the master PIC.
|
||||
* We never want to turn it off, so no matter the IRQL, it will be set to 0.
|
||||
*/
|
||||
0b11111111111111111111111111111011, /* IRQL 29 */
|
||||
0b11111111111111111111111111111011, /* IRQL 30 */
|
||||
0b11111111111111111111111111111011 /* IRQL 31 */
|
||||
};
|
||||
|
||||
/* This table indicates which IRQs, if pending, can preempt a given IRQL level */
|
||||
ULONG FindHigherIrqlMask[32] =
|
||||
{
|
||||
/*
|
||||
* Software IRQLs, at these levels all hardware interrupts can preempt.
|
||||
* Each higher IRQL simply enables which software IRQL can preempt the
|
||||
* current level.
|
||||
*/
|
||||
0b11111111111111111111111111111110, /* IRQL 0 */
|
||||
0b11111111111111111111111111111100, /* IRQL 1 */
|
||||
0b11111111111111111111111111111000, /* IRQL 2 */
|
||||
|
||||
/*
|
||||
* IRQL3 means only hardware IRQLs can now preempt. These last 4 zeros will
|
||||
* then continue throughout the rest of the list, trickling down.
|
||||
*/
|
||||
0b11111111111111111111111111110000, /* IRQL 3 */
|
||||
|
||||
/*
|
||||
* Just like in the previous list, these masks don't really mean anything
|
||||
* since we've only got two PICs with 16 possible IRQs total
|
||||
*/
|
||||
0b00000111111111111111111111110000, /* IRQL 4 */
|
||||
0b00000011111111111111111111110000, /* IRQL 5 */
|
||||
0b00000001111111111111111111110000, /* IRQL 6 */
|
||||
0b00000000111111111111111111110000, /* IRQL 7 */
|
||||
0b00000000011111111111111111110000, /* IRQL 8 */
|
||||
0b00000000001111111111111111110000, /* IRQL 9 */
|
||||
0b00000000000111111111111111110000, /* IRQL 10 */
|
||||
|
||||
/*
|
||||
* Now we start progressivly limiting which slave PIC interrupts have the
|
||||
* right to preempt us at each level.
|
||||
*/
|
||||
0b00000000000011111111111111110000, /* IRQL 11 */
|
||||
0b00000000000001111111111111110000, /* IRQL 12 */
|
||||
0b00000000000000111111111111110000, /* IRQL 13 */
|
||||
0b00000000000000011111111111110000, /* IRQL 14 */
|
||||
0b00000000000000001111111111110000, /* IRQL 15 */
|
||||
0b00000000000000000111111111110000, /* IRQL 16 */
|
||||
0b00000000000000000011111111110000, /* IRQL 17 */
|
||||
0b00000000000000000001111111110000, /* IRQL 18 */
|
||||
0b00000000000000000001111111110000, /* IRQL 19 */
|
||||
|
||||
/*
|
||||
* Also recall from the earlier table that IRQL 18/19 are treated the same
|
||||
* in order to spread the masks better thoughout the 32 IRQLs and to reflect
|
||||
* the fact that some bits will always stay on until much higher IRQLs since
|
||||
* they are system-critical. One such example is the 1 bit that you start to
|
||||
* see trickling down here. This is IRQ8, the RTC timer used for profiling,
|
||||
* so it will always preempt until we reach PROFILE_LEVEL.
|
||||
*/
|
||||
0b00000000000000000001011111110000, /* IRQL 20 */
|
||||
0b00000000000000000001001111110000, /* IRQL 21 */
|
||||
0b00000000000000000001000111110000, /* IRQL 22 */
|
||||
0b00000000000000000001000011110000, /* IRQL 23 */
|
||||
0b00000000000000000001000001110000, /* IRQL 24 */
|
||||
0b00000000000000000001000000110000, /* IRQL 25 */
|
||||
0b00000000000000000001000000010000, /* IRQL 26 */
|
||||
|
||||
/* At this point, only the clock (IRQ0) can still preempt... */
|
||||
0b00000000000000000000000000010000, /* IRQL 27 */
|
||||
|
||||
/* And any higher than that there's no relation with hardware PICs anymore */
|
||||
0b00000000000000000000000000000000, /* IRQL 28 */
|
||||
0b00000000000000000000000000000000, /* IRQL 29 */
|
||||
0b00000000000000000000000000000000, /* IRQL 30 */
|
||||
0b00000000000000000000000000000000 /* IRQL 31 */
|
||||
};
|
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* PROJECT: ReactOS HAL
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: hal/halx86/up/pic.c
|
||||
* PURPOSE: HAL PIC Management and Control Code
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
*/
|
||||
|
@ -9,6 +8,7 @@
|
|||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include <hal.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
@ -62,12 +62,20 @@ PHAL_DISMISS_INTERRUPT HalpSpecialDismissTable[16] =
|
|||
HalpDismissIrqGeneric,
|
||||
HalpDismissIrqGeneric,
|
||||
HalpDismissIrq07,
|
||||
#if defined(SARCH_PC98)
|
||||
HalpDismissIrq08,
|
||||
#else
|
||||
HalpDismissIrqGeneric,
|
||||
#endif
|
||||
HalpDismissIrqGeneric,
|
||||
HalpDismissIrqGeneric,
|
||||
HalpDismissIrqGeneric,
|
||||
HalpDismissIrqGeneric,
|
||||
#if defined(SARCH_PC98)
|
||||
HalpDismissIrqGeneric,
|
||||
#else
|
||||
HalpDismissIrq13,
|
||||
#endif
|
||||
HalpDismissIrqGeneric,
|
||||
HalpDismissIrq15
|
||||
};
|
||||
|
@ -86,166 +94,29 @@ PHAL_DISMISS_INTERRUPT HalpSpecialDismissLevelTable[16] =
|
|||
HalpDismissIrqLevel,
|
||||
HalpDismissIrqLevel,
|
||||
HalpDismissIrq07Level,
|
||||
#if defined(SARCH_PC98)
|
||||
HalpDismissIrq08Level,
|
||||
#else
|
||||
HalpDismissIrqLevel,
|
||||
#endif
|
||||
HalpDismissIrqLevel,
|
||||
HalpDismissIrqLevel,
|
||||
HalpDismissIrqLevel,
|
||||
HalpDismissIrqLevel,
|
||||
#if defined(SARCH_PC98)
|
||||
HalpDismissIrqLevel,
|
||||
#else
|
||||
HalpDismissIrq13Level,
|
||||
#endif
|
||||
HalpDismissIrqLevel,
|
||||
HalpDismissIrq15Level
|
||||
};
|
||||
|
||||
/* This table contains the static x86 PIC mapping between IRQLs and IRQs */
|
||||
ULONG KiI8259MaskTable[32] =
|
||||
{
|
||||
/*
|
||||
* It Device IRQLs only start at 4 or higher, so these are just software
|
||||
* IRQLs that don't really change anything on the hardware
|
||||
*/
|
||||
0b00000000000000000000000000000000, /* IRQL 0 */
|
||||
0b00000000000000000000000000000000, /* IRQL 1 */
|
||||
0b00000000000000000000000000000000, /* IRQL 2 */
|
||||
0b00000000000000000000000000000000, /* IRQL 3 */
|
||||
|
||||
/*
|
||||
* These next IRQLs are actually useless from the PIC perspective, because
|
||||
* with only 2 PICs, the mask you can send them is only 8 bits each, for 16
|
||||
* bits total, so these IRQLs are masking off a phantom PIC.
|
||||
*/
|
||||
0b11111111100000000000000000000000, /* IRQL 4 */
|
||||
0b11111111110000000000000000000000, /* IRQL 5 */
|
||||
0b11111111111000000000000000000000, /* IRQL 6 */
|
||||
0b11111111111100000000000000000000, /* IRQL 7 */
|
||||
0b11111111111110000000000000000000, /* IRQL 8 */
|
||||
0b11111111111111000000000000000000, /* IRQL 9 */
|
||||
0b11111111111111100000000000000000, /* IRQL 10 */
|
||||
0b11111111111111110000000000000000, /* IRQL 11 */
|
||||
|
||||
/*
|
||||
* Okay, now we're finally starting to mask off IRQs on the slave PIC, from
|
||||
* IRQ15 to IRQ8. This means the higher-level IRQs get less priority in the
|
||||
* IRQL sense.
|
||||
*/
|
||||
0b11111111111111111000000000000000, /* IRQL 12 */
|
||||
0b11111111111111111100000000000000, /* IRQL 13 */
|
||||
0b11111111111111111110000000000000, /* IRQL 14 */
|
||||
0b11111111111111111111000000000000, /* IRQL 15 */
|
||||
0b11111111111111111111100000000000, /* IRQL 16 */
|
||||
0b11111111111111111111110000000000, /* IRQL 17 */
|
||||
0b11111111111111111111111000000000, /* IRQL 18 */
|
||||
0b11111111111111111111111000000000, /* IRQL 19 */
|
||||
|
||||
/*
|
||||
* Now we mask off the IRQs on the master. Notice the 0 "droplet"? You might
|
||||
* have also seen that IRQL 18 and 19 are essentially equal as far as the
|
||||
* PIC is concerned. That bit is actually IRQ8, which happens to be the RTC.
|
||||
* The RTC will keep firing as long as we don't reach PROFILE_LEVEL which
|
||||
* actually kills it. The RTC clock (unlike the system clock) is used by the
|
||||
* profiling APIs in the HAL, so that explains the logic.
|
||||
*/
|
||||
0b11111111111111111111111010000000, /* IRQL 20 */
|
||||
0b11111111111111111111111011000000, /* IRQL 21 */
|
||||
0b11111111111111111111111011100000, /* IRQL 22 */
|
||||
0b11111111111111111111111011110000, /* IRQL 23 */
|
||||
0b11111111111111111111111011111000, /* IRQL 24 */
|
||||
0b11111111111111111111111011111000, /* IRQL 25 */
|
||||
0b11111111111111111111111011111010, /* IRQL 26 */
|
||||
0b11111111111111111111111111111010, /* IRQL 27 */
|
||||
|
||||
/*
|
||||
* IRQL 24 and 25 are actually identical, so IRQL 28 is actually the last
|
||||
* IRQL to modify a bit on the master PIC. It happens to modify the very
|
||||
* last of the IRQs, IRQ0, which corresponds to the system clock interval
|
||||
* timer that keeps track of time (the Windows heartbeat). We only want to
|
||||
* turn this off at a high-enough IRQL, which is why IRQLs 24 and 25 are the
|
||||
* same to give this guy a chance to come up higher. Note that IRQL 28 is
|
||||
* called CLOCK2_LEVEL, which explains the usage we just explained.
|
||||
*/
|
||||
0b11111111111111111111111111111011, /* IRQL 28 */
|
||||
|
||||
/*
|
||||
* We have finished off with the PIC so there's nothing left to mask at the
|
||||
* level of these IRQLs, making them only logical IRQLs on x86 machines.
|
||||
* Note that we have another 0 "droplet" you might've caught since IRQL 26.
|
||||
* In this case, it's the 2nd bit that never gets turned off, which is IRQ2,
|
||||
* the cascade IRQ that we use to bridge the slave PIC with the master PIC.
|
||||
* We never want to turn it off, so no matter the IRQL, it will be set to 0.
|
||||
*/
|
||||
0b11111111111111111111111111111011, /* IRQL 29 */
|
||||
0b11111111111111111111111111111011, /* IRQL 30 */
|
||||
0b11111111111111111111111111111011 /* IRQL 31 */
|
||||
};
|
||||
extern ULONG KiI8259MaskTable[32];
|
||||
|
||||
/* This table indicates which IRQs, if pending, can preempt a given IRQL level */
|
||||
ULONG FindHigherIrqlMask[32] =
|
||||
{
|
||||
/*
|
||||
* Software IRQLs, at these levels all hardware interrupts can preempt.
|
||||
* Each higher IRQL simply enables which software IRQL can preempt the
|
||||
* current level.
|
||||
*/
|
||||
0b11111111111111111111111111111110, /* IRQL 0 */
|
||||
0b11111111111111111111111111111100, /* IRQL 1 */
|
||||
0b11111111111111111111111111111000, /* IRQL 2 */
|
||||
|
||||
/*
|
||||
* IRQL3 means only hardware IRQLs can now preempt. These last 4 zeros will
|
||||
* then continue throughout the rest of the list, trickling down.
|
||||
*/
|
||||
0b11111111111111111111111111110000, /* IRQL 3 */
|
||||
|
||||
/*
|
||||
* Just like in the previous list, these masks don't really mean anything
|
||||
* since we've only got two PICs with 16 possible IRQs total
|
||||
*/
|
||||
0b00000111111111111111111111110000, /* IRQL 4 */
|
||||
0b00000011111111111111111111110000, /* IRQL 5 */
|
||||
0b00000001111111111111111111110000, /* IRQL 6 */
|
||||
0b00000000111111111111111111110000, /* IRQL 7 */
|
||||
0b00000000011111111111111111110000, /* IRQL 8 */
|
||||
0b00000000001111111111111111110000, /* IRQL 9 */
|
||||
0b00000000000111111111111111110000, /* IRQL 10 */
|
||||
|
||||
/*
|
||||
* Now we start progressivly limiting which slave PIC interrupts have the
|
||||
* right to preempt us at each level.
|
||||
*/
|
||||
0b00000000000011111111111111110000, /* IRQL 11 */
|
||||
0b00000000000001111111111111110000, /* IRQL 12 */
|
||||
0b00000000000000111111111111110000, /* IRQL 13 */
|
||||
0b00000000000000011111111111110000, /* IRQL 14 */
|
||||
0b00000000000000001111111111110000, /* IRQL 15 */
|
||||
0b00000000000000000111111111110000, /* IRQL 16 */
|
||||
0b00000000000000000011111111110000, /* IRQL 17 */
|
||||
0b00000000000000000001111111110000, /* IRQL 18 */
|
||||
0b00000000000000000001111111110000, /* IRQL 19 */
|
||||
|
||||
/*
|
||||
* Also recall from the earlier table that IRQL 18/19 are treated the same
|
||||
* in order to spread the masks better thoughout the 32 IRQLs and to reflect
|
||||
* the fact that some bits will always stay on until much higher IRQLs since
|
||||
* they are system-critical. One such example is the 1 bit that you start to
|
||||
* see trickling down here. This is IRQ8, the RTC timer used for profiling,
|
||||
* so it will always preempt until we reach PROFILE_LEVEL.
|
||||
*/
|
||||
0b00000000000000000001011111110000, /* IRQL 20 */
|
||||
0b00000000000000000001001111110000, /* IRQL 21 */
|
||||
0b00000000000000000001000111110000, /* IRQL 22 */
|
||||
0b00000000000000000001000011110000, /* IRQL 23 */
|
||||
0b00000000000000000001000001110000, /* IRQL 24 */
|
||||
0b00000000000000000001000000110000, /* IRQL 25 */
|
||||
0b00000000000000000001000000010000, /* IRQL 26 */
|
||||
|
||||
/* At this point, only the clock (IRQ0) can still preempt... */
|
||||
0b00000000000000000000000000010000, /* IRQL 27 */
|
||||
|
||||
/* And any higher than that there's no relation with hardware PICs anymore */
|
||||
0b00000000000000000000000000000000, /* IRQL 28 */
|
||||
0b00000000000000000000000000000000, /* IRQL 29 */
|
||||
0b00000000000000000000000000000000, /* IRQL 30 */
|
||||
0b00000000000000000000000000000000 /* IRQL 31 */
|
||||
};
|
||||
extern ULONG FindHigherIrqlMask[32];
|
||||
|
||||
/* Denotes minimum required IRQL before we can process pending SW interrupts */
|
||||
KIRQL SWInterruptLookUpTable[8] =
|
||||
|
@ -351,6 +222,7 @@ HalpInitializePICs(IN BOOLEAN EnableInterrupts)
|
|||
ULONG EFlags;
|
||||
EISA_ELCR Elcr;
|
||||
ULONG i, j;
|
||||
BOOLEAN ElcrFound;
|
||||
|
||||
/* Save EFlags and disable interrupts */
|
||||
EFlags = __readeflags();
|
||||
|
@ -362,9 +234,23 @@ HalpInitializePICs(IN BOOLEAN EnableInterrupts)
|
|||
/* Read EISA Edge/Level Register for master and slave */
|
||||
Elcr.Bits = (__inbyte(EISA_ELCR_SLAVE) << 8) | __inbyte(EISA_ELCR_MASTER);
|
||||
|
||||
#if defined(SARCH_PC98)
|
||||
/* Force defaults when ELCR is not supported */
|
||||
if (Elcr.Bits == 0xFFFF)
|
||||
{
|
||||
Elcr.Master.Irq0Level = 0;
|
||||
Elcr.Master.Irq1Level = 0;
|
||||
Elcr.Master.Irq7Level = 0;
|
||||
Elcr.Slave.Irq8Level = 0;
|
||||
}
|
||||
ElcrFound = TRUE;
|
||||
#else
|
||||
/* IRQs 0, 1, 2, 8, and 13 are system-reserved and must be edge */
|
||||
if (!(Elcr.Master.Irq0Level) && !(Elcr.Master.Irq1Level) && !(Elcr.Master.Irq2Level) &&
|
||||
!(Elcr.Slave.Irq8Level) && !(Elcr.Slave.Irq13Level))
|
||||
ElcrFound = (!(Elcr.Master.Irq0Level) && !(Elcr.Master.Irq1Level) && !(Elcr.Master.Irq2Level) &&
|
||||
!(Elcr.Slave.Irq8Level) && !(Elcr.Slave.Irq13Level));
|
||||
#endif
|
||||
|
||||
if (ElcrFound)
|
||||
{
|
||||
/* ELCR is as it's supposed to be, save it */
|
||||
HalpEisaELCR = Elcr.Bits;
|
||||
|
@ -383,10 +269,10 @@ HalpInitializePICs(IN BOOLEAN EnableInterrupts)
|
|||
}
|
||||
}
|
||||
|
||||
/* Register IRQ 2 */
|
||||
/* Report cascade IRQ usage */
|
||||
HalpRegisterVector(IDT_INTERNAL,
|
||||
PRIMARY_VECTOR_BASE + 2,
|
||||
PRIMARY_VECTOR_BASE + 2,
|
||||
PRIMARY_VECTOR_BASE + PIC_CASCADE_IRQ,
|
||||
PRIMARY_VECTOR_BASE + PIC_CASCADE_IRQ,
|
||||
HIGH_LEVEL);
|
||||
|
||||
/* Restore interrupt state */
|
||||
|
@ -690,16 +576,40 @@ _HalpDismissIrqGeneric(IN KIRQL Irql,
|
|||
/* Check which PIC needs the EOI */
|
||||
if (Irq >= 8)
|
||||
{
|
||||
#if defined(SARCH_PC98)
|
||||
I8259_OCW3 Ocw3;
|
||||
I8259_ISR Isr;
|
||||
|
||||
/* Send the EOI for the IRQ */
|
||||
__outbyte(PIC2_CONTROL_PORT, Ocw2.Bits | ((Irq - 8) & 0xFF));
|
||||
|
||||
/* Send the EOI for IRQ2 on the master because this was cascaded */
|
||||
__outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | 2);
|
||||
/* Request the ISR */
|
||||
Ocw3.Bits = 0;
|
||||
Ocw3.Sbo = 1;
|
||||
Ocw3.ReadRequest = ReadIsr;
|
||||
__outbyte(PIC2_CONTROL_PORT, Ocw3.Bits);
|
||||
|
||||
/* Read the ISR */
|
||||
Isr.Bits = __inbyte(PIC2_CONTROL_PORT);
|
||||
|
||||
/* Check if the interrupt serviced was the only one from the slave PIC */
|
||||
if (Isr.Bits == 0)
|
||||
{
|
||||
/* If ISR is empty, send the EOI for cascade IRQ on the master PIC */
|
||||
__outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | PIC_CASCADE_IRQ);
|
||||
}
|
||||
#else
|
||||
/* Send the EOI for the IRQ */
|
||||
__outbyte(PIC2_CONTROL_PORT, Ocw2.Bits | ((Irq - 8) & 0xFF));
|
||||
|
||||
/* Send the EOI for cascade IRQ on the master PIC */
|
||||
__outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | PIC_CASCADE_IRQ);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Send the EOI for the IRQ */
|
||||
__outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | (Irq &0xFF));
|
||||
__outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | (Irq & 0xFF));
|
||||
}
|
||||
|
||||
/* Enable interrupts and return success */
|
||||
|
@ -751,10 +661,10 @@ HalpDismissIrq15(IN KIRQL Irql,
|
|||
/* Is IRQ15 really active (this is IR7) */
|
||||
if (Isr.Irq7 == FALSE)
|
||||
{
|
||||
/* It isn't, so we have to EOI IRQ2 because this was cascaded */
|
||||
/* It isn't, so we have to EOI cascade IRQ */
|
||||
Ocw2.Bits = 0;
|
||||
Ocw2.EoiMode = SpecificEoi;
|
||||
__outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | 2);
|
||||
__outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | PIC_CASCADE_IRQ);
|
||||
|
||||
/* And now fail since this was spurious */
|
||||
return FALSE;
|
||||
|
@ -764,7 +674,6 @@ HalpDismissIrq15(IN KIRQL Irql,
|
|||
return _HalpDismissIrqGeneric(Irql, Irq, OldIrql);
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
HalpDismissIrq13(IN KIRQL Irql,
|
||||
|
@ -778,6 +687,22 @@ HalpDismissIrq13(IN KIRQL Irql,
|
|||
return _HalpDismissIrqGeneric(Irql, Irq, OldIrql);
|
||||
}
|
||||
|
||||
#if defined(SARCH_PC98)
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
HalpDismissIrq08(
|
||||
_In_ KIRQL Irql,
|
||||
_In_ ULONG Irq,
|
||||
_Out_ PKIRQL OldIrql)
|
||||
{
|
||||
/* Clear the FPU busy latch */
|
||||
__outbyte(CPU_IO_o_FPU_BUSY_LATCH, 0);
|
||||
|
||||
/* Do normal interrupt dismiss */
|
||||
return _HalpDismissIrqGeneric(Irql, Irq, OldIrql);
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
HalpDismissIrq07(IN KIRQL Irql,
|
||||
|
@ -834,11 +759,35 @@ _HalpDismissIrqLevel(IN KIRQL Irql,
|
|||
/* Check which PIC needs the EOI */
|
||||
if (Irq >= 8)
|
||||
{
|
||||
#if defined(SARCH_PC98)
|
||||
I8259_OCW3 Ocw3;
|
||||
I8259_ISR Isr;
|
||||
|
||||
/* Send the EOI for the IRQ */
|
||||
__outbyte(PIC2_CONTROL_PORT, Ocw2.Bits | ((Irq - 8) & 0xFF));
|
||||
|
||||
/* Send the EOI for IRQ2 on the master because this was cascaded */
|
||||
__outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | 2);
|
||||
/* Request the ISR */
|
||||
Ocw3.Bits = 0;
|
||||
Ocw3.Sbo = 1;
|
||||
Ocw3.ReadRequest = ReadIsr;
|
||||
__outbyte(PIC2_CONTROL_PORT, Ocw3.Bits);
|
||||
|
||||
/* Read the ISR */
|
||||
Isr.Bits = __inbyte(PIC2_CONTROL_PORT);
|
||||
|
||||
/* Check if the interrupt serviced was the only one from the slave PIC */
|
||||
if (Isr.Bits == 0)
|
||||
{
|
||||
/* If ISR is empty, send the EOI for cascade IRQ on the master PIC */
|
||||
__outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | PIC_CASCADE_IRQ);
|
||||
}
|
||||
#else
|
||||
/* Send the EOI for the IRQ */
|
||||
__outbyte(PIC2_CONTROL_PORT, Ocw2.Bits | ((Irq - 8) & 0xFF));
|
||||
|
||||
/* Send the EOI for cascade IRQ on the master PIC */
|
||||
__outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | PIC_CASCADE_IRQ);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -894,10 +843,10 @@ HalpDismissIrq15Level(IN KIRQL Irql,
|
|||
/* Is IRQ15 really active (this is IR7) */
|
||||
if (Isr.Irq7 == FALSE)
|
||||
{
|
||||
/* It isn't, so we have to EOI IRQ2 because this was cascaded */
|
||||
/* It isn't, so we have to EOI cascade IRQ */
|
||||
Ocw2.Bits = 0;
|
||||
Ocw2.EoiMode = SpecificEoi;
|
||||
__outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | 2);
|
||||
__outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | PIC_CASCADE_IRQ);
|
||||
|
||||
/* And now fail since this was spurious */
|
||||
return FALSE;
|
||||
|
@ -920,6 +869,22 @@ HalpDismissIrq13Level(IN KIRQL Irql,
|
|||
return _HalpDismissIrqLevel(Irql, Irq, OldIrql);
|
||||
}
|
||||
|
||||
#if defined(SARCH_PC98)
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
HalpDismissIrq08Level(
|
||||
_In_ KIRQL Irql,
|
||||
_In_ ULONG Irq,
|
||||
_Out_ PKIRQL OldIrql)
|
||||
{
|
||||
/* Clear the FPU busy latch */
|
||||
__outbyte(CPU_IO_o_FPU_BUSY_LATCH, 0);
|
||||
|
||||
/* Do normal interrupt dismiss */
|
||||
return _HalpDismissIrqLevel(Irql, Irq, OldIrql);
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
HalpDismissIrq07Level(IN KIRQL Irql,
|
||||
|
@ -1268,7 +1233,7 @@ HalpDispatchInterrupt2(VOID)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
#else /* _MINIHAL_ */
|
||||
|
||||
KIRQL
|
||||
NTAPI
|
||||
|
@ -1292,4 +1257,4 @@ KfRaiseIrql(
|
|||
return NewIrql;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* !_MINIHAL_ */
|
||||
|
|
|
@ -14,6 +14,7 @@ list(APPEND HAL_XBOX_SOURCE
|
|||
generic/halinit.c
|
||||
generic/memory.c
|
||||
generic/misc.c
|
||||
generic/nmi.c
|
||||
generic/pic.c
|
||||
generic/sysinfo.c
|
||||
generic/usage.c
|
||||
|
@ -35,16 +36,14 @@ list(APPEND HAL_XBOX_SOURCE
|
|||
xbox/part_xbox.c
|
||||
xbox/halinit_xbox.c
|
||||
xbox/reboot.c
|
||||
up/irql.c
|
||||
up/pic.c)
|
||||
|
||||
add_asm_files(lib_hal_xbox_asm ${HAL_XBOX_ASM_SOURCE})
|
||||
add_object_library(lib_hal_xbox ${HAL_XBOX_SOURCE} ${lib_hal_xbox_asm})
|
||||
if(NOT SARCH STREQUAL "xbox")
|
||||
target_compile_definitions(lib_hal_xbox PRIVATE SARCH_XBOX)
|
||||
endif()
|
||||
add_dependencies(lib_hal_xbox bugcodes xdk asm)
|
||||
#add_pch(lib_hal_xbox xbox/halxbox.h)
|
||||
|
||||
if(MSVC)
|
||||
target_link_libraries(lib_hal_xbox lib_hal_generic)
|
||||
target_link_libraries(lib_hal_xbox)
|
||||
endif()
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: hal/halx86/xbox/halinit_xbox.c
|
||||
* PURPOSE: Initialize the x86 hal
|
||||
* PROGRAMMER: David Welch (welch@cwcom.net)
|
||||
* UPDATE HISTORY:
|
||||
* 11/06/98: Created
|
||||
* PROJECT: Xbox HAL
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: Initialize the x86 HAL
|
||||
* COPYRIGHT: Copyright 1998 David Welch (welch@cwcom.net)
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
@ -28,7 +25,7 @@ HalpInitProcessor(
|
|||
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
/* Set default IDR */
|
||||
KeGetPcr()->IDR = 0xFFFFFFFB;
|
||||
KeGetPcr()->IDR = 0xFFFFFFFF & ~(1 << PIC_CASCADE_IRQ);
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -41,18 +38,18 @@ HalpInitPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
|||
VOID
|
||||
HalpInitPhase1(VOID)
|
||||
{
|
||||
/* Enable IRQ 0 */
|
||||
/* Enable timer interrupt handler */
|
||||
HalpEnableInterruptHandler(IDT_DEVICE,
|
||||
0,
|
||||
PRIMARY_VECTOR_BASE,
|
||||
PRIMARY_VECTOR_BASE + PIC_TIMER_IRQ,
|
||||
CLOCK2_LEVEL,
|
||||
HalpClockInterrupt,
|
||||
Latched);
|
||||
|
||||
/* Enable IRQ 8 */
|
||||
/* Enable RTC interrupt handler */
|
||||
HalpEnableInterruptHandler(IDT_DEVICE,
|
||||
0,
|
||||
PRIMARY_VECTOR_BASE + 8,
|
||||
PRIMARY_VECTOR_BASE + PIC_RTC_IRQ,
|
||||
PROFILE_LEVEL,
|
||||
HalpProfileInterrupt,
|
||||
Latched);
|
||||
|
|
|
@ -24,6 +24,7 @@ HKR, , Icon, 0, "-27"
|
|||
[Manufacturer]
|
||||
%GenericMfg% = GenericMfg
|
||||
%MsftMfg% = MsftMfg
|
||||
%NecMfg% = NecMfg
|
||||
|
||||
[GenericMfg]
|
||||
%acpipic_up.DeviceDesc% = NO_DRV,acpipic_up
|
||||
|
@ -32,6 +33,9 @@ HKR, , Icon, 0, "-27"
|
|||
[MsftMfg]
|
||||
%xbox.DeviceDesc% = NO_DRV,xbox
|
||||
|
||||
[NecMfg]
|
||||
%pc98_up.DeviceDesc% = NO_DRV,pc98_up
|
||||
|
||||
;------------------------------ NO DRIVER -----------------------------
|
||||
|
||||
[NO_DRV]
|
||||
|
@ -53,6 +57,9 @@ e_isa_up.DeviceDesc = "Standard Uniprocessor PC"
|
|||
MsftMfg = "Microsoft Corporation"
|
||||
xbox.DeviceDesc = "Original Xbox (x86 based)"
|
||||
|
||||
NecMfg = "NEC"
|
||||
pc98_up.DeviceDesc = "Uniprocessor NEC PC-98"
|
||||
|
||||
[Strings.0405]
|
||||
ComputerClassName = "Počítač"
|
||||
GenericMfg = "(Obecné počítače)"
|
||||
|
@ -62,6 +69,8 @@ e_isa_up.DeviceDesc = "Standardní jednoprocesorové PC"
|
|||
MsftMfg = "Microsoft Corporation"
|
||||
xbox.DeviceDesc = "Original Xbox (x86 based)"
|
||||
|
||||
pc98_up.DeviceDesc = "Uniprocessor NEC PC-98"
|
||||
|
||||
[Strings.0a]
|
||||
ReactOS = "Equipo de ReactOS"
|
||||
|
||||
|
@ -74,6 +83,8 @@ e_isa_up.DeviceDesc = "PC con uniprocesador estándar"
|
|||
MsftMfg = "Microsoft Corporation"
|
||||
xbox.DeviceDesc = "Original Xbox (x86 based)"
|
||||
|
||||
pc98_up.DeviceDesc = "Uniprocessor NEC PC-98"
|
||||
|
||||
[Strings.0415]
|
||||
ReactOS = "Zespół ReactOS"
|
||||
|
||||
|
@ -86,6 +97,8 @@ e_isa_up.DeviceDesc = "Standardowy komputer PC"
|
|||
MsftMfg = "Microsoft Corporation"
|
||||
xbox.DeviceDesc = "Original Xbox (x86 based)"
|
||||
|
||||
pc98_up.DeviceDesc = "Uniprocessor NEC PC-98"
|
||||
|
||||
[Strings.0418]
|
||||
ReactOS = "Echipa ReactOS"
|
||||
|
||||
|
@ -98,6 +111,8 @@ e_isa_up.DeviceDesc = "PC uniprocesor standard"
|
|||
MsftMfg = "Microsoft Corporation"
|
||||
xbox.DeviceDesc = "Original Xbox (x86 based)"
|
||||
|
||||
pc98_up.DeviceDesc = "Uniprocessor NEC PC-98"
|
||||
|
||||
[Strings.0419]
|
||||
ReactOS = "Команда ReactOS"
|
||||
|
||||
|
@ -110,6 +125,8 @@ e_isa_up.DeviceDesc = "Стандартный однопроцессорный
|
|||
MsftMfg = "Корпорация Microsoft"
|
||||
xbox.DeviceDesc = "Оригинальный Xbox (на базе x86)"
|
||||
|
||||
pc98_up.DeviceDesc = "Однопроцессорный NEC PC-98"
|
||||
|
||||
[Strings.041f]
|
||||
ReactOS = "ReactOS Takımı"
|
||||
|
||||
|
@ -122,6 +139,8 @@ e_isa_up.DeviceDesc = "Ölçünlü Tek İşlemcili PC"
|
|||
MsftMfg = "Microsoft Corporation"
|
||||
xbox.DeviceDesc = "Original Xbox (x86 based)"
|
||||
|
||||
pc98_up.DeviceDesc = "Uniprocessor NEC PC-98"
|
||||
|
||||
[Strings.0422]
|
||||
ReactOS = "Команда ReactOS"
|
||||
|
||||
|
@ -134,6 +153,8 @@ e_isa_up.DeviceDesc = "Стандартний однопроцесорний П
|
|||
MsftMfg = "Microsoft Corporation"
|
||||
xbox.DeviceDesc = "Original Xbox (x86 based)"
|
||||
|
||||
pc98_up.DeviceDesc = "Однопроцесорний NEC PC-98"
|
||||
|
||||
[Strings.0804]
|
||||
GenericMfg = "(通用计算机)"
|
||||
acpipic_up.DeviceDesc = "ACPI 单处理器 PC"
|
||||
|
@ -141,3 +162,5 @@ e_isa_up.DeviceDesc = "标准单处理器 PC"
|
|||
|
||||
MsftMfg = "Microsoft Corporation"
|
||||
xbox.DeviceDesc = "Original Xbox (x86 based)"
|
||||
|
||||
pc98_up.DeviceDesc = "Uniprocessor NEC PC-98"
|
||||
|
|
|
@ -7,13 +7,15 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#define CPU_IO_o_RESET 0x0F
|
||||
#define CPU_IO_o_RESET 0xF0
|
||||
#define CPU_IO_o_A20_UNMASK 0xF2
|
||||
|
||||
#define CPU_IO_o_A20_CONTROL 0xF6
|
||||
#define CPU_A20_ENABLE 0x02
|
||||
#define CPU_A20_DISABLE 0x03
|
||||
|
||||
#define CPU_IO_o_FPU_BUSY_LATCH 0xF8
|
||||
|
||||
/*
|
||||
* ARTIC (A Relative Time Indication Counter) - 24-bit binary up counter
|
||||
*/
|
||||
|
|
231
sdk/include/reactos/drivers/pc98/pic.h
Normal file
231
sdk/include/reactos/drivers/pc98/pic.h
Normal file
|
@ -0,0 +1,231 @@
|
|||
/*
|
||||
* PROJECT: NEC PC-98 series onboard hardware
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: Intel 8259A PIC header file
|
||||
* COPYRIGHT: Copyright 2020 Dmitry Borisov (di.sean@protonmail.com)
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define PIC1_CONTROL_PORT 0x00
|
||||
#define PIC1_DATA_PORT 0x02
|
||||
#define PIC2_CONTROL_PORT 0x08
|
||||
#define PIC2_DATA_PORT 0x0A
|
||||
|
||||
#define PIC_TIMER_IRQ 0
|
||||
#define PIC_CASCADE_IRQ 7
|
||||
#define PIC_RTC_IRQ 15
|
||||
|
||||
/*
|
||||
* Definitions for ICW/OCW Bits
|
||||
*/
|
||||
typedef enum _I8259_ICW1_OPERATING_MODE
|
||||
{
|
||||
Cascade,
|
||||
Single
|
||||
} I8259_ICW1_OPERATING_MODE;
|
||||
|
||||
typedef enum _I8259_ICW1_INTERRUPT_MODE
|
||||
{
|
||||
EdgeTriggered,
|
||||
LevelTriggered
|
||||
} I8259_ICW1_INTERRUPT_MODE;
|
||||
|
||||
typedef enum _I8259_ICW1_INTERVAL
|
||||
{
|
||||
Interval8,
|
||||
Interval4
|
||||
} I8259_ICW1_INTERVAL;
|
||||
|
||||
typedef enum _I8259_ICW4_SYSTEM_MODE
|
||||
{
|
||||
Mcs8085Mode,
|
||||
New8086Mode
|
||||
} I8259_ICW4_SYSTEM_MODE;
|
||||
|
||||
typedef enum _I8259_ICW4_EOI_MODE
|
||||
{
|
||||
NormalEoi,
|
||||
AutomaticEoi
|
||||
} I8259_ICW4_EOI_MODE;
|
||||
|
||||
typedef enum _I8259_ICW4_BUFFERED_MODE
|
||||
{
|
||||
NonBuffered,
|
||||
NonBuffered2,
|
||||
BufferedSlave,
|
||||
BufferedMaster
|
||||
} I8259_ICW4_BUFFERED_MODE;
|
||||
|
||||
typedef enum _I8259_READ_REQUEST
|
||||
{
|
||||
InvalidRequest,
|
||||
InvalidRequest2,
|
||||
ReadIdr,
|
||||
ReadIsr
|
||||
} I8259_READ_REQUEST;
|
||||
|
||||
typedef enum _I8259_EOI_MODE
|
||||
{
|
||||
RotateAutoEoiClear,
|
||||
NonSpecificEoi,
|
||||
InvalidEoiMode,
|
||||
SpecificEoi,
|
||||
RotateAutoEoiSet,
|
||||
RotateNonSpecific,
|
||||
SetPriority,
|
||||
RotateSpecific
|
||||
} I8259_EOI_MODE;
|
||||
|
||||
/*
|
||||
* Definitions for ICW Registers
|
||||
*/
|
||||
typedef union _I8259_ICW1
|
||||
{
|
||||
struct
|
||||
{
|
||||
UCHAR NeedIcw4:1;
|
||||
UCHAR OperatingMode:1;
|
||||
UCHAR Interval:1;
|
||||
UCHAR InterruptMode:1;
|
||||
UCHAR Init:1;
|
||||
UCHAR InterruptVectorAddress:3;
|
||||
};
|
||||
UCHAR Bits;
|
||||
} I8259_ICW1, *PI8259_ICW1;
|
||||
|
||||
typedef union _I8259_ICW2
|
||||
{
|
||||
struct
|
||||
{
|
||||
UCHAR Sbz:3;
|
||||
UCHAR InterruptVector:5;
|
||||
};
|
||||
UCHAR Bits;
|
||||
} I8259_ICW2, *PI8259_ICW2;
|
||||
|
||||
typedef union _I8259_ICW3
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
UCHAR SlaveIrq0:1;
|
||||
UCHAR SlaveIrq1:1;
|
||||
UCHAR SlaveIrq2:1;
|
||||
UCHAR SlaveIrq3:1;
|
||||
UCHAR SlaveIrq4:1;
|
||||
UCHAR SlaveIrq5:1;
|
||||
UCHAR SlaveIrq6:1;
|
||||
UCHAR SlaveIrq7:1;
|
||||
};
|
||||
struct
|
||||
{
|
||||
UCHAR SlaveId:3;
|
||||
UCHAR Reserved:5;
|
||||
};
|
||||
};
|
||||
UCHAR Bits;
|
||||
} I8259_ICW3, *PI8259_ICW3;
|
||||
|
||||
typedef union _I8259_ICW4
|
||||
{
|
||||
struct
|
||||
{
|
||||
UCHAR SystemMode:1;
|
||||
UCHAR EoiMode:1;
|
||||
UCHAR BufferedMode:2;
|
||||
UCHAR SpecialFullyNestedMode:1;
|
||||
UCHAR Reserved:3;
|
||||
};
|
||||
UCHAR Bits;
|
||||
} I8259_ICW4, *PI8259_ICW4;
|
||||
|
||||
typedef union _I8259_OCW2
|
||||
{
|
||||
struct
|
||||
{
|
||||
UCHAR IrqNumber:3;
|
||||
UCHAR Sbz:2;
|
||||
UCHAR EoiMode:3;
|
||||
};
|
||||
UCHAR Bits;
|
||||
} I8259_OCW2, *PI8259_OCW2;
|
||||
|
||||
typedef union _I8259_OCW3
|
||||
{
|
||||
struct
|
||||
{
|
||||
UCHAR ReadRequest:2;
|
||||
UCHAR PollCommand:1;
|
||||
UCHAR Sbo:1;
|
||||
UCHAR Sbz:1;
|
||||
UCHAR SpecialMaskMode:2;
|
||||
UCHAR Reserved:1;
|
||||
};
|
||||
UCHAR Bits;
|
||||
} I8259_OCW3, *PI8259_OCW3;
|
||||
|
||||
typedef union _I8259_ISR
|
||||
{
|
||||
struct
|
||||
{
|
||||
UCHAR Irq0:1;
|
||||
UCHAR Irq1:1;
|
||||
UCHAR Irq2:1;
|
||||
UCHAR Irq3:1;
|
||||
UCHAR Irq4:1;
|
||||
UCHAR Irq5:1;
|
||||
UCHAR Irq6:1;
|
||||
UCHAR Irq7:1;
|
||||
};
|
||||
UCHAR Bits;
|
||||
} I8259_ISR, *PI8259_ISR;
|
||||
|
||||
typedef I8259_ISR I8259_IDR, *PI8259_IDR;
|
||||
|
||||
/*
|
||||
* NESA Edge/Level Triggered Register
|
||||
*/
|
||||
#define EISA_ELCR_MASTER 0x98D2
|
||||
#define EISA_ELCR_SLAVE 0x98D4
|
||||
|
||||
typedef union _EISA_ELCR
|
||||
{
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
UCHAR Irq0Level:1;
|
||||
UCHAR Irq1Level:1;
|
||||
UCHAR Irq2Level:1;
|
||||
UCHAR Irq3Level:1;
|
||||
UCHAR Irq4Level:1;
|
||||
UCHAR Irq5Level:1;
|
||||
UCHAR Irq6Level:1;
|
||||
UCHAR Irq7Level:1;
|
||||
} Master;
|
||||
struct
|
||||
{
|
||||
UCHAR Irq8Level:1;
|
||||
UCHAR Irq9Level:1;
|
||||
UCHAR Irq10Level:1;
|
||||
UCHAR Irq11Level:1;
|
||||
UCHAR Irq12Level:1;
|
||||
UCHAR Irq13Level:1;
|
||||
UCHAR Irq14Level:1;
|
||||
UCHAR Irq15Level:1;
|
||||
} Slave;
|
||||
};
|
||||
USHORT Bits;
|
||||
} EISA_ELCR, *PEISA_ELCR;
|
||||
|
||||
typedef union _PIC_MASK
|
||||
{
|
||||
struct
|
||||
{
|
||||
UCHAR Master;
|
||||
UCHAR Slave;
|
||||
};
|
||||
USHORT Both;
|
||||
} PIC_MASK, *PPIC_MASK;
|
44
sdk/include/reactos/drivers/pc98/rtc.h
Normal file
44
sdk/include/reactos/drivers/pc98/rtc.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* PROJECT: NEC PC-98 series onboard hardware
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: NEC uPD1990A/uPD4990A RTC header file
|
||||
* COPYRIGHT: Copyright 2020 Dmitry Borisov (di.sean@protonmail.com)
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define RTC_IO_o_DATA 0x20
|
||||
/* Input terminals */
|
||||
#define RTC_DATA_INPUT 0x20
|
||||
#define RTC_CLOCK 0x10
|
||||
#define RTC_STROBE 0x08
|
||||
/* Commands, shift register 40 bit */
|
||||
#define RTC_CMD_REGISTER_HOLD 0x00
|
||||
#define RTC_CMD_REGISTER_SHIFT 0x01
|
||||
#define RTC_CMD_TIME_SET_COUNTER_HOLD 0x02
|
||||
#define RTC_CMD_TIME_READ 0x03
|
||||
#define RTC_CMD_TIMING_PULSE_64_HZ 0x04
|
||||
#define RTC_CMD_TIMING_PULSE_256_HZ 0x05
|
||||
#define RTC_CMD_TIMING_PULSE_2048_HZ 0x06
|
||||
#define RTC_CMD_SERIAL_TRANSFER_MODE 0x07
|
||||
/* Serial data commands, shift register 52 bit (uPD4990A only) */
|
||||
#define RTC_CMD_TIMING_PULSE_4096_HZ 0x07
|
||||
#define RTC_CMD_TIMING_PULSE_1_S_INT 0x08
|
||||
#define RTC_CMD_TIMING_PULSE_10_S_INT 0x09
|
||||
#define RTC_CMD_TIMING_PULSE_30_S_INT 0x0A
|
||||
#define RTC_CMD_TIMING_PULSE_60_S_INT 0x0B
|
||||
#define RTC_CMD_INTERRUPT_RESET 0x0C
|
||||
#define RTC_CMD_INTERRUPT_START 0x0D
|
||||
#define RTC_CMD_INTERRUPT_STOP 0x0E
|
||||
#define RTC_CMD_TEST_MODE 0x0F
|
||||
|
||||
#define RTC_IO_o_MODE 0x22
|
||||
|
||||
#define RTC_IO_o_INT_CLOCK_DIVISOR 0x128
|
||||
#define RTC_INT_CLOCK_DIVISOR_64 0x00
|
||||
#define RTC_INT_CLOCK_DIVISOR_32 0x01
|
||||
#define RTC_INT_CLOCK_DIVISOR_0 0x02
|
||||
#define RTC_INT_CLOCK_DIVISOR_16 0x03
|
||||
|
||||
#define RTC_IO_i_MODE 0x22
|
||||
#define RTC_IO_i_INTERRUPT_RESET 0x128
|
|
@ -8,7 +8,12 @@
|
|||
#pragma once
|
||||
|
||||
#define PPI_IO_o_PORT_C 0x35
|
||||
|
||||
#define PPI_IO_o_CONTROL 0x37
|
||||
#define PPI_TIMER_1_GATE_TO_SPEAKER 0x06
|
||||
#define PPI_TIMER_1_UNGATE_TO_SPEAKER 0x07
|
||||
#define PPI_SHUTDOWN_1_ENABLE 0x0B
|
||||
#define PPI_SHUTDOWN_0_ENABLE 0x0F
|
||||
|
||||
#define PPI_IO_i_PORT_A 0x31
|
||||
#define PPI_IO_i_PORT_B 0x33
|
||||
|
@ -64,19 +69,3 @@ typedef union _SYSTEM_CONTROL_PORT_C_REGISTER
|
|||
};
|
||||
UCHAR Bits;
|
||||
} SYSTEM_CONTROL_PORT_C_REGISTER, *PSYSTEM_CONTROL_PORT_C_REGISTER;
|
||||
|
||||
typedef union _SYSTEM_CONTROL_PORT_REGISTER
|
||||
{
|
||||
struct
|
||||
{
|
||||
UCHAR InterruptEnableRxReady:1;
|
||||
UCHAR InterruptEnableTxEmpty:1;
|
||||
UCHAR InterruptEnableTxReady:1;
|
||||
UCHAR Timer1GateToSpeaker:1;
|
||||
UCHAR Mcke:1;
|
||||
UCHAR Shut1:1;
|
||||
UCHAR PrinterStrobeSignal:1;
|
||||
UCHAR Shut0:1;
|
||||
};
|
||||
UCHAR Bits;
|
||||
} SYSTEM_CONTROL_PORT_REGISTER, *PSYSTEM_CONTROL_PORT_REGISTER;
|
||||
|
|
Loading…
Reference in a new issue