1 1991 heppo /* 2 1991 heppo * CDDL HEADER START 3 1991 heppo * 4 1991 heppo * The contents of this file are subject to the terms of the 5 1991 heppo * Common Development and Distribution License (the "License"). 6 1991 heppo * You may not use this file except in compliance with the License. 7 1991 heppo * 8 1991 heppo * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 1991 heppo * or http://www.opensolaris.org/os/licensing. 10 1991 heppo * See the License for the specific language governing permissions 11 1991 heppo * and limitations under the License. 12 1991 heppo * 13 1991 heppo * When distributing Covered Code, include this CDDL HEADER in each 14 1991 heppo * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 1991 heppo * If applicable, add the following below this CDDL HEADER, with the 16 1991 heppo * fields enclosed by brackets "[]" replaced with your own identifying 17 1991 heppo * information: Portions Copyright [yyyy] [name of copyright owner] 18 1991 heppo * 19 1991 heppo * CDDL HEADER END 20 1991 heppo */ 21 1991 heppo 22 1991 heppo /* 23 5768 jm22469 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 1991 heppo * Use is subject to license terms. 25 1991 heppo */ 26 1991 heppo 27 1991 heppo #pragma ident "%Z%%M% %I% %E% SMI" 28 1991 heppo 29 1991 heppo #include <sys/promif_impl.h> 30 1991 heppo #include <sys/systm.h> 31 1991 heppo #include <sys/hypervisor_api.h> 32 5974 jm22469 #include <sys/consdev.h> 33 1991 heppo #ifndef _KMDB 34 1991 heppo #include <sys/kmem.h> 35 1991 heppo #endif 36 5974 jm22469 37 5974 jm22469 /* 38 5974 jm22469 * Definitions for using Polled I/O. 39 5974 jm22469 * 40 5974 jm22469 * The usage of Polled I/O is different when we are in kmdb. In that case, 41 5974 jm22469 * we can not directly invoke the polled I/O functions and we have to use 42 5974 jm22469 * the kmdb DPI interface. Also we don't need to enter/exit the polled I/O 43 5974 jm22469 * mode because this is already managed by kmdb when entering/exiting the 44 5974 jm22469 * debugger. 45 5974 jm22469 * 46 5974 jm22469 * When we are not in kmdb then we can directly call the polled I/O functions 47 5974 jm22469 * but we have to enter the polled I/O mode first. After using polled I/O 48 5974 jm22469 * functions we have to exit the polled I/O mode. Note that entering/exiting 49 5974 jm22469 * the polled I/O mode is time consuming so this should be avoided when 50 5974 jm22469 * possible. 51 5974 jm22469 */ 52 5974 jm22469 #ifdef _KMDB 53 5974 jm22469 extern struct cons_polledio *kmdb_kdi_get_polled_io(void); 54 5974 jm22469 extern uintptr_t kmdb_dpi_call(uintptr_t, uint_t, const uintptr_t *); 55 5974 jm22469 56 5974 jm22469 #define PROMIF_PIO (kmdb_kdi_get_polled_io()) 57 5974 jm22469 58 5974 jm22469 #define PROMIF_PIO_CALL1(fn, arg) \ 59 5974 jm22469 (kmdb_dpi_call((uintptr_t)fn, 1, (uintptr_t *)&arg)) 60 5974 jm22469 61 5974 jm22469 #define PROMIF_PIO_CALL2(fn, arg1, arg2) \ 62 5974 jm22469 { \ 63 5974 jm22469 uintptr_t args[2]; \ 64 5974 jm22469 args[0] = (uintptr_t)arg1; \ 65 5974 jm22469 args[1] = (uintptr_t)arg2; \ 66 5974 jm22469 (void) (kmdb_dpi_call((uintptr_t)fn, 2, (uintptr_t *)args)); \ 67 5974 jm22469 } 68 5974 jm22469 69 5974 jm22469 #define PROMIF_PIO_ENTER(pio) 70 5974 jm22469 #define PROMIF_PIO_EXIT(pio) 71 5974 jm22469 72 5974 jm22469 #else /* _KMDB */ 73 5974 jm22469 74 5974 jm22469 #define PROMIF_PIO (cons_polledio) 75 5974 jm22469 #define PROMIF_PIO_CALL1(fn, arg) (fn(arg)) 76 5974 jm22469 #define PROMIF_PIO_CALL2(fn, arg1, arg2) (fn(arg1, arg2)) 77 5974 jm22469 78 5974 jm22469 #define PROMIF_PIO_ENTER(pio) \ 79 5974 jm22469 if (pio->cons_polledio_enter != NULL) { \ 80 5974 jm22469 pio->cons_polledio_enter(pio->cons_polledio_argument); \ 81 5974 jm22469 } 82 5974 jm22469 83 5974 jm22469 #define PROMIF_PIO_EXIT(pio) \ 84 5974 jm22469 if (pio->cons_polledio_exit != NULL) { \ 85 5974 jm22469 pio->cons_polledio_exit(pio->cons_polledio_argument); \ 86 5974 jm22469 } 87 5974 jm22469 88 5974 jm22469 #endif /* _KMDB */ 89 1991 heppo 90 1991 heppo #define PROM_REG_TO_UNIT_ADDR(r) ((r) & ~(0xful << 28)) 91 1991 heppo 92 1991 heppo static pnode_t instance_to_package(ihandle_t ih); 93 1991 heppo 94 1991 heppo /* cached copies of IO params */ 95 1991 heppo static phandle_t pstdin; 96 1991 heppo static phandle_t pstdout; 97 1991 heppo 98 1991 heppo static ihandle_t istdin; 99 1991 heppo static ihandle_t istdout; 100 5974 jm22469 101 5974 jm22469 static struct cons_polledio *promif_polledio = NULL; 102 1991 heppo 103 1991 heppo int 104 1991 heppo promif_instance_to_package(void *p) 105 1991 heppo { 106 1991 heppo cell_t *ci = (cell_t *)p; 107 1991 heppo ihandle_t ih; 108 1991 heppo phandle_t ph; 109 1991 heppo 110 1991 heppo ih = p1275_cell2ihandle(ci[3]); 111 1991 heppo 112 1991 heppo ph = instance_to_package(ih); 113 1991 heppo 114 1991 heppo ci[4] = p1275_phandle2cell(ph); 115 1991 heppo 116 1991 heppo return (0); 117 5974 jm22469 } 118 5974 jm22469 119 5974 jm22469 /* This function is not used but it is convenient for debugging I/O problems */ 120 5974 jm22469 static void 121 5974 jm22469 /* LINTED */ 122 5974 jm22469 promif_hv_print(char *str) 123 5974 jm22469 { 124 5974 jm22469 size_t i, len = strlen(str); 125 5974 jm22469 126 5974 jm22469 for (i = 0; i < len; i++) { 127 5974 jm22469 while (hv_cnputchar((uint8_t)str[i]) == H_EWOULDBLOCK) 128 5974 jm22469 /* try forever */; 129 5974 jm22469 } 130 5974 jm22469 } 131 5974 jm22469 132 5974 jm22469 static void 133 5974 jm22469 promif_pio_enter(void) 134 5974 jm22469 { 135 5974 jm22469 ASSERT(promif_polledio == NULL); 136 5974 jm22469 137 5974 jm22469 promif_polledio = PROMIF_PIO; 138 5974 jm22469 ASSERT(promif_polledio != NULL); 139 5974 jm22469 140 5974 jm22469 PROMIF_PIO_ENTER(promif_polledio); 141 5974 jm22469 } 142 5974 jm22469 143 5974 jm22469 static void 144 5974 jm22469 promif_pio_exit(void) 145 5974 jm22469 { 146 5974 jm22469 ASSERT(promif_polledio != NULL); 147 5974 jm22469 148 5974 jm22469 PROMIF_PIO_EXIT(promif_polledio); 149 5974 jm22469 promif_polledio = NULL; 150 5974 jm22469 } 151 5974 jm22469 152 5974 jm22469 static int 153 5974 jm22469 promif_do_read(char *buf, size_t len, boolean_t wait) 154 5974 jm22469 { 155 5974 jm22469 int rlen; 156 5974 jm22469 int (*getchar)(cons_polledio_arg_t); 157 5974 jm22469 boolean_t (*ischar)(cons_polledio_arg_t); 158 5974 jm22469 cons_polledio_arg_t arg; 159 5974 jm22469 160 5974 jm22469 promif_pio_enter(); 161 5974 jm22469 162 5974 jm22469 if ((ischar = promif_polledio->cons_polledio_ischar) == NULL) 163 5974 jm22469 return (0); 164 5974 jm22469 if ((getchar = promif_polledio->cons_polledio_getchar) == NULL) 165 5974 jm22469 return (0); 166 5974 jm22469 167 5974 jm22469 arg = promif_polledio->cons_polledio_argument; 168 5974 jm22469 169 5974 jm22469 for (rlen = 0; rlen < len; ) { 170 5974 jm22469 if (PROMIF_PIO_CALL1(ischar, arg)) { 171 5974 jm22469 buf[rlen] = PROMIF_PIO_CALL1(getchar, arg); 172 5974 jm22469 rlen++; 173 5974 jm22469 continue; 174 5974 jm22469 } 175 5974 jm22469 176 5974 jm22469 if (!wait) 177 5974 jm22469 break; 178 5974 jm22469 } 179 5974 jm22469 180 5974 jm22469 promif_pio_exit(); 181 5974 jm22469 182 5974 jm22469 return (rlen); 183 5974 jm22469 } 184 5974 jm22469 185 5974 jm22469 static int 186 5974 jm22469 promif_do_write(char *buf, size_t len) 187 5974 jm22469 { 188 5974 jm22469 int rlen; 189 5974 jm22469 void (*putchar)(cons_polledio_arg_t, uchar_t); 190 5974 jm22469 cons_polledio_arg_t arg; 191 5974 jm22469 192 5974 jm22469 promif_pio_enter(); 193 5974 jm22469 194 5974 jm22469 if ((putchar = promif_polledio->cons_polledio_putchar) == NULL) 195 5974 jm22469 return (0); 196 5974 jm22469 197 5974 jm22469 arg = promif_polledio->cons_polledio_argument; 198 5974 jm22469 199 5974 jm22469 for (rlen = 0; rlen < len; rlen++) 200 5974 jm22469 PROMIF_PIO_CALL2(putchar, arg, buf[rlen]); 201 5974 jm22469 202 5974 jm22469 promif_pio_exit(); 203 5974 jm22469 204 5974 jm22469 return (rlen); 205 5974 jm22469 } 206 5974 jm22469 207 5974 jm22469 char 208 5974 jm22469 promif_getchar(void) 209 5974 jm22469 { 210 5974 jm22469 char c; 211 5974 jm22469 212 5974 jm22469 (void) promif_do_read(&c, 1, B_TRUE); 213 5974 jm22469 return (c); 214 1991 heppo } 215 1991 heppo 216 1991 heppo int 217 1991 heppo promif_write(void *p) 218 1991 heppo { 219 1991 heppo cell_t *ci = (cell_t *)p; 220 1991 heppo uint_t fd; 221 1991 heppo char *buf; 222 1991 heppo size_t len; 223 1991 heppo size_t rlen; 224 1991 heppo 225 1991 heppo ASSERT(ci[1] == 3); 226 1991 heppo 227 1991 heppo fd = p1275_cell2uint(ci[3]); 228 1991 heppo buf = p1275_cell2ptr(ci[4]); 229 1991 heppo len = p1275_cell2size(ci[5]); 230 1991 heppo 231 1991 heppo /* only support stdout (console) */ 232 1991 heppo ASSERT(fd == istdout); 233 1991 heppo 234 5974 jm22469 rlen = promif_do_write(buf, len); 235 1991 heppo 236 1991 heppo /* return the length written */ 237 1991 heppo ci[6] = p1275_size2cell(rlen); 238 1991 heppo 239 1991 heppo return (0); 240 1991 heppo } 241 1991 heppo 242 1991 heppo int 243 1991 heppo promif_read(void *p) 244 1991 heppo { 245 1991 heppo cell_t *ci = (cell_t *)p; 246 1991 heppo uint_t fd; 247 1991 heppo char *buf; 248 1991 heppo size_t len; 249 1991 heppo size_t rlen; 250 1991 heppo 251 1991 heppo ASSERT(ci[1] == 3); 252 1991 heppo 253 1991 heppo /* unpack arguments */ 254 1991 heppo fd = p1275_cell2uint(ci[3]); 255 1991 heppo buf = p1275_cell2ptr(ci[4]); 256 1991 heppo len = p1275_cell2size(ci[5]); 257 1991 heppo 258 1991 heppo /* only support stdin (console) */ 259 1991 heppo ASSERT(fd == istdin); 260 1991 heppo 261 5974 jm22469 rlen = promif_do_read(buf, len, B_FALSE); 262 1991 heppo 263 1991 heppo /* return the length read */ 264 1991 heppo ci[6] = p1275_size2cell(rlen); 265 1991 heppo 266 1991 heppo return (0); 267 1991 heppo } 268 1991 heppo 269 1991 heppo static pnode_t 270 1991 heppo instance_to_package(ihandle_t ih) 271 1991 heppo { 272 1991 heppo /* only support stdin and stdout */ 273 1991 heppo ASSERT((ih == istdin) || (ih == istdout)); 274 1991 heppo 275 1991 heppo if (ih == istdin) 276 1991 heppo return (pstdin); 277 1991 heppo 278 1991 heppo if (ih == istdout) 279 1991 heppo return (pstdout); 280 1991 heppo 281 1991 heppo return (OBP_BADNODE); 282 1991 heppo } 283 1991 heppo 284 1991 heppo #ifdef _KMDB 285 1991 heppo 286 1991 heppo void 287 1991 heppo promif_io_init(ihandle_t in, ihandle_t out, phandle_t pin, phandle_t pout) 288 1991 heppo { 289 1991 heppo istdin = in; 290 1991 heppo istdout = out; 291 1991 heppo pstdin = pin; 292 1991 heppo pstdout = pout; 293 1991 heppo } 294 1991 heppo 295 1991 heppo #else 296 1991 heppo 297 1991 heppo void 298 1991 heppo promif_io_init(void) 299 1991 heppo { 300 1991 heppo /* 301 1991 heppo * Cache the mapping between the stdin and stdout 302 1991 heppo * ihandles and their respective phandles. 303 1991 heppo */ 304 1991 heppo pstdin = prom_stdin_node(); 305 1991 heppo pstdout = prom_stdout_node(); 306 1991 heppo 307 1991 heppo istdin = prom_stdin_ihandle(); 308 1991 heppo istdout = prom_stdout_ihandle(); 309 1991 heppo } 310 1991 heppo 311 1991 heppo int 312 1991 heppo promif_instance_to_path(void *p) 313 1991 heppo { 314 1991 heppo cell_t *ci = (cell_t *)p; 315 1991 heppo pnode_t node; 316 1991 heppo ihandle_t ih; 317 1991 heppo char *buf; 318 1991 heppo int rlen; 319 1991 heppo char *regval; 320 1991 heppo uint_t *csaddr; 321 1991 heppo char name[OBP_MAXPROPNAME]; 322 1991 heppo char scratch[OBP_MAXPATHLEN]; 323 1991 heppo int rvlen; 324 1991 heppo 325 1991 heppo ih = p1275_cell2ihandle(ci[3]); 326 1991 heppo buf = p1275_cell2ptr(ci[4]); 327 1991 heppo 328 1991 heppo ci[6] = p1275_uint2cell(0); 329 1991 heppo 330 1991 heppo node = instance_to_package(ih); 331 1991 heppo 332 1991 heppo *buf = '\0'; 333 1991 heppo 334 1991 heppo while (node != prom_rootnode()) { 335 1991 heppo if (prom_getprop(node, OBP_NAME, name) == -1) { 336 1991 heppo prom_printf("instance_to_path: no name property " 337 1991 heppo "node=0x%x\n", node); 338 1991 heppo return (-1); 339 1991 heppo } 340 1991 heppo 341 1991 heppo /* construct the unit address from the 'reg' property */ 342 1991 heppo if ((rlen = prom_getproplen(node, OBP_REG)) == -1) 343 1991 heppo return (-1); 344 1991 heppo 345 5502 jm22469 /* 346 5502 jm22469 * Make sure we don't get dispatched onto a different 347 5502 jm22469 * cpu if we happen to sleep. See kern_postprom(). 348 5502 jm22469 */ 349 5768 jm22469 thread_affinity_set(curthread, CPU->cpu_id); 350 1991 heppo regval = kmem_zalloc(rlen, KM_SLEEP); 351 1991 heppo 352 1991 heppo (void) prom_getprop(node, OBP_REG, regval); 353 1991 heppo 354 1991 heppo csaddr = (uint_t *)regval; 355 1991 heppo 356 1991 heppo (void) prom_sprintf(scratch, "/%s@%lx%s", name, 357 1991 heppo PROM_REG_TO_UNIT_ADDR(*csaddr), buf); 358 1991 heppo 359 1991 heppo kmem_free(regval, rlen); 360 5768 jm22469 thread_affinity_clear(curthread); 361 1991 heppo 362 1991 heppo (void) prom_strcpy(buf, scratch); 363 1991 heppo 364 1991 heppo node = prom_parentnode(node); 365 1991 heppo } 366 1991 heppo 367 1991 heppo rvlen = prom_strlen(buf); 368 1991 heppo ci[6] = p1275_uint2cell(rvlen); 369 1991 heppo 370 1991 heppo return (0); 371 1991 heppo } 372 1991 heppo 373 1991 heppo #endif /* _KMDB */ 374