diff --git a/bl2/aarch64/bl2_entrypoint.S b/bl2/aarch64/bl2_entrypoint.S
index 75eb02a9da9cf68f76dbc9b9ac7658082c7d4f12..476efe8520b9360ad8223de95b0c3e37b70592a3 100644
--- a/bl2/aarch64/bl2_entrypoint.S
+++ b/bl2/aarch64/bl2_entrypoint.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -43,8 +43,8 @@ func bl2_entrypoint
 	 * available to BL2 for future use.
 	 * x0 is not currently used.
 	 * ---------------------------------------------
- 	 */
- 	mov	x20, x1
+	 */
+	mov	x20, x1
 
 	/* ---------------------------------------------
 	 * Set the exception vector to something sane.
@@ -126,6 +126,11 @@ func bl2_entrypoint
 	 * ---------------------------------------------
 	 */
 	bl	bl2_main
-_panic:
-	b	_panic
+
+	/* ---------------------------------------------
+	 * Should never reach this point.
+	 * ---------------------------------------------
+	 */
+	bl	plat_panic_handler
+
 endfunc bl2_entrypoint
diff --git a/bl2u/aarch64/bl2u_entrypoint.S b/bl2u/aarch64/bl2u_entrypoint.S
index c9aad81f6e15f6b6318014297f0e6bd429950a15..ef3db926310c768e1ab4ea8350da8be7f260514c 100644
--- a/bl2u/aarch64/bl2u_entrypoint.S
+++ b/bl2u/aarch64/bl2u_entrypoint.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -122,6 +122,10 @@ func bl2u_entrypoint
 	 */
 	bl	bl2u_main
 
-_panic:
-	b	_panic
+	/* ---------------------------------------------
+	 * Should never reach this point.
+	 * ---------------------------------------------
+	 */
+	bl	plat_panic_handler
+
 endfunc bl2u_entrypoint
diff --git a/bl31/aarch64/crash_reporting.S b/bl31/aarch64/crash_reporting.S
index 1d1e60d8072b287ce0192bac5e040170674a8653..ff915728a16236d00cad5b99d51226a21a153862 100644
--- a/bl31/aarch64/crash_reporting.S
+++ b/bl31/aarch64/crash_reporting.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -351,17 +351,17 @@ func do_crash_reporting
 	plat_print_interconnect_regs
 
 	/* Done reporting */
-	b	crash_panic
+	bl	plat_panic_handler
 endfunc do_crash_reporting
 
 #else	/* CRASH_REPORTING */
 func report_unhandled_exception
 report_unhandled_interrupt:
-	b	crash_panic
+	bl	plat_panic_handler
 endfunc report_unhandled_exception
 #endif	/* CRASH_REPORTING */
 
 
 func crash_panic
-	b	crash_panic
-endfunc crash_panic
\ No newline at end of file
+	bl	plat_panic_handler
+endfunc crash_panic
diff --git a/bl32/tsp/aarch64/tsp_entrypoint.S b/bl32/tsp/aarch64/tsp_entrypoint.S
index 531ab9bfadeb476e14ed2cfae751bfed7a5f33f1..453d2c14dd4c84697057b485fceea2aea4631ef7 100644
--- a/bl32/tsp/aarch64/tsp_entrypoint.S
+++ b/bl32/tsp/aarch64/tsp_entrypoint.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -391,7 +391,7 @@ tsp_sel1_intr_return:
 
 	/* Should never reach here */
 tsp_sel1_int_entry_panic:
-	b	tsp_sel1_int_entry_panic
+	bl	plat_panic_handler
 endfunc tsp_sel1_intr_entry
 
 	/*---------------------------------------------
@@ -407,8 +407,9 @@ endfunc tsp_sel1_intr_entry
 func tsp_cpu_resume_entry
 	bl	tsp_cpu_resume_main
 	restore_args_call_smc
-tsp_cpu_resume_panic:
-	b	tsp_cpu_resume_panic
+
+	/* Should never reach here */
+	bl	plat_panic_handler
 endfunc tsp_cpu_resume_entry
 
 	/*---------------------------------------------
@@ -419,8 +420,9 @@ endfunc tsp_cpu_resume_entry
 func tsp_fast_smc_entry
 	bl	tsp_smc_handler
 	restore_args_call_smc
-tsp_fast_smc_entry_panic:
-	b	tsp_fast_smc_entry_panic
+
+	/* Should never reach here */
+	bl	plat_panic_handler
 endfunc tsp_fast_smc_entry
 
 	/*---------------------------------------------
@@ -435,6 +437,7 @@ func tsp_std_smc_entry
 	bl	tsp_smc_handler
 	msr	daifset, #DAIF_FIQ_BIT | DAIF_IRQ_BIT
 	restore_args_call_smc
-tsp_std_smc_entry_panic:
-	b	tsp_std_smc_entry_panic
+
+	/* Should never reach here */
+	bl	plat_panic_handler
 endfunc tsp_std_smc_entry
