https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7497b81e5bd8ca2725ed2…
commit 7497b81e5bd8ca2725ed274b20422414e549f9ee
Author: Stanislav Motylkov <x86corez(a)gmail.com>
AuthorDate: Fri Aug 16 21:00:25 2019 +0300
Commit: Hermès BÉLUSCA - MAÏTO <hermes.belusca-maito(a)reactos.org>
CommitDate: Fri Aug 16 20:00:25 2019 +0200
[FREELDR] Add Serial ports detection in DetectIsaBios() (#1829)
CORE-16216
---
boot/freeldr/freeldr/arch/i386/machpc.c | 40 +++++++++++--------
boot/freeldr/freeldr/arch/i386/machxbox.c | 48 +++++++++++++++++++++++
boot/freeldr/freeldr/include/arch/i386/machxbox.h | 15 +++++++
boot/freeldr/freeldr/include/arch/pc/hardware.h | 4 ++
4 files changed, 91 insertions(+), 16 deletions(-)
diff --git a/boot/freeldr/freeldr/arch/i386/machpc.c
b/boot/freeldr/freeldr/arch/i386/machpc.c
index ede5441dfae..1929be4a93e 100644
--- a/boot/freeldr/freeldr/arch/i386/machpc.c
+++ b/boot/freeldr/freeldr/arch/i386/machpc.c
@@ -636,17 +636,32 @@ DetectSerialPointerPeripheral(PCONFIGURATION_COMPONENT_DATA
ControllerKey,
}
}
-static
+ULONG
+PcGetSerialPort(ULONG Index, PULONG Irq)
+{
+ static const ULONG PcIrq[MAX_COM_PORTS] = {4, 3, 4, 3};
+ PUSHORT BasePtr;
+
+ /*
+ * The BIOS data area 0x400 holds the address of the first valid COM port.
+ * Each COM port address is stored in a 2-byte field.
+ * Infos at:
http://www.bioscentral.com/misc/bda.htm
+ */
+ BasePtr = (PUSHORT)0x400;
+ *Irq = PcIrq[Index];
+
+ return (ULONG) *(BasePtr + Index);
+}
+
VOID
-DetectSerialPorts(PCONFIGURATION_COMPONENT_DATA BusKey)
+DetectSerialPorts(PCONFIGURATION_COMPONENT_DATA BusKey, GET_SERIAL_PORT
MachGetSerialPort, ULONG Count)
{
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
PCM_SERIAL_DEVICE_DATA SerialDeviceData;
- ULONG Irq[MAX_COM_PORTS] = {4, 3, 4, 3};
+ ULONG Irq;
ULONG Base;
CHAR Buffer[80];
- PUSHORT BasePtr;
ULONG ControllerNumber = 0;
PCONFIGURATION_COMPONENT_DATA ControllerKey;
ULONG i;
@@ -654,16 +669,9 @@ DetectSerialPorts(PCONFIGURATION_COMPONENT_DATA BusKey)
TRACE("DetectSerialPorts()\n");
- /*
- * The BIOS data area 0x400 holds the address of the first valid COM port.
- * Each COM port address is stored in a 2-byte field.
- * Infos at:
http://www.bioscentral.com/misc/bda.htm
- */
- BasePtr = (PUSHORT)0x400;
-
- for (i = 0; i < MAX_COM_PORTS; i++, BasePtr++)
+ for (i = 0; i < Count; i++)
{
- Base = (ULONG) * BasePtr;
+ Base = MachGetSerialPort(i, &Irq);
if ((Base == 0) || !CpDoesPortExist(UlongToPtr(Base)))
continue;
@@ -703,8 +711,8 @@ DetectSerialPorts(PCONFIGURATION_COMPONENT_DATA BusKey)
PartialDescriptor->Type = CmResourceTypeInterrupt;
PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
- PartialDescriptor->u.Interrupt.Level = Irq[i];
- PartialDescriptor->u.Interrupt.Vector = Irq[i];
+ PartialDescriptor->u.Interrupt.Level = Irq;
+ PartialDescriptor->u.Interrupt.Vector = Irq;
PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
/* Set serial data (device specific) */
@@ -1319,7 +1327,7 @@ DetectIsaBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG
*BusNumber)
/* Detect ISA/BIOS devices */
DetectBiosDisks(SystemKey, BusKey);
- DetectSerialPorts(BusKey);
+ DetectSerialPorts(BusKey, PcGetSerialPort, MAX_COM_PORTS);
DetectParallelPorts(BusKey);
DetectKeyboardController(BusKey);
DetectPS2Mouse(BusKey);
diff --git a/boot/freeldr/freeldr/arch/i386/machxbox.c
b/boot/freeldr/freeldr/arch/i386/machxbox.c
index 4b96228f1cf..b3cd4f5616e 100644
--- a/boot/freeldr/freeldr/arch/i386/machxbox.c
+++ b/boot/freeldr/freeldr/arch/i386/machxbox.c
@@ -35,6 +35,53 @@ XboxFindPciBios(PPCI_REGISTRY_INFO BusData)
return TRUE;
}
+extern
+VOID
+DetectSerialPointerPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey, PUCHAR Base);
+
+static
+ULONG
+XboxGetSerialPort(ULONG Index, PULONG Irq)
+{
+ /*
+ * Xbox may have maximum two Serial COM ports
+ * if the Super I/O chip is connected via LPC
+ */
+ static const UCHAR Device[MAX_XBOX_COM_PORTS] = {LPC_DEVICE_SERIAL_PORT_1,
LPC_DEVICE_SERIAL_PORT_2};
+ ULONG ComBase = 0;
+
+ // Enter Configuration
+ WRITE_PORT_UCHAR(LPC_IO_BASE, LPC_ENTER_CONFIG_KEY);
+
+ // Select serial device
+ WRITE_PORT_UCHAR(LPC_IO_BASE, LPC_CONFIG_DEVICE_NUMBER);
+ WRITE_PORT_UCHAR(LPC_IO_BASE + 1, Device[Index]);
+
+ // Check if selected device is active
+ WRITE_PORT_UCHAR(LPC_IO_BASE, LPC_CONFIG_DEVICE_ACTIVATE);
+ if (READ_PORT_UCHAR(LPC_IO_BASE + 1) == 1)
+ {
+ // Read LSB
+ WRITE_PORT_UCHAR(LPC_IO_BASE, LPC_CONFIG_DEVICE_BASE_ADDRESS_LOW);
+ ComBase = READ_PORT_UCHAR(LPC_IO_BASE + 1);
+ // Read MSB
+ WRITE_PORT_UCHAR(LPC_IO_BASE, LPC_CONFIG_DEVICE_BASE_ADDRESS_HIGH);
+ ComBase |= (READ_PORT_UCHAR(LPC_IO_BASE + 1) << 8);
+ // Read IRQ
+ WRITE_PORT_UCHAR(LPC_IO_BASE, LPC_CONFIG_DEVICE_INTERRUPT);
+ *Irq = READ_PORT_UCHAR(LPC_IO_BASE + 1);
+ }
+
+ // Exit Configuration
+ WRITE_PORT_UCHAR(LPC_IO_BASE, LPC_EXIT_CONFIG_KEY);
+
+ return ComBase;
+}
+
+extern
+VOID
+DetectSerialPorts(PCONFIGURATION_COMPONENT_DATA BusKey, GET_SERIAL_PORT
MachGetSerialPort, ULONG Count);
+
VOID
XboxGetExtendedBIOSData(PULONG ExtendedBIOSDataArea, PULONG ExtendedBIOSDataSize)
{
@@ -155,6 +202,7 @@ DetectIsaBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG
*BusNumber)
/* Detect ISA/BIOS devices */
DetectBiosDisks(SystemKey, BusKey);
+ DetectSerialPorts(BusKey, XboxGetSerialPort, MAX_XBOX_COM_PORTS);
/* FIXME: Detect more ISA devices */
}
diff --git a/boot/freeldr/freeldr/include/arch/i386/machxbox.h
b/boot/freeldr/freeldr/include/arch/i386/machxbox.h
index d1c42a40bae..f481bbde8f9 100644
--- a/boot/freeldr/freeldr/include/arch/i386/machxbox.h
+++ b/boot/freeldr/freeldr/include/arch/i386/machxbox.h
@@ -22,6 +22,21 @@
#include "mm.h"
#endif
+#define MAX_XBOX_COM_PORTS 2
+
+#define LPC_IO_BASE 0x2E
+#define LPC_ENTER_CONFIG_KEY 0x55
+#define LPC_EXIT_CONFIG_KEY 0xAA
+
+#define LPC_DEVICE_SERIAL_PORT_1 0x4
+#define LPC_DEVICE_SERIAL_PORT_2 0x5
+
+#define LPC_CONFIG_DEVICE_NUMBER 0x07
+#define LPC_CONFIG_DEVICE_ACTIVATE 0x30
+#define LPC_CONFIG_DEVICE_BASE_ADDRESS_HIGH 0x60
+#define LPC_CONFIG_DEVICE_BASE_ADDRESS_LOW 0x61
+#define LPC_CONFIG_DEVICE_INTERRUPT 0x70
+
extern UCHAR XboxFont8x16[256 * 16];
VOID XboxMachInit(const char *CmdLine);
diff --git a/boot/freeldr/freeldr/include/arch/pc/hardware.h
b/boot/freeldr/freeldr/include/arch/pc/hardware.h
index bc6aad11971..56e6028ed06 100644
--- a/boot/freeldr/freeldr/include/arch/pc/hardware.h
+++ b/boot/freeldr/freeldr/include/arch/pc/hardware.h
@@ -44,6 +44,10 @@ BOOLEAN
extern FIND_PCI_BIOS FindPciBios;
+typedef
+ULONG
+(*GET_SERIAL_PORT)(ULONG Index, PULONG Irq);
+
VOID
DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA SystemKey,
PCONFIGURATION_COMPONENT_DATA BusKey);