1 /* $NetBSD: autoconf.c,v 1.5 2026/09/28 20:41:00 rkujawa Exp $ */ 2 3 /* 4 * Copyright (c) 2012, 2014, 2024, 2026 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Radoslaw Kujawa. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 /* 32 * Copyright 2004 Shigeyuki Fukushima. 33 * All rights reserved. 34 * 35 * Written by Shigeyuki Fukushima for The NetBSD Project. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above 43 * copyright notice, this list of conditions and the following 44 * disclaimer in the documentation and/or other materials provided 45 * with the distribution. 46 * 3. The name of the author may not be used to endorse or promote 47 * products derived from this software without specific prior 48 * written permission. 49 * 50 * THIS SOFTWARE IS PROVIDED THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 51 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 52 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 53 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE 54 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 55 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 56 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 57 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 58 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 60 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 61 * DAMAGE. 62 */ 63 64 /* 65 * Autoconfiguration for the ACube Sam460ex (AMCC 460EX). 66 * Modeled on evbppc/obs405/obs600_autoconf.c. 67 */ 68 69 #include <sys/cdefs.h> 70 __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.5 2026/09/28 20:41:00 rkujawa Exp $"); 71 72 #include <sys/param.h> 73 #include <sys/device.h> 74 #include <sys/disklabel.h> 75 #include <sys/intr.h> 76 #include <sys/systm.h> 77 78 #include <machine/sam460ex.h> 79 80 #include <powerpc/ibm4xx/amcc460ex.h> 81 #include <powerpc/ibm4xx/cpu.h> 82 #include <powerpc/ibm4xx/dcr4xx.h> 83 #include <powerpc/ibm4xx/pci_machdep.h> 84 85 #include <dev/pci/pcivar.h> 86 #include <dev/pci/pcireg.h> 87 #include <dev/pci/pcidevs.h> 88 89 /* PCIe INTA of a root port. */ 90 int 91 pciex_inta_irq(int port) 92 { 93 return SAM460EX_IRQ_PCIE_INTA(port); 94 } 95 96 #define UIC_IRQ_BIT(irq) __BIT(31 - ((irq) % SAM460EX_UIC_NIRQ)) 97 #define UIC_IRQ_BITS(lo, hi) __BITS(31 - ((hi) % SAM460EX_UIC_NIRQ), \ 98 31 - ((lo) % SAM460EX_UIC_NIRQ)) 99 #define UIC3_PCIE_INTX UIC_IRQ_BITS(SAM460EX_IRQ_PCIE_INTX, \ 100 SAM460EX_IRQ_PCIE_INTX + SAM460EX_NPCIE_INTX - 1) 101 #define UIC3_SM502 UIC_IRQ_BIT(SAM460EX_IRQ_SM502) 102 103 /* when console is on a PCI card, see device_register() */ 104 static device_t sam460ex_pci_console_dev; 105 static int sam460ex_pci_console_bdf[3]; 106 static pcireg_t sam460ex_pci_console_id; 107 108 /* 109 * Determine device configuration for a machine. 110 */ 111 void 112 cpu_configure(void) 113 { 114 115 /* UIC1 */ 116 mtdcr(DCR_UIC1_BASE + DCR_UIC_PR, 117 mfdcr(DCR_UIC1_BASE + DCR_UIC_PR) & ~UIC_IRQ_BIT(SAM460EX_IRQ_PCI_INTX)); 118 mtdcr(DCR_UIC1_BASE + DCR_UIC_TR, 119 mfdcr(DCR_UIC1_BASE + DCR_UIC_TR) & ~UIC_IRQ_BIT(SAM460EX_IRQ_PCI_INTX)); 120 mtdcr(DCR_UIC1_BASE + DCR_UIC_SR, UIC_IRQ_BIT(SAM460EX_IRQ_PCI_INTX)); 121 /* UIC3 */ 122 mtdcr(DCR_UIC3_BASE + DCR_UIC_PR, 123 (mfdcr(DCR_UIC3_BASE + DCR_UIC_PR) | UIC3_PCIE_INTX) & ~UIC3_SM502); 124 mtdcr(DCR_UIC3_BASE + DCR_UIC_TR, 125 mfdcr(DCR_UIC3_BASE + DCR_UIC_TR) & ~(UIC3_PCIE_INTX | UIC3_SM502)); 126 mtdcr(DCR_UIC3_BASE + DCR_UIC_SR, UIC3_PCIE_INTX | UIC3_SM502); 127 128 /* Cascaded UICs: irq = 32 * n + input. */ 129 intr_init(); 130 pic_add(&pic_uic1); 131 pic_add(&pic_uic2); 132 pic_add(&pic_uic3); 133 134 if (config_rootfound("plb", NULL) == NULL) 135 panic("configure: mainbus not configured"); 136 137 if (sam460ex_pci_console_dev != NULL) 138 aprint_normal("sam460ex: console=pci: %s at %d:%d:%d " 139 "(vendor 0x%04x product 0x%04x)\n", 140 device_xname(sam460ex_pci_console_dev), 141 sam460ex_pci_console_bdf[0], sam460ex_pci_console_bdf[1], 142 sam460ex_pci_console_bdf[2], 143 PCI_VENDOR(sam460ex_pci_console_id), 144 PCI_PRODUCT(sam460ex_pci_console_id)); 145 else if (sam460ex_console == SAM460EX_CONS_PCI) 146 printf("sam460ex: console=pci: no suitable PCI display found, " 147 "using serial\n"); 148 149 pic_finish_setup(); 150 151 genppc_cpu_configure(); 152 } 153 154 void 155 device_register(device_t dev, void *aux) 156 { 157 158 ibm4xx_device_register(dev, aux, sam460ex_com_freq()); 159 160 /* console=sm502: the on-board SM502 voyagerfb becomes the console */ 161 if (sam460ex_console == SAM460EX_CONS_SM502 && 162 device_is_a(dev, "voyagerfb")) 163 prop_dictionary_set_bool(device_properties(dev), 164 "is_console", true); 165 166 /* console=pci: find first/matching non-SM502 PCI display */ 167 if (sam460ex_console == SAM460EX_CONS_PCI && 168 sam460ex_pci_console_dev == NULL && device_parent(dev) != NULL && 169 device_is_a(device_parent(dev), "pci")) { 170 struct pci_attach_args *pa = aux; 171 const int *bdf = sam460ex_console_pci_bdf; 172 173 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY && 174 !(PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SILMOTION && 175 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SILMOTION_SM502) && 176 (bdf[0] == -1 || bdf[0] == pa->pa_bus) && 177 (bdf[1] == -1 || bdf[1] == pa->pa_device) && 178 (bdf[2] == -1 || bdf[2] == pa->pa_function)) { 179 /* announced later; a print here splits the "at" line */ 180 sam460ex_pci_console_dev = dev; 181 sam460ex_pci_console_bdf[0] = pa->pa_bus; 182 sam460ex_pci_console_bdf[1] = pa->pa_device; 183 sam460ex_pci_console_bdf[2] = pa->pa_function; 184 sam460ex_pci_console_id = pa->pa_id; 185 prop_dictionary_set_bool(device_properties(dev), 186 "is_console", true); 187 } 188 } 189 190 /* Match a root= from the bootargs */ 191 if (bootspec != NULL) { 192 size_t len = strlen(bootspec); 193 int part = 0; 194 195 if (len > 1 && bootspec[len - 1] >= 'a' && 196 bootspec[len - 1] < 'a' + MAXPARTITIONS && 197 bootspec[len - 2] >= '0' && bootspec[len - 2] <= '9') { 198 part = bootspec[len - 1] - 'a'; 199 len--; 200 } 201 if (strncmp(device_xname(dev), bootspec, len) == 0 && 202 device_xname(dev)[len] == '\0') { 203 booted_device = dev; 204 booted_partition = part; 205 } 206 } 207 } 208 209