diff --git a/bl32/tsp/aarch64/tsp_exceptions.S b/bl32/tsp/aarch64/tsp_exceptions.S
index d5e089f6e8a8a00803ff6c68665e645de82a8d5c..edcfb718dd6ac84ecce8d38b89f4e481bd343a53 100644
--- a/bl32/tsp/aarch64/tsp_exceptions.S
+++ b/bl32/tsp/aarch64/tsp_exceptions.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -108,24 +108,23 @@ tsp_exceptions:
 	 * -----------------------------------------------------
 	 */
 sync_exception_sp_el0:
-	wfi
-	b	sync_exception_sp_el0
+	bl	plat_panic_handler
 	check_vector_size sync_exception_sp_el0
 
 	.align	7
 
 irq_sp_el0:
-	b	irq_sp_el0
+	bl	plat_panic_handler
 	check_vector_size irq_sp_el0
 
 	.align	7
 fiq_sp_el0:
-	b	fiq_sp_el0
+	bl	plat_panic_handler
 	check_vector_size fiq_sp_el0
 
 	.align	7
 serror_sp_el0:
-	b	serror_sp_el0
+	bl	plat_panic_handler
 	check_vector_size serror_sp_el0
 
 
@@ -136,8 +135,7 @@ serror_sp_el0:
 	 */
 	.align	7
 sync_exception_sp_elx:
-	wfi
-	b	sync_exception_sp_elx
+	bl	plat_panic_handler
 	check_vector_size sync_exception_sp_elx
 
 	.align	7
@@ -152,7 +150,7 @@ fiq_sp_elx:
 
 	.align	7
 serror_sp_elx:
-	b	serror_sp_elx
+	bl	plat_panic_handler
 	check_vector_size serror_sp_elx
 
 
@@ -163,23 +161,22 @@ serror_sp_elx:
 	 */
 	.align	7
 sync_exception_aarch64:
-	wfi
-	b	sync_exception_aarch64
+	bl	plat_panic_handler
 	check_vector_size sync_exception_aarch64
 
 	.align	7
 irq_aarch64:
-	b	irq_aarch64
+	bl	plat_panic_handler
 	check_vector_size irq_aarch64
 
 	.align	7
 fiq_aarch64:
-	b	fiq_aarch64
+	bl	plat_panic_handler
 	check_vector_size fiq_aarch64
 
 	.align	7
 serror_aarch64:
-	b	serror_aarch64
+	bl	plat_panic_handler
 	check_vector_size serror_aarch64
 
 
@@ -190,22 +187,21 @@ serror_aarch64:
 	 */
 	.align	7
 sync_exception_aarch32:
-	wfi
-	b	sync_exception_aarch32
+	bl	plat_panic_handler
 	check_vector_size sync_exception_aarch32
 
 	.align	7
 irq_aarch32:
-	b	irq_aarch32
+	bl	plat_panic_handler
 	check_vector_size irq_aarch32
 
 	.align	7
 fiq_aarch32:
-	b	fiq_aarch32
+	bl	plat_panic_handler
 	check_vector_size fiq_aarch32
 
 	.align	7
 serror_aarch32:
-	b	serror_aarch32
+	bl	plat_panic_handler
 	check_vector_size serror_aarch32
 	.align	7
diff --git a/common/aarch64/debug.S b/common/aarch64/debug.S
index b3caafb97f8cf36ab39f74247802b6e62d4a80e9..d3538792d390128d97651c8077e40421ee70bb01 100644
--- a/common/aarch64/debug.S
+++ b/common/aarch64/debug.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -120,7 +120,7 @@ endfunc asm_print_str
 /*
  * This function prints a hexadecimal number in x4.
  * In: x4 = the hexadecimal to print.
- * Clobber: x30, x0, x5, x1, x2, x3
+ * Clobber: x30, x0 - x3, x5
  */
 func asm_print_hex
 	mov	x3, x30
@@ -178,7 +178,7 @@ el3_panic:
 	mov	x6, x30
 	bl	plat_crash_console_init
 	/* Check if the console is initialized */
-	cbz	x0, _panic_loop
+	cbz	x0, _panic_handler
 	/* The console is initialized */
 	adr	x4, panic_msg
 	bl	asm_print_str
@@ -186,7 +186,10 @@ el3_panic:
 	/* The panic location is lr -4 */
 	sub	x4, x4, #4
 	bl	asm_print_hex
-_panic_loop:
-	b	_panic_loop
-endfunc do_panic
 
+_panic_handler:
+	/* Pass to plat_panic_handler the address from where el3_panic was
+	 * called, not the address of the call from el3_panic. */
+	mov	x30,x6
+	b	plat_panic_handler
+endfunc do_panic
diff --git a/docs/porting-guide.md b/docs/porting-guide.md
index 741ee20775113035f80aad286bacace2c5ae5740..bd1b4489cbda0fe99848627f382349cdce74e914 100644
--- a/docs/porting-guide.md
+++ b/docs/porting-guide.md
@@ -783,6 +783,20 @@ Possible errors reported by the generic code are:
 
 The default implementation simply spins.
 
