blob: 7b7669bed0657f8472cc34a5408843de5ffce3eb [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Darwin Rambod32d4112014-06-09 11:12:59 -07002/*
Sean Anderson56e3fe82022-03-22 16:59:18 -04003 * Copyright (C) 2022 Sean Anderson <sean.anderson@seco.com>
Darwin Rambod32d4112014-06-09 11:12:59 -07004 * Copyright 2014 Broadcom Corporation
Darwin Rambod32d4112014-06-09 11:12:59 -07005 */
6
Darwin Rambod32d4112014-06-09 11:12:59 -07007#include <common.h>
Darwin Rambod32d4112014-06-09 11:12:59 -07008
Andre Przywarab94ebde2022-10-05 17:38:48 +01009/*
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 Przywarac1b6d762022-10-05 17:38:47 +010015#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 Rambod32d4112014-06-09 11:12:59 -070025/*
26 * Call the handler
27 */
Kautuk Consula51bb742022-12-07 17:12:34 +053028long smh_trap(unsigned int sysnum, void *addr)
Darwin Rambod32d4112014-06-09 11:12:59 -070029{
Linus Walleij6fda2652014-12-15 11:05:56 +010030 register long result asm("r0");
Andre Przywara0cd671b2022-10-05 17:38:49 +010031 register void *_addr asm("r1") = addr;
Andre Przywarac1b6d762022-10-05 17:38:47 +010032
Andre Przywarab94ebde2022-10-05 17:38:48 +010033 /*
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 Przywarac1b6d762022-10-05 17:38:47 +010041 asm volatile (SMH_TRAP
42 : "=r" (result)
Andre Przywara0cd671b2022-10-05 17:38:49 +010043 : "0"(sysnum), "r"(USE_PTR(_addr))
Andre Przywarac1b6d762022-10-05 17:38:47 +010044 : "memory");
45
Darwin Rambod32d4112014-06-09 11:12:59 -070046 return result;
47}