Mon Nov 30 05:00:58 2009 UTC ()
convert pci_intr_map() into a chipset tag function pointer, and implement
the schizo version slightly differently.

pull out the schizo's IGN from the upaid, not the apparently broken device
ID register.  from openbsd.

with this i appear to have valid working interrupts on the SB2500.

tested on U60 and SB2500.

XXX: we can probably kill (*spc_find_ino)() now that pci_intr_map() itself
XXX: is no longer a first class function.


(mrg)
diff -r1.64 -r1.65 src/sys/arch/sparc64/dev/pci_machdep.c
diff -r1.96 -r1.97 src/sys/arch/sparc64/dev/psycho.c
diff -r1.9 -r1.10 src/sys/arch/sparc64/dev/schizo.c
diff -r1.22 -r1.23 src/sys/arch/sparc64/include/pci_machdep.h

cvs diff -r1.64 -r1.65 src/sys/arch/sparc64/dev/pci_machdep.c (expand / switch to unified diff)

--- src/sys/arch/sparc64/dev/pci_machdep.c 2009/11/28 21:32:46 1.64
+++ src/sys/arch/sparc64/dev/pci_machdep.c 2009/11/30 05:00:58 1.65
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: pci_machdep.c,v 1.64 2009/11/28 21:32:46 mrg Exp $ */ 1/* $NetBSD: pci_machdep.c,v 1.65 2009/11/30 05:00:58 mrg Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1999, 2000 Matthew R. Green 4 * Copyright (c) 1999, 2000 Matthew R. Green
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -21,27 +21,27 @@ @@ -21,27 +21,27 @@
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29/* 29/*
30 * functions expected by the MI PCI code. 30 * functions expected by the MI PCI code.
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.64 2009/11/28 21:32:46 mrg Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.65 2009/11/30 05:00:58 mrg Exp $");
35 35
36#include <sys/types.h> 36#include <sys/types.h>
37#include <sys/param.h> 37#include <sys/param.h>
38#include <sys/time.h> 38#include <sys/time.h>
39#include <sys/systm.h> 39#include <sys/systm.h>
40#include <sys/errno.h> 40#include <sys/errno.h>
41#include <sys/device.h> 41#include <sys/device.h>
42#include <sys/malloc.h> 42#include <sys/malloc.h>
43 43
44#define _SPARC_BUS_DMA_PRIVATE 44#define _SPARC_BUS_DMA_PRIVATE
45#include <machine/bus.h> 45#include <machine/bus.h>
46#include <machine/autoconf.h> 46#include <machine/autoconf.h>
47#include <machine/openfirm.h> 47#include <machine/openfirm.h>
@@ -365,69 +365,26 @@ sparc64_pci_enumerate_bus(struct pci_sof @@ -365,69 +365,26 @@ sparc64_pci_enumerate_bus(struct pci_sof
365 bhlc &= ~((PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT) | 365 bhlc &= ~((PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT) |
366 (PCI_CACHELINE_MASK << PCI_CACHELINE_SHIFT)); 366 (PCI_CACHELINE_MASK << PCI_CACHELINE_SHIFT));
367 bhlc |= (lt << PCI_LATTIMER_SHIFT) | 367 bhlc |= (lt << PCI_LATTIMER_SHIFT) |
368 (cl << PCI_CACHELINE_SHIFT); 368 (cl << PCI_CACHELINE_SHIFT);
369 pci_conf_write(pc, tag, PCI_BHLC_REG, bhlc); 369 pci_conf_write(pc, tag, PCI_BHLC_REG, bhlc);
370 370
371 ret = pci_probe_device(sc, tag, match, pap); 371 ret = pci_probe_device(sc, tag, match, pap);
372 if (match != NULL && ret != 0) 372 if (match != NULL && ret != 0)
373 return (ret); 373 return (ret);
374 } 374 }
375 return (0); 375 return (0);
376} 376}
377 377
378/* 
379 * interrupt mapping foo. 
380 * XXX: how does this deal with multiple interrupts for a device? 
381 */ 
382int 
383pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) 
384{ 
385 pcitag_t tag = pa->pa_tag; 
386 int interrupts, *intp; 
387 int len, node = PCITAG_NODE(tag); 
388 char devtype[30]; 
389 
390 intp = &interrupts; 
391 len = 1; 
392 if (prom_getprop(node, "interrupts", sizeof(interrupts), 
393 &len, &intp) != 0 || len != 1) { 
394 DPRINTF(SPDB_INTMAP, 
395 ("pci_intr_map: could not read interrupts\n")); 
396 return (ENODEV); 
397 } 
398 
399 if (OF_mapintr(node, &interrupts, sizeof(interrupts),  
400 sizeof(interrupts)) < 0) { 
401 printf("OF_mapintr failed\n"); 
402 KASSERT(pa->pa_pc->spc_find_ino); 
403 pa->pa_pc->spc_find_ino(pa, &interrupts); 
404 } 
405 DPRINTF(SPDB_INTMAP, ("OF_mapintr() gave %x\n", interrupts)); 
406 
407 /* Try to find an IPL for this type of device. */ 
408 prom_getpropstringA(node, "device_type", devtype, sizeof(devtype)); 
409 for (len = 0; intrmap[len].in_class != NULL; len++) 
410 if (strcmp(intrmap[len].in_class, devtype) == 0) { 
411 interrupts |= INTLEVENCODE(intrmap[len].in_lev); 
412 DPRINTF(SPDB_INTMAP, ("reset to %x\n", interrupts)); 
413 break; 
414 } 
415 
416 /* XXXX -- we use the ino. What if there is a valid IGN? */ 
417 *ihp = interrupts; 
418 return (0); 
419} 
420 
421const char * 378const char *
422pci_intr_string(pci_chipset_tag_t pc, pci_intr_handle_t ih) 379pci_intr_string(pci_chipset_tag_t pc, pci_intr_handle_t ih)
423{ 380{
424 static char str[16]; 381 static char str[16];
425 382
426 sprintf(str, "ivec %x", ih); 383 sprintf(str, "ivec %x", ih);
427 DPRINTF(SPDB_INTR, ("pci_intr_string: returning %s\n", str)); 384 DPRINTF(SPDB_INTR, ("pci_intr_string: returning %s\n", str));
428 385
429 return (str); 386 return (str);
430} 387}
431 388
432const struct evcnt * 389const struct evcnt *
433pci_intr_evcnt(pci_chipset_tag_t pc, pci_intr_handle_t ih) 390pci_intr_evcnt(pci_chipset_tag_t pc, pci_intr_handle_t ih)

