1/*- 2 * Copyright (c) 2007 Marcel Moolenaar 3 * Copyright (c) 2000 Doug Rabson 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $FreeBSD$ 28 */ 29 30#ifndef _MACHINE_IA64_CPU_H_ 31#define _MACHINE_IA64_CPU_H_ 32 33/* 34 * Local Interrupt ID. 35 */ 36#define IA64_LID_GET_SAPIC_ID(x) ((u_int)((x) >> 16) & 0xffff) 37#define IA64_LID_SET_SAPIC_ID(x) ((u_int)((x) & 0xffff) << 16) 38 39/* 40 * Definition of DCR bits. 41 */ 42#define IA64_DCR_PP 0x0000000000000001 43#define IA64_DCR_BE 0x0000000000000002 44#define IA64_DCR_LC 0x0000000000000004 45#define IA64_DCR_DM 0x0000000000000100 46#define IA64_DCR_DP 0x0000000000000200 47#define IA64_DCR_DK 0x0000000000000400 48#define IA64_DCR_DX 0x0000000000000800 49#define IA64_DCR_DR 0x0000000000001000 50#define IA64_DCR_DA 0x0000000000002000 51#define IA64_DCR_DD 0x0000000000004000 52 53#define IA64_DCR_DEFAULT \ 54 (IA64_DCR_DM | IA64_DCR_DP | IA64_DCR_DK | IA64_DCR_DX | \ 55 IA64_DCR_DR | IA64_DCR_DA | IA64_DCR_DD) 56 57/* 58 * Definition of PSR and IPSR bits. 59 */ 60#define IA64_PSR_BE 0x0000000000000002 61#define IA64_PSR_UP 0x0000000000000004 62#define IA64_PSR_AC 0x0000000000000008 63#define IA64_PSR_MFL 0x0000000000000010 64#define IA64_PSR_MFH 0x0000000000000020 65#define IA64_PSR_IC 0x0000000000002000 66#define IA64_PSR_I 0x0000000000004000 67#define IA64_PSR_PK 0x0000000000008000 68#define IA64_PSR_DT 0x0000000000020000 69#define IA64_PSR_DFL 0x0000000000040000 70#define IA64_PSR_DFH 0x0000000000080000 71#define IA64_PSR_SP 0x0000000000100000 72#define IA64_PSR_PP 0x0000000000200000 73#define IA64_PSR_DI 0x0000000000400000 74#define IA64_PSR_SI 0x0000000000800000 75#define IA64_PSR_DB 0x0000000001000000 76#define IA64_PSR_LP 0x0000000002000000 77#define IA64_PSR_TB 0x0000000004000000 78#define IA64_PSR_RT 0x0000000008000000 79#define IA64_PSR_CPL 0x0000000300000000 80#define IA64_PSR_CPL_KERN 0x0000000000000000 81#define IA64_PSR_CPL_1 0x0000000100000000 82#define IA64_PSR_CPL_2 0x0000000200000000 83#define IA64_PSR_CPL_USER 0x0000000300000000 84#define IA64_PSR_IS 0x0000000400000000 85#define IA64_PSR_MC 0x0000000800000000 86#define IA64_PSR_IT 0x0000001000000000 87#define IA64_PSR_ID 0x0000002000000000 88#define IA64_PSR_DA 0x0000004000000000 89#define IA64_PSR_DD 0x0000008000000000 90#define IA64_PSR_SS 0x0000010000000000 91#define IA64_PSR_RI 0x0000060000000000 92#define IA64_PSR_RI_0 0x0000000000000000 93#define IA64_PSR_RI_1 0x0000020000000000 94#define IA64_PSR_RI_2 0x0000040000000000 95#define IA64_PSR_ED 0x0000080000000000 96#define IA64_PSR_BN 0x0000100000000000 97#define IA64_PSR_IA 0x0000200000000000 98 99/* 100 * Definition of ISR bits. 101 */ 102#define IA64_ISR_CODE 0x000000000000ffff 103#define IA64_ISR_VECTOR 0x0000000000ff0000 104#define IA64_ISR_X 0x0000000100000000 105#define IA64_ISR_W 0x0000000200000000 106#define IA64_ISR_R 0x0000000400000000 107#define IA64_ISR_NA 0x0000000800000000 108#define IA64_ISR_SP 0x0000001000000000 109#define IA64_ISR_RS 0x0000002000000000 110#define IA64_ISR_IR 0x0000004000000000 111#define IA64_ISR_NI 0x0000008000000000 112#define IA64_ISR_SO 0x0000010000000000 113#define IA64_ISR_EI 0x0000060000000000 114#define IA64_ISR_EI_0 0x0000000000000000 115#define IA64_ISR_EI_1 0x0000020000000000 116#define IA64_ISR_EI_2 0x0000040000000000 117#define IA64_ISR_ED 0x0000080000000000 118 119/* 120 * Vector numbers for various ia64 interrupts. 121 */ 122#define IA64_VEC_VHPT 0 123#define IA64_VEC_ITLB 1 124#define IA64_VEC_DTLB 2 125#define IA64_VEC_ALT_ITLB 3 126#define IA64_VEC_ALT_DTLB 4 127#define IA64_VEC_NESTED_DTLB 5 128#define IA64_VEC_IKEY_MISS 6 129#define IA64_VEC_DKEY_MISS 7 130#define IA64_VEC_DIRTY_BIT 8 131#define IA64_VEC_INST_ACCESS 9 132#define IA64_VEC_DATA_ACCESS 10 133#define IA64_VEC_BREAK 11 134#define IA64_VEC_EXT_INTR 12 135#define IA64_VEC_PAGE_NOT_PRESENT 20 136#define IA64_VEC_KEY_PERMISSION 21 137#define IA64_VEC_INST_ACCESS_RIGHTS 22 138#define IA64_VEC_DATA_ACCESS_RIGHTS 23 139#define IA64_VEC_GENERAL_EXCEPTION 24 140#define IA64_VEC_DISABLED_FP 25 141#define IA64_VEC_NAT_CONSUMPTION 26 142#define IA64_VEC_SPECULATION 27 143#define IA64_VEC_DEBUG 29 144#define IA64_VEC_UNALIGNED_REFERENCE 30 145#define IA64_VEC_UNSUPP_DATA_REFERENCE 31 146#define IA64_VEC_FLOATING_POINT_FAULT 32 147#define IA64_VEC_FLOATING_POINT_TRAP 33 148#define IA64_VEC_LOWER_PRIVILEGE_TRANSFER 34 149#define IA64_VEC_TAKEN_BRANCH_TRAP 35 150#define IA64_VEC_SINGLE_STEP_TRAP 36 151#define IA64_VEC_IA32_EXCEPTION 45 152#define IA64_VEC_IA32_INTERCEPT 46 153#define IA64_VEC_IA32_INTERRUPT 47 154 155/* 156 * IA-32 exceptions. 157 */ 158#define IA32_EXCEPTION_DIVIDE 0 159#define IA32_EXCEPTION_DEBUG 1 160#define IA32_EXCEPTION_BREAK 3 161#define IA32_EXCEPTION_OVERFLOW 4 162#define IA32_EXCEPTION_BOUND 5 163#define IA32_EXCEPTION_DNA 7 164#define IA32_EXCEPTION_NOT_PRESENT 11 165#define IA32_EXCEPTION_STACK_FAULT 12 166#define IA32_EXCEPTION_GPFAULT 13 167#define IA32_EXCEPTION_FPERROR 16 168#define IA32_EXCEPTION_ALIGNMENT_CHECK 17 169#define IA32_EXCEPTION_STREAMING_SIMD 19 170 171#define IA32_INTERCEPT_INSTRUCTION 0 172#define IA32_INTERCEPT_GATE 1 173#define IA32_INTERCEPT_SYSTEM_FLAG 2 174#define IA32_INTERCEPT_LOCK 4 175 176#ifndef LOCORE 177 178/* 179 * Various special ia64 instructions. 180 */ 181 182/* 183 * Memory Fence. 184 */ 185static __inline void 186ia64_mf(void) 187{ 188 __asm __volatile("mf"); 189} 190 191static __inline void 192ia64_mf_a(void) 193{ 194 __asm __volatile("mf.a"); 195} 196 197/* 198 * Flush Cache. 199 */ 200static __inline void 201ia64_fc(uint64_t va) 202{ 203 __asm __volatile("fc %0" :: "r"(va)); 204} 205 206static __inline void 207ia64_fc_i(uint64_t va) 208{ 209 __asm __volatile("fc.i %0" :: "r"(va)); 210} 211 212/* 213 * Sync instruction stream. 214 */ 215static __inline void 216ia64_sync_i(void) 217{ 218 __asm __volatile("sync.i"); 219} 220 221/* 222 * Calculate address in VHPT for va. 223 */ 224static __inline uint64_t 225ia64_thash(uint64_t va) 226{ 227 uint64_t result; 228 __asm __volatile("thash %0=%1" : "=r" (result) : "r" (va)); 229 return result; 230} 231 232/* 233 * Calculate VHPT tag for va. 234 */ 235static __inline uint64_t 236ia64_ttag(uint64_t va) 237{ 238 uint64_t result; 239 __asm __volatile("ttag %0=%1" : "=r" (result) : "r" (va)); 240 return result; 241} 242 243/* 244 * Convert virtual address to physical. 245 */ 246static __inline uint64_t 247ia64_tpa(uint64_t va) 248{ 249 uint64_t result; 250 __asm __volatile("tpa %0=%1" : "=r" (result) : "r" (va)); 251 return result; 252} 253 254/* 255 * Generate a ptc.e instruction. 256 */ 257static __inline void 258ia64_ptc_e(uint64_t v) 259{ 260 __asm __volatile("ptc.e %0;; srlz.i;;" :: "r"(v)); 261} 262 263/* 264 * Generate a ptc.g instruction. 265 */ 266static __inline void 267ia64_ptc_g(uint64_t va, uint64_t log2size) 268{ 269 __asm __volatile("ptc.g %0,%1;;" :: "r"(va), "r"(log2size)); 270} 271 272/* 273 * Generate a ptc.ga instruction. 274 */ 275static __inline void 276ia64_ptc_ga(uint64_t va, uint64_t log2size) 277{ 278 __asm __volatile("ptc.ga %0,%1;;" :: "r"(va), "r"(log2size)); 279} 280 281/* 282 * Generate a ptc.l instruction. 283 */ 284static __inline void 285ia64_ptc_l(uint64_t va, uint64_t log2size) 286{ 287 __asm __volatile("ptc.l %0,%1;; srlz.i;;" :: "r"(va), "r"(log2size)); 288} 289 290/* 291 * Invalidate the ALAT on the local processor. 292 */ 293static __inline void 294ia64_invala(void) 295{ 296 __asm __volatile("invala;;"); 297} 298 299/* 300 * Unordered memory load. 301 */ 302 303static __inline uint8_t 304ia64_ld1(uint8_t *p) 305{ 306 uint8_t v; 307 308 __asm __volatile("ld1 %0=[%1];;" : "=r"(v) : "r"(p)); 309 return (v); 310} 311 312static __inline uint16_t 313ia64_ld2(uint16_t *p) 314{ 315 uint16_t v; 316 317 __asm __volatile("ld2 %0=[%1];;" : "=r"(v) : "r"(p)); 318 return (v); 319} 320 321static __inline uint32_t 322ia64_ld4(uint32_t *p) 323{ 324 uint32_t v; 325 326 __asm __volatile("ld4 %0=[%1];;" : "=r"(v) : "r"(p)); 327 return (v); 328} 329 330static __inline uint64_t 331ia64_ld8(uint64_t *p) 332{ 333 uint64_t v; 334 335 __asm __volatile("ld8 %0=[%1];;" : "=r"(v) : "r"(p)); 336 return (v); 337} 338 339/* 340 * Unordered memory store. 341 */ 342 343static __inline void 344ia64_st1(uint8_t *p, uint8_t v) 345{ 346 __asm __volatile("st1 [%0]=%1;;" :: "r"(p), "r"(v)); 347} 348 349static __inline void 350ia64_st2(uint16_t *p, uint16_t v) 351{ 352 __asm __volatile("st2 [%0]=%1;;" :: "r"(p), "r"(v)); 353} 354 355static __inline void 356ia64_st4(uint32_t *p, uint32_t v) 357{ 358 __asm __volatile("st4 [%0]=%1;;" :: "r"(p), "r"(v)); 359} 360 361static __inline void 362ia64_st8(uint64_t *p, uint64_t v) 363{ 364 __asm __volatile("st8 [%0]=%1;;" :: "r"(p), "r"(v)); 365} 366 367/* 368 * Read the value of psr. 369 */ 370static __inline uint64_t 371ia64_get_psr(void) 372{ 373 uint64_t result; 374 __asm __volatile("mov %0=psr;;" : "=r" (result)); 375 return result; 376} 377 378/* 379 * Define accessors for application registers. 380 */ 381 382#define IA64_AR(name) \ 383 \ 384static __inline uint64_t \ 385ia64_get_##name(void) \ 386{ \ 387 uint64_t result; \ 388 __asm __volatile("mov %0=ar." #name : "=r" (result)); \ 389 return result; \ 390} \ 391 \ 392static __inline void \ 393ia64_set_##name(uint64_t v) \ 394{ \ 395 __asm __volatile("mov ar." #name "=%0;;" :: "r" (v)); \ 396} 397 398IA64_AR(k0) 399IA64_AR(k1) 400IA64_AR(k2) 401IA64_AR(k3) 402IA64_AR(k4) 403IA64_AR(k5) 404IA64_AR(k6) 405IA64_AR(k7) 406 407IA64_AR(rsc) 408IA64_AR(bsp) 409IA64_AR(bspstore) 410IA64_AR(rnat) 411 412IA64_AR(fcr) 413 414IA64_AR(eflag) 415IA64_AR(csd) 416IA64_AR(ssd) 417IA64_AR(cflg) 418IA64_AR(fsr) 419IA64_AR(fir) 420IA64_AR(fdr) 421 422IA64_AR(ccv) 423 424IA64_AR(unat) 425 426IA64_AR(fpsr) 427 428IA64_AR(itc) 429 430IA64_AR(pfs) 431IA64_AR(lc) 432IA64_AR(ec) 433 434/* 435 * Define accessors for control registers. 436 */ 437 438#define IA64_CR(name) \ 439 \ 440static __inline uint64_t \ 441ia64_get_##name(void) \ 442{ \ 443 uint64_t result; \ 444 __asm __volatile("mov %0=cr." #name : "=r" (result)); \ 445 return result; \ 446} \ 447 \ 448static __inline void \ 449ia64_set_##name(uint64_t v) \ 450{ \ 451 __asm __volatile("mov cr." #name "=%0;;" :: "r" (v)); \ 452} 453 454IA64_CR(dcr) 455IA64_CR(itm) 456IA64_CR(iva) 457 458IA64_CR(pta) 459 460IA64_CR(ipsr) 461IA64_CR(isr) 462 463IA64_CR(iip) 464IA64_CR(ifa) 465IA64_CR(itir) 466IA64_CR(iipa) 467IA64_CR(ifs) 468IA64_CR(iim) 469IA64_CR(iha) 470 471IA64_CR(lid) 472IA64_CR(ivr) 473IA64_CR(tpr) 474IA64_CR(eoi) 475IA64_CR(irr0) 476IA64_CR(irr1) 477IA64_CR(irr2) 478IA64_CR(irr3) 479IA64_CR(itv) 480IA64_CR(pmv) 481IA64_CR(cmcv) 482 483IA64_CR(lrr0) 484IA64_CR(lrr1) 485 486/* 487 * Write a region register. 488 */ 489static __inline void 490ia64_set_rr(uint64_t rrbase, uint64_t v) 491{ 492 __asm __volatile("mov rr[%0]=%1" 493 :: "r"(rrbase), "r"(v) : "memory"); 494} 495 496/* 497 * Read a CPUID register. 498 */ 499static __inline uint64_t 500ia64_get_cpuid(int i) 501{ 502 uint64_t result; 503 __asm __volatile("mov %0=cpuid[%1]" 504 : "=r" (result) : "r"(i)); 505 return result; 506} 507 508static __inline void 509ia64_disable_highfp(void) 510{ 511 __asm __volatile("ssm psr.dfh;; srlz.d"); 512} 513 514static __inline void 515ia64_enable_highfp(void) 516{ 517 __asm __volatile("rsm psr.dfh;; srlz.d"); 518} 519 520/* 521 * Avoid inline functions for the following so that they still work 522 * correctly when inlining is not enabled (e.g. -O0). Function calls 523 * need data serialization after setting psr, which results in a 524 * hazard. 525 */ 526#define ia64_srlz_d() __asm __volatile("srlz.d") 527#define ia64_srlz_i() __asm __volatile("srlz.i;;") 528 529#endif /* !LOCORE */ 530 531#endif /* _MACHINE_IA64_CPU_H_ */ 532 533