refactor(sgi): move from "sgi" to "neoverse_rd"

Currently, reference design platforms such as RD-N2, RD-N1-Edge,
RD-V1-MC, RD-V1 and SGI-575 utilize "css/sgi" as the common source
directory. The "sgi" prefix originated from the System Guidance for
Infrastructure (SGI) and was initially associated with the SGI-575
platform. However, subsequent platforms released were under the Neoverse
Reference Design product name.

To align with the Neoverse Reference Design nomenclature, rename the
common source directory from "css/sgi" to "css/neoverse_rd" and update
all file prefixes from "sgi" to "nrd."

Signed-off-by: Rohit Mathew <Rohit.Mathew@arm.com>
Change-Id: I3dcbb31b9ab202e82caf25218ba33c520dcea4e4
diff --git a/plat/arm/css/neoverse_rd/ras/nrd_ras_common.c b/plat/arm/css/neoverse_rd/ras/nrd_ras_common.c
new file mode 100644
index 0000000..d920560
--- /dev/null
+++ b/plat/arm/css/neoverse_rd/ras/nrd_ras_common.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <bl31/interrupt_mgmt.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include <nrd_ras.h>
+
+static struct plat_sgi_ras_config *sgi_ras_config;
+
+/*
+ * Find event map for a given interrupt number. On success, returns pointer to
+ * the event map. On error, returns NULL.
+ */
+struct sgi_ras_ev_map *sgi_find_ras_event_map_by_intr(uint32_t intr_num)
+{
+	struct sgi_ras_ev_map *map;
+	int size;
+	int i;
+
+	if (sgi_ras_config == NULL) {
+		ERROR("RAS config is NULL\n");
+		return NULL;
+	}
+
+	map = sgi_ras_config->ev_map;
+	size = sgi_ras_config->ev_map_size;
+
+	for (i = 0; i < size; i++) {
+		if (map->intr == intr_num)
+			return map;
+
+		map++;
+	}
+
+	return NULL;
+}
+
+/*
+ * Programs GIC registers and configures interrupt ID's as Group0 EL3
+ * interrupts. Current support is to register PPI and SPI interrupts.
+ */
+static void sgi_ras_intr_configure(int intr, int intr_type)
+{
+	plat_ic_set_interrupt_type(intr, INTR_TYPE_EL3);
+	plat_ic_set_interrupt_priority(intr, PLAT_RAS_PRI);
+	plat_ic_clear_interrupt_pending(intr);
+
+	/* Routing mode option available only for SPI interrupts */
+	if (intr_type == SGI_RAS_INTR_TYPE_SPI) {
+		plat_ic_set_spi_routing(intr, INTR_ROUTING_MODE_ANY,
+					(u_register_t)read_mpidr_el1());
+	}
+	plat_ic_enable_interrupt(intr);
+}
+
+/*
+ * Initialization function for the framework.
+ *
+ * Registers RAS config provided by the platform and then configures and
+ * enables interrupt for each registered error. On success, return 0.
+ */
+int sgi_ras_platform_setup(struct plat_sgi_ras_config *config)
+{
+	struct sgi_ras_ev_map *map;
+	int size;
+	int i;
+
+	/* Check if parameter is valid. */
+	if (config == NULL) {
+		ERROR("SGI: Failed to register RAS config\n");
+		return -1;
+	}
+
+	/*
+	 * Maintain a reference to the platform RAS config data for later
+	 * use.
+	 */
+	sgi_ras_config = config;
+
+	map = sgi_ras_config->ev_map;
+	size = sgi_ras_config->ev_map_size;
+
+	for (i = 0; i < size; i++) {
+		sgi_ras_intr_configure(map->intr, map->intr_type);
+		map++;
+	}
+
+	INFO("SGI: Platform RAS setup successful\n");
+
+	return 0;
+}
diff --git a/plat/arm/css/neoverse_rd/ras/nrd_ras_cpu.c b/plat/arm/css/neoverse_rd/ras/nrd_ras_cpu.c
new file mode 100644
index 0000000..71d1775
--- /dev/null
+++ b/plat/arm/css/neoverse_rd/ras/nrd_ras_cpu.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <bl31/interrupt_mgmt.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/extensions/ras.h>
+#include <plat/common/platform.h>
+#include <services/sdei.h>
+#include <services/spm_mm_svc.h>
+
+#include <nrd_ras.h>
+
+#define CPU_CONTEXT_REG_GPR_ARR_SIZE 32
+#define CPU_CONTEXT_REG_EL1_ARR_SIZE 17
+#define CPU_CONTEXT_REG_EL2_ARR_SIZE 16
+#define CPU_CONTEXT_REG_EL3_ARR_SIZE 10
+
+/*
+ * MM Communicate message header GUID to indicate the payload is intended for
+ * CPU MM driver.
+ */
+struct efi_guid cpu_ecc_event_guid = {
+	0x2c1b3bfc, 0x42cd, 0x4a66,
+	{0xac, 0xd1, 0xa4, 0xd1, 0x63, 0xe9, 0x90, 0xf6}
+	};
+
+/*
+ * CPU error information data structure communicated as part of MM
+ * Communication data payload.
+ */
+typedef struct {
+	uint64_t ErrStatus;
+	uint64_t ErrMisc0;
+	uint64_t ErrAddr;
+	uint64_t SecurityState;
+	uint64_t ErrCtxGpr[CPU_CONTEXT_REG_GPR_ARR_SIZE];
+	uint64_t ErrCtxEl1Reg[CPU_CONTEXT_REG_EL1_ARR_SIZE];
+	uint64_t ErrCtxEl2Reg[CPU_CONTEXT_REG_EL2_ARR_SIZE];
+	uint64_t ErrCtxEl3Reg[CPU_CONTEXT_REG_EL3_ARR_SIZE];
+} cpu_err_info;
+
+/*
+ * Reads the CPU context and error information from the relevant registers and
+ * populates the CPU error information data structure.
+ */
+static void populate_cpu_err_data(cpu_err_info *cpu_info,
+					uint64_t security_state)
+{
+	void *ctx;
+
+	ctx = cm_get_context(security_state);
+
+	cpu_info->ErrStatus = read_erxstatus_el1();
+	cpu_info->ErrMisc0 = read_erxmisc0_el1();
+	cpu_info->ErrAddr = read_erxaddr_el1();
+	cpu_info->SecurityState = security_state;
+
+	/* populate CPU EL1 context information. */
+	cpu_info->ErrCtxEl1Reg[0]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_ELR_EL1);
+	cpu_info->ErrCtxEl1Reg[1]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_ESR_EL1);
+	cpu_info->ErrCtxEl1Reg[2]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_FAR_EL1);
+	cpu_info->ErrCtxEl1Reg[3]  = read_isr_el1();
+	cpu_info->ErrCtxEl1Reg[4]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_MAIR_EL1);
+	cpu_info->ErrCtxEl1Reg[5]  = read_midr_el1();
+	cpu_info->ErrCtxEl1Reg[6]  = read_mpidr_el1();
+	cpu_info->ErrCtxEl1Reg[7]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_SCTLR_EL1);
+	cpu_info->ErrCtxEl1Reg[8]  = read_ctx_reg(get_gpregs_ctx(ctx),
+						  CTX_GPREG_SP_EL0);
+	cpu_info->ErrCtxEl1Reg[9]  = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_SP_EL1);
+	cpu_info->ErrCtxEl1Reg[10] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_SPSR_EL1);
+	cpu_info->ErrCtxEl1Reg[11] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_TCR_EL1);
+	cpu_info->ErrCtxEl1Reg[12] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_TPIDR_EL0);
+	cpu_info->ErrCtxEl1Reg[13] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_TPIDR_EL1);
+	cpu_info->ErrCtxEl1Reg[14] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_TPIDRRO_EL0);
+	cpu_info->ErrCtxEl1Reg[15] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_TTBR0_EL1);
+	cpu_info->ErrCtxEl1Reg[16] = read_ctx_reg(get_el1_sysregs_ctx(ctx),
+						  CTX_TTBR1_EL1);
+
+#if CTX_INCLUDE_EL2_REGS
+	cpu_info->ErrCtxEl2Reg[0]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_ELR_EL2);
+	cpu_info->ErrCtxEl2Reg[1]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_ESR_EL2);
+	cpu_info->ErrCtxEl2Reg[2]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_FAR_EL2);
+	cpu_info->ErrCtxEl2Reg[3]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_HACR_EL2);
+	cpu_info->ErrCtxEl2Reg[4]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_HCR_EL2);
+	cpu_info->ErrCtxEl2Reg[5]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_HPFAR_EL2);
+	cpu_info->ErrCtxEl2Reg[6]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_MAIR_EL2);
+	cpu_info->ErrCtxEl2Reg[7]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_SCTLR_EL2);
+	cpu_info->ErrCtxEl2Reg[8]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_SP_EL2);
+	cpu_info->ErrCtxEl2Reg[9]   = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_SPSR_EL2);
+	cpu_info->ErrCtxEl2Reg[10]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_TCR_EL2);
+	cpu_info->ErrCtxEl2Reg[11]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_TPIDR_EL2);
+	cpu_info->ErrCtxEl2Reg[12]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_TTBR0_EL2);
+	cpu_info->ErrCtxEl2Reg[13]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_VTCR_EL2);
+	cpu_info->ErrCtxEl2Reg[14]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_VTTBR_EL2);
+	cpu_info->ErrCtxEl2Reg[15]  = read_ctx_reg(get_el2_sysregs_ctx(ctx),
+						   CTX_ESR_EL2);
+#endif
+
+	cpu_info->ErrCtxEl3Reg[0]   = read_ctx_reg(get_el3state_ctx(ctx),
+						   CTX_ELR_EL3);
+	cpu_info->ErrCtxEl3Reg[1]   = read_ctx_reg(get_el3state_ctx(ctx),
+						   CTX_ESR_EL3);
+	cpu_info->ErrCtxEl3Reg[2]   = read_far_el3();
+	cpu_info->ErrCtxEl3Reg[4]   = read_mair_el3();
+	cpu_info->ErrCtxEl3Reg[5]   = read_sctlr_el3();
+	cpu_info->ErrCtxEl3Reg[6]   = 0; /* sp_el3 */
+	cpu_info->ErrCtxEl3Reg[7]   = read_tcr_el3();
+	cpu_info->ErrCtxEl3Reg[8]   = read_tpidr_el3();
+	cpu_info->ErrCtxEl3Reg[9]   = read_ttbr0_el3();
+}
+
+/* CPU RAS interrupt handler */
+int sgi_ras_cpu_intr_handler(const struct err_record_info *err_rec,
+				int probe_data,
+				const struct err_handler_data *const data)
+{
+	struct sgi_ras_ev_map *ras_map;
+	mm_communicate_header_t *header;
+	cpu_err_info cpu_info = {0};
+	uint64_t clear_status;
+	uint32_t intr;
+	int ret;
+
+	cm_el1_sysregs_context_save(NON_SECURE);
+	intr = data->interrupt;
+
+	INFO("[CPU RAS] CPU intr received = %d on cpu_id = %d\n",
+		intr, plat_my_core_pos());
+
+	INFO("[CPU RAS] ERXMISC0_EL1 = 0x%lx\n", read_erxmisc0_el1());
+	INFO("[CPU RAS] ERXSTATUS_EL1 = 0x%lx\n", read_erxstatus_el1());
+	INFO("[CPU RAS] ERXADDR_EL1 = 0x%lx\n", read_erxaddr_el1());
+
+	/* Populate CPU Error Source Information. */
+	populate_cpu_err_data(&cpu_info, get_interrupt_src_ss(data->flags));
+
+	/* Clear the interrupt. */
+	clear_status = read_erxstatus_el1();
+	write_erxstatus_el1(clear_status);
+	plat_ic_end_of_interrupt(intr);
+
+	header = (void *) PLAT_SPM_BUF_BASE;
+	memset(header, 0, sizeof(*header));
+	memcpy(&header->data, &cpu_info, sizeof(cpu_info));
+	header->message_len = sizeof(cpu_info);
+	memcpy(&header->header_guid, (void *) &cpu_ecc_event_guid,
+		sizeof(struct efi_guid));
+
+	spm_mm_sp_call(MM_COMMUNICATE_AARCH64, (uint64_t)header, 0,
+		       plat_my_core_pos());
+
+	/*
+	 * Find if this is a RAS interrupt. There must be an event against
+	 * this interrupt
+	 */
+	ras_map = sgi_find_ras_event_map_by_intr(intr);
+	if (ras_map == NULL) {
+		ERROR("SGI: RAS error info for interrupt id: %d not found\n",
+			intr);
+		return -1;
+	}
+
+	/* Dispatch the event to the SDEI client */
+	ret = sdei_dispatch_event(ras_map->sdei_ev_num);
+	if (ret != 0) {
+		/*
+		 * sdei_dispatch_event() may return failing result in some
+		 * cases, for example kernel may not have registered a handler
+		 * or RAS event may happen early during boot. We restore the NS
+		 * context when sdei_dispatch_event() returns failing result.
+		 */
+		ERROR("SDEI dispatch failed: %d", ret);
+		cm_el1_sysregs_context_restore(NON_SECURE);
+		cm_set_next_eret_context(NON_SECURE);
+	}
+
+	return ret;
+}
diff --git a/plat/arm/css/neoverse_rd/ras/nrd_ras_sram.c b/plat/arm/css/neoverse_rd/ras/nrd_ras_sram.c
new file mode 100644
index 0000000..8f4fb4c
--- /dev/null
+++ b/plat/arm/css/neoverse_rd/ras/nrd_ras_sram.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl31/interrupt_mgmt.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <plat/common/platform.h>
+#include <services/sdei.h>
+#include <services/spm_mm_svc.h>
+
+#include <platform_def.h>
+#include <nrd_ras.h>
+
+/* Base Element RAM Error Record offsets. */
+#define ERRSTATUS	U(0)
+#define ERRCODE		U(8)
+#define ERRADDR		U(12)
+
+/*
+ * Base Element RAM error information data structure communicated as part of MM
+ * Communication data payload.
+ */
+typedef struct sgi_sram_err_info {
+	uint32_t err_status;
+	uint32_t err_code;
+	uint32_t err_addr;
+} sgi_sram_err_info_t;
+
+/*
+ * MM Communicate message header GUID to indicate the payload is intended for
+ * base element RAM MM driver.
+ */
+struct efi_guid sram_ecc_event_guid = {
+	0x7312db4f, 0xd0c4, 0x4fb5,
+	{ 0x81, 0x2c, 0xb7, 0x4b, 0xc6, 0xc4, 0xa9, 0x38 }
+};
+
+/* Base element RAM RAS error interrupt handler */
+int sgi_ras_sram_intr_handler(const struct err_record_info *err_rec,
+				int probe_data,
+				const struct err_handler_data *const data)
+{
+	struct sgi_ras_ev_map *ras_map;
+	mm_communicate_header_t *header;
+	sgi_sram_err_info_t sram_info;
+	uintptr_t base_addr;
+	uint32_t clear_status, intr;
+	int ret;
+
+	cm_el1_sysregs_context_save(NON_SECURE);
+	intr = data->interrupt;
+
+	INFO("SGI: Base element RAM interrupt [%d] handler\n", intr);
+
+	/* Determine error record base address to read. */
+	base_addr = 0;
+	if (intr == NS_RAM_ECC_CE_INT || intr == NS_RAM_ECC_UE_INT) {
+		base_addr = SOC_NS_RAM_ERR_REC_BASE;
+	}
+	sram_info.err_status = mmio_read_32(base_addr + ERRSTATUS);
+	sram_info.err_code = mmio_read_32(base_addr + ERRCODE);
+	sram_info.err_addr = mmio_read_32(base_addr + ERRADDR);
+
+	/* Clear the interrupt. */
+	clear_status = mmio_read_32(base_addr + ERRSTATUS);
+	mmio_write_32((base_addr + ERRSTATUS), clear_status);
+
+	/*
+	 * Prepare the MM Communication buffer to pass the base element RAM
+	 * error information to Secure Partition.
+	 */
+	header = (void *)PLAT_SPM_BUF_BASE;
+	memset(header, 0, sizeof(*header));
+	memcpy(&header->data, &sram_info, sizeof(sram_info));
+	header->message_len = sizeof(sram_info);
+	memcpy(&header->header_guid, (void *)&sram_ecc_event_guid,
+		sizeof(struct efi_guid));
+
+	spm_mm_sp_call(MM_COMMUNICATE_AARCH64, (uint64_t)header, 0,
+			plat_my_core_pos());
+
+	plat_ic_end_of_interrupt(intr);
+
+	/*
+	 * Find if this is a RAS interrupt. There must be an event against
+	 * this interrupt
+	 */
+	ras_map = sgi_find_ras_event_map_by_intr(intr);
+	if (ras_map == NULL) {
+		ERROR("SGI: RAS error info for interrupt id: %d not found\n",
+			intr);
+		return -1;
+	}
+
+	/* Dispatch the event to the SDEI client */
+	ret = sdei_dispatch_event(ras_map->sdei_ev_num);
+	if (ret != 0) {
+		/*
+		 * sdei_dispatch_event() may return failing result in some
+		 * cases, for example kernel may not have registered a handler
+		 * or RAS event may happen early during boot. We restore the NS
+		 * context when sdei_dispatch_event() returns failing result.
+		 */
+		ERROR("SDEI dispatch failed: %d", ret);
+		cm_el1_sysregs_context_restore(NON_SECURE);
+		cm_set_next_eret_context(NON_SECURE);
+	}
+
+	return ret;
+}