Permalink
Browse files

Files for Part 17, https://www.youtube.com/watch?v=9xpKXEZ9Sxo

  • Loading branch information...
AlgorithMan-de committed Jul 16, 2016
1 parent e095bd0 commit 7a49a1635d2ba7c8e2a78763acefb04497938bc7
Showing with 241 additions and 8 deletions.
  1. +84 −0 include/drivers/amd_am79c973.h
  2. +1 −0 makefile
  3. +134 −0 src/drivers/amd_am79c973.cpp
  4. +9 −8 src/hardwarecommunication/pci.cpp
  5. +13 −0 src/kernel.cpp
@@ -0,0 +1,84 @@
#ifndef __MYOS__DRIVERS__AMD_AM79C973_H
#define __MYOS__DRIVERS__AMD_AM79C973_H
#include <common/types.h>
#include <drivers/driver.h>
#include <hardwarecommunication/pci.h>
#include <hardwarecommunication/interrupts.h>
#include <hardwarecommunication/port.h>
namespace myos
{
namespace drivers
{
class amd_am79c973 : public Driver, public hardwarecommunication::InterruptHandler
{
struct InitializationBlock
{
common::uint16_t mode;
unsigned reserved1 : 4;
unsigned numSendBuffers : 4;
unsigned reserved2 : 4;
unsigned numRecvBuffers : 4;
common::uint64_t physicalAddress : 48;
common::uint16_t reserved3;
common::uint64_t logicalAddress;
common::uint32_t recvBufferDescrAddress;
common::uint32_t sendBufferDescrAddress;
} __attribute__((packed));
struct BufferDescriptor
{
common::uint32_t address;
common::uint32_t flags;
common::uint32_t flags2;
common::uint32_t avail;
} __attribute__((packed));
hardwarecommunication::Port16Bit MACAddress0Port;
hardwarecommunication::Port16Bit MACAddress2Port;
hardwarecommunication::Port16Bit MACAddress4Port;
hardwarecommunication::Port16Bit registerDataPort;
hardwarecommunication::Port16Bit registerAddressPort;
hardwarecommunication::Port16Bit resetPort;
hardwarecommunication::Port16Bit busControlRegisterDataPort;
InitializationBlock initBlock;
BufferDescriptor* sendBufferDescr;
common::uint8_t sendBufferDescrMemory[2048+15];
common::uint8_t sendBuffers[2*1024+15][8];
common::uint8_t currentSendBuffer;
BufferDescriptor* recvBufferDescr;
common::uint8_t recvBufferDescrMemory[2048+15];
common::uint8_t recvBuffers[2*1024+15][8];
common::uint8_t currentRecvBuffer;
public:
amd_am79c973(myos::hardwarecommunication::PeripheralComponentInterconnectDeviceDescriptor *dev,
myos::hardwarecommunication::InterruptManager* interrupts);
~amd_am79c973();
void Activate();
int Reset();
common::uint32_t HandleInterrupt(common::uint32_t esp);
};
}
}
#endif
View
@@ -14,6 +14,7 @@ objects = obj/loader.o \
obj/hardwarecommunication/interruptstubs.o \
obj/hardwarecommunication/interrupts.o \
obj/multitasking.o \
obj/drivers/amd_am79c973.o \
obj/hardwarecommunication/pci.o \
obj/drivers/keyboard.o \
obj/drivers/mouse.o \
@@ -0,0 +1,134 @@
#include <drivers/amd_am79c973.h>
using namespace myos;
using namespace myos::common;
using namespace myos::drivers;
using namespace myos::hardwarecommunication;
amd_am79c973::amd_am79c973(PeripheralComponentInterconnectDeviceDescriptor *dev, InterruptManager* interrupts)
: Driver(),
InterruptHandler(interrupts, dev->interrupt + interrupts->HardwareInterruptOffset()),
MACAddress0Port(dev->portBase),
MACAddress2Port(dev->portBase + 0x02),
MACAddress4Port(dev->portBase + 0x04),
registerDataPort(dev->portBase + 0x10),
registerAddressPort(dev->portBase + 0x12),
resetPort(dev->portBase + 0x14),
busControlRegisterDataPort(dev->portBase + 0x16)
{
currentSendBuffer = 0;
currentRecvBuffer = 0;
uint64_t MAC0 = MACAddress0Port.Read() % 256;
uint64_t MAC1 = MACAddress0Port.Read() / 256;
uint64_t MAC2 = MACAddress2Port.Read() % 256;
uint64_t MAC3 = MACAddress2Port.Read() / 256;
uint64_t MAC4 = MACAddress4Port.Read() % 256;
uint64_t MAC5 = MACAddress4Port.Read() / 256;
uint64_t MAC = MAC5 << 40
| MAC4 << 32
| MAC3 << 24
| MAC2 << 16
| MAC1 << 8
| MAC0;
// 32 bit mode
registerAddressPort.Write(20);
busControlRegisterDataPort.Write(0x102);
// STOP reset
registerAddressPort.Write(0);
registerDataPort.Write(0x04);
// initBlock
initBlock.mode = 0x0000; // promiscuous mode = false
initBlock.reserved1 = 0;
initBlock.numSendBuffers = 3;
initBlock.reserved2 = 0;
initBlock.numRecvBuffers = 3;
initBlock.physicalAddress = MAC;
initBlock.reserved3 = 0;
initBlock.logicalAddress = 0;
sendBufferDescr = (BufferDescriptor*)((((uint32_t)&sendBufferDescrMemory[0]) + 15) & ~((uint32_t)0xF));
initBlock.sendBufferDescrAddress = (uint32_t)sendBufferDescr;
recvBufferDescr = (BufferDescriptor*)((((uint32_t)&recvBufferDescrMemory[0]) + 15) & ~((uint32_t)0xF));
initBlock.recvBufferDescrAddress = (uint32_t)recvBufferDescr;
for(uint8_t i = 0; i < 8; i++)
{
sendBufferDescr[i].address = (((uint32_t)&sendBuffers[i]) + 15 ) & ~(uint32_t)0xF;
sendBufferDescr[i].flags = 0x7FF
| 0xF000;
sendBufferDescr[i].flags2 = 0;
sendBufferDescr[i].avail = 0;
recvBufferDescr[i].address = (((uint32_t)&recvBuffers[i]) + 15 ) & ~(uint32_t)0xF;
recvBufferDescr[i].flags = 0xF7FF
| 0x80000000;
recvBufferDescr[i].flags2 = 0;
sendBufferDescr[i].avail = 0;
}
registerAddressPort.Write(1);
registerDataPort.Write( (uint32_t)(&initBlock) & 0xFFFF );
registerAddressPort.Write(2);
registerDataPort.Write( ((uint32_t)(&initBlock) >> 16) & 0xFFFF );
}
amd_am79c973::~amd_am79c973()
{
}
void amd_am79c973::Activate()
{
registerAddressPort.Write(0);
registerDataPort.Write(0x41);
registerAddressPort.Write(4);
uint32_t temp = registerDataPort.Read();
registerAddressPort.Write(4);
registerDataPort.Write(temp | 0xC00);
registerAddressPort.Write(0);
registerDataPort.Write(0x42);
}
int amd_am79c973::Reset()
{
resetPort.Read();
resetPort.Write(0);
return 10;
}
void printf(char*);
uint32_t amd_am79c973::HandleInterrupt(common::uint32_t esp)
{
printf("INTERRUPT FROM AMD am79c973\n");
registerAddressPort.Write(0);
uint32_t temp = registerDataPort.Read();
if((temp & 0x8000) == 0x8000) printf("AMD am79c973 ERROR\n");
if((temp & 0x2000) == 0x2000) printf("AMD am79c973 COLLISION ERROR\n");
if((temp & 0x1000) == 0x1000) printf("AMD am79c973 MISSED FRAME\n");
if((temp & 0x0800) == 0x0800) printf("AMD am79c973 MEMORY ERROR\n");
if((temp & 0x0400) == 0x0400) printf("AMD am79c973 DATA RECEVED\n");
if((temp & 0x0200) == 0x0200) printf("AMD am79c973 DATA SENT\n");
// acknoledge
registerAddressPort.Write(0);
registerDataPort.Write(temp);
if((temp & 0x0200) == 0x0200) printf("AMD am79c973 INIT DONE\n");
return esp;
}
@@ -1,4 +1,6 @@
#include <hardwarecommunication/pci.h>
#include <drivers/amd_am79c973.h>
using namespace myos::common;
using namespace myos::drivers;
using namespace myos::hardwarecommunication;
@@ -84,12 +86,12 @@ void PeripheralComponentInterconnectController::SelectDrivers(DriverManager* dri
BaseAddressRegister bar = GetBaseAddressRegister(bus, device, function, barNum);
if(bar.address && (bar.type == InputOutput))
dev.portBase = (uint32_t)bar.address;
Driver* driver = GetDriver(dev, interrupts);
if(driver != 0)
driverManager->AddDriver(driver);
}
Driver* driver = GetDriver(dev, interrupts);
if(driver != 0)
driverManager->AddDriver(driver);
printf("PCI BUS ");
printfHex(bus & 0xFF);
@@ -157,19 +159,18 @@ BaseAddressRegister PeripheralComponentInterconnectController::GetBaseAddressReg
Driver* PeripheralComponentInterconnectController::GetDriver(PeripheralComponentInterconnectDeviceDescriptor dev, InterruptManager* interrupts)
{
Driver *driver = 0;
Driver* driver = 0;
switch(dev.vendor_id)
{
case 0x1022: // AMD
switch(dev.device_id)
{
case 0x2000: // am79c973
/*
driver = (amd_am79c973*)MemoryManager::activeMemoryManager->malloc(sizeof(amd_am79c973));
if(driver != 0)
new (driver) amd_am79c973(...);
*/
new (driver) amd_am79c973(&dev, interrupts);
printf("AMD am79c973 ");
return driver;
break;
}
break;
View
@@ -69,6 +69,19 @@ void printfHex(uint8_t key)
foo[1] = hex[key & 0xF];
printf(foo);
}
void printfHex16(uint16_t key)
{
printfHex((key >> 8) & 0xFF);
printfHex( key & 0xFF);
}
void printfHex32(uint32_t key)
{
printfHex((key >> 24) & 0xFF);
printfHex((key >> 16) & 0xFF);
printfHex((key >> 8) & 0xFF);
printfHex( key & 0xFF);
}

0 comments on commit 7a49a16

Please sign in to comment.