freeldr: Remove duplicated / unused files for amd64 architecture

See issue #4672 for more details.

svn path=/trunk/; revision=41834
This commit is contained in:
Timo Kreuzer 2009-07-09 21:41:58 +00:00
parent e99d1fe3f9
commit 2d834b1bdd
13 changed files with 0 additions and 4901 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,5 +0,0 @@
/* No need to duplicate code ; import the i386 version */
#include "../i386/hwacpi.c"
/* EOF */

View file

@ -1,98 +0,0 @@
/*
* FreeLoader
*
* Copyright (C) 2004 Eric Kohl
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <freeldr.h>
#define NDEBUG
#include <debug.h>
static BOOLEAN
FindApmBios(VOID)
{
REGS RegsIn;
REGS RegsOut;
RegsIn.b.ah = 0x53;
RegsIn.b.al = 0x00;
RegsIn.w.bx = 0x0000;
Int386(0x15, &RegsIn, &RegsOut);
if (INT386_SUCCESS(RegsOut))
{
DbgPrint((DPRINT_HWDETECT, "Found APM BIOS\n"));
DbgPrint((DPRINT_HWDETECT, "AH: %x\n", RegsOut.b.ah));
DbgPrint((DPRINT_HWDETECT, "AL: %x\n", RegsOut.b.al));
DbgPrint((DPRINT_HWDETECT, "BH: %x\n", RegsOut.b.bh));
DbgPrint((DPRINT_HWDETECT, "BL: %x\n", RegsOut.b.bl));
DbgPrint((DPRINT_HWDETECT, "CX: %x\n", RegsOut.w.cx));
return TRUE;
}
DbgPrint((DPRINT_HWDETECT, "No APM BIOS found\n"));
return FALSE;
}
VOID
DetectApmBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
{
PCONFIGURATION_COMPONENT_DATA BiosKey;
CM_PARTIAL_RESOURCE_LIST PartialResourceList;
if (FindApmBios())
{
/* Create new bus key */
FldrCreateComponentKey(SystemKey,
L"MultifunctionAdapter",
*BusNumber,
AdapterClass,
MultiFunctionAdapter,
&BiosKey);
/* Set 'Component Information' */
FldrSetComponentInformation(BiosKey,
0x0,
0x0,
0xFFFFFFFF);
/* Set 'Configuration Data' value */
memset(&PartialResourceList, 0, sizeof(CM_PARTIAL_RESOURCE_LIST));
PartialResourceList.Version = 0;
PartialResourceList.Revision = 0;
PartialResourceList.Count = 0;
FldrSetConfigurationData(BiosKey,
&PartialResourceList,
sizeof(CM_PARTIAL_RESOURCE_LIST) -
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
/* Increment bus number */
(*BusNumber)++;
/* Set 'Identifier' value */
FldrSetIdentifier(BiosKey, "APM");
}
/* FIXME: Add configuration data */
}
/* EOF */

View file

@ -1,346 +0,0 @@
/*
* FreeLoader
*
* Copyright (C) 2004 Eric Kohl
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <freeldr.h>
#define NDEBUG
#include <debug.h>
typedef struct _ROUTING_SLOT
{
UCHAR BusNumber;
UCHAR DeviceNumber;
UCHAR LinkA;
USHORT BitmapA;
UCHAR LinkB;
USHORT BitmapB;
UCHAR LinkC;
USHORT BitmapC;
UCHAR LinkD;
USHORT BitmapD;
UCHAR SlotNumber;
UCHAR Reserved;
} __attribute__((packed)) ROUTING_SLOT, *PROUTING_SLOT;
typedef struct _PCI_IRQ_ROUTING_TABLE
{
ULONG Signature;
USHORT Version;
USHORT Size;
UCHAR RouterBus;
UCHAR RouterSlot;
USHORT ExclusiveIRQs;
ULONG CompatibleRouter;
ULONG MiniportData;
UCHAR Reserved[11];
UCHAR Checksum;
ROUTING_SLOT Slot[1];
} __attribute__((packed)) PCI_IRQ_ROUTING_TABLE, *PPCI_IRQ_ROUTING_TABLE;
typedef struct _PCI_REGISTRY_INFO
{
UCHAR MajorRevision;
UCHAR MinorRevision;
UCHAR NoBuses;
UCHAR HardwareMechanism;
} PCI_REGISTRY_INFO, *PPCI_REGISTRY_INFO;
static PPCI_IRQ_ROUTING_TABLE
GetPciIrqRoutingTable(VOID)
{
PPCI_IRQ_ROUTING_TABLE Table;
PUCHAR Ptr;
ULONG Sum;
ULONG i;
Table = (PPCI_IRQ_ROUTING_TABLE)0xF0000;
while ((ULONG_PTR)Table < 0x100000)
{
if (Table->Signature == 0x52495024)
{
DbgPrint((DPRINT_HWDETECT,
"Found signature\n"));
Ptr = (PUCHAR)Table;
Sum = 0;
for (i = 0; i < Table->Size; i++)
{
Sum += Ptr[i];
}
if ((Sum & 0xFF) != 0)
{
DbgPrint((DPRINT_HWDETECT,
"Invalid routing table\n"));
return NULL;
}
DbgPrint((DPRINT_HWDETECT,
"Valid checksum\n"));
return Table;
}
Table = (PPCI_IRQ_ROUTING_TABLE)((ULONG_PTR)Table + 0x10);
}
return NULL;
}
static BOOLEAN
FindPciBios(PPCI_REGISTRY_INFO BusData)
{
REGS RegsIn;
REGS RegsOut;
RegsIn.b.ah = 0xB1; /* Subfunction B1h */
RegsIn.b.al = 0x01; /* PCI BIOS present */
Int386(0x1A, &RegsIn, &RegsOut);
if (INT386_SUCCESS(RegsOut) && RegsOut.d.edx == 0x20494350 && RegsOut.b.ah == 0)
{
DbgPrint((DPRINT_HWDETECT, "Found PCI bios\n"));
DbgPrint((DPRINT_HWDETECT, "AL: %x\n", RegsOut.b.al));
DbgPrint((DPRINT_HWDETECT, "BH: %x\n", RegsOut.b.bh));
DbgPrint((DPRINT_HWDETECT, "BL: %x\n", RegsOut.b.bl));
DbgPrint((DPRINT_HWDETECT, "CL: %x\n", RegsOut.b.cl));
BusData->NoBuses = RegsOut.b.cl + 1;
BusData->MajorRevision = RegsOut.b.bh;
BusData->MinorRevision = RegsOut.b.bl;
BusData->HardwareMechanism = RegsOut.b.cl;
return TRUE;
}
DbgPrint((DPRINT_HWDETECT, "No PCI bios found\n"));
return FALSE;
}
static VOID
DetectPciIrqRoutingTable(PCONFIGURATION_COMPONENT_DATA BusKey)
{
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
PPCI_IRQ_ROUTING_TABLE Table;
PCONFIGURATION_COMPONENT_DATA TableKey;
ULONG Size;
Table = GetPciIrqRoutingTable();
if (Table != NULL)
{
DbgPrint((DPRINT_HWDETECT, "Table size: %u\n", Table->Size));
FldrCreateComponentKey(BusKey,
L"RealModeIrqRoutingTable",
0,
PeripheralClass,
RealModeIrqRoutingTable,
&TableKey);
/* Set 'Component Information' */
FldrSetComponentInformation(TableKey,
0x0,
0x0,
0xFFFFFFFF);
/* Set 'Identifier' value */
FldrSetIdentifier(TableKey, "PCI Real-mode IRQ Routing Table");
/* Set 'Configuration Data' value */
Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors) +
2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) + Table->Size;
PartialResourceList = MmAllocateMemory(Size);
if (PartialResourceList == NULL)
{
DbgPrint((DPRINT_HWDETECT,
"Failed to allocate resource descriptor\n"));
return;
}
/* Initialize resource descriptor */
memset(PartialResourceList, 0, Size);
PartialResourceList->Version = 1;
PartialResourceList->Revision = 1;
PartialResourceList->Count = 2;
PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
PartialDescriptor->Type = CmResourceTypeBusNumber;
PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
PartialDescriptor->u.BusNumber.Start = 0;
PartialDescriptor->u.BusNumber.Length = 1;
PartialDescriptor = &PartialResourceList->PartialDescriptors[1];
PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
PartialDescriptor->u.DeviceSpecificData.DataSize = Table->Size;
memcpy(&PartialResourceList->PartialDescriptors[2],
Table, Table->Size);
/* Set 'Configuration Data' value */
FldrSetConfigurationData(TableKey, PartialResourceList, Size);
MmFreeMemory(PartialResourceList);
}
}
VOID
DetectPciBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
{
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
PCI_REGISTRY_INFO BusData;
PCONFIGURATION_COMPONENT_DATA BiosKey;
ULONG Size;
PCONFIGURATION_COMPONENT_DATA BusKey;
ULONG i;
CHAR szPci[] = "PCI";
/* Report the PCI BIOS */
if (FindPciBios(&BusData))
{
/* Create new bus key */
FldrCreateComponentKey(SystemKey,
L"MultifunctionAdapter",
*BusNumber,
AdapterClass,
MultiFunctionAdapter,
&BiosKey);
/* Set 'Component Information' */
FldrSetComponentInformation(BiosKey,
0x0,
0x0,
0xFFFFFFFF);
/* Increment bus number */
(*BusNumber)++;
/* Set 'Identifier' value */
FldrSetIdentifier(BiosKey, "PCI BIOS");
/* Set 'Configuration Data' value */
Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST,
PartialDescriptors);
PartialResourceList = MmAllocateMemory(Size);
if (PartialResourceList == NULL)
{
DbgPrint((DPRINT_HWDETECT,
"Failed to allocate resource descriptor\n"));
return;
}
/* Initialize resource descriptor */
memset(PartialResourceList, 0, Size);
/* Set 'Configuration Data' value */
FldrSetConfigurationData(BiosKey, PartialResourceList, Size);
MmFreeMemory(PartialResourceList);
DetectPciIrqRoutingTable(BiosKey);
/* Report PCI buses */
for (i = 0; i < (ULONG)BusData.NoBuses; i++)
{
/* Create the bus key */
FldrCreateComponentKey(SystemKey,
L"MultifunctionAdapter",
*BusNumber,
AdapterClass,
MultiFunctionAdapter,
&BusKey);
/* Set 'Component Information' */
FldrSetComponentInformation(BusKey,
0x0,
0x0,
0xFFFFFFFF);
/* Check if this is the first bus */
if (i == 0)
{
/* Set 'Configuration Data' value */
Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST,
PartialDescriptors) +
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) +
sizeof(PCI_REGISTRY_INFO);
PartialResourceList = MmAllocateMemory(Size);
if (!PartialResourceList)
{
DbgPrint((DPRINT_HWDETECT,
"Failed to allocate resource descriptor\n"));
return;
}
/* Initialize resource descriptor */
memset(PartialResourceList, 0, Size);
PartialResourceList->Version = 1;
PartialResourceList->Revision = 1;
PartialResourceList->Count = 1;
PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
PartialDescriptor->u.DeviceSpecificData.DataSize = sizeof(PCI_REGISTRY_INFO);
memcpy(&PartialResourceList->PartialDescriptors[1],
&BusData,
sizeof(PCI_REGISTRY_INFO));
/* Set 'Configuration Data' value */
FldrSetConfigurationData(BusKey, PartialResourceList, Size);
MmFreeMemory(PartialResourceList);
}
else
{
/* Set 'Configuration Data' value */
Size = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST,
PartialDescriptors);
PartialResourceList = MmAllocateMemory(Size);
if (!PartialResourceList)
{
DbgPrint((DPRINT_HWDETECT,
"Failed to allocate resource descriptor\n"));
return;
}
/* Initialize resource descriptor */
memset(PartialResourceList, 0, Size);
/* Set 'Configuration Data' value */
FldrSetConfigurationData(BusKey, PartialResourceList, Size);
MmFreeMemory(PartialResourceList);
}
/* Increment bus number */
(*BusNumber)++;
/* Set 'Identifier' value */
FldrSetIdentifier(BusKey, szPci);
}
}
}
/* EOF */

