Merge branch 'master' of ssh://review.rcs.uwaterloo.ca:77/source/metal-cos

This commit is contained in:
quackerd 2023-12-01 05:29:21 +08:00
commit 0b23e00dad
6 changed files with 75 additions and 23 deletions

View File

@ -1,12 +1,14 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <syscall.h>
#include <sys/nic.h>
#include <net/ethernet.h>
static int nicNo = 1;
static int nicNo = 0;
static char buf[4096];
static MBuf mbuf;
@ -61,6 +63,10 @@ main(int argc, const char *argv[])
printf("Ethernet Dump Tool\n");
if (argc == 2) {
nicNo = atoi(argv[1]);
}
status = OSNICStat(nicNo, &nic);
if (status == ENOENT) {
printf("nic%d not present\n", nicNo);

View File

@ -24,6 +24,8 @@ typedef struct E1000Device
static E1000Device deviceList[] =
{
{ 0x8086100e, "E1000", 0 }, // EERD is not supported
{ 0x808610c9, "IGB", 0 },
{ 0x808610d3, "E1000E", 0 },
// { 0x80861209, "i82551", 0 }, // Doesn't seem to work on my qemu build
{ 0, "", 0 },
};
@ -62,6 +64,22 @@ void E1000_Configure(PCIDevice dev);
#define E1000_REG_MTABASE 0x5200
#define E1000_REG_RAL 0x5400
#define E1000_REG_RAH 0x5404
// EEPROM Control and Data Register
#define EE_SK (1 << 0)
#define EE_CS (1 << 1)
#define EE_DI (1 << 2)
#define EE_DO (1 << 3)
// FWE (Flash Write Enable) 5:4
#define EE_REQ (1 << 6)
#define EE_GNT (1 << 7)
#define EE_PRES (1 << 8)
#define EE_SIZE (1 << 9)
#define EE_SIZE2 (1 << 10)
#define EE_TYPE (1 << 13)
// EEPROM Offsets
#define NVM_MAC_ADDR 0x0000
#define NVM_DEVICE_ID 0x000D
@ -180,7 +198,7 @@ E1000_Init(uint32_t bus, uint32_t slot, uint32_t func)
int deviceIdx = 0;
while (deviceList[deviceIdx].device != 0x0) {
if (deviceList[deviceIdx].device == device) {
kprintf("E1000: Found %s\n", deviceList[deviceIdx].name);
Log(e1000, "Found %s\n", deviceList[deviceIdx].name);
// Configure and add disks
E1000_Configure(dev);
}
@ -198,7 +216,7 @@ MMIO_Read32(E1000Dev *dev, uint64_t addr)
static inline void
MMIO_Write32(E1000Dev *dev, uint64_t addr, uint32_t val)
{
*(uint32_t *)(dev->mmiobase + addr) = val;
*(uint32_t volatile *)(dev->mmiobase + addr) = val;
}
static uint16_t
@ -206,6 +224,13 @@ E1000_EEPROM_Read(E1000Dev *dev, uint8_t addr)
{
uint16_t val;
uint32_t eecd = MMIO_Read32(dev, E1000_REG_EECD);
MMIO_Write32(dev, E1000_REG_EECD, eecd & ~(EE_REQ|EE_GNT));
if (!(eecd & EE_PRES)) {
DLOG(e1000, "EEPROM Not Present!\n");
return 0;
}
// Write Address
MMIO_Write32(dev, E1000_REG_EERD, ((uint32_t)addr << 8) | 1);
@ -216,7 +241,7 @@ E1000_EEPROM_Read(E1000Dev *dev, uint8_t addr)
break;
}
kprintf("%08x\n", val);
DLOG(e1000, "EEPROM 0x%02x = %08x\n", addr, val);
return (uint16_t)((val >> 16) & 0x0000FFFF);
}
@ -225,7 +250,7 @@ void
E1000_TXPoll(E1000Dev *dev)
{
// Free memory
kprintf("TXPOLL\n");
Log(e1000, "TXPOLL\n");
}
void
@ -249,8 +274,8 @@ E1000_RXPoll(E1000Dev *dev)
}
if (dev->rxDesc[dev->rxTail].errors) {
kprintf("E1000: Error in RX Queue %x\n",
dev->rxDesc[dev->rxTail].errors);
Alert(e1000, "Error in RX Queue %x\n",
dev->rxDesc[dev->rxTail].errors);
dev->rxDesc[dev->rxTail].status = 0;
dev->rxDesc[dev->rxTail].errors = 0;
MMIO_Write32(dev, E1000_REG_RDT, dev->rxTail);
@ -272,8 +297,8 @@ E1000_Interrupt(void *arg)
{
E1000Dev *dev = (E1000Dev *)arg;
kprintf("E1000 (%d:%d) Interrupt\n",
dev->dev.bus, dev->dev.slot);
DLOG(e1000, "Interrupt (%d:%d)\n",
dev->dev.bus, dev->dev.slot);
uint32_t cause = MMIO_Read32(dev, E1000_REG_ICR);
@ -292,7 +317,7 @@ E1000_Interrupt(void *arg)
// Receive Overrun
if (cause & ICR_RXO) {
cause &= ~ICR_RXO;
kprintf("underrun %u %u\n", MMIO_Read32(dev, E1000_REG_RDH), dev->rxTail);
DLOG(e1000, "underrun %u %u\n", MMIO_Read32(dev, E1000_REG_RDH), dev->rxTail);
E1000_RXPoll(dev);
}
@ -304,7 +329,7 @@ E1000_Interrupt(void *arg)
}
if (cause != 0) {
kprintf("E1000: Unhandled cause %08x\n", cause);
Alert(e1000, "Unhandled cause %08x\n", cause);
}
MMIO_Read32(dev, E1000_REG_ICR);
@ -460,9 +485,9 @@ E1000_Configure(PCIDevice dev)
if (dev.bars[bar].size == 0)
continue;
kprintf("E1000: BAR%d base=%08x size=%08x %s\n",
bar, dev.bars[bar].base, dev.bars[bar].size,
dev.bars[bar].type == PCIBAR_TYPE_IO ? "IO" : "Mem");
Log(e1000, "BAR%d base=%08x size=%08x %s\n",
bar, dev.bars[bar].base, dev.bars[bar].size,
dev.bars[bar].type == PCIBAR_TYPE_IO ? "IO" : "Mem");
}
ethDev->mmiobase = (uint8_t *)DMPA2VA(dev.bars[0].base);
@ -471,16 +496,31 @@ E1000_Configure(PCIDevice dev)
MMIO_Write32(ethDev, E1000_REG_CTRL, MMIO_Read32(ethDev, E1000_REG_CTRL) | CTRL_SLU);
// Register IRQs
kprintf("E1000: IRQ %d\n", dev.irq);
Log(e1000, "IRQ %d\n", dev.irq);
ethDev->irqHandle.irq = dev.irq;
ethDev->irqHandle.cb = &E1000_Interrupt;
ethDev->irqHandle.arg = ethDev;
IRQ_Register(dev.irq, &ethDev->irqHandle);
kprintf("E1000: MAC XX:XX:XX:XX:XX:XX\n");
// EEPROM's are really supported on Qemu or Virtualbox
for (int i = 0; i < 3; i++) {
E1000_EEPROM_Read(ethDev, NVM_MAC_ADDR + 2*i);
}
uint32_t ral = MMIO_Read32(ethDev, E1000_REG_RAL);
uint32_t rah = MMIO_Read32(ethDev, E1000_REG_RAH);
ethDev->nic.mac[0] = ral & 0xff;
ethDev->nic.mac[1] = (ral >> 8) & 0xff;
ethDev->nic.mac[2] = (ral >> 16) & 0xff;
ethDev->nic.mac[3] = (ral >> 24) & 0xff;
ethDev->nic.mac[4] = rah & 0xff;
ethDev->nic.mac[5] = (rah >> 8) & 0xff;
Log(e1000, "MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
ethDev->nic.mac[0], ethDev->nic.mac[1],
ethDev->nic.mac[2], ethDev->nic.mac[3],
ethDev->nic.mac[4], ethDev->nic.mac[5]);
// Device lock
Spinlock_Init(&ethDev->lock, "E1000 Spinlock", SPINLOCK_TYPE_NORMAL);

