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); |
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 |
} |