View file

@ -1,199 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <freeldr.h>
#define NDEBUG
#include <debug.h>
/////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS
/////////////////////////////////////////////////////////////////////////////////////////////
BOOLEAN DiskResetController(ULONG DriveNumber)
{
REGS RegsIn;
REGS RegsOut;
DbgPrint((DPRINT_DISK, "DiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DriveNumber));
// BIOS Int 13h, function 0 - Reset disk system
// AH = 00h
// DL = drive (if bit 7 is set both hard disks and floppy disks reset)
// Return:
// AH = status
// CF clear if successful
// CF set on error
RegsIn.b.ah = 0x00;
RegsIn.b.dl = DriveNumber;
// Reset the disk controller
Int386(0x13, &RegsIn, &RegsOut);
return INT386_SUCCESS(RegsOut);
}
BOOLEAN DiskInt13ExtensionsSupported(ULONG DriveNumber)
{
REGS RegsIn;
REGS RegsOut;
DbgPrint((DPRINT_DISK, "DiskInt13ExtensionsSupported()\n"));
// IBM/MS INT 13 Extensions - INSTALLATION CHECK
// AH = 41h
// BX = 55AAh
// DL = drive (80h-FFh)
// Return:
// CF set on error (extensions not supported)
// AH = 01h (invalid function)
// CF clear if successful
// BX = AA55h if installed
// AH = major version of extensions
// 01h = 1.x
// 20h = 2.0 / EDD-1.0
// 21h = 2.1 / EDD-1.1
// 30h = EDD-3.0
// AL = internal use
// CX = API subset support bitmap
// DH = extension version (v2.0+ ??? -- not present in 1.x)
//
// Bitfields for IBM/MS INT 13 Extensions API support bitmap
// Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
// Bit 1, removable drive controller functions (AH=45h,46h,48h,49h,INT 15/AH=52h) supported
// Bit 2, enhanced disk drive (EDD) functions (AH=48h,AH=4Eh) supported
// extended drive parameter table is valid
// Bits 3-15 reserved
RegsIn.b.ah = 0x41;
RegsIn.w.bx = 0x55AA;
RegsIn.b.dl = DriveNumber;
// Reset the disk controller
Int386(0x13, &RegsIn, &RegsOut);
if (!INT386_SUCCESS(RegsOut))
{
// CF set on error (extensions not supported)
return FALSE;
}
if (RegsOut.w.bx != 0xAA55)
{
// BX = AA55h if installed
return FALSE;
}
// Note:
// The original check is too strict because some BIOSes report that
// extended disk access functions are not suported when booting
// from a CD (e.g. Phoenix BIOS v6.00PG). Argh!
#if 0
if (!(RegsOut.w.cx & 0x0001))
{
// CX = API subset support bitmap
// Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
return FALSE;
}
#endif
// Use this relaxed check instead
if (RegsOut.w.cx == 0x0000)
{
// CX = API subset support bitmap
return FALSE;
}
return TRUE;
}
VOID DiskStopFloppyMotor(VOID)
{
WRITE_PORT_UCHAR((PUCHAR)0x3F2, 0);
}
BOOLEAN DiskGetExtendedDriveParameters(ULONG DriveNumber, PVOID Buffer, USHORT BufferSize)
{
REGS RegsIn;
REGS RegsOut;
PUSHORT Ptr = (PUSHORT)(BIOSCALLBUFFER);
DbgPrint((DPRINT_DISK, "DiskGetExtendedDriveParameters()\n"));
// Initialize transfer buffer
*Ptr = BufferSize;
// BIOS Int 13h, function 48h - Get drive parameters
// AH = 48h
// DL = drive (bit 7 set for hard disk)
// DS:SI = result buffer
// Return:
// CF set on error
// AH = status (07h)
// CF clear if successful
// AH = 00h
// DS:SI -> result buffer
RegsIn.b.ah = 0x48;
RegsIn.b.dl = DriveNumber;
RegsIn.x.ds = BIOSCALLBUFSEGMENT; // DS:SI -> result buffer
RegsIn.w.si = BIOSCALLBUFOFFSET;
// Get drive parameters
Int386(0x13, &RegsIn, &RegsOut);
if (!INT386_SUCCESS(RegsOut))
{
return FALSE;
}
memcpy(Buffer, Ptr, BufferSize);
DbgPrint((DPRINT_DISK, "size of buffer: %x\n", Ptr[0]));
DbgPrint((DPRINT_DISK, "information flags: %x\n", Ptr[1]));
DbgPrint((DPRINT_DISK, "number of physical cylinders on drive: %u\n", *(PULONG)&Ptr[2]));
DbgPrint((DPRINT_DISK, "number of physical heads on drive: %u\n", *(PULONG)&Ptr[4]));
DbgPrint((DPRINT_DISK, "number of physical sectors per track: %u\n", *(PULONG)&Ptr[6]));
DbgPrint((DPRINT_DISK, "total number of sectors on drive: %I64u\n", *(unsigned long long*)&Ptr[8]));
DbgPrint((DPRINT_DISK, "bytes per sector: %u\n", Ptr[12]));
if (Ptr[0] >= 0x1e)
{
DbgPrint((DPRINT_DISK, "EED configuration parameters: %x:%x\n", Ptr[13], Ptr[14]));
if (Ptr[13] != 0xffff && Ptr[14] != 0xffff)
{
PUCHAR SpecPtr = (PUCHAR)(ULONG_PTR)((Ptr[13] << 4) + Ptr[14]);
DbgPrint((DPRINT_DISK, "SpecPtr: %x\n", SpecPtr));
DbgPrint((DPRINT_DISK, "physical I/O port base address: %x\n", *(PUSHORT)&SpecPtr[0]));
DbgPrint((DPRINT_DISK, "disk-drive control port address: %x\n", *(PUSHORT)&SpecPtr[2]));
DbgPrint((DPRINT_DISK, "drive flags: %x\n", SpecPtr[4]));
DbgPrint((DPRINT_DISK, "proprietary information: %x\n", SpecPtr[5]));
DbgPrint((DPRINT_DISK, "IRQ for drive: %u\n", SpecPtr[6]));
DbgPrint((DPRINT_DISK, "sector count for multi-sector transfers: %u\n", SpecPtr[7]));
DbgPrint((DPRINT_DISK, "DMA control: %x\n", SpecPtr[8]));
DbgPrint((DPRINT_DISK, "programmed I/O control: %x\n", SpecPtr[9]));
DbgPrint((DPRINT_DISK, "drive options: %x\n", *(PUSHORT)&SpecPtr[10]));
}
}
if (Ptr[0] >= 0x42)
{
DbgPrint((DPRINT_DISK, "signature: %x\n", Ptr[15]));
}
return TRUE;
}
/* EOF */

View file

@ -1,87 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <freeldr.h>
void PcBeep(void)
{
sound(700);
delay(200);
sound(0);
}
void delay(unsigned msec)
{
REGS Regs;
unsigned usec;
unsigned msec_this;
// Int 15h AH=86h
// BIOS - WAIT (AT,PS)
//
// AH = 86h
// CX:DX = interval in microseconds
// Return:
// CF clear if successful (wait interval elapsed)
// CF set on error or AH=83h wait already in progress
// AH = status (see #00496)
// Note: The resolution of the wait period is 977 microseconds on
// many systems because many BIOSes use the 1/1024 second fast
// interrupt from the AT real-time clock chip which is available on INT 70;
// because newer BIOSes may have much more precise timers available, it is
// not possible to use this function accurately for very short delays unless
// the precise behavior of the BIOS is known (or found through testing)
while (msec)
{
msec_this = msec;
if (msec_this > 4000)
{
msec_this = 4000;
}
usec = msec_this * 1000;
Regs.b.ah = 0x86;
Regs.w.cx = usec >> 16;
Regs.w.dx = usec & 0xffff;
Int386(0x15, &Regs, &Regs);
msec -= msec_this;
}
}
void sound(int freq)
{
int scale;
if (freq == 0)
{
WRITE_PORT_UCHAR((PUCHAR)0x61, READ_PORT_UCHAR((PUCHAR)0x61) & ~3);
return;
}
scale = 1193046 / freq;
WRITE_PORT_UCHAR((PUCHAR)0x43, 0xb6);
WRITE_PORT_UCHAR((PUCHAR)0x42, scale & 0xff);
WRITE_PORT_UCHAR((PUCHAR)0x42, scale >> 8);
WRITE_PORT_UCHAR((PUCHAR)0x61, READ_PORT_UCHAR((PUCHAR)0x61) | 3);
}

View file

@ -1,244 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
* Portions from Linux video.S - Display adapter & video mode setup, version 2.13 (14-May-99)
* Copyright (C) 1995 -- 1999 Martin Mares <mj@ucw.cz>
* Based on the original setup.S code (C) Linus Torvalds and Mats Anderson
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <freeldr.h>
#define NDEBUG
#include <debug.h>
typedef struct
{
UCHAR Signature[4]; // (ret) signature ("VESA")
// (call) VESA 2.0 request signature ("VBE2"), required to receive
// version 2.0 info
USHORT VesaVersion; // VESA version number (one-digit minor version -- 0102h = v1.2)
ULONG OemNamePtr; // pointer to OEM name
// "761295520" for ATI
ULONG Capabilities; // capabilities flags (see #00078)
ULONG SupportedModeListPtr; // pointer to list of supported VESA and OEM video modes
// (list of words terminated with FFFFh)
USHORT TotalVideoMemory; // total amount of video memory in 64K blocks
// ---VBE v1.x ---
//UCHAR Reserved[236];
// ---VBE v2.0 ---
USHORT OemSoftwareVersion; // OEM software version (BCD, high byte = major, low byte = minor)
ULONG VendorNamePtr; // pointer to vendor name
ULONG ProductNamePtr; // pointer to product name
ULONG ProductRevisionStringPtr; // pointer to product revision string
USHORT VBE_AF_Version; // (if capabilities bit 3 set) VBE/AF version (BCD)
// 0100h for v1.0P
ULONG AcceleratedModeListPtr; // (if capabilities bit 3 set) pointer to list of supported
// accelerated video modes (list of words terminated with FFFFh)
UCHAR Reserved[216]; // reserved for VBE implementation
UCHAR ScratchPad[256]; // OEM scratchpad (for OEM strings, etc.)
} PACKED VESA_SVGA_INFO, *PVESA_SVGA_INFO;
// Bitfields for VESA capabilities:
//
// Bit(s) Description (Table 00078)
// 0 DAC can be switched into 8-bit mode
// 1 non-VGA controller
// 2 programmed DAC with blank bit (i.e. only during blanking interval)
// 3 (VBE v3.0) controller supports hardware stereoscopic signalling
// 3 controller supports VBE/AF v1.0P extensions
// 4 (VBE v3.0) if bit 3 set:
// =0 stereo signalling via external VESA stereo connector
// =1 stereo signalling via VESA EVC connector
// 4 (VBE/AF v1.0P) must call EnableDirectAccess to access framebuffer
// 5 (VBE/AF v1.0P) controller supports hardware mouse cursor
// 6 (VBE/AF v1.0P) controller supports hardware clipping
// 7 (VBE/AF v1.0P) controller supports transparent BitBLT
// 8-31 reserved (0)
// Notes: The list of supported video modes is stored in the reserved
// portion of the SuperVGA information record by some implementations,
// and it may thus be necessary to either copy the mode list or use a
// different buffer for all subsequent VESA calls. Not all of the video
// modes in the list of mode numbers may be supported, e.g. if they require
// more memory than currently installed or are not supported by the
// attached monitor. Check any mode you intend to use through AX=4F01h first..
// The 1.1 VESA document specifies 242 reserved bytes at the end, so the
// buffer should be 262 bytes to ensure that it is not overrun; for v2.0,
// the buffer should be 512 bytes. The S3 specific video modes will most
// likely follow the FFFFh terminator at the end of the standard modes.
// A search must then be made to find them, FFFFh will also terminate this
// second list. In some cases, only a "stub" VBE may be present, supporting
// only AX=4F00h; this case may be assumed if the list of supported video modes
// is empty (consisting of a single word of FFFFh)
#if 0
static VOID BiosSetVideoFont8x16(VOID)
{
REGS Regs;
// Int 10h AX=1114h
// VIDEO - TEXT-MODE CHARGEN - LOAD ROM 8x16 CHARACTER SET (VGA)
//
// AX = 1114h
// BL = block to load
// Return:
// Nothing
Regs.w.ax = 0x1114;
Regs.b.bl = 0;
Int386(0x10, &Regs, &Regs);
}
static VOID VideoSetTextCursorPosition(ULONG X, ULONG Y)
{
}
static ULONG VideoGetTextCursorPositionX(VOID)
{
REGS Regs;
// Int 10h AH=03h
// VIDEO - GET CURSOR POSITION AND SIZE
//
// AH = 03h
// BH = page number
// 0-3 in modes 2&3
// 0-7 in modes 0&1
// 0 in graphics modes
// Return:
// AX = 0000h (Phoenix BIOS)
// CH = start scan line
// CL = end scan line
// DH = row (00h is top)
// DL = column (00h is left)
Regs.b.ah = 0x03;
Regs.b.bh = 0x00;
Int386(0x10, &Regs, &Regs);
return Regs.b.dl;
}
static ULONG VideoGetTextCursorPositionY(VOID)
{
REGS Regs;
// Int 10h AH=03h
// VIDEO - GET CURSOR POSITION AND SIZE
//
// AH = 03h
// BH = page number
// 0-3 in modes 2&3
// 0-7 in modes 0&1
// 0 in graphics modes
// Return:
// AX = 0000h (Phoenix BIOS)
// CH = start scan line
// CL = end scan line
// DH = row (00h is top)
// DL = column (00h is left)
Regs.b.ah = 0x03;
Regs.b.bh = 0x00;
Int386(0x10, &Regs, &Regs);
return Regs.b.dh;
}
#endif
USHORT BiosIsVesaSupported(VOID)
{
REGS Regs;
PVESA_SVGA_INFO SvgaInfo = (PVESA_SVGA_INFO)BIOSCALLBUFFER;
//USHORT* VideoModes;
//USHORT Index;
DbgPrint((DPRINT_UI, "BiosIsVesaSupported()\n"));
RtlZeroMemory(SvgaInfo, sizeof(VESA_SVGA_INFO));
// Make sure we receive version 2.0 info
SvgaInfo->Signature[0] = 'V';
SvgaInfo->Signature[1] = 'B';
SvgaInfo->Signature[2] = 'E';
SvgaInfo->Signature[3] = '2';
// Int 10h AX=4F00h
// VESA SuperVGA BIOS (VBE) - GET SuperVGA INFORMATION
//
// AX = 4F00h
// ES:DI -> buffer for SuperVGA information (see #00077)
// Return:
// AL = 4Fh if function supported
// AH = status
// 00h successful
// ES:DI buffer filled
// 01h failed
// ---VBE v2.0---
// 02h function not supported by current hardware configuration
// 03h function invalid in current video mode
//
// Determine whether VESA BIOS extensions are present and the
// capabilities supported by the display adapter
//
// Installation check;VESA SuperVGA
Regs.w.ax = 0x4F00;
Regs.w.es = BIOSCALLBUFSEGMENT;
Regs.w.di = BIOSCALLBUFOFFSET;
Int386(0x10, &Regs, &Regs);
DbgPrint((DPRINT_UI, "AL = 0x%x\n", Regs.b.al));
DbgPrint((DPRINT_UI, "AH = 0x%x\n", Regs.b.ah));
if (Regs.w.ax != 0x004F)
{
DbgPrint((DPRINT_UI, "Failed.\n"));
return 0x0000;
}
DbgPrint((DPRINT_UI, "Supported.\n"));
DbgPrint((DPRINT_UI, "SvgaInfo->Signature[4] = %c%c%c%c\n", SvgaInfo->Signature[0], SvgaInfo->Signature[1], SvgaInfo->Signature[2], SvgaInfo->Signature[3]));
DbgPrint((DPRINT_UI, "SvgaInfo->VesaVersion = v%d.%d\n", ((SvgaInfo->VesaVersion >> 8) & 0xFF), (SvgaInfo->VesaVersion & 0xFF)));
DbgPrint((DPRINT_UI, "SvgaInfo->OemNamePtr = 0x%x\n", SvgaInfo->OemNamePtr));
DbgPrint((DPRINT_UI, "SvgaInfo->Capabilities = 0x%x\n", SvgaInfo->Capabilities));
DbgPrint((DPRINT_UI, "SvgaInfo->VideoMemory = %dK\n", SvgaInfo->TotalVideoMemory * 64));
DbgPrint((DPRINT_UI, "---VBE v2.0 ---\n"));
DbgPrint((DPRINT_UI, "SvgaInfo->OemSoftwareVersion = v%d.%d\n", ((SvgaInfo->OemSoftwareVersion >> 8) & 0x0F) + (((SvgaInfo->OemSoftwareVersion >> 12) & 0x0F) * 10), (SvgaInfo->OemSoftwareVersion & 0x0F) + (((SvgaInfo->OemSoftwareVersion >> 4) & 0x0F) * 10)));
DbgPrint((DPRINT_UI, "SvgaInfo->VendorNamePtr = 0x%x\n", SvgaInfo->VendorNamePtr));
DbgPrint((DPRINT_UI, "SvgaInfo->ProductNamePtr = 0x%x\n", SvgaInfo->ProductNamePtr));
DbgPrint((DPRINT_UI, "SvgaInfo->ProductRevisionStringPtr = 0x%x\n", SvgaInfo->ProductRevisionStringPtr));
DbgPrint((DPRINT_UI, "SvgaInfo->VBE/AF Version = 0x%x (BCD WORD)\n", SvgaInfo->VBE_AF_Version));
//DbgPrint((DPRINT_UI, "\nSupported VESA and OEM video modes:\n"));
//VideoModes = (USHORT*)SvgaInfo->SupportedModeListPtr;
//for (Index=0; VideoModes[Index]!=0xFFFF; Index++)
//{
// DbgPrint((DPRINT_UI, "Mode %d: 0x%x\n", Index, VideoModes[Index]));
//}
//if (SvgaInfo->VesaVersion >= 0x0200)
//{
// DbgPrint((DPRINT_UI, "\nSupported accelerated video modes (VESA v2.0):\n"));
// VideoModes = (USHORT*)SvgaInfo->AcceleratedModeListPtr;
// for (Index=0; VideoModes[Index]!=0xFFFF; Index++)
// {
// DbgPrint((DPRINT_UI, "Mode %d: 0x%x\n", Index, VideoModes[Index]));
// }
//}
DbgPrint((DPRINT_UI, "\n"));
return SvgaInfo->VesaVersion;
}

View file

@ -1,70 +0,0 @@
/* $Id: machpc.c 32173 2008-02-07 00:43:09Z ros-arm-bringup $
*
* FreeLoader
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <freeldr.h>
VOID
MachInit(const char *CmdLine)
{
// EnableA20();
//DbgPrint((DPRINT_MEMORY, "MachInit.\n"));
/* Setup vtbl */
MachVtbl.ConsPutChar = PcConsPutChar;
MachVtbl.ConsKbHit = PcConsKbHit;
MachVtbl.ConsGetCh = PcConsGetCh;
MachVtbl.VideoClearScreen = PcVideoClearScreen;
MachVtbl.VideoSetDisplayMode = PcVideoSetDisplayMode;
MachVtbl.VideoGetDisplaySize = PcVideoGetDisplaySize;
MachVtbl.VideoGetBufferSize = PcVideoGetBufferSize;
MachVtbl.VideoSetTextCursorPosition = PcVideoSetTextCursorPosition;
MachVtbl.VideoSetTextCursorPosition = PcVideoSetTextCursorPosition;
MachVtbl.VideoHideShowTextCursor = PcVideoHideShowTextCursor;
MachVtbl.VideoPutChar = PcVideoPutChar;
MachVtbl.VideoCopyOffScreenBufferToVRAM = PcVideoCopyOffScreenBufferToVRAM;
MachVtbl.VideoIsPaletteFixed = PcVideoIsPaletteFixed;
MachVtbl.VideoSetPaletteColor = PcVideoSetPaletteColor;
MachVtbl.VideoGetPaletteColor = PcVideoGetPaletteColor;
MachVtbl.VideoSync = PcVideoSync;
MachVtbl.Beep = PcBeep;
MachVtbl.PrepareForReactOS = PcPrepareForReactOS;
MachVtbl.GetMemoryMap = PcMemGetMemoryMap;
MachVtbl.DiskGetBootVolume = DiskGetBootVolume;
MachVtbl.DiskGetSystemVolume = DiskGetSystemVolume;
MachVtbl.DiskGetBootPath = DiskGetBootPath;
MachVtbl.DiskGetBootDevice = DiskGetBootDevice;
MachVtbl.DiskBootingFromFloppy = DiskBootingFromFloppy;
MachVtbl.DiskNormalizeSystemPath = DiskNormalizeSystemPath;
MachVtbl.DiskReadLogicalSectors = PcDiskReadLogicalSectors;
MachVtbl.DiskGetPartitionEntry = DiskGetPartitionEntry;
MachVtbl.DiskGetDriveGeometry = PcDiskGetDriveGeometry;
MachVtbl.DiskGetCacheableBlockCount = PcDiskGetCacheableBlockCount;
MachVtbl.GetTime = PcGetTime;
MachVtbl.HwDetect = PcHwDetect;
}
VOID
PcPrepareForReactOS(IN BOOLEAN Setup)
{
//
// On PC, prepare video and turn off the floppy motor
//
// PcVideoPrepareForReactOS(Setup);
// DiskStopFloppyMotor();
}
/* EOF */

View file

@ -1,128 +0,0 @@
/* $Id: pccons.c 21917 2006-05-16 23:09:41Z hpoussin $
*
* FreeLoader
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <freeldr.h>
#define TEXTMODE_BUFFER 0xb8000
#define TEXTMODE_BUFFER_SIZE 0x8000
#define TEXT_COLS 80
#define TEXT_LINES 25
VOID
PcConsPutChar(int Ch)
{
REGS Regs;
/* If we are displaying a CR '\n' then do a LF also */
if ('\n' == Ch)
{
/* Display the LF */
PcConsPutChar('\r');
}
/* If we are displaying a TAB '\t' then display 8 spaces ' ' */
if ('\t' == Ch)
{
/* Display the 8 spaces ' ' */
PcConsPutChar(' ');
PcConsPutChar(' ');
PcConsPutChar(' ');
PcConsPutChar(' ');
PcConsPutChar(' ');
PcConsPutChar(' ');
PcConsPutChar(' ');
PcConsPutChar(' ');
return;
}
/* Int 10h AH=0Eh
* VIDEO - TELETYPE OUTPUT
*
* AH = 0Eh
* AL = character to write
* BH = page number
* BL = foreground color (graphics modes only)
*/
Regs.b.ah = 0x0E;
Regs.b.al = Ch;
Regs.w.bx = 1;
Int386(0x10, &Regs, &Regs);
}
BOOLEAN
PcConsKbHit(VOID)
{
REGS Regs;
/* Int 16h AH=01h
* KEYBOARD - CHECK FOR KEYSTROKE
*
* AH = 01h
* Return:
* ZF set if no keystroke available
* ZF clear if keystroke available
* AH = BIOS scan code
* AL = ASCII character
*/
Regs.b.ah = 0x01;
Int386(0x16, &Regs, &Regs);
return 0 == (Regs.x.eflags & I386FLAG_ZF);
}
int
PcConsGetCh(void)
{
REGS Regs;
static BOOLEAN ExtendedKey = FALSE;
static char ExtendedScanCode = 0;
/* If the last time we were called an
* extended key was pressed then return
* that keys scan code. */
if (ExtendedKey)
{
ExtendedKey = FALSE;
return ExtendedScanCode;
}
/* Int 16h AH=00h
* KEYBOARD - GET KEYSTROKE
*
* AH = 00h
* Return:
* AH = BIOS scan code
* AL = ASCII character
*/
Regs.b.ah = 0x00;
Int386(0x16, &Regs, &Regs);
/* Check for an extended keystroke */
if (0 == Regs.b.al)
{
ExtendedKey = TRUE;
ExtendedScanCode = Regs.b.ah;
}
/* Return keystroke */
return Regs.b.al;
}
/* EOF */

