EFI·UEFI에서 CXL 초기화 — CEDT 생성과 HDM Decoder 사전 설정
#한 줄 요약
“UEFI는 enumeration 결과를 ACPI 테이블로 커널에 인계합니다.” — *CEDT (CXL Early Discovery Table)*가 host bridge·memory window·interleave 규칙을 담고, HDM Decoder가 부팅 시점에 이미 프로그래밍되어 있어 커널이 깨어났을 때 즉시 메모리를 사용할 수 있습니다.
Ch 34에서 U-Boot의 PCIe enumeration과 CXL DVSEC scan을 봤습니다. 서버 환경에서는 EDK II 기반 UEFI가 비슷한 흐름에 ACPI 통합을 더해 훨씬 정교한 인계 절차를 거칩니다. 이 장은 UEFI에서 CXL 초기화가 어떻게 이루어지는지, 어떤 ACPI 테이블이 만들어지는지를 분해합니다.
#UEFI와 U-Boot의 차이
같은 enumeration 작업이지만 환경이 다릅니다.
| 항목 | U-Boot | UEFI |
|---|---|---|
| 사용처 | 임베디드 | 서버·데스크탑 |
| 인계 방식 | DTB (Device Tree) | ACPI tables |
| CXL 표준 통합 | 비교적 늦음 | spec 발표 직후 |
| HDM Decoder 처리 | 단순 | CFMWS 기반 정교 |
| Secure Boot 통합 | 옵션 | 표준 |
| Hot-add 지원 | 제한적 | spec |
서버 CXL 환경에서는 UEFI가 표준입니다.
#EDK II의 CXL 모듈
EDK II는 CXL 지원을 별도 DXE 드라이버 모듈로 제공합니다. 실제 모듈 이름은 EDK II 버전과 vendor fork마다 다르지만 역할 분류가 비슷합니다:
| 역할 | 모듈 카테고리 |
|---|---|
| CXL bus enumeration·DVSEC 검출 | bus driver (PCI/CXL bus DXE) |
| CXL.mem device 초기화·HDM 프로그래밍 | memory device driver DXE |
| CXL port·switch 처리 | port driver DXE |
| CEDT ACPI table 생성 | ACPI table generator |
| CXL host bridge 추상화 | host bridge driver |
부팅 흐름에서 bus driver가 가장 먼저 동작해 디바이스 발견, 그 다음 memory driver가 HDM Decoder 프로그래밍, 마지막에 ACPI generator가 CEDT 생성. 실 모듈 이름은 MdeModulePkg·OEM platform fork를 참고합니다.
#CEDT 구조
*CEDT (CXL Early Discovery Table)*는 CXL의 ACPI table입니다. UEFI Spec과 CXL Spec 양쪽에 정의:
| Subtable | Type | 의미 |
|---|---|---|
| Header | — | “CEDT” signature + revision |
| CHBS | 0x00 | CXL Host Bridge Structure |
| CFMWS | 0x01 | CXL Fixed Memory Window Structure |
| CXIMS | 0x02 | CXL XOR Interleave Math Structure |
| RDPAS | 0x03 | RCEC (Root Complex Event Collector) Downstream Port Association |
| CSDS | 0x04 | CXL System Description Structure |
핵심은 CHBS·CFMWS 두 가지. CHBS가 어디에 host bridge가 있나, CFMWS가 어느 SPA range가 CXL에 매핑되어 있나를 알려 줍니다.
#CHBS — Host Bridge Structure
각 CXL host bridge마다 CHBS 항목:
| Field | 의미 |
|---|---|
| Subtable Type | 0x00 (CHBS) |
| UID | 고유 식별자 |
| CXL Version | 0x0001 (1.1), 0x0002 (2.0) |
| Base | host bridge component register block 시작 주소 |
| Length | register block 크기 (0x10000 = 64 KB 기본) |
호스트 커널이 CHBS를 보고 각 host bridge 위치를 압니다.
#CFMWS — Fixed Memory Window Structure
가장 중요한 항목. 어느 SPA range가 CXL용으로 예약되어 있나:
| Field | 의미 |
|---|---|
| Subtable Type | 0x01 (CFMWS) |
| Window Size | window 크기 (예: 512 GB) |
| ENIW (Encoded Number of Interleave Ways) | interleave 방향 수 |
| HBIG (Host Bridge Interleave Granularity) | 256 B·512 B·…·16 KB |
| Restrictions | type 3 only / volatile only / persistent only 등 |
| QTG ID | QoS Throttling Group |
| Window Base Address | 시작 SPA |
| First Interleave Target List Index | 매핑된 host bridge IDs |
CFMWS가 여러 개면 각각 다른 메모리 영역·다른 interleave 정책입니다. 예를 들어:
- CFMWS 0: 직접 attach 256 GB, single host bridge
- CFMWS 1: pooling용 1 TB, 2-way interleave
#HDM Decoder 사전 프로그래밍
UEFI는 enumeration이 끝나면 HDM Decoder를 미리 프로그래밍해 둡니다.
이유:
- 커널이 깨어났을 때 즉시 메모리를 system RAM으로 인식하게 함
- SRAT·HMAT 통합이 부팅 시점에 완료
- NUMA 노드 자동 등록
이를 Auto-Commit이라 부르며, firmware-managed 모드입니다. 커널 측이 commit 불필요.
대조적으로 user-managed 모드는 커널 부팅 후 cxl-cli로 commit. Hot-add·테스트에는 user-managed가 유리.
#SRAT와 HMAT 통합
CXL.mem 메모리는 별도 ACPI 테이블에도 등록됩니다.
| 테이블 | 역할 | CXL 영향 |
|---|---|---|
| MADT | CPU·local APIC | 변경 없음 |
| SRAT | NUMA 노드 → CPU·memory affinity | CXL.mem 영역이 별도 노드로 등록 |
| HMAT | memory tier (latency·bandwidth) | CXL.mem이 higher latency tier로 분류 |
| SLIT | NUMA 노드 간 거리 | CXL 노드 distance 50~80으로 등록 |
| MCFG | PCIe config space | 변경 없음 |
핵심은 HMAT. UEFI가 CXL 디바이스의 latency·bandwidth를 HMAT에 미리 적어 두면 커널이 자동으로 memory tier를 분류. DAMON·NUMA balancing이 그 분류를 그대로 사용.
#Coherency Domain ID
CXL 3.0 fabric에서는 Coherency Domain ID가 필요합니다.
같은 coherency domain에 속한 디바이스는 cache coherency를 공유. 다른 domain은 별도 관리. UEFI는 CFMWS에 domain ID를 적어 host에 알려 줍니다.
Domain 0 (host A): CFMWS 0, CFMWS 1Domain 1 (host A·B 공유): CFMWS 2Domain 2 (host B): CFMWS 3이 정보가 fabric 토폴로지 인식에 핵심.
#SPDM 인증 통합 (옵션)
Confidential Computing 환경에서는 UEFI가 부팅 시 디바이스 SPDM 인증도 진행:
| 단계 | 동작 |
|---|---|
| 1 | UEFI가 CXL 디바이스 enumerate |
| 2 | UEFI가 SPDM 인증 시도 (Ch 12 Security) |
| 3 | 인증 성공 → CEDT에 active 표시 + IDE 활성화 |
| 4 | 인증 실패 → CEDT에 disabled 표시 또는 항목 제거 |
보안 부팅과 attestation이 부팅 시점에 완료됩니다.
#QEMU + OVMF 검증
EDK II 기반 *OVMF (Open Virtual Machine Firmware)*에 CXL 코드가 들어 있어 QEMU에서 검증 가능:
# OVMF 빌드 시 CXL 옵션$ cd edk2$ build -p OvmfPkg/OvmfPkgX64.dsc -t GCC -a X64 -b RELEASE \ -D CXL_ENABLED=TRUE
# QEMU에서 OVMF 사용$ qemu-system-x86_64 \ -bios OVMF.fd \ -machine q35,cxl=on \ [CXL device options...]
# Linux guest에서 CEDT 확인guest$ acpidump -bguest$ iasl -d cedt.datguest$ cat cedt.dsl # CHBS·CFMWS 내용 확인OVMF의 CXL 코드가 실 BIOS와 동일한 path. 드라이버 통합 검증에 충분합니다.
#상용 BIOS의 CXL 구현
| Vendor | BIOS | CXL 지원 시점 |
|---|---|---|
| Intel | RBU·MEBx | Sapphire Rapids (CXL 1.1), Granite Rapids (CXL 2.0) |
| AMI | Aptio V | Genoa (CXL 2.0), Turin (CXL 3.0) |
| Insyde | H2O | various OEM 적용 |
| Phoenix | SecureCore | 일부 서버 |
상용 BIOS는 EDK II base에 vendor-specific extension. 핵심 CEDT 생성·HDM 프로그래밍 코드는 공통.
#자주 하는 실수
#CEDT 누락 시 증상
[Linux kernel boot][ 0.524] cxl_acpi: device 0000:5e:00.0 — CHBS not found in CEDT[ 0.525] cxl_acpi: skipping enumerationBIOS의 CXL 활성화 옵션이 disabled거나 EDK II에 CXL 모듈이 안 들어간 경우. BIOS update가 답.
#CFMWS Restrictions 잘못 설정
CFMWS 0: Restrictions = 0x06 (Type 3 only + Volatile only)
[Persistent memory device를 이 window에 매핑 시도][ 1.234] cxl_mem mem0: window restrictions mismatch — skipRestrictions field가 디바이스 타입과 맞아야 mapping됩니다. Type 3 persistent를 volatile only window에 못 넣음.
#HDM Decoder Auto-Commit과 cxl-cli 충돌
$ cxl create-region -d decoder0.0 -t ram -s 128GError: decoder already committed by firmwareFirmware-managed mode에서는 user-managed 명령이 안 됩니다. BIOS에서 firmware vs user managed 선택 옵션이 보통 있음.
#Coherency Domain ID 누락 (CXL 3.0)
[CXL 3.0 fabric 환경][ 2.345] cxl_acpi: domain ID missing — assuming single domain[ 2.346] cxl_acpi: fabric features disabledCXL 2.0까지는 단일 domain 가정이지만 3.0 fabric은 domain ID 필수. OEM BIOS에 3.0 spec 준수 확인.
#SPDM 인증 실패가 silent
[BIOS SPDM 인증 실패 시]- CEDT에서 해당 디바이스 항목 제거- BIOS log에만 기록, 호스트 OS에 전달 안 됨인증 실패한 디바이스가 그냥 안 보임. Confidential Computing 환경에서는 BIOS log 확인 필수.
#정리
- UEFI는 EDK II 기반 CXL 모듈들로 enumeration → HDM 프로그래밍 → ACPI 테이블 생성을 수행합니다.
- CEDT는 *CHBS (host bridge)·CFMWS (memory window)·CXIMS (interleave)*를 호스트에 전달.
- SRAT·HMAT·SLIT에도 CXL 정보가 통합되어 커널이 자동으로 NUMA 노드·tier 분류.
- Firmware-managed는 BIOS가 HDM commit, user-managed는 cxl-cli로 commit. 각 모드의 장단이 있음.
- Confidential Computing은 부팅 시 SPDM 인증도 UEFI가 진행. 인증 실패 디바이스는 CEDT에서 빠짐.
- QEMU + OVMF로 드라이버 통합 검증이 가능. 상용 BIOS는 EDK II + vendor extension.
#다음 편
Ch 36: 부트 시 메모리 토폴로지 결정에서는 DDR DIMM·HBM·CXL.mem·Persistent memory가 하나의 메모리 토폴로지로 통합 인식되는 흐름을 봅니다. Bootloader Internals 시리즈의 마무리입니다.
#관련 항목
Bootloader Internals · 35 of 37
- 1ROM부터 init까지 — 임베디드 부팅 단계의 빈자리 분석
- 2Das U-Boot vs TF-A vs EDK II — 임베디드 부트로더 생태계 비교
- 3U-Boot 빌드 시스템 분석 — Kconfig·Makefile·defconfig 동작 추적
- 4ARM 임베디드 부트 4단계 분해 — BL1·SPL·TPL·U-Boot Proper의 역할
- 5U-Boot Falcon Mode — SPL이 U-Boot Proper 없이 커널 직접 부팅
- 6Device Tree DTB 부트로더 처리 — 로딩 시점과 fixup 메커니즘 추적
- 7U-Boot Driver Model 내부 — uclass·driver·device 추상화 구조
- 8U-Boot 보드 초기화 시퀀스 — board_init_f와 board_init_r 분리 이유
- 9DDR Controller 프로그래밍과 PHY Training — SPL의 가장 어려운 작업
- 10임베디드 스토리지 부팅 분석 — MMC·SCSI·NAND·SPI Flash 비교
- 11임베디드 네트워크 부팅 — TFTP·PXE·BOOTP 시퀀스 분석
- 12U-Boot USB 부팅 — fastboot·UMS·USB host 메커니즘
- 13U-Boot 환경 변수와 bootcmd — 부팅 시나리오 정의하기
- 14Modern U-Boot bootflow / bootmeth — 새 추상화 레이어 분석
- 15FIT image 구조 분석 — multi-image·hash·configuration 추적
- 16U-Boot Verified Boot — RSA 서명과 public key 임베딩 흐름
- 17임베디드 A/B 부팅 이중화 — OTA 안전성을 위한 부트 슬롯 설계
- 18U-Boot의 EFI 호환 분석 — bootefi 명령과 EFI loader 동작 원리
- 19Linux Boot ABI — ARM/ARM64 커널 진입 규약 추적
- 20임베디드 펌웨어 업데이트 — RAUC vs SWUpdate 비교
- 21새 보드 U-Boot 포팅 실전 — defconfig 작성부터 첫 부팅까지
- 22부트로더 디버깅 기법 — DEBUG·JTAG·serial·post-mortem 분석
- 23SoC BootROM·eFuse·OTP — 부팅의 0단계 분석
- 24SPL·TPL 내부 해부 — 가장 작은 부트 단계의 동작 추적
- 25ARM Trusted Firmware-A 통합 — BL1·BL2·BL31·BL32·BL33 흐름
- 26DDR Training과 PHY Calibration — 보드별 파라미터 튜닝
- 27임베디드 Chain of Trust — 다단계 서명 검증의 전체 흐름
- 28임베디드 Flash Layout 설계 — partition·NAND·eMMC·UBI 비교
- 29U-Boot Distro Boot — extlinux·boot.scr 표준화 분석
- 30부트로더 CI 구축 — build matrix와 자동 부팅 테스트
- 31TF-A BL31 EL3 Runtime 분석 — PSCI·SDEI·RAS dispatcher 추적
- 32PSCI와 SMCCC ABI — ARM 표준 SMC 호출 규약 분석
- 33ARM64 Secondary Core Bring-up — PSCI CPU_ON 호출부터 EL1 진입까지
- 34U-Boot PCIe Enumeration — 부트로더가 디바이스를 찾는 흐름 분석
- 35EFI·UEFI에서 CXL 초기화 — CEDT 생성과 HDM Decoder 사전 설정
- 36부트 시 메모리 토폴로지 결정 — DDR + CXL.mem 통합 인식
- 37UEFI Secure Boot 인증서 만료 — 2011→2023 CA 롤오버와 PQC 대비
관련 글
UEFI Secure Boot 인증서 만료 — 2011→2023 CA 롤오버와 PQC 대비
2026년 6월부터 시작되는 Microsoft Secure Boot 2011 인증서 만료 — PK·KEK·db·dbx 계층, 2023 CA 체인과 Option ROM CA 분리, 임베디드 기기 영향, 그리고 post-quantum 서명으로의 길.
U-Boot PCIe Enumeration — 부트로더가 디바이스를 찾는 흐름 분석
U-Boot PCIe 열거 과정 — Root Complex 초기화·Config Space scan·BAR sizing·resource 할당, CXL DVSEC 인식까지.
U-Boot의 EFI 호환 분석 — bootefi 명령과 EFI loader 동작 원리
U-Boot이 UEFI Boot Services를 노출하는 방식 — bootefi, EBBR, Linux EFI stub과의 연결.
이 글을 참조하는 글 (6)
- UEFI Secure Boot 인증서 만료 — 2011→2023 CA 롤오버와 PQC 대비— Bootloader Internals
- 부트 시 메모리 토폴로지 결정 — DDR + CXL.mem 통합 인식— Bootloader Internals
- U-Boot PCIe Enumeration — 부트로더가 디바이스를 찾는 흐름 분석— Bootloader Internals
- Linux CXL 드라이버 분석 — cxl_pci·cxl_core·region·DAX— Modern Embedded Recipes
- QEMU CXL Type 3 디바이스 에뮬레이션 — 노트북에서 CXL 개발 환경 구축— Modern Embedded Recipes
- CXL TEE 확장 — Trusted Execution을 메모리 디바이스까지— Embedded Security