모든 이야기

같은 길이의 AXI burst가 시작 주소에 따라 실패하는 이유

DMA가 연속된 메모리에 긴 burst를 보냈는데, 같은 크기의 전송이 어떤 시작 주소에서는 되고 다른 주소에서는 거절될 수 있다. AXI burst 경계는 데이터 총량만으로 판단하지 않기 때문이다. beat의 크기와 개수, 시작 위치가 함께 한 거래의 주소 범위를 결정한다. 특히 4KB 경계는 긴 전송을 만들 때 따로 계산해야 하는 조건이다.

AXI4 INCR burst의 개수는 AxLEN+1이고, 한 beat의 최대 바이트 수는 2^AxSIZE다. INCR에서는 주소가 전송 크기에 맞춰 증가한다. 규격은 한 burst가 4KB 주소 경계를 넘는 것을 금지한다. 이 제한은 경계를 사이에 둔 목적지 분리를 다루는 데도 의미가 있다. Arm IHI0022H, A3.4.1 Address structure

시작 주소가 beat 크기에 정렬된 INCR burst부터 보자. 주소를 a, beat 수를 n, beat 크기를 s라고 하면 마지막 beat의 시작 주소는 a+(n-1)s다. 마지막으로 접근 가능한 바이트는 a+ns-1이다. 이 둘은 서로 다른 숫자다. 마지막 beat 시작이 경계 안에 있는지만 보는 검사보다 마지막 바이트까지 같은 4KB 영역에 있는지 확인하는 것이 분명하다.

가상 64비트 데이터 버스에서 8바이트 beat 8개를 0x0FE0부터 요청한다고 하자. AxSIZE=3이고 AxLEN=7이다. 시작점의 4KB 안쪽 오프셋은 4064이며 경계까지 4096-4064=32바이트가 남았다. 요청은 64바이트를 담는 burst이므로 범위를 넘는다. 마지막 beat 시작은 0x1018, 마지막 바이트는 0x101F다.

경계를 지키려면 요청을 만들 때 네 beat와 네 beat로 나눌 수 있다. 첫 burst는 0x0FE0에서 시작해 마지막 beat 시작 0x0FF8, 마지막 바이트 0x0FFF까지 간다. 두 번째는 0x1000에서 시작해 마지막 바이트 0x101F까지 간다. 각각 AxLEN=3이며, 둘을 합치면 원래 의도한 64바이트를 같은 순서로 전달한다. 이것은 일반 메모리의 연속 데이터를 두 요청으로 발행하는 가상 예다.

정렬된 INCR에 대해 다음 계산은 경계 안에 담을 수 있는 최대 beat 수를 알려 준다.

remaining_bytes = 4096 - (start_address mod 4096)
boundary_beats  = remaining_bytes / beat_bytes
issue_beats     = min(wanted_beats, boundary_beats, interface_limit)
AxLEN           = issue_beats - 1

여기서는 시작점이 beat 크기에 정렬되어 나눗셈이 정확히 떨어진다. interface_limit에는 AXI4 INCR의 최대 256뿐 아니라 실제 연결 대상이 지원하는 더 작은 한계도 반영해야 한다. burst가 경계를 지켰다고 해서 수신기가 모든 길이와 크기를 지원한다는 뜻은 아니다.

비정렬 요청까지 같은 공식에 넣으면 틀릴 수 있다. INCR의 후속 beat 주소는 첫 시작 주소에 계속 s를 더하는 대신, 크기 s로 정렬한 주소를 기준으로 증가한다. 8바이트 크기, 한 beat를 0x0FFD에서 시작하는 경우를 보자. 유효한 첫 beat의 바이트 범위는 0x0FFD부터 0x0FFF까지이며, 정렬 기준은 0x0FF8이다. 시작 주소에 단순히 8을 더해 마지막 바이트를 0x1004로 계산하면 존재하지 않는 부분까지 센다. 쓰기라면 strobe도 이 합법적인 바이트 위치와 맞아야 한다. Arm IHI0022H, A3.4.1의 Burst address 수식·A3.4.4

같은 비정렬 시작점에서 두 beat를 요청하면 다음 beat 주소는 0x1000이 된다. 이때는 경계를 넘어선다. 반대로 주소 0x1000에서의 요청은 새 4KB 영역 안에서 시작한다. 경계 검사는 주소의 낮은 12비트와 크기만 보고 익숙한 계산을 적용하기보다, burst 종류의 실제 주소 생성 규칙에 맞추어야 한다.

WRAP에서는 지정된 범위 끝에 도달하면 그 범위의 처음으로 되돌아간다. FIXED는 각 beat가 같은 주소를 사용한다. 따라서 INCR용 범위 공식으로 세 종류를 모두 검사하면 안 된다. 예를 들어 4바이트씩 네 beat를 0x003C에서 시작하는 합법적인 WRAP의 주소는 0x003C, 0x0030, 0x0034, 0x0038이다. 단순 증가로 0x0048까지 간다고 해석하면 원래 거래와 다른 주소들을 검사한다.

분할할 때도 “데이터만 이어 보내면 된다”는 가정은 부족하다. 쓰기 요청을 두 burst로 나누면 각 burst의 마지막 데이터 표시와 쓰기 응답을 각각 처리해야 한다. 읽기도 요청한 beat 수와 마지막 표시가 새 거래에 맞아야 한다. 주변장치나 exclusive access처럼 요청 단위 자체에 의미가 있는 경우에는 일반 메모리 전송처럼 자유롭게 바꿀 수 있다고 가정하지 말고 속성과 허용 변환을 확인해야 한다.

AXI burst 경계를 다룰 때 가장 유용한 습관은 마지막 주소를 하나 더 쓰는 것이다. 마지막 beat 시작 주소 옆에 마지막 합법 바이트 주소를 적고, 시작점과 같은 4KB 영역인지 확인해 보자. 정렬된 INCR의 간단한 산식과 비정렬·WRAP의 실제 주소 규칙을 구분하면, 길이를 늘렸을 때 생기는 주소 오류를 전송 전에 찾아낼 수 있다.

같은 길이의 AXI burst가 시작 주소에 따라 실패하는 이유 · ariser