|
4 | 4 | # Copyright (C) 2021 Simon D. Levy <simon.d.levy@gmail.com> |
5 | 5 | # Copyright (C) 2022 Johan Carlsson <johan.carlsson@teenage.engineering> |
6 | 6 | # Copyright (c) 2022 Samuel Dewan |
| 7 | +# Copyright (c) 2024 Ein Terakawa <applause@elfmimi.jp> |
7 | 8 | # Copyright (C) 2023 Tejaswini Dasika <tejaswinidasika@gmail.com> |
8 | 9 | # Copyright (c) 2026 Arm Limited |
9 | 10 | # SPDX-License-Identifier: Apache-2.0 |
@@ -389,8 +390,8 @@ class GenericRTTControlBlock(RTTControlBlock): |
389 | 390 |
|
390 | 391 | target: SoCTarget |
391 | 392 | _cb_search_address: int |
392 | | - _cb_search_size_bytes: int |
393 | | - _control_block_id: Sequence[int] |
| 393 | + _cb_search_size: int |
| 394 | + _control_block_id: bytes |
394 | 395 |
|
395 | 396 | def __init__(self, target: SoCTarget, address: int = None, |
396 | 397 | size: int = None, control_block_id: bytes = b'SEGGER RTT'): |
@@ -420,45 +421,32 @@ def __init__(self, target: SoCTarget, address: int = None, |
420 | 421 | if size is None: |
421 | 422 | # Address was specified, but size was not. Assume that the control |
422 | 423 | # block is located exactly at the provided address. |
423 | | - self._cb_search_size_bytes = 0 |
| 424 | + self._cb_search_size = 0 |
424 | 425 | else: |
425 | | - self._cb_search_size_bytes = size |
| 426 | + self._cb_search_size = size |
426 | 427 | self._control_block_id = control_block_id |
427 | 428 |
|
428 | 429 | def _find_control_block(self) -> Optional[int]: |
429 | | - addr: int = self._cb_search_address & ~0x3 |
430 | | - search_addr: int = addr |
431 | | - search_size: int = self._cb_search_size_bytes |
432 | | - if search_size < len(self._control_block_id): |
433 | | - search_size = len(self._control_block_id) |
434 | | - |
435 | | - id_len = len(self._control_block_id) |
436 | | - offset: int = 0 |
437 | | - |
| 430 | + id_bytes: bytes = self._control_block_id |
| 431 | + id_size: int = len(id_bytes) |
| 432 | + addr: int = self._cb_search_address |
| 433 | + search_size: int = max(self._cb_search_size, id_size) |
| 434 | + carry_over_size: int = (1 - id_size) // 4 * 4 # it's negative! |
| 435 | + chunk_size: int = 1024 |
| 436 | + |
| 437 | + data: bytes = b'' |
438 | 438 | while search_size: |
439 | | - read_size = min(search_size, 32) |
440 | | - data = self.target.read_memory_block8(search_addr, read_size) |
441 | | - |
442 | | - if not data: |
443 | | - break |
444 | | - |
445 | | - for byte in data: |
446 | | - if byte == self._control_block_id[offset]: |
447 | | - offset += 1 |
448 | | - if offset == id_len: |
449 | | - break |
450 | | - else: |
451 | | - num_skip_words = (offset + 1) |
452 | | - addr += (num_skip_words * 1) |
453 | | - search_size -= num_skip_words |
454 | | - offset = 0 |
455 | | - |
456 | | - if offset == id_len: |
457 | | - break |
| 439 | + read_size: int = min(search_size, chunk_size) |
| 440 | + prev: bytes = data[carry_over_size:] |
| 441 | + data = bytes(self.target.read_memory_block8(addr, read_size)) |
| 442 | + idx: int = (prev + data).find(id_bytes) |
| 443 | + if idx >= 0: |
| 444 | + return addr - len(prev) + idx |
458 | 445 |
|
459 | | - search_addr += read_size |
| 446 | + addr += read_size |
| 447 | + search_size -= read_size |
460 | 448 |
|
461 | | - return addr if offset == id_len else None |
| 449 | + return None |
462 | 450 |
|
463 | 451 | def start(self): |
464 | 452 | """@brief Find the RTT control block on the target. |
|
0 commit comments