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/* 30 * General machine architecture & implementation specific 31 * assembly language routines. 32 */ 33#if defined(lint) 34#include <sys/types.h> 35#include <sys/machsystm.h> 36#include <sys/t_lock.h> 37#else /* lint */ 38#include "assym.h" 39#endif /* lint */ 40 41#include <sys/asm_linkage.h> 42#include <sys/async.h> 43#include <sys/machthread.h> 44 45#if defined(lint) 46caddr_t 47set_trap_table(void) 48{ 49 return ((caddr_t)0); 50} 51#else /* lint */ 52 53 ENTRY(set_trap_table) 54 set trap_table, %o1 55 rdpr %tba, %o0 56 wrpr %o1, %tba 57 retl 58 wrpr %g0, WSTATE_KERN, %wstate 59 SET_SIZE(set_trap_table) 60 61#endif /* lint */ 62 63#if defined(lint) 64 65/*ARGSUSED*/ 66void 67stphys(uint64_t physaddr, int value) 68{} 69 70/*ARGSUSED*/ 71int 72ldphys(uint64_t physaddr) 73{ return (0); } 74 75/*ARGSUSED*/ 76void 77stdphys(uint64_t physaddr, uint64_t value) 78{} 79 80/*ARGSUSED*/ 81uint64_t 82lddphys(uint64_t physaddr) 83{ return (0x0ull); } 84 85/* ARGSUSED */ 86void 87stphysio(u_longlong_t physaddr, uint_t value) 88{} 89 90/* ARGSUSED */ 91uint_t 92ldphysio(u_longlong_t physaddr) 93{ return(0); } 94 95/* ARGSUSED */ 96void 97sthphysio(u_longlong_t physaddr, ushort_t value) 98{} 99 100/* ARGSUSED */ 101ushort_t 102ldhphysio(u_longlong_t physaddr) 103{ return(0); } 104 105/* ARGSUSED */ 106void 107stbphysio(u_longlong_t physaddr, uchar_t value) 108{} 109 110/* ARGSUSED */ 111uchar_t 112ldbphysio(u_longlong_t physaddr) 113{ return(0); } 114 115/*ARGSUSED*/ 116void 117stdphysio(u_longlong_t physaddr, u_longlong_t value) 118{} 119 120/*ARGSUSED*/ 121u_longlong_t 122lddphysio(u_longlong_t physaddr) 123{ return (0ull); } 124 125#else 126 127 ! Store long word value at physical address 128 ! 129 ! void stdphys(uint64_t physaddr, uint64_t value) 130 ! 131 ENTRY(stdphys) 132 /* 133 * disable interrupts, clear Address Mask to access 64 bit physaddr 134 */ 135 rdpr %pstate, %o4 136 andn %o4, PSTATE_IE | PSTATE_AM, %o5 137 wrpr %o5, 0, %pstate 138 stxa %o1, [%o0]ASI_MEM 139 retl 140 wrpr %g0, %o4, %pstate ! restore earlier pstate register value 141 SET_SIZE(stdphys) 142 143 144 ! Store long word value at physical i/o address 145 ! 146 ! void stdphysio(u_longlong_t physaddr, u_longlong_t value) 147 ! 148 ENTRY(stdphysio) 149 /* 150 * disable interrupts, clear Address Mask to access 64 bit physaddr 151 */ 152 rdpr %pstate, %o4 153 andn %o4, PSTATE_IE | PSTATE_AM, %o5 154 wrpr %o5, 0, %pstate ! clear IE, AM bits 155 stxa %o1, [%o0]ASI_IO 156 retl 157 wrpr %g0, %o4, %pstate ! restore earlier pstate register value 158 SET_SIZE(stdphysio) 159 160 161 ! 162 ! Load long word value at physical address 163 ! 164 ! uint64_t lddphys(uint64_t physaddr) 165 ! 166 ENTRY(lddphys) 167 rdpr %pstate, %o4 168 andn %o4, PSTATE_IE | PSTATE_AM, %o5 169 wrpr %o5, 0, %pstate 170 ldxa [%o0]ASI_MEM, %o0 171 retl 172 wrpr %g0, %o4, %pstate ! restore earlier pstate register value 173 SET_SIZE(lddphys) 174 175 ! 176 ! Load long word value at physical i/o address 177 ! 178 ! unsigned long long lddphysio(u_longlong_t physaddr) 179 ! 180 ENTRY(lddphysio) 181 rdpr %pstate, %o4 182 andn %o4, PSTATE_IE | PSTATE_AM, %o5 183 wrpr %o5, 0, %pstate ! clear IE, AM bits 184 ldxa [%o0]ASI_IO, %o0 185 retl 186 wrpr %g0, %o4, %pstate ! restore earlier pstate register value 187 SET_SIZE(lddphysio) 188 189 ! 190 ! Store value at physical address 191 ! 192 ! void stphys(uint64_t physaddr, int value) 193 ! 194 ENTRY(stphys) 195 rdpr %pstate, %o4 196 andn %o4, PSTATE_IE | PSTATE_AM, %o5 197 wrpr %o5, 0, %pstate 198 sta %o1, [%o0]ASI_MEM 199 retl 200 wrpr %g0, %o4, %pstate ! restore earlier pstate register value 201 SET_SIZE(stphys) 202 203 204 ! 205 ! load value at physical address 206 ! 207 ! int ldphys(uint64_t physaddr) 208 ! 209 ENTRY(ldphys) 210 rdpr %pstate, %o4 211 andn %o4, PSTATE_IE | PSTATE_AM, %o5 212 wrpr %o5, 0, %pstate 213 lda [%o0]ASI_MEM, %o0 214 srl %o0, 0, %o0 ! clear upper 32 bits 215 retl 216 wrpr %g0, %o4, %pstate ! restore earlier pstate register value 217 SET_SIZE(ldphys) 218 219 ! 220 ! Store value into physical address in I/O space 221 ! 222 ! void stphysio(u_longlong_t physaddr, uint_t value) 223 ! 224 ENTRY_NP(stphysio) 225 rdpr %pstate, %o4 /* read PSTATE reg */ 226 andn %o4, PSTATE_IE | PSTATE_AM, %o5 227 wrpr %o5, 0, %pstate 228 stwa %o1, [%o0]ASI_IO /* store value via bypass ASI */ 229 retl 230 wrpr %g0, %o4, %pstate /* restore the PSTATE */ 231 SET_SIZE(stphysio) 232 233 ! 234 ! Store value into physical address in I/O space 235 ! 236 ! void sthphysio(u_longlong_t physaddr, ushort_t value) 237 ! 238 ENTRY_NP(sthphysio) 239 rdpr %pstate, %o4 /* read PSTATE reg */ 240 andn %o4, PSTATE_IE | PSTATE_AM, %o5 241 wrpr %o5, 0, %pstate 242 stha %o1, [%o0]ASI_IO /* store value via bypass ASI */ 243 retl 244 wrpr %g0, %o4, %pstate /* restore the PSTATE */ 245 SET_SIZE(sthphysio) 246 247 ! 248 ! Store value into one byte physical address in I/O space 249 ! 250 ! void stbphysio(u_longlong_t physaddr, uchar_t value) 251 ! 252 ENTRY_NP(stbphysio) 253 rdpr %pstate, %o4 /* read PSTATE reg */ 254 andn %o4, PSTATE_IE | PSTATE_AM, %o5 255 wrpr %o5, 0, %pstate 256 stba %o1, [%o0]ASI_IO /* store byte via bypass ASI */ 257 retl 258 wrpr %g0, %o4, %pstate /* restore the PSTATE */ 259 SET_SIZE(stbphysio) 260 261 ! 262 ! load value at physical address in I/O space 263 ! 264 ! uint_t ldphysio(u_longlong_t physaddr) 265 ! 266 ENTRY_NP(ldphysio) 267 rdpr %pstate, %o4 /* read PSTATE reg */ 268 andn %o4, PSTATE_IE | PSTATE_AM, %o5 269 wrpr %o5, 0, %pstate 270 lduwa [%o0]ASI_IO, %o0 /* load value via bypass ASI */ 271 retl 272 wrpr %g0, %o4, %pstate /* restore pstate */ 273 SET_SIZE(ldphysio) 274 275 ! 276 ! load value at physical address in I/O space 277 ! 278 ! ushort_t ldhphysio(u_longlong_t physaddr) 279 ! 280 ENTRY_NP(ldhphysio) 281 rdpr %pstate, %o4 /* read PSTATE reg */ 282 andn %o4, PSTATE_IE | PSTATE_AM, %o5 283 wrpr %o5, 0, %pstate 284 lduha [%o0]ASI_IO, %o0 /* load value via bypass ASI */ 285 retl 286 wrpr %g0, %o4, %pstate /* restore pstate */ 287 SET_SIZE(ldhphysio) 288 289 ! 290 ! load byte value at physical address in I/O space 291 ! 292 ! uchar_t ldbphysio(u_longlong_t physaddr) 293 ! 294 ENTRY_NP(ldbphysio) 295 rdpr %pstate, %o4 /* read PSTATE reg */ 296 andn %o4, PSTATE_IE | PSTATE_AM, %o5 297 wrpr %o5, 0, %pstate 298 lduba [%o0]ASI_IO, %o0 /* load value via bypass ASI */ 299 retl 300 wrpr %g0, %o4, %pstate /* restore pstate */ 301 SET_SIZE(ldbphysio) 302#endif /* lint */ 303 304/* 305 * save_gsr(kfpu_t *fp) 306 * Store the graphics status register 307 */ 308 309#if defined(lint) || defined(__lint) 310 311/* ARGSUSED */ 312void 313save_gsr(kfpu_t *fp) 314{} 315 316#else /* lint */ 317 318 ENTRY_NP(save_gsr) 319 rd %gsr, %g2 ! save gsr 320 retl 321 stx %g2, [%o0 + FPU_GSR] 322 SET_SIZE(save_gsr) 323 324#endif /* lint */ 325 326#if defined(lint) || defined(__lint) 327 328/* ARGSUSED */ 329void 330restore_gsr(kfpu_t *fp) 331{} 332 333#else /* lint */ 334 335 ENTRY_NP(restore_gsr) 336 ldx [%o0 + FPU_GSR], %g2 337 wr %g2, %g0, %gsr 338 retl 339 nop 340 SET_SIZE(restore_gsr) 341 342#endif /* lint */ 343 344/* 345 * uint64_t 346 * get_phys_gsr() 347 * Get the graphics status register info from fp and return it 348 */ 349 350#if defined(lint) || defined(__lint) 351 352/* ARGSUSED */ 353uint64_t 354get_phys_gsr(kfpu_t *fp) 355{ return 0; } 356 357#else /* lint */ 358 359 ENTRY_NP(get_phys_gsr) 360 retl 361 rd %gsr, %o0 362 SET_SIZE(get_phys_gsr) 363 364#endif /* lint */ 365 366 367/* 368 * uint64_t 369 * get_gsr(kfpu_t *fp) 370 * Get the graphics status register info from fp and return it 371 */ 372 373#if defined(lint) || defined(__lint) 374 375/* ARGSUSED */ 376uint64_t 377get_gsr(kfpu_t *fp) 378{ return 0; } 379 380#else /* lint */ 381 382 ENTRY_NP(get_gsr) 383 retl 384 ldx [%o0 + FPU_GSR], %o0 385 SET_SIZE(get_gsr) 386 387#endif 388 389/* 390 * set_phys_gsr(uint64_t *buf, kfpu_t *fp) 391 * Set the graphics status register info to fp from buf 392 */ 393 394#if defined(lint) || defined(__lint) 395 396/* ARGSUSED */ 397void 398set_phys_gsr(uint64_t buf, kfpu_t *fp) 399{} 400 401#else /* lint */ 402 403 ENTRY_NP(set_phys_gsr) 404 retl 405 mov %o0, %gsr 406 SET_SIZE(set_phys_gsr) 407 408#endif /* lint */ 409 410/* 411 * set_gsr(uint64_t buf, kfpu_t *fp) 412 * Set the graphics status register info to fp from buf 413 */ 414 415#if defined(lint) || defined(__lint) 416 417/* ARGSUSED */ 418void 419set_gsr(uint64_t buf, kfpu_t *fp) 420{} 421 422#else /* lint */ 423 424 ENTRY_NP(set_gsr) 425 retl 426 stx %o0, [%o1 + FPU_GSR] 427 SET_SIZE(set_gsr) 428 429#endif /* lint */ 430/* 431 * Routine to get the pstate reg - used by vis emulation code 432 * to test whether the AM bit for 32 bit instructions 433 * has been set. 434 */ 435#if defined(lint) || defined(__lint) 436 437/* ARGSUSED */ 438uint_t 439get_pstate(void) 440{ return 0; } 441#else /* lint */ 442 443 ENTRY_NP(get_pstate) 444 retl 445 rdpr %pstate, %o0 446 SET_SIZE(get_pstate) 447 448#endif /* lint */ 449/* 450 * Routine to get the ccr bits - used by vis emulation code 451 * to get the ccr bits before an edge instruction is performed 452 * 453 */ 454 455#if defined(lint) || defined(__lint) 456 457/* ARGSUSED */ 458 459uint_t 460get_ccr() 461{ return 0; } 462#else /* lint */ 463 464 ENTRY_NP(get_ccr) 465 retl 466 rd %ccr, %o0 467 SET_SIZE(get_ccr) 468 469#endif 470 471/* 472 * Routine to set the ccr bits - used by vis emulation code 473 * to set the ccr bits after an edge instruction is performed 474 * 475 */ 476#if defined(lint) || defined(__lint) 477 478/* ARGSUSED */ 479 480void 481set_ccr(uint_t buf) 482{} 483#else /* lint */ 484 485 ENTRY_NP(set_ccr) 486 retl 487 mov %o0, %ccr 488 SET_SIZE(set_ccr) 489 490#endif /* lint */ 491 492#if defined(lint) || defined(__lint) 493void 494kdi_cpu_index(void) 495{ 496} 497 498#else /* lint */ 499 500 ENTRY_NP(kdi_cpu_index) 501 CPU_INDEX(%g1, %g2) 502 jmp %g7 503 nop 504 SET_SIZE(kdi_cpu_index) 505 506#endif /* lint */ 507