// SPDX-License-Identifier: MIT
/*
 * Copyright 2025 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 */
#include <linux/list.h>
#include "amdgpu.h"
#include "amdgpu_ras_mgr.h"

static const guid_t MCE			= CPER_NOTIFY_MCE;
static const guid_t CMC			= CPER_NOTIFY_CMC;
static const guid_t BOOT		= BOOT_TYPE;

static const guid_t CRASHDUMP		= AMD_CRASHDUMP;
static const guid_t RUNTIME		= AMD_GPU_NONSTANDARD_ERROR;

#define CPER_SIGNATURE_SZ		(sizeof(((struct cper_hdr *)0)->signature))

static void __inc_entry_length(struct cper_hdr *hdr, uint32_t size)
{
	hdr->record_length += size;
}

static void amdgpu_cper_get_timestamp(struct cper_timestamp *timestamp)
{
	struct tm tm;
	time64_t now = ktime_get_real_seconds();

	time64_to_tm(now, 0, &tm);
	timestamp->seconds = tm.tm_sec;
	timestamp->minutes = tm.tm_min;
	timestamp->hours = tm.tm_hour;
	timestamp->flag = 0;
	timestamp->day = tm.tm_mday;
	timestamp->month = 1 + tm.tm_mon;
	timestamp->year = (1900 + tm.tm_year) % 100;
	timestamp->century = (1900 + tm.tm_year) / 100;
}

void amdgpu_cper_entry_fill_hdr(struct amdgpu_device *adev,
				struct cper_hdr *hdr,
				enum amdgpu_cper_type type,
				enum cper_error_severity sev)
{
	char record_id[16];

	hdr->signature[0]		= 'C';
	hdr->signature[1]		= 'P';
	hdr->signature[2]		= 'E';
	hdr->signature[3]		= 'R';
	hdr->revision			= CPER_HDR_REV_1;
	hdr->signature_end		= 0xFFFFFFFF;
	hdr->error_severity		= sev;

	hdr->valid_bits.platform_id	= 1;
	hdr->valid_bits.timestamp	= 1;

	amdgpu_cper_get_timestamp(&hdr->timestamp);

	snprintf(record_id, 9, "%d:%X",
		 (adev->smuio.funcs && adev->smuio.funcs->get_socket_id) ?
			 adev->smuio.funcs->get_socket_id(adev) :
			 0,
		 atomic_inc_return(&adev->cper.unique_id));
	memcpy(hdr->record_id, record_id, 8);

	snprintf(hdr->platform_id, 16, "0x%04X:0x%04X",
		 adev->pdev->vendor, adev->pdev->device);
	/* pmfw version should be part of creator_id according to CPER spec */
	snprintf(hdr->creator_id, 16, "%s", CPER_CREATOR_ID_AMDGPU);

	switch (type) {
	case AMDGPU_CPER_TYPE_BOOT:
		hdr->notify_type = BOOT;
		break;
	case AMDGPU_CPER_TYPE_FATAL:
	case AMDGPU_CPER_TYPE_BP_THRESHOLD:
		hdr->notify_type = MCE;
		break;
	case AMDGPU_CPER_TYPE_RUNTIME:
		if (sev == CPER_SEV_NON_FATAL_CORRECTED)
			hdr->notify_type = CMC;
		else
			hdr->notify_type = MCE;
		break;
	default:
		dev_err(adev->dev, "Unknown CPER Type\n");
		break;
	}

	__inc_entry_length(hdr, HDR_LEN);
}