cvs diff -r1.96 -r1.97 src/sys/arch/sparc64/dev/psycho.c (expand / switch to unified diff)

--- src/sys/arch/sparc64/dev/psycho.c 2009/11/27 22:31:29 1.96
+++ src/sys/arch/sparc64/dev/psycho.c 2009/11/30 05:00:58 1.97
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: psycho.c,v 1.96 2009/11/27 22:31:29 mrg Exp $ */ 1/* $NetBSD: psycho.c,v 1.97 2009/11/30 05:00:58 mrg Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1999, 2000 Matthew R. Green 4 * Copyright (c) 1999, 2000 Matthew R. Green
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -45,27 +45,27 @@ @@ -45,27 +45,27 @@
45 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 45 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
46 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 46 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
47 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 47 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
48 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 48 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
49 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 49 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 50 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
51 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 51 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
52 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 52 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * SUCH DAMAGE. 54 * SUCH DAMAGE.
55 */ 55 */
56 56
57#include <sys/cdefs.h> 57#include <sys/cdefs.h>
58__KERNEL_RCSID(0, "$NetBSD: psycho.c,v 1.96 2009/11/27 22:31:29 mrg Exp $"); 58__KERNEL_RCSID(0, "$NetBSD: psycho.c,v 1.97 2009/11/30 05:00:58 mrg Exp $");
59 59
60#include "opt_ddb.h" 60#include "opt_ddb.h"
61 61
62/* 62/*
63 * Support for `psycho' and `psycho+' UPA to PCI bridge and  63 * Support for `psycho' and `psycho+' UPA to PCI bridge and
64 * UltraSPARC IIi and IIe `sabre' PCI controllers. 64 * UltraSPARC IIi and IIe `sabre' PCI controllers.
65 */ 65 */
66 66
67#ifdef DEBUG 67#ifdef DEBUG
68#define PDB_PROM 0x01 68#define PDB_PROM 0x01
69#define PDB_BUSMAP 0x02 69#define PDB_BUSMAP 0x02
70#define PDB_INTR 0x04 70#define PDB_INTR 0x04
71#define PDB_INTMAP 0x08 71#define PDB_INTMAP 0x08
@@ -106,26 +106,28 @@ int psycho_debug = 0x0; @@ -106,26 +106,28 @@ int psycho_debug = 0x0;
106static pci_chipset_tag_t psycho_alloc_chipset(struct psycho_pbm *, int, 106static pci_chipset_tag_t psycho_alloc_chipset(struct psycho_pbm *, int,
107 pci_chipset_tag_t); 107 pci_chipset_tag_t);
108static struct extent *psycho_alloc_extent(struct psycho_pbm *, int, int, 108static struct extent *psycho_alloc_extent(struct psycho_pbm *, int, int,
109 const char *); 109 const char *);
110static void psycho_get_bus_range(int, int *); 110static void psycho_get_bus_range(int, int *);
111static void psycho_get_ranges(int, struct psycho_ranges **, int *); 111static void psycho_get_ranges(int, struct psycho_ranges **, int *);
112static void psycho_set_intr(struct psycho_softc *, int, void *, uint64_t *, 112static void psycho_set_intr(struct psycho_softc *, int, void *, uint64_t *,
113 uint64_t *); 113 uint64_t *);
114 114
115/* chipset handlers */ 115/* chipset handlers */
116static pcireg_t psycho_pci_conf_read(pci_chipset_tag_t, pcitag_t, int); 116static pcireg_t psycho_pci_conf_read(pci_chipset_tag_t, pcitag_t, int);
117static void psycho_pci_conf_write(pci_chipset_tag_t, pcitag_t, int, 117static void psycho_pci_conf_write(pci_chipset_tag_t, pcitag_t, int,
118 pcireg_t); 118 pcireg_t);
 119static int psycho_pci_intr_map(struct pci_attach_args *,
 120 pci_intr_handle_t *);
