Home | History | Annotate | Line # | Download | only in vsa
      1  1.10   rin /*	$NetBSD: tc_vsbus.c,v 1.10 2021/05/08 09:03:30 rin Exp $	*/
      2   1.1  matt /*-
      3   1.1  matt  * Copyright (c) 2008 The NetBSD Foundation, Inc.
      4   1.1  matt  * All rights reserved.
      5   1.1  matt  *
      6   1.1  matt  * This code is derived from software contributed to The NetBSD Foundation
      7   1.1  matt  * by Matt Thomas <matt (at) 3am-software.com>.
      8   1.1  matt  *
      9   1.1  matt  * Redistribution and use in source and binary forms, with or without
     10   1.1  matt  * modification, are permitted provided that the following conditions
     11   1.1  matt  * are met:
     12   1.1  matt  * 1. Redistributions of source code must retain the above copyright
     13   1.1  matt  *    notice, this list of conditions and the following disclaimer.
     14   1.1  matt  * 2. Redistributions in binary form must reproduce the above copyright
     15   1.1  matt  *    notice, this list of conditions and the following disclaimer in the
     16   1.1  matt  *    documentation and/or other materials provided with the distribution.
     17   1.1  matt  *
     18   1.1  matt  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     19   1.1  matt  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     20   1.1  matt  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     21   1.1  matt  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     22   1.1  matt  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     23   1.1  matt  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     24   1.1  matt  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     25   1.1  matt  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     26   1.1  matt  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     27   1.1  matt  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     28   1.1  matt  * POSSIBILITY OF SUCH DAMAGE.
     29   1.1  matt  */
     30   1.1  matt 
     31   1.8  flxd #include <sys/cdefs.h>
     32  1.10   rin __KERNEL_RCSID(0, "$NetBSD: tc_vsbus.c,v 1.10 2021/05/08 09:03:30 rin Exp $");
     33   1.8  flxd 
     34   1.1  matt #include <sys/param.h>
     35   1.5  matt #include <sys/bus.h>
     36   1.5  matt #include <sys/cpu.h>
     37   1.1  matt #include <sys/device.h>
     38   1.1  matt 
     39   1.8  flxd #include <machine/cpu.h>
     40   1.1  matt #include <machine/pte.h>
     41   1.1  matt #include <machine/scb.h>
     42   1.8  flxd #include <machine/sid.h>
     43   1.1  matt #include <machine/vsbus.h>
     44   1.8  flxd 
     45   1.1  matt #include <dev/tc/tcvar.h>
     46   1.1  matt 
     47   1.8  flxd #define NSLOTS	1
     48   1.1  matt 
     49   1.8  flxd struct tc_vsbus_softc {
     50   1.1  matt 	struct tc_softc sc_tc;
     51   1.8  flxd 	struct tc_slotdesc sc_slots[NSLOTS];
     52   1.1  matt 	struct vax_bus_dma_tag sc_dmatag;
     53   1.1  matt 	struct vax_sgmap sc_sgmap;
     54   1.1  matt 	struct evcnt sc_ev;
     55   1.8  flxd 	int (*sc_intr_func)(void *);
     56   1.8  flxd 	void *sc_intr_arg;
     57   1.8  flxd 	bus_space_tag_t sc_bst;
     58   1.8  flxd 	bus_space_handle_t sc_bsh_csr;
     59   1.8  flxd 	int sc_cvec;
     60   1.1  matt };
     61   1.1  matt 
     62   1.8  flxd static int tc_vsbus_match(device_t, cfdata_t, void *);
     63   1.8  flxd static void tc_vsbus_attach(device_t, device_t, void *);
     64   1.8  flxd 
     65   1.8  flxd static int tc_vsbus_dma_init(device_t);
     66   1.8  flxd static bus_dma_tag_t tc_vsbus_get_dma_tag(int);
     67   1.8  flxd 
     68   1.8  flxd static void tc_vsbus_intr(void *);
     69   1.8  flxd static void tc_vsbus_intr_establish(device_t, void *, int, int (*)(void *),
     70   1.8  flxd     void *);
     71   1.8  flxd static void tc_vsbus_intr_disestablish(device_t, void *);
     72   1.8  flxd static const struct evcnt *tc_vsbus_intr_evcnt(device_t, void *);
     73   1.8  flxd 
     74   1.8  flxd static int vax_tc_bus_space_map(void *, bus_addr_t, bus_size_t, int,
     75   1.8  flxd     bus_space_handle_t *, int);
     76   1.8  flxd static int vax_tc_bus_space_subregion(void *, bus_space_handle_t, bus_size_t,
     77   1.8  flxd     bus_size_t, bus_space_handle_t *);
     78   1.8  flxd static void vax_tc_bus_space_unmap(void *, bus_space_handle_t, bus_size_t, int);
     79   1.8  flxd static int vax_tc_bus_space_alloc(void *, bus_addr_t, bus_addr_t, bus_size_t,
     80   1.8  flxd     bus_size_t, bus_size_t, int, bus_addr_t *, bus_space_handle_t *);
     81   1.8  flxd static void vax_tc_bus_space_free(void *, bus_space_handle_t, bus_size_t);
     82   1.8  flxd static paddr_t vax_tc_bus_space_mmap(void *, bus_addr_t, off_t, int, int);
     83   1.8  flxd 
     84   1.8  flxd CFATTACH_DECL_NEW(tc_vsbus, sizeof(struct tc_vsbus_softc),
     85   1.8  flxd     tc_vsbus_match, tc_vsbus_attach, 0, 0);
     86   1.8  flxd 
     87   1.8  flxd static bus_dma_tag_t tc_vsbus_dmat;
     88   1.8  flxd 
     89   1.8  flxd struct vax_bus_space vax_tc_bus_space = {
     90   1.8  flxd 	NULL,
     91   1.8  flxd 	vax_tc_bus_space_map,
     92   1.8  flxd 	vax_tc_bus_space_unmap,
     93   1.8  flxd 	vax_tc_bus_space_subregion,
     94   1.8  flxd 	vax_tc_bus_space_alloc,
     95   1.8  flxd 	vax_tc_bus_space_free,
     96   1.8  flxd 	vax_tc_bus_space_mmap,
     97   1.8  flxd };
     98   1.8  flxd 
     99   1.8  flxd /*
    100   1.8  flxd  * taken from KA46 System Board Specification, KA46-0-DBF, Rev. X.02,
    101   1.8  flxd  * 10 October 1990
    102   1.8  flxd  */
    103   1.8  flxd #define KA46_BWF0			0x20080014
    104   1.8  flxd #define   KA46_BWF0_ADP			__BIT(31)
    105   1.8  flxd #define KA46_BWF0_SZ			4
    106   1.8  flxd 
    107   1.8  flxd /*
    108   1.8  flxd  * taken from KA49 Processor Module Specification V 1.1, 20 August 1992
    109   1.8  flxd  */
    110   1.8  flxd #define KA49_CFG			0x25800000
    111   1.8  flxd #define   KA49_CFG_BA			__BIT(0)
    112   1.8  flxd #define KA49_CFG_SZ			2
    113   1.8  flxd 
    114   1.8  flxd /*
    115   1.8  flxd  * taken from Pmariah TURBOchannel Adapter Specification, 29 November 1991
    116   1.8  flxd  */
    117   1.8  flxd #define KA4x_TCA_BASE			0x30000000
    118   1.8  flxd #define KA4x_TCA_DIAG_TRIG		(KA4x_TCA_BASE + 0x4000000)
    119   1.8  flxd #define KA4x_TCA_MAP_CHK_SEQ		(KA4x_TCA_BASE + 0x4800000)
    120   1.8  flxd #define KA4x_TCA_FIFO_DIAG		(KA4x_TCA_BASE + 0x5000000)
    121   1.8  flxd #define KA4x_TCA_SGMAP			(KA4x_TCA_BASE + 0x5800000)
    122   1.8  flxd #define KA4x_TCA_DIAG_ROM		(KA4x_TCA_BASE + 0x6000000)
    123   1.8  flxd #define KA4x_TCA_CSR			(KA4x_TCA_BASE + 0x6800000)
    124   1.8  flxd #define   KA4x_TCA_CSR_BLK_SZ		__BITS(0, 2)	/* 0x00007 RW   */
    125   1.8  flxd #define   KA4x_TCA_CSR_SPARE		__BIT(3)	/* 0x00008 RW   */
    126   1.8  flxd #define   KA4x_TCA_CSR_BAD_PAR		__BITS(4, 7)	/* 0x000f0 RW   */
    127   1.8  flxd #define   KA4x_TCA_CSR_RST_TC		__BIT(8)	/* 0x00100 RW   */
    128   1.8  flxd #define   KA4x_TCA_CSR_EN_MAP		__BIT(9)	/* 0x00200 RW   */
    129   1.8  flxd #define   KA4x_TCA_CSR_INVAL_REF	__BIT(10)	/* 0x00400 RW1C */
    130   1.8  flxd #define   KA4x_TCA_CSR_TC_TMO		__BIT(11)	/* 0x00800 RW   */
    131   1.8  flxd #define   KA4x_TCA_CSR_EN_TC_IRQ	__BIT(12)	/* 0x01000 RW   */
    132   1.8  flxd #define   KA4x_TCA_CSR_TC_IRQ		__BIT(13)	/* 0x02000 R    */
    133   1.8  flxd #define   KA4x_TCA_CSR_ERR		__BIT(14)	/* 0x04000 RW1C */
    134   1.8  flxd #define   KA4x_TCA_CSR_ALT_CYC_ST	__BIT(15)	/* 0x08000 RW   */
    135   1.8  flxd #define   KA4x_TCA_CSR_EN_PAR		__BIT(16)	/* 0x10000 RW   */
    136   1.8  flxd #define   KA4x_TCA_CSR_FIFO_EMPTY	__BIT(17)	/* 0x20000 R    */
    137   1.8  flxd #define KA4x_TCA_CSR_SZ			4
    138   1.8  flxd 
    139   1.8  flxd static int
    140   1.8  flxd tc_vsbus_match(device_t parent, cfdata_t cfdata, void *aux)
    141   1.8  flxd {
    142   1.8  flxd 	struct vsbus_attach_args * const va = aux;
    143   1.8  flxd 	uint32_t *csr;
    144   1.8  flxd 	bus_space_tag_t bst = va->va_memt;
    145   1.8  flxd 	bus_space_handle_t bsh;
    146   1.8  flxd 	int found, rc;
    147   1.8  flxd 
    148   1.8  flxd 	if (va->va_paddr != KA4x_TCA_CSR)
    149   1.8  flxd 		return 0;
    150   1.8  flxd 
    151   1.8  flxd 	/* Bus adaptor present? */
    152   1.8  flxd 	switch (vax_boardtype) {
    153   1.8  flxd 	case VAX_BTYP_46:
    154   1.8  flxd 		if (bus_space_map(bst, KA46_BWF0, KA46_BWF0_SZ, 0, &bsh))
    155   1.8  flxd 			return 0;
    156   1.8  flxd 		found = ((bus_space_read_4(bst, bsh, 0) & KA46_BWF0_ADP) != 0);
    157   1.8  flxd 		bus_space_unmap(bst, bsh, KA46_BWF0_SZ);
    158   1.8  flxd 		/*
    159   1.9  flxd 		 * On VS4000/60, although interrupting on a real vector, fool
    160   1.8  flxd 		 * vsbus interrupt, as no interrupt bit will be set in
    161   1.8  flxd 		 * vsbus_softc's sc_intreq for TC adaptor.
    162   1.9  flxd 		 */
    163   1.8  flxd 		rc = 20;
    164   1.8  flxd 		break;
    165   1.8  flxd 	case VAX_BTYP_49:
    166   1.8  flxd 		if (bus_space_map(bst, KA49_CFG, KA49_CFG_SZ, 0, &bsh))
    167   1.8  flxd 			return 0;
    168   1.8  flxd 		found = ((bus_space_read_2(bst, bsh, 0) & KA49_CFG_BA) != 0);
    169   1.8  flxd 		bus_space_unmap(bst, bsh, KA49_CFG_SZ);
    170   1.8  flxd 		rc = 10;
    171   1.8  flxd 		break;
    172   1.8  flxd 	default:
    173   1.8  flxd 		return 0;
    174   1.8  flxd 	}
    175   1.8  flxd 	if (!found)
    176   1.8  flxd 		return 0;
    177   1.8  flxd 
    178   1.8  flxd 	/* XXX Assume a found bus adaptor is the TC bus adaptor. */
    179   1.8  flxd 
    180   1.8  flxd 	/* Force interrupt. */
    181   1.8  flxd 	csr = (uint32_t *)va->va_addr;
    182   1.8  flxd 	*csr |= KA4x_TCA_CSR_TC_TMO;
    183   1.8  flxd 	DELAY(10000);
    184   1.8  flxd 	*csr &= ~KA4x_TCA_CSR_TC_TMO;
    185   1.8  flxd 	DELAY(10000);
    186   1.8  flxd 
    187   1.8  flxd 	return rc;
    188   1.8  flxd }
    189   1.8  flxd 
    190   1.8  flxd #define INIT_SLOTSZ	1
    191   1.8  flxd 
    192   1.8  flxd static void
    193   1.8  flxd tc_vsbus_attach(device_t parent, device_t self, void *aux)
    194   1.8  flxd {
    195   1.8  flxd 	struct tcbus_attach_args tba;
    196   1.8  flxd 	struct vsbus_attach_args * const va = aux;
    197   1.8  flxd 	struct tc_vsbus_softc * const sc = device_private(self);
    198   1.8  flxd 	struct tc_rommap *rommap;
    199   1.8  flxd 	bus_space_tag_t bst = va->va_memt;
    200   1.8  flxd 	bus_space_handle_t bsh_csr, bsh_slot;
    201   1.8  flxd 	const bus_size_t slotb = 4194304;
    202   1.8  flxd 	uint32_t csr;
    203   1.8  flxd 	int error, slotsz;
    204   1.8  flxd 
    205   1.8  flxd 	sc->sc_cvec = va->va_cvec;
    206   1.1  matt 
    207   1.8  flxd 	error = bus_space_map(bst, KA4x_TCA_CSR, KA4x_TCA_CSR_SZ, 0, &bsh_csr);
    208   1.8  flxd 	if (error) {
    209   1.8  flxd 		aprint_normal(": failed to map TCA CSR: %d\n", error);
    210   1.8  flxd 		return;
    211   1.8  flxd 	}
    212   1.8  flxd 	sc->sc_bst = bst;
    213   1.8  flxd 	sc->sc_bsh_csr = bsh_csr;
    214   1.8  flxd 
    215   1.8  flxd 	/* Deassert TC option reset and clean up. */
    216   1.8  flxd 	csr = bus_space_read_4(bst, bsh_csr, 0);
    217   1.8  flxd 	csr &= ~(KA4x_TCA_CSR_TC_TMO | KA4x_TCA_CSR_RST_TC);
    218   1.8  flxd 	csr |= KA4x_TCA_CSR_ERR | KA4x_TCA_CSR_INVAL_REF;
    219   1.8  flxd 	bus_space_write_4(bst, bsh_csr, 0, csr);
    220   1.8  flxd 
    221   1.8  flxd 	/*
    222   1.8  flxd 	 * Map initial number of "slots" (4 MB each) to read the option ROM
    223   1.8  flxd 	 * header.
    224   1.8  flxd 	 */
    225   1.8  flxd 	error = bus_space_map(bst, KA4x_TCA_BASE, INIT_SLOTSZ * slotb,
    226   1.8  flxd 	    BUS_SPACE_MAP_LINEAR, &bsh_slot);
    227   1.8  flxd 	if (error) {
    228   1.8  flxd 		aprint_normal(": failed to map TC slot: %d", error);
    229   1.8  flxd 		goto fail;
    230   1.8  flxd 	}
    231   1.8  flxd 	/* Determine number of slots required from option ROM header. */
    232   1.8  flxd 	slotsz = 0;
    233   1.8  flxd 	if (tc_checkslot((tc_addr_t)bus_space_vaddr(bst, bsh_slot), NULL,
    234   1.8  flxd 	    &rommap))
    235   1.8  flxd 		slotsz = rommap->tcr_ssize.v;
    236   1.8  flxd 	if (slotsz == 0) {
    237   1.8  flxd 		/* Invalid option ROM header or no option present. */
    238   1.8  flxd 		bus_space_unmap(bst, bsh_slot, INIT_SLOTSZ * slotb);
    239   1.8  flxd 		goto fail;
    240   1.8  flxd 	} else if (slotsz > INIT_SLOTSZ) {
    241   1.8  flxd 		/* Remap with actual slot size required. */
    242   1.8  flxd 		bus_space_unmap(bst, bsh_slot, INIT_SLOTSZ * slotb);
    243   1.8  flxd 		error = bus_space_map(bst, KA4x_TCA_BASE, slotsz * slotb,
    244   1.8  flxd 		    BUS_SPACE_MAP_LINEAR, &bsh_slot);
    245   1.8  flxd 		if (error) {
    246   1.8  flxd 			aprint_normal(": failed to map TC slot: %d", error);
    247   1.8  flxd 			goto fail;
    248   1.8  flxd 		}
    249   1.8  flxd 	} else
    250   1.8  flxd 		slotsz = INIT_SLOTSZ;
    251   1.8  flxd 
    252   1.8  flxd 	/* Pass pre-mapped space for TC drivers not bus_space'ified yet. */
    253   1.8  flxd 	sc->sc_slots[0].tcs_addr = (tc_addr_t)bus_space_vaddr(bst, bsh_slot);
    254   1.8  flxd 	sc->sc_slots[0].tcs_cookie = sc;
    255   1.8  flxd 
    256   1.8  flxd 	tba.tba_busname = "tc";
    257   1.8  flxd 	/* Tag with custom methods for pre-mapped bus_space. */
    258   1.8  flxd 	tba.tba_memt = &vax_tc_bus_space;
    259   1.8  flxd 	tba.tba_speed = TC_SPEED_12_5_MHZ;
    260   1.8  flxd 	tba.tba_nslots = __arraycount(sc->sc_slots);
    261   1.8  flxd 	tba.tba_slots = sc->sc_slots;
    262   1.8  flxd 	tba.tba_nbuiltins = 0;
    263   1.8  flxd 	tba.tba_intr_evcnt = tc_vsbus_intr_evcnt;
    264   1.8  flxd 	tba.tba_intr_establish = tc_vsbus_intr_establish;
    265   1.8  flxd 	tba.tba_intr_disestablish = tc_vsbus_intr_disestablish;
    266   1.8  flxd 	tba.tba_get_dma_tag = tc_vsbus_get_dma_tag;
    267   1.8  flxd 
    268   1.8  flxd 	error = tc_vsbus_dma_init(self);
    269   1.8  flxd 	if (error) {
    270   1.8  flxd 		aprint_normal(": failed to init DMA: %d", error);
    271   1.8  flxd 		bus_space_unmap(bst, bsh_slot, slotsz * slotb);
    272   1.8  flxd 		goto fail;
    273   1.8  flxd 	}
    274   1.8  flxd 
    275   1.8  flxd 	evcnt_attach_dynamic(&sc->sc_ev, EVCNT_TYPE_INTR, NULL,
    276   1.8  flxd 	    device_xname(self), "intr");
    277   1.8  flxd 
    278   1.8  flxd 	/* Enable SGDMA and option IRQ now. */
    279   1.8  flxd 	csr = bus_space_read_4(bst, bsh_csr, 0);
    280   1.8  flxd 	csr &= ~(KA4x_TCA_CSR_TC_TMO | KA4x_TCA_CSR_RST_TC);
    281   1.8  flxd 	csr |= KA4x_TCA_CSR_ERR | KA4x_TCA_CSR_EN_TC_IRQ |
    282   1.8  flxd 	    KA4x_TCA_CSR_INVAL_REF | KA4x_TCA_CSR_EN_MAP;
    283   1.8  flxd 	bus_space_write_4(bst, bsh_csr, 0, csr);
    284   1.8  flxd 
    285   1.8  flxd 	/* XXX: why not config_found(9)?? */
    286   1.8  flxd 	tcattach(parent, self, &tba);
    287   1.8  flxd 
    288   1.8  flxd 	return;
    289   1.8  flxd 
    290   1.8  flxd fail:
    291   1.8  flxd 	aprint_normal("\n");
    292   1.8  flxd 	/* Clear possible timeout bit which asserts TC interrupt. */
    293   1.8  flxd 	csr = bus_space_read_4(bst, bsh_csr, 0);
    294   1.8  flxd 	csr &= ~KA4x_TCA_CSR_TC_TMO;
    295   1.8  flxd 	bus_space_write_4(bst, bsh_csr, 0, csr);
    296   1.8  flxd 	bus_space_unmap(bst, bsh_csr, KA4x_TCA_CSR_SZ);
    297   1.8  flxd }
    298   1.8  flxd 
    299   1.8  flxd static int
    300   1.8  flxd tc_vsbus_dma_init(device_t dev)
    301   1.8  flxd {
    302   1.8  flxd 	struct tc_vsbus_softc * const sc = device_private(dev);
    303   1.8  flxd 	struct pte *pte;
    304   1.8  flxd 	bus_dma_tag_t dmat = &sc->sc_dmatag;
    305   1.8  flxd 	bus_space_tag_t bst = sc->sc_bst;
    306   1.8  flxd 	bus_space_handle_t bsh;
    307   1.8  flxd 	const bus_size_t ptecnt = 8192;
    308   1.8  flxd 	const bus_size_t mapsize = ptecnt * sizeof(pte[0]);
    309   1.8  flxd 	int error;
    310   1.8  flxd 
    311   1.8  flxd 	vax_sgmap_dmatag_init(dmat, sc, ptecnt);
    312   1.8  flxd 
    313   1.8  flxd 	dmat->_sgmap = &sc->sc_sgmap;
    314   1.8  flxd 
    315   1.8  flxd 	error = bus_space_map(bst, KA4x_TCA_SGMAP, mapsize,
    316   1.8  flxd 	    BUS_SPACE_MAP_LINEAR, &bsh);
    317   1.8  flxd 	if (error)
    318   1.8  flxd 		return error;
    319   1.8  flxd 	bus_space_set_region_4(bst, bsh, 0, 0, ptecnt);
    320   1.8  flxd 	pte = bus_space_vaddr(bst, bsh);
    321   1.8  flxd 
    322   1.8  flxd 	/* Initialize the SGMAP. */
    323   1.8  flxd 	vax_sgmap_init(dmat, &sc->sc_sgmap, "tc_sgmap", dmat->_wbase,
    324   1.8  flxd 	    dmat->_wsize, pte, 0);
    325   1.8  flxd 
    326   1.8  flxd 	tc_vsbus_dmat = dmat;
    327   1.8  flxd 
    328   1.8  flxd 	return 0;
    329   1.8  flxd }
    330   1.1  matt 
    331   1.1  matt static bus_dma_tag_t
    332   1.8  flxd tc_vsbus_get_dma_tag(int slotno)
    333   1.1  matt {
    334   1.8  flxd 
    335   1.8  flxd 	return tc_vsbus_dmat;
    336   1.8  flxd }
    337   1.8  flxd 
    338   1.8  flxd static void
    339   1.8  flxd tc_vsbus_intr(void *arg)
    340   1.8  flxd {
    341   1.8  flxd 	struct tc_vsbus_softc * const sc = arg;
    342   1.8  flxd 	bus_space_tag_t bst = sc->sc_bst;
    343   1.8  flxd 	bus_space_handle_t bsh = sc->sc_bsh_csr;
    344   1.8  flxd 	uint32_t csr;
    345   1.8  flxd 
    346   1.8  flxd 	sc->sc_ev.ev_count++;
    347   1.8  flxd 
    348   1.8  flxd 	csr = bus_space_read_4(bst, bsh, 0);
    349   1.8  flxd 	if (__predict_true((csr & KA4x_TCA_CSR_TC_IRQ) == 0))	/* active low */
    350   1.8  flxd 		sc->sc_intr_func(sc->sc_intr_arg);
    351   1.8  flxd 
    352   1.8  flxd 	/* Clear possible timeout bit which asserts TC interrupt. */
    353   1.8  flxd 	csr = bus_space_read_4(bst, bsh, 0);
    354   1.8  flxd 	csr &= ~KA4x_TCA_CSR_TC_TMO;
    355   1.8  flxd 	bus_space_write_4(bst, bsh, 0, csr);
    356   1.1  matt }
    357   1.1  matt 
    358   1.1  matt static void
    359   1.8  flxd tc_vsbus_intr_establish(device_t dv, void *cookie, int level,
    360   1.8  flxd     int (*func)(void *), void *arg)
    361   1.1  matt {
    362   1.8  flxd 	struct tc_vsbus_softc * const sc = cookie;
    363   1.8  flxd 
    364   1.8  flxd 	sc->sc_intr_func = func;
    365   1.8  flxd 	sc->sc_intr_arg = arg;
    366   1.1  matt 
    367   1.8  flxd 	scb_vecalloc(sc->sc_cvec, tc_vsbus_intr, sc, SCB_ISTACK, &sc->sc_ev);
    368   1.1  matt }
    369   1.1  matt 
    370   1.1  matt static void
    371   1.8  flxd tc_vsbus_intr_disestablish(device_t dv, void *cookie)
    372   1.1  matt {
    373   1.8  flxd 
    374   1.8  flxd 	/* Do nothing. */
    375   1.1  matt }
    376   1.1  matt 
    377   1.1  matt static const struct evcnt *
    378   1.8  flxd tc_vsbus_intr_evcnt(device_t dv, void *cookie)
    379   1.1  matt {
    380   1.8  flxd 	struct tc_vsbus_softc * const sc = device_private(dv);
    381   1.8  flxd 
    382   1.8  flxd 	return &sc->sc_ev;
    383   1.1  matt }
    384   1.1  matt 
    385   1.8  flxd static int
    386   1.8  flxd vax_tc_bus_space_map(void *t, bus_addr_t pa, bus_size_t size, int cacheable,
    387   1.8  flxd     bus_space_handle_t *bshp, int f2)
    388   1.1  matt {
    389   1.8  flxd 
    390   1.8  flxd 	/* bus_space is pre-mapped, so "pa" is a virtual address already. */
    391   1.8  flxd 	*bshp = pa;
    392   1.1  matt 	return 0;
    393   1.1  matt }
    394   1.1  matt 
    395   1.8  flxd static int
    396   1.8  flxd vax_tc_bus_space_subregion(void *t, bus_space_handle_t h, bus_size_t o,
    397   1.8  flxd     bus_size_t s, bus_space_handle_t *hp)
    398   1.1  matt {
    399   1.1  matt 
    400   1.8  flxd 	*hp = h + o;
    401   1.8  flxd 	return 0;
    402   1.8  flxd }
    403   1.1  matt 
    404   1.8  flxd static void
    405   1.8  flxd vax_tc_bus_space_unmap(void *t, bus_space_handle_t h, bus_size_t size, int f)
    406   1.8  flxd {
    407   1.1  matt 
    408   1.8  flxd 	/* Do nothing. */
    409   1.8  flxd }
    410   1.1  matt 
    411   1.8  flxd static int
    412   1.8  flxd vax_tc_bus_space_alloc(void *t, bus_addr_t rs, bus_addr_t re, bus_size_t s,
    413   1.8  flxd     bus_size_t a, bus_size_t b, int f, bus_addr_t *ap, bus_space_handle_t *hp)
    414   1.8  flxd {
    415   1.1  matt 
    416   1.8  flxd 	panic("vax_tc_bus_space_alloc not implemented");
    417   1.8  flxd }
    418   1.1  matt 
    419   1.8  flxd static void
    420   1.8  flxd vax_tc_bus_space_free(void *t, bus_space_handle_t h, bus_size_t s)
    421   1.8  flxd {
    422   1.1  matt 
    423   1.8  flxd 	panic("vax_tc_bus_space_free not implemented");
    424   1.8  flxd }
    425   1.1  matt 
    426   1.8  flxd static paddr_t
    427   1.8  flxd vax_tc_bus_space_mmap(void *v, bus_addr_t addr, off_t off, int prot, int flags)
    428   1.8  flxd {
    429   1.8  flxd 	bus_addr_t rv;
    430   1.1  matt 
    431   1.8  flxd 	rv = addr + off;
    432   1.8  flxd 	return btop(rv);
    433   1.1  matt }
    434