static int amdgpu_cper_entry_fill_section_desc(struct amdgpu_device *adev,
					       struct cper_sec_desc *section_desc,
					       bool bp_threshold,
					       bool poison,
					       enum cper_error_severity sev,
					       guid_t sec_type,
					       uint32_t section_length,
					       uint32_t section_offset)
{
	section_desc->revision_minor		= CPER_SEC_MINOR_REV_1;
	section_desc->revision_major		= CPER_SEC_MAJOR_REV_22;
	section_desc->sec_offset		= section_offset;
	section_desc->sec_length		= section_length;
	section_desc->valid_bits.fru_text	= 1;
	section_desc->flag_bits.primary		= 1;
	section_desc->severity			= sev;
	section_desc->sec_type			= sec_type;

	snprintf(section_desc->fru_text, 20, "OAM%d",
		 (adev->smuio.funcs && adev->smuio.funcs->get_socket_id) ?
			 adev->smuio.funcs->get_socket_id(adev) :
			 0);

	if (bp_threshold)
		section_desc->flag_bits.exceed_err_threshold = 1;
	if (poison)
		section_desc->flag_bits.latent_err = 1;

	return 0;
}

int amdgpu_cper_entry_fill_fatal_section(struct amdgpu_device *adev,
					 struct cper_hdr *hdr,
					 uint32_t idx,
					 struct cper_sec_crashdump_reg_data reg_data)
{
	struct cper_sec_desc *section_desc;
	struct cper_sec_crashdump_fatal *section;

	section_desc = (struct cper_sec_desc *)((uint8_t *)hdr + SEC_DESC_OFFSET(idx));
	section = (struct cper_sec_crashdump_fatal *)((uint8_t *)hdr +
		   FATAL_SEC_OFFSET(hdr->sec_cnt, idx));

	amdgpu_cper_entry_fill_section_desc(adev, section_desc, false, false,
					    CPER_SEV_FATAL_UNCORRECTED, CRASHDUMP, FATAL_SEC_LEN,
					    FATAL_SEC_OFFSET(hdr->sec_cnt, idx));

	section->body.reg_ctx_type = CPER_CTX_TYPE_CRASH;
	section->body.reg_arr_size = sizeof(reg_data);
	section->body.data = reg_data;

	__inc_entry_length(hdr, SEC_DESC_LEN + FATAL_SEC_LEN);

	return 0;
}

int amdgpu_cper_entry_fill_runtime_section(struct amdgpu_device *adev,
					   struct cper_hdr *hdr,
					   uint32_t idx,
					   enum cper_error_severity sev,
					   uint32_t *reg_dump,
					   uint32_t reg_count)
{
	struct cper_sec_desc *section_desc;
	struct cper_sec_nonstd_err *section;
	bool poison;

	poison = sev != CPER_SEV_NON_FATAL_CORRECTED;
	section_desc = (struct cper_sec_desc *)((uint8_t *)hdr + SEC_DESC_OFFSET(idx));
	section = (struct cper_sec_nonstd_err *)((uint8_t *)hdr +
		   NONSTD_SEC_OFFSET(hdr->sec_cnt, idx));

	amdgpu_cper_entry_fill_section_desc(adev, section_desc, false, poison,
					    sev, RUNTIME, NONSTD_SEC_LEN,
					    NONSTD_SEC_OFFSET(hdr->sec_cnt, idx));

	reg_count = umin(reg_count, CPER_ACA_REG_COUNT);

	section->hdr.valid_bits.err_info_cnt = 1;
	section->hdr.valid_bits.err_context_cnt = 1;

	section->info.error_type = RUNTIME;
	section->info.ms_chk_bits.err_type_valid = 1;
	section->ctx.reg_ctx_type = CPER_CTX_TYPE_CRASH;
	section->ctx.reg_arr_size = sizeof(section->ctx.reg_dump);

	memcpy(section->ctx.reg_dump, reg_dump, reg_count * sizeof(uint32_t));

	__inc_entry_length(hdr, SEC_DESC_LEN + NONSTD_SEC_LEN);

	return 0;
}

