rosieblue
article thumbnail
728x90

NPU의 레지스터들

 
ethos NPU 레지스터는 MMIO 영역으로 접근할 수 있다
그리고 아래 목차에 나와있는 것처럼, 각 페이지 별로 레지스터들이 구분되어서 저장되어있다

 
예를 들어 아래처럼 오프셋으로 접근할 수 있다

BASE page register offset 표

 

PROT 레지스터 

NPU의 레지스터를 접근하기 위해서는 프로세서의 상태 NPU의 PROT 레지스터의 값들과 비교하게 된다.

PPROT[0]>=CPL && PPROT[1]<=CNS

프로세서가 NPU에게 요청할 때 APB 버스로 신호를 보내게 되는데, 그 중에서 PPROT signal이라는 걸 실어서 보내게 된다
이때 PPROT 시그널 안에 현재 프로세서(NPU 아님)security/privilege state를 같이 보내게 된다
 
이 값과 NPU 내 PROT 레지스터의 값들과 비교하는 것이다.
 
아래는 PROT에 대한 간단한 요약이다. 이 레지스터는 BASE page에 있는 레지스터로, 현재 NPU의 특권/보안 상태를 저장하고 있다. Read-Only라고 되어있으니, 동작중에는 읽기만 가능하다는 걸 알 수 있다.(그러면 어떻게 바꾸지?)

 
 
 
 
Ethos의 PROT 레지스터 레이아웃은 아래와 같다
 

이 값들은 NPU가 AXI 마스터로 작용해서 DMA를 통해 메모리와 소통할 때에도 사용되게 된다 (AxPROT 시그널로 이 active_CSL, active_CPL값을 기반해서 보냄) 
 

active_CSL
active_CPL

 
 

RESET 레지스터 

NPU의 상태 전환은 NPU 리셋에 의해 트리거된다
이때 RESET에 있는 privilege, security 값을 읽어 PROT 레지스터에 반영하게 된다
 
구분 용도 변경 시점 저장 위치 및 지속성

RESET.pending_CSL / pending_CPL다음 리셋 사이클에 적용할 보안/권한 전환 요청값소프트웨어가 리셋 트리거 전에 설정리셋 동작 중 하드웨어가 읽어서 적용
PROT.active_CSL / active_CPL현재 리셋이 끝난 뒤, 런타임 중의 실제 보안/권한 상태하드웨어가 리셋 이후 pending 값을 반영해 초기화 런타임 중 직접 쓰기 불가

reset register
 
security state changing..
 
NPUNSPORPL, NPUSPPORPL
 
 
 

programming model

Ethos를 init할때, arm_ethosu_npu_init 함수에서 ETHOS_U_BASE_ADDR를 넘겨서 ethos를 init하게 된다.
이후 ethosu_dev_init함수에서 위에서 받은 NPU MMIO region의 시작주소를 받아서     
dev->reg        = (volatile struct NPU_REG *)base_address; 이런식으로 초기화하게 된다.
 
dev는 아래와 같은 ethosu_device 구조체이고,

 
NPU_REG 구조체는 아래처럼 이루어져있다.

따라서 예를 들어 RESET 레지스터에 값을 쓰면 실제로 그 MMIO region에 적히는 것이당
 
 
 
아래는 RESET register를 접근하기 위한 C 구조체이다 (C++도있는데 그냥 C것만 가져옴)

// reset_r - Request Reset and new security mode
struct reset_r
{
#ifndef __cplusplus
    union
    {
        struct
        {
            uint32_t pending_CPL : 1; // Current privilege level 0=User 1=Privileged
            uint32_t pending_CSL : 1; // Current security level 0=Secure 1=Non secure
            uint32_t reserved0 : 30;
        };
        uint32_t word;
    };

 
이런 식으로 한 레지스터의 값을 union으로 선언하고 있다!
union은 가장 큰 크기의 변수의 메모리만큼만 할당한다.
(union관련 개념 : https://velog.io/@commi1106/C-Union-%EA%B3%B5%EC%9A%A9%EC%B2%B4

더보기

💡 비트필드에서의 메모리 사용 — 기본 원칙

C에서 **비트필드(bit-field)**는 다음 규칙을 따릅니다:

  1. 비트 단위로 저장됩니다.
  2. 하나의 struct 안에서 **가능하면 하나의 정수 크기(예: 32비트)**에 다 묶이려고 합니다.
  3. 비트 수를 다 합쳐서 32비트를 넘기면 다음 32비트로 넘어감.

✅ 코드 다시 보기

c
CopyEdit
struct { uint32_t pending_CPL : 1; // 비트 0 uint32_t pending_CSL : 1; // 비트 1 uint32_t reserved0 : 30; // 비트 2~31 };

📦 메모리에서 실제 배치

필드 이름비트 수차지하는 비트 위치 (bit offset)
pending_CPL 1비트 비트 0
pending_CSL 1비트 비트 1
reserved0 30비트 비트 2~31
총합 32비트 = 4바이트 1개의 uint32_t 크기만큼 사용됨
 

🔹 정리하면, **모든 필드가 합쳐서 딱 4바이트(=32비트)**만 사용됩니다.
즉, 이 struct는 메모리에서 총 4바이트만 차지합니다.


🔍 질문 핵심 요약

변수 이름비트 수메모리 크기설명
pending_CPL 1비트 포함된 전체 구조가 4바이트 안에 있음 단독으로는 1비트지만, 구조체 내부의 일부
pending_CSL 1비트 위와 동일  
reserved0 30비트 위와 동일  
전체 구조체 크기 32비트 4바이트 uint32_t 하나만 사용
 

📌 추가 팁: 메모리 정렬/패딩 걱정은?

  • 이 비트필드들은 같은 타입(uint32_t)으로 선언되었기 때문에, 컴파일러는 1개의 32비트 정수 안에 전부 집어넣습니다.
  • 따라서 별도의 패딩 없이 정확히 4바이트만 사용합니다.

단, 비트필드에 int 대신 short 또는 char 등 다른 타입을 혼용하면 구조체 크기가 늘어날 수도 있어요.

 

profile

rosieblue

@Rosieblue

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!