+### Function : plat_panic_handler()
+
+    Argument : void
+    Return   : void
+
+This API is called when the generic code encounters an unexpected error
+situation from which it cannot recover. This function must not return,
+and must be implemented in assembly because it may be called before the C
+environment is initialized.
+
+Note: The address from where it was called is stored in x30 (Link Register).
+
+The default implementation simply spins.
+
 
 3.  Modifications specific to a Boot Loader stage
 -------------------------------------------------
diff --git a/include/common/el3_common_macros.S b/include/common/el3_common_macros.S
index 32df7d76346af0dffa9f68530ba3840c583ef460..0cd85c342608ab6c4ca7d59886103fec006d55f6 100644
--- a/include/common/el3_common_macros.S
+++ b/include/common/el3_common_macros.S
@@ -196,8 +196,7 @@
 		/* This is a cold boot on a secondary CPU */
 		bl	plat_secondary_cold_boot_setup
 		/* plat_secondary_cold_boot_setup() is not supposed to return */
-	secondary_panic:
-		b	secondary_panic
+		bl	el3_panic
 
 	do_primary_cold_boot:
 	.endif /* _secondary_cold_boot */
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index f37a80f3e0054137a190afb7c4f447a5ec3aa3a8..5c61f381281b30caa2d17ad7c2baaa55af186225 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -83,6 +83,7 @@ void plat_report_exception(unsigned long);
 int plat_crash_console_init(void);
 int plat_crash_console_putc(int c);
 void plat_error_handler(int err) __dead2;
+void plat_panic_handler(void) __dead2;
 
 /*******************************************************************************
  * Mandatory BL1 functions
diff --git a/plat/arm/board/fvp/aarch64/fvp_helpers.S b/plat/arm/board/fvp/aarch64/fvp_helpers.S
index fe7358f6a2adeb6f18c25d8830ecc3ec74200688..884fee82ad3f68e2145c5d76546ed03aea5e6dab 100644
--- a/plat/arm/board/fvp/aarch64/fvp_helpers.S
+++ b/plat/arm/board/fvp/aarch64/fvp_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -111,8 +111,7 @@ secondary_cold_boot_wait:
 	 */
 	dsb	sy
 	wfi
-cb_panic:
-	b	cb_panic
+	bl	plat_panic_handler
 #else
 	mov_imm	x0, PLAT_ARM_TRUSTED_MAILBOX_BASE
 
@@ -174,7 +173,7 @@ warm_reset:
 	 */
 	mov_imm	x0, PLAT_ARM_TRUSTED_MAILBOX_BASE
 	ldr	x0, [x0]
-	cbz	x0, _panic
+	cbz	x0, _panic_handler
 	ret
 
 	/* ---------------------------------------------------------------------
@@ -182,8 +181,8 @@ warm_reset:
 	 * is empty. This should never happen!
 	 * ---------------------------------------------------------------------
 	 */
-_panic:
-	b	_panic
+_panic_handler:
+	bl	plat_panic_handler
 endfunc plat_get_my_entrypoint
 
 	/* -----------------------------------------------------
diff --git a/plat/arm/board/juno/aarch64/juno_helpers.S b/plat/arm/board/juno/aarch64/juno_helpers.S
index 1931535e74b466a8d977922a00c897b6f61a101c..377b0cb3bcf2125175bfee7822b805169fd15fab 100644
--- a/plat/arm/board/juno/aarch64/juno_helpers.S
+++ b/plat/arm/board/juno/aarch64/juno_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -201,8 +201,7 @@ func plat_reset_handler
 	JUMP_TO_HANDLER_IF_JUNO_R(2)
 
 	/* Board revision is not supported */
-not_supported:
-	b	not_supported
+	bl	plat_panic_handler
 
 endfunc plat_reset_handler
 
diff --git a/plat/common/aarch64/platform_helpers.S b/plat/common/aarch64/platform_helpers.S
index 29f01ce9e0a72c0a76fc17c13f777af81de5ae93..08638303a5a6f98684a8b25fe00c2e9f46d3864c 100644
--- a/plat/common/aarch64/platform_helpers.S
+++ b/plat/common/aarch64/platform_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -39,6 +39,7 @@
 	.weak	plat_disable_acp
 	.weak	bl1_plat_prepare_exit
 	.weak	plat_error_handler
+	.weak	plat_panic_handler
 
 #if !ENABLE_PLAT_COMPAT
 	.globl	platform_get_core_pos
@@ -131,3 +132,12 @@ endfunc bl1_plat_prepare_exit
 func plat_error_handler
 	b	plat_error_handler
 endfunc plat_error_handler
+
+	/* -----------------------------------------------------
+	 * void plat_panic_handler(void) __dead2;
+	 * Endless loop by default.
+	 * -----------------------------------------------------
+	 */
+func plat_panic_handler
+	b	plat_panic_handler
+endfunc plat_panic_handler