mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-24 12:35:31 +00:00
This commit is contained in:
parent
7f03662b3a
commit
cda3f5c062
10 changed files with 0 additions and 1189 deletions
|
|
@ -1,107 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Cosmos.Hardware.PC.Bus
|
|
||||||
{
|
|
||||||
public abstract class AddressSpace
|
|
||||||
{
|
|
||||||
public UInt32 Offset;
|
|
||||||
public UInt32 Size;
|
|
||||||
|
|
||||||
public AddressSpace(UInt32 offset, UInt32 size)
|
|
||||||
{
|
|
||||||
this.Offset = offset;
|
|
||||||
this.Size = size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public unsafe class MemoryAddressSpace : AddressSpace
|
|
||||||
{
|
|
||||||
public MemoryAddressSpace(UInt32 offset, UInt32 size)
|
|
||||||
: base(offset, size)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte Read8(UInt32 offset)
|
|
||||||
{
|
|
||||||
if (offset < 0 || offset > Size)
|
|
||||||
throw new ArgumentOutOfRangeException("offset");
|
|
||||||
return *(byte*)(this.Offset + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UInt16 Read16(UInt32 offset)
|
|
||||||
{
|
|
||||||
if (offset < 0 || offset > Size)
|
|
||||||
throw new ArgumentOutOfRangeException("offset");
|
|
||||||
return *(UInt16*)(this.Offset + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UInt32 Read32(UInt32 offset)
|
|
||||||
{
|
|
||||||
if (offset < 0 || offset > Size)
|
|
||||||
throw new ArgumentOutOfRangeException("offset");
|
|
||||||
return *(UInt32*)(this.Offset + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte Read8Unchecked(UInt32 offset)
|
|
||||||
{
|
|
||||||
return *(byte*)(this.Offset + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UInt16 Read16Unchecked(UInt32 offset)
|
|
||||||
{
|
|
||||||
return *(UInt16*)(this.Offset + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UInt32 Read32Unchecked(UInt32 offset)
|
|
||||||
{
|
|
||||||
return *(UInt32*)(this.Offset + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Write8(UInt32 offset, byte value)
|
|
||||||
{
|
|
||||||
if (offset < 0 || offset > Size)
|
|
||||||
throw new ArgumentOutOfRangeException("offset");
|
|
||||||
(*(byte*)(this.Offset + offset)) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Write16(UInt32 offset, UInt16 value)
|
|
||||||
{
|
|
||||||
if (offset < 0 || offset > Size)
|
|
||||||
throw new ArgumentOutOfRangeException("offset");
|
|
||||||
(*(UInt16*)(this.Offset + offset)) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Write32(UInt32 offset, UInt32 value)
|
|
||||||
{
|
|
||||||
if (offset < 0 || offset > Size)
|
|
||||||
throw new ArgumentOutOfRangeException("offset");
|
|
||||||
(*(UInt32*)(this.Offset + offset)) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Write8Unchecked(UInt32 offset, byte value)
|
|
||||||
{
|
|
||||||
(*(byte*)(this.Offset + offset)) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Write16Unchecked(UInt32 offset, UInt16 value)
|
|
||||||
{
|
|
||||||
(*(UInt16*)(this.Offset + offset)) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Write32Unchecked(UInt32 offset, UInt32 value)
|
|
||||||
{
|
|
||||||
(*(UInt32*)(this.Offset + offset)) = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class IOAddressSpace : AddressSpace
|
|
||||||
{
|
|
||||||
public IOAddressSpace(UInt32 offset, UInt32 size)
|
|
||||||
: base(offset, size)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Cosmos.Hardware.PC.Bus.CPU {
|
|
||||||
public class Keyboard : Cosmos.Hardware.SerialDevice {
|
|
||||||
public Keyboard() {
|
|
||||||
mType = DeviceType.Keyboard;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void InterruptReceived() {
|
|
||||||
byte xByte = PC.Bus.CPUBus.Read8(0x60);
|
|
||||||
ByteReceived(xByte);
|
|
||||||
}
|
|
||||||
public override string Name {
|
|
||||||
get {
|
|
||||||
return "Keyboard";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Cosmos.Hardware.PC.Bus.CPU {
|
|
||||||
//TODO: Change this to be an instance like other drivers
|
|
||||||
public abstract class PIC : Cosmos.Hardware.Device {
|
|
||||||
/// <summary>
|
|
||||||
/// Remaps the IRQ's to INT20-INT2F
|
|
||||||
/// </summary>
|
|
||||||
const ushort CmdPort1 = 0x20;
|
|
||||||
const ushort DataPort1 = 0x21;
|
|
||||||
|
|
||||||
const ushort CmdPort2 = 0xA0;
|
|
||||||
const ushort DataPort2 = 0xA1;
|
|
||||||
|
|
||||||
public static void SignalPrimary() {
|
|
||||||
PC.Bus.CPUBus.Write8(CmdPort1, 0x20);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SignalSecondary() {
|
|
||||||
PC.Bus.CPUBus.Write8(CmdPort2, 0x20);
|
|
||||||
PC.Bus.CPUBus.Write8(CmdPort1, 0x20);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Init() {
|
|
||||||
// Init
|
|
||||||
PC.Bus.CPUBus.Write8(CmdPort1, 0x11);
|
|
||||||
PC.Bus.CPUBus.Write8(CmdPort2, 0x11);
|
|
||||||
// Offsets
|
|
||||||
PC.Bus.CPUBus.Write8(DataPort1, 0x20);
|
|
||||||
PC.Bus.CPUBus.Write8(DataPort2, 0x28);
|
|
||||||
// More Init
|
|
||||||
PC.Bus.CPUBus.Write8(DataPort1, 0x04);
|
|
||||||
PC.Bus.CPUBus.Write8(DataPort2, 0x02);
|
|
||||||
// 8086 mode
|
|
||||||
PC.Bus.CPUBus.Write8(DataPort1, 0x01);
|
|
||||||
PC.Bus.CPUBus.Write8(DataPort2, 0x01);
|
|
||||||
// Masks - 0 = receive all IRQ's
|
|
||||||
// MTW, to disable PIT, send 0x1 to DataPort1
|
|
||||||
PC.Bus.CPUBus.Write8(DataPort1, 0x00);
|
|
||||||
PC.Bus.CPUBus.Write8(DataPort2, 0x00);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Cosmos.Hardware.PC.Bus {
|
|
||||||
public class CPUBus : Cosmos.Hardware.Bus.CPUBus {
|
|
||||||
// These are public. Would prefer internal, but will cause issues
|
|
||||||
// in future as we add devices from other assemblies.
|
|
||||||
// What else can we do to restrict access to them?
|
|
||||||
//
|
|
||||||
// all plugs
|
|
||||||
public static void Write8(UInt16 aPort, byte aData) { }
|
|
||||||
public static void Write16(UInt16 aPort, UInt16 aData) { }
|
|
||||||
public static void Write32(UInt16 aPort, UInt32 aData) { }
|
|
||||||
|
|
||||||
public static byte Read8(UInt16 aPort) { return 0; }
|
|
||||||
public static UInt16 Read16(UInt16 aPort) { return 0; }
|
|
||||||
public static UInt32 Read32(UInt16 aPort) { return 0; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,540 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Cosmos.Hardware.PC.Bus
|
|
||||||
{
|
|
||||||
|
|
||||||
public class PCIBus : Cosmos.Hardware.Bus.PCIBus
|
|
||||||
{
|
|
||||||
public static PCIDevice[] Devices = new PCIDevice[0];
|
|
||||||
|
|
||||||
private static bool haveEnumerated = false;
|
|
||||||
|
|
||||||
public static PCIDevice GetPCIDevice(byte bus, byte slot, byte function)
|
|
||||||
{
|
|
||||||
if (!haveEnumerated)
|
|
||||||
Init();
|
|
||||||
|
|
||||||
foreach (PCIDevice dev in PCIBus.Devices)
|
|
||||||
{
|
|
||||||
if (dev.Bus == bus &&
|
|
||||||
dev.Slot == slot &&
|
|
||||||
dev.Function == function)
|
|
||||||
|
|
||||||
return dev;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Init()
|
|
||||||
{
|
|
||||||
//Console.WriteLine("Cosmos.Hardware.PC.Bus.Init()");
|
|
||||||
|
|
||||||
List<PCIDevice> devices = new List<PCIDevice>();
|
|
||||||
//Console.WriteLine("- created generic");
|
|
||||||
|
|
||||||
EnumerateBus(0, ref devices);
|
|
||||||
Devices = devices.ToArray();
|
|
||||||
|
|
||||||
haveEnumerated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void EnumerateBus(byte Bus, ref List<PCIDevice> Devices)
|
|
||||||
{
|
|
||||||
//Console.WriteLine("Enumerate " + Bus );
|
|
||||||
|
|
||||||
for (byte xSlot = 0; xSlot < 32; xSlot++)
|
|
||||||
{
|
|
||||||
byte xMaxFunctions = 1;
|
|
||||||
|
|
||||||
for (byte xFunction = 0; xFunction < xMaxFunctions; xFunction++)
|
|
||||||
{
|
|
||||||
PCIDevice xPCIDevice = new PCIDeviceNormal(Bus, xSlot, xFunction);
|
|
||||||
|
|
||||||
if (xPCIDevice.DeviceExists)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
//if (xPCIDevice.HeaderType == 0 /* PCIHeaderType.Normal */)
|
|
||||||
// xPCIDevice = xPCIDevice;
|
|
||||||
|
|
||||||
if (xPCIDevice.HeaderType == 2 /* PCIHeaderType.Cardbus */)
|
|
||||||
xPCIDevice = new PCIDeviceCardBus(Bus, xSlot, xFunction);
|
|
||||||
|
|
||||||
if (xPCIDevice.HeaderType == 1 /* PCIHeaderType.Bridge */)
|
|
||||||
xPCIDevice = new PCIDeviceBridge(Bus, xSlot, xFunction);
|
|
||||||
|
|
||||||
|
|
||||||
Devices.Add(xPCIDevice);
|
|
||||||
|
|
||||||
if (xPCIDevice is PCIDeviceBridge)
|
|
||||||
EnumerateBus(((PCIDeviceBridge)xPCIDevice).SecondaryBus, ref Devices);
|
|
||||||
|
|
||||||
if (xPCIDevice.IsMultiFunction)
|
|
||||||
xMaxFunctions = 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void DebugLSPCI()
|
|
||||||
{
|
|
||||||
PCIBus.DeviceIDs xDeviceIDs = new PCIBus.DeviceIDs();
|
|
||||||
|
|
||||||
for(int d =0;d<Cosmos.Hardware.PC.Bus.PCIBus.Devices.Length;d++){
|
|
||||||
var xPCIDevice = Cosmos.Hardware.PC.Bus.PCIBus.Devices[d];
|
|
||||||
string xVendor = xDeviceIDs.FindVendor(xPCIDevice.VendorID);
|
|
||||||
|
|
||||||
if (xVendor == default(string))
|
|
||||||
xVendor = ToHex(xPCIDevice.VendorID, 4);
|
|
||||||
|
|
||||||
System.Console.Write(xPCIDevice.Bus + "-" + xPCIDevice.Slot + "-" + xPCIDevice.Function);
|
|
||||||
System.Console.Write(" " + xVendor + ":" + ToHex(xPCIDevice.DeviceID, 4));
|
|
||||||
System.Console.WriteLine(" Type: " + xPCIDevice.HeaderType + " IRQ: " + xPCIDevice.InterruptLine);
|
|
||||||
// /*Enum.GetName(typeof(PCIHeaderType), */ xPCIDevice.HeaderType/*) */);
|
|
||||||
// Console.WriteLine(" Status: " + xPCIDevice.Status + " " +
|
|
||||||
// /*Enum.GetName(typeof(PCIStatus), */xPCIDevice.Status/*) */);
|
|
||||||
// Console.WriteLine(" Command: " + xPCIDevice.Command + " " +
|
|
||||||
// /*Enum.GetName(typeof(PCICommand), */xPCIDevice.Command /* ) */);
|
|
||||||
System.Console.Write(" Class [" + ToHex((UInt32)((xPCIDevice.ClassCode << 8) | xPCIDevice.SubClass), 4) + "] " + xPCIDevice.GetClassInfo());
|
|
||||||
System.Console.WriteLine();
|
|
||||||
System.Console.Write(" Memory: ");
|
|
||||||
|
|
||||||
for (byte i = 0; i < xPCIDevice.NumberOfBaseAddresses(); i++)
|
|
||||||
{
|
|
||||||
AddressSpace a = xPCIDevice.GetAddressSpace(i);
|
|
||||||
|
|
||||||
if (a != null)
|
|
||||||
{
|
|
||||||
System.Console.Write("register " + i + " @ " + ToHex(a.Offset, 8) + " (" + a.Size + "b) ");
|
|
||||||
if (a is MemoryAddressSpace)
|
|
||||||
Console.WriteLine("mem");
|
|
||||||
else
|
|
||||||
Console.WriteLine("io");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
System.Console.WriteLine();
|
|
||||||
|
|
||||||
|
|
||||||
System.Console.WriteLine();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string ToHex(UInt32 num, int length)
|
|
||||||
{
|
|
||||||
char[] ret = new char[length];
|
|
||||||
UInt32 cpy = num;
|
|
||||||
|
|
||||||
for (int index = length - 1; index >= 0; index--)
|
|
||||||
{
|
|
||||||
ret[index] = hex(cpy & 0xf);
|
|
||||||
cpy = cpy / 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
return "0x" + new string(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static char hex(uint p)
|
|
||||||
{
|
|
||||||
switch (p)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
return '0';
|
|
||||||
case 1:
|
|
||||||
return '1';
|
|
||||||
case 2:
|
|
||||||
return '2';
|
|
||||||
case 3:
|
|
||||||
return '3';
|
|
||||||
case 4:
|
|
||||||
return '4';
|
|
||||||
case 5:
|
|
||||||
return '5';
|
|
||||||
case 6:
|
|
||||||
return '6';
|
|
||||||
case 7:
|
|
||||||
return '7';
|
|
||||||
case 8:
|
|
||||||
return '8';
|
|
||||||
case 9:
|
|
||||||
return '9';
|
|
||||||
case 10:
|
|
||||||
return 'a';
|
|
||||||
case 11:
|
|
||||||
return 'b';
|
|
||||||
case 12:
|
|
||||||
return 'c';
|
|
||||||
case 13:
|
|
||||||
return 'd';
|
|
||||||
case 14:
|
|
||||||
return 'e';
|
|
||||||
case 15:
|
|
||||||
return 'f';
|
|
||||||
}
|
|
||||||
return ' ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Flags]
|
|
||||||
public enum PCICommand : short
|
|
||||||
{
|
|
||||||
IO = 0x1, /* Enable response in I/O space */
|
|
||||||
Memort = 0x2, /* Enable response in Memory space */
|
|
||||||
Master = 0x4, /* Enable bus mastering */
|
|
||||||
Special = 0x8, /* Enable response to special cycles */
|
|
||||||
Invalidate = 0x10, /* Use memory write and invalidate */
|
|
||||||
VGA_Pallete = 0x20, /* Enable palette snooping */
|
|
||||||
Parity = 0x40, /* Enable parity checking */
|
|
||||||
Wait = 0x80, /* Enable address/data stepping */
|
|
||||||
SERR = 0x100, /* Enable SERR */
|
|
||||||
Fast_Back = 0x200, /* Enable back-to-back writes */
|
|
||||||
}
|
|
||||||
|
|
||||||
[Flags]
|
|
||||||
public enum PCIStatus : int
|
|
||||||
{
|
|
||||||
CAP_LIST = 0x10, /* Support Capability List */
|
|
||||||
SUPPORT_66MHZ = 0x20, /* Support 66 Mhz PCI 2.1 bus */
|
|
||||||
UDF = 0x40, /* Support User Definable Features [obsolete] */
|
|
||||||
FAST_BACK = 0x80, /* Accept fast-back to back */
|
|
||||||
PARITY = 0x100, /* Detected parity error */
|
|
||||||
DEVSEL_MASK = 0x600, /* DEVSEL timing */
|
|
||||||
DEVSEL_FAST = 0x000,
|
|
||||||
DEVSEL_MEDIUM = 0x200,
|
|
||||||
DEVSEL_SLOW = 0x400,
|
|
||||||
SIG_TARGET_ABORT = 0x800, /* Set on target abort */
|
|
||||||
REC_TARGET_ABORT = 0x1000, /* Master ack of " */
|
|
||||||
REC_MASTER_ABORT = 0x2000, /* Set on master abort */
|
|
||||||
SIG_SYSTEM_ERROR = 0x4000, /* Set when we drive SERR */
|
|
||||||
DETECTED_PARITY = 0x8000 /* Set on parity error */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public enum PCIHeaderType : byte
|
|
||||||
{
|
|
||||||
Normal = 0,
|
|
||||||
Bridge = 1,
|
|
||||||
Cardbus = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[Flags]
|
|
||||||
public enum PCIBist : byte
|
|
||||||
{
|
|
||||||
CocdMask = 0x0f, /* Return result */
|
|
||||||
Start = 0x40, /* 1 to start BIST, 2 secs or less */
|
|
||||||
Capable = 0x80 /* 1 if BIST capable */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public class PCIDeviceCardBus : PCIDevice
|
|
||||||
{
|
|
||||||
public PCIDeviceCardBus(byte bus, byte slot, byte function)
|
|
||||||
: base (bus,slot,function)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int NumberOfBaseAddresses()
|
|
||||||
{
|
|
||||||
//get
|
|
||||||
//{
|
|
||||||
return 6;
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PCIDeviceBridge : PCIDevice
|
|
||||||
{
|
|
||||||
public PCIDeviceBridge(byte bus, byte slot, byte function)
|
|
||||||
: base (bus,slot,function)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int NumberOfBaseAddresses()
|
|
||||||
{
|
|
||||||
// get
|
|
||||||
// {
|
|
||||||
return 2;
|
|
||||||
////}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public byte PrimaryBus { get { return Read8(0x18); } set { Write8(0x18, value); } }
|
|
||||||
public byte SecondaryBus { get { return Read8(0x19); } set { Write8(0x19, value); } }
|
|
||||||
public byte SubordinateBus { get { return Read8(0x1a); } set { Write8(0x1a, value); } }
|
|
||||||
public byte SecondaryLatencyTime { get { return Read8(0x1b); } set { Write8(0x1b, value); } }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class PCIDeviceNormal : PCIDevice
|
|
||||||
{
|
|
||||||
public PCIDeviceNormal(byte bus, byte slot, byte function)
|
|
||||||
: base (bus,slot,function)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int NumberOfBaseAddresses()
|
|
||||||
{
|
|
||||||
//get
|
|
||||||
//{
|
|
||||||
return 6;
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
public UInt32 BaseAddress2 { get { return Read32(0x18); } set { Write32(0x18, value); } }
|
|
||||||
public UInt32 BaseAddress3 { get { return Read32(0x1a); } set { Write32(0x1a, value); } }
|
|
||||||
public UInt32 BaseAddress4 { get { return Read32(0x20); } set { Write32(0x20, value); } }
|
|
||||||
public UInt32 BaseAddress5 { get { return Read32(0x24); } set { Write32(0x24, value); } }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class PCIDevice
|
|
||||||
{
|
|
||||||
|
|
||||||
public abstract int NumberOfBaseAddresses();
|
|
||||||
//{
|
|
||||||
// get;
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
private static string[] classtext = new string[]
|
|
||||||
{
|
|
||||||
"pre pci 2.0", // 00
|
|
||||||
"disk", // 01
|
|
||||||
"network", // 02
|
|
||||||
"display", // 03
|
|
||||||
"multimedia", // 04
|
|
||||||
"memory", // 05
|
|
||||||
"bridge", // 06
|
|
||||||
"communication", // 07
|
|
||||||
"system peripheral",// 08
|
|
||||||
"input", // 09
|
|
||||||
"docking station", // 0A
|
|
||||||
"CPU", // 0B
|
|
||||||
"serial bus", // 0C
|
|
||||||
};
|
|
||||||
|
|
||||||
private static string[][] subclasstext = new string[][]
|
|
||||||
{
|
|
||||||
new string[] { "VGA Device", "non VGA device"},
|
|
||||||
new string[] { "SCSI" ,"IDE" , "floppy","IPI","RAID", "other" },
|
|
||||||
new string[] { "Ethernet", "TokenRing", "FDDI" , "ATM" , "other" },
|
|
||||||
new string[] { "VGA", "SuperVGA","XGA", "other"},
|
|
||||||
new string[] { "video" ,"audio", "other"},
|
|
||||||
new string[] { "RAM", "Flash memory" , "other"},
|
|
||||||
new string[] { "CPU/PCI" ,"PCI/ISA" , "PCI/EISA" , "PCI/MCA","PCI/PCI" , "PCI/PCMCIA", "PCI/NuBus", "PCI/CardBus", "other"},
|
|
||||||
new string[] { "serial", "parallel", "other"},
|
|
||||||
new string[] { "PIC", "DMAC" , "timer" ,"RTC", "other"},
|
|
||||||
new string[] { "keyboard","digitizer","mouse", "other" },
|
|
||||||
new string[] { "generic" , "other" },
|
|
||||||
new string[] { "386", "486","Pentium" , "P6" ,"Alpha","coproc","other" },
|
|
||||||
new string[] { "Firewire", "ACCESS.bus" , "SSA", "USB" ,"Fiber Channel" , "other"},
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
public string GetClassInfo()
|
|
||||||
{
|
|
||||||
int cc = ClassCode;
|
|
||||||
int sc = SubClass;
|
|
||||||
|
|
||||||
if (cc >= classtext.Length)
|
|
||||||
return "unknown class (" + cc.ToString() + ") / subclass (" + sc.ToString() + ")";
|
|
||||||
|
|
||||||
|
|
||||||
if (sc >= subclasstext[cc].Length)
|
|
||||||
return String.Concat(classtext[cc], " / unknown subclass (", sc.ToString(), ")");
|
|
||||||
|
|
||||||
return String.Concat( classtext[cc] , " / " , subclasstext[cc][sc]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private const UInt32 PCI_BASE_ADDRESS_SPACE = 0x01; /* 0 = memory, 1 = I/O */
|
|
||||||
private const UInt32 PCI_BASE_ADDRESS_SPACE_IO = 0x01;
|
|
||||||
private const UInt32 PCI_BASE_ADDRESS_SPACE_MEMORY = 0x00;
|
|
||||||
private const UInt32 PCI_BASE_ADDRESS_MEM_TYPE_MASK = 0x06;
|
|
||||||
private const UInt32 PCI_BASE_ADDRESS_MEM_TYPE_32 = 0x00; /* 32 bit address */
|
|
||||||
private const UInt32 PCI_BASE_ADDRESS_MEM_TYPE_1M = 0x02; /* Below 1M [obsolete] */
|
|
||||||
private const UInt32 PCI_BASE_ADDRESS_MEM_TYPE_64 = 0x04; /* 64 bit address */
|
|
||||||
private const UInt32 PCI_BASE_ADDRESS_MEM_PREFETCH = 0x08; /* prefetchable? */
|
|
||||||
private const UInt32 PCI_BASE_ADDRESS_MEM_MASK = 0xfffffff0;
|
|
||||||
private const UInt32 PCI_BASE_ADDRESS_IO_MASK = 0xfffffffc;
|
|
||||||
|
|
||||||
|
|
||||||
protected PCIDevice(byte bus, byte slot, byte function)
|
|
||||||
{
|
|
||||||
this.Bus = bus;
|
|
||||||
this.Slot = slot;
|
|
||||||
this.Function = function;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool NeedsIO = false;
|
|
||||||
private bool NeedsMemory = false;
|
|
||||||
|
|
||||||
private bool _NeedsLayingout = true;
|
|
||||||
private void LayoutIO()
|
|
||||||
{
|
|
||||||
//Console.WriteLine("Checking AdressSpaces of PCI(" + Bus + ", " + Slot + ", " + Function + ")");
|
|
||||||
|
|
||||||
IOMaps = new AddressSpace[NumberOfBaseAddresses()];
|
|
||||||
|
|
||||||
for (byte i = 0; i < NumberOfBaseAddresses(); i++)
|
|
||||||
{
|
|
||||||
UInt32 address = GetBaseAddress(i);
|
|
||||||
SetBaseAddress(i, 0xffffffff);
|
|
||||||
UInt32 flags = GetBaseAddress(i);
|
|
||||||
SetBaseAddress(i, address);
|
|
||||||
|
|
||||||
if (address == 0)
|
|
||||||
{
|
|
||||||
//Console.WriteLine("register " + i + " - none " + PCIBus.ToHex(flags,8));
|
|
||||||
|
|
||||||
IOMaps[i] = null;
|
|
||||||
}
|
|
||||||
else if ((address & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY)
|
|
||||||
{
|
|
||||||
UInt32 size = ~(PCI_BASE_ADDRESS_MEM_MASK & flags)+1;
|
|
||||||
|
|
||||||
IOMaps[i] = new MemoryAddressSpace(address, size);
|
|
||||||
//Console.WriteLine("register " + i + " - " + size + "b mem");
|
|
||||||
|
|
||||||
NeedsIO = true;
|
|
||||||
}
|
|
||||||
else if ((address & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
|
|
||||||
{
|
|
||||||
UInt32 size = ~(PCI_BASE_ADDRESS_IO_MASK & flags) +1;
|
|
||||||
|
|
||||||
IOMaps[i] = new IOAddressSpace(address, size);
|
|
||||||
//Console.WriteLine("register " + i + " - " + size + "b io");
|
|
||||||
|
|
||||||
NeedsMemory = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_NeedsLayingout = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private AddressSpace[] IOMaps;
|
|
||||||
|
|
||||||
public AddressSpace GetAddressSpace(byte index)
|
|
||||||
{
|
|
||||||
if (index < 0 || index >= NumberOfBaseAddresses())
|
|
||||||
throw new ArgumentOutOfRangeException("index");
|
|
||||||
|
|
||||||
if (_NeedsLayingout)
|
|
||||||
LayoutIO();
|
|
||||||
|
|
||||||
return IOMaps[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte Bus { get; private set; }
|
|
||||||
public byte Slot { get; private set; }
|
|
||||||
public byte Function { get; private set; }
|
|
||||||
|
|
||||||
public bool DeviceExists { get { return VendorID != 0xFFFF && VendorID != 0x0; } }
|
|
||||||
public bool IsMultiFunction { get { return (Read8(0x0e) & 0xf0) != 0; } }
|
|
||||||
|
|
||||||
public UInt32 VendorID { get { return Read16(0x0); } }
|
|
||||||
public UInt16 DeviceID { get { return Read16(0x2); } }
|
|
||||||
|
|
||||||
public PCICommand Command { get { return (PCICommand)Read16(0x4); } set { Write16(0x4, (ushort)value); } }
|
|
||||||
public PCIStatus Status { get { return (PCIStatus)Read16(0x6); } set { Write16(0x6, (ushort)value); } }
|
|
||||||
|
|
||||||
public byte RevisionID { get { return Read8(0x8); } }
|
|
||||||
public byte ProgIF { get { return Read8(0x9); } }
|
|
||||||
public byte SubClass { get { return Read8(0xa); } }
|
|
||||||
public byte ClassCode { get { return Read8(0xb); } }
|
|
||||||
|
|
||||||
public byte CacheLineSize { get { return Read8(0x0c); } set { Write8(0x0c, value); } }
|
|
||||||
public byte LatencyTimer { get { return Read8(0x0d); } set { Write8(0x0d, value); } }
|
|
||||||
public byte HeaderType { get { return (byte)(Read8(0x0e) & 0xf); } }
|
|
||||||
public PCIBist Bist { get { return (PCIBist)Read8(0x0f); } set { Write8(0x0f, (byte)value); } }
|
|
||||||
|
|
||||||
public UInt32 GetBaseAddress(byte index)
|
|
||||||
{
|
|
||||||
return Read32((byte)(0x10 + index * 4));
|
|
||||||
}
|
|
||||||
public void SetBaseAddress(byte index, UInt32 value)
|
|
||||||
{
|
|
||||||
Write32((byte)(0x10 + index *4), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UInt32 BaseAddress0 { get { return Read32(0x10); } set { Write32(0x10, value); } }
|
|
||||||
public UInt32 BaseAddress1 { get { return Read32(0x14); } set { Write32(0x14, value); } }
|
|
||||||
|
|
||||||
public byte InterruptLine { get { return Read8(0x3c); } set { Write8(0x3c, value); } }
|
|
||||||
public byte InterruptPin { get { return Read8(0x3d); } set { Write8(0x3d, value); } }
|
|
||||||
public byte MinGNT { get { return Read8(0x3e); } set { Write8(0x3e, value); } }
|
|
||||||
public byte MaxLAT { get { return Read8(0x3f); } set { Write8(0x3f, value); } }
|
|
||||||
|
|
||||||
protected const ushort ConfigAddr = 0xCF8;
|
|
||||||
protected const ushort ConfigData = 0xCFC;
|
|
||||||
|
|
||||||
|
|
||||||
public void DisableDevice()
|
|
||||||
{
|
|
||||||
Command = Command & (~PCICommand.IO & ~PCICommand.Master & PCICommand.Memort);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void EnableDevice()
|
|
||||||
{
|
|
||||||
Command = Command & ((NeedsIO ? PCICommand.IO : 0) & PCICommand.Master & (NeedsMemory ? PCICommand.Memort : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
private UInt32 GetAddress(byte aRegister)
|
|
||||||
{
|
|
||||||
return (UInt32)(
|
|
||||||
// Bits 23-16
|
|
||||||
((UInt32)Bus << 16)
|
|
||||||
// Bits 15-11
|
|
||||||
| (((UInt32)Slot & 0x1F) << 11)
|
|
||||||
// Bits 10-8
|
|
||||||
| (((UInt32)Function & 0x07) << 8)
|
|
||||||
// Bits 7-0
|
|
||||||
| ((UInt32)aRegister & 0xFF)
|
|
||||||
// Enable bit - must be set
|
|
||||||
| 0x80000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UInt32 Read32(byte aRegister)
|
|
||||||
{
|
|
||||||
CPUBus.Write32(ConfigAddr, GetAddress(aRegister));
|
|
||||||
return CPUBus.Read32(ConfigData);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UInt16 Read16(byte aRegister)
|
|
||||||
{
|
|
||||||
CPUBus.Write32(ConfigAddr, GetAddress(aRegister));
|
|
||||||
return CPUBus.Read16(ConfigData);
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte Read8(byte aRegister)
|
|
||||||
{
|
|
||||||
CPUBus.Write32(ConfigAddr, GetAddress(aRegister));
|
|
||||||
return CPUBus.Read8(ConfigData);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Write32(byte aRegister, UInt32 value)
|
|
||||||
{
|
|
||||||
CPUBus.Write32(ConfigAddr, GetAddress(aRegister));
|
|
||||||
CPUBus.Write32(ConfigData, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Write16(byte aRegister, UInt16 value)
|
|
||||||
{
|
|
||||||
CPUBus.Write32(ConfigAddr, GetAddress(aRegister));
|
|
||||||
CPUBus.Write16(ConfigData, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Write8(byte aRegister, byte value)
|
|
||||||
{
|
|
||||||
CPUBus.Write32(ConfigAddr, GetAddress(aRegister));
|
|
||||||
CPUBus.Write8(ConfigData, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Cosmos.Hardware.PC {
|
|
||||||
public static class DebugUtil {
|
|
||||||
public static unsafe void LogInterruptOccurred(Interrupts.InterruptContext* aContext) {
|
|
||||||
uint aInterrupt = aContext->Interrupt;
|
|
||||||
Cosmos.Hardware.DebugUtil.StartLogging();
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteSerialString("<InterruptOccurred Interrupt=\"");
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteNumber(aContext->Interrupt, 32);
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteSerialString("\" SS=\"");
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteNumber(aContext->SS, 32);
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteSerialString("\" GS=\"");
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteNumber(aContext->GS, 32);
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteSerialString("\" FS=\"");
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteNumber(aContext->FS, 32);
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteSerialString("\" ES=\"");
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteNumber(aContext->ES, 32);
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteSerialString("\" DS=\"");
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteNumber(aContext->DS, 32);
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteSerialString("\" CS=\"");
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteNumber(aContext->CS, 32);
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteSerialString("\" ESI=\"");
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteNumber(aContext->ESI, 32);
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteSerialString("\" EDI=\"");
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteNumber(aContext->EDI, 32);
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteSerialString("\" EBP=\"");
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteNumber(aContext->EBP, 32);
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteSerialString("\" ESP=\"");
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteNumber(aContext->ESP, 32);
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteSerialString("\" EBX=\"");
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteNumber(aContext->EBX, 32);
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteSerialString("\" EDX=\"");
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteNumber(aContext->EDX, 32);
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteSerialString("\" ECX=\"");
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteNumber(aContext->ECX, 32);
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteSerialString("\" EAX=\"");
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteNumber(aContext->EAX, 32);
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteSerialString("\" Param=\"");
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteNumber(aContext->Param, 32);
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteSerialString("\" EFlags=\"");
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteNumber(aContext->EFlags, 32);
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteSerialString("\" UserESP=\"");
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteNumber(aContext->UserESP, 32);
|
|
||||||
Cosmos.Hardware.DebugUtil.WriteSerialString("\"/>\r\n");
|
|
||||||
Cosmos.Hardware.DebugUtil.EndLogging();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using HW = Cosmos.Hardware;
|
|
||||||
|
|
||||||
namespace Cosmos.Hardware.PC {
|
|
||||||
public class Global : Cosmos.Hardware.Global {
|
|
||||||
public static void Init() {
|
|
||||||
mProcessor = new Processor();
|
|
||||||
Bus.CPU.PIC.Init();
|
|
||||||
|
|
||||||
//All old.. need to port ----------------
|
|
||||||
HW.Serial.InitSerial(0);
|
|
||||||
HW.DebugUtil.Initialize();
|
|
||||||
HW.DebugUtil.SendMessage("Logging", "Initialized!");
|
|
||||||
HW.PIT.Initialize(Tick);
|
|
||||||
|
|
||||||
// Partially new
|
|
||||||
//HW.Interrupts.IRQ01 += new Interrupts.InterruptDelegate(Cosmos.Hardware.Keyboard.HandleKeyboardInterrupt);
|
|
||||||
Interrupts.Init();
|
|
||||||
|
|
||||||
HW.PC.Bus.PCIBus.Init();
|
|
||||||
|
|
||||||
// end partially new
|
|
||||||
|
|
||||||
HW.Storage.ATA.Initialize(Sleep);
|
|
||||||
HW.Storage.ATAOld.Initialize(Sleep);
|
|
||||||
|
|
||||||
HW.CPU.CreateIDT();
|
|
||||||
// end old -----------------
|
|
||||||
|
|
||||||
// MTW new
|
|
||||||
HW.New.Storage.ATA.Initialize(Sleep);
|
|
||||||
// MTW new end
|
|
||||||
|
|
||||||
HW.Device.Add(new Bus.CPU.Keyboard());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static uint TickCount {
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void Tick(object aSender, EventArgs aEventArgs) {
|
|
||||||
TickCount += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: Change this to use an x86 Op or something so it doesnt
|
|
||||||
// just thrash
|
|
||||||
public static void Sleep(uint aMSec) {
|
|
||||||
uint xStart = TickCount;
|
|
||||||
uint xEnd = xStart + aMSec;
|
|
||||||
Cosmos.Hardware.DebugUtil.SendNumber("PC", "Sleep", aMSec, 32);
|
|
||||||
while (TickCount < xEnd) {
|
|
||||||
;
|
|
||||||
}
|
|
||||||
Cosmos.Hardware.DebugUtil.SendMessage("PC", "Sleeping done");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,325 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Cosmos.Hardware.PC {
|
|
||||||
public class Interrupts {
|
|
||||||
[StructLayout(LayoutKind.Explicit, Size=76)]
|
|
||||||
public struct InterruptContext {
|
|
||||||
[FieldOffset(0)]
|
|
||||||
public uint SS;
|
|
||||||
[FieldOffset(4)]
|
|
||||||
public uint GS;
|
|
||||||
[FieldOffset(8)]
|
|
||||||
public uint FS;
|
|
||||||
[FieldOffset(12)]
|
|
||||||
public uint ES;
|
|
||||||
[FieldOffset(16)]
|
|
||||||
public uint DS;
|
|
||||||
[FieldOffset(20)]
|
|
||||||
public uint EDI;
|
|
||||||
[FieldOffset(24)]
|
|
||||||
public uint ESI;
|
|
||||||
[FieldOffset(28)]
|
|
||||||
public uint EBP;
|
|
||||||
[FieldOffset(32)]
|
|
||||||
public uint ESP;
|
|
||||||
[FieldOffset(36)]
|
|
||||||
public uint EBX;
|
|
||||||
[FieldOffset(40)]
|
|
||||||
public uint EDX;
|
|
||||||
[FieldOffset(44)]
|
|
||||||
public uint ECX;
|
|
||||||
[FieldOffset(48)]
|
|
||||||
public uint EAX;
|
|
||||||
[FieldOffset(52)]
|
|
||||||
public uint Interrupt;
|
|
||||||
[FieldOffset(56)]
|
|
||||||
public uint Param;
|
|
||||||
[FieldOffset(60)]
|
|
||||||
public uint EIP;
|
|
||||||
[FieldOffset(64)]
|
|
||||||
public uint CS;
|
|
||||||
[FieldOffset(68)]
|
|
||||||
public uint EFlags;
|
|
||||||
[FieldOffset(72)]
|
|
||||||
public uint UserESP;
|
|
||||||
}
|
|
||||||
|
|
||||||
public unsafe static void HandleInterrupt_Default(InterruptContext* aContext) {
|
|
||||||
//Console.Write("Interrupt ");
|
|
||||||
//WriteNumber(aContext->Interrupt, 32);
|
|
||||||
//Console.WriteLine("");
|
|
||||||
DebugUtil.LogInterruptOccurred(aContext);
|
|
||||||
if (aContext->Interrupt >= 0x20 && aContext->Interrupt <= 0x2F) {
|
|
||||||
if (aContext->Interrupt >= 0x28) {
|
|
||||||
Bus.CPU.PIC.SignalSecondary();
|
|
||||||
} else {
|
|
||||||
Bus.CPU.PIC.SignalPrimary();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public delegate void InterruptDelegate();
|
|
||||||
|
|
||||||
//IRQ 2 - Cascaded signals from IRQs 8-15. A device configured to use IRQ 2 will actually be using IRQ 9
|
|
||||||
//IRQ 3 - COM2 (Default) and COM4 (User) serial ports
|
|
||||||
//IRQ 4 - COM1 (Default) and COM3 (User) serial ports
|
|
||||||
//IRQ 5 - LPT2 Parallel Port 2 or sound card
|
|
||||||
//IRQ 6 - Floppy disk controller
|
|
||||||
//IRQ 7 - LPT1 Parallel Port 1 or sound card (8-bit Sound Blaster and compatibles)
|
|
||||||
|
|
||||||
//IRQ 8 - Real time clock
|
|
||||||
//IRQ 9 - Free / Open interrupt / Available / SCSI. Any devices configured to use IRQ 2 will actually be using IRQ 9.
|
|
||||||
//IRQ 10 - Free / Open interrupt / Available / SCSI
|
|
||||||
//IRQ 11 - Free / Open interrupt / Available / SCSI
|
|
||||||
//IRQ 12 - PS/2 connector Mouse. If no PS/2 connector mouse is used, this can be used for other peripherals
|
|
||||||
//IRQ 13 - ISA / Math Co-Processor
|
|
||||||
|
|
||||||
//IRQ 0 - System timer. Reserved for the system. Cannot be changed by a user.
|
|
||||||
public static unsafe void HandleInterrupt_20(InterruptContext* aContext) {
|
|
||||||
PIT.HandleInterrupt();
|
|
||||||
Bus.CPU.PIC.SignalPrimary();
|
|
||||||
}
|
|
||||||
|
|
||||||
static public InterruptDelegate IRQ01;
|
|
||||||
//IRQ 1 - Keyboard. Reserved for the system. Cannot be altered even if no keyboard is present or needed.
|
|
||||||
public static unsafe void HandleInterrupt_21(InterruptContext* aContext) {
|
|
||||||
//Change area
|
|
||||||
//
|
|
||||||
// Triggers IL2CPU error
|
|
||||||
//IRQ01();
|
|
||||||
//
|
|
||||||
// Old keyboard
|
|
||||||
Cosmos.Hardware.Keyboard.HandleKeyboardInterrupt();
|
|
||||||
//
|
|
||||||
// New Keyboard
|
|
||||||
//Cosmos.Hardware.PC
|
|
||||||
//
|
|
||||||
// - End change area
|
|
||||||
|
|
||||||
Bus.CPU.PIC.SignalPrimary();
|
|
||||||
}
|
|
||||||
|
|
||||||
//IRQ 11 - (Added for RTL8139 network card)
|
|
||||||
static public InterruptDelegate IRQ11;
|
|
||||||
public static unsafe void HandleInterrupt_2B(InterruptContext* aContext)
|
|
||||||
{
|
|
||||||
if (IRQ11 != null)
|
|
||||||
IRQ11();
|
|
||||||
}
|
|
||||||
|
|
||||||
//IRQ 14 - Primary IDE. If no Primary IDE this can be changed
|
|
||||||
public static unsafe void HandleInterrupt_2E(InterruptContext* aContext) {
|
|
||||||
Cosmos.Hardware.DebugUtil.SendMessage("IRQ", "Primary IDE");
|
|
||||||
//Storage.ATAOld.HandleInterruptPrimary();
|
|
||||||
New.Storage.ATA.HandleInterruptPrimary();
|
|
||||||
Bus.CPU.PIC.SignalSecondary();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static unsafe void HandleInterrupt_35(InterruptContext* aContext) {
|
|
||||||
Cosmos.Hardware.DebugUtil.SendMessage("Interrupts", "Interrupt 35 handler");
|
|
||||||
Cosmos.Hardware.DebugUtil.SendNumber("Interrupts", "Context address", (uint)aContext, 32);
|
|
||||||
DebugUtil.LogInterruptOccurred(aContext);
|
|
||||||
Console.WriteLine("Halting");
|
|
||||||
while (true)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
//IRQ 15 - Secondary IDE
|
|
||||||
public static unsafe void HandleInterrupt_2F(InterruptContext* aContext) {
|
|
||||||
New.Storage.ATA.HandleInterruptSecondary();
|
|
||||||
Cosmos.Hardware.DebugUtil.SendMessage("IRQ", "Secondary IDE");
|
|
||||||
Bus.CPU.PIC.SignalSecondary();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static unsafe void HandleInterrupt_00(InterruptContext* aContext) {
|
|
||||||
HandleException(aContext->EIP, "Divide by zero", "EDivideByZero", aContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static unsafe void HandleInterrupt_06(InterruptContext* aContext) {
|
|
||||||
HandleException(aContext->EIP, "Invalid Opcode", "EInvalidOpcode", aContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static unsafe void HandleInterrupt_0D(InterruptContext* aContext) {
|
|
||||||
HandleException(aContext->EIP, "General Protection Fault", "GPF", aContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static unsafe void HandleInterrupt_01(InterruptContext* aContext) {
|
|
||||||
HandleException(aContext->EIP, "Debug Exception", "Debug Exception", aContext);
|
|
||||||
}
|
|
||||||
public static unsafe void HandleInterrupt_02(InterruptContext* aContext) {
|
|
||||||
HandleException(aContext->EIP, "Non Maskable Interrupt Exception", "Non Maskable Interrupt Exception", aContext);
|
|
||||||
}
|
|
||||||
public static unsafe void HandleInterrupt_03(InterruptContext* aContext) {
|
|
||||||
HandleException(aContext->EIP, "Breakpoint Exception", "Breakpoint Exception", aContext);
|
|
||||||
}
|
|
||||||
public static unsafe void HandleInterrupt_04(InterruptContext* aContext) {
|
|
||||||
HandleException(aContext->EIP, "Into Detected Overflow Exception", "Into Detected Overflow Exception", aContext);
|
|
||||||
}
|
|
||||||
public static unsafe void HandleInterrupt_05(InterruptContext* aContext) {
|
|
||||||
HandleException(aContext->EIP, "Out of Bounds Exception", "Out of Bounds Exception", aContext);
|
|
||||||
}
|
|
||||||
public static unsafe void HandleInterrupt_07(InterruptContext* aContext) {
|
|
||||||
HandleException(aContext->EIP, "No Coprocessor Exception", "No Coprocessor Exception", aContext);
|
|
||||||
}
|
|
||||||
public static unsafe void HandleInterrupt_08(InterruptContext* aContext) {
|
|
||||||
HandleException(aContext->EIP, "Double Fault Exception", "Double Fault Exception", aContext);
|
|
||||||
}
|
|
||||||
public static unsafe void HandleInterrupt_09(InterruptContext* aContext) {
|
|
||||||
HandleException(aContext->EIP, "Coprocessor Segment Overrun Exception", "Coprocessor Segment Overrun Exception", aContext);
|
|
||||||
}
|
|
||||||
public static unsafe void HandleInterrupt_0A(InterruptContext* aContext) {
|
|
||||||
HandleException(aContext->EIP, "Bad TSS Exception", "Bad TSS Exception", aContext);
|
|
||||||
}
|
|
||||||
public static unsafe void HandleInterrupt_0B(InterruptContext* aContext) {
|
|
||||||
HandleException(aContext->EIP, "Segment Not Present", "Segment Not Present", aContext);
|
|
||||||
}
|
|
||||||
public static unsafe void HandleInterrupt_0C(InterruptContext* aContext) {
|
|
||||||
HandleException(aContext->EIP, "Stack Fault Exception", "Stack Fault Exception", aContext);
|
|
||||||
}
|
|
||||||
public static unsafe void HandleInterrupt_0E(InterruptContext* aContext) {
|
|
||||||
HandleException(aContext->EIP, "Page Fault Exception", "Page Fault Exception", aContext);
|
|
||||||
}
|
|
||||||
public static unsafe void HandleInterrupt_0F(InterruptContext* aContext) {
|
|
||||||
HandleException(aContext->EIP, "Unknown Interrupt Exception", "Unknown Interrupt Exception", aContext);
|
|
||||||
}
|
|
||||||
public static unsafe void HandleInterrupt_10(InterruptContext* aContext) {
|
|
||||||
HandleException(aContext->EIP, "Coprocessor Fault Exception", "Coprocessor Fault Exception", aContext);
|
|
||||||
}
|
|
||||||
public static unsafe void HandleInterrupt_11(InterruptContext* aContext) {
|
|
||||||
HandleException(aContext->EIP, "Alignment Exception", "Alignment Exception", aContext);
|
|
||||||
}
|
|
||||||
public static unsafe void HandleInterrupt_12(InterruptContext* aContext) {
|
|
||||||
HandleException(aContext->EIP, "Machine Check Exception", "Machine Check Exception", aContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static unsafe void HandleException(uint aEIP, string aDescription, string aName, InterruptContext* ctx) {
|
|
||||||
const string SysFault = "System Fault";
|
|
||||||
|
|
||||||
//Console.ForegroundColor = ConsoleColor.White;
|
|
||||||
//Console.BackgroundColor = ConsoleColor.DarkRed;
|
|
||||||
Console.Write(SysFault);
|
|
||||||
//for (int i = 0; i < Console.WindowWidth - SysFault.Length; i++)
|
|
||||||
// Console.Write(" ");
|
|
||||||
|
|
||||||
//Console.BackgroundColor = ConsoleColor.Black;
|
|
||||||
|
|
||||||
Console.Write(aDescription);
|
|
||||||
Console.Write(" at ");
|
|
||||||
WriteNumber(aEIP, 32);
|
|
||||||
|
|
||||||
Console.WriteLine();
|
|
||||||
// Console.WriteLine("Register States:");
|
|
||||||
// TODO: Register states
|
|
||||||
|
|
||||||
Cosmos.Hardware.DebugUtil.SendMessage("Exceptions", aName);
|
|
||||||
Console.WriteLine();
|
|
||||||
while (true)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is to trick IL2CPU to compile it in
|
|
||||||
//TODO: Make a new attribute that IL2CPU sees when scanning to force inclusion so we dont have to do this.
|
|
||||||
public static void Init() {
|
|
||||||
bool xTest = false;
|
|
||||||
if (xTest) {
|
|
||||||
unsafe {
|
|
||||||
HandleInterrupt_Default(null);
|
|
||||||
HandleInterrupt_00(null);
|
|
||||||
HandleInterrupt_01(null);
|
|
||||||
HandleInterrupt_02(null);
|
|
||||||
HandleInterrupt_03(null);
|
|
||||||
HandleInterrupt_04(null);
|
|
||||||
HandleInterrupt_05(null);
|
|
||||||
HandleInterrupt_06(null);
|
|
||||||
HandleInterrupt_07(null);
|
|
||||||
HandleInterrupt_08(null);
|
|
||||||
HandleInterrupt_09(null);
|
|
||||||
HandleInterrupt_0A(null);
|
|
||||||
HandleInterrupt_0B(null);
|
|
||||||
HandleInterrupt_0C(null);
|
|
||||||
HandleInterrupt_0D(null);
|
|
||||||
HandleInterrupt_0E(null);
|
|
||||||
HandleInterrupt_0F(null);
|
|
||||||
HandleInterrupt_10(null);
|
|
||||||
HandleInterrupt_11(null);
|
|
||||||
HandleInterrupt_12(null);
|
|
||||||
HandleInterrupt_20(null);
|
|
||||||
HandleInterrupt_21(null);
|
|
||||||
HandleInterrupt_2B(null);
|
|
||||||
HandleInterrupt_2E(null);
|
|
||||||
HandleInterrupt_2F(null);
|
|
||||||
HandleInterrupt_35(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void WriteNumber(uint aValue, byte aBitCount) {
|
|
||||||
uint xValue = aValue;
|
|
||||||
byte xCurrentBits = aBitCount;
|
|
||||||
Console.Write("0x");
|
|
||||||
while (xCurrentBits >= 4) {
|
|
||||||
xCurrentBits -= 4;
|
|
||||||
byte xCurrentDigit = (byte)((xValue >> xCurrentBits) & 0xF);
|
|
||||||
string xDigitString = null;
|
|
||||||
switch (xCurrentDigit) {
|
|
||||||
case 0:
|
|
||||||
xDigitString = "0";
|
|
||||||
goto default;
|
|
||||||
case 1:
|
|
||||||
xDigitString = "1";
|
|
||||||
goto default;
|
|
||||||
case 2:
|
|
||||||
xDigitString = "2";
|
|
||||||
goto default;
|
|
||||||
case 3:
|
|
||||||
xDigitString = "3";
|
|
||||||
goto default;
|
|
||||||
case 4:
|
|
||||||
xDigitString = "4";
|
|
||||||
goto default;
|
|
||||||
case 5:
|
|
||||||
xDigitString = "5";
|
|
||||||
goto default;
|
|
||||||
case 6:
|
|
||||||
xDigitString = "6";
|
|
||||||
goto default;
|
|
||||||
case 7:
|
|
||||||
xDigitString = "7";
|
|
||||||
goto default;
|
|
||||||
case 8:
|
|
||||||
xDigitString = "8";
|
|
||||||
goto default;
|
|
||||||
case 9:
|
|
||||||
xDigitString = "9";
|
|
||||||
goto default;
|
|
||||||
case 10:
|
|
||||||
xDigitString = "A";
|
|
||||||
goto default;
|
|
||||||
case 11:
|
|
||||||
xDigitString = "B";
|
|
||||||
goto default;
|
|
||||||
case 12:
|
|
||||||
xDigitString = "C";
|
|
||||||
goto default;
|
|
||||||
case 13:
|
|
||||||
xDigitString = "D";
|
|
||||||
goto default;
|
|
||||||
case 14:
|
|
||||||
xDigitString = "E";
|
|
||||||
goto default;
|
|
||||||
case 15:
|
|
||||||
xDigitString = "F";
|
|
||||||
goto default;
|
|
||||||
default:
|
|
||||||
Console.Write(xDigitString);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Cosmos.Hardware.PC {
|
|
||||||
public class Processor : Cosmos.Hardware.Processor {
|
|
||||||
public Processor() {
|
|
||||||
Processor.CreateGDT();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Plugged
|
|
||||||
public static void CreateGDT() { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -87,8 +87,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cosmos.FileSystem", "Cosmos
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lost", "Tests\MathTest\Lost\Lost.csproj", "{EF65AFB7-9DC9-4ACD-946D-7E973A67DBBE}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lost", "Tests\MathTest\Lost\Lost.csproj", "{EF65AFB7-9DC9-4ACD-946D-7E973A67DBBE}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Drivers", "Drivers", "{E3AA753A-2E91-4FE7-A9E2-8119984DEA68}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{4DE8EC69-B412-41C4-BCD9-1E032984E888}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{4DE8EC69-B412-41C4-BCD9-1E032984E888}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cosmos.Debug", "Cosmos.Debug\Cosmos.Debug.csproj", "{23C298B4-A2A3-4D3F-A57F-CF068B572928}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cosmos.Debug", "Cosmos.Debug\Cosmos.Debug.csproj", "{23C298B4-A2A3-4D3F-A57F-CF068B572928}"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue