Tom Rini | 10e4779 | 2018-05-06 17:58:06 -0400 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0+ |
Darwin Rambo | d32d411 | 2014-06-09 11:12:59 -0700 | [diff] [blame] | 2 | /* |
Sean Anderson | 56e3fe8 | 2022-03-22 16:59:18 -0400 | [diff] [blame] | 3 | * Copyright (C) 2022 Sean Anderson <sean.anderson@seco.com> |
Darwin Rambo | d32d411 | 2014-06-09 11:12:59 -0700 | [diff] [blame] | 4 | * Copyright 2014 Broadcom Corporation |
Darwin Rambo | d32d411 | 2014-06-09 11:12:59 -0700 | [diff] [blame] | 5 | */ |
| 6 | |
Darwin Rambo | d32d411 | 2014-06-09 11:12:59 -0700 | [diff] [blame] | 7 | #include <common.h> |
Darwin Rambo | d32d411 | 2014-06-09 11:12:59 -0700 | [diff] [blame] | 8 | |
Andre Przywara | b94ebde | 2022-10-05 17:38:48 +0100 | [diff] [blame] | 9 | /* |
| 10 | * Macro to force the compiler to *populate* memory (for an array or struct) |
| 11 | * before passing the pointer to an inline assembly call. |
| 12 | */ |
| 13 | #define USE_PTR(ptr) *(const char (*)[]) (ptr) |
| 14 | |
Andre Przywara | c1b6d76 | 2022-10-05 17:38:47 +0100 | [diff] [blame] | 15 | #if defined(CONFIG_ARM64) |
| 16 | #define SMH_TRAP "hlt #0xf000" |
| 17 | #elif defined(CONFIG_CPU_V7M) |
| 18 | #define SMH_TRAP "bkpt #0xAB" |
| 19 | #elif defined(CONFIG_SYS_THUMB_BUILD) |
| 20 | #define SMH_TRAP "svc #0xab" |
| 21 | #else |
| 22 | #define SMH_TRAP "svc #0x123456" |
| 23 | #endif |
| 24 | |
Darwin Rambo | d32d411 | 2014-06-09 11:12:59 -0700 | [diff] [blame] | 25 | /* |
| 26 | * Call the handler |
| 27 | */ |
Kautuk Consul | a51bb74 | 2022-12-07 17:12:34 +0530 | [diff] [blame] | 28 | long smh_trap(unsigned int sysnum, void *addr) |
Darwin Rambo | d32d411 | 2014-06-09 11:12:59 -0700 | [diff] [blame] | 29 | { |
Linus Walleij | 6fda265 | 2014-12-15 11:05:56 +0100 | [diff] [blame] | 30 | register long result asm("r0"); |
Andre Przywara | 0cd671b | 2022-10-05 17:38:49 +0100 | [diff] [blame] | 31 | register void *_addr asm("r1") = addr; |
Andre Przywara | c1b6d76 | 2022-10-05 17:38:47 +0100 | [diff] [blame] | 32 | |
Andre Przywara | b94ebde | 2022-10-05 17:38:48 +0100 | [diff] [blame] | 33 | /* |
| 34 | * We need a memory clobber (aka compiler barrier) for two reasons: |
| 35 | * - The compiler needs to populate any data structures pointed to |
| 36 | * by "addr" *before* the trap instruction is called. |
| 37 | * - At least the SYSREAD function puts the result into memory pointed |
| 38 | * to by "addr", so the compiler must not use a cached version of |
| 39 | * the previous content, after the call has finished. |
| 40 | */ |
Andre Przywara | c1b6d76 | 2022-10-05 17:38:47 +0100 | [diff] [blame] | 41 | asm volatile (SMH_TRAP |
| 42 | : "=r" (result) |
Andre Przywara | 0cd671b | 2022-10-05 17:38:49 +0100 | [diff] [blame] | 43 | : "0"(sysnum), "r"(USE_PTR(_addr)) |
Andre Przywara | c1b6d76 | 2022-10-05 17:38:47 +0100 | [diff] [blame] | 44 | : "memory"); |
| 45 | |
Darwin Rambo | d32d411 | 2014-06-09 11:12:59 -0700 | [diff] [blame] | 46 | return result; |
| 47 | } |