View file

@ -1,455 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <freeldr.h>
#define NDEBUG
#include <debug.h>
typedef struct
{
UCHAR PacketSize; // 00h - Size of packet (10h or 18h)
UCHAR Reserved; // 01h - Reserved (0)
USHORT LBABlockCount; // 02h - Number of blocks to transfer (max 007Fh for Phoenix EDD)
USHORT TransferBufferOffset; // 04h - Transfer buffer offset (seg:off)
USHORT TransferBufferSegment; // Transfer buffer segment (seg:off)
ULONGLONG LBAStartBlock; // 08h - Starting absolute block number
//ULONGLONG TransferBuffer64; // 10h - (EDD-3.0, optional) 64-bit flat address of transfer buffer
// used if DWORD at 04h is FFFFh:FFFFh
// Commented since some earlier BIOSes refuse to work with
// such extended structure
} PACKED I386_DISK_ADDRESS_PACKET, *PI386_DISK_ADDRESS_PACKET;
/////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS
/////////////////////////////////////////////////////////////////////////////////////////////
static BOOLEAN PcDiskResetController(ULONG DriveNumber)
{
REGS RegsIn;
REGS RegsOut;
DbgPrint((DPRINT_DISK, "PcDiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DriveNumber));
// BIOS Int 13h, function 0 - Reset disk system
// AH = 00h
// DL = drive (if bit 7 is set both hard disks and floppy disks reset)
// Return:
// AH = status
// CF clear if successful
// CF set on error
RegsIn.b.ah = 0x00;
RegsIn.b.dl = DriveNumber;
// Reset the disk controller
Int386(0x13, &RegsIn, &RegsOut);
return INT386_SUCCESS(RegsOut);
}
static BOOLEAN PcDiskReadLogicalSectorsLBA(ULONG DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
{
REGS RegsIn;
REGS RegsOut;
ULONG RetryCount;
PI386_DISK_ADDRESS_PACKET Packet = (PI386_DISK_ADDRESS_PACKET)(BIOSCALLBUFFER);
DbgPrint((DPRINT_DISK, "PcDiskReadLogicalSectorsLBA() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, SectorCount, Buffer));
// BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ
RegsIn.b.ah = 0x42; // Subfunction 42h
RegsIn.b.dl = DriveNumber; // Drive number in DL (0 - floppy, 0x80 - harddisk)
RegsIn.x.ds = BIOSCALLBUFSEGMENT; // DS:SI -> disk address packet
RegsIn.w.si = BIOSCALLBUFOFFSET;
// Setup disk address packet
RtlZeroMemory(Packet, sizeof(I386_DISK_ADDRESS_PACKET));
Packet->PacketSize = sizeof(I386_DISK_ADDRESS_PACKET);
Packet->Reserved = 0;
Packet->LBABlockCount = SectorCount;
Packet->TransferBufferOffset = ((ULONG_PTR)Buffer) & 0x0F;
Packet->TransferBufferSegment = ((ULONG_PTR)Buffer) >> 4;
Packet->LBAStartBlock = SectorNumber;
// BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ
// Return:
// CF clear if successful
// AH = 00h
// CF set on error
// AH = error code
// disk address packet's block count field set to the
// number of blocks successfully transferred
// Retry 3 times
for (RetryCount=0; RetryCount<3; RetryCount++)
{
Int386(0x13, &RegsIn, &RegsOut);
// If it worked return TRUE
if (INT386_SUCCESS(RegsOut))
{
return TRUE;
}
// If it was a corrected ECC error then the data is still good
else if (RegsOut.b.ah == 0x11)
{
return TRUE;
}
// If it failed the do the next retry
else
{
PcDiskResetController(DriveNumber);
continue;
}
}
// If we get here then the read failed
DiskError("Disk Read Failed in LBA mode", RegsOut.b.ah);
return FALSE;
}
static BOOLEAN PcDiskReadLogicalSectorsCHS(ULONG DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
{
ULONG PhysicalSector;
ULONG PhysicalHead;
ULONG PhysicalTrack;
GEOMETRY DriveGeometry;
ULONG NumberOfSectorsToRead;
REGS RegsIn;
REGS RegsOut;
ULONG RetryCount;
DbgPrint((DPRINT_DISK, "PcDiskReadLogicalSectorsCHS()\n"));
//
// Get the drive geometry
//
if (!MachDiskGetDriveGeometry(DriveNumber, &DriveGeometry) ||
DriveGeometry.Sectors == 0 ||
DriveGeometry.Heads == 0)
{
return FALSE;
}
while (SectorCount)
{
//
// Calculate the physical disk offsets
//
PhysicalSector = 1 + (SectorNumber % DriveGeometry.Sectors);
PhysicalHead = (SectorNumber / DriveGeometry.Sectors) % DriveGeometry.Heads;
PhysicalTrack = (SectorNumber / DriveGeometry.Sectors) / DriveGeometry.Heads;
//
// Calculate how many sectors we need to read this round
//
if (PhysicalSector > 1)
{
if (SectorCount >= (DriveGeometry.Sectors - (PhysicalSector - 1)))
NumberOfSectorsToRead = (DriveGeometry.Sectors - (PhysicalSector - 1));
else
NumberOfSectorsToRead = SectorCount;
}
else
{
if (SectorCount >= DriveGeometry.Sectors)
NumberOfSectorsToRead = DriveGeometry.Sectors;
else
NumberOfSectorsToRead = SectorCount;
}
//
// Make sure the read is within the geometry boundaries
//
if ((PhysicalHead >= DriveGeometry.Heads) ||
(PhysicalTrack >= DriveGeometry.Cylinders) ||
((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.Sectors + 1)) ||
(PhysicalSector > DriveGeometry.Sectors))
{
DiskError("Disk read exceeds drive geometry limits.", 0);
return FALSE;
}
// BIOS Int 13h, function 2 - Read Disk Sectors
// AH = 02h
// AL = number of sectors to read (must be nonzero)
// CH = low eight bits of cylinder number
// CL = sector number 1-63 (bits 0-5)
// high two bits of cylinder (bits 6-7, hard disk only)
// DH = head number
// DL = drive number (bit 7 set for hard disk)
// ES:BX -> data buffer
// Return:
// CF set on error
// if AH = 11h (corrected ECC error), AL = burst length
// CF clear if successful
// AH = status
// AL = number of sectors transferred
// (only valid if CF set for some BIOSes)
RegsIn.b.ah = 0x02;
RegsIn.b.al = NumberOfSectorsToRead;
RegsIn.b.ch = (PhysicalTrack & 0xFF);
RegsIn.b.cl = (PhysicalSector + ((PhysicalTrack & 0x300) >> 2));
RegsIn.b.dh = PhysicalHead;
RegsIn.b.dl = DriveNumber;
RegsIn.w.es = ((ULONG_PTR)Buffer) >> 4;
RegsIn.w.bx = ((ULONG_PTR)Buffer) & 0x0F;
//
// Perform the read
// Retry 3 times
//
for (RetryCount=0; RetryCount<3; RetryCount++)
{
Int386(0x13, &RegsIn, &RegsOut);
// If it worked break out
if (INT386_SUCCESS(RegsOut))
{
break;
}
// If it was a corrected ECC error then the data is still good
else if (RegsOut.b.ah == 0x11)
{
break;
}
// If it failed the do the next retry
else
{
PcDiskResetController(DriveNumber);
continue;
}
}
// If we retried 3 times then fail
if (RetryCount >= 3)
{
DiskError("Disk Read Failed in CHS mode, after retrying 3 times", RegsOut.b.ah);
return FALSE;
}
// I have learned that not all bioses return
// the sector read count in the AL register (at least mine doesn't)
// even if the sectors were read correctly. So instead
// of checking the sector read count we will rely solely
// on the carry flag being set on error
Buffer = (PVOID)((ULONG_PTR)Buffer + (NumberOfSectorsToRead * DriveGeometry.BytesPerSector));
SectorCount -= NumberOfSectorsToRead;
SectorNumber += NumberOfSectorsToRead;
}
return TRUE;
}
static BOOLEAN PcDiskInt13ExtensionsSupported(ULONG DriveNumber)
{
static ULONG LastDriveNumber = 0xffffffff;
static BOOLEAN LastSupported;
REGS RegsIn;
REGS RegsOut;
DbgPrint((DPRINT_DISK, "PcDiskInt13ExtensionsSupported()\n"));
if (DriveNumber == LastDriveNumber)
{
DbgPrint((DPRINT_DISK, "Using cached value %s for drive 0x%x\n", LastSupported ? "TRUE" : "FALSE", DriveNumber));
return LastSupported;
}
// Some BIOSes report that extended disk access functions are not supported
// when booting from a CD (e.g. Phoenix BIOS v6.00PG and Insyde BIOS shipping
// with Intel Macs). Therefore we just return TRUE if we're booting from a CD -
// we can assume that all El Torito capable BIOSes support INT 13 extensions.
// We simply detect whether we're booting from CD by checking whether the drive
// number is >= 0x90. It's 0x90 on the Insyde BIOS, and 0x9F on most other BIOSes.
if (DriveNumber >= 0x90)
{
LastSupported = TRUE;
return TRUE;
}
LastDriveNumber = DriveNumber;
// IBM/MS INT 13 Extensions - INSTALLATION CHECK
// AH = 41h
// BX = 55AAh
// DL = drive (80h-FFh)
// Return:
// CF set on error (extensions not supported)
// AH = 01h (invalid function)
// CF clear if successful
// BX = AA55h if installed
// AH = major version of extensions
// 01h = 1.x
// 20h = 2.0 / EDD-1.0
// 21h = 2.1 / EDD-1.1
// 30h = EDD-3.0
// AL = internal use
// CX = API subset support bitmap
// DH = extension version (v2.0+ ??? -- not present in 1.x)
//
// Bitfields for IBM/MS INT 13 Extensions API support bitmap
// Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
// Bit 1, removable drive controller functions (AH=45h,46h,48h,49h,INT 15/AH=52h) supported
// Bit 2, enhanced disk drive (EDD) functions (AH=48h,AH=4Eh) supported
// extended drive parameter table is valid
// Bits 3-15 reserved
RegsIn.b.ah = 0x41;
RegsIn.w.bx = 0x55AA;
RegsIn.b.dl = DriveNumber;
// Reset the disk controller
Int386(0x13, &RegsIn, &RegsOut);
if (!INT386_SUCCESS(RegsOut))
{
// CF set on error (extensions not supported)
LastSupported = FALSE;
return FALSE;
}
if (RegsOut.w.bx != 0xAA55)
{
// BX = AA55h if installed
LastSupported = FALSE;
return FALSE;
}
if (!(RegsOut.w.cx & 0x0001))
{
// CX = API subset support bitmap
// Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
printf("Suspicious API subset support bitmap 0x%x on device 0x%lx\n", RegsOut.w.cx, DriveNumber);
LastSupported = FALSE;
return FALSE;
}
LastSupported = TRUE;
return TRUE;
}
BOOLEAN PcDiskReadLogicalSectors(ULONG DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
{
DbgPrint((DPRINT_DISK, "PcDiskReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, SectorCount, Buffer));
//
// Check to see if it is a fixed disk drive
// If so then check to see if Int13 extensions work
// If they do then use them, otherwise default back to BIOS calls
//
if ((DriveNumber >= 0x80) && PcDiskInt13ExtensionsSupported(DriveNumber))
{
DbgPrint((DPRINT_DISK, "Using Int 13 Extensions for read. PcDiskInt13ExtensionsSupported(%d) = %s\n", DriveNumber, PcDiskInt13ExtensionsSupported(DriveNumber) ? "TRUE" : "FALSE"));
//
// LBA is easy, nothing to calculate
// Just do the read
//
return PcDiskReadLogicalSectorsLBA(DriveNumber, SectorNumber, SectorCount, Buffer);
}
else
{
// LBA is not supported default to the CHS calls
return PcDiskReadLogicalSectorsCHS(DriveNumber, SectorNumber, SectorCount, Buffer);
}
return TRUE;
}
BOOLEAN
PcDiskGetDriveGeometry(ULONG DriveNumber, PGEOMETRY Geometry)
{
REGS RegsIn;
REGS RegsOut;
ULONG Cylinders;
DbgPrint((DPRINT_DISK, "DiskGetDriveGeometry()\n"));
/* BIOS Int 13h, function 08h - Get drive parameters
* AH = 08h
* DL = drive (bit 7 set for hard disk)
* ES:DI = 0000h:0000h to guard against BIOS bugs
* Return:
* CF set on error
* AH = status (07h)
* CF clear if successful
* AH = 00h
* AL = 00h on at least some BIOSes
* BL = drive type (AT/PS2 floppies only)
* CH = low eight bits of maximum cylinder number
* CL = maximum sector number (bits 5-0)
* high two bits of maximum cylinder number (bits 7-6)
* DH = maximum head number
* DL = number of drives
* ES:DI -> drive parameter table (floppies only)
*/
RegsIn.b.ah = 0x08;
RegsIn.b.dl = DriveNumber;
RegsIn.w.es = 0x0000;
RegsIn.w.di = 0x0000;
/* Get drive parameters */
Int386(0x13, &RegsIn, &RegsOut);
if (! INT386_SUCCESS(RegsOut))
{
return FALSE;
}
Cylinders = (RegsOut.b.cl & 0xC0) << 2;
Cylinders += RegsOut.b.ch;
Cylinders++;
Geometry->Cylinders = Cylinders;
Geometry->Heads = RegsOut.b.dh + 1;
Geometry->Sectors = RegsOut.b.cl & 0x3F;
Geometry->BytesPerSector = 512; /* Just assume 512 bytes per sector */
return TRUE;
}
ULONG
PcDiskGetCacheableBlockCount(ULONG DriveNumber)
{
GEOMETRY Geometry;
/* If LBA is supported then the block size will be 64 sectors (32k)
* If not then the block size is the size of one track */
if (DiskInt13ExtensionsSupported(DriveNumber))
{
return 64;
}
/* Get the disk geometry
* If this fails then we will just return 1 sector to be safe */
else if (! PcDiskGetDriveGeometry(DriveNumber, &Geometry))
{
return 1;
}
else
{
return Geometry.Sectors;
}
}
/* EOF */

View file

@ -1,249 +0,0 @@
/* $Id: pcmem.c 24238 2006-09-23 16:50:39Z fireball $
*
* FreeLoader
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Note: Most of this code comes from the old file "i386mem.c", which
* was Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*/
#include <freeldr.h>
#define NDEBUG
#include <debug.h>
static ULONG
PcMemGetExtendedMemorySize(VOID)
{
REGS RegsIn;
REGS RegsOut;
ULONG MemorySize;
DbgPrint((DPRINT_MEMORY, "GetExtendedMemorySize()\n"));
/* Int 15h AX=E801h
* Phoenix BIOS v4.0 - GET MEMORY SIZE FOR >64M CONFIGURATIONS
*
* AX = E801h
* Return:
* CF clear if successful
* AX = extended memory between 1M and 16M, in K (max 3C00h = 15MB)
* BX = extended memory above 16M, in 64K blocks
* CX = configured memory 1M to 16M, in K
* DX = configured memory above 16M, in 64K blocks
* CF set on error
*/
RegsIn.w.ax = 0xE801;
Int386(0x15, &RegsIn, &RegsOut);
DbgPrint((DPRINT_MEMORY, "Int15h AX=E801h\n"));
DbgPrint((DPRINT_MEMORY, "AX = 0x%x\n", RegsOut.w.ax));
DbgPrint((DPRINT_MEMORY, "BX = 0x%x\n", RegsOut.w.bx));
DbgPrint((DPRINT_MEMORY, "CX = 0x%x\n", RegsOut.w.cx));
DbgPrint((DPRINT_MEMORY, "DX = 0x%x\n", RegsOut.w.dx));
DbgPrint((DPRINT_MEMORY, "CF set = %s\n\n", (RegsOut.x.eflags & I386FLAG_CF) ? "TRUE" : "FALSE"));
if (INT386_SUCCESS(RegsOut))
{
/* If AX=BX=0000h the use CX and DX */
if (RegsOut.w.ax == 0)
{
/* Return extended memory size in K */
MemorySize = RegsOut.w.dx * 64;
MemorySize += RegsOut.w.cx;
return MemorySize;
}
else
{
/* Return extended memory size in K */
MemorySize = RegsOut.w.bx * 64;
MemorySize += RegsOut.w.ax;
return MemorySize;
}
}
/* If we get here then Int15 Func E801h didn't work */
/* So try Int15 Func 88h */
/* Int 15h AH=88h
* SYSTEM - GET EXTENDED MEMORY SIZE (286+)
*
* AH = 88h
* Return:
* CF clear if successful
* AX = number of contiguous KB starting at absolute address 100000h
* CF set on error
* AH = status
* 80h invalid command (PC,PCjr)
* 86h unsupported function (XT,PS30)
*/
RegsIn.b.ah = 0x88;
Int386(0x15, &RegsIn, &RegsOut);
DbgPrint((DPRINT_MEMORY, "Int15h AH=88h\n"));
DbgPrint((DPRINT_MEMORY, "AX = 0x%x\n", RegsOut.w.ax));
DbgPrint((DPRINT_MEMORY, "CF set = %s\n\n", (RegsOut.x.eflags & I386FLAG_CF) ? "TRUE" : "FALSE"));
if (INT386_SUCCESS(RegsOut) && RegsOut.w.ax != 0)
{
MemorySize = RegsOut.w.ax;
return MemorySize;
}
/* If we get here then Int15 Func 88h didn't work */
/* So try reading the CMOS */
WRITE_PORT_UCHAR((PUCHAR)0x70, 0x31);
MemorySize = READ_PORT_UCHAR((PUCHAR)0x71);
MemorySize = (MemorySize & 0xFFFF);
MemorySize = (MemorySize << 8);
DbgPrint((DPRINT_MEMORY, "Int15h Failed\n"));
DbgPrint((DPRINT_MEMORY, "CMOS reports: 0x%x\n", MemorySize));
return MemorySize;
}
static ULONG
PcMemGetConventionalMemorySize(VOID)
{
REGS Regs;
DbgPrint((DPRINT_MEMORY, "GetConventionalMemorySize()\n"));
/* Int 12h
* BIOS - GET MEMORY SIZE
*
* Return:
* AX = kilobytes of contiguous memory starting at absolute address 00000h
*
* This call returns the contents of the word at 0040h:0013h;
* in PC and XT, this value is set from the switches on the motherboard
*/
Regs.w.ax = 0;
Int386(0x12, &Regs, &Regs);
DbgPrint((DPRINT_MEMORY, "Int12h\n"));
DbgPrint((DPRINT_MEMORY, "AX = 0x%x\n\n", Regs.w.ax));
return (ULONG)Regs.w.ax;
}
static ULONG
PcMemGetBiosMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize)
{
REGS Regs;
ULONG MapCount;
DbgPrint((DPRINT_MEMORY, "GetBiosMemoryMap()\n"));
/* Int 15h AX=E820h
* Newer BIOSes - GET SYSTEM MEMORY MAP
*
* AX = E820h
* EAX = 0000E820h
* EDX = 534D4150h ('SMAP')
* EBX = continuation value or 00000000h to start at beginning of map
* ECX = size of buffer for result, in bytes (should be >= 20 bytes)
* ES:DI -> buffer for result
* Return:
* CF clear if successful
* EAX = 534D4150h ('SMAP')
* ES:DI buffer filled
* EBX = next offset from which to copy or 00000000h if all done
* ECX = actual length returned in bytes
* CF set on error
* AH = error code (86h)
*/
Regs.x.eax = 0x0000E820;
Regs.x.edx = 0x534D4150; /* ('SMAP') */
Regs.x.ebx = 0x00000000;
Regs.x.ecx = sizeof(BIOS_MEMORY_MAP);
Regs.w.es = BIOSCALLBUFSEGMENT;
Regs.w.di = BIOSCALLBUFOFFSET;
for (MapCount = 0; MapCount < MaxMemoryMapSize; MapCount++)
{
Int386(0x15, &Regs, &Regs);
DbgPrint((DPRINT_MEMORY, "Memory Map Entry %d\n", MapCount));
DbgPrint((DPRINT_MEMORY, "Int15h AX=E820h\n"));
DbgPrint((DPRINT_MEMORY, "EAX = 0x%x\n", Regs.x.eax));
DbgPrint((DPRINT_MEMORY, "EBX = 0x%x\n", Regs.x.ebx));
DbgPrint((DPRINT_MEMORY, "ECX = 0x%x\n", Regs.x.ecx));
DbgPrint((DPRINT_MEMORY, "CF set = %s\n", (Regs.x.eflags & I386FLAG_CF) ? "TRUE" : "FALSE"));
/* If the BIOS didn't return 'SMAP' in EAX then
* it doesn't support this call */
if (Regs.x.eax != 0x534D4150)
{
break;
}
/* Copy data to caller's buffer */
RtlCopyMemory(&BiosMemoryMap[MapCount], (PVOID)BIOSCALLBUFFER, Regs.x.ecx);
DbgPrint((DPRINT_MEMORY, "BaseAddress: 0x%p\n", (PVOID)BiosMemoryMap[MapCount].BaseAddress));
DbgPrint((DPRINT_MEMORY, "Length: 0x%p\n", (PVOID)BiosMemoryMap[MapCount].Length));
DbgPrint((DPRINT_MEMORY, "Type: 0x%x\n", BiosMemoryMap[MapCount].Type));
DbgPrint((DPRINT_MEMORY, "Reserved: 0x%x\n", BiosMemoryMap[MapCount].Reserved));
DbgPrint((DPRINT_MEMORY, "\n"));
/* If the continuation value is zero or the
* carry flag is set then this was
* the last entry so we're done */
if (Regs.x.ebx == 0x00000000 || !INT386_SUCCESS(Regs))
{
MapCount++;
DbgPrint((DPRINT_MEMORY, "End Of System Memory Map!\n\n"));
break;
}
/* Setup the registers for the next call */
Regs.x.eax = 0x0000E820;
Regs.x.edx = 0x534D4150; /* ('SMAP') */
/* Regs.x.ebx = 0x00000001; Continuation value already set by the BIOS */
Regs.x.ecx = sizeof(BIOS_MEMORY_MAP);
Regs.w.es = BIOSCALLBUFSEGMENT;
Regs.w.di = BIOSCALLBUFOFFSET;
}
return MapCount;
}
ULONG
PcMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize)
{
ULONG EntryCount;
EntryCount = PcMemGetBiosMemoryMap(BiosMemoryMap, MaxMemoryMapSize);
/* If the BIOS didn't provide a memory map, synthesize one */
if (0 == EntryCount && 2 <= MaxMemoryMapSize)
{
/* Conventional memory */
BiosMemoryMap[0].BaseAddress = 0;
BiosMemoryMap[0].Length = PcMemGetConventionalMemorySize() * 1024;
BiosMemoryMap[0].Type = BiosMemoryUsable;
/* Extended memory */
BiosMemoryMap[1].BaseAddress = 1024 * 1024;
BiosMemoryMap[1].Length = PcMemGetExtendedMemorySize() * 1024;
BiosMemoryMap[1].Type = BiosMemoryUsable;
EntryCount = 2;
}
return EntryCount;
}
/* EOF */

View file

@ -1,5 +0,0 @@
/* No need to duplicate code ; import the i386 version */
#include "../i386/pcrtc.c"
/* EOF */

File diff suppressed because it is too large Load diff