blob: bcf8ae1e6e605e97016c410fccee405c7cb40413 [file] [log] [blame]
Soby Mathew9b2de242024-02-27 16:08:42 +00001/*
2 * SPDX-License-Identifier: BSD-3-Clause
3 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4 */
5
AlexeiFedorovffef39a2024-10-28 16:35:21 +00006#include <arm_memory.h>
Soby Mathew9b2de242024-02-27 16:08:42 +00007#include <assert.h>
8#include <platform_api.h>
9#include <utils_def.h>
10
AlexeiFedorovffef39a2024-10-28 16:35:21 +000011static struct arm_memory_layout arm_dram;
12static struct arm_memory_layout arm_dev_ncoh;
13static struct arm_memory_layout arm_dev_coh;
Soby Mathew9b2de242024-02-27 16:08:42 +000014
AlexeiFedorovffef39a2024-10-28 16:35:21 +000015struct arm_memory_layout *arm_get_dram_layout(void)
Soby Mathew9b2de242024-02-27 16:08:42 +000016{
17 return &arm_dram;
18}
19
AlexeiFedorovffef39a2024-10-28 16:35:21 +000020struct arm_memory_layout *arm_get_dev_ncoh_layout(void)
21{
22 return &arm_dev_ncoh;
23}
24
25struct arm_memory_layout *arm_get_dev_coh_layout(void)
26{
27 return &arm_dev_coh;
28}
29
Soby Mathew9b2de242024-02-27 16:08:42 +000030unsigned long plat_granule_addr_to_idx(unsigned long addr)
31{
AlexeiFedorovffef39a2024-10-28 16:35:21 +000032 const struct arm_memory_layout *dram = &arm_dram;
Harry Moulton1c9c7b92024-03-07 16:33:59 +000033 unsigned long r, l = 0UL;
34
Soby Mathew9b2de242024-02-27 16:08:42 +000035 if (!GRANULE_ALIGNED(addr)) {
36 return UINT64_MAX;
37 }
38
Harry Moulton1c9c7b92024-03-07 16:33:59 +000039 assert(dram->num_banks > 0UL);
AlexeiFedorovffef39a2024-10-28 16:35:21 +000040 assert(dram->num_banks <= PLAT_ARM_MAX_MEM_BANKS);
Harry Moulton1c9c7b92024-03-07 16:33:59 +000041 r = dram->num_banks - 1UL;
Soby Mathew9b2de242024-02-27 16:08:42 +000042
Harry Moulton1c9c7b92024-03-07 16:33:59 +000043 /*
44 * Use a binary search rather than a linear one to locate the bank which
45 * the address falls within, then use the start_gran_idx (which is a
46 * cumulative idx from previous dram banks) to calculate the required
47 * granule index.
48 */
49 while (l <= r) {
AlexeiFedorovffef39a2024-10-28 16:35:21 +000050 const struct arm_memory_bank *bank;
Harry Moulton1c9c7b92024-03-07 16:33:59 +000051 unsigned long i;
Soby Mathew9b2de242024-02-27 16:08:42 +000052
Harry Moulton1c9c7b92024-03-07 16:33:59 +000053 i = l + ((r - l) / 2UL);
AlexeiFedorovffef39a2024-10-28 16:35:21 +000054 assert(i < PLAT_ARM_MAX_MEM_BANKS);
Harry Moulton1c9c7b92024-03-07 16:33:59 +000055
56 bank = &dram->bank[i];
57
58 if (addr < bank->base) {
59 if (i == 0UL) {
60 break;
61 }
62 r = i - 1UL;
63 } else if (addr > (bank->base + bank->size - 1UL)) {
64 l = i + 1UL;
65 } else {
66 return (bank->start_gran_idx +
67 ((addr - bank->base) >> GRANULE_SHIFT));
68 }
69 }
Soby Mathew9b2de242024-02-27 16:08:42 +000070 return UINT64_MAX;
71}
72
73unsigned long plat_granule_idx_to_addr(unsigned long idx)
74{
AlexeiFedorovffef39a2024-10-28 16:35:21 +000075 const struct arm_memory_layout *dram = &arm_dram;
Harry Moulton1c9c7b92024-03-07 16:33:59 +000076 unsigned long r, l = 0UL, addr = 0UL;
Soby Mathew9b2de242024-02-27 16:08:42 +000077
Harry Moulton1c9c7b92024-03-07 16:33:59 +000078 assert(dram->num_banks > 0UL);
79 assert(idx < dram->num_granules);
80
81 r = dram->num_banks - 1UL;
82
83 /*
84 * Calculate the start and end granule index of each bank using the
85 * start_gran_idx (which is a cumulative idx from previous dram banks)
86 * and then check whether the given index falls within it.
87 */
88 while (l <= r) {
AlexeiFedorovffef39a2024-10-28 16:35:21 +000089 const struct arm_memory_bank *bank;
Harry Moulton1c9c7b92024-03-07 16:33:59 +000090 unsigned long i;
91 unsigned long idx_start, idx_end;
92
93 i = l + ((r - l) / 2UL);
AlexeiFedorovffef39a2024-10-28 16:35:21 +000094 assert(i < PLAT_ARM_MAX_MEM_BANKS);
Harry Moulton1c9c7b92024-03-07 16:33:59 +000095
96 bank = &dram->bank[i];
97
98 idx_start = bank->start_gran_idx;
99 idx_end = idx_start + (bank->size >> GRANULE_SHIFT) - 1UL;
100
101 if (idx < idx_start) {
102 assert(i != 0UL);
103 r = i - 1UL;
104 } else if (idx > idx_end) {
105 l = i + 1UL;
106 } else {
107 addr = bank->base + ((idx - idx_start) << GRANULE_SHIFT);
108 break;
109 }
Soby Mathew9b2de242024-02-27 16:08:42 +0000110 }
Harry Moulton1c9c7b92024-03-07 16:33:59 +0000111 /* Assert that the search was successful */
112 assert(l <= r);
113 return addr;
Soby Mathew9b2de242024-02-27 16:08:42 +0000114}