int amdgpu_cper_entry_fill_bad_page_threshold_section(struct amdgpu_device *adev,
						      struct cper_hdr *hdr,
						      uint32_t idx)
{
	struct cper_sec_desc *section_desc;
	struct cper_sec_nonstd_err *section;
	uint32_t socket_id;

	section_desc = (struct cper_sec_desc *)((uint8_t *)hdr + SEC_DESC_OFFSET(idx));
	section = (struct cper_sec_nonstd_err *)((uint8_t *)hdr +
		   NONSTD_SEC_OFFSET(hdr->sec_cnt, idx));

	amdgpu_cper_entry_fill_section_desc(adev, section_desc, true, false,
					    CPER_SEV_FATAL_UNCORRECTED, RUNTIME, NONSTD_SEC_LEN,
					    NONSTD_SEC_OFFSET(hdr->sec_cnt, idx));

	section->hdr.valid_bits.err_info_cnt = 1;
	section->hdr.valid_bits.err_context_cnt = 1;

	section->info.error_type = RUNTIME;
	section->info.valid_bits.ms_chk = 1;
	section->info.ms_chk_bits.err_type_valid = 1;
	section->info.ms_chk_bits.err_type = 1;
	section->info.ms_chk_bits.pcc = 1;
	section->ctx.reg_ctx_type = CPER_CTX_TYPE_CRASH;
	section->ctx.reg_arr_size = sizeof(section->ctx.reg_dump);

	/* Hardcoded Reg dump for bad page threshold CPER */
	socket_id = (adev->smuio.funcs && adev->smuio.funcs->get_socket_id) ?
				adev->smuio.funcs->get_socket_id(adev) :
				0;
	section->ctx.reg_dump[CPER_ACA_REG_CTL_LO]    = 0x1;
	section->ctx.reg_dump[CPER_ACA_REG_CTL_HI]    = 0x0;
	section->ctx.reg_dump[CPER_ACA_REG_STATUS_LO] = 0x137;
	section->ctx.reg_dump[CPER_ACA_REG_STATUS_HI] = 0xB0000000;
	section->ctx.reg_dump[CPER_ACA_REG_ADDR_LO]   = 0x0;
	section->ctx.reg_dump[CPER_ACA_REG_ADDR_HI]   = 0x0;
	section->ctx.reg_dump[CPER_ACA_REG_MISC0_LO]  = 0x0;
	section->ctx.reg_dump[CPER_ACA_REG_MISC0_HI]  = 0x0;
	section->ctx.reg_dump[CPER_ACA_REG_CONFIG_LO] = 0x2;
	section->ctx.reg_dump[CPER_ACA_REG_CONFIG_HI] = 0x1ff;
	section->ctx.reg_dump[CPER_ACA_REG_IPID_LO]   = (socket_id / 4) & 0x01;
	section->ctx.reg_dump[CPER_ACA_REG_IPID_HI]   = 0x096 | (((socket_id % 4) & 0x3) << 12);
	section->ctx.reg_dump[CPER_ACA_REG_SYND_LO]   = 0x0;
	section->ctx.reg_dump[CPER_ACA_REG_SYND_HI]   = 0x0;

	__inc_entry_length(hdr, SEC_DESC_LEN + NONSTD_SEC_LEN);

	return 0;
}

struct cper_hdr *amdgpu_cper_alloc_entry(struct amdgpu_device *adev,
					 enum amdgpu_cper_type type,
					 uint16_t section_count)
{
	struct cper_hdr *hdr;
	uint32_t size = 0;

	size += HDR_LEN;
	size += (SEC_DESC_LEN * section_count);

	switch (type) {
	case AMDGPU_CPER_TYPE_RUNTIME:
	case AMDGPU_CPER_TYPE_BP_THRESHOLD:
		size += (NONSTD_SEC_LEN * section_count);
		break;
	case AMDGPU_CPER_TYPE_FATAL:
		size += (FATAL_SEC_LEN * section_count);
		break;
	case AMDGPU_CPER_TYPE_BOOT:
		size += (BOOT_SEC_LEN * section_count);
		break;
	default:
		dev_err(adev->dev, "Unknown CPER Type!\n");
		return NULL;
	}

	hdr = kzalloc(size, GFP_KERNEL);
	if (!hdr)
		return NULL;

	/* Save this early */
	hdr->sec_cnt = section_count;

	return hdr;
}

