1 /* $NetBSD: e500_autoconf.c,v 1.2 2011/01/18 01:02:52 matt Exp $ */ 2 3 /*- 4 * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Raytheon BBN Technologies Corp and Defense Advanced Research Projects 9 * Agency and which was developed by Matt Thomas of 3am Software Foundry. 10 * 11 * This material is based upon work supported by the Defense Advanced Research 12 * Projects Agency and Space and Naval Warfare Systems Center, Pacific, under 13 * Contract No. N66001-09-C-2073. 14 * Approved for Public Release, Distribution Unlimited 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted provided that the following conditions 18 * are met: 19 * 1. Redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer. 21 * 2. Redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 26 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 #include <sys/cdefs.h> 39 __KERNEL_RCSID(0, "$NetBSD: e500_autoconf.c,v 1.2 2011/01/18 01:02:52 matt Exp $"); 40 41 #include <sys/param.h> 42 #include <sys/cpu.h> 43 #include <sys/conf.h> 44 #include <sys/device.h> 45 #include <sys/systm.h> 46 47 #include <net/if.h> 48 #include <net/if_ether.h> 49 50 #define GLOBAL_PRIVATE 51 52 #include <powerpc/spr.h> 53 #include <powerpc/booke/spr.h> 54 55 #include <powerpc/booke/cpuvar.h> 56 #include <powerpc/booke/e500var.h> 57 #include <powerpc/booke/e500reg.h> 58 59 void 60 e500_device_register(device_t dev, void *aux) 61 { 62 } 63 64 /* 65 * Let's see if the DEVDISR bit encoded in the low 6 bits of cnl_flags is 66 * set. If it is, the device is disabled. 67 */ 68 bool 69 e500_device_disabled_p(uint32_t flags) 70 { 71 if ((flags-- & 63) == 0) 72 return false; 73 74 const uint32_t v = cpu_read_4(GLOBAL_BASE + DEVDISR); 75 return (v & (1 << (flags & 31))) != 0; 76 } 77 78 uint16_t 79 e500_get_svr(void) 80 { 81 uint32_t svr = (mfspr(SPR_SVR) >> 16) & ~8; 82 83 switch (svr) { 84 case SVR_MPC8543v1 >> 16: 85 return SVR_MPC8548v1 >> 16; 86 case SVR_MPC8541v1 >> 16: 87 return SVR_MPC8555v1 >> 16; 88 default: 89 return svr; 90 } 91 } 92 93 u_int 94 e500_truth_decode(u_int instance, uint32_t data, 95 const struct e500_truthtab *tab, size_t ntab, u_int default_value) 96 { 97 const uint16_t svr = e500_get_svr(); 98 99 for (u_int i = ntab; i-- > 0; tab++) { 100 #if 0 101 printf("%s: [%u] = %x/%x %u/%u (%#x & %#x) = %#x (%#x)\n", 102 __func__, i, tab->tt_svrhi, svr, 103 tab->tt_instance, instance, 104 data, tab->tt_mask, data & tab->tt_mask, tab->tt_value); 105 #endif 106 if (tab->tt_svrhi == svr 107 && tab->tt_instance == instance 108 && (data & tab->tt_mask) == tab->tt_value) 109 return tab->tt_result; 110 } 111 return default_value; 112 } 113 114 int 115 e500_cpunode_submatch(device_t parent, cfdata_t cf, const char *name, void *aux) 116 { 117 struct cpunode_softc * const psc = device_private(parent); 118 struct cpunode_attach_args * const cna = aux; 119 struct cpunode_locators * const cnl = &cna->cna_locs; 120 121 if (!board_info_get_bool("pq3") 122 || strcmp(cnl->cnl_name, name) != 0 123 || e500_device_disabled_p(cnl->cnl_flags) 124 || (cna->cna_childmask & psc->sc_children) 125 || (cf->cf_loc[CPUNODECF_INSTANCE] != CPUNODECF_INSTANCE_DEFAULT 126 && cf->cf_loc[CPUNODECF_INSTANCE] != cnl->cnl_instance)) 127 return 0; 128 129 return 1; 130 } 131