// 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) { … }