diff options
Diffstat (limited to 'roms/skiboot/libc/include/assert.h')
-rw-r--r-- | roms/skiboot/libc/include/assert.h | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/roms/skiboot/libc/include/assert.h b/roms/skiboot/libc/include/assert.h new file mode 100644 index 000000000..1e511fbe5 --- /dev/null +++ b/roms/skiboot/libc/include/assert.h @@ -0,0 +1,60 @@ +/****************************************************************************** + * Copyright (c) 2004, 2008, 2012 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#ifndef _ASSERT_H +#define _ASSERT_H + +struct trap_table_entry { + unsigned long address; + const char *message; +}; + +extern struct trap_table_entry __trap_table_start[]; +extern struct trap_table_entry __trap_table_end[]; + +#define stringify(expr) stringify_1(expr) +/* Double-indirection required to stringify expansions */ +#define stringify_1(expr) #expr + +void __attribute__((noreturn)) assert_fail(const char *msg, + const char *file, + unsigned int line, + const char *function); + +/* + * The 'nop' gets patched to 'trap' after skiboot takes over the exception + * vectors, then patched to 'nop' before booting the OS (see patch_traps). + * This makes assert fall through to assert_fail when we can't use the 0x700 + * interrupt. + */ +#define assert(cond) \ +do { \ + /* evaluate cond exactly once */ \ + const unsigned long __cond = (unsigned long)(cond); \ + asm volatile( \ + " cmpdi %0,0" "\n\t" \ + " bne 2f" "\n\t" \ + "1: nop # assert" "\n\t" \ + "2:" "\n\t" \ + ".section .rodata" "\n\t" \ + "3: .string \"assert failed at " __FILE__ ":" stringify(__LINE__) "\"" "\n\t" \ + ".previous" "\n\t" \ + ".section .trap_table,\"aw\"" "\n\t" \ + ".llong 1b" "\n\t" \ + ".llong 3b" "\n\t" \ + ".previous" "\n\t" \ + : : "r"(__cond) : "cr0"); \ + if (!__cond) \ + assert_fail(stringify(cond), __FILE__, __LINE__, __FUNCTION__); \ +} while (0) + +#endif |