From mpi@openbsd.org Tue May 26 21:27:23 2015 Delivered-To: david@gwynne.id.au Received: by 10.194.186.241 with SMTP id fn17csp2096473wjc; Tue, 26 May 2015 04:27:23 -0700 (PDT) X-Received: by 10.70.101.168 with SMTP id fh8mr11156455pdb.15.1432639643374; Tue, 26 May 2015 04:27:23 -0700 (PDT) Return-Path: Received: from cvs.openbsd.org (cvs.openbsd.org. [199.185.137.3]) by mx.google.com with ESMTPS id zq5si20499720pbc.109.2015.05.26.04.27.22 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 26 May 2015 04:27:23 -0700 (PDT) Received-SPF: pass (google.com: domain of mpi@openbsd.org designates 199.185.137.3 as permitted sender) client-ip=199.185.137.3; Authentication-Results: mx.google.com; spf=pass (google.com: domain of mpi@openbsd.org designates 199.185.137.3 as permitted sender) smtp.mail=mpi@openbsd.org Received: from shear.ucar.edu (lists.openbsd.org [192.43.244.163]) by cvs.openbsd.org (OpenSMTPD) with ESMTPS id 5c59644f TLS version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL for ; Tue, 26 May 2015 05:27:21 -0600 (MDT) Received: from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net [217.70.183.195]) by shear.ucar.edu (8.14.7/8.14.7) with ESMTP id t4QBRJjB000388 (version=TLSv1/SSLv3 cipher=DHE-DSS-AES256-SHA bits=256 verify=NO) for ; Tue, 26 May 2015 05:27:20 -0600 (MDT) Received: from mfilter12-d.gandi.net (mfilter12-d.gandi.net [217.70.178.129]) by relay3-d.mail.gandi.net (Postfix) with ESMTP id B63E8A80D7 for ; Tue, 26 May 2015 13:27:18 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mfilter12-d.gandi.net Received: from relay3-d.mail.gandi.net ([217.70.183.195]) by mfilter12-d.gandi.net (mfilter12-d.gandi.net [10.0.15.180]) (amavisd-new, port 10024) with ESMTP id 9aVkDT2YCEZQ for ; Tue, 26 May 2015 13:27:16 +0200 (CEST) X-Originating-IP: 195.132.27.120 Received: from figo.nolizard.org (195-132-27-120.rev.numericable.fr [195.132.27.120]) (Authenticated sender: mpieuchot@nolizard.org) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 5F501A80B8 for ; Tue, 26 May 2015 13:27:16 +0200 (CEST) Received: from localhost (figo.nolizard.org [local]); by figo.nolizard.org (OpenSMTPD) with ESMTPA id fe9c9f23; for ; Tue, 26 May 2015 13:27:15 +0200 (CEST) Date: Tue, 26 May 2015 13:27:15 +0200 From: Martin Pieuchot To: dlg@openbsd.org Subject: openpic regression on xserve g4 Message-ID: <20150526112715.GA24852@figo.nolizard.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) Status: RO Content-Length: 19434 Lines: 720 Does it still work on macppc-*.port? Index: dev/pci/pcireg.h =================================================================== RCS file: /cvs/src/sys/dev/pci/pcireg.h,v retrieving revision 1.47 diff -u -p -r1.47 pcireg.h --- dev/pci/pcireg.h 27 Apr 2014 14:55:09 -0000 1.47 +++ dev/pci/pcireg.h 4 May 2015 15:05:33 -0000 @@ -534,7 +534,7 @@ typedef u_int8_t pci_revision_t; #define PCI_HT_CAP_SLAVE 0x00 #define PCI_HT_CAP_HOST 0x04 -#define PCI_HT_CAP_INTERRUPT 0x10 +#define PCI_HT_CAP_INTR 0x10 #define PCI_HT_CAP_MSI 0x15 #define PCI_HT_MSI_ENABLED 0x00010000 @@ -544,6 +544,8 @@ typedef u_int8_t pci_revision_t; #define PCI_HT_MSI_ADDR 0x04 #define PCI_HT_MSI_ADDR_HI32 0x08 + +#define PCI_HT_INTR_DATA 0x04 /* * PCI Express; access via capability pointer. Index: arch/macppc/conf/GENERIC =================================================================== RCS file: /cvs/src/sys/arch/macppc/conf/GENERIC,v retrieving revision 1.249 diff -u -p -r1.249 GENERIC --- arch/macppc/conf/GENERIC 16 Apr 2015 09:09:49 -0000 1.249 +++ arch/macppc/conf/GENERIC 20 May 2015 08:56:19 -0000 @@ -46,6 +46,7 @@ smu* at mainbus0 pci* at mpcpcibr? pci* at ht? ppb* at pci? # PCI-PCI bridges +htb* at pci? pci* at ppb? siop* at pci? Index: arch/macppc/conf/files.macppc =================================================================== RCS file: /cvs/src/sys/arch/macppc/conf/files.macppc,v retrieving revision 1.81 diff -u -p -r1.81 files.macppc --- arch/macppc/conf/files.macppc 11 May 2015 06:46:21 -0000 1.81 +++ arch/macppc/conf/files.macppc 20 May 2015 08:56:19 -0000 @@ -86,7 +86,12 @@ include "dev/wscons/files.wscons" #file arch/macppc/pci/bandit.c pci -#PCI-Host bridge chipsets +# HT bridge +device htb {} +attach htb at pci +file arch/macppc/pci/htb.c htb needs-flag + +# PCI-Host bridge chipsets device pchb: agpbus attach pchb at pci file arch/macppc/pci/pchb.c pchb Index: arch/macppc/dev/openpic.c =================================================================== RCS file: /cvs/src/sys/arch/macppc/dev/openpic.c,v retrieving revision 1.79 diff -u -p -r1.79 openpic.c --- arch/macppc/dev/openpic.c 2 Apr 2015 11:22:48 -0000 1.79 +++ arch/macppc/dev/openpic.c 20 May 2015 12:25:41 -0000 @@ -37,13 +37,15 @@ * @(#)isa.c 7.2 (Berkeley) 5/12/91 */ +#include "htb.h" + #include #include #include #include +#include #include -#include #include #include @@ -85,16 +87,37 @@ void openpic_splx(int); u_int openpic_read(int reg); void openpic_write(int reg, u_int val); -void openpic_enable_irq(int, int); -void openpic_disable_irq(int); + +void openpic_acknowledge_irq(int, int); +void openpic_enable_irq(int, int, int); +void openpic_disable_irq(int, int); + void openpic_calc_mask(void); void openpic_set_priority(int, int); void *openpic_intr_establish(void *, int, int, int, int (*)(void *), void *, const char *); -void openpic_intr_disestablish( void *lcp, void *arg); +void openpic_intr_disestablish(void *, void *); void openpic_collect_preconf_intr(void); void openpic_ext_intr(void); +struct openpic_ops { + void (*acknowledge_irq)(int, int); + void (*enable_irq)(int, int, int); + void (*disable_irq)(int, int); +} openpic_ops; + +/* Generic IRQ management routines. */ +void openpic_gen_acknowledge_irq(int, int); +void openpic_gen_enable_irq(int, int, int); +void openpic_gen_disable_irq(int, int); + +#if NHTB > 0 +/* CPC945 IRQ management routines. */ +void openpic_cpc945_acknowledge_irq(int, int); +void openpic_cpc945_enable_irq(int, int, int); +void openpic_cpc945_disable_irq(int, int); +#endif /* NHTB */ + #ifdef MULTIPROCESSOR void openpic_ipi_ddb(void); @@ -124,7 +147,7 @@ openpic_read(int reg) { char *addr = (void *)(openpic_base + reg); - asm volatile("eieio"::: "memory"); + membar_sync(); if (openpic_big_endian) return in32(addr); else @@ -140,7 +163,7 @@ openpic_write(int reg, u_int val) out32(addr, val); else out32rb(addr, val); - asm volatile("eieio"::: "memory"); + membar_sync(); } static inline int @@ -183,7 +206,7 @@ openpic_match(struct device *parent, voi } void -openpic_attach(struct device *parent, struct device *self, void *aux) +openpic_attach(struct device *parent, struct device *self, void *aux) { struct cpu_info *ci = curcpu(); struct confargs *ca = aux; @@ -198,6 +221,13 @@ openpic_attach(struct device *parent, st openpic_base = (vaddr_t) mapiodev (ca->ca_baseaddr + ca->ca_reg[0], 0x40000); + /* Reset the PIC */ + x = openpic_read(OPENPIC_CONFIG) | OPENPIC_CONFIG_RESET; + openpic_write(OPENPIC_CONFIG, x); + + while (openpic_read(OPENPIC_CONFIG) & OPENPIC_CONFIG_RESET) + delay(100); + /* openpic may support more than 128 interupts but driver doesn't */ openpic_numirq = ((openpic_read(OPENPIC_FEATURE) >> 16) & 0x7f)+1; @@ -275,7 +305,7 @@ openpic_attach(struct device *parent, st openpic_set_priority(ci->ci_cpuid, 0); intr_establish_func = openpic_intr_establish; - intr_disestablish_func = openpic_intr_disestablish; + intr_disestablish_func = openpic_intr_disestablish; #ifdef MULTIPROCESSOR intr_send_ipi_func = openpic_send_ipi; #endif @@ -290,6 +320,22 @@ openpic_attach(struct device *parent, st ppc_intr_func.lower = openpic_spllower; ppc_intr_func.x = openpic_splx; +#if NHTB > 0 + /* + * Only U4 systems have a big-endian MPIC. + */ + if (openpic_big_endian) { + openpic_ops.acknowledge_irq = openpic_cpc945_acknowledge_irq; + openpic_ops.enable_irq = openpic_cpc945_enable_irq; + openpic_ops.disable_irq = openpic_cpc945_disable_irq; + } else +#endif + { + openpic_ops.acknowledge_irq = openpic_gen_acknowledge_irq; + openpic_ops.enable_irq = openpic_gen_enable_irq; + openpic_ops.disable_irq = openpic_gen_disable_irq; + } + openpic_set_priority(0, ci->ci_cpl); ppc_intr_enable(1); @@ -498,12 +544,12 @@ openpic_calc_mask() if (maxipl == IPL_NONE) { minipl = IPL_NONE; /* Interrupt not enabled */ - openpic_disable_irq(irq); + openpic_disable_irq(irq, iq->iq_ist); } else { for (i = minipl; i <= maxipl; i++) { openpic_pri_share[i] = maxipl; } - openpic_enable_irq(irq, maxipl); + openpic_enable_irq(irq, iq->iq_ist, maxipl); } iq->iq_ipl = maxipl; @@ -514,13 +560,19 @@ openpic_calc_mask() } void -openpic_enable_irq(int irq, int pri) +openpic_gen_acknowledge_irq(int irq, int cpuid) +{ + openpic_eoi(cpuid); +} + +void +openpic_gen_enable_irq(int irq, int ist, int pri) { u_int x; - struct intrq *iq = &openpic_handler[irq]; x = irq; - if (iq->iq_ist == IST_LEVEL) + + if (ist == IST_LEVEL) x |= OPENPIC_SENSE_LEVEL; else x |= OPENPIC_SENSE_EDGE; @@ -530,7 +582,7 @@ openpic_enable_irq(int irq, int pri) } void -openpic_disable_irq(int irq) +openpic_gen_disable_irq(int irq, int ist) { u_int x; @@ -545,30 +597,11 @@ openpic_set_priority(int cpu, int pri) openpic_write(OPENPIC_CPU_PRIORITY(cpu), pri); } -#ifdef MULTIPROCESSOR -void -openpic_send_ipi(struct cpu_info *ci, int id) -{ - switch (id) { - case PPC_IPI_NOP: - id = 0; - break; - case PPC_IPI_DDB: - id = 1; - break; - default: - panic("invalid ipi send to cpu %d %d", ci->ci_cpuid, id); - } - - openpic_write(OPENPIC_IPI(curcpu()->ci_cpuid, id), 1 << ci->ci_cpuid); -} - -#endif - int openpic_irqnest[PPC_MAXPROCS]; int openpic_irqloop[PPC_MAXPROCS]; + void -openpic_ext_intr() +openpic_ext_intr(void) { struct cpu_info *ci = curcpu(); int irq, pcpl, ret; @@ -624,7 +657,7 @@ openpic_ext_intr() if (iq->iq_ipl > maxipl) maxipl = iq->iq_ipl; openpic_splraise(iq->iq_ipl); - openpic_eoi(ci->ci_cpuid); + openpic_acknowledge_irq(irq, ci->ci_cpuid); spurious = 1; TAILQ_FOREACH(ih, &iq->iq_list, ih_list) { @@ -656,9 +689,44 @@ openpic_ext_intr() openpic_irqnest[ci->ci_cpuid]--; } +void +openpic_acknowledge_irq(int irq, int cpuid) +{ + (openpic_ops.acknowledge_irq)(irq, cpuid); +} + +void +openpic_enable_irq(int irq, int ist, int pri) +{ + (openpic_ops.enable_irq)(irq, ist, pri); +} + +void +openpic_disable_irq(int irq, int ist) +{ + (openpic_ops.disable_irq)(irq, ist); +} + #ifdef MULTIPROCESSOR void -openpic_ipi_ddb() +openpic_send_ipi(struct cpu_info *ci, int id) +{ + switch (id) { + case PPC_IPI_NOP: + id = 0; + break; + case PPC_IPI_DDB: + id = 1; + break; + default: + panic("invalid ipi send to cpu %d %d", ci->ci_cpuid, id); + } + + openpic_write(OPENPIC_IPI(curcpu()->ci_cpuid, id), 1 << ci->ci_cpuid); +} + +void +openpic_ipi_ddb(void) { DPRINTF("ipi_ddb() called\n"); #ifdef DDB @@ -666,3 +734,40 @@ openpic_ipi_ddb() #endif } #endif /* MULTIPROCESSOR */ + +#if NHTB > 0 +extern int htb_enable_irq(int, int); +extern int htb_disable_irq(int, int); +extern void htb_eoi(int); + +void +openpic_cpc945_acknowledge_irq(int irq, int cpuid) +{ + htb_eoi(irq); + openpic_gen_acknowledge_irq(irq, cpuid); +} + +void +openpic_cpc945_enable_irq(int irq, int ist, int pri) +{ + if (htb_enable_irq(irq, ist)) { + u_int x = irq; + + x |= OPENPIC_SENSE_EDGE; + x |= OPENPIC_POLARITY_POSITIVE; + x |= pri << OPENPIC_PRIORITY_SHIFT; + openpic_write(OPENPIC_SRC_VECTOR(irq), x); + + htb_eoi(irq); + } else + openpic_gen_enable_irq(irq, ist, pri); +} + +void +openpic_cpc945_disable_irq(int irq, int ist) +{ + htb_disable_irq(irq, ist); + openpic_gen_disable_irq(irq, ist); +} +#endif /* NHTB */ + Index: arch/macppc/dev/smu.c =================================================================== RCS file: /cvs/src/sys/arch/macppc/dev/smu.c,v retrieving revision 1.26 diff -u -p -r1.26 smu.c --- arch/macppc/dev/smu.c 8 Oct 2014 16:07:45 -0000 1.26 +++ arch/macppc/dev/smu.c 20 May 2015 08:56:19 -0000 @@ -54,6 +54,13 @@ struct smu_sensor { struct ksensor sensor; }; +/* SMU CPU T-Diode sensor. */ +#define SMU_CPU_TEMP 0 + +/* CPU temperature boundaries in muK. */ +#define CPU_TEMP_MAX (80 * 1000000 + 273150000) +#define CPU_TEMP_MIN (30 * 1000000 + 273150000) + struct smu_softc { struct device sc_dev; @@ -145,8 +152,9 @@ int smu_time_write(time_t); int smu_get_datablock(struct smu_softc *sc, u_int8_t, u_int8_t *, size_t); int smu_fan_set_rpm(struct smu_softc *, struct smu_fan *, u_int16_t); int smu_fan_refresh(struct smu_softc *, struct smu_fan *); +int smu_fan_adjust(struct smu_softc *, struct smu_fan *, u_int64_t); int smu_sensor_refresh(struct smu_softc *, struct smu_sensor *); -void smu_refresh_sensors(void *); +void smu_refresh(void *); int smu_i2c_acquire_bus(void *, int); void smu_i2c_release_bus(void *, int); @@ -365,7 +373,7 @@ smu_attach(struct device *parent, struct sc->sc_slots_pow_scale = (data[4] << 8) + data[5]; sc->sc_slots_pow_offset = (data[6] << 8) + data[7]; - sensor_task_register(sc, smu_refresh_sensors, 5); + sensor_task_register(sc, smu_refresh, 5); #endif /* !SMALL_KERNEL */ printf("\n"); @@ -643,9 +651,10 @@ smu_sensor_refresh(struct smu_softc *sc, } void -smu_refresh_sensors(void *arg) +smu_refresh(void *arg) { struct smu_softc *sc = arg; + struct ksensor *ks; int i; rw_enter_write(&sc->sc_lock); @@ -653,6 +662,10 @@ smu_refresh_sensors(void *arg) smu_sensor_refresh(sc, &sc->sc_sensors[i]); for (i = 0; i < sc->sc_num_fans; i++) smu_fan_refresh(sc, &sc->sc_fans[i]); + if (sensor_find(0, SENSOR_TEMP, SMU_CPU_TEMP, &ks) == 0) { + for (i = 0; i < sc->sc_num_fans; i++) + smu_fan_adjust(sc, &sc->sc_fans[i], ks->value); + } rw_exit_write(&sc->sc_lock); } @@ -750,4 +763,22 @@ smu_slew_voltage(u_int freq_scale) cmd->data[7] = freq_scale; smu_do_cmd(sc, 250); +} + +int +smu_fan_adjust(struct smu_softc *sc, struct smu_fan *fan, u_int64_t ctemp) +{ + u_int16_t rpm;; + + if (ctemp < CPU_TEMP_MIN) { + rpm = fan->min_rpm; + } else if (ctemp < CPU_TEMP_MAX) { + rpm = fan->min_rpm + (ctemp - CPU_TEMP_MIN) * + (fan->max_rpm - fan->min_rpm) / + (CPU_TEMP_MAX - CPU_TEMP_MIN); + } else { + rpm = fan->max_rpm; + } + + return smu_fan_set_rpm(sc, fan, rpm); } Index: arch/macppc/pci/htb.c =================================================================== RCS file: arch/macppc/pci/htb.c diff -N arch/macppc/pci/htb.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ arch/macppc/pci/htb.c 20 May 2015 08:59:38 -0000 @@ -0,0 +1,222 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2015 Martin Pieuchot + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include + +#include +#include +#include + +/* + * Section 7.6.2 Interrupt Message Definition Register + */ +#define PCI_HT_LAST_ISMG (0x01 << 16) +#define PCI_HT_IMSG_LO(idx) (((2 * (idx)) + 0x10) << 16) +#define HT_MASK (1 << 0) +#define HT_ACTIVELOW (1 << 1) +#define HT_EOI (1 << 5) + +#define PCI_HT_IMSG_HI(idx) (PCI_HT_IMSG_LO(idx) + 1) +#define HT_PASSPW (1U << 30) +#define HT_WAITEOI (1U << 31) /* Waiting for EOI */ + + +/* Apple hardware is special... */ +#define HT_APPL_EOIOFF(idx) (0x60 + (((idx) >> 3) & ~3)) +#define HT_APPL_WEOI(idx) (1 << ((idx) & 0x1f)) + +struct ht_intr_msg { + unsigned int him_idx; /* Index */ + int him_ist; /* Share type */ + pcireg_t him_weoi; /* Cached wait for interrupt data */ +}; + +#define HTB_MAX_IMSG 128 + +struct htb_softc { + struct device sc_dev; + pci_chipset_tag_t sc_pc; + pcitag_t sc_tag; + pcireg_t sc_id; /* Needed for Apple hardware */ + unsigned int sc_off; /* Interrupt cap. offset */ + unsigned int sc_nirq; + struct ht_intr_msg sc_imap[HTB_MAX_IMSG]; +}; + +int htb_match(struct device *, void *, void *); +void htb_attach(struct device *, struct device *, void *); + +void htb_eoi(int); +int htb_enable_irq(int, int); +int htb_disable_irq(int, int); + +const struct cfattach htb_ca = { + sizeof(struct htb_softc), htb_match, htb_attach +}; + +struct cfdriver htb_cd = { + NULL, "htb", DV_DULL, +}; + +const struct pci_matchid htb_devices[] = { + { PCI_VENDOR_APPLE, PCI_PRODUCT_APPLE_SHASTA_PCI1 } +}; + +int +htb_match(struct device *parent, void *match, void *aux) +{ + struct pci_attach_args *pa = aux; + pci_chipset_tag_t pc = pa->pa_pc; + pcitag_t tag = pa->pa_tag; + + if (!pci_matchbyid(pa, htb_devices, nitems(htb_devices))) + return (0); + + if (!pci_get_ht_capability(pc, tag, PCI_HT_CAP_INTR, NULL, NULL)) + return (0); + + return (10); +} + +void +htb_attach(struct device *parent, struct device *self, void *aux) +{ + struct htb_softc *sc = (struct htb_softc *)self; + struct pci_attach_args *pa = aux; + pci_chipset_tag_t pc = pa->pa_pc; + pcitag_t tag = pa->pa_tag; + int idx, irq, off; + pcireg_t reg; + + if (!pci_get_ht_capability(pc, tag, PCI_HT_CAP_INTR, &off, NULL)) + panic("\nA clown ate your HT capability"); + + /* Interrupt definitions are numbered beginning with 0. */ + pci_conf_write(pc, tag, off, PCI_HT_LAST_ISMG); + reg = pci_conf_read(pc, tag, off + PCI_HT_INTR_DATA); + + sc->sc_pc = pc; + sc->sc_tag = tag; + sc->sc_id = pa->pa_id; + sc->sc_off = off; + sc->sc_nirq = ((reg >> 16) & 0xff); + + if (sc->sc_nirq == 0 || sc->sc_nirq > HTB_MAX_IMSG) + return; + + printf(": %u sources\n", sc->sc_nirq); + + for (idx = 0; idx < sc->sc_nirq; idx++) { + pci_conf_write(pc, tag, off, PCI_HT_IMSG_LO(idx)); + reg = pci_conf_read(pc, tag, off + PCI_HT_INTR_DATA); + + pci_conf_write(pc, tag, off + PCI_HT_INTR_DATA, reg | HT_MASK); + irq = (reg >> 16) & 0xff; + +#ifdef DIAGNOSTIC + if (sc->sc_imap[irq].him_idx != 0) { + printf("%s: multiple definition for irq %d\n", + sc->sc_dev.dv_xname, irq); + continue; + } +#endif + pci_conf_write(pc, tag, off, PCI_HT_IMSG_HI(idx)); + reg = pci_conf_read(pc, tag, off + PCI_HT_INTR_DATA); + + sc->sc_imap[irq].him_idx = idx; + sc->sc_imap[irq].him_weoi = reg | HT_WAITEOI; + } +} + +void +htb_eoi(int irq) +{ + struct htb_softc *sc = htb_cd.cd_devs[0]; + pci_chipset_tag_t pc = sc->sc_pc; + pcitag_t tag = sc->sc_tag; + int idx; + + if (irq >= sc->sc_nirq || sc->sc_imap[irq].him_weoi == 0 || + sc->sc_imap[irq].him_ist != IST_LEVEL) + return; + + idx = sc->sc_imap[irq].him_idx; + + if (PCI_VENDOR(sc->sc_id) == PCI_VENDOR_APPLE) { + pci_conf_write(pc, tag, HT_APPL_EOIOFF(idx), HT_APPL_WEOI(idx)); + } else { + pci_conf_write(pc, tag, sc->sc_off, PCI_HT_IMSG_HI(idx)); + pci_conf_write(pc, tag, sc->sc_off + PCI_HT_INTR_DATA, + sc->sc_imap[irq].him_weoi); + } +} + +int +htb_enable_irq(int irq, int ist) +{ + struct htb_softc *sc = htb_cd.cd_devs[0]; + pci_chipset_tag_t pc = sc->sc_pc; + pcitag_t tag = sc->sc_tag; + pcireg_t reg; + int idx; + + if (irq >= sc->sc_nirq || sc->sc_imap[irq].him_weoi == 0) + return (0); + + idx = sc->sc_imap[irq].him_idx; + sc->sc_imap[irq].him_ist = ist; + + pci_conf_write(pc, tag, sc->sc_off, PCI_HT_IMSG_LO(idx)); + reg = pci_conf_read(pc, tag, sc->sc_off + PCI_HT_INTR_DATA); + + pci_conf_write(pc, tag, sc->sc_off + PCI_HT_INTR_DATA, reg | HT_MASK); + + reg &= ~(HT_ACTIVELOW | HT_EOI | HT_MASK); + if (ist == IST_LEVEL) + reg |= HT_ACTIVELOW | HT_EOI; + + pci_conf_write(pc, tag, sc->sc_off + PCI_HT_INTR_DATA, reg); + + return (1); +} + +int +htb_disable_irq(int irq, int ist) +{ + struct htb_softc *sc = htb_cd.cd_devs[0]; + pci_chipset_tag_t pc = sc->sc_pc; + pcitag_t tag = sc->sc_tag; + pcireg_t reg; + int idx; + + if (irq > sc->sc_nirq || sc->sc_imap[irq].him_weoi == 0) + return (0); + + idx = sc->sc_imap[irq].him_idx; + + pci_conf_write(pc, tag, sc->sc_off, PCI_HT_IMSG_LO(idx)); + reg = pci_conf_read(pc, tag, sc->sc_off + PCI_HT_INTR_DATA); + + pci_conf_write(pc, tag, sc->sc_off + PCI_HT_INTR_DATA, reg | HT_MASK); + + return (1); +} Index: arch/macppc/pci/mpcpcibus.c =================================================================== RCS file: /cvs/src/sys/arch/macppc/pci/mpcpcibus.c,v retrieving revision 1.46 diff -u -p -r1.46 mpcpcibus.c --- arch/macppc/pci/mpcpcibus.c 7 Aug 2013 07:29:19 -0000 1.46 +++ arch/macppc/pci/mpcpcibus.c 20 May 2015 08:56:19 -0000 @@ -103,6 +103,7 @@ struct config_type config_offsets[] = { {"uni-north", 0x00800000, 0x00c00000, 3 }, {"u3-agp", 0x00800000, 0x00c00000, 3 }, {"u3-ht", 0x00000cf8, 0x00000cfc, 3 }, + {"u4-pcie", 0x00800000, 0x00c00000, 7 }, {"legacy", 0x00000cf8, 0x00000cfc, 0 }, {"IBM,27-82660", 0x00000cf8, 0x00000cfc, 0 }, {NULL, 0x00000000, 0x00000000, 0 }, @@ -445,7 +446,10 @@ mpc_gen_config_reg(void *cpv, pcitag_t t pci_decompose_tag(cpv, tag, &bus, &dev, &fcn); - if (cp->config_type & 1) { + if (cp->config_type & 4) { + reg = val | offset | 1; + reg |= (offset >> 8) << 28; + } else if (cp->config_type & 1) { /* Config Mechanism #2 */ if (bus == 0) { if (dev < 11)