119static void *psycho_pci_intr_establish(pci_chipset_tag_t, 121static void *psycho_pci_intr_establish(pci_chipset_tag_t,
120 pci_intr_handle_t, 122 pci_intr_handle_t,
121 int, int (*)(void *), void *); 123 int, int (*)(void *), void *);
122static int psycho_pci_find_ino(struct pci_attach_args *, 124static int psycho_pci_find_ino(struct pci_attach_args *,
123 pci_intr_handle_t *); 125 pci_intr_handle_t *);
124 126
125/* Interrupt handlers */ 127/* Interrupt handlers */
126static int psycho_ue(void *); 128static int psycho_ue(void *);
127static int psycho_ce(void *); 129static int psycho_ce(void *);
128static int psycho_bus_a(void *); 130static int psycho_bus_a(void *);
129static int psycho_bus_b(void *); 131static int psycho_bus_b(void *);
130static int psycho_powerfail(void *); 132static int psycho_powerfail(void *);
131static int psycho_wakeup(void *); 133static int psycho_wakeup(void *);
@@ -741,26 +743,27 @@ psycho_power_button_pressed(void *arg) @@ -741,26 +743,27 @@ psycho_power_button_pressed(void *arg)
741static pci_chipset_tag_t 743static pci_chipset_tag_t
742psycho_alloc_chipset(struct psycho_pbm *pp, int node, pci_chipset_tag_t pc) 744psycho_alloc_chipset(struct psycho_pbm *pp, int node, pci_chipset_tag_t pc)
743{ 745{
744 pci_chipset_tag_t npc; 746 pci_chipset_tag_t npc;
745  747
746 npc = malloc(sizeof *npc, M_DEVBUF, M_NOWAIT); 748 npc = malloc(sizeof *npc, M_DEVBUF, M_NOWAIT);
747 if (npc == NULL) 749 if (npc == NULL)
748 panic("could not allocate pci_chipset_tag_t"); 750 panic("could not allocate pci_chipset_tag_t");
749 memcpy(npc, pc, sizeof *pc); 751 memcpy(npc, pc, sizeof *pc);
750 npc->cookie = pp; 752 npc->cookie = pp;
751 npc->rootnode = node; 753 npc->rootnode = node;
752 npc->spc_conf_read = psycho_pci_conf_read; 754 npc->spc_conf_read = psycho_pci_conf_read;
753 npc->spc_conf_write = psycho_pci_conf_write; 755 npc->spc_conf_write = psycho_pci_conf_write;
 756 npc->spc_intr_map = psycho_pci_intr_map;
754 npc->spc_intr_establish = psycho_pci_intr_establish; 757 npc->spc_intr_establish = psycho_pci_intr_establish;
755 npc->spc_find_ino = psycho_pci_find_ino; 758 npc->spc_find_ino = psycho_pci_find_ino;
756 759
757 return (npc); 760 return (npc);
758} 761}
759 762
760/* 763/*
761 * create extent for free bus space, then allocate assigned regions. 764 * create extent for free bus space, then allocate assigned regions.
762 */ 765 */
763static struct extent * 766static struct extent *
764psycho_alloc_extent(struct psycho_pbm *pp, int node, int ss, const char *name) 767psycho_alloc_extent(struct psycho_pbm *pp, int node, int ss, const char *name)
765{ 768{
766 struct psycho_registers *pa = NULL; 769 struct psycho_registers *pa = NULL;
@@ -1379,26 +1382,69 @@ psycho_pci_conf_write(pci_chipset_tag_t  @@ -1379,26 +1382,69 @@ psycho_pci_conf_write(pci_chipset_tag_t
1379 (long long)(sc->sc_configaddr._ptr + PCITAG_OFFSET(tag) + reg),  1382 (long long)(sc->sc_configaddr._ptr + PCITAG_OFFSET(tag) + reg),
1380 (int)PCITAG_OFFSET(tag) + reg)); 1383 (int)PCITAG_OFFSET(tag) + reg));
1381 1384
1382 /* If we don't know it, just punt it. */ 1385 /* If we don't know it, just punt it. */
1383 if (PCITAG_NODE(tag) == -1) { 1386 if (PCITAG_NODE(tag) == -1) {
1384 DPRINTF(PDB_CONF, ("pci_conf_write: bad addr")); 1387 DPRINTF(PDB_CONF, ("pci_conf_write: bad addr"));
1385 return; 1388 return;
1386 } 1389 }
1387  1390
1388 bus_space_write_4(sc->sc_configtag, sc->sc_configaddr,  1391 bus_space_write_4(sc->sc_configtag, sc->sc_configaddr,
1389 PCITAG_OFFSET(tag) + reg, data); 1392 PCITAG_OFFSET(tag) + reg, data);
1390} 1393}
1391 1394
 1395/*
 1396 * interrupt mapping foo.
 1397 * XXX: how does this deal with multiple interrupts for a device?
 1398 */
 1399int
 1400psycho_pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
 1401{
 1402 pcitag_t tag = pa->pa_tag;
 1403 int interrupts, *intp;
 1404 int len, node = PCITAG_NODE(tag);
 1405 char devtype[30];
 1406
 1407 intp = &interrupts;
 1408 len = 1;
 1409 if (prom_getprop(node, "interrupts", sizeof(interrupts),
 1410 &len, &intp) != 0 || len != 1) {
 1411 DPRINTF(PDB_INTMAP,
 1412 ("pci_intr_map: could not read interrupts\n"));
 1413 return (ENODEV);
 1414 }
 1415
 1416 if (OF_mapintr(node, &interrupts, sizeof(interrupts),
 1417 sizeof(interrupts)) < 0) {
 1418 printf("OF_mapintr failed\n");
 1419 KASSERT(pa->pa_pc->spc_find_ino);
 1420 pa->pa_pc->spc_find_ino(pa, &interrupts);
 1421 }
 1422 DPRINTF(PDB_INTMAP, ("OF_mapintr() gave %x\n", interrupts));
 1423
 1424 /* Try to find an IPL for this type of device. */
 1425 prom_getpropstringA(node, "device_type", devtype, sizeof(devtype));
 1426 for (len = 0; intrmap[len].in_class != NULL; len++)
 1427 if (strcmp(intrmap[len].in_class, devtype) == 0) {
 1428 interrupts |= INTLEVENCODE(intrmap[len].in_lev);
 1429 DPRINTF(PDB_INTMAP, ("reset to %x\n", interrupts));
 1430 break;
 1431 }
 1432
 1433 /* XXXX -- we use the ino. What if there is a valid IGN? */
 1434 *ihp = interrupts;
 1435 return (0);
 1436}
 1437
