From: Jacob Potter Date: Thu, 2 Oct 2008 22:43:35 +0000 (-0400) Subject: Merge branch 'master' of nyus:/storage/git/netwatch X-Git-Url: http://git.joshuawise.com/netwatch.git/commitdiff_plain/3309f0f4c6885cc382fb6fa77493ae68bd4eb5b0?hp=644af6b41a9ecbefecb70ec4cca307974e1300c4 Merge branch 'master' of nyus:/storage/git/netwatch --- diff --git a/aseg/3c905.c b/aseg/3c905.c new file mode 100644 index 0000000..b89abe2 --- /dev/null +++ b/aseg/3c905.c @@ -0,0 +1,36 @@ +#include +#include +#include "3c905.h" + +static int found = 0, _bus, _dev, _fn; + +static int bother_3c905(pci_dev_t *dev, void *nutrinus) +{ + if (dev->vid == 0x10B7 || dev->did == 0x9200) + { + outputf("Found a 3c905 to bother"); + + _bus = dev->bus; + _dev = dev->dev; + _fn = dev->fn; + found = 1; + + return 1; + } + return 0; +} + +void eth_poll() +{ + if (!found) + return; + + pci_write16(_bus, _dev, _fn, 0x04, 0xFF); + + pci_write16(_bus, _dev, _fn, 0x04, 0x00); +} + +void eth_init() +{ + pci_probe(bother_3c905, 0x0); +} diff --git a/aseg/3c905.h b/aseg/3c905.h new file mode 100644 index 0000000..708069b --- /dev/null +++ b/aseg/3c905.h @@ -0,0 +1,7 @@ +#ifndef _3C905_H +#define _3C905_H + +extern void eth_init(); +extern void eth_poll(); + +#endif diff --git a/aseg/Makefile b/aseg/Makefile index c5f33f4..8283648 100644 --- a/aseg/Makefile +++ b/aseg/Makefile @@ -1,6 +1,6 @@ CC=gcc CFLAGS=-I../include -I../include/raw -nostdlib -nostdinc -fno-builtin -D__RAW__ -Wall -Werror -pedantic -ansi -std=gnu99 -OBJS=counter.o firstrun.o ../pci/pci-raw.o ../lib/minilib.o ../lib/console.o ../ich2/smram-ich2.o ../ich2/smi.o vga-overlay.o packet.o ../lib/sprintf.o ../lib/doprnt.o ../pci/pci.o +OBJS=counter.o firstrun.o ../pci/pci-raw.o ../lib/minilib.o ../lib/console.o ../ich2/smram-ich2.o ../ich2/smi.o vga-overlay.o packet.o ../lib/sprintf.o ../lib/doprnt.o ../pci/pci.o 3c905.o all: aseg.elf diff --git a/aseg/counter.c b/aseg/counter.c index 5c88850..eaeec52 100644 --- a/aseg/counter.c +++ b/aseg/counter.c @@ -3,6 +3,7 @@ #include #include #include +#include "3c905.h" #include "vga-overlay.h" #include "packet.h" @@ -100,8 +101,7 @@ void smi_entry(void) sprintf(statstr, "15-412! %08x %08x", smi_status(), counter); strblit(statstr, 0, 0); - extern void do_bother(); - do_bother(); + eth_poll(); if (inl(0x840) & 0x1000) { diff --git a/aseg/firstrun.c b/aseg/firstrun.c index 75bcccc..d45bc81 100644 --- a/aseg/firstrun.c +++ b/aseg/firstrun.c @@ -5,6 +5,7 @@ #include #include "vga-overlay.h" #include +#include "3c905.h" extern int _bss, _bssend; @@ -12,38 +13,6 @@ extern void timer_handler(smi_event_t ev); extern void kbc_handler(smi_event_t ev); extern void gbl_rls_handler(smi_event_t ev); -static int found = 0, _bus, _dev, _fn; - -void do_bother() -{ - int bar; - - if (!found) - return; - - pci_write16(_bus, _dev, _fn, 0x04, 0x00); - for (bar = 0; bar < 6; bar++) - pci_write32(_bus, _dev, _fn, 0x10 + bar*4, 0x1FFFFFFF); -} - -int bother_3c905(pci_dev_t *dev) -{ - if (dev->vid == 0x10B7 || dev->did == 0x9200) - { - outputf("Found a 3c905 to bother"); - - _bus = dev->bus; - _dev = dev->dev; - _fn = dev->fn; - found = 1; - - do_bother(); - - return 1; - } - return 0; -} - void __firstrun_start() { unsigned char *bp; smram_state_t smram; @@ -65,7 +34,7 @@ void __firstrun_start() { /* Turn on the SMIs we want */ smi_disable(); - pci_probe(bother_3c905); + eth_init(); smi_register_handler(SMI_EVENT_FAST_TIMER, timer_handler); smi_enable_event(SMI_EVENT_FAST_TIMER); diff --git a/include/pci.h b/include/pci.h index 313b3e0..9f7e6b9 100644 --- a/include/pci.h +++ b/include/pci.h @@ -36,9 +36,25 @@ typedef struct pci_dev { pci_bar_t bars[6]; } pci_dev_t; -typedef int (*pci_probe_fn_t)(pci_dev_t *); +typedef int (*pci_probe_fn_t)(pci_dev_t *, void *data); void pci_bus_enum(); -int pci_probe(pci_probe_fn_t probe); +int pci_probe(pci_probe_fn_t probe, void *data); + +typedef struct pci_id { + unsigned short vid, did; + const char *name, *friendlyname; +} pci_id_t; + +#define PCI_ROM(a,b,c,d) {(a),(b),(c),(d)} + +typedef struct pci_driver { + const char *name; + pci_probe_fn_t probe; + pci_id_t *ids; + int id_count; +} pci_driver_t; + +int pci_probe_driver(pci_driver_t driver); #endif diff --git a/lib/minilib.c b/lib/minilib.c index 0e5786e..677c77a 100644 --- a/lib/minilib.c +++ b/lib/minilib.c @@ -3,8 +3,8 @@ void memcpy(void *dest, const void *src, int bytes) { - char * cdest = dest; - char * csrc = src; + char *cdest = dest; + const char *csrc = src; while (bytes--) *(cdest++) = *(csrc++); } diff --git a/pci/pci.c b/pci/pci.c index e5ab816..c7385de 100644 --- a/pci/pci.c +++ b/pci/pci.c @@ -1,7 +1,7 @@ #include #include -int pci_probe(pci_probe_fn_t probe) +int pci_probe(pci_probe_fn_t probe, void *data) { int devsfound = 0; pci_dev_t pdev; @@ -11,62 +11,65 @@ int pci_probe(pci_probe_fn_t probe) for (bus = 0; bus < 0x100; bus++) for (dev = 0; dev < 0x20; dev++) - if (pci_read32(bus, dev, 0, 0) != 0xFFFFFFFF) - for (fn = 0; fn < 8; fn++) + { + if (pci_read32(bus, dev, 0, 0) == 0xFFFFFFFF) + continue; + for (fn = 0; fn < 8; fn++) + { + int bar; + + if (pci_read32(bus, dev, fn, 0) == 0xFFFFFFFF) + continue; + + if ((fn != 0) && !(pci_read8(bus, dev, 0, 0x0E) & 0x80)) + continue; + + pdev.bus = bus; + pdev.dev = dev; + pdev.fn = fn; + pdev.vid = pci_read16(bus, dev, fn, 0); + pdev.did = pci_read16(bus, dev, fn, 2); + + for (bar = 0; bar < 6; bar++) { - int bar; - - if (pci_read32(bus, dev, fn, 0) == 0xFFFFFFFF) - continue; - - if ((fn != 0) && !(pci_read8(bus, dev, 0, 0x0E) & 0x80)) + unsigned long bardat = pci_read32(bus, dev, fn, 0x10 + bar*4); + if (bardat == 0) + { + pdev.bars[bar].type = PCI_BAR_NONE; continue; - - pdev.bus = bus; - pdev.dev = dev; - pdev.fn = fn; - pdev.vid = pci_read16(bus, dev, fn, 0); - pdev.did = pci_read16(bus, dev, fn, 2); - - for (bar = 0; bar < 6; bar++) + } + if (bardat & 1) { - unsigned long bardat = pci_read32(bus, dev, fn, 0x10 + bar*4); - if (bardat == 0) + pdev.bars[bar].type = PCI_BAR_IO; + pdev.bars[bar].addr = bardat & ~0x3; + } else { + pdev.bars[bar].prefetchable = (bardat >> 3) & 1; + switch ((bardat >> 1) & 0x3) { + case 0: + pdev.bars[bar].type = PCI_BAR_MEMORY32; + pdev.bars[bar].addr = bardat & ~0xF; + break; + case 2: + pdev.bars[bar].type = PCI_BAR_MEMORY64; + bar++; + pdev.bars[bar].type = PCI_BAR_NONE; + break; + default: pdev.bars[bar].type = PCI_BAR_NONE; continue; } - if (bardat & 1) - { - pdev.bars[bar].type = PCI_BAR_IO; - pdev.bars[bar].addr = bardat & ~0x3; - } else { - pdev.bars[bar].prefetchable = (bardat >> 3) & 1; - switch ((bardat >> 1) & 0x3) - { - case 0: - pdev.bars[bar].type = PCI_BAR_MEMORY32; - pdev.bars[bar].addr = bardat & ~0xF; - break; - case 2: - pdev.bars[bar].type = PCI_BAR_MEMORY64; - bar++; - pdev.bars[bar].type = PCI_BAR_NONE; - break; - default: - pdev.bars[bar].type = PCI_BAR_NONE; - continue; - } - } } - - devsfound += probe(&pdev); } + + devsfound += probe(&pdev, data); + } + } return devsfound; } -static int _enumfn(pci_dev_t *pdev) +static int _enumfn(pci_dev_t *pdev, void *data) { int bar; @@ -95,6 +98,24 @@ static int _enumfn(pci_dev_t *pdev) void pci_bus_enum() { - pci_probe(_enumfn); + pci_probe(_enumfn, 0x0); } +static int _probefn(pci_dev_t *dev, void *d) +{ + pci_driver_t *driver = d; + int i; + + for (i = 0; i < driver->id_count; i++) + if ((dev->vid == driver->ids[i].vid) && (dev->did == driver->ids[i].did)) + { + outputf("Probing PCI device: %s (%s)", driver->ids[i].name ? driver->ids[i].name : driver->name, driver->ids[i].friendlyname ? driver->ids[i].friendlyname : "no friendly name"); + return driver->probe(dev, d); + } + return 0; +} + +int pci_probe_driver(pci_driver_t driver) +{ + return pci_probe(_probefn, &driver); +}