1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * SBI initialilization and all extension implementation. 4 * 5 * Copyright (c) 2020 Western Digital Corporation or its affiliates. 6 */ 7 8 #include <linux/bits.h> 9 #include <linux/init.h> 10 #include <linux/mm.h> 11 #include <linux/pm.h> 12 #include <linux/reboot.h> 13 #include <asm/sbi.h> 14 #include <asm/smp.h> 15 #include <asm/tlbflush.h> 16 17 /* default SBI version is 0.1 */ 18 unsigned long sbi_spec_version __ro_after_init = SBI_SPEC_VERSION_DEFAULT; 19 EXPORT_SYMBOL(sbi_spec_version); 20 21 static void (*__sbi_set_timer)(uint64_t stime) __ro_after_init; 22 static void (*__sbi_send_ipi)(unsigned int cpu) __ro_after_init; 23 static int (*__sbi_rfence)(int fid, const struct cpumask *cpu_mask, 24 unsigned long start, unsigned long size, 25 unsigned long arg4, unsigned long arg5) __ro_after_init; 26 27 #ifdef CONFIG_RISCV_SBI_V01 28 static unsigned long __sbi_v01_cpumask_to_hartmask(const struct cpumask *cpu_mask) 29 { 30 unsigned long cpuid, hartid; 31 unsigned long hmask = 0; 32 33 /* 34 * There is no maximum hartid concept in RISC-V and NR_CPUS must not be 35 * associated with hartid. As SBI v0.1 is only kept for backward compatibility 36 * and will be removed in the future, there is no point in supporting hartid 37 * greater than BITS_PER_LONG (32 for RV32 and 64 for RV64). Ideally, SBI v0.2 38 * should be used for platforms with hartid greater than BITS_PER_LONG. 39 */ 40 for_each_cpu(cpuid, cpu_mask) { 41 hartid = cpuid_to_hartid_map(cpuid); 42 if (hartid >= BITS_PER_LONG) { 43 pr_warn("Unable to send any request to hartid > BITS_PER_LONG for SBI v0.1\n"); 44 break; 45 } 46 hmask |= BIT(hartid); 47 } 48 49 return hmask; 50 } 51 52 /** 53 * sbi_console_putchar() - Writes given character to the console device. 54 * @ch: The data to be written to the console. 55 * 56 * Return: None 57 */ 58 void sbi_console_putchar(int ch) 59 { 60 sbi_ecall(SBI_EXT_0_1_CONSOLE_PUTCHAR, 0, ch, 0, 0, 0, 0, 0); 61 } 62 EXPORT_SYMBOL(sbi_console_putchar); 63 64 /** 65 * sbi_console_getchar() - Reads a byte from console device. 66 * 67 * Returns the value read from console. 68 */ 69 int sbi_console_getchar(void) 70 { 71 struct sbiret ret; 72 73 ret = sbi_ecall(SBI_EXT_0_1_CONSOLE_GETCHAR, 0, 0, 0, 0, 0, 0, 0); 74 75 return ret.error; 76 } 77 EXPORT_SYMBOL(sbi_console_getchar); 78 79 /** 80 * sbi_shutdown() - Remove all the harts from executing supervisor code. 81 * 82 * Return: None 83 */ 84 void sbi_shutdown(void) 85 { 86 sbi_ecall(SBI_EXT_0_1_SHUTDOWN, 0, 0, 0, 0, 0, 0, 0); 87 } 88 EXPORT_SYMBOL(sbi_shutdown); 89 90 /** 91 * __sbi_set_timer_v01() - Program the timer for next timer event. 92 * @stime_value: The value after which next timer event should fire. 93 * 94 * Return: None 95 */ 96 static void __sbi_set_timer_v01(uint64_t stime_value) 97 { 98 #if __riscv_xlen == 32 99 sbi_ecall(SBI_EXT_0_1_SET_TIMER, 0, stime_value, 100 stime_value >> 32, 0, 0, 0, 0); 101 #else 102 sbi_ecall(SBI_EXT_0_1_SET_TIMER, 0, stime_value, 0, 0, 0, 0, 0); 103 #endif 104 } 105 106 static void __sbi_send_ipi_v01(unsigned int cpu) 107 { 108 unsigned long hart_mask = 109 __sbi_v01_cpumask_to_hartmask(cpumask_of(cpu)); 110 sbi_ecall(SBI_EXT_0_1_SEND_IPI, 0, (unsigned long)(&hart_mask), 111 0, 0, 0, 0, 0); 112 } 113 114 static int __sbi_rfence_v01(int fid, const struct cpumask *cpu_mask, 115 unsigned long start, unsigned long size, 116 unsigned long arg4, unsigned long arg5) 117 { 118 int result = 0; 119 unsigned long hart_mask; 120 121 if (!cpu_mask || cpumask_empty(cpu_mask)) 122 cpu_mask = cpu_online_mask; 123 hart_mask = __sbi_v01_cpumask_to_hartmask(cpu_mask); 124 125 /* v0.2 function IDs are equivalent to v0.1 extension IDs */ 126 switch (fid) { 127 case SBI_EXT_RFENCE_REMOTE_FENCE_I: 128 sbi_ecall(SBI_EXT_0_1_REMOTE_FENCE_I, 0, 129 (unsigned long)&hart_mask, 0, 0, 0, 0, 0); 130 break; 131 case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA: 132 sbi_ecall(SBI_EXT_0_1_REMOTE_SFENCE_VMA, 0, 133 (unsigned long)&hart_mask, start, size, 134 0, 0, 0); 135 break; 136 case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID: 137 sbi_ecall(SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID, 0, 138 (unsigned long)&hart_mask, start, size, 139 arg4, 0, 0); 140 break; 141 default: 142 pr_err("SBI call [%d]not supported in SBI v0.1\n", fid); 143 result = -EINVAL; 144 } 145 146 return result; 147 } 148 149 static void sbi_set_power_off(void) 150 { 151 pm_power_off = sbi_shutdown; 152 } 153 #else 154 static void __sbi_set_timer_v01(uint64_t stime_value) 155 { 156 pr_warn("Timer extension is not available in SBI v%lu.%lu\n", 157 sbi_major_version(), sbi_minor_version()); 158 } 159 160 static void __sbi_send_ipi_v01(unsigned int cpu) 161 { 162 pr_warn("IPI extension is not available in SBI v%lu.%lu\n", 163 sbi_major_version(), sbi_minor_version()); 164 } 165 166 static int __sbi_rfence_v01(int fid, const struct cpumask *cpu_mask, 167 unsigned long start, unsigned long size, 168 unsigned long arg4, unsigned long arg5) 169 { 170 pr_warn("remote fence extension is not available in SBI v%lu.%lu\n", 171 sbi_major_version(), sbi_minor_version()); 172 173 return 0; 174 } 175 176 static void sbi_set_power_off(void) {} 177 #endif /* CONFIG_RISCV_SBI_V01 */ 178 179 static void __sbi_set_timer_v02(uint64_t stime_value) 180 { 181 #if __riscv_xlen == 32 182 sbi_ecall(SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, stime_value, 183 stime_value >> 32, 0, 0, 0, 0); 184 #else 185 sbi_ecall(SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, stime_value, 0, 186 0, 0, 0, 0); 187 #endif 188 } 189 190 static void __sbi_send_ipi_v02(unsigned int cpu) 191 { 192 int result; 193 struct sbiret ret = {0}; 194 195 ret = sbi_ecall(SBI_EXT_IPI, SBI_EXT_IPI_SEND_IPI, 196 1UL, cpuid_to_hartid_map(cpu), 0, 0, 0, 0); 197 if (ret.error) { 198 result = sbi_err_map_linux_errno(ret.error); 199 pr_err("%s: hbase = [%lu] failed (error [%d])\n", 200 __func__, cpuid_to_hartid_map(cpu), result); 201 } 202 } 203 204 static int __sbi_rfence_v02_call(unsigned long fid, unsigned long hmask, 205 unsigned long hbase, unsigned long start, 206 unsigned long size, unsigned long arg4, 207 unsigned long arg5) 208 { 209 struct sbiret ret = {0}; 210 int ext = SBI_EXT_RFENCE; 211 int result = 0; 212 213 switch (fid) { 214 case SBI_EXT_RFENCE_REMOTE_FENCE_I: 215 ret = sbi_ecall(ext, fid, hmask, hbase, 0, 0, 0, 0); 216 break; 217 case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA: 218 ret = sbi_ecall(ext, fid, hmask, hbase, start, 219 size, 0, 0); 220 break; 221 case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID: 222 ret = sbi_ecall(ext, fid, hmask, hbase, start, 223 size, arg4, 0); 224 break; 225 226 case SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA: 227 ret = sbi_ecall(ext, fid, hmask, hbase, start, 228 size, 0, 0); 229 break; 230 case SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID: 231 ret = sbi_ecall(ext, fid, hmask, hbase, start, 232 size, arg4, 0); 233 break; 234 case SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA: 235 ret = sbi_ecall(ext, fid, hmask, hbase, start, 236 size, 0, 0); 237 break; 238 case SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID: 239 ret = sbi_ecall(ext, fid, hmask, hbase, start, 240 size, arg4, 0); 241 break; 242 default: 243 pr_err("unknown function ID [%lu] for SBI extension [%d]\n", 244 fid, ext); 245 result = -EINVAL; 246 } 247 248 if (ret.error) { 249 result = sbi_err_map_linux_errno(ret.error); 250 pr_err("%s: hbase = [%lu] hmask = [0x%lx] failed (error [%d])\n", 251 __func__, hbase, hmask, result); 252 } 253 254 return result; 255 } 256 257 static int __sbi_rfence_v02(int fid, const struct cpumask *cpu_mask, 258 unsigned long start, unsigned long size, 259 unsigned long arg4, unsigned long arg5) 260 { 261 unsigned long hartid, cpuid, hmask = 0, hbase = 0, htop = 0; 262 int result; 263 264 if (!cpu_mask || cpumask_empty(cpu_mask)) 265 cpu_mask = cpu_online_mask; 266 267 for_each_cpu(cpuid, cpu_mask) { 268 hartid = cpuid_to_hartid_map(cpuid); 269 if (hmask) { 270 if (hartid + BITS_PER_LONG <= htop || 271 hbase + BITS_PER_LONG <= hartid) { 272 result = __sbi_rfence_v02_call(fid, hmask, 273 hbase, start, size, arg4, arg5); 274 if (result) 275 return result; 276 hmask = 0; 277 } else if (hartid < hbase) { 278 /* shift the mask to fit lower hartid */ 279 hmask <<= hbase - hartid; 280 hbase = hartid; 281 } 282 } 283 if (!hmask) { 284 hbase = hartid; 285 htop = hartid; 286 } else if (hartid > htop) { 287 htop = hartid; 288 } 289 hmask |= BIT(hartid - hbase); 290 } 291 292 if (hmask) { 293 result = __sbi_rfence_v02_call(fid, hmask, hbase, 294 start, size, arg4, arg5); 295 if (result) 296 return result; 297 } 298 299 return 0; 300 } 301 302 /** 303 * sbi_set_timer() - Program the timer for next timer event. 304 * @stime_value: The value after which next timer event should fire. 305 * 306 * Return: None. 307 */ 308 void sbi_set_timer(uint64_t stime_value) 309 { 310 __sbi_set_timer(stime_value); 311 } 312 313 /** 314 * sbi_send_ipi() - Send an IPI to any hart. 315 * @cpu: Logical id of the target CPU. 316 */ 317 void sbi_send_ipi(unsigned int cpu) 318 { 319 __sbi_send_ipi(cpu); 320 } 321 EXPORT_SYMBOL(sbi_send_ipi); 322 323 /** 324 * sbi_remote_fence_i() - Execute FENCE.I instruction on given remote harts. 325 * @cpu_mask: A cpu mask containing all the target harts. 326 * 327 * Return: 0 on success, appropriate linux error code otherwise. 328 */ 329 int sbi_remote_fence_i(const struct cpumask *cpu_mask) 330 { 331 return __sbi_rfence(SBI_EXT_RFENCE_REMOTE_FENCE_I, 332 cpu_mask, 0, 0, 0, 0); 333 } 334 EXPORT_SYMBOL(sbi_remote_fence_i); 335 336 /** 337 * sbi_remote_sfence_vma_asid() - Execute SFENCE.VMA instructions on given 338 * remote harts for a virtual address range belonging to a specific ASID or not. 339 * 340 * @cpu_mask: A cpu mask containing all the target harts. 341 * @start: Start of the virtual address 342 * @size: Total size of the virtual address range. 343 * @asid: The value of address space identifier (ASID), or FLUSH_TLB_NO_ASID 344 * for flushing all address spaces. 345 * 346 * Return: 0 on success, appropriate linux error code otherwise. 347 */ 348 int sbi_remote_sfence_vma_asid(const struct cpumask *cpu_mask, 349 unsigned long start, 350 unsigned long size, 351 unsigned long asid) 352 { 353 if (asid == FLUSH_TLB_NO_ASID) 354 return __sbi_rfence(SBI_EXT_RFENCE_REMOTE_SFENCE_VMA, 355 cpu_mask, start, size, 0, 0); 356 else 357 return __sbi_rfence(SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID, 358 cpu_mask, start, size, asid, 0); 359 } 360 EXPORT_SYMBOL(sbi_remote_sfence_vma_asid); 361 362 /** 363 * sbi_remote_hfence_gvma() - Execute HFENCE.GVMA instructions on given remote 364 * harts for the specified guest physical address range. 365 * @cpu_mask: A cpu mask containing all the target harts. 366 * @start: Start of the guest physical address 367 * @size: Total size of the guest physical address range. 368 * 369 * Return: None 370 */ 371 int sbi_remote_hfence_gvma(const struct cpumask *cpu_mask, 372 unsigned long start, 373 unsigned long size) 374 { 375 return __sbi_rfence(SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA, 376 cpu_mask, start, size, 0, 0); 377 } 378 EXPORT_SYMBOL_GPL(sbi_remote_hfence_gvma); 379 380 /** 381 * sbi_remote_hfence_gvma_vmid() - Execute HFENCE.GVMA instructions on given 382 * remote harts for a guest physical address range belonging to a specific VMID. 383 * 384 * @cpu_mask: A cpu mask containing all the target harts. 385 * @start: Start of the guest physical address 386 * @size: Total size of the guest physical address range. 387 * @vmid: The value of guest ID (VMID). 388 * 389 * Return: 0 if success, Error otherwise. 390 */ 391 int sbi_remote_hfence_gvma_vmid(const struct cpumask *cpu_mask, 392 unsigned long start, 393 unsigned long size, 394 unsigned long vmid) 395 { 396 return __sbi_rfence(SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID, 397 cpu_mask, start, size, vmid, 0); 398 } 399 EXPORT_SYMBOL(sbi_remote_hfence_gvma_vmid); 400 401 /** 402 * sbi_remote_hfence_vvma() - Execute HFENCE.VVMA instructions on given remote 403 * harts for the current guest virtual address range. 404 * @cpu_mask: A cpu mask containing all the target harts. 405 * @start: Start of the current guest virtual address 406 * @size: Total size of the current guest virtual address range. 407 * 408 * Return: None 409 */ 410 int sbi_remote_hfence_vvma(const struct cpumask *cpu_mask, 411 unsigned long start, 412 unsigned long size) 413 { 414 return __sbi_rfence(SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA, 415 cpu_mask, start, size, 0, 0); 416 } 417 EXPORT_SYMBOL(sbi_remote_hfence_vvma); 418 419 /** 420 * sbi_remote_hfence_vvma_asid() - Execute HFENCE.VVMA instructions on given 421 * remote harts for current guest virtual address range belonging to a specific 422 * ASID. 423 * 424 * @cpu_mask: A cpu mask containing all the target harts. 425 * @start: Start of the current guest virtual address 426 * @size: Total size of the current guest virtual address range. 427 * @asid: The value of address space identifier (ASID). 428 * 429 * Return: None 430 */ 431 int sbi_remote_hfence_vvma_asid(const struct cpumask *cpu_mask, 432 unsigned long start, 433 unsigned long size, 434 unsigned long asid) 435 { 436 return __sbi_rfence(SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID, 437 cpu_mask, start, size, asid, 0); 438 } 439 EXPORT_SYMBOL(sbi_remote_hfence_vvma_asid); 440 441 static void sbi_srst_reset(unsigned long type, unsigned long reason) 442 { 443 sbi_ecall(SBI_EXT_SRST, SBI_EXT_SRST_RESET, type, reason, 444 0, 0, 0, 0); 445 pr_warn("%s: type=0x%lx reason=0x%lx failed\n", 446 __func__, type, reason); 447 } 448 449 static int sbi_srst_reboot(struct notifier_block *this, 450 unsigned long mode, void *cmd) 451 { 452 sbi_srst_reset((mode == REBOOT_WARM || mode == REBOOT_SOFT) ? 453 SBI_SRST_RESET_TYPE_WARM_REBOOT : 454 SBI_SRST_RESET_TYPE_COLD_REBOOT, 455 SBI_SRST_RESET_REASON_NONE); 456 return NOTIFY_DONE; 457 } 458 459 static struct notifier_block sbi_srst_reboot_nb; 460 461 static void sbi_srst_power_off(void) 462 { 463 sbi_srst_reset(SBI_SRST_RESET_TYPE_SHUTDOWN, 464 SBI_SRST_RESET_REASON_NONE); 465 } 466 467 /** 468 * sbi_probe_extension() - Check if an SBI extension ID is supported or not. 469 * @extid: The extension ID to be probed. 470 * 471 * Return: 1 or an extension specific nonzero value if yes, 0 otherwise. 472 */ 473 long sbi_probe_extension(int extid) 474 { 475 struct sbiret ret; 476 477 ret = sbi_ecall(SBI_EXT_BASE, SBI_EXT_BASE_PROBE_EXT, extid, 478 0, 0, 0, 0, 0); 479 if (!ret.error) 480 return ret.value; 481 482 return 0; 483 } 484 EXPORT_SYMBOL(sbi_probe_extension); 485 486 static inline long sbi_get_spec_version(void) 487 { 488 return __sbi_base_ecall(SBI_EXT_BASE_GET_SPEC_VERSION); 489 } 490 491 static inline long sbi_get_firmware_id(void) 492 { 493 return __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_ID); 494 } 495 496 static inline long sbi_get_firmware_version(void) 497 { 498 return __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_VERSION); 499 } 500 501 long sbi_get_mvendorid(void) 502 { 503 return __sbi_base_ecall(SBI_EXT_BASE_GET_MVENDORID); 504 } 505 EXPORT_SYMBOL_GPL(sbi_get_mvendorid); 506 507 long sbi_get_marchid(void) 508 { 509 return __sbi_base_ecall(SBI_EXT_BASE_GET_MARCHID); 510 } 511 EXPORT_SYMBOL_GPL(sbi_get_marchid); 512 513 long sbi_get_mimpid(void) 514 { 515 return __sbi_base_ecall(SBI_EXT_BASE_GET_MIMPID); 516 } 517 EXPORT_SYMBOL_GPL(sbi_get_mimpid); 518 519 bool sbi_debug_console_available; 520 521 int sbi_debug_console_write(const char *bytes, unsigned int num_bytes) 522 { 523 phys_addr_t base_addr; 524 struct sbiret ret; 525 526 if (!sbi_debug_console_available) 527 return -EOPNOTSUPP; 528 529 if (is_vmalloc_addr(bytes)) 530 base_addr = page_to_phys(vmalloc_to_page(bytes)) + 531 offset_in_page(bytes); 532 else 533 base_addr = __pa(bytes); 534 if (PAGE_SIZE < (offset_in_page(bytes) + num_bytes)) 535 num_bytes = PAGE_SIZE - offset_in_page(bytes); 536 537 if (IS_ENABLED(CONFIG_32BIT)) 538 ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_WRITE, 539 num_bytes, lower_32_bits(base_addr), 540 upper_32_bits(base_addr), 0, 0, 0); 541 else 542 ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_WRITE, 543 num_bytes, base_addr, 0, 0, 0, 0); 544 545 if (ret.error == SBI_ERR_FAILURE) 546 return -EIO; 547 return ret.error ? sbi_err_map_linux_errno(ret.error) : ret.value; 548 } 549 550 int sbi_debug_console_read(char *bytes, unsigned int num_bytes) 551 { 552 phys_addr_t base_addr; 553 struct sbiret ret; 554 555 if (!sbi_debug_console_available) 556 return -EOPNOTSUPP; 557 558 if (is_vmalloc_addr(bytes)) 559 base_addr = page_to_phys(vmalloc_to_page(bytes)) + 560 offset_in_page(bytes); 561 else 562 base_addr = __pa(bytes); 563 if (PAGE_SIZE < (offset_in_page(bytes) + num_bytes)) 564 num_bytes = PAGE_SIZE - offset_in_page(bytes); 565 566 if (IS_ENABLED(CONFIG_32BIT)) 567 ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_READ, 568 num_bytes, lower_32_bits(base_addr), 569 upper_32_bits(base_addr), 0, 0, 0); 570 else 571 ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_READ, 572 num_bytes, base_addr, 0, 0, 0, 0); 573 574 if (ret.error == SBI_ERR_FAILURE) 575 return -EIO; 576 return ret.error ? sbi_err_map_linux_errno(ret.error) : ret.value; 577 } 578 579 void __init sbi_init(void) 580 { 581 int ret; 582 583 sbi_set_power_off(); 584 ret = sbi_get_spec_version(); 585 if (ret > 0) 586 sbi_spec_version = ret; 587 588 pr_info("SBI specification v%lu.%lu detected\n", 589 sbi_major_version(), sbi_minor_version()); 590 591 if (!sbi_spec_is_0_1()) { 592 pr_info("SBI implementation ID=0x%lx Version=0x%lx\n", 593 sbi_get_firmware_id(), sbi_get_firmware_version()); 594 if (sbi_probe_extension(SBI_EXT_TIME)) { 595 __sbi_set_timer = __sbi_set_timer_v02; 596 pr_info("SBI TIME extension detected\n"); 597 } else { 598 __sbi_set_timer = __sbi_set_timer_v01; 599 } 600 if (sbi_probe_extension(SBI_EXT_IPI)) { 601 __sbi_send_ipi = __sbi_send_ipi_v02; 602 pr_info("SBI IPI extension detected\n"); 603 } else { 604 __sbi_send_ipi = __sbi_send_ipi_v01; 605 } 606 if (sbi_probe_extension(SBI_EXT_RFENCE)) { 607 __sbi_rfence = __sbi_rfence_v02; 608 pr_info("SBI RFENCE extension detected\n"); 609 } else { 610 __sbi_rfence = __sbi_rfence_v01; 611 } 612 if ((sbi_spec_version >= sbi_mk_version(0, 3)) && 613 sbi_probe_extension(SBI_EXT_SRST)) { 614 pr_info("SBI SRST extension detected\n"); 615 pm_power_off = sbi_srst_power_off; 616 sbi_srst_reboot_nb.notifier_call = sbi_srst_reboot; 617 sbi_srst_reboot_nb.priority = 192; 618 register_restart_handler(&sbi_srst_reboot_nb); 619 } 620 if ((sbi_spec_version >= sbi_mk_version(2, 0)) && 621 (sbi_probe_extension(SBI_EXT_DBCN) > 0)) { 622 pr_info("SBI DBCN extension detected\n"); 623 sbi_debug_console_available = true; 624 } 625 } else { 626 __sbi_set_timer = __sbi_set_timer_v01; 627 __sbi_send_ipi = __sbi_send_ipi_v01; 628 __sbi_rfence = __sbi_rfence_v01; 629 } 630 } 631
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.