1392static void * 1438static void *
1393psycho_pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level, 1439psycho_pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level,
1394 int (*func)(void *), void *arg) 1440 int (*func)(void *), void *arg)
1395{ 1441{
1396 void *cookie; 1442 void *cookie;
1397 struct psycho_pbm *pp = (struct psycho_pbm *)pc->cookie; 1443 struct psycho_pbm *pp = (struct psycho_pbm *)pc->cookie;
1398 1444
1399 DPRINTF(PDB_INTR, ("%s: ih %lx; level %d", __func__, (u_long)ih, level)); 1445 DPRINTF(PDB_INTR, ("%s: ih %lx; level %d", __func__, (u_long)ih, level));
1400 cookie = bus_intr_establish(pp->pp_memt, ih, level, func, arg); 1446 cookie = bus_intr_establish(pp->pp_memt, ih, level, func, arg);
1401 1447
1402 DPRINTF(PDB_INTR, ("; returning handle %p\n", cookie)); 1448 DPRINTF(PDB_INTR, ("; returning handle %p\n", cookie));
1403 return (cookie); 1449 return (cookie);
1404} 1450}

cvs diff -r1.9 -r1.10 src/sys/arch/sparc64/dev/schizo.c (expand / switch to unified diff)

--- src/sys/arch/sparc64/dev/schizo.c 2009/11/27 22:31:29 1.9
+++ src/sys/arch/sparc64/dev/schizo.c 2009/11/30 05:00:58 1.10
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: schizo.c,v 1.9 2009/11/27 22:31:29 mrg Exp $ */ 1/* $NetBSD: schizo.c,v 1.10 2009/11/30 05:00:58 mrg Exp $ */
2/* $OpenBSD: schizo.c,v 1.55 2008/08/18 20:29:37 brad Exp $ */ 2/* $OpenBSD: schizo.c,v 1.55 2008/08/18 20:29:37 brad Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2002 Jason L. Wright (jason@thought.net) 5 * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
6 * Copyright (c) 2003 Henric Jungheim 6 * Copyright (c) 2003 Henric Jungheim
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -84,33 +84,33 @@ int schizo_pci_error(void *); @@ -84,33 +84,33 @@ int schizo_pci_error(void *);
84 84
85pci_chipset_tag_t schizo_alloc_chipset(struct schizo_pbm *, int, 85pci_chipset_tag_t schizo_alloc_chipset(struct schizo_pbm *, int,
86 pci_chipset_tag_t); 86 pci_chipset_tag_t);
87bus_space_tag_t schizo_alloc_mem_tag(struct schizo_pbm *); 87bus_space_tag_t schizo_alloc_mem_tag(struct schizo_pbm *);
88bus_space_tag_t schizo_alloc_io_tag(struct schizo_pbm *); 88bus_space_tag_t schizo_alloc_io_tag(struct schizo_pbm *);
89bus_space_tag_t schizo_alloc_config_tag(struct schizo_pbm *); 89bus_space_tag_t schizo_alloc_config_tag(struct schizo_pbm *);
90bus_space_tag_t schizo_alloc_bus_tag(struct schizo_pbm *, const char *, 90bus_space_tag_t schizo_alloc_bus_tag(struct schizo_pbm *, const char *,
91 int); 91 int);
92bus_dma_tag_t schizo_alloc_dma_tag(struct schizo_pbm *); 92bus_dma_tag_t schizo_alloc_dma_tag(struct schizo_pbm *);
93 93
94pcireg_t schizo_conf_read(pci_chipset_tag_t, pcitag_t, int); 94pcireg_t schizo_conf_read(pci_chipset_tag_t, pcitag_t, int);
95void schizo_conf_write(pci_chipset_tag_t, pcitag_t, int, pcireg_t); 95void schizo_conf_write(pci_chipset_tag_t, pcitag_t, int, pcireg_t);
96 96
97int schizo_intr_map(struct pci_attach_args *, pci_intr_handle_t *); 
98int schizo_bus_map(bus_space_tag_t t, bus_addr_t offset, bus_size_t size, 97int schizo_bus_map(bus_space_tag_t t, bus_addr_t offset, bus_size_t size,
99 int flags, vaddr_t unused, bus_space_handle_t *hp); 98 int flags, vaddr_t unused, bus_space_handle_t *hp);
100static paddr_t schizo_bus_mmap(bus_space_tag_t t, bus_addr_t paddr, 99static paddr_t schizo_bus_mmap(bus_space_tag_t t, bus_addr_t paddr,
101 off_t off, int prot, int flags); 100 off_t off, int prot, int flags);
102static void *schizo_intr_establish(bus_space_tag_t, int, int, int (*)(void *), 101static void *schizo_intr_establish(bus_space_tag_t, int, int, int (*)(void *),
103 void *, void(*)(void)); 102 void *, void(*)(void));
 103static int schizo_pci_intr_map(struct pci_attach_args *, pci_intr_handle_t *);
104static void *schizo_pci_intr_establish(pci_chipset_tag_t, pci_intr_handle_t, 104static void *schizo_pci_intr_establish(pci_chipset_tag_t, pci_intr_handle_t,
105 int, int (*)(void *), void *); 105 int, int (*)(void *), void *);
106static int schizo_pci_find_ino(struct pci_attach_args *, pci_intr_handle_t *); 106static int schizo_pci_find_ino(struct pci_attach_args *, pci_intr_handle_t *);
107static int schizo_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t, 107static int schizo_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t,
108 bus_size_t, int, bus_dmamap_t *); 108 bus_size_t, int, bus_dmamap_t *);
109 109
110int 110int
111schizo_match(struct device *parent, struct cfdata *match, void *aux) 111schizo_match(struct device *parent, struct cfdata *match, void *aux)
112{ 112{
113 struct mainbus_attach_args *ma = aux; 113 struct mainbus_attach_args *ma = aux;
114 char *str; 114 char *str;
115 115
116 if (strcmp(ma->ma_name, "pci") != 0) 116 if (strcmp(ma->ma_name, "pci") != 0)
@@ -126,50 +126,48 @@ schizo_match(struct device *parent, stru @@ -126,50 +126,48 @@ schizo_match(struct device *parent, stru
126 if (strcmp(str, "pci108e,8002") == 0) /* XMITS */ 126 if (strcmp(str, "pci108e,8002") == 0) /* XMITS */
127 return (1); 127 return (1);
128 if (strcmp(str, "pci108e,a801") == 0) /* Tomatillo */ 128 if (strcmp(str, "pci108e,a801") == 0) /* Tomatillo */
129 return (1); 129 return (1);
130 130
131 return (0); 131 return (0);
132} 132}
133 133
134void 134void
135schizo_attach(struct device *parent, struct device *self, void *aux) 135schizo_attach(struct device *parent, struct device *self, void *aux)
136{ 136{
137 struct schizo_softc *sc = (struct schizo_softc *)self; 137 struct schizo_softc *sc = (struct schizo_softc *)self;
138 struct mainbus_attach_args *ma = aux; 138 struct mainbus_attach_args *ma = aux;
139 uint64_t eccctrl, csr; 139 uint64_t eccctrl;
140 char *str; 140 char *str;
141 141
142 printf(": addr %lx", ma->ma_reg[0].ur_paddr); 142 printf(": addr %lx", ma->ma_reg[0].ur_paddr);
143 str = prom_getpropstring(ma->ma_node, "compatible"); 143 str = prom_getpropstring(ma->ma_node, "compatible");
144 if (strcmp(str, "pci108e,a801") == 0) 144 if (strcmp(str, "pci108e,a801") == 0)
145 sc->sc_tomatillo = 1; 145 sc->sc_tomatillo = 1;
146 146
147 sc->sc_node = ma->ma_node; 147 sc->sc_node = ma->ma_node;
148 sc->sc_dmat = ma->ma_dmatag; 148 sc->sc_dmat = ma->ma_dmatag;
149 sc->sc_bustag = ma->ma_bustag; 149 sc->sc_bustag = ma->ma_bustag;
150 sc->sc_ctrl = ma->ma_reg[1].ur_paddr - 0x10000UL; 150 sc->sc_ctrl = ma->ma_reg[1].ur_paddr - 0x10000UL;
151 sc->sc_reg0 = ma->ma_reg[0]; 151 sc->sc_reg0 = ma->ma_reg[0];
152 152
153 if (bus_space_map(sc->sc_bustag, sc->sc_ctrl, 153 if (bus_space_map(sc->sc_bustag, sc->sc_ctrl,
154 sizeof(struct schizo_regs), 0, 154 sizeof(struct schizo_regs), 0,
155 &sc->sc_ctrlh)) { 155 &sc->sc_ctrlh)) {
156 printf(": failed to map registers\n"); 156 printf(": failed to map registers\n");
157 return; 157 return;
158 } 158 }
159 159
160 csr = schizo_read(sc, SCZ_CONTROL_STATUS); 160 sc->sc_ign = INTIGN(ma->ma_upaid << INTMAP_IGN_SHIFT);
161 sc->sc_ign = ((csr & SCZ_CONTROL_STATUS_AID_MASK) >> 
162 SCZ_CONTROL_STATUS_AID_SHIFT); 
163 161
164 /* enable schizo ecc error interrupts */ 162 /* enable schizo ecc error interrupts */
165 eccctrl = schizo_read(sc, SCZ_ECCCTRL); 163 eccctrl = schizo_read(sc, SCZ_ECCCTRL);
166 eccctrl |= SCZ_ECCCTRL_EE_INTEN | 164 eccctrl |= SCZ_ECCCTRL_EE_INTEN |
167 SCZ_ECCCTRL_UE_INTEN | 165 SCZ_ECCCTRL_UE_INTEN |
168 SCZ_ECCCTRL_CE_INTEN; 166 SCZ_ECCCTRL_CE_INTEN;
169 schizo_write(sc, SCZ_ECCCTRL, eccctrl); 167 schizo_write(sc, SCZ_ECCCTRL, eccctrl);
170 168
171 schizo_init(sc); 169 schizo_init(sc);
172} 170}
173 171
174void 172void
175schizo_init(struct schizo_softc *sc) 173schizo_init(struct schizo_softc *sc)
@@ -577,26 +575,27 @@ schizo_alloc_dma_tag(struct schizo_pbm * @@ -577,26 +575,27 @@ schizo_alloc_dma_tag(struct schizo_pbm *
577pci_chipset_tag_t 575pci_chipset_tag_t
578schizo_alloc_chipset(struct schizo_pbm *pbm, int node, pci_chipset_tag_t pc) 576schizo_alloc_chipset(struct schizo_pbm *pbm, int node, pci_chipset_tag_t pc)
579{ 577{
580 pci_chipset_tag_t npc; 578 pci_chipset_tag_t npc;
581 579
582 npc = malloc(sizeof *npc, M_DEVBUF, M_NOWAIT); 580 npc = malloc(sizeof *npc, M_DEVBUF, M_NOWAIT);
583 if (npc == NULL) 581 if (npc == NULL)
584 panic("schizo: could not allocate pci_chipset_tag_t"); 582 panic("schizo: could not allocate pci_chipset_tag_t");
585 memcpy(npc, pc, sizeof *pc); 583 memcpy(npc, pc, sizeof *pc);
586 npc->cookie = pbm; 584 npc->cookie = pbm;
587 npc->rootnode = node; 585 npc->rootnode = node;
588 npc->spc_conf_read = schizo_conf_read; 586 npc->spc_conf_read = schizo_conf_read;
589 npc->spc_conf_write = schizo_conf_write; 587 npc->spc_conf_write = schizo_conf_write;
 588 npc->spc_intr_map = schizo_pci_intr_map;
590 npc->spc_intr_establish = schizo_pci_intr_establish; 589 npc->spc_intr_establish = schizo_pci_intr_establish;
591 npc->spc_find_ino = schizo_pci_find_ino; 590 npc->spc_find_ino = schizo_pci_find_ino;
592 return (npc); 591 return (npc);
593} 592}
594 593
595int 594int
596schizo_dmamap_create(bus_dma_tag_t t, bus_size_t size, 595schizo_dmamap_create(bus_dma_tag_t t, bus_size_t size,
597 int nsegments, bus_size_t maxsegsz, bus_size_t boundary, int flags, 596 int nsegments, bus_size_t maxsegsz, bus_size_t boundary, int flags,
598 bus_dmamap_t *dmamp) 597 bus_dmamap_t *dmamp)
599{ 598{
600 struct schizo_pbm *pbm = t->_cookie; 599 struct schizo_pbm *pbm = t->_cookie;
601 int error; 600 int error;
602 601
@@ -672,26 +671,71 @@ schizo_bus_mmap(bus_space_tag_t t, bus_a @@ -672,26 +671,71 @@ schizo_bus_mmap(bus_space_tag_t t, bus_a
672 if (sr != NULL) { 671 if (sr != NULL) {
673 paddr = BUS_ADDR(sr->phys_hi, sr->phys_lo + offset); 672 paddr = BUS_ADDR(sr->phys_hi, sr->phys_lo + offset);
674 DPRINTF(SDB_BUSMAP, ("%s: mapping paddr " 673 DPRINTF(SDB_BUSMAP, ("%s: mapping paddr "
675 "space %lx offset %lx paddr %qx\n", 674 "space %lx offset %lx paddr %qx\n",
676 __func__, (long)ss, (long)offset, 675 __func__, (long)ss, (long)offset,
677 (unsigned long long)paddr)); 676 (unsigned long long)paddr));
678 return (bus_space_mmap(sc->sc_bustag, paddr, off, 677 return (bus_space_mmap(sc->sc_bustag, paddr, off,
679 prot, flags)); 678 prot, flags));
680 } 679 }
681 DPRINTF(SDB_BUSMAP, ("%s: FAILED\n", __func__)); 680 DPRINTF(SDB_BUSMAP, ("%s: FAILED\n", __func__));
682 return (-1); 681 return (-1);
683} 682}
684 683
 684/*
 685 * interrupt mapping foo.
 686 * XXX: how does this deal with multiple interrupts for a device?
 687 */
 688int
 689schizo_pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
 690{
 691 pcitag_t tag = pa->pa_tag;
 692 struct schizo_pbm *pbm = pa->pa_pc->cookie;
 693 struct schizo_softc *sc = pbm->sp_sc;
 694 int interrupts, *intp;
 695 int len, node = PCITAG_NODE(tag);
 696 char devtype[30];
 697
 698 intp = &interrupts;
 699 len = 1;
 700 if (prom_getprop(node, "interrupts", sizeof(interrupts),
 701 &len, &intp) != 0 || len != 1) {
 702 DPRINTF(SDB_INTMAP,
 703 ("pci_intr_map: could not read interrupts\n"));
 704 return (ENODEV);
 705 }
 706
 707 if (OF_mapintr(node, &interrupts, sizeof(interrupts),
 708 sizeof(interrupts)) < 0) {
 709 printf("OF_mapintr failed\n");
 710 KASSERT(pa->pa_pc->spc_find_ino);
 711 pa->pa_pc->spc_find_ino(pa, &interrupts);
 712 }
 713 DPRINTF(SDB_INTMAP, ("OF_mapintr() gave %x\n", interrupts));
 714
 715 /* Try to find an IPL for this type of device. */
 716 prom_getpropstringA(node, "device_type", devtype, sizeof(devtype));
 717 for (len = 0; intrmap[len].in_class != NULL; len++)
 718 if (strcmp(intrmap[len].in_class, devtype) == 0) {
 719 interrupts |= INTLEVENCODE(intrmap[len].in_lev);
 720 DPRINTF(SDB_INTMAP, ("reset to %x\n", interrupts));
 721 break;
 722 }
 723
 724 *ihp = interrupts | sc->sc_ign;
 725 DPRINTF(SDB_INTMAP, ("returning IGN adjusted to %x\n", *ihp));
 726 return (0);
 727}
 728
685static void * 729static void *
686schizo_intr_establish(bus_space_tag_t t, int ihandle, int level, 730schizo_intr_establish(bus_space_tag_t t, int ihandle, int level,
687 int (*handler)(void *), void *arg, void (*fastvec)(void) /* ignored */) 731 int (*handler)(void *), void *arg, void (*fastvec)(void) /* ignored */)
688{ 732{
689 struct schizo_pbm *pbm = t->cookie; 733 struct schizo_pbm *pbm = t->cookie;
690 struct schizo_softc *sc = pbm->sp_sc; 734 struct schizo_softc *sc = pbm->sp_sc;
691 struct intrhand *ih = NULL; 735 struct intrhand *ih = NULL;
692 uint64_t mapoff, clroff; 736 uint64_t mapoff, clroff;
693 volatile uint64_t *intrmapptr = NULL, *intrclrptr = NULL; 737 volatile uint64_t *intrmapptr = NULL, *intrclrptr = NULL;
694 int ino; 738 int ino;
695 long vec; 739 long vec;
696 740
697 vec = INTVEC(ihandle); 741 vec = INTVEC(ihandle);

cvs diff -r1.22 -r1.23 src/sys/arch/sparc64/include/pci_machdep.h (expand / switch to unified diff)

--- src/sys/arch/sparc64/include/pci_machdep.h 2008/12/10 03:31:51 1.22
+++ src/sys/arch/sparc64/include/pci_machdep.h 2009/11/30 05:00:58 1.23
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: pci_machdep.h,v 1.22 2008/12/10 03:31:51 mrg Exp $ */ 1/* $NetBSD: pci_machdep.h,v 1.23 2009/11/30 05:00:58 mrg Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1999 Matthew R. Green 4 * Copyright (c) 1999 Matthew R. Green
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -57,54 +57,56 @@ struct pci_attach_args; @@ -57,54 +57,56 @@ struct pci_attach_args;
57typedef uint64_t pcitag_t;  57typedef uint64_t pcitag_t;
58 58
59typedef struct sparc_pci_chipset *pci_chipset_tag_t; 59typedef struct sparc_pci_chipset *pci_chipset_tag_t;
60typedef u_int pci_intr_handle_t; 60typedef u_int pci_intr_handle_t;
61 61
62struct sparc_pci_chipset { 62struct sparc_pci_chipset {
63 void *cookie; /* psycho_pbm/, but sssh! */ 63 void *cookie; /* psycho_pbm/, but sssh! */
64 int rootnode; /* PCI controller */ 64 int rootnode; /* PCI controller */
65 65
66 /* pci(9) interfaces */ 66 /* pci(9) interfaces */
67 pcireg_t (*spc_conf_read)(pci_chipset_tag_t, pcitag_t, int); 67 pcireg_t (*spc_conf_read)(pci_chipset_tag_t, pcitag_t, int);
68 void (*spc_conf_write)(pci_chipset_tag_t, pcitag_t, int, pcireg_t); 68 void (*spc_conf_write)(pci_chipset_tag_t, pcitag_t, int, pcireg_t);
69 69
 70 int (*spc_intr_map)(struct pci_attach_args *, pci_intr_handle_t *);
70 void *(*spc_intr_establish)(pci_chipset_tag_t, pci_intr_handle_t, int, int (*)(void *), void *); 71 void *(*spc_intr_establish)(pci_chipset_tag_t, pci_intr_handle_t, int, int (*)(void *), void *);
71 72
72 /* private interfaces */ 73 /* private interfaces */
73 int (*spc_find_ino)(struct pci_attach_args *, pci_intr_handle_t *); 74 int (*spc_find_ino)(struct pci_attach_args *, pci_intr_handle_t *);
74 75
75 int spc_busmax; 76 int spc_busmax;
76 struct spc_busnode { 77 struct spc_busnode {
77 int node; 78 int node;
78 int (*valid)(void *); 79 int (*valid)(void *);
79 void *arg; 80 void *arg;
80 } (*spc_busnode)[256]; 81 } (*spc_busnode)[256];
81}; 82};
82 83
83 84
84void pci_attach_hook(struct device *, struct device *, 85void pci_attach_hook(struct device *, struct device *,
85 struct pcibus_attach_args *); 86 struct pcibus_attach_args *);
86int pci_bus_maxdevs(pci_chipset_tag_t, int); 87int pci_bus_maxdevs(pci_chipset_tag_t, int);
87pcitag_t pci_make_tag(pci_chipset_tag_t, int, int, int); 88pcitag_t pci_make_tag(pci_chipset_tag_t, int, int, int);
88void pci_decompose_tag(pci_chipset_tag_t, pcitag_t, int *, int *, 89void pci_decompose_tag(pci_chipset_tag_t, pcitag_t, int *, int *,
89 int *); 90 int *);
90int pci_intr_map(struct pci_attach_args *, pci_intr_handle_t *); 
91const char *pci_intr_string(pci_chipset_tag_t, pci_intr_handle_t); 91const char *pci_intr_string(pci_chipset_tag_t, pci_intr_handle_t);
92const struct evcnt *pci_intr_evcnt(pci_chipset_tag_t, pci_intr_handle_t); 92const struct evcnt *pci_intr_evcnt(pci_chipset_tag_t, pci_intr_handle_t);
93void pci_intr_disestablish(pci_chipset_tag_t, void *); 93void pci_intr_disestablish(pci_chipset_tag_t, void *);
94 94
95int sparc64_pci_enumerate_bus(struct pci_softc *, const int *, 95int sparc64_pci_enumerate_bus(struct pci_softc *, const int *,
96 int (*)(struct pci_attach_args *), 96 int (*)(struct pci_attach_args *),
97 struct pci_attach_args *); 97 struct pci_attach_args *);
98#define PCI_MACHDEP_ENUMERATE_BUS sparc64_pci_enumerate_bus 98#define PCI_MACHDEP_ENUMERATE_BUS sparc64_pci_enumerate_bus
99 99
100#define pci_conf_read(pc, tag, reg) \ 100#define pci_conf_read(pc, tag, reg) \
101 ((pc)->spc_conf_read(pc, tag, reg)) 101 ((pc)->spc_conf_read(pc, tag, reg))
102#define pci_conf_write(pc, tag, reg, val) \ 102#define pci_conf_write(pc, tag, reg, val) \
103 ((pc)->spc_conf_write(pc, tag, reg, val)) 103 ((pc)->spc_conf_write(pc, tag, reg, val))
 104#define pci_intr_map(pa, handle) \
 105 ((pa)->pa_pc->spc_intr_map(pa, handle))
104#define pci_intr_establish(pc, handle, level, func, arg) \ 106#define pci_intr_establish(pc, handle, level, func, arg) \
105 ((pc)->spc_intr_establish(pc, handle, level, func, arg)) 107 ((pc)->spc_intr_establish(pc, handle, level, func, arg))
106 108
107/* SPARC specific PCI interfaces */ 109/* SPARC specific PCI interfaces */
108int sparc_pci_childspace(int); 110int sparc_pci_childspace(int);
109 111
110#endif /* _MACHINE_PCI_MACHDEP_H_ */ 112#endif /* _MACHINE_PCI_MACHDEP_H_ */