int amdgpu_cper_generate_bp_threshold_record(struct amdgpu_device *adev)
{
	struct cper_hdr *bp_threshold = NULL;
	struct amdgpu_ring *ring = &adev->cper.ring_buf;
	int ret;

	bp_threshold = amdgpu_cper_alloc_entry(adev, AMDGPU_CPER_TYPE_BP_THRESHOLD, 1);
	if (!bp_threshold) {
		dev_err(adev->dev, "fail to alloc cper entry for bad page threshold record\n");
		return -ENOMEM;
	}

	amdgpu_cper_entry_fill_hdr(adev, bp_threshold,
				   AMDGPU_CPER_TYPE_BP_THRESHOLD,
				   CPER_SEV_FATAL_UNCORRECTED);
	ret = amdgpu_cper_entry_fill_bad_page_threshold_section(adev, bp_threshold, 0);
	if (ret)
		return ret;

	amdgpu_cper_ring_write(ring, bp_threshold, bp_threshold->record_length);
	kfree(bp_threshold);

	return 0;
}

static bool amdgpu_cper_is_hdr(struct amdgpu_ring *ring, u64 pos)
{
	char signature[CPER_SIGNATURE_SZ];

	if ((pos << 2) >= ring->ring_size)
		return false;

	if ((pos << 2) + CPER_SIGNATURE_SZ <= ring->ring_size) {
		memcpy(signature, &ring->ring[pos], CPER_SIGNATURE_SZ);
	} else {
		u32 chunk = ring->ring_size - (pos << 2);

		memcpy(signature, &ring->ring[pos], chunk);
		memcpy(signature + chunk, ring->ring, CPER_SIGNATURE_SZ - chunk);
	}

	return !memcmp(signature, "CPER", CPER_SIGNATURE_SZ);
}

static u32 amdgpu_cper_ring_get_ent_sz(struct amdgpu_ring *ring, u64 pos)
{
	struct cper_hdr chdr;
	u64 p;
	u32 chunk, rec_len = 0;

	chunk = ring->ring_size - (pos << 2);

	if (amdgpu_cper_is_hdr(ring, pos)) {
		if (chunk >= sizeof(chdr)) {
			memcpy(&chdr, &ring->ring[pos], sizeof(chdr));
		} else {
			memcpy(&chdr, &ring->ring[pos], chunk);
			memcpy((u8 *)&chdr + chunk, ring->ring, sizeof(chdr) - chunk);
		}

		rec_len = chdr.record_length;
		goto calc;
	}

	/* ring buffer is not full, no cper data after ring->wptr */
	if (ring->count_dw)
		goto calc;

	for (p = pos + 1; p <= ring->buf_mask; p++) {
		if (amdgpu_cper_is_hdr(ring, p)) {
			rec_len = (p - pos) << 2;
			goto calc;
		}
	}

calc:
	if (!rec_len)
		return chunk;
	else
		return umin(rec_len, chunk);
}

