linux/drivers/ras/amd/atl/denormalize.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * AMD Address Translation Library
 *
 * denormalize.c : Functions to account for interleaving bits
 *
 * Copyright (c) 2023, Advanced Micro Devices, Inc.
 * All Rights Reserved.
 *
 * Author: Yazen Ghannam <[email protected]>
 */

#include "internal.h"

/*
 * Returns the Destination Fabric ID. This is the first (lowest)
 * COH_ST Fabric ID used within a DRAM Address map.
 */
static u16 get_dst_fabric_id(struct addr_ctx *ctx)
{}

/*
 * Make a contiguous gap in address for N bits starting at bit P.
 *
 * Example:
 * address bits:		[20:0]
 * # of interleave bits    (n):	3
 * starting interleave bit (p):	8
 *
 * expanded address bits:	[20+n : n+p][n+p-1 : p][p-1 : 0]
 *				[23   :  11][10    : 8][7   : 0]
 */
static u64 make_space_for_coh_st_id_at_intlv_bit(struct addr_ctx *ctx)
{}

/*
 * Make two gaps in address for N bits.
 * First gap is a single bit at bit P.
 * Second gap is the remaining N-1 bits at bit 12.
 *
 * Example:
 * address bits:		[20:0]
 * # of interleave bits    (n):	3
 * starting interleave bit (p):	8
 *
 * First gap
 * expanded address bits:	[20+1 : p+1][p][p-1 : 0]
 *				[21   :   9][8][7   : 0]
 *
 * Second gap uses result from first.
 *				r = n - 1; remaining interleave bits
 * expanded address bits:	[21+r : 12+r][12+r-1: 12][11 : 0]
 *				[23   :   14][13    : 12][11 : 0]
 */
static u64 make_space_for_coh_st_id_split_2_1(struct addr_ctx *ctx)
{}

/*
 * Make space for CS ID at bits [14:8] as follows:
 *
 * 8 channels	-> bits [10:8]
 * 16 channels	-> bits [11:8]
 * 32 channels	-> bits [14,11:8]
 *
 * 1 die	-> N/A
 * 2 dies	-> bit  [12]
 * 4 dies	-> bits [13:12]
 */
static u64 make_space_for_coh_st_id_mi300(struct addr_ctx *ctx)
{}

/*
 * Take the current calculated address and shift enough bits in the middle
 * to make a gap where the interleave bits will be inserted.
 */
static u64 make_space_for_coh_st_id(struct addr_ctx *ctx)
{}

static u16 get_coh_st_id_df2(struct addr_ctx *ctx)
{}

static u16 get_coh_st_id_df4(struct addr_ctx *ctx)
{}

/*
 * MI300 hash has:
 * (C)hannel[3:0]	= coh_st_id[3:0]
 * (S)tack[0]		= coh_st_id[4]
 * (D)ie[1:0]		= coh_st_id[6:5]
 *
 * Hashed coh_st_id is swizzled so that Stack bit is at the end.
 * coh_st_id = SDDCCCC
 */
static u16 get_coh_st_id_mi300(struct addr_ctx *ctx)
{}

/*
 * Derive the correct Coherent Station ID that represents the interleave bits
 * used within the system physical address. This accounts for the
 * interleave mode, number of interleaved channels/dies/sockets, and
 * other system/mode-specific bit swizzling.
 *
 * Returns:	Coherent Station ID on success.
 *		All bits set on error.
 */
static u16 calculate_coh_st_id(struct addr_ctx *ctx)
{}

static u64 insert_coh_st_id_at_intlv_bit(struct addr_ctx *ctx, u64 denorm_addr, u16 coh_st_id)
{}

static u64 insert_coh_st_id_split_2_1(struct addr_ctx *ctx, u64 denorm_addr, u16 coh_st_id)
{}

static u64 insert_coh_st_id_split_2_2(struct addr_ctx *ctx, u64 denorm_addr, u16 coh_st_id)
{}

static u64 insert_coh_st_id(struct addr_ctx *ctx, u64 denorm_addr, u16 coh_st_id)
{}

/*
 * MI300 systems have a fixed, hardware-defined physical-to-logical
 * Coherent Station mapping. The Remap registers are not used.
 */
static const u16 phy_to_log_coh_st_map_mi300[] =;

static u16 get_logical_coh_st_fabric_id_mi300(struct addr_ctx *ctx)
{}

static u16 get_logical_coh_st_fabric_id(struct addr_ctx *ctx)
{}

static u16 get_logical_coh_st_fabric_id_for_current_spa(struct addr_ctx *ctx,
							struct df4p5_denorm_ctx *denorm_ctx)
{}

static int denorm_addr_common(struct addr_ctx *ctx)
{}

static int denorm_addr_df3_6chan(struct addr_ctx *ctx)
{}

static int denorm_addr_df4_np2(struct addr_ctx *ctx)
{}

static u64 normalize_addr_df4p5_np2(struct addr_ctx *ctx, struct df4p5_denorm_ctx *denorm_ctx,
				    u64 addr)
{}

static void recalculate_hashed_bits_df4p5_np2(struct addr_ctx *ctx,
					      struct df4p5_denorm_ctx *denorm_ctx)
{}

static bool match_logical_coh_st_fabric_id(struct addr_ctx *ctx,
					   struct df4p5_denorm_ctx *denorm_ctx)
{}

static bool match_norm_addr(struct addr_ctx *ctx, struct df4p5_denorm_ctx *denorm_ctx)
{}

static int check_permutations(struct addr_ctx *ctx, struct df4p5_denorm_ctx *denorm_ctx)
{}

static int init_df4p5_denorm_ctx(struct addr_ctx *ctx, struct df4p5_denorm_ctx *denorm_ctx)
{}

/*
 * For DF 4.5, parts of the physical address can be directly pulled from the
 * normalized address. The exact bits will differ between interleave modes, but
 * using NPS0_24CHAN_1K_HASH as an example, the normalized address consists of
 * bits [63:13] (divided by 3), bits [11:10], and bits [7:0] of the system
 * physical address.
 *
 * In this case, there is no way to reconstruct the missing bits (bits 8, 9,
 * and 12) from the normalized address. Additionally, when bits [63:13] are
 * divided by 3, the remainder is dropped. Determine the proper combination of
 * "lost" bits and dropped remainder by iterating through each possible
 * permutation of these bits and then normalizing the generated system physical
 * addresses. If the normalized address matches the address we are trying to
 * translate, then we have found the correct permutation of bits.
 */
static int denorm_addr_df4p5_np2(struct addr_ctx *ctx)
{}

int denormalize_address(struct addr_ctx *ctx)
{}