schizo.c (227960) | schizo.c (230664) |
---|---|
1/*- 2 * Copyright (c) 1999, 2000 Matthew R. Green 3 * Copyright (c) 2001 - 2003 by Thomas Moestl <tmm@FreeBSD.org> 4 * Copyright (c) 2005 - 2011 by Marius Strobl <marius@FreeBSD.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 18 unchanged lines hidden (view full) --- 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * from: NetBSD: psycho.c,v 1.39 2001/10/07 20:30:41 eeh Exp 31 * from: FreeBSD: psycho.c 183152 2008-09-18 19:45:22Z marius 32 */ 33 34#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1999, 2000 Matthew R. Green 3 * Copyright (c) 2001 - 2003 by Thomas Moestl <tmm@FreeBSD.org> 4 * Copyright (c) 2005 - 2011 by Marius Strobl <marius@FreeBSD.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 18 unchanged lines hidden (view full) --- 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * from: NetBSD: psycho.c,v 1.39 2001/10/07 20:30:41 eeh Exp 31 * from: FreeBSD: psycho.c 183152 2008-09-18 19:45:22Z marius 32 */ 33 34#include <sys/cdefs.h> |
35__FBSDID("$FreeBSD: head/sys/sparc64/pci/schizo.c 227960 2011-11-24 23:48:22Z marius $"); | 35__FBSDID("$FreeBSD: head/sys/sparc64/pci/schizo.c 230664 2012-01-28 22:42:33Z marius $"); |
36 37/* 38 * Driver for `Schizo' Fireplane/Safari to PCI 2.1, `Tomatillo' JBus to 39 * PCI 2.2 and `XMITS' Fireplane/Safari to PCI-X bridges 40 */ 41 42#include "opt_ofw_pci.h" 43#include "opt_schizo.h" --- 129 unchanged lines hidden (view full) --- 173}; 174 175struct schizo_icarg { 176 struct schizo_softc *sica_sc; 177 bus_addr_t sica_map; 178 bus_addr_t sica_clr; 179}; 180 | 36 37/* 38 * Driver for `Schizo' Fireplane/Safari to PCI 2.1, `Tomatillo' JBus to 39 * PCI 2.2 and `XMITS' Fireplane/Safari to PCI-X bridges 40 */ 41 42#include "opt_ofw_pci.h" 43#include "opt_schizo.h" --- 129 unchanged lines hidden (view full) --- 173}; 174 175struct schizo_icarg { 176 struct schizo_softc *sica_sc; 177 bus_addr_t sica_map; 178 bus_addr_t sica_clr; 179}; 180 |
181#define SCHIZO_CDMA_TIMEOUT 1 /* 1 second per try */ 182#define SCHIZO_CDMA_TRIES 15 |
|
181#define SCHIZO_PERF_CNT_QLTY 100 182 183#define SCHIZO_SPC_BARRIER(spc, sc, offs, len, flags) \ 184 bus_barrier((sc)->sc_mem_res[(spc)], (offs), (len), (flags)) 185#define SCHIZO_SPC_READ_8(spc, sc, offs) \ 186 bus_read_8((sc)->sc_mem_res[(spc)], (offs)) 187#define SCHIZO_SPC_WRITE_8(spc, sc, offs, v) \ 188 bus_write_8((sc)->sc_mem_res[(spc)], (offs), (v)) --- 512 unchanged lines hidden (view full) --- 701 /* 702 * Some firmware versions include the CDMA interrupt 703 * at RID 4 but most don't. With the latter we add 704 * it ourselves at the spare RID 5. 705 */ 706 i = INTINO(bus_get_resource_start(dev, SYS_RES_IRQ, 707 4)); 708 if (i == STX_CDMA_A_INO || i == STX_CDMA_B_INO) { | 183#define SCHIZO_PERF_CNT_QLTY 100 184 185#define SCHIZO_SPC_BARRIER(spc, sc, offs, len, flags) \ 186 bus_barrier((sc)->sc_mem_res[(spc)], (offs), (len), (flags)) 187#define SCHIZO_SPC_READ_8(spc, sc, offs) \ 188 bus_read_8((sc)->sc_mem_res[(spc)], (offs)) 189#define SCHIZO_SPC_WRITE_8(spc, sc, offs, v) \ 190 bus_write_8((sc)->sc_mem_res[(spc)], (offs), (v)) --- 512 unchanged lines hidden (view full) --- 703 /* 704 * Some firmware versions include the CDMA interrupt 705 * at RID 4 but most don't. With the latter we add 706 * it ourselves at the spare RID 5. 707 */ 708 i = INTINO(bus_get_resource_start(dev, SYS_RES_IRQ, 709 4)); 710 if (i == STX_CDMA_A_INO || i == STX_CDMA_B_INO) { |
709 (void)schizo_get_intrmap(sc, i, NULL, 710 &sc->sc_cdma_clr); | 711 sc->sc_cdma_vec = INTMAP_VEC(sc->sc_ign, i); 712 (void)schizo_get_intrmap(sc, i, 713 &sc->sc_cdma_map, &sc->sc_cdma_clr); |
711 schizo_set_intr(sc, 4, i, schizo_cdma); 712 } else { 713 i = STX_CDMA_A_INO + sc->sc_half; | 714 schizo_set_intr(sc, 4, i, schizo_cdma); 715 } else { 716 i = STX_CDMA_A_INO + sc->sc_half; |
717 sc->sc_cdma_vec = INTMAP_VEC(sc->sc_ign, i); |
|
714 if (bus_set_resource(dev, SYS_RES_IRQ, 5, | 718 if (bus_set_resource(dev, SYS_RES_IRQ, 5, |
715 INTMAP_VEC(sc->sc_ign, i), 1) != 0) | 719 sc->sc_cdma_vec, 1) != 0) |
716 panic("%s: failed to add CDMA " 717 "interrupt", __func__); 718 j = schizo_intr_register(sc, i); 719 if (j != 0) 720 panic("%s: could not register " 721 "interrupt controller for CDMA " 722 "(%d)", __func__, j); | 720 panic("%s: failed to add CDMA " 721 "interrupt", __func__); 722 j = schizo_intr_register(sc, i); 723 if (j != 0) 724 panic("%s: could not register " 725 "interrupt controller for CDMA " 726 "(%d)", __func__, j); |
723 (void)schizo_get_intrmap(sc, i, NULL, 724 &sc->sc_cdma_clr); | 727 (void)schizo_get_intrmap(sc, i, 728 &sc->sc_cdma_map, &sc->sc_cdma_clr); |
725 schizo_set_intr(sc, 5, i, schizo_cdma); 726 } 727 } else { 728 if (sc->sc_mode == SCHIZO_MODE_XMS) 729 mtx_init(&sc->sc_sync_mtx, "pcib_sync_mtx", 730 NULL, MTX_SPIN); 731 sc->sc_sync_val = 1ULL << (STX_PCIERR_A_INO + 732 sc->sc_half); --- 250 unchanged lines hidden (view full) --- 983 return (FILTER_HANDLED); 984} 985 986static int 987schizo_cdma(void *arg) 988{ 989 struct schizo_softc *sc = arg; 990 | 729 schizo_set_intr(sc, 5, i, schizo_cdma); 730 } 731 } else { 732 if (sc->sc_mode == SCHIZO_MODE_XMS) 733 mtx_init(&sc->sc_sync_mtx, "pcib_sync_mtx", 734 NULL, MTX_SPIN); 735 sc->sc_sync_val = 1ULL << (STX_PCIERR_A_INO + 736 sc->sc_half); --- 250 unchanged lines hidden (view full) --- 987 return (FILTER_HANDLED); 988} 989 990static int 991schizo_cdma(void *arg) 992{ 993 struct schizo_softc *sc = arg; 994 |
991 atomic_store_rel_32(&sc->sc_cdma_state, SCHIZO_CDMA_STATE_RECEIVED); | 995 atomic_cmpset_32(&sc->sc_cdma_state, SCHIZO_CDMA_STATE_PENDING, 996 SCHIZO_CDMA_STATE_RECEIVED); |
992 return (FILTER_HANDLED); 993} 994 995static void 996schizo_iommu_init(struct schizo_softc *sc, int tsbsize, uint32_t dvmabase) 997{ 998 999 /* Punch in our copies. */ --- 148 unchanged lines hidden (view full) --- 1148} 1149 1150static void 1151schizo_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, bus_dmasync_op_t op) 1152{ 1153 struct timeval cur, end; 1154 struct schizo_iommu_state *sis = dt->dt_cookie; 1155 struct schizo_softc *sc = sis->sis_sc; | 997 return (FILTER_HANDLED); 998} 999 1000static void 1001schizo_iommu_init(struct schizo_softc *sc, int tsbsize, uint32_t dvmabase) 1002{ 1003 1004 /* Punch in our copies. */ --- 148 unchanged lines hidden (view full) --- 1153} 1154 1155static void 1156schizo_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, bus_dmasync_op_t op) 1157{ 1158 struct timeval cur, end; 1159 struct schizo_iommu_state *sis = dt->dt_cookie; 1160 struct schizo_softc *sc = sis->sis_sc; |
1156 int res; | 1161 int i, res; 1162#ifdef INVARIANTS 1163 register_t pil; 1164#endif |
1157 1158 if ((map->dm_flags & DMF_STREAMED) != 0) { 1159 iommu_dma_methods.dm_dmamap_sync(dt, map, op); 1160 return; 1161 } 1162 1163 if ((map->dm_flags & DMF_LOADED) == 0) 1164 return; 1165 1166 if ((op & BUS_DMASYNC_POSTREAD) != 0) { 1167 /* 1168 * Note that in order to allow this function to be called from 1169 * filters we would need to use a spin mutex for serialization 1170 * but given that these disable interrupts we have to emulate 1171 * one. 1172 */ | 1165 1166 if ((map->dm_flags & DMF_STREAMED) != 0) { 1167 iommu_dma_methods.dm_dmamap_sync(dt, map, op); 1168 return; 1169 } 1170 1171 if ((map->dm_flags & DMF_LOADED) == 0) 1172 return; 1173 1174 if ((op & BUS_DMASYNC_POSTREAD) != 0) { 1175 /* 1176 * Note that in order to allow this function to be called from 1177 * filters we would need to use a spin mutex for serialization 1178 * but given that these disable interrupts we have to emulate 1179 * one. 1180 */ |
1181 critical_enter(); 1182 KASSERT((rdpr(pstate) & PSTATE_IE) != 0, 1183 ("%s: interrupts disabled", __func__)); 1184 KASSERT((pil = rdpr(pil)) <= PIL_BRIDGE, 1185 ("%s: PIL too low (%ld)", __func__, pil)); |
|
1173 for (; atomic_cmpset_acq_32(&sc->sc_cdma_state, 1174 SCHIZO_CDMA_STATE_IDLE, SCHIZO_CDMA_STATE_PENDING) == 0;) 1175 ; | 1186 for (; atomic_cmpset_acq_32(&sc->sc_cdma_state, 1187 SCHIZO_CDMA_STATE_IDLE, SCHIZO_CDMA_STATE_PENDING) == 0;) 1188 ; |
1176 SCHIZO_PCI_WRITE_8(sc, sc->sc_cdma_clr, INTCLR_RECEIVED); 1177 microuptime(&cur); 1178 end.tv_sec = 15; 1179 end.tv_usec = 0; 1180 timevaladd(&end, &cur); 1181 for (; (res = atomic_cmpset_rel_32(&sc->sc_cdma_state, 1182 SCHIZO_CDMA_STATE_RECEIVED, SCHIZO_CDMA_STATE_IDLE)) == 1183 0 && timevalcmp(&cur, &end, <=);) | 1189 SCHIZO_PCI_WRITE_8(sc, sc->sc_cdma_map, 1190 INTMAP_ENABLE(sc->sc_cdma_vec, PCPU_GET(mid))); 1191 for (i = 0; i < SCHIZO_CDMA_TRIES; i++) { 1192 if (i > 0) 1193 printf("%s: try %d\n", __func__, i); 1194 SCHIZO_PCI_WRITE_8(sc, sc->sc_cdma_clr, 1195 INTCLR_RECEIVED); |
1184 microuptime(&cur); | 1196 microuptime(&cur); |
1197 end.tv_sec = SCHIZO_CDMA_TIMEOUT; 1198 end.tv_usec = 0; 1199 timevaladd(&end, &cur); 1200 for (; (res = atomic_cmpset_rel_32(&sc->sc_cdma_state, 1201 SCHIZO_CDMA_STATE_RECEIVED, 1202 SCHIZO_CDMA_STATE_IDLE)) == 0 && 1203 timevalcmp(&cur, &end, <=);) 1204 microuptime(&cur); 1205 if (res != 0) 1206 break; 1207 } |
|
1185 if (res == 0) 1186 panic("%s: DMA does not sync", __func__); | 1208 if (res == 0) 1209 panic("%s: DMA does not sync", __func__); |
1210 critical_exit(); |
|
1187 } 1188 1189 if ((op & BUS_DMASYNC_PREWRITE) != 0) 1190 membar(Sync); 1191} 1192 1193#define VIS_BLOCKSIZE 64 1194 --- 152 unchanged lines hidden (view full) --- 1347 * the MI PCI code... 1348 * XXX: This may return a resource that is out of the 1349 * range that was specified. Is this correct...? 1350 */ 1351 if (start != end) 1352 panic("%s: XXX: interrupt range", __func__); 1353 start = end = INTMAP_VEC(sc->sc_ign, end); 1354 return (bus_generic_alloc_resource(bus, child, type, rid, | 1211 } 1212 1213 if ((op & BUS_DMASYNC_PREWRITE) != 0) 1214 membar(Sync); 1215} 1216 1217#define VIS_BLOCKSIZE 64 1218 --- 152 unchanged lines hidden (view full) --- 1371 * the MI PCI code... 1372 * XXX: This may return a resource that is out of the 1373 * range that was specified. Is this correct...? 1374 */ 1375 if (start != end) 1376 panic("%s: XXX: interrupt range", __func__); 1377 start = end = INTMAP_VEC(sc->sc_ign, end); 1378 return (bus_generic_alloc_resource(bus, child, type, rid, |
1355 start, end, count, flags)); | 1379 start, end, count, flags)); |
1356 case SYS_RES_MEMORY: 1357 rm = &sc->sc_pci_mem_rman; 1358 break; 1359 case SYS_RES_IOPORT: 1360 rm = &sc->sc_pci_io_rman; 1361 break; 1362 default: 1363 return (NULL); --- 137 unchanged lines hidden --- | 1380 case SYS_RES_MEMORY: 1381 rm = &sc->sc_pci_mem_rman; 1382 break; 1383 case SYS_RES_IOPORT: 1384 rm = &sc->sc_pci_io_rman; 1385 break; 1386 default: 1387 return (NULL); --- 137 unchanged lines hidden --- |