void amdgpu_cper_ring_write(struct amdgpu_ring *ring, void *src, int count)
{
	u64 pos, wptr_old, rptr, next_rptr;
	int rec_cnt_dw = count >> 2;
	u32 chunk, ent_sz;
	u8 *s = (u8 *)src;

	if (count >= ring->ring_size - 4) {
		dev_err(ring->adev->dev,
			"CPER data size(%d) is larger than ring size(%d)\n",
			count, ring->ring_size - 4);

		return;
	}

	mutex_lock(&ring->adev->cper.ring_lock);

	wptr_old = ring->wptr;
	rptr = *ring->rptr_cpu_addr & ring->ptr_mask;

	while (count) {
		ent_sz = amdgpu_cper_ring_get_ent_sz(ring, ring->wptr);
		chunk = umin(ent_sz, count);

		memcpy(&ring->ring[ring->wptr], s, chunk);

		ring->wptr += (chunk >> 2);
		ring->wptr &= ring->ptr_mask;
		count -= chunk;
		s += chunk;
	}

	if (ring->count_dw < rec_cnt_dw)
		ring->count_dw = 0;

	/* the buffer is overflow, adjust rptr */
	if (((wptr_old < rptr) && (rptr <= ring->wptr)) ||
	    ((ring->wptr < wptr_old) && (wptr_old < rptr)) ||
	    ((rptr <= ring->wptr) && (ring->wptr < wptr_old))) {
		pos = (ring->wptr + 1) & ring->ptr_mask;

		do {
			ent_sz = amdgpu_cper_ring_get_ent_sz(ring, pos);
			next_rptr = rptr;
			if (ent_sz >= sizeof(u32))
				next_rptr = (rptr + (ent_sz >> 2)) & ring->ptr_mask;

			if (next_rptr == rptr) {
				/* Corrupt entry size, reset the ring to avoid an infinite loop. */
				rptr = ring->wptr;
				*ring->rptr_cpu_addr = rptr;
				ring->count_dw = (ring->ring_size - 4) >> 2;
				goto out_unlock;
			}

			rptr = next_rptr;
			*ring->rptr_cpu_addr = rptr;

			pos = rptr;
		} while (!amdgpu_cper_is_hdr(ring, rptr));
	}

	if (ring->count_dw >= rec_cnt_dw)
		ring->count_dw -= rec_cnt_dw;

out_unlock:
	mutex_unlock(&ring->adev->cper.ring_lock);
}

static u64 amdgpu_cper_ring_get_rptr(struct amdgpu_ring *ring)
{
	return *(ring->rptr_cpu_addr);
}

static u64 amdgpu_cper_ring_get_wptr(struct amdgpu_ring *ring)
{
	return ring->wptr;
}

static const struct amdgpu_ring_funcs cper_ring_funcs = {
	.type = AMDGPU_RING_TYPE_CPER,
	.align_mask = 0xff,
	.support_64bit_ptrs = false,
	.get_rptr = amdgpu_cper_ring_get_rptr,
	.get_wptr = amdgpu_cper_ring_get_wptr,
};

static int amdgpu_cper_ring_init(struct amdgpu_device *adev)
{
	struct amdgpu_ring *ring = &(adev->cper.ring_buf);

	mutex_init(&adev->cper.ring_lock);

	ring->adev = NULL;
	ring->ring_obj = NULL;
	ring->use_doorbell = false;
	ring->no_scheduler = true;
	ring->funcs = &cper_ring_funcs;

	sprintf(ring->name, "cper");
	return amdgpu_ring_init(adev, ring, CPER_MAX_RING_SIZE, NULL, 0,
				AMDGPU_RING_PRIO_DEFAULT, NULL);
}

int amdgpu_cper_init(struct amdgpu_device *adev)
{
	int r;

	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_ras_cper_en(adev))
		return 0;
	else if (!amdgpu_sriov_vf(adev) && !amdgpu_uniras_enabled(adev))
		return 0;

	r = amdgpu_cper_ring_init(adev);
	if (r) {
		dev_err(adev->dev, "failed to initialize cper ring, r = %d\n", r);
		return r;
	}

	mutex_init(&adev->cper.cper_lock);

	adev->cper.enabled = true;
	adev->cper.max_count = CPER_MAX_ALLOWED_COUNT;

	return 0;
}

int amdgpu_cper_deferred_init(struct amdgpu_device *adev)
{
	int r;

	if (adev->cper.enabled)
		return 0;

	r = amdgpu_cper_init(adev);
	if (r || !adev->cper.enabled)
		return r;

#if defined(CONFIG_DEBUG_FS)
	if (adev_to_drm(adev)->primary->debugfs_root)
		amdgpu_debugfs_ring_init(adev, &adev->cper.ring_buf);
#endif

	return 0;
}

int amdgpu_cper_fini(struct amdgpu_device *adev)
{
	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_ras_cper_en(adev))
		return 0;

	adev->cper.enabled = false;

	amdgpu_ring_fini(&(adev->cper.ring_buf));
	adev->cper.count = 0;
	adev->cper.wptr = 0;

	return 0;
}
