|
Lines 74-79
__FBSDID("$FreeBSD: stable/11/sys/dev/ic
Link Here
|
| 74 |
|
74 |
|
| 75 |
#include <dev/ichwd/ichwd.h> |
75 |
#include <dev/ichwd/ichwd.h> |
| 76 |
|
76 |
|
|
|
77 |
#include <x86/pci_cfgreg.h> |
| 78 |
#include <dev/pci/pcivar.h> |
| 79 |
#include <dev/pci/pci_private.h> |
| 80 |
|
| 77 |
static struct ichwd_device ichwd_devices[] = { |
81 |
static struct ichwd_device ichwd_devices[] = { |
| 78 |
{ DEVICEID_82801AA, "Intel 82801AA watchdog timer", 1, 1 }, |
82 |
{ DEVICEID_82801AA, "Intel 82801AA watchdog timer", 1, 1 }, |
| 79 |
{ DEVICEID_82801AB, "Intel 82801AB watchdog timer", 1, 1 }, |
83 |
{ DEVICEID_82801AB, "Intel 82801AB watchdog timer", 1, 1 }, |
|
Lines 308-313
static devclass_t ichwd_devclass;
Link Here
|
| 308 |
/* NB: TCO version 3 devices use the gcs_res resource for the PMC register. */ |
312 |
/* NB: TCO version 3 devices use the gcs_res resource for the PMC register. */ |
| 309 |
#define ichwd_read_pmc_4(sc, off) \ |
313 |
#define ichwd_read_pmc_4(sc, off) \ |
| 310 |
bus_read_4((sc)->gcs_res, (off)) |
314 |
bus_read_4((sc)->gcs_res, (off)) |
|
|
315 |
#define ichwd_read_p2sb_4(sc, off) \ |
| 316 |
bus_read_4((sc)->p2sb_res, (off)) |
| 311 |
|
317 |
|
| 312 |
#define ichwd_write_tco_1(sc, off, val) \ |
318 |
#define ichwd_write_tco_1(sc, off, val) \ |
| 313 |
bus_write_1((sc)->tco_res, (off), (val)) |
319 |
bus_write_1((sc)->tco_res, (off), (val)) |
|
Lines 322-327
static devclass_t ichwd_devclass;
Link Here
|
| 322 |
/* NB: TCO version 3 devices use the gcs_res resource for the PMC register. */ |
328 |
/* NB: TCO version 3 devices use the gcs_res resource for the PMC register. */ |
| 323 |
#define ichwd_write_pmc_4(sc, off, val) \ |
329 |
#define ichwd_write_pmc_4(sc, off, val) \ |
| 324 |
bus_write_4((sc)->gcs_res, (off), (val)) |
330 |
bus_write_4((sc)->gcs_res, (off), (val)) |
|
|
331 |
#define ichwd_write_p2sb_4(sc, off, val) \ |
| 332 |
bus_write_4((sc)->p2sb_res, (off), (val)) |
| 325 |
|
333 |
|
| 326 |
#define ichwd_verbose_printf(dev, ...) \ |
334 |
#define ichwd_verbose_printf(dev, ...) \ |
| 327 |
do { \ |
335 |
do { \ |
|
Lines 494-502
ichwd_clear_noreboot(struct ichwd_softc
Link Here
|
| 494 |
rc = EIO; |
502 |
rc = EIO; |
| 495 |
break; |
503 |
break; |
| 496 |
case 4: |
504 |
case 4: |
| 497 |
/* |
505 |
status = ichwd_read_p2sb_4(sc, 0); |
| 498 |
* TODO. This needs access to a hidden PCI device at 31:1. |
506 |
status &= ~ICH_GEN_STA_NO_REBOOT; |
| 499 |
*/ |
507 |
ichwd_write_p2sb_4(sc, 0, status); |
|
|
508 |
status = ichwd_read_p2sb_4(sc, 0); |
| 509 |
if (status & ICH_GEN_STA_NO_REBOOT) |
| 510 |
rc = EIO; |
| 500 |
break; |
511 |
break; |
| 501 |
default: |
512 |
default: |
| 502 |
ichwd_verbose_printf(sc->device, |
513 |
ichwd_verbose_printf(sc->device, |
|
Lines 705-710
ichwd_smb_attach(device_t dev)
Link Here
|
| 705 |
device_t smb; |
716 |
device_t smb; |
| 706 |
uint32_t acpi_base; |
717 |
uint32_t acpi_base; |
| 707 |
|
718 |
|
|
|
719 |
u_int32_t cfg[2]; |
| 720 |
u_int64_t p2sb; |
| 721 |
|
| 708 |
sc = device_get_softc(dev); |
722 |
sc = device_get_softc(dev); |
| 709 |
smb = ichwd_find_smb_dev(device_get_parent(dev), &id_p); |
723 |
smb = ichwd_find_smb_dev(device_get_parent(dev), &id_p); |
| 710 |
if (smb == NULL) |
724 |
if (smb == NULL) |
|
Lines 745-750
ichwd_smb_attach(device_t dev)
Link Here
|
| 745 |
return (ENXIO); |
759 |
return (ENXIO); |
| 746 |
} |
760 |
} |
| 747 |
|
761 |
|
|
|
762 |
/* Unhide and enumerate p2sb device. */ |
| 763 |
pci_cfgregwrite(0, 31, 1, 0xe1, 0, 1); |
| 764 |
if ((sc->p2sb = pci_find_dbsf(0, 0, 31, 1)) == NULL) { |
| 765 |
device_t bus = device_get_parent(smb); |
| 766 |
struct pci_devinfo *dinfo = pci_read_device( |
| 767 |
device_get_parent(bus), bus, 0, 0, 31, 1); |
| 768 |
pci_add_child(bus, dinfo); |
| 769 |
if ((sc->p2sb = pci_find_dbsf(0, 0, 31, 1)) == NULL) |
| 770 |
return (ENXIO); |
| 771 |
} |
| 772 |
/* Get the 64 bit base address and hide the device again. */ |
| 773 |
cfg[0] = pci_cfgregread(0, 31, 1, 0x10, 4); |
| 774 |
cfg[1] = pci_cfgregread(0, 31, 1, 0x10 + 4, 4); |
| 775 |
pci_cfgregwrite(0, 31, 1, 0xe1, 1, 1); |
| 776 |
p2sb = cfg[0] & 0xfffffff0; |
| 777 |
p2sb |= (u_int64_t) cfg[1] << 32; |
| 778 |
|
| 779 |
/* Map the address. */ |
| 780 |
sc->p2sb_rid = 0x10; |
| 781 |
sc->p2sb_res = bus_alloc_resource( |
| 782 |
sc->p2sb, SYS_RES_MEMORY, &sc->p2sb_rid, |
| 783 |
p2sb + 0xc6000c, p2sb + 0xc6000c + 3, 4, |
| 784 |
RF_ACTIVE|RF_SHAREABLE); |
| 785 |
if (sc->p2sb_res == NULL) { |
| 786 |
device_printf(dev, "unable to reserve hidden P2SB registers\n"); |
| 787 |
return (ENXIO); |
| 788 |
} |
| 789 |
|
| 748 |
return (0); |
790 |
return (0); |
| 749 |
} |
791 |
} |
| 750 |
|
792 |
|
|
Lines 853-858
ichwd_attach(device_t dev)
Link Here
|
| 853 |
if (sc->gcs_res != NULL) |
895 |
if (sc->gcs_res != NULL) |
| 854 |
bus_release_resource(sc->ich, SYS_RES_MEMORY, |
896 |
bus_release_resource(sc->ich, SYS_RES_MEMORY, |
| 855 |
sc->gcs_rid, sc->gcs_res); |
897 |
sc->gcs_rid, sc->gcs_res); |
|
|
898 |
if (sc->p2sb_res != NULL) |
| 899 |
bus_release_resource(sc->p2sb, SYS_RES_MEMORY, |
| 900 |
sc->p2sb_rid, sc->p2sb_res); |
| 856 |
|
901 |
|
| 857 |
return (ENXIO); |
902 |
return (ENXIO); |
| 858 |
} |
903 |
} |
|
Lines 888-893
ichwd_detach(device_t dev)
Link Here
|
| 888 |
if (sc->gcs_res) |
933 |
if (sc->gcs_res) |
| 889 |
bus_release_resource(sc->ich, SYS_RES_MEMORY, sc->gcs_rid, |
934 |
bus_release_resource(sc->ich, SYS_RES_MEMORY, sc->gcs_rid, |
| 890 |
sc->gcs_res); |
935 |
sc->gcs_res); |
|
|
936 |
if (sc->p2sb_res) |
| 937 |
bus_release_resource(sc->p2sb, SYS_RES_MEMORY, sc->p2sb_rid, |
| 938 |
sc->p2sb_res); |
| 891 |
|
939 |
|
| 892 |
return (0); |
940 |
return (0); |
| 893 |
} |
941 |
} |