View File

@ -397,7 +397,8 @@ Debug_PCIDump(int argc, const char *argv[])
uint32_t bar;
if (argc != 4) {
kprintf("Requires 3 arguments!\n");
kprintf("pcidump requires 3 arguments!\n");
kprintf("Usage: pcidump <bus> <device> <func>\n");
return;
}
@ -409,6 +410,7 @@ Debug_PCIDump(int argc, const char *argv[])
kprintf("Device ID: %04x\n", PCIGetDeviceID(bus, device, func));
kprintf("Class: %d\n", PCIGetBaseClass(bus, device, func));
kprintf("Subclass: %d\n", PCIGetSubClass(bus, device, func));
kprintf("ProgIf: %02x\n", PCICfgRead8(bus, device, func, PCI_OFFSET_PROGIF));
kprintf("Header Type: %d\n", PCIGetHeaderType(bus, device, func));
for (bar = 0; bar < PCI_MAX_BARS; bar++)

View File

@ -24,11 +24,12 @@
SYSCTL_STR(kern_ostype, SYSCTL_FLAG_RO, "OS Type", "Castor") \
SYSCTL_INT(kern_hz, SYSCTL_FLAG_RW, "Tick frequency", 100) \
SYSCTL_INT(time_tzadj, SYSCTL_FLAG_RW, "Time zone offset in seconds", 0) \
SYSCTL_INT(log_syscall, SYSCTL_FLAG_RW, "Syscall log level", 0) \
SYSCTL_INT(log_e1000, SYSCTL_FLAG_RW, "E1000 log level", 10) \
SYSCTL_INT(log_ide, SYSCTL_FLAG_RW, "IDE log level", 0) \
SYSCTL_INT(log_loader, SYSCTL_FLAG_RW, "Loader log level", 0) \
SYSCTL_INT(log_vfs, SYSCTL_FLAG_RW, "VFS log level", 0) \
SYSCTL_INT(log_o2fs, SYSCTL_FLAG_RW, "O2FS log level", 0) \
SYSCTL_INT(log_ide, SYSCTL_FLAG_RW, "IDE log level", 0)
SYSCTL_INT(log_syscall, SYSCTL_FLAG_RW, "Syscall log level", 0) \
SYSCTL_INT(log_vfs, SYSCTL_FLAG_RW, "VFS log level", 0)
#define SYSCTL_STR_MAXLENGTH 128

View File

@ -208,7 +208,8 @@ Debug_Dump(int argc, const char *argv[])
if (argc != 3)
{
kprintf("Dump requires 3 arguments\n");
kprintf("dump requires 2 arguments!\n");
kprintf("Usage: dump <off> <len>\n");
return;
}
@ -227,7 +228,8 @@ Debug_Disasm(int argc, const char *argv[])
int len = 1;
if (argc != 2 && argc != 3) {
kprintf("Disasm requires 2 or 3 arguments\n");
kprintf("disasm requires 1 or 2 arguments!\n");
kprintf("Usage: disasm <off> [<len>]\n");
return;
}

View File

@ -80,7 +80,8 @@ Debug_DumpDisk(int argc, const char *argv[])
SGArray sga;
if (argc != 4) {
kprintf("dumpdisk requires 4 arguments!\n");
kprintf("dumpdisk requires 3 arguments\n");
kprintf("Usage: dumpdisk <ctrl> <disk> <sector>\n");
return;
}