버스 오류가 알려 주는 실패와 알려 주지 않는 부작용
버스가 잘못된 주소에 오류를 반환했다면 그 거래는 실패했다고 볼 수 있다. 하지만 오류가 어떤 종류의 실패를 말하는지, 앞에서 적용된 쓰기까지 취소되었는지, 소프트웨어가 이를 어떻게 받는지는 별도 질문이다. bus error response는 실패를 전달하는 프로토콜 사건이며, 모든 실패의 원인을 자세히 기록한 보고서는 아니다.
일반 AXI 읽기 응답에는 RRESP, 쓰기 응답에는 BRESP가 있다. 정상 접근 성공을 나타내는 OKAY와 함께 SLVERR, DECERR가 정의되어 있다. SLVERR는 목적지에 접근이 도달했지만 그쪽이 실패를 보고하는 경우이고, DECERR는 보통 interconnect가 주소에 맞는 목적지를 찾지 못할 때 쓰인다. 이 분류는 오류가 발생한 층을 구분하는 데 도움이 된다. Arm IHI0022H, A3.4.5 Read and write response structure
가상 주소 지도에서 0x1000부터 0x1FFF까지가 장치의 공간이라고 하자. 0x3000 읽기는 어떤 장치에도 해당하지 않아 DECERR를 받을 수 있다. 0x1000의 읽기 전용 레지스터에 쓰기를 시도하면 장치에 도달한 뒤 SLVERR를 받을 수 있다. 그러나 SLVERR라는 두 비트만 보고 정확히 읽기 전용 위반인지, 지원하지 않는 크기인지, 장치 내부 문제인지까지 알 수는 없다. 세부 원인을 구별하려면 해당 IP의 설명과 추가 상태 기록이 필요하다.
오류 응답이 있다는 사실과 오류 응답을 수락했다는 사실도 구별해야 한다. RVALID=1, RRESP=DECERR인데 RREADY=0이면 아직 응답 handshake가 아니다. 오류를 보낸 쪽은 필요한 응답을 보존하고, 받은 쪽은 나중의 수락 경계에서 거래 상태를 갱신해야 한다. error를 한 사이클만 펄스로 내보내고 거래를 지우면 수신자는 끝났다는 사실을 놓칠 수 있다.
요청을 버려 아무 응답도 내지 않는 것과 오류를 반환하는 것은 특히 다르다. 전자는 요청자의 outstanding 상태를 남겨 기다리게 할 수 있다. 후자는 정해진 응답 형식으로 거래를 마무리하게 한다. 목적지가 없는 주소도 처리하는 기본 오류 응답 경로가 필요한 이유다. 주소 decode가 실패했다는 내부 신호만으로 외부 요청이 완료되지는 않는다.
여러 beat를 읽을 때는 오류가 나왔다는 이유로 응답 수가 줄어들지 않는다. 가상 요청이 네 beat이고 응답 상태가 [OKAY, SLVERR, OKAY, OKAY]라고 하자. 둘째 beat에서 오류를 관찰했어도 네 beat의 전송을 완료해야 한다. 마지막 표시는 넷째 beat에 와야 한다. 검증기가 첫 오류 뒤에 요청을 지우면 셋째와 넷째 응답을 출처 없는 데이터로 오해할 수 있다. AXI의 오류 응답 규칙은 요구된 전송들을 완료하도록 한다. Arm IHI0022H, A3.4.5의 burst 오류 설명
쓰기에서는 burst 전체에 대해 B 응답 하나가 나온다. 이 응답이 SLVERR라고 해서 이미 적용된 모든 바이트가 원상복구된다고 약속한 것은 아니다. 가상 장치가 앞의 두 beat를 적용한 뒤 나머지 두 beat에서 내부 문제를 발견하고, 데이터 채널은 끝까지 수락한 뒤 SLVERR를 반환할 수 있다. 그 경우 오류 응답은 거래가 정상 완료되지 않았다는 정보이지 앞의 변경이 없었다는 정보가 아니다.
어떤 장치가 쓰기를 먼저 전부 검사해 실패하면 아무것도 바꾸지 않는 방식으로 동작할 수는 있다. 그런 성질은 장치가 추가로 제공하는 계약이다. 일반 오류 코드만으로 추론하면 안 된다. 응답을 받지 못한 timeout의 경우에는 요청이 적용되었는지 자체가 불확실할 수도 있으므로, retry 정책에는 더 많은 조건이 필요하다.
다른 버스의 오류 표현도 범위를 확인해야 한다. OpenTitan의 TL-UL은 읽기·쓰기 응답에 d_error를 사용하고, 잘못된 opcode나 주소·크기·mask 조합, 존재하지 않는 주소 등에 대한 검사 범위를 설명한다. 어떤 subword mask를 지원하는지는 장치별로 다를 수 있다. 기본 프로토콜이 표현할 수 있는 접근과, 실제 장치가 지원하는 접근은 같은 집합일 필요가 없다. OpenTitan TL-UL, Explicit Error Cases
이런 오류가 CPU 예외가 되는지, DMA의 상태 레지스터에 기록되는지, 인터럽트로 알려지는지는 버스의 응답 비트만으로 결정되지 않는다. 프로토콜 응답을 받은 host와 시스템의 보고 경로가 연결되어 있어야 한다. 버스 파형에서 오류가 확인되었다는 사실과 소프트웨어가 원인을 정확히 진단했다는 사실은 그 경로를 통해 이어진다.
검증할 때는 오류 종류, 응답 수락, 남은 전송, 상태 해제를 따로 기록하는 편이 좋다. 잘못된 주소에 성공을 보고하지 않는지와 함께, 실패 뒤 요청이 영원히 남거나 응답이 두 번 생기지 않는지도 살펴야 한다. 오류의 세부 원인과 쓰기 부작용까지 확인하려면 대상 장치가 약속한 의미를 추가해야 한다.
bus error response가 알려 주는 것은 버스가 정한 수준의 접근 결과다. 그 정보가 제대로 전달되어 거래가 끝나는지를 먼저 보장하고, 소프트웨어가 필요한 진단과 복구 정보는 별도의 장치 계약으로 연결해야 한다. 실패를 표현하는 것과 실패를 되돌리는 것은 서로 다른 책임이다.