1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/param.h> 30 #include <sys/systm.h> 31 #include <sys/sysmacros.h> 32 #include <sys/sunddi.h> 33 #include <sys/esunddi.h> 34 #include <sys/platform_module.h> 35 #include <sys/errno.h> 36 37 /* 38 * 1535D+ IDE Interface Control Register Index 39 */ 40 #define IDEIC_RINDEX (0x58) 41 42 int (*p2get_mem_unum)(int, uint64_t, char *, int, int *); 43 44 void 45 startup_platform(void) 46 { 47 } 48 49 int 50 set_platform_tsb_spares(void) 51 { 52 return (0); 53 } 54 55 void 56 set_platform_defaults(void) 57 { 58 } 59 60 /* 61 * Definitions for accessing the pci config space of the ISA node 62 * of Southbridge. 63 */ 64 #define TACO_ISA_PATHNAME "/pci@1e,600000/isa@7" 65 static ddi_acc_handle_t isa_handle; /* handle for ISA pci space */ 66 67 68 void 69 load_platform_drivers(void) 70 { 71 dev_info_t *dip; /* dip of the ISA driver */ 72 73 /* 74 * Install power driver which handles the power button. 75 */ 76 if (i_ddi_attach_hw_nodes("power") != DDI_SUCCESS) 77 cmn_err(CE_WARN, "Failed to install \"power\" driver."); 78 (void) ddi_hold_driver(ddi_name_to_major("power")); 79 80 /* 81 * It is OK to return error because 'us' driver is not available 82 * in all clusters (e.g. missing in Core cluster). 83 */ 84 (void) i_ddi_attach_hw_nodes("us"); 85 86 if (i_ddi_attach_hw_nodes("grbeep") != DDI_SUCCESS) 87 cmn_err(CE_WARN, "Failed to install \"beep\" driver."); 88 89 90 /* 91 * mc-us3i must stay loaded for plat_get_mem_unum() 92 */ 93 if (i_ddi_attach_hw_nodes("mc-us3i") != DDI_SUCCESS) 94 cmn_err(CE_WARN, "mc-us3i driver failed to install"); 95 (void) ddi_hold_driver(ddi_name_to_major("mc-us3i")); 96 97 /* 98 * Install ISA driver. This is required for the southbridge IDE 99 * workaround - to reset the IDE channel during IDE bus reset. 100 * Panic the system in case ISA driver could not be loaded or 101 * any problem in accessing its pci config space. Since the register 102 * to reset the channel for IDE is in ISA config space!. 103 */ 104 105 dip = e_ddi_hold_devi_by_path(TACO_ISA_PATHNAME, 0); 106 if (dip == NULL) { 107 cmn_err(CE_PANIC, "Could not install the ISA driver\n"); 108 return; 109 } 110 111 if (pci_config_setup(dip, &isa_handle) != DDI_SUCCESS) { 112 cmn_err(CE_PANIC, "Could not get the config space of ISA\n"); 113 return; 114 } 115 } 116 117 /* 118 * This routine provides a workaround for a bug in the SB chip which 119 * can cause data corruption. Will be invoked from the IDE HBA driver for 120 * Acer SouthBridge at the time of IDE bus reset. 121 */ 122 /*ARGSUSED*/ 123 int 124 plat_ide_chipreset(dev_info_t *dip, int chno) 125 { 126 uint8_t val; 127 int ret = DDI_SUCCESS; 128 129 if (isa_handle == NULL) { 130 return (DDI_FAILURE); 131 } 132 133 val = pci_config_get8(isa_handle, IDEIC_RINDEX); 134 /* 135 * The dip passed as the argument is not used here. 136 * This will be needed for platforms which have multiple on-board SB, 137 * The dip passed will be used to match the corresponding ISA node. 138 */ 139 switch (chno) { 140 case 0: 141 /* 142 * First disable the primary channel then re-enable it. 143 * As per ALI no wait should be required in between have 144 * given 1ms delay in between to be on safer side. 145 * bit 2 of register 0x58 when 0 disable the channel 0. 146 * bit 2 of register 0x58 when 1 enables the channel 0. 147 */ 148 pci_config_put8(isa_handle, IDEIC_RINDEX, val & 0xFB); 149 drv_usecwait(1000); 150 pci_config_put8(isa_handle, IDEIC_RINDEX, val); 151 break; 152 case 1: 153 /* 154 * bit 3 of register 0x58 when 0 disable the channel 1. 155 * bit 3 of register 0x58 when 1 enables the channel 1. 156 */ 157 pci_config_put8(isa_handle, IDEIC_RINDEX, val & 0xF7); 158 drv_usecwait(1000); 159 pci_config_put8(isa_handle, IDEIC_RINDEX, val); 160 break; 161 default: 162 /* 163 * Unknown channel number passed. Return failure. 164 */ 165 ret = DDI_FAILURE; 166 } 167 168 return (ret); 169 } 170 171 172 /*ARGSUSED*/ 173 int 174 plat_cpu_poweron(struct cpu *cp) 175 { 176 return (ENOTSUP); /* not supported on this platform */ 177 } 178 179 /*ARGSUSED*/ 180 int 181 plat_cpu_poweroff(struct cpu *cp) 182 { 183 return (ENOTSUP); /* not supported on this platform */ 184 } 185 186 /*ARGSUSED*/ 187 void 188 plat_freelist_process(int mnode) 189 { 190 } 191 192 char *platform_module_list[] = { 193 "m1535ppm", 194 "jbusppm", 195 "ics951601", 196 "ppm", 197 (char *)0 198 }; 199 200 /*ARGSUSED*/ 201 void 202 plat_tod_fault(enum tod_fault_type tod_bad) 203 { 204 } 205 206 /*ARGSUSED*/ 207 int 208 plat_get_mem_unum(int synd_code, uint64_t flt_addr, int flt_bus_id, 209 int flt_in_memory, ushort_t flt_status, char *buf, int buflen, int *lenp) 210 { 211 if (flt_in_memory && (p2get_mem_unum != NULL)) 212 return (p2get_mem_unum(synd_code, P2ALIGN(flt_addr, 8), 213 buf, buflen, lenp)); 214 else 215 return (ENOTSUP); 216 } 217 218 /*ARGSUSED*/ 219 int 220 plat_get_cpu_unum(int cpuid, char *buf, int buflen, int *lenp) 221 { 222 if (snprintf(buf, buflen, "MB") >= buflen) { 223 return (ENOSPC); 224 } else { 225 *lenp = strlen(buf); 226 return (0); 227 } 228 } 229