1/* $NetBSD: gbus.c,v 1.2 2024/03/06 05:33:09 thorpej Exp $ */ 2 3/* 4 * Copyright (c) 1997 by Matthew Jacob 5 * NASA AMES Research Center. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice immediately at the beginning of the file, without modification, 13 * this list of conditions, and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33/* 34 * Autoconfiguration and support routines for the Gbus: the internal 35 * bus on AlphaServer CPU modules. 36 */ 37 38#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 39 40__KERNEL_RCSID(0, "$NetBSD: gbus.c,v 1.2 2024/03/06 05:33:09 thorpej Exp $"); 41 42#include <sys/param.h> 43#include <sys/systm.h> 44#include <sys/device.h> 45 46#include <machine/rpb.h> 47#include <machine/pte.h> 48 49#include <alpha/gbus/gbusreg.h> 50#include <alpha/gbus/gbusvar.h> 51 52#include <alpha/tlsb/tlsbreg.h> 53#include <alpha/tlsb/tlsbvar.h> 54 55#include "locators.h" 56 57#define KV(_addr) ((void *)ALPHA_PHYS_TO_K0SEG((_addr))) 58 59struct gbus_softc { 60 device_t sc_dev; 61 int sc_tlsbnode; /* node on the TurboLaser */ 62}; 63 64static int gbusmatch(device_t, cfdata_t, void *); 65static void gbusattach(device_t, device_t, void *); 66 67CFATTACH_DECL_NEW(gbus, sizeof(struct gbus_softc), 68 gbusmatch, gbusattach, NULL, NULL); 69 70static int gbusprint(void *, const char *); 71 72static const struct gbus_attach_args gbus_children[] = { 73 { "zsc", NULL, GBUS_DUART0_OFFSET }, 74 { "zsc", NULL, GBUS_DUART1_OFFSET }, 75 { "mcclock", NULL, GBUS_CLOCK_OFFSET }, 76 { NULL, NULL, 0 }, 77}; 78 79static int 80gbusprint(void *aux, const char *pnp) 81{ 82 struct gbus_attach_args *ga = aux; 83 84 if (pnp) 85 aprint_normal("%s at %s", ga->ga_name, pnp); 86 aprint_normal(" offset 0x%lx", ga->ga_offset); 87 return (UNCONF); 88} 89 90static int 91gbusmatch(device_t parent, cfdata_t cf, void *aux) 92{ 93 struct tlsb_dev_attach_args *ta = aux; 94 95 /* 96 * Make sure we're looking for a Gbus. The Gbus only 97 * "exists" on the CPU module that holds the primary CPU. 98 * 99 * Compute which node this should exist on by dividing the 100 * primary CPU by 2 (since there are up to 2 CPUs per CPU 101 * module). 102 */ 103 if (TLDEV_ISCPU(ta->ta_dtype) && 104 ta->ta_node == (hwrpb->rpb_primary_cpu_id / 2)) 105 return (1); 106 107 return (0); 108} 109 110static void 111gbusattach(device_t parent, device_t self, void *aux) 112{ 113 struct gbus_softc *sc = device_private(self); 114 struct tlsb_dev_attach_args *ta = aux; 115 const struct gbus_attach_args *ga; 116 bus_space_tag_t iot = gbus_io_init(TLSB_GBUS_BASE); 117 int locs[GBUSCF_NLOCS]; 118 119 aprint_normal("\n"); 120 121 sc->sc_dev = self; 122 sc->sc_tlsbnode = ta->ta_node; 123 124 /* Attach the children. */ 125 for (ga = gbus_children; ga->ga_name != NULL; ga++) { 126 struct gbus_attach_args gaa = *ga; 127 gaa.ga_iot = iot; 128 locs[GBUSCF_OFFSET] = gaa.ga_offset; 129 config_found(self, &gaa, gbusprint, 130 CFARGS(.submatch = config_stdsubmatch, 131 .locators = locs)); 132 } 133} 134