|
Lines 76-81
__FBSDID("$FreeBSD$");
Link Here
|
| 76 |
|
76 |
|
| 77 |
#include <dev/ichwd/ichwd.h> |
77 |
#include <dev/ichwd/ichwd.h> |
| 78 |
|
78 |
|
|
|
79 |
#include <x86/pci_cfgreg.h> |
| 80 |
#include <dev/pci/pcivar.h> |
| 81 |
#include <dev/pci/pci_private.h> |
| 82 |
|
| 79 |
static struct ichwd_device ichwd_devices[] = { |
83 |
static struct ichwd_device ichwd_devices[] = { |
| 80 |
{ DEVICEID_82801AA, "Intel 82801AA watchdog timer", 1, 1 }, |
84 |
{ DEVICEID_82801AA, "Intel 82801AA watchdog timer", 1, 1 }, |
| 81 |
{ DEVICEID_82801AB, "Intel 82801AB watchdog timer", 1, 1 }, |
85 |
{ DEVICEID_82801AB, "Intel 82801AB watchdog timer", 1, 1 }, |
|
Lines 291-296
static struct ichwd_device ichwd_devices[] = {
Link Here
|
| 291 |
|
295 |
|
| 292 |
static struct ichwd_device ichwd_smb_devices[] = { |
296 |
static struct ichwd_device ichwd_smb_devices[] = { |
| 293 |
{ DEVICEID_LEWISBURG_SMB, "Lewisburg watchdog timer", 10, 4 }, |
297 |
{ DEVICEID_LEWISBURG_SMB, "Lewisburg watchdog timer", 10, 4 }, |
|
|
298 |
{ DEVICEID_SRPTLP_SMB, "Sunrise Point-LP watchdog timer", 10, 4 }, |
| 294 |
{ 0, NULL, 0, 0 }, |
299 |
{ 0, NULL, 0, 0 }, |
| 295 |
}; |
300 |
}; |
| 296 |
|
301 |
|
|
Lines 309-314
static devclass_t ichwd_devclass;
Link Here
|
| 309 |
/* NB: TCO version 3 devices use the gcs_res resource for the PMC register. */ |
314 |
/* NB: TCO version 3 devices use the gcs_res resource for the PMC register. */ |
| 310 |
#define ichwd_read_pmc_4(sc, off) \ |
315 |
#define ichwd_read_pmc_4(sc, off) \ |
| 311 |
bus_read_4((sc)->gcs_res, (off)) |
316 |
bus_read_4((sc)->gcs_res, (off)) |
|
|
317 |
#define ichwd_read_gc_4(sc, off) \ |
| 318 |
bus_read_4((sc)->gc_res, (off)) |
| 312 |
|
319 |
|
| 313 |
#define ichwd_write_tco_1(sc, off, val) \ |
320 |
#define ichwd_write_tco_1(sc, off, val) \ |
| 314 |
bus_write_1((sc)->tco_res, (off), (val)) |
321 |
bus_write_1((sc)->tco_res, (off), (val)) |
|
Lines 323-328
static devclass_t ichwd_devclass;
Link Here
|
| 323 |
/* NB: TCO version 3 devices use the gcs_res resource for the PMC register. */ |
330 |
/* NB: TCO version 3 devices use the gcs_res resource for the PMC register. */ |
| 324 |
#define ichwd_write_pmc_4(sc, off, val) \ |
331 |
#define ichwd_write_pmc_4(sc, off, val) \ |
| 325 |
bus_write_4((sc)->gcs_res, (off), (val)) |
332 |
bus_write_4((sc)->gcs_res, (off), (val)) |
|
|
333 |
#define ichwd_write_gc_4(sc, off, val) \ |
| 334 |
bus_write_4((sc)->gc_res, (off), (val)) |
| 326 |
|
335 |
|
| 327 |
#define ichwd_verbose_printf(dev, ...) \ |
336 |
#define ichwd_verbose_printf(dev, ...) \ |
| 328 |
do { \ |
337 |
do { \ |
|
Lines 495-503
ichwd_clear_noreboot(struct ichwd_softc *sc)
Link Here
|
| 495 |
rc = EIO; |
504 |
rc = EIO; |
| 496 |
break; |
505 |
break; |
| 497 |
case 4: |
506 |
case 4: |
| 498 |
/* |
507 |
status = ichwd_read_gc_4(sc, 0); |
| 499 |
* TODO. This needs access to a hidden PCI device at 31:1. |
508 |
status &= ~SMB_GC_NO_REBOOT; |
| 500 |
*/ |
509 |
ichwd_write_gc_4(sc, 0, status); |
|
|
510 |
status = ichwd_read_gc_4(sc, 0); |
| 511 |
if (status & SMB_GC_NO_REBOOT) |
| 512 |
rc = EIO; |
| 501 |
break; |
513 |
break; |
| 502 |
default: |
514 |
default: |
| 503 |
ichwd_verbose_printf(sc->device, |
515 |
ichwd_verbose_printf(sc->device, |
|
Lines 611-616
ichwd_identify(driver_t *driver, device_t parent)
Link Here
|
| 611 |
struct ichwd_device *id_p; |
623 |
struct ichwd_device *id_p; |
| 612 |
device_t ich, smb; |
624 |
device_t ich, smb; |
| 613 |
device_t dev; |
625 |
device_t dev; |
|
|
626 |
uint64_t base_address64; |
| 614 |
uint32_t base_address; |
627 |
uint32_t base_address; |
| 615 |
uint32_t ctl; |
628 |
uint32_t ctl; |
| 616 |
int rc; |
629 |
int rc; |
|
Lines 671-676
ichwd_identify(driver_t *driver, device_t parent)
Link Here
|
| 671 |
"Can not set TCO v%d I/O resource (err = %d)\n", |
684 |
"Can not set TCO v%d I/O resource (err = %d)\n", |
| 672 |
id_p->tco_version, rc); |
685 |
id_p->tco_version, rc); |
| 673 |
} |
686 |
} |
|
|
687 |
|
| 688 |
/* |
| 689 |
* Unhide Primary to Sideband Bridge (P2SB) PCI device, so that |
| 690 |
* we can discover the base address of Private Configuration |
| 691 |
* Space via the bridge's BAR. |
| 692 |
* Then hide back the bridge. |
| 693 |
*/ |
| 694 |
pci_cfgregwrite(0, 31, 1, 0xe1, 0, 1); |
| 695 |
base_address64 = pci_cfgregread(0, 31, 1, SBREG_BAR + 4, 4); |
| 696 |
base_address64 <<= 32; |
| 697 |
base_address64 |= pci_cfgregread(0, 31, 1, SBREG_BAR + 4, 4); |
| 698 |
base_address64 &= ~0xfull; |
| 699 |
pci_cfgregwrite(0, 31, 1, 0xe1, 1, 1); |
| 700 |
|
| 701 |
/* |
| 702 |
* No Reboot bit is in General Control register, offset 0xc, |
| 703 |
* within the SMBus target port, ID 0xc6. |
| 704 |
*/ |
| 705 |
base_address64 += PCR_REG_OFF(SMB_PORT_ID, SMB_GC_REG); |
| 706 |
rc = bus_set_resource(dev, SYS_RES_MEMORY, 1, base_address64, |
| 707 |
SMB_GC_SIZE); |
| 708 |
if (rc != 0) { |
| 709 |
ichwd_verbose_printf(dev, |
| 710 |
"Can not set TCO v%d PCR I/O resource (err = %d)\n", |
| 711 |
id_p->tco_version, rc); |
| 712 |
} |
| 713 |
|
| 674 |
break; |
714 |
break; |
| 675 |
default: |
715 |
default: |
| 676 |
ichwd_verbose_printf(dev, |
716 |
ichwd_verbose_printf(dev, |
|
Lines 723-728
ichwd_smb_attach(device_t dev)
Link Here
|
| 723 |
return (ENXIO); |
763 |
return (ENXIO); |
| 724 |
} |
764 |
} |
| 725 |
|
765 |
|
|
|
766 |
/* |
| 767 |
* Allocate General Control I/O register in PCH |
| 768 |
* Private Configuration Space (PCR). |
| 769 |
*/ |
| 770 |
sc->gc_rid = 1; |
| 771 |
sc->gc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->gc_rid, |
| 772 |
RF_ACTIVE | RF_SHAREABLE); |
| 773 |
if (sc->gc_res == NULL) { |
| 774 |
device_printf(dev, "unable to reserve hidden P2SB registers\n"); |
| 775 |
return (ENXIO); |
| 776 |
} |
| 777 |
|
| 726 |
/* Get ACPI base address. */ |
778 |
/* Get ACPI base address. */ |
| 727 |
isab = device_get_parent(device_get_parent(dev)); |
779 |
isab = device_get_parent(device_get_parent(dev)); |
| 728 |
pmdev = pci_find_dbsf(pci_get_domain(isab), pci_get_bus(isab), 31, 2); |
780 |
pmdev = pci_find_dbsf(pci_get_domain(isab), pci_get_bus(isab), 31, 2); |
|
Lines 737-743
ichwd_smb_attach(device_t dev)
Link Here
|
| 737 |
} |
789 |
} |
| 738 |
|
790 |
|
| 739 |
/* Allocate SMI control I/O register space. */ |
791 |
/* Allocate SMI control I/O register space. */ |
| 740 |
sc->smi_rid = 1; |
792 |
sc->smi_rid = 2; |
| 741 |
sc->smi_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->smi_rid, |
793 |
sc->smi_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->smi_rid, |
| 742 |
acpi_base + SMI_BASE, acpi_base + SMI_BASE + SMI_LEN - 1, SMI_LEN, |
794 |
acpi_base + SMI_BASE, acpi_base + SMI_BASE + SMI_LEN - 1, SMI_LEN, |
| 743 |
RF_ACTIVE | RF_SHAREABLE); |
795 |
RF_ACTIVE | RF_SHAREABLE); |
|
Lines 854-859
ichwd_attach(device_t dev)
Link Here
|
| 854 |
if (sc->gcs_res != NULL) |
906 |
if (sc->gcs_res != NULL) |
| 855 |
bus_release_resource(sc->ich, SYS_RES_MEMORY, |
907 |
bus_release_resource(sc->ich, SYS_RES_MEMORY, |
| 856 |
sc->gcs_rid, sc->gcs_res); |
908 |
sc->gcs_rid, sc->gcs_res); |
|
|
909 |
if (sc->gc_res != NULL) |
| 910 |
bus_release_resource(dev, SYS_RES_MEMORY, |
| 911 |
sc->gc_rid, sc->gc_res); |
| 857 |
|
912 |
|
| 858 |
return (ENXIO); |
913 |
return (ENXIO); |
| 859 |
} |
914 |
} |
|
Lines 889-894
ichwd_detach(device_t dev)
Link Here
|
| 889 |
if (sc->gcs_res) |
944 |
if (sc->gcs_res) |
| 890 |
bus_release_resource(sc->ich, SYS_RES_MEMORY, sc->gcs_rid, |
945 |
bus_release_resource(sc->ich, SYS_RES_MEMORY, sc->gcs_rid, |
| 891 |
sc->gcs_res); |
946 |
sc->gcs_res); |
|
|
947 |
if (sc->gc_res) |
| 948 |
bus_release_resource(dev, SYS_RES_MEMORY, sc->gc_rid, |
| 949 |
sc->gc_res); |
| 892 |
|
950 |
|
| 893 |
return (0); |
951 |
return (0); |
| 894 |
} |
952 |
} |