Function report

Linux Kernel

v5.5.9

Brick Technologies Co., Ltd

Source Code:arch\x86\kernel\cpu\mce\amd.c Create Date:2022-07-28 08:03:24
Last Modify:2020-03-12 14:18:49 Copyright©Brick
home page Tree
Annotation kernel can get tool activityDownload SCCTChinese

Name:umc_normaddr_to_sysaddr

Proto:int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr)

Type:int

Parameter:

TypeParameterName
u64norm_addr
u16nid
u8umc
u64 *sys_addr
666  ret_addr = norm_addr
674  base = 0
675  cs_id = 0
676  bool hash_enabled = false
679  If amd_df_indirect_read(nid, 0, 0x1B4, umc, & tmp) Then Go to out_err
683  If tmp & BIT(0) Then
684  hi_addr_offset = (tmp & GENMASK_ULL(31, 20)) << 8
686  If norm_addr >= hi_addr_offset Then
688  base = 1
693  If amd_df_indirect_read(nid, 0, 0x110 + (8 * base), umc, & tmp) Then Go to out_err
697  If Not (tmp & BIT(0)) Then
698  pr_err("%s: Invalid DramBaseAddress range: 0x%x.\n", __func__, tmp)
700  Go to out_err
703  lgcy_mmio_hole_en = tmp & BIT(1)
704  intlv_num_chan = tmp >> 4 & 0xF
705  intlv_addr_sel = tmp >> 8 & 0x7
706  dram_base_addr = (tmp & GENMASK_ULL(31, 12)) << 16
709  If intlv_addr_sel > 3 Then
710  pr_err("%s: Invalid interleave address select %d.\n", __func__, intlv_addr_sel)
712  Go to out_err
716  If amd_df_indirect_read(nid, 0, 0x114 + (8 * base), umc, & tmp) Then Go to out_err
719  intlv_num_sockets = tmp >> 8 & 0x1
720  intlv_num_dies = tmp >> 10 & 0x3
721  dram_limit_addr = (tmp & GENMASK_ULL(31, 12)) << 16 | GENMASK_ULL(27, 0)
723  intlv_addr_bit = intlv_addr_sel + 8
727  Case intlv_num_chan == 0
727  intlv_num_chan = 0
727  Break
728  Case intlv_num_chan == 1
728  intlv_num_chan = 1
728  Break
729  Case intlv_num_chan == 3
729  intlv_num_chan = 2
729  Break
730  Case intlv_num_chan == 5
730  intlv_num_chan = 3
730  Break
731  Case intlv_num_chan == 7
731  intlv_num_chan = 4
731  Break
733  Case intlv_num_chan == 8
733  intlv_num_chan = 1
734  hash_enabled = true
735  Break
736  Default
737  pr_err("%s: Invalid number of interleaved channels %d.\n", __func__, intlv_num_chan)
739  Go to out_err
742  num_intlv_bits = intlv_num_chan
744  If intlv_num_dies > 2 Then
745  pr_err("%s: Invalid number of interleaved nodes/dies %d.\n", __func__, intlv_num_dies)
747  Go to out_err
750  num_intlv_bits += intlv_num_dies
753  num_intlv_bits += intlv_num_sockets
756  If num_intlv_bits > 4 Then
757  pr_err("%s: Invalid interleave bits %d.\n", __func__, num_intlv_bits)
759  Go to out_err
762  If num_intlv_bits > 0 Then
772  If amd_df_indirect_read(nid, 0, 0x50, umc, & tmp) Then Go to out_err
775  cs_fabric_id = tmp >> 8 & 0xFF
776  die_id_bit = 0
779  If intlv_num_chan Then
781  cs_mask = (1 << die_id_bit) - 1
785  sock_id_bit = die_id_bit
788  If intlv_num_dies || intlv_num_sockets Then If amd_df_indirect_read(nid, 1, 0x208, umc, & tmp) Then
790  Go to out_err
793  If intlv_num_dies Then
795  die_id_shift = tmp >> 24 & 0xF
796  die_id_mask = tmp >> 8 & 0xFF
802  If intlv_num_sockets Then
803  socket_id_shift = tmp >> 28 & 0xF
804  socket_id_mask = tmp >> 16 & 0xFF
817  temp_addr_y = ret_addr & GENMASK_ULL(intlv_addr_bit - 1, 0)
818  temp_addr_i = cs_id << intlv_addr_bit
819  temp_addr_x = (ret_addr & GENMASK_ULL(63, intlv_addr_bit)) << num_intlv_bits
820  ret_addr = temp_addr_x | temp_addr_i | temp_addr_y
824  ret_addr += dram_base_addr
827  If lgcy_mmio_hole_en Then
828  If amd_df_indirect_read(nid, 0, 0x104, umc, & tmp) Then Go to out_err
831  dram_hole_base = tmp & Create a contiguous bitmask starting at bit position @l and ending at* position @h. For example* GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.(31, 24)
832  If ret_addr >= dram_hole_base Then ret_addr += BIT_ULL(32) - dram_hole_base
836  If hash_enabled Then
838  hashed_bit = ret_addr >> 12 ^ ret_addr >> 18 ^ ret_addr >> 21 ^ ret_addr >> 30 ^ cs_id
844  hashed_bit &= BIT(0)
846  If hashed_bit != ( ret_addr >> intlv_addr_bit & BIT(0)) Then ret_addr ^= BIT(intlv_addr_bit)
851  If ret_addr > dram_limit_addr Then Go to out_err
854  sys_addr = ret_addr
855  Return 0
857  out_err :
858  Return -EINVAL