[FREELDR] Add Serial ports detection in DetectIsaBios() (#1829)

CORE-16216
This commit is contained in:
Stanislav Motylkov 2019-08-16 21:00:25 +03:00 committed by Hermès BÉLUSCA - MAÏTO
parent 2faee11672
commit 7497b81e5b
4 changed files with 95 additions and 20 deletions

View file

@ -636,23 +636,11 @@ DetectSerialPointerPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey,
}
}
static
VOID
DetectSerialPorts(PCONFIGURATION_COMPONENT_DATA BusKey)
ULONG
PcGetSerialPort(ULONG Index, PULONG Irq)
{
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 Base;
CHAR Buffer[80];
static const ULONG PcIrq[MAX_COM_PORTS] = {4, 3, 4, 3};
PUSHORT BasePtr;
ULONG ControllerNumber = 0;
PCONFIGURATION_COMPONENT_DATA ControllerKey;
ULONG i;
ULONG Size;
TRACE("DetectSerialPorts()\n");
/*
* The BIOS data area 0x400 holds the address of the first valid COM port.
@ -660,10 +648,30 @@ DetectSerialPorts(PCONFIGURATION_COMPONENT_DATA BusKey)
* Infos at: http://www.bioscentral.com/misc/bda.htm
*/
BasePtr = (PUSHORT)0x400;
*Irq = PcIrq[Index];
for (i = 0; i < MAX_COM_PORTS; i++, BasePtr++)
return (ULONG) *(BasePtr + Index);
}
VOID
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;
ULONG Base;
CHAR Buffer[80];
ULONG ControllerNumber = 0;
PCONFIGURATION_COMPONENT_DATA ControllerKey;
ULONG i;
ULONG Size;
TRACE("DetectSerialPorts()\n");
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);

View file

@ -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 */
}

View file

@ -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);

View file

@ -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);