@@ -135,15 +135,94 @@ impl<'a> Fdt<'a> {
135135 }
136136 }
137137
138+ /// Translate device address to CPU physical address.
139+ ///
140+ /// This function implements address translation similar to Linux's of_translate_address.
141+ /// It walks up the device tree hierarchy, applying each parent's ranges property to
142+ /// translate the child address space to parent address space, ultimately obtaining
143+ /// the CPU physical address.
144+ ///
145+ /// # Arguments
146+ /// * `path` - Node path (absolute path starting with '/' or alias name)
147+ /// * `address` - Device address from the node's reg property
148+ ///
149+ /// # Returns
150+ /// The translated CPU physical address. If translation fails, returns the original address.
138151 pub fn translate_address ( & self , path : & ' a str , address : u64 ) -> u64 {
139152 let path = match self . normalize_path ( path) {
140153 Some ( p) => p,
141154 None => return address,
142155 } ;
143- let split = path. trim_matches ( '/' ) . split ( '/' ) ;
156+
157+ // 分割路径为各级节点名称
158+ let path_parts: heapless:: Vec < & str , 16 > = path
159+ . trim_matches ( '/' )
160+ . split ( '/' )
161+ . filter ( |s| !s. is_empty ( ) )
162+ . collect ( ) ;
163+
164+ if path_parts. is_empty ( ) {
165+ return address;
166+ }
167+
144168 let mut current_address = address;
145-
146-
169+
170+ // 从最深层的节点向上遍历,对每一层应用 ranges 转换
171+ // 注意:我们需要从倒数第二层开始(因为最后一层是目标节点本身)
172+ for depth in ( 0 ..path_parts. len ( ) ) . rev ( ) {
173+ // 构建到当前层的路径
174+ let parent_parts = & path_parts[ ..depth] ;
175+ if parent_parts. is_empty ( ) {
176+ // 已经到达根节点,不需要继续转换
177+ break ;
178+ }
179+
180+ // 查找父节点
181+ let mut parent_path = heapless:: String :: < 256 > :: new ( ) ;
182+ parent_path. push ( '/' ) . ok ( ) ;
183+ for ( i, part) in parent_parts. iter ( ) . enumerate ( ) {
184+ if i > 0 {
185+ parent_path. push ( '/' ) . ok ( ) ;
186+ }
187+ parent_path. push_str ( part) . ok ( ) ;
188+ }
189+
190+ let parent_node = match self . find_by_path ( parent_path. as_str ( ) ) {
191+ Some ( node) => node,
192+ None => continue ,
193+ } ;
194+
195+ // 获取父节点的 ranges 属性
196+ let ranges = match parent_node. ranges ( ) {
197+ Some ( r) => r,
198+ None => {
199+ // 没有 ranges 属性,停止转换
200+ break ;
201+ }
202+ } ;
203+
204+ // 在 ranges 中查找匹配的转换规则
205+ let mut found = false ;
206+ for range in ranges. iter ( ) {
207+ // 检查地址是否在当前 range 的范围内
208+ if current_address >= range. child_address
209+ && current_address < range. child_address + range. length
210+ {
211+ // 计算在 child address space 中的偏移
212+ let offset = current_address - range. child_address ;
213+ // 转换到 parent address space
214+ current_address = range. parent_address + offset;
215+ found = true ;
216+ break ;
217+ }
218+ }
219+
220+ if !found {
221+ // 如果在 ranges 中没有找到匹配项,保持当前地址不变
222+ // 这通常意味着地址转换失败,但我们继续尝试上层
223+ }
224+ }
225+
147226 current_address
148227 }
149228
0 commit comments