diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b9e8ec1..0f7d663 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,67 +1,150 @@ -name: CI Matrix +name: CI on: push: - branches: [ "master", "release" ] + branches: [master, release] pull_request: - branches: [ "master", "release" ] + branches: [master, release] permissions: contents: read jobs: - build-and-test: - runs-on: ${{ startsWith(matrix.platform, 'arm') && 'ubuntu-24.04-arm' || format('{0}-latest', matrix.os) }} # GitHub-hosted runners + # ─── Host: build + run unittest exes on every supported host arch/OS ─── + host: + name: host ${{ matrix.os }} ${{ matrix.arch }} ${{ matrix.compiler }} + runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || format('{0}-latest', matrix.os) }} strategy: + fail-fast: false matrix: - os: [windows, ubuntu] + os: [ubuntu, windows] compiler: [dmd, ldc] - platform: [x86, x86_64, arm, arm64, riscv64] + arch: [x86, x86_64, arm64] exclude: - # No point cross-compiling on Windows; linux is so much faster! - - os: windows - platform: arm - - os: windows - platform: arm64 - - os: windows - platform: riscv64 - # TODO: DMD ARM64 support is WIP; remove when it releases... - - compiler: dmd - platform: arm64 - - compiler: dmd - platform: arm - - platform: arm # TODO: not yet working... - - platform: riscv64 # TODO: not yet working... - fail-fast: false + - { os: windows, arch: arm64 } # windows-arm64 runner not in free tier + - { compiler: dmd, arch: arm64 } # DMD arm64 still WIP + env: + MAKE_OS: ${{ matrix.os == 'ubuntu' && 'linux' || matrix.os }} steps: - uses: actions/checkout@v4 - - name: Setup D Compiler + - name: Setup D compiler uses: dlang-community/setup-dlang@v2 with: compiler: ${{ matrix.compiler == 'dmd' && 'dmd-master' || matrix.compiler }} - # 32-bit linux needs libs to link and run tests... - - name: Install 32-bit Toolchains (Linux) - if: ${{ matrix.os == 'ubuntu' && matrix.platform == 'x86' }} - run: sudo apt-get update && sudo apt-get install -y gcc-multilib - - name: Install 32-bit ARM Toolchains (Linux) - if: ${{ matrix.os == 'ubuntu' && matrix.platform == 'arm' }} - run: sudo dpkg --add-architecture armhf && sudo apt-get update && sudo apt-get install -y libstdc++6:armhf - - - name: Build release - if: ${{ github.ref == 'refs/heads/release' }} - run: make PLATFORM=${{ matrix.platform }} CONFIG=release OS=${{ matrix.os }} D_COMPILER=${{ matrix.compiler }} + - name: Install mbedtls (Linux host) + if: matrix.os == 'ubuntu' + run: sudo apt-get update && sudo apt-get install -y libmbedtls-dev + + - name: Install 32-bit deps (Linux x86) + if: matrix.os == 'ubuntu' && matrix.arch == 'x86' + run: | + sudo dpkg --add-architecture i386 + sudo apt-get update + sudo apt-get install -y gcc-multilib libmbedtls-dev:i386 + - name: Build unittest - run: make PLATFORM=${{ matrix.platform }} CONFIG=unittest OS=${{ matrix.os }} D_COMPILER=${{ matrix.compiler }} + run: make ARCH=${{ matrix.arch }} OS=${{ env.MAKE_OS }} CONFIG=unittest COMPILER=${{ matrix.compiler }} + + - name: Run unittest + run: ./bin/${{ matrix.arch }}_${{ env.MAKE_OS }}_unittest/urt_test${{ matrix.os == 'windows' && '.exe' || '' }} - - name: Test - if: ${{ success() && (matrix.platform == 'x86_64' || matrix.platform == 'x86' || matrix.platform == 'arm64') }} - run: ./bin/${{ matrix.platform }}_unittest/urt_test + - name: Build release library + if: github.ref == 'refs/heads/release' + run: make ARCH=${{ matrix.arch }} OS=${{ env.MAKE_OS }} CONFIG=release COMPILER=${{ matrix.compiler }} - name: Upload release library - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/release' && matrix.compiler == 'ldc' }} + if: github.event_name == 'push' && github.ref == 'refs/heads/release' && matrix.compiler == 'ldc' + uses: actions/upload-artifact@v4 + with: + name: urt-lib_${{ matrix.os }}_${{ matrix.arch }} + path: ./bin/${{ matrix.arch }}_${{ env.MAKE_OS }}_release/ + + # ─── Cross-bare: build flashable urt_test.bin for every embedded target ─── + # CI runner can't execute these — they're flash images. Artifacts are + # uploaded so anyone can grab one and flash it to real hardware for testing. + cross-bare: + name: cross ${{ matrix.target.name }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + target: + - { name: bl618, toolchain: riscv, args: PLATFORM=bl618 } + - { name: bl808-d0, toolchain: riscv, args: 'PLATFORM=bl808 PROCESSOR=c906' } + - { name: bl808-m0, toolchain: riscv, args: 'PLATFORM=bl808 PROCESSOR=e907' } + - { name: rp2350, toolchain: arm, args: PLATFORM=rp2350 } + - { name: bk7231n, toolchain: arm, args: PLATFORM=bk7231n } + - { name: bk7231t, toolchain: arm, args: PLATFORM=bk7231t } + - { name: stm4xx, toolchain: arm, args: PLATFORM=stm4xx } + - { name: stm7xx, toolchain: arm, args: PLATFORM=stm7xx } + steps: + - uses: actions/checkout@v4 + + - uses: dlang-community/setup-dlang@v2 + with: + compiler: ldc + + - name: Install ARM cross-toolchain + if: matrix.target.toolchain == 'arm' + run: | + sudo apt-get update + sudo apt-get install -y gcc-arm-none-eabi picolibc-arm-none-eabi + + - name: Install RISC-V cross-toolchain + if: matrix.target.toolchain == 'riscv' + run: | + sudo apt-get update + sudo apt-get install -y gcc-riscv64-unknown-elf picolibc-riscv64-unknown-elf + + - name: Build flashable unittest image + run: make ${{ matrix.target.args }} CONFIG=unittest + + - name: Upload flash image + uses: actions/upload-artifact@v4 + with: + name: urt_test_${{ matrix.target.name }} + path: | + bin/*/urt_test + bin/*/urt_test.bin + + # ─── Cross-ESP: pre-link artifacts only (no ESP-IDF on build slave) ─── + # esp32, esp32-s3 (Xtensa): emit LLVM bitcode (.bc) for downstream Espressif + # llc / ESP-IDF link. Requires LDC with Xtensa target enabled. + # esp32-p4 (RISC-V): plain compile to object (.o); link needs ESP-IDF. + cross-esp: + name: cross ${{ matrix.target.name }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + target: + - { name: esp32, arch: xtensa, ext: bc } # LX6 + - { name: esp32-s3, arch: xtensa, ext: bc } # LX7 + - { name: esp32-p4, arch: riscv, ext: o } # RV32IMAFDCV + steps: + - uses: actions/checkout@v4 + + - uses: dlang-community/setup-dlang@v2 + with: + compiler: ldc + + - name: Install RISC-V toolchain + if: matrix.target.arch == 'riscv' + run: | + sudo apt-get update + sudo apt-get install -y gcc-riscv64-unknown-elf picolibc-riscv64-unknown-elf + + # TODO: Xtensa needs LDC built with Xtensa target. Recent upstream LDC + # has experimental support; if dlang-community/setup-dlang's LDC build + # lacks it, install Espressif's LDC fork here. + + - name: Build + run: make PLATFORM=${{ matrix.target.name }} CONFIG=unittest + + - name: Upload artifact uses: actions/upload-artifact@v4 with: - name: urt-lib_${{ matrix.os }}_${{ matrix.platform }} - path: ./bin/${{ matrix.platform }}_release/${{ matrix.os == 'windows' && 'urt.lib' || 'liburt.a' }} + name: urt_test_${{ matrix.target.name }} + path: obj/*/urt_test.${{ matrix.target.ext }} diff --git a/Makefile b/Makefile index 924a71e..5d1e5fa 100644 --- a/Makefile +++ b/Makefile @@ -1,126 +1,166 @@ -OS ?= ubuntu -PLATFORM ?= x86_64 -CONFIG ?= debug -D_COMPILER ?= dmd -DC ?= dmd - -SRCDIR := src -TARGET_SUBDIR := $(PLATFORM)_$(CONFIG) -OBJDIR := obj/$(TARGET_SUBDIR) -TARGETDIR := bin/$(TARGET_SUBDIR) -TARGETNAME := urt - -# unittest config adjustments -ifeq ($(CONFIG),unittest) - TARGETNAME := $(TARGETNAME)_test - BUILD_TYPE := exe -else - BUILD_TYPE := lib -endif +URT_SRCDIR := src -DEPFILE := $(OBJDIR)/$(TARGETNAME).d +include platforms.mk -DFLAGS := $(DFLAGS) -preview=bitfields -preview=rvaluerefparam -preview=nosharedaccess -preview=in +# ======================================================================= +# Build mode +# +# Host (windows/linux/freebsd): +# default -> static lib (liburt.a / urt.lib) +# CONFIG=unittest -> standalone test exe +# +# Cross (freertos/baremetal): +# CONFIG=unittest -> flashable test image (.bin via objcopy), using URT's +# in-tree linker script (platforms//.ld) +# default -> compile-only (.o for non-ESP, .bc for ESP) +# ESP -> always .bc, no link possible without ESP-IDF +# ======================================================================= -ifeq ($(OS),windows) -SOURCES := $(shell dir /s /b $(SRCDIR)\\*.d) -else -SOURCES := $(shell find "$(SRCDIR)" -type f -name '*.d') +# OBJDIR/TARGETDIR and the vendor.mk import come from platforms.mk. + +# Linker script selection for cross-target unittest builds (ESP excluded -- +# no ESP-IDF on build slave). platforms.mk falls back to compile-only when +# BAREMETAL_LD isn't set. +ifeq ($(CONFIG),unittest) + ifeq ($(PLATFORM),bl808) + ifeq ($(PROCESSOR),c906) + BAREMETAL_LD := platforms/bl808/bl808_d0.ld + else ifeq ($(PROCESSOR),e907) + BAREMETAL_LD := platforms/bl808/bl808_m0.ld + endif + else ifeq ($(PLATFORM),bl618) + BAREMETAL_LD := platforms/bl618/bl618.ld + else ifneq ($(filter bk7231n bk7231t,$(PLATFORM)),) + BAREMETAL_LD := platforms/bk7231/$(PLATFORM).ld + else ifeq ($(PLATFORM),rp2350) + BAREMETAL_LD := platforms/rp2350/rp2350.ld + else ifdef STM32_VARIANT + BAREMETAL_LD := platforms/stm32/stm32_$(STM32_VARIANT).ld + endif + ifdef BAREMETAL_LD + DFLAGS := $(DFLAGS) -L-T$(BAREMETAL_LD) -main + endif endif -# Set target file based on build type and OS -ifeq ($(BUILD_TYPE),exe) +# Resolve build mode + target file +ifneq ($(filter freertos baremetal,$(OS)),) + ifdef BAREMETAL_LD + BUILD_MODE := embedded-exe + TARGETNAME := urt_test + TARGET := $(TARGETDIR)/$(TARGETNAME) BUILD_CMD_FLAGS := - ifeq ($(OS),windows) - TARGET = $(TARGETDIR)/$(TARGETNAME).exe - else - TARGET = $(TARGETDIR)/$(TARGETNAME) - endif -else # lib - BUILD_CMD_FLAGS := -lib - ifeq ($(OS),windows) - TARGET = $(TARGETDIR)/$(TARGETNAME).lib - else - TARGET = $(TARGETDIR)/lib$(TARGETNAME).a - endif + else ifeq ($(ARCH),xtensa) + # Xtensa: bitcode for downstream Espressif llc / ESP-IDF + BUILD_MODE := bitcode + TARGETNAME := urt$(if $(filter unittest,$(CONFIG)),_test) + TARGET := $(OBJDIR)/$(TARGETNAME).bc + BUILD_CMD_FLAGS := + else + # No linker script + non-Xtensa cross: compile-only object + BUILD_MODE := compile-only + TARGETNAME := urt$(if $(filter unittest,$(CONFIG)),_test) + TARGET := $(OBJDIR)/$(TARGETNAME).o + BUILD_CMD_FLAGS := + endif +else ifeq ($(CONFIG),unittest) + BUILD_MODE := exe + TARGETNAME := urt_test + BUILD_CMD_FLAGS := -main + ifeq ($(OS),windows) + TARGET := $(TARGETDIR)/$(TARGETNAME).exe + else + TARGET := $(TARGETDIR)/$(TARGETNAME) + endif +else + BUILD_MODE := lib + TARGETNAME := urt + BUILD_CMD_FLAGS := -lib + ifeq ($(OS),windows) + TARGET := $(TARGETDIR)/$(TARGETNAME).lib + else + TARGET := $(TARGETDIR)/lib$(TARGETNAME).a + endif endif -ifeq ($(D_COMPILER),ldc) - DFLAGS := $(DFLAGS) -I $(SRCDIR) - - ifeq ($(PLATFORM),x86_64) -# DFLAGS := $(DFLAGS) -mtriple=x86_64-linux-gnu - else ifeq ($(PLATFORM),x86) - ifeq ($(OS),windows) - DFLAGS := $(DFLAGS) -mtriple=i686-windows-msvc - else - DFLAGS := $(DFLAGS) -mtriple=i686-linux-gnu - endif - else ifeq ($(PLATFORM),arm64) - DFLAGS := $(DFLAGS) -mtriple=aarch64-linux-gnu - else ifeq ($(PLATFORM),arm) - DFLAGS := $(DFLAGS) -mtriple=arm-linux-eabihf -mcpu=cortex-a7 - else ifeq ($(PLATFORM),riscv64) - # we are building the Sipeed M1s device... which is BL808 as I understand - DFLAGS := $(DFLAGS) -mtriple=riscv64-unknown-elf -mcpu=c906 -mattr=+m,+a,+f,+c,+v - else - $(error "Unsupported platform: $(PLATFORM)") - endif +DEPFILE := $(OBJDIR)/$(TARGETNAME).d - ifeq ($(CONFIG),release) - DFLAGS := $(DFLAGS) -release -O3 -enable-inlining - else - DFLAGS := $(DFLAGS) -g -d-debug - endif -else ifeq ($(D_COMPILER),dmd) - DFLAGS := $(DFLAGS) -I=$(SRCDIR) - - ifeq ($(PLATFORM),x86_64) -# DFLAGS := $(DFLAGS) -m64 - else ifeq ($(PLATFORM),x86) - DFLAGS := $(DFLAGS) -m32 - else - $(error "Unsupported platform: $(PLATFORM)") - endif +# objcopy for embedded-exe -> .bin (derive from cross-gcc path) +ifeq ($(BUILD_MODE),embedded-exe) + ifneq ($(filter arm thumb,$(ARCH)),) + BAREMETAL_OBJCOPY := arm-none-eabi-objcopy + OBJCOPY_FLAGS := -R .bss -R .tbss -R '.tbss.*' -R .ARM.attributes -R '.debug*' + else + BAREMETAL_OBJCOPY := riscv64-unknown-elf-objcopy + OBJCOPY_FLAGS := + endif - ifeq ($(CONFIG),release) - DFLAGS := $(DFLAGS) -release -O -inline - else - DFLAGS := $(DFLAGS) -g -debug - endif -else - $(error "Unknown D compiler: $(D_COMPILER)") -endif + BAREMETAL_OBJS := $(patsubst %.S,$(OBJDIR)/%.o,$(patsubst %.c,$(OBJDIR)/%.o,$(BAREMETAL_SRCS))) + BAREMETAL_CFLAGS := $(BAREMETAL_CFLAGS) -ffreestanding -O2 -ifeq ($(CONFIG),unittest) - DFLAGS := $(DFLAGS) -unittest +$(OBJDIR)/%.o: $(BAREMETAL_DIR)/%.S + @mkdir -p $(OBJDIR) + $(BAREMETAL_GCC) $(BAREMETAL_CFLAGS) -c -o $@ $< + +$(OBJDIR)/%.o: $(BAREMETAL_DIR)/%.c + @mkdir -p $(OBJDIR) + $(BAREMETAL_GCC) $(BAREMETAL_CFLAGS) -c -o $@ $< endif --include $(DEPFILE) +# Vendor C deps ($(BL_*_OBJS) / $(MBEDTLS_OBJS)) come from vendor.mk. -$(TARGET): -ifeq ($(OS),windows) - @if not exist "obj" mkdir "obj" > nul 2>&1 - @if not exist "$(subst /,\,$(OBJDIR))" mkdir "$(subst /,\,$(OBJDIR))" > nul 2>&1 - @if not exist "bin" mkdir "bin" > nul 2>&1 - @if not exist "$(subst /,\,$(TARGETDIR))" mkdir "$(subst /,\,$(TARGETDIR))" > nul 2>&1 -else +# ======================================================================= +# Build rule +# ======================================================================= + +$(TARGET): $(BAREMETAL_OBJS) $(VENDOR_OBJS) mkdir -p $(OBJDIR) $(TARGETDIR) -endif -ifeq ($(D_COMPILER),ldc) - "$(DC)" $(DFLAGS) $(BUILD_CMD_FLAGS) -of$(TARGET) -od$(OBJDIR) -deps=$(DEPFILE) $(SOURCES) -else ifeq ($(D_COMPILER),dmd) -ifeq ($(BUILD_TYPE),lib) - "$(DC)" $(DFLAGS) $(BUILD_CMD_FLAGS) -of$(notdir $(TARGET)) -od$(OBJDIR) -makedeps $(SOURCES) > $(DEPFILE) -ifeq ($(OS),windows) - move "$(subst /,\,$(OBJDIR))\\$(notdir $(TARGET))" "$(subst /,\,$(TARGETDIR))" > nul -else +ifeq ($(COMPILER),ldc) + "$(DC)" $(DFLAGS) $(BUILD_CMD_FLAGS) -of$(TARGET) -od$(OBJDIR) -deps=$(DEPFILE) $(BAREMETAL_OBJS) $(VENDOR_OBJS) $(URT_SOURCES) +else ifeq ($(COMPILER),dmd) +ifeq ($(BUILD_MODE),lib) + "$(DC)" $(DFLAGS) $(BUILD_CMD_FLAGS) -of$(OBJDIR)/$(notdir $(TARGET)) -od$(OBJDIR) -makedeps $(URT_SOURCES) > $(DEPFILE) mv "$(OBJDIR)/$(notdir $(TARGET))" "$(TARGETDIR)" +else + "$(DC)" $(DFLAGS) $(BUILD_CMD_FLAGS) -of$(TARGET) -od$(OBJDIR) -makedeps $(URT_SOURCES) > $(DEPFILE) endif -else # exe - "$(DC)" $(DFLAGS) $(BUILD_CMD_FLAGS) -of$(TARGET) -od$(OBJDIR) -makedeps $(SOURCES) > $(DEPFILE) endif +ifeq ($(BUILD_MODE),embedded-exe) + $(BAREMETAL_OBJCOPY) -O binary $(OBJCOPY_FLAGS) $(TARGET) $(TARGETDIR)/$(TARGETNAME).bin endif +# ======================================================================= +# CI: build the full cross-target matrix +# +# Embedded targets produce flashable urt_test images (.bin); ESP variants +# produce LLVM bitcode (no ESP-IDF on build slave). Catches submodule-bump +# breakage before downstream projects update. +# ======================================================================= + +CI_PLATFORMS := \ + esp32 esp32-s2 esp32-s3 esp32-c2 esp32-c3 esp32-c5 esp32-c6 esp32-h2 esp32-p4 \ + bl618 bk7231n bk7231t rp2350 stm4xx stm7xx bl808-d0 bl808-m0 + +.PHONY: ci-build +ci-build: + @set -e; for p in $(CI_PLATFORMS); do \ + case $$p in \ + bl808-d0) args="PLATFORM=bl808 PROCESSOR=c906" ;; \ + bl808-m0) args="PLATFORM=bl808 PROCESSOR=e907" ;; \ + *) args="PLATFORM=$$p" ;; \ + esac; \ + echo "=== ci-build: $$p ($$args) ==="; \ + $(MAKE) --no-print-directory $$args CONFIG=unittest || exit 1; \ + done + @echo "" + @echo "=== ci-build complete ===" + @find bin obj -type f \( -name 'urt_test*.bin' -o -name 'urt_test*.bc' -o -name 'urt_test*.o' \) 2>/dev/null | sort + +# ======================================================================= +# Clean +# ======================================================================= + clean: rm -rf $(OBJDIR) $(TARGETDIR) + +clean-all: + rm -rf obj bin diff --git a/platforms.mk b/platforms.mk new file mode 100644 index 0000000..d11929d --- /dev/null +++ b/platforms.mk @@ -0,0 +1,778 @@ +# ======================================================================= +# URT platform/processor/toolchain configuration +# +# Shared between URT's own Makefile and downstream consumers (OpenWatt etc.). +# Anything that depends on which SoC/core/toolchain we're targeting lives here. +# +# Inputs (set by caller before include): +# PLATFORM - SoC/board (esp32-s3, bl808, bl618, bk7231n, rp2350, stm4xx, ...) +# or OS name (windows, linux, ubuntu, freebsd) for host builds. +# Auto-detected from `uname` if undefined. +# PROCESSOR - CPU core (e907, c906, lx7, cortex-m33, ...). Usually derived +# from PLATFORM; override only for multi-core SoCs (e.g. +# PROCESSOR=e907 for the BL808 M0 core). +# CONFIG - debug | release | unittest +# COMPILER - dmd | ldc | gdc. Auto-promoted to ldc for cross-compile. +# URT_SRCDIR - path to URT's src/ tree. Default `src` (URT in-tree); outer +# projects set this to e.g. `third_party/urt/src`. +# +# Outputs (resolved variables for caller to consume): +# ARCH, OS, MARCH, MATTR, MABI, PROCESSOR, BUILDNAME, COMPILER, DC +# DFLAGS - augmented with triple, mattr, platform version flags +# URT_SOURCES - urt/**.d + urt/driver//**.d (+ mbedtls.c on host) +# BAREMETAL_DIR - dir containing start.S etc. (empty on host targets) +# BAREMETAL_SRCS - basenames of asm/c sources for cross-gcc +# BAREMETAL_GCC - cross-gcc path +# BAREMETAL_CFLAGS - cross-gcc cflags (mcpu/march/mabi/mfpu) +# BAREMETAL_LIBC/M/GCC - resolved newlib/picolibc/libgcc archive paths +# ESPRESSIF_PATH, ESPRESSIF_XTENSA_BIN, ESPRESSIF_RISCV32_BIN +# XTENSA_TWO_STAGE, ESPRESSIF_LLC, XTENSA_MATTR +# +# Caller still owns (NOT set here -- these are app-specific): +# - BAREMETAL_LD: linker script (app memory map lives in the consumer's +# platforms//ld/*.ld tree). +# - `-J` string-imports for app config dirs (consumer's platforms//). +# - Vendor SDK roots and blob paths (BK_SDK_ROOT, ESP_PROJECT_DIR, ...). +# - Final link/objcopy/packaging (containers, .bin, flashing, OTA). +# - The build rule that actually produces $(TARGET). +# ======================================================================= + +URT_SRCDIR ?= src + +# URT checkout root (./ in-tree, /third_party/urt/ downstream). +# Used to locate vendor.mk and the vendored blob trees. +URT_ROOT := $(dir $(URT_SRCDIR)) +CONFIG ?= debug +COMPILER ?= dmd + +# Windows always sets env OS=Windows_NT -- normalize so OS-conditional blocks +# (driver/windows source selection, host triple) recognize it. Plain `:=` (not +# `override`) so platform blocks can still set OS=baremetal/freertos for cross. +ifeq ($(OS),Windows_NT) + OS := windows +endif + +# ======================================================================= +# PLATFORM -- SoC/board identity +# +# Sets: BUILDNAME, PROCESSOR (default), OS, vendor version flags, +# platform source paths, vendor-specific GCC wrappers (Xtensa). +# ======================================================================= + +# Normalize CI-friendly platform aliases before platform detection +ifeq ($(PLATFORM),bl808_m0) + override PLATFORM := bl808 + PROCESSOR := e907 +endif + +ifeq ($(PLATFORM),esp8266) + # ESP8266 has no FPU! + BUILDNAME := esp8266 + PROCESSOR := l106 + OS = freertos + XTENSA_GCC := xtensa-lx106-elf-gcc +else ifeq ($(PLATFORM),esp32) + BUILDNAME := esp32 + PROCESSOR := lx6 + OS = freertos + XTENSA_GCC := xtensa-esp32-elf-gcc +else ifeq ($(PLATFORM),esp32-s2) + # Single-core LX7, 240MHz -- NO FPU, NO loops + BUILDNAME := esp32-s2 + PROCESSOR := lx7 + OS = freertos + XTENSA_GCC := xtensa-esp32s2-elf-gcc +else ifeq ($(PLATFORM),esp32-s3) + # Dual-core LX7, 240MHz -- FPU, loops, hardware unaligned access + BUILDNAME := esp32-s3 + PROCESSOR := lx7 + OS = freertos + XTENSA_GCC := xtensa-esp32s3-elf-gcc + MATTR = +fp,+loop + DFLAGS := $(DFLAGS) -d-version=SupportUnaligned +else ifeq ($(PLATFORM),esp32-h2) + BUILDNAME := esp32-h2 + PROCESSOR := e906 + OS = freertos +else ifeq ($(PLATFORM),esp32-c2) + BUILDNAME := esp32-c2 + PROCESSOR := e906 + OS = freertos +else ifeq ($(PLATFORM),esp32-c3) + BUILDNAME := esp32-c3 + PROCESSOR := e906 + OS = freertos +else ifeq ($(PLATFORM),esp32-c5) + # RV32IMAC, 240MHz -- has atomics + BUILDNAME := esp32-c5 + PROCESSOR := e907 + OS = freertos +else ifeq ($(PLATFORM),esp32-c6) + # RV32IMAC, 160MHz -- has atomics + BUILDNAME := esp32-c6 + PROCESSOR := e907 + OS = freertos +else ifeq ($(PLATFORM),esp32-p4) + # HP core: RV32IMAFDCV, 400MHz + BUILDNAME := esp32-p4 + PROCESSOR := esp32p4 + OS = freertos +else ifeq ($(PLATFORM),bl808) + # BL808 multi-core SoC -- default to D0 (C906 RV64GC) + # Override with PROCESSOR=e907 for M0 core (E907 RV32IMAFC) + PROCESSOR ?= c906 + OS = baremetal + ifeq ($(PROCESSOR),c906) + BUILDNAME := bl808-d0 + else ifeq ($(PROCESSOR),e907) + BUILDNAME := bl808-m0 + else + $(error "BL808: unsupported PROCESSOR=$(PROCESSOR) (expected c906 or e907)") + endif +else ifeq ($(PLATFORM),bl618) + # Sipeed M0P -- Bouffalo BL618, single-core T-Head E907 RV32IMAFC, 320MHz + BUILDNAME := bl618 + PROCESSOR := e907 + OS = baremetal +else ifneq ($(filter bk7231n bk7231t,$(PLATFORM)),) + # Beken BK7231 family -- ARM968E-S (ARMv5TE), 120MHz, 256KB SRAM, 2MB SPI flash + # BK7231N adds BLE 5.0; BK7231T is Wi-Fi only. Same MCU peripherals. + BUILDNAME := $(PLATFORM) + PROCESSOR := arm968e-s + OS = baremetal +else ifeq ($(PLATFORM),rp2350) + # Raspberry Pi RP2350 -- dual Cortex-M33, 150MHz, 520KB SRAM, XIP QSPI flash + BUILDNAME := rp2350 + PROCESSOR := cortex-m33 + OS = baremetal +else ifeq ($(PLATFORM),stm7xx) + BUILDNAME := stm7xx + PROCESSOR := cortex-m7 + OS = baremetal + STM32_VARIANT = f7 + MFPU = fpv5-d16 +else ifeq ($(PLATFORM),stm4xx) + BUILDNAME := stm4xx + PROCESSOR := cortex-m4 + OS = baremetal + STM32_VARIANT = f4 + MFPU = fpv4-sp-d16 +else ifeq ($(PLATFORM),routeros) + # MikroTik RouterOS container (ARM64 Linux). Packaging is consumer-side. + BUILDNAME := routeros + PROCESSOR := aarch64-generic + OS := linux +else + ifeq ($(origin PLATFORM),undefined) + # No platform specified -- auto-detect host + UNAME_S := $(shell uname -s 2>/dev/null || echo Unknown) + UNAME_M := $(shell uname -m 2>/dev/null || echo unknown) + + ifneq ($(findstring MINGW,$(UNAME_S)),) + PLATFORM := windows + OS := windows + else ifneq ($(findstring MSYS,$(UNAME_S)),) + PLATFORM := windows + OS := windows + else ifneq ($(findstring CYGWIN,$(UNAME_S)),) + PLATFORM := windows + OS := windows + else ifeq ($(UNAME_S),Unknown) + # no uname, probably native Windows - assume x86_64 + PLATFORM := windows + OS := windows + UNAME_M := x86_64 + else ifeq ($(UNAME_S),) + # cmd.exe / PowerShell: shell couldn't honour `|| echo Unknown` either + OS := windows + UNAME_M := x86_64 + else + OS ?= linux + endif + + PLATFORM := $(OS) + + ifndef ARCH + ifeq ($(UNAME_M),x86_64) + ARCH := x86_64 + else ifeq ($(UNAME_M),amd64) + ARCH := x86_64 + else ifeq ($(UNAME_M),i686) + ARCH := x86 + else ifeq ($(UNAME_M),i386) + ARCH := x86 + else ifeq ($(UNAME_M),aarch64) + ARCH := arm64 + else ifeq ($(UNAME_M),arm64) + ARCH := arm64 + else ifeq ($(UNAME_M),armv7l) + ARCH := arm + else ifeq ($(UNAME_M),riscv64) + ARCH := riscv64 + endif + endif + endif +endif + +# Bare-processor fallback: if PLATFORM was set but didn't match any known +# platform above, treat it as a raw processor name (e.g., make PLATFORM=e906). +ifndef PROCESSOR + ifdef PLATFORM + ifneq ($(PLATFORM),$(OS)) + PROCESSOR := $(PLATFORM) + endif + endif +endif + +# ======================================================================= +# PROCESSOR -- CPU core identity +# +# Sets: ARCH, MARCH, MABI. Pure ISA/compiler-target config. +# OS is set with ?= only as a fallback for bare-processor builds; +# PLATFORM always takes precedence. +# ======================================================================= + +ifdef PROCESSOR + ifeq ($(PROCESSOR),aarch64-generic) + ARCH = arm64 + else ifeq ($(PROCESSOR),cortex-a7) + ARCH = arm + MARCH = cortex-a7 + else ifeq ($(PROCESSOR),cortex-m4) + ARCH = thumb + MARCH = cortex-m4 + else ifeq ($(PROCESSOR),arm968e-s) + ARCH = arm + MARCH = arm968e-s + MABI = soft + OS ?= baremetal + else ifeq ($(PROCESSOR),cortex-m33) + ARCH = thumb + MARCH = cortex-m33 + else ifeq ($(PROCESSOR),cortex-m7) + ARCH = thumb + MARCH = cortex-m7 + else ifeq ($(PROCESSOR),l106) + ARCH = xtensa + else ifeq ($(PROCESSOR),lx6) + ARCH = xtensa + MATTR = +fp,+loop,+mac16,+dfpaccel + else ifeq ($(PROCESSOR),lx7) + ARCH = xtensa + else ifeq ($(PROCESSOR),k210) + ARCH = riscv64 + MARCH = rv64imafdc + MATTR = +m,+a,+f,+d,+c,+zicsr,+zifencei + MABI = lp64d + OS ?= baremetal + else ifeq ($(PROCESSOR),c906) + ARCH = riscv64 + MARCH = rv64imafdc + MATTR = +m,+a,+f,+d,+c,+unaligned-scalar-mem,+xtheadba,+xtheadbb,+xtheadbs,+xtheadcmo,+xtheadcondmov,+xtheadfmemidx,+xtheadmac,+xtheadmemidx,+xtheadsync + MABI = lp64d + OS ?= baremetal + else ifeq ($(PROCESSOR),e902) + ARCH = riscv + MARCH = rv32emc + MATTR = +e,+m,+c + MABI = ilp32e + OS ?= baremetal + else ifeq ($(PROCESSOR),e906) + ARCH = riscv + MARCH = rv32imc + MATTR = +m,+c + MABI = ilp32 + OS ?= freertos + else ifeq ($(PROCESSOR),e907) + ARCH = riscv + MARCH = rv32imafc + MATTR = +m,+a,+f,+c + MABI = ilp32f + OS ?= freertos + else ifeq ($(PROCESSOR),esp32p4) + ARCH = riscv + MARCH = rv32imafdcv + MATTR = +m,+a,+f,+d,+c,+v + MABI = ilp32f + OS ?= freertos + endif +endif + +ifndef BUILDNAME + ifdef PROCESSOR + BUILDNAME := $(PROCESSOR) + else + BUILDNAME := $(ARCH)_$(OS) + endif +endif + +# ======================================================================= +# Compiler auto-selection: cross-compilation targets use LDC +# ======================================================================= + +ifeq ($(COMPILER),dmd) +ifdef ARCH +ifneq ($(ARCH),x86_64) +ifneq ($(ARCH),x86) + COMPILER = ldc +endif +endif +endif +endif + +ifeq ($(COMPILER),dmd) + VERSION_FLAG := -version= +else ifeq ($(COMPILER),gdc) + VERSION_FLAG := -fversion= +else + VERSION_FLAG := -d-version= +endif + +# ======================================================================= +# Toolchain discovery (Espressif) +# ======================================================================= + +ESPRESSIF_PATH ?= $(wildcard $(HOME)/.espressif) +ifdef ESPRESSIF_PATH + ESPRESSIF_XTENSA_BIN := $(lastword $(sort $(wildcard $(ESPRESSIF_PATH)/tools/xtensa-esp-elf/*/xtensa-esp-elf/bin))) + ESPRESSIF_RISCV32_BIN := $(lastword $(sort $(wildcard $(ESPRESSIF_PATH)/tools/riscv32-esp-elf/*/riscv32-esp-elf/bin))) +endif + +# ======================================================================= +# URT_SOURCES -- urt/**.d + urt/driver//**.d +# +# Caller appends app sources separately. C glue (mbedtls) is host-only. +# ======================================================================= + +URT_SOURCES := $(shell find "$(URT_SRCDIR)" -type f -name '*.d' -not -path '$(URT_SRCDIR)/urt/driver/*') +URT_SOURCES := $(URT_SOURCES) $(shell find "$(URT_SRCDIR)/urt/driver" -maxdepth 1 -type f -name '*.d') +URT_SOURCES := $(URT_SOURCES) $(shell find "$(URT_SRCDIR)/urt/driver/baremetal" -type f -name '*.d') + +# mbedtls availability -- host posix builds get it from system libs, +# ESP-IDF ships it for esp% targets (linked via IDF main component). +# User can force via USE_MBEDTLS=1/0 on the command line. +ifneq ($(filter linux ubuntu freebsd,$(OS)),) + USE_MBEDTLS ?= 1 +endif +ifneq ($(filter esp%,$(PLATFORM)),) + USE_MBEDTLS ?= 1 +endif +ifneq ($(filter bl808 bl618,$(PLATFORM)),) + USE_MBEDTLS ?= 1 +endif + +# mbedtls C glue: host posix builds compile it directly via URT_SOURCES. +# Embedded targets must compile it via their platform's build system +# (e.g. esp32 via IDF main component, bouffalo via consumer Makefile) so +# the cross-compiler picks up the right mbedtls headers. +ifeq ($(USE_MBEDTLS),1) +ifeq ($(filter freertos baremetal,$(OS)),) + URT_SOURCES := $(URT_SOURCES) $(URT_SRCDIR)/urt/internal/mbedtls.c +endif +endif + +ifeq ($(PLATFORM),bl808) + URT_SOURCES := $(URT_SOURCES) $(shell find "$(URT_SRCDIR)/urt/driver/bl_common" -type f -name '*.d') + ifeq ($(PROCESSOR),c906) + URT_SOURCES := $(URT_SOURCES) $(shell find "$(URT_SRCDIR)/urt/driver/bl808" -type f -name '*.d') + else ifeq ($(PROCESSOR),e907) + # BL808 M0 core -- E907 uses same peripheral drivers as BL618. + URT_SOURCES := $(URT_SOURCES) $(shell find "$(URT_SRCDIR)/urt/driver/bl618" -type f -name '*.d') + URT_SOURCES := $(URT_SOURCES) $(shell find "$(URT_SRCDIR)/urt/driver/wpa" -type f -name '*.d') + URT_SOURCES := $(URT_SOURCES) $(shell find "$(URT_SRCDIR)/urt/driver/bl808_m0" -type f -name '*.d') + endif +endif +ifeq ($(PLATFORM),bl618) + URT_SOURCES := $(URT_SOURCES) $(shell find "$(URT_SRCDIR)/urt/driver/bl618" -type f -name '*.d') + URT_SOURCES := $(URT_SOURCES) $(shell find "$(URT_SRCDIR)/urt/driver/bl_common" -type f -name '*.d') +endif +ifeq ($(PLATFORM),rp2350) + URT_SOURCES := $(URT_SOURCES) $(shell find "$(URT_SRCDIR)/urt/driver/rp2350" -type f -name '*.d') +endif +ifneq ($(filter bk7231n bk7231t,$(PLATFORM)),) + URT_SOURCES := $(URT_SOURCES) $(shell find "$(URT_SRCDIR)/urt/driver/bk7231" -type f -name '*.d' 2>/dev/null) +endif +ifneq ($(filter esp%,$(PLATFORM)),) + URT_SOURCES := $(URT_SOURCES) $(shell find "$(URT_SRCDIR)/urt/driver/esp32" -type f -name '*.d') +endif +ifdef STM32_VARIANT + URT_SOURCES := $(URT_SOURCES) $(shell find "$(URT_SRCDIR)/urt/driver/stm32" -type f -name '*.d') +endif +ifeq ($(OS),windows) + URT_SOURCES := $(URT_SOURCES) $(shell find "$(URT_SRCDIR)/urt/driver/windows" -type f -name '*.d') +endif +ifneq ($(filter linux ubuntu freebsd,$(OS)),) + URT_SOURCES := $(URT_SOURCES) $(shell find "$(URT_SRCDIR)/urt/driver/posix" -type f -name '*.d') +endif +ifeq ($(OS),freertos) + URT_SOURCES := $(URT_SOURCES) $(shell find "$(URT_SRCDIR)/urt/driver/freertos" -type f -name '*.d') +endif + +# ======================================================================= +# DFLAGS -- version flags + previews +# +# Only platform/processor *version* flags live here (so URT's urt/driver/ code +# can `version (BL808)` etc.). Consumer-side `-J platforms/` string +# imports stay in the consumer Makefile. +# ======================================================================= + +DFLAGS := $(DFLAGS) -preview=bitfields -preview=rvaluerefparam -preview=in #-preview=nosharedaccess <- TODO + +# OS-level versions +ifeq ($(OS),freertos) + DFLAGS := $(DFLAGS) -d-version=FreeRTOS +endif +ifeq ($(OS),baremetal) + DFLAGS := $(DFLAGS) -d-version=BareMetal +endif +ifneq ($(filter freertos baremetal,$(OS)),) + DFLAGS := $(DFLAGS) -d-version=Embedded +endif + +# "Tiny" targets: <~350KB RAM and <2MB flash, or no external memory at all. +# Code gates nice-to-haves (verbose help, optional protocols) behind +# `version (Tiny)` to minimise binary size. Override with TINY=1/0. +ifneq ($(filter esp8266 bk7231n bk7231t esp32-c2 esp32-h2 esp32-s2,$(PLATFORM)),) + TINY ?= 1 +endif +ifeq ($(PLATFORM),bl808) + ifeq ($(PROCESSOR),e907) + TINY ?= 1 + endif +endif +ifeq ($(TINY),1) + DFLAGS := $(DFLAGS) -d-version=Tiny +endif +ifeq ($(USE_MBEDTLS),1) +ifdef VERSIONS + VERSIONS := $(VERSIONS),MbedTLS +else + VERSIONS := MbedTLS +endif +endif + +# Vendor/family versions consumed by URT's urt/driver/ code +ifneq ($(filter esp%,$(PLATFORM)),) + DFLAGS := $(DFLAGS) -d-version=Espressif -d-version=CRuntime_Picolibc + USE_LWIP := 1 +endif +ifeq ($(PLATFORM),bl808) + ifeq ($(PROCESSOR),c906) + DFLAGS := $(DFLAGS) -d-version=BL808 -d-version=Bouffalo -d-version=CRuntime_Picolibc + else ifeq ($(PROCESSOR),e907) + DFLAGS := $(DFLAGS) -d-version=BL808 -d-version=BL808_M0 -d-version=Bouffalo -d-version=CRuntime_Picolibc + endif +endif +ifeq ($(PLATFORM),bl618) + DFLAGS := $(DFLAGS) -d-version=BL618 -d-version=Bouffalo -d-version=CRuntime_Picolibc +endif +ifeq ($(PLATFORM),rp2350) + DFLAGS := $(DFLAGS) -d-version=RP2350 -d-version=CRuntime_Picolibc +endif +ifdef STM32_VARIANT + DFLAGS := $(DFLAGS) -d-version=STM32 -d-version=CRuntime_Picolibc + ifeq ($(STM32_VARIANT),f4) + DFLAGS := $(DFLAGS) -d-version=STM32F4 + else ifeq ($(STM32_VARIANT),f7) + DFLAGS := $(DFLAGS) -d-version=STM32F7 + endif +endif +ifneq ($(filter bk7231n bk7231t,$(PLATFORM)),) + DFLAGS := $(DFLAGS) -d-version=Beken -d-version=CRuntime_Picolibc + ifeq ($(PLATFORM),bk7231n) + DFLAGS := $(DFLAGS) -d-version=BK7231N + else + DFLAGS := $(DFLAGS) -d-version=BK7231T + endif +endif + +# Chip-specific versions +ifeq ($(PLATFORM),esp8266) + DFLAGS := $(DFLAGS) -d-version=ESP8266 +else ifeq ($(PLATFORM),esp32) + DFLAGS := $(DFLAGS) -d-version=ESP32 +else ifeq ($(PLATFORM),esp32-s2) + DFLAGS := $(DFLAGS) -d-version=ESP32_S2 +else ifeq ($(PLATFORM),esp32-s3) + DFLAGS := $(DFLAGS) -d-version=ESP32_S3 +else ifeq ($(PLATFORM),esp32-c2) + DFLAGS := $(DFLAGS) -d-version=ESP32_C2 +else ifeq ($(PLATFORM),esp32-c3) + DFLAGS := $(DFLAGS) -d-version=ESP32_C3 +else ifeq ($(PLATFORM),esp32-c5) + DFLAGS := $(DFLAGS) -d-version=ESP32_C5 +else ifeq ($(PLATFORM),esp32-c6) + DFLAGS := $(DFLAGS) -d-version=ESP32_C6 +else ifeq ($(PLATFORM),esp32-h2) + DFLAGS := $(DFLAGS) -d-version=ESP32_H2 +else ifeq ($(PLATFORM),esp32-p4) + DFLAGS := $(DFLAGS) -d-version=ESP32_P4 +endif + +# IP stack: windows/linux drive the host kernel's network stack by default; +# every other target has no host stack and falls back to URT's in-tree stack. +# Override either default on the command line (e.g. USE_INTERNAL_IP_STACK=1). +ifeq ($(USE_INTERNAL_IP_STACK),) + ifeq ($(filter windows linux,$(OS)),) + USE_INTERNAL_IP_STACK := 1 + else + USE_INTERNAL_IP_STACK := 0 + endif +endif +ifeq ($(USE_INTERNAL_IP_STACK),1) + DFLAGS := $(DFLAGS) $(VERSION_FLAG)UseInternalIPStack +else ifeq ($(USE_LWIP),1) + DFLAGS := $(DFLAGS) $(VERSION_FLAG)lwIP +endif + +ifeq ($(CONFIG),unittest) + DFLAGS := $(DFLAGS) -unittest +endif + +# ======================================================================= +# Compiler configuration -- triple, mattr, link flags +# ======================================================================= + +ifeq ($(COMPILER),ldc) + # Prefer dlang-installer LDC (avoids system package conflicts with cross-compile) + DC := $(lastword $(sort $(wildcard $(HOME)/dlang/ldc-*/bin/ldc2))) + DC := $(if $(DC),$(DC),ldc2) + + # Strip druntime/phobos -- URT brings its own object.d and runtime support. + # OpenWatt's ldc2.conf does the same via `switches = ["-defaultlib="]` for + # builds invoked from its tree; setting it here too means URT-standalone + # builds (e.g. URT's own CI) don't need their own ldc2.conf. + # + # -frame-pointer=all: keep the frame pointer in every function. URT's + # exception/unwind machinery walks EBP/RBP chains directly (notably on + # x86 Windows SEH and bare-metal stack-trace capture); leaf-FPO would + # leave gaps and crash the walker. Skipped for Espressif targets, which + # use libgcc _Unwind_Backtrace (DWARF) and have no FP-chain walker -- + # and where the attribute also triggers an Xtensa LLVM register + # scavenger bug at -O>=1 (LLVM_BUG_5_REGSCAVENGER_SPILL). + DFLAGS := $(DFLAGS) -defaultlib= -I $(URT_SRCDIR) + ifneq ($(filter esp%,$(PLATFORM)),) + # ESP32 family: DWARF unwind, no FP-chain walking. + else + DFLAGS := $(DFLAGS) -frame-pointer=all + endif + + ifeq ($(ARCH),x86_64) +# DFLAGS := $(DFLAGS) -mtriple=x86_64-linux-gnu + else ifeq ($(ARCH),x86) + ifeq ($(OS),windows) + DFLAGS := $(DFLAGS) -mtriple=i686-windows-msvc + else + DFLAGS := $(DFLAGS) -mtriple=i686-linux-gnu + endif + else ifeq ($(ARCH),arm64) + ifeq ($(OS),freertos) + DFLAGS := $(DFLAGS) -mtriple=aarch64-none-elf + else ifeq ($(OS),windows) + DFLAGS := $(DFLAGS) -mtriple=aarch64-windows-msvc + else + DFLAGS := $(DFLAGS) -mtriple=aarch64-linux-gnu + # Cross-compile linker, fully static for minimal container size + DFLAGS := $(DFLAGS) -gcc=aarch64-linux-gnu-gcc -static -L-static + endif + else ifeq ($(ARCH),thumb) + ifeq ($(MARCH),cortex-m33) + DFLAGS := $(DFLAGS) -mtriple=thumbv8m.main-none-eabihf -gcc=arm-none-eabi-gcc + else + DFLAGS := $(DFLAGS) -mtriple=thumbv7em-none-eabihf -gcc=arm-none-eabi-gcc + endif + ifdef MARCH + DFLAGS := $(DFLAGS) -mcpu=$(MARCH) + endif + else ifeq ($(ARCH),arm) + ifeq ($(OS),baremetal) + ifeq ($(MABI),soft) + # ARMv5TE has no atomic instructions -- single-thread model + # makes LLVM lower atomics to plain loads/stores + DFLAGS := $(DFLAGS) -mtriple=armv5te-none-eabi -float-abi=soft --thread-model=single + else + DFLAGS := $(DFLAGS) -mtriple=arm-none-eabihf + endif + else ifeq ($(OS),freertos) + DFLAGS := $(DFLAGS) -mtriple=arm-none-eabihf + else ifeq ($(OS),windows) + DFLAGS := $(DFLAGS) -mtriple=armv7-windows-msvc + else + DFLAGS := $(DFLAGS) -mtriple=armv7-linux-gnueabihf + endif + DFLAGS := $(DFLAGS) -gcc=arm-none-eabi-gcc + ifdef MARCH + DFLAGS := $(DFLAGS) -mcpu=$(MARCH) + endif + else ifeq ($(ARCH),riscv64) + DFLAGS := $(DFLAGS) -mtriple=riscv64-unknown-elf -gcc=riscv64-unknown-elf-gcc -code-model=medium + DFLAGS := $(DFLAGS) -mattr=$(MATTR) + # ImportC needs picolibc headers for C imports (stdio.h etc.) + PICOLIBC_INCLUDE := $(firstword $(wildcard /usr/riscv64-unknown-elf/include /usr/lib/picolibc/riscv64-unknown-elf/include)) + DFLAGS := $(DFLAGS) $(if $(PICOLIBC_INCLUDE),-P=-isystem -P=$(PICOLIBC_INCLUDE)) + else ifeq ($(ARCH),riscv) + RISCV32_GCC ?= $(or $(if $(ESPRESSIF_RISCV32_BIN),$(ESPRESSIF_RISCV32_BIN)/riscv32-esp-elf-gcc),$(shell which riscv32-esp-elf-gcc 2>/dev/null),riscv64-unknown-elf-gcc) + DFLAGS := $(DFLAGS) -mtriple=riscv32-unknown-elf -gcc=$(RISCV32_GCC) + DFLAGS := $(DFLAGS) -mattr=$(MATTR) -mabi=$(MABI) + ifeq ($(PROCESSOR),e902) + DFLAGS := $(DFLAGS) -d-version=RISCV32E + endif + else ifeq ($(ARCH),xtensa) + # Xtensa -- requires Espressif toolchain (chip-specific GCC wrappers). + # Two-stage codegen: LDC emits bitcode, Espressif's llc does codegen + # (upstream LLVM Xtensa backend crashes on invoke+landingpad at -O1+). + XTENSA_GCC_DIR ?= $(or $(if $(ESPRESSIF_XTENSA_BIN),$(ESPRESSIF_XTENSA_BIN)/),$(dir $(shell which xtensa-esp-elf-gcc 2>/dev/null))) + # Base features common to all ESP32 Xtensa cores (LX6, S2 LX7, S3 LX7). + # +fp and +loop are NOT universal -- S2 lacks both. + XTENSA_MATTR := -mattr=+density,+mul16,+mul32,+mul32high,+div32 \ + -mattr=+sext,+nsa,+clamps,+minmax,+bool \ + -mattr=+windowed,+threadptr \ + -mattr=+exception,+interrupt,+highpriinterrupts,+debug + ifdef MATTR + XTENSA_MATTR := $(XTENSA_MATTR) -mattr=$(MATTR) + endif + # Workarounds: + # - single-thread model: no atomic instructions, lower atomics to plain loads/stores + # - emulated TLS: @TPOFF symbol suffixes incompatible with GNU ld + # - align-all-functions=2: ensures 4-byte alignment for l32r literal targets + DFLAGS := $(DFLAGS) -mtriple=xtensa-none-elf --thread-model=single -emulated-tls \ + --align-all-functions=2 $(XTENSA_MATTR) \ + -gcc=$(XTENSA_GCC_DIR)$(XTENSA_GCC) + ESPRESSIF_LLC := $(lastword $(sort $(wildcard $(HOME)/.espressif/tools/esp-clang/*/esp-clang/bin/llc))) + XTENSA_TWO_STAGE := 1 + else + $(error "Unsupported ARCH: $(ARCH)") + endif + + # Embedded baremetal: assemble cross-gcc flags + libc/libm/libgcc paths. + # Caller supplies BAREMETAL_LD (linker script) -- without it we emit `-c` + # (compile-only; sufficient for CI link-check of URT-only builds). + ifneq ($(filter freertos baremetal,$(OS)),) + ifeq ($(PLATFORM),bl808) + ifeq ($(PROCESSOR),c906) + BAREMETAL_DIR := $(URT_SRCDIR)/urt/driver/bl808 + BAREMETAL_SRCS := start.S hbn_ram.c + else ifeq ($(PROCESSOR),e907) + BAREMETAL_DIR := $(URT_SRCDIR)/urt/driver/bl808_m0 + BAREMETAL_SRCS := start.S + endif + else ifeq ($(PLATFORM),bl618) + BAREMETAL_DIR := $(URT_SRCDIR)/urt/driver/bl618 + BAREMETAL_SRCS := start.S + else ifneq ($(filter bk7231n bk7231t,$(PLATFORM)),) + BAREMETAL_DIR := $(URT_SRCDIR)/urt/driver/bk7231 + BAREMETAL_SRCS := start.S + else ifeq ($(PLATFORM),rp2350) + BAREMETAL_DIR := $(URT_SRCDIR)/urt/driver/rp2350 + BAREMETAL_SRCS := start.S boot2.S + else ifdef STM32_VARIANT + BAREMETAL_DIR := $(URT_SRCDIR)/urt/driver/stm32 + BAREMETAL_SRCS := start.S + endif + + ifdef BAREMETAL_DIR + ifeq ($(ARCH),arm) + BAREMETAL_GCC := arm-none-eabi-gcc + BAREMETAL_CFLAGS := -mcpu=$(MARCH) -marm -mfloat-abi=$(MABI) + else ifeq ($(ARCH),thumb) + BAREMETAL_GCC := arm-none-eabi-gcc + MFPU ?= fpv5-sp-d16 + BAREMETAL_CFLAGS := -mcpu=$(MARCH) -mthumb -mfloat-abi=hard -mfpu=$(MFPU) + else + BAREMETAL_GCC := riscv64-unknown-elf-gcc + BAREMETAL_CFLAGS := -march=$(MARCH) -mabi=$(MABI) + endif + BAREMETAL_LIBGCC := $(shell $(BAREMETAL_GCC) $(BAREMETAL_CFLAGS) --print-libgcc-file-name) + # picolibc/newlib via --specs=picolibc.specs first, then plain gcc, then multilib fallback + PICOLIBC_MULTIDIR := $(shell $(BAREMETAL_GCC) $(BAREMETAL_CFLAGS) --print-multi-directory 2>/dev/null) + BAREMETAL_LIBC := $(or $(filter /%,$(shell $(BAREMETAL_GCC) --specs=picolibc.specs $(BAREMETAL_CFLAGS) --print-file-name=libc.a 2>/dev/null)),$(filter /%,$(shell $(BAREMETAL_GCC) $(BAREMETAL_CFLAGS) --print-file-name=libc.a 2>/dev/null)),$(wildcard /usr/lib/picolibc/riscv64-unknown-elf/lib/$(PICOLIBC_MULTIDIR)/libc.a)) + BAREMETAL_LIBM := $(or $(filter /%,$(shell $(BAREMETAL_GCC) --specs=picolibc.specs $(BAREMETAL_CFLAGS) --print-file-name=libm.a 2>/dev/null)),$(filter /%,$(shell $(BAREMETAL_GCC) $(BAREMETAL_CFLAGS) --print-file-name=libm.a 2>/dev/null)),$(wildcard /usr/lib/picolibc/riscv64-unknown-elf/lib/$(PICOLIBC_MULTIDIR)/libm.a)) + # Vendor C deps (tlsf, mbedtls shim) include hosted headers (assert.h, + # string.h). A bare cross-gcc (CI's gcc-) only finds those via + # picolibc's specs; a full newlib toolchain has them by default. Add + # the specs only when picolibc is present. Probe for the specs file + # itself, not libc.a -- on the bare CI gcc libc.a is unfindable without + # the specs (the very problem this solves), so a libc.a probe fails + # exactly where it must succeed; --print-file-name=picolibc.specs + # returns an absolute path iff the file is installed. + BAREMETAL_SPECS := $(if $(filter /%,$(shell $(BAREMETAL_GCC) --print-file-name=picolibc.specs 2>/dev/null)),--specs=picolibc.specs) + # Caller adds: -L-T + any vendor blob archives. + # TODO: drop -L--allow-multiple-definition once we migrate intentional + # blob-symbol overrides (currently bl_sleep_check) to -L--wrap=. + # The flag silently hides shadow-stub bugs (see bl808_m0/wifi.d for + # the history of bl_init/bl_pm_ops_register/bl_nap_calculate/bl_reset_evt + # accidental shadows). Re-enable the strict link periodically by + # commenting this out and running clean to catch new shadows. + DFLAGS := $(DFLAGS) -L--gc-sections -L--allow-multiple-definition --link-internally -L-z -Lnorelro -L$(BAREMETAL_LIBC) -L$(BAREMETAL_LIBM) -L$(BAREMETAL_LIBGCC) + + else ifeq ($(ARCH),xtensa) + # Xtensa: emit LLVM bitcode for two-stage codegen via Espressif's llc + # (upstream LLVM Xtensa backend crashes on invoke+landingpad at -O1+). + DFLAGS := $(DFLAGS) --output-bc + else + # No link script wired up (e.g. ESP RISC-V variants without ESP-IDF): + # compile-only object output. + DFLAGS := $(DFLAGS) -c + endif + endif + + ifeq ($(CONFIG),release) + ifeq ($(TINY),1) + DFLAGS := $(DFLAGS) -release --enable-asserts -Oz -enable-inlining + else ifeq ($(ARCH),xtensa) + DFLAGS := $(DFLAGS) -release --enable-asserts -Oz -enable-inlining + else + DFLAGS := $(DFLAGS) -release --enable-asserts -O3 -enable-inlining + endif + else ifdef BAREMETAL_DIR + # Embedded debug/unittest: still optimize to fit in firmware partition + DFLAGS := $(DFLAGS) --enable-asserts -O2 -enable-inlining + else ifeq ($(ARCH),xtensa) + # Xtensa: -Oz to fit in flash; bitcode emission set above + DFLAGS := $(DFLAGS) --enable-asserts -Oz -enable-inlining -d-debug + else + DFLAGS := $(DFLAGS) -g -d-debug + endif + +else ifeq ($(COMPILER),dmd) + DC ?= dmd + + # Strip druntime/phobos, use URT's own object.d. + # Consumers may need to prepend their own -I to shadow druntime's + # __importc_builtins.di (e.g. OpenWatt's third_party/dmd/ for MSVC va_list). + DFLAGS := $(DFLAGS) -defaultlib= -I=$(URT_SRCDIR) + + ifeq ($(ARCH),x86_64) +# DFLAGS := $(DFLAGS) -m64 + else ifeq ($(ARCH),x86) + DFLAGS := $(DFLAGS) -m32 + else + $(error "DMD: unsupported ARCH=$(ARCH) for PLATFORM=$(PLATFORM) (use COMPILER=ldc)") + endif + + ifeq ($(CONFIG),release) + DFLAGS := $(DFLAGS) -release -O -inline + else + DFLAGS := $(DFLAGS) -g -debug + endif +else + $(error "Unknown D compiler: $(COMPILER)") +endif + +# User-specified D version idents, comma-separated (e.g. VERSIONS=Foo,Bar) +ifdef VERSIONS + comma := , + empty := + space := $(empty) $(empty) + DFLAGS := $(DFLAGS) $(addprefix $(VERSION_FLAG),$(subst $(comma),$(space),$(VERSIONS))) +endif + +# Derived build dirs (BUILDNAME/CONFIG resolved above). Consumers inherit these +# and own only TARGETNAME/TARGET. Defined before the vendor.mk import, whose +# compile-rule targets need OBJDIR. +OBJDIR ?= obj/$(BUILDNAME)_$(CONFIG) +TARGETDIR ?= bin/$(BUILDNAME)_$(CONFIG) + +# Bouffalo vendor C deps: paths, $(VENDOR_OBJS), compile rules and -L/-I. +# Consumers just link $(VENDOR_OBJS); the per-blob lists stay private. +include $(URT_ROOT)vendor.mk diff --git a/platforms/bk7231/README.txt b/platforms/bk7231/README.txt new file mode 100644 index 0000000..e10ad6d --- /dev/null +++ b/platforms/bk7231/README.txt @@ -0,0 +1,90 @@ +BK7231 (Beken) -- ARM968E-S @ 120 MHz, ARMv5TE +============================================== + +Two variants in this directory: + + bk7231n Wi-Fi 802.11b/g/n + BLE 5.0 + bk7231t Wi-Fi only (no BLE) + +Both share the same MCU core and most peripherals. SRAM layout differs +(N reserves TCM regions for the BLE stack; T uses full SRAM). They are +NOT interchangeable -- flashing the wrong image will not boot. + +Setup +----- + +Toolchain (Ubuntu 22.04+): + + # D compiler -- LDC with the official upstream build. + curl -fsS https://dlang.org/install.sh | bash -s ldc + source ~/dlang/ldc-*/activate + + # ARM cross-toolchain and picolibc. + sudo apt-get install gcc-arm-none-eabi picolibc-arm-none-eabi + +Flash tool (Python; bundled with OpenBK7231T_App): + + git clone https://github.com/openshwprojects/OpenBK7231T_App + pip install pyserial # only dependency hid_download.py needs + +The flasher is at OpenBK7231T_App/scripts/hid_download.py -- run it +directly, no install step. + +Windows: LDC installer from https://github.com/ldc-developers/ldc/releases; +ARM GNU Toolchain installer from +https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads. + +Build the unittest image +------------------------ + +From the URT root: + + make PLATFORM=bk7231n CONFIG=unittest + make PLATFORM=bk7231t CONFIG=unittest + +Outputs: + + bin/bk7231n_unittest/urt_test.bin + bin/bk7231t_unittest/urt_test.bin + +Toolchain required: ldc, gcc-arm-none-eabi, picolibc-arm-none-eabi. +Linker scripts: bk7231n.ld (192 KB SRAM, BLE TCM carve-out) and +bk7231t.ld (256 KB SRAM, no carve-out). + +This URT-only build does NOT include the Beken SDK -- no Wi-Fi, no BLE, +no SDK-provided UART driver beyond what URT ships. The full OpenWatt +build links against libbeken.a + WiFi/BLE blobs; the URT unittest does +not. The image will boot, run unittests, print results to UART, halt. + +Flash +----- + +Use hid_download_py from the OpenBK7231T_App project: + + git clone https://github.com/openshwprojects/OpenBK7231T_App + cd OpenBK7231T_App/scripts + python hid_download.py -d COM5 -f bin/bk7231n_unittest/urt_test.bin \ + -c bk7231n -a 0x011000 + +(Use bk7231t / -a 0x011000 for the T variant.) + +The bootloader expects the application at offset 0x11000 in flash. Hold +the CEN/RESET button while invoking the tool to enter download mode. + +Console +------- + +UART1 (the SDK calls it "uart_print"), 921600 baud, 8N1. Pins are board- +specific; on most modules UART1 is broken out to a header. The unittest +harness prints results then halts. + +Notes +----- + +* ARMv5TE has no atomic instructions. URT's start.S sets the LLVM + thread-model to "single" so atomics lower to plain loads/stores -- + fine for single-core unittests, NOT safe if you ever bring up + the SDK's RTOS scheduler alongside URT code. +* Vector table lives in the bootloader (no VTOR on ARM968E-S) -- IRQs + must be installed via SDK API in real applications. The URT unittest + runs polled, so this is not exercised. diff --git a/platforms/bk7231/bk7231n.ld b/platforms/bk7231/bk7231n.ld new file mode 100644 index 0000000..7514b29 --- /dev/null +++ b/platforms/bk7231/bk7231n.ld @@ -0,0 +1,140 @@ +/* BK7231N (ARM968E-S, ARMv5TE) linker script + * + * Beken BK7231N -- ARM968E-S @ 120MHz, no FPU, no MMU. + * Wi-Fi 802.11b/g/n + BLE 5.0. + * + * Flash partition table (from BkDriverFlash.c): + * Bootloader: 0x000000, 68KB (0x11000) + * Application: 0x011000, 1156KB (0x121000) + * OTA: 0x12A000, 664KB (0xA6000) + * RF Firmware: 0x1D0000, 4KB + * NET Param: 0x1D1000, 4KB + * + * SRAM layout (OTA build, from SDK bk7231_ota.ld): + * TCM: 0x003F0000, 60KB - 512 (BLE/WiFi critical paths) + * ITCM: 0x003FEE00, 4608 bytes (interrupt entry) + * RAM: 0x00400100, 192KB - 256 (application) + * + * The BLE 5.x stack claims 64KB from general SRAM as TCM regions. + * Application gets 192KB minus the 256-byte reserved header. + * + * Non-OTA: set FLASH LENGTH to 1788K (up to RF firmware at 0x1D0000). + */ + +ENTRY(Reset_Handler) + +EXTERN(_write _read _close _lseek _fstat _isatty _sbrk _exit _kill _getpid) +EXTERN(_Dmodule_ref __errno_location stdout) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00011000, LENGTH = 4M /* TODO: restore to 1156K */ + SRAM (rwx) : ORIGIN = 0x00400100, LENGTH = 192K - 0x100 +} + +SECTIONS +{ + .text : ALIGN(4) + { + KEEP(*(.vector_table)) + *(.text .text.*) + } > FLASH + + .rodata : ALIGN(8) + { + *(.rodata .rodata.*) + } > FLASH + + .eh_frame : ALIGN(8) + { + __eh_frame_start = .; + KEEP(*(.eh_frame)) + KEEP(*(.eh_frame_hdr)) + } > FLASH + + .gcc_except_table : ALIGN(4) + { + *(.gcc_except_table .gcc_except_table.*) + } > FLASH + + .init_array : ALIGN(4) + { + __init_array_start = .; + KEEP(*(.init_array)) + __init_array_end = .; + } > FLASH + + .ARM.exidx : ALIGN(4) + { + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } > FLASH + + .ARM.extab : ALIGN(4) + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + .got : ALIGN(4) + { + _got_load = LOADADDR(.got); + _got_start = .; + *(.got .got.*) + *(.got.plt) + _got_end = .; + } > SRAM AT > FLASH + + .data : ALIGN(4) + { + _data_start = .; + *(.data .data.*) + _data_end = .; + } > SRAM AT > FLASH + + _data_load = LOADADDR(.data); + __ram_load_addr = _data_load; + __ram_data_start__ = _data_start; + __ram_data_end__ = _data_end; + + .tdata : ALIGN(4) + { + _tdata_start = .; + *(.tdata .tdata.*) + _tdata_end = .; + } > SRAM AT > FLASH + + _tdata_load = LOADADDR(.tdata); + + .tbss (NOLOAD) : ALIGN(4) + { + _tbss_start = .; + *(.tbss .tbss.*) + _tbss_end = .; + } > SRAM + + .bss (NOLOAD) : ALIGN(4) + { + __bss_start__ = .; + _bss_start = .; + *(.bss .bss.*) + *(COMMON) + _bss_end = .; + __bss_end__ = .; + } > SRAM + + __heap_start = _bss_end; + __heap_end = ORIGIN(SRAM) + LENGTH(SRAM) - 4K; + + _stack_top = ORIGIN(SRAM) + LENGTH(SRAM); + _stack_low = ORIGIN(SRAM); + __StackTop = _stack_top; + + /DISCARD/ : + { + *(.comment) + *(.note.*) + *(.gnu.hash) + *(.gnu.linkonce.*) + } +} diff --git a/platforms/bk7231/bk7231t.ld b/platforms/bk7231/bk7231t.ld new file mode 100644 index 0000000..0badfc9 --- /dev/null +++ b/platforms/bk7231/bk7231t.ld @@ -0,0 +1,137 @@ +/* BK7231T (ARM968E-S, ARMv5TE) linker script + * + * Beken BK7231T -- ARM968E-S @ 120MHz, no FPU, no MMU. + * Wi-Fi 802.11b/g/n only (no BLE). + * + * Flash partition table (from BkDriverFlash.c): + * Bootloader: 0x000000, 68KB (0x11000) + * Application: 0x011000, 1156KB (0x121000) + * OTA: 0x132000, 600KB (0x96000) + * RF Firmware: 0x1E0000, 4KB + * NET Param: 0x1E1000, 4KB + * + * SRAM layout (OTA build, from SDK bk7231_ota.ld): + * RAM: 0x00400020, 256KB - 32 (full SRAM minus 32-byte header) + * + * No BLE stack means no TCM carve-out -- application gets full 256KB SRAM. + * + * Non-OTA: set FLASH LENGTH to 1812K (up to RF firmware at 0x1E0000). + */ + +ENTRY(Reset_Handler) + +EXTERN(_write _read _close _lseek _fstat _isatty _sbrk _exit _kill _getpid) +EXTERN(_Dmodule_ref __errno_location stdout) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00011000, LENGTH = 1156K + SRAM (rwx) : ORIGIN = 0x00400020, LENGTH = 256K - 0x20 +} + +SECTIONS +{ + .text : ALIGN(4) + { + KEEP(*(.vector_table)) + *(.text .text.*) + } > FLASH + + .rodata : ALIGN(8) + { + *(.rodata .rodata.*) + } > FLASH + + .eh_frame : ALIGN(8) + { + __eh_frame_start = .; + KEEP(*(.eh_frame)) + KEEP(*(.eh_frame_hdr)) + } > FLASH + + .gcc_except_table : ALIGN(4) + { + *(.gcc_except_table .gcc_except_table.*) + } > FLASH + + .init_array : ALIGN(4) + { + __init_array_start = .; + KEEP(*(.init_array)) + __init_array_end = .; + } > FLASH + + .ARM.exidx : ALIGN(4) + { + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } > FLASH + + .ARM.extab : ALIGN(4) + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + .got : ALIGN(4) + { + _got_load = LOADADDR(.got); + _got_start = .; + *(.got .got.*) + *(.got.plt) + _got_end = .; + } > SRAM AT > FLASH + + .data : ALIGN(4) + { + _data_start = .; + *(.data .data.*) + _data_end = .; + } > SRAM AT > FLASH + + _data_load = LOADADDR(.data); + __ram_load_addr = _data_load; + __ram_data_start__ = _data_start; + __ram_data_end__ = _data_end; + + .tdata : ALIGN(4) + { + _tdata_start = .; + *(.tdata .tdata.*) + _tdata_end = .; + } > SRAM AT > FLASH + + _tdata_load = LOADADDR(.tdata); + + .tbss (NOLOAD) : ALIGN(4) + { + _tbss_start = .; + *(.tbss .tbss.*) + _tbss_end = .; + } > SRAM + + .bss (NOLOAD) : ALIGN(4) + { + __bss_start__ = .; + _bss_start = .; + *(.bss .bss.*) + *(COMMON) + _bss_end = .; + __bss_end__ = .; + } > SRAM + + __heap_start = _bss_end; + __heap_end = ORIGIN(SRAM) + LENGTH(SRAM) - 4K; + + _stack_top = ORIGIN(SRAM) + LENGTH(SRAM); + _stack_low = ORIGIN(SRAM); + __StackTop = _stack_top; + + /DISCARD/ : + { + *(.comment) + *(.note.*) + *(.gnu.hash) + *(.gnu.linkonce.*) + } +} diff --git a/platforms/bl618/README.txt b/platforms/bl618/README.txt new file mode 100644 index 0000000..74b12e2 --- /dev/null +++ b/platforms/bl618/README.txt @@ -0,0 +1,74 @@ +BL618 (Bouffalo Lab) -- T-Head E907 RV32IMAFC @ 320 MHz +======================================================== + +Reference board: Sipeed M0P Dock. + +Setup +----- + +Toolchain (Ubuntu 22.04+): + + # D compiler -- LDC with the official upstream build (includes RISC-V). + # The Ubuntu apt 'ldc' package also works but may lag the latest release. + curl -fsS https://dlang.org/install.sh | bash -s ldc + source ~/dlang/ldc-*/activate + + # RISC-V cross-toolchain and picolibc + sudo apt-get install gcc-riscv64-unknown-elf picolibc-riscv64-unknown-elf + +Flash tool (Python, host-side; no target dependency): + + pip install bflb-mcu-tool + +Windows: LDC installer from https://github.com/ldc-developers/ldc/releases. +RISC-V toolchain from the xpack distribution +(https://xpack.github.io/dev-tools/riscv-none-elf-gcc/) -- put its bin +directory on PATH; picolibc is bundled. Or use WSL2 with the Ubuntu +instructions above. + +Build the unittest image +------------------------ + +From the URT root: + + make PLATFORM=bl618 CONFIG=unittest + +Outputs (in bin/bl618_unittest/): + + urt_test ELF with debug symbols + urt_test.bin Raw binary, ready to flash + +Toolchain required: ldc, gcc-riscv64-unknown-elf, picolibc-riscv64-unknown-elf. +Linker script: third_party/urt/platforms/bl618/bl618.ld (uses flash XIP from +0xA0000000, OCRAM at 0x22020000, DTCM at 0x20000000). + +Flash +----- + +Bouffalo's official tool is BLDevCube (GUI) or bflb-mcu-tool (CLI): + + pip install bflb-mcu-tool + bflb-mcu-tool --chipname bl616 --interface uart \ + --port /dev/ttyUSB0 --baudrate 2000000 \ + --firmware bin/bl618_unittest/urt_test.bin \ + --addr 0x0 + +Hold BOOT, tap RESET, release BOOT to enter the ROM bootloader before +running the command. The chipname is "bl616" -- BL618 is a pin/package +variant of the same die, the tool only knows the bl616 family identifier. + +Console +------- + +UART0 on the default pins (GPIO14 TX, GPIO15 RX on the M0P Dock, exposed +on the onboard USB-serial bridge). 2 Mbaud, 8N1. The unittest harness +prints test results to stdout, then halts; tap RESET to re-run. + +Notes +----- + +* The memory map in bl618.ld is from the BL616 reference manual and may + need tweaking for non-Sipeed boards. Verify against the vendor BSP for + your specific carrier. +* No FreeRTOS, no SDK -- bare metal. URT brings its own start.S, syscall + stubs, UART driver, and IRQ table. diff --git a/platforms/bl618/bl618.ld b/platforms/bl618/bl618.ld new file mode 100644 index 0000000..007eff0 --- /dev/null +++ b/platforms/bl618/bl618.ld @@ -0,0 +1,190 @@ +/* BL616/BL618 (T-Head E907 RV32IMAFC) linker script -- Sipeed M0P Dock. + * + * Memory map from the BL616/BL618 datasheet and the vendor bouffalo_sdk + * bl616dk linker template. Cacheability is address-based: bit 30 set = cached + * (0x62.. / 0x63..), clear = non-cache (0x22.. / 0x23..) -- same physical RAM, + * two windows. Code and data run from the cached windows; only DMA buffers use + * the non-cache alias. There is NO TCM on this part (vendor MEMORY{} has none; + * .tcm_* sections fold into main RAM). + * + * FLASH : 0xA0000000 8M XIP, I-cached -- .text/.rodata + * OCRAM : 0x62FC0000 320K cached; top 64K aliased non-cache for DMA + * WRAM : 0x23010000 160K reserved (non-cache) for WiFi DMA + * PSRAM : 0xA8000000 4M M0P pseudo-SRAM (needs bl_psram_init before use) + * HBN : 0x20010000 4K @persist, survives hibernate + * + * D-cache is still disabled in start.S (see its TODO); until it's enabled the + * cached windows are simply accessed uncached. The split below keeps the DMA + * region in separate physical RAM from the cached region, so it stays coherent + * once D-cache is turned on. + */ + +ENTRY(_start) + +EXTERN(_write _read _close _lseek _fstat _isatty _sbrk _exit _kill _getpid) +EXTERN(_Dmodule_ref __errno_location stdout) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0xA0000000, LENGTH = 8M + /* OCRAM is 320K physical. Top 64K is reserved for DMA via the non-cache + * alias (OCRAM_DMA below); the cached window covers the lower 256K. */ + OCRAM (rwx) : ORIGIN = 0x62FC0000, LENGTH = 256K + OCRAM_DMA(rw) : ORIGIN = 0x23000000, LENGTH = 64K + WRAM (rwx) : ORIGIN = 0x23010000, LENGTH = 160K + PSRAM (rwx) : ORIGIN = 0xA8000000, LENGTH = 4M + HBNRAM (rw) : ORIGIN = 0x20010000, LENGTH = 4K +} + +SECTIONS +{ + .text : ALIGN(4) + { + KEEP(*(.text.entry)) + . = ALIGN(4); + *(.text .text.*) + } > FLASH + + .rodata : ALIGN(8) + { + *(.rodata .rodata.*) + } > FLASH + + .eh_frame : ALIGN(8) + { + __eh_frame_start = .; + KEEP(*(.eh_frame)) + KEEP(*(.eh_frame_hdr)) + } > FLASH + + .gcc_except_table : ALIGN(4) + { + *(.gcc_except_table .gcc_except_table.*) + } > FLASH + + .init_array : ALIGN(4) + { + __init_array_start = .; + KEEP(*(.init_array)) + __init_array_end = .; + } > FLASH + + /* @critical -- code that runs from RAM (no ITCM; OCRAM). */ + .ramfunc : ALIGN(4) + { + *(.ramfunc .ramfunc.*) + } > OCRAM AT > FLASH + + _ramfunc_load = LOADADDR(.ramfunc); + _ramfunc_start = ADDR(.ramfunc); + _ramfunc_end = _ramfunc_start + SIZEOF(.ramfunc); + + .got : ALIGN(4) + { + PROVIDE(__global_pointer$ = . + 0x800); + *(.got .got.*) + *(.got.plt) + *(.sdata .sdata.*) + *(.srodata .srodata.*) + } > OCRAM AT > FLASH + + _got_load = LOADADDR(.got); + _got_start = ADDR(.got); + _got_end = _got_start + SIZEOF(.got); + + /* @fast_data. */ + .sram_data : ALIGN(4) + { + *(.sram_data .sram_data.*) + } > OCRAM AT > FLASH + + _sram_data_load = LOADADDR(.sram_data); + _sram_data_start = ADDR(.sram_data); + _sram_data_end = _sram_data_start + SIZEOF(.sram_data); + + /* .data + @bulk_data in cached OCRAM. @bulk_data stays here (not PSRAM) + * until bl_psram_init is wired into boot -- copying into uninitialised + * PSRAM would hang. */ + .data : ALIGN(4) + { + *(.data .data.*) + *(.psram_data .psram_data.*) + } > OCRAM AT > FLASH + + _data_load = LOADADDR(.data); + _data_start = ADDR(.data); + _data_end = _data_start + SIZEOF(.data); + __ram_load_addr = _data_load; + __ram_data_start__ = _data_start; + __ram_data_end__ = _data_end; + + .bss (NOLOAD) : ALIGN(4) + { + __bss_start__ = .; + _bss_start = .; + *(.bss .bss.*) + *(.sbss .sbss.*) + *(COMMON) + _bss_end = .; + __bss_end__ = .; + } > OCRAM + + .tdata : ALIGN(4) + { + *(.tdata .tdata.*) + } > OCRAM AT > FLASH + + _tdata_load = LOADADDR(.tdata); + _tdata_start = ADDR(.tdata); + _tdata_end = _tdata_start + SIZEOF(.tdata); + + .tbss (NOLOAD) : ALIGN(4) + { + _tbss_start = .; + *(.tbss .tbss.*) + _tbss_end = .; + } > OCRAM + + /* @persist -- survives hibernate when VBAT is held. NOLOAD by design. */ + .hbn_ram (NOLOAD) : ALIGN(4) + { + *(.hbn_ram .hbn_ram.*) + } > HBNRAM + + /* Stack at top of cached OCRAM, 16K. */ + _stack_top = ORIGIN(OCRAM) + LENGTH(OCRAM); + _stack_low = _stack_top - 16K; + __StackTop = _stack_top; + + /* OCRAM heap (cached, fast): between TLS and the stack. */ + __ocram_heap_start = _tbss_end; + __ocram_heap_end = _stack_low; + + /* DMA heap (non-cache): the full reserved alias region. */ + __dma_heap_start = ORIGIN(OCRAM_DMA); + __dma_heap_end = ORIGIN(OCRAM_DMA) + LENGTH(OCRAM_DMA); + + /* WRAM reserved for inevitable WiFi use (non-cache, like the M0's WIFIRAM). + * No sections placed; exported for the future WiFi port. */ + __wifi_ram_start = ORIGIN(WRAM); + __wifi_ram_end = ORIGIN(WRAM) + LENGTH(WRAM); + + /* PSRAM reserved (4M). Not an allocator pool yet -- it needs bl_psram_init + * at boot, which the bl618 build doesn't wire. Exported for when it does. */ + __psram_start = ORIGIN(PSRAM); + __psram_end = ORIGIN(PSRAM) + LENGTH(PSRAM); + + ASSERT(__ocram_heap_start <= __ocram_heap_end, "OCRAM overflow: code/data + heap + stack don't fit in cached 256K") + + /* get_sysinfo / dead _sbrk aliases. */ + __heap_start = __ocram_heap_start; + __heap_end = __ocram_heap_end; + + /DISCARD/ : + { + *(.comment) + *(.note.*) + *(.gnu.hash) + *(.gnu.linkonce.*) + } +} diff --git a/platforms/bl618/lib/libmbedtls.a b/platforms/bl618/lib/libmbedtls.a new file mode 100644 index 0000000..4502ad8 Binary files /dev/null and b/platforms/bl618/lib/libmbedtls.a differ diff --git a/platforms/bl808/README.txt b/platforms/bl808/README.txt new file mode 100644 index 0000000..b615895 --- /dev/null +++ b/platforms/bl808/README.txt @@ -0,0 +1,94 @@ +BL808 (Bouffalo Lab) -- multi-core SoC +====================================== + +Two heterogeneous cores in one package: + + D0 T-Head C906 RV64GC @ 480 MHz (application/multimedia) + M0 T-Head E907 RV32IMAFC @ 320 MHz (boot core, MCU domain) + +Reference board: Sipeed M1s Dock. + +There is also an LP core (E902) in the LP domain; URT does not target it. + +Setup +----- + +Toolchain (Ubuntu 22.04+): + + # D compiler -- LDC with the official upstream build. + curl -fsS https://dlang.org/install.sh | bash -s ldc + source ~/dlang/ldc-*/activate + + # RISC-V cross-toolchain and picolibc (covers both D0 RV64 and M0 RV32). + sudo apt-get install gcc-riscv64-unknown-elf picolibc-riscv64-unknown-elf + +Flash tool (Python, host-side): + + pip install bflb-mcu-tool + +The C906 (D0) core uses the T-Head xthead extensions; recent +gcc-riscv64-unknown-elf and LDC both accept the +xthead* mattr flags. +If you see "unsupported mattr" errors, your toolchain is too old -- +upgrade to Ubuntu 24.04 or install LDC 1.36+ from the upstream tarball. + +Windows: LDC installer from https://github.com/ldc-developers/ldc/releases; +xpack RISC-V toolchain (https://xpack.github.io/dev-tools/riscv-none-elf-gcc/); +or use WSL2 with the Ubuntu instructions above. Older xpack builds may +not include the xthead extensions needed for C906; if so, use the +T-Head toolchain from https://www.xrvm.cn/community/download. + +Build the unittest image +------------------------ + +From the URT root: + + make PLATFORM=bl808 PROCESSOR=c906 CONFIG=unittest (D0 image) + make PLATFORM=bl808 PROCESSOR=e907 CONFIG=unittest (M0 image) + +Outputs: + + bin/bl808-d0_unittest/urt_test.bin D0 firmware, loads to PSRAM + bin/bl808-m0_unittest/urt_test.bin M0 firmware, runs XIP from flash + +Linker scripts: bl808_d0.ld (D0 expects to run from PSRAM at 0x50100000; +M0 firmware copies it from flash at boot). bl808_m0.ld (M0 runs XIP from +flash at 0x58000000). + +Boot dependency +--------------- + +D0 cannot boot standalone -- only M0 starts at power-on. Before D0 can +fetch its first instruction, M0 must: + + 1. Initialize clocks and PLLs. + 2. Bring up the flash controller and PSRAM controller. + 3. Copy the D0 firmware from flash (typically 0x580F0000) to PSRAM. + 4. Release D0 from reset by writing its boot-address register. + +This means a D0-only urt_test.bin is a valid build artifact but is NOT +flashable on its own. To run the D0 unittests on hardware, flash both +images together: an M0 firmware that performs the handoff, plus the D0 +image at the address M0 expects. + +Flash +----- + +Same tool as BL618, with chipname=bl808: + + pip install bflb-mcu-tool + bflb-mcu-tool --chipname bl808 --interface uart \ + --port /dev/ttyUSB0 --baudrate 2000000 \ + --firmware bin/bl808-m0_unittest/urt_test.bin \ + --addr 0x58000000 + +For a paired D0+M0 image, flash D0 at 0x580F0000 in the same command +(refer to BLDevCube's partition table editor for the proper layout). + +Hold BOOT, tap RESET, release BOOT to enter ROM bootloader. + +Console +------- + +UART0 on the default pins (exposed via the onboard USB-serial bridge on +the M1s Dock). 2 Mbaud, 8N1. M0 brings up UART early; D0 prints once it +has been released and reaches main(). diff --git a/platforms/bl808/bl808_d0.ld b/platforms/bl808/bl808_d0.ld new file mode 100644 index 0000000..9893f0a --- /dev/null +++ b/platforms/bl808/bl808_d0.ld @@ -0,0 +1,197 @@ +/* BL808 D0 core (T-Head C906 RV64GC) linker script + * + * M0 copies D0 firmware from Flash (0x58100000, D0FW partition) to PSRAM and + * starts D0 executing from PSRAM at 0x50100000. This is NOT XIP -- code runs + * from RAM. + * + * Memory layout (must stay in sync with D0_PSRAM_LOAD_SIZE / D0_IMAGE_FLASH_SIZE + * in driver/bl808_m0/start.d, and with partition.toml D0FW size): + * PSRAM: 0x50100000, 60MB (D0 firmware image + .data + .bss + heap, contiguous) + * SRAM: 0x3eff8000, 64KB (.got + .sram_data fast globals + .tdata/.tbss + stack) + * HBNRAM: 0x20010000, 4KB (survives hibernate if VBAT maintained) + * + * @fast_data globals land in SRAM (fast on-chip, single-cycle); everything + * else lives in PSRAM. + * + * Image layout in PSRAM (file offset order, LMA-tail discipline): + * .text / .rodata / .eh_frame / .gcc_except_table / .init_array (in-place) + * .data (in-place, VMA = LMA) + * .bss range (NOLOAD; objcopy zero-fills the gap) + * .got / .sram_data / .tdata LMAs (copied to SRAM at boot) + * + * After start.S has copied the LMA tail to SRAM, those PSRAM bytes are dead; + * the heap starts at _bss_end and grows over them. start.S finishes all + * section init before any allocator call, so the overlap is safe. + */ + +ENTRY(_start) + +/* Force-link newlib syscall stubs and D runtime symbols + * (otherwise --gc-sections strips them before newlib resolves) */ +EXTERN(_write _read _close _lseek _fstat _isatty _sbrk _exit _kill _getpid) +EXTERN(_Dmodule_ref __errno_location stdout) +EXTERN(socket close poll _accept _recv _recvfrom _sendmsg) +EXTERN(_shutdown _bind _listen _connect setsockopt getsockname getpeername) +EXTERN(getaddrinfo freeaddrinfo) + +MEMORY +{ + PSRAM (rwx) : ORIGIN = 0x50100000, LENGTH = 60M + SRAM (rwx) : ORIGIN = 0x3eff8000, LENGTH = 64K + HBNRAM (rw) : ORIGIN = 0x20010000, LENGTH = 4K +} + +SECTIONS +{ + .text : ALIGN(4) + { + KEEP(*(.text.entry)) + . = ALIGN(4); + *(.text.psram_early) + *(.text .text.*) + } > PSRAM + + .rodata : ALIGN(8) + { + *(.rodata .rodata.*) + } > PSRAM + + /* DWARF exception handling -- required for D throw/catch (fibre abort, etc.). */ + .eh_frame : ALIGN(8) + { + __eh_frame_start = .; + KEEP(*(.eh_frame)) + KEEP(*(.eh_frame_hdr)) + } > PSRAM + + .gcc_except_table : ALIGN(4) + { + *(.gcc_except_table .gcc_except_table.*) + } > PSRAM + + /* Init array -- LDC module info registration functions. Called from start.S before main(). */ + .init_array : ALIGN(8) + { + __init_array_start = .; + KEEP(*(.init_array)) + __init_array_end = .; + } > PSRAM + + /* .data: VMA = LMA in PSRAM. M0 places initialised data via the image load, + * so start.S's .data copy loop becomes a no-op. */ + .data : ALIGN(8) + { + *(.data .data.*) + } > PSRAM + + _data_load = LOADADDR(.data); + _data_start = ADDR(.data); + _data_end = _data_start + SIZEOF(.data); + __ram_load_addr = _data_load; + __ram_data_start__ = _data_start; + __ram_data_end__ = _data_end; + + /* .bss: VMA in PSRAM right after .data. NOLOAD -- no LMA bytes, but the + * binary still spans this range as zeros (objcopy fills the LMA gap to + * the next section). After start.S zeros it, the heap starts here. */ + .bss (NOLOAD) : ALIGN(8) + { + __bss_start__ = .; + _bss_start = .; + *(.bss .bss.*) + *(.sbss .sbss.*) + *(COMMON) + _bss_end = .; + __bss_end__ = .; + } > PSRAM + + /* LMA tail -- SRAM-resident sections placed in PSRAM right after _bss_end. + * start.S copies these to SRAM at boot; the heap then overwrites the + * PSRAM bytes (safe because the copy is done before sys_init / main). */ + + .got : AT(ALIGN(_bss_end, 8)) ALIGN(8) + { + PROVIDE(__global_pointer$ = . + 0x800); + *(.got .got.*) + *(.got.plt) + *(.sdata .sdata.*) + *(.srodata .srodata.*) + } > SRAM + + _got_load = LOADADDR(.got); + _got_start = ADDR(.got); + _got_end = _got_start + SIZEOF(.got); + + /* @fast_data -- frequently-accessed globals in fast on-chip SRAM. */ + .sram_data : AT(ALIGN(_got_load + SIZEOF(.got), 8)) ALIGN(8) + { + *(.sram_data .sram_data.*) + } > SRAM + + _sram_data_load = LOADADDR(.sram_data); + _sram_data_start = ADDR(.sram_data); + _sram_data_end = _sram_data_start + SIZEOF(.sram_data); + + /* TLS: .tdata + .tbss must be VMA-contiguous (they form the TLS template). */ + .tdata : AT(ALIGN(_sram_data_load + SIZEOF(.sram_data), 8)) ALIGN(8) + { + *(.tdata .tdata.*) + } > SRAM + + _tdata_load = LOADADDR(.tdata); + _tdata_start = ADDR(.tdata); + _tdata_end = _tdata_start + SIZEOF(.tdata); + + .tbss (NOLOAD) : ALIGN(8) + { + _tbss_start = .; + *(.tbss .tbss.*) + _tbss_end = .; + } > SRAM + + /* HBN RAM: persistent across hibernate, not initialized by startup */ + .hbn_ram (NOLOAD) : ALIGN(4) + { + *(.hbn_ram) + } > HBNRAM + + /* PSRAM heap pool (default / slow for urt.driver.bl_common.alloc). + * Starts at _bss_end and grows to end of PSRAM. The allocator reclaims + * the LMA-tail bytes after start.S finishes the SRAM copies. */ + __psram_heap_start = _bss_end; + __psram_heap_end = ORIGIN(PSRAM) + LENGTH(PSRAM); + + /* SRAM heap pool (fast / dma / fastest -- D0 has no DTCM). End of .tbss + * up to stack reservation at top of SRAM. */ + __sram_heap_start = _tbss_end; + __sram_heap_end = ORIGIN(SRAM) + LENGTH(SRAM) - 16K; + + /* Stack in fast on-chip SRAM, top 16K reserved. */ + _stack_top = ORIGIN(SRAM) + LENGTH(SRAM); + _stack_low = __sram_heap_end; + __StackTop = _stack_top; + + /* Compatibility aliases for get_sysinfo (urt.system.d). */ + __heap_start = __psram_heap_start; + __heap_end = __psram_heap_end; + + /* Vendor start_load.c expects these symbols for ITCM/DTCM/system RAM + * copy loops. We don't use those sections, so define them as empty. */ + PROVIDE(__itcm_load_addr = 0); + PROVIDE(__tcm_code_start__ = 0); + PROVIDE(__tcm_code_end__ = 0); + PROVIDE(__dtcm_load_addr = 0); + PROVIDE(__tcm_data_start__ = 0); + PROVIDE(__tcm_data_end__ = 0); + PROVIDE(__system_ram_load_addr = 0); + PROVIDE(__system_ram_data_start__ = 0); + PROVIDE(__system_ram_data_end__ = 0); + + /DISCARD/ : + { + *(.comment) + *(.note.*) + *(.gnu.hash) + *(.gnu.linkonce.*) + } +} diff --git a/platforms/bl808/bl808_m0.ld b/platforms/bl808/bl808_m0.ld new file mode 100644 index 0000000..13c4228 --- /dev/null +++ b/platforms/bl808/bl808_m0.ld @@ -0,0 +1,339 @@ +/* BL808 M0 core (T-Head E907 RV32IMAFC) linker script + * + * Memory layout follows vendor M1s_BL808_SDK/components/platform/soc/bl808/ + * bl808_e907_std/bl808_bsp_driver/startup/m0/bl808_flash.ld in spirit: + * keep the vendor split: 48K system SRAM below a 96K WiFi SRAM window. + * + * BootROM responsibilities (before M0 starts): + * - Configure XIP for flash @ 0x58000000 + * - Initialise PSRAM (basic config; M0 calls bl_psram_init for full setup) + * - Set sp to _stack_top + * - Jump to _start + * + * Memory map (M0 view): + * FLASH : 0x58000000 2MB XIP -- .text, .rodata (matches M0 FW partition) + * ITCM : 0x62028000 28KB @critical code (.ramfunc), copied at boot + * DTCM : 0x6202F000 4KB fastest heap pool (uncached, single-cycle) + * HBNRAM : 0x20010000 4KB @persist data (.hbn_ram), survives hibernate + * XRAM : 0x40000000 16K EMI shared RAM for M0/LP/D0 IPC + * OCRAM : 0x22020000 64K @fast_data + ocram heap + stack + * WIFIRAM : 0x22030000 96K vendor .wifibss + WiFi-side @fast_data tail + * PSRAM : 0x50000000 1MB .data + @bulk_data + .bss + .tdata + .tbss + slow heap + * + * OCRAM layout (low to high): + * .sram_data @fast_data; LMA in flash, copied at boot + * ocram heap small DMA-reachable heap, fills gap to stack low + * stack 16K, grows down to the WiFi window boundary + * + * WIFIRAM layout (low to high): + * .wifibss vendor-selected WiFi shared/DMA state + * .got GOT + small data, hot indirect-call surface + * .sram_data_tail WiFi adapter @fast_data, packed into .wifibss slack + * + * Notes: + * - WIFIRAM base 0x22030000 is hardware-fixed: PHY DMA wires are routed + * to this exact bank. Moving the base (even within OCRAM) kills the + * radio. Tested 2026-05-26: same selective list at 0x22024000 = no TX. + * - LENGTH stays 96K. Extending to 160K (matching vendor's `ram_memory`) + * with *libwifi.a:*(COMMON) hangs at wifi_hw_open. Vendor's selective + * curation is load-bearing even though the linker rule looks "all in". + * - GLB_SRAM_CFG3.EM_SEL = 0xFF set by m0_bringup carves the top 64K of + * the WRAM bank as EM (dual-port for WiFi DSP DMA). We don't put any + * sections in EM; libwifi uses it for internal scratch. + * - DTCM cannot be reached by peripheral DMA; the allocator routes + * MemFlags.dma to the OCRAM pool only. + * - HBNRAM survives deep-sleep / HBN if VBAT is maintained. NOLOAD -- + * @persist data is not initialised at boot, that's the point. + * - ITCM stays empty unless the build has @critical functions; the + * copy loop in start.S is a no-op if .ramfunc is zero-length. + * - D0 uses PSRAM from 0x50100000 upward; the 1MB M0 slice (0x50000000 + * .. 0x50100000) stays clear of that. + */ + +ENTRY(_start) + +EXTERN(_write _read _close _lseek _fstat _isatty _exit _kill _getpid) +EXTERN(_Dmodule_ref __errno_location stdout) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x58000000, LENGTH = 2M + ITCM (rx) : ORIGIN = 0x62028000, LENGTH = 28K + DTCM (rwx) : ORIGIN = 0x6202F000, LENGTH = 4K + HBNRAM (rw) : ORIGIN = 0x20010000, LENGTH = 4K + XRAM (rw) : ORIGIN = 0x40000000, LENGTH = 16K + OCRAM (rwx) : ORIGIN = 0x22020000, LENGTH = 64K + /* WIFIRAM base MUST be 0x22030000 (tested 2026-05-26: moving to 0x22024000 + * killed beacon TX -- PHY DMA is physically routed to this bank). LENGTH + * stays 96K with codex's selective COMMON list; expanding to 160K with + * *libwifi.a:*(COMMON) hangs at wifi_hw_open (some COMMON wakes up a + * subsystem that needs host-side init we don't provide). */ + WIFIRAM(rwx) : ORIGIN = 0x22030000, LENGTH = 96K + PSRAM (rwx) : ORIGIN = 0x50000000, LENGTH = 1M +} + +SECTIONS +{ + .text : ALIGN(4) + { + KEEP(*(.text.entry)) + . = ALIGN(4); + *(.text .text.*) + *(.sclock_rlt_code .sclock_rlt_code.*) + } > FLASH + + .rodata : ALIGN(8) + { + *(.rodata .rodata.*) + *(.sclock_rlt_const .sclock_rlt_const.*) + + /* Static WiFi cfg entry table -- the blob (libwifi.a) scans this + * range at boot for static cfg registrations. We register none, + * so start == end and the scan loop runs zero iterations. */ + . = ALIGN(4); + _ld_bl_static_cfg_entry_start = .; + KEEP(*(.wifi.cfg.entry)) + _ld_bl_static_cfg_entry_end = .; + } > FLASH + + .eh_frame : ALIGN(8) + { + __eh_frame_start = .; + KEEP(*(.eh_frame)) + KEEP(*(.eh_frame_hdr)) + } > FLASH + + .gcc_except_table : ALIGN(4) + { + *(.gcc_except_table .gcc_except_table.*) + } > FLASH + + .init_array : ALIGN(4) + { + __init_array_start = .; + KEEP(*(.init_array)) + __init_array_end = .; + } > FLASH + + /* @critical -- code that must execute from internal SRAM. LMA in flash, + * start.S copies to ITCM at boot. ISRs, flash-erase paths, low-latency + * code paths land here. */ + .ramfunc : ALIGN(4) + { + *(.ramfunc .ramfunc.*) + } > ITCM AT > FLASH + + _ramfunc_load = LOADADDR(.ramfunc); + _ramfunc_start = ADDR(.ramfunc); + _ramfunc_end = _ramfunc_start + SIZEOF(.ramfunc); + + .xram (NOLOAD) : ALIGN(4) + { + _xram_start = .; + *(.xram .xram.*) + . = ALIGN(4); + _xram_end = .; + } > XRAM + + /* Vendor WiFi shared/DMA state goes at the fixed 96K WiFi window base. + * The reference SDK does not place every libwifi COMMON here; it places + * only the shared rings/buffers and a few crypto/scan scratch objects. + * Keeping this at 0x22030000 matters because the LMAC/PHY side appears + * to treat this WRAM window specially, not merely "any address in SRAM". */ + .wifibss (NOLOAD) : ALIGN(16) + { + __wifi_bss_start = .; + *(.wifi_ram*) + *ipc_shared.o(COMMON) + *ipc_shared.o(.bss .bss.*) + *sdu_shared.o(COMMON) + *sdu_shared.o(.bss .bss.*) + *hal_desc.o(COMMON) + *hal_desc.o(.bss .bss.*) + *txl_buffer_shared.o(COMMON) + *txl_buffer_shared.o(.bss .bss.*) + *txl_frame_shared.o(COMMON) + *txl_frame_shared.o(.bss .bss.*) + *scan_shared.o(COMMON) + *scan_shared.o(.bss .bss.*) + *scanu_shared.o(COMMON) + *scanu_shared.o(.bss .bss.*) + *mfp_bip.o(COMMON) + *mfp_bip.o(.bss .bss.*) + *me_mic.o(COMMON) + *me_mic.o(.bss .bss.*) + *bl_sta_mgmt_others.o(COMMON) + *bl_sta_mgmt_others.o(.bss .bss.*) + *bl_pmk_mgmt.o(COMMON) + *bl_pmk_mgmt.o(.bss .bss.*) + *bl_pmk_mgmt_internal.o(COMMON) + *bl_pmk_mgmt_internal.o(.bss .bss.*) + *rx_swdesc.o(COMMON) + *rx_swdesc.o(.bss .bss.*) + *rxl_cntrl.o(COMMON) + *rxl_cntrl.o(.bss .bss.*) + *rxl_hwdesc.o(COMMON) + *rxl_hwdesc.o(.bss .bss.*) + *rxu_cntrl.o(COMMON) + *rxu_cntrl.o(.bss .bss.*) + *txl_buffer.o(COMMON) + *txl_buffer.o(.bss .bss.*) + *txl_cfm.o(COMMON) + *txl_cfm.o(.bss .bss.*) + *txl_cntrl.o(COMMON) + *txl_cntrl.o(.bss .bss.*) + *txl_frame.o(COMMON) + *txl_frame.o(.bss .bss.*) + *ipc_emb.o(COMMON) + *ipc_emb.o(.bss .bss.*) + *rc.o(COMMON) + *rc.o(.data .data.* .bss .bss.*) + *chan.o(COMMON) + *chan.o(.data .data.* .bss .bss.*) + *bam.o(COMMON) + *bam.o(.data .data.* .bss .bss.*) + *me.o(COMMON) + *me.o(.data .data.* .bss .bss.*) + *mm.o(COMMON) + *mm.o(.data .data.* .bss .bss.*) + *ke_env.o(COMMON) + *ke_env.o(.data .data.* .bss .bss.*) + *sm.o(COMMON) + *sm.o(.data .data.* .bss .bss.*) + *scan.o(COMMON) + *scan.o(.data .data.* .bss .bss.*) + *apm.o(COMMON) + *apm.o(.data .data.* .bss .bss.*) + *mm_timer.o(COMMON) + *mm_timer.o(.data .data.* .bss .bss.*) + + . = ALIGN(16); + __wifi_bss_end = .; + } > WIFIRAM + + /* GOT + small data. LMA in flash, start.S copies at boot. + * Every indirect call / SDA load hits this region, so keeping it out of + * PSRAM avoids a bus round-trip on the hot path. */ + .got : ALIGN(4) + { + PROVIDE(__global_pointer$ = . + 0x800); + *(.got .got.*) + *(.got.plt) + *(.sdata .sdata.*) + *(.srodata .srodata.*) + } > OCRAM AT > FLASH + + _got_load = LOADADDR(.got); + _got_start = ADDR(.got); + _got_end = _got_start + SIZEOF(.got); + + /* WiFi-side @fast_data packed into the slack after .wifibss. */ + .sram_data_tail : ALIGN(4) + { + *(.sram_data.wifi .sram_data.wifi.*) + } > WIFIRAM AT > FLASH + + _sram_data_tail_load = LOADADDR(.sram_data_tail); + _sram_data_tail_start = ADDR(.sram_data_tail); + _sram_data_tail_end = _sram_data_tail_start + SIZEOF(.sram_data_tail); + + /* @fast_data -- app-side fast data in system SRAM. */ + .sram_data : ALIGN(4) + { + *(.sram_data .sram_data.*) + } > OCRAM AT > FLASH + + _sram_data_load = LOADADDR(.sram_data); + _sram_data_start = ADDR(.sram_data); + _sram_data_end = _sram_data_start + SIZEOF(.sram_data); + + /* .data + @bulk_data both live in PSRAM with the same LMA copy + * treatment; folding them keeps start.S simple. */ + .data : ALIGN(4) + { + *(.data .data.*) + *(.psram_data .psram_data.*) + } > PSRAM AT > FLASH + + _data_load = LOADADDR(.data); + _data_start = ADDR(.data); + _data_end = _data_start + SIZEOF(.data); + __ram_load_addr = _data_load; + __ram_data_start__ = _data_start; + __ram_data_end__ = _data_end; + + .bss (NOLOAD) : ALIGN(4) + { + __bss_start__ = .; + _bss_start = .; + *(.bss .bss.*) + *(.sbss .sbss.*) + *(COMMON) + _bss_end = .; + __bss_end__ = .; + } > PSRAM + + .tdata : ALIGN(4) + { + *(.tdata .tdata.*) + } > PSRAM AT > FLASH + + _tdata_load = LOADADDR(.tdata); + _tdata_start = ADDR(.tdata); + _tdata_end = _tdata_start + SIZEOF(.tdata); + + .tbss (NOLOAD) : ALIGN(4) + { + _tbss_start = .; + *(.tbss .tbss.*) + _tbss_end = .; + } > PSRAM + + /* @persist -- survives hibernate / deep sleep when VBAT is held up. + * NOLOAD: not initialised at boot, prior contents are the point. */ + .hbn_ram (NOLOAD) : ALIGN(4) + { + *(.hbn_ram .hbn_ram.*) + } > HBNRAM + + /* PSRAM heap pool: end of .tbss up to top of slice. */ + __psram_heap_start = _tbss_end; + __psram_heap_end = ORIGIN(PSRAM) + LENGTH(PSRAM); + + /* Stack at the top of OCRAM, immediately below WIFIRAM. + * 4K was tried (vendor-style, DTCM-only) + * and overflowed once the AP path reached the main loop. 16K is the + * smallest size that's stayed safe; revisit with the high-water-mark + * scan before shrinking. */ + _stack_top = ORIGIN(OCRAM) + LENGTH(OCRAM); + _stack_low = _stack_top - 16K; + __StackTop = _stack_top; + + /* OCRAM heap pool: between fast data and stack. DMA-reachable; the + * allocator's MemFlags.dma routes here. */ + __ocram_heap_start = _sram_data_end; + __ocram_heap_end = _stack_low; + + ASSERT(__ocram_heap_start <= __ocram_heap_end, "OCRAM overflow: .xram + .sram_data + heap + stack don't fit in 64K") + ASSERT(_sram_data_tail_end <= ORIGIN(WIFIRAM) + LENGTH(WIFIRAM), "WIFIRAM overflow: .wifibss + .got + .sram_data_tail don't fit in 96K") + + /* DTCM heap pool: full region (no sections placed here). */ + __dtcm_heap_start = ORIGIN(DTCM); + __dtcm_heap_end = ORIGIN(DTCM) + LENGTH(DTCM); + + /* Compatibility aliases: get_sysinfo and the (now dead) bl618 _sbrk + * still reference __heap_start/__heap_end. Point them at the PSRAM + * pool so heap-size reporting reflects the dominant pool. The TLSF + * allocator owns the actual heap; _sbrk is dropped by --gc-sections + * because malloc is satisfied by alloc.d before libc.a is consulted. */ + __heap_start = __psram_heap_start; + __heap_end = __psram_heap_end; + + /DISCARD/ : + { + *(.comment) + *(.note.*) + *(.gnu.hash) + *(.gnu.linkonce.*) + } +} diff --git a/platforms/bl808/lib/libmbedtls.a b/platforms/bl808/lib/libmbedtls.a new file mode 100644 index 0000000..6bd992b Binary files /dev/null and b/platforms/bl808/lib/libmbedtls.a differ diff --git a/platforms/bl808_m0/vendor/psram/include/aon_reg.h b/platforms/bl808_m0/vendor/psram/include/aon_reg.h new file mode 100644 index 0000000..65d46a0 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/aon_reg.h @@ -0,0 +1,2041 @@ +/** + ****************************************************************************** + * @file aon_reg.h + * @version V1.0 + * @date 2021-09-10 + * @brief This file is the description of.IP register + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __AON_REG_H__ +#define __AON_REG_H__ + +#include "bl808.h" + +/* 0x800 : aon */ +#define AON_OFFSET (0x800) +#define AON_RESV AON_RESV +#define AON_RESV_POS (0U) +#define AON_RESV_LEN (8U) +#define AON_RESV_MSK (((1U << AON_RESV_LEN) - 1) << AON_RESV_POS) +#define AON_RESV_UMSK (~(((1U << AON_RESV_LEN) - 1) << AON_RESV_POS)) +#define AON_PU_AON_DC_TBUF AON_PU_AON_DC_TBUF +#define AON_PU_AON_DC_TBUF_POS (12U) +#define AON_PU_AON_DC_TBUF_LEN (1U) +#define AON_PU_AON_DC_TBUF_MSK (((1U << AON_PU_AON_DC_TBUF_LEN) - 1) << AON_PU_AON_DC_TBUF_POS) +#define AON_PU_AON_DC_TBUF_UMSK (~(((1U << AON_PU_AON_DC_TBUF_LEN) - 1) << AON_PU_AON_DC_TBUF_POS)) +#define AON_LDO11_RT_PULLDOWN AON_LDO11_RT_PULLDOWN +#define AON_LDO11_RT_PULLDOWN_POS (20U) +#define AON_LDO11_RT_PULLDOWN_LEN (1U) +#define AON_LDO11_RT_PULLDOWN_MSK (((1U << AON_LDO11_RT_PULLDOWN_LEN) - 1) << AON_LDO11_RT_PULLDOWN_POS) +#define AON_LDO11_RT_PULLDOWN_UMSK (~(((1U << AON_LDO11_RT_PULLDOWN_LEN) - 1) << AON_LDO11_RT_PULLDOWN_POS)) +#define AON_LDO11_RT_PULLDOWN_SEL AON_LDO11_RT_PULLDOWN_SEL +#define AON_LDO11_RT_PULLDOWN_SEL_POS (21U) +#define AON_LDO11_RT_PULLDOWN_SEL_LEN (1U) +#define AON_LDO11_RT_PULLDOWN_SEL_MSK (((1U << AON_LDO11_RT_PULLDOWN_SEL_LEN) - 1) << AON_LDO11_RT_PULLDOWN_SEL_POS) +#define AON_LDO11_RT_PULLDOWN_SEL_UMSK (~(((1U << AON_LDO11_RT_PULLDOWN_SEL_LEN) - 1) << AON_LDO11_RT_PULLDOWN_SEL_POS)) +#define AON_SW_PU_LDO11_RT AON_SW_PU_LDO11_RT +#define AON_SW_PU_LDO11_RT_POS (22U) +#define AON_SW_PU_LDO11_RT_LEN (1U) +#define AON_SW_PU_LDO11_RT_MSK (((1U << AON_SW_PU_LDO11_RT_LEN) - 1) << AON_SW_PU_LDO11_RT_POS) +#define AON_SW_PU_LDO11_RT_UMSK (~(((1U << AON_SW_PU_LDO11_RT_LEN) - 1) << AON_SW_PU_LDO11_RT_POS)) + +/* 0x804 : aon_common */ +#define AON_COMMON_OFFSET (0x804) +#define AON_TMUX_AON AON_TMUX_AON +#define AON_TMUX_AON_POS (0U) +#define AON_TMUX_AON_LEN (3U) +#define AON_TMUX_AON_MSK (((1U << AON_TMUX_AON_LEN) - 1) << AON_TMUX_AON_POS) +#define AON_TMUX_AON_UMSK (~(((1U << AON_TMUX_AON_LEN) - 1) << AON_TMUX_AON_POS)) +#define AON_PMIP_DC_TP_OUT_EN_AON AON_PMIP_DC_TP_OUT_EN_AON +#define AON_PMIP_DC_TP_OUT_EN_AON_POS (3U) +#define AON_PMIP_DC_TP_OUT_EN_AON_LEN (1U) +#define AON_PMIP_DC_TP_OUT_EN_AON_MSK (((1U << AON_PMIP_DC_TP_OUT_EN_AON_LEN) - 1) << AON_PMIP_DC_TP_OUT_EN_AON_POS) +#define AON_PMIP_DC_TP_OUT_EN_AON_UMSK (~(((1U << AON_PMIP_DC_TP_OUT_EN_AON_LEN) - 1) << AON_PMIP_DC_TP_OUT_EN_AON_POS)) +#define AON_TEN_BG_SYS_AON AON_TEN_BG_SYS_AON +#define AON_TEN_BG_SYS_AON_POS (4U) +#define AON_TEN_BG_SYS_AON_LEN (1U) +#define AON_TEN_BG_SYS_AON_MSK (((1U << AON_TEN_BG_SYS_AON_LEN) - 1) << AON_TEN_BG_SYS_AON_POS) +#define AON_TEN_BG_SYS_AON_UMSK (~(((1U << AON_TEN_BG_SYS_AON_LEN) - 1) << AON_TEN_BG_SYS_AON_POS)) +#define AON_TEN_DCDC11_0_AON AON_TEN_DCDC11_0_AON +#define AON_TEN_DCDC11_0_AON_POS (5U) +#define AON_TEN_DCDC11_0_AON_LEN (1U) +#define AON_TEN_DCDC11_0_AON_MSK (((1U << AON_TEN_DCDC11_0_AON_LEN) - 1) << AON_TEN_DCDC11_0_AON_POS) +#define AON_TEN_DCDC11_0_AON_UMSK (~(((1U << AON_TEN_DCDC11_0_AON_LEN) - 1) << AON_TEN_DCDC11_0_AON_POS)) +#define AON_TEN_DCDC11_1_AON AON_TEN_DCDC11_1_AON +#define AON_TEN_DCDC11_1_AON_POS (6U) +#define AON_TEN_DCDC11_1_AON_LEN (1U) +#define AON_TEN_DCDC11_1_AON_MSK (((1U << AON_TEN_DCDC11_1_AON_LEN) - 1) << AON_TEN_DCDC11_1_AON_POS) +#define AON_TEN_DCDC11_1_AON_UMSK (~(((1U << AON_TEN_DCDC11_1_AON_LEN) - 1) << AON_TEN_DCDC11_1_AON_POS)) +#define AON_TEN_DCDC18_0_AON AON_TEN_DCDC18_0_AON +#define AON_TEN_DCDC18_0_AON_POS (7U) +#define AON_TEN_DCDC18_0_AON_LEN (1U) +#define AON_TEN_DCDC18_0_AON_MSK (((1U << AON_TEN_DCDC18_0_AON_LEN) - 1) << AON_TEN_DCDC18_0_AON_POS) +#define AON_TEN_DCDC18_0_AON_UMSK (~(((1U << AON_TEN_DCDC18_0_AON_LEN) - 1) << AON_TEN_DCDC18_0_AON_POS)) +#define AON_TEN_DCDC18_1_AON AON_TEN_DCDC18_1_AON +#define AON_TEN_DCDC18_1_AON_POS (8U) +#define AON_TEN_DCDC18_1_AON_LEN (1U) +#define AON_TEN_DCDC18_1_AON_MSK (((1U << AON_TEN_DCDC18_1_AON_LEN) - 1) << AON_TEN_DCDC18_1_AON_POS) +#define AON_TEN_DCDC18_1_AON_UMSK (~(((1U << AON_TEN_DCDC18_1_AON_LEN) - 1) << AON_TEN_DCDC18_1_AON_POS)) +#define AON_TEN_LDO12UHS AON_TEN_LDO12UHS +#define AON_TEN_LDO12UHS_POS (9U) +#define AON_TEN_LDO12UHS_LEN (1U) +#define AON_TEN_LDO12UHS_MSK (((1U << AON_TEN_LDO12UHS_LEN) - 1) << AON_TEN_LDO12UHS_POS) +#define AON_TEN_LDO12UHS_UMSK (~(((1U << AON_TEN_LDO12UHS_LEN) - 1) << AON_TEN_LDO12UHS_POS)) +#define AON_TEN_LDO18FLASH AON_TEN_LDO18FLASH +#define AON_TEN_LDO18FLASH_POS (10U) +#define AON_TEN_LDO18FLASH_LEN (1U) +#define AON_TEN_LDO18FLASH_MSK (((1U << AON_TEN_LDO18FLASH_LEN) - 1) << AON_TEN_LDO18FLASH_POS) +#define AON_TEN_LDO18FLASH_UMSK (~(((1U << AON_TEN_LDO18FLASH_LEN) - 1) << AON_TEN_LDO18FLASH_POS)) +#define AON_TEN_LDO15CIS AON_TEN_LDO15CIS +#define AON_TEN_LDO15CIS_POS (11U) +#define AON_TEN_LDO15CIS_LEN (1U) +#define AON_TEN_LDO15CIS_MSK (((1U << AON_TEN_LDO15CIS_LEN) - 1) << AON_TEN_LDO15CIS_POS) +#define AON_TEN_LDO15CIS_UMSK (~(((1U << AON_TEN_LDO15CIS_LEN) - 1) << AON_TEN_LDO15CIS_POS)) +#define AON_TEN_LDO18IO_AON AON_TEN_LDO18IO_AON +#define AON_TEN_LDO18IO_AON_POS (12U) +#define AON_TEN_LDO18IO_AON_LEN (1U) +#define AON_TEN_LDO18IO_AON_MSK (((1U << AON_TEN_LDO18IO_AON_LEN) - 1) << AON_TEN_LDO18IO_AON_POS) +#define AON_TEN_LDO18IO_AON_UMSK (~(((1U << AON_TEN_LDO18IO_AON_LEN) - 1) << AON_TEN_LDO18IO_AON_POS)) +#define AON_TEN_LDO28CIS AON_TEN_LDO28CIS +#define AON_TEN_LDO28CIS_POS (13U) +#define AON_TEN_LDO28CIS_LEN (1U) +#define AON_TEN_LDO28CIS_MSK (((1U << AON_TEN_LDO28CIS_LEN) - 1) << AON_TEN_LDO28CIS_POS) +#define AON_TEN_LDO28CIS_UMSK (~(((1U << AON_TEN_LDO28CIS_LEN) - 1) << AON_TEN_LDO28CIS_POS)) +#define AON_TEN_RC32M AON_TEN_RC32M +#define AON_TEN_RC32M_POS (14U) +#define AON_TEN_RC32M_LEN (1U) +#define AON_TEN_RC32M_MSK (((1U << AON_TEN_RC32M_LEN) - 1) << AON_TEN_RC32M_POS) +#define AON_TEN_RC32M_UMSK (~(((1U << AON_TEN_RC32M_LEN) - 1) << AON_TEN_RC32M_POS)) +#define AON_TEN_LDO15RF_AON AON_TEN_LDO15RF_AON +#define AON_TEN_LDO15RF_AON_POS (16U) +#define AON_TEN_LDO15RF_AON_LEN (1U) +#define AON_TEN_LDO15RF_AON_MSK (((1U << AON_TEN_LDO15RF_AON_LEN) - 1) << AON_TEN_LDO15RF_AON_POS) +#define AON_TEN_LDO15RF_AON_UMSK (~(((1U << AON_TEN_LDO15RF_AON_LEN) - 1) << AON_TEN_LDO15RF_AON_POS)) +#define AON_TEN_XTAL_AON AON_TEN_XTAL_AON +#define AON_TEN_XTAL_AON_POS (17U) +#define AON_TEN_XTAL_AON_LEN (1U) +#define AON_TEN_XTAL_AON_MSK (((1U << AON_TEN_XTAL_AON_LEN) - 1) << AON_TEN_XTAL_AON_POS) +#define AON_TEN_XTAL_AON_UMSK (~(((1U << AON_TEN_XTAL_AON_LEN) - 1) << AON_TEN_XTAL_AON_POS)) +#define AON_DTEN_XTAL_AON AON_DTEN_XTAL_AON +#define AON_DTEN_XTAL_AON_POS (18U) +#define AON_DTEN_XTAL_AON_LEN (1U) +#define AON_DTEN_XTAL_AON_MSK (((1U << AON_DTEN_XTAL_AON_LEN) - 1) << AON_DTEN_XTAL_AON_POS) +#define AON_DTEN_XTAL_AON_UMSK (~(((1U << AON_DTEN_XTAL_AON_LEN) - 1) << AON_DTEN_XTAL_AON_POS)) +#define AON_TEN_MBG_AON AON_TEN_MBG_AON +#define AON_TEN_MBG_AON_POS (19U) +#define AON_TEN_MBG_AON_LEN (1U) +#define AON_TEN_MBG_AON_MSK (((1U << AON_TEN_MBG_AON_LEN) - 1) << AON_TEN_MBG_AON_POS) +#define AON_TEN_MBG_AON_UMSK (~(((1U << AON_TEN_MBG_AON_LEN) - 1) << AON_TEN_MBG_AON_POS)) +#define AON_TEN_CIP_MISC_AON AON_TEN_CIP_MISC_AON +#define AON_TEN_CIP_MISC_AON_POS (20U) +#define AON_TEN_CIP_MISC_AON_LEN (1U) +#define AON_TEN_CIP_MISC_AON_MSK (((1U << AON_TEN_CIP_MISC_AON_LEN) - 1) << AON_TEN_CIP_MISC_AON_POS) +#define AON_TEN_CIP_MISC_AON_UMSK (~(((1U << AON_TEN_CIP_MISC_AON_LEN) - 1) << AON_TEN_CIP_MISC_AON_POS)) +#define AON_TEN_AON AON_TEN_AON +#define AON_TEN_AON_POS (21U) +#define AON_TEN_AON_LEN (1U) +#define AON_TEN_AON_MSK (((1U << AON_TEN_AON_LEN) - 1) << AON_TEN_AON_POS) +#define AON_TEN_AON_UMSK (~(((1U << AON_TEN_AON_LEN) - 1) << AON_TEN_AON_POS)) + +/* 0x808 : aon_misc */ +#define AON_MISC_OFFSET (0x808) +#define AON_SW_SOC_EN_AON AON_SW_SOC_EN_AON +#define AON_SW_SOC_EN_AON_POS (0U) +#define AON_SW_SOC_EN_AON_LEN (1U) +#define AON_SW_SOC_EN_AON_MSK (((1U << AON_SW_SOC_EN_AON_LEN) - 1) << AON_SW_SOC_EN_AON_POS) +#define AON_SW_SOC_EN_AON_UMSK (~(((1U << AON_SW_SOC_EN_AON_LEN) - 1) << AON_SW_SOC_EN_AON_POS)) +#define AON_SW_WB_EN_AON AON_SW_WB_EN_AON +#define AON_SW_WB_EN_AON_POS (1U) +#define AON_SW_WB_EN_AON_LEN (1U) +#define AON_SW_WB_EN_AON_MSK (((1U << AON_SW_WB_EN_AON_LEN) - 1) << AON_SW_WB_EN_AON_POS) +#define AON_SW_WB_EN_AON_UMSK (~(((1U << AON_SW_WB_EN_AON_LEN) - 1) << AON_SW_WB_EN_AON_POS)) + +/* 0x810 : bg_sys_top */ +#define AON_BG_SYS_TOP_OFFSET (0x810) +#define AON_PU_BG_SYS_AON AON_PU_BG_SYS_AON +#define AON_PU_BG_SYS_AON_POS (0U) +#define AON_PU_BG_SYS_AON_LEN (1U) +#define AON_PU_BG_SYS_AON_MSK (((1U << AON_PU_BG_SYS_AON_LEN) - 1) << AON_PU_BG_SYS_AON_POS) +#define AON_PU_BG_SYS_AON_UMSK (~(((1U << AON_PU_BG_SYS_AON_LEN) - 1) << AON_PU_BG_SYS_AON_POS)) +#define AON_ISTART_CTRL_AON AON_ISTART_CTRL_AON +#define AON_ISTART_CTRL_AON_POS (1U) +#define AON_ISTART_CTRL_AON_LEN (1U) +#define AON_ISTART_CTRL_AON_MSK (((1U << AON_ISTART_CTRL_AON_LEN) - 1) << AON_ISTART_CTRL_AON_POS) +#define AON_ISTART_CTRL_AON_UMSK (~(((1U << AON_ISTART_CTRL_AON_LEN) - 1) << AON_ISTART_CTRL_AON_POS)) + +/* 0x814 : dcdc_top_0 */ +#define AON_DCDC_TOP_0_OFFSET (0x814) +#define AON_DCDC11_SSTART_TIME_AON AON_DCDC11_SSTART_TIME_AON +#define AON_DCDC11_SSTART_TIME_AON_POS (0U) +#define AON_DCDC11_SSTART_TIME_AON_LEN (2U) +#define AON_DCDC11_SSTART_TIME_AON_MSK (((1U << AON_DCDC11_SSTART_TIME_AON_LEN) - 1) << AON_DCDC11_SSTART_TIME_AON_POS) +#define AON_DCDC11_SSTART_TIME_AON_UMSK (~(((1U << AON_DCDC11_SSTART_TIME_AON_LEN) - 1) << AON_DCDC11_SSTART_TIME_AON_POS)) +#define AON_DCDC11_STBY_LP_CUR_AON AON_DCDC11_STBY_LP_CUR_AON +#define AON_DCDC11_STBY_LP_CUR_AON_POS (4U) +#define AON_DCDC11_STBY_LP_CUR_AON_LEN (3U) +#define AON_DCDC11_STBY_LP_CUR_AON_MSK (((1U << AON_DCDC11_STBY_LP_CUR_AON_LEN) - 1) << AON_DCDC11_STBY_LP_CUR_AON_POS) +#define AON_DCDC11_STBY_LP_CUR_AON_UMSK (~(((1U << AON_DCDC11_STBY_LP_CUR_AON_LEN) - 1) << AON_DCDC11_STBY_LP_CUR_AON_POS)) +#define AON_DCDC11_VC_CLAMP_VTH_AON AON_DCDC11_VC_CLAMP_VTH_AON +#define AON_DCDC11_VC_CLAMP_VTH_AON_POS (8U) +#define AON_DCDC11_VC_CLAMP_VTH_AON_LEN (3U) +#define AON_DCDC11_VC_CLAMP_VTH_AON_MSK (((1U << AON_DCDC11_VC_CLAMP_VTH_AON_LEN) - 1) << AON_DCDC11_VC_CLAMP_VTH_AON_POS) +#define AON_DCDC11_VC_CLAMP_VTH_AON_UMSK (~(((1U << AON_DCDC11_VC_CLAMP_VTH_AON_LEN) - 1) << AON_DCDC11_VC_CLAMP_VTH_AON_POS)) +#define AON_DCDC11_VOUT_SEL_AON AON_DCDC11_VOUT_SEL_AON +#define AON_DCDC11_VOUT_SEL_AON_POS (11U) +#define AON_DCDC11_VOUT_SEL_AON_LEN (5U) +#define AON_DCDC11_VOUT_SEL_AON_MSK (((1U << AON_DCDC11_VOUT_SEL_AON_LEN) - 1) << AON_DCDC11_VOUT_SEL_AON_POS) +#define AON_DCDC11_VOUT_SEL_AON_UMSK (~(((1U << AON_DCDC11_VOUT_SEL_AON_LEN) - 1) << AON_DCDC11_VOUT_SEL_AON_POS)) +#define AON_DCDC11_VOUT_TRIM_AON AON_DCDC11_VOUT_TRIM_AON +#define AON_DCDC11_VOUT_TRIM_AON_POS (16U) +#define AON_DCDC11_VOUT_TRIM_AON_LEN (4U) +#define AON_DCDC11_VOUT_TRIM_AON_MSK (((1U << AON_DCDC11_VOUT_TRIM_AON_LEN) - 1) << AON_DCDC11_VOUT_TRIM_AON_POS) +#define AON_DCDC11_VOUT_TRIM_AON_UMSK (~(((1U << AON_DCDC11_VOUT_TRIM_AON_LEN) - 1) << AON_DCDC11_VOUT_TRIM_AON_POS)) +#define AON_DCDC11_VPFM_AON AON_DCDC11_VPFM_AON +#define AON_DCDC11_VPFM_AON_POS (20U) +#define AON_DCDC11_VPFM_AON_LEN (4U) +#define AON_DCDC11_VPFM_AON_MSK (((1U << AON_DCDC11_VPFM_AON_LEN) - 1) << AON_DCDC11_VPFM_AON_POS) +#define AON_DCDC11_VPFM_AON_UMSK (~(((1U << AON_DCDC11_VPFM_AON_LEN) - 1) << AON_DCDC11_VPFM_AON_POS)) +#define AON_DCDC11_ZVS_TD_OPT_AON AON_DCDC11_ZVS_TD_OPT_AON +#define AON_DCDC11_ZVS_TD_OPT_AON_POS (24U) +#define AON_DCDC11_ZVS_TD_OPT_AON_LEN (3U) +#define AON_DCDC11_ZVS_TD_OPT_AON_MSK (((1U << AON_DCDC11_ZVS_TD_OPT_AON_LEN) - 1) << AON_DCDC11_ZVS_TD_OPT_AON_POS) +#define AON_DCDC11_ZVS_TD_OPT_AON_UMSK (~(((1U << AON_DCDC11_ZVS_TD_OPT_AON_LEN) - 1) << AON_DCDC11_ZVS_TD_OPT_AON_POS)) +#define AON_DCDC11_VSTBY_AON AON_DCDC11_VSTBY_AON +#define AON_DCDC11_VSTBY_AON_POS (28U) +#define AON_DCDC11_VSTBY_AON_LEN (2U) +#define AON_DCDC11_VSTBY_AON_MSK (((1U << AON_DCDC11_VSTBY_AON_LEN) - 1) << AON_DCDC11_VSTBY_AON_POS) +#define AON_DCDC11_VSTBY_AON_UMSK (~(((1U << AON_DCDC11_VSTBY_AON_LEN) - 1) << AON_DCDC11_VSTBY_AON_POS)) + +/* 0x818 : dcdc_top_1 */ +#define AON_DCDC_TOP_1_OFFSET (0x818) +#define AON_DCDC11_NONOVERLAP_TD_AON AON_DCDC11_NONOVERLAP_TD_AON +#define AON_DCDC11_NONOVERLAP_TD_AON_POS (0U) +#define AON_DCDC11_NONOVERLAP_TD_AON_LEN (5U) +#define AON_DCDC11_NONOVERLAP_TD_AON_MSK (((1U << AON_DCDC11_NONOVERLAP_TD_AON_LEN) - 1) << AON_DCDC11_NONOVERLAP_TD_AON_POS) +#define AON_DCDC11_NONOVERLAP_TD_AON_UMSK (~(((1U << AON_DCDC11_NONOVERLAP_TD_AON_LEN) - 1) << AON_DCDC11_NONOVERLAP_TD_AON_POS)) +#define AON_DCDC11_OCP_OUT_AON AON_DCDC11_OCP_OUT_AON +#define AON_DCDC11_OCP_OUT_AON_POS (5U) +#define AON_DCDC11_OCP_OUT_AON_LEN (1U) +#define AON_DCDC11_OCP_OUT_AON_MSK (((1U << AON_DCDC11_OCP_OUT_AON_LEN) - 1) << AON_DCDC11_OCP_OUT_AON_POS) +#define AON_DCDC11_OCP_OUT_AON_UMSK (~(((1U << AON_DCDC11_OCP_OUT_AON_LEN) - 1) << AON_DCDC11_OCP_OUT_AON_POS)) +#define AON_DCDC11_OCP_RST_AON AON_DCDC11_OCP_RST_AON +#define AON_DCDC11_OCP_RST_AON_POS (6U) +#define AON_DCDC11_OCP_RST_AON_LEN (1U) +#define AON_DCDC11_OCP_RST_AON_MSK (((1U << AON_DCDC11_OCP_RST_AON_LEN) - 1) << AON_DCDC11_OCP_RST_AON_POS) +#define AON_DCDC11_OCP_RST_AON_UMSK (~(((1U << AON_DCDC11_OCP_RST_AON_LEN) - 1) << AON_DCDC11_OCP_RST_AON_POS)) +#define AON_DCDC11_OCP_VTH_AON AON_DCDC11_OCP_VTH_AON +#define AON_DCDC11_OCP_VTH_AON_POS (8U) +#define AON_DCDC11_OCP_VTH_AON_LEN (3U) +#define AON_DCDC11_OCP_VTH_AON_MSK (((1U << AON_DCDC11_OCP_VTH_AON_LEN) - 1) << AON_DCDC11_OCP_VTH_AON_POS) +#define AON_DCDC11_OCP_VTH_AON_UMSK (~(((1U << AON_DCDC11_OCP_VTH_AON_LEN) - 1) << AON_DCDC11_OCP_VTH_AON_POS)) +#define AON_DCDC11_OSC_2M_MODE_AON AON_DCDC11_OSC_2M_MODE_AON +#define AON_DCDC11_OSC_2M_MODE_AON_POS (11U) +#define AON_DCDC11_OSC_2M_MODE_AON_LEN (1U) +#define AON_DCDC11_OSC_2M_MODE_AON_MSK (((1U << AON_DCDC11_OSC_2M_MODE_AON_LEN) - 1) << AON_DCDC11_OSC_2M_MODE_AON_POS) +#define AON_DCDC11_OSC_2M_MODE_AON_UMSK (~(((1U << AON_DCDC11_OSC_2M_MODE_AON_LEN) - 1) << AON_DCDC11_OSC_2M_MODE_AON_POS)) +#define AON_DCDC11_OSC_FREQ_TRIM_AON AON_DCDC11_OSC_FREQ_TRIM_AON +#define AON_DCDC11_OSC_FREQ_TRIM_AON_POS (12U) +#define AON_DCDC11_OSC_FREQ_TRIM_AON_LEN (4U) +#define AON_DCDC11_OSC_FREQ_TRIM_AON_MSK (((1U << AON_DCDC11_OSC_FREQ_TRIM_AON_LEN) - 1) << AON_DCDC11_OSC_FREQ_TRIM_AON_POS) +#define AON_DCDC11_OSC_FREQ_TRIM_AON_UMSK (~(((1U << AON_DCDC11_OSC_FREQ_TRIM_AON_LEN) - 1) << AON_DCDC11_OSC_FREQ_TRIM_AON_POS)) +#define AON_DCDC11_PULLDOWN_AON AON_DCDC11_PULLDOWN_AON +#define AON_DCDC11_PULLDOWN_AON_POS (16U) +#define AON_DCDC11_PULLDOWN_AON_LEN (1U) +#define AON_DCDC11_PULLDOWN_AON_MSK (((1U << AON_DCDC11_PULLDOWN_AON_LEN) - 1) << AON_DCDC11_PULLDOWN_AON_POS) +#define AON_DCDC11_PULLDOWN_AON_UMSK (~(((1U << AON_DCDC11_PULLDOWN_AON_LEN) - 1) << AON_DCDC11_PULLDOWN_AON_POS)) +#define AON_DCDC11_RC_SEL_AON AON_DCDC11_RC_SEL_AON +#define AON_DCDC11_RC_SEL_AON_POS (20U) +#define AON_DCDC11_RC_SEL_AON_LEN (4U) +#define AON_DCDC11_RC_SEL_AON_MSK (((1U << AON_DCDC11_RC_SEL_AON_LEN) - 1) << AON_DCDC11_RC_SEL_AON_POS) +#define AON_DCDC11_RC_SEL_AON_UMSK (~(((1U << AON_DCDC11_RC_SEL_AON_LEN) - 1) << AON_DCDC11_RC_SEL_AON_POS)) +#define AON_DCDC11_RDY_AON AON_DCDC11_RDY_AON +#define AON_DCDC11_RDY_AON_POS (24U) +#define AON_DCDC11_RDY_AON_LEN (1U) +#define AON_DCDC11_RDY_AON_MSK (((1U << AON_DCDC11_RDY_AON_LEN) - 1) << AON_DCDC11_RDY_AON_POS) +#define AON_DCDC11_RDY_AON_UMSK (~(((1U << AON_DCDC11_RDY_AON_LEN) - 1) << AON_DCDC11_RDY_AON_POS)) +#define AON_DCDC11_SLOPE_CURR_SEL_AON AON_DCDC11_SLOPE_CURR_SEL_AON +#define AON_DCDC11_SLOPE_CURR_SEL_AON_POS (26U) +#define AON_DCDC11_SLOPE_CURR_SEL_AON_LEN (5U) +#define AON_DCDC11_SLOPE_CURR_SEL_AON_MSK (((1U << AON_DCDC11_SLOPE_CURR_SEL_AON_LEN) - 1) << AON_DCDC11_SLOPE_CURR_SEL_AON_POS) +#define AON_DCDC11_SLOPE_CURR_SEL_AON_UMSK (~(((1U << AON_DCDC11_SLOPE_CURR_SEL_AON_LEN) - 1) << AON_DCDC11_SLOPE_CURR_SEL_AON_POS)) + +/* 0x81C : ldo11soc_and_dctest */ +#define AON_LDO11SOC_AND_DCTEST_OFFSET (0x81C) +#define AON_DCDC11_CFB_SEL_AON AON_DCDC11_CFB_SEL_AON +#define AON_DCDC11_CFB_SEL_AON_POS (4U) +#define AON_DCDC11_CFB_SEL_AON_LEN (4U) +#define AON_DCDC11_CFB_SEL_AON_MSK (((1U << AON_DCDC11_CFB_SEL_AON_LEN) - 1) << AON_DCDC11_CFB_SEL_AON_POS) +#define AON_DCDC11_CFB_SEL_AON_UMSK (~(((1U << AON_DCDC11_CFB_SEL_AON_LEN) - 1) << AON_DCDC11_CFB_SEL_AON_POS)) +#define AON_DCDC11_CHF_SEL_AON AON_DCDC11_CHF_SEL_AON +#define AON_DCDC11_CHF_SEL_AON_POS (8U) +#define AON_DCDC11_CHF_SEL_AON_LEN (4U) +#define AON_DCDC11_CHF_SEL_AON_MSK (((1U << AON_DCDC11_CHF_SEL_AON_LEN) - 1) << AON_DCDC11_CHF_SEL_AON_POS) +#define AON_DCDC11_CHF_SEL_AON_UMSK (~(((1U << AON_DCDC11_CHF_SEL_AON_LEN) - 1) << AON_DCDC11_CHF_SEL_AON_POS)) +#define AON_DCDC11_COMP_GM_SEL_AON AON_DCDC11_COMP_GM_SEL_AON +#define AON_DCDC11_COMP_GM_SEL_AON_POS (12U) +#define AON_DCDC11_COMP_GM_SEL_AON_LEN (3U) +#define AON_DCDC11_COMP_GM_SEL_AON_MSK (((1U << AON_DCDC11_COMP_GM_SEL_AON_LEN) - 1) << AON_DCDC11_COMP_GM_SEL_AON_POS) +#define AON_DCDC11_COMP_GM_SEL_AON_UMSK (~(((1U << AON_DCDC11_COMP_GM_SEL_AON_LEN) - 1) << AON_DCDC11_COMP_GM_SEL_AON_POS)) +#define AON_DCDC11_CS_DELAY_AON AON_DCDC11_CS_DELAY_AON +#define AON_DCDC11_CS_DELAY_AON_POS (16U) +#define AON_DCDC11_CS_DELAY_AON_LEN (3U) +#define AON_DCDC11_CS_DELAY_AON_MSK (((1U << AON_DCDC11_CS_DELAY_AON_LEN) - 1) << AON_DCDC11_CS_DELAY_AON_POS) +#define AON_DCDC11_CS_DELAY_AON_UMSK (~(((1U << AON_DCDC11_CS_DELAY_AON_LEN) - 1) << AON_DCDC11_CS_DELAY_AON_POS)) +#define AON_DCDC11_DRV_SR_AON AON_DCDC11_DRV_SR_AON +#define AON_DCDC11_DRV_SR_AON_POS (20U) +#define AON_DCDC11_DRV_SR_AON_LEN (2U) +#define AON_DCDC11_DRV_SR_AON_MSK (((1U << AON_DCDC11_DRV_SR_AON_LEN) - 1) << AON_DCDC11_DRV_SR_AON_POS) +#define AON_DCDC11_DRV_SR_AON_UMSK (~(((1U << AON_DCDC11_DRV_SR_AON_LEN) - 1) << AON_DCDC11_DRV_SR_AON_POS)) +#define AON_DCDC11_EN_ANTIRING_AON AON_DCDC11_EN_ANTIRING_AON +#define AON_DCDC11_EN_ANTIRING_AON_POS (22U) +#define AON_DCDC11_EN_ANTIRING_AON_LEN (1U) +#define AON_DCDC11_EN_ANTIRING_AON_MSK (((1U << AON_DCDC11_EN_ANTIRING_AON_LEN) - 1) << AON_DCDC11_EN_ANTIRING_AON_POS) +#define AON_DCDC11_EN_ANTIRING_AON_UMSK (~(((1U << AON_DCDC11_EN_ANTIRING_AON_LEN) - 1) << AON_DCDC11_EN_ANTIRING_AON_POS)) +#define AON_DCDC11_EN_OSC_INHIBIT_T2_AON AON_DCDC11_EN_OSC_INHIBIT_T2_AON +#define AON_DCDC11_EN_OSC_INHIBIT_T2_AON_POS (23U) +#define AON_DCDC11_EN_OSC_INHIBIT_T2_AON_LEN (1U) +#define AON_DCDC11_EN_OSC_INHIBIT_T2_AON_MSK (((1U << AON_DCDC11_EN_OSC_INHIBIT_T2_AON_LEN) - 1) << AON_DCDC11_EN_OSC_INHIBIT_T2_AON_POS) +#define AON_DCDC11_EN_OSC_INHIBIT_T2_AON_UMSK (~(((1U << AON_DCDC11_EN_OSC_INHIBIT_T2_AON_LEN) - 1) << AON_DCDC11_EN_OSC_INHIBIT_T2_AON_POS)) +#define AON_DCDC11_EN_SLOW_OSC_AON AON_DCDC11_EN_SLOW_OSC_AON +#define AON_DCDC11_EN_SLOW_OSC_AON_POS (24U) +#define AON_DCDC11_EN_SLOW_OSC_AON_LEN (1U) +#define AON_DCDC11_EN_SLOW_OSC_AON_MSK (((1U << AON_DCDC11_EN_SLOW_OSC_AON_LEN) - 1) << AON_DCDC11_EN_SLOW_OSC_AON_POS) +#define AON_DCDC11_EN_SLOW_OSC_AON_UMSK (~(((1U << AON_DCDC11_EN_SLOW_OSC_AON_LEN) - 1) << AON_DCDC11_EN_SLOW_OSC_AON_POS)) +#define AON_DCDC11_EN_STBY_LP_AON AON_DCDC11_EN_STBY_LP_AON +#define AON_DCDC11_EN_STBY_LP_AON_POS (25U) +#define AON_DCDC11_EN_STBY_LP_AON_LEN (1U) +#define AON_DCDC11_EN_STBY_LP_AON_MSK (((1U << AON_DCDC11_EN_STBY_LP_AON_LEN) - 1) << AON_DCDC11_EN_STBY_LP_AON_POS) +#define AON_DCDC11_EN_STBY_LP_AON_UMSK (~(((1U << AON_DCDC11_EN_STBY_LP_AON_LEN) - 1) << AON_DCDC11_EN_STBY_LP_AON_POS)) +#define AON_DCDC11_EN_STOP_OSC_AON AON_DCDC11_EN_STOP_OSC_AON +#define AON_DCDC11_EN_STOP_OSC_AON_POS (26U) +#define AON_DCDC11_EN_STOP_OSC_AON_LEN (1U) +#define AON_DCDC11_EN_STOP_OSC_AON_MSK (((1U << AON_DCDC11_EN_STOP_OSC_AON_LEN) - 1) << AON_DCDC11_EN_STOP_OSC_AON_POS) +#define AON_DCDC11_EN_STOP_OSC_AON_UMSK (~(((1U << AON_DCDC11_EN_STOP_OSC_AON_LEN) - 1) << AON_DCDC11_EN_STOP_OSC_AON_POS)) +#define AON_DCDC11_FORCE_EN_CS_ZVS_AON AON_DCDC11_FORCE_EN_CS_ZVS_AON +#define AON_DCDC11_FORCE_EN_CS_ZVS_AON_POS (27U) +#define AON_DCDC11_FORCE_EN_CS_ZVS_AON_LEN (1U) +#define AON_DCDC11_FORCE_EN_CS_ZVS_AON_MSK (((1U << AON_DCDC11_FORCE_EN_CS_ZVS_AON_LEN) - 1) << AON_DCDC11_FORCE_EN_CS_ZVS_AON_POS) +#define AON_DCDC11_FORCE_EN_CS_ZVS_AON_UMSK (~(((1U << AON_DCDC11_FORCE_EN_CS_ZVS_AON_LEN) - 1) << AON_DCDC11_FORCE_EN_CS_ZVS_AON_POS)) +#define AON_DCDC11_ISENSE_TRIM_AON AON_DCDC11_ISENSE_TRIM_AON +#define AON_DCDC11_ISENSE_TRIM_AON_POS (28U) +#define AON_DCDC11_ISENSE_TRIM_AON_LEN (3U) +#define AON_DCDC11_ISENSE_TRIM_AON_MSK (((1U << AON_DCDC11_ISENSE_TRIM_AON_LEN) - 1) << AON_DCDC11_ISENSE_TRIM_AON_POS) +#define AON_DCDC11_ISENSE_TRIM_AON_UMSK (~(((1U << AON_DCDC11_ISENSE_TRIM_AON_LEN) - 1) << AON_DCDC11_ISENSE_TRIM_AON_POS)) + +/* 0x820 : move to 0x2000F000[23] */ +#define AON_DCDC18_TOP_0_OFFSET (0x820) +#define AON_DCDC18_SSTART_TIME_AON AON_DCDC18_SSTART_TIME_AON +#define AON_DCDC18_SSTART_TIME_AON_POS (0U) +#define AON_DCDC18_SSTART_TIME_AON_LEN (2U) +#define AON_DCDC18_SSTART_TIME_AON_MSK (((1U << AON_DCDC18_SSTART_TIME_AON_LEN) - 1) << AON_DCDC18_SSTART_TIME_AON_POS) +#define AON_DCDC18_SSTART_TIME_AON_UMSK (~(((1U << AON_DCDC18_SSTART_TIME_AON_LEN) - 1) << AON_DCDC18_SSTART_TIME_AON_POS)) +#define AON_DCDC18_STBY_LP_CUR_AON AON_DCDC18_STBY_LP_CUR_AON +#define AON_DCDC18_STBY_LP_CUR_AON_POS (4U) +#define AON_DCDC18_STBY_LP_CUR_AON_LEN (3U) +#define AON_DCDC18_STBY_LP_CUR_AON_MSK (((1U << AON_DCDC18_STBY_LP_CUR_AON_LEN) - 1) << AON_DCDC18_STBY_LP_CUR_AON_POS) +#define AON_DCDC18_STBY_LP_CUR_AON_UMSK (~(((1U << AON_DCDC18_STBY_LP_CUR_AON_LEN) - 1) << AON_DCDC18_STBY_LP_CUR_AON_POS)) +#define AON_DCDC18_VC_CLAMP_VTH_AON AON_DCDC18_VC_CLAMP_VTH_AON +#define AON_DCDC18_VC_CLAMP_VTH_AON_POS (8U) +#define AON_DCDC18_VC_CLAMP_VTH_AON_LEN (3U) +#define AON_DCDC18_VC_CLAMP_VTH_AON_MSK (((1U << AON_DCDC18_VC_CLAMP_VTH_AON_LEN) - 1) << AON_DCDC18_VC_CLAMP_VTH_AON_POS) +#define AON_DCDC18_VC_CLAMP_VTH_AON_UMSK (~(((1U << AON_DCDC18_VC_CLAMP_VTH_AON_LEN) - 1) << AON_DCDC18_VC_CLAMP_VTH_AON_POS)) +#define AON_DCDC18_VOUT_SEL_AON AON_DCDC18_VOUT_SEL_AON +#define AON_DCDC18_VOUT_SEL_AON_POS (11U) +#define AON_DCDC18_VOUT_SEL_AON_LEN (5U) +#define AON_DCDC18_VOUT_SEL_AON_MSK (((1U << AON_DCDC18_VOUT_SEL_AON_LEN) - 1) << AON_DCDC18_VOUT_SEL_AON_POS) +#define AON_DCDC18_VOUT_SEL_AON_UMSK (~(((1U << AON_DCDC18_VOUT_SEL_AON_LEN) - 1) << AON_DCDC18_VOUT_SEL_AON_POS)) +#define AON_DCDC18_VOUT_TRIM_AON AON_DCDC18_VOUT_TRIM_AON +#define AON_DCDC18_VOUT_TRIM_AON_POS (16U) +#define AON_DCDC18_VOUT_TRIM_AON_LEN (4U) +#define AON_DCDC18_VOUT_TRIM_AON_MSK (((1U << AON_DCDC18_VOUT_TRIM_AON_LEN) - 1) << AON_DCDC18_VOUT_TRIM_AON_POS) +#define AON_DCDC18_VOUT_TRIM_AON_UMSK (~(((1U << AON_DCDC18_VOUT_TRIM_AON_LEN) - 1) << AON_DCDC18_VOUT_TRIM_AON_POS)) +#define AON_DCDC18_VPFM_AON AON_DCDC18_VPFM_AON +#define AON_DCDC18_VPFM_AON_POS (20U) +#define AON_DCDC18_VPFM_AON_LEN (4U) +#define AON_DCDC18_VPFM_AON_MSK (((1U << AON_DCDC18_VPFM_AON_LEN) - 1) << AON_DCDC18_VPFM_AON_POS) +#define AON_DCDC18_VPFM_AON_UMSK (~(((1U << AON_DCDC18_VPFM_AON_LEN) - 1) << AON_DCDC18_VPFM_AON_POS)) +#define AON_DCDC18_ZVS_TD_OPT_AON AON_DCDC18_ZVS_TD_OPT_AON +#define AON_DCDC18_ZVS_TD_OPT_AON_POS (24U) +#define AON_DCDC18_ZVS_TD_OPT_AON_LEN (3U) +#define AON_DCDC18_ZVS_TD_OPT_AON_MSK (((1U << AON_DCDC18_ZVS_TD_OPT_AON_LEN) - 1) << AON_DCDC18_ZVS_TD_OPT_AON_POS) +#define AON_DCDC18_ZVS_TD_OPT_AON_UMSK (~(((1U << AON_DCDC18_ZVS_TD_OPT_AON_LEN) - 1) << AON_DCDC18_ZVS_TD_OPT_AON_POS)) +#define AON_DCDC18_VSTBY_AON AON_DCDC18_VSTBY_AON +#define AON_DCDC18_VSTBY_AON_POS (28U) +#define AON_DCDC18_VSTBY_AON_LEN (2U) +#define AON_DCDC18_VSTBY_AON_MSK (((1U << AON_DCDC18_VSTBY_AON_LEN) - 1) << AON_DCDC18_VSTBY_AON_POS) +#define AON_DCDC18_VSTBY_AON_UMSK (~(((1U << AON_DCDC18_VSTBY_AON_LEN) - 1) << AON_DCDC18_VSTBY_AON_POS)) + +/* 0x824 : dcdc18_top_1 */ +#define AON_DCDC18_TOP_1_OFFSET (0x824) +#define AON_DCDC18_NONOVERLAP_TD_AON AON_DCDC18_NONOVERLAP_TD_AON +#define AON_DCDC18_NONOVERLAP_TD_AON_POS (0U) +#define AON_DCDC18_NONOVERLAP_TD_AON_LEN (5U) +#define AON_DCDC18_NONOVERLAP_TD_AON_MSK (((1U << AON_DCDC18_NONOVERLAP_TD_AON_LEN) - 1) << AON_DCDC18_NONOVERLAP_TD_AON_POS) +#define AON_DCDC18_NONOVERLAP_TD_AON_UMSK (~(((1U << AON_DCDC18_NONOVERLAP_TD_AON_LEN) - 1) << AON_DCDC18_NONOVERLAP_TD_AON_POS)) +#define AON_DCDC18_OCP_OUT_AON AON_DCDC18_OCP_OUT_AON +#define AON_DCDC18_OCP_OUT_AON_POS (5U) +#define AON_DCDC18_OCP_OUT_AON_LEN (1U) +#define AON_DCDC18_OCP_OUT_AON_MSK (((1U << AON_DCDC18_OCP_OUT_AON_LEN) - 1) << AON_DCDC18_OCP_OUT_AON_POS) +#define AON_DCDC18_OCP_OUT_AON_UMSK (~(((1U << AON_DCDC18_OCP_OUT_AON_LEN) - 1) << AON_DCDC18_OCP_OUT_AON_POS)) +#define AON_DCDC18_OCP_RST_AON AON_DCDC18_OCP_RST_AON +#define AON_DCDC18_OCP_RST_AON_POS (6U) +#define AON_DCDC18_OCP_RST_AON_LEN (1U) +#define AON_DCDC18_OCP_RST_AON_MSK (((1U << AON_DCDC18_OCP_RST_AON_LEN) - 1) << AON_DCDC18_OCP_RST_AON_POS) +#define AON_DCDC18_OCP_RST_AON_UMSK (~(((1U << AON_DCDC18_OCP_RST_AON_LEN) - 1) << AON_DCDC18_OCP_RST_AON_POS)) +#define AON_DCDC18_OCP_VTH_AON AON_DCDC18_OCP_VTH_AON +#define AON_DCDC18_OCP_VTH_AON_POS (8U) +#define AON_DCDC18_OCP_VTH_AON_LEN (3U) +#define AON_DCDC18_OCP_VTH_AON_MSK (((1U << AON_DCDC18_OCP_VTH_AON_LEN) - 1) << AON_DCDC18_OCP_VTH_AON_POS) +#define AON_DCDC18_OCP_VTH_AON_UMSK (~(((1U << AON_DCDC18_OCP_VTH_AON_LEN) - 1) << AON_DCDC18_OCP_VTH_AON_POS)) +#define AON_DCDC18_OSC_2M_MODE_AON AON_DCDC18_OSC_2M_MODE_AON +#define AON_DCDC18_OSC_2M_MODE_AON_POS (11U) +#define AON_DCDC18_OSC_2M_MODE_AON_LEN (1U) +#define AON_DCDC18_OSC_2M_MODE_AON_MSK (((1U << AON_DCDC18_OSC_2M_MODE_AON_LEN) - 1) << AON_DCDC18_OSC_2M_MODE_AON_POS) +#define AON_DCDC18_OSC_2M_MODE_AON_UMSK (~(((1U << AON_DCDC18_OSC_2M_MODE_AON_LEN) - 1) << AON_DCDC18_OSC_2M_MODE_AON_POS)) +#define AON_DCDC18_OSC_FREQ_TRIM_AON AON_DCDC18_OSC_FREQ_TRIM_AON +#define AON_DCDC18_OSC_FREQ_TRIM_AON_POS (12U) +#define AON_DCDC18_OSC_FREQ_TRIM_AON_LEN (4U) +#define AON_DCDC18_OSC_FREQ_TRIM_AON_MSK (((1U << AON_DCDC18_OSC_FREQ_TRIM_AON_LEN) - 1) << AON_DCDC18_OSC_FREQ_TRIM_AON_POS) +#define AON_DCDC18_OSC_FREQ_TRIM_AON_UMSK (~(((1U << AON_DCDC18_OSC_FREQ_TRIM_AON_LEN) - 1) << AON_DCDC18_OSC_FREQ_TRIM_AON_POS)) +#define AON_DCDC18_PULLDOWN_AON AON_DCDC18_PULLDOWN_AON +#define AON_DCDC18_PULLDOWN_AON_POS (16U) +#define AON_DCDC18_PULLDOWN_AON_LEN (1U) +#define AON_DCDC18_PULLDOWN_AON_MSK (((1U << AON_DCDC18_PULLDOWN_AON_LEN) - 1) << AON_DCDC18_PULLDOWN_AON_POS) +#define AON_DCDC18_PULLDOWN_AON_UMSK (~(((1U << AON_DCDC18_PULLDOWN_AON_LEN) - 1) << AON_DCDC18_PULLDOWN_AON_POS)) +#define AON_DCDC18_RC_SEL_AON AON_DCDC18_RC_SEL_AON +#define AON_DCDC18_RC_SEL_AON_POS (20U) +#define AON_DCDC18_RC_SEL_AON_LEN (4U) +#define AON_DCDC18_RC_SEL_AON_MSK (((1U << AON_DCDC18_RC_SEL_AON_LEN) - 1) << AON_DCDC18_RC_SEL_AON_POS) +#define AON_DCDC18_RC_SEL_AON_UMSK (~(((1U << AON_DCDC18_RC_SEL_AON_LEN) - 1) << AON_DCDC18_RC_SEL_AON_POS)) +#define AON_DCDC18_RDY_AON AON_DCDC18_RDY_AON +#define AON_DCDC18_RDY_AON_POS (24U) +#define AON_DCDC18_RDY_AON_LEN (1U) +#define AON_DCDC18_RDY_AON_MSK (((1U << AON_DCDC18_RDY_AON_LEN) - 1) << AON_DCDC18_RDY_AON_POS) +#define AON_DCDC18_RDY_AON_UMSK (~(((1U << AON_DCDC18_RDY_AON_LEN) - 1) << AON_DCDC18_RDY_AON_POS)) +#define AON_DCDC18_SLOPE_CURR_SEL_AON AON_DCDC18_SLOPE_CURR_SEL_AON +#define AON_DCDC18_SLOPE_CURR_SEL_AON_POS (26U) +#define AON_DCDC18_SLOPE_CURR_SEL_AON_LEN (5U) +#define AON_DCDC18_SLOPE_CURR_SEL_AON_MSK (((1U << AON_DCDC18_SLOPE_CURR_SEL_AON_LEN) - 1) << AON_DCDC18_SLOPE_CURR_SEL_AON_POS) +#define AON_DCDC18_SLOPE_CURR_SEL_AON_UMSK (~(((1U << AON_DCDC18_SLOPE_CURR_SEL_AON_LEN) - 1) << AON_DCDC18_SLOPE_CURR_SEL_AON_POS)) + +/* 0x828 : dcdc18_top_2 */ +#define AON_DCDC18_TOP_2_OFFSET (0x828) +#define AON_DCDC18_CFB_SEL_AON AON_DCDC18_CFB_SEL_AON +#define AON_DCDC18_CFB_SEL_AON_POS (4U) +#define AON_DCDC18_CFB_SEL_AON_LEN (4U) +#define AON_DCDC18_CFB_SEL_AON_MSK (((1U << AON_DCDC18_CFB_SEL_AON_LEN) - 1) << AON_DCDC18_CFB_SEL_AON_POS) +#define AON_DCDC18_CFB_SEL_AON_UMSK (~(((1U << AON_DCDC18_CFB_SEL_AON_LEN) - 1) << AON_DCDC18_CFB_SEL_AON_POS)) +#define AON_DCDC18_CHF_SEL_AON AON_DCDC18_CHF_SEL_AON +#define AON_DCDC18_CHF_SEL_AON_POS (8U) +#define AON_DCDC18_CHF_SEL_AON_LEN (4U) +#define AON_DCDC18_CHF_SEL_AON_MSK (((1U << AON_DCDC18_CHF_SEL_AON_LEN) - 1) << AON_DCDC18_CHF_SEL_AON_POS) +#define AON_DCDC18_CHF_SEL_AON_UMSK (~(((1U << AON_DCDC18_CHF_SEL_AON_LEN) - 1) << AON_DCDC18_CHF_SEL_AON_POS)) +#define AON_DCDC18_COMP_GM_SEL_AON AON_DCDC18_COMP_GM_SEL_AON +#define AON_DCDC18_COMP_GM_SEL_AON_POS (12U) +#define AON_DCDC18_COMP_GM_SEL_AON_LEN (3U) +#define AON_DCDC18_COMP_GM_SEL_AON_MSK (((1U << AON_DCDC18_COMP_GM_SEL_AON_LEN) - 1) << AON_DCDC18_COMP_GM_SEL_AON_POS) +#define AON_DCDC18_COMP_GM_SEL_AON_UMSK (~(((1U << AON_DCDC18_COMP_GM_SEL_AON_LEN) - 1) << AON_DCDC18_COMP_GM_SEL_AON_POS)) +#define AON_DCDC18_CS_DELAY_AON AON_DCDC18_CS_DELAY_AON +#define AON_DCDC18_CS_DELAY_AON_POS (16U) +#define AON_DCDC18_CS_DELAY_AON_LEN (3U) +#define AON_DCDC18_CS_DELAY_AON_MSK (((1U << AON_DCDC18_CS_DELAY_AON_LEN) - 1) << AON_DCDC18_CS_DELAY_AON_POS) +#define AON_DCDC18_CS_DELAY_AON_UMSK (~(((1U << AON_DCDC18_CS_DELAY_AON_LEN) - 1) << AON_DCDC18_CS_DELAY_AON_POS)) +#define AON_DCDC18_DRV_SR_AON AON_DCDC18_DRV_SR_AON +#define AON_DCDC18_DRV_SR_AON_POS (20U) +#define AON_DCDC18_DRV_SR_AON_LEN (2U) +#define AON_DCDC18_DRV_SR_AON_MSK (((1U << AON_DCDC18_DRV_SR_AON_LEN) - 1) << AON_DCDC18_DRV_SR_AON_POS) +#define AON_DCDC18_DRV_SR_AON_UMSK (~(((1U << AON_DCDC18_DRV_SR_AON_LEN) - 1) << AON_DCDC18_DRV_SR_AON_POS)) +#define AON_DCDC18_EN_ANTIRING_AON AON_DCDC18_EN_ANTIRING_AON +#define AON_DCDC18_EN_ANTIRING_AON_POS (22U) +#define AON_DCDC18_EN_ANTIRING_AON_LEN (1U) +#define AON_DCDC18_EN_ANTIRING_AON_MSK (((1U << AON_DCDC18_EN_ANTIRING_AON_LEN) - 1) << AON_DCDC18_EN_ANTIRING_AON_POS) +#define AON_DCDC18_EN_ANTIRING_AON_UMSK (~(((1U << AON_DCDC18_EN_ANTIRING_AON_LEN) - 1) << AON_DCDC18_EN_ANTIRING_AON_POS)) +#define AON_DCDC18_EN_OSC_INHIBIT_T2_AON AON_DCDC18_EN_OSC_INHIBIT_T2_AON +#define AON_DCDC18_EN_OSC_INHIBIT_T2_AON_POS (23U) +#define AON_DCDC18_EN_OSC_INHIBIT_T2_AON_LEN (1U) +#define AON_DCDC18_EN_OSC_INHIBIT_T2_AON_MSK (((1U << AON_DCDC18_EN_OSC_INHIBIT_T2_AON_LEN) - 1) << AON_DCDC18_EN_OSC_INHIBIT_T2_AON_POS) +#define AON_DCDC18_EN_OSC_INHIBIT_T2_AON_UMSK (~(((1U << AON_DCDC18_EN_OSC_INHIBIT_T2_AON_LEN) - 1) << AON_DCDC18_EN_OSC_INHIBIT_T2_AON_POS)) +#define AON_DCDC18_EN_SLOW_OSC_AON AON_DCDC18_EN_SLOW_OSC_AON +#define AON_DCDC18_EN_SLOW_OSC_AON_POS (24U) +#define AON_DCDC18_EN_SLOW_OSC_AON_LEN (1U) +#define AON_DCDC18_EN_SLOW_OSC_AON_MSK (((1U << AON_DCDC18_EN_SLOW_OSC_AON_LEN) - 1) << AON_DCDC18_EN_SLOW_OSC_AON_POS) +#define AON_DCDC18_EN_SLOW_OSC_AON_UMSK (~(((1U << AON_DCDC18_EN_SLOW_OSC_AON_LEN) - 1) << AON_DCDC18_EN_SLOW_OSC_AON_POS)) +#define AON_DCDC18_EN_STBY_LP_AON AON_DCDC18_EN_STBY_LP_AON +#define AON_DCDC18_EN_STBY_LP_AON_POS (25U) +#define AON_DCDC18_EN_STBY_LP_AON_LEN (1U) +#define AON_DCDC18_EN_STBY_LP_AON_MSK (((1U << AON_DCDC18_EN_STBY_LP_AON_LEN) - 1) << AON_DCDC18_EN_STBY_LP_AON_POS) +#define AON_DCDC18_EN_STBY_LP_AON_UMSK (~(((1U << AON_DCDC18_EN_STBY_LP_AON_LEN) - 1) << AON_DCDC18_EN_STBY_LP_AON_POS)) +#define AON_DCDC18_EN_STOP_OSC_AON AON_DCDC18_EN_STOP_OSC_AON +#define AON_DCDC18_EN_STOP_OSC_AON_POS (26U) +#define AON_DCDC18_EN_STOP_OSC_AON_LEN (1U) +#define AON_DCDC18_EN_STOP_OSC_AON_MSK (((1U << AON_DCDC18_EN_STOP_OSC_AON_LEN) - 1) << AON_DCDC18_EN_STOP_OSC_AON_POS) +#define AON_DCDC18_EN_STOP_OSC_AON_UMSK (~(((1U << AON_DCDC18_EN_STOP_OSC_AON_LEN) - 1) << AON_DCDC18_EN_STOP_OSC_AON_POS)) +#define AON_DCDC18_FORCE_EN_CS_ZVS_AON AON_DCDC18_FORCE_EN_CS_ZVS_AON +#define AON_DCDC18_FORCE_EN_CS_ZVS_AON_POS (27U) +#define AON_DCDC18_FORCE_EN_CS_ZVS_AON_LEN (1U) +#define AON_DCDC18_FORCE_EN_CS_ZVS_AON_MSK (((1U << AON_DCDC18_FORCE_EN_CS_ZVS_AON_LEN) - 1) << AON_DCDC18_FORCE_EN_CS_ZVS_AON_POS) +#define AON_DCDC18_FORCE_EN_CS_ZVS_AON_UMSK (~(((1U << AON_DCDC18_FORCE_EN_CS_ZVS_AON_LEN) - 1) << AON_DCDC18_FORCE_EN_CS_ZVS_AON_POS)) +#define AON_DCDC18_ISENSE_TRIM_AON AON_DCDC18_ISENSE_TRIM_AON +#define AON_DCDC18_ISENSE_TRIM_AON_POS (28U) +#define AON_DCDC18_ISENSE_TRIM_AON_LEN (3U) +#define AON_DCDC18_ISENSE_TRIM_AON_MSK (((1U << AON_DCDC18_ISENSE_TRIM_AON_LEN) - 1) << AON_DCDC18_ISENSE_TRIM_AON_POS) +#define AON_DCDC18_ISENSE_TRIM_AON_UMSK (~(((1U << AON_DCDC18_ISENSE_TRIM_AON_LEN) - 1) << AON_DCDC18_ISENSE_TRIM_AON_POS)) + +/* 0x82C : psw_irrcv */ +#define AON_PSW_IRRCV_OFFSET (0x82C) +#define AON_PU_PSW_IRRCV_AON AON_PU_PSW_IRRCV_AON +#define AON_PU_PSW_IRRCV_AON_POS (0U) +#define AON_PU_PSW_IRRCV_AON_LEN (1U) +#define AON_PU_PSW_IRRCV_AON_MSK (((1U << AON_PU_PSW_IRRCV_AON_LEN) - 1) << AON_PU_PSW_IRRCV_AON_POS) +#define AON_PU_PSW_IRRCV_AON_UMSK (~(((1U << AON_PU_PSW_IRRCV_AON_LEN) - 1) << AON_PU_PSW_IRRCV_AON_POS)) +#define AON_USB20_RREF_EXT_EN_AON AON_USB20_RREF_EXT_EN_AON +#define AON_USB20_RREF_EXT_EN_AON_POS (19U) +#define AON_USB20_RREF_EXT_EN_AON_LEN (1U) +#define AON_USB20_RREF_EXT_EN_AON_MSK (((1U << AON_USB20_RREF_EXT_EN_AON_LEN) - 1) << AON_USB20_RREF_EXT_EN_AON_POS) +#define AON_USB20_RREF_EXT_EN_AON_UMSK (~(((1U << AON_USB20_RREF_EXT_EN_AON_LEN) - 1) << AON_USB20_RREF_EXT_EN_AON_POS)) +#define AON_EN_POR33_AON AON_EN_POR33_AON +#define AON_EN_POR33_AON_POS (20U) +#define AON_EN_POR33_AON_LEN (1U) +#define AON_EN_POR33_AON_MSK (((1U << AON_EN_POR33_AON_LEN) - 1) << AON_EN_POR33_AON_POS) +#define AON_EN_POR33_AON_UMSK (~(((1U << AON_EN_POR33_AON_LEN) - 1) << AON_EN_POR33_AON_POS)) +#define AON_USB20_RREF_HIZ_AON AON_USB20_RREF_HIZ_AON +#define AON_USB20_RREF_HIZ_AON_POS (21U) +#define AON_USB20_RREF_HIZ_AON_LEN (1U) +#define AON_USB20_RREF_HIZ_AON_MSK (((1U << AON_USB20_RREF_HIZ_AON_LEN) - 1) << AON_USB20_RREF_HIZ_AON_POS) +#define AON_USB20_RREF_HIZ_AON_UMSK (~(((1U << AON_USB20_RREF_HIZ_AON_LEN) - 1) << AON_USB20_RREF_HIZ_AON_POS)) +#define AON_USB20_RCAL_CODE_AON AON_USB20_RCAL_CODE_AON +#define AON_USB20_RCAL_CODE_AON_POS (24U) +#define AON_USB20_RCAL_CODE_AON_LEN (6U) +#define AON_USB20_RCAL_CODE_AON_MSK (((1U << AON_USB20_RCAL_CODE_AON_LEN) - 1) << AON_USB20_RCAL_CODE_AON_POS) +#define AON_USB20_RCAL_CODE_AON_UMSK (~(((1U << AON_USB20_RCAL_CODE_AON_LEN) - 1) << AON_USB20_RCAL_CODE_AON_POS)) + +/* 0x880 : rf_top_aon */ +#define AON_RF_TOP_AON_OFFSET (0x880) +#define AON_PU_MBG_AON AON_PU_MBG_AON +#define AON_PU_MBG_AON_POS (0U) +#define AON_PU_MBG_AON_LEN (1U) +#define AON_PU_MBG_AON_MSK (((1U << AON_PU_MBG_AON_LEN) - 1) << AON_PU_MBG_AON_POS) +#define AON_PU_MBG_AON_UMSK (~(((1U << AON_PU_MBG_AON_LEN) - 1) << AON_PU_MBG_AON_POS)) +#define AON_PU_LDO15RF_AON AON_PU_LDO15RF_AON +#define AON_PU_LDO15RF_AON_POS (1U) +#define AON_PU_LDO15RF_AON_LEN (1U) +#define AON_PU_LDO15RF_AON_MSK (((1U << AON_PU_LDO15RF_AON_LEN) - 1) << AON_PU_LDO15RF_AON_POS) +#define AON_PU_LDO15RF_AON_UMSK (~(((1U << AON_PU_LDO15RF_AON_LEN) - 1) << AON_PU_LDO15RF_AON_POS)) +#define AON_PU_SFREG_AON AON_PU_SFREG_AON +#define AON_PU_SFREG_AON_POS (2U) +#define AON_PU_SFREG_AON_LEN (1U) +#define AON_PU_SFREG_AON_MSK (((1U << AON_PU_SFREG_AON_LEN) - 1) << AON_PU_SFREG_AON_POS) +#define AON_PU_SFREG_AON_UMSK (~(((1U << AON_PU_SFREG_AON_LEN) - 1) << AON_PU_SFREG_AON_POS)) +#define AON_PU_XTAL_BUF_AON AON_PU_XTAL_BUF_AON +#define AON_PU_XTAL_BUF_AON_POS (4U) +#define AON_PU_XTAL_BUF_AON_LEN (1U) +#define AON_PU_XTAL_BUF_AON_MSK (((1U << AON_PU_XTAL_BUF_AON_LEN) - 1) << AON_PU_XTAL_BUF_AON_POS) +#define AON_PU_XTAL_BUF_AON_UMSK (~(((1U << AON_PU_XTAL_BUF_AON_LEN) - 1) << AON_PU_XTAL_BUF_AON_POS)) +#define AON_PU_XTAL_AON AON_PU_XTAL_AON +#define AON_PU_XTAL_AON_POS (5U) +#define AON_PU_XTAL_AON_LEN (1U) +#define AON_PU_XTAL_AON_MSK (((1U << AON_PU_XTAL_AON_LEN) - 1) << AON_PU_XTAL_AON_POS) +#define AON_PU_XTAL_AON_UMSK (~(((1U << AON_PU_XTAL_AON_LEN) - 1) << AON_PU_XTAL_AON_POS)) +#define AON_LDO15RF_SSTART_SEL_AON AON_LDO15RF_SSTART_SEL_AON +#define AON_LDO15RF_SSTART_SEL_AON_POS (8U) +#define AON_LDO15RF_SSTART_SEL_AON_LEN (1U) +#define AON_LDO15RF_SSTART_SEL_AON_MSK (((1U << AON_LDO15RF_SSTART_SEL_AON_LEN) - 1) << AON_LDO15RF_SSTART_SEL_AON_POS) +#define AON_LDO15RF_SSTART_SEL_AON_UMSK (~(((1U << AON_LDO15RF_SSTART_SEL_AON_LEN) - 1) << AON_LDO15RF_SSTART_SEL_AON_POS)) +#define AON_LDO15RF_SSTART_DELAY_AON AON_LDO15RF_SSTART_DELAY_AON +#define AON_LDO15RF_SSTART_DELAY_AON_POS (9U) +#define AON_LDO15RF_SSTART_DELAY_AON_LEN (2U) +#define AON_LDO15RF_SSTART_DELAY_AON_MSK (((1U << AON_LDO15RF_SSTART_DELAY_AON_LEN) - 1) << AON_LDO15RF_SSTART_DELAY_AON_POS) +#define AON_LDO15RF_SSTART_DELAY_AON_UMSK (~(((1U << AON_LDO15RF_SSTART_DELAY_AON_LEN) - 1) << AON_LDO15RF_SSTART_DELAY_AON_POS)) +#define AON_LDO15RF_PULLDOWN_AON AON_LDO15RF_PULLDOWN_AON +#define AON_LDO15RF_PULLDOWN_AON_POS (12U) +#define AON_LDO15RF_PULLDOWN_AON_LEN (1U) +#define AON_LDO15RF_PULLDOWN_AON_MSK (((1U << AON_LDO15RF_PULLDOWN_AON_LEN) - 1) << AON_LDO15RF_PULLDOWN_AON_POS) +#define AON_LDO15RF_PULLDOWN_AON_UMSK (~(((1U << AON_LDO15RF_PULLDOWN_AON_LEN) - 1) << AON_LDO15RF_PULLDOWN_AON_POS)) +#define AON_LDO15RF_PULLDOWN_SEL_AON AON_LDO15RF_PULLDOWN_SEL_AON +#define AON_LDO15RF_PULLDOWN_SEL_AON_POS (13U) +#define AON_LDO15RF_PULLDOWN_SEL_AON_LEN (1U) +#define AON_LDO15RF_PULLDOWN_SEL_AON_MSK (((1U << AON_LDO15RF_PULLDOWN_SEL_AON_LEN) - 1) << AON_LDO15RF_PULLDOWN_SEL_AON_POS) +#define AON_LDO15RF_PULLDOWN_SEL_AON_UMSK (~(((1U << AON_LDO15RF_PULLDOWN_SEL_AON_LEN) - 1) << AON_LDO15RF_PULLDOWN_SEL_AON_POS)) +#define AON_LDO15RF_VOUT_SEL_AON AON_LDO15RF_VOUT_SEL_AON +#define AON_LDO15RF_VOUT_SEL_AON_POS (16U) +#define AON_LDO15RF_VOUT_SEL_AON_LEN (3U) +#define AON_LDO15RF_VOUT_SEL_AON_MSK (((1U << AON_LDO15RF_VOUT_SEL_AON_LEN) - 1) << AON_LDO15RF_VOUT_SEL_AON_POS) +#define AON_LDO15RF_VOUT_SEL_AON_UMSK (~(((1U << AON_LDO15RF_VOUT_SEL_AON_LEN) - 1) << AON_LDO15RF_VOUT_SEL_AON_POS)) +#define AON_LDO15RF_CC_AON AON_LDO15RF_CC_AON +#define AON_LDO15RF_CC_AON_POS (24U) +#define AON_LDO15RF_CC_AON_LEN (2U) +#define AON_LDO15RF_CC_AON_MSK (((1U << AON_LDO15RF_CC_AON_LEN) - 1) << AON_LDO15RF_CC_AON_POS) +#define AON_LDO15RF_CC_AON_UMSK (~(((1U << AON_LDO15RF_CC_AON_LEN) - 1) << AON_LDO15RF_CC_AON_POS)) +#define AON_LDO15RF_BYPASS_AON AON_LDO15RF_BYPASS_AON +#define AON_LDO15RF_BYPASS_AON_POS (28U) +#define AON_LDO15RF_BYPASS_AON_LEN (1U) +#define AON_LDO15RF_BYPASS_AON_MSK (((1U << AON_LDO15RF_BYPASS_AON_LEN) - 1) << AON_LDO15RF_BYPASS_AON_POS) +#define AON_LDO15RF_BYPASS_AON_UMSK (~(((1U << AON_LDO15RF_BYPASS_AON_LEN) - 1) << AON_LDO15RF_BYPASS_AON_POS)) + +/* 0x884 : xtal_cfg */ +#define AON_XTAL_CFG_OFFSET (0x884) +#define AON_XTAL_BK_AON AON_XTAL_BK_AON +#define AON_XTAL_BK_AON_POS (0U) +#define AON_XTAL_BK_AON_LEN (2U) +#define AON_XTAL_BK_AON_MSK (((1U << AON_XTAL_BK_AON_LEN) - 1) << AON_XTAL_BK_AON_POS) +#define AON_XTAL_BK_AON_UMSK (~(((1U << AON_XTAL_BK_AON_LEN) - 1) << AON_XTAL_BK_AON_POS)) +#define AON_XTAL_CAPCODE_EXTRA_AON AON_XTAL_CAPCODE_EXTRA_AON +#define AON_XTAL_CAPCODE_EXTRA_AON_POS (2U) +#define AON_XTAL_CAPCODE_EXTRA_AON_LEN (1U) +#define AON_XTAL_CAPCODE_EXTRA_AON_MSK (((1U << AON_XTAL_CAPCODE_EXTRA_AON_LEN) - 1) << AON_XTAL_CAPCODE_EXTRA_AON_POS) +#define AON_XTAL_CAPCODE_EXTRA_AON_UMSK (~(((1U << AON_XTAL_CAPCODE_EXTRA_AON_LEN) - 1) << AON_XTAL_CAPCODE_EXTRA_AON_POS)) +#define AON_XTAL_EXT_SEL_AON AON_XTAL_EXT_SEL_AON +#define AON_XTAL_EXT_SEL_AON_POS (3U) +#define AON_XTAL_EXT_SEL_AON_LEN (1U) +#define AON_XTAL_EXT_SEL_AON_MSK (((1U << AON_XTAL_EXT_SEL_AON_LEN) - 1) << AON_XTAL_EXT_SEL_AON_POS) +#define AON_XTAL_EXT_SEL_AON_UMSK (~(((1U << AON_XTAL_EXT_SEL_AON_LEN) - 1) << AON_XTAL_EXT_SEL_AON_POS)) +#define AON_XTAL_BUF_EN_AON AON_XTAL_BUF_EN_AON +#define AON_XTAL_BUF_EN_AON_POS (4U) +#define AON_XTAL_BUF_EN_AON_LEN (4U) +#define AON_XTAL_BUF_EN_AON_MSK (((1U << AON_XTAL_BUF_EN_AON_LEN) - 1) << AON_XTAL_BUF_EN_AON_POS) +#define AON_XTAL_BUF_EN_AON_UMSK (~(((1U << AON_XTAL_BUF_EN_AON_LEN) - 1) << AON_XTAL_BUF_EN_AON_POS)) +#define AON_XTAL_BUF_HP_AON AON_XTAL_BUF_HP_AON +#define AON_XTAL_BUF_HP_AON_POS (8U) +#define AON_XTAL_BUF_HP_AON_LEN (4U) +#define AON_XTAL_BUF_HP_AON_MSK (((1U << AON_XTAL_BUF_HP_AON_LEN) - 1) << AON_XTAL_BUF_HP_AON_POS) +#define AON_XTAL_BUF_HP_AON_UMSK (~(((1U << AON_XTAL_BUF_HP_AON_LEN) - 1) << AON_XTAL_BUF_HP_AON_POS)) +#define AON_XTAL_FAST_STARTUP_AON AON_XTAL_FAST_STARTUP_AON +#define AON_XTAL_FAST_STARTUP_AON_POS (12U) +#define AON_XTAL_FAST_STARTUP_AON_LEN (1U) +#define AON_XTAL_FAST_STARTUP_AON_MSK (((1U << AON_XTAL_FAST_STARTUP_AON_LEN) - 1) << AON_XTAL_FAST_STARTUP_AON_POS) +#define AON_XTAL_FAST_STARTUP_AON_UMSK (~(((1U << AON_XTAL_FAST_STARTUP_AON_LEN) - 1) << AON_XTAL_FAST_STARTUP_AON_POS)) +#define AON_XTAL_SLEEP_AON AON_XTAL_SLEEP_AON +#define AON_XTAL_SLEEP_AON_POS (13U) +#define AON_XTAL_SLEEP_AON_LEN (1U) +#define AON_XTAL_SLEEP_AON_MSK (((1U << AON_XTAL_SLEEP_AON_LEN) - 1) << AON_XTAL_SLEEP_AON_POS) +#define AON_XTAL_SLEEP_AON_UMSK (~(((1U << AON_XTAL_SLEEP_AON_LEN) - 1) << AON_XTAL_SLEEP_AON_POS)) +#define AON_XTAL_AMP_CTRL_AON AON_XTAL_AMP_CTRL_AON +#define AON_XTAL_AMP_CTRL_AON_POS (14U) +#define AON_XTAL_AMP_CTRL_AON_LEN (2U) +#define AON_XTAL_AMP_CTRL_AON_MSK (((1U << AON_XTAL_AMP_CTRL_AON_LEN) - 1) << AON_XTAL_AMP_CTRL_AON_POS) +#define AON_XTAL_AMP_CTRL_AON_UMSK (~(((1U << AON_XTAL_AMP_CTRL_AON_LEN) - 1) << AON_XTAL_AMP_CTRL_AON_POS)) +#define AON_XTAL_CAPCODE_OUT_AON AON_XTAL_CAPCODE_OUT_AON +#define AON_XTAL_CAPCODE_OUT_AON_POS (16U) +#define AON_XTAL_CAPCODE_OUT_AON_LEN (6U) +#define AON_XTAL_CAPCODE_OUT_AON_MSK (((1U << AON_XTAL_CAPCODE_OUT_AON_LEN) - 1) << AON_XTAL_CAPCODE_OUT_AON_POS) +#define AON_XTAL_CAPCODE_OUT_AON_UMSK (~(((1U << AON_XTAL_CAPCODE_OUT_AON_LEN) - 1) << AON_XTAL_CAPCODE_OUT_AON_POS)) +#define AON_XTAL_CAPCODE_IN_AON AON_XTAL_CAPCODE_IN_AON +#define AON_XTAL_CAPCODE_IN_AON_POS (22U) +#define AON_XTAL_CAPCODE_IN_AON_LEN (6U) +#define AON_XTAL_CAPCODE_IN_AON_MSK (((1U << AON_XTAL_CAPCODE_IN_AON_LEN) - 1) << AON_XTAL_CAPCODE_IN_AON_POS) +#define AON_XTAL_CAPCODE_IN_AON_UMSK (~(((1U << AON_XTAL_CAPCODE_IN_AON_LEN) - 1) << AON_XTAL_CAPCODE_IN_AON_POS)) +#define AON_XTAL_GM_BOOST_AON AON_XTAL_GM_BOOST_AON +#define AON_XTAL_GM_BOOST_AON_POS (28U) +#define AON_XTAL_GM_BOOST_AON_LEN (2U) +#define AON_XTAL_GM_BOOST_AON_MSK (((1U << AON_XTAL_GM_BOOST_AON_LEN) - 1) << AON_XTAL_GM_BOOST_AON_POS) +#define AON_XTAL_GM_BOOST_AON_UMSK (~(((1U << AON_XTAL_GM_BOOST_AON_LEN) - 1) << AON_XTAL_GM_BOOST_AON_POS)) +#define AON_XTAL_RDY_SEL_AON AON_XTAL_RDY_SEL_AON +#define AON_XTAL_RDY_SEL_AON_POS (30U) +#define AON_XTAL_RDY_SEL_AON_LEN (2U) +#define AON_XTAL_RDY_SEL_AON_MSK (((1U << AON_XTAL_RDY_SEL_AON_LEN) - 1) << AON_XTAL_RDY_SEL_AON_POS) +#define AON_XTAL_RDY_SEL_AON_UMSK (~(((1U << AON_XTAL_RDY_SEL_AON_LEN) - 1) << AON_XTAL_RDY_SEL_AON_POS)) + +/* 0x888 : xtal_cfg2 */ +#define AON_XTAL_CFG2_OFFSET (0x888) +#define AON_WIFI_XTAL_LDO33_BYPASS_AON AON_WIFI_XTAL_LDO33_BYPASS_AON +#define AON_WIFI_XTAL_LDO33_BYPASS_AON_POS (0U) +#define AON_WIFI_XTAL_LDO33_BYPASS_AON_LEN (1U) +#define AON_WIFI_XTAL_LDO33_BYPASS_AON_MSK (((1U << AON_WIFI_XTAL_LDO33_BYPASS_AON_LEN) - 1) << AON_WIFI_XTAL_LDO33_BYPASS_AON_POS) +#define AON_WIFI_XTAL_LDO33_BYPASS_AON_UMSK (~(((1U << AON_WIFI_XTAL_LDO33_BYPASS_AON_LEN) - 1) << AON_WIFI_XTAL_LDO33_BYPASS_AON_POS)) +#define AON_WIFI_XTAL_LDO33_SEL_AON AON_WIFI_XTAL_LDO33_SEL_AON +#define AON_WIFI_XTAL_LDO33_SEL_AON_POS (1U) +#define AON_WIFI_XTAL_LDO33_SEL_AON_LEN (3U) +#define AON_WIFI_XTAL_LDO33_SEL_AON_MSK (((1U << AON_WIFI_XTAL_LDO33_SEL_AON_LEN) - 1) << AON_WIFI_XTAL_LDO33_SEL_AON_POS) +#define AON_WIFI_XTAL_LDO33_SEL_AON_UMSK (~(((1U << AON_WIFI_XTAL_LDO33_SEL_AON_LEN) - 1) << AON_WIFI_XTAL_LDO33_SEL_AON_POS)) +#define AON_WIFI_XTAL_LDO18_SEL_AON AON_WIFI_XTAL_LDO18_SEL_AON +#define AON_WIFI_XTAL_LDO18_SEL_AON_POS (4U) +#define AON_WIFI_XTAL_LDO18_SEL_AON_LEN (2U) +#define AON_WIFI_XTAL_LDO18_SEL_AON_MSK (((1U << AON_WIFI_XTAL_LDO18_SEL_AON_LEN) - 1) << AON_WIFI_XTAL_LDO18_SEL_AON_POS) +#define AON_WIFI_XTAL_LDO18_SEL_AON_UMSK (~(((1U << AON_WIFI_XTAL_LDO18_SEL_AON_LEN) - 1) << AON_WIFI_XTAL_LDO18_SEL_AON_POS)) +#define AON_WIFI_XTAL_LDO33_PU_AON AON_WIFI_XTAL_LDO33_PU_AON +#define AON_WIFI_XTAL_LDO33_PU_AON_POS (6U) +#define AON_WIFI_XTAL_LDO33_PU_AON_LEN (1U) +#define AON_WIFI_XTAL_LDO33_PU_AON_MSK (((1U << AON_WIFI_XTAL_LDO33_PU_AON_LEN) - 1) << AON_WIFI_XTAL_LDO33_PU_AON_POS) +#define AON_WIFI_XTAL_LDO33_PU_AON_UMSK (~(((1U << AON_WIFI_XTAL_LDO33_PU_AON_LEN) - 1) << AON_WIFI_XTAL_LDO33_PU_AON_POS)) +#define AON_WIFI_XTAL_LDO18_PU_AON AON_WIFI_XTAL_LDO18_PU_AON +#define AON_WIFI_XTAL_LDO18_PU_AON_POS (7U) +#define AON_WIFI_XTAL_LDO18_PU_AON_LEN (1U) +#define AON_WIFI_XTAL_LDO18_PU_AON_MSK (((1U << AON_WIFI_XTAL_LDO18_PU_AON_LEN) - 1) << AON_WIFI_XTAL_LDO18_PU_AON_POS) +#define AON_WIFI_XTAL_LDO18_PU_AON_UMSK (~(((1U << AON_WIFI_XTAL_LDO18_PU_AON_LEN) - 1) << AON_WIFI_XTAL_LDO18_PU_AON_POS)) +#define AON_WIFI_XTAL_RESERVE AON_WIFI_XTAL_RESERVE +#define AON_WIFI_XTAL_RESERVE_POS (10U) +#define AON_WIFI_XTAL_RESERVE_LEN (4U) +#define AON_WIFI_XTAL_RESERVE_MSK (((1U << AON_WIFI_XTAL_RESERVE_LEN) - 1) << AON_WIFI_XTAL_RESERVE_POS) +#define AON_WIFI_XTAL_RESERVE_UMSK (~(((1U << AON_WIFI_XTAL_RESERVE_LEN) - 1) << AON_WIFI_XTAL_RESERVE_POS)) +#define AON_WIFI_XTAL_LDO18_SHORT_FILTER_AON AON_WIFI_XTAL_LDO18_SHORT_FILTER_AON +#define AON_WIFI_XTAL_LDO18_SHORT_FILTER_AON_POS (16U) +#define AON_WIFI_XTAL_LDO18_SHORT_FILTER_AON_LEN (1U) +#define AON_WIFI_XTAL_LDO18_SHORT_FILTER_AON_MSK (((1U << AON_WIFI_XTAL_LDO18_SHORT_FILTER_AON_LEN) - 1) << AON_WIFI_XTAL_LDO18_SHORT_FILTER_AON_POS) +#define AON_WIFI_XTAL_LDO18_SHORT_FILTER_AON_UMSK (~(((1U << AON_WIFI_XTAL_LDO18_SHORT_FILTER_AON_LEN) - 1) << AON_WIFI_XTAL_LDO18_SHORT_FILTER_AON_POS)) +#define AON_XTAL_BUF_DRV_AON AON_XTAL_BUF_DRV_AON +#define AON_XTAL_BUF_DRV_AON_POS (30U) +#define AON_XTAL_BUF_DRV_AON_LEN (2U) +#define AON_XTAL_BUF_DRV_AON_MSK (((1U << AON_XTAL_BUF_DRV_AON_LEN) - 1) << AON_XTAL_BUF_DRV_AON_POS) +#define AON_XTAL_BUF_DRV_AON_UMSK (~(((1U << AON_XTAL_BUF_DRV_AON_LEN) - 1) << AON_XTAL_BUF_DRV_AON_POS)) + +/* 0x88C : xtal_cfg3 */ +#define AON_XTAL_CFG3_OFFSET (0x88C) +#define AON_WIFI_XTAL_CLK_INV_EN_AON AON_WIFI_XTAL_CLK_INV_EN_AON +#define AON_WIFI_XTAL_CLK_INV_EN_AON_POS (12U) +#define AON_WIFI_XTAL_CLK_INV_EN_AON_LEN (1U) +#define AON_WIFI_XTAL_CLK_INV_EN_AON_MSK (((1U << AON_WIFI_XTAL_CLK_INV_EN_AON_LEN) - 1) << AON_WIFI_XTAL_CLK_INV_EN_AON_POS) +#define AON_WIFI_XTAL_CLK_INV_EN_AON_UMSK (~(((1U << AON_WIFI_XTAL_CLK_INV_EN_AON_LEN) - 1) << AON_WIFI_XTAL_CLK_INV_EN_AON_POS)) +#define AON_WIFI_XTAL_CML_EN_AON AON_WIFI_XTAL_CML_EN_AON +#define AON_WIFI_XTAL_CML_EN_AON_POS (16U) +#define AON_WIFI_XTAL_CML_EN_AON_LEN (1U) +#define AON_WIFI_XTAL_CML_EN_AON_MSK (((1U << AON_WIFI_XTAL_CML_EN_AON_LEN) - 1) << AON_WIFI_XTAL_CML_EN_AON_POS) +#define AON_WIFI_XTAL_CML_EN_AON_UMSK (~(((1U << AON_WIFI_XTAL_CML_EN_AON_LEN) - 1) << AON_WIFI_XTAL_CML_EN_AON_POS)) +#define AON_WIFI_XTAL_CML_R_SEL_AON AON_WIFI_XTAL_CML_R_SEL_AON +#define AON_WIFI_XTAL_CML_R_SEL_AON_POS (17U) +#define AON_WIFI_XTAL_CML_R_SEL_AON_LEN (2U) +#define AON_WIFI_XTAL_CML_R_SEL_AON_MSK (((1U << AON_WIFI_XTAL_CML_R_SEL_AON_LEN) - 1) << AON_WIFI_XTAL_CML_R_SEL_AON_POS) +#define AON_WIFI_XTAL_CML_R_SEL_AON_UMSK (~(((1U << AON_WIFI_XTAL_CML_R_SEL_AON_LEN) - 1) << AON_WIFI_XTAL_CML_R_SEL_AON_POS)) +#define AON_WIFI_XTAL_CLK_EN_AON AON_WIFI_XTAL_CLK_EN_AON +#define AON_WIFI_XTAL_CLK_EN_AON_POS (20U) +#define AON_WIFI_XTAL_CLK_EN_AON_LEN (1U) +#define AON_WIFI_XTAL_CLK_EN_AON_MSK (((1U << AON_WIFI_XTAL_CLK_EN_AON_LEN) - 1) << AON_WIFI_XTAL_CLK_EN_AON_POS) +#define AON_WIFI_XTAL_CLK_EN_AON_UMSK (~(((1U << AON_WIFI_XTAL_CLK_EN_AON_LEN) - 1) << AON_WIFI_XTAL_CLK_EN_AON_POS)) +#define AON_WIFI_XTAL_BUF_DRV_AON AON_WIFI_XTAL_BUF_DRV_AON +#define AON_WIFI_XTAL_BUF_DRV_AON_POS (30U) +#define AON_WIFI_XTAL_BUF_DRV_AON_LEN (2U) +#define AON_WIFI_XTAL_BUF_DRV_AON_MSK (((1U << AON_WIFI_XTAL_BUF_DRV_AON_LEN) - 1) << AON_WIFI_XTAL_BUF_DRV_AON_POS) +#define AON_WIFI_XTAL_BUF_DRV_AON_UMSK (~(((1U << AON_WIFI_XTAL_BUF_DRV_AON_LEN) - 1) << AON_WIFI_XTAL_BUF_DRV_AON_POS)) + +/* 0x890 : tsen */ +#define AON_TSEN_OFFSET (0x890) +#define AON_TSEN_REFCODE_CORNER AON_TSEN_REFCODE_CORNER +#define AON_TSEN_REFCODE_CORNER_POS (0U) +#define AON_TSEN_REFCODE_CORNER_LEN (12U) +#define AON_TSEN_REFCODE_CORNER_MSK (((1U << AON_TSEN_REFCODE_CORNER_LEN) - 1) << AON_TSEN_REFCODE_CORNER_POS) +#define AON_TSEN_REFCODE_CORNER_UMSK (~(((1U << AON_TSEN_REFCODE_CORNER_LEN) - 1) << AON_TSEN_REFCODE_CORNER_POS)) +#define AON_TSEN_REFCODE_RFCAL AON_TSEN_REFCODE_RFCAL +#define AON_TSEN_REFCODE_RFCAL_POS (16U) +#define AON_TSEN_REFCODE_RFCAL_LEN (12U) +#define AON_TSEN_REFCODE_RFCAL_MSK (((1U << AON_TSEN_REFCODE_RFCAL_LEN) - 1) << AON_TSEN_REFCODE_RFCAL_POS) +#define AON_TSEN_REFCODE_RFCAL_UMSK (~(((1U << AON_TSEN_REFCODE_RFCAL_LEN) - 1) << AON_TSEN_REFCODE_RFCAL_POS)) +#define AON_XTAL_RDY AON_XTAL_RDY +#define AON_XTAL_RDY_POS (28U) +#define AON_XTAL_RDY_LEN (1U) +#define AON_XTAL_RDY_MSK (((1U << AON_XTAL_RDY_LEN) - 1) << AON_XTAL_RDY_POS) +#define AON_XTAL_RDY_UMSK (~(((1U << AON_XTAL_RDY_LEN) - 1) << AON_XTAL_RDY_POS)) +#define AON_XTAL_INN_CFG_EN_AON AON_XTAL_INN_CFG_EN_AON +#define AON_XTAL_INN_CFG_EN_AON_POS (29U) +#define AON_XTAL_INN_CFG_EN_AON_LEN (1U) +#define AON_XTAL_INN_CFG_EN_AON_MSK (((1U << AON_XTAL_INN_CFG_EN_AON_LEN) - 1) << AON_XTAL_INN_CFG_EN_AON_POS) +#define AON_XTAL_INN_CFG_EN_AON_UMSK (~(((1U << AON_XTAL_INN_CFG_EN_AON_LEN) - 1) << AON_XTAL_INN_CFG_EN_AON_POS)) +#define AON_XTAL_RDY_INT_SEL_AON AON_XTAL_RDY_INT_SEL_AON +#define AON_XTAL_RDY_INT_SEL_AON_POS (30U) +#define AON_XTAL_RDY_INT_SEL_AON_LEN (2U) +#define AON_XTAL_RDY_INT_SEL_AON_MSK (((1U << AON_XTAL_RDY_INT_SEL_AON_LEN) - 1) << AON_XTAL_RDY_INT_SEL_AON_POS) +#define AON_XTAL_RDY_INT_SEL_AON_UMSK (~(((1U << AON_XTAL_RDY_INT_SEL_AON_LEN) - 1) << AON_XTAL_RDY_INT_SEL_AON_POS)) + +/* 0x8C4 : ldo18io */ +#define AON_LDO18IO_OFFSET (0x8C4) +#define AON_LDO18IO_BYPASS_ISO_AON AON_LDO18IO_BYPASS_ISO_AON +#define AON_LDO18IO_BYPASS_ISO_AON_POS (1U) +#define AON_LDO18IO_BYPASS_ISO_AON_LEN (1U) +#define AON_LDO18IO_BYPASS_ISO_AON_MSK (((1U << AON_LDO18IO_BYPASS_ISO_AON_LEN) - 1) << AON_LDO18IO_BYPASS_ISO_AON_POS) +#define AON_LDO18IO_BYPASS_ISO_AON_UMSK (~(((1U << AON_LDO18IO_BYPASS_ISO_AON_LEN) - 1) << AON_LDO18IO_BYPASS_ISO_AON_POS)) +#define AON_LDO18IO_PULLDOWN_AON AON_LDO18IO_PULLDOWN_AON +#define AON_LDO18IO_PULLDOWN_AON_POS (2U) +#define AON_LDO18IO_PULLDOWN_AON_LEN (1U) +#define AON_LDO18IO_PULLDOWN_AON_MSK (((1U << AON_LDO18IO_PULLDOWN_AON_LEN) - 1) << AON_LDO18IO_PULLDOWN_AON_POS) +#define AON_LDO18IO_PULLDOWN_AON_UMSK (~(((1U << AON_LDO18IO_PULLDOWN_AON_LEN) - 1) << AON_LDO18IO_PULLDOWN_AON_POS)) +#define AON_LDO18IO_PULLDOWN_SEL_AON AON_LDO18IO_PULLDOWN_SEL_AON +#define AON_LDO18IO_PULLDOWN_SEL_AON_POS (3U) +#define AON_LDO18IO_PULLDOWN_SEL_AON_LEN (1U) +#define AON_LDO18IO_PULLDOWN_SEL_AON_MSK (((1U << AON_LDO18IO_PULLDOWN_SEL_AON_LEN) - 1) << AON_LDO18IO_PULLDOWN_SEL_AON_POS) +#define AON_LDO18IO_PULLDOWN_SEL_AON_UMSK (~(((1U << AON_LDO18IO_PULLDOWN_SEL_AON_LEN) - 1) << AON_LDO18IO_PULLDOWN_SEL_AON_POS)) +#define AON_LDO18IO_BM_AON AON_LDO18IO_BM_AON +#define AON_LDO18IO_BM_AON_POS (4U) +#define AON_LDO18IO_BM_AON_LEN (3U) +#define AON_LDO18IO_BM_AON_MSK (((1U << AON_LDO18IO_BM_AON_LEN) - 1) << AON_LDO18IO_BM_AON_POS) +#define AON_LDO18IO_BM_AON_UMSK (~(((1U << AON_LDO18IO_BM_AON_LEN) - 1) << AON_LDO18IO_BM_AON_POS)) +#define AON_LDO18IO_CC_AON AON_LDO18IO_CC_AON +#define AON_LDO18IO_CC_AON_POS (8U) +#define AON_LDO18IO_CC_AON_LEN (3U) +#define AON_LDO18IO_CC_AON_MSK (((1U << AON_LDO18IO_CC_AON_LEN) - 1) << AON_LDO18IO_CC_AON_POS) +#define AON_LDO18IO_CC_AON_UMSK (~(((1U << AON_LDO18IO_CC_AON_LEN) - 1) << AON_LDO18IO_CC_AON_POS)) +#define AON_LDO18IO_OCP_OUT_AON AON_LDO18IO_OCP_OUT_AON +#define AON_LDO18IO_OCP_OUT_AON_POS (11U) +#define AON_LDO18IO_OCP_OUT_AON_LEN (1U) +#define AON_LDO18IO_OCP_OUT_AON_MSK (((1U << AON_LDO18IO_OCP_OUT_AON_LEN) - 1) << AON_LDO18IO_OCP_OUT_AON_POS) +#define AON_LDO18IO_OCP_OUT_AON_UMSK (~(((1U << AON_LDO18IO_OCP_OUT_AON_LEN) - 1) << AON_LDO18IO_OCP_OUT_AON_POS)) +#define AON_LDO18IO_OCP_TH_AON AON_LDO18IO_OCP_TH_AON +#define AON_LDO18IO_OCP_TH_AON_POS (12U) +#define AON_LDO18IO_OCP_TH_AON_LEN (3U) +#define AON_LDO18IO_OCP_TH_AON_MSK (((1U << AON_LDO18IO_OCP_TH_AON_LEN) - 1) << AON_LDO18IO_OCP_TH_AON_POS) +#define AON_LDO18IO_OCP_TH_AON_UMSK (~(((1U << AON_LDO18IO_OCP_TH_AON_LEN) - 1) << AON_LDO18IO_OCP_TH_AON_POS)) +#define AON_LDO18IO_OCP_EN_AON AON_LDO18IO_OCP_EN_AON +#define AON_LDO18IO_OCP_EN_AON_POS (15U) +#define AON_LDO18IO_OCP_EN_AON_LEN (1U) +#define AON_LDO18IO_OCP_EN_AON_MSK (((1U << AON_LDO18IO_OCP_EN_AON_LEN) - 1) << AON_LDO18IO_OCP_EN_AON_POS) +#define AON_LDO18IO_OCP_EN_AON_UMSK (~(((1U << AON_LDO18IO_OCP_EN_AON_LEN) - 1) << AON_LDO18IO_OCP_EN_AON_POS)) +#define AON_LDO18IO_SSTART_DELAY_AON AON_LDO18IO_SSTART_DELAY_AON +#define AON_LDO18IO_SSTART_DELAY_AON_POS (16U) +#define AON_LDO18IO_SSTART_DELAY_AON_LEN (3U) +#define AON_LDO18IO_SSTART_DELAY_AON_MSK (((1U << AON_LDO18IO_SSTART_DELAY_AON_LEN) - 1) << AON_LDO18IO_SSTART_DELAY_AON_POS) +#define AON_LDO18IO_SSTART_DELAY_AON_UMSK (~(((1U << AON_LDO18IO_SSTART_DELAY_AON_LEN) - 1) << AON_LDO18IO_SSTART_DELAY_AON_POS)) +#define AON_LDO18IO_SSTART_EN_AON AON_LDO18IO_SSTART_EN_AON +#define AON_LDO18IO_SSTART_EN_AON_POS (19U) +#define AON_LDO18IO_SSTART_EN_AON_LEN (1U) +#define AON_LDO18IO_SSTART_EN_AON_MSK (((1U << AON_LDO18IO_SSTART_EN_AON_LEN) - 1) << AON_LDO18IO_SSTART_EN_AON_POS) +#define AON_LDO18IO_SSTART_EN_AON_UMSK (~(((1U << AON_LDO18IO_SSTART_EN_AON_LEN) - 1) << AON_LDO18IO_SSTART_EN_AON_POS)) +#define AON_LDO18IO_VOUT_SEL_AON AON_LDO18IO_VOUT_SEL_AON +#define AON_LDO18IO_VOUT_SEL_AON_POS (20U) +#define AON_LDO18IO_VOUT_SEL_AON_LEN (4U) +#define AON_LDO18IO_VOUT_SEL_AON_MSK (((1U << AON_LDO18IO_VOUT_SEL_AON_LEN) - 1) << AON_LDO18IO_VOUT_SEL_AON_POS) +#define AON_LDO18IO_VOUT_SEL_AON_UMSK (~(((1U << AON_LDO18IO_VOUT_SEL_AON_LEN) - 1) << AON_LDO18IO_VOUT_SEL_AON_POS)) +#define AON_LDO18IO_VOUT_TRIM_AON AON_LDO18IO_VOUT_TRIM_AON +#define AON_LDO18IO_VOUT_TRIM_AON_POS (24U) +#define AON_LDO18IO_VOUT_TRIM_AON_LEN (4U) +#define AON_LDO18IO_VOUT_TRIM_AON_MSK (((1U << AON_LDO18IO_VOUT_TRIM_AON_LEN) - 1) << AON_LDO18IO_VOUT_TRIM_AON_POS) +#define AON_LDO18IO_VOUT_TRIM_AON_UMSK (~(((1U << AON_LDO18IO_VOUT_TRIM_AON_LEN) - 1) << AON_LDO18IO_VOUT_TRIM_AON_POS)) + +/* 0x900 : acomp0_ctrl */ +#define AON_ACOMP0_CTRL_OFFSET (0x900) +#define AON_ACOMP0_EN AON_ACOMP0_EN +#define AON_ACOMP0_EN_POS (0U) +#define AON_ACOMP0_EN_LEN (1U) +#define AON_ACOMP0_EN_MSK (((1U << AON_ACOMP0_EN_LEN) - 1) << AON_ACOMP0_EN_POS) +#define AON_ACOMP0_EN_UMSK (~(((1U << AON_ACOMP0_EN_LEN) - 1) << AON_ACOMP0_EN_POS)) +#define AON_ACOMP0_HYST_SELN AON_ACOMP0_HYST_SELN +#define AON_ACOMP0_HYST_SELN_POS (4U) +#define AON_ACOMP0_HYST_SELN_LEN (3U) +#define AON_ACOMP0_HYST_SELN_MSK (((1U << AON_ACOMP0_HYST_SELN_LEN) - 1) << AON_ACOMP0_HYST_SELN_POS) +#define AON_ACOMP0_HYST_SELN_UMSK (~(((1U << AON_ACOMP0_HYST_SELN_LEN) - 1) << AON_ACOMP0_HYST_SELN_POS)) +#define AON_ACOMP0_HYST_SELP AON_ACOMP0_HYST_SELP +#define AON_ACOMP0_HYST_SELP_POS (7U) +#define AON_ACOMP0_HYST_SELP_LEN (3U) +#define AON_ACOMP0_HYST_SELP_MSK (((1U << AON_ACOMP0_HYST_SELP_LEN) - 1) << AON_ACOMP0_HYST_SELP_POS) +#define AON_ACOMP0_HYST_SELP_UMSK (~(((1U << AON_ACOMP0_HYST_SELP_LEN) - 1) << AON_ACOMP0_HYST_SELP_POS)) +#define AON_ACOMP0_BIAS_PROG AON_ACOMP0_BIAS_PROG +#define AON_ACOMP0_BIAS_PROG_POS (10U) +#define AON_ACOMP0_BIAS_PROG_LEN (2U) +#define AON_ACOMP0_BIAS_PROG_MSK (((1U << AON_ACOMP0_BIAS_PROG_LEN) - 1) << AON_ACOMP0_BIAS_PROG_POS) +#define AON_ACOMP0_BIAS_PROG_UMSK (~(((1U << AON_ACOMP0_BIAS_PROG_LEN) - 1) << AON_ACOMP0_BIAS_PROG_POS)) +#define AON_ACOMP0_LEVEL_SEL AON_ACOMP0_LEVEL_SEL +#define AON_ACOMP0_LEVEL_SEL_POS (12U) +#define AON_ACOMP0_LEVEL_SEL_LEN (6U) +#define AON_ACOMP0_LEVEL_SEL_MSK (((1U << AON_ACOMP0_LEVEL_SEL_LEN) - 1) << AON_ACOMP0_LEVEL_SEL_POS) +#define AON_ACOMP0_LEVEL_SEL_UMSK (~(((1U << AON_ACOMP0_LEVEL_SEL_LEN) - 1) << AON_ACOMP0_LEVEL_SEL_POS)) +#define AON_ACOMP0_NEG_SEL AON_ACOMP0_NEG_SEL +#define AON_ACOMP0_NEG_SEL_POS (18U) +#define AON_ACOMP0_NEG_SEL_LEN (4U) +#define AON_ACOMP0_NEG_SEL_MSK (((1U << AON_ACOMP0_NEG_SEL_LEN) - 1) << AON_ACOMP0_NEG_SEL_POS) +#define AON_ACOMP0_NEG_SEL_UMSK (~(((1U << AON_ACOMP0_NEG_SEL_LEN) - 1) << AON_ACOMP0_NEG_SEL_POS)) +#define AON_ACOMP0_POS_SEL AON_ACOMP0_POS_SEL +#define AON_ACOMP0_POS_SEL_POS (22U) +#define AON_ACOMP0_POS_SEL_LEN (4U) +#define AON_ACOMP0_POS_SEL_MSK (((1U << AON_ACOMP0_POS_SEL_LEN) - 1) << AON_ACOMP0_POS_SEL_POS) +#define AON_ACOMP0_POS_SEL_UMSK (~(((1U << AON_ACOMP0_POS_SEL_LEN) - 1) << AON_ACOMP0_POS_SEL_POS)) +#define AON_ACOMP0_MUXEN AON_ACOMP0_MUXEN +#define AON_ACOMP0_MUXEN_POS (26U) +#define AON_ACOMP0_MUXEN_LEN (1U) +#define AON_ACOMP0_MUXEN_MSK (((1U << AON_ACOMP0_MUXEN_LEN) - 1) << AON_ACOMP0_MUXEN_POS) +#define AON_ACOMP0_MUXEN_UMSK (~(((1U << AON_ACOMP0_MUXEN_LEN) - 1) << AON_ACOMP0_MUXEN_POS)) + +/* 0x904 : acomp1_ctrl */ +#define AON_ACOMP1_CTRL_OFFSET (0x904) +#define AON_ACOMP1_EN AON_ACOMP1_EN +#define AON_ACOMP1_EN_POS (0U) +#define AON_ACOMP1_EN_LEN (1U) +#define AON_ACOMP1_EN_MSK (((1U << AON_ACOMP1_EN_LEN) - 1) << AON_ACOMP1_EN_POS) +#define AON_ACOMP1_EN_UMSK (~(((1U << AON_ACOMP1_EN_LEN) - 1) << AON_ACOMP1_EN_POS)) +#define AON_ACOMP1_HYST_SELN AON_ACOMP1_HYST_SELN +#define AON_ACOMP1_HYST_SELN_POS (4U) +#define AON_ACOMP1_HYST_SELN_LEN (3U) +#define AON_ACOMP1_HYST_SELN_MSK (((1U << AON_ACOMP1_HYST_SELN_LEN) - 1) << AON_ACOMP1_HYST_SELN_POS) +#define AON_ACOMP1_HYST_SELN_UMSK (~(((1U << AON_ACOMP1_HYST_SELN_LEN) - 1) << AON_ACOMP1_HYST_SELN_POS)) +#define AON_ACOMP1_HYST_SELP AON_ACOMP1_HYST_SELP +#define AON_ACOMP1_HYST_SELP_POS (7U) +#define AON_ACOMP1_HYST_SELP_LEN (3U) +#define AON_ACOMP1_HYST_SELP_MSK (((1U << AON_ACOMP1_HYST_SELP_LEN) - 1) << AON_ACOMP1_HYST_SELP_POS) +#define AON_ACOMP1_HYST_SELP_UMSK (~(((1U << AON_ACOMP1_HYST_SELP_LEN) - 1) << AON_ACOMP1_HYST_SELP_POS)) +#define AON_ACOMP1_BIAS_PROG AON_ACOMP1_BIAS_PROG +#define AON_ACOMP1_BIAS_PROG_POS (10U) +#define AON_ACOMP1_BIAS_PROG_LEN (2U) +#define AON_ACOMP1_BIAS_PROG_MSK (((1U << AON_ACOMP1_BIAS_PROG_LEN) - 1) << AON_ACOMP1_BIAS_PROG_POS) +#define AON_ACOMP1_BIAS_PROG_UMSK (~(((1U << AON_ACOMP1_BIAS_PROG_LEN) - 1) << AON_ACOMP1_BIAS_PROG_POS)) +#define AON_ACOMP1_LEVEL_SEL AON_ACOMP1_LEVEL_SEL +#define AON_ACOMP1_LEVEL_SEL_POS (12U) +#define AON_ACOMP1_LEVEL_SEL_LEN (6U) +#define AON_ACOMP1_LEVEL_SEL_MSK (((1U << AON_ACOMP1_LEVEL_SEL_LEN) - 1) << AON_ACOMP1_LEVEL_SEL_POS) +#define AON_ACOMP1_LEVEL_SEL_UMSK (~(((1U << AON_ACOMP1_LEVEL_SEL_LEN) - 1) << AON_ACOMP1_LEVEL_SEL_POS)) +#define AON_ACOMP1_NEG_SEL AON_ACOMP1_NEG_SEL +#define AON_ACOMP1_NEG_SEL_POS (18U) +#define AON_ACOMP1_NEG_SEL_LEN (4U) +#define AON_ACOMP1_NEG_SEL_MSK (((1U << AON_ACOMP1_NEG_SEL_LEN) - 1) << AON_ACOMP1_NEG_SEL_POS) +#define AON_ACOMP1_NEG_SEL_UMSK (~(((1U << AON_ACOMP1_NEG_SEL_LEN) - 1) << AON_ACOMP1_NEG_SEL_POS)) +#define AON_ACOMP1_POS_SEL AON_ACOMP1_POS_SEL +#define AON_ACOMP1_POS_SEL_POS (22U) +#define AON_ACOMP1_POS_SEL_LEN (4U) +#define AON_ACOMP1_POS_SEL_MSK (((1U << AON_ACOMP1_POS_SEL_LEN) - 1) << AON_ACOMP1_POS_SEL_POS) +#define AON_ACOMP1_POS_SEL_UMSK (~(((1U << AON_ACOMP1_POS_SEL_LEN) - 1) << AON_ACOMP1_POS_SEL_POS)) +#define AON_ACOMP1_MUXEN AON_ACOMP1_MUXEN +#define AON_ACOMP1_MUXEN_POS (26U) +#define AON_ACOMP1_MUXEN_LEN (1U) +#define AON_ACOMP1_MUXEN_MSK (((1U << AON_ACOMP1_MUXEN_LEN) - 1) << AON_ACOMP1_MUXEN_POS) +#define AON_ACOMP1_MUXEN_UMSK (~(((1U << AON_ACOMP1_MUXEN_LEN) - 1) << AON_ACOMP1_MUXEN_POS)) + +/* 0x908 : acomp_ctrl */ +#define AON_ACOMP_CTRL_OFFSET (0x908) +#define AON_ACOMP1_RSTN_ANA AON_ACOMP1_RSTN_ANA +#define AON_ACOMP1_RSTN_ANA_POS (0U) +#define AON_ACOMP1_RSTN_ANA_LEN (1U) +#define AON_ACOMP1_RSTN_ANA_MSK (((1U << AON_ACOMP1_RSTN_ANA_LEN) - 1) << AON_ACOMP1_RSTN_ANA_POS) +#define AON_ACOMP1_RSTN_ANA_UMSK (~(((1U << AON_ACOMP1_RSTN_ANA_LEN) - 1) << AON_ACOMP1_RSTN_ANA_POS)) +#define AON_ACOMP0_RSTN_ANA AON_ACOMP0_RSTN_ANA +#define AON_ACOMP0_RSTN_ANA_POS (1U) +#define AON_ACOMP0_RSTN_ANA_LEN (1U) +#define AON_ACOMP0_RSTN_ANA_MSK (((1U << AON_ACOMP0_RSTN_ANA_LEN) - 1) << AON_ACOMP0_RSTN_ANA_POS) +#define AON_ACOMP0_RSTN_ANA_UMSK (~(((1U << AON_ACOMP0_RSTN_ANA_LEN) - 1) << AON_ACOMP0_RSTN_ANA_POS)) +#define AON_ACOMP1_TEST_EN AON_ACOMP1_TEST_EN +#define AON_ACOMP1_TEST_EN_POS (8U) +#define AON_ACOMP1_TEST_EN_LEN (1U) +#define AON_ACOMP1_TEST_EN_MSK (((1U << AON_ACOMP1_TEST_EN_LEN) - 1) << AON_ACOMP1_TEST_EN_POS) +#define AON_ACOMP1_TEST_EN_UMSK (~(((1U << AON_ACOMP1_TEST_EN_LEN) - 1) << AON_ACOMP1_TEST_EN_POS)) +#define AON_ACOMP0_TEST_EN AON_ACOMP0_TEST_EN +#define AON_ACOMP0_TEST_EN_POS (9U) +#define AON_ACOMP0_TEST_EN_LEN (1U) +#define AON_ACOMP0_TEST_EN_MSK (((1U << AON_ACOMP0_TEST_EN_LEN) - 1) << AON_ACOMP0_TEST_EN_POS) +#define AON_ACOMP0_TEST_EN_UMSK (~(((1U << AON_ACOMP0_TEST_EN_LEN) - 1) << AON_ACOMP0_TEST_EN_POS)) +#define AON_ACOMP1_TEST_SEL AON_ACOMP1_TEST_SEL +#define AON_ACOMP1_TEST_SEL_POS (10U) +#define AON_ACOMP1_TEST_SEL_LEN (2U) +#define AON_ACOMP1_TEST_SEL_MSK (((1U << AON_ACOMP1_TEST_SEL_LEN) - 1) << AON_ACOMP1_TEST_SEL_POS) +#define AON_ACOMP1_TEST_SEL_UMSK (~(((1U << AON_ACOMP1_TEST_SEL_LEN) - 1) << AON_ACOMP1_TEST_SEL_POS)) +#define AON_ACOMP0_TEST_SEL AON_ACOMP0_TEST_SEL +#define AON_ACOMP0_TEST_SEL_POS (12U) +#define AON_ACOMP0_TEST_SEL_LEN (2U) +#define AON_ACOMP0_TEST_SEL_MSK (((1U << AON_ACOMP0_TEST_SEL_LEN) - 1) << AON_ACOMP0_TEST_SEL_POS) +#define AON_ACOMP0_TEST_SEL_UMSK (~(((1U << AON_ACOMP0_TEST_SEL_LEN) - 1) << AON_ACOMP0_TEST_SEL_POS)) +#define AON_ACOMP1_OUT_RAW AON_ACOMP1_OUT_RAW +#define AON_ACOMP1_OUT_RAW_POS (17U) +#define AON_ACOMP1_OUT_RAW_LEN (1U) +#define AON_ACOMP1_OUT_RAW_MSK (((1U << AON_ACOMP1_OUT_RAW_LEN) - 1) << AON_ACOMP1_OUT_RAW_POS) +#define AON_ACOMP1_OUT_RAW_UMSK (~(((1U << AON_ACOMP1_OUT_RAW_LEN) - 1) << AON_ACOMP1_OUT_RAW_POS)) +#define AON_ACOMP0_OUT_RAW AON_ACOMP0_OUT_RAW +#define AON_ACOMP0_OUT_RAW_POS (19U) +#define AON_ACOMP0_OUT_RAW_LEN (1U) +#define AON_ACOMP0_OUT_RAW_MSK (((1U << AON_ACOMP0_OUT_RAW_LEN) - 1) << AON_ACOMP0_OUT_RAW_POS) +#define AON_ACOMP0_OUT_RAW_UMSK (~(((1U << AON_ACOMP0_OUT_RAW_LEN) - 1) << AON_ACOMP0_OUT_RAW_POS)) +#define AON_ACOMP_VREF_SEL AON_ACOMP_VREF_SEL +#define AON_ACOMP_VREF_SEL_POS (24U) +#define AON_ACOMP_VREF_SEL_LEN (6U) +#define AON_ACOMP_VREF_SEL_MSK (((1U << AON_ACOMP_VREF_SEL_LEN) - 1) << AON_ACOMP_VREF_SEL_POS) +#define AON_ACOMP_VREF_SEL_UMSK (~(((1U << AON_ACOMP_VREF_SEL_LEN) - 1) << AON_ACOMP_VREF_SEL_POS)) +#define AON_ACOMP_RESERVED AON_ACOMP_RESERVED +#define AON_ACOMP_RESERVED_POS (30U) +#define AON_ACOMP_RESERVED_LEN (2U) +#define AON_ACOMP_RESERVED_MSK (((1U << AON_ACOMP_RESERVED_LEN) - 1) << AON_ACOMP_RESERVED_POS) +#define AON_ACOMP_RESERVED_UMSK (~(((1U << AON_ACOMP_RESERVED_LEN) - 1) << AON_ACOMP_RESERVED_POS)) + +/* 0x90C : gpadc_reg_cmd */ +#define AON_GPADC_REG_CMD_OFFSET (0x90C) +#define AON_GPADC_GLOBAL_EN AON_GPADC_GLOBAL_EN +#define AON_GPADC_GLOBAL_EN_POS (0U) +#define AON_GPADC_GLOBAL_EN_LEN (1U) +#define AON_GPADC_GLOBAL_EN_MSK (((1U << AON_GPADC_GLOBAL_EN_LEN) - 1) << AON_GPADC_GLOBAL_EN_POS) +#define AON_GPADC_GLOBAL_EN_UMSK (~(((1U << AON_GPADC_GLOBAL_EN_LEN) - 1) << AON_GPADC_GLOBAL_EN_POS)) +#define AON_GPADC_CONV_START AON_GPADC_CONV_START +#define AON_GPADC_CONV_START_POS (1U) +#define AON_GPADC_CONV_START_LEN (1U) +#define AON_GPADC_CONV_START_MSK (((1U << AON_GPADC_CONV_START_LEN) - 1) << AON_GPADC_CONV_START_POS) +#define AON_GPADC_CONV_START_UMSK (~(((1U << AON_GPADC_CONV_START_LEN) - 1) << AON_GPADC_CONV_START_POS)) +#define AON_GPADC_SOFT_RST AON_GPADC_SOFT_RST +#define AON_GPADC_SOFT_RST_POS (2U) +#define AON_GPADC_SOFT_RST_LEN (1U) +#define AON_GPADC_SOFT_RST_MSK (((1U << AON_GPADC_SOFT_RST_LEN) - 1) << AON_GPADC_SOFT_RST_POS) +#define AON_GPADC_SOFT_RST_UMSK (~(((1U << AON_GPADC_SOFT_RST_LEN) - 1) << AON_GPADC_SOFT_RST_POS)) +#define AON_GPADC_NEG_SEL AON_GPADC_NEG_SEL +#define AON_GPADC_NEG_SEL_POS (3U) +#define AON_GPADC_NEG_SEL_LEN (5U) +#define AON_GPADC_NEG_SEL_MSK (((1U << AON_GPADC_NEG_SEL_LEN) - 1) << AON_GPADC_NEG_SEL_POS) +#define AON_GPADC_NEG_SEL_UMSK (~(((1U << AON_GPADC_NEG_SEL_LEN) - 1) << AON_GPADC_NEG_SEL_POS)) +#define AON_GPADC_POS_SEL AON_GPADC_POS_SEL +#define AON_GPADC_POS_SEL_POS (8U) +#define AON_GPADC_POS_SEL_LEN (5U) +#define AON_GPADC_POS_SEL_MSK (((1U << AON_GPADC_POS_SEL_LEN) - 1) << AON_GPADC_POS_SEL_POS) +#define AON_GPADC_POS_SEL_UMSK (~(((1U << AON_GPADC_POS_SEL_LEN) - 1) << AON_GPADC_POS_SEL_POS)) +#define AON_GPADC_NEG_GND AON_GPADC_NEG_GND +#define AON_GPADC_NEG_GND_POS (13U) +#define AON_GPADC_NEG_GND_LEN (1U) +#define AON_GPADC_NEG_GND_MSK (((1U << AON_GPADC_NEG_GND_LEN) - 1) << AON_GPADC_NEG_GND_POS) +#define AON_GPADC_NEG_GND_UMSK (~(((1U << AON_GPADC_NEG_GND_LEN) - 1) << AON_GPADC_NEG_GND_POS)) +#define AON_GPADC_MICBIAS_EN AON_GPADC_MICBIAS_EN +#define AON_GPADC_MICBIAS_EN_POS (14U) +#define AON_GPADC_MICBIAS_EN_LEN (1U) +#define AON_GPADC_MICBIAS_EN_MSK (((1U << AON_GPADC_MICBIAS_EN_LEN) - 1) << AON_GPADC_MICBIAS_EN_POS) +#define AON_GPADC_MICBIAS_EN_UMSK (~(((1U << AON_GPADC_MICBIAS_EN_LEN) - 1) << AON_GPADC_MICBIAS_EN_POS)) +#define AON_GPADC_MICPGA_EN AON_GPADC_MICPGA_EN +#define AON_GPADC_MICPGA_EN_POS (15U) +#define AON_GPADC_MICPGA_EN_LEN (1U) +#define AON_GPADC_MICPGA_EN_MSK (((1U << AON_GPADC_MICPGA_EN_LEN) - 1) << AON_GPADC_MICPGA_EN_POS) +#define AON_GPADC_MICPGA_EN_UMSK (~(((1U << AON_GPADC_MICPGA_EN_LEN) - 1) << AON_GPADC_MICPGA_EN_POS)) +#define AON_GPADC_BYP_MICBOOST AON_GPADC_BYP_MICBOOST +#define AON_GPADC_BYP_MICBOOST_POS (16U) +#define AON_GPADC_BYP_MICBOOST_LEN (1U) +#define AON_GPADC_BYP_MICBOOST_MSK (((1U << AON_GPADC_BYP_MICBOOST_LEN) - 1) << AON_GPADC_BYP_MICBOOST_POS) +#define AON_GPADC_BYP_MICBOOST_UMSK (~(((1U << AON_GPADC_BYP_MICBOOST_LEN) - 1) << AON_GPADC_BYP_MICBOOST_POS)) +#define AON_GPADC_RCAL_EN AON_GPADC_RCAL_EN +#define AON_GPADC_RCAL_EN_POS (17U) +#define AON_GPADC_RCAL_EN_LEN (1U) +#define AON_GPADC_RCAL_EN_MSK (((1U << AON_GPADC_RCAL_EN_LEN) - 1) << AON_GPADC_RCAL_EN_POS) +#define AON_GPADC_RCAL_EN_UMSK (~(((1U << AON_GPADC_RCAL_EN_LEN) - 1) << AON_GPADC_RCAL_EN_POS)) +#define AON_GPADC_DWA_EN AON_GPADC_DWA_EN +#define AON_GPADC_DWA_EN_POS (18U) +#define AON_GPADC_DWA_EN_LEN (1U) +#define AON_GPADC_DWA_EN_MSK (((1U << AON_GPADC_DWA_EN_LEN) - 1) << AON_GPADC_DWA_EN_POS) +#define AON_GPADC_DWA_EN_UMSK (~(((1U << AON_GPADC_DWA_EN_LEN) - 1) << AON_GPADC_DWA_EN_POS)) +#define AON_GPADC_MIC2_DIFF AON_GPADC_MIC2_DIFF +#define AON_GPADC_MIC2_DIFF_POS (19U) +#define AON_GPADC_MIC2_DIFF_LEN (1U) +#define AON_GPADC_MIC2_DIFF_MSK (((1U << AON_GPADC_MIC2_DIFF_LEN) - 1) << AON_GPADC_MIC2_DIFF_POS) +#define AON_GPADC_MIC2_DIFF_UMSK (~(((1U << AON_GPADC_MIC2_DIFF_LEN) - 1) << AON_GPADC_MIC2_DIFF_POS)) +#define AON_GPADC_MIC1_DIFF AON_GPADC_MIC1_DIFF +#define AON_GPADC_MIC1_DIFF_POS (20U) +#define AON_GPADC_MIC1_DIFF_LEN (1U) +#define AON_GPADC_MIC1_DIFF_MSK (((1U << AON_GPADC_MIC1_DIFF_LEN) - 1) << AON_GPADC_MIC1_DIFF_POS) +#define AON_GPADC_MIC1_DIFF_UMSK (~(((1U << AON_GPADC_MIC1_DIFF_LEN) - 1) << AON_GPADC_MIC1_DIFF_POS)) +#define AON_GPADC_MIC_PGA2_GAIN AON_GPADC_MIC_PGA2_GAIN +#define AON_GPADC_MIC_PGA2_GAIN_POS (21U) +#define AON_GPADC_MIC_PGA2_GAIN_LEN (2U) +#define AON_GPADC_MIC_PGA2_GAIN_MSK (((1U << AON_GPADC_MIC_PGA2_GAIN_LEN) - 1) << AON_GPADC_MIC_PGA2_GAIN_POS) +#define AON_GPADC_MIC_PGA2_GAIN_UMSK (~(((1U << AON_GPADC_MIC_PGA2_GAIN_LEN) - 1) << AON_GPADC_MIC_PGA2_GAIN_POS)) +#define AON_GPADC_MICBOOST_32DB_EN AON_GPADC_MICBOOST_32DB_EN +#define AON_GPADC_MICBOOST_32DB_EN_POS (23U) +#define AON_GPADC_MICBOOST_32DB_EN_LEN (1U) +#define AON_GPADC_MICBOOST_32DB_EN_MSK (((1U << AON_GPADC_MICBOOST_32DB_EN_LEN) - 1) << AON_GPADC_MICBOOST_32DB_EN_POS) +#define AON_GPADC_MICBOOST_32DB_EN_UMSK (~(((1U << AON_GPADC_MICBOOST_32DB_EN_LEN) - 1) << AON_GPADC_MICBOOST_32DB_EN_POS)) +#define AON_GPADC_CHIP_SEN_PU AON_GPADC_CHIP_SEN_PU +#define AON_GPADC_CHIP_SEN_PU_POS (27U) +#define AON_GPADC_CHIP_SEN_PU_LEN (1U) +#define AON_GPADC_CHIP_SEN_PU_MSK (((1U << AON_GPADC_CHIP_SEN_PU_LEN) - 1) << AON_GPADC_CHIP_SEN_PU_POS) +#define AON_GPADC_CHIP_SEN_PU_UMSK (~(((1U << AON_GPADC_CHIP_SEN_PU_LEN) - 1) << AON_GPADC_CHIP_SEN_PU_POS)) +#define AON_GPADC_SEN_SEL AON_GPADC_SEN_SEL +#define AON_GPADC_SEN_SEL_POS (28U) +#define AON_GPADC_SEN_SEL_LEN (3U) +#define AON_GPADC_SEN_SEL_MSK (((1U << AON_GPADC_SEN_SEL_LEN) - 1) << AON_GPADC_SEN_SEL_POS) +#define AON_GPADC_SEN_SEL_UMSK (~(((1U << AON_GPADC_SEN_SEL_LEN) - 1) << AON_GPADC_SEN_SEL_POS)) +#define AON_GPADC_SEN_TEST_EN AON_GPADC_SEN_TEST_EN +#define AON_GPADC_SEN_TEST_EN_POS (31U) +#define AON_GPADC_SEN_TEST_EN_LEN (1U) +#define AON_GPADC_SEN_TEST_EN_MSK (((1U << AON_GPADC_SEN_TEST_EN_LEN) - 1) << AON_GPADC_SEN_TEST_EN_POS) +#define AON_GPADC_SEN_TEST_EN_UMSK (~(((1U << AON_GPADC_SEN_TEST_EN_LEN) - 1) << AON_GPADC_SEN_TEST_EN_POS)) + +/* 0x910 : gpadc_reg_config1 */ +#define AON_GPADC_REG_CONFIG1_OFFSET (0x910) +#define AON_GPADC_CAL_OS_EN AON_GPADC_CAL_OS_EN +#define AON_GPADC_CAL_OS_EN_POS (0U) +#define AON_GPADC_CAL_OS_EN_LEN (1U) +#define AON_GPADC_CAL_OS_EN_MSK (((1U << AON_GPADC_CAL_OS_EN_LEN) - 1) << AON_GPADC_CAL_OS_EN_POS) +#define AON_GPADC_CAL_OS_EN_UMSK (~(((1U << AON_GPADC_CAL_OS_EN_LEN) - 1) << AON_GPADC_CAL_OS_EN_POS)) +#define AON_GPADC_CONT_CONV_EN AON_GPADC_CONT_CONV_EN +#define AON_GPADC_CONT_CONV_EN_POS (1U) +#define AON_GPADC_CONT_CONV_EN_LEN (1U) +#define AON_GPADC_CONT_CONV_EN_MSK (((1U << AON_GPADC_CONT_CONV_EN_LEN) - 1) << AON_GPADC_CONT_CONV_EN_POS) +#define AON_GPADC_CONT_CONV_EN_UMSK (~(((1U << AON_GPADC_CONT_CONV_EN_LEN) - 1) << AON_GPADC_CONT_CONV_EN_POS)) +#define AON_GPADC_RES_SEL AON_GPADC_RES_SEL +#define AON_GPADC_RES_SEL_POS (2U) +#define AON_GPADC_RES_SEL_LEN (3U) +#define AON_GPADC_RES_SEL_MSK (((1U << AON_GPADC_RES_SEL_LEN) - 1) << AON_GPADC_RES_SEL_POS) +#define AON_GPADC_RES_SEL_UMSK (~(((1U << AON_GPADC_RES_SEL_LEN) - 1) << AON_GPADC_RES_SEL_POS)) +#define AON_GPADC_VCM_SEL_EN AON_GPADC_VCM_SEL_EN +#define AON_GPADC_VCM_SEL_EN_POS (8U) +#define AON_GPADC_VCM_SEL_EN_LEN (1U) +#define AON_GPADC_VCM_SEL_EN_MSK (((1U << AON_GPADC_VCM_SEL_EN_LEN) - 1) << AON_GPADC_VCM_SEL_EN_POS) +#define AON_GPADC_VCM_SEL_EN_UMSK (~(((1U << AON_GPADC_VCM_SEL_EN_LEN) - 1) << AON_GPADC_VCM_SEL_EN_POS)) +#define AON_GPADC_VCM_HYST_SEL AON_GPADC_VCM_HYST_SEL +#define AON_GPADC_VCM_HYST_SEL_POS (9U) +#define AON_GPADC_VCM_HYST_SEL_LEN (1U) +#define AON_GPADC_VCM_HYST_SEL_MSK (((1U << AON_GPADC_VCM_HYST_SEL_LEN) - 1) << AON_GPADC_VCM_HYST_SEL_POS) +#define AON_GPADC_VCM_HYST_SEL_UMSK (~(((1U << AON_GPADC_VCM_HYST_SEL_LEN) - 1) << AON_GPADC_VCM_HYST_SEL_POS)) +#define AON_GPADC_LOWV_DET_EN AON_GPADC_LOWV_DET_EN +#define AON_GPADC_LOWV_DET_EN_POS (10U) +#define AON_GPADC_LOWV_DET_EN_LEN (1U) +#define AON_GPADC_LOWV_DET_EN_MSK (((1U << AON_GPADC_LOWV_DET_EN_LEN) - 1) << AON_GPADC_LOWV_DET_EN_POS) +#define AON_GPADC_LOWV_DET_EN_UMSK (~(((1U << AON_GPADC_LOWV_DET_EN_LEN) - 1) << AON_GPADC_LOWV_DET_EN_POS)) +#define AON_GPADC_PWM_TRG_EN AON_GPADC_PWM_TRG_EN +#define AON_GPADC_PWM_TRG_EN_POS (11U) +#define AON_GPADC_PWM_TRG_EN_LEN (1U) +#define AON_GPADC_PWM_TRG_EN_MSK (((1U << AON_GPADC_PWM_TRG_EN_LEN) - 1) << AON_GPADC_PWM_TRG_EN_POS) +#define AON_GPADC_PWM_TRG_EN_UMSK (~(((1U << AON_GPADC_PWM_TRG_EN_LEN) - 1) << AON_GPADC_PWM_TRG_EN_POS)) +#define AON_GPADC_CLK_ANA_DLY AON_GPADC_CLK_ANA_DLY +#define AON_GPADC_CLK_ANA_DLY_POS (12U) +#define AON_GPADC_CLK_ANA_DLY_LEN (4U) +#define AON_GPADC_CLK_ANA_DLY_MSK (((1U << AON_GPADC_CLK_ANA_DLY_LEN) - 1) << AON_GPADC_CLK_ANA_DLY_POS) +#define AON_GPADC_CLK_ANA_DLY_UMSK (~(((1U << AON_GPADC_CLK_ANA_DLY_LEN) - 1) << AON_GPADC_CLK_ANA_DLY_POS)) +#define AON_GPADC_CLK_ANA_DLY_EN AON_GPADC_CLK_ANA_DLY_EN +#define AON_GPADC_CLK_ANA_DLY_EN_POS (16U) +#define AON_GPADC_CLK_ANA_DLY_EN_LEN (1U) +#define AON_GPADC_CLK_ANA_DLY_EN_MSK (((1U << AON_GPADC_CLK_ANA_DLY_EN_LEN) - 1) << AON_GPADC_CLK_ANA_DLY_EN_POS) +#define AON_GPADC_CLK_ANA_DLY_EN_UMSK (~(((1U << AON_GPADC_CLK_ANA_DLY_EN_LEN) - 1) << AON_GPADC_CLK_ANA_DLY_EN_POS)) +#define AON_GPADC_CLK_ANA_INV AON_GPADC_CLK_ANA_INV +#define AON_GPADC_CLK_ANA_INV_POS (17U) +#define AON_GPADC_CLK_ANA_INV_LEN (1U) +#define AON_GPADC_CLK_ANA_INV_MSK (((1U << AON_GPADC_CLK_ANA_INV_LEN) - 1) << AON_GPADC_CLK_ANA_INV_POS) +#define AON_GPADC_CLK_ANA_INV_UMSK (~(((1U << AON_GPADC_CLK_ANA_INV_LEN) - 1) << AON_GPADC_CLK_ANA_INV_POS)) +#define AON_GPADC_CLK_DIV_RATIO AON_GPADC_CLK_DIV_RATIO +#define AON_GPADC_CLK_DIV_RATIO_POS (18U) +#define AON_GPADC_CLK_DIV_RATIO_LEN (3U) +#define AON_GPADC_CLK_DIV_RATIO_MSK (((1U << AON_GPADC_CLK_DIV_RATIO_LEN) - 1) << AON_GPADC_CLK_DIV_RATIO_POS) +#define AON_GPADC_CLK_DIV_RATIO_UMSK (~(((1U << AON_GPADC_CLK_DIV_RATIO_LEN) - 1) << AON_GPADC_CLK_DIV_RATIO_POS)) +#define AON_GPADC_SCAN_LENGTH AON_GPADC_SCAN_LENGTH +#define AON_GPADC_SCAN_LENGTH_POS (21U) +#define AON_GPADC_SCAN_LENGTH_LEN (4U) +#define AON_GPADC_SCAN_LENGTH_MSK (((1U << AON_GPADC_SCAN_LENGTH_LEN) - 1) << AON_GPADC_SCAN_LENGTH_POS) +#define AON_GPADC_SCAN_LENGTH_UMSK (~(((1U << AON_GPADC_SCAN_LENGTH_LEN) - 1) << AON_GPADC_SCAN_LENGTH_POS)) +#define AON_GPADC_SCAN_EN AON_GPADC_SCAN_EN +#define AON_GPADC_SCAN_EN_POS (25U) +#define AON_GPADC_SCAN_EN_LEN (1U) +#define AON_GPADC_SCAN_EN_MSK (((1U << AON_GPADC_SCAN_EN_LEN) - 1) << AON_GPADC_SCAN_EN_POS) +#define AON_GPADC_SCAN_EN_UMSK (~(((1U << AON_GPADC_SCAN_EN_LEN) - 1) << AON_GPADC_SCAN_EN_POS)) +#define AON_GPADC_DITHER_EN AON_GPADC_DITHER_EN +#define AON_GPADC_DITHER_EN_POS (26U) +#define AON_GPADC_DITHER_EN_LEN (1U) +#define AON_GPADC_DITHER_EN_MSK (((1U << AON_GPADC_DITHER_EN_LEN) - 1) << AON_GPADC_DITHER_EN_POS) +#define AON_GPADC_DITHER_EN_UMSK (~(((1U << AON_GPADC_DITHER_EN_LEN) - 1) << AON_GPADC_DITHER_EN_POS)) +#define AON_GPADC_V11_SEL AON_GPADC_V11_SEL +#define AON_GPADC_V11_SEL_POS (27U) +#define AON_GPADC_V11_SEL_LEN (2U) +#define AON_GPADC_V11_SEL_MSK (((1U << AON_GPADC_V11_SEL_LEN) - 1) << AON_GPADC_V11_SEL_POS) +#define AON_GPADC_V11_SEL_UMSK (~(((1U << AON_GPADC_V11_SEL_LEN) - 1) << AON_GPADC_V11_SEL_POS)) +#define AON_GPADC_V18_SEL AON_GPADC_V18_SEL +#define AON_GPADC_V18_SEL_POS (29U) +#define AON_GPADC_V18_SEL_LEN (2U) +#define AON_GPADC_V18_SEL_MSK (((1U << AON_GPADC_V18_SEL_LEN) - 1) << AON_GPADC_V18_SEL_POS) +#define AON_GPADC_V18_SEL_UMSK (~(((1U << AON_GPADC_V18_SEL_LEN) - 1) << AON_GPADC_V18_SEL_POS)) + +/* 0x914 : gpadc_reg_config2 */ +#define AON_GPADC_REG_CONFIG2_OFFSET (0x914) +#define AON_GPADC_DIFF_MODE AON_GPADC_DIFF_MODE +#define AON_GPADC_DIFF_MODE_POS (2U) +#define AON_GPADC_DIFF_MODE_LEN (1U) +#define AON_GPADC_DIFF_MODE_MSK (((1U << AON_GPADC_DIFF_MODE_LEN) - 1) << AON_GPADC_DIFF_MODE_POS) +#define AON_GPADC_DIFF_MODE_UMSK (~(((1U << AON_GPADC_DIFF_MODE_LEN) - 1) << AON_GPADC_DIFF_MODE_POS)) +#define AON_GPADC_VREF_SEL AON_GPADC_VREF_SEL +#define AON_GPADC_VREF_SEL_POS (3U) +#define AON_GPADC_VREF_SEL_LEN (1U) +#define AON_GPADC_VREF_SEL_MSK (((1U << AON_GPADC_VREF_SEL_LEN) - 1) << AON_GPADC_VREF_SEL_POS) +#define AON_GPADC_VREF_SEL_UMSK (~(((1U << AON_GPADC_VREF_SEL_LEN) - 1) << AON_GPADC_VREF_SEL_POS)) +#define AON_GPADC_VBAT_EN AON_GPADC_VBAT_EN +#define AON_GPADC_VBAT_EN_POS (4U) +#define AON_GPADC_VBAT_EN_LEN (1U) +#define AON_GPADC_VBAT_EN_MSK (((1U << AON_GPADC_VBAT_EN_LEN) - 1) << AON_GPADC_VBAT_EN_POS) +#define AON_GPADC_VBAT_EN_UMSK (~(((1U << AON_GPADC_VBAT_EN_LEN) - 1) << AON_GPADC_VBAT_EN_POS)) +#define AON_GPADC_TSEXT_SEL AON_GPADC_TSEXT_SEL +#define AON_GPADC_TSEXT_SEL_POS (5U) +#define AON_GPADC_TSEXT_SEL_LEN (1U) +#define AON_GPADC_TSEXT_SEL_MSK (((1U << AON_GPADC_TSEXT_SEL_LEN) - 1) << AON_GPADC_TSEXT_SEL_POS) +#define AON_GPADC_TSEXT_SEL_UMSK (~(((1U << AON_GPADC_TSEXT_SEL_LEN) - 1) << AON_GPADC_TSEXT_SEL_POS)) +#define AON_GPADC_TS_EN AON_GPADC_TS_EN +#define AON_GPADC_TS_EN_POS (6U) +#define AON_GPADC_TS_EN_LEN (1U) +#define AON_GPADC_TS_EN_MSK (((1U << AON_GPADC_TS_EN_LEN) - 1) << AON_GPADC_TS_EN_POS) +#define AON_GPADC_TS_EN_UMSK (~(((1U << AON_GPADC_TS_EN_LEN) - 1) << AON_GPADC_TS_EN_POS)) +#define AON_GPADC_PGA_VCM AON_GPADC_PGA_VCM +#define AON_GPADC_PGA_VCM_POS (7U) +#define AON_GPADC_PGA_VCM_LEN (2U) +#define AON_GPADC_PGA_VCM_MSK (((1U << AON_GPADC_PGA_VCM_LEN) - 1) << AON_GPADC_PGA_VCM_POS) +#define AON_GPADC_PGA_VCM_UMSK (~(((1U << AON_GPADC_PGA_VCM_LEN) - 1) << AON_GPADC_PGA_VCM_POS)) +#define AON_GPADC_PGA_OS_CAL AON_GPADC_PGA_OS_CAL +#define AON_GPADC_PGA_OS_CAL_POS (9U) +#define AON_GPADC_PGA_OS_CAL_LEN (4U) +#define AON_GPADC_PGA_OS_CAL_MSK (((1U << AON_GPADC_PGA_OS_CAL_LEN) - 1) << AON_GPADC_PGA_OS_CAL_POS) +#define AON_GPADC_PGA_OS_CAL_UMSK (~(((1U << AON_GPADC_PGA_OS_CAL_LEN) - 1) << AON_GPADC_PGA_OS_CAL_POS)) +#define AON_GPADC_PGA_EN AON_GPADC_PGA_EN +#define AON_GPADC_PGA_EN_POS (13U) +#define AON_GPADC_PGA_EN_LEN (1U) +#define AON_GPADC_PGA_EN_MSK (((1U << AON_GPADC_PGA_EN_LEN) - 1) << AON_GPADC_PGA_EN_POS) +#define AON_GPADC_PGA_EN_UMSK (~(((1U << AON_GPADC_PGA_EN_LEN) - 1) << AON_GPADC_PGA_EN_POS)) +#define AON_GPADC_PGA_VCMI_EN AON_GPADC_PGA_VCMI_EN +#define AON_GPADC_PGA_VCMI_EN_POS (14U) +#define AON_GPADC_PGA_VCMI_EN_LEN (1U) +#define AON_GPADC_PGA_VCMI_EN_MSK (((1U << AON_GPADC_PGA_VCMI_EN_LEN) - 1) << AON_GPADC_PGA_VCMI_EN_POS) +#define AON_GPADC_PGA_VCMI_EN_UMSK (~(((1U << AON_GPADC_PGA_VCMI_EN_LEN) - 1) << AON_GPADC_PGA_VCMI_EN_POS)) +#define AON_GPADC_CHOP_MODE AON_GPADC_CHOP_MODE +#define AON_GPADC_CHOP_MODE_POS (15U) +#define AON_GPADC_CHOP_MODE_LEN (2U) +#define AON_GPADC_CHOP_MODE_MSK (((1U << AON_GPADC_CHOP_MODE_LEN) - 1) << AON_GPADC_CHOP_MODE_POS) +#define AON_GPADC_CHOP_MODE_UMSK (~(((1U << AON_GPADC_CHOP_MODE_LEN) - 1) << AON_GPADC_CHOP_MODE_POS)) +#define AON_GPADC_BIAS_SEL AON_GPADC_BIAS_SEL +#define AON_GPADC_BIAS_SEL_POS (17U) +#define AON_GPADC_BIAS_SEL_LEN (1U) +#define AON_GPADC_BIAS_SEL_MSK (((1U << AON_GPADC_BIAS_SEL_LEN) - 1) << AON_GPADC_BIAS_SEL_POS) +#define AON_GPADC_BIAS_SEL_UMSK (~(((1U << AON_GPADC_BIAS_SEL_LEN) - 1) << AON_GPADC_BIAS_SEL_POS)) +#define AON_GPADC_TEST_EN AON_GPADC_TEST_EN +#define AON_GPADC_TEST_EN_POS (18U) +#define AON_GPADC_TEST_EN_LEN (1U) +#define AON_GPADC_TEST_EN_MSK (((1U << AON_GPADC_TEST_EN_LEN) - 1) << AON_GPADC_TEST_EN_POS) +#define AON_GPADC_TEST_EN_UMSK (~(((1U << AON_GPADC_TEST_EN_LEN) - 1) << AON_GPADC_TEST_EN_POS)) +#define AON_GPADC_TEST_SEL AON_GPADC_TEST_SEL +#define AON_GPADC_TEST_SEL_POS (19U) +#define AON_GPADC_TEST_SEL_LEN (3U) +#define AON_GPADC_TEST_SEL_MSK (((1U << AON_GPADC_TEST_SEL_LEN) - 1) << AON_GPADC_TEST_SEL_POS) +#define AON_GPADC_TEST_SEL_UMSK (~(((1U << AON_GPADC_TEST_SEL_LEN) - 1) << AON_GPADC_TEST_SEL_POS)) +#define AON_GPADC_PGA2_GAIN AON_GPADC_PGA2_GAIN +#define AON_GPADC_PGA2_GAIN_POS (22U) +#define AON_GPADC_PGA2_GAIN_LEN (3U) +#define AON_GPADC_PGA2_GAIN_MSK (((1U << AON_GPADC_PGA2_GAIN_LEN) - 1) << AON_GPADC_PGA2_GAIN_POS) +#define AON_GPADC_PGA2_GAIN_UMSK (~(((1U << AON_GPADC_PGA2_GAIN_LEN) - 1) << AON_GPADC_PGA2_GAIN_POS)) +#define AON_GPADC_PGA1_GAIN AON_GPADC_PGA1_GAIN +#define AON_GPADC_PGA1_GAIN_POS (25U) +#define AON_GPADC_PGA1_GAIN_LEN (3U) +#define AON_GPADC_PGA1_GAIN_MSK (((1U << AON_GPADC_PGA1_GAIN_LEN) - 1) << AON_GPADC_PGA1_GAIN_POS) +#define AON_GPADC_PGA1_GAIN_UMSK (~(((1U << AON_GPADC_PGA1_GAIN_LEN) - 1) << AON_GPADC_PGA1_GAIN_POS)) +#define AON_GPADC_DLY_SEL AON_GPADC_DLY_SEL +#define AON_GPADC_DLY_SEL_POS (28U) +#define AON_GPADC_DLY_SEL_LEN (3U) +#define AON_GPADC_DLY_SEL_MSK (((1U << AON_GPADC_DLY_SEL_LEN) - 1) << AON_GPADC_DLY_SEL_POS) +#define AON_GPADC_DLY_SEL_UMSK (~(((1U << AON_GPADC_DLY_SEL_LEN) - 1) << AON_GPADC_DLY_SEL_POS)) +#define AON_GPADC_TSVBE_LOW AON_GPADC_TSVBE_LOW +#define AON_GPADC_TSVBE_LOW_POS (31U) +#define AON_GPADC_TSVBE_LOW_LEN (1U) +#define AON_GPADC_TSVBE_LOW_MSK (((1U << AON_GPADC_TSVBE_LOW_LEN) - 1) << AON_GPADC_TSVBE_LOW_POS) +#define AON_GPADC_TSVBE_LOW_UMSK (~(((1U << AON_GPADC_TSVBE_LOW_LEN) - 1) << AON_GPADC_TSVBE_LOW_POS)) + +/* 0x918 : adc converation sequence 1 */ +#define AON_GPADC_REG_SCN_POS1_OFFSET (0x918) +#define AON_GPADC_SCAN_POS_0 AON_GPADC_SCAN_POS_0 +#define AON_GPADC_SCAN_POS_0_POS (0U) +#define AON_GPADC_SCAN_POS_0_LEN (5U) +#define AON_GPADC_SCAN_POS_0_MSK (((1U << AON_GPADC_SCAN_POS_0_LEN) - 1) << AON_GPADC_SCAN_POS_0_POS) +#define AON_GPADC_SCAN_POS_0_UMSK (~(((1U << AON_GPADC_SCAN_POS_0_LEN) - 1) << AON_GPADC_SCAN_POS_0_POS)) +#define AON_GPADC_SCAN_POS_1 AON_GPADC_SCAN_POS_1 +#define AON_GPADC_SCAN_POS_1_POS (5U) +#define AON_GPADC_SCAN_POS_1_LEN (5U) +#define AON_GPADC_SCAN_POS_1_MSK (((1U << AON_GPADC_SCAN_POS_1_LEN) - 1) << AON_GPADC_SCAN_POS_1_POS) +#define AON_GPADC_SCAN_POS_1_UMSK (~(((1U << AON_GPADC_SCAN_POS_1_LEN) - 1) << AON_GPADC_SCAN_POS_1_POS)) +#define AON_GPADC_SCAN_POS_2 AON_GPADC_SCAN_POS_2 +#define AON_GPADC_SCAN_POS_2_POS (10U) +#define AON_GPADC_SCAN_POS_2_LEN (5U) +#define AON_GPADC_SCAN_POS_2_MSK (((1U << AON_GPADC_SCAN_POS_2_LEN) - 1) << AON_GPADC_SCAN_POS_2_POS) +#define AON_GPADC_SCAN_POS_2_UMSK (~(((1U << AON_GPADC_SCAN_POS_2_LEN) - 1) << AON_GPADC_SCAN_POS_2_POS)) +#define AON_GPADC_SCAN_POS_3 AON_GPADC_SCAN_POS_3 +#define AON_GPADC_SCAN_POS_3_POS (15U) +#define AON_GPADC_SCAN_POS_3_LEN (5U) +#define AON_GPADC_SCAN_POS_3_MSK (((1U << AON_GPADC_SCAN_POS_3_LEN) - 1) << AON_GPADC_SCAN_POS_3_POS) +#define AON_GPADC_SCAN_POS_3_UMSK (~(((1U << AON_GPADC_SCAN_POS_3_LEN) - 1) << AON_GPADC_SCAN_POS_3_POS)) +#define AON_GPADC_SCAN_POS_4 AON_GPADC_SCAN_POS_4 +#define AON_GPADC_SCAN_POS_4_POS (20U) +#define AON_GPADC_SCAN_POS_4_LEN (5U) +#define AON_GPADC_SCAN_POS_4_MSK (((1U << AON_GPADC_SCAN_POS_4_LEN) - 1) << AON_GPADC_SCAN_POS_4_POS) +#define AON_GPADC_SCAN_POS_4_UMSK (~(((1U << AON_GPADC_SCAN_POS_4_LEN) - 1) << AON_GPADC_SCAN_POS_4_POS)) +#define AON_GPADC_SCAN_POS_5 AON_GPADC_SCAN_POS_5 +#define AON_GPADC_SCAN_POS_5_POS (25U) +#define AON_GPADC_SCAN_POS_5_LEN (5U) +#define AON_GPADC_SCAN_POS_5_MSK (((1U << AON_GPADC_SCAN_POS_5_LEN) - 1) << AON_GPADC_SCAN_POS_5_POS) +#define AON_GPADC_SCAN_POS_5_UMSK (~(((1U << AON_GPADC_SCAN_POS_5_LEN) - 1) << AON_GPADC_SCAN_POS_5_POS)) + +/* 0x91C : adc converation sequence 2 */ +#define AON_GPADC_REG_SCN_POS2_OFFSET (0x91C) +#define AON_GPADC_SCAN_POS_6 AON_GPADC_SCAN_POS_6 +#define AON_GPADC_SCAN_POS_6_POS (0U) +#define AON_GPADC_SCAN_POS_6_LEN (5U) +#define AON_GPADC_SCAN_POS_6_MSK (((1U << AON_GPADC_SCAN_POS_6_LEN) - 1) << AON_GPADC_SCAN_POS_6_POS) +#define AON_GPADC_SCAN_POS_6_UMSK (~(((1U << AON_GPADC_SCAN_POS_6_LEN) - 1) << AON_GPADC_SCAN_POS_6_POS)) +#define AON_GPADC_SCAN_POS_7 AON_GPADC_SCAN_POS_7 +#define AON_GPADC_SCAN_POS_7_POS (5U) +#define AON_GPADC_SCAN_POS_7_LEN (5U) +#define AON_GPADC_SCAN_POS_7_MSK (((1U << AON_GPADC_SCAN_POS_7_LEN) - 1) << AON_GPADC_SCAN_POS_7_POS) +#define AON_GPADC_SCAN_POS_7_UMSK (~(((1U << AON_GPADC_SCAN_POS_7_LEN) - 1) << AON_GPADC_SCAN_POS_7_POS)) +#define AON_GPADC_SCAN_POS_8 AON_GPADC_SCAN_POS_8 +#define AON_GPADC_SCAN_POS_8_POS (10U) +#define AON_GPADC_SCAN_POS_8_LEN (5U) +#define AON_GPADC_SCAN_POS_8_MSK (((1U << AON_GPADC_SCAN_POS_8_LEN) - 1) << AON_GPADC_SCAN_POS_8_POS) +#define AON_GPADC_SCAN_POS_8_UMSK (~(((1U << AON_GPADC_SCAN_POS_8_LEN) - 1) << AON_GPADC_SCAN_POS_8_POS)) +#define AON_GPADC_SCAN_POS_9 AON_GPADC_SCAN_POS_9 +#define AON_GPADC_SCAN_POS_9_POS (15U) +#define AON_GPADC_SCAN_POS_9_LEN (5U) +#define AON_GPADC_SCAN_POS_9_MSK (((1U << AON_GPADC_SCAN_POS_9_LEN) - 1) << AON_GPADC_SCAN_POS_9_POS) +#define AON_GPADC_SCAN_POS_9_UMSK (~(((1U << AON_GPADC_SCAN_POS_9_LEN) - 1) << AON_GPADC_SCAN_POS_9_POS)) +#define AON_GPADC_SCAN_POS_10 AON_GPADC_SCAN_POS_10 +#define AON_GPADC_SCAN_POS_10_POS (20U) +#define AON_GPADC_SCAN_POS_10_LEN (5U) +#define AON_GPADC_SCAN_POS_10_MSK (((1U << AON_GPADC_SCAN_POS_10_LEN) - 1) << AON_GPADC_SCAN_POS_10_POS) +#define AON_GPADC_SCAN_POS_10_UMSK (~(((1U << AON_GPADC_SCAN_POS_10_LEN) - 1) << AON_GPADC_SCAN_POS_10_POS)) +#define AON_GPADC_SCAN_POS_11 AON_GPADC_SCAN_POS_11 +#define AON_GPADC_SCAN_POS_11_POS (25U) +#define AON_GPADC_SCAN_POS_11_LEN (5U) +#define AON_GPADC_SCAN_POS_11_MSK (((1U << AON_GPADC_SCAN_POS_11_LEN) - 1) << AON_GPADC_SCAN_POS_11_POS) +#define AON_GPADC_SCAN_POS_11_UMSK (~(((1U << AON_GPADC_SCAN_POS_11_LEN) - 1) << AON_GPADC_SCAN_POS_11_POS)) + +/* 0x920 : adc converation sequence 3 */ +#define AON_GPADC_REG_SCN_NEG1_OFFSET (0x920) +#define AON_GPADC_SCAN_NEG_0 AON_GPADC_SCAN_NEG_0 +#define AON_GPADC_SCAN_NEG_0_POS (0U) +#define AON_GPADC_SCAN_NEG_0_LEN (5U) +#define AON_GPADC_SCAN_NEG_0_MSK (((1U << AON_GPADC_SCAN_NEG_0_LEN) - 1) << AON_GPADC_SCAN_NEG_0_POS) +#define AON_GPADC_SCAN_NEG_0_UMSK (~(((1U << AON_GPADC_SCAN_NEG_0_LEN) - 1) << AON_GPADC_SCAN_NEG_0_POS)) +#define AON_GPADC_SCAN_NEG_1 AON_GPADC_SCAN_NEG_1 +#define AON_GPADC_SCAN_NEG_1_POS (5U) +#define AON_GPADC_SCAN_NEG_1_LEN (5U) +#define AON_GPADC_SCAN_NEG_1_MSK (((1U << AON_GPADC_SCAN_NEG_1_LEN) - 1) << AON_GPADC_SCAN_NEG_1_POS) +#define AON_GPADC_SCAN_NEG_1_UMSK (~(((1U << AON_GPADC_SCAN_NEG_1_LEN) - 1) << AON_GPADC_SCAN_NEG_1_POS)) +#define AON_GPADC_SCAN_NEG_2 AON_GPADC_SCAN_NEG_2 +#define AON_GPADC_SCAN_NEG_2_POS (10U) +#define AON_GPADC_SCAN_NEG_2_LEN (5U) +#define AON_GPADC_SCAN_NEG_2_MSK (((1U << AON_GPADC_SCAN_NEG_2_LEN) - 1) << AON_GPADC_SCAN_NEG_2_POS) +#define AON_GPADC_SCAN_NEG_2_UMSK (~(((1U << AON_GPADC_SCAN_NEG_2_LEN) - 1) << AON_GPADC_SCAN_NEG_2_POS)) +#define AON_GPADC_SCAN_NEG_3 AON_GPADC_SCAN_NEG_3 +#define AON_GPADC_SCAN_NEG_3_POS (15U) +#define AON_GPADC_SCAN_NEG_3_LEN (5U) +#define AON_GPADC_SCAN_NEG_3_MSK (((1U << AON_GPADC_SCAN_NEG_3_LEN) - 1) << AON_GPADC_SCAN_NEG_3_POS) +#define AON_GPADC_SCAN_NEG_3_UMSK (~(((1U << AON_GPADC_SCAN_NEG_3_LEN) - 1) << AON_GPADC_SCAN_NEG_3_POS)) +#define AON_GPADC_SCAN_NEG_4 AON_GPADC_SCAN_NEG_4 +#define AON_GPADC_SCAN_NEG_4_POS (20U) +#define AON_GPADC_SCAN_NEG_4_LEN (5U) +#define AON_GPADC_SCAN_NEG_4_MSK (((1U << AON_GPADC_SCAN_NEG_4_LEN) - 1) << AON_GPADC_SCAN_NEG_4_POS) +#define AON_GPADC_SCAN_NEG_4_UMSK (~(((1U << AON_GPADC_SCAN_NEG_4_LEN) - 1) << AON_GPADC_SCAN_NEG_4_POS)) +#define AON_GPADC_SCAN_NEG_5 AON_GPADC_SCAN_NEG_5 +#define AON_GPADC_SCAN_NEG_5_POS (25U) +#define AON_GPADC_SCAN_NEG_5_LEN (5U) +#define AON_GPADC_SCAN_NEG_5_MSK (((1U << AON_GPADC_SCAN_NEG_5_LEN) - 1) << AON_GPADC_SCAN_NEG_5_POS) +#define AON_GPADC_SCAN_NEG_5_UMSK (~(((1U << AON_GPADC_SCAN_NEG_5_LEN) - 1) << AON_GPADC_SCAN_NEG_5_POS)) + +/* 0x924 : adc converation sequence 4 */ +#define AON_GPADC_REG_SCN_NEG2_OFFSET (0x924) +#define AON_GPADC_SCAN_NEG_6 AON_GPADC_SCAN_NEG_6 +#define AON_GPADC_SCAN_NEG_6_POS (0U) +#define AON_GPADC_SCAN_NEG_6_LEN (5U) +#define AON_GPADC_SCAN_NEG_6_MSK (((1U << AON_GPADC_SCAN_NEG_6_LEN) - 1) << AON_GPADC_SCAN_NEG_6_POS) +#define AON_GPADC_SCAN_NEG_6_UMSK (~(((1U << AON_GPADC_SCAN_NEG_6_LEN) - 1) << AON_GPADC_SCAN_NEG_6_POS)) +#define AON_GPADC_SCAN_NEG_7 AON_GPADC_SCAN_NEG_7 +#define AON_GPADC_SCAN_NEG_7_POS (5U) +#define AON_GPADC_SCAN_NEG_7_LEN (5U) +#define AON_GPADC_SCAN_NEG_7_MSK (((1U << AON_GPADC_SCAN_NEG_7_LEN) - 1) << AON_GPADC_SCAN_NEG_7_POS) +#define AON_GPADC_SCAN_NEG_7_UMSK (~(((1U << AON_GPADC_SCAN_NEG_7_LEN) - 1) << AON_GPADC_SCAN_NEG_7_POS)) +#define AON_GPADC_SCAN_NEG_8 AON_GPADC_SCAN_NEG_8 +#define AON_GPADC_SCAN_NEG_8_POS (10U) +#define AON_GPADC_SCAN_NEG_8_LEN (5U) +#define AON_GPADC_SCAN_NEG_8_MSK (((1U << AON_GPADC_SCAN_NEG_8_LEN) - 1) << AON_GPADC_SCAN_NEG_8_POS) +#define AON_GPADC_SCAN_NEG_8_UMSK (~(((1U << AON_GPADC_SCAN_NEG_8_LEN) - 1) << AON_GPADC_SCAN_NEG_8_POS)) +#define AON_GPADC_SCAN_NEG_9 AON_GPADC_SCAN_NEG_9 +#define AON_GPADC_SCAN_NEG_9_POS (15U) +#define AON_GPADC_SCAN_NEG_9_LEN (5U) +#define AON_GPADC_SCAN_NEG_9_MSK (((1U << AON_GPADC_SCAN_NEG_9_LEN) - 1) << AON_GPADC_SCAN_NEG_9_POS) +#define AON_GPADC_SCAN_NEG_9_UMSK (~(((1U << AON_GPADC_SCAN_NEG_9_LEN) - 1) << AON_GPADC_SCAN_NEG_9_POS)) +#define AON_GPADC_SCAN_NEG_10 AON_GPADC_SCAN_NEG_10 +#define AON_GPADC_SCAN_NEG_10_POS (20U) +#define AON_GPADC_SCAN_NEG_10_LEN (5U) +#define AON_GPADC_SCAN_NEG_10_MSK (((1U << AON_GPADC_SCAN_NEG_10_LEN) - 1) << AON_GPADC_SCAN_NEG_10_POS) +#define AON_GPADC_SCAN_NEG_10_UMSK (~(((1U << AON_GPADC_SCAN_NEG_10_LEN) - 1) << AON_GPADC_SCAN_NEG_10_POS)) +#define AON_GPADC_SCAN_NEG_11 AON_GPADC_SCAN_NEG_11 +#define AON_GPADC_SCAN_NEG_11_POS (25U) +#define AON_GPADC_SCAN_NEG_11_LEN (5U) +#define AON_GPADC_SCAN_NEG_11_MSK (((1U << AON_GPADC_SCAN_NEG_11_LEN) - 1) << AON_GPADC_SCAN_NEG_11_POS) +#define AON_GPADC_SCAN_NEG_11_UMSK (~(((1U << AON_GPADC_SCAN_NEG_11_LEN) - 1) << AON_GPADC_SCAN_NEG_11_POS)) + +/* 0x928 : gpadc_reg_status */ +#define AON_GPADC_REG_STATUS_OFFSET (0x928) +#define AON_GPADC_DATA_RDY AON_GPADC_DATA_RDY +#define AON_GPADC_DATA_RDY_POS (0U) +#define AON_GPADC_DATA_RDY_LEN (1U) +#define AON_GPADC_DATA_RDY_MSK (((1U << AON_GPADC_DATA_RDY_LEN) - 1) << AON_GPADC_DATA_RDY_POS) +#define AON_GPADC_DATA_RDY_UMSK (~(((1U << AON_GPADC_DATA_RDY_LEN) - 1) << AON_GPADC_DATA_RDY_POS)) +#define AON_GPADC_RESERVED AON_GPADC_RESERVED +#define AON_GPADC_RESERVED_POS (16U) +#define AON_GPADC_RESERVED_LEN (16U) +#define AON_GPADC_RESERVED_MSK (((1U << AON_GPADC_RESERVED_LEN) - 1) << AON_GPADC_RESERVED_POS) +#define AON_GPADC_RESERVED_UMSK (~(((1U << AON_GPADC_RESERVED_LEN) - 1) << AON_GPADC_RESERVED_POS)) + +/* 0x92C : gpadc_reg_isr */ +#define AON_GPADC_REG_ISR_OFFSET (0x92C) +#define AON_GPADC_NEG_SATUR AON_GPADC_NEG_SATUR +#define AON_GPADC_NEG_SATUR_POS (0U) +#define AON_GPADC_NEG_SATUR_LEN (1U) +#define AON_GPADC_NEG_SATUR_MSK (((1U << AON_GPADC_NEG_SATUR_LEN) - 1) << AON_GPADC_NEG_SATUR_POS) +#define AON_GPADC_NEG_SATUR_UMSK (~(((1U << AON_GPADC_NEG_SATUR_LEN) - 1) << AON_GPADC_NEG_SATUR_POS)) +#define AON_GPADC_POS_SATUR AON_GPADC_POS_SATUR +#define AON_GPADC_POS_SATUR_POS (1U) +#define AON_GPADC_POS_SATUR_LEN (1U) +#define AON_GPADC_POS_SATUR_MSK (((1U << AON_GPADC_POS_SATUR_LEN) - 1) << AON_GPADC_POS_SATUR_POS) +#define AON_GPADC_POS_SATUR_UMSK (~(((1U << AON_GPADC_POS_SATUR_LEN) - 1) << AON_GPADC_POS_SATUR_POS)) +#define AON_GPADC_NEG_SATUR_CLR AON_GPADC_NEG_SATUR_CLR +#define AON_GPADC_NEG_SATUR_CLR_POS (4U) +#define AON_GPADC_NEG_SATUR_CLR_LEN (1U) +#define AON_GPADC_NEG_SATUR_CLR_MSK (((1U << AON_GPADC_NEG_SATUR_CLR_LEN) - 1) << AON_GPADC_NEG_SATUR_CLR_POS) +#define AON_GPADC_NEG_SATUR_CLR_UMSK (~(((1U << AON_GPADC_NEG_SATUR_CLR_LEN) - 1) << AON_GPADC_NEG_SATUR_CLR_POS)) +#define AON_GPADC_POS_SATUR_CLR AON_GPADC_POS_SATUR_CLR +#define AON_GPADC_POS_SATUR_CLR_POS (5U) +#define AON_GPADC_POS_SATUR_CLR_LEN (1U) +#define AON_GPADC_POS_SATUR_CLR_MSK (((1U << AON_GPADC_POS_SATUR_CLR_LEN) - 1) << AON_GPADC_POS_SATUR_CLR_POS) +#define AON_GPADC_POS_SATUR_CLR_UMSK (~(((1U << AON_GPADC_POS_SATUR_CLR_LEN) - 1) << AON_GPADC_POS_SATUR_CLR_POS)) +#define AON_GPADC_NEG_SATUR_MASK AON_GPADC_NEG_SATUR_MASK +#define AON_GPADC_NEG_SATUR_MASK_POS (8U) +#define AON_GPADC_NEG_SATUR_MASK_LEN (1U) +#define AON_GPADC_NEG_SATUR_MASK_MSK (((1U << AON_GPADC_NEG_SATUR_MASK_LEN) - 1) << AON_GPADC_NEG_SATUR_MASK_POS) +#define AON_GPADC_NEG_SATUR_MASK_UMSK (~(((1U << AON_GPADC_NEG_SATUR_MASK_LEN) - 1) << AON_GPADC_NEG_SATUR_MASK_POS)) +#define AON_GPADC_POS_SATUR_MASK AON_GPADC_POS_SATUR_MASK +#define AON_GPADC_POS_SATUR_MASK_POS (9U) +#define AON_GPADC_POS_SATUR_MASK_LEN (1U) +#define AON_GPADC_POS_SATUR_MASK_MSK (((1U << AON_GPADC_POS_SATUR_MASK_LEN) - 1) << AON_GPADC_POS_SATUR_MASK_POS) +#define AON_GPADC_POS_SATUR_MASK_UMSK (~(((1U << AON_GPADC_POS_SATUR_MASK_LEN) - 1) << AON_GPADC_POS_SATUR_MASK_POS)) + +/* 0x930 : gpadc_reg_result */ +#define AON_GPADC_REG_RESULT_OFFSET (0x930) +#define AON_GPADC_DATA_OUT AON_GPADC_DATA_OUT +#define AON_GPADC_DATA_OUT_POS (0U) +#define AON_GPADC_DATA_OUT_LEN (26U) +#define AON_GPADC_DATA_OUT_MSK (((1U << AON_GPADC_DATA_OUT_LEN) - 1) << AON_GPADC_DATA_OUT_POS) +#define AON_GPADC_DATA_OUT_UMSK (~(((1U << AON_GPADC_DATA_OUT_LEN) - 1) << AON_GPADC_DATA_OUT_POS)) + +/* 0x934 : gpadc_reg_raw_result */ +#define AON_GPADC_REG_RAW_RESULT_OFFSET (0x934) +#define AON_GPADC_RAW_DATA AON_GPADC_RAW_DATA +#define AON_GPADC_RAW_DATA_POS (0U) +#define AON_GPADC_RAW_DATA_LEN (12U) +#define AON_GPADC_RAW_DATA_MSK (((1U << AON_GPADC_RAW_DATA_LEN) - 1) << AON_GPADC_RAW_DATA_POS) +#define AON_GPADC_RAW_DATA_UMSK (~(((1U << AON_GPADC_RAW_DATA_LEN) - 1) << AON_GPADC_RAW_DATA_POS)) + +/* 0x938 : gpadc_reg_define */ +#define AON_GPADC_REG_DEFINE_OFFSET (0x938) +#define AON_GPADC_OS_CAL_DATA AON_GPADC_OS_CAL_DATA +#define AON_GPADC_OS_CAL_DATA_POS (0U) +#define AON_GPADC_OS_CAL_DATA_LEN (16U) +#define AON_GPADC_OS_CAL_DATA_MSK (((1U << AON_GPADC_OS_CAL_DATA_LEN) - 1) << AON_GPADC_OS_CAL_DATA_POS) +#define AON_GPADC_OS_CAL_DATA_UMSK (~(((1U << AON_GPADC_OS_CAL_DATA_LEN) - 1) << AON_GPADC_OS_CAL_DATA_POS)) + +/* 0x93C : hbncore_resv0 */ +#define AON_HBNCORE_RESV0_OFFSET (0x93C) +#define AON_HBNCORE_RESV0_DATA AON_HBNCORE_RESV0_DATA +#define AON_HBNCORE_RESV0_DATA_POS (0U) +#define AON_HBNCORE_RESV0_DATA_LEN (32U) +#define AON_HBNCORE_RESV0_DATA_MSK (((1U << AON_HBNCORE_RESV0_DATA_LEN) - 1) << AON_HBNCORE_RESV0_DATA_POS) +#define AON_HBNCORE_RESV0_DATA_UMSK (~(((1U << AON_HBNCORE_RESV0_DATA_LEN) - 1) << AON_HBNCORE_RESV0_DATA_POS)) + +/* 0x940 : hbncore_resv1 */ +#define AON_HBNCORE_RESV1_OFFSET (0x940) +#define AON_HBNCORE_RESV1_DATA AON_HBNCORE_RESV1_DATA +#define AON_HBNCORE_RESV1_DATA_POS (0U) +#define AON_HBNCORE_RESV1_DATA_LEN (32U) +#define AON_HBNCORE_RESV1_DATA_MSK (((1U << AON_HBNCORE_RESV1_DATA_LEN) - 1) << AON_HBNCORE_RESV1_DATA_POS) +#define AON_HBNCORE_RESV1_DATA_UMSK (~(((1U << AON_HBNCORE_RESV1_DATA_LEN) - 1) << AON_HBNCORE_RESV1_DATA_POS)) + +struct aon_reg { + /* 0x0 reserved */ + uint8_t RESERVED0x0[2048]; + + /* 0x800 : aon */ + union { + struct { + uint32_t aon_resv : 8; /* [ 7: 0], r/w, 0xf */ + uint32_t reserved_8_11 : 4; /* [11: 8], rsvd, 0x0 */ + uint32_t pu_aon_dc_tbuf : 1; /* [ 12], r/w, 0x0 */ + uint32_t reserved_13_19 : 7; /* [19:13], rsvd, 0x0 */ + uint32_t ldo11_rt_pulldown : 1; /* [ 20], r/w, 0x0 */ + uint32_t ldo11_rt_pulldown_sel : 1; /* [ 21], r/w, 0x0 */ + uint32_t sw_pu_ldo11_rt : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23_31 : 9; /* [31:23], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } aon; + + /* 0x804 : aon_common */ + union { + struct { + uint32_t tmux_aon : 3; /* [ 2: 0], r/w, 0x0 */ + uint32_t pmip_dc_tp_out_en_aon : 1; /* [ 3], r/w, 0x0 */ + uint32_t ten_bg_sys_aon : 1; /* [ 4], r/w, 0x0 */ + uint32_t ten_dcdc11_0_aon : 1; /* [ 5], r/w, 0x0 */ + uint32_t ten_dcdc11_1_aon : 1; /* [ 6], r/w, 0x0 */ + uint32_t ten_dcdc18_0_aon : 1; /* [ 7], r/w, 0x0 */ + uint32_t ten_dcdc18_1_aon : 1; /* [ 8], r/w, 0x0 */ + uint32_t ten_ldo12uhs : 1; /* [ 9], r/w, 0x0 */ + uint32_t ten_ldo18flash : 1; /* [ 10], r/w, 0x0 */ + uint32_t ten_ldo15cis : 1; /* [ 11], r/w, 0x0 */ + uint32_t ten_ldo18io_aon : 1; /* [ 12], r/w, 0x0 */ + uint32_t ten_ldo28cis : 1; /* [ 13], r/w, 0x0 */ + uint32_t ten_rc32m : 1; /* [ 14], r/w, 0x0 */ + uint32_t reserved_15 : 1; /* [ 15], rsvd, 0x0 */ + uint32_t ten_ldo15rf_aon : 1; /* [ 16], r/w, 0x0 */ + uint32_t ten_xtal_aon : 1; /* [ 17], r/w, 0x0 */ + uint32_t dten_xtal_aon : 1; /* [ 18], r/w, 0x0 */ + uint32_t ten_mbg_aon : 1; /* [ 19], r/w, 0x0 */ + uint32_t ten_cip_misc_aon : 1; /* [ 20], r/w, 0x0 */ + uint32_t ten_aon : 1; /* [ 21], r/w, 0x0 */ + uint32_t reserved_22_31 : 10; /* [31:22], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } aon_common; + + /* 0x808 : aon_misc */ + union { + struct { + uint32_t sw_soc_en_aon : 1; /* [ 0], r/w, 0x1 */ + uint32_t sw_wb_en_aon : 1; /* [ 1], r/w, 0x1 */ + uint32_t reserved_2_31 : 30; /* [31: 2], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } aon_misc; + + /* 0x80c reserved */ + uint8_t RESERVED0x80c[4]; + + /* 0x810 : bg_sys_top */ + union { + struct { + uint32_t pu_bg_sys_aon : 1; /* [ 0], r/w, 0x1 */ + uint32_t istart_ctrl_aon : 1; /* [ 1], r/w, 0x1 */ + uint32_t reserved_2_31 : 30; /* [31: 2], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } bg_sys_top; + + /* 0x814 : dcdc_top_0 */ + union { + struct { + uint32_t dcdc11_sstart_time_aon : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_3 : 2; /* [ 3: 2], rsvd, 0x0 */ + uint32_t dcdc11_stby_lp_cur_aon : 3; /* [ 6: 4], r/w, 0x2 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t dcdc11_vc_clamp_vth_aon : 3; /* [10: 8], r/w, 0x4 */ + uint32_t dcdc11_vout_sel_aon : 5; /* [15:11], r/w, 0x8 */ + uint32_t dcdc11_vout_trim_aon : 4; /* [19:16], r/w, 0x7 */ + uint32_t dcdc11_vpfm_aon : 4; /* [23:20], r/w, 0x4 */ + uint32_t dcdc11_zvs_td_opt_aon : 3; /* [26:24], r/w, 0x4 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t dcdc11_vstby_aon : 2; /* [29:28], r/w, 0x1 */ + uint32_t reserved_30_31 : 2; /* [31:30], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } dcdc_top_0; + + /* 0x818 : dcdc_top_1 */ + union { + struct { + uint32_t dcdc11_nonoverlap_td_aon : 5; /* [ 4: 0], r/w, 0x0 */ + uint32_t dcdc11_ocp_out_aon : 1; /* [ 5], r, 0x0 */ + uint32_t dcdc11_ocp_rst_aon : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t dcdc11_ocp_vth_aon : 3; /* [10: 8], r/w, 0x4 */ + uint32_t dcdc11_osc_2m_mode_aon : 1; /* [ 11], r/w, 0x0 */ + uint32_t dcdc11_osc_freq_trim_aon : 4; /* [15:12], r/w, 0x8 */ + uint32_t dcdc11_pulldown_aon : 1; /* [ 16], r/w, 0x0 */ + uint32_t reserved_17_19 : 3; /* [19:17], rsvd, 0x0 */ + uint32_t dcdc11_rc_sel_aon : 4; /* [23:20], r/w, 0x8 */ + uint32_t dcdc11_rdy_aon : 1; /* [ 24], r, 0x0 */ + uint32_t reserved_25 : 1; /* [ 25], rsvd, 0x0 */ + uint32_t dcdc11_slope_curr_sel_aon : 5; /* [30:26], r/w, 0x6 */ + uint32_t reserved_31 : 1; /* [ 31], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } dcdc_top_1; + + /* 0x81C : ldo11soc_and_dctest */ + union { + struct { + uint32_t reserved_0_3 : 4; /* [ 3: 0], rsvd, 0x0 */ + uint32_t dcdc11_cfb_sel_aon : 4; /* [ 7: 4], r/w, 0x8 */ + uint32_t dcdc11_chf_sel_aon : 4; /* [11: 8], r/w, 0x1 */ + uint32_t dcdc11_comp_gm_sel_aon : 3; /* [14:12], r/w, 0x4 */ + uint32_t reserved_15 : 1; /* [ 15], rsvd, 0x0 */ + uint32_t dcdc11_cs_delay_aon : 3; /* [18:16], r/w, 0x4 */ + uint32_t reserved_19 : 1; /* [ 19], rsvd, 0x0 */ + uint32_t dcdc11_drv_sr_aon : 2; /* [21:20], r/w, 0x3 */ + uint32_t dcdc11_en_antiring_aon : 1; /* [ 22], r/w, 0x1 */ + uint32_t dcdc11_en_osc_inhibit_t2_aon : 1; /* [ 23], r/w, 0x1 */ + uint32_t dcdc11_en_slow_osc_aon : 1; /* [ 24], r/w, 0x0 */ + uint32_t dcdc11_en_stby_lp_aon : 1; /* [ 25], r/w, 0x1 */ + uint32_t dcdc11_en_stop_osc_aon : 1; /* [ 26], r/w, 0x1 */ + uint32_t dcdc11_force_en_cs_zvs_aon : 1; /* [ 27], r/w, 0x0 */ + uint32_t dcdc11_isense_trim_aon : 3; /* [30:28], r/w, 0x4 */ + uint32_t reserved_31 : 1; /* [ 31], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } ldo11soc_and_dctest; + + /* 0x820 : move to 0x2000F000[23] */ + union { + struct { + uint32_t dcdc18_sstart_time_aon : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_3 : 2; /* [ 3: 2], rsvd, 0x0 */ + uint32_t dcdc18_stby_lp_cur_aon : 3; /* [ 6: 4], r/w, 0x2 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t dcdc18_vc_clamp_vth_aon : 3; /* [10: 8], r/w, 0x4 */ + uint32_t dcdc18_vout_sel_aon : 5; /* [15:11], r/w, 0x1b */ + uint32_t dcdc18_vout_trim_aon : 4; /* [19:16], r/w, 0x7 */ + uint32_t dcdc18_vpfm_aon : 4; /* [23:20], r/w, 0x4 */ + uint32_t dcdc18_zvs_td_opt_aon : 3; /* [26:24], r/w, 0x4 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t dcdc18_vstby_aon : 2; /* [29:28], r/w, 0x1 */ + uint32_t reserved_30_31 : 2; /* [31:30], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } dcdc18_top_0; + + /* 0x824 : dcdc18_top_1 */ + union { + struct { + uint32_t dcdc18_nonoverlap_td_aon : 5; /* [ 4: 0], r/w, 0x0 */ + uint32_t dcdc18_ocp_out_aon : 1; /* [ 5], r, 0x0 */ + uint32_t dcdc18_ocp_rst_aon : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t dcdc18_ocp_vth_aon : 3; /* [10: 8], r/w, 0x4 */ + uint32_t dcdc18_osc_2m_mode_aon : 1; /* [ 11], r/w, 0x0 */ + uint32_t dcdc18_osc_freq_trim_aon : 4; /* [15:12], r/w, 0x8 */ + uint32_t dcdc18_pulldown_aon : 1; /* [ 16], r/w, 0x0 */ + uint32_t reserved_17_19 : 3; /* [19:17], rsvd, 0x0 */ + uint32_t dcdc18_rc_sel_aon : 4; /* [23:20], r/w, 0x8 */ + uint32_t dcdc18_rdy_aon : 1; /* [ 24], r, 0x0 */ + uint32_t reserved_25 : 1; /* [ 25], rsvd, 0x0 */ + uint32_t dcdc18_slope_curr_sel_aon : 5; /* [30:26], r/w, 0xa */ + uint32_t reserved_31 : 1; /* [ 31], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } dcdc18_top_1; + + /* 0x828 : dcdc18_top_2 */ + union { + struct { + uint32_t reserved_0_3 : 4; /* [ 3: 0], rsvd, 0x0 */ + uint32_t dcdc18_cfb_sel_aon : 4; /* [ 7: 4], r/w, 0x8 */ + uint32_t dcdc18_chf_sel_aon : 4; /* [11: 8], r/w, 0x1 */ + uint32_t dcdc18_comp_gm_sel_aon : 3; /* [14:12], r/w, 0x4 */ + uint32_t reserved_15 : 1; /* [ 15], rsvd, 0x0 */ + uint32_t dcdc18_cs_delay_aon : 3; /* [18:16], r/w, 0x4 */ + uint32_t reserved_19 : 1; /* [ 19], rsvd, 0x0 */ + uint32_t dcdc18_drv_sr_aon : 2; /* [21:20], r/w, 0x3 */ + uint32_t dcdc18_en_antiring_aon : 1; /* [ 22], r/w, 0x1 */ + uint32_t dcdc18_en_osc_inhibit_t2_aon : 1; /* [ 23], r/w, 0x0 */ + uint32_t dcdc18_en_slow_osc_aon : 1; /* [ 24], r/w, 0x0 */ + uint32_t dcdc18_en_stby_lp_aon : 1; /* [ 25], r/w, 0x1 */ + uint32_t dcdc18_en_stop_osc_aon : 1; /* [ 26], r/w, 0x1 */ + uint32_t dcdc18_force_en_cs_zvs_aon : 1; /* [ 27], r/w, 0x0 */ + uint32_t dcdc18_isense_trim_aon : 3; /* [30:28], r/w, 0x4 */ + uint32_t reserved_31 : 1; /* [ 31], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } dcdc18_top_2; + + /* 0x82C : psw_irrcv */ + union { + struct { + uint32_t pu_psw_irrcv_aon : 1; /* [ 0], r/w, 0x0 */ + uint32_t reserved_1_18 : 18; /* [18: 1], rsvd, 0x0 */ + uint32_t usb20_rref_ext_en_aon : 1; /* [ 19], r/w, 0x0 */ + uint32_t en_por33_aon : 1; /* [ 20], r/w, 0x0 */ + uint32_t usb20_rref_hiz_aon : 1; /* [ 21], r/w, 0x0 */ + uint32_t reserved_22_23 : 2; /* [23:22], rsvd, 0x0 */ + uint32_t usb20_rcal_code_aon : 6; /* [29:24], r/w, 0x1a */ + uint32_t reserved_30_31 : 2; /* [31:30], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } psw_irrcv; + + /* 0x830 reserved */ + uint8_t RESERVED0x830[80]; + + /* 0x880 : rf_top_aon */ + union { + struct { + uint32_t pu_mbg_aon : 1; /* [ 0], r/w, 0x1 */ + uint32_t pu_ldo15rf_aon : 1; /* [ 1], r/w, 0x1 */ + uint32_t pu_sfreg_aon : 1; /* [ 2], r/w, 0x1 */ + uint32_t reserved_3 : 1; /* [ 3], rsvd, 0x0 */ + uint32_t pu_xtal_buf_aon : 1; /* [ 4], r/w, 0x1 */ + uint32_t pu_xtal_aon : 1; /* [ 5], r/w, 0x1 */ + uint32_t reserved_6_7 : 2; /* [ 7: 6], rsvd, 0x0 */ + uint32_t ldo15rf_sstart_sel_aon : 1; /* [ 8], r/w, 0x1 */ + uint32_t ldo15rf_sstart_delay_aon : 2; /* [10: 9], r/w, 0x0 */ + uint32_t reserved_11 : 1; /* [ 11], rsvd, 0x0 */ + uint32_t ldo15rf_pulldown_aon : 1; /* [ 12], r/w, 0x0 */ + uint32_t ldo15rf_pulldown_sel_aon : 1; /* [ 13], r/w, 0x0 */ + uint32_t reserved_14_15 : 2; /* [15:14], rsvd, 0x0 */ + uint32_t ldo15rf_vout_sel_aon : 3; /* [18:16], r/w, 0x2 */ + uint32_t reserved_19_23 : 5; /* [23:19], rsvd, 0x0 */ + uint32_t ldo15rf_cc_aon : 2; /* [25:24], r/w, 0x0 */ + uint32_t reserved_26_27 : 2; /* [27:26], rsvd, 0x0 */ + uint32_t ldo15rf_bypass_aon : 1; /* [ 28], r/w, 0x0 */ + uint32_t reserved_29_31 : 3; /* [31:29], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } rf_top_aon; + + /* 0x884 : xtal_cfg */ + union { + struct { + uint32_t xtal_bk_aon : 2; /* [ 1: 0], r/w, 0x1 */ + uint32_t xtal_capcode_extra_aon : 1; /* [ 2], r/w, 0x0 */ + uint32_t xtal_ext_sel_aon : 1; /* [ 3], r/w, 0x0 */ + uint32_t xtal_buf_en_aon : 4; /* [ 7: 4], r/w, 0xe */ + uint32_t xtal_buf_hp_aon : 4; /* [11: 8], r/w, 0x0 */ + uint32_t xtal_fast_startup_aon : 1; /* [ 12], r/w, 0x1 */ + uint32_t xtal_sleep_aon : 1; /* [ 13], r/w, 0x1 */ + uint32_t xtal_amp_ctrl_aon : 2; /* [15:14], r/w, 0x3 */ + uint32_t xtal_capcode_out_aon : 6; /* [21:16], r/w, 0x10 */ + uint32_t xtal_capcode_in_aon : 6; /* [27:22], r/w, 0x10 */ + uint32_t xtal_gm_boost_aon : 2; /* [29:28], r/w, 0x3 */ + uint32_t xtal_rdy_sel_aon : 2; /* [31:30], r/w, 0x2 */ + } BF; + uint32_t WORD; + } xtal_cfg; + + /* 0x888 : xtal_cfg2 */ + union { + struct { + uint32_t wifi_xtal_ldo33_bypass_aon : 1; /* [ 0], r/w, 0x0 */ + uint32_t wifi_xtal_ldo33_sel_aon : 3; /* [ 3: 1], r/w, 0x0 */ + uint32_t wifi_xtal_ldo18_sel_aon : 2; /* [ 5: 4], r/w, 0x1 */ + uint32_t wifi_xtal_ldo33_pu_aon : 1; /* [ 6], r/w, 0x1 */ + uint32_t wifi_xtal_ldo18_pu_aon : 1; /* [ 7], r/w, 0x1 */ + uint32_t reserved_8_9 : 2; /* [ 9: 8], rsvd, 0x0 */ + uint32_t wifi_xtal_reserve : 4; /* [13:10], r/w, 0x0 */ + uint32_t reserved_14_15 : 2; /* [15:14], rsvd, 0x0 */ + uint32_t wifi_xtal_ldo18_short_filter_aon : 1; /* [ 16], r/w, 0x0 */ + uint32_t reserved_17_29 : 13; /* [29:17], rsvd, 0x0 */ + uint32_t xtal_buf_drv_aon : 2; /* [31:30], r/w, 0x1 */ + } BF; + uint32_t WORD; + } xtal_cfg2; + + /* 0x88C : xtal_cfg3 */ + union { + struct { + uint32_t reserved_0_11 : 12; /* [11: 0], rsvd, 0x0 */ + uint32_t wifi_xtal_clk_inv_en_aon : 1; /* [ 12], r/w, 0x0 */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t wifi_xtal_cml_en_aon : 1; /* [ 16], r/w, 0x0 */ + uint32_t wifi_xtal_cml_r_sel_aon : 2; /* [18:17], r/w, 0x1 */ + uint32_t reserved_19 : 1; /* [ 19], rsvd, 0x0 */ + uint32_t wifi_xtal_clk_en_aon : 1; /* [ 20], r/w, 0x1 */ + uint32_t reserved_21_29 : 9; /* [29:21], rsvd, 0x0 */ + uint32_t wifi_xtal_buf_drv_aon : 2; /* [31:30], r/w, 0x1 */ + } BF; + uint32_t WORD; + } xtal_cfg3; + + /* 0x890 : tsen */ + union { + struct { + uint32_t tsen_refcode_corner : 12; /* [11: 0], r/w, 0x8ff */ + uint32_t reserved_12_15 : 4; /* [15:12], rsvd, 0x0 */ + uint32_t tsen_refcode_rfcal : 12; /* [27:16], r/w, 0x8ff */ + uint32_t xtal_rdy : 1; /* [ 28], r, 0x1 */ + uint32_t xtal_inn_cfg_en_aon : 1; /* [ 29], r/w, 0x1 */ + uint32_t xtal_rdy_int_sel_aon : 2; /* [31:30], r/w, 0x1 */ + } BF; + uint32_t WORD; + } tsen; + + /* 0x894 reserved */ + uint8_t RESERVED0x894[48]; + + /* 0x8C4 : ldo18io */ + union { + struct { + uint32_t reserved_0 : 1; /* [ 0], rsvd, 0x0 */ + uint32_t ldo18io_bypass_iso_aon : 1; /* [ 1], r/w, 0x0 */ + uint32_t ldo18io_pulldown_aon : 1; /* [ 2], r/w, 0x0 */ + uint32_t ldo18io_pulldown_sel_aon : 1; /* [ 3], r/w, 0x1 */ + uint32_t ldo18io_bm_aon : 3; /* [ 6: 4], r/w, 0x3 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t ldo18io_cc_aon : 3; /* [10: 8], r/w, 0x3 */ + uint32_t ldo18io_ocp_out_aon : 1; /* [ 11], r, 0x0 */ + uint32_t ldo18io_ocp_th_aon : 3; /* [14:12], r/w, 0x3 */ + uint32_t ldo18io_ocp_en_aon : 1; /* [ 15], r/w, 0x1 */ + uint32_t ldo18io_sstart_delay_aon : 3; /* [18:16], r/w, 0x3 */ + uint32_t ldo18io_sstart_en_aon : 1; /* [ 19], r/w, 0x1 */ + uint32_t ldo18io_vout_sel_aon : 4; /* [23:20], r/w, 0x5 */ + uint32_t ldo18io_vout_trim_aon : 4; /* [27:24], r/w, 0x7 */ + uint32_t reserved_28_31 : 4; /* [31:28], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } ldo18io; + + /* 0x8c8 reserved */ + uint8_t RESERVED0x8c8[56]; + + /* 0x900 : acomp0_ctrl */ + union { + struct { + uint32_t acomp0_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t reserved_1_3 : 3; /* [ 3: 1], rsvd, 0x0 */ + uint32_t acomp0_hyst_seln : 3; /* [ 6: 4], r/w, 0x0 */ + uint32_t acomp0_hyst_selp : 3; /* [ 9: 7], r/w, 0x0 */ + uint32_t acomp0_bias_prog : 2; /* [11:10], r/w, 0x0 */ + uint32_t acomp0_level_sel : 6; /* [17:12], r/w, 0x0 */ + uint32_t acomp0_neg_sel : 4; /* [21:18], r/w, 0x0 */ + uint32_t acomp0_pos_sel : 4; /* [25:22], r/w, 0x0 */ + uint32_t acomp0_muxen : 1; /* [ 26], r/w, 0x0 */ + uint32_t reserved_27_31 : 5; /* [31:27], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } acomp0_ctrl; + + /* 0x904 : acomp1_ctrl */ + union { + struct { + uint32_t acomp1_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t reserved_1_3 : 3; /* [ 3: 1], rsvd, 0x0 */ + uint32_t acomp1_hyst_seln : 3; /* [ 6: 4], r/w, 0x0 */ + uint32_t acomp1_hyst_selp : 3; /* [ 9: 7], r/w, 0x0 */ + uint32_t acomp1_bias_prog : 2; /* [11:10], r/w, 0x0 */ + uint32_t acomp1_level_sel : 6; /* [17:12], r/w, 0x0 */ + uint32_t acomp1_neg_sel : 4; /* [21:18], r/w, 0x0 */ + uint32_t acomp1_pos_sel : 4; /* [25:22], r/w, 0x0 */ + uint32_t acomp1_muxen : 1; /* [ 26], r/w, 0x0 */ + uint32_t reserved_27_31 : 5; /* [31:27], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } acomp1_ctrl; + + /* 0x908 : acomp_ctrl */ + union { + struct { + uint32_t acomp1_rstn_ana : 1; /* [ 0], r/w, 0x1 */ + uint32_t acomp0_rstn_ana : 1; /* [ 1], r/w, 0x1 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t acomp1_test_en : 1; /* [ 8], r/w, 0x0 */ + uint32_t acomp0_test_en : 1; /* [ 9], r/w, 0x0 */ + uint32_t acomp1_test_sel : 2; /* [11:10], r/w, 0x0 */ + uint32_t acomp0_test_sel : 2; /* [13:12], r/w, 0x0 */ + uint32_t reserved_14_16 : 3; /* [16:14], rsvd, 0x0 */ + uint32_t acomp1_out_raw : 1; /* [ 17], r, 0x0 */ + uint32_t reserved_18 : 1; /* [ 18], rsvd, 0x0 */ + uint32_t acomp0_out_raw : 1; /* [ 19], r, 0x0 */ + uint32_t reserved_20_23 : 4; /* [23:20], rsvd, 0x0 */ + uint32_t acomp_vref_sel : 6; /* [29:24], r/w, 0x0 */ + uint32_t acomp_reserved : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } acomp_ctrl; + + /* 0x90C : gpadc_reg_cmd */ + union { + struct { + uint32_t gpadc_global_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t gpadc_conv_start : 1; /* [ 1], r/w, 0x0 */ + uint32_t gpadc_soft_rst : 1; /* [ 2], r/w, 0x0 */ + uint32_t gpadc_neg_sel : 5; /* [ 7: 3], r/w, 0xf */ + uint32_t gpadc_pos_sel : 5; /* [12: 8], r/w, 0xf */ + uint32_t gpadc_neg_gnd : 1; /* [ 13], r/w, 0x0 */ + uint32_t gpadc_micbias_en : 1; /* [ 14], r/w, 0x0 */ + uint32_t gpadc_micpga_en : 1; /* [ 15], r/w, 0x0 */ + uint32_t gpadc_byp_micboost : 1; /* [ 16], r/w, 0x0 */ + uint32_t gpadc_rcal_en : 1; /* [ 17], r/w, 0x0 */ + uint32_t gpadc_dwa_en : 1; /* [ 18], r/w, 0x0 */ + uint32_t gpadc_mic2_diff : 1; /* [ 19], r/w, 0x0 */ + uint32_t gpadc_mic1_diff : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpadc_mic_pga2_gain : 2; /* [22:21], r/w, 0x0 */ + uint32_t gpadc_micboost_32db_en : 1; /* [ 23], r/w, 0x0 */ + uint32_t reserved_24_26 : 3; /* [26:24], rsvd, 0x0 */ + uint32_t gpadc_chip_sen_pu : 1; /* [ 27], r/w, 0x0 */ + uint32_t gpadc_sen_sel : 3; /* [30:28], r/w, 0x0 */ + uint32_t gpadc_sen_test_en : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpadc_reg_cmd; + + /* 0x910 : gpadc_reg_config1 */ + union { + struct { + uint32_t gpadc_cal_os_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t gpadc_cont_conv_en : 1; /* [ 1], r/w, 0x1 */ + uint32_t gpadc_res_sel : 3; /* [ 4: 2], r/w, 0x0 */ + uint32_t reserved_5_7 : 3; /* [ 7: 5], rsvd, 0x0 */ + uint32_t gpadc_vcm_sel_en : 1; /* [ 8], r/w, 0x0 */ + uint32_t gpadc_vcm_hyst_sel : 1; /* [ 9], r/w, 0x0 */ + uint32_t gpadc_lowv_det_en : 1; /* [ 10], r/w, 0x0 */ + uint32_t gpadc_pwm_trg_en : 1; /* [ 11], r/w, 0x0 */ + uint32_t gpadc_clk_ana_dly : 4; /* [15:12], r/w, 0x0 */ + uint32_t gpadc_clk_ana_dly_en : 1; /* [ 16], r/w, 0x0 */ + uint32_t gpadc_clk_ana_inv : 1; /* [ 17], r/w, 0x0 */ + uint32_t gpadc_clk_div_ratio : 3; /* [20:18], r/w, 0x3 */ + uint32_t gpadc_scan_length : 4; /* [24:21], r/w, 0x0 */ + uint32_t gpadc_scan_en : 1; /* [ 25], r/w, 0x0 */ + uint32_t gpadc_dither_en : 1; /* [ 26], r/w, 0x0 */ + uint32_t gpadc_v11_sel : 2; /* [28:27], r/w, 0x0 */ + uint32_t gpadc_v18_sel : 2; /* [30:29], r/w, 0x0 */ + uint32_t reserved_31 : 1; /* [ 31], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpadc_reg_config1; + + /* 0x914 : gpadc_reg_config2 */ + union { + struct { + uint32_t reserved_0_1 : 2; /* [ 1: 0], rsvd, 0x0 */ + uint32_t gpadc_diff_mode : 1; /* [ 2], r/w, 0x0 */ + uint32_t gpadc_vref_sel : 1; /* [ 3], r/w, 0x0 */ + uint32_t gpadc_vbat_en : 1; /* [ 4], r/w, 0x0 */ + uint32_t gpadc_tsext_sel : 1; /* [ 5], r/w, 0x0 */ + uint32_t gpadc_ts_en : 1; /* [ 6], r/w, 0x0 */ + uint32_t gpadc_pga_vcm : 2; /* [ 8: 7], r/w, 0x2 */ + uint32_t gpadc_pga_os_cal : 4; /* [12: 9], r/w, 0x8 */ + uint32_t gpadc_pga_en : 1; /* [ 13], r/w, 0x0 */ + uint32_t gpadc_pga_vcmi_en : 1; /* [ 14], r/w, 0x0 */ + uint32_t gpadc_chop_mode : 2; /* [16:15], r/w, 0x3 */ + uint32_t gpadc_bias_sel : 1; /* [ 17], r/w, 0x0 */ + uint32_t gpadc_test_en : 1; /* [ 18], r/w, 0x0 */ + uint32_t gpadc_test_sel : 3; /* [21:19], r/w, 0x0 */ + uint32_t gpadc_pga2_gain : 3; /* [24:22], r/w, 0x0 */ + uint32_t gpadc_pga1_gain : 3; /* [27:25], r/w, 0x0 */ + uint32_t gpadc_dly_sel : 3; /* [30:28], r/w, 0x0 */ + uint32_t gpadc_tsvbe_low : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpadc_reg_config2; + + /* 0x918 : adc converation sequence 1 */ + union { + struct { + uint32_t gpadc_scan_pos_0 : 5; /* [ 4: 0], r/w, 0xf */ + uint32_t gpadc_scan_pos_1 : 5; /* [ 9: 5], r/w, 0xf */ + uint32_t gpadc_scan_pos_2 : 5; /* [14:10], r/w, 0xf */ + uint32_t gpadc_scan_pos_3 : 5; /* [19:15], r/w, 0xf */ + uint32_t gpadc_scan_pos_4 : 5; /* [24:20], r/w, 0xf */ + uint32_t gpadc_scan_pos_5 : 5; /* [29:25], r/w, 0xf */ + uint32_t reserved_30_31 : 2; /* [31:30], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpadc_reg_scn_pos1; + + /* 0x91C : adc converation sequence 2 */ + union { + struct { + uint32_t gpadc_scan_pos_6 : 5; /* [ 4: 0], r/w, 0xf */ + uint32_t gpadc_scan_pos_7 : 5; /* [ 9: 5], r/w, 0xf */ + uint32_t gpadc_scan_pos_8 : 5; /* [14:10], r/w, 0xf */ + uint32_t gpadc_scan_pos_9 : 5; /* [19:15], r/w, 0xf */ + uint32_t gpadc_scan_pos_10 : 5; /* [24:20], r/w, 0xf */ + uint32_t gpadc_scan_pos_11 : 5; /* [29:25], r/w, 0xf */ + uint32_t reserved_30_31 : 2; /* [31:30], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpadc_reg_scn_pos2; + + /* 0x920 : adc converation sequence 3 */ + union { + struct { + uint32_t gpadc_scan_neg_0 : 5; /* [ 4: 0], r/w, 0xf */ + uint32_t gpadc_scan_neg_1 : 5; /* [ 9: 5], r/w, 0xf */ + uint32_t gpadc_scan_neg_2 : 5; /* [14:10], r/w, 0xf */ + uint32_t gpadc_scan_neg_3 : 5; /* [19:15], r/w, 0xf */ + uint32_t gpadc_scan_neg_4 : 5; /* [24:20], r/w, 0xf */ + uint32_t gpadc_scan_neg_5 : 5; /* [29:25], r/w, 0xf */ + uint32_t reserved_30_31 : 2; /* [31:30], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpadc_reg_scn_neg1; + + /* 0x924 : adc converation sequence 4 */ + union { + struct { + uint32_t gpadc_scan_neg_6 : 5; /* [ 4: 0], r/w, 0xf */ + uint32_t gpadc_scan_neg_7 : 5; /* [ 9: 5], r/w, 0xf */ + uint32_t gpadc_scan_neg_8 : 5; /* [14:10], r/w, 0xf */ + uint32_t gpadc_scan_neg_9 : 5; /* [19:15], r/w, 0xf */ + uint32_t gpadc_scan_neg_10 : 5; /* [24:20], r/w, 0xf */ + uint32_t gpadc_scan_neg_11 : 5; /* [29:25], r/w, 0xf */ + uint32_t reserved_30_31 : 2; /* [31:30], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpadc_reg_scn_neg2; + + /* 0x928 : gpadc_reg_status */ + union { + struct { + uint32_t gpadc_data_rdy : 1; /* [ 0], r, 0x0 */ + uint32_t reserved_1_15 : 15; /* [15: 1], rsvd, 0x0 */ + uint32_t gpadc_reserved : 16; /* [31:16], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpadc_reg_status; + + /* 0x92C : gpadc_reg_isr */ + union { + struct { + uint32_t gpadc_neg_satur : 1; /* [ 0], r, 0x0 */ + uint32_t gpadc_pos_satur : 1; /* [ 1], r, 0x0 */ + uint32_t reserved_2_3 : 2; /* [ 3: 2], rsvd, 0x0 */ + uint32_t gpadc_neg_satur_clr : 1; /* [ 4], r/w, 0x0 */ + uint32_t gpadc_pos_satur_clr : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6_7 : 2; /* [ 7: 6], rsvd, 0x0 */ + uint32_t gpadc_neg_satur_mask : 1; /* [ 8], r/w, 0x0 */ + uint32_t gpadc_pos_satur_mask : 1; /* [ 9], r/w, 0x0 */ + uint32_t reserved_10_31 : 22; /* [31:10], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpadc_reg_isr; + + /* 0x930 : gpadc_reg_result */ + union { + struct { + uint32_t gpadc_data_out : 26; /* [25: 0], r, 0x1ef0000 */ + uint32_t reserved_26_31 : 6; /* [31:26], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpadc_reg_result; + + /* 0x934 : gpadc_reg_raw_result */ + union { + struct { + uint32_t gpadc_raw_data : 12; /* [11: 0], r, 0x0 */ + uint32_t reserved_12_31 : 20; /* [31:12], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpadc_reg_raw_result; + + /* 0x938 : gpadc_reg_define */ + union { + struct { + uint32_t gpadc_os_cal_data : 16; /* [15: 0], r/w, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpadc_reg_define; + + /* 0x93C : hbncore_resv0 */ + union { + struct { + uint32_t hbncore_resv0_data : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } hbncore_resv0; + + /* 0x940 : hbncore_resv1 */ + union { + struct { + uint32_t hbncore_resv1_data : 32; /* [31: 0], r/w, 0xffffffff */ + } BF; + uint32_t WORD; + } hbncore_resv1; +}; + +typedef volatile struct aon_reg aon_reg_t; + +#endif /* __AON_REG_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/bl808.h b/platforms/bl808_m0/vendor/psram/include/bl808.h new file mode 100644 index 0000000..9542fd6 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/bl808.h @@ -0,0 +1,659 @@ +#ifndef __BL808_H__ +#define __BL808_H__ + +/** @addtogroup Configuration_section_for_RISCV + * @{ + */ + +/** + * @brief Configuration of the Processor and Core Peripherals + */ + +#define CORE_ID_ADDRESS (0xF0000000) +#define CORE_ID_M0 (0xE9070000) +#define CORE_ID_D0 (0xDEAD5500) +#define CORE_ID_LP (0xDEADE902) + +#define CORE_M0_JTAG_TCK_PIN (GLB_GPIO_PIN_27) +#define CORE_M0_JTAG_TMS_PIN (GLB_GPIO_PIN_28) +#define CORE_M0_JTAG_TCK_FUNC (GPIO_FUN_M_CJTAG) +#define CORE_M0_JTAG_TMS_FUNC (GPIO_FUN_M_CJTAG) + +#define IPC_SYNC_ADDR1 0x40000000 +#define IPC_SYNC_ADDR2 0x40000004 +#define IPC_SYNC_FLAG 0x12345678 + +/** + * @} + */ + +/** @addtogroup Peripheral_interrupt_number_definition + * @{ + */ + +#ifdef ARCH_ARM +#define IRQ_NUM_BASE 0 +#endif + +#ifdef ARCH_RISCV +#if (__riscv_xlen == 64) +#define IRQ_NUM_BASE 16 /* PLIC ===> MEXT_IRQn */ +#else +#define IRQ_NUM_BASE 16 +#endif +#endif +/** + * @brief BL808 Interrupt Number Definition, according to the selected device + * in @ref Library_configuration_section + */ +typedef enum { +#ifdef ARCH_ARM + /****** Cortex-M4 Processor Exceptions Numbers ****************************************************************/ + NonMaskableInt_IRQn = -14, /*!< 2 Cortex-M4 Non Maskable Interrupt */ + HardFault_IRQn = -13, /*!< 3 Cortex-M4 Hard Fault Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Cortex-M4 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Cortex-M4 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Cortex-M4 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M4 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Cortex-M4 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M4 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M4 System Tick Interrupt */ +#endif +#ifdef ARCH_RISCV + SSOFT_IRQn = 1, /*!< 1 RISCV supervisor software Interrupt */ + MSOFT_IRQn = 3, /*!< 3 RISCV machine software Interrupt */ + STIME_IRQn = 5, /*!< 5 RISCV supervisor time Interrupt */ + MTIME_IRQn = 7, /*!< 7 RISCV machine time Interrupt */ + SEXT_IRQn = 9, /*!< 9 RISCV S-mode external Interrupt */ + MEXT_IRQn = 11, /*!< 11 RISCV M-mode external Interrupt */ + CLIC_SOFT_PEND_IRQn = 12, /*!< 12 RISCV CLIC software pending Interrupt */ +#if (__riscv_xlen == 64) + HPM_OVF_IRQn = 17, /*!< 17 RISCV HPM counter overflow Interrupt */ +#endif +#endif +#if defined(CPU_M0) || defined(CPU_LP) +#ifdef CPU_LP +#define CPU_LP_MAX_IRQ_NUM (IRQ_NUM_BASE + 32) +#endif + /****** BL808 specific Interrupt Numbers **********************************************************************/ + BMX_MCU_BUS_ERR_IRQn = IRQ_NUM_BASE + 0, /*!< bmx mcu bus_err_int Interrupt */ + BMX_MCU_TO_IRQn = IRQ_NUM_BASE + 1, /*!< bmx_timeout_int|mcu_timeout_int Interrupt */ + M0_RESERVED2_IRQn = IRQ_NUM_BASE + 2, /*!< reserved Interrupt */ + IPC_M0_IRQn = IRQ_NUM_BASE + 3, /*!< ipc0_m0_irq Interrupt */ + AUDIO_IRQn = IRQ_NUM_BASE + 4, /*!< Audio Interrupt */ + RF_TOP_INT0_IRQn = IRQ_NUM_BASE + 5, /*!< RF_TOP_INT0 Interrupt */ + RF_TOP_INT1_IRQn = IRQ_NUM_BASE + 6, /*!< RF_TOP_INT1 Interrupt */ + LZ4D_IRQn = IRQ_NUM_BASE + 7, /*!< LZ4 decompressor Interrupt */ + GAUGE_ITF_IRQn = IRQ_NUM_BASE + 8, /*!< gauge_itf_int Interrupt */ + SEC_ENG_ID1_SHA_AES_TRNG_PKA_GMAC_IRQn = IRQ_NUM_BASE + 9, /*!< sec_eng_id1 Interrupt */ + SEC_ENG_ID0_SHA_AES_TRNG_PKA_GMAC_IRQn = IRQ_NUM_BASE + 10, /*!< sec_eng_id0 Interrupt */ + SEC_ENG_ID1_CDET_IRQn = IRQ_NUM_BASE + 11, /*!< sec_eng_id1_cdet Interrupt */ + SEC_ENG_ID0_CDET_IRQn = IRQ_NUM_BASE + 12, /*!< sec_eng_id0_cdet Interrupt */ + SF_CTRL_ID1_IRQn = IRQ_NUM_BASE + 13, /*!< sf_ctrl_id1 Interrupt */ + SF_CTRL_ID0_IRQn = IRQ_NUM_BASE + 14, /*!< sf_ctrl_id0 Interrupt */ + DMA0_ALL_IRQn = IRQ_NUM_BASE + 15, /*!< DMA0_INTR_ALL Interrupt */ + DMA1_ALL_IRQn = IRQ_NUM_BASE + 16, /*!< DMA1_INTR_ALL Interrupt */ + SDH_IRQn = IRQ_NUM_BASE + 17, /*!< sdh Interrupt */ + MM_ALL_IRQn = IRQ_NUM_BASE + 18, /*!< MM System All Interrupt */ + IRTX_IRQn = IRQ_NUM_BASE + 19, /*!< IR TX Interrupt */ + IRRX_IRQn = IRQ_NUM_BASE + 20, /*!< IR RX Interrupt */ + USB_IRQn = IRQ_NUM_BASE + 21, /*!< USB Interrupt */ + AUPDM_TOUCH_IRQn = IRQ_NUM_BASE + 22, /*!< aupdm_touch_int Interrupt */ + M0_RESERVED23_IRQn = IRQ_NUM_BASE + 23, /*!< reserved Interrupt */ + EMAC_IRQn = IRQ_NUM_BASE + 24, /*!< EMAC Interrupt */ + GPADC_DMA_IRQn = IRQ_NUM_BASE + 25, /*!< GPADC_DMA Interrupt */ + EFUSE_IRQn = IRQ_NUM_BASE + 26, /*!< Efuse Interrupt */ + SPI0_IRQn = IRQ_NUM_BASE + 27, /*!< SPI0 Interrupt */ + UART0_IRQn = IRQ_NUM_BASE + 28, /*!< UART0 Interrupt */ + UART1_IRQn = IRQ_NUM_BASE + 29, /*!< UART1 Interrupt */ + UART2_IRQn = IRQ_NUM_BASE + 30, /*!< UART2 Interrupt */ + GPIO_DMA_IRQn = IRQ_NUM_BASE + 31, /*!< GPIO DMA Interrupt */ + I2C0_IRQn = IRQ_NUM_BASE + 32, /*!< I2C0 Interrupt */ + PWM_IRQn = IRQ_NUM_BASE + 33, /*!< PWM Interrupt */ + IPC_RSVD_IRQn = IRQ_NUM_BASE + 34, /*!< ipc reserved Interrupt */ + IPC_LP_IRQn = IRQ_NUM_BASE + 35, /*!< ipc lp_irq Interrupt */ + TIMER0_CH0_IRQn = IRQ_NUM_BASE + 36, /*!< Timer0 Channel 0 Interrupt */ + TIMER0_CH1_IRQn = IRQ_NUM_BASE + 37, /*!< Timer0 Channel 1 Interrupt */ + TIMER0_WDT_IRQn = IRQ_NUM_BASE + 38, /*!< Timer0 Watch Dog Interrupt */ + I2C1_IRQn = IRQ_NUM_BASE + 39, /*!< I2C1 Interrupt */ + I2S_IRQn = IRQ_NUM_BASE + 40, /*!< I2S Interrupt */ + ANA_OCP_OUT_TO_CPU_0_IRQn = IRQ_NUM_BASE + 41, /*!< ana_ocp_out_to_cpu_irq0 Interrupt */ + ANA_OCP_OUT_TO_CPU_1_IRQn = IRQ_NUM_BASE + 42, /*!< ana_ocp_out_to_cpu_irq1 Interrupt */ + ANA_OCP_OUT_TO_CPU_2_IRQn = IRQ_NUM_BASE + 43, /*!< ana_ocp_out_to_cpu_irq2 Interrupt */ + GPIO_INT0_IRQn = IRQ_NUM_BASE + 44, /*!< GPIO Interrupt */ + DM_IRQn = IRQ_NUM_BASE + 45, /*!< DM Interrupt */ + BT_IRQn = IRQ_NUM_BASE + 46, /*!< BT Interrupt */ + M154_REQ_ACK_IRQn = IRQ_NUM_BASE + 47, /*!< M154 req enh ack Interrupt */ + M154_INT_IRQn = IRQ_NUM_BASE + 48, /*!< M154 Interrupt */ + M154_AES_IRQn = IRQ_NUM_BASE + 49, /*!< m154 aes Interrupt */ + PDS_WAKEUP_IRQn = IRQ_NUM_BASE + 50, /*!< PDS Wakeup Interrupt */ + HBN_OUT0_IRQn = IRQ_NUM_BASE + 51, /*!< Hibernate out 0 Interrupt */ + HBN_OUT1_IRQn = IRQ_NUM_BASE + 52, /*!< Hibernate out 1 Interrupt */ + BOR_IRQn = IRQ_NUM_BASE + 53, /*!< BOR Interrupt */ + WIFI_IRQn = IRQ_NUM_BASE + 54, /*!< WIFI To CPU Interrupt */ + BZ_PHY_INT_IRQn = IRQ_NUM_BASE + 55, /*!< BZ phy Interrupt */ + BLE_IRQn = IRQ_NUM_BASE + 56, /*!< BLE Interrupt */ + MAC_TXRX_TIMER_IRQn = IRQ_NUM_BASE + 57, /*!< MAC Tx Rx Timer Interrupt */ + MAC_TXRX_MISC_IRQn = IRQ_NUM_BASE + 58, /*!< MAC Tx Rx Misc Interrupt */ + MAC_RX_TRG_IRQn = IRQ_NUM_BASE + 59, /*!< MAC Rx Trigger Interrupt */ + MAC_TX_TRG_IRQn = IRQ_NUM_BASE + 60, /*!< MAC tx Trigger Interrupt */ + MAC_GEN_IRQn = IRQ_NUM_BASE + 61, /*!< MAC Gen Interrupt */ + MAC_PORT_TRG_IRQn = IRQ_NUM_BASE + 62, /*!< MAC Prot Trigger Interrupt */ + WIFI_IPC_PUBLIC_IRQn = IRQ_NUM_BASE + 63, /*!< WIFI Ipc Interrupt */ + IRQn_LAST, +#endif + +#if defined(CPU_D0) + /****** BL808 specific Interrupt Numbers **********************************************************************/ + BMX_DSP_BUS_ERR_IRQn = IRQ_NUM_BASE + 0, /*!< BMX DSP BUS Error Interrupt */ + DSP2_AWB2_IRQn = IRQ_NUM_BASE + 1, /*!< DSP2 AWB3 Interrupt */ + D0_RESERVED2_IRQn = IRQ_NUM_BASE + 2, /*!< IPC reserved Interrupt */ + D0_RESERVED3_IRQn = IRQ_NUM_BASE + 3, /*!< UART4 reserved Interrupt */ + UART3_IRQn = IRQ_NUM_BASE + 4, /*!< UART3 Interrupt */ + I2C2_IRQn = IRQ_NUM_BASE + 5, /*!< I2C2 Interrupt */ + I2C3_IRQn = IRQ_NUM_BASE + 6, /*!< I2C3 Interrupt */ + SPI1_IRQn = IRQ_NUM_BASE + 7, /*!< SPI1 Interrupt */ + DSP2_AE_IRQn = IRQ_NUM_BASE + 8, /*!< DSP2 AE Interrupt */ + DSP2_AWB0_IRQn = IRQ_NUM_BASE + 9, /*!< DSP2 AWB1 Interrupt */ + SEOF_INT0_IRQn = IRQ_NUM_BASE + 10, /*!< SEOF INT0 Interrupt */ + SEOF_INT1_IRQn = IRQ_NUM_BASE + 11, /*!< SEOF INT1 Interrupt */ + SEOF_INT2_IRQn = IRQ_NUM_BASE + 12, /*!< SEOF INT2 Interrupt */ + DVP2BUS_INT0_IRQn = IRQ_NUM_BASE + 13, /*!< DVP2BUS INT0 Interrupt */ + DVP2BUS_INT1_IRQn = IRQ_NUM_BASE + 14, /*!< DVP2BUS INT1 Interrupt */ + DVP2BUS_INT2_IRQn = IRQ_NUM_BASE + 15, /*!< DVP2BUS INT2 Interrupt */ + DVP2BUS_INT3_IRQn = IRQ_NUM_BASE + 16, /*!< DVP2BUS INT3 Interrupt */ + H264_BS_IRQn = IRQ_NUM_BASE + 17, /*!< H264 BS Interrupt */ + H264_FRAME_IRQn = IRQ_NUM_BASE + 18, /*!< H264 Frame Interrupt */ + H264_SEQ_DONE_IRQn = IRQ_NUM_BASE + 19, /*!< H264 SEQ Done Interrupt */ + MJPEG_IRQn = IRQ_NUM_BASE + 20, /*!< MJPEG Interrupt */ + H264_S_BS_IRQn = IRQ_NUM_BASE + 21, /*!< H264 S BS Interrupt */ + H264_S_FRAME_IRQn = IRQ_NUM_BASE + 22, /*!< H264 S Frame Interrupt */ + H264_S_SEQ_DONE_IRQn = IRQ_NUM_BASE + 23, /*!< H264 S SEQ Done Interrupt */ + DMA2_INT0_IRQn = IRQ_NUM_BASE + 24, /*!< DMA2 INT0 Interrupt */ + DMA2_INT1_IRQn = IRQ_NUM_BASE + 25, /*!< DMA2 INT1 Interrupt */ + DMA2_INT2_IRQn = IRQ_NUM_BASE + 26, /*!< DMA2 INT2 Interrupt */ + DMA2_INT3_IRQn = IRQ_NUM_BASE + 27, /*!< DMA2 INT3 Interrupt */ + DMA2_INT4_IRQn = IRQ_NUM_BASE + 28, /*!< DMA2 INT4 Interrupt */ + DMA2_INT5_IRQn = IRQ_NUM_BASE + 29, /*!< DMA2 INT5 Interrupt */ + DMA2_INT6_IRQn = IRQ_NUM_BASE + 30, /*!< DMA2 INT6 Interrupt */ + DMA2_INT7_IRQn = IRQ_NUM_BASE + 31, /*!< DMA2 INT7 Interrupt */ + SDH_MMC1_IRQn = IRQ_NUM_BASE + 32, /*!< SDH MMC1 Interrupt */ + SDH_MMC3_IRQn = IRQ_NUM_BASE + 33, /*!< SDH MMC3 Interrupt */ + SDH2PMU_WAKEUP1_IRQn = IRQ_NUM_BASE + 34, /*!< SDH2PMU Wakeup1 Interrupt */ + SDH2PMU_WAKEUP3_IRQn = IRQ_NUM_BASE + 35, /*!< SDH2PMU Wakeup3 Interrupt */ + EMAC2_IRQn = IRQ_NUM_BASE + 36, /*!< EMAC2 Interrupt */ + MIPI_CSI_IRQn = IRQ_NUM_BASE + 37, /*!< MIPI CSI Interrupt */ + IPC_D0_IRQn = IRQ_NUM_BASE + 38, /*!< IPC D0 Interrupt */ + APU_IRQn = IRQ_NUM_BASE + 39, /*!< APU Interrupt */ + MJDEC_IRQn = IRQ_NUM_BASE + 40, /*!< MJDEC Interrupt */ + DVP2BUS_INT4_IRQn = IRQ_NUM_BASE + 41, /*!< DVP2BUS INT4 Interrupt */ + DVP2BUS_INT5_IRQn = IRQ_NUM_BASE + 42, /*!< DVP2BUS INT5 Interrupt */ + DVP2BUS_INT6_IRQn = IRQ_NUM_BASE + 43, /*!< DVP2BUS INT6 Interrupt */ + DVP2BUS_INT7_IRQn = IRQ_NUM_BASE + 44, /*!< DVP2BUS INT7 Interrupt */ + DMA2D_INT0_IRQn = IRQ_NUM_BASE + 45, /*!< DMA2D INT0 Interrupt */ + DMA2D_INT1_IRQn = IRQ_NUM_BASE + 46, /*!< DMA2D INT1 Interrupt */ + DISPLAY_IRQn = IRQ_NUM_BASE + 47, /*!< Display Interrupt */ + PWM_IRQn = IRQ_NUM_BASE + 48, /*!< PWM1 Interrupt */ + SEOF_INT3_IRQn = IRQ_NUM_BASE + 49, /*!< SEOF INT0 Interrupt */ + RESERVED1_IRQn = IRQ_NUM_BASE + 50, /*!< Reserved Interrupt */ + RESERVED2_IRQn = IRQ_NUM_BASE + 51, /*!< Reserved Interrupt */ + OSD_IRQn = IRQ_NUM_BASE + 52, /*!< OSD Interrupt */ + DBI_IRQn = IRQ_NUM_BASE + 53, /*!< DBI Interrupt */ + DSP2_WDR_IRQn = IRQ_NUM_BASE + 54, /*!< DSP2 WDR Interrupt */ + OSDA_BUS_DRAIN_IRQn = IRQ_NUM_BASE + 55, /*!< OSDA Bus Drain Interrupt */ + OSDB_BUS_DRAIN_IRQn = IRQ_NUM_BASE + 56, /*!< OSDB Bus Drain Interrupt */ + OSD_PB_IRQn = IRQ_NUM_BASE + 57, /*!< OSD PB Interrupt */ + DSP2_AWB1_IRQn = IRQ_NUM_BASE + 58, /*!< DSP2 AWB2 Interrupt */ + MIPI_DSI_IRQn = IRQ_NUM_BASE + 59, /*!< MIPI DSI Interrupt */ + DSP2_AE_HIST_IRQn = IRQ_NUM_BASE + 60, /*!< DSP2 AE HIST Interrupt */ + TIMER1_CH0_IRQn = IRQ_NUM_BASE + 61, /*!< Timer1 Channel 0 Interrupt */ + TIMER1_CH1_IRQn = IRQ_NUM_BASE + 62, /*!< Timer1 Channel 1 Interrupt */ + TIMER1_WDT_IRQn = IRQ_NUM_BASE + 63, /*!< Timer1 Watch Dog Interrupt */ + AUDIO_IRQn = IRQ_NUM_BASE + 64, /*!< Audio Interrupt */ + WL_ALL_IRQn = IRQ_NUM_BASE + 65, /*!< WL System All Interrupt */ + PDS_IRQn = IRQ_NUM_BASE + 66, /*!< PDS Interrupt */ + IRQn_LAST, +#endif +} IRQn_Type; + +/* Add following macro definition in order to pass the compilation */ +#if defined(CPU_M0) || defined(CPU_LP) +#define BMX_DSP_BUS_ERR_IRQn (IRQn_LAST) +#define DSP2_AWB2_IRQn (IRQn_LAST) +#define D0_RESERVED2_IRQn (IRQn_LAST) +#define UART3_IRQn (IRQn_LAST) +#define I2C2_IRQn (IRQn_LAST) +#define I2C3_IRQn (IRQn_LAST) +#define SPI1_IRQn (IRQn_LAST) +#define DSP2_AE_IRQn (IRQn_LAST) +#define DSP2_AWB0_IRQn (IRQn_LAST) +#define SEOF_INT0_IRQn (IRQn_LAST) +#define SEOF_INT1_IRQn (IRQn_LAST) +#define SEOF_INT2_IRQn (IRQn_LAST) +#define DVP2BUS_INT0_IRQn (IRQn_LAST) +#define DVP2BUS_INT1_IRQn (IRQn_LAST) +#define DVP2BUS_INT2_IRQn (IRQn_LAST) +#define DVP2BUS_INT3_IRQn (IRQn_LAST) +#define H264_BS_IRQn (IRQn_LAST) +#define H264_FRAME_IRQn (IRQn_LAST) +#define H264_SEQ_DONE_IRQn (IRQn_LAST) +#define MJPEG_IRQn (IRQn_LAST) +#define H264_S_BS_IRQn (IRQn_LAST) +#define H264_S_FRAME_IRQn (IRQn_LAST) +#define H264_S_SEQ_DONE_IRQn (IRQn_LAST) +#define DMA2_INT0_IRQn (IRQn_LAST) +#define DMA2_INT1_IRQn (IRQn_LAST) +#define DMA2_INT2_IRQn (IRQn_LAST) +#define DMA2_INT3_IRQn (IRQn_LAST) +#define DMA2_INT4_IRQn (IRQn_LAST) +#define DMA2_INT5_IRQn (IRQn_LAST) +#define DMA2_INT6_IRQn (IRQn_LAST) +#define DMA2_INT7_IRQn (IRQn_LAST) +#define SDH_MMC1_IRQn (IRQn_LAST) +#define SDH_MMC3_IRQn (IRQn_LAST) +#define SDH2PMU_WAKEUP1_IRQn (IRQn_LAST) +#define SDH2PMU_WAKEUP3_IRQn (IRQn_LAST) +#define EMAC2_IRQn (IRQn_LAST) +#define MIPI_CSI_IRQn (IRQn_LAST) +#define IPC_D0_IRQn (IRQn_LAST) +#define APU_IRQn (IRQn_LAST) +#define MJDEC_IRQn (IRQn_LAST) +#define DVP2BUS_INT4_IRQn (IRQn_LAST) +#define DVP2BUS_INT5_IRQn (IRQn_LAST) +#define DVP2BUS_INT6_IRQn (IRQn_LAST) +#define DVP2BUS_INT7_IRQn (IRQn_LAST) +#define DMA2D_INT0_IRQn (IRQn_LAST) +#define DMA2D_INT1_IRQn (IRQn_LAST) +#define DISPLAY_IRQn (IRQn_LAST) +#define SEOF_INT3_IRQn (IRQn_LAST) +#define RESERVED1_IRQn (IRQn_LAST) +#define RESERVED2_IRQn (IRQn_LAST) +#define OSD_IRQn (IRQn_LAST) +#define DBI_IRQn (IRQn_LAST) +#define DSP2_WDR_IRQn (IRQn_LAST) +#define OSDA_BUS_DRAIN_IRQn (IRQn_LAST) +#define OSDB_BUS_DRAIN_IRQn (IRQn_LAST) +#define OSD_PB_IRQn (IRQn_LAST) +#define DSP2_AWB1_IRQn (IRQn_LAST) +#define MIPI_DSI_IRQn (IRQn_LAST) +#define DSP2_AE_HIST_IRQn (IRQn_LAST) +#define TIMER1_CH0_IRQn (IRQn_LAST) +#define TIMER1_CH1_IRQn (IRQn_LAST) +#define TIMER1_WDT_IRQn (IRQn_LAST) +#define WL_ALL_IRQn (IRQn_LAST) +#define PDS_IRQn (IRQn_LAST) +#endif + +#if defined(CPU_D0) +#define BMX_MCU_BUS_ERR_IRQn (IRQn_LAST) +#define BMX_MCU_TO_IRQn (IRQn_LAST) +#define M0_RESERVED2_IRQn (IRQn_LAST) +#define IPC_M0_IRQn (IRQn_LAST) +#define RF_TOP_INT0_IRQn (IRQn_LAST) +#define RF_TOP_INT1_IRQn (IRQn_LAST) +#define LZ4D_IRQn (IRQn_LAST) +#define GAUGE_ITF_IRQn (IRQn_LAST) +#define SEC_ENG_ID1_SHA_AES_TRNG_PKA_GMAC_IRQn (IRQn_LAST) +#define SEC_ENG_ID0_SHA_AES_TRNG_PKA_GMAC_IRQn (IRQn_LAST) +#define SEC_ENG_ID1_CDET_IRQn (IRQn_LAST) +#define SEC_ENG_ID0_CDET_IRQn (IRQn_LAST) +#define SF_CTRL_ID1_IRQn (IRQn_LAST) +#define SF_CTRL_ID0_IRQn (IRQn_LAST) +#define DMA0_ALL_IRQn (IRQn_LAST) +#define DMA1_ALL_IRQn (IRQn_LAST) +#define SDH_IRQn (IRQn_LAST) +#define MM_ALL_IRQn (IRQn_LAST) +#define IRTX_IRQn (IRQn_LAST) +#define IRRX_IRQn (IRQn_LAST) +#define USB_IRQn (IRQn_LAST) +#define AUPDM_TOUCH_IRQn (IRQn_LAST) +#define M0_RESERVED23_IRQn (IRQn_LAST) +#define EMAC_IRQn (IRQn_LAST) +#define GPADC_DMA_IRQn (IRQn_LAST) +#define EFUSE_IRQn (IRQn_LAST) +#define SPI0_IRQn (IRQn_LAST) +#define UART0_IRQn (IRQn_LAST) +#define UART1_IRQn (IRQn_LAST) +#define UART2_IRQn (IRQn_LAST) +#define GPIO_DMA_IRQn (IRQn_LAST) +#define I2C0_IRQn (IRQn_LAST) +#define IPC_RSVD_IRQn (IRQn_LAST) +#define IPC_LP_IRQn (IRQn_LAST) +#define TIMER0_CH0_IRQn (IRQn_LAST) +#define TIMER0_CH1_IRQn (IRQn_LAST) +#define TIMER0_WDT_IRQn (IRQn_LAST) +#define I2C1_IRQn (IRQn_LAST) +#define I2S_IRQn (IRQn_LAST) +#define ANA_OCP_OUT_TO_CPU_0_IRQn (IRQn_LAST) +#define ANA_OCP_OUT_TO_CPU_1_IRQn (IRQn_LAST) +#define ANA_OCP_OUT_TO_CPU_2_IRQn (IRQn_LAST) +#define GPIO_INT0_IRQn (IRQn_LAST) +#define DM_IRQn (IRQn_LAST) +#define BT_IRQn (IRQn_LAST) +#define M154_REQ_ACK_IRQn (IRQn_LAST) +#define M154_INT_IRQn (IRQn_LAST) +#define M154_AES_IRQn (IRQn_LAST) +#define PDS_WAKEUP_IRQn (IRQn_LAST) +#define HBN_OUT0_IRQn (IRQn_LAST) +#define HBN_OUT1_IRQn (IRQn_LAST) +#define BOR_IRQn (IRQn_LAST) +#define WIFI_IRQn (IRQn_LAST) +#define BZ_PHY_INT_IRQn (IRQn_LAST) +#define BLE_IRQn (IRQn_LAST) +#define MAC_TXRX_TIMER_IRQn (IRQn_LAST) +#define MAC_TXRX_MISC_IRQn (IRQn_LAST) +#define MAC_RX_TRG_IRQn (IRQn_LAST) +#define MAC_TX_TRG_IRQn (IRQn_LAST) +#define MAC_GEN_IRQn (IRQn_LAST) +#define MAC_PORT_TRG_IRQn (IRQn_LAST) +#define WIFI_IPC_PUBLIC_IRQn (IRQn_LAST) +#endif + +/** + * @brief BL808 Memory Map Definitions + */ +#define BL808_OCRAM_BASE (0x22020000) +#define BL808_OCRAM_END (0x22020000 + 64 * 1024) +#define BL808_OCRAM_CACHEABLE_BASE (0x62020000) +#define BL808_OCRAM_CACHEABLE_END (0x62020000 + 64 * 1024) + +#define BL808_WRAM_BASE (0x22030000) +#define BL808_WRAM_END (0x22030000 + 160 * 1024) +#define BL808_WRAM_CACHEABLE_BASE (0x62030000) +#define BL808_WRAM_CACHEABLE_END (0x62030000 + 160 * 1024) + +#define BL808_MCU_ALLRAM_BASE (0x22020000) +#define BL808_MCU_ALLRAM_END (0x22020000 + 64 * 1024 + 160 * 1024) +#define BL808_MCU_ALLRAM_CACHEABLE_BASE (0x62020000) +#define BL808_MCU_ALLRAM_CACHEABLE_END (0x62020000 + 64 * 1024 + 160 * 1024) + +#define BL808_DRAM_BASE (0x3EF80000) +#define BL808_DRAM_END (0x3EF80000 + 512 * 1024) +#define BL808_DRAM_CACHEABLE_BASE (0x7EF80000) +#define BL808_DRAM_CACHEABLE_END (0x7EF80000 + 512 * 1024) + +#define BL808_VRAM_BASE (0x3F000000) +#define BL808_VRAM_END (0x3F000000 + 32 * 1024) +#define BL808_VRAM_CACHEABLE_BASE (0x7F000000) +#define BL808_VRAM_CACHEABLE_END (0x7F000000 + 32 * 1024) + +#define BL808_MM_ALLRAM_BASE (0x3EF80000) +#define BL808_MM_ALLRAM_END (0x3EF80000 + 512 * 1024 + 32 * 1024) +#define BL808_MM_ALLRAM_CACHEABLE_BASE (0x7EF80000) +#define BL808_MM_ALLRAM_CACHEABLE_END (0x7EF80000 + 512 * 1024 + 32 * 1024) + +#define BL808_FLASH_XIP_BASE (0x58000000) +#define BL808_FLASH_XIP_END (0x58000000 + 64 * 1024 * 1024) +#define BL808_FLASH2_XIP_BASE (0x5C000000) +#define BL808_FLASH2_XIP_END (0x5C000000 + 64 * 1024 * 1024) +#define BL808_FLASH_XIP_REMAP0_BASE (0xD8000000) +#define BL808_FLASH_XIP_REMAP0_END (0xD8000000 + 64 * 1024 * 1024) +#define BL808_FLASH2_XIP_REMAP0_BASE (0xDC000000) +#define BL808_FLASH2_XIP_REMAP0_END (0xDC000000 + 64 * 1024 * 1024) + +#define BL808_MM_WHOLERAM_BASE (0x3EF80000) +#define BL808_MM_WHOLERAM_END (0x3EF80000 + 512 * 1024 + 96 * 1024) +#define BL808_MM_WHOLERAM_CACHEABLE_BASE (0x7EF80000) +#define BL808_MM_WHOLERAM_CACHEABLE_END (0x7EF80000 + 512 * 1024 + 96 * 1024) + +/*@} end of group Memory_Map_Section */ + +/* BL808 peripherals base address */ +/* WLSYS */ +#define GLB_BASE ((uint32_t)0x20000000) +#define MIX_BASE ((uint32_t)0x20001000) +#define GPIP_BASE ((uint32_t)0x20002000) +#define PHY_BASE ((uint32_t)0x20002800) +#define AGC_BASE ((uint32_t)0x20002c00) +#define SEC_DBG_BASE ((uint32_t)0x20003000) +#define SEC_ENG_BASE ((uint32_t)0x20004000) +#define TZ1_BASE ((uint32_t)0x20005000) +#define TZC_SEC_BASE ((uint32_t)0x20005000) +#define TZ2_BASE ((uint32_t)0x20006000) +#define TZC_NSEC_BASE ((uint32_t)0x20006000) +#define EFUSE_BASE ((uint32_t)0x20056000) +#define EF_DATA_BASE ((uint32_t)0x20056000) +#define EF_CTRL_BASE ((uint32_t)0x20056000) +#define CCI_BASE ((uint32_t)0x20008000) +#define MCU_MISC_BASE ((uint32_t)0x20009000) +#define L1C_BASE ((uint32_t)0x20009000) +#define UART0_BASE ((uint32_t)0x2000a000) +#define UART1_BASE ((uint32_t)0x2000a100) +#define SPI0_BASE ((uint32_t)0x2000a200) +#define I2C0_BASE ((uint32_t)0x2000a300) +#define PWM_BASE ((uint32_t)0x2000a400) +#define TIMER0_BASE ((uint32_t)0x2000a500) +#define IR_BASE ((uint32_t)0x2000a600) +#define CKS_BASE ((uint32_t)0x2000a700) +#define IPC0_BASE ((uint32_t)0x2000a800) +#define IPC1_BASE ((uint32_t)0x2000a840) +#define I2C1_BASE ((uint32_t)0x2000a900) +#define UART2_BASE ((uint32_t)0x2000aa00) +#define ISO11898_BASE ((uint32_t)0x2000aa00) +#define I2S_BASE ((uint32_t)0x2000ab00) +#define PDM0_BASE ((uint32_t)0x2000a000) +#define LZ4D_BASE ((uint32_t)0x2000ad00) +#define QSPI_BASE ((uint32_t)0x2000b000) +#define SF_CTRL_BASE ((uint32_t)0x2000b000) +#define SF_CTRL_BUF_BASE ((uint32_t)0x2000b600) +#define DMA0_BASE ((uint32_t)0x2000c000) +#define PDS_BASE ((uint32_t)0x2000e000) +#define HBN_BASE ((uint32_t)0x2000f000) +#define AON_BASE ((uint32_t)0x2000f000) +#define EMI_MISC_BASE ((uint32_t)0x20050000) +#define PSRAM_CTRL_BASE ((uint32_t)0x20052000) +#define USB_BASE ((uint32_t)0x20072000) +#define AUDIO_BASE ((uint32_t)0x20055000) +#define SDH_BASE ((uint32_t)0x20060000) +#define EMAC_BASE ((uint32_t)0x20070000) +#define DMA1_BASE ((uint32_t)0x20071000) + +/* MMSYS */ +#define MM_MISC_BASE ((uint32_t)0x30000000) +#define DMA2_BASE ((uint32_t)0x30001000) +#define UART3_BASE ((uint32_t)0x30002000) +#define I2C2_BASE ((uint32_t)0x30003000) +#define I2C3_BASE ((uint32_t)0x30004000) +#define IPC2_BASE ((uint32_t)0x30005000) +#define DMA2D_BASE ((uint32_t)0x30006000) +#define CLKRST_CTRL_BASE ((uint32_t)0x30007000) +#define MM_GLB_BASE ((uint32_t)0x30007000) +#define SPI1_BASE ((uint32_t)0x30008000) +#define TIMER1_BASE ((uint32_t)0x30009000) +#define PSRAM_UHS_BASE ((uint32_t)0x3000f000) + +/* DSP2_SUBSYS */ +#define DSP2_MISC_BASE ((uint32_t)0x30010000) +#define DSP2_BASE ((uint32_t)0x30011000) +#define DVP0_BASE ((uint32_t)0x30012000) +#define DVP1_BASE ((uint32_t)0x30012100) +#define DVP2_BASE ((uint32_t)0x30012200) +#define DVP3_BASE ((uint32_t)0x30012300) +#define DVP4_BASE ((uint32_t)0x30012400) +#define DVP5_BASE ((uint32_t)0x30012500) +#define DVP6_BASE ((uint32_t)0x30012600) +#define DVP7_BASE ((uint32_t)0x30012700) +#define DVP_TSRC0_BASE ((uint32_t)0x30012800) +#define DVP_TSRC1_BASE ((uint32_t)0x30012900) +#define AXI_CTRL_NR3D_BASE ((uint32_t)0x30012a00) +#define OSD_PROBE_BASE ((uint32_t)0x30012b00) +#define OSD_A_BASE ((uint32_t)0x30013000) +#define OSD_B_BASE ((uint32_t)0x30014000) +#define OSD_DP_BASE ((uint32_t)0x30015000) +#define OSD_BLEND0_OFFSET (0x000) +#define OSD_BLEND1_OFFSET (0x100) +#define OSD_BLEND2_OFFSET (0x200) +#define OSD_BLEND3_OFFSET (0x300) +#define OSD_DRAW_LOW_OFFSET (0x400) +#define OSD_DRAW_HIGH_OFFSET (0x504) +#define MIPI_BASE ((uint32_t)0x3001a000) +#define DBI_BASE ((uint32_t)0x3001b000) +#define DSI_BASE ((uint32_t)0x3001a100) + +/* CODEC_SUBSYS */ +#define CODEC_MISC_BASE ((uint32_t)0x30020000) +#define MJPEG_BASE ((uint32_t)0x30021000) +#define VIDEO_BASE ((uint32_t)0x30022000) +#define MJPEG_DEC_BASE ((uint32_t)0x30023000) +#define BL_CNN_BASE ((uint32_t)0x30024000) + +#define HBN_RAM_BASE ((uint32_t)0x20010000) + +#define RF_BASE ((uint32_t)0x20001000) + +typedef enum { + BL_AHB_MASTER_CPU = 0x00, + BL_AHB_MASTER_SDU = 0x01, + BL_AHB_MASTER_SEC = 0x02, + BL_AHB_MASTER_DMA = 0x03, + BL_AHB_MASTER_CCI = 0x04, + BL_AHB_MASTER_WIFI_PLATFORM = 0x05, + BL_AHB_MASTER_WIFI_MAC_PHY = 0x06, + BL_AHB_MASTER_WIFI_PHY = 0x07, + BL_AHB_MASTER_MAX = 0x08, +} BL_AHB_Master_Type; + +typedef enum { + BL_AHB_SLAVE1_GLB = 0x00, //cgen rsvd + BL_AHB_SLAVE1_RF_TOP = 0x01, //swrst mix + BL_AHB_SLAVE1_GPIP = 0x02, + BL_AHB_SLAVE1_SEC_DBG = 0x03, + BL_AHB_SLAVE1_SEC_ENG = 0x04, + BL_AHB_SLAVE1_TZ = 0x05, //swrst tz1,cgen tz1+tz2 + BL_AHB_SLAVE1_RSVD6 = 0x06, //swrst tz2, + BL_AHB_SLAVE1_EF_CTRL = 0x07, + BL_AHB_SLAVE1_CCI = 0x08, //cgen rsvd + BL_AHB_SLAVE1_L1C = 0x09, //cgen rsvd + BL_AHB_SLAVE1_RSVD10 = 0x0A, + BL_AHB_SLAVE1_SF_CTRL = 0x0B, + BL_AHB_SLAVE1_DMA = 0x0C, + BL_AHB_SLAVE1_SDU = 0x0D, //cgen rsvd + BL_AHB_SLAVE1_PDS = 0x0E, //cgen rsvd + BL_AHB_SLAVE1_RSVD15 = 0x0F, + BL_AHB_SLAVE1_UART0 = 0x10, + BL_AHB_SLAVE1_UART1 = 0x11, + BL_AHB_SLAVE1_SPI = 0x12, + BL_AHB_SLAVE1_I2C = 0x13, + BL_AHB_SLAVE1_PWM = 0x14, + BL_AHB_SLAVE1_TIMER = 0x15, + BL_AHB_SLAVE1_IRR = 0x16, + BL_AHB_SLAVE1_CKS = 0x17, + BL_AHB_SLAVE1_QDEC = 0x18, + BL_AHB_SLAVE1_KYS = 0x19, + BL_AHB_SLAVE1_UART2 = 0x1A, + BL_AHB_SLAVE1_RSVD27 = 0x1B, + BL_AHB_SLAVE1_RSVD28 = 0x1C, + BL_AHB_SLAVE1_RSVD29 = 0x1D, + BL_AHB_SLAVE1_RSVD30 = 0x1E, + BL_AHB_SLAVE1_RSVD31 = 0x1F, + BL_AHB_SLAVE1_MAX = 0x20, + BL_AHB_SLAVE1_GPADC = 0x21, /* not used for cgen and swrst */ + BL_AHB_SLAVE1_GPDAC = 0x22, /* not used for cgen and swrst */ + BL_AHB_SLAVE1_I2S = 0x23, /* not used for cgen and swrst */ + BL_AHB_SLAVE1_CAM = 0x24, /* not used for cgen and swrst */ +} BL_AHB_Slave1_Type; + +typedef enum { + BL_AHB_SLAVE2_RSVD0 = 0x00, + BL_AHB_SLAVE2_RSVD1 = 0x01, + BL_AHB_SLAVE2_RSVD2 = 0x02, + BL_AHB_SLAVE2_RSVD3 = 0x03, + BL_AHB_SLAVE2_WIFI = 0x04, + BL_AHB_SLAVE2_RSVD5 = 0x05, + BL_AHB_SLAVE2_RSVD6 = 0x06, + BL_AHB_SLAVE2_RSVD7 = 0x07, + BL_AHB_SLAVE2_BT_BLE = 0x08, + BL_AHB_SLAVE2_M154 = 0x09, + BL_AHB_SLAVE2_BT_BLE2 = 0x0A, + BL_AHB_SLAVE2_M1542 = 0x0B, + BL_AHB_SLAVE2_RSVD12 = 0x0C, + BL_AHB_SLAVE2_RSVD13 = 0x0D, + BL_AHB_SLAVE2_RSVD14 = 0x0E, + BL_AHB_SLAVE2_RSVD15 = 0x0F, + BL_AHB_SLAVE2_EXT_EMI_MISC = 0x10, + BL_AHB_SLAVE2_EXT_PSRAM0_CTRL = 0x11, + BL_AHB_SLAVE2_EXT_PSRAM1_CTRL = 0x12, + BL_AHB_SLAVE2_EXT_USB = 0x13, + BL_AHB_SLAVE2_EXT_MIX2 = 0x14, + BL_AHB_SLAVE2_EXT_AUDIO = 0x15, + BL_AHB_SLAVE2_EXT_SDH = 0x16, + BL_AHB_SLAVE2_EXT_EMAC = 0x17, + BL_AHB_SLAVE2_EXT_DMA2 = 0x18, + BL_AHB_SLAVE2_EXT_RSVD25 = 0x19, + BL_AHB_SLAVE2_EXT_RSVD26 = 0x1A, + BL_AHB_SLAVE2_EXT_RSVD27 = 0x1B, + BL_AHB_SLAVE2_MAX = 0x1C, +} BL_AHB_Slave2_Type; + +typedef enum { + BL_AHB_SLAVE3_WIFIPLL_240M = 0x00, + BL_AHB_SLAVE3_CPUPLL_120M = 0x01, + BL_AHB_SLAVE3_CPUPLL_300M = 0x02, + BL_AHB_SLAVE3_CPUPLL_600M = 0x03, + BL_AHB_SLAVE3_MAX = 0x04, +} BL_AHB_Slave3_Type; + +typedef enum { + BL_AHB_SEC_ENG_AES0 = 0, + BL_AHB_SEC_ENG_AES1, + BL_AHB_SEC_ENG_SHA0, + BL_AHB_SEC_ENG_SHA1, +} BL_AHB_Sec_Eng_Type; + +typedef enum { + BL_AHB_DMA0_CH0 = 0, + BL_AHB_DMA0_CH1, + BL_AHB_DMA0_CH2, + BL_AHB_DMA0_CH3, + BL_AHB_DMA0_CH4, + BL_AHB_DMA0_CH5, + BL_AHB_DMA0_CH6, + BL_AHB_DMA0_CH7, +} BL_AHB_DMA0_CHNL_Type; + +typedef enum { + BL_CORE_MASTER_IBUS_CPU = 0, + BL_CORE_MASTER_DBUS_CPU, + BL_CORE_MASTER_BUS_S2F, + BL_CORE_MASTER_MAX, +} BL_Core_Master_Type; + +typedef enum { + BL_CORE_SLAVE0_DTCM_CPU = 0, + BL_CORE_SLAVE0_MAX, +} BL_Core_Slave0_Type; + +typedef enum { + BL_CORE_SLAVE1_XIP_CPU = 0, + BL_CORE_SLAVE1_ITCM_CPU, + BL_CORE_SLAVE1_ROM, + BL_CORE_SLAVE1_MAX, +} BL_Core_Slave1_Type; + +typedef enum { + BL_CORE_SLAVE2_F2S = 0, + BL_CORE_SLAVE2_MAX, +} BL_Core_Slave2_Type; + +/** + * @} + */ +#include +#include +/* ARM CPU include files */ +#ifdef ARCH_ARM +#ifdef CPU_AP_CM4 +#include "core_cm4.h" /* Cortex-M4 processor and core peripherals */ +#endif +#ifdef CPU_NP_CM0 +#include "core_cm0.h" /* Cortex-M0 processor and core peripherals */ +#endif +#endif +/* RISCV CPU include files */ +#ifdef ARCH_RISCV +#ifdef __GNUC__ +#include +#endif +#endif + +#endif diff --git a/platforms/bl808_m0/vendor/psram/include/bl808_aon.h b/platforms/bl808_m0/vendor/psram/include/bl808_aon.h new file mode 100644 index 0000000..e35e8a5 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/bl808_aon.h @@ -0,0 +1,127 @@ +/** + ****************************************************************************** + * @file bl808_aon.h + * @version V1.0 + * @date + * @brief This file is the standard driver header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __BL808_AON_H__ +#define __BL808_AON_H__ + +#include "aon_reg.h" +#include "glb_reg.h" +#include "hbn_reg.h" +#include "pds_reg.h" +#include "bl808_ef_ctrl.h" +#include "bl808_common.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup AON + * @{ + */ + +/** @defgroup AON_Public_Types + * @{ + */ + +/** + * @brief AON DCDC level type definition + */ +typedef enum { + AON_DCDC_LEVEL_0P900V = 0, /*!< AON DCDC voltage 0.900V */ + AON_DCDC_LEVEL_1P075V = 7, /*!< AON DCDC voltage 1.075V */ + AON_DCDC_LEVEL_1P100V = 8, /*!< AON DCDC voltage 1.100V */ + AON_DCDC_LEVEL_1P125V = 9, /*!< AON DCDC voltage 1.125V */ + AON_DCDC_LEVEL_1P900V = 31, /*!< AON DCDC voltage 1.900V */ +} AON_DCDC_LEVEL_Type; + +/*@} end of group AON_Public_Types */ + +/** @defgroup AON_Public_Constants + * @{ + */ + +/*@} end of group AON_Public_Constants */ + +/** @defgroup AON_Public_Macros + * @{ + */ +/** @defgroup HBN_LDO_LEVEL_TYPE + * @{ + */ +#define IS_AON_DCDC_LEVEL_TYPE(type) (((type) == AON_DCDC_LEVEL_0P900V) || \ + ((type) == AON_DCDC_LEVEL_1P075V) || \ + ((type) == AON_DCDC_LEVEL_1P100V) || \ + ((type) == AON_DCDC_LEVEL_1P125V) || \ + ((type) == AON_DCDC_LEVEL_1P900V)) + +/*@} end of group AON_Public_Macros */ + +/** @defgroup AON_Public_Functions + * @{ + */ +/*----------*/ +BL_Err_Type AON_Power_On_MBG(void); +BL_Err_Type AON_Power_Off_MBG(void); +/*----------*/ +BL_Err_Type AON_Power_On_XTAL(void); +BL_Err_Type AON_Set_Xtal_CapCode(uint8_t capIn, uint8_t capOut); +uint8_t AON_Get_Xtal_CapCode(void); +BL_Err_Type AON_Power_Off_XTAL(void); +/*----------*/ +BL_Err_Type AON_Power_On_BG(void); +BL_Err_Type AON_Power_Off_BG(void); +/*----------*/ +BL_Err_Type AON_Trim_DCDC11_Vout(void); +BL_Err_Type AON_Trim_DCDC18_Vout(void); +BL_Err_Type AON_Trim_USB20_RCAL(void); +/*----------*/ +BL_Err_Type AON_Power_On_LDO15_RF(void); +BL_Err_Type AON_Power_Off_LDO15_RF(void); +/*----------*/ +BL_Err_Type AON_Power_On_SFReg(void); +BL_Err_Type AON_Power_Off_SFReg(void); +/*----------*/ +BL_Err_Type AON_LowPower_Enter_PDS0(void); +BL_Err_Type AON_LowPower_Exit_PDS0(void); +/*----------*/ +BL_Err_Type AON_Set_DCDC11_Top_Vout(AON_DCDC_LEVEL_Type dcdcLevel); + +/*@} end of group AON_Public_Functions */ + +/*@} end of group AON */ + +/*@} end of group BL808_Peripheral_Driver */ + +#endif /* __BL808_AON_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/bl808_clock.h b/platforms/bl808_m0/vendor/psram/include/bl808_clock.h new file mode 100644 index 0000000..989f922 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/bl808_clock.h @@ -0,0 +1,201 @@ +/** + ****************************************************************************** + * @file bl808_clock.h + * @version V1.0 + * @date + * @brief This file is the standard driver header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __BL808_CLOCK_H__ +#define __BL808_CLOCK_H__ + +#include "glb_reg.h" +#include "mcu_misc_reg.h" +#include "mm_misc_reg.h" +#include "pds_reg.h" +#include "bl808_glb.h" +#include "bl808_hbn.h" +#include "bl808_common.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup CLOCK + * @{ + */ + +/** @defgroup CLOCK_Public_Types + * @{ + */ + +/** + * @brief System clock type definition + */ +typedef enum { + BL_SYSTEM_CLOCK_MCU_XCLK, /*!< MCU xclk clock */ + BL_SYSTEM_CLOCK_MCU_ROOT_CLK, /*!< MCU root clock */ + BL_SYSTEM_CLOCK_MCU_CLK, /*!< MCU Fast clock/CPU clock */ + BL_SYSTEM_CLOCK_MCU_BCLK, /*!< MCU BUS clock */ + BL_SYSTEM_CLOCK_MCU_PBCLK, /*!< MCU peri BUS clock */ + BL_SYSTEM_CLOCK_DSP_XCLK, /*!< DSP xclk clock */ + BL_SYSTEM_CLOCK_DSP_ROOT_CLK, /*!< DSP root clock */ + BL_SYSTEM_CLOCK_DSP_CLK, /*!< DSP Fast clock/CPU clock */ + BL_SYSTEM_CLOCK_DSP_BCLK, /*!< DSP BUS clock */ + BL_SYSTEM_CLOCK_DSP_PBCLK, /*!< DSP peri BUS clock */ + BL_SYSTEM_CLOCK_LP_CLK, /*!< LP clock */ + BL_SYSTEM_CLOCK_F32K, /*!< F32K clock */ + BL_SYSTEM_CLOCK_XTAL, /*!< XTAL clock */ + BL_SYSTEM_CLOCK_MAX, /*!< MAX type of system clock */ +} BL_System_Clock_Type; + +/** + * @brief SOC clock config type + */ +typedef struct +{ + uint32_t magic; /*!< Clock config magic */ + uint32_t systemClock[BL_SYSTEM_CLOCK_MAX]; /*!< System lock value */ + uint32_t peripheralClock[BL_AHB_SLAVE1_MAX]; /*!< Pewripherals clock value */ + uint32_t i2sClock; /*!< I2S clock */ +} Clock_Cfg_Type; + +typedef enum { + CLOCK_AUPLL_DIV1, + CLOCK_AUPLL_DIV2, + CLOCK_AUPLL_DIV2P5, + CLOCK_AUPLL_DIV3, + CLOCK_AUPLL_DIV4, + CLOCK_AUPLL_DIV5, + CLOCK_AUPLL_DIV6, + CLOCK_AUPLL_DIV10, + CLOCK_AUPLL_DIV15, +} CLOCK_AUPLL_Type; + +/** + * @brief Peripheral clock type definition + */ +typedef enum { + BL_PERIPHERAL_CLOCK_UART0, /*!< UART0 clock */ + BL_PERIPHERAL_CLOCK_UART1, /*!< UART1 clock */ + BL_PERIPHERAL_CLOCK_UART2, /*!< UART2 clock */ + BL_PERIPHERAL_CLOCK_UART3, /*!< UART3 clock */ + BL_PERIPHERAL_CLOCK_SPI0, /*!< SPI0 clock */ + BL_PERIPHERAL_CLOCK_SPI1, /*!< SPI1 clock */ + BL_PERIPHERAL_CLOCK_I2C0, /*!< I2C0 clock */ + BL_PERIPHERAL_CLOCK_I2C1, /*!< I2C1 clock */ + BL_PERIPHERAL_CLOCK_I2C2, /*!< I2C2 clock */ + BL_PERIPHERAL_CLOCK_I2C3, /*!< I2C3 clock */ + BL_PERIPHERAL_CLOCK_TIMER0, /*!< TIMER0 clock */ + BL_PERIPHERAL_CLOCK_TIMER1, /*!< TIMER1 clock */ + BL_PERIPHERAL_CLOCK_PSRAMA, /*!< PSRAMA clock */ + BL_PERIPHERAL_CLOCK_PSRAMB, /*!< PSRAMB clock */ + BL_PERIPHERAL_CLOCK_FLASH, /*!< FLASH clock */ + BL_PERIPHERAL_CLOCK_I2S, /*!< I2S clock */ + BL_PERIPHERAL_CLOCK_BLAI, /*!< BLAI clock */ + BL_PERIPHERAL_CLOCK_DISPLAY, /*!< DISPLAY clock */ + BL_PERIPHERAL_CLOCK_IR, /*!< IR clock */ + BL_PERIPHERAL_CLOCK_PDM, /*!< PDM clock */ + BL_PERIPHERAL_CLOCK_ADC, /*!< ADC clock */ + BL_PERIPHERAL_CLOCK_DAC, /*!< DAC clock */ + BL_PERIPHERAL_CLOCK_GPADC, /*!< GPADC clock */ + BL_PERIPHERAL_CLOCK_GPDAC, /*!< GPDAC clock */ + BL_PERIPHERAL_CLOCK_CAM, /*!< CAM clock */ + BL_PERIPHERAL_CLOCK_SDH, /*!< SDH clock */ + BL_PERIPHERAL_CLOCK_PKA, /*!< PKA clock */ + BL_PERIPHERAL_CLOCK_EMI, /*!< EMI clock */ + BL_PERIPHERAL_CLOCK_H264, /*!< H264 clock */ + BL_PERIPHERAL_CLOCK_DSP2, /*!< DSP2 clock */ + BL_PERIPHERAL_CLOCK_MAX, +} BL_Peripheral_Type; + +/*@} end of group CLOCK_Public_Types */ + +/** @defgroup CLOCK_Public_Constants + * @{ + */ + +/** @defgroup BL_SYSTEM_CLOCK_TYPE + * @{ + */ +#define IS_BL_SYSTEM_CLOCK_TYPE(type) (((type) == BL_SYSTEM_CLOCK_MCU_XCLK) || \ + ((type) == BL_SYSTEM_CLOCK_MCU_ROOT_CLK) || \ + ((type) == BL_SYSTEM_CLOCK_MCU_CLK) || \ + ((type) == BL_SYSTEM_CLOCK_MCU_BCLK) || \ + ((type) == BL_SYSTEM_CLOCK_MCU_PBCLK) || \ + ((type) == BL_SYSTEM_CLOCK_DSP_XCLK) || \ + ((type) == BL_SYSTEM_CLOCK_DSP_ROOT_CLK) || \ + ((type) == BL_SYSTEM_CLOCK_DSP_CLK) || \ + ((type) == BL_SYSTEM_CLOCK_DSP_BCLK) || \ + ((type) == BL_SYSTEM_CLOCK_DSP_PBCLK) || \ + ((type) == BL_SYSTEM_CLOCK_LP_CLK) || \ + ((type) == BL_SYSTEM_CLOCK_F32K) || \ + ((type) == BL_SYSTEM_CLOCK_XTAL) || \ + ((type) == BL_SYSTEM_CLOCK_MAX)) + +/*@} end of group CLOCK_Public_Constants */ + +/** @defgroup CLOCK_Public_Macros + * @{ + */ +#define SYS_CLOCK_CFG_MAGIC (0x12345678) +#define SYS_CLOCK_CFG_ADDR (0x20010000 + 4 * 1024 - 512) + +/*@} end of group CLOCK_Public_Macros */ + +/** @defgroup CLOCK_Public_Functions + * @{ + */ +/*----------*/ +uint32_t Clock_System_Clock_Get(BL_System_Clock_Type type); +uint32_t Clock_Peripheral_Clock_Get(BL_Peripheral_Type type); +/*----------*/ +uint32_t SystemCoreClockGet(void); +/*----------*/ +BL_Err_Type CPU_Set_MTimer_RST(uint8_t rstEn); +BL_Err_Type CPU_Reset_MTimer(void); +BL_Err_Type CPU_Set_MTimer_CLK(uint8_t enable, uint16_t div); +uint32_t CPU_Get_MTimer_Source_Clock(void); +uint32_t CPU_Get_MTimer_Clock(void); +uint64_t CPU_Get_MTimer_Counter(void); +uint64_t CPU_Get_CPU_Cycle(void); +uint64_t CPU_Get_MTimer_US(void); +uint64_t CPU_Get_MTimer_MS(void); +BL_Err_Type CPU_MTimer_Delay_US(uint32_t cnt); +BL_Err_Type CPU_MTimer_Delay_MS(uint32_t cnt); +/*----------*/ + +/*@} end of group CLOCK_Public_Functions */ + +/*@} end of group CLOCK */ + +/*@} end of group BL808_Peripheral_Driver */ + +#endif /* __BL808_CLOCK_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/bl808_common.h b/platforms/bl808_m0/vendor/psram/include/bl808_common.h new file mode 100644 index 0000000..dc0d456 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/bl808_common.h @@ -0,0 +1,56 @@ +#ifndef __BL808_COMMON_H__ +#define __BL808_COMMON_H__ + +#include "bl808.h" +#include "misc.h" + +#ifndef __set_MSP +#define __set_MSP(msp) __ASM volatile("add sp, x0, %0" ::"r"(msp)) +#endif + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup COMMON + * @{ + */ + +/** @defgroup COMMON_Public_Types + * @{ + */ + +/*@} end of group COMMON_Public_Types */ + +/** @defgroup COMMON_Public_Constants + * @{ + */ + +/** @defgroup DRIVER_INT_PERIPH + * @{ + */ +#define IS_INT_PERIPH(INT_PERIPH) ((INT_PERIPH) < IRQn_LAST) + +/*@} end of group DRIVER_INT_PERIPH */ + +/** @defgroup DRIVER_INT_MASK + * @{ + */ +#define IS_BL_MASK_TYPE(type) (((type) == MASK) || ((type) == UNMASK)) + +/*@} end of group COMMON_Public_Constants */ + +/** @defgroup DRIVER_Public_FunctionDeclaration + * @brief DRIVER functions declaration + * @{ + */ + +void ASM_Delay_Us(uint32_t core, uint32_t cnt, uint32_t loopT); +void arch_delay_us(uint32_t cnt); +void arch_delay_ms(uint32_t cnt); + +void C906_All_Int_Enable(void); +void C906_All_Int_Disable(void); +/*@} end of group DRIVER_COMMON */ + +#endif /* __BL808_COMMON_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/bl808_ef_ctrl.h b/platforms/bl808_m0/vendor/psram/include/bl808_ef_ctrl.h new file mode 100644 index 0000000..9869abf --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/bl808_ef_ctrl.h @@ -0,0 +1,383 @@ +/** + ****************************************************************************** + * @file bl808_ef_ctrl.h + * @version V1.0 + * @date + * @brief This file is the standard driver header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __BL808_EF_CTRL_H__ +#define __BL808_EF_CTRL_H__ + +#include "ef_ctrl_reg.h" +#include "bl808_common.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup EF_CTRL + * @{ + */ + +/** @defgroup EF_CTRL_Public_Types + * @{ + */ + +/** + * @brief Efuse Ctrl key slot type definition + */ +typedef enum { + EF_CTRL_KEY_SLOT0, /*!< key slot 0 */ + EF_CTRL_KEY_SLOT1, /*!< key slot 1 */ + EF_CTRL_KEY_SLOT2, /*!< key slot 2 */ + EF_CTRL_KEY_SLOT3, /*!< key slot 3 */ + EF_CTRL_KEY_SLOT4, /*!< key slot 4 */ + EF_CTRL_KEY_SLOT5, /*!< key slot 5 */ + EF_CTRL_KEY_MAX, /*!< */ +} EF_Ctrl_Key_Type; + +/** + * @brief Efuse Ctrl sign type definition + */ +typedef enum { + EF_CTRL_SIGN_NONE, /*!< no sign */ + EF_CTRL_SIGN_RSA, /*!< use RSA to sign */ + EF_CTRL_SIGN_ECC, /*!< use ECC to sign */ +} EF_Ctrl_Sign_Type; + +/** + * @brief Efuse Ctrl flash AES type definition + */ +typedef enum { + EF_CTRL_SF_AES_NONE, /*!< No AES */ + EF_CTRL_SF_AES_128, /*!< AES 128 */ + EF_CTRL_SF_AES_192, /*!< AES 192 */ + EF_CTRL_SF_AES_256, /*!< AES 256 */ +} EF_Ctrl_SF_AES_Type; + +/** + * @brief Efuse Ctrl Dbg type definition + */ +typedef enum { + EF_CTRL_DBG_OPEN = 0, /*!< Open debug */ + EF_CTRL_DBG_PASSWORD, /*!< Open debug with password */ + EF_CTRL_DBG_CLOSE = 4, /*!< Close debug */ +} EF_Ctrl_Dbg_Mode_Type; + +/** + * @brief Efuse Ctrl clock type definition + */ +typedef enum { + EF_CTRL_EF_CLK, /*!< Select efuse clock */ + EF_CTRL_SAHB_CLK, /*!< Select SAHB clock */ +} EF_Ctrl_CLK_Type; + +/** + * @brief Efuse Ctrl clock type definition + */ +typedef enum { + EF_CTRL_PARA_DFT, /*!< Select default cyc parameter */ + EF_CTRL_PARA_MANUAL, /*!< Select manual cyc parameter */ +} EF_Ctrl_CYC_PARA_Type; + +/** + * @brief Efuse Ctrl clock type definition + */ +typedef enum { + EF_CTRL_OP_MODE_AUTO, /*!< Select efuse program auto mode */ + EF_CTRL_OP_MODE_MANUAL, /*!< Select efuse program manual mode */ +} EF_Ctrl_OP_MODE_Type; + +/** + * @brief Efuse Ctrl secure configuration structure type definition + */ +typedef struct +{ + EF_Ctrl_Dbg_Mode_Type ef_dbg_mode; /*!< Efuse debug mode */ + uint8_t ef_dbg_jtag_0_dis; /*!< Jtag debug disable config value */ + uint8_t ef_dbg_jtag_1_dis; /*!< Jtag debug disable config value */ + uint8_t ef_sboot_en; /*!< Secure boot enable config value */ +} EF_Ctrl_Sec_Param_Type; + +/** + * @brief Efuse analog dcdc11 trim type definition + */ +typedef struct +{ + uint32_t trimDcdc11VoutAon : 4; /*!< Efuse analog trim:dcdc11_vout_trim_aon */ + uint32_t trimDcdc11VoutAonParity : 1; /*!< Efuse analog trim:dcdc11_vout_trim_aon_parity */ + uint32_t trimDcdc11VoutAonEn : 1; /*!< Efuse analog trim:dcdc11_vout_trim_aon_en */ + uint32_t reserved : 26; /*!< Efuse analog trim:reserved */ +} Efuse_Ana_DCDC11_Trim_Type; + +/** + * @brief Efuse analog dcdc18 trim type definition + */ +typedef struct +{ + uint32_t trimDcdc18VoutAon : 4; /*!< Efuse analog trim:dcdc18_vout_trim_aon */ + uint32_t trimDcdc18VoutAonParity : 1; /*!< Efuse analog trim:dcdc18_vout_trim_aon_parity */ + uint32_t trimDcdc18VoutAonEn : 1; /*!< Efuse analog trim:dcdc18_vout_trim_aon_en */ + uint32_t reserved : 26; /*!< Efuse analog trim:reserved */ +} Efuse_Ana_DCDC18_Trim_Type; + +/** + * @brief Efuse analog ldo18flash trim type definition + */ +typedef struct +{ + uint32_t trimLdo18flashVoutAon : 4; /*!< Efuse analog trim:ldo18flash_vout_trim */ + uint32_t trimLdo18flashVoutAonParity : 1; /*!< Efuse analog trim:ldo18flash_vout_trim_parity */ + uint32_t trimLdo18flashVoutAonEn : 1; /*!< Efuse analog trim:ldo18flash_vout_trim_en */ + uint32_t reserved : 26; /*!< Efuse analog trim:reserved */ +} Efuse_Ana_LDO18FLASH_Trim_Type; + +/** + * @brief Efuse analog usb20rcal trim type definition + */ +typedef struct +{ + uint32_t trimUsb20rcalAon : 6; /*!< Efuse analog trim:usb20_rcal_code_aon */ + uint32_t trimUsb20rcalAonParity : 1; /*!< Efuse analog trim:usb20_rcal_code_aon_parity */ + uint32_t trimUsb20rcalAonEn : 1; /*!< Efuse analog trim:usb20_rcal_code_aon_en */ + uint32_t reserved : 24; /*!< Efuse analog trim:reserved */ +} Efuse_Ana_USB20RCAL_Trim_Type; + +/** + * @brief Efuse analog RC32M trim type definition + */ +typedef struct +{ + uint32_t trimRc32mCodeFrExt : 8; /*!< Efuse analog trim:trim_rc32m_code_fr_ext */ + uint32_t trimRc32mCodeFrExtParity : 1; /*!< Efuse analog trim:trim_rc32m_ext_code_en_parity */ + uint32_t trimRc32mExtCodeEn : 1; /*!< Efuse analog trim:trim_rc32m_ext_code_en */ + uint32_t reserved : 22; /*!< Efuse analog trim:reserved */ +} Efuse_Ana_RC32M_Trim_Type; + +/** + * @brief Efuse analog RC32K trim type definition + */ +typedef struct +{ + uint32_t trimRc32kCodeFrExt : 10; /*!< Efuse analog trim:trim_rc32k_code_fr_ext */ + uint32_t trimRc32kCodeFrExtParity : 1; /*!< Efuse analog trim:trim_rc32k_code_fr_ext_parity */ + uint32_t trimRc32kExtCodeEn : 1; /*!< Efuse analog trim:trim_rc32k_ext_code_en */ + uint32_t reserved : 20; /*!< Efuse analog trim:reserved */ +} Efuse_Ana_RC32K_Trim_Type; + +typedef struct +{ + uint32_t trimLdo18ioVoutVal : 4; /*!< Efuse analog trim:trim_ldo18io_vout_val */ + uint32_t trimLdo18ioVoutParity : 1; /*!< Efuse analog trim:trim_ldo18io_vout_parity */ + uint32_t trimLdo18ioVoutEn : 1; /*!< Efuse analog trim:trim_ldo18io_vout_en */ + uint32_t reserved : 26; /*!< Efuse analog trim:reserved */ +} Efuse_Ana_LDO18IO_VOUT_Trim_Type; + +/** + * @brief Efuse analog TSEN trim type definition + */ +typedef struct +{ + uint32_t tsenRefcodeCorner : 12; /*!< TSEN refcode */ + uint32_t tsenRefcodeCornerParity : 1; /*!< TSEN refcode parity */ + uint32_t tsenRefcodeCornerEn : 1; /*!< TSEN refcode enable */ + uint32_t tsenRefcodeCornerVersion : 1; /*!< TSEN refcode version */ + uint32_t reserved : 17; /*!< TSEN analog trim:reserved */ +} Efuse_TSEN_Refcode_Corner_Type; + +/** + * @brief Efuse analog ADC Gain trim type definition + */ +typedef struct +{ + uint32_t adcGainCoeff : 12; /*!< ADC gain coeff */ + uint32_t adcGainCoeffParity : 1; /*!< ADC gain coeff parity */ + uint32_t adcGainCoeffEn : 1; /*!< ADC gain coeff enable */ + uint32_t reserved : 18; /*!< ADC gain coeff:reserved */ +} Efuse_ADC_Gain_Coeff_Type; + +/** + * @brief Efuse analog device info type definition + */ +typedef struct +{ + uint32_t rsvd : 22; /*!< Reserved */ + uint32_t deviceInfo : 3; /*!< Efuse device information */ + uint32_t psramInfo : 2; /*!< Efuse psram info 0:no psram, 1:BW 4MB, 2:UHS 64MB */ + uint32_t memoryInfo : 2; /*!< Efuse memory info 0:no memory, 8:1MB flash */ + uint32_t chipInfo : 3; /*!< Efuse chip revision */ +} Efuse_Device_Info_Type; + +/** + * @brief Efuse Capcode type definition + */ +typedef struct +{ + uint32_t capCode : 6; /*!< Cap code value */ + uint32_t parity : 1; /*!< Parity of capcode */ + uint32_t en : 1; /*!< Enable status */ + uint32_t rsvd : 24; /*!< Reserved */ +} Efuse_Capcode_Info_Type; + +/*@} end of group EF_CTRL_Public_Types */ + +/** @defgroup EF_CTRL_Public_Constants + * @{ + */ + +/** @defgroup EF_CTRL_KEY_TYPE + * @{ + */ +#define IS_EF_CTRL_KEY_TYPE(type) (((type) == EF_CTRL_KEY_SLOT0) || \ + ((type) == EF_CTRL_KEY_SLOT1) || \ + ((type) == EF_CTRL_KEY_SLOT2) || \ + ((type) == EF_CTRL_KEY_SLOT3) || \ + ((type) == EF_CTRL_KEY_SLOT4) || \ + ((type) == EF_CTRL_KEY_SLOT5) || \ + ((type) == EF_CTRL_KEY_MAX)) + +/** @defgroup EF_CTRL_SIGN_TYPE + * @{ + */ +#define IS_EF_CTRL_SIGN_TYPE(type) (((type) == EF_CTRL_SIGN_NONE) || \ + ((type) == EF_CTRL_SIGN_RSA) || \ + ((type) == EF_CTRL_SIGN_ECC)) + +/** @defgroup EF_CTRL_SF_AES_TYPE + * @{ + */ +#define IS_EF_CTRL_SF_AES_TYPE(type) (((type) == EF_CTRL_SF_AES_NONE) || \ + ((type) == EF_CTRL_SF_AES_128) || \ + ((type) == EF_CTRL_SF_AES_192) || \ + ((type) == EF_CTRL_SF_AES_256)) + +/** @defgroup EF_CTRL_DBG_MODE_TYPE + * @{ + */ +#define IS_EF_CTRL_DBG_MODE_TYPE(type) (((type) == EF_CTRL_DBG_OPEN) || \ + ((type) == EF_CTRL_DBG_PASSWORD) || \ + ((type) == EF_CTRL_DBG_CLOSE)) + +/** @defgroup EF_CTRL_CLK_TYPE + * @{ + */ +#define IS_EF_CTRL_CLK_TYPE(type) (((type) == EF_CTRL_EF_CLK) || \ + ((type) == EF_CTRL_SAHB_CLK)) + +/** @defgroup EF_CTRL_CYC_PARA_TYPE + * @{ + */ +#define IS_EF_CTRL_CYC_PARA_TYPE(type) (((type) == EF_CTRL_PARA_DFT) || \ + ((type) == EF_CTRL_PARA_MANUAL)) + +/** @defgroup EF_CTRL_OP_MODE_TYPE + * @{ + */ +#define IS_EF_CTRL_OP_MODE_TYPE(type) (((type) == EF_CTRL_OP_MODE_AUTO) || \ + ((type) == EF_CTRL_OP_MODE_MANUAL)) + +/*@} end of group EF_CTRL_Public_Constants */ + +/** @defgroup EF_CTRL_Public_Macros + * @{ + */ +#define EF_CTRL_EFUSE_R0_SIZE 128 +#define EF_CTRL_EFUSE_R1_SIZE 128 + +/*@} end of group EF_CTRL_Public_Macros */ + +/** @defgroup EF_CTRL_Public_Functions + * @{ + */ +/*----------*/ +BL_Err_Type EF_Ctrl_Get_Customer_PIDVID(uint16_t pid[1], uint16_t vid[1]); +/*----------*/ +void EF_Ctrl_Load_Efuse_R0(void); +void EF_Ctrl_Load_Efuse_R1(void); +void EF_Ctrl_Program_Efuse_0(void); +void EF_Ctrl_Program_Efuse_1(void); +BL_Sts_Type EF_Ctrl_Busy(void); +BL_Sts_Type EF_Ctrl_AutoLoad_Done(void); +void EF_Ctrl_Write_Dbg_Pwd(uint8_t slot, uint32_t passWdLow, uint32_t passWdHigh, uint8_t program); +void EF_Ctrl_Read_Dbg_Pwd(uint8_t slot, uint32_t *passWdLow, uint32_t *passWdHigh); +void EF_Ctrl_Readlock_Dbg_Pwd(uint8_t program); +void EF_Ctrl_Writelock_Dbg_Pwd(uint8_t program); +void EF_Ctrl_Write_Secure_Cfg(EF_Ctrl_Sec_Param_Type *cfg, uint8_t program); +void EF_Ctrl_Read_Secure_Cfg(EF_Ctrl_Sec_Param_Type *cfg); +void EF_Ctrl_Write_Secure_Boot(EF_Ctrl_Sign_Type sign[1], EF_Ctrl_SF_AES_Type aes[1], uint8_t program); +void EF_Ctrl_Read_Secure_Boot(EF_Ctrl_SF_AES_Type aes[2]); +void EF_Ctrl_Read_Xtal_Trim_RC32M(uint8_t *forceNoTrim, uint8_t *noXtal); +void EF_Ctrl_Set_sf_key_re_sel(uint8_t ef_sf_key_re_sel); +uint8_t EF_Ctrl_Get_Trim_Parity(uint32_t val, uint8_t len); +void EF_Ctrl_Read_DCDC11_Trim(Efuse_Ana_DCDC11_Trim_Type *trim); +void EF_Ctrl_Read_DCDC18_Trim(Efuse_Ana_DCDC18_Trim_Type *trim); +void EF_Ctrl_Read_LDO18FLASH_Trim(Efuse_Ana_LDO18FLASH_Trim_Type *trim); +void EF_Ctrl_Read_USB20RCAL_Trim(Efuse_Ana_USB20RCAL_Trim_Type *trim); +void EF_Ctrl_Read_RC32M_Trim(Efuse_Ana_RC32M_Trim_Type *trim); +void EF_Ctrl_Read_RC32K_Trim(Efuse_Ana_RC32K_Trim_Type *trim); +void EF_Ctrl_Read_LDO18IO_Vout_Trim(Efuse_Ana_LDO18IO_VOUT_Trim_Type *trim); +void EF_Ctrl_Read_TSEN_Trim(Efuse_TSEN_Refcode_Corner_Type *trim); +void EF_Ctrl_Read_ADC_Gain_Trim(Efuse_ADC_Gain_Coeff_Type *trim); +void EF_Ctrl_Write_Sw_Usage(uint32_t index, uint32_t usage, uint8_t program); +void EF_Ctrl_Read_Sw_Usage(uint32_t index, uint32_t *usage); +void EF_Ctrl_Writelock_Sw_Usage(uint32_t index, uint8_t program); +void EF_Ctrl_Write_MAC_Address(uint8_t mac[6], uint8_t program); +BL_Err_Type EF_Ctrl_Read_MAC_Address(uint8_t mac[6]); +BL_Err_Type EF_Ctrl_Read_MAC_Address_Raw(uint8_t mac[7]); +BL_Err_Type EF_Ctrl_Read_ZiggBee_MAC_Address(uint8_t mac[8]); +void EF_Ctrl_Writelock_MAC_Address(uint8_t program); +BL_Err_Type EF_Ctrl_Read_Chip_ID(uint8_t id[8]); +void EF_Ctrl_Write_AES_Key(uint8_t index, uint32_t *keyData, uint32_t len, uint8_t program); +void EF_Ctrl_Read_AES_Key(uint8_t index, uint32_t *keyData, uint32_t len); +void EF_Ctrl_Writelock_AES_Key(uint8_t index, uint8_t program); +void EF_Ctrl_Readlock_AES_Key(uint8_t index, uint8_t program); +void EF_Ctrl_Program_Direct_R0(uint32_t index, uint32_t *data, uint32_t len); +void EF_Ctrl_Program_Direct_R1(uint32_t index, uint32_t *data, uint32_t len); +void EF_Ctrl_Read_Direct_R0(uint32_t index, uint32_t *data, uint32_t len); +void EF_Ctrl_Read_Direct_R1(uint32_t index, uint32_t *data, uint32_t len); +void EF_Ctrl_Program_Direct(uint32_t region, uint32_t index, uint32_t *data, uint32_t len); +void EF_Ctrl_Read_Direct(uint32_t region, uint32_t index, uint32_t *data, uint32_t len); +void EF_Ctrl_Clear(uint8_t region, uint32_t index, uint32_t len); +void EF_Ctrl_Crc_Enable(void); +BL_Sts_Type EF_Ctrl_Crc_Is_Busy(void); +void EF_Ctrl_Crc_Set_Golden(uint32_t goldenValue); +BL_Err_Type EF_Ctrl_Crc_Result(void); +void EF_Ctrl_Sw_AHB_Clk_0(void); +void EF_Ctrl_Sw_AHB_Clk_1(void); +uint8_t EF_Ctrl_Is_All_Bits_Zero(uint32_t val, uint8_t start, uint8_t len); + +/*@} end of group EF_CTRL_Public_Functions */ + +/*@} end of group EF_CTRL */ + +/*@} end of group BL808_Peripheral_Driver */ + +#endif /* __BL808_EF_CTRL_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/bl808_glb.h b/platforms/bl808_m0/vendor/psram/include/bl808_glb.h new file mode 100644 index 0000000..ffb5d6d --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/bl808_glb.h @@ -0,0 +1,2480 @@ +/** + ****************************************************************************** + * @file bl808_glb.h + * @version V1.0 + * @date + * @brief This file is the standard driver header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __BL808_GLB_H__ +#define __BL808_GLB_H__ + +#include "glb_reg.h" +#include "cci_reg.h" +#include "mm_glb_reg.h" +#include "pds_reg.h" +#include "bl808_gpio.h" +#include "bl808_hbn.h" +#include "bl808_sf_ctrl.h" +#include "bl808_sf_cfg.h" +#include "bl808_aon.h" +#include "bl808_ef_ctrl.h" +#include "bl808_pds.h" +#include "bl808_common.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup GLB + * @{ + */ + +/** @defgroup GLB_Public_Types + * @{ + */ + +/** + * @brief GLB AHB clock IP type definition + */ +typedef enum { + GLB_AHB_CLOCK_IP_CPU, + GLB_AHB_CLOCK_IP_SDU, + GLB_AHB_CLOCK_IP_SEC, + GLB_AHB_CLOCK_IP_DMA_0, + GLB_AHB_CLOCK_IP_DMA_1, + GLB_AHB_CLOCK_IP_DMA_2, + GLB_AHB_CLOCK_IP_CCI, + GLB_AHB_CLOCK_IP_RF_TOP, + GLB_AHB_CLOCK_IP_GPIP, + GLB_AHB_CLOCK_IP_TZC, + GLB_AHB_CLOCK_IP_EF_CTRL, + GLB_AHB_CLOCK_IP_SF_CTRL, + GLB_AHB_CLOCK_IP_EMAC, + GLB_AHB_CLOCK_IP_UART0, + GLB_AHB_CLOCK_IP_UART1, + GLB_AHB_CLOCK_IP_UART2, + GLB_AHB_CLOCK_IP_UART3, + GLB_AHB_CLOCK_IP_UART4, /* OpenWatt: vendor bug -- bl808_glb_pll.c references this enum value but the e907_std header omitted it. Added to fix dead-code compile (this case is unreachable in our build). */ + GLB_AHB_CLOCK_IP_SPI, + GLB_AHB_CLOCK_IP_I2C, + GLB_AHB_CLOCK_IP_PWM, + GLB_AHB_CLOCK_IP_TIMER, + GLB_AHB_CLOCK_IP_IR, + GLB_AHB_CLOCK_IP_CHECKSUM, + GLB_AHB_CLOCK_IP_QDEC, + GLB_AHB_CLOCK_IP_KYS, + GLB_AHB_CLOCK_IP_I2S, + GLB_AHB_CLOCK_IP_USB11, + GLB_AHB_CLOCK_IP_CAM, + GLB_AHB_CLOCK_IP_MJPEG, + GLB_AHB_CLOCK_IP_BT_BLE_NORMAL, + GLB_AHB_CLOCK_IP_BT_BLE_LP, + GLB_AHB_CLOCK_IP_ZB_NORMAL, + GLB_AHB_CLOCK_IP_ZB_LP, + GLB_AHB_CLOCK_IP_WIFI_NORMAL, + GLB_AHB_CLOCK_IP_WIFI_LP, + GLB_AHB_CLOCK_IP_BT_BLE_2_NORMAL, + GLB_AHB_CLOCK_IP_BT_BLE_2_LP, + GLB_AHB_CLOCK_IP_EMI_MISC, + GLB_AHB_CLOCK_IP_PSRAM0_CTRL, + GLB_AHB_CLOCK_IP_PSRAM1_CTRL, + GLB_AHB_CLOCK_IP_USB20, + GLB_AHB_CLOCK_IP_MIX2, + GLB_AHB_CLOCK_IP_AUDIO, + GLB_AHB_CLOCK_IP_SDH, + GLB_AHB_CLOCK_IP_ZB2_NORMAL, + GLB_AHB_CLOCK_IP_ZB2_LP, + GLB_AHB_CLOCK_IP_I2C1, + GLB_AHB_CLOCK_IP_WIFI_PHY, + GLB_AHB_CLOCK_IP_WIFI_MAC_PHY, + GLB_AHB_CLOCK_IP_WIFI_PLATFORM, + GLB_AHB_CLOCK_IP_LZ4, + GLB_AHB_CLOCK_IP_AUPDM, + GLB_AHB_CLOCK_IP_GAUGE, +} GLB_AHB_CLOCK_IP_Type; + +/** + * @brief GLB core ID type definition + */ +typedef enum { + GLB_CORE_ID_M0, /*!< M0 */ + GLB_CORE_ID_D0, /*!< D0 */ + GLB_CORE_ID_LP, /*!< LP */ + GLB_CORE_ID_MAX, /*!< ID max */ + GLB_CORE_ID_INVALID, /*!< ID invalid */ +} GLB_CORE_ID_Type; + +/** + * @brief cci ID type definition + */ +typedef enum { + CCI0_ID, /*!< CCI0 port define */ + CCI_ID_MAX, /*!< CCI MAX ID define */ +} CCI_ID_Type; + +/** + * @brief GLB DSP all interrupt type definition + */ +typedef enum { + GLB_DSP_ALL_INT_BUS_DEC_ERR_INT = 0, /*!< bus_dec_err_int */ + GLB_DSP_ALL_INT_DSP2_AWB3_INT = 1, /*!< dsp2_awb3_int */ + GLB_DSP_ALL_INT_IPC2_NP2AP_IRQ = 2, /*!< |ipc2_np2ap_irq */ + GLB_DSP_ALL_INT_RSV3 = 3, /*!< rsv3 */ + GLB_DSP_ALL_INT_UART0_INT = 4, /*!< uart0_int */ + GLB_DSP_ALL_INT_I2C0_INT = 5, /*!< i2c0_int */ + GLB_DSP_ALL_INT_I2C1_INT = 6, /*!< i2c1_int */ + GLB_DSP_ALL_INT_SPI_INT = 7, /*!< spi_int */ + GLB_DSP_ALL_INT_DSP2_AE_INT = 8, /*!< dsp2_ae_int */ + GLB_DSP_ALL_INT_DSP2_AWB_INT = 9, /*!< dsp2_awb_int */ + GLB_DSP_ALL_INT_SEOF1_INT = 10, /*!< seof1_int */ + GLB_DSP_ALL_INT_SEOF2_INT = 11, /*!< seof2_int */ + GLB_DSP_ALL_INT_SEOF3_INT = 12, /*!< seof3_int */ + GLB_DSP_ALL_INT_DVP2BUS_INT_0 = 13, /*!< dvp2bus_int[0] */ + GLB_DSP_ALL_INT_DVP2BUS_INT_1 = 14, /*!< dvp2bus_int[1] */ + GLB_DSP_ALL_INT_DVP2BUS_INT_2 = 15, /*!< dvp2bus_int[2] */ + GLB_DSP_ALL_INT_DVP2BUS_INT_3 = 16, /*!< dvp2bus_int[3] */ + GLB_DSP_ALL_INT_H264_BS_IRQ = 17, /*!< h264_bs_irq */ + GLB_DSP_ALL_INT_H264_FRAME_IRQ = 18, /*!< h264_frame_irq */ + GLB_DSP_ALL_INT_H264_SEQ_DONE_INT = 19, /*!< h264_seq_done_int */ + GLB_DSP_ALL_INT_MJPEG_INT = 20, /*!< mjpeg_int */ + GLB_DSP_ALL_INT_H264_S_BS_IRQ = 21, /*!< h264_s_bs_irq */ + GLB_DSP_ALL_INT_H264_S_FRAME_IRQ = 22, /*!< h264_s_frame_irq */ + GLB_DSP_ALL_INT_H264_S_SEQ_DONE_INT = 23, /*!< h264_s_seq_done_int */ + GLB_DSP_ALL_INT_DMA_INTR_0 = 24, /*!< DMA_INTR[0] */ + GLB_DSP_ALL_INT_DMA_INTR_1 = 25, /*!< DMA_INTR[1] */ + GLB_DSP_ALL_INT_DMA_INTR_2 = 26, /*!< DMA_INTR[2] */ + GLB_DSP_ALL_INT_DMA_INTR_3 = 27, /*!< DMA_INTR[3] */ + GLB_DSP_ALL_INT_DMA_INTR_4 = 28, /*!< DMA_INTR[4] */ + GLB_DSP_ALL_INT_DMA_INTR_5 = 29, /*!< DMA_INTR[5] */ + GLB_DSP_ALL_INT_DMA_INTR_6 = 30, /*!< DMA_INTR[6] */ + GLB_DSP_ALL_INT_DMA_INTR_7 = 31, /*!< DMA_INTR[7] */ + GLB_DSP_ALL_INT_RSV32 = 32, /*!< rsv32 */ + GLB_DSP_ALL_INT_RSV33 = 33, /*!< rsv33 */ + GLB_DSP_ALL_INT_RSV34 = 34, /*!< rsv34 */ + GLB_DSP_ALL_INT_RSV35 = 35, /*!< rsv35 */ + GLB_DSP_ALL_INT_RSV36 = 36, /*!< rsv36 */ + GLB_DSP_ALL_INT_MIPI_CSI_INT = 37, /*!< mipi_csi_int */ + GLB_DSP_ALL_INT_IPC2_AP2NP_IRQ = 38, /*!< |ipc2_ap2np_irq */ + GLB_DSP_ALL_INT_RSV39 = 39, /*!< rsv39 */ + GLB_DSP_ALL_INT_MJDEC_INT = 40, /*!< mjdec_int */ + GLB_DSP_ALL_INT_DVP2BUS_IN_4 = 41, /*!< dvp2bus_int[4] */ + GLB_DSP_ALL_INT_DVP2BUS_IN_5 = 42, /*!< dvp2bus_int[5] */ + GLB_DSP_ALL_INT_DVP2BUS_IN_6 = 43, /*!< dvp2bus_int[6] */ + GLB_DSP_ALL_INT_DVP2BUS_IN_7 = 44, /*!< dvp2bus_int[7] */ + GLB_DSP_ALL_INT_DMA2D_INT_0 = 45, /*!< dma2d_int[0] */ + GLB_DSP_ALL_INT_DMA2D_INT_1 = 46, /*!< dma2d_int[1] */ + GLB_DSP_ALL_INT_DP_SOEF0_INT = 47, /*!< dp_soef0_int */ + GLB_DSP_ALL_INT_RSV48 = 48, /*!< rsv48 */ + GLB_DSP_ALL_INT_RSV49 = 49, /*!< rsv49 */ + GLB_DSP_ALL_INT_RSV50 = 50, /*!< rsv50 */ + GLB_DSP_ALL_INT_RSV51 = 51, /*!< rsv51 */ + GLB_DSP_ALL_INT_OSDDP_INT = 52, /*!< osdDP_int */ + GLB_DSP_ALL_INT_DBI_INT = 53, /*!< dbi_int */ + GLB_DSP_ALL_INT_DSP2_WDR_INT = 54, /*!< dsp2_wdr_int */ + GLB_DSP_ALL_INT_OSDA_INT = 55, /*!< osdA_int */ + GLB_DSP_ALL_INT_OSDB_INT = 56, /*!< osdB_int */ + GLB_DSP_ALL_INT_OSD_PB_INT = 57, /*!< osd_pb_int */ + GLB_DSP_ALL_INT_DSP2_AWB2_INT = 58, /*!< dsp2_awb2_int */ + GLB_DSP_ALL_INT_MIPI_DSI_INT = 59, /*!< mipi_dsi_int */ + GLB_DSP_ALL_INT_DSP2_AE_HIST_INT = 60, /*!< dsp2_ae_hist_int */ + GLB_DSP_ALL_INT_MM_TIMER_IRQ2 = 61, /*!< mm_timer_irq2 */ + GLB_DSP_ALL_INT_MM_TIMER_IRQ3 = 62, /*!< mm_timer_irq3 */ + GLB_DSP_ALL_INT_MM_WDT_IRQ = 63, /*!< mm_wdt_irq */ +} GLB_DSP_ALL_INT_Type; + +/** + * @brief GLB MCU all interrupt type definition + */ +typedef enum { + GLB_MCU_ALL_INT_BMX_ERR_INT = 0, /*!< bmx_err_intmcu_dec_err_int */ + GLB_MCU_ALL_INT_BMX_TIMEOUT_INT_MCU_TIMEOUT_INT = 1, /*!< bmx_timeout_intmcu_timeout_int */ + GLB_MCU_ALL_INT_IPC0_NP2AP_IRQ = 2, /*!< ipc0_np2ap_irq */ + GLB_MCU_ALL_INT_IPC0_AP2NP_IRQ = 3, /*!< ipc0_ap2np_irq */ + GLB_MCU_ALL_INT_AUDIO_INT = 4, /*!< audio_int */ + GLB_MCU_ALL_INT_RF_TOP_INT_0 = 5, /*!< rf_top_int[0] */ + GLB_MCU_ALL_INT_RF_TOP_INT_1 = 6, /*!< rf_top_int[1] */ + GLB_MCU_ALL_INT_LZ4_INT = 7, /*!< lz4_int */ + GLB_MCU_ALL_INT_RSV8 = 8, /*!< rsv8 */ + GLB_MCU_ALL_INT_SEC_ENG_ID0_GMAC_INT = 9, /*!< sec_eng_id0_gmac_int */ + GLB_MCU_ALL_INT_SEC_ENG_ID0_CDET_INT = 10, /*!< sec_eng_id0_cdet_int */ + GLB_MCU_ALL_INT_SEC_ENG_ID0_PKA_INT = 11, /*!< sec_eng_id0_pka_int */ + GLB_MCU_ALL_INT_SEC_ENG_ID0_TRNG_INT = 12, /*!< sec_eng_id0_trng_int */ + GLB_MCU_ALL_INT_SEC_ENG_ID0_AES_INT = 13, /*!< sec_eng_id0_aes_int */ + GLB_MCU_ALL_INT_SEC_ENG_ID0_SHA_INT = 14, /*!< sec_eng_id0_sha_int */ + GLB_MCU_ALL_INT_DMA_INTR_ALL = 15, /*!< DMA_INTR_ALL */ + GLB_MCU_ALL_INT_DMA2_INTR_ALL = 16, /*!< DMA2_INTR_ALL */ + GLB_MCU_ALL_INT_SDH_MMC1_INT_SDH2PMU_WAKEUP_INT1 = 17, /*!< sdh_mmc1_intsdh2pmu_wakeup_int1 */ + GLB_MCU_ALL_INT_MM_IRQ_ALL = 18, /*!< mm_irq_all */ + GLB_MCU_ALL_INT_IRTX_INT = 19, /*!< irtx_int */ + GLB_MCU_ALL_INT_IRRX_INT = 20, /*!< irrx_int */ + GLB_MCU_ALL_INT_USB_INT = 21, /*!< usb_int */ + GLB_MCU_ALL_INT_AUPDM_INT = 22, /*!< aupdm_int */ + GLB_MCU_ALL_INT_SF_CTRL_ID0_INT = 23, /*!< sf_ctrl_id0_int */ + GLB_MCU_ALL_INT_EMAC_INT = 24, /*!< emac_int */ + GLB_MCU_ALL_INT_GPADC_DMA_INT = 25, /*!< gpadc_dma_int */ + GLB_MCU_ALL_INT_EFUSE_INT = 26, /*!< efuse_int */ + GLB_MCU_ALL_INT_SPI_0_INT = 27, /*!< spi_0_int */ + GLB_MCU_ALL_INT_UART_IRQ = 28, /*!< uart_irq */ + GLB_MCU_ALL_INT_UART1_IRQ = 29, /*!< uart1_irq */ + GLB_MCU_ALL_INT_UART2_IRQ = 30, /*!< uart2_irq */ + GLB_MCU_ALL_INT_GPIO_DMA_INT = 31, /*!< gpio_dma_int */ + GLB_MCU_ALL_INT_I2C_0_INT = 32, /*!< i2c_0_int */ + GLB_MCU_ALL_INT_PWM_INT = 33, /*!< pwm_int */ + GLB_MCU_ALL_INT_IPC1_NP2AP_IRQ = 34, /*!< ipc1_np2ap_irq */ + GLB_MCU_ALL_INT_IPC1_AP2NP_IRQ = 35, /*!< ipc1_ap2np_irq */ + GLB_MCU_ALL_INT_TIMER0_2_IRQ = 36, /*!< timer0_2_irq */ + GLB_MCU_ALL_INT_TIMER0_3_IRQ = 37, /*!< timer0_3_irq */ + GLB_MCU_ALL_INT_WDT0_IRQ = 38, /*!< wdt0_irq */ + GLB_MCU_ALL_INT_I2C_1_INT = 39, /*!< i2c_1_int */ + GLB_MCU_ALL_INT_I2S0_INT = 40, /*!< i2s0_int */ + GLB_MCU_ALL_INT_RSV41 = 41, /*!< rsv41 */ + GLB_MCU_ALL_INT_RSV42 = 42, /*!< rsv42 */ + GLB_MCU_ALL_INT_ANA_OCP_OUT_TO_CPU_IRQ = 43, /*!< ana_ocp_out_to_cpu_irq[2:0] */ + GLB_MCU_ALL_INT_GPIO_IRQ = 44, /*!< gpio_irq */ + GLB_MCU_ALL_INT_DM_IRQ = 45, /*!< dm_irq */ + GLB_MCU_ALL_INT_BT_IRQ = 46, /*!< bt_irq */ + GLB_MCU_ALL_INT_M154_REQ_ENH_ACK_INT = 47, /*!< m154_req_enh_ack_int */ + GLB_MCU_ALL_INT_M154_INT = 48, /*!< m154_int */ + GLB_MCU_ALL_INT_M154_AES_INT = 49, /*!< m154_aes_int */ + GLB_MCU_ALL_INT_PDS_INT = 50, /*!< pds_int */ + GLB_MCU_ALL_INT_HBN_IRQ_OUT_0 = 51, /*!< hbn_irq_out[0] */ + GLB_MCU_ALL_INT_HBN_IRQ_OUT_1 = 52, /*!< hbn_irq_out[1] */ + GLB_MCU_ALL_INT_BOR_OUT = 53, /*!< bor_out */ + GLB_MCU_ALL_INT_WIFI_TO_CPU_IRQ_N = 54, /*!< wifi_to_cpu_irq_n */ + GLB_MCU_ALL_INT_BZ_PHY_INT = 55, /*!< bz_phy_int */ + GLB_MCU_ALL_INT_BLE_INT = 56, /*!< ble_int */ + GLB_MCU_ALL_INT_MAC_INT_TX_RX_TIMER = 57, /*!< mac_int_tx_rx_timer */ + GLB_MCU_ALL_INT_MAC_INT_TX_RX_MISC = 58, /*!< mac_int_tx_rx_misc */ + GLB_MCU_ALL_INT_MAC_INT_RX_TRIGGER = 59, /*!< mac_int_rx_trigger */ + GLB_MCU_ALL_INT_MAC_INT_TX_TRIGGER = 60, /*!< mac_int_tx_trigger */ + GLB_MCU_ALL_INT_MAC_INT_GEN = 61, /*!< mac_int_gen */ + GLB_MCU_ALL_INT_MAC_INT_PROT_TRIGGER = 62, /*!< mac_int_prot_trigger */ + GLB_MCU_ALL_INT_WIFI_IPC = 63, /*!< wifi_ipc */ +} GLB_MCU_ALL_INT_Type; + +/** + * @brief GLB LP all interrupt type definition + */ +typedef enum { + GLB_LP_ALL_INT_BMX_ERR_INT = 0, /*!< bmx_err_int */ + GLB_LP_ALL_INT_BMX_TIMEOUT_INT_MCU_TIMEOUT_INT = 1, /*!< bmx_timeout_intmcu_timeout_int */ + GLB_LP_ALL_INT_IPC0_NP2AP_IRQ = 2, /*!< ipc0_np2ap_irq */ + GLB_LP_ALL_INT_IPC0_AP2NP_IRQ = 3, /*!< ipc0_ap2np_irq */ + GLB_LP_ALL_INT_AUDIO_INT = 4, /*!< audio_int */ + GLB_LP_ALL_INT_RF_TOP_INT_0 = 5, /*!< rf_top_int[0] */ + GLB_LP_ALL_INT_RF_TOP_INT_1 = 6, /*!< rf_top_int[1] */ + GLB_LP_ALL_INT_LZ4_INT = 7, /*!< lz4_int */ + GLB_LP_ALL_INT_RSV8 = 8, /*!< rsv8 */ + GLB_LP_ALL_INT_SEC_ENG_ID0_GMAC_INT = 9, /*!< sec_eng_id0_gmac_int */ + GLB_LP_ALL_INT_SEC_ENG_ID0_CDET_INT = 10, /*!< sec_eng_id0_cdet_int */ + GLB_LP_ALL_INT_SEC_ENG_ID0_PKA_INT = 11, /*!< sec_eng_id0_pka_int */ + GLB_LP_ALL_INT_SEC_ENG_ID0_TRNG_INT = 12, /*!< sec_eng_id0_trng_int */ + GLB_LP_ALL_INT_SEC_ENG_ID0_AES_INT = 13, /*!< sec_eng_id0_aes_int */ + GLB_LP_ALL_INT_SEC_ENG_ID0_SHA_INT = 14, /*!< sec_eng_id0_sha_int */ + GLB_LP_ALL_INT_DMA_INTR_ALL = 15, /*!< DMA_INTR_ALL */ + GLB_LP_ALL_INT_DMA2_INTR_ALL = 16, /*!< DMA2_INTR_ALL */ + GLB_LP_ALL_INT_SDH_MMC1_INT_SDH2PMU_WAKEUP_INT1 = 17, /*!< sdh_mmc1_intsdh2pmu_wakeup_int1 */ + GLB_LP_ALL_INT_MM_IRQ_ALL = 18, /*!< mm_irq_all */ + GLB_LP_ALL_INT_IRTX_INT = 19, /*!< irtx_int */ + GLB_LP_ALL_INT_IRRX_INT = 20, /*!< irrx_int */ + GLB_LP_ALL_INT_USB_INT = 21, /*!< usb_int */ + GLB_LP_ALL_INT_AUPDM_INT = 22, /*!< aupdm_int */ + GLB_LP_ALL_INT_SF_CTRL_ID0_INT = 23, /*!< sf_ctrl_id0_int */ + GLB_LP_ALL_INT_EMAC_INT = 24, /*!< emac_int */ + GLB_LP_ALL_INT_GPADC_DMA_INT = 25, /*!< gpadc_dma_int */ + GLB_LP_ALL_INT_EFUSE_INT = 26, /*!< efuse_int */ + GLB_LP_ALL_INT_SPI_0_INT = 27, /*!< spi_0_int */ + GLB_LP_ALL_INT_UART_IRQ = 28, /*!< uart_irq */ + GLB_LP_ALL_INT_UART1_IRQ = 29, /*!< uart1_irq */ + GLB_LP_ALL_INT_UART2_IRQ = 30, /*!< uart2_irq */ + GLB_LP_ALL_INT_GPIO_DMA_INT = 31, /*!< gpio_dma_int */ + GLB_LP_ALL_INT_I2C_0_INT = 32, /*!< i2c_0_int */ + GLB_LP_ALL_INT_PWM_INT = 33, /*!< pwm_int */ + GLB_LP_ALL_INT_IPC1_NP2AP_IRQ = 34, /*!< ipc1_np2ap_irq */ + GLB_LP_ALL_INT_IPC1_AP2NP_IRQ = 35, /*!< ipc1_ap2np_irq */ + GLB_LP_ALL_INT_TIMER0_2_IRQ = 36, /*!< timer0_2_irq */ + GLB_LP_ALL_INT_TIMER0_3_IRQ = 37, /*!< timer0_3_irq */ + GLB_LP_ALL_INT_WDT0_IRQ = 38, /*!< wdt0_irq */ + GLB_LP_ALL_INT_I2C_1_INT = 39, /*!< i2c_1_int */ + GLB_LP_ALL_INT_I2S0_INT = 40, /*!< i2s0_int */ + GLB_LP_ALL_INT_RSV41 = 41, /*!< rsv41 */ + GLB_LP_ALL_INT_RSV42 = 42, /*!< rsv42 */ + GLB_LP_ALL_INT_ANA_OCP_OUT_TO_CPU_IRQ = 43, /*!< ana_ocp_out_to_cpu_irq[2:0] */ + GLB_LP_ALL_INT_GPIO_IRQ = 44, /*!< gpio_irq */ + GLB_LP_ALL_INT_DM_IRQ = 45, /*!< dm_irq */ + GLB_LP_ALL_INT_BT_IRQ = 46, /*!< bt_irq */ + GLB_LP_ALL_INT_M154_REQ_ENH_ACK_INT = 47, /*!< m154_req_enh_ack_int */ + GLB_LP_ALL_INT_M154_INT = 48, /*!< m154_int */ + GLB_LP_ALL_INT_M154_AES_INT = 49, /*!< m154_aes_int */ + GLB_LP_ALL_INT_PDS_INT = 50, /*!< pds_int */ + GLB_LP_ALL_INT_HBN_IRQ_OUT_0 = 51, /*!< hbn_irq_out[0] */ + GLB_LP_ALL_INT_HBN_IRQ_OUT_1 = 52, /*!< hbn_irq_out[1] */ + GLB_LP_ALL_INT_BOR_OUT = 53, /*!< bor_out */ + GLB_LP_ALL_INT_WIFI_TO_CPU_IRQ_N = 54, /*!< wifi_to_cpu_irq_n */ + GLB_LP_ALL_INT_BZ_PHY_INT = 55, /*!< bz_phy_int */ + GLB_LP_ALL_INT_BLE_INT = 56, /*!< ble_int */ + GLB_LP_ALL_INT_MAC_INT_TX_RX_TIMER = 57, /*!< mac_int_tx_rx_timer */ + GLB_LP_ALL_INT_MAC_INT_TX_RX_MISC = 58, /*!< mac_int_tx_rx_misc */ + GLB_LP_ALL_INT_MAC_INT_RX_TRIGGER = 59, /*!< mac_int_rx_trigger */ + GLB_LP_ALL_INT_MAC_INT_TX_TRIGGER = 60, /*!< mac_int_tx_trigger */ + GLB_LP_ALL_INT_MAC_INT_GEN = 61, /*!< mac_int_gen */ + GLB_LP_ALL_INT_MAC_INT_PROT_TRIGGER = 62, /*!< mac_int_prot_trigger */ + GLB_LP_ALL_INT_WIFI_IPC = 63, /*!< wifi_ipc */ +} GLB_LP_ALL_INT_Type; + +/** + * @brief GLB dsp muxpll 320M clock type definition + */ +typedef enum { + GLB_DSP_MUXPLL_SEL_WIFIPLL_320M, /*!< dsp muxpll select wifipll 320M */ + GLB_DSP_MUXPLL_SEL_AUPLL_DIV1, /*!< dsp muxpll select aupll div1 */ +} GLB_DSP_MUXPLL_320M_CLK_SEL_Type; + +/** + * @brief GLB dsp muxpll 240M clock type definition + */ +typedef enum { + GLB_DSP_MUXPLL_SEL_WIFIPLL_240M, /*!< dsp muxpll select wifipll 240M */ + GLB_DSP_MUXPLL_SEL_AUPLL_DIV2, /*!< dsp muxpll select aupll div2 */ +} GLB_DSP_MUXPLL_240M_CLK_SEL_Type; + +/** + * @brief GLB dsp muxpll 160M clock type definition + */ +typedef enum { + GLB_DSP_MUXPLL_SEL_WIFIPLL_160M, /*!< dsp muxpll select wifipll 160M */ + GLB_DSP_MUXPLL_SEL_CPUPLL_160M, /*!< dsp muxpll select cpupll 160M */ +} GLB_DSP_MUXPLL_160M_CLK_SEL_Type; + +/** + * @brief GLB mcu muxpll 160M clock type definition + */ +typedef enum { + GLB_MCU_MUXPLL_SEL_WIFIPLL_160M, /*!< mcu muxpll select wifipll 160M */ + GLB_MCU_MUXPLL_SEL_TOP_CPUPLL_160M, /*!< mcu muxpll select top cpupll 160M */ + GLB_MCU_MUXPLL_SEL_TOP_AUPLL_DIV2, /*!< mcu muxpll select top aupll div2 */ + GLB_MCU_MUXPLL_SEL_AUPLL_DIV2P5, /*!< mcu muxpll select aupll div2p5 */ +} GLB_MCU_MUXPLL_160M_CLK_SEL_Type; + +/** + * @brief GLB mcu muxpll 80M clock type definition + */ +typedef enum { + GLB_MCU_MUXPLL_SEL_WIFIPLL_80M, /*!< mcu muxpll select wifipll 80M */ + GLB_MCU_MUXPLL_SEL_TOP_CPUPLL_80M, /*!< mcu muxpll select top cpupll 80M */ + GLB_MCU_MUXPLL_SEL_AUPLL_DIV5, /*!< mcu muxpll select aupll div5 */ + GLB_MCU_MUXPLL_SEL_AUPLL_DIV6, /*!< mcu muxpll select aupll div6 */ +} GLB_MCU_MUXPLL_80M_CLK_SEL_Type; + +/** + * @brief GLB pll clock gate type definition + */ +typedef enum { + GLB_PLL_CGEN_MM_WIFIPLL_160M, /*!< pll cgen mm wifipll 160m */ + GLB_PLL_CGEN_MM_WIFIPLL_240M, /*!< pll cgen mm wifipll 240m */ + GLB_PLL_CGEN_MM_WIFIPLL_320M, /*!< pll cgen mm wifipll 320m */ + GLB_PLL_CGEN_MM_AUPLL_DIV1, /*!< pll cgen mm aupll div1 */ + GLB_PLL_CGEN_MM_AUPLL_DIV2, /*!< pll cgen mm aupll div2 */ + GLB_PLL_CGEN_EMI_CPUPLL_400M, /*!< pll cgen emi cpupll 400m */ + GLB_PLL_CGEN_EMI_CPUPLL_200M, /*!< pll cgen emi cpupll 200m */ + GLB_PLL_CGEN_EMI_WIFIPLL_320M, /*!< pll cgen emi wifipll 320m */ + GLB_PLL_CGEN_EMI_AUPLL_DIV1, /*!< pll cgen emi aupll div1 */ + GLB_PLL_CGEN_TOP_CPUPLL_80M, /*!< pll cgen top cpupll 80m */ + GLB_PLL_CGEN_TOP_CPUPLL_100M, /*!< pll cgen top cpupll 100m */ + GLB_PLL_CGEN_TOP_CPUPLL_160M, /*!< pll cgen top cpupll 160m */ + GLB_PLL_CGEN_TOP_CPUPLL_400M, /*!< pll cgen top cpupll 400m */ + GLB_PLL_CGEN_TOP_WIFIPLL_240M, /*!< pll cgen top wifipll 240m */ + GLB_PLL_CGEN_TOP_WIFIPLL_320M, /*!< pll cgen top wifipll 320m */ + GLB_PLL_CGEN_TOP_AUPLL_DIV2, /*!< pll cgen top aupll div2 */ + GLB_PLL_CGEN_TOP_AUPLL_DIV1, /*!< pll cgen top aupll div1 */ +} GLB_PLL_CGEN_Type; + +/** + * @brief GLB mcu system clock type definition + */ +typedef enum { + GLB_MCU_SYS_CLK_RC32M, /*!< use RC32M as system clock frequency */ + GLB_MCU_SYS_CLK_XTAL, /*!< use XTAL as system clock */ + GLB_MCU_SYS_CLK_CPUPLL_400M, /*!< use CPUPLL output 400M as system clock */ + GLB_MCU_SYS_CLK_WIFIPLL_240M, /*!< use WIFIPLL output 240M as system clock */ + GLB_MCU_SYS_CLK_WIFIPLL_320M, /*!< use WIFIPLL output 320M as system clock */ +} GLB_MCU_SYS_CLK_Type; + +/** + * @brief GLB dsp system clock type definition + */ +typedef enum { + GLB_DSP_SYS_CLK_RC32M, /*!< use RC32M as system clock frequency */ + GLB_DSP_SYS_CLK_XTAL, /*!< use XTAL as system clock */ + GLB_DSP_SYS_CLK_MM_WIFIPLL_240M, /*!< use WIFIPLL 240M as system clock */ + GLB_DSP_SYS_CLK_MM_WIFIPLL_320M, /*!< use WIFIPLL 320M as system clock */ + GLB_DSP_SYS_CLK_CPUPLL_400M, /*!< use CPUPLL output 400M as system clock */ +} GLB_DSP_SYS_CLK_Type; + +/** + * @brief GLB dsp pbus clock type definition + */ +typedef enum { + GLB_DSP_SYS_PBCLK_RC32M, /*!< use rc32m as pbus clock */ + GLB_DSP_SYS_PBCLK_XTAL, /*!< use xtal as pbus clock */ + GLB_DSP_SYS_PBCLK_MM_WIFIPLL_160M, /*!< use mm_wifipll_160m_clk as pbus clock */ + GLB_DSP_SYS_PBCLK_CPUPLL_160M, /*!< use cpupll_160m_clk as pbus clock */ + GLB_DSP_SYS_PBCLK_MM_WIFIPLL_240M, /*!< use mm_wifipll_240m_clk as pbus clock */ +} GLB_DSP_SYS_PBCLK_Type; + +/** + * @brief GLB dsp system clock type definition + */ +typedef enum { + GLB_PLL_REFCLK_XTAL = 0, /*!< use XTAL as pll ref clock */ + GLB_PLL_REFCLK_RC32M = 3, /*!< use RC32M as pll ref clock */ +} GLB_PLL_REF_CLK_Type; + +typedef struct { + uint8_t clkpllRefdivRatio; /*!< xxx pll_refdiv_ratio */ + uint8_t clkpllIntFracSw; /*!< xxx pll_int_frac_sw */ + uint8_t clkpllIcp1u; /*!< xxx pll_icp_1u */ + uint8_t clkpllIcp5u; /*!< xxx pll_icp_5u */ + uint8_t clkpllRz; /*!< xxx pll_rz */ + uint8_t clkpllCz; /*!< xxx pll_cz */ + uint8_t clkpllC3; /*!< xxx pll_c3 */ + uint8_t clkpllR4Short; /*!< xxx pll_r4_short */ + uint8_t clkpllC4En; /*!< xxx pll_r4_en */ + uint8_t clkpllSelSampleClk; /*!< xxx pll_sel_sample_clk */ + uint8_t clkpllVcoSpeed; /*!< xxx pll_vco_speed */ + uint8_t clkpllSdmCtrlHw; /*!< xxx pll_sdm_ctrl_hw */ + uint8_t clkpllSdmBypass; /*!< xxx pll_sdm_bypass */ +} GLB_WAC_PLL_CFG_BASIC_Type; + +typedef struct { + const GLB_WAC_PLL_CFG_BASIC_Type *const basicCfg; /*!< pll basic configuration */ + uint32_t clkpllSdmin; /*!< pll sdmin value */ +} GLB_WAC_PLL_Cfg_Type; + +typedef struct { + uint8_t clkpllRefdivRatio; /*!< xxx pll_refdiv_ratio */ + uint8_t clkpllSelSampleClk; /*!< xxx pll_sel_sample_clk */ + uint8_t clkpllVcoSpeed; /*!< xxx pll_vco_speed */ + uint8_t clkpllEvenDivEn; /*!< xxx pll_even_div_en */ + uint8_t clkpllEvenDivRatio; /*!< xxx pll_even_div_ratio */ +} GLB_MU_PLL_CFG_BASIC_Type; + +typedef struct { + const GLB_MU_PLL_CFG_BASIC_Type *const basicCfg; /*!< pll basic configuration */ + uint32_t clkpllSdmin; /*!< pll sdmin value */ +} GLB_MU_PLL_Cfg_Type; + +/** + * @brief GLB CAM clock type definition + */ +typedef enum { + GLB_CAM_CLK_XCLK, /*!< Select XCLK as CAM clock */ + GLB_CAM_CLK_WIFIPLL_96M, /*!< Select WIFIPLL_96M as CAM clock */ + GLB_CAM_CLK_CPUPLL_100M, /*!< Select CPUPLL_96M as CAM clock */ +} GLB_CAM_CLK_Type; + +/** + * @brief GLB SDH clock type definition + */ +typedef enum { + GLB_SDH_CLK_WIFIPLL_96M, /*!< Select WIFIPLL_96M as SDH clock */ + GLB_SDH_CLK_CPUPLL_100M, /*!< Select CPUPLL_100M as SDH clock */ +} GLB_SDH_CLK_Type; + +/** + * @brief GLB UART sig swap group type definition + */ +typedef enum { + GLB_UART_SIG_SWAP_GRP_GPIO0_GPIO11, /*!< SWAP UART SIG GROUP GPIO0 - GPIO11 */ + GLB_UART_SIG_SWAP_GRP_GPIO12_GPIO23, /*!< SWAP UART SIG GROUP GPIO12 - GPIO23 */ + GLB_UART_SIG_SWAP_GRP_GPIO24_GPIO35, /*!< SWAP UART SIG GROUP GPIO24 - GPIO35 */ + GLB_UART_SIG_SWAP_GRP_GPIO36_GPIO45, /*!< SWAP UART SIG GROUP GPIO36 - GPIO45 */ +} GLB_UART_SIG_SWAP_GRP_Type; + +/** + * @brief GLB I2S output ref clock type definition + */ +typedef enum { + GLB_I2S_OUT_REF_CLK_NONE, /*!< no output reference clock on I2S_0 ref_clock port */ + GLB_I2S_OUT_REF_CLK_SRC, /*!< output reference clock on I2S_0 ref_clock port */ +} GLB_I2S_OUT_REF_CLK_Type; + +/** + * @brief GLB DMA clock ID type definition + */ +typedef enum { + GLB_DMA0_CLK_CH0, /*!< DMA0 clock ID:channel 0 */ + GLB_DMA0_CLK_CH1, /*!< DMA0 clock ID:channel 1 */ + GLB_DMA0_CLK_CH2, /*!< DMA0 clock ID:channel 2 */ + GLB_DMA0_CLK_CH3, /*!< DMA0 clock ID:channel 3 */ + GLB_DMA0_CLK_CH4, /*!< DMA0 clock ID:channel 4 */ + GLB_DMA0_CLK_CH5, /*!< DMA0 clock ID:channel 5 */ + GLB_DMA0_CLK_CH6, /*!< DMA0 clock ID:channel 6 */ + GLB_DMA0_CLK_CH7, /*!< DMA0 clock ID:channel 7 */ + GLB_DMA1_CLK_CH0, /*!< DMA1 clock ID:channel 0 */ + GLB_DMA1_CLK_CH1, /*!< DMA1 clock ID:channel 1 */ + GLB_DMA1_CLK_CH2, /*!< DMA1 clock ID:channel 2 */ + GLB_DMA1_CLK_CH3, /*!< DMA1 clock ID:channel 3 */ +} GLB_DMA_CLK_ID_Type; + +/** + * @brief GLB peripheral DMA type definition + */ +typedef enum { + GLB_PERI_DMA_UART0_RX = 0, /*!< uart_rx */ + GLB_PERI_DMA_UART0_TX = 1, /*!< uart_tx */ + GLB_PERI_DMA_UART1_RX = 2, /*!< uart1_rx */ + GLB_PERI_DMA_UART1_TX = 3, /*!< uart1_tx */ + GLB_PERI_DMA_UART2_RX = 4, /*!< uart2_rx */ + GLB_PERI_DMA_UART2_TX = 5, /*!< uart2_tx */ + GLB_PERI_DMA_I2C_0_RX = 6, /*!< i2c_0_rx */ + GLB_PERI_DMA_I2C_0_TX = 7, /*!< i2c_0_tx */ + GLB_PERI_DMA_IRTX_TX = 8, /*!< irtx_tx */ + GLB_PERI_DMA_GPIO_TX = 9, /*!< gpio_tx */ + GLB_PERI_DMA_SPI_RX = 10, /*!< spi_rx */ + GLB_PERI_DMA_SPI_TX = 11, /*!< spi_tx */ + GLB_PERI_DMA_AUDIO_RX = 12, /*!< audio_rx */ + GLB_PERI_DMA_AUDIO_TX = 13, /*!< audio_tx */ + GLB_PERI_DMA_I2C_1_RX = 14, /*!< i2c_1_rx */ + GLB_PERI_DMA_I2C_1_TX = 15, /*!< i2c_1_tx */ + GLB_PERI_DMA_I2S_0_RX = 16, /*!< i2s_0_rx */ + GLB_PERI_DMA_I2S_0_TX = 17, /*!< i2s_0_tx */ + GLB_PERI_DMA_PDM_RX = 18, /*!< pdm_rx */ + GLB_PERI_DMA_PADC = 19, /*!< padc */ + GLB_PERI_DMA_GAUGE = 20, /*!< gauge */ + GLB_PERI_DMA_GPADC = 22, /*!< gpadc */ + GLB_PERI_DMA_GPDAC_TX = 23, /*!< gpdac_tx */ +} GLB_PERI_DMA_Type; + +/** + * @brief GLB DMA CN selection type definition + */ +typedef enum { + GLB_PERI_DMA_CN_SEL_DMA0 = 0, /*!< peripheral DMA channel select DMA0 */ + GLB_PERI_DMA_CN_SEL_DMA1 = 1, /*!< peripheral DMA channel select DMA1 */ +} GLB_PERI_DMA_CN_SEL_Type; + +/** + * @brief GLB clock source type definition + */ +typedef enum { + GLB_IR_CLK_SRC_XCLK, /*!< IR clock source select XCLK */ +} GLB_IR_CLK_SRC_Type; + +/** + * @brief GLB flash clock type definition + */ +typedef enum { + GLB_SFLASH_CLK_120M_WIFIPLL, /*!< Select WIFIPLL 120M as flash clock */ + GLB_SFLASH_CLK_XTAL, /*!< Select XTAL as flash clock */ + GLB_SFLASH_CLK_100M_CPUPLL, /*!< Select CPUPLL 100M as flash clock */ + GLB_SFLASH_CLK_80M_MUXPLL, /*!< Select MUXPLL 80M as flash clock */ + GLB_SFLASH_CLK_BCLK, /*!< Select BCLK as flash clock */ + GLB_SFLASH_CLK_96M_WIFIPLL, /*!< Select WIFIPLL 96M as flash clock */ +} GLB_SFLASH_CLK_Type; + +/** + * @brief GLB I2C clock type definition + */ +typedef enum { + GLB_I2C_CLK_BCLK, /*!< Select bus clk as I2C clock */ + GLB_I2C_CLK_XCLK, /*!< Select xclk as I2C clock */ +} GLB_I2C_CLK_Type; + +/** + * @brief GLB SPI clock type definition + */ +typedef enum { + GLB_SPI_CLK_MCU_MUXPLL_160M, /*!< Select MCU MUXPLL 160M as SPI clock */ + GLB_SPI_CLK_XCLK, /*!< Select xclk as SPI clock */ +} GLB_SPI_CLK_Type; + +/** + * @brief GLB PWM1 io type definition + */ +typedef enum { + GLB_PWM1_IO_SINGLE_END, /*!< Select pwm1 io single end */ + GLB_PWM1_IO_DIFF_END, /*!< Select pwm1 io differential end for BLDC */ +} GLB_PWM1_IO_SEL_Type; + +/** + * @brief GLB PWM2 io type definition + */ +typedef enum { + GLB_PWM2_IO_SINGLE_END, /*!< Select pwm2 io single end */ + GLB_PWM2_IO_SINGLE_END_BLDC, /*!< Select pwm2 io single end BLDC */ +} GLB_PWM2_IO_SEL_Type; + +/** + * @brief GLB PDM io type definition + */ +typedef enum { + GLB_PDM_IO_SEL_AUDIO_TOP, /*!< Select audio_top PDM */ + GLB_PDM_IO_SEL_AUPDM_TOP, /*!< Select aupdm_top PDM */ +} GLB_PDM_IO_SEL_Type; + +/** + * @brief GLB SPI pad action type definition + */ +typedef enum { + GLB_SPI_PAD_ACT_AS_SLAVE, /*!< SPI pad act as slave */ + GLB_SPI_PAD_ACT_AS_MASTER, /*!< SPI pad act as master */ +} GLB_SPI_PAD_ACT_AS_Type; + +/** + * @brief GLB AHB software type definition + */ +typedef enum { + GLB_AHB_MCU_SW_RSV0 = 0, + GLB_AHB_MCU_SW_RSV1 = 1, + GLB_AHB_MCU_SW_WIFI = 4, + GLB_AHB_MCU_SW_BTDM = 8, + GLB_AHB_MCU_SW_ZIGBEE = 9, + GLB_AHB_MCU_SW_BLE2 = 10, + GLB_AHB_MCU_SW_ZIGBEE2 = 11, + GLB_AHB_MCU_SW_EMI_MISC = 16, + GLB_AHB_MCU_SW_PSRAM0_CTRL = 17, + GLB_AHB_MCU_SW_PSRAM1_CTRL = 18, + GLB_AHB_MCU_SW_USB_EMAC = 19, + GLB_AHB_MCU_SW_RSV20 = 20, + GLB_AHB_MCU_SW_AUDIO = 21, + GLB_AHB_MCU_SW_SDH = 22, + GLB_AHB_MCU_SW_RSV23 = 23, + GLB_AHB_MCU_SW_DMA2 = 24, + GLB_AHB_MCU_SW_GLB = 32, + GLB_AHB_MCU_SW_MIX = 33, + GLB_AHB_MCU_SW_GPIP = 34, + GLB_AHB_MCU_SW_SEC_DBG = 35, + GLB_AHB_MCU_SW_SEC_ENG = 36, + GLB_AHB_MCU_SW_TZ1 = 37, + GLB_AHB_MCU_SW_TZ2 = 38, + GLB_AHB_MCU_SW_EFUSE = 39, + GLB_AHB_MCU_SW_CCI = 40, + GLB_AHB_MCU_SW_MCU_PERI_BUS = 41, + GLB_AHB_MCU_SW_RSV42 = 42, + GLB_AHB_MCU_SW_SF = 43, + GLB_AHB_MCU_SW_DMA = 44, + GLB_AHB_MCU_SW_SDU = 45, + GLB_AHB_MCU_SW_PDS = 46, + GLB_AHB_MCU_SW_RSV47 = 47, + GLB_AHB_MCU_SW_UART0 = 48, + GLB_AHB_MCU_SW_UART1 = 49, + GLB_AHB_MCU_SW_SPI = 50, + GLB_AHB_MCU_SW_I2C = 51, + GLB_AHB_MCU_SW_PWM = 52, + GLB_AHB_MCU_SW_TIMER = 53, + GLB_AHB_MCU_SW_IR_REMOTE = 54, + GLB_AHB_MCU_SW_CHECKSUM = 55, + GLB_AHB_MCU_SW_IPC = 56, + GLB_AHB_MCU_SW_I2C1 = 57, + GLB_AHB_MCU_SW_UART2 = 58, + GLB_AHB_MCU_SW_I2S = 59, + GLB_AHB_MCU_SW_AUPDM = 60, + GLB_AHB_MCU_SW_LZ4 = 61, + GLB_AHB_MCU_SW_RSV62 = 62, + GLB_AHB_MCU_SW_RSV63 = 63, + GLB_AHB_MCU_SW_PWRON_RST = 64, + GLB_AHB_MCU_SW_CPU_RESET = 65, + GLB_AHB_MCU_SW_SYS_RESET = 66, + GLB_AHB_MCU_SW_PICO_RESET = 67, + GLB_AHB_MCU_SW_CPU2_RESET = 68, + GLB_AHB_MCU_SW_CHIP_RESET = 69, + GLB_AHB_MCU_SW_WL_WDT_RESET_MM_EN = 70, + GLB_AHB_MCU_SW_MMWDT2WL_RST_MSK = 71, +} GLB_AHB_MCU_SW_Type; + +/** + * @brief GLB AHB software type definition + */ +typedef enum { + GLB_AHB_DSP_SW_REG_CTRL_SYS_RESET = 0, + GLB_AHB_DSP_SW_REG_CTRL_PWRON_RST = 2, + GLB_AHB_DSP_SW_REG_CTRL_MMCPU0_RESET = 8, + GLB_AHB_DSP_SW_SWRST_MM_MISC = 32, + GLB_AHB_DSP_SW_SWRST_DMA = 33, + GLB_AHB_DSP_SW_SWRST_UART0 = 34, + GLB_AHB_DSP_SW_SWRST_I2C0 = 35, + GLB_AHB_DSP_SW_SWRST_I2C1 = 36, + GLB_AHB_DSP_SW_SWRST_IPC = 37, + GLB_AHB_DSP_SW_SWRST_DMA2D = 38, + GLB_AHB_DSP_SW_SWRST_SPI = 40, + GLB_AHB_DSP_SW_SWRST_TIMER = 41, + GLB_AHB_DSP_SW_SWRST_I2S0 = 42, + GLB_AHB_DSP_SW_SWRST_I2S1 = 43, + GLB_AHB_DSP_SW_SWRST_PDM0 = 44, + GLB_AHB_DSP_SW_SWRST_PDM1 = 45, + GLB_AHB_DSP_SW_SWRST_PUHS = 47, + GLB_AHB_DSP_SW_SWRST_DSP2_MISC = 64, + GLB_AHB_DSP_SW_SWRST_DSP2_MAIN = 65, + GLB_AHB_DSP_SW_SWRST_DSP2_TSRC = 66, + GLB_AHB_DSP_SW_SWRST_DP_TSRC = 67, + GLB_AHB_DSP_SW_SWRST_NR3D_CTRL = 68, + GLB_AHB_DSP_SW_SWRST_DVP2BUSA = 69, + GLB_AHB_DSP_SW_SWRST_DVP2BUSB = 70, + GLB_AHB_DSP_SW_SWRST_DVP2BUSC = 71, + GLB_AHB_DSP_SW_SWRST_DVP2BUSD = 72, + GLB_AHB_DSP_SW_SWRST_MIPI = 73, + GLB_AHB_DSP_SW_SWRST_DSP2_REG = 80, + GLB_AHB_DSP_SW_SWRST_DVP2BUSE = 81, + GLB_AHB_DSP_SW_SWRST_DVP2BUSF = 82, + GLB_AHB_DSP_SW_SWRST_DVP2BUSG = 83, + GLB_AHB_DSP_SW_SWRST_DVP2BUSH = 84, + GLB_AHB_DSP_SW_SWRST_CODEC_MISC = 96, + GLB_AHB_DSP_SW_SWRST_MJPEG = 97, + GLB_AHB_DSP_SW_SWRST_H264 = 98, + GLB_AHB_DSP_SW_SWRST_MJPEG_DEC = 99, + GLB_AHB_DSP_SW_SWRST_CNN = 100, + GLB_AHB_DSP_SW_SWRST_VRAM = 112, + GLB_AHB_DSP_SW_RG_IS_RST_N = 128, +} GLB_AHB_DSP_SW_Type; + +/** + * @brief GLB dis reset type definition + */ +typedef enum { + GLB_DISRST_GPIP = 2, + GLB_DISRST_SEC_ENG = 4, + GLB_DISRST_CCI = 8, + GLB_DISRST_SF = 11, + GLB_DISRST_UART0 = 16, + GLB_DISRST_UART1 = 17, + GLB_DISRST_SPI = 18, + GLB_DISRST_I2C0 = 19, + GLB_DISRST_PWM = 20, + GLB_DISRST_TIMER = 21, + GLB_DISRST_IR_REMOTE = 22, + GLB_DISRST_CHECKSUM = 23, + GLB_DISRST_IPC = 24, + GLB_DISRST_I2C1 = 25, + GLB_DISRST_UART2 = 26, +} GLB_DISRST_Type; + +/** + * @brief GLB PKA clock type definition + */ +typedef enum { + GLB_PKA_CLK_MCU_BCLK, /*!< Select MCU_BCLK as PKA clock */ + GLB_PKA_CLK_MCU_MUXPLL_160M, /*!< Select MCU MUXPLL 160M as PKA clock */ +} GLB_PKA_CLK_Type; + +/** + * @brief GLB MCU software system reset type definition + */ +typedef enum { + GLB_MCU_SW_SYSTEM_CTRL_MCU = 1, /*!< mcu reset */ + GLB_MCU_SW_SYSTEM_CTRL_LP = 3, /*!< lp reset */ +} GLB_MCU_SW_SYSTEM_Type; + +/** + * @brief BMX arb mode type definition + */ +typedef enum { + BMX_ARB_ROUND_ROBIN = 0, /*!< 0->round-robin */ + BMX_ARB_FIX = 1, /*!< 1->fix */ +} BMX_ARB_Type; + +/** + * @brief BMX latch type definition + */ +typedef enum { + BMX_LATCH_FIRST_ERROR = 0, /*!< 0->Latch first error */ + BMX_LATCH_LAST_ERROR = 1, /*!< 1->Latch last error */ +} BMX_LATCH_Type; + +/** + * @brief BMX configuration structure type definition + */ +typedef struct { + BMX_ARB_Type arbMod; /*!< 0->fix, 2->round-robin, 3->random */ + uint8_t timeoutEn; /*!< Bus timeout enable: detect slave no reaponse in 1024 cycles */ +} BMX_TO_Cfg_Type; + +/** + * @brief BMX bus err type definition + */ +typedef enum { + BMX_BUS_ERR_TRUSTZONE_DECODE, /*!< Bus trustzone decode error */ + BMX_BUS_ERR_ADDR_DECODE, /*!< Bus addr decode error */ +} BMX_BUS_ERR_Type; + +/** + * @brief BMX bus err interrupt type definition + */ +typedef enum { + BMX_ERR_INT_ERR, /*!< BMX bus err interrupt */ + BMX_ERR_INT_ALL, /*!< BMX bus err interrupt max num */ +} BMX_ERR_INT_Type; + +/** + * @brief BMX time out interrupt type definition + */ +typedef enum { + BMX_TO_INT_TIMEOUT, /*!< BMX timeout interrupt */ + BMX_TO_INT_ALL, /*!< BMX timeout interrupt max num */ +} BMX_TO_INT_Type; + +/** + * @brief GLB eth ref clock out type definition + */ +typedef enum { + GLB_ETH_REF_CLK_OUT_OUTSIDE_50M, /*!< select outside 50MHz RMII ref clock */ + GLB_ETH_REF_CLK_OUT_INSIDE_50M, /*!< select inside 50MHz RMII ref clock */ +} GLB_ETH_REF_CLK_OUT_Type; + +/** + * @brief GLB EM type definition + */ +typedef enum { + GLB_WRAM160KB_EM0KB, /*!< WRAM_160KB EM_0KB */ + GLB_WRAM144KB_EM16KB, /*!< WRAM_144KB EM_16KB */ + GLB_WRAM128KB_EM32KB, /*!< WRAM_128KB EM_32KB */ + GLB_WRAM112KB_EM48KB, /*!< WRAM_112KB EM_48KB */ + GLB_WRAM96KB_EM64KB, /*!< WRAM_96KB EM_64KB */ +} GLB_EM_Type; + +/** + * @brief GLB ADC clock type definition + */ +typedef enum { + GLB_ADC_CLK_AUPLL, /*!< use AUPLL as ADC clock */ + GLB_ADC_CLK_XCLK, /*!< use XCLK as ADC clock */ +} GLB_ADC_CLK_Type; + +/** + * @brief GLB DAC clock type definition + */ +typedef enum { + GLB_DAC_CLK_32M, /*!< use 32M as DAC clock */ + GLB_DAC_CLK_XCLK, /*!< use XCLK as DAC clock */ +} GLB_DAC_CLK_Type; + +/** + * @brief GLB chip clock input output type definition + */ +/** + * @brief GLB chip clock out 0 type definition + */ +typedef enum { + GLB_CHIP_CLK_OUT_0_CAM_REF_CLK = 0, /*!< cam_ref_clk */ + GLB_CHIP_CLK_OUT_0_I2S_REF_CLK = 1, /*!< i2s_ref_clk out */ + GLB_CHIP_CLK_OUT_0_CLK_AUDIO_ADC = 2, /*!< clk_adc */ + GLB_CHIP_CLK_OUT_0_CLK_AUDIO_DAC = 3, /*!< clk_dac */ +} GLB_CHIP_CLK_OUT_0_Type; + +/** + * @brief GLB chip clock out 1 type definition + */ +typedef enum { + GLB_CHIP_CLK_OUT_1_CAM_REF_CLK = 0, /*!< no chip clock out */ + GLB_CHIP_CLK_OUT_1_I2S_REF_CLK = 1, /*!< i2s_ref_clk out */ + GLB_CHIP_CLK_OUT_1_CLK_AUDIO_ADC = 2, /*!< clk_adc_in_128fs */ + GLB_CHIP_CLK_OUT_1_CLK_AUDIO_DAC = 3, /*!< clk_dac_in_128fs */ +} GLB_CHIP_CLK_OUT_1_Type; + +/** + * @brief GLB chip clock out 2 type definition + */ +typedef enum { + GLB_CHIP_CLK_OUT_2_CAM_REF_CLK = 0, /*!< cam_ref_clk */ + GLB_CHIP_CLK_OUT_2_I2S_REF_CLK = 1, /*!< i2s_ref_clk */ + GLB_CHIP_CLK_OUT_2_ANA_XTAL_CLK = 2, /*!< ana_xtal_clk */ + GLB_CHIP_CLK_OUT_2_PLL_32M_CLK = 3, /*!< pll_32m_clk */ +} GLB_CHIP_CLK_OUT_2_Type; + +/** + * @brief GLB chip clock out 3 type definition + */ +typedef enum { + GLB_CHIP_CLK_OUT_3_CAM_REF_CLK = 0, /*!< no chip clock out */ + GLB_CHIP_CLK_OUT_3_I2S_REF_CLK = 1, /*!< i2s_ref_clk out */ + GLB_CHIP_CLK_OUT_3_NONE = 2, /*!< no clock out */ + GLB_CHIP_CLK_OUT_3_PLL_48M_CLK = 3, /*!< pll_48m_clk */ +} GLB_CHIP_CLK_OUT_3_Type; + +/** + * @brief GLB CSI DSI clock source select type definition + */ +typedef enum { + GLB_CSI_DSI_CLK_SEL_XTAL_CLK, /*!< xtal_clk */ + GLB_CSI_DSI_CLK_SEL_CPUPLL_DIV10, /*!< cpupll_div10 */ +} GLB_CSI_DSI_CLK_SEL_Type; + +/** + * @brief GLB DIG clock source select type definition + */ +typedef enum { + GLB_DIG_CLK_WIFIPLL_32M, /*!< select WIFIPLL 32M as DIG clock source */ + GLB_DIG_CLK_XCLK, /*!< select XCLK as DIG clock source */ + GLB_DIG_CLK_AUPLL, /*!< select AUPLL as DIG clock source */ +} GLB_DIG_CLK_Type; + +/** + * @brief GLB 512K clock out select type definition + */ +typedef enum { + GLB_512K_CLK_OUT_512K, /*!< select 512K clock out */ + GLB_512K_CLK_OUT_256K, /*!< select 256K clock out */ + GLB_512K_CLK_OUT_128K, /*!< select 128K clock out */ +} GLB_512K_CLK_OUT_Type; + +/** + * @brief GLB BT bandwidth type definition + */ +typedef enum { + GLB_BT_BANDWIDTH_1M, /*!< BT bandwidth 1MHz */ + GLB_BT_BANDWIDTH_2M, /*!< BT bandwidth 2MHz */ +} GLB_BT_BANDWIDTH_Type; + +/** + * @brief GLB UART2 IO selection type definition + */ +typedef enum { + GLB_UART2_IO_SEL_UART2, /*!< Select UART2 function */ + GLB_UART2_IO_SEL_ISO11898, /*!< Select ISO11898 function */ +} GLB_UART2_IO_SEL_Type; + +/** + * @brief GLB UART signal type definition + */ +typedef enum { + GLB_UART_SIG_0, /*!< UART signal 0 */ + GLB_UART_SIG_1, /*!< UART signal 1 */ + GLB_UART_SIG_2, /*!< UART signal 2 */ + GLB_UART_SIG_3, /*!< UART signal 3 */ + GLB_UART_SIG_4, /*!< UART signal 4 */ + GLB_UART_SIG_5, /*!< UART signal 5 */ + GLB_UART_SIG_6, /*!< UART signal 6 */ + GLB_UART_SIG_7, /*!< UART signal 7 */ + GLB_UART_SIG_8, /*!< UART signal 8 */ + GLB_UART_SIG_9, /*!< UART signal 9 */ + GLB_UART_SIG_10, /*!< UART signal 10 */ + GLB_UART_SIG_11, /*!< UART signal 11 */ +} GLB_UART_SIG_Type; + +/** + * @brief GLB UART signal function type definition + */ +typedef enum { + GLB_UART_SIG_FUN_UART0_RTS, /*!< UART funtion: UART 0 RTS */ + GLB_UART_SIG_FUN_UART0_CTS, /*!< UART funtion: UART 0 CTS */ + GLB_UART_SIG_FUN_UART0_TXD, /*!< UART funtion: UART 0 TXD */ + GLB_UART_SIG_FUN_UART0_RXD, /*!< UART funtion: UART 0 RXD */ + GLB_UART_SIG_FUN_UART1_RTS, /*!< UART funtion: UART 1 RTS */ + GLB_UART_SIG_FUN_UART1_CTS, /*!< UART funtion: UART 1 CTS */ + GLB_UART_SIG_FUN_UART1_TXD, /*!< UART funtion: UART 1 TXD */ + GLB_UART_SIG_FUN_UART1_RXD, /*!< UART funtion: UART 1 RXD */ + GLB_UART_SIG_FUN_UART2_RTS, /*!< UART funtion: UART 2 RTS */ + GLB_UART_SIG_FUN_UART2_CTS, /*!< UART funtion: UART 2 CTS */ + GLB_UART_SIG_FUN_UART2_TXD, /*!< UART funtion: UART 2 TXD */ + GLB_UART_SIG_FUN_UART2_RXD, /*!< UART funtion: UART 2 RXD */ +} GLB_UART_SIG_FUN_Type; + +/** + * @brief XTAL type definition + */ +typedef enum { + GLB_XTAL_NONE, /*!< XTAL is none */ + GLB_XTAL_24M, /*!< XTAL is 24M */ + GLB_XTAL_32M, /*!< XTAL is 32M */ + GLB_XTAL_38P4M, /*!< XTAL is 38.4M */ + GLB_XTAL_40M, /*!< XTAL is 40M */ + GLB_XTAL_26M, /*!< XTAL is 26M */ + GLB_XTAL_RC32M, /*!< XTAL is RC32M */ + GLB_XTAL_MAX, /*!< type max num */ +} GLB_XTAL_Type; + +/** + * @brief PLL power on type definition + */ +typedef enum { + GLB_PLL_NONE = 0, /*!< power on xtal and pll */ + GLB_PLL_WIFIPLL = 1, /*!< power on WIFIPLL */ + GLB_PLL_AUPLL = 2, /*!< power on AUPLL */ + GLB_PLL_CPUPLL = 4, /*!< power on CPUPLL */ + GLB_PLL_MIPIPLL = 8, /*!< power on ETHPLL */ + GLB_PLL_UHSPLL = 16, /*!< power on ETHPLL */ +} GLB_PLL_Type; + +/** + * @brief WAC PLL XTAL type definition + */ +typedef enum { + GLB_WAC_PLL_WIFIPLL, /*!< wifi pll */ + GLB_WAC_PLL_AUPLL, /*!< audio pll */ + GLB_WAC_PLL_CPUPLL, /*!< cpu pll */ +} GLB_WAC_PLL_Type; + +/** + * @brief MU PLL XTAL type definition + */ +typedef enum { + GLB_MU_PLL_MIPIPLL, /*!< mipi pll */ + GLB_MU_PLL_UHSPLL, /*!< uhs pll */ +} GLB_MU_PLL_Type; + +/** + * @brief DISP clock type definition + */ +typedef enum { + GLB_DISP_CLK_MIPIPLL_1500M, /*!< mipi pll 1500M */ +} GLB_DISP_CLK_Type; + +/** + * @brief PLL XTAL type definition + */ +typedef enum { + GLB_PSRAM_EMI_CPUPLL_400M, /*!< emi_cpupll_400m_clk */ + GLB_PSRAM_EMI_WIFIPLL_320M, /*!< emi_wifipll_320m_clk */ + GLB_PSRAM_EMI_AUPLL_DIV1, /*!< emi_aupll_div1_clk */ +} GLB_PSRAM_PLL_Type; + +/** + * @brief GLB DSP xclk clock type definition + */ +typedef enum { + GLB_DSP_XCLK_RC32M, /*!< use RC32M as xclk clock */ + GLB_DSP_XCLK_XTAL, /*!< use XTAL as xclk clock */ +} GLB_DSP_XCLK_Type; + +/** + * @brief GLB DSP root clock type definition + */ +typedef enum { + GLB_DSP_ROOT_CLK_XCLK, /*!< use XCLK as root clock */ + GLB_DSP_ROOT_CLK_PLL, /*!< use PLL as root clock */ +} GLB_DSP_ROOT_CLK_Type; + +/** + * @brief GLB DSP pbroot clock type definition + */ +typedef enum { + GLB_DSP_PBROOT_CLK_MM_XCLK, /*!< use mm_xclk as pbroot clock */ + GLB_DSP_PBROOT_CLK_MM_MUXPLL_160M, /*!< use mm_muxpll_160m_clk as pbroot clock */ + GLB_DSP_PBROOT_CLK_MM_MUXPLL_240M, /*!< use mm_muxpll_240m_clk as pbroot clock */ +} GLB_DSP_PBROOT_CLK_Type; + +/** + * @brief GLB DSP PLL clock type definition + */ +typedef enum { + GLB_DSP_PLL_CLK_MUXPLL_240M, /*!< select DSP PLL output muxpll 240m as cpu clock */ + GLB_DSP_PLL_CLK_MUXPLL_320M, /*!< select DSP PLL output muxpll 320m as cpu clock */ + GLB_DSP_PLL_CLK_CPUPLL_400M, /*!< select DSP PLL output cpupll 400m as cpu clock */ +} GLB_DSP_PLL_CLK_Type; + +/** + * @brief GLB DSP UART clock type definition + */ +typedef enum { + GLB_DSP_UART_CLK_DSP_PBCLK, /*!< Select dsp pbclk as UART clock */ + GLB_DSP_UART_CLK_MUXPLL_160M, /*!< Select muxpll 160m as UART clock */ + GLB_DSP_UART_CLK_DSP_XCLK, /*!< Select xclk as UART clock */ +} GLB_DSP_UART_CLK_Type; + +/** + * @brief GLB UART clock type definition + */ +typedef enum { + GLB_UART_CLK_BCLK, /*!< Select bclk clock as UART clock */ + GLB_UART_CLK_PLL_160M, /*!< Select PLL 160M as UART clock */ +} GLB_UART_CLK_Type; + +/** + * @brief GLB DSP CNN clock type definition + */ +typedef enum { + GLB_DSP_CNN_CLK_160M, /*!< Select 160M as CNN clock */ + GLB_DSP_CNN_CLK_240M, /*!< Select 240M as CNN clock */ + GLB_DSP_CNN_CLK_320M, /*!< Select 320M as CNN clock */ +} GLB_DSP_CNN_CLK_Type; + +/** + * @brief GLB DSP DP clock type definition + */ +typedef enum { + GLB_DSP_DP_CLK_DISPLAY_PLL, /*!< Select display pll as DP clock */ + GLB_DSP_DP_CLK_DSP_XCLK, /*!< Select mm xclk as DP clock */ +} GLB_DSP_DP_CLK_Type; + +/** + * @brief GLB DSP DSP2 clock type definition + */ +typedef enum { + GLB_DSP_DSP2_CLK_MUXPLL_160M, /*!< Select muxpll 160M as DSP2 clock */ + GLB_DSP_DSP2_CLK_MUXPLL_240M, /*!< Select muxpll 240M as DSP2 clock */ + GLB_DSP_DSP2_CLK_CPUPLL_400M, /*!< Select cpupll 400M as DSP2 clock */ + GLB_DSP_DSP2_CLK_DSP_XCLK, /*!< Select dsp xclk as DSP2 clock */ +} GLB_DSP_DSP2_CLK_Type; + +/** + * @brief GLB DSP H264 clock type definition + */ +typedef enum { + GLB_DSP_H264_DSP_MUXPLL_160M, /*!< Select dsp muxpll 160M as DSP2 clock */ + GLB_DSP_H264_DSP_MUXPLL_240M, /*!< Select dsp muxpll 240M as DSP2 clock */ + GLB_DSP_H264_DSP_MUXPLL_320M, /*!< Select dsp muxpll 320M as DSP2 clock */ +} GLB_DSP_H264_CLK_Type; + +/** + * @brief GLB DSP SPI clock type definition + */ +typedef enum { + GLB_DSP_SPI_CLK_DSP_MUXPLL_160M, /*!< Select muxpll 160M as SPI clock */ + GLB_DSP_SPI_CLK_DSP_XCLK, /*!< Select xclk as SPI clock */ +} GLB_DSP_SPI_CLK_Type; + +/** + * @brief GLB DSP I2C clock type definition + */ +typedef enum { + GLB_DSP_I2C_CLK_DSP_PBCLK, /*!< Select dsp pbclk as I2C clock */ + GLB_DSP_I2C_CLK_XCLK, /*!< Select xclk as I2C clock */ +} GLB_DSP_I2C_CLK_Type; + +/** + * @brief GLB I2S di ref clock type definition + */ +typedef enum { + GLB_I2S_DI_SEL_I2S_DI_INPUT, /*!< Select i2s_di input */ + GLB_I2S_DI_SEL_I2S_REF_OUTPUT, /*!< Select i2s_ref_clk output */ +} GLB_I2S_DI_REF_CLK_Type; + +/** + * @brief GLB I2S do ref clock type definition + */ +typedef enum { + GLB_I2S_DO_SEL_I2S_DO_OUTPT, /*!< Select i2s_do output */ + GLB_I2S_DO_SEL_I2S_REF_OUTPUT, /*!< Select i2s_ref_clk output */ +} GLB_I2S_DO_REF_CLK_Type; + +/** + * @brief GLB EMI clock type definition + */ +typedef enum { + GLB_EMI_CLK_MCU_PBCLK, /*!< mcu_pbclk */ + GLB_EMI_CLK_CPUPLL_200M_CLK, /*!< cpupll_200m_clk */ + GLB_EMI_CLK_WIFIPLL_320M_CLK, /*!< wifipll_320m_clk */ + GLB_EMI_CLK_CPUPLL_400M_CLK, /*!< cpupll_400m_clk */ +} GLB_EMI_CLK_Type; + +/** + * @brief GLB DSP sw system type definition + */ +typedef enum { + GLB_DSP_SW_SYSTEM_CTRL_SYS = 0, /*!< SW system reset(pulse trigger) */ + GLB_DSP_SW_SYSTEM_CTRL_PWRON = 2, /*!< SW power-on reset (pulse trigger) */ + GLB_DSP_SW_SYSTEM_CTRL_DSP0 = 8, /*!< MMCPU0 reset(pulse trigger) */ + GLB_DSP_SW_SYSTEM_CTRL_DSP1 = 9, /*!< MMCPU1 reset(pulse trigger) */ + GLB_DSP_SW_SYSTEM_CTRL_WL2MM = 15, /*!< wl2mm */ +} GLB_DSP_SW_SYSTEM_Type; + +/** + * @brief GLB DSP peripheral type definition + */ +typedef enum { + GLB_DSP_PERIPHERAL_MM_MISC = 0, /*!< mm_misc */ + GLB_DSP_PERIPHERAL_DMA = 1, /*!< dma */ + GLB_DSP_PERIPHERAL_UART0 = 2, /*!< uart0 */ + GLB_DSP_PERIPHERAL_I2C0 = 3, /*!< i2c0 */ + GLB_DSP_PERIPHERAL_IPC = 5, /*!< ipc */ + GLB_DSP_PERIPHERAL_SPI = 8, /*!< spi */ + GLB_DSP_PERIPHERAL_TIMER = 9, /*!< timer */ + GLB_DSP_PERIPHERAL_I2S0 = 10, /*!< i2s0 */ +} GLB_DSP_PERIPHERAL_Type; + +/** + * @brief GLB DSP dsp2 sub type definition + */ +typedef enum { + GLB_DSP_DSP2_SUB_DSP2_MISC = 0, /*!< dsp2_misc */ + GLB_DSP_DSP2_SUB_DVP2BUSA = 1, /*!< dvp2busA */ + GLB_DSP_DSP2_SUB_DVP2BUSB = 2, /*!< dvp2busB */ + GLB_DSP_DSP2_SUB_DVP2BUSC = 3, /*!< dvp2busC */ + GLB_DSP_DSP2_SUB_OSD_DRAW = 4, /*!< osd_draw */ + GLB_DSP_DSP2_SUB_DP = 5, /*!< display */ + GLB_DSP_DSP2_SUB_IMG_PR = 16, /*!< img_pr scaler/yuv2rgb */ + GLB_DSP_DSP2_SUB_SCLRA = 17, /*!< ScalerA */ + GLB_DSP_DSP2_SUB_SCLRB = 18, /*!< ScalerB */ +} GLB_DSP_DSP2_SUB_Type; + +/** + * @brief GLB DSP codec sub type definition + */ +typedef enum { + GLB_DSP_CODEC_SUB_MJPEG = 1, /*!< mjpeg */ + GLB_DSP_CODEC_SUB_CNN = 2, /*!< BLAI */ + GLB_DSP_CODEC_SUB_VRAM = 16, /*!< vram control logic(SRAM content would not be reset) */ +} GLB_DSP_CODEC_SUB_Type; + +/** + * @brief GLB DSP image sensor type definition + */ +typedef enum { + GLB_DSP_IMAGE_SENSOR_RG_IS = 1, /*!< Image sensor */ +} GLB_DSP_IMAGE_SENSOR_Type; + +/*@} end of group GLB_Public_Types */ + +/** @defgroup GLB_Public_Constants + * @{ + */ + +/** @defgroup GLB_CORE_ID_TYPE + * @{ + */ +#define IS_GLB_CORE_ID_TYPE(type) (((type) == GLB_CORE_ID_M0) || \ + ((type) == GLB_CORE_ID_D0) || \ + ((type) == GLB_CORE_ID_LP) || \ + ((type) == GLB_CORE_ID_MAX) || \ + ((type) == GLB_CORE_ID_INVALID)) + +/** @defgroup CCI_ID_TYPE + * @{ + */ +#define IS_CCI_ID_TYPE(type) (((type) == CCI0_ID) || \ + ((type) == CCI_ID_MAX)) + +/** @defgroup GLB_DSP_ALL_INT_TYPE + * @{ + */ +#define IS_GLB_DSP_ALL_INT_TYPE(type) (((type) == GLB_DSP_ALL_INT_BUS_DEC_ERR_INT) || \ + ((type) == GLB_DSP_ALL_INT_DSP2_AWB3_INT) || \ + ((type) == GLB_DSP_ALL_INT_IPC2_NP2AP_IRQ) || \ + ((type) == GLB_DSP_ALL_INT_RSV3) || \ + ((type) == GLB_DSP_ALL_INT_UART0_INT) || \ + ((type) == GLB_DSP_ALL_INT_I2C0_INT) || \ + ((type) == GLB_DSP_ALL_INT_I2C1_INT) || \ + ((type) == GLB_DSP_ALL_INT_SPI_INT) || \ + ((type) == GLB_DSP_ALL_INT_DSP2_AE_INT) || \ + ((type) == GLB_DSP_ALL_INT_DSP2_AWB_INT) || \ + ((type) == GLB_DSP_ALL_INT_SEOF1_INT) || \ + ((type) == GLB_DSP_ALL_INT_SEOF2_INT) || \ + ((type) == GLB_DSP_ALL_INT_SEOF3_INT) || \ + ((type) == GLB_DSP_ALL_INT_DVP2BUS_INT_0) || \ + ((type) == GLB_DSP_ALL_INT_DVP2BUS_INT_1) || \ + ((type) == GLB_DSP_ALL_INT_DVP2BUS_INT_2) || \ + ((type) == GLB_DSP_ALL_INT_DVP2BUS_INT_3) || \ + ((type) == GLB_DSP_ALL_INT_H264_BS_IRQ) || \ + ((type) == GLB_DSP_ALL_INT_H264_FRAME_IRQ) || \ + ((type) == GLB_DSP_ALL_INT_H264_SEQ_DONE_INT) || \ + ((type) == GLB_DSP_ALL_INT_MJPEG_INT) || \ + ((type) == GLB_DSP_ALL_INT_H264_S_BS_IRQ) || \ + ((type) == GLB_DSP_ALL_INT_H264_S_FRAME_IRQ) || \ + ((type) == GLB_DSP_ALL_INT_H264_S_SEQ_DONE_INT) || \ + ((type) == GLB_DSP_ALL_INT_DMA_INTR_0) || \ + ((type) == GLB_DSP_ALL_INT_DMA_INTR_1) || \ + ((type) == GLB_DSP_ALL_INT_DMA_INTR_2) || \ + ((type) == GLB_DSP_ALL_INT_DMA_INTR_3) || \ + ((type) == GLB_DSP_ALL_INT_DMA_INTR_4) || \ + ((type) == GLB_DSP_ALL_INT_DMA_INTR_5) || \ + ((type) == GLB_DSP_ALL_INT_DMA_INTR_6) || \ + ((type) == GLB_DSP_ALL_INT_DMA_INTR_7) || \ + ((type) == GLB_DSP_ALL_INT_RSV32) || \ + ((type) == GLB_DSP_ALL_INT_RSV33) || \ + ((type) == GLB_DSP_ALL_INT_RSV34) || \ + ((type) == GLB_DSP_ALL_INT_RSV35) || \ + ((type) == GLB_DSP_ALL_INT_RSV36) || \ + ((type) == GLB_DSP_ALL_INT_MIPI_CSI_INT) || \ + ((type) == GLB_DSP_ALL_INT_IPC2_AP2NP_IRQ) || \ + ((type) == GLB_DSP_ALL_INT_RSV39) || \ + ((type) == GLB_DSP_ALL_INT_MJDEC_INT) || \ + ((type) == GLB_DSP_ALL_INT_DVP2BUS_IN_4) || \ + ((type) == GLB_DSP_ALL_INT_DVP2BUS_IN_5) || \ + ((type) == GLB_DSP_ALL_INT_DVP2BUS_IN_6) || \ + ((type) == GLB_DSP_ALL_INT_DVP2BUS_IN_7) || \ + ((type) == GLB_DSP_ALL_INT_DMA2D_INT_0) || \ + ((type) == GLB_DSP_ALL_INT_DMA2D_INT_1) || \ + ((type) == GLB_DSP_ALL_INT_DP_SOEF0_INT) || \ + ((type) == GLB_DSP_ALL_INT_RSV48) || \ + ((type) == GLB_DSP_ALL_INT_RSV49) || \ + ((type) == GLB_DSP_ALL_INT_RSV50) || \ + ((type) == GLB_DSP_ALL_INT_RSV51) || \ + ((type) == GLB_DSP_ALL_INT_OSDDP_INT) || \ + ((type) == GLB_DSP_ALL_INT_DBI_INT) || \ + ((type) == GLB_DSP_ALL_INT_DSP2_WDR_INT) || \ + ((type) == GLB_DSP_ALL_INT_OSDA_INT) || \ + ((type) == GLB_DSP_ALL_INT_OSDB_INT) || \ + ((type) == GLB_DSP_ALL_INT_OSD_PB_INT) || \ + ((type) == GLB_DSP_ALL_INT_DSP2_AWB2_INT) || \ + ((type) == GLB_DSP_ALL_INT_MIPI_DSI_INT) || \ + ((type) == GLB_DSP_ALL_INT_DSP2_AE_HIST_INT) || \ + ((type) == GLB_DSP_ALL_INT_MM_TIMER_IRQ2) || \ + ((type) == GLB_DSP_ALL_INT_MM_TIMER_IRQ3) || \ + ((type) == GLB_DSP_ALL_INT_MM_WDT_IRQ)) + +/** @defgroup GLB_MCU_ALL_INT_TYPE + * @{ + */ +#define IS_GLB_MCU_ALL_INT_TYPE(type) (((type) == GLB_MCU_ALL_INT_BMX_ERR_INT) || \ + ((type) == GLB_MCU_ALL_INT_BMX_TIMEOUT_INT_MCU_TIMEOUT_INT) || \ + ((type) == GLB_MCU_ALL_INT_IPC0_NP2AP_IRQ) || \ + ((type) == GLB_MCU_ALL_INT_IPC0_AP2NP_IRQ) || \ + ((type) == GLB_MCU_ALL_INT_AUDIO_INT) || \ + ((type) == GLB_MCU_ALL_INT_RF_TOP_INT_0) || \ + ((type) == GLB_MCU_ALL_INT_RF_TOP_INT_1) || \ + ((type) == GLB_MCU_ALL_INT_LZ4_INT) || \ + ((type) == GLB_MCU_ALL_INT_RSV8) || \ + ((type) == GLB_MCU_ALL_INT_SEC_ENG_ID0_GMAC_INT) || \ + ((type) == GLB_MCU_ALL_INT_SEC_ENG_ID0_CDET_INT) || \ + ((type) == GLB_MCU_ALL_INT_SEC_ENG_ID0_PKA_INT) || \ + ((type) == GLB_MCU_ALL_INT_SEC_ENG_ID0_TRNG_INT) || \ + ((type) == GLB_MCU_ALL_INT_SEC_ENG_ID0_AES_INT) || \ + ((type) == GLB_MCU_ALL_INT_SEC_ENG_ID0_SHA_INT) || \ + ((type) == GLB_MCU_ALL_INT_DMA_INTR_ALL) || \ + ((type) == GLB_MCU_ALL_INT_DMA2_INTR_ALL) || \ + ((type) == GLB_MCU_ALL_INT_SDH_MMC1_INT_SDH2PMU_WAKEUP_INT1) || \ + ((type) == GLB_MCU_ALL_INT_MM_IRQ_ALL) || \ + ((type) == GLB_MCU_ALL_INT_IRTX_INT) || \ + ((type) == GLB_MCU_ALL_INT_IRRX_INT) || \ + ((type) == GLB_MCU_ALL_INT_USB_INT) || \ + ((type) == GLB_MCU_ALL_INT_AUPDM_INT) || \ + ((type) == GLB_MCU_ALL_INT_SF_CTRL_ID0_INT) || \ + ((type) == GLB_MCU_ALL_INT_EMAC_INT) || \ + ((type) == GLB_MCU_ALL_INT_GPADC_DMA_INT) || \ + ((type) == GLB_MCU_ALL_INT_EFUSE_INT) || \ + ((type) == GLB_MCU_ALL_INT_SPI_0_INT) || \ + ((type) == GLB_MCU_ALL_INT_UART_IRQ) || \ + ((type) == GLB_MCU_ALL_INT_UART1_IRQ) || \ + ((type) == GLB_MCU_ALL_INT_UART2_IRQ) || \ + ((type) == GLB_MCU_ALL_INT_GPIO_DMA_INT) || \ + ((type) == GLB_MCU_ALL_INT_I2C_0_INT) || \ + ((type) == GLB_MCU_ALL_INT_PWM_INT) || \ + ((type) == GLB_MCU_ALL_INT_IPC1_NP2AP_IRQ) || \ + ((type) == GLB_MCU_ALL_INT_IPC1_AP2NP_IRQ) || \ + ((type) == GLB_MCU_ALL_INT_TIMER0_2_IRQ) || \ + ((type) == GLB_MCU_ALL_INT_TIMER0_3_IRQ) || \ + ((type) == GLB_MCU_ALL_INT_WDT0_IRQ) || \ + ((type) == GLB_MCU_ALL_INT_I2C_1_INT) || \ + ((type) == GLB_MCU_ALL_INT_I2S0_INT) || \ + ((type) == GLB_MCU_ALL_INT_RSV41) || \ + ((type) == GLB_MCU_ALL_INT_RSV42) || \ + ((type) == GLB_MCU_ALL_INT_ANA_OCP_OUT_TO_CPU_IRQ) || \ + ((type) == GLB_MCU_ALL_INT_GPIO_IRQ) || \ + ((type) == GLB_MCU_ALL_INT_DM_IRQ) || \ + ((type) == GLB_MCU_ALL_INT_BT_IRQ) || \ + ((type) == GLB_MCU_ALL_INT_M154_REQ_ENH_ACK_INT) || \ + ((type) == GLB_MCU_ALL_INT_M154_INT) || \ + ((type) == GLB_MCU_ALL_INT_M154_AES_INT) || \ + ((type) == GLB_MCU_ALL_INT_PDS_INT) || \ + ((type) == GLB_MCU_ALL_INT_HBN_IRQ_OUT_0) || \ + ((type) == GLB_MCU_ALL_INT_HBN_IRQ_OUT_1) || \ + ((type) == GLB_MCU_ALL_INT_BOR_OUT) || \ + ((type) == GLB_MCU_ALL_INT_WIFI_TO_CPU_IRQ_N) || \ + ((type) == GLB_MCU_ALL_INT_BZ_PHY_INT) || \ + ((type) == GLB_MCU_ALL_INT_BLE_INT) || \ + ((type) == GLB_MCU_ALL_INT_MAC_INT_TX_RX_TIMER) || \ + ((type) == GLB_MCU_ALL_INT_MAC_INT_TX_RX_MISC) || \ + ((type) == GLB_MCU_ALL_INT_MAC_INT_RX_TRIGGER) || \ + ((type) == GLB_MCU_ALL_INT_MAC_INT_TX_TRIGGER) || \ + ((type) == GLB_MCU_ALL_INT_MAC_INT_GEN) || \ + ((type) == GLB_MCU_ALL_INT_MAC_INT_PROT_TRIGGER) || \ + ((type) == GLB_MCU_ALL_INT_WIFI_IPC)) + +/** @defgroup GLB_LP_ALL_INT_TYPE + * @{ + */ +#define IS_GLB_LP_ALL_INT_TYPE(type) (((type) == GLB_LP_ALL_INT_BMX_ERR_INT) || \ + ((type) == GLB_LP_ALL_INT_BMX_TIMEOUT_INT_MCU_TIMEOUT_INT) || \ + ((type) == GLB_LP_ALL_INT_IPC0_NP2AP_IRQ) || \ + ((type) == GLB_LP_ALL_INT_IPC0_AP2NP_IRQ) || \ + ((type) == GLB_LP_ALL_INT_AUDIO_INT) || \ + ((type) == GLB_LP_ALL_INT_RF_TOP_INT_0) || \ + ((type) == GLB_LP_ALL_INT_RF_TOP_INT_1) || \ + ((type) == GLB_LP_ALL_INT_LZ4_INT) || \ + ((type) == GLB_LP_ALL_INT_RSV8) || \ + ((type) == GLB_LP_ALL_INT_SEC_ENG_ID0_GMAC_INT) || \ + ((type) == GLB_LP_ALL_INT_SEC_ENG_ID0_CDET_INT) || \ + ((type) == GLB_LP_ALL_INT_SEC_ENG_ID0_PKA_INT) || \ + ((type) == GLB_LP_ALL_INT_SEC_ENG_ID0_TRNG_INT) || \ + ((type) == GLB_LP_ALL_INT_SEC_ENG_ID0_AES_INT) || \ + ((type) == GLB_LP_ALL_INT_SEC_ENG_ID0_SHA_INT) || \ + ((type) == GLB_LP_ALL_INT_DMA_INTR_ALL) || \ + ((type) == GLB_LP_ALL_INT_DMA2_INTR_ALL) || \ + ((type) == GLB_LP_ALL_INT_SDH_MMC1_INT_SDH2PMU_WAKEUP_INT1) || \ + ((type) == GLB_LP_ALL_INT_MM_IRQ_ALL) || \ + ((type) == GLB_LP_ALL_INT_IRTX_INT) || \ + ((type) == GLB_LP_ALL_INT_IRRX_INT) || \ + ((type) == GLB_LP_ALL_INT_USB_INT) || \ + ((type) == GLB_LP_ALL_INT_AUPDM_INT) || \ + ((type) == GLB_LP_ALL_INT_SF_CTRL_ID0_INT) || \ + ((type) == GLB_LP_ALL_INT_EMAC_INT) || \ + ((type) == GLB_LP_ALL_INT_GPADC_DMA_INT) || \ + ((type) == GLB_LP_ALL_INT_EFUSE_INT) || \ + ((type) == GLB_LP_ALL_INT_SPI_0_INT) || \ + ((type) == GLB_LP_ALL_INT_UART_IRQ) || \ + ((type) == GLB_LP_ALL_INT_UART1_IRQ) || \ + ((type) == GLB_LP_ALL_INT_UART2_IRQ) || \ + ((type) == GLB_LP_ALL_INT_GPIO_DMA_INT) || \ + ((type) == GLB_LP_ALL_INT_I2C_0_INT) || \ + ((type) == GLB_LP_ALL_INT_PWM_INT) || \ + ((type) == GLB_LP_ALL_INT_IPC1_NP2AP_IRQ) || \ + ((type) == GLB_LP_ALL_INT_IPC1_AP2NP_IRQ) || \ + ((type) == GLB_LP_ALL_INT_TIMER0_2_IRQ) || \ + ((type) == GLB_LP_ALL_INT_TIMER0_3_IRQ) || \ + ((type) == GLB_LP_ALL_INT_WDT0_IRQ) || \ + ((type) == GLB_LP_ALL_INT_I2C_1_INT) || \ + ((type) == GLB_LP_ALL_INT_I2S0_INT) || \ + ((type) == GLB_LP_ALL_INT_RSV41) || \ + ((type) == GLB_LP_ALL_INT_RSV42) || \ + ((type) == GLB_LP_ALL_INT_ANA_OCP_OUT_TO_CPU_IRQ) || \ + ((type) == GLB_LP_ALL_INT_GPIO_IRQ) || \ + ((type) == GLB_LP_ALL_INT_DM_IRQ) || \ + ((type) == GLB_LP_ALL_INT_BT_IRQ) || \ + ((type) == GLB_LP_ALL_INT_M154_REQ_ENH_ACK_INT) || \ + ((type) == GLB_LP_ALL_INT_M154_INT) || \ + ((type) == GLB_LP_ALL_INT_M154_AES_INT) || \ + ((type) == GLB_LP_ALL_INT_PDS_INT) || \ + ((type) == GLB_LP_ALL_INT_HBN_IRQ_OUT_0) || \ + ((type) == GLB_LP_ALL_INT_HBN_IRQ_OUT_1) || \ + ((type) == GLB_LP_ALL_INT_BOR_OUT) || \ + ((type) == GLB_LP_ALL_INT_WIFI_TO_CPU_IRQ_N) || \ + ((type) == GLB_LP_ALL_INT_BZ_PHY_INT) || \ + ((type) == GLB_LP_ALL_INT_BLE_INT) || \ + ((type) == GLB_LP_ALL_INT_MAC_INT_TX_RX_TIMER) || \ + ((type) == GLB_LP_ALL_INT_MAC_INT_TX_RX_MISC) || \ + ((type) == GLB_LP_ALL_INT_MAC_INT_RX_TRIGGER) || \ + ((type) == GLB_LP_ALL_INT_MAC_INT_TX_TRIGGER) || \ + ((type) == GLB_LP_ALL_INT_MAC_INT_GEN) || \ + ((type) == GLB_LP_ALL_INT_MAC_INT_PROT_TRIGGER) || \ + ((type) == GLB_LP_ALL_INT_WIFI_IPC)) + +/** @defgroup GLB_DSP_MUXPLL_320M_CLK_SEL_TYPE + * @{ + */ +#define IS_GLB_DSP_MUXPLL_320M_CLK_SEL_TYPE(type) (((type) == GLB_DSP_MUXPLL_SEL_WIFIPLL_320M) || \ + ((type) == GLB_DSP_MUXPLL_SEL_AUPLL_DIV1)) + +/** @defgroup GLB_DSP_MUXPLL_240M_CLK_SEL_TYPE + * @{ + */ +#define IS_GLB_DSP_MUXPLL_240M_CLK_SEL_TYPE(type) (((type) == GLB_DSP_MUXPLL_SEL_WIFIPLL_240M) || \ + ((type) == GLB_DSP_MUXPLL_SEL_AUPLL_DIV2)) + +/** @defgroup GLB_DSP_MUXPLL_160M_CLK_SEL_TYPE + * @{ + */ +#define IS_GLB_DSP_MUXPLL_160M_CLK_SEL_TYPE(type) (((type) == GLB_DSP_MUXPLL_SEL_WIFIPLL_160M) || \ + ((type) == GLB_DSP_MUXPLL_SEL_CPUPLL_160M)) + +/** @defgroup GLB_MCU_MUXPLL_160M_CLK_SEL_TYPE + * @{ + */ +#define IS_GLB_MCU_MUXPLL_160M_CLK_SEL_TYPE(type) (((type) == GLB_MCU_MUXPLL_SEL_WIFIPLL_160M) || \ + ((type) == GLB_MCU_MUXPLL_SEL_TOP_CPUPLL_160M) || \ + ((type) == GLB_MCU_MUXPLL_SEL_TOP_AUPLL_DIV2) || \ + ((type) == GLB_MCU_MUXPLL_SEL_AUPLL_DIV2P5)) + +/** @defgroup GLB_MCU_MUXPLL_80M_CLK_SEL_TYPE + * @{ + */ +#define IS_GLB_MCU_MUXPLL_80M_CLK_SEL_TYPE(type) (((type) == GLB_MCU_MUXPLL_SEL_WIFIPLL_80M) || \ + ((type) == GLB_MCU_MUXPLL_SEL_TOP_CPUPLL_80M) || \ + ((type) == GLB_MCU_MUXPLL_SEL_AUPLL_DIV5) || \ + ((type) == GLB_MCU_MUXPLL_SEL_AUPLL_DIV6)) + +/** @defgroup GLB_PLL_CGEN_TYPE + * @{ + */ +#define IS_GLB_PLL_CGEN_TYPE(type) (((type) == GLB_PLL_CGEN_MM_WIFIPLL_160M) || \ + ((type) == GLB_PLL_CGEN_MM_WIFIPLL_240M) || \ + ((type) == GLB_PLL_CGEN_MM_WIFIPLL_320M) || \ + ((type) == GLB_PLL_CGEN_MM_AUPLL_DIV1) || \ + ((type) == GLB_PLL_CGEN_MM_AUPLL_DIV2) || \ + ((type) == GLB_PLL_CGEN_EMI_CPUPLL_400M) || \ + ((type) == GLB_PLL_CGEN_EMI_CPUPLL_200M) || \ + ((type) == GLB_PLL_CGEN_EMI_WIFIPLL_320M) || \ + ((type) == GLB_PLL_CGEN_EMI_AUPLL_DIV1) || \ + ((type) == GLB_PLL_CGEN_TOP_CPUPLL_80M) || \ + ((type) == GLB_PLL_CGEN_TOP_CPUPLL_100M) || \ + ((type) == GLB_PLL_CGEN_TOP_CPUPLL_160M) || \ + ((type) == GLB_PLL_CGEN_TOP_CPUPLL_400M) || \ + ((type) == GLB_PLL_CGEN_TOP_WIFIPLL_240M) || \ + ((type) == GLB_PLL_CGEN_TOP_WIFIPLL_320M) || \ + ((type) == GLB_PLL_CGEN_TOP_AUPLL_DIV2) || \ + ((type) == GLB_PLL_CGEN_TOP_AUPLL_DIV1)) + +/** @defgroup GLB_MCU_SYS_CLK_TYPE + * @{ + */ +#define IS_GLB_MCU_SYS_CLK_TYPE(type) (((type) == GLB_MCU_SYS_CLK_RC32M) || \ + ((type) == GLB_MCU_SYS_CLK_XTAL) || \ + ((type) == GLB_MCU_SYS_CLK_CPUPLL_400M) || \ + ((type) == GLB_MCU_SYS_CLK_WIFIPLL_240M) || \ + ((type) == GLB_MCU_SYS_CLK_WIFIPLL_320M)) + +/** @defgroup GLB_DSP_SYS_CLK_TYPE + * @{ + */ +#define IS_GLB_DSP_SYS_CLK_TYPE(type) (((type) == GLB_DSP_SYS_CLK_RC32M) || \ + ((type) == GLB_DSP_SYS_CLK_XTAL) || \ + ((type) == GLB_DSP_SYS_CLK_MM_WIFIPLL_240M) || \ + ((type) == GLB_DSP_SYS_CLK_MM_WIFIPLL_320M) || \ + ((type) == GLB_DSP_SYS_CLK_CPUPLL_400M)) + +/** @defgroup GLB_DSP_SYS_PBCLK_TYPE + * @{ + */ +#define IS_GLB_DSP_SYS_PBCLK_TYPE(type) (((type) == GLB_DSP_SYS_PBCLK_RC32M) || \ + ((type) == GLB_DSP_SYS_PBCLK_XTAL) || \ + ((type) == GLB_DSP_SYS_PBCLK_MM_WIFIPLL_160M) || \ + ((type) == GLB_DSP_SYS_PBCLK_CPUPLL_160M) || \ + ((type) == GLB_DSP_SYS_PBCLK_MM_WIFIPLL_240M)) + +/** @defgroup GLB_PLL_REF_CLK_TYPE + * @{ + */ +#define IS_GLB_PLL_REF_CLK_TYPE(type) (((type) == GLB_PLL_REFCLK_XTAL) || \ + ((type) == GLB_PLL_REFCLK_RC32M)) + +/** @defgroup GLB_WIFIPLL_REF_CLK_Type + * @{ + */ +#define IS_GLB_WIFIPLL_REF_CLK_TYPE(type) (((type) == GLB_WIFIPLL_REF_XTAL_SOC_CLK) || \ + ((type) == GLB_WIFIPLL_REF_XTAL_CLK) || \ + ((type) == GLB_WIFIPLL_REF_XTAL_LO_CLK) || \ + ((type) == GLB_WIFIPLL_REF_RC32M_CLK)) + +/** @defgroup GLB_AUPLL_REF_CLK_Type + * @{ + */ +#define IS_GLB_AUPLL_REF_CLK_TYPE(type) (((type) == GLB_AUPLL_REF_XTAL_SOC_CLK) || \ + ((type) == GLB_AUPLL_REF_RC32M_CLK)) + +/** @defgroup GLB_CPUPLL_REF_CLK_Type + * @{ + */ +#define IS_GLB_CPUPLL_REF_CLK_TYPE(type) (((type) == GLB_CPUPLL_REF_XTAL_SOC_CLK) || \ + ((type) == GLB_CPUPLL_REF_RC32M_CLK)) + +/** @defgroup GLB_MIPIPLL_REF_CLK_Type + * @{ + */ +#define IS_GLB_MIPIPLL_REF_CLK_TYPE(type) (((type) == GLB_MIPIPLL_REF_XTAL_SOC_CLK) || \ + ((type) == GLB_MIPIPLL_REF_RC32M_CLK)) + +/** @defgroup GLB_UHSPLL_REF_CLK_Type + * @{ + */ +#define IS_GLB_UHSPLL_REF_CLK_TYPE(type) (((type) == GLB_UHSPLL_REF_XTAL_SOC_CLK) || \ + ((type) == GLB_UHSPLL_REF_RC32M_CLK)) + +/** @defgroup GLB_CAM_CLK_TYPE + * @{ + */ +#define IS_GLB_CAM_CLK_TYPE(type) (((type) == GLB_CAM_CLK_XCLK) || \ + ((type) == GLB_CAM_CLK_WIFIPLL_96M) || \ + ((type) == GLB_CAM_CLK_CPUPLL_100M)) + +/** @defgroup GLB_SDH_CLK_TYPE + * @{ + */ +#define IS_GLB_SDH_CLK_TYPE(type) (((type) == GLB_SDH_CLK_WIFIPLL_96M) || \ + ((type) == GLB_SDH_CLK_CPUPLL_100M)) + +/** @defgroup GLB_GLB_UART_SIG_SWAP_SET_TYPE + * @{ + */ +#define IS_GLB_UART_SIG_SWAP_GRP_TYPE(type) (((type) == GLB_UART_SIG_SWAP_GRP_GPIO0_GPIO11) || \ + ((type) == GLB_UART_SIG_SWAP_GRP_GPIO12_GPIO23) || \ + ((type) == GLB_UART_SIG_SWAP_GRP_GPIO24_GPIO35) || \ + ((type) == GLB_UART_SIG_SWAP_GRP_GPIO36_GPIO45)) + +/** @defgroup GLB_I2S_OUT_REF_CLK_TYPE + * @{ + */ +#define IS_GLB_I2S_OUT_REF_CLK_TYPE(type) (((type) == GLB_I2S_OUT_REF_CLK_NONE) || \ + ((type) == GLB_I2S_OUT_REF_CLK_SRC)) + +/** @defgroup GLB_DMA_CLK_ID_TYPE + * @{ + */ +#define IS_GLB_DMA_CLK_ID_TYPE(type) (((type) == GLB_DMA0_CLK_CH0) || \ + ((type) == GLB_DMA0_CLK_CH1) || \ + ((type) == GLB_DMA0_CLK_CH2) || \ + ((type) == GLB_DMA0_CLK_CH3) || \ + ((type) == GLB_DMA0_CLK_CH4) || \ + ((type) == GLB_DMA0_CLK_CH5) || \ + ((type) == GLB_DMA0_CLK_CH6) || \ + ((type) == GLB_DMA0_CLK_CH7) || \ + ((type) == GLB_DMA1_CLK_CH0) || \ + ((type) == GLB_DMA1_CLK_CH1) || \ + ((type) == GLB_DMA1_CLK_CH2) || \ + ((type) == GLB_DMA1_CLK_CH3)) + +/** @defgroup GLB_PERI_DMA_TYPE + * @{ + */ +#define IS_GLB_PERI_DMA_TYPE(type) (((type) == GLB_PERI_DMA_UART0_RX) || \ + ((type) == GLB_PERI_DMA_UART0_TX) || \ + ((type) == GLB_PERI_DMA_UART1_RX) || \ + ((type) == GLB_PERI_DMA_UART1_TX) || \ + ((type) == GLB_PERI_DMA_UART2_RX) || \ + ((type) == GLB_PERI_DMA_UART2_TX) || \ + ((type) == GLB_PERI_DMA_I2C_0_RX) || \ + ((type) == GLB_PERI_DMA_I2C_0_TX) || \ + ((type) == GLB_PERI_DMA_IRTX_TX) || \ + ((type) == GLB_PERI_DMA_GPIO_TX) || \ + ((type) == GLB_PERI_DMA_SPI_RX) || \ + ((type) == GLB_PERI_DMA_SPI_TX) || \ + ((type) == GLB_PERI_DMA_AUDIO_RX) || \ + ((type) == GLB_PERI_DMA_AUDIO_TX) || \ + ((type) == GLB_PERI_DMA_I2C_1_RX) || \ + ((type) == GLB_PERI_DMA_I2C_1_TX) || \ + ((type) == GLB_PERI_DMA_I2S_0_RX) || \ + ((type) == GLB_PERI_DMA_I2S_0_TX) || \ + ((type) == GLB_PERI_DMA_PDM_RX) || \ + ((type) == GLB_PERI_DMA_PADC) || \ + ((type) == GLB_PERI_DMA_GAUGE) || \ + ((type) == GLB_PERI_DMA_GPADC) || \ + ((type) == GLB_PERI_DMA_GPDAC_TX)) + +/** @defgroup GLB_PERI_DMA_CN_SEL_TYPE + * @{ + */ +#define IS_GLB_PERI_DMA_CN_SEL_TYPE(type) (((type) == GLB_PERI_DMA_CN_SEL_DMA0) || \ + ((type) == GLB_PERI_DMA_CN_SEL_DMA1)) + +/** @defgroup GLB_IR_CLK_SRC_TYPE + * @{ + */ +#define IS_GLB_IR_CLK_SRC_TYPE(type) (((type) == GLB_IR_CLK_SRC_XCLK)) + +/** @defgroup GLB_SFLASH_CLK_TYPE + * @{ + */ +#define IS_GLB_SFLASH_CLK_TYPE(type) (((type) == GLB_SFLASH_CLK_120M_WIFIPLL) || \ + ((type) == GLB_SFLASH_CLK_XTAL) || \ + ((type) == GLB_SFLASH_CLK_100M_CPUPLL) || \ + ((type) == GLB_SFLASH_CLK_80M_MUXPLL) || \ + ((type) == GLB_SFLASH_CLK_BCLK) || \ + ((type) == GLB_SFLASH_CLK_96M_WIFIPLL)) + +/** @defgroup GLB_I2C_CLK_TYPE + * @{ + */ +#define IS_GLB_I2C_CLK_TYPE(type) (((type) == GLB_I2C_CLK_BCLK) || \ + ((type) == GLB_I2C_CLK_XCLK)) + +/** @defgroup GLB_SPI_CLK_TYPE + * @{ + */ +#define IS_GLB_SPI_CLK_TYPE(type) (((type) == GLB_SPI_CLK_PLL160M) || \ + ((type) == GLB_SPI_CLK_XCLK)) + +/** @defgroup GLB_PWM1_IO_SEL_TYPE + * @{ + */ +#define IS_GLB_PWM1_IO_SEL_TYPE(type) (((type) == GLB_PWM1_IO_SINGLE_END) || \ + ((type) == GLB_PWM1_IO_DIFF_END)) + +/** @defgroup GLB_PWM2_IO_SEL_TYPE + * @{ + */ +#define IS_GLB_PWM2_IO_SEL_TYPE(type) (((type) == GLB_PWM2_IO_SINGLE_END) || \ + ((type) == GLB_PWM2_IO_SINGLE_END_BLDC)) + +/** @defgroup GLB_PDM_IO_SEL_TYPE + * @{ + */ +#define IS_GLB_PDM_IO_SEL_TYPE(type) (((type) == GLB_PDM_IO_SEL_AUDIO_TOP) || \ + ((type) == GLB_PDM_IO_SEL_AUPDM_TOP)) + +/** @defgroup GLB_SPI_PAD_ACT_AS_TYPE + * @{ + */ +#define IS_GLB_SPI_PAD_ACT_AS_TYPE(type) (((type) == GLB_SPI_PAD_ACT_AS_SLAVE) || \ + ((type) == GLB_SPI_PAD_ACT_AS_MASTER)) + +/** @defgroup GLB_AHB_SW_TYPE + * @{ + */ +#define IS_GLB_AHB_MCU_SW_TYPE(type) (((type) == GLB_AHB_MCU_SW_RSV0) || \ + ((type) == GLB_AHB_MCU_SW_RSV1) || \ + ((type) == GLB_AHB_MCU_SW_WIFI) || \ + ((type) == GLB_AHB_MCU_SW_BTDM) || \ + ((type) == GLB_AHB_MCU_SW_ZIGBEE) || \ + ((type) == GLB_AHB_MCU_SW_BLE2) || \ + ((type) == GLB_AHB_MCU_SW_ZIGBEE2) || \ + ((type) == GLB_AHB_MCU_SW_EMI_MISC) || \ + ((type) == GLB_AHB_MCU_SW_PSRAM0_CTRL) || \ + ((type) == GLB_AHB_MCU_SW_PSRAM1_CTRL) || \ + ((type) == GLB_AHB_MCU_SW_USB) || \ + ((type) == GLB_AHB_MCU_SW_MIX2) || \ + ((type) == GLB_AHB_MCU_SW_AUDIO) || \ + ((type) == GLB_AHB_MCU_SW_SDH) || \ + ((type) == GLB_AHB_MCU_SW_EMAC) || \ + ((type) == GLB_AHB_MCU_SW_DMA2) || \ + ((type) == GLB_AHB_MCU_SW_GLB) || \ + ((type) == GLB_AHB_MCU_SW_MIX) || \ + ((type) == GLB_AHB_MCU_SW_GPIP) || \ + ((type) == GLB_AHB_MCU_SW_SEC_DBG) || \ + ((type) == GLB_AHB_MCU_SW_SEC_ENG) || \ + ((type) == GLB_AHB_MCU_SW_TZ1) || \ + ((type) == GLB_AHB_MCU_SW_TZ2) || \ + ((type) == GLB_AHB_MCU_SW_EFUSE) || \ + ((type) == GLB_AHB_MCU_SW_CCI) || \ + ((type) == GLB_AHB_MCU_SW_L1C) || \ + ((type) == GLB_AHB_MCU_SW_RSV42) || \ + ((type) == GLB_AHB_MCU_SW_SF) || \ + ((type) == GLB_AHB_MCU_SW_DMA) || \ + ((type) == GLB_AHB_MCU_SW_SDU) || \ + ((type) == GLB_AHB_MCU_SW_PDS) || \ + ((type) == GLB_AHB_MCU_SW_RSV47) || \ + ((type) == GLB_AHB_MCU_SW_UART0) || \ + ((type) == GLB_AHB_MCU_SW_UART1) || \ + ((type) == GLB_AHB_MCU_SW_SPI) || \ + ((type) == GLB_AHB_MCU_SW_I2C) || \ + ((type) == GLB_AHB_MCU_SW_PWM) || \ + ((type) == GLB_AHB_MCU_SW_TIMER) || \ + ((type) == GLB_AHB_MCU_SW_IR_REMOTE) || \ + ((type) == GLB_AHB_MCU_SW_CHECKSUM) || \ + ((type) == GLB_AHB_MCU_SW_QDEC) || \ + ((type) == GLB_AHB_MCU_SW_KYS) || \ + ((type) == GLB_AHB_MCU_SW_UART2) || \ + ((type) == GLB_AHB_MCU_SW_RSV59) || \ + ((type) == GLB_AHB_MCU_SW_RSV60) || \ + ((type) == GLB_AHB_MCU_SW_RSV61) || \ + ((type) == GLB_AHB_MCU_SW_RSV62) || \ + ((type) == GLB_AHB_MCU_SW_RSV63) || \ + ((type) == GLB_AHB_MCU_SW_PWRON_RST) || \ + ((type) == GLB_AHB_MCU_SW_CPU_RESET) || \ + ((type) == GLB_AHB_MCU_SW_SYS_RESET) || \ + ((type) == GLB_AHB_MCU_SW_PICO_RESET) || \ + ((type) == GLB_AHB_MCU_SW_CPU2_RESET) || \ + ((type) == GLB_AHB_MCU_SW_CHIP_RESET) || \ + ((type) == GLB_AHB_MCU_SW_WL_WDT_RESET_MM_EN) || \ + ((type) == GLB_AHB_MCU_SW_MMWDT2WL_RST_MSK)) + +/** @defgroup GLB_AHB_DSP_SW_TYPE + * @{ + */ +#define IS_GLB_AHB_DSP_SW_TYPE(type) (((type) == GLB_AHB_DSP_SW_REG_CTRL_SYS_RESET) || \ + ((type) == GLB_AHB_DSP_SW_REG_CTRL_PWRON_RST) || \ + ((type) == GLB_AHB_DSP_SW_REG_CTRL_MMCPU0_RESET) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_MM_MISC) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_DMA) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_UART0) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_I2C0) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_I2C1) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_IPC) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_DMA2D) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_SPI) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_TIMER) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_I2S0) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_I2S1) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_PDM0) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_PDM1) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_PUHS) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_DSP2_MISC) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_DSP2_MAIN) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_DSP2_TSRC) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_DP_TSRC) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_NR3D_CTRL) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_DVP2BUSA) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_DVP2BUSB) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_DVP2BUSC) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_DVP2BUSD) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_MIPI) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_DSP2_REG) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_DVP2BUSE) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_DVP2BUSF) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_DVP2BUSG) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_DVP2BUSH) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_CODEC_MISC) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_MJPEG) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_H264) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_MJPEG_DEC) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_CNN) || \ + ((type) == GLB_AHB_DSP_SW_SWRST_VRAM) || \ + ((type) == GLB_AHB_DSP_SW_RG_IS_RST_N)) + +/** @defgroup GLB DISRST_TYPE + * @{ + */ +#define IS_GLB_DISRST_TYPE(type) (((type) == GLB_DISRST_GPIP) || \ + ((type) == GLB_DISRST_SEC_ENG) || \ + ((type) == GLB_DISRST_CCI) || \ + ((type) == GLB_DISRST_SF) || \ + ((type) == GLB_DISRST_UART0) || \ + ((type) == GLB_DISRST_UART1) || \ + ((type) == GLB_DISRST_SPI) || \ + ((type) == GLB_DISRST_I2C0) || \ + ((type) == GLB_DISRST_PWM) || \ + ((type) == GLB_DISRST_TIMER) || \ + ((type) == GLB_DISRST_IR_REMOTE) || \ + ((type) == GLB_DISRST_CHECKSUM) || \ + ((type) == GLB_DISRST_IPC) || \ + ((type) == GLB_DISRST_I2C1) || \ + ((type) == GLB_DISRST_UART2)) + +/** @defgroup GLB_PKA_CLK_TYPE + * @{ + */ +#define IS_GLB_PKA_CLK_TYPE(type) (((type) == GLB_PKA_CLK_MCU_BCLK) || \ + ((type) == GLB_PKA_CLK_MCU_MUXPLL_160M)) + +/** @defgroup GLB_MCU_SW_SYSTEM_TYPE + * @{ + */ +#define IS_GLB_MCU_SW_SYSTEM_TYPE(type) (((type) == GLB_MCU_SW_SYSTEM_CTRL_MCU) || \ + ((type) == GLB_MCU_SW_SYSTEM_CTRL_LP)) + +/** @defgroup BMX_ARB_TYPE + * @{ + */ +#define IS_BMX_ARB_TYPE(type) (((type) == BMX_ARB_ROUND_ROBIN) || \ + ((type) == BMX_ARB_FIX)) + +/** @defgroup BMX_LATCH_TYPE + * @{ + */ +#define IS_BMX_LATCH_TYPE(type) (((type) == BMX_LATCH_FIRST_ERROR) || \ + ((type) == BMX_LATCH_LAST_ERROR)) + +/** @defgroup BMX_BUS_ERR_TYPE + * @{ + */ +#define IS_BMX_BUS_ERR_TYPE(type) (((type) == BMX_BUS_ERR_TRUSTZONE_DECODE) || \ + ((type) == BMX_BUS_ERR_ADDR_DECODE)) + +/** @defgroup BMX_ERR_INT_TYPE + * @{ + */ +#define IS_BMX_ERR_INT_TYPE(type) (((type) == BMX_ERR_INT_ERR) || \ + ((type) == BMX_ERR_INT_ALL)) + +/** @defgroup BMX_TO_INT_TYPE + * @{ + */ +#define IS_BMX_TO_INT_TYPE(type) (((type) == BMX_TO_INT_TIMEOUT) || \ + ((type) == BMX_TO_INT_ALL)) + +/** @defgroup GLB_ETH_REF_CLK_OUT_TYPE + * @{ + */ +#define IS_GLB_ETH_REF_CLK_OUT_TYPE(type) (((type) == GLB_ETH_REF_CLK_OUT_OUTSIDE_50M) || \ + ((type) == GLB_ETH_REF_CLK_OUT_INSIDE_50M)) + +/** @defgroup GLB_EM_TYPE + * @{ + */ +#define IS_GLB_EM_TYPE(type) (((type) == GLB_WRAM160KB_EM0KB) || \ + ((type) == GLB_WRAM144KB_EM16KB) || \ + ((type) == GLB_WRAM128KB_EM32KB) || \ + ((type) == GLB_WRAM112KB_EM48KB) || \ + ((type) == GLB_WRAM96KB_EM64KB)) + +/** @defgroup GLB_ADC_CLK_TYPE + * @{ + */ +#define IS_GLB_ADC_CLK_TYPE(type) (((type) == GLB_ADC_CLK_AUPLL) || \ + ((type) == GLB_ADC_CLK_XCLK)) + +/** @defgroup GLB_DAC_CLK_TYPE + * @{ + */ +#define IS_GLB_DAC_CLK_TYPE(type) (((type) == GLB_DAC_CLK_32M) || \ + ((type) == GLB_DAC_CLK_XCLK)) + +/** @defgroup GLB_CHIP_CLK_INOUT_TYPE + * @{ + */ +#define IS_GLB_CHIP_CLK_INOUT_TYPE(type) (((type) == GLB_CHIP_CLK_INOUT_INPUT) || \ + ((type) == GLB_CHIP_CLK_INOUT_OUTPUT)) + +/** @defgroup GLB_CHIP_CLK_OUT_0_TYPE + * @{ + */ +#define IS_GLB_CHIP_CLK_OUT_0_TYPE(type) (((type) == GLB_CHIP_CLK_OUT_0_CAM_REF_CLK) || \ + ((type) == GLB_CHIP_CLK_OUT_0_I2S_REF_CLK) || \ + ((type) == GLB_CHIP_CLK_OUT_0_CLK_AUDIO_ADC) || \ + ((type) == GLB_CHIP_CLK_OUT_0_CLK_AUDIO_DAC)) + +/** @defgroup GLB_CHIP_CLK_OUT_1_TYPE + * @{ + */ +#define IS_GLB_CHIP_CLK_OUT_1_TYPE(type) (((type) == GLB_CHIP_CLK_OUT_1_CAM_REF_CLK) || \ + ((type) == GLB_CHIP_CLK_OUT_1_I2S_REF_CLK) || \ + ((type) == GLB_CHIP_CLK_OUT_1_CLK_AUDIO_ADC) || \ + ((type) == GLB_CHIP_CLK_OUT_1_CLK_AUDIO_DAC)) + +/** @defgroup GLB_CHIP_CLK_OUT_2_TYPE + * @{ + */ +#define IS_GLB_CHIP_CLK_OUT_2_TYPE(type) (((type) == GLB_CHIP_CLK_OUT_2_CAM_REF_CLK) || \ + ((type) == GLB_CHIP_CLK_OUT_2_I2S_REF_CLK) || \ + ((type) == GLB_CHIP_CLK_OUT_2_ANA_XTAL_CLK) || \ + ((type) == GLB_CHIP_CLK_OUT_2_PLL_32M_CLK)) + +/** @defgroup GLB_CHIP_CLK_OUT_3_TYPE + * @{ + */ +#define IS_GLB_CHIP_CLK_OUT_3_TYPE(type) (((type) == GLB_CHIP_CLK_OUT_3_CAM_REF_CLK) || \ + ((type) == GLB_CHIP_CLK_OUT_3_I2S_REF_CLK) || \ + ((type) == GLB_CHIP_CLK_OUT_3_NONE) || \ + ((type) == GLB_CHIP_CLK_OUT_3_PLL_48M_CLK)) + +/** @defgroup GLB_CSI_DSI_CLK_SEL_TYPE + * @{ + */ +#define IS_GLB_CSI_DSI_CLK_SEL_TYPE(type) (((type) == GLB_CSI_DSI_CLK_SEL_XTAL_CLK) || \ + ((type) == GLB_CSI_DSI_CLK_SEL_CPUPLL_DIV10)) + +/** @defgroup GLB_DIG_CLK_TYPE + * @{ + */ +#define IS_GLB_DIG_CLK_TYPE(type) (((type) == GLB_DIG_CLK_WIFIPLL_32M) || \ + ((type) == GLB_DIG_CLK_XCLK) || \ + ((type) == GLB_DIG_CLK_AUPLL)) + +/** @defgroup GLB_512K_CLK_OUT_TYPE + * @{ + */ +#define IS_GLB_512K_CLK_OUT_TYPE(type) (((type) == GLB_512K_CLK_OUT_512K) || \ + ((type) == GLB_512K_CLK_OUT_256K) || \ + ((type) == GLB_512K_CLK_OUT_128K)) + +/** @defgroup GLB_BT_BANDWIDTH_TYPE + * @{ + */ +#define IS_GLB_BT_BANDWIDTH_TYPE(type) (((type) == GLB_BT_BANDWIDTH_1M) || \ + ((type) == GLB_BT_BANDWIDTH_2M)) + +/** @defgroup GLB_UART2_IO_SEL_TYPE + * @{ + */ +#define IS_GLB_UART2_IO_SEL_TYPE(type) (((type) == GLB_UART2_IO_SEL_UART2) || \ + ((type) == GLB_UART2_IO_SEL_ISO11898)) + +/** @defgroup GLB_UART_SIG_TYPE + * @{ + */ +#define IS_GLB_UART_SIG_TYPE(type) (((type) == GLB_UART_SIG_0) || \ + ((type) == GLB_UART_SIG_1) || \ + ((type) == GLB_UART_SIG_2) || \ + ((type) == GLB_UART_SIG_3) || \ + ((type) == GLB_UART_SIG_4) || \ + ((type) == GLB_UART_SIG_5) || \ + ((type) == GLB_UART_SIG_6) || \ + ((type) == GLB_UART_SIG_7) || \ + ((type) == GLB_UART_SIG_8) || \ + ((type) == GLB_UART_SIG_9) || \ + ((type) == GLB_UART_SIG_10) || \ + ((type) == GLB_UART_SIG_11)) + +/** @defgroup GLB_UART_SIG_FUN_TYPE + * @{ + */ +#define IS_GLB_UART_SIG_FUN_TYPE(type) (((type) == GLB_UART_SIG_FUN_UART0_RTS) || \ + ((type) == GLB_UART_SIG_FUN_UART0_CTS) || \ + ((type) == GLB_UART_SIG_FUN_UART0_TXD) || \ + ((type) == GLB_UART_SIG_FUN_UART0_RXD) || \ + ((type) == GLB_UART_SIG_FUN_UART1_RTS) || \ + ((type) == GLB_UART_SIG_FUN_UART1_CTS) || \ + ((type) == GLB_UART_SIG_FUN_UART1_TXD) || \ + ((type) == GLB_UART_SIG_FUN_UART1_RXD) || \ + ((type) == GLB_UART_SIG_FUN_UART2_RTS) || \ + ((type) == GLB_UART_SIG_FUN_UART2_CTS) || \ + ((type) == GLB_UART_SIG_FUN_UART2_TXD) || \ + ((type) == GLB_UART_SIG_FUN_UART2_RXD)) + +/** @defgroup GLB_XTAL_TYPE + * @{ + */ +#define IS_GLB_XTAL_TYPE(type) (((type) == GLB_XTAL_NONE) || \ + ((type) == GLB_XTAL_24M) || \ + ((type) == GLB_XTAL_32M) || \ + ((type) == GLB_XTAL_38P4M) || \ + ((type) == GLB_XTAL_40M) || \ + ((type) == GLB_XTAL_26M) || \ + ((type) == GLB_XTAL_RC32M) || \ + ((type) == GLB_XTAL_MAX)) + +/** @defgroup GLB_PLL_TYPE + * @{ + */ +#define IS_GLB_PLL_TYPE(type) (((type) == GLB_PLL_NONE) || \ + ((type) == GLB_PLL_WIFIPLL) || \ + ((type) == GLB_PLL_AUPLL) || \ + ((type) == GLB_PLL_CPUPLL) || \ + ((type) == GLB_PLL_MIPIPLL) || \ + ((type) == GLB_PLL_UHSPLL)) + +/** @defgroup GLB_WAC_PLL_TYPE + * @{ + */ +#define IS_GLB_WAC_PLL_TYPE(type) (((type) == GLB_WAC_PLL_WIFIPLL) || \ + ((type) == GLB_WAC_PLL_AUPLL) || \ + ((type) == GLB_WAC_PLL_CPUPLL)) + +/** @defgroup GLB_MU_PLL_TYPE + * @{ + */ +#define IS_GLB_MU_PLL_TYPE(type) (((type) == GLB_MU_PLL_MIPIPLL) || \ + ((type) == GLB_MU_PLL_UHSPLL)) + +/** @defgroup GLB_DISP_CLK_TYPE + * @{ + */ +#define IS_GLB_DISP_CLK_TYPE(type) (((type) == GLB_DISP_CLK_MIPIPLL_1500M)) + +/** @defgroup GLB_PSRAM_PLL_TYPE + * @{ + */ +#define IS_GLB_PSRAM_PLL_TYPE(type) (((type) == GLB_PSRAM_EMI_CPUPLL_400M) || \ + ((type) == GLB_PSRAM_EMI_WIFIPLL_320M) || \ + ((type) == GLB_PSRAM_EMI_AUPLL_DIV1)) + +/** @defgroup GLB_DSP_XCLK_TYPE + * @{ + */ +#define IS_GLB_DSP_XCLK_TYPE(type) (((type) == GLB_DSP_XCLK_RC32M) || \ + ((type) == GLB_DSP_XCLK_XTAL)) + +/** @defgroup GLB_DSP_ROOT_CLK_TYPE + * @{ + */ +#define IS_GLB_DSP_ROOT_CLK_TYPE(type) (((type) == GLB_DSP_ROOT_CLK_XCLK) || \ + ((type) == GLB_DSP_ROOT_CLK_PLL)) + +/** @defgroup GLB_DSP_PBROOT_CLK_TYPE + * @{ + */ +#define IS_GLB_DSP_PBROOT_CLK_TYPE(type) (((type) == GLB_DSP_PBROOT_CLK_MM_XCLK) || \ + ((type) == GLB_DSP_PBROOT_CLK_MM_MUXPLL_240M) || \ + ((type) == GLB_DSP_PBROOT_CLK_MM_MUXPLL_160M)) + +/** @defgroup GLB_DSP_PLL_CLK_TYPE + * @{ + */ +#define IS_GLB_DSP_PLL_CLK_TYPE(type) (((type) == GLB_DSP_PLL_CLK_MUXPLL_240M) || \ + ((type) == GLB_DSP_PLL_CLK_MUXPLL_320M) || \ + ((type) == GLB_DSP_PLL_CLK_CPUPLL_400M)) + +/** @defgroup GLB_DSP_UART_CLK_TYPE + * @{ + */ +#define IS_GLB_DSP_UART_CLK_TYPE(type) (((type) == GLB_DSP_UART_CLK_DSP_PBCLK) || \ + ((type) == GLB_DSP_UART_CLK_MUXPLL_160M) || \ + ((type) == GLB_DSP_UART_CLK_DSP_XCLK)) + +/** @defgroup GLB_UART_CLK_TYPE + * @{ + */ +#define IS_GLB_UART_CLK_TYPE(type) (((type) == GLB_UART_CLK_BCLK) || \ + ((type) == GLB_UART_CLK_PLL_160M)) + +/** @defgroup GLB_DSP_CNN_CLK_TYPE + * @{ + */ +#define IS_GLB_DSP_CNN_CLK_TYPE(type) (((type) == GLB_DSP_CNN_CLK_160M) || \ + ((type) == GLB_DSP_CNN_CLK_240M) || \ + ((type) == GLB_DSP_CNN_CLK_320M)) + +/** @defgroup GLB_DSP_DP_CLK_TYPE + * @{ + */ +#define IS_GLB_DSP_DP_CLK_TYPE(type) (((type) == GLB_DSP_DP_CLK_DISPLAY_PLL) || \ + ((type) == GLB_DSP_DP_CLK_DSP_XCLK)) + +/** @defgroup GLB_DSP_DSP2_CLK_TYPE + * @{ + */ +#define IS_GLB_DSP_DSP2_CLK_TYPE(type) (((type) == GLB_DSP_DSP2_CLK_MUXPLL_160M) || \ + ((type) == GLB_DSP_DSP2_CLK_MUXPLL_240M) || \ + ((type) == GLB_DSP_DSP2_CLK_CPUPLL_400M) || \ + ((type) == GLB_DSP_DSP2_CLK_DSP_XCLK)) + +/** @defgroup GLB_DSP_H264_CLK_TYPE + * @{ + */ +#define IS_GLB_DSP_H264_CLK_TYPE(type) (((type) == GLB_DSP_H264_DSP_MUXPLL_160M) || \ + ((type) == GLB_DSP_H264_DSP_MUXPLL_240M) || \ + ((type) == GLB_DSP_H264_DSP_MUXPLL_320M)) + +/** @defgroup GLB_DSP_SPI_CLK_TYPE + * @{ + */ +#define IS_GLB_DSP_SPI_CLK_TYPE(type) (((type) == GLB_DSP_SPI_CLK_DSP_MUXPLL_160M) || \ + ((type) == GLB_DSP_SPI_CLK_DSP_XCLK)) + +/** @defgroup GLB_DSP_I2C_CLK_TYPE + * @{ + */ +#define IS_GLB_DSP_I2C_CLK_TYPE(type) (((type) == GLB_DSP_I2C_CLK_DSP_PBCLK) || \ + ((type) == GLB_DSP_I2C_CLK_XCLK)) + +/** @defgroup GLB_I2S_DI_REF_CLK_TYPE + * @{ + */ +#define IS_GLB_I2S_DI_REF_CLK_TYPE(type) (((type) == GLB_I2S_DI_SEL_I2S_DI_INPUT) || \ + ((type) == GLB_I2S_DI_SEL_I2S_REF_OUTPUT)) + +/** @defgroup GLB_I2S_DO_REF_CLK_TYPE + * @{ + */ +#define IS_GLB_I2S_DO_REF_CLK_TYPE(type) (((type) == GLB_I2S_DO_SEL_I2S_DO_OUTPT) || \ + ((type) == GLB_I2S_DO_SEL_I2S_REF_OUTPUT)) + +/** @defgroup GLB_EMI_CLK_TYPE + * @{ + */ +#define IS_GLB_EMI_CLK_TYPE(type) (((type) == GLB_EMI_CLK_MCU_PBCLK) || \ + ((type) == GLB_EMI_CLK_CPUPLL_200M_CLK) || \ + ((type) == GLB_EMI_CLK_WIFIPLL_320M_CLK) || \ + ((type) == GLB_EMI_CLK_CPUPLL_400M_CLK)) + +/** @defgroup GLB_DSP_SW_SYSTEM_TYPE + * @{ + */ +#define IS_GLB_DSP_SW_SYSTEM_TYPE(type) (((type) == GLB_DSP_SW_SYSTEM_CTRL_SYS) || \ + ((type) == GLB_DSP_SW_SYSTEM_CTRL_PWRON) || \ + ((type) == GLB_DSP_SW_SYSTEM_CTRL_DSP0) || \ + ((type) == GLB_DSP_SW_SYSTEM_CTRL_DSP1) || \ + ((type) == GLB_DSP_SW_SYSTEM_CTRL_WL2MM)) + +/** @defgroup GLB_DSP_PERIPHERAL_TYPE + * @{ + */ +#define IS_GLB_DSP_PERIPHERAL_TYPE(type) (((type) == GLB_DSP_PERIPHERAL_MM_MISC) || \ + ((type) == GLB_DSP_PERIPHERAL_DMA) || \ + ((type) == GLB_DSP_PERIPHERAL_UART0) || \ + ((type) == GLB_DSP_PERIPHERAL_I2C0) || \ + ((type) == GLB_DSP_PERIPHERAL_IPC) || \ + ((type) == GLB_DSP_PERIPHERAL_SPI) || \ + ((type) == GLB_DSP_PERIPHERAL_TIMER) || \ + ((type) == GLB_DSP_PERIPHERAL_I2S0)) + +/** @defgroup GLB_DSP_DSP2_SUB_TYPE + * @{ + */ +#define IS_GLB_DSP_DSP2_SUB_TYPE(type) (((type) == GLB_DSP_DSP2_SUB_DSP2_MISC) || \ + ((type) == GLB_DSP_DSP2_SUB_DVP2BUSA) || \ + ((type) == GLB_DSP_DSP2_SUB_DVP2BUSB) || \ + ((type) == GLB_DSP_DSP2_SUB_DVP2BUSC) || \ + ((type) == GLB_DSP_DSP2_SUB_OSD_DRAW) || \ + ((type) == GLB_DSP_DSP2_SUB_DP) || \ + ((type) == GLB_DSP_DSP2_SUB_IMG_PR) || \ + ((type) == GLB_DSP_DSP2_SUB_SCLRA) || \ + ((type) == GLB_DSP_DSP2_SUB_SCLRB)) + +/** @defgroup GLB_DSP_CODEC_SUB_TYPE + * @{ + */ +#define IS_GLB_DSP_CODEC_SUB_TYPE(type) (((type) == GLB_DSP_CODEC_SUB_MJPEG) || \ + ((type) == GLB_DSP_CODEC_SUB_CNN) || \ + ((type) == GLB_DSP_CODEC_SUB_VRAM)) + +/** @defgroup GLB_DSP_IMAGE_SENSOR_TYPE + * @{ + */ +#define IS_GLB_DSP_IMAGE_SENSOR_TYPE(type) (((type) == GLB_DSP_IMAGE_SENSOR_RG_IS)) + +/*@} end of group GLB_Public_Constants */ + +/** @defgroup GLB_Public_Macros + * @{ + */ +#define UART_SIG_SWAP_NONE (0x00) /* uart_sig[0:11] -> uart_sig[0:11] */ +#define UART_SIG_SWAP_GPIO0_GPIO11 (0x01) /* GPIO0-11 uart_sig[ 0:11] -> uart_sig[ 6:11], uart_sig[ 0: 5] */ +#define UART_SIG_SWAP_GPIO12_GPIO23 (0x02) /* GPIO12-23 uart_sig[12:23] -> uart_sig[18:23], uart_sig[12:17] */ +#define UART_SIG_SWAP_GPIO24_GPIO35 (0x04) /* GPIO24-35 uart_sig[24:35] -> uart_sig[30:35], uart_sig[24:29] */ +#define UART_SIG_SWAP_GPIO36_GPIO47 (0x08) /* GPIO36-47 uart_sig[36:47] -> uart_sig[42:47], uart_sig[36:41] */ + +#define JTAG_SIG_SWAP_NONE 0x00 /* GPIO0-22 E21_TMS/E21_TDI/E21_TCK/E21_TDO <- E21_TCK/E21_TDO/E21_TMS/E21_TDI */ + +#define GLB_AHB_CLOCK_CPU (0x1ULL<
© COPYRIGHT(c) 2020 Bouffalo Lab
+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __BL808_GLB_GPIO_H__ +#define __BL808_GLB_GPIO_H__ + +#include "glb_reg.h" +#include "mm_glb_reg.h" +#include "pds_reg.h" +#include "bl808_gpio.h" +#include "bl808_hbn.h" +#include "bl808_sf_ctrl.h" +#include "bl808_sf_cfg.h" +#include "bl808_aon.h" +#include "bl808_ef_ctrl.h" +#include "bl808_pds.h" +#include "bl808_common.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup GLB_GPIO + * @{ + */ + +/** @defgroup GLB_GPIO_Public_Types + * @{ + */ + +/** + * @brief GLB GPIO interrupt control mode type definition + */ +typedef enum { + GLB_GPIO_INT_TRIG_SYNC_FALLING_EDGE = 0, /*!< GPIO interrupt sync mode, GPIO falling edge trigger interrupt */ + GLB_GPIO_INT_TRIG_SYNC_RISING_EDGE = 1, /*!< GPIO interrupt sync mode, GPIO rising edge trigger interrupt */ + GLB_GPIO_INT_TRIG_SYNC_LOW_LEVEL = 2, /*!< GPIO interrupt sync mode, GPIO low level trigger interrupt (32k 3T) */ + GLB_GPIO_INT_TRIG_SYNC_HIGH_LEVEL = 3, /*!< GPIO interrupt sync mode, GPIO high level trigger interrupt (32k 3T) */ + GLB_GPIO_INT_TRIG_SYNC_FALLING_RISING_EDGE = 4, /*!< GPIO interrupt sync mode, GPIO falling and rising edge trigger interrupt */ + GLB_GPIO_INT_TRIG_ASYNC_FALLING_EDGE = 8, /*!< GPIO interrupt async mode, GPIO falling edge trigger interrupt */ + GLB_GPIO_INT_TRIG_ASYNC_RISING_EDGE = 9, /*!< GPIO interrupt async mode, GPIO rising edge trigger interrupt */ + GLB_GPIO_INT_TRIG_ASYNC_LOW_LEVEL = 10, /*!< GPIO interrupt async mode, GPIO low level trigger interrupt (32k 3T) */ + GLB_GPIO_INT_TRIG_ASYNC_HIGH_LEVEL = 11, /*!< GPIO interrupt async mode, GPIO high level trigger interrupt (32k 3T) */ +} GLB_GPIO_INT_TRIG_Type; + +/** + * @brief GLB GPIO FIFO interrupt type definition + */ +typedef enum { + GLB_GPIO_FIFO_INT_FER, /*!< GLB GPIO FIFO Underflow or Overflow interrupt */ + GLB_GPIO_FIFO_INT_FIFO, /*!< GLB GPIO FIFO ready (tx_fifo_cnt > tx_fifo_th) interrupt */ + GLB_GPIO_FIFO_INT_END, /*!< GLB GPIO FIFO Empty interrupt */ + GLB_GPIO_FIFO_INT_ALL, /*!< All the interrupt */ +} GLB_GPIO_FIFO_INT_Type; + +/** + * @brief GLB GPIO FIFO Timing Phase type definition + */ +typedef enum { + GPIO_FIFO_PHASE_FIRST_HIGH, /*!< GPIO first send high level */ + GPIO_FIFO_PHASE_FIRST_LOW, /*!< GPIO first send low level */ +} GLB_GPIO_FIFO_PHASE_Type; + +/** + * @brief GLB GPIO FIFO Idle State type definition + */ +typedef enum { + GPIO_FIFO_IDLE_LOW, + GPIO_FIFO_IDLE_HIGH, +} GLB_GPIO_FIFO_IDLE_Type; + +/** + * @brief GLB GPIO FIFO Latch Mode type definition + */ +typedef enum { + GPIO_FIFO_LATCH_WRITE, /*!< GPIO FIFO direct write I/O */ + GPIO_FIFO_LATCH_SETCLEAR, /*!< GPIO FIFO set/clr I/O */ +} GLB_GPIO_FIFO_LATCH_Type; + +/** + * @brief GPIO interrupt configuration structure type definition + */ +typedef struct +{ + GLB_GPIO_Type gpioPin; /*!< GPIO pin num */ + GLB_GPIO_INT_TRIG_Type trig; /*!< GPIO interrupt trig mode */ + BL_Mask_Type intMask; /*!< GPIO interrupt mask config */ +} GLB_GPIO_INT_Cfg_Type; + +/** + * @brief UART configuration structure type definition + */ +typedef struct +{ + uint8_t code0FirstTime; /*!< The clock num of code0 first send */ + uint8_t code1FirstTime; /*!< The clock num of code1 first send */ + uint16_t codeTotalTime; /*!< The total clock num of code0/1(high + low */ + GLB_GPIO_FIFO_PHASE_Type code0Phase; /*!< low or high level of code0 first send */ + GLB_GPIO_FIFO_PHASE_Type code1Phase; /*!< low or high level of code1 first send */ + GLB_GPIO_FIFO_IDLE_Type idle; /*!< the I/O idle level */ + uint8_t fifoDmaThreshold; /*!< FIFO threshold */ + BL_Fun_Type fifoDmaEnable; /*!< Enable or disable DMA of GPIO */ + GLB_GPIO_FIFO_LATCH_Type latch; /*!< Write or set/clr GPIO level */ +} GLB_GPIO_FIFO_CFG_Type; + +/*@} end of group GLB_GPIO_Public_Types */ + +/** @defgroup GLB_GPIO_Public_Constants + * @{ + */ + +/** @defgroup GLB_GPIO_INT_TRIG_TYPE + * @{ + */ +#define IS_GLB_GPIO_INT_TRIG_TYPE(type) (((type) == GLB_GPIO_INT_TRIG_SYNC_FALLING_EDGE) || \ + ((type) == GLB_GPIO_INT_TRIG_SYNC_RISING_EDGE) || \ + ((type) == GLB_GPIO_INT_TRIG_SYNC_LOW_LEVEL) || \ + ((type) == GLB_GPIO_INT_TRIG_SYNC_HIGH_LEVEL) || \ + ((type) == GLB_GPIO_INT_TRIG_SYNC_FALLING_RISING_EDGE) || \ + ((type) == GLB_GPIO_INT_TRIG_ASYNC_FALLING_EDGE) || \ + ((type) == GLB_GPIO_INT_TRIG_ASYNC_RISING_EDGE) || \ + ((type) == GLB_GPIO_INT_TRIG_ASYNC_LOW_LEVEL) || \ + ((type) == GLB_GPIO_INT_TRIG_ASYNC_HIGH_LEVEL)) + +/** @defgroup GLB_GPIO_INT_TRIG_TYPE + * @{ + */ +#define IS_GLB_GPIO_FIFO_INT_TYPE(type) (((type) == GLB_GPIO_INT_FER) || \ + ((type) == GLB_GPIO_INT_FIFO) || \ + ((type) == GLB_GPIO_INT_END) || \ + ((type) == GLB_GPIO_FIFO_INT_ALL)) + +/** @defgroup GLB_GPIO_FIFO_PHASE_TYPE + * @{ + */ +#define IS_GLB_GPIO_FIFO_PHASE_TYPE(type) (((type) == GPIO_FIFO_HIGH_FIRST_LOW_FOLLOWED) || \ + ((type) == GPIO_FIFO_LOW_FIRST_HIGH_FOLLOWED)) + +/** @defgroup GLB_GPIO_FIFO_PHASE_TYPE + * @{ + */ +#define IS_GLB_GPIO_FIFO_LATCH_TYPE(type) (((type) == GPIO_FIFO_LATCH_WRITE) || \ + ((type) == GPIO_FIFO_LATCH_SETCLEAR)) + +/*@} end of group GLB_GPIO_Public_Constants */ + +/** @defgroup GLB_GPIO_Public_Macros + * @{ + */ + +/*@} end of group GLB_GPIO_Public_Macros */ + +/** @defgroup GLB_GPIO_Public_Functions + * @{ + */ +/*----------*/ +#ifndef BFLB_USE_HAL_DRIVER +void GPIO_INT0_IRQHandler(void); +#endif +/*----------*/ +BL_Err_Type GLB_GPIO_Init(GLB_GPIO_Cfg_Type *cfg); +BL_Err_Type GLB_GPIO_Func_Init(GLB_GPIO_FUNC_Type gpioFun, GLB_GPIO_Type *pinList, uint8_t cnt); +BL_Err_Type GLB_GPIO_Input_Enable(GLB_GPIO_Type gpioPin); +BL_Err_Type GLB_Embedded_Flash_Pad_Enable(void); +BL_Err_Type GLB_GPIO_Input_Disable(GLB_GPIO_Type gpioPin); +BL_Err_Type GLB_GPIO_Output_Enable(GLB_GPIO_Type gpioPin); +BL_Err_Type GLB_GPIO_Output_Disable(GLB_GPIO_Type gpioPin); +BL_Err_Type GLB_GPIO_Set_HZ(GLB_GPIO_Type gpioPin); +uint8_t GLB_GPIO_Get_Fun(GLB_GPIO_Type gpioPin); +uint32_t GLB_GPIO_Read(GLB_GPIO_Type gpioPin); +BL_Err_Type GLB_GPIO_Write(GLB_GPIO_Type gpioPin, uint32_t val); +BL_Err_Type GLB_GPIO_Set(GLB_GPIO_Type gpioPin); +BL_Err_Type GLB_GPIO_Clr(GLB_GPIO_Type gpioPin); +BL_Err_Type GLB_GPIO_Int_Init(GLB_GPIO_INT_Cfg_Type *intCfg); +BL_Err_Type GLB_GPIO_IntMask(GLB_GPIO_Type gpioPin, BL_Mask_Type intMask); +BL_Sts_Type GLB_Get_GPIO_IntStatus(GLB_GPIO_Type gpioPin); +BL_Err_Type GLB_Clr_GPIO_IntStatus(GLB_GPIO_Type gpioPin); +BL_Err_Type GLB_GPIO_INT0_IRQHandler_Install(void); +BL_Err_Type GLB_GPIO_INT0_Callback_Install(GLB_GPIO_Type gpioPin, intCallback_Type *cbFun); + +#ifndef BFLB_USE_HAL_DRIVER +void GPIO_FIFO_IRQHandler(void); +#endif +BL_Err_Type GLB_GPIO_Fifo_Callback_Install(GLB_GPIO_FIFO_INT_Type intType, intCallback_Type *cbFun); +BL_Err_Type GLB_GPIO_Fifo_IRQHandler_Install(void); +BL_Err_Type GLB_GPIO_Fifo_Init(GLB_GPIO_FIFO_CFG_Type *cfg); +BL_Err_Type GLB_GPIO_Fifo_Push(uint16_t *data, uint16_t len); +uint32_t GLB_GPIO_Fifo_GetCount(void); +BL_Err_Type GLB_GPIO_Fifo_Clear(void); +BL_Err_Type GLB_GPIO_Fifo_IntMask(GLB_GPIO_FIFO_INT_Type intType, BL_Mask_Type intMask); +BL_Err_Type GLB_GPIO_Fifo_IntClear(GLB_GPIO_FIFO_INT_Type intType); +BL_Sts_Type GLB_GPIO_Fifo_GetIntStatus(GLB_GPIO_FIFO_INT_Type intType); +BL_Sts_Type GLB_GPIO_Fifo_Enable(void); +BL_Sts_Type GLB_GPIO_Fifo_Disable(void); + +/*@} end of group GLB_GPIO_Public_Functions */ + +/*@} end of group GLB_GPIO */ + +/*@} end of group BL808_Peripheral_Driver */ + +#endif /* __BL808_GLB_GPIO_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/bl808_gpio.h b/platforms/bl808_m0/vendor/psram/include/bl808_gpio.h new file mode 100644 index 0000000..f4c0fb6 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/bl808_gpio.h @@ -0,0 +1,166 @@ +/** + ****************************************************************************** + * @file bl808_gpio.h + * @version V1.0 + * @date 2020-11-06 + * @brief This file is the description of.IP register + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __BL808_GPIO_H__ +#define __BL808_GPIO_H__ + +typedef enum { + GLB_GPIO_PIN_0 = 0, + GLB_GPIO_PIN_1, + GLB_GPIO_PIN_2, + GLB_GPIO_PIN_3, + GLB_GPIO_PIN_4, + GLB_GPIO_PIN_5, + GLB_GPIO_PIN_6, + GLB_GPIO_PIN_7, + GLB_GPIO_PIN_8, + GLB_GPIO_PIN_9, + GLB_GPIO_PIN_10, + GLB_GPIO_PIN_11, + GLB_GPIO_PIN_12, + GLB_GPIO_PIN_13, + GLB_GPIO_PIN_14, + GLB_GPIO_PIN_15, + GLB_GPIO_PIN_16, + GLB_GPIO_PIN_17, + GLB_GPIO_PIN_18, + GLB_GPIO_PIN_19, + GLB_GPIO_PIN_20, + GLB_GPIO_PIN_21, + GLB_GPIO_PIN_22, + GLB_GPIO_PIN_23, + GLB_GPIO_PIN_24, + GLB_GPIO_PIN_25, + GLB_GPIO_PIN_26, + GLB_GPIO_PIN_27, + GLB_GPIO_PIN_28, + GLB_GPIO_PIN_29, + GLB_GPIO_PIN_30, + GLB_GPIO_PIN_31, + GLB_GPIO_PIN_32, + GLB_GPIO_PIN_33, + GLB_GPIO_PIN_34, + GLB_GPIO_PIN_35, + GLB_GPIO_PIN_36, + GLB_GPIO_PIN_37, + GLB_GPIO_PIN_38, + GLB_GPIO_PIN_39, + GLB_GPIO_PIN_40, + GLB_GPIO_PIN_41, + GLB_GPIO_PIN_42, + GLB_GPIO_PIN_43, + GLB_GPIO_PIN_44, + GLB_GPIO_PIN_45, + GLB_GPIO_PIN_MAX, +} GLB_GPIO_Type; + +#define GPIO_MODE_INPUT ((uint32_t)0x00000000U) /*!< Input Floating Mode */ +#define GPIO_MODE_OUTPUT ((uint32_t)0x00000001U) /*!< Output Push Pull Mode */ +#define GPIO_MODE_AF ((uint32_t)0x00000002U) /*!< Alternate function */ +#define GPIO_MODE_ANALOG ((uint32_t)0x00000003U) /*!< Analog function */ +#define GPIO_PULL_UP ((uint32_t)0x00000000U) /*!< GPIO pull up */ +#define GPIO_PULL_DOWN ((uint32_t)0x00000001U) /*!< GPIO pull down */ +#define GPIO_PULL_NONE ((uint32_t)0x00000002U) /*!< GPIO no pull up or down */ +#define GPIO_OUTPUT_VALUE_MODE ((uint8_t)0x00U) /*!< GPIO Output by reg_gpio_x_o Value */ +#define GPIO_SET_CLR_MODE ((uint8_t)0x01U) /*!< GPIO Output set by reg_gpio_x_set and clear by reg_gpio_x_clr */ +#define GPIO_DMA_OUTPUT_VALUE_MODE ((uint8_t)0x02U) /*!< GPIO Output value by gpio_dma_o */ +#define GPIO_DMA_SET_CLR_MODE ((uint8_t)0x03U) /*!< GPIO Outout value by gpio_dma_set/gpio_dma_clr */ + +typedef enum { + GPIO_FUN_SDH = 0, + GPIO_FUN_SPI0 = 1, + GPIO_FUN_FLASH = 2, + GPIO_FUN_I2S = 3, + GPIO_FUN_PDM = 4, + GPIO_FUN_I2C0 = 5, + GPIO_FUN_I2C1 = 6, + GPIO_FUN_UART = 7, + GPIO_FUN_ETHER_MAC = 8, + GPIO_FUN_CAM = 9, + GPIO_FUN_ANALOG = 10, + GPIO_FUN_GPIO = 11, + GPIO_FUN_PWM0 = 16, + GPIO_FUN_PWM1 = 17, + GPIO_FUN_SPI1 = 18, + GPIO_FUN_I2C2 = 19, + GPIO_FUN_I2C3 = 20, + GPIO_FUN_MM_UART = 21, + GPIO_FUN_DBI_B = 22, + GPIO_FUN_DBI_C = 23, + GPIO_FUN_DPI = 24, + GPIO_FUN_JTAG_LP = 25, + GPIO_FUN_JTAG_M0 = 26, + GPIO_FUN_JTAG_D0 = 27, + GPIO_FUN_CLOCK_OUT = 31, + + GPIO_FUN_CLOCK_OUT_X_CAM_REF_CLK = 0xE0, + GPIO_FUN_CLOCK_OUT_X_I2S_REF_CLK = 0xE1, + GPIO_FUN_CLOCK_OUT_0_1_AUDIO_ADC_CLK = 0xE2, + GPIO_FUN_CLOCK_OUT_0_1_AUDIO_DAC_CLK = 0xE3, + GPIO_FUN_CLOCK_OUT_2_ANA_XTAL_CLK = 0xE2, + GPIO_FUN_CLOCK_OUT_2_PLL_32M_CLK = 0xE3, + GPIO_FUN_CLOCK_OUT_3_NONE = 0xE2, + GPIO_FUN_CLOCK_OUT_3_PLL_48M_CLK = 0xE3, + + GPIO_FUN_UART0_RTS = 0xF0, + GPIO_FUN_UART0_CTS = 0xF1, + GPIO_FUN_UART0_TX = 0xF2, + GPIO_FUN_UART0_RX = 0xF3, + GPIO_FUN_UART1_RTS = 0xF4, + GPIO_FUN_UART1_CTS = 0xF5, + GPIO_FUN_UART1_TX = 0xF6, + GPIO_FUN_UART1_RX = 0xF7, + GPIO_FUN_UART2_RTS = 0xF8, + GPIO_FUN_UART2_CTS = 0xF9, + GPIO_FUN_UART2_TX = 0xFA, + GPIO_FUN_UART2_RX = 0xFB, + + GPIO_FUN_UART3 = 21, + + GPIO_FUN_UNUSED = 0xFF, +} GLB_GPIO_FUNC_Type; + +typedef struct +{ + uint8_t gpioPin; + uint8_t gpioFun; + uint8_t gpioMode; + uint8_t pullType; + uint8_t drive; + uint8_t smtCtrl; + uint8_t outputMode; +} GLB_GPIO_Cfg_Type; + +#endif /*__BL808_GPIO_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/bl808_hbn.h b/platforms/bl808_m0/vendor/psram/include/bl808_hbn.h new file mode 100644 index 0000000..ece53d4 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/bl808_hbn.h @@ -0,0 +1,677 @@ +/** + ****************************************************************************** + * @file bl808_hbn.h + * @version V1.0 + * @date + * @brief This file is the standard driver header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __BL808_HBN_H__ +#define __BL808_HBN_H__ + +#include "hbn_reg.h" +#include "bl808_aon.h" +#include "bl808_l1c.h" +#include "bl808_sflash.h" +#include "bl808_common.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup HBN + * @{ + */ + +/** @defgroup HBN_Public_Types + * @{ + */ + +/** + * @brief HBN PIR interrupt configuration type definition + */ +typedef struct +{ + BL_Fun_Type lowIntEn; /*!< Low will trigger interrupt */ + BL_Fun_Type highIntEn; /*!< High will trigger interrupt */ +} HBN_PIR_INT_CFG_Type; + +/** + * @brief HBN PIR low pass filter type definition + */ +typedef enum { + HBN_PIR_LPF_DIV1, /*!< HBN PIR lpf div 1 */ + HBN_PIR_LPF_DIV2, /*!< HBN PIR lpf div 2 */ +} HBN_PIR_LPF_Type; + +/** + * @brief HBN PIR high pass filter type definition + */ +typedef enum { + HBN_PIR_HPF_METHOD0, /*!< HBN PIR hpf calc method 0, 1-z^-1 */ + HBN_PIR_HPF_METHOD1, /*!< HBN PIR hpf calc method 1, 1-z^-2 */ + HBN_PIR_HPF_METHOD2, /*!< HBN PIR hpf calc method 2, 1-z^-3 */ +} HBN_PIR_HPF_Type; + +/** + * @brief HBN flash pad pu pd type + */ +typedef enum { + HBN_FLASH_PAD_PULL_NONE, /*!< flash pad pull none when Flash at Deep Power Down Mode */ + HBN_FLASH_PAD_PULL_UP, /*!< flash pad pull up when Flash at Deep Power Down Mode */ + HBN_FLASH_PAD_PULL_DOWN, /*!< flash pad pull down when Flash at Deep Power Down Mode */ +} HBN_FLASH_PAD_PULL_Type; + +/** + * @brief HBN BOD threshold type definition + */ +typedef enum { + HBN_BOD_THRES_2P05V, /*!< BOD threshold 2.05V */ + HBN_BOD_THRES_2P10V, /*!< BOD threshold 2.10V */ + HBN_BOD_THRES_2P15V, /*!< BOD threshold 2.15V */ + HBN_BOD_THRES_2P20V, /*!< BOD threshold 2.20V */ + HBN_BOD_THRES_2P25V, /*!< BOD threshold 2.25V */ + HBN_BOD_THRES_2P30V, /*!< BOD threshold 2.30V */ + HBN_BOD_THRES_2P35V, /*!< BOD threshold 2.35V */ + HBN_BOD_THRES_2P40V, /*!< BOD threshold 2.40V */ +} HBN_BOD_THRES_Type; + +/** + * @brief HBN BOD mode type definition + */ +typedef enum { + HBN_BOD_MODE_POR_INDEPENDENT, /*!< POR is independent of BOD */ + HBN_BOD_MODE_POR_RELEVANT, /*!< POR is relevant to BOD */ +} HBN_BOD_MODE_Type; + +/** + * @brief HBN 32K clock type definition + */ +typedef enum { + HBN_32K_RC = 0, /*!< HBN use rc 32k */ + HBN_32K_XTAL, /*!< HBN use xtal 32k */ + HBN_32K_DIG = 3, /*!< HBN use dig 32k */ +} HBN_32K_CLK_Type; + +/** + * @brief HBN xclk clock type definition + */ +typedef enum { + HBN_MCU_XCLK_RC32M, /*!< use RC32M as xclk clock */ + HBN_MCU_XCLK_XTAL, /*!< use XTAL as xclk clock */ +} HBN_MCU_XCLK_Type; + +/** + * @brief HBN root clock type definition + */ +typedef enum { + HBN_MCU_ROOT_CLK_XCLK, /*!< use XCLK as root clock */ + HBN_MCU_ROOT_CLK_PLL, /*!< use PLL as root clock */ +} HBN_MCU_ROOT_CLK_Type; + +/** + * @brief HBN UART clock type definition + */ +typedef enum { + HBN_UART_CLK_MCU_PBCLK = 0, /*!< Select mcu_pbclk as UART clock */ + HBN_UART_CLK_160M, /*!< Select 160M as UART clock */ + HBN_UART_CLK_XCLK, /*!< Select XCLK as UART clock */ +} HBN_UART_CLK_Type; + +/** + * @brief HBN RTC interrupt delay type definition + */ +typedef enum { + HBN_RTC_INT_DELAY_32T = 0, /*!< HBN RTC interrupt delay 32T */ + HBN_RTC_INT_DELAY_0T = 1, /*!< HBN RTC interrupt delay 0T */ +} HBN_RTC_INT_Delay_Type; + +/** + * @brief HBN interrupt type definition + */ +typedef enum { + HBN_INT_GPIO9 = 0, /*!< HBN interrupt type: GPIO9 */ + HBN_INT_GPIO10 = 1, /*!< HBN interrupt type: GPIO10 */ + HBN_INT_GPIO11 = 2, /*!< HBN interrupt type: GPIO11 */ + HBN_INT_GPIO12 = 3, /*!< HBN interrupt type: GPIO12 */ + HBN_INT_GPIO13 = 4, /*!< HBN interrupt type: GPIO13 */ + HBN_INT_GPIO14 = 5, /*!< HBN interrupt type: GPIO14 */ + HBN_INT_GPIO15 = 6, /*!< HBN interrupt type: GPIO15 */ + HBN_INT_GPIO40 = 7, /*!< HBN interrupt type: GPIO40 */ + HBN_INT_GPIO41 = 8, /*!< HBN interrupt type: GPIO41 */ + HBN_INT_RTC = 16, /*!< HBN interrupt type: RTC */ + HBN_INT_PIR = 17, /*!< HBN interrupt type: PIR */ + HBN_INT_BOD = 18, /*!< HBN interrupt type: BOD */ + HBN_INT_ACOMP0 = 20, /*!< HBN interrupt type: ACOMP0 */ + HBN_INT_ACOMP1 = 22, /*!< HBN interrupt type: ACOMP1 */ +} HBN_INT_Type; + +/** + * @brief HBN aon pad type definition + */ +typedef enum { + HBN_AON_PAD_GPIO9 = 0, /*!< HBN aon pad type: GPIO9 */ + HBN_AON_PAD_GPIO10 = 1, /*!< HBN aon pad type: GPIO10 */ + HBN_AON_PAD_GPIO11 = 2, /*!< HBN aon pad type: GPIO11 */ + HBN_AON_PAD_GPIO12 = 3, /*!< HBN aon pad type: GPIO12 */ + HBN_AON_PAD_GPIO13 = 4, /*!< HBN aon pad type: GPIO13 */ + HBN_AON_PAD_GPIO14 = 5, /*!< HBN aon pad type: GPIO14 */ + HBN_AON_PAD_GPIO15 = 6, /*!< HBN aon pad type: GPIO15 */ + HBN_AON_PAD_GPIO40 = 7, /*!< HBN aon pad type: GPIO40 */ + HBN_AON_PAD_GPIO41 = 8, /*!< HBN aon pad type: GPIO41 */ +} HBN_AON_PAD_Type; + +/** + * @brief HBN acomp interrupt type definition + */ +typedef enum { + HBN_ACOMP_INT_EDGE_POSEDGE = 0, /*!< HBN acomp interrupt edge posedge */ + HBN_ACOMP_INT_EDGE_NEGEDGE = 1, /*!< HBN acomp interrupt edge negedge */ +} HBN_ACOMP_INT_EDGE_Type; + +/** + * @brief HBN GPIO pad pu pd type + */ +typedef enum { + HBN_GPIO_PAD_PULL_NONE = 0, /*!< gpio pad pull none at hbn */ + HBN_GPIO_PAD_PULL_DOWN = 1, /*!< gpio pad pull down at hbn */ + HBN_GPIO_PAD_PULL_UP = 2, /*!< gpio pad pull up at hbn */ + HBN_GPIO_PAD_ACTIVE_IE = 3, /*!< gpio pad active ie at hbn */ +} HBN_GPIO_PAD_PULL_Type; + +/** + * @brief HBN AON PAD configuration type definition + */ +typedef struct +{ + uint8_t ctrlEn; /*!< AON GPIO41/40/15~9 Control by AON HW */ + uint8_t inputEn; /*!< Always on PAD IE/SMT (if corresponding AON GPIO controlled by AON HW) */ + uint8_t outputEn; /*!< Always on PAD OE (if corresponding AON GPIO controlled by AON HW) */ + HBN_GPIO_PAD_PULL_Type pullCfg; /*!< Always on PAD PU/PD (if corresponding AON GPIO controlled by AON HW) */ +} HBN_AON_PAD_CFG_Type; + +/** + * @brief HBN GPIO interrupt trigger type definition + */ +typedef enum { + HBN_GPIO_INT_TRIGGER_SYNC_FALLING_EDGE = 0x0, /*!< HBN GPIO INT trigger type: sync falling edge trigger */ + HBN_GPIO_INT_TRIGGER_SYNC_RISING_EDGE = 0x1, /*!< HBN GPIO INT trigger type: sync rising edge trigger */ + HBN_GPIO_INT_TRIGGER_SYNC_LOW_LEVEL = 0x2, /*!< HBN GPIO INT trigger type: sync low level trigger */ + HBN_GPIO_INT_TRIGGER_SYNC_HIGH_LEVEL = 0x3, /*!< HBN GPIO INT trigger type: sync high level trigger */ + HBN_GPIO_INT_TRIGGER_SYNC_RISING_FALLING_EDGE = 0x4, /*!< HBN GPIO INT trigger type: sync rising falling edge trigger */ + HBN_GPIO_INT_TRIGGER_ASYNC_FALLING_EDGE = 0x8, /*!< HBN GPIO INT trigger type: async falling edge trigger */ + HBN_GPIO_INT_TRIGGER_ASYNC_RISING_EDGE = 0x9, /*!< HBN GPIO INT trigger type: async rising edge trigger */ + HBN_GPIO_INT_TRIGGER_ASYNC_LOW_LEVEL = 0xA, /*!< HBN GPIO INT trigger type: async low level trigger */ + HBN_GPIO_INT_TRIGGER_ASYNC_HIGH_LEVEL = 0xB, /*!< HBN GPIO INT trigger type: async high level trigger */ +} HBN_GPIO_INT_Trigger_Type; + +/** + * @brief HBN OUT0 interrupt type definition + */ +typedef enum { + HBN_OUT0_INT_GPIO9 = 0, /*!< HBN out 0 interrupt type: GPIO9 */ + HBN_OUT0_INT_GPIO10 = 1, /*!< HBN out 0 interrupt type: GPIO10 */ + HBN_OUT0_INT_GPIO11 = 2, /*!< HBN out 0 interrupt type: GPIO11 */ + HBN_OUT0_INT_GPIO12 = 3, /*!< HBN out 0 interrupt type: GPIO12 */ + HBN_OUT0_INT_GPIO13 = 4, /*!< HBN out 0 interrupt type: GPIO13 */ + HBN_OUT0_INT_GPIO14 = 5, /*!< HBN out 0 interrupt type: GPIO14 */ + HBN_OUT0_INT_GPIO15 = 6, /*!< HBN out 0 interrupt type: GPIO15 */ + HBN_OUT0_INT_GPIO40 = 7, /*!< HBN out 0 interrupt type: GPIO40 */ + HBN_OUT0_INT_GPIO41 = 8, /*!< HBN out 0 interrupt type: GPIO41 */ + HBN_OUT0_INT_RTC, /*!< HBN out 0 interrupt type: RTC */ + HBN_OUT0_INT_MAX, /*!< MAX */ +} HBN_OUT0_INT_Type; + +/** + * @brief HBN OUT0 interrupt type definition + */ +typedef enum { + HBN_OUT1_INT_PIR, /*!< HBN out 1 interrupt type: PIR */ + HBN_OUT1_INT_BOD, /*!< HBN out 1 interrupt type: BOD */ + HBN_OUT1_INT_ACOMP0, /*!< HBN out 1 interrupt type: ACOMP0 */ + HBN_OUT1_INT_ACOMP1, /*!< HBN out 1 interrupt type: ACOMP1 */ + HBN_OUT1_INT_MAX, /*!< MAX */ +} HBN_OUT1_INT_Type; + +/** + * @brief HBN LDO level type definition + */ +typedef enum { + HBN_LDO_LEVEL_0P70V = 2, /*!< HBN LDO voltage 0.70V */ + HBN_LDO_LEVEL_0P75V = 3, /*!< HBN LDO voltage 0.75V */ + HBN_LDO_LEVEL_0P80V = 4, /*!< HBN LDO voltage 0.80V */ + HBN_LDO_LEVEL_0P85V = 5, /*!< HBN LDO voltage 0.85V */ + HBN_LDO_LEVEL_0P90V = 6, /*!< HBN LDO voltage 0.90V */ + HBN_LDO_LEVEL_0P95V = 7, /*!< HBN LDO voltage 0.95V */ + HBN_LDO_LEVEL_1P00V = 8, /*!< HBN LDO voltage 1.00V */ + HBN_LDO_LEVEL_1P05V = 9, /*!< HBN LDO voltage 1.05V */ + HBN_LDO_LEVEL_1P10V = 10, /*!< HBN LDO voltage 1.10V */ + HBN_LDO_LEVEL_1P15V = 11, /*!< HBN LDO voltage 1.15V */ + HBN_LDO_LEVEL_1P20V = 12, /*!< HBN LDO voltage 1.20V */ + HBN_LDO_LEVEL_1P25V = 13, /*!< HBN LDO voltage 1.25V */ + HBN_LDO_LEVEL_1P30V = 14, /*!< HBN LDO voltage 1.30V */ + HBN_LDO_LEVEL_1P35V = 15, /*!< HBN LDO voltage 1.35V */ +} HBN_LDO_LEVEL_Type; + +/** + * @brief HBN level type definition + */ +typedef enum { + HBN_LEVEL_0, /*!< HBN pd_core */ + HBN_LEVEL_1, /*!< HBN pd_aon_hbncore + pd_core */ +} HBN_LEVEL_Type; + +/** + * @brief HBN RTC misc configuration type definition + */ +typedef struct +{ + uint32_t rtcRstHoldCnt_rtc : 3; /*!< rtc_rst_hold_cnt_rtc */ + uint32_t rsvda : 1; /*!< reserved */ + uint32_t rtcRstEnRtc : 1; /*!< rtc_rst_en_rtc */ + uint32_t rtcRstInvRtc : 1; /*!< rtc_rst_inv_rtc */ + uint32_t rtcRstClkSel_rtc : 1; /*!< rtc_rst_clk_sel_rtc */ + uint32_t rsvdb : 1; /*!< reserved */ + uint32_t ldo11RtcVoutSelRtc : 4; /*!< ldo11_rtc_vout_sel_rtc */ + uint32_t rsvdc : 22; /*!< reserved */ +} HBN_RTC_MISC_Type; + +/** + * @brief HBN BOD configuration type definition + */ +typedef struct +{ + uint8_t enableBod; /*!< Enable BOD or not */ + uint8_t enableBodInt; /*!< Enable BOD interrupt or not */ + uint8_t bodThreshold; /*!< BOD threshold */ + uint8_t enablePorInBod; /*!< Enable POR when BOD occure or not */ +} HBN_BOD_CFG_Type; + +/** + * @brief HBN APP configuration type definition + */ +typedef struct +{ + uint8_t useXtal32k; /*!< Whether use xtal 32K as 32K clock source,otherwise use rc32k */ + uint32_t sleepTime; /*!< HBN sleep time */ + uint8_t gpioWakeupSrc; /*!< GPIO Wakeup source */ + HBN_GPIO_INT_Trigger_Type gpioTrigType; /*!< GPIO Triger type */ + SPI_Flash_Cfg_Type *flashCfg; /*!< Flash config pointer, used when power down flash */ + HBN_LEVEL_Type hbnLevel; /*!< HBN level */ + HBN_LDO_LEVEL_Type ldoLevel; /*!< LDO level */ + uint8_t dcdcPuSeq; /*!< power on dcdc sequence */ +} HBN_APP_CFG_Type; + +/*@} end of group HBN_Public_Types */ + +/** @defgroup HBN_Public_Constants + * @{ + */ + +/** @defgroup HBN_PIR_LPF_TYPE + * @{ + */ +#define IS_HBN_PIR_LPF_TYPE(type) (((type) == HBN_PIR_LPF_DIV1) || \ + ((type) == HBN_PIR_LPF_DIV2)) + +/** @defgroup HBN_PIR_HPF_TYPE + * @{ + */ +#define IS_HBN_PIR_HPF_TYPE(type) (((type) == HBN_PIR_HPF_METHOD0) || \ + ((type) == HBN_PIR_HPF_METHOD1) || \ + ((type) == HBN_PIR_HPF_METHOD2)) + +/** @defgroup HBN_FLASH_PAD_PULL_TYPE + * @{ + */ +#define IS_HBN_FLASH_PAD_PULL_TYPE(type) (((type) == HBN_FLASH_PAD_PULL_NONE) || \ + ((type) == HBN_FLASH_PAD_PULL_UP) || \ + ((type) == HBN_FLASH_PAD_PULL_DOWN)) + +/** @defgroup HBN_BOD_THRES_TYPE + * @{ + */ +#define IS_HBN_BOD_THRES_TYPE(type) (((type) == HBN_BOD_THRES_2P05V) || \ + ((type) == HBN_BOD_THRES_2P10V) || \ + ((type) == HBN_BOD_THRES_2P15V) || \ + ((type) == HBN_BOD_THRES_2P20V) || \ + ((type) == HBN_BOD_THRES_2P25V) || \ + ((type) == HBN_BOD_THRES_2P30V) || \ + ((type) == HBN_BOD_THRES_2P35V) || \ + ((type) == HBN_BOD_THRES_2P40V)) + +/** @defgroup HBN_BOD_MODE_TYPE + * @{ + */ +#define IS_HBN_BOD_MODE_TYPE(type) (((type) == HBN_BOD_MODE_POR_INDEPENDENT) || \ + ((type) == HBN_BOD_MODE_POR_RELEVANT)) + +/** @defgroup HBN_32K_CLK_TYPE + * @{ + */ +#define IS_HBN_32K_CLK_TYPE(type) (((type) == HBN_32K_RC) || \ + ((type) == HBN_32K_XTAL) || \ + ((type) == HBN_32K_DIG)) + +/** @defgroup HBN_MCU_XCLK_TYPE + * @{ + */ +#define IS_HBN_MCU_XCLK_TYPE(type) (((type) == HBN_MCU_XCLK_RC32M) || \ + ((type) == HBN_MCU_XCLK_XTAL)) + +/** @defgroup HBN_MCU_ROOT_CLK_TYPE + * @{ + */ +#define IS_HBN_MCU_ROOT_CLK_TYPE(type) (((type) == HBN_MCU_ROOT_CLK_XCLK) || \ + ((type) == HBN_MCU_ROOT_CLK_PLL)) + +/** @defgroup HBN_UART_CLK_TYPE + * @{ + */ +#define IS_HBN_UART_CLK_TYPE(type) (((type) == HBN_UART_CLK_MCU_PBCLK) || \ + ((type) == HBN_UART_CLK_160M) || \ + ((type) == HBN_UART_CLK_XCLK)) + +/** @defgroup HBN_RTC_INT_DELAY_TYPE + * @{ + */ +#define IS_HBN_RTC_INT_DELAY_TYPE(type) (((type) == HBN_RTC_INT_DELAY_32T) || \ + ((type) == HBN_RTC_INT_DELAY_0T)) + +/** @defgroup HBN_INT_TYPE + * @{ + */ +#define IS_HBN_INT_TYPE(type) (((type) == HBN_INT_GPIO9) || \ + ((type) == HBN_INT_GPIO10) || \ + ((type) == HBN_INT_GPIO11) || \ + ((type) == HBN_INT_GPIO12) || \ + ((type) == HBN_INT_GPIO13) || \ + ((type) == HBN_INT_GPIO14) || \ + ((type) == HBN_INT_GPIO15) || \ + ((type) == HBN_INT_GPIO40) || \ + ((type) == HBN_INT_GPIO41) || \ + ((type) == HBN_INT_RTC) || \ + ((type) == HBN_INT_PIR) || \ + ((type) == HBN_INT_BOD) || \ + ((type) == HBN_INT_ACOMP0) || \ + ((type) == HBN_INT_ACOMP1)) + +/** @defgroup HBN_ACOMP_INT_EDGE_TYPE + * @{ + */ +#define IS_HBN_ACOMP_INT_EDGE_TYPE(type) (((type) == HBN_ACOMP_INT_EDGE_POSEDGE) || \ + ((type) == HBN_ACOMP_INT_EDGE_NEGEDGE)) + +/** @defgroup HBN_AON_PAD_TYPE + * @{ + */ +#define IS_HBN_AON_PAD_TYPE(type) (((type) == HBN_AON_PAD_GPIO9) || \ + ((type) == HBN_AON_PAD_GPIO10) || \ + ((type) == HBN_AON_PAD_GPIO11) || \ + ((type) == HBN_AON_PAD_GPIO12) || \ + ((type) == HBN_AON_PAD_GPIO13) || \ + ((type) == HBN_AON_PAD_GPIO14) || \ + ((type) == HBN_AON_PAD_GPIO15) || \ + ((type) == HBN_AON_PAD_GPIO40) || \ + ((type) == HBN_AON_PAD_GPIO41)) + +/** @defgroup HBN_GPIO_PAD_PULL_TYPE + * @{ + */ +#define IS_HBN_GPIO_PAD_PULL_TYPE(type) (((type) == HBN_GPIO_PAD_PULL_NONE) || \ + ((type) == HBN_GPIO_PAD_PULL_DOWN) || \ + ((type) == HBN_GPIO_PAD_PULL_UP) || \ + ((type) == HBN_GPIO_PAD_ACTIVE_IE)) + +/** @defgroup HBN_GPIO_INT_TRIGGER_TYPE + * @{ + */ +#define IS_HBN_GPIO_INT_TRIGGER_TYPE(type) (((type) == HBN_GPIO_INT_TRIGGER_SYNC_FALLING_EDGE) || \ + ((type) == HBN_GPIO_INT_TRIGGER_SYNC_RISING_EDGE) || \ + ((type) == HBN_GPIO_INT_TRIGGER_SYNC_LOW_LEVEL) || \ + ((type) == HBN_GPIO_INT_TRIGGER_SYNC_HIGH_LEVEL) || \ + ((type) == HBN_GPIO_INT_TRIGGER_SYNC_RISING_FALLING_EDGE) || \ + ((type) == HBN_GPIO_INT_TRIGGER_ASYNC_FALLING_EDGE) || \ + ((type) == HBN_GPIO_INT_TRIGGER_ASYNC_RISING_EDGE) || \ + ((type) == HBN_GPIO_INT_TRIGGER_ASYNC_LOW_LEVEL) || \ + ((type) == HBN_GPIO_INT_TRIGGER_ASYNC_HIGH_LEVEL)) + +/** @defgroup HBN_OUT0_INT_TYPE + * @{ + */ +#define IS_HBN_OUT0_INT_TYPE(type) (((type) == HBN_OUT0_INT_GPIO9) || \ + ((type) == HBN_OUT0_INT_GPIO10) || \ + ((type) == HBN_OUT0_INT_GPIO11) || \ + ((type) == HBN_OUT0_INT_GPIO12) || \ + ((type) == HBN_OUT0_INT_GPIO13) || \ + ((type) == HBN_OUT0_INT_GPIO14) || \ + ((type) == HBN_OUT0_INT_GPIO15) || \ + ((type) == HBN_OUT0_INT_GPIO40) || \ + ((type) == HBN_OUT0_INT_GPIO41) || \ + ((type) == HBN_OUT0_INT_RTC) || \ + ((type) == HBN_OUT0_INT_MAX)) + +/** @defgroup HBN_OUT1_INT_TYPE + * @{ + */ +#define IS_HBN_OUT1_INT_TYPE(type) (((type) == HBN_OUT1_INT_PIR) || \ + ((type) == HBN_OUT1_INT_BOD) || \ + ((type) == HBN_OUT1_INT_ACOMP0) || \ + ((type) == HBN_OUT1_INT_ACOMP1) || \ + ((type) == HBN_OUT1_INT_MAX)) + +/** @defgroup HBN_LDO_LEVEL_TYPE + * @{ + */ +#define IS_HBN_LDO_LEVEL_TYPE(type) (((type) == HBN_LDO_LEVEL_0P70V) || \ + ((type) == HBN_LDO_LEVEL_0P75V) || \ + ((type) == HBN_LDO_LEVEL_0P80V) || \ + ((type) == HBN_LDO_LEVEL_0P85V) || \ + ((type) == HBN_LDO_LEVEL_0P90V) || \ + ((type) == HBN_LDO_LEVEL_0P95V) || \ + ((type) == HBN_LDO_LEVEL_1P00V) || \ + ((type) == HBN_LDO_LEVEL_1P05V) || \ + ((type) == HBN_LDO_LEVEL_1P10V) || \ + ((type) == HBN_LDO_LEVEL_1P15V) || \ + ((type) == HBN_LDO_LEVEL_1P20V) || \ + ((type) == HBN_LDO_LEVEL_1P25V) || \ + ((type) == HBN_LDO_LEVEL_1P30V) || \ + ((type) == HBN_LDO_LEVEL_1P35V)) + +/** @defgroup HBN_LEVEL_TYPE + * @{ + */ +#define IS_HBN_LEVEL_TYPE(type) (((type) == HBN_LEVEL_0) || \ + ((type) == HBN_LEVEL_1)) + +/*@} end of group HBN_Public_Constants */ + +/** @defgroup HBN_Public_Macros + * @{ + */ +#define HBN_RAM_SIZE (4 * 1024) +#define HBN_RTC_COMP_BIT0_39 0x01 +#define HBN_RTC_COMP_BIT0_23 0x02 +#define HBN_RTC_COMP_BIT13_39 0x04 +#define HBN_STATUS_ENTER_FLAG 0x4e424845 +#define HBN_STATUS_WAKEUP_FLAG 0x4e424857 +#define HBN_RELEASE_CORE_FLAG (0x48) +#define HBN_REPOWER_LDO18FLASH_FLAG (0x52) +#define HBN_XTAL_FLAG_MASK 0x0000ff00 +#define HBN_XTAL_FLAG_VALUE 0x5800 + +/* 0x108 : HBN_RSV2 */ +#define HBN_REPOWER_LDO18FLASH_DLY HBN_REPOWER_LDO18FLASH_DLY +#define HBN_REPOWER_LDO18FLASH_DLY_POS (0U) +#define HBN_REPOWER_LDO18FLASH_DLY_LEN (8U) +#define HBN_REPOWER_LDO18FLASH_DLY_MSK (((1U << HBN_REPOWER_LDO18FLASH_DLY_LEN) - 1) << HBN_REPOWER_LDO18FLASH_DLY_POS) +#define HBN_REPOWER_LDO18FLASH_DLY_UMSK (~(((1U << HBN_REPOWER_LDO18FLASH_DLY_LEN) - 1) << HBN_REPOWER_LDO18FLASH_DLY_POS)) +#define HBN_REPOWER_LDO18FLASH HBN_REPOWER_LDO18FLASH +#define HBN_REPOWER_LDO18FLASH_POS (8U) +#define HBN_REPOWER_LDO18FLASH_LEN (8U) +#define HBN_REPOWER_LDO18FLASH_MSK (((1U << HBN_REPOWER_LDO18FLASH_LEN) - 1) << HBN_REPOWER_LDO18FLASH_POS) +#define HBN_REPOWER_LDO18FLASH_UMSK (~(((1U << HBN_REPOWER_LDO18FLASH_LEN) - 1) << HBN_REPOWER_LDO18FLASH_POS)) +#define HBN_CORE_UNHALT HBN_CORE_UNHALT +#define HBN_CORE_UNHALT_POS (16U) +#define HBN_CORE_UNHALT_LEN (5U) +#define HBN_CORE_UNHALT_MSK (((1U << HBN_CORE_UNHALT_LEN) - 1) << HBN_CORE_UNHALT_POS) +#define HBN_CORE_UNHALT_UMSK (~(((1U << HBN_CORE_UNHALT_LEN) - 1) << HBN_CORE_UNHALT_POS)) +#define HBN_POWER_ON_MM HBN_POWER_ON_MM +#define HBN_POWER_ON_MM_POS (21U) +#define HBN_POWER_ON_MM_LEN (1U) +#define HBN_POWER_ON_MM_MSK (((1U << HBN_POWER_ON_MM_LEN) - 1) << HBN_POWER_ON_MM_POS) +#define HBN_POWER_ON_MM_UMSK (~(((1U << HBN_POWER_ON_MM_LEN) - 1) << HBN_POWER_ON_MM_POS)) +#define HBN_HAND_OFF_SEL HBN_HAND_OFF_SEL +#define HBN_HAND_OFF_SEL_POS (22U) +#define HBN_HAND_OFF_SEL_LEN (2U) +#define HBN_HAND_OFF_SEL_MSK (((1U << HBN_HAND_OFF_SEL_LEN) - 1) << HBN_HAND_OFF_SEL_POS) +#define HBN_HAND_OFF_SEL_UMSK (~(((1U << HBN_HAND_OFF_SEL_LEN) - 1) << HBN_HAND_OFF_SEL_POS)) +#define HBN_RELEASE_CORE HBN_RELEASE_CORE +#define HBN_RELEASE_CORE_POS (24U) +#define HBN_RELEASE_CORE_LEN (8U) +#define HBN_RELEASE_CORE_MSK (((1U << HBN_RELEASE_CORE_LEN) - 1) << HBN_RELEASE_CORE_POS) +#define HBN_RELEASE_CORE_UMSK (~(((1U << HBN_RELEASE_CORE_LEN) - 1) << HBN_RELEASE_CORE_POS)) + +/*@} end of group HBN_Public_Macros */ + +/** @defgroup HBN_Public_Functions + * @{ + */ +/*----------*/ +#ifndef BFLB_USE_HAL_DRIVER +void HBN_OUT0_IRQHandler(void); +void HBN_OUT1_IRQHandler(void); +#endif +/*----------*/ +void HBN_Mode_Enter(HBN_APP_CFG_Type *cfg); +void HBN_Power_Down_Flash(SPI_Flash_Cfg_Type *flashCfg); +void HBN_Enable(uint32_t aGPIOIeCfg, HBN_LDO_LEVEL_Type ldoLevel, HBN_LEVEL_Type hbnLevel, uint8_t dcdcPuSeq); +BL_Err_Type HBN_Reset(void); +/*----------*/ +BL_Err_Type HBN_PIR_Enable(void); +BL_Err_Type HBN_PIR_Disable(void); +BL_Err_Type HBN_PIR_INT_Config(HBN_PIR_INT_CFG_Type *pirIntCfg); +BL_Err_Type HBN_PIR_LPF_Sel(HBN_PIR_LPF_Type lpf); +BL_Err_Type HBN_PIR_HPF_Sel(HBN_PIR_HPF_Type hpf); +BL_Err_Type HBN_Set_PIR_Threshold(uint16_t threshold); +uint16_t HBN_Get_PIR_Threshold(void); +BL_Err_Type HBN_Set_PIR_Interval(uint16_t interval); +uint16_t HBN_Get_PIR_Interval(void); +/*----------*/ +BL_Sts_Type HBN_Get_BOD_OUT_State(void); +BL_Err_Type HBN_Set_BOD_Config(uint8_t enable, HBN_BOD_THRES_Type threshold, HBN_BOD_MODE_Type mode); +/*----------*/ +BL_Err_Type HBN_Set_Ldo11_Aon_Vout(HBN_LDO_LEVEL_Type ldoLevel); +BL_Err_Type HBN_Set_Ldo11_Rt_Vout(HBN_LDO_LEVEL_Type ldoLevel); +BL_Err_Type HBN_Set_Ldo11_Rtc_Vout(HBN_LDO_LEVEL_Type ldoLevel); +BL_Err_Type HBN_Set_Ldo11_All_Vout(HBN_LDO_LEVEL_Type ldoLevel); +/*----------*/ +BL_Err_Type HBN_32K_Sel(HBN_32K_CLK_Type clkType); +BL_Err_Type HBN_Set_UART_CLK_Sel(HBN_UART_CLK_Type clkSel); +HBN_MCU_XCLK_Type HBN_Get_MCU_XCLK_Sel(void); +BL_Err_Type HBN_Set_MCU_XCLK_Sel(HBN_MCU_XCLK_Type xclk); +HBN_MCU_ROOT_CLK_Type HBN_Get_MCU_Root_CLK_Sel(void); +BL_Err_Type HBN_Set_MCU_Root_CLK_Sel(HBN_MCU_ROOT_CLK_Type rootClk); +/*----------*/ +BL_Err_Type HBN_Set_HRAM_slp(void); +BL_Err_Type HBN_Set_HRAM_Ret(void); + +/*----------*/ +uint32_t HBN_Get_Status_Flag(void); +BL_Err_Type HBN_Set_Status_Flag(uint32_t flag); +uint32_t HBN_Get_Wakeup_Addr(void); +BL_Err_Type HBN_Set_Wakeup_Addr(uint32_t addr); +/*----------*/ +uint8_t HBN_Get_Core_Unhalt_Config(void); +BL_Err_Type HBN_Set_Core_Reboot_Config(uint8_t core, uint8_t hcfg); +uint8_t HBN_Get_MM_Power_Config(void); +BL_Err_Type HBN_Set_MM_Power_Config(uint8_t pcfg); +uint8_t HBN_Get_Hand_Off_Config(void); +BL_Err_Type HBN_Set_Hand_Off_Config(uint8_t dcfg); +uint16_t HBN_Get_Ldo18flash_Repower_Config(void); +BL_Err_Type HBN_Set_Ldo18flash_Repower_Delay(uint8_t delay); +/*----------*/ +BL_Err_Type HBN_Set_Xtal_Type(uint8_t xtalType); +BL_Err_Type HBN_Get_Xtal_Type(uint8_t *xtalType); +BL_Err_Type HBN_Get_Xtal_Value(uint32_t *xtalVal); +/*----------*/ +BL_Err_Type HBN_Clear_RTC_Counter(void); +BL_Err_Type HBN_Enable_RTC_Counter(void); +BL_Err_Type HBN_Set_RTC_Timer(HBN_RTC_INT_Delay_Type delay, uint32_t compValLow, uint32_t compValHigh, uint8_t compMode); +BL_Err_Type HBN_Get_RTC_Timer_Val(uint32_t *valLow, uint32_t *valHigh); +BL_Err_Type HBN_Clear_RTC_IRQ(void); +/*----------*/ +BL_Err_Type HBN_GPIO_INT_Enable(HBN_GPIO_INT_Trigger_Type gpioIntTrigType); +BL_Err_Type HBN_GPIO_INT_Disable(void); +BL_Sts_Type HBN_Get_INT_State(HBN_INT_Type irqType); +uint8_t HBN_Get_Pin_Wakeup_Mode(void); +BL_Err_Type HBN_Clear_IRQ(HBN_INT_Type irqType); +BL_Err_Type HBN_Hw_Pu_Pd_Cfg(uint8_t enable); +BL_Err_Type HBN_Pin_WakeUp_Mask(uint8_t maskVal); +BL_Err_Type HBN_Aon_Pad_Ctrl(uint32_t aonPadCtl1, uint32_t aonPadCtl2); +BL_Err_Type HBN_Aon_Pad_Cfg(uint8_t aonPadHwCtrlEn, HBN_AON_PAD_Type aonGpio, HBN_AON_PAD_CFG_Type *aonPadCfg); +BL_Err_Type HBN_Set_IO4041_As_Xtal_32K_IO(uint8_t xtal32kIoEn); +/*----------*/ +BL_Err_Type HBN_Enable_AComp0_IRQ(HBN_ACOMP_INT_EDGE_Type edge); +BL_Err_Type HBN_Disable_AComp0_IRQ(HBN_ACOMP_INT_EDGE_Type edge); +BL_Err_Type HBN_Enable_AComp1_IRQ(HBN_ACOMP_INT_EDGE_Type edge); +BL_Err_Type HBN_Disable_AComp1_IRQ(HBN_ACOMP_INT_EDGE_Type edge); +/*----------*/ +BL_Err_Type HBN_Enable_BOD_IRQ(void); +BL_Err_Type HBN_Disable_BOD_IRQ(void); +/*----------*/ +BL_Err_Type HBN_Out0_Callback_Install(HBN_OUT0_INT_Type intType, intCallback_Type *cbFun); +BL_Err_Type HBN_Out1_Callback_Install(HBN_OUT1_INT_Type intType, intCallback_Type *cbFun); +/*----------*/ +BL_Err_Type HBN_Aon_Pad_WakeUpCfg(BL_Fun_Type puPdEn, HBN_GPIO_INT_Trigger_Type trigMode, uint32_t maskVal, BL_Fun_Type dlyEn, uint8_t dlySec); +/*----------*/ +BL_Err_Type HBN_Power_On_Xtal_32K(void); +BL_Err_Type HBN_Power_Off_Xtal_32K(void); +BL_Err_Type HBN_Power_On_RC32K(void); +BL_Err_Type HBN_Power_Off_RC32K(void); +BL_Err_Type HBN_Trim_RC32K(void); +/*----------*/ +BL_Err_Type HBN_PD_RC32K_All_State(void); +BL_Err_Type HBN_PD_RC32K_In_Poff(void); +/*----------*/ +BL_Err_Type HBN_Get_RTC_Misc_Cfg(HBN_RTC_MISC_Type *cfg); +BL_Err_Type HBN_Set_RTC_Misc_Cfg(HBN_RTC_MISC_Type *cfg); +/*----------*/ +BL_Err_Type HBN_Set_BOD_Cfg(HBN_BOD_CFG_Type *cfg); +BL_Err_Type HBN_Clear_RTC_INT(void); +/*----------*/ + +/*@} end of group HBN_Public_Functions */ + +/*@} end of group HBN */ + +/*@} end of group BL808_Peripheral_Driver */ + +#endif /* __BL808_HBN_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/bl808_l1c.h b/platforms/bl808_m0/vendor/psram/include/bl808_l1c.h new file mode 100644 index 0000000..3d796c1 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/bl808_l1c.h @@ -0,0 +1,118 @@ +/** + ****************************************************************************** + * @file bl808_l1c.h + * @version V1.0 + * @date + * @brief This file is the standard driver header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __BL808_L1C_H__ +#define __BL808_L1C_H__ + +#include "pds_reg.h" +#include "bl808_common.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup L1C + * @{ + */ + +/** @defgroup L1C_Public_Types + * @{ + */ + +/** + * @brief L1C configuration structure type definition + */ +typedef struct +{ + uint8_t cacheEn; + uint8_t wayDis; + uint8_t wa; + uint8_t wb; + uint8_t wt; + uint8_t rsvd[3]; + uint32_t cacheRangeL; + uint32_t cacheRangeH; +} L1C_CACHE_Cfg_Type; + +/*@} end of group L1C_Public_Types */ + +/** @defgroup L1C_Public_Constants + * @{ + */ + +/*@} end of group L1C_Public_Constants */ + +/** @defgroup L1C_Public_Macros + * @{ + */ +#define L1C_WAY_DISABLE_NONE 0x00 +#define L1C_WAY_DISABLE_ONE 0x01 +#define L1C_WAY_DISABLE_TWO 0x03 +#define L1C_WAY_DISABLE_ALL 0x03 +#define L1C_WAY_DISABLE_NOT_CAHNGE 0xFF + +/*@} end of group L1C_Public_Macros */ + +/** @defgroup L1C_Public_Functions + * @{ + */ + +/*----------*/ +BL_Err_Type L1C_ICache_Enable(uint8_t wayDsiable); +BL_Err_Type L1C_DCache_Enable(uint8_t wayDsiable); +BL_Err_Type L1C_ICache_Disable(void); +BL_Err_Type L1C_DCache_Disable(void); +void L1C_DCache_Write_Set(BL_Fun_Type wtEn, BL_Fun_Type wbEn, BL_Fun_Type waEn); +BL_Err_Type L1C_DCache_Clean_All(void); +BL_Err_Type L1C_DCache_Clean_Invalid_All(void); +BL_Err_Type L1C_ICache_Invalid_All(void); +BL_Err_Type L1C_DCache_Invalid_All(void); +BL_Err_Type L1C_DCache_Clean_By_Addr(uintptr_t addr, uint32_t len); +BL_Err_Type L1C_DCache_Clean_Invalid_By_Addr(uintptr_t addr, uint32_t len); +BL_Err_Type L1C_ICache_Invalid_By_Addr(uintptr_t addr, uint32_t len); +BL_Err_Type L1C_DCache_Invalid_By_Addr(uintptr_t addr, uint32_t len); +/*----------*/ +BL_Err_Type L1C_Set_Wrap(uint8_t en); +BL_Err_Type L1C_Set_Cache_Setting_By_ID(uint8_t core, L1C_CACHE_Cfg_Type *cacheSetting); +/*----------*/ +int L1C_Is_DCache_Range(uintptr_t addr); +int L1C_Get_None_Cache_Addr(uintptr_t addr); +/*@} end of group L1C_Public_Functions */ + +/*@} end of group L1C */ + +/*@} end of group BL808_Peripheral_Driver */ + +#endif /* __BL808_L1C_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/bl808_pds.h b/platforms/bl808_m0/vendor/psram/include/bl808_pds.h new file mode 100644 index 0000000..1658ccd --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/bl808_pds.h @@ -0,0 +1,519 @@ +/** + ****************************************************************************** + * @file bl808_pds.h + * @version V1.0 + * @date + * @brief This file is the standard driver header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __BL808_PDS_H__ +#define __BL808_PDS_H__ + +#include "pds_reg.h" +#include "glb_reg.h" +#include "bl808_ef_ctrl.h" +#include "bl808_clock.h" +#include "bl808_aon.h" +#include "bl808_hbn.h" +#include "bl808_sflash.h" +#include "bl808_sf_ctrl.h" +#include "bl808_common.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup PDS + * @{ + */ + +/** @defgroup PDS_Public_Types + * @{ + */ + +/** + * @brief PDS GPIO int set type + */ +typedef enum { + PDS_GPIO_INT_SET_1_GPIO0_GPIO7, /*!< gpio int set 1, gpio0 - gpio7 */ + PDS_GPIO_INT_SET_2_GPIO8_16_GPIO22, /*!< gpio int set 2, gpio8, gpio16 - gpio22 */ + PDS_GPIO_INT_SET_3_GPIO23_GPIO30, /*!< gpio int set 3, gpio23 - gpio30 */ + PDS_GPIO_INT_SET_4_GPIO31_GPIO38, /*!< gpio int set 4, gpio31 - gpio38 */ +} PDS_GPIO_INT_SET_Type; + +/** + * @brief PDS GPIO interrupt control mode type definition + */ +typedef enum { + PDS_GPIO_INT_SYNC_FALLING_EDGE = 0, /*!< GPIO interrupt sync mode, GPIO negedge pulse trigger interrupt */ + PDS_GPIO_INT_SYNC_RISING_EDGE = 1, /*!< GPIO interrupt sync mode, GPIO posedge pulse trigger interrupt */ + PDS_GPIO_INT_SYNC_LOW_LEVEL = 2, /*!< GPIO interrupt sync mode, GPIO negedge level trigger interrupt */ + PDS_GPIO_INT_SYNC_HIGH_LEVEL = 3, /*!< GPIO interrupt sync mode, GPIO posedge level trigger interrupt */ + PDS_GPIO_INT_SYNC_RISING_FALLING_EDGE = 4, /*!< GPIO interrupt sync mode, GPIO posedge negedge pulse trigger interrupt */ + PDS_GPIO_INT_ASYNC_FALLING_EDGE = 8, /*!< GPIO interrupt async mode, GPIO negedge pulse trigger interrupt */ + PDS_GPIO_INT_ASYNC_RISING_EDGE = 9, /*!< GPIO interrupt async mode, GPIO posedge pulse trigger interrupt */ + PDS_GPIO_INT_ASYNC_LOW_LEVEL = 10, /*!< GPIO interrupt async mode, GPIO negedge level trigger interrupt */ + PDS_GPIO_INT_ASYNC_HIGH_LEVEL = 11, /*!< GPIO interrupt async mode, GPIO posedge level trigger interrupt */ +} PDS_GPIO_INT_TRIG_Type; + +/** + * @brief PDS lp system clock type definition + */ +typedef enum { + PDS_LP_SYS_CLK_BCLK_DIV, /*!< use bclk div as system clock frequency */ +} PDS_LP_SYS_CLK_Type; + +/** + * @brief PDS LDO level type definition + */ +typedef enum { + PDS_LDO_LEVEL_0P70V = 2, /*!< PDS LDO voltage 0.70V */ + PDS_LDO_LEVEL_0P75V = 3, /*!< PDS LDO voltage 0.75V */ + PDS_LDO_LEVEL_0P80V = 4, /*!< PDS LDO voltage 0.80V */ + PDS_LDO_LEVEL_0P85V = 5, /*!< PDS LDO voltage 0.85V */ + PDS_LDO_LEVEL_0P90V = 6, /*!< PDS LDO voltage 0.90V */ + PDS_LDO_LEVEL_0P95V = 7, /*!< PDS LDO voltage 0.95V */ + PDS_LDO_LEVEL_1P00V = 8, /*!< PDS LDO voltage 1.00V */ + PDS_LDO_LEVEL_1P05V = 9, /*!< PDS LDO voltage 1.05V */ + PDS_LDO_LEVEL_1P10V = 10, /*!< PDS LDO voltage 1.10V */ + PDS_LDO_LEVEL_1P15V = 11, /*!< PDS LDO voltage 1.15V */ + PDS_LDO_LEVEL_1P20V = 12, /*!< PDS LDO voltage 1.20V */ + PDS_LDO_LEVEL_1P25V = 13, /*!< PDS LDO voltage 1.25V */ + PDS_LDO_LEVEL_1P30V = 14, /*!< PDS LDO voltage 1.30V */ + PDS_LDO_LEVEL_1P35V = 15, /*!< PDS LDO voltage 1.35V */ +} PDS_LDO_LEVEL_Type; + +/** + * @brief PDS configuration type definition + */ +typedef struct +{ + uint32_t pdsStart : 1; /*!< [0]PDS Start */ + uint32_t sleepForever : 1; /*!< [1]PDS sleep forever */ + uint32_t xtalForceOff : 1; /*!< [2]Power off xtal force */ + uint32_t saveWiFiState : 1; /*!< [3]Save WIFI State Before Enter PDS */ + uint32_t dcdc11Off : 1; /*!< [4]power down dcdc11 during PDS */ + uint32_t bgSysOff : 1; /*!< [5]power down bg_sys during PDS */ + uint32_t ctrlGpioIePuPd : 1; /*!< [6]PDS control */ + uint32_t dcdc18Off : 1; /*!< [7]power down dcdc18 during PDS */ + uint32_t clkOff : 1; /*!< [8]gate clock during PDS (each pwr domain has its own control) */ + uint32_t memStby : 1; /*!< [9]mem_stby during PDS (each power domain can has its own control) */ + uint32_t glbRstProtect : 1; /*!< [10]avoid glb_reg reset by any reset */ + uint32_t isolation : 1; /*!< [11]Isolation during PDS (each power domain can has its own control) */ + uint32_t waitXtalRdy : 1; /*!< [12]wait XTAL Ready during before PDS Interrupt */ + uint32_t pdsPwrOff : 1; /*!< [13]Power off during PDS (each power domain can has its own control) */ + uint32_t xtalOff : 1; /*!< [14]xtal power down during PDS */ + uint32_t socEnbForceOn : 1; /*!< [15]pds_soc_enb always active */ + uint32_t pdsRstSocEn : 1; /*!< [16]pds_rst controlled by PDS */ + uint32_t pdsRC32mOn : 1; /*!< [17]RC32M always on or RC32M on/off controlled by PDS state */ + uint32_t pdsDcdc11VselEn : 1; /*!< [18]PDS "SLEEP" control DCDC11 voltage enable */ + uint32_t usbpllOff : 1; /*!< [19]PDS Control USB PLL off When pds_pwr_off */ + uint32_t aupllOff : 1; /*!< [20]PDS control aupll power off */ + uint32_t cpupllOff : 1; /*!< [21]PDS control cpupll power off */ + uint32_t wifipllOff : 1; /*!< [22]PDS control wifipll power off */ + uint32_t pdsDcdc11Vsel : 5; /*!< [27:23]DCDC11 voltage selection in PDS mode */ + uint32_t pdsCtlRfSel : 2; /*!< [29:28]select the way RF controlled by PDS */ + uint32_t pdsUseTbttSlp : 1; /*!< [30]PDS Auto Sleep When wifi_tbtt_sleep_irq detect to 1 */ + uint32_t pdsGpioIsoMod : 1; /*!< [31]HW Keep GPIO at PDS Mode */ +} PDS_CTL_Type; + +/** + * @brief PDS force configuration type definition + */ +typedef struct +{ + uint32_t rsv0 : 1; /*!< [0] */ + uint32_t mcuRst : 1; /*!< [1] */ + uint32_t mcuMemStby : 1; /*!< [2] */ + uint32_t mcuGateClk : 1; /*!< [3] */ + uint32_t rsv4_7 : 4; /*!< [7:4]reserve */ + uint32_t dspPwrOff : 1; /*!< [8] */ + uint32_t dspRst : 1; /*!< [9] */ + uint32_t dspMemStby : 1; /*!< [10] */ + uint32_t dspGateClk : 1; /*!< [11] */ + uint32_t rsv12 : 1; /*!< [12] */ + uint32_t WbRst : 1; /*!< [13] */ + uint32_t WbMemStby : 1; /*!< [14] */ + uint32_t WbGateClk : 1; /*!< [15] */ + uint32_t rsv16_19 : 4; /*!< [19:16]reserve */ + uint32_t usbPwrOff : 1; /*!< [20] */ + uint32_t usbRst : 1; /*!< [21] */ + uint32_t usbMemStby : 1; /*!< [22] */ + uint32_t usbGateClk : 1; /*!< [23] */ + uint32_t MiscPwrOff : 1; /*!< [24] */ + uint32_t MiscRst : 1; /*!< [25] */ + uint32_t MiscMemStby : 1; /*!< [26] */ + uint32_t MiscGateClk : 1; /*!< [27] */ + uint32_t rsv28_31 : 4; /*!< [31:28]reserve */ +} PDS_CTL4_Type; + +/** + * @brief PDS interrupt type definition + */ +typedef enum { + PDS_INT_WAKEUP = 0, /*!< PDS wakeup interrupt(assert bit while wakeup, include PDS_Timer/...) */ + PDS_INT_RF_DONE = 1, /*!< PDS RF done interrupt */ + PDS_INT_WIFI_TBTT_SLEEP = 2, /*!< PDS wifi tbtt sleep interrupt */ + PDS_INT_WIFI_TBTT_WAKEUP = 3, /*!< PDS wifi tbtt wakeup interrupt */ + PDS_INT_MAX = 4, /*!< PDS int max number */ +} PDS_INT_Type; + +/** + * @brief PDS force configuration type definition + */ +typedef struct +{ + uint32_t rsv0 : 1; /*!< [0]manual force NP power off */ + uint32_t forceDspPwrOff : 1; /*!< [1]manual force MM power off */ + uint32_t rsv2 : 1; /*!< [2]manual force WB power off */ + uint32_t forceUsbPwrOff : 1; /*!< [3]manual force USB power off */ + uint32_t rsv4 : 1; /*!< [4]manual force NP isolation */ + uint32_t forceDspIso : 1; /*!< [5]manual force MM isolation */ + uint32_t rsv6 : 1; /*!< [6]manual force WB isolation */ + uint32_t forceUsbIso : 1; /*!< [7]manual force USB isolation */ + uint32_t forceMcuPdsRst : 1; /*!< [8]manual force NP pds reset */ + uint32_t forceDspPdsRst : 1; /*!< [9]manual force MM pds reset */ + uint32_t forceWbPdsRst : 1; /*!< [10]manual force WB pds reset */ + uint32_t forceUsbPdsRst : 1; /*!< [11]manual force USB pds reset */ + uint32_t forceMcuMemStby : 1; /*!< [12]manual force NP memory sleep */ + uint32_t forceDspMemStby : 1; /*!< [13]manual force MM memory sleep */ + uint32_t forceWbMemStby : 1; /*!< [14]manual force WB memory sleep */ + uint32_t forceUsbMemStby : 1; /*!< [15]manual force USB memory sleep */ + uint32_t forceMcuGateClk : 1; /*!< [16]manual force NP clock gated */ + uint32_t forceDspGateClk : 1; /*!< [17]manual force MM clock gated */ + uint32_t forceWbGateClk : 1; /*!< [18]manual force WB clock gated */ + uint32_t forceUsbGateClk : 1; /*!< [19]manual force USB clock gated */ + uint32_t rsv20_31 : 12; /*!< [31:20]reserve */ +} PDS_CTL2_Type; + +/** + * @brief PDS force configuration type definition + */ +typedef struct +{ + uint32_t rsv0 : 1; /*!< [0]reserve */ + uint32_t forceMiscPwrOff : 1; /*!< [1]manual force MISC pwr_off */ + uint32_t rsv2_3 : 2; /*!< [3:2]reserve */ + uint32_t forceMiscIsoEn : 1; /*!< [4]manual force MISC iso_en */ + uint32_t rsv5_6 : 2; /*!< [6:5]reserve */ + uint32_t forceMiscPdsRst : 1; /*!< [7]manual force MISC pds_rst */ + uint32_t rsv8_9 : 2; /*!< [9:8]reserve */ + uint32_t forceMiscMemStby : 1; /*!< [10]manual force MISC mem_stby */ + uint32_t rsv11_12 : 2; /*!< [12:11]reserve */ + uint32_t forceMiscGateClk : 1; /*!< [13]manual force MISC gate_clk */ + uint32_t rsv14_25 : 12; /*!< [25:14]reserve */ + uint32_t DspIsoEn : 1; /*!< [26]make MM isolated at PDS Sleep state */ + uint32_t rsv27_28 : 2; /*!< [28:27]reserve */ + uint32_t UsbIsoEn : 1; /*!< [29]make USB isolated at PDS Sleep state */ + uint32_t MiscIsoEn : 1; /*!< [30]make misc isolated at PDS Sleep state */ + uint32_t rsv31 : 1; /*!< [31]reserve */ +} PDS_CTL3_Type; + +/** + * @brief PDS force configuration type definition + */ +typedef struct +{ + uint32_t McuWfiMask : 1; /*!< [0]pds start condition mask np_wfi */ + uint32_t rsv1 : 1; /*!< [1]reserve */ + uint32_t DspWfiMask : 1; /*!< [2]pds start condition mask mm_wfi */ + uint32_t rsv3 : 1; /*!< [3]reserve */ + uint32_t LpWfiMask : 1; /*!< [4]pds start condition mask pico_wfi */ + uint32_t rsv5_7 : 3; /*!< [7:5]reserve */ + uint32_t ctrlUsb33 : 1; /*!< [8]enable HW control turn on&&off USB 3.3V */ + uint32_t pdLdo18io : 1; /*!< [9]power down ldo18io during PDS */ + uint32_t rsv10_15 : 6; /*!< [15:10]reserve */ + uint32_t gpioKeepEn : 3; /*!< [18:16]can use bit to enable or disable keep function */ + uint32_t rsv19_31 : 13; /*!< [31:19]reserve */ +} PDS_CTL5_Type; + +/** + * @brief PDS default level configuration type definition + */ +typedef struct +{ + PDS_CTL_Type pdsCtl; /*!< PDS_CTL configuration */ + PDS_CTL2_Type pdsCtl2; /*!< PDS_CTL2 configuration */ + PDS_CTL3_Type pdsCtl3; /*!< PDS_CTL3 configuration */ + PDS_CTL4_Type pdsCtl4; /*!< PDS_CTL4 configuration */ + PDS_CTL5_Type pdsCtl5; /*!< PDS_CTL5 configuration */ +} PDS_DEFAULT_LV_CFG_Type; + +/** + * @brief PDS control RAM1 type definition + */ +typedef struct +{ + uint32_t ocramSlp : 4; /*!< [3:0] cr_ocram_slp */ + uint32_t ocramRet : 4; /*!< [7:4] cr_ocram_ret */ + uint32_t ramClkCnt : 6; /*!< [13:8] HW Option : Assert Extra Clock Counter in MEM_STBY */ + uint32_t rsv14_15 : 2; /*!< [15:14] reserved */ + uint32_t ramClkCnt2 : 6; /*!< [21:16] HW Option : Assert Extra Clock Counter in MEM_IDLE/LV_MEM_IDLE */ + uint32_t rsv22_23 : 2; /*!< [23:22] reserved */ + uint32_t mcuRamClk : 1; /*!< [24] PDS Control PD_CORE_CPU SRAM Clock */ + uint32_t dspRamClk : 1; /*!< [25] PDS Control PD_MM SRAM Clock */ + uint32_t wbRamClk : 1; /*!< [26] PDS Control PD_WB SRAM Clock */ + uint32_t usbRamClk : 1; /*!< [27] PDS Control PD_usb SRAM Clock */ + uint32_t miscRamClk : 1; /*!< [28] PDS Control PD_CORE_MISC SRAM Clock */ + uint32_t rsv29 : 1; /*!< [29] reserved */ + uint32_t ctlRamClk2 : 1; /*!< [30] To assert extra clock during PDS on sequence */ + uint32_t ctlRamClk : 1; /*!< [31] Enable PDS Control PD_CORE SRAM Clock */ +} PDS_CTRL_RAM1_Type; + +/** + * @brief PDS control RAM2 type definition + */ +typedef struct +{ + uint32_t wramSlp : 10; /*!< [9:0] cr_wram_slp */ + uint32_t wramRet : 10; /*!< [19:10] cr_wram_ret */ + uint32_t rsv20_31 : 12; /*!< [31:20] reserved */ +} PDS_CTRL_RAM2_Type; + +/** + * @brief PDS OCRAM configuration type definition + */ +typedef struct +{ + uint32_t PDS_OCRAM_CFG_0KB_16KB_CPU_RAM_SLP : 1; /*!< [0] 0~16KB cpu_ram sleep */ + uint32_t PDS_OCRAM_CFG_16KB_32KB_CPU_RAM_SLP : 1; /*!< [1] 16~32KB cpu_ram sleep */ + uint32_t PDS_OCRAM_CFG_32KB_48KB_CPU_RAM_SLP : 1; /*!< [2] 32~48KB cpu_ram sleep */ + uint32_t PDS_OCRAM_CFG_48KB_64KB_CPU_RAM_SLP : 1; /*!< [3] 48~64KB cpu_ram sleep */ + uint32_t PDS_OCRAM_CFG_0KB_16KB_CPU_RAM_RET : 1; /*!< [4] 0~16KB cpu_ram retension */ + uint32_t PDS_OCRAM_CFG_16KB_32KB_CPU_RAM_RET : 1; /*!< [5] 16~32KB cpu_ram retension */ + uint32_t PDS_OCRAM_CFG_32KB_48KB_CPU_RAM_RET : 1; /*!< [6] 32~48KB cpu_ram retension */ + uint32_t PDS_OCRAM_CFG_48KB_64KB_CPU_RAM_RET : 1; /*!< [7] 48~64KB cpu_ram retension */ + uint32_t PDS_OCRAM_CFG_RSV : 24; /*!< [31:8]reserve */ +} PDS_OCRAM_CFG_Type; + +/** + * @brief PDS WRAM configuration type definition + */ +typedef struct +{ + uint32_t PDS_WRAM_CFG_0KB_16KB_CPU_RAM_SLP : 1; /*!< [0] 0~16KB cpu_ram sleep */ + uint32_t PDS_WRAM_CFG_16KB_32KB_CPU_RAM_SLP : 1; /*!< [1] 16~32KB cpu_ram sleep */ + uint32_t PDS_WRAM_CFG_32KB_48KB_CPU_RAM_SLP : 1; /*!< [2] 32~48KB cpu_ram sleep */ + uint32_t PDS_WRAM_CFG_48KB_64KB_CPU_RAM_SLP : 1; /*!< [3] 48~64KB cpu_ram sleep */ + uint32_t PDS_WRAM_CFG_64KB_80KB_CPU_RAM_SLP : 1; /*!< [4] 64~80KB cpu_ram sleep */ + uint32_t PDS_WRAM_CFG_80KB_96KB_CPU_RAM_SLP : 1; /*!< [5] 80~96KB cpu_ram sleep */ + uint32_t PDS_WRAM_CFG_96KB_112KB_CPU_RAM_SLP : 1; /*!< [6] 96~112KB cpu_ram sleep */ + uint32_t PDS_WRAM_CFG_112KB_128KB_CPU_RAM_SLP : 1; /*!< [7] 112~128KB cpu_ram sleep */ + uint32_t PDS_WRAM_CFG_128KB_144KB_CPU_RAM_SLP : 1; /*!< [8] 128~144KB cpu_ram sleep */ + uint32_t PDS_WRAM_CFG_144KB_160KB_CPU_RAM_SLP : 1; /*!< [9] 144~160KB cpu_ram sleep */ + uint32_t PDS_WRAM_CFG_0KB_16KB_CPU_RAM_RET : 1; /*!< [10] 0~16KB cpu_ram retension */ + uint32_t PDS_WRAM_CFG_16KB_32KB_CPU_RAM_RET : 1; /*!< [11] 16~32KB cpu_ram retension */ + uint32_t PDS_WRAM_CFG_32KB_48KB_CPU_RAM_RET : 1; /*!< [12] 32~48KB cpu_ram retension */ + uint32_t PDS_WRAM_CFG_48KB_64KB_CPU_RAM_RET : 1; /*!< [13] 48~64KB cpu_ram retension */ + uint32_t PDS_WRAM_CFG_64KB_80KB_CPU_RAM_RET : 1; /*!< [14] 64~80KB cpu_ram retension */ + uint32_t PDS_WRAM_CFG_80KB_96KB_CPU_RAM_RET : 1; /*!< [15] 80~96KB cpu_ram retension */ + uint32_t PDS_WRAM_CFG_96KB_112KB_CPU_RAM_RET : 1; /*!< [16] 96~112KB cpu_ram retension */ + uint32_t PDS_WRAM_CFG_112KB_128KB_CPU_RAM_RET : 1; /*!< [17] 112~128KB cpu_ram retension */ + uint32_t PDS_WRAM_CFG_128KB_144KB_CPU_RAM_RET : 1; /*!< [18] 128~144KB cpu_ram retension */ + uint32_t PDS_WRAM_CFG_144KB_160KB_CPU_RAM_RET : 1; /*!< [19] 144~160KB cpu_ram retension */ + uint32_t PDS_WRAM_CFG_RSV : 22; /*!< [31:20]reserve */ +} PDS_WRAM_CFG_Type; + +/** + * @brief PDS level 0/1/2/3 mode HBN GPIO interrupt trigger type definition + */ +typedef enum { + PDS_AON_GPIO_INT_TRIGGER_SYNC_FALLING_EDGE = 0, /*!< PDS level 0/1/2/3 mode HBN GPIO INT trigger type: sync falling edge trigger */ + PDS_AON_GPIO_INT_TRIGGER_SYNC_RISING_EDGE = 1, /*!< PDS level 0/1/2/3 mode HBN GPIO INT trigger type: sync rising edge trigger */ + PDS_AON_GPIO_INT_TRIGGER_SYNC_LOW_LEVEL = 2, /*!< PDS level 0/1/2/3 mode HBN GPIO INT trigger type: sync low level trigger */ + PDS_AON_GPIO_INT_TRIGGER_SYNC_HIGH_LEVEL = 3, /*!< PDS level 0/1/2/3 mode HBN GPIO INT trigger type: sync high level trigger */ + PDS_AON_GPIO_INT_TRIGGER_SYNC_RISING_FALLING = 7, /*!< PDS level 0/1/2/3 mode HBN GPIO INT trigger type: sync rising+falling edge trigger */ + PDS_AON_GPIO_INT_TRIGGER_ASYNC_FALLING_EDGE = 8, /*!< PDS level 0/1/2/3 mode HBN GPIO INT trigger type: async falling edge trigger */ + PDS_AON_GPIO_INT_TRIGGER_ASYNC_RISING_EDGE = 9, /*!< PDS level 0/1/2/3 mode HBN GPIO INT trigger type: async rising edge trigger */ + PDS_AON_GPIO_INT_TRIGGER_ASYNC_LOW_LEVEL = 10, /*!< PDS level 0/1/2/3 mode HBN GPIO INT trigger type: async low level trigger */ + PDS_AON_GPIO_INT_TRIGGER_ASYNC_HIGH_LEVEL = 11, /*!< PDS level 0/1/2/3 mode HBN GPIO INT trigger type: async high level trigger */ +} PDS_AON_GPIO_INT_Trigger_Type; + +/** + * @brief PDS APP configuration type definition + */ +typedef struct +{ + uint8_t pdsLevel; /*!< PDS level */ + uint8_t turnOffRF; /*!< Wheather turn off RF */ + uint8_t useXtal32k; /*!< Wheather use xtal 32K as 32K clock source,otherwise use rc32k */ + uint8_t pdsAonGpioWakeupSrc; /*!< PDS level 0/1/2/3 mode always on GPIO Wakeup source(HBN wakeup pin) */ + PDS_AON_GPIO_INT_Trigger_Type pdsAonGpioTrigType; /*!< PDS level 0/1/2/3 mode always on GPIO Triger type(HBN wakeup pin) */ + uint8_t powerDownFlash; /*!< Whether power down flash */ + uint8_t turnOffFlashPad; /*!< Whether turn off embedded flash pad */ + uint8_t ocramRetetion; /*!< Whether OCRAM Retention */ + uint8_t turnoffPLL; /*!< Whether trun off PLL */ + uint8_t xtalType; /*!< XTal type, used when user choose turn off PLL, PDS will turn on when exit PDS mode */ + uint8_t flashContRead; /*!< Whether enable flash continue read */ + uint32_t sleepTime; /*!< PDS sleep time */ + SPI_Flash_Cfg_Type *flashCfg; /*!< Flash config pointer, used when power down flash */ + PDS_LDO_LEVEL_Type ldoLevel; /*!< LDO level */ + void (*preCbFun)(void); /*!< Pre callback function */ + void (*postCbFun)(void); /*!< Post callback function */ +} PDS_APP_CFG_Type; + +/*@} end of group PDS_Public_Types */ + +/** @defgroup PDS_Public_Constants + * @{ + */ + +/** @defgroup PDS_GPIO_INT_SET_TYPE + * @{ + */ +#define IS_PDS_GPIO_INT_SET_TYPE(type) (((type) == PDS_GPIO_INT_SET_1_GPIO0_GPIO7) || \ + ((type) == PDS_GPIO_INT_SET_2_GPIO8_16_GPIO22) || \ + ((type) == PDS_GPIO_INT_SET_3_GPIO23_GPIO30) || \ + ((type) == PDS_GPIO_INT_SET_4_GPIO31_GPIO38)) + +/** @defgroup GLB_GPIO_INT_TRIG_TYPE + * @{ + */ +#define IS_PDS_GPIO_INT_TRIG_TYPE(type) (((type) == PDS_GPIO_INT_SYNC_FALLING_EDGE) || \ + ((type) == PDS_GPIO_INT_SYNC_RISING_EDGE) || \ + ((type) == PDS_GPIO_INT_SYNC_LOW_LEVEL) || \ + ((type) == PDS_GPIO_INT_SYNC_HIGH_LEVEL) || \ + ((type) == PDS_GPIO_INT_SYNC_RISING_FALLING_EDGE) || \ + ((type) == PDS_GPIO_INT_ASYNC_FALLING_EDGE) || \ + ((type) == PDS_GPIO_INT_ASYNC_RISING_EDGE) || \ + ((type) == PDS_GPIO_INT_ASYNC_LOW_LEVEL) || \ + ((type) == PDS_GPIO_INT_ASYNC_HIGH_LEVEL)) + +/** @defgroup PDS_LP_SYS_CLK_TYPE + * @{ + */ +#define IS_PDS_LP_SYS_CLK_TYPE(type) (((type) == PDS_LP_SYS_CLK_BCLK_DIV)) + +/** @defgroup PDS_LDO_LEVEL_TYPE + * @{ + */ +#define IS_PDS_LDO_LEVEL_TYPE(type) (((type) == PDS_LDO_LEVEL_0P70V) || \ + ((type) == PDS_LDO_LEVEL_0P75V) || \ + ((type) == PDS_LDO_LEVEL_0P80V) || \ + ((type) == PDS_LDO_LEVEL_0P85V) || \ + ((type) == PDS_LDO_LEVEL_0P90V) || \ + ((type) == PDS_LDO_LEVEL_0P95V) || \ + ((type) == PDS_LDO_LEVEL_1P00V) || \ + ((type) == PDS_LDO_LEVEL_1P05V) || \ + ((type) == PDS_LDO_LEVEL_1P10V) || \ + ((type) == PDS_LDO_LEVEL_1P15V) || \ + ((type) == PDS_LDO_LEVEL_1P20V) || \ + ((type) == PDS_LDO_LEVEL_1P25V) || \ + ((type) == PDS_LDO_LEVEL_1P30V) || \ + ((type) == PDS_LDO_LEVEL_1P35V)) + +/** @defgroup PDS_INT_TYPE + * @{ + */ +#define IS_PDS_INT_TYPE(type) (((type) == PDS_INT_WAKEUP) || \ + ((type) == PDS_INT_RF_DONE) || \ + ((type) == PDS_INT_WIFI_TBTT_SLEEP) || \ + ((type) == PDS_INT_WIFI_TBTT_WAKEUP) || \ + ((type) == PDS_INT_MAX)) + +/** @defgroup PDS_AON_GPIO_INT_TRIGGER_TYPE + * @{ + */ +#define IS_PDS_AON_GPIO_INT_TRIGGER_TYPE(type) (((type) == PDS_AON_GPIO_INT_TRIGGER_SYNC_FALLING_EDGE) || \ + ((type) == PDS_AON_GPIO_INT_TRIGGER_SYNC_RISING_EDGE) || \ + ((type) == PDS_AON_GPIO_INT_TRIGGER_SYNC_LOW_LEVEL) || \ + ((type) == PDS_AON_GPIO_INT_TRIGGER_SYNC_HIGH_LEVEL) || \ + ((type) == PDS_AON_GPIO_INT_TRIGGER_SYNC_RISING_FALLING) || \ + ((type) == PDS_AON_GPIO_INT_TRIGGER_ASYNC_FALLING_EDGE) || \ + ((type) == PDS_AON_GPIO_INT_TRIGGER_ASYNC_RISING_EDGE) || \ + ((type) == PDS_AON_GPIO_INT_TRIGGER_ASYNC_LOW_LEVEL) || \ + ((type) == PDS_AON_GPIO_INT_TRIGGER_ASYNC_HIGH_LEVEL)) + +/*@} end of group PDS_Public_Constants */ + +/** @defgroup PDS_Public_Macros + * @{ + */ +#define PDS_LDO_MIN_PU_CNT (25) /* LDO need 25 cycles to power up */ +#define PDS_WARMUP_LATENCY_CNT (38) /* LDO hw warmup compensation latency cycles */ +#define PDS_INT_MASK_BIT_OFFSET (4) + +/*@} end of group PDS_Public_Macros */ + +/** @defgroup PDS_Public_Functions + * @{ + */ +/*----------*/ +#ifndef BFLB_USE_HAL_DRIVER +void PDS_WAKEUP_IRQHandler(void); +#endif +BL_Err_Type PDS_Set_GPIO_Pad_Pn_Pu_Pd_Ie(GLB_GPIO_Type pad, uint8_t pu, uint8_t pd, uint8_t ie); +BL_Err_Type PDS_Set_GPIO_Pad_IntMask(GLB_GPIO_Type pad, BL_Mask_Type intMask); +BL_Err_Type PDS_Set_GPIO_Pad_IntMode(PDS_GPIO_INT_SET_Type set, PDS_GPIO_INT_TRIG_Type trig); +BL_Err_Type PDS_Set_GPIO_Pad_IntClr(PDS_GPIO_INT_SET_Type set); +BL_Sts_Type PDS_Get_GPIO_Pad_IntStatus(GLB_GPIO_Type pad); +BL_Err_Type PDS_Set_Flash_Pad_Pull_None(SF_Ctrl_Pin_Select pinCfg); +BL_Err_Type PDS_Set_Flash_Pad_Pull_None_Fast(SF_Ctrl_Pin_Select pinCfg); +BL_Err_Type PDS_Set_MCU0_Clock_Enable(void); +BL_Err_Type PDS_Set_MCU0_Clock_Disable(void); +BL_Err_Type PDS_Set_MCU0_Reset_Address(uint32_t addr); +BL_Err_Type PDS_Set_LP_Clock_Enable(void); +BL_Err_Type PDS_Set_LP_Clock_Disable(void); +BL_Err_Type PDS_Set_LP_System_CLK_Div(uint8_t div); +BL_Err_Type PDS_Set_LP_System_CLK(PDS_LP_SYS_CLK_Type clkFreq); +BL_Err_Type PDS_Reset_LP_RTC(void); +BL_Err_Type PDS_Set_LP_RTC_CLK(uint8_t enable, uint16_t div); +BL_Err_Type PDS_Set_LP_Reset_Address(uint32_t addr); +/*----------*/ +BL_Sts_Type PDS_Get_MM_System_Power_On_State(void); +BL_Err_Type PDS_Power_On_MM_System(void); +/*----------*/ +BL_Err_Type PDS_Enable(PDS_CTL_Type *cfg, PDS_CTL4_Type *cfg4, uint32_t pdsSleepCnt); +BL_Err_Type PDS_Force_Config(PDS_CTL2_Type *cfg2, PDS_CTL3_Type *cfg3, PDS_CTL5_Type *cfg5); +BL_Err_Type PDS_RAM_Config(PDS_CTRL_RAM1_Type *ram1Cfg, PDS_CTRL_RAM2_Type *ram2Cfg); +/*----------*/ +BL_Err_Type PDS_Default_Level_Config(PDS_DEFAULT_LV_CFG_Type *defaultLvCfg, PDS_CTRL_RAM1_Type *ram1Cfg, + PDS_CTRL_RAM2_Type *ram2Cfg, uint32_t pdsSleepCnt); +/*----------*/ +BL_Err_Type PDS_IntMask(PDS_INT_Type intType, BL_Mask_Type intMask); +BL_Sts_Type PDS_Get_IntStatus(PDS_INT_Type intType); +BL_Err_Type PDS_IntClear(void); +BL_Err_Type PDS_Int_Callback_Install(PDS_INT_Type intType, intCallback_Type *cbFun); +/*----------*/ +BL_Err_Type PDS_Trim_RC32M(void); +/*----------*/ +BL_Err_Type PDS_Turn_On_USB(uint8_t waitReady); +BL_Err_Type PDS_Turn_Off_USB(void); +BL_Err_Type PDS_Set_USB_Suspend(void); +BL_Err_Type PDS_Set_USB_Resume(void); +/*----------*/ + +/*@} end of group PDS_Public_Functions */ + +/*@} end of group PDS */ + +/*@} end of group BL808_Peripheral_Driver */ + +#endif /* __BL808_PDS_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/bl808_psram_uhs.h b/platforms/bl808_m0/vendor/psram/include/bl808_psram_uhs.h new file mode 100644 index 0000000..740b018 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/bl808_psram_uhs.h @@ -0,0 +1,272 @@ +/** + ****************************************************************************** + * @file bl808_psram_uhs.h + * @version V1.0 + * @date + * @brief This file is the standard driver header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __BL808_PSRAM_UHS_H__ +#define __BL808_PSRAM_UHS_H__ + +#include "psram_uhs_reg.h" +#include "bl808_common.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup PSRAM_UHS + * @{ + */ + +/** @defgroup PSRAM_UHS_Public_Types + * @{ + */ + +/** + * @brief Psram UHS Size + */ +typedef enum { + PSRAM_MEM_SIZE_4MB = 0x03, /*!< PSRAM Memory Size 4M */ + PSRAM_MEM_SIZE_8MB = 0x07, /*!< PSRAM Memory Size 8M */ + PSRAM_MEM_SIZE_16MB = 0x0f, /*!< PSRAM Memory Size 16M */ + PSRAM_MEM_SIZE_32MB = 0x1f, /*!< PSRAM Memory Size 32M */ + PSRAM_MEM_SIZE_64MB = 0x3f, /*!< PSRAM Memory Size 64M */ +} PSRAM_UHS_Mem_Size_Type; + +/** + * @brief Psram UHS Page Type + */ +typedef enum { + PSRAM_PAGE_SIZE_2KB = 0x0B, /*!< PSRAM Page Size 2KB */ + PSRAM_PAGE_SIZE_4KB = 0x16, /*!< PSRAM Page Size 4KB */ +} PSRAM_UHS_Page_Size_Type; + +/** + * @brief Psram UHS Burst Size + */ +typedef enum { + PSRAM_UHS_WARP_BURST_64, /*!< PSRAM Warp Burst Size 64 */ + PSRAM_UHS_WARP_BURST_32, /*!< PSRAM Warp Burst Size 32 */ + PSRAM_UHS_WARP_BURST_16, /*!< PSRAM Warp Burst Size 16 */ + PSRAM_UHS_WARP_BURST_NONE, /*!< PSRAM Warp Burst NONE */ + PSRAM_UHS_WARP_BURST_NO_CHANGE, /*!< Not change this value */ +} PSRAM_UHS_WARP_BURST_Type; + +/** + * @brief Psram UHS Driver Strength + */ +typedef enum { + PSRAM_UHS_DRIVER_ST_34P3_PDPU = 0x1, /*!< 34.3 PD/PU */ + PSRAM_UHS_DRIVER_ST_40_PDPU = 0x2, /*!< 40 PD/PU */ + PSRAM_UHS_DRIVER_ST_48_PDPU = 0x3, /*!< 48 PD/PU */ + PSRAM_UHS_DRIVER_ST_60_PDPU = 0x4, /*!< 60 PD/PU */ + PSRAM_UHS_DRIVER_ST_80_PDPU = 0x6, /*!< 80 PD/PU */ + PSRAM_UHS_DRIVER_ST_34P3_PD_40_PU = 0x9, /*!< 34.3 PD & 40 PU */ + PSRAM_UHS_DRIVER_ST_40_PD_48_PU = 0xa, /*!< 40 PD & 48 PU */ + PSRAM_UHS_DRIVER_ST_34P3_PD_48_PU = 0xb, /*!< 34.3 PD & 48 PU */ + PSRAM_UHS_DRIVER_ST_NO_CHANGE = 0xf, /*!< Not change this value */ +} PSRAM_UHS_DRIVER_ST_Type; + +/** + * @brief Psram UHS LATENCY + */ +typedef enum { + PSRAM_UHS_LATENCY_W10_R20_MAX_FRE_533_MHZ, /*!< MAX freq. = 533 MHz / Write LATENCY=10 / Read LATENCY=20 */ + PSRAM_UHS_LATENCY_W14_R29_MAX_FRE_800_MHZ, /*!< MAX freq. = 800 MHz / Write LATENCY=14 / Read LATENCY=29 */ + PSRAM_UHS_LATENCY_W16_R33_MAX_FRE_933_MHZ, /*!< MAX freq. = 933 MHz / Write LATENCY=16 / Read LATENCY=33 */ + PSRAM_UHS_LATENCY_W18_R37_MAX_FRE_1066_MHZ, /*!< MAX freq. = 1066 MHz / Write LATENCY=18 / Read LATENCY=37 */ + PSRAM_UHS_LATENCY_RESERVED, /*!< Reserved */ + PSRAM_UHS_LATENCY_W6_R16_MAX_FRE_400_MHZ, /*!< MAX freq. = 400 MHz / Write LATENCY=6 / Read LATENCY=16 */ + PSRAM_UHS_LATENCY_W5_R13_MAX_FRE_333_MHZ, /*!< MAX freq. = 333 MHz / Write LATENCY=5 / Read LATENCY=13 */ + PSRAM_UHS_LATENCY_W5_R9_MAX_FRE_200_MHZ, /*!< MAX freq. = 200 MHz / Write LATENCY=5 / Read LATENCY=9 */ + PSRAM_UHS_LATENCY_NO_CHANGE, /*!< Not change this value */ +} PSRAM_UHS_LATENCY_Type; + +/** + * @brief Psram UHS CMD Type + */ +typedef enum { + PSRAM_UHS_CMD_SELF_REFRESH_IN, /*!< pSRAM self-refresh in command */ + PSRAM_UHS_CMD_SELF_REFRESH_EXIT, /*!< pSRAM self-refresh exit command */ + PSRAM_UHS_CMD_GLOBAL_RESET, /*!< pSRAM global reset command */ + PSRAM_UHS_CMD_ZQ_CAL_LONG, /*! */ + PSRAM_UHS_CMD_ZQ_CAL_SHORT, /*!*/ + PSRAM_UHS_CMD_ZQ_CAL_RESET, /*!*/ +} PSRAM_UHS_CMD_Type; + +/** + * @brief PSRAM UHS Temperature + * + */ +typedef enum { + PSRAM_UHS_NORMAL_TEMP, + PSRAM_UHS_HIGH_TEMP, +} PSRAM_UHS_TEMP_Type; + +/** + * @brief PSRAM_UHS_Cfg_Type + */ +typedef struct { + uint32_t pck_freq; /*!< pck frequency unit is MHZ */ + PSRAM_UHS_Mem_Size_Type psramMemSize; /*!< psram uhm memory size */ + PSRAM_UHS_Page_Size_Type psramPageSize; /*!< psram uhm page size */ + PSRAM_UHS_TEMP_Type isHighTem; /*!< auto refresh work temperature */ +} PSRAM_UHS_Cfg_Type; + +/** + * @brief PSRAM_UHS_Phy_Latency_Pra_Type + */ +typedef struct { + uint8_t phy_rl_ana; /*!< phy_rl_ana */ + uint8_t phy_rl_dig; /*!< phy_rl_dig*/ + uint8_t phy_wl_ana; /*!< phy_wl_ana */ + uint8_t phy_wl_dig; /*!< phy_wl_dig*/ + uint8_t phy_wl_dq_ana; /*!< phy_wl_dq_ana */ + uint8_t phy_wl_dq_dig; /*!< phy_wl_dq_dig */ + + uint8_t reg_timer_array_read; /*!< reg_timer_array_read */ + uint8_t reg_timer_array_write; /*!< reg_timer_array_write */ + uint8_t reg_timer_dqs_array_stop; /*!< reg_timer_dqs_array_stop */ + uint8_t reg_timer_dqs_start; /*!< reg_timer_dqs_start */ + + uint8_t reg_timer_dqs_stop; /*!< reg_timer_dqs_stop */ + uint8_t reg_timer_reg_read; /*!< reg_timer_reg_read */ + uint8_t reg_timer_reg_write; /*!< reg_timer_reg_write */ + uint8_t reg_timer_auto_refresh; /*!< reg_timer_auto_refresh */ + + uint16_t reg_timer_global_rst; /*!< reg_timer_global_rst */ + uint8_t reg_timer_self_refresh1_in; /*!< reg_timer_self_refresh1_in */ + uint8_t reg_timer_self_refresh1_exit; /*!< reg_timer_self_refresh1_exit */ + + uint8_t reg_timer_reg_write_busy; /*!< reg_timer_reg_write_busy */ + uint8_t reg_timer_reg_read_busy; /*!< reg_timer_reg_read_busy */ + uint8_t reg_timer_arrary_write_busy; /*!< reg_timer_arrary_write_busy */ + uint8_t reg_timer_arrary_read_busy; /*!< reg_timer_arrary_read_busy */ + + uint8_t en_rx_fe_dly; /*!< en_rx_fe_dly */ + uint8_t odt_sel_dly; /*!< odt_sel_dly */ + + uint8_t reg_trc_cycle; /*!< reg_trc_cycle */ + uint8_t reg_trfc_cycle; /*!< reg_trfc_cycle */ + uint8_t reg_tcphr_cycle; /*!< reg_tcphr_cycle */ + uint8_t reg_tcphw_cycle; /*!< reg_tcphw_cycle */ + +} PSRAM_UHS_Phy_Latency_Pra_Type; + +/** + * @brief PSRAM_UHS_Write_Reg_Cfg_Type + */ +typedef struct { + PSRAM_UHS_DRIVER_ST_Type driver_st; /*!< driver strength */ + PSRAM_UHS_WARP_BURST_Type burst_size; /*!< burst size */ + PSRAM_UHS_LATENCY_Type lentency; /*!< lentency */ +} PSRAM_UHS_Write_Reg_Cfg_Type; + +/*@} end of group PSRAM_UHS_Public_Types */ + +/** @defgroup PSRAM_UHS_Public_Constants + * @{ + */ + +/** @defgroup PSRAM_UHS_MEM_SIZE_TYPE + * @{ + */ +#define IS_PSRAM_UHS_MEM_SIZE_TYPE(type) (((type) == PSRAM_MEM_SIZE_4MB) || \ + ((type) == PSRAM_MEM_SIZE_8MB) || \ + ((type) == PSRAM_MEM_SIZE_16MB) || \ + ((type) == PSRAM_MEM_SIZE_32MB)) + +/** @defgroup PSRAM_UHS_PAGE_SIZE_TYPE + * @{ + */ +#define IS_PSRAM_UHS_PAGE_SIZE_TYPE(type) (((type) == PSRAM_PAGE_SIZE_2KB) || \ + ((type) == PSRAM_PAGE_SIZE_4KB)) + +/** @defgroup PSRAM_UHS_WARP_BURST_TYPE + * @{ + */ +#define IS_PSRAM_UHS_WARP_BURST_TYPE(type) (((type) == PSRAM_UHS_WARP_BURST_64) || \ + ((type) == PSRAM_UHS_WARP_BURST_32) || \ + ((type) == PSRAM_UHS_WARP_BURST_16)) + +/** @defgroup PSRAM_UHS_DRIVER_ST_TYPE + * @{ + */ +#define IS_PSRAM_UHS_DRIVER_ST_TYPE(type) (((type) == PSRAM_UHS_DRIVER_ST_34P3_PUPU) || \ + ((type) == PSRAM_UHS_DRIVER_ST_40_PUPU) || \ + ((type) == PSRAM_UHS_DRIVER_ST_48_PUPU) || \ + ((type) == PSRAM_UHS_DRIVER_ST_60_PUPU) || \ + ((type) == PSRAM_UHS_DRIVER_ST_80_PUPU) || \ + ((type) == PSRAM_UHS_DRIVER_ST_34P3_PD_40_PU) || \ + ((type) == PSRAM_UHS_DRIVER_ST_40_PD_48_PU) || \ + ((type) == PSRAM_UHS_DRIVER_ST_34P3_PD_48_PU)) + +/** @defgroup PSRAM_UHS_LATENCY_TYPE + * @{ + */ +#define IS_PSRAM_UHS_LATENCY_TYPE(type) (((type) == PSRAM_UHS_LATENCY_W10_R20_MAX_FRE_533_MHZ) || \ + ((type) == PSRAM_UHS_LATENCY_W14_R29_MAX_FRE_800_MHZ) || \ + ((type) == PSRAM_UHS_LATENCY_W16_R33_MAX_FRE_933_MHZ) || \ + ((type) == PSRAM_UHS_LATENCY_W18_R37_MAX_FRE_1066_MHZ) || \ + ((type) == PSRAM_UHS_LATENCY_W6_R16_MAX_FRE_400_MHZ) || \ + ((type) == PSRAM_UHS_LATENCY_W5_R13_MAX_FRE_333_MHZ) || \ + ((type) == PSRAM_UHS_LATENCY_W5_R9_MAX_FRE_200_MHZ)) +/** @defgroup PSRAM_UHS_CMD_Type + * @{ + */ +#define IS_PSRAM_UHS_CMD_TYPE(type) (((type) == PSRAM_UHS_CMD_SELF_REFRESH_IN) || \ + ((type) == PSRAM_UHS_CMD_SELF_REFRESH_EXIT) || \ + ((type) == PSRAM_UHS_CMD_GLOBAL_RESET) + +/*@} end of group PSRAM_UHS_Public_Constants */ + +/** @defgroup PSRAM_UHS_Public_Macros + * @{ + */ + +/*@} end of group PSRAM_UHS_Public_Macros */ + +/** @defgroup PSRAM_UHS_Public_Functions + * @{ + */ +void Psram_UHS_Init(PSRAM_UHS_Cfg_Type *cfg); +int PSram_UHS_Read_Reg(uint32_t reg_addr, uint8_t *regVal); +int PSram_UHS_Write_Reg(PSRAM_UHS_Write_Reg_Cfg_Type *regCfg); +int PSram_UHS_Construct_Cmd(PSRAM_UHS_CMD_Type cmd); +void Psram_UHS_x16_Init(uint32_t uhs_pll_clk); +/*@} end of group PSRAM_UHS_Public_Functions */ + +/*@} end of group PSRAM_UHS */ + +/*@} end of group BL808_Peripheral_Driver */ + +#endif /* __BL808_PSRAM_UHS_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/bl808_sf_cfg.h b/platforms/bl808_m0/vendor/psram/include/bl808_sf_cfg.h new file mode 100644 index 0000000..ee315f7 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/bl808_sf_cfg.h @@ -0,0 +1,106 @@ +/** + ****************************************************************************** + * @file bl808_sf_cfg.h + * @version V1.0 + * @date + * @brief This file is the standard driver header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __BL808_SF_CFG_H__ +#define __BL808_SF_CFG_H__ + +#include "string.h" +#include "bl808_glb.h" +#include "bl808_glb_gpio.h" +#include "bl808_sflash.h" +#include "bl808_sf_ctrl.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup SF_CFG + * @{ + */ + +/** @defgroup SF_CFG_Public_Types + * @{ + */ + +/*@} end of group SF_CFG_Public_Types */ + +/** @defgroup SF_CFG_Public_Constants + * @{ + */ + +/*@} end of group SF_CFG_Public_Constants */ + +/** @defgroup SF_CFG_Public_Macros + * @{ + */ +/* Flash option sf2 */ +/* Flash CLK */ +#define BFLB_EXTFLASH_CLK0_GPIO GLB_GPIO_PIN_34 +/* FLASH CS */ +#define BFLB_EXTFLASH_CS0_GPIO GLB_GPIO_PIN_35 +/* FLASH DATA */ +#define BFLB_EXTFLASH_DATA00_GPIO GLB_GPIO_PIN_36 +#define BFLB_EXTFLASH_DATA10_GPIO GLB_GPIO_PIN_37 +#define BFLB_EXTFLASH_DATA20_GPIO GLB_GPIO_PIN_38 +#define BFLB_EXTFLASH_DATA30_GPIO GLB_GPIO_PIN_39 +#define BFLB_FLASH_ID_VALID_FLAG 0x80000000 +#define BFLB_FLASH_ID_VALID_MASK 0x7FFFFFFF + +/*@} end of group SF_CFG_Public_Macros */ + +/** @defgroup SF_CFG_Public_Functions + * @{ + */ +BL_Err_Type SF_Cfg_Get_Flash_Cfg_Need_Lock(uint32_t flashID, SPI_Flash_Cfg_Type *pFlashCfg, + uint8_t group, SF_Ctrl_Bank_Select bank); +BL_Err_Type SF_Cfg_Get_Flash_Cfg_Need_Lock_Ext(uint32_t flashID, SPI_Flash_Cfg_Type *pFlashCfg, + uint8_t group, SF_Ctrl_Bank_Select bank); +BL_Err_Type SF_Cfg_Init_Flash_Gpio(SF_Ctrl_Pin_Select flashPinCfg, uint8_t restoreDefault); +BL_Err_Type SF_Cfg_Init_Ext_Flash_Gpio(uint8_t extFlashPin); +BL_Err_Type SF_Cfg_Deinit_Ext_Flash_Gpio(uint8_t extFlashPin); +uint32_t SF_Cfg_Flash_Identify(uint8_t callFromFlash, uint8_t flashPinCfg, uint8_t restoreDefault, + SPI_Flash_Cfg_Type *pFlashCfg, uint8_t group, SF_Ctrl_Bank_Select bank); +uint32_t SF_Cfg_Flash_Identify_Ext(uint8_t callFromFlash, uint8_t flashPinCfg, uint8_t restoreDefault, + SPI_Flash_Cfg_Type *pFlashCfg, uint8_t group, SF_Ctrl_Bank_Select bank); +BL_Err_Type SF_Cfg_Flash_Init(SF_Ctrl_Pin_Select sel, const SF_Ctrl_Cfg_Type *pSfCtrlCfg, const SF_Ctrl_Bank2_Cfg *pBank2Cfg); +BL_Err_Type SF_Cfg_Sbus2_Flash_Init(SF_Ctrl_Pin_Select sel, const SF_Ctrl_Bank2_Cfg *pBank2Cfg); + +/*@} end of group SF_CFG_Public_Functions */ + +/*@} end of group SF_CFG */ + +/*@} end of group BL808_Peripheral_Driver */ + +#endif /* __BL808_SF_CFG_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/bl808_sf_ctrl.h b/platforms/bl808_m0/vendor/psram/include/bl808_sf_ctrl.h new file mode 100644 index 0000000..eea942a --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/bl808_sf_ctrl.h @@ -0,0 +1,470 @@ +/** + ****************************************************************************** + * @file bl808_sf_ctrl.h + * @version V1.0 + * @date + * @brief This file is the standard driver header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __BL808_SF_CTRL_H__ +#define __BL808_SF_CTRL_H__ + +#include "sf_ctrl_reg.h" +#include "bl808_common.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup SF_CTRL + * @{ + */ + +/** @defgroup SF_CTRL_Public_Types + * @{ + */ + +/** + * @brief Serial flash pad type definition + */ +typedef enum { + SF_CTRL_PAD1, /*!< SF Ctrl pad 1 */ + SF_CTRL_PAD2, /*!< SF Ctrl pad 2 */ + SF_CTRL_PAD3, /*!< SF Ctrl pad 3 */ +} SF_Ctrl_Pad_Type; + +/** + * @brief Serial flash config pin select type definition + */ +typedef enum { + SF_IO_EMB_SWAP_IO0_IO3 = 0x0, /*!< SF select embedded flash swap io0 with io3 */ + SF_IO_EMB_SWAP_DUAL_IO0_IO3 = 0x1, /*!< SF select embedded flash swap dual io0 with io3 */ + SF_IO_EMB_SWAP_NONE = 0x2, /*!< SF select embedded flash no swap */ + SF_IO_EMB_SWAP_NONE_DUAL_IO0 = 0x3, /*!< SF select embedded flash no swap and use dual io0 */ + SF_IO_EXT_SF2 = 0x4, /*!< SF select external flash SF2 use gpio34-39 */ + SF_IO_EMB_SWAP_IO0_IO3_AND_EXT_SF2 = 0x14, /*!< SF select embedded flash swap io0 with io3 and external SF2 use gpio34-39 */ + SF_IO_EMB_SWAP_DUAL_IO0_IO3_AND_EXT_SF2 = 0x15, /*!< SF select embedded flash swap dual io0 with io3 and external SF2 use gpio34-39 */ + SF_IO_EMB_SWAP_NONE_AND_EXT_SF2 = 0x16, /*!< SF select embedded flash no swap and external SF2 use gpio34-39 */ + SF_IO_EMB_SWAP_NONE_DUAL_IO0_AND_EXT_SF2 = 0x17, /*!< SF select embedded flash no swap, use dual io0 and external SF2 use gpio34-39 */ +} SF_Ctrl_Pin_Select; + +/** + * @brief Serial flash select bank control type definition + */ +typedef enum { + SF_CTRL_FLASH_BANK0, /*!< SF Ctrl select flash bank0 */ + SF_CTRL_FLASH_BANK1, /*!< SF Ctrl select flash bank1 */ +} SF_Ctrl_Bank_Select; + +/** + * @brief Serial flash controller wrap mode type definition + */ +typedef enum { + SF_CTRL_WRAP_MODE_0, /*!< Cmds bypass wrap commands to macro, original mode */ + SF_CTRL_WRAP_MODE_1, /*!< Cmds handle wrap commands, original mode */ + SF_CTRL_WRAP_MODE_2, /*!< Cmds bypass wrap commands to macro, cmds force wrap16*4 splitted into two wrap8*4 */ + SF_CTRL_WRAP_MODE_3, /*!< Cmds handle wrap commands, cmds force wrap16*4 splitted into two wrap8*4 */ +} SF_Ctrl_Wrap_Mode; + +/** + * @brief Serail flash controller wrap mode len type definition + */ +typedef enum { + SF_CTRL_WRAP_LEN_8, /*!< SF Ctrl wrap length: 8 */ + SF_CTRL_WRAP_LEN_16, /*!< SF Ctrl wrap length: 16 */ + SF_CTRL_WRAP_LEN_32, /*!< SF Ctrl wrap length: 32 */ + SF_CTRL_WRAP_LEN_64, /*!< SF Ctrl wrap length: 64 */ + SF_CTRL_WRAP_LEN_128, /*!< SF Ctrl wrap length: 128 */ + SF_CTRL_WRAP_LEN_256, /*!< SF Ctrl wrap length: 256 */ + SF_CTRL_WRAP_LEN_512, /*!< SF Ctrl wrap length: 512 */ + SF_CTRL_WRAP_LEN_1024, /*!< SF Ctrl wrap length: 1024 */ + SF_CTRL_WRAP_LEN_2048, /*!< SF Ctrl wrap length: 2048 */ + SF_CTRL_WRAP_LEN_4096, /*!< SF Ctrl wrap length: 4096 */ +} SF_Ctrl_Wrap_Len_Type; + +/** + * @brief Serail flash controller memory remap type define + */ +typedef enum { + SF_CTRL_ORIGINAL_MEMORY_MAP, /*!< Remap none, use two addr map when use dual flash */ + SF_CTRL_REMAP_16MB, /*!< Remap HADDR>16MB region to psram port HADDR[24] -> HADDR[28] */ + SF_CTRL_REMAP_8MB, /*!< Remap HADDR>8MB region to psram port HADDR[23] -> HADDR[28] */ + SF_CTRL_REMAP_4MB, /*!< Remap HADDR>4MB region to psram port HADDR[22] -> HADDR[28] */ +} SF_Ctrl_Remap_Type; + +/** + * @brief Serial flash controller owner type definition + */ +typedef enum { + SF_CTRL_OWNER_SAHB, /*!< System AHB bus control serial flash controller */ + SF_CTRL_OWNER_IAHB, /*!< I-Code AHB bus control serial flash controller */ +} SF_Ctrl_Owner_Type; + +/** + * @brief Read and write type definition + */ +typedef enum { + SF_CTRL_READ, /*!< Serail flash read command flag */ + SF_CTRL_WRITE, /*!< Serail flash write command flag */ +} SF_Ctrl_RW_Type; + +/** + * @brief Serail flash interface IO type definition + */ +typedef enum { + SF_CTRL_NIO_MODE, /*!< Normal IO mode define */ + SF_CTRL_DO_MODE, /*!< Dual Output mode define */ + SF_CTRL_QO_MODE, /*!< Quad Output mode define */ + SF_CTRL_DIO_MODE, /*!< Dual IO mode define */ + SF_CTRL_QIO_MODE, /*!< Quad IO mode define */ +} SF_Ctrl_IO_Type; + +/** + * @brief Serail flash controller interface mode type definition + */ +typedef enum { + SF_CTRL_SPI_MODE, /*!< SPI mode define */ + SF_CTRL_QPI_MODE, /*!< QPI mode define */ +} SF_Ctrl_Mode_Type; + +/** + * @brief Serail flash controller command mode type definition + */ +typedef enum { + SF_CTRL_CMD_1_LINE, /*!< Command in one line mode */ + SF_CTRL_CMD_4_LINES, /*!< Command in four lines mode */ +} SF_Ctrl_Cmd_Mode_Type; + +/** + * @brief Serail flash controller address mode type definition + */ +typedef enum { + SF_CTRL_ADDR_1_LINE, /*!< Address in one line mode */ + SF_CTRL_ADDR_2_LINES, /*!< Address in two lines mode */ + SF_CTRL_ADDR_4_LINES, /*!< Address in four lines mode */ +} SF_Ctrl_Addr_Mode_Type; + +/** + * @brief Serail flash controller dummy mode type definition + */ +typedef enum { + SF_CTRL_DUMMY_1_LINE, /*!< Dummy in one line mode */ + SF_CTRL_DUMMY_2_LINES, /*!< Dummy in two lines mode */ + SF_CTRL_DUMMY_4_LINES, /*!< Dummy in four lines mode */ +} SF_Ctrl_Dmy_Mode_Type; + +/** + * @brief Serail flash controller data mode type definition + */ +typedef enum { + SF_CTRL_DATA_1_LINE, /*!< Data in one line mode */ + SF_CTRL_DATA_2_LINES, /*!< Data in two lines mode */ + SF_CTRL_DATA_4_LINES, /*!< Data in four lines mode */ +} SF_Ctrl_Data_Mode_Type; + +/** + * @brief Serail flash controller AES mode type definition + */ +typedef enum { + SF_CTRL_AES_CTR_MODE, /*!< Serail flash AES CTR mode */ + SF_CTRL_AES_XTS_MODE, /*!< Serail flash AES XTS mode */ +} SF_Ctrl_AES_Mode_Type; + +/** + * @brief Serail flash controller AES key len type definition + */ +typedef enum { + SF_CTRL_AES_128BITS, /*!< Serail flash AES key 128 bits length */ + SF_CTRL_AES_256BITS, /*!< Serail flash AES key 256 bits length */ + SF_CTRL_AES_192BITS, /*!< Serail flash AES key 192 bits length */ + SF_CTRL_AES_128BITS_DOUBLE_KEY, /*!< Serail flash AES key 128 bits length double key */ +} SF_Ctrl_AES_Key_Type; + +/** + * @brief Serail flash controller configuration structure type definition + */ +typedef struct +{ + SF_Ctrl_Owner_Type owner; /*!< Sflash interface bus owner */ + BL_Fun_Type en32bAddr; /*!< Sflash enable 32-bits address */ + uint8_t clkDelay; /*!< Clock count for read due to pad delay */ + uint8_t clkInvert; /*!< Clock invert */ + uint8_t rxClkInvert; /*!< RX clock invert */ + uint8_t doDelay; /*!< Data out delay */ + uint8_t diDelay; /*!< Data in delay */ + uint8_t oeDelay; /*!< Output enable delay */ +} SF_Ctrl_Cfg_Type; + +/** + * @brief SF Ctrl bank2 controller configuration structure type definition + */ +typedef struct +{ + BL_Fun_Type sbus2Select; /*!< Select sbus2 as 2nd flash controller */ + BL_Fun_Type bank2RxClkInvertSrc; /*!< Select bank2 rx clock invert source */ + BL_Fun_Type bank2RxClkInvertSel; /*!< Select inveted bank2 rx clock */ + BL_Fun_Type bank2DelaySrc; /*!< Select bank2 read delay source */ + uint8_t bank2ClkDelay; /*!< Bank2 read delay cycle = n + 1 */ + uint8_t doDelay; /*!< Data out delay */ + uint8_t diDelay; /*!< Data in delay */ + uint8_t oeDelay; /*!< Output enable delay */ + SF_Ctrl_Remap_Type remap; /*!< Select dual flash memory remap set */ + uint8_t remapLock; /*!< Select memory remap lock */ +} SF_Ctrl_Bank2_Cfg; + +/** + * @brief SF Ctrl cmds configuration structure type definition + */ +typedef struct +{ + uint8_t ackLatency; /*!< SF Ctrl ack latency cycles */ + BL_Fun_Type cmdsCoreEn; /*!< SF Ctrl cmds core enable */ + BL_Fun_Type cmdsEn; /*!< SF Ctrl cmds enable */ + SF_Ctrl_Wrap_Mode cmdsWrapMode; /*!< SF Ctrl cmds wrap mode */ + SF_Ctrl_Wrap_Len_Type cmdsWrapLen; /*!< SF Ctrl cmds wrap length */ +} SF_Ctrl_Cmds_Cfg; + +/** + * @brief Serail flash command configuration structure type definition + */ +typedef struct +{ + uint8_t rwFlag; /*!< Read write flag */ + SF_Ctrl_Cmd_Mode_Type cmdMode; /*!< Command mode */ + SF_Ctrl_Addr_Mode_Type addrMode; /*!< Address mode */ + uint8_t addrSize; /*!< Address size */ + uint8_t dummyClks; /*!< Dummy clocks */ + SF_Ctrl_Dmy_Mode_Type dummyMode; /*!< Dummy mode */ + SF_Ctrl_Data_Mode_Type dataMode; /*!< Data mode */ + uint8_t rsv[1]; /*!< */ + uint32_t nbData; /*!< Transfer number of bytes */ + uint32_t cmdBuf[2]; /*!< Command buffer */ +} SF_Ctrl_Cmd_Cfg_Type; + +/*@} end of group SF_CTRL_Public_Types */ + +/** @defgroup SF_CTRL_Public_Constants + * @{ + */ + +/** @defgroup SF_CTRL_PAD_TYPE + * @{ + */ +#define IS_SF_CTRL_PAD_TYPE(type) (((type) == SF_CTRL_PAD1) || \ + ((type) == SF_CTRL_PAD2) || \ + ((type) == SF_CTRL_PAD3)) + +/** @defgroup SF_CTRL_PIN_SELECT + * @{ + */ +#define IS_SF_CTRL_PIN_SELECT(type) (((type) == SF_IO_EMB_SWAP_IO0_IO3) || \ + ((type) == SF_IO_EMB_SWAP_DUAL_IO0_IO3) || \ + ((type) == SF_IO_EMB_SWAP_NONE) || \ + ((type) == SF_IO_EMB_SWAP_NONE_DUAL_IO0) || \ + ((type) == SF_IO_EXT_SF2) || \ + ((type) == SF_IO_EMB_SWAP_IO0_IO3_AND_EXT_SF2) || \ + ((type) == SF_IO_EMB_SWAP_DUAL_IO0_IO3_AND_EXT_SF2) || \ + ((type) == SF_IO_EMB_SWAP_NONE_AND_EXT_SF2) || \ + ((type) == SF_IO_EMB_SWAP_NONE_DUAL_IO0_AND_EXT_SF2)) + +/** @defgroup SF_CTRL_BANK_SELECT + * @{ + */ +#define IS_SF_CTRL_BANK_SELECT(type) (((type) == SF_CTRL_FLASH_BANK0) || \ + ((type) == SF_CTRL_FLASH_BANK1)) + +/** @defgroup SF_CTRL_WRAP_MODE + * @{ + */ +#define IS_SF_CTRL_WRAP_MODE(type) (((type) == SF_CTRL_WRAP_MODE_0) || \ + ((type) == SF_CTRL_WRAP_MODE_1) || \ + ((type) == SF_CTRL_WRAP_MODE_2) || \ + ((type) == SF_CTRL_WRAP_MODE_3)) + +/** @defgroup SF_CTRL_WRAP_LEN_TYPE + * @{ + */ +#define IS_SF_CTRL_WRAP_LEN_TYPE(type) (((type) == SF_CTRL_WRAP_LEN_8) || \ + ((type) == SF_CTRL_WRAP_LEN_16) || \ + ((type) == SF_CTRL_WRAP_LEN_32) || \ + ((type) == SF_CTRL_WRAP_LEN_64) || \ + ((type) == SF_CTRL_WRAP_LEN_128) || \ + ((type) == SF_CTRL_WRAP_LEN_256) || \ + ((type) == SF_CTRL_WRAP_LEN_512) || \ + ((type) == SF_CTRL_WRAP_LEN_1024) || \ + ((type) == SF_CTRL_WRAP_LEN_2048) || \ + ((type) == SF_CTRL_WRAP_LEN_4096)) + +/** @defgroup SF_CTRL_REMAP_TYPE + * @{ + */ +#define IS_SF_CTRL_REMAP_TYPE(type) (((type) == SF_CTRL_ORIGINAL_MEMORY_MAP) || \ + ((type) == SF_CTRL_REMAP_16MB) || \ + ((type) == SF_CTRL_REMAP_8MB) || \ + ((type) == SF_CTRL_REMAP_4MB)) + +/** @defgroup SF_CTRL_OWNER_TYPE + * @{ + */ +#define IS_SF_CTRL_OWNER_TYPE(type) (((type) == SF_CTRL_OWNER_SAHB) || \ + ((type) == SF_CTRL_OWNER_IAHB)) + +/** @defgroup SF_CTRL_RW_TYPE + * @{ + */ +#define IS_SF_CTRL_RW_TYPE(type) (((type) == SF_CTRL_READ) || \ + ((type) == SF_CTRL_WRITE)) + +/** @defgroup SF_CTRL_IO_TYPE + * @{ + */ +#define IS_SF_CTRL_IO_TYPE(type) (((type) == SF_CTRL_NIO_MODE) || \ + ((type) == SF_CTRL_DO_MODE) || \ + ((type) == SF_CTRL_QO_MODE) || \ + ((type) == SF_CTRL_DIO_MODE) || \ + ((type) == SF_CTRL_QIO_MODE)) + +/** @defgroup SF_CTRL_MODE_TYPE + * @{ + */ +#define IS_SF_CTRL_MODE_TYPE(type) (((type) == SF_CTRL_SPI_MODE) || \ + ((type) == SF_CTRL_QPI_MODE)) + +/** @defgroup SF_CTRL_CMD_MODE_TYPE + * @{ + */ +#define IS_SF_CTRL_CMD_MODE_TYPE(type) (((type) == SF_CTRL_CMD_1_LINE) || \ + ((type) == SF_CTRL_CMD_4_LINES)) + +/** @defgroup SF_CTRL_ADDR_MODE_TYPE + * @{ + */ +#define IS_SF_CTRL_ADDR_MODE_TYPE(type) (((type) == SF_CTRL_ADDR_1_LINE) || \ + ((type) == SF_CTRL_ADDR_2_LINES) || \ + ((type) == SF_CTRL_ADDR_4_LINES)) + +/** @defgroup SF_CTRL_DMY_MODE_TYPE + * @{ + */ +#define IS_SF_CTRL_DMY_MODE_TYPE(type) (((type) == SF_CTRL_DUMMY_1_LINE) || \ + ((type) == SF_CTRL_DUMMY_2_LINES) || \ + ((type) == SF_CTRL_DUMMY_4_LINES)) + +/** @defgroup SF_CTRL_DATA_MODE_TYPE + * @{ + */ +#define IS_SF_CTRL_DATA_MODE_TYPE(type) (((type) == SF_CTRL_DATA_1_LINE) || \ + ((type) == SF_CTRL_DATA_2_LINES) || \ + ((type) == SF_CTRL_DATA_4_LINES)) + +/** @defgroup SF_CTRL_AES_MODE_TYPE + * @{ + */ +#define IS_SF_CTRL_AES_MODE_TYPE(type) (((type) == SF_CTRL_AES_CTR_MODE) || \ + ((type) == SF_CTRL_AES_XTS_MODE)) + +/** @defgroup SF_CTRL_AES_KEY_TYPE + * @{ + */ +#define IS_SF_CTRL_AES_KEY_TYPE(type) (((type) == SF_CTRL_AES_128BITS) || \ + ((type) == SF_CTRL_AES_256BITS) || \ + ((type) == SF_CTRL_AES_192BITS) || \ + ((type) == SF_CTRL_AES_128BITS_DOUBLE_KEY)) + +/*@} end of group SF_CTRL_Public_Constants */ + +/** @defgroup SF_CTRL_Public_Macros + * @{ + */ +#define SF_CTRL_NO_ADDRESS 0xFFFFFFFF +#define NOR_FLASH_CTRL_BUF_SIZE 256 +#define NAND_FLASH_CTRL_BUF_SIZE 512 + +/*@} end of group SF_CTRL_Public_Macros */ + +/** @defgroup SF_CTRL_Public_Functions + * @{ + */ +#ifndef BFLB_USE_HAL_DRIVER +void SF_Ctrl_IRQHandler(void); +#endif +void SF_Ctrl_Enable(const SF_Ctrl_Cfg_Type *cfg); +void SF_Ctrl_Bank2_Enable(const SF_Ctrl_Bank2_Cfg *bank2Cfg); +void SF_Ctrl_Set_IO_Delay(SF_Ctrl_Pad_Type pad, uint8_t doDelay, uint8_t diDelay, uint8_t oeDelay); +void SF_Ctrl_Sbus2_Hold_Sram(void); +void SF_Ctrl_Sbus2_Release_Sram(void); +BL_Sts_Type SF_Ctrl_Is_Sbus2_Enable(void); +void SF_Ctrl_Sbus2_Replace(SF_Ctrl_Pad_Type pad); +void SF_Ctrl_Sbus2_Revoke_replace(void); +void SF_Ctrl_Sbus2_Set_Delay(uint8_t clkDelay, uint8_t rxClkInvert); +void SF_Ctrl_32bits_Addr_En(BL_Fun_Type en32BitsAddr); +uint8_t SF_Ctrl_Get_Clock_Delay(void); +void SF_Ctrl_Set_Clock_Delay(uint8_t delay); +uint8_t SF_Ctrl_Get_Wrap_Queue_Value(void); +void SF_Ctrl_Cmds_Set(SF_Ctrl_Cmds_Cfg *cmdsCfg, SF_Ctrl_Bank_Select bank); +void SF_Ctrl_Remap_Set(SF_Ctrl_Remap_Type remap, uint8_t lock); +void SF_Ctrl_Select_Pad(SF_Ctrl_Pin_Select sel); +void SF_Ctrl_Sbus_Select_Bank(SF_Ctrl_Bank_Select bank); +void SF_Ctrl_Set_Owner(SF_Ctrl_Owner_Type owner); +void SF_Ctrl_Disable(void); +void SF_Ctrl_AES_Enable_BE(void); +void SF_Ctrl_AES_Enable_LE(void); +void SF_Ctrl_AES_Set_Region(uint8_t region, uint8_t enable, uint8_t hwKey, uint32_t startAddr, uint32_t endAddr, + uint8_t locked); +void SF_Ctrl_AES_Set_Key(uint8_t region, uint8_t *key, SF_Ctrl_AES_Key_Type keyType); +void SF_Ctrl_AES_Set_Key_BE(uint8_t region, uint8_t *key, SF_Ctrl_AES_Key_Type keyType); +void SF_Ctrl_AES_XTS_Set_Key(uint8_t region, uint8_t *key, SF_Ctrl_AES_Key_Type keyType); +void SF_Ctrl_AES_Set_Key_BE(uint8_t region, uint8_t *key, SF_Ctrl_AES_Key_Type keyType); +void SF_Ctrl_AES_XTS_Set_Key(uint8_t region, uint8_t *key, SF_Ctrl_AES_Key_Type keyType); +void SF_Ctrl_AES_XTS_Set_Key_BE(uint8_t region, uint8_t *key, SF_Ctrl_AES_Key_Type keyType); +void SF_Ctrl_AES_Set_IV(uint8_t region, uint8_t *iv, uint32_t addrOffset); +void SF_Ctrl_AES_XTS_Set_IV(uint8_t region, uint8_t *iv, uint32_t addrOffset); +void SF_Ctrl_AES_Set_IV_BE(uint8_t region, uint8_t *iv, uint32_t addrOffset); +void SF_Ctrl_AES_XTS_Set_IV_BE(uint8_t region, uint8_t *iv, uint32_t addrOffset); +void SF_Ctrl_AES_Set_Mode(SF_Ctrl_AES_Mode_Type mode); +void SF_Ctrl_AES_Enable(void); +void SF_Ctrl_AES_Disable(void); +BL_Sts_Type SF_Ctrl_Is_AES_Enable(void); +void SF_Ctrl_Set_Flash_Image_Offset(uint32_t addrOffset, uint8_t group, SF_Ctrl_Bank_Select bank); +uint32_t SF_Ctrl_Get_Flash_Image_Offset(uint8_t group, SF_Ctrl_Bank_Select bank); +void SF_Ctrl_Lock_Flash_Image_Offset(uint8_t lock); +void SF_Ctrl_SendCmd(SF_Ctrl_Cmd_Cfg_Type *cfg); +void SF_Ctrl_Disable_Wrap_Access(uint8_t disable); +void SF_Ctrl_Flash_Read_Icache_Set(SF_Ctrl_Cmd_Cfg_Type *cfg, uint8_t cmdValid); +void SF_Ctrl_Flash2_Read_Icache_Set(SF_Ctrl_Cmd_Cfg_Type *cfg, uint8_t cmdValid); +BL_Sts_Type SF_Ctrl_GetBusyState(void); + +/*@} end of group SF_CTRL_Public_Functions */ + +/*@} end of group SF_CTRL */ + +/*@} end of group BL808_Peripheral_Driver */ + +#endif /* __BL808_SF_CTRL_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/bl808_sflash.h b/platforms/bl808_m0/vendor/psram/include/bl808_sflash.h new file mode 100644 index 0000000..51f9bc2 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/bl808_sflash.h @@ -0,0 +1,218 @@ +/** + ****************************************************************************** + * @file bl808_sflah.h + * @version V1.0 + * @date + * @brief This file is the standard driver header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __BL808_SFLAH_H__ +#define __BL808_SFLAH_H__ + +#include "bl808_common.h" +#include "bl808_sf_ctrl.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup SFLAH + * @{ + */ + +/** @defgroup SFLAH_Public_Types + * @{ + */ + +/** + * @brief Serial flash configuration structure type definition + */ +typedef struct +{ + uint8_t ioMode; /*!< Serail flash interface mode,bit0-3:IF mode,bit4:unwrap,bit5:32-bits addr mode support */ + uint8_t cReadSupport; /*!< Support continuous read mode,bit0:continuous read mode support,bit1:read mode cfg */ + uint8_t clkDelay; /*!< SPI clock delay,bit0-3:delay,bit4-6:pad delay */ + uint8_t clkInvert; /*!< SPI clock phase invert,bit0:clck invert,bit1:rx invert,bit2-4:pad delay,bit5-7:pad delay */ + uint8_t resetEnCmd; /*!< Flash enable reset command */ + uint8_t resetCmd; /*!< Flash reset command */ + uint8_t resetCreadCmd; /*!< Flash reset continuous read command */ + uint8_t resetCreadCmdSize; /*!< Flash reset continuous read command size */ + uint8_t jedecIdCmd; /*!< JEDEC ID command */ + uint8_t jedecIdCmdDmyClk; /*!< JEDEC ID command dummy clock */ + uint8_t enter32BitsAddrCmd; /*!< Enter 32-bits addr command */ + uint8_t exit32BitsAddrCmd; /*!< Exit 32-bits addr command */ + uint8_t sectorSize; /*!< *1024bytes */ + uint8_t mid; /*!< Manufacturer ID */ + uint16_t pageSize; /*!< Page size */ + uint8_t chipEraseCmd; /*!< Chip erase cmd */ + uint8_t sectorEraseCmd; /*!< Sector erase command */ + uint8_t blk32EraseCmd; /*!< Block 32K erase command,some Micron not support */ + uint8_t blk64EraseCmd; /*!< Block 64K erase command */ + uint8_t writeEnableCmd; /*!< Need before every erase or program */ + uint8_t pageProgramCmd; /*!< Page program cmd */ + uint8_t qpageProgramCmd; /*!< QIO page program cmd */ + uint8_t qppAddrMode; /*!< QIO page program address mode */ + uint8_t fastReadCmd; /*!< Fast read command */ + uint8_t frDmyClk; /*!< Fast read command dummy clock */ + uint8_t qpiFastReadCmd; /*!< QPI fast read command */ + uint8_t qpiFrDmyClk; /*!< QPI fast read command dummy clock */ + uint8_t fastReadDoCmd; /*!< Fast read dual output command */ + uint8_t frDoDmyClk; /*!< Fast read dual output command dummy clock */ + uint8_t fastReadDioCmd; /*!< Fast read dual io comamnd */ + uint8_t frDioDmyClk; /*!< Fast read dual io command dummy clock */ + uint8_t fastReadQoCmd; /*!< Fast read quad output comamnd */ + uint8_t frQoDmyClk; /*!< Fast read quad output comamnd dummy clock */ + uint8_t fastReadQioCmd; /*!< Fast read quad io comamnd */ + uint8_t frQioDmyClk; /*!< Fast read quad io comamnd dummy clock */ + uint8_t qpiFastReadQioCmd; /*!< QPI fast read quad io comamnd */ + uint8_t qpiFrQioDmyClk; /*!< QPI fast read QIO dummy clock */ + uint8_t qpiPageProgramCmd; /*!< QPI program command */ + uint8_t writeVregEnableCmd; /*!< Enable write reg */ + uint8_t wrEnableIndex; /*!< Write enable register index */ + uint8_t qeIndex; /*!< Quad mode enable register index */ + uint8_t busyIndex; /*!< Busy status register index */ + uint8_t wrEnableBit; /*!< Write enable bit pos */ + uint8_t qeBit; /*!< Quad enable bit pos */ + uint8_t busyBit; /*!< Busy status bit pos */ + uint8_t wrEnableWriteRegLen; /*!< Register length of write enable */ + uint8_t wrEnableReadRegLen; /*!< Register length of write enable status */ + uint8_t qeWriteRegLen; /*!< Register length of contain quad enable */ + uint8_t qeReadRegLen; /*!< Register length of contain quad enable status */ + uint8_t releasePowerDown; /*!< Release power down command */ + uint8_t busyReadRegLen; /*!< Register length of contain busy status */ + uint8_t readRegCmd[4]; /*!< Read register command buffer */ + uint8_t writeRegCmd[4]; /*!< Write register command buffer */ + uint8_t enterQpi; /*!< Enter qpi command */ + uint8_t exitQpi; /*!< Exit qpi command */ + uint8_t cReadMode; /*!< Config data for continuous read mode */ + uint8_t cRExit; /*!< Config data for exit continuous read mode */ + uint8_t burstWrapCmd; /*!< Enable burst wrap command */ + uint8_t burstWrapCmdDmyClk; /*!< Enable burst wrap command dummy clock */ + uint8_t burstWrapDataMode; /*!< Data and address mode for this command */ + uint8_t burstWrapData; /*!< Data to enable burst wrap */ + uint8_t deBurstWrapCmd; /*!< Disable burst wrap command */ + uint8_t deBurstWrapCmdDmyClk; /*!< Disable burst wrap command dummy clock */ + uint8_t deBurstWrapDataMode; /*!< Data and address mode for this command */ + uint8_t deBurstWrapData; /*!< Data to disable burst wrap */ + uint16_t timeEsector; /*!< 4K erase time */ + uint16_t timeE32k; /*!< 32K erase time */ + uint16_t timeE64k; /*!< 64K erase time */ + uint16_t timePagePgm; /*!< Page program time */ + uint16_t timeCe; /*!< Chip erase time in ms */ + uint8_t pdDelay; /*!< Release power down command delay time for wake up */ + uint8_t qeData; /*!< QE set data */ +} __attribute__((packed)) SPI_Flash_Cfg_Type; + +/** + * @brief Serial flash security register configuration + */ +typedef struct +{ + uint8_t eraseCmd; /*!< Erase security register command */ + uint8_t programCmd; /*!< Program security register command */ + uint8_t readCmd; /*!< Read security register command */ + uint8_t enterSecOptCmd; /*!< Enter security register option mode command */ + uint8_t exitSecOptCmd; /*!< Exit security register option mode command */ + uint8_t blockNum; /*!< Security register block number */ + uint8_t *data; /*!< Data pointer to be program/read */ + uint32_t addr; /*!< Start address to be program/read */ + uint32_t len; /*!< Data length to be program/read */ +} SFlash_Sec_Reg_Cfg; +/*@} end of group SFLAH_Public_Types */ + +/** @defgroup SFLAH_Public_Constants + * @{ + */ + +/*@} end of group SFLAH_Public_Constants */ + +/** @defgroup SFLAH_Public_Macros + * @{ + */ +#define BFLB_SPIFLASH_BLK32K_SIZE (32 * 1024) +#define BFLB_SPIFLASH_BLK64K_SIZE (64 * 1024) +#define BFLB_SPIFLASH_CMD_INVALID 0xff + +/*@} end of group SFLAH_Public_Macros */ + +/** @defgroup SFLAH_Public_Functions + * @{ + */ +void ATTR_TCM_SECTION SFlash_Init(const SF_Ctrl_Cfg_Type *pSfCtrlCfg, const SF_Ctrl_Bank2_Cfg *pBank2Cfg); +BL_Err_Type SFlash_SetSPIMode(SF_Ctrl_Mode_Type mode); +BL_Err_Type SFlash_Read_Reg(SPI_Flash_Cfg_Type *flashCfg, uint8_t regIndex, uint8_t *regValue, uint8_t regLen); +BL_Err_Type SFlash_Write_Reg(SPI_Flash_Cfg_Type *flashCfg, uint8_t regIndex, uint8_t *regValue, uint8_t regLen); +BL_Err_Type SFlash_Read_Reg_With_Cmd(SPI_Flash_Cfg_Type *flashCfg, uint8_t readRegCmd, uint8_t *regValue, + uint8_t regLen); +BL_Err_Type SFlash_Write_Reg_With_Cmd(SPI_Flash_Cfg_Type *flashCfg, uint8_t writeRegCmd, uint8_t *regValue, + uint8_t regLen); +BL_Sts_Type SFlash_Busy(SPI_Flash_Cfg_Type *flashCfg); +BL_Err_Type SFlash_Write_Enable(SPI_Flash_Cfg_Type *flashCfg); +BL_Err_Type SFlash_Qspi_Enable(SPI_Flash_Cfg_Type *flashCfg); +BL_Err_Type SFlash_Qspi_Disable(SPI_Flash_Cfg_Type *flashCfg); +void SFlash_Volatile_Reg_Write_Enable(SPI_Flash_Cfg_Type *flashCfg); +BL_Err_Type SFlash_Chip_Erase(SPI_Flash_Cfg_Type *flashCfg); +BL_Err_Type SFlash_Sector_Erase(SPI_Flash_Cfg_Type *flashCfg, uint32_t secNum); +BL_Err_Type SFlash_Blk32_Erase(SPI_Flash_Cfg_Type *flashCfg, uint32_t blkNum); +BL_Err_Type SFlash_Blk64_Erase(SPI_Flash_Cfg_Type *flashCfg, uint32_t blkNum); +BL_Err_Type SFlash_Erase(SPI_Flash_Cfg_Type *flashCfg, uint32_t startaddr, uint32_t endaddr); +void SFlash_GetUniqueId(uint8_t *data, uint8_t idLen); +void SFlash_GetJedecId(SPI_Flash_Cfg_Type *flashCfg, uint8_t *data); +void SFlash_GetDeviceId(uint8_t *data, BL_Fun_Type is32BitsAddr); +void SFlash_Powerdown(void); +void SFlash_Release_Powerdown(SPI_Flash_Cfg_Type *flashCfg); +BL_Err_Type SFlash_Restore_From_Powerdown(SPI_Flash_Cfg_Type *pFlashCfg, uint8_t flashContRead, + SF_Ctrl_Bank_Select bank); +void SFlash_SetBurstWrap(SPI_Flash_Cfg_Type *flashCfg); +void SFlash_DisableBurstWrap(SPI_Flash_Cfg_Type *flashCfg); +BL_Err_Type SFlash_Set32BitsAddrMode(SPI_Flash_Cfg_Type *flashCfg, BL_Fun_Type en32BitsAddr); +BL_Err_Type SFlash_Software_Reset(SPI_Flash_Cfg_Type *flashCfg); +void SFlash_Reset_Continue_Read(SPI_Flash_Cfg_Type *flashCfg); +BL_Err_Type SFlash_Set_IDbus_Cfg(SPI_Flash_Cfg_Type *flashCfg, SF_Ctrl_IO_Type ioMode, uint8_t contRead, uint32_t addr, + uint32_t len, SF_Ctrl_Bank_Select bank); +BL_Err_Type SFlash_IDbus_Read_Enable(SPI_Flash_Cfg_Type *flashCfg, SF_Ctrl_IO_Type ioMode, uint8_t contRead, + SF_Ctrl_Bank_Select bank); +void SFlash_IDbus_Read_Disable(void); +BL_Err_Type SFlash_RCV_Enable(SPI_Flash_Cfg_Type *pFlashCfg, uint8_t rCmd, uint8_t wCmd, uint8_t bitPos); +BL_Err_Type SFlash_Erase_Security_Register(SPI_Flash_Cfg_Type *pFlashCfg, SFlash_Sec_Reg_Cfg *pSecRegCfg); +BL_Err_Type SFlash_Program_Security_Register(SPI_Flash_Cfg_Type *pFlashCfg, + SFlash_Sec_Reg_Cfg *pSecRegCfg); +BL_Err_Type SFlash_Read_Security_Register(SFlash_Sec_Reg_Cfg *pSecRegCfg); +BL_Err_Type SFlash_Read(SPI_Flash_Cfg_Type *flashCfg, SF_Ctrl_IO_Type ioMode, uint8_t contRead, uint32_t addr, uint8_t *data, + uint32_t len); +BL_Err_Type SFlash_Program(SPI_Flash_Cfg_Type *flashCfg, SF_Ctrl_IO_Type ioMode, uint32_t addr, uint8_t *data, uint32_t len); + +/*@} end of group SFLAH_Public_Functions */ + +/*@} end of group SFLAH */ + +/*@} end of group BL808_Peripheral_Driver */ + +#endif /* __BL808_SFLAH_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/bl_psram.h b/platforms/bl808_m0/vendor/psram/include/bl_psram.h new file mode 100644 index 0000000..7120c15 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/bl_psram.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016-2022 Bouffalolab. + * + * This file is part of + * *** Bouffalolab Software Dev Kit *** + * (see www.bouffalolab.com). + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __BL_PSRAM_H__ +#define __BL_PSRAM_H__ + +int bl_psram_init(void); +#endif diff --git a/platforms/bl808_m0/vendor/psram/include/cci_reg.h b/platforms/bl808_m0/vendor/psram/include/cci_reg.h new file mode 100644 index 0000000..e6ef09f --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/cci_reg.h @@ -0,0 +1,1353 @@ +/** + ****************************************************************************** + * @file cci_reg.h + * @version V1.0 + * @date 2021-07-14 + * @brief This file is the description of.IP register + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __CCI_REG_H__ +#define __CCI_REG_H__ + +#include "bl808.h" + +/* 0x0 : cci_cfg */ +#define CCI_CFG_OFFSET (0x0) +#define CCI_EN CCI_EN +#define CCI_EN_POS (0U) +#define CCI_EN_LEN (1U) +#define CCI_EN_MSK (((1U << CCI_EN_LEN) - 1) << CCI_EN_POS) +#define CCI_EN_UMSK (~(((1U << CCI_EN_LEN) - 1) << CCI_EN_POS)) +#define CCI_SLV_SEL_CCI2 CCI_SLV_SEL_CCI2 +#define CCI_SLV_SEL_CCI2_POS (1U) +#define CCI_SLV_SEL_CCI2_LEN (1U) +#define CCI_SLV_SEL_CCI2_MSK (((1U << CCI_SLV_SEL_CCI2_LEN) - 1) << CCI_SLV_SEL_CCI2_POS) +#define CCI_SLV_SEL_CCI2_UMSK (~(((1U << CCI_SLV_SEL_CCI2_LEN) - 1) << CCI_SLV_SEL_CCI2_POS)) +#define CCI_MAS_SEL_CCI2 CCI_MAS_SEL_CCI2 +#define CCI_MAS_SEL_CCI2_POS (2U) +#define CCI_MAS_SEL_CCI2_LEN (1U) +#define CCI_MAS_SEL_CCI2_MSK (((1U << CCI_MAS_SEL_CCI2_LEN) - 1) << CCI_MAS_SEL_CCI2_POS) +#define CCI_MAS_SEL_CCI2_UMSK (~(((1U << CCI_MAS_SEL_CCI2_LEN) - 1) << CCI_MAS_SEL_CCI2_POS)) +#define CCI_MAS_HW_MODE CCI_MAS_HW_MODE +#define CCI_MAS_HW_MODE_POS (3U) +#define CCI_MAS_HW_MODE_LEN (1U) +#define CCI_MAS_HW_MODE_MSK (((1U << CCI_MAS_HW_MODE_LEN) - 1) << CCI_MAS_HW_MODE_POS) +#define CCI_MAS_HW_MODE_UMSK (~(((1U << CCI_MAS_HW_MODE_LEN) - 1) << CCI_MAS_HW_MODE_POS)) +#define CCI_REG_M_CCI_SCLK_EN CCI_REG_M_CCI_SCLK_EN +#define CCI_REG_M_CCI_SCLK_EN_POS (4U) +#define CCI_REG_M_CCI_SCLK_EN_LEN (1U) +#define CCI_REG_M_CCI_SCLK_EN_MSK (((1U << CCI_REG_M_CCI_SCLK_EN_LEN) - 1) << CCI_REG_M_CCI_SCLK_EN_POS) +#define CCI_REG_M_CCI_SCLK_EN_UMSK (~(((1U << CCI_REG_M_CCI_SCLK_EN_LEN) - 1) << CCI_REG_M_CCI_SCLK_EN_POS)) +#define CCI_REG_DIV_M_CCI_SCLK CCI_REG_DIV_M_CCI_SCLK +#define CCI_REG_DIV_M_CCI_SCLK_POS (5U) +#define CCI_REG_DIV_M_CCI_SCLK_LEN (2U) +#define CCI_REG_DIV_M_CCI_SCLK_MSK (((1U << CCI_REG_DIV_M_CCI_SCLK_LEN) - 1) << CCI_REG_DIV_M_CCI_SCLK_POS) +#define CCI_REG_DIV_M_CCI_SCLK_UMSK (~(((1U << CCI_REG_DIV_M_CCI_SCLK_LEN) - 1) << CCI_REG_DIV_M_CCI_SCLK_POS)) +#define CCI_CFG_CCI1_PRE_READ CCI_CFG_CCI1_PRE_READ +#define CCI_CFG_CCI1_PRE_READ_POS (7U) +#define CCI_CFG_CCI1_PRE_READ_LEN (1U) +#define CCI_CFG_CCI1_PRE_READ_MSK (((1U << CCI_CFG_CCI1_PRE_READ_LEN) - 1) << CCI_CFG_CCI1_PRE_READ_POS) +#define CCI_CFG_CCI1_PRE_READ_UMSK (~(((1U << CCI_CFG_CCI1_PRE_READ_LEN) - 1) << CCI_CFG_CCI1_PRE_READ_POS)) +#define CCI_REG_SCCI_CLK_INV CCI_REG_SCCI_CLK_INV +#define CCI_REG_SCCI_CLK_INV_POS (8U) +#define CCI_REG_SCCI_CLK_INV_LEN (1U) +#define CCI_REG_SCCI_CLK_INV_MSK (((1U << CCI_REG_SCCI_CLK_INV_LEN) - 1) << CCI_REG_SCCI_CLK_INV_POS) +#define CCI_REG_SCCI_CLK_INV_UMSK (~(((1U << CCI_REG_SCCI_CLK_INV_LEN) - 1) << CCI_REG_SCCI_CLK_INV_POS)) +#define CCI_REG_MCCI_CLK_INV CCI_REG_MCCI_CLK_INV +#define CCI_REG_MCCI_CLK_INV_POS (9U) +#define CCI_REG_MCCI_CLK_INV_LEN (1U) +#define CCI_REG_MCCI_CLK_INV_MSK (((1U << CCI_REG_MCCI_CLK_INV_LEN) - 1) << CCI_REG_MCCI_CLK_INV_POS) +#define CCI_REG_MCCI_CLK_INV_UMSK (~(((1U << CCI_REG_MCCI_CLK_INV_LEN) - 1) << CCI_REG_MCCI_CLK_INV_POS)) + +/* 0x4 : cci_addr */ +#define CCI_ADDR_OFFSET (0x4) +#define CCI_APB_CCI_ADDR CCI_APB_CCI_ADDR +#define CCI_APB_CCI_ADDR_POS (0U) +#define CCI_APB_CCI_ADDR_LEN (32U) +#define CCI_APB_CCI_ADDR_MSK (((1U << CCI_APB_CCI_ADDR_LEN) - 1) << CCI_APB_CCI_ADDR_POS) +#define CCI_APB_CCI_ADDR_UMSK (~(((1U << CCI_APB_CCI_ADDR_LEN) - 1) << CCI_APB_CCI_ADDR_POS)) + +/* 0x8 : cci_wdata */ +#define CCI_WDATA_OFFSET (0x8) +#define CCI_APB_CCI_WDATA CCI_APB_CCI_WDATA +#define CCI_APB_CCI_WDATA_POS (0U) +#define CCI_APB_CCI_WDATA_LEN (32U) +#define CCI_APB_CCI_WDATA_MSK (((1U << CCI_APB_CCI_WDATA_LEN) - 1) << CCI_APB_CCI_WDATA_POS) +#define CCI_APB_CCI_WDATA_UMSK (~(((1U << CCI_APB_CCI_WDATA_LEN) - 1) << CCI_APB_CCI_WDATA_POS)) + +/* 0xC : cci_rdata */ +#define CCI_RDATA_OFFSET (0xC) +#define CCI_APB_CCI_RDATA CCI_APB_CCI_RDATA +#define CCI_APB_CCI_RDATA_POS (0U) +#define CCI_APB_CCI_RDATA_LEN (32U) +#define CCI_APB_CCI_RDATA_MSK (((1U << CCI_APB_CCI_RDATA_LEN) - 1) << CCI_APB_CCI_RDATA_POS) +#define CCI_APB_CCI_RDATA_UMSK (~(((1U << CCI_APB_CCI_RDATA_LEN) - 1) << CCI_APB_CCI_RDATA_POS)) + +/* 0x10 : cci_ctl */ +#define CCI_CTL_OFFSET (0x10) +#define CCI_WRITE_FLAG CCI_WRITE_FLAG +#define CCI_WRITE_FLAG_POS (0U) +#define CCI_WRITE_FLAG_LEN (1U) +#define CCI_WRITE_FLAG_MSK (((1U << CCI_WRITE_FLAG_LEN) - 1) << CCI_WRITE_FLAG_POS) +#define CCI_WRITE_FLAG_UMSK (~(((1U << CCI_WRITE_FLAG_LEN) - 1) << CCI_WRITE_FLAG_POS)) +#define CCI_READ_FLAG CCI_READ_FLAG +#define CCI_READ_FLAG_POS (1U) +#define CCI_READ_FLAG_LEN (1U) +#define CCI_READ_FLAG_MSK (((1U << CCI_READ_FLAG_LEN) - 1) << CCI_READ_FLAG_POS) +#define CCI_READ_FLAG_UMSK (~(((1U << CCI_READ_FLAG_LEN) - 1) << CCI_READ_FLAG_POS)) +#define CCI_AHB_STATE CCI_AHB_STATE +#define CCI_AHB_STATE_POS (2U) +#define CCI_AHB_STATE_LEN (2U) +#define CCI_AHB_STATE_MSK (((1U << CCI_AHB_STATE_LEN) - 1) << CCI_AHB_STATE_POS) +#define CCI_AHB_STATE_UMSK (~(((1U << CCI_AHB_STATE_LEN) - 1) << CCI_AHB_STATE_POS)) + +/* 0x750 : audio_pll_cfg0 */ +#define CCI_AUDIO_PLL_CFG0_OFFSET (0x750) +#define CCI_AUPLL_SDM_RSTB CCI_AUPLL_SDM_RSTB +#define CCI_AUPLL_SDM_RSTB_POS (0U) +#define CCI_AUPLL_SDM_RSTB_LEN (1U) +#define CCI_AUPLL_SDM_RSTB_MSK (((1U << CCI_AUPLL_SDM_RSTB_LEN) - 1) << CCI_AUPLL_SDM_RSTB_POS) +#define CCI_AUPLL_SDM_RSTB_UMSK (~(((1U << CCI_AUPLL_SDM_RSTB_LEN) - 1) << CCI_AUPLL_SDM_RSTB_POS)) +#define CCI_AUPLL_POSTDIV_RSTB CCI_AUPLL_POSTDIV_RSTB +#define CCI_AUPLL_POSTDIV_RSTB_POS (1U) +#define CCI_AUPLL_POSTDIV_RSTB_LEN (1U) +#define CCI_AUPLL_POSTDIV_RSTB_MSK (((1U << CCI_AUPLL_POSTDIV_RSTB_LEN) - 1) << CCI_AUPLL_POSTDIV_RSTB_POS) +#define CCI_AUPLL_POSTDIV_RSTB_UMSK (~(((1U << CCI_AUPLL_POSTDIV_RSTB_LEN) - 1) << CCI_AUPLL_POSTDIV_RSTB_POS)) +#define CCI_AUPLL_FBDV_RSTB CCI_AUPLL_FBDV_RSTB +#define CCI_AUPLL_FBDV_RSTB_POS (2U) +#define CCI_AUPLL_FBDV_RSTB_LEN (1U) +#define CCI_AUPLL_FBDV_RSTB_MSK (((1U << CCI_AUPLL_FBDV_RSTB_LEN) - 1) << CCI_AUPLL_FBDV_RSTB_POS) +#define CCI_AUPLL_FBDV_RSTB_UMSK (~(((1U << CCI_AUPLL_FBDV_RSTB_LEN) - 1) << CCI_AUPLL_FBDV_RSTB_POS)) +#define CCI_AUPLL_REFDIV_RSTB CCI_AUPLL_REFDIV_RSTB +#define CCI_AUPLL_REFDIV_RSTB_POS (3U) +#define CCI_AUPLL_REFDIV_RSTB_LEN (1U) +#define CCI_AUPLL_REFDIV_RSTB_MSK (((1U << CCI_AUPLL_REFDIV_RSTB_LEN) - 1) << CCI_AUPLL_REFDIV_RSTB_POS) +#define CCI_AUPLL_REFDIV_RSTB_UMSK (~(((1U << CCI_AUPLL_REFDIV_RSTB_LEN) - 1) << CCI_AUPLL_REFDIV_RSTB_POS)) +#define CCI_PU_AUPLL_POSTDIV CCI_PU_AUPLL_POSTDIV +#define CCI_PU_AUPLL_POSTDIV_POS (4U) +#define CCI_PU_AUPLL_POSTDIV_LEN (1U) +#define CCI_PU_AUPLL_POSTDIV_MSK (((1U << CCI_PU_AUPLL_POSTDIV_LEN) - 1) << CCI_PU_AUPLL_POSTDIV_POS) +#define CCI_PU_AUPLL_POSTDIV_UMSK (~(((1U << CCI_PU_AUPLL_POSTDIV_LEN) - 1) << CCI_PU_AUPLL_POSTDIV_POS)) +#define CCI_PU_AUPLL_FBDV CCI_PU_AUPLL_FBDV +#define CCI_PU_AUPLL_FBDV_POS (5U) +#define CCI_PU_AUPLL_FBDV_LEN (1U) +#define CCI_PU_AUPLL_FBDV_MSK (((1U << CCI_PU_AUPLL_FBDV_LEN) - 1) << CCI_PU_AUPLL_FBDV_POS) +#define CCI_PU_AUPLL_FBDV_UMSK (~(((1U << CCI_PU_AUPLL_FBDV_LEN) - 1) << CCI_PU_AUPLL_FBDV_POS)) +#define CCI_PU_AUPLL_CLAMP_OP CCI_PU_AUPLL_CLAMP_OP +#define CCI_PU_AUPLL_CLAMP_OP_POS (6U) +#define CCI_PU_AUPLL_CLAMP_OP_LEN (1U) +#define CCI_PU_AUPLL_CLAMP_OP_MSK (((1U << CCI_PU_AUPLL_CLAMP_OP_LEN) - 1) << CCI_PU_AUPLL_CLAMP_OP_POS) +#define CCI_PU_AUPLL_CLAMP_OP_UMSK (~(((1U << CCI_PU_AUPLL_CLAMP_OP_LEN) - 1) << CCI_PU_AUPLL_CLAMP_OP_POS)) +#define CCI_PU_AUPLL_PFD CCI_PU_AUPLL_PFD +#define CCI_PU_AUPLL_PFD_POS (7U) +#define CCI_PU_AUPLL_PFD_LEN (1U) +#define CCI_PU_AUPLL_PFD_MSK (((1U << CCI_PU_AUPLL_PFD_LEN) - 1) << CCI_PU_AUPLL_PFD_POS) +#define CCI_PU_AUPLL_PFD_UMSK (~(((1U << CCI_PU_AUPLL_PFD_LEN) - 1) << CCI_PU_AUPLL_PFD_POS)) +#define CCI_PU_AUPLL_CP CCI_PU_AUPLL_CP +#define CCI_PU_AUPLL_CP_POS (8U) +#define CCI_PU_AUPLL_CP_LEN (1U) +#define CCI_PU_AUPLL_CP_MSK (((1U << CCI_PU_AUPLL_CP_LEN) - 1) << CCI_PU_AUPLL_CP_POS) +#define CCI_PU_AUPLL_CP_UMSK (~(((1U << CCI_PU_AUPLL_CP_LEN) - 1) << CCI_PU_AUPLL_CP_POS)) +#define CCI_PU_AUPLL_SFREG CCI_PU_AUPLL_SFREG +#define CCI_PU_AUPLL_SFREG_POS (9U) +#define CCI_PU_AUPLL_SFREG_LEN (1U) +#define CCI_PU_AUPLL_SFREG_MSK (((1U << CCI_PU_AUPLL_SFREG_LEN) - 1) << CCI_PU_AUPLL_SFREG_POS) +#define CCI_PU_AUPLL_SFREG_UMSK (~(((1U << CCI_PU_AUPLL_SFREG_LEN) - 1) << CCI_PU_AUPLL_SFREG_POS)) +#define CCI_PU_AUPLL CCI_PU_AUPLL +#define CCI_PU_AUPLL_POS (10U) +#define CCI_PU_AUPLL_LEN (1U) +#define CCI_PU_AUPLL_MSK (((1U << CCI_PU_AUPLL_LEN) - 1) << CCI_PU_AUPLL_POS) +#define CCI_PU_AUPLL_UMSK (~(((1U << CCI_PU_AUPLL_LEN) - 1) << CCI_PU_AUPLL_POS)) +#define CCI_PU_AUPLL_CLKTREE CCI_PU_AUPLL_CLKTREE +#define CCI_PU_AUPLL_CLKTREE_POS (11U) +#define CCI_PU_AUPLL_CLKTREE_LEN (1U) +#define CCI_PU_AUPLL_CLKTREE_MSK (((1U << CCI_PU_AUPLL_CLKTREE_LEN) - 1) << CCI_PU_AUPLL_CLKTREE_POS) +#define CCI_PU_AUPLL_CLKTREE_UMSK (~(((1U << CCI_PU_AUPLL_CLKTREE_LEN) - 1) << CCI_PU_AUPLL_CLKTREE_POS)) + +/* 0x754 : audio_pll_cfg1 */ +#define CCI_AUDIO_PLL_CFG1_OFFSET (0x754) +#define CCI_AUPLL_POSTDIV CCI_AUPLL_POSTDIV +#define CCI_AUPLL_POSTDIV_POS (0U) +#define CCI_AUPLL_POSTDIV_LEN (7U) +#define CCI_AUPLL_POSTDIV_MSK (((1U << CCI_AUPLL_POSTDIV_LEN) - 1) << CCI_AUPLL_POSTDIV_POS) +#define CCI_AUPLL_POSTDIV_UMSK (~(((1U << CCI_AUPLL_POSTDIV_LEN) - 1) << CCI_AUPLL_POSTDIV_POS)) +#define CCI_AUPLL_REFDIV_RATIO CCI_AUPLL_REFDIV_RATIO +#define CCI_AUPLL_REFDIV_RATIO_POS (8U) +#define CCI_AUPLL_REFDIV_RATIO_LEN (4U) +#define CCI_AUPLL_REFDIV_RATIO_MSK (((1U << CCI_AUPLL_REFDIV_RATIO_LEN) - 1) << CCI_AUPLL_REFDIV_RATIO_POS) +#define CCI_AUPLL_REFDIV_RATIO_UMSK (~(((1U << CCI_AUPLL_REFDIV_RATIO_LEN) - 1) << CCI_AUPLL_REFDIV_RATIO_POS)) +#define CCI_AUPLL_REFCLK_SEL CCI_AUPLL_REFCLK_SEL +#define CCI_AUPLL_REFCLK_SEL_POS (16U) +#define CCI_AUPLL_REFCLK_SEL_LEN (2U) +#define CCI_AUPLL_REFCLK_SEL_MSK (((1U << CCI_AUPLL_REFCLK_SEL_LEN) - 1) << CCI_AUPLL_REFCLK_SEL_POS) +#define CCI_AUPLL_REFCLK_SEL_UMSK (~(((1U << CCI_AUPLL_REFCLK_SEL_LEN) - 1) << CCI_AUPLL_REFCLK_SEL_POS)) +#define CCI_AUPLL_VG11_SEL CCI_AUPLL_VG11_SEL +#define CCI_AUPLL_VG11_SEL_POS (20U) +#define CCI_AUPLL_VG11_SEL_LEN (2U) +#define CCI_AUPLL_VG11_SEL_MSK (((1U << CCI_AUPLL_VG11_SEL_LEN) - 1) << CCI_AUPLL_VG11_SEL_POS) +#define CCI_AUPLL_VG11_SEL_UMSK (~(((1U << CCI_AUPLL_VG11_SEL_LEN) - 1) << CCI_AUPLL_VG11_SEL_POS)) +#define CCI_AUPLL_VG13_SEL CCI_AUPLL_VG13_SEL +#define CCI_AUPLL_VG13_SEL_POS (24U) +#define CCI_AUPLL_VG13_SEL_LEN (2U) +#define CCI_AUPLL_VG13_SEL_MSK (((1U << CCI_AUPLL_VG13_SEL_LEN) - 1) << CCI_AUPLL_VG13_SEL_POS) +#define CCI_AUPLL_VG13_SEL_UMSK (~(((1U << CCI_AUPLL_VG13_SEL_LEN) - 1) << CCI_AUPLL_VG13_SEL_POS)) + +/* 0x758 : audio_pll_cfg2 */ +#define CCI_AUDIO_PLL_CFG2_OFFSET (0x758) +#define CCI_AUPLL_SEL_CP_BIAS CCI_AUPLL_SEL_CP_BIAS +#define CCI_AUPLL_SEL_CP_BIAS_POS (0U) +#define CCI_AUPLL_SEL_CP_BIAS_LEN (1U) +#define CCI_AUPLL_SEL_CP_BIAS_MSK (((1U << CCI_AUPLL_SEL_CP_BIAS_LEN) - 1) << CCI_AUPLL_SEL_CP_BIAS_POS) +#define CCI_AUPLL_SEL_CP_BIAS_UMSK (~(((1U << CCI_AUPLL_SEL_CP_BIAS_LEN) - 1) << CCI_AUPLL_SEL_CP_BIAS_POS)) +#define CCI_AUPLL_ICP_5U CCI_AUPLL_ICP_5U +#define CCI_AUPLL_ICP_5U_POS (4U) +#define CCI_AUPLL_ICP_5U_LEN (2U) +#define CCI_AUPLL_ICP_5U_MSK (((1U << CCI_AUPLL_ICP_5U_LEN) - 1) << CCI_AUPLL_ICP_5U_POS) +#define CCI_AUPLL_ICP_5U_UMSK (~(((1U << CCI_AUPLL_ICP_5U_LEN) - 1) << CCI_AUPLL_ICP_5U_POS)) +#define CCI_AUPLL_ICP_1U CCI_AUPLL_ICP_1U +#define CCI_AUPLL_ICP_1U_POS (6U) +#define CCI_AUPLL_ICP_1U_LEN (2U) +#define CCI_AUPLL_ICP_1U_MSK (((1U << CCI_AUPLL_ICP_1U_LEN) - 1) << CCI_AUPLL_ICP_1U_POS) +#define CCI_AUPLL_ICP_1U_UMSK (~(((1U << CCI_AUPLL_ICP_1U_LEN) - 1) << CCI_AUPLL_ICP_1U_POS)) +#define CCI_AUPLL_INT_FRAC_SW CCI_AUPLL_INT_FRAC_SW +#define CCI_AUPLL_INT_FRAC_SW_POS (8U) +#define CCI_AUPLL_INT_FRAC_SW_LEN (1U) +#define CCI_AUPLL_INT_FRAC_SW_MSK (((1U << CCI_AUPLL_INT_FRAC_SW_LEN) - 1) << CCI_AUPLL_INT_FRAC_SW_POS) +#define CCI_AUPLL_INT_FRAC_SW_UMSK (~(((1U << CCI_AUPLL_INT_FRAC_SW_LEN) - 1) << CCI_AUPLL_INT_FRAC_SW_POS)) +#define CCI_AUPLL_CP_STARTUP_EN CCI_AUPLL_CP_STARTUP_EN +#define CCI_AUPLL_CP_STARTUP_EN_POS (9U) +#define CCI_AUPLL_CP_STARTUP_EN_LEN (1U) +#define CCI_AUPLL_CP_STARTUP_EN_MSK (((1U << CCI_AUPLL_CP_STARTUP_EN_LEN) - 1) << CCI_AUPLL_CP_STARTUP_EN_POS) +#define CCI_AUPLL_CP_STARTUP_EN_UMSK (~(((1U << CCI_AUPLL_CP_STARTUP_EN_LEN) - 1) << CCI_AUPLL_CP_STARTUP_EN_POS)) +#define CCI_AUPLL_CP_OPAMP_EN CCI_AUPLL_CP_OPAMP_EN +#define CCI_AUPLL_CP_OPAMP_EN_POS (10U) +#define CCI_AUPLL_CP_OPAMP_EN_LEN (1U) +#define CCI_AUPLL_CP_OPAMP_EN_MSK (((1U << CCI_AUPLL_CP_OPAMP_EN_LEN) - 1) << CCI_AUPLL_CP_OPAMP_EN_POS) +#define CCI_AUPLL_CP_OPAMP_EN_UMSK (~(((1U << CCI_AUPLL_CP_OPAMP_EN_LEN) - 1) << CCI_AUPLL_CP_OPAMP_EN_POS)) + +/* 0x75C : audio_pll_cfg3 */ +#define CCI_AUDIO_PLL_CFG3_OFFSET (0x75C) +#define CCI_AUPLL_C4_EN CCI_AUPLL_C4_EN +#define CCI_AUPLL_C4_EN_POS (0U) +#define CCI_AUPLL_C4_EN_LEN (1U) +#define CCI_AUPLL_C4_EN_MSK (((1U << CCI_AUPLL_C4_EN_LEN) - 1) << CCI_AUPLL_C4_EN_POS) +#define CCI_AUPLL_C4_EN_UMSK (~(((1U << CCI_AUPLL_C4_EN_LEN) - 1) << CCI_AUPLL_C4_EN_POS)) +#define CCI_AUPLL_R4 CCI_AUPLL_R4 +#define CCI_AUPLL_R4_POS (4U) +#define CCI_AUPLL_R4_LEN (2U) +#define CCI_AUPLL_R4_MSK (((1U << CCI_AUPLL_R4_LEN) - 1) << CCI_AUPLL_R4_POS) +#define CCI_AUPLL_R4_UMSK (~(((1U << CCI_AUPLL_R4_LEN) - 1) << CCI_AUPLL_R4_POS)) +#define CCI_AUPLL_R4_SHORT CCI_AUPLL_R4_SHORT +#define CCI_AUPLL_R4_SHORT_POS (8U) +#define CCI_AUPLL_R4_SHORT_LEN (1U) +#define CCI_AUPLL_R4_SHORT_MSK (((1U << CCI_AUPLL_R4_SHORT_LEN) - 1) << CCI_AUPLL_R4_SHORT_POS) +#define CCI_AUPLL_R4_SHORT_UMSK (~(((1U << CCI_AUPLL_R4_SHORT_LEN) - 1) << CCI_AUPLL_R4_SHORT_POS)) +#define CCI_AUPLL_C3 CCI_AUPLL_C3 +#define CCI_AUPLL_C3_POS (12U) +#define CCI_AUPLL_C3_LEN (2U) +#define CCI_AUPLL_C3_MSK (((1U << CCI_AUPLL_C3_LEN) - 1) << CCI_AUPLL_C3_POS) +#define CCI_AUPLL_C3_UMSK (~(((1U << CCI_AUPLL_C3_LEN) - 1) << CCI_AUPLL_C3_POS)) +#define CCI_AUPLL_CZ CCI_AUPLL_CZ +#define CCI_AUPLL_CZ_POS (14U) +#define CCI_AUPLL_CZ_LEN (2U) +#define CCI_AUPLL_CZ_MSK (((1U << CCI_AUPLL_CZ_LEN) - 1) << CCI_AUPLL_CZ_POS) +#define CCI_AUPLL_CZ_UMSK (~(((1U << CCI_AUPLL_CZ_LEN) - 1) << CCI_AUPLL_CZ_POS)) +#define CCI_AUPLL_RZ CCI_AUPLL_RZ +#define CCI_AUPLL_RZ_POS (16U) +#define CCI_AUPLL_RZ_LEN (3U) +#define CCI_AUPLL_RZ_MSK (((1U << CCI_AUPLL_RZ_LEN) - 1) << CCI_AUPLL_RZ_POS) +#define CCI_AUPLL_RZ_UMSK (~(((1U << CCI_AUPLL_RZ_LEN) - 1) << CCI_AUPLL_RZ_POS)) + +/* 0x760 : audio_pll_cfg4 */ +#define CCI_AUDIO_PLL_CFG4_OFFSET (0x760) +#define CCI_AUPLL_SEL_SAMPLE_CLK CCI_AUPLL_SEL_SAMPLE_CLK +#define CCI_AUPLL_SEL_SAMPLE_CLK_POS (0U) +#define CCI_AUPLL_SEL_SAMPLE_CLK_LEN (2U) +#define CCI_AUPLL_SEL_SAMPLE_CLK_MSK (((1U << CCI_AUPLL_SEL_SAMPLE_CLK_LEN) - 1) << CCI_AUPLL_SEL_SAMPLE_CLK_POS) +#define CCI_AUPLL_SEL_SAMPLE_CLK_UMSK (~(((1U << CCI_AUPLL_SEL_SAMPLE_CLK_LEN) - 1) << CCI_AUPLL_SEL_SAMPLE_CLK_POS)) +#define CCI_AUPLL_SEL_FB_CLK CCI_AUPLL_SEL_FB_CLK +#define CCI_AUPLL_SEL_FB_CLK_POS (4U) +#define CCI_AUPLL_SEL_FB_CLK_LEN (2U) +#define CCI_AUPLL_SEL_FB_CLK_MSK (((1U << CCI_AUPLL_SEL_FB_CLK_LEN) - 1) << CCI_AUPLL_SEL_FB_CLK_POS) +#define CCI_AUPLL_SEL_FB_CLK_UMSK (~(((1U << CCI_AUPLL_SEL_FB_CLK_LEN) - 1) << CCI_AUPLL_SEL_FB_CLK_POS)) +#define CCI_AUPLL_SDMCLK_SEL CCI_AUPLL_SDMCLK_SEL +#define CCI_AUPLL_SDMCLK_SEL_POS (8U) +#define CCI_AUPLL_SDMCLK_SEL_LEN (1U) +#define CCI_AUPLL_SDMCLK_SEL_MSK (((1U << CCI_AUPLL_SDMCLK_SEL_LEN) - 1) << CCI_AUPLL_SDMCLK_SEL_POS) +#define CCI_AUPLL_SDMCLK_SEL_UMSK (~(((1U << CCI_AUPLL_SDMCLK_SEL_LEN) - 1) << CCI_AUPLL_SDMCLK_SEL_POS)) + +/* 0x764 : audio_pll_cfg5 */ +#define CCI_AUDIO_PLL_CFG5_OFFSET (0x764) +#define CCI_AUPLL_VCO_SPEED CCI_AUPLL_VCO_SPEED +#define CCI_AUPLL_VCO_SPEED_POS (0U) +#define CCI_AUPLL_VCO_SPEED_LEN (3U) +#define CCI_AUPLL_VCO_SPEED_MSK (((1U << CCI_AUPLL_VCO_SPEED_LEN) - 1) << CCI_AUPLL_VCO_SPEED_POS) +#define CCI_AUPLL_VCO_SPEED_UMSK (~(((1U << CCI_AUPLL_VCO_SPEED_LEN) - 1) << CCI_AUPLL_VCO_SPEED_POS)) + +/* 0x768 : audio_pll_cfg6 */ +#define CCI_AUDIO_PLL_CFG6_OFFSET (0x768) +#define CCI_AUPLL_SDMIN CCI_AUPLL_SDMIN +#define CCI_AUPLL_SDMIN_POS (0U) +#define CCI_AUPLL_SDMIN_LEN (19U) +#define CCI_AUPLL_SDMIN_MSK (((1U << CCI_AUPLL_SDMIN_LEN) - 1) << CCI_AUPLL_SDMIN_POS) +#define CCI_AUPLL_SDMIN_UMSK (~(((1U << CCI_AUPLL_SDMIN_LEN) - 1) << CCI_AUPLL_SDMIN_POS)) +#define CCI_AUPLL_SDM_BYPASS CCI_AUPLL_SDM_BYPASS +#define CCI_AUPLL_SDM_BYPASS_POS (24U) +#define CCI_AUPLL_SDM_BYPASS_LEN (1U) +#define CCI_AUPLL_SDM_BYPASS_MSK (((1U << CCI_AUPLL_SDM_BYPASS_LEN) - 1) << CCI_AUPLL_SDM_BYPASS_POS) +#define CCI_AUPLL_SDM_BYPASS_UMSK (~(((1U << CCI_AUPLL_SDM_BYPASS_LEN) - 1) << CCI_AUPLL_SDM_BYPASS_POS)) + +/* 0x76C : audio_pll_cfg7 */ +#define CCI_AUDIO_PLL_CFG7_OFFSET (0x76C) +#define CCI_AUPLL_SDM_ORDER_SEL CCI_AUPLL_SDM_ORDER_SEL +#define CCI_AUPLL_SDM_ORDER_SEL_POS (0U) +#define CCI_AUPLL_SDM_ORDER_SEL_LEN (1U) +#define CCI_AUPLL_SDM_ORDER_SEL_MSK (((1U << CCI_AUPLL_SDM_ORDER_SEL_LEN) - 1) << CCI_AUPLL_SDM_ORDER_SEL_POS) +#define CCI_AUPLL_SDM_ORDER_SEL_UMSK (~(((1U << CCI_AUPLL_SDM_ORDER_SEL_LEN) - 1) << CCI_AUPLL_SDM_ORDER_SEL_POS)) +#define CCI_AUPLL_SDM_SIG_DITH_SEL CCI_AUPLL_SDM_SIG_DITH_SEL +#define CCI_AUPLL_SDM_SIG_DITH_SEL_POS (16U) +#define CCI_AUPLL_SDM_SIG_DITH_SEL_LEN (2U) +#define CCI_AUPLL_SDM_SIG_DITH_SEL_MSK (((1U << CCI_AUPLL_SDM_SIG_DITH_SEL_LEN) - 1) << CCI_AUPLL_SDM_SIG_DITH_SEL_POS) +#define CCI_AUPLL_SDM_SIG_DITH_SEL_UMSK (~(((1U << CCI_AUPLL_SDM_SIG_DITH_SEL_LEN) - 1) << CCI_AUPLL_SDM_SIG_DITH_SEL_POS)) + +/* 0x770 : audio_pll_cfg8 */ +#define CCI_AUDIO_PLL_CFG8_OFFSET (0x770) +#define CCI_AUPLL_EN_DIV1 CCI_AUPLL_EN_DIV1 +#define CCI_AUPLL_EN_DIV1_POS (0U) +#define CCI_AUPLL_EN_DIV1_LEN (1U) +#define CCI_AUPLL_EN_DIV1_MSK (((1U << CCI_AUPLL_EN_DIV1_LEN) - 1) << CCI_AUPLL_EN_DIV1_POS) +#define CCI_AUPLL_EN_DIV1_UMSK (~(((1U << CCI_AUPLL_EN_DIV1_LEN) - 1) << CCI_AUPLL_EN_DIV1_POS)) +#define CCI_AUPLL_EN_DIV2 CCI_AUPLL_EN_DIV2 +#define CCI_AUPLL_EN_DIV2_POS (1U) +#define CCI_AUPLL_EN_DIV2_LEN (1U) +#define CCI_AUPLL_EN_DIV2_MSK (((1U << CCI_AUPLL_EN_DIV2_LEN) - 1) << CCI_AUPLL_EN_DIV2_POS) +#define CCI_AUPLL_EN_DIV2_UMSK (~(((1U << CCI_AUPLL_EN_DIV2_LEN) - 1) << CCI_AUPLL_EN_DIV2_POS)) +#define CCI_AUPLL_EN_DIV2P5 CCI_AUPLL_EN_DIV2P5 +#define CCI_AUPLL_EN_DIV2P5_POS (2U) +#define CCI_AUPLL_EN_DIV2P5_LEN (1U) +#define CCI_AUPLL_EN_DIV2P5_MSK (((1U << CCI_AUPLL_EN_DIV2P5_LEN) - 1) << CCI_AUPLL_EN_DIV2P5_POS) +#define CCI_AUPLL_EN_DIV2P5_UMSK (~(((1U << CCI_AUPLL_EN_DIV2P5_LEN) - 1) << CCI_AUPLL_EN_DIV2P5_POS)) +#define CCI_AUPLL_EN_DIV3 CCI_AUPLL_EN_DIV3 +#define CCI_AUPLL_EN_DIV3_POS (3U) +#define CCI_AUPLL_EN_DIV3_LEN (1U) +#define CCI_AUPLL_EN_DIV3_MSK (((1U << CCI_AUPLL_EN_DIV3_LEN) - 1) << CCI_AUPLL_EN_DIV3_POS) +#define CCI_AUPLL_EN_DIV3_UMSK (~(((1U << CCI_AUPLL_EN_DIV3_LEN) - 1) << CCI_AUPLL_EN_DIV3_POS)) +#define CCI_AUPLL_EN_DIV4 CCI_AUPLL_EN_DIV4 +#define CCI_AUPLL_EN_DIV4_POS (4U) +#define CCI_AUPLL_EN_DIV4_LEN (1U) +#define CCI_AUPLL_EN_DIV4_MSK (((1U << CCI_AUPLL_EN_DIV4_LEN) - 1) << CCI_AUPLL_EN_DIV4_POS) +#define CCI_AUPLL_EN_DIV4_UMSK (~(((1U << CCI_AUPLL_EN_DIV4_LEN) - 1) << CCI_AUPLL_EN_DIV4_POS)) +#define CCI_AUPLL_EN_DIV5 CCI_AUPLL_EN_DIV5 +#define CCI_AUPLL_EN_DIV5_POS (5U) +#define CCI_AUPLL_EN_DIV5_LEN (1U) +#define CCI_AUPLL_EN_DIV5_MSK (((1U << CCI_AUPLL_EN_DIV5_LEN) - 1) << CCI_AUPLL_EN_DIV5_POS) +#define CCI_AUPLL_EN_DIV5_UMSK (~(((1U << CCI_AUPLL_EN_DIV5_LEN) - 1) << CCI_AUPLL_EN_DIV5_POS)) +#define CCI_AUPLL_EN_DIV6 CCI_AUPLL_EN_DIV6 +#define CCI_AUPLL_EN_DIV6_POS (6U) +#define CCI_AUPLL_EN_DIV6_LEN (1U) +#define CCI_AUPLL_EN_DIV6_MSK (((1U << CCI_AUPLL_EN_DIV6_LEN) - 1) << CCI_AUPLL_EN_DIV6_POS) +#define CCI_AUPLL_EN_DIV6_UMSK (~(((1U << CCI_AUPLL_EN_DIV6_LEN) - 1) << CCI_AUPLL_EN_DIV6_POS)) +#define CCI_AUPLL_EN_DIV10 CCI_AUPLL_EN_DIV10 +#define CCI_AUPLL_EN_DIV10_POS (7U) +#define CCI_AUPLL_EN_DIV10_LEN (1U) +#define CCI_AUPLL_EN_DIV10_MSK (((1U << CCI_AUPLL_EN_DIV10_LEN) - 1) << CCI_AUPLL_EN_DIV10_POS) +#define CCI_AUPLL_EN_DIV10_UMSK (~(((1U << CCI_AUPLL_EN_DIV10_LEN) - 1) << CCI_AUPLL_EN_DIV10_POS)) +#define CCI_AUPLL_EN_DIV15 CCI_AUPLL_EN_DIV15 +#define CCI_AUPLL_EN_DIV15_POS (8U) +#define CCI_AUPLL_EN_DIV15_LEN (1U) +#define CCI_AUPLL_EN_DIV15_MSK (((1U << CCI_AUPLL_EN_DIV15_LEN) - 1) << CCI_AUPLL_EN_DIV15_POS) +#define CCI_AUPLL_EN_DIV15_UMSK (~(((1U << CCI_AUPLL_EN_DIV15_LEN) - 1) << CCI_AUPLL_EN_DIV15_POS)) +#define CCI_AUPLL_SEL_DIV1_DIV2 CCI_AUPLL_SEL_DIV1_DIV2 +#define CCI_AUPLL_SEL_DIV1_DIV2_POS (9U) +#define CCI_AUPLL_SEL_DIV1_DIV2_LEN (1U) +#define CCI_AUPLL_SEL_DIV1_DIV2_MSK (((1U << CCI_AUPLL_SEL_DIV1_DIV2_LEN) - 1) << CCI_AUPLL_SEL_DIV1_DIV2_POS) +#define CCI_AUPLL_SEL_DIV1_DIV2_UMSK (~(((1U << CCI_AUPLL_SEL_DIV1_DIV2_LEN) - 1) << CCI_AUPLL_SEL_DIV1_DIV2_POS)) + +/* 0x774 : audio_pll_cfg9 */ +#define CCI_AUDIO_PLL_CFG9_OFFSET (0x774) +#define CCI_AUPLL_DC_TP_OUT_EN CCI_AUPLL_DC_TP_OUT_EN +#define CCI_AUPLL_DC_TP_OUT_EN_POS (0U) +#define CCI_AUPLL_DC_TP_OUT_EN_LEN (1U) +#define CCI_AUPLL_DC_TP_OUT_EN_MSK (((1U << CCI_AUPLL_DC_TP_OUT_EN_LEN) - 1) << CCI_AUPLL_DC_TP_OUT_EN_POS) +#define CCI_AUPLL_DC_TP_OUT_EN_UMSK (~(((1U << CCI_AUPLL_DC_TP_OUT_EN_LEN) - 1) << CCI_AUPLL_DC_TP_OUT_EN_POS)) +#define CCI_TEN_AUPLL CCI_TEN_AUPLL +#define CCI_TEN_AUPLL_POS (1U) +#define CCI_TEN_AUPLL_LEN (1U) +#define CCI_TEN_AUPLL_MSK (((1U << CCI_TEN_AUPLL_LEN) - 1) << CCI_TEN_AUPLL_POS) +#define CCI_TEN_AUPLL_UMSK (~(((1U << CCI_TEN_AUPLL_LEN) - 1) << CCI_TEN_AUPLL_POS)) +#define CCI_TEN_AUPLL_SFREG CCI_TEN_AUPLL_SFREG +#define CCI_TEN_AUPLL_SFREG_POS (2U) +#define CCI_TEN_AUPLL_SFREG_LEN (1U) +#define CCI_TEN_AUPLL_SFREG_MSK (((1U << CCI_TEN_AUPLL_SFREG_LEN) - 1) << CCI_TEN_AUPLL_SFREG_POS) +#define CCI_TEN_AUPLL_SFREG_UMSK (~(((1U << CCI_TEN_AUPLL_SFREG_LEN) - 1) << CCI_TEN_AUPLL_SFREG_POS)) +#define CCI_DTEN_AUPLL_FIN CCI_DTEN_AUPLL_FIN +#define CCI_DTEN_AUPLL_FIN_POS (4U) +#define CCI_DTEN_AUPLL_FIN_LEN (1U) +#define CCI_DTEN_AUPLL_FIN_MSK (((1U << CCI_DTEN_AUPLL_FIN_LEN) - 1) << CCI_DTEN_AUPLL_FIN_POS) +#define CCI_DTEN_AUPLL_FIN_UMSK (~(((1U << CCI_DTEN_AUPLL_FIN_LEN) - 1) << CCI_DTEN_AUPLL_FIN_POS)) +#define CCI_DTEN_AUPLL_FREF CCI_DTEN_AUPLL_FREF +#define CCI_DTEN_AUPLL_FREF_POS (5U) +#define CCI_DTEN_AUPLL_FREF_LEN (1U) +#define CCI_DTEN_AUPLL_FREF_MSK (((1U << CCI_DTEN_AUPLL_FREF_LEN) - 1) << CCI_DTEN_AUPLL_FREF_POS) +#define CCI_DTEN_AUPLL_FREF_UMSK (~(((1U << CCI_DTEN_AUPLL_FREF_LEN) - 1) << CCI_DTEN_AUPLL_FREF_POS)) +#define CCI_DTEN_AUPLL_FSDM CCI_DTEN_AUPLL_FSDM +#define CCI_DTEN_AUPLL_FSDM_POS (6U) +#define CCI_DTEN_AUPLL_FSDM_LEN (1U) +#define CCI_DTEN_AUPLL_FSDM_MSK (((1U << CCI_DTEN_AUPLL_FSDM_LEN) - 1) << CCI_DTEN_AUPLL_FSDM_POS) +#define CCI_DTEN_AUPLL_FSDM_UMSK (~(((1U << CCI_DTEN_AUPLL_FSDM_LEN) - 1) << CCI_DTEN_AUPLL_FSDM_POS)) +#define CCI_DTEN_AUPLL_DIV15 CCI_DTEN_AUPLL_DIV15 +#define CCI_DTEN_AUPLL_DIV15_POS (7U) +#define CCI_DTEN_AUPLL_DIV15_LEN (1U) +#define CCI_DTEN_AUPLL_DIV15_MSK (((1U << CCI_DTEN_AUPLL_DIV15_LEN) - 1) << CCI_DTEN_AUPLL_DIV15_POS) +#define CCI_DTEN_AUPLL_DIV15_UMSK (~(((1U << CCI_DTEN_AUPLL_DIV15_LEN) - 1) << CCI_DTEN_AUPLL_DIV15_POS)) +#define CCI_DTEN_AUPLL_DIV5 CCI_DTEN_AUPLL_DIV5 +#define CCI_DTEN_AUPLL_DIV5_POS (8U) +#define CCI_DTEN_AUPLL_DIV5_LEN (1U) +#define CCI_DTEN_AUPLL_DIV5_MSK (((1U << CCI_DTEN_AUPLL_DIV5_LEN) - 1) << CCI_DTEN_AUPLL_DIV5_POS) +#define CCI_DTEN_AUPLL_DIV5_UMSK (~(((1U << CCI_DTEN_AUPLL_DIV5_LEN) - 1) << CCI_DTEN_AUPLL_DIV5_POS)) +#define CCI_DTEN_AUPLL_POSTDIV_CLK CCI_DTEN_AUPLL_POSTDIV_CLK +#define CCI_DTEN_AUPLL_POSTDIV_CLK_POS (9U) +#define CCI_DTEN_AUPLL_POSTDIV_CLK_LEN (1U) +#define CCI_DTEN_AUPLL_POSTDIV_CLK_MSK (((1U << CCI_DTEN_AUPLL_POSTDIV_CLK_LEN) - 1) << CCI_DTEN_AUPLL_POSTDIV_CLK_POS) +#define CCI_DTEN_AUPLL_POSTDIV_CLK_UMSK (~(((1U << CCI_DTEN_AUPLL_POSTDIV_CLK_LEN) - 1) << CCI_DTEN_AUPLL_POSTDIV_CLK_POS)) +#define CCI_DTEST_AUPLL_PULLDOWN CCI_DTEST_AUPLL_PULLDOWN +#define CCI_DTEST_AUPLL_PULLDOWN_POS (10U) +#define CCI_DTEST_AUPLL_PULLDOWN_LEN (1U) +#define CCI_DTEST_AUPLL_PULLDOWN_MSK (((1U << CCI_DTEST_AUPLL_PULLDOWN_LEN) - 1) << CCI_DTEST_AUPLL_PULLDOWN_POS) +#define CCI_DTEST_AUPLL_PULLDOWN_UMSK (~(((1U << CCI_DTEST_AUPLL_PULLDOWN_LEN) - 1) << CCI_DTEST_AUPLL_PULLDOWN_POS)) + +/* 0x778 : audio_pll_cfg10 */ +#define CCI_AUDIO_PLL_CFG10_OFFSET (0x778) +#define CCI_AUPLL_SSC_EN CCI_AUPLL_SSC_EN +#define CCI_AUPLL_SSC_EN_POS (0U) +#define CCI_AUPLL_SSC_EN_LEN (1U) +#define CCI_AUPLL_SSC_EN_MSK (((1U << CCI_AUPLL_SSC_EN_LEN) - 1) << CCI_AUPLL_SSC_EN_POS) +#define CCI_AUPLL_SSC_EN_UMSK (~(((1U << CCI_AUPLL_SSC_EN_LEN) - 1) << CCI_AUPLL_SSC_EN_POS)) +#define CCI_AUPLL_SSC_CNT CCI_AUPLL_SSC_CNT +#define CCI_AUPLL_SSC_CNT_POS (4U) +#define CCI_AUPLL_SSC_CNT_LEN (8U) +#define CCI_AUPLL_SSC_CNT_MSK (((1U << CCI_AUPLL_SSC_CNT_LEN) - 1) << CCI_AUPLL_SSC_CNT_POS) +#define CCI_AUPLL_SSC_CNT_UMSK (~(((1U << CCI_AUPLL_SSC_CNT_LEN) - 1) << CCI_AUPLL_SSC_CNT_POS)) +#define CCI_AUPLL_SSC_GAIN CCI_AUPLL_SSC_GAIN +#define CCI_AUPLL_SSC_GAIN_POS (12U) +#define CCI_AUPLL_SSC_GAIN_LEN (3U) +#define CCI_AUPLL_SSC_GAIN_MSK (((1U << CCI_AUPLL_SSC_GAIN_LEN) - 1) << CCI_AUPLL_SSC_GAIN_POS) +#define CCI_AUPLL_SSC_GAIN_UMSK (~(((1U << CCI_AUPLL_SSC_GAIN_LEN) - 1) << CCI_AUPLL_SSC_GAIN_POS)) +#define CCI_AUPLL_SSC_START_GATE_EN CCI_AUPLL_SSC_START_GATE_EN +#define CCI_AUPLL_SSC_START_GATE_EN_POS (16U) +#define CCI_AUPLL_SSC_START_GATE_EN_LEN (1U) +#define CCI_AUPLL_SSC_START_GATE_EN_MSK (((1U << CCI_AUPLL_SSC_START_GATE_EN_LEN) - 1) << CCI_AUPLL_SSC_START_GATE_EN_POS) +#define CCI_AUPLL_SSC_START_GATE_EN_UMSK (~(((1U << CCI_AUPLL_SSC_START_GATE_EN_LEN) - 1) << CCI_AUPLL_SSC_START_GATE_EN_POS)) +#define CCI_AUPLL_SSC_START CCI_AUPLL_SSC_START +#define CCI_AUPLL_SSC_START_POS (20U) +#define CCI_AUPLL_SSC_START_LEN (1U) +#define CCI_AUPLL_SSC_START_MSK (((1U << CCI_AUPLL_SSC_START_LEN) - 1) << CCI_AUPLL_SSC_START_POS) +#define CCI_AUPLL_SSC_START_UMSK (~(((1U << CCI_AUPLL_SSC_START_LEN) - 1) << CCI_AUPLL_SSC_START_POS)) + +/* 0x77C : audio_pll_cfg11 */ +#define CCI_AUDIO_PLL_CFG11_OFFSET (0x77C) +#define CCI_AUPLL_RESV CCI_AUPLL_RESV +#define CCI_AUPLL_RESV_POS (0U) +#define CCI_AUPLL_RESV_LEN (16U) +#define CCI_AUPLL_RESV_MSK (((1U << CCI_AUPLL_RESV_LEN) - 1) << CCI_AUPLL_RESV_POS) +#define CCI_AUPLL_RESV_UMSK (~(((1U << CCI_AUPLL_RESV_LEN) - 1) << CCI_AUPLL_RESV_POS)) +#define CCI_AUPLL_DL_CTRL_15 CCI_AUPLL_DL_CTRL_15 +#define CCI_AUPLL_DL_CTRL_15_POS (23U) +#define CCI_AUPLL_DL_CTRL_15_LEN (1U) +#define CCI_AUPLL_DL_CTRL_15_MSK (((1U << CCI_AUPLL_DL_CTRL_15_LEN) - 1) << CCI_AUPLL_DL_CTRL_15_POS) +#define CCI_AUPLL_DL_CTRL_15_UMSK (~(((1U << CCI_AUPLL_DL_CTRL_15_LEN) - 1) << CCI_AUPLL_DL_CTRL_15_POS)) +#define CCI_AUPLL_DL_CTRL_10 CCI_AUPLL_DL_CTRL_10 +#define CCI_AUPLL_DL_CTRL_10_POS (24U) +#define CCI_AUPLL_DL_CTRL_10_LEN (1U) +#define CCI_AUPLL_DL_CTRL_10_MSK (((1U << CCI_AUPLL_DL_CTRL_10_LEN) - 1) << CCI_AUPLL_DL_CTRL_10_POS) +#define CCI_AUPLL_DL_CTRL_10_UMSK (~(((1U << CCI_AUPLL_DL_CTRL_10_LEN) - 1) << CCI_AUPLL_DL_CTRL_10_POS)) +#define CCI_AUPLL_DL_CTRL_6 CCI_AUPLL_DL_CTRL_6 +#define CCI_AUPLL_DL_CTRL_6_POS (25U) +#define CCI_AUPLL_DL_CTRL_6_LEN (1U) +#define CCI_AUPLL_DL_CTRL_6_MSK (((1U << CCI_AUPLL_DL_CTRL_6_LEN) - 1) << CCI_AUPLL_DL_CTRL_6_POS) +#define CCI_AUPLL_DL_CTRL_6_UMSK (~(((1U << CCI_AUPLL_DL_CTRL_6_LEN) - 1) << CCI_AUPLL_DL_CTRL_6_POS)) +#define CCI_AUPLL_DL_CTRL_5 CCI_AUPLL_DL_CTRL_5 +#define CCI_AUPLL_DL_CTRL_5_POS (26U) +#define CCI_AUPLL_DL_CTRL_5_LEN (1U) +#define CCI_AUPLL_DL_CTRL_5_MSK (((1U << CCI_AUPLL_DL_CTRL_5_LEN) - 1) << CCI_AUPLL_DL_CTRL_5_POS) +#define CCI_AUPLL_DL_CTRL_5_UMSK (~(((1U << CCI_AUPLL_DL_CTRL_5_LEN) - 1) << CCI_AUPLL_DL_CTRL_5_POS)) +#define CCI_AUPLL_DL_CTRL_4 CCI_AUPLL_DL_CTRL_4 +#define CCI_AUPLL_DL_CTRL_4_POS (27U) +#define CCI_AUPLL_DL_CTRL_4_LEN (1U) +#define CCI_AUPLL_DL_CTRL_4_MSK (((1U << CCI_AUPLL_DL_CTRL_4_LEN) - 1) << CCI_AUPLL_DL_CTRL_4_POS) +#define CCI_AUPLL_DL_CTRL_4_UMSK (~(((1U << CCI_AUPLL_DL_CTRL_4_LEN) - 1) << CCI_AUPLL_DL_CTRL_4_POS)) +#define CCI_AUPLL_DL_CTRL_3 CCI_AUPLL_DL_CTRL_3 +#define CCI_AUPLL_DL_CTRL_3_POS (28U) +#define CCI_AUPLL_DL_CTRL_3_LEN (1U) +#define CCI_AUPLL_DL_CTRL_3_MSK (((1U << CCI_AUPLL_DL_CTRL_3_LEN) - 1) << CCI_AUPLL_DL_CTRL_3_POS) +#define CCI_AUPLL_DL_CTRL_3_UMSK (~(((1U << CCI_AUPLL_DL_CTRL_3_LEN) - 1) << CCI_AUPLL_DL_CTRL_3_POS)) +#define CCI_AUPLL_DL_CTRL_2P5 CCI_AUPLL_DL_CTRL_2P5 +#define CCI_AUPLL_DL_CTRL_2P5_POS (29U) +#define CCI_AUPLL_DL_CTRL_2P5_LEN (1U) +#define CCI_AUPLL_DL_CTRL_2P5_MSK (((1U << CCI_AUPLL_DL_CTRL_2P5_LEN) - 1) << CCI_AUPLL_DL_CTRL_2P5_POS) +#define CCI_AUPLL_DL_CTRL_2P5_UMSK (~(((1U << CCI_AUPLL_DL_CTRL_2P5_LEN) - 1) << CCI_AUPLL_DL_CTRL_2P5_POS)) +#define CCI_AUPLL_DL_CTRL_2 CCI_AUPLL_DL_CTRL_2 +#define CCI_AUPLL_DL_CTRL_2_POS (30U) +#define CCI_AUPLL_DL_CTRL_2_LEN (1U) +#define CCI_AUPLL_DL_CTRL_2_MSK (((1U << CCI_AUPLL_DL_CTRL_2_LEN) - 1) << CCI_AUPLL_DL_CTRL_2_POS) +#define CCI_AUPLL_DL_CTRL_2_UMSK (~(((1U << CCI_AUPLL_DL_CTRL_2_LEN) - 1) << CCI_AUPLL_DL_CTRL_2_POS)) +#define CCI_AUPLL_DL_CTRL_1 CCI_AUPLL_DL_CTRL_1 +#define CCI_AUPLL_DL_CTRL_1_POS (31U) +#define CCI_AUPLL_DL_CTRL_1_LEN (1U) +#define CCI_AUPLL_DL_CTRL_1_MSK (((1U << CCI_AUPLL_DL_CTRL_1_LEN) - 1) << CCI_AUPLL_DL_CTRL_1_POS) +#define CCI_AUPLL_DL_CTRL_1_UMSK (~(((1U << CCI_AUPLL_DL_CTRL_1_LEN) - 1) << CCI_AUPLL_DL_CTRL_1_POS)) + +/* 0x7D0 : cpu_pll_cfg0 */ +#define CCI_CPU_PLL_CFG0_OFFSET (0x7D0) +#define CCI_CPUPLL_SDM_RSTB CCI_CPUPLL_SDM_RSTB +#define CCI_CPUPLL_SDM_RSTB_POS (0U) +#define CCI_CPUPLL_SDM_RSTB_LEN (1U) +#define CCI_CPUPLL_SDM_RSTB_MSK (((1U << CCI_CPUPLL_SDM_RSTB_LEN) - 1) << CCI_CPUPLL_SDM_RSTB_POS) +#define CCI_CPUPLL_SDM_RSTB_UMSK (~(((1U << CCI_CPUPLL_SDM_RSTB_LEN) - 1) << CCI_CPUPLL_SDM_RSTB_POS)) +#define CCI_CPUPLL_POSTDIV_RSTB CCI_CPUPLL_POSTDIV_RSTB +#define CCI_CPUPLL_POSTDIV_RSTB_POS (1U) +#define CCI_CPUPLL_POSTDIV_RSTB_LEN (1U) +#define CCI_CPUPLL_POSTDIV_RSTB_MSK (((1U << CCI_CPUPLL_POSTDIV_RSTB_LEN) - 1) << CCI_CPUPLL_POSTDIV_RSTB_POS) +#define CCI_CPUPLL_POSTDIV_RSTB_UMSK (~(((1U << CCI_CPUPLL_POSTDIV_RSTB_LEN) - 1) << CCI_CPUPLL_POSTDIV_RSTB_POS)) +#define CCI_CPUPLL_FBDV_RSTB CCI_CPUPLL_FBDV_RSTB +#define CCI_CPUPLL_FBDV_RSTB_POS (2U) +#define CCI_CPUPLL_FBDV_RSTB_LEN (1U) +#define CCI_CPUPLL_FBDV_RSTB_MSK (((1U << CCI_CPUPLL_FBDV_RSTB_LEN) - 1) << CCI_CPUPLL_FBDV_RSTB_POS) +#define CCI_CPUPLL_FBDV_RSTB_UMSK (~(((1U << CCI_CPUPLL_FBDV_RSTB_LEN) - 1) << CCI_CPUPLL_FBDV_RSTB_POS)) +#define CCI_CPUPLL_REFDIV_RSTB CCI_CPUPLL_REFDIV_RSTB +#define CCI_CPUPLL_REFDIV_RSTB_POS (3U) +#define CCI_CPUPLL_REFDIV_RSTB_LEN (1U) +#define CCI_CPUPLL_REFDIV_RSTB_MSK (((1U << CCI_CPUPLL_REFDIV_RSTB_LEN) - 1) << CCI_CPUPLL_REFDIV_RSTB_POS) +#define CCI_CPUPLL_REFDIV_RSTB_UMSK (~(((1U << CCI_CPUPLL_REFDIV_RSTB_LEN) - 1) << CCI_CPUPLL_REFDIV_RSTB_POS)) +#define CCI_PU_CPUPLL_POSTDIV CCI_PU_CPUPLL_POSTDIV +#define CCI_PU_CPUPLL_POSTDIV_POS (4U) +#define CCI_PU_CPUPLL_POSTDIV_LEN (1U) +#define CCI_PU_CPUPLL_POSTDIV_MSK (((1U << CCI_PU_CPUPLL_POSTDIV_LEN) - 1) << CCI_PU_CPUPLL_POSTDIV_POS) +#define CCI_PU_CPUPLL_POSTDIV_UMSK (~(((1U << CCI_PU_CPUPLL_POSTDIV_LEN) - 1) << CCI_PU_CPUPLL_POSTDIV_POS)) +#define CCI_PU_CPUPLL_FBDV CCI_PU_CPUPLL_FBDV +#define CCI_PU_CPUPLL_FBDV_POS (5U) +#define CCI_PU_CPUPLL_FBDV_LEN (1U) +#define CCI_PU_CPUPLL_FBDV_MSK (((1U << CCI_PU_CPUPLL_FBDV_LEN) - 1) << CCI_PU_CPUPLL_FBDV_POS) +#define CCI_PU_CPUPLL_FBDV_UMSK (~(((1U << CCI_PU_CPUPLL_FBDV_LEN) - 1) << CCI_PU_CPUPLL_FBDV_POS)) +#define CCI_PU_CPUPLL_CLAMP_OP CCI_PU_CPUPLL_CLAMP_OP +#define CCI_PU_CPUPLL_CLAMP_OP_POS (6U) +#define CCI_PU_CPUPLL_CLAMP_OP_LEN (1U) +#define CCI_PU_CPUPLL_CLAMP_OP_MSK (((1U << CCI_PU_CPUPLL_CLAMP_OP_LEN) - 1) << CCI_PU_CPUPLL_CLAMP_OP_POS) +#define CCI_PU_CPUPLL_CLAMP_OP_UMSK (~(((1U << CCI_PU_CPUPLL_CLAMP_OP_LEN) - 1) << CCI_PU_CPUPLL_CLAMP_OP_POS)) +#define CCI_PU_CPUPLL_PFD CCI_PU_CPUPLL_PFD +#define CCI_PU_CPUPLL_PFD_POS (7U) +#define CCI_PU_CPUPLL_PFD_LEN (1U) +#define CCI_PU_CPUPLL_PFD_MSK (((1U << CCI_PU_CPUPLL_PFD_LEN) - 1) << CCI_PU_CPUPLL_PFD_POS) +#define CCI_PU_CPUPLL_PFD_UMSK (~(((1U << CCI_PU_CPUPLL_PFD_LEN) - 1) << CCI_PU_CPUPLL_PFD_POS)) +#define CCI_PU_CPUPLL_CP CCI_PU_CPUPLL_CP +#define CCI_PU_CPUPLL_CP_POS (8U) +#define CCI_PU_CPUPLL_CP_LEN (1U) +#define CCI_PU_CPUPLL_CP_MSK (((1U << CCI_PU_CPUPLL_CP_LEN) - 1) << CCI_PU_CPUPLL_CP_POS) +#define CCI_PU_CPUPLL_CP_UMSK (~(((1U << CCI_PU_CPUPLL_CP_LEN) - 1) << CCI_PU_CPUPLL_CP_POS)) +#define CCI_PU_CPUPLL_SFREG CCI_PU_CPUPLL_SFREG +#define CCI_PU_CPUPLL_SFREG_POS (9U) +#define CCI_PU_CPUPLL_SFREG_LEN (1U) +#define CCI_PU_CPUPLL_SFREG_MSK (((1U << CCI_PU_CPUPLL_SFREG_LEN) - 1) << CCI_PU_CPUPLL_SFREG_POS) +#define CCI_PU_CPUPLL_SFREG_UMSK (~(((1U << CCI_PU_CPUPLL_SFREG_LEN) - 1) << CCI_PU_CPUPLL_SFREG_POS)) +#define CCI_PU_CPUPLL CCI_PU_CPUPLL +#define CCI_PU_CPUPLL_POS (10U) +#define CCI_PU_CPUPLL_LEN (1U) +#define CCI_PU_CPUPLL_MSK (((1U << CCI_PU_CPUPLL_LEN) - 1) << CCI_PU_CPUPLL_POS) +#define CCI_PU_CPUPLL_UMSK (~(((1U << CCI_PU_CPUPLL_LEN) - 1) << CCI_PU_CPUPLL_POS)) +#define CCI_PU_CPUPLL_CLKTREE CCI_PU_CPUPLL_CLKTREE +#define CCI_PU_CPUPLL_CLKTREE_POS (11U) +#define CCI_PU_CPUPLL_CLKTREE_LEN (1U) +#define CCI_PU_CPUPLL_CLKTREE_MSK (((1U << CCI_PU_CPUPLL_CLKTREE_LEN) - 1) << CCI_PU_CPUPLL_CLKTREE_POS) +#define CCI_PU_CPUPLL_CLKTREE_UMSK (~(((1U << CCI_PU_CPUPLL_CLKTREE_LEN) - 1) << CCI_PU_CPUPLL_CLKTREE_POS)) + +/* 0x7D4 : cpu_pll_cfg1 */ +#define CCI_CPU_PLL_CFG1_OFFSET (0x7D4) +#define CCI_CPUPLL_POSTDIV CCI_CPUPLL_POSTDIV +#define CCI_CPUPLL_POSTDIV_POS (0U) +#define CCI_CPUPLL_POSTDIV_LEN (7U) +#define CCI_CPUPLL_POSTDIV_MSK (((1U << CCI_CPUPLL_POSTDIV_LEN) - 1) << CCI_CPUPLL_POSTDIV_POS) +#define CCI_CPUPLL_POSTDIV_UMSK (~(((1U << CCI_CPUPLL_POSTDIV_LEN) - 1) << CCI_CPUPLL_POSTDIV_POS)) +#define CCI_CPUPLL_REFDIV_RATIO CCI_CPUPLL_REFDIV_RATIO +#define CCI_CPUPLL_REFDIV_RATIO_POS (8U) +#define CCI_CPUPLL_REFDIV_RATIO_LEN (4U) +#define CCI_CPUPLL_REFDIV_RATIO_MSK (((1U << CCI_CPUPLL_REFDIV_RATIO_LEN) - 1) << CCI_CPUPLL_REFDIV_RATIO_POS) +#define CCI_CPUPLL_REFDIV_RATIO_UMSK (~(((1U << CCI_CPUPLL_REFDIV_RATIO_LEN) - 1) << CCI_CPUPLL_REFDIV_RATIO_POS)) +#define CCI_CPUPLL_REFCLK_SEL CCI_CPUPLL_REFCLK_SEL +#define CCI_CPUPLL_REFCLK_SEL_POS (16U) +#define CCI_CPUPLL_REFCLK_SEL_LEN (2U) +#define CCI_CPUPLL_REFCLK_SEL_MSK (((1U << CCI_CPUPLL_REFCLK_SEL_LEN) - 1) << CCI_CPUPLL_REFCLK_SEL_POS) +#define CCI_CPUPLL_REFCLK_SEL_UMSK (~(((1U << CCI_CPUPLL_REFCLK_SEL_LEN) - 1) << CCI_CPUPLL_REFCLK_SEL_POS)) +#define CCI_CPUPLL_VG11_SEL CCI_CPUPLL_VG11_SEL +#define CCI_CPUPLL_VG11_SEL_POS (20U) +#define CCI_CPUPLL_VG11_SEL_LEN (2U) +#define CCI_CPUPLL_VG11_SEL_MSK (((1U << CCI_CPUPLL_VG11_SEL_LEN) - 1) << CCI_CPUPLL_VG11_SEL_POS) +#define CCI_CPUPLL_VG11_SEL_UMSK (~(((1U << CCI_CPUPLL_VG11_SEL_LEN) - 1) << CCI_CPUPLL_VG11_SEL_POS)) +#define CCI_CPUPLL_VG13_SEL CCI_CPUPLL_VG13_SEL +#define CCI_CPUPLL_VG13_SEL_POS (24U) +#define CCI_CPUPLL_VG13_SEL_LEN (2U) +#define CCI_CPUPLL_VG13_SEL_MSK (((1U << CCI_CPUPLL_VG13_SEL_LEN) - 1) << CCI_CPUPLL_VG13_SEL_POS) +#define CCI_CPUPLL_VG13_SEL_UMSK (~(((1U << CCI_CPUPLL_VG13_SEL_LEN) - 1) << CCI_CPUPLL_VG13_SEL_POS)) + +/* 0x7D8 : cpu_pll_cfg2 */ +#define CCI_CPU_PLL_CFG2_OFFSET (0x7D8) +#define CCI_CPUPLL_SEL_CP_BIAS CCI_CPUPLL_SEL_CP_BIAS +#define CCI_CPUPLL_SEL_CP_BIAS_POS (0U) +#define CCI_CPUPLL_SEL_CP_BIAS_LEN (1U) +#define CCI_CPUPLL_SEL_CP_BIAS_MSK (((1U << CCI_CPUPLL_SEL_CP_BIAS_LEN) - 1) << CCI_CPUPLL_SEL_CP_BIAS_POS) +#define CCI_CPUPLL_SEL_CP_BIAS_UMSK (~(((1U << CCI_CPUPLL_SEL_CP_BIAS_LEN) - 1) << CCI_CPUPLL_SEL_CP_BIAS_POS)) +#define CCI_CPUPLL_ICP_5U CCI_CPUPLL_ICP_5U +#define CCI_CPUPLL_ICP_5U_POS (4U) +#define CCI_CPUPLL_ICP_5U_LEN (2U) +#define CCI_CPUPLL_ICP_5U_MSK (((1U << CCI_CPUPLL_ICP_5U_LEN) - 1) << CCI_CPUPLL_ICP_5U_POS) +#define CCI_CPUPLL_ICP_5U_UMSK (~(((1U << CCI_CPUPLL_ICP_5U_LEN) - 1) << CCI_CPUPLL_ICP_5U_POS)) +#define CCI_CPUPLL_ICP_1U CCI_CPUPLL_ICP_1U +#define CCI_CPUPLL_ICP_1U_POS (6U) +#define CCI_CPUPLL_ICP_1U_LEN (2U) +#define CCI_CPUPLL_ICP_1U_MSK (((1U << CCI_CPUPLL_ICP_1U_LEN) - 1) << CCI_CPUPLL_ICP_1U_POS) +#define CCI_CPUPLL_ICP_1U_UMSK (~(((1U << CCI_CPUPLL_ICP_1U_LEN) - 1) << CCI_CPUPLL_ICP_1U_POS)) +#define CCI_CPUPLL_INT_FRAC_SW CCI_CPUPLL_INT_FRAC_SW +#define CCI_CPUPLL_INT_FRAC_SW_POS (8U) +#define CCI_CPUPLL_INT_FRAC_SW_LEN (1U) +#define CCI_CPUPLL_INT_FRAC_SW_MSK (((1U << CCI_CPUPLL_INT_FRAC_SW_LEN) - 1) << CCI_CPUPLL_INT_FRAC_SW_POS) +#define CCI_CPUPLL_INT_FRAC_SW_UMSK (~(((1U << CCI_CPUPLL_INT_FRAC_SW_LEN) - 1) << CCI_CPUPLL_INT_FRAC_SW_POS)) +#define CCI_CPUPLL_CP_STARTUP_EN CCI_CPUPLL_CP_STARTUP_EN +#define CCI_CPUPLL_CP_STARTUP_EN_POS (9U) +#define CCI_CPUPLL_CP_STARTUP_EN_LEN (1U) +#define CCI_CPUPLL_CP_STARTUP_EN_MSK (((1U << CCI_CPUPLL_CP_STARTUP_EN_LEN) - 1) << CCI_CPUPLL_CP_STARTUP_EN_POS) +#define CCI_CPUPLL_CP_STARTUP_EN_UMSK (~(((1U << CCI_CPUPLL_CP_STARTUP_EN_LEN) - 1) << CCI_CPUPLL_CP_STARTUP_EN_POS)) +#define CCI_CPUPLL_CP_OPAMP_EN CCI_CPUPLL_CP_OPAMP_EN +#define CCI_CPUPLL_CP_OPAMP_EN_POS (10U) +#define CCI_CPUPLL_CP_OPAMP_EN_LEN (1U) +#define CCI_CPUPLL_CP_OPAMP_EN_MSK (((1U << CCI_CPUPLL_CP_OPAMP_EN_LEN) - 1) << CCI_CPUPLL_CP_OPAMP_EN_POS) +#define CCI_CPUPLL_CP_OPAMP_EN_UMSK (~(((1U << CCI_CPUPLL_CP_OPAMP_EN_LEN) - 1) << CCI_CPUPLL_CP_OPAMP_EN_POS)) + +/* 0x7DC : cpu_pll_cfg3 */ +#define CCI_CPU_PLL_CFG3_OFFSET (0x7DC) +#define CCI_CPUPLL_C4_EN CCI_CPUPLL_C4_EN +#define CCI_CPUPLL_C4_EN_POS (0U) +#define CCI_CPUPLL_C4_EN_LEN (1U) +#define CCI_CPUPLL_C4_EN_MSK (((1U << CCI_CPUPLL_C4_EN_LEN) - 1) << CCI_CPUPLL_C4_EN_POS) +#define CCI_CPUPLL_C4_EN_UMSK (~(((1U << CCI_CPUPLL_C4_EN_LEN) - 1) << CCI_CPUPLL_C4_EN_POS)) +#define CCI_CPUPLL_R4 CCI_CPUPLL_R4 +#define CCI_CPUPLL_R4_POS (4U) +#define CCI_CPUPLL_R4_LEN (2U) +#define CCI_CPUPLL_R4_MSK (((1U << CCI_CPUPLL_R4_LEN) - 1) << CCI_CPUPLL_R4_POS) +#define CCI_CPUPLL_R4_UMSK (~(((1U << CCI_CPUPLL_R4_LEN) - 1) << CCI_CPUPLL_R4_POS)) +#define CCI_CPUPLL_R4_SHORT CCI_CPUPLL_R4_SHORT +#define CCI_CPUPLL_R4_SHORT_POS (8U) +#define CCI_CPUPLL_R4_SHORT_LEN (1U) +#define CCI_CPUPLL_R4_SHORT_MSK (((1U << CCI_CPUPLL_R4_SHORT_LEN) - 1) << CCI_CPUPLL_R4_SHORT_POS) +#define CCI_CPUPLL_R4_SHORT_UMSK (~(((1U << CCI_CPUPLL_R4_SHORT_LEN) - 1) << CCI_CPUPLL_R4_SHORT_POS)) +#define CCI_CPUPLL_C3 CCI_CPUPLL_C3 +#define CCI_CPUPLL_C3_POS (12U) +#define CCI_CPUPLL_C3_LEN (2U) +#define CCI_CPUPLL_C3_MSK (((1U << CCI_CPUPLL_C3_LEN) - 1) << CCI_CPUPLL_C3_POS) +#define CCI_CPUPLL_C3_UMSK (~(((1U << CCI_CPUPLL_C3_LEN) - 1) << CCI_CPUPLL_C3_POS)) +#define CCI_CPUPLL_CZ CCI_CPUPLL_CZ +#define CCI_CPUPLL_CZ_POS (14U) +#define CCI_CPUPLL_CZ_LEN (2U) +#define CCI_CPUPLL_CZ_MSK (((1U << CCI_CPUPLL_CZ_LEN) - 1) << CCI_CPUPLL_CZ_POS) +#define CCI_CPUPLL_CZ_UMSK (~(((1U << CCI_CPUPLL_CZ_LEN) - 1) << CCI_CPUPLL_CZ_POS)) +#define CCI_CPUPLL_RZ CCI_CPUPLL_RZ +#define CCI_CPUPLL_RZ_POS (16U) +#define CCI_CPUPLL_RZ_LEN (3U) +#define CCI_CPUPLL_RZ_MSK (((1U << CCI_CPUPLL_RZ_LEN) - 1) << CCI_CPUPLL_RZ_POS) +#define CCI_CPUPLL_RZ_UMSK (~(((1U << CCI_CPUPLL_RZ_LEN) - 1) << CCI_CPUPLL_RZ_POS)) + +/* 0x7E0 : cpu_pll_cfg4 */ +#define CCI_CPU_PLL_CFG4_OFFSET (0x7E0) +#define CCI_CPUPLL_SEL_SAMPLE_CLK CCI_CPUPLL_SEL_SAMPLE_CLK +#define CCI_CPUPLL_SEL_SAMPLE_CLK_POS (0U) +#define CCI_CPUPLL_SEL_SAMPLE_CLK_LEN (2U) +#define CCI_CPUPLL_SEL_SAMPLE_CLK_MSK (((1U << CCI_CPUPLL_SEL_SAMPLE_CLK_LEN) - 1) << CCI_CPUPLL_SEL_SAMPLE_CLK_POS) +#define CCI_CPUPLL_SEL_SAMPLE_CLK_UMSK (~(((1U << CCI_CPUPLL_SEL_SAMPLE_CLK_LEN) - 1) << CCI_CPUPLL_SEL_SAMPLE_CLK_POS)) +#define CCI_CPUPLL_SEL_FB_CLK CCI_CPUPLL_SEL_FB_CLK +#define CCI_CPUPLL_SEL_FB_CLK_POS (4U) +#define CCI_CPUPLL_SEL_FB_CLK_LEN (2U) +#define CCI_CPUPLL_SEL_FB_CLK_MSK (((1U << CCI_CPUPLL_SEL_FB_CLK_LEN) - 1) << CCI_CPUPLL_SEL_FB_CLK_POS) +#define CCI_CPUPLL_SEL_FB_CLK_UMSK (~(((1U << CCI_CPUPLL_SEL_FB_CLK_LEN) - 1) << CCI_CPUPLL_SEL_FB_CLK_POS)) +#define CCI_CPUPLL_SDMCLK_SEL CCI_CPUPLL_SDMCLK_SEL +#define CCI_CPUPLL_SDMCLK_SEL_POS (8U) +#define CCI_CPUPLL_SDMCLK_SEL_LEN (1U) +#define CCI_CPUPLL_SDMCLK_SEL_MSK (((1U << CCI_CPUPLL_SDMCLK_SEL_LEN) - 1) << CCI_CPUPLL_SDMCLK_SEL_POS) +#define CCI_CPUPLL_SDMCLK_SEL_UMSK (~(((1U << CCI_CPUPLL_SDMCLK_SEL_LEN) - 1) << CCI_CPUPLL_SDMCLK_SEL_POS)) + +/* 0x7E4 : cpu_pll_cfg5 */ +#define CCI_CPU_PLL_CFG5_OFFSET (0x7E4) +#define CCI_CPUPLL_VCO_SPEED CCI_CPUPLL_VCO_SPEED +#define CCI_CPUPLL_VCO_SPEED_POS (0U) +#define CCI_CPUPLL_VCO_SPEED_LEN (3U) +#define CCI_CPUPLL_VCO_SPEED_MSK (((1U << CCI_CPUPLL_VCO_SPEED_LEN) - 1) << CCI_CPUPLL_VCO_SPEED_POS) +#define CCI_CPUPLL_VCO_SPEED_UMSK (~(((1U << CCI_CPUPLL_VCO_SPEED_LEN) - 1) << CCI_CPUPLL_VCO_SPEED_POS)) + +/* 0x7E8 : cpu_pll_cfg6 */ +#define CCI_CPU_PLL_CFG6_OFFSET (0x7E8) +#define CCI_CPUPLL_SDMIN CCI_CPUPLL_SDMIN +#define CCI_CPUPLL_SDMIN_POS (0U) +#define CCI_CPUPLL_SDMIN_LEN (19U) +#define CCI_CPUPLL_SDMIN_MSK (((1U << CCI_CPUPLL_SDMIN_LEN) - 1) << CCI_CPUPLL_SDMIN_POS) +#define CCI_CPUPLL_SDMIN_UMSK (~(((1U << CCI_CPUPLL_SDMIN_LEN) - 1) << CCI_CPUPLL_SDMIN_POS)) +#define CCI_CPUPLL_SDM_BYPASS CCI_CPUPLL_SDM_BYPASS +#define CCI_CPUPLL_SDM_BYPASS_POS (24U) +#define CCI_CPUPLL_SDM_BYPASS_LEN (1U) +#define CCI_CPUPLL_SDM_BYPASS_MSK (((1U << CCI_CPUPLL_SDM_BYPASS_LEN) - 1) << CCI_CPUPLL_SDM_BYPASS_POS) +#define CCI_CPUPLL_SDM_BYPASS_UMSK (~(((1U << CCI_CPUPLL_SDM_BYPASS_LEN) - 1) << CCI_CPUPLL_SDM_BYPASS_POS)) + +/* 0x7EC : cpu_pll_cfg7 */ +#define CCI_CPU_PLL_CFG7_OFFSET (0x7EC) +#define CCI_CPUPLL_SDM_ORDER_SEL CCI_CPUPLL_SDM_ORDER_SEL +#define CCI_CPUPLL_SDM_ORDER_SEL_POS (0U) +#define CCI_CPUPLL_SDM_ORDER_SEL_LEN (1U) +#define CCI_CPUPLL_SDM_ORDER_SEL_MSK (((1U << CCI_CPUPLL_SDM_ORDER_SEL_LEN) - 1) << CCI_CPUPLL_SDM_ORDER_SEL_POS) +#define CCI_CPUPLL_SDM_ORDER_SEL_UMSK (~(((1U << CCI_CPUPLL_SDM_ORDER_SEL_LEN) - 1) << CCI_CPUPLL_SDM_ORDER_SEL_POS)) +#define CCI_CPUPLL_SDM_SIG_DITH_SEL CCI_CPUPLL_SDM_SIG_DITH_SEL +#define CCI_CPUPLL_SDM_SIG_DITH_SEL_POS (16U) +#define CCI_CPUPLL_SDM_SIG_DITH_SEL_LEN (2U) +#define CCI_CPUPLL_SDM_SIG_DITH_SEL_MSK (((1U << CCI_CPUPLL_SDM_SIG_DITH_SEL_LEN) - 1) << CCI_CPUPLL_SDM_SIG_DITH_SEL_POS) +#define CCI_CPUPLL_SDM_SIG_DITH_SEL_UMSK (~(((1U << CCI_CPUPLL_SDM_SIG_DITH_SEL_LEN) - 1) << CCI_CPUPLL_SDM_SIG_DITH_SEL_POS)) + +/* 0x7F0 : cpu_pll_cfg8 */ +#define CCI_CPU_PLL_CFG8_OFFSET (0x7F0) +#define CCI_CPUPLL_EN_DIV1 CCI_CPUPLL_EN_DIV1 +#define CCI_CPUPLL_EN_DIV1_POS (0U) +#define CCI_CPUPLL_EN_DIV1_LEN (1U) +#define CCI_CPUPLL_EN_DIV1_MSK (((1U << CCI_CPUPLL_EN_DIV1_LEN) - 1) << CCI_CPUPLL_EN_DIV1_POS) +#define CCI_CPUPLL_EN_DIV1_UMSK (~(((1U << CCI_CPUPLL_EN_DIV1_LEN) - 1) << CCI_CPUPLL_EN_DIV1_POS)) +#define CCI_CPUPLL_EN_DIV2 CCI_CPUPLL_EN_DIV2 +#define CCI_CPUPLL_EN_DIV2_POS (1U) +#define CCI_CPUPLL_EN_DIV2_LEN (1U) +#define CCI_CPUPLL_EN_DIV2_MSK (((1U << CCI_CPUPLL_EN_DIV2_LEN) - 1) << CCI_CPUPLL_EN_DIV2_POS) +#define CCI_CPUPLL_EN_DIV2_UMSK (~(((1U << CCI_CPUPLL_EN_DIV2_LEN) - 1) << CCI_CPUPLL_EN_DIV2_POS)) +#define CCI_CPUPLL_EN_DIV2P5 CCI_CPUPLL_EN_DIV2P5 +#define CCI_CPUPLL_EN_DIV2P5_POS (2U) +#define CCI_CPUPLL_EN_DIV2P5_LEN (1U) +#define CCI_CPUPLL_EN_DIV2P5_MSK (((1U << CCI_CPUPLL_EN_DIV2P5_LEN) - 1) << CCI_CPUPLL_EN_DIV2P5_POS) +#define CCI_CPUPLL_EN_DIV2P5_UMSK (~(((1U << CCI_CPUPLL_EN_DIV2P5_LEN) - 1) << CCI_CPUPLL_EN_DIV2P5_POS)) +#define CCI_CPUPLL_EN_DIV3 CCI_CPUPLL_EN_DIV3 +#define CCI_CPUPLL_EN_DIV3_POS (3U) +#define CCI_CPUPLL_EN_DIV3_LEN (1U) +#define CCI_CPUPLL_EN_DIV3_MSK (((1U << CCI_CPUPLL_EN_DIV3_LEN) - 1) << CCI_CPUPLL_EN_DIV3_POS) +#define CCI_CPUPLL_EN_DIV3_UMSK (~(((1U << CCI_CPUPLL_EN_DIV3_LEN) - 1) << CCI_CPUPLL_EN_DIV3_POS)) +#define CCI_CPUPLL_EN_DIV4 CCI_CPUPLL_EN_DIV4 +#define CCI_CPUPLL_EN_DIV4_POS (4U) +#define CCI_CPUPLL_EN_DIV4_LEN (1U) +#define CCI_CPUPLL_EN_DIV4_MSK (((1U << CCI_CPUPLL_EN_DIV4_LEN) - 1) << CCI_CPUPLL_EN_DIV4_POS) +#define CCI_CPUPLL_EN_DIV4_UMSK (~(((1U << CCI_CPUPLL_EN_DIV4_LEN) - 1) << CCI_CPUPLL_EN_DIV4_POS)) +#define CCI_CPUPLL_EN_DIV5 CCI_CPUPLL_EN_DIV5 +#define CCI_CPUPLL_EN_DIV5_POS (5U) +#define CCI_CPUPLL_EN_DIV5_LEN (1U) +#define CCI_CPUPLL_EN_DIV5_MSK (((1U << CCI_CPUPLL_EN_DIV5_LEN) - 1) << CCI_CPUPLL_EN_DIV5_POS) +#define CCI_CPUPLL_EN_DIV5_UMSK (~(((1U << CCI_CPUPLL_EN_DIV5_LEN) - 1) << CCI_CPUPLL_EN_DIV5_POS)) +#define CCI_CPUPLL_EN_DIV6 CCI_CPUPLL_EN_DIV6 +#define CCI_CPUPLL_EN_DIV6_POS (6U) +#define CCI_CPUPLL_EN_DIV6_LEN (1U) +#define CCI_CPUPLL_EN_DIV6_MSK (((1U << CCI_CPUPLL_EN_DIV6_LEN) - 1) << CCI_CPUPLL_EN_DIV6_POS) +#define CCI_CPUPLL_EN_DIV6_UMSK (~(((1U << CCI_CPUPLL_EN_DIV6_LEN) - 1) << CCI_CPUPLL_EN_DIV6_POS)) +#define CCI_CPUPLL_EN_DIV10 CCI_CPUPLL_EN_DIV10 +#define CCI_CPUPLL_EN_DIV10_POS (7U) +#define CCI_CPUPLL_EN_DIV10_LEN (1U) +#define CCI_CPUPLL_EN_DIV10_MSK (((1U << CCI_CPUPLL_EN_DIV10_LEN) - 1) << CCI_CPUPLL_EN_DIV10_POS) +#define CCI_CPUPLL_EN_DIV10_UMSK (~(((1U << CCI_CPUPLL_EN_DIV10_LEN) - 1) << CCI_CPUPLL_EN_DIV10_POS)) +#define CCI_CPUPLL_EN_DIV15 CCI_CPUPLL_EN_DIV15 +#define CCI_CPUPLL_EN_DIV15_POS (8U) +#define CCI_CPUPLL_EN_DIV15_LEN (1U) +#define CCI_CPUPLL_EN_DIV15_MSK (((1U << CCI_CPUPLL_EN_DIV15_LEN) - 1) << CCI_CPUPLL_EN_DIV15_POS) +#define CCI_CPUPLL_EN_DIV15_UMSK (~(((1U << CCI_CPUPLL_EN_DIV15_LEN) - 1) << CCI_CPUPLL_EN_DIV15_POS)) +#define CCI_CPUPLL_SEL_DIV1_DIV2 CCI_CPUPLL_SEL_DIV1_DIV2 +#define CCI_CPUPLL_SEL_DIV1_DIV2_POS (9U) +#define CCI_CPUPLL_SEL_DIV1_DIV2_LEN (1U) +#define CCI_CPUPLL_SEL_DIV1_DIV2_MSK (((1U << CCI_CPUPLL_SEL_DIV1_DIV2_LEN) - 1) << CCI_CPUPLL_SEL_DIV1_DIV2_POS) +#define CCI_CPUPLL_SEL_DIV1_DIV2_UMSK (~(((1U << CCI_CPUPLL_SEL_DIV1_DIV2_LEN) - 1) << CCI_CPUPLL_SEL_DIV1_DIV2_POS)) + +/* 0x7F4 : cpu_pll_cfg9 */ +#define CCI_CPU_PLL_CFG9_OFFSET (0x7F4) +#define CCI_CPUPLL_DC_TP_OUT_EN CCI_CPUPLL_DC_TP_OUT_EN +#define CCI_CPUPLL_DC_TP_OUT_EN_POS (0U) +#define CCI_CPUPLL_DC_TP_OUT_EN_LEN (1U) +#define CCI_CPUPLL_DC_TP_OUT_EN_MSK (((1U << CCI_CPUPLL_DC_TP_OUT_EN_LEN) - 1) << CCI_CPUPLL_DC_TP_OUT_EN_POS) +#define CCI_CPUPLL_DC_TP_OUT_EN_UMSK (~(((1U << CCI_CPUPLL_DC_TP_OUT_EN_LEN) - 1) << CCI_CPUPLL_DC_TP_OUT_EN_POS)) +#define CCI_TEN_CPUPLL CCI_TEN_CPUPLL +#define CCI_TEN_CPUPLL_POS (1U) +#define CCI_TEN_CPUPLL_LEN (1U) +#define CCI_TEN_CPUPLL_MSK (((1U << CCI_TEN_CPUPLL_LEN) - 1) << CCI_TEN_CPUPLL_POS) +#define CCI_TEN_CPUPLL_UMSK (~(((1U << CCI_TEN_CPUPLL_LEN) - 1) << CCI_TEN_CPUPLL_POS)) +#define CCI_TEN_CPUPLL_SFREG CCI_TEN_CPUPLL_SFREG +#define CCI_TEN_CPUPLL_SFREG_POS (2U) +#define CCI_TEN_CPUPLL_SFREG_LEN (1U) +#define CCI_TEN_CPUPLL_SFREG_MSK (((1U << CCI_TEN_CPUPLL_SFREG_LEN) - 1) << CCI_TEN_CPUPLL_SFREG_POS) +#define CCI_TEN_CPUPLL_SFREG_UMSK (~(((1U << CCI_TEN_CPUPLL_SFREG_LEN) - 1) << CCI_TEN_CPUPLL_SFREG_POS)) +#define CCI_DTEN_CPUPLL_FIN CCI_DTEN_CPUPLL_FIN +#define CCI_DTEN_CPUPLL_FIN_POS (4U) +#define CCI_DTEN_CPUPLL_FIN_LEN (1U) +#define CCI_DTEN_CPUPLL_FIN_MSK (((1U << CCI_DTEN_CPUPLL_FIN_LEN) - 1) << CCI_DTEN_CPUPLL_FIN_POS) +#define CCI_DTEN_CPUPLL_FIN_UMSK (~(((1U << CCI_DTEN_CPUPLL_FIN_LEN) - 1) << CCI_DTEN_CPUPLL_FIN_POS)) +#define CCI_DTEN_CPUPLL_FREF CCI_DTEN_CPUPLL_FREF +#define CCI_DTEN_CPUPLL_FREF_POS (5U) +#define CCI_DTEN_CPUPLL_FREF_LEN (1U) +#define CCI_DTEN_CPUPLL_FREF_MSK (((1U << CCI_DTEN_CPUPLL_FREF_LEN) - 1) << CCI_DTEN_CPUPLL_FREF_POS) +#define CCI_DTEN_CPUPLL_FREF_UMSK (~(((1U << CCI_DTEN_CPUPLL_FREF_LEN) - 1) << CCI_DTEN_CPUPLL_FREF_POS)) +#define CCI_DTEN_CPUPLL_FSDM CCI_DTEN_CPUPLL_FSDM +#define CCI_DTEN_CPUPLL_FSDM_POS (6U) +#define CCI_DTEN_CPUPLL_FSDM_LEN (1U) +#define CCI_DTEN_CPUPLL_FSDM_MSK (((1U << CCI_DTEN_CPUPLL_FSDM_LEN) - 1) << CCI_DTEN_CPUPLL_FSDM_POS) +#define CCI_DTEN_CPUPLL_FSDM_UMSK (~(((1U << CCI_DTEN_CPUPLL_FSDM_LEN) - 1) << CCI_DTEN_CPUPLL_FSDM_POS)) +#define CCI_DTEN_CPUPLL_DIV15 CCI_DTEN_CPUPLL_DIV15 +#define CCI_DTEN_CPUPLL_DIV15_POS (7U) +#define CCI_DTEN_CPUPLL_DIV15_LEN (1U) +#define CCI_DTEN_CPUPLL_DIV15_MSK (((1U << CCI_DTEN_CPUPLL_DIV15_LEN) - 1) << CCI_DTEN_CPUPLL_DIV15_POS) +#define CCI_DTEN_CPUPLL_DIV15_UMSK (~(((1U << CCI_DTEN_CPUPLL_DIV15_LEN) - 1) << CCI_DTEN_CPUPLL_DIV15_POS)) +#define CCI_DTEN_CPUPLL_DIV5 CCI_DTEN_CPUPLL_DIV5 +#define CCI_DTEN_CPUPLL_DIV5_POS (8U) +#define CCI_DTEN_CPUPLL_DIV5_LEN (1U) +#define CCI_DTEN_CPUPLL_DIV5_MSK (((1U << CCI_DTEN_CPUPLL_DIV5_LEN) - 1) << CCI_DTEN_CPUPLL_DIV5_POS) +#define CCI_DTEN_CPUPLL_DIV5_UMSK (~(((1U << CCI_DTEN_CPUPLL_DIV5_LEN) - 1) << CCI_DTEN_CPUPLL_DIV5_POS)) +#define CCI_DTEN_CPUPLL_POSTDIV_CLK CCI_DTEN_CPUPLL_POSTDIV_CLK +#define CCI_DTEN_CPUPLL_POSTDIV_CLK_POS (9U) +#define CCI_DTEN_CPUPLL_POSTDIV_CLK_LEN (1U) +#define CCI_DTEN_CPUPLL_POSTDIV_CLK_MSK (((1U << CCI_DTEN_CPUPLL_POSTDIV_CLK_LEN) - 1) << CCI_DTEN_CPUPLL_POSTDIV_CLK_POS) +#define CCI_DTEN_CPUPLL_POSTDIV_CLK_UMSK (~(((1U << CCI_DTEN_CPUPLL_POSTDIV_CLK_LEN) - 1) << CCI_DTEN_CPUPLL_POSTDIV_CLK_POS)) +#define CCI_DTEST_CPUPLL_PULLDOWN CCI_DTEST_CPUPLL_PULLDOWN +#define CCI_DTEST_CPUPLL_PULLDOWN_POS (10U) +#define CCI_DTEST_CPUPLL_PULLDOWN_LEN (1U) +#define CCI_DTEST_CPUPLL_PULLDOWN_MSK (((1U << CCI_DTEST_CPUPLL_PULLDOWN_LEN) - 1) << CCI_DTEST_CPUPLL_PULLDOWN_POS) +#define CCI_DTEST_CPUPLL_PULLDOWN_UMSK (~(((1U << CCI_DTEST_CPUPLL_PULLDOWN_LEN) - 1) << CCI_DTEST_CPUPLL_PULLDOWN_POS)) + +/* 0x7F8 : cpu_pll_cfg10 */ +#define CCI_CPU_PLL_CFG10_OFFSET (0x7F8) +#define CCI_CPUPLL_SSC_EN CCI_CPUPLL_SSC_EN +#define CCI_CPUPLL_SSC_EN_POS (0U) +#define CCI_CPUPLL_SSC_EN_LEN (1U) +#define CCI_CPUPLL_SSC_EN_MSK (((1U << CCI_CPUPLL_SSC_EN_LEN) - 1) << CCI_CPUPLL_SSC_EN_POS) +#define CCI_CPUPLL_SSC_EN_UMSK (~(((1U << CCI_CPUPLL_SSC_EN_LEN) - 1) << CCI_CPUPLL_SSC_EN_POS)) +#define CCI_CPUPLL_SSC_CNT CCI_CPUPLL_SSC_CNT +#define CCI_CPUPLL_SSC_CNT_POS (4U) +#define CCI_CPUPLL_SSC_CNT_LEN (8U) +#define CCI_CPUPLL_SSC_CNT_MSK (((1U << CCI_CPUPLL_SSC_CNT_LEN) - 1) << CCI_CPUPLL_SSC_CNT_POS) +#define CCI_CPUPLL_SSC_CNT_UMSK (~(((1U << CCI_CPUPLL_SSC_CNT_LEN) - 1) << CCI_CPUPLL_SSC_CNT_POS)) +#define CCI_CPUPLL_SSC_GAIN CCI_CPUPLL_SSC_GAIN +#define CCI_CPUPLL_SSC_GAIN_POS (12U) +#define CCI_CPUPLL_SSC_GAIN_LEN (3U) +#define CCI_CPUPLL_SSC_GAIN_MSK (((1U << CCI_CPUPLL_SSC_GAIN_LEN) - 1) << CCI_CPUPLL_SSC_GAIN_POS) +#define CCI_CPUPLL_SSC_GAIN_UMSK (~(((1U << CCI_CPUPLL_SSC_GAIN_LEN) - 1) << CCI_CPUPLL_SSC_GAIN_POS)) +#define CCI_CPUPLL_SSC_START_GATE_EN CCI_CPUPLL_SSC_START_GATE_EN +#define CCI_CPUPLL_SSC_START_GATE_EN_POS (16U) +#define CCI_CPUPLL_SSC_START_GATE_EN_LEN (1U) +#define CCI_CPUPLL_SSC_START_GATE_EN_MSK (((1U << CCI_CPUPLL_SSC_START_GATE_EN_LEN) - 1) << CCI_CPUPLL_SSC_START_GATE_EN_POS) +#define CCI_CPUPLL_SSC_START_GATE_EN_UMSK (~(((1U << CCI_CPUPLL_SSC_START_GATE_EN_LEN) - 1) << CCI_CPUPLL_SSC_START_GATE_EN_POS)) +#define CCI_CPUPLL_SSC_START CCI_CPUPLL_SSC_START +#define CCI_CPUPLL_SSC_START_POS (20U) +#define CCI_CPUPLL_SSC_START_LEN (1U) +#define CCI_CPUPLL_SSC_START_MSK (((1U << CCI_CPUPLL_SSC_START_LEN) - 1) << CCI_CPUPLL_SSC_START_POS) +#define CCI_CPUPLL_SSC_START_UMSK (~(((1U << CCI_CPUPLL_SSC_START_LEN) - 1) << CCI_CPUPLL_SSC_START_POS)) + +/* 0x7FC : cpu_pll_cfg11 */ +#define CCI_CPU_PLL_CFG11_OFFSET (0x7FC) +#define CCI_CPUPLL_RESV CCI_CPUPLL_RESV +#define CCI_CPUPLL_RESV_POS (0U) +#define CCI_CPUPLL_RESV_LEN (16U) +#define CCI_CPUPLL_RESV_MSK (((1U << CCI_CPUPLL_RESV_LEN) - 1) << CCI_CPUPLL_RESV_POS) +#define CCI_CPUPLL_RESV_UMSK (~(((1U << CCI_CPUPLL_RESV_LEN) - 1) << CCI_CPUPLL_RESV_POS)) +#define CCI_CPUPLL_DL_CTRL_15 CCI_CPUPLL_DL_CTRL_15 +#define CCI_CPUPLL_DL_CTRL_15_POS (23U) +#define CCI_CPUPLL_DL_CTRL_15_LEN (1U) +#define CCI_CPUPLL_DL_CTRL_15_MSK (((1U << CCI_CPUPLL_DL_CTRL_15_LEN) - 1) << CCI_CPUPLL_DL_CTRL_15_POS) +#define CCI_CPUPLL_DL_CTRL_15_UMSK (~(((1U << CCI_CPUPLL_DL_CTRL_15_LEN) - 1) << CCI_CPUPLL_DL_CTRL_15_POS)) +#define CCI_CPUPLL_DL_CTRL_10 CCI_CPUPLL_DL_CTRL_10 +#define CCI_CPUPLL_DL_CTRL_10_POS (24U) +#define CCI_CPUPLL_DL_CTRL_10_LEN (1U) +#define CCI_CPUPLL_DL_CTRL_10_MSK (((1U << CCI_CPUPLL_DL_CTRL_10_LEN) - 1) << CCI_CPUPLL_DL_CTRL_10_POS) +#define CCI_CPUPLL_DL_CTRL_10_UMSK (~(((1U << CCI_CPUPLL_DL_CTRL_10_LEN) - 1) << CCI_CPUPLL_DL_CTRL_10_POS)) +#define CCI_CPUPLL_DL_CTRL_6 CCI_CPUPLL_DL_CTRL_6 +#define CCI_CPUPLL_DL_CTRL_6_POS (25U) +#define CCI_CPUPLL_DL_CTRL_6_LEN (1U) +#define CCI_CPUPLL_DL_CTRL_6_MSK (((1U << CCI_CPUPLL_DL_CTRL_6_LEN) - 1) << CCI_CPUPLL_DL_CTRL_6_POS) +#define CCI_CPUPLL_DL_CTRL_6_UMSK (~(((1U << CCI_CPUPLL_DL_CTRL_6_LEN) - 1) << CCI_CPUPLL_DL_CTRL_6_POS)) +#define CCI_CPUPLL_DL_CTRL_5 CCI_CPUPLL_DL_CTRL_5 +#define CCI_CPUPLL_DL_CTRL_5_POS (26U) +#define CCI_CPUPLL_DL_CTRL_5_LEN (1U) +#define CCI_CPUPLL_DL_CTRL_5_MSK (((1U << CCI_CPUPLL_DL_CTRL_5_LEN) - 1) << CCI_CPUPLL_DL_CTRL_5_POS) +#define CCI_CPUPLL_DL_CTRL_5_UMSK (~(((1U << CCI_CPUPLL_DL_CTRL_5_LEN) - 1) << CCI_CPUPLL_DL_CTRL_5_POS)) +#define CCI_CPUPLL_DL_CTRL_4 CCI_CPUPLL_DL_CTRL_4 +#define CCI_CPUPLL_DL_CTRL_4_POS (27U) +#define CCI_CPUPLL_DL_CTRL_4_LEN (1U) +#define CCI_CPUPLL_DL_CTRL_4_MSK (((1U << CCI_CPUPLL_DL_CTRL_4_LEN) - 1) << CCI_CPUPLL_DL_CTRL_4_POS) +#define CCI_CPUPLL_DL_CTRL_4_UMSK (~(((1U << CCI_CPUPLL_DL_CTRL_4_LEN) - 1) << CCI_CPUPLL_DL_CTRL_4_POS)) +#define CCI_CPUPLL_DL_CTRL_3 CCI_CPUPLL_DL_CTRL_3 +#define CCI_CPUPLL_DL_CTRL_3_POS (28U) +#define CCI_CPUPLL_DL_CTRL_3_LEN (1U) +#define CCI_CPUPLL_DL_CTRL_3_MSK (((1U << CCI_CPUPLL_DL_CTRL_3_LEN) - 1) << CCI_CPUPLL_DL_CTRL_3_POS) +#define CCI_CPUPLL_DL_CTRL_3_UMSK (~(((1U << CCI_CPUPLL_DL_CTRL_3_LEN) - 1) << CCI_CPUPLL_DL_CTRL_3_POS)) +#define CCI_CPUPLL_DL_CTRL_2P5 CCI_CPUPLL_DL_CTRL_2P5 +#define CCI_CPUPLL_DL_CTRL_2P5_POS (29U) +#define CCI_CPUPLL_DL_CTRL_2P5_LEN (1U) +#define CCI_CPUPLL_DL_CTRL_2P5_MSK (((1U << CCI_CPUPLL_DL_CTRL_2P5_LEN) - 1) << CCI_CPUPLL_DL_CTRL_2P5_POS) +#define CCI_CPUPLL_DL_CTRL_2P5_UMSK (~(((1U << CCI_CPUPLL_DL_CTRL_2P5_LEN) - 1) << CCI_CPUPLL_DL_CTRL_2P5_POS)) +#define CCI_CPUPLL_DL_CTRL_2 CCI_CPUPLL_DL_CTRL_2 +#define CCI_CPUPLL_DL_CTRL_2_POS (30U) +#define CCI_CPUPLL_DL_CTRL_2_LEN (1U) +#define CCI_CPUPLL_DL_CTRL_2_MSK (((1U << CCI_CPUPLL_DL_CTRL_2_LEN) - 1) << CCI_CPUPLL_DL_CTRL_2_POS) +#define CCI_CPUPLL_DL_CTRL_2_UMSK (~(((1U << CCI_CPUPLL_DL_CTRL_2_LEN) - 1) << CCI_CPUPLL_DL_CTRL_2_POS)) +#define CCI_CPUPLL_DL_CTRL_1 CCI_CPUPLL_DL_CTRL_1 +#define CCI_CPUPLL_DL_CTRL_1_POS (31U) +#define CCI_CPUPLL_DL_CTRL_1_LEN (1U) +#define CCI_CPUPLL_DL_CTRL_1_MSK (((1U << CCI_CPUPLL_DL_CTRL_1_LEN) - 1) << CCI_CPUPLL_DL_CTRL_1_POS) +#define CCI_CPUPLL_DL_CTRL_1_UMSK (~(((1U << CCI_CPUPLL_DL_CTRL_1_LEN) - 1) << CCI_CPUPLL_DL_CTRL_1_POS)) + +struct cci_reg { + /* 0x0 : cci_cfg */ + union { + struct { + uint32_t cci_en : 1; /* [ 0], r/w, 0x1 */ + uint32_t cci_slv_sel_cci2 : 1; /* [ 1], r/w, 0x0 */ + uint32_t cci_mas_sel_cci2 : 1; /* [ 2], r/w, 0x0 */ + uint32_t cci_mas_hw_mode : 1; /* [ 3], r/w, 0x0 */ + uint32_t reg_m_cci_sclk_en : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_div_m_cci_sclk : 2; /* [ 6: 5], r/w, 0x1 */ + uint32_t cfg_cci1_pre_read : 1; /* [ 7], r/w, 0x0 */ + uint32_t reg_scci_clk_inv : 1; /* [ 8], r/w, 0x0 */ + uint32_t reg_mcci_clk_inv : 1; /* [ 9], r/w, 0x1 */ + uint32_t reserved_10_31 : 22; /* [31:10], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } cci_cfg; + + /* 0x4 : cci_addr */ + union { + struct { + uint32_t apb_cci_addr : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } cci_addr; + + /* 0x8 : cci_wdata */ + union { + struct { + uint32_t apb_cci_wdata : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } cci_wdata; + + /* 0xC : cci_rdata */ + union { + struct { + uint32_t apb_cci_rdata : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } cci_rdata; + + /* 0x10 : cci_ctl */ + union { + struct { + uint32_t cci_write_flag : 1; /* [ 0], r, 0x0 */ + uint32_t cci_read_flag : 1; /* [ 1], r, 0x0 */ + uint32_t ahb_state : 2; /* [ 3: 2], r, 0x0 */ + uint32_t reserved_4_31 : 28; /* [31: 4], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } cci_ctl; + + /* 0x14 reserved */ + uint8_t RESERVED0x14[1852]; + + /* 0x750 : audio_pll_cfg0 */ + union { + struct { + uint32_t aupll_sdm_rstb : 1; /* [ 0], r/w, 0x1 */ + uint32_t aupll_postdiv_rstb : 1; /* [ 1], r/w, 0x1 */ + uint32_t aupll_fbdv_rstb : 1; /* [ 2], r/w, 0x1 */ + uint32_t aupll_refdiv_rstb : 1; /* [ 3], r/w, 0x1 */ + uint32_t pu_aupll_postdiv : 1; /* [ 4], r/w, 0x1 */ + uint32_t pu_aupll_fbdv : 1; /* [ 5], r/w, 0x1 */ + uint32_t pu_aupll_clamp_op : 1; /* [ 6], r/w, 0x1 */ + uint32_t pu_aupll_pfd : 1; /* [ 7], r/w, 0x1 */ + uint32_t pu_aupll_cp : 1; /* [ 8], r/w, 0x1 */ + uint32_t pu_aupll_sfreg : 1; /* [ 9], r/w, 0x0 */ + uint32_t pu_aupll : 1; /* [ 10], r/w, 0x0 */ + uint32_t pu_aupll_clktree : 1; /* [ 11], r/w, 0x1 */ + uint32_t reserved_12_31 : 20; /* [31:12], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } audio_pll_cfg0; + + /* 0x754 : audio_pll_cfg1 */ + union { + struct { + uint32_t aupll_postdiv : 7; /* [ 6: 0], r/w, 0x12 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t aupll_refdiv_ratio : 4; /* [11: 8], r/w, 0x4 */ + uint32_t reserved_12_15 : 4; /* [15:12], rsvd, 0x0 */ + uint32_t aupll_refclk_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_19 : 2; /* [19:18], rsvd, 0x0 */ + uint32_t aupll_vg11_sel : 2; /* [21:20], r/w, 0x1 */ + uint32_t reserved_22_23 : 2; /* [23:22], rsvd, 0x0 */ + uint32_t aupll_vg13_sel : 2; /* [25:24], r/w, 0x1 */ + uint32_t reserved_26_31 : 6; /* [31:26], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } audio_pll_cfg1; + + /* 0x758 : audio_pll_cfg2 */ + union { + struct { + uint32_t aupll_sel_cp_bias : 1; /* [ 0], r/w, 0x1 */ + uint32_t reserved_1_3 : 3; /* [ 3: 1], rsvd, 0x0 */ + uint32_t aupll_icp_5u : 2; /* [ 5: 4], r/w, 0x0 */ + uint32_t aupll_icp_1u : 2; /* [ 7: 6], r/w, 0x1 */ + uint32_t aupll_int_frac_sw : 1; /* [ 8], r/w, 0x1 */ + uint32_t aupll_cp_startup_en : 1; /* [ 9], r/w, 0x1 */ + uint32_t aupll_cp_opamp_en : 1; /* [ 10], r/w, 0x1 */ + uint32_t reserved_11_31 : 21; /* [31:11], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } audio_pll_cfg2; + + /* 0x75C : audio_pll_cfg3 */ + union { + struct { + uint32_t aupll_c4_en : 1; /* [ 0], r/w, 0x1 */ + uint32_t reserved_1_3 : 3; /* [ 3: 1], rsvd, 0x0 */ + uint32_t aupll_r4 : 2; /* [ 5: 4], r/w, 0x2 */ + uint32_t reserved_6_7 : 2; /* [ 7: 6], rsvd, 0x0 */ + uint32_t aupll_r4_short : 1; /* [ 8], r/w, 0x0 */ + uint32_t reserved_9_11 : 3; /* [11: 9], rsvd, 0x0 */ + uint32_t aupll_c3 : 2; /* [13:12], r/w, 0x2 */ + uint32_t aupll_cz : 2; /* [15:14], r/w, 0x2 */ + uint32_t aupll_rz : 3; /* [18:16], r/w, 0x5 */ + uint32_t reserved_19_31 : 13; /* [31:19], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } audio_pll_cfg3; + + /* 0x760 : audio_pll_cfg4 */ + union { + struct { + uint32_t aupll_sel_sample_clk : 2; /* [ 1: 0], r/w, 0x1 */ + uint32_t reserved_2_3 : 2; /* [ 3: 2], rsvd, 0x0 */ + uint32_t aupll_sel_fb_clk : 2; /* [ 5: 4], r/w, 0x1 */ + uint32_t reserved_6_7 : 2; /* [ 7: 6], rsvd, 0x0 */ + uint32_t aupll_sdmclk_sel : 1; /* [ 8], r/w, 0x1 */ + uint32_t reserved_9_31 : 23; /* [31: 9], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } audio_pll_cfg4; + + /* 0x764 : audio_pll_cfg5 */ + union { + struct { + uint32_t aupll_vco_speed : 3; /* [ 2: 0], r/w, 0x3 */ + uint32_t reserved_3_31 : 29; /* [31: 3], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } audio_pll_cfg5; + + /* 0x768 : audio_pll_cfg6 */ + union { + struct { + uint32_t aupll_sdmin : 19; /* [18: 0], r/w, 0x161e5 */ + uint32_t reserved_19_23 : 5; /* [23:19], rsvd, 0x0 */ + uint32_t aupll_sdm_bypass : 1; /* [ 24], r/w, 0x0 */ + uint32_t reserved_25_31 : 7; /* [31:25], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } audio_pll_cfg6; + + /* 0x76C : audio_pll_cfg7 */ + union { + struct { + uint32_t aupll_sdm_order_sel : 1; /* [ 0], r/w, 0x1 */ + uint32_t reserved_1_15 : 15; /* [15: 1], rsvd, 0x0 */ + uint32_t aupll_sdm_sig_dith_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_31 : 14; /* [31:18], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } audio_pll_cfg7; + + /* 0x770 : audio_pll_cfg8 */ + union { + struct { + uint32_t aupll_en_div1 : 1; /* [ 0], r/w, 0x0 */ + uint32_t aupll_en_div2 : 1; /* [ 1], r/w, 0x0 */ + uint32_t aupll_en_div2p5 : 1; /* [ 2], r/w, 0x0 */ + uint32_t aupll_en_div3 : 1; /* [ 3], r/w, 0x0 */ + uint32_t aupll_en_div4 : 1; /* [ 4], r/w, 0x0 */ + uint32_t aupll_en_div5 : 1; /* [ 5], r/w, 0x0 */ + uint32_t aupll_en_div6 : 1; /* [ 6], r/w, 0x0 */ + uint32_t aupll_en_div10 : 1; /* [ 7], r/w, 0x0 */ + uint32_t aupll_en_div15 : 1; /* [ 8], r/w, 0x0 */ + uint32_t aupll_sel_div1_div2 : 1; /* [ 9], r/w, 0x0 */ + uint32_t reserved_10_31 : 22; /* [31:10], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } audio_pll_cfg8; + + /* 0x774 : audio_pll_cfg9 */ + union { + struct { + uint32_t aupll_dc_tp_out_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t ten_aupll : 1; /* [ 1], r/w, 0x0 */ + uint32_t ten_aupll_sfreg : 1; /* [ 2], r/w, 0x0 */ + uint32_t reserved_3 : 1; /* [ 3], rsvd, 0x0 */ + uint32_t dten_aupll_fin : 1; /* [ 4], r/w, 0x0 */ + uint32_t dten_aupll_fref : 1; /* [ 5], r/w, 0x0 */ + uint32_t dten_aupll_fsdm : 1; /* [ 6], r/w, 0x0 */ + uint32_t dten_aupll_div15 : 1; /* [ 7], r/w, 0x0 */ + uint32_t dten_aupll_div5 : 1; /* [ 8], r/w, 0x0 */ + uint32_t dten_aupll_postdiv_clk : 1; /* [ 9], r/w, 0x0 */ + uint32_t dtest_aupll_pulldown : 1; /* [ 10], r/w, 0x1 */ + uint32_t reserved_11_31 : 21; /* [31:11], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } audio_pll_cfg9; + + /* 0x778 : audio_pll_cfg10 */ + union { + struct { + uint32_t aupll_ssc_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t reserved_1_3 : 3; /* [ 3: 1], rsvd, 0x0 */ + uint32_t aupll_ssc_cnt : 8; /* [11: 4], r/w, 0x64 */ + uint32_t aupll_ssc_gain : 3; /* [14:12], r/w, 0x4 */ + uint32_t reserved_15 : 1; /* [ 15], rsvd, 0x0 */ + uint32_t aupll_ssc_start_gate_en : 1; /* [ 16], r/w, 0x0 */ + uint32_t reserved_17_19 : 3; /* [19:17], rsvd, 0x0 */ + uint32_t aupll_ssc_start : 1; /* [ 20], r/w, 0x1 */ + uint32_t reserved_21_31 : 11; /* [31:21], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } audio_pll_cfg10; + + /* 0x77C : audio_pll_cfg11 */ + union { + struct { + uint32_t aupll_resv : 16; /* [15: 0], r/w, 0x0 */ + uint32_t reserved_16_22 : 7; /* [22:16], rsvd, 0x0 */ + uint32_t aupll_dl_ctrl_15 : 1; /* [ 23], r/w, 0x0 */ + uint32_t aupll_dl_ctrl_10 : 1; /* [ 24], r/w, 0x0 */ + uint32_t aupll_dl_ctrl_6 : 1; /* [ 25], r/w, 0x0 */ + uint32_t aupll_dl_ctrl_5 : 1; /* [ 26], r/w, 0x0 */ + uint32_t aupll_dl_ctrl_4 : 1; /* [ 27], r/w, 0x0 */ + uint32_t aupll_dl_ctrl_3 : 1; /* [ 28], r/w, 0x0 */ + uint32_t aupll_dl_ctrl_2p5 : 1; /* [ 29], r/w, 0x0 */ + uint32_t aupll_dl_ctrl_2 : 1; /* [ 30], r/w, 0x0 */ + uint32_t aupll_dl_ctrl_1 : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } audio_pll_cfg11; + + /* 0x780 reserved */ + uint8_t RESERVED0x780[80]; + + /* 0x7D0 : cpu_pll_cfg0 */ + union { + struct { + uint32_t cpupll_sdm_rstb : 1; /* [ 0], r/w, 0x1 */ + uint32_t cpupll_postdiv_rstb : 1; /* [ 1], r/w, 0x1 */ + uint32_t cpupll_fbdv_rstb : 1; /* [ 2], r/w, 0x1 */ + uint32_t cpupll_refdiv_rstb : 1; /* [ 3], r/w, 0x1 */ + uint32_t pu_cpupll_postdiv : 1; /* [ 4], r/w, 0x0 */ + uint32_t pu_cpupll_fbdv : 1; /* [ 5], r/w, 0x1 */ + uint32_t pu_cpupll_clamp_op : 1; /* [ 6], r/w, 0x1 */ + uint32_t pu_cpupll_pfd : 1; /* [ 7], r/w, 0x1 */ + uint32_t pu_cpupll_cp : 1; /* [ 8], r/w, 0x1 */ + uint32_t pu_cpupll_sfreg : 1; /* [ 9], r/w, 0x0 */ + uint32_t pu_cpupll : 1; /* [ 10], r/w, 0x0 */ + uint32_t pu_cpupll_clktree : 1; /* [ 11], r/w, 0x1 */ + uint32_t reserved_12_31 : 20; /* [31:12], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } cpu_pll_cfg0; + + /* 0x7D4 : cpu_pll_cfg1 */ + union { + struct { + uint32_t cpupll_postdiv : 7; /* [ 6: 0], r/w, 0x18 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t cpupll_refdiv_ratio : 4; /* [11: 8], r/w, 0x4 */ + uint32_t reserved_12_15 : 4; /* [15:12], rsvd, 0x0 */ + uint32_t cpupll_refclk_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_19 : 2; /* [19:18], rsvd, 0x0 */ + uint32_t cpupll_vg11_sel : 2; /* [21:20], r/w, 0x1 */ + uint32_t reserved_22_23 : 2; /* [23:22], rsvd, 0x0 */ + uint32_t cpupll_vg13_sel : 2; /* [25:24], r/w, 0x1 */ + uint32_t reserved_26_31 : 6; /* [31:26], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } cpu_pll_cfg1; + + /* 0x7D8 : cpu_pll_cfg2 */ + union { + struct { + uint32_t cpupll_sel_cp_bias : 1; /* [ 0], r/w, 0x1 */ + uint32_t reserved_1_3 : 3; /* [ 3: 1], rsvd, 0x0 */ + uint32_t cpupll_icp_5u : 2; /* [ 5: 4], r/w, 0x0 */ + uint32_t cpupll_icp_1u : 2; /* [ 7: 6], r/w, 0x1 */ + uint32_t cpupll_int_frac_sw : 1; /* [ 8], r/w, 0x1 */ + uint32_t cpupll_cp_startup_en : 1; /* [ 9], r/w, 0x1 */ + uint32_t cpupll_cp_opamp_en : 1; /* [ 10], r/w, 0x1 */ + uint32_t reserved_11_31 : 21; /* [31:11], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } cpu_pll_cfg2; + + /* 0x7DC : cpu_pll_cfg3 */ + union { + struct { + uint32_t cpupll_c4_en : 1; /* [ 0], r/w, 0x1 */ + uint32_t reserved_1_3 : 3; /* [ 3: 1], rsvd, 0x0 */ + uint32_t cpupll_r4 : 2; /* [ 5: 4], r/w, 0x2 */ + uint32_t reserved_6_7 : 2; /* [ 7: 6], rsvd, 0x0 */ + uint32_t cpupll_r4_short : 1; /* [ 8], r/w, 0x0 */ + uint32_t reserved_9_11 : 3; /* [11: 9], rsvd, 0x0 */ + uint32_t cpupll_c3 : 2; /* [13:12], r/w, 0x2 */ + uint32_t cpupll_cz : 2; /* [15:14], r/w, 0x2 */ + uint32_t cpupll_rz : 3; /* [18:16], r/w, 0x5 */ + uint32_t reserved_19_31 : 13; /* [31:19], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } cpu_pll_cfg3; + + /* 0x7E0 : cpu_pll_cfg4 */ + union { + struct { + uint32_t cpupll_sel_sample_clk : 2; /* [ 1: 0], r/w, 0x1 */ + uint32_t reserved_2_3 : 2; /* [ 3: 2], rsvd, 0x0 */ + uint32_t cpupll_sel_fb_clk : 2; /* [ 5: 4], r/w, 0x1 */ + uint32_t reserved_6_7 : 2; /* [ 7: 6], rsvd, 0x0 */ + uint32_t cpupll_sdmclk_sel : 1; /* [ 8], r/w, 0x1 */ + uint32_t reserved_9_31 : 23; /* [31: 9], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } cpu_pll_cfg4; + + /* 0x7E4 : cpu_pll_cfg5 */ + union { + struct { + uint32_t cpupll_vco_speed : 3; /* [ 2: 0], r/w, 0x3 */ + uint32_t reserved_3_31 : 29; /* [31: 3], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } cpu_pll_cfg5; + + /* 0x7E8 : cpu_pll_cfg6 */ + union { + struct { + uint32_t cpupll_sdmin : 19; /* [18: 0], r/w, 0x161e5 */ + uint32_t reserved_19_23 : 5; /* [23:19], rsvd, 0x0 */ + uint32_t cpupll_sdm_bypass : 1; /* [ 24], r/w, 0x0 */ + uint32_t reserved_25_31 : 7; /* [31:25], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } cpu_pll_cfg6; + + /* 0x7EC : cpu_pll_cfg7 */ + union { + struct { + uint32_t cpupll_sdm_order_sel : 1; /* [ 0], r/w, 0x1 */ + uint32_t reserved_1_15 : 15; /* [15: 1], rsvd, 0x0 */ + uint32_t cpupll_sdm_sig_dith_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_31 : 14; /* [31:18], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } cpu_pll_cfg7; + + /* 0x7F0 : cpu_pll_cfg8 */ + union { + struct { + uint32_t cpupll_en_div1 : 1; /* [ 0], r/w, 0x1 */ + uint32_t cpupll_en_div2 : 1; /* [ 1], r/w, 0x0 */ + uint32_t cpupll_en_div2p5 : 1; /* [ 2], r/w, 0x0 */ + uint32_t cpupll_en_div3 : 1; /* [ 3], r/w, 0x0 */ + uint32_t cpupll_en_div4 : 1; /* [ 4], r/w, 0x0 */ + uint32_t cpupll_en_div5 : 1; /* [ 5], r/w, 0x0 */ + uint32_t cpupll_en_div6 : 1; /* [ 6], r/w, 0x0 */ + uint32_t cpupll_en_div10 : 1; /* [ 7], r/w, 0x0 */ + uint32_t cpupll_en_div15 : 1; /* [ 8], r/w, 0x0 */ + uint32_t cpupll_sel_div1_div2 : 1; /* [ 9], r/w, 0x0 */ + uint32_t reserved_10_31 : 22; /* [31:10], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } cpu_pll_cfg8; + + /* 0x7F4 : cpu_pll_cfg9 */ + union { + struct { + uint32_t cpupll_dc_tp_out_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t ten_cpupll : 1; /* [ 1], r/w, 0x0 */ + uint32_t ten_cpupll_sfreg : 1; /* [ 2], r/w, 0x0 */ + uint32_t reserved_3 : 1; /* [ 3], rsvd, 0x0 */ + uint32_t dten_cpupll_fin : 1; /* [ 4], r/w, 0x0 */ + uint32_t dten_cpupll_fref : 1; /* [ 5], r/w, 0x0 */ + uint32_t dten_cpupll_fsdm : 1; /* [ 6], r/w, 0x0 */ + uint32_t dten_cpupll_div15 : 1; /* [ 7], r/w, 0x0 */ + uint32_t dten_cpupll_div5 : 1; /* [ 8], r/w, 0x0 */ + uint32_t dten_cpupll_postdiv_clk : 1; /* [ 9], r/w, 0x0 */ + uint32_t dtest_cpupll_pulldown : 1; /* [ 10], r/w, 0x1 */ + uint32_t reserved_11_31 : 21; /* [31:11], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } cpu_pll_cfg9; + + /* 0x7F8 : cpu_pll_cfg10 */ + union { + struct { + uint32_t cpupll_ssc_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t reserved_1_3 : 3; /* [ 3: 1], rsvd, 0x0 */ + uint32_t cpupll_ssc_cnt : 8; /* [11: 4], r/w, 0x64 */ + uint32_t cpupll_ssc_gain : 3; /* [14:12], r/w, 0x4 */ + uint32_t reserved_15 : 1; /* [ 15], rsvd, 0x0 */ + uint32_t cpupll_ssc_start_gate_en : 1; /* [ 16], r/w, 0x0 */ + uint32_t reserved_17_19 : 3; /* [19:17], rsvd, 0x0 */ + uint32_t cpupll_ssc_start : 1; /* [ 20], r/w, 0x1 */ + uint32_t reserved_21_31 : 11; /* [31:21], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } cpu_pll_cfg10; + + /* 0x7FC : cpu_pll_cfg11 */ + union { + struct { + uint32_t cpupll_resv : 16; /* [15: 0], r/w, 0x0 */ + uint32_t reserved_16_22 : 7; /* [22:16], rsvd, 0x0 */ + uint32_t cpupll_dl_ctrl_15 : 1; /* [ 23], r/w, 0x0 */ + uint32_t cpupll_dl_ctrl_10 : 1; /* [ 24], r/w, 0x0 */ + uint32_t cpupll_dl_ctrl_6 : 1; /* [ 25], r/w, 0x0 */ + uint32_t cpupll_dl_ctrl_5 : 1; /* [ 26], r/w, 0x0 */ + uint32_t cpupll_dl_ctrl_4 : 1; /* [ 27], r/w, 0x0 */ + uint32_t cpupll_dl_ctrl_3 : 1; /* [ 28], r/w, 0x0 */ + uint32_t cpupll_dl_ctrl_2p5 : 1; /* [ 29], r/w, 0x0 */ + uint32_t cpupll_dl_ctrl_2 : 1; /* [ 30], r/w, 0x0 */ + uint32_t cpupll_dl_ctrl_1 : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } cpu_pll_cfg11; +}; + +typedef volatile struct cci_reg cci_reg_t; + +#endif /* __CCI_REG_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/compiler/common.h b/platforms/bl808_m0/vendor/psram/include/compiler/common.h new file mode 100644 index 0000000..29489e3 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/compiler/common.h @@ -0,0 +1,63 @@ +#ifndef __COMMON_H +#define __COMMON_H + +/** + * @brief Memory access macro + */ +#define BL_RD_WORD(addr) (*((volatile uint32_t *)(uintptr_t)(addr))) +#define BL_WR_WORD(addr, val) ((*(volatile uint32_t *)(uintptr_t)(addr)) = (val)) +#define BL_RD_SHORT(addr) (*((volatile uint16_t *)(uintptr_t)(addr))) +#define BL_WR_SHORT(addr, val) ((*(volatile uint16_t *)(uintptr_t)(addr)) = (val)) +#define BL_RD_BYTE(addr) (*((volatile uint8_t *)(uintptr_t)(addr))) +#define BL_WR_BYTE(addr, val) ((*(volatile uint8_t *)(uintptr_t)(addr)) = (val)) +#define BL_RDWD_FRM_BYTEP(p) ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | (p[0])) + +#define BL_WRWD_TO_BYTEP(p, val) \ + { \ + p[0] = val & 0xff; \ + p[1] = (val >> 8) & 0xff; \ + p[2] = (val >> 16) & 0xff; \ + p[3] = (val >> 24) & 0xff; \ + } +/** + * @brief Register access macro + */ +#define BL_RD_REG16(addr, regname) BL_RD_SHORT(addr + regname##_OFFSET) +#define BL_WR_REG16(addr, regname, val) BL_WR_SHORT(addr + regname##_OFFSET, val) +#define BL_RD_REG(addr, regname) BL_RD_WORD(addr + regname##_OFFSET) +#define BL_WR_REG(addr, regname, val) BL_WR_WORD(addr + regname##_OFFSET, val) +#define BL_SET_REG_BIT(val, bitname) ((val) | (1U << bitname##_POS)) +#define BL_CLR_REG_BIT(val, bitname) ((val)&bitname##_UMSK) +#define BL_GET_REG_BITS_VAL(val, bitname) (((val)&bitname##_MSK) >> bitname##_POS) +#define BL_SET_REG_BITS_VAL(val, bitname, bitval) (((val)&bitname##_UMSK) | ((uint32_t)(bitval) << bitname##_POS)) +#define BL_IS_REG_BIT_SET(val, bitname) (((val) & (1U << (bitname##_POS))) != 0) +#define BL_DRV_DUMMY \ + { \ + __ASM volatile("nop"); \ + __ASM volatile("nop"); \ + __ASM volatile("nop"); \ + __ASM volatile("nop"); \ + } + +/* Std driver attribute macro*/ +#ifndef BFLB_USE_CUSTOM_LD_SECTIONS +//#define ATTR_UNI_SYMBOL +#define ATTR_STRINGIFY(x) #x +#define ATTR_TOSTRING(x) ATTR_STRINGIFY(x) +#define ATTR_UNI_SYMBOL __FILE__ ATTR_TOSTRING(__LINE__) +#define ATTR_CLOCK_SECTION __attribute__((section(".sclock_rlt_code." ATTR_UNI_SYMBOL))) +#define ATTR_CLOCK_CONST_SECTION __attribute__((section(".sclock_rlt_const." ATTR_UNI_SYMBOL))) +#define ATTR_TCM_SECTION __attribute__((section(".tcm_code." ATTR_UNI_SYMBOL))) +#define ATTR_TCM_CONST_SECTION __attribute__((section(".tcm_const." ATTR_UNI_SYMBOL))) +#define ATTR_DTCM_SECTION __attribute__((section(".tcm_data"))) +#define ATTR_HSRAM_SECTION __attribute__((section(".hsram_code"))) +#define ATTR_DMA_RAM_SECTION __attribute__((section(".system_ram"))) +#define ATTR_HBN_RAM_SECTION __attribute__((section(".hbn_ram_code"))) +#define ATTR_HBN_RAM_CONST_SECTION __attribute__((section(".hbn_ram_data"))) +#define ATTR_EALIGN(x) __attribute__((aligned(x))) +#define ATTR_FALLTHROUGH() __attribute__((fallthrough)) +#define ATTR_USED __attribute__((__used__)) +#else +#include "bl_ld_sections.h" +#endif /* BFLB_USE_CUSTOM_LD_SECTIONS */ +#endif diff --git a/platforms/bl808_m0/vendor/psram/include/compiler/gcc.h b/platforms/bl808_m0/vendor/psram/include/compiler/gcc.h new file mode 100644 index 0000000..844dd00 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/compiler/gcc.h @@ -0,0 +1,112 @@ +#ifndef __GCC_H +#define __GCC_H + +#ifndef __ORDER_BIG_ENDIAN__ +#define __ORDER_BIG_ENDIAN__ (1) +#endif + +#ifndef __ORDER_LITTLE_ENDIAN__ +#define __ORDER_LITTLE_ENDIAN__ (2) +#endif + +#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ + +/* CPP header guards */ +#ifdef __cplusplus +#define EXTERN_C_BEGIN extern "C" { +#define EXTERN_C_END } +#else +#define EXTERN_C_BEGIN +#define EXTERN_C_END +#endif + +#define __MACRO_BEGIN do { +#define __MACRO_END \ + } \ + while (0) + +#if defined(__GNUC__) +#ifndef __ASM +#define __ASM __asm +#endif +#ifndef __INLINE +#define __INLINE inline +#endif +#ifndef __INLINE__ +#define __INLINE__ inline +#endif +#ifndef __ALWAYS_INLINE +#define __ALWAYS_INLINE inline __attribute__((always_inline)) +#endif +#ifndef __ALWAYS_STATIC_INLINE +#define __ALWAYS_STATIC_INLINE __attribute__((always_inline)) static inline +#endif +#ifndef __STATIC_INLINE +#define __STATIC_INLINE static inline +#endif +#ifndef __NO_RETURN +#define __NO_RETURN __attribute__((noreturn)) +#endif +#ifndef __USED +#define __USED __attribute__((used)) +#endif +#ifndef __UNUSED__ +#define __UNUSED__ __attribute__((__unused__)) +#endif +#ifndef __WEAK +#define __WEAK __attribute__((weak)) +#endif +#ifndef __WEAK__ +#define __WEAK__ __attribute__((weak)) +#endif +#ifndef __PACKED +#define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED__ +#define __PACKED__ __attribute__((packed)) +#endif +#ifndef __PACKED_STRUCT +#define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION +#define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __IRQ +#define __IRQ __attribute__((interrupt)) +#endif +#ifndef __IRQ_ALIGN64 +#define __IRQ_ALIGN64 __attribute__((interrupt, aligned(64))) +#endif +#ifndef ALIGN4 +#define ALIGN4 __attribute((aligned(4))) +#endif +#ifndef PACK_START +#define PACK_START +#endif +#ifndef PACK_END +#define PACK_END __attribute__((packed)) +#endif +#ifndef likely +#define likely(x) __builtin_expect(!!(x), 1) +#endif +#ifndef unlikely +#define unlikely(x) __builtin_expect(!!(x), 0) +#endif +#ifndef __ALIGNED__ +#define __ALIGNED__(x) __attribute__((aligned(x))) +#endif +#ifndef SECTION +#define SECTION(x) __attribute__((section(x))) +#endif +#ifndef __CONST__ +#define __CONST__ __attribute__((__const__)) +#endif +#ifndef __NAKED__ +#define __NAKED__ __attribute__((naked)) +#endif +#ifndef __deprecated +#define __deprecated __attribute__((deprecated)) +#endif +#endif + +#endif \ No newline at end of file diff --git a/platforms/bl808_m0/vendor/psram/include/core_rv32.h b/platforms/bl808_m0/vendor/psram/include/core_rv32.h new file mode 100644 index 0000000..e4b3d57 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/core_rv32.h @@ -0,0 +1,1364 @@ +/* + * Copyright (C) 2017-2019 Alibaba Group Holding Limited + */ + +/****************************************************************************** + * @file core_rv32.h + * @brief CSI RV32 Core Peripheral Access Layer Header File + * @version V1.0 + * @date 01. Sep 2018 + ******************************************************************************/ + +#ifndef __CORE_RV32_H_GENERIC +#define __CORE_RV32_H_GENERIC + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * CSI definitions + ******************************************************************************/ +/** + \ingroup RV32 + @{ + */ + +#ifndef __RV32 +#define __RV32 (0x01U) +#endif + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined(__GNUC__) +#if defined(__VFP_FP__) && !defined(__SOFTFP__) +#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" +#endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_RV32_H_GENERIC */ + +#ifndef __CSI_GENERIC + +#ifndef __CORE_RV32_H_DEPENDANT +#define __CORE_RV32_H_DEPENDANT + +#ifdef __cplusplus +extern "C" { +#endif + +/* check device defines and use defaults */ +#ifndef __RV32_REV +#define __RV32_REV 0x0000U +#endif + +#ifndef __VIC_PRIO_BITS +#define __VIC_PRIO_BITS 2U +#endif + +#ifndef __Vendor_SysTickConfig +#define __Vendor_SysTickConfig 1U +#endif + +#ifndef __MPU_PRESENT +#define __MPU_PRESENT 1U +#endif + +#ifndef __ICACHE_PRESENT +#define __ICACHE_PRESENT 1U +#endif + +#ifndef __DCACHE_PRESENT +#define __DCACHE_PRESENT 1U +#endif + +#include + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CSI_glob_defs CSI Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus +#define __I volatile /*!< Defines 'read only' permissions */ +#else +#define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group RV32 */ + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core CLIC Register + ******************************************************************************/ +/** + \defgroup CSI_core_register Defines and Type Definitions + \brief Type definitions and defines for CK80X processor based devices. +*/ + +/** + \ingroup CSI_core_register + \defgroup CSI_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \ingroup CSI_core_register + \defgroup CSI_CLIC Core-Local Interrupt Controller (CLIC) + \brief Type definitions for the CLIC Registers + @{ + */ + +/** + \brief Access to the structure of a vector interrupt controller. + */ +typedef struct +{ + __IOM uint8_t IP; /*!< Offset: 0x000 (R/W) Interrupt set pending register */ + __IOM uint8_t IE; /*!< Offset: 0x004 (R/W) Interrupt set enable register */ + __IOM uint8_t ATTR; /*!< Offset: 0x008 (R/W) Interrupt set attribute register */ + __IOM uint8_t CTL; /*!< Offset: 0x00C (R/W) Interrupt control register */ +} CLIC_INT_Control; + +typedef struct +{ + __IOM uint32_t CLICCFG : 8; /*!< Offset: 0x000 (R/W) CLIC configure register */ + __IM uint32_t CLICINFO; + __IOM uint32_t MINTTHRESH; + uint32_t RESERVED[1021]; + CLIC_INT_Control CLICINT[4096]; +} CLIC_Type; + +#define CLIC_INFO_CLICINTCTLBITS_Pos 21U +#define CLIC_INFO_CLICINTCTLBITS_Msk (0xFUL << CLIC_INFO_CLICINTCTLBITS_Pos) + +#define CLIC_INTIP_IP_Pos 0U /*!< CLIC INTIP: IP Position */ +#define CLIC_INTIP_IP_Msk (0x1UL << CLIC_INTIP_IP_Pos) /*!< CLIC INTIP: IP Mask */ + +#define CLIC_INTIE_IE_Pos 0U /*!< CLIC INTIE: IE Position */ +#define CLIC_INTIE_IE_Msk (0x1UL << CLIC_INTIE_IE_Pos) /*!< CLIC INTIE: IE Mask */ + +#define CLIC_INTIE_T_Pos 7U /*!< CLIC INTIE: T Position */ +#define CLIC_INTIE_T_Msk (0x1UL << CLIC_INTIE_T_Pos) /*!< CLIC INTIE: T Mask */ + +#define CLIC_INTATTR_TRIG_Pos 1U /*!< CLIC INTATTR: TRIG Position */ +#define CLIC_INTATTR_TRIG_Msk (0x3UL << CLIC_INTATTR_TRIG_Pos) /*!< CLIC INTATTR: TRIG Mask */ + +#define CLIC_INTATTR_SHV_Pos 0U /*!< CLIC INTATTR: SHV Position */ +#define CLIC_INTATTR_SHV_Msk (0x1UL << CLIC_INTATTR_SHV_Pos) /*!< CLIC INTATTR: SHV Mask */ + +#define CLIC_INTCFG_NVBIT_Pos 5U /*!< CLIC INTCFG: NVBIT Position */ +#define CLIC_INTCFG_NVBIT_Msk (0x1UL << CLIC_INTCFG_NVBIT_Pos) /*!< CLIC INTCFG: NVBIT Mask */ + +#define CLIC_INTCFG_PRIO_Pos 4U /*!< CLIC INTCFG: INTCFG Position */ +#define CLIC_INTCFG_PRIO_Msk (0xFUL << CLIC_INTCFG_PRIO_Pos) /*!< CLIC INTCFG: INTCFG Mask */ + +#define CLIC_CLICCFG_NVBIT_Pos 0U /*!< CLIC CLICCFG: NVBIT Position */ +#define CLIC_CLICCFG_NVBIT_Msk (0x1UL << CLIC_CLICCFG_NVBIT_Pos) /*!< CLIC CLICCFG: NVBIT Mask */ + +#define CLIC_CLICCFG_NLBIT_Pos 1U /*!< CLIC CLICCFG: NLBIT Position */ +#define CLIC_CLICCFG_NLBIT_Msk (0xFUL << CLIC_CLICCFG_NLBIT_Pos) /*!< CLIC CLICCFG: NLBIT Mask */ + +#define CLIC_CLICCFG_NMBIT_Pos 5U /*!< CLIC CLICCFG: NMBIT Position */ +#define CLIC_CLICCFG_NMBIT_Msk (0x3UL << CLIC_CLICCFG_NMBIT_Pos) /*!< CLIC CLICCFG: NMBIT Mask */ + +/*@} end of group CSI_CLIC */ + +/** + \ingroup CSI_core_register + \defgroup CSI_PMP Physical Memory Protection (PMP) + \brief Type definitions for the PMP Registers + @{ + */ + +#define PMP_PMPCFG_R_Pos 0U /*!< PMP PMPCFG: R Position */ +#define PMP_PMPCFG_R_Msk (0x1UL << PMP_PMPCFG_R_Pos) /*!< PMP PMPCFG: R Mask */ + +#define PMP_PMPCFG_W_Pos 1U /*!< PMP PMPCFG: W Position */ +#define PMP_PMPCFG_W_Msk (0x1UL << PMP_PMPCFG_W_Pos) /*!< PMP PMPCFG: W Mask */ + +#define PMP_PMPCFG_X_Pos 2U /*!< PMP PMPCFG: X Position */ +#define PMP_PMPCFG_X_Msk (0x1UL << PMP_PMPCFG_X_Pos) /*!< PMP PMPCFG: X Mask */ + +#define PMP_PMPCFG_A_Pos 3U /*!< PMP PMPCFG: A Position */ +#define PMP_PMPCFG_A_Msk (0x3UL << PMP_PMPCFG_A_Pos) /*!< PMP PMPCFG: A Mask */ + +#define PMP_PMPCFG_L_Pos 7U /*!< PMP PMPCFG: L Position */ +#define PMP_PMPCFG_L_Msk (0x1UL << PMP_PMPCFG_L_Pos) /*!< PMP PMPCFG: L Mask */ + +typedef enum { + REGION_SIZE_4B = -1, + REGION_SIZE_8B = 0, + REGION_SIZE_16B = 1, + REGION_SIZE_32B = 2, + REGION_SIZE_64B = 3, + REGION_SIZE_128B = 4, + REGION_SIZE_256B = 5, + REGION_SIZE_512B = 6, + REGION_SIZE_1KB = 7, + REGION_SIZE_2KB = 8, + REGION_SIZE_4KB = 9, + REGION_SIZE_8KB = 10, + REGION_SIZE_16KB = 11, + REGION_SIZE_32KB = 12, + REGION_SIZE_64KB = 13, + REGION_SIZE_128KB = 14, + REGION_SIZE_256KB = 15, + REGION_SIZE_512KB = 16, + REGION_SIZE_1MB = 17, + REGION_SIZE_2MB = 18, + REGION_SIZE_4MB = 19, + REGION_SIZE_8MB = 20, + REGION_SIZE_16MB = 21, + REGION_SIZE_32MB = 22, + REGION_SIZE_64MB = 23, + REGION_SIZE_128MB = 24, + REGION_SIZE_256MB = 25, + REGION_SIZE_512MB = 26, + REGION_SIZE_1GB = 27, + REGION_SIZE_2GB = 28, + REGION_SIZE_4GB = 29, + REGION_SIZE_8GB = 30, + REGION_SIZE_16GB = 31 +} region_size_e; + +typedef enum { + ADDRESS_MATCHING_TOR = 1, + ADDRESS_MATCHING_NAPOT = 3 +} address_matching_e; + +typedef struct +{ + uint32_t r : 1; /* readable enable */ + uint32_t w : 1; /* writeable enable */ + uint32_t x : 1; /* execable enable */ + address_matching_e a : 2; /* address matching mode */ + uint32_t reserved : 2; /* reserved */ + uint32_t l : 1; /* lock enable */ +} mpu_region_attr_t; + +/*@} end of group CSI_PMP */ + +/* CACHE Register Definitions */ +#define CACHE_MHCR_L0BTB_Pos 12U /*!< CACHE MHCR: L0BTB Position */ +#define CACHE_MHCR_L0BTB_Msk (0x1UL << CACHE_MHCR_L0BTB_Pos) /*!< CACHE MHCR: WA Mask */ + +#define CACHE_MHCR_BPE_Pos 5U /*!< CACHE MHCR: BPE Position */ +#define CACHE_MHCR_BPE_Msk (0x1UL << CACHE_MHCR_BPE_Pos) /*!< CACHE MHCR: BPE Mask */ + +#define CACHE_MHCR_RS_Pos 4U /*!< CACHE MHCR: RS Position */ +#define CACHE_MHCR_RS_Msk (0x1UL << CACHE_MHCR_RS_Pos) /*!< CACHE MHCR: RS Mask */ + +#define CACHE_MHCR_WA_Pos 3U /*!< CACHE MHCR: WA Position */ +#define CACHE_MHCR_WA_Msk (0x1UL << CACHE_MHCR_WA_Pos) /*!< CACHE MHCR: WA Mask */ + +#define CACHE_MHCR_WB_Pos 2U /*!< CACHE MHCR: WB Position */ +#define CACHE_MHCR_WB_Msk (0x1UL << CACHE_MHCR_WB_Pos) /*!< CACHE MHCR: WB Mask */ + +#define CACHE_MHCR_DE_Pos 1U /*!< CACHE MHCR: DE Position */ +#define CACHE_MHCR_DE_Msk (0x1UL << CACHE_MHCR_DE_Pos) /*!< CACHE MHCR: DE Mask */ + +#define CACHE_MHCR_IE_Pos 0U /*!< CACHE MHCR: IE Position */ +#define CACHE_MHCR_IE_Msk (0x1UL << CACHE_MHCR_IE_Pos) /*!< CACHE MHCR: IE Mask */ + +#define CACHE_INV_ADDR_Pos 5U +#define CACHE_INV_ADDR_Msk (0xFFFFFFFFUL << CACHE_INV_ADDR_Pos) + +/*@} end of group CSI_CACHE */ + +/** + \ingroup CSI_core_register + \defgroup CSI_SYSMAP system map (SYSMAP) + \brief Type definitions for the SYSMAP Registers + @{ + */ + +#define SYSMAP_SYSMAPCFG_B_Pos 0U /*!< SYSMAP SYSMAPCFG: B Position */ +#define SYSMAP_SYSMAPCFG_B_Msk (0x1UL << SYSMAP_SYSMAPCFG_B_Pos) /*!< SYSMAP SYSMAPCFG: B Mask */ + +#define SYSMAP_SYSMAPCFG_C_Pos 1U /*!< SYSMAP SYSMAPCFG: C Position */ +#define SYSMAP_SYSMAPCFG_C_Msk (0x1UL << SYSMAP_SYSMAPCFG_C_Pos) /*!< SYSMAP SYSMAPCFG: C Mask */ + +#define SYSMAP_SYSMAPCFG_SO_Pos 2U /*!< SYSMAP SYSMAPCFG: SO Position */ +#define SYSMAP_SYSMAPCFG_SO_Msk (0x1UL << SYSMAP_SYSMAPCFG_SO_Pos) /*!< SYSMAP SYSMAPCFG: SO Mask */ + +/** + \ingroup CSI_core_register + \defgroup CSI_SYSMAP system map (SYSMAP) + \brief Type definitions for the SYSMAP Registers + @{ + */ +typedef struct +{ + __IOM uint32_t SYSMAPADDR0; /*!< Offset: 0x000 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPCFG0; /*!< Offset: 0x004 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPADDR1; /*!< Offset: 0x008 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPCFG1; /*!< Offset: 0x00c (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPADDR2; /*!< Offset: 0x010 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPCFG2; /*!< Offset: 0x014 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPADDR3; /*!< Offset: 0x018 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPCFG3; /*!< Offset: 0x01c (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPADDR4; /*!< Offset: 0x020 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPCFG4; /*!< Offset: 0x024 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPADDR5; /*!< Offset: 0x028 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPCFG5; /*!< Offset: 0x02c (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPADDR6; /*!< Offset: 0x030 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPCFG6; /*!< Offset: 0x034 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPADDR7; /*!< Offset: 0x038 (R/W) SYSMAP configure register */ + __IOM uint32_t SYSMAPCFG7; /*!< Offset: 0x03c (R/W) SYSMAP configure register */ +} SYSMAP_Type; + +/*@} end of group CSI_SYSMAP */ + +/** + \ingroup CSI_core_register + \defgroup CSI_SysTick System Tick Timer (CORET) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief The data structure of the access system timer. + */ +typedef struct +{ + __IOM unsigned long long MTIMECMP; /*!< Offset: 0x000 (R/W) Timer compare register */ + uint32_t RESERVED[8187]; + __IM unsigned long long MTIME; /*!< Offset: 0x7FFC (R) Timer current register */ +} CORET_Type; + +/*@} end of group CSI_SysTick */ + +/** + \ingroup CSI_core_register + \defgroup CSI_DCC + \brief Type definitions for the DCC. + @{ + */ + +/** + \brief Access to the data structure of DCC. + */ +typedef struct +{ + uint32_t RESERVED0[13U]; + __IOM uint32_t HCR; /*!< Offset: 0x034 (R/W) */ + __IM uint32_t EHSR; /*!< Offset: 0x03C (R/ ) */ + uint32_t RESERVED1[6U]; + union { + __IM uint32_t DERJW; /*!< Offset: 0x058 (R/ ) Data exchange register CPU read*/ + __OM uint32_t DERJR; /*!< Offset: 0x058 ( /W) Data exchange register CPU writer*/ + }; + +} DCC_Type; + +#define DCC_HCR_JW_Pos 18U /*!< DCC HCR: jw_int_en Position */ +#define DCC_HCR_JW_Msk (1UL << DCC_HCR_JW_Pos) /*!< DCC HCR: jw_int_en Mask */ + +#define DCC_HCR_JR_Pos 19U /*!< DCC HCR: jr_int_en Position */ +#define DCC_HCR_JR_Msk (1UL << DCC_HCR_JR_Pos) /*!< DCC HCR: jr_int_en Mask */ + +#define DCC_EHSR_JW_Pos 1U /*!< DCC EHSR: jw_vld Position */ +#define DCC_EHSR_JW_Msk (1UL << DCC_EHSR_JW_Pos) /*!< DCC EHSR: jw_vld Mask */ + +#define DCC_EHSR_JR_Pos 2U /*!< DCC EHSR: jr_vld Position */ +#define DCC_EHSR_JR_Msk (1UL << DCC_EHSR_JR_Pos) /*!< DCC EHSR: jr_vld Mask */ + +/*@} end of group CSI_DCC */ + +/** + \ingroup CSI_core_register + \defgroup CSI_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) ((value << field##_Pos) & field##_Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) ((value & field##_Msk) >> field##_Pos) + +/*@} end of group CSI_core_bitfield */ + +/** + \ingroup CSI_core_register + \defgroup CSI_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of THEAD CPU */ +#define TCIP_BASE (0xE000E000UL) /*!< Titly Coupled IP Base Address */ +#define CORET_BASE (0xE0004000UL) /*!< CORET Base Address */ +#define CLIC_BASE (0xE0800000UL) /*!< CLIC Base Address */ +#define SYSMAP_BASE (0xEFFFF000UL) /*!< SYSMAP Base Address */ +#define DCC_BASE (0xE4010000UL) /*!< DCC Base Address */ +#define CACHE_BASE (TCIP_BASE + 0x1000UL) /*!< CACHE Base Address */ + +#define CORET ((CORET_Type *)CORET_BASE) /*!< SysTick configuration struct */ +#define CLIC ((CLIC_Type *)CLIC_BASE) /*!< CLIC configuration struct */ +#define DCC ((DCC_Type *)DCC_BASE) /*!< DCC configuration struct */ +#define SYSMAP ((SYSMAP_Type *)SYSMAP_BASE) /*!< SYSMAP configuration struct */ +#define CACHE ((CACHE_Type *)CACHE_BASE) /*!< cache configuration struct */ + +/*@} */ + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core VIC Functions + - Core CORET Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CSI_Core_FunctionInterface Functions and Instructions Reference +*/ + +/* ########################## VIC functions #################################### */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_VICFunctions VIC Functions + \brief Functions that manage interrupts and exceptions via the VIC. + @{ + */ + +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) (((((uint32_t)(int32_t)(IRQn))) & 0x03UL) * 8UL) +#define _IP_IDX(IRQn) ((((uint32_t)(int32_t)(IRQn)) >> 5UL)) +#define _IP2_IDX(IRQn) ((((uint32_t)(int32_t)(IRQn)) >> 2UL)) + +/** + \brief Enable External Interrupt + \details Enable a device-specific interrupt in the VIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void csi_vic_enable_irq(int32_t IRQn) +{ + CLIC->CLICINT[IRQn].IE |= CLIC_INTIE_IE_Msk; +} + +/** + \brief Disable External Interrupt + \details Disable a device-specific interrupt in the VIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void csi_vic_disable_irq(int32_t IRQn) +{ + CLIC->CLICINT[IRQn].IE &= ~CLIC_INTIE_IE_Msk; +} + +/** + \brief Enable External Secure Interrupt + \details Enable a secure device-specific interrupt in the VIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void csi_vic_enable_sirq(int32_t IRQn) +{ + CLIC->CLICINT[IRQn].IE |= (CLIC_INTIE_IE_Msk | CLIC_INTIE_T_Msk); +} + +/** + \brief Disable External Secure Interrupt + \details Disable a secure device-specific interrupt in the VIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void csi_vic_disable_sirq(int32_t IRQn) +{ + CLIC->CLICINT[IRQn].IE &= ~(CLIC_INTIE_IE_Msk | CLIC_INTIE_T_Msk); +} + +/** + \brief Check Interrupt is Enabled or not + \details Read the enabled register in the VIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not enabled. + \return 1 Interrupt status is enabled. + */ +__STATIC_INLINE uint32_t csi_vic_get_enabled_irq(int32_t IRQn) +{ + return (uint32_t)(CLIC->CLICINT[IRQn].IE & CLIC_INTIE_IE_Msk); +} + +/** + \brief Check Interrupt is Pending or not + \details Read the pending register in the VIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t csi_vic_get_pending_irq(int32_t IRQn) +{ + return (uint32_t)(CLIC->CLICINT[IRQn].IP & CLIC_INTIP_IP_Msk); +} + +/** + \brief Set Pending Interrupt + \details Set the pending bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void csi_vic_set_pending_irq(int32_t IRQn) +{ + CLIC->CLICINT[IRQn].IP |= CLIC_INTIP_IP_Msk; +} + +/** + \brief Clear Pending Interrupt + \details Clear the pending bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void csi_vic_clear_pending_irq(int32_t IRQn) +{ + CLIC->CLICINT[IRQn].IP &= ~CLIC_INTIP_IP_Msk; +} + +/** + \brief Set Interrupt Priority + \details Set the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void csi_vic_set_prio(int32_t IRQn, uint32_t priority) +{ + uint8_t nlbits = (CLIC->CLICINFO & CLIC_INFO_CLICINTCTLBITS_Msk) >> CLIC_INFO_CLICINTCTLBITS_Pos; + CLIC->CLICINT[IRQn].CTL = (CLIC->CLICINT[IRQn].CTL & (~CLIC_INTCFG_PRIO_Msk)) | (priority << (8 - nlbits)); +} + +/** + \brief Get Interrupt Priority + \details Read the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t csi_vic_get_prio(int32_t IRQn) +{ + uint8_t nlbits = (CLIC->CLICINFO & CLIC_INFO_CLICINTCTLBITS_Msk) >> CLIC_INFO_CLICINTCTLBITS_Pos; + return CLIC->CLICINT[IRQn].CTL >> (8 - nlbits); +} + +/** + \brief Set interrupt handler + \details Set the interrupt handler according to the interrupt num, the handler will be filled in irq vectors. + \param [in] IRQn Interrupt number. + \param [in] handler Interrupt handler. + */ +__STATIC_INLINE void csi_vic_set_vector(int32_t IRQn, uint32_t handler) +{ + if (IRQn >= 0 && IRQn < 1024) { + uint32_t *vectors = (uint32_t *)__get_MTVT(); + vectors[IRQn] = handler; + } +} + +/** + \brief Get interrupt handler + \details Get the address of interrupt handler function. + \param [in] IRQn Interrupt number. + */ +__STATIC_INLINE uint32_t csi_vic_get_vector(int32_t IRQn) +{ + if (IRQn >= 0 && IRQn < 1024) { + uint32_t *vectors = (uint32_t *)__get_MTVT(); + return (uint32_t)vectors[IRQn]; + } + + return 0; +} + +/*@} end of CSI_Core_VICFunctions */ + +/* ########################## PMP functions #################################### */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_PMPFunctions PMP Functions + \brief Functions that manage interrupts and exceptions via the VIC. + @{ + */ + +/** + \brief configure memory protected region. + \details + \param [in] idx memory protected region (0, 1, 2, ..., 15). + \param [in] base_addr base address must be aligned with page size. + \param [in] size \ref region_size_e. memory protected region size. + \param [in] attr \ref region_size_t. memory protected region attribute. + \param [in] enable enable or disable memory protected region. + */ +__STATIC_INLINE void csi_mpu_config_region(uint32_t idx, uint32_t base_addr, region_size_e size, + mpu_region_attr_t attr, uint32_t enable) +{ + uint8_t pmpxcfg = 0; + uint32_t addr = 0; + + if (idx > 15) { + return; + } + + if (!enable) { + attr.a = 0; + } + + if (attr.a == ADDRESS_MATCHING_TOR) { + addr = base_addr >> 2; + } else { + if (size == REGION_SIZE_4B) { + addr = base_addr >> 2; + attr.a = 2; + } else { + addr = ((base_addr >> 2) & (0xFFFFFFFFU - ((1 << (size + 1)) - 1))) | ((1 << size) - 1); + } + } + + __set_PMPADDRx(idx, addr); + + pmpxcfg |= (attr.r << PMP_PMPCFG_R_Pos) | (attr.w << PMP_PMPCFG_W_Pos) | + (attr.x << PMP_PMPCFG_X_Pos) | (attr.a << PMP_PMPCFG_A_Pos) | + (attr.l << PMP_PMPCFG_L_Pos); + + __set_PMPxCFG(idx, pmpxcfg); +} + +/** + \brief disable mpu region by idx. + \details + \param [in] idx memory protected region (0, 1, 2, ..., 15). + */ +__STATIC_INLINE void csi_mpu_disable_region(uint32_t idx) +{ + __set_PMPxCFG(idx, __get_PMPxCFG(idx) & (~PMP_PMPCFG_A_Msk)); +} + +/*@} end of CSI_Core_PMPFunctions */ + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +/** + \brief CORE timer Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \param [in] IRQn core timer Interrupt number. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t csi_coret_config(uint32_t ticks, int32_t IRQn) +{ + if ((CORET->MTIMECMP != 0) && (CORET->MTIMECMP != 0xffffffffffffffff)) { + CORET->MTIMECMP = CORET->MTIMECMP + ticks; + } else { + CORET->MTIMECMP = CORET->MTIME + ticks; + } + + return (0UL); +} + +/** + \brief CORE timer Configuration in use + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \param [in] IRQn core timer Interrupt number. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t csi_coret_config_use(uint32_t ticks, int32_t IRQn) +{ + CORET->MTIMECMP = CORET->MTIME + ticks; + + return (0UL); +} + +/** + \brief get CORE timer reload value + \return CORE timer counter value. + */ +__STATIC_INLINE uint32_t csi_coret_get_load(void) +{ + return CORET->MTIMECMP & 0xFFFFFFFF; +} + +/** + \brief get CORE timer reload high value + \return CORE timer counter value. + */ +__STATIC_INLINE uint32_t csi_coret_get_loadh(void) +{ + return (CORET->MTIMECMP >> 32) & 0xFFFFFFFF; +} + +/** + \brief get CORE timer counter value + \return CORE timer counter value. + */ +__STATIC_INLINE uint32_t csi_coret_get_value(void) +{ + return CORET->MTIME & 0xFFFFFFFF; +} + +/** + \brief get CORE timer counter high value + \return CORE timer counter value. + */ +__STATIC_INLINE uint32_t csi_coret_get_valueh(void) +{ + return (CORET->MTIME >> 32) & 0xFFFFFFFF; +} + +/*@} end of CSI_Core_SysTickFunctions */ + +/* ########################## SYSMAP functions #################################### */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_SYSMAPFunctions SYSMAP Functions + \brief Functions that manage system map attribute + @{ + */ + +/** + \brief Get SYSMAPCFGx Register by index + \details Returns the content of the SYSMAPxCFG Register. + \param [in] idx SYSMAP region index + \return SYSMAPxCFG Register value + */ +__STATIC_INLINE uint8_t __get_SYSMAPCFGx(uint32_t idx) +{ + switch (idx) { + case 0: + return SYSMAP->SYSMAPCFG0; + + case 1: + return SYSMAP->SYSMAPCFG1; + + case 2: + return SYSMAP->SYSMAPCFG2; + + case 3: + return SYSMAP->SYSMAPCFG3; + + case 4: + return SYSMAP->SYSMAPCFG4; + + case 5: + return SYSMAP->SYSMAPCFG5; + + case 6: + return SYSMAP->SYSMAPCFG6; + + case 7: + return SYSMAP->SYSMAPCFG7; + + default: + return 0; + } +} + +/** + \brief Set SYSMAPCFGx by index + \details Writes the given value to the SYSMAPxCFG Register. + \param [in] idx SYSMAPx region index + \param [in] sysmapxcfg SYSMAPxCFG Register value to set + */ +__STATIC_INLINE void __set_SYSMAPCFGx(uint32_t idx, uint32_t sysmapxcfg) +{ + switch (idx) { + case 0: + SYSMAP->SYSMAPCFG0 = sysmapxcfg; + break; + + case 1: + SYSMAP->SYSMAPCFG1 = sysmapxcfg; + break; + + case 2: + SYSMAP->SYSMAPCFG2 = sysmapxcfg; + break; + + case 3: + SYSMAP->SYSMAPCFG3 = sysmapxcfg; + break; + + case 4: + SYSMAP->SYSMAPCFG4 = sysmapxcfg; + break; + + case 5: + SYSMAP->SYSMAPCFG5 = sysmapxcfg; + break; + + case 6: + SYSMAP->SYSMAPCFG6 = sysmapxcfg; + break; + + case 7: + SYSMAP->SYSMAPCFG7 = sysmapxcfg; + break; + + default: + return; + } +} + +/** + \brief Get SYSMAPADDRx Register by index + \details Returns the content of the SYSMAPADDRx Register. + \param [in] idx SYSMAP region index + \return SYSMAPADDRx Register value + */ +__STATIC_INLINE uint32_t __get_SYSMAPADDRx(uint32_t idx) +{ + switch (idx) { + case 0: + return SYSMAP->SYSMAPADDR0; + + case 1: + return SYSMAP->SYSMAPADDR1; + + case 2: + return SYSMAP->SYSMAPADDR2; + + case 3: + return SYSMAP->SYSMAPADDR3; + + case 4: + return SYSMAP->SYSMAPADDR4; + + case 5: + return SYSMAP->SYSMAPADDR5; + + case 6: + return SYSMAP->SYSMAPADDR6; + + case 7: + return SYSMAP->SYSMAPADDR7; + + default: + return 0; + } +} + +/** + \brief Set SYSMAPADDRx by index + \details Writes the given value to the SYSMAPADDRx Register. + \param [in] idx SYSMAP region index + \param [in] sysmapaddr SYSMAPADDRx Register value to set + */ +__STATIC_INLINE void __set_SYSMAPADDRx(uint32_t idx, uint32_t sysmapxaddr) +{ + switch (idx) { + case 0: + SYSMAP->SYSMAPADDR0 = sysmapxaddr; + break; + + case 1: + SYSMAP->SYSMAPADDR1 = sysmapxaddr; + break; + + case 2: + SYSMAP->SYSMAPADDR2 = sysmapxaddr; + break; + + case 3: + SYSMAP->SYSMAPADDR3 = sysmapxaddr; + break; + + case 4: + SYSMAP->SYSMAPADDR4 = sysmapxaddr; + break; + + case 5: + SYSMAP->SYSMAPADDR5 = sysmapxaddr; + break; + + case 6: + SYSMAP->SYSMAPADDR6 = sysmapxaddr; + break; + + case 7: + SYSMAP->SYSMAPADDR7 = sysmapxaddr; + break; + + default: + return; + } +} + +/** + \brief configure system map attribute. + \details + \param [in] idx system map region (0, 1, 2, ..., 7). + \param [in] base_addr base address must be aligned with page size. + \param [in] enable enable or disable memory protected region. + */ +__STATIC_INLINE void csi_sysmap_config_region(uint32_t idx, uint32_t base_addr, uint32_t attr) +{ + uint32_t addr = 0; + + if (idx > 7) { + return; + } + + addr = base_addr >> 12; + attr = attr << 2; + + __set_SYSMAPADDRx(idx, addr); + __set_SYSMAPCFGx(idx, attr); +} + +/*@} end of CSI_Core_SYSMAPFunctions */ + +/* ##################################### DCC function ########################################### */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_core_DebugFunctions HAD Functions + \brief Functions that access the HAD debug interface. + @{ + */ + +/** + \brief HAD Send Character + \details Transmits a character via the HAD channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t csi_had_send_char(uint32_t ch) +{ + DCC->DERJR = (uint8_t)ch; + + return (ch); +} + +/** + \brief HAD Receive Character + \details Inputs a character via the external variable \ref HAD_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t csi_had_receive_char(void) +{ + int32_t ch = -1; /* no character available */ + + if (_FLD2VAL(DCC_EHSR_JW, DCC->EHSR)) { + ch = DCC->DERJW; + } + + return (ch); +} + +/** + \brief HAD Check Character + \details Check whether a character is pending for reading in the variable \ref HAD_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t csi_had_check_char(void) +{ + return _FLD2VAL(DCC_EHSR_JW, DCC->EHSR); /* no character available */ +} + +/*@} end of CSI_core_DebugFunctions */ + +/* ########################## sleep and Reset functions #################################### */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_SleepAndResetFunctions Sleep and Reset Functions + \brief Functions that configure Sleep and Reset. + @{ + */ + +/* MEXSTATUS Register Definitions */ +#define MEXSTATUS_RESET_Pos 0U +#define MEXSTATUS_RESET_Msk (0x3UL << MEXSTATUS_RESET_Pos) /*!< MEXSTATUS: RESET Position */ +#define MEXSTATUS_SLEEP_Pos 2U +#define MEXSTATUS_SLEEP_Msk (0x3UL << MEXSTATUS_SLEEP_Pos) /*!< MEXSTATUS: RESET Position */ +/*@} end of group CSI_MEXSTATUS */ + +/** + \brief CPU System Reset + \details Triggle CPU System Reset + */ +__STATIC_INLINE void csi_system_reset(void) +{ + uint32_t mexstatus; + mexstatus = __get_MEXSTATUS(); + mexstatus &= (~(MEXSTATUS_RESET_Msk)); + mexstatus |= (uint32_t)(0x2 << MEXSTATUS_RESET_Pos); + __set_MEXSTATUS(mexstatus); +} + +/** + \brief CPU Core Reset + \details Triggle CPU Core Reset + */ +__STATIC_INLINE void csi_core_reset(void) +{ + uint32_t mexstatus; + mexstatus = __get_MEXSTATUS(); + mexstatus &= (~(MEXSTATUS_RESET_Msk)); + mexstatus |= (uint32_t)(0x1 << MEXSTATUS_RESET_Pos); + __set_MEXSTATUS(mexstatus); +} + +/* ########################## Cache functions #################################### */ +/** + \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_CacheFunctions Cache Functions + \brief Functions that configure Instruction and Data cache. + @{ + */ + +/** + \brief Enable I-Cache + \details Turns on I-Cache + */ +__STATIC_INLINE void csi_icache_enable(void) +{ +#if (__ICACHE_PRESENT == 1U) + uint32_t cache; + __DSB(); + __ISB(); + __ICACHE_IALL(); + cache = __get_MHCR(); + cache |= CACHE_MHCR_IE_Msk; + __set_MHCR(cache); + __DSB(); + __ISB(); +#endif +} + +/** + \brief Disable I-Cache + \details Turns off I-Cache + */ +__STATIC_INLINE void csi_icache_disable(void) +{ +#if (__ICACHE_PRESENT == 1U) + uint32_t cache; + __DSB(); + __ISB(); + cache = __get_MHCR(); + cache &= ~CACHE_MHCR_IE_Msk; /* disable icache */ + __set_MHCR(cache); + __ICACHE_IALL(); /* invalidate all icache */ + __DSB(); + __ISB(); +#endif +} + +/** + \brief Invalidate I-Cache + \details Invalidates I-Cache + */ +__STATIC_INLINE void csi_icache_invalid(void) +{ +#if (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + __ICACHE_IALL(); /* invalidate all icache */ + __DSB(); + __ISB(); +#endif +} + +/** + \brief Enable D-Cache + \details Turns on D-Cache + \note I-Cache also turns on. + */ +__STATIC_INLINE void csi_dcache_enable(void) +{ +#if (__DCACHE_PRESENT == 1U) + uint32_t cache; + __DSB(); + __ISB(); + __DCACHE_IALL(); /* invalidate all dcache */ + cache = __get_MHCR(); + cache |= (CACHE_MHCR_DE_Msk | CACHE_MHCR_WB_Msk | CACHE_MHCR_WA_Msk | CACHE_MHCR_RS_Msk | CACHE_MHCR_BPE_Msk | CACHE_MHCR_L0BTB_Msk); /* enable all Cache */ + __set_MHCR(cache); + + __DSB(); + __ISB(); +#endif +} + +/** + \brief Disable D-Cache + \details Turns off D-Cache + \note I-Cache also turns off. + */ +__STATIC_INLINE void csi_dcache_disable(void) +{ +#if (__DCACHE_PRESENT == 1U) + uint32_t cache; + __DSB(); + __ISB(); + cache = __get_MHCR(); + cache &= ~(uint32_t)CACHE_MHCR_DE_Msk; /* disable all Cache */ + __set_MHCR(cache); + __DCACHE_IALL(); /* invalidate all Cache */ + __DSB(); + __ISB(); +#endif +} + +/** + \brief Invalidate D-Cache + \details Invalidates D-Cache + \note I-Cache also invalid + */ +__STATIC_INLINE void csi_dcache_invalid(void) +{ +#if (__DCACHE_PRESENT == 1U) + __DSB(); + __DCACHE_IALL(); /* invalidate all Cache */ + __DSB(); +#endif +} + +/** + \brief Clean D-Cache + \details Cleans D-Cache + \note I-Cache also cleans + */ +__STATIC_INLINE void csi_dcache_clean(void) +{ +#if (__DCACHE_PRESENT == 1U) + __DSB(); + __DCACHE_CALL(); /* clean all Cache */ + __DSB(); +#endif +} + +/** + \brief Clean & Invalidate D-Cache + \details Cleans and Invalidates D-Cache + \note I-Cache also flush. + */ +__STATIC_INLINE void csi_dcache_clean_invalid(void) +{ +#if (__DCACHE_PRESENT == 1U) + __DSB(); + __DCACHE_CIALL(); /* clean and inv all Cache */ + __DSB(); +#endif +} + +/** + \brief D-Cache Invalidate by address + \details Invalidates D-Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void csi_dcache_invalid_range(uint32_t *addr, int32_t dsize) +{ +#if (__DCACHE_PRESENT == 1U) + int32_t op_size = dsize + (uint32_t)addr % 32; + uint32_t op_addr = (uint32_t)addr; + int32_t linesize = 32; + + __DSB(); + + while (op_size > 0) { + __DCACHE_IPA(op_addr); + op_addr += linesize; + op_size -= linesize; + } + + __DSB(); +#endif +} + +/** + \brief D-Cache Clean by address + \details Cleans D-Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void csi_dcache_clean_range(uint32_t *addr, int32_t dsize) +{ +#if (__DCACHE_PRESENT == 1U) + int32_t op_size = dsize + (uint32_t)addr % 32; + uint32_t op_addr = (uint32_t)addr & CACHE_INV_ADDR_Msk; + int32_t linesize = 32; + + __DSB(); + + while (op_size > 0) { + __DCACHE_CPA(op_addr); + op_addr += linesize; + op_size -= linesize; + } + + __DSB(); +#endif +} + +/** + \brief D-Cache Clean and Invalidate by address + \details Cleans and invalidates D_Cache for the given address + \param[in] addr address (aligned to 16-byte boundary) + \param[in] dsize size of memory block (aligned to 16-byte boundary) +*/ +__STATIC_INLINE void csi_dcache_clean_invalid_range(uint32_t *addr, int32_t dsize) +{ +#if (__DCACHE_PRESENT == 1U) + int32_t op_size = dsize + (uint32_t)addr % 32; + uint32_t op_addr = (uint32_t)addr; + int32_t linesize = 32; + + __DSB(); + + while (op_size > 0) { + __DCACHE_CIPA(op_addr); + op_addr += linesize; + op_size -= linesize; + } + + __DSB(); +#endif +} + +/** + \brief setup cacheable range Cache + \details setup Cache range + */ +__STATIC_INLINE void csi_cache_set_range(uint32_t index, uint32_t baseAddr, uint32_t size, uint32_t enable) +{ + ; +} + +/** + \brief Enable cache profile + \details Turns on Cache profile + */ +__STATIC_INLINE void csi_cache_enable_profile(void) +{ + ; +} + +/** + \brief Disable cache profile + \details Turns off Cache profile + */ +__STATIC_INLINE void csi_cache_disable_profile(void) +{ + ; +} + +/** + \brief Reset cache profile + \details Reset Cache profile + */ +__STATIC_INLINE void csi_cache_reset_profile(void) +{ + ; +} + +/** + \brief cache access times + \details Cache access times + \note every 256 access add 1. + \return cache access times, actual times should be multiplied by 256 + */ +__STATIC_INLINE uint32_t csi_cache_get_access_time(void) +{ + return 0; +} + +/** + \brief cache miss times + \details Cache miss times + \note every 256 miss add 1. + \return cache miss times, actual times should be multiplied by 256 + */ +__STATIC_INLINE uint32_t csi_cache_get_miss_time(void) +{ + return 0; +} + +/*@} end of CSI_Core_CacheFunctions */ + +/*@} end of CSI_core_DebugFunctions */ + +/* ################################## IRQ Functions ############################################ */ + +/** + \brief Save the Irq context + \details save the psr result before disable irq. + */ +__STATIC_INLINE uint32_t csi_irq_save(void) +{ + uint32_t result; + result = __get_MSTATUS(); + __disable_irq(); + return (result); +} + +/** + \brief Restore the Irq context + \details restore saved primask state. + \param [in] irq_state psr irq state. + */ +__STATIC_INLINE void csi_irq_restore(uint32_t irq_state) +{ + __set_MSTATUS(irq_state); +} + +/*@} end of IRQ Functions */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_RV32_H_DEPENDANT */ + +#endif /* __CSI_GENERIC */ diff --git a/platforms/bl808_m0/vendor/psram/include/csi_core.h b/platforms/bl808_m0/vendor/psram/include/csi_core.h new file mode 100644 index 0000000..026e06e --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/csi_core.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2017-2019 Alibaba Group Holding Limited + */ + +/****************************************************************************** + * @file csi_core.h + * @brief CSI Core Layer Header File + * @version V1.0 + * @date 02. June 2017 + ******************************************************************************/ + +#ifndef _CORE_H_ +#define _CORE_H_ + +#include + +#if defined(__CK801__) || defined(__E801__) +#include +#elif defined(__CK802__) || defined(__E802__) || defined(__E802T__) || defined(__S802__) || defined(__S802T__) +#include +#elif defined(__CK804__) || defined(__E804D__) || defined(__E804DT__) || defined(__E804F__) || defined(__E804FT__) || defined(__E804DF__) || defined(__E804DFT__) +#include +#elif defined(__CK803__) || defined(__E803__) || defined(__E803T__) || defined(__S803__) || defined(__S803T__) +#include +#elif defined(__CK805__) || defined(__I805__) || defined(__I805F__) +#include +#elif defined(__CK610__) +#include +#elif defined(__CK810__) || defined(__C810__) || defined(__C810T__) || defined(__C810V__) || defined(__C810VT__) +#include +#elif defined(__CK807__) || defined(__C807__) || defined(__C807F__) || defined(__C807FV__) || defined(__R807__) +#include +#elif defined(__riscv) && defined(CONFIG_CSKY_CORETIM) +#include +#elif defined(__riscv) +#if (__riscv_xlen == 32) +#include +#elif (__riscv_xlen == 64) +#include +#else +#error "XLEN of riscv not supported" +#endif +#endif + +#ifdef __riscv +#if (__riscv_xlen == 32) +#include +#elif (__riscv_xlen == 64) +#include +#else +#error "XLEN of riscv not supported" +#endif +#else +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _CORE_H_ */ diff --git a/platforms/bl808_m0/vendor/psram/include/csi_rv32_gcc.h b/platforms/bl808_m0/vendor/psram/include/csi_rv32_gcc.h new file mode 100644 index 0000000..595bdd5 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/csi_rv32_gcc.h @@ -0,0 +1,3104 @@ +/* + * Copyright (C) 2017-2019 Alibaba Group Holding Limited + */ + +/****************************************************************************** + * @file csi_rv32_gcc.h + * @brief CSI Header File for GCC. + * @version V1.0 + * @date 01. Sep 2018 + ******************************************************************************/ + +#ifndef _CSI_RV32_GCC_H_ +#define _CSI_RV32_GCC_H_ + +#include + +#ifndef __ASM +#define __ASM __asm /*!< asm keyword for GNU Compiler */ +#endif + +#ifndef __INLINE +#define __INLINE inline /*!< inline keyword for GNU Compiler */ +#endif + +#ifndef __ALWAYS_STATIC_INLINE +#define __ALWAYS_STATIC_INLINE __attribute__((always_inline)) static inline +#endif + +#ifndef __STATIC_INLINE +#define __STATIC_INLINE static inline +#endif + +/* ########################### Core Function Access ########################### */ +/** \ingroup CSI_Core_FunctionInterface + \defgroup CSI_Core_RegAccFunctions CSI Core Register Access Functions + @{ + */ +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by setting the IE-bit in the PSR. + Can only be executed in Privileged modes. + */ +__ALWAYS_STATIC_INLINE void __enable_irq(void) +{ + __ASM volatile("csrs mstatus, 8"); +} + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by clearing the IE-bit in the PSR. + Can only be executed in Privileged modes. + */ +__ALWAYS_STATIC_INLINE void __disable_irq(void) +{ + __ASM volatile("csrc mstatus, 8"); +} + +/** + \brief Get MXSTATUS + \details Returns the content of the MXSTATUS Register. + \return MXSTATUS Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MXSTATUS(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mxstatus" + : "=r"(result)); + return (result); +} + +/** + \brief Set MXSTATUS + \details Writes the given value to the MXSTATUS Register. + \param [in] MXSTATUS Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MXSTATUS(uint32_t mxstatus) +{ + __ASM volatile("csrw mxstatus, %0" + : + : "r"(mxstatus)); +} + +/** + \brief Get MEXSTATUS + \details Returns the content of the MEXSTATUS Register. + \return MEXSTATUS Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MEXSTATUS(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mexstatus" + : "=r"(result)); + return (result); +} + +/** + \brief Set MEXSTATUS + \details Writes the given value to the MSTATUS Register. + \param [in] MEXSTATUS Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MEXSTATUS(uint32_t mexstatus) +{ + __ASM volatile("csrw mexstatus, %0" + : + : "r"(mexstatus)); +} + +/** + \brief Get MRADDR + \details Returns the content of the MRADDR Register. + \return MRADDR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MRADDR(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mraddr" + : "=r"(result)); + return (result); +} + +/** + \brief Get FXCR + \details Returns the content of the FXCR Register. + \return FXCR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_FXCR(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, fxcr" + : "=r"(result)); + return (result); +} + +/** + \brief Set FXCR + \details Writes the given value to the FXCR Register. + \param [in] FXCR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_FXCR(uint32_t fxcr) +{ + __ASM volatile("csrw fxcr, %0" + : + : "r"(fxcr)); +} + +/** + \brief Get MSTATUS + \details Returns the content of the MSTATUS Register. + \return MSTATUS Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MSTATUS(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mstatus" + : "=r"(result)); + return (result); +} + +/** + \brief Set MSTATUS + \details Writes the given value to the MSTATUS Register. + \param [in] mstatus MSTATUS Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MSTATUS(uint32_t mstatus) +{ + __ASM volatile("csrw mstatus, %0" + : + : "r"(mstatus)); +} + +/** + \brief Get MHCR + \details Returns the content of the MHCR Register. + \return MHCR Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MHCR(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mhcr" + : "=r"(result)); + return (result); +} + +/** + \brief Set MHCR + \details Writes the given value to the MHCR Register. + \param [in] MHCR Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MHCR(uint32_t mhcr) +{ + __ASM volatile("csrw mhcr, %0" + : + : "r"(mhcr)); +} + +/** + \brief Get MHINT + \details Returns the content of the MHINT Register. + \return MHINT Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MHINT(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mhint" + : "=r"(result)); + return (result); +} + +/** + \brief Set MHINT + \details Writes the given value to the MHINT Register. + \param [in] MHINT Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MHINT(uint32_t mhint) +{ + __ASM volatile("csrw mhint, %0" + : + : "r"(mhint)); +} + +/** + \brief Get MISA Register + \details Returns the content of the MISA Register. + \return MISA Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MISA(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, misa" + : "=r"(result)); + return (result); +} + +/** + \brief Set MISA + \details Writes the given value to the MISA Register. + \param [in] misa MISA Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MISA(uint32_t misa) +{ + __ASM volatile("csrw misa, %0" + : + : "r"(misa)); +} + +/** + \brief Get MIE Register + \details Returns the content of the MIE Register. + \return MIE Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MIE(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mie" + : "=r"(result)); + return (result); +} + +/** + \brief Set MIE + \details Writes the given value to the MIE Register. + \param [in] mie MIE Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MIE(uint32_t mie) +{ + __ASM volatile("csrw mie, %0" + : + : "r"(mie)); +} + +/** + \brief Get MTVEC Register + \details Returns the content of the MTVEC Register. + \return MTVEC Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MTVEC(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mtvec" + : "=r"(result)); + return (result); +} + +/** + \brief Set MTVEC + \details Writes the given value to the MTVEC Register. + \param [in] mtvec MTVEC Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MTVEC(uint32_t mtvec) +{ + __ASM volatile("csrw mtvec, %0" + : + : "r"(mtvec)); +} + +/** + \brief Set MTVT + \details Writes the given value to the MTVT Register. + \param [in] mtvt MTVT Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MTVT(uint32_t mtvt) +{ + __ASM volatile("csrw mtvt, %0" + : + : "r"(mtvt)); +} + +/** + \brief Get MTVT Register + \details Returns the content of the MTVT Register. + \return MTVT Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MTVT(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mtvt" + : "=r"(result)); + return (result); +} + +/** + \brief Get SP + \details Returns the content of the SP Register. + \return SP Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_SP(void) +{ + uint32_t result; + + __ASM volatile("mv %0, sp" + : "=r"(result)); + return (result); +} + +/** + \brief Set SP + \details Writes the given value to the SP Register. + \param [in] sp SP Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_SP(uint32_t sp) +{ + __ASM volatile("mv sp, %0" + : + : "r"(sp) + : "sp"); +} + +/** + \brief Get MSCRATCH Register + \details Returns the content of the MSCRATCH Register. + \return MSCRATCH Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MSCRATCH(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mscratch" + : "=r"(result)); + return (result); +} + +/** + \brief Set MSCRATCH + \details Writes the given value to the MSCRATCH Register. + \param [in] mscratch MSCRATCH Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MSCRATCH(uint32_t mscratch) +{ + __ASM volatile("csrw mscratch, %0" + : + : "r"(mscratch)); +} + +/** + \brief Get MEPC Register + \details Returns the content of the MEPC Register. + \return MEPC Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MEPC(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mepc" + : "=r"(result)); + return (result); +} + +/** + \brief Set MEPC + \details Writes the given value to the MEPC Register. + \param [in] mepc MEPC Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MEPC(uint32_t mepc) +{ + __ASM volatile("csrw mepc, %0" + : + : "r"(mepc)); +} + +/** + \brief Get MCAUSE Register + \details Returns the content of the MCAUSE Register. + \return MCAUSE Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MCAUSE(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mcause" + : "=r"(result)); + return (result); +} + +/** + \brief Get MNXTI Register + \details Returns the content of the MNXTI Register. + \return MNXTI Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MNXTI(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mnxti" + : "=r"(result)); + return (result); +} + +/** + \brief Set MNXTI + \details Writes the given value to the MNXTI Register. + \param [in] mnxti MNXTI Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MNXTI(uint32_t mnxti) +{ + __ASM volatile("csrw mnxti, %0" + : + : "r"(mnxti)); +} + +/** + \brief Get MINTSTATUS Register + \details Returns the content of the MINTSTATUS Register. + \return MINTSTATUS Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MINTSTATUS(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mintstatus" + : "=r"(result)); + return (result); +} + +/** + \brief Get MTVAL Register + \details Returns the content of the MTVAL Register. + \return MTVAL Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MTVAL(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mtval" + : "=r"(result)); + return (result); +} + +/** + \brief Get MIP Register + \details Returns the content of the MIP Register. + \return MIP Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MIP(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mip" + : "=r"(result)); + return (result); +} + +/** + \brief Set MIP + \details Writes the given value to the MIP Register. + \param [in] mip MIP Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_MIP(uint32_t mip) +{ + __ASM volatile("csrw mip, %0" + : + : "r"(mip)); +} + +/** + \brief Get MCYCLEL Register + \details Returns the content of the MCYCLEL Register. + \return MCYCLE Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MCYCLE(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mcycle" + : "=r"(result)); + return (result); +} + +/** + \brief Get MCYCLEH Register + \details Returns the content of the MCYCLEH Register. + \return MCYCLEH Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MCYCLEH(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mcycleh" + : "=r"(result)); + return (result); +} + +/** + \brief Get MINSTRET Register + \details Returns the content of the MINSTRET Register. + \return MINSTRET Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MINSTRET(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, minstret" + : "=r"(result)); + return (result); +} + +/** + \brief Get MINSTRETH Register + \details Returns the content of the MINSTRETH Register. + \return MINSTRETH Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MINSTRETH(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, minstreth" + : "=r"(result)); + return (result); +} + +/** + \brief Get MVENDORID Register + \details Returns the content of the MVENDROID Register. + \return MVENDORID Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MVENDORID(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mvendorid" + : "=r"(result)); + return (result); +} + +/** + \brief Get MARCHID Register + \details Returns the content of the MARCHID Register. + \return MARCHID Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MARCHID(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, marchid" + : "=r"(result)); + return (result); +} + +/** + \brief Get MIMPID Register + \details Returns the content of the MIMPID Register. + \return MIMPID Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MIMPID(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mimpid" + : "=r"(result)); + return (result); +} + +/** + \brief Get MHARTID Register + \details Returns the content of the MHARTID Register. + \return MHARTID Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_MHARTID(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, mhartid" + : "=r"(result)); + return (result); +} + +/** + \brief Get PMPCFGx Register + \details Returns the content of the PMPCFGx Register. + \return PMPCFGx Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_PMPCFG0(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, pmpcfg0" + : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE uint32_t __get_PMPCFG1(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, pmpcfg1" + : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE uint32_t __get_PMPCFG2(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, pmpcfg2" + : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE uint32_t __get_PMPCFG3(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, pmpcfg3" + : "=r"(result)); + return (result); +} + +/** + \brief Get PMPxCFG Register by index + \details Returns the content of the PMPxCFG Register. + \param [in] idx PMP region index + \return PMPxCFG Register value + */ +__STATIC_INLINE uint8_t __get_PMPxCFG(uint32_t idx) +{ + uint32_t pmpcfgx = 0; + + if (idx < 4) { + pmpcfgx = __get_PMPCFG0(); + } else if (idx >= 4 && idx < 8) { + idx -= 4; + pmpcfgx = __get_PMPCFG1(); + } else if (idx >= 8 && idx < 12) { + idx -= 8; + pmpcfgx = __get_PMPCFG2(); + } else if (idx >= 12 && idx < 16) { + idx -= 12; + pmpcfgx = __get_PMPCFG3(); + } else { + return 0; + } + + return (uint8_t)((pmpcfgx & (0xFF << (idx << 3))) >> (idx << 3)); +} + +/** + \brief Set PMPCFGx + \details Writes the given value to the PMPCFGx Register. + \param [in] pmpcfg PMPCFGx Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_PMPCFG0(uint32_t pmpcfg) +{ + __ASM volatile("csrw pmpcfg0, %0" + : + : "r"(pmpcfg)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPCFG1(uint32_t pmpcfg) +{ + __ASM volatile("csrw pmpcfg1, %0" + : + : "r"(pmpcfg)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPCFG2(uint32_t pmpcfg) +{ + __ASM volatile("csrw pmpcfg2, %0" + : + : "r"(pmpcfg)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPCFG3(uint32_t pmpcfg) +{ + __ASM volatile("csrw pmpcfg3, %0" + : + : "r"(pmpcfg)); +} + +/** + \brief Set PMPxCFG by index + \details Writes the given value to the PMPxCFG Register. + \param [in] idx PMPx region index + \param [in] pmpxcfg PMPxCFG Register value to set + */ +__STATIC_INLINE void __set_PMPxCFG(uint32_t idx, uint8_t pmpxcfg) +{ + uint32_t pmpcfgx = 0; + + if (idx < 4) { + pmpcfgx = __get_PMPCFG0(); + pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | (pmpxcfg << (idx << 3)); + __set_PMPCFG0(pmpcfgx); + } else if (idx >= 4 && idx < 8) { + idx -= 4; + pmpcfgx = __get_PMPCFG1(); + pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | (pmpxcfg << (idx << 3)); + __set_PMPCFG1(pmpcfgx); + } else if (idx >= 8 && idx < 12) { + idx -= 8; + pmpcfgx = __get_PMPCFG2(); + pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | (pmpxcfg << (idx << 3)); + __set_PMPCFG2(pmpcfgx); + } else if (idx >= 12 && idx < 16) { + idx -= 12; + pmpcfgx = __get_PMPCFG3(); + pmpcfgx = (pmpcfgx & ~(0xFF << (idx << 3))) | (pmpxcfg << (idx << 3)); + __set_PMPCFG3(pmpcfgx); + } else { + return; + } +} + +/** + \brief Get PMPADDRx Register + \details Returns the content of the PMPADDRx Register. + \return PMPADDRx Register value + */ +__ALWAYS_STATIC_INLINE uint32_t __get_PMPADDR0(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, pmpaddr0" + : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE uint32_t __get_PMPADDR1(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, pmpaddr1" + : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE uint32_t __get_PMPADDR2(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, pmpaddr2" + : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE uint32_t __get_PMPADDR3(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, pmpaddr3" + : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE uint32_t __get_PMPADDR4(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, pmpaddr4" + : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE uint32_t __get_PMPADDR5(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, pmpaddr5" + : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE uint32_t __get_PMPADDR6(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, pmpaddr6" + : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE uint32_t __get_PMPADDR7(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, pmpaddr7" + : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE uint32_t __get_PMPADDR8(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, pmpaddr8" + : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE uint32_t __get_PMPADDR9(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, pmpaddr9" + : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE uint32_t __get_PMPADDR10(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, pmpaddr10" + : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE uint32_t __get_PMPADDR11(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, pmpaddr11" + : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE uint32_t __get_PMPADDR12(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, pmpaddr12" + : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE uint32_t __get_PMPADDR13(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, pmpaddr13" + : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE uint32_t __get_PMPADDR14(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, pmpaddr14" + : "=r"(result)); + return (result); +} + +__ALWAYS_STATIC_INLINE uint32_t __get_PMPADDR15(void) +{ + uint32_t result; + + __ASM volatile("csrr %0, pmpaddr15" + : "=r"(result)); + return (result); +} + +/** + \brief Get PMPADDRx Register by index + \details Returns the content of the PMPADDRx Register. + \param [in] idx PMP region index + \return PMPADDRx Register value + */ +__STATIC_INLINE uint32_t __get_PMPADDRx(uint32_t idx) +{ + switch (idx) { + case 0: + return __get_PMPADDR0(); + + case 1: + return __get_PMPADDR1(); + + case 2: + return __get_PMPADDR2(); + + case 3: + return __get_PMPADDR3(); + + case 4: + return __get_PMPADDR4(); + + case 5: + return __get_PMPADDR5(); + + case 6: + return __get_PMPADDR6(); + + case 7: + return __get_PMPADDR7(); + + case 8: + return __get_PMPADDR8(); + + case 9: + return __get_PMPADDR9(); + + case 10: + return __get_PMPADDR10(); + + case 11: + return __get_PMPADDR11(); + + case 12: + return __get_PMPADDR12(); + + case 13: + return __get_PMPADDR13(); + + case 14: + return __get_PMPADDR14(); + + case 15: + return __get_PMPADDR15(); + + default: + return 0; + } +} + +/** + \brief Set PMPADDRx + \details Writes the given value to the PMPADDRx Register. + \param [in] pmpaddr PMPADDRx Register value to set + */ +__ALWAYS_STATIC_INLINE void __set_PMPADDR0(uint32_t pmpaddr) +{ + __ASM volatile("csrw pmpaddr0, %0" + : + : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR1(uint32_t pmpaddr) +{ + __ASM volatile("csrw pmpaddr1, %0" + : + : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR2(uint32_t pmpaddr) +{ + __ASM volatile("csrw pmpaddr2, %0" + : + : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR3(uint32_t pmpaddr) +{ + __ASM volatile("csrw pmpaddr3, %0" + : + : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR4(uint32_t pmpaddr) +{ + __ASM volatile("csrw pmpaddr4, %0" + : + : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR5(uint32_t pmpaddr) +{ + __ASM volatile("csrw pmpaddr5, %0" + : + : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR6(uint32_t pmpaddr) +{ + __ASM volatile("csrw pmpaddr6, %0" + : + : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR7(uint32_t pmpaddr) +{ + __ASM volatile("csrw pmpaddr7, %0" + : + : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR8(uint32_t pmpaddr) +{ + __ASM volatile("csrw pmpaddr8, %0" + : + : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR9(uint32_t pmpaddr) +{ + __ASM volatile("csrw pmpaddr9, %0" + : + : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR10(uint32_t pmpaddr) +{ + __ASM volatile("csrw pmpaddr10, %0" + : + : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR11(uint32_t pmpaddr) +{ + __ASM volatile("csrw pmpaddr11, %0" + : + : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR12(uint32_t pmpaddr) +{ + __ASM volatile("csrw pmpaddr12, %0" + : + : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR13(uint32_t pmpaddr) +{ + __ASM volatile("csrw pmpaddr13, %0" + : + : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR14(uint32_t pmpaddr) +{ + __ASM volatile("csrw pmpaddr14, %0" + : + : "r"(pmpaddr)); +} + +__ALWAYS_STATIC_INLINE void __set_PMPADDR15(uint32_t pmpaddr) +{ + __ASM volatile("csrw pmpaddr15, %0" + : + : "r"(pmpaddr)); +} + +/** + \brief Set PMPADDRx by index + \details Writes the given value to the PMPADDRx Register. + \param [in] idx PMP region index + \param [in] pmpaddr PMPADDRx Register value to set + */ +__STATIC_INLINE void __set_PMPADDRx(uint32_t idx, uint32_t pmpaddr) +{ + switch (idx) { + case 0: + __set_PMPADDR0(pmpaddr); + break; + + case 1: + __set_PMPADDR1(pmpaddr); + break; + + case 2: + __set_PMPADDR2(pmpaddr); + break; + + case 3: + __set_PMPADDR3(pmpaddr); + break; + + case 4: + __set_PMPADDR4(pmpaddr); + break; + + case 5: + __set_PMPADDR5(pmpaddr); + break; + + case 6: + __set_PMPADDR6(pmpaddr); + break; + + case 7: + __set_PMPADDR7(pmpaddr); + break; + + case 8: + __set_PMPADDR8(pmpaddr); + break; + + case 9: + __set_PMPADDR9(pmpaddr); + break; + + case 10: + __set_PMPADDR10(pmpaddr); + break; + + case 11: + __set_PMPADDR11(pmpaddr); + break; + + case 12: + __set_PMPADDR12(pmpaddr); + break; + + case 13: + __set_PMPADDR13(pmpaddr); + break; + + case 14: + __set_PMPADDR14(pmpaddr); + break; + + case 15: + __set_PMPADDR15(pmpaddr); + break; + + default: + return; + } +} + +/** + \brief Enable interrupts and exceptions + \details Enables interrupts and exceptions by setting the IE-bit and EE-bit in the PSR. + Can only be executed in Privileged modes. + */ +__ALWAYS_STATIC_INLINE void __enable_excp_irq(void) +{ + __enable_irq(); +} + +/** + \brief Disable interrupts and exceptions + \details Disables interrupts and exceptions by clearing the IE-bit and EE-bit in the PSR. + Can only be executed in Privileged modes. + */ +__ALWAYS_STATIC_INLINE void __disable_excp_irq(void) +{ + __disable_irq(); +} + +#define __CSI_GCC_OUT_REG(r) "=r"(r) +#define __CSI_GCC_USE_REG(r) "r"(r) + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +__ALWAYS_STATIC_INLINE void __NOP(void) +{ + __ASM volatile("nop"); +} + +/** + \brief No Operation with mem barrier + \details No Operation does nothing. This instruction can be used for debugging purposes. + */ +__ALWAYS_STATIC_INLINE void __NOP_BARRIER(void) +{ + __ASM volatile("nop" :: + : "memory"); +} + +/** + \brief mem barrier for compiler + \details This will not generate any actual instructions, but add mem barrier for compiler. + */ +__ALWAYS_STATIC_INLINE void __COMPILE_BARRIER(void) +{ + __ASM volatile("" :: + : "memory"); +} + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +__ALWAYS_STATIC_INLINE void __WFI(void) +{ + __ASM volatile("wfi"); +} + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one interrupt occurs. + */ +__ALWAYS_STATIC_INLINE void __WAIT(void) +{ + __ASM volatile("wfi"); +} + +/** + \brief Doze For Interrupt + \details Doze For Interrupt is a hint instruction that suspends execution until one interrupt occurs. + */ +__ALWAYS_STATIC_INLINE void __DOZE(void) +{ + __ASM volatile("wfi"); +} + +/** + \brief Stop For Interrupt + \details Stop For Interrupt is a hint instruction that suspends execution until one interrupt occurs. + */ +__ALWAYS_STATIC_INLINE void __STOP(void) +{ + __ASM volatile("wfi"); +} + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__ALWAYS_STATIC_INLINE void __ISB(void) +{ + __ASM volatile("fence.i"); +} + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__ALWAYS_STATIC_INLINE void __DSB(void) +{ + __ASM volatile("fence"); +} + +/** + \brief Invalid all icache + \details invalid all icache. + */ +__ALWAYS_STATIC_INLINE void __ICACHE_IALL(void) +{ + __ASM volatile("icache.iall"); +} + +/** + \brief Invalid Icache by addr + \details Invalid Icache by addr. + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __ICACHE_IPA(uint32_t addr) +{ + __ASM volatile("icache.ipa %0" + : + : "r"(addr)); +} + +/** + \brief Invalid all dcache + \details invalid all dcache. + */ +__ALWAYS_STATIC_INLINE void __DCACHE_IALL(void) +{ + __ASM volatile("dcache.iall"); +} + +/** + \brief Clear all dcache + \details clear all dcache. + */ +__ALWAYS_STATIC_INLINE void __DCACHE_CALL(void) +{ + __ASM volatile("dcache.call"); +} + +/** + \brief Clear&invalid all dcache + \details clear & invalid all dcache. + */ +__ALWAYS_STATIC_INLINE void __DCACHE_CIALL(void) +{ + __ASM volatile("dcache.ciall"); +} + +/** + \brief Invalid Dcache by addr + \details Invalid Dcache by addr. + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __DCACHE_IPA(uint32_t addr) +{ + __ASM volatile("dcache.ipa %0" + : + : "r"(addr)); +} + +/** + \brief Clear Dcache by addr + \details Clear Dcache by addr. + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __DCACHE_CPA(uint32_t addr) +{ + __ASM volatile("dcache.cpa %0" + : + : "r"(addr)); +} + +/** + \brief Clear & Invalid Dcache by addr + \details Clear & Invalid Dcache by addr. + \param [in] addr operate addr + */ +__ALWAYS_STATIC_INLINE void __DCACHE_CIPA(uint32_t addr) +{ + __ASM volatile("dcache.cipa %0" + : + : "r"(addr)); +} + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__ALWAYS_STATIC_INLINE void __DMB(void) +{ + __ASM volatile("fence"); +} + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in integer value. + \param [in] value Value to reverse + \return Reversed value + */ +__ALWAYS_STATIC_INLINE uint32_t __REV(uint32_t value) +{ + return __builtin_bswap32(value); +} + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in two unsigned short values. + \param [in] value Value to reverse + \return Reversed value + */ +__ALWAYS_STATIC_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + result = ((value & 0xFF000000) >> 8) | ((value & 0x00FF0000) << 8) | + ((value & 0x0000FF00) >> 8) | ((value & 0x000000FF) << 8); + + return (result); +} + +/** + \brief Reverse byte order in signed short value + \details Reverses the byte order in a signed short value with sign extension to integer. + \param [in] value Value to reverse + \return Reversed value + */ +__ALWAYS_STATIC_INLINE int32_t __REVSH(int32_t value) +{ + return (short)(((value & 0xFF00) >> 8) | ((value & 0x00FF) << 8)); +} + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__ALWAYS_STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + return (op1 >> op2) | (op1 << (32U - op2)); +} + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + */ +__ALWAYS_STATIC_INLINE void __BKPT(void) +{ + __ASM volatile("ebreak"); +} + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__ALWAYS_STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + + int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + + for (value >>= 1U; value; value >>= 1U) { + result <<= 1U; + result |= value & 1U; + s--; + } + + result <<= s; /* shift when v's highest bits are zero */ + + return (result); +} + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#if defined(__riscv_32e) +#define __CLZ __builtin_clz +#else +__ALWAYS_STATIC_INLINE uint32_t __CLZ(uint32_t in) +{ + uint32_t result; + + __ASM volatile("ff1 %0, %1" + : "=r"(result) + : "r"(in)); + return (result); +} +#endif +/** + \details This function saturates a signed value. + \param [in] x Value to be saturated + \param [in] y Bit position to saturate to [1..32] + \return Saturated value. + */ +__ALWAYS_STATIC_INLINE int32_t __SSAT(int32_t x, uint32_t y) +{ + int32_t posMax, negMin; + uint32_t i; + + posMax = 1; + + for (i = 0; i < (y - 1); i++) { + posMax = posMax * 2; + } + + if (x > 0) { + posMax = (posMax - 1); + + if (x > posMax) { + x = posMax; + } + + // x &= (posMax * 2 + 1); + } else { + negMin = -posMax; + + if (x < negMin) { + x = negMin; + } + + // x &= (posMax * 2 - 1); + } + + return (x); +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__ALWAYS_STATIC_INLINE uint32_t __USAT(uint32_t value, uint32_t sat) +{ + uint32_t result; + + if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) { + result = 0xFFFFFFFF >> (32 - sat); + } else { + result = value; + } + + return (result); +} + +/** + \brief Unsigned Saturate for internal use + \details Saturates an unsigned value, should not call directly. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__ALWAYS_STATIC_INLINE uint32_t __IUSAT(uint32_t value, uint32_t sat) +{ + uint32_t result; + + if (value & 0x80000000) /* only overflow set bit-31 */ + { + result = 0; + } else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0) { + result = 0xFFFFFFFF >> (32 - sat); + } else { + result = value; + } + + return (result); +} + +/** + \brief Rotate Right with Extend + \details This function moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \note carry input will always 0. + \param [in] op1 Value to rotate + \return Rotated value + */ +__ALWAYS_STATIC_INLINE uint32_t __RRX(uint32_t op1) +{ + return 0; +} + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] addr Pointer to location + \return value of type uint8_t at (*ptr) + */ +__ALWAYS_STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile("lb %0, 0(%1)" + : "=r"(result) + : "r"(addr)); + + return ((uint8_t)result); /* Add explicit type cast here */ +} + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] addr Pointer to location + \return value of type uint16_t at (*ptr) + */ +__ALWAYS_STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile("lh %0, 0(%1)" + : "=r"(result) + : "r"(addr)); + + return ((uint16_t)result); /* Add explicit type cast here */ +} + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] addr Pointer to location + \return value of type uint32_t at (*ptr) + */ +__ALWAYS_STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile("lw %0, 0(%1)" + : "=r"(result) + : "r"(addr)); + + return (result); +} + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] addr Pointer to location + */ +__ALWAYS_STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr) +{ + __ASM volatile("sb %1, 0(%0)" ::"r"(addr), "r"((uint32_t)value) + : "memory"); +} + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] addr Pointer to location + */ +__ALWAYS_STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr) +{ + __ASM volatile("sh %1, 0(%0)" ::"r"(addr), "r"((uint32_t)value) + : "memory"); +} + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] addr Pointer to location + */ +__ALWAYS_STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr) +{ + __ASM volatile("sw %1, 0(%0)" ::"r"(addr), "r"(value) + : "memory"); +} + +/*@}*/ /* end of group CSI_Core_InstructionInterface */ + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CSI_SIMD_intrinsics CSI SIMD Intrinsics + Access to dedicated SIMD instructions \n + Single Instruction Multiple Data (SIMD) extensions are provided to simplify development of application software. SIMD extensions increase the processing capability without materially increasing the power consumption. The SIMD extensions are completely transparent to the operating system (OS), allowing existing OS ports to be used. + + @{ +*/ + +/** + \brief Halfword packing instruction. Combines bits[15:0] of val1 with bits[31:16] + of val2 levitated with the val3. + \details Combine a halfword from one register with a halfword from another register. + The second argument can be left-shifted before extraction of the halfword. + \param [in] val1 first 16-bit operands + \param [in] val2 second 16-bit operands + \param [in] val3 value for left-shifting val2. Value range [0..31]. + \return the combination of halfwords. + \remark + res[15:0] = val1[15:0] \n + res[31:16] = val2[31:16] << val3 + */ +__ALWAYS_STATIC_INLINE uint32_t __PKHBT(uint32_t val1, uint32_t val2, uint32_t val3) +{ + return ((((int32_t)(val1) << 0) & (int32_t)0x0000FFFF) | (((int32_t)(val2) << val3) & (int32_t)0xFFFF0000)); +} + +/** + \brief Halfword packing instruction. Combines bits[31:16] of val1 with bits[15:0] + of val2 right-shifted with the val3. + \details Combine a halfword from one register with a halfword from another register. + The second argument can be right-shifted before extraction of the halfword. + \param [in] val1 first 16-bit operands + \param [in] val2 second 16-bit operands + \param [in] val3 value for right-shifting val2. Value range [1..32]. + \return the combination of halfwords. + \remark + res[15:0] = val2[15:0] >> val3 \n + res[31:16] = val1[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __PKHTB(uint32_t val1, uint32_t val2, uint32_t val3) +{ + return ((((int32_t)(val1) << 0) & (int32_t)0xFFFF0000) | (((int32_t)(val2) >> val3) & (int32_t)0x0000FFFF)); +} + +/** + \brief Dual 16-bit signed saturate. + \details This function saturates a signed value. + \param [in] x two signed 16-bit values to be saturated. + \param [in] y bit position for saturation, an integral constant expression in the range 1 to 16. + \return the sum of the absolute differences of the following bytes, added to the accumulation value:\n + the signed saturation of the low halfword in val1, saturated to the bit position specified in + val2 and returned in the low halfword of the return value.\n + the signed saturation of the high halfword in val1, saturated to the bit position specified in + val2 and returned in the high halfword of the return value. + */ +__ALWAYS_STATIC_INLINE uint32_t __SSAT16(int32_t x, const uint32_t y) +{ + int32_t r = 0, s = 0; + + r = __SSAT((((int32_t)x << 16) >> 16), y) & (int32_t)0x0000FFFF; + s = __SSAT((((int32_t)x) >> 16), y) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturate. + \details This function enables you to saturate two signed 16-bit values to a selected unsigned range. + \param [in] x two signed 16-bit values to be saturated. + \param [in] y bit position for saturation, an integral constant expression in the range 1 to 16. + \return the saturation of the two signed 16-bit values, as non-negative values: + the saturation of the low halfword in val1, saturated to the bit position specified in + val2 and returned in the low halfword of the return value.\n + the saturation of the high halfword in val1, saturated to the bit position specified in + val2 and returned in the high halfword of the return value. + */ +__ALWAYS_STATIC_INLINE uint32_t __USAT16(uint32_t x, const uint32_t y) +{ + int32_t r = 0, s = 0; + + r = __IUSAT(((x << 16) >> 16), y) & 0x0000FFFF; + s = __IUSAT(((x) >> 16), y) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Quad 8-bit saturating addition. + \details This function enables you to perform four 8-bit integer additions, + saturating the results to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the saturated addition of the first byte of each operand in the first byte of the return value.\n + the saturated addition of the second byte of each operand in the second byte of the return value.\n + the saturated addition of the third byte of each operand in the third byte of the return value.\n + the saturated addition of the fourth byte of each operand in the fourth byte of the return value.\n + The returned results are saturated to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1. + \remark + res[7:0] = val1[7:0] + val2[7:0] \n + res[15:8] = val1[15:8] + val2[15:8] \n + res[23:16] = val1[23:16] + val2[23:16] \n + res[31:24] = val1[31:24] + val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __QADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = __SSAT(((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((int32_t)x << 8) >> 24) + (((int32_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((int32_t)x) >> 24) + (((int32_t)y) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned saturating addition. + \details This function enables you to perform four unsigned 8-bit integer additions, + saturating the results to the 8-bit unsigned integer range 0 < x < 2^8 - 1. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the saturated addition of the first byte of each operand in the first byte of the return value.\n + the saturated addition of the second byte of each operand in the second byte of the return value.\n + the saturated addition of the third byte of each operand in the third byte of the return value.\n + the saturated addition of the fourth byte of each operand in the fourth byte of the return value.\n + The returned results are saturated to the 8-bit signed integer range 0 <= x <= 2^8 - 1. + \remark + res[7:0] = val1[7:0] + val2[7:0] \n + res[15:8] = val1[15:8] + val2[15:8] \n + res[23:16] = val1[23:16] + val2[23:16] \n + res[31:24] = val1[31:24] + val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __UQADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = __IUSAT((((x << 24) >> 24) + ((y << 24) >> 24)), 8) & 0x000000FF; + s = __IUSAT((((x << 16) >> 24) + ((y << 16) >> 24)), 8) & 0x000000FF; + t = __IUSAT((((x << 8) >> 24) + ((y << 8) >> 24)), 8) & 0x000000FF; + u = __IUSAT((((x) >> 24) + ((y) >> 24)), 8) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Quad 8-bit signed addition. + \details This function performs four 8-bit signed integer additions. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the addition of the first bytes from each operand, in the first byte of the return value.\n + the addition of the second bytes of each operand, in the second byte of the return value.\n + the addition of the third bytes of each operand, in the third byte of the return value.\n + the addition of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + res[7:0] = val1[7:0] + val2[7:0] \n + res[15:8] = val1[15:8] + val2[15:8] \n + res[23:16] = val1[23:16] + val2[23:16] \n + res[31:24] = val1[31:24] + val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __SADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = ((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)) & (int32_t)0x000000FF; + s = ((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)) & (int32_t)0x000000FF; + t = ((((int32_t)x << 8) >> 24) + (((int32_t)y << 8) >> 24)) & (int32_t)0x000000FF; + u = ((((int32_t)x) >> 24) + (((int32_t)y) >> 24)) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned addition. + \details This function performs four unsigned 8-bit integer additions. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the addition of the first bytes from each operand, in the first byte of the return value.\n + the addition of the second bytes of each operand, in the second byte of the return value.\n + the addition of the third bytes of each operand, in the third byte of the return value.\n + the addition of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + res[7:0] = val1[7:0] + val2[7:0] \n + res[15:8] = val1[15:8] + val2[15:8] \n + res[23:16] = val1[23:16] + val2[23:16] \n + res[31:24] = val1[31:24] + val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __UADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = (((x << 24) >> 24) + ((y << 24) >> 24)) & 0x000000FF; + s = (((x << 16) >> 24) + ((y << 16) >> 24)) & 0x000000FF; + t = (((x << 8) >> 24) + ((y << 8) >> 24)) & 0x000000FF; + u = (((x) >> 24) + ((y) >> 24)) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Quad 8-bit saturating subtract. + \details This function enables you to perform four 8-bit integer subtractions, + saturating the results to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the subtraction of the first byte of each operand in the first byte of the return value.\n + the subtraction of the second byte of each operand in the second byte of the return value.\n + the subtraction of the third byte of each operand in the third byte of the return value.\n + the subtraction of the fourth byte of each operand in the fourth byte of the return value.\n + The returned results are saturated to the 8-bit signed integer range -2^7 <= x <= 2^7 - 1. + \remark + res[7:0] = val1[7:0] - val2[7:0] \n + res[15:8] = val1[15:8] - val2[15:8] \n + res[23:16] = val1[23:16] - val2[23:16] \n + res[31:24] = val1[31:24] - val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __QSUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = __SSAT(((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((int32_t)x << 8) >> 24) - (((int32_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((int32_t)x) >> 24) - (((int32_t)y) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned saturating subtraction. + \details This function enables you to perform four unsigned 8-bit integer subtractions, + saturating the results to the 8-bit unsigned integer range 0 < x < 2^8 - 1. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the subtraction of the first byte of each operand in the first byte of the return value.\n + the subtraction of the second byte of each operand in the second byte of the return value.\n + the subtraction of the third byte of each operand in the third byte of the return value.\n + the subtraction of the fourth byte of each operand in the fourth byte of the return value.\n + The returned results are saturated to the 8-bit unsigned integer range 0 <= x <= 2^8 - 1. + \remark + res[7:0] = val1[7:0] - val2[7:0] \n + res[15:8] = val1[15:8] - val2[15:8] \n + res[23:16] = val1[23:16] - val2[23:16] \n + res[31:24] = val1[31:24] - val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __UQSUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = __IUSAT((((x << 24) >> 24) - ((y << 24) >> 24)), 8) & 0x000000FF; + s = __IUSAT((((x << 16) >> 24) - ((y << 16) >> 24)), 8) & 0x000000FF; + t = __IUSAT((((x << 8) >> 24) - ((y << 8) >> 24)), 8) & 0x000000FF; + u = __IUSAT((((x) >> 24) - ((y) >> 24)), 8) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Quad 8-bit signed subtraction. + \details This function enables you to perform four 8-bit signed integer subtractions. + \param [in] x first four 8-bit operands of each subtraction. + \param [in] y second four 8-bit operands of each subtraction. + \return the subtraction of the first bytes from each operand, in the first byte of the return value.\n + the subtraction of the second bytes of each operand, in the second byte of the return value.\n + the subtraction of the third bytes of each operand, in the third byte of the return value.\n + the subtraction of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + res[7:0] = val1[7:0] - val2[7:0] \n + res[15:8] = val1[15:8] - val2[15:8] \n + res[23:16] = val1[23:16] - val2[23:16] \n + res[31:24] = val1[31:24] - val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __SSUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = ((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)) & (int32_t)0x000000FF; + s = ((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)) & (int32_t)0x000000FF; + t = ((((int32_t)x << 8) >> 24) - (((int32_t)y << 8) >> 24)) & (int32_t)0x000000FF; + u = ((((int32_t)x) >> 24) - (((int32_t)y) >> 24)) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned subtract. + \details This function enables you to perform four 8-bit unsigned integer subtractions. + \param [in] x first four 8-bit operands of each subtraction. + \param [in] y second four 8-bit operands of each subtraction. + \return the subtraction of the first bytes from each operand, in the first byte of the return value.\n + the subtraction of the second bytes of each operand, in the second byte of the return value.\n + the subtraction of the third bytes of each operand, in the third byte of the return value.\n + the subtraction of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + res[7:0] = val1[7:0] - val2[7:0] \n + res[15:8] = val1[15:8] - val2[15:8] \n + res[23:16] = val1[23:16] - val2[23:16] \n + res[31:24] = val1[31:24] - val2[31:24] + */ +__ALWAYS_STATIC_INLINE uint32_t __USUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = (((x << 24) >> 24) - ((y << 24) >> 24)) & 0x000000FF; + s = (((x << 16) >> 24) - ((y << 16) >> 24)) & 0x000000FF; + t = (((x << 8) >> 24) - ((y << 8) >> 24)) & 0x000000FF; + u = (((x) >> 24) - ((y) >> 24)) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Unsigned sum of quad 8-bit unsigned absolute difference. + \details This function enables you to perform four unsigned 8-bit subtractions, and add the absolute values + of the differences together, returning the result as a single unsigned integer. + \param [in] x first four 8-bit operands of each subtraction. + \param [in] y second four 8-bit operands of each subtraction. + \return the subtraction of the first bytes from each operand, in the first byte of the return value.\n + the subtraction of the second bytes of each operand, in the second byte of the return value.\n + the subtraction of the third bytes of each operand, in the third byte of the return value.\n + the subtraction of the fourth bytes of each operand, in the fourth byte of the return value.\n + The sum is returned as a single unsigned integer. + \remark + absdiff1 = val1[7:0] - val2[7:0] \n + absdiff2 = val1[15:8] - val2[15:8] \n + absdiff3 = val1[23:16] - val2[23:16] \n + absdiff4 = val1[31:24] - val2[31:24] \n + res[31:0] = absdiff1 + absdiff2 + absdiff3 + absdiff4 + */ +__ALWAYS_STATIC_INLINE uint32_t __USAD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = (((x << 24) >> 24) - ((y << 24) >> 24)) & 0x000000FF; + s = (((x << 16) >> 24) - ((y << 16) >> 24)) & 0x000000FF; + t = (((x << 8) >> 24) - ((y << 8) >> 24)) & 0x000000FF; + u = (((x) >> 24) - ((y) >> 24)) & 0x000000FF; + + return (u + t + s + r); +} + +/** + \brief Unsigned sum of quad 8-bit unsigned absolute difference with 32-bit accumulate. + \details This function enables you to perform four unsigned 8-bit subtractions, and add the absolute values + of the differences to a 32-bit accumulate operand. + \param [in] x first four 8-bit operands of each subtraction. + \param [in] y second four 8-bit operands of each subtraction. + \param [in] sum accumulation value. + \return the sum of the absolute differences of the following bytes, added to the accumulation value: + the subtraction of the first bytes from each operand, in the first byte of the return value.\n + the subtraction of the second bytes of each operand, in the second byte of the return value.\n + the subtraction of the third bytes of each operand, in the third byte of the return value.\n + the subtraction of the fourth bytes of each operand, in the fourth byte of the return value. + \remark + absdiff1 = val1[7:0] - val2[7:0] \n + absdiff2 = val1[15:8] - val2[15:8] \n + absdiff3 = val1[23:16] - val2[23:16] \n + absdiff4 = val1[31:24] - val2[31:24] \n + sum = absdiff1 + absdiff2 + absdiff3 + absdiff4 \n + res[31:0] = sum[31:0] + val3[31:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __USADA8(uint32_t x, uint32_t y, uint32_t sum) +{ + int32_t r, s, t, u; + +#ifdef __cplusplus + r = (abs((long long)((x << 24) >> 24) - ((y << 24) >> 24))) & 0x000000FF; + s = (abs((long long)((x << 16) >> 24) - ((y << 16) >> 24))) & 0x000000FF; + t = (abs((long long)((x << 8) >> 24) - ((y << 8) >> 24))) & 0x000000FF; + u = (abs((long long)((x) >> 24) - ((y) >> 24))) & 0x000000FF; +#else + r = (abs((int32_t)(((x << 24) >> 24) - ((y << 24) >> 24)))) & 0x000000FF; + s = (abs((int32_t)(((x << 16) >> 24) - ((y << 16) >> 24)))) & 0x000000FF; + t = (abs((int32_t)(((x << 8) >> 24) - ((y << 8) >> 24)))) & 0x000000FF; + u = (abs((int32_t)(((x) >> 24) - ((y) >> 24)))) & 0x000000FF; +#endif + return (u + t + s + r + sum); +} + +/** + \brief Dual 16-bit saturating addition. + \details This function enables you to perform two 16-bit integer arithmetic additions in parallel, + saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the saturated addition of the low halfwords, in the low halfword of the return value.\n + the saturated addition of the high halfwords, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] + val2[15:0] \n + res[31:16] = val1[31:16] + val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __QADD16(uint32_t x, uint32_t y) +{ + int32_t r = 0, s = 0; + + r = __SSAT(((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((int32_t)x) >> 16) + (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturating addition. + \details This function enables you to perform two unsigned 16-bit integer additions, saturating + the results to the 16-bit unsigned integer range 0 < x < 2^16 - 1. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the saturated addition of the low halfwords, in the low halfword of the return value.\n + the saturated addition of the high halfwords, in the high halfword of the return value.\n + The results are saturated to the 16-bit unsigned integer range 0 < x < 2^16 - 1. + \remark + res[15:0] = val1[15:0] + val2[15:0] \n + res[31:16] = val1[31:16] + val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __UQADD16(uint32_t x, uint32_t y) +{ + int32_t r = 0, s = 0; + + r = __IUSAT((((x << 16) >> 16) + ((y << 16) >> 16)), 16) & 0x0000FFFF; + s = __IUSAT((((x) >> 16) + ((y) >> 16)), 16) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed addition. + \details This function enables you to perform two 16-bit signed integer additions. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the addition of the low halfwords in the low halfword of the return value.\n + the addition of the high halfwords in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] + val2[15:0] \n + res[31:16] = val1[31:16] + val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __SADD16(uint32_t x, uint32_t y) +{ + int32_t r = 0, s = 0; + + r = ((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF; + s = ((((int32_t)x) >> 16) + (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned addition + \details This function enables you to perform two 16-bit unsigned integer additions. + \param [in] x first two 16-bit summands for each addition. + \param [in] y second two 16-bit summands for each addition. + \return the addition of the low halfwords in the low halfword of the return value.\n + the addition of the high halfwords in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] + val2[15:0] \n + res[31:16] = val1[31:16] + val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __UADD16(uint32_t x, uint32_t y) +{ + int32_t r = 0, s = 0; + + r = (((x << 16) >> 16) + ((y << 16) >> 16)) & 0x0000FFFF; + s = (((x) >> 16) + ((y) >> 16)) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed addition with halved results. + \details This function enables you to perform two signed 16-bit integer additions, halving the results. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the halved addition of the low halfwords, in the low halfword of the return value.\n + the halved addition of the high halfwords, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] + val2[15:0]) >> 1 \n + res[31:16] = (val1[31:16] + val2[31:16]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __SHADD16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((((int32_t)x << 16) >> 16) + (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((int32_t)x) >> 16) + (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned addition with halved results. + \details This function enables you to perform two unsigned 16-bit integer additions, halving the results. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the halved addition of the low halfwords, in the low halfword of the return value.\n + the halved addition of the high halfwords, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] + val2[15:0]) >> 1 \n + res[31:16] = (val1[31:16] + val2[31:16]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __UHADD16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((x << 16) >> 16) + ((y << 16) >> 16)) >> 1) & 0x0000FFFF; + s = ((((x) >> 16) + ((y) >> 16)) >> 1) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Quad 8-bit signed addition with halved results. + \details This function enables you to perform four signed 8-bit integer additions, halving the results. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the halved addition of the first bytes from each operand, in the first byte of the return value.\n + the halved addition of the second bytes from each operand, in the second byte of the return value.\n + the halved addition of the third bytes from each operand, in the third byte of the return value.\n + the halved addition of the fourth bytes from each operand, in the fourth byte of the return value. + \remark + res[7:0] = (val1[7:0] + val2[7:0] ) >> 1 \n + res[15:8] = (val1[15:8] + val2[15:8] ) >> 1 \n + res[23:16] = (val1[23:16] + val2[23:16]) >> 1 \n + res[31:24] = (val1[31:24] + val2[31:24]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __SHADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = (((((int32_t)x << 24) >> 24) + (((int32_t)y << 24) >> 24)) >> 1) & (int32_t)0x000000FF; + s = (((((int32_t)x << 16) >> 24) + (((int32_t)y << 16) >> 24)) >> 1) & (int32_t)0x000000FF; + t = (((((int32_t)x << 8) >> 24) + (((int32_t)y << 8) >> 24)) >> 1) & (int32_t)0x000000FF; + u = (((((int32_t)x) >> 24) + (((int32_t)y) >> 24)) >> 1) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned addition with halved results. + \details This function enables you to perform four unsigned 8-bit integer additions, halving the results. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the halved addition of the first bytes from each operand, in the first byte of the return value.\n + the halved addition of the second bytes from each operand, in the second byte of the return value.\n + the halved addition of the third bytes from each operand, in the third byte of the return value.\n + the halved addition of the fourth bytes from each operand, in the fourth byte of the return value. + \remark + res[7:0] = (val1[7:0] + val2[7:0] ) >> 1 \n + res[15:8] = (val1[15:8] + val2[15:8] ) >> 1 \n + res[23:16] = (val1[23:16] + val2[23:16]) >> 1 \n + res[31:24] = (val1[31:24] + val2[31:24]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __UHADD8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = ((((x << 24) >> 24) + ((y << 24) >> 24)) >> 1) & 0x000000FF; + s = ((((x << 16) >> 24) + ((y << 16) >> 24)) >> 1) & 0x000000FF; + t = ((((x << 8) >> 24) + ((y << 8) >> 24)) >> 1) & 0x000000FF; + u = ((((x) >> 24) + ((y) >> 24)) >> 1) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Dual 16-bit saturating subtract. + \details This function enables you to perform two 16-bit integer subtractions in parallel, + saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the saturated subtraction of the low halfwords, in the low halfword of the return value.\n + the saturated subtraction of the high halfwords, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] - val2[15:0] \n + res[31:16] = val1[31:16] - val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __QSUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __SSAT(((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((int32_t)x) >> 16) - (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturating subtraction. + \details This function enables you to perform two unsigned 16-bit integer subtractions, + saturating the results to the 16-bit unsigned integer range 0 < x < 2^16 - 1. + \param [in] x first two 16-bit operands for each subtraction. + \param [in] y second two 16-bit operands for each subtraction. + \return the saturated subtraction of the low halfwords, in the low halfword of the return value.\n + the saturated subtraction of the high halfwords, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] - val2[15:0] \n + res[31:16] = val1[31:16] - val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __UQSUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __IUSAT((((x << 16) >> 16) - ((y << 16) >> 16)), 16) & 0x0000FFFF; + s = __IUSAT((((x) >> 16) - ((y) >> 16)), 16) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed subtraction. + \details This function enables you to perform two 16-bit signed integer subtractions. + \param [in] x first two 16-bit operands of each subtraction. + \param [in] y second two 16-bit operands of each subtraction. + \return the subtraction of the low halfword in the second operand from the low + halfword in the first operand, in the low halfword of the return value. \n + the subtraction of the high halfword in the second operand from the high + halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] - val2[15:0] \n + res[31:16] = val1[31:16] - val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __SSUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF; + s = ((((int32_t)x) >> 16) - (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned subtract. + \details This function enables you to perform two 16-bit unsigned integer subtractions. + \param [in] x first two 16-bit operands of each subtraction. + \param [in] y second two 16-bit operands of each subtraction. + \return the subtraction of the low halfword in the second operand from the low + halfword in the first operand, in the low halfword of the return value. \n + the subtraction of the high halfword in the second operand from the high + halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] - val2[15:0] \n + res[31:16] = val1[31:16] - val2[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __USUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((x << 16) >> 16) - ((y << 16) >> 16)) & 0x0000FFFF; + s = (((x) >> 16) - ((y) >> 16)) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed subtraction with halved results. + \details This function enables you to perform two signed 16-bit integer subtractions, halving the results. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the halved subtraction of the low halfwords, in the low halfword of the return value.\n + the halved subtraction of the high halfwords, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] - val2[15:0]) >> 1 \n + res[31:16] = (val1[31:16] - val2[31:16]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __SHSUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((((int32_t)x << 16) >> 16) - (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((int32_t)x) >> 16) - (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned subtraction with halved results. + \details This function enables you to perform two unsigned 16-bit integer subtractions, halving the results. + \param [in] x first two 16-bit summands. + \param [in] y second two 16-bit summands. + \return the halved subtraction of the low halfwords, in the low halfword of the return value.\n + the halved subtraction of the high halfwords, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] - val2[15:0]) >> 1 \n + res[31:16] = (val1[31:16] - val2[31:16]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __UHSUB16(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((x << 16) >> 16) - ((y << 16) >> 16)) >> 1) & 0x0000FFFF; + s = ((((x) >> 16) - ((y) >> 16)) >> 1) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Quad 8-bit signed addition with halved results. + \details This function enables you to perform four signed 8-bit integer subtractions, halving the results. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the halved subtraction of the first bytes from each operand, in the first byte of the return value.\n + the halved subtraction of the second bytes from each operand, in the second byte of the return value.\n + the halved subtraction of the third bytes from each operand, in the third byte of the return value.\n + the halved subtraction of the fourth bytes from each operand, in the fourth byte of the return value. + \remark + res[7:0] = (val1[7:0] - val2[7:0] ) >> 1 \n + res[15:8] = (val1[15:8] - val2[15:8] ) >> 1 \n + res[23:16] = (val1[23:16] - val2[23:16]) >> 1 \n + res[31:24] = (val1[31:24] - val2[31:24]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __SHSUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = (((((int32_t)x << 24) >> 24) - (((int32_t)y << 24) >> 24)) >> 1) & (int32_t)0x000000FF; + s = (((((int32_t)x << 16) >> 24) - (((int32_t)y << 16) >> 24)) >> 1) & (int32_t)0x000000FF; + t = (((((int32_t)x << 8) >> 24) - (((int32_t)y << 8) >> 24)) >> 1) & (int32_t)0x000000FF; + u = (((((int32_t)x) >> 24) - (((int32_t)y) >> 24)) >> 1) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r))); +} + +/** + \brief Quad 8-bit unsigned subtraction with halved results. + \details This function enables you to perform four unsigned 8-bit integer subtractions, halving the results. + \param [in] x first four 8-bit summands. + \param [in] y second four 8-bit summands. + \return the halved subtraction of the first bytes from each operand, in the first byte of the return value.\n + the halved subtraction of the second bytes from each operand, in the second byte of the return value.\n + the halved subtraction of the third bytes from each operand, in the third byte of the return value.\n + the halved subtraction of the fourth bytes from each operand, in the fourth byte of the return value. + \remark + res[7:0] = (val1[7:0] - val2[7:0] ) >> 1 \n + res[15:8] = (val1[15:8] - val2[15:8] ) >> 1 \n + res[23:16] = (val1[23:16] - val2[23:16]) >> 1 \n + res[31:24] = (val1[31:24] - val2[31:24]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __UHSUB8(uint32_t x, uint32_t y) +{ + int32_t r, s, t, u; + + r = ((((x << 24) >> 24) - ((y << 24) >> 24)) >> 1) & 0x000000FF; + s = ((((x << 16) >> 24) - ((y << 16) >> 24)) >> 1) & 0x000000FF; + t = ((((x << 8) >> 24) - ((y << 8) >> 24)) >> 1) & 0x000000FF; + u = ((((x) >> 24) - ((y) >> 24)) >> 1) & 0x000000FF; + + return ((u << 24) | (t << 16) | (s << 8) | (r)); +} + +/** + \brief Dual 16-bit add and subtract with exchange. + \details This function enables you to exchange the halfwords of the one operand, + then add the high halfwords and subtract the low halfwords, + saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \param [in] x first operand for the subtraction in the low halfword, + and the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, + and the second operand for the addition in the low halfword. + \return the saturated subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the saturated addition of the high halfword in the first operand and the + low halfword in the second operand, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] - val2[31:16] \n + res[31:16] = val1[31:16] + val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __QASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __SSAT(((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturating addition and subtraction with exchange. + \details This function enables you to exchange the halfwords of the second operand and + perform one unsigned 16-bit integer addition and one unsigned 16-bit subtraction, + saturating the results to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1. + \param [in] x first operand for the subtraction in the low halfword, + and the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, + and the second operand for the addition in the low halfword. + \return the saturated subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the saturated addition of the high halfword in the first operand and the + low halfword in the second operand, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1. + \remark + res[15:0] = val1[15:0] - val2[31:16] \n + res[31:16] = val1[31:16] + val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __UQASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __IUSAT((((x << 16) >> 16) - ((y) >> 16)), 16) & 0x0000FFFF; + s = __IUSAT((((x) >> 16) + ((y << 16) >> 16)), 16) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit addition and subtraction with exchange. + \details It enables you to exchange the halfwords of the second operand, add the high halfwords + and subtract the low halfwords. + \param [in] x first operand for the subtraction in the low halfword, + and the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, + and the second operand for the addition in the low halfword. + \return the subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the addition of the high halfword in the first operand and the + low halfword in the second operand, in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] - val2[31:16] \n + res[31:16] = val1[31:16] + val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __SASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF; + s = ((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned addition and subtraction with exchange. + \details This function enables you to exchange the two halfwords of the second operand, + add the high halfwords and subtract the low halfwords. + \param [in] x first operand for the subtraction in the low halfword, + and the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, + and the second operand for the addition in the low halfword. + \return the subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the addition of the high halfword in the first operand and the + low halfword in the second operand, in the high halfword of the return value. + \remark + res[15:0] = val1[15:0] - val2[31:16] \n + res[31:16] = val1[31:16] + val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __UASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((x << 16) >> 16) - ((y) >> 16)) & 0x0000FFFF; + s = (((x) >> 16) + ((y << 16) >> 16)) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed addition and subtraction with halved results. + \details This function enables you to exchange the two halfwords of one operand, perform one + signed 16-bit integer addition and one signed 16-bit subtraction, and halve the results. + \param [in] x first 16-bit operands. + \param [in] y second 16-bit operands. + \return the halved subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the halved addition of the low halfword in the second operand from the high + halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] - val2[31:16]) >> 1 \n + res[31:16] = (val1[31:16] + val2[15:0]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __SHASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((((int32_t)x << 16) >> 16) - (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((int32_t)x) >> 16) + (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned addition and subtraction with halved results and exchange. + \details This function enables you to exchange the halfwords of the second operand, + add the high halfwords and subtract the low halfwords, halving the results. + \param [in] x first operand for the subtraction in the low halfword, and + the first operand for the addition in the high halfword. + \param [in] y second operand for the subtraction in the high halfword, and + the second operand for the addition in the low halfword. + \return the halved subtraction of the high halfword in the second operand from the + low halfword in the first operand, in the low halfword of the return value.\n + the halved addition of the low halfword in the second operand from the high + halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] - val2[31:16]) >> 1 \n + res[31:16] = (val1[31:16] + val2[15:0]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __UHASX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((x << 16) >> 16) - ((y) >> 16)) >> 1) & 0x0000FFFF; + s = ((((x) >> 16) + ((y << 16) >> 16)) >> 1) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit subtract and add with exchange. + \details This function enables you to exchange the halfwords of one operand, + then subtract the high halfwords and add the low halfwords, + saturating the results to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \param [in] x first operand for the addition in the low halfword, + and the first operand for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, + and the second operand for the subtraction in the low halfword. + \return the saturated addition of the low halfword of the first operand and the high + halfword of the second operand, in the low halfword of the return value.\n + the saturated subtraction of the low halfword of the second operand from the + high halfword of the first operand, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit signed integer range -2^15 <= x <= 2^15 - 1. + \remark + res[15:0] = val1[15:0] + val2[31:16] \n + res[31:16] = val1[31:16] - val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __QSAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __SSAT(((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned saturating subtraction and addition with exchange. + \details This function enables you to exchange the halfwords of the second operand and perform + one unsigned 16-bit integer subtraction and one unsigned 16-bit addition, saturating + the results to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1. + \param [in] x first operand for the addition in the low halfword, + and the first operand for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, + and the second operand for the subtraction in the low halfword. + \return the saturated addition of the low halfword of the first operand and the high + halfword of the second operand, in the low halfword of the return value.\n + the saturated subtraction of the low halfword of the second operand from the + high halfword of the first operand, in the high halfword of the return value.\n + The returned results are saturated to the 16-bit unsigned integer range 0 <= x <= 2^16 - 1. + \remark + res[15:0] = val1[15:0] + val2[31:16] \n + res[31:16] = val1[31:16] - val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __UQSAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = __IUSAT((((x << 16) >> 16) + ((y) >> 16)), 16) & 0x0000FFFF; + s = __IUSAT((((x) >> 16) - ((y << 16) >> 16)), 16) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit unsigned subtract and add with exchange. + \details This function enables you to exchange the halfwords of the second operand, + subtract the high halfwords and add the low halfwords. + \param [in] x first operand for the addition in the low halfword, + and the first operand for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, + and the second operand for the subtraction in the low halfword. + \return the addition of the low halfword of the first operand and the high + halfword of the second operand, in the low halfword of the return value.\n + the subtraction of the low halfword of the second operand from the + high halfword of the first operand, in the high halfword of the return value.\n + \remark + res[15:0] = val1[15:0] + val2[31:16] \n + res[31:16] = val1[31:16] - val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __USAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((x << 16) >> 16) + ((y) >> 16)) & 0x0000FFFF; + s = (((x) >> 16) - ((y << 16) >> 16)) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed subtraction and addition with exchange. + \details This function enables you to exchange the two halfwords of one operand and perform one + 16-bit integer subtraction and one 16-bit addition. + \param [in] x first operand for the addition in the low halfword, and the first operand + for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, and the second + operand for the subtraction in the low halfword. + \return the addition of the low halfword of the first operand and the high + halfword of the second operand, in the low halfword of the return value.\n + the subtraction of the low halfword of the second operand from the + high halfword of the first operand, in the high halfword of the return value.\n + \remark + res[15:0] = val1[15:0] + val2[31:16] \n + res[31:16] = val1[31:16] - val2[15:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __SSAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)) & (int32_t)0x0000FFFF; + s = ((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit signed subtraction and addition with halved results. + \details This function enables you to exchange the two halfwords of one operand, perform one signed + 16-bit integer subtraction and one signed 16-bit addition, and halve the results. + \param [in] x first 16-bit operands. + \param [in] y second 16-bit operands. + \return the halved addition of the low halfword in the first operand and the + high halfword in the second operand, in the low halfword of the return value.\n + the halved subtraction of the low halfword in the second operand from the + high halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] + val2[31:16]) >> 1 \n + res[31:16] = (val1[31:16] - val2[15:0]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __SHSAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = (((((int32_t)x << 16) >> 16) + (((int32_t)y) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((int32_t)x) >> 16) - (((int32_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r))); +} + +/** + \brief Dual 16-bit unsigned subtraction and addition with halved results and exchange. + \details This function enables you to exchange the halfwords of the second operand, + subtract the high halfwords and add the low halfwords, halving the results. + \param [in] x first operand for the addition in the low halfword, and + the first operand for the subtraction in the high halfword. + \param [in] y second operand for the addition in the high halfword, and + the second operand for the subtraction in the low halfword. + \return the halved addition of the low halfword in the first operand and the + high halfword in the second operand, in the low halfword of the return value.\n + the halved subtraction of the low halfword in the second operand from the + high halfword in the first operand, in the high halfword of the return value. + \remark + res[15:0] = (val1[15:0] + val2[31:16]) >> 1 \n + res[31:16] = (val1[31:16] - val2[15:0]) >> 1 + */ +__ALWAYS_STATIC_INLINE uint32_t __UHSAX(uint32_t x, uint32_t y) +{ + int32_t r, s; + + r = ((((x << 16) >> 16) + ((y) >> 16)) >> 1) & 0x0000FFFF; + s = ((((x) >> 16) - ((y << 16) >> 16)) >> 1) & 0x0000FFFF; + + return ((s << 16) | (r)); +} + +/** + \brief Dual 16-bit signed multiply with exchange returning difference. + \details This function enables you to perform two 16-bit signed multiplications, subtracting + one of the products from the other. The halfwords of the second operand are exchanged + before performing the arithmetic. This produces top * bottom and bottom * top multiplication. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \return the difference of the products of the two 16-bit signed multiplications. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[31:0] = p1 - p2 + */ +__ALWAYS_STATIC_INLINE uint32_t __SMUSDX(uint32_t x, uint32_t y) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)))); +} + +/** + \brief Sum of dual 16-bit signed multiply with exchange. + \details This function enables you to perform two 16-bit signed multiplications with exchanged + halfwords of the second operand, adding the products together. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \return the sum of the products of the two 16-bit signed multiplications with exchanged halfwords of the second operand. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[31:0] = p1 + p2 + */ +__ALWAYS_STATIC_INLINE uint32_t __SMUADX(uint32_t x, uint32_t y) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)))); +} + +/** + \brief Saturating add. + \details This function enables you to obtain the saturating add of two integers. + \param [in] x first summand of the saturating add operation. + \param [in] y second summand of the saturating add operation. + \return the saturating addition of val1 and val2. + \remark + res[31:0] = SAT(val1 + SAT(val2)) + */ +__ALWAYS_STATIC_INLINE int32_t __QADD(int32_t x, int32_t y) +{ + int32_t result; + + if (y >= 0) { + if ((int32_t)((uint32_t)x + (uint32_t)y) >= x) { + result = x + y; + } else { + result = 0x7FFFFFFF; + } + } else { + if ((int32_t)((uint32_t)x + (uint32_t)y) < x) { + result = x + y; + } else { + result = 0x80000000; + } + } + + return result; +} + +/** + \brief Saturating subtract. + \details This function enables you to obtain the saturating add of two integers. + \param [in] x first summand of the saturating add operation. + \param [in] y second summand of the saturating add operation. + \return the saturating addition of val1 and val2. + \remark + res[31:0] = SAT(val1 - SAT(val2)) + */ +__ALWAYS_STATIC_INLINE int32_t __QSUB(int32_t x, int32_t y) +{ + int64_t tmp; + int32_t result; + + tmp = (int64_t)x - (int64_t)y; + + if (tmp > 0x7fffffff) { + tmp = 0x7fffffff; + } else if (tmp < (-2147483647 - 1)) { + tmp = -2147483647 - 1; + } + + result = tmp; + return result; +} + +/** + \brief Dual 16-bit signed multiply with single 32-bit accumulator. + \details This function enables you to perform two signed 16-bit multiplications, + adding both results to a 32-bit accumulate operand. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the product of each multiplication added to the accumulate value, as a 32-bit integer. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[31:0] = p1 + p2 + val3[31:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __SMLAD(uint32_t x, uint32_t y, uint32_t sum) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) + + (((int32_t)sum)))); +} + +/** + \brief Pre-exchanged dual 16-bit signed multiply with single 32-bit accumulator. + \details This function enables you to perform two signed 16-bit multiplications with exchanged + halfwords of the second operand, adding both results to a 32-bit accumulate operand. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the product of each multiplication with exchanged halfwords of the second + operand added to the accumulate value, as a 32-bit integer. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[31:0] = p1 + p2 + val3[31:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __SMLADX(uint32_t x, uint32_t y, uint32_t sum) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) + + (((int32_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with exchange subtract with 32-bit accumulate. + \details This function enables you to perform two 16-bit signed multiplications, take the + difference of the products, subtracting the high halfword product from the low + halfword product, and add the difference to a 32-bit accumulate operand. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the difference of the product of each multiplication, added to the accumulate value. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[31:0] = p1 - p2 + val3[31:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __SMLSD(uint32_t x, uint32_t y, uint32_t sum) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) + + (((int32_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with exchange subtract with 32-bit accumulate. + \details This function enables you to exchange the halfwords in the second operand, then perform two 16-bit + signed multiplications. The difference of the products is added to a 32-bit accumulate operand. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the difference of the product of each multiplication, added to the accumulate value. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[31:0] = p1 - p2 + val3[31:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __SMLSDX(uint32_t x, uint32_t y, uint32_t sum) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) + + (((int32_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with single 64-bit accumulator. + \details This function enables you to perform two signed 16-bit multiplications, adding both results + to a 64-bit accumulate operand. Overflow is only possible as a result of the 64-bit addition. + This overflow is not detected if it occurs. Instead, the result wraps around modulo2^64. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the product of each multiplication added to the accumulate value. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + sum = p1 + p2 + val3[63:32][31:0] \n + res[63:32] = sum[63:32] \n + res[31:0] = sum[31:0] + */ +__ALWAYS_STATIC_INLINE uint64_t __SMLALD(uint32_t x, uint32_t y, uint64_t sum) +{ + return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) + + (((uint64_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with exchange with single 64-bit accumulator. + \details This function enables you to exchange the halfwords of the second operand, and perform two + signed 16-bit multiplications, adding both results to a 64-bit accumulate operand. Overflow + is only possible as a result of the 64-bit addition. This overflow is not detected if it occurs. + Instead, the result wraps around modulo2^64. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the product of each multiplication added to the accumulate value. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + sum = p1 + p2 + val3[63:32][31:0] \n + res[63:32] = sum[63:32] \n + res[31:0] = sum[31:0] + */ +__ALWAYS_STATIC_INLINE uint64_t __SMLALDX(uint32_t x, uint32_t y, uint64_t sum) +{ + return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) + + (((uint64_t)sum)))); +} + +/** + \brief dual 16-bit signed multiply subtract with 64-bit accumulate. + \details This function It enables you to perform two 16-bit signed multiplications, take the difference + of the products, subtracting the high halfword product from the low halfword product, and add the + difference to a 64-bit accumulate operand. Overflow cannot occur during the multiplications or the + subtraction. Overflow can occur as a result of the 64-bit addition, and this overflow is not + detected. Instead, the result wraps round to modulo2^64. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the difference of the product of each multiplication, added to the accumulate value. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[63:32][31:0] = p1 - p2 + val3[63:32][31:0] + */ +__ALWAYS_STATIC_INLINE uint64_t __SMLSLD(uint32_t x, uint32_t y, uint64_t sum) +{ + return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)) + + (((uint64_t)sum)))); +} + +/** + \brief Dual 16-bit signed multiply with exchange subtract with 64-bit accumulate. + \details This function enables you to exchange the halfwords of the second operand, perform two 16-bit multiplications, + adding the difference of the products to a 64-bit accumulate operand. Overflow cannot occur during the + multiplications or the subtraction. Overflow can occur as a result of the 64-bit addition, and this overflow + is not detected. Instead, the result wraps round to modulo2^64. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \param [in] sum accumulate value. + \return the difference of the product of each multiplication, added to the accumulate value. + \remark + p1 = val1[15:0] * val2[31:16] \n + p2 = val1[31:16] * val2[15:0] \n + res[63:32][31:0] = p1 - p2 + val3[63:32][31:0] + */ +__ALWAYS_STATIC_INLINE uint64_t __SMLSLDX(uint32_t x, uint32_t y, uint64_t sum) +{ + return ((uint64_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y << 16) >> 16)) + + (((uint64_t)sum)))); +} + +/** + \brief 32-bit signed multiply with 32-bit truncated accumulator. + \details This function enables you to perform a signed 32-bit multiplications, adding the most + significant 32 bits of the 64-bit result to a 32-bit accumulate operand. + \param [in] x first operand for multiplication. + \param [in] y second operand for multiplication. + \param [in] sum accumulate value. + \return the product of multiplication (most significant 32 bits) is added to the accumulate value, as a 32-bit integer. + \remark + p = val1 * val2 \n + res[31:0] = p[63:32] + val3[31:0] + */ +__ALWAYS_STATIC_INLINE uint32_t __SMMLA(int32_t x, int32_t y, int32_t sum) +{ + return (uint32_t)((int32_t)((int64_t)((int64_t)x * (int64_t)y) >> 32) + sum); +} + +/** + \brief Sum of dual 16-bit signed multiply. + \details This function enables you to perform two 16-bit signed multiplications, adding the products together. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \return the sum of the products of the two 16-bit signed multiplications. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[31:0] = p1 + p2 + */ +__ALWAYS_STATIC_INLINE uint32_t __SMUAD(uint32_t x, uint32_t y) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) + + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)))); +} + +/** + \brief Dual 16-bit signed multiply returning difference. + \details This function enables you to perform two 16-bit signed multiplications, taking the difference + of the products by subtracting the high halfword product from the low halfword product. + \param [in] x first 16-bit operands for each multiplication. + \param [in] y second 16-bit operands for each multiplication. + \return the difference of the products of the two 16-bit signed multiplications. + \remark + p1 = val1[15:0] * val2[15:0] \n + p2 = val1[31:16] * val2[31:16] \n + res[31:0] = p1 - p2 + */ +__ALWAYS_STATIC_INLINE uint32_t __SMUSD(uint32_t x, uint32_t y) +{ + return ((uint32_t)(((((int32_t)x << 16) >> 16) * (((int32_t)y << 16) >> 16)) - + ((((int32_t)x) >> 16) * (((int32_t)y) >> 16)))); +} + +/** + \brief Dual extracted 8-bit to 16-bit signed addition. + \details This function enables you to extract two 8-bit values from the second operand (at bit positions + [7:0] and [23:16]), sign-extend them to 16-bits each, and add the results to the first operand. + \param [in] x values added to the sign-extended to 16-bit values. + \param [in] y two 8-bit values to be extracted and sign-extended. + \return the addition of val1 and val2, where the 8-bit values in val2[7:0] and + val2[23:16] have been extracted and sign-extended prior to the addition. + \remark + res[15:0] = val1[15:0] + SignExtended(val2[7:0]) \n + res[31:16] = val1[31:16] + SignExtended(val2[23:16]) + */ +__ALWAYS_STATIC_INLINE uint32_t __SXTAB16(uint32_t x, uint32_t y) +{ + return ((uint32_t)((((((int32_t)y << 24) >> 24) + (((int32_t)x << 16) >> 16)) & (int32_t)0x0000FFFF) | + (((((int32_t)y << 8) >> 8) + (((int32_t)x >> 16) << 16)) & (int32_t)0xFFFF0000))); +} + +/** + \brief Extracted 16-bit to 32-bit unsigned addition. + \details This function enables you to extract two 8-bit values from one operand, zero-extend + them to 16 bits each, and add the results to two 16-bit values from another operand. + \param [in] x values added to the zero-extended to 16-bit values. + \param [in] y two 8-bit values to be extracted and zero-extended. + \return the addition of val1 and val2, where the 8-bit values in val2[7:0] and + val2[23:16] have been extracted and zero-extended prior to the addition. + \remark + res[15:0] = ZeroExt(val2[7:0] to 16 bits) + val1[15:0] \n + res[31:16] = ZeroExt(val2[31:16] to 16 bits) + val1[31:16] + */ +__ALWAYS_STATIC_INLINE uint32_t __UXTAB16(uint32_t x, uint32_t y) +{ + return ((uint32_t)(((((y << 24) >> 24) + ((x << 16) >> 16)) & 0x0000FFFF) | + ((((y << 8) >> 8) + ((x >> 16) << 16)) & 0xFFFF0000))); +} + +/** + \brief Dual extract 8-bits and sign extend each to 16-bits. + \details This function enables you to extract two 8-bit values from an operand and sign-extend them to 16 bits each. + \param [in] x two 8-bit values in val[7:0] and val[23:16] to be sign-extended. + \return the 8-bit values sign-extended to 16-bit values.\n + sign-extended value of val[7:0] in the low halfword of the return value.\n + sign-extended value of val[23:16] in the high halfword of the return value. + \remark + res[15:0] = SignExtended(val[7:0]) \n + res[31:16] = SignExtended(val[23:16]) + */ +__ALWAYS_STATIC_INLINE uint32_t __SXTB16(uint32_t x) +{ + return ((uint32_t)(((((int32_t)x << 24) >> 24) & (int32_t)0x0000FFFF) | + ((((int32_t)x << 8) >> 8) & (int32_t)0xFFFF0000))); +} + +/** + \brief Dual extract 8-bits and zero-extend to 16-bits. + \details This function enables you to extract two 8-bit values from an operand and zero-extend them to 16 bits each. + \param [in] x two 8-bit values in val[7:0] and val[23:16] to be zero-extended. + \return the 8-bit values sign-extended to 16-bit values.\n + sign-extended value of val[7:0] in the low halfword of the return value.\n + sign-extended value of val[23:16] in the high halfword of the return value. + \remark + res[15:0] = SignExtended(val[7:0]) \n + res[31:16] = SignExtended(val[23:16]) + */ +__ALWAYS_STATIC_INLINE uint32_t __UXTB16(uint32_t x) +{ + return ((uint32_t)((((x << 24) >> 24) & 0x0000FFFF) | + (((x << 8) >> 8) & 0xFFFF0000))); +} + +#endif /* _CSI_RV32_GCC_H_ */ diff --git a/platforms/bl808_m0/vendor/psram/include/ef_ctrl_reg.h b/platforms/bl808_m0/vendor/psram/include/ef_ctrl_reg.h new file mode 100644 index 0000000..515e14e --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/ef_ctrl_reg.h @@ -0,0 +1,942 @@ +/** + ****************************************************************************** + * @file ef_ctrl_reg.h + * @version V1.0 + * @date 2021-07-31 + * @brief This file is the description of.IP register + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __EF_CTRL_REG_H__ +#define __EF_CTRL_REG_H__ + +#include "bl808.h" + +/* 0x800 : ef_if_ctrl_0 */ +#define EF_CTRL_EF_IF_CTRL_0_OFFSET (0x800) +#define EF_CTRL_EF_IF_0_AUTOLOAD_P1_DONE EF_CTRL_EF_IF_0_AUTOLOAD_P1_DONE +#define EF_CTRL_EF_IF_0_AUTOLOAD_P1_DONE_POS (0U) +#define EF_CTRL_EF_IF_0_AUTOLOAD_P1_DONE_LEN (1U) +#define EF_CTRL_EF_IF_0_AUTOLOAD_P1_DONE_MSK (((1U << EF_CTRL_EF_IF_0_AUTOLOAD_P1_DONE_LEN) - 1) << EF_CTRL_EF_IF_0_AUTOLOAD_P1_DONE_POS) +#define EF_CTRL_EF_IF_0_AUTOLOAD_P1_DONE_UMSK (~(((1U << EF_CTRL_EF_IF_0_AUTOLOAD_P1_DONE_LEN) - 1) << EF_CTRL_EF_IF_0_AUTOLOAD_P1_DONE_POS)) +#define EF_CTRL_EF_IF_0_AUTOLOAD_DONE EF_CTRL_EF_IF_0_AUTOLOAD_DONE +#define EF_CTRL_EF_IF_0_AUTOLOAD_DONE_POS (1U) +#define EF_CTRL_EF_IF_0_AUTOLOAD_DONE_LEN (1U) +#define EF_CTRL_EF_IF_0_AUTOLOAD_DONE_MSK (((1U << EF_CTRL_EF_IF_0_AUTOLOAD_DONE_LEN) - 1) << EF_CTRL_EF_IF_0_AUTOLOAD_DONE_POS) +#define EF_CTRL_EF_IF_0_AUTOLOAD_DONE_UMSK (~(((1U << EF_CTRL_EF_IF_0_AUTOLOAD_DONE_LEN) - 1) << EF_CTRL_EF_IF_0_AUTOLOAD_DONE_POS)) +#define EF_CTRL_EF_IF_0_BUSY EF_CTRL_EF_IF_0_BUSY +#define EF_CTRL_EF_IF_0_BUSY_POS (2U) +#define EF_CTRL_EF_IF_0_BUSY_LEN (1U) +#define EF_CTRL_EF_IF_0_BUSY_MSK (((1U << EF_CTRL_EF_IF_0_BUSY_LEN) - 1) << EF_CTRL_EF_IF_0_BUSY_POS) +#define EF_CTRL_EF_IF_0_BUSY_UMSK (~(((1U << EF_CTRL_EF_IF_0_BUSY_LEN) - 1) << EF_CTRL_EF_IF_0_BUSY_POS)) +#define EF_CTRL_EF_IF_0_RW EF_CTRL_EF_IF_0_RW +#define EF_CTRL_EF_IF_0_RW_POS (3U) +#define EF_CTRL_EF_IF_0_RW_LEN (1U) +#define EF_CTRL_EF_IF_0_RW_MSK (((1U << EF_CTRL_EF_IF_0_RW_LEN) - 1) << EF_CTRL_EF_IF_0_RW_POS) +#define EF_CTRL_EF_IF_0_RW_UMSK (~(((1U << EF_CTRL_EF_IF_0_RW_LEN) - 1) << EF_CTRL_EF_IF_0_RW_POS)) +#define EF_CTRL_EF_IF_0_TRIG EF_CTRL_EF_IF_0_TRIG +#define EF_CTRL_EF_IF_0_TRIG_POS (4U) +#define EF_CTRL_EF_IF_0_TRIG_LEN (1U) +#define EF_CTRL_EF_IF_0_TRIG_MSK (((1U << EF_CTRL_EF_IF_0_TRIG_LEN) - 1) << EF_CTRL_EF_IF_0_TRIG_POS) +#define EF_CTRL_EF_IF_0_TRIG_UMSK (~(((1U << EF_CTRL_EF_IF_0_TRIG_LEN) - 1) << EF_CTRL_EF_IF_0_TRIG_POS)) +#define EF_CTRL_EF_IF_0_MANUAL_EN EF_CTRL_EF_IF_0_MANUAL_EN +#define EF_CTRL_EF_IF_0_MANUAL_EN_POS (5U) +#define EF_CTRL_EF_IF_0_MANUAL_EN_LEN (1U) +#define EF_CTRL_EF_IF_0_MANUAL_EN_MSK (((1U << EF_CTRL_EF_IF_0_MANUAL_EN_LEN) - 1) << EF_CTRL_EF_IF_0_MANUAL_EN_POS) +#define EF_CTRL_EF_IF_0_MANUAL_EN_UMSK (~(((1U << EF_CTRL_EF_IF_0_MANUAL_EN_LEN) - 1) << EF_CTRL_EF_IF_0_MANUAL_EN_POS)) +#define EF_CTRL_EF_IF_0_CYC_MODIFY EF_CTRL_EF_IF_0_CYC_MODIFY +#define EF_CTRL_EF_IF_0_CYC_MODIFY_POS (6U) +#define EF_CTRL_EF_IF_0_CYC_MODIFY_LEN (1U) +#define EF_CTRL_EF_IF_0_CYC_MODIFY_MSK (((1U << EF_CTRL_EF_IF_0_CYC_MODIFY_LEN) - 1) << EF_CTRL_EF_IF_0_CYC_MODIFY_POS) +#define EF_CTRL_EF_IF_0_CYC_MODIFY_UMSK (~(((1U << EF_CTRL_EF_IF_0_CYC_MODIFY_LEN) - 1) << EF_CTRL_EF_IF_0_CYC_MODIFY_POS)) +#define EF_CTRL_EF_IF_PROT_CODE_CTRL EF_CTRL_EF_IF_PROT_CODE_CTRL +#define EF_CTRL_EF_IF_PROT_CODE_CTRL_POS (8U) +#define EF_CTRL_EF_IF_PROT_CODE_CTRL_LEN (8U) +#define EF_CTRL_EF_IF_PROT_CODE_CTRL_MSK (((1U << EF_CTRL_EF_IF_PROT_CODE_CTRL_LEN) - 1) << EF_CTRL_EF_IF_PROT_CODE_CTRL_POS) +#define EF_CTRL_EF_IF_PROT_CODE_CTRL_UMSK (~(((1U << EF_CTRL_EF_IF_PROT_CODE_CTRL_LEN) - 1) << EF_CTRL_EF_IF_PROT_CODE_CTRL_POS)) +#define EF_CTRL_EF_IF_POR_DIG EF_CTRL_EF_IF_POR_DIG +#define EF_CTRL_EF_IF_POR_DIG_POS (16U) +#define EF_CTRL_EF_IF_POR_DIG_LEN (1U) +#define EF_CTRL_EF_IF_POR_DIG_MSK (((1U << EF_CTRL_EF_IF_POR_DIG_LEN) - 1) << EF_CTRL_EF_IF_POR_DIG_POS) +#define EF_CTRL_EF_IF_POR_DIG_UMSK (~(((1U << EF_CTRL_EF_IF_POR_DIG_LEN) - 1) << EF_CTRL_EF_IF_POR_DIG_POS)) +#define EF_CTRL_EF_PCLK_FORCE_ON EF_CTRL_EF_PCLK_FORCE_ON +#define EF_CTRL_EF_PCLK_FORCE_ON_POS (17U) +#define EF_CTRL_EF_PCLK_FORCE_ON_LEN (1U) +#define EF_CTRL_EF_PCLK_FORCE_ON_MSK (((1U << EF_CTRL_EF_PCLK_FORCE_ON_LEN) - 1) << EF_CTRL_EF_PCLK_FORCE_ON_POS) +#define EF_CTRL_EF_PCLK_FORCE_ON_UMSK (~(((1U << EF_CTRL_EF_PCLK_FORCE_ON_LEN) - 1) << EF_CTRL_EF_PCLK_FORCE_ON_POS)) +#define EF_CTRL_EF_IF_AUTO_RD_EN EF_CTRL_EF_IF_AUTO_RD_EN +#define EF_CTRL_EF_IF_AUTO_RD_EN_POS (18U) +#define EF_CTRL_EF_IF_AUTO_RD_EN_LEN (1U) +#define EF_CTRL_EF_IF_AUTO_RD_EN_MSK (((1U << EF_CTRL_EF_IF_AUTO_RD_EN_LEN) - 1) << EF_CTRL_EF_IF_AUTO_RD_EN_POS) +#define EF_CTRL_EF_IF_AUTO_RD_EN_UMSK (~(((1U << EF_CTRL_EF_IF_AUTO_RD_EN_LEN) - 1) << EF_CTRL_EF_IF_AUTO_RD_EN_POS)) +#define EF_CTRL_EF_IF_CYC_MODIFY_LOCK EF_CTRL_EF_IF_CYC_MODIFY_LOCK +#define EF_CTRL_EF_IF_CYC_MODIFY_LOCK_POS (19U) +#define EF_CTRL_EF_IF_CYC_MODIFY_LOCK_LEN (1U) +#define EF_CTRL_EF_IF_CYC_MODIFY_LOCK_MSK (((1U << EF_CTRL_EF_IF_CYC_MODIFY_LOCK_LEN) - 1) << EF_CTRL_EF_IF_CYC_MODIFY_LOCK_POS) +#define EF_CTRL_EF_IF_CYC_MODIFY_LOCK_UMSK (~(((1U << EF_CTRL_EF_IF_CYC_MODIFY_LOCK_LEN) - 1) << EF_CTRL_EF_IF_CYC_MODIFY_LOCK_POS)) +#define EF_CTRL_EF_IF_0_INT EF_CTRL_EF_IF_0_INT +#define EF_CTRL_EF_IF_0_INT_POS (20U) +#define EF_CTRL_EF_IF_0_INT_LEN (1U) +#define EF_CTRL_EF_IF_0_INT_MSK (((1U << EF_CTRL_EF_IF_0_INT_LEN) - 1) << EF_CTRL_EF_IF_0_INT_POS) +#define EF_CTRL_EF_IF_0_INT_UMSK (~(((1U << EF_CTRL_EF_IF_0_INT_LEN) - 1) << EF_CTRL_EF_IF_0_INT_POS)) +#define EF_CTRL_EF_IF_0_INT_CLR EF_CTRL_EF_IF_0_INT_CLR +#define EF_CTRL_EF_IF_0_INT_CLR_POS (21U) +#define EF_CTRL_EF_IF_0_INT_CLR_LEN (1U) +#define EF_CTRL_EF_IF_0_INT_CLR_MSK (((1U << EF_CTRL_EF_IF_0_INT_CLR_LEN) - 1) << EF_CTRL_EF_IF_0_INT_CLR_POS) +#define EF_CTRL_EF_IF_0_INT_CLR_UMSK (~(((1U << EF_CTRL_EF_IF_0_INT_CLR_LEN) - 1) << EF_CTRL_EF_IF_0_INT_CLR_POS)) +#define EF_CTRL_EF_IF_0_INT_SET EF_CTRL_EF_IF_0_INT_SET +#define EF_CTRL_EF_IF_0_INT_SET_POS (22U) +#define EF_CTRL_EF_IF_0_INT_SET_LEN (1U) +#define EF_CTRL_EF_IF_0_INT_SET_MSK (((1U << EF_CTRL_EF_IF_0_INT_SET_LEN) - 1) << EF_CTRL_EF_IF_0_INT_SET_POS) +#define EF_CTRL_EF_IF_0_INT_SET_UMSK (~(((1U << EF_CTRL_EF_IF_0_INT_SET_LEN) - 1) << EF_CTRL_EF_IF_0_INT_SET_POS)) +#define EF_CTRL_EF_IF_PROT_CODE_CYC EF_CTRL_EF_IF_PROT_CODE_CYC +#define EF_CTRL_EF_IF_PROT_CODE_CYC_POS (24U) +#define EF_CTRL_EF_IF_PROT_CODE_CYC_LEN (8U) +#define EF_CTRL_EF_IF_PROT_CODE_CYC_MSK (((1U << EF_CTRL_EF_IF_PROT_CODE_CYC_LEN) - 1) << EF_CTRL_EF_IF_PROT_CODE_CYC_POS) +#define EF_CTRL_EF_IF_PROT_CODE_CYC_UMSK (~(((1U << EF_CTRL_EF_IF_PROT_CODE_CYC_LEN) - 1) << EF_CTRL_EF_IF_PROT_CODE_CYC_POS)) + +/* 0x804 : ef_if_cyc_0 */ +#define EF_CTRL_EF_IF_CYC_0_OFFSET (0x804) +#define EF_CTRL_EF_IF_CYC_RD_DMY EF_CTRL_EF_IF_CYC_RD_DMY +#define EF_CTRL_EF_IF_CYC_RD_DMY_POS (0U) +#define EF_CTRL_EF_IF_CYC_RD_DMY_LEN (6U) +#define EF_CTRL_EF_IF_CYC_RD_DMY_MSK (((1U << EF_CTRL_EF_IF_CYC_RD_DMY_LEN) - 1) << EF_CTRL_EF_IF_CYC_RD_DMY_POS) +#define EF_CTRL_EF_IF_CYC_RD_DMY_UMSK (~(((1U << EF_CTRL_EF_IF_CYC_RD_DMY_LEN) - 1) << EF_CTRL_EF_IF_CYC_RD_DMY_POS)) +#define EF_CTRL_EF_IF_CYC_RD_DAT EF_CTRL_EF_IF_CYC_RD_DAT +#define EF_CTRL_EF_IF_CYC_RD_DAT_POS (6U) +#define EF_CTRL_EF_IF_CYC_RD_DAT_LEN (6U) +#define EF_CTRL_EF_IF_CYC_RD_DAT_MSK (((1U << EF_CTRL_EF_IF_CYC_RD_DAT_LEN) - 1) << EF_CTRL_EF_IF_CYC_RD_DAT_POS) +#define EF_CTRL_EF_IF_CYC_RD_DAT_UMSK (~(((1U << EF_CTRL_EF_IF_CYC_RD_DAT_LEN) - 1) << EF_CTRL_EF_IF_CYC_RD_DAT_POS)) +#define EF_CTRL_EF_IF_CYC_RD_ADR EF_CTRL_EF_IF_CYC_RD_ADR +#define EF_CTRL_EF_IF_CYC_RD_ADR_POS (12U) +#define EF_CTRL_EF_IF_CYC_RD_ADR_LEN (6U) +#define EF_CTRL_EF_IF_CYC_RD_ADR_MSK (((1U << EF_CTRL_EF_IF_CYC_RD_ADR_LEN) - 1) << EF_CTRL_EF_IF_CYC_RD_ADR_POS) +#define EF_CTRL_EF_IF_CYC_RD_ADR_UMSK (~(((1U << EF_CTRL_EF_IF_CYC_RD_ADR_LEN) - 1) << EF_CTRL_EF_IF_CYC_RD_ADR_POS)) +#define EF_CTRL_EF_IF_CYC_CS EF_CTRL_EF_IF_CYC_CS +#define EF_CTRL_EF_IF_CYC_CS_POS (18U) +#define EF_CTRL_EF_IF_CYC_CS_LEN (6U) +#define EF_CTRL_EF_IF_CYC_CS_MSK (((1U << EF_CTRL_EF_IF_CYC_CS_LEN) - 1) << EF_CTRL_EF_IF_CYC_CS_POS) +#define EF_CTRL_EF_IF_CYC_CS_UMSK (~(((1U << EF_CTRL_EF_IF_CYC_CS_LEN) - 1) << EF_CTRL_EF_IF_CYC_CS_POS)) +#define EF_CTRL_EF_IF_CYC_PD_CS_S EF_CTRL_EF_IF_CYC_PD_CS_S +#define EF_CTRL_EF_IF_CYC_PD_CS_S_POS (24U) +#define EF_CTRL_EF_IF_CYC_PD_CS_S_LEN (8U) +#define EF_CTRL_EF_IF_CYC_PD_CS_S_MSK (((1U << EF_CTRL_EF_IF_CYC_PD_CS_S_LEN) - 1) << EF_CTRL_EF_IF_CYC_PD_CS_S_POS) +#define EF_CTRL_EF_IF_CYC_PD_CS_S_UMSK (~(((1U << EF_CTRL_EF_IF_CYC_PD_CS_S_LEN) - 1) << EF_CTRL_EF_IF_CYC_PD_CS_S_POS)) + +/* 0x808 : ef_if_cyc_1 */ +#define EF_CTRL_EF_IF_CYC_1_OFFSET (0x808) +#define EF_CTRL_EF_IF_CYC_PI EF_CTRL_EF_IF_CYC_PI +#define EF_CTRL_EF_IF_CYC_PI_POS (0U) +#define EF_CTRL_EF_IF_CYC_PI_LEN (6U) +#define EF_CTRL_EF_IF_CYC_PI_MSK (((1U << EF_CTRL_EF_IF_CYC_PI_LEN) - 1) << EF_CTRL_EF_IF_CYC_PI_POS) +#define EF_CTRL_EF_IF_CYC_PI_UMSK (~(((1U << EF_CTRL_EF_IF_CYC_PI_LEN) - 1) << EF_CTRL_EF_IF_CYC_PI_POS)) +#define EF_CTRL_EF_IF_CYC_PP EF_CTRL_EF_IF_CYC_PP +#define EF_CTRL_EF_IF_CYC_PP_POS (6U) +#define EF_CTRL_EF_IF_CYC_PP_LEN (8U) +#define EF_CTRL_EF_IF_CYC_PP_MSK (((1U << EF_CTRL_EF_IF_CYC_PP_LEN) - 1) << EF_CTRL_EF_IF_CYC_PP_POS) +#define EF_CTRL_EF_IF_CYC_PP_UMSK (~(((1U << EF_CTRL_EF_IF_CYC_PP_LEN) - 1) << EF_CTRL_EF_IF_CYC_PP_POS)) +#define EF_CTRL_EF_IF_CYC_WR_ADR EF_CTRL_EF_IF_CYC_WR_ADR +#define EF_CTRL_EF_IF_CYC_WR_ADR_POS (14U) +#define EF_CTRL_EF_IF_CYC_WR_ADR_LEN (6U) +#define EF_CTRL_EF_IF_CYC_WR_ADR_MSK (((1U << EF_CTRL_EF_IF_CYC_WR_ADR_LEN) - 1) << EF_CTRL_EF_IF_CYC_WR_ADR_POS) +#define EF_CTRL_EF_IF_CYC_WR_ADR_UMSK (~(((1U << EF_CTRL_EF_IF_CYC_WR_ADR_LEN) - 1) << EF_CTRL_EF_IF_CYC_WR_ADR_POS)) +#define EF_CTRL_EF_IF_CYC_PS_CS EF_CTRL_EF_IF_CYC_PS_CS +#define EF_CTRL_EF_IF_CYC_PS_CS_POS (20U) +#define EF_CTRL_EF_IF_CYC_PS_CS_LEN (6U) +#define EF_CTRL_EF_IF_CYC_PS_CS_MSK (((1U << EF_CTRL_EF_IF_CYC_PS_CS_LEN) - 1) << EF_CTRL_EF_IF_CYC_PS_CS_POS) +#define EF_CTRL_EF_IF_CYC_PS_CS_UMSK (~(((1U << EF_CTRL_EF_IF_CYC_PS_CS_LEN) - 1) << EF_CTRL_EF_IF_CYC_PS_CS_POS)) +#define EF_CTRL_EF_IF_CYC_PD_CS_H EF_CTRL_EF_IF_CYC_PD_CS_H +#define EF_CTRL_EF_IF_CYC_PD_CS_H_POS (26U) +#define EF_CTRL_EF_IF_CYC_PD_CS_H_LEN (6U) +#define EF_CTRL_EF_IF_CYC_PD_CS_H_MSK (((1U << EF_CTRL_EF_IF_CYC_PD_CS_H_LEN) - 1) << EF_CTRL_EF_IF_CYC_PD_CS_H_POS) +#define EF_CTRL_EF_IF_CYC_PD_CS_H_UMSK (~(((1U << EF_CTRL_EF_IF_CYC_PD_CS_H_LEN) - 1) << EF_CTRL_EF_IF_CYC_PD_CS_H_POS)) + +/* 0x80C : ef_if_0_manual */ +#define EF_CTRL_EF_IF_0_MANUAL_OFFSET (0x80C) +#define EF_CTRL_EF_IF_A EF_CTRL_EF_IF_A +#define EF_CTRL_EF_IF_A_POS (0U) +#define EF_CTRL_EF_IF_A_LEN (10U) +#define EF_CTRL_EF_IF_A_MSK (((1U << EF_CTRL_EF_IF_A_LEN) - 1) << EF_CTRL_EF_IF_A_POS) +#define EF_CTRL_EF_IF_A_UMSK (~(((1U << EF_CTRL_EF_IF_A_LEN) - 1) << EF_CTRL_EF_IF_A_POS)) +#define EF_CTRL_EF_IF_PD EF_CTRL_EF_IF_PD +#define EF_CTRL_EF_IF_PD_POS (10U) +#define EF_CTRL_EF_IF_PD_LEN (1U) +#define EF_CTRL_EF_IF_PD_MSK (((1U << EF_CTRL_EF_IF_PD_LEN) - 1) << EF_CTRL_EF_IF_PD_POS) +#define EF_CTRL_EF_IF_PD_UMSK (~(((1U << EF_CTRL_EF_IF_PD_LEN) - 1) << EF_CTRL_EF_IF_PD_POS)) +#define EF_CTRL_EF_IF_PS EF_CTRL_EF_IF_PS +#define EF_CTRL_EF_IF_PS_POS (11U) +#define EF_CTRL_EF_IF_PS_LEN (1U) +#define EF_CTRL_EF_IF_PS_MSK (((1U << EF_CTRL_EF_IF_PS_LEN) - 1) << EF_CTRL_EF_IF_PS_POS) +#define EF_CTRL_EF_IF_PS_UMSK (~(((1U << EF_CTRL_EF_IF_PS_LEN) - 1) << EF_CTRL_EF_IF_PS_POS)) +#define EF_CTRL_EF_IF_STROBE EF_CTRL_EF_IF_STROBE +#define EF_CTRL_EF_IF_STROBE_POS (12U) +#define EF_CTRL_EF_IF_STROBE_LEN (1U) +#define EF_CTRL_EF_IF_STROBE_MSK (((1U << EF_CTRL_EF_IF_STROBE_LEN) - 1) << EF_CTRL_EF_IF_STROBE_POS) +#define EF_CTRL_EF_IF_STROBE_UMSK (~(((1U << EF_CTRL_EF_IF_STROBE_LEN) - 1) << EF_CTRL_EF_IF_STROBE_POS)) +#define EF_CTRL_EF_IF_PGENB EF_CTRL_EF_IF_PGENB +#define EF_CTRL_EF_IF_PGENB_POS (13U) +#define EF_CTRL_EF_IF_PGENB_LEN (1U) +#define EF_CTRL_EF_IF_PGENB_MSK (((1U << EF_CTRL_EF_IF_PGENB_LEN) - 1) << EF_CTRL_EF_IF_PGENB_POS) +#define EF_CTRL_EF_IF_PGENB_UMSK (~(((1U << EF_CTRL_EF_IF_PGENB_LEN) - 1) << EF_CTRL_EF_IF_PGENB_POS)) +#define EF_CTRL_EF_IF_LOAD EF_CTRL_EF_IF_LOAD +#define EF_CTRL_EF_IF_LOAD_POS (14U) +#define EF_CTRL_EF_IF_LOAD_LEN (1U) +#define EF_CTRL_EF_IF_LOAD_MSK (((1U << EF_CTRL_EF_IF_LOAD_LEN) - 1) << EF_CTRL_EF_IF_LOAD_POS) +#define EF_CTRL_EF_IF_LOAD_UMSK (~(((1U << EF_CTRL_EF_IF_LOAD_LEN) - 1) << EF_CTRL_EF_IF_LOAD_POS)) +#define EF_CTRL_EF_IF_CSB EF_CTRL_EF_IF_CSB +#define EF_CTRL_EF_IF_CSB_POS (15U) +#define EF_CTRL_EF_IF_CSB_LEN (1U) +#define EF_CTRL_EF_IF_CSB_MSK (((1U << EF_CTRL_EF_IF_CSB_LEN) - 1) << EF_CTRL_EF_IF_CSB_POS) +#define EF_CTRL_EF_IF_CSB_UMSK (~(((1U << EF_CTRL_EF_IF_CSB_LEN) - 1) << EF_CTRL_EF_IF_CSB_POS)) +#define EF_CTRL_EF_IF_0_Q EF_CTRL_EF_IF_0_Q +#define EF_CTRL_EF_IF_0_Q_POS (16U) +#define EF_CTRL_EF_IF_0_Q_LEN (8U) +#define EF_CTRL_EF_IF_0_Q_MSK (((1U << EF_CTRL_EF_IF_0_Q_LEN) - 1) << EF_CTRL_EF_IF_0_Q_POS) +#define EF_CTRL_EF_IF_0_Q_UMSK (~(((1U << EF_CTRL_EF_IF_0_Q_LEN) - 1) << EF_CTRL_EF_IF_0_Q_POS)) +#define EF_CTRL_EF_IF_PROT_CODE_MANUAL EF_CTRL_EF_IF_PROT_CODE_MANUAL +#define EF_CTRL_EF_IF_PROT_CODE_MANUAL_POS (24U) +#define EF_CTRL_EF_IF_PROT_CODE_MANUAL_LEN (8U) +#define EF_CTRL_EF_IF_PROT_CODE_MANUAL_MSK (((1U << EF_CTRL_EF_IF_PROT_CODE_MANUAL_LEN) - 1) << EF_CTRL_EF_IF_PROT_CODE_MANUAL_POS) +#define EF_CTRL_EF_IF_PROT_CODE_MANUAL_UMSK (~(((1U << EF_CTRL_EF_IF_PROT_CODE_MANUAL_LEN) - 1) << EF_CTRL_EF_IF_PROT_CODE_MANUAL_POS)) + +/* 0x810 : ef_if_0_status */ +#define EF_CTRL_EF_IF_0_STATUS_OFFSET (0x810) +#define EF_CTRL_EF_IF_0_STATUS EF_CTRL_EF_IF_0_STATUS +#define EF_CTRL_EF_IF_0_STATUS_POS (0U) +#define EF_CTRL_EF_IF_0_STATUS_LEN (32U) +#define EF_CTRL_EF_IF_0_STATUS_MSK (((1U << EF_CTRL_EF_IF_0_STATUS_LEN) - 1) << EF_CTRL_EF_IF_0_STATUS_POS) +#define EF_CTRL_EF_IF_0_STATUS_UMSK (~(((1U << EF_CTRL_EF_IF_0_STATUS_LEN) - 1) << EF_CTRL_EF_IF_0_STATUS_POS)) + +/* 0x814 : ef_if_cfg_0 */ +#define EF_CTRL_EF_IF_CFG_0_OFFSET (0x814) +#define EF_CTRL_EF_IF_SF_AES_MODE EF_CTRL_EF_IF_SF_AES_MODE +#define EF_CTRL_EF_IF_SF_AES_MODE_POS (0U) +#define EF_CTRL_EF_IF_SF_AES_MODE_LEN (2U) +#define EF_CTRL_EF_IF_SF_AES_MODE_MSK (((1U << EF_CTRL_EF_IF_SF_AES_MODE_LEN) - 1) << EF_CTRL_EF_IF_SF_AES_MODE_POS) +#define EF_CTRL_EF_IF_SF_AES_MODE_UMSK (~(((1U << EF_CTRL_EF_IF_SF_AES_MODE_LEN) - 1) << EF_CTRL_EF_IF_SF_AES_MODE_POS)) +#define EF_CTRL_EF_IF_AI_DIS EF_CTRL_EF_IF_AI_DIS +#define EF_CTRL_EF_IF_AI_DIS_POS (2U) +#define EF_CTRL_EF_IF_AI_DIS_LEN (1U) +#define EF_CTRL_EF_IF_AI_DIS_MSK (((1U << EF_CTRL_EF_IF_AI_DIS_LEN) - 1) << EF_CTRL_EF_IF_AI_DIS_POS) +#define EF_CTRL_EF_IF_AI_DIS_UMSK (~(((1U << EF_CTRL_EF_IF_AI_DIS_LEN) - 1) << EF_CTRL_EF_IF_AI_DIS_POS)) +#define EF_CTRL_EF_IF_CPU0_DIS EF_CTRL_EF_IF_CPU0_DIS +#define EF_CTRL_EF_IF_CPU0_DIS_POS (3U) +#define EF_CTRL_EF_IF_CPU0_DIS_LEN (1U) +#define EF_CTRL_EF_IF_CPU0_DIS_MSK (((1U << EF_CTRL_EF_IF_CPU0_DIS_LEN) - 1) << EF_CTRL_EF_IF_CPU0_DIS_POS) +#define EF_CTRL_EF_IF_CPU0_DIS_UMSK (~(((1U << EF_CTRL_EF_IF_CPU0_DIS_LEN) - 1) << EF_CTRL_EF_IF_CPU0_DIS_POS)) +#define EF_CTRL_EF_IF_SBOOT_EN EF_CTRL_EF_IF_SBOOT_EN +#define EF_CTRL_EF_IF_SBOOT_EN_POS (4U) +#define EF_CTRL_EF_IF_SBOOT_EN_LEN (2U) +#define EF_CTRL_EF_IF_SBOOT_EN_MSK (((1U << EF_CTRL_EF_IF_SBOOT_EN_LEN) - 1) << EF_CTRL_EF_IF_SBOOT_EN_POS) +#define EF_CTRL_EF_IF_SBOOT_EN_UMSK (~(((1U << EF_CTRL_EF_IF_SBOOT_EN_LEN) - 1) << EF_CTRL_EF_IF_SBOOT_EN_POS)) +#define EF_CTRL_EF_IF_UART_DIS EF_CTRL_EF_IF_UART_DIS +#define EF_CTRL_EF_IF_UART_DIS_POS (6U) +#define EF_CTRL_EF_IF_UART_DIS_LEN (4U) +#define EF_CTRL_EF_IF_UART_DIS_MSK (((1U << EF_CTRL_EF_IF_UART_DIS_LEN) - 1) << EF_CTRL_EF_IF_UART_DIS_POS) +#define EF_CTRL_EF_IF_UART_DIS_UMSK (~(((1U << EF_CTRL_EF_IF_UART_DIS_LEN) - 1) << EF_CTRL_EF_IF_UART_DIS_POS)) +#define EF_CTRL_EF_IF_BLE2_DIS EF_CTRL_EF_IF_BLE2_DIS +#define EF_CTRL_EF_IF_BLE2_DIS_POS (10U) +#define EF_CTRL_EF_IF_BLE2_DIS_LEN (1U) +#define EF_CTRL_EF_IF_BLE2_DIS_MSK (((1U << EF_CTRL_EF_IF_BLE2_DIS_LEN) - 1) << EF_CTRL_EF_IF_BLE2_DIS_POS) +#define EF_CTRL_EF_IF_BLE2_DIS_UMSK (~(((1U << EF_CTRL_EF_IF_BLE2_DIS_LEN) - 1) << EF_CTRL_EF_IF_BLE2_DIS_POS)) +#define EF_CTRL_EF_IF_M1542_DIS EF_CTRL_EF_IF_M1542_DIS +#define EF_CTRL_EF_IF_M1542_DIS_POS (11U) +#define EF_CTRL_EF_IF_M1542_DIS_LEN (1U) +#define EF_CTRL_EF_IF_M1542_DIS_MSK (((1U << EF_CTRL_EF_IF_M1542_DIS_LEN) - 1) << EF_CTRL_EF_IF_M1542_DIS_POS) +#define EF_CTRL_EF_IF_M1542_DIS_UMSK (~(((1U << EF_CTRL_EF_IF_M1542_DIS_LEN) - 1) << EF_CTRL_EF_IF_M1542_DIS_POS)) +#define EF_CTRL_EF_IF_SF_KEY_RE_SEL EF_CTRL_EF_IF_SF_KEY_RE_SEL +#define EF_CTRL_EF_IF_SF_KEY_RE_SEL_POS (12U) +#define EF_CTRL_EF_IF_SF_KEY_RE_SEL_LEN (2U) +#define EF_CTRL_EF_IF_SF_KEY_RE_SEL_MSK (((1U << EF_CTRL_EF_IF_SF_KEY_RE_SEL_LEN) - 1) << EF_CTRL_EF_IF_SF_KEY_RE_SEL_POS) +#define EF_CTRL_EF_IF_SF_KEY_RE_SEL_UMSK (~(((1U << EF_CTRL_EF_IF_SF_KEY_RE_SEL_LEN) - 1) << EF_CTRL_EF_IF_SF_KEY_RE_SEL_POS)) +#define EF_CTRL_EF_IF_SDU_DIS EF_CTRL_EF_IF_SDU_DIS +#define EF_CTRL_EF_IF_SDU_DIS_POS (14U) +#define EF_CTRL_EF_IF_SDU_DIS_LEN (1U) +#define EF_CTRL_EF_IF_SDU_DIS_MSK (((1U << EF_CTRL_EF_IF_SDU_DIS_LEN) - 1) << EF_CTRL_EF_IF_SDU_DIS_POS) +#define EF_CTRL_EF_IF_SDU_DIS_UMSK (~(((1U << EF_CTRL_EF_IF_SDU_DIS_LEN) - 1) << EF_CTRL_EF_IF_SDU_DIS_POS)) +#define EF_CTRL_EF_IF_BTDM_DIS EF_CTRL_EF_IF_BTDM_DIS +#define EF_CTRL_EF_IF_BTDM_DIS_POS (15U) +#define EF_CTRL_EF_IF_BTDM_DIS_LEN (1U) +#define EF_CTRL_EF_IF_BTDM_DIS_MSK (((1U << EF_CTRL_EF_IF_BTDM_DIS_LEN) - 1) << EF_CTRL_EF_IF_BTDM_DIS_POS) +#define EF_CTRL_EF_IF_BTDM_DIS_UMSK (~(((1U << EF_CTRL_EF_IF_BTDM_DIS_LEN) - 1) << EF_CTRL_EF_IF_BTDM_DIS_POS)) +#define EF_CTRL_EF_IF_WIFI_DIS EF_CTRL_EF_IF_WIFI_DIS +#define EF_CTRL_EF_IF_WIFI_DIS_POS (16U) +#define EF_CTRL_EF_IF_WIFI_DIS_LEN (1U) +#define EF_CTRL_EF_IF_WIFI_DIS_MSK (((1U << EF_CTRL_EF_IF_WIFI_DIS_LEN) - 1) << EF_CTRL_EF_IF_WIFI_DIS_POS) +#define EF_CTRL_EF_IF_WIFI_DIS_UMSK (~(((1U << EF_CTRL_EF_IF_WIFI_DIS_LEN) - 1) << EF_CTRL_EF_IF_WIFI_DIS_POS)) +#define EF_CTRL_EF_IF_0_KEY_ENC_EN EF_CTRL_EF_IF_0_KEY_ENC_EN +#define EF_CTRL_EF_IF_0_KEY_ENC_EN_POS (17U) +#define EF_CTRL_EF_IF_0_KEY_ENC_EN_LEN (1U) +#define EF_CTRL_EF_IF_0_KEY_ENC_EN_MSK (((1U << EF_CTRL_EF_IF_0_KEY_ENC_EN_LEN) - 1) << EF_CTRL_EF_IF_0_KEY_ENC_EN_POS) +#define EF_CTRL_EF_IF_0_KEY_ENC_EN_UMSK (~(((1U << EF_CTRL_EF_IF_0_KEY_ENC_EN_LEN) - 1) << EF_CTRL_EF_IF_0_KEY_ENC_EN_POS)) +#define EF_CTRL_EF_IF_CAM_DIS EF_CTRL_EF_IF_CAM_DIS +#define EF_CTRL_EF_IF_CAM_DIS_POS (18U) +#define EF_CTRL_EF_IF_CAM_DIS_LEN (1U) +#define EF_CTRL_EF_IF_CAM_DIS_MSK (((1U << EF_CTRL_EF_IF_CAM_DIS_LEN) - 1) << EF_CTRL_EF_IF_CAM_DIS_POS) +#define EF_CTRL_EF_IF_CAM_DIS_UMSK (~(((1U << EF_CTRL_EF_IF_CAM_DIS_LEN) - 1) << EF_CTRL_EF_IF_CAM_DIS_POS)) +#define EF_CTRL_EF_IF_M154_DIS EF_CTRL_EF_IF_M154_DIS +#define EF_CTRL_EF_IF_M154_DIS_POS (19U) +#define EF_CTRL_EF_IF_M154_DIS_LEN (1U) +#define EF_CTRL_EF_IF_M154_DIS_MSK (((1U << EF_CTRL_EF_IF_M154_DIS_LEN) - 1) << EF_CTRL_EF_IF_M154_DIS_POS) +#define EF_CTRL_EF_IF_M154_DIS_UMSK (~(((1U << EF_CTRL_EF_IF_M154_DIS_LEN) - 1) << EF_CTRL_EF_IF_M154_DIS_POS)) +#define EF_CTRL_EF_IF_CPU1_DIS EF_CTRL_EF_IF_CPU1_DIS +#define EF_CTRL_EF_IF_CPU1_DIS_POS (20U) +#define EF_CTRL_EF_IF_CPU1_DIS_LEN (1U) +#define EF_CTRL_EF_IF_CPU1_DIS_MSK (((1U << EF_CTRL_EF_IF_CPU1_DIS_LEN) - 1) << EF_CTRL_EF_IF_CPU1_DIS_POS) +#define EF_CTRL_EF_IF_CPU1_DIS_UMSK (~(((1U << EF_CTRL_EF_IF_CPU1_DIS_LEN) - 1) << EF_CTRL_EF_IF_CPU1_DIS_POS)) +#define EF_CTRL_EF_IF_CPU_RST_DBG_DIS EF_CTRL_EF_IF_CPU_RST_DBG_DIS +#define EF_CTRL_EF_IF_CPU_RST_DBG_DIS_POS (21U) +#define EF_CTRL_EF_IF_CPU_RST_DBG_DIS_LEN (1U) +#define EF_CTRL_EF_IF_CPU_RST_DBG_DIS_MSK (((1U << EF_CTRL_EF_IF_CPU_RST_DBG_DIS_LEN) - 1) << EF_CTRL_EF_IF_CPU_RST_DBG_DIS_POS) +#define EF_CTRL_EF_IF_CPU_RST_DBG_DIS_UMSK (~(((1U << EF_CTRL_EF_IF_CPU_RST_DBG_DIS_LEN) - 1) << EF_CTRL_EF_IF_CPU_RST_DBG_DIS_POS)) +#define EF_CTRL_EF_IF_SE_DBG_DIS EF_CTRL_EF_IF_SE_DBG_DIS +#define EF_CTRL_EF_IF_SE_DBG_DIS_POS (22U) +#define EF_CTRL_EF_IF_SE_DBG_DIS_LEN (1U) +#define EF_CTRL_EF_IF_SE_DBG_DIS_MSK (((1U << EF_CTRL_EF_IF_SE_DBG_DIS_LEN) - 1) << EF_CTRL_EF_IF_SE_DBG_DIS_POS) +#define EF_CTRL_EF_IF_SE_DBG_DIS_UMSK (~(((1U << EF_CTRL_EF_IF_SE_DBG_DIS_LEN) - 1) << EF_CTRL_EF_IF_SE_DBG_DIS_POS)) +#define EF_CTRL_EF_IF_EFUSE_DBG_DIS EF_CTRL_EF_IF_EFUSE_DBG_DIS +#define EF_CTRL_EF_IF_EFUSE_DBG_DIS_POS (23U) +#define EF_CTRL_EF_IF_EFUSE_DBG_DIS_LEN (1U) +#define EF_CTRL_EF_IF_EFUSE_DBG_DIS_MSK (((1U << EF_CTRL_EF_IF_EFUSE_DBG_DIS_LEN) - 1) << EF_CTRL_EF_IF_EFUSE_DBG_DIS_POS) +#define EF_CTRL_EF_IF_EFUSE_DBG_DIS_UMSK (~(((1U << EF_CTRL_EF_IF_EFUSE_DBG_DIS_LEN) - 1) << EF_CTRL_EF_IF_EFUSE_DBG_DIS_POS)) +#define EF_CTRL_EF_IF_DBG_JTAG_1_DIS EF_CTRL_EF_IF_DBG_JTAG_1_DIS +#define EF_CTRL_EF_IF_DBG_JTAG_1_DIS_POS (24U) +#define EF_CTRL_EF_IF_DBG_JTAG_1_DIS_LEN (2U) +#define EF_CTRL_EF_IF_DBG_JTAG_1_DIS_MSK (((1U << EF_CTRL_EF_IF_DBG_JTAG_1_DIS_LEN) - 1) << EF_CTRL_EF_IF_DBG_JTAG_1_DIS_POS) +#define EF_CTRL_EF_IF_DBG_JTAG_1_DIS_UMSK (~(((1U << EF_CTRL_EF_IF_DBG_JTAG_1_DIS_LEN) - 1) << EF_CTRL_EF_IF_DBG_JTAG_1_DIS_POS)) +#define EF_CTRL_EF_IF_DBG_JTAG_0_DIS EF_CTRL_EF_IF_DBG_JTAG_0_DIS +#define EF_CTRL_EF_IF_DBG_JTAG_0_DIS_POS (26U) +#define EF_CTRL_EF_IF_DBG_JTAG_0_DIS_LEN (2U) +#define EF_CTRL_EF_IF_DBG_JTAG_0_DIS_MSK (((1U << EF_CTRL_EF_IF_DBG_JTAG_0_DIS_LEN) - 1) << EF_CTRL_EF_IF_DBG_JTAG_0_DIS_POS) +#define EF_CTRL_EF_IF_DBG_JTAG_0_DIS_UMSK (~(((1U << EF_CTRL_EF_IF_DBG_JTAG_0_DIS_LEN) - 1) << EF_CTRL_EF_IF_DBG_JTAG_0_DIS_POS)) +#define EF_CTRL_EF_IF_DBG_MODE EF_CTRL_EF_IF_DBG_MODE +#define EF_CTRL_EF_IF_DBG_MODE_POS (28U) +#define EF_CTRL_EF_IF_DBG_MODE_LEN (4U) +#define EF_CTRL_EF_IF_DBG_MODE_MSK (((1U << EF_CTRL_EF_IF_DBG_MODE_LEN) - 1) << EF_CTRL_EF_IF_DBG_MODE_POS) +#define EF_CTRL_EF_IF_DBG_MODE_UMSK (~(((1U << EF_CTRL_EF_IF_DBG_MODE_LEN) - 1) << EF_CTRL_EF_IF_DBG_MODE_POS)) + +/* 0x818 : ef_sw_cfg_0 */ +#define EF_CTRL_EF_SW_CFG_0_OFFSET (0x818) +#define EF_CTRL_EF_SW_SF_AES_MODE EF_CTRL_EF_SW_SF_AES_MODE +#define EF_CTRL_EF_SW_SF_AES_MODE_POS (0U) +#define EF_CTRL_EF_SW_SF_AES_MODE_LEN (2U) +#define EF_CTRL_EF_SW_SF_AES_MODE_MSK (((1U << EF_CTRL_EF_SW_SF_AES_MODE_LEN) - 1) << EF_CTRL_EF_SW_SF_AES_MODE_POS) +#define EF_CTRL_EF_SW_SF_AES_MODE_UMSK (~(((1U << EF_CTRL_EF_SW_SF_AES_MODE_LEN) - 1) << EF_CTRL_EF_SW_SF_AES_MODE_POS)) +#define EF_CTRL_EF_SW_AI_DIS EF_CTRL_EF_SW_AI_DIS +#define EF_CTRL_EF_SW_AI_DIS_POS (2U) +#define EF_CTRL_EF_SW_AI_DIS_LEN (1U) +#define EF_CTRL_EF_SW_AI_DIS_MSK (((1U << EF_CTRL_EF_SW_AI_DIS_LEN) - 1) << EF_CTRL_EF_SW_AI_DIS_POS) +#define EF_CTRL_EF_SW_AI_DIS_UMSK (~(((1U << EF_CTRL_EF_SW_AI_DIS_LEN) - 1) << EF_CTRL_EF_SW_AI_DIS_POS)) +#define EF_CTRL_EF_SW_CPU0_DIS EF_CTRL_EF_SW_CPU0_DIS +#define EF_CTRL_EF_SW_CPU0_DIS_POS (3U) +#define EF_CTRL_EF_SW_CPU0_DIS_LEN (1U) +#define EF_CTRL_EF_SW_CPU0_DIS_MSK (((1U << EF_CTRL_EF_SW_CPU0_DIS_LEN) - 1) << EF_CTRL_EF_SW_CPU0_DIS_POS) +#define EF_CTRL_EF_SW_CPU0_DIS_UMSK (~(((1U << EF_CTRL_EF_SW_CPU0_DIS_LEN) - 1) << EF_CTRL_EF_SW_CPU0_DIS_POS)) +#define EF_CTRL_EF_SW_SBOOT_EN EF_CTRL_EF_SW_SBOOT_EN +#define EF_CTRL_EF_SW_SBOOT_EN_POS (4U) +#define EF_CTRL_EF_SW_SBOOT_EN_LEN (2U) +#define EF_CTRL_EF_SW_SBOOT_EN_MSK (((1U << EF_CTRL_EF_SW_SBOOT_EN_LEN) - 1) << EF_CTRL_EF_SW_SBOOT_EN_POS) +#define EF_CTRL_EF_SW_SBOOT_EN_UMSK (~(((1U << EF_CTRL_EF_SW_SBOOT_EN_LEN) - 1) << EF_CTRL_EF_SW_SBOOT_EN_POS)) +#define EF_CTRL_EF_SW_UART_DIS EF_CTRL_EF_SW_UART_DIS +#define EF_CTRL_EF_SW_UART_DIS_POS (6U) +#define EF_CTRL_EF_SW_UART_DIS_LEN (4U) +#define EF_CTRL_EF_SW_UART_DIS_MSK (((1U << EF_CTRL_EF_SW_UART_DIS_LEN) - 1) << EF_CTRL_EF_SW_UART_DIS_POS) +#define EF_CTRL_EF_SW_UART_DIS_UMSK (~(((1U << EF_CTRL_EF_SW_UART_DIS_LEN) - 1) << EF_CTRL_EF_SW_UART_DIS_POS)) +#define EF_CTRL_EF_SW_BLE2_DIS EF_CTRL_EF_SW_BLE2_DIS +#define EF_CTRL_EF_SW_BLE2_DIS_POS (10U) +#define EF_CTRL_EF_SW_BLE2_DIS_LEN (1U) +#define EF_CTRL_EF_SW_BLE2_DIS_MSK (((1U << EF_CTRL_EF_SW_BLE2_DIS_LEN) - 1) << EF_CTRL_EF_SW_BLE2_DIS_POS) +#define EF_CTRL_EF_SW_BLE2_DIS_UMSK (~(((1U << EF_CTRL_EF_SW_BLE2_DIS_LEN) - 1) << EF_CTRL_EF_SW_BLE2_DIS_POS)) +#define EF_CTRL_EF_SW_M1542_DIS EF_CTRL_EF_SW_M1542_DIS +#define EF_CTRL_EF_SW_M1542_DIS_POS (11U) +#define EF_CTRL_EF_SW_M1542_DIS_LEN (1U) +#define EF_CTRL_EF_SW_M1542_DIS_MSK (((1U << EF_CTRL_EF_SW_M1542_DIS_LEN) - 1) << EF_CTRL_EF_SW_M1542_DIS_POS) +#define EF_CTRL_EF_SW_M1542_DIS_UMSK (~(((1U << EF_CTRL_EF_SW_M1542_DIS_LEN) - 1) << EF_CTRL_EF_SW_M1542_DIS_POS)) +#define EF_CTRL_EF_SW_SF_KEY_RE_SEL EF_CTRL_EF_SW_SF_KEY_RE_SEL +#define EF_CTRL_EF_SW_SF_KEY_RE_SEL_POS (12U) +#define EF_CTRL_EF_SW_SF_KEY_RE_SEL_LEN (2U) +#define EF_CTRL_EF_SW_SF_KEY_RE_SEL_MSK (((1U << EF_CTRL_EF_SW_SF_KEY_RE_SEL_LEN) - 1) << EF_CTRL_EF_SW_SF_KEY_RE_SEL_POS) +#define EF_CTRL_EF_SW_SF_KEY_RE_SEL_UMSK (~(((1U << EF_CTRL_EF_SW_SF_KEY_RE_SEL_LEN) - 1) << EF_CTRL_EF_SW_SF_KEY_RE_SEL_POS)) +#define EF_CTRL_EF_SW_SDU_DIS EF_CTRL_EF_SW_SDU_DIS +#define EF_CTRL_EF_SW_SDU_DIS_POS (14U) +#define EF_CTRL_EF_SW_SDU_DIS_LEN (1U) +#define EF_CTRL_EF_SW_SDU_DIS_MSK (((1U << EF_CTRL_EF_SW_SDU_DIS_LEN) - 1) << EF_CTRL_EF_SW_SDU_DIS_POS) +#define EF_CTRL_EF_SW_SDU_DIS_UMSK (~(((1U << EF_CTRL_EF_SW_SDU_DIS_LEN) - 1) << EF_CTRL_EF_SW_SDU_DIS_POS)) +#define EF_CTRL_EF_SW_BTDM_DIS EF_CTRL_EF_SW_BTDM_DIS +#define EF_CTRL_EF_SW_BTDM_DIS_POS (15U) +#define EF_CTRL_EF_SW_BTDM_DIS_LEN (1U) +#define EF_CTRL_EF_SW_BTDM_DIS_MSK (((1U << EF_CTRL_EF_SW_BTDM_DIS_LEN) - 1) << EF_CTRL_EF_SW_BTDM_DIS_POS) +#define EF_CTRL_EF_SW_BTDM_DIS_UMSK (~(((1U << EF_CTRL_EF_SW_BTDM_DIS_LEN) - 1) << EF_CTRL_EF_SW_BTDM_DIS_POS)) +#define EF_CTRL_EF_SW_WIFI_DIS EF_CTRL_EF_SW_WIFI_DIS +#define EF_CTRL_EF_SW_WIFI_DIS_POS (16U) +#define EF_CTRL_EF_SW_WIFI_DIS_LEN (1U) +#define EF_CTRL_EF_SW_WIFI_DIS_MSK (((1U << EF_CTRL_EF_SW_WIFI_DIS_LEN) - 1) << EF_CTRL_EF_SW_WIFI_DIS_POS) +#define EF_CTRL_EF_SW_WIFI_DIS_UMSK (~(((1U << EF_CTRL_EF_SW_WIFI_DIS_LEN) - 1) << EF_CTRL_EF_SW_WIFI_DIS_POS)) +#define EF_CTRL_EF_SW_0_KEY_ENC_EN EF_CTRL_EF_SW_0_KEY_ENC_EN +#define EF_CTRL_EF_SW_0_KEY_ENC_EN_POS (17U) +#define EF_CTRL_EF_SW_0_KEY_ENC_EN_LEN (1U) +#define EF_CTRL_EF_SW_0_KEY_ENC_EN_MSK (((1U << EF_CTRL_EF_SW_0_KEY_ENC_EN_LEN) - 1) << EF_CTRL_EF_SW_0_KEY_ENC_EN_POS) +#define EF_CTRL_EF_SW_0_KEY_ENC_EN_UMSK (~(((1U << EF_CTRL_EF_SW_0_KEY_ENC_EN_LEN) - 1) << EF_CTRL_EF_SW_0_KEY_ENC_EN_POS)) +#define EF_CTRL_EF_SW_CAM_DIS EF_CTRL_EF_SW_CAM_DIS +#define EF_CTRL_EF_SW_CAM_DIS_POS (18U) +#define EF_CTRL_EF_SW_CAM_DIS_LEN (1U) +#define EF_CTRL_EF_SW_CAM_DIS_MSK (((1U << EF_CTRL_EF_SW_CAM_DIS_LEN) - 1) << EF_CTRL_EF_SW_CAM_DIS_POS) +#define EF_CTRL_EF_SW_CAM_DIS_UMSK (~(((1U << EF_CTRL_EF_SW_CAM_DIS_LEN) - 1) << EF_CTRL_EF_SW_CAM_DIS_POS)) +#define EF_CTRL_EF_SW_M154_DIS EF_CTRL_EF_SW_M154_DIS +#define EF_CTRL_EF_SW_M154_DIS_POS (19U) +#define EF_CTRL_EF_SW_M154_DIS_LEN (1U) +#define EF_CTRL_EF_SW_M154_DIS_MSK (((1U << EF_CTRL_EF_SW_M154_DIS_LEN) - 1) << EF_CTRL_EF_SW_M154_DIS_POS) +#define EF_CTRL_EF_SW_M154_DIS_UMSK (~(((1U << EF_CTRL_EF_SW_M154_DIS_LEN) - 1) << EF_CTRL_EF_SW_M154_DIS_POS)) +#define EF_CTRL_EF_SW_CPU1_DIS EF_CTRL_EF_SW_CPU1_DIS +#define EF_CTRL_EF_SW_CPU1_DIS_POS (20U) +#define EF_CTRL_EF_SW_CPU1_DIS_LEN (1U) +#define EF_CTRL_EF_SW_CPU1_DIS_MSK (((1U << EF_CTRL_EF_SW_CPU1_DIS_LEN) - 1) << EF_CTRL_EF_SW_CPU1_DIS_POS) +#define EF_CTRL_EF_SW_CPU1_DIS_UMSK (~(((1U << EF_CTRL_EF_SW_CPU1_DIS_LEN) - 1) << EF_CTRL_EF_SW_CPU1_DIS_POS)) +#define EF_CTRL_EF_SW_CPU_RST_DBG_DIS EF_CTRL_EF_SW_CPU_RST_DBG_DIS +#define EF_CTRL_EF_SW_CPU_RST_DBG_DIS_POS (21U) +#define EF_CTRL_EF_SW_CPU_RST_DBG_DIS_LEN (1U) +#define EF_CTRL_EF_SW_CPU_RST_DBG_DIS_MSK (((1U << EF_CTRL_EF_SW_CPU_RST_DBG_DIS_LEN) - 1) << EF_CTRL_EF_SW_CPU_RST_DBG_DIS_POS) +#define EF_CTRL_EF_SW_CPU_RST_DBG_DIS_UMSK (~(((1U << EF_CTRL_EF_SW_CPU_RST_DBG_DIS_LEN) - 1) << EF_CTRL_EF_SW_CPU_RST_DBG_DIS_POS)) +#define EF_CTRL_EF_SW_SE_DBG_DIS EF_CTRL_EF_SW_SE_DBG_DIS +#define EF_CTRL_EF_SW_SE_DBG_DIS_POS (22U) +#define EF_CTRL_EF_SW_SE_DBG_DIS_LEN (1U) +#define EF_CTRL_EF_SW_SE_DBG_DIS_MSK (((1U << EF_CTRL_EF_SW_SE_DBG_DIS_LEN) - 1) << EF_CTRL_EF_SW_SE_DBG_DIS_POS) +#define EF_CTRL_EF_SW_SE_DBG_DIS_UMSK (~(((1U << EF_CTRL_EF_SW_SE_DBG_DIS_LEN) - 1) << EF_CTRL_EF_SW_SE_DBG_DIS_POS)) +#define EF_CTRL_EF_SW_EFUSE_DBG_DIS EF_CTRL_EF_SW_EFUSE_DBG_DIS +#define EF_CTRL_EF_SW_EFUSE_DBG_DIS_POS (23U) +#define EF_CTRL_EF_SW_EFUSE_DBG_DIS_LEN (1U) +#define EF_CTRL_EF_SW_EFUSE_DBG_DIS_MSK (((1U << EF_CTRL_EF_SW_EFUSE_DBG_DIS_LEN) - 1) << EF_CTRL_EF_SW_EFUSE_DBG_DIS_POS) +#define EF_CTRL_EF_SW_EFUSE_DBG_DIS_UMSK (~(((1U << EF_CTRL_EF_SW_EFUSE_DBG_DIS_LEN) - 1) << EF_CTRL_EF_SW_EFUSE_DBG_DIS_POS)) +#define EF_CTRL_EF_SW_DBG_JTAG_1_DIS EF_CTRL_EF_SW_DBG_JTAG_1_DIS +#define EF_CTRL_EF_SW_DBG_JTAG_1_DIS_POS (24U) +#define EF_CTRL_EF_SW_DBG_JTAG_1_DIS_LEN (2U) +#define EF_CTRL_EF_SW_DBG_JTAG_1_DIS_MSK (((1U << EF_CTRL_EF_SW_DBG_JTAG_1_DIS_LEN) - 1) << EF_CTRL_EF_SW_DBG_JTAG_1_DIS_POS) +#define EF_CTRL_EF_SW_DBG_JTAG_1_DIS_UMSK (~(((1U << EF_CTRL_EF_SW_DBG_JTAG_1_DIS_LEN) - 1) << EF_CTRL_EF_SW_DBG_JTAG_1_DIS_POS)) +#define EF_CTRL_EF_SW_DBG_JTAG_0_DIS EF_CTRL_EF_SW_DBG_JTAG_0_DIS +#define EF_CTRL_EF_SW_DBG_JTAG_0_DIS_POS (26U) +#define EF_CTRL_EF_SW_DBG_JTAG_0_DIS_LEN (2U) +#define EF_CTRL_EF_SW_DBG_JTAG_0_DIS_MSK (((1U << EF_CTRL_EF_SW_DBG_JTAG_0_DIS_LEN) - 1) << EF_CTRL_EF_SW_DBG_JTAG_0_DIS_POS) +#define EF_CTRL_EF_SW_DBG_JTAG_0_DIS_UMSK (~(((1U << EF_CTRL_EF_SW_DBG_JTAG_0_DIS_LEN) - 1) << EF_CTRL_EF_SW_DBG_JTAG_0_DIS_POS)) +#define EF_CTRL_EF_SW_DBG_MODE EF_CTRL_EF_SW_DBG_MODE +#define EF_CTRL_EF_SW_DBG_MODE_POS (28U) +#define EF_CTRL_EF_SW_DBG_MODE_LEN (4U) +#define EF_CTRL_EF_SW_DBG_MODE_MSK (((1U << EF_CTRL_EF_SW_DBG_MODE_LEN) - 1) << EF_CTRL_EF_SW_DBG_MODE_POS) +#define EF_CTRL_EF_SW_DBG_MODE_UMSK (~(((1U << EF_CTRL_EF_SW_DBG_MODE_LEN) - 1) << EF_CTRL_EF_SW_DBG_MODE_POS)) + +/* 0x81C : ef_reserved */ +#define EF_CTRL_EF_RESERVED_OFFSET (0x81C) +#define EF_CTRL_EF_RESERVED EF_CTRL_EF_RESERVED +#define EF_CTRL_EF_RESERVED_POS (0U) +#define EF_CTRL_EF_RESERVED_LEN (32U) +#define EF_CTRL_EF_RESERVED_MSK (((1U << EF_CTRL_EF_RESERVED_LEN) - 1) << EF_CTRL_EF_RESERVED_POS) +#define EF_CTRL_EF_RESERVED_UMSK (~(((1U << EF_CTRL_EF_RESERVED_LEN) - 1) << EF_CTRL_EF_RESERVED_POS)) + +/* 0x820 : ef_if_sw_usage_0 */ +#define EF_CTRL_EF_IF_SW_USAGE_0_OFFSET (0x820) +#define EF_CTRL_EF_IF_SW_USAGE_0 EF_CTRL_EF_IF_SW_USAGE_0 +#define EF_CTRL_EF_IF_SW_USAGE_0_POS (0U) +#define EF_CTRL_EF_IF_SW_USAGE_0_LEN (32U) +#define EF_CTRL_EF_IF_SW_USAGE_0_MSK (((1U << EF_CTRL_EF_IF_SW_USAGE_0_LEN) - 1) << EF_CTRL_EF_IF_SW_USAGE_0_POS) +#define EF_CTRL_EF_IF_SW_USAGE_0_UMSK (~(((1U << EF_CTRL_EF_IF_SW_USAGE_0_LEN) - 1) << EF_CTRL_EF_IF_SW_USAGE_0_POS)) + +/* 0x824 : ef_if_sw_usage_1 */ +#define EF_CTRL_EF_IF_SW_USAGE_1_OFFSET (0x824) +#define EF_CTRL_EF_IF_SW_USAGE_1 EF_CTRL_EF_IF_SW_USAGE_1 +#define EF_CTRL_EF_IF_SW_USAGE_1_POS (0U) +#define EF_CTRL_EF_IF_SW_USAGE_1_LEN (32U) +#define EF_CTRL_EF_IF_SW_USAGE_1_MSK (((1U << EF_CTRL_EF_IF_SW_USAGE_1_LEN) - 1) << EF_CTRL_EF_IF_SW_USAGE_1_POS) +#define EF_CTRL_EF_IF_SW_USAGE_1_UMSK (~(((1U << EF_CTRL_EF_IF_SW_USAGE_1_LEN) - 1) << EF_CTRL_EF_IF_SW_USAGE_1_POS)) + +/* 0x900 : ef_if_ctrl_1 */ +#define EF_CTRL_EF_IF_CTRL_1_OFFSET (0x900) +#define EF_CTRL_EF_IF_1_BUSY EF_CTRL_EF_IF_1_BUSY +#define EF_CTRL_EF_IF_1_BUSY_POS (2U) +#define EF_CTRL_EF_IF_1_BUSY_LEN (1U) +#define EF_CTRL_EF_IF_1_BUSY_MSK (((1U << EF_CTRL_EF_IF_1_BUSY_LEN) - 1) << EF_CTRL_EF_IF_1_BUSY_POS) +#define EF_CTRL_EF_IF_1_BUSY_UMSK (~(((1U << EF_CTRL_EF_IF_1_BUSY_LEN) - 1) << EF_CTRL_EF_IF_1_BUSY_POS)) +#define EF_CTRL_EF_IF_1_RW EF_CTRL_EF_IF_1_RW +#define EF_CTRL_EF_IF_1_RW_POS (3U) +#define EF_CTRL_EF_IF_1_RW_LEN (1U) +#define EF_CTRL_EF_IF_1_RW_MSK (((1U << EF_CTRL_EF_IF_1_RW_LEN) - 1) << EF_CTRL_EF_IF_1_RW_POS) +#define EF_CTRL_EF_IF_1_RW_UMSK (~(((1U << EF_CTRL_EF_IF_1_RW_LEN) - 1) << EF_CTRL_EF_IF_1_RW_POS)) +#define EF_CTRL_EF_IF_1_TRIG EF_CTRL_EF_IF_1_TRIG +#define EF_CTRL_EF_IF_1_TRIG_POS (4U) +#define EF_CTRL_EF_IF_1_TRIG_LEN (1U) +#define EF_CTRL_EF_IF_1_TRIG_MSK (((1U << EF_CTRL_EF_IF_1_TRIG_LEN) - 1) << EF_CTRL_EF_IF_1_TRIG_POS) +#define EF_CTRL_EF_IF_1_TRIG_UMSK (~(((1U << EF_CTRL_EF_IF_1_TRIG_LEN) - 1) << EF_CTRL_EF_IF_1_TRIG_POS)) +#define EF_CTRL_EF_IF_1_MANUAL_EN EF_CTRL_EF_IF_1_MANUAL_EN +#define EF_CTRL_EF_IF_1_MANUAL_EN_POS (5U) +#define EF_CTRL_EF_IF_1_MANUAL_EN_LEN (1U) +#define EF_CTRL_EF_IF_1_MANUAL_EN_MSK (((1U << EF_CTRL_EF_IF_1_MANUAL_EN_LEN) - 1) << EF_CTRL_EF_IF_1_MANUAL_EN_POS) +#define EF_CTRL_EF_IF_1_MANUAL_EN_UMSK (~(((1U << EF_CTRL_EF_IF_1_MANUAL_EN_LEN) - 1) << EF_CTRL_EF_IF_1_MANUAL_EN_POS)) +#define EF_CTRL_EF_IF_1_CYC_MODIFY EF_CTRL_EF_IF_1_CYC_MODIFY +#define EF_CTRL_EF_IF_1_CYC_MODIFY_POS (6U) +#define EF_CTRL_EF_IF_1_CYC_MODIFY_LEN (1U) +#define EF_CTRL_EF_IF_1_CYC_MODIFY_MSK (((1U << EF_CTRL_EF_IF_1_CYC_MODIFY_LEN) - 1) << EF_CTRL_EF_IF_1_CYC_MODIFY_POS) +#define EF_CTRL_EF_IF_1_CYC_MODIFY_UMSK (~(((1U << EF_CTRL_EF_IF_1_CYC_MODIFY_LEN) - 1) << EF_CTRL_EF_IF_1_CYC_MODIFY_POS)) +#define EF_CTRL_EF_IF_1_INT EF_CTRL_EF_IF_1_INT +#define EF_CTRL_EF_IF_1_INT_POS (20U) +#define EF_CTRL_EF_IF_1_INT_LEN (1U) +#define EF_CTRL_EF_IF_1_INT_MSK (((1U << EF_CTRL_EF_IF_1_INT_LEN) - 1) << EF_CTRL_EF_IF_1_INT_POS) +#define EF_CTRL_EF_IF_1_INT_UMSK (~(((1U << EF_CTRL_EF_IF_1_INT_LEN) - 1) << EF_CTRL_EF_IF_1_INT_POS)) +#define EF_CTRL_EF_IF_1_INT_CLR EF_CTRL_EF_IF_1_INT_CLR +#define EF_CTRL_EF_IF_1_INT_CLR_POS (21U) +#define EF_CTRL_EF_IF_1_INT_CLR_LEN (1U) +#define EF_CTRL_EF_IF_1_INT_CLR_MSK (((1U << EF_CTRL_EF_IF_1_INT_CLR_LEN) - 1) << EF_CTRL_EF_IF_1_INT_CLR_POS) +#define EF_CTRL_EF_IF_1_INT_CLR_UMSK (~(((1U << EF_CTRL_EF_IF_1_INT_CLR_LEN) - 1) << EF_CTRL_EF_IF_1_INT_CLR_POS)) +#define EF_CTRL_EF_IF_1_INT_SET EF_CTRL_EF_IF_1_INT_SET +#define EF_CTRL_EF_IF_1_INT_SET_POS (22U) +#define EF_CTRL_EF_IF_1_INT_SET_LEN (1U) +#define EF_CTRL_EF_IF_1_INT_SET_MSK (((1U << EF_CTRL_EF_IF_1_INT_SET_LEN) - 1) << EF_CTRL_EF_IF_1_INT_SET_POS) +#define EF_CTRL_EF_IF_1_INT_SET_UMSK (~(((1U << EF_CTRL_EF_IF_1_INT_SET_LEN) - 1) << EF_CTRL_EF_IF_1_INT_SET_POS)) + +/* 0x904 : ef_if_1_manual */ +#define EF_CTRL_EF_IF_1_MANUAL_OFFSET (0x904) +#define EF_CTRL_EF_IF_1_Q EF_CTRL_EF_IF_1_Q +#define EF_CTRL_EF_IF_1_Q_POS (16U) +#define EF_CTRL_EF_IF_1_Q_LEN (8U) +#define EF_CTRL_EF_IF_1_Q_MSK (((1U << EF_CTRL_EF_IF_1_Q_LEN) - 1) << EF_CTRL_EF_IF_1_Q_POS) +#define EF_CTRL_EF_IF_1_Q_UMSK (~(((1U << EF_CTRL_EF_IF_1_Q_LEN) - 1) << EF_CTRL_EF_IF_1_Q_POS)) + +/* 0x908 : ef_if_1_status */ +#define EF_CTRL_EF_IF_1_STATUS_OFFSET (0x908) +#define EF_CTRL_EF_IF_1_STATUS EF_CTRL_EF_IF_1_STATUS +#define EF_CTRL_EF_IF_1_STATUS_POS (0U) +#define EF_CTRL_EF_IF_1_STATUS_LEN (32U) +#define EF_CTRL_EF_IF_1_STATUS_MSK (((1U << EF_CTRL_EF_IF_1_STATUS_LEN) - 1) << EF_CTRL_EF_IF_1_STATUS_POS) +#define EF_CTRL_EF_IF_1_STATUS_UMSK (~(((1U << EF_CTRL_EF_IF_1_STATUS_LEN) - 1) << EF_CTRL_EF_IF_1_STATUS_POS)) + +/* 0x910 : ef_if_ctrl_2 */ +#define EF_CTRL_EF_IF_CTRL_2_OFFSET (0x910) + +/* 0x914 : ef_if_2_manual */ +#define EF_CTRL_EF_IF_2_MANUAL_OFFSET (0x914) + +/* 0x918 : ef_if_2_status */ +#define EF_CTRL_EF_IF_2_STATUS_OFFSET (0x918) + +/* 0xA00 : ef_crc_ctrl_0 */ +#define EF_CTRL_EF_CRC_CTRL_0_OFFSET (0xA00) +#define EF_CTRL_EF_CRC_BUSY EF_CTRL_EF_CRC_BUSY +#define EF_CTRL_EF_CRC_BUSY_POS (0U) +#define EF_CTRL_EF_CRC_BUSY_LEN (1U) +#define EF_CTRL_EF_CRC_BUSY_MSK (((1U << EF_CTRL_EF_CRC_BUSY_LEN) - 1) << EF_CTRL_EF_CRC_BUSY_POS) +#define EF_CTRL_EF_CRC_BUSY_UMSK (~(((1U << EF_CTRL_EF_CRC_BUSY_LEN) - 1) << EF_CTRL_EF_CRC_BUSY_POS)) +#define EF_CTRL_EF_CRC_TRIG EF_CTRL_EF_CRC_TRIG +#define EF_CTRL_EF_CRC_TRIG_POS (1U) +#define EF_CTRL_EF_CRC_TRIG_LEN (1U) +#define EF_CTRL_EF_CRC_TRIG_MSK (((1U << EF_CTRL_EF_CRC_TRIG_LEN) - 1) << EF_CTRL_EF_CRC_TRIG_POS) +#define EF_CTRL_EF_CRC_TRIG_UMSK (~(((1U << EF_CTRL_EF_CRC_TRIG_LEN) - 1) << EF_CTRL_EF_CRC_TRIG_POS)) +#define EF_CTRL_EF_CRC_EN EF_CTRL_EF_CRC_EN +#define EF_CTRL_EF_CRC_EN_POS (2U) +#define EF_CTRL_EF_CRC_EN_LEN (1U) +#define EF_CTRL_EF_CRC_EN_MSK (((1U << EF_CTRL_EF_CRC_EN_LEN) - 1) << EF_CTRL_EF_CRC_EN_POS) +#define EF_CTRL_EF_CRC_EN_UMSK (~(((1U << EF_CTRL_EF_CRC_EN_LEN) - 1) << EF_CTRL_EF_CRC_EN_POS)) +#define EF_CTRL_EF_CRC_MODE EF_CTRL_EF_CRC_MODE +#define EF_CTRL_EF_CRC_MODE_POS (3U) +#define EF_CTRL_EF_CRC_MODE_LEN (1U) +#define EF_CTRL_EF_CRC_MODE_MSK (((1U << EF_CTRL_EF_CRC_MODE_LEN) - 1) << EF_CTRL_EF_CRC_MODE_POS) +#define EF_CTRL_EF_CRC_MODE_UMSK (~(((1U << EF_CTRL_EF_CRC_MODE_LEN) - 1) << EF_CTRL_EF_CRC_MODE_POS)) +#define EF_CTRL_EF_CRC_ERROR EF_CTRL_EF_CRC_ERROR +#define EF_CTRL_EF_CRC_ERROR_POS (4U) +#define EF_CTRL_EF_CRC_ERROR_LEN (1U) +#define EF_CTRL_EF_CRC_ERROR_MSK (((1U << EF_CTRL_EF_CRC_ERROR_LEN) - 1) << EF_CTRL_EF_CRC_ERROR_POS) +#define EF_CTRL_EF_CRC_ERROR_UMSK (~(((1U << EF_CTRL_EF_CRC_ERROR_LEN) - 1) << EF_CTRL_EF_CRC_ERROR_POS)) +#define EF_CTRL_EF_CRC_DOUT_INV_EN EF_CTRL_EF_CRC_DOUT_INV_EN +#define EF_CTRL_EF_CRC_DOUT_INV_EN_POS (5U) +#define EF_CTRL_EF_CRC_DOUT_INV_EN_LEN (1U) +#define EF_CTRL_EF_CRC_DOUT_INV_EN_MSK (((1U << EF_CTRL_EF_CRC_DOUT_INV_EN_LEN) - 1) << EF_CTRL_EF_CRC_DOUT_INV_EN_POS) +#define EF_CTRL_EF_CRC_DOUT_INV_EN_UMSK (~(((1U << EF_CTRL_EF_CRC_DOUT_INV_EN_LEN) - 1) << EF_CTRL_EF_CRC_DOUT_INV_EN_POS)) +#define EF_CTRL_EF_CRC_DOUT_ENDIAN EF_CTRL_EF_CRC_DOUT_ENDIAN +#define EF_CTRL_EF_CRC_DOUT_ENDIAN_POS (6U) +#define EF_CTRL_EF_CRC_DOUT_ENDIAN_LEN (1U) +#define EF_CTRL_EF_CRC_DOUT_ENDIAN_MSK (((1U << EF_CTRL_EF_CRC_DOUT_ENDIAN_LEN) - 1) << EF_CTRL_EF_CRC_DOUT_ENDIAN_POS) +#define EF_CTRL_EF_CRC_DOUT_ENDIAN_UMSK (~(((1U << EF_CTRL_EF_CRC_DOUT_ENDIAN_LEN) - 1) << EF_CTRL_EF_CRC_DOUT_ENDIAN_POS)) +#define EF_CTRL_EF_CRC_DIN_ENDIAN EF_CTRL_EF_CRC_DIN_ENDIAN +#define EF_CTRL_EF_CRC_DIN_ENDIAN_POS (7U) +#define EF_CTRL_EF_CRC_DIN_ENDIAN_LEN (1U) +#define EF_CTRL_EF_CRC_DIN_ENDIAN_MSK (((1U << EF_CTRL_EF_CRC_DIN_ENDIAN_LEN) - 1) << EF_CTRL_EF_CRC_DIN_ENDIAN_POS) +#define EF_CTRL_EF_CRC_DIN_ENDIAN_UMSK (~(((1U << EF_CTRL_EF_CRC_DIN_ENDIAN_LEN) - 1) << EF_CTRL_EF_CRC_DIN_ENDIAN_POS)) +#define EF_CTRL_EF_CRC_INT EF_CTRL_EF_CRC_INT +#define EF_CTRL_EF_CRC_INT_POS (8U) +#define EF_CTRL_EF_CRC_INT_LEN (1U) +#define EF_CTRL_EF_CRC_INT_MSK (((1U << EF_CTRL_EF_CRC_INT_LEN) - 1) << EF_CTRL_EF_CRC_INT_POS) +#define EF_CTRL_EF_CRC_INT_UMSK (~(((1U << EF_CTRL_EF_CRC_INT_LEN) - 1) << EF_CTRL_EF_CRC_INT_POS)) +#define EF_CTRL_EF_CRC_INT_CLR EF_CTRL_EF_CRC_INT_CLR +#define EF_CTRL_EF_CRC_INT_CLR_POS (9U) +#define EF_CTRL_EF_CRC_INT_CLR_LEN (1U) +#define EF_CTRL_EF_CRC_INT_CLR_MSK (((1U << EF_CTRL_EF_CRC_INT_CLR_LEN) - 1) << EF_CTRL_EF_CRC_INT_CLR_POS) +#define EF_CTRL_EF_CRC_INT_CLR_UMSK (~(((1U << EF_CTRL_EF_CRC_INT_CLR_LEN) - 1) << EF_CTRL_EF_CRC_INT_CLR_POS)) +#define EF_CTRL_EF_CRC_INT_SET EF_CTRL_EF_CRC_INT_SET +#define EF_CTRL_EF_CRC_INT_SET_POS (10U) +#define EF_CTRL_EF_CRC_INT_SET_LEN (1U) +#define EF_CTRL_EF_CRC_INT_SET_MSK (((1U << EF_CTRL_EF_CRC_INT_SET_LEN) - 1) << EF_CTRL_EF_CRC_INT_SET_POS) +#define EF_CTRL_EF_CRC_INT_SET_UMSK (~(((1U << EF_CTRL_EF_CRC_INT_SET_LEN) - 1) << EF_CTRL_EF_CRC_INT_SET_POS)) +#define EF_CTRL_EF_CRC_LOCK EF_CTRL_EF_CRC_LOCK +#define EF_CTRL_EF_CRC_LOCK_POS (11U) +#define EF_CTRL_EF_CRC_LOCK_LEN (1U) +#define EF_CTRL_EF_CRC_LOCK_MSK (((1U << EF_CTRL_EF_CRC_LOCK_LEN) - 1) << EF_CTRL_EF_CRC_LOCK_POS) +#define EF_CTRL_EF_CRC_LOCK_UMSK (~(((1U << EF_CTRL_EF_CRC_LOCK_LEN) - 1) << EF_CTRL_EF_CRC_LOCK_POS)) +#define EF_CTRL_EF_CRC_SLP_N EF_CTRL_EF_CRC_SLP_N +#define EF_CTRL_EF_CRC_SLP_N_POS (16U) +#define EF_CTRL_EF_CRC_SLP_N_LEN (16U) +#define EF_CTRL_EF_CRC_SLP_N_MSK (((1U << EF_CTRL_EF_CRC_SLP_N_LEN) - 1) << EF_CTRL_EF_CRC_SLP_N_POS) +#define EF_CTRL_EF_CRC_SLP_N_UMSK (~(((1U << EF_CTRL_EF_CRC_SLP_N_LEN) - 1) << EF_CTRL_EF_CRC_SLP_N_POS)) + +/* 0xA04 : ef_crc_ctrl_1 */ +#define EF_CTRL_EF_CRC_CTRL_1_OFFSET (0xA04) +#define EF_CTRL_EF_CRC_DATA_0_EN EF_CTRL_EF_CRC_DATA_0_EN +#define EF_CTRL_EF_CRC_DATA_0_EN_POS (0U) +#define EF_CTRL_EF_CRC_DATA_0_EN_LEN (32U) +#define EF_CTRL_EF_CRC_DATA_0_EN_MSK (((1U << EF_CTRL_EF_CRC_DATA_0_EN_LEN) - 1) << EF_CTRL_EF_CRC_DATA_0_EN_POS) +#define EF_CTRL_EF_CRC_DATA_0_EN_UMSK (~(((1U << EF_CTRL_EF_CRC_DATA_0_EN_LEN) - 1) << EF_CTRL_EF_CRC_DATA_0_EN_POS)) + +/* 0xA08 : ef_crc_ctrl_2 */ +#define EF_CTRL_EF_CRC_CTRL_2_OFFSET (0xA08) +#define EF_CTRL_EF_CRC_DATA_1_EN EF_CTRL_EF_CRC_DATA_1_EN +#define EF_CTRL_EF_CRC_DATA_1_EN_POS (0U) +#define EF_CTRL_EF_CRC_DATA_1_EN_LEN (32U) +#define EF_CTRL_EF_CRC_DATA_1_EN_MSK (((1U << EF_CTRL_EF_CRC_DATA_1_EN_LEN) - 1) << EF_CTRL_EF_CRC_DATA_1_EN_POS) +#define EF_CTRL_EF_CRC_DATA_1_EN_UMSK (~(((1U << EF_CTRL_EF_CRC_DATA_1_EN_LEN) - 1) << EF_CTRL_EF_CRC_DATA_1_EN_POS)) + +/* 0xA0C : ef_crc_ctrl_3 */ +#define EF_CTRL_EF_CRC_CTRL_3_OFFSET (0xA0C) +#define EF_CTRL_EF_CRC_IV EF_CTRL_EF_CRC_IV +#define EF_CTRL_EF_CRC_IV_POS (0U) +#define EF_CTRL_EF_CRC_IV_LEN (32U) +#define EF_CTRL_EF_CRC_IV_MSK (((1U << EF_CTRL_EF_CRC_IV_LEN) - 1) << EF_CTRL_EF_CRC_IV_POS) +#define EF_CTRL_EF_CRC_IV_UMSK (~(((1U << EF_CTRL_EF_CRC_IV_LEN) - 1) << EF_CTRL_EF_CRC_IV_POS)) + +/* 0xA10 : ef_crc_ctrl_4 */ +#define EF_CTRL_EF_CRC_CTRL_4_OFFSET (0xA10) +#define EF_CTRL_EF_CRC_GOLDEN EF_CTRL_EF_CRC_GOLDEN +#define EF_CTRL_EF_CRC_GOLDEN_POS (0U) +#define EF_CTRL_EF_CRC_GOLDEN_LEN (32U) +#define EF_CTRL_EF_CRC_GOLDEN_MSK (((1U << EF_CTRL_EF_CRC_GOLDEN_LEN) - 1) << EF_CTRL_EF_CRC_GOLDEN_POS) +#define EF_CTRL_EF_CRC_GOLDEN_UMSK (~(((1U << EF_CTRL_EF_CRC_GOLDEN_LEN) - 1) << EF_CTRL_EF_CRC_GOLDEN_POS)) + +/* 0xA14 : ef_crc_ctrl_5 */ +#define EF_CTRL_EF_CRC_CTRL_5_OFFSET (0xA14) +#define EF_CTRL_EF_CRC_DOUT EF_CTRL_EF_CRC_DOUT +#define EF_CTRL_EF_CRC_DOUT_POS (0U) +#define EF_CTRL_EF_CRC_DOUT_LEN (32U) +#define EF_CTRL_EF_CRC_DOUT_MSK (((1U << EF_CTRL_EF_CRC_DOUT_LEN) - 1) << EF_CTRL_EF_CRC_DOUT_POS) +#define EF_CTRL_EF_CRC_DOUT_UMSK (~(((1U << EF_CTRL_EF_CRC_DOUT_LEN) - 1) << EF_CTRL_EF_CRC_DOUT_POS)) + +struct ef_ctrl_reg { + /* 0x0 reserved */ + uint8_t RESERVED0x0[2048]; + + /* 0x800 : ef_if_ctrl_0 */ + union { + struct { + uint32_t ef_if_0_autoload_p1_done : 1; /* [ 0], r, 0x1 */ + uint32_t ef_if_0_autoload_done : 1; /* [ 1], r, 0x1 */ + uint32_t ef_if_0_busy : 1; /* [ 2], r, 0x0 */ + uint32_t ef_if_0_rw : 1; /* [ 3], r/w, 0x0 */ + uint32_t ef_if_0_trig : 1; /* [ 4], r/w, 0x0 */ + uint32_t ef_if_0_manual_en : 1; /* [ 5], r/w, 0x0 */ + uint32_t ef_if_0_cyc_modify : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t ef_if_prot_code_ctrl : 8; /* [15: 8], r/w, 0x0 */ + uint32_t ef_if_por_dig : 1; /* [ 16], r/w, 0x0 */ + uint32_t ef_pclk_force_on : 1; /* [ 17], r/w, 0x0 */ + uint32_t ef_if_auto_rd_en : 1; /* [ 18], r/w, 0x1 */ + uint32_t ef_if_cyc_modify_lock : 1; /* [ 19], r/w, 0x0 */ + uint32_t ef_if_0_int : 1; /* [ 20], r, 0x0 */ + uint32_t ef_if_0_int_clr : 1; /* [ 21], r/w, 0x1 */ + uint32_t ef_if_0_int_set : 1; /* [ 22], r/w, 0x0 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t ef_if_prot_code_cyc : 8; /* [31:24], r/w, 0x0 */ + } BF; + uint32_t WORD; + } ef_if_ctrl_0; + + /* 0x804 : ef_if_cyc_0 */ + union { + struct { + uint32_t ef_if_cyc_rd_dmy : 6; /* [ 5: 0], r/w, 0x0 */ + uint32_t ef_if_cyc_rd_dat : 6; /* [11: 6], r/w, 0x1 */ + uint32_t ef_if_cyc_rd_adr : 6; /* [17:12], r/w, 0x0 */ + uint32_t ef_if_cyc_cs : 6; /* [23:18], r/w, 0x0 */ + uint32_t ef_if_cyc_pd_cs_s : 8; /* [31:24], r/w, 0x16 */ + } BF; + uint32_t WORD; + } ef_if_cyc_0; + + /* 0x808 : ef_if_cyc_1 */ + union { + struct { + uint32_t ef_if_cyc_pi : 6; /* [ 5: 0], r/w, 0x9 */ + uint32_t ef_if_cyc_pp : 8; /* [13: 6], r/w, 0x98 */ + uint32_t ef_if_cyc_wr_adr : 6; /* [19:14], r/w, 0x1 */ + uint32_t ef_if_cyc_ps_cs : 6; /* [25:20], r/w, 0x2 */ + uint32_t ef_if_cyc_pd_cs_h : 6; /* [31:26], r/w, 0x0 */ + } BF; + uint32_t WORD; + } ef_if_cyc_1; + + /* 0x80C : ef_if_0_manual */ + union { + struct { + uint32_t ef_if_a : 10; /* [ 9: 0], r/w, 0x0 */ + uint32_t ef_if_pd : 1; /* [ 10], r/w, 0x1 */ + uint32_t ef_if_ps : 1; /* [ 11], r/w, 0x0 */ + uint32_t ef_if_strobe : 1; /* [ 12], r/w, 0x0 */ + uint32_t ef_if_pgenb : 1; /* [ 13], r/w, 0x1 */ + uint32_t ef_if_load : 1; /* [ 14], r/w, 0x1 */ + uint32_t ef_if_csb : 1; /* [ 15], r/w, 0x1 */ + uint32_t ef_if_0_q : 8; /* [23:16], r, 0x0 */ + uint32_t ef_if_prot_code_manual : 8; /* [31:24], r/w, 0x0 */ + } BF; + uint32_t WORD; + } ef_if_0_manual; + + /* 0x810 : ef_if_0_status */ + union { + struct { + uint32_t ef_if_0_status : 32; /* [31: 0], r, 0xe400 */ + } BF; + uint32_t WORD; + } ef_if_0_status; + + /* 0x814 : ef_if_cfg_0 */ + union { + struct { + uint32_t ef_if_sf_aes_mode : 2; /* [ 1: 0], r, 0x0 */ + uint32_t ef_if_ai_dis : 1; /* [ 2], r, 0x0 */ + uint32_t ef_if_cpu0_dis : 1; /* [ 3], r, 0x0 */ + uint32_t ef_if_sboot_en : 2; /* [ 5: 4], r, 0x0 */ + uint32_t ef_if_uart_dis : 4; /* [ 9: 6], r, 0x0 */ + uint32_t ef_if_ble2_dis : 1; /* [ 10], r, 0x0 */ + uint32_t ef_if_m1542_dis : 1; /* [ 11], r, 0x0 */ + uint32_t ef_if_sf_key_re_sel : 2; /* [13:12], r, 0x0 */ + uint32_t ef_if_sdu_dis : 1; /* [ 14], r, 0x0 */ + uint32_t ef_if_btdm_dis : 1; /* [ 15], r, 0x0 */ + uint32_t ef_if_wifi_dis : 1; /* [ 16], r, 0x0 */ + uint32_t ef_if_0_key_enc_en : 1; /* [ 17], r, 0x0 */ + uint32_t ef_if_cam_dis : 1; /* [ 18], r, 0x0 */ + uint32_t ef_if_m154_dis : 1; /* [ 19], r, 0x0 */ + uint32_t ef_if_cpu1_dis : 1; /* [ 20], r, 0x0 */ + uint32_t ef_if_cpu_rst_dbg_dis : 1; /* [ 21], r, 0x0 */ + uint32_t ef_if_se_dbg_dis : 1; /* [ 22], r, 0x0 */ + uint32_t ef_if_efuse_dbg_dis : 1; /* [ 23], r, 0x0 */ + uint32_t ef_if_dbg_jtag_1_dis : 2; /* [25:24], r, 0x0 */ + uint32_t ef_if_dbg_jtag_0_dis : 2; /* [27:26], r, 0x0 */ + uint32_t ef_if_dbg_mode : 4; /* [31:28], r, 0x0 */ + } BF; + uint32_t WORD; + } ef_if_cfg_0; + + /* 0x818 : ef_sw_cfg_0 */ + union { + struct { + uint32_t ef_sw_sf_aes_mode : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t ef_sw_ai_dis : 1; /* [ 2], r/w, 0x0 */ + uint32_t ef_sw_cpu0_dis : 1; /* [ 3], r/w, 0x0 */ + uint32_t ef_sw_sboot_en : 2; /* [ 5: 4], r/w, 0x0 */ + uint32_t ef_sw_uart_dis : 4; /* [ 9: 6], r/w, 0x0 */ + uint32_t ef_sw_ble2_dis : 1; /* [ 10], r/w, 0x0 */ + uint32_t ef_sw_m1542_dis : 1; /* [ 11], r/w, 0x0 */ + uint32_t ef_sw_sf_key_re_sel : 2; /* [13:12], r/w, 0x0 */ + uint32_t ef_sw_sdu_dis : 1; /* [ 14], r/w, 0x0 */ + uint32_t ef_sw_btdm_dis : 1; /* [ 15], r/w, 0x0 */ + uint32_t ef_sw_wifi_dis : 1; /* [ 16], r/w, 0x0 */ + uint32_t ef_sw_0_key_enc_en : 1; /* [ 17], r/w, 0x0 */ + uint32_t ef_sw_cam_dis : 1; /* [ 18], r/w, 0x0 */ + uint32_t ef_sw_m154_dis : 1; /* [ 19], r/w, 0x0 */ + uint32_t ef_sw_cpu1_dis : 1; /* [ 20], r/w, 0x0 */ + uint32_t ef_sw_cpu_rst_dbg_dis : 1; /* [ 21], r/w, 0x0 */ + uint32_t ef_sw_se_dbg_dis : 1; /* [ 22], r/w, 0x0 */ + uint32_t ef_sw_efuse_dbg_dis : 1; /* [ 23], r/w, 0x0 */ + uint32_t ef_sw_dbg_jtag_1_dis : 2; /* [25:24], r/w, 0x0 */ + uint32_t ef_sw_dbg_jtag_0_dis : 2; /* [27:26], r/w, 0x0 */ + uint32_t ef_sw_dbg_mode : 4; /* [31:28], r/w, 0x0 */ + } BF; + uint32_t WORD; + } ef_sw_cfg_0; + + /* 0x81C : ef_reserved */ + union { + struct { + uint32_t ef_reserved : 32; /* [31: 0], r/w, 0xffff */ + } BF; + uint32_t WORD; + } ef_reserved; + + /* 0x820 : ef_if_sw_usage_0 */ + union { + struct { + uint32_t ef_if_sw_usage_0 : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } ef_if_sw_usage_0; + + /* 0x824 : ef_if_sw_usage_1 */ + union { + struct { + uint32_t ef_if_sw_usage_1 : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } ef_if_sw_usage_1; + + /* 0x828 reserved */ + uint8_t RESERVED0x828[216]; + + /* 0x900 : ef_if_ctrl_1 */ + union { + struct { + uint32_t reserved_0_1 : 2; /* [ 1: 0], rsvd, 0x0 */ + uint32_t ef_if_1_busy : 1; /* [ 2], r, 0x0 */ + uint32_t ef_if_1_rw : 1; /* [ 3], r/w, 0x0 */ + uint32_t ef_if_1_trig : 1; /* [ 4], r/w, 0x0 */ + uint32_t ef_if_1_manual_en : 1; /* [ 5], r/w, 0x0 */ + uint32_t ef_if_1_cyc_modify : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7_19 : 13; /* [19: 7], rsvd, 0x0 */ + uint32_t ef_if_1_int : 1; /* [ 20], r, 0x0 */ + uint32_t ef_if_1_int_clr : 1; /* [ 21], r/w, 0x1 */ + uint32_t ef_if_1_int_set : 1; /* [ 22], r/w, 0x0 */ + uint32_t reserved_23_31 : 9; /* [31:23], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } ef_if_ctrl_1; + + /* 0x904 : ef_if_1_manual */ + union { + struct { + uint32_t reserved_0_15 : 16; /* [15: 0], rsvd, 0x0 */ + uint32_t ef_if_1_q : 8; /* [23:16], r, 0x0 */ + uint32_t reserved_24_31 : 8; /* [31:24], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } ef_if_1_manual; + + /* 0x908 : ef_if_1_status */ + union { + struct { + uint32_t ef_if_1_status : 32; /* [31: 0], r, 0xe400 */ + } BF; + uint32_t WORD; + } ef_if_1_status; + + /* 0x90c reserved */ + uint8_t RESERVED0x90c[4]; + + /* 0x910 : ef_if_ctrl_2 */ + union { + struct { + uint32_t reserved_0_31 : 32; /* [31: 0], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } ef_if_ctrl_2; + + /* 0x914 : ef_if_2_manual */ + union { + struct { + uint32_t reserved_0_31 : 32; /* [31: 0], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } ef_if_2_manual; + + /* 0x918 : ef_if_2_status */ + union { + struct { + uint32_t reserved_0_31 : 32; /* [31: 0], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } ef_if_2_status; + + /* 0x91c reserved */ + uint8_t RESERVED0x91c[228]; + + /* 0xA00 : ef_crc_ctrl_0 */ + union { + struct { + uint32_t ef_crc_busy : 1; /* [ 0], r, 0x0 */ + uint32_t ef_crc_trig : 1; /* [ 1], r/w, 0x0 */ + uint32_t ef_crc_en : 1; /* [ 2], r/w, 0x1 */ + uint32_t ef_crc_mode : 1; /* [ 3], r/w, 0x0 */ + uint32_t ef_crc_error : 1; /* [ 4], r, 0x0 */ + uint32_t ef_crc_dout_inv_en : 1; /* [ 5], r/w, 0x1 */ + uint32_t ef_crc_dout_endian : 1; /* [ 6], r/w, 0x0 */ + uint32_t ef_crc_din_endian : 1; /* [ 7], r/w, 0x0 */ + uint32_t ef_crc_int : 1; /* [ 8], r, 0x0 */ + uint32_t ef_crc_int_clr : 1; /* [ 9], r/w, 0x1 */ + uint32_t ef_crc_int_set : 1; /* [ 10], r/w, 0x0 */ + uint32_t ef_crc_lock : 1; /* [ 11], r/w, 0x0 */ + uint32_t reserved_12_15 : 4; /* [15:12], rsvd, 0x0 */ + uint32_t ef_crc_slp_n : 16; /* [31:16], r/w, 0xff */ + } BF; + uint32_t WORD; + } ef_crc_ctrl_0; + + /* 0xA04 : ef_crc_ctrl_1 */ + union { + struct { + uint32_t ef_crc_data_0_en : 32; /* [31: 0], r/w, 0xffffffffL */ + } BF; + uint32_t WORD; + } ef_crc_ctrl_1; + + /* 0xA08 : ef_crc_ctrl_2 */ + union { + struct { + uint32_t ef_crc_data_1_en : 32; /* [31: 0], r/w, 0xffffffffL */ + } BF; + uint32_t WORD; + } ef_crc_ctrl_2; + + /* 0xA0C : ef_crc_ctrl_3 */ + union { + struct { + uint32_t ef_crc_iv : 32; /* [31: 0], r/w, 0xffffffffL */ + } BF; + uint32_t WORD; + } ef_crc_ctrl_3; + + /* 0xA10 : ef_crc_ctrl_4 */ + union { + struct { + uint32_t ef_crc_golden : 32; /* [31: 0], r/w, 0xc2a8fa9dL */ + } BF; + uint32_t WORD; + } ef_crc_ctrl_4; + + /* 0xA14 : ef_crc_ctrl_5 */ + union { + struct { + uint32_t ef_crc_dout : 32; /* [31: 0], r, 0xffffffffL */ + } BF; + uint32_t WORD; + } ef_crc_ctrl_5; +}; + +typedef volatile struct ef_ctrl_reg ef_ctrl_reg_t; + +#endif /* __EF_CTRL_REG_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/glb_reg.h b/platforms/bl808_m0/vendor/psram/include/glb_reg.h new file mode 100644 index 0000000..7e518f5 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/glb_reg.h @@ -0,0 +1,13190 @@ +/** + ****************************************************************************** + * @file glb_reg.h + * @version V1.0 + * @date 2021-09-10 + * @brief This file is the description of.IP register + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __GLB_REG_H__ +#define __GLB_REG_H__ + +#include "bl808.h" + +/* 0x0 : soc_info0 */ +#define GLB_SOC_INFO0_OFFSET (0x0) +#define GLB_CHIP_RDY GLB_CHIP_RDY +#define GLB_CHIP_RDY_POS (27U) +#define GLB_CHIP_RDY_LEN (1U) +#define GLB_CHIP_RDY_MSK (((1U << GLB_CHIP_RDY_LEN) - 1) << GLB_CHIP_RDY_POS) +#define GLB_CHIP_RDY_UMSK (~(((1U << GLB_CHIP_RDY_LEN) - 1) << GLB_CHIP_RDY_POS)) +#define GLB_ID GLB_ID +#define GLB_ID_POS (28U) +#define GLB_ID_LEN (4U) +#define GLB_ID_MSK (((1U << GLB_ID_LEN) - 1) << GLB_ID_POS) +#define GLB_ID_UMSK (~(((1U << GLB_ID_LEN) - 1) << GLB_ID_POS)) + +/* 0x50 : core_cfg16 */ +#define GLB_CORE_CFG16_OFFSET (0x50) +#define GLB_NP_INT_STA0 GLB_NP_INT_STA0 +#define GLB_NP_INT_STA0_POS (0U) +#define GLB_NP_INT_STA0_LEN (32U) +#define GLB_NP_INT_STA0_MSK (((1U << GLB_NP_INT_STA0_LEN) - 1) << GLB_NP_INT_STA0_POS) +#define GLB_NP_INT_STA0_UMSK (~(((1U << GLB_NP_INT_STA0_LEN) - 1) << GLB_NP_INT_STA0_POS)) + +/* 0x54 : core_cfg17 */ +#define GLB_CORE_CFG17_OFFSET (0x54) +#define GLB_NP_INT_STA1 GLB_NP_INT_STA1 +#define GLB_NP_INT_STA1_POS (0U) +#define GLB_NP_INT_STA1_LEN (32U) +#define GLB_NP_INT_STA1_MSK (((1U << GLB_NP_INT_STA1_LEN) - 1) << GLB_NP_INT_STA1_POS) +#define GLB_NP_INT_STA1_UMSK (~(((1U << GLB_NP_INT_STA1_LEN) - 1) << GLB_NP_INT_STA1_POS)) + +/* 0x58 : core_cfg18 */ +#define GLB_CORE_CFG18_OFFSET (0x58) +#define GLB_NP_INT_MASK0 GLB_NP_INT_MASK0 +#define GLB_NP_INT_MASK0_POS (0U) +#define GLB_NP_INT_MASK0_LEN (32U) +#define GLB_NP_INT_MASK0_MSK (((1U << GLB_NP_INT_MASK0_LEN) - 1) << GLB_NP_INT_MASK0_POS) +#define GLB_NP_INT_MASK0_UMSK (~(((1U << GLB_NP_INT_MASK0_LEN) - 1) << GLB_NP_INT_MASK0_POS)) + +/* 0x5C : core_cfg19 */ +#define GLB_CORE_CFG19_OFFSET (0x5C) +#define GLB_NP_INT_MASK1 GLB_NP_INT_MASK1 +#define GLB_NP_INT_MASK1_POS (0U) +#define GLB_NP_INT_MASK1_LEN (32U) +#define GLB_NP_INT_MASK1_MSK (((1U << GLB_NP_INT_MASK1_LEN) - 1) << GLB_NP_INT_MASK1_POS) +#define GLB_NP_INT_MASK1_UMSK (~(((1U << GLB_NP_INT_MASK1_LEN) - 1) << GLB_NP_INT_MASK1_POS)) + +/* 0x60 : core_cfg20 */ +#define GLB_CORE_CFG20_OFFSET (0x60) +#define GLB_NP_INT_CLR0 GLB_NP_INT_CLR0 +#define GLB_NP_INT_CLR0_POS (0U) +#define GLB_NP_INT_CLR0_LEN (32U) +#define GLB_NP_INT_CLR0_MSK (((1U << GLB_NP_INT_CLR0_LEN) - 1) << GLB_NP_INT_CLR0_POS) +#define GLB_NP_INT_CLR0_UMSK (~(((1U << GLB_NP_INT_CLR0_LEN) - 1) << GLB_NP_INT_CLR0_POS)) + +/* 0x64 : core_cfg21 */ +#define GLB_CORE_CFG21_OFFSET (0x64) +#define GLB_NP_INT_CLR1 GLB_NP_INT_CLR1 +#define GLB_NP_INT_CLR1_POS (0U) +#define GLB_NP_INT_CLR1_LEN (32U) +#define GLB_NP_INT_CLR1_MSK (((1U << GLB_NP_INT_CLR1_LEN) - 1) << GLB_NP_INT_CLR1_POS) +#define GLB_NP_INT_CLR1_UMSK (~(((1U << GLB_NP_INT_CLR1_LEN) - 1) << GLB_NP_INT_CLR1_POS)) + +/* 0x68 : core_cfg22 */ +#define GLB_CORE_CFG22_OFFSET (0x68) +#define GLB_REG_E902_INT_EN0 GLB_REG_E902_INT_EN0 +#define GLB_REG_E902_INT_EN0_POS (0U) +#define GLB_REG_E902_INT_EN0_LEN (32U) +#define GLB_REG_E902_INT_EN0_MSK (((1U << GLB_REG_E902_INT_EN0_LEN) - 1) << GLB_REG_E902_INT_EN0_POS) +#define GLB_REG_E902_INT_EN0_UMSK (~(((1U << GLB_REG_E902_INT_EN0_LEN) - 1) << GLB_REG_E902_INT_EN0_POS)) + +/* 0x6C : core_cfg23 */ +#define GLB_CORE_CFG23_OFFSET (0x6C) +#define GLB_REG_E902_INT_EN1 GLB_REG_E902_INT_EN1 +#define GLB_REG_E902_INT_EN1_POS (0U) +#define GLB_REG_E902_INT_EN1_LEN (32U) +#define GLB_REG_E902_INT_EN1_MSK (((1U << GLB_REG_E902_INT_EN1_LEN) - 1) << GLB_REG_E902_INT_EN1_POS) +#define GLB_REG_E902_INT_EN1_UMSK (~(((1U << GLB_REG_E902_INT_EN1_LEN) - 1) << GLB_REG_E902_INT_EN1_POS)) + +/* 0x70 : core_cfg24 */ +#define GLB_CORE_CFG24_OFFSET (0x70) +#define GLB_STS_E902_INT_BUS_0 GLB_STS_E902_INT_BUS_0 +#define GLB_STS_E902_INT_BUS_0_POS (0U) +#define GLB_STS_E902_INT_BUS_0_LEN (32U) +#define GLB_STS_E902_INT_BUS_0_MSK (((1U << GLB_STS_E902_INT_BUS_0_LEN) - 1) << GLB_STS_E902_INT_BUS_0_POS) +#define GLB_STS_E902_INT_BUS_0_UMSK (~(((1U << GLB_STS_E902_INT_BUS_0_LEN) - 1) << GLB_STS_E902_INT_BUS_0_POS)) + +/* 0x74 : core_cfg25 */ +#define GLB_CORE_CFG25_OFFSET (0x74) +#define GLB_STS_E902_INT_BUS_1 GLB_STS_E902_INT_BUS_1 +#define GLB_STS_E902_INT_BUS_1_POS (0U) +#define GLB_STS_E902_INT_BUS_1_LEN (32U) +#define GLB_STS_E902_INT_BUS_1_MSK (((1U << GLB_STS_E902_INT_BUS_1_LEN) - 1) << GLB_STS_E902_INT_BUS_1_POS) +#define GLB_STS_E902_INT_BUS_1_UMSK (~(((1U << GLB_STS_E902_INT_BUS_1_LEN) - 1) << GLB_STS_E902_INT_BUS_1_POS)) + +/* 0x90 : sys_cfg0 */ +#define GLB_SYS_CFG0_OFFSET (0x90) +#define GLB_REG_PLL_EN GLB_REG_PLL_EN +#define GLB_REG_PLL_EN_POS (0U) +#define GLB_REG_PLL_EN_LEN (1U) +#define GLB_REG_PLL_EN_MSK (((1U << GLB_REG_PLL_EN_LEN) - 1) << GLB_REG_PLL_EN_POS) +#define GLB_REG_PLL_EN_UMSK (~(((1U << GLB_REG_PLL_EN_LEN) - 1) << GLB_REG_PLL_EN_POS)) +#define GLB_REG_FCLK_EN GLB_REG_FCLK_EN +#define GLB_REG_FCLK_EN_POS (1U) +#define GLB_REG_FCLK_EN_LEN (1U) +#define GLB_REG_FCLK_EN_MSK (((1U << GLB_REG_FCLK_EN_LEN) - 1) << GLB_REG_FCLK_EN_POS) +#define GLB_REG_FCLK_EN_UMSK (~(((1U << GLB_REG_FCLK_EN_LEN) - 1) << GLB_REG_FCLK_EN_POS)) +#define GLB_REG_HCLK_EN GLB_REG_HCLK_EN +#define GLB_REG_HCLK_EN_POS (2U) +#define GLB_REG_HCLK_EN_LEN (1U) +#define GLB_REG_HCLK_EN_MSK (((1U << GLB_REG_HCLK_EN_LEN) - 1) << GLB_REG_HCLK_EN_POS) +#define GLB_REG_HCLK_EN_UMSK (~(((1U << GLB_REG_HCLK_EN_LEN) - 1) << GLB_REG_HCLK_EN_POS)) +#define GLB_REG_BCLK_EN GLB_REG_BCLK_EN +#define GLB_REG_BCLK_EN_POS (3U) +#define GLB_REG_BCLK_EN_LEN (1U) +#define GLB_REG_BCLK_EN_MSK (((1U << GLB_REG_BCLK_EN_LEN) - 1) << GLB_REG_BCLK_EN_POS) +#define GLB_REG_BCLK_EN_UMSK (~(((1U << GLB_REG_BCLK_EN_LEN) - 1) << GLB_REG_BCLK_EN_POS)) +#define GLB_HBN_ROOT_CLK_SEL GLB_HBN_ROOT_CLK_SEL +#define GLB_HBN_ROOT_CLK_SEL_POS (6U) +#define GLB_HBN_ROOT_CLK_SEL_LEN (2U) +#define GLB_HBN_ROOT_CLK_SEL_MSK (((1U << GLB_HBN_ROOT_CLK_SEL_LEN) - 1) << GLB_HBN_ROOT_CLK_SEL_POS) +#define GLB_HBN_ROOT_CLK_SEL_UMSK (~(((1U << GLB_HBN_ROOT_CLK_SEL_LEN) - 1) << GLB_HBN_ROOT_CLK_SEL_POS)) +#define GLB_REG_HCLK_DIV GLB_REG_HCLK_DIV +#define GLB_REG_HCLK_DIV_POS (8U) +#define GLB_REG_HCLK_DIV_LEN (8U) +#define GLB_REG_HCLK_DIV_MSK (((1U << GLB_REG_HCLK_DIV_LEN) - 1) << GLB_REG_HCLK_DIV_POS) +#define GLB_REG_HCLK_DIV_UMSK (~(((1U << GLB_REG_HCLK_DIV_LEN) - 1) << GLB_REG_HCLK_DIV_POS)) +#define GLB_REG_BCLK_DIV GLB_REG_BCLK_DIV +#define GLB_REG_BCLK_DIV_POS (16U) +#define GLB_REG_BCLK_DIV_LEN (8U) +#define GLB_REG_BCLK_DIV_MSK (((1U << GLB_REG_BCLK_DIV_LEN) - 1) << GLB_REG_BCLK_DIV_POS) +#define GLB_REG_BCLK_DIV_UMSK (~(((1U << GLB_REG_BCLK_DIV_LEN) - 1) << GLB_REG_BCLK_DIV_POS)) + +/* 0x94 : sys_cfg1 */ +#define GLB_SYS_CFG1_OFFSET (0x94) +#define GLB_REG_BCLK_DIV_ACT_PULSE GLB_REG_BCLK_DIV_ACT_PULSE +#define GLB_REG_BCLK_DIV_ACT_PULSE_POS (0U) +#define GLB_REG_BCLK_DIV_ACT_PULSE_LEN (1U) +#define GLB_REG_BCLK_DIV_ACT_PULSE_MSK (((1U << GLB_REG_BCLK_DIV_ACT_PULSE_LEN) - 1) << GLB_REG_BCLK_DIV_ACT_PULSE_POS) +#define GLB_REG_BCLK_DIV_ACT_PULSE_UMSK (~(((1U << GLB_REG_BCLK_DIV_ACT_PULSE_LEN) - 1) << GLB_REG_BCLK_DIV_ACT_PULSE_POS)) +#define GLB_REG_BCLK_DIV_BYPASS GLB_REG_BCLK_DIV_BYPASS +#define GLB_REG_BCLK_DIV_BYPASS_POS (1U) +#define GLB_REG_BCLK_DIV_BYPASS_LEN (1U) +#define GLB_REG_BCLK_DIV_BYPASS_MSK (((1U << GLB_REG_BCLK_DIV_BYPASS_LEN) - 1) << GLB_REG_BCLK_DIV_BYPASS_POS) +#define GLB_REG_BCLK_DIV_BYPASS_UMSK (~(((1U << GLB_REG_BCLK_DIV_BYPASS_LEN) - 1) << GLB_REG_BCLK_DIV_BYPASS_POS)) +#define GLB_STS_BCLK_PROT_DONE GLB_STS_BCLK_PROT_DONE +#define GLB_STS_BCLK_PROT_DONE_POS (2U) +#define GLB_STS_BCLK_PROT_DONE_LEN (1U) +#define GLB_STS_BCLK_PROT_DONE_MSK (((1U << GLB_STS_BCLK_PROT_DONE_LEN) - 1) << GLB_STS_BCLK_PROT_DONE_POS) +#define GLB_STS_BCLK_PROT_DONE_UMSK (~(((1U << GLB_STS_BCLK_PROT_DONE_LEN) - 1) << GLB_STS_BCLK_PROT_DONE_POS)) +#define GLB_REG_BCLK_SW_DONE_CNT GLB_REG_BCLK_SW_DONE_CNT +#define GLB_REG_BCLK_SW_DONE_CNT_POS (4U) +#define GLB_REG_BCLK_SW_DONE_CNT_LEN (4U) +#define GLB_REG_BCLK_SW_DONE_CNT_MSK (((1U << GLB_REG_BCLK_SW_DONE_CNT_LEN) - 1) << GLB_REG_BCLK_SW_DONE_CNT_POS) +#define GLB_REG_BCLK_SW_DONE_CNT_UMSK (~(((1U << GLB_REG_BCLK_SW_DONE_CNT_LEN) - 1) << GLB_REG_BCLK_SW_DONE_CNT_POS)) +#define GLB_REG_PICO_CLK_DIV_ACT_PULSE GLB_REG_PICO_CLK_DIV_ACT_PULSE +#define GLB_REG_PICO_CLK_DIV_ACT_PULSE_POS (16U) +#define GLB_REG_PICO_CLK_DIV_ACT_PULSE_LEN (1U) +#define GLB_REG_PICO_CLK_DIV_ACT_PULSE_MSK (((1U << GLB_REG_PICO_CLK_DIV_ACT_PULSE_LEN) - 1) << GLB_REG_PICO_CLK_DIV_ACT_PULSE_POS) +#define GLB_REG_PICO_CLK_DIV_ACT_PULSE_UMSK (~(((1U << GLB_REG_PICO_CLK_DIV_ACT_PULSE_LEN) - 1) << GLB_REG_PICO_CLK_DIV_ACT_PULSE_POS)) +#define GLB_REG_PICO_CLK_DIV_BYPASS GLB_REG_PICO_CLK_DIV_BYPASS +#define GLB_REG_PICO_CLK_DIV_BYPASS_POS (17U) +#define GLB_REG_PICO_CLK_DIV_BYPASS_LEN (1U) +#define GLB_REG_PICO_CLK_DIV_BYPASS_MSK (((1U << GLB_REG_PICO_CLK_DIV_BYPASS_LEN) - 1) << GLB_REG_PICO_CLK_DIV_BYPASS_POS) +#define GLB_REG_PICO_CLK_DIV_BYPASS_UMSK (~(((1U << GLB_REG_PICO_CLK_DIV_BYPASS_LEN) - 1) << GLB_REG_PICO_CLK_DIV_BYPASS_POS)) +#define GLB_STS_PICO_CLK_PROT_DONE GLB_STS_PICO_CLK_PROT_DONE +#define GLB_STS_PICO_CLK_PROT_DONE_POS (18U) +#define GLB_STS_PICO_CLK_PROT_DONE_LEN (1U) +#define GLB_STS_PICO_CLK_PROT_DONE_MSK (((1U << GLB_STS_PICO_CLK_PROT_DONE_LEN) - 1) << GLB_STS_PICO_CLK_PROT_DONE_POS) +#define GLB_STS_PICO_CLK_PROT_DONE_UMSK (~(((1U << GLB_STS_PICO_CLK_PROT_DONE_LEN) - 1) << GLB_STS_PICO_CLK_PROT_DONE_POS)) +#define GLB_REG_PICO_CLK_SW_DONE_CNT GLB_REG_PICO_CLK_SW_DONE_CNT +#define GLB_REG_PICO_CLK_SW_DONE_CNT_POS (20U) +#define GLB_REG_PICO_CLK_SW_DONE_CNT_LEN (4U) +#define GLB_REG_PICO_CLK_SW_DONE_CNT_MSK (((1U << GLB_REG_PICO_CLK_SW_DONE_CNT_LEN) - 1) << GLB_REG_PICO_CLK_SW_DONE_CNT_POS) +#define GLB_REG_PICO_CLK_SW_DONE_CNT_UMSK (~(((1U << GLB_REG_PICO_CLK_SW_DONE_CNT_LEN) - 1) << GLB_REG_PICO_CLK_SW_DONE_CNT_POS)) +#define GLB_FCLK_SW_STATE GLB_FCLK_SW_STATE +#define GLB_FCLK_SW_STATE_POS (24U) +#define GLB_FCLK_SW_STATE_LEN (3U) +#define GLB_FCLK_SW_STATE_MSK (((1U << GLB_FCLK_SW_STATE_LEN) - 1) << GLB_FCLK_SW_STATE_POS) +#define GLB_FCLK_SW_STATE_UMSK (~(((1U << GLB_FCLK_SW_STATE_LEN) - 1) << GLB_FCLK_SW_STATE_POS)) + +/* 0xA0 : bus_cfg0 */ +#define GLB_BUS_CFG0_OFFSET (0xA0) +#define GLB_RG_APB2_PCK_FORCE GLB_RG_APB2_PCK_FORCE +#define GLB_RG_APB2_PCK_FORCE_POS (0U) +#define GLB_RG_APB2_PCK_FORCE_LEN (16U) +#define GLB_RG_APB2_PCK_FORCE_MSK (((1U << GLB_RG_APB2_PCK_FORCE_LEN) - 1) << GLB_RG_APB2_PCK_FORCE_POS) +#define GLB_RG_APB2_PCK_FORCE_UMSK (~(((1U << GLB_RG_APB2_PCK_FORCE_LEN) - 1) << GLB_RG_APB2_PCK_FORCE_POS)) + +/* 0xE0 : emi_cfg0 */ +#define GLB_EMI_CFG0_OFFSET (0xE0) +#define GLB_REG_EMI_CLK_EN GLB_REG_EMI_CLK_EN +#define GLB_REG_EMI_CLK_EN_POS (9U) +#define GLB_REG_EMI_CLK_EN_LEN (1U) +#define GLB_REG_EMI_CLK_EN_MSK (((1U << GLB_REG_EMI_CLK_EN_LEN) - 1) << GLB_REG_EMI_CLK_EN_POS) +#define GLB_REG_EMI_CLK_EN_UMSK (~(((1U << GLB_REG_EMI_CLK_EN_LEN) - 1) << GLB_REG_EMI_CLK_EN_POS)) +#define GLB_REG_EMI_CLK_SEL GLB_REG_EMI_CLK_SEL +#define GLB_REG_EMI_CLK_SEL_POS (14U) +#define GLB_REG_EMI_CLK_SEL_LEN (3U) +#define GLB_REG_EMI_CLK_SEL_MSK (((1U << GLB_REG_EMI_CLK_SEL_LEN) - 1) << GLB_REG_EMI_CLK_SEL_POS) +#define GLB_REG_EMI_CLK_SEL_UMSK (~(((1U << GLB_REG_EMI_CLK_SEL_LEN) - 1) << GLB_REG_EMI_CLK_SEL_POS)) +#define GLB_REG_EMI_CLK_DIV GLB_REG_EMI_CLK_DIV +#define GLB_REG_EMI_CLK_DIV_POS (22U) +#define GLB_REG_EMI_CLK_DIV_LEN (2U) +#define GLB_REG_EMI_CLK_DIV_MSK (((1U << GLB_REG_EMI_CLK_DIV_LEN) - 1) << GLB_REG_EMI_CLK_DIV_POS) +#define GLB_REG_EMI_CLK_DIV_UMSK (~(((1U << GLB_REG_EMI_CLK_DIV_LEN) - 1) << GLB_REG_EMI_CLK_DIV_POS)) + +/* 0xF0 : rtc_cfg0 */ +#define GLB_RTC_CFG0_OFFSET (0xF0) +#define GLB_CPU_RTC_DIV GLB_CPU_RTC_DIV +#define GLB_CPU_RTC_DIV_POS (0U) +#define GLB_CPU_RTC_DIV_LEN (17U) +#define GLB_CPU_RTC_DIV_MSK (((1U << GLB_CPU_RTC_DIV_LEN) - 1) << GLB_CPU_RTC_DIV_POS) +#define GLB_CPU_RTC_DIV_UMSK (~(((1U << GLB_CPU_RTC_DIV_LEN) - 1) << GLB_CPU_RTC_DIV_POS)) +#define GLB_CPU_RTC_EN GLB_CPU_RTC_EN +#define GLB_CPU_RTC_EN_POS (18U) +#define GLB_CPU_RTC_EN_LEN (1U) +#define GLB_CPU_RTC_EN_MSK (((1U << GLB_CPU_RTC_EN_LEN) - 1) << GLB_CPU_RTC_EN_POS) +#define GLB_CPU_RTC_EN_UMSK (~(((1U << GLB_CPU_RTC_EN_LEN) - 1) << GLB_CPU_RTC_EN_POS)) +#define GLB_CPU_RTC_SEL GLB_CPU_RTC_SEL +#define GLB_CPU_RTC_SEL_POS (19U) +#define GLB_CPU_RTC_SEL_LEN (1U) +#define GLB_CPU_RTC_SEL_MSK (((1U << GLB_CPU_RTC_SEL_LEN) - 1) << GLB_CPU_RTC_SEL_POS) +#define GLB_CPU_RTC_SEL_UMSK (~(((1U << GLB_CPU_RTC_SEL_LEN) - 1) << GLB_CPU_RTC_SEL_POS)) + +/* 0x110 : adc_cfg0 */ +#define GLB_ADC_CFG0_OFFSET (0x110) +#define GLB_GPADC_32M_CLK_DIV GLB_GPADC_32M_CLK_DIV +#define GLB_GPADC_32M_CLK_DIV_POS (0U) +#define GLB_GPADC_32M_CLK_DIV_LEN (6U) +#define GLB_GPADC_32M_CLK_DIV_MSK (((1U << GLB_GPADC_32M_CLK_DIV_LEN) - 1) << GLB_GPADC_32M_CLK_DIV_POS) +#define GLB_GPADC_32M_CLK_DIV_UMSK (~(((1U << GLB_GPADC_32M_CLK_DIV_LEN) - 1) << GLB_GPADC_32M_CLK_DIV_POS)) +#define GLB_GPADC_32M_CLK_SEL GLB_GPADC_32M_CLK_SEL +#define GLB_GPADC_32M_CLK_SEL_POS (7U) +#define GLB_GPADC_32M_CLK_SEL_LEN (1U) +#define GLB_GPADC_32M_CLK_SEL_MSK (((1U << GLB_GPADC_32M_CLK_SEL_LEN) - 1) << GLB_GPADC_32M_CLK_SEL_POS) +#define GLB_GPADC_32M_CLK_SEL_UMSK (~(((1U << GLB_GPADC_32M_CLK_SEL_LEN) - 1) << GLB_GPADC_32M_CLK_SEL_POS)) +#define GLB_GPADC_32M_DIV_EN GLB_GPADC_32M_DIV_EN +#define GLB_GPADC_32M_DIV_EN_POS (8U) +#define GLB_GPADC_32M_DIV_EN_LEN (1U) +#define GLB_GPADC_32M_DIV_EN_MSK (((1U << GLB_GPADC_32M_DIV_EN_LEN) - 1) << GLB_GPADC_32M_DIV_EN_POS) +#define GLB_GPADC_32M_DIV_EN_UMSK (~(((1U << GLB_GPADC_32M_DIV_EN_LEN) - 1) << GLB_GPADC_32M_DIV_EN_POS)) + +/* 0x120 : dac_cfg0 */ +#define GLB_DAC_CFG0_OFFSET (0x120) +#define GLB_GPDACA_RSTN_ANA GLB_GPDACA_RSTN_ANA +#define GLB_GPDACA_RSTN_ANA_POS (0U) +#define GLB_GPDACA_RSTN_ANA_LEN (1U) +#define GLB_GPDACA_RSTN_ANA_MSK (((1U << GLB_GPDACA_RSTN_ANA_LEN) - 1) << GLB_GPDACA_RSTN_ANA_POS) +#define GLB_GPDACA_RSTN_ANA_UMSK (~(((1U << GLB_GPDACA_RSTN_ANA_LEN) - 1) << GLB_GPDACA_RSTN_ANA_POS)) +#define GLB_GPDACB_RSTN_ANA GLB_GPDACB_RSTN_ANA +#define GLB_GPDACB_RSTN_ANA_POS (1U) +#define GLB_GPDACB_RSTN_ANA_LEN (1U) +#define GLB_GPDACB_RSTN_ANA_MSK (((1U << GLB_GPDACB_RSTN_ANA_LEN) - 1) << GLB_GPDACB_RSTN_ANA_POS) +#define GLB_GPDACB_RSTN_ANA_UMSK (~(((1U << GLB_GPDACB_RSTN_ANA_LEN) - 1) << GLB_GPDACB_RSTN_ANA_POS)) +#define GLB_GPDAC_TEST_EN GLB_GPDAC_TEST_EN +#define GLB_GPDAC_TEST_EN_POS (7U) +#define GLB_GPDAC_TEST_EN_LEN (1U) +#define GLB_GPDAC_TEST_EN_MSK (((1U << GLB_GPDAC_TEST_EN_LEN) - 1) << GLB_GPDAC_TEST_EN_POS) +#define GLB_GPDAC_TEST_EN_UMSK (~(((1U << GLB_GPDAC_TEST_EN_LEN) - 1) << GLB_GPDAC_TEST_EN_POS)) +#define GLB_GPDAC_REF_SEL GLB_GPDAC_REF_SEL +#define GLB_GPDAC_REF_SEL_POS (8U) +#define GLB_GPDAC_REF_SEL_LEN (1U) +#define GLB_GPDAC_REF_SEL_MSK (((1U << GLB_GPDAC_REF_SEL_LEN) - 1) << GLB_GPDAC_REF_SEL_POS) +#define GLB_GPDAC_REF_SEL_UMSK (~(((1U << GLB_GPDAC_REF_SEL_LEN) - 1) << GLB_GPDAC_REF_SEL_POS)) +#define GLB_GPDAC_TEST_SEL GLB_GPDAC_TEST_SEL +#define GLB_GPDAC_TEST_SEL_POS (9U) +#define GLB_GPDAC_TEST_SEL_LEN (3U) +#define GLB_GPDAC_TEST_SEL_MSK (((1U << GLB_GPDAC_TEST_SEL_LEN) - 1) << GLB_GPDAC_TEST_SEL_POS) +#define GLB_GPDAC_TEST_SEL_UMSK (~(((1U << GLB_GPDAC_TEST_SEL_LEN) - 1) << GLB_GPDAC_TEST_SEL_POS)) +#define GLB_GPDAC_RESERVED GLB_GPDAC_RESERVED +#define GLB_GPDAC_RESERVED_POS (24U) +#define GLB_GPDAC_RESERVED_LEN (8U) +#define GLB_GPDAC_RESERVED_MSK (((1U << GLB_GPDAC_RESERVED_LEN) - 1) << GLB_GPDAC_RESERVED_POS) +#define GLB_GPDAC_RESERVED_UMSK (~(((1U << GLB_GPDAC_RESERVED_LEN) - 1) << GLB_GPDAC_RESERVED_POS)) + +/* 0x124 : dac_cfg1 */ +#define GLB_DAC_CFG1_OFFSET (0x124) +#define GLB_GPDAC_A_EN GLB_GPDAC_A_EN +#define GLB_GPDAC_A_EN_POS (0U) +#define GLB_GPDAC_A_EN_LEN (1U) +#define GLB_GPDAC_A_EN_MSK (((1U << GLB_GPDAC_A_EN_LEN) - 1) << GLB_GPDAC_A_EN_POS) +#define GLB_GPDAC_A_EN_UMSK (~(((1U << GLB_GPDAC_A_EN_LEN) - 1) << GLB_GPDAC_A_EN_POS)) +#define GLB_GPDAC_IOA_EN GLB_GPDAC_IOA_EN +#define GLB_GPDAC_IOA_EN_POS (1U) +#define GLB_GPDAC_IOA_EN_LEN (1U) +#define GLB_GPDAC_IOA_EN_MSK (((1U << GLB_GPDAC_IOA_EN_LEN) - 1) << GLB_GPDAC_IOA_EN_POS) +#define GLB_GPDAC_IOA_EN_UMSK (~(((1U << GLB_GPDAC_IOA_EN_LEN) - 1) << GLB_GPDAC_IOA_EN_POS)) +#define GLB_GPDAC_A_RNG GLB_GPDAC_A_RNG +#define GLB_GPDAC_A_RNG_POS (18U) +#define GLB_GPDAC_A_RNG_LEN (2U) +#define GLB_GPDAC_A_RNG_MSK (((1U << GLB_GPDAC_A_RNG_LEN) - 1) << GLB_GPDAC_A_RNG_POS) +#define GLB_GPDAC_A_RNG_UMSK (~(((1U << GLB_GPDAC_A_RNG_LEN) - 1) << GLB_GPDAC_A_RNG_POS)) +#define GLB_GPDAC_A_OUTMUX GLB_GPDAC_A_OUTMUX +#define GLB_GPDAC_A_OUTMUX_POS (20U) +#define GLB_GPDAC_A_OUTMUX_LEN (3U) +#define GLB_GPDAC_A_OUTMUX_MSK (((1U << GLB_GPDAC_A_OUTMUX_LEN) - 1) << GLB_GPDAC_A_OUTMUX_POS) +#define GLB_GPDAC_A_OUTMUX_UMSK (~(((1U << GLB_GPDAC_A_OUTMUX_LEN) - 1) << GLB_GPDAC_A_OUTMUX_POS)) + +/* 0x128 : dac_cfg2 */ +#define GLB_DAC_CFG2_OFFSET (0x128) +#define GLB_GPDAC_B_EN GLB_GPDAC_B_EN +#define GLB_GPDAC_B_EN_POS (0U) +#define GLB_GPDAC_B_EN_LEN (1U) +#define GLB_GPDAC_B_EN_MSK (((1U << GLB_GPDAC_B_EN_LEN) - 1) << GLB_GPDAC_B_EN_POS) +#define GLB_GPDAC_B_EN_UMSK (~(((1U << GLB_GPDAC_B_EN_LEN) - 1) << GLB_GPDAC_B_EN_POS)) +#define GLB_GPDAC_IOB_EN GLB_GPDAC_IOB_EN +#define GLB_GPDAC_IOB_EN_POS (1U) +#define GLB_GPDAC_IOB_EN_LEN (1U) +#define GLB_GPDAC_IOB_EN_MSK (((1U << GLB_GPDAC_IOB_EN_LEN) - 1) << GLB_GPDAC_IOB_EN_POS) +#define GLB_GPDAC_IOB_EN_UMSK (~(((1U << GLB_GPDAC_IOB_EN_LEN) - 1) << GLB_GPDAC_IOB_EN_POS)) +#define GLB_GPDAC_B_RNG GLB_GPDAC_B_RNG +#define GLB_GPDAC_B_RNG_POS (18U) +#define GLB_GPDAC_B_RNG_LEN (2U) +#define GLB_GPDAC_B_RNG_MSK (((1U << GLB_GPDAC_B_RNG_LEN) - 1) << GLB_GPDAC_B_RNG_POS) +#define GLB_GPDAC_B_RNG_UMSK (~(((1U << GLB_GPDAC_B_RNG_LEN) - 1) << GLB_GPDAC_B_RNG_POS)) +#define GLB_GPDAC_B_OUTMUX GLB_GPDAC_B_OUTMUX +#define GLB_GPDAC_B_OUTMUX_POS (20U) +#define GLB_GPDAC_B_OUTMUX_LEN (3U) +#define GLB_GPDAC_B_OUTMUX_MSK (((1U << GLB_GPDAC_B_OUTMUX_LEN) - 1) << GLB_GPDAC_B_OUTMUX_POS) +#define GLB_GPDAC_B_OUTMUX_UMSK (~(((1U << GLB_GPDAC_B_OUTMUX_LEN) - 1) << GLB_GPDAC_B_OUTMUX_POS)) + +/* 0x12C : dac_cfg3 */ +#define GLB_DAC_CFG3_OFFSET (0x12C) +#define GLB_GPDAC_B_DATA GLB_GPDAC_B_DATA +#define GLB_GPDAC_B_DATA_POS (0U) +#define GLB_GPDAC_B_DATA_LEN (10U) +#define GLB_GPDAC_B_DATA_MSK (((1U << GLB_GPDAC_B_DATA_LEN) - 1) << GLB_GPDAC_B_DATA_POS) +#define GLB_GPDAC_B_DATA_UMSK (~(((1U << GLB_GPDAC_B_DATA_LEN) - 1) << GLB_GPDAC_B_DATA_POS)) +#define GLB_GPDAC_A_DATA GLB_GPDAC_A_DATA +#define GLB_GPDAC_A_DATA_POS (16U) +#define GLB_GPDAC_A_DATA_LEN (10U) +#define GLB_GPDAC_A_DATA_MSK (((1U << GLB_GPDAC_A_DATA_LEN) - 1) << GLB_GPDAC_A_DATA_POS) +#define GLB_GPDAC_A_DATA_UMSK (~(((1U << GLB_GPDAC_A_DATA_LEN) - 1) << GLB_GPDAC_A_DATA_POS)) + +/* 0x130 : dma_cfg0 */ +#define GLB_DMA_CFG0_OFFSET (0x130) +#define GLB_DMA_CLK_EN GLB_DMA_CLK_EN +#define GLB_DMA_CLK_EN_POS (24U) +#define GLB_DMA_CLK_EN_LEN (8U) +#define GLB_DMA_CLK_EN_MSK (((1U << GLB_DMA_CLK_EN_LEN) - 1) << GLB_DMA_CLK_EN_POS) +#define GLB_DMA_CLK_EN_UMSK (~(((1U << GLB_DMA_CLK_EN_LEN) - 1) << GLB_DMA_CLK_EN_POS)) + +/* 0x134 : dma_cfg1 */ +#define GLB_DMA_CFG1_OFFSET (0x134) +#define GLB_DMA2_CLK_EN GLB_DMA2_CLK_EN +#define GLB_DMA2_CLK_EN_POS (24U) +#define GLB_DMA2_CLK_EN_LEN (8U) +#define GLB_DMA2_CLK_EN_MSK (((1U << GLB_DMA2_CLK_EN_LEN) - 1) << GLB_DMA2_CLK_EN_POS) +#define GLB_DMA2_CLK_EN_UMSK (~(((1U << GLB_DMA2_CLK_EN_LEN) - 1) << GLB_DMA2_CLK_EN_POS)) + +/* 0x138 : dma_cfg2 */ +#define GLB_DMA_CFG2_OFFSET (0x138) +#define GLB_REG_DMA_CN_SEL GLB_REG_DMA_CN_SEL +#define GLB_REG_DMA_CN_SEL_POS (0U) +#define GLB_REG_DMA_CN_SEL_LEN (32U) +#define GLB_REG_DMA_CN_SEL_MSK (((1U << GLB_REG_DMA_CN_SEL_LEN) - 1) << GLB_REG_DMA_CN_SEL_POS) +#define GLB_REG_DMA_CN_SEL_UMSK (~(((1U << GLB_REG_DMA_CN_SEL_LEN) - 1) << GLB_REG_DMA_CN_SEL_POS)) + +/* 0x140 : ir_cfg0 */ +#define GLB_IR_CFG0_OFFSET (0x140) +#define GLB_IR_CLK_DIV GLB_IR_CLK_DIV +#define GLB_IR_CLK_DIV_POS (16U) +#define GLB_IR_CLK_DIV_LEN (6U) +#define GLB_IR_CLK_DIV_MSK (((1U << GLB_IR_CLK_DIV_LEN) - 1) << GLB_IR_CLK_DIV_POS) +#define GLB_IR_CLK_DIV_UMSK (~(((1U << GLB_IR_CLK_DIV_LEN) - 1) << GLB_IR_CLK_DIV_POS)) +#define GLB_IR_CLK_EN GLB_IR_CLK_EN +#define GLB_IR_CLK_EN_POS (23U) +#define GLB_IR_CLK_EN_LEN (1U) +#define GLB_IR_CLK_EN_MSK (((1U << GLB_IR_CLK_EN_LEN) - 1) << GLB_IR_CLK_EN_POS) +#define GLB_IR_CLK_EN_UMSK (~(((1U << GLB_IR_CLK_EN_LEN) - 1) << GLB_IR_CLK_EN_POS)) + +/* 0x144 : ir_cfg1 */ +#define GLB_IR_CFG1_OFFSET (0x144) +#define GLB_LED_DIN_REG GLB_LED_DIN_REG +#define GLB_LED_DIN_REG_POS (0U) +#define GLB_LED_DIN_REG_LEN (1U) +#define GLB_LED_DIN_REG_MSK (((1U << GLB_LED_DIN_REG_LEN) - 1) << GLB_LED_DIN_REG_POS) +#define GLB_LED_DIN_REG_UMSK (~(((1U << GLB_LED_DIN_REG_LEN) - 1) << GLB_LED_DIN_REG_POS)) +#define GLB_LED_DIN_SEL GLB_LED_DIN_SEL +#define GLB_LED_DIN_SEL_POS (1U) +#define GLB_LED_DIN_SEL_LEN (1U) +#define GLB_LED_DIN_SEL_MSK (((1U << GLB_LED_DIN_SEL_LEN) - 1) << GLB_LED_DIN_SEL_POS) +#define GLB_LED_DIN_SEL_UMSK (~(((1U << GLB_LED_DIN_SEL_LEN) - 1) << GLB_LED_DIN_SEL_POS)) +#define GLB_LED_DIN_POLARITY_SEL GLB_LED_DIN_POLARITY_SEL +#define GLB_LED_DIN_POLARITY_SEL_POS (2U) +#define GLB_LED_DIN_POLARITY_SEL_LEN (1U) +#define GLB_LED_DIN_POLARITY_SEL_MSK (((1U << GLB_LED_DIN_POLARITY_SEL_LEN) - 1) << GLB_LED_DIN_POLARITY_SEL_POS) +#define GLB_LED_DIN_POLARITY_SEL_UMSK (~(((1U << GLB_LED_DIN_POLARITY_SEL_LEN) - 1) << GLB_LED_DIN_POLARITY_SEL_POS)) +#define GLB_LEDDRV_IBIAS GLB_LEDDRV_IBIAS +#define GLB_LEDDRV_IBIAS_POS (4U) +#define GLB_LEDDRV_IBIAS_LEN (4U) +#define GLB_LEDDRV_IBIAS_MSK (((1U << GLB_LEDDRV_IBIAS_LEN) - 1) << GLB_LEDDRV_IBIAS_POS) +#define GLB_LEDDRV_IBIAS_UMSK (~(((1U << GLB_LEDDRV_IBIAS_LEN) - 1) << GLB_LEDDRV_IBIAS_POS)) +#define GLB_IR_RX_GPIO_SEL GLB_IR_RX_GPIO_SEL +#define GLB_IR_RX_GPIO_SEL_POS (8U) +#define GLB_IR_RX_GPIO_SEL_LEN (4U) +#define GLB_IR_RX_GPIO_SEL_MSK (((1U << GLB_IR_RX_GPIO_SEL_LEN) - 1) << GLB_IR_RX_GPIO_SEL_POS) +#define GLB_IR_RX_GPIO_SEL_UMSK (~(((1U << GLB_IR_RX_GPIO_SEL_LEN) - 1) << GLB_IR_RX_GPIO_SEL_POS)) +#define GLB_PU_LEDDRV GLB_PU_LEDDRV +#define GLB_PU_LEDDRV_POS (31U) +#define GLB_PU_LEDDRV_LEN (1U) +#define GLB_PU_LEDDRV_MSK (((1U << GLB_PU_LEDDRV_LEN) - 1) << GLB_PU_LEDDRV_POS) +#define GLB_PU_LEDDRV_UMSK (~(((1U << GLB_PU_LEDDRV_LEN) - 1) << GLB_PU_LEDDRV_POS)) + +/* 0x150 : uart_cfg0 */ +#define GLB_UART_CFG0_OFFSET (0x150) +#define GLB_UART_CLK_DIV GLB_UART_CLK_DIV +#define GLB_UART_CLK_DIV_POS (0U) +#define GLB_UART_CLK_DIV_LEN (3U) +#define GLB_UART_CLK_DIV_MSK (((1U << GLB_UART_CLK_DIV_LEN) - 1) << GLB_UART_CLK_DIV_POS) +#define GLB_UART_CLK_DIV_UMSK (~(((1U << GLB_UART_CLK_DIV_LEN) - 1) << GLB_UART_CLK_DIV_POS)) +#define GLB_UART_CLK_EN GLB_UART_CLK_EN +#define GLB_UART_CLK_EN_POS (4U) +#define GLB_UART_CLK_EN_LEN (1U) +#define GLB_UART_CLK_EN_MSK (((1U << GLB_UART_CLK_EN_LEN) - 1) << GLB_UART_CLK_EN_POS) +#define GLB_UART_CLK_EN_UMSK (~(((1U << GLB_UART_CLK_EN_LEN) - 1) << GLB_UART_CLK_EN_POS)) +#define GLB_HBN_UART_CLK_SEL GLB_HBN_UART_CLK_SEL +#define GLB_HBN_UART_CLK_SEL_POS (7U) +#define GLB_HBN_UART_CLK_SEL_LEN (1U) +#define GLB_HBN_UART_CLK_SEL_MSK (((1U << GLB_HBN_UART_CLK_SEL_LEN) - 1) << GLB_HBN_UART_CLK_SEL_POS) +#define GLB_HBN_UART_CLK_SEL_UMSK (~(((1U << GLB_HBN_UART_CLK_SEL_LEN) - 1) << GLB_HBN_UART_CLK_SEL_POS)) +#define GLB_HBN_UART_CLK_SEL2 GLB_HBN_UART_CLK_SEL2 +#define GLB_HBN_UART_CLK_SEL2_POS (22U) +#define GLB_HBN_UART_CLK_SEL2_LEN (1U) +#define GLB_HBN_UART_CLK_SEL2_MSK (((1U << GLB_HBN_UART_CLK_SEL2_LEN) - 1) << GLB_HBN_UART_CLK_SEL2_POS) +#define GLB_HBN_UART_CLK_SEL2_UMSK (~(((1U << GLB_HBN_UART_CLK_SEL2_LEN) - 1) << GLB_HBN_UART_CLK_SEL2_POS)) +#define GLB_UART2_IO_SEL GLB_UART2_IO_SEL +#define GLB_UART2_IO_SEL_POS (24U) +#define GLB_UART2_IO_SEL_LEN (1U) +#define GLB_UART2_IO_SEL_MSK (((1U << GLB_UART2_IO_SEL_LEN) - 1) << GLB_UART2_IO_SEL_POS) +#define GLB_UART2_IO_SEL_UMSK (~(((1U << GLB_UART2_IO_SEL_LEN) - 1) << GLB_UART2_IO_SEL_POS)) + +/* 0x154 : uart_cfg1 */ +#define GLB_UART_CFG1_OFFSET (0x154) +#define GLB_UART_SIG_0_SEL GLB_UART_SIG_0_SEL +#define GLB_UART_SIG_0_SEL_POS (0U) +#define GLB_UART_SIG_0_SEL_LEN (4U) +#define GLB_UART_SIG_0_SEL_MSK (((1U << GLB_UART_SIG_0_SEL_LEN) - 1) << GLB_UART_SIG_0_SEL_POS) +#define GLB_UART_SIG_0_SEL_UMSK (~(((1U << GLB_UART_SIG_0_SEL_LEN) - 1) << GLB_UART_SIG_0_SEL_POS)) +#define GLB_UART_SIG_1_SEL GLB_UART_SIG_1_SEL +#define GLB_UART_SIG_1_SEL_POS (4U) +#define GLB_UART_SIG_1_SEL_LEN (4U) +#define GLB_UART_SIG_1_SEL_MSK (((1U << GLB_UART_SIG_1_SEL_LEN) - 1) << GLB_UART_SIG_1_SEL_POS) +#define GLB_UART_SIG_1_SEL_UMSK (~(((1U << GLB_UART_SIG_1_SEL_LEN) - 1) << GLB_UART_SIG_1_SEL_POS)) +#define GLB_UART_SIG_2_SEL GLB_UART_SIG_2_SEL +#define GLB_UART_SIG_2_SEL_POS (8U) +#define GLB_UART_SIG_2_SEL_LEN (4U) +#define GLB_UART_SIG_2_SEL_MSK (((1U << GLB_UART_SIG_2_SEL_LEN) - 1) << GLB_UART_SIG_2_SEL_POS) +#define GLB_UART_SIG_2_SEL_UMSK (~(((1U << GLB_UART_SIG_2_SEL_LEN) - 1) << GLB_UART_SIG_2_SEL_POS)) +#define GLB_UART_SIG_3_SEL GLB_UART_SIG_3_SEL +#define GLB_UART_SIG_3_SEL_POS (12U) +#define GLB_UART_SIG_3_SEL_LEN (4U) +#define GLB_UART_SIG_3_SEL_MSK (((1U << GLB_UART_SIG_3_SEL_LEN) - 1) << GLB_UART_SIG_3_SEL_POS) +#define GLB_UART_SIG_3_SEL_UMSK (~(((1U << GLB_UART_SIG_3_SEL_LEN) - 1) << GLB_UART_SIG_3_SEL_POS)) +#define GLB_UART_SIG_4_SEL GLB_UART_SIG_4_SEL +#define GLB_UART_SIG_4_SEL_POS (16U) +#define GLB_UART_SIG_4_SEL_LEN (4U) +#define GLB_UART_SIG_4_SEL_MSK (((1U << GLB_UART_SIG_4_SEL_LEN) - 1) << GLB_UART_SIG_4_SEL_POS) +#define GLB_UART_SIG_4_SEL_UMSK (~(((1U << GLB_UART_SIG_4_SEL_LEN) - 1) << GLB_UART_SIG_4_SEL_POS)) +#define GLB_UART_SIG_5_SEL GLB_UART_SIG_5_SEL +#define GLB_UART_SIG_5_SEL_POS (20U) +#define GLB_UART_SIG_5_SEL_LEN (4U) +#define GLB_UART_SIG_5_SEL_MSK (((1U << GLB_UART_SIG_5_SEL_LEN) - 1) << GLB_UART_SIG_5_SEL_POS) +#define GLB_UART_SIG_5_SEL_UMSK (~(((1U << GLB_UART_SIG_5_SEL_LEN) - 1) << GLB_UART_SIG_5_SEL_POS)) +#define GLB_UART_SIG_6_SEL GLB_UART_SIG_6_SEL +#define GLB_UART_SIG_6_SEL_POS (24U) +#define GLB_UART_SIG_6_SEL_LEN (4U) +#define GLB_UART_SIG_6_SEL_MSK (((1U << GLB_UART_SIG_6_SEL_LEN) - 1) << GLB_UART_SIG_6_SEL_POS) +#define GLB_UART_SIG_6_SEL_UMSK (~(((1U << GLB_UART_SIG_6_SEL_LEN) - 1) << GLB_UART_SIG_6_SEL_POS)) +#define GLB_UART_SIG_7_SEL GLB_UART_SIG_7_SEL +#define GLB_UART_SIG_7_SEL_POS (28U) +#define GLB_UART_SIG_7_SEL_LEN (4U) +#define GLB_UART_SIG_7_SEL_MSK (((1U << GLB_UART_SIG_7_SEL_LEN) - 1) << GLB_UART_SIG_7_SEL_POS) +#define GLB_UART_SIG_7_SEL_UMSK (~(((1U << GLB_UART_SIG_7_SEL_LEN) - 1) << GLB_UART_SIG_7_SEL_POS)) + +/* 0x158 : uart_cfg2 */ +#define GLB_UART_CFG2_OFFSET (0x158) +#define GLB_UART_SIG_8_SEL GLB_UART_SIG_8_SEL +#define GLB_UART_SIG_8_SEL_POS (0U) +#define GLB_UART_SIG_8_SEL_LEN (4U) +#define GLB_UART_SIG_8_SEL_MSK (((1U << GLB_UART_SIG_8_SEL_LEN) - 1) << GLB_UART_SIG_8_SEL_POS) +#define GLB_UART_SIG_8_SEL_UMSK (~(((1U << GLB_UART_SIG_8_SEL_LEN) - 1) << GLB_UART_SIG_8_SEL_POS)) +#define GLB_UART_SIG_9_SEL GLB_UART_SIG_9_SEL +#define GLB_UART_SIG_9_SEL_POS (4U) +#define GLB_UART_SIG_9_SEL_LEN (4U) +#define GLB_UART_SIG_9_SEL_MSK (((1U << GLB_UART_SIG_9_SEL_LEN) - 1) << GLB_UART_SIG_9_SEL_POS) +#define GLB_UART_SIG_9_SEL_UMSK (~(((1U << GLB_UART_SIG_9_SEL_LEN) - 1) << GLB_UART_SIG_9_SEL_POS)) +#define GLB_UART_SIG_10_SEL GLB_UART_SIG_10_SEL +#define GLB_UART_SIG_10_SEL_POS (8U) +#define GLB_UART_SIG_10_SEL_LEN (4U) +#define GLB_UART_SIG_10_SEL_MSK (((1U << GLB_UART_SIG_10_SEL_LEN) - 1) << GLB_UART_SIG_10_SEL_POS) +#define GLB_UART_SIG_10_SEL_UMSK (~(((1U << GLB_UART_SIG_10_SEL_LEN) - 1) << GLB_UART_SIG_10_SEL_POS)) +#define GLB_UART_SIG_11_SEL GLB_UART_SIG_11_SEL +#define GLB_UART_SIG_11_SEL_POS (12U) +#define GLB_UART_SIG_11_SEL_LEN (4U) +#define GLB_UART_SIG_11_SEL_MSK (((1U << GLB_UART_SIG_11_SEL_LEN) - 1) << GLB_UART_SIG_11_SEL_POS) +#define GLB_UART_SIG_11_SEL_UMSK (~(((1U << GLB_UART_SIG_11_SEL_LEN) - 1) << GLB_UART_SIG_11_SEL_POS)) + +/* 0x170 : sf_cfg0 */ +#define GLB_SF_CFG0_OFFSET (0x170) +#define GLB_SF_CLK_DIV GLB_SF_CLK_DIV +#define GLB_SF_CLK_DIV_POS (8U) +#define GLB_SF_CLK_DIV_LEN (3U) +#define GLB_SF_CLK_DIV_MSK (((1U << GLB_SF_CLK_DIV_LEN) - 1) << GLB_SF_CLK_DIV_POS) +#define GLB_SF_CLK_DIV_UMSK (~(((1U << GLB_SF_CLK_DIV_LEN) - 1) << GLB_SF_CLK_DIV_POS)) +#define GLB_SF_CLK_EN GLB_SF_CLK_EN +#define GLB_SF_CLK_EN_POS (11U) +#define GLB_SF_CLK_EN_LEN (1U) +#define GLB_SF_CLK_EN_MSK (((1U << GLB_SF_CLK_EN_LEN) - 1) << GLB_SF_CLK_EN_POS) +#define GLB_SF_CLK_EN_UMSK (~(((1U << GLB_SF_CLK_EN_LEN) - 1) << GLB_SF_CLK_EN_POS)) +#define GLB_SF_CLK_SEL GLB_SF_CLK_SEL +#define GLB_SF_CLK_SEL_POS (12U) +#define GLB_SF_CLK_SEL_LEN (2U) +#define GLB_SF_CLK_SEL_MSK (((1U << GLB_SF_CLK_SEL_LEN) - 1) << GLB_SF_CLK_SEL_POS) +#define GLB_SF_CLK_SEL_UMSK (~(((1U << GLB_SF_CLK_SEL_LEN) - 1) << GLB_SF_CLK_SEL_POS)) +#define GLB_SF_CLK_SEL2 GLB_SF_CLK_SEL2 +#define GLB_SF_CLK_SEL2_POS (14U) +#define GLB_SF_CLK_SEL2_LEN (2U) +#define GLB_SF_CLK_SEL2_MSK (((1U << GLB_SF_CLK_SEL2_LEN) - 1) << GLB_SF_CLK_SEL2_POS) +#define GLB_SF_CLK_SEL2_UMSK (~(((1U << GLB_SF_CLK_SEL2_LEN) - 1) << GLB_SF_CLK_SEL2_POS)) + +/* 0x180 : i2c_cfg0 */ +#define GLB_I2C_CFG0_OFFSET (0x180) +#define GLB_I2C_CLK_DIV GLB_I2C_CLK_DIV +#define GLB_I2C_CLK_DIV_POS (16U) +#define GLB_I2C_CLK_DIV_LEN (8U) +#define GLB_I2C_CLK_DIV_MSK (((1U << GLB_I2C_CLK_DIV_LEN) - 1) << GLB_I2C_CLK_DIV_POS) +#define GLB_I2C_CLK_DIV_UMSK (~(((1U << GLB_I2C_CLK_DIV_LEN) - 1) << GLB_I2C_CLK_DIV_POS)) +#define GLB_I2C_CLK_EN GLB_I2C_CLK_EN +#define GLB_I2C_CLK_EN_POS (24U) +#define GLB_I2C_CLK_EN_LEN (1U) +#define GLB_I2C_CLK_EN_MSK (((1U << GLB_I2C_CLK_EN_LEN) - 1) << GLB_I2C_CLK_EN_POS) +#define GLB_I2C_CLK_EN_UMSK (~(((1U << GLB_I2C_CLK_EN_LEN) - 1) << GLB_I2C_CLK_EN_POS)) +#define GLB_I2C_CLK_SEL GLB_I2C_CLK_SEL +#define GLB_I2C_CLK_SEL_POS (25U) +#define GLB_I2C_CLK_SEL_LEN (1U) +#define GLB_I2C_CLK_SEL_MSK (((1U << GLB_I2C_CLK_SEL_LEN) - 1) << GLB_I2C_CLK_SEL_POS) +#define GLB_I2C_CLK_SEL_UMSK (~(((1U << GLB_I2C_CLK_SEL_LEN) - 1) << GLB_I2C_CLK_SEL_POS)) + +/* 0x190 : i2s_cfg0 */ +#define GLB_I2S_CFG0_OFFSET (0x190) +#define GLB_REG_I2S_REF_CLK_DIV GLB_REG_I2S_REF_CLK_DIV +#define GLB_REG_I2S_REF_CLK_DIV_POS (0U) +#define GLB_REG_I2S_REF_CLK_DIV_LEN (6U) +#define GLB_REG_I2S_REF_CLK_DIV_MSK (((1U << GLB_REG_I2S_REF_CLK_DIV_LEN) - 1) << GLB_REG_I2S_REF_CLK_DIV_POS) +#define GLB_REG_I2S_REF_CLK_DIV_UMSK (~(((1U << GLB_REG_I2S_REF_CLK_DIV_LEN) - 1) << GLB_REG_I2S_REF_CLK_DIV_POS)) +#define GLB_REG_I2S_DI_REF_CLK_SEL GLB_REG_I2S_DI_REF_CLK_SEL +#define GLB_REG_I2S_DI_REF_CLK_SEL_POS (6U) +#define GLB_REG_I2S_DI_REF_CLK_SEL_LEN (1U) +#define GLB_REG_I2S_DI_REF_CLK_SEL_MSK (((1U << GLB_REG_I2S_DI_REF_CLK_SEL_LEN) - 1) << GLB_REG_I2S_DI_REF_CLK_SEL_POS) +#define GLB_REG_I2S_DI_REF_CLK_SEL_UMSK (~(((1U << GLB_REG_I2S_DI_REF_CLK_SEL_LEN) - 1) << GLB_REG_I2S_DI_REF_CLK_SEL_POS)) +#define GLB_REG_I2S_REF_CLK_EN GLB_REG_I2S_REF_CLK_EN +#define GLB_REG_I2S_REF_CLK_EN_POS (7U) +#define GLB_REG_I2S_REF_CLK_EN_LEN (1U) +#define GLB_REG_I2S_REF_CLK_EN_MSK (((1U << GLB_REG_I2S_REF_CLK_EN_LEN) - 1) << GLB_REG_I2S_REF_CLK_EN_POS) +#define GLB_REG_I2S_REF_CLK_EN_UMSK (~(((1U << GLB_REG_I2S_REF_CLK_EN_LEN) - 1) << GLB_REG_I2S_REF_CLK_EN_POS)) +#define GLB_REG_I2S_DO_REF_CLK_SEL GLB_REG_I2S_DO_REF_CLK_SEL +#define GLB_REG_I2S_DO_REF_CLK_SEL_POS (8U) +#define GLB_REG_I2S_DO_REF_CLK_SEL_LEN (1U) +#define GLB_REG_I2S_DO_REF_CLK_SEL_MSK (((1U << GLB_REG_I2S_DO_REF_CLK_SEL_LEN) - 1) << GLB_REG_I2S_DO_REF_CLK_SEL_POS) +#define GLB_REG_I2S_DO_REF_CLK_SEL_UMSK (~(((1U << GLB_REG_I2S_DO_REF_CLK_SEL_LEN) - 1) << GLB_REG_I2S_DO_REF_CLK_SEL_POS)) + +/* 0x1B0 : spi_cfg0 */ +#define GLB_SPI_CFG0_OFFSET (0x1B0) +#define GLB_SPI_CLK_DIV GLB_SPI_CLK_DIV +#define GLB_SPI_CLK_DIV_POS (0U) +#define GLB_SPI_CLK_DIV_LEN (5U) +#define GLB_SPI_CLK_DIV_MSK (((1U << GLB_SPI_CLK_DIV_LEN) - 1) << GLB_SPI_CLK_DIV_POS) +#define GLB_SPI_CLK_DIV_UMSK (~(((1U << GLB_SPI_CLK_DIV_LEN) - 1) << GLB_SPI_CLK_DIV_POS)) +#define GLB_SPI_CLK_EN GLB_SPI_CLK_EN +#define GLB_SPI_CLK_EN_POS (8U) +#define GLB_SPI_CLK_EN_LEN (1U) +#define GLB_SPI_CLK_EN_MSK (((1U << GLB_SPI_CLK_EN_LEN) - 1) << GLB_SPI_CLK_EN_POS) +#define GLB_SPI_CLK_EN_UMSK (~(((1U << GLB_SPI_CLK_EN_LEN) - 1) << GLB_SPI_CLK_EN_POS)) +#define GLB_SPI_CLK_SEL GLB_SPI_CLK_SEL +#define GLB_SPI_CLK_SEL_POS (9U) +#define GLB_SPI_CLK_SEL_LEN (1U) +#define GLB_SPI_CLK_SEL_MSK (((1U << GLB_SPI_CLK_SEL_LEN) - 1) << GLB_SPI_CLK_SEL_POS) +#define GLB_SPI_CLK_SEL_UMSK (~(((1U << GLB_SPI_CLK_SEL_LEN) - 1) << GLB_SPI_CLK_SEL_POS)) +#define GLB_SPI_SWAP_SET GLB_SPI_SWAP_SET +#define GLB_SPI_SWAP_SET_POS (16U) +#define GLB_SPI_SWAP_SET_LEN (4U) +#define GLB_SPI_SWAP_SET_MSK (((1U << GLB_SPI_SWAP_SET_LEN) - 1) << GLB_SPI_SWAP_SET_POS) +#define GLB_SPI_SWAP_SET_UMSK (~(((1U << GLB_SPI_SWAP_SET_LEN) - 1) << GLB_SPI_SWAP_SET_POS)) + +/* 0x1C0 : qdec_cfg0 */ +#define GLB_QDEC_CFG0_OFFSET (0x1C0) + +/* 0x1D0 : pwm_cfg0 */ +#define GLB_PWM_CFG0_OFFSET (0x1D0) +#define GLB_REG_PWM1_IO_SEL GLB_REG_PWM1_IO_SEL +#define GLB_REG_PWM1_IO_SEL_POS (0U) +#define GLB_REG_PWM1_IO_SEL_LEN (1U) +#define GLB_REG_PWM1_IO_SEL_MSK (((1U << GLB_REG_PWM1_IO_SEL_LEN) - 1) << GLB_REG_PWM1_IO_SEL_POS) +#define GLB_REG_PWM1_IO_SEL_UMSK (~(((1U << GLB_REG_PWM1_IO_SEL_LEN) - 1) << GLB_REG_PWM1_IO_SEL_POS)) +#define GLB_REG_PWM2_IO_SEL GLB_REG_PWM2_IO_SEL +#define GLB_REG_PWM2_IO_SEL_POS (1U) +#define GLB_REG_PWM2_IO_SEL_LEN (1U) +#define GLB_REG_PWM2_IO_SEL_MSK (((1U << GLB_REG_PWM2_IO_SEL_LEN) - 1) << GLB_REG_PWM2_IO_SEL_POS) +#define GLB_REG_PWM2_IO_SEL_UMSK (~(((1U << GLB_REG_PWM2_IO_SEL_LEN) - 1) << GLB_REG_PWM2_IO_SEL_POS)) + +/* 0x1E0 : pdm_cfg0 */ +#define GLB_PDM_CFG0_OFFSET (0x1E0) +#define GLB_REG_PDM_IO_SEL GLB_REG_PDM_IO_SEL +#define GLB_REG_PDM_IO_SEL_POS (0U) +#define GLB_REG_PDM_IO_SEL_LEN (1U) +#define GLB_REG_PDM_IO_SEL_MSK (((1U << GLB_REG_PDM_IO_SEL_LEN) - 1) << GLB_REG_PDM_IO_SEL_POS) +#define GLB_REG_PDM_IO_SEL_UMSK (~(((1U << GLB_REG_PDM_IO_SEL_LEN) - 1) << GLB_REG_PDM_IO_SEL_POS)) + +/* 0x250 : dig_clk_cfg0 */ +#define GLB_DIG_CLK_CFG0_OFFSET (0x250) +#define GLB_DIG_32K_DIV GLB_DIG_32K_DIV +#define GLB_DIG_32K_DIV_POS (0U) +#define GLB_DIG_32K_DIV_LEN (11U) +#define GLB_DIG_32K_DIV_MSK (((1U << GLB_DIG_32K_DIV_LEN) - 1) << GLB_DIG_32K_DIV_POS) +#define GLB_DIG_32K_DIV_UMSK (~(((1U << GLB_DIG_32K_DIV_LEN) - 1) << GLB_DIG_32K_DIV_POS)) +#define GLB_DIG_32K_EN GLB_DIG_32K_EN +#define GLB_DIG_32K_EN_POS (12U) +#define GLB_DIG_32K_EN_LEN (1U) +#define GLB_DIG_32K_EN_MSK (((1U << GLB_DIG_32K_EN_LEN) - 1) << GLB_DIG_32K_EN_POS) +#define GLB_DIG_32K_EN_UMSK (~(((1U << GLB_DIG_32K_EN_LEN) - 1) << GLB_DIG_32K_EN_POS)) +#define GLB_DIG_32K_COMP GLB_DIG_32K_COMP +#define GLB_DIG_32K_COMP_POS (13U) +#define GLB_DIG_32K_COMP_LEN (1U) +#define GLB_DIG_32K_COMP_MSK (((1U << GLB_DIG_32K_COMP_LEN) - 1) << GLB_DIG_32K_COMP_POS) +#define GLB_DIG_32K_COMP_UMSK (~(((1U << GLB_DIG_32K_COMP_LEN) - 1) << GLB_DIG_32K_COMP_POS)) +#define GLB_DIG_512K_DIV GLB_DIG_512K_DIV +#define GLB_DIG_512K_DIV_POS (16U) +#define GLB_DIG_512K_DIV_LEN (7U) +#define GLB_DIG_512K_DIV_MSK (((1U << GLB_DIG_512K_DIV_LEN) - 1) << GLB_DIG_512K_DIV_POS) +#define GLB_DIG_512K_DIV_UMSK (~(((1U << GLB_DIG_512K_DIV_LEN) - 1) << GLB_DIG_512K_DIV_POS)) +#define GLB_DIG_512K_EN GLB_DIG_512K_EN +#define GLB_DIG_512K_EN_POS (24U) +#define GLB_DIG_512K_EN_LEN (1U) +#define GLB_DIG_512K_EN_MSK (((1U << GLB_DIG_512K_EN_LEN) - 1) << GLB_DIG_512K_EN_POS) +#define GLB_DIG_512K_EN_UMSK (~(((1U << GLB_DIG_512K_EN_LEN) - 1) << GLB_DIG_512K_EN_POS)) +#define GLB_DIG_512K_COMP GLB_DIG_512K_COMP +#define GLB_DIG_512K_COMP_POS (25U) +#define GLB_DIG_512K_COMP_LEN (1U) +#define GLB_DIG_512K_COMP_MSK (((1U << GLB_DIG_512K_COMP_LEN) - 1) << GLB_DIG_512K_COMP_POS) +#define GLB_DIG_512K_COMP_UMSK (~(((1U << GLB_DIG_512K_COMP_LEN) - 1) << GLB_DIG_512K_COMP_POS)) +#define GLB_DIG_CLK_SRC_SEL GLB_DIG_CLK_SRC_SEL +#define GLB_DIG_CLK_SRC_SEL_POS (28U) +#define GLB_DIG_CLK_SRC_SEL_LEN (2U) +#define GLB_DIG_CLK_SRC_SEL_MSK (((1U << GLB_DIG_CLK_SRC_SEL_LEN) - 1) << GLB_DIG_CLK_SRC_SEL_POS) +#define GLB_DIG_CLK_SRC_SEL_UMSK (~(((1U << GLB_DIG_CLK_SRC_SEL_LEN) - 1) << GLB_DIG_CLK_SRC_SEL_POS)) +#define GLB_REG_EN_PLATFORM_WAKEUP GLB_REG_EN_PLATFORM_WAKEUP +#define GLB_REG_EN_PLATFORM_WAKEUP_POS (31U) +#define GLB_REG_EN_PLATFORM_WAKEUP_LEN (1U) +#define GLB_REG_EN_PLATFORM_WAKEUP_MSK (((1U << GLB_REG_EN_PLATFORM_WAKEUP_LEN) - 1) << GLB_REG_EN_PLATFORM_WAKEUP_POS) +#define GLB_REG_EN_PLATFORM_WAKEUP_UMSK (~(((1U << GLB_REG_EN_PLATFORM_WAKEUP_LEN) - 1) << GLB_REG_EN_PLATFORM_WAKEUP_POS)) + +/* 0x254 : dig_clk_cfg1 */ +#define GLB_DIG_CLK_CFG1_OFFSET (0x254) +#define GLB_REG_MM_MUXPLL_160M_SEL GLB_REG_MM_MUXPLL_160M_SEL +#define GLB_REG_MM_MUXPLL_160M_SEL_POS (0U) +#define GLB_REG_MM_MUXPLL_160M_SEL_LEN (1U) +#define GLB_REG_MM_MUXPLL_160M_SEL_MSK (((1U << GLB_REG_MM_MUXPLL_160M_SEL_LEN) - 1) << GLB_REG_MM_MUXPLL_160M_SEL_POS) +#define GLB_REG_MM_MUXPLL_160M_SEL_UMSK (~(((1U << GLB_REG_MM_MUXPLL_160M_SEL_LEN) - 1) << GLB_REG_MM_MUXPLL_160M_SEL_POS)) +#define GLB_REG_MM_MUXPLL_240M_SEL GLB_REG_MM_MUXPLL_240M_SEL +#define GLB_REG_MM_MUXPLL_240M_SEL_POS (1U) +#define GLB_REG_MM_MUXPLL_240M_SEL_LEN (1U) +#define GLB_REG_MM_MUXPLL_240M_SEL_MSK (((1U << GLB_REG_MM_MUXPLL_240M_SEL_LEN) - 1) << GLB_REG_MM_MUXPLL_240M_SEL_POS) +#define GLB_REG_MM_MUXPLL_240M_SEL_UMSK (~(((1U << GLB_REG_MM_MUXPLL_240M_SEL_LEN) - 1) << GLB_REG_MM_MUXPLL_240M_SEL_POS)) +#define GLB_REG_MM_MUXPLL_320M_SEL GLB_REG_MM_MUXPLL_320M_SEL +#define GLB_REG_MM_MUXPLL_320M_SEL_POS (2U) +#define GLB_REG_MM_MUXPLL_320M_SEL_LEN (1U) +#define GLB_REG_MM_MUXPLL_320M_SEL_MSK (((1U << GLB_REG_MM_MUXPLL_320M_SEL_LEN) - 1) << GLB_REG_MM_MUXPLL_320M_SEL_POS) +#define GLB_REG_MM_MUXPLL_320M_SEL_UMSK (~(((1U << GLB_REG_MM_MUXPLL_320M_SEL_LEN) - 1) << GLB_REG_MM_MUXPLL_320M_SEL_POS)) +#define GLB_REG_TOP_MUXPLL_80M_SEL GLB_REG_TOP_MUXPLL_80M_SEL +#define GLB_REG_TOP_MUXPLL_80M_SEL_POS (8U) +#define GLB_REG_TOP_MUXPLL_80M_SEL_LEN (2U) +#define GLB_REG_TOP_MUXPLL_80M_SEL_MSK (((1U << GLB_REG_TOP_MUXPLL_80M_SEL_LEN) - 1) << GLB_REG_TOP_MUXPLL_80M_SEL_POS) +#define GLB_REG_TOP_MUXPLL_80M_SEL_UMSK (~(((1U << GLB_REG_TOP_MUXPLL_80M_SEL_LEN) - 1) << GLB_REG_TOP_MUXPLL_80M_SEL_POS)) +#define GLB_REG_TOP_MUXPLL_160M_SEL GLB_REG_TOP_MUXPLL_160M_SEL +#define GLB_REG_TOP_MUXPLL_160M_SEL_POS (10U) +#define GLB_REG_TOP_MUXPLL_160M_SEL_LEN (2U) +#define GLB_REG_TOP_MUXPLL_160M_SEL_MSK (((1U << GLB_REG_TOP_MUXPLL_160M_SEL_LEN) - 1) << GLB_REG_TOP_MUXPLL_160M_SEL_POS) +#define GLB_REG_TOP_MUXPLL_160M_SEL_UMSK (~(((1U << GLB_REG_TOP_MUXPLL_160M_SEL_LEN) - 1) << GLB_REG_TOP_MUXPLL_160M_SEL_POS)) + +/* 0x258 : dig_clk_cfg2 */ +#define GLB_DIG_CLK_CFG2_OFFSET (0x258) +#define GLB_CHIP_CLK_OUT_0_SEL GLB_CHIP_CLK_OUT_0_SEL +#define GLB_CHIP_CLK_OUT_0_SEL_POS (0U) +#define GLB_CHIP_CLK_OUT_0_SEL_LEN (2U) +#define GLB_CHIP_CLK_OUT_0_SEL_MSK (((1U << GLB_CHIP_CLK_OUT_0_SEL_LEN) - 1) << GLB_CHIP_CLK_OUT_0_SEL_POS) +#define GLB_CHIP_CLK_OUT_0_SEL_UMSK (~(((1U << GLB_CHIP_CLK_OUT_0_SEL_LEN) - 1) << GLB_CHIP_CLK_OUT_0_SEL_POS)) +#define GLB_CHIP_CLK_OUT_1_SEL GLB_CHIP_CLK_OUT_1_SEL +#define GLB_CHIP_CLK_OUT_1_SEL_POS (2U) +#define GLB_CHIP_CLK_OUT_1_SEL_LEN (2U) +#define GLB_CHIP_CLK_OUT_1_SEL_MSK (((1U << GLB_CHIP_CLK_OUT_1_SEL_LEN) - 1) << GLB_CHIP_CLK_OUT_1_SEL_POS) +#define GLB_CHIP_CLK_OUT_1_SEL_UMSK (~(((1U << GLB_CHIP_CLK_OUT_1_SEL_LEN) - 1) << GLB_CHIP_CLK_OUT_1_SEL_POS)) +#define GLB_CHIP_CLK_OUT_2_SEL GLB_CHIP_CLK_OUT_2_SEL +#define GLB_CHIP_CLK_OUT_2_SEL_POS (4U) +#define GLB_CHIP_CLK_OUT_2_SEL_LEN (2U) +#define GLB_CHIP_CLK_OUT_2_SEL_MSK (((1U << GLB_CHIP_CLK_OUT_2_SEL_LEN) - 1) << GLB_CHIP_CLK_OUT_2_SEL_POS) +#define GLB_CHIP_CLK_OUT_2_SEL_UMSK (~(((1U << GLB_CHIP_CLK_OUT_2_SEL_LEN) - 1) << GLB_CHIP_CLK_OUT_2_SEL_POS)) +#define GLB_CHIP_CLK_OUT_3_SEL GLB_CHIP_CLK_OUT_3_SEL +#define GLB_CHIP_CLK_OUT_3_SEL_POS (6U) +#define GLB_CHIP_CLK_OUT_3_SEL_LEN (2U) +#define GLB_CHIP_CLK_OUT_3_SEL_MSK (((1U << GLB_CHIP_CLK_OUT_3_SEL_LEN) - 1) << GLB_CHIP_CLK_OUT_3_SEL_POS) +#define GLB_CHIP_CLK_OUT_3_SEL_UMSK (~(((1U << GLB_CHIP_CLK_OUT_3_SEL_LEN) - 1) << GLB_CHIP_CLK_OUT_3_SEL_POS)) +#define GLB_CHIP_CLK_OUT_0_EN GLB_CHIP_CLK_OUT_0_EN +#define GLB_CHIP_CLK_OUT_0_EN_POS (8U) +#define GLB_CHIP_CLK_OUT_0_EN_LEN (1U) +#define GLB_CHIP_CLK_OUT_0_EN_MSK (((1U << GLB_CHIP_CLK_OUT_0_EN_LEN) - 1) << GLB_CHIP_CLK_OUT_0_EN_POS) +#define GLB_CHIP_CLK_OUT_0_EN_UMSK (~(((1U << GLB_CHIP_CLK_OUT_0_EN_LEN) - 1) << GLB_CHIP_CLK_OUT_0_EN_POS)) +#define GLB_CHIP_CLK_OUT_1_EN GLB_CHIP_CLK_OUT_1_EN +#define GLB_CHIP_CLK_OUT_1_EN_POS (9U) +#define GLB_CHIP_CLK_OUT_1_EN_LEN (1U) +#define GLB_CHIP_CLK_OUT_1_EN_MSK (((1U << GLB_CHIP_CLK_OUT_1_EN_LEN) - 1) << GLB_CHIP_CLK_OUT_1_EN_POS) +#define GLB_CHIP_CLK_OUT_1_EN_UMSK (~(((1U << GLB_CHIP_CLK_OUT_1_EN_LEN) - 1) << GLB_CHIP_CLK_OUT_1_EN_POS)) +#define GLB_CHIP_CLK_OUT_2_EN GLB_CHIP_CLK_OUT_2_EN +#define GLB_CHIP_CLK_OUT_2_EN_POS (10U) +#define GLB_CHIP_CLK_OUT_2_EN_LEN (1U) +#define GLB_CHIP_CLK_OUT_2_EN_MSK (((1U << GLB_CHIP_CLK_OUT_2_EN_LEN) - 1) << GLB_CHIP_CLK_OUT_2_EN_POS) +#define GLB_CHIP_CLK_OUT_2_EN_UMSK (~(((1U << GLB_CHIP_CLK_OUT_2_EN_LEN) - 1) << GLB_CHIP_CLK_OUT_2_EN_POS)) +#define GLB_CHIP_CLK_OUT_3_EN GLB_CHIP_CLK_OUT_3_EN +#define GLB_CHIP_CLK_OUT_3_EN_POS (11U) +#define GLB_CHIP_CLK_OUT_3_EN_LEN (1U) +#define GLB_CHIP_CLK_OUT_3_EN_MSK (((1U << GLB_CHIP_CLK_OUT_3_EN_LEN) - 1) << GLB_CHIP_CLK_OUT_3_EN_POS) +#define GLB_CHIP_CLK_OUT_3_EN_UMSK (~(((1U << GLB_CHIP_CLK_OUT_3_EN_LEN) - 1) << GLB_CHIP_CLK_OUT_3_EN_POS)) +#define GLB_GPIO_TMR_CLK_SEL GLB_GPIO_TMR_CLK_SEL +#define GLB_GPIO_TMR_CLK_SEL_POS (12U) +#define GLB_GPIO_TMR_CLK_SEL_LEN (2U) +#define GLB_GPIO_TMR_CLK_SEL_MSK (((1U << GLB_GPIO_TMR_CLK_SEL_LEN) - 1) << GLB_GPIO_TMR_CLK_SEL_POS) +#define GLB_GPIO_TMR_CLK_SEL_UMSK (~(((1U << GLB_GPIO_TMR_CLK_SEL_LEN) - 1) << GLB_GPIO_TMR_CLK_SEL_POS)) +#define GLB_GPIO_MM_TMR_CLK_SEL GLB_GPIO_MM_TMR_CLK_SEL +#define GLB_GPIO_MM_TMR_CLK_SEL_POS (14U) +#define GLB_GPIO_MM_TMR_CLK_SEL_LEN (2U) +#define GLB_GPIO_MM_TMR_CLK_SEL_MSK (((1U << GLB_GPIO_MM_TMR_CLK_SEL_LEN) - 1) << GLB_GPIO_MM_TMR_CLK_SEL_POS) +#define GLB_GPIO_MM_TMR_CLK_SEL_UMSK (~(((1U << GLB_GPIO_MM_TMR_CLK_SEL_LEN) - 1) << GLB_GPIO_MM_TMR_CLK_SEL_POS)) + +/* 0x25C : dig_clk_cfg3 */ +#define GLB_DIG_CLK_CFG3_OFFSET (0x25C) +#define GLB_DSI_TXCLKESC_SEL GLB_DSI_TXCLKESC_SEL +#define GLB_DSI_TXCLKESC_SEL_POS (0U) +#define GLB_DSI_TXCLKESC_SEL_LEN (1U) +#define GLB_DSI_TXCLKESC_SEL_MSK (((1U << GLB_DSI_TXCLKESC_SEL_LEN) - 1) << GLB_DSI_TXCLKESC_SEL_POS) +#define GLB_DSI_TXCLKESC_SEL_UMSK (~(((1U << GLB_DSI_TXCLKESC_SEL_LEN) - 1) << GLB_DSI_TXCLKESC_SEL_POS)) +#define GLB_CSI_TXCLKESC_SEL GLB_CSI_TXCLKESC_SEL +#define GLB_CSI_TXCLKESC_SEL_POS (1U) +#define GLB_CSI_TXCLKESC_SEL_LEN (1U) +#define GLB_CSI_TXCLKESC_SEL_MSK (((1U << GLB_CSI_TXCLKESC_SEL_LEN) - 1) << GLB_CSI_TXCLKESC_SEL_POS) +#define GLB_CSI_TXCLKESC_SEL_UMSK (~(((1U << GLB_CSI_TXCLKESC_SEL_LEN) - 1) << GLB_CSI_TXCLKESC_SEL_POS)) + +/* 0x260 : rf_cfg0 */ +#define GLB_RF_CFG0_OFFSET (0x260) +#define GLB_CFG_INV_RF2_TEST_CLK_O GLB_CFG_INV_RF2_TEST_CLK_O +#define GLB_CFG_INV_RF2_TEST_CLK_O_POS (9U) +#define GLB_CFG_INV_RF2_TEST_CLK_O_LEN (1U) +#define GLB_CFG_INV_RF2_TEST_CLK_O_MSK (((1U << GLB_CFG_INV_RF2_TEST_CLK_O_LEN) - 1) << GLB_CFG_INV_RF2_TEST_CLK_O_POS) +#define GLB_CFG_INV_RF2_TEST_CLK_O_UMSK (~(((1U << GLB_CFG_INV_RF2_TEST_CLK_O_LEN) - 1) << GLB_CFG_INV_RF2_TEST_CLK_O_POS)) + +/* 0x2E0 : dbg_cfg0 */ +#define GLB_DBG_CFG0_OFFSET (0x2E0) +#define GLB_REG_DBG_LL_CTRL GLB_REG_DBG_LL_CTRL +#define GLB_REG_DBG_LL_CTRL_POS (0U) +#define GLB_REG_DBG_LL_CTRL_LEN (30U) +#define GLB_REG_DBG_LL_CTRL_MSK (((1U << GLB_REG_DBG_LL_CTRL_LEN) - 1) << GLB_REG_DBG_LL_CTRL_POS) +#define GLB_REG_DBG_LL_CTRL_UMSK (~(((1U << GLB_REG_DBG_LL_CTRL_LEN) - 1) << GLB_REG_DBG_LL_CTRL_POS)) +#define GLB_REG_DBG_LL_SEL GLB_REG_DBG_LL_SEL +#define GLB_REG_DBG_LL_SEL_POS (30U) +#define GLB_REG_DBG_LL_SEL_LEN (2U) +#define GLB_REG_DBG_LL_SEL_MSK (((1U << GLB_REG_DBG_LL_SEL_LEN) - 1) << GLB_REG_DBG_LL_SEL_POS) +#define GLB_REG_DBG_LL_SEL_UMSK (~(((1U << GLB_REG_DBG_LL_SEL_LEN) - 1) << GLB_REG_DBG_LL_SEL_POS)) + +/* 0x2E4 : dbg_cfg1 */ +#define GLB_DBG_CFG1_OFFSET (0x2E4) +#define GLB_REG_DBG_LH_CTRL GLB_REG_DBG_LH_CTRL +#define GLB_REG_DBG_LH_CTRL_POS (0U) +#define GLB_REG_DBG_LH_CTRL_LEN (30U) +#define GLB_REG_DBG_LH_CTRL_MSK (((1U << GLB_REG_DBG_LH_CTRL_LEN) - 1) << GLB_REG_DBG_LH_CTRL_POS) +#define GLB_REG_DBG_LH_CTRL_UMSK (~(((1U << GLB_REG_DBG_LH_CTRL_LEN) - 1) << GLB_REG_DBG_LH_CTRL_POS)) +#define GLB_REG_DBG_LH_SEL GLB_REG_DBG_LH_SEL +#define GLB_REG_DBG_LH_SEL_POS (30U) +#define GLB_REG_DBG_LH_SEL_LEN (2U) +#define GLB_REG_DBG_LH_SEL_MSK (((1U << GLB_REG_DBG_LH_SEL_LEN) - 1) << GLB_REG_DBG_LH_SEL_POS) +#define GLB_REG_DBG_LH_SEL_UMSK (~(((1U << GLB_REG_DBG_LH_SEL_LEN) - 1) << GLB_REG_DBG_LH_SEL_POS)) + +/* 0x2E8 : dbg_cfg2 */ +#define GLB_DBG_CFG2_OFFSET (0x2E8) +#define GLB_REG_DBG_HL_CTRL GLB_REG_DBG_HL_CTRL +#define GLB_REG_DBG_HL_CTRL_POS (0U) +#define GLB_REG_DBG_HL_CTRL_LEN (30U) +#define GLB_REG_DBG_HL_CTRL_MSK (((1U << GLB_REG_DBG_HL_CTRL_LEN) - 1) << GLB_REG_DBG_HL_CTRL_POS) +#define GLB_REG_DBG_HL_CTRL_UMSK (~(((1U << GLB_REG_DBG_HL_CTRL_LEN) - 1) << GLB_REG_DBG_HL_CTRL_POS)) +#define GLB_REG_DBG_HL_SEL GLB_REG_DBG_HL_SEL +#define GLB_REG_DBG_HL_SEL_POS (30U) +#define GLB_REG_DBG_HL_SEL_LEN (2U) +#define GLB_REG_DBG_HL_SEL_MSK (((1U << GLB_REG_DBG_HL_SEL_LEN) - 1) << GLB_REG_DBG_HL_SEL_POS) +#define GLB_REG_DBG_HL_SEL_UMSK (~(((1U << GLB_REG_DBG_HL_SEL_LEN) - 1) << GLB_REG_DBG_HL_SEL_POS)) + +/* 0x2EC : dbg_cfg3 */ +#define GLB_DBG_CFG3_OFFSET (0x2EC) +#define GLB_REG_DBG_HH_CTRL GLB_REG_DBG_HH_CTRL +#define GLB_REG_DBG_HH_CTRL_POS (0U) +#define GLB_REG_DBG_HH_CTRL_LEN (30U) +#define GLB_REG_DBG_HH_CTRL_MSK (((1U << GLB_REG_DBG_HH_CTRL_LEN) - 1) << GLB_REG_DBG_HH_CTRL_POS) +#define GLB_REG_DBG_HH_CTRL_UMSK (~(((1U << GLB_REG_DBG_HH_CTRL_LEN) - 1) << GLB_REG_DBG_HH_CTRL_POS)) +#define GLB_REG_DBG_HH_SEL GLB_REG_DBG_HH_SEL +#define GLB_REG_DBG_HH_SEL_POS (30U) +#define GLB_REG_DBG_HH_SEL_LEN (2U) +#define GLB_REG_DBG_HH_SEL_MSK (((1U << GLB_REG_DBG_HH_SEL_LEN) - 1) << GLB_REG_DBG_HH_SEL_POS) +#define GLB_REG_DBG_HH_SEL_UMSK (~(((1U << GLB_REG_DBG_HH_SEL_LEN) - 1) << GLB_REG_DBG_HH_SEL_POS)) + +/* 0x2F0 : dbg_cfg4 */ +#define GLB_DBG_CFG4_OFFSET (0x2F0) +#define GLB_DEBUG_OE GLB_DEBUG_OE +#define GLB_DEBUG_OE_POS (0U) +#define GLB_DEBUG_OE_LEN (1U) +#define GLB_DEBUG_OE_MSK (((1U << GLB_DEBUG_OE_LEN) - 1) << GLB_DEBUG_OE_POS) +#define GLB_DEBUG_OE_UMSK (~(((1U << GLB_DEBUG_OE_LEN) - 1) << GLB_DEBUG_OE_POS)) +#define GLB_DEBUG_I GLB_DEBUG_I +#define GLB_DEBUG_I_POS (1U) +#define GLB_DEBUG_I_LEN (31U) +#define GLB_DEBUG_I_MSK (((1U << GLB_DEBUG_I_LEN) - 1) << GLB_DEBUG_I_POS) +#define GLB_DEBUG_I_UMSK (~(((1U << GLB_DEBUG_I_LEN) - 1) << GLB_DEBUG_I_POS)) + +/* 0x300 : mbist_cfg0 */ +#define GLB_MBIST_CFG0_OFFSET (0x300) +#define GLB_MBIST_MODE GLB_MBIST_MODE +#define GLB_MBIST_MODE_POS (0U) +#define GLB_MBIST_MODE_LEN (1U) +#define GLB_MBIST_MODE_MSK (((1U << GLB_MBIST_MODE_LEN) - 1) << GLB_MBIST_MODE_POS) +#define GLB_MBIST_MODE_UMSK (~(((1U << GLB_MBIST_MODE_LEN) - 1) << GLB_MBIST_MODE_POS)) + +/* 0x320 : bmx_cfg0 */ +#define GLB_BMX_CFG0_OFFSET (0x320) +#define GLB_REG_BMX_TIMEOUT_EN GLB_REG_BMX_TIMEOUT_EN +#define GLB_REG_BMX_TIMEOUT_EN_POS (0U) +#define GLB_REG_BMX_TIMEOUT_EN_LEN (5U) +#define GLB_REG_BMX_TIMEOUT_EN_MSK (((1U << GLB_REG_BMX_TIMEOUT_EN_LEN) - 1) << GLB_REG_BMX_TIMEOUT_EN_POS) +#define GLB_REG_BMX_TIMEOUT_EN_UMSK (~(((1U << GLB_REG_BMX_TIMEOUT_EN_LEN) - 1) << GLB_REG_BMX_TIMEOUT_EN_POS)) +#define GLB_REG_BMX_ARB_MODE GLB_REG_BMX_ARB_MODE +#define GLB_REG_BMX_ARB_MODE_POS (5U) +#define GLB_REG_BMX_ARB_MODE_LEN (1U) +#define GLB_REG_BMX_ARB_MODE_MSK (((1U << GLB_REG_BMX_ARB_MODE_LEN) - 1) << GLB_REG_BMX_ARB_MODE_POS) +#define GLB_REG_BMX_ARB_MODE_UMSK (~(((1U << GLB_REG_BMX_ARB_MODE_LEN) - 1) << GLB_REG_BMX_ARB_MODE_POS)) +#define GLB_REG_BMX_TIMEOUT_CLR GLB_REG_BMX_TIMEOUT_CLR +#define GLB_REG_BMX_TIMEOUT_CLR_POS (6U) +#define GLB_REG_BMX_TIMEOUT_CLR_LEN (1U) +#define GLB_REG_BMX_TIMEOUT_CLR_MSK (((1U << GLB_REG_BMX_TIMEOUT_CLR_LEN) - 1) << GLB_REG_BMX_TIMEOUT_CLR_POS) +#define GLB_REG_BMX_TIMEOUT_CLR_UMSK (~(((1U << GLB_REG_BMX_TIMEOUT_CLR_LEN) - 1) << GLB_REG_BMX_TIMEOUT_CLR_POS)) +#define GLB_REG_H_WTHRE_HW2EXT GLB_REG_H_WTHRE_HW2EXT +#define GLB_REG_H_WTHRE_HW2EXT_POS (7U) +#define GLB_REG_H_WTHRE_HW2EXT_LEN (2U) +#define GLB_REG_H_WTHRE_HW2EXT_MSK (((1U << GLB_REG_H_WTHRE_HW2EXT_LEN) - 1) << GLB_REG_H_WTHRE_HW2EXT_POS) +#define GLB_REG_H_WTHRE_HW2EXT_UMSK (~(((1U << GLB_REG_H_WTHRE_HW2EXT_LEN) - 1) << GLB_REG_H_WTHRE_HW2EXT_POS)) +#define GLB_BMX_BUSY_OPTION_DIS GLB_BMX_BUSY_OPTION_DIS +#define GLB_BMX_BUSY_OPTION_DIS_POS (9U) +#define GLB_BMX_BUSY_OPTION_DIS_LEN (1U) +#define GLB_BMX_BUSY_OPTION_DIS_MSK (((1U << GLB_BMX_BUSY_OPTION_DIS_LEN) - 1) << GLB_BMX_BUSY_OPTION_DIS_POS) +#define GLB_BMX_BUSY_OPTION_DIS_UMSK (~(((1U << GLB_BMX_BUSY_OPTION_DIS_LEN) - 1) << GLB_BMX_BUSY_OPTION_DIS_POS)) +#define GLB_BMX_GATING_DIS GLB_BMX_GATING_DIS +#define GLB_BMX_GATING_DIS_POS (10U) +#define GLB_BMX_GATING_DIS_LEN (1U) +#define GLB_BMX_GATING_DIS_MSK (((1U << GLB_BMX_GATING_DIS_LEN) - 1) << GLB_BMX_GATING_DIS_POS) +#define GLB_BMX_GATING_DIS_UMSK (~(((1U << GLB_BMX_GATING_DIS_LEN) - 1) << GLB_BMX_GATING_DIS_POS)) +#define GLB_STS_BMX_TIMEOUT_STS GLB_STS_BMX_TIMEOUT_STS +#define GLB_STS_BMX_TIMEOUT_STS_POS (11U) +#define GLB_STS_BMX_TIMEOUT_STS_LEN (5U) +#define GLB_STS_BMX_TIMEOUT_STS_MSK (((1U << GLB_STS_BMX_TIMEOUT_STS_LEN) - 1) << GLB_STS_BMX_TIMEOUT_STS_POS) +#define GLB_STS_BMX_TIMEOUT_STS_UMSK (~(((1U << GLB_STS_BMX_TIMEOUT_STS_LEN) - 1) << GLB_STS_BMX_TIMEOUT_STS_POS)) +#define GLB_PDS_APB_CFG GLB_PDS_APB_CFG +#define GLB_PDS_APB_CFG_POS (16U) +#define GLB_PDS_APB_CFG_LEN (8U) +#define GLB_PDS_APB_CFG_MSK (((1U << GLB_PDS_APB_CFG_LEN) - 1) << GLB_PDS_APB_CFG_POS) +#define GLB_PDS_APB_CFG_UMSK (~(((1U << GLB_PDS_APB_CFG_LEN) - 1) << GLB_PDS_APB_CFG_POS)) +#define GLB_HBN_APB_CFG GLB_HBN_APB_CFG +#define GLB_HBN_APB_CFG_POS (24U) +#define GLB_HBN_APB_CFG_LEN (8U) +#define GLB_HBN_APB_CFG_MSK (((1U << GLB_HBN_APB_CFG_LEN) - 1) << GLB_HBN_APB_CFG_POS) +#define GLB_HBN_APB_CFG_UMSK (~(((1U << GLB_HBN_APB_CFG_LEN) - 1) << GLB_HBN_APB_CFG_POS)) + +/* 0x324 : bmx_cfg1 */ +#define GLB_BMX_CFG1_OFFSET (0x324) +#define GLB_REG_BMX_BERR_INT_EN GLB_REG_BMX_BERR_INT_EN +#define GLB_REG_BMX_BERR_INT_EN_POS (0U) +#define GLB_REG_BMX_BERR_INT_EN_LEN (1U) +#define GLB_REG_BMX_BERR_INT_EN_MSK (((1U << GLB_REG_BMX_BERR_INT_EN_LEN) - 1) << GLB_REG_BMX_BERR_INT_EN_POS) +#define GLB_REG_BMX_BERR_INT_EN_UMSK (~(((1U << GLB_REG_BMX_BERR_INT_EN_LEN) - 1) << GLB_REG_BMX_BERR_INT_EN_POS)) +#define GLB_REG_MCU_BERR_INT_EN GLB_REG_MCU_BERR_INT_EN +#define GLB_REG_MCU_BERR_INT_EN_POS (1U) +#define GLB_REG_MCU_BERR_INT_EN_LEN (1U) +#define GLB_REG_MCU_BERR_INT_EN_MSK (((1U << GLB_REG_MCU_BERR_INT_EN_LEN) - 1) << GLB_REG_MCU_BERR_INT_EN_POS) +#define GLB_REG_MCU_BERR_INT_EN_UMSK (~(((1U << GLB_REG_MCU_BERR_INT_EN_LEN) - 1) << GLB_REG_MCU_BERR_INT_EN_POS)) +#define GLB_REG_BMX_QOS_CPU GLB_REG_BMX_QOS_CPU +#define GLB_REG_BMX_QOS_CPU_POS (16U) +#define GLB_REG_BMX_QOS_CPU_LEN (1U) +#define GLB_REG_BMX_QOS_CPU_MSK (((1U << GLB_REG_BMX_QOS_CPU_LEN) - 1) << GLB_REG_BMX_QOS_CPU_POS) +#define GLB_REG_BMX_QOS_CPU_UMSK (~(((1U << GLB_REG_BMX_QOS_CPU_LEN) - 1) << GLB_REG_BMX_QOS_CPU_POS)) +#define GLB_REG_BMX_QOS_SDU GLB_REG_BMX_QOS_SDU +#define GLB_REG_BMX_QOS_SDU_POS (17U) +#define GLB_REG_BMX_QOS_SDU_LEN (1U) +#define GLB_REG_BMX_QOS_SDU_MSK (((1U << GLB_REG_BMX_QOS_SDU_LEN) - 1) << GLB_REG_BMX_QOS_SDU_POS) +#define GLB_REG_BMX_QOS_SDU_UMSK (~(((1U << GLB_REG_BMX_QOS_SDU_LEN) - 1) << GLB_REG_BMX_QOS_SDU_POS)) +#define GLB_REG_BMX_QOS_SEC0 GLB_REG_BMX_QOS_SEC0 +#define GLB_REG_BMX_QOS_SEC0_POS (18U) +#define GLB_REG_BMX_QOS_SEC0_LEN (1U) +#define GLB_REG_BMX_QOS_SEC0_MSK (((1U << GLB_REG_BMX_QOS_SEC0_LEN) - 1) << GLB_REG_BMX_QOS_SEC0_POS) +#define GLB_REG_BMX_QOS_SEC0_UMSK (~(((1U << GLB_REG_BMX_QOS_SEC0_LEN) - 1) << GLB_REG_BMX_QOS_SEC0_POS)) +#define GLB_REG_BMX_QOS_SEC1 GLB_REG_BMX_QOS_SEC1 +#define GLB_REG_BMX_QOS_SEC1_POS (19U) +#define GLB_REG_BMX_QOS_SEC1_LEN (1U) +#define GLB_REG_BMX_QOS_SEC1_MSK (((1U << GLB_REG_BMX_QOS_SEC1_LEN) - 1) << GLB_REG_BMX_QOS_SEC1_POS) +#define GLB_REG_BMX_QOS_SEC1_UMSK (~(((1U << GLB_REG_BMX_QOS_SEC1_LEN) - 1) << GLB_REG_BMX_QOS_SEC1_POS)) +#define GLB_REG_BMX_QOS_SEC2 GLB_REG_BMX_QOS_SEC2 +#define GLB_REG_BMX_QOS_SEC2_POS (20U) +#define GLB_REG_BMX_QOS_SEC2_LEN (1U) +#define GLB_REG_BMX_QOS_SEC2_MSK (((1U << GLB_REG_BMX_QOS_SEC2_LEN) - 1) << GLB_REG_BMX_QOS_SEC2_POS) +#define GLB_REG_BMX_QOS_SEC2_UMSK (~(((1U << GLB_REG_BMX_QOS_SEC2_LEN) - 1) << GLB_REG_BMX_QOS_SEC2_POS)) +#define GLB_REG_BMX_QOS_DMA GLB_REG_BMX_QOS_DMA +#define GLB_REG_BMX_QOS_DMA_POS (21U) +#define GLB_REG_BMX_QOS_DMA_LEN (1U) +#define GLB_REG_BMX_QOS_DMA_MSK (((1U << GLB_REG_BMX_QOS_DMA_LEN) - 1) << GLB_REG_BMX_QOS_DMA_POS) +#define GLB_REG_BMX_QOS_DMA_UMSK (~(((1U << GLB_REG_BMX_QOS_DMA_LEN) - 1) << GLB_REG_BMX_QOS_DMA_POS)) +#define GLB_REG_BMX_QOS_CCI GLB_REG_BMX_QOS_CCI +#define GLB_REG_BMX_QOS_CCI_POS (22U) +#define GLB_REG_BMX_QOS_CCI_LEN (1U) +#define GLB_REG_BMX_QOS_CCI_MSK (((1U << GLB_REG_BMX_QOS_CCI_LEN) - 1) << GLB_REG_BMX_QOS_CCI_POS) +#define GLB_REG_BMX_QOS_CCI_UMSK (~(((1U << GLB_REG_BMX_QOS_CCI_LEN) - 1) << GLB_REG_BMX_QOS_CCI_POS)) +#define GLB_REG_BMX_QOS_PLDMA GLB_REG_BMX_QOS_PLDMA +#define GLB_REG_BMX_QOS_PLDMA_POS (23U) +#define GLB_REG_BMX_QOS_PLDMA_LEN (1U) +#define GLB_REG_BMX_QOS_PLDMA_MSK (((1U << GLB_REG_BMX_QOS_PLDMA_LEN) - 1) << GLB_REG_BMX_QOS_PLDMA_POS) +#define GLB_REG_BMX_QOS_PLDMA_UMSK (~(((1U << GLB_REG_BMX_QOS_PLDMA_LEN) - 1) << GLB_REG_BMX_QOS_PLDMA_POS)) +#define GLB_REG_BMX_QOS_BLEM GLB_REG_BMX_QOS_BLEM +#define GLB_REG_BMX_QOS_BLEM_POS (24U) +#define GLB_REG_BMX_QOS_BLEM_LEN (1U) +#define GLB_REG_BMX_QOS_BLEM_MSK (((1U << GLB_REG_BMX_QOS_BLEM_LEN) - 1) << GLB_REG_BMX_QOS_BLEM_POS) +#define GLB_REG_BMX_QOS_BLEM_UMSK (~(((1U << GLB_REG_BMX_QOS_BLEM_LEN) - 1) << GLB_REG_BMX_QOS_BLEM_POS)) +#define GLB_REG_BMX_QOS_EMACA GLB_REG_BMX_QOS_EMACA +#define GLB_REG_BMX_QOS_EMACA_POS (25U) +#define GLB_REG_BMX_QOS_EMACA_LEN (1U) +#define GLB_REG_BMX_QOS_EMACA_MSK (((1U << GLB_REG_BMX_QOS_EMACA_LEN) - 1) << GLB_REG_BMX_QOS_EMACA_POS) +#define GLB_REG_BMX_QOS_EMACA_UMSK (~(((1U << GLB_REG_BMX_QOS_EMACA_LEN) - 1) << GLB_REG_BMX_QOS_EMACA_POS)) +#define GLB_REG_BMX_QOS_DMA2 GLB_REG_BMX_QOS_DMA2 +#define GLB_REG_BMX_QOS_DMA2_POS (26U) +#define GLB_REG_BMX_QOS_DMA2_LEN (1U) +#define GLB_REG_BMX_QOS_DMA2_MSK (((1U << GLB_REG_BMX_QOS_DMA2_LEN) - 1) << GLB_REG_BMX_QOS_DMA2_POS) +#define GLB_REG_BMX_QOS_DMA2_UMSK (~(((1U << GLB_REG_BMX_QOS_DMA2_LEN) - 1) << GLB_REG_BMX_QOS_DMA2_POS)) +#define GLB_REG_BMX_QOS_SDHM GLB_REG_BMX_QOS_SDHM +#define GLB_REG_BMX_QOS_SDHM_POS (27U) +#define GLB_REG_BMX_QOS_SDHM_LEN (1U) +#define GLB_REG_BMX_QOS_SDHM_MSK (((1U << GLB_REG_BMX_QOS_SDHM_LEN) - 1) << GLB_REG_BMX_QOS_SDHM_POS) +#define GLB_REG_BMX_QOS_SDHM_UMSK (~(((1U << GLB_REG_BMX_QOS_SDHM_LEN) - 1) << GLB_REG_BMX_QOS_SDHM_POS)) +#define GLB_BMX_DBG_SEL GLB_BMX_DBG_SEL +#define GLB_BMX_DBG_SEL_POS (28U) +#define GLB_BMX_DBG_SEL_LEN (4U) +#define GLB_BMX_DBG_SEL_MSK (((1U << GLB_BMX_DBG_SEL_LEN) - 1) << GLB_BMX_DBG_SEL_POS) +#define GLB_BMX_DBG_SEL_UMSK (~(((1U << GLB_BMX_DBG_SEL_LEN) - 1) << GLB_BMX_DBG_SEL_POS)) + +/* 0x328 : bmx_cfg2 */ +#define GLB_BMX_CFG2_OFFSET (0x328) +#define GLB_REG_BMX_BERR_EN GLB_REG_BMX_BERR_EN +#define GLB_REG_BMX_BERR_EN_POS (0U) +#define GLB_REG_BMX_BERR_EN_LEN (14U) +#define GLB_REG_BMX_BERR_EN_MSK (((1U << GLB_REG_BMX_BERR_EN_LEN) - 1) << GLB_REG_BMX_BERR_EN_POS) +#define GLB_REG_BMX_BERR_EN_UMSK (~(((1U << GLB_REG_BMX_BERR_EN_LEN) - 1) << GLB_REG_BMX_BERR_EN_POS)) +#define GLB_REG_MCU_BERR_EN GLB_REG_MCU_BERR_EN +#define GLB_REG_MCU_BERR_EN_POS (16U) +#define GLB_REG_MCU_BERR_EN_LEN (1U) +#define GLB_REG_MCU_BERR_EN_MSK (((1U << GLB_REG_MCU_BERR_EN_LEN) - 1) << GLB_REG_MCU_BERR_EN_POS) +#define GLB_REG_MCU_BERR_EN_UMSK (~(((1U << GLB_REG_MCU_BERR_EN_LEN) - 1) << GLB_REG_MCU_BERR_EN_POS)) + +/* 0x32C : bmx_cfg3 */ +#define GLB_BMX_CFG3_OFFSET (0x32C) +#define GLB_REG_BMX_BERR_CLR GLB_REG_BMX_BERR_CLR +#define GLB_REG_BMX_BERR_CLR_POS (0U) +#define GLB_REG_BMX_BERR_CLR_LEN (1U) +#define GLB_REG_BMX_BERR_CLR_MSK (((1U << GLB_REG_BMX_BERR_CLR_LEN) - 1) << GLB_REG_BMX_BERR_CLR_POS) +#define GLB_REG_BMX_BERR_CLR_UMSK (~(((1U << GLB_REG_BMX_BERR_CLR_LEN) - 1) << GLB_REG_BMX_BERR_CLR_POS)) +#define GLB_REG_BMX_BERR_LAST GLB_REG_BMX_BERR_LAST +#define GLB_REG_BMX_BERR_LAST_POS (1U) +#define GLB_REG_BMX_BERR_LAST_LEN (1U) +#define GLB_REG_BMX_BERR_LAST_MSK (((1U << GLB_REG_BMX_BERR_LAST_LEN) - 1) << GLB_REG_BMX_BERR_LAST_POS) +#define GLB_REG_BMX_BERR_LAST_UMSK (~(((1U << GLB_REG_BMX_BERR_LAST_LEN) - 1) << GLB_REG_BMX_BERR_LAST_POS)) +#define GLB_REG_MCU_BERR_CLR GLB_REG_MCU_BERR_CLR +#define GLB_REG_MCU_BERR_CLR_POS (8U) +#define GLB_REG_MCU_BERR_CLR_LEN (1U) +#define GLB_REG_MCU_BERR_CLR_MSK (((1U << GLB_REG_MCU_BERR_CLR_LEN) - 1) << GLB_REG_MCU_BERR_CLR_POS) +#define GLB_REG_MCU_BERR_CLR_UMSK (~(((1U << GLB_REG_MCU_BERR_CLR_LEN) - 1) << GLB_REG_MCU_BERR_CLR_POS)) +#define GLB_REG_MCU_BERR_LAST GLB_REG_MCU_BERR_LAST +#define GLB_REG_MCU_BERR_LAST_POS (9U) +#define GLB_REG_MCU_BERR_LAST_LEN (1U) +#define GLB_REG_MCU_BERR_LAST_MSK (((1U << GLB_REG_MCU_BERR_LAST_LEN) - 1) << GLB_REG_MCU_BERR_LAST_POS) +#define GLB_REG_MCU_BERR_LAST_UMSK (~(((1U << GLB_REG_MCU_BERR_LAST_LEN) - 1) << GLB_REG_MCU_BERR_LAST_POS)) +#define GLB_STS_BMX_BERR GLB_STS_BMX_BERR +#define GLB_STS_BMX_BERR_POS (16U) +#define GLB_STS_BMX_BERR_LEN (1U) +#define GLB_STS_BMX_BERR_MSK (((1U << GLB_STS_BMX_BERR_LEN) - 1) << GLB_STS_BMX_BERR_POS) +#define GLB_STS_BMX_BERR_UMSK (~(((1U << GLB_STS_BMX_BERR_LEN) - 1) << GLB_STS_BMX_BERR_POS)) +#define GLB_STS_MCU_BERR GLB_STS_MCU_BERR +#define GLB_STS_MCU_BERR_POS (17U) +#define GLB_STS_MCU_BERR_LEN (1U) +#define GLB_STS_MCU_BERR_MSK (((1U << GLB_STS_MCU_BERR_LEN) - 1) << GLB_STS_MCU_BERR_POS) +#define GLB_STS_MCU_BERR_UMSK (~(((1U << GLB_STS_MCU_BERR_LEN) - 1) << GLB_STS_MCU_BERR_POS)) +#define GLB_STS_BMX_BERR_WRITE GLB_STS_BMX_BERR_WRITE +#define GLB_STS_BMX_BERR_WRITE_POS (24U) +#define GLB_STS_BMX_BERR_WRITE_LEN (1U) +#define GLB_STS_BMX_BERR_WRITE_MSK (((1U << GLB_STS_BMX_BERR_WRITE_LEN) - 1) << GLB_STS_BMX_BERR_WRITE_POS) +#define GLB_STS_BMX_BERR_WRITE_UMSK (~(((1U << GLB_STS_BMX_BERR_WRITE_LEN) - 1) << GLB_STS_BMX_BERR_WRITE_POS)) +#define GLB_STS_MCU_BERR_WRITE GLB_STS_MCU_BERR_WRITE +#define GLB_STS_MCU_BERR_WRITE_POS (25U) +#define GLB_STS_MCU_BERR_WRITE_LEN (1U) +#define GLB_STS_MCU_BERR_WRITE_MSK (((1U << GLB_STS_MCU_BERR_WRITE_LEN) - 1) << GLB_STS_MCU_BERR_WRITE_POS) +#define GLB_STS_MCU_BERR_WRITE_UMSK (~(((1U << GLB_STS_MCU_BERR_WRITE_LEN) - 1) << GLB_STS_MCU_BERR_WRITE_POS)) + +/* 0x330 : bmx_cfg4 */ +#define GLB_BMX_CFG4_OFFSET (0x330) +#define GLB_STS_BMX_BERR_SRC GLB_STS_BMX_BERR_SRC +#define GLB_STS_BMX_BERR_SRC_POS (0U) +#define GLB_STS_BMX_BERR_SRC_LEN (14U) +#define GLB_STS_BMX_BERR_SRC_MSK (((1U << GLB_STS_BMX_BERR_SRC_LEN) - 1) << GLB_STS_BMX_BERR_SRC_POS) +#define GLB_STS_BMX_BERR_SRC_UMSK (~(((1U << GLB_STS_BMX_BERR_SRC_LEN) - 1) << GLB_STS_BMX_BERR_SRC_POS)) +#define GLB_STS_MCU_BERR_SRC GLB_STS_MCU_BERR_SRC +#define GLB_STS_MCU_BERR_SRC_POS (16U) +#define GLB_STS_MCU_BERR_SRC_LEN (1U) +#define GLB_STS_MCU_BERR_SRC_MSK (((1U << GLB_STS_MCU_BERR_SRC_LEN) - 1) << GLB_STS_MCU_BERR_SRC_POS) +#define GLB_STS_MCU_BERR_SRC_UMSK (~(((1U << GLB_STS_MCU_BERR_SRC_LEN) - 1) << GLB_STS_MCU_BERR_SRC_POS)) +#define GLB_STS_MCU_BERR_ID GLB_STS_MCU_BERR_ID +#define GLB_STS_MCU_BERR_ID_POS (24U) +#define GLB_STS_MCU_BERR_ID_LEN (8U) +#define GLB_STS_MCU_BERR_ID_MSK (((1U << GLB_STS_MCU_BERR_ID_LEN) - 1) << GLB_STS_MCU_BERR_ID_POS) +#define GLB_STS_MCU_BERR_ID_UMSK (~(((1U << GLB_STS_MCU_BERR_ID_LEN) - 1) << GLB_STS_MCU_BERR_ID_POS)) + +/* 0x334 : bmx_cfg5 */ +#define GLB_BMX_CFG5_OFFSET (0x334) +#define GLB_STS_BMX_BERR_ADDR GLB_STS_BMX_BERR_ADDR +#define GLB_STS_BMX_BERR_ADDR_POS (0U) +#define GLB_STS_BMX_BERR_ADDR_LEN (32U) +#define GLB_STS_BMX_BERR_ADDR_MSK (((1U << GLB_STS_BMX_BERR_ADDR_LEN) - 1) << GLB_STS_BMX_BERR_ADDR_POS) +#define GLB_STS_BMX_BERR_ADDR_UMSK (~(((1U << GLB_STS_BMX_BERR_ADDR_LEN) - 1) << GLB_STS_BMX_BERR_ADDR_POS)) + +/* 0x338 : bmx_cfg6 */ +#define GLB_BMX_CFG6_OFFSET (0x338) +#define GLB_STS_MCU_BERR_ADDR GLB_STS_MCU_BERR_ADDR +#define GLB_STS_MCU_BERR_ADDR_POS (0U) +#define GLB_STS_MCU_BERR_ADDR_LEN (32U) +#define GLB_STS_MCU_BERR_ADDR_MSK (((1U << GLB_STS_MCU_BERR_ADDR_LEN) - 1) << GLB_STS_MCU_BERR_ADDR_POS) +#define GLB_STS_MCU_BERR_ADDR_UMSK (~(((1U << GLB_STS_MCU_BERR_ADDR_LEN) - 1) << GLB_STS_MCU_BERR_ADDR_POS)) + +/* 0x340 : audio_cfg0 */ +#define GLB_AUDIO_CFG0_OFFSET (0x340) +#define GLB_REG_AUDIO_PDM_CLK_DIV GLB_REG_AUDIO_PDM_CLK_DIV +#define GLB_REG_AUDIO_PDM_CLK_DIV_POS (0U) +#define GLB_REG_AUDIO_PDM_CLK_DIV_LEN (6U) +#define GLB_REG_AUDIO_PDM_CLK_DIV_MSK (((1U << GLB_REG_AUDIO_PDM_CLK_DIV_LEN) - 1) << GLB_REG_AUDIO_PDM_CLK_DIV_POS) +#define GLB_REG_AUDIO_PDM_CLK_DIV_UMSK (~(((1U << GLB_REG_AUDIO_PDM_CLK_DIV_LEN) - 1) << GLB_REG_AUDIO_PDM_CLK_DIV_POS)) +#define GLB_REG_AUDIO_PDM_CLK_EN GLB_REG_AUDIO_PDM_CLK_EN +#define GLB_REG_AUDIO_PDM_CLK_EN_POS (7U) +#define GLB_REG_AUDIO_PDM_CLK_EN_LEN (1U) +#define GLB_REG_AUDIO_PDM_CLK_EN_MSK (((1U << GLB_REG_AUDIO_PDM_CLK_EN_LEN) - 1) << GLB_REG_AUDIO_PDM_CLK_EN_POS) +#define GLB_REG_AUDIO_PDM_CLK_EN_UMSK (~(((1U << GLB_REG_AUDIO_PDM_CLK_EN_LEN) - 1) << GLB_REG_AUDIO_PDM_CLK_EN_POS)) +#define GLB_REG_AUDIO_ADC_CLK_DIV GLB_REG_AUDIO_ADC_CLK_DIV +#define GLB_REG_AUDIO_ADC_CLK_DIV_POS (8U) +#define GLB_REG_AUDIO_ADC_CLK_DIV_LEN (6U) +#define GLB_REG_AUDIO_ADC_CLK_DIV_MSK (((1U << GLB_REG_AUDIO_ADC_CLK_DIV_LEN) - 1) << GLB_REG_AUDIO_ADC_CLK_DIV_POS) +#define GLB_REG_AUDIO_ADC_CLK_DIV_UMSK (~(((1U << GLB_REG_AUDIO_ADC_CLK_DIV_LEN) - 1) << GLB_REG_AUDIO_ADC_CLK_DIV_POS)) +#define GLB_REG_AUDIO_ADC_CLK_EN GLB_REG_AUDIO_ADC_CLK_EN +#define GLB_REG_AUDIO_ADC_CLK_EN_POS (15U) +#define GLB_REG_AUDIO_ADC_CLK_EN_LEN (1U) +#define GLB_REG_AUDIO_ADC_CLK_EN_MSK (((1U << GLB_REG_AUDIO_ADC_CLK_EN_LEN) - 1) << GLB_REG_AUDIO_ADC_CLK_EN_POS) +#define GLB_REG_AUDIO_ADC_CLK_EN_UMSK (~(((1U << GLB_REG_AUDIO_ADC_CLK_EN_LEN) - 1) << GLB_REG_AUDIO_ADC_CLK_EN_POS)) +#define GLB_REG_AUDIO_DAC_CLK_DIV GLB_REG_AUDIO_DAC_CLK_DIV +#define GLB_REG_AUDIO_DAC_CLK_DIV_POS (16U) +#define GLB_REG_AUDIO_DAC_CLK_DIV_LEN (6U) +#define GLB_REG_AUDIO_DAC_CLK_DIV_MSK (((1U << GLB_REG_AUDIO_DAC_CLK_DIV_LEN) - 1) << GLB_REG_AUDIO_DAC_CLK_DIV_POS) +#define GLB_REG_AUDIO_DAC_CLK_DIV_UMSK (~(((1U << GLB_REG_AUDIO_DAC_CLK_DIV_LEN) - 1) << GLB_REG_AUDIO_DAC_CLK_DIV_POS)) +#define GLB_REG_AUDIO_DAC_CLK_EN GLB_REG_AUDIO_DAC_CLK_EN +#define GLB_REG_AUDIO_DAC_CLK_EN_POS (23U) +#define GLB_REG_AUDIO_DAC_CLK_EN_LEN (1U) +#define GLB_REG_AUDIO_DAC_CLK_EN_MSK (((1U << GLB_REG_AUDIO_DAC_CLK_EN_LEN) - 1) << GLB_REG_AUDIO_DAC_CLK_EN_POS) +#define GLB_REG_AUDIO_DAC_CLK_EN_UMSK (~(((1U << GLB_REG_AUDIO_DAC_CLK_EN_LEN) - 1) << GLB_REG_AUDIO_DAC_CLK_EN_POS)) +#define GLB_REG_AUDIO_AUTO_DIV_EN GLB_REG_AUDIO_AUTO_DIV_EN +#define GLB_REG_AUDIO_AUTO_DIV_EN_POS (31U) +#define GLB_REG_AUDIO_AUTO_DIV_EN_LEN (1U) +#define GLB_REG_AUDIO_AUTO_DIV_EN_MSK (((1U << GLB_REG_AUDIO_AUTO_DIV_EN_LEN) - 1) << GLB_REG_AUDIO_AUTO_DIV_EN_POS) +#define GLB_REG_AUDIO_AUTO_DIV_EN_UMSK (~(((1U << GLB_REG_AUDIO_AUTO_DIV_EN_LEN) - 1) << GLB_REG_AUDIO_AUTO_DIV_EN_POS)) + +/* 0x344 : audio_cfg1 */ +#define GLB_AUDIO_CFG1_OFFSET (0x344) +#define GLB_REG_PADC_CLK_DIV GLB_REG_PADC_CLK_DIV +#define GLB_REG_PADC_CLK_DIV_POS (0U) +#define GLB_REG_PADC_CLK_DIV_LEN (10U) +#define GLB_REG_PADC_CLK_DIV_MSK (((1U << GLB_REG_PADC_CLK_DIV_LEN) - 1) << GLB_REG_PADC_CLK_DIV_POS) +#define GLB_REG_PADC_CLK_DIV_UMSK (~(((1U << GLB_REG_PADC_CLK_DIV_LEN) - 1) << GLB_REG_PADC_CLK_DIV_POS)) +#define GLB_REG_PADC_CLK_EN GLB_REG_PADC_CLK_EN +#define GLB_REG_PADC_CLK_EN_POS (10U) +#define GLB_REG_PADC_CLK_EN_LEN (1U) +#define GLB_REG_PADC_CLK_EN_MSK (((1U << GLB_REG_PADC_CLK_EN_LEN) - 1) << GLB_REG_PADC_CLK_EN_POS) +#define GLB_REG_PADC_CLK_EN_UMSK (~(((1U << GLB_REG_PADC_CLK_EN_LEN) - 1) << GLB_REG_PADC_CLK_EN_POS)) + +/* 0x390 : eth_cfg0 */ +#define GLB_ETH_CFG0_OFFSET (0x390) +#define GLB_CFG_SEL_ETH_REF_CLK_O GLB_CFG_SEL_ETH_REF_CLK_O +#define GLB_CFG_SEL_ETH_REF_CLK_O_POS (5U) +#define GLB_CFG_SEL_ETH_REF_CLK_O_LEN (1U) +#define GLB_CFG_SEL_ETH_REF_CLK_O_MSK (((1U << GLB_CFG_SEL_ETH_REF_CLK_O_LEN) - 1) << GLB_CFG_SEL_ETH_REF_CLK_O_POS) +#define GLB_CFG_SEL_ETH_REF_CLK_O_UMSK (~(((1U << GLB_CFG_SEL_ETH_REF_CLK_O_LEN) - 1) << GLB_CFG_SEL_ETH_REF_CLK_O_POS)) +#define GLB_CFG_INV_ETH_REF_CLK_O GLB_CFG_INV_ETH_REF_CLK_O +#define GLB_CFG_INV_ETH_REF_CLK_O_POS (6U) +#define GLB_CFG_INV_ETH_REF_CLK_O_LEN (1U) +#define GLB_CFG_INV_ETH_REF_CLK_O_MSK (((1U << GLB_CFG_INV_ETH_REF_CLK_O_LEN) - 1) << GLB_CFG_INV_ETH_REF_CLK_O_POS) +#define GLB_CFG_INV_ETH_REF_CLK_O_UMSK (~(((1U << GLB_CFG_INV_ETH_REF_CLK_O_LEN) - 1) << GLB_CFG_INV_ETH_REF_CLK_O_POS)) +#define GLB_CFG_INV_ETH_TX_CLK GLB_CFG_INV_ETH_TX_CLK +#define GLB_CFG_INV_ETH_TX_CLK_POS (7U) +#define GLB_CFG_INV_ETH_TX_CLK_LEN (1U) +#define GLB_CFG_INV_ETH_TX_CLK_MSK (((1U << GLB_CFG_INV_ETH_TX_CLK_LEN) - 1) << GLB_CFG_INV_ETH_TX_CLK_POS) +#define GLB_CFG_INV_ETH_TX_CLK_UMSK (~(((1U << GLB_CFG_INV_ETH_TX_CLK_LEN) - 1) << GLB_CFG_INV_ETH_TX_CLK_POS)) +#define GLB_CFG_INV_ETH_RX_CLK GLB_CFG_INV_ETH_RX_CLK +#define GLB_CFG_INV_ETH_RX_CLK_POS (10U) +#define GLB_CFG_INV_ETH_RX_CLK_LEN (1U) +#define GLB_CFG_INV_ETH_RX_CLK_MSK (((1U << GLB_CFG_INV_ETH_RX_CLK_LEN) - 1) << GLB_CFG_INV_ETH_RX_CLK_POS) +#define GLB_CFG_INV_ETH_RX_CLK_UMSK (~(((1U << GLB_CFG_INV_ETH_RX_CLK_LEN) - 1) << GLB_CFG_INV_ETH_RX_CLK_POS)) + +/* 0x420 : cam_cfg0 */ +#define GLB_CAM_CFG0_OFFSET (0x420) +#define GLB_REG_CAM_REF_CLK_EN GLB_REG_CAM_REF_CLK_EN +#define GLB_REG_CAM_REF_CLK_EN_POS (27U) +#define GLB_REG_CAM_REF_CLK_EN_LEN (1U) +#define GLB_REG_CAM_REF_CLK_EN_MSK (((1U << GLB_REG_CAM_REF_CLK_EN_LEN) - 1) << GLB_REG_CAM_REF_CLK_EN_POS) +#define GLB_REG_CAM_REF_CLK_EN_UMSK (~(((1U << GLB_REG_CAM_REF_CLK_EN_LEN) - 1) << GLB_REG_CAM_REF_CLK_EN_POS)) +#define GLB_REG_CAM_REF_CLK_SRC_SEL GLB_REG_CAM_REF_CLK_SRC_SEL +#define GLB_REG_CAM_REF_CLK_SRC_SEL_POS (28U) +#define GLB_REG_CAM_REF_CLK_SRC_SEL_LEN (2U) +#define GLB_REG_CAM_REF_CLK_SRC_SEL_MSK (((1U << GLB_REG_CAM_REF_CLK_SRC_SEL_LEN) - 1) << GLB_REG_CAM_REF_CLK_SRC_SEL_POS) +#define GLB_REG_CAM_REF_CLK_SRC_SEL_UMSK (~(((1U << GLB_REG_CAM_REF_CLK_SRC_SEL_LEN) - 1) << GLB_REG_CAM_REF_CLK_SRC_SEL_POS)) +#define GLB_REG_CAM_REF_CLK_DIV GLB_REG_CAM_REF_CLK_DIV +#define GLB_REG_CAM_REF_CLK_DIV_POS (30U) +#define GLB_REG_CAM_REF_CLK_DIV_LEN (2U) +#define GLB_REG_CAM_REF_CLK_DIV_MSK (((1U << GLB_REG_CAM_REF_CLK_DIV_LEN) - 1) << GLB_REG_CAM_REF_CLK_DIV_POS) +#define GLB_REG_CAM_REF_CLK_DIV_UMSK (~(((1U << GLB_REG_CAM_REF_CLK_DIV_LEN) - 1) << GLB_REG_CAM_REF_CLK_DIV_POS)) + +/* 0x430 : sdh_cfg0 */ +#define GLB_SDH_CFG0_OFFSET (0x430) +#define GLB_REG_SDH_CLK_DIV GLB_REG_SDH_CLK_DIV +#define GLB_REG_SDH_CLK_DIV_POS (9U) +#define GLB_REG_SDH_CLK_DIV_LEN (3U) +#define GLB_REG_SDH_CLK_DIV_MSK (((1U << GLB_REG_SDH_CLK_DIV_LEN) - 1) << GLB_REG_SDH_CLK_DIV_POS) +#define GLB_REG_SDH_CLK_DIV_UMSK (~(((1U << GLB_REG_SDH_CLK_DIV_LEN) - 1) << GLB_REG_SDH_CLK_DIV_POS)) +#define GLB_REG_SDH_CLK_SEL GLB_REG_SDH_CLK_SEL +#define GLB_REG_SDH_CLK_SEL_POS (12U) +#define GLB_REG_SDH_CLK_SEL_LEN (1U) +#define GLB_REG_SDH_CLK_SEL_MSK (((1U << GLB_REG_SDH_CLK_SEL_LEN) - 1) << GLB_REG_SDH_CLK_SEL_POS) +#define GLB_REG_SDH_CLK_SEL_UMSK (~(((1U << GLB_REG_SDH_CLK_SEL_LEN) - 1) << GLB_REG_SDH_CLK_SEL_POS)) +#define GLB_REG_SDH_CLK_EN GLB_REG_SDH_CLK_EN +#define GLB_REG_SDH_CLK_EN_POS (13U) +#define GLB_REG_SDH_CLK_EN_LEN (1U) +#define GLB_REG_SDH_CLK_EN_MSK (((1U << GLB_REG_SDH_CLK_EN_LEN) - 1) << GLB_REG_SDH_CLK_EN_POS) +#define GLB_REG_SDH_CLK_EN_UMSK (~(((1U << GLB_REG_SDH_CLK_EN_LEN) - 1) << GLB_REG_SDH_CLK_EN_POS)) + +/* 0x490 : tzc_cfg0 */ +#define GLB_TZC_CFG0_OFFSET (0x490) +#define GLB_TZC_GLB_PWRON_RST_LOCK GLB_TZC_GLB_PWRON_RST_LOCK +#define GLB_TZC_GLB_PWRON_RST_LOCK_POS (12U) +#define GLB_TZC_GLB_PWRON_RST_LOCK_LEN (1U) +#define GLB_TZC_GLB_PWRON_RST_LOCK_MSK (((1U << GLB_TZC_GLB_PWRON_RST_LOCK_LEN) - 1) << GLB_TZC_GLB_PWRON_RST_LOCK_POS) +#define GLB_TZC_GLB_PWRON_RST_LOCK_UMSK (~(((1U << GLB_TZC_GLB_PWRON_RST_LOCK_LEN) - 1) << GLB_TZC_GLB_PWRON_RST_LOCK_POS)) +#define GLB_TZC_GLB_CPU_RESET_LOCK GLB_TZC_GLB_CPU_RESET_LOCK +#define GLB_TZC_GLB_CPU_RESET_LOCK_POS (13U) +#define GLB_TZC_GLB_CPU_RESET_LOCK_LEN (1U) +#define GLB_TZC_GLB_CPU_RESET_LOCK_MSK (((1U << GLB_TZC_GLB_CPU_RESET_LOCK_LEN) - 1) << GLB_TZC_GLB_CPU_RESET_LOCK_POS) +#define GLB_TZC_GLB_CPU_RESET_LOCK_UMSK (~(((1U << GLB_TZC_GLB_CPU_RESET_LOCK_LEN) - 1) << GLB_TZC_GLB_CPU_RESET_LOCK_POS)) +#define GLB_TZC_GLB_SYS_RESET_LOCK GLB_TZC_GLB_SYS_RESET_LOCK +#define GLB_TZC_GLB_SYS_RESET_LOCK_POS (14U) +#define GLB_TZC_GLB_SYS_RESET_LOCK_LEN (1U) +#define GLB_TZC_GLB_SYS_RESET_LOCK_MSK (((1U << GLB_TZC_GLB_SYS_RESET_LOCK_LEN) - 1) << GLB_TZC_GLB_SYS_RESET_LOCK_POS) +#define GLB_TZC_GLB_SYS_RESET_LOCK_UMSK (~(((1U << GLB_TZC_GLB_SYS_RESET_LOCK_LEN) - 1) << GLB_TZC_GLB_SYS_RESET_LOCK_POS)) +#define GLB_TZC_GLB_CPU2_RESET_LOCK GLB_TZC_GLB_CPU2_RESET_LOCK +#define GLB_TZC_GLB_CPU2_RESET_LOCK_POS (15U) +#define GLB_TZC_GLB_CPU2_RESET_LOCK_LEN (1U) +#define GLB_TZC_GLB_CPU2_RESET_LOCK_MSK (((1U << GLB_TZC_GLB_CPU2_RESET_LOCK_LEN) - 1) << GLB_TZC_GLB_CPU2_RESET_LOCK_POS) +#define GLB_TZC_GLB_CPU2_RESET_LOCK_UMSK (~(((1U << GLB_TZC_GLB_CPU2_RESET_LOCK_LEN) - 1) << GLB_TZC_GLB_CPU2_RESET_LOCK_POS)) +#define GLB_TZC_GLB_PWR_LOCK GLB_TZC_GLB_PWR_LOCK +#define GLB_TZC_GLB_PWR_LOCK_POS (21U) +#define GLB_TZC_GLB_PWR_LOCK_LEN (1U) +#define GLB_TZC_GLB_PWR_LOCK_MSK (((1U << GLB_TZC_GLB_PWR_LOCK_LEN) - 1) << GLB_TZC_GLB_PWR_LOCK_POS) +#define GLB_TZC_GLB_PWR_LOCK_UMSK (~(((1U << GLB_TZC_GLB_PWR_LOCK_LEN) - 1) << GLB_TZC_GLB_PWR_LOCK_POS)) +#define GLB_TZC_GLB_INT_LOCK GLB_TZC_GLB_INT_LOCK +#define GLB_TZC_GLB_INT_LOCK_POS (22U) +#define GLB_TZC_GLB_INT_LOCK_LEN (1U) +#define GLB_TZC_GLB_INT_LOCK_MSK (((1U << GLB_TZC_GLB_INT_LOCK_LEN) - 1) << GLB_TZC_GLB_INT_LOCK_POS) +#define GLB_TZC_GLB_INT_LOCK_UMSK (~(((1U << GLB_TZC_GLB_INT_LOCK_LEN) - 1) << GLB_TZC_GLB_INT_LOCK_POS)) +#define GLB_TZC_GLB_CPUPLL_LOCK GLB_TZC_GLB_CPUPLL_LOCK +#define GLB_TZC_GLB_CPUPLL_LOCK_POS (24U) +#define GLB_TZC_GLB_CPUPLL_LOCK_LEN (1U) +#define GLB_TZC_GLB_CPUPLL_LOCK_MSK (((1U << GLB_TZC_GLB_CPUPLL_LOCK_LEN) - 1) << GLB_TZC_GLB_CPUPLL_LOCK_POS) +#define GLB_TZC_GLB_CPUPLL_LOCK_UMSK (~(((1U << GLB_TZC_GLB_CPUPLL_LOCK_LEN) - 1) << GLB_TZC_GLB_CPUPLL_LOCK_POS)) +#define GLB_TZC_GLB_MISC_LOCK GLB_TZC_GLB_MISC_LOCK +#define GLB_TZC_GLB_MISC_LOCK_POS (25U) +#define GLB_TZC_GLB_MISC_LOCK_LEN (1U) +#define GLB_TZC_GLB_MISC_LOCK_MSK (((1U << GLB_TZC_GLB_MISC_LOCK_LEN) - 1) << GLB_TZC_GLB_MISC_LOCK_POS) +#define GLB_TZC_GLB_MISC_LOCK_UMSK (~(((1U << GLB_TZC_GLB_MISC_LOCK_LEN) - 1) << GLB_TZC_GLB_MISC_LOCK_POS)) +#define GLB_TZC_GLB_SRAM_LOCK GLB_TZC_GLB_SRAM_LOCK +#define GLB_TZC_GLB_SRAM_LOCK_POS (26U) +#define GLB_TZC_GLB_SRAM_LOCK_LEN (1U) +#define GLB_TZC_GLB_SRAM_LOCK_MSK (((1U << GLB_TZC_GLB_SRAM_LOCK_LEN) - 1) << GLB_TZC_GLB_SRAM_LOCK_POS) +#define GLB_TZC_GLB_SRAM_LOCK_UMSK (~(((1U << GLB_TZC_GLB_SRAM_LOCK_LEN) - 1) << GLB_TZC_GLB_SRAM_LOCK_POS)) +#define GLB_TZC_GLB_SWRST_LOCK GLB_TZC_GLB_SWRST_LOCK +#define GLB_TZC_GLB_SWRST_LOCK_POS (27U) +#define GLB_TZC_GLB_SWRST_LOCK_LEN (1U) +#define GLB_TZC_GLB_SWRST_LOCK_MSK (((1U << GLB_TZC_GLB_SWRST_LOCK_LEN) - 1) << GLB_TZC_GLB_SWRST_LOCK_POS) +#define GLB_TZC_GLB_SWRST_LOCK_UMSK (~(((1U << GLB_TZC_GLB_SWRST_LOCK_LEN) - 1) << GLB_TZC_GLB_SWRST_LOCK_POS)) +#define GLB_TZC_GLB_BMX_LOCK GLB_TZC_GLB_BMX_LOCK +#define GLB_TZC_GLB_BMX_LOCK_POS (28U) +#define GLB_TZC_GLB_BMX_LOCK_LEN (1U) +#define GLB_TZC_GLB_BMX_LOCK_MSK (((1U << GLB_TZC_GLB_BMX_LOCK_LEN) - 1) << GLB_TZC_GLB_BMX_LOCK_POS) +#define GLB_TZC_GLB_BMX_LOCK_UMSK (~(((1U << GLB_TZC_GLB_BMX_LOCK_LEN) - 1) << GLB_TZC_GLB_BMX_LOCK_POS)) +#define GLB_TZC_GLB_DBG_LOCK GLB_TZC_GLB_DBG_LOCK +#define GLB_TZC_GLB_DBG_LOCK_POS (29U) +#define GLB_TZC_GLB_DBG_LOCK_LEN (1U) +#define GLB_TZC_GLB_DBG_LOCK_MSK (((1U << GLB_TZC_GLB_DBG_LOCK_LEN) - 1) << GLB_TZC_GLB_DBG_LOCK_POS) +#define GLB_TZC_GLB_DBG_LOCK_UMSK (~(((1U << GLB_TZC_GLB_DBG_LOCK_LEN) - 1) << GLB_TZC_GLB_DBG_LOCK_POS)) +#define GLB_TZC_GLB_MBIST_LOCK GLB_TZC_GLB_MBIST_LOCK +#define GLB_TZC_GLB_MBIST_LOCK_POS (30U) +#define GLB_TZC_GLB_MBIST_LOCK_LEN (1U) +#define GLB_TZC_GLB_MBIST_LOCK_MSK (((1U << GLB_TZC_GLB_MBIST_LOCK_LEN) - 1) << GLB_TZC_GLB_MBIST_LOCK_POS) +#define GLB_TZC_GLB_MBIST_LOCK_UMSK (~(((1U << GLB_TZC_GLB_MBIST_LOCK_LEN) - 1) << GLB_TZC_GLB_MBIST_LOCK_POS)) +#define GLB_TZC_GLB_CLK_LOCK GLB_TZC_GLB_CLK_LOCK +#define GLB_TZC_GLB_CLK_LOCK_POS (31U) +#define GLB_TZC_GLB_CLK_LOCK_LEN (1U) +#define GLB_TZC_GLB_CLK_LOCK_MSK (((1U << GLB_TZC_GLB_CLK_LOCK_LEN) - 1) << GLB_TZC_GLB_CLK_LOCK_POS) +#define GLB_TZC_GLB_CLK_LOCK_UMSK (~(((1U << GLB_TZC_GLB_CLK_LOCK_LEN) - 1) << GLB_TZC_GLB_CLK_LOCK_POS)) + +/* 0x510 : glb_parm_cfg0 */ +#define GLB_PARM_CFG0_OFFSET (0x510) +#define GLB_REG_BD_EN GLB_REG_BD_EN +#define GLB_REG_BD_EN_POS (0U) +#define GLB_REG_BD_EN_LEN (1U) +#define GLB_REG_BD_EN_MSK (((1U << GLB_REG_BD_EN_LEN) - 1) << GLB_REG_BD_EN_POS) +#define GLB_REG_BD_EN_UMSK (~(((1U << GLB_REG_BD_EN_LEN) - 1) << GLB_REG_BD_EN_POS)) +#define GLB_UART_SWAP_SET GLB_UART_SWAP_SET +#define GLB_UART_SWAP_SET_POS (2U) +#define GLB_UART_SWAP_SET_LEN (4U) +#define GLB_UART_SWAP_SET_MSK (((1U << GLB_UART_SWAP_SET_LEN) - 1) << GLB_UART_SWAP_SET_POS) +#define GLB_UART_SWAP_SET_UMSK (~(((1U << GLB_UART_SWAP_SET_LEN) - 1) << GLB_UART_SWAP_SET_POS)) +#define GLB_SWAP_SFLASH_IO_3_IO_0 GLB_SWAP_SFLASH_IO_3_IO_0 +#define GLB_SWAP_SFLASH_IO_3_IO_0_POS (8U) +#define GLB_SWAP_SFLASH_IO_3_IO_0_LEN (1U) +#define GLB_SWAP_SFLASH_IO_3_IO_0_MSK (((1U << GLB_SWAP_SFLASH_IO_3_IO_0_LEN) - 1) << GLB_SWAP_SFLASH_IO_3_IO_0_POS) +#define GLB_SWAP_SFLASH_IO_3_IO_0_UMSK (~(((1U << GLB_SWAP_SFLASH_IO_3_IO_0_LEN) - 1) << GLB_SWAP_SFLASH_IO_3_IO_0_POS)) +#define GLB_SEL_EMBEDDED_SFLASH GLB_SEL_EMBEDDED_SFLASH +#define GLB_SEL_EMBEDDED_SFLASH_POS (9U) +#define GLB_SEL_EMBEDDED_SFLASH_LEN (1U) +#define GLB_SEL_EMBEDDED_SFLASH_MSK (((1U << GLB_SEL_EMBEDDED_SFLASH_LEN) - 1) << GLB_SEL_EMBEDDED_SFLASH_POS) +#define GLB_SEL_EMBEDDED_SFLASH_UMSK (~(((1U << GLB_SEL_EMBEDDED_SFLASH_LEN) - 1) << GLB_SEL_EMBEDDED_SFLASH_POS)) +#define GLB_REG_SEL_PSRAM0_X16 GLB_REG_SEL_PSRAM0_X16 +#define GLB_REG_SEL_PSRAM0_X16_POS (11U) +#define GLB_REG_SEL_PSRAM0_X16_LEN (1U) +#define GLB_REG_SEL_PSRAM0_X16_MSK (((1U << GLB_REG_SEL_PSRAM0_X16_LEN) - 1) << GLB_REG_SEL_PSRAM0_X16_POS) +#define GLB_REG_SEL_PSRAM0_X16_UMSK (~(((1U << GLB_REG_SEL_PSRAM0_X16_LEN) - 1) << GLB_REG_SEL_PSRAM0_X16_POS)) +#define GLB_REG_SPI_0_MASTER_MODE GLB_REG_SPI_0_MASTER_MODE +#define GLB_REG_SPI_0_MASTER_MODE_POS (12U) +#define GLB_REG_SPI_0_MASTER_MODE_LEN (1U) +#define GLB_REG_SPI_0_MASTER_MODE_MSK (((1U << GLB_REG_SPI_0_MASTER_MODE_LEN) - 1) << GLB_REG_SPI_0_MASTER_MODE_POS) +#define GLB_REG_SPI_0_MASTER_MODE_UMSK (~(((1U << GLB_REG_SPI_0_MASTER_MODE_LEN) - 1) << GLB_REG_SPI_0_MASTER_MODE_POS)) +#define GLB_REG_SPI_0_SWAP GLB_REG_SPI_0_SWAP +#define GLB_REG_SPI_0_SWAP_POS (13U) +#define GLB_REG_SPI_0_SWAP_LEN (1U) +#define GLB_REG_SPI_0_SWAP_MSK (((1U << GLB_REG_SPI_0_SWAP_LEN) - 1) << GLB_REG_SPI_0_SWAP_POS) +#define GLB_REG_SPI_0_SWAP_UMSK (~(((1U << GLB_REG_SPI_0_SWAP_LEN) - 1) << GLB_REG_SPI_0_SWAP_POS)) +#define GLB_REG_SEL_DBI_TYPE_C GLB_REG_SEL_DBI_TYPE_C +#define GLB_REG_SEL_DBI_TYPE_C_POS (14U) +#define GLB_REG_SEL_DBI_TYPE_C_LEN (1U) +#define GLB_REG_SEL_DBI_TYPE_C_MSK (((1U << GLB_REG_SEL_DBI_TYPE_C_LEN) - 1) << GLB_REG_SEL_DBI_TYPE_C_POS) +#define GLB_REG_SEL_DBI_TYPE_C_UMSK (~(((1U << GLB_REG_SEL_DBI_TYPE_C_LEN) - 1) << GLB_REG_SEL_DBI_TYPE_C_POS)) +#define GLB_ANT_SWITCH_SEL GLB_ANT_SWITCH_SEL +#define GLB_ANT_SWITCH_SEL_POS (15U) +#define GLB_ANT_SWITCH_SEL_LEN (1U) +#define GLB_ANT_SWITCH_SEL_MSK (((1U << GLB_ANT_SWITCH_SEL_LEN) - 1) << GLB_ANT_SWITCH_SEL_POS) +#define GLB_ANT_SWITCH_SEL_UMSK (~(((1U << GLB_ANT_SWITCH_SEL_LEN) - 1) << GLB_ANT_SWITCH_SEL_POS)) +#define GLB_P1_ADC_TEST_WITH_CCI GLB_P1_ADC_TEST_WITH_CCI +#define GLB_P1_ADC_TEST_WITH_CCI_POS (17U) +#define GLB_P1_ADC_TEST_WITH_CCI_LEN (1U) +#define GLB_P1_ADC_TEST_WITH_CCI_MSK (((1U << GLB_P1_ADC_TEST_WITH_CCI_LEN) - 1) << GLB_P1_ADC_TEST_WITH_CCI_POS) +#define GLB_P1_ADC_TEST_WITH_CCI_UMSK (~(((1U << GLB_P1_ADC_TEST_WITH_CCI_LEN) - 1) << GLB_P1_ADC_TEST_WITH_CCI_POS)) +#define GLB_P2_DAC_TEST_WITH_CCI GLB_P2_DAC_TEST_WITH_CCI +#define GLB_P2_DAC_TEST_WITH_CCI_POS (18U) +#define GLB_P2_DAC_TEST_WITH_CCI_LEN (1U) +#define GLB_P2_DAC_TEST_WITH_CCI_MSK (((1U << GLB_P2_DAC_TEST_WITH_CCI_LEN) - 1) << GLB_P2_DAC_TEST_WITH_CCI_POS) +#define GLB_P2_DAC_TEST_WITH_CCI_UMSK (~(((1U << GLB_P2_DAC_TEST_WITH_CCI_LEN) - 1) << GLB_P2_DAC_TEST_WITH_CCI_POS)) +#define GLB_P3_CCI_USE_IO_2_5 GLB_P3_CCI_USE_IO_2_5 +#define GLB_P3_CCI_USE_IO_2_5_POS (19U) +#define GLB_P3_CCI_USE_IO_2_5_LEN (1U) +#define GLB_P3_CCI_USE_IO_2_5_MSK (((1U << GLB_P3_CCI_USE_IO_2_5_LEN) - 1) << GLB_P3_CCI_USE_IO_2_5_POS) +#define GLB_P3_CCI_USE_IO_2_5_UMSK (~(((1U << GLB_P3_CCI_USE_IO_2_5_LEN) - 1) << GLB_P3_CCI_USE_IO_2_5_POS)) +#define GLB_P4_ADC_TEST_WITH_JTAG GLB_P4_ADC_TEST_WITH_JTAG +#define GLB_P4_ADC_TEST_WITH_JTAG_POS (20U) +#define GLB_P4_ADC_TEST_WITH_JTAG_LEN (1U) +#define GLB_P4_ADC_TEST_WITH_JTAG_MSK (((1U << GLB_P4_ADC_TEST_WITH_JTAG_LEN) - 1) << GLB_P4_ADC_TEST_WITH_JTAG_POS) +#define GLB_P4_ADC_TEST_WITH_JTAG_UMSK (~(((1U << GLB_P4_ADC_TEST_WITH_JTAG_LEN) - 1) << GLB_P4_ADC_TEST_WITH_JTAG_POS)) +#define GLB_P5_DAC_TEST_WITH_JTAG GLB_P5_DAC_TEST_WITH_JTAG +#define GLB_P5_DAC_TEST_WITH_JTAG_POS (21U) +#define GLB_P5_DAC_TEST_WITH_JTAG_LEN (1U) +#define GLB_P5_DAC_TEST_WITH_JTAG_MSK (((1U << GLB_P5_DAC_TEST_WITH_JTAG_LEN) - 1) << GLB_P5_DAC_TEST_WITH_JTAG_POS) +#define GLB_P5_DAC_TEST_WITH_JTAG_UMSK (~(((1U << GLB_P5_DAC_TEST_WITH_JTAG_LEN) - 1) << GLB_P5_DAC_TEST_WITH_JTAG_POS)) +#define GLB_P6_SDH_USE_IO_0_5 GLB_P6_SDH_USE_IO_0_5 +#define GLB_P6_SDH_USE_IO_0_5_POS (22U) +#define GLB_P6_SDH_USE_IO_0_5_LEN (1U) +#define GLB_P6_SDH_USE_IO_0_5_MSK (((1U << GLB_P6_SDH_USE_IO_0_5_LEN) - 1) << GLB_P6_SDH_USE_IO_0_5_POS) +#define GLB_P6_SDH_USE_IO_0_5_UMSK (~(((1U << GLB_P6_SDH_USE_IO_0_5_LEN) - 1) << GLB_P6_SDH_USE_IO_0_5_POS)) +#define GLB_P7_JTAG_USE_IO_2_5 GLB_P7_JTAG_USE_IO_2_5 +#define GLB_P7_JTAG_USE_IO_2_5_POS (23U) +#define GLB_P7_JTAG_USE_IO_2_5_LEN (1U) +#define GLB_P7_JTAG_USE_IO_2_5_MSK (((1U << GLB_P7_JTAG_USE_IO_2_5_LEN) - 1) << GLB_P7_JTAG_USE_IO_2_5_POS) +#define GLB_P7_JTAG_USE_IO_2_5_UMSK (~(((1U << GLB_P7_JTAG_USE_IO_2_5_LEN) - 1) << GLB_P7_JTAG_USE_IO_2_5_POS)) +#define GLB_RF1_TEST_MODE GLB_RF1_TEST_MODE +#define GLB_RF1_TEST_MODE_POS (25U) +#define GLB_RF1_TEST_MODE_LEN (2U) +#define GLB_RF1_TEST_MODE_MSK (((1U << GLB_RF1_TEST_MODE_LEN) - 1) << GLB_RF1_TEST_MODE_POS) +#define GLB_RF1_TEST_MODE_UMSK (~(((1U << GLB_RF1_TEST_MODE_LEN) - 1) << GLB_RF1_TEST_MODE_POS)) +#define GLB_REG_MM_SPI_MASTER_MODE GLB_REG_MM_SPI_MASTER_MODE +#define GLB_REG_MM_SPI_MASTER_MODE_POS (27U) +#define GLB_REG_MM_SPI_MASTER_MODE_LEN (1U) +#define GLB_REG_MM_SPI_MASTER_MODE_MSK (((1U << GLB_REG_MM_SPI_MASTER_MODE_LEN) - 1) << GLB_REG_MM_SPI_MASTER_MODE_POS) +#define GLB_REG_MM_SPI_MASTER_MODE_UMSK (~(((1U << GLB_REG_MM_SPI_MASTER_MODE_LEN) - 1) << GLB_REG_MM_SPI_MASTER_MODE_POS)) +#define GLB_REG_MM_SPI_SWAP GLB_REG_MM_SPI_SWAP +#define GLB_REG_MM_SPI_SWAP_POS (28U) +#define GLB_REG_MM_SPI_SWAP_LEN (1U) +#define GLB_REG_MM_SPI_SWAP_MSK (((1U << GLB_REG_MM_SPI_SWAP_LEN) - 1) << GLB_REG_MM_SPI_SWAP_POS) +#define GLB_REG_MM_SPI_SWAP_UMSK (~(((1U << GLB_REG_MM_SPI_SWAP_LEN) - 1) << GLB_REG_MM_SPI_SWAP_POS)) +#define GLB_AUDIO_TEST_MODE GLB_AUDIO_TEST_MODE +#define GLB_AUDIO_TEST_MODE_POS (29U) +#define GLB_AUDIO_TEST_MODE_LEN (1U) +#define GLB_AUDIO_TEST_MODE_MSK (((1U << GLB_AUDIO_TEST_MODE_LEN) - 1) << GLB_AUDIO_TEST_MODE_POS) +#define GLB_AUDIO_TEST_MODE_UMSK (~(((1U << GLB_AUDIO_TEST_MODE_LEN) - 1) << GLB_AUDIO_TEST_MODE_POS)) +#define GLB_SEL_RF_AUDIO_TEST GLB_SEL_RF_AUDIO_TEST +#define GLB_SEL_RF_AUDIO_TEST_POS (30U) +#define GLB_SEL_RF_AUDIO_TEST_LEN (2U) +#define GLB_SEL_RF_AUDIO_TEST_MSK (((1U << GLB_SEL_RF_AUDIO_TEST_LEN) - 1) << GLB_SEL_RF_AUDIO_TEST_POS) +#define GLB_SEL_RF_AUDIO_TEST_UMSK (~(((1U << GLB_SEL_RF_AUDIO_TEST_LEN) - 1) << GLB_SEL_RF_AUDIO_TEST_POS)) + +/* 0x520 : debug_cfg0 */ +#define GLB_DEBUG_CFG0_OFFSET (0x520) + +/* 0x524 : debug_cfg1 */ +#define GLB_DEBUG_CFG1_OFFSET (0x524) +#define GLB_DEBUG_NDRESET_GATE GLB_DEBUG_NDRESET_GATE +#define GLB_DEBUG_NDRESET_GATE_POS (20U) +#define GLB_DEBUG_NDRESET_GATE_LEN (1U) +#define GLB_DEBUG_NDRESET_GATE_MSK (((1U << GLB_DEBUG_NDRESET_GATE_LEN) - 1) << GLB_DEBUG_NDRESET_GATE_POS) +#define GLB_DEBUG_NDRESET_GATE_UMSK (~(((1U << GLB_DEBUG_NDRESET_GATE_LEN) - 1) << GLB_DEBUG_NDRESET_GATE_POS)) + +/* 0x530 : reset_sts0 */ +#define GLB_RESET_STS0_OFFSET (0x530) +#define GLB_TOP_RESET_RECORDER GLB_TOP_RESET_RECORDER +#define GLB_TOP_RESET_RECORDER_POS (0U) +#define GLB_TOP_RESET_RECORDER_LEN (7U) +#define GLB_TOP_RESET_RECORDER_MSK (((1U << GLB_TOP_RESET_RECORDER_LEN) - 1) << GLB_TOP_RESET_RECORDER_POS) +#define GLB_TOP_RESET_RECORDER_UMSK (~(((1U << GLB_TOP_RESET_RECORDER_LEN) - 1) << GLB_TOP_RESET_RECORDER_POS)) +#define GLB_CLR_TOP_RESET_RECORDER GLB_CLR_TOP_RESET_RECORDER +#define GLB_CLR_TOP_RESET_RECORDER_POS (7U) +#define GLB_CLR_TOP_RESET_RECORDER_LEN (1U) +#define GLB_CLR_TOP_RESET_RECORDER_MSK (((1U << GLB_CLR_TOP_RESET_RECORDER_LEN) - 1) << GLB_CLR_TOP_RESET_RECORDER_POS) +#define GLB_CLR_TOP_RESET_RECORDER_UMSK (~(((1U << GLB_CLR_TOP_RESET_RECORDER_LEN) - 1) << GLB_CLR_TOP_RESET_RECORDER_POS)) + +/* 0x540 : swrst_s1_ext + swrst_s3 + swrst_s2 */ +#define GLB_SWRST_CFG0_OFFSET (0x540) +#define GLB_SWRST_S00 GLB_SWRST_S00 +#define GLB_SWRST_S00_POS (0U) +#define GLB_SWRST_S00_LEN (1U) +#define GLB_SWRST_S00_MSK (((1U << GLB_SWRST_S00_LEN) - 1) << GLB_SWRST_S00_POS) +#define GLB_SWRST_S00_UMSK (~(((1U << GLB_SWRST_S00_LEN) - 1) << GLB_SWRST_S00_POS)) +#define GLB_SWRST_S01 GLB_SWRST_S01 +#define GLB_SWRST_S01_POS (1U) +#define GLB_SWRST_S01_LEN (1U) +#define GLB_SWRST_S01_MSK (((1U << GLB_SWRST_S01_LEN) - 1) << GLB_SWRST_S01_POS) +#define GLB_SWRST_S01_UMSK (~(((1U << GLB_SWRST_S01_LEN) - 1) << GLB_SWRST_S01_POS)) +#define GLB_SWRST_S20 GLB_SWRST_S20 +#define GLB_SWRST_S20_POS (4U) +#define GLB_SWRST_S20_LEN (1U) +#define GLB_SWRST_S20_MSK (((1U << GLB_SWRST_S20_LEN) - 1) << GLB_SWRST_S20_POS) +#define GLB_SWRST_S20_UMSK (~(((1U << GLB_SWRST_S20_LEN) - 1) << GLB_SWRST_S20_POS)) +#define GLB_SWRST_S30 GLB_SWRST_S30 +#define GLB_SWRST_S30_POS (8U) +#define GLB_SWRST_S30_LEN (1U) +#define GLB_SWRST_S30_MSK (((1U << GLB_SWRST_S30_LEN) - 1) << GLB_SWRST_S30_POS) +#define GLB_SWRST_S30_UMSK (~(((1U << GLB_SWRST_S30_LEN) - 1) << GLB_SWRST_S30_POS)) +#define GLB_SWRST_S31 GLB_SWRST_S31 +#define GLB_SWRST_S31_POS (9U) +#define GLB_SWRST_S31_LEN (1U) +#define GLB_SWRST_S31_MSK (((1U << GLB_SWRST_S31_LEN) - 1) << GLB_SWRST_S31_POS) +#define GLB_SWRST_S31_UMSK (~(((1U << GLB_SWRST_S31_LEN) - 1) << GLB_SWRST_S31_POS)) +#define GLB_SWRST_S32 GLB_SWRST_S32 +#define GLB_SWRST_S32_POS (10U) +#define GLB_SWRST_S32_LEN (1U) +#define GLB_SWRST_S32_MSK (((1U << GLB_SWRST_S32_LEN) - 1) << GLB_SWRST_S32_POS) +#define GLB_SWRST_S32_UMSK (~(((1U << GLB_SWRST_S32_LEN) - 1) << GLB_SWRST_S32_POS)) +#define GLB_SWRST_S33 GLB_SWRST_S33 +#define GLB_SWRST_S33_POS (11U) +#define GLB_SWRST_S33_LEN (1U) +#define GLB_SWRST_S33_MSK (((1U << GLB_SWRST_S33_LEN) - 1) << GLB_SWRST_S33_POS) +#define GLB_SWRST_S33_UMSK (~(((1U << GLB_SWRST_S33_LEN) - 1) << GLB_SWRST_S33_POS)) +#define GLB_SWRST_S1_EXT_EMI_MISC GLB_SWRST_S1_EXT_EMI_MISC +#define GLB_SWRST_S1_EXT_EMI_MISC_POS (16U) +#define GLB_SWRST_S1_EXT_EMI_MISC_LEN (1U) +#define GLB_SWRST_S1_EXT_EMI_MISC_MSK (((1U << GLB_SWRST_S1_EXT_EMI_MISC_LEN) - 1) << GLB_SWRST_S1_EXT_EMI_MISC_POS) +#define GLB_SWRST_S1_EXT_EMI_MISC_UMSK (~(((1U << GLB_SWRST_S1_EXT_EMI_MISC_LEN) - 1) << GLB_SWRST_S1_EXT_EMI_MISC_POS)) +#define GLB_SWRST_S1_EXT_PSRAM0_CTRL GLB_SWRST_S1_EXT_PSRAM0_CTRL +#define GLB_SWRST_S1_EXT_PSRAM0_CTRL_POS (17U) +#define GLB_SWRST_S1_EXT_PSRAM0_CTRL_LEN (1U) +#define GLB_SWRST_S1_EXT_PSRAM0_CTRL_MSK (((1U << GLB_SWRST_S1_EXT_PSRAM0_CTRL_LEN) - 1) << GLB_SWRST_S1_EXT_PSRAM0_CTRL_POS) +#define GLB_SWRST_S1_EXT_PSRAM0_CTRL_UMSK (~(((1U << GLB_SWRST_S1_EXT_PSRAM0_CTRL_LEN) - 1) << GLB_SWRST_S1_EXT_PSRAM0_CTRL_POS)) +#define GLB_SWRST_S1_EXT_PSRAM1_CTRL GLB_SWRST_S1_EXT_PSRAM1_CTRL +#define GLB_SWRST_S1_EXT_PSRAM1_CTRL_POS (18U) +#define GLB_SWRST_S1_EXT_PSRAM1_CTRL_LEN (1U) +#define GLB_SWRST_S1_EXT_PSRAM1_CTRL_MSK (((1U << GLB_SWRST_S1_EXT_PSRAM1_CTRL_LEN) - 1) << GLB_SWRST_S1_EXT_PSRAM1_CTRL_POS) +#define GLB_SWRST_S1_EXT_PSRAM1_CTRL_UMSK (~(((1U << GLB_SWRST_S1_EXT_PSRAM1_CTRL_LEN) - 1) << GLB_SWRST_S1_EXT_PSRAM1_CTRL_POS)) +#define GLB_SWRST_S1_EXT_USB GLB_SWRST_S1_EXT_USB +#define GLB_SWRST_S1_EXT_USB_POS (19U) +#define GLB_SWRST_S1_EXT_USB_LEN (1U) +#define GLB_SWRST_S1_EXT_USB_MSK (((1U << GLB_SWRST_S1_EXT_USB_LEN) - 1) << GLB_SWRST_S1_EXT_USB_POS) +#define GLB_SWRST_S1_EXT_USB_UMSK (~(((1U << GLB_SWRST_S1_EXT_USB_LEN) - 1) << GLB_SWRST_S1_EXT_USB_POS)) +#define GLB_SWRST_S1_EXT_MIX2 GLB_SWRST_S1_EXT_MIX2 +#define GLB_SWRST_S1_EXT_MIX2_POS (20U) +#define GLB_SWRST_S1_EXT_MIX2_LEN (1U) +#define GLB_SWRST_S1_EXT_MIX2_MSK (((1U << GLB_SWRST_S1_EXT_MIX2_LEN) - 1) << GLB_SWRST_S1_EXT_MIX2_POS) +#define GLB_SWRST_S1_EXT_MIX2_UMSK (~(((1U << GLB_SWRST_S1_EXT_MIX2_LEN) - 1) << GLB_SWRST_S1_EXT_MIX2_POS)) +#define GLB_SWRST_S1_EXT_AUDIO GLB_SWRST_S1_EXT_AUDIO +#define GLB_SWRST_S1_EXT_AUDIO_POS (21U) +#define GLB_SWRST_S1_EXT_AUDIO_LEN (1U) +#define GLB_SWRST_S1_EXT_AUDIO_MSK (((1U << GLB_SWRST_S1_EXT_AUDIO_LEN) - 1) << GLB_SWRST_S1_EXT_AUDIO_POS) +#define GLB_SWRST_S1_EXT_AUDIO_UMSK (~(((1U << GLB_SWRST_S1_EXT_AUDIO_LEN) - 1) << GLB_SWRST_S1_EXT_AUDIO_POS)) +#define GLB_SWRST_S1_EXT_SDH GLB_SWRST_S1_EXT_SDH +#define GLB_SWRST_S1_EXT_SDH_POS (22U) +#define GLB_SWRST_S1_EXT_SDH_LEN (1U) +#define GLB_SWRST_S1_EXT_SDH_MSK (((1U << GLB_SWRST_S1_EXT_SDH_LEN) - 1) << GLB_SWRST_S1_EXT_SDH_POS) +#define GLB_SWRST_S1_EXT_SDH_UMSK (~(((1U << GLB_SWRST_S1_EXT_SDH_LEN) - 1) << GLB_SWRST_S1_EXT_SDH_POS)) +#define GLB_SWRST_S1_EXT_EMAC GLB_SWRST_S1_EXT_EMAC +#define GLB_SWRST_S1_EXT_EMAC_POS (23U) +#define GLB_SWRST_S1_EXT_EMAC_LEN (1U) +#define GLB_SWRST_S1_EXT_EMAC_MSK (((1U << GLB_SWRST_S1_EXT_EMAC_LEN) - 1) << GLB_SWRST_S1_EXT_EMAC_POS) +#define GLB_SWRST_S1_EXT_EMAC_UMSK (~(((1U << GLB_SWRST_S1_EXT_EMAC_LEN) - 1) << GLB_SWRST_S1_EXT_EMAC_POS)) +#define GLB_SWRST_S1_EXT_DMA2 GLB_SWRST_S1_EXT_DMA2 +#define GLB_SWRST_S1_EXT_DMA2_POS (24U) +#define GLB_SWRST_S1_EXT_DMA2_LEN (1U) +#define GLB_SWRST_S1_EXT_DMA2_MSK (((1U << GLB_SWRST_S1_EXT_DMA2_LEN) - 1) << GLB_SWRST_S1_EXT_DMA2_POS) +#define GLB_SWRST_S1_EXT_DMA2_UMSK (~(((1U << GLB_SWRST_S1_EXT_DMA2_LEN) - 1) << GLB_SWRST_S1_EXT_DMA2_POS)) + +/* 0x544 : swrst_s1 */ +#define GLB_SWRST_CFG1_OFFSET (0x544) +#define GLB_SWRST_S10 GLB_SWRST_S10 +#define GLB_SWRST_S10_POS (0U) +#define GLB_SWRST_S10_LEN (1U) +#define GLB_SWRST_S10_MSK (((1U << GLB_SWRST_S10_LEN) - 1) << GLB_SWRST_S10_POS) +#define GLB_SWRST_S10_UMSK (~(((1U << GLB_SWRST_S10_LEN) - 1) << GLB_SWRST_S10_POS)) +#define GLB_SWRST_S11 GLB_SWRST_S11 +#define GLB_SWRST_S11_POS (1U) +#define GLB_SWRST_S11_LEN (1U) +#define GLB_SWRST_S11_MSK (((1U << GLB_SWRST_S11_LEN) - 1) << GLB_SWRST_S11_POS) +#define GLB_SWRST_S11_UMSK (~(((1U << GLB_SWRST_S11_LEN) - 1) << GLB_SWRST_S11_POS)) +#define GLB_SWRST_S12 GLB_SWRST_S12 +#define GLB_SWRST_S12_POS (2U) +#define GLB_SWRST_S12_LEN (1U) +#define GLB_SWRST_S12_MSK (((1U << GLB_SWRST_S12_LEN) - 1) << GLB_SWRST_S12_POS) +#define GLB_SWRST_S12_UMSK (~(((1U << GLB_SWRST_S12_LEN) - 1) << GLB_SWRST_S12_POS)) +#define GLB_SWRST_S13 GLB_SWRST_S13 +#define GLB_SWRST_S13_POS (3U) +#define GLB_SWRST_S13_LEN (1U) +#define GLB_SWRST_S13_MSK (((1U << GLB_SWRST_S13_LEN) - 1) << GLB_SWRST_S13_POS) +#define GLB_SWRST_S13_UMSK (~(((1U << GLB_SWRST_S13_LEN) - 1) << GLB_SWRST_S13_POS)) +#define GLB_SWRST_S14 GLB_SWRST_S14 +#define GLB_SWRST_S14_POS (4U) +#define GLB_SWRST_S14_LEN (1U) +#define GLB_SWRST_S14_MSK (((1U << GLB_SWRST_S14_LEN) - 1) << GLB_SWRST_S14_POS) +#define GLB_SWRST_S14_UMSK (~(((1U << GLB_SWRST_S14_LEN) - 1) << GLB_SWRST_S14_POS)) +#define GLB_SWRST_S15 GLB_SWRST_S15 +#define GLB_SWRST_S15_POS (5U) +#define GLB_SWRST_S15_LEN (1U) +#define GLB_SWRST_S15_MSK (((1U << GLB_SWRST_S15_LEN) - 1) << GLB_SWRST_S15_POS) +#define GLB_SWRST_S15_UMSK (~(((1U << GLB_SWRST_S15_LEN) - 1) << GLB_SWRST_S15_POS)) +#define GLB_SWRST_S16 GLB_SWRST_S16 +#define GLB_SWRST_S16_POS (6U) +#define GLB_SWRST_S16_LEN (1U) +#define GLB_SWRST_S16_MSK (((1U << GLB_SWRST_S16_LEN) - 1) << GLB_SWRST_S16_POS) +#define GLB_SWRST_S16_UMSK (~(((1U << GLB_SWRST_S16_LEN) - 1) << GLB_SWRST_S16_POS)) +#define GLB_SWRST_S17 GLB_SWRST_S17 +#define GLB_SWRST_S17_POS (7U) +#define GLB_SWRST_S17_LEN (1U) +#define GLB_SWRST_S17_MSK (((1U << GLB_SWRST_S17_LEN) - 1) << GLB_SWRST_S17_POS) +#define GLB_SWRST_S17_UMSK (~(((1U << GLB_SWRST_S17_LEN) - 1) << GLB_SWRST_S17_POS)) +#define GLB_SWRST_S18 GLB_SWRST_S18 +#define GLB_SWRST_S18_POS (8U) +#define GLB_SWRST_S18_LEN (1U) +#define GLB_SWRST_S18_MSK (((1U << GLB_SWRST_S18_LEN) - 1) << GLB_SWRST_S18_POS) +#define GLB_SWRST_S18_UMSK (~(((1U << GLB_SWRST_S18_LEN) - 1) << GLB_SWRST_S18_POS)) +#define GLB_SWRST_S19 GLB_SWRST_S19 +#define GLB_SWRST_S19_POS (9U) +#define GLB_SWRST_S19_LEN (1U) +#define GLB_SWRST_S19_MSK (((1U << GLB_SWRST_S19_LEN) - 1) << GLB_SWRST_S19_POS) +#define GLB_SWRST_S19_UMSK (~(((1U << GLB_SWRST_S19_LEN) - 1) << GLB_SWRST_S19_POS)) +#define GLB_SWRST_S1A GLB_SWRST_S1A +#define GLB_SWRST_S1A_POS (10U) +#define GLB_SWRST_S1A_LEN (1U) +#define GLB_SWRST_S1A_MSK (((1U << GLB_SWRST_S1A_LEN) - 1) << GLB_SWRST_S1A_POS) +#define GLB_SWRST_S1A_UMSK (~(((1U << GLB_SWRST_S1A_LEN) - 1) << GLB_SWRST_S1A_POS)) +#define GLB_SWRST_S1B GLB_SWRST_S1B +#define GLB_SWRST_S1B_POS (11U) +#define GLB_SWRST_S1B_LEN (1U) +#define GLB_SWRST_S1B_MSK (((1U << GLB_SWRST_S1B_LEN) - 1) << GLB_SWRST_S1B_POS) +#define GLB_SWRST_S1B_UMSK (~(((1U << GLB_SWRST_S1B_LEN) - 1) << GLB_SWRST_S1B_POS)) +#define GLB_SWRST_S1C GLB_SWRST_S1C +#define GLB_SWRST_S1C_POS (12U) +#define GLB_SWRST_S1C_LEN (1U) +#define GLB_SWRST_S1C_MSK (((1U << GLB_SWRST_S1C_LEN) - 1) << GLB_SWRST_S1C_POS) +#define GLB_SWRST_S1C_UMSK (~(((1U << GLB_SWRST_S1C_LEN) - 1) << GLB_SWRST_S1C_POS)) +#define GLB_SWRST_S1D GLB_SWRST_S1D +#define GLB_SWRST_S1D_POS (13U) +#define GLB_SWRST_S1D_LEN (1U) +#define GLB_SWRST_S1D_MSK (((1U << GLB_SWRST_S1D_LEN) - 1) << GLB_SWRST_S1D_POS) +#define GLB_SWRST_S1D_UMSK (~(((1U << GLB_SWRST_S1D_LEN) - 1) << GLB_SWRST_S1D_POS)) +#define GLB_SWRST_S1E GLB_SWRST_S1E +#define GLB_SWRST_S1E_POS (14U) +#define GLB_SWRST_S1E_LEN (1U) +#define GLB_SWRST_S1E_MSK (((1U << GLB_SWRST_S1E_LEN) - 1) << GLB_SWRST_S1E_POS) +#define GLB_SWRST_S1E_UMSK (~(((1U << GLB_SWRST_S1E_LEN) - 1) << GLB_SWRST_S1E_POS)) +#define GLB_SWRST_S1F GLB_SWRST_S1F +#define GLB_SWRST_S1F_POS (15U) +#define GLB_SWRST_S1F_LEN (1U) +#define GLB_SWRST_S1F_MSK (((1U << GLB_SWRST_S1F_LEN) - 1) << GLB_SWRST_S1F_POS) +#define GLB_SWRST_S1F_UMSK (~(((1U << GLB_SWRST_S1F_LEN) - 1) << GLB_SWRST_S1F_POS)) +#define GLB_SWRST_S1A0 GLB_SWRST_S1A0 +#define GLB_SWRST_S1A0_POS (16U) +#define GLB_SWRST_S1A0_LEN (1U) +#define GLB_SWRST_S1A0_MSK (((1U << GLB_SWRST_S1A0_LEN) - 1) << GLB_SWRST_S1A0_POS) +#define GLB_SWRST_S1A0_UMSK (~(((1U << GLB_SWRST_S1A0_LEN) - 1) << GLB_SWRST_S1A0_POS)) +#define GLB_SWRST_S1A1 GLB_SWRST_S1A1 +#define GLB_SWRST_S1A1_POS (17U) +#define GLB_SWRST_S1A1_LEN (1U) +#define GLB_SWRST_S1A1_MSK (((1U << GLB_SWRST_S1A1_LEN) - 1) << GLB_SWRST_S1A1_POS) +#define GLB_SWRST_S1A1_UMSK (~(((1U << GLB_SWRST_S1A1_LEN) - 1) << GLB_SWRST_S1A1_POS)) +#define GLB_SWRST_S1A2 GLB_SWRST_S1A2 +#define GLB_SWRST_S1A2_POS (18U) +#define GLB_SWRST_S1A2_LEN (1U) +#define GLB_SWRST_S1A2_MSK (((1U << GLB_SWRST_S1A2_LEN) - 1) << GLB_SWRST_S1A2_POS) +#define GLB_SWRST_S1A2_UMSK (~(((1U << GLB_SWRST_S1A2_LEN) - 1) << GLB_SWRST_S1A2_POS)) +#define GLB_SWRST_S1A3 GLB_SWRST_S1A3 +#define GLB_SWRST_S1A3_POS (19U) +#define GLB_SWRST_S1A3_LEN (1U) +#define GLB_SWRST_S1A3_MSK (((1U << GLB_SWRST_S1A3_LEN) - 1) << GLB_SWRST_S1A3_POS) +#define GLB_SWRST_S1A3_UMSK (~(((1U << GLB_SWRST_S1A3_LEN) - 1) << GLB_SWRST_S1A3_POS)) +#define GLB_SWRST_S1A4 GLB_SWRST_S1A4 +#define GLB_SWRST_S1A4_POS (20U) +#define GLB_SWRST_S1A4_LEN (1U) +#define GLB_SWRST_S1A4_MSK (((1U << GLB_SWRST_S1A4_LEN) - 1) << GLB_SWRST_S1A4_POS) +#define GLB_SWRST_S1A4_UMSK (~(((1U << GLB_SWRST_S1A4_LEN) - 1) << GLB_SWRST_S1A4_POS)) +#define GLB_SWRST_S1A5 GLB_SWRST_S1A5 +#define GLB_SWRST_S1A5_POS (21U) +#define GLB_SWRST_S1A5_LEN (1U) +#define GLB_SWRST_S1A5_MSK (((1U << GLB_SWRST_S1A5_LEN) - 1) << GLB_SWRST_S1A5_POS) +#define GLB_SWRST_S1A5_UMSK (~(((1U << GLB_SWRST_S1A5_LEN) - 1) << GLB_SWRST_S1A5_POS)) +#define GLB_SWRST_S1A6 GLB_SWRST_S1A6 +#define GLB_SWRST_S1A6_POS (22U) +#define GLB_SWRST_S1A6_LEN (1U) +#define GLB_SWRST_S1A6_MSK (((1U << GLB_SWRST_S1A6_LEN) - 1) << GLB_SWRST_S1A6_POS) +#define GLB_SWRST_S1A6_UMSK (~(((1U << GLB_SWRST_S1A6_LEN) - 1) << GLB_SWRST_S1A6_POS)) +#define GLB_SWRST_S1A7 GLB_SWRST_S1A7 +#define GLB_SWRST_S1A7_POS (23U) +#define GLB_SWRST_S1A7_LEN (1U) +#define GLB_SWRST_S1A7_MSK (((1U << GLB_SWRST_S1A7_LEN) - 1) << GLB_SWRST_S1A7_POS) +#define GLB_SWRST_S1A7_UMSK (~(((1U << GLB_SWRST_S1A7_LEN) - 1) << GLB_SWRST_S1A7_POS)) +#define GLB_SWRST_S1A8 GLB_SWRST_S1A8 +#define GLB_SWRST_S1A8_POS (24U) +#define GLB_SWRST_S1A8_LEN (1U) +#define GLB_SWRST_S1A8_MSK (((1U << GLB_SWRST_S1A8_LEN) - 1) << GLB_SWRST_S1A8_POS) +#define GLB_SWRST_S1A8_UMSK (~(((1U << GLB_SWRST_S1A8_LEN) - 1) << GLB_SWRST_S1A8_POS)) +#define GLB_SWRST_S1A9 GLB_SWRST_S1A9 +#define GLB_SWRST_S1A9_POS (25U) +#define GLB_SWRST_S1A9_LEN (1U) +#define GLB_SWRST_S1A9_MSK (((1U << GLB_SWRST_S1A9_LEN) - 1) << GLB_SWRST_S1A9_POS) +#define GLB_SWRST_S1A9_UMSK (~(((1U << GLB_SWRST_S1A9_LEN) - 1) << GLB_SWRST_S1A9_POS)) +#define GLB_SWRST_S1AA GLB_SWRST_S1AA +#define GLB_SWRST_S1AA_POS (26U) +#define GLB_SWRST_S1AA_LEN (1U) +#define GLB_SWRST_S1AA_MSK (((1U << GLB_SWRST_S1AA_LEN) - 1) << GLB_SWRST_S1AA_POS) +#define GLB_SWRST_S1AA_UMSK (~(((1U << GLB_SWRST_S1AA_LEN) - 1) << GLB_SWRST_S1AA_POS)) +#define GLB_SWRST_S1AB GLB_SWRST_S1AB +#define GLB_SWRST_S1AB_POS (27U) +#define GLB_SWRST_S1AB_LEN (1U) +#define GLB_SWRST_S1AB_MSK (((1U << GLB_SWRST_S1AB_LEN) - 1) << GLB_SWRST_S1AB_POS) +#define GLB_SWRST_S1AB_UMSK (~(((1U << GLB_SWRST_S1AB_LEN) - 1) << GLB_SWRST_S1AB_POS)) +#define GLB_SWRST_S1AC GLB_SWRST_S1AC +#define GLB_SWRST_S1AC_POS (28U) +#define GLB_SWRST_S1AC_LEN (1U) +#define GLB_SWRST_S1AC_MSK (((1U << GLB_SWRST_S1AC_LEN) - 1) << GLB_SWRST_S1AC_POS) +#define GLB_SWRST_S1AC_UMSK (~(((1U << GLB_SWRST_S1AC_LEN) - 1) << GLB_SWRST_S1AC_POS)) +#define GLB_SWRST_S1AD GLB_SWRST_S1AD +#define GLB_SWRST_S1AD_POS (29U) +#define GLB_SWRST_S1AD_LEN (1U) +#define GLB_SWRST_S1AD_MSK (((1U << GLB_SWRST_S1AD_LEN) - 1) << GLB_SWRST_S1AD_POS) +#define GLB_SWRST_S1AD_UMSK (~(((1U << GLB_SWRST_S1AD_LEN) - 1) << GLB_SWRST_S1AD_POS)) +#define GLB_SWRST_S1AE GLB_SWRST_S1AE +#define GLB_SWRST_S1AE_POS (30U) +#define GLB_SWRST_S1AE_LEN (1U) +#define GLB_SWRST_S1AE_MSK (((1U << GLB_SWRST_S1AE_LEN) - 1) << GLB_SWRST_S1AE_POS) +#define GLB_SWRST_S1AE_UMSK (~(((1U << GLB_SWRST_S1AE_LEN) - 1) << GLB_SWRST_S1AE_POS)) +#define GLB_SWRST_S1AF GLB_SWRST_S1AF +#define GLB_SWRST_S1AF_POS (31U) +#define GLB_SWRST_S1AF_LEN (1U) +#define GLB_SWRST_S1AF_MSK (((1U << GLB_SWRST_S1AF_LEN) - 1) << GLB_SWRST_S1AF_POS) +#define GLB_SWRST_S1AF_UMSK (~(((1U << GLB_SWRST_S1AF_LEN) - 1) << GLB_SWRST_S1AF_POS)) + +/* 0x548 : swrst_cfg2 */ +#define GLB_SWRST_CFG2_OFFSET (0x548) +#define GLB_REG_CTRL_PWRON_RST GLB_REG_CTRL_PWRON_RST +#define GLB_REG_CTRL_PWRON_RST_POS (0U) +#define GLB_REG_CTRL_PWRON_RST_LEN (1U) +#define GLB_REG_CTRL_PWRON_RST_MSK (((1U << GLB_REG_CTRL_PWRON_RST_LEN) - 1) << GLB_REG_CTRL_PWRON_RST_POS) +#define GLB_REG_CTRL_PWRON_RST_UMSK (~(((1U << GLB_REG_CTRL_PWRON_RST_LEN) - 1) << GLB_REG_CTRL_PWRON_RST_POS)) +#define GLB_REG_CTRL_CPU_RESET GLB_REG_CTRL_CPU_RESET +#define GLB_REG_CTRL_CPU_RESET_POS (1U) +#define GLB_REG_CTRL_CPU_RESET_LEN (1U) +#define GLB_REG_CTRL_CPU_RESET_MSK (((1U << GLB_REG_CTRL_CPU_RESET_LEN) - 1) << GLB_REG_CTRL_CPU_RESET_POS) +#define GLB_REG_CTRL_CPU_RESET_UMSK (~(((1U << GLB_REG_CTRL_CPU_RESET_LEN) - 1) << GLB_REG_CTRL_CPU_RESET_POS)) +#define GLB_REG_CTRL_SYS_RESET GLB_REG_CTRL_SYS_RESET +#define GLB_REG_CTRL_SYS_RESET_POS (2U) +#define GLB_REG_CTRL_SYS_RESET_LEN (1U) +#define GLB_REG_CTRL_SYS_RESET_MSK (((1U << GLB_REG_CTRL_SYS_RESET_LEN) - 1) << GLB_REG_CTRL_SYS_RESET_POS) +#define GLB_REG_CTRL_SYS_RESET_UMSK (~(((1U << GLB_REG_CTRL_SYS_RESET_LEN) - 1) << GLB_REG_CTRL_SYS_RESET_POS)) +#define GLB_REG_CTRL_PICO_RESET GLB_REG_CTRL_PICO_RESET +#define GLB_REG_CTRL_PICO_RESET_POS (3U) +#define GLB_REG_CTRL_PICO_RESET_LEN (1U) +#define GLB_REG_CTRL_PICO_RESET_MSK (((1U << GLB_REG_CTRL_PICO_RESET_LEN) - 1) << GLB_REG_CTRL_PICO_RESET_POS) +#define GLB_REG_CTRL_PICO_RESET_UMSK (~(((1U << GLB_REG_CTRL_PICO_RESET_LEN) - 1) << GLB_REG_CTRL_PICO_RESET_POS)) +#define GLB_REG_CTRL_CPU2_RESET GLB_REG_CTRL_CPU2_RESET +#define GLB_REG_CTRL_CPU2_RESET_POS (4U) +#define GLB_REG_CTRL_CPU2_RESET_LEN (1U) +#define GLB_REG_CTRL_CPU2_RESET_MSK (((1U << GLB_REG_CTRL_CPU2_RESET_LEN) - 1) << GLB_REG_CTRL_CPU2_RESET_POS) +#define GLB_REG_CTRL_CPU2_RESET_UMSK (~(((1U << GLB_REG_CTRL_CPU2_RESET_LEN) - 1) << GLB_REG_CTRL_CPU2_RESET_POS)) +#define GLB_REG_CTRL_CHIP_RESET GLB_REG_CTRL_CHIP_RESET +#define GLB_REG_CTRL_CHIP_RESET_POS (5U) +#define GLB_REG_CTRL_CHIP_RESET_LEN (1U) +#define GLB_REG_CTRL_CHIP_RESET_MSK (((1U << GLB_REG_CTRL_CHIP_RESET_LEN) - 1) << GLB_REG_CTRL_CHIP_RESET_POS) +#define GLB_REG_CTRL_CHIP_RESET_UMSK (~(((1U << GLB_REG_CTRL_CHIP_RESET_LEN) - 1) << GLB_REG_CTRL_CHIP_RESET_POS)) +#define GLB_REG_WL_WDT_RESET_MM_EN GLB_REG_WL_WDT_RESET_MM_EN +#define GLB_REG_WL_WDT_RESET_MM_EN_POS (6U) +#define GLB_REG_WL_WDT_RESET_MM_EN_LEN (1U) +#define GLB_REG_WL_WDT_RESET_MM_EN_MSK (((1U << GLB_REG_WL_WDT_RESET_MM_EN_LEN) - 1) << GLB_REG_WL_WDT_RESET_MM_EN_POS) +#define GLB_REG_WL_WDT_RESET_MM_EN_UMSK (~(((1U << GLB_REG_WL_WDT_RESET_MM_EN_LEN) - 1) << GLB_REG_WL_WDT_RESET_MM_EN_POS)) +#define GLB_REG_MMWDT2WL_RST_MSK GLB_REG_MMWDT2WL_RST_MSK +#define GLB_REG_MMWDT2WL_RST_MSK_POS (7U) +#define GLB_REG_MMWDT2WL_RST_MSK_LEN (1U) +#define GLB_REG_MMWDT2WL_RST_MSK_MSK (((1U << GLB_REG_MMWDT2WL_RST_MSK_LEN) - 1) << GLB_REG_MMWDT2WL_RST_MSK_POS) +#define GLB_REG_MMWDT2WL_RST_MSK_UMSK (~(((1U << GLB_REG_MMWDT2WL_RST_MSK_LEN) - 1) << GLB_REG_MMWDT2WL_RST_MSK_POS)) +#define GLB_PKA_CLK_SEL GLB_PKA_CLK_SEL +#define GLB_PKA_CLK_SEL_POS (24U) +#define GLB_PKA_CLK_SEL_LEN (1U) +#define GLB_PKA_CLK_SEL_MSK (((1U << GLB_PKA_CLK_SEL_LEN) - 1) << GLB_PKA_CLK_SEL_POS) +#define GLB_PKA_CLK_SEL_UMSK (~(((1U << GLB_PKA_CLK_SEL_LEN) - 1) << GLB_PKA_CLK_SEL_POS)) +#define GLB_REG_CTRL_RESET_DUMMY GLB_REG_CTRL_RESET_DUMMY +#define GLB_REG_CTRL_RESET_DUMMY_POS (28U) +#define GLB_REG_CTRL_RESET_DUMMY_LEN (4U) +#define GLB_REG_CTRL_RESET_DUMMY_MSK (((1U << GLB_REG_CTRL_RESET_DUMMY_LEN) - 1) << GLB_REG_CTRL_RESET_DUMMY_POS) +#define GLB_REG_CTRL_RESET_DUMMY_UMSK (~(((1U << GLB_REG_CTRL_RESET_DUMMY_LEN) - 1) << GLB_REG_CTRL_RESET_DUMMY_POS)) + +/* 0x54C : Disable hreset */ +#define GLB_SWRST_CFG3_OFFSET (0x54C) +#define GLB_DISRST_S12 GLB_DISRST_S12 +#define GLB_DISRST_S12_POS (2U) +#define GLB_DISRST_S12_LEN (1U) +#define GLB_DISRST_S12_MSK (((1U << GLB_DISRST_S12_LEN) - 1) << GLB_DISRST_S12_POS) +#define GLB_DISRST_S12_UMSK (~(((1U << GLB_DISRST_S12_LEN) - 1) << GLB_DISRST_S12_POS)) +#define GLB_DISRST_S14 GLB_DISRST_S14 +#define GLB_DISRST_S14_POS (4U) +#define GLB_DISRST_S14_LEN (1U) +#define GLB_DISRST_S14_MSK (((1U << GLB_DISRST_S14_LEN) - 1) << GLB_DISRST_S14_POS) +#define GLB_DISRST_S14_UMSK (~(((1U << GLB_DISRST_S14_LEN) - 1) << GLB_DISRST_S14_POS)) +#define GLB_DISRST_S18 GLB_DISRST_S18 +#define GLB_DISRST_S18_POS (8U) +#define GLB_DISRST_S18_LEN (1U) +#define GLB_DISRST_S18_MSK (((1U << GLB_DISRST_S18_LEN) - 1) << GLB_DISRST_S18_POS) +#define GLB_DISRST_S18_UMSK (~(((1U << GLB_DISRST_S18_LEN) - 1) << GLB_DISRST_S18_POS)) +#define GLB_DISRST_S1B GLB_DISRST_S1B +#define GLB_DISRST_S1B_POS (11U) +#define GLB_DISRST_S1B_LEN (1U) +#define GLB_DISRST_S1B_MSK (((1U << GLB_DISRST_S1B_LEN) - 1) << GLB_DISRST_S1B_POS) +#define GLB_DISRST_S1B_UMSK (~(((1U << GLB_DISRST_S1B_LEN) - 1) << GLB_DISRST_S1B_POS)) +#define GLB_DISRST_S1A0 GLB_DISRST_S1A0 +#define GLB_DISRST_S1A0_POS (16U) +#define GLB_DISRST_S1A0_LEN (1U) +#define GLB_DISRST_S1A0_MSK (((1U << GLB_DISRST_S1A0_LEN) - 1) << GLB_DISRST_S1A0_POS) +#define GLB_DISRST_S1A0_UMSK (~(((1U << GLB_DISRST_S1A0_LEN) - 1) << GLB_DISRST_S1A0_POS)) +#define GLB_DISRST_S1A1 GLB_DISRST_S1A1 +#define GLB_DISRST_S1A1_POS (17U) +#define GLB_DISRST_S1A1_LEN (1U) +#define GLB_DISRST_S1A1_MSK (((1U << GLB_DISRST_S1A1_LEN) - 1) << GLB_DISRST_S1A1_POS) +#define GLB_DISRST_S1A1_UMSK (~(((1U << GLB_DISRST_S1A1_LEN) - 1) << GLB_DISRST_S1A1_POS)) +#define GLB_DISRST_S1A2 GLB_DISRST_S1A2 +#define GLB_DISRST_S1A2_POS (18U) +#define GLB_DISRST_S1A2_LEN (1U) +#define GLB_DISRST_S1A2_MSK (((1U << GLB_DISRST_S1A2_LEN) - 1) << GLB_DISRST_S1A2_POS) +#define GLB_DISRST_S1A2_UMSK (~(((1U << GLB_DISRST_S1A2_LEN) - 1) << GLB_DISRST_S1A2_POS)) +#define GLB_DISRST_S1A3 GLB_DISRST_S1A3 +#define GLB_DISRST_S1A3_POS (19U) +#define GLB_DISRST_S1A3_LEN (1U) +#define GLB_DISRST_S1A3_MSK (((1U << GLB_DISRST_S1A3_LEN) - 1) << GLB_DISRST_S1A3_POS) +#define GLB_DISRST_S1A3_UMSK (~(((1U << GLB_DISRST_S1A3_LEN) - 1) << GLB_DISRST_S1A3_POS)) +#define GLB_DISRST_S1A4 GLB_DISRST_S1A4 +#define GLB_DISRST_S1A4_POS (20U) +#define GLB_DISRST_S1A4_LEN (1U) +#define GLB_DISRST_S1A4_MSK (((1U << GLB_DISRST_S1A4_LEN) - 1) << GLB_DISRST_S1A4_POS) +#define GLB_DISRST_S1A4_UMSK (~(((1U << GLB_DISRST_S1A4_LEN) - 1) << GLB_DISRST_S1A4_POS)) +#define GLB_DISRST_S1A5 GLB_DISRST_S1A5 +#define GLB_DISRST_S1A5_POS (21U) +#define GLB_DISRST_S1A5_LEN (1U) +#define GLB_DISRST_S1A5_MSK (((1U << GLB_DISRST_S1A5_LEN) - 1) << GLB_DISRST_S1A5_POS) +#define GLB_DISRST_S1A5_UMSK (~(((1U << GLB_DISRST_S1A5_LEN) - 1) << GLB_DISRST_S1A5_POS)) +#define GLB_DISRST_S1A6 GLB_DISRST_S1A6 +#define GLB_DISRST_S1A6_POS (22U) +#define GLB_DISRST_S1A6_LEN (1U) +#define GLB_DISRST_S1A6_MSK (((1U << GLB_DISRST_S1A6_LEN) - 1) << GLB_DISRST_S1A6_POS) +#define GLB_DISRST_S1A6_UMSK (~(((1U << GLB_DISRST_S1A6_LEN) - 1) << GLB_DISRST_S1A6_POS)) +#define GLB_DISRST_S1A7 GLB_DISRST_S1A7 +#define GLB_DISRST_S1A7_POS (23U) +#define GLB_DISRST_S1A7_LEN (1U) +#define GLB_DISRST_S1A7_MSK (((1U << GLB_DISRST_S1A7_LEN) - 1) << GLB_DISRST_S1A7_POS) +#define GLB_DISRST_S1A7_UMSK (~(((1U << GLB_DISRST_S1A7_LEN) - 1) << GLB_DISRST_S1A7_POS)) +#define GLB_DISRST_S1A8 GLB_DISRST_S1A8 +#define GLB_DISRST_S1A8_POS (24U) +#define GLB_DISRST_S1A8_LEN (1U) +#define GLB_DISRST_S1A8_MSK (((1U << GLB_DISRST_S1A8_LEN) - 1) << GLB_DISRST_S1A8_POS) +#define GLB_DISRST_S1A8_UMSK (~(((1U << GLB_DISRST_S1A8_LEN) - 1) << GLB_DISRST_S1A8_POS)) +#define GLB_DISRST_S1A9 GLB_DISRST_S1A9 +#define GLB_DISRST_S1A9_POS (25U) +#define GLB_DISRST_S1A9_LEN (1U) +#define GLB_DISRST_S1A9_MSK (((1U << GLB_DISRST_S1A9_LEN) - 1) << GLB_DISRST_S1A9_POS) +#define GLB_DISRST_S1A9_UMSK (~(((1U << GLB_DISRST_S1A9_LEN) - 1) << GLB_DISRST_S1A9_POS)) +#define GLB_DISRST_S1AA GLB_DISRST_S1AA +#define GLB_DISRST_S1AA_POS (26U) +#define GLB_DISRST_S1AA_LEN (1U) +#define GLB_DISRST_S1AA_MSK (((1U << GLB_DISRST_S1AA_LEN) - 1) << GLB_DISRST_S1AA_POS) +#define GLB_DISRST_S1AA_UMSK (~(((1U << GLB_DISRST_S1AA_LEN) - 1) << GLB_DISRST_S1AA_POS)) + +/* 0x580 : cgen_m */ +#define GLB_CGEN_CFG0_OFFSET (0x580) +#define GLB_CGEN_M_CPU GLB_CGEN_M_CPU +#define GLB_CGEN_M_CPU_POS (0U) +#define GLB_CGEN_M_CPU_LEN (1U) +#define GLB_CGEN_M_CPU_MSK (((1U << GLB_CGEN_M_CPU_LEN) - 1) << GLB_CGEN_M_CPU_POS) +#define GLB_CGEN_M_CPU_UMSK (~(((1U << GLB_CGEN_M_CPU_LEN) - 1) << GLB_CGEN_M_CPU_POS)) +#define GLB_CGEN_M_SDU GLB_CGEN_M_SDU +#define GLB_CGEN_M_SDU_POS (1U) +#define GLB_CGEN_M_SDU_LEN (1U) +#define GLB_CGEN_M_SDU_MSK (((1U << GLB_CGEN_M_SDU_LEN) - 1) << GLB_CGEN_M_SDU_POS) +#define GLB_CGEN_M_SDU_UMSK (~(((1U << GLB_CGEN_M_SDU_LEN) - 1) << GLB_CGEN_M_SDU_POS)) +#define GLB_CGEN_M_SEC GLB_CGEN_M_SEC +#define GLB_CGEN_M_SEC_POS (2U) +#define GLB_CGEN_M_SEC_LEN (1U) +#define GLB_CGEN_M_SEC_MSK (((1U << GLB_CGEN_M_SEC_LEN) - 1) << GLB_CGEN_M_SEC_POS) +#define GLB_CGEN_M_SEC_UMSK (~(((1U << GLB_CGEN_M_SEC_LEN) - 1) << GLB_CGEN_M_SEC_POS)) +#define GLB_CGEN_M_DMA GLB_CGEN_M_DMA +#define GLB_CGEN_M_DMA_POS (3U) +#define GLB_CGEN_M_DMA_LEN (1U) +#define GLB_CGEN_M_DMA_MSK (((1U << GLB_CGEN_M_DMA_LEN) - 1) << GLB_CGEN_M_DMA_POS) +#define GLB_CGEN_M_DMA_UMSK (~(((1U << GLB_CGEN_M_DMA_LEN) - 1) << GLB_CGEN_M_DMA_POS)) +#define GLB_CGEN_M_CCI GLB_CGEN_M_CCI +#define GLB_CGEN_M_CCI_POS (4U) +#define GLB_CGEN_M_CCI_LEN (1U) +#define GLB_CGEN_M_CCI_MSK (((1U << GLB_CGEN_M_CCI_LEN) - 1) << GLB_CGEN_M_CCI_POS) +#define GLB_CGEN_M_CCI_UMSK (~(((1U << GLB_CGEN_M_CCI_LEN) - 1) << GLB_CGEN_M_CCI_POS)) + +/* 0x584 : cgen_s1a + cgen_s1 */ +#define GLB_CGEN_CFG1_OFFSET (0x584) +#define GLB_CGEN_S1_RSVD0 GLB_CGEN_S1_RSVD0 +#define GLB_CGEN_S1_RSVD0_POS (0U) +#define GLB_CGEN_S1_RSVD0_LEN (1U) +#define GLB_CGEN_S1_RSVD0_MSK (((1U << GLB_CGEN_S1_RSVD0_LEN) - 1) << GLB_CGEN_S1_RSVD0_POS) +#define GLB_CGEN_S1_RSVD0_UMSK (~(((1U << GLB_CGEN_S1_RSVD0_LEN) - 1) << GLB_CGEN_S1_RSVD0_POS)) +#define GLB_CGEN_S1_GPIP GLB_CGEN_S1_GPIP +#define GLB_CGEN_S1_GPIP_POS (2U) +#define GLB_CGEN_S1_GPIP_LEN (1U) +#define GLB_CGEN_S1_GPIP_MSK (((1U << GLB_CGEN_S1_GPIP_LEN) - 1) << GLB_CGEN_S1_GPIP_POS) +#define GLB_CGEN_S1_GPIP_UMSK (~(((1U << GLB_CGEN_S1_GPIP_LEN) - 1) << GLB_CGEN_S1_GPIP_POS)) +#define GLB_CGEN_S1_SEC_DBG GLB_CGEN_S1_SEC_DBG +#define GLB_CGEN_S1_SEC_DBG_POS (3U) +#define GLB_CGEN_S1_SEC_DBG_LEN (1U) +#define GLB_CGEN_S1_SEC_DBG_MSK (((1U << GLB_CGEN_S1_SEC_DBG_LEN) - 1) << GLB_CGEN_S1_SEC_DBG_POS) +#define GLB_CGEN_S1_SEC_DBG_UMSK (~(((1U << GLB_CGEN_S1_SEC_DBG_LEN) - 1) << GLB_CGEN_S1_SEC_DBG_POS)) +#define GLB_CGEN_S1_SEC_ENG GLB_CGEN_S1_SEC_ENG +#define GLB_CGEN_S1_SEC_ENG_POS (4U) +#define GLB_CGEN_S1_SEC_ENG_LEN (1U) +#define GLB_CGEN_S1_SEC_ENG_MSK (((1U << GLB_CGEN_S1_SEC_ENG_LEN) - 1) << GLB_CGEN_S1_SEC_ENG_POS) +#define GLB_CGEN_S1_SEC_ENG_UMSK (~(((1U << GLB_CGEN_S1_SEC_ENG_LEN) - 1) << GLB_CGEN_S1_SEC_ENG_POS)) +#define GLB_CGEN_S1_TZ GLB_CGEN_S1_TZ +#define GLB_CGEN_S1_TZ_POS (5U) +#define GLB_CGEN_S1_TZ_LEN (1U) +#define GLB_CGEN_S1_TZ_MSK (((1U << GLB_CGEN_S1_TZ_LEN) - 1) << GLB_CGEN_S1_TZ_POS) +#define GLB_CGEN_S1_TZ_UMSK (~(((1U << GLB_CGEN_S1_TZ_LEN) - 1) << GLB_CGEN_S1_TZ_POS)) +#define GLB_CGEN_S1_RSVD6 GLB_CGEN_S1_RSVD6 +#define GLB_CGEN_S1_RSVD6_POS (6U) +#define GLB_CGEN_S1_RSVD6_LEN (1U) +#define GLB_CGEN_S1_RSVD6_MSK (((1U << GLB_CGEN_S1_RSVD6_LEN) - 1) << GLB_CGEN_S1_RSVD6_POS) +#define GLB_CGEN_S1_RSVD6_UMSK (~(((1U << GLB_CGEN_S1_RSVD6_LEN) - 1) << GLB_CGEN_S1_RSVD6_POS)) +#define GLB_CGEN_S1_EF_CTRL GLB_CGEN_S1_EF_CTRL +#define GLB_CGEN_S1_EF_CTRL_POS (7U) +#define GLB_CGEN_S1_EF_CTRL_LEN (1U) +#define GLB_CGEN_S1_EF_CTRL_MSK (((1U << GLB_CGEN_S1_EF_CTRL_LEN) - 1) << GLB_CGEN_S1_EF_CTRL_POS) +#define GLB_CGEN_S1_EF_CTRL_UMSK (~(((1U << GLB_CGEN_S1_EF_CTRL_LEN) - 1) << GLB_CGEN_S1_EF_CTRL_POS)) +#define GLB_CGEN_S1_RSVD8 GLB_CGEN_S1_RSVD8 +#define GLB_CGEN_S1_RSVD8_POS (8U) +#define GLB_CGEN_S1_RSVD8_LEN (1U) +#define GLB_CGEN_S1_RSVD8_MSK (((1U << GLB_CGEN_S1_RSVD8_LEN) - 1) << GLB_CGEN_S1_RSVD8_POS) +#define GLB_CGEN_S1_RSVD8_UMSK (~(((1U << GLB_CGEN_S1_RSVD8_LEN) - 1) << GLB_CGEN_S1_RSVD8_POS)) +#define GLB_CGEN_S1_RSVD9 GLB_CGEN_S1_RSVD9 +#define GLB_CGEN_S1_RSVD9_POS (9U) +#define GLB_CGEN_S1_RSVD9_LEN (1U) +#define GLB_CGEN_S1_RSVD9_MSK (((1U << GLB_CGEN_S1_RSVD9_LEN) - 1) << GLB_CGEN_S1_RSVD9_POS) +#define GLB_CGEN_S1_RSVD9_UMSK (~(((1U << GLB_CGEN_S1_RSVD9_LEN) - 1) << GLB_CGEN_S1_RSVD9_POS)) +#define GLB_CGEN_S1_RSVD10 GLB_CGEN_S1_RSVD10 +#define GLB_CGEN_S1_RSVD10_POS (10U) +#define GLB_CGEN_S1_RSVD10_LEN (1U) +#define GLB_CGEN_S1_RSVD10_MSK (((1U << GLB_CGEN_S1_RSVD10_LEN) - 1) << GLB_CGEN_S1_RSVD10_POS) +#define GLB_CGEN_S1_RSVD10_UMSK (~(((1U << GLB_CGEN_S1_RSVD10_LEN) - 1) << GLB_CGEN_S1_RSVD10_POS)) +#define GLB_CGEN_S1_SF_CTRL GLB_CGEN_S1_SF_CTRL +#define GLB_CGEN_S1_SF_CTRL_POS (11U) +#define GLB_CGEN_S1_SF_CTRL_LEN (1U) +#define GLB_CGEN_S1_SF_CTRL_MSK (((1U << GLB_CGEN_S1_SF_CTRL_LEN) - 1) << GLB_CGEN_S1_SF_CTRL_POS) +#define GLB_CGEN_S1_SF_CTRL_UMSK (~(((1U << GLB_CGEN_S1_SF_CTRL_LEN) - 1) << GLB_CGEN_S1_SF_CTRL_POS)) +#define GLB_CGEN_S1_DMA GLB_CGEN_S1_DMA +#define GLB_CGEN_S1_DMA_POS (12U) +#define GLB_CGEN_S1_DMA_LEN (1U) +#define GLB_CGEN_S1_DMA_MSK (((1U << GLB_CGEN_S1_DMA_LEN) - 1) << GLB_CGEN_S1_DMA_POS) +#define GLB_CGEN_S1_DMA_UMSK (~(((1U << GLB_CGEN_S1_DMA_LEN) - 1) << GLB_CGEN_S1_DMA_POS)) +#define GLB_CGEN_S1_RSVD13 GLB_CGEN_S1_RSVD13 +#define GLB_CGEN_S1_RSVD13_POS (13U) +#define GLB_CGEN_S1_RSVD13_LEN (1U) +#define GLB_CGEN_S1_RSVD13_MSK (((1U << GLB_CGEN_S1_RSVD13_LEN) - 1) << GLB_CGEN_S1_RSVD13_POS) +#define GLB_CGEN_S1_RSVD13_UMSK (~(((1U << GLB_CGEN_S1_RSVD13_LEN) - 1) << GLB_CGEN_S1_RSVD13_POS)) +#define GLB_CGEN_S1_RSVD14 GLB_CGEN_S1_RSVD14 +#define GLB_CGEN_S1_RSVD14_POS (14U) +#define GLB_CGEN_S1_RSVD14_LEN (1U) +#define GLB_CGEN_S1_RSVD14_MSK (((1U << GLB_CGEN_S1_RSVD14_LEN) - 1) << GLB_CGEN_S1_RSVD14_POS) +#define GLB_CGEN_S1_RSVD14_UMSK (~(((1U << GLB_CGEN_S1_RSVD14_LEN) - 1) << GLB_CGEN_S1_RSVD14_POS)) +#define GLB_CGEN_S1_RSVD15 GLB_CGEN_S1_RSVD15 +#define GLB_CGEN_S1_RSVD15_POS (15U) +#define GLB_CGEN_S1_RSVD15_LEN (1U) +#define GLB_CGEN_S1_RSVD15_MSK (((1U << GLB_CGEN_S1_RSVD15_LEN) - 1) << GLB_CGEN_S1_RSVD15_POS) +#define GLB_CGEN_S1_RSVD15_UMSK (~(((1U << GLB_CGEN_S1_RSVD15_LEN) - 1) << GLB_CGEN_S1_RSVD15_POS)) +#define GLB_CGEN_S1A_UART0 GLB_CGEN_S1A_UART0 +#define GLB_CGEN_S1A_UART0_POS (16U) +#define GLB_CGEN_S1A_UART0_LEN (1U) +#define GLB_CGEN_S1A_UART0_MSK (((1U << GLB_CGEN_S1A_UART0_LEN) - 1) << GLB_CGEN_S1A_UART0_POS) +#define GLB_CGEN_S1A_UART0_UMSK (~(((1U << GLB_CGEN_S1A_UART0_LEN) - 1) << GLB_CGEN_S1A_UART0_POS)) +#define GLB_CGEN_S1A_UART1 GLB_CGEN_S1A_UART1 +#define GLB_CGEN_S1A_UART1_POS (17U) +#define GLB_CGEN_S1A_UART1_LEN (1U) +#define GLB_CGEN_S1A_UART1_MSK (((1U << GLB_CGEN_S1A_UART1_LEN) - 1) << GLB_CGEN_S1A_UART1_POS) +#define GLB_CGEN_S1A_UART1_UMSK (~(((1U << GLB_CGEN_S1A_UART1_LEN) - 1) << GLB_CGEN_S1A_UART1_POS)) +#define GLB_CGEN_S1A_SPI GLB_CGEN_S1A_SPI +#define GLB_CGEN_S1A_SPI_POS (18U) +#define GLB_CGEN_S1A_SPI_LEN (1U) +#define GLB_CGEN_S1A_SPI_MSK (((1U << GLB_CGEN_S1A_SPI_LEN) - 1) << GLB_CGEN_S1A_SPI_POS) +#define GLB_CGEN_S1A_SPI_UMSK (~(((1U << GLB_CGEN_S1A_SPI_LEN) - 1) << GLB_CGEN_S1A_SPI_POS)) +#define GLB_CGEN_S1A_I2C GLB_CGEN_S1A_I2C +#define GLB_CGEN_S1A_I2C_POS (19U) +#define GLB_CGEN_S1A_I2C_LEN (1U) +#define GLB_CGEN_S1A_I2C_MSK (((1U << GLB_CGEN_S1A_I2C_LEN) - 1) << GLB_CGEN_S1A_I2C_POS) +#define GLB_CGEN_S1A_I2C_UMSK (~(((1U << GLB_CGEN_S1A_I2C_LEN) - 1) << GLB_CGEN_S1A_I2C_POS)) +#define GLB_CGEN_S1A_PWM GLB_CGEN_S1A_PWM +#define GLB_CGEN_S1A_PWM_POS (20U) +#define GLB_CGEN_S1A_PWM_LEN (1U) +#define GLB_CGEN_S1A_PWM_MSK (((1U << GLB_CGEN_S1A_PWM_LEN) - 1) << GLB_CGEN_S1A_PWM_POS) +#define GLB_CGEN_S1A_PWM_UMSK (~(((1U << GLB_CGEN_S1A_PWM_LEN) - 1) << GLB_CGEN_S1A_PWM_POS)) +#define GLB_CGEN_S1A_TIMER GLB_CGEN_S1A_TIMER +#define GLB_CGEN_S1A_TIMER_POS (21U) +#define GLB_CGEN_S1A_TIMER_LEN (1U) +#define GLB_CGEN_S1A_TIMER_MSK (((1U << GLB_CGEN_S1A_TIMER_LEN) - 1) << GLB_CGEN_S1A_TIMER_POS) +#define GLB_CGEN_S1A_TIMER_UMSK (~(((1U << GLB_CGEN_S1A_TIMER_LEN) - 1) << GLB_CGEN_S1A_TIMER_POS)) +#define GLB_CGEN_S1A_IR GLB_CGEN_S1A_IR +#define GLB_CGEN_S1A_IR_POS (22U) +#define GLB_CGEN_S1A_IR_LEN (1U) +#define GLB_CGEN_S1A_IR_MSK (((1U << GLB_CGEN_S1A_IR_LEN) - 1) << GLB_CGEN_S1A_IR_POS) +#define GLB_CGEN_S1A_IR_UMSK (~(((1U << GLB_CGEN_S1A_IR_LEN) - 1) << GLB_CGEN_S1A_IR_POS)) +#define GLB_CGEN_S1A_CKS GLB_CGEN_S1A_CKS +#define GLB_CGEN_S1A_CKS_POS (23U) +#define GLB_CGEN_S1A_CKS_LEN (1U) +#define GLB_CGEN_S1A_CKS_MSK (((1U << GLB_CGEN_S1A_CKS_LEN) - 1) << GLB_CGEN_S1A_CKS_POS) +#define GLB_CGEN_S1A_CKS_UMSK (~(((1U << GLB_CGEN_S1A_CKS_LEN) - 1) << GLB_CGEN_S1A_CKS_POS)) +#define GLB_CGEN_S1A_RSVD8 GLB_CGEN_S1A_RSVD8 +#define GLB_CGEN_S1A_RSVD8_POS (24U) +#define GLB_CGEN_S1A_RSVD8_LEN (1U) +#define GLB_CGEN_S1A_RSVD8_MSK (((1U << GLB_CGEN_S1A_RSVD8_LEN) - 1) << GLB_CGEN_S1A_RSVD8_POS) +#define GLB_CGEN_S1A_RSVD8_UMSK (~(((1U << GLB_CGEN_S1A_RSVD8_LEN) - 1) << GLB_CGEN_S1A_RSVD8_POS)) +#define GLB_CGEN_S1A_I2C1 GLB_CGEN_S1A_I2C1 +#define GLB_CGEN_S1A_I2C1_POS (25U) +#define GLB_CGEN_S1A_I2C1_LEN (1U) +#define GLB_CGEN_S1A_I2C1_MSK (((1U << GLB_CGEN_S1A_I2C1_LEN) - 1) << GLB_CGEN_S1A_I2C1_POS) +#define GLB_CGEN_S1A_I2C1_UMSK (~(((1U << GLB_CGEN_S1A_I2C1_LEN) - 1) << GLB_CGEN_S1A_I2C1_POS)) +#define GLB_CGEN_S1A_UART2 GLB_CGEN_S1A_UART2 +#define GLB_CGEN_S1A_UART2_POS (26U) +#define GLB_CGEN_S1A_UART2_LEN (1U) +#define GLB_CGEN_S1A_UART2_MSK (((1U << GLB_CGEN_S1A_UART2_LEN) - 1) << GLB_CGEN_S1A_UART2_POS) +#define GLB_CGEN_S1A_UART2_UMSK (~(((1U << GLB_CGEN_S1A_UART2_LEN) - 1) << GLB_CGEN_S1A_UART2_POS)) +#define GLB_CGEN_S1A_RSVD11 GLB_CGEN_S1A_RSVD11 +#define GLB_CGEN_S1A_RSVD11_POS (27U) +#define GLB_CGEN_S1A_RSVD11_LEN (1U) +#define GLB_CGEN_S1A_RSVD11_MSK (((1U << GLB_CGEN_S1A_RSVD11_LEN) - 1) << GLB_CGEN_S1A_RSVD11_POS) +#define GLB_CGEN_S1A_RSVD11_UMSK (~(((1U << GLB_CGEN_S1A_RSVD11_LEN) - 1) << GLB_CGEN_S1A_RSVD11_POS)) +#define GLB_CGEN_S1A_RSVD12 GLB_CGEN_S1A_RSVD12 +#define GLB_CGEN_S1A_RSVD12_POS (28U) +#define GLB_CGEN_S1A_RSVD12_LEN (1U) +#define GLB_CGEN_S1A_RSVD12_MSK (((1U << GLB_CGEN_S1A_RSVD12_LEN) - 1) << GLB_CGEN_S1A_RSVD12_POS) +#define GLB_CGEN_S1A_RSVD12_UMSK (~(((1U << GLB_CGEN_S1A_RSVD12_LEN) - 1) << GLB_CGEN_S1A_RSVD12_POS)) +#define GLB_CGEN_S1A_RSVD13 GLB_CGEN_S1A_RSVD13 +#define GLB_CGEN_S1A_RSVD13_POS (29U) +#define GLB_CGEN_S1A_RSVD13_LEN (1U) +#define GLB_CGEN_S1A_RSVD13_MSK (((1U << GLB_CGEN_S1A_RSVD13_LEN) - 1) << GLB_CGEN_S1A_RSVD13_POS) +#define GLB_CGEN_S1A_RSVD13_UMSK (~(((1U << GLB_CGEN_S1A_RSVD13_LEN) - 1) << GLB_CGEN_S1A_RSVD13_POS)) +#define GLB_CGEN_S1A_RSVD14 GLB_CGEN_S1A_RSVD14 +#define GLB_CGEN_S1A_RSVD14_POS (30U) +#define GLB_CGEN_S1A_RSVD14_LEN (1U) +#define GLB_CGEN_S1A_RSVD14_MSK (((1U << GLB_CGEN_S1A_RSVD14_LEN) - 1) << GLB_CGEN_S1A_RSVD14_POS) +#define GLB_CGEN_S1A_RSVD14_UMSK (~(((1U << GLB_CGEN_S1A_RSVD14_LEN) - 1) << GLB_CGEN_S1A_RSVD14_POS)) +#define GLB_CGEN_S1A_RSVD15 GLB_CGEN_S1A_RSVD15 +#define GLB_CGEN_S1A_RSVD15_POS (31U) +#define GLB_CGEN_S1A_RSVD15_LEN (1U) +#define GLB_CGEN_S1A_RSVD15_MSK (((1U << GLB_CGEN_S1A_RSVD15_LEN) - 1) << GLB_CGEN_S1A_RSVD15_POS) +#define GLB_CGEN_S1A_RSVD15_UMSK (~(((1U << GLB_CGEN_S1A_RSVD15_LEN) - 1) << GLB_CGEN_S1A_RSVD15_POS)) + +/* 0x588 : cgen_s1_ext + cgen_s3 */ +#define GLB_CGEN_CFG2_OFFSET (0x588) +#define GLB_CGEN_S0 GLB_CGEN_S0 +#define GLB_CGEN_S0_POS (0U) +#define GLB_CGEN_S0_LEN (1U) +#define GLB_CGEN_S0_MSK (((1U << GLB_CGEN_S0_LEN) - 1) << GLB_CGEN_S0_POS) +#define GLB_CGEN_S0_UMSK (~(((1U << GLB_CGEN_S0_LEN) - 1) << GLB_CGEN_S0_POS)) +#define GLB_CGEN_S2_WIFI GLB_CGEN_S2_WIFI +#define GLB_CGEN_S2_WIFI_POS (4U) +#define GLB_CGEN_S2_WIFI_LEN (1U) +#define GLB_CGEN_S2_WIFI_MSK (((1U << GLB_CGEN_S2_WIFI_LEN) - 1) << GLB_CGEN_S2_WIFI_POS) +#define GLB_CGEN_S2_WIFI_UMSK (~(((1U << GLB_CGEN_S2_WIFI_LEN) - 1) << GLB_CGEN_S2_WIFI_POS)) +#define GLB_CGEN_S3_BT_BLE2 GLB_CGEN_S3_BT_BLE2 +#define GLB_CGEN_S3_BT_BLE2_POS (10U) +#define GLB_CGEN_S3_BT_BLE2_LEN (1U) +#define GLB_CGEN_S3_BT_BLE2_MSK (((1U << GLB_CGEN_S3_BT_BLE2_LEN) - 1) << GLB_CGEN_S3_BT_BLE2_POS) +#define GLB_CGEN_S3_BT_BLE2_UMSK (~(((1U << GLB_CGEN_S3_BT_BLE2_LEN) - 1) << GLB_CGEN_S3_BT_BLE2_POS)) +#define GLB_CGEN_S3_M1542 GLB_CGEN_S3_M1542 +#define GLB_CGEN_S3_M1542_POS (11U) +#define GLB_CGEN_S3_M1542_LEN (1U) +#define GLB_CGEN_S3_M1542_MSK (((1U << GLB_CGEN_S3_M1542_LEN) - 1) << GLB_CGEN_S3_M1542_POS) +#define GLB_CGEN_S3_M1542_UMSK (~(((1U << GLB_CGEN_S3_M1542_LEN) - 1) << GLB_CGEN_S3_M1542_POS)) +#define GLB_CGEN_S1_EXT_EMI_MISC GLB_CGEN_S1_EXT_EMI_MISC +#define GLB_CGEN_S1_EXT_EMI_MISC_POS (16U) +#define GLB_CGEN_S1_EXT_EMI_MISC_LEN (1U) +#define GLB_CGEN_S1_EXT_EMI_MISC_MSK (((1U << GLB_CGEN_S1_EXT_EMI_MISC_LEN) - 1) << GLB_CGEN_S1_EXT_EMI_MISC_POS) +#define GLB_CGEN_S1_EXT_EMI_MISC_UMSK (~(((1U << GLB_CGEN_S1_EXT_EMI_MISC_LEN) - 1) << GLB_CGEN_S1_EXT_EMI_MISC_POS)) +#define GLB_CGEN_S1_EXT_PSRAM0_CTRL GLB_CGEN_S1_EXT_PSRAM0_CTRL +#define GLB_CGEN_S1_EXT_PSRAM0_CTRL_POS (17U) +#define GLB_CGEN_S1_EXT_PSRAM0_CTRL_LEN (1U) +#define GLB_CGEN_S1_EXT_PSRAM0_CTRL_MSK (((1U << GLB_CGEN_S1_EXT_PSRAM0_CTRL_LEN) - 1) << GLB_CGEN_S1_EXT_PSRAM0_CTRL_POS) +#define GLB_CGEN_S1_EXT_PSRAM0_CTRL_UMSK (~(((1U << GLB_CGEN_S1_EXT_PSRAM0_CTRL_LEN) - 1) << GLB_CGEN_S1_EXT_PSRAM0_CTRL_POS)) +#define GLB_CGEN_S1_EXT_PSRAM_CTRL GLB_CGEN_S1_EXT_PSRAM_CTRL +#define GLB_CGEN_S1_EXT_PSRAM_CTRL_POS (18U) +#define GLB_CGEN_S1_EXT_PSRAM_CTRL_LEN (1U) +#define GLB_CGEN_S1_EXT_PSRAM_CTRL_MSK (((1U << GLB_CGEN_S1_EXT_PSRAM_CTRL_LEN) - 1) << GLB_CGEN_S1_EXT_PSRAM_CTRL_POS) +#define GLB_CGEN_S1_EXT_PSRAM_CTRL_UMSK (~(((1U << GLB_CGEN_S1_EXT_PSRAM_CTRL_LEN) - 1) << GLB_CGEN_S1_EXT_PSRAM_CTRL_POS)) +#define GLB_CGEN_S1_EXT_USB GLB_CGEN_S1_EXT_USB +#define GLB_CGEN_S1_EXT_USB_POS (19U) +#define GLB_CGEN_S1_EXT_USB_LEN (1U) +#define GLB_CGEN_S1_EXT_USB_MSK (((1U << GLB_CGEN_S1_EXT_USB_LEN) - 1) << GLB_CGEN_S1_EXT_USB_POS) +#define GLB_CGEN_S1_EXT_USB_UMSK (~(((1U << GLB_CGEN_S1_EXT_USB_LEN) - 1) << GLB_CGEN_S1_EXT_USB_POS)) +#define GLB_CGEN_S1_EXT_MIX2 GLB_CGEN_S1_EXT_MIX2 +#define GLB_CGEN_S1_EXT_MIX2_POS (20U) +#define GLB_CGEN_S1_EXT_MIX2_LEN (1U) +#define GLB_CGEN_S1_EXT_MIX2_MSK (((1U << GLB_CGEN_S1_EXT_MIX2_LEN) - 1) << GLB_CGEN_S1_EXT_MIX2_POS) +#define GLB_CGEN_S1_EXT_MIX2_UMSK (~(((1U << GLB_CGEN_S1_EXT_MIX2_LEN) - 1) << GLB_CGEN_S1_EXT_MIX2_POS)) +#define GLB_CGEN_S1_EXT_AUDIO GLB_CGEN_S1_EXT_AUDIO +#define GLB_CGEN_S1_EXT_AUDIO_POS (21U) +#define GLB_CGEN_S1_EXT_AUDIO_LEN (1U) +#define GLB_CGEN_S1_EXT_AUDIO_MSK (((1U << GLB_CGEN_S1_EXT_AUDIO_LEN) - 1) << GLB_CGEN_S1_EXT_AUDIO_POS) +#define GLB_CGEN_S1_EXT_AUDIO_UMSK (~(((1U << GLB_CGEN_S1_EXT_AUDIO_LEN) - 1) << GLB_CGEN_S1_EXT_AUDIO_POS)) +#define GLB_CGEN_S1_EXT_SDH GLB_CGEN_S1_EXT_SDH +#define GLB_CGEN_S1_EXT_SDH_POS (22U) +#define GLB_CGEN_S1_EXT_SDH_LEN (1U) +#define GLB_CGEN_S1_EXT_SDH_MSK (((1U << GLB_CGEN_S1_EXT_SDH_LEN) - 1) << GLB_CGEN_S1_EXT_SDH_POS) +#define GLB_CGEN_S1_EXT_SDH_UMSK (~(((1U << GLB_CGEN_S1_EXT_SDH_LEN) - 1) << GLB_CGEN_S1_EXT_SDH_POS)) +#define GLB_CGEN_S1_EXT_EMAC GLB_CGEN_S1_EXT_EMAC +#define GLB_CGEN_S1_EXT_EMAC_POS (23U) +#define GLB_CGEN_S1_EXT_EMAC_LEN (1U) +#define GLB_CGEN_S1_EXT_EMAC_MSK (((1U << GLB_CGEN_S1_EXT_EMAC_LEN) - 1) << GLB_CGEN_S1_EXT_EMAC_POS) +#define GLB_CGEN_S1_EXT_EMAC_UMSK (~(((1U << GLB_CGEN_S1_EXT_EMAC_LEN) - 1) << GLB_CGEN_S1_EXT_EMAC_POS)) +#define GLB_CGEN_S1_EXT_DMA2 GLB_CGEN_S1_EXT_DMA2 +#define GLB_CGEN_S1_EXT_DMA2_POS (24U) +#define GLB_CGEN_S1_EXT_DMA2_LEN (1U) +#define GLB_CGEN_S1_EXT_DMA2_MSK (((1U << GLB_CGEN_S1_EXT_DMA2_LEN) - 1) << GLB_CGEN_S1_EXT_DMA2_POS) +#define GLB_CGEN_S1_EXT_DMA2_UMSK (~(((1U << GLB_CGEN_S1_EXT_DMA2_LEN) - 1) << GLB_CGEN_S1_EXT_DMA2_POS)) +#define GLB_CGEN_S1_EXT_RSVD9 GLB_CGEN_S1_EXT_RSVD9 +#define GLB_CGEN_S1_EXT_RSVD9_POS (25U) +#define GLB_CGEN_S1_EXT_RSVD9_LEN (1U) +#define GLB_CGEN_S1_EXT_RSVD9_MSK (((1U << GLB_CGEN_S1_EXT_RSVD9_LEN) - 1) << GLB_CGEN_S1_EXT_RSVD9_POS) +#define GLB_CGEN_S1_EXT_RSVD9_UMSK (~(((1U << GLB_CGEN_S1_EXT_RSVD9_LEN) - 1) << GLB_CGEN_S1_EXT_RSVD9_POS)) +#define GLB_CGEN_S1_EXT_RSVD10 GLB_CGEN_S1_EXT_RSVD10 +#define GLB_CGEN_S1_EXT_RSVD10_POS (26U) +#define GLB_CGEN_S1_EXT_RSVD10_LEN (1U) +#define GLB_CGEN_S1_EXT_RSVD10_MSK (((1U << GLB_CGEN_S1_EXT_RSVD10_LEN) - 1) << GLB_CGEN_S1_EXT_RSVD10_POS) +#define GLB_CGEN_S1_EXT_RSVD10_UMSK (~(((1U << GLB_CGEN_S1_EXT_RSVD10_LEN) - 1) << GLB_CGEN_S1_EXT_RSVD10_POS)) +#define GLB_CGEN_S1_EXT_RSVD11 GLB_CGEN_S1_EXT_RSVD11 +#define GLB_CGEN_S1_EXT_RSVD11_POS (27U) +#define GLB_CGEN_S1_EXT_RSVD11_LEN (1U) +#define GLB_CGEN_S1_EXT_RSVD11_MSK (((1U << GLB_CGEN_S1_EXT_RSVD11_LEN) - 1) << GLB_CGEN_S1_EXT_RSVD11_POS) +#define GLB_CGEN_S1_EXT_RSVD11_UMSK (~(((1U << GLB_CGEN_S1_EXT_RSVD11_LEN) - 1) << GLB_CGEN_S1_EXT_RSVD11_POS)) + +/* 0x58C : cgen_cfg3 */ +#define GLB_CGEN_CFG3_OFFSET (0x58C) +#define GLB_CGEN_MM_WIFIPLL_160M GLB_CGEN_MM_WIFIPLL_160M +#define GLB_CGEN_MM_WIFIPLL_160M_POS (0U) +#define GLB_CGEN_MM_WIFIPLL_160M_LEN (1U) +#define GLB_CGEN_MM_WIFIPLL_160M_MSK (((1U << GLB_CGEN_MM_WIFIPLL_160M_LEN) - 1) << GLB_CGEN_MM_WIFIPLL_160M_POS) +#define GLB_CGEN_MM_WIFIPLL_160M_UMSK (~(((1U << GLB_CGEN_MM_WIFIPLL_160M_LEN) - 1) << GLB_CGEN_MM_WIFIPLL_160M_POS)) +#define GLB_CGEN_MM_WIFIPLL_240M GLB_CGEN_MM_WIFIPLL_240M +#define GLB_CGEN_MM_WIFIPLL_240M_POS (1U) +#define GLB_CGEN_MM_WIFIPLL_240M_LEN (1U) +#define GLB_CGEN_MM_WIFIPLL_240M_MSK (((1U << GLB_CGEN_MM_WIFIPLL_240M_LEN) - 1) << GLB_CGEN_MM_WIFIPLL_240M_POS) +#define GLB_CGEN_MM_WIFIPLL_240M_UMSK (~(((1U << GLB_CGEN_MM_WIFIPLL_240M_LEN) - 1) << GLB_CGEN_MM_WIFIPLL_240M_POS)) +#define GLB_CGEN_MM_WIFIPLL_320M GLB_CGEN_MM_WIFIPLL_320M +#define GLB_CGEN_MM_WIFIPLL_320M_POS (2U) +#define GLB_CGEN_MM_WIFIPLL_320M_LEN (1U) +#define GLB_CGEN_MM_WIFIPLL_320M_MSK (((1U << GLB_CGEN_MM_WIFIPLL_320M_LEN) - 1) << GLB_CGEN_MM_WIFIPLL_320M_POS) +#define GLB_CGEN_MM_WIFIPLL_320M_UMSK (~(((1U << GLB_CGEN_MM_WIFIPLL_320M_LEN) - 1) << GLB_CGEN_MM_WIFIPLL_320M_POS)) +#define GLB_CGEN_MM_AUPLL_DIV1 GLB_CGEN_MM_AUPLL_DIV1 +#define GLB_CGEN_MM_AUPLL_DIV1_POS (3U) +#define GLB_CGEN_MM_AUPLL_DIV1_LEN (1U) +#define GLB_CGEN_MM_AUPLL_DIV1_MSK (((1U << GLB_CGEN_MM_AUPLL_DIV1_LEN) - 1) << GLB_CGEN_MM_AUPLL_DIV1_POS) +#define GLB_CGEN_MM_AUPLL_DIV1_UMSK (~(((1U << GLB_CGEN_MM_AUPLL_DIV1_LEN) - 1) << GLB_CGEN_MM_AUPLL_DIV1_POS)) +#define GLB_CGEN_MM_AUPLL_DIV2 GLB_CGEN_MM_AUPLL_DIV2 +#define GLB_CGEN_MM_AUPLL_DIV2_POS (4U) +#define GLB_CGEN_MM_AUPLL_DIV2_LEN (1U) +#define GLB_CGEN_MM_AUPLL_DIV2_MSK (((1U << GLB_CGEN_MM_AUPLL_DIV2_LEN) - 1) << GLB_CGEN_MM_AUPLL_DIV2_POS) +#define GLB_CGEN_MM_AUPLL_DIV2_UMSK (~(((1U << GLB_CGEN_MM_AUPLL_DIV2_LEN) - 1) << GLB_CGEN_MM_AUPLL_DIV2_POS)) +#define GLB_CGEN_EMI_CPUPLL_400M GLB_CGEN_EMI_CPUPLL_400M +#define GLB_CGEN_EMI_CPUPLL_400M_POS (5U) +#define GLB_CGEN_EMI_CPUPLL_400M_LEN (1U) +#define GLB_CGEN_EMI_CPUPLL_400M_MSK (((1U << GLB_CGEN_EMI_CPUPLL_400M_LEN) - 1) << GLB_CGEN_EMI_CPUPLL_400M_POS) +#define GLB_CGEN_EMI_CPUPLL_400M_UMSK (~(((1U << GLB_CGEN_EMI_CPUPLL_400M_LEN) - 1) << GLB_CGEN_EMI_CPUPLL_400M_POS)) +#define GLB_CGEN_EMI_CPUPLL_200M GLB_CGEN_EMI_CPUPLL_200M +#define GLB_CGEN_EMI_CPUPLL_200M_POS (6U) +#define GLB_CGEN_EMI_CPUPLL_200M_LEN (1U) +#define GLB_CGEN_EMI_CPUPLL_200M_MSK (((1U << GLB_CGEN_EMI_CPUPLL_200M_LEN) - 1) << GLB_CGEN_EMI_CPUPLL_200M_POS) +#define GLB_CGEN_EMI_CPUPLL_200M_UMSK (~(((1U << GLB_CGEN_EMI_CPUPLL_200M_LEN) - 1) << GLB_CGEN_EMI_CPUPLL_200M_POS)) +#define GLB_CGEN_EMI_WIFIPLL_320M GLB_CGEN_EMI_WIFIPLL_320M +#define GLB_CGEN_EMI_WIFIPLL_320M_POS (7U) +#define GLB_CGEN_EMI_WIFIPLL_320M_LEN (1U) +#define GLB_CGEN_EMI_WIFIPLL_320M_MSK (((1U << GLB_CGEN_EMI_WIFIPLL_320M_LEN) - 1) << GLB_CGEN_EMI_WIFIPLL_320M_POS) +#define GLB_CGEN_EMI_WIFIPLL_320M_UMSK (~(((1U << GLB_CGEN_EMI_WIFIPLL_320M_LEN) - 1) << GLB_CGEN_EMI_WIFIPLL_320M_POS)) +#define GLB_CGEN_EMI_AUPLL_DIV1 GLB_CGEN_EMI_AUPLL_DIV1 +#define GLB_CGEN_EMI_AUPLL_DIV1_POS (8U) +#define GLB_CGEN_EMI_AUPLL_DIV1_LEN (1U) +#define GLB_CGEN_EMI_AUPLL_DIV1_MSK (((1U << GLB_CGEN_EMI_AUPLL_DIV1_LEN) - 1) << GLB_CGEN_EMI_AUPLL_DIV1_POS) +#define GLB_CGEN_EMI_AUPLL_DIV1_UMSK (~(((1U << GLB_CGEN_EMI_AUPLL_DIV1_LEN) - 1) << GLB_CGEN_EMI_AUPLL_DIV1_POS)) +#define GLB_CGEN_TOP_CPUPLL_80M GLB_CGEN_TOP_CPUPLL_80M +#define GLB_CGEN_TOP_CPUPLL_80M_POS (9U) +#define GLB_CGEN_TOP_CPUPLL_80M_LEN (1U) +#define GLB_CGEN_TOP_CPUPLL_80M_MSK (((1U << GLB_CGEN_TOP_CPUPLL_80M_LEN) - 1) << GLB_CGEN_TOP_CPUPLL_80M_POS) +#define GLB_CGEN_TOP_CPUPLL_80M_UMSK (~(((1U << GLB_CGEN_TOP_CPUPLL_80M_LEN) - 1) << GLB_CGEN_TOP_CPUPLL_80M_POS)) +#define GLB_CGEN_TOP_CPUPLL_100M GLB_CGEN_TOP_CPUPLL_100M +#define GLB_CGEN_TOP_CPUPLL_100M_POS (10U) +#define GLB_CGEN_TOP_CPUPLL_100M_LEN (1U) +#define GLB_CGEN_TOP_CPUPLL_100M_MSK (((1U << GLB_CGEN_TOP_CPUPLL_100M_LEN) - 1) << GLB_CGEN_TOP_CPUPLL_100M_POS) +#define GLB_CGEN_TOP_CPUPLL_100M_UMSK (~(((1U << GLB_CGEN_TOP_CPUPLL_100M_LEN) - 1) << GLB_CGEN_TOP_CPUPLL_100M_POS)) +#define GLB_CGEN_TOP_CPUPLL_160M GLB_CGEN_TOP_CPUPLL_160M +#define GLB_CGEN_TOP_CPUPLL_160M_POS (11U) +#define GLB_CGEN_TOP_CPUPLL_160M_LEN (1U) +#define GLB_CGEN_TOP_CPUPLL_160M_MSK (((1U << GLB_CGEN_TOP_CPUPLL_160M_LEN) - 1) << GLB_CGEN_TOP_CPUPLL_160M_POS) +#define GLB_CGEN_TOP_CPUPLL_160M_UMSK (~(((1U << GLB_CGEN_TOP_CPUPLL_160M_LEN) - 1) << GLB_CGEN_TOP_CPUPLL_160M_POS)) +#define GLB_CGEN_TOP_CPUPLL_400M GLB_CGEN_TOP_CPUPLL_400M +#define GLB_CGEN_TOP_CPUPLL_400M_POS (12U) +#define GLB_CGEN_TOP_CPUPLL_400M_LEN (1U) +#define GLB_CGEN_TOP_CPUPLL_400M_MSK (((1U << GLB_CGEN_TOP_CPUPLL_400M_LEN) - 1) << GLB_CGEN_TOP_CPUPLL_400M_POS) +#define GLB_CGEN_TOP_CPUPLL_400M_UMSK (~(((1U << GLB_CGEN_TOP_CPUPLL_400M_LEN) - 1) << GLB_CGEN_TOP_CPUPLL_400M_POS)) +#define GLB_CGEN_TOP_WIFIPLL_240M GLB_CGEN_TOP_WIFIPLL_240M +#define GLB_CGEN_TOP_WIFIPLL_240M_POS (13U) +#define GLB_CGEN_TOP_WIFIPLL_240M_LEN (1U) +#define GLB_CGEN_TOP_WIFIPLL_240M_MSK (((1U << GLB_CGEN_TOP_WIFIPLL_240M_LEN) - 1) << GLB_CGEN_TOP_WIFIPLL_240M_POS) +#define GLB_CGEN_TOP_WIFIPLL_240M_UMSK (~(((1U << GLB_CGEN_TOP_WIFIPLL_240M_LEN) - 1) << GLB_CGEN_TOP_WIFIPLL_240M_POS)) +#define GLB_CGEN_TOP_WIFIPLL_320M GLB_CGEN_TOP_WIFIPLL_320M +#define GLB_CGEN_TOP_WIFIPLL_320M_POS (14U) +#define GLB_CGEN_TOP_WIFIPLL_320M_LEN (1U) +#define GLB_CGEN_TOP_WIFIPLL_320M_MSK (((1U << GLB_CGEN_TOP_WIFIPLL_320M_LEN) - 1) << GLB_CGEN_TOP_WIFIPLL_320M_POS) +#define GLB_CGEN_TOP_WIFIPLL_320M_UMSK (~(((1U << GLB_CGEN_TOP_WIFIPLL_320M_LEN) - 1) << GLB_CGEN_TOP_WIFIPLL_320M_POS)) +#define GLB_CGEN_TOP_AUPLL_DIV2 GLB_CGEN_TOP_AUPLL_DIV2 +#define GLB_CGEN_TOP_AUPLL_DIV2_POS (15U) +#define GLB_CGEN_TOP_AUPLL_DIV2_LEN (1U) +#define GLB_CGEN_TOP_AUPLL_DIV2_MSK (((1U << GLB_CGEN_TOP_AUPLL_DIV2_LEN) - 1) << GLB_CGEN_TOP_AUPLL_DIV2_POS) +#define GLB_CGEN_TOP_AUPLL_DIV2_UMSK (~(((1U << GLB_CGEN_TOP_AUPLL_DIV2_LEN) - 1) << GLB_CGEN_TOP_AUPLL_DIV2_POS)) +#define GLB_CGEN_TOP_AUPLL_DIV1 GLB_CGEN_TOP_AUPLL_DIV1 +#define GLB_CGEN_TOP_AUPLL_DIV1_POS (16U) +#define GLB_CGEN_TOP_AUPLL_DIV1_LEN (1U) +#define GLB_CGEN_TOP_AUPLL_DIV1_MSK (((1U << GLB_CGEN_TOP_AUPLL_DIV1_LEN) - 1) << GLB_CGEN_TOP_AUPLL_DIV1_POS) +#define GLB_CGEN_TOP_AUPLL_DIV1_UMSK (~(((1U << GLB_CGEN_TOP_AUPLL_DIV1_LEN) - 1) << GLB_CGEN_TOP_AUPLL_DIV1_POS)) + +/* 0x5C0 : hw_rsv0 */ +#define GLB_HW_RSV0_OFFSET (0x5C0) + +/* 0x5C4 : hw_rsv1 */ +#define GLB_HW_RSV1_OFFSET (0x5C4) + +/* 0x5C8 : hw_rsv2 */ +#define GLB_HW_RSV2_OFFSET (0x5C8) + +/* 0x5CC : hw_rsv3 */ +#define GLB_HW_RSV3_OFFSET (0x5CC) + +/* 0x600 : reg_sram_ret */ +#define GLB_SRAM_CFG0_OFFSET (0x600) +#define GLB_CR_MCU_CACHE_RET GLB_CR_MCU_CACHE_RET +#define GLB_CR_MCU_CACHE_RET_POS (0U) +#define GLB_CR_MCU_CACHE_RET_LEN (2U) +#define GLB_CR_MCU_CACHE_RET_MSK (((1U << GLB_CR_MCU_CACHE_RET_LEN) - 1) << GLB_CR_MCU_CACHE_RET_POS) +#define GLB_CR_MCU_CACHE_RET_UMSK (~(((1U << GLB_CR_MCU_CACHE_RET_LEN) - 1) << GLB_CR_MCU_CACHE_RET_POS)) +#define GLB_CR_MCU_HSRAM_RET GLB_CR_MCU_HSRAM_RET +#define GLB_CR_MCU_HSRAM_RET_POS (2U) +#define GLB_CR_MCU_HSRAM_RET_LEN (4U) +#define GLB_CR_MCU_HSRAM_RET_MSK (((1U << GLB_CR_MCU_HSRAM_RET_LEN) - 1) << GLB_CR_MCU_HSRAM_RET_POS) +#define GLB_CR_MCU_HSRAM_RET_UMSK (~(((1U << GLB_CR_MCU_HSRAM_RET_LEN) - 1) << GLB_CR_MCU_HSRAM_RET_POS)) +#define GLB_CR_WB_RAM_RET GLB_CR_WB_RAM_RET +#define GLB_CR_WB_RAM_RET_POS (8U) +#define GLB_CR_WB_RAM_RET_LEN (1U) +#define GLB_CR_WB_RAM_RET_MSK (((1U << GLB_CR_WB_RAM_RET_LEN) - 1) << GLB_CR_WB_RAM_RET_POS) +#define GLB_CR_WB_RAM_RET_UMSK (~(((1U << GLB_CR_WB_RAM_RET_LEN) - 1) << GLB_CR_WB_RAM_RET_POS)) +#define GLB_CR_MISC_RAM_RET GLB_CR_MISC_RAM_RET +#define GLB_CR_MISC_RAM_RET_POS (9U) +#define GLB_CR_MISC_RAM_RET_LEN (2U) +#define GLB_CR_MISC_RAM_RET_MSK (((1U << GLB_CR_MISC_RAM_RET_LEN) - 1) << GLB_CR_MISC_RAM_RET_POS) +#define GLB_CR_MISC_RAM_RET_UMSK (~(((1U << GLB_CR_MISC_RAM_RET_LEN) - 1) << GLB_CR_MISC_RAM_RET_POS)) + +/* 0x604 : reg_sram_slp */ +#define GLB_SRAM_CFG1_OFFSET (0x604) +#define GLB_CR_MCU_CACHE_SLP GLB_CR_MCU_CACHE_SLP +#define GLB_CR_MCU_CACHE_SLP_POS (0U) +#define GLB_CR_MCU_CACHE_SLP_LEN (2U) +#define GLB_CR_MCU_CACHE_SLP_MSK (((1U << GLB_CR_MCU_CACHE_SLP_LEN) - 1) << GLB_CR_MCU_CACHE_SLP_POS) +#define GLB_CR_MCU_CACHE_SLP_UMSK (~(((1U << GLB_CR_MCU_CACHE_SLP_LEN) - 1) << GLB_CR_MCU_CACHE_SLP_POS)) +#define GLB_CR_MCU_HSRAM_SLP GLB_CR_MCU_HSRAM_SLP +#define GLB_CR_MCU_HSRAM_SLP_POS (2U) +#define GLB_CR_MCU_HSRAM_SLP_LEN (4U) +#define GLB_CR_MCU_HSRAM_SLP_MSK (((1U << GLB_CR_MCU_HSRAM_SLP_LEN) - 1) << GLB_CR_MCU_HSRAM_SLP_POS) +#define GLB_CR_MCU_HSRAM_SLP_UMSK (~(((1U << GLB_CR_MCU_HSRAM_SLP_LEN) - 1) << GLB_CR_MCU_HSRAM_SLP_POS)) +#define GLB_CR_MCU_ROM_SLP GLB_CR_MCU_ROM_SLP +#define GLB_CR_MCU_ROM_SLP_POS (6U) +#define GLB_CR_MCU_ROM_SLP_LEN (2U) +#define GLB_CR_MCU_ROM_SLP_MSK (((1U << GLB_CR_MCU_ROM_SLP_LEN) - 1) << GLB_CR_MCU_ROM_SLP_POS) +#define GLB_CR_MCU_ROM_SLP_UMSK (~(((1U << GLB_CR_MCU_ROM_SLP_LEN) - 1) << GLB_CR_MCU_ROM_SLP_POS)) +#define GLB_CR_WB_RAM_SLP GLB_CR_WB_RAM_SLP +#define GLB_CR_WB_RAM_SLP_POS (8U) +#define GLB_CR_WB_RAM_SLP_LEN (1U) +#define GLB_CR_WB_RAM_SLP_MSK (((1U << GLB_CR_WB_RAM_SLP_LEN) - 1) << GLB_CR_WB_RAM_SLP_POS) +#define GLB_CR_WB_RAM_SLP_UMSK (~(((1U << GLB_CR_WB_RAM_SLP_LEN) - 1) << GLB_CR_WB_RAM_SLP_POS)) +#define GLB_CR_MISC_RAM_SLP GLB_CR_MISC_RAM_SLP +#define GLB_CR_MISC_RAM_SLP_POS (9U) +#define GLB_CR_MISC_RAM_SLP_LEN (2U) +#define GLB_CR_MISC_RAM_SLP_MSK (((1U << GLB_CR_MISC_RAM_SLP_LEN) - 1) << GLB_CR_MISC_RAM_SLP_POS) +#define GLB_CR_MISC_RAM_SLP_UMSK (~(((1U << GLB_CR_MISC_RAM_SLP_LEN) - 1) << GLB_CR_MISC_RAM_SLP_POS)) + +/* 0x608 : reg_sram_parm */ +#define GLB_SRAM_CFG2_OFFSET (0x608) +#define GLB_CR_MCU_CACHE_DVSE GLB_CR_MCU_CACHE_DVSE +#define GLB_CR_MCU_CACHE_DVSE_POS (0U) +#define GLB_CR_MCU_CACHE_DVSE_LEN (1U) +#define GLB_CR_MCU_CACHE_DVSE_MSK (((1U << GLB_CR_MCU_CACHE_DVSE_LEN) - 1) << GLB_CR_MCU_CACHE_DVSE_POS) +#define GLB_CR_MCU_CACHE_DVSE_UMSK (~(((1U << GLB_CR_MCU_CACHE_DVSE_LEN) - 1) << GLB_CR_MCU_CACHE_DVSE_POS)) +#define GLB_CR_MCU_HSRAM_DVSE GLB_CR_MCU_HSRAM_DVSE +#define GLB_CR_MCU_HSRAM_DVSE_POS (1U) +#define GLB_CR_MCU_HSRAM_DVSE_LEN (1U) +#define GLB_CR_MCU_HSRAM_DVSE_MSK (((1U << GLB_CR_MCU_HSRAM_DVSE_LEN) - 1) << GLB_CR_MCU_HSRAM_DVSE_POS) +#define GLB_CR_MCU_HSRAM_DVSE_UMSK (~(((1U << GLB_CR_MCU_HSRAM_DVSE_LEN) - 1) << GLB_CR_MCU_HSRAM_DVSE_POS)) +#define GLB_CR_MCU_ROM_DVSE GLB_CR_MCU_ROM_DVSE +#define GLB_CR_MCU_ROM_DVSE_POS (2U) +#define GLB_CR_MCU_ROM_DVSE_LEN (1U) +#define GLB_CR_MCU_ROM_DVSE_MSK (((1U << GLB_CR_MCU_ROM_DVSE_LEN) - 1) << GLB_CR_MCU_ROM_DVSE_POS) +#define GLB_CR_MCU_ROM_DVSE_UMSK (~(((1U << GLB_CR_MCU_ROM_DVSE_LEN) - 1) << GLB_CR_MCU_ROM_DVSE_POS)) +#define GLB_CR_WB_RAM_DVSE GLB_CR_WB_RAM_DVSE +#define GLB_CR_WB_RAM_DVSE_POS (3U) +#define GLB_CR_WB_RAM_DVSE_LEN (1U) +#define GLB_CR_WB_RAM_DVSE_MSK (((1U << GLB_CR_WB_RAM_DVSE_LEN) - 1) << GLB_CR_WB_RAM_DVSE_POS) +#define GLB_CR_WB_RAM_DVSE_UMSK (~(((1U << GLB_CR_WB_RAM_DVSE_LEN) - 1) << GLB_CR_WB_RAM_DVSE_POS)) +#define GLB_CR_MISC_RAM_DVSE GLB_CR_MISC_RAM_DVSE +#define GLB_CR_MISC_RAM_DVSE_POS (4U) +#define GLB_CR_MISC_RAM_DVSE_LEN (1U) +#define GLB_CR_MISC_RAM_DVSE_MSK (((1U << GLB_CR_MISC_RAM_DVSE_LEN) - 1) << GLB_CR_MISC_RAM_DVSE_POS) +#define GLB_CR_MISC_RAM_DVSE_UMSK (~(((1U << GLB_CR_MISC_RAM_DVSE_LEN) - 1) << GLB_CR_MISC_RAM_DVSE_POS)) +#define GLB_CR_OCRAM_DVSE GLB_CR_OCRAM_DVSE +#define GLB_CR_OCRAM_DVSE_POS (5U) +#define GLB_CR_OCRAM_DVSE_LEN (1U) +#define GLB_CR_OCRAM_DVSE_MSK (((1U << GLB_CR_OCRAM_DVSE_LEN) - 1) << GLB_CR_OCRAM_DVSE_POS) +#define GLB_CR_OCRAM_DVSE_UMSK (~(((1U << GLB_CR_OCRAM_DVSE_LEN) - 1) << GLB_CR_OCRAM_DVSE_POS)) +#define GLB_CR_WRAM_DVSE GLB_CR_WRAM_DVSE +#define GLB_CR_WRAM_DVSE_POS (6U) +#define GLB_CR_WRAM_DVSE_LEN (1U) +#define GLB_CR_WRAM_DVSE_MSK (((1U << GLB_CR_WRAM_DVSE_LEN) - 1) << GLB_CR_WRAM_DVSE_POS) +#define GLB_CR_WRAM_DVSE_UMSK (~(((1U << GLB_CR_WRAM_DVSE_LEN) - 1) << GLB_CR_WRAM_DVSE_POS)) +#define GLB_CR_MCU_CACHE_NAP GLB_CR_MCU_CACHE_NAP +#define GLB_CR_MCU_CACHE_NAP_POS (8U) +#define GLB_CR_MCU_CACHE_NAP_LEN (1U) +#define GLB_CR_MCU_CACHE_NAP_MSK (((1U << GLB_CR_MCU_CACHE_NAP_LEN) - 1) << GLB_CR_MCU_CACHE_NAP_POS) +#define GLB_CR_MCU_CACHE_NAP_UMSK (~(((1U << GLB_CR_MCU_CACHE_NAP_LEN) - 1) << GLB_CR_MCU_CACHE_NAP_POS)) +#define GLB_CR_MCU_HSRAM_NAP GLB_CR_MCU_HSRAM_NAP +#define GLB_CR_MCU_HSRAM_NAP_POS (9U) +#define GLB_CR_MCU_HSRAM_NAP_LEN (1U) +#define GLB_CR_MCU_HSRAM_NAP_MSK (((1U << GLB_CR_MCU_HSRAM_NAP_LEN) - 1) << GLB_CR_MCU_HSRAM_NAP_POS) +#define GLB_CR_MCU_HSRAM_NAP_UMSK (~(((1U << GLB_CR_MCU_HSRAM_NAP_LEN) - 1) << GLB_CR_MCU_HSRAM_NAP_POS)) +#define GLB_CR_WB_RAM_NAP GLB_CR_WB_RAM_NAP +#define GLB_CR_WB_RAM_NAP_POS (11U) +#define GLB_CR_WB_RAM_NAP_LEN (1U) +#define GLB_CR_WB_RAM_NAP_MSK (((1U << GLB_CR_WB_RAM_NAP_LEN) - 1) << GLB_CR_WB_RAM_NAP_POS) +#define GLB_CR_WB_RAM_NAP_UMSK (~(((1U << GLB_CR_WB_RAM_NAP_LEN) - 1) << GLB_CR_WB_RAM_NAP_POS)) +#define GLB_CR_MISC_RAM_NAP GLB_CR_MISC_RAM_NAP +#define GLB_CR_MISC_RAM_NAP_POS (12U) +#define GLB_CR_MISC_RAM_NAP_LEN (1U) +#define GLB_CR_MISC_RAM_NAP_MSK (((1U << GLB_CR_MISC_RAM_NAP_LEN) - 1) << GLB_CR_MISC_RAM_NAP_POS) +#define GLB_CR_MISC_RAM_NAP_UMSK (~(((1U << GLB_CR_MISC_RAM_NAP_LEN) - 1) << GLB_CR_MISC_RAM_NAP_POS)) +#define GLB_CR_OCRAM_NAP GLB_CR_OCRAM_NAP +#define GLB_CR_OCRAM_NAP_POS (13U) +#define GLB_CR_OCRAM_NAP_LEN (1U) +#define GLB_CR_OCRAM_NAP_MSK (((1U << GLB_CR_OCRAM_NAP_LEN) - 1) << GLB_CR_OCRAM_NAP_POS) +#define GLB_CR_OCRAM_NAP_UMSK (~(((1U << GLB_CR_OCRAM_NAP_LEN) - 1) << GLB_CR_OCRAM_NAP_POS)) +#define GLB_CR_WRAM_NAP GLB_CR_WRAM_NAP +#define GLB_CR_WRAM_NAP_POS (14U) +#define GLB_CR_WRAM_NAP_LEN (1U) +#define GLB_CR_WRAM_NAP_MSK (((1U << GLB_CR_WRAM_NAP_LEN) - 1) << GLB_CR_WRAM_NAP_POS) +#define GLB_CR_WRAM_NAP_UMSK (~(((1U << GLB_CR_WRAM_NAP_LEN) - 1) << GLB_CR_WRAM_NAP_POS)) + +/* 0x60C : sram_cfg3 */ +#define GLB_SRAM_CFG3_OFFSET (0x60C) +#define GLB_EM_SEL GLB_EM_SEL +#define GLB_EM_SEL_POS (0U) +#define GLB_EM_SEL_LEN (8U) +#define GLB_EM_SEL_MSK (((1U << GLB_EM_SEL_LEN) - 1) << GLB_EM_SEL_POS) +#define GLB_EM_SEL_UMSK (~(((1U << GLB_EM_SEL_LEN) - 1) << GLB_EM_SEL_POS)) +#define GLB_REG_VRAM_SEL GLB_REG_VRAM_SEL +#define GLB_REG_VRAM_SEL_POS (28U) +#define GLB_REG_VRAM_SEL_LEN (2U) +#define GLB_REG_VRAM_SEL_MSK (((1U << GLB_REG_VRAM_SEL_LEN) - 1) << GLB_REG_VRAM_SEL_POS) +#define GLB_REG_VRAM_SEL_UMSK (~(((1U << GLB_REG_VRAM_SEL_LEN) - 1) << GLB_REG_VRAM_SEL_POS)) + +/* 0x610 : reg_sram_parm2 */ +#define GLB_SRAM_CFG4_OFFSET (0x610) +#define GLB_CR_MCU_CACHE_DVS GLB_CR_MCU_CACHE_DVS +#define GLB_CR_MCU_CACHE_DVS_POS (0U) +#define GLB_CR_MCU_CACHE_DVS_LEN (4U) +#define GLB_CR_MCU_CACHE_DVS_MSK (((1U << GLB_CR_MCU_CACHE_DVS_LEN) - 1) << GLB_CR_MCU_CACHE_DVS_POS) +#define GLB_CR_MCU_CACHE_DVS_UMSK (~(((1U << GLB_CR_MCU_CACHE_DVS_LEN) - 1) << GLB_CR_MCU_CACHE_DVS_POS)) +#define GLB_CR_MCU_HSRAM_DVS GLB_CR_MCU_HSRAM_DVS +#define GLB_CR_MCU_HSRAM_DVS_POS (4U) +#define GLB_CR_MCU_HSRAM_DVS_LEN (4U) +#define GLB_CR_MCU_HSRAM_DVS_MSK (((1U << GLB_CR_MCU_HSRAM_DVS_LEN) - 1) << GLB_CR_MCU_HSRAM_DVS_POS) +#define GLB_CR_MCU_HSRAM_DVS_UMSK (~(((1U << GLB_CR_MCU_HSRAM_DVS_LEN) - 1) << GLB_CR_MCU_HSRAM_DVS_POS)) +#define GLB_CR_MCU_ROM_DVS GLB_CR_MCU_ROM_DVS +#define GLB_CR_MCU_ROM_DVS_POS (8U) +#define GLB_CR_MCU_ROM_DVS_LEN (4U) +#define GLB_CR_MCU_ROM_DVS_MSK (((1U << GLB_CR_MCU_ROM_DVS_LEN) - 1) << GLB_CR_MCU_ROM_DVS_POS) +#define GLB_CR_MCU_ROM_DVS_UMSK (~(((1U << GLB_CR_MCU_ROM_DVS_LEN) - 1) << GLB_CR_MCU_ROM_DVS_POS)) +#define GLB_CR_WB_RAM_DVS GLB_CR_WB_RAM_DVS +#define GLB_CR_WB_RAM_DVS_POS (12U) +#define GLB_CR_WB_RAM_DVS_LEN (4U) +#define GLB_CR_WB_RAM_DVS_MSK (((1U << GLB_CR_WB_RAM_DVS_LEN) - 1) << GLB_CR_WB_RAM_DVS_POS) +#define GLB_CR_WB_RAM_DVS_UMSK (~(((1U << GLB_CR_WB_RAM_DVS_LEN) - 1) << GLB_CR_WB_RAM_DVS_POS)) +#define GLB_CR_MISC_RAM_DVS GLB_CR_MISC_RAM_DVS +#define GLB_CR_MISC_RAM_DVS_POS (16U) +#define GLB_CR_MISC_RAM_DVS_LEN (4U) +#define GLB_CR_MISC_RAM_DVS_MSK (((1U << GLB_CR_MISC_RAM_DVS_LEN) - 1) << GLB_CR_MISC_RAM_DVS_POS) +#define GLB_CR_MISC_RAM_DVS_UMSK (~(((1U << GLB_CR_MISC_RAM_DVS_LEN) - 1) << GLB_CR_MISC_RAM_DVS_POS)) +#define GLB_CR_OCRAM_DVS GLB_CR_OCRAM_DVS +#define GLB_CR_OCRAM_DVS_POS (20U) +#define GLB_CR_OCRAM_DVS_LEN (4U) +#define GLB_CR_OCRAM_DVS_MSK (((1U << GLB_CR_OCRAM_DVS_LEN) - 1) << GLB_CR_OCRAM_DVS_POS) +#define GLB_CR_OCRAM_DVS_UMSK (~(((1U << GLB_CR_OCRAM_DVS_LEN) - 1) << GLB_CR_OCRAM_DVS_POS)) +#define GLB_CR_WRAM_DVS GLB_CR_WRAM_DVS +#define GLB_CR_WRAM_DVS_POS (24U) +#define GLB_CR_WRAM_DVS_LEN (4U) +#define GLB_CR_WRAM_DVS_MSK (((1U << GLB_CR_WRAM_DVS_LEN) - 1) << GLB_CR_WRAM_DVS_POS) +#define GLB_CR_WRAM_DVS_UMSK (~(((1U << GLB_CR_WRAM_DVS_LEN) - 1) << GLB_CR_WRAM_DVS_POS)) + +/* 0x620 : psram_cfg0 */ +#define GLB_PSRAM_CFG0_OFFSET (0x620) +#define GLB_REG_PSRAMB_CLK_EN GLB_REG_PSRAMB_CLK_EN +#define GLB_REG_PSRAMB_CLK_EN_POS (27U) +#define GLB_REG_PSRAMB_CLK_EN_LEN (1U) +#define GLB_REG_PSRAMB_CLK_EN_MSK (((1U << GLB_REG_PSRAMB_CLK_EN_LEN) - 1) << GLB_REG_PSRAMB_CLK_EN_POS) +#define GLB_REG_PSRAMB_CLK_EN_UMSK (~(((1U << GLB_REG_PSRAMB_CLK_EN_LEN) - 1) << GLB_REG_PSRAMB_CLK_EN_POS)) +#define GLB_REG_PSRAMB_CLK_SEL GLB_REG_PSRAMB_CLK_SEL +#define GLB_REG_PSRAMB_CLK_SEL_POS (28U) +#define GLB_REG_PSRAMB_CLK_SEL_LEN (2U) +#define GLB_REG_PSRAMB_CLK_SEL_MSK (((1U << GLB_REG_PSRAMB_CLK_SEL_LEN) - 1) << GLB_REG_PSRAMB_CLK_SEL_POS) +#define GLB_REG_PSRAMB_CLK_SEL_UMSK (~(((1U << GLB_REG_PSRAMB_CLK_SEL_LEN) - 1) << GLB_REG_PSRAMB_CLK_SEL_POS)) +#define GLB_REG_PSRAMB_CLK_DIV GLB_REG_PSRAMB_CLK_DIV +#define GLB_REG_PSRAMB_CLK_DIV_POS (30U) +#define GLB_REG_PSRAMB_CLK_DIV_LEN (2U) +#define GLB_REG_PSRAMB_CLK_DIV_MSK (((1U << GLB_REG_PSRAMB_CLK_DIV_LEN) - 1) << GLB_REG_PSRAMB_CLK_DIV_POS) +#define GLB_REG_PSRAMB_CLK_DIV_UMSK (~(((1U << GLB_REG_PSRAMB_CLK_DIV_LEN) - 1) << GLB_REG_PSRAMB_CLK_DIV_POS)) + +/* 0x6C0 : ldo28cis */ +#define GLB_LDO28CIS_OFFSET (0x6C0) +#define GLB_PU_LDO28CIS GLB_PU_LDO28CIS +#define GLB_PU_LDO28CIS_POS (0U) +#define GLB_PU_LDO28CIS_LEN (1U) +#define GLB_PU_LDO28CIS_MSK (((1U << GLB_PU_LDO28CIS_LEN) - 1) << GLB_PU_LDO28CIS_POS) +#define GLB_PU_LDO28CIS_UMSK (~(((1U << GLB_PU_LDO28CIS_LEN) - 1) << GLB_PU_LDO28CIS_POS)) +#define GLB_LDO28CIS_BYPASS GLB_LDO28CIS_BYPASS +#define GLB_LDO28CIS_BYPASS_POS (1U) +#define GLB_LDO28CIS_BYPASS_LEN (1U) +#define GLB_LDO28CIS_BYPASS_MSK (((1U << GLB_LDO28CIS_BYPASS_LEN) - 1) << GLB_LDO28CIS_BYPASS_POS) +#define GLB_LDO28CIS_BYPASS_UMSK (~(((1U << GLB_LDO28CIS_BYPASS_LEN) - 1) << GLB_LDO28CIS_BYPASS_POS)) +#define GLB_LDO28CIS_PULLDOWN GLB_LDO28CIS_PULLDOWN +#define GLB_LDO28CIS_PULLDOWN_POS (2U) +#define GLB_LDO28CIS_PULLDOWN_LEN (1U) +#define GLB_LDO28CIS_PULLDOWN_MSK (((1U << GLB_LDO28CIS_PULLDOWN_LEN) - 1) << GLB_LDO28CIS_PULLDOWN_POS) +#define GLB_LDO28CIS_PULLDOWN_UMSK (~(((1U << GLB_LDO28CIS_PULLDOWN_LEN) - 1) << GLB_LDO28CIS_PULLDOWN_POS)) +#define GLB_LDO28CIS_PULLDOWN_SEL GLB_LDO28CIS_PULLDOWN_SEL +#define GLB_LDO28CIS_PULLDOWN_SEL_POS (3U) +#define GLB_LDO28CIS_PULLDOWN_SEL_LEN (1U) +#define GLB_LDO28CIS_PULLDOWN_SEL_MSK (((1U << GLB_LDO28CIS_PULLDOWN_SEL_LEN) - 1) << GLB_LDO28CIS_PULLDOWN_SEL_POS) +#define GLB_LDO28CIS_PULLDOWN_SEL_UMSK (~(((1U << GLB_LDO28CIS_PULLDOWN_SEL_LEN) - 1) << GLB_LDO28CIS_PULLDOWN_SEL_POS)) +#define GLB_LDO28CIS_BM GLB_LDO28CIS_BM +#define GLB_LDO28CIS_BM_POS (4U) +#define GLB_LDO28CIS_BM_LEN (3U) +#define GLB_LDO28CIS_BM_MSK (((1U << GLB_LDO28CIS_BM_LEN) - 1) << GLB_LDO28CIS_BM_POS) +#define GLB_LDO28CIS_BM_UMSK (~(((1U << GLB_LDO28CIS_BM_LEN) - 1) << GLB_LDO28CIS_BM_POS)) +#define GLB_LDO28CIS_CC GLB_LDO28CIS_CC +#define GLB_LDO28CIS_CC_POS (8U) +#define GLB_LDO28CIS_CC_LEN (3U) +#define GLB_LDO28CIS_CC_MSK (((1U << GLB_LDO28CIS_CC_LEN) - 1) << GLB_LDO28CIS_CC_POS) +#define GLB_LDO28CIS_CC_UMSK (~(((1U << GLB_LDO28CIS_CC_LEN) - 1) << GLB_LDO28CIS_CC_POS)) +#define GLB_LDO28CIS_OCP_OUT GLB_LDO28CIS_OCP_OUT +#define GLB_LDO28CIS_OCP_OUT_POS (11U) +#define GLB_LDO28CIS_OCP_OUT_LEN (1U) +#define GLB_LDO28CIS_OCP_OUT_MSK (((1U << GLB_LDO28CIS_OCP_OUT_LEN) - 1) << GLB_LDO28CIS_OCP_OUT_POS) +#define GLB_LDO28CIS_OCP_OUT_UMSK (~(((1U << GLB_LDO28CIS_OCP_OUT_LEN) - 1) << GLB_LDO28CIS_OCP_OUT_POS)) +#define GLB_LDO28CIS_OCP_TH GLB_LDO28CIS_OCP_TH +#define GLB_LDO28CIS_OCP_TH_POS (12U) +#define GLB_LDO28CIS_OCP_TH_LEN (3U) +#define GLB_LDO28CIS_OCP_TH_MSK (((1U << GLB_LDO28CIS_OCP_TH_LEN) - 1) << GLB_LDO28CIS_OCP_TH_POS) +#define GLB_LDO28CIS_OCP_TH_UMSK (~(((1U << GLB_LDO28CIS_OCP_TH_LEN) - 1) << GLB_LDO28CIS_OCP_TH_POS)) +#define GLB_LDO28CIS_OCP_EN GLB_LDO28CIS_OCP_EN +#define GLB_LDO28CIS_OCP_EN_POS (15U) +#define GLB_LDO28CIS_OCP_EN_LEN (1U) +#define GLB_LDO28CIS_OCP_EN_MSK (((1U << GLB_LDO28CIS_OCP_EN_LEN) - 1) << GLB_LDO28CIS_OCP_EN_POS) +#define GLB_LDO28CIS_OCP_EN_UMSK (~(((1U << GLB_LDO28CIS_OCP_EN_LEN) - 1) << GLB_LDO28CIS_OCP_EN_POS)) +#define GLB_LDO28CIS_SSTART_DELAY GLB_LDO28CIS_SSTART_DELAY +#define GLB_LDO28CIS_SSTART_DELAY_POS (16U) +#define GLB_LDO28CIS_SSTART_DELAY_LEN (3U) +#define GLB_LDO28CIS_SSTART_DELAY_MSK (((1U << GLB_LDO28CIS_SSTART_DELAY_LEN) - 1) << GLB_LDO28CIS_SSTART_DELAY_POS) +#define GLB_LDO28CIS_SSTART_DELAY_UMSK (~(((1U << GLB_LDO28CIS_SSTART_DELAY_LEN) - 1) << GLB_LDO28CIS_SSTART_DELAY_POS)) +#define GLB_LDO28CIS_SSTART_EN GLB_LDO28CIS_SSTART_EN +#define GLB_LDO28CIS_SSTART_EN_POS (19U) +#define GLB_LDO28CIS_SSTART_EN_LEN (1U) +#define GLB_LDO28CIS_SSTART_EN_MSK (((1U << GLB_LDO28CIS_SSTART_EN_LEN) - 1) << GLB_LDO28CIS_SSTART_EN_POS) +#define GLB_LDO28CIS_SSTART_EN_UMSK (~(((1U << GLB_LDO28CIS_SSTART_EN_LEN) - 1) << GLB_LDO28CIS_SSTART_EN_POS)) +#define GLB_LDO28CIS_VOUT_SEL GLB_LDO28CIS_VOUT_SEL +#define GLB_LDO28CIS_VOUT_SEL_POS (20U) +#define GLB_LDO28CIS_VOUT_SEL_LEN (4U) +#define GLB_LDO28CIS_VOUT_SEL_MSK (((1U << GLB_LDO28CIS_VOUT_SEL_LEN) - 1) << GLB_LDO28CIS_VOUT_SEL_POS) +#define GLB_LDO28CIS_VOUT_SEL_UMSK (~(((1U << GLB_LDO28CIS_VOUT_SEL_LEN) - 1) << GLB_LDO28CIS_VOUT_SEL_POS)) +#define GLB_LDO28CIS_VOUT_TRIM GLB_LDO28CIS_VOUT_TRIM +#define GLB_LDO28CIS_VOUT_TRIM_POS (24U) +#define GLB_LDO28CIS_VOUT_TRIM_LEN (4U) +#define GLB_LDO28CIS_VOUT_TRIM_MSK (((1U << GLB_LDO28CIS_VOUT_TRIM_LEN) - 1) << GLB_LDO28CIS_VOUT_TRIM_POS) +#define GLB_LDO28CIS_VOUT_TRIM_UMSK (~(((1U << GLB_LDO28CIS_VOUT_TRIM_LEN) - 1) << GLB_LDO28CIS_VOUT_TRIM_POS)) + +/* 0x6C4 : ldo18io */ +#define GLB_LDO18IO_OFFSET (0x6C4) + +/* 0x6C8 : ldo15cis */ +#define GLB_LDO15CIS_OFFSET (0x6C8) +#define GLB_PU_LDO15CIS GLB_PU_LDO15CIS +#define GLB_PU_LDO15CIS_POS (0U) +#define GLB_PU_LDO15CIS_LEN (1U) +#define GLB_PU_LDO15CIS_MSK (((1U << GLB_PU_LDO15CIS_LEN) - 1) << GLB_PU_LDO15CIS_POS) +#define GLB_PU_LDO15CIS_UMSK (~(((1U << GLB_PU_LDO15CIS_LEN) - 1) << GLB_PU_LDO15CIS_POS)) +#define GLB_LDO15CIS_BYPASS GLB_LDO15CIS_BYPASS +#define GLB_LDO15CIS_BYPASS_POS (1U) +#define GLB_LDO15CIS_BYPASS_LEN (1U) +#define GLB_LDO15CIS_BYPASS_MSK (((1U << GLB_LDO15CIS_BYPASS_LEN) - 1) << GLB_LDO15CIS_BYPASS_POS) +#define GLB_LDO15CIS_BYPASS_UMSK (~(((1U << GLB_LDO15CIS_BYPASS_LEN) - 1) << GLB_LDO15CIS_BYPASS_POS)) +#define GLB_LDO15CIS_PULLDOWN GLB_LDO15CIS_PULLDOWN +#define GLB_LDO15CIS_PULLDOWN_POS (2U) +#define GLB_LDO15CIS_PULLDOWN_LEN (1U) +#define GLB_LDO15CIS_PULLDOWN_MSK (((1U << GLB_LDO15CIS_PULLDOWN_LEN) - 1) << GLB_LDO15CIS_PULLDOWN_POS) +#define GLB_LDO15CIS_PULLDOWN_UMSK (~(((1U << GLB_LDO15CIS_PULLDOWN_LEN) - 1) << GLB_LDO15CIS_PULLDOWN_POS)) +#define GLB_LDO15CIS_PULLDOWN_SEL GLB_LDO15CIS_PULLDOWN_SEL +#define GLB_LDO15CIS_PULLDOWN_SEL_POS (3U) +#define GLB_LDO15CIS_PULLDOWN_SEL_LEN (1U) +#define GLB_LDO15CIS_PULLDOWN_SEL_MSK (((1U << GLB_LDO15CIS_PULLDOWN_SEL_LEN) - 1) << GLB_LDO15CIS_PULLDOWN_SEL_POS) +#define GLB_LDO15CIS_PULLDOWN_SEL_UMSK (~(((1U << GLB_LDO15CIS_PULLDOWN_SEL_LEN) - 1) << GLB_LDO15CIS_PULLDOWN_SEL_POS)) +#define GLB_LDO15CIS_BM GLB_LDO15CIS_BM +#define GLB_LDO15CIS_BM_POS (4U) +#define GLB_LDO15CIS_BM_LEN (3U) +#define GLB_LDO15CIS_BM_MSK (((1U << GLB_LDO15CIS_BM_LEN) - 1) << GLB_LDO15CIS_BM_POS) +#define GLB_LDO15CIS_BM_UMSK (~(((1U << GLB_LDO15CIS_BM_LEN) - 1) << GLB_LDO15CIS_BM_POS)) +#define GLB_LDO15CIS_CC GLB_LDO15CIS_CC +#define GLB_LDO15CIS_CC_POS (8U) +#define GLB_LDO15CIS_CC_LEN (3U) +#define GLB_LDO15CIS_CC_MSK (((1U << GLB_LDO15CIS_CC_LEN) - 1) << GLB_LDO15CIS_CC_POS) +#define GLB_LDO15CIS_CC_UMSK (~(((1U << GLB_LDO15CIS_CC_LEN) - 1) << GLB_LDO15CIS_CC_POS)) +#define GLB_LDO15CIS_OCP_OUT GLB_LDO15CIS_OCP_OUT +#define GLB_LDO15CIS_OCP_OUT_POS (11U) +#define GLB_LDO15CIS_OCP_OUT_LEN (1U) +#define GLB_LDO15CIS_OCP_OUT_MSK (((1U << GLB_LDO15CIS_OCP_OUT_LEN) - 1) << GLB_LDO15CIS_OCP_OUT_POS) +#define GLB_LDO15CIS_OCP_OUT_UMSK (~(((1U << GLB_LDO15CIS_OCP_OUT_LEN) - 1) << GLB_LDO15CIS_OCP_OUT_POS)) +#define GLB_LDO15CIS_OCP_TH GLB_LDO15CIS_OCP_TH +#define GLB_LDO15CIS_OCP_TH_POS (12U) +#define GLB_LDO15CIS_OCP_TH_LEN (3U) +#define GLB_LDO15CIS_OCP_TH_MSK (((1U << GLB_LDO15CIS_OCP_TH_LEN) - 1) << GLB_LDO15CIS_OCP_TH_POS) +#define GLB_LDO15CIS_OCP_TH_UMSK (~(((1U << GLB_LDO15CIS_OCP_TH_LEN) - 1) << GLB_LDO15CIS_OCP_TH_POS)) +#define GLB_LDO15CIS_OCP_EN GLB_LDO15CIS_OCP_EN +#define GLB_LDO15CIS_OCP_EN_POS (15U) +#define GLB_LDO15CIS_OCP_EN_LEN (1U) +#define GLB_LDO15CIS_OCP_EN_MSK (((1U << GLB_LDO15CIS_OCP_EN_LEN) - 1) << GLB_LDO15CIS_OCP_EN_POS) +#define GLB_LDO15CIS_OCP_EN_UMSK (~(((1U << GLB_LDO15CIS_OCP_EN_LEN) - 1) << GLB_LDO15CIS_OCP_EN_POS)) +#define GLB_LDO15CIS_SSTART_DELAY GLB_LDO15CIS_SSTART_DELAY +#define GLB_LDO15CIS_SSTART_DELAY_POS (16U) +#define GLB_LDO15CIS_SSTART_DELAY_LEN (3U) +#define GLB_LDO15CIS_SSTART_DELAY_MSK (((1U << GLB_LDO15CIS_SSTART_DELAY_LEN) - 1) << GLB_LDO15CIS_SSTART_DELAY_POS) +#define GLB_LDO15CIS_SSTART_DELAY_UMSK (~(((1U << GLB_LDO15CIS_SSTART_DELAY_LEN) - 1) << GLB_LDO15CIS_SSTART_DELAY_POS)) +#define GLB_LDO15CIS_SSTART_EN GLB_LDO15CIS_SSTART_EN +#define GLB_LDO15CIS_SSTART_EN_POS (19U) +#define GLB_LDO15CIS_SSTART_EN_LEN (1U) +#define GLB_LDO15CIS_SSTART_EN_MSK (((1U << GLB_LDO15CIS_SSTART_EN_LEN) - 1) << GLB_LDO15CIS_SSTART_EN_POS) +#define GLB_LDO15CIS_SSTART_EN_UMSK (~(((1U << GLB_LDO15CIS_SSTART_EN_LEN) - 1) << GLB_LDO15CIS_SSTART_EN_POS)) +#define GLB_LDO15CIS_VOUT_SEL GLB_LDO15CIS_VOUT_SEL +#define GLB_LDO15CIS_VOUT_SEL_POS (20U) +#define GLB_LDO15CIS_VOUT_SEL_LEN (4U) +#define GLB_LDO15CIS_VOUT_SEL_MSK (((1U << GLB_LDO15CIS_VOUT_SEL_LEN) - 1) << GLB_LDO15CIS_VOUT_SEL_POS) +#define GLB_LDO15CIS_VOUT_SEL_UMSK (~(((1U << GLB_LDO15CIS_VOUT_SEL_LEN) - 1) << GLB_LDO15CIS_VOUT_SEL_POS)) +#define GLB_LDO15CIS_VOUT_TRIM GLB_LDO15CIS_VOUT_TRIM +#define GLB_LDO15CIS_VOUT_TRIM_POS (24U) +#define GLB_LDO15CIS_VOUT_TRIM_LEN (4U) +#define GLB_LDO15CIS_VOUT_TRIM_MSK (((1U << GLB_LDO15CIS_VOUT_TRIM_LEN) - 1) << GLB_LDO15CIS_VOUT_TRIM_POS) +#define GLB_LDO15CIS_VOUT_TRIM_UMSK (~(((1U << GLB_LDO15CIS_VOUT_TRIM_LEN) - 1) << GLB_LDO15CIS_VOUT_TRIM_POS)) + +/* 0x6CC : ldo18flash */ +#define GLB_LDO18FLASH_OFFSET (0x6CC) +#define GLB_PU_LDO18FLASH GLB_PU_LDO18FLASH +#define GLB_PU_LDO18FLASH_POS (0U) +#define GLB_PU_LDO18FLASH_LEN (1U) +#define GLB_PU_LDO18FLASH_MSK (((1U << GLB_PU_LDO18FLASH_LEN) - 1) << GLB_PU_LDO18FLASH_POS) +#define GLB_PU_LDO18FLASH_UMSK (~(((1U << GLB_PU_LDO18FLASH_LEN) - 1) << GLB_PU_LDO18FLASH_POS)) +#define GLB_LDO18FLASH_BYPASS GLB_LDO18FLASH_BYPASS +#define GLB_LDO18FLASH_BYPASS_POS (1U) +#define GLB_LDO18FLASH_BYPASS_LEN (1U) +#define GLB_LDO18FLASH_BYPASS_MSK (((1U << GLB_LDO18FLASH_BYPASS_LEN) - 1) << GLB_LDO18FLASH_BYPASS_POS) +#define GLB_LDO18FLASH_BYPASS_UMSK (~(((1U << GLB_LDO18FLASH_BYPASS_LEN) - 1) << GLB_LDO18FLASH_BYPASS_POS)) +#define GLB_LDO18FLASH_PULLDOWN GLB_LDO18FLASH_PULLDOWN +#define GLB_LDO18FLASH_PULLDOWN_POS (2U) +#define GLB_LDO18FLASH_PULLDOWN_LEN (1U) +#define GLB_LDO18FLASH_PULLDOWN_MSK (((1U << GLB_LDO18FLASH_PULLDOWN_LEN) - 1) << GLB_LDO18FLASH_PULLDOWN_POS) +#define GLB_LDO18FLASH_PULLDOWN_UMSK (~(((1U << GLB_LDO18FLASH_PULLDOWN_LEN) - 1) << GLB_LDO18FLASH_PULLDOWN_POS)) +#define GLB_LDO18FLASH_PULLDOWN_SEL GLB_LDO18FLASH_PULLDOWN_SEL +#define GLB_LDO18FLASH_PULLDOWN_SEL_POS (3U) +#define GLB_LDO18FLASH_PULLDOWN_SEL_LEN (1U) +#define GLB_LDO18FLASH_PULLDOWN_SEL_MSK (((1U << GLB_LDO18FLASH_PULLDOWN_SEL_LEN) - 1) << GLB_LDO18FLASH_PULLDOWN_SEL_POS) +#define GLB_LDO18FLASH_PULLDOWN_SEL_UMSK (~(((1U << GLB_LDO18FLASH_PULLDOWN_SEL_LEN) - 1) << GLB_LDO18FLASH_PULLDOWN_SEL_POS)) +#define GLB_LDO18FLASH_BM GLB_LDO18FLASH_BM +#define GLB_LDO18FLASH_BM_POS (4U) +#define GLB_LDO18FLASH_BM_LEN (3U) +#define GLB_LDO18FLASH_BM_MSK (((1U << GLB_LDO18FLASH_BM_LEN) - 1) << GLB_LDO18FLASH_BM_POS) +#define GLB_LDO18FLASH_BM_UMSK (~(((1U << GLB_LDO18FLASH_BM_LEN) - 1) << GLB_LDO18FLASH_BM_POS)) +#define GLB_LDO18FLASH_CC GLB_LDO18FLASH_CC +#define GLB_LDO18FLASH_CC_POS (8U) +#define GLB_LDO18FLASH_CC_LEN (3U) +#define GLB_LDO18FLASH_CC_MSK (((1U << GLB_LDO18FLASH_CC_LEN) - 1) << GLB_LDO18FLASH_CC_POS) +#define GLB_LDO18FLASH_CC_UMSK (~(((1U << GLB_LDO18FLASH_CC_LEN) - 1) << GLB_LDO18FLASH_CC_POS)) +#define GLB_LDO18FLASH_OCP_OUT GLB_LDO18FLASH_OCP_OUT +#define GLB_LDO18FLASH_OCP_OUT_POS (11U) +#define GLB_LDO18FLASH_OCP_OUT_LEN (1U) +#define GLB_LDO18FLASH_OCP_OUT_MSK (((1U << GLB_LDO18FLASH_OCP_OUT_LEN) - 1) << GLB_LDO18FLASH_OCP_OUT_POS) +#define GLB_LDO18FLASH_OCP_OUT_UMSK (~(((1U << GLB_LDO18FLASH_OCP_OUT_LEN) - 1) << GLB_LDO18FLASH_OCP_OUT_POS)) +#define GLB_LDO18FLASH_OCP_TH GLB_LDO18FLASH_OCP_TH +#define GLB_LDO18FLASH_OCP_TH_POS (12U) +#define GLB_LDO18FLASH_OCP_TH_LEN (3U) +#define GLB_LDO18FLASH_OCP_TH_MSK (((1U << GLB_LDO18FLASH_OCP_TH_LEN) - 1) << GLB_LDO18FLASH_OCP_TH_POS) +#define GLB_LDO18FLASH_OCP_TH_UMSK (~(((1U << GLB_LDO18FLASH_OCP_TH_LEN) - 1) << GLB_LDO18FLASH_OCP_TH_POS)) +#define GLB_LDO18FLASH_OCP_EN GLB_LDO18FLASH_OCP_EN +#define GLB_LDO18FLASH_OCP_EN_POS (15U) +#define GLB_LDO18FLASH_OCP_EN_LEN (1U) +#define GLB_LDO18FLASH_OCP_EN_MSK (((1U << GLB_LDO18FLASH_OCP_EN_LEN) - 1) << GLB_LDO18FLASH_OCP_EN_POS) +#define GLB_LDO18FLASH_OCP_EN_UMSK (~(((1U << GLB_LDO18FLASH_OCP_EN_LEN) - 1) << GLB_LDO18FLASH_OCP_EN_POS)) +#define GLB_LDO18FLASH_SSTART_DELAY GLB_LDO18FLASH_SSTART_DELAY +#define GLB_LDO18FLASH_SSTART_DELAY_POS (16U) +#define GLB_LDO18FLASH_SSTART_DELAY_LEN (3U) +#define GLB_LDO18FLASH_SSTART_DELAY_MSK (((1U << GLB_LDO18FLASH_SSTART_DELAY_LEN) - 1) << GLB_LDO18FLASH_SSTART_DELAY_POS) +#define GLB_LDO18FLASH_SSTART_DELAY_UMSK (~(((1U << GLB_LDO18FLASH_SSTART_DELAY_LEN) - 1) << GLB_LDO18FLASH_SSTART_DELAY_POS)) +#define GLB_LDO18FLASH_SSTART_EN GLB_LDO18FLASH_SSTART_EN +#define GLB_LDO18FLASH_SSTART_EN_POS (19U) +#define GLB_LDO18FLASH_SSTART_EN_LEN (1U) +#define GLB_LDO18FLASH_SSTART_EN_MSK (((1U << GLB_LDO18FLASH_SSTART_EN_LEN) - 1) << GLB_LDO18FLASH_SSTART_EN_POS) +#define GLB_LDO18FLASH_SSTART_EN_UMSK (~(((1U << GLB_LDO18FLASH_SSTART_EN_LEN) - 1) << GLB_LDO18FLASH_SSTART_EN_POS)) +#define GLB_LDO18FLASH_VOUT_SEL GLB_LDO18FLASH_VOUT_SEL +#define GLB_LDO18FLASH_VOUT_SEL_POS (20U) +#define GLB_LDO18FLASH_VOUT_SEL_LEN (4U) +#define GLB_LDO18FLASH_VOUT_SEL_MSK (((1U << GLB_LDO18FLASH_VOUT_SEL_LEN) - 1) << GLB_LDO18FLASH_VOUT_SEL_POS) +#define GLB_LDO18FLASH_VOUT_SEL_UMSK (~(((1U << GLB_LDO18FLASH_VOUT_SEL_LEN) - 1) << GLB_LDO18FLASH_VOUT_SEL_POS)) +#define GLB_LDO18FLASH_VOUT_TRIM GLB_LDO18FLASH_VOUT_TRIM +#define GLB_LDO18FLASH_VOUT_TRIM_POS (24U) +#define GLB_LDO18FLASH_VOUT_TRIM_LEN (4U) +#define GLB_LDO18FLASH_VOUT_TRIM_MSK (((1U << GLB_LDO18FLASH_VOUT_TRIM_LEN) - 1) << GLB_LDO18FLASH_VOUT_TRIM_POS) +#define GLB_LDO18FLASH_VOUT_TRIM_UMSK (~(((1U << GLB_LDO18FLASH_VOUT_TRIM_LEN) - 1) << GLB_LDO18FLASH_VOUT_TRIM_POS)) + +/* 0x6D0 : ldo12uhs */ +#define GLB_LDO12UHS_OFFSET (0x6D0) +#define GLB_PU_LDO12UHS GLB_PU_LDO12UHS +#define GLB_PU_LDO12UHS_POS (0U) +#define GLB_PU_LDO12UHS_LEN (1U) +#define GLB_PU_LDO12UHS_MSK (((1U << GLB_PU_LDO12UHS_LEN) - 1) << GLB_PU_LDO12UHS_POS) +#define GLB_PU_LDO12UHS_UMSK (~(((1U << GLB_PU_LDO12UHS_LEN) - 1) << GLB_PU_LDO12UHS_POS)) +#define GLB_LDO12UHS_BYPASS GLB_LDO12UHS_BYPASS +#define GLB_LDO12UHS_BYPASS_POS (1U) +#define GLB_LDO12UHS_BYPASS_LEN (1U) +#define GLB_LDO12UHS_BYPASS_MSK (((1U << GLB_LDO12UHS_BYPASS_LEN) - 1) << GLB_LDO12UHS_BYPASS_POS) +#define GLB_LDO12UHS_BYPASS_UMSK (~(((1U << GLB_LDO12UHS_BYPASS_LEN) - 1) << GLB_LDO12UHS_BYPASS_POS)) +#define GLB_LDO12UHS_PULLDOWN GLB_LDO12UHS_PULLDOWN +#define GLB_LDO12UHS_PULLDOWN_POS (2U) +#define GLB_LDO12UHS_PULLDOWN_LEN (1U) +#define GLB_LDO12UHS_PULLDOWN_MSK (((1U << GLB_LDO12UHS_PULLDOWN_LEN) - 1) << GLB_LDO12UHS_PULLDOWN_POS) +#define GLB_LDO12UHS_PULLDOWN_UMSK (~(((1U << GLB_LDO12UHS_PULLDOWN_LEN) - 1) << GLB_LDO12UHS_PULLDOWN_POS)) +#define GLB_LDO12UHS_PULLDOWN_SEL GLB_LDO12UHS_PULLDOWN_SEL +#define GLB_LDO12UHS_PULLDOWN_SEL_POS (3U) +#define GLB_LDO12UHS_PULLDOWN_SEL_LEN (1U) +#define GLB_LDO12UHS_PULLDOWN_SEL_MSK (((1U << GLB_LDO12UHS_PULLDOWN_SEL_LEN) - 1) << GLB_LDO12UHS_PULLDOWN_SEL_POS) +#define GLB_LDO12UHS_PULLDOWN_SEL_UMSK (~(((1U << GLB_LDO12UHS_PULLDOWN_SEL_LEN) - 1) << GLB_LDO12UHS_PULLDOWN_SEL_POS)) +#define GLB_LDO12UHS_BM GLB_LDO12UHS_BM +#define GLB_LDO12UHS_BM_POS (4U) +#define GLB_LDO12UHS_BM_LEN (3U) +#define GLB_LDO12UHS_BM_MSK (((1U << GLB_LDO12UHS_BM_LEN) - 1) << GLB_LDO12UHS_BM_POS) +#define GLB_LDO12UHS_BM_UMSK (~(((1U << GLB_LDO12UHS_BM_LEN) - 1) << GLB_LDO12UHS_BM_POS)) +#define GLB_LDO12UHS_CC GLB_LDO12UHS_CC +#define GLB_LDO12UHS_CC_POS (8U) +#define GLB_LDO12UHS_CC_LEN (3U) +#define GLB_LDO12UHS_CC_MSK (((1U << GLB_LDO12UHS_CC_LEN) - 1) << GLB_LDO12UHS_CC_POS) +#define GLB_LDO12UHS_CC_UMSK (~(((1U << GLB_LDO12UHS_CC_LEN) - 1) << GLB_LDO12UHS_CC_POS)) +#define GLB_LDO12UHS_OCP_OUT GLB_LDO12UHS_OCP_OUT +#define GLB_LDO12UHS_OCP_OUT_POS (11U) +#define GLB_LDO12UHS_OCP_OUT_LEN (1U) +#define GLB_LDO12UHS_OCP_OUT_MSK (((1U << GLB_LDO12UHS_OCP_OUT_LEN) - 1) << GLB_LDO12UHS_OCP_OUT_POS) +#define GLB_LDO12UHS_OCP_OUT_UMSK (~(((1U << GLB_LDO12UHS_OCP_OUT_LEN) - 1) << GLB_LDO12UHS_OCP_OUT_POS)) +#define GLB_LDO12UHS_OCP_TH GLB_LDO12UHS_OCP_TH +#define GLB_LDO12UHS_OCP_TH_POS (12U) +#define GLB_LDO12UHS_OCP_TH_LEN (3U) +#define GLB_LDO12UHS_OCP_TH_MSK (((1U << GLB_LDO12UHS_OCP_TH_LEN) - 1) << GLB_LDO12UHS_OCP_TH_POS) +#define GLB_LDO12UHS_OCP_TH_UMSK (~(((1U << GLB_LDO12UHS_OCP_TH_LEN) - 1) << GLB_LDO12UHS_OCP_TH_POS)) +#define GLB_LDO12UHS_OCP_EN GLB_LDO12UHS_OCP_EN +#define GLB_LDO12UHS_OCP_EN_POS (15U) +#define GLB_LDO12UHS_OCP_EN_LEN (1U) +#define GLB_LDO12UHS_OCP_EN_MSK (((1U << GLB_LDO12UHS_OCP_EN_LEN) - 1) << GLB_LDO12UHS_OCP_EN_POS) +#define GLB_LDO12UHS_OCP_EN_UMSK (~(((1U << GLB_LDO12UHS_OCP_EN_LEN) - 1) << GLB_LDO12UHS_OCP_EN_POS)) +#define GLB_LDO12UHS_SSTART_DELAY GLB_LDO12UHS_SSTART_DELAY +#define GLB_LDO12UHS_SSTART_DELAY_POS (16U) +#define GLB_LDO12UHS_SSTART_DELAY_LEN (3U) +#define GLB_LDO12UHS_SSTART_DELAY_MSK (((1U << GLB_LDO12UHS_SSTART_DELAY_LEN) - 1) << GLB_LDO12UHS_SSTART_DELAY_POS) +#define GLB_LDO12UHS_SSTART_DELAY_UMSK (~(((1U << GLB_LDO12UHS_SSTART_DELAY_LEN) - 1) << GLB_LDO12UHS_SSTART_DELAY_POS)) +#define GLB_LDO12UHS_SSTART_EN GLB_LDO12UHS_SSTART_EN +#define GLB_LDO12UHS_SSTART_EN_POS (19U) +#define GLB_LDO12UHS_SSTART_EN_LEN (1U) +#define GLB_LDO12UHS_SSTART_EN_MSK (((1U << GLB_LDO12UHS_SSTART_EN_LEN) - 1) << GLB_LDO12UHS_SSTART_EN_POS) +#define GLB_LDO12UHS_SSTART_EN_UMSK (~(((1U << GLB_LDO12UHS_SSTART_EN_LEN) - 1) << GLB_LDO12UHS_SSTART_EN_POS)) +#define GLB_LDO12UHS_VOUT_SEL GLB_LDO12UHS_VOUT_SEL +#define GLB_LDO12UHS_VOUT_SEL_POS (20U) +#define GLB_LDO12UHS_VOUT_SEL_LEN (4U) +#define GLB_LDO12UHS_VOUT_SEL_MSK (((1U << GLB_LDO12UHS_VOUT_SEL_LEN) - 1) << GLB_LDO12UHS_VOUT_SEL_POS) +#define GLB_LDO12UHS_VOUT_SEL_UMSK (~(((1U << GLB_LDO12UHS_VOUT_SEL_LEN) - 1) << GLB_LDO12UHS_VOUT_SEL_POS)) +#define GLB_LDO12UHS_VOUT_TRIM GLB_LDO12UHS_VOUT_TRIM +#define GLB_LDO12UHS_VOUT_TRIM_POS (24U) +#define GLB_LDO12UHS_VOUT_TRIM_LEN (4U) +#define GLB_LDO12UHS_VOUT_TRIM_MSK (((1U << GLB_LDO12UHS_VOUT_TRIM_LEN) - 1) << GLB_LDO12UHS_VOUT_TRIM_POS) +#define GLB_LDO12UHS_VOUT_TRIM_UMSK (~(((1U << GLB_LDO12UHS_VOUT_TRIM_LEN) - 1) << GLB_LDO12UHS_VOUT_TRIM_POS)) + +/* 0x6F0 : proc_mon */ +#define GLB_PROC_MON_OFFSET (0x6F0) +#define GLB_PU_PROC_MON GLB_PU_PROC_MON +#define GLB_PU_PROC_MON_POS (0U) +#define GLB_PU_PROC_MON_LEN (1U) +#define GLB_PU_PROC_MON_MSK (((1U << GLB_PU_PROC_MON_LEN) - 1) << GLB_PU_PROC_MON_POS) +#define GLB_PU_PROC_MON_UMSK (~(((1U << GLB_PU_PROC_MON_LEN) - 1) << GLB_PU_PROC_MON_POS)) +#define GLB_OSC_EN_RVT GLB_OSC_EN_RVT +#define GLB_OSC_EN_RVT_POS (1U) +#define GLB_OSC_EN_RVT_LEN (1U) +#define GLB_OSC_EN_RVT_MSK (((1U << GLB_OSC_EN_RVT_LEN) - 1) << GLB_OSC_EN_RVT_POS) +#define GLB_OSC_EN_RVT_UMSK (~(((1U << GLB_OSC_EN_RVT_LEN) - 1) << GLB_OSC_EN_RVT_POS)) +#define GLB_OSC_EN_LVT GLB_OSC_EN_LVT +#define GLB_OSC_EN_LVT_POS (2U) +#define GLB_OSC_EN_LVT_LEN (1U) +#define GLB_OSC_EN_LVT_MSK (((1U << GLB_OSC_EN_LVT_LEN) - 1) << GLB_OSC_EN_LVT_POS) +#define GLB_OSC_EN_LVT_UMSK (~(((1U << GLB_OSC_EN_LVT_LEN) - 1) << GLB_OSC_EN_LVT_POS)) +#define GLB_OSC_SEL GLB_OSC_SEL +#define GLB_OSC_SEL_POS (3U) +#define GLB_OSC_SEL_LEN (1U) +#define GLB_OSC_SEL_MSK (((1U << GLB_OSC_SEL_LEN) - 1) << GLB_OSC_SEL_POS) +#define GLB_OSC_SEL_UMSK (~(((1U << GLB_OSC_SEL_LEN) - 1) << GLB_OSC_SEL_POS)) +#define GLB_RSTN_RINGCOUNT GLB_RSTN_RINGCOUNT +#define GLB_RSTN_RINGCOUNT_POS (4U) +#define GLB_RSTN_RINGCOUNT_LEN (1U) +#define GLB_RSTN_RINGCOUNT_MSK (((1U << GLB_RSTN_RINGCOUNT_LEN) - 1) << GLB_RSTN_RINGCOUNT_POS) +#define GLB_RSTN_RINGCOUNT_UMSK (~(((1U << GLB_RSTN_RINGCOUNT_LEN) - 1) << GLB_RSTN_RINGCOUNT_POS)) +#define GLB_RSTN_REFCOUNT GLB_RSTN_REFCOUNT +#define GLB_RSTN_REFCOUNT_POS (5U) +#define GLB_RSTN_REFCOUNT_LEN (1U) +#define GLB_RSTN_REFCOUNT_MSK (((1U << GLB_RSTN_REFCOUNT_LEN) - 1) << GLB_RSTN_REFCOUNT_POS) +#define GLB_RSTN_REFCOUNT_UMSK (~(((1U << GLB_RSTN_REFCOUNT_LEN) - 1) << GLB_RSTN_REFCOUNT_POS)) +#define GLB_REFCOUNT_DIV_ONEHOT GLB_REFCOUNT_DIV_ONEHOT +#define GLB_REFCOUNT_DIV_ONEHOT_POS (8U) +#define GLB_REFCOUNT_DIV_ONEHOT_LEN (4U) +#define GLB_REFCOUNT_DIV_ONEHOT_MSK (((1U << GLB_REFCOUNT_DIV_ONEHOT_LEN) - 1) << GLB_REFCOUNT_DIV_ONEHOT_POS) +#define GLB_REFCOUNT_DIV_ONEHOT_UMSK (~(((1U << GLB_REFCOUNT_DIV_ONEHOT_LEN) - 1) << GLB_REFCOUNT_DIV_ONEHOT_POS)) +#define GLB_RING_FREQ GLB_RING_FREQ +#define GLB_RING_FREQ_POS (12U) +#define GLB_RING_FREQ_LEN (16U) +#define GLB_RING_FREQ_MSK (((1U << GLB_RING_FREQ_LEN) - 1) << GLB_RING_FREQ_POS) +#define GLB_RING_FREQ_UMSK (~(((1U << GLB_RING_FREQ_LEN) - 1) << GLB_RING_FREQ_POS)) +#define GLB_RING_FREQ_RDY GLB_RING_FREQ_RDY +#define GLB_RING_FREQ_RDY_POS (28U) +#define GLB_RING_FREQ_RDY_LEN (1U) +#define GLB_RING_FREQ_RDY_MSK (((1U << GLB_RING_FREQ_RDY_LEN) - 1) << GLB_RING_FREQ_RDY_POS) +#define GLB_RING_FREQ_RDY_UMSK (~(((1U << GLB_RING_FREQ_RDY_LEN) - 1) << GLB_RING_FREQ_RDY_POS)) + +/* 0x700 : dll_cfg0 */ +#define GLB_DLL_CFG0_OFFSET (0x700) + +/* 0x790 : mipi_pll_cfg0 */ +#define GLB_MIPI_PLL_CFG0_OFFSET (0x790) +#define GLB_MIPIPLL_SDM_RSTB GLB_MIPIPLL_SDM_RSTB +#define GLB_MIPIPLL_SDM_RSTB_POS (0U) +#define GLB_MIPIPLL_SDM_RSTB_LEN (1U) +#define GLB_MIPIPLL_SDM_RSTB_MSK (((1U << GLB_MIPIPLL_SDM_RSTB_LEN) - 1) << GLB_MIPIPLL_SDM_RSTB_POS) +#define GLB_MIPIPLL_SDM_RSTB_UMSK (~(((1U << GLB_MIPIPLL_SDM_RSTB_LEN) - 1) << GLB_MIPIPLL_SDM_RSTB_POS)) +#define GLB_MIPIPLL_FBDV_RSTB GLB_MIPIPLL_FBDV_RSTB +#define GLB_MIPIPLL_FBDV_RSTB_POS (2U) +#define GLB_MIPIPLL_FBDV_RSTB_LEN (1U) +#define GLB_MIPIPLL_FBDV_RSTB_MSK (((1U << GLB_MIPIPLL_FBDV_RSTB_LEN) - 1) << GLB_MIPIPLL_FBDV_RSTB_POS) +#define GLB_MIPIPLL_FBDV_RSTB_UMSK (~(((1U << GLB_MIPIPLL_FBDV_RSTB_LEN) - 1) << GLB_MIPIPLL_FBDV_RSTB_POS)) +#define GLB_PU_MIPIPLL_FBDV GLB_PU_MIPIPLL_FBDV +#define GLB_PU_MIPIPLL_FBDV_POS (5U) +#define GLB_PU_MIPIPLL_FBDV_LEN (1U) +#define GLB_PU_MIPIPLL_FBDV_MSK (((1U << GLB_PU_MIPIPLL_FBDV_LEN) - 1) << GLB_PU_MIPIPLL_FBDV_POS) +#define GLB_PU_MIPIPLL_FBDV_UMSK (~(((1U << GLB_PU_MIPIPLL_FBDV_LEN) - 1) << GLB_PU_MIPIPLL_FBDV_POS)) +#define GLB_PU_MIPIPLL_CP GLB_PU_MIPIPLL_CP +#define GLB_PU_MIPIPLL_CP_POS (8U) +#define GLB_PU_MIPIPLL_CP_LEN (1U) +#define GLB_PU_MIPIPLL_CP_MSK (((1U << GLB_PU_MIPIPLL_CP_LEN) - 1) << GLB_PU_MIPIPLL_CP_POS) +#define GLB_PU_MIPIPLL_CP_UMSK (~(((1U << GLB_PU_MIPIPLL_CP_LEN) - 1) << GLB_PU_MIPIPLL_CP_POS)) +#define GLB_PU_MIPIPLL_SFREG GLB_PU_MIPIPLL_SFREG +#define GLB_PU_MIPIPLL_SFREG_POS (9U) +#define GLB_PU_MIPIPLL_SFREG_LEN (1U) +#define GLB_PU_MIPIPLL_SFREG_MSK (((1U << GLB_PU_MIPIPLL_SFREG_LEN) - 1) << GLB_PU_MIPIPLL_SFREG_POS) +#define GLB_PU_MIPIPLL_SFREG_UMSK (~(((1U << GLB_PU_MIPIPLL_SFREG_LEN) - 1) << GLB_PU_MIPIPLL_SFREG_POS)) +#define GLB_PU_MIPIPLL GLB_PU_MIPIPLL +#define GLB_PU_MIPIPLL_POS (10U) +#define GLB_PU_MIPIPLL_LEN (1U) +#define GLB_PU_MIPIPLL_MSK (((1U << GLB_PU_MIPIPLL_LEN) - 1) << GLB_PU_MIPIPLL_POS) +#define GLB_PU_MIPIPLL_UMSK (~(((1U << GLB_PU_MIPIPLL_LEN) - 1) << GLB_PU_MIPIPLL_POS)) + +/* 0x794 : mipi_pll_cfg1 */ +#define GLB_MIPI_PLL_CFG1_OFFSET (0x794) +#define GLB_MIPIPLL_EVEN_DIV_RATIO GLB_MIPIPLL_EVEN_DIV_RATIO +#define GLB_MIPIPLL_EVEN_DIV_RATIO_POS (0U) +#define GLB_MIPIPLL_EVEN_DIV_RATIO_LEN (7U) +#define GLB_MIPIPLL_EVEN_DIV_RATIO_MSK (((1U << GLB_MIPIPLL_EVEN_DIV_RATIO_LEN) - 1) << GLB_MIPIPLL_EVEN_DIV_RATIO_POS) +#define GLB_MIPIPLL_EVEN_DIV_RATIO_UMSK (~(((1U << GLB_MIPIPLL_EVEN_DIV_RATIO_LEN) - 1) << GLB_MIPIPLL_EVEN_DIV_RATIO_POS)) +#define GLB_MIPIPLL_EVEN_DIV_EN GLB_MIPIPLL_EVEN_DIV_EN +#define GLB_MIPIPLL_EVEN_DIV_EN_POS (7U) +#define GLB_MIPIPLL_EVEN_DIV_EN_LEN (1U) +#define GLB_MIPIPLL_EVEN_DIV_EN_MSK (((1U << GLB_MIPIPLL_EVEN_DIV_EN_LEN) - 1) << GLB_MIPIPLL_EVEN_DIV_EN_POS) +#define GLB_MIPIPLL_EVEN_DIV_EN_UMSK (~(((1U << GLB_MIPIPLL_EVEN_DIV_EN_LEN) - 1) << GLB_MIPIPLL_EVEN_DIV_EN_POS)) +#define GLB_MIPIPLL_REFDIV_RATIO GLB_MIPIPLL_REFDIV_RATIO +#define GLB_MIPIPLL_REFDIV_RATIO_POS (8U) +#define GLB_MIPIPLL_REFDIV_RATIO_LEN (4U) +#define GLB_MIPIPLL_REFDIV_RATIO_MSK (((1U << GLB_MIPIPLL_REFDIV_RATIO_LEN) - 1) << GLB_MIPIPLL_REFDIV_RATIO_POS) +#define GLB_MIPIPLL_REFDIV_RATIO_UMSK (~(((1U << GLB_MIPIPLL_REFDIV_RATIO_LEN) - 1) << GLB_MIPIPLL_REFDIV_RATIO_POS)) +#define GLB_MIPIPLL_REFCLK_SEL GLB_MIPIPLL_REFCLK_SEL +#define GLB_MIPIPLL_REFCLK_SEL_POS (16U) +#define GLB_MIPIPLL_REFCLK_SEL_LEN (2U) +#define GLB_MIPIPLL_REFCLK_SEL_MSK (((1U << GLB_MIPIPLL_REFCLK_SEL_LEN) - 1) << GLB_MIPIPLL_REFCLK_SEL_POS) +#define GLB_MIPIPLL_REFCLK_SEL_UMSK (~(((1U << GLB_MIPIPLL_REFCLK_SEL_LEN) - 1) << GLB_MIPIPLL_REFCLK_SEL_POS)) +#define GLB_MIPIPLL_VG11_SEL GLB_MIPIPLL_VG11_SEL +#define GLB_MIPIPLL_VG11_SEL_POS (20U) +#define GLB_MIPIPLL_VG11_SEL_LEN (2U) +#define GLB_MIPIPLL_VG11_SEL_MSK (((1U << GLB_MIPIPLL_VG11_SEL_LEN) - 1) << GLB_MIPIPLL_VG11_SEL_POS) +#define GLB_MIPIPLL_VG11_SEL_UMSK (~(((1U << GLB_MIPIPLL_VG11_SEL_LEN) - 1) << GLB_MIPIPLL_VG11_SEL_POS)) +#define GLB_MIPIPLL_VG13_SEL GLB_MIPIPLL_VG13_SEL +#define GLB_MIPIPLL_VG13_SEL_POS (24U) +#define GLB_MIPIPLL_VG13_SEL_LEN (2U) +#define GLB_MIPIPLL_VG13_SEL_MSK (((1U << GLB_MIPIPLL_VG13_SEL_LEN) - 1) << GLB_MIPIPLL_VG13_SEL_POS) +#define GLB_MIPIPLL_VG13_SEL_UMSK (~(((1U << GLB_MIPIPLL_VG13_SEL_LEN) - 1) << GLB_MIPIPLL_VG13_SEL_POS)) + +/* 0x798 : mipi_pll_cfg2 */ +#define GLB_MIPI_PLL_CFG2_OFFSET (0x798) +#define GLB_MIPIPLL_SEL_CP_BIAS GLB_MIPIPLL_SEL_CP_BIAS +#define GLB_MIPIPLL_SEL_CP_BIAS_POS (0U) +#define GLB_MIPIPLL_SEL_CP_BIAS_LEN (1U) +#define GLB_MIPIPLL_SEL_CP_BIAS_MSK (((1U << GLB_MIPIPLL_SEL_CP_BIAS_LEN) - 1) << GLB_MIPIPLL_SEL_CP_BIAS_POS) +#define GLB_MIPIPLL_SEL_CP_BIAS_UMSK (~(((1U << GLB_MIPIPLL_SEL_CP_BIAS_LEN) - 1) << GLB_MIPIPLL_SEL_CP_BIAS_POS)) +#define GLB_MIPIPLL_ICP_5U GLB_MIPIPLL_ICP_5U +#define GLB_MIPIPLL_ICP_5U_POS (4U) +#define GLB_MIPIPLL_ICP_5U_LEN (2U) +#define GLB_MIPIPLL_ICP_5U_MSK (((1U << GLB_MIPIPLL_ICP_5U_LEN) - 1) << GLB_MIPIPLL_ICP_5U_POS) +#define GLB_MIPIPLL_ICP_5U_UMSK (~(((1U << GLB_MIPIPLL_ICP_5U_LEN) - 1) << GLB_MIPIPLL_ICP_5U_POS)) +#define GLB_MIPIPLL_ICP_1U GLB_MIPIPLL_ICP_1U +#define GLB_MIPIPLL_ICP_1U_POS (6U) +#define GLB_MIPIPLL_ICP_1U_LEN (2U) +#define GLB_MIPIPLL_ICP_1U_MSK (((1U << GLB_MIPIPLL_ICP_1U_LEN) - 1) << GLB_MIPIPLL_ICP_1U_POS) +#define GLB_MIPIPLL_ICP_1U_UMSK (~(((1U << GLB_MIPIPLL_ICP_1U_LEN) - 1) << GLB_MIPIPLL_ICP_1U_POS)) +#define GLB_MIPIPLL_INT_FRAC_SW GLB_MIPIPLL_INT_FRAC_SW +#define GLB_MIPIPLL_INT_FRAC_SW_POS (8U) +#define GLB_MIPIPLL_INT_FRAC_SW_LEN (1U) +#define GLB_MIPIPLL_INT_FRAC_SW_MSK (((1U << GLB_MIPIPLL_INT_FRAC_SW_LEN) - 1) << GLB_MIPIPLL_INT_FRAC_SW_POS) +#define GLB_MIPIPLL_INT_FRAC_SW_UMSK (~(((1U << GLB_MIPIPLL_INT_FRAC_SW_LEN) - 1) << GLB_MIPIPLL_INT_FRAC_SW_POS)) +#define GLB_MIPIPLL_CP_STARTUP_EN GLB_MIPIPLL_CP_STARTUP_EN +#define GLB_MIPIPLL_CP_STARTUP_EN_POS (9U) +#define GLB_MIPIPLL_CP_STARTUP_EN_LEN (1U) +#define GLB_MIPIPLL_CP_STARTUP_EN_MSK (((1U << GLB_MIPIPLL_CP_STARTUP_EN_LEN) - 1) << GLB_MIPIPLL_CP_STARTUP_EN_POS) +#define GLB_MIPIPLL_CP_STARTUP_EN_UMSK (~(((1U << GLB_MIPIPLL_CP_STARTUP_EN_LEN) - 1) << GLB_MIPIPLL_CP_STARTUP_EN_POS)) +#define GLB_MIPIPLL_CP_OPAMP_EN GLB_MIPIPLL_CP_OPAMP_EN +#define GLB_MIPIPLL_CP_OPAMP_EN_POS (10U) +#define GLB_MIPIPLL_CP_OPAMP_EN_LEN (1U) +#define GLB_MIPIPLL_CP_OPAMP_EN_MSK (((1U << GLB_MIPIPLL_CP_OPAMP_EN_LEN) - 1) << GLB_MIPIPLL_CP_OPAMP_EN_POS) +#define GLB_MIPIPLL_CP_OPAMP_EN_UMSK (~(((1U << GLB_MIPIPLL_CP_OPAMP_EN_LEN) - 1) << GLB_MIPIPLL_CP_OPAMP_EN_POS)) +#define GLB_MIPIPLL_CP_OTA_EN GLB_MIPIPLL_CP_OTA_EN +#define GLB_MIPIPLL_CP_OTA_EN_POS (11U) +#define GLB_MIPIPLL_CP_OTA_EN_LEN (1U) +#define GLB_MIPIPLL_CP_OTA_EN_MSK (((1U << GLB_MIPIPLL_CP_OTA_EN_LEN) - 1) << GLB_MIPIPLL_CP_OTA_EN_POS) +#define GLB_MIPIPLL_CP_OTA_EN_UMSK (~(((1U << GLB_MIPIPLL_CP_OTA_EN_LEN) - 1) << GLB_MIPIPLL_CP_OTA_EN_POS)) +#define GLB_MIPIPLL_PFD_EN GLB_MIPIPLL_PFD_EN +#define GLB_MIPIPLL_PFD_EN_POS (12U) +#define GLB_MIPIPLL_PFD_EN_LEN (1U) +#define GLB_MIPIPLL_PFD_EN_MSK (((1U << GLB_MIPIPLL_PFD_EN_LEN) - 1) << GLB_MIPIPLL_PFD_EN_POS) +#define GLB_MIPIPLL_PFD_EN_UMSK (~(((1U << GLB_MIPIPLL_PFD_EN_LEN) - 1) << GLB_MIPIPLL_PFD_EN_POS)) + +/* 0x79C : mipi_pll_cfg3 */ +#define GLB_MIPI_PLL_CFG3_OFFSET (0x79C) +#define GLB_MIPIPLL_C4_EN GLB_MIPIPLL_C4_EN +#define GLB_MIPIPLL_C4_EN_POS (0U) +#define GLB_MIPIPLL_C4_EN_LEN (1U) +#define GLB_MIPIPLL_C4_EN_MSK (((1U << GLB_MIPIPLL_C4_EN_LEN) - 1) << GLB_MIPIPLL_C4_EN_POS) +#define GLB_MIPIPLL_C4_EN_UMSK (~(((1U << GLB_MIPIPLL_C4_EN_LEN) - 1) << GLB_MIPIPLL_C4_EN_POS)) +#define GLB_MIPIPLL_R4 GLB_MIPIPLL_R4 +#define GLB_MIPIPLL_R4_POS (4U) +#define GLB_MIPIPLL_R4_LEN (2U) +#define GLB_MIPIPLL_R4_MSK (((1U << GLB_MIPIPLL_R4_LEN) - 1) << GLB_MIPIPLL_R4_POS) +#define GLB_MIPIPLL_R4_UMSK (~(((1U << GLB_MIPIPLL_R4_LEN) - 1) << GLB_MIPIPLL_R4_POS)) +#define GLB_MIPIPLL_R4_SHORT GLB_MIPIPLL_R4_SHORT +#define GLB_MIPIPLL_R4_SHORT_POS (8U) +#define GLB_MIPIPLL_R4_SHORT_LEN (1U) +#define GLB_MIPIPLL_R4_SHORT_MSK (((1U << GLB_MIPIPLL_R4_SHORT_LEN) - 1) << GLB_MIPIPLL_R4_SHORT_POS) +#define GLB_MIPIPLL_R4_SHORT_UMSK (~(((1U << GLB_MIPIPLL_R4_SHORT_LEN) - 1) << GLB_MIPIPLL_R4_SHORT_POS)) +#define GLB_MIPIPLL_C3 GLB_MIPIPLL_C3 +#define GLB_MIPIPLL_C3_POS (12U) +#define GLB_MIPIPLL_C3_LEN (2U) +#define GLB_MIPIPLL_C3_MSK (((1U << GLB_MIPIPLL_C3_LEN) - 1) << GLB_MIPIPLL_C3_POS) +#define GLB_MIPIPLL_C3_UMSK (~(((1U << GLB_MIPIPLL_C3_LEN) - 1) << GLB_MIPIPLL_C3_POS)) +#define GLB_MIPIPLL_CZ GLB_MIPIPLL_CZ +#define GLB_MIPIPLL_CZ_POS (14U) +#define GLB_MIPIPLL_CZ_LEN (2U) +#define GLB_MIPIPLL_CZ_MSK (((1U << GLB_MIPIPLL_CZ_LEN) - 1) << GLB_MIPIPLL_CZ_POS) +#define GLB_MIPIPLL_CZ_UMSK (~(((1U << GLB_MIPIPLL_CZ_LEN) - 1) << GLB_MIPIPLL_CZ_POS)) +#define GLB_MIPIPLL_RZ GLB_MIPIPLL_RZ +#define GLB_MIPIPLL_RZ_POS (16U) +#define GLB_MIPIPLL_RZ_LEN (3U) +#define GLB_MIPIPLL_RZ_MSK (((1U << GLB_MIPIPLL_RZ_LEN) - 1) << GLB_MIPIPLL_RZ_POS) +#define GLB_MIPIPLL_RZ_UMSK (~(((1U << GLB_MIPIPLL_RZ_LEN) - 1) << GLB_MIPIPLL_RZ_POS)) +#define GLB_MIPIPLL_LF_TEST_EN GLB_MIPIPLL_LF_TEST_EN +#define GLB_MIPIPLL_LF_TEST_EN_POS (19U) +#define GLB_MIPIPLL_LF_TEST_EN_LEN (1U) +#define GLB_MIPIPLL_LF_TEST_EN_MSK (((1U << GLB_MIPIPLL_LF_TEST_EN_LEN) - 1) << GLB_MIPIPLL_LF_TEST_EN_POS) +#define GLB_MIPIPLL_LF_TEST_EN_UMSK (~(((1U << GLB_MIPIPLL_LF_TEST_EN_LEN) - 1) << GLB_MIPIPLL_LF_TEST_EN_POS)) +#define GLB_MIPIPLL_FAST_LOCK_EN GLB_MIPIPLL_FAST_LOCK_EN +#define GLB_MIPIPLL_FAST_LOCK_EN_POS (20U) +#define GLB_MIPIPLL_FAST_LOCK_EN_LEN (1U) +#define GLB_MIPIPLL_FAST_LOCK_EN_MSK (((1U << GLB_MIPIPLL_FAST_LOCK_EN_LEN) - 1) << GLB_MIPIPLL_FAST_LOCK_EN_POS) +#define GLB_MIPIPLL_FAST_LOCK_EN_UMSK (~(((1U << GLB_MIPIPLL_FAST_LOCK_EN_LEN) - 1) << GLB_MIPIPLL_FAST_LOCK_EN_POS)) + +/* 0x7A0 : mipi_pll_cfg4 */ +#define GLB_MIPI_PLL_CFG4_OFFSET (0x7A0) +#define GLB_MIPIPLL_SEL_SAMPLE_CLK GLB_MIPIPLL_SEL_SAMPLE_CLK +#define GLB_MIPIPLL_SEL_SAMPLE_CLK_POS (0U) +#define GLB_MIPIPLL_SEL_SAMPLE_CLK_LEN (2U) +#define GLB_MIPIPLL_SEL_SAMPLE_CLK_MSK (((1U << GLB_MIPIPLL_SEL_SAMPLE_CLK_LEN) - 1) << GLB_MIPIPLL_SEL_SAMPLE_CLK_POS) +#define GLB_MIPIPLL_SEL_SAMPLE_CLK_UMSK (~(((1U << GLB_MIPIPLL_SEL_SAMPLE_CLK_LEN) - 1) << GLB_MIPIPLL_SEL_SAMPLE_CLK_POS)) +#define GLB_MIPIPLL_SEL_FB_CLK GLB_MIPIPLL_SEL_FB_CLK +#define GLB_MIPIPLL_SEL_FB_CLK_POS (4U) +#define GLB_MIPIPLL_SEL_FB_CLK_LEN (2U) +#define GLB_MIPIPLL_SEL_FB_CLK_MSK (((1U << GLB_MIPIPLL_SEL_FB_CLK_LEN) - 1) << GLB_MIPIPLL_SEL_FB_CLK_POS) +#define GLB_MIPIPLL_SEL_FB_CLK_UMSK (~(((1U << GLB_MIPIPLL_SEL_FB_CLK_LEN) - 1) << GLB_MIPIPLL_SEL_FB_CLK_POS)) +#define GLB_MIPIPLL_LOCK_DET_EN GLB_MIPIPLL_LOCK_DET_EN +#define GLB_MIPIPLL_LOCK_DET_EN_POS (8U) +#define GLB_MIPIPLL_LOCK_DET_EN_LEN (1U) +#define GLB_MIPIPLL_LOCK_DET_EN_MSK (((1U << GLB_MIPIPLL_LOCK_DET_EN_LEN) - 1) << GLB_MIPIPLL_LOCK_DET_EN_POS) +#define GLB_MIPIPLL_LOCK_DET_EN_UMSK (~(((1U << GLB_MIPIPLL_LOCK_DET_EN_LEN) - 1) << GLB_MIPIPLL_LOCK_DET_EN_POS)) +#define GLB_MIPIPLL_LOCK_CLK_SEL GLB_MIPIPLL_LOCK_CLK_SEL +#define GLB_MIPIPLL_LOCK_CLK_SEL_POS (9U) +#define GLB_MIPIPLL_LOCK_CLK_SEL_LEN (2U) +#define GLB_MIPIPLL_LOCK_CLK_SEL_MSK (((1U << GLB_MIPIPLL_LOCK_CLK_SEL_LEN) - 1) << GLB_MIPIPLL_LOCK_CLK_SEL_POS) +#define GLB_MIPIPLL_LOCK_CLK_SEL_UMSK (~(((1U << GLB_MIPIPLL_LOCK_CLK_SEL_LEN) - 1) << GLB_MIPIPLL_LOCK_CLK_SEL_POS)) +#define GLB_MIPIPLL_LOCK_CLK_INV_EN GLB_MIPIPLL_LOCK_CLK_INV_EN +#define GLB_MIPIPLL_LOCK_CLK_INV_EN_POS (12U) +#define GLB_MIPIPLL_LOCK_CLK_INV_EN_LEN (1U) +#define GLB_MIPIPLL_LOCK_CLK_INV_EN_MSK (((1U << GLB_MIPIPLL_LOCK_CLK_INV_EN_LEN) - 1) << GLB_MIPIPLL_LOCK_CLK_INV_EN_POS) +#define GLB_MIPIPLL_LOCK_CLK_INV_EN_UMSK (~(((1U << GLB_MIPIPLL_LOCK_CLK_INV_EN_LEN) - 1) << GLB_MIPIPLL_LOCK_CLK_INV_EN_POS)) +#define GLB_MIPIPLL_LOCK_WIN_SEL GLB_MIPIPLL_LOCK_WIN_SEL +#define GLB_MIPIPLL_LOCK_WIN_SEL_POS (15U) +#define GLB_MIPIPLL_LOCK_WIN_SEL_LEN (2U) +#define GLB_MIPIPLL_LOCK_WIN_SEL_MSK (((1U << GLB_MIPIPLL_LOCK_WIN_SEL_LEN) - 1) << GLB_MIPIPLL_LOCK_WIN_SEL_POS) +#define GLB_MIPIPLL_LOCK_WIN_SEL_UMSK (~(((1U << GLB_MIPIPLL_LOCK_WIN_SEL_LEN) - 1) << GLB_MIPIPLL_LOCK_WIN_SEL_POS)) + +/* 0x7A4 : mipi_pll_cfg5 */ +#define GLB_MIPI_PLL_CFG5_OFFSET (0x7A4) +#define GLB_MIPIPLL_VCO_SPEED GLB_MIPIPLL_VCO_SPEED +#define GLB_MIPIPLL_VCO_SPEED_POS (0U) +#define GLB_MIPIPLL_VCO_SPEED_LEN (3U) +#define GLB_MIPIPLL_VCO_SPEED_MSK (((1U << GLB_MIPIPLL_VCO_SPEED_LEN) - 1) << GLB_MIPIPLL_VCO_SPEED_POS) +#define GLB_MIPIPLL_VCO_SPEED_UMSK (~(((1U << GLB_MIPIPLL_VCO_SPEED_LEN) - 1) << GLB_MIPIPLL_VCO_SPEED_POS)) +#define GLB_MIPIPLL_VCO_VDD_CTRL GLB_MIPIPLL_VCO_VDD_CTRL +#define GLB_MIPIPLL_VCO_VDD_CTRL_POS (3U) +#define GLB_MIPIPLL_VCO_VDD_CTRL_LEN (2U) +#define GLB_MIPIPLL_VCO_VDD_CTRL_MSK (((1U << GLB_MIPIPLL_VCO_VDD_CTRL_LEN) - 1) << GLB_MIPIPLL_VCO_VDD_CTRL_POS) +#define GLB_MIPIPLL_VCO_VDD_CTRL_UMSK (~(((1U << GLB_MIPIPLL_VCO_VDD_CTRL_LEN) - 1) << GLB_MIPIPLL_VCO_VDD_CTRL_POS)) +#define GLB_MIPIPLL_VCO_VDD_CTRL_EXTRA GLB_MIPIPLL_VCO_VDD_CTRL_EXTRA +#define GLB_MIPIPLL_VCO_VDD_CTRL_EXTRA_POS (5U) +#define GLB_MIPIPLL_VCO_VDD_CTRL_EXTRA_LEN (1U) +#define GLB_MIPIPLL_VCO_VDD_CTRL_EXTRA_MSK (((1U << GLB_MIPIPLL_VCO_VDD_CTRL_EXTRA_LEN) - 1) << GLB_MIPIPLL_VCO_VDD_CTRL_EXTRA_POS) +#define GLB_MIPIPLL_VCO_VDD_CTRL_EXTRA_UMSK (~(((1U << GLB_MIPIPLL_VCO_VDD_CTRL_EXTRA_LEN) - 1) << GLB_MIPIPLL_VCO_VDD_CTRL_EXTRA_POS)) +#define GLB_MIPIPLL_VCO_POSTDIV_SEL GLB_MIPIPLL_VCO_POSTDIV_SEL +#define GLB_MIPIPLL_VCO_POSTDIV_SEL_POS (7U) +#define GLB_MIPIPLL_VCO_POSTDIV_SEL_LEN (3U) +#define GLB_MIPIPLL_VCO_POSTDIV_SEL_MSK (((1U << GLB_MIPIPLL_VCO_POSTDIV_SEL_LEN) - 1) << GLB_MIPIPLL_VCO_POSTDIV_SEL_POS) +#define GLB_MIPIPLL_VCO_POSTDIV_SEL_UMSK (~(((1U << GLB_MIPIPLL_VCO_POSTDIV_SEL_LEN) - 1) << GLB_MIPIPLL_VCO_POSTDIV_SEL_POS)) +#define GLB_MIPIPLL_VCO_POSTDIV_CLK_EN GLB_MIPIPLL_VCO_POSTDIV_CLK_EN +#define GLB_MIPIPLL_VCO_POSTDIV_CLK_EN_POS (10U) +#define GLB_MIPIPLL_VCO_POSTDIV_CLK_EN_LEN (1U) +#define GLB_MIPIPLL_VCO_POSTDIV_CLK_EN_MSK (((1U << GLB_MIPIPLL_VCO_POSTDIV_CLK_EN_LEN) - 1) << GLB_MIPIPLL_VCO_POSTDIV_CLK_EN_POS) +#define GLB_MIPIPLL_VCO_POSTDIV_CLK_EN_UMSK (~(((1U << GLB_MIPIPLL_VCO_POSTDIV_CLK_EN_LEN) - 1) << GLB_MIPIPLL_VCO_POSTDIV_CLK_EN_POS)) + +/* 0x7A8 : mipi_pll_cfg6 */ +#define GLB_MIPI_PLL_CFG6_OFFSET (0x7A8) +#define GLB_MIPIPLL_SDMIN GLB_MIPIPLL_SDMIN +#define GLB_MIPIPLL_SDMIN_POS (0U) +#define GLB_MIPIPLL_SDMIN_LEN (19U) +#define GLB_MIPIPLL_SDMIN_MSK (((1U << GLB_MIPIPLL_SDMIN_LEN) - 1) << GLB_MIPIPLL_SDMIN_POS) +#define GLB_MIPIPLL_SDMIN_UMSK (~(((1U << GLB_MIPIPLL_SDMIN_LEN) - 1) << GLB_MIPIPLL_SDMIN_POS)) +#define GLB_MIPIPLL_SDM_BYPASS GLB_MIPIPLL_SDM_BYPASS +#define GLB_MIPIPLL_SDM_BYPASS_POS (24U) +#define GLB_MIPIPLL_SDM_BYPASS_LEN (1U) +#define GLB_MIPIPLL_SDM_BYPASS_MSK (((1U << GLB_MIPIPLL_SDM_BYPASS_LEN) - 1) << GLB_MIPIPLL_SDM_BYPASS_POS) +#define GLB_MIPIPLL_SDM_BYPASS_UMSK (~(((1U << GLB_MIPIPLL_SDM_BYPASS_LEN) - 1) << GLB_MIPIPLL_SDM_BYPASS_POS)) + +/* 0x7AC : mipi_pll_cfg7 */ +#define GLB_MIPI_PLL_CFG7_OFFSET (0x7AC) +#define GLB_MIPIPLL_SDM_ORDER_SEL GLB_MIPIPLL_SDM_ORDER_SEL +#define GLB_MIPIPLL_SDM_ORDER_SEL_POS (0U) +#define GLB_MIPIPLL_SDM_ORDER_SEL_LEN (1U) +#define GLB_MIPIPLL_SDM_ORDER_SEL_MSK (((1U << GLB_MIPIPLL_SDM_ORDER_SEL_LEN) - 1) << GLB_MIPIPLL_SDM_ORDER_SEL_POS) +#define GLB_MIPIPLL_SDM_ORDER_SEL_UMSK (~(((1U << GLB_MIPIPLL_SDM_ORDER_SEL_LEN) - 1) << GLB_MIPIPLL_SDM_ORDER_SEL_POS)) +#define GLB_MIPIPLL_SDM_DITH_SEL GLB_MIPIPLL_SDM_DITH_SEL +#define GLB_MIPIPLL_SDM_DITH_SEL_POS (1U) +#define GLB_MIPIPLL_SDM_DITH_SEL_LEN (2U) +#define GLB_MIPIPLL_SDM_DITH_SEL_MSK (((1U << GLB_MIPIPLL_SDM_DITH_SEL_LEN) - 1) << GLB_MIPIPLL_SDM_DITH_SEL_POS) +#define GLB_MIPIPLL_SDM_DITH_SEL_UMSK (~(((1U << GLB_MIPIPLL_SDM_DITH_SEL_LEN) - 1) << GLB_MIPIPLL_SDM_DITH_SEL_POS)) + +/* 0x7B0 : mipi_pll_cfg8 */ +#define GLB_MIPI_PLL_CFG8_OFFSET (0x7B0) +#define GLB_MIPIPLL_DC_TP_OUT_EN GLB_MIPIPLL_DC_TP_OUT_EN +#define GLB_MIPIPLL_DC_TP_OUT_EN_POS (0U) +#define GLB_MIPIPLL_DC_TP_OUT_EN_LEN (1U) +#define GLB_MIPIPLL_DC_TP_OUT_EN_MSK (((1U << GLB_MIPIPLL_DC_TP_OUT_EN_LEN) - 1) << GLB_MIPIPLL_DC_TP_OUT_EN_POS) +#define GLB_MIPIPLL_DC_TP_OUT_EN_UMSK (~(((1U << GLB_MIPIPLL_DC_TP_OUT_EN_LEN) - 1) << GLB_MIPIPLL_DC_TP_OUT_EN_POS)) +#define GLB_MIPIPLL_TEN GLB_MIPIPLL_TEN +#define GLB_MIPIPLL_TEN_POS (1U) +#define GLB_MIPIPLL_TEN_LEN (1U) +#define GLB_MIPIPLL_TEN_MSK (((1U << GLB_MIPIPLL_TEN_LEN) - 1) << GLB_MIPIPLL_TEN_POS) +#define GLB_MIPIPLL_TEN_UMSK (~(((1U << GLB_MIPIPLL_TEN_LEN) - 1) << GLB_MIPIPLL_TEN_POS)) +#define GLB_MIPIPLL_TEN_SFREG GLB_MIPIPLL_TEN_SFREG +#define GLB_MIPIPLL_TEN_SFREG_POS (2U) +#define GLB_MIPIPLL_TEN_SFREG_LEN (1U) +#define GLB_MIPIPLL_TEN_SFREG_MSK (((1U << GLB_MIPIPLL_TEN_SFREG_LEN) - 1) << GLB_MIPIPLL_TEN_SFREG_POS) +#define GLB_MIPIPLL_TEN_SFREG_UMSK (~(((1U << GLB_MIPIPLL_TEN_SFREG_LEN) - 1) << GLB_MIPIPLL_TEN_SFREG_POS)) +#define GLB_MIPIPLL_DTEN_CKIN GLB_MIPIPLL_DTEN_CKIN +#define GLB_MIPIPLL_DTEN_CKIN_POS (4U) +#define GLB_MIPIPLL_DTEN_CKIN_LEN (1U) +#define GLB_MIPIPLL_DTEN_CKIN_MSK (((1U << GLB_MIPIPLL_DTEN_CKIN_LEN) - 1) << GLB_MIPIPLL_DTEN_CKIN_POS) +#define GLB_MIPIPLL_DTEN_CKIN_UMSK (~(((1U << GLB_MIPIPLL_DTEN_CKIN_LEN) - 1) << GLB_MIPIPLL_DTEN_CKIN_POS)) +#define GLB_MIPIPLL_DTEN_FREF GLB_MIPIPLL_DTEN_FREF +#define GLB_MIPIPLL_DTEN_FREF_POS (5U) +#define GLB_MIPIPLL_DTEN_FREF_LEN (1U) +#define GLB_MIPIPLL_DTEN_FREF_MSK (((1U << GLB_MIPIPLL_DTEN_FREF_LEN) - 1) << GLB_MIPIPLL_DTEN_FREF_POS) +#define GLB_MIPIPLL_DTEN_FREF_UMSK (~(((1U << GLB_MIPIPLL_DTEN_FREF_LEN) - 1) << GLB_MIPIPLL_DTEN_FREF_POS)) +#define GLB_MIPIPLL_DTEN_FSDM GLB_MIPIPLL_DTEN_FSDM +#define GLB_MIPIPLL_DTEN_FSDM_POS (6U) +#define GLB_MIPIPLL_DTEN_FSDM_LEN (1U) +#define GLB_MIPIPLL_DTEN_FSDM_MSK (((1U << GLB_MIPIPLL_DTEN_FSDM_LEN) - 1) << GLB_MIPIPLL_DTEN_FSDM_POS) +#define GLB_MIPIPLL_DTEN_FSDM_UMSK (~(((1U << GLB_MIPIPLL_DTEN_FSDM_LEN) - 1) << GLB_MIPIPLL_DTEN_FSDM_POS)) +#define GLB_MIPIPLL_DTEN_PUPLL GLB_MIPIPLL_DTEN_PUPLL +#define GLB_MIPIPLL_DTEN_PUPLL_POS (7U) +#define GLB_MIPIPLL_DTEN_PUPLL_LEN (1U) +#define GLB_MIPIPLL_DTEN_PUPLL_MSK (((1U << GLB_MIPIPLL_DTEN_PUPLL_LEN) - 1) << GLB_MIPIPLL_DTEN_PUPLL_POS) +#define GLB_MIPIPLL_DTEN_PUPLL_UMSK (~(((1U << GLB_MIPIPLL_DTEN_PUPLL_LEN) - 1) << GLB_MIPIPLL_DTEN_PUPLL_POS)) +#define GLB_MIPIPLL_DTEN_PLL_LOCKED GLB_MIPIPLL_DTEN_PLL_LOCKED +#define GLB_MIPIPLL_DTEN_PLL_LOCKED_POS (8U) +#define GLB_MIPIPLL_DTEN_PLL_LOCKED_LEN (1U) +#define GLB_MIPIPLL_DTEN_PLL_LOCKED_MSK (((1U << GLB_MIPIPLL_DTEN_PLL_LOCKED_LEN) - 1) << GLB_MIPIPLL_DTEN_PLL_LOCKED_POS) +#define GLB_MIPIPLL_DTEN_PLL_LOCKED_UMSK (~(((1U << GLB_MIPIPLL_DTEN_PLL_LOCKED_LEN) - 1) << GLB_MIPIPLL_DTEN_PLL_LOCKED_POS)) +#define GLB_MIPIPLL_DTEST_PULL_DOWN GLB_MIPIPLL_DTEST_PULL_DOWN +#define GLB_MIPIPLL_DTEST_PULL_DOWN_POS (10U) +#define GLB_MIPIPLL_DTEST_PULL_DOWN_LEN (1U) +#define GLB_MIPIPLL_DTEST_PULL_DOWN_MSK (((1U << GLB_MIPIPLL_DTEST_PULL_DOWN_LEN) - 1) << GLB_MIPIPLL_DTEST_PULL_DOWN_POS) +#define GLB_MIPIPLL_DTEST_PULL_DOWN_UMSK (~(((1U << GLB_MIPIPLL_DTEST_PULL_DOWN_LEN) - 1) << GLB_MIPIPLL_DTEST_PULL_DOWN_POS)) + +/* 0x7B4 : mipi_pll_cfg9 */ +#define GLB_MIPI_PLL_CFG9_OFFSET (0x7B4) +#define GLB_MIPIPLL_SSC_EN GLB_MIPIPLL_SSC_EN +#define GLB_MIPIPLL_SSC_EN_POS (0U) +#define GLB_MIPIPLL_SSC_EN_LEN (1U) +#define GLB_MIPIPLL_SSC_EN_MSK (((1U << GLB_MIPIPLL_SSC_EN_LEN) - 1) << GLB_MIPIPLL_SSC_EN_POS) +#define GLB_MIPIPLL_SSC_EN_UMSK (~(((1U << GLB_MIPIPLL_SSC_EN_LEN) - 1) << GLB_MIPIPLL_SSC_EN_POS)) +#define GLB_MIPIPLL_SSC_CNT GLB_MIPIPLL_SSC_CNT +#define GLB_MIPIPLL_SSC_CNT_POS (4U) +#define GLB_MIPIPLL_SSC_CNT_LEN (8U) +#define GLB_MIPIPLL_SSC_CNT_MSK (((1U << GLB_MIPIPLL_SSC_CNT_LEN) - 1) << GLB_MIPIPLL_SSC_CNT_POS) +#define GLB_MIPIPLL_SSC_CNT_UMSK (~(((1U << GLB_MIPIPLL_SSC_CNT_LEN) - 1) << GLB_MIPIPLL_SSC_CNT_POS)) +#define GLB_MIPIPLL_SSC_GAIN GLB_MIPIPLL_SSC_GAIN +#define GLB_MIPIPLL_SSC_GAIN_POS (12U) +#define GLB_MIPIPLL_SSC_GAIN_LEN (3U) +#define GLB_MIPIPLL_SSC_GAIN_MSK (((1U << GLB_MIPIPLL_SSC_GAIN_LEN) - 1) << GLB_MIPIPLL_SSC_GAIN_POS) +#define GLB_MIPIPLL_SSC_GAIN_UMSK (~(((1U << GLB_MIPIPLL_SSC_GAIN_LEN) - 1) << GLB_MIPIPLL_SSC_GAIN_POS)) +#define GLB_MIPIPLL_SSC_START_GATE_EN GLB_MIPIPLL_SSC_START_GATE_EN +#define GLB_MIPIPLL_SSC_START_GATE_EN_POS (16U) +#define GLB_MIPIPLL_SSC_START_GATE_EN_LEN (1U) +#define GLB_MIPIPLL_SSC_START_GATE_EN_MSK (((1U << GLB_MIPIPLL_SSC_START_GATE_EN_LEN) - 1) << GLB_MIPIPLL_SSC_START_GATE_EN_POS) +#define GLB_MIPIPLL_SSC_START_GATE_EN_UMSK (~(((1U << GLB_MIPIPLL_SSC_START_GATE_EN_LEN) - 1) << GLB_MIPIPLL_SSC_START_GATE_EN_POS)) + +/* 0x7D0 : uhs_pll_cfg0 */ +#define GLB_UHS_PLL_CFG0_OFFSET (0x7D0) +#define GLB_UHSPLL_SDM_RSTB GLB_UHSPLL_SDM_RSTB +#define GLB_UHSPLL_SDM_RSTB_POS (0U) +#define GLB_UHSPLL_SDM_RSTB_LEN (1U) +#define GLB_UHSPLL_SDM_RSTB_MSK (((1U << GLB_UHSPLL_SDM_RSTB_LEN) - 1) << GLB_UHSPLL_SDM_RSTB_POS) +#define GLB_UHSPLL_SDM_RSTB_UMSK (~(((1U << GLB_UHSPLL_SDM_RSTB_LEN) - 1) << GLB_UHSPLL_SDM_RSTB_POS)) +#define GLB_UHSPLL_FBDV_RSTB GLB_UHSPLL_FBDV_RSTB +#define GLB_UHSPLL_FBDV_RSTB_POS (2U) +#define GLB_UHSPLL_FBDV_RSTB_LEN (1U) +#define GLB_UHSPLL_FBDV_RSTB_MSK (((1U << GLB_UHSPLL_FBDV_RSTB_LEN) - 1) << GLB_UHSPLL_FBDV_RSTB_POS) +#define GLB_UHSPLL_FBDV_RSTB_UMSK (~(((1U << GLB_UHSPLL_FBDV_RSTB_LEN) - 1) << GLB_UHSPLL_FBDV_RSTB_POS)) +#define GLB_PU_UHSPLL_FBDV GLB_PU_UHSPLL_FBDV +#define GLB_PU_UHSPLL_FBDV_POS (5U) +#define GLB_PU_UHSPLL_FBDV_LEN (1U) +#define GLB_PU_UHSPLL_FBDV_MSK (((1U << GLB_PU_UHSPLL_FBDV_LEN) - 1) << GLB_PU_UHSPLL_FBDV_POS) +#define GLB_PU_UHSPLL_FBDV_UMSK (~(((1U << GLB_PU_UHSPLL_FBDV_LEN) - 1) << GLB_PU_UHSPLL_FBDV_POS)) +#define GLB_PU_UHSPLL_CP GLB_PU_UHSPLL_CP +#define GLB_PU_UHSPLL_CP_POS (8U) +#define GLB_PU_UHSPLL_CP_LEN (1U) +#define GLB_PU_UHSPLL_CP_MSK (((1U << GLB_PU_UHSPLL_CP_LEN) - 1) << GLB_PU_UHSPLL_CP_POS) +#define GLB_PU_UHSPLL_CP_UMSK (~(((1U << GLB_PU_UHSPLL_CP_LEN) - 1) << GLB_PU_UHSPLL_CP_POS)) +#define GLB_PU_UHSPLL_SFREG GLB_PU_UHSPLL_SFREG +#define GLB_PU_UHSPLL_SFREG_POS (9U) +#define GLB_PU_UHSPLL_SFREG_LEN (1U) +#define GLB_PU_UHSPLL_SFREG_MSK (((1U << GLB_PU_UHSPLL_SFREG_LEN) - 1) << GLB_PU_UHSPLL_SFREG_POS) +#define GLB_PU_UHSPLL_SFREG_UMSK (~(((1U << GLB_PU_UHSPLL_SFREG_LEN) - 1) << GLB_PU_UHSPLL_SFREG_POS)) +#define GLB_PU_UHSPLL GLB_PU_UHSPLL +#define GLB_PU_UHSPLL_POS (10U) +#define GLB_PU_UHSPLL_LEN (1U) +#define GLB_PU_UHSPLL_MSK (((1U << GLB_PU_UHSPLL_LEN) - 1) << GLB_PU_UHSPLL_POS) +#define GLB_PU_UHSPLL_UMSK (~(((1U << GLB_PU_UHSPLL_LEN) - 1) << GLB_PU_UHSPLL_POS)) + +/* 0x7D4 : uhs_pll_cfg1 */ +#define GLB_UHS_PLL_CFG1_OFFSET (0x7D4) +#define GLB_UHSPLL_EVEN_DIV_RATIO GLB_UHSPLL_EVEN_DIV_RATIO +#define GLB_UHSPLL_EVEN_DIV_RATIO_POS (0U) +#define GLB_UHSPLL_EVEN_DIV_RATIO_LEN (7U) +#define GLB_UHSPLL_EVEN_DIV_RATIO_MSK (((1U << GLB_UHSPLL_EVEN_DIV_RATIO_LEN) - 1) << GLB_UHSPLL_EVEN_DIV_RATIO_POS) +#define GLB_UHSPLL_EVEN_DIV_RATIO_UMSK (~(((1U << GLB_UHSPLL_EVEN_DIV_RATIO_LEN) - 1) << GLB_UHSPLL_EVEN_DIV_RATIO_POS)) +#define GLB_UHSPLL_EVEN_DIV_EN GLB_UHSPLL_EVEN_DIV_EN +#define GLB_UHSPLL_EVEN_DIV_EN_POS (7U) +#define GLB_UHSPLL_EVEN_DIV_EN_LEN (1U) +#define GLB_UHSPLL_EVEN_DIV_EN_MSK (((1U << GLB_UHSPLL_EVEN_DIV_EN_LEN) - 1) << GLB_UHSPLL_EVEN_DIV_EN_POS) +#define GLB_UHSPLL_EVEN_DIV_EN_UMSK (~(((1U << GLB_UHSPLL_EVEN_DIV_EN_LEN) - 1) << GLB_UHSPLL_EVEN_DIV_EN_POS)) +#define GLB_UHSPLL_REFDIV_RATIO GLB_UHSPLL_REFDIV_RATIO +#define GLB_UHSPLL_REFDIV_RATIO_POS (8U) +#define GLB_UHSPLL_REFDIV_RATIO_LEN (4U) +#define GLB_UHSPLL_REFDIV_RATIO_MSK (((1U << GLB_UHSPLL_REFDIV_RATIO_LEN) - 1) << GLB_UHSPLL_REFDIV_RATIO_POS) +#define GLB_UHSPLL_REFDIV_RATIO_UMSK (~(((1U << GLB_UHSPLL_REFDIV_RATIO_LEN) - 1) << GLB_UHSPLL_REFDIV_RATIO_POS)) +#define GLB_UHSPLL_REFCLK_SEL GLB_UHSPLL_REFCLK_SEL +#define GLB_UHSPLL_REFCLK_SEL_POS (16U) +#define GLB_UHSPLL_REFCLK_SEL_LEN (2U) +#define GLB_UHSPLL_REFCLK_SEL_MSK (((1U << GLB_UHSPLL_REFCLK_SEL_LEN) - 1) << GLB_UHSPLL_REFCLK_SEL_POS) +#define GLB_UHSPLL_REFCLK_SEL_UMSK (~(((1U << GLB_UHSPLL_REFCLK_SEL_LEN) - 1) << GLB_UHSPLL_REFCLK_SEL_POS)) +#define GLB_UHSPLL_VG11_SEL GLB_UHSPLL_VG11_SEL +#define GLB_UHSPLL_VG11_SEL_POS (20U) +#define GLB_UHSPLL_VG11_SEL_LEN (2U) +#define GLB_UHSPLL_VG11_SEL_MSK (((1U << GLB_UHSPLL_VG11_SEL_LEN) - 1) << GLB_UHSPLL_VG11_SEL_POS) +#define GLB_UHSPLL_VG11_SEL_UMSK (~(((1U << GLB_UHSPLL_VG11_SEL_LEN) - 1) << GLB_UHSPLL_VG11_SEL_POS)) +#define GLB_UHSPLL_VG13_SEL GLB_UHSPLL_VG13_SEL +#define GLB_UHSPLL_VG13_SEL_POS (24U) +#define GLB_UHSPLL_VG13_SEL_LEN (2U) +#define GLB_UHSPLL_VG13_SEL_MSK (((1U << GLB_UHSPLL_VG13_SEL_LEN) - 1) << GLB_UHSPLL_VG13_SEL_POS) +#define GLB_UHSPLL_VG13_SEL_UMSK (~(((1U << GLB_UHSPLL_VG13_SEL_LEN) - 1) << GLB_UHSPLL_VG13_SEL_POS)) + +/* 0x7D8 : uhs_pll_cfg2 */ +#define GLB_UHS_PLL_CFG2_OFFSET (0x7D8) +#define GLB_UHSPLL_SEL_CP_BIAS GLB_UHSPLL_SEL_CP_BIAS +#define GLB_UHSPLL_SEL_CP_BIAS_POS (0U) +#define GLB_UHSPLL_SEL_CP_BIAS_LEN (1U) +#define GLB_UHSPLL_SEL_CP_BIAS_MSK (((1U << GLB_UHSPLL_SEL_CP_BIAS_LEN) - 1) << GLB_UHSPLL_SEL_CP_BIAS_POS) +#define GLB_UHSPLL_SEL_CP_BIAS_UMSK (~(((1U << GLB_UHSPLL_SEL_CP_BIAS_LEN) - 1) << GLB_UHSPLL_SEL_CP_BIAS_POS)) +#define GLB_UHSPLL_ICP_5U GLB_UHSPLL_ICP_5U +#define GLB_UHSPLL_ICP_5U_POS (4U) +#define GLB_UHSPLL_ICP_5U_LEN (2U) +#define GLB_UHSPLL_ICP_5U_MSK (((1U << GLB_UHSPLL_ICP_5U_LEN) - 1) << GLB_UHSPLL_ICP_5U_POS) +#define GLB_UHSPLL_ICP_5U_UMSK (~(((1U << GLB_UHSPLL_ICP_5U_LEN) - 1) << GLB_UHSPLL_ICP_5U_POS)) +#define GLB_UHSPLL_ICP_1U GLB_UHSPLL_ICP_1U +#define GLB_UHSPLL_ICP_1U_POS (6U) +#define GLB_UHSPLL_ICP_1U_LEN (2U) +#define GLB_UHSPLL_ICP_1U_MSK (((1U << GLB_UHSPLL_ICP_1U_LEN) - 1) << GLB_UHSPLL_ICP_1U_POS) +#define GLB_UHSPLL_ICP_1U_UMSK (~(((1U << GLB_UHSPLL_ICP_1U_LEN) - 1) << GLB_UHSPLL_ICP_1U_POS)) +#define GLB_UHSPLL_INT_FRAC_SW GLB_UHSPLL_INT_FRAC_SW +#define GLB_UHSPLL_INT_FRAC_SW_POS (8U) +#define GLB_UHSPLL_INT_FRAC_SW_LEN (1U) +#define GLB_UHSPLL_INT_FRAC_SW_MSK (((1U << GLB_UHSPLL_INT_FRAC_SW_LEN) - 1) << GLB_UHSPLL_INT_FRAC_SW_POS) +#define GLB_UHSPLL_INT_FRAC_SW_UMSK (~(((1U << GLB_UHSPLL_INT_FRAC_SW_LEN) - 1) << GLB_UHSPLL_INT_FRAC_SW_POS)) +#define GLB_UHSPLL_CP_STARTUP_EN GLB_UHSPLL_CP_STARTUP_EN +#define GLB_UHSPLL_CP_STARTUP_EN_POS (9U) +#define GLB_UHSPLL_CP_STARTUP_EN_LEN (1U) +#define GLB_UHSPLL_CP_STARTUP_EN_MSK (((1U << GLB_UHSPLL_CP_STARTUP_EN_LEN) - 1) << GLB_UHSPLL_CP_STARTUP_EN_POS) +#define GLB_UHSPLL_CP_STARTUP_EN_UMSK (~(((1U << GLB_UHSPLL_CP_STARTUP_EN_LEN) - 1) << GLB_UHSPLL_CP_STARTUP_EN_POS)) +#define GLB_UHSPLL_CP_OPAMP_EN GLB_UHSPLL_CP_OPAMP_EN +#define GLB_UHSPLL_CP_OPAMP_EN_POS (10U) +#define GLB_UHSPLL_CP_OPAMP_EN_LEN (1U) +#define GLB_UHSPLL_CP_OPAMP_EN_MSK (((1U << GLB_UHSPLL_CP_OPAMP_EN_LEN) - 1) << GLB_UHSPLL_CP_OPAMP_EN_POS) +#define GLB_UHSPLL_CP_OPAMP_EN_UMSK (~(((1U << GLB_UHSPLL_CP_OPAMP_EN_LEN) - 1) << GLB_UHSPLL_CP_OPAMP_EN_POS)) +#define GLB_UHSPLL_CP_OTA_EN GLB_UHSPLL_CP_OTA_EN +#define GLB_UHSPLL_CP_OTA_EN_POS (11U) +#define GLB_UHSPLL_CP_OTA_EN_LEN (1U) +#define GLB_UHSPLL_CP_OTA_EN_MSK (((1U << GLB_UHSPLL_CP_OTA_EN_LEN) - 1) << GLB_UHSPLL_CP_OTA_EN_POS) +#define GLB_UHSPLL_CP_OTA_EN_UMSK (~(((1U << GLB_UHSPLL_CP_OTA_EN_LEN) - 1) << GLB_UHSPLL_CP_OTA_EN_POS)) +#define GLB_UHSPLL_PFD_EN GLB_UHSPLL_PFD_EN +#define GLB_UHSPLL_PFD_EN_POS (12U) +#define GLB_UHSPLL_PFD_EN_LEN (1U) +#define GLB_UHSPLL_PFD_EN_MSK (((1U << GLB_UHSPLL_PFD_EN_LEN) - 1) << GLB_UHSPLL_PFD_EN_POS) +#define GLB_UHSPLL_PFD_EN_UMSK (~(((1U << GLB_UHSPLL_PFD_EN_LEN) - 1) << GLB_UHSPLL_PFD_EN_POS)) + +/* 0x7DC : uhs_pll_cfg3 */ +#define GLB_UHS_PLL_CFG3_OFFSET (0x7DC) +#define GLB_UHSPLL_C4_EN GLB_UHSPLL_C4_EN +#define GLB_UHSPLL_C4_EN_POS (0U) +#define GLB_UHSPLL_C4_EN_LEN (1U) +#define GLB_UHSPLL_C4_EN_MSK (((1U << GLB_UHSPLL_C4_EN_LEN) - 1) << GLB_UHSPLL_C4_EN_POS) +#define GLB_UHSPLL_C4_EN_UMSK (~(((1U << GLB_UHSPLL_C4_EN_LEN) - 1) << GLB_UHSPLL_C4_EN_POS)) +#define GLB_UHSPLL_R4 GLB_UHSPLL_R4 +#define GLB_UHSPLL_R4_POS (4U) +#define GLB_UHSPLL_R4_LEN (2U) +#define GLB_UHSPLL_R4_MSK (((1U << GLB_UHSPLL_R4_LEN) - 1) << GLB_UHSPLL_R4_POS) +#define GLB_UHSPLL_R4_UMSK (~(((1U << GLB_UHSPLL_R4_LEN) - 1) << GLB_UHSPLL_R4_POS)) +#define GLB_UHSPLL_R4_SHORT GLB_UHSPLL_R4_SHORT +#define GLB_UHSPLL_R4_SHORT_POS (8U) +#define GLB_UHSPLL_R4_SHORT_LEN (1U) +#define GLB_UHSPLL_R4_SHORT_MSK (((1U << GLB_UHSPLL_R4_SHORT_LEN) - 1) << GLB_UHSPLL_R4_SHORT_POS) +#define GLB_UHSPLL_R4_SHORT_UMSK (~(((1U << GLB_UHSPLL_R4_SHORT_LEN) - 1) << GLB_UHSPLL_R4_SHORT_POS)) +#define GLB_UHSPLL_C3 GLB_UHSPLL_C3 +#define GLB_UHSPLL_C3_POS (12U) +#define GLB_UHSPLL_C3_LEN (2U) +#define GLB_UHSPLL_C3_MSK (((1U << GLB_UHSPLL_C3_LEN) - 1) << GLB_UHSPLL_C3_POS) +#define GLB_UHSPLL_C3_UMSK (~(((1U << GLB_UHSPLL_C3_LEN) - 1) << GLB_UHSPLL_C3_POS)) +#define GLB_UHSPLL_CZ GLB_UHSPLL_CZ +#define GLB_UHSPLL_CZ_POS (14U) +#define GLB_UHSPLL_CZ_LEN (2U) +#define GLB_UHSPLL_CZ_MSK (((1U << GLB_UHSPLL_CZ_LEN) - 1) << GLB_UHSPLL_CZ_POS) +#define GLB_UHSPLL_CZ_UMSK (~(((1U << GLB_UHSPLL_CZ_LEN) - 1) << GLB_UHSPLL_CZ_POS)) +#define GLB_UHSPLL_RZ GLB_UHSPLL_RZ +#define GLB_UHSPLL_RZ_POS (16U) +#define GLB_UHSPLL_RZ_LEN (3U) +#define GLB_UHSPLL_RZ_MSK (((1U << GLB_UHSPLL_RZ_LEN) - 1) << GLB_UHSPLL_RZ_POS) +#define GLB_UHSPLL_RZ_UMSK (~(((1U << GLB_UHSPLL_RZ_LEN) - 1) << GLB_UHSPLL_RZ_POS)) +#define GLB_UHSPLL_LF_TEST_EN GLB_UHSPLL_LF_TEST_EN +#define GLB_UHSPLL_LF_TEST_EN_POS (19U) +#define GLB_UHSPLL_LF_TEST_EN_LEN (1U) +#define GLB_UHSPLL_LF_TEST_EN_MSK (((1U << GLB_UHSPLL_LF_TEST_EN_LEN) - 1) << GLB_UHSPLL_LF_TEST_EN_POS) +#define GLB_UHSPLL_LF_TEST_EN_UMSK (~(((1U << GLB_UHSPLL_LF_TEST_EN_LEN) - 1) << GLB_UHSPLL_LF_TEST_EN_POS)) +#define GLB_UHSPLL_FAST_LOCK_EN GLB_UHSPLL_FAST_LOCK_EN +#define GLB_UHSPLL_FAST_LOCK_EN_POS (20U) +#define GLB_UHSPLL_FAST_LOCK_EN_LEN (1U) +#define GLB_UHSPLL_FAST_LOCK_EN_MSK (((1U << GLB_UHSPLL_FAST_LOCK_EN_LEN) - 1) << GLB_UHSPLL_FAST_LOCK_EN_POS) +#define GLB_UHSPLL_FAST_LOCK_EN_UMSK (~(((1U << GLB_UHSPLL_FAST_LOCK_EN_LEN) - 1) << GLB_UHSPLL_FAST_LOCK_EN_POS)) + +/* 0x7E0 : uhs_pll_cfg4 */ +#define GLB_UHS_PLL_CFG4_OFFSET (0x7E0) +#define GLB_UHSPLL_SEL_SAMPLE_CLK GLB_UHSPLL_SEL_SAMPLE_CLK +#define GLB_UHSPLL_SEL_SAMPLE_CLK_POS (0U) +#define GLB_UHSPLL_SEL_SAMPLE_CLK_LEN (2U) +#define GLB_UHSPLL_SEL_SAMPLE_CLK_MSK (((1U << GLB_UHSPLL_SEL_SAMPLE_CLK_LEN) - 1) << GLB_UHSPLL_SEL_SAMPLE_CLK_POS) +#define GLB_UHSPLL_SEL_SAMPLE_CLK_UMSK (~(((1U << GLB_UHSPLL_SEL_SAMPLE_CLK_LEN) - 1) << GLB_UHSPLL_SEL_SAMPLE_CLK_POS)) +#define GLB_UHSPLL_SEL_FB_CLK GLB_UHSPLL_SEL_FB_CLK +#define GLB_UHSPLL_SEL_FB_CLK_POS (4U) +#define GLB_UHSPLL_SEL_FB_CLK_LEN (2U) +#define GLB_UHSPLL_SEL_FB_CLK_MSK (((1U << GLB_UHSPLL_SEL_FB_CLK_LEN) - 1) << GLB_UHSPLL_SEL_FB_CLK_POS) +#define GLB_UHSPLL_SEL_FB_CLK_UMSK (~(((1U << GLB_UHSPLL_SEL_FB_CLK_LEN) - 1) << GLB_UHSPLL_SEL_FB_CLK_POS)) +#define GLB_UHSPLL_LOCK_DET_EN GLB_UHSPLL_LOCK_DET_EN +#define GLB_UHSPLL_LOCK_DET_EN_POS (8U) +#define GLB_UHSPLL_LOCK_DET_EN_LEN (1U) +#define GLB_UHSPLL_LOCK_DET_EN_MSK (((1U << GLB_UHSPLL_LOCK_DET_EN_LEN) - 1) << GLB_UHSPLL_LOCK_DET_EN_POS) +#define GLB_UHSPLL_LOCK_DET_EN_UMSK (~(((1U << GLB_UHSPLL_LOCK_DET_EN_LEN) - 1) << GLB_UHSPLL_LOCK_DET_EN_POS)) +#define GLB_UHSPLL_LOCK_CLK_SEL GLB_UHSPLL_LOCK_CLK_SEL +#define GLB_UHSPLL_LOCK_CLK_SEL_POS (9U) +#define GLB_UHSPLL_LOCK_CLK_SEL_LEN (2U) +#define GLB_UHSPLL_LOCK_CLK_SEL_MSK (((1U << GLB_UHSPLL_LOCK_CLK_SEL_LEN) - 1) << GLB_UHSPLL_LOCK_CLK_SEL_POS) +#define GLB_UHSPLL_LOCK_CLK_SEL_UMSK (~(((1U << GLB_UHSPLL_LOCK_CLK_SEL_LEN) - 1) << GLB_UHSPLL_LOCK_CLK_SEL_POS)) +#define GLB_UHSPLL_LOCK_CLK_INV_EN GLB_UHSPLL_LOCK_CLK_INV_EN +#define GLB_UHSPLL_LOCK_CLK_INV_EN_POS (12U) +#define GLB_UHSPLL_LOCK_CLK_INV_EN_LEN (1U) +#define GLB_UHSPLL_LOCK_CLK_INV_EN_MSK (((1U << GLB_UHSPLL_LOCK_CLK_INV_EN_LEN) - 1) << GLB_UHSPLL_LOCK_CLK_INV_EN_POS) +#define GLB_UHSPLL_LOCK_CLK_INV_EN_UMSK (~(((1U << GLB_UHSPLL_LOCK_CLK_INV_EN_LEN) - 1) << GLB_UHSPLL_LOCK_CLK_INV_EN_POS)) +#define GLB_UHSPLL_LOCK_WIN_SEL GLB_UHSPLL_LOCK_WIN_SEL +#define GLB_UHSPLL_LOCK_WIN_SEL_POS (15U) +#define GLB_UHSPLL_LOCK_WIN_SEL_LEN (2U) +#define GLB_UHSPLL_LOCK_WIN_SEL_MSK (((1U << GLB_UHSPLL_LOCK_WIN_SEL_LEN) - 1) << GLB_UHSPLL_LOCK_WIN_SEL_POS) +#define GLB_UHSPLL_LOCK_WIN_SEL_UMSK (~(((1U << GLB_UHSPLL_LOCK_WIN_SEL_LEN) - 1) << GLB_UHSPLL_LOCK_WIN_SEL_POS)) + +/* 0x7E4 : uhs_pll_cfg5 */ +#define GLB_UHS_PLL_CFG5_OFFSET (0x7E4) +#define GLB_UHSPLL_VCO_SPEED GLB_UHSPLL_VCO_SPEED +#define GLB_UHSPLL_VCO_SPEED_POS (0U) +#define GLB_UHSPLL_VCO_SPEED_LEN (3U) +#define GLB_UHSPLL_VCO_SPEED_MSK (((1U << GLB_UHSPLL_VCO_SPEED_LEN) - 1) << GLB_UHSPLL_VCO_SPEED_POS) +#define GLB_UHSPLL_VCO_SPEED_UMSK (~(((1U << GLB_UHSPLL_VCO_SPEED_LEN) - 1) << GLB_UHSPLL_VCO_SPEED_POS)) +#define GLB_UHSPLL_VCO_VDD_CTRL GLB_UHSPLL_VCO_VDD_CTRL +#define GLB_UHSPLL_VCO_VDD_CTRL_POS (3U) +#define GLB_UHSPLL_VCO_VDD_CTRL_LEN (2U) +#define GLB_UHSPLL_VCO_VDD_CTRL_MSK (((1U << GLB_UHSPLL_VCO_VDD_CTRL_LEN) - 1) << GLB_UHSPLL_VCO_VDD_CTRL_POS) +#define GLB_UHSPLL_VCO_VDD_CTRL_UMSK (~(((1U << GLB_UHSPLL_VCO_VDD_CTRL_LEN) - 1) << GLB_UHSPLL_VCO_VDD_CTRL_POS)) +#define GLB_UHSPLL_VCO_VDD_CTRL_EXTRA GLB_UHSPLL_VCO_VDD_CTRL_EXTRA +#define GLB_UHSPLL_VCO_VDD_CTRL_EXTRA_POS (5U) +#define GLB_UHSPLL_VCO_VDD_CTRL_EXTRA_LEN (1U) +#define GLB_UHSPLL_VCO_VDD_CTRL_EXTRA_MSK (((1U << GLB_UHSPLL_VCO_VDD_CTRL_EXTRA_LEN) - 1) << GLB_UHSPLL_VCO_VDD_CTRL_EXTRA_POS) +#define GLB_UHSPLL_VCO_VDD_CTRL_EXTRA_UMSK (~(((1U << GLB_UHSPLL_VCO_VDD_CTRL_EXTRA_LEN) - 1) << GLB_UHSPLL_VCO_VDD_CTRL_EXTRA_POS)) +#define GLB_UHSPLL_VCO_POSTDIV_SEL GLB_UHSPLL_VCO_POSTDIV_SEL +#define GLB_UHSPLL_VCO_POSTDIV_SEL_POS (7U) +#define GLB_UHSPLL_VCO_POSTDIV_SEL_LEN (3U) +#define GLB_UHSPLL_VCO_POSTDIV_SEL_MSK (((1U << GLB_UHSPLL_VCO_POSTDIV_SEL_LEN) - 1) << GLB_UHSPLL_VCO_POSTDIV_SEL_POS) +#define GLB_UHSPLL_VCO_POSTDIV_SEL_UMSK (~(((1U << GLB_UHSPLL_VCO_POSTDIV_SEL_LEN) - 1) << GLB_UHSPLL_VCO_POSTDIV_SEL_POS)) +#define GLB_UHSPLL_VCO_POSTDIV_CLK_EN GLB_UHSPLL_VCO_POSTDIV_CLK_EN +#define GLB_UHSPLL_VCO_POSTDIV_CLK_EN_POS (10U) +#define GLB_UHSPLL_VCO_POSTDIV_CLK_EN_LEN (1U) +#define GLB_UHSPLL_VCO_POSTDIV_CLK_EN_MSK (((1U << GLB_UHSPLL_VCO_POSTDIV_CLK_EN_LEN) - 1) << GLB_UHSPLL_VCO_POSTDIV_CLK_EN_POS) +#define GLB_UHSPLL_VCO_POSTDIV_CLK_EN_UMSK (~(((1U << GLB_UHSPLL_VCO_POSTDIV_CLK_EN_LEN) - 1) << GLB_UHSPLL_VCO_POSTDIV_CLK_EN_POS)) + +/* 0x7E8 : uhs_pll_cfg6 */ +#define GLB_UHS_PLL_CFG6_OFFSET (0x7E8) +#define GLB_UHSPLL_SDMIN GLB_UHSPLL_SDMIN +#define GLB_UHSPLL_SDMIN_POS (0U) +#define GLB_UHSPLL_SDMIN_LEN (19U) +#define GLB_UHSPLL_SDMIN_MSK (((1U << GLB_UHSPLL_SDMIN_LEN) - 1) << GLB_UHSPLL_SDMIN_POS) +#define GLB_UHSPLL_SDMIN_UMSK (~(((1U << GLB_UHSPLL_SDMIN_LEN) - 1) << GLB_UHSPLL_SDMIN_POS)) +#define GLB_UHSPLL_SDM_BYPASS GLB_UHSPLL_SDM_BYPASS +#define GLB_UHSPLL_SDM_BYPASS_POS (24U) +#define GLB_UHSPLL_SDM_BYPASS_LEN (1U) +#define GLB_UHSPLL_SDM_BYPASS_MSK (((1U << GLB_UHSPLL_SDM_BYPASS_LEN) - 1) << GLB_UHSPLL_SDM_BYPASS_POS) +#define GLB_UHSPLL_SDM_BYPASS_UMSK (~(((1U << GLB_UHSPLL_SDM_BYPASS_LEN) - 1) << GLB_UHSPLL_SDM_BYPASS_POS)) + +/* 0x7EC : uhs_pll_cfg7 */ +#define GLB_UHS_PLL_CFG7_OFFSET (0x7EC) +#define GLB_UHSPLL_SDM_ORDER_SEL GLB_UHSPLL_SDM_ORDER_SEL +#define GLB_UHSPLL_SDM_ORDER_SEL_POS (0U) +#define GLB_UHSPLL_SDM_ORDER_SEL_LEN (1U) +#define GLB_UHSPLL_SDM_ORDER_SEL_MSK (((1U << GLB_UHSPLL_SDM_ORDER_SEL_LEN) - 1) << GLB_UHSPLL_SDM_ORDER_SEL_POS) +#define GLB_UHSPLL_SDM_ORDER_SEL_UMSK (~(((1U << GLB_UHSPLL_SDM_ORDER_SEL_LEN) - 1) << GLB_UHSPLL_SDM_ORDER_SEL_POS)) +#define GLB_UHSPLL_SDM_DITH_SEL GLB_UHSPLL_SDM_DITH_SEL +#define GLB_UHSPLL_SDM_DITH_SEL_POS (1U) +#define GLB_UHSPLL_SDM_DITH_SEL_LEN (2U) +#define GLB_UHSPLL_SDM_DITH_SEL_MSK (((1U << GLB_UHSPLL_SDM_DITH_SEL_LEN) - 1) << GLB_UHSPLL_SDM_DITH_SEL_POS) +#define GLB_UHSPLL_SDM_DITH_SEL_UMSK (~(((1U << GLB_UHSPLL_SDM_DITH_SEL_LEN) - 1) << GLB_UHSPLL_SDM_DITH_SEL_POS)) + +/* 0x7F0 : uhs_pll_cfg8 */ +#define GLB_UHS_PLL_CFG8_OFFSET (0x7F0) +#define GLB_UHSPLL_DC_TP_OUT_EN GLB_UHSPLL_DC_TP_OUT_EN +#define GLB_UHSPLL_DC_TP_OUT_EN_POS (0U) +#define GLB_UHSPLL_DC_TP_OUT_EN_LEN (1U) +#define GLB_UHSPLL_DC_TP_OUT_EN_MSK (((1U << GLB_UHSPLL_DC_TP_OUT_EN_LEN) - 1) << GLB_UHSPLL_DC_TP_OUT_EN_POS) +#define GLB_UHSPLL_DC_TP_OUT_EN_UMSK (~(((1U << GLB_UHSPLL_DC_TP_OUT_EN_LEN) - 1) << GLB_UHSPLL_DC_TP_OUT_EN_POS)) +#define GLB_UHSPLL_TEN GLB_UHSPLL_TEN +#define GLB_UHSPLL_TEN_POS (1U) +#define GLB_UHSPLL_TEN_LEN (1U) +#define GLB_UHSPLL_TEN_MSK (((1U << GLB_UHSPLL_TEN_LEN) - 1) << GLB_UHSPLL_TEN_POS) +#define GLB_UHSPLL_TEN_UMSK (~(((1U << GLB_UHSPLL_TEN_LEN) - 1) << GLB_UHSPLL_TEN_POS)) +#define GLB_UHSPLL_TEN_SFREG GLB_UHSPLL_TEN_SFREG +#define GLB_UHSPLL_TEN_SFREG_POS (2U) +#define GLB_UHSPLL_TEN_SFREG_LEN (1U) +#define GLB_UHSPLL_TEN_SFREG_MSK (((1U << GLB_UHSPLL_TEN_SFREG_LEN) - 1) << GLB_UHSPLL_TEN_SFREG_POS) +#define GLB_UHSPLL_TEN_SFREG_UMSK (~(((1U << GLB_UHSPLL_TEN_SFREG_LEN) - 1) << GLB_UHSPLL_TEN_SFREG_POS)) +#define GLB_UHSPLL_DTEN_CKIN GLB_UHSPLL_DTEN_CKIN +#define GLB_UHSPLL_DTEN_CKIN_POS (4U) +#define GLB_UHSPLL_DTEN_CKIN_LEN (1U) +#define GLB_UHSPLL_DTEN_CKIN_MSK (((1U << GLB_UHSPLL_DTEN_CKIN_LEN) - 1) << GLB_UHSPLL_DTEN_CKIN_POS) +#define GLB_UHSPLL_DTEN_CKIN_UMSK (~(((1U << GLB_UHSPLL_DTEN_CKIN_LEN) - 1) << GLB_UHSPLL_DTEN_CKIN_POS)) +#define GLB_UHSPLL_DTEN_FREF GLB_UHSPLL_DTEN_FREF +#define GLB_UHSPLL_DTEN_FREF_POS (5U) +#define GLB_UHSPLL_DTEN_FREF_LEN (1U) +#define GLB_UHSPLL_DTEN_FREF_MSK (((1U << GLB_UHSPLL_DTEN_FREF_LEN) - 1) << GLB_UHSPLL_DTEN_FREF_POS) +#define GLB_UHSPLL_DTEN_FREF_UMSK (~(((1U << GLB_UHSPLL_DTEN_FREF_LEN) - 1) << GLB_UHSPLL_DTEN_FREF_POS)) +#define GLB_UHSPLL_DTEN_FSDM GLB_UHSPLL_DTEN_FSDM +#define GLB_UHSPLL_DTEN_FSDM_POS (6U) +#define GLB_UHSPLL_DTEN_FSDM_LEN (1U) +#define GLB_UHSPLL_DTEN_FSDM_MSK (((1U << GLB_UHSPLL_DTEN_FSDM_LEN) - 1) << GLB_UHSPLL_DTEN_FSDM_POS) +#define GLB_UHSPLL_DTEN_FSDM_UMSK (~(((1U << GLB_UHSPLL_DTEN_FSDM_LEN) - 1) << GLB_UHSPLL_DTEN_FSDM_POS)) +#define GLB_UHSPLL_DTEN_PUPLL GLB_UHSPLL_DTEN_PUPLL +#define GLB_UHSPLL_DTEN_PUPLL_POS (7U) +#define GLB_UHSPLL_DTEN_PUPLL_LEN (1U) +#define GLB_UHSPLL_DTEN_PUPLL_MSK (((1U << GLB_UHSPLL_DTEN_PUPLL_LEN) - 1) << GLB_UHSPLL_DTEN_PUPLL_POS) +#define GLB_UHSPLL_DTEN_PUPLL_UMSK (~(((1U << GLB_UHSPLL_DTEN_PUPLL_LEN) - 1) << GLB_UHSPLL_DTEN_PUPLL_POS)) +#define GLB_UHSPLL_DTEN_PLL_LOCKED GLB_UHSPLL_DTEN_PLL_LOCKED +#define GLB_UHSPLL_DTEN_PLL_LOCKED_POS (8U) +#define GLB_UHSPLL_DTEN_PLL_LOCKED_LEN (1U) +#define GLB_UHSPLL_DTEN_PLL_LOCKED_MSK (((1U << GLB_UHSPLL_DTEN_PLL_LOCKED_LEN) - 1) << GLB_UHSPLL_DTEN_PLL_LOCKED_POS) +#define GLB_UHSPLL_DTEN_PLL_LOCKED_UMSK (~(((1U << GLB_UHSPLL_DTEN_PLL_LOCKED_LEN) - 1) << GLB_UHSPLL_DTEN_PLL_LOCKED_POS)) +#define GLB_UHSPLL_DTEST_PULL_DOWN GLB_UHSPLL_DTEST_PULL_DOWN +#define GLB_UHSPLL_DTEST_PULL_DOWN_POS (10U) +#define GLB_UHSPLL_DTEST_PULL_DOWN_LEN (1U) +#define GLB_UHSPLL_DTEST_PULL_DOWN_MSK (((1U << GLB_UHSPLL_DTEST_PULL_DOWN_LEN) - 1) << GLB_UHSPLL_DTEST_PULL_DOWN_POS) +#define GLB_UHSPLL_DTEST_PULL_DOWN_UMSK (~(((1U << GLB_UHSPLL_DTEST_PULL_DOWN_LEN) - 1) << GLB_UHSPLL_DTEST_PULL_DOWN_POS)) + +/* 0x7F4 : uhs_pll_cfg9 */ +#define GLB_UHS_PLL_CFG9_OFFSET (0x7F4) +#define GLB_UHSPLL_SSC_EN GLB_UHSPLL_SSC_EN +#define GLB_UHSPLL_SSC_EN_POS (0U) +#define GLB_UHSPLL_SSC_EN_LEN (1U) +#define GLB_UHSPLL_SSC_EN_MSK (((1U << GLB_UHSPLL_SSC_EN_LEN) - 1) << GLB_UHSPLL_SSC_EN_POS) +#define GLB_UHSPLL_SSC_EN_UMSK (~(((1U << GLB_UHSPLL_SSC_EN_LEN) - 1) << GLB_UHSPLL_SSC_EN_POS)) +#define GLB_UHSPLL_SSC_CNT GLB_UHSPLL_SSC_CNT +#define GLB_UHSPLL_SSC_CNT_POS (4U) +#define GLB_UHSPLL_SSC_CNT_LEN (8U) +#define GLB_UHSPLL_SSC_CNT_MSK (((1U << GLB_UHSPLL_SSC_CNT_LEN) - 1) << GLB_UHSPLL_SSC_CNT_POS) +#define GLB_UHSPLL_SSC_CNT_UMSK (~(((1U << GLB_UHSPLL_SSC_CNT_LEN) - 1) << GLB_UHSPLL_SSC_CNT_POS)) +#define GLB_UHSPLL_SSC_GAIN GLB_UHSPLL_SSC_GAIN +#define GLB_UHSPLL_SSC_GAIN_POS (12U) +#define GLB_UHSPLL_SSC_GAIN_LEN (3U) +#define GLB_UHSPLL_SSC_GAIN_MSK (((1U << GLB_UHSPLL_SSC_GAIN_LEN) - 1) << GLB_UHSPLL_SSC_GAIN_POS) +#define GLB_UHSPLL_SSC_GAIN_UMSK (~(((1U << GLB_UHSPLL_SSC_GAIN_LEN) - 1) << GLB_UHSPLL_SSC_GAIN_POS)) +#define GLB_UHSPLL_SSC_START_GATE_EN GLB_UHSPLL_SSC_START_GATE_EN +#define GLB_UHSPLL_SSC_START_GATE_EN_POS (16U) +#define GLB_UHSPLL_SSC_START_GATE_EN_LEN (1U) +#define GLB_UHSPLL_SSC_START_GATE_EN_MSK (((1U << GLB_UHSPLL_SSC_START_GATE_EN_LEN) - 1) << GLB_UHSPLL_SSC_START_GATE_EN_POS) +#define GLB_UHSPLL_SSC_START_GATE_EN_UMSK (~(((1U << GLB_UHSPLL_SSC_START_GATE_EN_LEN) - 1) << GLB_UHSPLL_SSC_START_GATE_EN_POS)) + +/* 0x810 : wifi_pll_cfg0 */ +#define GLB_WIFI_PLL_CFG0_OFFSET (0x810) +#define GLB_WIFIPLL_SDM_RSTB GLB_WIFIPLL_SDM_RSTB +#define GLB_WIFIPLL_SDM_RSTB_POS (0U) +#define GLB_WIFIPLL_SDM_RSTB_LEN (1U) +#define GLB_WIFIPLL_SDM_RSTB_MSK (((1U << GLB_WIFIPLL_SDM_RSTB_LEN) - 1) << GLB_WIFIPLL_SDM_RSTB_POS) +#define GLB_WIFIPLL_SDM_RSTB_UMSK (~(((1U << GLB_WIFIPLL_SDM_RSTB_LEN) - 1) << GLB_WIFIPLL_SDM_RSTB_POS)) +#define GLB_WIFIPLL_POSTDIV_RSTB GLB_WIFIPLL_POSTDIV_RSTB +#define GLB_WIFIPLL_POSTDIV_RSTB_POS (1U) +#define GLB_WIFIPLL_POSTDIV_RSTB_LEN (1U) +#define GLB_WIFIPLL_POSTDIV_RSTB_MSK (((1U << GLB_WIFIPLL_POSTDIV_RSTB_LEN) - 1) << GLB_WIFIPLL_POSTDIV_RSTB_POS) +#define GLB_WIFIPLL_POSTDIV_RSTB_UMSK (~(((1U << GLB_WIFIPLL_POSTDIV_RSTB_LEN) - 1) << GLB_WIFIPLL_POSTDIV_RSTB_POS)) +#define GLB_WIFIPLL_FBDV_RSTB GLB_WIFIPLL_FBDV_RSTB +#define GLB_WIFIPLL_FBDV_RSTB_POS (2U) +#define GLB_WIFIPLL_FBDV_RSTB_LEN (1U) +#define GLB_WIFIPLL_FBDV_RSTB_MSK (((1U << GLB_WIFIPLL_FBDV_RSTB_LEN) - 1) << GLB_WIFIPLL_FBDV_RSTB_POS) +#define GLB_WIFIPLL_FBDV_RSTB_UMSK (~(((1U << GLB_WIFIPLL_FBDV_RSTB_LEN) - 1) << GLB_WIFIPLL_FBDV_RSTB_POS)) +#define GLB_WIFIPLL_REFDIV_RSTB GLB_WIFIPLL_REFDIV_RSTB +#define GLB_WIFIPLL_REFDIV_RSTB_POS (3U) +#define GLB_WIFIPLL_REFDIV_RSTB_LEN (1U) +#define GLB_WIFIPLL_REFDIV_RSTB_MSK (((1U << GLB_WIFIPLL_REFDIV_RSTB_LEN) - 1) << GLB_WIFIPLL_REFDIV_RSTB_POS) +#define GLB_WIFIPLL_REFDIV_RSTB_UMSK (~(((1U << GLB_WIFIPLL_REFDIV_RSTB_LEN) - 1) << GLB_WIFIPLL_REFDIV_RSTB_POS)) +#define GLB_PU_WIFIPLL_POSTDIV GLB_PU_WIFIPLL_POSTDIV +#define GLB_PU_WIFIPLL_POSTDIV_POS (4U) +#define GLB_PU_WIFIPLL_POSTDIV_LEN (1U) +#define GLB_PU_WIFIPLL_POSTDIV_MSK (((1U << GLB_PU_WIFIPLL_POSTDIV_LEN) - 1) << GLB_PU_WIFIPLL_POSTDIV_POS) +#define GLB_PU_WIFIPLL_POSTDIV_UMSK (~(((1U << GLB_PU_WIFIPLL_POSTDIV_LEN) - 1) << GLB_PU_WIFIPLL_POSTDIV_POS)) +#define GLB_PU_WIFIPLL_FBDV GLB_PU_WIFIPLL_FBDV +#define GLB_PU_WIFIPLL_FBDV_POS (5U) +#define GLB_PU_WIFIPLL_FBDV_LEN (1U) +#define GLB_PU_WIFIPLL_FBDV_MSK (((1U << GLB_PU_WIFIPLL_FBDV_LEN) - 1) << GLB_PU_WIFIPLL_FBDV_POS) +#define GLB_PU_WIFIPLL_FBDV_UMSK (~(((1U << GLB_PU_WIFIPLL_FBDV_LEN) - 1) << GLB_PU_WIFIPLL_FBDV_POS)) +#define GLB_PU_WIFIPLL_CLAMP_OP GLB_PU_WIFIPLL_CLAMP_OP +#define GLB_PU_WIFIPLL_CLAMP_OP_POS (6U) +#define GLB_PU_WIFIPLL_CLAMP_OP_LEN (1U) +#define GLB_PU_WIFIPLL_CLAMP_OP_MSK (((1U << GLB_PU_WIFIPLL_CLAMP_OP_LEN) - 1) << GLB_PU_WIFIPLL_CLAMP_OP_POS) +#define GLB_PU_WIFIPLL_CLAMP_OP_UMSK (~(((1U << GLB_PU_WIFIPLL_CLAMP_OP_LEN) - 1) << GLB_PU_WIFIPLL_CLAMP_OP_POS)) +#define GLB_PU_WIFIPLL_PFD GLB_PU_WIFIPLL_PFD +#define GLB_PU_WIFIPLL_PFD_POS (7U) +#define GLB_PU_WIFIPLL_PFD_LEN (1U) +#define GLB_PU_WIFIPLL_PFD_MSK (((1U << GLB_PU_WIFIPLL_PFD_LEN) - 1) << GLB_PU_WIFIPLL_PFD_POS) +#define GLB_PU_WIFIPLL_PFD_UMSK (~(((1U << GLB_PU_WIFIPLL_PFD_LEN) - 1) << GLB_PU_WIFIPLL_PFD_POS)) +#define GLB_PU_WIFIPLL_CP GLB_PU_WIFIPLL_CP +#define GLB_PU_WIFIPLL_CP_POS (8U) +#define GLB_PU_WIFIPLL_CP_LEN (1U) +#define GLB_PU_WIFIPLL_CP_MSK (((1U << GLB_PU_WIFIPLL_CP_LEN) - 1) << GLB_PU_WIFIPLL_CP_POS) +#define GLB_PU_WIFIPLL_CP_UMSK (~(((1U << GLB_PU_WIFIPLL_CP_LEN) - 1) << GLB_PU_WIFIPLL_CP_POS)) +#define GLB_PU_WIFIPLL_SFREG GLB_PU_WIFIPLL_SFREG +#define GLB_PU_WIFIPLL_SFREG_POS (9U) +#define GLB_PU_WIFIPLL_SFREG_LEN (1U) +#define GLB_PU_WIFIPLL_SFREG_MSK (((1U << GLB_PU_WIFIPLL_SFREG_LEN) - 1) << GLB_PU_WIFIPLL_SFREG_POS) +#define GLB_PU_WIFIPLL_SFREG_UMSK (~(((1U << GLB_PU_WIFIPLL_SFREG_LEN) - 1) << GLB_PU_WIFIPLL_SFREG_POS)) +#define GLB_PU_WIFIPLL GLB_PU_WIFIPLL +#define GLB_PU_WIFIPLL_POS (10U) +#define GLB_PU_WIFIPLL_LEN (1U) +#define GLB_PU_WIFIPLL_MSK (((1U << GLB_PU_WIFIPLL_LEN) - 1) << GLB_PU_WIFIPLL_POS) +#define GLB_PU_WIFIPLL_UMSK (~(((1U << GLB_PU_WIFIPLL_LEN) - 1) << GLB_PU_WIFIPLL_POS)) +#define GLB_PU_WIFIPLL_CLKTREE GLB_PU_WIFIPLL_CLKTREE +#define GLB_PU_WIFIPLL_CLKTREE_POS (11U) +#define GLB_PU_WIFIPLL_CLKTREE_LEN (1U) +#define GLB_PU_WIFIPLL_CLKTREE_MSK (((1U << GLB_PU_WIFIPLL_CLKTREE_LEN) - 1) << GLB_PU_WIFIPLL_CLKTREE_POS) +#define GLB_PU_WIFIPLL_CLKTREE_UMSK (~(((1U << GLB_PU_WIFIPLL_CLKTREE_LEN) - 1) << GLB_PU_WIFIPLL_CLKTREE_POS)) + +/* 0x814 : wifi_pll_cfg1 */ +#define GLB_WIFI_PLL_CFG1_OFFSET (0x814) +#define GLB_WIFIPLL_POSTDIV GLB_WIFIPLL_POSTDIV +#define GLB_WIFIPLL_POSTDIV_POS (0U) +#define GLB_WIFIPLL_POSTDIV_LEN (7U) +#define GLB_WIFIPLL_POSTDIV_MSK (((1U << GLB_WIFIPLL_POSTDIV_LEN) - 1) << GLB_WIFIPLL_POSTDIV_POS) +#define GLB_WIFIPLL_POSTDIV_UMSK (~(((1U << GLB_WIFIPLL_POSTDIV_LEN) - 1) << GLB_WIFIPLL_POSTDIV_POS)) +#define GLB_WIFIPLL_REFDIV_RATIO GLB_WIFIPLL_REFDIV_RATIO +#define GLB_WIFIPLL_REFDIV_RATIO_POS (8U) +#define GLB_WIFIPLL_REFDIV_RATIO_LEN (4U) +#define GLB_WIFIPLL_REFDIV_RATIO_MSK (((1U << GLB_WIFIPLL_REFDIV_RATIO_LEN) - 1) << GLB_WIFIPLL_REFDIV_RATIO_POS) +#define GLB_WIFIPLL_REFDIV_RATIO_UMSK (~(((1U << GLB_WIFIPLL_REFDIV_RATIO_LEN) - 1) << GLB_WIFIPLL_REFDIV_RATIO_POS)) +#define GLB_WIFIPLL_REFCLK_SEL GLB_WIFIPLL_REFCLK_SEL +#define GLB_WIFIPLL_REFCLK_SEL_POS (16U) +#define GLB_WIFIPLL_REFCLK_SEL_LEN (2U) +#define GLB_WIFIPLL_REFCLK_SEL_MSK (((1U << GLB_WIFIPLL_REFCLK_SEL_LEN) - 1) << GLB_WIFIPLL_REFCLK_SEL_POS) +#define GLB_WIFIPLL_REFCLK_SEL_UMSK (~(((1U << GLB_WIFIPLL_REFCLK_SEL_LEN) - 1) << GLB_WIFIPLL_REFCLK_SEL_POS)) +#define GLB_WIFIPLL_VG11_SEL GLB_WIFIPLL_VG11_SEL +#define GLB_WIFIPLL_VG11_SEL_POS (20U) +#define GLB_WIFIPLL_VG11_SEL_LEN (2U) +#define GLB_WIFIPLL_VG11_SEL_MSK (((1U << GLB_WIFIPLL_VG11_SEL_LEN) - 1) << GLB_WIFIPLL_VG11_SEL_POS) +#define GLB_WIFIPLL_VG11_SEL_UMSK (~(((1U << GLB_WIFIPLL_VG11_SEL_LEN) - 1) << GLB_WIFIPLL_VG11_SEL_POS)) +#define GLB_WIFIPLL_VG13_SEL GLB_WIFIPLL_VG13_SEL +#define GLB_WIFIPLL_VG13_SEL_POS (24U) +#define GLB_WIFIPLL_VG13_SEL_LEN (2U) +#define GLB_WIFIPLL_VG13_SEL_MSK (((1U << GLB_WIFIPLL_VG13_SEL_LEN) - 1) << GLB_WIFIPLL_VG13_SEL_POS) +#define GLB_WIFIPLL_VG13_SEL_UMSK (~(((1U << GLB_WIFIPLL_VG13_SEL_LEN) - 1) << GLB_WIFIPLL_VG13_SEL_POS)) + +/* 0x818 : wifi_pll_cfg2 */ +#define GLB_WIFI_PLL_CFG2_OFFSET (0x818) +#define GLB_WIFIPLL_SEL_CP_BIAS GLB_WIFIPLL_SEL_CP_BIAS +#define GLB_WIFIPLL_SEL_CP_BIAS_POS (0U) +#define GLB_WIFIPLL_SEL_CP_BIAS_LEN (1U) +#define GLB_WIFIPLL_SEL_CP_BIAS_MSK (((1U << GLB_WIFIPLL_SEL_CP_BIAS_LEN) - 1) << GLB_WIFIPLL_SEL_CP_BIAS_POS) +#define GLB_WIFIPLL_SEL_CP_BIAS_UMSK (~(((1U << GLB_WIFIPLL_SEL_CP_BIAS_LEN) - 1) << GLB_WIFIPLL_SEL_CP_BIAS_POS)) +#define GLB_WIFIPLL_ICP_5U GLB_WIFIPLL_ICP_5U +#define GLB_WIFIPLL_ICP_5U_POS (4U) +#define GLB_WIFIPLL_ICP_5U_LEN (2U) +#define GLB_WIFIPLL_ICP_5U_MSK (((1U << GLB_WIFIPLL_ICP_5U_LEN) - 1) << GLB_WIFIPLL_ICP_5U_POS) +#define GLB_WIFIPLL_ICP_5U_UMSK (~(((1U << GLB_WIFIPLL_ICP_5U_LEN) - 1) << GLB_WIFIPLL_ICP_5U_POS)) +#define GLB_WIFIPLL_ICP_1U GLB_WIFIPLL_ICP_1U +#define GLB_WIFIPLL_ICP_1U_POS (6U) +#define GLB_WIFIPLL_ICP_1U_LEN (2U) +#define GLB_WIFIPLL_ICP_1U_MSK (((1U << GLB_WIFIPLL_ICP_1U_LEN) - 1) << GLB_WIFIPLL_ICP_1U_POS) +#define GLB_WIFIPLL_ICP_1U_UMSK (~(((1U << GLB_WIFIPLL_ICP_1U_LEN) - 1) << GLB_WIFIPLL_ICP_1U_POS)) +#define GLB_WIFIPLL_INT_FRAC_SW GLB_WIFIPLL_INT_FRAC_SW +#define GLB_WIFIPLL_INT_FRAC_SW_POS (8U) +#define GLB_WIFIPLL_INT_FRAC_SW_LEN (1U) +#define GLB_WIFIPLL_INT_FRAC_SW_MSK (((1U << GLB_WIFIPLL_INT_FRAC_SW_LEN) - 1) << GLB_WIFIPLL_INT_FRAC_SW_POS) +#define GLB_WIFIPLL_INT_FRAC_SW_UMSK (~(((1U << GLB_WIFIPLL_INT_FRAC_SW_LEN) - 1) << GLB_WIFIPLL_INT_FRAC_SW_POS)) +#define GLB_WIFIPLL_CP_STARTUP_EN GLB_WIFIPLL_CP_STARTUP_EN +#define GLB_WIFIPLL_CP_STARTUP_EN_POS (9U) +#define GLB_WIFIPLL_CP_STARTUP_EN_LEN (1U) +#define GLB_WIFIPLL_CP_STARTUP_EN_MSK (((1U << GLB_WIFIPLL_CP_STARTUP_EN_LEN) - 1) << GLB_WIFIPLL_CP_STARTUP_EN_POS) +#define GLB_WIFIPLL_CP_STARTUP_EN_UMSK (~(((1U << GLB_WIFIPLL_CP_STARTUP_EN_LEN) - 1) << GLB_WIFIPLL_CP_STARTUP_EN_POS)) +#define GLB_WIFIPLL_CP_OPAMP_EN GLB_WIFIPLL_CP_OPAMP_EN +#define GLB_WIFIPLL_CP_OPAMP_EN_POS (10U) +#define GLB_WIFIPLL_CP_OPAMP_EN_LEN (1U) +#define GLB_WIFIPLL_CP_OPAMP_EN_MSK (((1U << GLB_WIFIPLL_CP_OPAMP_EN_LEN) - 1) << GLB_WIFIPLL_CP_OPAMP_EN_POS) +#define GLB_WIFIPLL_CP_OPAMP_EN_UMSK (~(((1U << GLB_WIFIPLL_CP_OPAMP_EN_LEN) - 1) << GLB_WIFIPLL_CP_OPAMP_EN_POS)) + +/* 0x81C : wifi_pll_cfg3 */ +#define GLB_WIFI_PLL_CFG3_OFFSET (0x81C) +#define GLB_WIFIPLL_C4_EN GLB_WIFIPLL_C4_EN +#define GLB_WIFIPLL_C4_EN_POS (0U) +#define GLB_WIFIPLL_C4_EN_LEN (1U) +#define GLB_WIFIPLL_C4_EN_MSK (((1U << GLB_WIFIPLL_C4_EN_LEN) - 1) << GLB_WIFIPLL_C4_EN_POS) +#define GLB_WIFIPLL_C4_EN_UMSK (~(((1U << GLB_WIFIPLL_C4_EN_LEN) - 1) << GLB_WIFIPLL_C4_EN_POS)) +#define GLB_WIFIPLL_R4 GLB_WIFIPLL_R4 +#define GLB_WIFIPLL_R4_POS (4U) +#define GLB_WIFIPLL_R4_LEN (2U) +#define GLB_WIFIPLL_R4_MSK (((1U << GLB_WIFIPLL_R4_LEN) - 1) << GLB_WIFIPLL_R4_POS) +#define GLB_WIFIPLL_R4_UMSK (~(((1U << GLB_WIFIPLL_R4_LEN) - 1) << GLB_WIFIPLL_R4_POS)) +#define GLB_WIFIPLL_R4_SHORT GLB_WIFIPLL_R4_SHORT +#define GLB_WIFIPLL_R4_SHORT_POS (8U) +#define GLB_WIFIPLL_R4_SHORT_LEN (1U) +#define GLB_WIFIPLL_R4_SHORT_MSK (((1U << GLB_WIFIPLL_R4_SHORT_LEN) - 1) << GLB_WIFIPLL_R4_SHORT_POS) +#define GLB_WIFIPLL_R4_SHORT_UMSK (~(((1U << GLB_WIFIPLL_R4_SHORT_LEN) - 1) << GLB_WIFIPLL_R4_SHORT_POS)) +#define GLB_WIFIPLL_C3 GLB_WIFIPLL_C3 +#define GLB_WIFIPLL_C3_POS (12U) +#define GLB_WIFIPLL_C3_LEN (2U) +#define GLB_WIFIPLL_C3_MSK (((1U << GLB_WIFIPLL_C3_LEN) - 1) << GLB_WIFIPLL_C3_POS) +#define GLB_WIFIPLL_C3_UMSK (~(((1U << GLB_WIFIPLL_C3_LEN) - 1) << GLB_WIFIPLL_C3_POS)) +#define GLB_WIFIPLL_CZ GLB_WIFIPLL_CZ +#define GLB_WIFIPLL_CZ_POS (14U) +#define GLB_WIFIPLL_CZ_LEN (2U) +#define GLB_WIFIPLL_CZ_MSK (((1U << GLB_WIFIPLL_CZ_LEN) - 1) << GLB_WIFIPLL_CZ_POS) +#define GLB_WIFIPLL_CZ_UMSK (~(((1U << GLB_WIFIPLL_CZ_LEN) - 1) << GLB_WIFIPLL_CZ_POS)) +#define GLB_WIFIPLL_RZ GLB_WIFIPLL_RZ +#define GLB_WIFIPLL_RZ_POS (16U) +#define GLB_WIFIPLL_RZ_LEN (3U) +#define GLB_WIFIPLL_RZ_MSK (((1U << GLB_WIFIPLL_RZ_LEN) - 1) << GLB_WIFIPLL_RZ_POS) +#define GLB_WIFIPLL_RZ_UMSK (~(((1U << GLB_WIFIPLL_RZ_LEN) - 1) << GLB_WIFIPLL_RZ_POS)) + +/* 0x820 : wifi_pll_cfg4 */ +#define GLB_WIFI_PLL_CFG4_OFFSET (0x820) +#define GLB_WIFIPLL_SEL_SAMPLE_CLK GLB_WIFIPLL_SEL_SAMPLE_CLK +#define GLB_WIFIPLL_SEL_SAMPLE_CLK_POS (0U) +#define GLB_WIFIPLL_SEL_SAMPLE_CLK_LEN (2U) +#define GLB_WIFIPLL_SEL_SAMPLE_CLK_MSK (((1U << GLB_WIFIPLL_SEL_SAMPLE_CLK_LEN) - 1) << GLB_WIFIPLL_SEL_SAMPLE_CLK_POS) +#define GLB_WIFIPLL_SEL_SAMPLE_CLK_UMSK (~(((1U << GLB_WIFIPLL_SEL_SAMPLE_CLK_LEN) - 1) << GLB_WIFIPLL_SEL_SAMPLE_CLK_POS)) +#define GLB_WIFIPLL_SEL_FB_CLK GLB_WIFIPLL_SEL_FB_CLK +#define GLB_WIFIPLL_SEL_FB_CLK_POS (4U) +#define GLB_WIFIPLL_SEL_FB_CLK_LEN (2U) +#define GLB_WIFIPLL_SEL_FB_CLK_MSK (((1U << GLB_WIFIPLL_SEL_FB_CLK_LEN) - 1) << GLB_WIFIPLL_SEL_FB_CLK_POS) +#define GLB_WIFIPLL_SEL_FB_CLK_UMSK (~(((1U << GLB_WIFIPLL_SEL_FB_CLK_LEN) - 1) << GLB_WIFIPLL_SEL_FB_CLK_POS)) +#define GLB_WIFIPLL_SDMCLK_SEL GLB_WIFIPLL_SDMCLK_SEL +#define GLB_WIFIPLL_SDMCLK_SEL_POS (8U) +#define GLB_WIFIPLL_SDMCLK_SEL_LEN (1U) +#define GLB_WIFIPLL_SDMCLK_SEL_MSK (((1U << GLB_WIFIPLL_SDMCLK_SEL_LEN) - 1) << GLB_WIFIPLL_SDMCLK_SEL_POS) +#define GLB_WIFIPLL_SDMCLK_SEL_UMSK (~(((1U << GLB_WIFIPLL_SDMCLK_SEL_LEN) - 1) << GLB_WIFIPLL_SDMCLK_SEL_POS)) + +/* 0x824 : wifi_pll_cfg5 */ +#define GLB_WIFI_PLL_CFG5_OFFSET (0x824) +#define GLB_WIFIPLL_VCO_SPEED GLB_WIFIPLL_VCO_SPEED +#define GLB_WIFIPLL_VCO_SPEED_POS (0U) +#define GLB_WIFIPLL_VCO_SPEED_LEN (3U) +#define GLB_WIFIPLL_VCO_SPEED_MSK (((1U << GLB_WIFIPLL_VCO_SPEED_LEN) - 1) << GLB_WIFIPLL_VCO_SPEED_POS) +#define GLB_WIFIPLL_VCO_SPEED_UMSK (~(((1U << GLB_WIFIPLL_VCO_SPEED_LEN) - 1) << GLB_WIFIPLL_VCO_SPEED_POS)) +#define GLB_WIFIPLL_VCO_DIV1_EN GLB_WIFIPLL_VCO_DIV1_EN +#define GLB_WIFIPLL_VCO_DIV1_EN_POS (4U) +#define GLB_WIFIPLL_VCO_DIV1_EN_LEN (1U) +#define GLB_WIFIPLL_VCO_DIV1_EN_MSK (((1U << GLB_WIFIPLL_VCO_DIV1_EN_LEN) - 1) << GLB_WIFIPLL_VCO_DIV1_EN_POS) +#define GLB_WIFIPLL_VCO_DIV1_EN_UMSK (~(((1U << GLB_WIFIPLL_VCO_DIV1_EN_LEN) - 1) << GLB_WIFIPLL_VCO_DIV1_EN_POS)) +#define GLB_WIFIPLL_VCO_DIV2_EN GLB_WIFIPLL_VCO_DIV2_EN +#define GLB_WIFIPLL_VCO_DIV2_EN_POS (8U) +#define GLB_WIFIPLL_VCO_DIV2_EN_LEN (1U) +#define GLB_WIFIPLL_VCO_DIV2_EN_MSK (((1U << GLB_WIFIPLL_VCO_DIV2_EN_LEN) - 1) << GLB_WIFIPLL_VCO_DIV2_EN_POS) +#define GLB_WIFIPLL_VCO_DIV2_EN_UMSK (~(((1U << GLB_WIFIPLL_VCO_DIV2_EN_LEN) - 1) << GLB_WIFIPLL_VCO_DIV2_EN_POS)) +#define GLB_WIFIPLL_VCO_DIV3_EN GLB_WIFIPLL_VCO_DIV3_EN +#define GLB_WIFIPLL_VCO_DIV3_EN_POS (12U) +#define GLB_WIFIPLL_VCO_DIV3_EN_LEN (1U) +#define GLB_WIFIPLL_VCO_DIV3_EN_MSK (((1U << GLB_WIFIPLL_VCO_DIV3_EN_LEN) - 1) << GLB_WIFIPLL_VCO_DIV3_EN_POS) +#define GLB_WIFIPLL_VCO_DIV3_EN_UMSK (~(((1U << GLB_WIFIPLL_VCO_DIV3_EN_LEN) - 1) << GLB_WIFIPLL_VCO_DIV3_EN_POS)) + +/* 0x828 : wifi_pll_cfg6 */ +#define GLB_WIFI_PLL_CFG6_OFFSET (0x828) +#define GLB_WIFIPLL_SDMIN GLB_WIFIPLL_SDMIN +#define GLB_WIFIPLL_SDMIN_POS (0U) +#define GLB_WIFIPLL_SDMIN_LEN (26U) +#define GLB_WIFIPLL_SDMIN_MSK (((1U << GLB_WIFIPLL_SDMIN_LEN) - 1) << GLB_WIFIPLL_SDMIN_POS) +#define GLB_WIFIPLL_SDMIN_UMSK (~(((1U << GLB_WIFIPLL_SDMIN_LEN) - 1) << GLB_WIFIPLL_SDMIN_POS)) +#define GLB_WIFIPLL_SDM_BYPASS GLB_WIFIPLL_SDM_BYPASS +#define GLB_WIFIPLL_SDM_BYPASS_POS (28U) +#define GLB_WIFIPLL_SDM_BYPASS_LEN (1U) +#define GLB_WIFIPLL_SDM_BYPASS_MSK (((1U << GLB_WIFIPLL_SDM_BYPASS_LEN) - 1) << GLB_WIFIPLL_SDM_BYPASS_POS) +#define GLB_WIFIPLL_SDM_BYPASS_UMSK (~(((1U << GLB_WIFIPLL_SDM_BYPASS_LEN) - 1) << GLB_WIFIPLL_SDM_BYPASS_POS)) +#define GLB_WIFIPLL_SDM_BYPASS_HW GLB_WIFIPLL_SDM_BYPASS_HW +#define GLB_WIFIPLL_SDM_BYPASS_HW_POS (29U) +#define GLB_WIFIPLL_SDM_BYPASS_HW_LEN (1U) +#define GLB_WIFIPLL_SDM_BYPASS_HW_MSK (((1U << GLB_WIFIPLL_SDM_BYPASS_HW_LEN) - 1) << GLB_WIFIPLL_SDM_BYPASS_HW_POS) +#define GLB_WIFIPLL_SDM_BYPASS_HW_UMSK (~(((1U << GLB_WIFIPLL_SDM_BYPASS_HW_LEN) - 1) << GLB_WIFIPLL_SDM_BYPASS_HW_POS)) +#define GLB_WIFIPLL_SDM_CTRL_HW GLB_WIFIPLL_SDM_CTRL_HW +#define GLB_WIFIPLL_SDM_CTRL_HW_POS (31U) +#define GLB_WIFIPLL_SDM_CTRL_HW_LEN (1U) +#define GLB_WIFIPLL_SDM_CTRL_HW_MSK (((1U << GLB_WIFIPLL_SDM_CTRL_HW_LEN) - 1) << GLB_WIFIPLL_SDM_CTRL_HW_POS) +#define GLB_WIFIPLL_SDM_CTRL_HW_UMSK (~(((1U << GLB_WIFIPLL_SDM_CTRL_HW_LEN) - 1) << GLB_WIFIPLL_SDM_CTRL_HW_POS)) + +/* 0x82C : wifi_pll_cfg7 */ +#define GLB_WIFI_PLL_CFG7_OFFSET (0x82C) +#define GLB_WIFIPLL_SDM_ORDER_SEL GLB_WIFIPLL_SDM_ORDER_SEL +#define GLB_WIFIPLL_SDM_ORDER_SEL_POS (0U) +#define GLB_WIFIPLL_SDM_ORDER_SEL_LEN (2U) +#define GLB_WIFIPLL_SDM_ORDER_SEL_MSK (((1U << GLB_WIFIPLL_SDM_ORDER_SEL_LEN) - 1) << GLB_WIFIPLL_SDM_ORDER_SEL_POS) +#define GLB_WIFIPLL_SDM_ORDER_SEL_UMSK (~(((1U << GLB_WIFIPLL_SDM_ORDER_SEL_LEN) - 1) << GLB_WIFIPLL_SDM_ORDER_SEL_POS)) +#define GLB_WIFIPLL_SDM_NOI_PRBS_SEL GLB_WIFIPLL_SDM_NOI_PRBS_SEL +#define GLB_WIFIPLL_SDM_NOI_PRBS_SEL_POS (4U) +#define GLB_WIFIPLL_SDM_NOI_PRBS_SEL_LEN (2U) +#define GLB_WIFIPLL_SDM_NOI_PRBS_SEL_MSK (((1U << GLB_WIFIPLL_SDM_NOI_PRBS_SEL_LEN) - 1) << GLB_WIFIPLL_SDM_NOI_PRBS_SEL_POS) +#define GLB_WIFIPLL_SDM_NOI_PRBS_SEL_UMSK (~(((1U << GLB_WIFIPLL_SDM_NOI_PRBS_SEL_LEN) - 1) << GLB_WIFIPLL_SDM_NOI_PRBS_SEL_POS)) +#define GLB_WIFIPLL_SDM_NOI_PRBS_EN GLB_WIFIPLL_SDM_NOI_PRBS_EN +#define GLB_WIFIPLL_SDM_NOI_PRBS_EN_POS (8U) +#define GLB_WIFIPLL_SDM_NOI_PRBS_EN_LEN (1U) +#define GLB_WIFIPLL_SDM_NOI_PRBS_EN_MSK (((1U << GLB_WIFIPLL_SDM_NOI_PRBS_EN_LEN) - 1) << GLB_WIFIPLL_SDM_NOI_PRBS_EN_POS) +#define GLB_WIFIPLL_SDM_NOI_PRBS_EN_UMSK (~(((1U << GLB_WIFIPLL_SDM_NOI_PRBS_EN_LEN) - 1) << GLB_WIFIPLL_SDM_NOI_PRBS_EN_POS)) +#define GLB_WIFIPLL_SDM_SIG_PRBS_SEL GLB_WIFIPLL_SDM_SIG_PRBS_SEL +#define GLB_WIFIPLL_SDM_SIG_PRBS_SEL_POS (12U) +#define GLB_WIFIPLL_SDM_SIG_PRBS_SEL_LEN (2U) +#define GLB_WIFIPLL_SDM_SIG_PRBS_SEL_MSK (((1U << GLB_WIFIPLL_SDM_SIG_PRBS_SEL_LEN) - 1) << GLB_WIFIPLL_SDM_SIG_PRBS_SEL_POS) +#define GLB_WIFIPLL_SDM_SIG_PRBS_SEL_UMSK (~(((1U << GLB_WIFIPLL_SDM_SIG_PRBS_SEL_LEN) - 1) << GLB_WIFIPLL_SDM_SIG_PRBS_SEL_POS)) +#define GLB_WIFIPLL_SDM_SIG_DITH_SEL GLB_WIFIPLL_SDM_SIG_DITH_SEL +#define GLB_WIFIPLL_SDM_SIG_DITH_SEL_POS (16U) +#define GLB_WIFIPLL_SDM_SIG_DITH_SEL_LEN (2U) +#define GLB_WIFIPLL_SDM_SIG_DITH_SEL_MSK (((1U << GLB_WIFIPLL_SDM_SIG_DITH_SEL_LEN) - 1) << GLB_WIFIPLL_SDM_SIG_DITH_SEL_POS) +#define GLB_WIFIPLL_SDM_SIG_DITH_SEL_UMSK (~(((1U << GLB_WIFIPLL_SDM_SIG_DITH_SEL_LEN) - 1) << GLB_WIFIPLL_SDM_SIG_DITH_SEL_POS)) + +/* 0x830 : wifi_pll_cfg8 */ +#define GLB_WIFI_PLL_CFG8_OFFSET (0x830) +#define GLB_WIFIPLL_EN_DIV2 GLB_WIFIPLL_EN_DIV2 +#define GLB_WIFIPLL_EN_DIV2_POS (0U) +#define GLB_WIFIPLL_EN_DIV2_LEN (1U) +#define GLB_WIFIPLL_EN_DIV2_MSK (((1U << GLB_WIFIPLL_EN_DIV2_LEN) - 1) << GLB_WIFIPLL_EN_DIV2_POS) +#define GLB_WIFIPLL_EN_DIV2_UMSK (~(((1U << GLB_WIFIPLL_EN_DIV2_LEN) - 1) << GLB_WIFIPLL_EN_DIV2_POS)) +#define GLB_WIFIPLL_EN_DIV4 GLB_WIFIPLL_EN_DIV4 +#define GLB_WIFIPLL_EN_DIV4_POS (1U) +#define GLB_WIFIPLL_EN_DIV4_LEN (1U) +#define GLB_WIFIPLL_EN_DIV4_MSK (((1U << GLB_WIFIPLL_EN_DIV4_LEN) - 1) << GLB_WIFIPLL_EN_DIV4_POS) +#define GLB_WIFIPLL_EN_DIV4_UMSK (~(((1U << GLB_WIFIPLL_EN_DIV4_LEN) - 1) << GLB_WIFIPLL_EN_DIV4_POS)) +#define GLB_WIFIPLL_EN_DIV5 GLB_WIFIPLL_EN_DIV5 +#define GLB_WIFIPLL_EN_DIV5_POS (2U) +#define GLB_WIFIPLL_EN_DIV5_LEN (1U) +#define GLB_WIFIPLL_EN_DIV5_MSK (((1U << GLB_WIFIPLL_EN_DIV5_LEN) - 1) << GLB_WIFIPLL_EN_DIV5_POS) +#define GLB_WIFIPLL_EN_DIV5_UMSK (~(((1U << GLB_WIFIPLL_EN_DIV5_LEN) - 1) << GLB_WIFIPLL_EN_DIV5_POS)) +#define GLB_WIFIPLL_EN_DIV6 GLB_WIFIPLL_EN_DIV6 +#define GLB_WIFIPLL_EN_DIV6_POS (3U) +#define GLB_WIFIPLL_EN_DIV6_LEN (1U) +#define GLB_WIFIPLL_EN_DIV6_MSK (((1U << GLB_WIFIPLL_EN_DIV6_LEN) - 1) << GLB_WIFIPLL_EN_DIV6_POS) +#define GLB_WIFIPLL_EN_DIV6_UMSK (~(((1U << GLB_WIFIPLL_EN_DIV6_LEN) - 1) << GLB_WIFIPLL_EN_DIV6_POS)) +#define GLB_WIFIPLL_EN_DIV8 GLB_WIFIPLL_EN_DIV8 +#define GLB_WIFIPLL_EN_DIV8_POS (4U) +#define GLB_WIFIPLL_EN_DIV8_LEN (1U) +#define GLB_WIFIPLL_EN_DIV8_MSK (((1U << GLB_WIFIPLL_EN_DIV8_LEN) - 1) << GLB_WIFIPLL_EN_DIV8_POS) +#define GLB_WIFIPLL_EN_DIV8_UMSK (~(((1U << GLB_WIFIPLL_EN_DIV8_LEN) - 1) << GLB_WIFIPLL_EN_DIV8_POS)) +#define GLB_WIFIPLL_EN_DIV10 GLB_WIFIPLL_EN_DIV10 +#define GLB_WIFIPLL_EN_DIV10_POS (5U) +#define GLB_WIFIPLL_EN_DIV10_LEN (1U) +#define GLB_WIFIPLL_EN_DIV10_MSK (((1U << GLB_WIFIPLL_EN_DIV10_LEN) - 1) << GLB_WIFIPLL_EN_DIV10_POS) +#define GLB_WIFIPLL_EN_DIV10_UMSK (~(((1U << GLB_WIFIPLL_EN_DIV10_LEN) - 1) << GLB_WIFIPLL_EN_DIV10_POS)) +#define GLB_WIFIPLL_EN_DIV12 GLB_WIFIPLL_EN_DIV12 +#define GLB_WIFIPLL_EN_DIV12_POS (6U) +#define GLB_WIFIPLL_EN_DIV12_LEN (1U) +#define GLB_WIFIPLL_EN_DIV12_MSK (((1U << GLB_WIFIPLL_EN_DIV12_LEN) - 1) << GLB_WIFIPLL_EN_DIV12_POS) +#define GLB_WIFIPLL_EN_DIV12_UMSK (~(((1U << GLB_WIFIPLL_EN_DIV12_LEN) - 1) << GLB_WIFIPLL_EN_DIV12_POS)) +#define GLB_WIFIPLL_EN_DIV20 GLB_WIFIPLL_EN_DIV20 +#define GLB_WIFIPLL_EN_DIV20_POS (7U) +#define GLB_WIFIPLL_EN_DIV20_LEN (1U) +#define GLB_WIFIPLL_EN_DIV20_MSK (((1U << GLB_WIFIPLL_EN_DIV20_LEN) - 1) << GLB_WIFIPLL_EN_DIV20_POS) +#define GLB_WIFIPLL_EN_DIV20_UMSK (~(((1U << GLB_WIFIPLL_EN_DIV20_LEN) - 1) << GLB_WIFIPLL_EN_DIV20_POS)) +#define GLB_WIFIPLL_EN_DIV30 GLB_WIFIPLL_EN_DIV30 +#define GLB_WIFIPLL_EN_DIV30_POS (8U) +#define GLB_WIFIPLL_EN_DIV30_LEN (1U) +#define GLB_WIFIPLL_EN_DIV30_MSK (((1U << GLB_WIFIPLL_EN_DIV30_LEN) - 1) << GLB_WIFIPLL_EN_DIV30_POS) +#define GLB_WIFIPLL_EN_DIV30_UMSK (~(((1U << GLB_WIFIPLL_EN_DIV30_LEN) - 1) << GLB_WIFIPLL_EN_DIV30_POS)) +#define GLB_WIFIPLL_SEL_DIV2_DIV4 GLB_WIFIPLL_SEL_DIV2_DIV4 +#define GLB_WIFIPLL_SEL_DIV2_DIV4_POS (9U) +#define GLB_WIFIPLL_SEL_DIV2_DIV4_LEN (1U) +#define GLB_WIFIPLL_SEL_DIV2_DIV4_MSK (((1U << GLB_WIFIPLL_SEL_DIV2_DIV4_LEN) - 1) << GLB_WIFIPLL_SEL_DIV2_DIV4_POS) +#define GLB_WIFIPLL_SEL_DIV2_DIV4_UMSK (~(((1U << GLB_WIFIPLL_SEL_DIV2_DIV4_LEN) - 1) << GLB_WIFIPLL_SEL_DIV2_DIV4_POS)) +#define GLB_EN_WIFIPLL_DIV30_BZ_ADC GLB_EN_WIFIPLL_DIV30_BZ_ADC +#define GLB_EN_WIFIPLL_DIV30_BZ_ADC_POS (10U) +#define GLB_EN_WIFIPLL_DIV30_BZ_ADC_LEN (1U) +#define GLB_EN_WIFIPLL_DIV30_BZ_ADC_MSK (((1U << GLB_EN_WIFIPLL_DIV30_BZ_ADC_LEN) - 1) << GLB_EN_WIFIPLL_DIV30_BZ_ADC_POS) +#define GLB_EN_WIFIPLL_DIV30_BZ_ADC_UMSK (~(((1U << GLB_EN_WIFIPLL_DIV30_BZ_ADC_LEN) - 1) << GLB_EN_WIFIPLL_DIV30_BZ_ADC_POS)) +#define GLB_WIFIPLL_EN_DIV2_HW GLB_WIFIPLL_EN_DIV2_HW +#define GLB_WIFIPLL_EN_DIV2_HW_POS (12U) +#define GLB_WIFIPLL_EN_DIV2_HW_LEN (1U) +#define GLB_WIFIPLL_EN_DIV2_HW_MSK (((1U << GLB_WIFIPLL_EN_DIV2_HW_LEN) - 1) << GLB_WIFIPLL_EN_DIV2_HW_POS) +#define GLB_WIFIPLL_EN_DIV2_HW_UMSK (~(((1U << GLB_WIFIPLL_EN_DIV2_HW_LEN) - 1) << GLB_WIFIPLL_EN_DIV2_HW_POS)) +#define GLB_WIFIPLL_EN_CTRL_HW GLB_WIFIPLL_EN_CTRL_HW +#define GLB_WIFIPLL_EN_CTRL_HW_POS (31U) +#define GLB_WIFIPLL_EN_CTRL_HW_LEN (1U) +#define GLB_WIFIPLL_EN_CTRL_HW_MSK (((1U << GLB_WIFIPLL_EN_CTRL_HW_LEN) - 1) << GLB_WIFIPLL_EN_CTRL_HW_POS) +#define GLB_WIFIPLL_EN_CTRL_HW_UMSK (~(((1U << GLB_WIFIPLL_EN_CTRL_HW_LEN) - 1) << GLB_WIFIPLL_EN_CTRL_HW_POS)) + +/* 0x834 : wifi_pll_cfg9 */ +#define GLB_WIFI_PLL_CFG9_OFFSET (0x834) +#define GLB_WIFIPLL_DC_TP_OUT_EN GLB_WIFIPLL_DC_TP_OUT_EN +#define GLB_WIFIPLL_DC_TP_OUT_EN_POS (0U) +#define GLB_WIFIPLL_DC_TP_OUT_EN_LEN (1U) +#define GLB_WIFIPLL_DC_TP_OUT_EN_MSK (((1U << GLB_WIFIPLL_DC_TP_OUT_EN_LEN) - 1) << GLB_WIFIPLL_DC_TP_OUT_EN_POS) +#define GLB_WIFIPLL_DC_TP_OUT_EN_UMSK (~(((1U << GLB_WIFIPLL_DC_TP_OUT_EN_LEN) - 1) << GLB_WIFIPLL_DC_TP_OUT_EN_POS)) +#define GLB_TEN_WIFIPLL GLB_TEN_WIFIPLL +#define GLB_TEN_WIFIPLL_POS (1U) +#define GLB_TEN_WIFIPLL_LEN (1U) +#define GLB_TEN_WIFIPLL_MSK (((1U << GLB_TEN_WIFIPLL_LEN) - 1) << GLB_TEN_WIFIPLL_POS) +#define GLB_TEN_WIFIPLL_UMSK (~(((1U << GLB_TEN_WIFIPLL_LEN) - 1) << GLB_TEN_WIFIPLL_POS)) +#define GLB_TEN_WIFIPLL_SFREG GLB_TEN_WIFIPLL_SFREG +#define GLB_TEN_WIFIPLL_SFREG_POS (2U) +#define GLB_TEN_WIFIPLL_SFREG_LEN (1U) +#define GLB_TEN_WIFIPLL_SFREG_MSK (((1U << GLB_TEN_WIFIPLL_SFREG_LEN) - 1) << GLB_TEN_WIFIPLL_SFREG_POS) +#define GLB_TEN_WIFIPLL_SFREG_UMSK (~(((1U << GLB_TEN_WIFIPLL_SFREG_LEN) - 1) << GLB_TEN_WIFIPLL_SFREG_POS)) +#define GLB_DTEN_WIFIPLL_FIN GLB_DTEN_WIFIPLL_FIN +#define GLB_DTEN_WIFIPLL_FIN_POS (4U) +#define GLB_DTEN_WIFIPLL_FIN_LEN (1U) +#define GLB_DTEN_WIFIPLL_FIN_MSK (((1U << GLB_DTEN_WIFIPLL_FIN_LEN) - 1) << GLB_DTEN_WIFIPLL_FIN_POS) +#define GLB_DTEN_WIFIPLL_FIN_UMSK (~(((1U << GLB_DTEN_WIFIPLL_FIN_LEN) - 1) << GLB_DTEN_WIFIPLL_FIN_POS)) +#define GLB_DTEN_WIFIPLL_FREF GLB_DTEN_WIFIPLL_FREF +#define GLB_DTEN_WIFIPLL_FREF_POS (5U) +#define GLB_DTEN_WIFIPLL_FREF_LEN (1U) +#define GLB_DTEN_WIFIPLL_FREF_MSK (((1U << GLB_DTEN_WIFIPLL_FREF_LEN) - 1) << GLB_DTEN_WIFIPLL_FREF_POS) +#define GLB_DTEN_WIFIPLL_FREF_UMSK (~(((1U << GLB_DTEN_WIFIPLL_FREF_LEN) - 1) << GLB_DTEN_WIFIPLL_FREF_POS)) +#define GLB_DTEN_WIFIPLL_FSDM GLB_DTEN_WIFIPLL_FSDM +#define GLB_DTEN_WIFIPLL_FSDM_POS (6U) +#define GLB_DTEN_WIFIPLL_FSDM_LEN (1U) +#define GLB_DTEN_WIFIPLL_FSDM_MSK (((1U << GLB_DTEN_WIFIPLL_FSDM_LEN) - 1) << GLB_DTEN_WIFIPLL_FSDM_POS) +#define GLB_DTEN_WIFIPLL_FSDM_UMSK (~(((1U << GLB_DTEN_WIFIPLL_FSDM_LEN) - 1) << GLB_DTEN_WIFIPLL_FSDM_POS)) +#define GLB_DTEN_WIFIPLL_DIV30 GLB_DTEN_WIFIPLL_DIV30 +#define GLB_DTEN_WIFIPLL_DIV30_POS (7U) +#define GLB_DTEN_WIFIPLL_DIV30_LEN (1U) +#define GLB_DTEN_WIFIPLL_DIV30_MSK (((1U << GLB_DTEN_WIFIPLL_DIV30_LEN) - 1) << GLB_DTEN_WIFIPLL_DIV30_POS) +#define GLB_DTEN_WIFIPLL_DIV30_UMSK (~(((1U << GLB_DTEN_WIFIPLL_DIV30_LEN) - 1) << GLB_DTEN_WIFIPLL_DIV30_POS)) +#define GLB_DTEN_WIFIPLL_DIV10 GLB_DTEN_WIFIPLL_DIV10 +#define GLB_DTEN_WIFIPLL_DIV10_POS (8U) +#define GLB_DTEN_WIFIPLL_DIV10_LEN (1U) +#define GLB_DTEN_WIFIPLL_DIV10_MSK (((1U << GLB_DTEN_WIFIPLL_DIV10_LEN) - 1) << GLB_DTEN_WIFIPLL_DIV10_POS) +#define GLB_DTEN_WIFIPLL_DIV10_UMSK (~(((1U << GLB_DTEN_WIFIPLL_DIV10_LEN) - 1) << GLB_DTEN_WIFIPLL_DIV10_POS)) +#define GLB_DTEN_WIFIPLL_POSTDIV_CLK GLB_DTEN_WIFIPLL_POSTDIV_CLK +#define GLB_DTEN_WIFIPLL_POSTDIV_CLK_POS (9U) +#define GLB_DTEN_WIFIPLL_POSTDIV_CLK_LEN (1U) +#define GLB_DTEN_WIFIPLL_POSTDIV_CLK_MSK (((1U << GLB_DTEN_WIFIPLL_POSTDIV_CLK_LEN) - 1) << GLB_DTEN_WIFIPLL_POSTDIV_CLK_POS) +#define GLB_DTEN_WIFIPLL_POSTDIV_CLK_UMSK (~(((1U << GLB_DTEN_WIFIPLL_POSTDIV_CLK_LEN) - 1) << GLB_DTEN_WIFIPLL_POSTDIV_CLK_POS)) +#define GLB_USBPLL_DTEST_PCLK_EN GLB_USBPLL_DTEST_PCLK_EN +#define GLB_USBPLL_DTEST_PCLK_EN_POS (10U) +#define GLB_USBPLL_DTEST_PCLK_EN_LEN (1U) +#define GLB_USBPLL_DTEST_PCLK_EN_MSK (((1U << GLB_USBPLL_DTEST_PCLK_EN_LEN) - 1) << GLB_USBPLL_DTEST_PCLK_EN_POS) +#define GLB_USBPLL_DTEST_PCLK_EN_UMSK (~(((1U << GLB_USBPLL_DTEST_PCLK_EN_LEN) - 1) << GLB_USBPLL_DTEST_PCLK_EN_POS)) +#define GLB_USBPLL_DTEST_CLKOUT_EN GLB_USBPLL_DTEST_CLKOUT_EN +#define GLB_USBPLL_DTEST_CLKOUT_EN_POS (11U) +#define GLB_USBPLL_DTEST_CLKOUT_EN_LEN (1U) +#define GLB_USBPLL_DTEST_CLKOUT_EN_MSK (((1U << GLB_USBPLL_DTEST_CLKOUT_EN_LEN) - 1) << GLB_USBPLL_DTEST_CLKOUT_EN_POS) +#define GLB_USBPLL_DTEST_CLKOUT_EN_UMSK (~(((1U << GLB_USBPLL_DTEST_CLKOUT_EN_LEN) - 1) << GLB_USBPLL_DTEST_CLKOUT_EN_POS)) +#define GLB_DTEST_WIFIPLL_PULLDOWN GLB_DTEST_WIFIPLL_PULLDOWN +#define GLB_DTEST_WIFIPLL_PULLDOWN_POS (12U) +#define GLB_DTEST_WIFIPLL_PULLDOWN_LEN (1U) +#define GLB_DTEST_WIFIPLL_PULLDOWN_MSK (((1U << GLB_DTEST_WIFIPLL_PULLDOWN_LEN) - 1) << GLB_DTEST_WIFIPLL_PULLDOWN_POS) +#define GLB_DTEST_WIFIPLL_PULLDOWN_UMSK (~(((1U << GLB_DTEST_WIFIPLL_PULLDOWN_LEN) - 1) << GLB_DTEST_WIFIPLL_PULLDOWN_POS)) + +/* 0x838 : wifi_pll_cfg10 */ +#define GLB_WIFI_PLL_CFG10_OFFSET (0x838) +#define GLB_USBPLL_SSC_START GLB_USBPLL_SSC_START +#define GLB_USBPLL_SSC_START_POS (2U) +#define GLB_USBPLL_SSC_START_LEN (1U) +#define GLB_USBPLL_SSC_START_MSK (((1U << GLB_USBPLL_SSC_START_LEN) - 1) << GLB_USBPLL_SSC_START_POS) +#define GLB_USBPLL_SSC_START_UMSK (~(((1U << GLB_USBPLL_SSC_START_LEN) - 1) << GLB_USBPLL_SSC_START_POS)) +#define GLB_USBPLL_SSC_START_GATE_EN GLB_USBPLL_SSC_START_GATE_EN +#define GLB_USBPLL_SSC_START_GATE_EN_POS (3U) +#define GLB_USBPLL_SSC_START_GATE_EN_LEN (1U) +#define GLB_USBPLL_SSC_START_GATE_EN_MSK (((1U << GLB_USBPLL_SSC_START_GATE_EN_LEN) - 1) << GLB_USBPLL_SSC_START_GATE_EN_POS) +#define GLB_USBPLL_SSC_START_GATE_EN_UMSK (~(((1U << GLB_USBPLL_SSC_START_GATE_EN_LEN) - 1) << GLB_USBPLL_SSC_START_GATE_EN_POS)) +#define GLB_USBPLL_SSC_GAIN GLB_USBPLL_SSC_GAIN +#define GLB_USBPLL_SSC_GAIN_POS (4U) +#define GLB_USBPLL_SSC_GAIN_LEN (3U) +#define GLB_USBPLL_SSC_GAIN_MSK (((1U << GLB_USBPLL_SSC_GAIN_LEN) - 1) << GLB_USBPLL_SSC_GAIN_POS) +#define GLB_USBPLL_SSC_GAIN_UMSK (~(((1U << GLB_USBPLL_SSC_GAIN_LEN) - 1) << GLB_USBPLL_SSC_GAIN_POS)) +#define GLB_USBPLL_SSC_EN GLB_USBPLL_SSC_EN +#define GLB_USBPLL_SSC_EN_POS (8U) +#define GLB_USBPLL_SSC_EN_LEN (1U) +#define GLB_USBPLL_SSC_EN_MSK (((1U << GLB_USBPLL_SSC_EN_LEN) - 1) << GLB_USBPLL_SSC_EN_POS) +#define GLB_USBPLL_SSC_EN_UMSK (~(((1U << GLB_USBPLL_SSC_EN_LEN) - 1) << GLB_USBPLL_SSC_EN_POS)) +#define GLB_USBPLL_SDM_BYPASS GLB_USBPLL_SDM_BYPASS +#define GLB_USBPLL_SDM_BYPASS_POS (9U) +#define GLB_USBPLL_SDM_BYPASS_LEN (1U) +#define GLB_USBPLL_SDM_BYPASS_MSK (((1U << GLB_USBPLL_SDM_BYPASS_LEN) - 1) << GLB_USBPLL_SDM_BYPASS_POS) +#define GLB_USBPLL_SDM_BYPASS_UMSK (~(((1U << GLB_USBPLL_SDM_BYPASS_LEN) - 1) << GLB_USBPLL_SDM_BYPASS_POS)) +#define GLB_USBPLL_SDM_ORDER_SEL GLB_USBPLL_SDM_ORDER_SEL +#define GLB_USBPLL_SDM_ORDER_SEL_POS (10U) +#define GLB_USBPLL_SDM_ORDER_SEL_LEN (1U) +#define GLB_USBPLL_SDM_ORDER_SEL_MSK (((1U << GLB_USBPLL_SDM_ORDER_SEL_LEN) - 1) << GLB_USBPLL_SDM_ORDER_SEL_POS) +#define GLB_USBPLL_SDM_ORDER_SEL_UMSK (~(((1U << GLB_USBPLL_SDM_ORDER_SEL_LEN) - 1) << GLB_USBPLL_SDM_ORDER_SEL_POS)) +#define GLB_USBPLL_SDM_SIG_DITH_SEL GLB_USBPLL_SDM_SIG_DITH_SEL +#define GLB_USBPLL_SDM_SIG_DITH_SEL_POS (16U) +#define GLB_USBPLL_SDM_SIG_DITH_SEL_LEN (2U) +#define GLB_USBPLL_SDM_SIG_DITH_SEL_MSK (((1U << GLB_USBPLL_SDM_SIG_DITH_SEL_LEN) - 1) << GLB_USBPLL_SDM_SIG_DITH_SEL_POS) +#define GLB_USBPLL_SDM_SIG_DITH_SEL_UMSK (~(((1U << GLB_USBPLL_SDM_SIG_DITH_SEL_LEN) - 1) << GLB_USBPLL_SDM_SIG_DITH_SEL_POS)) +#define GLB_USBPLL_DIV2_EN GLB_USBPLL_DIV2_EN +#define GLB_USBPLL_DIV2_EN_POS (20U) +#define GLB_USBPLL_DIV2_EN_LEN (1U) +#define GLB_USBPLL_DIV2_EN_MSK (((1U << GLB_USBPLL_DIV2_EN_LEN) - 1) << GLB_USBPLL_DIV2_EN_POS) +#define GLB_USBPLL_DIV2_EN_UMSK (~(((1U << GLB_USBPLL_DIV2_EN_LEN) - 1) << GLB_USBPLL_DIV2_EN_POS)) +#define GLB_USBPLL_CLKOUT_EN GLB_USBPLL_CLKOUT_EN +#define GLB_USBPLL_CLKOUT_EN_POS (21U) +#define GLB_USBPLL_CLKOUT_EN_LEN (1U) +#define GLB_USBPLL_CLKOUT_EN_MSK (((1U << GLB_USBPLL_CLKOUT_EN_LEN) - 1) << GLB_USBPLL_CLKOUT_EN_POS) +#define GLB_USBPLL_CLKOUT_EN_UMSK (~(((1U << GLB_USBPLL_CLKOUT_EN_LEN) - 1) << GLB_USBPLL_CLKOUT_EN_POS)) +#define GLB_USBPLL_SEL_SAMPLE_CLK GLB_USBPLL_SEL_SAMPLE_CLK +#define GLB_USBPLL_SEL_SAMPLE_CLK_POS (24U) +#define GLB_USBPLL_SEL_SAMPLE_CLK_LEN (2U) +#define GLB_USBPLL_SEL_SAMPLE_CLK_MSK (((1U << GLB_USBPLL_SEL_SAMPLE_CLK_LEN) - 1) << GLB_USBPLL_SEL_SAMPLE_CLK_POS) +#define GLB_USBPLL_SEL_SAMPLE_CLK_UMSK (~(((1U << GLB_USBPLL_SEL_SAMPLE_CLK_LEN) - 1) << GLB_USBPLL_SEL_SAMPLE_CLK_POS)) +#define GLB_USBPLL_RSTB GLB_USBPLL_RSTB +#define GLB_USBPLL_RSTB_POS (28U) +#define GLB_USBPLL_RSTB_LEN (1U) +#define GLB_USBPLL_RSTB_MSK (((1U << GLB_USBPLL_RSTB_LEN) - 1) << GLB_USBPLL_RSTB_POS) +#define GLB_USBPLL_RSTB_UMSK (~(((1U << GLB_USBPLL_RSTB_LEN) - 1) << GLB_USBPLL_RSTB_POS)) +#define GLB_PU_USBPLL_MMDIV GLB_PU_USBPLL_MMDIV +#define GLB_PU_USBPLL_MMDIV_POS (29U) +#define GLB_PU_USBPLL_MMDIV_LEN (1U) +#define GLB_PU_USBPLL_MMDIV_MSK (((1U << GLB_PU_USBPLL_MMDIV_LEN) - 1) << GLB_PU_USBPLL_MMDIV_POS) +#define GLB_PU_USBPLL_MMDIV_UMSK (~(((1U << GLB_PU_USBPLL_MMDIV_LEN) - 1) << GLB_PU_USBPLL_MMDIV_POS)) + +/* 0x83C : wifi_pll_cfg11 */ +#define GLB_WIFI_PLL_CFG11_OFFSET (0x83C) +#define GLB_USBPLL_SDMIN GLB_USBPLL_SDMIN +#define GLB_USBPLL_SDMIN_POS (0U) +#define GLB_USBPLL_SDMIN_LEN (19U) +#define GLB_USBPLL_SDMIN_MSK (((1U << GLB_USBPLL_SDMIN_LEN) - 1) << GLB_USBPLL_SDMIN_POS) +#define GLB_USBPLL_SDMIN_UMSK (~(((1U << GLB_USBPLL_SDMIN_LEN) - 1) << GLB_USBPLL_SDMIN_POS)) + +/* 0x840 : wifi_pll_cfg12 */ +#define GLB_WIFI_PLL_CFG12_OFFSET (0x840) +#define GLB_USBPLL_SSC_CNT GLB_USBPLL_SSC_CNT +#define GLB_USBPLL_SSC_CNT_POS (0U) +#define GLB_USBPLL_SSC_CNT_LEN (9U) +#define GLB_USBPLL_SSC_CNT_MSK (((1U << GLB_USBPLL_SSC_CNT_LEN) - 1) << GLB_USBPLL_SSC_CNT_POS) +#define GLB_USBPLL_SSC_CNT_UMSK (~(((1U << GLB_USBPLL_SSC_CNT_LEN) - 1) << GLB_USBPLL_SSC_CNT_POS)) + +/* 0x844 : wifi_pll_cfg13 */ +#define GLB_WIFI_PLL_CFG13_OFFSET (0x844) +#define GLB_WIFIPLL_RESV GLB_WIFIPLL_RESV +#define GLB_WIFIPLL_RESV_POS (0U) +#define GLB_WIFIPLL_RESV_LEN (16U) +#define GLB_WIFIPLL_RESV_MSK (((1U << GLB_WIFIPLL_RESV_LEN) - 1) << GLB_WIFIPLL_RESV_POS) +#define GLB_WIFIPLL_RESV_UMSK (~(((1U << GLB_WIFIPLL_RESV_LEN) - 1) << GLB_WIFIPLL_RESV_POS)) +#define GLB_USBPLL_DL_CTRL GLB_USBPLL_DL_CTRL +#define GLB_USBPLL_DL_CTRL_POS (21U) +#define GLB_USBPLL_DL_CTRL_LEN (1U) +#define GLB_USBPLL_DL_CTRL_MSK (((1U << GLB_USBPLL_DL_CTRL_LEN) - 1) << GLB_USBPLL_DL_CTRL_POS) +#define GLB_USBPLL_DL_CTRL_UMSK (~(((1U << GLB_USBPLL_DL_CTRL_LEN) - 1) << GLB_USBPLL_DL_CTRL_POS)) +#define GLB_WIFIPLL_DL_CTRL_30_BZ_ADC GLB_WIFIPLL_DL_CTRL_30_BZ_ADC +#define GLB_WIFIPLL_DL_CTRL_30_BZ_ADC_POS (22U) +#define GLB_WIFIPLL_DL_CTRL_30_BZ_ADC_LEN (1U) +#define GLB_WIFIPLL_DL_CTRL_30_BZ_ADC_MSK (((1U << GLB_WIFIPLL_DL_CTRL_30_BZ_ADC_LEN) - 1) << GLB_WIFIPLL_DL_CTRL_30_BZ_ADC_POS) +#define GLB_WIFIPLL_DL_CTRL_30_BZ_ADC_UMSK (~(((1U << GLB_WIFIPLL_DL_CTRL_30_BZ_ADC_LEN) - 1) << GLB_WIFIPLL_DL_CTRL_30_BZ_ADC_POS)) +#define GLB_WIFIPLL_DL_CTRL_30 GLB_WIFIPLL_DL_CTRL_30 +#define GLB_WIFIPLL_DL_CTRL_30_POS (23U) +#define GLB_WIFIPLL_DL_CTRL_30_LEN (1U) +#define GLB_WIFIPLL_DL_CTRL_30_MSK (((1U << GLB_WIFIPLL_DL_CTRL_30_LEN) - 1) << GLB_WIFIPLL_DL_CTRL_30_POS) +#define GLB_WIFIPLL_DL_CTRL_30_UMSK (~(((1U << GLB_WIFIPLL_DL_CTRL_30_LEN) - 1) << GLB_WIFIPLL_DL_CTRL_30_POS)) +#define GLB_WIFIPLL_DL_CTRL_20 GLB_WIFIPLL_DL_CTRL_20 +#define GLB_WIFIPLL_DL_CTRL_20_POS (24U) +#define GLB_WIFIPLL_DL_CTRL_20_LEN (1U) +#define GLB_WIFIPLL_DL_CTRL_20_MSK (((1U << GLB_WIFIPLL_DL_CTRL_20_LEN) - 1) << GLB_WIFIPLL_DL_CTRL_20_POS) +#define GLB_WIFIPLL_DL_CTRL_20_UMSK (~(((1U << GLB_WIFIPLL_DL_CTRL_20_LEN) - 1) << GLB_WIFIPLL_DL_CTRL_20_POS)) +#define GLB_WIFIPLL_DL_CTRL_12 GLB_WIFIPLL_DL_CTRL_12 +#define GLB_WIFIPLL_DL_CTRL_12_POS (25U) +#define GLB_WIFIPLL_DL_CTRL_12_LEN (1U) +#define GLB_WIFIPLL_DL_CTRL_12_MSK (((1U << GLB_WIFIPLL_DL_CTRL_12_LEN) - 1) << GLB_WIFIPLL_DL_CTRL_12_POS) +#define GLB_WIFIPLL_DL_CTRL_12_UMSK (~(((1U << GLB_WIFIPLL_DL_CTRL_12_LEN) - 1) << GLB_WIFIPLL_DL_CTRL_12_POS)) +#define GLB_WIFIPLL_DL_CTRL_10 GLB_WIFIPLL_DL_CTRL_10 +#define GLB_WIFIPLL_DL_CTRL_10_POS (26U) +#define GLB_WIFIPLL_DL_CTRL_10_LEN (1U) +#define GLB_WIFIPLL_DL_CTRL_10_MSK (((1U << GLB_WIFIPLL_DL_CTRL_10_LEN) - 1) << GLB_WIFIPLL_DL_CTRL_10_POS) +#define GLB_WIFIPLL_DL_CTRL_10_UMSK (~(((1U << GLB_WIFIPLL_DL_CTRL_10_LEN) - 1) << GLB_WIFIPLL_DL_CTRL_10_POS)) +#define GLB_WIFIPLL_DL_CTRL_8 GLB_WIFIPLL_DL_CTRL_8 +#define GLB_WIFIPLL_DL_CTRL_8_POS (27U) +#define GLB_WIFIPLL_DL_CTRL_8_LEN (1U) +#define GLB_WIFIPLL_DL_CTRL_8_MSK (((1U << GLB_WIFIPLL_DL_CTRL_8_LEN) - 1) << GLB_WIFIPLL_DL_CTRL_8_POS) +#define GLB_WIFIPLL_DL_CTRL_8_UMSK (~(((1U << GLB_WIFIPLL_DL_CTRL_8_LEN) - 1) << GLB_WIFIPLL_DL_CTRL_8_POS)) +#define GLB_WIFIPLL_DL_CTRL_6 GLB_WIFIPLL_DL_CTRL_6 +#define GLB_WIFIPLL_DL_CTRL_6_POS (28U) +#define GLB_WIFIPLL_DL_CTRL_6_LEN (1U) +#define GLB_WIFIPLL_DL_CTRL_6_MSK (((1U << GLB_WIFIPLL_DL_CTRL_6_LEN) - 1) << GLB_WIFIPLL_DL_CTRL_6_POS) +#define GLB_WIFIPLL_DL_CTRL_6_UMSK (~(((1U << GLB_WIFIPLL_DL_CTRL_6_LEN) - 1) << GLB_WIFIPLL_DL_CTRL_6_POS)) +#define GLB_WIFIPLL_DL_CTRL_5 GLB_WIFIPLL_DL_CTRL_5 +#define GLB_WIFIPLL_DL_CTRL_5_POS (29U) +#define GLB_WIFIPLL_DL_CTRL_5_LEN (1U) +#define GLB_WIFIPLL_DL_CTRL_5_MSK (((1U << GLB_WIFIPLL_DL_CTRL_5_LEN) - 1) << GLB_WIFIPLL_DL_CTRL_5_POS) +#define GLB_WIFIPLL_DL_CTRL_5_UMSK (~(((1U << GLB_WIFIPLL_DL_CTRL_5_LEN) - 1) << GLB_WIFIPLL_DL_CTRL_5_POS)) +#define GLB_WIFIPLL_DL_CTRL_4 GLB_WIFIPLL_DL_CTRL_4 +#define GLB_WIFIPLL_DL_CTRL_4_POS (30U) +#define GLB_WIFIPLL_DL_CTRL_4_LEN (1U) +#define GLB_WIFIPLL_DL_CTRL_4_MSK (((1U << GLB_WIFIPLL_DL_CTRL_4_LEN) - 1) << GLB_WIFIPLL_DL_CTRL_4_POS) +#define GLB_WIFIPLL_DL_CTRL_4_UMSK (~(((1U << GLB_WIFIPLL_DL_CTRL_4_LEN) - 1) << GLB_WIFIPLL_DL_CTRL_4_POS)) +#define GLB_WIFIPLL_DL_CTRL_2 GLB_WIFIPLL_DL_CTRL_2 +#define GLB_WIFIPLL_DL_CTRL_2_POS (31U) +#define GLB_WIFIPLL_DL_CTRL_2_LEN (1U) +#define GLB_WIFIPLL_DL_CTRL_2_MSK (((1U << GLB_WIFIPLL_DL_CTRL_2_LEN) - 1) << GLB_WIFIPLL_DL_CTRL_2_POS) +#define GLB_WIFIPLL_DL_CTRL_2_UMSK (~(((1U << GLB_WIFIPLL_DL_CTRL_2_LEN) - 1) << GLB_WIFIPLL_DL_CTRL_2_POS)) + +/* 0x8A4 : gauge */ +#define GLB_GAUGE_OFFSET (0x8A4) +#define GLB_GAUGE_RESERVE GLB_GAUGE_RESERVE +#define GLB_GAUGE_RESERVE_POS (0U) +#define GLB_GAUGE_RESERVE_LEN (3U) +#define GLB_GAUGE_RESERVE_MSK (((1U << GLB_GAUGE_RESERVE_LEN) - 1) << GLB_GAUGE_RESERVE_POS) +#define GLB_GAUGE_RESERVE_UMSK (~(((1U << GLB_GAUGE_RESERVE_LEN) - 1) << GLB_GAUGE_RESERVE_POS)) +#define GLB_GAUGE_ICTRL_ADC GLB_GAUGE_ICTRL_ADC +#define GLB_GAUGE_ICTRL_ADC_POS (3U) +#define GLB_GAUGE_ICTRL_ADC_LEN (2U) +#define GLB_GAUGE_ICTRL_ADC_MSK (((1U << GLB_GAUGE_ICTRL_ADC_LEN) - 1) << GLB_GAUGE_ICTRL_ADC_POS) +#define GLB_GAUGE_ICTRL_ADC_UMSK (~(((1U << GLB_GAUGE_ICTRL_ADC_LEN) - 1) << GLB_GAUGE_ICTRL_ADC_POS)) +#define GLB_GAUGE_DEM_EN GLB_GAUGE_DEM_EN +#define GLB_GAUGE_DEM_EN_POS (5U) +#define GLB_GAUGE_DEM_EN_LEN (1U) +#define GLB_GAUGE_DEM_EN_MSK (((1U << GLB_GAUGE_DEM_EN_LEN) - 1) << GLB_GAUGE_DEM_EN_POS) +#define GLB_GAUGE_DEM_EN_UMSK (~(((1U << GLB_GAUGE_DEM_EN_LEN) - 1) << GLB_GAUGE_DEM_EN_POS)) +#define GLB_GAUGE_CKB_EN GLB_GAUGE_CKB_EN +#define GLB_GAUGE_CKB_EN_POS (6U) +#define GLB_GAUGE_CKB_EN_LEN (1U) +#define GLB_GAUGE_CKB_EN_MSK (((1U << GLB_GAUGE_CKB_EN_LEN) - 1) << GLB_GAUGE_CKB_EN_POS) +#define GLB_GAUGE_CKB_EN_UMSK (~(((1U << GLB_GAUGE_CKB_EN_LEN) - 1) << GLB_GAUGE_CKB_EN_POS)) +#define GLB_GAUGE_CHOP_PHAS GLB_GAUGE_CHOP_PHAS +#define GLB_GAUGE_CHOP_PHAS_POS (7U) +#define GLB_GAUGE_CHOP_PHAS_LEN (1U) +#define GLB_GAUGE_CHOP_PHAS_MSK (((1U << GLB_GAUGE_CHOP_PHAS_LEN) - 1) << GLB_GAUGE_CHOP_PHAS_POS) +#define GLB_GAUGE_CHOP_PHAS_UMSK (~(((1U << GLB_GAUGE_CHOP_PHAS_LEN) - 1) << GLB_GAUGE_CHOP_PHAS_POS)) +#define GLB_GAUGE_CHOP_FREQ GLB_GAUGE_CHOP_FREQ +#define GLB_GAUGE_CHOP_FREQ_POS (8U) +#define GLB_GAUGE_CHOP_FREQ_LEN (3U) +#define GLB_GAUGE_CHOP_FREQ_MSK (((1U << GLB_GAUGE_CHOP_FREQ_LEN) - 1) << GLB_GAUGE_CHOP_FREQ_POS) +#define GLB_GAUGE_CHOP_FREQ_UMSK (~(((1U << GLB_GAUGE_CHOP_FREQ_LEN) - 1) << GLB_GAUGE_CHOP_FREQ_POS)) +#define GLB_GAUGE_CHOP_EN GLB_GAUGE_CHOP_EN +#define GLB_GAUGE_CHOP_EN_POS (11U) +#define GLB_GAUGE_CHOP_EN_LEN (1U) +#define GLB_GAUGE_CHOP_EN_MSK (((1U << GLB_GAUGE_CHOP_EN_LEN) - 1) << GLB_GAUGE_CHOP_EN_POS) +#define GLB_GAUGE_CHOP_EN_UMSK (~(((1U << GLB_GAUGE_CHOP_EN_LEN) - 1) << GLB_GAUGE_CHOP_EN_POS)) +#define GLB_GAUGE_SEL_EDGE GLB_GAUGE_SEL_EDGE +#define GLB_GAUGE_SEL_EDGE_POS (12U) +#define GLB_GAUGE_SEL_EDGE_LEN (1U) +#define GLB_GAUGE_SEL_EDGE_MSK (((1U << GLB_GAUGE_SEL_EDGE_LEN) - 1) << GLB_GAUGE_SEL_EDGE_POS) +#define GLB_GAUGE_SEL_EDGE_UMSK (~(((1U << GLB_GAUGE_SEL_EDGE_LEN) - 1) << GLB_GAUGE_SEL_EDGE_POS)) +#define GLB_GAUGE_QUAN_GAIN GLB_GAUGE_QUAN_GAIN +#define GLB_GAUGE_QUAN_GAIN_POS (13U) +#define GLB_GAUGE_QUAN_GAIN_LEN (2U) +#define GLB_GAUGE_QUAN_GAIN_MSK (((1U << GLB_GAUGE_QUAN_GAIN_LEN) - 1) << GLB_GAUGE_QUAN_GAIN_POS) +#define GLB_GAUGE_QUAN_GAIN_UMSK (~(((1U << GLB_GAUGE_QUAN_GAIN_LEN) - 1) << GLB_GAUGE_QUAN_GAIN_POS)) +#define GLB_GAUGE_SDM_PU GLB_GAUGE_SDM_PU +#define GLB_GAUGE_SDM_PU_POS (15U) +#define GLB_GAUGE_SDM_PU_LEN (1U) +#define GLB_GAUGE_SDM_PU_MSK (((1U << GLB_GAUGE_SDM_PU_LEN) - 1) << GLB_GAUGE_SDM_PU_POS) +#define GLB_GAUGE_SDM_PU_UMSK (~(((1U << GLB_GAUGE_SDM_PU_LEN) - 1) << GLB_GAUGE_SDM_PU_POS)) +#define GLB_GAUGE_CHANNEL_SEL GLB_GAUGE_CHANNEL_SEL +#define GLB_GAUGE_CHANNEL_SEL_POS (16U) +#define GLB_GAUGE_CHANNEL_SEL_LEN (1U) +#define GLB_GAUGE_CHANNEL_SEL_MSK (((1U << GLB_GAUGE_CHANNEL_SEL_LEN) - 1) << GLB_GAUGE_CHANNEL_SEL_POS) +#define GLB_GAUGE_CHANNEL_SEL_UMSK (~(((1U << GLB_GAUGE_CHANNEL_SEL_LEN) - 1) << GLB_GAUGE_CHANNEL_SEL_POS)) +#define GLB_GAUGE_CHANNEL_EN GLB_GAUGE_CHANNEL_EN +#define GLB_GAUGE_CHANNEL_EN_POS (17U) +#define GLB_GAUGE_CHANNEL_EN_LEN (1U) +#define GLB_GAUGE_CHANNEL_EN_MSK (((1U << GLB_GAUGE_CHANNEL_EN_LEN) - 1) << GLB_GAUGE_CHANNEL_EN_POS) +#define GLB_GAUGE_CHANNEL_EN_UMSK (~(((1U << GLB_GAUGE_CHANNEL_EN_LEN) - 1) << GLB_GAUGE_CHANNEL_EN_POS)) +#define GLB_GAUGE_LP_MODE GLB_GAUGE_LP_MODE +#define GLB_GAUGE_LP_MODE_POS (18U) +#define GLB_GAUGE_LP_MODE_LEN (1U) +#define GLB_GAUGE_LP_MODE_MSK (((1U << GLB_GAUGE_LP_MODE_LEN) - 1) << GLB_GAUGE_LP_MODE_POS) +#define GLB_GAUGE_LP_MODE_UMSK (~(((1U << GLB_GAUGE_LP_MODE_LEN) - 1) << GLB_GAUGE_LP_MODE_POS)) +#define GLB_TMUX_GAUGE_POWER GLB_TMUX_GAUGE_POWER +#define GLB_TMUX_GAUGE_POWER_POS (20U) +#define GLB_TMUX_GAUGE_POWER_LEN (3U) +#define GLB_TMUX_GAUGE_POWER_MSK (((1U << GLB_TMUX_GAUGE_POWER_LEN) - 1) << GLB_TMUX_GAUGE_POWER_POS) +#define GLB_TMUX_GAUGE_POWER_UMSK (~(((1U << GLB_TMUX_GAUGE_POWER_LEN) - 1) << GLB_TMUX_GAUGE_POWER_POS)) +#define GLB_TEN_GAUGE_POWER GLB_TEN_GAUGE_POWER +#define GLB_TEN_GAUGE_POWER_POS (23U) +#define GLB_TEN_GAUGE_POWER_LEN (1U) +#define GLB_TEN_GAUGE_POWER_MSK (((1U << GLB_TEN_GAUGE_POWER_LEN) - 1) << GLB_TEN_GAUGE_POWER_POS) +#define GLB_TEN_GAUGE_POWER_UMSK (~(((1U << GLB_TEN_GAUGE_POWER_LEN) - 1) << GLB_TEN_GAUGE_POWER_POS)) +#define GLB_NTC_BIAS_SEL GLB_NTC_BIAS_SEL +#define GLB_NTC_BIAS_SEL_POS (24U) +#define GLB_NTC_BIAS_SEL_LEN (4U) +#define GLB_NTC_BIAS_SEL_MSK (((1U << GLB_NTC_BIAS_SEL_LEN) - 1) << GLB_NTC_BIAS_SEL_POS) +#define GLB_NTC_BIAS_SEL_UMSK (~(((1U << GLB_NTC_BIAS_SEL_LEN) - 1) << GLB_NTC_BIAS_SEL_POS)) +#define GLB_NTC_BIAS_EN GLB_NTC_BIAS_EN +#define GLB_NTC_BIAS_EN_POS (28U) +#define GLB_NTC_BIAS_EN_LEN (1U) +#define GLB_NTC_BIAS_EN_MSK (((1U << GLB_NTC_BIAS_EN_LEN) - 1) << GLB_NTC_BIAS_EN_POS) +#define GLB_NTC_BIAS_EN_UMSK (~(((1U << GLB_NTC_BIAS_EN_LEN) - 1) << GLB_NTC_BIAS_EN_POS)) +#define GLB_GAUGE_LDO_PU GLB_GAUGE_LDO_PU +#define GLB_GAUGE_LDO_PU_POS (29U) +#define GLB_GAUGE_LDO_PU_LEN (1U) +#define GLB_GAUGE_LDO_PU_MSK (((1U << GLB_GAUGE_LDO_PU_LEN) - 1) << GLB_GAUGE_LDO_PU_POS) +#define GLB_GAUGE_LDO_PU_UMSK (~(((1U << GLB_GAUGE_LDO_PU_LEN) - 1) << GLB_GAUGE_LDO_PU_POS)) +#define GLB_GAUGE_VCM_PU GLB_GAUGE_VCM_PU +#define GLB_GAUGE_VCM_PU_POS (30U) +#define GLB_GAUGE_VCM_PU_LEN (1U) +#define GLB_GAUGE_VCM_PU_MSK (((1U << GLB_GAUGE_VCM_PU_LEN) - 1) << GLB_GAUGE_VCM_PU_POS) +#define GLB_GAUGE_VCM_PU_UMSK (~(((1U << GLB_GAUGE_VCM_PU_LEN) - 1) << GLB_GAUGE_VCM_PU_POS)) +#define GLB_GAUGE_BG_PU GLB_GAUGE_BG_PU +#define GLB_GAUGE_BG_PU_POS (31U) +#define GLB_GAUGE_BG_PU_LEN (1U) +#define GLB_GAUGE_BG_PU_MSK (((1U << GLB_GAUGE_BG_PU_LEN) - 1) << GLB_GAUGE_BG_PU_POS) +#define GLB_GAUGE_BG_PU_UMSK (~(((1U << GLB_GAUGE_BG_PU_LEN) - 1) << GLB_GAUGE_BG_PU_POS)) + +/* 0x8B8 : gauge_rx_fifo_ctrl */ +#define GLB_GAUGE_RX_FIFO_CTRL_OFFSET (0x8B8) +#define GLB_GAUGE_RX_FIFO_FLUSH GLB_GAUGE_RX_FIFO_FLUSH +#define GLB_GAUGE_RX_FIFO_FLUSH_POS (0U) +#define GLB_GAUGE_RX_FIFO_FLUSH_LEN (1U) +#define GLB_GAUGE_RX_FIFO_FLUSH_MSK (((1U << GLB_GAUGE_RX_FIFO_FLUSH_LEN) - 1) << GLB_GAUGE_RX_FIFO_FLUSH_POS) +#define GLB_GAUGE_RX_FIFO_FLUSH_UMSK (~(((1U << GLB_GAUGE_RX_FIFO_FLUSH_LEN) - 1) << GLB_GAUGE_RX_FIFO_FLUSH_POS)) +#define GLB_GAUGE_RXO_INT_EN GLB_GAUGE_RXO_INT_EN +#define GLB_GAUGE_RXO_INT_EN_POS (1U) +#define GLB_GAUGE_RXO_INT_EN_LEN (1U) +#define GLB_GAUGE_RXO_INT_EN_MSK (((1U << GLB_GAUGE_RXO_INT_EN_LEN) - 1) << GLB_GAUGE_RXO_INT_EN_POS) +#define GLB_GAUGE_RXO_INT_EN_UMSK (~(((1U << GLB_GAUGE_RXO_INT_EN_LEN) - 1) << GLB_GAUGE_RXO_INT_EN_POS)) +#define GLB_GAUGE_RXU_INT_EN GLB_GAUGE_RXU_INT_EN +#define GLB_GAUGE_RXU_INT_EN_POS (2U) +#define GLB_GAUGE_RXU_INT_EN_LEN (1U) +#define GLB_GAUGE_RXU_INT_EN_MSK (((1U << GLB_GAUGE_RXU_INT_EN_LEN) - 1) << GLB_GAUGE_RXU_INT_EN_POS) +#define GLB_GAUGE_RXU_INT_EN_UMSK (~(((1U << GLB_GAUGE_RXU_INT_EN_LEN) - 1) << GLB_GAUGE_RXU_INT_EN_POS)) +#define GLB_GAUGE_RXA_INT_EN GLB_GAUGE_RXA_INT_EN +#define GLB_GAUGE_RXA_INT_EN_POS (3U) +#define GLB_GAUGE_RXA_INT_EN_LEN (1U) +#define GLB_GAUGE_RXA_INT_EN_MSK (((1U << GLB_GAUGE_RXA_INT_EN_LEN) - 1) << GLB_GAUGE_RXA_INT_EN_POS) +#define GLB_GAUGE_RXA_INT_EN_UMSK (~(((1U << GLB_GAUGE_RXA_INT_EN_LEN) - 1) << GLB_GAUGE_RXA_INT_EN_POS)) +#define GLB_GAUGE_RX_DRQ_EN GLB_GAUGE_RX_DRQ_EN +#define GLB_GAUGE_RX_DRQ_EN_POS (4U) +#define GLB_GAUGE_RX_DRQ_EN_LEN (1U) +#define GLB_GAUGE_RX_DRQ_EN_MSK (((1U << GLB_GAUGE_RX_DRQ_EN_LEN) - 1) << GLB_GAUGE_RX_DRQ_EN_POS) +#define GLB_GAUGE_RX_DRQ_EN_UMSK (~(((1U << GLB_GAUGE_RX_DRQ_EN_LEN) - 1) << GLB_GAUGE_RX_DRQ_EN_POS)) +#define GLB_GAUGE_RX_DATA_RES GLB_GAUGE_RX_DATA_RES +#define GLB_GAUGE_RX_DATA_RES_POS (5U) +#define GLB_GAUGE_RX_DATA_RES_LEN (1U) +#define GLB_GAUGE_RX_DATA_RES_MSK (((1U << GLB_GAUGE_RX_DATA_RES_LEN) - 1) << GLB_GAUGE_RX_DATA_RES_POS) +#define GLB_GAUGE_RX_DATA_RES_UMSK (~(((1U << GLB_GAUGE_RX_DATA_RES_LEN) - 1) << GLB_GAUGE_RX_DATA_RES_POS)) +#define GLB_GAUGE_RX_CH_EN GLB_GAUGE_RX_CH_EN +#define GLB_GAUGE_RX_CH_EN_POS (8U) +#define GLB_GAUGE_RX_CH_EN_LEN (1U) +#define GLB_GAUGE_RX_CH_EN_MSK (((1U << GLB_GAUGE_RX_CH_EN_LEN) - 1) << GLB_GAUGE_RX_CH_EN_POS) +#define GLB_GAUGE_RX_CH_EN_UMSK (~(((1U << GLB_GAUGE_RX_CH_EN_LEN) - 1) << GLB_GAUGE_RX_CH_EN_POS)) +#define GLB_GAUGE_RX_DRQ_CNT GLB_GAUGE_RX_DRQ_CNT +#define GLB_GAUGE_RX_DRQ_CNT_POS (14U) +#define GLB_GAUGE_RX_DRQ_CNT_LEN (2U) +#define GLB_GAUGE_RX_DRQ_CNT_MSK (((1U << GLB_GAUGE_RX_DRQ_CNT_LEN) - 1) << GLB_GAUGE_RX_DRQ_CNT_POS) +#define GLB_GAUGE_RX_DRQ_CNT_UMSK (~(((1U << GLB_GAUGE_RX_DRQ_CNT_LEN) - 1) << GLB_GAUGE_RX_DRQ_CNT_POS)) +#define GLB_GAUGE_RX_TRG_LEVEL GLB_GAUGE_RX_TRG_LEVEL +#define GLB_GAUGE_RX_TRG_LEVEL_POS (16U) +#define GLB_GAUGE_RX_TRG_LEVEL_LEN (3U) +#define GLB_GAUGE_RX_TRG_LEVEL_MSK (((1U << GLB_GAUGE_RX_TRG_LEVEL_LEN) - 1) << GLB_GAUGE_RX_TRG_LEVEL_POS) +#define GLB_GAUGE_RX_TRG_LEVEL_UMSK (~(((1U << GLB_GAUGE_RX_TRG_LEVEL_LEN) - 1) << GLB_GAUGE_RX_TRG_LEVEL_POS)) +#define GLB_GAUGE_RX_DATA_MODE GLB_GAUGE_RX_DATA_MODE +#define GLB_GAUGE_RX_DATA_MODE_POS (24U) +#define GLB_GAUGE_RX_DATA_MODE_LEN (2U) +#define GLB_GAUGE_RX_DATA_MODE_MSK (((1U << GLB_GAUGE_RX_DATA_MODE_LEN) - 1) << GLB_GAUGE_RX_DATA_MODE_POS) +#define GLB_GAUGE_RX_DATA_MODE_UMSK (~(((1U << GLB_GAUGE_RX_DATA_MODE_LEN) - 1) << GLB_GAUGE_RX_DATA_MODE_POS)) + +/* 0x8BC : gauge_rx_fifo_status */ +#define GLB_GAUGE_RX_FIFO_STATUS_OFFSET (0x8BC) +#define GLB_GAUGE_RXO_INT GLB_GAUGE_RXO_INT +#define GLB_GAUGE_RXO_INT_POS (1U) +#define GLB_GAUGE_RXO_INT_LEN (1U) +#define GLB_GAUGE_RXO_INT_MSK (((1U << GLB_GAUGE_RXO_INT_LEN) - 1) << GLB_GAUGE_RXO_INT_POS) +#define GLB_GAUGE_RXO_INT_UMSK (~(((1U << GLB_GAUGE_RXO_INT_LEN) - 1) << GLB_GAUGE_RXO_INT_POS)) +#define GLB_GAUGE_RXU_INT GLB_GAUGE_RXU_INT +#define GLB_GAUGE_RXU_INT_POS (2U) +#define GLB_GAUGE_RXU_INT_LEN (1U) +#define GLB_GAUGE_RXU_INT_MSK (((1U << GLB_GAUGE_RXU_INT_LEN) - 1) << GLB_GAUGE_RXU_INT_POS) +#define GLB_GAUGE_RXU_INT_UMSK (~(((1U << GLB_GAUGE_RXU_INT_LEN) - 1) << GLB_GAUGE_RXU_INT_POS)) +#define GLB_GAUGE_RXA_INT GLB_GAUGE_RXA_INT +#define GLB_GAUGE_RXA_INT_POS (4U) +#define GLB_GAUGE_RXA_INT_LEN (1U) +#define GLB_GAUGE_RXA_INT_MSK (((1U << GLB_GAUGE_RXA_INT_LEN) - 1) << GLB_GAUGE_RXA_INT_POS) +#define GLB_GAUGE_RXA_INT_UMSK (~(((1U << GLB_GAUGE_RXA_INT_LEN) - 1) << GLB_GAUGE_RXA_INT_POS)) +#define GLB_GAUGE_RXA_CNT GLB_GAUGE_RXA_CNT +#define GLB_GAUGE_RXA_CNT_POS (16U) +#define GLB_GAUGE_RXA_CNT_LEN (3U) +#define GLB_GAUGE_RXA_CNT_MSK (((1U << GLB_GAUGE_RXA_CNT_LEN) - 1) << GLB_GAUGE_RXA_CNT_POS) +#define GLB_GAUGE_RXA_CNT_UMSK (~(((1U << GLB_GAUGE_RXA_CNT_LEN) - 1) << GLB_GAUGE_RXA_CNT_POS)) +#define GLB_GAUGE_RXA GLB_GAUGE_RXA +#define GLB_GAUGE_RXA_POS (24U) +#define GLB_GAUGE_RXA_LEN (1U) +#define GLB_GAUGE_RXA_MSK (((1U << GLB_GAUGE_RXA_LEN) - 1) << GLB_GAUGE_RXA_POS) +#define GLB_GAUGE_RXA_UMSK (~(((1U << GLB_GAUGE_RXA_LEN) - 1) << GLB_GAUGE_RXA_POS)) + +/* 0x8C0 : gauge_rx_fifo_data */ +#define GLB_GAUGE_RX_FIFO_DATA_OFFSET (0x8C0) +#define GLB_GAUGE_RX_DATA GLB_GAUGE_RX_DATA +#define GLB_GAUGE_RX_DATA_POS (0U) +#define GLB_GAUGE_RX_DATA_LEN (32U) +#define GLB_GAUGE_RX_DATA_MSK (((1U << GLB_GAUGE_RX_DATA_LEN) - 1) << GLB_GAUGE_RX_DATA_POS) +#define GLB_GAUGE_RX_DATA_UMSK (~(((1U << GLB_GAUGE_RX_DATA_LEN) - 1) << GLB_GAUGE_RX_DATA_POS)) + +/* 0x8C4 : gpio_cfg0 */ +#define GLB_GPIO_CFG0_OFFSET (0x8C4) +#define GLB_REG_GPIO_0_IE GLB_REG_GPIO_0_IE +#define GLB_REG_GPIO_0_IE_POS (0U) +#define GLB_REG_GPIO_0_IE_LEN (1U) +#define GLB_REG_GPIO_0_IE_MSK (((1U << GLB_REG_GPIO_0_IE_LEN) - 1) << GLB_REG_GPIO_0_IE_POS) +#define GLB_REG_GPIO_0_IE_UMSK (~(((1U << GLB_REG_GPIO_0_IE_LEN) - 1) << GLB_REG_GPIO_0_IE_POS)) +#define GLB_REG_GPIO_0_SMT GLB_REG_GPIO_0_SMT +#define GLB_REG_GPIO_0_SMT_POS (1U) +#define GLB_REG_GPIO_0_SMT_LEN (1U) +#define GLB_REG_GPIO_0_SMT_MSK (((1U << GLB_REG_GPIO_0_SMT_LEN) - 1) << GLB_REG_GPIO_0_SMT_POS) +#define GLB_REG_GPIO_0_SMT_UMSK (~(((1U << GLB_REG_GPIO_0_SMT_LEN) - 1) << GLB_REG_GPIO_0_SMT_POS)) +#define GLB_REG_GPIO_0_DRV GLB_REG_GPIO_0_DRV +#define GLB_REG_GPIO_0_DRV_POS (2U) +#define GLB_REG_GPIO_0_DRV_LEN (2U) +#define GLB_REG_GPIO_0_DRV_MSK (((1U << GLB_REG_GPIO_0_DRV_LEN) - 1) << GLB_REG_GPIO_0_DRV_POS) +#define GLB_REG_GPIO_0_DRV_UMSK (~(((1U << GLB_REG_GPIO_0_DRV_LEN) - 1) << GLB_REG_GPIO_0_DRV_POS)) +#define GLB_REG_GPIO_0_PU GLB_REG_GPIO_0_PU +#define GLB_REG_GPIO_0_PU_POS (4U) +#define GLB_REG_GPIO_0_PU_LEN (1U) +#define GLB_REG_GPIO_0_PU_MSK (((1U << GLB_REG_GPIO_0_PU_LEN) - 1) << GLB_REG_GPIO_0_PU_POS) +#define GLB_REG_GPIO_0_PU_UMSK (~(((1U << GLB_REG_GPIO_0_PU_LEN) - 1) << GLB_REG_GPIO_0_PU_POS)) +#define GLB_REG_GPIO_0_PD GLB_REG_GPIO_0_PD +#define GLB_REG_GPIO_0_PD_POS (5U) +#define GLB_REG_GPIO_0_PD_LEN (1U) +#define GLB_REG_GPIO_0_PD_MSK (((1U << GLB_REG_GPIO_0_PD_LEN) - 1) << GLB_REG_GPIO_0_PD_POS) +#define GLB_REG_GPIO_0_PD_UMSK (~(((1U << GLB_REG_GPIO_0_PD_LEN) - 1) << GLB_REG_GPIO_0_PD_POS)) +#define GLB_REG_GPIO_0_OE GLB_REG_GPIO_0_OE +#define GLB_REG_GPIO_0_OE_POS (6U) +#define GLB_REG_GPIO_0_OE_LEN (1U) +#define GLB_REG_GPIO_0_OE_MSK (((1U << GLB_REG_GPIO_0_OE_LEN) - 1) << GLB_REG_GPIO_0_OE_POS) +#define GLB_REG_GPIO_0_OE_UMSK (~(((1U << GLB_REG_GPIO_0_OE_LEN) - 1) << GLB_REG_GPIO_0_OE_POS)) +#define GLB_REG_GPIO_0_FUNC_SEL GLB_REG_GPIO_0_FUNC_SEL +#define GLB_REG_GPIO_0_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_0_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_0_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_0_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_0_FUNC_SEL_POS) +#define GLB_REG_GPIO_0_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_0_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_0_FUNC_SEL_POS)) +#define GLB_REG_GPIO_0_INT_MODE_SET GLB_REG_GPIO_0_INT_MODE_SET +#define GLB_REG_GPIO_0_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_0_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_0_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_0_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_0_INT_MODE_SET_POS) +#define GLB_REG_GPIO_0_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_0_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_0_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_0_INT_CLR GLB_REG_GPIO_0_INT_CLR +#define GLB_REG_GPIO_0_INT_CLR_POS (20U) +#define GLB_REG_GPIO_0_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_0_INT_CLR_MSK (((1U << GLB_REG_GPIO_0_INT_CLR_LEN) - 1) << GLB_REG_GPIO_0_INT_CLR_POS) +#define GLB_REG_GPIO_0_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_0_INT_CLR_LEN) - 1) << GLB_REG_GPIO_0_INT_CLR_POS)) +#define GLB_GPIO_0_INT_STAT GLB_GPIO_0_INT_STAT +#define GLB_GPIO_0_INT_STAT_POS (21U) +#define GLB_GPIO_0_INT_STAT_LEN (1U) +#define GLB_GPIO_0_INT_STAT_MSK (((1U << GLB_GPIO_0_INT_STAT_LEN) - 1) << GLB_GPIO_0_INT_STAT_POS) +#define GLB_GPIO_0_INT_STAT_UMSK (~(((1U << GLB_GPIO_0_INT_STAT_LEN) - 1) << GLB_GPIO_0_INT_STAT_POS)) +#define GLB_REG_GPIO_0_INT_MASK GLB_REG_GPIO_0_INT_MASK +#define GLB_REG_GPIO_0_INT_MASK_POS (22U) +#define GLB_REG_GPIO_0_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_0_INT_MASK_MSK (((1U << GLB_REG_GPIO_0_INT_MASK_LEN) - 1) << GLB_REG_GPIO_0_INT_MASK_POS) +#define GLB_REG_GPIO_0_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_0_INT_MASK_LEN) - 1) << GLB_REG_GPIO_0_INT_MASK_POS)) +#define GLB_REG_GPIO_0_O GLB_REG_GPIO_0_O +#define GLB_REG_GPIO_0_O_POS (24U) +#define GLB_REG_GPIO_0_O_LEN (1U) +#define GLB_REG_GPIO_0_O_MSK (((1U << GLB_REG_GPIO_0_O_LEN) - 1) << GLB_REG_GPIO_0_O_POS) +#define GLB_REG_GPIO_0_O_UMSK (~(((1U << GLB_REG_GPIO_0_O_LEN) - 1) << GLB_REG_GPIO_0_O_POS)) +#define GLB_REG_GPIO_0_SET GLB_REG_GPIO_0_SET +#define GLB_REG_GPIO_0_SET_POS (25U) +#define GLB_REG_GPIO_0_SET_LEN (1U) +#define GLB_REG_GPIO_0_SET_MSK (((1U << GLB_REG_GPIO_0_SET_LEN) - 1) << GLB_REG_GPIO_0_SET_POS) +#define GLB_REG_GPIO_0_SET_UMSK (~(((1U << GLB_REG_GPIO_0_SET_LEN) - 1) << GLB_REG_GPIO_0_SET_POS)) +#define GLB_REG_GPIO_0_CLR GLB_REG_GPIO_0_CLR +#define GLB_REG_GPIO_0_CLR_POS (26U) +#define GLB_REG_GPIO_0_CLR_LEN (1U) +#define GLB_REG_GPIO_0_CLR_MSK (((1U << GLB_REG_GPIO_0_CLR_LEN) - 1) << GLB_REG_GPIO_0_CLR_POS) +#define GLB_REG_GPIO_0_CLR_UMSK (~(((1U << GLB_REG_GPIO_0_CLR_LEN) - 1) << GLB_REG_GPIO_0_CLR_POS)) +#define GLB_REG_GPIO_0_I GLB_REG_GPIO_0_I +#define GLB_REG_GPIO_0_I_POS (28U) +#define GLB_REG_GPIO_0_I_LEN (1U) +#define GLB_REG_GPIO_0_I_MSK (((1U << GLB_REG_GPIO_0_I_LEN) - 1) << GLB_REG_GPIO_0_I_POS) +#define GLB_REG_GPIO_0_I_UMSK (~(((1U << GLB_REG_GPIO_0_I_LEN) - 1) << GLB_REG_GPIO_0_I_POS)) +#define GLB_REG_GPIO_0_MODE GLB_REG_GPIO_0_MODE +#define GLB_REG_GPIO_0_MODE_POS (30U) +#define GLB_REG_GPIO_0_MODE_LEN (2U) +#define GLB_REG_GPIO_0_MODE_MSK (((1U << GLB_REG_GPIO_0_MODE_LEN) - 1) << GLB_REG_GPIO_0_MODE_POS) +#define GLB_REG_GPIO_0_MODE_UMSK (~(((1U << GLB_REG_GPIO_0_MODE_LEN) - 1) << GLB_REG_GPIO_0_MODE_POS)) + +/* 0x8C8 : gpio_cfg1 */ +#define GLB_GPIO_CFG1_OFFSET (0x8C8) +#define GLB_REG_GPIO_1_IE GLB_REG_GPIO_1_IE +#define GLB_REG_GPIO_1_IE_POS (0U) +#define GLB_REG_GPIO_1_IE_LEN (1U) +#define GLB_REG_GPIO_1_IE_MSK (((1U << GLB_REG_GPIO_1_IE_LEN) - 1) << GLB_REG_GPIO_1_IE_POS) +#define GLB_REG_GPIO_1_IE_UMSK (~(((1U << GLB_REG_GPIO_1_IE_LEN) - 1) << GLB_REG_GPIO_1_IE_POS)) +#define GLB_REG_GPIO_1_SMT GLB_REG_GPIO_1_SMT +#define GLB_REG_GPIO_1_SMT_POS (1U) +#define GLB_REG_GPIO_1_SMT_LEN (1U) +#define GLB_REG_GPIO_1_SMT_MSK (((1U << GLB_REG_GPIO_1_SMT_LEN) - 1) << GLB_REG_GPIO_1_SMT_POS) +#define GLB_REG_GPIO_1_SMT_UMSK (~(((1U << GLB_REG_GPIO_1_SMT_LEN) - 1) << GLB_REG_GPIO_1_SMT_POS)) +#define GLB_REG_GPIO_1_DRV GLB_REG_GPIO_1_DRV +#define GLB_REG_GPIO_1_DRV_POS (2U) +#define GLB_REG_GPIO_1_DRV_LEN (2U) +#define GLB_REG_GPIO_1_DRV_MSK (((1U << GLB_REG_GPIO_1_DRV_LEN) - 1) << GLB_REG_GPIO_1_DRV_POS) +#define GLB_REG_GPIO_1_DRV_UMSK (~(((1U << GLB_REG_GPIO_1_DRV_LEN) - 1) << GLB_REG_GPIO_1_DRV_POS)) +#define GLB_REG_GPIO_1_PU GLB_REG_GPIO_1_PU +#define GLB_REG_GPIO_1_PU_POS (4U) +#define GLB_REG_GPIO_1_PU_LEN (1U) +#define GLB_REG_GPIO_1_PU_MSK (((1U << GLB_REG_GPIO_1_PU_LEN) - 1) << GLB_REG_GPIO_1_PU_POS) +#define GLB_REG_GPIO_1_PU_UMSK (~(((1U << GLB_REG_GPIO_1_PU_LEN) - 1) << GLB_REG_GPIO_1_PU_POS)) +#define GLB_REG_GPIO_1_PD GLB_REG_GPIO_1_PD +#define GLB_REG_GPIO_1_PD_POS (5U) +#define GLB_REG_GPIO_1_PD_LEN (1U) +#define GLB_REG_GPIO_1_PD_MSK (((1U << GLB_REG_GPIO_1_PD_LEN) - 1) << GLB_REG_GPIO_1_PD_POS) +#define GLB_REG_GPIO_1_PD_UMSK (~(((1U << GLB_REG_GPIO_1_PD_LEN) - 1) << GLB_REG_GPIO_1_PD_POS)) +#define GLB_REG_GPIO_1_OE GLB_REG_GPIO_1_OE +#define GLB_REG_GPIO_1_OE_POS (6U) +#define GLB_REG_GPIO_1_OE_LEN (1U) +#define GLB_REG_GPIO_1_OE_MSK (((1U << GLB_REG_GPIO_1_OE_LEN) - 1) << GLB_REG_GPIO_1_OE_POS) +#define GLB_REG_GPIO_1_OE_UMSK (~(((1U << GLB_REG_GPIO_1_OE_LEN) - 1) << GLB_REG_GPIO_1_OE_POS)) +#define GLB_REG_GPIO_1_FUNC_SEL GLB_REG_GPIO_1_FUNC_SEL +#define GLB_REG_GPIO_1_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_1_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_1_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_1_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_1_FUNC_SEL_POS) +#define GLB_REG_GPIO_1_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_1_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_1_FUNC_SEL_POS)) +#define GLB_REG_GPIO_1_INT_MODE_SET GLB_REG_GPIO_1_INT_MODE_SET +#define GLB_REG_GPIO_1_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_1_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_1_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_1_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_1_INT_MODE_SET_POS) +#define GLB_REG_GPIO_1_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_1_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_1_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_1_INT_CLR GLB_REG_GPIO_1_INT_CLR +#define GLB_REG_GPIO_1_INT_CLR_POS (20U) +#define GLB_REG_GPIO_1_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_1_INT_CLR_MSK (((1U << GLB_REG_GPIO_1_INT_CLR_LEN) - 1) << GLB_REG_GPIO_1_INT_CLR_POS) +#define GLB_REG_GPIO_1_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_1_INT_CLR_LEN) - 1) << GLB_REG_GPIO_1_INT_CLR_POS)) +#define GLB_GPIO_1_INT_STAT GLB_GPIO_1_INT_STAT +#define GLB_GPIO_1_INT_STAT_POS (21U) +#define GLB_GPIO_1_INT_STAT_LEN (1U) +#define GLB_GPIO_1_INT_STAT_MSK (((1U << GLB_GPIO_1_INT_STAT_LEN) - 1) << GLB_GPIO_1_INT_STAT_POS) +#define GLB_GPIO_1_INT_STAT_UMSK (~(((1U << GLB_GPIO_1_INT_STAT_LEN) - 1) << GLB_GPIO_1_INT_STAT_POS)) +#define GLB_REG_GPIO_1_INT_MASK GLB_REG_GPIO_1_INT_MASK +#define GLB_REG_GPIO_1_INT_MASK_POS (22U) +#define GLB_REG_GPIO_1_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_1_INT_MASK_MSK (((1U << GLB_REG_GPIO_1_INT_MASK_LEN) - 1) << GLB_REG_GPIO_1_INT_MASK_POS) +#define GLB_REG_GPIO_1_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_1_INT_MASK_LEN) - 1) << GLB_REG_GPIO_1_INT_MASK_POS)) +#define GLB_REG_GPIO_1_O GLB_REG_GPIO_1_O +#define GLB_REG_GPIO_1_O_POS (24U) +#define GLB_REG_GPIO_1_O_LEN (1U) +#define GLB_REG_GPIO_1_O_MSK (((1U << GLB_REG_GPIO_1_O_LEN) - 1) << GLB_REG_GPIO_1_O_POS) +#define GLB_REG_GPIO_1_O_UMSK (~(((1U << GLB_REG_GPIO_1_O_LEN) - 1) << GLB_REG_GPIO_1_O_POS)) +#define GLB_REG_GPIO_1_SET GLB_REG_GPIO_1_SET +#define GLB_REG_GPIO_1_SET_POS (25U) +#define GLB_REG_GPIO_1_SET_LEN (1U) +#define GLB_REG_GPIO_1_SET_MSK (((1U << GLB_REG_GPIO_1_SET_LEN) - 1) << GLB_REG_GPIO_1_SET_POS) +#define GLB_REG_GPIO_1_SET_UMSK (~(((1U << GLB_REG_GPIO_1_SET_LEN) - 1) << GLB_REG_GPIO_1_SET_POS)) +#define GLB_REG_GPIO_1_CLR GLB_REG_GPIO_1_CLR +#define GLB_REG_GPIO_1_CLR_POS (26U) +#define GLB_REG_GPIO_1_CLR_LEN (1U) +#define GLB_REG_GPIO_1_CLR_MSK (((1U << GLB_REG_GPIO_1_CLR_LEN) - 1) << GLB_REG_GPIO_1_CLR_POS) +#define GLB_REG_GPIO_1_CLR_UMSK (~(((1U << GLB_REG_GPIO_1_CLR_LEN) - 1) << GLB_REG_GPIO_1_CLR_POS)) +#define GLB_REG_GPIO_1_I GLB_REG_GPIO_1_I +#define GLB_REG_GPIO_1_I_POS (28U) +#define GLB_REG_GPIO_1_I_LEN (1U) +#define GLB_REG_GPIO_1_I_MSK (((1U << GLB_REG_GPIO_1_I_LEN) - 1) << GLB_REG_GPIO_1_I_POS) +#define GLB_REG_GPIO_1_I_UMSK (~(((1U << GLB_REG_GPIO_1_I_LEN) - 1) << GLB_REG_GPIO_1_I_POS)) +#define GLB_REG_GPIO_1_MODE GLB_REG_GPIO_1_MODE +#define GLB_REG_GPIO_1_MODE_POS (30U) +#define GLB_REG_GPIO_1_MODE_LEN (2U) +#define GLB_REG_GPIO_1_MODE_MSK (((1U << GLB_REG_GPIO_1_MODE_LEN) - 1) << GLB_REG_GPIO_1_MODE_POS) +#define GLB_REG_GPIO_1_MODE_UMSK (~(((1U << GLB_REG_GPIO_1_MODE_LEN) - 1) << GLB_REG_GPIO_1_MODE_POS)) + +/* 0x8CC : gpio_cfg2 */ +#define GLB_GPIO_CFG2_OFFSET (0x8CC) +#define GLB_REG_GPIO_2_IE GLB_REG_GPIO_2_IE +#define GLB_REG_GPIO_2_IE_POS (0U) +#define GLB_REG_GPIO_2_IE_LEN (1U) +#define GLB_REG_GPIO_2_IE_MSK (((1U << GLB_REG_GPIO_2_IE_LEN) - 1) << GLB_REG_GPIO_2_IE_POS) +#define GLB_REG_GPIO_2_IE_UMSK (~(((1U << GLB_REG_GPIO_2_IE_LEN) - 1) << GLB_REG_GPIO_2_IE_POS)) +#define GLB_REG_GPIO_2_SMT GLB_REG_GPIO_2_SMT +#define GLB_REG_GPIO_2_SMT_POS (1U) +#define GLB_REG_GPIO_2_SMT_LEN (1U) +#define GLB_REG_GPIO_2_SMT_MSK (((1U << GLB_REG_GPIO_2_SMT_LEN) - 1) << GLB_REG_GPIO_2_SMT_POS) +#define GLB_REG_GPIO_2_SMT_UMSK (~(((1U << GLB_REG_GPIO_2_SMT_LEN) - 1) << GLB_REG_GPIO_2_SMT_POS)) +#define GLB_REG_GPIO_2_DRV GLB_REG_GPIO_2_DRV +#define GLB_REG_GPIO_2_DRV_POS (2U) +#define GLB_REG_GPIO_2_DRV_LEN (2U) +#define GLB_REG_GPIO_2_DRV_MSK (((1U << GLB_REG_GPIO_2_DRV_LEN) - 1) << GLB_REG_GPIO_2_DRV_POS) +#define GLB_REG_GPIO_2_DRV_UMSK (~(((1U << GLB_REG_GPIO_2_DRV_LEN) - 1) << GLB_REG_GPIO_2_DRV_POS)) +#define GLB_REG_GPIO_2_PU GLB_REG_GPIO_2_PU +#define GLB_REG_GPIO_2_PU_POS (4U) +#define GLB_REG_GPIO_2_PU_LEN (1U) +#define GLB_REG_GPIO_2_PU_MSK (((1U << GLB_REG_GPIO_2_PU_LEN) - 1) << GLB_REG_GPIO_2_PU_POS) +#define GLB_REG_GPIO_2_PU_UMSK (~(((1U << GLB_REG_GPIO_2_PU_LEN) - 1) << GLB_REG_GPIO_2_PU_POS)) +#define GLB_REG_GPIO_2_PD GLB_REG_GPIO_2_PD +#define GLB_REG_GPIO_2_PD_POS (5U) +#define GLB_REG_GPIO_2_PD_LEN (1U) +#define GLB_REG_GPIO_2_PD_MSK (((1U << GLB_REG_GPIO_2_PD_LEN) - 1) << GLB_REG_GPIO_2_PD_POS) +#define GLB_REG_GPIO_2_PD_UMSK (~(((1U << GLB_REG_GPIO_2_PD_LEN) - 1) << GLB_REG_GPIO_2_PD_POS)) +#define GLB_REG_GPIO_2_OE GLB_REG_GPIO_2_OE +#define GLB_REG_GPIO_2_OE_POS (6U) +#define GLB_REG_GPIO_2_OE_LEN (1U) +#define GLB_REG_GPIO_2_OE_MSK (((1U << GLB_REG_GPIO_2_OE_LEN) - 1) << GLB_REG_GPIO_2_OE_POS) +#define GLB_REG_GPIO_2_OE_UMSK (~(((1U << GLB_REG_GPIO_2_OE_LEN) - 1) << GLB_REG_GPIO_2_OE_POS)) +#define GLB_REG_GPIO_2_FUNC_SEL GLB_REG_GPIO_2_FUNC_SEL +#define GLB_REG_GPIO_2_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_2_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_2_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_2_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_2_FUNC_SEL_POS) +#define GLB_REG_GPIO_2_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_2_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_2_FUNC_SEL_POS)) +#define GLB_REG_GPIO_2_INT_MODE_SET GLB_REG_GPIO_2_INT_MODE_SET +#define GLB_REG_GPIO_2_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_2_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_2_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_2_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_2_INT_MODE_SET_POS) +#define GLB_REG_GPIO_2_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_2_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_2_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_2_INT_CLR GLB_REG_GPIO_2_INT_CLR +#define GLB_REG_GPIO_2_INT_CLR_POS (20U) +#define GLB_REG_GPIO_2_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_2_INT_CLR_MSK (((1U << GLB_REG_GPIO_2_INT_CLR_LEN) - 1) << GLB_REG_GPIO_2_INT_CLR_POS) +#define GLB_REG_GPIO_2_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_2_INT_CLR_LEN) - 1) << GLB_REG_GPIO_2_INT_CLR_POS)) +#define GLB_GPIO_2_INT_STAT GLB_GPIO_2_INT_STAT +#define GLB_GPIO_2_INT_STAT_POS (21U) +#define GLB_GPIO_2_INT_STAT_LEN (1U) +#define GLB_GPIO_2_INT_STAT_MSK (((1U << GLB_GPIO_2_INT_STAT_LEN) - 1) << GLB_GPIO_2_INT_STAT_POS) +#define GLB_GPIO_2_INT_STAT_UMSK (~(((1U << GLB_GPIO_2_INT_STAT_LEN) - 1) << GLB_GPIO_2_INT_STAT_POS)) +#define GLB_REG_GPIO_2_INT_MASK GLB_REG_GPIO_2_INT_MASK +#define GLB_REG_GPIO_2_INT_MASK_POS (22U) +#define GLB_REG_GPIO_2_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_2_INT_MASK_MSK (((1U << GLB_REG_GPIO_2_INT_MASK_LEN) - 1) << GLB_REG_GPIO_2_INT_MASK_POS) +#define GLB_REG_GPIO_2_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_2_INT_MASK_LEN) - 1) << GLB_REG_GPIO_2_INT_MASK_POS)) +#define GLB_REG_GPIO_2_O GLB_REG_GPIO_2_O +#define GLB_REG_GPIO_2_O_POS (24U) +#define GLB_REG_GPIO_2_O_LEN (1U) +#define GLB_REG_GPIO_2_O_MSK (((1U << GLB_REG_GPIO_2_O_LEN) - 1) << GLB_REG_GPIO_2_O_POS) +#define GLB_REG_GPIO_2_O_UMSK (~(((1U << GLB_REG_GPIO_2_O_LEN) - 1) << GLB_REG_GPIO_2_O_POS)) +#define GLB_REG_GPIO_2_SET GLB_REG_GPIO_2_SET +#define GLB_REG_GPIO_2_SET_POS (25U) +#define GLB_REG_GPIO_2_SET_LEN (1U) +#define GLB_REG_GPIO_2_SET_MSK (((1U << GLB_REG_GPIO_2_SET_LEN) - 1) << GLB_REG_GPIO_2_SET_POS) +#define GLB_REG_GPIO_2_SET_UMSK (~(((1U << GLB_REG_GPIO_2_SET_LEN) - 1) << GLB_REG_GPIO_2_SET_POS)) +#define GLB_REG_GPIO_2_CLR GLB_REG_GPIO_2_CLR +#define GLB_REG_GPIO_2_CLR_POS (26U) +#define GLB_REG_GPIO_2_CLR_LEN (1U) +#define GLB_REG_GPIO_2_CLR_MSK (((1U << GLB_REG_GPIO_2_CLR_LEN) - 1) << GLB_REG_GPIO_2_CLR_POS) +#define GLB_REG_GPIO_2_CLR_UMSK (~(((1U << GLB_REG_GPIO_2_CLR_LEN) - 1) << GLB_REG_GPIO_2_CLR_POS)) +#define GLB_REG_GPIO_2_I GLB_REG_GPIO_2_I +#define GLB_REG_GPIO_2_I_POS (28U) +#define GLB_REG_GPIO_2_I_LEN (1U) +#define GLB_REG_GPIO_2_I_MSK (((1U << GLB_REG_GPIO_2_I_LEN) - 1) << GLB_REG_GPIO_2_I_POS) +#define GLB_REG_GPIO_2_I_UMSK (~(((1U << GLB_REG_GPIO_2_I_LEN) - 1) << GLB_REG_GPIO_2_I_POS)) +#define GLB_REG_GPIO_2_MODE GLB_REG_GPIO_2_MODE +#define GLB_REG_GPIO_2_MODE_POS (30U) +#define GLB_REG_GPIO_2_MODE_LEN (2U) +#define GLB_REG_GPIO_2_MODE_MSK (((1U << GLB_REG_GPIO_2_MODE_LEN) - 1) << GLB_REG_GPIO_2_MODE_POS) +#define GLB_REG_GPIO_2_MODE_UMSK (~(((1U << GLB_REG_GPIO_2_MODE_LEN) - 1) << GLB_REG_GPIO_2_MODE_POS)) + +/* 0x8D0 : gpio_cfg3 */ +#define GLB_GPIO_CFG3_OFFSET (0x8D0) +#define GLB_REG_GPIO_3_IE GLB_REG_GPIO_3_IE +#define GLB_REG_GPIO_3_IE_POS (0U) +#define GLB_REG_GPIO_3_IE_LEN (1U) +#define GLB_REG_GPIO_3_IE_MSK (((1U << GLB_REG_GPIO_3_IE_LEN) - 1) << GLB_REG_GPIO_3_IE_POS) +#define GLB_REG_GPIO_3_IE_UMSK (~(((1U << GLB_REG_GPIO_3_IE_LEN) - 1) << GLB_REG_GPIO_3_IE_POS)) +#define GLB_REG_GPIO_3_SMT GLB_REG_GPIO_3_SMT +#define GLB_REG_GPIO_3_SMT_POS (1U) +#define GLB_REG_GPIO_3_SMT_LEN (1U) +#define GLB_REG_GPIO_3_SMT_MSK (((1U << GLB_REG_GPIO_3_SMT_LEN) - 1) << GLB_REG_GPIO_3_SMT_POS) +#define GLB_REG_GPIO_3_SMT_UMSK (~(((1U << GLB_REG_GPIO_3_SMT_LEN) - 1) << GLB_REG_GPIO_3_SMT_POS)) +#define GLB_REG_GPIO_3_DRV GLB_REG_GPIO_3_DRV +#define GLB_REG_GPIO_3_DRV_POS (2U) +#define GLB_REG_GPIO_3_DRV_LEN (2U) +#define GLB_REG_GPIO_3_DRV_MSK (((1U << GLB_REG_GPIO_3_DRV_LEN) - 1) << GLB_REG_GPIO_3_DRV_POS) +#define GLB_REG_GPIO_3_DRV_UMSK (~(((1U << GLB_REG_GPIO_3_DRV_LEN) - 1) << GLB_REG_GPIO_3_DRV_POS)) +#define GLB_REG_GPIO_3_PU GLB_REG_GPIO_3_PU +#define GLB_REG_GPIO_3_PU_POS (4U) +#define GLB_REG_GPIO_3_PU_LEN (1U) +#define GLB_REG_GPIO_3_PU_MSK (((1U << GLB_REG_GPIO_3_PU_LEN) - 1) << GLB_REG_GPIO_3_PU_POS) +#define GLB_REG_GPIO_3_PU_UMSK (~(((1U << GLB_REG_GPIO_3_PU_LEN) - 1) << GLB_REG_GPIO_3_PU_POS)) +#define GLB_REG_GPIO_3_PD GLB_REG_GPIO_3_PD +#define GLB_REG_GPIO_3_PD_POS (5U) +#define GLB_REG_GPIO_3_PD_LEN (1U) +#define GLB_REG_GPIO_3_PD_MSK (((1U << GLB_REG_GPIO_3_PD_LEN) - 1) << GLB_REG_GPIO_3_PD_POS) +#define GLB_REG_GPIO_3_PD_UMSK (~(((1U << GLB_REG_GPIO_3_PD_LEN) - 1) << GLB_REG_GPIO_3_PD_POS)) +#define GLB_REG_GPIO_3_OE GLB_REG_GPIO_3_OE +#define GLB_REG_GPIO_3_OE_POS (6U) +#define GLB_REG_GPIO_3_OE_LEN (1U) +#define GLB_REG_GPIO_3_OE_MSK (((1U << GLB_REG_GPIO_3_OE_LEN) - 1) << GLB_REG_GPIO_3_OE_POS) +#define GLB_REG_GPIO_3_OE_UMSK (~(((1U << GLB_REG_GPIO_3_OE_LEN) - 1) << GLB_REG_GPIO_3_OE_POS)) +#define GLB_REG_GPIO_3_FUNC_SEL GLB_REG_GPIO_3_FUNC_SEL +#define GLB_REG_GPIO_3_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_3_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_3_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_3_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_3_FUNC_SEL_POS) +#define GLB_REG_GPIO_3_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_3_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_3_FUNC_SEL_POS)) +#define GLB_REG_GPIO_3_INT_MODE_SET GLB_REG_GPIO_3_INT_MODE_SET +#define GLB_REG_GPIO_3_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_3_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_3_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_3_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_3_INT_MODE_SET_POS) +#define GLB_REG_GPIO_3_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_3_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_3_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_3_INT_CLR GLB_REG_GPIO_3_INT_CLR +#define GLB_REG_GPIO_3_INT_CLR_POS (20U) +#define GLB_REG_GPIO_3_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_3_INT_CLR_MSK (((1U << GLB_REG_GPIO_3_INT_CLR_LEN) - 1) << GLB_REG_GPIO_3_INT_CLR_POS) +#define GLB_REG_GPIO_3_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_3_INT_CLR_LEN) - 1) << GLB_REG_GPIO_3_INT_CLR_POS)) +#define GLB_GPIO_3_INT_STAT GLB_GPIO_3_INT_STAT +#define GLB_GPIO_3_INT_STAT_POS (21U) +#define GLB_GPIO_3_INT_STAT_LEN (1U) +#define GLB_GPIO_3_INT_STAT_MSK (((1U << GLB_GPIO_3_INT_STAT_LEN) - 1) << GLB_GPIO_3_INT_STAT_POS) +#define GLB_GPIO_3_INT_STAT_UMSK (~(((1U << GLB_GPIO_3_INT_STAT_LEN) - 1) << GLB_GPIO_3_INT_STAT_POS)) +#define GLB_REG_GPIO_3_INT_MASK GLB_REG_GPIO_3_INT_MASK +#define GLB_REG_GPIO_3_INT_MASK_POS (22U) +#define GLB_REG_GPIO_3_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_3_INT_MASK_MSK (((1U << GLB_REG_GPIO_3_INT_MASK_LEN) - 1) << GLB_REG_GPIO_3_INT_MASK_POS) +#define GLB_REG_GPIO_3_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_3_INT_MASK_LEN) - 1) << GLB_REG_GPIO_3_INT_MASK_POS)) +#define GLB_REG_GPIO_3_O GLB_REG_GPIO_3_O +#define GLB_REG_GPIO_3_O_POS (24U) +#define GLB_REG_GPIO_3_O_LEN (1U) +#define GLB_REG_GPIO_3_O_MSK (((1U << GLB_REG_GPIO_3_O_LEN) - 1) << GLB_REG_GPIO_3_O_POS) +#define GLB_REG_GPIO_3_O_UMSK (~(((1U << GLB_REG_GPIO_3_O_LEN) - 1) << GLB_REG_GPIO_3_O_POS)) +#define GLB_REG_GPIO_3_SET GLB_REG_GPIO_3_SET +#define GLB_REG_GPIO_3_SET_POS (25U) +#define GLB_REG_GPIO_3_SET_LEN (1U) +#define GLB_REG_GPIO_3_SET_MSK (((1U << GLB_REG_GPIO_3_SET_LEN) - 1) << GLB_REG_GPIO_3_SET_POS) +#define GLB_REG_GPIO_3_SET_UMSK (~(((1U << GLB_REG_GPIO_3_SET_LEN) - 1) << GLB_REG_GPIO_3_SET_POS)) +#define GLB_REG_GPIO_3_CLR GLB_REG_GPIO_3_CLR +#define GLB_REG_GPIO_3_CLR_POS (26U) +#define GLB_REG_GPIO_3_CLR_LEN (1U) +#define GLB_REG_GPIO_3_CLR_MSK (((1U << GLB_REG_GPIO_3_CLR_LEN) - 1) << GLB_REG_GPIO_3_CLR_POS) +#define GLB_REG_GPIO_3_CLR_UMSK (~(((1U << GLB_REG_GPIO_3_CLR_LEN) - 1) << GLB_REG_GPIO_3_CLR_POS)) +#define GLB_REG_GPIO_3_I GLB_REG_GPIO_3_I +#define GLB_REG_GPIO_3_I_POS (28U) +#define GLB_REG_GPIO_3_I_LEN (1U) +#define GLB_REG_GPIO_3_I_MSK (((1U << GLB_REG_GPIO_3_I_LEN) - 1) << GLB_REG_GPIO_3_I_POS) +#define GLB_REG_GPIO_3_I_UMSK (~(((1U << GLB_REG_GPIO_3_I_LEN) - 1) << GLB_REG_GPIO_3_I_POS)) +#define GLB_REG_GPIO_3_MODE GLB_REG_GPIO_3_MODE +#define GLB_REG_GPIO_3_MODE_POS (30U) +#define GLB_REG_GPIO_3_MODE_LEN (2U) +#define GLB_REG_GPIO_3_MODE_MSK (((1U << GLB_REG_GPIO_3_MODE_LEN) - 1) << GLB_REG_GPIO_3_MODE_POS) +#define GLB_REG_GPIO_3_MODE_UMSK (~(((1U << GLB_REG_GPIO_3_MODE_LEN) - 1) << GLB_REG_GPIO_3_MODE_POS)) + +/* 0x8D4 : gpio_cfg4 */ +#define GLB_GPIO_CFG4_OFFSET (0x8D4) +#define GLB_REG_GPIO_4_IE GLB_REG_GPIO_4_IE +#define GLB_REG_GPIO_4_IE_POS (0U) +#define GLB_REG_GPIO_4_IE_LEN (1U) +#define GLB_REG_GPIO_4_IE_MSK (((1U << GLB_REG_GPIO_4_IE_LEN) - 1) << GLB_REG_GPIO_4_IE_POS) +#define GLB_REG_GPIO_4_IE_UMSK (~(((1U << GLB_REG_GPIO_4_IE_LEN) - 1) << GLB_REG_GPIO_4_IE_POS)) +#define GLB_REG_GPIO_4_SMT GLB_REG_GPIO_4_SMT +#define GLB_REG_GPIO_4_SMT_POS (1U) +#define GLB_REG_GPIO_4_SMT_LEN (1U) +#define GLB_REG_GPIO_4_SMT_MSK (((1U << GLB_REG_GPIO_4_SMT_LEN) - 1) << GLB_REG_GPIO_4_SMT_POS) +#define GLB_REG_GPIO_4_SMT_UMSK (~(((1U << GLB_REG_GPIO_4_SMT_LEN) - 1) << GLB_REG_GPIO_4_SMT_POS)) +#define GLB_REG_GPIO_4_DRV GLB_REG_GPIO_4_DRV +#define GLB_REG_GPIO_4_DRV_POS (2U) +#define GLB_REG_GPIO_4_DRV_LEN (2U) +#define GLB_REG_GPIO_4_DRV_MSK (((1U << GLB_REG_GPIO_4_DRV_LEN) - 1) << GLB_REG_GPIO_4_DRV_POS) +#define GLB_REG_GPIO_4_DRV_UMSK (~(((1U << GLB_REG_GPIO_4_DRV_LEN) - 1) << GLB_REG_GPIO_4_DRV_POS)) +#define GLB_REG_GPIO_4_PU GLB_REG_GPIO_4_PU +#define GLB_REG_GPIO_4_PU_POS (4U) +#define GLB_REG_GPIO_4_PU_LEN (1U) +#define GLB_REG_GPIO_4_PU_MSK (((1U << GLB_REG_GPIO_4_PU_LEN) - 1) << GLB_REG_GPIO_4_PU_POS) +#define GLB_REG_GPIO_4_PU_UMSK (~(((1U << GLB_REG_GPIO_4_PU_LEN) - 1) << GLB_REG_GPIO_4_PU_POS)) +#define GLB_REG_GPIO_4_PD GLB_REG_GPIO_4_PD +#define GLB_REG_GPIO_4_PD_POS (5U) +#define GLB_REG_GPIO_4_PD_LEN (1U) +#define GLB_REG_GPIO_4_PD_MSK (((1U << GLB_REG_GPIO_4_PD_LEN) - 1) << GLB_REG_GPIO_4_PD_POS) +#define GLB_REG_GPIO_4_PD_UMSK (~(((1U << GLB_REG_GPIO_4_PD_LEN) - 1) << GLB_REG_GPIO_4_PD_POS)) +#define GLB_REG_GPIO_4_OE GLB_REG_GPIO_4_OE +#define GLB_REG_GPIO_4_OE_POS (6U) +#define GLB_REG_GPIO_4_OE_LEN (1U) +#define GLB_REG_GPIO_4_OE_MSK (((1U << GLB_REG_GPIO_4_OE_LEN) - 1) << GLB_REG_GPIO_4_OE_POS) +#define GLB_REG_GPIO_4_OE_UMSK (~(((1U << GLB_REG_GPIO_4_OE_LEN) - 1) << GLB_REG_GPIO_4_OE_POS)) +#define GLB_REG_GPIO_4_FUNC_SEL GLB_REG_GPIO_4_FUNC_SEL +#define GLB_REG_GPIO_4_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_4_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_4_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_4_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_4_FUNC_SEL_POS) +#define GLB_REG_GPIO_4_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_4_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_4_FUNC_SEL_POS)) +#define GLB_REG_GPIO_4_INT_MODE_SET GLB_REG_GPIO_4_INT_MODE_SET +#define GLB_REG_GPIO_4_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_4_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_4_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_4_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_4_INT_MODE_SET_POS) +#define GLB_REG_GPIO_4_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_4_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_4_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_4_INT_CLR GLB_REG_GPIO_4_INT_CLR +#define GLB_REG_GPIO_4_INT_CLR_POS (20U) +#define GLB_REG_GPIO_4_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_4_INT_CLR_MSK (((1U << GLB_REG_GPIO_4_INT_CLR_LEN) - 1) << GLB_REG_GPIO_4_INT_CLR_POS) +#define GLB_REG_GPIO_4_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_4_INT_CLR_LEN) - 1) << GLB_REG_GPIO_4_INT_CLR_POS)) +#define GLB_GPIO_4_INT_STAT GLB_GPIO_4_INT_STAT +#define GLB_GPIO_4_INT_STAT_POS (21U) +#define GLB_GPIO_4_INT_STAT_LEN (1U) +#define GLB_GPIO_4_INT_STAT_MSK (((1U << GLB_GPIO_4_INT_STAT_LEN) - 1) << GLB_GPIO_4_INT_STAT_POS) +#define GLB_GPIO_4_INT_STAT_UMSK (~(((1U << GLB_GPIO_4_INT_STAT_LEN) - 1) << GLB_GPIO_4_INT_STAT_POS)) +#define GLB_REG_GPIO_4_INT_MASK GLB_REG_GPIO_4_INT_MASK +#define GLB_REG_GPIO_4_INT_MASK_POS (22U) +#define GLB_REG_GPIO_4_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_4_INT_MASK_MSK (((1U << GLB_REG_GPIO_4_INT_MASK_LEN) - 1) << GLB_REG_GPIO_4_INT_MASK_POS) +#define GLB_REG_GPIO_4_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_4_INT_MASK_LEN) - 1) << GLB_REG_GPIO_4_INT_MASK_POS)) +#define GLB_REG_GPIO_4_O GLB_REG_GPIO_4_O +#define GLB_REG_GPIO_4_O_POS (24U) +#define GLB_REG_GPIO_4_O_LEN (1U) +#define GLB_REG_GPIO_4_O_MSK (((1U << GLB_REG_GPIO_4_O_LEN) - 1) << GLB_REG_GPIO_4_O_POS) +#define GLB_REG_GPIO_4_O_UMSK (~(((1U << GLB_REG_GPIO_4_O_LEN) - 1) << GLB_REG_GPIO_4_O_POS)) +#define GLB_REG_GPIO_4_SET GLB_REG_GPIO_4_SET +#define GLB_REG_GPIO_4_SET_POS (25U) +#define GLB_REG_GPIO_4_SET_LEN (1U) +#define GLB_REG_GPIO_4_SET_MSK (((1U << GLB_REG_GPIO_4_SET_LEN) - 1) << GLB_REG_GPIO_4_SET_POS) +#define GLB_REG_GPIO_4_SET_UMSK (~(((1U << GLB_REG_GPIO_4_SET_LEN) - 1) << GLB_REG_GPIO_4_SET_POS)) +#define GLB_REG_GPIO_4_CLR GLB_REG_GPIO_4_CLR +#define GLB_REG_GPIO_4_CLR_POS (26U) +#define GLB_REG_GPIO_4_CLR_LEN (1U) +#define GLB_REG_GPIO_4_CLR_MSK (((1U << GLB_REG_GPIO_4_CLR_LEN) - 1) << GLB_REG_GPIO_4_CLR_POS) +#define GLB_REG_GPIO_4_CLR_UMSK (~(((1U << GLB_REG_GPIO_4_CLR_LEN) - 1) << GLB_REG_GPIO_4_CLR_POS)) +#define GLB_REG_GPIO_4_I GLB_REG_GPIO_4_I +#define GLB_REG_GPIO_4_I_POS (28U) +#define GLB_REG_GPIO_4_I_LEN (1U) +#define GLB_REG_GPIO_4_I_MSK (((1U << GLB_REG_GPIO_4_I_LEN) - 1) << GLB_REG_GPIO_4_I_POS) +#define GLB_REG_GPIO_4_I_UMSK (~(((1U << GLB_REG_GPIO_4_I_LEN) - 1) << GLB_REG_GPIO_4_I_POS)) +#define GLB_REG_GPIO_4_MODE GLB_REG_GPIO_4_MODE +#define GLB_REG_GPIO_4_MODE_POS (30U) +#define GLB_REG_GPIO_4_MODE_LEN (2U) +#define GLB_REG_GPIO_4_MODE_MSK (((1U << GLB_REG_GPIO_4_MODE_LEN) - 1) << GLB_REG_GPIO_4_MODE_POS) +#define GLB_REG_GPIO_4_MODE_UMSK (~(((1U << GLB_REG_GPIO_4_MODE_LEN) - 1) << GLB_REG_GPIO_4_MODE_POS)) + +/* 0x8D8 : gpio_cfg5 */ +#define GLB_GPIO_CFG5_OFFSET (0x8D8) +#define GLB_REG_GPIO_5_IE GLB_REG_GPIO_5_IE +#define GLB_REG_GPIO_5_IE_POS (0U) +#define GLB_REG_GPIO_5_IE_LEN (1U) +#define GLB_REG_GPIO_5_IE_MSK (((1U << GLB_REG_GPIO_5_IE_LEN) - 1) << GLB_REG_GPIO_5_IE_POS) +#define GLB_REG_GPIO_5_IE_UMSK (~(((1U << GLB_REG_GPIO_5_IE_LEN) - 1) << GLB_REG_GPIO_5_IE_POS)) +#define GLB_REG_GPIO_5_SMT GLB_REG_GPIO_5_SMT +#define GLB_REG_GPIO_5_SMT_POS (1U) +#define GLB_REG_GPIO_5_SMT_LEN (1U) +#define GLB_REG_GPIO_5_SMT_MSK (((1U << GLB_REG_GPIO_5_SMT_LEN) - 1) << GLB_REG_GPIO_5_SMT_POS) +#define GLB_REG_GPIO_5_SMT_UMSK (~(((1U << GLB_REG_GPIO_5_SMT_LEN) - 1) << GLB_REG_GPIO_5_SMT_POS)) +#define GLB_REG_GPIO_5_DRV GLB_REG_GPIO_5_DRV +#define GLB_REG_GPIO_5_DRV_POS (2U) +#define GLB_REG_GPIO_5_DRV_LEN (2U) +#define GLB_REG_GPIO_5_DRV_MSK (((1U << GLB_REG_GPIO_5_DRV_LEN) - 1) << GLB_REG_GPIO_5_DRV_POS) +#define GLB_REG_GPIO_5_DRV_UMSK (~(((1U << GLB_REG_GPIO_5_DRV_LEN) - 1) << GLB_REG_GPIO_5_DRV_POS)) +#define GLB_REG_GPIO_5_PU GLB_REG_GPIO_5_PU +#define GLB_REG_GPIO_5_PU_POS (4U) +#define GLB_REG_GPIO_5_PU_LEN (1U) +#define GLB_REG_GPIO_5_PU_MSK (((1U << GLB_REG_GPIO_5_PU_LEN) - 1) << GLB_REG_GPIO_5_PU_POS) +#define GLB_REG_GPIO_5_PU_UMSK (~(((1U << GLB_REG_GPIO_5_PU_LEN) - 1) << GLB_REG_GPIO_5_PU_POS)) +#define GLB_REG_GPIO_5_PD GLB_REG_GPIO_5_PD +#define GLB_REG_GPIO_5_PD_POS (5U) +#define GLB_REG_GPIO_5_PD_LEN (1U) +#define GLB_REG_GPIO_5_PD_MSK (((1U << GLB_REG_GPIO_5_PD_LEN) - 1) << GLB_REG_GPIO_5_PD_POS) +#define GLB_REG_GPIO_5_PD_UMSK (~(((1U << GLB_REG_GPIO_5_PD_LEN) - 1) << GLB_REG_GPIO_5_PD_POS)) +#define GLB_REG_GPIO_5_OE GLB_REG_GPIO_5_OE +#define GLB_REG_GPIO_5_OE_POS (6U) +#define GLB_REG_GPIO_5_OE_LEN (1U) +#define GLB_REG_GPIO_5_OE_MSK (((1U << GLB_REG_GPIO_5_OE_LEN) - 1) << GLB_REG_GPIO_5_OE_POS) +#define GLB_REG_GPIO_5_OE_UMSK (~(((1U << GLB_REG_GPIO_5_OE_LEN) - 1) << GLB_REG_GPIO_5_OE_POS)) +#define GLB_REG_GPIO_5_FUNC_SEL GLB_REG_GPIO_5_FUNC_SEL +#define GLB_REG_GPIO_5_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_5_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_5_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_5_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_5_FUNC_SEL_POS) +#define GLB_REG_GPIO_5_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_5_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_5_FUNC_SEL_POS)) +#define GLB_REG_GPIO_5_INT_MODE_SET GLB_REG_GPIO_5_INT_MODE_SET +#define GLB_REG_GPIO_5_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_5_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_5_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_5_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_5_INT_MODE_SET_POS) +#define GLB_REG_GPIO_5_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_5_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_5_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_5_INT_CLR GLB_REG_GPIO_5_INT_CLR +#define GLB_REG_GPIO_5_INT_CLR_POS (20U) +#define GLB_REG_GPIO_5_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_5_INT_CLR_MSK (((1U << GLB_REG_GPIO_5_INT_CLR_LEN) - 1) << GLB_REG_GPIO_5_INT_CLR_POS) +#define GLB_REG_GPIO_5_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_5_INT_CLR_LEN) - 1) << GLB_REG_GPIO_5_INT_CLR_POS)) +#define GLB_GPIO_5_INT_STAT GLB_GPIO_5_INT_STAT +#define GLB_GPIO_5_INT_STAT_POS (21U) +#define GLB_GPIO_5_INT_STAT_LEN (1U) +#define GLB_GPIO_5_INT_STAT_MSK (((1U << GLB_GPIO_5_INT_STAT_LEN) - 1) << GLB_GPIO_5_INT_STAT_POS) +#define GLB_GPIO_5_INT_STAT_UMSK (~(((1U << GLB_GPIO_5_INT_STAT_LEN) - 1) << GLB_GPIO_5_INT_STAT_POS)) +#define GLB_REG_GPIO_5_INT_MASK GLB_REG_GPIO_5_INT_MASK +#define GLB_REG_GPIO_5_INT_MASK_POS (22U) +#define GLB_REG_GPIO_5_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_5_INT_MASK_MSK (((1U << GLB_REG_GPIO_5_INT_MASK_LEN) - 1) << GLB_REG_GPIO_5_INT_MASK_POS) +#define GLB_REG_GPIO_5_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_5_INT_MASK_LEN) - 1) << GLB_REG_GPIO_5_INT_MASK_POS)) +#define GLB_REG_GPIO_5_O GLB_REG_GPIO_5_O +#define GLB_REG_GPIO_5_O_POS (24U) +#define GLB_REG_GPIO_5_O_LEN (1U) +#define GLB_REG_GPIO_5_O_MSK (((1U << GLB_REG_GPIO_5_O_LEN) - 1) << GLB_REG_GPIO_5_O_POS) +#define GLB_REG_GPIO_5_O_UMSK (~(((1U << GLB_REG_GPIO_5_O_LEN) - 1) << GLB_REG_GPIO_5_O_POS)) +#define GLB_REG_GPIO_5_SET GLB_REG_GPIO_5_SET +#define GLB_REG_GPIO_5_SET_POS (25U) +#define GLB_REG_GPIO_5_SET_LEN (1U) +#define GLB_REG_GPIO_5_SET_MSK (((1U << GLB_REG_GPIO_5_SET_LEN) - 1) << GLB_REG_GPIO_5_SET_POS) +#define GLB_REG_GPIO_5_SET_UMSK (~(((1U << GLB_REG_GPIO_5_SET_LEN) - 1) << GLB_REG_GPIO_5_SET_POS)) +#define GLB_REG_GPIO_5_CLR GLB_REG_GPIO_5_CLR +#define GLB_REG_GPIO_5_CLR_POS (26U) +#define GLB_REG_GPIO_5_CLR_LEN (1U) +#define GLB_REG_GPIO_5_CLR_MSK (((1U << GLB_REG_GPIO_5_CLR_LEN) - 1) << GLB_REG_GPIO_5_CLR_POS) +#define GLB_REG_GPIO_5_CLR_UMSK (~(((1U << GLB_REG_GPIO_5_CLR_LEN) - 1) << GLB_REG_GPIO_5_CLR_POS)) +#define GLB_REG_GPIO_5_I GLB_REG_GPIO_5_I +#define GLB_REG_GPIO_5_I_POS (28U) +#define GLB_REG_GPIO_5_I_LEN (1U) +#define GLB_REG_GPIO_5_I_MSK (((1U << GLB_REG_GPIO_5_I_LEN) - 1) << GLB_REG_GPIO_5_I_POS) +#define GLB_REG_GPIO_5_I_UMSK (~(((1U << GLB_REG_GPIO_5_I_LEN) - 1) << GLB_REG_GPIO_5_I_POS)) +#define GLB_REG_GPIO_5_MODE GLB_REG_GPIO_5_MODE +#define GLB_REG_GPIO_5_MODE_POS (30U) +#define GLB_REG_GPIO_5_MODE_LEN (2U) +#define GLB_REG_GPIO_5_MODE_MSK (((1U << GLB_REG_GPIO_5_MODE_LEN) - 1) << GLB_REG_GPIO_5_MODE_POS) +#define GLB_REG_GPIO_5_MODE_UMSK (~(((1U << GLB_REG_GPIO_5_MODE_LEN) - 1) << GLB_REG_GPIO_5_MODE_POS)) + +/* 0x8DC : gpio_cfg6 */ +#define GLB_GPIO_CFG6_OFFSET (0x8DC) +#define GLB_REG_GPIO_6_IE GLB_REG_GPIO_6_IE +#define GLB_REG_GPIO_6_IE_POS (0U) +#define GLB_REG_GPIO_6_IE_LEN (1U) +#define GLB_REG_GPIO_6_IE_MSK (((1U << GLB_REG_GPIO_6_IE_LEN) - 1) << GLB_REG_GPIO_6_IE_POS) +#define GLB_REG_GPIO_6_IE_UMSK (~(((1U << GLB_REG_GPIO_6_IE_LEN) - 1) << GLB_REG_GPIO_6_IE_POS)) +#define GLB_REG_GPIO_6_SMT GLB_REG_GPIO_6_SMT +#define GLB_REG_GPIO_6_SMT_POS (1U) +#define GLB_REG_GPIO_6_SMT_LEN (1U) +#define GLB_REG_GPIO_6_SMT_MSK (((1U << GLB_REG_GPIO_6_SMT_LEN) - 1) << GLB_REG_GPIO_6_SMT_POS) +#define GLB_REG_GPIO_6_SMT_UMSK (~(((1U << GLB_REG_GPIO_6_SMT_LEN) - 1) << GLB_REG_GPIO_6_SMT_POS)) +#define GLB_REG_GPIO_6_DRV GLB_REG_GPIO_6_DRV +#define GLB_REG_GPIO_6_DRV_POS (2U) +#define GLB_REG_GPIO_6_DRV_LEN (2U) +#define GLB_REG_GPIO_6_DRV_MSK (((1U << GLB_REG_GPIO_6_DRV_LEN) - 1) << GLB_REG_GPIO_6_DRV_POS) +#define GLB_REG_GPIO_6_DRV_UMSK (~(((1U << GLB_REG_GPIO_6_DRV_LEN) - 1) << GLB_REG_GPIO_6_DRV_POS)) +#define GLB_REG_GPIO_6_PU GLB_REG_GPIO_6_PU +#define GLB_REG_GPIO_6_PU_POS (4U) +#define GLB_REG_GPIO_6_PU_LEN (1U) +#define GLB_REG_GPIO_6_PU_MSK (((1U << GLB_REG_GPIO_6_PU_LEN) - 1) << GLB_REG_GPIO_6_PU_POS) +#define GLB_REG_GPIO_6_PU_UMSK (~(((1U << GLB_REG_GPIO_6_PU_LEN) - 1) << GLB_REG_GPIO_6_PU_POS)) +#define GLB_REG_GPIO_6_PD GLB_REG_GPIO_6_PD +#define GLB_REG_GPIO_6_PD_POS (5U) +#define GLB_REG_GPIO_6_PD_LEN (1U) +#define GLB_REG_GPIO_6_PD_MSK (((1U << GLB_REG_GPIO_6_PD_LEN) - 1) << GLB_REG_GPIO_6_PD_POS) +#define GLB_REG_GPIO_6_PD_UMSK (~(((1U << GLB_REG_GPIO_6_PD_LEN) - 1) << GLB_REG_GPIO_6_PD_POS)) +#define GLB_REG_GPIO_6_OE GLB_REG_GPIO_6_OE +#define GLB_REG_GPIO_6_OE_POS (6U) +#define GLB_REG_GPIO_6_OE_LEN (1U) +#define GLB_REG_GPIO_6_OE_MSK (((1U << GLB_REG_GPIO_6_OE_LEN) - 1) << GLB_REG_GPIO_6_OE_POS) +#define GLB_REG_GPIO_6_OE_UMSK (~(((1U << GLB_REG_GPIO_6_OE_LEN) - 1) << GLB_REG_GPIO_6_OE_POS)) +#define GLB_REG_GPIO_6_FUNC_SEL GLB_REG_GPIO_6_FUNC_SEL +#define GLB_REG_GPIO_6_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_6_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_6_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_6_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_6_FUNC_SEL_POS) +#define GLB_REG_GPIO_6_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_6_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_6_FUNC_SEL_POS)) +#define GLB_REG_GPIO_6_INT_MODE_SET GLB_REG_GPIO_6_INT_MODE_SET +#define GLB_REG_GPIO_6_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_6_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_6_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_6_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_6_INT_MODE_SET_POS) +#define GLB_REG_GPIO_6_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_6_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_6_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_6_INT_CLR GLB_REG_GPIO_6_INT_CLR +#define GLB_REG_GPIO_6_INT_CLR_POS (20U) +#define GLB_REG_GPIO_6_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_6_INT_CLR_MSK (((1U << GLB_REG_GPIO_6_INT_CLR_LEN) - 1) << GLB_REG_GPIO_6_INT_CLR_POS) +#define GLB_REG_GPIO_6_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_6_INT_CLR_LEN) - 1) << GLB_REG_GPIO_6_INT_CLR_POS)) +#define GLB_GPIO_6_INT_STAT GLB_GPIO_6_INT_STAT +#define GLB_GPIO_6_INT_STAT_POS (21U) +#define GLB_GPIO_6_INT_STAT_LEN (1U) +#define GLB_GPIO_6_INT_STAT_MSK (((1U << GLB_GPIO_6_INT_STAT_LEN) - 1) << GLB_GPIO_6_INT_STAT_POS) +#define GLB_GPIO_6_INT_STAT_UMSK (~(((1U << GLB_GPIO_6_INT_STAT_LEN) - 1) << GLB_GPIO_6_INT_STAT_POS)) +#define GLB_REG_GPIO_6_INT_MASK GLB_REG_GPIO_6_INT_MASK +#define GLB_REG_GPIO_6_INT_MASK_POS (22U) +#define GLB_REG_GPIO_6_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_6_INT_MASK_MSK (((1U << GLB_REG_GPIO_6_INT_MASK_LEN) - 1) << GLB_REG_GPIO_6_INT_MASK_POS) +#define GLB_REG_GPIO_6_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_6_INT_MASK_LEN) - 1) << GLB_REG_GPIO_6_INT_MASK_POS)) +#define GLB_REG_GPIO_6_O GLB_REG_GPIO_6_O +#define GLB_REG_GPIO_6_O_POS (24U) +#define GLB_REG_GPIO_6_O_LEN (1U) +#define GLB_REG_GPIO_6_O_MSK (((1U << GLB_REG_GPIO_6_O_LEN) - 1) << GLB_REG_GPIO_6_O_POS) +#define GLB_REG_GPIO_6_O_UMSK (~(((1U << GLB_REG_GPIO_6_O_LEN) - 1) << GLB_REG_GPIO_6_O_POS)) +#define GLB_REG_GPIO_6_SET GLB_REG_GPIO_6_SET +#define GLB_REG_GPIO_6_SET_POS (25U) +#define GLB_REG_GPIO_6_SET_LEN (1U) +#define GLB_REG_GPIO_6_SET_MSK (((1U << GLB_REG_GPIO_6_SET_LEN) - 1) << GLB_REG_GPIO_6_SET_POS) +#define GLB_REG_GPIO_6_SET_UMSK (~(((1U << GLB_REG_GPIO_6_SET_LEN) - 1) << GLB_REG_GPIO_6_SET_POS)) +#define GLB_REG_GPIO_6_CLR GLB_REG_GPIO_6_CLR +#define GLB_REG_GPIO_6_CLR_POS (26U) +#define GLB_REG_GPIO_6_CLR_LEN (1U) +#define GLB_REG_GPIO_6_CLR_MSK (((1U << GLB_REG_GPIO_6_CLR_LEN) - 1) << GLB_REG_GPIO_6_CLR_POS) +#define GLB_REG_GPIO_6_CLR_UMSK (~(((1U << GLB_REG_GPIO_6_CLR_LEN) - 1) << GLB_REG_GPIO_6_CLR_POS)) +#define GLB_REG_GPIO_6_I GLB_REG_GPIO_6_I +#define GLB_REG_GPIO_6_I_POS (28U) +#define GLB_REG_GPIO_6_I_LEN (1U) +#define GLB_REG_GPIO_6_I_MSK (((1U << GLB_REG_GPIO_6_I_LEN) - 1) << GLB_REG_GPIO_6_I_POS) +#define GLB_REG_GPIO_6_I_UMSK (~(((1U << GLB_REG_GPIO_6_I_LEN) - 1) << GLB_REG_GPIO_6_I_POS)) +#define GLB_REG_GPIO_6_MODE GLB_REG_GPIO_6_MODE +#define GLB_REG_GPIO_6_MODE_POS (30U) +#define GLB_REG_GPIO_6_MODE_LEN (2U) +#define GLB_REG_GPIO_6_MODE_MSK (((1U << GLB_REG_GPIO_6_MODE_LEN) - 1) << GLB_REG_GPIO_6_MODE_POS) +#define GLB_REG_GPIO_6_MODE_UMSK (~(((1U << GLB_REG_GPIO_6_MODE_LEN) - 1) << GLB_REG_GPIO_6_MODE_POS)) + +/* 0x8E0 : gpio_cfg7 */ +#define GLB_GPIO_CFG7_OFFSET (0x8E0) +#define GLB_REG_GPIO_7_IE GLB_REG_GPIO_7_IE +#define GLB_REG_GPIO_7_IE_POS (0U) +#define GLB_REG_GPIO_7_IE_LEN (1U) +#define GLB_REG_GPIO_7_IE_MSK (((1U << GLB_REG_GPIO_7_IE_LEN) - 1) << GLB_REG_GPIO_7_IE_POS) +#define GLB_REG_GPIO_7_IE_UMSK (~(((1U << GLB_REG_GPIO_7_IE_LEN) - 1) << GLB_REG_GPIO_7_IE_POS)) +#define GLB_REG_GPIO_7_SMT GLB_REG_GPIO_7_SMT +#define GLB_REG_GPIO_7_SMT_POS (1U) +#define GLB_REG_GPIO_7_SMT_LEN (1U) +#define GLB_REG_GPIO_7_SMT_MSK (((1U << GLB_REG_GPIO_7_SMT_LEN) - 1) << GLB_REG_GPIO_7_SMT_POS) +#define GLB_REG_GPIO_7_SMT_UMSK (~(((1U << GLB_REG_GPIO_7_SMT_LEN) - 1) << GLB_REG_GPIO_7_SMT_POS)) +#define GLB_REG_GPIO_7_DRV GLB_REG_GPIO_7_DRV +#define GLB_REG_GPIO_7_DRV_POS (2U) +#define GLB_REG_GPIO_7_DRV_LEN (2U) +#define GLB_REG_GPIO_7_DRV_MSK (((1U << GLB_REG_GPIO_7_DRV_LEN) - 1) << GLB_REG_GPIO_7_DRV_POS) +#define GLB_REG_GPIO_7_DRV_UMSK (~(((1U << GLB_REG_GPIO_7_DRV_LEN) - 1) << GLB_REG_GPIO_7_DRV_POS)) +#define GLB_REG_GPIO_7_PU GLB_REG_GPIO_7_PU +#define GLB_REG_GPIO_7_PU_POS (4U) +#define GLB_REG_GPIO_7_PU_LEN (1U) +#define GLB_REG_GPIO_7_PU_MSK (((1U << GLB_REG_GPIO_7_PU_LEN) - 1) << GLB_REG_GPIO_7_PU_POS) +#define GLB_REG_GPIO_7_PU_UMSK (~(((1U << GLB_REG_GPIO_7_PU_LEN) - 1) << GLB_REG_GPIO_7_PU_POS)) +#define GLB_REG_GPIO_7_PD GLB_REG_GPIO_7_PD +#define GLB_REG_GPIO_7_PD_POS (5U) +#define GLB_REG_GPIO_7_PD_LEN (1U) +#define GLB_REG_GPIO_7_PD_MSK (((1U << GLB_REG_GPIO_7_PD_LEN) - 1) << GLB_REG_GPIO_7_PD_POS) +#define GLB_REG_GPIO_7_PD_UMSK (~(((1U << GLB_REG_GPIO_7_PD_LEN) - 1) << GLB_REG_GPIO_7_PD_POS)) +#define GLB_REG_GPIO_7_OE GLB_REG_GPIO_7_OE +#define GLB_REG_GPIO_7_OE_POS (6U) +#define GLB_REG_GPIO_7_OE_LEN (1U) +#define GLB_REG_GPIO_7_OE_MSK (((1U << GLB_REG_GPIO_7_OE_LEN) - 1) << GLB_REG_GPIO_7_OE_POS) +#define GLB_REG_GPIO_7_OE_UMSK (~(((1U << GLB_REG_GPIO_7_OE_LEN) - 1) << GLB_REG_GPIO_7_OE_POS)) +#define GLB_REG_GPIO_7_FUNC_SEL GLB_REG_GPIO_7_FUNC_SEL +#define GLB_REG_GPIO_7_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_7_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_7_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_7_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_7_FUNC_SEL_POS) +#define GLB_REG_GPIO_7_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_7_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_7_FUNC_SEL_POS)) +#define GLB_REG_GPIO_7_INT_MODE_SET GLB_REG_GPIO_7_INT_MODE_SET +#define GLB_REG_GPIO_7_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_7_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_7_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_7_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_7_INT_MODE_SET_POS) +#define GLB_REG_GPIO_7_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_7_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_7_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_7_INT_CLR GLB_REG_GPIO_7_INT_CLR +#define GLB_REG_GPIO_7_INT_CLR_POS (20U) +#define GLB_REG_GPIO_7_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_7_INT_CLR_MSK (((1U << GLB_REG_GPIO_7_INT_CLR_LEN) - 1) << GLB_REG_GPIO_7_INT_CLR_POS) +#define GLB_REG_GPIO_7_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_7_INT_CLR_LEN) - 1) << GLB_REG_GPIO_7_INT_CLR_POS)) +#define GLB_GPIO_7_INT_STAT GLB_GPIO_7_INT_STAT +#define GLB_GPIO_7_INT_STAT_POS (21U) +#define GLB_GPIO_7_INT_STAT_LEN (1U) +#define GLB_GPIO_7_INT_STAT_MSK (((1U << GLB_GPIO_7_INT_STAT_LEN) - 1) << GLB_GPIO_7_INT_STAT_POS) +#define GLB_GPIO_7_INT_STAT_UMSK (~(((1U << GLB_GPIO_7_INT_STAT_LEN) - 1) << GLB_GPIO_7_INT_STAT_POS)) +#define GLB_REG_GPIO_7_INT_MASK GLB_REG_GPIO_7_INT_MASK +#define GLB_REG_GPIO_7_INT_MASK_POS (22U) +#define GLB_REG_GPIO_7_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_7_INT_MASK_MSK (((1U << GLB_REG_GPIO_7_INT_MASK_LEN) - 1) << GLB_REG_GPIO_7_INT_MASK_POS) +#define GLB_REG_GPIO_7_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_7_INT_MASK_LEN) - 1) << GLB_REG_GPIO_7_INT_MASK_POS)) +#define GLB_REG_GPIO_7_O GLB_REG_GPIO_7_O +#define GLB_REG_GPIO_7_O_POS (24U) +#define GLB_REG_GPIO_7_O_LEN (1U) +#define GLB_REG_GPIO_7_O_MSK (((1U << GLB_REG_GPIO_7_O_LEN) - 1) << GLB_REG_GPIO_7_O_POS) +#define GLB_REG_GPIO_7_O_UMSK (~(((1U << GLB_REG_GPIO_7_O_LEN) - 1) << GLB_REG_GPIO_7_O_POS)) +#define GLB_REG_GPIO_7_SET GLB_REG_GPIO_7_SET +#define GLB_REG_GPIO_7_SET_POS (25U) +#define GLB_REG_GPIO_7_SET_LEN (1U) +#define GLB_REG_GPIO_7_SET_MSK (((1U << GLB_REG_GPIO_7_SET_LEN) - 1) << GLB_REG_GPIO_7_SET_POS) +#define GLB_REG_GPIO_7_SET_UMSK (~(((1U << GLB_REG_GPIO_7_SET_LEN) - 1) << GLB_REG_GPIO_7_SET_POS)) +#define GLB_REG_GPIO_7_CLR GLB_REG_GPIO_7_CLR +#define GLB_REG_GPIO_7_CLR_POS (26U) +#define GLB_REG_GPIO_7_CLR_LEN (1U) +#define GLB_REG_GPIO_7_CLR_MSK (((1U << GLB_REG_GPIO_7_CLR_LEN) - 1) << GLB_REG_GPIO_7_CLR_POS) +#define GLB_REG_GPIO_7_CLR_UMSK (~(((1U << GLB_REG_GPIO_7_CLR_LEN) - 1) << GLB_REG_GPIO_7_CLR_POS)) +#define GLB_REG_GPIO_7_I GLB_REG_GPIO_7_I +#define GLB_REG_GPIO_7_I_POS (28U) +#define GLB_REG_GPIO_7_I_LEN (1U) +#define GLB_REG_GPIO_7_I_MSK (((1U << GLB_REG_GPIO_7_I_LEN) - 1) << GLB_REG_GPIO_7_I_POS) +#define GLB_REG_GPIO_7_I_UMSK (~(((1U << GLB_REG_GPIO_7_I_LEN) - 1) << GLB_REG_GPIO_7_I_POS)) +#define GLB_REG_GPIO_7_MODE GLB_REG_GPIO_7_MODE +#define GLB_REG_GPIO_7_MODE_POS (30U) +#define GLB_REG_GPIO_7_MODE_LEN (2U) +#define GLB_REG_GPIO_7_MODE_MSK (((1U << GLB_REG_GPIO_7_MODE_LEN) - 1) << GLB_REG_GPIO_7_MODE_POS) +#define GLB_REG_GPIO_7_MODE_UMSK (~(((1U << GLB_REG_GPIO_7_MODE_LEN) - 1) << GLB_REG_GPIO_7_MODE_POS)) + +/* 0x8E4 : gpio_cfg8 */ +#define GLB_GPIO_CFG8_OFFSET (0x8E4) +#define GLB_REG_GPIO_8_IE GLB_REG_GPIO_8_IE +#define GLB_REG_GPIO_8_IE_POS (0U) +#define GLB_REG_GPIO_8_IE_LEN (1U) +#define GLB_REG_GPIO_8_IE_MSK (((1U << GLB_REG_GPIO_8_IE_LEN) - 1) << GLB_REG_GPIO_8_IE_POS) +#define GLB_REG_GPIO_8_IE_UMSK (~(((1U << GLB_REG_GPIO_8_IE_LEN) - 1) << GLB_REG_GPIO_8_IE_POS)) +#define GLB_REG_GPIO_8_SMT GLB_REG_GPIO_8_SMT +#define GLB_REG_GPIO_8_SMT_POS (1U) +#define GLB_REG_GPIO_8_SMT_LEN (1U) +#define GLB_REG_GPIO_8_SMT_MSK (((1U << GLB_REG_GPIO_8_SMT_LEN) - 1) << GLB_REG_GPIO_8_SMT_POS) +#define GLB_REG_GPIO_8_SMT_UMSK (~(((1U << GLB_REG_GPIO_8_SMT_LEN) - 1) << GLB_REG_GPIO_8_SMT_POS)) +#define GLB_REG_GPIO_8_DRV GLB_REG_GPIO_8_DRV +#define GLB_REG_GPIO_8_DRV_POS (2U) +#define GLB_REG_GPIO_8_DRV_LEN (2U) +#define GLB_REG_GPIO_8_DRV_MSK (((1U << GLB_REG_GPIO_8_DRV_LEN) - 1) << GLB_REG_GPIO_8_DRV_POS) +#define GLB_REG_GPIO_8_DRV_UMSK (~(((1U << GLB_REG_GPIO_8_DRV_LEN) - 1) << GLB_REG_GPIO_8_DRV_POS)) +#define GLB_REG_GPIO_8_PU GLB_REG_GPIO_8_PU +#define GLB_REG_GPIO_8_PU_POS (4U) +#define GLB_REG_GPIO_8_PU_LEN (1U) +#define GLB_REG_GPIO_8_PU_MSK (((1U << GLB_REG_GPIO_8_PU_LEN) - 1) << GLB_REG_GPIO_8_PU_POS) +#define GLB_REG_GPIO_8_PU_UMSK (~(((1U << GLB_REG_GPIO_8_PU_LEN) - 1) << GLB_REG_GPIO_8_PU_POS)) +#define GLB_REG_GPIO_8_PD GLB_REG_GPIO_8_PD +#define GLB_REG_GPIO_8_PD_POS (5U) +#define GLB_REG_GPIO_8_PD_LEN (1U) +#define GLB_REG_GPIO_8_PD_MSK (((1U << GLB_REG_GPIO_8_PD_LEN) - 1) << GLB_REG_GPIO_8_PD_POS) +#define GLB_REG_GPIO_8_PD_UMSK (~(((1U << GLB_REG_GPIO_8_PD_LEN) - 1) << GLB_REG_GPIO_8_PD_POS)) +#define GLB_REG_GPIO_8_OE GLB_REG_GPIO_8_OE +#define GLB_REG_GPIO_8_OE_POS (6U) +#define GLB_REG_GPIO_8_OE_LEN (1U) +#define GLB_REG_GPIO_8_OE_MSK (((1U << GLB_REG_GPIO_8_OE_LEN) - 1) << GLB_REG_GPIO_8_OE_POS) +#define GLB_REG_GPIO_8_OE_UMSK (~(((1U << GLB_REG_GPIO_8_OE_LEN) - 1) << GLB_REG_GPIO_8_OE_POS)) +#define GLB_REG_GPIO_8_FUNC_SEL GLB_REG_GPIO_8_FUNC_SEL +#define GLB_REG_GPIO_8_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_8_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_8_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_8_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_8_FUNC_SEL_POS) +#define GLB_REG_GPIO_8_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_8_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_8_FUNC_SEL_POS)) +#define GLB_REG_GPIO_8_INT_MODE_SET GLB_REG_GPIO_8_INT_MODE_SET +#define GLB_REG_GPIO_8_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_8_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_8_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_8_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_8_INT_MODE_SET_POS) +#define GLB_REG_GPIO_8_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_8_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_8_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_8_INT_CLR GLB_REG_GPIO_8_INT_CLR +#define GLB_REG_GPIO_8_INT_CLR_POS (20U) +#define GLB_REG_GPIO_8_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_8_INT_CLR_MSK (((1U << GLB_REG_GPIO_8_INT_CLR_LEN) - 1) << GLB_REG_GPIO_8_INT_CLR_POS) +#define GLB_REG_GPIO_8_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_8_INT_CLR_LEN) - 1) << GLB_REG_GPIO_8_INT_CLR_POS)) +#define GLB_GPIO_8_INT_STAT GLB_GPIO_8_INT_STAT +#define GLB_GPIO_8_INT_STAT_POS (21U) +#define GLB_GPIO_8_INT_STAT_LEN (1U) +#define GLB_GPIO_8_INT_STAT_MSK (((1U << GLB_GPIO_8_INT_STAT_LEN) - 1) << GLB_GPIO_8_INT_STAT_POS) +#define GLB_GPIO_8_INT_STAT_UMSK (~(((1U << GLB_GPIO_8_INT_STAT_LEN) - 1) << GLB_GPIO_8_INT_STAT_POS)) +#define GLB_REG_GPIO_8_INT_MASK GLB_REG_GPIO_8_INT_MASK +#define GLB_REG_GPIO_8_INT_MASK_POS (22U) +#define GLB_REG_GPIO_8_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_8_INT_MASK_MSK (((1U << GLB_REG_GPIO_8_INT_MASK_LEN) - 1) << GLB_REG_GPIO_8_INT_MASK_POS) +#define GLB_REG_GPIO_8_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_8_INT_MASK_LEN) - 1) << GLB_REG_GPIO_8_INT_MASK_POS)) +#define GLB_REG_GPIO_8_O GLB_REG_GPIO_8_O +#define GLB_REG_GPIO_8_O_POS (24U) +#define GLB_REG_GPIO_8_O_LEN (1U) +#define GLB_REG_GPIO_8_O_MSK (((1U << GLB_REG_GPIO_8_O_LEN) - 1) << GLB_REG_GPIO_8_O_POS) +#define GLB_REG_GPIO_8_O_UMSK (~(((1U << GLB_REG_GPIO_8_O_LEN) - 1) << GLB_REG_GPIO_8_O_POS)) +#define GLB_REG_GPIO_8_SET GLB_REG_GPIO_8_SET +#define GLB_REG_GPIO_8_SET_POS (25U) +#define GLB_REG_GPIO_8_SET_LEN (1U) +#define GLB_REG_GPIO_8_SET_MSK (((1U << GLB_REG_GPIO_8_SET_LEN) - 1) << GLB_REG_GPIO_8_SET_POS) +#define GLB_REG_GPIO_8_SET_UMSK (~(((1U << GLB_REG_GPIO_8_SET_LEN) - 1) << GLB_REG_GPIO_8_SET_POS)) +#define GLB_REG_GPIO_8_CLR GLB_REG_GPIO_8_CLR +#define GLB_REG_GPIO_8_CLR_POS (26U) +#define GLB_REG_GPIO_8_CLR_LEN (1U) +#define GLB_REG_GPIO_8_CLR_MSK (((1U << GLB_REG_GPIO_8_CLR_LEN) - 1) << GLB_REG_GPIO_8_CLR_POS) +#define GLB_REG_GPIO_8_CLR_UMSK (~(((1U << GLB_REG_GPIO_8_CLR_LEN) - 1) << GLB_REG_GPIO_8_CLR_POS)) +#define GLB_REG_GPIO_8_I GLB_REG_GPIO_8_I +#define GLB_REG_GPIO_8_I_POS (28U) +#define GLB_REG_GPIO_8_I_LEN (1U) +#define GLB_REG_GPIO_8_I_MSK (((1U << GLB_REG_GPIO_8_I_LEN) - 1) << GLB_REG_GPIO_8_I_POS) +#define GLB_REG_GPIO_8_I_UMSK (~(((1U << GLB_REG_GPIO_8_I_LEN) - 1) << GLB_REG_GPIO_8_I_POS)) +#define GLB_REG_GPIO_8_MODE GLB_REG_GPIO_8_MODE +#define GLB_REG_GPIO_8_MODE_POS (30U) +#define GLB_REG_GPIO_8_MODE_LEN (2U) +#define GLB_REG_GPIO_8_MODE_MSK (((1U << GLB_REG_GPIO_8_MODE_LEN) - 1) << GLB_REG_GPIO_8_MODE_POS) +#define GLB_REG_GPIO_8_MODE_UMSK (~(((1U << GLB_REG_GPIO_8_MODE_LEN) - 1) << GLB_REG_GPIO_8_MODE_POS)) + +/* 0x8E8 : gpio_cfg9 */ +#define GLB_GPIO_CFG9_OFFSET (0x8E8) +#define GLB_REG_GPIO_9_IE GLB_REG_GPIO_9_IE +#define GLB_REG_GPIO_9_IE_POS (0U) +#define GLB_REG_GPIO_9_IE_LEN (1U) +#define GLB_REG_GPIO_9_IE_MSK (((1U << GLB_REG_GPIO_9_IE_LEN) - 1) << GLB_REG_GPIO_9_IE_POS) +#define GLB_REG_GPIO_9_IE_UMSK (~(((1U << GLB_REG_GPIO_9_IE_LEN) - 1) << GLB_REG_GPIO_9_IE_POS)) +#define GLB_REG_GPIO_9_SMT GLB_REG_GPIO_9_SMT +#define GLB_REG_GPIO_9_SMT_POS (1U) +#define GLB_REG_GPIO_9_SMT_LEN (1U) +#define GLB_REG_GPIO_9_SMT_MSK (((1U << GLB_REG_GPIO_9_SMT_LEN) - 1) << GLB_REG_GPIO_9_SMT_POS) +#define GLB_REG_GPIO_9_SMT_UMSK (~(((1U << GLB_REG_GPIO_9_SMT_LEN) - 1) << GLB_REG_GPIO_9_SMT_POS)) +#define GLB_REG_GPIO_9_DRV GLB_REG_GPIO_9_DRV +#define GLB_REG_GPIO_9_DRV_POS (2U) +#define GLB_REG_GPIO_9_DRV_LEN (2U) +#define GLB_REG_GPIO_9_DRV_MSK (((1U << GLB_REG_GPIO_9_DRV_LEN) - 1) << GLB_REG_GPIO_9_DRV_POS) +#define GLB_REG_GPIO_9_DRV_UMSK (~(((1U << GLB_REG_GPIO_9_DRV_LEN) - 1) << GLB_REG_GPIO_9_DRV_POS)) +#define GLB_REG_GPIO_9_PU GLB_REG_GPIO_9_PU +#define GLB_REG_GPIO_9_PU_POS (4U) +#define GLB_REG_GPIO_9_PU_LEN (1U) +#define GLB_REG_GPIO_9_PU_MSK (((1U << GLB_REG_GPIO_9_PU_LEN) - 1) << GLB_REG_GPIO_9_PU_POS) +#define GLB_REG_GPIO_9_PU_UMSK (~(((1U << GLB_REG_GPIO_9_PU_LEN) - 1) << GLB_REG_GPIO_9_PU_POS)) +#define GLB_REG_GPIO_9_PD GLB_REG_GPIO_9_PD +#define GLB_REG_GPIO_9_PD_POS (5U) +#define GLB_REG_GPIO_9_PD_LEN (1U) +#define GLB_REG_GPIO_9_PD_MSK (((1U << GLB_REG_GPIO_9_PD_LEN) - 1) << GLB_REG_GPIO_9_PD_POS) +#define GLB_REG_GPIO_9_PD_UMSK (~(((1U << GLB_REG_GPIO_9_PD_LEN) - 1) << GLB_REG_GPIO_9_PD_POS)) +#define GLB_REG_GPIO_9_OE GLB_REG_GPIO_9_OE +#define GLB_REG_GPIO_9_OE_POS (6U) +#define GLB_REG_GPIO_9_OE_LEN (1U) +#define GLB_REG_GPIO_9_OE_MSK (((1U << GLB_REG_GPIO_9_OE_LEN) - 1) << GLB_REG_GPIO_9_OE_POS) +#define GLB_REG_GPIO_9_OE_UMSK (~(((1U << GLB_REG_GPIO_9_OE_LEN) - 1) << GLB_REG_GPIO_9_OE_POS)) +#define GLB_REG_GPIO_9_FUNC_SEL GLB_REG_GPIO_9_FUNC_SEL +#define GLB_REG_GPIO_9_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_9_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_9_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_9_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_9_FUNC_SEL_POS) +#define GLB_REG_GPIO_9_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_9_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_9_FUNC_SEL_POS)) +#define GLB_REG_GPIO_9_INT_MODE_SET GLB_REG_GPIO_9_INT_MODE_SET +#define GLB_REG_GPIO_9_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_9_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_9_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_9_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_9_INT_MODE_SET_POS) +#define GLB_REG_GPIO_9_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_9_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_9_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_9_INT_CLR GLB_REG_GPIO_9_INT_CLR +#define GLB_REG_GPIO_9_INT_CLR_POS (20U) +#define GLB_REG_GPIO_9_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_9_INT_CLR_MSK (((1U << GLB_REG_GPIO_9_INT_CLR_LEN) - 1) << GLB_REG_GPIO_9_INT_CLR_POS) +#define GLB_REG_GPIO_9_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_9_INT_CLR_LEN) - 1) << GLB_REG_GPIO_9_INT_CLR_POS)) +#define GLB_GPIO_9_INT_STAT GLB_GPIO_9_INT_STAT +#define GLB_GPIO_9_INT_STAT_POS (21U) +#define GLB_GPIO_9_INT_STAT_LEN (1U) +#define GLB_GPIO_9_INT_STAT_MSK (((1U << GLB_GPIO_9_INT_STAT_LEN) - 1) << GLB_GPIO_9_INT_STAT_POS) +#define GLB_GPIO_9_INT_STAT_UMSK (~(((1U << GLB_GPIO_9_INT_STAT_LEN) - 1) << GLB_GPIO_9_INT_STAT_POS)) +#define GLB_REG_GPIO_9_INT_MASK GLB_REG_GPIO_9_INT_MASK +#define GLB_REG_GPIO_9_INT_MASK_POS (22U) +#define GLB_REG_GPIO_9_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_9_INT_MASK_MSK (((1U << GLB_REG_GPIO_9_INT_MASK_LEN) - 1) << GLB_REG_GPIO_9_INT_MASK_POS) +#define GLB_REG_GPIO_9_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_9_INT_MASK_LEN) - 1) << GLB_REG_GPIO_9_INT_MASK_POS)) +#define GLB_REG_GPIO_9_O GLB_REG_GPIO_9_O +#define GLB_REG_GPIO_9_O_POS (24U) +#define GLB_REG_GPIO_9_O_LEN (1U) +#define GLB_REG_GPIO_9_O_MSK (((1U << GLB_REG_GPIO_9_O_LEN) - 1) << GLB_REG_GPIO_9_O_POS) +#define GLB_REG_GPIO_9_O_UMSK (~(((1U << GLB_REG_GPIO_9_O_LEN) - 1) << GLB_REG_GPIO_9_O_POS)) +#define GLB_REG_GPIO_9_SET GLB_REG_GPIO_9_SET +#define GLB_REG_GPIO_9_SET_POS (25U) +#define GLB_REG_GPIO_9_SET_LEN (1U) +#define GLB_REG_GPIO_9_SET_MSK (((1U << GLB_REG_GPIO_9_SET_LEN) - 1) << GLB_REG_GPIO_9_SET_POS) +#define GLB_REG_GPIO_9_SET_UMSK (~(((1U << GLB_REG_GPIO_9_SET_LEN) - 1) << GLB_REG_GPIO_9_SET_POS)) +#define GLB_REG_GPIO_9_CLR GLB_REG_GPIO_9_CLR +#define GLB_REG_GPIO_9_CLR_POS (26U) +#define GLB_REG_GPIO_9_CLR_LEN (1U) +#define GLB_REG_GPIO_9_CLR_MSK (((1U << GLB_REG_GPIO_9_CLR_LEN) - 1) << GLB_REG_GPIO_9_CLR_POS) +#define GLB_REG_GPIO_9_CLR_UMSK (~(((1U << GLB_REG_GPIO_9_CLR_LEN) - 1) << GLB_REG_GPIO_9_CLR_POS)) +#define GLB_REG_GPIO_9_I GLB_REG_GPIO_9_I +#define GLB_REG_GPIO_9_I_POS (28U) +#define GLB_REG_GPIO_9_I_LEN (1U) +#define GLB_REG_GPIO_9_I_MSK (((1U << GLB_REG_GPIO_9_I_LEN) - 1) << GLB_REG_GPIO_9_I_POS) +#define GLB_REG_GPIO_9_I_UMSK (~(((1U << GLB_REG_GPIO_9_I_LEN) - 1) << GLB_REG_GPIO_9_I_POS)) +#define GLB_REG_GPIO_9_MODE GLB_REG_GPIO_9_MODE +#define GLB_REG_GPIO_9_MODE_POS (30U) +#define GLB_REG_GPIO_9_MODE_LEN (2U) +#define GLB_REG_GPIO_9_MODE_MSK (((1U << GLB_REG_GPIO_9_MODE_LEN) - 1) << GLB_REG_GPIO_9_MODE_POS) +#define GLB_REG_GPIO_9_MODE_UMSK (~(((1U << GLB_REG_GPIO_9_MODE_LEN) - 1) << GLB_REG_GPIO_9_MODE_POS)) + +/* 0x8EC : gpio_cfg10 */ +#define GLB_GPIO_CFG10_OFFSET (0x8EC) +#define GLB_REG_GPIO_10_IE GLB_REG_GPIO_10_IE +#define GLB_REG_GPIO_10_IE_POS (0U) +#define GLB_REG_GPIO_10_IE_LEN (1U) +#define GLB_REG_GPIO_10_IE_MSK (((1U << GLB_REG_GPIO_10_IE_LEN) - 1) << GLB_REG_GPIO_10_IE_POS) +#define GLB_REG_GPIO_10_IE_UMSK (~(((1U << GLB_REG_GPIO_10_IE_LEN) - 1) << GLB_REG_GPIO_10_IE_POS)) +#define GLB_REG_GPIO_10_SMT GLB_REG_GPIO_10_SMT +#define GLB_REG_GPIO_10_SMT_POS (1U) +#define GLB_REG_GPIO_10_SMT_LEN (1U) +#define GLB_REG_GPIO_10_SMT_MSK (((1U << GLB_REG_GPIO_10_SMT_LEN) - 1) << GLB_REG_GPIO_10_SMT_POS) +#define GLB_REG_GPIO_10_SMT_UMSK (~(((1U << GLB_REG_GPIO_10_SMT_LEN) - 1) << GLB_REG_GPIO_10_SMT_POS)) +#define GLB_REG_GPIO_10_DRV GLB_REG_GPIO_10_DRV +#define GLB_REG_GPIO_10_DRV_POS (2U) +#define GLB_REG_GPIO_10_DRV_LEN (2U) +#define GLB_REG_GPIO_10_DRV_MSK (((1U << GLB_REG_GPIO_10_DRV_LEN) - 1) << GLB_REG_GPIO_10_DRV_POS) +#define GLB_REG_GPIO_10_DRV_UMSK (~(((1U << GLB_REG_GPIO_10_DRV_LEN) - 1) << GLB_REG_GPIO_10_DRV_POS)) +#define GLB_REG_GPIO_10_PU GLB_REG_GPIO_10_PU +#define GLB_REG_GPIO_10_PU_POS (4U) +#define GLB_REG_GPIO_10_PU_LEN (1U) +#define GLB_REG_GPIO_10_PU_MSK (((1U << GLB_REG_GPIO_10_PU_LEN) - 1) << GLB_REG_GPIO_10_PU_POS) +#define GLB_REG_GPIO_10_PU_UMSK (~(((1U << GLB_REG_GPIO_10_PU_LEN) - 1) << GLB_REG_GPIO_10_PU_POS)) +#define GLB_REG_GPIO_10_PD GLB_REG_GPIO_10_PD +#define GLB_REG_GPIO_10_PD_POS (5U) +#define GLB_REG_GPIO_10_PD_LEN (1U) +#define GLB_REG_GPIO_10_PD_MSK (((1U << GLB_REG_GPIO_10_PD_LEN) - 1) << GLB_REG_GPIO_10_PD_POS) +#define GLB_REG_GPIO_10_PD_UMSK (~(((1U << GLB_REG_GPIO_10_PD_LEN) - 1) << GLB_REG_GPIO_10_PD_POS)) +#define GLB_REG_GPIO_10_OE GLB_REG_GPIO_10_OE +#define GLB_REG_GPIO_10_OE_POS (6U) +#define GLB_REG_GPIO_10_OE_LEN (1U) +#define GLB_REG_GPIO_10_OE_MSK (((1U << GLB_REG_GPIO_10_OE_LEN) - 1) << GLB_REG_GPIO_10_OE_POS) +#define GLB_REG_GPIO_10_OE_UMSK (~(((1U << GLB_REG_GPIO_10_OE_LEN) - 1) << GLB_REG_GPIO_10_OE_POS)) +#define GLB_REG_GPIO_10_FUNC_SEL GLB_REG_GPIO_10_FUNC_SEL +#define GLB_REG_GPIO_10_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_10_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_10_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_10_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_10_FUNC_SEL_POS) +#define GLB_REG_GPIO_10_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_10_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_10_FUNC_SEL_POS)) +#define GLB_REG_GPIO_10_INT_MODE_SET GLB_REG_GPIO_10_INT_MODE_SET +#define GLB_REG_GPIO_10_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_10_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_10_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_10_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_10_INT_MODE_SET_POS) +#define GLB_REG_GPIO_10_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_10_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_10_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_10_INT_CLR GLB_REG_GPIO_10_INT_CLR +#define GLB_REG_GPIO_10_INT_CLR_POS (20U) +#define GLB_REG_GPIO_10_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_10_INT_CLR_MSK (((1U << GLB_REG_GPIO_10_INT_CLR_LEN) - 1) << GLB_REG_GPIO_10_INT_CLR_POS) +#define GLB_REG_GPIO_10_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_10_INT_CLR_LEN) - 1) << GLB_REG_GPIO_10_INT_CLR_POS)) +#define GLB_GPIO_10_INT_STAT GLB_GPIO_10_INT_STAT +#define GLB_GPIO_10_INT_STAT_POS (21U) +#define GLB_GPIO_10_INT_STAT_LEN (1U) +#define GLB_GPIO_10_INT_STAT_MSK (((1U << GLB_GPIO_10_INT_STAT_LEN) - 1) << GLB_GPIO_10_INT_STAT_POS) +#define GLB_GPIO_10_INT_STAT_UMSK (~(((1U << GLB_GPIO_10_INT_STAT_LEN) - 1) << GLB_GPIO_10_INT_STAT_POS)) +#define GLB_REG_GPIO_10_INT_MASK GLB_REG_GPIO_10_INT_MASK +#define GLB_REG_GPIO_10_INT_MASK_POS (22U) +#define GLB_REG_GPIO_10_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_10_INT_MASK_MSK (((1U << GLB_REG_GPIO_10_INT_MASK_LEN) - 1) << GLB_REG_GPIO_10_INT_MASK_POS) +#define GLB_REG_GPIO_10_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_10_INT_MASK_LEN) - 1) << GLB_REG_GPIO_10_INT_MASK_POS)) +#define GLB_REG_GPIO_10_O GLB_REG_GPIO_10_O +#define GLB_REG_GPIO_10_O_POS (24U) +#define GLB_REG_GPIO_10_O_LEN (1U) +#define GLB_REG_GPIO_10_O_MSK (((1U << GLB_REG_GPIO_10_O_LEN) - 1) << GLB_REG_GPIO_10_O_POS) +#define GLB_REG_GPIO_10_O_UMSK (~(((1U << GLB_REG_GPIO_10_O_LEN) - 1) << GLB_REG_GPIO_10_O_POS)) +#define GLB_REG_GPIO_10_SET GLB_REG_GPIO_10_SET +#define GLB_REG_GPIO_10_SET_POS (25U) +#define GLB_REG_GPIO_10_SET_LEN (1U) +#define GLB_REG_GPIO_10_SET_MSK (((1U << GLB_REG_GPIO_10_SET_LEN) - 1) << GLB_REG_GPIO_10_SET_POS) +#define GLB_REG_GPIO_10_SET_UMSK (~(((1U << GLB_REG_GPIO_10_SET_LEN) - 1) << GLB_REG_GPIO_10_SET_POS)) +#define GLB_REG_GPIO_10_CLR GLB_REG_GPIO_10_CLR +#define GLB_REG_GPIO_10_CLR_POS (26U) +#define GLB_REG_GPIO_10_CLR_LEN (1U) +#define GLB_REG_GPIO_10_CLR_MSK (((1U << GLB_REG_GPIO_10_CLR_LEN) - 1) << GLB_REG_GPIO_10_CLR_POS) +#define GLB_REG_GPIO_10_CLR_UMSK (~(((1U << GLB_REG_GPIO_10_CLR_LEN) - 1) << GLB_REG_GPIO_10_CLR_POS)) +#define GLB_REG_GPIO_10_I GLB_REG_GPIO_10_I +#define GLB_REG_GPIO_10_I_POS (28U) +#define GLB_REG_GPIO_10_I_LEN (1U) +#define GLB_REG_GPIO_10_I_MSK (((1U << GLB_REG_GPIO_10_I_LEN) - 1) << GLB_REG_GPIO_10_I_POS) +#define GLB_REG_GPIO_10_I_UMSK (~(((1U << GLB_REG_GPIO_10_I_LEN) - 1) << GLB_REG_GPIO_10_I_POS)) +#define GLB_REG_GPIO_10_MODE GLB_REG_GPIO_10_MODE +#define GLB_REG_GPIO_10_MODE_POS (30U) +#define GLB_REG_GPIO_10_MODE_LEN (2U) +#define GLB_REG_GPIO_10_MODE_MSK (((1U << GLB_REG_GPIO_10_MODE_LEN) - 1) << GLB_REG_GPIO_10_MODE_POS) +#define GLB_REG_GPIO_10_MODE_UMSK (~(((1U << GLB_REG_GPIO_10_MODE_LEN) - 1) << GLB_REG_GPIO_10_MODE_POS)) + +/* 0x8F0 : gpio_cfg11 */ +#define GLB_GPIO_CFG11_OFFSET (0x8F0) +#define GLB_REG_GPIO_11_IE GLB_REG_GPIO_11_IE +#define GLB_REG_GPIO_11_IE_POS (0U) +#define GLB_REG_GPIO_11_IE_LEN (1U) +#define GLB_REG_GPIO_11_IE_MSK (((1U << GLB_REG_GPIO_11_IE_LEN) - 1) << GLB_REG_GPIO_11_IE_POS) +#define GLB_REG_GPIO_11_IE_UMSK (~(((1U << GLB_REG_GPIO_11_IE_LEN) - 1) << GLB_REG_GPIO_11_IE_POS)) +#define GLB_REG_GPIO_11_SMT GLB_REG_GPIO_11_SMT +#define GLB_REG_GPIO_11_SMT_POS (1U) +#define GLB_REG_GPIO_11_SMT_LEN (1U) +#define GLB_REG_GPIO_11_SMT_MSK (((1U << GLB_REG_GPIO_11_SMT_LEN) - 1) << GLB_REG_GPIO_11_SMT_POS) +#define GLB_REG_GPIO_11_SMT_UMSK (~(((1U << GLB_REG_GPIO_11_SMT_LEN) - 1) << GLB_REG_GPIO_11_SMT_POS)) +#define GLB_REG_GPIO_11_DRV GLB_REG_GPIO_11_DRV +#define GLB_REG_GPIO_11_DRV_POS (2U) +#define GLB_REG_GPIO_11_DRV_LEN (2U) +#define GLB_REG_GPIO_11_DRV_MSK (((1U << GLB_REG_GPIO_11_DRV_LEN) - 1) << GLB_REG_GPIO_11_DRV_POS) +#define GLB_REG_GPIO_11_DRV_UMSK (~(((1U << GLB_REG_GPIO_11_DRV_LEN) - 1) << GLB_REG_GPIO_11_DRV_POS)) +#define GLB_REG_GPIO_11_PU GLB_REG_GPIO_11_PU +#define GLB_REG_GPIO_11_PU_POS (4U) +#define GLB_REG_GPIO_11_PU_LEN (1U) +#define GLB_REG_GPIO_11_PU_MSK (((1U << GLB_REG_GPIO_11_PU_LEN) - 1) << GLB_REG_GPIO_11_PU_POS) +#define GLB_REG_GPIO_11_PU_UMSK (~(((1U << GLB_REG_GPIO_11_PU_LEN) - 1) << GLB_REG_GPIO_11_PU_POS)) +#define GLB_REG_GPIO_11_PD GLB_REG_GPIO_11_PD +#define GLB_REG_GPIO_11_PD_POS (5U) +#define GLB_REG_GPIO_11_PD_LEN (1U) +#define GLB_REG_GPIO_11_PD_MSK (((1U << GLB_REG_GPIO_11_PD_LEN) - 1) << GLB_REG_GPIO_11_PD_POS) +#define GLB_REG_GPIO_11_PD_UMSK (~(((1U << GLB_REG_GPIO_11_PD_LEN) - 1) << GLB_REG_GPIO_11_PD_POS)) +#define GLB_REG_GPIO_11_OE GLB_REG_GPIO_11_OE +#define GLB_REG_GPIO_11_OE_POS (6U) +#define GLB_REG_GPIO_11_OE_LEN (1U) +#define GLB_REG_GPIO_11_OE_MSK (((1U << GLB_REG_GPIO_11_OE_LEN) - 1) << GLB_REG_GPIO_11_OE_POS) +#define GLB_REG_GPIO_11_OE_UMSK (~(((1U << GLB_REG_GPIO_11_OE_LEN) - 1) << GLB_REG_GPIO_11_OE_POS)) +#define GLB_REG_GPIO_11_FUNC_SEL GLB_REG_GPIO_11_FUNC_SEL +#define GLB_REG_GPIO_11_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_11_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_11_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_11_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_11_FUNC_SEL_POS) +#define GLB_REG_GPIO_11_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_11_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_11_FUNC_SEL_POS)) +#define GLB_REG_GPIO_11_INT_MODE_SET GLB_REG_GPIO_11_INT_MODE_SET +#define GLB_REG_GPIO_11_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_11_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_11_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_11_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_11_INT_MODE_SET_POS) +#define GLB_REG_GPIO_11_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_11_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_11_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_11_INT_CLR GLB_REG_GPIO_11_INT_CLR +#define GLB_REG_GPIO_11_INT_CLR_POS (20U) +#define GLB_REG_GPIO_11_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_11_INT_CLR_MSK (((1U << GLB_REG_GPIO_11_INT_CLR_LEN) - 1) << GLB_REG_GPIO_11_INT_CLR_POS) +#define GLB_REG_GPIO_11_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_11_INT_CLR_LEN) - 1) << GLB_REG_GPIO_11_INT_CLR_POS)) +#define GLB_GPIO_11_INT_STAT GLB_GPIO_11_INT_STAT +#define GLB_GPIO_11_INT_STAT_POS (21U) +#define GLB_GPIO_11_INT_STAT_LEN (1U) +#define GLB_GPIO_11_INT_STAT_MSK (((1U << GLB_GPIO_11_INT_STAT_LEN) - 1) << GLB_GPIO_11_INT_STAT_POS) +#define GLB_GPIO_11_INT_STAT_UMSK (~(((1U << GLB_GPIO_11_INT_STAT_LEN) - 1) << GLB_GPIO_11_INT_STAT_POS)) +#define GLB_REG_GPIO_11_INT_MASK GLB_REG_GPIO_11_INT_MASK +#define GLB_REG_GPIO_11_INT_MASK_POS (22U) +#define GLB_REG_GPIO_11_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_11_INT_MASK_MSK (((1U << GLB_REG_GPIO_11_INT_MASK_LEN) - 1) << GLB_REG_GPIO_11_INT_MASK_POS) +#define GLB_REG_GPIO_11_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_11_INT_MASK_LEN) - 1) << GLB_REG_GPIO_11_INT_MASK_POS)) +#define GLB_REG_GPIO_11_O GLB_REG_GPIO_11_O +#define GLB_REG_GPIO_11_O_POS (24U) +#define GLB_REG_GPIO_11_O_LEN (1U) +#define GLB_REG_GPIO_11_O_MSK (((1U << GLB_REG_GPIO_11_O_LEN) - 1) << GLB_REG_GPIO_11_O_POS) +#define GLB_REG_GPIO_11_O_UMSK (~(((1U << GLB_REG_GPIO_11_O_LEN) - 1) << GLB_REG_GPIO_11_O_POS)) +#define GLB_REG_GPIO_11_SET GLB_REG_GPIO_11_SET +#define GLB_REG_GPIO_11_SET_POS (25U) +#define GLB_REG_GPIO_11_SET_LEN (1U) +#define GLB_REG_GPIO_11_SET_MSK (((1U << GLB_REG_GPIO_11_SET_LEN) - 1) << GLB_REG_GPIO_11_SET_POS) +#define GLB_REG_GPIO_11_SET_UMSK (~(((1U << GLB_REG_GPIO_11_SET_LEN) - 1) << GLB_REG_GPIO_11_SET_POS)) +#define GLB_REG_GPIO_11_CLR GLB_REG_GPIO_11_CLR +#define GLB_REG_GPIO_11_CLR_POS (26U) +#define GLB_REG_GPIO_11_CLR_LEN (1U) +#define GLB_REG_GPIO_11_CLR_MSK (((1U << GLB_REG_GPIO_11_CLR_LEN) - 1) << GLB_REG_GPIO_11_CLR_POS) +#define GLB_REG_GPIO_11_CLR_UMSK (~(((1U << GLB_REG_GPIO_11_CLR_LEN) - 1) << GLB_REG_GPIO_11_CLR_POS)) +#define GLB_REG_GPIO_11_I GLB_REG_GPIO_11_I +#define GLB_REG_GPIO_11_I_POS (28U) +#define GLB_REG_GPIO_11_I_LEN (1U) +#define GLB_REG_GPIO_11_I_MSK (((1U << GLB_REG_GPIO_11_I_LEN) - 1) << GLB_REG_GPIO_11_I_POS) +#define GLB_REG_GPIO_11_I_UMSK (~(((1U << GLB_REG_GPIO_11_I_LEN) - 1) << GLB_REG_GPIO_11_I_POS)) +#define GLB_REG_GPIO_11_MODE GLB_REG_GPIO_11_MODE +#define GLB_REG_GPIO_11_MODE_POS (30U) +#define GLB_REG_GPIO_11_MODE_LEN (2U) +#define GLB_REG_GPIO_11_MODE_MSK (((1U << GLB_REG_GPIO_11_MODE_LEN) - 1) << GLB_REG_GPIO_11_MODE_POS) +#define GLB_REG_GPIO_11_MODE_UMSK (~(((1U << GLB_REG_GPIO_11_MODE_LEN) - 1) << GLB_REG_GPIO_11_MODE_POS)) + +/* 0x8F4 : gpio_cfg12 */ +#define GLB_GPIO_CFG12_OFFSET (0x8F4) +#define GLB_REG_GPIO_12_IE GLB_REG_GPIO_12_IE +#define GLB_REG_GPIO_12_IE_POS (0U) +#define GLB_REG_GPIO_12_IE_LEN (1U) +#define GLB_REG_GPIO_12_IE_MSK (((1U << GLB_REG_GPIO_12_IE_LEN) - 1) << GLB_REG_GPIO_12_IE_POS) +#define GLB_REG_GPIO_12_IE_UMSK (~(((1U << GLB_REG_GPIO_12_IE_LEN) - 1) << GLB_REG_GPIO_12_IE_POS)) +#define GLB_REG_GPIO_12_SMT GLB_REG_GPIO_12_SMT +#define GLB_REG_GPIO_12_SMT_POS (1U) +#define GLB_REG_GPIO_12_SMT_LEN (1U) +#define GLB_REG_GPIO_12_SMT_MSK (((1U << GLB_REG_GPIO_12_SMT_LEN) - 1) << GLB_REG_GPIO_12_SMT_POS) +#define GLB_REG_GPIO_12_SMT_UMSK (~(((1U << GLB_REG_GPIO_12_SMT_LEN) - 1) << GLB_REG_GPIO_12_SMT_POS)) +#define GLB_REG_GPIO_12_DRV GLB_REG_GPIO_12_DRV +#define GLB_REG_GPIO_12_DRV_POS (2U) +#define GLB_REG_GPIO_12_DRV_LEN (2U) +#define GLB_REG_GPIO_12_DRV_MSK (((1U << GLB_REG_GPIO_12_DRV_LEN) - 1) << GLB_REG_GPIO_12_DRV_POS) +#define GLB_REG_GPIO_12_DRV_UMSK (~(((1U << GLB_REG_GPIO_12_DRV_LEN) - 1) << GLB_REG_GPIO_12_DRV_POS)) +#define GLB_REG_GPIO_12_PU GLB_REG_GPIO_12_PU +#define GLB_REG_GPIO_12_PU_POS (4U) +#define GLB_REG_GPIO_12_PU_LEN (1U) +#define GLB_REG_GPIO_12_PU_MSK (((1U << GLB_REG_GPIO_12_PU_LEN) - 1) << GLB_REG_GPIO_12_PU_POS) +#define GLB_REG_GPIO_12_PU_UMSK (~(((1U << GLB_REG_GPIO_12_PU_LEN) - 1) << GLB_REG_GPIO_12_PU_POS)) +#define GLB_REG_GPIO_12_PD GLB_REG_GPIO_12_PD +#define GLB_REG_GPIO_12_PD_POS (5U) +#define GLB_REG_GPIO_12_PD_LEN (1U) +#define GLB_REG_GPIO_12_PD_MSK (((1U << GLB_REG_GPIO_12_PD_LEN) - 1) << GLB_REG_GPIO_12_PD_POS) +#define GLB_REG_GPIO_12_PD_UMSK (~(((1U << GLB_REG_GPIO_12_PD_LEN) - 1) << GLB_REG_GPIO_12_PD_POS)) +#define GLB_REG_GPIO_12_OE GLB_REG_GPIO_12_OE +#define GLB_REG_GPIO_12_OE_POS (6U) +#define GLB_REG_GPIO_12_OE_LEN (1U) +#define GLB_REG_GPIO_12_OE_MSK (((1U << GLB_REG_GPIO_12_OE_LEN) - 1) << GLB_REG_GPIO_12_OE_POS) +#define GLB_REG_GPIO_12_OE_UMSK (~(((1U << GLB_REG_GPIO_12_OE_LEN) - 1) << GLB_REG_GPIO_12_OE_POS)) +#define GLB_REG_GPIO_12_FUNC_SEL GLB_REG_GPIO_12_FUNC_SEL +#define GLB_REG_GPIO_12_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_12_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_12_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_12_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_12_FUNC_SEL_POS) +#define GLB_REG_GPIO_12_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_12_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_12_FUNC_SEL_POS)) +#define GLB_REG_GPIO_12_INT_MODE_SET GLB_REG_GPIO_12_INT_MODE_SET +#define GLB_REG_GPIO_12_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_12_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_12_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_12_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_12_INT_MODE_SET_POS) +#define GLB_REG_GPIO_12_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_12_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_12_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_12_INT_CLR GLB_REG_GPIO_12_INT_CLR +#define GLB_REG_GPIO_12_INT_CLR_POS (20U) +#define GLB_REG_GPIO_12_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_12_INT_CLR_MSK (((1U << GLB_REG_GPIO_12_INT_CLR_LEN) - 1) << GLB_REG_GPIO_12_INT_CLR_POS) +#define GLB_REG_GPIO_12_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_12_INT_CLR_LEN) - 1) << GLB_REG_GPIO_12_INT_CLR_POS)) +#define GLB_GPIO_12_INT_STAT GLB_GPIO_12_INT_STAT +#define GLB_GPIO_12_INT_STAT_POS (21U) +#define GLB_GPIO_12_INT_STAT_LEN (1U) +#define GLB_GPIO_12_INT_STAT_MSK (((1U << GLB_GPIO_12_INT_STAT_LEN) - 1) << GLB_GPIO_12_INT_STAT_POS) +#define GLB_GPIO_12_INT_STAT_UMSK (~(((1U << GLB_GPIO_12_INT_STAT_LEN) - 1) << GLB_GPIO_12_INT_STAT_POS)) +#define GLB_REG_GPIO_12_INT_MASK GLB_REG_GPIO_12_INT_MASK +#define GLB_REG_GPIO_12_INT_MASK_POS (22U) +#define GLB_REG_GPIO_12_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_12_INT_MASK_MSK (((1U << GLB_REG_GPIO_12_INT_MASK_LEN) - 1) << GLB_REG_GPIO_12_INT_MASK_POS) +#define GLB_REG_GPIO_12_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_12_INT_MASK_LEN) - 1) << GLB_REG_GPIO_12_INT_MASK_POS)) +#define GLB_REG_GPIO_12_O GLB_REG_GPIO_12_O +#define GLB_REG_GPIO_12_O_POS (24U) +#define GLB_REG_GPIO_12_O_LEN (1U) +#define GLB_REG_GPIO_12_O_MSK (((1U << GLB_REG_GPIO_12_O_LEN) - 1) << GLB_REG_GPIO_12_O_POS) +#define GLB_REG_GPIO_12_O_UMSK (~(((1U << GLB_REG_GPIO_12_O_LEN) - 1) << GLB_REG_GPIO_12_O_POS)) +#define GLB_REG_GPIO_12_SET GLB_REG_GPIO_12_SET +#define GLB_REG_GPIO_12_SET_POS (25U) +#define GLB_REG_GPIO_12_SET_LEN (1U) +#define GLB_REG_GPIO_12_SET_MSK (((1U << GLB_REG_GPIO_12_SET_LEN) - 1) << GLB_REG_GPIO_12_SET_POS) +#define GLB_REG_GPIO_12_SET_UMSK (~(((1U << GLB_REG_GPIO_12_SET_LEN) - 1) << GLB_REG_GPIO_12_SET_POS)) +#define GLB_REG_GPIO_12_CLR GLB_REG_GPIO_12_CLR +#define GLB_REG_GPIO_12_CLR_POS (26U) +#define GLB_REG_GPIO_12_CLR_LEN (1U) +#define GLB_REG_GPIO_12_CLR_MSK (((1U << GLB_REG_GPIO_12_CLR_LEN) - 1) << GLB_REG_GPIO_12_CLR_POS) +#define GLB_REG_GPIO_12_CLR_UMSK (~(((1U << GLB_REG_GPIO_12_CLR_LEN) - 1) << GLB_REG_GPIO_12_CLR_POS)) +#define GLB_REG_GPIO_12_I GLB_REG_GPIO_12_I +#define GLB_REG_GPIO_12_I_POS (28U) +#define GLB_REG_GPIO_12_I_LEN (1U) +#define GLB_REG_GPIO_12_I_MSK (((1U << GLB_REG_GPIO_12_I_LEN) - 1) << GLB_REG_GPIO_12_I_POS) +#define GLB_REG_GPIO_12_I_UMSK (~(((1U << GLB_REG_GPIO_12_I_LEN) - 1) << GLB_REG_GPIO_12_I_POS)) +#define GLB_REG_GPIO_12_MODE GLB_REG_GPIO_12_MODE +#define GLB_REG_GPIO_12_MODE_POS (30U) +#define GLB_REG_GPIO_12_MODE_LEN (2U) +#define GLB_REG_GPIO_12_MODE_MSK (((1U << GLB_REG_GPIO_12_MODE_LEN) - 1) << GLB_REG_GPIO_12_MODE_POS) +#define GLB_REG_GPIO_12_MODE_UMSK (~(((1U << GLB_REG_GPIO_12_MODE_LEN) - 1) << GLB_REG_GPIO_12_MODE_POS)) + +/* 0x8F8 : gpio_cfg13 */ +#define GLB_GPIO_CFG13_OFFSET (0x8F8) +#define GLB_REG_GPIO_13_IE GLB_REG_GPIO_13_IE +#define GLB_REG_GPIO_13_IE_POS (0U) +#define GLB_REG_GPIO_13_IE_LEN (1U) +#define GLB_REG_GPIO_13_IE_MSK (((1U << GLB_REG_GPIO_13_IE_LEN) - 1) << GLB_REG_GPIO_13_IE_POS) +#define GLB_REG_GPIO_13_IE_UMSK (~(((1U << GLB_REG_GPIO_13_IE_LEN) - 1) << GLB_REG_GPIO_13_IE_POS)) +#define GLB_REG_GPIO_13_SMT GLB_REG_GPIO_13_SMT +#define GLB_REG_GPIO_13_SMT_POS (1U) +#define GLB_REG_GPIO_13_SMT_LEN (1U) +#define GLB_REG_GPIO_13_SMT_MSK (((1U << GLB_REG_GPIO_13_SMT_LEN) - 1) << GLB_REG_GPIO_13_SMT_POS) +#define GLB_REG_GPIO_13_SMT_UMSK (~(((1U << GLB_REG_GPIO_13_SMT_LEN) - 1) << GLB_REG_GPIO_13_SMT_POS)) +#define GLB_REG_GPIO_13_DRV GLB_REG_GPIO_13_DRV +#define GLB_REG_GPIO_13_DRV_POS (2U) +#define GLB_REG_GPIO_13_DRV_LEN (2U) +#define GLB_REG_GPIO_13_DRV_MSK (((1U << GLB_REG_GPIO_13_DRV_LEN) - 1) << GLB_REG_GPIO_13_DRV_POS) +#define GLB_REG_GPIO_13_DRV_UMSK (~(((1U << GLB_REG_GPIO_13_DRV_LEN) - 1) << GLB_REG_GPIO_13_DRV_POS)) +#define GLB_REG_GPIO_13_PU GLB_REG_GPIO_13_PU +#define GLB_REG_GPIO_13_PU_POS (4U) +#define GLB_REG_GPIO_13_PU_LEN (1U) +#define GLB_REG_GPIO_13_PU_MSK (((1U << GLB_REG_GPIO_13_PU_LEN) - 1) << GLB_REG_GPIO_13_PU_POS) +#define GLB_REG_GPIO_13_PU_UMSK (~(((1U << GLB_REG_GPIO_13_PU_LEN) - 1) << GLB_REG_GPIO_13_PU_POS)) +#define GLB_REG_GPIO_13_PD GLB_REG_GPIO_13_PD +#define GLB_REG_GPIO_13_PD_POS (5U) +#define GLB_REG_GPIO_13_PD_LEN (1U) +#define GLB_REG_GPIO_13_PD_MSK (((1U << GLB_REG_GPIO_13_PD_LEN) - 1) << GLB_REG_GPIO_13_PD_POS) +#define GLB_REG_GPIO_13_PD_UMSK (~(((1U << GLB_REG_GPIO_13_PD_LEN) - 1) << GLB_REG_GPIO_13_PD_POS)) +#define GLB_REG_GPIO_13_OE GLB_REG_GPIO_13_OE +#define GLB_REG_GPIO_13_OE_POS (6U) +#define GLB_REG_GPIO_13_OE_LEN (1U) +#define GLB_REG_GPIO_13_OE_MSK (((1U << GLB_REG_GPIO_13_OE_LEN) - 1) << GLB_REG_GPIO_13_OE_POS) +#define GLB_REG_GPIO_13_OE_UMSK (~(((1U << GLB_REG_GPIO_13_OE_LEN) - 1) << GLB_REG_GPIO_13_OE_POS)) +#define GLB_REG_GPIO_13_FUNC_SEL GLB_REG_GPIO_13_FUNC_SEL +#define GLB_REG_GPIO_13_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_13_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_13_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_13_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_13_FUNC_SEL_POS) +#define GLB_REG_GPIO_13_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_13_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_13_FUNC_SEL_POS)) +#define GLB_REG_GPIO_13_INT_MODE_SET GLB_REG_GPIO_13_INT_MODE_SET +#define GLB_REG_GPIO_13_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_13_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_13_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_13_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_13_INT_MODE_SET_POS) +#define GLB_REG_GPIO_13_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_13_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_13_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_13_INT_CLR GLB_REG_GPIO_13_INT_CLR +#define GLB_REG_GPIO_13_INT_CLR_POS (20U) +#define GLB_REG_GPIO_13_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_13_INT_CLR_MSK (((1U << GLB_REG_GPIO_13_INT_CLR_LEN) - 1) << GLB_REG_GPIO_13_INT_CLR_POS) +#define GLB_REG_GPIO_13_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_13_INT_CLR_LEN) - 1) << GLB_REG_GPIO_13_INT_CLR_POS)) +#define GLB_GPIO_13_INT_STAT GLB_GPIO_13_INT_STAT +#define GLB_GPIO_13_INT_STAT_POS (21U) +#define GLB_GPIO_13_INT_STAT_LEN (1U) +#define GLB_GPIO_13_INT_STAT_MSK (((1U << GLB_GPIO_13_INT_STAT_LEN) - 1) << GLB_GPIO_13_INT_STAT_POS) +#define GLB_GPIO_13_INT_STAT_UMSK (~(((1U << GLB_GPIO_13_INT_STAT_LEN) - 1) << GLB_GPIO_13_INT_STAT_POS)) +#define GLB_REG_GPIO_13_INT_MASK GLB_REG_GPIO_13_INT_MASK +#define GLB_REG_GPIO_13_INT_MASK_POS (22U) +#define GLB_REG_GPIO_13_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_13_INT_MASK_MSK (((1U << GLB_REG_GPIO_13_INT_MASK_LEN) - 1) << GLB_REG_GPIO_13_INT_MASK_POS) +#define GLB_REG_GPIO_13_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_13_INT_MASK_LEN) - 1) << GLB_REG_GPIO_13_INT_MASK_POS)) +#define GLB_REG_GPIO_13_O GLB_REG_GPIO_13_O +#define GLB_REG_GPIO_13_O_POS (24U) +#define GLB_REG_GPIO_13_O_LEN (1U) +#define GLB_REG_GPIO_13_O_MSK (((1U << GLB_REG_GPIO_13_O_LEN) - 1) << GLB_REG_GPIO_13_O_POS) +#define GLB_REG_GPIO_13_O_UMSK (~(((1U << GLB_REG_GPIO_13_O_LEN) - 1) << GLB_REG_GPIO_13_O_POS)) +#define GLB_REG_GPIO_13_SET GLB_REG_GPIO_13_SET +#define GLB_REG_GPIO_13_SET_POS (25U) +#define GLB_REG_GPIO_13_SET_LEN (1U) +#define GLB_REG_GPIO_13_SET_MSK (((1U << GLB_REG_GPIO_13_SET_LEN) - 1) << GLB_REG_GPIO_13_SET_POS) +#define GLB_REG_GPIO_13_SET_UMSK (~(((1U << GLB_REG_GPIO_13_SET_LEN) - 1) << GLB_REG_GPIO_13_SET_POS)) +#define GLB_REG_GPIO_13_CLR GLB_REG_GPIO_13_CLR +#define GLB_REG_GPIO_13_CLR_POS (26U) +#define GLB_REG_GPIO_13_CLR_LEN (1U) +#define GLB_REG_GPIO_13_CLR_MSK (((1U << GLB_REG_GPIO_13_CLR_LEN) - 1) << GLB_REG_GPIO_13_CLR_POS) +#define GLB_REG_GPIO_13_CLR_UMSK (~(((1U << GLB_REG_GPIO_13_CLR_LEN) - 1) << GLB_REG_GPIO_13_CLR_POS)) +#define GLB_REG_GPIO_13_I GLB_REG_GPIO_13_I +#define GLB_REG_GPIO_13_I_POS (28U) +#define GLB_REG_GPIO_13_I_LEN (1U) +#define GLB_REG_GPIO_13_I_MSK (((1U << GLB_REG_GPIO_13_I_LEN) - 1) << GLB_REG_GPIO_13_I_POS) +#define GLB_REG_GPIO_13_I_UMSK (~(((1U << GLB_REG_GPIO_13_I_LEN) - 1) << GLB_REG_GPIO_13_I_POS)) +#define GLB_REG_GPIO_13_MODE GLB_REG_GPIO_13_MODE +#define GLB_REG_GPIO_13_MODE_POS (30U) +#define GLB_REG_GPIO_13_MODE_LEN (2U) +#define GLB_REG_GPIO_13_MODE_MSK (((1U << GLB_REG_GPIO_13_MODE_LEN) - 1) << GLB_REG_GPIO_13_MODE_POS) +#define GLB_REG_GPIO_13_MODE_UMSK (~(((1U << GLB_REG_GPIO_13_MODE_LEN) - 1) << GLB_REG_GPIO_13_MODE_POS)) + +/* 0x8FC : gpio_cfg14 */ +#define GLB_GPIO_CFG14_OFFSET (0x8FC) +#define GLB_REG_GPIO_14_IE GLB_REG_GPIO_14_IE +#define GLB_REG_GPIO_14_IE_POS (0U) +#define GLB_REG_GPIO_14_IE_LEN (1U) +#define GLB_REG_GPIO_14_IE_MSK (((1U << GLB_REG_GPIO_14_IE_LEN) - 1) << GLB_REG_GPIO_14_IE_POS) +#define GLB_REG_GPIO_14_IE_UMSK (~(((1U << GLB_REG_GPIO_14_IE_LEN) - 1) << GLB_REG_GPIO_14_IE_POS)) +#define GLB_REG_GPIO_14_SMT GLB_REG_GPIO_14_SMT +#define GLB_REG_GPIO_14_SMT_POS (1U) +#define GLB_REG_GPIO_14_SMT_LEN (1U) +#define GLB_REG_GPIO_14_SMT_MSK (((1U << GLB_REG_GPIO_14_SMT_LEN) - 1) << GLB_REG_GPIO_14_SMT_POS) +#define GLB_REG_GPIO_14_SMT_UMSK (~(((1U << GLB_REG_GPIO_14_SMT_LEN) - 1) << GLB_REG_GPIO_14_SMT_POS)) +#define GLB_REG_GPIO_14_DRV GLB_REG_GPIO_14_DRV +#define GLB_REG_GPIO_14_DRV_POS (2U) +#define GLB_REG_GPIO_14_DRV_LEN (2U) +#define GLB_REG_GPIO_14_DRV_MSK (((1U << GLB_REG_GPIO_14_DRV_LEN) - 1) << GLB_REG_GPIO_14_DRV_POS) +#define GLB_REG_GPIO_14_DRV_UMSK (~(((1U << GLB_REG_GPIO_14_DRV_LEN) - 1) << GLB_REG_GPIO_14_DRV_POS)) +#define GLB_REG_GPIO_14_PU GLB_REG_GPIO_14_PU +#define GLB_REG_GPIO_14_PU_POS (4U) +#define GLB_REG_GPIO_14_PU_LEN (1U) +#define GLB_REG_GPIO_14_PU_MSK (((1U << GLB_REG_GPIO_14_PU_LEN) - 1) << GLB_REG_GPIO_14_PU_POS) +#define GLB_REG_GPIO_14_PU_UMSK (~(((1U << GLB_REG_GPIO_14_PU_LEN) - 1) << GLB_REG_GPIO_14_PU_POS)) +#define GLB_REG_GPIO_14_PD GLB_REG_GPIO_14_PD +#define GLB_REG_GPIO_14_PD_POS (5U) +#define GLB_REG_GPIO_14_PD_LEN (1U) +#define GLB_REG_GPIO_14_PD_MSK (((1U << GLB_REG_GPIO_14_PD_LEN) - 1) << GLB_REG_GPIO_14_PD_POS) +#define GLB_REG_GPIO_14_PD_UMSK (~(((1U << GLB_REG_GPIO_14_PD_LEN) - 1) << GLB_REG_GPIO_14_PD_POS)) +#define GLB_REG_GPIO_14_OE GLB_REG_GPIO_14_OE +#define GLB_REG_GPIO_14_OE_POS (6U) +#define GLB_REG_GPIO_14_OE_LEN (1U) +#define GLB_REG_GPIO_14_OE_MSK (((1U << GLB_REG_GPIO_14_OE_LEN) - 1) << GLB_REG_GPIO_14_OE_POS) +#define GLB_REG_GPIO_14_OE_UMSK (~(((1U << GLB_REG_GPIO_14_OE_LEN) - 1) << GLB_REG_GPIO_14_OE_POS)) +#define GLB_REG_GPIO_14_FUNC_SEL GLB_REG_GPIO_14_FUNC_SEL +#define GLB_REG_GPIO_14_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_14_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_14_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_14_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_14_FUNC_SEL_POS) +#define GLB_REG_GPIO_14_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_14_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_14_FUNC_SEL_POS)) +#define GLB_REG_GPIO_14_INT_MODE_SET GLB_REG_GPIO_14_INT_MODE_SET +#define GLB_REG_GPIO_14_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_14_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_14_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_14_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_14_INT_MODE_SET_POS) +#define GLB_REG_GPIO_14_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_14_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_14_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_14_INT_CLR GLB_REG_GPIO_14_INT_CLR +#define GLB_REG_GPIO_14_INT_CLR_POS (20U) +#define GLB_REG_GPIO_14_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_14_INT_CLR_MSK (((1U << GLB_REG_GPIO_14_INT_CLR_LEN) - 1) << GLB_REG_GPIO_14_INT_CLR_POS) +#define GLB_REG_GPIO_14_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_14_INT_CLR_LEN) - 1) << GLB_REG_GPIO_14_INT_CLR_POS)) +#define GLB_GPIO_14_INT_STAT GLB_GPIO_14_INT_STAT +#define GLB_GPIO_14_INT_STAT_POS (21U) +#define GLB_GPIO_14_INT_STAT_LEN (1U) +#define GLB_GPIO_14_INT_STAT_MSK (((1U << GLB_GPIO_14_INT_STAT_LEN) - 1) << GLB_GPIO_14_INT_STAT_POS) +#define GLB_GPIO_14_INT_STAT_UMSK (~(((1U << GLB_GPIO_14_INT_STAT_LEN) - 1) << GLB_GPIO_14_INT_STAT_POS)) +#define GLB_REG_GPIO_14_INT_MASK GLB_REG_GPIO_14_INT_MASK +#define GLB_REG_GPIO_14_INT_MASK_POS (22U) +#define GLB_REG_GPIO_14_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_14_INT_MASK_MSK (((1U << GLB_REG_GPIO_14_INT_MASK_LEN) - 1) << GLB_REG_GPIO_14_INT_MASK_POS) +#define GLB_REG_GPIO_14_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_14_INT_MASK_LEN) - 1) << GLB_REG_GPIO_14_INT_MASK_POS)) +#define GLB_REG_GPIO_14_O GLB_REG_GPIO_14_O +#define GLB_REG_GPIO_14_O_POS (24U) +#define GLB_REG_GPIO_14_O_LEN (1U) +#define GLB_REG_GPIO_14_O_MSK (((1U << GLB_REG_GPIO_14_O_LEN) - 1) << GLB_REG_GPIO_14_O_POS) +#define GLB_REG_GPIO_14_O_UMSK (~(((1U << GLB_REG_GPIO_14_O_LEN) - 1) << GLB_REG_GPIO_14_O_POS)) +#define GLB_REG_GPIO_14_SET GLB_REG_GPIO_14_SET +#define GLB_REG_GPIO_14_SET_POS (25U) +#define GLB_REG_GPIO_14_SET_LEN (1U) +#define GLB_REG_GPIO_14_SET_MSK (((1U << GLB_REG_GPIO_14_SET_LEN) - 1) << GLB_REG_GPIO_14_SET_POS) +#define GLB_REG_GPIO_14_SET_UMSK (~(((1U << GLB_REG_GPIO_14_SET_LEN) - 1) << GLB_REG_GPIO_14_SET_POS)) +#define GLB_REG_GPIO_14_CLR GLB_REG_GPIO_14_CLR +#define GLB_REG_GPIO_14_CLR_POS (26U) +#define GLB_REG_GPIO_14_CLR_LEN (1U) +#define GLB_REG_GPIO_14_CLR_MSK (((1U << GLB_REG_GPIO_14_CLR_LEN) - 1) << GLB_REG_GPIO_14_CLR_POS) +#define GLB_REG_GPIO_14_CLR_UMSK (~(((1U << GLB_REG_GPIO_14_CLR_LEN) - 1) << GLB_REG_GPIO_14_CLR_POS)) +#define GLB_REG_GPIO_14_I GLB_REG_GPIO_14_I +#define GLB_REG_GPIO_14_I_POS (28U) +#define GLB_REG_GPIO_14_I_LEN (1U) +#define GLB_REG_GPIO_14_I_MSK (((1U << GLB_REG_GPIO_14_I_LEN) - 1) << GLB_REG_GPIO_14_I_POS) +#define GLB_REG_GPIO_14_I_UMSK (~(((1U << GLB_REG_GPIO_14_I_LEN) - 1) << GLB_REG_GPIO_14_I_POS)) +#define GLB_REG_GPIO_14_MODE GLB_REG_GPIO_14_MODE +#define GLB_REG_GPIO_14_MODE_POS (30U) +#define GLB_REG_GPIO_14_MODE_LEN (2U) +#define GLB_REG_GPIO_14_MODE_MSK (((1U << GLB_REG_GPIO_14_MODE_LEN) - 1) << GLB_REG_GPIO_14_MODE_POS) +#define GLB_REG_GPIO_14_MODE_UMSK (~(((1U << GLB_REG_GPIO_14_MODE_LEN) - 1) << GLB_REG_GPIO_14_MODE_POS)) + +/* 0x900 : gpio_cfg15 */ +#define GLB_GPIO_CFG15_OFFSET (0x900) +#define GLB_REG_GPIO_15_IE GLB_REG_GPIO_15_IE +#define GLB_REG_GPIO_15_IE_POS (0U) +#define GLB_REG_GPIO_15_IE_LEN (1U) +#define GLB_REG_GPIO_15_IE_MSK (((1U << GLB_REG_GPIO_15_IE_LEN) - 1) << GLB_REG_GPIO_15_IE_POS) +#define GLB_REG_GPIO_15_IE_UMSK (~(((1U << GLB_REG_GPIO_15_IE_LEN) - 1) << GLB_REG_GPIO_15_IE_POS)) +#define GLB_REG_GPIO_15_SMT GLB_REG_GPIO_15_SMT +#define GLB_REG_GPIO_15_SMT_POS (1U) +#define GLB_REG_GPIO_15_SMT_LEN (1U) +#define GLB_REG_GPIO_15_SMT_MSK (((1U << GLB_REG_GPIO_15_SMT_LEN) - 1) << GLB_REG_GPIO_15_SMT_POS) +#define GLB_REG_GPIO_15_SMT_UMSK (~(((1U << GLB_REG_GPIO_15_SMT_LEN) - 1) << GLB_REG_GPIO_15_SMT_POS)) +#define GLB_REG_GPIO_15_DRV GLB_REG_GPIO_15_DRV +#define GLB_REG_GPIO_15_DRV_POS (2U) +#define GLB_REG_GPIO_15_DRV_LEN (2U) +#define GLB_REG_GPIO_15_DRV_MSK (((1U << GLB_REG_GPIO_15_DRV_LEN) - 1) << GLB_REG_GPIO_15_DRV_POS) +#define GLB_REG_GPIO_15_DRV_UMSK (~(((1U << GLB_REG_GPIO_15_DRV_LEN) - 1) << GLB_REG_GPIO_15_DRV_POS)) +#define GLB_REG_GPIO_15_PU GLB_REG_GPIO_15_PU +#define GLB_REG_GPIO_15_PU_POS (4U) +#define GLB_REG_GPIO_15_PU_LEN (1U) +#define GLB_REG_GPIO_15_PU_MSK (((1U << GLB_REG_GPIO_15_PU_LEN) - 1) << GLB_REG_GPIO_15_PU_POS) +#define GLB_REG_GPIO_15_PU_UMSK (~(((1U << GLB_REG_GPIO_15_PU_LEN) - 1) << GLB_REG_GPIO_15_PU_POS)) +#define GLB_REG_GPIO_15_PD GLB_REG_GPIO_15_PD +#define GLB_REG_GPIO_15_PD_POS (5U) +#define GLB_REG_GPIO_15_PD_LEN (1U) +#define GLB_REG_GPIO_15_PD_MSK (((1U << GLB_REG_GPIO_15_PD_LEN) - 1) << GLB_REG_GPIO_15_PD_POS) +#define GLB_REG_GPIO_15_PD_UMSK (~(((1U << GLB_REG_GPIO_15_PD_LEN) - 1) << GLB_REG_GPIO_15_PD_POS)) +#define GLB_REG_GPIO_15_OE GLB_REG_GPIO_15_OE +#define GLB_REG_GPIO_15_OE_POS (6U) +#define GLB_REG_GPIO_15_OE_LEN (1U) +#define GLB_REG_GPIO_15_OE_MSK (((1U << GLB_REG_GPIO_15_OE_LEN) - 1) << GLB_REG_GPIO_15_OE_POS) +#define GLB_REG_GPIO_15_OE_UMSK (~(((1U << GLB_REG_GPIO_15_OE_LEN) - 1) << GLB_REG_GPIO_15_OE_POS)) +#define GLB_REG_GPIO_15_FUNC_SEL GLB_REG_GPIO_15_FUNC_SEL +#define GLB_REG_GPIO_15_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_15_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_15_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_15_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_15_FUNC_SEL_POS) +#define GLB_REG_GPIO_15_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_15_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_15_FUNC_SEL_POS)) +#define GLB_REG_GPIO_15_INT_MODE_SET GLB_REG_GPIO_15_INT_MODE_SET +#define GLB_REG_GPIO_15_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_15_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_15_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_15_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_15_INT_MODE_SET_POS) +#define GLB_REG_GPIO_15_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_15_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_15_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_15_INT_CLR GLB_REG_GPIO_15_INT_CLR +#define GLB_REG_GPIO_15_INT_CLR_POS (20U) +#define GLB_REG_GPIO_15_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_15_INT_CLR_MSK (((1U << GLB_REG_GPIO_15_INT_CLR_LEN) - 1) << GLB_REG_GPIO_15_INT_CLR_POS) +#define GLB_REG_GPIO_15_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_15_INT_CLR_LEN) - 1) << GLB_REG_GPIO_15_INT_CLR_POS)) +#define GLB_GPIO_15_INT_STAT GLB_GPIO_15_INT_STAT +#define GLB_GPIO_15_INT_STAT_POS (21U) +#define GLB_GPIO_15_INT_STAT_LEN (1U) +#define GLB_GPIO_15_INT_STAT_MSK (((1U << GLB_GPIO_15_INT_STAT_LEN) - 1) << GLB_GPIO_15_INT_STAT_POS) +#define GLB_GPIO_15_INT_STAT_UMSK (~(((1U << GLB_GPIO_15_INT_STAT_LEN) - 1) << GLB_GPIO_15_INT_STAT_POS)) +#define GLB_REG_GPIO_15_INT_MASK GLB_REG_GPIO_15_INT_MASK +#define GLB_REG_GPIO_15_INT_MASK_POS (22U) +#define GLB_REG_GPIO_15_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_15_INT_MASK_MSK (((1U << GLB_REG_GPIO_15_INT_MASK_LEN) - 1) << GLB_REG_GPIO_15_INT_MASK_POS) +#define GLB_REG_GPIO_15_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_15_INT_MASK_LEN) - 1) << GLB_REG_GPIO_15_INT_MASK_POS)) +#define GLB_REG_GPIO_15_O GLB_REG_GPIO_15_O +#define GLB_REG_GPIO_15_O_POS (24U) +#define GLB_REG_GPIO_15_O_LEN (1U) +#define GLB_REG_GPIO_15_O_MSK (((1U << GLB_REG_GPIO_15_O_LEN) - 1) << GLB_REG_GPIO_15_O_POS) +#define GLB_REG_GPIO_15_O_UMSK (~(((1U << GLB_REG_GPIO_15_O_LEN) - 1) << GLB_REG_GPIO_15_O_POS)) +#define GLB_REG_GPIO_15_SET GLB_REG_GPIO_15_SET +#define GLB_REG_GPIO_15_SET_POS (25U) +#define GLB_REG_GPIO_15_SET_LEN (1U) +#define GLB_REG_GPIO_15_SET_MSK (((1U << GLB_REG_GPIO_15_SET_LEN) - 1) << GLB_REG_GPIO_15_SET_POS) +#define GLB_REG_GPIO_15_SET_UMSK (~(((1U << GLB_REG_GPIO_15_SET_LEN) - 1) << GLB_REG_GPIO_15_SET_POS)) +#define GLB_REG_GPIO_15_CLR GLB_REG_GPIO_15_CLR +#define GLB_REG_GPIO_15_CLR_POS (26U) +#define GLB_REG_GPIO_15_CLR_LEN (1U) +#define GLB_REG_GPIO_15_CLR_MSK (((1U << GLB_REG_GPIO_15_CLR_LEN) - 1) << GLB_REG_GPIO_15_CLR_POS) +#define GLB_REG_GPIO_15_CLR_UMSK (~(((1U << GLB_REG_GPIO_15_CLR_LEN) - 1) << GLB_REG_GPIO_15_CLR_POS)) +#define GLB_REG_GPIO_15_I GLB_REG_GPIO_15_I +#define GLB_REG_GPIO_15_I_POS (28U) +#define GLB_REG_GPIO_15_I_LEN (1U) +#define GLB_REG_GPIO_15_I_MSK (((1U << GLB_REG_GPIO_15_I_LEN) - 1) << GLB_REG_GPIO_15_I_POS) +#define GLB_REG_GPIO_15_I_UMSK (~(((1U << GLB_REG_GPIO_15_I_LEN) - 1) << GLB_REG_GPIO_15_I_POS)) +#define GLB_REG_GPIO_15_MODE GLB_REG_GPIO_15_MODE +#define GLB_REG_GPIO_15_MODE_POS (30U) +#define GLB_REG_GPIO_15_MODE_LEN (2U) +#define GLB_REG_GPIO_15_MODE_MSK (((1U << GLB_REG_GPIO_15_MODE_LEN) - 1) << GLB_REG_GPIO_15_MODE_POS) +#define GLB_REG_GPIO_15_MODE_UMSK (~(((1U << GLB_REG_GPIO_15_MODE_LEN) - 1) << GLB_REG_GPIO_15_MODE_POS)) + +/* 0x904 : gpio_cfg16 */ +#define GLB_GPIO_CFG16_OFFSET (0x904) +#define GLB_REG_GPIO_16_IE GLB_REG_GPIO_16_IE +#define GLB_REG_GPIO_16_IE_POS (0U) +#define GLB_REG_GPIO_16_IE_LEN (1U) +#define GLB_REG_GPIO_16_IE_MSK (((1U << GLB_REG_GPIO_16_IE_LEN) - 1) << GLB_REG_GPIO_16_IE_POS) +#define GLB_REG_GPIO_16_IE_UMSK (~(((1U << GLB_REG_GPIO_16_IE_LEN) - 1) << GLB_REG_GPIO_16_IE_POS)) +#define GLB_REG_GPIO_16_SMT GLB_REG_GPIO_16_SMT +#define GLB_REG_GPIO_16_SMT_POS (1U) +#define GLB_REG_GPIO_16_SMT_LEN (1U) +#define GLB_REG_GPIO_16_SMT_MSK (((1U << GLB_REG_GPIO_16_SMT_LEN) - 1) << GLB_REG_GPIO_16_SMT_POS) +#define GLB_REG_GPIO_16_SMT_UMSK (~(((1U << GLB_REG_GPIO_16_SMT_LEN) - 1) << GLB_REG_GPIO_16_SMT_POS)) +#define GLB_REG_GPIO_16_DRV GLB_REG_GPIO_16_DRV +#define GLB_REG_GPIO_16_DRV_POS (2U) +#define GLB_REG_GPIO_16_DRV_LEN (2U) +#define GLB_REG_GPIO_16_DRV_MSK (((1U << GLB_REG_GPIO_16_DRV_LEN) - 1) << GLB_REG_GPIO_16_DRV_POS) +#define GLB_REG_GPIO_16_DRV_UMSK (~(((1U << GLB_REG_GPIO_16_DRV_LEN) - 1) << GLB_REG_GPIO_16_DRV_POS)) +#define GLB_REG_GPIO_16_PU GLB_REG_GPIO_16_PU +#define GLB_REG_GPIO_16_PU_POS (4U) +#define GLB_REG_GPIO_16_PU_LEN (1U) +#define GLB_REG_GPIO_16_PU_MSK (((1U << GLB_REG_GPIO_16_PU_LEN) - 1) << GLB_REG_GPIO_16_PU_POS) +#define GLB_REG_GPIO_16_PU_UMSK (~(((1U << GLB_REG_GPIO_16_PU_LEN) - 1) << GLB_REG_GPIO_16_PU_POS)) +#define GLB_REG_GPIO_16_PD GLB_REG_GPIO_16_PD +#define GLB_REG_GPIO_16_PD_POS (5U) +#define GLB_REG_GPIO_16_PD_LEN (1U) +#define GLB_REG_GPIO_16_PD_MSK (((1U << GLB_REG_GPIO_16_PD_LEN) - 1) << GLB_REG_GPIO_16_PD_POS) +#define GLB_REG_GPIO_16_PD_UMSK (~(((1U << GLB_REG_GPIO_16_PD_LEN) - 1) << GLB_REG_GPIO_16_PD_POS)) +#define GLB_REG_GPIO_16_OE GLB_REG_GPIO_16_OE +#define GLB_REG_GPIO_16_OE_POS (6U) +#define GLB_REG_GPIO_16_OE_LEN (1U) +#define GLB_REG_GPIO_16_OE_MSK (((1U << GLB_REG_GPIO_16_OE_LEN) - 1) << GLB_REG_GPIO_16_OE_POS) +#define GLB_REG_GPIO_16_OE_UMSK (~(((1U << GLB_REG_GPIO_16_OE_LEN) - 1) << GLB_REG_GPIO_16_OE_POS)) +#define GLB_REG_GPIO_16_FUNC_SEL GLB_REG_GPIO_16_FUNC_SEL +#define GLB_REG_GPIO_16_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_16_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_16_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_16_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_16_FUNC_SEL_POS) +#define GLB_REG_GPIO_16_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_16_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_16_FUNC_SEL_POS)) +#define GLB_REG_GPIO_16_INT_MODE_SET GLB_REG_GPIO_16_INT_MODE_SET +#define GLB_REG_GPIO_16_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_16_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_16_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_16_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_16_INT_MODE_SET_POS) +#define GLB_REG_GPIO_16_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_16_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_16_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_16_INT_CLR GLB_REG_GPIO_16_INT_CLR +#define GLB_REG_GPIO_16_INT_CLR_POS (20U) +#define GLB_REG_GPIO_16_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_16_INT_CLR_MSK (((1U << GLB_REG_GPIO_16_INT_CLR_LEN) - 1) << GLB_REG_GPIO_16_INT_CLR_POS) +#define GLB_REG_GPIO_16_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_16_INT_CLR_LEN) - 1) << GLB_REG_GPIO_16_INT_CLR_POS)) +#define GLB_GPIO_16_INT_STAT GLB_GPIO_16_INT_STAT +#define GLB_GPIO_16_INT_STAT_POS (21U) +#define GLB_GPIO_16_INT_STAT_LEN (1U) +#define GLB_GPIO_16_INT_STAT_MSK (((1U << GLB_GPIO_16_INT_STAT_LEN) - 1) << GLB_GPIO_16_INT_STAT_POS) +#define GLB_GPIO_16_INT_STAT_UMSK (~(((1U << GLB_GPIO_16_INT_STAT_LEN) - 1) << GLB_GPIO_16_INT_STAT_POS)) +#define GLB_REG_GPIO_16_INT_MASK GLB_REG_GPIO_16_INT_MASK +#define GLB_REG_GPIO_16_INT_MASK_POS (22U) +#define GLB_REG_GPIO_16_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_16_INT_MASK_MSK (((1U << GLB_REG_GPIO_16_INT_MASK_LEN) - 1) << GLB_REG_GPIO_16_INT_MASK_POS) +#define GLB_REG_GPIO_16_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_16_INT_MASK_LEN) - 1) << GLB_REG_GPIO_16_INT_MASK_POS)) +#define GLB_REG_GPIO_16_O GLB_REG_GPIO_16_O +#define GLB_REG_GPIO_16_O_POS (24U) +#define GLB_REG_GPIO_16_O_LEN (1U) +#define GLB_REG_GPIO_16_O_MSK (((1U << GLB_REG_GPIO_16_O_LEN) - 1) << GLB_REG_GPIO_16_O_POS) +#define GLB_REG_GPIO_16_O_UMSK (~(((1U << GLB_REG_GPIO_16_O_LEN) - 1) << GLB_REG_GPIO_16_O_POS)) +#define GLB_REG_GPIO_16_SET GLB_REG_GPIO_16_SET +#define GLB_REG_GPIO_16_SET_POS (25U) +#define GLB_REG_GPIO_16_SET_LEN (1U) +#define GLB_REG_GPIO_16_SET_MSK (((1U << GLB_REG_GPIO_16_SET_LEN) - 1) << GLB_REG_GPIO_16_SET_POS) +#define GLB_REG_GPIO_16_SET_UMSK (~(((1U << GLB_REG_GPIO_16_SET_LEN) - 1) << GLB_REG_GPIO_16_SET_POS)) +#define GLB_REG_GPIO_16_CLR GLB_REG_GPIO_16_CLR +#define GLB_REG_GPIO_16_CLR_POS (26U) +#define GLB_REG_GPIO_16_CLR_LEN (1U) +#define GLB_REG_GPIO_16_CLR_MSK (((1U << GLB_REG_GPIO_16_CLR_LEN) - 1) << GLB_REG_GPIO_16_CLR_POS) +#define GLB_REG_GPIO_16_CLR_UMSK (~(((1U << GLB_REG_GPIO_16_CLR_LEN) - 1) << GLB_REG_GPIO_16_CLR_POS)) +#define GLB_REG_GPIO_16_I GLB_REG_GPIO_16_I +#define GLB_REG_GPIO_16_I_POS (28U) +#define GLB_REG_GPIO_16_I_LEN (1U) +#define GLB_REG_GPIO_16_I_MSK (((1U << GLB_REG_GPIO_16_I_LEN) - 1) << GLB_REG_GPIO_16_I_POS) +#define GLB_REG_GPIO_16_I_UMSK (~(((1U << GLB_REG_GPIO_16_I_LEN) - 1) << GLB_REG_GPIO_16_I_POS)) +#define GLB_REG_GPIO_16_MODE GLB_REG_GPIO_16_MODE +#define GLB_REG_GPIO_16_MODE_POS (30U) +#define GLB_REG_GPIO_16_MODE_LEN (2U) +#define GLB_REG_GPIO_16_MODE_MSK (((1U << GLB_REG_GPIO_16_MODE_LEN) - 1) << GLB_REG_GPIO_16_MODE_POS) +#define GLB_REG_GPIO_16_MODE_UMSK (~(((1U << GLB_REG_GPIO_16_MODE_LEN) - 1) << GLB_REG_GPIO_16_MODE_POS)) + +/* 0x908 : gpio_cfg17 */ +#define GLB_GPIO_CFG17_OFFSET (0x908) +#define GLB_REG_GPIO_17_IE GLB_REG_GPIO_17_IE +#define GLB_REG_GPIO_17_IE_POS (0U) +#define GLB_REG_GPIO_17_IE_LEN (1U) +#define GLB_REG_GPIO_17_IE_MSK (((1U << GLB_REG_GPIO_17_IE_LEN) - 1) << GLB_REG_GPIO_17_IE_POS) +#define GLB_REG_GPIO_17_IE_UMSK (~(((1U << GLB_REG_GPIO_17_IE_LEN) - 1) << GLB_REG_GPIO_17_IE_POS)) +#define GLB_REG_GPIO_17_SMT GLB_REG_GPIO_17_SMT +#define GLB_REG_GPIO_17_SMT_POS (1U) +#define GLB_REG_GPIO_17_SMT_LEN (1U) +#define GLB_REG_GPIO_17_SMT_MSK (((1U << GLB_REG_GPIO_17_SMT_LEN) - 1) << GLB_REG_GPIO_17_SMT_POS) +#define GLB_REG_GPIO_17_SMT_UMSK (~(((1U << GLB_REG_GPIO_17_SMT_LEN) - 1) << GLB_REG_GPIO_17_SMT_POS)) +#define GLB_REG_GPIO_17_DRV GLB_REG_GPIO_17_DRV +#define GLB_REG_GPIO_17_DRV_POS (2U) +#define GLB_REG_GPIO_17_DRV_LEN (2U) +#define GLB_REG_GPIO_17_DRV_MSK (((1U << GLB_REG_GPIO_17_DRV_LEN) - 1) << GLB_REG_GPIO_17_DRV_POS) +#define GLB_REG_GPIO_17_DRV_UMSK (~(((1U << GLB_REG_GPIO_17_DRV_LEN) - 1) << GLB_REG_GPIO_17_DRV_POS)) +#define GLB_REG_GPIO_17_PU GLB_REG_GPIO_17_PU +#define GLB_REG_GPIO_17_PU_POS (4U) +#define GLB_REG_GPIO_17_PU_LEN (1U) +#define GLB_REG_GPIO_17_PU_MSK (((1U << GLB_REG_GPIO_17_PU_LEN) - 1) << GLB_REG_GPIO_17_PU_POS) +#define GLB_REG_GPIO_17_PU_UMSK (~(((1U << GLB_REG_GPIO_17_PU_LEN) - 1) << GLB_REG_GPIO_17_PU_POS)) +#define GLB_REG_GPIO_17_PD GLB_REG_GPIO_17_PD +#define GLB_REG_GPIO_17_PD_POS (5U) +#define GLB_REG_GPIO_17_PD_LEN (1U) +#define GLB_REG_GPIO_17_PD_MSK (((1U << GLB_REG_GPIO_17_PD_LEN) - 1) << GLB_REG_GPIO_17_PD_POS) +#define GLB_REG_GPIO_17_PD_UMSK (~(((1U << GLB_REG_GPIO_17_PD_LEN) - 1) << GLB_REG_GPIO_17_PD_POS)) +#define GLB_REG_GPIO_17_OE GLB_REG_GPIO_17_OE +#define GLB_REG_GPIO_17_OE_POS (6U) +#define GLB_REG_GPIO_17_OE_LEN (1U) +#define GLB_REG_GPIO_17_OE_MSK (((1U << GLB_REG_GPIO_17_OE_LEN) - 1) << GLB_REG_GPIO_17_OE_POS) +#define GLB_REG_GPIO_17_OE_UMSK (~(((1U << GLB_REG_GPIO_17_OE_LEN) - 1) << GLB_REG_GPIO_17_OE_POS)) +#define GLB_REG_GPIO_17_FUNC_SEL GLB_REG_GPIO_17_FUNC_SEL +#define GLB_REG_GPIO_17_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_17_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_17_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_17_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_17_FUNC_SEL_POS) +#define GLB_REG_GPIO_17_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_17_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_17_FUNC_SEL_POS)) +#define GLB_REG_GPIO_17_INT_MODE_SET GLB_REG_GPIO_17_INT_MODE_SET +#define GLB_REG_GPIO_17_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_17_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_17_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_17_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_17_INT_MODE_SET_POS) +#define GLB_REG_GPIO_17_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_17_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_17_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_17_INT_CLR GLB_REG_GPIO_17_INT_CLR +#define GLB_REG_GPIO_17_INT_CLR_POS (20U) +#define GLB_REG_GPIO_17_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_17_INT_CLR_MSK (((1U << GLB_REG_GPIO_17_INT_CLR_LEN) - 1) << GLB_REG_GPIO_17_INT_CLR_POS) +#define GLB_REG_GPIO_17_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_17_INT_CLR_LEN) - 1) << GLB_REG_GPIO_17_INT_CLR_POS)) +#define GLB_GPIO_17_INT_STAT GLB_GPIO_17_INT_STAT +#define GLB_GPIO_17_INT_STAT_POS (21U) +#define GLB_GPIO_17_INT_STAT_LEN (1U) +#define GLB_GPIO_17_INT_STAT_MSK (((1U << GLB_GPIO_17_INT_STAT_LEN) - 1) << GLB_GPIO_17_INT_STAT_POS) +#define GLB_GPIO_17_INT_STAT_UMSK (~(((1U << GLB_GPIO_17_INT_STAT_LEN) - 1) << GLB_GPIO_17_INT_STAT_POS)) +#define GLB_REG_GPIO_17_INT_MASK GLB_REG_GPIO_17_INT_MASK +#define GLB_REG_GPIO_17_INT_MASK_POS (22U) +#define GLB_REG_GPIO_17_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_17_INT_MASK_MSK (((1U << GLB_REG_GPIO_17_INT_MASK_LEN) - 1) << GLB_REG_GPIO_17_INT_MASK_POS) +#define GLB_REG_GPIO_17_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_17_INT_MASK_LEN) - 1) << GLB_REG_GPIO_17_INT_MASK_POS)) +#define GLB_REG_GPIO_17_O GLB_REG_GPIO_17_O +#define GLB_REG_GPIO_17_O_POS (24U) +#define GLB_REG_GPIO_17_O_LEN (1U) +#define GLB_REG_GPIO_17_O_MSK (((1U << GLB_REG_GPIO_17_O_LEN) - 1) << GLB_REG_GPIO_17_O_POS) +#define GLB_REG_GPIO_17_O_UMSK (~(((1U << GLB_REG_GPIO_17_O_LEN) - 1) << GLB_REG_GPIO_17_O_POS)) +#define GLB_REG_GPIO_17_SET GLB_REG_GPIO_17_SET +#define GLB_REG_GPIO_17_SET_POS (25U) +#define GLB_REG_GPIO_17_SET_LEN (1U) +#define GLB_REG_GPIO_17_SET_MSK (((1U << GLB_REG_GPIO_17_SET_LEN) - 1) << GLB_REG_GPIO_17_SET_POS) +#define GLB_REG_GPIO_17_SET_UMSK (~(((1U << GLB_REG_GPIO_17_SET_LEN) - 1) << GLB_REG_GPIO_17_SET_POS)) +#define GLB_REG_GPIO_17_CLR GLB_REG_GPIO_17_CLR +#define GLB_REG_GPIO_17_CLR_POS (26U) +#define GLB_REG_GPIO_17_CLR_LEN (1U) +#define GLB_REG_GPIO_17_CLR_MSK (((1U << GLB_REG_GPIO_17_CLR_LEN) - 1) << GLB_REG_GPIO_17_CLR_POS) +#define GLB_REG_GPIO_17_CLR_UMSK (~(((1U << GLB_REG_GPIO_17_CLR_LEN) - 1) << GLB_REG_GPIO_17_CLR_POS)) +#define GLB_REG_GPIO_17_I GLB_REG_GPIO_17_I +#define GLB_REG_GPIO_17_I_POS (28U) +#define GLB_REG_GPIO_17_I_LEN (1U) +#define GLB_REG_GPIO_17_I_MSK (((1U << GLB_REG_GPIO_17_I_LEN) - 1) << GLB_REG_GPIO_17_I_POS) +#define GLB_REG_GPIO_17_I_UMSK (~(((1U << GLB_REG_GPIO_17_I_LEN) - 1) << GLB_REG_GPIO_17_I_POS)) +#define GLB_REG_GPIO_17_MODE GLB_REG_GPIO_17_MODE +#define GLB_REG_GPIO_17_MODE_POS (30U) +#define GLB_REG_GPIO_17_MODE_LEN (2U) +#define GLB_REG_GPIO_17_MODE_MSK (((1U << GLB_REG_GPIO_17_MODE_LEN) - 1) << GLB_REG_GPIO_17_MODE_POS) +#define GLB_REG_GPIO_17_MODE_UMSK (~(((1U << GLB_REG_GPIO_17_MODE_LEN) - 1) << GLB_REG_GPIO_17_MODE_POS)) + +/* 0x90C : gpio_cfg18 */ +#define GLB_GPIO_CFG18_OFFSET (0x90C) +#define GLB_REG_GPIO_18_IE GLB_REG_GPIO_18_IE +#define GLB_REG_GPIO_18_IE_POS (0U) +#define GLB_REG_GPIO_18_IE_LEN (1U) +#define GLB_REG_GPIO_18_IE_MSK (((1U << GLB_REG_GPIO_18_IE_LEN) - 1) << GLB_REG_GPIO_18_IE_POS) +#define GLB_REG_GPIO_18_IE_UMSK (~(((1U << GLB_REG_GPIO_18_IE_LEN) - 1) << GLB_REG_GPIO_18_IE_POS)) +#define GLB_REG_GPIO_18_SMT GLB_REG_GPIO_18_SMT +#define GLB_REG_GPIO_18_SMT_POS (1U) +#define GLB_REG_GPIO_18_SMT_LEN (1U) +#define GLB_REG_GPIO_18_SMT_MSK (((1U << GLB_REG_GPIO_18_SMT_LEN) - 1) << GLB_REG_GPIO_18_SMT_POS) +#define GLB_REG_GPIO_18_SMT_UMSK (~(((1U << GLB_REG_GPIO_18_SMT_LEN) - 1) << GLB_REG_GPIO_18_SMT_POS)) +#define GLB_REG_GPIO_18_DRV GLB_REG_GPIO_18_DRV +#define GLB_REG_GPIO_18_DRV_POS (2U) +#define GLB_REG_GPIO_18_DRV_LEN (2U) +#define GLB_REG_GPIO_18_DRV_MSK (((1U << GLB_REG_GPIO_18_DRV_LEN) - 1) << GLB_REG_GPIO_18_DRV_POS) +#define GLB_REG_GPIO_18_DRV_UMSK (~(((1U << GLB_REG_GPIO_18_DRV_LEN) - 1) << GLB_REG_GPIO_18_DRV_POS)) +#define GLB_REG_GPIO_18_PU GLB_REG_GPIO_18_PU +#define GLB_REG_GPIO_18_PU_POS (4U) +#define GLB_REG_GPIO_18_PU_LEN (1U) +#define GLB_REG_GPIO_18_PU_MSK (((1U << GLB_REG_GPIO_18_PU_LEN) - 1) << GLB_REG_GPIO_18_PU_POS) +#define GLB_REG_GPIO_18_PU_UMSK (~(((1U << GLB_REG_GPIO_18_PU_LEN) - 1) << GLB_REG_GPIO_18_PU_POS)) +#define GLB_REG_GPIO_18_PD GLB_REG_GPIO_18_PD +#define GLB_REG_GPIO_18_PD_POS (5U) +#define GLB_REG_GPIO_18_PD_LEN (1U) +#define GLB_REG_GPIO_18_PD_MSK (((1U << GLB_REG_GPIO_18_PD_LEN) - 1) << GLB_REG_GPIO_18_PD_POS) +#define GLB_REG_GPIO_18_PD_UMSK (~(((1U << GLB_REG_GPIO_18_PD_LEN) - 1) << GLB_REG_GPIO_18_PD_POS)) +#define GLB_REG_GPIO_18_OE GLB_REG_GPIO_18_OE +#define GLB_REG_GPIO_18_OE_POS (6U) +#define GLB_REG_GPIO_18_OE_LEN (1U) +#define GLB_REG_GPIO_18_OE_MSK (((1U << GLB_REG_GPIO_18_OE_LEN) - 1) << GLB_REG_GPIO_18_OE_POS) +#define GLB_REG_GPIO_18_OE_UMSK (~(((1U << GLB_REG_GPIO_18_OE_LEN) - 1) << GLB_REG_GPIO_18_OE_POS)) +#define GLB_REG_GPIO_18_FUNC_SEL GLB_REG_GPIO_18_FUNC_SEL +#define GLB_REG_GPIO_18_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_18_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_18_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_18_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_18_FUNC_SEL_POS) +#define GLB_REG_GPIO_18_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_18_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_18_FUNC_SEL_POS)) +#define GLB_REG_GPIO_18_INT_MODE_SET GLB_REG_GPIO_18_INT_MODE_SET +#define GLB_REG_GPIO_18_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_18_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_18_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_18_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_18_INT_MODE_SET_POS) +#define GLB_REG_GPIO_18_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_18_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_18_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_18_INT_CLR GLB_REG_GPIO_18_INT_CLR +#define GLB_REG_GPIO_18_INT_CLR_POS (20U) +#define GLB_REG_GPIO_18_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_18_INT_CLR_MSK (((1U << GLB_REG_GPIO_18_INT_CLR_LEN) - 1) << GLB_REG_GPIO_18_INT_CLR_POS) +#define GLB_REG_GPIO_18_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_18_INT_CLR_LEN) - 1) << GLB_REG_GPIO_18_INT_CLR_POS)) +#define GLB_GPIO_18_INT_STAT GLB_GPIO_18_INT_STAT +#define GLB_GPIO_18_INT_STAT_POS (21U) +#define GLB_GPIO_18_INT_STAT_LEN (1U) +#define GLB_GPIO_18_INT_STAT_MSK (((1U << GLB_GPIO_18_INT_STAT_LEN) - 1) << GLB_GPIO_18_INT_STAT_POS) +#define GLB_GPIO_18_INT_STAT_UMSK (~(((1U << GLB_GPIO_18_INT_STAT_LEN) - 1) << GLB_GPIO_18_INT_STAT_POS)) +#define GLB_REG_GPIO_18_INT_MASK GLB_REG_GPIO_18_INT_MASK +#define GLB_REG_GPIO_18_INT_MASK_POS (22U) +#define GLB_REG_GPIO_18_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_18_INT_MASK_MSK (((1U << GLB_REG_GPIO_18_INT_MASK_LEN) - 1) << GLB_REG_GPIO_18_INT_MASK_POS) +#define GLB_REG_GPIO_18_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_18_INT_MASK_LEN) - 1) << GLB_REG_GPIO_18_INT_MASK_POS)) +#define GLB_REG_GPIO_18_O GLB_REG_GPIO_18_O +#define GLB_REG_GPIO_18_O_POS (24U) +#define GLB_REG_GPIO_18_O_LEN (1U) +#define GLB_REG_GPIO_18_O_MSK (((1U << GLB_REG_GPIO_18_O_LEN) - 1) << GLB_REG_GPIO_18_O_POS) +#define GLB_REG_GPIO_18_O_UMSK (~(((1U << GLB_REG_GPIO_18_O_LEN) - 1) << GLB_REG_GPIO_18_O_POS)) +#define GLB_REG_GPIO_18_SET GLB_REG_GPIO_18_SET +#define GLB_REG_GPIO_18_SET_POS (25U) +#define GLB_REG_GPIO_18_SET_LEN (1U) +#define GLB_REG_GPIO_18_SET_MSK (((1U << GLB_REG_GPIO_18_SET_LEN) - 1) << GLB_REG_GPIO_18_SET_POS) +#define GLB_REG_GPIO_18_SET_UMSK (~(((1U << GLB_REG_GPIO_18_SET_LEN) - 1) << GLB_REG_GPIO_18_SET_POS)) +#define GLB_REG_GPIO_18_CLR GLB_REG_GPIO_18_CLR +#define GLB_REG_GPIO_18_CLR_POS (26U) +#define GLB_REG_GPIO_18_CLR_LEN (1U) +#define GLB_REG_GPIO_18_CLR_MSK (((1U << GLB_REG_GPIO_18_CLR_LEN) - 1) << GLB_REG_GPIO_18_CLR_POS) +#define GLB_REG_GPIO_18_CLR_UMSK (~(((1U << GLB_REG_GPIO_18_CLR_LEN) - 1) << GLB_REG_GPIO_18_CLR_POS)) +#define GLB_REG_GPIO_18_I GLB_REG_GPIO_18_I +#define GLB_REG_GPIO_18_I_POS (28U) +#define GLB_REG_GPIO_18_I_LEN (1U) +#define GLB_REG_GPIO_18_I_MSK (((1U << GLB_REG_GPIO_18_I_LEN) - 1) << GLB_REG_GPIO_18_I_POS) +#define GLB_REG_GPIO_18_I_UMSK (~(((1U << GLB_REG_GPIO_18_I_LEN) - 1) << GLB_REG_GPIO_18_I_POS)) +#define GLB_REG_GPIO_18_MODE GLB_REG_GPIO_18_MODE +#define GLB_REG_GPIO_18_MODE_POS (30U) +#define GLB_REG_GPIO_18_MODE_LEN (2U) +#define GLB_REG_GPIO_18_MODE_MSK (((1U << GLB_REG_GPIO_18_MODE_LEN) - 1) << GLB_REG_GPIO_18_MODE_POS) +#define GLB_REG_GPIO_18_MODE_UMSK (~(((1U << GLB_REG_GPIO_18_MODE_LEN) - 1) << GLB_REG_GPIO_18_MODE_POS)) + +/* 0x910 : gpio_cfg19 */ +#define GLB_GPIO_CFG19_OFFSET (0x910) +#define GLB_REG_GPIO_19_IE GLB_REG_GPIO_19_IE +#define GLB_REG_GPIO_19_IE_POS (0U) +#define GLB_REG_GPIO_19_IE_LEN (1U) +#define GLB_REG_GPIO_19_IE_MSK (((1U << GLB_REG_GPIO_19_IE_LEN) - 1) << GLB_REG_GPIO_19_IE_POS) +#define GLB_REG_GPIO_19_IE_UMSK (~(((1U << GLB_REG_GPIO_19_IE_LEN) - 1) << GLB_REG_GPIO_19_IE_POS)) +#define GLB_REG_GPIO_19_SMT GLB_REG_GPIO_19_SMT +#define GLB_REG_GPIO_19_SMT_POS (1U) +#define GLB_REG_GPIO_19_SMT_LEN (1U) +#define GLB_REG_GPIO_19_SMT_MSK (((1U << GLB_REG_GPIO_19_SMT_LEN) - 1) << GLB_REG_GPIO_19_SMT_POS) +#define GLB_REG_GPIO_19_SMT_UMSK (~(((1U << GLB_REG_GPIO_19_SMT_LEN) - 1) << GLB_REG_GPIO_19_SMT_POS)) +#define GLB_REG_GPIO_19_DRV GLB_REG_GPIO_19_DRV +#define GLB_REG_GPIO_19_DRV_POS (2U) +#define GLB_REG_GPIO_19_DRV_LEN (2U) +#define GLB_REG_GPIO_19_DRV_MSK (((1U << GLB_REG_GPIO_19_DRV_LEN) - 1) << GLB_REG_GPIO_19_DRV_POS) +#define GLB_REG_GPIO_19_DRV_UMSK (~(((1U << GLB_REG_GPIO_19_DRV_LEN) - 1) << GLB_REG_GPIO_19_DRV_POS)) +#define GLB_REG_GPIO_19_PU GLB_REG_GPIO_19_PU +#define GLB_REG_GPIO_19_PU_POS (4U) +#define GLB_REG_GPIO_19_PU_LEN (1U) +#define GLB_REG_GPIO_19_PU_MSK (((1U << GLB_REG_GPIO_19_PU_LEN) - 1) << GLB_REG_GPIO_19_PU_POS) +#define GLB_REG_GPIO_19_PU_UMSK (~(((1U << GLB_REG_GPIO_19_PU_LEN) - 1) << GLB_REG_GPIO_19_PU_POS)) +#define GLB_REG_GPIO_19_PD GLB_REG_GPIO_19_PD +#define GLB_REG_GPIO_19_PD_POS (5U) +#define GLB_REG_GPIO_19_PD_LEN (1U) +#define GLB_REG_GPIO_19_PD_MSK (((1U << GLB_REG_GPIO_19_PD_LEN) - 1) << GLB_REG_GPIO_19_PD_POS) +#define GLB_REG_GPIO_19_PD_UMSK (~(((1U << GLB_REG_GPIO_19_PD_LEN) - 1) << GLB_REG_GPIO_19_PD_POS)) +#define GLB_REG_GPIO_19_OE GLB_REG_GPIO_19_OE +#define GLB_REG_GPIO_19_OE_POS (6U) +#define GLB_REG_GPIO_19_OE_LEN (1U) +#define GLB_REG_GPIO_19_OE_MSK (((1U << GLB_REG_GPIO_19_OE_LEN) - 1) << GLB_REG_GPIO_19_OE_POS) +#define GLB_REG_GPIO_19_OE_UMSK (~(((1U << GLB_REG_GPIO_19_OE_LEN) - 1) << GLB_REG_GPIO_19_OE_POS)) +#define GLB_REG_GPIO_19_FUNC_SEL GLB_REG_GPIO_19_FUNC_SEL +#define GLB_REG_GPIO_19_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_19_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_19_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_19_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_19_FUNC_SEL_POS) +#define GLB_REG_GPIO_19_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_19_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_19_FUNC_SEL_POS)) +#define GLB_REG_GPIO_19_INT_MODE_SET GLB_REG_GPIO_19_INT_MODE_SET +#define GLB_REG_GPIO_19_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_19_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_19_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_19_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_19_INT_MODE_SET_POS) +#define GLB_REG_GPIO_19_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_19_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_19_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_19_INT_CLR GLB_REG_GPIO_19_INT_CLR +#define GLB_REG_GPIO_19_INT_CLR_POS (20U) +#define GLB_REG_GPIO_19_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_19_INT_CLR_MSK (((1U << GLB_REG_GPIO_19_INT_CLR_LEN) - 1) << GLB_REG_GPIO_19_INT_CLR_POS) +#define GLB_REG_GPIO_19_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_19_INT_CLR_LEN) - 1) << GLB_REG_GPIO_19_INT_CLR_POS)) +#define GLB_GPIO_19_INT_STAT GLB_GPIO_19_INT_STAT +#define GLB_GPIO_19_INT_STAT_POS (21U) +#define GLB_GPIO_19_INT_STAT_LEN (1U) +#define GLB_GPIO_19_INT_STAT_MSK (((1U << GLB_GPIO_19_INT_STAT_LEN) - 1) << GLB_GPIO_19_INT_STAT_POS) +#define GLB_GPIO_19_INT_STAT_UMSK (~(((1U << GLB_GPIO_19_INT_STAT_LEN) - 1) << GLB_GPIO_19_INT_STAT_POS)) +#define GLB_REG_GPIO_19_INT_MASK GLB_REG_GPIO_19_INT_MASK +#define GLB_REG_GPIO_19_INT_MASK_POS (22U) +#define GLB_REG_GPIO_19_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_19_INT_MASK_MSK (((1U << GLB_REG_GPIO_19_INT_MASK_LEN) - 1) << GLB_REG_GPIO_19_INT_MASK_POS) +#define GLB_REG_GPIO_19_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_19_INT_MASK_LEN) - 1) << GLB_REG_GPIO_19_INT_MASK_POS)) +#define GLB_REG_GPIO_19_O GLB_REG_GPIO_19_O +#define GLB_REG_GPIO_19_O_POS (24U) +#define GLB_REG_GPIO_19_O_LEN (1U) +#define GLB_REG_GPIO_19_O_MSK (((1U << GLB_REG_GPIO_19_O_LEN) - 1) << GLB_REG_GPIO_19_O_POS) +#define GLB_REG_GPIO_19_O_UMSK (~(((1U << GLB_REG_GPIO_19_O_LEN) - 1) << GLB_REG_GPIO_19_O_POS)) +#define GLB_REG_GPIO_19_SET GLB_REG_GPIO_19_SET +#define GLB_REG_GPIO_19_SET_POS (25U) +#define GLB_REG_GPIO_19_SET_LEN (1U) +#define GLB_REG_GPIO_19_SET_MSK (((1U << GLB_REG_GPIO_19_SET_LEN) - 1) << GLB_REG_GPIO_19_SET_POS) +#define GLB_REG_GPIO_19_SET_UMSK (~(((1U << GLB_REG_GPIO_19_SET_LEN) - 1) << GLB_REG_GPIO_19_SET_POS)) +#define GLB_REG_GPIO_19_CLR GLB_REG_GPIO_19_CLR +#define GLB_REG_GPIO_19_CLR_POS (26U) +#define GLB_REG_GPIO_19_CLR_LEN (1U) +#define GLB_REG_GPIO_19_CLR_MSK (((1U << GLB_REG_GPIO_19_CLR_LEN) - 1) << GLB_REG_GPIO_19_CLR_POS) +#define GLB_REG_GPIO_19_CLR_UMSK (~(((1U << GLB_REG_GPIO_19_CLR_LEN) - 1) << GLB_REG_GPIO_19_CLR_POS)) +#define GLB_REG_GPIO_19_I GLB_REG_GPIO_19_I +#define GLB_REG_GPIO_19_I_POS (28U) +#define GLB_REG_GPIO_19_I_LEN (1U) +#define GLB_REG_GPIO_19_I_MSK (((1U << GLB_REG_GPIO_19_I_LEN) - 1) << GLB_REG_GPIO_19_I_POS) +#define GLB_REG_GPIO_19_I_UMSK (~(((1U << GLB_REG_GPIO_19_I_LEN) - 1) << GLB_REG_GPIO_19_I_POS)) +#define GLB_REG_GPIO_19_MODE GLB_REG_GPIO_19_MODE +#define GLB_REG_GPIO_19_MODE_POS (30U) +#define GLB_REG_GPIO_19_MODE_LEN (2U) +#define GLB_REG_GPIO_19_MODE_MSK (((1U << GLB_REG_GPIO_19_MODE_LEN) - 1) << GLB_REG_GPIO_19_MODE_POS) +#define GLB_REG_GPIO_19_MODE_UMSK (~(((1U << GLB_REG_GPIO_19_MODE_LEN) - 1) << GLB_REG_GPIO_19_MODE_POS)) + +/* 0x914 : gpio_cfg20 */ +#define GLB_GPIO_CFG20_OFFSET (0x914) +#define GLB_REG_GPIO_20_IE GLB_REG_GPIO_20_IE +#define GLB_REG_GPIO_20_IE_POS (0U) +#define GLB_REG_GPIO_20_IE_LEN (1U) +#define GLB_REG_GPIO_20_IE_MSK (((1U << GLB_REG_GPIO_20_IE_LEN) - 1) << GLB_REG_GPIO_20_IE_POS) +#define GLB_REG_GPIO_20_IE_UMSK (~(((1U << GLB_REG_GPIO_20_IE_LEN) - 1) << GLB_REG_GPIO_20_IE_POS)) +#define GLB_REG_GPIO_20_SMT GLB_REG_GPIO_20_SMT +#define GLB_REG_GPIO_20_SMT_POS (1U) +#define GLB_REG_GPIO_20_SMT_LEN (1U) +#define GLB_REG_GPIO_20_SMT_MSK (((1U << GLB_REG_GPIO_20_SMT_LEN) - 1) << GLB_REG_GPIO_20_SMT_POS) +#define GLB_REG_GPIO_20_SMT_UMSK (~(((1U << GLB_REG_GPIO_20_SMT_LEN) - 1) << GLB_REG_GPIO_20_SMT_POS)) +#define GLB_REG_GPIO_20_DRV GLB_REG_GPIO_20_DRV +#define GLB_REG_GPIO_20_DRV_POS (2U) +#define GLB_REG_GPIO_20_DRV_LEN (2U) +#define GLB_REG_GPIO_20_DRV_MSK (((1U << GLB_REG_GPIO_20_DRV_LEN) - 1) << GLB_REG_GPIO_20_DRV_POS) +#define GLB_REG_GPIO_20_DRV_UMSK (~(((1U << GLB_REG_GPIO_20_DRV_LEN) - 1) << GLB_REG_GPIO_20_DRV_POS)) +#define GLB_REG_GPIO_20_PU GLB_REG_GPIO_20_PU +#define GLB_REG_GPIO_20_PU_POS (4U) +#define GLB_REG_GPIO_20_PU_LEN (1U) +#define GLB_REG_GPIO_20_PU_MSK (((1U << GLB_REG_GPIO_20_PU_LEN) - 1) << GLB_REG_GPIO_20_PU_POS) +#define GLB_REG_GPIO_20_PU_UMSK (~(((1U << GLB_REG_GPIO_20_PU_LEN) - 1) << GLB_REG_GPIO_20_PU_POS)) +#define GLB_REG_GPIO_20_PD GLB_REG_GPIO_20_PD +#define GLB_REG_GPIO_20_PD_POS (5U) +#define GLB_REG_GPIO_20_PD_LEN (1U) +#define GLB_REG_GPIO_20_PD_MSK (((1U << GLB_REG_GPIO_20_PD_LEN) - 1) << GLB_REG_GPIO_20_PD_POS) +#define GLB_REG_GPIO_20_PD_UMSK (~(((1U << GLB_REG_GPIO_20_PD_LEN) - 1) << GLB_REG_GPIO_20_PD_POS)) +#define GLB_REG_GPIO_20_OE GLB_REG_GPIO_20_OE +#define GLB_REG_GPIO_20_OE_POS (6U) +#define GLB_REG_GPIO_20_OE_LEN (1U) +#define GLB_REG_GPIO_20_OE_MSK (((1U << GLB_REG_GPIO_20_OE_LEN) - 1) << GLB_REG_GPIO_20_OE_POS) +#define GLB_REG_GPIO_20_OE_UMSK (~(((1U << GLB_REG_GPIO_20_OE_LEN) - 1) << GLB_REG_GPIO_20_OE_POS)) +#define GLB_REG_GPIO_20_FUNC_SEL GLB_REG_GPIO_20_FUNC_SEL +#define GLB_REG_GPIO_20_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_20_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_20_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_20_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_20_FUNC_SEL_POS) +#define GLB_REG_GPIO_20_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_20_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_20_FUNC_SEL_POS)) +#define GLB_REG_GPIO_20_INT_MODE_SET GLB_REG_GPIO_20_INT_MODE_SET +#define GLB_REG_GPIO_20_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_20_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_20_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_20_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_20_INT_MODE_SET_POS) +#define GLB_REG_GPIO_20_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_20_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_20_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_20_INT_CLR GLB_REG_GPIO_20_INT_CLR +#define GLB_REG_GPIO_20_INT_CLR_POS (20U) +#define GLB_REG_GPIO_20_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_20_INT_CLR_MSK (((1U << GLB_REG_GPIO_20_INT_CLR_LEN) - 1) << GLB_REG_GPIO_20_INT_CLR_POS) +#define GLB_REG_GPIO_20_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_20_INT_CLR_LEN) - 1) << GLB_REG_GPIO_20_INT_CLR_POS)) +#define GLB_GPIO_20_INT_STAT GLB_GPIO_20_INT_STAT +#define GLB_GPIO_20_INT_STAT_POS (21U) +#define GLB_GPIO_20_INT_STAT_LEN (1U) +#define GLB_GPIO_20_INT_STAT_MSK (((1U << GLB_GPIO_20_INT_STAT_LEN) - 1) << GLB_GPIO_20_INT_STAT_POS) +#define GLB_GPIO_20_INT_STAT_UMSK (~(((1U << GLB_GPIO_20_INT_STAT_LEN) - 1) << GLB_GPIO_20_INT_STAT_POS)) +#define GLB_REG_GPIO_20_INT_MASK GLB_REG_GPIO_20_INT_MASK +#define GLB_REG_GPIO_20_INT_MASK_POS (22U) +#define GLB_REG_GPIO_20_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_20_INT_MASK_MSK (((1U << GLB_REG_GPIO_20_INT_MASK_LEN) - 1) << GLB_REG_GPIO_20_INT_MASK_POS) +#define GLB_REG_GPIO_20_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_20_INT_MASK_LEN) - 1) << GLB_REG_GPIO_20_INT_MASK_POS)) +#define GLB_REG_GPIO_20_O GLB_REG_GPIO_20_O +#define GLB_REG_GPIO_20_O_POS (24U) +#define GLB_REG_GPIO_20_O_LEN (1U) +#define GLB_REG_GPIO_20_O_MSK (((1U << GLB_REG_GPIO_20_O_LEN) - 1) << GLB_REG_GPIO_20_O_POS) +#define GLB_REG_GPIO_20_O_UMSK (~(((1U << GLB_REG_GPIO_20_O_LEN) - 1) << GLB_REG_GPIO_20_O_POS)) +#define GLB_REG_GPIO_20_SET GLB_REG_GPIO_20_SET +#define GLB_REG_GPIO_20_SET_POS (25U) +#define GLB_REG_GPIO_20_SET_LEN (1U) +#define GLB_REG_GPIO_20_SET_MSK (((1U << GLB_REG_GPIO_20_SET_LEN) - 1) << GLB_REG_GPIO_20_SET_POS) +#define GLB_REG_GPIO_20_SET_UMSK (~(((1U << GLB_REG_GPIO_20_SET_LEN) - 1) << GLB_REG_GPIO_20_SET_POS)) +#define GLB_REG_GPIO_20_CLR GLB_REG_GPIO_20_CLR +#define GLB_REG_GPIO_20_CLR_POS (26U) +#define GLB_REG_GPIO_20_CLR_LEN (1U) +#define GLB_REG_GPIO_20_CLR_MSK (((1U << GLB_REG_GPIO_20_CLR_LEN) - 1) << GLB_REG_GPIO_20_CLR_POS) +#define GLB_REG_GPIO_20_CLR_UMSK (~(((1U << GLB_REG_GPIO_20_CLR_LEN) - 1) << GLB_REG_GPIO_20_CLR_POS)) +#define GLB_REG_GPIO_20_I GLB_REG_GPIO_20_I +#define GLB_REG_GPIO_20_I_POS (28U) +#define GLB_REG_GPIO_20_I_LEN (1U) +#define GLB_REG_GPIO_20_I_MSK (((1U << GLB_REG_GPIO_20_I_LEN) - 1) << GLB_REG_GPIO_20_I_POS) +#define GLB_REG_GPIO_20_I_UMSK (~(((1U << GLB_REG_GPIO_20_I_LEN) - 1) << GLB_REG_GPIO_20_I_POS)) +#define GLB_REG_GPIO_20_MODE GLB_REG_GPIO_20_MODE +#define GLB_REG_GPIO_20_MODE_POS (30U) +#define GLB_REG_GPIO_20_MODE_LEN (2U) +#define GLB_REG_GPIO_20_MODE_MSK (((1U << GLB_REG_GPIO_20_MODE_LEN) - 1) << GLB_REG_GPIO_20_MODE_POS) +#define GLB_REG_GPIO_20_MODE_UMSK (~(((1U << GLB_REG_GPIO_20_MODE_LEN) - 1) << GLB_REG_GPIO_20_MODE_POS)) + +/* 0x918 : gpio_cfg21 */ +#define GLB_GPIO_CFG21_OFFSET (0x918) +#define GLB_REG_GPIO_21_IE GLB_REG_GPIO_21_IE +#define GLB_REG_GPIO_21_IE_POS (0U) +#define GLB_REG_GPIO_21_IE_LEN (1U) +#define GLB_REG_GPIO_21_IE_MSK (((1U << GLB_REG_GPIO_21_IE_LEN) - 1) << GLB_REG_GPIO_21_IE_POS) +#define GLB_REG_GPIO_21_IE_UMSK (~(((1U << GLB_REG_GPIO_21_IE_LEN) - 1) << GLB_REG_GPIO_21_IE_POS)) +#define GLB_REG_GPIO_21_SMT GLB_REG_GPIO_21_SMT +#define GLB_REG_GPIO_21_SMT_POS (1U) +#define GLB_REG_GPIO_21_SMT_LEN (1U) +#define GLB_REG_GPIO_21_SMT_MSK (((1U << GLB_REG_GPIO_21_SMT_LEN) - 1) << GLB_REG_GPIO_21_SMT_POS) +#define GLB_REG_GPIO_21_SMT_UMSK (~(((1U << GLB_REG_GPIO_21_SMT_LEN) - 1) << GLB_REG_GPIO_21_SMT_POS)) +#define GLB_REG_GPIO_21_DRV GLB_REG_GPIO_21_DRV +#define GLB_REG_GPIO_21_DRV_POS (2U) +#define GLB_REG_GPIO_21_DRV_LEN (2U) +#define GLB_REG_GPIO_21_DRV_MSK (((1U << GLB_REG_GPIO_21_DRV_LEN) - 1) << GLB_REG_GPIO_21_DRV_POS) +#define GLB_REG_GPIO_21_DRV_UMSK (~(((1U << GLB_REG_GPIO_21_DRV_LEN) - 1) << GLB_REG_GPIO_21_DRV_POS)) +#define GLB_REG_GPIO_21_PU GLB_REG_GPIO_21_PU +#define GLB_REG_GPIO_21_PU_POS (4U) +#define GLB_REG_GPIO_21_PU_LEN (1U) +#define GLB_REG_GPIO_21_PU_MSK (((1U << GLB_REG_GPIO_21_PU_LEN) - 1) << GLB_REG_GPIO_21_PU_POS) +#define GLB_REG_GPIO_21_PU_UMSK (~(((1U << GLB_REG_GPIO_21_PU_LEN) - 1) << GLB_REG_GPIO_21_PU_POS)) +#define GLB_REG_GPIO_21_PD GLB_REG_GPIO_21_PD +#define GLB_REG_GPIO_21_PD_POS (5U) +#define GLB_REG_GPIO_21_PD_LEN (1U) +#define GLB_REG_GPIO_21_PD_MSK (((1U << GLB_REG_GPIO_21_PD_LEN) - 1) << GLB_REG_GPIO_21_PD_POS) +#define GLB_REG_GPIO_21_PD_UMSK (~(((1U << GLB_REG_GPIO_21_PD_LEN) - 1) << GLB_REG_GPIO_21_PD_POS)) +#define GLB_REG_GPIO_21_OE GLB_REG_GPIO_21_OE +#define GLB_REG_GPIO_21_OE_POS (6U) +#define GLB_REG_GPIO_21_OE_LEN (1U) +#define GLB_REG_GPIO_21_OE_MSK (((1U << GLB_REG_GPIO_21_OE_LEN) - 1) << GLB_REG_GPIO_21_OE_POS) +#define GLB_REG_GPIO_21_OE_UMSK (~(((1U << GLB_REG_GPIO_21_OE_LEN) - 1) << GLB_REG_GPIO_21_OE_POS)) +#define GLB_REG_GPIO_21_FUNC_SEL GLB_REG_GPIO_21_FUNC_SEL +#define GLB_REG_GPIO_21_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_21_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_21_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_21_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_21_FUNC_SEL_POS) +#define GLB_REG_GPIO_21_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_21_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_21_FUNC_SEL_POS)) +#define GLB_REG_GPIO_21_INT_MODE_SET GLB_REG_GPIO_21_INT_MODE_SET +#define GLB_REG_GPIO_21_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_21_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_21_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_21_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_21_INT_MODE_SET_POS) +#define GLB_REG_GPIO_21_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_21_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_21_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_21_INT_CLR GLB_REG_GPIO_21_INT_CLR +#define GLB_REG_GPIO_21_INT_CLR_POS (20U) +#define GLB_REG_GPIO_21_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_21_INT_CLR_MSK (((1U << GLB_REG_GPIO_21_INT_CLR_LEN) - 1) << GLB_REG_GPIO_21_INT_CLR_POS) +#define GLB_REG_GPIO_21_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_21_INT_CLR_LEN) - 1) << GLB_REG_GPIO_21_INT_CLR_POS)) +#define GLB_GPIO_21_INT_STAT GLB_GPIO_21_INT_STAT +#define GLB_GPIO_21_INT_STAT_POS (21U) +#define GLB_GPIO_21_INT_STAT_LEN (1U) +#define GLB_GPIO_21_INT_STAT_MSK (((1U << GLB_GPIO_21_INT_STAT_LEN) - 1) << GLB_GPIO_21_INT_STAT_POS) +#define GLB_GPIO_21_INT_STAT_UMSK (~(((1U << GLB_GPIO_21_INT_STAT_LEN) - 1) << GLB_GPIO_21_INT_STAT_POS)) +#define GLB_REG_GPIO_21_INT_MASK GLB_REG_GPIO_21_INT_MASK +#define GLB_REG_GPIO_21_INT_MASK_POS (22U) +#define GLB_REG_GPIO_21_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_21_INT_MASK_MSK (((1U << GLB_REG_GPIO_21_INT_MASK_LEN) - 1) << GLB_REG_GPIO_21_INT_MASK_POS) +#define GLB_REG_GPIO_21_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_21_INT_MASK_LEN) - 1) << GLB_REG_GPIO_21_INT_MASK_POS)) +#define GLB_REG_GPIO_21_O GLB_REG_GPIO_21_O +#define GLB_REG_GPIO_21_O_POS (24U) +#define GLB_REG_GPIO_21_O_LEN (1U) +#define GLB_REG_GPIO_21_O_MSK (((1U << GLB_REG_GPIO_21_O_LEN) - 1) << GLB_REG_GPIO_21_O_POS) +#define GLB_REG_GPIO_21_O_UMSK (~(((1U << GLB_REG_GPIO_21_O_LEN) - 1) << GLB_REG_GPIO_21_O_POS)) +#define GLB_REG_GPIO_21_SET GLB_REG_GPIO_21_SET +#define GLB_REG_GPIO_21_SET_POS (25U) +#define GLB_REG_GPIO_21_SET_LEN (1U) +#define GLB_REG_GPIO_21_SET_MSK (((1U << GLB_REG_GPIO_21_SET_LEN) - 1) << GLB_REG_GPIO_21_SET_POS) +#define GLB_REG_GPIO_21_SET_UMSK (~(((1U << GLB_REG_GPIO_21_SET_LEN) - 1) << GLB_REG_GPIO_21_SET_POS)) +#define GLB_REG_GPIO_21_CLR GLB_REG_GPIO_21_CLR +#define GLB_REG_GPIO_21_CLR_POS (26U) +#define GLB_REG_GPIO_21_CLR_LEN (1U) +#define GLB_REG_GPIO_21_CLR_MSK (((1U << GLB_REG_GPIO_21_CLR_LEN) - 1) << GLB_REG_GPIO_21_CLR_POS) +#define GLB_REG_GPIO_21_CLR_UMSK (~(((1U << GLB_REG_GPIO_21_CLR_LEN) - 1) << GLB_REG_GPIO_21_CLR_POS)) +#define GLB_REG_GPIO_21_I GLB_REG_GPIO_21_I +#define GLB_REG_GPIO_21_I_POS (28U) +#define GLB_REG_GPIO_21_I_LEN (1U) +#define GLB_REG_GPIO_21_I_MSK (((1U << GLB_REG_GPIO_21_I_LEN) - 1) << GLB_REG_GPIO_21_I_POS) +#define GLB_REG_GPIO_21_I_UMSK (~(((1U << GLB_REG_GPIO_21_I_LEN) - 1) << GLB_REG_GPIO_21_I_POS)) +#define GLB_REG_GPIO_21_MODE GLB_REG_GPIO_21_MODE +#define GLB_REG_GPIO_21_MODE_POS (30U) +#define GLB_REG_GPIO_21_MODE_LEN (2U) +#define GLB_REG_GPIO_21_MODE_MSK (((1U << GLB_REG_GPIO_21_MODE_LEN) - 1) << GLB_REG_GPIO_21_MODE_POS) +#define GLB_REG_GPIO_21_MODE_UMSK (~(((1U << GLB_REG_GPIO_21_MODE_LEN) - 1) << GLB_REG_GPIO_21_MODE_POS)) + +/* 0x91C : gpio_cfg22 */ +#define GLB_GPIO_CFG22_OFFSET (0x91C) +#define GLB_REG_GPIO_22_IE GLB_REG_GPIO_22_IE +#define GLB_REG_GPIO_22_IE_POS (0U) +#define GLB_REG_GPIO_22_IE_LEN (1U) +#define GLB_REG_GPIO_22_IE_MSK (((1U << GLB_REG_GPIO_22_IE_LEN) - 1) << GLB_REG_GPIO_22_IE_POS) +#define GLB_REG_GPIO_22_IE_UMSK (~(((1U << GLB_REG_GPIO_22_IE_LEN) - 1) << GLB_REG_GPIO_22_IE_POS)) +#define GLB_REG_GPIO_22_SMT GLB_REG_GPIO_22_SMT +#define GLB_REG_GPIO_22_SMT_POS (1U) +#define GLB_REG_GPIO_22_SMT_LEN (1U) +#define GLB_REG_GPIO_22_SMT_MSK (((1U << GLB_REG_GPIO_22_SMT_LEN) - 1) << GLB_REG_GPIO_22_SMT_POS) +#define GLB_REG_GPIO_22_SMT_UMSK (~(((1U << GLB_REG_GPIO_22_SMT_LEN) - 1) << GLB_REG_GPIO_22_SMT_POS)) +#define GLB_REG_GPIO_22_DRV GLB_REG_GPIO_22_DRV +#define GLB_REG_GPIO_22_DRV_POS (2U) +#define GLB_REG_GPIO_22_DRV_LEN (2U) +#define GLB_REG_GPIO_22_DRV_MSK (((1U << GLB_REG_GPIO_22_DRV_LEN) - 1) << GLB_REG_GPIO_22_DRV_POS) +#define GLB_REG_GPIO_22_DRV_UMSK (~(((1U << GLB_REG_GPIO_22_DRV_LEN) - 1) << GLB_REG_GPIO_22_DRV_POS)) +#define GLB_REG_GPIO_22_PU GLB_REG_GPIO_22_PU +#define GLB_REG_GPIO_22_PU_POS (4U) +#define GLB_REG_GPIO_22_PU_LEN (1U) +#define GLB_REG_GPIO_22_PU_MSK (((1U << GLB_REG_GPIO_22_PU_LEN) - 1) << GLB_REG_GPIO_22_PU_POS) +#define GLB_REG_GPIO_22_PU_UMSK (~(((1U << GLB_REG_GPIO_22_PU_LEN) - 1) << GLB_REG_GPIO_22_PU_POS)) +#define GLB_REG_GPIO_22_PD GLB_REG_GPIO_22_PD +#define GLB_REG_GPIO_22_PD_POS (5U) +#define GLB_REG_GPIO_22_PD_LEN (1U) +#define GLB_REG_GPIO_22_PD_MSK (((1U << GLB_REG_GPIO_22_PD_LEN) - 1) << GLB_REG_GPIO_22_PD_POS) +#define GLB_REG_GPIO_22_PD_UMSK (~(((1U << GLB_REG_GPIO_22_PD_LEN) - 1) << GLB_REG_GPIO_22_PD_POS)) +#define GLB_REG_GPIO_22_OE GLB_REG_GPIO_22_OE +#define GLB_REG_GPIO_22_OE_POS (6U) +#define GLB_REG_GPIO_22_OE_LEN (1U) +#define GLB_REG_GPIO_22_OE_MSK (((1U << GLB_REG_GPIO_22_OE_LEN) - 1) << GLB_REG_GPIO_22_OE_POS) +#define GLB_REG_GPIO_22_OE_UMSK (~(((1U << GLB_REG_GPIO_22_OE_LEN) - 1) << GLB_REG_GPIO_22_OE_POS)) +#define GLB_REG_GPIO_22_FUNC_SEL GLB_REG_GPIO_22_FUNC_SEL +#define GLB_REG_GPIO_22_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_22_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_22_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_22_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_22_FUNC_SEL_POS) +#define GLB_REG_GPIO_22_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_22_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_22_FUNC_SEL_POS)) +#define GLB_REG_GPIO_22_INT_MODE_SET GLB_REG_GPIO_22_INT_MODE_SET +#define GLB_REG_GPIO_22_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_22_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_22_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_22_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_22_INT_MODE_SET_POS) +#define GLB_REG_GPIO_22_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_22_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_22_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_22_INT_CLR GLB_REG_GPIO_22_INT_CLR +#define GLB_REG_GPIO_22_INT_CLR_POS (20U) +#define GLB_REG_GPIO_22_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_22_INT_CLR_MSK (((1U << GLB_REG_GPIO_22_INT_CLR_LEN) - 1) << GLB_REG_GPIO_22_INT_CLR_POS) +#define GLB_REG_GPIO_22_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_22_INT_CLR_LEN) - 1) << GLB_REG_GPIO_22_INT_CLR_POS)) +#define GLB_GPIO_22_INT_STAT GLB_GPIO_22_INT_STAT +#define GLB_GPIO_22_INT_STAT_POS (21U) +#define GLB_GPIO_22_INT_STAT_LEN (1U) +#define GLB_GPIO_22_INT_STAT_MSK (((1U << GLB_GPIO_22_INT_STAT_LEN) - 1) << GLB_GPIO_22_INT_STAT_POS) +#define GLB_GPIO_22_INT_STAT_UMSK (~(((1U << GLB_GPIO_22_INT_STAT_LEN) - 1) << GLB_GPIO_22_INT_STAT_POS)) +#define GLB_REG_GPIO_22_INT_MASK GLB_REG_GPIO_22_INT_MASK +#define GLB_REG_GPIO_22_INT_MASK_POS (22U) +#define GLB_REG_GPIO_22_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_22_INT_MASK_MSK (((1U << GLB_REG_GPIO_22_INT_MASK_LEN) - 1) << GLB_REG_GPIO_22_INT_MASK_POS) +#define GLB_REG_GPIO_22_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_22_INT_MASK_LEN) - 1) << GLB_REG_GPIO_22_INT_MASK_POS)) +#define GLB_REG_GPIO_22_O GLB_REG_GPIO_22_O +#define GLB_REG_GPIO_22_O_POS (24U) +#define GLB_REG_GPIO_22_O_LEN (1U) +#define GLB_REG_GPIO_22_O_MSK (((1U << GLB_REG_GPIO_22_O_LEN) - 1) << GLB_REG_GPIO_22_O_POS) +#define GLB_REG_GPIO_22_O_UMSK (~(((1U << GLB_REG_GPIO_22_O_LEN) - 1) << GLB_REG_GPIO_22_O_POS)) +#define GLB_REG_GPIO_22_SET GLB_REG_GPIO_22_SET +#define GLB_REG_GPIO_22_SET_POS (25U) +#define GLB_REG_GPIO_22_SET_LEN (1U) +#define GLB_REG_GPIO_22_SET_MSK (((1U << GLB_REG_GPIO_22_SET_LEN) - 1) << GLB_REG_GPIO_22_SET_POS) +#define GLB_REG_GPIO_22_SET_UMSK (~(((1U << GLB_REG_GPIO_22_SET_LEN) - 1) << GLB_REG_GPIO_22_SET_POS)) +#define GLB_REG_GPIO_22_CLR GLB_REG_GPIO_22_CLR +#define GLB_REG_GPIO_22_CLR_POS (26U) +#define GLB_REG_GPIO_22_CLR_LEN (1U) +#define GLB_REG_GPIO_22_CLR_MSK (((1U << GLB_REG_GPIO_22_CLR_LEN) - 1) << GLB_REG_GPIO_22_CLR_POS) +#define GLB_REG_GPIO_22_CLR_UMSK (~(((1U << GLB_REG_GPIO_22_CLR_LEN) - 1) << GLB_REG_GPIO_22_CLR_POS)) +#define GLB_REG_GPIO_22_I GLB_REG_GPIO_22_I +#define GLB_REG_GPIO_22_I_POS (28U) +#define GLB_REG_GPIO_22_I_LEN (1U) +#define GLB_REG_GPIO_22_I_MSK (((1U << GLB_REG_GPIO_22_I_LEN) - 1) << GLB_REG_GPIO_22_I_POS) +#define GLB_REG_GPIO_22_I_UMSK (~(((1U << GLB_REG_GPIO_22_I_LEN) - 1) << GLB_REG_GPIO_22_I_POS)) +#define GLB_REG_GPIO_22_MODE GLB_REG_GPIO_22_MODE +#define GLB_REG_GPIO_22_MODE_POS (30U) +#define GLB_REG_GPIO_22_MODE_LEN (2U) +#define GLB_REG_GPIO_22_MODE_MSK (((1U << GLB_REG_GPIO_22_MODE_LEN) - 1) << GLB_REG_GPIO_22_MODE_POS) +#define GLB_REG_GPIO_22_MODE_UMSK (~(((1U << GLB_REG_GPIO_22_MODE_LEN) - 1) << GLB_REG_GPIO_22_MODE_POS)) + +/* 0x920 : gpio_cfg23 */ +#define GLB_GPIO_CFG23_OFFSET (0x920) +#define GLB_REG_GPIO_23_IE GLB_REG_GPIO_23_IE +#define GLB_REG_GPIO_23_IE_POS (0U) +#define GLB_REG_GPIO_23_IE_LEN (1U) +#define GLB_REG_GPIO_23_IE_MSK (((1U << GLB_REG_GPIO_23_IE_LEN) - 1) << GLB_REG_GPIO_23_IE_POS) +#define GLB_REG_GPIO_23_IE_UMSK (~(((1U << GLB_REG_GPIO_23_IE_LEN) - 1) << GLB_REG_GPIO_23_IE_POS)) +#define GLB_REG_GPIO_23_SMT GLB_REG_GPIO_23_SMT +#define GLB_REG_GPIO_23_SMT_POS (1U) +#define GLB_REG_GPIO_23_SMT_LEN (1U) +#define GLB_REG_GPIO_23_SMT_MSK (((1U << GLB_REG_GPIO_23_SMT_LEN) - 1) << GLB_REG_GPIO_23_SMT_POS) +#define GLB_REG_GPIO_23_SMT_UMSK (~(((1U << GLB_REG_GPIO_23_SMT_LEN) - 1) << GLB_REG_GPIO_23_SMT_POS)) +#define GLB_REG_GPIO_23_DRV GLB_REG_GPIO_23_DRV +#define GLB_REG_GPIO_23_DRV_POS (2U) +#define GLB_REG_GPIO_23_DRV_LEN (2U) +#define GLB_REG_GPIO_23_DRV_MSK (((1U << GLB_REG_GPIO_23_DRV_LEN) - 1) << GLB_REG_GPIO_23_DRV_POS) +#define GLB_REG_GPIO_23_DRV_UMSK (~(((1U << GLB_REG_GPIO_23_DRV_LEN) - 1) << GLB_REG_GPIO_23_DRV_POS)) +#define GLB_REG_GPIO_23_PU GLB_REG_GPIO_23_PU +#define GLB_REG_GPIO_23_PU_POS (4U) +#define GLB_REG_GPIO_23_PU_LEN (1U) +#define GLB_REG_GPIO_23_PU_MSK (((1U << GLB_REG_GPIO_23_PU_LEN) - 1) << GLB_REG_GPIO_23_PU_POS) +#define GLB_REG_GPIO_23_PU_UMSK (~(((1U << GLB_REG_GPIO_23_PU_LEN) - 1) << GLB_REG_GPIO_23_PU_POS)) +#define GLB_REG_GPIO_23_PD GLB_REG_GPIO_23_PD +#define GLB_REG_GPIO_23_PD_POS (5U) +#define GLB_REG_GPIO_23_PD_LEN (1U) +#define GLB_REG_GPIO_23_PD_MSK (((1U << GLB_REG_GPIO_23_PD_LEN) - 1) << GLB_REG_GPIO_23_PD_POS) +#define GLB_REG_GPIO_23_PD_UMSK (~(((1U << GLB_REG_GPIO_23_PD_LEN) - 1) << GLB_REG_GPIO_23_PD_POS)) +#define GLB_REG_GPIO_23_OE GLB_REG_GPIO_23_OE +#define GLB_REG_GPIO_23_OE_POS (6U) +#define GLB_REG_GPIO_23_OE_LEN (1U) +#define GLB_REG_GPIO_23_OE_MSK (((1U << GLB_REG_GPIO_23_OE_LEN) - 1) << GLB_REG_GPIO_23_OE_POS) +#define GLB_REG_GPIO_23_OE_UMSK (~(((1U << GLB_REG_GPIO_23_OE_LEN) - 1) << GLB_REG_GPIO_23_OE_POS)) +#define GLB_REG_GPIO_23_FUNC_SEL GLB_REG_GPIO_23_FUNC_SEL +#define GLB_REG_GPIO_23_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_23_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_23_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_23_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_23_FUNC_SEL_POS) +#define GLB_REG_GPIO_23_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_23_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_23_FUNC_SEL_POS)) +#define GLB_REG_GPIO_23_INT_MODE_SET GLB_REG_GPIO_23_INT_MODE_SET +#define GLB_REG_GPIO_23_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_23_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_23_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_23_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_23_INT_MODE_SET_POS) +#define GLB_REG_GPIO_23_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_23_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_23_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_23_INT_CLR GLB_REG_GPIO_23_INT_CLR +#define GLB_REG_GPIO_23_INT_CLR_POS (20U) +#define GLB_REG_GPIO_23_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_23_INT_CLR_MSK (((1U << GLB_REG_GPIO_23_INT_CLR_LEN) - 1) << GLB_REG_GPIO_23_INT_CLR_POS) +#define GLB_REG_GPIO_23_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_23_INT_CLR_LEN) - 1) << GLB_REG_GPIO_23_INT_CLR_POS)) +#define GLB_GPIO_23_INT_STAT GLB_GPIO_23_INT_STAT +#define GLB_GPIO_23_INT_STAT_POS (21U) +#define GLB_GPIO_23_INT_STAT_LEN (1U) +#define GLB_GPIO_23_INT_STAT_MSK (((1U << GLB_GPIO_23_INT_STAT_LEN) - 1) << GLB_GPIO_23_INT_STAT_POS) +#define GLB_GPIO_23_INT_STAT_UMSK (~(((1U << GLB_GPIO_23_INT_STAT_LEN) - 1) << GLB_GPIO_23_INT_STAT_POS)) +#define GLB_REG_GPIO_23_INT_MASK GLB_REG_GPIO_23_INT_MASK +#define GLB_REG_GPIO_23_INT_MASK_POS (22U) +#define GLB_REG_GPIO_23_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_23_INT_MASK_MSK (((1U << GLB_REG_GPIO_23_INT_MASK_LEN) - 1) << GLB_REG_GPIO_23_INT_MASK_POS) +#define GLB_REG_GPIO_23_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_23_INT_MASK_LEN) - 1) << GLB_REG_GPIO_23_INT_MASK_POS)) +#define GLB_REG_GPIO_23_O GLB_REG_GPIO_23_O +#define GLB_REG_GPIO_23_O_POS (24U) +#define GLB_REG_GPIO_23_O_LEN (1U) +#define GLB_REG_GPIO_23_O_MSK (((1U << GLB_REG_GPIO_23_O_LEN) - 1) << GLB_REG_GPIO_23_O_POS) +#define GLB_REG_GPIO_23_O_UMSK (~(((1U << GLB_REG_GPIO_23_O_LEN) - 1) << GLB_REG_GPIO_23_O_POS)) +#define GLB_REG_GPIO_23_SET GLB_REG_GPIO_23_SET +#define GLB_REG_GPIO_23_SET_POS (25U) +#define GLB_REG_GPIO_23_SET_LEN (1U) +#define GLB_REG_GPIO_23_SET_MSK (((1U << GLB_REG_GPIO_23_SET_LEN) - 1) << GLB_REG_GPIO_23_SET_POS) +#define GLB_REG_GPIO_23_SET_UMSK (~(((1U << GLB_REG_GPIO_23_SET_LEN) - 1) << GLB_REG_GPIO_23_SET_POS)) +#define GLB_REG_GPIO_23_CLR GLB_REG_GPIO_23_CLR +#define GLB_REG_GPIO_23_CLR_POS (26U) +#define GLB_REG_GPIO_23_CLR_LEN (1U) +#define GLB_REG_GPIO_23_CLR_MSK (((1U << GLB_REG_GPIO_23_CLR_LEN) - 1) << GLB_REG_GPIO_23_CLR_POS) +#define GLB_REG_GPIO_23_CLR_UMSK (~(((1U << GLB_REG_GPIO_23_CLR_LEN) - 1) << GLB_REG_GPIO_23_CLR_POS)) +#define GLB_REG_GPIO_23_I GLB_REG_GPIO_23_I +#define GLB_REG_GPIO_23_I_POS (28U) +#define GLB_REG_GPIO_23_I_LEN (1U) +#define GLB_REG_GPIO_23_I_MSK (((1U << GLB_REG_GPIO_23_I_LEN) - 1) << GLB_REG_GPIO_23_I_POS) +#define GLB_REG_GPIO_23_I_UMSK (~(((1U << GLB_REG_GPIO_23_I_LEN) - 1) << GLB_REG_GPIO_23_I_POS)) +#define GLB_REG_GPIO_23_MODE GLB_REG_GPIO_23_MODE +#define GLB_REG_GPIO_23_MODE_POS (30U) +#define GLB_REG_GPIO_23_MODE_LEN (2U) +#define GLB_REG_GPIO_23_MODE_MSK (((1U << GLB_REG_GPIO_23_MODE_LEN) - 1) << GLB_REG_GPIO_23_MODE_POS) +#define GLB_REG_GPIO_23_MODE_UMSK (~(((1U << GLB_REG_GPIO_23_MODE_LEN) - 1) << GLB_REG_GPIO_23_MODE_POS)) + +/* 0x924 : gpio_cfg24 */ +#define GLB_GPIO_CFG24_OFFSET (0x924) +#define GLB_REG_GPIO_24_IE GLB_REG_GPIO_24_IE +#define GLB_REG_GPIO_24_IE_POS (0U) +#define GLB_REG_GPIO_24_IE_LEN (1U) +#define GLB_REG_GPIO_24_IE_MSK (((1U << GLB_REG_GPIO_24_IE_LEN) - 1) << GLB_REG_GPIO_24_IE_POS) +#define GLB_REG_GPIO_24_IE_UMSK (~(((1U << GLB_REG_GPIO_24_IE_LEN) - 1) << GLB_REG_GPIO_24_IE_POS)) +#define GLB_REG_GPIO_24_SMT GLB_REG_GPIO_24_SMT +#define GLB_REG_GPIO_24_SMT_POS (1U) +#define GLB_REG_GPIO_24_SMT_LEN (1U) +#define GLB_REG_GPIO_24_SMT_MSK (((1U << GLB_REG_GPIO_24_SMT_LEN) - 1) << GLB_REG_GPIO_24_SMT_POS) +#define GLB_REG_GPIO_24_SMT_UMSK (~(((1U << GLB_REG_GPIO_24_SMT_LEN) - 1) << GLB_REG_GPIO_24_SMT_POS)) +#define GLB_REG_GPIO_24_DRV GLB_REG_GPIO_24_DRV +#define GLB_REG_GPIO_24_DRV_POS (2U) +#define GLB_REG_GPIO_24_DRV_LEN (2U) +#define GLB_REG_GPIO_24_DRV_MSK (((1U << GLB_REG_GPIO_24_DRV_LEN) - 1) << GLB_REG_GPIO_24_DRV_POS) +#define GLB_REG_GPIO_24_DRV_UMSK (~(((1U << GLB_REG_GPIO_24_DRV_LEN) - 1) << GLB_REG_GPIO_24_DRV_POS)) +#define GLB_REG_GPIO_24_PU GLB_REG_GPIO_24_PU +#define GLB_REG_GPIO_24_PU_POS (4U) +#define GLB_REG_GPIO_24_PU_LEN (1U) +#define GLB_REG_GPIO_24_PU_MSK (((1U << GLB_REG_GPIO_24_PU_LEN) - 1) << GLB_REG_GPIO_24_PU_POS) +#define GLB_REG_GPIO_24_PU_UMSK (~(((1U << GLB_REG_GPIO_24_PU_LEN) - 1) << GLB_REG_GPIO_24_PU_POS)) +#define GLB_REG_GPIO_24_PD GLB_REG_GPIO_24_PD +#define GLB_REG_GPIO_24_PD_POS (5U) +#define GLB_REG_GPIO_24_PD_LEN (1U) +#define GLB_REG_GPIO_24_PD_MSK (((1U << GLB_REG_GPIO_24_PD_LEN) - 1) << GLB_REG_GPIO_24_PD_POS) +#define GLB_REG_GPIO_24_PD_UMSK (~(((1U << GLB_REG_GPIO_24_PD_LEN) - 1) << GLB_REG_GPIO_24_PD_POS)) +#define GLB_REG_GPIO_24_OE GLB_REG_GPIO_24_OE +#define GLB_REG_GPIO_24_OE_POS (6U) +#define GLB_REG_GPIO_24_OE_LEN (1U) +#define GLB_REG_GPIO_24_OE_MSK (((1U << GLB_REG_GPIO_24_OE_LEN) - 1) << GLB_REG_GPIO_24_OE_POS) +#define GLB_REG_GPIO_24_OE_UMSK (~(((1U << GLB_REG_GPIO_24_OE_LEN) - 1) << GLB_REG_GPIO_24_OE_POS)) +#define GLB_REG_GPIO_24_FUNC_SEL GLB_REG_GPIO_24_FUNC_SEL +#define GLB_REG_GPIO_24_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_24_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_24_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_24_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_24_FUNC_SEL_POS) +#define GLB_REG_GPIO_24_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_24_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_24_FUNC_SEL_POS)) +#define GLB_REG_GPIO_24_INT_MODE_SET GLB_REG_GPIO_24_INT_MODE_SET +#define GLB_REG_GPIO_24_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_24_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_24_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_24_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_24_INT_MODE_SET_POS) +#define GLB_REG_GPIO_24_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_24_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_24_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_24_INT_CLR GLB_REG_GPIO_24_INT_CLR +#define GLB_REG_GPIO_24_INT_CLR_POS (20U) +#define GLB_REG_GPIO_24_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_24_INT_CLR_MSK (((1U << GLB_REG_GPIO_24_INT_CLR_LEN) - 1) << GLB_REG_GPIO_24_INT_CLR_POS) +#define GLB_REG_GPIO_24_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_24_INT_CLR_LEN) - 1) << GLB_REG_GPIO_24_INT_CLR_POS)) +#define GLB_GPIO_24_INT_STAT GLB_GPIO_24_INT_STAT +#define GLB_GPIO_24_INT_STAT_POS (21U) +#define GLB_GPIO_24_INT_STAT_LEN (1U) +#define GLB_GPIO_24_INT_STAT_MSK (((1U << GLB_GPIO_24_INT_STAT_LEN) - 1) << GLB_GPIO_24_INT_STAT_POS) +#define GLB_GPIO_24_INT_STAT_UMSK (~(((1U << GLB_GPIO_24_INT_STAT_LEN) - 1) << GLB_GPIO_24_INT_STAT_POS)) +#define GLB_REG_GPIO_24_INT_MASK GLB_REG_GPIO_24_INT_MASK +#define GLB_REG_GPIO_24_INT_MASK_POS (22U) +#define GLB_REG_GPIO_24_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_24_INT_MASK_MSK (((1U << GLB_REG_GPIO_24_INT_MASK_LEN) - 1) << GLB_REG_GPIO_24_INT_MASK_POS) +#define GLB_REG_GPIO_24_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_24_INT_MASK_LEN) - 1) << GLB_REG_GPIO_24_INT_MASK_POS)) +#define GLB_REG_GPIO_24_O GLB_REG_GPIO_24_O +#define GLB_REG_GPIO_24_O_POS (24U) +#define GLB_REG_GPIO_24_O_LEN (1U) +#define GLB_REG_GPIO_24_O_MSK (((1U << GLB_REG_GPIO_24_O_LEN) - 1) << GLB_REG_GPIO_24_O_POS) +#define GLB_REG_GPIO_24_O_UMSK (~(((1U << GLB_REG_GPIO_24_O_LEN) - 1) << GLB_REG_GPIO_24_O_POS)) +#define GLB_REG_GPIO_24_SET GLB_REG_GPIO_24_SET +#define GLB_REG_GPIO_24_SET_POS (25U) +#define GLB_REG_GPIO_24_SET_LEN (1U) +#define GLB_REG_GPIO_24_SET_MSK (((1U << GLB_REG_GPIO_24_SET_LEN) - 1) << GLB_REG_GPIO_24_SET_POS) +#define GLB_REG_GPIO_24_SET_UMSK (~(((1U << GLB_REG_GPIO_24_SET_LEN) - 1) << GLB_REG_GPIO_24_SET_POS)) +#define GLB_REG_GPIO_24_CLR GLB_REG_GPIO_24_CLR +#define GLB_REG_GPIO_24_CLR_POS (26U) +#define GLB_REG_GPIO_24_CLR_LEN (1U) +#define GLB_REG_GPIO_24_CLR_MSK (((1U << GLB_REG_GPIO_24_CLR_LEN) - 1) << GLB_REG_GPIO_24_CLR_POS) +#define GLB_REG_GPIO_24_CLR_UMSK (~(((1U << GLB_REG_GPIO_24_CLR_LEN) - 1) << GLB_REG_GPIO_24_CLR_POS)) +#define GLB_REG_GPIO_24_I GLB_REG_GPIO_24_I +#define GLB_REG_GPIO_24_I_POS (28U) +#define GLB_REG_GPIO_24_I_LEN (1U) +#define GLB_REG_GPIO_24_I_MSK (((1U << GLB_REG_GPIO_24_I_LEN) - 1) << GLB_REG_GPIO_24_I_POS) +#define GLB_REG_GPIO_24_I_UMSK (~(((1U << GLB_REG_GPIO_24_I_LEN) - 1) << GLB_REG_GPIO_24_I_POS)) +#define GLB_REG_GPIO_24_MODE GLB_REG_GPIO_24_MODE +#define GLB_REG_GPIO_24_MODE_POS (30U) +#define GLB_REG_GPIO_24_MODE_LEN (2U) +#define GLB_REG_GPIO_24_MODE_MSK (((1U << GLB_REG_GPIO_24_MODE_LEN) - 1) << GLB_REG_GPIO_24_MODE_POS) +#define GLB_REG_GPIO_24_MODE_UMSK (~(((1U << GLB_REG_GPIO_24_MODE_LEN) - 1) << GLB_REG_GPIO_24_MODE_POS)) + +/* 0x928 : gpio_cfg25 */ +#define GLB_GPIO_CFG25_OFFSET (0x928) +#define GLB_REG_GPIO_25_IE GLB_REG_GPIO_25_IE +#define GLB_REG_GPIO_25_IE_POS (0U) +#define GLB_REG_GPIO_25_IE_LEN (1U) +#define GLB_REG_GPIO_25_IE_MSK (((1U << GLB_REG_GPIO_25_IE_LEN) - 1) << GLB_REG_GPIO_25_IE_POS) +#define GLB_REG_GPIO_25_IE_UMSK (~(((1U << GLB_REG_GPIO_25_IE_LEN) - 1) << GLB_REG_GPIO_25_IE_POS)) +#define GLB_REG_GPIO_25_SMT GLB_REG_GPIO_25_SMT +#define GLB_REG_GPIO_25_SMT_POS (1U) +#define GLB_REG_GPIO_25_SMT_LEN (1U) +#define GLB_REG_GPIO_25_SMT_MSK (((1U << GLB_REG_GPIO_25_SMT_LEN) - 1) << GLB_REG_GPIO_25_SMT_POS) +#define GLB_REG_GPIO_25_SMT_UMSK (~(((1U << GLB_REG_GPIO_25_SMT_LEN) - 1) << GLB_REG_GPIO_25_SMT_POS)) +#define GLB_REG_GPIO_25_DRV GLB_REG_GPIO_25_DRV +#define GLB_REG_GPIO_25_DRV_POS (2U) +#define GLB_REG_GPIO_25_DRV_LEN (2U) +#define GLB_REG_GPIO_25_DRV_MSK (((1U << GLB_REG_GPIO_25_DRV_LEN) - 1) << GLB_REG_GPIO_25_DRV_POS) +#define GLB_REG_GPIO_25_DRV_UMSK (~(((1U << GLB_REG_GPIO_25_DRV_LEN) - 1) << GLB_REG_GPIO_25_DRV_POS)) +#define GLB_REG_GPIO_25_PU GLB_REG_GPIO_25_PU +#define GLB_REG_GPIO_25_PU_POS (4U) +#define GLB_REG_GPIO_25_PU_LEN (1U) +#define GLB_REG_GPIO_25_PU_MSK (((1U << GLB_REG_GPIO_25_PU_LEN) - 1) << GLB_REG_GPIO_25_PU_POS) +#define GLB_REG_GPIO_25_PU_UMSK (~(((1U << GLB_REG_GPIO_25_PU_LEN) - 1) << GLB_REG_GPIO_25_PU_POS)) +#define GLB_REG_GPIO_25_PD GLB_REG_GPIO_25_PD +#define GLB_REG_GPIO_25_PD_POS (5U) +#define GLB_REG_GPIO_25_PD_LEN (1U) +#define GLB_REG_GPIO_25_PD_MSK (((1U << GLB_REG_GPIO_25_PD_LEN) - 1) << GLB_REG_GPIO_25_PD_POS) +#define GLB_REG_GPIO_25_PD_UMSK (~(((1U << GLB_REG_GPIO_25_PD_LEN) - 1) << GLB_REG_GPIO_25_PD_POS)) +#define GLB_REG_GPIO_25_OE GLB_REG_GPIO_25_OE +#define GLB_REG_GPIO_25_OE_POS (6U) +#define GLB_REG_GPIO_25_OE_LEN (1U) +#define GLB_REG_GPIO_25_OE_MSK (((1U << GLB_REG_GPIO_25_OE_LEN) - 1) << GLB_REG_GPIO_25_OE_POS) +#define GLB_REG_GPIO_25_OE_UMSK (~(((1U << GLB_REG_GPIO_25_OE_LEN) - 1) << GLB_REG_GPIO_25_OE_POS)) +#define GLB_REG_GPIO_25_FUNC_SEL GLB_REG_GPIO_25_FUNC_SEL +#define GLB_REG_GPIO_25_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_25_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_25_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_25_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_25_FUNC_SEL_POS) +#define GLB_REG_GPIO_25_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_25_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_25_FUNC_SEL_POS)) +#define GLB_REG_GPIO_25_INT_MODE_SET GLB_REG_GPIO_25_INT_MODE_SET +#define GLB_REG_GPIO_25_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_25_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_25_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_25_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_25_INT_MODE_SET_POS) +#define GLB_REG_GPIO_25_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_25_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_25_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_25_INT_CLR GLB_REG_GPIO_25_INT_CLR +#define GLB_REG_GPIO_25_INT_CLR_POS (20U) +#define GLB_REG_GPIO_25_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_25_INT_CLR_MSK (((1U << GLB_REG_GPIO_25_INT_CLR_LEN) - 1) << GLB_REG_GPIO_25_INT_CLR_POS) +#define GLB_REG_GPIO_25_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_25_INT_CLR_LEN) - 1) << GLB_REG_GPIO_25_INT_CLR_POS)) +#define GLB_GPIO_25_INT_STAT GLB_GPIO_25_INT_STAT +#define GLB_GPIO_25_INT_STAT_POS (21U) +#define GLB_GPIO_25_INT_STAT_LEN (1U) +#define GLB_GPIO_25_INT_STAT_MSK (((1U << GLB_GPIO_25_INT_STAT_LEN) - 1) << GLB_GPIO_25_INT_STAT_POS) +#define GLB_GPIO_25_INT_STAT_UMSK (~(((1U << GLB_GPIO_25_INT_STAT_LEN) - 1) << GLB_GPIO_25_INT_STAT_POS)) +#define GLB_REG_GPIO_25_INT_MASK GLB_REG_GPIO_25_INT_MASK +#define GLB_REG_GPIO_25_INT_MASK_POS (22U) +#define GLB_REG_GPIO_25_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_25_INT_MASK_MSK (((1U << GLB_REG_GPIO_25_INT_MASK_LEN) - 1) << GLB_REG_GPIO_25_INT_MASK_POS) +#define GLB_REG_GPIO_25_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_25_INT_MASK_LEN) - 1) << GLB_REG_GPIO_25_INT_MASK_POS)) +#define GLB_REG_GPIO_25_O GLB_REG_GPIO_25_O +#define GLB_REG_GPIO_25_O_POS (24U) +#define GLB_REG_GPIO_25_O_LEN (1U) +#define GLB_REG_GPIO_25_O_MSK (((1U << GLB_REG_GPIO_25_O_LEN) - 1) << GLB_REG_GPIO_25_O_POS) +#define GLB_REG_GPIO_25_O_UMSK (~(((1U << GLB_REG_GPIO_25_O_LEN) - 1) << GLB_REG_GPIO_25_O_POS)) +#define GLB_REG_GPIO_25_SET GLB_REG_GPIO_25_SET +#define GLB_REG_GPIO_25_SET_POS (25U) +#define GLB_REG_GPIO_25_SET_LEN (1U) +#define GLB_REG_GPIO_25_SET_MSK (((1U << GLB_REG_GPIO_25_SET_LEN) - 1) << GLB_REG_GPIO_25_SET_POS) +#define GLB_REG_GPIO_25_SET_UMSK (~(((1U << GLB_REG_GPIO_25_SET_LEN) - 1) << GLB_REG_GPIO_25_SET_POS)) +#define GLB_REG_GPIO_25_CLR GLB_REG_GPIO_25_CLR +#define GLB_REG_GPIO_25_CLR_POS (26U) +#define GLB_REG_GPIO_25_CLR_LEN (1U) +#define GLB_REG_GPIO_25_CLR_MSK (((1U << GLB_REG_GPIO_25_CLR_LEN) - 1) << GLB_REG_GPIO_25_CLR_POS) +#define GLB_REG_GPIO_25_CLR_UMSK (~(((1U << GLB_REG_GPIO_25_CLR_LEN) - 1) << GLB_REG_GPIO_25_CLR_POS)) +#define GLB_REG_GPIO_25_I GLB_REG_GPIO_25_I +#define GLB_REG_GPIO_25_I_POS (28U) +#define GLB_REG_GPIO_25_I_LEN (1U) +#define GLB_REG_GPIO_25_I_MSK (((1U << GLB_REG_GPIO_25_I_LEN) - 1) << GLB_REG_GPIO_25_I_POS) +#define GLB_REG_GPIO_25_I_UMSK (~(((1U << GLB_REG_GPIO_25_I_LEN) - 1) << GLB_REG_GPIO_25_I_POS)) +#define GLB_REG_GPIO_25_MODE GLB_REG_GPIO_25_MODE +#define GLB_REG_GPIO_25_MODE_POS (30U) +#define GLB_REG_GPIO_25_MODE_LEN (2U) +#define GLB_REG_GPIO_25_MODE_MSK (((1U << GLB_REG_GPIO_25_MODE_LEN) - 1) << GLB_REG_GPIO_25_MODE_POS) +#define GLB_REG_GPIO_25_MODE_UMSK (~(((1U << GLB_REG_GPIO_25_MODE_LEN) - 1) << GLB_REG_GPIO_25_MODE_POS)) + +/* 0x92C : gpio_cfg26 */ +#define GLB_GPIO_CFG26_OFFSET (0x92C) +#define GLB_REG_GPIO_26_IE GLB_REG_GPIO_26_IE +#define GLB_REG_GPIO_26_IE_POS (0U) +#define GLB_REG_GPIO_26_IE_LEN (1U) +#define GLB_REG_GPIO_26_IE_MSK (((1U << GLB_REG_GPIO_26_IE_LEN) - 1) << GLB_REG_GPIO_26_IE_POS) +#define GLB_REG_GPIO_26_IE_UMSK (~(((1U << GLB_REG_GPIO_26_IE_LEN) - 1) << GLB_REG_GPIO_26_IE_POS)) +#define GLB_REG_GPIO_26_SMT GLB_REG_GPIO_26_SMT +#define GLB_REG_GPIO_26_SMT_POS (1U) +#define GLB_REG_GPIO_26_SMT_LEN (1U) +#define GLB_REG_GPIO_26_SMT_MSK (((1U << GLB_REG_GPIO_26_SMT_LEN) - 1) << GLB_REG_GPIO_26_SMT_POS) +#define GLB_REG_GPIO_26_SMT_UMSK (~(((1U << GLB_REG_GPIO_26_SMT_LEN) - 1) << GLB_REG_GPIO_26_SMT_POS)) +#define GLB_REG_GPIO_26_DRV GLB_REG_GPIO_26_DRV +#define GLB_REG_GPIO_26_DRV_POS (2U) +#define GLB_REG_GPIO_26_DRV_LEN (2U) +#define GLB_REG_GPIO_26_DRV_MSK (((1U << GLB_REG_GPIO_26_DRV_LEN) - 1) << GLB_REG_GPIO_26_DRV_POS) +#define GLB_REG_GPIO_26_DRV_UMSK (~(((1U << GLB_REG_GPIO_26_DRV_LEN) - 1) << GLB_REG_GPIO_26_DRV_POS)) +#define GLB_REG_GPIO_26_PU GLB_REG_GPIO_26_PU +#define GLB_REG_GPIO_26_PU_POS (4U) +#define GLB_REG_GPIO_26_PU_LEN (1U) +#define GLB_REG_GPIO_26_PU_MSK (((1U << GLB_REG_GPIO_26_PU_LEN) - 1) << GLB_REG_GPIO_26_PU_POS) +#define GLB_REG_GPIO_26_PU_UMSK (~(((1U << GLB_REG_GPIO_26_PU_LEN) - 1) << GLB_REG_GPIO_26_PU_POS)) +#define GLB_REG_GPIO_26_PD GLB_REG_GPIO_26_PD +#define GLB_REG_GPIO_26_PD_POS (5U) +#define GLB_REG_GPIO_26_PD_LEN (1U) +#define GLB_REG_GPIO_26_PD_MSK (((1U << GLB_REG_GPIO_26_PD_LEN) - 1) << GLB_REG_GPIO_26_PD_POS) +#define GLB_REG_GPIO_26_PD_UMSK (~(((1U << GLB_REG_GPIO_26_PD_LEN) - 1) << GLB_REG_GPIO_26_PD_POS)) +#define GLB_REG_GPIO_26_OE GLB_REG_GPIO_26_OE +#define GLB_REG_GPIO_26_OE_POS (6U) +#define GLB_REG_GPIO_26_OE_LEN (1U) +#define GLB_REG_GPIO_26_OE_MSK (((1U << GLB_REG_GPIO_26_OE_LEN) - 1) << GLB_REG_GPIO_26_OE_POS) +#define GLB_REG_GPIO_26_OE_UMSK (~(((1U << GLB_REG_GPIO_26_OE_LEN) - 1) << GLB_REG_GPIO_26_OE_POS)) +#define GLB_REG_GPIO_26_FUNC_SEL GLB_REG_GPIO_26_FUNC_SEL +#define GLB_REG_GPIO_26_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_26_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_26_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_26_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_26_FUNC_SEL_POS) +#define GLB_REG_GPIO_26_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_26_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_26_FUNC_SEL_POS)) +#define GLB_REG_GPIO_26_INT_MODE_SET GLB_REG_GPIO_26_INT_MODE_SET +#define GLB_REG_GPIO_26_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_26_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_26_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_26_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_26_INT_MODE_SET_POS) +#define GLB_REG_GPIO_26_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_26_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_26_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_26_INT_CLR GLB_REG_GPIO_26_INT_CLR +#define GLB_REG_GPIO_26_INT_CLR_POS (20U) +#define GLB_REG_GPIO_26_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_26_INT_CLR_MSK (((1U << GLB_REG_GPIO_26_INT_CLR_LEN) - 1) << GLB_REG_GPIO_26_INT_CLR_POS) +#define GLB_REG_GPIO_26_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_26_INT_CLR_LEN) - 1) << GLB_REG_GPIO_26_INT_CLR_POS)) +#define GLB_GPIO_26_INT_STAT GLB_GPIO_26_INT_STAT +#define GLB_GPIO_26_INT_STAT_POS (21U) +#define GLB_GPIO_26_INT_STAT_LEN (1U) +#define GLB_GPIO_26_INT_STAT_MSK (((1U << GLB_GPIO_26_INT_STAT_LEN) - 1) << GLB_GPIO_26_INT_STAT_POS) +#define GLB_GPIO_26_INT_STAT_UMSK (~(((1U << GLB_GPIO_26_INT_STAT_LEN) - 1) << GLB_GPIO_26_INT_STAT_POS)) +#define GLB_REG_GPIO_26_INT_MASK GLB_REG_GPIO_26_INT_MASK +#define GLB_REG_GPIO_26_INT_MASK_POS (22U) +#define GLB_REG_GPIO_26_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_26_INT_MASK_MSK (((1U << GLB_REG_GPIO_26_INT_MASK_LEN) - 1) << GLB_REG_GPIO_26_INT_MASK_POS) +#define GLB_REG_GPIO_26_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_26_INT_MASK_LEN) - 1) << GLB_REG_GPIO_26_INT_MASK_POS)) +#define GLB_REG_GPIO_26_O GLB_REG_GPIO_26_O +#define GLB_REG_GPIO_26_O_POS (24U) +#define GLB_REG_GPIO_26_O_LEN (1U) +#define GLB_REG_GPIO_26_O_MSK (((1U << GLB_REG_GPIO_26_O_LEN) - 1) << GLB_REG_GPIO_26_O_POS) +#define GLB_REG_GPIO_26_O_UMSK (~(((1U << GLB_REG_GPIO_26_O_LEN) - 1) << GLB_REG_GPIO_26_O_POS)) +#define GLB_REG_GPIO_26_SET GLB_REG_GPIO_26_SET +#define GLB_REG_GPIO_26_SET_POS (25U) +#define GLB_REG_GPIO_26_SET_LEN (1U) +#define GLB_REG_GPIO_26_SET_MSK (((1U << GLB_REG_GPIO_26_SET_LEN) - 1) << GLB_REG_GPIO_26_SET_POS) +#define GLB_REG_GPIO_26_SET_UMSK (~(((1U << GLB_REG_GPIO_26_SET_LEN) - 1) << GLB_REG_GPIO_26_SET_POS)) +#define GLB_REG_GPIO_26_CLR GLB_REG_GPIO_26_CLR +#define GLB_REG_GPIO_26_CLR_POS (26U) +#define GLB_REG_GPIO_26_CLR_LEN (1U) +#define GLB_REG_GPIO_26_CLR_MSK (((1U << GLB_REG_GPIO_26_CLR_LEN) - 1) << GLB_REG_GPIO_26_CLR_POS) +#define GLB_REG_GPIO_26_CLR_UMSK (~(((1U << GLB_REG_GPIO_26_CLR_LEN) - 1) << GLB_REG_GPIO_26_CLR_POS)) +#define GLB_REG_GPIO_26_I GLB_REG_GPIO_26_I +#define GLB_REG_GPIO_26_I_POS (28U) +#define GLB_REG_GPIO_26_I_LEN (1U) +#define GLB_REG_GPIO_26_I_MSK (((1U << GLB_REG_GPIO_26_I_LEN) - 1) << GLB_REG_GPIO_26_I_POS) +#define GLB_REG_GPIO_26_I_UMSK (~(((1U << GLB_REG_GPIO_26_I_LEN) - 1) << GLB_REG_GPIO_26_I_POS)) +#define GLB_REG_GPIO_26_MODE GLB_REG_GPIO_26_MODE +#define GLB_REG_GPIO_26_MODE_POS (30U) +#define GLB_REG_GPIO_26_MODE_LEN (2U) +#define GLB_REG_GPIO_26_MODE_MSK (((1U << GLB_REG_GPIO_26_MODE_LEN) - 1) << GLB_REG_GPIO_26_MODE_POS) +#define GLB_REG_GPIO_26_MODE_UMSK (~(((1U << GLB_REG_GPIO_26_MODE_LEN) - 1) << GLB_REG_GPIO_26_MODE_POS)) + +/* 0x930 : gpio_cfg27 */ +#define GLB_GPIO_CFG27_OFFSET (0x930) +#define GLB_REG_GPIO_27_IE GLB_REG_GPIO_27_IE +#define GLB_REG_GPIO_27_IE_POS (0U) +#define GLB_REG_GPIO_27_IE_LEN (1U) +#define GLB_REG_GPIO_27_IE_MSK (((1U << GLB_REG_GPIO_27_IE_LEN) - 1) << GLB_REG_GPIO_27_IE_POS) +#define GLB_REG_GPIO_27_IE_UMSK (~(((1U << GLB_REG_GPIO_27_IE_LEN) - 1) << GLB_REG_GPIO_27_IE_POS)) +#define GLB_REG_GPIO_27_SMT GLB_REG_GPIO_27_SMT +#define GLB_REG_GPIO_27_SMT_POS (1U) +#define GLB_REG_GPIO_27_SMT_LEN (1U) +#define GLB_REG_GPIO_27_SMT_MSK (((1U << GLB_REG_GPIO_27_SMT_LEN) - 1) << GLB_REG_GPIO_27_SMT_POS) +#define GLB_REG_GPIO_27_SMT_UMSK (~(((1U << GLB_REG_GPIO_27_SMT_LEN) - 1) << GLB_REG_GPIO_27_SMT_POS)) +#define GLB_REG_GPIO_27_DRV GLB_REG_GPIO_27_DRV +#define GLB_REG_GPIO_27_DRV_POS (2U) +#define GLB_REG_GPIO_27_DRV_LEN (2U) +#define GLB_REG_GPIO_27_DRV_MSK (((1U << GLB_REG_GPIO_27_DRV_LEN) - 1) << GLB_REG_GPIO_27_DRV_POS) +#define GLB_REG_GPIO_27_DRV_UMSK (~(((1U << GLB_REG_GPIO_27_DRV_LEN) - 1) << GLB_REG_GPIO_27_DRV_POS)) +#define GLB_REG_GPIO_27_PU GLB_REG_GPIO_27_PU +#define GLB_REG_GPIO_27_PU_POS (4U) +#define GLB_REG_GPIO_27_PU_LEN (1U) +#define GLB_REG_GPIO_27_PU_MSK (((1U << GLB_REG_GPIO_27_PU_LEN) - 1) << GLB_REG_GPIO_27_PU_POS) +#define GLB_REG_GPIO_27_PU_UMSK (~(((1U << GLB_REG_GPIO_27_PU_LEN) - 1) << GLB_REG_GPIO_27_PU_POS)) +#define GLB_REG_GPIO_27_PD GLB_REG_GPIO_27_PD +#define GLB_REG_GPIO_27_PD_POS (5U) +#define GLB_REG_GPIO_27_PD_LEN (1U) +#define GLB_REG_GPIO_27_PD_MSK (((1U << GLB_REG_GPIO_27_PD_LEN) - 1) << GLB_REG_GPIO_27_PD_POS) +#define GLB_REG_GPIO_27_PD_UMSK (~(((1U << GLB_REG_GPIO_27_PD_LEN) - 1) << GLB_REG_GPIO_27_PD_POS)) +#define GLB_REG_GPIO_27_OE GLB_REG_GPIO_27_OE +#define GLB_REG_GPIO_27_OE_POS (6U) +#define GLB_REG_GPIO_27_OE_LEN (1U) +#define GLB_REG_GPIO_27_OE_MSK (((1U << GLB_REG_GPIO_27_OE_LEN) - 1) << GLB_REG_GPIO_27_OE_POS) +#define GLB_REG_GPIO_27_OE_UMSK (~(((1U << GLB_REG_GPIO_27_OE_LEN) - 1) << GLB_REG_GPIO_27_OE_POS)) +#define GLB_REG_GPIO_27_FUNC_SEL GLB_REG_GPIO_27_FUNC_SEL +#define GLB_REG_GPIO_27_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_27_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_27_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_27_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_27_FUNC_SEL_POS) +#define GLB_REG_GPIO_27_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_27_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_27_FUNC_SEL_POS)) +#define GLB_REG_GPIO_27_INT_MODE_SET GLB_REG_GPIO_27_INT_MODE_SET +#define GLB_REG_GPIO_27_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_27_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_27_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_27_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_27_INT_MODE_SET_POS) +#define GLB_REG_GPIO_27_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_27_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_27_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_27_INT_CLR GLB_REG_GPIO_27_INT_CLR +#define GLB_REG_GPIO_27_INT_CLR_POS (20U) +#define GLB_REG_GPIO_27_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_27_INT_CLR_MSK (((1U << GLB_REG_GPIO_27_INT_CLR_LEN) - 1) << GLB_REG_GPIO_27_INT_CLR_POS) +#define GLB_REG_GPIO_27_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_27_INT_CLR_LEN) - 1) << GLB_REG_GPIO_27_INT_CLR_POS)) +#define GLB_GPIO_27_INT_STAT GLB_GPIO_27_INT_STAT +#define GLB_GPIO_27_INT_STAT_POS (21U) +#define GLB_GPIO_27_INT_STAT_LEN (1U) +#define GLB_GPIO_27_INT_STAT_MSK (((1U << GLB_GPIO_27_INT_STAT_LEN) - 1) << GLB_GPIO_27_INT_STAT_POS) +#define GLB_GPIO_27_INT_STAT_UMSK (~(((1U << GLB_GPIO_27_INT_STAT_LEN) - 1) << GLB_GPIO_27_INT_STAT_POS)) +#define GLB_REG_GPIO_27_INT_MASK GLB_REG_GPIO_27_INT_MASK +#define GLB_REG_GPIO_27_INT_MASK_POS (22U) +#define GLB_REG_GPIO_27_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_27_INT_MASK_MSK (((1U << GLB_REG_GPIO_27_INT_MASK_LEN) - 1) << GLB_REG_GPIO_27_INT_MASK_POS) +#define GLB_REG_GPIO_27_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_27_INT_MASK_LEN) - 1) << GLB_REG_GPIO_27_INT_MASK_POS)) +#define GLB_REG_GPIO_27_O GLB_REG_GPIO_27_O +#define GLB_REG_GPIO_27_O_POS (24U) +#define GLB_REG_GPIO_27_O_LEN (1U) +#define GLB_REG_GPIO_27_O_MSK (((1U << GLB_REG_GPIO_27_O_LEN) - 1) << GLB_REG_GPIO_27_O_POS) +#define GLB_REG_GPIO_27_O_UMSK (~(((1U << GLB_REG_GPIO_27_O_LEN) - 1) << GLB_REG_GPIO_27_O_POS)) +#define GLB_REG_GPIO_27_SET GLB_REG_GPIO_27_SET +#define GLB_REG_GPIO_27_SET_POS (25U) +#define GLB_REG_GPIO_27_SET_LEN (1U) +#define GLB_REG_GPIO_27_SET_MSK (((1U << GLB_REG_GPIO_27_SET_LEN) - 1) << GLB_REG_GPIO_27_SET_POS) +#define GLB_REG_GPIO_27_SET_UMSK (~(((1U << GLB_REG_GPIO_27_SET_LEN) - 1) << GLB_REG_GPIO_27_SET_POS)) +#define GLB_REG_GPIO_27_CLR GLB_REG_GPIO_27_CLR +#define GLB_REG_GPIO_27_CLR_POS (26U) +#define GLB_REG_GPIO_27_CLR_LEN (1U) +#define GLB_REG_GPIO_27_CLR_MSK (((1U << GLB_REG_GPIO_27_CLR_LEN) - 1) << GLB_REG_GPIO_27_CLR_POS) +#define GLB_REG_GPIO_27_CLR_UMSK (~(((1U << GLB_REG_GPIO_27_CLR_LEN) - 1) << GLB_REG_GPIO_27_CLR_POS)) +#define GLB_REG_GPIO_27_I GLB_REG_GPIO_27_I +#define GLB_REG_GPIO_27_I_POS (28U) +#define GLB_REG_GPIO_27_I_LEN (1U) +#define GLB_REG_GPIO_27_I_MSK (((1U << GLB_REG_GPIO_27_I_LEN) - 1) << GLB_REG_GPIO_27_I_POS) +#define GLB_REG_GPIO_27_I_UMSK (~(((1U << GLB_REG_GPIO_27_I_LEN) - 1) << GLB_REG_GPIO_27_I_POS)) +#define GLB_REG_GPIO_27_MODE GLB_REG_GPIO_27_MODE +#define GLB_REG_GPIO_27_MODE_POS (30U) +#define GLB_REG_GPIO_27_MODE_LEN (2U) +#define GLB_REG_GPIO_27_MODE_MSK (((1U << GLB_REG_GPIO_27_MODE_LEN) - 1) << GLB_REG_GPIO_27_MODE_POS) +#define GLB_REG_GPIO_27_MODE_UMSK (~(((1U << GLB_REG_GPIO_27_MODE_LEN) - 1) << GLB_REG_GPIO_27_MODE_POS)) + +/* 0x934 : gpio_cfg28 */ +#define GLB_GPIO_CFG28_OFFSET (0x934) +#define GLB_REG_GPIO_28_IE GLB_REG_GPIO_28_IE +#define GLB_REG_GPIO_28_IE_POS (0U) +#define GLB_REG_GPIO_28_IE_LEN (1U) +#define GLB_REG_GPIO_28_IE_MSK (((1U << GLB_REG_GPIO_28_IE_LEN) - 1) << GLB_REG_GPIO_28_IE_POS) +#define GLB_REG_GPIO_28_IE_UMSK (~(((1U << GLB_REG_GPIO_28_IE_LEN) - 1) << GLB_REG_GPIO_28_IE_POS)) +#define GLB_REG_GPIO_28_SMT GLB_REG_GPIO_28_SMT +#define GLB_REG_GPIO_28_SMT_POS (1U) +#define GLB_REG_GPIO_28_SMT_LEN (1U) +#define GLB_REG_GPIO_28_SMT_MSK (((1U << GLB_REG_GPIO_28_SMT_LEN) - 1) << GLB_REG_GPIO_28_SMT_POS) +#define GLB_REG_GPIO_28_SMT_UMSK (~(((1U << GLB_REG_GPIO_28_SMT_LEN) - 1) << GLB_REG_GPIO_28_SMT_POS)) +#define GLB_REG_GPIO_28_DRV GLB_REG_GPIO_28_DRV +#define GLB_REG_GPIO_28_DRV_POS (2U) +#define GLB_REG_GPIO_28_DRV_LEN (2U) +#define GLB_REG_GPIO_28_DRV_MSK (((1U << GLB_REG_GPIO_28_DRV_LEN) - 1) << GLB_REG_GPIO_28_DRV_POS) +#define GLB_REG_GPIO_28_DRV_UMSK (~(((1U << GLB_REG_GPIO_28_DRV_LEN) - 1) << GLB_REG_GPIO_28_DRV_POS)) +#define GLB_REG_GPIO_28_PU GLB_REG_GPIO_28_PU +#define GLB_REG_GPIO_28_PU_POS (4U) +#define GLB_REG_GPIO_28_PU_LEN (1U) +#define GLB_REG_GPIO_28_PU_MSK (((1U << GLB_REG_GPIO_28_PU_LEN) - 1) << GLB_REG_GPIO_28_PU_POS) +#define GLB_REG_GPIO_28_PU_UMSK (~(((1U << GLB_REG_GPIO_28_PU_LEN) - 1) << GLB_REG_GPIO_28_PU_POS)) +#define GLB_REG_GPIO_28_PD GLB_REG_GPIO_28_PD +#define GLB_REG_GPIO_28_PD_POS (5U) +#define GLB_REG_GPIO_28_PD_LEN (1U) +#define GLB_REG_GPIO_28_PD_MSK (((1U << GLB_REG_GPIO_28_PD_LEN) - 1) << GLB_REG_GPIO_28_PD_POS) +#define GLB_REG_GPIO_28_PD_UMSK (~(((1U << GLB_REG_GPIO_28_PD_LEN) - 1) << GLB_REG_GPIO_28_PD_POS)) +#define GLB_REG_GPIO_28_OE GLB_REG_GPIO_28_OE +#define GLB_REG_GPIO_28_OE_POS (6U) +#define GLB_REG_GPIO_28_OE_LEN (1U) +#define GLB_REG_GPIO_28_OE_MSK (((1U << GLB_REG_GPIO_28_OE_LEN) - 1) << GLB_REG_GPIO_28_OE_POS) +#define GLB_REG_GPIO_28_OE_UMSK (~(((1U << GLB_REG_GPIO_28_OE_LEN) - 1) << GLB_REG_GPIO_28_OE_POS)) +#define GLB_REG_GPIO_28_FUNC_SEL GLB_REG_GPIO_28_FUNC_SEL +#define GLB_REG_GPIO_28_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_28_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_28_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_28_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_28_FUNC_SEL_POS) +#define GLB_REG_GPIO_28_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_28_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_28_FUNC_SEL_POS)) +#define GLB_REG_GPIO_28_INT_MODE_SET GLB_REG_GPIO_28_INT_MODE_SET +#define GLB_REG_GPIO_28_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_28_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_28_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_28_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_28_INT_MODE_SET_POS) +#define GLB_REG_GPIO_28_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_28_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_28_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_28_INT_CLR GLB_REG_GPIO_28_INT_CLR +#define GLB_REG_GPIO_28_INT_CLR_POS (20U) +#define GLB_REG_GPIO_28_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_28_INT_CLR_MSK (((1U << GLB_REG_GPIO_28_INT_CLR_LEN) - 1) << GLB_REG_GPIO_28_INT_CLR_POS) +#define GLB_REG_GPIO_28_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_28_INT_CLR_LEN) - 1) << GLB_REG_GPIO_28_INT_CLR_POS)) +#define GLB_GPIO_28_INT_STAT GLB_GPIO_28_INT_STAT +#define GLB_GPIO_28_INT_STAT_POS (21U) +#define GLB_GPIO_28_INT_STAT_LEN (1U) +#define GLB_GPIO_28_INT_STAT_MSK (((1U << GLB_GPIO_28_INT_STAT_LEN) - 1) << GLB_GPIO_28_INT_STAT_POS) +#define GLB_GPIO_28_INT_STAT_UMSK (~(((1U << GLB_GPIO_28_INT_STAT_LEN) - 1) << GLB_GPIO_28_INT_STAT_POS)) +#define GLB_REG_GPIO_28_INT_MASK GLB_REG_GPIO_28_INT_MASK +#define GLB_REG_GPIO_28_INT_MASK_POS (22U) +#define GLB_REG_GPIO_28_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_28_INT_MASK_MSK (((1U << GLB_REG_GPIO_28_INT_MASK_LEN) - 1) << GLB_REG_GPIO_28_INT_MASK_POS) +#define GLB_REG_GPIO_28_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_28_INT_MASK_LEN) - 1) << GLB_REG_GPIO_28_INT_MASK_POS)) +#define GLB_REG_GPIO_28_O GLB_REG_GPIO_28_O +#define GLB_REG_GPIO_28_O_POS (24U) +#define GLB_REG_GPIO_28_O_LEN (1U) +#define GLB_REG_GPIO_28_O_MSK (((1U << GLB_REG_GPIO_28_O_LEN) - 1) << GLB_REG_GPIO_28_O_POS) +#define GLB_REG_GPIO_28_O_UMSK (~(((1U << GLB_REG_GPIO_28_O_LEN) - 1) << GLB_REG_GPIO_28_O_POS)) +#define GLB_REG_GPIO_28_SET GLB_REG_GPIO_28_SET +#define GLB_REG_GPIO_28_SET_POS (25U) +#define GLB_REG_GPIO_28_SET_LEN (1U) +#define GLB_REG_GPIO_28_SET_MSK (((1U << GLB_REG_GPIO_28_SET_LEN) - 1) << GLB_REG_GPIO_28_SET_POS) +#define GLB_REG_GPIO_28_SET_UMSK (~(((1U << GLB_REG_GPIO_28_SET_LEN) - 1) << GLB_REG_GPIO_28_SET_POS)) +#define GLB_REG_GPIO_28_CLR GLB_REG_GPIO_28_CLR +#define GLB_REG_GPIO_28_CLR_POS (26U) +#define GLB_REG_GPIO_28_CLR_LEN (1U) +#define GLB_REG_GPIO_28_CLR_MSK (((1U << GLB_REG_GPIO_28_CLR_LEN) - 1) << GLB_REG_GPIO_28_CLR_POS) +#define GLB_REG_GPIO_28_CLR_UMSK (~(((1U << GLB_REG_GPIO_28_CLR_LEN) - 1) << GLB_REG_GPIO_28_CLR_POS)) +#define GLB_REG_GPIO_28_I GLB_REG_GPIO_28_I +#define GLB_REG_GPIO_28_I_POS (28U) +#define GLB_REG_GPIO_28_I_LEN (1U) +#define GLB_REG_GPIO_28_I_MSK (((1U << GLB_REG_GPIO_28_I_LEN) - 1) << GLB_REG_GPIO_28_I_POS) +#define GLB_REG_GPIO_28_I_UMSK (~(((1U << GLB_REG_GPIO_28_I_LEN) - 1) << GLB_REG_GPIO_28_I_POS)) +#define GLB_REG_GPIO_28_MODE GLB_REG_GPIO_28_MODE +#define GLB_REG_GPIO_28_MODE_POS (30U) +#define GLB_REG_GPIO_28_MODE_LEN (2U) +#define GLB_REG_GPIO_28_MODE_MSK (((1U << GLB_REG_GPIO_28_MODE_LEN) - 1) << GLB_REG_GPIO_28_MODE_POS) +#define GLB_REG_GPIO_28_MODE_UMSK (~(((1U << GLB_REG_GPIO_28_MODE_LEN) - 1) << GLB_REG_GPIO_28_MODE_POS)) + +/* 0x938 : gpio_cfg29 */ +#define GLB_GPIO_CFG29_OFFSET (0x938) +#define GLB_REG_GPIO_29_IE GLB_REG_GPIO_29_IE +#define GLB_REG_GPIO_29_IE_POS (0U) +#define GLB_REG_GPIO_29_IE_LEN (1U) +#define GLB_REG_GPIO_29_IE_MSK (((1U << GLB_REG_GPIO_29_IE_LEN) - 1) << GLB_REG_GPIO_29_IE_POS) +#define GLB_REG_GPIO_29_IE_UMSK (~(((1U << GLB_REG_GPIO_29_IE_LEN) - 1) << GLB_REG_GPIO_29_IE_POS)) +#define GLB_REG_GPIO_29_SMT GLB_REG_GPIO_29_SMT +#define GLB_REG_GPIO_29_SMT_POS (1U) +#define GLB_REG_GPIO_29_SMT_LEN (1U) +#define GLB_REG_GPIO_29_SMT_MSK (((1U << GLB_REG_GPIO_29_SMT_LEN) - 1) << GLB_REG_GPIO_29_SMT_POS) +#define GLB_REG_GPIO_29_SMT_UMSK (~(((1U << GLB_REG_GPIO_29_SMT_LEN) - 1) << GLB_REG_GPIO_29_SMT_POS)) +#define GLB_REG_GPIO_29_DRV GLB_REG_GPIO_29_DRV +#define GLB_REG_GPIO_29_DRV_POS (2U) +#define GLB_REG_GPIO_29_DRV_LEN (2U) +#define GLB_REG_GPIO_29_DRV_MSK (((1U << GLB_REG_GPIO_29_DRV_LEN) - 1) << GLB_REG_GPIO_29_DRV_POS) +#define GLB_REG_GPIO_29_DRV_UMSK (~(((1U << GLB_REG_GPIO_29_DRV_LEN) - 1) << GLB_REG_GPIO_29_DRV_POS)) +#define GLB_REG_GPIO_29_PU GLB_REG_GPIO_29_PU +#define GLB_REG_GPIO_29_PU_POS (4U) +#define GLB_REG_GPIO_29_PU_LEN (1U) +#define GLB_REG_GPIO_29_PU_MSK (((1U << GLB_REG_GPIO_29_PU_LEN) - 1) << GLB_REG_GPIO_29_PU_POS) +#define GLB_REG_GPIO_29_PU_UMSK (~(((1U << GLB_REG_GPIO_29_PU_LEN) - 1) << GLB_REG_GPIO_29_PU_POS)) +#define GLB_REG_GPIO_29_PD GLB_REG_GPIO_29_PD +#define GLB_REG_GPIO_29_PD_POS (5U) +#define GLB_REG_GPIO_29_PD_LEN (1U) +#define GLB_REG_GPIO_29_PD_MSK (((1U << GLB_REG_GPIO_29_PD_LEN) - 1) << GLB_REG_GPIO_29_PD_POS) +#define GLB_REG_GPIO_29_PD_UMSK (~(((1U << GLB_REG_GPIO_29_PD_LEN) - 1) << GLB_REG_GPIO_29_PD_POS)) +#define GLB_REG_GPIO_29_OE GLB_REG_GPIO_29_OE +#define GLB_REG_GPIO_29_OE_POS (6U) +#define GLB_REG_GPIO_29_OE_LEN (1U) +#define GLB_REG_GPIO_29_OE_MSK (((1U << GLB_REG_GPIO_29_OE_LEN) - 1) << GLB_REG_GPIO_29_OE_POS) +#define GLB_REG_GPIO_29_OE_UMSK (~(((1U << GLB_REG_GPIO_29_OE_LEN) - 1) << GLB_REG_GPIO_29_OE_POS)) +#define GLB_REG_GPIO_29_FUNC_SEL GLB_REG_GPIO_29_FUNC_SEL +#define GLB_REG_GPIO_29_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_29_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_29_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_29_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_29_FUNC_SEL_POS) +#define GLB_REG_GPIO_29_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_29_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_29_FUNC_SEL_POS)) +#define GLB_REG_GPIO_29_INT_MODE_SET GLB_REG_GPIO_29_INT_MODE_SET +#define GLB_REG_GPIO_29_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_29_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_29_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_29_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_29_INT_MODE_SET_POS) +#define GLB_REG_GPIO_29_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_29_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_29_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_29_INT_CLR GLB_REG_GPIO_29_INT_CLR +#define GLB_REG_GPIO_29_INT_CLR_POS (20U) +#define GLB_REG_GPIO_29_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_29_INT_CLR_MSK (((1U << GLB_REG_GPIO_29_INT_CLR_LEN) - 1) << GLB_REG_GPIO_29_INT_CLR_POS) +#define GLB_REG_GPIO_29_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_29_INT_CLR_LEN) - 1) << GLB_REG_GPIO_29_INT_CLR_POS)) +#define GLB_GPIO_29_INT_STAT GLB_GPIO_29_INT_STAT +#define GLB_GPIO_29_INT_STAT_POS (21U) +#define GLB_GPIO_29_INT_STAT_LEN (1U) +#define GLB_GPIO_29_INT_STAT_MSK (((1U << GLB_GPIO_29_INT_STAT_LEN) - 1) << GLB_GPIO_29_INT_STAT_POS) +#define GLB_GPIO_29_INT_STAT_UMSK (~(((1U << GLB_GPIO_29_INT_STAT_LEN) - 1) << GLB_GPIO_29_INT_STAT_POS)) +#define GLB_REG_GPIO_29_INT_MASK GLB_REG_GPIO_29_INT_MASK +#define GLB_REG_GPIO_29_INT_MASK_POS (22U) +#define GLB_REG_GPIO_29_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_29_INT_MASK_MSK (((1U << GLB_REG_GPIO_29_INT_MASK_LEN) - 1) << GLB_REG_GPIO_29_INT_MASK_POS) +#define GLB_REG_GPIO_29_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_29_INT_MASK_LEN) - 1) << GLB_REG_GPIO_29_INT_MASK_POS)) +#define GLB_REG_GPIO_29_O GLB_REG_GPIO_29_O +#define GLB_REG_GPIO_29_O_POS (24U) +#define GLB_REG_GPIO_29_O_LEN (1U) +#define GLB_REG_GPIO_29_O_MSK (((1U << GLB_REG_GPIO_29_O_LEN) - 1) << GLB_REG_GPIO_29_O_POS) +#define GLB_REG_GPIO_29_O_UMSK (~(((1U << GLB_REG_GPIO_29_O_LEN) - 1) << GLB_REG_GPIO_29_O_POS)) +#define GLB_REG_GPIO_29_SET GLB_REG_GPIO_29_SET +#define GLB_REG_GPIO_29_SET_POS (25U) +#define GLB_REG_GPIO_29_SET_LEN (1U) +#define GLB_REG_GPIO_29_SET_MSK (((1U << GLB_REG_GPIO_29_SET_LEN) - 1) << GLB_REG_GPIO_29_SET_POS) +#define GLB_REG_GPIO_29_SET_UMSK (~(((1U << GLB_REG_GPIO_29_SET_LEN) - 1) << GLB_REG_GPIO_29_SET_POS)) +#define GLB_REG_GPIO_29_CLR GLB_REG_GPIO_29_CLR +#define GLB_REG_GPIO_29_CLR_POS (26U) +#define GLB_REG_GPIO_29_CLR_LEN (1U) +#define GLB_REG_GPIO_29_CLR_MSK (((1U << GLB_REG_GPIO_29_CLR_LEN) - 1) << GLB_REG_GPIO_29_CLR_POS) +#define GLB_REG_GPIO_29_CLR_UMSK (~(((1U << GLB_REG_GPIO_29_CLR_LEN) - 1) << GLB_REG_GPIO_29_CLR_POS)) +#define GLB_REG_GPIO_29_I GLB_REG_GPIO_29_I +#define GLB_REG_GPIO_29_I_POS (28U) +#define GLB_REG_GPIO_29_I_LEN (1U) +#define GLB_REG_GPIO_29_I_MSK (((1U << GLB_REG_GPIO_29_I_LEN) - 1) << GLB_REG_GPIO_29_I_POS) +#define GLB_REG_GPIO_29_I_UMSK (~(((1U << GLB_REG_GPIO_29_I_LEN) - 1) << GLB_REG_GPIO_29_I_POS)) +#define GLB_REG_GPIO_29_MODE GLB_REG_GPIO_29_MODE +#define GLB_REG_GPIO_29_MODE_POS (30U) +#define GLB_REG_GPIO_29_MODE_LEN (2U) +#define GLB_REG_GPIO_29_MODE_MSK (((1U << GLB_REG_GPIO_29_MODE_LEN) - 1) << GLB_REG_GPIO_29_MODE_POS) +#define GLB_REG_GPIO_29_MODE_UMSK (~(((1U << GLB_REG_GPIO_29_MODE_LEN) - 1) << GLB_REG_GPIO_29_MODE_POS)) + +/* 0x93C : gpio_cfg30 */ +#define GLB_GPIO_CFG30_OFFSET (0x93C) +#define GLB_REG_GPIO_30_IE GLB_REG_GPIO_30_IE +#define GLB_REG_GPIO_30_IE_POS (0U) +#define GLB_REG_GPIO_30_IE_LEN (1U) +#define GLB_REG_GPIO_30_IE_MSK (((1U << GLB_REG_GPIO_30_IE_LEN) - 1) << GLB_REG_GPIO_30_IE_POS) +#define GLB_REG_GPIO_30_IE_UMSK (~(((1U << GLB_REG_GPIO_30_IE_LEN) - 1) << GLB_REG_GPIO_30_IE_POS)) +#define GLB_REG_GPIO_30_SMT GLB_REG_GPIO_30_SMT +#define GLB_REG_GPIO_30_SMT_POS (1U) +#define GLB_REG_GPIO_30_SMT_LEN (1U) +#define GLB_REG_GPIO_30_SMT_MSK (((1U << GLB_REG_GPIO_30_SMT_LEN) - 1) << GLB_REG_GPIO_30_SMT_POS) +#define GLB_REG_GPIO_30_SMT_UMSK (~(((1U << GLB_REG_GPIO_30_SMT_LEN) - 1) << GLB_REG_GPIO_30_SMT_POS)) +#define GLB_REG_GPIO_30_DRV GLB_REG_GPIO_30_DRV +#define GLB_REG_GPIO_30_DRV_POS (2U) +#define GLB_REG_GPIO_30_DRV_LEN (2U) +#define GLB_REG_GPIO_30_DRV_MSK (((1U << GLB_REG_GPIO_30_DRV_LEN) - 1) << GLB_REG_GPIO_30_DRV_POS) +#define GLB_REG_GPIO_30_DRV_UMSK (~(((1U << GLB_REG_GPIO_30_DRV_LEN) - 1) << GLB_REG_GPIO_30_DRV_POS)) +#define GLB_REG_GPIO_30_PU GLB_REG_GPIO_30_PU +#define GLB_REG_GPIO_30_PU_POS (4U) +#define GLB_REG_GPIO_30_PU_LEN (1U) +#define GLB_REG_GPIO_30_PU_MSK (((1U << GLB_REG_GPIO_30_PU_LEN) - 1) << GLB_REG_GPIO_30_PU_POS) +#define GLB_REG_GPIO_30_PU_UMSK (~(((1U << GLB_REG_GPIO_30_PU_LEN) - 1) << GLB_REG_GPIO_30_PU_POS)) +#define GLB_REG_GPIO_30_PD GLB_REG_GPIO_30_PD +#define GLB_REG_GPIO_30_PD_POS (5U) +#define GLB_REG_GPIO_30_PD_LEN (1U) +#define GLB_REG_GPIO_30_PD_MSK (((1U << GLB_REG_GPIO_30_PD_LEN) - 1) << GLB_REG_GPIO_30_PD_POS) +#define GLB_REG_GPIO_30_PD_UMSK (~(((1U << GLB_REG_GPIO_30_PD_LEN) - 1) << GLB_REG_GPIO_30_PD_POS)) +#define GLB_REG_GPIO_30_OE GLB_REG_GPIO_30_OE +#define GLB_REG_GPIO_30_OE_POS (6U) +#define GLB_REG_GPIO_30_OE_LEN (1U) +#define GLB_REG_GPIO_30_OE_MSK (((1U << GLB_REG_GPIO_30_OE_LEN) - 1) << GLB_REG_GPIO_30_OE_POS) +#define GLB_REG_GPIO_30_OE_UMSK (~(((1U << GLB_REG_GPIO_30_OE_LEN) - 1) << GLB_REG_GPIO_30_OE_POS)) +#define GLB_REG_GPIO_30_FUNC_SEL GLB_REG_GPIO_30_FUNC_SEL +#define GLB_REG_GPIO_30_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_30_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_30_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_30_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_30_FUNC_SEL_POS) +#define GLB_REG_GPIO_30_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_30_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_30_FUNC_SEL_POS)) +#define GLB_REG_GPIO_30_INT_MODE_SET GLB_REG_GPIO_30_INT_MODE_SET +#define GLB_REG_GPIO_30_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_30_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_30_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_30_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_30_INT_MODE_SET_POS) +#define GLB_REG_GPIO_30_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_30_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_30_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_30_INT_CLR GLB_REG_GPIO_30_INT_CLR +#define GLB_REG_GPIO_30_INT_CLR_POS (20U) +#define GLB_REG_GPIO_30_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_30_INT_CLR_MSK (((1U << GLB_REG_GPIO_30_INT_CLR_LEN) - 1) << GLB_REG_GPIO_30_INT_CLR_POS) +#define GLB_REG_GPIO_30_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_30_INT_CLR_LEN) - 1) << GLB_REG_GPIO_30_INT_CLR_POS)) +#define GLB_GPIO_30_INT_STAT GLB_GPIO_30_INT_STAT +#define GLB_GPIO_30_INT_STAT_POS (21U) +#define GLB_GPIO_30_INT_STAT_LEN (1U) +#define GLB_GPIO_30_INT_STAT_MSK (((1U << GLB_GPIO_30_INT_STAT_LEN) - 1) << GLB_GPIO_30_INT_STAT_POS) +#define GLB_GPIO_30_INT_STAT_UMSK (~(((1U << GLB_GPIO_30_INT_STAT_LEN) - 1) << GLB_GPIO_30_INT_STAT_POS)) +#define GLB_REG_GPIO_30_INT_MASK GLB_REG_GPIO_30_INT_MASK +#define GLB_REG_GPIO_30_INT_MASK_POS (22U) +#define GLB_REG_GPIO_30_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_30_INT_MASK_MSK (((1U << GLB_REG_GPIO_30_INT_MASK_LEN) - 1) << GLB_REG_GPIO_30_INT_MASK_POS) +#define GLB_REG_GPIO_30_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_30_INT_MASK_LEN) - 1) << GLB_REG_GPIO_30_INT_MASK_POS)) +#define GLB_REG_GPIO_30_O GLB_REG_GPIO_30_O +#define GLB_REG_GPIO_30_O_POS (24U) +#define GLB_REG_GPIO_30_O_LEN (1U) +#define GLB_REG_GPIO_30_O_MSK (((1U << GLB_REG_GPIO_30_O_LEN) - 1) << GLB_REG_GPIO_30_O_POS) +#define GLB_REG_GPIO_30_O_UMSK (~(((1U << GLB_REG_GPIO_30_O_LEN) - 1) << GLB_REG_GPIO_30_O_POS)) +#define GLB_REG_GPIO_30_SET GLB_REG_GPIO_30_SET +#define GLB_REG_GPIO_30_SET_POS (25U) +#define GLB_REG_GPIO_30_SET_LEN (1U) +#define GLB_REG_GPIO_30_SET_MSK (((1U << GLB_REG_GPIO_30_SET_LEN) - 1) << GLB_REG_GPIO_30_SET_POS) +#define GLB_REG_GPIO_30_SET_UMSK (~(((1U << GLB_REG_GPIO_30_SET_LEN) - 1) << GLB_REG_GPIO_30_SET_POS)) +#define GLB_REG_GPIO_30_CLR GLB_REG_GPIO_30_CLR +#define GLB_REG_GPIO_30_CLR_POS (26U) +#define GLB_REG_GPIO_30_CLR_LEN (1U) +#define GLB_REG_GPIO_30_CLR_MSK (((1U << GLB_REG_GPIO_30_CLR_LEN) - 1) << GLB_REG_GPIO_30_CLR_POS) +#define GLB_REG_GPIO_30_CLR_UMSK (~(((1U << GLB_REG_GPIO_30_CLR_LEN) - 1) << GLB_REG_GPIO_30_CLR_POS)) +#define GLB_REG_GPIO_30_I GLB_REG_GPIO_30_I +#define GLB_REG_GPIO_30_I_POS (28U) +#define GLB_REG_GPIO_30_I_LEN (1U) +#define GLB_REG_GPIO_30_I_MSK (((1U << GLB_REG_GPIO_30_I_LEN) - 1) << GLB_REG_GPIO_30_I_POS) +#define GLB_REG_GPIO_30_I_UMSK (~(((1U << GLB_REG_GPIO_30_I_LEN) - 1) << GLB_REG_GPIO_30_I_POS)) +#define GLB_REG_GPIO_30_MODE GLB_REG_GPIO_30_MODE +#define GLB_REG_GPIO_30_MODE_POS (30U) +#define GLB_REG_GPIO_30_MODE_LEN (2U) +#define GLB_REG_GPIO_30_MODE_MSK (((1U << GLB_REG_GPIO_30_MODE_LEN) - 1) << GLB_REG_GPIO_30_MODE_POS) +#define GLB_REG_GPIO_30_MODE_UMSK (~(((1U << GLB_REG_GPIO_30_MODE_LEN) - 1) << GLB_REG_GPIO_30_MODE_POS)) + +/* 0x940 : gpio_cfg31 */ +#define GLB_GPIO_CFG31_OFFSET (0x940) +#define GLB_REG_GPIO_31_IE GLB_REG_GPIO_31_IE +#define GLB_REG_GPIO_31_IE_POS (0U) +#define GLB_REG_GPIO_31_IE_LEN (1U) +#define GLB_REG_GPIO_31_IE_MSK (((1U << GLB_REG_GPIO_31_IE_LEN) - 1) << GLB_REG_GPIO_31_IE_POS) +#define GLB_REG_GPIO_31_IE_UMSK (~(((1U << GLB_REG_GPIO_31_IE_LEN) - 1) << GLB_REG_GPIO_31_IE_POS)) +#define GLB_REG_GPIO_31_SMT GLB_REG_GPIO_31_SMT +#define GLB_REG_GPIO_31_SMT_POS (1U) +#define GLB_REG_GPIO_31_SMT_LEN (1U) +#define GLB_REG_GPIO_31_SMT_MSK (((1U << GLB_REG_GPIO_31_SMT_LEN) - 1) << GLB_REG_GPIO_31_SMT_POS) +#define GLB_REG_GPIO_31_SMT_UMSK (~(((1U << GLB_REG_GPIO_31_SMT_LEN) - 1) << GLB_REG_GPIO_31_SMT_POS)) +#define GLB_REG_GPIO_31_DRV GLB_REG_GPIO_31_DRV +#define GLB_REG_GPIO_31_DRV_POS (2U) +#define GLB_REG_GPIO_31_DRV_LEN (2U) +#define GLB_REG_GPIO_31_DRV_MSK (((1U << GLB_REG_GPIO_31_DRV_LEN) - 1) << GLB_REG_GPIO_31_DRV_POS) +#define GLB_REG_GPIO_31_DRV_UMSK (~(((1U << GLB_REG_GPIO_31_DRV_LEN) - 1) << GLB_REG_GPIO_31_DRV_POS)) +#define GLB_REG_GPIO_31_PU GLB_REG_GPIO_31_PU +#define GLB_REG_GPIO_31_PU_POS (4U) +#define GLB_REG_GPIO_31_PU_LEN (1U) +#define GLB_REG_GPIO_31_PU_MSK (((1U << GLB_REG_GPIO_31_PU_LEN) - 1) << GLB_REG_GPIO_31_PU_POS) +#define GLB_REG_GPIO_31_PU_UMSK (~(((1U << GLB_REG_GPIO_31_PU_LEN) - 1) << GLB_REG_GPIO_31_PU_POS)) +#define GLB_REG_GPIO_31_PD GLB_REG_GPIO_31_PD +#define GLB_REG_GPIO_31_PD_POS (5U) +#define GLB_REG_GPIO_31_PD_LEN (1U) +#define GLB_REG_GPIO_31_PD_MSK (((1U << GLB_REG_GPIO_31_PD_LEN) - 1) << GLB_REG_GPIO_31_PD_POS) +#define GLB_REG_GPIO_31_PD_UMSK (~(((1U << GLB_REG_GPIO_31_PD_LEN) - 1) << GLB_REG_GPIO_31_PD_POS)) +#define GLB_REG_GPIO_31_OE GLB_REG_GPIO_31_OE +#define GLB_REG_GPIO_31_OE_POS (6U) +#define GLB_REG_GPIO_31_OE_LEN (1U) +#define GLB_REG_GPIO_31_OE_MSK (((1U << GLB_REG_GPIO_31_OE_LEN) - 1) << GLB_REG_GPIO_31_OE_POS) +#define GLB_REG_GPIO_31_OE_UMSK (~(((1U << GLB_REG_GPIO_31_OE_LEN) - 1) << GLB_REG_GPIO_31_OE_POS)) +#define GLB_REG_GPIO_31_FUNC_SEL GLB_REG_GPIO_31_FUNC_SEL +#define GLB_REG_GPIO_31_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_31_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_31_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_31_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_31_FUNC_SEL_POS) +#define GLB_REG_GPIO_31_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_31_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_31_FUNC_SEL_POS)) +#define GLB_REG_GPIO_31_INT_MODE_SET GLB_REG_GPIO_31_INT_MODE_SET +#define GLB_REG_GPIO_31_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_31_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_31_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_31_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_31_INT_MODE_SET_POS) +#define GLB_REG_GPIO_31_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_31_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_31_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_31_INT_CLR GLB_REG_GPIO_31_INT_CLR +#define GLB_REG_GPIO_31_INT_CLR_POS (20U) +#define GLB_REG_GPIO_31_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_31_INT_CLR_MSK (((1U << GLB_REG_GPIO_31_INT_CLR_LEN) - 1) << GLB_REG_GPIO_31_INT_CLR_POS) +#define GLB_REG_GPIO_31_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_31_INT_CLR_LEN) - 1) << GLB_REG_GPIO_31_INT_CLR_POS)) +#define GLB_GPIO_31_INT_STAT GLB_GPIO_31_INT_STAT +#define GLB_GPIO_31_INT_STAT_POS (21U) +#define GLB_GPIO_31_INT_STAT_LEN (1U) +#define GLB_GPIO_31_INT_STAT_MSK (((1U << GLB_GPIO_31_INT_STAT_LEN) - 1) << GLB_GPIO_31_INT_STAT_POS) +#define GLB_GPIO_31_INT_STAT_UMSK (~(((1U << GLB_GPIO_31_INT_STAT_LEN) - 1) << GLB_GPIO_31_INT_STAT_POS)) +#define GLB_REG_GPIO_31_INT_MASK GLB_REG_GPIO_31_INT_MASK +#define GLB_REG_GPIO_31_INT_MASK_POS (22U) +#define GLB_REG_GPIO_31_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_31_INT_MASK_MSK (((1U << GLB_REG_GPIO_31_INT_MASK_LEN) - 1) << GLB_REG_GPIO_31_INT_MASK_POS) +#define GLB_REG_GPIO_31_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_31_INT_MASK_LEN) - 1) << GLB_REG_GPIO_31_INT_MASK_POS)) +#define GLB_REG_GPIO_31_O GLB_REG_GPIO_31_O +#define GLB_REG_GPIO_31_O_POS (24U) +#define GLB_REG_GPIO_31_O_LEN (1U) +#define GLB_REG_GPIO_31_O_MSK (((1U << GLB_REG_GPIO_31_O_LEN) - 1) << GLB_REG_GPIO_31_O_POS) +#define GLB_REG_GPIO_31_O_UMSK (~(((1U << GLB_REG_GPIO_31_O_LEN) - 1) << GLB_REG_GPIO_31_O_POS)) +#define GLB_REG_GPIO_31_SET GLB_REG_GPIO_31_SET +#define GLB_REG_GPIO_31_SET_POS (25U) +#define GLB_REG_GPIO_31_SET_LEN (1U) +#define GLB_REG_GPIO_31_SET_MSK (((1U << GLB_REG_GPIO_31_SET_LEN) - 1) << GLB_REG_GPIO_31_SET_POS) +#define GLB_REG_GPIO_31_SET_UMSK (~(((1U << GLB_REG_GPIO_31_SET_LEN) - 1) << GLB_REG_GPIO_31_SET_POS)) +#define GLB_REG_GPIO_31_CLR GLB_REG_GPIO_31_CLR +#define GLB_REG_GPIO_31_CLR_POS (26U) +#define GLB_REG_GPIO_31_CLR_LEN (1U) +#define GLB_REG_GPIO_31_CLR_MSK (((1U << GLB_REG_GPIO_31_CLR_LEN) - 1) << GLB_REG_GPIO_31_CLR_POS) +#define GLB_REG_GPIO_31_CLR_UMSK (~(((1U << GLB_REG_GPIO_31_CLR_LEN) - 1) << GLB_REG_GPIO_31_CLR_POS)) +#define GLB_REG_GPIO_31_I GLB_REG_GPIO_31_I +#define GLB_REG_GPIO_31_I_POS (28U) +#define GLB_REG_GPIO_31_I_LEN (1U) +#define GLB_REG_GPIO_31_I_MSK (((1U << GLB_REG_GPIO_31_I_LEN) - 1) << GLB_REG_GPIO_31_I_POS) +#define GLB_REG_GPIO_31_I_UMSK (~(((1U << GLB_REG_GPIO_31_I_LEN) - 1) << GLB_REG_GPIO_31_I_POS)) +#define GLB_REG_GPIO_31_MODE GLB_REG_GPIO_31_MODE +#define GLB_REG_GPIO_31_MODE_POS (30U) +#define GLB_REG_GPIO_31_MODE_LEN (2U) +#define GLB_REG_GPIO_31_MODE_MSK (((1U << GLB_REG_GPIO_31_MODE_LEN) - 1) << GLB_REG_GPIO_31_MODE_POS) +#define GLB_REG_GPIO_31_MODE_UMSK (~(((1U << GLB_REG_GPIO_31_MODE_LEN) - 1) << GLB_REG_GPIO_31_MODE_POS)) + +/* 0x944 : gpio_cfg32 */ +#define GLB_GPIO_CFG32_OFFSET (0x944) +#define GLB_REG_GPIO_32_IE GLB_REG_GPIO_32_IE +#define GLB_REG_GPIO_32_IE_POS (0U) +#define GLB_REG_GPIO_32_IE_LEN (1U) +#define GLB_REG_GPIO_32_IE_MSK (((1U << GLB_REG_GPIO_32_IE_LEN) - 1) << GLB_REG_GPIO_32_IE_POS) +#define GLB_REG_GPIO_32_IE_UMSK (~(((1U << GLB_REG_GPIO_32_IE_LEN) - 1) << GLB_REG_GPIO_32_IE_POS)) +#define GLB_REG_GPIO_32_SMT GLB_REG_GPIO_32_SMT +#define GLB_REG_GPIO_32_SMT_POS (1U) +#define GLB_REG_GPIO_32_SMT_LEN (1U) +#define GLB_REG_GPIO_32_SMT_MSK (((1U << GLB_REG_GPIO_32_SMT_LEN) - 1) << GLB_REG_GPIO_32_SMT_POS) +#define GLB_REG_GPIO_32_SMT_UMSK (~(((1U << GLB_REG_GPIO_32_SMT_LEN) - 1) << GLB_REG_GPIO_32_SMT_POS)) +#define GLB_REG_GPIO_32_DRV GLB_REG_GPIO_32_DRV +#define GLB_REG_GPIO_32_DRV_POS (2U) +#define GLB_REG_GPIO_32_DRV_LEN (2U) +#define GLB_REG_GPIO_32_DRV_MSK (((1U << GLB_REG_GPIO_32_DRV_LEN) - 1) << GLB_REG_GPIO_32_DRV_POS) +#define GLB_REG_GPIO_32_DRV_UMSK (~(((1U << GLB_REG_GPIO_32_DRV_LEN) - 1) << GLB_REG_GPIO_32_DRV_POS)) +#define GLB_REG_GPIO_32_PU GLB_REG_GPIO_32_PU +#define GLB_REG_GPIO_32_PU_POS (4U) +#define GLB_REG_GPIO_32_PU_LEN (1U) +#define GLB_REG_GPIO_32_PU_MSK (((1U << GLB_REG_GPIO_32_PU_LEN) - 1) << GLB_REG_GPIO_32_PU_POS) +#define GLB_REG_GPIO_32_PU_UMSK (~(((1U << GLB_REG_GPIO_32_PU_LEN) - 1) << GLB_REG_GPIO_32_PU_POS)) +#define GLB_REG_GPIO_32_PD GLB_REG_GPIO_32_PD +#define GLB_REG_GPIO_32_PD_POS (5U) +#define GLB_REG_GPIO_32_PD_LEN (1U) +#define GLB_REG_GPIO_32_PD_MSK (((1U << GLB_REG_GPIO_32_PD_LEN) - 1) << GLB_REG_GPIO_32_PD_POS) +#define GLB_REG_GPIO_32_PD_UMSK (~(((1U << GLB_REG_GPIO_32_PD_LEN) - 1) << GLB_REG_GPIO_32_PD_POS)) +#define GLB_REG_GPIO_32_OE GLB_REG_GPIO_32_OE +#define GLB_REG_GPIO_32_OE_POS (6U) +#define GLB_REG_GPIO_32_OE_LEN (1U) +#define GLB_REG_GPIO_32_OE_MSK (((1U << GLB_REG_GPIO_32_OE_LEN) - 1) << GLB_REG_GPIO_32_OE_POS) +#define GLB_REG_GPIO_32_OE_UMSK (~(((1U << GLB_REG_GPIO_32_OE_LEN) - 1) << GLB_REG_GPIO_32_OE_POS)) +#define GLB_REG_GPIO_32_FUNC_SEL GLB_REG_GPIO_32_FUNC_SEL +#define GLB_REG_GPIO_32_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_32_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_32_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_32_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_32_FUNC_SEL_POS) +#define GLB_REG_GPIO_32_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_32_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_32_FUNC_SEL_POS)) +#define GLB_REG_GPIO_32_INT_MODE_SET GLB_REG_GPIO_32_INT_MODE_SET +#define GLB_REG_GPIO_32_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_32_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_32_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_32_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_32_INT_MODE_SET_POS) +#define GLB_REG_GPIO_32_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_32_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_32_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_32_INT_CLR GLB_REG_GPIO_32_INT_CLR +#define GLB_REG_GPIO_32_INT_CLR_POS (20U) +#define GLB_REG_GPIO_32_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_32_INT_CLR_MSK (((1U << GLB_REG_GPIO_32_INT_CLR_LEN) - 1) << GLB_REG_GPIO_32_INT_CLR_POS) +#define GLB_REG_GPIO_32_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_32_INT_CLR_LEN) - 1) << GLB_REG_GPIO_32_INT_CLR_POS)) +#define GLB_GPIO_32_INT_STAT GLB_GPIO_32_INT_STAT +#define GLB_GPIO_32_INT_STAT_POS (21U) +#define GLB_GPIO_32_INT_STAT_LEN (1U) +#define GLB_GPIO_32_INT_STAT_MSK (((1U << GLB_GPIO_32_INT_STAT_LEN) - 1) << GLB_GPIO_32_INT_STAT_POS) +#define GLB_GPIO_32_INT_STAT_UMSK (~(((1U << GLB_GPIO_32_INT_STAT_LEN) - 1) << GLB_GPIO_32_INT_STAT_POS)) +#define GLB_REG_GPIO_32_INT_MASK GLB_REG_GPIO_32_INT_MASK +#define GLB_REG_GPIO_32_INT_MASK_POS (22U) +#define GLB_REG_GPIO_32_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_32_INT_MASK_MSK (((1U << GLB_REG_GPIO_32_INT_MASK_LEN) - 1) << GLB_REG_GPIO_32_INT_MASK_POS) +#define GLB_REG_GPIO_32_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_32_INT_MASK_LEN) - 1) << GLB_REG_GPIO_32_INT_MASK_POS)) +#define GLB_REG_GPIO_32_O GLB_REG_GPIO_32_O +#define GLB_REG_GPIO_32_O_POS (24U) +#define GLB_REG_GPIO_32_O_LEN (1U) +#define GLB_REG_GPIO_32_O_MSK (((1U << GLB_REG_GPIO_32_O_LEN) - 1) << GLB_REG_GPIO_32_O_POS) +#define GLB_REG_GPIO_32_O_UMSK (~(((1U << GLB_REG_GPIO_32_O_LEN) - 1) << GLB_REG_GPIO_32_O_POS)) +#define GLB_REG_GPIO_32_SET GLB_REG_GPIO_32_SET +#define GLB_REG_GPIO_32_SET_POS (25U) +#define GLB_REG_GPIO_32_SET_LEN (1U) +#define GLB_REG_GPIO_32_SET_MSK (((1U << GLB_REG_GPIO_32_SET_LEN) - 1) << GLB_REG_GPIO_32_SET_POS) +#define GLB_REG_GPIO_32_SET_UMSK (~(((1U << GLB_REG_GPIO_32_SET_LEN) - 1) << GLB_REG_GPIO_32_SET_POS)) +#define GLB_REG_GPIO_32_CLR GLB_REG_GPIO_32_CLR +#define GLB_REG_GPIO_32_CLR_POS (26U) +#define GLB_REG_GPIO_32_CLR_LEN (1U) +#define GLB_REG_GPIO_32_CLR_MSK (((1U << GLB_REG_GPIO_32_CLR_LEN) - 1) << GLB_REG_GPIO_32_CLR_POS) +#define GLB_REG_GPIO_32_CLR_UMSK (~(((1U << GLB_REG_GPIO_32_CLR_LEN) - 1) << GLB_REG_GPIO_32_CLR_POS)) +#define GLB_REG_GPIO_32_I GLB_REG_GPIO_32_I +#define GLB_REG_GPIO_32_I_POS (28U) +#define GLB_REG_GPIO_32_I_LEN (1U) +#define GLB_REG_GPIO_32_I_MSK (((1U << GLB_REG_GPIO_32_I_LEN) - 1) << GLB_REG_GPIO_32_I_POS) +#define GLB_REG_GPIO_32_I_UMSK (~(((1U << GLB_REG_GPIO_32_I_LEN) - 1) << GLB_REG_GPIO_32_I_POS)) +#define GLB_REG_GPIO_32_MODE GLB_REG_GPIO_32_MODE +#define GLB_REG_GPIO_32_MODE_POS (30U) +#define GLB_REG_GPIO_32_MODE_LEN (2U) +#define GLB_REG_GPIO_32_MODE_MSK (((1U << GLB_REG_GPIO_32_MODE_LEN) - 1) << GLB_REG_GPIO_32_MODE_POS) +#define GLB_REG_GPIO_32_MODE_UMSK (~(((1U << GLB_REG_GPIO_32_MODE_LEN) - 1) << GLB_REG_GPIO_32_MODE_POS)) + +/* 0x948 : gpio_cfg33 */ +#define GLB_GPIO_CFG33_OFFSET (0x948) +#define GLB_REG_GPIO_33_IE GLB_REG_GPIO_33_IE +#define GLB_REG_GPIO_33_IE_POS (0U) +#define GLB_REG_GPIO_33_IE_LEN (1U) +#define GLB_REG_GPIO_33_IE_MSK (((1U << GLB_REG_GPIO_33_IE_LEN) - 1) << GLB_REG_GPIO_33_IE_POS) +#define GLB_REG_GPIO_33_IE_UMSK (~(((1U << GLB_REG_GPIO_33_IE_LEN) - 1) << GLB_REG_GPIO_33_IE_POS)) +#define GLB_REG_GPIO_33_SMT GLB_REG_GPIO_33_SMT +#define GLB_REG_GPIO_33_SMT_POS (1U) +#define GLB_REG_GPIO_33_SMT_LEN (1U) +#define GLB_REG_GPIO_33_SMT_MSK (((1U << GLB_REG_GPIO_33_SMT_LEN) - 1) << GLB_REG_GPIO_33_SMT_POS) +#define GLB_REG_GPIO_33_SMT_UMSK (~(((1U << GLB_REG_GPIO_33_SMT_LEN) - 1) << GLB_REG_GPIO_33_SMT_POS)) +#define GLB_REG_GPIO_33_DRV GLB_REG_GPIO_33_DRV +#define GLB_REG_GPIO_33_DRV_POS (2U) +#define GLB_REG_GPIO_33_DRV_LEN (2U) +#define GLB_REG_GPIO_33_DRV_MSK (((1U << GLB_REG_GPIO_33_DRV_LEN) - 1) << GLB_REG_GPIO_33_DRV_POS) +#define GLB_REG_GPIO_33_DRV_UMSK (~(((1U << GLB_REG_GPIO_33_DRV_LEN) - 1) << GLB_REG_GPIO_33_DRV_POS)) +#define GLB_REG_GPIO_33_PU GLB_REG_GPIO_33_PU +#define GLB_REG_GPIO_33_PU_POS (4U) +#define GLB_REG_GPIO_33_PU_LEN (1U) +#define GLB_REG_GPIO_33_PU_MSK (((1U << GLB_REG_GPIO_33_PU_LEN) - 1) << GLB_REG_GPIO_33_PU_POS) +#define GLB_REG_GPIO_33_PU_UMSK (~(((1U << GLB_REG_GPIO_33_PU_LEN) - 1) << GLB_REG_GPIO_33_PU_POS)) +#define GLB_REG_GPIO_33_PD GLB_REG_GPIO_33_PD +#define GLB_REG_GPIO_33_PD_POS (5U) +#define GLB_REG_GPIO_33_PD_LEN (1U) +#define GLB_REG_GPIO_33_PD_MSK (((1U << GLB_REG_GPIO_33_PD_LEN) - 1) << GLB_REG_GPIO_33_PD_POS) +#define GLB_REG_GPIO_33_PD_UMSK (~(((1U << GLB_REG_GPIO_33_PD_LEN) - 1) << GLB_REG_GPIO_33_PD_POS)) +#define GLB_REG_GPIO_33_OE GLB_REG_GPIO_33_OE +#define GLB_REG_GPIO_33_OE_POS (6U) +#define GLB_REG_GPIO_33_OE_LEN (1U) +#define GLB_REG_GPIO_33_OE_MSK (((1U << GLB_REG_GPIO_33_OE_LEN) - 1) << GLB_REG_GPIO_33_OE_POS) +#define GLB_REG_GPIO_33_OE_UMSK (~(((1U << GLB_REG_GPIO_33_OE_LEN) - 1) << GLB_REG_GPIO_33_OE_POS)) +#define GLB_REG_GPIO_33_FUNC_SEL GLB_REG_GPIO_33_FUNC_SEL +#define GLB_REG_GPIO_33_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_33_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_33_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_33_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_33_FUNC_SEL_POS) +#define GLB_REG_GPIO_33_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_33_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_33_FUNC_SEL_POS)) +#define GLB_REG_GPIO_33_INT_MODE_SET GLB_REG_GPIO_33_INT_MODE_SET +#define GLB_REG_GPIO_33_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_33_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_33_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_33_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_33_INT_MODE_SET_POS) +#define GLB_REG_GPIO_33_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_33_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_33_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_33_INT_CLR GLB_REG_GPIO_33_INT_CLR +#define GLB_REG_GPIO_33_INT_CLR_POS (20U) +#define GLB_REG_GPIO_33_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_33_INT_CLR_MSK (((1U << GLB_REG_GPIO_33_INT_CLR_LEN) - 1) << GLB_REG_GPIO_33_INT_CLR_POS) +#define GLB_REG_GPIO_33_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_33_INT_CLR_LEN) - 1) << GLB_REG_GPIO_33_INT_CLR_POS)) +#define GLB_GPIO_33_INT_STAT GLB_GPIO_33_INT_STAT +#define GLB_GPIO_33_INT_STAT_POS (21U) +#define GLB_GPIO_33_INT_STAT_LEN (1U) +#define GLB_GPIO_33_INT_STAT_MSK (((1U << GLB_GPIO_33_INT_STAT_LEN) - 1) << GLB_GPIO_33_INT_STAT_POS) +#define GLB_GPIO_33_INT_STAT_UMSK (~(((1U << GLB_GPIO_33_INT_STAT_LEN) - 1) << GLB_GPIO_33_INT_STAT_POS)) +#define GLB_REG_GPIO_33_INT_MASK GLB_REG_GPIO_33_INT_MASK +#define GLB_REG_GPIO_33_INT_MASK_POS (22U) +#define GLB_REG_GPIO_33_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_33_INT_MASK_MSK (((1U << GLB_REG_GPIO_33_INT_MASK_LEN) - 1) << GLB_REG_GPIO_33_INT_MASK_POS) +#define GLB_REG_GPIO_33_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_33_INT_MASK_LEN) - 1) << GLB_REG_GPIO_33_INT_MASK_POS)) +#define GLB_REG_GPIO_33_O GLB_REG_GPIO_33_O +#define GLB_REG_GPIO_33_O_POS (24U) +#define GLB_REG_GPIO_33_O_LEN (1U) +#define GLB_REG_GPIO_33_O_MSK (((1U << GLB_REG_GPIO_33_O_LEN) - 1) << GLB_REG_GPIO_33_O_POS) +#define GLB_REG_GPIO_33_O_UMSK (~(((1U << GLB_REG_GPIO_33_O_LEN) - 1) << GLB_REG_GPIO_33_O_POS)) +#define GLB_REG_GPIO_33_SET GLB_REG_GPIO_33_SET +#define GLB_REG_GPIO_33_SET_POS (25U) +#define GLB_REG_GPIO_33_SET_LEN (1U) +#define GLB_REG_GPIO_33_SET_MSK (((1U << GLB_REG_GPIO_33_SET_LEN) - 1) << GLB_REG_GPIO_33_SET_POS) +#define GLB_REG_GPIO_33_SET_UMSK (~(((1U << GLB_REG_GPIO_33_SET_LEN) - 1) << GLB_REG_GPIO_33_SET_POS)) +#define GLB_REG_GPIO_33_CLR GLB_REG_GPIO_33_CLR +#define GLB_REG_GPIO_33_CLR_POS (26U) +#define GLB_REG_GPIO_33_CLR_LEN (1U) +#define GLB_REG_GPIO_33_CLR_MSK (((1U << GLB_REG_GPIO_33_CLR_LEN) - 1) << GLB_REG_GPIO_33_CLR_POS) +#define GLB_REG_GPIO_33_CLR_UMSK (~(((1U << GLB_REG_GPIO_33_CLR_LEN) - 1) << GLB_REG_GPIO_33_CLR_POS)) +#define GLB_REG_GPIO_33_I GLB_REG_GPIO_33_I +#define GLB_REG_GPIO_33_I_POS (28U) +#define GLB_REG_GPIO_33_I_LEN (1U) +#define GLB_REG_GPIO_33_I_MSK (((1U << GLB_REG_GPIO_33_I_LEN) - 1) << GLB_REG_GPIO_33_I_POS) +#define GLB_REG_GPIO_33_I_UMSK (~(((1U << GLB_REG_GPIO_33_I_LEN) - 1) << GLB_REG_GPIO_33_I_POS)) +#define GLB_REG_GPIO_33_MODE GLB_REG_GPIO_33_MODE +#define GLB_REG_GPIO_33_MODE_POS (30U) +#define GLB_REG_GPIO_33_MODE_LEN (2U) +#define GLB_REG_GPIO_33_MODE_MSK (((1U << GLB_REG_GPIO_33_MODE_LEN) - 1) << GLB_REG_GPIO_33_MODE_POS) +#define GLB_REG_GPIO_33_MODE_UMSK (~(((1U << GLB_REG_GPIO_33_MODE_LEN) - 1) << GLB_REG_GPIO_33_MODE_POS)) + +/* 0x94C : gpio_cfg34 */ +#define GLB_GPIO_CFG34_OFFSET (0x94C) +#define GLB_REG_GPIO_34_IE GLB_REG_GPIO_34_IE +#define GLB_REG_GPIO_34_IE_POS (0U) +#define GLB_REG_GPIO_34_IE_LEN (1U) +#define GLB_REG_GPIO_34_IE_MSK (((1U << GLB_REG_GPIO_34_IE_LEN) - 1) << GLB_REG_GPIO_34_IE_POS) +#define GLB_REG_GPIO_34_IE_UMSK (~(((1U << GLB_REG_GPIO_34_IE_LEN) - 1) << GLB_REG_GPIO_34_IE_POS)) +#define GLB_REG_GPIO_34_SMT GLB_REG_GPIO_34_SMT +#define GLB_REG_GPIO_34_SMT_POS (1U) +#define GLB_REG_GPIO_34_SMT_LEN (1U) +#define GLB_REG_GPIO_34_SMT_MSK (((1U << GLB_REG_GPIO_34_SMT_LEN) - 1) << GLB_REG_GPIO_34_SMT_POS) +#define GLB_REG_GPIO_34_SMT_UMSK (~(((1U << GLB_REG_GPIO_34_SMT_LEN) - 1) << GLB_REG_GPIO_34_SMT_POS)) +#define GLB_REG_GPIO_34_DRV GLB_REG_GPIO_34_DRV +#define GLB_REG_GPIO_34_DRV_POS (2U) +#define GLB_REG_GPIO_34_DRV_LEN (2U) +#define GLB_REG_GPIO_34_DRV_MSK (((1U << GLB_REG_GPIO_34_DRV_LEN) - 1) << GLB_REG_GPIO_34_DRV_POS) +#define GLB_REG_GPIO_34_DRV_UMSK (~(((1U << GLB_REG_GPIO_34_DRV_LEN) - 1) << GLB_REG_GPIO_34_DRV_POS)) +#define GLB_REG_GPIO_34_PU GLB_REG_GPIO_34_PU +#define GLB_REG_GPIO_34_PU_POS (4U) +#define GLB_REG_GPIO_34_PU_LEN (1U) +#define GLB_REG_GPIO_34_PU_MSK (((1U << GLB_REG_GPIO_34_PU_LEN) - 1) << GLB_REG_GPIO_34_PU_POS) +#define GLB_REG_GPIO_34_PU_UMSK (~(((1U << GLB_REG_GPIO_34_PU_LEN) - 1) << GLB_REG_GPIO_34_PU_POS)) +#define GLB_REG_GPIO_34_PD GLB_REG_GPIO_34_PD +#define GLB_REG_GPIO_34_PD_POS (5U) +#define GLB_REG_GPIO_34_PD_LEN (1U) +#define GLB_REG_GPIO_34_PD_MSK (((1U << GLB_REG_GPIO_34_PD_LEN) - 1) << GLB_REG_GPIO_34_PD_POS) +#define GLB_REG_GPIO_34_PD_UMSK (~(((1U << GLB_REG_GPIO_34_PD_LEN) - 1) << GLB_REG_GPIO_34_PD_POS)) +#define GLB_REG_GPIO_34_OE GLB_REG_GPIO_34_OE +#define GLB_REG_GPIO_34_OE_POS (6U) +#define GLB_REG_GPIO_34_OE_LEN (1U) +#define GLB_REG_GPIO_34_OE_MSK (((1U << GLB_REG_GPIO_34_OE_LEN) - 1) << GLB_REG_GPIO_34_OE_POS) +#define GLB_REG_GPIO_34_OE_UMSK (~(((1U << GLB_REG_GPIO_34_OE_LEN) - 1) << GLB_REG_GPIO_34_OE_POS)) +#define GLB_REG_GPIO_34_FUNC_SEL GLB_REG_GPIO_34_FUNC_SEL +#define GLB_REG_GPIO_34_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_34_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_34_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_34_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_34_FUNC_SEL_POS) +#define GLB_REG_GPIO_34_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_34_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_34_FUNC_SEL_POS)) +#define GLB_REG_GPIO_34_INT_MODE_SET GLB_REG_GPIO_34_INT_MODE_SET +#define GLB_REG_GPIO_34_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_34_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_34_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_34_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_34_INT_MODE_SET_POS) +#define GLB_REG_GPIO_34_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_34_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_34_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_34_INT_CLR GLB_REG_GPIO_34_INT_CLR +#define GLB_REG_GPIO_34_INT_CLR_POS (20U) +#define GLB_REG_GPIO_34_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_34_INT_CLR_MSK (((1U << GLB_REG_GPIO_34_INT_CLR_LEN) - 1) << GLB_REG_GPIO_34_INT_CLR_POS) +#define GLB_REG_GPIO_34_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_34_INT_CLR_LEN) - 1) << GLB_REG_GPIO_34_INT_CLR_POS)) +#define GLB_GPIO_34_INT_STAT GLB_GPIO_34_INT_STAT +#define GLB_GPIO_34_INT_STAT_POS (21U) +#define GLB_GPIO_34_INT_STAT_LEN (1U) +#define GLB_GPIO_34_INT_STAT_MSK (((1U << GLB_GPIO_34_INT_STAT_LEN) - 1) << GLB_GPIO_34_INT_STAT_POS) +#define GLB_GPIO_34_INT_STAT_UMSK (~(((1U << GLB_GPIO_34_INT_STAT_LEN) - 1) << GLB_GPIO_34_INT_STAT_POS)) +#define GLB_REG_GPIO_34_INT_MASK GLB_REG_GPIO_34_INT_MASK +#define GLB_REG_GPIO_34_INT_MASK_POS (22U) +#define GLB_REG_GPIO_34_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_34_INT_MASK_MSK (((1U << GLB_REG_GPIO_34_INT_MASK_LEN) - 1) << GLB_REG_GPIO_34_INT_MASK_POS) +#define GLB_REG_GPIO_34_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_34_INT_MASK_LEN) - 1) << GLB_REG_GPIO_34_INT_MASK_POS)) +#define GLB_REG_GPIO_34_O GLB_REG_GPIO_34_O +#define GLB_REG_GPIO_34_O_POS (24U) +#define GLB_REG_GPIO_34_O_LEN (1U) +#define GLB_REG_GPIO_34_O_MSK (((1U << GLB_REG_GPIO_34_O_LEN) - 1) << GLB_REG_GPIO_34_O_POS) +#define GLB_REG_GPIO_34_O_UMSK (~(((1U << GLB_REG_GPIO_34_O_LEN) - 1) << GLB_REG_GPIO_34_O_POS)) +#define GLB_REG_GPIO_34_SET GLB_REG_GPIO_34_SET +#define GLB_REG_GPIO_34_SET_POS (25U) +#define GLB_REG_GPIO_34_SET_LEN (1U) +#define GLB_REG_GPIO_34_SET_MSK (((1U << GLB_REG_GPIO_34_SET_LEN) - 1) << GLB_REG_GPIO_34_SET_POS) +#define GLB_REG_GPIO_34_SET_UMSK (~(((1U << GLB_REG_GPIO_34_SET_LEN) - 1) << GLB_REG_GPIO_34_SET_POS)) +#define GLB_REG_GPIO_34_CLR GLB_REG_GPIO_34_CLR +#define GLB_REG_GPIO_34_CLR_POS (26U) +#define GLB_REG_GPIO_34_CLR_LEN (1U) +#define GLB_REG_GPIO_34_CLR_MSK (((1U << GLB_REG_GPIO_34_CLR_LEN) - 1) << GLB_REG_GPIO_34_CLR_POS) +#define GLB_REG_GPIO_34_CLR_UMSK (~(((1U << GLB_REG_GPIO_34_CLR_LEN) - 1) << GLB_REG_GPIO_34_CLR_POS)) +#define GLB_REG_GPIO_34_I GLB_REG_GPIO_34_I +#define GLB_REG_GPIO_34_I_POS (28U) +#define GLB_REG_GPIO_34_I_LEN (1U) +#define GLB_REG_GPIO_34_I_MSK (((1U << GLB_REG_GPIO_34_I_LEN) - 1) << GLB_REG_GPIO_34_I_POS) +#define GLB_REG_GPIO_34_I_UMSK (~(((1U << GLB_REG_GPIO_34_I_LEN) - 1) << GLB_REG_GPIO_34_I_POS)) +#define GLB_REG_GPIO_34_MODE GLB_REG_GPIO_34_MODE +#define GLB_REG_GPIO_34_MODE_POS (30U) +#define GLB_REG_GPIO_34_MODE_LEN (2U) +#define GLB_REG_GPIO_34_MODE_MSK (((1U << GLB_REG_GPIO_34_MODE_LEN) - 1) << GLB_REG_GPIO_34_MODE_POS) +#define GLB_REG_GPIO_34_MODE_UMSK (~(((1U << GLB_REG_GPIO_34_MODE_LEN) - 1) << GLB_REG_GPIO_34_MODE_POS)) + +/* 0x950 : gpio_cfg35 */ +#define GLB_GPIO_CFG35_OFFSET (0x950) +#define GLB_REG_GPIO_35_IE GLB_REG_GPIO_35_IE +#define GLB_REG_GPIO_35_IE_POS (0U) +#define GLB_REG_GPIO_35_IE_LEN (1U) +#define GLB_REG_GPIO_35_IE_MSK (((1U << GLB_REG_GPIO_35_IE_LEN) - 1) << GLB_REG_GPIO_35_IE_POS) +#define GLB_REG_GPIO_35_IE_UMSK (~(((1U << GLB_REG_GPIO_35_IE_LEN) - 1) << GLB_REG_GPIO_35_IE_POS)) +#define GLB_REG_GPIO_35_SMT GLB_REG_GPIO_35_SMT +#define GLB_REG_GPIO_35_SMT_POS (1U) +#define GLB_REG_GPIO_35_SMT_LEN (1U) +#define GLB_REG_GPIO_35_SMT_MSK (((1U << GLB_REG_GPIO_35_SMT_LEN) - 1) << GLB_REG_GPIO_35_SMT_POS) +#define GLB_REG_GPIO_35_SMT_UMSK (~(((1U << GLB_REG_GPIO_35_SMT_LEN) - 1) << GLB_REG_GPIO_35_SMT_POS)) +#define GLB_REG_GPIO_35_DRV GLB_REG_GPIO_35_DRV +#define GLB_REG_GPIO_35_DRV_POS (2U) +#define GLB_REG_GPIO_35_DRV_LEN (2U) +#define GLB_REG_GPIO_35_DRV_MSK (((1U << GLB_REG_GPIO_35_DRV_LEN) - 1) << GLB_REG_GPIO_35_DRV_POS) +#define GLB_REG_GPIO_35_DRV_UMSK (~(((1U << GLB_REG_GPIO_35_DRV_LEN) - 1) << GLB_REG_GPIO_35_DRV_POS)) +#define GLB_REG_GPIO_35_PU GLB_REG_GPIO_35_PU +#define GLB_REG_GPIO_35_PU_POS (4U) +#define GLB_REG_GPIO_35_PU_LEN (1U) +#define GLB_REG_GPIO_35_PU_MSK (((1U << GLB_REG_GPIO_35_PU_LEN) - 1) << GLB_REG_GPIO_35_PU_POS) +#define GLB_REG_GPIO_35_PU_UMSK (~(((1U << GLB_REG_GPIO_35_PU_LEN) - 1) << GLB_REG_GPIO_35_PU_POS)) +#define GLB_REG_GPIO_35_PD GLB_REG_GPIO_35_PD +#define GLB_REG_GPIO_35_PD_POS (5U) +#define GLB_REG_GPIO_35_PD_LEN (1U) +#define GLB_REG_GPIO_35_PD_MSK (((1U << GLB_REG_GPIO_35_PD_LEN) - 1) << GLB_REG_GPIO_35_PD_POS) +#define GLB_REG_GPIO_35_PD_UMSK (~(((1U << GLB_REG_GPIO_35_PD_LEN) - 1) << GLB_REG_GPIO_35_PD_POS)) +#define GLB_REG_GPIO_35_OE GLB_REG_GPIO_35_OE +#define GLB_REG_GPIO_35_OE_POS (6U) +#define GLB_REG_GPIO_35_OE_LEN (1U) +#define GLB_REG_GPIO_35_OE_MSK (((1U << GLB_REG_GPIO_35_OE_LEN) - 1) << GLB_REG_GPIO_35_OE_POS) +#define GLB_REG_GPIO_35_OE_UMSK (~(((1U << GLB_REG_GPIO_35_OE_LEN) - 1) << GLB_REG_GPIO_35_OE_POS)) +#define GLB_REG_GPIO_35_FUNC_SEL GLB_REG_GPIO_35_FUNC_SEL +#define GLB_REG_GPIO_35_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_35_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_35_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_35_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_35_FUNC_SEL_POS) +#define GLB_REG_GPIO_35_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_35_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_35_FUNC_SEL_POS)) +#define GLB_REG_GPIO_35_INT_MODE_SET GLB_REG_GPIO_35_INT_MODE_SET +#define GLB_REG_GPIO_35_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_35_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_35_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_35_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_35_INT_MODE_SET_POS) +#define GLB_REG_GPIO_35_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_35_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_35_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_35_INT_CLR GLB_REG_GPIO_35_INT_CLR +#define GLB_REG_GPIO_35_INT_CLR_POS (20U) +#define GLB_REG_GPIO_35_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_35_INT_CLR_MSK (((1U << GLB_REG_GPIO_35_INT_CLR_LEN) - 1) << GLB_REG_GPIO_35_INT_CLR_POS) +#define GLB_REG_GPIO_35_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_35_INT_CLR_LEN) - 1) << GLB_REG_GPIO_35_INT_CLR_POS)) +#define GLB_GPIO_35_INT_STAT GLB_GPIO_35_INT_STAT +#define GLB_GPIO_35_INT_STAT_POS (21U) +#define GLB_GPIO_35_INT_STAT_LEN (1U) +#define GLB_GPIO_35_INT_STAT_MSK (((1U << GLB_GPIO_35_INT_STAT_LEN) - 1) << GLB_GPIO_35_INT_STAT_POS) +#define GLB_GPIO_35_INT_STAT_UMSK (~(((1U << GLB_GPIO_35_INT_STAT_LEN) - 1) << GLB_GPIO_35_INT_STAT_POS)) +#define GLB_REG_GPIO_35_INT_MASK GLB_REG_GPIO_35_INT_MASK +#define GLB_REG_GPIO_35_INT_MASK_POS (22U) +#define GLB_REG_GPIO_35_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_35_INT_MASK_MSK (((1U << GLB_REG_GPIO_35_INT_MASK_LEN) - 1) << GLB_REG_GPIO_35_INT_MASK_POS) +#define GLB_REG_GPIO_35_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_35_INT_MASK_LEN) - 1) << GLB_REG_GPIO_35_INT_MASK_POS)) +#define GLB_REG_GPIO_35_O GLB_REG_GPIO_35_O +#define GLB_REG_GPIO_35_O_POS (24U) +#define GLB_REG_GPIO_35_O_LEN (1U) +#define GLB_REG_GPIO_35_O_MSK (((1U << GLB_REG_GPIO_35_O_LEN) - 1) << GLB_REG_GPIO_35_O_POS) +#define GLB_REG_GPIO_35_O_UMSK (~(((1U << GLB_REG_GPIO_35_O_LEN) - 1) << GLB_REG_GPIO_35_O_POS)) +#define GLB_REG_GPIO_35_SET GLB_REG_GPIO_35_SET +#define GLB_REG_GPIO_35_SET_POS (25U) +#define GLB_REG_GPIO_35_SET_LEN (1U) +#define GLB_REG_GPIO_35_SET_MSK (((1U << GLB_REG_GPIO_35_SET_LEN) - 1) << GLB_REG_GPIO_35_SET_POS) +#define GLB_REG_GPIO_35_SET_UMSK (~(((1U << GLB_REG_GPIO_35_SET_LEN) - 1) << GLB_REG_GPIO_35_SET_POS)) +#define GLB_REG_GPIO_35_CLR GLB_REG_GPIO_35_CLR +#define GLB_REG_GPIO_35_CLR_POS (26U) +#define GLB_REG_GPIO_35_CLR_LEN (1U) +#define GLB_REG_GPIO_35_CLR_MSK (((1U << GLB_REG_GPIO_35_CLR_LEN) - 1) << GLB_REG_GPIO_35_CLR_POS) +#define GLB_REG_GPIO_35_CLR_UMSK (~(((1U << GLB_REG_GPIO_35_CLR_LEN) - 1) << GLB_REG_GPIO_35_CLR_POS)) +#define GLB_REG_GPIO_35_I GLB_REG_GPIO_35_I +#define GLB_REG_GPIO_35_I_POS (28U) +#define GLB_REG_GPIO_35_I_LEN (1U) +#define GLB_REG_GPIO_35_I_MSK (((1U << GLB_REG_GPIO_35_I_LEN) - 1) << GLB_REG_GPIO_35_I_POS) +#define GLB_REG_GPIO_35_I_UMSK (~(((1U << GLB_REG_GPIO_35_I_LEN) - 1) << GLB_REG_GPIO_35_I_POS)) +#define GLB_REG_GPIO_35_MODE GLB_REG_GPIO_35_MODE +#define GLB_REG_GPIO_35_MODE_POS (30U) +#define GLB_REG_GPIO_35_MODE_LEN (2U) +#define GLB_REG_GPIO_35_MODE_MSK (((1U << GLB_REG_GPIO_35_MODE_LEN) - 1) << GLB_REG_GPIO_35_MODE_POS) +#define GLB_REG_GPIO_35_MODE_UMSK (~(((1U << GLB_REG_GPIO_35_MODE_LEN) - 1) << GLB_REG_GPIO_35_MODE_POS)) + +/* 0x954 : gpio_cfg36 */ +#define GLB_GPIO_CFG36_OFFSET (0x954) +#define GLB_REG_GPIO_36_IE GLB_REG_GPIO_36_IE +#define GLB_REG_GPIO_36_IE_POS (0U) +#define GLB_REG_GPIO_36_IE_LEN (1U) +#define GLB_REG_GPIO_36_IE_MSK (((1U << GLB_REG_GPIO_36_IE_LEN) - 1) << GLB_REG_GPIO_36_IE_POS) +#define GLB_REG_GPIO_36_IE_UMSK (~(((1U << GLB_REG_GPIO_36_IE_LEN) - 1) << GLB_REG_GPIO_36_IE_POS)) +#define GLB_REG_GPIO_36_SMT GLB_REG_GPIO_36_SMT +#define GLB_REG_GPIO_36_SMT_POS (1U) +#define GLB_REG_GPIO_36_SMT_LEN (1U) +#define GLB_REG_GPIO_36_SMT_MSK (((1U << GLB_REG_GPIO_36_SMT_LEN) - 1) << GLB_REG_GPIO_36_SMT_POS) +#define GLB_REG_GPIO_36_SMT_UMSK (~(((1U << GLB_REG_GPIO_36_SMT_LEN) - 1) << GLB_REG_GPIO_36_SMT_POS)) +#define GLB_REG_GPIO_36_DRV GLB_REG_GPIO_36_DRV +#define GLB_REG_GPIO_36_DRV_POS (2U) +#define GLB_REG_GPIO_36_DRV_LEN (2U) +#define GLB_REG_GPIO_36_DRV_MSK (((1U << GLB_REG_GPIO_36_DRV_LEN) - 1) << GLB_REG_GPIO_36_DRV_POS) +#define GLB_REG_GPIO_36_DRV_UMSK (~(((1U << GLB_REG_GPIO_36_DRV_LEN) - 1) << GLB_REG_GPIO_36_DRV_POS)) +#define GLB_REG_GPIO_36_PU GLB_REG_GPIO_36_PU +#define GLB_REG_GPIO_36_PU_POS (4U) +#define GLB_REG_GPIO_36_PU_LEN (1U) +#define GLB_REG_GPIO_36_PU_MSK (((1U << GLB_REG_GPIO_36_PU_LEN) - 1) << GLB_REG_GPIO_36_PU_POS) +#define GLB_REG_GPIO_36_PU_UMSK (~(((1U << GLB_REG_GPIO_36_PU_LEN) - 1) << GLB_REG_GPIO_36_PU_POS)) +#define GLB_REG_GPIO_36_PD GLB_REG_GPIO_36_PD +#define GLB_REG_GPIO_36_PD_POS (5U) +#define GLB_REG_GPIO_36_PD_LEN (1U) +#define GLB_REG_GPIO_36_PD_MSK (((1U << GLB_REG_GPIO_36_PD_LEN) - 1) << GLB_REG_GPIO_36_PD_POS) +#define GLB_REG_GPIO_36_PD_UMSK (~(((1U << GLB_REG_GPIO_36_PD_LEN) - 1) << GLB_REG_GPIO_36_PD_POS)) +#define GLB_REG_GPIO_36_OE GLB_REG_GPIO_36_OE +#define GLB_REG_GPIO_36_OE_POS (6U) +#define GLB_REG_GPIO_36_OE_LEN (1U) +#define GLB_REG_GPIO_36_OE_MSK (((1U << GLB_REG_GPIO_36_OE_LEN) - 1) << GLB_REG_GPIO_36_OE_POS) +#define GLB_REG_GPIO_36_OE_UMSK (~(((1U << GLB_REG_GPIO_36_OE_LEN) - 1) << GLB_REG_GPIO_36_OE_POS)) +#define GLB_REG_GPIO_36_FUNC_SEL GLB_REG_GPIO_36_FUNC_SEL +#define GLB_REG_GPIO_36_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_36_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_36_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_36_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_36_FUNC_SEL_POS) +#define GLB_REG_GPIO_36_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_36_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_36_FUNC_SEL_POS)) +#define GLB_REG_GPIO_36_INT_MODE_SET GLB_REG_GPIO_36_INT_MODE_SET +#define GLB_REG_GPIO_36_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_36_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_36_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_36_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_36_INT_MODE_SET_POS) +#define GLB_REG_GPIO_36_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_36_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_36_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_36_INT_CLR GLB_REG_GPIO_36_INT_CLR +#define GLB_REG_GPIO_36_INT_CLR_POS (20U) +#define GLB_REG_GPIO_36_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_36_INT_CLR_MSK (((1U << GLB_REG_GPIO_36_INT_CLR_LEN) - 1) << GLB_REG_GPIO_36_INT_CLR_POS) +#define GLB_REG_GPIO_36_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_36_INT_CLR_LEN) - 1) << GLB_REG_GPIO_36_INT_CLR_POS)) +#define GLB_GPIO_36_INT_STAT GLB_GPIO_36_INT_STAT +#define GLB_GPIO_36_INT_STAT_POS (21U) +#define GLB_GPIO_36_INT_STAT_LEN (1U) +#define GLB_GPIO_36_INT_STAT_MSK (((1U << GLB_GPIO_36_INT_STAT_LEN) - 1) << GLB_GPIO_36_INT_STAT_POS) +#define GLB_GPIO_36_INT_STAT_UMSK (~(((1U << GLB_GPIO_36_INT_STAT_LEN) - 1) << GLB_GPIO_36_INT_STAT_POS)) +#define GLB_REG_GPIO_36_INT_MASK GLB_REG_GPIO_36_INT_MASK +#define GLB_REG_GPIO_36_INT_MASK_POS (22U) +#define GLB_REG_GPIO_36_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_36_INT_MASK_MSK (((1U << GLB_REG_GPIO_36_INT_MASK_LEN) - 1) << GLB_REG_GPIO_36_INT_MASK_POS) +#define GLB_REG_GPIO_36_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_36_INT_MASK_LEN) - 1) << GLB_REG_GPIO_36_INT_MASK_POS)) +#define GLB_REG_GPIO_36_O GLB_REG_GPIO_36_O +#define GLB_REG_GPIO_36_O_POS (24U) +#define GLB_REG_GPIO_36_O_LEN (1U) +#define GLB_REG_GPIO_36_O_MSK (((1U << GLB_REG_GPIO_36_O_LEN) - 1) << GLB_REG_GPIO_36_O_POS) +#define GLB_REG_GPIO_36_O_UMSK (~(((1U << GLB_REG_GPIO_36_O_LEN) - 1) << GLB_REG_GPIO_36_O_POS)) +#define GLB_REG_GPIO_36_SET GLB_REG_GPIO_36_SET +#define GLB_REG_GPIO_36_SET_POS (25U) +#define GLB_REG_GPIO_36_SET_LEN (1U) +#define GLB_REG_GPIO_36_SET_MSK (((1U << GLB_REG_GPIO_36_SET_LEN) - 1) << GLB_REG_GPIO_36_SET_POS) +#define GLB_REG_GPIO_36_SET_UMSK (~(((1U << GLB_REG_GPIO_36_SET_LEN) - 1) << GLB_REG_GPIO_36_SET_POS)) +#define GLB_REG_GPIO_36_CLR GLB_REG_GPIO_36_CLR +#define GLB_REG_GPIO_36_CLR_POS (26U) +#define GLB_REG_GPIO_36_CLR_LEN (1U) +#define GLB_REG_GPIO_36_CLR_MSK (((1U << GLB_REG_GPIO_36_CLR_LEN) - 1) << GLB_REG_GPIO_36_CLR_POS) +#define GLB_REG_GPIO_36_CLR_UMSK (~(((1U << GLB_REG_GPIO_36_CLR_LEN) - 1) << GLB_REG_GPIO_36_CLR_POS)) +#define GLB_REG_GPIO_36_I GLB_REG_GPIO_36_I +#define GLB_REG_GPIO_36_I_POS (28U) +#define GLB_REG_GPIO_36_I_LEN (1U) +#define GLB_REG_GPIO_36_I_MSK (((1U << GLB_REG_GPIO_36_I_LEN) - 1) << GLB_REG_GPIO_36_I_POS) +#define GLB_REG_GPIO_36_I_UMSK (~(((1U << GLB_REG_GPIO_36_I_LEN) - 1) << GLB_REG_GPIO_36_I_POS)) +#define GLB_REG_GPIO_36_MODE GLB_REG_GPIO_36_MODE +#define GLB_REG_GPIO_36_MODE_POS (30U) +#define GLB_REG_GPIO_36_MODE_LEN (2U) +#define GLB_REG_GPIO_36_MODE_MSK (((1U << GLB_REG_GPIO_36_MODE_LEN) - 1) << GLB_REG_GPIO_36_MODE_POS) +#define GLB_REG_GPIO_36_MODE_UMSK (~(((1U << GLB_REG_GPIO_36_MODE_LEN) - 1) << GLB_REG_GPIO_36_MODE_POS)) + +/* 0x958 : gpio_cfg37 */ +#define GLB_GPIO_CFG37_OFFSET (0x958) +#define GLB_REG_GPIO_37_IE GLB_REG_GPIO_37_IE +#define GLB_REG_GPIO_37_IE_POS (0U) +#define GLB_REG_GPIO_37_IE_LEN (1U) +#define GLB_REG_GPIO_37_IE_MSK (((1U << GLB_REG_GPIO_37_IE_LEN) - 1) << GLB_REG_GPIO_37_IE_POS) +#define GLB_REG_GPIO_37_IE_UMSK (~(((1U << GLB_REG_GPIO_37_IE_LEN) - 1) << GLB_REG_GPIO_37_IE_POS)) +#define GLB_REG_GPIO_37_SMT GLB_REG_GPIO_37_SMT +#define GLB_REG_GPIO_37_SMT_POS (1U) +#define GLB_REG_GPIO_37_SMT_LEN (1U) +#define GLB_REG_GPIO_37_SMT_MSK (((1U << GLB_REG_GPIO_37_SMT_LEN) - 1) << GLB_REG_GPIO_37_SMT_POS) +#define GLB_REG_GPIO_37_SMT_UMSK (~(((1U << GLB_REG_GPIO_37_SMT_LEN) - 1) << GLB_REG_GPIO_37_SMT_POS)) +#define GLB_REG_GPIO_37_DRV GLB_REG_GPIO_37_DRV +#define GLB_REG_GPIO_37_DRV_POS (2U) +#define GLB_REG_GPIO_37_DRV_LEN (2U) +#define GLB_REG_GPIO_37_DRV_MSK (((1U << GLB_REG_GPIO_37_DRV_LEN) - 1) << GLB_REG_GPIO_37_DRV_POS) +#define GLB_REG_GPIO_37_DRV_UMSK (~(((1U << GLB_REG_GPIO_37_DRV_LEN) - 1) << GLB_REG_GPIO_37_DRV_POS)) +#define GLB_REG_GPIO_37_PU GLB_REG_GPIO_37_PU +#define GLB_REG_GPIO_37_PU_POS (4U) +#define GLB_REG_GPIO_37_PU_LEN (1U) +#define GLB_REG_GPIO_37_PU_MSK (((1U << GLB_REG_GPIO_37_PU_LEN) - 1) << GLB_REG_GPIO_37_PU_POS) +#define GLB_REG_GPIO_37_PU_UMSK (~(((1U << GLB_REG_GPIO_37_PU_LEN) - 1) << GLB_REG_GPIO_37_PU_POS)) +#define GLB_REG_GPIO_37_PD GLB_REG_GPIO_37_PD +#define GLB_REG_GPIO_37_PD_POS (5U) +#define GLB_REG_GPIO_37_PD_LEN (1U) +#define GLB_REG_GPIO_37_PD_MSK (((1U << GLB_REG_GPIO_37_PD_LEN) - 1) << GLB_REG_GPIO_37_PD_POS) +#define GLB_REG_GPIO_37_PD_UMSK (~(((1U << GLB_REG_GPIO_37_PD_LEN) - 1) << GLB_REG_GPIO_37_PD_POS)) +#define GLB_REG_GPIO_37_OE GLB_REG_GPIO_37_OE +#define GLB_REG_GPIO_37_OE_POS (6U) +#define GLB_REG_GPIO_37_OE_LEN (1U) +#define GLB_REG_GPIO_37_OE_MSK (((1U << GLB_REG_GPIO_37_OE_LEN) - 1) << GLB_REG_GPIO_37_OE_POS) +#define GLB_REG_GPIO_37_OE_UMSK (~(((1U << GLB_REG_GPIO_37_OE_LEN) - 1) << GLB_REG_GPIO_37_OE_POS)) +#define GLB_REG_GPIO_37_FUNC_SEL GLB_REG_GPIO_37_FUNC_SEL +#define GLB_REG_GPIO_37_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_37_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_37_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_37_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_37_FUNC_SEL_POS) +#define GLB_REG_GPIO_37_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_37_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_37_FUNC_SEL_POS)) +#define GLB_REG_GPIO_37_INT_MODE_SET GLB_REG_GPIO_37_INT_MODE_SET +#define GLB_REG_GPIO_37_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_37_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_37_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_37_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_37_INT_MODE_SET_POS) +#define GLB_REG_GPIO_37_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_37_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_37_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_37_INT_CLR GLB_REG_GPIO_37_INT_CLR +#define GLB_REG_GPIO_37_INT_CLR_POS (20U) +#define GLB_REG_GPIO_37_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_37_INT_CLR_MSK (((1U << GLB_REG_GPIO_37_INT_CLR_LEN) - 1) << GLB_REG_GPIO_37_INT_CLR_POS) +#define GLB_REG_GPIO_37_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_37_INT_CLR_LEN) - 1) << GLB_REG_GPIO_37_INT_CLR_POS)) +#define GLB_GPIO_37_INT_STAT GLB_GPIO_37_INT_STAT +#define GLB_GPIO_37_INT_STAT_POS (21U) +#define GLB_GPIO_37_INT_STAT_LEN (1U) +#define GLB_GPIO_37_INT_STAT_MSK (((1U << GLB_GPIO_37_INT_STAT_LEN) - 1) << GLB_GPIO_37_INT_STAT_POS) +#define GLB_GPIO_37_INT_STAT_UMSK (~(((1U << GLB_GPIO_37_INT_STAT_LEN) - 1) << GLB_GPIO_37_INT_STAT_POS)) +#define GLB_REG_GPIO_37_INT_MASK GLB_REG_GPIO_37_INT_MASK +#define GLB_REG_GPIO_37_INT_MASK_POS (22U) +#define GLB_REG_GPIO_37_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_37_INT_MASK_MSK (((1U << GLB_REG_GPIO_37_INT_MASK_LEN) - 1) << GLB_REG_GPIO_37_INT_MASK_POS) +#define GLB_REG_GPIO_37_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_37_INT_MASK_LEN) - 1) << GLB_REG_GPIO_37_INT_MASK_POS)) +#define GLB_REG_GPIO_37_O GLB_REG_GPIO_37_O +#define GLB_REG_GPIO_37_O_POS (24U) +#define GLB_REG_GPIO_37_O_LEN (1U) +#define GLB_REG_GPIO_37_O_MSK (((1U << GLB_REG_GPIO_37_O_LEN) - 1) << GLB_REG_GPIO_37_O_POS) +#define GLB_REG_GPIO_37_O_UMSK (~(((1U << GLB_REG_GPIO_37_O_LEN) - 1) << GLB_REG_GPIO_37_O_POS)) +#define GLB_REG_GPIO_37_SET GLB_REG_GPIO_37_SET +#define GLB_REG_GPIO_37_SET_POS (25U) +#define GLB_REG_GPIO_37_SET_LEN (1U) +#define GLB_REG_GPIO_37_SET_MSK (((1U << GLB_REG_GPIO_37_SET_LEN) - 1) << GLB_REG_GPIO_37_SET_POS) +#define GLB_REG_GPIO_37_SET_UMSK (~(((1U << GLB_REG_GPIO_37_SET_LEN) - 1) << GLB_REG_GPIO_37_SET_POS)) +#define GLB_REG_GPIO_37_CLR GLB_REG_GPIO_37_CLR +#define GLB_REG_GPIO_37_CLR_POS (26U) +#define GLB_REG_GPIO_37_CLR_LEN (1U) +#define GLB_REG_GPIO_37_CLR_MSK (((1U << GLB_REG_GPIO_37_CLR_LEN) - 1) << GLB_REG_GPIO_37_CLR_POS) +#define GLB_REG_GPIO_37_CLR_UMSK (~(((1U << GLB_REG_GPIO_37_CLR_LEN) - 1) << GLB_REG_GPIO_37_CLR_POS)) +#define GLB_REG_GPIO_37_I GLB_REG_GPIO_37_I +#define GLB_REG_GPIO_37_I_POS (28U) +#define GLB_REG_GPIO_37_I_LEN (1U) +#define GLB_REG_GPIO_37_I_MSK (((1U << GLB_REG_GPIO_37_I_LEN) - 1) << GLB_REG_GPIO_37_I_POS) +#define GLB_REG_GPIO_37_I_UMSK (~(((1U << GLB_REG_GPIO_37_I_LEN) - 1) << GLB_REG_GPIO_37_I_POS)) +#define GLB_REG_GPIO_37_MODE GLB_REG_GPIO_37_MODE +#define GLB_REG_GPIO_37_MODE_POS (30U) +#define GLB_REG_GPIO_37_MODE_LEN (2U) +#define GLB_REG_GPIO_37_MODE_MSK (((1U << GLB_REG_GPIO_37_MODE_LEN) - 1) << GLB_REG_GPIO_37_MODE_POS) +#define GLB_REG_GPIO_37_MODE_UMSK (~(((1U << GLB_REG_GPIO_37_MODE_LEN) - 1) << GLB_REG_GPIO_37_MODE_POS)) + +/* 0x95C : gpio_cfg38 */ +#define GLB_GPIO_CFG38_OFFSET (0x95C) +#define GLB_REG_GPIO_38_IE GLB_REG_GPIO_38_IE +#define GLB_REG_GPIO_38_IE_POS (0U) +#define GLB_REG_GPIO_38_IE_LEN (1U) +#define GLB_REG_GPIO_38_IE_MSK (((1U << GLB_REG_GPIO_38_IE_LEN) - 1) << GLB_REG_GPIO_38_IE_POS) +#define GLB_REG_GPIO_38_IE_UMSK (~(((1U << GLB_REG_GPIO_38_IE_LEN) - 1) << GLB_REG_GPIO_38_IE_POS)) +#define GLB_REG_GPIO_38_SMT GLB_REG_GPIO_38_SMT +#define GLB_REG_GPIO_38_SMT_POS (1U) +#define GLB_REG_GPIO_38_SMT_LEN (1U) +#define GLB_REG_GPIO_38_SMT_MSK (((1U << GLB_REG_GPIO_38_SMT_LEN) - 1) << GLB_REG_GPIO_38_SMT_POS) +#define GLB_REG_GPIO_38_SMT_UMSK (~(((1U << GLB_REG_GPIO_38_SMT_LEN) - 1) << GLB_REG_GPIO_38_SMT_POS)) +#define GLB_REG_GPIO_38_DRV GLB_REG_GPIO_38_DRV +#define GLB_REG_GPIO_38_DRV_POS (2U) +#define GLB_REG_GPIO_38_DRV_LEN (2U) +#define GLB_REG_GPIO_38_DRV_MSK (((1U << GLB_REG_GPIO_38_DRV_LEN) - 1) << GLB_REG_GPIO_38_DRV_POS) +#define GLB_REG_GPIO_38_DRV_UMSK (~(((1U << GLB_REG_GPIO_38_DRV_LEN) - 1) << GLB_REG_GPIO_38_DRV_POS)) +#define GLB_REG_GPIO_38_PU GLB_REG_GPIO_38_PU +#define GLB_REG_GPIO_38_PU_POS (4U) +#define GLB_REG_GPIO_38_PU_LEN (1U) +#define GLB_REG_GPIO_38_PU_MSK (((1U << GLB_REG_GPIO_38_PU_LEN) - 1) << GLB_REG_GPIO_38_PU_POS) +#define GLB_REG_GPIO_38_PU_UMSK (~(((1U << GLB_REG_GPIO_38_PU_LEN) - 1) << GLB_REG_GPIO_38_PU_POS)) +#define GLB_REG_GPIO_38_PD GLB_REG_GPIO_38_PD +#define GLB_REG_GPIO_38_PD_POS (5U) +#define GLB_REG_GPIO_38_PD_LEN (1U) +#define GLB_REG_GPIO_38_PD_MSK (((1U << GLB_REG_GPIO_38_PD_LEN) - 1) << GLB_REG_GPIO_38_PD_POS) +#define GLB_REG_GPIO_38_PD_UMSK (~(((1U << GLB_REG_GPIO_38_PD_LEN) - 1) << GLB_REG_GPIO_38_PD_POS)) +#define GLB_REG_GPIO_38_OE GLB_REG_GPIO_38_OE +#define GLB_REG_GPIO_38_OE_POS (6U) +#define GLB_REG_GPIO_38_OE_LEN (1U) +#define GLB_REG_GPIO_38_OE_MSK (((1U << GLB_REG_GPIO_38_OE_LEN) - 1) << GLB_REG_GPIO_38_OE_POS) +#define GLB_REG_GPIO_38_OE_UMSK (~(((1U << GLB_REG_GPIO_38_OE_LEN) - 1) << GLB_REG_GPIO_38_OE_POS)) +#define GLB_REG_GPIO_38_FUNC_SEL GLB_REG_GPIO_38_FUNC_SEL +#define GLB_REG_GPIO_38_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_38_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_38_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_38_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_38_FUNC_SEL_POS) +#define GLB_REG_GPIO_38_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_38_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_38_FUNC_SEL_POS)) +#define GLB_REG_GPIO_38_INT_MODE_SET GLB_REG_GPIO_38_INT_MODE_SET +#define GLB_REG_GPIO_38_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_38_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_38_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_38_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_38_INT_MODE_SET_POS) +#define GLB_REG_GPIO_38_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_38_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_38_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_38_INT_CLR GLB_REG_GPIO_38_INT_CLR +#define GLB_REG_GPIO_38_INT_CLR_POS (20U) +#define GLB_REG_GPIO_38_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_38_INT_CLR_MSK (((1U << GLB_REG_GPIO_38_INT_CLR_LEN) - 1) << GLB_REG_GPIO_38_INT_CLR_POS) +#define GLB_REG_GPIO_38_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_38_INT_CLR_LEN) - 1) << GLB_REG_GPIO_38_INT_CLR_POS)) +#define GLB_GPIO_38_INT_STAT GLB_GPIO_38_INT_STAT +#define GLB_GPIO_38_INT_STAT_POS (21U) +#define GLB_GPIO_38_INT_STAT_LEN (1U) +#define GLB_GPIO_38_INT_STAT_MSK (((1U << GLB_GPIO_38_INT_STAT_LEN) - 1) << GLB_GPIO_38_INT_STAT_POS) +#define GLB_GPIO_38_INT_STAT_UMSK (~(((1U << GLB_GPIO_38_INT_STAT_LEN) - 1) << GLB_GPIO_38_INT_STAT_POS)) +#define GLB_REG_GPIO_38_INT_MASK GLB_REG_GPIO_38_INT_MASK +#define GLB_REG_GPIO_38_INT_MASK_POS (22U) +#define GLB_REG_GPIO_38_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_38_INT_MASK_MSK (((1U << GLB_REG_GPIO_38_INT_MASK_LEN) - 1) << GLB_REG_GPIO_38_INT_MASK_POS) +#define GLB_REG_GPIO_38_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_38_INT_MASK_LEN) - 1) << GLB_REG_GPIO_38_INT_MASK_POS)) +#define GLB_REG_GPIO_38_O GLB_REG_GPIO_38_O +#define GLB_REG_GPIO_38_O_POS (24U) +#define GLB_REG_GPIO_38_O_LEN (1U) +#define GLB_REG_GPIO_38_O_MSK (((1U << GLB_REG_GPIO_38_O_LEN) - 1) << GLB_REG_GPIO_38_O_POS) +#define GLB_REG_GPIO_38_O_UMSK (~(((1U << GLB_REG_GPIO_38_O_LEN) - 1) << GLB_REG_GPIO_38_O_POS)) +#define GLB_REG_GPIO_38_SET GLB_REG_GPIO_38_SET +#define GLB_REG_GPIO_38_SET_POS (25U) +#define GLB_REG_GPIO_38_SET_LEN (1U) +#define GLB_REG_GPIO_38_SET_MSK (((1U << GLB_REG_GPIO_38_SET_LEN) - 1) << GLB_REG_GPIO_38_SET_POS) +#define GLB_REG_GPIO_38_SET_UMSK (~(((1U << GLB_REG_GPIO_38_SET_LEN) - 1) << GLB_REG_GPIO_38_SET_POS)) +#define GLB_REG_GPIO_38_CLR GLB_REG_GPIO_38_CLR +#define GLB_REG_GPIO_38_CLR_POS (26U) +#define GLB_REG_GPIO_38_CLR_LEN (1U) +#define GLB_REG_GPIO_38_CLR_MSK (((1U << GLB_REG_GPIO_38_CLR_LEN) - 1) << GLB_REG_GPIO_38_CLR_POS) +#define GLB_REG_GPIO_38_CLR_UMSK (~(((1U << GLB_REG_GPIO_38_CLR_LEN) - 1) << GLB_REG_GPIO_38_CLR_POS)) +#define GLB_REG_GPIO_38_I GLB_REG_GPIO_38_I +#define GLB_REG_GPIO_38_I_POS (28U) +#define GLB_REG_GPIO_38_I_LEN (1U) +#define GLB_REG_GPIO_38_I_MSK (((1U << GLB_REG_GPIO_38_I_LEN) - 1) << GLB_REG_GPIO_38_I_POS) +#define GLB_REG_GPIO_38_I_UMSK (~(((1U << GLB_REG_GPIO_38_I_LEN) - 1) << GLB_REG_GPIO_38_I_POS)) +#define GLB_REG_GPIO_38_MODE GLB_REG_GPIO_38_MODE +#define GLB_REG_GPIO_38_MODE_POS (30U) +#define GLB_REG_GPIO_38_MODE_LEN (2U) +#define GLB_REG_GPIO_38_MODE_MSK (((1U << GLB_REG_GPIO_38_MODE_LEN) - 1) << GLB_REG_GPIO_38_MODE_POS) +#define GLB_REG_GPIO_38_MODE_UMSK (~(((1U << GLB_REG_GPIO_38_MODE_LEN) - 1) << GLB_REG_GPIO_38_MODE_POS)) + +/* 0x960 : gpio_cfg39 */ +#define GLB_GPIO_CFG39_OFFSET (0x960) +#define GLB_REG_GPIO_39_IE GLB_REG_GPIO_39_IE +#define GLB_REG_GPIO_39_IE_POS (0U) +#define GLB_REG_GPIO_39_IE_LEN (1U) +#define GLB_REG_GPIO_39_IE_MSK (((1U << GLB_REG_GPIO_39_IE_LEN) - 1) << GLB_REG_GPIO_39_IE_POS) +#define GLB_REG_GPIO_39_IE_UMSK (~(((1U << GLB_REG_GPIO_39_IE_LEN) - 1) << GLB_REG_GPIO_39_IE_POS)) +#define GLB_REG_GPIO_39_SMT GLB_REG_GPIO_39_SMT +#define GLB_REG_GPIO_39_SMT_POS (1U) +#define GLB_REG_GPIO_39_SMT_LEN (1U) +#define GLB_REG_GPIO_39_SMT_MSK (((1U << GLB_REG_GPIO_39_SMT_LEN) - 1) << GLB_REG_GPIO_39_SMT_POS) +#define GLB_REG_GPIO_39_SMT_UMSK (~(((1U << GLB_REG_GPIO_39_SMT_LEN) - 1) << GLB_REG_GPIO_39_SMT_POS)) +#define GLB_REG_GPIO_39_DRV GLB_REG_GPIO_39_DRV +#define GLB_REG_GPIO_39_DRV_POS (2U) +#define GLB_REG_GPIO_39_DRV_LEN (2U) +#define GLB_REG_GPIO_39_DRV_MSK (((1U << GLB_REG_GPIO_39_DRV_LEN) - 1) << GLB_REG_GPIO_39_DRV_POS) +#define GLB_REG_GPIO_39_DRV_UMSK (~(((1U << GLB_REG_GPIO_39_DRV_LEN) - 1) << GLB_REG_GPIO_39_DRV_POS)) +#define GLB_REG_GPIO_39_PU GLB_REG_GPIO_39_PU +#define GLB_REG_GPIO_39_PU_POS (4U) +#define GLB_REG_GPIO_39_PU_LEN (1U) +#define GLB_REG_GPIO_39_PU_MSK (((1U << GLB_REG_GPIO_39_PU_LEN) - 1) << GLB_REG_GPIO_39_PU_POS) +#define GLB_REG_GPIO_39_PU_UMSK (~(((1U << GLB_REG_GPIO_39_PU_LEN) - 1) << GLB_REG_GPIO_39_PU_POS)) +#define GLB_REG_GPIO_39_PD GLB_REG_GPIO_39_PD +#define GLB_REG_GPIO_39_PD_POS (5U) +#define GLB_REG_GPIO_39_PD_LEN (1U) +#define GLB_REG_GPIO_39_PD_MSK (((1U << GLB_REG_GPIO_39_PD_LEN) - 1) << GLB_REG_GPIO_39_PD_POS) +#define GLB_REG_GPIO_39_PD_UMSK (~(((1U << GLB_REG_GPIO_39_PD_LEN) - 1) << GLB_REG_GPIO_39_PD_POS)) +#define GLB_REG_GPIO_39_OE GLB_REG_GPIO_39_OE +#define GLB_REG_GPIO_39_OE_POS (6U) +#define GLB_REG_GPIO_39_OE_LEN (1U) +#define GLB_REG_GPIO_39_OE_MSK (((1U << GLB_REG_GPIO_39_OE_LEN) - 1) << GLB_REG_GPIO_39_OE_POS) +#define GLB_REG_GPIO_39_OE_UMSK (~(((1U << GLB_REG_GPIO_39_OE_LEN) - 1) << GLB_REG_GPIO_39_OE_POS)) +#define GLB_REG_GPIO_39_FUNC_SEL GLB_REG_GPIO_39_FUNC_SEL +#define GLB_REG_GPIO_39_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_39_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_39_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_39_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_39_FUNC_SEL_POS) +#define GLB_REG_GPIO_39_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_39_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_39_FUNC_SEL_POS)) +#define GLB_REG_GPIO_39_INT_MODE_SET GLB_REG_GPIO_39_INT_MODE_SET +#define GLB_REG_GPIO_39_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_39_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_39_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_39_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_39_INT_MODE_SET_POS) +#define GLB_REG_GPIO_39_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_39_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_39_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_39_INT_CLR GLB_REG_GPIO_39_INT_CLR +#define GLB_REG_GPIO_39_INT_CLR_POS (20U) +#define GLB_REG_GPIO_39_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_39_INT_CLR_MSK (((1U << GLB_REG_GPIO_39_INT_CLR_LEN) - 1) << GLB_REG_GPIO_39_INT_CLR_POS) +#define GLB_REG_GPIO_39_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_39_INT_CLR_LEN) - 1) << GLB_REG_GPIO_39_INT_CLR_POS)) +#define GLB_GPIO_39_INT_STAT GLB_GPIO_39_INT_STAT +#define GLB_GPIO_39_INT_STAT_POS (21U) +#define GLB_GPIO_39_INT_STAT_LEN (1U) +#define GLB_GPIO_39_INT_STAT_MSK (((1U << GLB_GPIO_39_INT_STAT_LEN) - 1) << GLB_GPIO_39_INT_STAT_POS) +#define GLB_GPIO_39_INT_STAT_UMSK (~(((1U << GLB_GPIO_39_INT_STAT_LEN) - 1) << GLB_GPIO_39_INT_STAT_POS)) +#define GLB_REG_GPIO_39_INT_MASK GLB_REG_GPIO_39_INT_MASK +#define GLB_REG_GPIO_39_INT_MASK_POS (22U) +#define GLB_REG_GPIO_39_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_39_INT_MASK_MSK (((1U << GLB_REG_GPIO_39_INT_MASK_LEN) - 1) << GLB_REG_GPIO_39_INT_MASK_POS) +#define GLB_REG_GPIO_39_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_39_INT_MASK_LEN) - 1) << GLB_REG_GPIO_39_INT_MASK_POS)) +#define GLB_REG_GPIO_39_O GLB_REG_GPIO_39_O +#define GLB_REG_GPIO_39_O_POS (24U) +#define GLB_REG_GPIO_39_O_LEN (1U) +#define GLB_REG_GPIO_39_O_MSK (((1U << GLB_REG_GPIO_39_O_LEN) - 1) << GLB_REG_GPIO_39_O_POS) +#define GLB_REG_GPIO_39_O_UMSK (~(((1U << GLB_REG_GPIO_39_O_LEN) - 1) << GLB_REG_GPIO_39_O_POS)) +#define GLB_REG_GPIO_39_SET GLB_REG_GPIO_39_SET +#define GLB_REG_GPIO_39_SET_POS (25U) +#define GLB_REG_GPIO_39_SET_LEN (1U) +#define GLB_REG_GPIO_39_SET_MSK (((1U << GLB_REG_GPIO_39_SET_LEN) - 1) << GLB_REG_GPIO_39_SET_POS) +#define GLB_REG_GPIO_39_SET_UMSK (~(((1U << GLB_REG_GPIO_39_SET_LEN) - 1) << GLB_REG_GPIO_39_SET_POS)) +#define GLB_REG_GPIO_39_CLR GLB_REG_GPIO_39_CLR +#define GLB_REG_GPIO_39_CLR_POS (26U) +#define GLB_REG_GPIO_39_CLR_LEN (1U) +#define GLB_REG_GPIO_39_CLR_MSK (((1U << GLB_REG_GPIO_39_CLR_LEN) - 1) << GLB_REG_GPIO_39_CLR_POS) +#define GLB_REG_GPIO_39_CLR_UMSK (~(((1U << GLB_REG_GPIO_39_CLR_LEN) - 1) << GLB_REG_GPIO_39_CLR_POS)) +#define GLB_REG_GPIO_39_I GLB_REG_GPIO_39_I +#define GLB_REG_GPIO_39_I_POS (28U) +#define GLB_REG_GPIO_39_I_LEN (1U) +#define GLB_REG_GPIO_39_I_MSK (((1U << GLB_REG_GPIO_39_I_LEN) - 1) << GLB_REG_GPIO_39_I_POS) +#define GLB_REG_GPIO_39_I_UMSK (~(((1U << GLB_REG_GPIO_39_I_LEN) - 1) << GLB_REG_GPIO_39_I_POS)) +#define GLB_REG_GPIO_39_MODE GLB_REG_GPIO_39_MODE +#define GLB_REG_GPIO_39_MODE_POS (30U) +#define GLB_REG_GPIO_39_MODE_LEN (2U) +#define GLB_REG_GPIO_39_MODE_MSK (((1U << GLB_REG_GPIO_39_MODE_LEN) - 1) << GLB_REG_GPIO_39_MODE_POS) +#define GLB_REG_GPIO_39_MODE_UMSK (~(((1U << GLB_REG_GPIO_39_MODE_LEN) - 1) << GLB_REG_GPIO_39_MODE_POS)) + +/* 0x964 : gpio_cfg40 */ +#define GLB_GPIO_CFG40_OFFSET (0x964) +#define GLB_REG_GPIO_40_IE GLB_REG_GPIO_40_IE +#define GLB_REG_GPIO_40_IE_POS (0U) +#define GLB_REG_GPIO_40_IE_LEN (1U) +#define GLB_REG_GPIO_40_IE_MSK (((1U << GLB_REG_GPIO_40_IE_LEN) - 1) << GLB_REG_GPIO_40_IE_POS) +#define GLB_REG_GPIO_40_IE_UMSK (~(((1U << GLB_REG_GPIO_40_IE_LEN) - 1) << GLB_REG_GPIO_40_IE_POS)) +#define GLB_REG_GPIO_40_SMT GLB_REG_GPIO_40_SMT +#define GLB_REG_GPIO_40_SMT_POS (1U) +#define GLB_REG_GPIO_40_SMT_LEN (1U) +#define GLB_REG_GPIO_40_SMT_MSK (((1U << GLB_REG_GPIO_40_SMT_LEN) - 1) << GLB_REG_GPIO_40_SMT_POS) +#define GLB_REG_GPIO_40_SMT_UMSK (~(((1U << GLB_REG_GPIO_40_SMT_LEN) - 1) << GLB_REG_GPIO_40_SMT_POS)) +#define GLB_REG_GPIO_40_DRV GLB_REG_GPIO_40_DRV +#define GLB_REG_GPIO_40_DRV_POS (2U) +#define GLB_REG_GPIO_40_DRV_LEN (2U) +#define GLB_REG_GPIO_40_DRV_MSK (((1U << GLB_REG_GPIO_40_DRV_LEN) - 1) << GLB_REG_GPIO_40_DRV_POS) +#define GLB_REG_GPIO_40_DRV_UMSK (~(((1U << GLB_REG_GPIO_40_DRV_LEN) - 1) << GLB_REG_GPIO_40_DRV_POS)) +#define GLB_REG_GPIO_40_PU GLB_REG_GPIO_40_PU +#define GLB_REG_GPIO_40_PU_POS (4U) +#define GLB_REG_GPIO_40_PU_LEN (1U) +#define GLB_REG_GPIO_40_PU_MSK (((1U << GLB_REG_GPIO_40_PU_LEN) - 1) << GLB_REG_GPIO_40_PU_POS) +#define GLB_REG_GPIO_40_PU_UMSK (~(((1U << GLB_REG_GPIO_40_PU_LEN) - 1) << GLB_REG_GPIO_40_PU_POS)) +#define GLB_REG_GPIO_40_PD GLB_REG_GPIO_40_PD +#define GLB_REG_GPIO_40_PD_POS (5U) +#define GLB_REG_GPIO_40_PD_LEN (1U) +#define GLB_REG_GPIO_40_PD_MSK (((1U << GLB_REG_GPIO_40_PD_LEN) - 1) << GLB_REG_GPIO_40_PD_POS) +#define GLB_REG_GPIO_40_PD_UMSK (~(((1U << GLB_REG_GPIO_40_PD_LEN) - 1) << GLB_REG_GPIO_40_PD_POS)) +#define GLB_REG_GPIO_40_OE GLB_REG_GPIO_40_OE +#define GLB_REG_GPIO_40_OE_POS (6U) +#define GLB_REG_GPIO_40_OE_LEN (1U) +#define GLB_REG_GPIO_40_OE_MSK (((1U << GLB_REG_GPIO_40_OE_LEN) - 1) << GLB_REG_GPIO_40_OE_POS) +#define GLB_REG_GPIO_40_OE_UMSK (~(((1U << GLB_REG_GPIO_40_OE_LEN) - 1) << GLB_REG_GPIO_40_OE_POS)) +#define GLB_REG_GPIO_40_FUNC_SEL GLB_REG_GPIO_40_FUNC_SEL +#define GLB_REG_GPIO_40_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_40_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_40_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_40_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_40_FUNC_SEL_POS) +#define GLB_REG_GPIO_40_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_40_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_40_FUNC_SEL_POS)) +#define GLB_REG_GPIO_40_INT_MODE_SET GLB_REG_GPIO_40_INT_MODE_SET +#define GLB_REG_GPIO_40_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_40_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_40_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_40_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_40_INT_MODE_SET_POS) +#define GLB_REG_GPIO_40_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_40_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_40_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_40_INT_CLR GLB_REG_GPIO_40_INT_CLR +#define GLB_REG_GPIO_40_INT_CLR_POS (20U) +#define GLB_REG_GPIO_40_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_40_INT_CLR_MSK (((1U << GLB_REG_GPIO_40_INT_CLR_LEN) - 1) << GLB_REG_GPIO_40_INT_CLR_POS) +#define GLB_REG_GPIO_40_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_40_INT_CLR_LEN) - 1) << GLB_REG_GPIO_40_INT_CLR_POS)) +#define GLB_GPIO_40_INT_STAT GLB_GPIO_40_INT_STAT +#define GLB_GPIO_40_INT_STAT_POS (21U) +#define GLB_GPIO_40_INT_STAT_LEN (1U) +#define GLB_GPIO_40_INT_STAT_MSK (((1U << GLB_GPIO_40_INT_STAT_LEN) - 1) << GLB_GPIO_40_INT_STAT_POS) +#define GLB_GPIO_40_INT_STAT_UMSK (~(((1U << GLB_GPIO_40_INT_STAT_LEN) - 1) << GLB_GPIO_40_INT_STAT_POS)) +#define GLB_REG_GPIO_40_INT_MASK GLB_REG_GPIO_40_INT_MASK +#define GLB_REG_GPIO_40_INT_MASK_POS (22U) +#define GLB_REG_GPIO_40_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_40_INT_MASK_MSK (((1U << GLB_REG_GPIO_40_INT_MASK_LEN) - 1) << GLB_REG_GPIO_40_INT_MASK_POS) +#define GLB_REG_GPIO_40_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_40_INT_MASK_LEN) - 1) << GLB_REG_GPIO_40_INT_MASK_POS)) +#define GLB_REG_GPIO_40_O GLB_REG_GPIO_40_O +#define GLB_REG_GPIO_40_O_POS (24U) +#define GLB_REG_GPIO_40_O_LEN (1U) +#define GLB_REG_GPIO_40_O_MSK (((1U << GLB_REG_GPIO_40_O_LEN) - 1) << GLB_REG_GPIO_40_O_POS) +#define GLB_REG_GPIO_40_O_UMSK (~(((1U << GLB_REG_GPIO_40_O_LEN) - 1) << GLB_REG_GPIO_40_O_POS)) +#define GLB_REG_GPIO_40_SET GLB_REG_GPIO_40_SET +#define GLB_REG_GPIO_40_SET_POS (25U) +#define GLB_REG_GPIO_40_SET_LEN (1U) +#define GLB_REG_GPIO_40_SET_MSK (((1U << GLB_REG_GPIO_40_SET_LEN) - 1) << GLB_REG_GPIO_40_SET_POS) +#define GLB_REG_GPIO_40_SET_UMSK (~(((1U << GLB_REG_GPIO_40_SET_LEN) - 1) << GLB_REG_GPIO_40_SET_POS)) +#define GLB_REG_GPIO_40_CLR GLB_REG_GPIO_40_CLR +#define GLB_REG_GPIO_40_CLR_POS (26U) +#define GLB_REG_GPIO_40_CLR_LEN (1U) +#define GLB_REG_GPIO_40_CLR_MSK (((1U << GLB_REG_GPIO_40_CLR_LEN) - 1) << GLB_REG_GPIO_40_CLR_POS) +#define GLB_REG_GPIO_40_CLR_UMSK (~(((1U << GLB_REG_GPIO_40_CLR_LEN) - 1) << GLB_REG_GPIO_40_CLR_POS)) +#define GLB_REG_GPIO_40_I GLB_REG_GPIO_40_I +#define GLB_REG_GPIO_40_I_POS (28U) +#define GLB_REG_GPIO_40_I_LEN (1U) +#define GLB_REG_GPIO_40_I_MSK (((1U << GLB_REG_GPIO_40_I_LEN) - 1) << GLB_REG_GPIO_40_I_POS) +#define GLB_REG_GPIO_40_I_UMSK (~(((1U << GLB_REG_GPIO_40_I_LEN) - 1) << GLB_REG_GPIO_40_I_POS)) +#define GLB_REG_GPIO_40_MODE GLB_REG_GPIO_40_MODE +#define GLB_REG_GPIO_40_MODE_POS (30U) +#define GLB_REG_GPIO_40_MODE_LEN (2U) +#define GLB_REG_GPIO_40_MODE_MSK (((1U << GLB_REG_GPIO_40_MODE_LEN) - 1) << GLB_REG_GPIO_40_MODE_POS) +#define GLB_REG_GPIO_40_MODE_UMSK (~(((1U << GLB_REG_GPIO_40_MODE_LEN) - 1) << GLB_REG_GPIO_40_MODE_POS)) + +/* 0x968 : gpio_cfg41 */ +#define GLB_GPIO_CFG41_OFFSET (0x968) +#define GLB_REG_GPIO_41_IE GLB_REG_GPIO_41_IE +#define GLB_REG_GPIO_41_IE_POS (0U) +#define GLB_REG_GPIO_41_IE_LEN (1U) +#define GLB_REG_GPIO_41_IE_MSK (((1U << GLB_REG_GPIO_41_IE_LEN) - 1) << GLB_REG_GPIO_41_IE_POS) +#define GLB_REG_GPIO_41_IE_UMSK (~(((1U << GLB_REG_GPIO_41_IE_LEN) - 1) << GLB_REG_GPIO_41_IE_POS)) +#define GLB_REG_GPIO_41_SMT GLB_REG_GPIO_41_SMT +#define GLB_REG_GPIO_41_SMT_POS (1U) +#define GLB_REG_GPIO_41_SMT_LEN (1U) +#define GLB_REG_GPIO_41_SMT_MSK (((1U << GLB_REG_GPIO_41_SMT_LEN) - 1) << GLB_REG_GPIO_41_SMT_POS) +#define GLB_REG_GPIO_41_SMT_UMSK (~(((1U << GLB_REG_GPIO_41_SMT_LEN) - 1) << GLB_REG_GPIO_41_SMT_POS)) +#define GLB_REG_GPIO_41_DRV GLB_REG_GPIO_41_DRV +#define GLB_REG_GPIO_41_DRV_POS (2U) +#define GLB_REG_GPIO_41_DRV_LEN (2U) +#define GLB_REG_GPIO_41_DRV_MSK (((1U << GLB_REG_GPIO_41_DRV_LEN) - 1) << GLB_REG_GPIO_41_DRV_POS) +#define GLB_REG_GPIO_41_DRV_UMSK (~(((1U << GLB_REG_GPIO_41_DRV_LEN) - 1) << GLB_REG_GPIO_41_DRV_POS)) +#define GLB_REG_GPIO_41_PU GLB_REG_GPIO_41_PU +#define GLB_REG_GPIO_41_PU_POS (4U) +#define GLB_REG_GPIO_41_PU_LEN (1U) +#define GLB_REG_GPIO_41_PU_MSK (((1U << GLB_REG_GPIO_41_PU_LEN) - 1) << GLB_REG_GPIO_41_PU_POS) +#define GLB_REG_GPIO_41_PU_UMSK (~(((1U << GLB_REG_GPIO_41_PU_LEN) - 1) << GLB_REG_GPIO_41_PU_POS)) +#define GLB_REG_GPIO_41_PD GLB_REG_GPIO_41_PD +#define GLB_REG_GPIO_41_PD_POS (5U) +#define GLB_REG_GPIO_41_PD_LEN (1U) +#define GLB_REG_GPIO_41_PD_MSK (((1U << GLB_REG_GPIO_41_PD_LEN) - 1) << GLB_REG_GPIO_41_PD_POS) +#define GLB_REG_GPIO_41_PD_UMSK (~(((1U << GLB_REG_GPIO_41_PD_LEN) - 1) << GLB_REG_GPIO_41_PD_POS)) +#define GLB_REG_GPIO_41_OE GLB_REG_GPIO_41_OE +#define GLB_REG_GPIO_41_OE_POS (6U) +#define GLB_REG_GPIO_41_OE_LEN (1U) +#define GLB_REG_GPIO_41_OE_MSK (((1U << GLB_REG_GPIO_41_OE_LEN) - 1) << GLB_REG_GPIO_41_OE_POS) +#define GLB_REG_GPIO_41_OE_UMSK (~(((1U << GLB_REG_GPIO_41_OE_LEN) - 1) << GLB_REG_GPIO_41_OE_POS)) +#define GLB_REG_GPIO_41_FUNC_SEL GLB_REG_GPIO_41_FUNC_SEL +#define GLB_REG_GPIO_41_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_41_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_41_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_41_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_41_FUNC_SEL_POS) +#define GLB_REG_GPIO_41_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_41_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_41_FUNC_SEL_POS)) +#define GLB_REG_GPIO_41_INT_MODE_SET GLB_REG_GPIO_41_INT_MODE_SET +#define GLB_REG_GPIO_41_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_41_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_41_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_41_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_41_INT_MODE_SET_POS) +#define GLB_REG_GPIO_41_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_41_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_41_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_41_INT_CLR GLB_REG_GPIO_41_INT_CLR +#define GLB_REG_GPIO_41_INT_CLR_POS (20U) +#define GLB_REG_GPIO_41_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_41_INT_CLR_MSK (((1U << GLB_REG_GPIO_41_INT_CLR_LEN) - 1) << GLB_REG_GPIO_41_INT_CLR_POS) +#define GLB_REG_GPIO_41_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_41_INT_CLR_LEN) - 1) << GLB_REG_GPIO_41_INT_CLR_POS)) +#define GLB_GPIO_41_INT_STAT GLB_GPIO_41_INT_STAT +#define GLB_GPIO_41_INT_STAT_POS (21U) +#define GLB_GPIO_41_INT_STAT_LEN (1U) +#define GLB_GPIO_41_INT_STAT_MSK (((1U << GLB_GPIO_41_INT_STAT_LEN) - 1) << GLB_GPIO_41_INT_STAT_POS) +#define GLB_GPIO_41_INT_STAT_UMSK (~(((1U << GLB_GPIO_41_INT_STAT_LEN) - 1) << GLB_GPIO_41_INT_STAT_POS)) +#define GLB_REG_GPIO_41_INT_MASK GLB_REG_GPIO_41_INT_MASK +#define GLB_REG_GPIO_41_INT_MASK_POS (22U) +#define GLB_REG_GPIO_41_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_41_INT_MASK_MSK (((1U << GLB_REG_GPIO_41_INT_MASK_LEN) - 1) << GLB_REG_GPIO_41_INT_MASK_POS) +#define GLB_REG_GPIO_41_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_41_INT_MASK_LEN) - 1) << GLB_REG_GPIO_41_INT_MASK_POS)) +#define GLB_REG_GPIO_41_O GLB_REG_GPIO_41_O +#define GLB_REG_GPIO_41_O_POS (24U) +#define GLB_REG_GPIO_41_O_LEN (1U) +#define GLB_REG_GPIO_41_O_MSK (((1U << GLB_REG_GPIO_41_O_LEN) - 1) << GLB_REG_GPIO_41_O_POS) +#define GLB_REG_GPIO_41_O_UMSK (~(((1U << GLB_REG_GPIO_41_O_LEN) - 1) << GLB_REG_GPIO_41_O_POS)) +#define GLB_REG_GPIO_41_SET GLB_REG_GPIO_41_SET +#define GLB_REG_GPIO_41_SET_POS (25U) +#define GLB_REG_GPIO_41_SET_LEN (1U) +#define GLB_REG_GPIO_41_SET_MSK (((1U << GLB_REG_GPIO_41_SET_LEN) - 1) << GLB_REG_GPIO_41_SET_POS) +#define GLB_REG_GPIO_41_SET_UMSK (~(((1U << GLB_REG_GPIO_41_SET_LEN) - 1) << GLB_REG_GPIO_41_SET_POS)) +#define GLB_REG_GPIO_41_CLR GLB_REG_GPIO_41_CLR +#define GLB_REG_GPIO_41_CLR_POS (26U) +#define GLB_REG_GPIO_41_CLR_LEN (1U) +#define GLB_REG_GPIO_41_CLR_MSK (((1U << GLB_REG_GPIO_41_CLR_LEN) - 1) << GLB_REG_GPIO_41_CLR_POS) +#define GLB_REG_GPIO_41_CLR_UMSK (~(((1U << GLB_REG_GPIO_41_CLR_LEN) - 1) << GLB_REG_GPIO_41_CLR_POS)) +#define GLB_REG_GPIO_41_I GLB_REG_GPIO_41_I +#define GLB_REG_GPIO_41_I_POS (28U) +#define GLB_REG_GPIO_41_I_LEN (1U) +#define GLB_REG_GPIO_41_I_MSK (((1U << GLB_REG_GPIO_41_I_LEN) - 1) << GLB_REG_GPIO_41_I_POS) +#define GLB_REG_GPIO_41_I_UMSK (~(((1U << GLB_REG_GPIO_41_I_LEN) - 1) << GLB_REG_GPIO_41_I_POS)) +#define GLB_REG_GPIO_41_MODE GLB_REG_GPIO_41_MODE +#define GLB_REG_GPIO_41_MODE_POS (30U) +#define GLB_REG_GPIO_41_MODE_LEN (2U) +#define GLB_REG_GPIO_41_MODE_MSK (((1U << GLB_REG_GPIO_41_MODE_LEN) - 1) << GLB_REG_GPIO_41_MODE_POS) +#define GLB_REG_GPIO_41_MODE_UMSK (~(((1U << GLB_REG_GPIO_41_MODE_LEN) - 1) << GLB_REG_GPIO_41_MODE_POS)) + +/* 0x96C : gpio_cfg42 */ +#define GLB_GPIO_CFG42_OFFSET (0x96C) +#define GLB_REG_GPIO_42_IE GLB_REG_GPIO_42_IE +#define GLB_REG_GPIO_42_IE_POS (0U) +#define GLB_REG_GPIO_42_IE_LEN (1U) +#define GLB_REG_GPIO_42_IE_MSK (((1U << GLB_REG_GPIO_42_IE_LEN) - 1) << GLB_REG_GPIO_42_IE_POS) +#define GLB_REG_GPIO_42_IE_UMSK (~(((1U << GLB_REG_GPIO_42_IE_LEN) - 1) << GLB_REG_GPIO_42_IE_POS)) +#define GLB_REG_GPIO_42_SMT GLB_REG_GPIO_42_SMT +#define GLB_REG_GPIO_42_SMT_POS (1U) +#define GLB_REG_GPIO_42_SMT_LEN (1U) +#define GLB_REG_GPIO_42_SMT_MSK (((1U << GLB_REG_GPIO_42_SMT_LEN) - 1) << GLB_REG_GPIO_42_SMT_POS) +#define GLB_REG_GPIO_42_SMT_UMSK (~(((1U << GLB_REG_GPIO_42_SMT_LEN) - 1) << GLB_REG_GPIO_42_SMT_POS)) +#define GLB_REG_GPIO_42_DRV GLB_REG_GPIO_42_DRV +#define GLB_REG_GPIO_42_DRV_POS (2U) +#define GLB_REG_GPIO_42_DRV_LEN (2U) +#define GLB_REG_GPIO_42_DRV_MSK (((1U << GLB_REG_GPIO_42_DRV_LEN) - 1) << GLB_REG_GPIO_42_DRV_POS) +#define GLB_REG_GPIO_42_DRV_UMSK (~(((1U << GLB_REG_GPIO_42_DRV_LEN) - 1) << GLB_REG_GPIO_42_DRV_POS)) +#define GLB_REG_GPIO_42_PU GLB_REG_GPIO_42_PU +#define GLB_REG_GPIO_42_PU_POS (4U) +#define GLB_REG_GPIO_42_PU_LEN (1U) +#define GLB_REG_GPIO_42_PU_MSK (((1U << GLB_REG_GPIO_42_PU_LEN) - 1) << GLB_REG_GPIO_42_PU_POS) +#define GLB_REG_GPIO_42_PU_UMSK (~(((1U << GLB_REG_GPIO_42_PU_LEN) - 1) << GLB_REG_GPIO_42_PU_POS)) +#define GLB_REG_GPIO_42_PD GLB_REG_GPIO_42_PD +#define GLB_REG_GPIO_42_PD_POS (5U) +#define GLB_REG_GPIO_42_PD_LEN (1U) +#define GLB_REG_GPIO_42_PD_MSK (((1U << GLB_REG_GPIO_42_PD_LEN) - 1) << GLB_REG_GPIO_42_PD_POS) +#define GLB_REG_GPIO_42_PD_UMSK (~(((1U << GLB_REG_GPIO_42_PD_LEN) - 1) << GLB_REG_GPIO_42_PD_POS)) +#define GLB_REG_GPIO_42_OE GLB_REG_GPIO_42_OE +#define GLB_REG_GPIO_42_OE_POS (6U) +#define GLB_REG_GPIO_42_OE_LEN (1U) +#define GLB_REG_GPIO_42_OE_MSK (((1U << GLB_REG_GPIO_42_OE_LEN) - 1) << GLB_REG_GPIO_42_OE_POS) +#define GLB_REG_GPIO_42_OE_UMSK (~(((1U << GLB_REG_GPIO_42_OE_LEN) - 1) << GLB_REG_GPIO_42_OE_POS)) +#define GLB_REG_GPIO_42_FUNC_SEL GLB_REG_GPIO_42_FUNC_SEL +#define GLB_REG_GPIO_42_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_42_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_42_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_42_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_42_FUNC_SEL_POS) +#define GLB_REG_GPIO_42_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_42_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_42_FUNC_SEL_POS)) +#define GLB_REG_GPIO_42_INT_MODE_SET GLB_REG_GPIO_42_INT_MODE_SET +#define GLB_REG_GPIO_42_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_42_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_42_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_42_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_42_INT_MODE_SET_POS) +#define GLB_REG_GPIO_42_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_42_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_42_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_42_INT_CLR GLB_REG_GPIO_42_INT_CLR +#define GLB_REG_GPIO_42_INT_CLR_POS (20U) +#define GLB_REG_GPIO_42_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_42_INT_CLR_MSK (((1U << GLB_REG_GPIO_42_INT_CLR_LEN) - 1) << GLB_REG_GPIO_42_INT_CLR_POS) +#define GLB_REG_GPIO_42_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_42_INT_CLR_LEN) - 1) << GLB_REG_GPIO_42_INT_CLR_POS)) +#define GLB_GPIO_42_INT_STAT GLB_GPIO_42_INT_STAT +#define GLB_GPIO_42_INT_STAT_POS (21U) +#define GLB_GPIO_42_INT_STAT_LEN (1U) +#define GLB_GPIO_42_INT_STAT_MSK (((1U << GLB_GPIO_42_INT_STAT_LEN) - 1) << GLB_GPIO_42_INT_STAT_POS) +#define GLB_GPIO_42_INT_STAT_UMSK (~(((1U << GLB_GPIO_42_INT_STAT_LEN) - 1) << GLB_GPIO_42_INT_STAT_POS)) +#define GLB_REG_GPIO_42_INT_MASK GLB_REG_GPIO_42_INT_MASK +#define GLB_REG_GPIO_42_INT_MASK_POS (22U) +#define GLB_REG_GPIO_42_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_42_INT_MASK_MSK (((1U << GLB_REG_GPIO_42_INT_MASK_LEN) - 1) << GLB_REG_GPIO_42_INT_MASK_POS) +#define GLB_REG_GPIO_42_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_42_INT_MASK_LEN) - 1) << GLB_REG_GPIO_42_INT_MASK_POS)) +#define GLB_REG_GPIO_42_O GLB_REG_GPIO_42_O +#define GLB_REG_GPIO_42_O_POS (24U) +#define GLB_REG_GPIO_42_O_LEN (1U) +#define GLB_REG_GPIO_42_O_MSK (((1U << GLB_REG_GPIO_42_O_LEN) - 1) << GLB_REG_GPIO_42_O_POS) +#define GLB_REG_GPIO_42_O_UMSK (~(((1U << GLB_REG_GPIO_42_O_LEN) - 1) << GLB_REG_GPIO_42_O_POS)) +#define GLB_REG_GPIO_42_SET GLB_REG_GPIO_42_SET +#define GLB_REG_GPIO_42_SET_POS (25U) +#define GLB_REG_GPIO_42_SET_LEN (1U) +#define GLB_REG_GPIO_42_SET_MSK (((1U << GLB_REG_GPIO_42_SET_LEN) - 1) << GLB_REG_GPIO_42_SET_POS) +#define GLB_REG_GPIO_42_SET_UMSK (~(((1U << GLB_REG_GPIO_42_SET_LEN) - 1) << GLB_REG_GPIO_42_SET_POS)) +#define GLB_REG_GPIO_42_CLR GLB_REG_GPIO_42_CLR +#define GLB_REG_GPIO_42_CLR_POS (26U) +#define GLB_REG_GPIO_42_CLR_LEN (1U) +#define GLB_REG_GPIO_42_CLR_MSK (((1U << GLB_REG_GPIO_42_CLR_LEN) - 1) << GLB_REG_GPIO_42_CLR_POS) +#define GLB_REG_GPIO_42_CLR_UMSK (~(((1U << GLB_REG_GPIO_42_CLR_LEN) - 1) << GLB_REG_GPIO_42_CLR_POS)) +#define GLB_REG_GPIO_42_I GLB_REG_GPIO_42_I +#define GLB_REG_GPIO_42_I_POS (28U) +#define GLB_REG_GPIO_42_I_LEN (1U) +#define GLB_REG_GPIO_42_I_MSK (((1U << GLB_REG_GPIO_42_I_LEN) - 1) << GLB_REG_GPIO_42_I_POS) +#define GLB_REG_GPIO_42_I_UMSK (~(((1U << GLB_REG_GPIO_42_I_LEN) - 1) << GLB_REG_GPIO_42_I_POS)) +#define GLB_REG_GPIO_42_MODE GLB_REG_GPIO_42_MODE +#define GLB_REG_GPIO_42_MODE_POS (30U) +#define GLB_REG_GPIO_42_MODE_LEN (2U) +#define GLB_REG_GPIO_42_MODE_MSK (((1U << GLB_REG_GPIO_42_MODE_LEN) - 1) << GLB_REG_GPIO_42_MODE_POS) +#define GLB_REG_GPIO_42_MODE_UMSK (~(((1U << GLB_REG_GPIO_42_MODE_LEN) - 1) << GLB_REG_GPIO_42_MODE_POS)) + +/* 0x970 : gpio_cfg43 */ +#define GLB_GPIO_CFG43_OFFSET (0x970) +#define GLB_REG_GPIO_43_IE GLB_REG_GPIO_43_IE +#define GLB_REG_GPIO_43_IE_POS (0U) +#define GLB_REG_GPIO_43_IE_LEN (1U) +#define GLB_REG_GPIO_43_IE_MSK (((1U << GLB_REG_GPIO_43_IE_LEN) - 1) << GLB_REG_GPIO_43_IE_POS) +#define GLB_REG_GPIO_43_IE_UMSK (~(((1U << GLB_REG_GPIO_43_IE_LEN) - 1) << GLB_REG_GPIO_43_IE_POS)) +#define GLB_REG_GPIO_43_SMT GLB_REG_GPIO_43_SMT +#define GLB_REG_GPIO_43_SMT_POS (1U) +#define GLB_REG_GPIO_43_SMT_LEN (1U) +#define GLB_REG_GPIO_43_SMT_MSK (((1U << GLB_REG_GPIO_43_SMT_LEN) - 1) << GLB_REG_GPIO_43_SMT_POS) +#define GLB_REG_GPIO_43_SMT_UMSK (~(((1U << GLB_REG_GPIO_43_SMT_LEN) - 1) << GLB_REG_GPIO_43_SMT_POS)) +#define GLB_REG_GPIO_43_DRV GLB_REG_GPIO_43_DRV +#define GLB_REG_GPIO_43_DRV_POS (2U) +#define GLB_REG_GPIO_43_DRV_LEN (2U) +#define GLB_REG_GPIO_43_DRV_MSK (((1U << GLB_REG_GPIO_43_DRV_LEN) - 1) << GLB_REG_GPIO_43_DRV_POS) +#define GLB_REG_GPIO_43_DRV_UMSK (~(((1U << GLB_REG_GPIO_43_DRV_LEN) - 1) << GLB_REG_GPIO_43_DRV_POS)) +#define GLB_REG_GPIO_43_PU GLB_REG_GPIO_43_PU +#define GLB_REG_GPIO_43_PU_POS (4U) +#define GLB_REG_GPIO_43_PU_LEN (1U) +#define GLB_REG_GPIO_43_PU_MSK (((1U << GLB_REG_GPIO_43_PU_LEN) - 1) << GLB_REG_GPIO_43_PU_POS) +#define GLB_REG_GPIO_43_PU_UMSK (~(((1U << GLB_REG_GPIO_43_PU_LEN) - 1) << GLB_REG_GPIO_43_PU_POS)) +#define GLB_REG_GPIO_43_PD GLB_REG_GPIO_43_PD +#define GLB_REG_GPIO_43_PD_POS (5U) +#define GLB_REG_GPIO_43_PD_LEN (1U) +#define GLB_REG_GPIO_43_PD_MSK (((1U << GLB_REG_GPIO_43_PD_LEN) - 1) << GLB_REG_GPIO_43_PD_POS) +#define GLB_REG_GPIO_43_PD_UMSK (~(((1U << GLB_REG_GPIO_43_PD_LEN) - 1) << GLB_REG_GPIO_43_PD_POS)) +#define GLB_REG_GPIO_43_OE GLB_REG_GPIO_43_OE +#define GLB_REG_GPIO_43_OE_POS (6U) +#define GLB_REG_GPIO_43_OE_LEN (1U) +#define GLB_REG_GPIO_43_OE_MSK (((1U << GLB_REG_GPIO_43_OE_LEN) - 1) << GLB_REG_GPIO_43_OE_POS) +#define GLB_REG_GPIO_43_OE_UMSK (~(((1U << GLB_REG_GPIO_43_OE_LEN) - 1) << GLB_REG_GPIO_43_OE_POS)) +#define GLB_REG_GPIO_43_FUNC_SEL GLB_REG_GPIO_43_FUNC_SEL +#define GLB_REG_GPIO_43_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_43_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_43_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_43_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_43_FUNC_SEL_POS) +#define GLB_REG_GPIO_43_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_43_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_43_FUNC_SEL_POS)) +#define GLB_REG_GPIO_43_INT_MODE_SET GLB_REG_GPIO_43_INT_MODE_SET +#define GLB_REG_GPIO_43_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_43_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_43_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_43_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_43_INT_MODE_SET_POS) +#define GLB_REG_GPIO_43_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_43_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_43_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_43_INT_CLR GLB_REG_GPIO_43_INT_CLR +#define GLB_REG_GPIO_43_INT_CLR_POS (20U) +#define GLB_REG_GPIO_43_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_43_INT_CLR_MSK (((1U << GLB_REG_GPIO_43_INT_CLR_LEN) - 1) << GLB_REG_GPIO_43_INT_CLR_POS) +#define GLB_REG_GPIO_43_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_43_INT_CLR_LEN) - 1) << GLB_REG_GPIO_43_INT_CLR_POS)) +#define GLB_GPIO_43_INT_STAT GLB_GPIO_43_INT_STAT +#define GLB_GPIO_43_INT_STAT_POS (21U) +#define GLB_GPIO_43_INT_STAT_LEN (1U) +#define GLB_GPIO_43_INT_STAT_MSK (((1U << GLB_GPIO_43_INT_STAT_LEN) - 1) << GLB_GPIO_43_INT_STAT_POS) +#define GLB_GPIO_43_INT_STAT_UMSK (~(((1U << GLB_GPIO_43_INT_STAT_LEN) - 1) << GLB_GPIO_43_INT_STAT_POS)) +#define GLB_REG_GPIO_43_INT_MASK GLB_REG_GPIO_43_INT_MASK +#define GLB_REG_GPIO_43_INT_MASK_POS (22U) +#define GLB_REG_GPIO_43_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_43_INT_MASK_MSK (((1U << GLB_REG_GPIO_43_INT_MASK_LEN) - 1) << GLB_REG_GPIO_43_INT_MASK_POS) +#define GLB_REG_GPIO_43_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_43_INT_MASK_LEN) - 1) << GLB_REG_GPIO_43_INT_MASK_POS)) +#define GLB_REG_GPIO_43_O GLB_REG_GPIO_43_O +#define GLB_REG_GPIO_43_O_POS (24U) +#define GLB_REG_GPIO_43_O_LEN (1U) +#define GLB_REG_GPIO_43_O_MSK (((1U << GLB_REG_GPIO_43_O_LEN) - 1) << GLB_REG_GPIO_43_O_POS) +#define GLB_REG_GPIO_43_O_UMSK (~(((1U << GLB_REG_GPIO_43_O_LEN) - 1) << GLB_REG_GPIO_43_O_POS)) +#define GLB_REG_GPIO_43_SET GLB_REG_GPIO_43_SET +#define GLB_REG_GPIO_43_SET_POS (25U) +#define GLB_REG_GPIO_43_SET_LEN (1U) +#define GLB_REG_GPIO_43_SET_MSK (((1U << GLB_REG_GPIO_43_SET_LEN) - 1) << GLB_REG_GPIO_43_SET_POS) +#define GLB_REG_GPIO_43_SET_UMSK (~(((1U << GLB_REG_GPIO_43_SET_LEN) - 1) << GLB_REG_GPIO_43_SET_POS)) +#define GLB_REG_GPIO_43_CLR GLB_REG_GPIO_43_CLR +#define GLB_REG_GPIO_43_CLR_POS (26U) +#define GLB_REG_GPIO_43_CLR_LEN (1U) +#define GLB_REG_GPIO_43_CLR_MSK (((1U << GLB_REG_GPIO_43_CLR_LEN) - 1) << GLB_REG_GPIO_43_CLR_POS) +#define GLB_REG_GPIO_43_CLR_UMSK (~(((1U << GLB_REG_GPIO_43_CLR_LEN) - 1) << GLB_REG_GPIO_43_CLR_POS)) +#define GLB_REG_GPIO_43_I GLB_REG_GPIO_43_I +#define GLB_REG_GPIO_43_I_POS (28U) +#define GLB_REG_GPIO_43_I_LEN (1U) +#define GLB_REG_GPIO_43_I_MSK (((1U << GLB_REG_GPIO_43_I_LEN) - 1) << GLB_REG_GPIO_43_I_POS) +#define GLB_REG_GPIO_43_I_UMSK (~(((1U << GLB_REG_GPIO_43_I_LEN) - 1) << GLB_REG_GPIO_43_I_POS)) +#define GLB_REG_GPIO_43_MODE GLB_REG_GPIO_43_MODE +#define GLB_REG_GPIO_43_MODE_POS (30U) +#define GLB_REG_GPIO_43_MODE_LEN (2U) +#define GLB_REG_GPIO_43_MODE_MSK (((1U << GLB_REG_GPIO_43_MODE_LEN) - 1) << GLB_REG_GPIO_43_MODE_POS) +#define GLB_REG_GPIO_43_MODE_UMSK (~(((1U << GLB_REG_GPIO_43_MODE_LEN) - 1) << GLB_REG_GPIO_43_MODE_POS)) + +/* 0x974 : gpio_cfg44 */ +#define GLB_GPIO_CFG44_OFFSET (0x974) +#define GLB_REG_GPIO_44_IE GLB_REG_GPIO_44_IE +#define GLB_REG_GPIO_44_IE_POS (0U) +#define GLB_REG_GPIO_44_IE_LEN (1U) +#define GLB_REG_GPIO_44_IE_MSK (((1U << GLB_REG_GPIO_44_IE_LEN) - 1) << GLB_REG_GPIO_44_IE_POS) +#define GLB_REG_GPIO_44_IE_UMSK (~(((1U << GLB_REG_GPIO_44_IE_LEN) - 1) << GLB_REG_GPIO_44_IE_POS)) +#define GLB_REG_GPIO_44_SMT GLB_REG_GPIO_44_SMT +#define GLB_REG_GPIO_44_SMT_POS (1U) +#define GLB_REG_GPIO_44_SMT_LEN (1U) +#define GLB_REG_GPIO_44_SMT_MSK (((1U << GLB_REG_GPIO_44_SMT_LEN) - 1) << GLB_REG_GPIO_44_SMT_POS) +#define GLB_REG_GPIO_44_SMT_UMSK (~(((1U << GLB_REG_GPIO_44_SMT_LEN) - 1) << GLB_REG_GPIO_44_SMT_POS)) +#define GLB_REG_GPIO_44_DRV GLB_REG_GPIO_44_DRV +#define GLB_REG_GPIO_44_DRV_POS (2U) +#define GLB_REG_GPIO_44_DRV_LEN (2U) +#define GLB_REG_GPIO_44_DRV_MSK (((1U << GLB_REG_GPIO_44_DRV_LEN) - 1) << GLB_REG_GPIO_44_DRV_POS) +#define GLB_REG_GPIO_44_DRV_UMSK (~(((1U << GLB_REG_GPIO_44_DRV_LEN) - 1) << GLB_REG_GPIO_44_DRV_POS)) +#define GLB_REG_GPIO_44_PU GLB_REG_GPIO_44_PU +#define GLB_REG_GPIO_44_PU_POS (4U) +#define GLB_REG_GPIO_44_PU_LEN (1U) +#define GLB_REG_GPIO_44_PU_MSK (((1U << GLB_REG_GPIO_44_PU_LEN) - 1) << GLB_REG_GPIO_44_PU_POS) +#define GLB_REG_GPIO_44_PU_UMSK (~(((1U << GLB_REG_GPIO_44_PU_LEN) - 1) << GLB_REG_GPIO_44_PU_POS)) +#define GLB_REG_GPIO_44_PD GLB_REG_GPIO_44_PD +#define GLB_REG_GPIO_44_PD_POS (5U) +#define GLB_REG_GPIO_44_PD_LEN (1U) +#define GLB_REG_GPIO_44_PD_MSK (((1U << GLB_REG_GPIO_44_PD_LEN) - 1) << GLB_REG_GPIO_44_PD_POS) +#define GLB_REG_GPIO_44_PD_UMSK (~(((1U << GLB_REG_GPIO_44_PD_LEN) - 1) << GLB_REG_GPIO_44_PD_POS)) +#define GLB_REG_GPIO_44_OE GLB_REG_GPIO_44_OE +#define GLB_REG_GPIO_44_OE_POS (6U) +#define GLB_REG_GPIO_44_OE_LEN (1U) +#define GLB_REG_GPIO_44_OE_MSK (((1U << GLB_REG_GPIO_44_OE_LEN) - 1) << GLB_REG_GPIO_44_OE_POS) +#define GLB_REG_GPIO_44_OE_UMSK (~(((1U << GLB_REG_GPIO_44_OE_LEN) - 1) << GLB_REG_GPIO_44_OE_POS)) +#define GLB_REG_GPIO_44_FUNC_SEL GLB_REG_GPIO_44_FUNC_SEL +#define GLB_REG_GPIO_44_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_44_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_44_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_44_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_44_FUNC_SEL_POS) +#define GLB_REG_GPIO_44_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_44_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_44_FUNC_SEL_POS)) +#define GLB_REG_GPIO_44_INT_MODE_SET GLB_REG_GPIO_44_INT_MODE_SET +#define GLB_REG_GPIO_44_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_44_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_44_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_44_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_44_INT_MODE_SET_POS) +#define GLB_REG_GPIO_44_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_44_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_44_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_44_INT_CLR GLB_REG_GPIO_44_INT_CLR +#define GLB_REG_GPIO_44_INT_CLR_POS (20U) +#define GLB_REG_GPIO_44_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_44_INT_CLR_MSK (((1U << GLB_REG_GPIO_44_INT_CLR_LEN) - 1) << GLB_REG_GPIO_44_INT_CLR_POS) +#define GLB_REG_GPIO_44_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_44_INT_CLR_LEN) - 1) << GLB_REG_GPIO_44_INT_CLR_POS)) +#define GLB_GPIO_44_INT_STAT GLB_GPIO_44_INT_STAT +#define GLB_GPIO_44_INT_STAT_POS (21U) +#define GLB_GPIO_44_INT_STAT_LEN (1U) +#define GLB_GPIO_44_INT_STAT_MSK (((1U << GLB_GPIO_44_INT_STAT_LEN) - 1) << GLB_GPIO_44_INT_STAT_POS) +#define GLB_GPIO_44_INT_STAT_UMSK (~(((1U << GLB_GPIO_44_INT_STAT_LEN) - 1) << GLB_GPIO_44_INT_STAT_POS)) +#define GLB_REG_GPIO_44_INT_MASK GLB_REG_GPIO_44_INT_MASK +#define GLB_REG_GPIO_44_INT_MASK_POS (22U) +#define GLB_REG_GPIO_44_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_44_INT_MASK_MSK (((1U << GLB_REG_GPIO_44_INT_MASK_LEN) - 1) << GLB_REG_GPIO_44_INT_MASK_POS) +#define GLB_REG_GPIO_44_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_44_INT_MASK_LEN) - 1) << GLB_REG_GPIO_44_INT_MASK_POS)) +#define GLB_REG_GPIO_44_O GLB_REG_GPIO_44_O +#define GLB_REG_GPIO_44_O_POS (24U) +#define GLB_REG_GPIO_44_O_LEN (1U) +#define GLB_REG_GPIO_44_O_MSK (((1U << GLB_REG_GPIO_44_O_LEN) - 1) << GLB_REG_GPIO_44_O_POS) +#define GLB_REG_GPIO_44_O_UMSK (~(((1U << GLB_REG_GPIO_44_O_LEN) - 1) << GLB_REG_GPIO_44_O_POS)) +#define GLB_REG_GPIO_44_SET GLB_REG_GPIO_44_SET +#define GLB_REG_GPIO_44_SET_POS (25U) +#define GLB_REG_GPIO_44_SET_LEN (1U) +#define GLB_REG_GPIO_44_SET_MSK (((1U << GLB_REG_GPIO_44_SET_LEN) - 1) << GLB_REG_GPIO_44_SET_POS) +#define GLB_REG_GPIO_44_SET_UMSK (~(((1U << GLB_REG_GPIO_44_SET_LEN) - 1) << GLB_REG_GPIO_44_SET_POS)) +#define GLB_REG_GPIO_44_CLR GLB_REG_GPIO_44_CLR +#define GLB_REG_GPIO_44_CLR_POS (26U) +#define GLB_REG_GPIO_44_CLR_LEN (1U) +#define GLB_REG_GPIO_44_CLR_MSK (((1U << GLB_REG_GPIO_44_CLR_LEN) - 1) << GLB_REG_GPIO_44_CLR_POS) +#define GLB_REG_GPIO_44_CLR_UMSK (~(((1U << GLB_REG_GPIO_44_CLR_LEN) - 1) << GLB_REG_GPIO_44_CLR_POS)) +#define GLB_REG_GPIO_44_I GLB_REG_GPIO_44_I +#define GLB_REG_GPIO_44_I_POS (28U) +#define GLB_REG_GPIO_44_I_LEN (1U) +#define GLB_REG_GPIO_44_I_MSK (((1U << GLB_REG_GPIO_44_I_LEN) - 1) << GLB_REG_GPIO_44_I_POS) +#define GLB_REG_GPIO_44_I_UMSK (~(((1U << GLB_REG_GPIO_44_I_LEN) - 1) << GLB_REG_GPIO_44_I_POS)) +#define GLB_REG_GPIO_44_MODE GLB_REG_GPIO_44_MODE +#define GLB_REG_GPIO_44_MODE_POS (30U) +#define GLB_REG_GPIO_44_MODE_LEN (2U) +#define GLB_REG_GPIO_44_MODE_MSK (((1U << GLB_REG_GPIO_44_MODE_LEN) - 1) << GLB_REG_GPIO_44_MODE_POS) +#define GLB_REG_GPIO_44_MODE_UMSK (~(((1U << GLB_REG_GPIO_44_MODE_LEN) - 1) << GLB_REG_GPIO_44_MODE_POS)) + +/* 0x978 : gpio_cfg45 */ +#define GLB_GPIO_CFG45_OFFSET (0x978) +#define GLB_REG_GPIO_45_IE GLB_REG_GPIO_45_IE +#define GLB_REG_GPIO_45_IE_POS (0U) +#define GLB_REG_GPIO_45_IE_LEN (1U) +#define GLB_REG_GPIO_45_IE_MSK (((1U << GLB_REG_GPIO_45_IE_LEN) - 1) << GLB_REG_GPIO_45_IE_POS) +#define GLB_REG_GPIO_45_IE_UMSK (~(((1U << GLB_REG_GPIO_45_IE_LEN) - 1) << GLB_REG_GPIO_45_IE_POS)) +#define GLB_REG_GPIO_45_SMT GLB_REG_GPIO_45_SMT +#define GLB_REG_GPIO_45_SMT_POS (1U) +#define GLB_REG_GPIO_45_SMT_LEN (1U) +#define GLB_REG_GPIO_45_SMT_MSK (((1U << GLB_REG_GPIO_45_SMT_LEN) - 1) << GLB_REG_GPIO_45_SMT_POS) +#define GLB_REG_GPIO_45_SMT_UMSK (~(((1U << GLB_REG_GPIO_45_SMT_LEN) - 1) << GLB_REG_GPIO_45_SMT_POS)) +#define GLB_REG_GPIO_45_DRV GLB_REG_GPIO_45_DRV +#define GLB_REG_GPIO_45_DRV_POS (2U) +#define GLB_REG_GPIO_45_DRV_LEN (2U) +#define GLB_REG_GPIO_45_DRV_MSK (((1U << GLB_REG_GPIO_45_DRV_LEN) - 1) << GLB_REG_GPIO_45_DRV_POS) +#define GLB_REG_GPIO_45_DRV_UMSK (~(((1U << GLB_REG_GPIO_45_DRV_LEN) - 1) << GLB_REG_GPIO_45_DRV_POS)) +#define GLB_REG_GPIO_45_PU GLB_REG_GPIO_45_PU +#define GLB_REG_GPIO_45_PU_POS (4U) +#define GLB_REG_GPIO_45_PU_LEN (1U) +#define GLB_REG_GPIO_45_PU_MSK (((1U << GLB_REG_GPIO_45_PU_LEN) - 1) << GLB_REG_GPIO_45_PU_POS) +#define GLB_REG_GPIO_45_PU_UMSK (~(((1U << GLB_REG_GPIO_45_PU_LEN) - 1) << GLB_REG_GPIO_45_PU_POS)) +#define GLB_REG_GPIO_45_PD GLB_REG_GPIO_45_PD +#define GLB_REG_GPIO_45_PD_POS (5U) +#define GLB_REG_GPIO_45_PD_LEN (1U) +#define GLB_REG_GPIO_45_PD_MSK (((1U << GLB_REG_GPIO_45_PD_LEN) - 1) << GLB_REG_GPIO_45_PD_POS) +#define GLB_REG_GPIO_45_PD_UMSK (~(((1U << GLB_REG_GPIO_45_PD_LEN) - 1) << GLB_REG_GPIO_45_PD_POS)) +#define GLB_REG_GPIO_45_OE GLB_REG_GPIO_45_OE +#define GLB_REG_GPIO_45_OE_POS (6U) +#define GLB_REG_GPIO_45_OE_LEN (1U) +#define GLB_REG_GPIO_45_OE_MSK (((1U << GLB_REG_GPIO_45_OE_LEN) - 1) << GLB_REG_GPIO_45_OE_POS) +#define GLB_REG_GPIO_45_OE_UMSK (~(((1U << GLB_REG_GPIO_45_OE_LEN) - 1) << GLB_REG_GPIO_45_OE_POS)) +#define GLB_REG_GPIO_45_FUNC_SEL GLB_REG_GPIO_45_FUNC_SEL +#define GLB_REG_GPIO_45_FUNC_SEL_POS (8U) +#define GLB_REG_GPIO_45_FUNC_SEL_LEN (5U) +#define GLB_REG_GPIO_45_FUNC_SEL_MSK (((1U << GLB_REG_GPIO_45_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_45_FUNC_SEL_POS) +#define GLB_REG_GPIO_45_FUNC_SEL_UMSK (~(((1U << GLB_REG_GPIO_45_FUNC_SEL_LEN) - 1) << GLB_REG_GPIO_45_FUNC_SEL_POS)) +#define GLB_REG_GPIO_45_INT_MODE_SET GLB_REG_GPIO_45_INT_MODE_SET +#define GLB_REG_GPIO_45_INT_MODE_SET_POS (16U) +#define GLB_REG_GPIO_45_INT_MODE_SET_LEN (4U) +#define GLB_REG_GPIO_45_INT_MODE_SET_MSK (((1U << GLB_REG_GPIO_45_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_45_INT_MODE_SET_POS) +#define GLB_REG_GPIO_45_INT_MODE_SET_UMSK (~(((1U << GLB_REG_GPIO_45_INT_MODE_SET_LEN) - 1) << GLB_REG_GPIO_45_INT_MODE_SET_POS)) +#define GLB_REG_GPIO_45_INT_CLR GLB_REG_GPIO_45_INT_CLR +#define GLB_REG_GPIO_45_INT_CLR_POS (20U) +#define GLB_REG_GPIO_45_INT_CLR_LEN (1U) +#define GLB_REG_GPIO_45_INT_CLR_MSK (((1U << GLB_REG_GPIO_45_INT_CLR_LEN) - 1) << GLB_REG_GPIO_45_INT_CLR_POS) +#define GLB_REG_GPIO_45_INT_CLR_UMSK (~(((1U << GLB_REG_GPIO_45_INT_CLR_LEN) - 1) << GLB_REG_GPIO_45_INT_CLR_POS)) +#define GLB_GPIO_45_INT_STAT GLB_GPIO_45_INT_STAT +#define GLB_GPIO_45_INT_STAT_POS (21U) +#define GLB_GPIO_45_INT_STAT_LEN (1U) +#define GLB_GPIO_45_INT_STAT_MSK (((1U << GLB_GPIO_45_INT_STAT_LEN) - 1) << GLB_GPIO_45_INT_STAT_POS) +#define GLB_GPIO_45_INT_STAT_UMSK (~(((1U << GLB_GPIO_45_INT_STAT_LEN) - 1) << GLB_GPIO_45_INT_STAT_POS)) +#define GLB_REG_GPIO_45_INT_MASK GLB_REG_GPIO_45_INT_MASK +#define GLB_REG_GPIO_45_INT_MASK_POS (22U) +#define GLB_REG_GPIO_45_INT_MASK_LEN (1U) +#define GLB_REG_GPIO_45_INT_MASK_MSK (((1U << GLB_REG_GPIO_45_INT_MASK_LEN) - 1) << GLB_REG_GPIO_45_INT_MASK_POS) +#define GLB_REG_GPIO_45_INT_MASK_UMSK (~(((1U << GLB_REG_GPIO_45_INT_MASK_LEN) - 1) << GLB_REG_GPIO_45_INT_MASK_POS)) +#define GLB_REG_GPIO_45_O GLB_REG_GPIO_45_O +#define GLB_REG_GPIO_45_O_POS (24U) +#define GLB_REG_GPIO_45_O_LEN (1U) +#define GLB_REG_GPIO_45_O_MSK (((1U << GLB_REG_GPIO_45_O_LEN) - 1) << GLB_REG_GPIO_45_O_POS) +#define GLB_REG_GPIO_45_O_UMSK (~(((1U << GLB_REG_GPIO_45_O_LEN) - 1) << GLB_REG_GPIO_45_O_POS)) +#define GLB_REG_GPIO_45_SET GLB_REG_GPIO_45_SET +#define GLB_REG_GPIO_45_SET_POS (25U) +#define GLB_REG_GPIO_45_SET_LEN (1U) +#define GLB_REG_GPIO_45_SET_MSK (((1U << GLB_REG_GPIO_45_SET_LEN) - 1) << GLB_REG_GPIO_45_SET_POS) +#define GLB_REG_GPIO_45_SET_UMSK (~(((1U << GLB_REG_GPIO_45_SET_LEN) - 1) << GLB_REG_GPIO_45_SET_POS)) +#define GLB_REG_GPIO_45_CLR GLB_REG_GPIO_45_CLR +#define GLB_REG_GPIO_45_CLR_POS (26U) +#define GLB_REG_GPIO_45_CLR_LEN (1U) +#define GLB_REG_GPIO_45_CLR_MSK (((1U << GLB_REG_GPIO_45_CLR_LEN) - 1) << GLB_REG_GPIO_45_CLR_POS) +#define GLB_REG_GPIO_45_CLR_UMSK (~(((1U << GLB_REG_GPIO_45_CLR_LEN) - 1) << GLB_REG_GPIO_45_CLR_POS)) +#define GLB_REG_GPIO_45_I GLB_REG_GPIO_45_I +#define GLB_REG_GPIO_45_I_POS (28U) +#define GLB_REG_GPIO_45_I_LEN (1U) +#define GLB_REG_GPIO_45_I_MSK (((1U << GLB_REG_GPIO_45_I_LEN) - 1) << GLB_REG_GPIO_45_I_POS) +#define GLB_REG_GPIO_45_I_UMSK (~(((1U << GLB_REG_GPIO_45_I_LEN) - 1) << GLB_REG_GPIO_45_I_POS)) +#define GLB_REG_GPIO_45_MODE GLB_REG_GPIO_45_MODE +#define GLB_REG_GPIO_45_MODE_POS (30U) +#define GLB_REG_GPIO_45_MODE_LEN (2U) +#define GLB_REG_GPIO_45_MODE_MSK (((1U << GLB_REG_GPIO_45_MODE_LEN) - 1) << GLB_REG_GPIO_45_MODE_POS) +#define GLB_REG_GPIO_45_MODE_UMSK (~(((1U << GLB_REG_GPIO_45_MODE_LEN) - 1) << GLB_REG_GPIO_45_MODE_POS)) + +/* 0x97C : gpio_cfg46 */ +#define GLB_GPIO_CFG46_OFFSET (0x97C) +#define GLB_REG_GPIO_46_IE GLB_REG_GPIO_46_IE +#define GLB_REG_GPIO_46_IE_POS (0U) +#define GLB_REG_GPIO_46_IE_LEN (1U) +#define GLB_REG_GPIO_46_IE_MSK (((1U << GLB_REG_GPIO_46_IE_LEN) - 1) << GLB_REG_GPIO_46_IE_POS) +#define GLB_REG_GPIO_46_IE_UMSK (~(((1U << GLB_REG_GPIO_46_IE_LEN) - 1) << GLB_REG_GPIO_46_IE_POS)) +#define GLB_REG_GPIO_46_SMT GLB_REG_GPIO_46_SMT +#define GLB_REG_GPIO_46_SMT_POS (1U) +#define GLB_REG_GPIO_46_SMT_LEN (1U) +#define GLB_REG_GPIO_46_SMT_MSK (((1U << GLB_REG_GPIO_46_SMT_LEN) - 1) << GLB_REG_GPIO_46_SMT_POS) +#define GLB_REG_GPIO_46_SMT_UMSK (~(((1U << GLB_REG_GPIO_46_SMT_LEN) - 1) << GLB_REG_GPIO_46_SMT_POS)) +#define GLB_REG_GPIO_46_DRV GLB_REG_GPIO_46_DRV +#define GLB_REG_GPIO_46_DRV_POS (2U) +#define GLB_REG_GPIO_46_DRV_LEN (2U) +#define GLB_REG_GPIO_46_DRV_MSK (((1U << GLB_REG_GPIO_46_DRV_LEN) - 1) << GLB_REG_GPIO_46_DRV_POS) +#define GLB_REG_GPIO_46_DRV_UMSK (~(((1U << GLB_REG_GPIO_46_DRV_LEN) - 1) << GLB_REG_GPIO_46_DRV_POS)) +#define GLB_REG_GPIO_46_PU GLB_REG_GPIO_46_PU +#define GLB_REG_GPIO_46_PU_POS (4U) +#define GLB_REG_GPIO_46_PU_LEN (1U) +#define GLB_REG_GPIO_46_PU_MSK (((1U << GLB_REG_GPIO_46_PU_LEN) - 1) << GLB_REG_GPIO_46_PU_POS) +#define GLB_REG_GPIO_46_PU_UMSK (~(((1U << GLB_REG_GPIO_46_PU_LEN) - 1) << GLB_REG_GPIO_46_PU_POS)) +#define GLB_REG_GPIO_46_PD GLB_REG_GPIO_46_PD +#define GLB_REG_GPIO_46_PD_POS (5U) +#define GLB_REG_GPIO_46_PD_LEN (1U) +#define GLB_REG_GPIO_46_PD_MSK (((1U << GLB_REG_GPIO_46_PD_LEN) - 1) << GLB_REG_GPIO_46_PD_POS) +#define GLB_REG_GPIO_46_PD_UMSK (~(((1U << GLB_REG_GPIO_46_PD_LEN) - 1) << GLB_REG_GPIO_46_PD_POS)) + +/* 0x980 : gpio_cfg47 */ +#define GLB_GPIO_CFG47_OFFSET (0x980) +#define GLB_REG_GPIO_47_IE GLB_REG_GPIO_47_IE +#define GLB_REG_GPIO_47_IE_POS (0U) +#define GLB_REG_GPIO_47_IE_LEN (1U) +#define GLB_REG_GPIO_47_IE_MSK (((1U << GLB_REG_GPIO_47_IE_LEN) - 1) << GLB_REG_GPIO_47_IE_POS) +#define GLB_REG_GPIO_47_IE_UMSK (~(((1U << GLB_REG_GPIO_47_IE_LEN) - 1) << GLB_REG_GPIO_47_IE_POS)) +#define GLB_REG_GPIO_47_SMT GLB_REG_GPIO_47_SMT +#define GLB_REG_GPIO_47_SMT_POS (1U) +#define GLB_REG_GPIO_47_SMT_LEN (1U) +#define GLB_REG_GPIO_47_SMT_MSK (((1U << GLB_REG_GPIO_47_SMT_LEN) - 1) << GLB_REG_GPIO_47_SMT_POS) +#define GLB_REG_GPIO_47_SMT_UMSK (~(((1U << GLB_REG_GPIO_47_SMT_LEN) - 1) << GLB_REG_GPIO_47_SMT_POS)) +#define GLB_REG_GPIO_47_DRV GLB_REG_GPIO_47_DRV +#define GLB_REG_GPIO_47_DRV_POS (2U) +#define GLB_REG_GPIO_47_DRV_LEN (2U) +#define GLB_REG_GPIO_47_DRV_MSK (((1U << GLB_REG_GPIO_47_DRV_LEN) - 1) << GLB_REG_GPIO_47_DRV_POS) +#define GLB_REG_GPIO_47_DRV_UMSK (~(((1U << GLB_REG_GPIO_47_DRV_LEN) - 1) << GLB_REG_GPIO_47_DRV_POS)) +#define GLB_REG_GPIO_47_PU GLB_REG_GPIO_47_PU +#define GLB_REG_GPIO_47_PU_POS (4U) +#define GLB_REG_GPIO_47_PU_LEN (1U) +#define GLB_REG_GPIO_47_PU_MSK (((1U << GLB_REG_GPIO_47_PU_LEN) - 1) << GLB_REG_GPIO_47_PU_POS) +#define GLB_REG_GPIO_47_PU_UMSK (~(((1U << GLB_REG_GPIO_47_PU_LEN) - 1) << GLB_REG_GPIO_47_PU_POS)) +#define GLB_REG_GPIO_47_PD GLB_REG_GPIO_47_PD +#define GLB_REG_GPIO_47_PD_POS (5U) +#define GLB_REG_GPIO_47_PD_LEN (1U) +#define GLB_REG_GPIO_47_PD_MSK (((1U << GLB_REG_GPIO_47_PD_LEN) - 1) << GLB_REG_GPIO_47_PD_POS) +#define GLB_REG_GPIO_47_PD_UMSK (~(((1U << GLB_REG_GPIO_47_PD_LEN) - 1) << GLB_REG_GPIO_47_PD_POS)) + +/* 0x984 : gpio_cfg48 */ +#define GLB_GPIO_CFG48_OFFSET (0x984) +#define GLB_REG_GPIO_48_IE GLB_REG_GPIO_48_IE +#define GLB_REG_GPIO_48_IE_POS (0U) +#define GLB_REG_GPIO_48_IE_LEN (1U) +#define GLB_REG_GPIO_48_IE_MSK (((1U << GLB_REG_GPIO_48_IE_LEN) - 1) << GLB_REG_GPIO_48_IE_POS) +#define GLB_REG_GPIO_48_IE_UMSK (~(((1U << GLB_REG_GPIO_48_IE_LEN) - 1) << GLB_REG_GPIO_48_IE_POS)) +#define GLB_REG_GPIO_48_SMT GLB_REG_GPIO_48_SMT +#define GLB_REG_GPIO_48_SMT_POS (1U) +#define GLB_REG_GPIO_48_SMT_LEN (1U) +#define GLB_REG_GPIO_48_SMT_MSK (((1U << GLB_REG_GPIO_48_SMT_LEN) - 1) << GLB_REG_GPIO_48_SMT_POS) +#define GLB_REG_GPIO_48_SMT_UMSK (~(((1U << GLB_REG_GPIO_48_SMT_LEN) - 1) << GLB_REG_GPIO_48_SMT_POS)) +#define GLB_REG_GPIO_48_DRV GLB_REG_GPIO_48_DRV +#define GLB_REG_GPIO_48_DRV_POS (2U) +#define GLB_REG_GPIO_48_DRV_LEN (2U) +#define GLB_REG_GPIO_48_DRV_MSK (((1U << GLB_REG_GPIO_48_DRV_LEN) - 1) << GLB_REG_GPIO_48_DRV_POS) +#define GLB_REG_GPIO_48_DRV_UMSK (~(((1U << GLB_REG_GPIO_48_DRV_LEN) - 1) << GLB_REG_GPIO_48_DRV_POS)) +#define GLB_REG_GPIO_48_PU GLB_REG_GPIO_48_PU +#define GLB_REG_GPIO_48_PU_POS (4U) +#define GLB_REG_GPIO_48_PU_LEN (1U) +#define GLB_REG_GPIO_48_PU_MSK (((1U << GLB_REG_GPIO_48_PU_LEN) - 1) << GLB_REG_GPIO_48_PU_POS) +#define GLB_REG_GPIO_48_PU_UMSK (~(((1U << GLB_REG_GPIO_48_PU_LEN) - 1) << GLB_REG_GPIO_48_PU_POS)) +#define GLB_REG_GPIO_48_PD GLB_REG_GPIO_48_PD +#define GLB_REG_GPIO_48_PD_POS (5U) +#define GLB_REG_GPIO_48_PD_LEN (1U) +#define GLB_REG_GPIO_48_PD_MSK (((1U << GLB_REG_GPIO_48_PD_LEN) - 1) << GLB_REG_GPIO_48_PD_POS) +#define GLB_REG_GPIO_48_PD_UMSK (~(((1U << GLB_REG_GPIO_48_PD_LEN) - 1) << GLB_REG_GPIO_48_PD_POS)) + +/* 0x988 : gpio_cfg49 */ +#define GLB_GPIO_CFG49_OFFSET (0x988) +#define GLB_REG_GPIO_49_IE GLB_REG_GPIO_49_IE +#define GLB_REG_GPIO_49_IE_POS (0U) +#define GLB_REG_GPIO_49_IE_LEN (1U) +#define GLB_REG_GPIO_49_IE_MSK (((1U << GLB_REG_GPIO_49_IE_LEN) - 1) << GLB_REG_GPIO_49_IE_POS) +#define GLB_REG_GPIO_49_IE_UMSK (~(((1U << GLB_REG_GPIO_49_IE_LEN) - 1) << GLB_REG_GPIO_49_IE_POS)) +#define GLB_REG_GPIO_49_SMT GLB_REG_GPIO_49_SMT +#define GLB_REG_GPIO_49_SMT_POS (1U) +#define GLB_REG_GPIO_49_SMT_LEN (1U) +#define GLB_REG_GPIO_49_SMT_MSK (((1U << GLB_REG_GPIO_49_SMT_LEN) - 1) << GLB_REG_GPIO_49_SMT_POS) +#define GLB_REG_GPIO_49_SMT_UMSK (~(((1U << GLB_REG_GPIO_49_SMT_LEN) - 1) << GLB_REG_GPIO_49_SMT_POS)) +#define GLB_REG_GPIO_49_DRV GLB_REG_GPIO_49_DRV +#define GLB_REG_GPIO_49_DRV_POS (2U) +#define GLB_REG_GPIO_49_DRV_LEN (2U) +#define GLB_REG_GPIO_49_DRV_MSK (((1U << GLB_REG_GPIO_49_DRV_LEN) - 1) << GLB_REG_GPIO_49_DRV_POS) +#define GLB_REG_GPIO_49_DRV_UMSK (~(((1U << GLB_REG_GPIO_49_DRV_LEN) - 1) << GLB_REG_GPIO_49_DRV_POS)) +#define GLB_REG_GPIO_49_PU GLB_REG_GPIO_49_PU +#define GLB_REG_GPIO_49_PU_POS (4U) +#define GLB_REG_GPIO_49_PU_LEN (1U) +#define GLB_REG_GPIO_49_PU_MSK (((1U << GLB_REG_GPIO_49_PU_LEN) - 1) << GLB_REG_GPIO_49_PU_POS) +#define GLB_REG_GPIO_49_PU_UMSK (~(((1U << GLB_REG_GPIO_49_PU_LEN) - 1) << GLB_REG_GPIO_49_PU_POS)) +#define GLB_REG_GPIO_49_PD GLB_REG_GPIO_49_PD +#define GLB_REG_GPIO_49_PD_POS (5U) +#define GLB_REG_GPIO_49_PD_LEN (1U) +#define GLB_REG_GPIO_49_PD_MSK (((1U << GLB_REG_GPIO_49_PD_LEN) - 1) << GLB_REG_GPIO_49_PD_POS) +#define GLB_REG_GPIO_49_PD_UMSK (~(((1U << GLB_REG_GPIO_49_PD_LEN) - 1) << GLB_REG_GPIO_49_PD_POS)) + +/* 0x98C : gpio_cfg50 */ +#define GLB_GPIO_CFG50_OFFSET (0x98C) +#define GLB_REG_GPIO_50_IE GLB_REG_GPIO_50_IE +#define GLB_REG_GPIO_50_IE_POS (0U) +#define GLB_REG_GPIO_50_IE_LEN (1U) +#define GLB_REG_GPIO_50_IE_MSK (((1U << GLB_REG_GPIO_50_IE_LEN) - 1) << GLB_REG_GPIO_50_IE_POS) +#define GLB_REG_GPIO_50_IE_UMSK (~(((1U << GLB_REG_GPIO_50_IE_LEN) - 1) << GLB_REG_GPIO_50_IE_POS)) +#define GLB_REG_GPIO_50_SMT GLB_REG_GPIO_50_SMT +#define GLB_REG_GPIO_50_SMT_POS (1U) +#define GLB_REG_GPIO_50_SMT_LEN (1U) +#define GLB_REG_GPIO_50_SMT_MSK (((1U << GLB_REG_GPIO_50_SMT_LEN) - 1) << GLB_REG_GPIO_50_SMT_POS) +#define GLB_REG_GPIO_50_SMT_UMSK (~(((1U << GLB_REG_GPIO_50_SMT_LEN) - 1) << GLB_REG_GPIO_50_SMT_POS)) +#define GLB_REG_GPIO_50_DRV GLB_REG_GPIO_50_DRV +#define GLB_REG_GPIO_50_DRV_POS (2U) +#define GLB_REG_GPIO_50_DRV_LEN (2U) +#define GLB_REG_GPIO_50_DRV_MSK (((1U << GLB_REG_GPIO_50_DRV_LEN) - 1) << GLB_REG_GPIO_50_DRV_POS) +#define GLB_REG_GPIO_50_DRV_UMSK (~(((1U << GLB_REG_GPIO_50_DRV_LEN) - 1) << GLB_REG_GPIO_50_DRV_POS)) +#define GLB_REG_GPIO_50_PU GLB_REG_GPIO_50_PU +#define GLB_REG_GPIO_50_PU_POS (4U) +#define GLB_REG_GPIO_50_PU_LEN (1U) +#define GLB_REG_GPIO_50_PU_MSK (((1U << GLB_REG_GPIO_50_PU_LEN) - 1) << GLB_REG_GPIO_50_PU_POS) +#define GLB_REG_GPIO_50_PU_UMSK (~(((1U << GLB_REG_GPIO_50_PU_LEN) - 1) << GLB_REG_GPIO_50_PU_POS)) +#define GLB_REG_GPIO_50_PD GLB_REG_GPIO_50_PD +#define GLB_REG_GPIO_50_PD_POS (5U) +#define GLB_REG_GPIO_50_PD_LEN (1U) +#define GLB_REG_GPIO_50_PD_MSK (((1U << GLB_REG_GPIO_50_PD_LEN) - 1) << GLB_REG_GPIO_50_PD_POS) +#define GLB_REG_GPIO_50_PD_UMSK (~(((1U << GLB_REG_GPIO_50_PD_LEN) - 1) << GLB_REG_GPIO_50_PD_POS)) + +/* 0x990 : gpio_cfg51 */ +#define GLB_GPIO_CFG51_OFFSET (0x990) +#define GLB_REG_GPIO_51_IE GLB_REG_GPIO_51_IE +#define GLB_REG_GPIO_51_IE_POS (0U) +#define GLB_REG_GPIO_51_IE_LEN (1U) +#define GLB_REG_GPIO_51_IE_MSK (((1U << GLB_REG_GPIO_51_IE_LEN) - 1) << GLB_REG_GPIO_51_IE_POS) +#define GLB_REG_GPIO_51_IE_UMSK (~(((1U << GLB_REG_GPIO_51_IE_LEN) - 1) << GLB_REG_GPIO_51_IE_POS)) +#define GLB_REG_GPIO_51_SMT GLB_REG_GPIO_51_SMT +#define GLB_REG_GPIO_51_SMT_POS (1U) +#define GLB_REG_GPIO_51_SMT_LEN (1U) +#define GLB_REG_GPIO_51_SMT_MSK (((1U << GLB_REG_GPIO_51_SMT_LEN) - 1) << GLB_REG_GPIO_51_SMT_POS) +#define GLB_REG_GPIO_51_SMT_UMSK (~(((1U << GLB_REG_GPIO_51_SMT_LEN) - 1) << GLB_REG_GPIO_51_SMT_POS)) +#define GLB_REG_GPIO_51_DRV GLB_REG_GPIO_51_DRV +#define GLB_REG_GPIO_51_DRV_POS (2U) +#define GLB_REG_GPIO_51_DRV_LEN (2U) +#define GLB_REG_GPIO_51_DRV_MSK (((1U << GLB_REG_GPIO_51_DRV_LEN) - 1) << GLB_REG_GPIO_51_DRV_POS) +#define GLB_REG_GPIO_51_DRV_UMSK (~(((1U << GLB_REG_GPIO_51_DRV_LEN) - 1) << GLB_REG_GPIO_51_DRV_POS)) +#define GLB_REG_GPIO_51_PU GLB_REG_GPIO_51_PU +#define GLB_REG_GPIO_51_PU_POS (4U) +#define GLB_REG_GPIO_51_PU_LEN (1U) +#define GLB_REG_GPIO_51_PU_MSK (((1U << GLB_REG_GPIO_51_PU_LEN) - 1) << GLB_REG_GPIO_51_PU_POS) +#define GLB_REG_GPIO_51_PU_UMSK (~(((1U << GLB_REG_GPIO_51_PU_LEN) - 1) << GLB_REG_GPIO_51_PU_POS)) +#define GLB_REG_GPIO_51_PD GLB_REG_GPIO_51_PD +#define GLB_REG_GPIO_51_PD_POS (5U) +#define GLB_REG_GPIO_51_PD_LEN (1U) +#define GLB_REG_GPIO_51_PD_MSK (((1U << GLB_REG_GPIO_51_PD_LEN) - 1) << GLB_REG_GPIO_51_PD_POS) +#define GLB_REG_GPIO_51_PD_UMSK (~(((1U << GLB_REG_GPIO_51_PD_LEN) - 1) << GLB_REG_GPIO_51_PD_POS)) + +/* 0x994 : gpio_cfg52 */ +#define GLB_GPIO_CFG52_OFFSET (0x994) +#define GLB_REG_GPIO_52_IE GLB_REG_GPIO_52_IE +#define GLB_REG_GPIO_52_IE_POS (0U) +#define GLB_REG_GPIO_52_IE_LEN (1U) +#define GLB_REG_GPIO_52_IE_MSK (((1U << GLB_REG_GPIO_52_IE_LEN) - 1) << GLB_REG_GPIO_52_IE_POS) +#define GLB_REG_GPIO_52_IE_UMSK (~(((1U << GLB_REG_GPIO_52_IE_LEN) - 1) << GLB_REG_GPIO_52_IE_POS)) +#define GLB_REG_GPIO_52_SMT GLB_REG_GPIO_52_SMT +#define GLB_REG_GPIO_52_SMT_POS (1U) +#define GLB_REG_GPIO_52_SMT_LEN (1U) +#define GLB_REG_GPIO_52_SMT_MSK (((1U << GLB_REG_GPIO_52_SMT_LEN) - 1) << GLB_REG_GPIO_52_SMT_POS) +#define GLB_REG_GPIO_52_SMT_UMSK (~(((1U << GLB_REG_GPIO_52_SMT_LEN) - 1) << GLB_REG_GPIO_52_SMT_POS)) +#define GLB_REG_GPIO_52_DRV GLB_REG_GPIO_52_DRV +#define GLB_REG_GPIO_52_DRV_POS (2U) +#define GLB_REG_GPIO_52_DRV_LEN (2U) +#define GLB_REG_GPIO_52_DRV_MSK (((1U << GLB_REG_GPIO_52_DRV_LEN) - 1) << GLB_REG_GPIO_52_DRV_POS) +#define GLB_REG_GPIO_52_DRV_UMSK (~(((1U << GLB_REG_GPIO_52_DRV_LEN) - 1) << GLB_REG_GPIO_52_DRV_POS)) +#define GLB_REG_GPIO_52_PU GLB_REG_GPIO_52_PU +#define GLB_REG_GPIO_52_PU_POS (4U) +#define GLB_REG_GPIO_52_PU_LEN (1U) +#define GLB_REG_GPIO_52_PU_MSK (((1U << GLB_REG_GPIO_52_PU_LEN) - 1) << GLB_REG_GPIO_52_PU_POS) +#define GLB_REG_GPIO_52_PU_UMSK (~(((1U << GLB_REG_GPIO_52_PU_LEN) - 1) << GLB_REG_GPIO_52_PU_POS)) +#define GLB_REG_GPIO_52_PD GLB_REG_GPIO_52_PD +#define GLB_REG_GPIO_52_PD_POS (5U) +#define GLB_REG_GPIO_52_PD_LEN (1U) +#define GLB_REG_GPIO_52_PD_MSK (((1U << GLB_REG_GPIO_52_PD_LEN) - 1) << GLB_REG_GPIO_52_PD_POS) +#define GLB_REG_GPIO_52_PD_UMSK (~(((1U << GLB_REG_GPIO_52_PD_LEN) - 1) << GLB_REG_GPIO_52_PD_POS)) + +/* 0x998 : gpio_cfg53 */ +#define GLB_GPIO_CFG53_OFFSET (0x998) +#define GLB_REG_GPIO_53_IE GLB_REG_GPIO_53_IE +#define GLB_REG_GPIO_53_IE_POS (0U) +#define GLB_REG_GPIO_53_IE_LEN (1U) +#define GLB_REG_GPIO_53_IE_MSK (((1U << GLB_REG_GPIO_53_IE_LEN) - 1) << GLB_REG_GPIO_53_IE_POS) +#define GLB_REG_GPIO_53_IE_UMSK (~(((1U << GLB_REG_GPIO_53_IE_LEN) - 1) << GLB_REG_GPIO_53_IE_POS)) +#define GLB_REG_GPIO_53_SMT GLB_REG_GPIO_53_SMT +#define GLB_REG_GPIO_53_SMT_POS (1U) +#define GLB_REG_GPIO_53_SMT_LEN (1U) +#define GLB_REG_GPIO_53_SMT_MSK (((1U << GLB_REG_GPIO_53_SMT_LEN) - 1) << GLB_REG_GPIO_53_SMT_POS) +#define GLB_REG_GPIO_53_SMT_UMSK (~(((1U << GLB_REG_GPIO_53_SMT_LEN) - 1) << GLB_REG_GPIO_53_SMT_POS)) +#define GLB_REG_GPIO_53_DRV GLB_REG_GPIO_53_DRV +#define GLB_REG_GPIO_53_DRV_POS (2U) +#define GLB_REG_GPIO_53_DRV_LEN (2U) +#define GLB_REG_GPIO_53_DRV_MSK (((1U << GLB_REG_GPIO_53_DRV_LEN) - 1) << GLB_REG_GPIO_53_DRV_POS) +#define GLB_REG_GPIO_53_DRV_UMSK (~(((1U << GLB_REG_GPIO_53_DRV_LEN) - 1) << GLB_REG_GPIO_53_DRV_POS)) +#define GLB_REG_GPIO_53_PU GLB_REG_GPIO_53_PU +#define GLB_REG_GPIO_53_PU_POS (4U) +#define GLB_REG_GPIO_53_PU_LEN (1U) +#define GLB_REG_GPIO_53_PU_MSK (((1U << GLB_REG_GPIO_53_PU_LEN) - 1) << GLB_REG_GPIO_53_PU_POS) +#define GLB_REG_GPIO_53_PU_UMSK (~(((1U << GLB_REG_GPIO_53_PU_LEN) - 1) << GLB_REG_GPIO_53_PU_POS)) +#define GLB_REG_GPIO_53_PD GLB_REG_GPIO_53_PD +#define GLB_REG_GPIO_53_PD_POS (5U) +#define GLB_REG_GPIO_53_PD_LEN (1U) +#define GLB_REG_GPIO_53_PD_MSK (((1U << GLB_REG_GPIO_53_PD_LEN) - 1) << GLB_REG_GPIO_53_PD_POS) +#define GLB_REG_GPIO_53_PD_UMSK (~(((1U << GLB_REG_GPIO_53_PD_LEN) - 1) << GLB_REG_GPIO_53_PD_POS)) + +/* 0x99C : gpio_cfg54 */ +#define GLB_GPIO_CFG54_OFFSET (0x99C) +#define GLB_REG_GPIO_54_IE GLB_REG_GPIO_54_IE +#define GLB_REG_GPIO_54_IE_POS (0U) +#define GLB_REG_GPIO_54_IE_LEN (1U) +#define GLB_REG_GPIO_54_IE_MSK (((1U << GLB_REG_GPIO_54_IE_LEN) - 1) << GLB_REG_GPIO_54_IE_POS) +#define GLB_REG_GPIO_54_IE_UMSK (~(((1U << GLB_REG_GPIO_54_IE_LEN) - 1) << GLB_REG_GPIO_54_IE_POS)) +#define GLB_REG_GPIO_54_SMT GLB_REG_GPIO_54_SMT +#define GLB_REG_GPIO_54_SMT_POS (1U) +#define GLB_REG_GPIO_54_SMT_LEN (1U) +#define GLB_REG_GPIO_54_SMT_MSK (((1U << GLB_REG_GPIO_54_SMT_LEN) - 1) << GLB_REG_GPIO_54_SMT_POS) +#define GLB_REG_GPIO_54_SMT_UMSK (~(((1U << GLB_REG_GPIO_54_SMT_LEN) - 1) << GLB_REG_GPIO_54_SMT_POS)) +#define GLB_REG_GPIO_54_DRV GLB_REG_GPIO_54_DRV +#define GLB_REG_GPIO_54_DRV_POS (2U) +#define GLB_REG_GPIO_54_DRV_LEN (2U) +#define GLB_REG_GPIO_54_DRV_MSK (((1U << GLB_REG_GPIO_54_DRV_LEN) - 1) << GLB_REG_GPIO_54_DRV_POS) +#define GLB_REG_GPIO_54_DRV_UMSK (~(((1U << GLB_REG_GPIO_54_DRV_LEN) - 1) << GLB_REG_GPIO_54_DRV_POS)) +#define GLB_REG_GPIO_54_PU GLB_REG_GPIO_54_PU +#define GLB_REG_GPIO_54_PU_POS (4U) +#define GLB_REG_GPIO_54_PU_LEN (1U) +#define GLB_REG_GPIO_54_PU_MSK (((1U << GLB_REG_GPIO_54_PU_LEN) - 1) << GLB_REG_GPIO_54_PU_POS) +#define GLB_REG_GPIO_54_PU_UMSK (~(((1U << GLB_REG_GPIO_54_PU_LEN) - 1) << GLB_REG_GPIO_54_PU_POS)) +#define GLB_REG_GPIO_54_PD GLB_REG_GPIO_54_PD +#define GLB_REG_GPIO_54_PD_POS (5U) +#define GLB_REG_GPIO_54_PD_LEN (1U) +#define GLB_REG_GPIO_54_PD_MSK (((1U << GLB_REG_GPIO_54_PD_LEN) - 1) << GLB_REG_GPIO_54_PD_POS) +#define GLB_REG_GPIO_54_PD_UMSK (~(((1U << GLB_REG_GPIO_54_PD_LEN) - 1) << GLB_REG_GPIO_54_PD_POS)) + +/* 0x9A0 : gpio_cfg55 */ +#define GLB_GPIO_CFG55_OFFSET (0x9A0) +#define GLB_REG_GPIO_55_IE GLB_REG_GPIO_55_IE +#define GLB_REG_GPIO_55_IE_POS (0U) +#define GLB_REG_GPIO_55_IE_LEN (1U) +#define GLB_REG_GPIO_55_IE_MSK (((1U << GLB_REG_GPIO_55_IE_LEN) - 1) << GLB_REG_GPIO_55_IE_POS) +#define GLB_REG_GPIO_55_IE_UMSK (~(((1U << GLB_REG_GPIO_55_IE_LEN) - 1) << GLB_REG_GPIO_55_IE_POS)) +#define GLB_REG_GPIO_55_SMT GLB_REG_GPIO_55_SMT +#define GLB_REG_GPIO_55_SMT_POS (1U) +#define GLB_REG_GPIO_55_SMT_LEN (1U) +#define GLB_REG_GPIO_55_SMT_MSK (((1U << GLB_REG_GPIO_55_SMT_LEN) - 1) << GLB_REG_GPIO_55_SMT_POS) +#define GLB_REG_GPIO_55_SMT_UMSK (~(((1U << GLB_REG_GPIO_55_SMT_LEN) - 1) << GLB_REG_GPIO_55_SMT_POS)) +#define GLB_REG_GPIO_55_DRV GLB_REG_GPIO_55_DRV +#define GLB_REG_GPIO_55_DRV_POS (2U) +#define GLB_REG_GPIO_55_DRV_LEN (2U) +#define GLB_REG_GPIO_55_DRV_MSK (((1U << GLB_REG_GPIO_55_DRV_LEN) - 1) << GLB_REG_GPIO_55_DRV_POS) +#define GLB_REG_GPIO_55_DRV_UMSK (~(((1U << GLB_REG_GPIO_55_DRV_LEN) - 1) << GLB_REG_GPIO_55_DRV_POS)) +#define GLB_REG_GPIO_55_PU GLB_REG_GPIO_55_PU +#define GLB_REG_GPIO_55_PU_POS (4U) +#define GLB_REG_GPIO_55_PU_LEN (1U) +#define GLB_REG_GPIO_55_PU_MSK (((1U << GLB_REG_GPIO_55_PU_LEN) - 1) << GLB_REG_GPIO_55_PU_POS) +#define GLB_REG_GPIO_55_PU_UMSK (~(((1U << GLB_REG_GPIO_55_PU_LEN) - 1) << GLB_REG_GPIO_55_PU_POS)) +#define GLB_REG_GPIO_55_PD GLB_REG_GPIO_55_PD +#define GLB_REG_GPIO_55_PD_POS (5U) +#define GLB_REG_GPIO_55_PD_LEN (1U) +#define GLB_REG_GPIO_55_PD_MSK (((1U << GLB_REG_GPIO_55_PD_LEN) - 1) << GLB_REG_GPIO_55_PD_POS) +#define GLB_REG_GPIO_55_PD_UMSK (~(((1U << GLB_REG_GPIO_55_PD_LEN) - 1) << GLB_REG_GPIO_55_PD_POS)) + +/* 0x9A4 : gpio_cfg56 */ +#define GLB_GPIO_CFG56_OFFSET (0x9A4) +#define GLB_REG_GPIO_56_IE GLB_REG_GPIO_56_IE +#define GLB_REG_GPIO_56_IE_POS (0U) +#define GLB_REG_GPIO_56_IE_LEN (1U) +#define GLB_REG_GPIO_56_IE_MSK (((1U << GLB_REG_GPIO_56_IE_LEN) - 1) << GLB_REG_GPIO_56_IE_POS) +#define GLB_REG_GPIO_56_IE_UMSK (~(((1U << GLB_REG_GPIO_56_IE_LEN) - 1) << GLB_REG_GPIO_56_IE_POS)) +#define GLB_REG_GPIO_56_SMT GLB_REG_GPIO_56_SMT +#define GLB_REG_GPIO_56_SMT_POS (1U) +#define GLB_REG_GPIO_56_SMT_LEN (1U) +#define GLB_REG_GPIO_56_SMT_MSK (((1U << GLB_REG_GPIO_56_SMT_LEN) - 1) << GLB_REG_GPIO_56_SMT_POS) +#define GLB_REG_GPIO_56_SMT_UMSK (~(((1U << GLB_REG_GPIO_56_SMT_LEN) - 1) << GLB_REG_GPIO_56_SMT_POS)) +#define GLB_REG_GPIO_56_DRV GLB_REG_GPIO_56_DRV +#define GLB_REG_GPIO_56_DRV_POS (2U) +#define GLB_REG_GPIO_56_DRV_LEN (2U) +#define GLB_REG_GPIO_56_DRV_MSK (((1U << GLB_REG_GPIO_56_DRV_LEN) - 1) << GLB_REG_GPIO_56_DRV_POS) +#define GLB_REG_GPIO_56_DRV_UMSK (~(((1U << GLB_REG_GPIO_56_DRV_LEN) - 1) << GLB_REG_GPIO_56_DRV_POS)) +#define GLB_REG_GPIO_56_PU GLB_REG_GPIO_56_PU +#define GLB_REG_GPIO_56_PU_POS (4U) +#define GLB_REG_GPIO_56_PU_LEN (1U) +#define GLB_REG_GPIO_56_PU_MSK (((1U << GLB_REG_GPIO_56_PU_LEN) - 1) << GLB_REG_GPIO_56_PU_POS) +#define GLB_REG_GPIO_56_PU_UMSK (~(((1U << GLB_REG_GPIO_56_PU_LEN) - 1) << GLB_REG_GPIO_56_PU_POS)) +#define GLB_REG_GPIO_56_PD GLB_REG_GPIO_56_PD +#define GLB_REG_GPIO_56_PD_POS (5U) +#define GLB_REG_GPIO_56_PD_LEN (1U) +#define GLB_REG_GPIO_56_PD_MSK (((1U << GLB_REG_GPIO_56_PD_LEN) - 1) << GLB_REG_GPIO_56_PD_POS) +#define GLB_REG_GPIO_56_PD_UMSK (~(((1U << GLB_REG_GPIO_56_PD_LEN) - 1) << GLB_REG_GPIO_56_PD_POS)) + +/* 0x9A8 : gpio_cfg57 */ +#define GLB_GPIO_CFG57_OFFSET (0x9A8) +#define GLB_REG_GPIO_57_IE GLB_REG_GPIO_57_IE +#define GLB_REG_GPIO_57_IE_POS (0U) +#define GLB_REG_GPIO_57_IE_LEN (1U) +#define GLB_REG_GPIO_57_IE_MSK (((1U << GLB_REG_GPIO_57_IE_LEN) - 1) << GLB_REG_GPIO_57_IE_POS) +#define GLB_REG_GPIO_57_IE_UMSK (~(((1U << GLB_REG_GPIO_57_IE_LEN) - 1) << GLB_REG_GPIO_57_IE_POS)) +#define GLB_REG_GPIO_57_SMT GLB_REG_GPIO_57_SMT +#define GLB_REG_GPIO_57_SMT_POS (1U) +#define GLB_REG_GPIO_57_SMT_LEN (1U) +#define GLB_REG_GPIO_57_SMT_MSK (((1U << GLB_REG_GPIO_57_SMT_LEN) - 1) << GLB_REG_GPIO_57_SMT_POS) +#define GLB_REG_GPIO_57_SMT_UMSK (~(((1U << GLB_REG_GPIO_57_SMT_LEN) - 1) << GLB_REG_GPIO_57_SMT_POS)) +#define GLB_REG_GPIO_57_DRV GLB_REG_GPIO_57_DRV +#define GLB_REG_GPIO_57_DRV_POS (2U) +#define GLB_REG_GPIO_57_DRV_LEN (2U) +#define GLB_REG_GPIO_57_DRV_MSK (((1U << GLB_REG_GPIO_57_DRV_LEN) - 1) << GLB_REG_GPIO_57_DRV_POS) +#define GLB_REG_GPIO_57_DRV_UMSK (~(((1U << GLB_REG_GPIO_57_DRV_LEN) - 1) << GLB_REG_GPIO_57_DRV_POS)) +#define GLB_REG_GPIO_57_PU GLB_REG_GPIO_57_PU +#define GLB_REG_GPIO_57_PU_POS (4U) +#define GLB_REG_GPIO_57_PU_LEN (1U) +#define GLB_REG_GPIO_57_PU_MSK (((1U << GLB_REG_GPIO_57_PU_LEN) - 1) << GLB_REG_GPIO_57_PU_POS) +#define GLB_REG_GPIO_57_PU_UMSK (~(((1U << GLB_REG_GPIO_57_PU_LEN) - 1) << GLB_REG_GPIO_57_PU_POS)) +#define GLB_REG_GPIO_57_PD GLB_REG_GPIO_57_PD +#define GLB_REG_GPIO_57_PD_POS (5U) +#define GLB_REG_GPIO_57_PD_LEN (1U) +#define GLB_REG_GPIO_57_PD_MSK (((1U << GLB_REG_GPIO_57_PD_LEN) - 1) << GLB_REG_GPIO_57_PD_POS) +#define GLB_REG_GPIO_57_PD_UMSK (~(((1U << GLB_REG_GPIO_57_PD_LEN) - 1) << GLB_REG_GPIO_57_PD_POS)) + +/* 0x9AC : gpio_cfg58 */ +#define GLB_GPIO_CFG58_OFFSET (0x9AC) +#define GLB_REG_GPIO_58_IE GLB_REG_GPIO_58_IE +#define GLB_REG_GPIO_58_IE_POS (0U) +#define GLB_REG_GPIO_58_IE_LEN (1U) +#define GLB_REG_GPIO_58_IE_MSK (((1U << GLB_REG_GPIO_58_IE_LEN) - 1) << GLB_REG_GPIO_58_IE_POS) +#define GLB_REG_GPIO_58_IE_UMSK (~(((1U << GLB_REG_GPIO_58_IE_LEN) - 1) << GLB_REG_GPIO_58_IE_POS)) +#define GLB_REG_GPIO_58_SMT GLB_REG_GPIO_58_SMT +#define GLB_REG_GPIO_58_SMT_POS (1U) +#define GLB_REG_GPIO_58_SMT_LEN (1U) +#define GLB_REG_GPIO_58_SMT_MSK (((1U << GLB_REG_GPIO_58_SMT_LEN) - 1) << GLB_REG_GPIO_58_SMT_POS) +#define GLB_REG_GPIO_58_SMT_UMSK (~(((1U << GLB_REG_GPIO_58_SMT_LEN) - 1) << GLB_REG_GPIO_58_SMT_POS)) +#define GLB_REG_GPIO_58_DRV GLB_REG_GPIO_58_DRV +#define GLB_REG_GPIO_58_DRV_POS (2U) +#define GLB_REG_GPIO_58_DRV_LEN (2U) +#define GLB_REG_GPIO_58_DRV_MSK (((1U << GLB_REG_GPIO_58_DRV_LEN) - 1) << GLB_REG_GPIO_58_DRV_POS) +#define GLB_REG_GPIO_58_DRV_UMSK (~(((1U << GLB_REG_GPIO_58_DRV_LEN) - 1) << GLB_REG_GPIO_58_DRV_POS)) +#define GLB_REG_GPIO_58_PU GLB_REG_GPIO_58_PU +#define GLB_REG_GPIO_58_PU_POS (4U) +#define GLB_REG_GPIO_58_PU_LEN (1U) +#define GLB_REG_GPIO_58_PU_MSK (((1U << GLB_REG_GPIO_58_PU_LEN) - 1) << GLB_REG_GPIO_58_PU_POS) +#define GLB_REG_GPIO_58_PU_UMSK (~(((1U << GLB_REG_GPIO_58_PU_LEN) - 1) << GLB_REG_GPIO_58_PU_POS)) +#define GLB_REG_GPIO_58_PD GLB_REG_GPIO_58_PD +#define GLB_REG_GPIO_58_PD_POS (5U) +#define GLB_REG_GPIO_58_PD_LEN (1U) +#define GLB_REG_GPIO_58_PD_MSK (((1U << GLB_REG_GPIO_58_PD_LEN) - 1) << GLB_REG_GPIO_58_PD_POS) +#define GLB_REG_GPIO_58_PD_UMSK (~(((1U << GLB_REG_GPIO_58_PD_LEN) - 1) << GLB_REG_GPIO_58_PD_POS)) + +/* 0x9B0 : gpio_cfg59 */ +#define GLB_GPIO_CFG59_OFFSET (0x9B0) +#define GLB_REG_GPIO_59_IE GLB_REG_GPIO_59_IE +#define GLB_REG_GPIO_59_IE_POS (0U) +#define GLB_REG_GPIO_59_IE_LEN (1U) +#define GLB_REG_GPIO_59_IE_MSK (((1U << GLB_REG_GPIO_59_IE_LEN) - 1) << GLB_REG_GPIO_59_IE_POS) +#define GLB_REG_GPIO_59_IE_UMSK (~(((1U << GLB_REG_GPIO_59_IE_LEN) - 1) << GLB_REG_GPIO_59_IE_POS)) +#define GLB_REG_GPIO_59_SMT GLB_REG_GPIO_59_SMT +#define GLB_REG_GPIO_59_SMT_POS (1U) +#define GLB_REG_GPIO_59_SMT_LEN (1U) +#define GLB_REG_GPIO_59_SMT_MSK (((1U << GLB_REG_GPIO_59_SMT_LEN) - 1) << GLB_REG_GPIO_59_SMT_POS) +#define GLB_REG_GPIO_59_SMT_UMSK (~(((1U << GLB_REG_GPIO_59_SMT_LEN) - 1) << GLB_REG_GPIO_59_SMT_POS)) +#define GLB_REG_GPIO_59_DRV GLB_REG_GPIO_59_DRV +#define GLB_REG_GPIO_59_DRV_POS (2U) +#define GLB_REG_GPIO_59_DRV_LEN (2U) +#define GLB_REG_GPIO_59_DRV_MSK (((1U << GLB_REG_GPIO_59_DRV_LEN) - 1) << GLB_REG_GPIO_59_DRV_POS) +#define GLB_REG_GPIO_59_DRV_UMSK (~(((1U << GLB_REG_GPIO_59_DRV_LEN) - 1) << GLB_REG_GPIO_59_DRV_POS)) +#define GLB_REG_GPIO_59_PU GLB_REG_GPIO_59_PU +#define GLB_REG_GPIO_59_PU_POS (4U) +#define GLB_REG_GPIO_59_PU_LEN (1U) +#define GLB_REG_GPIO_59_PU_MSK (((1U << GLB_REG_GPIO_59_PU_LEN) - 1) << GLB_REG_GPIO_59_PU_POS) +#define GLB_REG_GPIO_59_PU_UMSK (~(((1U << GLB_REG_GPIO_59_PU_LEN) - 1) << GLB_REG_GPIO_59_PU_POS)) +#define GLB_REG_GPIO_59_PD GLB_REG_GPIO_59_PD +#define GLB_REG_GPIO_59_PD_POS (5U) +#define GLB_REG_GPIO_59_PD_LEN (1U) +#define GLB_REG_GPIO_59_PD_MSK (((1U << GLB_REG_GPIO_59_PD_LEN) - 1) << GLB_REG_GPIO_59_PD_POS) +#define GLB_REG_GPIO_59_PD_UMSK (~(((1U << GLB_REG_GPIO_59_PD_LEN) - 1) << GLB_REG_GPIO_59_PD_POS)) + +/* 0x9B4 : gpio_cfg60 */ +#define GLB_GPIO_CFG60_OFFSET (0x9B4) +#define GLB_REG_GPIO_60_IE GLB_REG_GPIO_60_IE +#define GLB_REG_GPIO_60_IE_POS (0U) +#define GLB_REG_GPIO_60_IE_LEN (1U) +#define GLB_REG_GPIO_60_IE_MSK (((1U << GLB_REG_GPIO_60_IE_LEN) - 1) << GLB_REG_GPIO_60_IE_POS) +#define GLB_REG_GPIO_60_IE_UMSK (~(((1U << GLB_REG_GPIO_60_IE_LEN) - 1) << GLB_REG_GPIO_60_IE_POS)) +#define GLB_REG_GPIO_60_SMT GLB_REG_GPIO_60_SMT +#define GLB_REG_GPIO_60_SMT_POS (1U) +#define GLB_REG_GPIO_60_SMT_LEN (1U) +#define GLB_REG_GPIO_60_SMT_MSK (((1U << GLB_REG_GPIO_60_SMT_LEN) - 1) << GLB_REG_GPIO_60_SMT_POS) +#define GLB_REG_GPIO_60_SMT_UMSK (~(((1U << GLB_REG_GPIO_60_SMT_LEN) - 1) << GLB_REG_GPIO_60_SMT_POS)) +#define GLB_REG_GPIO_60_DRV GLB_REG_GPIO_60_DRV +#define GLB_REG_GPIO_60_DRV_POS (2U) +#define GLB_REG_GPIO_60_DRV_LEN (2U) +#define GLB_REG_GPIO_60_DRV_MSK (((1U << GLB_REG_GPIO_60_DRV_LEN) - 1) << GLB_REG_GPIO_60_DRV_POS) +#define GLB_REG_GPIO_60_DRV_UMSK (~(((1U << GLB_REG_GPIO_60_DRV_LEN) - 1) << GLB_REG_GPIO_60_DRV_POS)) +#define GLB_REG_GPIO_60_PU GLB_REG_GPIO_60_PU +#define GLB_REG_GPIO_60_PU_POS (4U) +#define GLB_REG_GPIO_60_PU_LEN (1U) +#define GLB_REG_GPIO_60_PU_MSK (((1U << GLB_REG_GPIO_60_PU_LEN) - 1) << GLB_REG_GPIO_60_PU_POS) +#define GLB_REG_GPIO_60_PU_UMSK (~(((1U << GLB_REG_GPIO_60_PU_LEN) - 1) << GLB_REG_GPIO_60_PU_POS)) +#define GLB_REG_GPIO_60_PD GLB_REG_GPIO_60_PD +#define GLB_REG_GPIO_60_PD_POS (5U) +#define GLB_REG_GPIO_60_PD_LEN (1U) +#define GLB_REG_GPIO_60_PD_MSK (((1U << GLB_REG_GPIO_60_PD_LEN) - 1) << GLB_REG_GPIO_60_PD_POS) +#define GLB_REG_GPIO_60_PD_UMSK (~(((1U << GLB_REG_GPIO_60_PD_LEN) - 1) << GLB_REG_GPIO_60_PD_POS)) + +/* 0x9B8 : gpio_cfg61 */ +#define GLB_GPIO_CFG61_OFFSET (0x9B8) +#define GLB_REG_GPIO_61_IE GLB_REG_GPIO_61_IE +#define GLB_REG_GPIO_61_IE_POS (0U) +#define GLB_REG_GPIO_61_IE_LEN (1U) +#define GLB_REG_GPIO_61_IE_MSK (((1U << GLB_REG_GPIO_61_IE_LEN) - 1) << GLB_REG_GPIO_61_IE_POS) +#define GLB_REG_GPIO_61_IE_UMSK (~(((1U << GLB_REG_GPIO_61_IE_LEN) - 1) << GLB_REG_GPIO_61_IE_POS)) +#define GLB_REG_GPIO_61_SMT GLB_REG_GPIO_61_SMT +#define GLB_REG_GPIO_61_SMT_POS (1U) +#define GLB_REG_GPIO_61_SMT_LEN (1U) +#define GLB_REG_GPIO_61_SMT_MSK (((1U << GLB_REG_GPIO_61_SMT_LEN) - 1) << GLB_REG_GPIO_61_SMT_POS) +#define GLB_REG_GPIO_61_SMT_UMSK (~(((1U << GLB_REG_GPIO_61_SMT_LEN) - 1) << GLB_REG_GPIO_61_SMT_POS)) +#define GLB_REG_GPIO_61_DRV GLB_REG_GPIO_61_DRV +#define GLB_REG_GPIO_61_DRV_POS (2U) +#define GLB_REG_GPIO_61_DRV_LEN (2U) +#define GLB_REG_GPIO_61_DRV_MSK (((1U << GLB_REG_GPIO_61_DRV_LEN) - 1) << GLB_REG_GPIO_61_DRV_POS) +#define GLB_REG_GPIO_61_DRV_UMSK (~(((1U << GLB_REG_GPIO_61_DRV_LEN) - 1) << GLB_REG_GPIO_61_DRV_POS)) +#define GLB_REG_GPIO_61_PU GLB_REG_GPIO_61_PU +#define GLB_REG_GPIO_61_PU_POS (4U) +#define GLB_REG_GPIO_61_PU_LEN (1U) +#define GLB_REG_GPIO_61_PU_MSK (((1U << GLB_REG_GPIO_61_PU_LEN) - 1) << GLB_REG_GPIO_61_PU_POS) +#define GLB_REG_GPIO_61_PU_UMSK (~(((1U << GLB_REG_GPIO_61_PU_LEN) - 1) << GLB_REG_GPIO_61_PU_POS)) +#define GLB_REG_GPIO_61_PD GLB_REG_GPIO_61_PD +#define GLB_REG_GPIO_61_PD_POS (5U) +#define GLB_REG_GPIO_61_PD_LEN (1U) +#define GLB_REG_GPIO_61_PD_MSK (((1U << GLB_REG_GPIO_61_PD_LEN) - 1) << GLB_REG_GPIO_61_PD_POS) +#define GLB_REG_GPIO_61_PD_UMSK (~(((1U << GLB_REG_GPIO_61_PD_LEN) - 1) << GLB_REG_GPIO_61_PD_POS)) + +/* 0x9BC : gpio_cfg62 */ +#define GLB_GPIO_CFG62_OFFSET (0x9BC) +#define GLB_REG_GPIO_62_IE GLB_REG_GPIO_62_IE +#define GLB_REG_GPIO_62_IE_POS (0U) +#define GLB_REG_GPIO_62_IE_LEN (1U) +#define GLB_REG_GPIO_62_IE_MSK (((1U << GLB_REG_GPIO_62_IE_LEN) - 1) << GLB_REG_GPIO_62_IE_POS) +#define GLB_REG_GPIO_62_IE_UMSK (~(((1U << GLB_REG_GPIO_62_IE_LEN) - 1) << GLB_REG_GPIO_62_IE_POS)) +#define GLB_REG_GPIO_62_SMT GLB_REG_GPIO_62_SMT +#define GLB_REG_GPIO_62_SMT_POS (1U) +#define GLB_REG_GPIO_62_SMT_LEN (1U) +#define GLB_REG_GPIO_62_SMT_MSK (((1U << GLB_REG_GPIO_62_SMT_LEN) - 1) << GLB_REG_GPIO_62_SMT_POS) +#define GLB_REG_GPIO_62_SMT_UMSK (~(((1U << GLB_REG_GPIO_62_SMT_LEN) - 1) << GLB_REG_GPIO_62_SMT_POS)) +#define GLB_REG_GPIO_62_DRV GLB_REG_GPIO_62_DRV +#define GLB_REG_GPIO_62_DRV_POS (2U) +#define GLB_REG_GPIO_62_DRV_LEN (2U) +#define GLB_REG_GPIO_62_DRV_MSK (((1U << GLB_REG_GPIO_62_DRV_LEN) - 1) << GLB_REG_GPIO_62_DRV_POS) +#define GLB_REG_GPIO_62_DRV_UMSK (~(((1U << GLB_REG_GPIO_62_DRV_LEN) - 1) << GLB_REG_GPIO_62_DRV_POS)) +#define GLB_REG_GPIO_62_PU GLB_REG_GPIO_62_PU +#define GLB_REG_GPIO_62_PU_POS (4U) +#define GLB_REG_GPIO_62_PU_LEN (1U) +#define GLB_REG_GPIO_62_PU_MSK (((1U << GLB_REG_GPIO_62_PU_LEN) - 1) << GLB_REG_GPIO_62_PU_POS) +#define GLB_REG_GPIO_62_PU_UMSK (~(((1U << GLB_REG_GPIO_62_PU_LEN) - 1) << GLB_REG_GPIO_62_PU_POS)) +#define GLB_REG_GPIO_62_PD GLB_REG_GPIO_62_PD +#define GLB_REG_GPIO_62_PD_POS (5U) +#define GLB_REG_GPIO_62_PD_LEN (1U) +#define GLB_REG_GPIO_62_PD_MSK (((1U << GLB_REG_GPIO_62_PD_LEN) - 1) << GLB_REG_GPIO_62_PD_POS) +#define GLB_REG_GPIO_62_PD_UMSK (~(((1U << GLB_REG_GPIO_62_PD_LEN) - 1) << GLB_REG_GPIO_62_PD_POS)) + +/* 0x9C0 : gpio_cfg63 */ +#define GLB_GPIO_CFG63_OFFSET (0x9C0) +#define GLB_REG_GPIO_63_IE GLB_REG_GPIO_63_IE +#define GLB_REG_GPIO_63_IE_POS (0U) +#define GLB_REG_GPIO_63_IE_LEN (1U) +#define GLB_REG_GPIO_63_IE_MSK (((1U << GLB_REG_GPIO_63_IE_LEN) - 1) << GLB_REG_GPIO_63_IE_POS) +#define GLB_REG_GPIO_63_IE_UMSK (~(((1U << GLB_REG_GPIO_63_IE_LEN) - 1) << GLB_REG_GPIO_63_IE_POS)) +#define GLB_REG_GPIO_63_SMT GLB_REG_GPIO_63_SMT +#define GLB_REG_GPIO_63_SMT_POS (1U) +#define GLB_REG_GPIO_63_SMT_LEN (1U) +#define GLB_REG_GPIO_63_SMT_MSK (((1U << GLB_REG_GPIO_63_SMT_LEN) - 1) << GLB_REG_GPIO_63_SMT_POS) +#define GLB_REG_GPIO_63_SMT_UMSK (~(((1U << GLB_REG_GPIO_63_SMT_LEN) - 1) << GLB_REG_GPIO_63_SMT_POS)) +#define GLB_REG_GPIO_63_DRV GLB_REG_GPIO_63_DRV +#define GLB_REG_GPIO_63_DRV_POS (2U) +#define GLB_REG_GPIO_63_DRV_LEN (2U) +#define GLB_REG_GPIO_63_DRV_MSK (((1U << GLB_REG_GPIO_63_DRV_LEN) - 1) << GLB_REG_GPIO_63_DRV_POS) +#define GLB_REG_GPIO_63_DRV_UMSK (~(((1U << GLB_REG_GPIO_63_DRV_LEN) - 1) << GLB_REG_GPIO_63_DRV_POS)) +#define GLB_REG_GPIO_63_PU GLB_REG_GPIO_63_PU +#define GLB_REG_GPIO_63_PU_POS (4U) +#define GLB_REG_GPIO_63_PU_LEN (1U) +#define GLB_REG_GPIO_63_PU_MSK (((1U << GLB_REG_GPIO_63_PU_LEN) - 1) << GLB_REG_GPIO_63_PU_POS) +#define GLB_REG_GPIO_63_PU_UMSK (~(((1U << GLB_REG_GPIO_63_PU_LEN) - 1) << GLB_REG_GPIO_63_PU_POS)) +#define GLB_REG_GPIO_63_PD GLB_REG_GPIO_63_PD +#define GLB_REG_GPIO_63_PD_POS (5U) +#define GLB_REG_GPIO_63_PD_LEN (1U) +#define GLB_REG_GPIO_63_PD_MSK (((1U << GLB_REG_GPIO_63_PD_LEN) - 1) << GLB_REG_GPIO_63_PD_POS) +#define GLB_REG_GPIO_63_PD_UMSK (~(((1U << GLB_REG_GPIO_63_PD_LEN) - 1) << GLB_REG_GPIO_63_PD_POS)) + +/* 0xAC4 : gpio_cfg128 */ +#define GLB_GPIO_CFG128_OFFSET (0xAC4) +#define GLB_REG2_GPIO_0_I GLB_REG2_GPIO_0_I +#define GLB_REG2_GPIO_0_I_POS (0U) +#define GLB_REG2_GPIO_0_I_LEN (1U) +#define GLB_REG2_GPIO_0_I_MSK (((1U << GLB_REG2_GPIO_0_I_LEN) - 1) << GLB_REG2_GPIO_0_I_POS) +#define GLB_REG2_GPIO_0_I_UMSK (~(((1U << GLB_REG2_GPIO_0_I_LEN) - 1) << GLB_REG2_GPIO_0_I_POS)) +#define GLB_REG2_GPIO_1_I GLB_REG2_GPIO_1_I +#define GLB_REG2_GPIO_1_I_POS (1U) +#define GLB_REG2_GPIO_1_I_LEN (1U) +#define GLB_REG2_GPIO_1_I_MSK (((1U << GLB_REG2_GPIO_1_I_LEN) - 1) << GLB_REG2_GPIO_1_I_POS) +#define GLB_REG2_GPIO_1_I_UMSK (~(((1U << GLB_REG2_GPIO_1_I_LEN) - 1) << GLB_REG2_GPIO_1_I_POS)) +#define GLB_REG2_GPIO_2_I GLB_REG2_GPIO_2_I +#define GLB_REG2_GPIO_2_I_POS (2U) +#define GLB_REG2_GPIO_2_I_LEN (1U) +#define GLB_REG2_GPIO_2_I_MSK (((1U << GLB_REG2_GPIO_2_I_LEN) - 1) << GLB_REG2_GPIO_2_I_POS) +#define GLB_REG2_GPIO_2_I_UMSK (~(((1U << GLB_REG2_GPIO_2_I_LEN) - 1) << GLB_REG2_GPIO_2_I_POS)) +#define GLB_REG2_GPIO_3_I GLB_REG2_GPIO_3_I +#define GLB_REG2_GPIO_3_I_POS (3U) +#define GLB_REG2_GPIO_3_I_LEN (1U) +#define GLB_REG2_GPIO_3_I_MSK (((1U << GLB_REG2_GPIO_3_I_LEN) - 1) << GLB_REG2_GPIO_3_I_POS) +#define GLB_REG2_GPIO_3_I_UMSK (~(((1U << GLB_REG2_GPIO_3_I_LEN) - 1) << GLB_REG2_GPIO_3_I_POS)) +#define GLB_REG2_GPIO_4_I GLB_REG2_GPIO_4_I +#define GLB_REG2_GPIO_4_I_POS (4U) +#define GLB_REG2_GPIO_4_I_LEN (1U) +#define GLB_REG2_GPIO_4_I_MSK (((1U << GLB_REG2_GPIO_4_I_LEN) - 1) << GLB_REG2_GPIO_4_I_POS) +#define GLB_REG2_GPIO_4_I_UMSK (~(((1U << GLB_REG2_GPIO_4_I_LEN) - 1) << GLB_REG2_GPIO_4_I_POS)) +#define GLB_REG2_GPIO_5_I GLB_REG2_GPIO_5_I +#define GLB_REG2_GPIO_5_I_POS (5U) +#define GLB_REG2_GPIO_5_I_LEN (1U) +#define GLB_REG2_GPIO_5_I_MSK (((1U << GLB_REG2_GPIO_5_I_LEN) - 1) << GLB_REG2_GPIO_5_I_POS) +#define GLB_REG2_GPIO_5_I_UMSK (~(((1U << GLB_REG2_GPIO_5_I_LEN) - 1) << GLB_REG2_GPIO_5_I_POS)) +#define GLB_REG2_GPIO_6_I GLB_REG2_GPIO_6_I +#define GLB_REG2_GPIO_6_I_POS (6U) +#define GLB_REG2_GPIO_6_I_LEN (1U) +#define GLB_REG2_GPIO_6_I_MSK (((1U << GLB_REG2_GPIO_6_I_LEN) - 1) << GLB_REG2_GPIO_6_I_POS) +#define GLB_REG2_GPIO_6_I_UMSK (~(((1U << GLB_REG2_GPIO_6_I_LEN) - 1) << GLB_REG2_GPIO_6_I_POS)) +#define GLB_REG2_GPIO_7_I GLB_REG2_GPIO_7_I +#define GLB_REG2_GPIO_7_I_POS (7U) +#define GLB_REG2_GPIO_7_I_LEN (1U) +#define GLB_REG2_GPIO_7_I_MSK (((1U << GLB_REG2_GPIO_7_I_LEN) - 1) << GLB_REG2_GPIO_7_I_POS) +#define GLB_REG2_GPIO_7_I_UMSK (~(((1U << GLB_REG2_GPIO_7_I_LEN) - 1) << GLB_REG2_GPIO_7_I_POS)) +#define GLB_REG2_GPIO_8_I GLB_REG2_GPIO_8_I +#define GLB_REG2_GPIO_8_I_POS (8U) +#define GLB_REG2_GPIO_8_I_LEN (1U) +#define GLB_REG2_GPIO_8_I_MSK (((1U << GLB_REG2_GPIO_8_I_LEN) - 1) << GLB_REG2_GPIO_8_I_POS) +#define GLB_REG2_GPIO_8_I_UMSK (~(((1U << GLB_REG2_GPIO_8_I_LEN) - 1) << GLB_REG2_GPIO_8_I_POS)) +#define GLB_REG2_GPIO_9_I GLB_REG2_GPIO_9_I +#define GLB_REG2_GPIO_9_I_POS (9U) +#define GLB_REG2_GPIO_9_I_LEN (1U) +#define GLB_REG2_GPIO_9_I_MSK (((1U << GLB_REG2_GPIO_9_I_LEN) - 1) << GLB_REG2_GPIO_9_I_POS) +#define GLB_REG2_GPIO_9_I_UMSK (~(((1U << GLB_REG2_GPIO_9_I_LEN) - 1) << GLB_REG2_GPIO_9_I_POS)) +#define GLB_REG2_GPIO_10_I GLB_REG2_GPIO_10_I +#define GLB_REG2_GPIO_10_I_POS (10U) +#define GLB_REG2_GPIO_10_I_LEN (1U) +#define GLB_REG2_GPIO_10_I_MSK (((1U << GLB_REG2_GPIO_10_I_LEN) - 1) << GLB_REG2_GPIO_10_I_POS) +#define GLB_REG2_GPIO_10_I_UMSK (~(((1U << GLB_REG2_GPIO_10_I_LEN) - 1) << GLB_REG2_GPIO_10_I_POS)) +#define GLB_REG2_GPIO_11_I GLB_REG2_GPIO_11_I +#define GLB_REG2_GPIO_11_I_POS (11U) +#define GLB_REG2_GPIO_11_I_LEN (1U) +#define GLB_REG2_GPIO_11_I_MSK (((1U << GLB_REG2_GPIO_11_I_LEN) - 1) << GLB_REG2_GPIO_11_I_POS) +#define GLB_REG2_GPIO_11_I_UMSK (~(((1U << GLB_REG2_GPIO_11_I_LEN) - 1) << GLB_REG2_GPIO_11_I_POS)) +#define GLB_REG2_GPIO_12_I GLB_REG2_GPIO_12_I +#define GLB_REG2_GPIO_12_I_POS (12U) +#define GLB_REG2_GPIO_12_I_LEN (1U) +#define GLB_REG2_GPIO_12_I_MSK (((1U << GLB_REG2_GPIO_12_I_LEN) - 1) << GLB_REG2_GPIO_12_I_POS) +#define GLB_REG2_GPIO_12_I_UMSK (~(((1U << GLB_REG2_GPIO_12_I_LEN) - 1) << GLB_REG2_GPIO_12_I_POS)) +#define GLB_REG2_GPIO_13_I GLB_REG2_GPIO_13_I +#define GLB_REG2_GPIO_13_I_POS (13U) +#define GLB_REG2_GPIO_13_I_LEN (1U) +#define GLB_REG2_GPIO_13_I_MSK (((1U << GLB_REG2_GPIO_13_I_LEN) - 1) << GLB_REG2_GPIO_13_I_POS) +#define GLB_REG2_GPIO_13_I_UMSK (~(((1U << GLB_REG2_GPIO_13_I_LEN) - 1) << GLB_REG2_GPIO_13_I_POS)) +#define GLB_REG2_GPIO_14_I GLB_REG2_GPIO_14_I +#define GLB_REG2_GPIO_14_I_POS (14U) +#define GLB_REG2_GPIO_14_I_LEN (1U) +#define GLB_REG2_GPIO_14_I_MSK (((1U << GLB_REG2_GPIO_14_I_LEN) - 1) << GLB_REG2_GPIO_14_I_POS) +#define GLB_REG2_GPIO_14_I_UMSK (~(((1U << GLB_REG2_GPIO_14_I_LEN) - 1) << GLB_REG2_GPIO_14_I_POS)) +#define GLB_REG2_GPIO_15_I GLB_REG2_GPIO_15_I +#define GLB_REG2_GPIO_15_I_POS (15U) +#define GLB_REG2_GPIO_15_I_LEN (1U) +#define GLB_REG2_GPIO_15_I_MSK (((1U << GLB_REG2_GPIO_15_I_LEN) - 1) << GLB_REG2_GPIO_15_I_POS) +#define GLB_REG2_GPIO_15_I_UMSK (~(((1U << GLB_REG2_GPIO_15_I_LEN) - 1) << GLB_REG2_GPIO_15_I_POS)) +#define GLB_REG2_GPIO_16_I GLB_REG2_GPIO_16_I +#define GLB_REG2_GPIO_16_I_POS (16U) +#define GLB_REG2_GPIO_16_I_LEN (1U) +#define GLB_REG2_GPIO_16_I_MSK (((1U << GLB_REG2_GPIO_16_I_LEN) - 1) << GLB_REG2_GPIO_16_I_POS) +#define GLB_REG2_GPIO_16_I_UMSK (~(((1U << GLB_REG2_GPIO_16_I_LEN) - 1) << GLB_REG2_GPIO_16_I_POS)) +#define GLB_REG2_GPIO_17_I GLB_REG2_GPIO_17_I +#define GLB_REG2_GPIO_17_I_POS (17U) +#define GLB_REG2_GPIO_17_I_LEN (1U) +#define GLB_REG2_GPIO_17_I_MSK (((1U << GLB_REG2_GPIO_17_I_LEN) - 1) << GLB_REG2_GPIO_17_I_POS) +#define GLB_REG2_GPIO_17_I_UMSK (~(((1U << GLB_REG2_GPIO_17_I_LEN) - 1) << GLB_REG2_GPIO_17_I_POS)) +#define GLB_REG2_GPIO_18_I GLB_REG2_GPIO_18_I +#define GLB_REG2_GPIO_18_I_POS (18U) +#define GLB_REG2_GPIO_18_I_LEN (1U) +#define GLB_REG2_GPIO_18_I_MSK (((1U << GLB_REG2_GPIO_18_I_LEN) - 1) << GLB_REG2_GPIO_18_I_POS) +#define GLB_REG2_GPIO_18_I_UMSK (~(((1U << GLB_REG2_GPIO_18_I_LEN) - 1) << GLB_REG2_GPIO_18_I_POS)) +#define GLB_REG2_GPIO_19_I GLB_REG2_GPIO_19_I +#define GLB_REG2_GPIO_19_I_POS (19U) +#define GLB_REG2_GPIO_19_I_LEN (1U) +#define GLB_REG2_GPIO_19_I_MSK (((1U << GLB_REG2_GPIO_19_I_LEN) - 1) << GLB_REG2_GPIO_19_I_POS) +#define GLB_REG2_GPIO_19_I_UMSK (~(((1U << GLB_REG2_GPIO_19_I_LEN) - 1) << GLB_REG2_GPIO_19_I_POS)) +#define GLB_REG2_GPIO_20_I GLB_REG2_GPIO_20_I +#define GLB_REG2_GPIO_20_I_POS (20U) +#define GLB_REG2_GPIO_20_I_LEN (1U) +#define GLB_REG2_GPIO_20_I_MSK (((1U << GLB_REG2_GPIO_20_I_LEN) - 1) << GLB_REG2_GPIO_20_I_POS) +#define GLB_REG2_GPIO_20_I_UMSK (~(((1U << GLB_REG2_GPIO_20_I_LEN) - 1) << GLB_REG2_GPIO_20_I_POS)) +#define GLB_REG2_GPIO_21_I GLB_REG2_GPIO_21_I +#define GLB_REG2_GPIO_21_I_POS (21U) +#define GLB_REG2_GPIO_21_I_LEN (1U) +#define GLB_REG2_GPIO_21_I_MSK (((1U << GLB_REG2_GPIO_21_I_LEN) - 1) << GLB_REG2_GPIO_21_I_POS) +#define GLB_REG2_GPIO_21_I_UMSK (~(((1U << GLB_REG2_GPIO_21_I_LEN) - 1) << GLB_REG2_GPIO_21_I_POS)) +#define GLB_REG2_GPIO_22_I GLB_REG2_GPIO_22_I +#define GLB_REG2_GPIO_22_I_POS (22U) +#define GLB_REG2_GPIO_22_I_LEN (1U) +#define GLB_REG2_GPIO_22_I_MSK (((1U << GLB_REG2_GPIO_22_I_LEN) - 1) << GLB_REG2_GPIO_22_I_POS) +#define GLB_REG2_GPIO_22_I_UMSK (~(((1U << GLB_REG2_GPIO_22_I_LEN) - 1) << GLB_REG2_GPIO_22_I_POS)) +#define GLB_REG2_GPIO_23_I GLB_REG2_GPIO_23_I +#define GLB_REG2_GPIO_23_I_POS (23U) +#define GLB_REG2_GPIO_23_I_LEN (1U) +#define GLB_REG2_GPIO_23_I_MSK (((1U << GLB_REG2_GPIO_23_I_LEN) - 1) << GLB_REG2_GPIO_23_I_POS) +#define GLB_REG2_GPIO_23_I_UMSK (~(((1U << GLB_REG2_GPIO_23_I_LEN) - 1) << GLB_REG2_GPIO_23_I_POS)) +#define GLB_REG2_GPIO_24_I GLB_REG2_GPIO_24_I +#define GLB_REG2_GPIO_24_I_POS (24U) +#define GLB_REG2_GPIO_24_I_LEN (1U) +#define GLB_REG2_GPIO_24_I_MSK (((1U << GLB_REG2_GPIO_24_I_LEN) - 1) << GLB_REG2_GPIO_24_I_POS) +#define GLB_REG2_GPIO_24_I_UMSK (~(((1U << GLB_REG2_GPIO_24_I_LEN) - 1) << GLB_REG2_GPIO_24_I_POS)) +#define GLB_REG2_GPIO_25_I GLB_REG2_GPIO_25_I +#define GLB_REG2_GPIO_25_I_POS (25U) +#define GLB_REG2_GPIO_25_I_LEN (1U) +#define GLB_REG2_GPIO_25_I_MSK (((1U << GLB_REG2_GPIO_25_I_LEN) - 1) << GLB_REG2_GPIO_25_I_POS) +#define GLB_REG2_GPIO_25_I_UMSK (~(((1U << GLB_REG2_GPIO_25_I_LEN) - 1) << GLB_REG2_GPIO_25_I_POS)) +#define GLB_REG2_GPIO_26_I GLB_REG2_GPIO_26_I +#define GLB_REG2_GPIO_26_I_POS (26U) +#define GLB_REG2_GPIO_26_I_LEN (1U) +#define GLB_REG2_GPIO_26_I_MSK (((1U << GLB_REG2_GPIO_26_I_LEN) - 1) << GLB_REG2_GPIO_26_I_POS) +#define GLB_REG2_GPIO_26_I_UMSK (~(((1U << GLB_REG2_GPIO_26_I_LEN) - 1) << GLB_REG2_GPIO_26_I_POS)) +#define GLB_REG2_GPIO_27_I GLB_REG2_GPIO_27_I +#define GLB_REG2_GPIO_27_I_POS (27U) +#define GLB_REG2_GPIO_27_I_LEN (1U) +#define GLB_REG2_GPIO_27_I_MSK (((1U << GLB_REG2_GPIO_27_I_LEN) - 1) << GLB_REG2_GPIO_27_I_POS) +#define GLB_REG2_GPIO_27_I_UMSK (~(((1U << GLB_REG2_GPIO_27_I_LEN) - 1) << GLB_REG2_GPIO_27_I_POS)) +#define GLB_REG2_GPIO_28_I GLB_REG2_GPIO_28_I +#define GLB_REG2_GPIO_28_I_POS (28U) +#define GLB_REG2_GPIO_28_I_LEN (1U) +#define GLB_REG2_GPIO_28_I_MSK (((1U << GLB_REG2_GPIO_28_I_LEN) - 1) << GLB_REG2_GPIO_28_I_POS) +#define GLB_REG2_GPIO_28_I_UMSK (~(((1U << GLB_REG2_GPIO_28_I_LEN) - 1) << GLB_REG2_GPIO_28_I_POS)) +#define GLB_REG2_GPIO_29_I GLB_REG2_GPIO_29_I +#define GLB_REG2_GPIO_29_I_POS (29U) +#define GLB_REG2_GPIO_29_I_LEN (1U) +#define GLB_REG2_GPIO_29_I_MSK (((1U << GLB_REG2_GPIO_29_I_LEN) - 1) << GLB_REG2_GPIO_29_I_POS) +#define GLB_REG2_GPIO_29_I_UMSK (~(((1U << GLB_REG2_GPIO_29_I_LEN) - 1) << GLB_REG2_GPIO_29_I_POS)) +#define GLB_REG2_GPIO_30_I GLB_REG2_GPIO_30_I +#define GLB_REG2_GPIO_30_I_POS (30U) +#define GLB_REG2_GPIO_30_I_LEN (1U) +#define GLB_REG2_GPIO_30_I_MSK (((1U << GLB_REG2_GPIO_30_I_LEN) - 1) << GLB_REG2_GPIO_30_I_POS) +#define GLB_REG2_GPIO_30_I_UMSK (~(((1U << GLB_REG2_GPIO_30_I_LEN) - 1) << GLB_REG2_GPIO_30_I_POS)) +#define GLB_REG2_GPIO_31_I GLB_REG2_GPIO_31_I +#define GLB_REG2_GPIO_31_I_POS (31U) +#define GLB_REG2_GPIO_31_I_LEN (1U) +#define GLB_REG2_GPIO_31_I_MSK (((1U << GLB_REG2_GPIO_31_I_LEN) - 1) << GLB_REG2_GPIO_31_I_POS) +#define GLB_REG2_GPIO_31_I_UMSK (~(((1U << GLB_REG2_GPIO_31_I_LEN) - 1) << GLB_REG2_GPIO_31_I_POS)) + +/* 0xAC8 : gpio_cfg129 */ +#define GLB_GPIO_CFG129_OFFSET (0xAC8) +#define GLB_REG2_GPIO_32_I GLB_REG2_GPIO_32_I +#define GLB_REG2_GPIO_32_I_POS (0U) +#define GLB_REG2_GPIO_32_I_LEN (1U) +#define GLB_REG2_GPIO_32_I_MSK (((1U << GLB_REG2_GPIO_32_I_LEN) - 1) << GLB_REG2_GPIO_32_I_POS) +#define GLB_REG2_GPIO_32_I_UMSK (~(((1U << GLB_REG2_GPIO_32_I_LEN) - 1) << GLB_REG2_GPIO_32_I_POS)) +#define GLB_REG2_GPIO_33_I GLB_REG2_GPIO_33_I +#define GLB_REG2_GPIO_33_I_POS (1U) +#define GLB_REG2_GPIO_33_I_LEN (1U) +#define GLB_REG2_GPIO_33_I_MSK (((1U << GLB_REG2_GPIO_33_I_LEN) - 1) << GLB_REG2_GPIO_33_I_POS) +#define GLB_REG2_GPIO_33_I_UMSK (~(((1U << GLB_REG2_GPIO_33_I_LEN) - 1) << GLB_REG2_GPIO_33_I_POS)) +#define GLB_REG2_GPIO_34_I GLB_REG2_GPIO_34_I +#define GLB_REG2_GPIO_34_I_POS (2U) +#define GLB_REG2_GPIO_34_I_LEN (1U) +#define GLB_REG2_GPIO_34_I_MSK (((1U << GLB_REG2_GPIO_34_I_LEN) - 1) << GLB_REG2_GPIO_34_I_POS) +#define GLB_REG2_GPIO_34_I_UMSK (~(((1U << GLB_REG2_GPIO_34_I_LEN) - 1) << GLB_REG2_GPIO_34_I_POS)) +#define GLB_REG2_GPIO_35_I GLB_REG2_GPIO_35_I +#define GLB_REG2_GPIO_35_I_POS (3U) +#define GLB_REG2_GPIO_35_I_LEN (1U) +#define GLB_REG2_GPIO_35_I_MSK (((1U << GLB_REG2_GPIO_35_I_LEN) - 1) << GLB_REG2_GPIO_35_I_POS) +#define GLB_REG2_GPIO_35_I_UMSK (~(((1U << GLB_REG2_GPIO_35_I_LEN) - 1) << GLB_REG2_GPIO_35_I_POS)) +#define GLB_REG2_GPIO_36_I GLB_REG2_GPIO_36_I +#define GLB_REG2_GPIO_36_I_POS (4U) +#define GLB_REG2_GPIO_36_I_LEN (1U) +#define GLB_REG2_GPIO_36_I_MSK (((1U << GLB_REG2_GPIO_36_I_LEN) - 1) << GLB_REG2_GPIO_36_I_POS) +#define GLB_REG2_GPIO_36_I_UMSK (~(((1U << GLB_REG2_GPIO_36_I_LEN) - 1) << GLB_REG2_GPIO_36_I_POS)) +#define GLB_REG2_GPIO_37_I GLB_REG2_GPIO_37_I +#define GLB_REG2_GPIO_37_I_POS (5U) +#define GLB_REG2_GPIO_37_I_LEN (1U) +#define GLB_REG2_GPIO_37_I_MSK (((1U << GLB_REG2_GPIO_37_I_LEN) - 1) << GLB_REG2_GPIO_37_I_POS) +#define GLB_REG2_GPIO_37_I_UMSK (~(((1U << GLB_REG2_GPIO_37_I_LEN) - 1) << GLB_REG2_GPIO_37_I_POS)) +#define GLB_REG2_GPIO_38_I GLB_REG2_GPIO_38_I +#define GLB_REG2_GPIO_38_I_POS (6U) +#define GLB_REG2_GPIO_38_I_LEN (1U) +#define GLB_REG2_GPIO_38_I_MSK (((1U << GLB_REG2_GPIO_38_I_LEN) - 1) << GLB_REG2_GPIO_38_I_POS) +#define GLB_REG2_GPIO_38_I_UMSK (~(((1U << GLB_REG2_GPIO_38_I_LEN) - 1) << GLB_REG2_GPIO_38_I_POS)) +#define GLB_REG2_GPIO_39_I GLB_REG2_GPIO_39_I +#define GLB_REG2_GPIO_39_I_POS (7U) +#define GLB_REG2_GPIO_39_I_LEN (1U) +#define GLB_REG2_GPIO_39_I_MSK (((1U << GLB_REG2_GPIO_39_I_LEN) - 1) << GLB_REG2_GPIO_39_I_POS) +#define GLB_REG2_GPIO_39_I_UMSK (~(((1U << GLB_REG2_GPIO_39_I_LEN) - 1) << GLB_REG2_GPIO_39_I_POS)) +#define GLB_REG2_GPIO_40_I GLB_REG2_GPIO_40_I +#define GLB_REG2_GPIO_40_I_POS (8U) +#define GLB_REG2_GPIO_40_I_LEN (1U) +#define GLB_REG2_GPIO_40_I_MSK (((1U << GLB_REG2_GPIO_40_I_LEN) - 1) << GLB_REG2_GPIO_40_I_POS) +#define GLB_REG2_GPIO_40_I_UMSK (~(((1U << GLB_REG2_GPIO_40_I_LEN) - 1) << GLB_REG2_GPIO_40_I_POS)) +#define GLB_REG2_GPIO_41_I GLB_REG2_GPIO_41_I +#define GLB_REG2_GPIO_41_I_POS (9U) +#define GLB_REG2_GPIO_41_I_LEN (1U) +#define GLB_REG2_GPIO_41_I_MSK (((1U << GLB_REG2_GPIO_41_I_LEN) - 1) << GLB_REG2_GPIO_41_I_POS) +#define GLB_REG2_GPIO_41_I_UMSK (~(((1U << GLB_REG2_GPIO_41_I_LEN) - 1) << GLB_REG2_GPIO_41_I_POS)) +#define GLB_REG2_GPIO_42_I GLB_REG2_GPIO_42_I +#define GLB_REG2_GPIO_42_I_POS (10U) +#define GLB_REG2_GPIO_42_I_LEN (1U) +#define GLB_REG2_GPIO_42_I_MSK (((1U << GLB_REG2_GPIO_42_I_LEN) - 1) << GLB_REG2_GPIO_42_I_POS) +#define GLB_REG2_GPIO_42_I_UMSK (~(((1U << GLB_REG2_GPIO_42_I_LEN) - 1) << GLB_REG2_GPIO_42_I_POS)) +#define GLB_REG2_GPIO_43_I GLB_REG2_GPIO_43_I +#define GLB_REG2_GPIO_43_I_POS (11U) +#define GLB_REG2_GPIO_43_I_LEN (1U) +#define GLB_REG2_GPIO_43_I_MSK (((1U << GLB_REG2_GPIO_43_I_LEN) - 1) << GLB_REG2_GPIO_43_I_POS) +#define GLB_REG2_GPIO_43_I_UMSK (~(((1U << GLB_REG2_GPIO_43_I_LEN) - 1) << GLB_REG2_GPIO_43_I_POS)) +#define GLB_REG2_GPIO_44_I GLB_REG2_GPIO_44_I +#define GLB_REG2_GPIO_44_I_POS (12U) +#define GLB_REG2_GPIO_44_I_LEN (1U) +#define GLB_REG2_GPIO_44_I_MSK (((1U << GLB_REG2_GPIO_44_I_LEN) - 1) << GLB_REG2_GPIO_44_I_POS) +#define GLB_REG2_GPIO_44_I_UMSK (~(((1U << GLB_REG2_GPIO_44_I_LEN) - 1) << GLB_REG2_GPIO_44_I_POS)) +#define GLB_REG2_GPIO_45_I GLB_REG2_GPIO_45_I +#define GLB_REG2_GPIO_45_I_POS (13U) +#define GLB_REG2_GPIO_45_I_LEN (1U) +#define GLB_REG2_GPIO_45_I_MSK (((1U << GLB_REG2_GPIO_45_I_LEN) - 1) << GLB_REG2_GPIO_45_I_POS) +#define GLB_REG2_GPIO_45_I_UMSK (~(((1U << GLB_REG2_GPIO_45_I_LEN) - 1) << GLB_REG2_GPIO_45_I_POS)) + +/* 0xAE4 : gpio_cfg136 */ +#define GLB_GPIO_CFG136_OFFSET (0xAE4) +#define GLB_REG2_GPIO_0_O GLB_REG2_GPIO_0_O +#define GLB_REG2_GPIO_0_O_POS (0U) +#define GLB_REG2_GPIO_0_O_LEN (1U) +#define GLB_REG2_GPIO_0_O_MSK (((1U << GLB_REG2_GPIO_0_O_LEN) - 1) << GLB_REG2_GPIO_0_O_POS) +#define GLB_REG2_GPIO_0_O_UMSK (~(((1U << GLB_REG2_GPIO_0_O_LEN) - 1) << GLB_REG2_GPIO_0_O_POS)) +#define GLB_REG2_GPIO_1_O GLB_REG2_GPIO_1_O +#define GLB_REG2_GPIO_1_O_POS (1U) +#define GLB_REG2_GPIO_1_O_LEN (1U) +#define GLB_REG2_GPIO_1_O_MSK (((1U << GLB_REG2_GPIO_1_O_LEN) - 1) << GLB_REG2_GPIO_1_O_POS) +#define GLB_REG2_GPIO_1_O_UMSK (~(((1U << GLB_REG2_GPIO_1_O_LEN) - 1) << GLB_REG2_GPIO_1_O_POS)) +#define GLB_REG2_GPIO_2_O GLB_REG2_GPIO_2_O +#define GLB_REG2_GPIO_2_O_POS (2U) +#define GLB_REG2_GPIO_2_O_LEN (1U) +#define GLB_REG2_GPIO_2_O_MSK (((1U << GLB_REG2_GPIO_2_O_LEN) - 1) << GLB_REG2_GPIO_2_O_POS) +#define GLB_REG2_GPIO_2_O_UMSK (~(((1U << GLB_REG2_GPIO_2_O_LEN) - 1) << GLB_REG2_GPIO_2_O_POS)) +#define GLB_REG2_GPIO_3_O GLB_REG2_GPIO_3_O +#define GLB_REG2_GPIO_3_O_POS (3U) +#define GLB_REG2_GPIO_3_O_LEN (1U) +#define GLB_REG2_GPIO_3_O_MSK (((1U << GLB_REG2_GPIO_3_O_LEN) - 1) << GLB_REG2_GPIO_3_O_POS) +#define GLB_REG2_GPIO_3_O_UMSK (~(((1U << GLB_REG2_GPIO_3_O_LEN) - 1) << GLB_REG2_GPIO_3_O_POS)) +#define GLB_REG2_GPIO_4_O GLB_REG2_GPIO_4_O +#define GLB_REG2_GPIO_4_O_POS (4U) +#define GLB_REG2_GPIO_4_O_LEN (1U) +#define GLB_REG2_GPIO_4_O_MSK (((1U << GLB_REG2_GPIO_4_O_LEN) - 1) << GLB_REG2_GPIO_4_O_POS) +#define GLB_REG2_GPIO_4_O_UMSK (~(((1U << GLB_REG2_GPIO_4_O_LEN) - 1) << GLB_REG2_GPIO_4_O_POS)) +#define GLB_REG2_GPIO_5_O GLB_REG2_GPIO_5_O +#define GLB_REG2_GPIO_5_O_POS (5U) +#define GLB_REG2_GPIO_5_O_LEN (1U) +#define GLB_REG2_GPIO_5_O_MSK (((1U << GLB_REG2_GPIO_5_O_LEN) - 1) << GLB_REG2_GPIO_5_O_POS) +#define GLB_REG2_GPIO_5_O_UMSK (~(((1U << GLB_REG2_GPIO_5_O_LEN) - 1) << GLB_REG2_GPIO_5_O_POS)) +#define GLB_REG2_GPIO_6_O GLB_REG2_GPIO_6_O +#define GLB_REG2_GPIO_6_O_POS (6U) +#define GLB_REG2_GPIO_6_O_LEN (1U) +#define GLB_REG2_GPIO_6_O_MSK (((1U << GLB_REG2_GPIO_6_O_LEN) - 1) << GLB_REG2_GPIO_6_O_POS) +#define GLB_REG2_GPIO_6_O_UMSK (~(((1U << GLB_REG2_GPIO_6_O_LEN) - 1) << GLB_REG2_GPIO_6_O_POS)) +#define GLB_REG2_GPIO_7_O GLB_REG2_GPIO_7_O +#define GLB_REG2_GPIO_7_O_POS (7U) +#define GLB_REG2_GPIO_7_O_LEN (1U) +#define GLB_REG2_GPIO_7_O_MSK (((1U << GLB_REG2_GPIO_7_O_LEN) - 1) << GLB_REG2_GPIO_7_O_POS) +#define GLB_REG2_GPIO_7_O_UMSK (~(((1U << GLB_REG2_GPIO_7_O_LEN) - 1) << GLB_REG2_GPIO_7_O_POS)) +#define GLB_REG2_GPIO_8_O GLB_REG2_GPIO_8_O +#define GLB_REG2_GPIO_8_O_POS (8U) +#define GLB_REG2_GPIO_8_O_LEN (1U) +#define GLB_REG2_GPIO_8_O_MSK (((1U << GLB_REG2_GPIO_8_O_LEN) - 1) << GLB_REG2_GPIO_8_O_POS) +#define GLB_REG2_GPIO_8_O_UMSK (~(((1U << GLB_REG2_GPIO_8_O_LEN) - 1) << GLB_REG2_GPIO_8_O_POS)) +#define GLB_REG2_GPIO_9_O GLB_REG2_GPIO_9_O +#define GLB_REG2_GPIO_9_O_POS (9U) +#define GLB_REG2_GPIO_9_O_LEN (1U) +#define GLB_REG2_GPIO_9_O_MSK (((1U << GLB_REG2_GPIO_9_O_LEN) - 1) << GLB_REG2_GPIO_9_O_POS) +#define GLB_REG2_GPIO_9_O_UMSK (~(((1U << GLB_REG2_GPIO_9_O_LEN) - 1) << GLB_REG2_GPIO_9_O_POS)) +#define GLB_REG2_GPIO_10_O GLB_REG2_GPIO_10_O +#define GLB_REG2_GPIO_10_O_POS (10U) +#define GLB_REG2_GPIO_10_O_LEN (1U) +#define GLB_REG2_GPIO_10_O_MSK (((1U << GLB_REG2_GPIO_10_O_LEN) - 1) << GLB_REG2_GPIO_10_O_POS) +#define GLB_REG2_GPIO_10_O_UMSK (~(((1U << GLB_REG2_GPIO_10_O_LEN) - 1) << GLB_REG2_GPIO_10_O_POS)) +#define GLB_REG2_GPIO_11_O GLB_REG2_GPIO_11_O +#define GLB_REG2_GPIO_11_O_POS (11U) +#define GLB_REG2_GPIO_11_O_LEN (1U) +#define GLB_REG2_GPIO_11_O_MSK (((1U << GLB_REG2_GPIO_11_O_LEN) - 1) << GLB_REG2_GPIO_11_O_POS) +#define GLB_REG2_GPIO_11_O_UMSK (~(((1U << GLB_REG2_GPIO_11_O_LEN) - 1) << GLB_REG2_GPIO_11_O_POS)) +#define GLB_REG2_GPIO_12_O GLB_REG2_GPIO_12_O +#define GLB_REG2_GPIO_12_O_POS (12U) +#define GLB_REG2_GPIO_12_O_LEN (1U) +#define GLB_REG2_GPIO_12_O_MSK (((1U << GLB_REG2_GPIO_12_O_LEN) - 1) << GLB_REG2_GPIO_12_O_POS) +#define GLB_REG2_GPIO_12_O_UMSK (~(((1U << GLB_REG2_GPIO_12_O_LEN) - 1) << GLB_REG2_GPIO_12_O_POS)) +#define GLB_REG2_GPIO_13_O GLB_REG2_GPIO_13_O +#define GLB_REG2_GPIO_13_O_POS (13U) +#define GLB_REG2_GPIO_13_O_LEN (1U) +#define GLB_REG2_GPIO_13_O_MSK (((1U << GLB_REG2_GPIO_13_O_LEN) - 1) << GLB_REG2_GPIO_13_O_POS) +#define GLB_REG2_GPIO_13_O_UMSK (~(((1U << GLB_REG2_GPIO_13_O_LEN) - 1) << GLB_REG2_GPIO_13_O_POS)) +#define GLB_REG2_GPIO_14_O GLB_REG2_GPIO_14_O +#define GLB_REG2_GPIO_14_O_POS (14U) +#define GLB_REG2_GPIO_14_O_LEN (1U) +#define GLB_REG2_GPIO_14_O_MSK (((1U << GLB_REG2_GPIO_14_O_LEN) - 1) << GLB_REG2_GPIO_14_O_POS) +#define GLB_REG2_GPIO_14_O_UMSK (~(((1U << GLB_REG2_GPIO_14_O_LEN) - 1) << GLB_REG2_GPIO_14_O_POS)) +#define GLB_REG2_GPIO_15_O GLB_REG2_GPIO_15_O +#define GLB_REG2_GPIO_15_O_POS (15U) +#define GLB_REG2_GPIO_15_O_LEN (1U) +#define GLB_REG2_GPIO_15_O_MSK (((1U << GLB_REG2_GPIO_15_O_LEN) - 1) << GLB_REG2_GPIO_15_O_POS) +#define GLB_REG2_GPIO_15_O_UMSK (~(((1U << GLB_REG2_GPIO_15_O_LEN) - 1) << GLB_REG2_GPIO_15_O_POS)) +#define GLB_REG2_GPIO_16_O GLB_REG2_GPIO_16_O +#define GLB_REG2_GPIO_16_O_POS (16U) +#define GLB_REG2_GPIO_16_O_LEN (1U) +#define GLB_REG2_GPIO_16_O_MSK (((1U << GLB_REG2_GPIO_16_O_LEN) - 1) << GLB_REG2_GPIO_16_O_POS) +#define GLB_REG2_GPIO_16_O_UMSK (~(((1U << GLB_REG2_GPIO_16_O_LEN) - 1) << GLB_REG2_GPIO_16_O_POS)) +#define GLB_REG2_GPIO_17_O GLB_REG2_GPIO_17_O +#define GLB_REG2_GPIO_17_O_POS (17U) +#define GLB_REG2_GPIO_17_O_LEN (1U) +#define GLB_REG2_GPIO_17_O_MSK (((1U << GLB_REG2_GPIO_17_O_LEN) - 1) << GLB_REG2_GPIO_17_O_POS) +#define GLB_REG2_GPIO_17_O_UMSK (~(((1U << GLB_REG2_GPIO_17_O_LEN) - 1) << GLB_REG2_GPIO_17_O_POS)) +#define GLB_REG2_GPIO_18_O GLB_REG2_GPIO_18_O +#define GLB_REG2_GPIO_18_O_POS (18U) +#define GLB_REG2_GPIO_18_O_LEN (1U) +#define GLB_REG2_GPIO_18_O_MSK (((1U << GLB_REG2_GPIO_18_O_LEN) - 1) << GLB_REG2_GPIO_18_O_POS) +#define GLB_REG2_GPIO_18_O_UMSK (~(((1U << GLB_REG2_GPIO_18_O_LEN) - 1) << GLB_REG2_GPIO_18_O_POS)) +#define GLB_REG2_GPIO_19_O GLB_REG2_GPIO_19_O +#define GLB_REG2_GPIO_19_O_POS (19U) +#define GLB_REG2_GPIO_19_O_LEN (1U) +#define GLB_REG2_GPIO_19_O_MSK (((1U << GLB_REG2_GPIO_19_O_LEN) - 1) << GLB_REG2_GPIO_19_O_POS) +#define GLB_REG2_GPIO_19_O_UMSK (~(((1U << GLB_REG2_GPIO_19_O_LEN) - 1) << GLB_REG2_GPIO_19_O_POS)) +#define GLB_REG2_GPIO_20_O GLB_REG2_GPIO_20_O +#define GLB_REG2_GPIO_20_O_POS (20U) +#define GLB_REG2_GPIO_20_O_LEN (1U) +#define GLB_REG2_GPIO_20_O_MSK (((1U << GLB_REG2_GPIO_20_O_LEN) - 1) << GLB_REG2_GPIO_20_O_POS) +#define GLB_REG2_GPIO_20_O_UMSK (~(((1U << GLB_REG2_GPIO_20_O_LEN) - 1) << GLB_REG2_GPIO_20_O_POS)) +#define GLB_REG2_GPIO_21_O GLB_REG2_GPIO_21_O +#define GLB_REG2_GPIO_21_O_POS (21U) +#define GLB_REG2_GPIO_21_O_LEN (1U) +#define GLB_REG2_GPIO_21_O_MSK (((1U << GLB_REG2_GPIO_21_O_LEN) - 1) << GLB_REG2_GPIO_21_O_POS) +#define GLB_REG2_GPIO_21_O_UMSK (~(((1U << GLB_REG2_GPIO_21_O_LEN) - 1) << GLB_REG2_GPIO_21_O_POS)) +#define GLB_REG2_GPIO_22_O GLB_REG2_GPIO_22_O +#define GLB_REG2_GPIO_22_O_POS (22U) +#define GLB_REG2_GPIO_22_O_LEN (1U) +#define GLB_REG2_GPIO_22_O_MSK (((1U << GLB_REG2_GPIO_22_O_LEN) - 1) << GLB_REG2_GPIO_22_O_POS) +#define GLB_REG2_GPIO_22_O_UMSK (~(((1U << GLB_REG2_GPIO_22_O_LEN) - 1) << GLB_REG2_GPIO_22_O_POS)) +#define GLB_REG2_GPIO_23_O GLB_REG2_GPIO_23_O +#define GLB_REG2_GPIO_23_O_POS (23U) +#define GLB_REG2_GPIO_23_O_LEN (1U) +#define GLB_REG2_GPIO_23_O_MSK (((1U << GLB_REG2_GPIO_23_O_LEN) - 1) << GLB_REG2_GPIO_23_O_POS) +#define GLB_REG2_GPIO_23_O_UMSK (~(((1U << GLB_REG2_GPIO_23_O_LEN) - 1) << GLB_REG2_GPIO_23_O_POS)) +#define GLB_REG2_GPIO_24_O GLB_REG2_GPIO_24_O +#define GLB_REG2_GPIO_24_O_POS (24U) +#define GLB_REG2_GPIO_24_O_LEN (1U) +#define GLB_REG2_GPIO_24_O_MSK (((1U << GLB_REG2_GPIO_24_O_LEN) - 1) << GLB_REG2_GPIO_24_O_POS) +#define GLB_REG2_GPIO_24_O_UMSK (~(((1U << GLB_REG2_GPIO_24_O_LEN) - 1) << GLB_REG2_GPIO_24_O_POS)) +#define GLB_REG2_GPIO_25_O GLB_REG2_GPIO_25_O +#define GLB_REG2_GPIO_25_O_POS (25U) +#define GLB_REG2_GPIO_25_O_LEN (1U) +#define GLB_REG2_GPIO_25_O_MSK (((1U << GLB_REG2_GPIO_25_O_LEN) - 1) << GLB_REG2_GPIO_25_O_POS) +#define GLB_REG2_GPIO_25_O_UMSK (~(((1U << GLB_REG2_GPIO_25_O_LEN) - 1) << GLB_REG2_GPIO_25_O_POS)) +#define GLB_REG2_GPIO_26_O GLB_REG2_GPIO_26_O +#define GLB_REG2_GPIO_26_O_POS (26U) +#define GLB_REG2_GPIO_26_O_LEN (1U) +#define GLB_REG2_GPIO_26_O_MSK (((1U << GLB_REG2_GPIO_26_O_LEN) - 1) << GLB_REG2_GPIO_26_O_POS) +#define GLB_REG2_GPIO_26_O_UMSK (~(((1U << GLB_REG2_GPIO_26_O_LEN) - 1) << GLB_REG2_GPIO_26_O_POS)) +#define GLB_REG2_GPIO_27_O GLB_REG2_GPIO_27_O +#define GLB_REG2_GPIO_27_O_POS (27U) +#define GLB_REG2_GPIO_27_O_LEN (1U) +#define GLB_REG2_GPIO_27_O_MSK (((1U << GLB_REG2_GPIO_27_O_LEN) - 1) << GLB_REG2_GPIO_27_O_POS) +#define GLB_REG2_GPIO_27_O_UMSK (~(((1U << GLB_REG2_GPIO_27_O_LEN) - 1) << GLB_REG2_GPIO_27_O_POS)) +#define GLB_REG2_GPIO_28_O GLB_REG2_GPIO_28_O +#define GLB_REG2_GPIO_28_O_POS (28U) +#define GLB_REG2_GPIO_28_O_LEN (1U) +#define GLB_REG2_GPIO_28_O_MSK (((1U << GLB_REG2_GPIO_28_O_LEN) - 1) << GLB_REG2_GPIO_28_O_POS) +#define GLB_REG2_GPIO_28_O_UMSK (~(((1U << GLB_REG2_GPIO_28_O_LEN) - 1) << GLB_REG2_GPIO_28_O_POS)) +#define GLB_REG2_GPIO_29_O GLB_REG2_GPIO_29_O +#define GLB_REG2_GPIO_29_O_POS (29U) +#define GLB_REG2_GPIO_29_O_LEN (1U) +#define GLB_REG2_GPIO_29_O_MSK (((1U << GLB_REG2_GPIO_29_O_LEN) - 1) << GLB_REG2_GPIO_29_O_POS) +#define GLB_REG2_GPIO_29_O_UMSK (~(((1U << GLB_REG2_GPIO_29_O_LEN) - 1) << GLB_REG2_GPIO_29_O_POS)) +#define GLB_REG2_GPIO_30_O GLB_REG2_GPIO_30_O +#define GLB_REG2_GPIO_30_O_POS (30U) +#define GLB_REG2_GPIO_30_O_LEN (1U) +#define GLB_REG2_GPIO_30_O_MSK (((1U << GLB_REG2_GPIO_30_O_LEN) - 1) << GLB_REG2_GPIO_30_O_POS) +#define GLB_REG2_GPIO_30_O_UMSK (~(((1U << GLB_REG2_GPIO_30_O_LEN) - 1) << GLB_REG2_GPIO_30_O_POS)) +#define GLB_REG2_GPIO_31_O GLB_REG2_GPIO_31_O +#define GLB_REG2_GPIO_31_O_POS (31U) +#define GLB_REG2_GPIO_31_O_LEN (1U) +#define GLB_REG2_GPIO_31_O_MSK (((1U << GLB_REG2_GPIO_31_O_LEN) - 1) << GLB_REG2_GPIO_31_O_POS) +#define GLB_REG2_GPIO_31_O_UMSK (~(((1U << GLB_REG2_GPIO_31_O_LEN) - 1) << GLB_REG2_GPIO_31_O_POS)) + +/* 0xAE8 : gpio_cfg137 */ +#define GLB_GPIO_CFG137_OFFSET (0xAE8) +#define GLB_REG2_GPIO_32_O GLB_REG2_GPIO_32_O +#define GLB_REG2_GPIO_32_O_POS (0U) +#define GLB_REG2_GPIO_32_O_LEN (1U) +#define GLB_REG2_GPIO_32_O_MSK (((1U << GLB_REG2_GPIO_32_O_LEN) - 1) << GLB_REG2_GPIO_32_O_POS) +#define GLB_REG2_GPIO_32_O_UMSK (~(((1U << GLB_REG2_GPIO_32_O_LEN) - 1) << GLB_REG2_GPIO_32_O_POS)) +#define GLB_REG2_GPIO_33_O GLB_REG2_GPIO_33_O +#define GLB_REG2_GPIO_33_O_POS (1U) +#define GLB_REG2_GPIO_33_O_LEN (1U) +#define GLB_REG2_GPIO_33_O_MSK (((1U << GLB_REG2_GPIO_33_O_LEN) - 1) << GLB_REG2_GPIO_33_O_POS) +#define GLB_REG2_GPIO_33_O_UMSK (~(((1U << GLB_REG2_GPIO_33_O_LEN) - 1) << GLB_REG2_GPIO_33_O_POS)) +#define GLB_REG2_GPIO_34_O GLB_REG2_GPIO_34_O +#define GLB_REG2_GPIO_34_O_POS (2U) +#define GLB_REG2_GPIO_34_O_LEN (1U) +#define GLB_REG2_GPIO_34_O_MSK (((1U << GLB_REG2_GPIO_34_O_LEN) - 1) << GLB_REG2_GPIO_34_O_POS) +#define GLB_REG2_GPIO_34_O_UMSK (~(((1U << GLB_REG2_GPIO_34_O_LEN) - 1) << GLB_REG2_GPIO_34_O_POS)) +#define GLB_REG2_GPIO_35_O GLB_REG2_GPIO_35_O +#define GLB_REG2_GPIO_35_O_POS (3U) +#define GLB_REG2_GPIO_35_O_LEN (1U) +#define GLB_REG2_GPIO_35_O_MSK (((1U << GLB_REG2_GPIO_35_O_LEN) - 1) << GLB_REG2_GPIO_35_O_POS) +#define GLB_REG2_GPIO_35_O_UMSK (~(((1U << GLB_REG2_GPIO_35_O_LEN) - 1) << GLB_REG2_GPIO_35_O_POS)) +#define GLB_REG2_GPIO_36_O GLB_REG2_GPIO_36_O +#define GLB_REG2_GPIO_36_O_POS (4U) +#define GLB_REG2_GPIO_36_O_LEN (1U) +#define GLB_REG2_GPIO_36_O_MSK (((1U << GLB_REG2_GPIO_36_O_LEN) - 1) << GLB_REG2_GPIO_36_O_POS) +#define GLB_REG2_GPIO_36_O_UMSK (~(((1U << GLB_REG2_GPIO_36_O_LEN) - 1) << GLB_REG2_GPIO_36_O_POS)) +#define GLB_REG2_GPIO_37_O GLB_REG2_GPIO_37_O +#define GLB_REG2_GPIO_37_O_POS (5U) +#define GLB_REG2_GPIO_37_O_LEN (1U) +#define GLB_REG2_GPIO_37_O_MSK (((1U << GLB_REG2_GPIO_37_O_LEN) - 1) << GLB_REG2_GPIO_37_O_POS) +#define GLB_REG2_GPIO_37_O_UMSK (~(((1U << GLB_REG2_GPIO_37_O_LEN) - 1) << GLB_REG2_GPIO_37_O_POS)) +#define GLB_REG2_GPIO_38_O GLB_REG2_GPIO_38_O +#define GLB_REG2_GPIO_38_O_POS (6U) +#define GLB_REG2_GPIO_38_O_LEN (1U) +#define GLB_REG2_GPIO_38_O_MSK (((1U << GLB_REG2_GPIO_38_O_LEN) - 1) << GLB_REG2_GPIO_38_O_POS) +#define GLB_REG2_GPIO_38_O_UMSK (~(((1U << GLB_REG2_GPIO_38_O_LEN) - 1) << GLB_REG2_GPIO_38_O_POS)) +#define GLB_REG2_GPIO_39_O GLB_REG2_GPIO_39_O +#define GLB_REG2_GPIO_39_O_POS (7U) +#define GLB_REG2_GPIO_39_O_LEN (1U) +#define GLB_REG2_GPIO_39_O_MSK (((1U << GLB_REG2_GPIO_39_O_LEN) - 1) << GLB_REG2_GPIO_39_O_POS) +#define GLB_REG2_GPIO_39_O_UMSK (~(((1U << GLB_REG2_GPIO_39_O_LEN) - 1) << GLB_REG2_GPIO_39_O_POS)) +#define GLB_REG2_GPIO_40_O GLB_REG2_GPIO_40_O +#define GLB_REG2_GPIO_40_O_POS (8U) +#define GLB_REG2_GPIO_40_O_LEN (1U) +#define GLB_REG2_GPIO_40_O_MSK (((1U << GLB_REG2_GPIO_40_O_LEN) - 1) << GLB_REG2_GPIO_40_O_POS) +#define GLB_REG2_GPIO_40_O_UMSK (~(((1U << GLB_REG2_GPIO_40_O_LEN) - 1) << GLB_REG2_GPIO_40_O_POS)) +#define GLB_REG2_GPIO_41_O GLB_REG2_GPIO_41_O +#define GLB_REG2_GPIO_41_O_POS (9U) +#define GLB_REG2_GPIO_41_O_LEN (1U) +#define GLB_REG2_GPIO_41_O_MSK (((1U << GLB_REG2_GPIO_41_O_LEN) - 1) << GLB_REG2_GPIO_41_O_POS) +#define GLB_REG2_GPIO_41_O_UMSK (~(((1U << GLB_REG2_GPIO_41_O_LEN) - 1) << GLB_REG2_GPIO_41_O_POS)) +#define GLB_REG2_GPIO_42_O GLB_REG2_GPIO_42_O +#define GLB_REG2_GPIO_42_O_POS (10U) +#define GLB_REG2_GPIO_42_O_LEN (1U) +#define GLB_REG2_GPIO_42_O_MSK (((1U << GLB_REG2_GPIO_42_O_LEN) - 1) << GLB_REG2_GPIO_42_O_POS) +#define GLB_REG2_GPIO_42_O_UMSK (~(((1U << GLB_REG2_GPIO_42_O_LEN) - 1) << GLB_REG2_GPIO_42_O_POS)) +#define GLB_REG2_GPIO_43_O GLB_REG2_GPIO_43_O +#define GLB_REG2_GPIO_43_O_POS (11U) +#define GLB_REG2_GPIO_43_O_LEN (1U) +#define GLB_REG2_GPIO_43_O_MSK (((1U << GLB_REG2_GPIO_43_O_LEN) - 1) << GLB_REG2_GPIO_43_O_POS) +#define GLB_REG2_GPIO_43_O_UMSK (~(((1U << GLB_REG2_GPIO_43_O_LEN) - 1) << GLB_REG2_GPIO_43_O_POS)) +#define GLB_REG2_GPIO_44_O GLB_REG2_GPIO_44_O +#define GLB_REG2_GPIO_44_O_POS (12U) +#define GLB_REG2_GPIO_44_O_LEN (1U) +#define GLB_REG2_GPIO_44_O_MSK (((1U << GLB_REG2_GPIO_44_O_LEN) - 1) << GLB_REG2_GPIO_44_O_POS) +#define GLB_REG2_GPIO_44_O_UMSK (~(((1U << GLB_REG2_GPIO_44_O_LEN) - 1) << GLB_REG2_GPIO_44_O_POS)) +#define GLB_REG2_GPIO_45_O GLB_REG2_GPIO_45_O +#define GLB_REG2_GPIO_45_O_POS (13U) +#define GLB_REG2_GPIO_45_O_LEN (1U) +#define GLB_REG2_GPIO_45_O_MSK (((1U << GLB_REG2_GPIO_45_O_LEN) - 1) << GLB_REG2_GPIO_45_O_POS) +#define GLB_REG2_GPIO_45_O_UMSK (~(((1U << GLB_REG2_GPIO_45_O_LEN) - 1) << GLB_REG2_GPIO_45_O_POS)) + +/* 0xAEC : gpio_cfg138 */ +#define GLB_GPIO_CFG138_OFFSET (0xAEC) +#define GLB_REG2_GPIO_0_SET GLB_REG2_GPIO_0_SET +#define GLB_REG2_GPIO_0_SET_POS (0U) +#define GLB_REG2_GPIO_0_SET_LEN (1U) +#define GLB_REG2_GPIO_0_SET_MSK (((1U << GLB_REG2_GPIO_0_SET_LEN) - 1) << GLB_REG2_GPIO_0_SET_POS) +#define GLB_REG2_GPIO_0_SET_UMSK (~(((1U << GLB_REG2_GPIO_0_SET_LEN) - 1) << GLB_REG2_GPIO_0_SET_POS)) +#define GLB_REG2_GPIO_1_SET GLB_REG2_GPIO_1_SET +#define GLB_REG2_GPIO_1_SET_POS (1U) +#define GLB_REG2_GPIO_1_SET_LEN (1U) +#define GLB_REG2_GPIO_1_SET_MSK (((1U << GLB_REG2_GPIO_1_SET_LEN) - 1) << GLB_REG2_GPIO_1_SET_POS) +#define GLB_REG2_GPIO_1_SET_UMSK (~(((1U << GLB_REG2_GPIO_1_SET_LEN) - 1) << GLB_REG2_GPIO_1_SET_POS)) +#define GLB_REG2_GPIO_2_SET GLB_REG2_GPIO_2_SET +#define GLB_REG2_GPIO_2_SET_POS (2U) +#define GLB_REG2_GPIO_2_SET_LEN (1U) +#define GLB_REG2_GPIO_2_SET_MSK (((1U << GLB_REG2_GPIO_2_SET_LEN) - 1) << GLB_REG2_GPIO_2_SET_POS) +#define GLB_REG2_GPIO_2_SET_UMSK (~(((1U << GLB_REG2_GPIO_2_SET_LEN) - 1) << GLB_REG2_GPIO_2_SET_POS)) +#define GLB_REG2_GPIO_3_SET GLB_REG2_GPIO_3_SET +#define GLB_REG2_GPIO_3_SET_POS (3U) +#define GLB_REG2_GPIO_3_SET_LEN (1U) +#define GLB_REG2_GPIO_3_SET_MSK (((1U << GLB_REG2_GPIO_3_SET_LEN) - 1) << GLB_REG2_GPIO_3_SET_POS) +#define GLB_REG2_GPIO_3_SET_UMSK (~(((1U << GLB_REG2_GPIO_3_SET_LEN) - 1) << GLB_REG2_GPIO_3_SET_POS)) +#define GLB_REG2_GPIO_4_SET GLB_REG2_GPIO_4_SET +#define GLB_REG2_GPIO_4_SET_POS (4U) +#define GLB_REG2_GPIO_4_SET_LEN (1U) +#define GLB_REG2_GPIO_4_SET_MSK (((1U << GLB_REG2_GPIO_4_SET_LEN) - 1) << GLB_REG2_GPIO_4_SET_POS) +#define GLB_REG2_GPIO_4_SET_UMSK (~(((1U << GLB_REG2_GPIO_4_SET_LEN) - 1) << GLB_REG2_GPIO_4_SET_POS)) +#define GLB_REG2_GPIO_5_SET GLB_REG2_GPIO_5_SET +#define GLB_REG2_GPIO_5_SET_POS (5U) +#define GLB_REG2_GPIO_5_SET_LEN (1U) +#define GLB_REG2_GPIO_5_SET_MSK (((1U << GLB_REG2_GPIO_5_SET_LEN) - 1) << GLB_REG2_GPIO_5_SET_POS) +#define GLB_REG2_GPIO_5_SET_UMSK (~(((1U << GLB_REG2_GPIO_5_SET_LEN) - 1) << GLB_REG2_GPIO_5_SET_POS)) +#define GLB_REG2_GPIO_6_SET GLB_REG2_GPIO_6_SET +#define GLB_REG2_GPIO_6_SET_POS (6U) +#define GLB_REG2_GPIO_6_SET_LEN (1U) +#define GLB_REG2_GPIO_6_SET_MSK (((1U << GLB_REG2_GPIO_6_SET_LEN) - 1) << GLB_REG2_GPIO_6_SET_POS) +#define GLB_REG2_GPIO_6_SET_UMSK (~(((1U << GLB_REG2_GPIO_6_SET_LEN) - 1) << GLB_REG2_GPIO_6_SET_POS)) +#define GLB_REG2_GPIO_7_SET GLB_REG2_GPIO_7_SET +#define GLB_REG2_GPIO_7_SET_POS (7U) +#define GLB_REG2_GPIO_7_SET_LEN (1U) +#define GLB_REG2_GPIO_7_SET_MSK (((1U << GLB_REG2_GPIO_7_SET_LEN) - 1) << GLB_REG2_GPIO_7_SET_POS) +#define GLB_REG2_GPIO_7_SET_UMSK (~(((1U << GLB_REG2_GPIO_7_SET_LEN) - 1) << GLB_REG2_GPIO_7_SET_POS)) +#define GLB_REG2_GPIO_8_SET GLB_REG2_GPIO_8_SET +#define GLB_REG2_GPIO_8_SET_POS (8U) +#define GLB_REG2_GPIO_8_SET_LEN (1U) +#define GLB_REG2_GPIO_8_SET_MSK (((1U << GLB_REG2_GPIO_8_SET_LEN) - 1) << GLB_REG2_GPIO_8_SET_POS) +#define GLB_REG2_GPIO_8_SET_UMSK (~(((1U << GLB_REG2_GPIO_8_SET_LEN) - 1) << GLB_REG2_GPIO_8_SET_POS)) +#define GLB_REG2_GPIO_9_SET GLB_REG2_GPIO_9_SET +#define GLB_REG2_GPIO_9_SET_POS (9U) +#define GLB_REG2_GPIO_9_SET_LEN (1U) +#define GLB_REG2_GPIO_9_SET_MSK (((1U << GLB_REG2_GPIO_9_SET_LEN) - 1) << GLB_REG2_GPIO_9_SET_POS) +#define GLB_REG2_GPIO_9_SET_UMSK (~(((1U << GLB_REG2_GPIO_9_SET_LEN) - 1) << GLB_REG2_GPIO_9_SET_POS)) +#define GLB_REG2_GPIO_10_SET GLB_REG2_GPIO_10_SET +#define GLB_REG2_GPIO_10_SET_POS (10U) +#define GLB_REG2_GPIO_10_SET_LEN (1U) +#define GLB_REG2_GPIO_10_SET_MSK (((1U << GLB_REG2_GPIO_10_SET_LEN) - 1) << GLB_REG2_GPIO_10_SET_POS) +#define GLB_REG2_GPIO_10_SET_UMSK (~(((1U << GLB_REG2_GPIO_10_SET_LEN) - 1) << GLB_REG2_GPIO_10_SET_POS)) +#define GLB_REG2_GPIO_11_SET GLB_REG2_GPIO_11_SET +#define GLB_REG2_GPIO_11_SET_POS (11U) +#define GLB_REG2_GPIO_11_SET_LEN (1U) +#define GLB_REG2_GPIO_11_SET_MSK (((1U << GLB_REG2_GPIO_11_SET_LEN) - 1) << GLB_REG2_GPIO_11_SET_POS) +#define GLB_REG2_GPIO_11_SET_UMSK (~(((1U << GLB_REG2_GPIO_11_SET_LEN) - 1) << GLB_REG2_GPIO_11_SET_POS)) +#define GLB_REG2_GPIO_12_SET GLB_REG2_GPIO_12_SET +#define GLB_REG2_GPIO_12_SET_POS (12U) +#define GLB_REG2_GPIO_12_SET_LEN (1U) +#define GLB_REG2_GPIO_12_SET_MSK (((1U << GLB_REG2_GPIO_12_SET_LEN) - 1) << GLB_REG2_GPIO_12_SET_POS) +#define GLB_REG2_GPIO_12_SET_UMSK (~(((1U << GLB_REG2_GPIO_12_SET_LEN) - 1) << GLB_REG2_GPIO_12_SET_POS)) +#define GLB_REG2_GPIO_13_SET GLB_REG2_GPIO_13_SET +#define GLB_REG2_GPIO_13_SET_POS (13U) +#define GLB_REG2_GPIO_13_SET_LEN (1U) +#define GLB_REG2_GPIO_13_SET_MSK (((1U << GLB_REG2_GPIO_13_SET_LEN) - 1) << GLB_REG2_GPIO_13_SET_POS) +#define GLB_REG2_GPIO_13_SET_UMSK (~(((1U << GLB_REG2_GPIO_13_SET_LEN) - 1) << GLB_REG2_GPIO_13_SET_POS)) +#define GLB_REG2_GPIO_14_SET GLB_REG2_GPIO_14_SET +#define GLB_REG2_GPIO_14_SET_POS (14U) +#define GLB_REG2_GPIO_14_SET_LEN (1U) +#define GLB_REG2_GPIO_14_SET_MSK (((1U << GLB_REG2_GPIO_14_SET_LEN) - 1) << GLB_REG2_GPIO_14_SET_POS) +#define GLB_REG2_GPIO_14_SET_UMSK (~(((1U << GLB_REG2_GPIO_14_SET_LEN) - 1) << GLB_REG2_GPIO_14_SET_POS)) +#define GLB_REG2_GPIO_15_SET GLB_REG2_GPIO_15_SET +#define GLB_REG2_GPIO_15_SET_POS (15U) +#define GLB_REG2_GPIO_15_SET_LEN (1U) +#define GLB_REG2_GPIO_15_SET_MSK (((1U << GLB_REG2_GPIO_15_SET_LEN) - 1) << GLB_REG2_GPIO_15_SET_POS) +#define GLB_REG2_GPIO_15_SET_UMSK (~(((1U << GLB_REG2_GPIO_15_SET_LEN) - 1) << GLB_REG2_GPIO_15_SET_POS)) +#define GLB_REG2_GPIO_16_SET GLB_REG2_GPIO_16_SET +#define GLB_REG2_GPIO_16_SET_POS (16U) +#define GLB_REG2_GPIO_16_SET_LEN (1U) +#define GLB_REG2_GPIO_16_SET_MSK (((1U << GLB_REG2_GPIO_16_SET_LEN) - 1) << GLB_REG2_GPIO_16_SET_POS) +#define GLB_REG2_GPIO_16_SET_UMSK (~(((1U << GLB_REG2_GPIO_16_SET_LEN) - 1) << GLB_REG2_GPIO_16_SET_POS)) +#define GLB_REG2_GPIO_17_SET GLB_REG2_GPIO_17_SET +#define GLB_REG2_GPIO_17_SET_POS (17U) +#define GLB_REG2_GPIO_17_SET_LEN (1U) +#define GLB_REG2_GPIO_17_SET_MSK (((1U << GLB_REG2_GPIO_17_SET_LEN) - 1) << GLB_REG2_GPIO_17_SET_POS) +#define GLB_REG2_GPIO_17_SET_UMSK (~(((1U << GLB_REG2_GPIO_17_SET_LEN) - 1) << GLB_REG2_GPIO_17_SET_POS)) +#define GLB_REG2_GPIO_18_SET GLB_REG2_GPIO_18_SET +#define GLB_REG2_GPIO_18_SET_POS (18U) +#define GLB_REG2_GPIO_18_SET_LEN (1U) +#define GLB_REG2_GPIO_18_SET_MSK (((1U << GLB_REG2_GPIO_18_SET_LEN) - 1) << GLB_REG2_GPIO_18_SET_POS) +#define GLB_REG2_GPIO_18_SET_UMSK (~(((1U << GLB_REG2_GPIO_18_SET_LEN) - 1) << GLB_REG2_GPIO_18_SET_POS)) +#define GLB_REG2_GPIO_19_SET GLB_REG2_GPIO_19_SET +#define GLB_REG2_GPIO_19_SET_POS (19U) +#define GLB_REG2_GPIO_19_SET_LEN (1U) +#define GLB_REG2_GPIO_19_SET_MSK (((1U << GLB_REG2_GPIO_19_SET_LEN) - 1) << GLB_REG2_GPIO_19_SET_POS) +#define GLB_REG2_GPIO_19_SET_UMSK (~(((1U << GLB_REG2_GPIO_19_SET_LEN) - 1) << GLB_REG2_GPIO_19_SET_POS)) +#define GLB_REG2_GPIO_20_SET GLB_REG2_GPIO_20_SET +#define GLB_REG2_GPIO_20_SET_POS (20U) +#define GLB_REG2_GPIO_20_SET_LEN (1U) +#define GLB_REG2_GPIO_20_SET_MSK (((1U << GLB_REG2_GPIO_20_SET_LEN) - 1) << GLB_REG2_GPIO_20_SET_POS) +#define GLB_REG2_GPIO_20_SET_UMSK (~(((1U << GLB_REG2_GPIO_20_SET_LEN) - 1) << GLB_REG2_GPIO_20_SET_POS)) +#define GLB_REG2_GPIO_21_SET GLB_REG2_GPIO_21_SET +#define GLB_REG2_GPIO_21_SET_POS (21U) +#define GLB_REG2_GPIO_21_SET_LEN (1U) +#define GLB_REG2_GPIO_21_SET_MSK (((1U << GLB_REG2_GPIO_21_SET_LEN) - 1) << GLB_REG2_GPIO_21_SET_POS) +#define GLB_REG2_GPIO_21_SET_UMSK (~(((1U << GLB_REG2_GPIO_21_SET_LEN) - 1) << GLB_REG2_GPIO_21_SET_POS)) +#define GLB_REG2_GPIO_22_SET GLB_REG2_GPIO_22_SET +#define GLB_REG2_GPIO_22_SET_POS (22U) +#define GLB_REG2_GPIO_22_SET_LEN (1U) +#define GLB_REG2_GPIO_22_SET_MSK (((1U << GLB_REG2_GPIO_22_SET_LEN) - 1) << GLB_REG2_GPIO_22_SET_POS) +#define GLB_REG2_GPIO_22_SET_UMSK (~(((1U << GLB_REG2_GPIO_22_SET_LEN) - 1) << GLB_REG2_GPIO_22_SET_POS)) +#define GLB_REG2_GPIO_23_SET GLB_REG2_GPIO_23_SET +#define GLB_REG2_GPIO_23_SET_POS (23U) +#define GLB_REG2_GPIO_23_SET_LEN (1U) +#define GLB_REG2_GPIO_23_SET_MSK (((1U << GLB_REG2_GPIO_23_SET_LEN) - 1) << GLB_REG2_GPIO_23_SET_POS) +#define GLB_REG2_GPIO_23_SET_UMSK (~(((1U << GLB_REG2_GPIO_23_SET_LEN) - 1) << GLB_REG2_GPIO_23_SET_POS)) +#define GLB_REG2_GPIO_24_SET GLB_REG2_GPIO_24_SET +#define GLB_REG2_GPIO_24_SET_POS (24U) +#define GLB_REG2_GPIO_24_SET_LEN (1U) +#define GLB_REG2_GPIO_24_SET_MSK (((1U << GLB_REG2_GPIO_24_SET_LEN) - 1) << GLB_REG2_GPIO_24_SET_POS) +#define GLB_REG2_GPIO_24_SET_UMSK (~(((1U << GLB_REG2_GPIO_24_SET_LEN) - 1) << GLB_REG2_GPIO_24_SET_POS)) +#define GLB_REG2_GPIO_25_SET GLB_REG2_GPIO_25_SET +#define GLB_REG2_GPIO_25_SET_POS (25U) +#define GLB_REG2_GPIO_25_SET_LEN (1U) +#define GLB_REG2_GPIO_25_SET_MSK (((1U << GLB_REG2_GPIO_25_SET_LEN) - 1) << GLB_REG2_GPIO_25_SET_POS) +#define GLB_REG2_GPIO_25_SET_UMSK (~(((1U << GLB_REG2_GPIO_25_SET_LEN) - 1) << GLB_REG2_GPIO_25_SET_POS)) +#define GLB_REG2_GPIO_26_SET GLB_REG2_GPIO_26_SET +#define GLB_REG2_GPIO_26_SET_POS (26U) +#define GLB_REG2_GPIO_26_SET_LEN (1U) +#define GLB_REG2_GPIO_26_SET_MSK (((1U << GLB_REG2_GPIO_26_SET_LEN) - 1) << GLB_REG2_GPIO_26_SET_POS) +#define GLB_REG2_GPIO_26_SET_UMSK (~(((1U << GLB_REG2_GPIO_26_SET_LEN) - 1) << GLB_REG2_GPIO_26_SET_POS)) +#define GLB_REG2_GPIO_27_SET GLB_REG2_GPIO_27_SET +#define GLB_REG2_GPIO_27_SET_POS (27U) +#define GLB_REG2_GPIO_27_SET_LEN (1U) +#define GLB_REG2_GPIO_27_SET_MSK (((1U << GLB_REG2_GPIO_27_SET_LEN) - 1) << GLB_REG2_GPIO_27_SET_POS) +#define GLB_REG2_GPIO_27_SET_UMSK (~(((1U << GLB_REG2_GPIO_27_SET_LEN) - 1) << GLB_REG2_GPIO_27_SET_POS)) +#define GLB_REG2_GPIO_28_SET GLB_REG2_GPIO_28_SET +#define GLB_REG2_GPIO_28_SET_POS (28U) +#define GLB_REG2_GPIO_28_SET_LEN (1U) +#define GLB_REG2_GPIO_28_SET_MSK (((1U << GLB_REG2_GPIO_28_SET_LEN) - 1) << GLB_REG2_GPIO_28_SET_POS) +#define GLB_REG2_GPIO_28_SET_UMSK (~(((1U << GLB_REG2_GPIO_28_SET_LEN) - 1) << GLB_REG2_GPIO_28_SET_POS)) +#define GLB_REG2_GPIO_29_SET GLB_REG2_GPIO_29_SET +#define GLB_REG2_GPIO_29_SET_POS (29U) +#define GLB_REG2_GPIO_29_SET_LEN (1U) +#define GLB_REG2_GPIO_29_SET_MSK (((1U << GLB_REG2_GPIO_29_SET_LEN) - 1) << GLB_REG2_GPIO_29_SET_POS) +#define GLB_REG2_GPIO_29_SET_UMSK (~(((1U << GLB_REG2_GPIO_29_SET_LEN) - 1) << GLB_REG2_GPIO_29_SET_POS)) +#define GLB_REG2_GPIO_30_SET GLB_REG2_GPIO_30_SET +#define GLB_REG2_GPIO_30_SET_POS (30U) +#define GLB_REG2_GPIO_30_SET_LEN (1U) +#define GLB_REG2_GPIO_30_SET_MSK (((1U << GLB_REG2_GPIO_30_SET_LEN) - 1) << GLB_REG2_GPIO_30_SET_POS) +#define GLB_REG2_GPIO_30_SET_UMSK (~(((1U << GLB_REG2_GPIO_30_SET_LEN) - 1) << GLB_REG2_GPIO_30_SET_POS)) +#define GLB_REG2_GPIO_31_SET GLB_REG2_GPIO_31_SET +#define GLB_REG2_GPIO_31_SET_POS (31U) +#define GLB_REG2_GPIO_31_SET_LEN (1U) +#define GLB_REG2_GPIO_31_SET_MSK (((1U << GLB_REG2_GPIO_31_SET_LEN) - 1) << GLB_REG2_GPIO_31_SET_POS) +#define GLB_REG2_GPIO_31_SET_UMSK (~(((1U << GLB_REG2_GPIO_31_SET_LEN) - 1) << GLB_REG2_GPIO_31_SET_POS)) + +/* 0xAF0 : gpio_cfg139 */ +#define GLB_GPIO_CFG139_OFFSET (0xAF0) +#define GLB_REG2_GPIO_32_SET GLB_REG2_GPIO_32_SET +#define GLB_REG2_GPIO_32_SET_POS (0U) +#define GLB_REG2_GPIO_32_SET_LEN (1U) +#define GLB_REG2_GPIO_32_SET_MSK (((1U << GLB_REG2_GPIO_32_SET_LEN) - 1) << GLB_REG2_GPIO_32_SET_POS) +#define GLB_REG2_GPIO_32_SET_UMSK (~(((1U << GLB_REG2_GPIO_32_SET_LEN) - 1) << GLB_REG2_GPIO_32_SET_POS)) +#define GLB_REG2_GPIO_33_SET GLB_REG2_GPIO_33_SET +#define GLB_REG2_GPIO_33_SET_POS (1U) +#define GLB_REG2_GPIO_33_SET_LEN (1U) +#define GLB_REG2_GPIO_33_SET_MSK (((1U << GLB_REG2_GPIO_33_SET_LEN) - 1) << GLB_REG2_GPIO_33_SET_POS) +#define GLB_REG2_GPIO_33_SET_UMSK (~(((1U << GLB_REG2_GPIO_33_SET_LEN) - 1) << GLB_REG2_GPIO_33_SET_POS)) +#define GLB_REG2_GPIO_34_SET GLB_REG2_GPIO_34_SET +#define GLB_REG2_GPIO_34_SET_POS (2U) +#define GLB_REG2_GPIO_34_SET_LEN (1U) +#define GLB_REG2_GPIO_34_SET_MSK (((1U << GLB_REG2_GPIO_34_SET_LEN) - 1) << GLB_REG2_GPIO_34_SET_POS) +#define GLB_REG2_GPIO_34_SET_UMSK (~(((1U << GLB_REG2_GPIO_34_SET_LEN) - 1) << GLB_REG2_GPIO_34_SET_POS)) +#define GLB_REG2_GPIO_35_SET GLB_REG2_GPIO_35_SET +#define GLB_REG2_GPIO_35_SET_POS (3U) +#define GLB_REG2_GPIO_35_SET_LEN (1U) +#define GLB_REG2_GPIO_35_SET_MSK (((1U << GLB_REG2_GPIO_35_SET_LEN) - 1) << GLB_REG2_GPIO_35_SET_POS) +#define GLB_REG2_GPIO_35_SET_UMSK (~(((1U << GLB_REG2_GPIO_35_SET_LEN) - 1) << GLB_REG2_GPIO_35_SET_POS)) +#define GLB_REG2_GPIO_36_SET GLB_REG2_GPIO_36_SET +#define GLB_REG2_GPIO_36_SET_POS (4U) +#define GLB_REG2_GPIO_36_SET_LEN (1U) +#define GLB_REG2_GPIO_36_SET_MSK (((1U << GLB_REG2_GPIO_36_SET_LEN) - 1) << GLB_REG2_GPIO_36_SET_POS) +#define GLB_REG2_GPIO_36_SET_UMSK (~(((1U << GLB_REG2_GPIO_36_SET_LEN) - 1) << GLB_REG2_GPIO_36_SET_POS)) +#define GLB_REG2_GPIO_37_SET GLB_REG2_GPIO_37_SET +#define GLB_REG2_GPIO_37_SET_POS (5U) +#define GLB_REG2_GPIO_37_SET_LEN (1U) +#define GLB_REG2_GPIO_37_SET_MSK (((1U << GLB_REG2_GPIO_37_SET_LEN) - 1) << GLB_REG2_GPIO_37_SET_POS) +#define GLB_REG2_GPIO_37_SET_UMSK (~(((1U << GLB_REG2_GPIO_37_SET_LEN) - 1) << GLB_REG2_GPIO_37_SET_POS)) +#define GLB_REG2_GPIO_38_SET GLB_REG2_GPIO_38_SET +#define GLB_REG2_GPIO_38_SET_POS (6U) +#define GLB_REG2_GPIO_38_SET_LEN (1U) +#define GLB_REG2_GPIO_38_SET_MSK (((1U << GLB_REG2_GPIO_38_SET_LEN) - 1) << GLB_REG2_GPIO_38_SET_POS) +#define GLB_REG2_GPIO_38_SET_UMSK (~(((1U << GLB_REG2_GPIO_38_SET_LEN) - 1) << GLB_REG2_GPIO_38_SET_POS)) +#define GLB_REG2_GPIO_39_SET GLB_REG2_GPIO_39_SET +#define GLB_REG2_GPIO_39_SET_POS (7U) +#define GLB_REG2_GPIO_39_SET_LEN (1U) +#define GLB_REG2_GPIO_39_SET_MSK (((1U << GLB_REG2_GPIO_39_SET_LEN) - 1) << GLB_REG2_GPIO_39_SET_POS) +#define GLB_REG2_GPIO_39_SET_UMSK (~(((1U << GLB_REG2_GPIO_39_SET_LEN) - 1) << GLB_REG2_GPIO_39_SET_POS)) +#define GLB_REG2_GPIO_40_SET GLB_REG2_GPIO_40_SET +#define GLB_REG2_GPIO_40_SET_POS (8U) +#define GLB_REG2_GPIO_40_SET_LEN (1U) +#define GLB_REG2_GPIO_40_SET_MSK (((1U << GLB_REG2_GPIO_40_SET_LEN) - 1) << GLB_REG2_GPIO_40_SET_POS) +#define GLB_REG2_GPIO_40_SET_UMSK (~(((1U << GLB_REG2_GPIO_40_SET_LEN) - 1) << GLB_REG2_GPIO_40_SET_POS)) +#define GLB_REG2_GPIO_41_SET GLB_REG2_GPIO_41_SET +#define GLB_REG2_GPIO_41_SET_POS (9U) +#define GLB_REG2_GPIO_41_SET_LEN (1U) +#define GLB_REG2_GPIO_41_SET_MSK (((1U << GLB_REG2_GPIO_41_SET_LEN) - 1) << GLB_REG2_GPIO_41_SET_POS) +#define GLB_REG2_GPIO_41_SET_UMSK (~(((1U << GLB_REG2_GPIO_41_SET_LEN) - 1) << GLB_REG2_GPIO_41_SET_POS)) +#define GLB_REG2_GPIO_42_SET GLB_REG2_GPIO_42_SET +#define GLB_REG2_GPIO_42_SET_POS (10U) +#define GLB_REG2_GPIO_42_SET_LEN (1U) +#define GLB_REG2_GPIO_42_SET_MSK (((1U << GLB_REG2_GPIO_42_SET_LEN) - 1) << GLB_REG2_GPIO_42_SET_POS) +#define GLB_REG2_GPIO_42_SET_UMSK (~(((1U << GLB_REG2_GPIO_42_SET_LEN) - 1) << GLB_REG2_GPIO_42_SET_POS)) +#define GLB_REG2_GPIO_43_SET GLB_REG2_GPIO_43_SET +#define GLB_REG2_GPIO_43_SET_POS (11U) +#define GLB_REG2_GPIO_43_SET_LEN (1U) +#define GLB_REG2_GPIO_43_SET_MSK (((1U << GLB_REG2_GPIO_43_SET_LEN) - 1) << GLB_REG2_GPIO_43_SET_POS) +#define GLB_REG2_GPIO_43_SET_UMSK (~(((1U << GLB_REG2_GPIO_43_SET_LEN) - 1) << GLB_REG2_GPIO_43_SET_POS)) +#define GLB_REG2_GPIO_44_SET GLB_REG2_GPIO_44_SET +#define GLB_REG2_GPIO_44_SET_POS (12U) +#define GLB_REG2_GPIO_44_SET_LEN (1U) +#define GLB_REG2_GPIO_44_SET_MSK (((1U << GLB_REG2_GPIO_44_SET_LEN) - 1) << GLB_REG2_GPIO_44_SET_POS) +#define GLB_REG2_GPIO_44_SET_UMSK (~(((1U << GLB_REG2_GPIO_44_SET_LEN) - 1) << GLB_REG2_GPIO_44_SET_POS)) +#define GLB_REG2_GPIO_45_SET GLB_REG2_GPIO_45_SET +#define GLB_REG2_GPIO_45_SET_POS (13U) +#define GLB_REG2_GPIO_45_SET_LEN (1U) +#define GLB_REG2_GPIO_45_SET_MSK (((1U << GLB_REG2_GPIO_45_SET_LEN) - 1) << GLB_REG2_GPIO_45_SET_POS) +#define GLB_REG2_GPIO_45_SET_UMSK (~(((1U << GLB_REG2_GPIO_45_SET_LEN) - 1) << GLB_REG2_GPIO_45_SET_POS)) + +/* 0xAF4 : gpio_cfg140 */ +#define GLB_GPIO_CFG140_OFFSET (0xAF4) +#define GLB_REG2_GPIO_0_CLR GLB_REG2_GPIO_0_CLR +#define GLB_REG2_GPIO_0_CLR_POS (0U) +#define GLB_REG2_GPIO_0_CLR_LEN (1U) +#define GLB_REG2_GPIO_0_CLR_MSK (((1U << GLB_REG2_GPIO_0_CLR_LEN) - 1) << GLB_REG2_GPIO_0_CLR_POS) +#define GLB_REG2_GPIO_0_CLR_UMSK (~(((1U << GLB_REG2_GPIO_0_CLR_LEN) - 1) << GLB_REG2_GPIO_0_CLR_POS)) +#define GLB_REG2_GPIO_1_CLR GLB_REG2_GPIO_1_CLR +#define GLB_REG2_GPIO_1_CLR_POS (1U) +#define GLB_REG2_GPIO_1_CLR_LEN (1U) +#define GLB_REG2_GPIO_1_CLR_MSK (((1U << GLB_REG2_GPIO_1_CLR_LEN) - 1) << GLB_REG2_GPIO_1_CLR_POS) +#define GLB_REG2_GPIO_1_CLR_UMSK (~(((1U << GLB_REG2_GPIO_1_CLR_LEN) - 1) << GLB_REG2_GPIO_1_CLR_POS)) +#define GLB_REG2_GPIO_2_CLR GLB_REG2_GPIO_2_CLR +#define GLB_REG2_GPIO_2_CLR_POS (2U) +#define GLB_REG2_GPIO_2_CLR_LEN (1U) +#define GLB_REG2_GPIO_2_CLR_MSK (((1U << GLB_REG2_GPIO_2_CLR_LEN) - 1) << GLB_REG2_GPIO_2_CLR_POS) +#define GLB_REG2_GPIO_2_CLR_UMSK (~(((1U << GLB_REG2_GPIO_2_CLR_LEN) - 1) << GLB_REG2_GPIO_2_CLR_POS)) +#define GLB_REG2_GPIO_3_CLR GLB_REG2_GPIO_3_CLR +#define GLB_REG2_GPIO_3_CLR_POS (3U) +#define GLB_REG2_GPIO_3_CLR_LEN (1U) +#define GLB_REG2_GPIO_3_CLR_MSK (((1U << GLB_REG2_GPIO_3_CLR_LEN) - 1) << GLB_REG2_GPIO_3_CLR_POS) +#define GLB_REG2_GPIO_3_CLR_UMSK (~(((1U << GLB_REG2_GPIO_3_CLR_LEN) - 1) << GLB_REG2_GPIO_3_CLR_POS)) +#define GLB_REG2_GPIO_4_CLR GLB_REG2_GPIO_4_CLR +#define GLB_REG2_GPIO_4_CLR_POS (4U) +#define GLB_REG2_GPIO_4_CLR_LEN (1U) +#define GLB_REG2_GPIO_4_CLR_MSK (((1U << GLB_REG2_GPIO_4_CLR_LEN) - 1) << GLB_REG2_GPIO_4_CLR_POS) +#define GLB_REG2_GPIO_4_CLR_UMSK (~(((1U << GLB_REG2_GPIO_4_CLR_LEN) - 1) << GLB_REG2_GPIO_4_CLR_POS)) +#define GLB_REG2_GPIO_5_CLR GLB_REG2_GPIO_5_CLR +#define GLB_REG2_GPIO_5_CLR_POS (5U) +#define GLB_REG2_GPIO_5_CLR_LEN (1U) +#define GLB_REG2_GPIO_5_CLR_MSK (((1U << GLB_REG2_GPIO_5_CLR_LEN) - 1) << GLB_REG2_GPIO_5_CLR_POS) +#define GLB_REG2_GPIO_5_CLR_UMSK (~(((1U << GLB_REG2_GPIO_5_CLR_LEN) - 1) << GLB_REG2_GPIO_5_CLR_POS)) +#define GLB_REG2_GPIO_6_CLR GLB_REG2_GPIO_6_CLR +#define GLB_REG2_GPIO_6_CLR_POS (6U) +#define GLB_REG2_GPIO_6_CLR_LEN (1U) +#define GLB_REG2_GPIO_6_CLR_MSK (((1U << GLB_REG2_GPIO_6_CLR_LEN) - 1) << GLB_REG2_GPIO_6_CLR_POS) +#define GLB_REG2_GPIO_6_CLR_UMSK (~(((1U << GLB_REG2_GPIO_6_CLR_LEN) - 1) << GLB_REG2_GPIO_6_CLR_POS)) +#define GLB_REG2_GPIO_7_CLR GLB_REG2_GPIO_7_CLR +#define GLB_REG2_GPIO_7_CLR_POS (7U) +#define GLB_REG2_GPIO_7_CLR_LEN (1U) +#define GLB_REG2_GPIO_7_CLR_MSK (((1U << GLB_REG2_GPIO_7_CLR_LEN) - 1) << GLB_REG2_GPIO_7_CLR_POS) +#define GLB_REG2_GPIO_7_CLR_UMSK (~(((1U << GLB_REG2_GPIO_7_CLR_LEN) - 1) << GLB_REG2_GPIO_7_CLR_POS)) +#define GLB_REG2_GPIO_8_CLR GLB_REG2_GPIO_8_CLR +#define GLB_REG2_GPIO_8_CLR_POS (8U) +#define GLB_REG2_GPIO_8_CLR_LEN (1U) +#define GLB_REG2_GPIO_8_CLR_MSK (((1U << GLB_REG2_GPIO_8_CLR_LEN) - 1) << GLB_REG2_GPIO_8_CLR_POS) +#define GLB_REG2_GPIO_8_CLR_UMSK (~(((1U << GLB_REG2_GPIO_8_CLR_LEN) - 1) << GLB_REG2_GPIO_8_CLR_POS)) +#define GLB_REG2_GPIO_9_CLR GLB_REG2_GPIO_9_CLR +#define GLB_REG2_GPIO_9_CLR_POS (9U) +#define GLB_REG2_GPIO_9_CLR_LEN (1U) +#define GLB_REG2_GPIO_9_CLR_MSK (((1U << GLB_REG2_GPIO_9_CLR_LEN) - 1) << GLB_REG2_GPIO_9_CLR_POS) +#define GLB_REG2_GPIO_9_CLR_UMSK (~(((1U << GLB_REG2_GPIO_9_CLR_LEN) - 1) << GLB_REG2_GPIO_9_CLR_POS)) +#define GLB_REG2_GPIO_10_CLR GLB_REG2_GPIO_10_CLR +#define GLB_REG2_GPIO_10_CLR_POS (10U) +#define GLB_REG2_GPIO_10_CLR_LEN (1U) +#define GLB_REG2_GPIO_10_CLR_MSK (((1U << GLB_REG2_GPIO_10_CLR_LEN) - 1) << GLB_REG2_GPIO_10_CLR_POS) +#define GLB_REG2_GPIO_10_CLR_UMSK (~(((1U << GLB_REG2_GPIO_10_CLR_LEN) - 1) << GLB_REG2_GPIO_10_CLR_POS)) +#define GLB_REG2_GPIO_11_CLR GLB_REG2_GPIO_11_CLR +#define GLB_REG2_GPIO_11_CLR_POS (11U) +#define GLB_REG2_GPIO_11_CLR_LEN (1U) +#define GLB_REG2_GPIO_11_CLR_MSK (((1U << GLB_REG2_GPIO_11_CLR_LEN) - 1) << GLB_REG2_GPIO_11_CLR_POS) +#define GLB_REG2_GPIO_11_CLR_UMSK (~(((1U << GLB_REG2_GPIO_11_CLR_LEN) - 1) << GLB_REG2_GPIO_11_CLR_POS)) +#define GLB_REG2_GPIO_12_CLR GLB_REG2_GPIO_12_CLR +#define GLB_REG2_GPIO_12_CLR_POS (12U) +#define GLB_REG2_GPIO_12_CLR_LEN (1U) +#define GLB_REG2_GPIO_12_CLR_MSK (((1U << GLB_REG2_GPIO_12_CLR_LEN) - 1) << GLB_REG2_GPIO_12_CLR_POS) +#define GLB_REG2_GPIO_12_CLR_UMSK (~(((1U << GLB_REG2_GPIO_12_CLR_LEN) - 1) << GLB_REG2_GPIO_12_CLR_POS)) +#define GLB_REG2_GPIO_13_CLR GLB_REG2_GPIO_13_CLR +#define GLB_REG2_GPIO_13_CLR_POS (13U) +#define GLB_REG2_GPIO_13_CLR_LEN (1U) +#define GLB_REG2_GPIO_13_CLR_MSK (((1U << GLB_REG2_GPIO_13_CLR_LEN) - 1) << GLB_REG2_GPIO_13_CLR_POS) +#define GLB_REG2_GPIO_13_CLR_UMSK (~(((1U << GLB_REG2_GPIO_13_CLR_LEN) - 1) << GLB_REG2_GPIO_13_CLR_POS)) +#define GLB_REG2_GPIO_14_CLR GLB_REG2_GPIO_14_CLR +#define GLB_REG2_GPIO_14_CLR_POS (14U) +#define GLB_REG2_GPIO_14_CLR_LEN (1U) +#define GLB_REG2_GPIO_14_CLR_MSK (((1U << GLB_REG2_GPIO_14_CLR_LEN) - 1) << GLB_REG2_GPIO_14_CLR_POS) +#define GLB_REG2_GPIO_14_CLR_UMSK (~(((1U << GLB_REG2_GPIO_14_CLR_LEN) - 1) << GLB_REG2_GPIO_14_CLR_POS)) +#define GLB_REG2_GPIO_15_CLR GLB_REG2_GPIO_15_CLR +#define GLB_REG2_GPIO_15_CLR_POS (15U) +#define GLB_REG2_GPIO_15_CLR_LEN (1U) +#define GLB_REG2_GPIO_15_CLR_MSK (((1U << GLB_REG2_GPIO_15_CLR_LEN) - 1) << GLB_REG2_GPIO_15_CLR_POS) +#define GLB_REG2_GPIO_15_CLR_UMSK (~(((1U << GLB_REG2_GPIO_15_CLR_LEN) - 1) << GLB_REG2_GPIO_15_CLR_POS)) +#define GLB_REG2_GPIO_16_CLR GLB_REG2_GPIO_16_CLR +#define GLB_REG2_GPIO_16_CLR_POS (16U) +#define GLB_REG2_GPIO_16_CLR_LEN (1U) +#define GLB_REG2_GPIO_16_CLR_MSK (((1U << GLB_REG2_GPIO_16_CLR_LEN) - 1) << GLB_REG2_GPIO_16_CLR_POS) +#define GLB_REG2_GPIO_16_CLR_UMSK (~(((1U << GLB_REG2_GPIO_16_CLR_LEN) - 1) << GLB_REG2_GPIO_16_CLR_POS)) +#define GLB_REG2_GPIO_17_CLR GLB_REG2_GPIO_17_CLR +#define GLB_REG2_GPIO_17_CLR_POS (17U) +#define GLB_REG2_GPIO_17_CLR_LEN (1U) +#define GLB_REG2_GPIO_17_CLR_MSK (((1U << GLB_REG2_GPIO_17_CLR_LEN) - 1) << GLB_REG2_GPIO_17_CLR_POS) +#define GLB_REG2_GPIO_17_CLR_UMSK (~(((1U << GLB_REG2_GPIO_17_CLR_LEN) - 1) << GLB_REG2_GPIO_17_CLR_POS)) +#define GLB_REG2_GPIO_18_CLR GLB_REG2_GPIO_18_CLR +#define GLB_REG2_GPIO_18_CLR_POS (18U) +#define GLB_REG2_GPIO_18_CLR_LEN (1U) +#define GLB_REG2_GPIO_18_CLR_MSK (((1U << GLB_REG2_GPIO_18_CLR_LEN) - 1) << GLB_REG2_GPIO_18_CLR_POS) +#define GLB_REG2_GPIO_18_CLR_UMSK (~(((1U << GLB_REG2_GPIO_18_CLR_LEN) - 1) << GLB_REG2_GPIO_18_CLR_POS)) +#define GLB_REG2_GPIO_19_CLR GLB_REG2_GPIO_19_CLR +#define GLB_REG2_GPIO_19_CLR_POS (19U) +#define GLB_REG2_GPIO_19_CLR_LEN (1U) +#define GLB_REG2_GPIO_19_CLR_MSK (((1U << GLB_REG2_GPIO_19_CLR_LEN) - 1) << GLB_REG2_GPIO_19_CLR_POS) +#define GLB_REG2_GPIO_19_CLR_UMSK (~(((1U << GLB_REG2_GPIO_19_CLR_LEN) - 1) << GLB_REG2_GPIO_19_CLR_POS)) +#define GLB_REG2_GPIO_20_CLR GLB_REG2_GPIO_20_CLR +#define GLB_REG2_GPIO_20_CLR_POS (20U) +#define GLB_REG2_GPIO_20_CLR_LEN (1U) +#define GLB_REG2_GPIO_20_CLR_MSK (((1U << GLB_REG2_GPIO_20_CLR_LEN) - 1) << GLB_REG2_GPIO_20_CLR_POS) +#define GLB_REG2_GPIO_20_CLR_UMSK (~(((1U << GLB_REG2_GPIO_20_CLR_LEN) - 1) << GLB_REG2_GPIO_20_CLR_POS)) +#define GLB_REG2_GPIO_21_CLR GLB_REG2_GPIO_21_CLR +#define GLB_REG2_GPIO_21_CLR_POS (21U) +#define GLB_REG2_GPIO_21_CLR_LEN (1U) +#define GLB_REG2_GPIO_21_CLR_MSK (((1U << GLB_REG2_GPIO_21_CLR_LEN) - 1) << GLB_REG2_GPIO_21_CLR_POS) +#define GLB_REG2_GPIO_21_CLR_UMSK (~(((1U << GLB_REG2_GPIO_21_CLR_LEN) - 1) << GLB_REG2_GPIO_21_CLR_POS)) +#define GLB_REG2_GPIO_22_CLR GLB_REG2_GPIO_22_CLR +#define GLB_REG2_GPIO_22_CLR_POS (22U) +#define GLB_REG2_GPIO_22_CLR_LEN (1U) +#define GLB_REG2_GPIO_22_CLR_MSK (((1U << GLB_REG2_GPIO_22_CLR_LEN) - 1) << GLB_REG2_GPIO_22_CLR_POS) +#define GLB_REG2_GPIO_22_CLR_UMSK (~(((1U << GLB_REG2_GPIO_22_CLR_LEN) - 1) << GLB_REG2_GPIO_22_CLR_POS)) +#define GLB_REG2_GPIO_23_CLR GLB_REG2_GPIO_23_CLR +#define GLB_REG2_GPIO_23_CLR_POS (23U) +#define GLB_REG2_GPIO_23_CLR_LEN (1U) +#define GLB_REG2_GPIO_23_CLR_MSK (((1U << GLB_REG2_GPIO_23_CLR_LEN) - 1) << GLB_REG2_GPIO_23_CLR_POS) +#define GLB_REG2_GPIO_23_CLR_UMSK (~(((1U << GLB_REG2_GPIO_23_CLR_LEN) - 1) << GLB_REG2_GPIO_23_CLR_POS)) +#define GLB_REG2_GPIO_24_CLR GLB_REG2_GPIO_24_CLR +#define GLB_REG2_GPIO_24_CLR_POS (24U) +#define GLB_REG2_GPIO_24_CLR_LEN (1U) +#define GLB_REG2_GPIO_24_CLR_MSK (((1U << GLB_REG2_GPIO_24_CLR_LEN) - 1) << GLB_REG2_GPIO_24_CLR_POS) +#define GLB_REG2_GPIO_24_CLR_UMSK (~(((1U << GLB_REG2_GPIO_24_CLR_LEN) - 1) << GLB_REG2_GPIO_24_CLR_POS)) +#define GLB_REG2_GPIO_25_CLR GLB_REG2_GPIO_25_CLR +#define GLB_REG2_GPIO_25_CLR_POS (25U) +#define GLB_REG2_GPIO_25_CLR_LEN (1U) +#define GLB_REG2_GPIO_25_CLR_MSK (((1U << GLB_REG2_GPIO_25_CLR_LEN) - 1) << GLB_REG2_GPIO_25_CLR_POS) +#define GLB_REG2_GPIO_25_CLR_UMSK (~(((1U << GLB_REG2_GPIO_25_CLR_LEN) - 1) << GLB_REG2_GPIO_25_CLR_POS)) +#define GLB_REG2_GPIO_26_CLR GLB_REG2_GPIO_26_CLR +#define GLB_REG2_GPIO_26_CLR_POS (26U) +#define GLB_REG2_GPIO_26_CLR_LEN (1U) +#define GLB_REG2_GPIO_26_CLR_MSK (((1U << GLB_REG2_GPIO_26_CLR_LEN) - 1) << GLB_REG2_GPIO_26_CLR_POS) +#define GLB_REG2_GPIO_26_CLR_UMSK (~(((1U << GLB_REG2_GPIO_26_CLR_LEN) - 1) << GLB_REG2_GPIO_26_CLR_POS)) +#define GLB_REG2_GPIO_27_CLR GLB_REG2_GPIO_27_CLR +#define GLB_REG2_GPIO_27_CLR_POS (27U) +#define GLB_REG2_GPIO_27_CLR_LEN (1U) +#define GLB_REG2_GPIO_27_CLR_MSK (((1U << GLB_REG2_GPIO_27_CLR_LEN) - 1) << GLB_REG2_GPIO_27_CLR_POS) +#define GLB_REG2_GPIO_27_CLR_UMSK (~(((1U << GLB_REG2_GPIO_27_CLR_LEN) - 1) << GLB_REG2_GPIO_27_CLR_POS)) +#define GLB_REG2_GPIO_28_CLR GLB_REG2_GPIO_28_CLR +#define GLB_REG2_GPIO_28_CLR_POS (28U) +#define GLB_REG2_GPIO_28_CLR_LEN (1U) +#define GLB_REG2_GPIO_28_CLR_MSK (((1U << GLB_REG2_GPIO_28_CLR_LEN) - 1) << GLB_REG2_GPIO_28_CLR_POS) +#define GLB_REG2_GPIO_28_CLR_UMSK (~(((1U << GLB_REG2_GPIO_28_CLR_LEN) - 1) << GLB_REG2_GPIO_28_CLR_POS)) +#define GLB_REG2_GPIO_29_CLR GLB_REG2_GPIO_29_CLR +#define GLB_REG2_GPIO_29_CLR_POS (29U) +#define GLB_REG2_GPIO_29_CLR_LEN (1U) +#define GLB_REG2_GPIO_29_CLR_MSK (((1U << GLB_REG2_GPIO_29_CLR_LEN) - 1) << GLB_REG2_GPIO_29_CLR_POS) +#define GLB_REG2_GPIO_29_CLR_UMSK (~(((1U << GLB_REG2_GPIO_29_CLR_LEN) - 1) << GLB_REG2_GPIO_29_CLR_POS)) +#define GLB_REG2_GPIO_30_CLR GLB_REG2_GPIO_30_CLR +#define GLB_REG2_GPIO_30_CLR_POS (30U) +#define GLB_REG2_GPIO_30_CLR_LEN (1U) +#define GLB_REG2_GPIO_30_CLR_MSK (((1U << GLB_REG2_GPIO_30_CLR_LEN) - 1) << GLB_REG2_GPIO_30_CLR_POS) +#define GLB_REG2_GPIO_30_CLR_UMSK (~(((1U << GLB_REG2_GPIO_30_CLR_LEN) - 1) << GLB_REG2_GPIO_30_CLR_POS)) +#define GLB_REG2_GPIO_31_CLR GLB_REG2_GPIO_31_CLR +#define GLB_REG2_GPIO_31_CLR_POS (31U) +#define GLB_REG2_GPIO_31_CLR_LEN (1U) +#define GLB_REG2_GPIO_31_CLR_MSK (((1U << GLB_REG2_GPIO_31_CLR_LEN) - 1) << GLB_REG2_GPIO_31_CLR_POS) +#define GLB_REG2_GPIO_31_CLR_UMSK (~(((1U << GLB_REG2_GPIO_31_CLR_LEN) - 1) << GLB_REG2_GPIO_31_CLR_POS)) + +/* 0xAF8 : gpio_cfg141 */ +#define GLB_GPIO_CFG141_OFFSET (0xAF8) +#define GLB_REG2_GPIO_32_CLR GLB_REG2_GPIO_32_CLR +#define GLB_REG2_GPIO_32_CLR_POS (0U) +#define GLB_REG2_GPIO_32_CLR_LEN (1U) +#define GLB_REG2_GPIO_32_CLR_MSK (((1U << GLB_REG2_GPIO_32_CLR_LEN) - 1) << GLB_REG2_GPIO_32_CLR_POS) +#define GLB_REG2_GPIO_32_CLR_UMSK (~(((1U << GLB_REG2_GPIO_32_CLR_LEN) - 1) << GLB_REG2_GPIO_32_CLR_POS)) +#define GLB_REG2_GPIO_33_CLR GLB_REG2_GPIO_33_CLR +#define GLB_REG2_GPIO_33_CLR_POS (1U) +#define GLB_REG2_GPIO_33_CLR_LEN (1U) +#define GLB_REG2_GPIO_33_CLR_MSK (((1U << GLB_REG2_GPIO_33_CLR_LEN) - 1) << GLB_REG2_GPIO_33_CLR_POS) +#define GLB_REG2_GPIO_33_CLR_UMSK (~(((1U << GLB_REG2_GPIO_33_CLR_LEN) - 1) << GLB_REG2_GPIO_33_CLR_POS)) +#define GLB_REG2_GPIO_34_CLR GLB_REG2_GPIO_34_CLR +#define GLB_REG2_GPIO_34_CLR_POS (2U) +#define GLB_REG2_GPIO_34_CLR_LEN (1U) +#define GLB_REG2_GPIO_34_CLR_MSK (((1U << GLB_REG2_GPIO_34_CLR_LEN) - 1) << GLB_REG2_GPIO_34_CLR_POS) +#define GLB_REG2_GPIO_34_CLR_UMSK (~(((1U << GLB_REG2_GPIO_34_CLR_LEN) - 1) << GLB_REG2_GPIO_34_CLR_POS)) +#define GLB_REG2_GPIO_35_CLR GLB_REG2_GPIO_35_CLR +#define GLB_REG2_GPIO_35_CLR_POS (3U) +#define GLB_REG2_GPIO_35_CLR_LEN (1U) +#define GLB_REG2_GPIO_35_CLR_MSK (((1U << GLB_REG2_GPIO_35_CLR_LEN) - 1) << GLB_REG2_GPIO_35_CLR_POS) +#define GLB_REG2_GPIO_35_CLR_UMSK (~(((1U << GLB_REG2_GPIO_35_CLR_LEN) - 1) << GLB_REG2_GPIO_35_CLR_POS)) +#define GLB_REG2_GPIO_36_CLR GLB_REG2_GPIO_36_CLR +#define GLB_REG2_GPIO_36_CLR_POS (4U) +#define GLB_REG2_GPIO_36_CLR_LEN (1U) +#define GLB_REG2_GPIO_36_CLR_MSK (((1U << GLB_REG2_GPIO_36_CLR_LEN) - 1) << GLB_REG2_GPIO_36_CLR_POS) +#define GLB_REG2_GPIO_36_CLR_UMSK (~(((1U << GLB_REG2_GPIO_36_CLR_LEN) - 1) << GLB_REG2_GPIO_36_CLR_POS)) +#define GLB_REG2_GPIO_37_CLR GLB_REG2_GPIO_37_CLR +#define GLB_REG2_GPIO_37_CLR_POS (5U) +#define GLB_REG2_GPIO_37_CLR_LEN (1U) +#define GLB_REG2_GPIO_37_CLR_MSK (((1U << GLB_REG2_GPIO_37_CLR_LEN) - 1) << GLB_REG2_GPIO_37_CLR_POS) +#define GLB_REG2_GPIO_37_CLR_UMSK (~(((1U << GLB_REG2_GPIO_37_CLR_LEN) - 1) << GLB_REG2_GPIO_37_CLR_POS)) +#define GLB_REG2_GPIO_38_CLR GLB_REG2_GPIO_38_CLR +#define GLB_REG2_GPIO_38_CLR_POS (6U) +#define GLB_REG2_GPIO_38_CLR_LEN (1U) +#define GLB_REG2_GPIO_38_CLR_MSK (((1U << GLB_REG2_GPIO_38_CLR_LEN) - 1) << GLB_REG2_GPIO_38_CLR_POS) +#define GLB_REG2_GPIO_38_CLR_UMSK (~(((1U << GLB_REG2_GPIO_38_CLR_LEN) - 1) << GLB_REG2_GPIO_38_CLR_POS)) +#define GLB_REG2_GPIO_39_CLR GLB_REG2_GPIO_39_CLR +#define GLB_REG2_GPIO_39_CLR_POS (7U) +#define GLB_REG2_GPIO_39_CLR_LEN (1U) +#define GLB_REG2_GPIO_39_CLR_MSK (((1U << GLB_REG2_GPIO_39_CLR_LEN) - 1) << GLB_REG2_GPIO_39_CLR_POS) +#define GLB_REG2_GPIO_39_CLR_UMSK (~(((1U << GLB_REG2_GPIO_39_CLR_LEN) - 1) << GLB_REG2_GPIO_39_CLR_POS)) +#define GLB_REG2_GPIO_40_CLR GLB_REG2_GPIO_40_CLR +#define GLB_REG2_GPIO_40_CLR_POS (8U) +#define GLB_REG2_GPIO_40_CLR_LEN (1U) +#define GLB_REG2_GPIO_40_CLR_MSK (((1U << GLB_REG2_GPIO_40_CLR_LEN) - 1) << GLB_REG2_GPIO_40_CLR_POS) +#define GLB_REG2_GPIO_40_CLR_UMSK (~(((1U << GLB_REG2_GPIO_40_CLR_LEN) - 1) << GLB_REG2_GPIO_40_CLR_POS)) +#define GLB_REG2_GPIO_41_CLR GLB_REG2_GPIO_41_CLR +#define GLB_REG2_GPIO_41_CLR_POS (9U) +#define GLB_REG2_GPIO_41_CLR_LEN (1U) +#define GLB_REG2_GPIO_41_CLR_MSK (((1U << GLB_REG2_GPIO_41_CLR_LEN) - 1) << GLB_REG2_GPIO_41_CLR_POS) +#define GLB_REG2_GPIO_41_CLR_UMSK (~(((1U << GLB_REG2_GPIO_41_CLR_LEN) - 1) << GLB_REG2_GPIO_41_CLR_POS)) +#define GLB_REG2_GPIO_42_CLR GLB_REG2_GPIO_42_CLR +#define GLB_REG2_GPIO_42_CLR_POS (10U) +#define GLB_REG2_GPIO_42_CLR_LEN (1U) +#define GLB_REG2_GPIO_42_CLR_MSK (((1U << GLB_REG2_GPIO_42_CLR_LEN) - 1) << GLB_REG2_GPIO_42_CLR_POS) +#define GLB_REG2_GPIO_42_CLR_UMSK (~(((1U << GLB_REG2_GPIO_42_CLR_LEN) - 1) << GLB_REG2_GPIO_42_CLR_POS)) +#define GLB_REG2_GPIO_43_CLR GLB_REG2_GPIO_43_CLR +#define GLB_REG2_GPIO_43_CLR_POS (11U) +#define GLB_REG2_GPIO_43_CLR_LEN (1U) +#define GLB_REG2_GPIO_43_CLR_MSK (((1U << GLB_REG2_GPIO_43_CLR_LEN) - 1) << GLB_REG2_GPIO_43_CLR_POS) +#define GLB_REG2_GPIO_43_CLR_UMSK (~(((1U << GLB_REG2_GPIO_43_CLR_LEN) - 1) << GLB_REG2_GPIO_43_CLR_POS)) +#define GLB_REG2_GPIO_44_CLR GLB_REG2_GPIO_44_CLR +#define GLB_REG2_GPIO_44_CLR_POS (12U) +#define GLB_REG2_GPIO_44_CLR_LEN (1U) +#define GLB_REG2_GPIO_44_CLR_MSK (((1U << GLB_REG2_GPIO_44_CLR_LEN) - 1) << GLB_REG2_GPIO_44_CLR_POS) +#define GLB_REG2_GPIO_44_CLR_UMSK (~(((1U << GLB_REG2_GPIO_44_CLR_LEN) - 1) << GLB_REG2_GPIO_44_CLR_POS)) +#define GLB_REG2_GPIO_45_CLR GLB_REG2_GPIO_45_CLR +#define GLB_REG2_GPIO_45_CLR_POS (13U) +#define GLB_REG2_GPIO_45_CLR_LEN (1U) +#define GLB_REG2_GPIO_45_CLR_MSK (((1U << GLB_REG2_GPIO_45_CLR_LEN) - 1) << GLB_REG2_GPIO_45_CLR_POS) +#define GLB_REG2_GPIO_45_CLR_UMSK (~(((1U << GLB_REG2_GPIO_45_CLR_LEN) - 1) << GLB_REG2_GPIO_45_CLR_POS)) + +/* 0xAFC : gpio_cfg142 */ +#define GLB_GPIO_CFG142_OFFSET (0xAFC) +#define GLB_CR_GPIO_TX_EN GLB_CR_GPIO_TX_EN +#define GLB_CR_GPIO_TX_EN_POS (0U) +#define GLB_CR_GPIO_TX_EN_LEN (1U) +#define GLB_CR_GPIO_TX_EN_MSK (((1U << GLB_CR_GPIO_TX_EN_LEN) - 1) << GLB_CR_GPIO_TX_EN_POS) +#define GLB_CR_GPIO_TX_EN_UMSK (~(((1U << GLB_CR_GPIO_TX_EN_LEN) - 1) << GLB_CR_GPIO_TX_EN_POS)) +#define GLB_CR_INVERT_CODE0_HIGH GLB_CR_INVERT_CODE0_HIGH +#define GLB_CR_INVERT_CODE0_HIGH_POS (1U) +#define GLB_CR_INVERT_CODE0_HIGH_LEN (1U) +#define GLB_CR_INVERT_CODE0_HIGH_MSK (((1U << GLB_CR_INVERT_CODE0_HIGH_LEN) - 1) << GLB_CR_INVERT_CODE0_HIGH_POS) +#define GLB_CR_INVERT_CODE0_HIGH_UMSK (~(((1U << GLB_CR_INVERT_CODE0_HIGH_LEN) - 1) << GLB_CR_INVERT_CODE0_HIGH_POS)) +#define GLB_CR_INVERT_CODE1_HIGH GLB_CR_INVERT_CODE1_HIGH +#define GLB_CR_INVERT_CODE1_HIGH_POS (2U) +#define GLB_CR_INVERT_CODE1_HIGH_LEN (1U) +#define GLB_CR_INVERT_CODE1_HIGH_MSK (((1U << GLB_CR_INVERT_CODE1_HIGH_LEN) - 1) << GLB_CR_INVERT_CODE1_HIGH_POS) +#define GLB_CR_INVERT_CODE1_HIGH_UMSK (~(((1U << GLB_CR_INVERT_CODE1_HIGH_LEN) - 1) << GLB_CR_INVERT_CODE1_HIGH_POS)) +#define GLB_CR_CODE_TOTAL_TIME GLB_CR_CODE_TOTAL_TIME +#define GLB_CR_CODE_TOTAL_TIME_POS (7U) +#define GLB_CR_CODE_TOTAL_TIME_LEN (9U) +#define GLB_CR_CODE_TOTAL_TIME_MSK (((1U << GLB_CR_CODE_TOTAL_TIME_LEN) - 1) << GLB_CR_CODE_TOTAL_TIME_POS) +#define GLB_CR_CODE_TOTAL_TIME_UMSK (~(((1U << GLB_CR_CODE_TOTAL_TIME_LEN) - 1) << GLB_CR_CODE_TOTAL_TIME_POS)) +#define GLB_CR_CODE0_HIGH_TIME GLB_CR_CODE0_HIGH_TIME +#define GLB_CR_CODE0_HIGH_TIME_POS (16U) +#define GLB_CR_CODE0_HIGH_TIME_LEN (8U) +#define GLB_CR_CODE0_HIGH_TIME_MSK (((1U << GLB_CR_CODE0_HIGH_TIME_LEN) - 1) << GLB_CR_CODE0_HIGH_TIME_POS) +#define GLB_CR_CODE0_HIGH_TIME_UMSK (~(((1U << GLB_CR_CODE0_HIGH_TIME_LEN) - 1) << GLB_CR_CODE0_HIGH_TIME_POS)) +#define GLB_CR_CODE1_HIGH_TIME GLB_CR_CODE1_HIGH_TIME +#define GLB_CR_CODE1_HIGH_TIME_POS (24U) +#define GLB_CR_CODE1_HIGH_TIME_LEN (8U) +#define GLB_CR_CODE1_HIGH_TIME_MSK (((1U << GLB_CR_CODE1_HIGH_TIME_LEN) - 1) << GLB_CR_CODE1_HIGH_TIME_POS) +#define GLB_CR_CODE1_HIGH_TIME_UMSK (~(((1U << GLB_CR_CODE1_HIGH_TIME_LEN) - 1) << GLB_CR_CODE1_HIGH_TIME_POS)) + +/* 0xB00 : gpio_cfg143 */ +#define GLB_GPIO_CFG143_OFFSET (0xB00) +#define GLB_CR_GPIO_DMA_TX_EN GLB_CR_GPIO_DMA_TX_EN +#define GLB_CR_GPIO_DMA_TX_EN_POS (0U) +#define GLB_CR_GPIO_DMA_TX_EN_LEN (1U) +#define GLB_CR_GPIO_DMA_TX_EN_MSK (((1U << GLB_CR_GPIO_DMA_TX_EN_LEN) - 1) << GLB_CR_GPIO_DMA_TX_EN_POS) +#define GLB_CR_GPIO_DMA_TX_EN_UMSK (~(((1U << GLB_CR_GPIO_DMA_TX_EN_LEN) - 1) << GLB_CR_GPIO_DMA_TX_EN_POS)) +#define GLB_CR_GPIO_DMA_OUT_SEL_LATCH GLB_CR_GPIO_DMA_OUT_SEL_LATCH +#define GLB_CR_GPIO_DMA_OUT_SEL_LATCH_POS (1U) +#define GLB_CR_GPIO_DMA_OUT_SEL_LATCH_LEN (1U) +#define GLB_CR_GPIO_DMA_OUT_SEL_LATCH_MSK (((1U << GLB_CR_GPIO_DMA_OUT_SEL_LATCH_LEN) - 1) << GLB_CR_GPIO_DMA_OUT_SEL_LATCH_POS) +#define GLB_CR_GPIO_DMA_OUT_SEL_LATCH_UMSK (~(((1U << GLB_CR_GPIO_DMA_OUT_SEL_LATCH_LEN) - 1) << GLB_CR_GPIO_DMA_OUT_SEL_LATCH_POS)) +#define GLB_GPIO_TX_FIFO_CLR GLB_GPIO_TX_FIFO_CLR +#define GLB_GPIO_TX_FIFO_CLR_POS (2U) +#define GLB_GPIO_TX_FIFO_CLR_LEN (1U) +#define GLB_GPIO_TX_FIFO_CLR_MSK (((1U << GLB_GPIO_TX_FIFO_CLR_LEN) - 1) << GLB_GPIO_TX_FIFO_CLR_POS) +#define GLB_GPIO_TX_FIFO_CLR_UMSK (~(((1U << GLB_GPIO_TX_FIFO_CLR_LEN) - 1) << GLB_GPIO_TX_FIFO_CLR_POS)) +#define GLB_GPIO_TX_END_CLR GLB_GPIO_TX_END_CLR +#define GLB_GPIO_TX_END_CLR_POS (3U) +#define GLB_GPIO_TX_END_CLR_LEN (1U) +#define GLB_GPIO_TX_END_CLR_MSK (((1U << GLB_GPIO_TX_END_CLR_LEN) - 1) << GLB_GPIO_TX_END_CLR_POS) +#define GLB_GPIO_TX_END_CLR_UMSK (~(((1U << GLB_GPIO_TX_END_CLR_LEN) - 1) << GLB_GPIO_TX_END_CLR_POS)) +#define GLB_GPIO_TX_FIFO_OVERFLOW GLB_GPIO_TX_FIFO_OVERFLOW +#define GLB_GPIO_TX_FIFO_OVERFLOW_POS (4U) +#define GLB_GPIO_TX_FIFO_OVERFLOW_LEN (1U) +#define GLB_GPIO_TX_FIFO_OVERFLOW_MSK (((1U << GLB_GPIO_TX_FIFO_OVERFLOW_LEN) - 1) << GLB_GPIO_TX_FIFO_OVERFLOW_POS) +#define GLB_GPIO_TX_FIFO_OVERFLOW_UMSK (~(((1U << GLB_GPIO_TX_FIFO_OVERFLOW_LEN) - 1) << GLB_GPIO_TX_FIFO_OVERFLOW_POS)) +#define GLB_GPIO_TX_FIFO_UNDERFLOW GLB_GPIO_TX_FIFO_UNDERFLOW +#define GLB_GPIO_TX_FIFO_UNDERFLOW_POS (5U) +#define GLB_GPIO_TX_FIFO_UNDERFLOW_LEN (1U) +#define GLB_GPIO_TX_FIFO_UNDERFLOW_MSK (((1U << GLB_GPIO_TX_FIFO_UNDERFLOW_LEN) - 1) << GLB_GPIO_TX_FIFO_UNDERFLOW_POS) +#define GLB_GPIO_TX_FIFO_UNDERFLOW_UMSK (~(((1U << GLB_GPIO_TX_FIFO_UNDERFLOW_LEN) - 1) << GLB_GPIO_TX_FIFO_UNDERFLOW_POS)) +#define GLB_CR_GPIO_DMA_PARK_VALUE GLB_CR_GPIO_DMA_PARK_VALUE +#define GLB_CR_GPIO_DMA_PARK_VALUE_POS (7U) +#define GLB_CR_GPIO_DMA_PARK_VALUE_LEN (1U) +#define GLB_CR_GPIO_DMA_PARK_VALUE_MSK (((1U << GLB_CR_GPIO_DMA_PARK_VALUE_LEN) - 1) << GLB_CR_GPIO_DMA_PARK_VALUE_POS) +#define GLB_CR_GPIO_DMA_PARK_VALUE_UMSK (~(((1U << GLB_CR_GPIO_DMA_PARK_VALUE_LEN) - 1) << GLB_CR_GPIO_DMA_PARK_VALUE_POS)) +#define GLB_GPIO_TX_FIFO_CNT GLB_GPIO_TX_FIFO_CNT +#define GLB_GPIO_TX_FIFO_CNT_POS (8U) +#define GLB_GPIO_TX_FIFO_CNT_LEN (8U) +#define GLB_GPIO_TX_FIFO_CNT_MSK (((1U << GLB_GPIO_TX_FIFO_CNT_LEN) - 1) << GLB_GPIO_TX_FIFO_CNT_POS) +#define GLB_GPIO_TX_FIFO_CNT_UMSK (~(((1U << GLB_GPIO_TX_FIFO_CNT_LEN) - 1) << GLB_GPIO_TX_FIFO_CNT_POS)) +#define GLB_CR_GPIO_TX_FIFO_TH GLB_CR_GPIO_TX_FIFO_TH +#define GLB_CR_GPIO_TX_FIFO_TH_POS (16U) +#define GLB_CR_GPIO_TX_FIFO_TH_LEN (7U) +#define GLB_CR_GPIO_TX_FIFO_TH_MSK (((1U << GLB_CR_GPIO_TX_FIFO_TH_LEN) - 1) << GLB_CR_GPIO_TX_FIFO_TH_POS) +#define GLB_CR_GPIO_TX_FIFO_TH_UMSK (~(((1U << GLB_CR_GPIO_TX_FIFO_TH_LEN) - 1) << GLB_CR_GPIO_TX_FIFO_TH_POS)) +#define GLB_CR_GPIO_TX_END_MASK GLB_CR_GPIO_TX_END_MASK +#define GLB_CR_GPIO_TX_END_MASK_POS (23U) +#define GLB_CR_GPIO_TX_END_MASK_LEN (1U) +#define GLB_CR_GPIO_TX_END_MASK_MSK (((1U << GLB_CR_GPIO_TX_END_MASK_LEN) - 1) << GLB_CR_GPIO_TX_END_MASK_POS) +#define GLB_CR_GPIO_TX_END_MASK_UMSK (~(((1U << GLB_CR_GPIO_TX_END_MASK_LEN) - 1) << GLB_CR_GPIO_TX_END_MASK_POS)) +#define GLB_CR_GPIO_TX_FIFO_MASK GLB_CR_GPIO_TX_FIFO_MASK +#define GLB_CR_GPIO_TX_FIFO_MASK_POS (24U) +#define GLB_CR_GPIO_TX_FIFO_MASK_LEN (1U) +#define GLB_CR_GPIO_TX_FIFO_MASK_MSK (((1U << GLB_CR_GPIO_TX_FIFO_MASK_LEN) - 1) << GLB_CR_GPIO_TX_FIFO_MASK_POS) +#define GLB_CR_GPIO_TX_FIFO_MASK_UMSK (~(((1U << GLB_CR_GPIO_TX_FIFO_MASK_LEN) - 1) << GLB_CR_GPIO_TX_FIFO_MASK_POS)) +#define GLB_CR_GPIO_TX_FER_MASK GLB_CR_GPIO_TX_FER_MASK +#define GLB_CR_GPIO_TX_FER_MASK_POS (25U) +#define GLB_CR_GPIO_TX_FER_MASK_LEN (1U) +#define GLB_CR_GPIO_TX_FER_MASK_MSK (((1U << GLB_CR_GPIO_TX_FER_MASK_LEN) - 1) << GLB_CR_GPIO_TX_FER_MASK_POS) +#define GLB_CR_GPIO_TX_FER_MASK_UMSK (~(((1U << GLB_CR_GPIO_TX_FER_MASK_LEN) - 1) << GLB_CR_GPIO_TX_FER_MASK_POS)) +#define GLB_R_GPIO_TX_END_INT GLB_R_GPIO_TX_END_INT +#define GLB_R_GPIO_TX_END_INT_POS (26U) +#define GLB_R_GPIO_TX_END_INT_LEN (1U) +#define GLB_R_GPIO_TX_END_INT_MSK (((1U << GLB_R_GPIO_TX_END_INT_LEN) - 1) << GLB_R_GPIO_TX_END_INT_POS) +#define GLB_R_GPIO_TX_END_INT_UMSK (~(((1U << GLB_R_GPIO_TX_END_INT_LEN) - 1) << GLB_R_GPIO_TX_END_INT_POS)) +#define GLB_R_GPIO_TX_FIFO_INT GLB_R_GPIO_TX_FIFO_INT +#define GLB_R_GPIO_TX_FIFO_INT_POS (27U) +#define GLB_R_GPIO_TX_FIFO_INT_LEN (1U) +#define GLB_R_GPIO_TX_FIFO_INT_MSK (((1U << GLB_R_GPIO_TX_FIFO_INT_LEN) - 1) << GLB_R_GPIO_TX_FIFO_INT_POS) +#define GLB_R_GPIO_TX_FIFO_INT_UMSK (~(((1U << GLB_R_GPIO_TX_FIFO_INT_LEN) - 1) << GLB_R_GPIO_TX_FIFO_INT_POS)) +#define GLB_R_GPIO_TX_FER_INT GLB_R_GPIO_TX_FER_INT +#define GLB_R_GPIO_TX_FER_INT_POS (28U) +#define GLB_R_GPIO_TX_FER_INT_LEN (1U) +#define GLB_R_GPIO_TX_FER_INT_MSK (((1U << GLB_R_GPIO_TX_FER_INT_LEN) - 1) << GLB_R_GPIO_TX_FER_INT_POS) +#define GLB_R_GPIO_TX_FER_INT_UMSK (~(((1U << GLB_R_GPIO_TX_FER_INT_LEN) - 1) << GLB_R_GPIO_TX_FER_INT_POS)) +#define GLB_CR_GPIO_TX_END_EN GLB_CR_GPIO_TX_END_EN +#define GLB_CR_GPIO_TX_END_EN_POS (29U) +#define GLB_CR_GPIO_TX_END_EN_LEN (1U) +#define GLB_CR_GPIO_TX_END_EN_MSK (((1U << GLB_CR_GPIO_TX_END_EN_LEN) - 1) << GLB_CR_GPIO_TX_END_EN_POS) +#define GLB_CR_GPIO_TX_END_EN_UMSK (~(((1U << GLB_CR_GPIO_TX_END_EN_LEN) - 1) << GLB_CR_GPIO_TX_END_EN_POS)) +#define GLB_CR_GPIO_TX_FIFO_EN GLB_CR_GPIO_TX_FIFO_EN +#define GLB_CR_GPIO_TX_FIFO_EN_POS (30U) +#define GLB_CR_GPIO_TX_FIFO_EN_LEN (1U) +#define GLB_CR_GPIO_TX_FIFO_EN_MSK (((1U << GLB_CR_GPIO_TX_FIFO_EN_LEN) - 1) << GLB_CR_GPIO_TX_FIFO_EN_POS) +#define GLB_CR_GPIO_TX_FIFO_EN_UMSK (~(((1U << GLB_CR_GPIO_TX_FIFO_EN_LEN) - 1) << GLB_CR_GPIO_TX_FIFO_EN_POS)) +#define GLB_CR_GPIO_TX_FER_EN GLB_CR_GPIO_TX_FER_EN +#define GLB_CR_GPIO_TX_FER_EN_POS (31U) +#define GLB_CR_GPIO_TX_FER_EN_LEN (1U) +#define GLB_CR_GPIO_TX_FER_EN_MSK (((1U << GLB_CR_GPIO_TX_FER_EN_LEN) - 1) << GLB_CR_GPIO_TX_FER_EN_POS) +#define GLB_CR_GPIO_TX_FER_EN_UMSK (~(((1U << GLB_CR_GPIO_TX_FER_EN_LEN) - 1) << GLB_CR_GPIO_TX_FER_EN_POS)) + +/* 0xB04 : gpio_cfg144 */ +#define GLB_GPIO_CFG144_OFFSET (0xB04) +#define GLB_GPIO_TX_DATA_TO_FIFO GLB_GPIO_TX_DATA_TO_FIFO +#define GLB_GPIO_TX_DATA_TO_FIFO_POS (0U) +#define GLB_GPIO_TX_DATA_TO_FIFO_LEN (16U) +#define GLB_GPIO_TX_DATA_TO_FIFO_MSK (((1U << GLB_GPIO_TX_DATA_TO_FIFO_LEN) - 1) << GLB_GPIO_TX_DATA_TO_FIFO_POS) +#define GLB_GPIO_TX_DATA_TO_FIFO_UMSK (~(((1U << GLB_GPIO_TX_DATA_TO_FIFO_LEN) - 1) << GLB_GPIO_TX_DATA_TO_FIFO_POS)) + +struct glb_reg { + /* 0x0 : soc_info0 */ + union { + struct { + uint32_t reserved_0_26 : 27; /* [26: 0], rsvd, 0x0 */ + uint32_t chip_rdy : 1; /* [ 27], r, 0x0 */ + uint32_t glb_id : 4; /* [31:28], r, 0x6 */ + } BF; + uint32_t WORD; + } soc_info0; + + /* 0x4 reserved */ + uint8_t RESERVED0x4[76]; + + /* 0x50 : core_cfg16 */ + union { + struct { + uint32_t np_int_sta0 : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } core_cfg16; + + /* 0x54 : core_cfg17 */ + union { + struct { + uint32_t np_int_sta1 : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } core_cfg17; + + /* 0x58 : core_cfg18 */ + union { + struct { + uint32_t np_int_mask0 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } core_cfg18; + + /* 0x5C : core_cfg19 */ + union { + struct { + uint32_t np_int_mask1 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } core_cfg19; + + /* 0x60 : core_cfg20 */ + union { + struct { + uint32_t np_int_clr0 : 32; /* [31: 0], w1c, 0x0 */ + } BF; + uint32_t WORD; + } core_cfg20; + + /* 0x64 : core_cfg21 */ + union { + struct { + uint32_t np_int_clr1 : 32; /* [31: 0], w1c, 0x0 */ + } BF; + uint32_t WORD; + } core_cfg21; + + /* 0x68 : core_cfg22 */ + union { + struct { + uint32_t reg_e902_int_en0 : 32; /* [31: 0], r/w, 0xffffffff */ + } BF; + uint32_t WORD; + } core_cfg22; + + /* 0x6C : core_cfg23 */ + union { + struct { + uint32_t reg_e902_int_en1 : 32; /* [31: 0], r/w, 0xffffffff */ + } BF; + uint32_t WORD; + } core_cfg23; + + /* 0x70 : core_cfg24 */ + union { + struct { + uint32_t sts_e902_int_bus_0 : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } core_cfg24; + + /* 0x74 : core_cfg25 */ + union { + struct { + uint32_t sts_e902_int_bus_1 : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } core_cfg25; + + /* 0x78 reserved */ + uint8_t RESERVED0x78[24]; + + /* 0x90 : sys_cfg0 */ + union { + struct { + uint32_t reg_pll_en : 1; /* [ 0], r/w, 0x1 */ + uint32_t reg_fclk_en : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_hclk_en : 1; /* [ 2], r/w, 0x1 */ + uint32_t reg_bclk_en : 1; /* [ 3], r/w, 0x1 */ + uint32_t reserved_4_5 : 2; /* [ 5: 4], rsvd, 0x0 */ + uint32_t hbn_root_clk_sel : 2; /* [ 7: 6], r, 0x0 */ + uint32_t reg_hclk_div : 8; /* [15: 8], r/w, 0x0 */ + uint32_t reg_bclk_div : 8; /* [23:16], r/w, 0x0 */ + uint32_t reserved_24_31 : 8; /* [31:24], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sys_cfg0; + + /* 0x94 : sys_cfg1 */ + union { + struct { + uint32_t reg_bclk_div_act_pulse : 1; /* [ 0], w1p, 0x0 */ + uint32_t reg_bclk_div_bypass : 1; /* [ 1], r/w, 0x0 */ + uint32_t sts_bclk_prot_done : 1; /* [ 2], r, 0x1 */ + uint32_t reserved_3 : 1; /* [ 3], rsvd, 0x0 */ + uint32_t reg_bclk_sw_done_cnt : 4; /* [ 7: 4], r/w, 0x5 */ + uint32_t reserved_8_15 : 8; /* [15: 8], rsvd, 0x0 */ + uint32_t reg_pico_clk_div_act_pulse : 1; /* [ 16], w1p, 0x0 */ + uint32_t reg_pico_clk_div_bypass : 1; /* [ 17], r/w, 0x0 */ + uint32_t sts_pico_clk_prot_done : 1; /* [ 18], r, 0x1 */ + uint32_t reserved_19 : 1; /* [ 19], rsvd, 0x0 */ + uint32_t reg_pico_clk_sw_done_cnt : 4; /* [23:20], r/w, 0x5 */ + uint32_t fclk_sw_state : 3; /* [26:24], r, 0x0 */ + uint32_t reserved_27_31 : 5; /* [31:27], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sys_cfg1; + + /* 0x98 reserved */ + uint8_t RESERVED0x98[8]; + + /* 0xA0 : bus_cfg0 */ + union { + struct { + uint32_t rg_apb2_pck_force : 16; /* [15: 0], r/w, 0xffff */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } bus_cfg0; + + /* 0xa4 reserved */ + uint8_t RESERVED0xa4[60]; + + /* 0xE0 : emi_cfg0 */ + union { + struct { + uint32_t reserved_0_8 : 9; /* [ 8: 0], rsvd, 0x0 */ + uint32_t reg_emi_clk_en : 1; /* [ 9], r/w, 0x1 */ + uint32_t reserved_10_13 : 4; /* [13:10], rsvd, 0x0 */ + uint32_t reg_emi_clk_sel : 3; /* [16:14], r/w, 0x0 */ + uint32_t reserved_17_21 : 5; /* [21:17], rsvd, 0x0 */ + uint32_t reg_emi_clk_div : 2; /* [23:22], r/w, 0x0 */ + uint32_t reserved_24_31 : 8; /* [31:24], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } emi_cfg0; + + /* 0xe4 reserved */ + uint8_t RESERVED0xe4[12]; + + /* 0xF0 : rtc_cfg0 */ + union { + struct { + uint32_t cpu_rtc_div : 17; /* [16: 0], r/w, 0x10 */ + uint32_t reserved_17 : 1; /* [ 17], rsvd, 0x0 */ + uint32_t cpu_rtc_en : 1; /* [ 18], r/w, 0x0 */ + uint32_t cpu_rtc_sel : 1; /* [ 19], r/w, 0x1 */ + uint32_t reserved_20_31 : 12; /* [31:20], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } rtc_cfg0; + + /* 0xf4 reserved */ + uint8_t RESERVED0xf4[28]; + + /* 0x110 : adc_cfg0 */ + union { + struct { + uint32_t gpadc_32m_clk_div : 6; /* [ 5: 0], r/w, 0x2 */ + uint32_t reserved_6 : 1; /* [ 6], rsvd, 0x0 */ + uint32_t gpadc_32m_clk_sel : 1; /* [ 7], r/w, 0x0 */ + uint32_t gpadc_32m_div_en : 1; /* [ 8], r/w, 0x1 */ + uint32_t reserved_9_31 : 23; /* [31: 9], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } adc_cfg0; + + /* 0x114 reserved */ + uint8_t RESERVED0x114[12]; + + /* 0x120 : dac_cfg0 */ + union { + struct { + uint32_t gpdaca_rstn_ana : 1; /* [ 0], r/w, 0x1 */ + uint32_t gpdacb_rstn_ana : 1; /* [ 1], r/w, 0x1 */ + uint32_t reserved_2_6 : 5; /* [ 6: 2], rsvd, 0x0 */ + uint32_t gpdac_test_en : 1; /* [ 7], r/w, 0x0 */ + uint32_t gpdac_ref_sel : 1; /* [ 8], r/w, 0x0 */ + uint32_t gpdac_test_sel : 3; /* [11: 9], r/w, 0x0 */ + uint32_t reserved_12_23 : 12; /* [23:12], rsvd, 0x0 */ + uint32_t gpdac_reserved : 8; /* [31:24], r/w, 0xf */ + } BF; + uint32_t WORD; + } dac_cfg0; + + /* 0x124 : dac_cfg1 */ + union { + struct { + uint32_t gpdac_a_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t gpdac_ioa_en : 1; /* [ 1], r/w, 0x0 */ + uint32_t reserved_2_17 : 16; /* [17: 2], rsvd, 0x0 */ + uint32_t gpdac_a_rng : 2; /* [19:18], r/w, 0x3 */ + uint32_t gpdac_a_outmux : 3; /* [22:20], r/w, 0x0 */ + uint32_t reserved_23_31 : 9; /* [31:23], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } dac_cfg1; + + /* 0x128 : dac_cfg2 */ + union { + struct { + uint32_t gpdac_b_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t gpdac_iob_en : 1; /* [ 1], r/w, 0x0 */ + uint32_t reserved_2_17 : 16; /* [17: 2], rsvd, 0x0 */ + uint32_t gpdac_b_rng : 2; /* [19:18], r/w, 0x3 */ + uint32_t gpdac_b_outmux : 3; /* [22:20], r/w, 0x0 */ + uint32_t reserved_23_31 : 9; /* [31:23], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } dac_cfg2; + + /* 0x12C : dac_cfg3 */ + union { + struct { + uint32_t gpdac_b_data : 10; /* [ 9: 0], r/w, 0x0 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t gpdac_a_data : 10; /* [25:16], r/w, 0x0 */ + uint32_t reserved_26_31 : 6; /* [31:26], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } dac_cfg3; + + /* 0x130 : dma_cfg0 */ + union { + struct { + uint32_t reserved_0_23 : 24; /* [23: 0], rsvd, 0x0 */ + uint32_t dma_clk_en : 8; /* [31:24], r/w, 0xff */ + } BF; + uint32_t WORD; + } dma_cfg0; + + /* 0x134 : dma_cfg1 */ + union { + struct { + uint32_t reserved_0_23 : 24; /* [23: 0], rsvd, 0x0 */ + uint32_t dma2_clk_en : 8; /* [31:24], r/w, 0xff */ + } BF; + uint32_t WORD; + } dma_cfg1; + + /* 0x138 : dma_cfg2 */ + union { + struct { + uint32_t reg_dma_cn_sel : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } dma_cfg2; + + /* 0x13c reserved */ + uint8_t RESERVED0x13c[4]; + + /* 0x140 : ir_cfg0 */ + union { + struct { + uint32_t reserved_0_15 : 16; /* [15: 0], rsvd, 0x0 */ + uint32_t ir_clk_div : 6; /* [21:16], r/w, 0xf */ + uint32_t reserved_22 : 1; /* [ 22], rsvd, 0x0 */ + uint32_t ir_clk_en : 1; /* [ 23], r/w, 0x1 */ + uint32_t reserved_24_31 : 8; /* [31:24], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } ir_cfg0; + + /* 0x144 : ir_cfg1 */ + union { + struct { + uint32_t led_din_reg : 1; /* [ 0], r/w, 0x0 */ + uint32_t led_din_sel : 1; /* [ 1], r/w, 0x0 */ + uint32_t led_din_polarity_sel : 1; /* [ 2], r/w, 0x0 */ + uint32_t reserved_3 : 1; /* [ 3], rsvd, 0x0 */ + uint32_t leddrv_ibias : 4; /* [ 7: 4], r/w, 0x8 */ + uint32_t ir_rx_gpio_sel : 4; /* [11: 8], r/w, 0x0 */ + uint32_t reserved_12_30 : 19; /* [30:12], rsvd, 0x0 */ + uint32_t pu_leddrv : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } ir_cfg1; + + /* 0x148 reserved */ + uint8_t RESERVED0x148[8]; + + /* 0x150 : uart_cfg0 */ + union { + struct { + uint32_t uart_clk_div : 3; /* [ 2: 0], r/w, 0x7 */ + uint32_t reserved_3 : 1; /* [ 3], rsvd, 0x0 */ + uint32_t uart_clk_en : 1; /* [ 4], r/w, 0x1 */ + uint32_t reserved_5_6 : 2; /* [ 6: 5], rsvd, 0x0 */ + uint32_t hbn_uart_clk_sel : 1; /* [ 7], r, 0x0 */ + uint32_t reserved_8_21 : 14; /* [21: 8], rsvd, 0x0 */ + uint32_t hbn_uart_clk_sel2 : 1; /* [ 22], r, 0x0 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t uart2_io_sel : 1; /* [ 24], r/w, 0x0 */ + uint32_t reserved_25_31 : 7; /* [31:25], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } uart_cfg0; + + /* 0x154 : uart_cfg1 */ + union { + struct { + uint32_t uart_sig_0_sel : 4; /* [ 3: 0], r/w, 0x0 */ + uint32_t uart_sig_1_sel : 4; /* [ 7: 4], r/w, 0x1 */ + uint32_t uart_sig_2_sel : 4; /* [11: 8], r/w, 0x2 */ + uint32_t uart_sig_3_sel : 4; /* [15:12], r/w, 0x3 */ + uint32_t uart_sig_4_sel : 4; /* [19:16], r/w, 0x4 */ + uint32_t uart_sig_5_sel : 4; /* [23:20], r/w, 0x5 */ + uint32_t uart_sig_6_sel : 4; /* [27:24], r/w, 0x6 */ + uint32_t uart_sig_7_sel : 4; /* [31:28], r/w, 0x7 */ + } BF; + uint32_t WORD; + } uart_cfg1; + + /* 0x158 : uart_cfg2 */ + union { + struct { + uint32_t uart_sig_8_sel : 4; /* [ 3: 0], r/w, 0x8 */ + uint32_t uart_sig_9_sel : 4; /* [ 7: 4], r/w, 0x9 */ + uint32_t uart_sig_10_sel : 4; /* [11: 8], r/w, 0xa */ + uint32_t uart_sig_11_sel : 4; /* [15:12], r/w, 0xb */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } uart_cfg2; + + /* 0x15c reserved */ + uint8_t RESERVED0x15c[20]; + + /* 0x170 : sf_cfg0 */ + union { + struct { + uint32_t reserved_0_7 : 8; /* [ 7: 0], rsvd, 0x0 */ + uint32_t sf_clk_div : 3; /* [10: 8], r/w, 0x3 */ + uint32_t sf_clk_en : 1; /* [ 11], r/w, 0x1 */ + uint32_t sf_clk_sel : 2; /* [13:12], r/w, 0x2 */ + uint32_t sf_clk_sel2 : 2; /* [15:14], r/w, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf_cfg0; + + /* 0x174 reserved */ + uint8_t RESERVED0x174[12]; + + /* 0x180 : i2c_cfg0 */ + union { + struct { + uint32_t reserved_0_15 : 16; /* [15: 0], rsvd, 0x0 */ + uint32_t i2c_clk_div : 8; /* [23:16], r/w, 0xff */ + uint32_t i2c_clk_en : 1; /* [ 24], r/w, 0x1 */ + uint32_t i2c_clk_sel : 1; /* [ 25], r/w, 0x0 */ + uint32_t reserved_26_31 : 6; /* [31:26], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } i2c_cfg0; + + /* 0x184 reserved */ + uint8_t RESERVED0x184[12]; + + /* 0x190 : i2s_cfg0 */ + union { + struct { + uint32_t reg_i2s_ref_clk_div : 6; /* [ 5: 0], r/w, 0x1 */ + uint32_t reg_i2s_di_ref_clk_sel : 1; /* [ 6], r/w, 0x0 */ + uint32_t reg_i2s_ref_clk_en : 1; /* [ 7], r/w, 0x1 */ + uint32_t reg_i2s_do_ref_clk_sel : 1; /* [ 8], r/w, 0x0 */ + uint32_t reserved_9_31 : 23; /* [31: 9], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } i2s_cfg0; + + /* 0x194 reserved */ + uint8_t RESERVED0x194[28]; + + /* 0x1B0 : spi_cfg0 */ + union { + struct { + uint32_t spi_clk_div : 5; /* [ 4: 0], r/w, 0x3 */ + uint32_t reserved_5_7 : 3; /* [ 7: 5], rsvd, 0x0 */ + uint32_t spi_clk_en : 1; /* [ 8], r/w, 0x1 */ + uint32_t spi_clk_sel : 1; /* [ 9], r/w, 0x0 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t spi_swap_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reserved_20_31 : 12; /* [31:20], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } spi_cfg0; + + /* 0x1b4 reserved */ + uint8_t RESERVED0x1b4[12]; + + /* 0x1C0 : qdec_cfg0 */ + union { + struct { + uint32_t reserved_0_31 : 32; /* [31: 0], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } qdec_cfg0; + + /* 0x1c4 reserved */ + uint8_t RESERVED0x1c4[12]; + + /* 0x1D0 : pwm_cfg0 */ + union { + struct { + uint32_t reg_pwm1_io_sel : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_pwm2_io_sel : 1; /* [ 1], r/w, 0x0 */ + uint32_t reserved_2_31 : 30; /* [31: 2], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } pwm_cfg0; + + /* 0x1d4 reserved */ + uint8_t RESERVED0x1d4[12]; + + /* 0x1E0 : pdm_cfg0 */ + union { + struct { + uint32_t reg_pdm_io_sel : 1; /* [ 0], r/w, 0x0 */ + uint32_t reserved_1_31 : 31; /* [31: 1], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } pdm_cfg0; + + /* 0x1e4 reserved */ + uint8_t RESERVED0x1e4[108]; + + /* 0x250 : dig_clk_cfg0 */ + union { + struct { + uint32_t dig_32k_div : 11; /* [10: 0], r/w, 0x3e8 */ + uint32_t reserved_11 : 1; /* [ 11], rsvd, 0x0 */ + uint32_t dig_32k_en : 1; /* [ 12], r/w, 0x1 */ + uint32_t dig_32k_comp : 1; /* [ 13], r/w, 0x0 */ + uint32_t reserved_14_15 : 2; /* [15:14], rsvd, 0x0 */ + uint32_t dig_512k_div : 7; /* [22:16], r/w, 0x3e */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t dig_512k_en : 1; /* [ 24], r/w, 0x1 */ + uint32_t dig_512k_comp : 1; /* [ 25], r/w, 0x1 */ + uint32_t reserved_26_27 : 2; /* [27:26], rsvd, 0x0 */ + uint32_t dig_clk_src_sel : 2; /* [29:28], r/w, 0x0 */ + uint32_t reserved_30 : 1; /* [ 30], rsvd, 0x0 */ + uint32_t reg_en_platform_wakeup : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } dig_clk_cfg0; + + /* 0x254 : dig_clk_cfg1 */ + union { + struct { + uint32_t reg_mm_muxpll_160m_sel : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_mm_muxpll_240m_sel : 1; /* [ 1], r/w, 0x0 */ + uint32_t reg_mm_muxpll_320m_sel : 1; /* [ 2], r/w, 0x0 */ + uint32_t reserved_3_7 : 5; /* [ 7: 3], rsvd, 0x0 */ + uint32_t reg_top_muxpll_80m_sel : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reg_top_muxpll_160m_sel : 2; /* [11:10], r/w, 0x0 */ + uint32_t reserved_12_31 : 20; /* [31:12], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } dig_clk_cfg1; + + /* 0x258 : dig_clk_cfg2 */ + union { + struct { + uint32_t chip_clk_out_0_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t chip_clk_out_1_sel : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t chip_clk_out_2_sel : 2; /* [ 5: 4], r/w, 0x0 */ + uint32_t chip_clk_out_3_sel : 2; /* [ 7: 6], r/w, 0x0 */ + uint32_t chip_clk_out_0_en : 1; /* [ 8], r/w, 0x1 */ + uint32_t chip_clk_out_1_en : 1; /* [ 9], r/w, 0x1 */ + uint32_t chip_clk_out_2_en : 1; /* [ 10], r/w, 0x1 */ + uint32_t chip_clk_out_3_en : 1; /* [ 11], r/w, 0x1 */ + uint32_t gpio_tmr_clk_sel : 2; /* [13:12], r/w, 0x0 */ + uint32_t gpio_mm_tmr_clk_sel : 2; /* [15:14], r/w, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } dig_clk_cfg2; + + /* 0x25C : dig_clk_cfg3 */ + union { + struct { + uint32_t dsi_txclkesc_sel : 1; /* [ 0], r/w, 0x0 */ + uint32_t csi_txclkesc_sel : 1; /* [ 1], r/w, 0x0 */ + uint32_t reserved_2_31 : 30; /* [31: 2], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } dig_clk_cfg3; + + /* 0x260 : rf_cfg0 */ + union { + struct { + uint32_t reserved_0_8 : 9; /* [ 8: 0], rsvd, 0x0 */ + uint32_t cfg_inv_rf2_test_clk_o : 1; /* [ 9], r/w, 0x1 */ + uint32_t reserved_10_31 : 22; /* [31:10], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } rf_cfg0; + + /* 0x264 reserved */ + uint8_t RESERVED0x264[124]; + + /* 0x2E0 : dbg_cfg0 */ + union { + struct { + uint32_t reg_dbg_ll_ctrl : 30; /* [29: 0], r/w, 0x0 */ + uint32_t reg_dbg_ll_sel : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } dbg_cfg0; + + /* 0x2E4 : dbg_cfg1 */ + union { + struct { + uint32_t reg_dbg_lh_ctrl : 30; /* [29: 0], r/w, 0x0 */ + uint32_t reg_dbg_lh_sel : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } dbg_cfg1; + + /* 0x2E8 : dbg_cfg2 */ + union { + struct { + uint32_t reg_dbg_hl_ctrl : 30; /* [29: 0], r/w, 0x0 */ + uint32_t reg_dbg_hl_sel : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } dbg_cfg2; + + /* 0x2EC : dbg_cfg3 */ + union { + struct { + uint32_t reg_dbg_hh_ctrl : 30; /* [29: 0], r/w, 0x0 */ + uint32_t reg_dbg_hh_sel : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } dbg_cfg3; + + /* 0x2F0 : dbg_cfg4 */ + union { + struct { + uint32_t debug_oe : 1; /* [ 0], r/w, 0x0 */ + uint32_t debug_i : 31; /* [31: 1], r, 0x0 */ + } BF; + uint32_t WORD; + } dbg_cfg4; + + /* 0x2f4 reserved */ + uint8_t RESERVED0x2f4[12]; + + /* 0x300 : mbist_cfg0 */ + union { + struct { + uint32_t mbist_mode : 1; /* [ 0], r/w, 0x0 */ + uint32_t reserved_1_31 : 31; /* [31: 1], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mbist_cfg0; + + /* 0x304 reserved */ + uint8_t RESERVED0x304[28]; + + /* 0x320 : bmx_cfg0 */ + union { + struct { + uint32_t reg_bmx_timeout_en : 5; /* [ 4: 0], r/w, 0x0 */ + uint32_t reg_bmx_arb_mode : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_bmx_timeout_clr : 1; /* [ 6], r/w, 0x0 */ + uint32_t reg_h_wthre_hw2ext : 2; /* [ 8: 7], r/w, 0x0 */ + uint32_t bmx_busy_option_dis : 1; /* [ 9], r/w, 0x0 */ + uint32_t bmx_gating_dis : 1; /* [ 10], r/w, 0x0 */ + uint32_t sts_bmx_timeout_sts : 5; /* [15:11], r, 0x0 */ + uint32_t pds_apb_cfg : 8; /* [23:16], r/w, 0x0 */ + uint32_t hbn_apb_cfg : 8; /* [31:24], r/w, 0x0 */ + } BF; + uint32_t WORD; + } bmx_cfg0; + + /* 0x324 : bmx_cfg1 */ + union { + struct { + uint32_t reg_bmx_berr_int_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_mcu_berr_int_en : 1; /* [ 1], r/w, 0x0 */ + uint32_t reserved_2_15 : 14; /* [15: 2], rsvd, 0x0 */ + uint32_t reg_bmx_qos_cpu : 1; /* [ 16], r/w, 0x0 */ + uint32_t reg_bmx_qos_sdu : 1; /* [ 17], r/w, 0x0 */ + uint32_t reg_bmx_qos_sec0 : 1; /* [ 18], r/w, 0x0 */ + uint32_t reg_bmx_qos_sec1 : 1; /* [ 19], r/w, 0x0 */ + uint32_t reg_bmx_qos_sec2 : 1; /* [ 20], r/w, 0x0 */ + uint32_t reg_bmx_qos_dma : 1; /* [ 21], r/w, 0x0 */ + uint32_t reg_bmx_qos_cci : 1; /* [ 22], r/w, 0x0 */ + uint32_t reg_bmx_qos_pldma : 1; /* [ 23], r/w, 0x0 */ + uint32_t reg_bmx_qos_blem : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_bmx_qos_emacA : 1; /* [ 25], r/w, 0x0 */ + uint32_t reg_bmx_qos_dma2 : 1; /* [ 26], r/w, 0x0 */ + uint32_t reg_bmx_qos_sdhm : 1; /* [ 27], r/w, 0x0 */ + uint32_t bmx_dbg_sel : 4; /* [31:28], r/w, 0x0 */ + } BF; + uint32_t WORD; + } bmx_cfg1; + + /* 0x328 : bmx_cfg2 */ + union { + struct { + uint32_t reg_bmx_berr_en : 14; /* [13: 0], r/w, 0x3fff */ + uint32_t reserved_14_15 : 2; /* [15:14], rsvd, 0x0 */ + uint32_t reg_mcu_berr_en : 1; /* [ 16], r/w, 0x1 */ + uint32_t reserved_17_31 : 15; /* [31:17], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } bmx_cfg2; + + /* 0x32C : bmx_cfg3 */ + union { + struct { + uint32_t reg_bmx_berr_clr : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_bmx_berr_last : 1; /* [ 1], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t reg_mcu_berr_clr : 1; /* [ 8], r/w, 0x0 */ + uint32_t reg_mcu_berr_last : 1; /* [ 9], r/w, 0x0 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t sts_bmx_berr : 1; /* [ 16], r, 0x0 */ + uint32_t sts_mcu_berr : 1; /* [ 17], r, 0x0 */ + uint32_t reserved_18_23 : 6; /* [23:18], rsvd, 0x0 */ + uint32_t sts_bmx_berr_write : 1; /* [ 24], r, 0x0 */ + uint32_t sts_mcu_berr_write : 1; /* [ 25], r, 0x0 */ + uint32_t reserved_26_31 : 6; /* [31:26], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } bmx_cfg3; + + /* 0x330 : bmx_cfg4 */ + union { + struct { + uint32_t sts_bmx_berr_src : 14; /* [13: 0], r, 0x0 */ + uint32_t reserved_14_15 : 2; /* [15:14], rsvd, 0x0 */ + uint32_t sts_mcu_berr_src : 1; /* [ 16], r, 0x0 */ + uint32_t reserved_17_23 : 7; /* [23:17], rsvd, 0x0 */ + uint32_t sts_mcu_berr_id : 8; /* [31:24], r, 0x0 */ + } BF; + uint32_t WORD; + } bmx_cfg4; + + /* 0x334 : bmx_cfg5 */ + union { + struct { + uint32_t sts_bmx_berr_addr : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } bmx_cfg5; + + /* 0x338 : bmx_cfg6 */ + union { + struct { + uint32_t sts_mcu_berr_addr : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } bmx_cfg6; + + /* 0x33c reserved */ + uint8_t RESERVED0x33c[4]; + + /* 0x340 : audio_cfg0 */ + union { + struct { + uint32_t reg_audio_pdm_clk_div : 6; /* [ 5: 0], r/w, 0x3 */ + uint32_t reserved_6 : 1; /* [ 6], rsvd, 0x0 */ + uint32_t reg_audio_pdm_clk_en : 1; /* [ 7], r/w, 0x1 */ + uint32_t reg_audio_adc_clk_div : 6; /* [13: 8], r/w, 0x3 */ + uint32_t reserved_14 : 1; /* [ 14], rsvd, 0x0 */ + uint32_t reg_audio_adc_clk_en : 1; /* [ 15], r/w, 0x1 */ + uint32_t reg_audio_dac_clk_div : 6; /* [21:16], r/w, 0x3 */ + uint32_t reserved_22 : 1; /* [ 22], rsvd, 0x0 */ + uint32_t reg_audio_dac_clk_en : 1; /* [ 23], r/w, 0x1 */ + uint32_t reserved_24_30 : 7; /* [30:24], rsvd, 0x0 */ + uint32_t reg_audio_auto_div_en : 1; /* [ 31], r/w, 0x1 */ + } BF; + uint32_t WORD; + } audio_cfg0; + + /* 0x344 : audio_cfg1 */ + union { + struct { + uint32_t reg_padc_clk_div : 10; /* [ 9: 0], r/w, 0x60 */ + uint32_t reg_padc_clk_en : 1; /* [ 10], r/w, 0x1 */ + uint32_t reserved_11_31 : 21; /* [31:11], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } audio_cfg1; + + /* 0x348 reserved */ + uint8_t RESERVED0x348[72]; + + /* 0x390 : eth_cfg0 */ + union { + struct { + uint32_t reserved_0_4 : 5; /* [ 4: 0], rsvd, 0x0 */ + uint32_t cfg_sel_eth_ref_clk_o : 1; /* [ 5], r/w, 0x0 */ + uint32_t cfg_inv_eth_ref_clk_o : 1; /* [ 6], r/w, 0x1 */ + uint32_t cfg_inv_eth_tx_clk : 1; /* [ 7], r/w, 0x1 */ + uint32_t reserved_8_9 : 2; /* [ 9: 8], rsvd, 0x0 */ + uint32_t cfg_inv_eth_rx_clk : 1; /* [ 10], r/w, 0x1 */ + uint32_t reserved_11_31 : 21; /* [31:11], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } eth_cfg0; + + /* 0x394 reserved */ + uint8_t RESERVED0x394[140]; + + /* 0x420 : cam_cfg0 */ + union { + struct { + uint32_t reserved_0_26 : 27; /* [26: 0], rsvd, 0x0 */ + uint32_t reg_cam_ref_clk_en : 1; /* [ 27], r/w, 0x0 */ + uint32_t reg_cam_ref_clk_src_sel : 2; /* [29:28], r/w, 0x0 */ + uint32_t reg_cam_ref_clk_div : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } cam_cfg0; + + /* 0x424 reserved */ + uint8_t RESERVED0x424[12]; + + /* 0x430 : sdh_cfg0 */ + union { + struct { + uint32_t reserved_0_8 : 9; /* [ 8: 0], rsvd, 0x0 */ + uint32_t reg_sdh_clk_div : 3; /* [11: 9], r/w, 0x0 */ + uint32_t reg_sdh_clk_sel : 1; /* [ 12], r/w, 0x0 */ + uint32_t reg_sdh_clk_en : 1; /* [ 13], r/w, 0x1 */ + uint32_t reserved_14_31 : 18; /* [31:14], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sdh_cfg0; + + /* 0x434 reserved */ + uint8_t RESERVED0x434[92]; + + /* 0x490 : tzc_cfg0 */ + union { + struct { + uint32_t reserved_0_11 : 12; /* [11: 0], rsvd, 0x0 */ + uint32_t tzc_glb_pwron_rst_lock : 1; /* [ 12], r, 0x0 */ + uint32_t tzc_glb_cpu_reset_lock : 1; /* [ 13], r, 0x0 */ + uint32_t tzc_glb_sys_reset_lock : 1; /* [ 14], r, 0x0 */ + uint32_t tzc_glb_cpu2_reset_lock : 1; /* [ 15], r, 0x0 */ + uint32_t reserved_16_20 : 5; /* [20:16], rsvd, 0x0 */ + uint32_t tzc_glb_pwr_lock : 1; /* [ 21], r, 0x0 */ + uint32_t tzc_glb_int_lock : 1; /* [ 22], r, 0x0 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t tzc_glb_cpupll_lock : 1; /* [ 24], r, 0x0 */ + uint32_t tzc_glb_misc_lock : 1; /* [ 25], r, 0x0 */ + uint32_t tzc_glb_sram_lock : 1; /* [ 26], r, 0x0 */ + uint32_t tzc_glb_swrst_lock : 1; /* [ 27], r, 0x0 */ + uint32_t tzc_glb_bmx_lock : 1; /* [ 28], r, 0x0 */ + uint32_t tzc_glb_dbg_lock : 1; /* [ 29], r, 0x0 */ + uint32_t tzc_glb_mbist_lock : 1; /* [ 30], r, 0x0 */ + uint32_t tzc_glb_clk_lock : 1; /* [ 31], r, 0x0 */ + } BF; + uint32_t WORD; + } tzc_cfg0; + + /* 0x494 reserved */ + uint8_t RESERVED0x494[124]; + + /* 0x510 : glb_parm_cfg0 */ + union { + struct { + uint32_t reg_bd_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t reserved_1 : 1; /* [ 1], rsvd, 0x0 */ + uint32_t uart_swap_set : 4; /* [ 5: 2], r/w, 0x0 */ + uint32_t reserved_6_7 : 2; /* [ 7: 6], rsvd, 0x0 */ + uint32_t swap_sflash_io_3_io_0 : 1; /* [ 8], r/w, 0x1 */ + uint32_t sel_embedded_sflash : 1; /* [ 9], r/w, 0x1 */ + uint32_t reserved_10 : 1; /* [ 10], rsvd, 0x0 */ + uint32_t reg_sel_psram0_x16 : 1; /* [ 11], r/w, 0x1 */ + uint32_t reg_spi_0_master_mode : 1; /* [ 12], r/w, 0x0 */ + uint32_t reg_spi_0_swap : 1; /* [ 13], r/w, 0x0 */ + uint32_t reg_sel_dbi_type_c : 1; /* [ 14], r/w, 0x0 */ + uint32_t ant_switch_sel : 1; /* [ 15], r/w, 0x0 */ + uint32_t reserved_16 : 1; /* [ 16], rsvd, 0x0 */ + uint32_t p1_adc_test_with_cci : 1; /* [ 17], r/w, 0x0 */ + uint32_t p2_dac_test_with_cci : 1; /* [ 18], r/w, 0x0 */ + uint32_t p3_cci_use_io_2_5 : 1; /* [ 19], r/w, 0x0 */ + uint32_t p4_adc_test_with_jtag : 1; /* [ 20], r/w, 0x0 */ + uint32_t p5_dac_test_with_jtag : 1; /* [ 21], r/w, 0x0 */ + uint32_t p6_sdh_use_io_0_5 : 1; /* [ 22], r/w, 0x0 */ + uint32_t p7_jtag_use_io_2_5 : 1; /* [ 23], r/w, 0x0 */ + uint32_t reserved_24 : 1; /* [ 24], rsvd, 0x0 */ + uint32_t rf1_test_mode : 2; /* [26:25], r/w, 0x0 */ + uint32_t reg_mm_spi_master_mode : 1; /* [ 27], r/w, 0x0 */ + uint32_t reg_mm_spi_swap : 1; /* [ 28], r/w, 0x0 */ + uint32_t audio_test_mode : 1; /* [ 29], r/w, 0x0 */ + uint32_t sel_rf_audio_test : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } glb_parm_cfg0; + + /* 0x514 reserved */ + uint8_t RESERVED0x514[12]; + + /* 0x520 : debug_cfg0 */ + union { + struct { + uint32_t reserved_0_31 : 32; /* [31: 0], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } debug_cfg0; + + /* 0x524 : debug_cfg1 */ + union { + struct { + uint32_t reserved_0_19 : 20; /* [19: 0], rsvd, 0x0 */ + uint32_t debug_ndreset_gate : 1; /* [ 20], r/w, 0x0 */ + uint32_t reserved_21_31 : 11; /* [31:21], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } debug_cfg1; + + /* 0x528 reserved */ + uint8_t RESERVED0x528[8]; + + /* 0x530 : reset_sts0 */ + union { + struct { + uint32_t top_reset_recorder : 7; /* [ 6: 0], r, 0x0 */ + uint32_t clr_top_reset_recorder : 1; /* [ 7], r/w, 0x0 */ + uint32_t reserved_8_31 : 24; /* [31: 8], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } reset_sts0; + + /* 0x534 reserved */ + uint8_t RESERVED0x534[12]; + + /* 0x540 : swrst_s1_ext + swrst_s3 + swrst_s2 */ + union { + struct { + uint32_t swrst_s00 : 1; /* [ 0], r/w, 0x0 */ + uint32_t swrst_s01 : 1; /* [ 1], r/w, 0x0 */ + uint32_t reserved_2_3 : 2; /* [ 3: 2], rsvd, 0x0 */ + uint32_t swrst_s20 : 1; /* [ 4], r/w, 0x0 */ + uint32_t reserved_5_7 : 3; /* [ 7: 5], rsvd, 0x0 */ + uint32_t swrst_s30 : 1; /* [ 8], r/w, 0x0 */ + uint32_t swrst_s31 : 1; /* [ 9], r/w, 0x0 */ + uint32_t swrst_s32 : 1; /* [ 10], r/w, 0x0 */ + uint32_t swrst_s33 : 1; /* [ 11], r/w, 0x0 */ + uint32_t reserved_12_15 : 4; /* [15:12], rsvd, 0x0 */ + uint32_t swrst_s1_ext_emi_misc : 1; /* [ 16], r/w, 0x0 */ + uint32_t swrst_s1_ext_psram0_ctrl : 1; /* [ 17], r/w, 0x0 */ + uint32_t swrst_s1_ext_psram1_ctrl : 1; /* [ 18], r/w, 0x0 */ + uint32_t swrst_s1_ext_usb : 1; /* [ 19], r/w, 0x0 */ + uint32_t swrst_s1_ext_mix2 : 1; /* [ 20], r/w, 0x0 */ + uint32_t swrst_s1_ext_audio : 1; /* [ 21], r/w, 0x0 */ + uint32_t swrst_s1_ext_sdh : 1; /* [ 22], r/w, 0x0 */ + uint32_t swrst_s1_ext_emac : 1; /* [ 23], r/w, 0x0 */ + uint32_t swrst_s1_ext_dma2 : 1; /* [ 24], r/w, 0x0 */ + uint32_t reserved_25_31 : 7; /* [31:25], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } swrst_cfg0; + + /* 0x544 : swrst_s1 */ + union { + struct { + uint32_t swrst_s10 : 1; /* [ 0], r/w, 0x0 */ + uint32_t swrst_s11 : 1; /* [ 1], r/w, 0x0 */ + uint32_t swrst_s12 : 1; /* [ 2], r/w, 0x0 */ + uint32_t swrst_s13 : 1; /* [ 3], r/w, 0x0 */ + uint32_t swrst_s14 : 1; /* [ 4], r/w, 0x0 */ + uint32_t swrst_s15 : 1; /* [ 5], r/w, 0x0 */ + uint32_t swrst_s16 : 1; /* [ 6], r/w, 0x0 */ + uint32_t swrst_s17 : 1; /* [ 7], r/w, 0x0 */ + uint32_t swrst_s18 : 1; /* [ 8], r/w, 0x0 */ + uint32_t swrst_s19 : 1; /* [ 9], r/w, 0x0 */ + uint32_t swrst_s1a : 1; /* [ 10], r/w, 0x0 */ + uint32_t swrst_s1b : 1; /* [ 11], r/w, 0x0 */ + uint32_t swrst_s1c : 1; /* [ 12], r/w, 0x0 */ + uint32_t swrst_s1d : 1; /* [ 13], r/w, 0x0 */ + uint32_t swrst_s1e : 1; /* [ 14], r/w, 0x0 */ + uint32_t swrst_s1f : 1; /* [ 15], r/w, 0x0 */ + uint32_t swrst_s1a0 : 1; /* [ 16], r/w, 0x0 */ + uint32_t swrst_s1a1 : 1; /* [ 17], r/w, 0x0 */ + uint32_t swrst_s1a2 : 1; /* [ 18], r/w, 0x0 */ + uint32_t swrst_s1a3 : 1; /* [ 19], r/w, 0x0 */ + uint32_t swrst_s1a4 : 1; /* [ 20], r/w, 0x0 */ + uint32_t swrst_s1a5 : 1; /* [ 21], r/w, 0x0 */ + uint32_t swrst_s1a6 : 1; /* [ 22], r/w, 0x0 */ + uint32_t swrst_s1a7 : 1; /* [ 23], r/w, 0x0 */ + uint32_t swrst_s1a8 : 1; /* [ 24], r/w, 0x0 */ + uint32_t swrst_s1a9 : 1; /* [ 25], r/w, 0x0 */ + uint32_t swrst_s1aa : 1; /* [ 26], r/w, 0x0 */ + uint32_t swrst_s1ab : 1; /* [ 27], r/w, 0x0 */ + uint32_t swrst_s1ac : 1; /* [ 28], r/w, 0x0 */ + uint32_t swrst_s1ad : 1; /* [ 29], r/w, 0x0 */ + uint32_t swrst_s1ae : 1; /* [ 30], r/w, 0x0 */ + uint32_t swrst_s1af : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } swrst_cfg1; + + /* 0x548 : swrst_cfg2 */ + union { + struct { + uint32_t reg_ctrl_pwron_rst : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_ctrl_cpu_reset : 1; /* [ 1], r/w, 0x0 */ + uint32_t reg_ctrl_sys_reset : 1; /* [ 2], r/w, 0x0 */ + uint32_t reg_ctrl_pico_reset : 1; /* [ 3], r/w, 0x0 */ + uint32_t reg_ctrl_cpu2_reset : 1; /* [ 4], r/w, 0x1 */ + uint32_t reg_ctrl_chip_reset : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_wl_wdt_reset_mm_en : 1; /* [ 6], r/w, 0x0 */ + uint32_t reg_mmwdt2wl_rst_msk : 1; /* [ 7], r/w, 0x1 */ + uint32_t reserved_8_23 : 16; /* [23: 8], rsvd, 0x0 */ + uint32_t pka_clk_sel : 1; /* [ 24], r/w, 0x0 */ + uint32_t reserved_25_27 : 3; /* [27:25], rsvd, 0x0 */ + uint32_t reg_ctrl_reset_dummy : 4; /* [31:28], r/w, 0x0 */ + } BF; + uint32_t WORD; + } swrst_cfg2; + + /* 0x54C : Disable hreset */ + union { + struct { + uint32_t reserved_0_1 : 2; /* [ 1: 0], rsvd, 0x0 */ + uint32_t disrst_s12 : 1; /* [ 2], r/w, 0x0 */ + uint32_t reserved_3 : 1; /* [ 3], rsvd, 0x0 */ + uint32_t disrst_s14 : 1; /* [ 4], r/w, 0x0 */ + uint32_t reserved_5_7 : 3; /* [ 7: 5], rsvd, 0x0 */ + uint32_t disrst_s18 : 1; /* [ 8], r/w, 0x0 */ + uint32_t reserved_9_10 : 2; /* [10: 9], rsvd, 0x0 */ + uint32_t disrst_s1b : 1; /* [ 11], r/w, 0x0 */ + uint32_t reserved_12_15 : 4; /* [15:12], rsvd, 0x0 */ + uint32_t disrst_s1a0 : 1; /* [ 16], r/w, 0x0 */ + uint32_t disrst_s1a1 : 1; /* [ 17], r/w, 0x0 */ + uint32_t disrst_s1a2 : 1; /* [ 18], r/w, 0x0 */ + uint32_t disrst_s1a3 : 1; /* [ 19], r/w, 0x0 */ + uint32_t disrst_s1a4 : 1; /* [ 20], r/w, 0x0 */ + uint32_t disrst_s1a5 : 1; /* [ 21], r/w, 0x0 */ + uint32_t disrst_s1a6 : 1; /* [ 22], r/w, 0x0 */ + uint32_t disrst_s1a7 : 1; /* [ 23], r/w, 0x0 */ + uint32_t disrst_s1a8 : 1; /* [ 24], r/w, 0x0 */ + uint32_t disrst_s1a9 : 1; /* [ 25], r/w, 0x0 */ + uint32_t disrst_s1aa : 1; /* [ 26], r/w, 0x0 */ + uint32_t reserved_27_31 : 5; /* [31:27], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } swrst_cfg3; + + /* 0x550 reserved */ + uint8_t RESERVED0x550[48]; + + /* 0x580 : cgen_m */ + union { + struct { + uint32_t cgen_m_cpu : 1; /* [ 0], r/w, 0x1 */ + uint32_t cgen_m_sdu : 1; /* [ 1], r/w, 0x1 */ + uint32_t cgen_m_sec : 1; /* [ 2], r/w, 0x1 */ + uint32_t cgen_m_dma : 1; /* [ 3], r/w, 0x1 */ + uint32_t cgen_m_cci : 1; /* [ 4], r/w, 0x1 */ + uint32_t reserved_5_31 : 27; /* [31: 5], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } cgen_cfg0; + + /* 0x584 : cgen_s1a + cgen_s1 */ + union { + struct { + uint32_t cgen_s1_rsvd0 : 1; /* [ 0], r/w, 0x1 */ + uint32_t reserved_1 : 1; /* [ 1], rsvd, 0x0 */ + uint32_t cgen_s1_gpip : 1; /* [ 2], r/w, 0x1 */ + uint32_t cgen_s1_sec_dbg : 1; /* [ 3], r/w, 0x1 */ + uint32_t cgen_s1_sec_eng : 1; /* [ 4], r/w, 0x1 */ + uint32_t cgen_s1_tz : 1; /* [ 5], r/w, 0x1 */ + uint32_t cgen_s1_rsvd6 : 1; /* [ 6], r/w, 0x1 */ + uint32_t cgen_s1_ef_ctrl : 1; /* [ 7], r/w, 0x1 */ + uint32_t cgen_s1_rsvd8 : 1; /* [ 8], r/w, 0x1 */ + uint32_t cgen_s1_rsvd9 : 1; /* [ 9], r/w, 0x1 */ + uint32_t cgen_s1_rsvd10 : 1; /* [ 10], r/w, 0x1 */ + uint32_t cgen_s1_sf_ctrl : 1; /* [ 11], r/w, 0x1 */ + uint32_t cgen_s1_dma : 1; /* [ 12], r/w, 0x0 */ + uint32_t cgen_s1_rsvd13 : 1; /* [ 13], r/w, 0x0 */ + uint32_t cgen_s1_rsvd14 : 1; /* [ 14], r/w, 0x1 */ + uint32_t cgen_s1_rsvd15 : 1; /* [ 15], r/w, 0x1 */ + uint32_t cgen_s1a_uart0 : 1; /* [ 16], r/w, 0x1 */ + uint32_t cgen_s1a_uart1 : 1; /* [ 17], r/w, 0x1 */ + uint32_t cgen_s1a_spi : 1; /* [ 18], r/w, 0x0 */ + uint32_t cgen_s1a_i2c : 1; /* [ 19], r/w, 0x0 */ + uint32_t cgen_s1a_pwm : 1; /* [ 20], r/w, 0x0 */ + uint32_t cgen_s1a_timer : 1; /* [ 21], r/w, 0x1 */ + uint32_t cgen_s1a_ir : 1; /* [ 22], r/w, 0x0 */ + uint32_t cgen_s1a_cks : 1; /* [ 23], r/w, 0x0 */ + uint32_t cgen_s1a_rsvd8 : 1; /* [ 24], r/w, 0x1 */ + uint32_t cgen_s1a_i2c1 : 1; /* [ 25], r/w, 0x1 */ + uint32_t cgen_s1a_uart2 : 1; /* [ 26], r/w, 0x0 */ + uint32_t cgen_s1a_rsvd11 : 1; /* [ 27], r/w, 0x1 */ + uint32_t cgen_s1a_rsvd12 : 1; /* [ 28], r/w, 0x1 */ + uint32_t cgen_s1a_rsvd13 : 1; /* [ 29], r/w, 0x0 */ + uint32_t cgen_s1a_rsvd14 : 1; /* [ 30], r/w, 0x0 */ + uint32_t cgen_s1a_rsvd15 : 1; /* [ 31], r/w, 0x1 */ + } BF; + uint32_t WORD; + } cgen_cfg1; + + /* 0x588 : cgen_s1_ext + cgen_s3 */ + union { + struct { + uint32_t cgen_s0 : 1; /* [ 0], r/w, 0x1 */ + uint32_t reserved_1_3 : 3; /* [ 3: 1], rsvd, 0x0 */ + uint32_t cgen_s2_wifi : 1; /* [ 4], r/w, 0x1 */ + uint32_t reserved_5_9 : 5; /* [ 9: 5], rsvd, 0x0 */ + uint32_t cgen_s3_bt_ble2 : 1; /* [ 10], r/w, 0x1 */ + uint32_t cgen_s3_m1542 : 1; /* [ 11], r/w, 0x1 */ + uint32_t reserved_12_15 : 4; /* [15:12], rsvd, 0x0 */ + uint32_t cgen_s1_ext_emi_misc : 1; /* [ 16], r/w, 0x1 */ + uint32_t cgen_s1_ext_psram0_ctrl : 1; /* [ 17], r/w, 0x1 */ + uint32_t cgen_s1_ext_psram_ctrl : 1; /* [ 18], r/w, 0x1 */ + uint32_t cgen_s1_ext_usb : 1; /* [ 19], r/w, 0x1 */ + uint32_t cgen_s1_ext_mix2 : 1; /* [ 20], r/w, 0x1 */ + uint32_t cgen_s1_ext_audio : 1; /* [ 21], r/w, 0x1 */ + uint32_t cgen_s1_ext_sdh : 1; /* [ 22], r/w, 0x1 */ + uint32_t cgen_s1_ext_emac : 1; /* [ 23], r/w, 0x1 */ + uint32_t cgen_s1_ext_dma2 : 1; /* [ 24], r/w, 0x1 */ + uint32_t cgen_s1_ext_rsvd9 : 1; /* [ 25], r/w, 0x1 */ + uint32_t cgen_s1_ext_rsvd10 : 1; /* [ 26], r/w, 0x1 */ + uint32_t cgen_s1_ext_rsvd11 : 1; /* [ 27], r/w, 0x1 */ + uint32_t reserved_28_31 : 4; /* [31:28], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } cgen_cfg2; + + /* 0x58C : cgen_cfg3 */ + union { + struct { + uint32_t cgen_mm_wifipll_160m : 1; /* [ 0], r/w, 0x1 */ + uint32_t cgen_mm_wifipll_240m : 1; /* [ 1], r/w, 0x1 */ + uint32_t cgen_mm_wifipll_320m : 1; /* [ 2], r/w, 0x1 */ + uint32_t cgen_mm_aupll_div1 : 1; /* [ 3], r/w, 0x1 */ + uint32_t cgen_mm_aupll_div2 : 1; /* [ 4], r/w, 0x1 */ + uint32_t cgen_emi_cpupll_400m : 1; /* [ 5], r/w, 0x1 */ + uint32_t cgen_emi_cpupll_200m : 1; /* [ 6], r/w, 0x1 */ + uint32_t cgen_emi_wifipll_320m : 1; /* [ 7], r/w, 0x1 */ + uint32_t cgen_emi_aupll_div1 : 1; /* [ 8], r/w, 0x1 */ + uint32_t cgen_top_cpupll_80m : 1; /* [ 9], r/w, 0x1 */ + uint32_t cgen_top_cpupll_100m : 1; /* [ 10], r/w, 0x1 */ + uint32_t cgen_top_cpupll_160m : 1; /* [ 11], r/w, 0x1 */ + uint32_t cgen_top_cpupll_400m : 1; /* [ 12], r/w, 0x1 */ + uint32_t cgen_top_wifipll_240m : 1; /* [ 13], r/w, 0x1 */ + uint32_t cgen_top_wifipll_320m : 1; /* [ 14], r/w, 0x1 */ + uint32_t cgen_top_aupll_div2 : 1; /* [ 15], r/w, 0x1 */ + uint32_t cgen_top_aupll_div1 : 1; /* [ 16], r/w, 0x1 */ + uint32_t reserved_17_31 : 15; /* [31:17], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } cgen_cfg3; + + /* 0x590 reserved */ + uint8_t RESERVED0x590[48]; + + /* 0x5C0 : hw_rsv0 */ + union { + struct { + uint32_t rsvd_31_0 : 32; /* [31: 0], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } hw_rsv0; + + /* 0x5C4 : hw_rsv1 */ + union { + struct { + uint32_t rsvd_31_0 : 32; /* [31: 0], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } hw_rsv1; + + /* 0x5C8 : hw_rsv2 */ + union { + struct { + uint32_t rsvd_31_0 : 32; /* [31: 0], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } hw_rsv2; + + /* 0x5CC : hw_rsv3 */ + union { + struct { + uint32_t rsvd_31_0 : 32; /* [31: 0], rsvd, 0xffffffff */ + } BF; + uint32_t WORD; + } hw_rsv3; + + /* 0x5d0 reserved */ + uint8_t RESERVED0x5d0[48]; + + /* 0x600 : reg_sram_ret */ + union { + struct { + uint32_t cr_mcu_cache_ret : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t cr_mcu_hsram_ret : 4; /* [ 5: 2], r/w, 0x0 */ + uint32_t reserved_6_7 : 2; /* [ 7: 6], rsvd, 0x0 */ + uint32_t cr_wb_ram_ret : 1; /* [ 8], r/w, 0x0 */ + uint32_t cr_misc_ram_ret : 2; /* [10: 9], r/w, 0x0 */ + uint32_t reserved_11_31 : 21; /* [31:11], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sram_cfg0; + + /* 0x604 : reg_sram_slp */ + union { + struct { + uint32_t cr_mcu_cache_slp : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t cr_mcu_hsram_slp : 4; /* [ 5: 2], r/w, 0x0 */ + uint32_t cr_mcu_rom_slp : 2; /* [ 7: 6], r/w, 0x0 */ + uint32_t cr_wb_ram_slp : 1; /* [ 8], r/w, 0x0 */ + uint32_t cr_misc_ram_slp : 2; /* [10: 9], r/w, 0x0 */ + uint32_t reserved_11_31 : 21; /* [31:11], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sram_cfg1; + + /* 0x608 : reg_sram_parm */ + union { + struct { + uint32_t cr_mcu_cache_dvse : 1; /* [ 0], r/w, 0x0 */ + uint32_t cr_mcu_hsram_dvse : 1; /* [ 1], r/w, 0x0 */ + uint32_t cr_mcu_rom_dvse : 1; /* [ 2], r/w, 0x0 */ + uint32_t cr_wb_ram_dvse : 1; /* [ 3], r/w, 0x0 */ + uint32_t cr_misc_ram_dvse : 1; /* [ 4], r/w, 0x0 */ + uint32_t cr_ocram_dvse : 1; /* [ 5], r/w, 0x0 */ + uint32_t cr_wram_dvse : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t cr_mcu_cache_nap : 1; /* [ 8], r/w, 0x0 */ + uint32_t cr_mcu_hsram_nap : 1; /* [ 9], r/w, 0x0 */ + uint32_t reserved_10 : 1; /* [ 10], rsvd, 0x0 */ + uint32_t cr_wb_ram_nap : 1; /* [ 11], r/w, 0x0 */ + uint32_t cr_misc_ram_nap : 1; /* [ 12], r/w, 0x0 */ + uint32_t cr_ocram_nap : 1; /* [ 13], r/w, 0x0 */ + uint32_t cr_wram_nap : 1; /* [ 14], r/w, 0x0 */ + uint32_t reserved_15_31 : 17; /* [31:15], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sram_cfg2; + + /* 0x60C : sram_cfg3 */ + union { + struct { + uint32_t em_sel : 8; /* [ 7: 0], r/w, 0x3 */ + uint32_t reserved_8_27 : 20; /* [27: 8], rsvd, 0x0 */ + uint32_t reg_vram_sel : 2; /* [29:28], r/w, 0x0 */ + uint32_t reserved_30_31 : 2; /* [31:30], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sram_cfg3; + + /* 0x610 : reg_sram_parm2 */ + union { + struct { + uint32_t cr_mcu_cache_dvs : 4; /* [ 3: 0], r/w, 0xc */ + uint32_t cr_mcu_hsram_dvs : 4; /* [ 7: 4], r/w, 0xc */ + uint32_t cr_mcu_rom_dvs : 4; /* [11: 8], r/w, 0xc */ + uint32_t cr_wb_ram_dvs : 4; /* [15:12], r/w, 0xc */ + uint32_t cr_misc_ram_dvs : 4; /* [19:16], r/w, 0xc */ + uint32_t cr_ocram_dvs : 4; /* [23:20], r/w, 0xc */ + uint32_t cr_wram_dvs : 4; /* [27:24], r/w, 0xc */ + uint32_t reserved_28_31 : 4; /* [31:28], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sram_cfg4; + + /* 0x614 reserved */ + uint8_t RESERVED0x614[12]; + + /* 0x620 : psram_cfg0 */ + union { + struct { + uint32_t reserved_0_26 : 27; /* [26: 0], rsvd, 0x0 */ + uint32_t reg_psramB_clk_en : 1; /* [ 27], r/w, 0x1 */ + uint32_t reg_psramB_clk_sel : 2; /* [29:28], r/w, 0x0 */ + uint32_t reg_psramB_clk_div : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } psram_cfg0; + + /* 0x624 reserved */ + uint8_t RESERVED0x624[156]; + + /* 0x6C0 : ldo28cis */ + union { + struct { + uint32_t pu_ldo28cis : 1; /* [ 0], r/w, 0x1 */ + uint32_t ldo28cis_bypass : 1; /* [ 1], r/w, 0x0 */ + uint32_t ldo28cis_pulldown : 1; /* [ 2], r/w, 0x0 */ + uint32_t ldo28cis_pulldown_sel : 1; /* [ 3], r/w, 0x0 */ + uint32_t ldo28cis_bm : 3; /* [ 6: 4], r/w, 0x5 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t ldo28cis_cc : 3; /* [10: 8], r/w, 0x3 */ + uint32_t ldo28cis_ocp_out : 1; /* [ 11], r, 0x0 */ + uint32_t ldo28cis_ocp_th : 3; /* [14:12], r/w, 0x3 */ + uint32_t ldo28cis_ocp_en : 1; /* [ 15], r/w, 0x1 */ + uint32_t ldo28cis_sstart_delay : 3; /* [18:16], r/w, 0x2 */ + uint32_t ldo28cis_sstart_en : 1; /* [ 19], r/w, 0x1 */ + uint32_t ldo28cis_vout_sel : 4; /* [23:20], r/w, 0x3 */ + uint32_t ldo28cis_vout_trim : 4; /* [27:24], r/w, 0x8 */ + uint32_t reserved_28_31 : 4; /* [31:28], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } ldo28cis; + + /* 0x6C4 : ldo18io */ + union { + struct { + uint32_t reserved_0_31 : 32; /* [31: 0], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } ldo18io; + + /* 0x6C8 : ldo15cis */ + union { + struct { + uint32_t pu_ldo15cis : 1; /* [ 0], r/w, 0x1 */ + uint32_t ldo15cis_bypass : 1; /* [ 1], r/w, 0x0 */ + uint32_t ldo15cis_pulldown : 1; /* [ 2], r/w, 0x0 */ + uint32_t ldo15cis_pulldown_sel : 1; /* [ 3], r/w, 0x0 */ + uint32_t ldo15cis_bm : 3; /* [ 6: 4], r/w, 0x2 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t ldo15cis_cc : 3; /* [10: 8], r/w, 0x3 */ + uint32_t ldo15cis_ocp_out : 1; /* [ 11], r, 0x0 */ + uint32_t ldo15cis_ocp_th : 3; /* [14:12], r/w, 0x3 */ + uint32_t ldo15cis_ocp_en : 1; /* [ 15], r/w, 0x1 */ + uint32_t ldo15cis_sstart_delay : 3; /* [18:16], r/w, 0x2 */ + uint32_t ldo15cis_sstart_en : 1; /* [ 19], r/w, 0x1 */ + uint32_t ldo15cis_vout_sel : 4; /* [23:20], r/w, 0x8 */ + uint32_t ldo15cis_vout_trim : 4; /* [27:24], r/w, 0x8 */ + uint32_t reserved_28_31 : 4; /* [31:28], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } ldo15cis; + + /* 0x6CC : ldo18flash */ + union { + struct { + uint32_t pu_ldo18flash : 1; /* [ 0], r/w, 0x0 */ + uint32_t ldo18flash_bypass : 1; /* [ 1], r/w, 0x0 */ + uint32_t ldo18flash_pulldown : 1; /* [ 2], r/w, 0x0 */ + uint32_t ldo18flash_pulldown_sel : 1; /* [ 3], r/w, 0x0 */ + uint32_t ldo18flash_bm : 3; /* [ 6: 4], r/w, 0x3 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t ldo18flash_cc : 3; /* [10: 8], r/w, 0x3 */ + uint32_t ldo18flash_ocp_out : 1; /* [ 11], r, 0x0 */ + uint32_t ldo18flash_ocp_th : 3; /* [14:12], r/w, 0x3 */ + uint32_t ldo18flash_ocp_en : 1; /* [ 15], r/w, 0x1 */ + uint32_t ldo18flash_sstart_delay : 3; /* [18:16], r/w, 0x3 */ + uint32_t ldo18flash_sstart_en : 1; /* [ 19], r/w, 0x1 */ + uint32_t ldo18flash_vout_sel : 4; /* [23:20], r/w, 0x3 */ + uint32_t ldo18flash_vout_trim : 4; /* [27:24], r/w, 0x7 */ + uint32_t reserved_28_31 : 4; /* [31:28], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } ldo18flash; + + /* 0x6D0 : ldo12uhs */ + union { + struct { + uint32_t pu_ldo12uhs : 1; /* [ 0], r/w, 0x0 */ + uint32_t ldo12uhs_bypass : 1; /* [ 1], r/w, 0x0 */ + uint32_t ldo12uhs_pulldown : 1; /* [ 2], r/w, 0x0 */ + uint32_t ldo12uhs_pulldown_sel : 1; /* [ 3], r/w, 0x0 */ + uint32_t ldo12uhs_bm : 3; /* [ 6: 4], r/w, 0x2 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t ldo12uhs_cc : 3; /* [10: 8], r/w, 0x3 */ + uint32_t ldo12uhs_ocp_out : 1; /* [ 11], r, 0x0 */ + uint32_t ldo12uhs_ocp_th : 3; /* [14:12], r/w, 0x3 */ + uint32_t ldo12uhs_ocp_en : 1; /* [ 15], r/w, 0x1 */ + uint32_t ldo12uhs_sstart_delay : 3; /* [18:16], r/w, 0x2 */ + uint32_t ldo12uhs_sstart_en : 1; /* [ 19], r/w, 0x1 */ + uint32_t ldo12uhs_vout_sel : 4; /* [23:20], r/w, 0x3 */ + uint32_t ldo12uhs_vout_trim : 4; /* [27:24], r/w, 0x8 */ + uint32_t reserved_28_31 : 4; /* [31:28], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } ldo12uhs; + + /* 0x6d4 reserved */ + uint8_t RESERVED0x6d4[28]; + + /* 0x6F0 : proc_mon */ + union { + struct { + uint32_t pu_proc_mon : 1; /* [ 0], r/w, 0x0 */ + uint32_t osc_en_rvt : 1; /* [ 1], r/w, 0x0 */ + uint32_t osc_en_lvt : 1; /* [ 2], r/w, 0x0 */ + uint32_t osc_sel : 1; /* [ 3], r/w, 0x0 */ + uint32_t rstn_ringcount : 1; /* [ 4], r/w, 0x0 */ + uint32_t rstn_refcount : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6_7 : 2; /* [ 7: 6], rsvd, 0x0 */ + uint32_t refcount_div_onehot : 4; /* [11: 8], r/w, 0x4 */ + uint32_t ring_freq : 16; /* [27:12], r, 0x0 */ + uint32_t ring_freq_rdy : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29_31 : 3; /* [31:29], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } proc_mon; + + /* 0x6f4 reserved */ + uint8_t RESERVED0x6f4[12]; + + /* 0x700 : dll_cfg0 */ + union { + struct { + uint32_t reserved_0_31 : 32; /* [31: 0], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } dll_cfg0; + + /* 0x704 reserved */ + uint8_t RESERVED0x704[140]; + + /* 0x790 : mipi_pll_cfg0 */ + union { + struct { + uint32_t mipipll_sdm_rstb : 1; /* [ 0], r/w, 0x1 */ + uint32_t reserved_1 : 1; /* [ 1], rsvd, 0x0 */ + uint32_t mipipll_fbdv_rstb : 1; /* [ 2], r/w, 0x1 */ + uint32_t reserved_3_4 : 2; /* [ 4: 3], rsvd, 0x0 */ + uint32_t pu_mipipll_fbdv : 1; /* [ 5], r/w, 0x1 */ + uint32_t reserved_6_7 : 2; /* [ 7: 6], rsvd, 0x0 */ + uint32_t pu_mipipll_cp : 1; /* [ 8], r/w, 0x1 */ + uint32_t pu_mipipll_sfreg : 1; /* [ 9], r/w, 0x0 */ + uint32_t pu_mipipll : 1; /* [ 10], r/w, 0x0 */ + uint32_t reserved_11_31 : 21; /* [31:11], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mipi_pll_cfg0; + + /* 0x794 : mipi_pll_cfg1 */ + union { + struct { + uint32_t mipipll_even_div_ratio : 7; /* [ 6: 0], r/w, 0x32 */ + uint32_t mipipll_even_div_en : 1; /* [ 7], r/w, 0x0 */ + uint32_t mipipll_refdiv_ratio : 4; /* [11: 8], r/w, 0x2 */ + uint32_t reserved_12_15 : 4; /* [15:12], rsvd, 0x0 */ + uint32_t mipipll_refclk_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_19 : 2; /* [19:18], rsvd, 0x0 */ + uint32_t mipipll_vg11_sel : 2; /* [21:20], r/w, 0x1 */ + uint32_t reserved_22_23 : 2; /* [23:22], rsvd, 0x0 */ + uint32_t mipipll_vg13_sel : 2; /* [25:24], r/w, 0x1 */ + uint32_t reserved_26_31 : 6; /* [31:26], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mipi_pll_cfg1; + + /* 0x798 : mipi_pll_cfg2 */ + union { + struct { + uint32_t mipipll_sel_cp_bias : 1; /* [ 0], r/w, 0x1 */ + uint32_t reserved_1_3 : 3; /* [ 3: 1], rsvd, 0x0 */ + uint32_t mipipll_icp_5u : 2; /* [ 5: 4], r/w, 0x3 */ + uint32_t mipipll_icp_1u : 2; /* [ 7: 6], r/w, 0x0 */ + uint32_t mipipll_int_frac_sw : 1; /* [ 8], r/w, 0x0 */ + uint32_t mipipll_cp_startup_en : 1; /* [ 9], r/w, 0x1 */ + uint32_t mipipll_cp_opamp_en : 1; /* [ 10], r/w, 0x1 */ + uint32_t mipipll_cp_ota_en : 1; /* [ 11], r/w, 0x1 */ + uint32_t mipipll_pfd_en : 1; /* [ 12], r/w, 0x1 */ + uint32_t reserved_13_31 : 19; /* [31:13], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mipi_pll_cfg2; + + /* 0x79C : mipi_pll_cfg3 */ + union { + struct { + uint32_t mipipll_c4_en : 1; /* [ 0], r/w, 0x1 */ + uint32_t reserved_1_3 : 3; /* [ 3: 1], rsvd, 0x0 */ + uint32_t mipipll_r4 : 2; /* [ 5: 4], r/w, 0x1 */ + uint32_t reserved_6_7 : 2; /* [ 7: 6], rsvd, 0x0 */ + uint32_t mipipll_r4_short : 1; /* [ 8], r/w, 0x0 */ + uint32_t reserved_9_11 : 3; /* [11: 9], rsvd, 0x0 */ + uint32_t mipipll_c3 : 2; /* [13:12], r/w, 0x2 */ + uint32_t mipipll_cz : 2; /* [15:14], r/w, 0x2 */ + uint32_t mipipll_rz : 3; /* [18:16], r/w, 0x1 */ + uint32_t mipipll_lf_test_en : 1; /* [ 19], r/w, 0x0 */ + uint32_t mipipll_fast_lock_en : 1; /* [ 20], r/w, 0x1 */ + uint32_t reserved_21_31 : 11; /* [31:21], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mipi_pll_cfg3; + + /* 0x7A0 : mipi_pll_cfg4 */ + union { + struct { + uint32_t mipipll_sel_sample_clk : 2; /* [ 1: 0], r/w, 0x1 */ + uint32_t reserved_2_3 : 2; /* [ 3: 2], rsvd, 0x0 */ + uint32_t mipipll_sel_fb_clk : 2; /* [ 5: 4], r/w, 0x1 */ + uint32_t reserved_6_7 : 2; /* [ 7: 6], rsvd, 0x0 */ + uint32_t mipipll_lock_det_en : 1; /* [ 8], r/w, 0x1 */ + uint32_t mipipll_lock_clk_sel : 2; /* [10: 9], r/w, 0x1 */ + uint32_t reserved_11 : 1; /* [ 11], rsvd, 0x0 */ + uint32_t mipipll_lock_clk_inv_en : 1; /* [ 12], r/w, 0x0 */ + uint32_t reserved_13_14 : 2; /* [14:13], rsvd, 0x0 */ + uint32_t mipipll_lock_win_sel : 2; /* [16:15], r/w, 0x1 */ + uint32_t reserved_17_31 : 15; /* [31:17], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mipi_pll_cfg4; + + /* 0x7A4 : mipi_pll_cfg5 */ + union { + struct { + uint32_t mipipll_vco_speed : 3; /* [ 2: 0], r/w, 0x5 */ + uint32_t mipipll_vco_vdd_ctrl : 2; /* [ 4: 3], r/w, 0x2 */ + uint32_t mipipll_vco_vdd_ctrl_extra : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6 : 1; /* [ 6], rsvd, 0x0 */ + uint32_t mipipll_vco_postdiv_sel : 3; /* [ 9: 7], r/w, 0x0 */ + uint32_t mipipll_vco_postdiv_clk_en : 1; /* [ 10], r/w, 0x1 */ + uint32_t reserved_11_31 : 21; /* [31:11], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mipi_pll_cfg5; + + /* 0x7A8 : mipi_pll_cfg6 */ + union { + struct { + uint32_t mipipll_sdmin : 19; /* [18: 0], r/w, 0x25800 */ + uint32_t reserved_19_23 : 5; /* [23:19], rsvd, 0x0 */ + uint32_t mipipll_sdm_bypass : 1; /* [ 24], r/w, 0x0 */ + uint32_t reserved_25_31 : 7; /* [31:25], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mipi_pll_cfg6; + + /* 0x7AC : mipi_pll_cfg7 */ + union { + struct { + uint32_t mipipll_sdm_order_sel : 1; /* [ 0], r/w, 0x1 */ + uint32_t mipipll_sdm_dith_sel : 2; /* [ 2: 1], r/w, 0x0 */ + uint32_t reserved_3_31 : 29; /* [31: 3], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mipi_pll_cfg7; + + /* 0x7B0 : mipi_pll_cfg8 */ + union { + struct { + uint32_t mipipll_dc_tp_out_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t mipipll_ten : 1; /* [ 1], r/w, 0x0 */ + uint32_t mipipll_ten_sfreg : 1; /* [ 2], r/w, 0x0 */ + uint32_t reserved_3 : 1; /* [ 3], rsvd, 0x0 */ + uint32_t mipipll_dten_ckin : 1; /* [ 4], r/w, 0x0 */ + uint32_t mipipll_dten_fref : 1; /* [ 5], r/w, 0x0 */ + uint32_t mipipll_dten_fsdm : 1; /* [ 6], r/w, 0x0 */ + uint32_t mipipll_dten_pupll : 1; /* [ 7], r/w, 0x0 */ + uint32_t mipipll_dten_pll_locked : 1; /* [ 8], r/w, 0x0 */ + uint32_t reserved_9 : 1; /* [ 9], rsvd, 0x0 */ + uint32_t mipipll_dtest_pull_down : 1; /* [ 10], r/w, 0x1 */ + uint32_t reserved_11_31 : 21; /* [31:11], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mipi_pll_cfg8; + + /* 0x7B4 : mipi_pll_cfg9 */ + union { + struct { + uint32_t mipipll_ssc_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t reserved_1_3 : 3; /* [ 3: 1], rsvd, 0x0 */ + uint32_t mipipll_ssc_cnt : 8; /* [11: 4], r/w, 0x64 */ + uint32_t mipipll_ssc_gain : 3; /* [14:12], r/w, 0x5 */ + uint32_t reserved_15 : 1; /* [ 15], rsvd, 0x0 */ + uint32_t mipipll_ssc_start_gate_en : 1; /* [ 16], r/w, 0x1 */ + uint32_t reserved_17_31 : 15; /* [31:17], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mipi_pll_cfg9; + + /* 0x7b8 reserved */ + uint8_t RESERVED0x7b8[24]; + + /* 0x7D0 : uhs_pll_cfg0 */ + union { + struct { + uint32_t uhspll_sdm_rstb : 1; /* [ 0], r/w, 0x1 */ + uint32_t reserved_1 : 1; /* [ 1], rsvd, 0x0 */ + uint32_t uhspll_fbdv_rstb : 1; /* [ 2], r/w, 0x1 */ + uint32_t reserved_3_4 : 2; /* [ 4: 3], rsvd, 0x0 */ + uint32_t pu_uhspll_fbdv : 1; /* [ 5], r/w, 0x1 */ + uint32_t reserved_6_7 : 2; /* [ 7: 6], rsvd, 0x0 */ + uint32_t pu_uhspll_cp : 1; /* [ 8], r/w, 0x1 */ + uint32_t pu_uhspll_sfreg : 1; /* [ 9], r/w, 0x0 */ + uint32_t pu_uhspll : 1; /* [ 10], r/w, 0x0 */ + uint32_t reserved_11_31 : 21; /* [31:11], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } uhs_pll_cfg0; + + /* 0x7D4 : uhs_pll_cfg1 */ + union { + struct { + uint32_t uhspll_even_div_ratio : 7; /* [ 6: 0], r/w, 0x54 */ + uint32_t uhspll_even_div_en : 1; /* [ 7], r/w, 0x0 */ + uint32_t uhspll_refdiv_ratio : 4; /* [11: 8], r/w, 0x2 */ + uint32_t reserved_12_15 : 4; /* [15:12], rsvd, 0x0 */ + uint32_t uhspll_refclk_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_19 : 2; /* [19:18], rsvd, 0x0 */ + uint32_t uhspll_vg11_sel : 2; /* [21:20], r/w, 0x1 */ + uint32_t reserved_22_23 : 2; /* [23:22], rsvd, 0x0 */ + uint32_t uhspll_vg13_sel : 2; /* [25:24], r/w, 0x1 */ + uint32_t reserved_26_31 : 6; /* [31:26], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } uhs_pll_cfg1; + + /* 0x7D8 : uhs_pll_cfg2 */ + union { + struct { + uint32_t uhspll_sel_cp_bias : 1; /* [ 0], r/w, 0x1 */ + uint32_t reserved_1_3 : 3; /* [ 3: 1], rsvd, 0x0 */ + uint32_t uhspll_icp_5u : 2; /* [ 5: 4], r/w, 0x3 */ + uint32_t uhspll_icp_1u : 2; /* [ 7: 6], r/w, 0x0 */ + uint32_t uhspll_int_frac_sw : 1; /* [ 8], r/w, 0x0 */ + uint32_t uhspll_cp_startup_en : 1; /* [ 9], r/w, 0x1 */ + uint32_t uhspll_cp_opamp_en : 1; /* [ 10], r/w, 0x1 */ + uint32_t uhspll_cp_ota_en : 1; /* [ 11], r/w, 0x1 */ + uint32_t uhspll_pfd_en : 1; /* [ 12], r/w, 0x1 */ + uint32_t reserved_13_31 : 19; /* [31:13], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } uhs_pll_cfg2; + + /* 0x7DC : uhs_pll_cfg3 */ + union { + struct { + uint32_t uhspll_c4_en : 1; /* [ 0], r/w, 0x1 */ + uint32_t reserved_1_3 : 3; /* [ 3: 1], rsvd, 0x0 */ + uint32_t uhspll_r4 : 2; /* [ 5: 4], r/w, 0x1 */ + uint32_t reserved_6_7 : 2; /* [ 7: 6], rsvd, 0x0 */ + uint32_t uhspll_r4_short : 1; /* [ 8], r/w, 0x0 */ + uint32_t reserved_9_11 : 3; /* [11: 9], rsvd, 0x0 */ + uint32_t uhspll_c3 : 2; /* [13:12], r/w, 0x2 */ + uint32_t uhspll_cz : 2; /* [15:14], r/w, 0x2 */ + uint32_t uhspll_rz : 3; /* [18:16], r/w, 0x1 */ + uint32_t uhspll_lf_test_en : 1; /* [ 19], r/w, 0x0 */ + uint32_t uhspll_fast_lock_en : 1; /* [ 20], r/w, 0x1 */ + uint32_t reserved_21_31 : 11; /* [31:21], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } uhs_pll_cfg3; + + /* 0x7E0 : uhs_pll_cfg4 */ + union { + struct { + uint32_t uhspll_sel_sample_clk : 2; /* [ 1: 0], r/w, 0x1 */ + uint32_t reserved_2_3 : 2; /* [ 3: 2], rsvd, 0x0 */ + uint32_t uhspll_sel_fb_clk : 2; /* [ 5: 4], r/w, 0x1 */ + uint32_t reserved_6_7 : 2; /* [ 7: 6], rsvd, 0x0 */ + uint32_t uhspll_lock_det_en : 1; /* [ 8], r/w, 0x1 */ + uint32_t uhspll_lock_clk_sel : 2; /* [10: 9], r/w, 0x1 */ + uint32_t reserved_11 : 1; /* [ 11], rsvd, 0x0 */ + uint32_t uhspll_lock_clk_inv_en : 1; /* [ 12], r/w, 0x0 */ + uint32_t reserved_13_14 : 2; /* [14:13], rsvd, 0x0 */ + uint32_t uhspll_lock_win_sel : 2; /* [16:15], r/w, 0x1 */ + uint32_t reserved_17_31 : 15; /* [31:17], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } uhs_pll_cfg4; + + /* 0x7E4 : uhs_pll_cfg5 */ + union { + struct { + uint32_t uhspll_vco_speed : 3; /* [ 2: 0], r/w, 0x7 */ + uint32_t uhspll_vco_vdd_ctrl : 2; /* [ 4: 3], r/w, 0x3 */ + uint32_t uhspll_vco_vdd_ctrl_extra : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6 : 1; /* [ 6], rsvd, 0x0 */ + uint32_t uhspll_vco_postdiv_sel : 3; /* [ 9: 7], r/w, 0x0 */ + uint32_t uhspll_vco_postdiv_clk_en : 1; /* [ 10], r/w, 0x1 */ + uint32_t reserved_11_31 : 21; /* [31:11], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } uhs_pll_cfg5; + + /* 0x7E8 : uhs_pll_cfg6 */ + union { + struct { + uint32_t uhspll_sdmin : 19; /* [18: 0], r/w, 0x34800 */ + uint32_t reserved_19_23 : 5; /* [23:19], rsvd, 0x0 */ + uint32_t uhspll_sdm_bypass : 1; /* [ 24], r/w, 0x0 */ + uint32_t reserved_25_31 : 7; /* [31:25], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } uhs_pll_cfg6; + + /* 0x7EC : uhs_pll_cfg7 */ + union { + struct { + uint32_t uhspll_sdm_order_sel : 1; /* [ 0], r/w, 0x1 */ + uint32_t uhspll_sdm_dith_sel : 2; /* [ 2: 1], r/w, 0x0 */ + uint32_t reserved_3_31 : 29; /* [31: 3], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } uhs_pll_cfg7; + + /* 0x7F0 : uhs_pll_cfg8 */ + union { + struct { + uint32_t uhspll_dc_tp_out_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t uhspll_ten : 1; /* [ 1], r/w, 0x0 */ + uint32_t uhspll_ten_sfreg : 1; /* [ 2], r/w, 0x0 */ + uint32_t reserved_3 : 1; /* [ 3], rsvd, 0x0 */ + uint32_t uhspll_dten_ckin : 1; /* [ 4], r/w, 0x0 */ + uint32_t uhspll_dten_fref : 1; /* [ 5], r/w, 0x0 */ + uint32_t uhspll_dten_fsdm : 1; /* [ 6], r/w, 0x0 */ + uint32_t uhspll_dten_pupll : 1; /* [ 7], r/w, 0x0 */ + uint32_t uhspll_dten_pll_locked : 1; /* [ 8], r/w, 0x0 */ + uint32_t reserved_9 : 1; /* [ 9], rsvd, 0x0 */ + uint32_t uhspll_dtest_pull_down : 1; /* [ 10], r/w, 0x1 */ + uint32_t reserved_11_31 : 21; /* [31:11], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } uhs_pll_cfg8; + + /* 0x7F4 : uhs_pll_cfg9 */ + union { + struct { + uint32_t uhspll_ssc_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t reserved_1_3 : 3; /* [ 3: 1], rsvd, 0x0 */ + uint32_t uhspll_ssc_cnt : 8; /* [11: 4], r/w, 0x64 */ + uint32_t uhspll_ssc_gain : 3; /* [14:12], r/w, 0x5 */ + uint32_t reserved_15 : 1; /* [ 15], rsvd, 0x0 */ + uint32_t uhspll_ssc_start_gate_en : 1; /* [ 16], r/w, 0x1 */ + uint32_t reserved_17_31 : 15; /* [31:17], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } uhs_pll_cfg9; + + /* 0x7f8 reserved */ + uint8_t RESERVED0x7f8[24]; + + /* 0x810 : wifi_pll_cfg0 */ + union { + struct { + uint32_t wifipll_sdm_rstb : 1; /* [ 0], r/w, 0x1 */ + uint32_t wifipll_postdiv_rstb : 1; /* [ 1], r/w, 0x1 */ + uint32_t wifipll_fbdv_rstb : 1; /* [ 2], r/w, 0x1 */ + uint32_t wifipll_refdiv_rstb : 1; /* [ 3], r/w, 0x1 */ + uint32_t pu_wifipll_postdiv : 1; /* [ 4], r/w, 0x0 */ + uint32_t pu_wifipll_fbdv : 1; /* [ 5], r/w, 0x1 */ + uint32_t pu_wifipll_clamp_op : 1; /* [ 6], r/w, 0x1 */ + uint32_t pu_wifipll_pfd : 1; /* [ 7], r/w, 0x1 */ + uint32_t pu_wifipll_cp : 1; /* [ 8], r/w, 0x1 */ + uint32_t pu_wifipll_sfreg : 1; /* [ 9], r/w, 0x0 */ + uint32_t pu_wifipll : 1; /* [ 10], r/w, 0x0 */ + uint32_t pu_wifipll_clktree : 1; /* [ 11], r/w, 0x1 */ + uint32_t reserved_12_31 : 20; /* [31:12], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } wifi_pll_cfg0; + + /* 0x814 : wifi_pll_cfg1 */ + union { + struct { + uint32_t wifipll_postdiv : 7; /* [ 6: 0], r/w, 0x16 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t wifipll_refdiv_ratio : 4; /* [11: 8], r/w, 0x2 */ + uint32_t reserved_12_15 : 4; /* [15:12], rsvd, 0x0 */ + uint32_t wifipll_refclk_sel : 2; /* [17:16], r/w, 0x1 */ + uint32_t reserved_18_19 : 2; /* [19:18], rsvd, 0x0 */ + uint32_t wifipll_vg11_sel : 2; /* [21:20], r/w, 0x1 */ + uint32_t reserved_22_23 : 2; /* [23:22], rsvd, 0x0 */ + uint32_t wifipll_vg13_sel : 2; /* [25:24], r/w, 0x1 */ + uint32_t reserved_26_31 : 6; /* [31:26], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } wifi_pll_cfg1; + + /* 0x818 : wifi_pll_cfg2 */ + union { + struct { + uint32_t wifipll_sel_cp_bias : 1; /* [ 0], r/w, 0x1 */ + uint32_t reserved_1_3 : 3; /* [ 3: 1], rsvd, 0x0 */ + uint32_t wifipll_icp_5u : 2; /* [ 5: 4], r/w, 0x2 */ + uint32_t wifipll_icp_1u : 2; /* [ 7: 6], r/w, 0x0 */ + uint32_t wifipll_int_frac_sw : 1; /* [ 8], r/w, 0x0 */ + uint32_t wifipll_cp_startup_en : 1; /* [ 9], r/w, 0x1 */ + uint32_t wifipll_cp_opamp_en : 1; /* [ 10], r/w, 0x1 */ + uint32_t reserved_11_31 : 21; /* [31:11], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } wifi_pll_cfg2; + + /* 0x81C : wifi_pll_cfg3 */ + union { + struct { + uint32_t wifipll_c4_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t reserved_1_3 : 3; /* [ 3: 1], rsvd, 0x0 */ + uint32_t wifipll_r4 : 2; /* [ 5: 4], r/w, 0x2 */ + uint32_t reserved_6_7 : 2; /* [ 7: 6], rsvd, 0x0 */ + uint32_t wifipll_r4_short : 1; /* [ 8], r/w, 0x1 */ + uint32_t reserved_9_11 : 3; /* [11: 9], rsvd, 0x0 */ + uint32_t wifipll_c3 : 2; /* [13:12], r/w, 0x2 */ + uint32_t wifipll_cz : 2; /* [15:14], r/w, 0x1 */ + uint32_t wifipll_rz : 3; /* [18:16], r/w, 0x3 */ + uint32_t reserved_19_31 : 13; /* [31:19], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } wifi_pll_cfg3; + + /* 0x820 : wifi_pll_cfg4 */ + union { + struct { + uint32_t wifipll_sel_sample_clk : 2; /* [ 1: 0], r/w, 0x1 */ + uint32_t reserved_2_3 : 2; /* [ 3: 2], rsvd, 0x0 */ + uint32_t wifipll_sel_fb_clk : 2; /* [ 5: 4], r/w, 0x1 */ + uint32_t reserved_6_7 : 2; /* [ 7: 6], rsvd, 0x0 */ + uint32_t wifipll_sdmclk_sel : 1; /* [ 8], r/w, 0x1 */ + uint32_t reserved_9_31 : 23; /* [31: 9], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } wifi_pll_cfg4; + + /* 0x824 : wifi_pll_cfg5 */ + union { + struct { + uint32_t wifipll_vco_speed : 3; /* [ 2: 0], r/w, 0x5 */ + uint32_t reserved_3 : 1; /* [ 3], rsvd, 0x0 */ + uint32_t wifipll_vco_div1_en : 1; /* [ 4], r/w, 0x0 */ + uint32_t reserved_5_7 : 3; /* [ 7: 5], rsvd, 0x0 */ + uint32_t wifipll_vco_div2_en : 1; /* [ 8], r/w, 0x1 */ + uint32_t reserved_9_11 : 3; /* [11: 9], rsvd, 0x0 */ + uint32_t wifipll_vco_div3_en : 1; /* [ 12], r/w, 0x1 */ + uint32_t reserved_13_31 : 19; /* [31:13], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } wifi_pll_cfg5; + + /* 0x828 : wifi_pll_cfg6 */ + union { + struct { + uint32_t wifipll_sdmin : 26; /* [25: 0], r/w, 0x1800000 */ + uint32_t reserved_26_27 : 2; /* [27:26], rsvd, 0x0 */ + uint32_t wifipll_sdm_bypass : 1; /* [ 28], r/w, 0x0 */ + uint32_t wifipll_sdm_bypass_hw : 1; /* [ 29], r, 0x0 */ + uint32_t reserved_30 : 1; /* [ 30], rsvd, 0x0 */ + uint32_t wifipll_sdm_ctrl_hw : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } wifi_pll_cfg6; + + /* 0x82C : wifi_pll_cfg7 */ + union { + struct { + uint32_t wifipll_sdm_order_sel : 2; /* [ 1: 0], r/w, 0x2 */ + uint32_t reserved_2_3 : 2; /* [ 3: 2], rsvd, 0x0 */ + uint32_t wifipll_sdm_noi_prbs_sel : 2; /* [ 5: 4], r/w, 0x3 */ + uint32_t reserved_6_7 : 2; /* [ 7: 6], rsvd, 0x0 */ + uint32_t wifipll_sdm_noi_prbs_en : 1; /* [ 8], r/w, 0x0 */ + uint32_t reserved_9_11 : 3; /* [11: 9], rsvd, 0x0 */ + uint32_t wifipll_sdm_sig_prbs_sel : 2; /* [13:12], r/w, 0x0 */ + uint32_t reserved_14_15 : 2; /* [15:14], rsvd, 0x0 */ + uint32_t wifipll_sdm_sig_dith_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_31 : 14; /* [31:18], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } wifi_pll_cfg7; + + /* 0x830 : wifi_pll_cfg8 */ + union { + struct { + uint32_t wifipll_en_div2 : 1; /* [ 0], r/w, 0x1 */ + uint32_t wifipll_en_div4 : 1; /* [ 1], r/w, 0x1 */ + uint32_t wifipll_en_div5 : 1; /* [ 2], r/w, 0x1 */ + uint32_t wifipll_en_div6 : 1; /* [ 3], r/w, 0x1 */ + uint32_t wifipll_en_div8 : 1; /* [ 4], r/w, 0x1 */ + uint32_t wifipll_en_div10 : 1; /* [ 5], r/w, 0x1 */ + uint32_t wifipll_en_div12 : 1; /* [ 6], r/w, 0x1 */ + uint32_t wifipll_en_div20 : 1; /* [ 7], r/w, 0x1 */ + uint32_t wifipll_en_div30 : 1; /* [ 8], r/w, 0x1 */ + uint32_t wifipll_sel_div2_div4 : 1; /* [ 9], r/w, 0x0 */ + uint32_t en_wifipll_div30_bz_adc : 1; /* [ 10], r/w, 0x0 */ + uint32_t reserved_11 : 1; /* [ 11], rsvd, 0x0 */ + uint32_t wifipll_en_div2_hw : 1; /* [ 12], r, 0x1 */ + uint32_t reserved_13_30 : 18; /* [30:13], rsvd, 0x0 */ + uint32_t wifipll_en_ctrl_hw : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } wifi_pll_cfg8; + + /* 0x834 : wifi_pll_cfg9 */ + union { + struct { + uint32_t wifipll_dc_tp_out_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t ten_wifipll : 1; /* [ 1], r/w, 0x0 */ + uint32_t ten_wifipll_sfreg : 1; /* [ 2], r/w, 0x0 */ + uint32_t reserved_3 : 1; /* [ 3], rsvd, 0x0 */ + uint32_t dten_wifipll_fin : 1; /* [ 4], r/w, 0x0 */ + uint32_t dten_wifipll_fref : 1; /* [ 5], r/w, 0x0 */ + uint32_t dten_wifipll_fsdm : 1; /* [ 6], r/w, 0x0 */ + uint32_t dten_wifipll_div30 : 1; /* [ 7], r/w, 0x0 */ + uint32_t dten_wifipll_div10 : 1; /* [ 8], r/w, 0x0 */ + uint32_t dten_wifipll_postdiv_clk : 1; /* [ 9], r/w, 0x0 */ + uint32_t usbpll_dtest_pclk_en : 1; /* [ 10], r/w, 0x0 */ + uint32_t usbpll_dtest_clkout_en : 1; /* [ 11], r/w, 0x0 */ + uint32_t dtest_wifipll_pulldown : 1; /* [ 12], r/w, 0x1 */ + uint32_t reserved_13_31 : 19; /* [31:13], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } wifi_pll_cfg9; + + /* 0x838 : wifi_pll_cfg10 */ + union { + struct { + uint32_t reserved_0_1 : 2; /* [ 1: 0], rsvd, 0x0 */ + uint32_t usbpll_ssc_start : 1; /* [ 2], r/w, 0x1 */ + uint32_t usbpll_ssc_start_gate_en : 1; /* [ 3], r/w, 0x0 */ + uint32_t usbpll_ssc_gain : 3; /* [ 6: 4], r/w, 0x3 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t usbpll_ssc_en : 1; /* [ 8], r/w, 0x0 */ + uint32_t usbpll_sdm_bypass : 1; /* [ 9], r/w, 0x0 */ + uint32_t usbpll_sdm_order_sel : 1; /* [ 10], r/w, 0x1 */ + uint32_t reserved_11_15 : 5; /* [15:11], rsvd, 0x0 */ + uint32_t usbpll_sdm_sig_dith_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_19 : 2; /* [19:18], rsvd, 0x0 */ + uint32_t usbpll_div2_en : 1; /* [ 20], r/w, 0x1 */ + uint32_t usbpll_clkout_en : 1; /* [ 21], r/w, 0x1 */ + uint32_t reserved_22_23 : 2; /* [23:22], rsvd, 0x0 */ + uint32_t usbpll_sel_sample_clk : 2; /* [25:24], r/w, 0x1 */ + uint32_t reserved_26_27 : 2; /* [27:26], rsvd, 0x0 */ + uint32_t usbpll_rstb : 1; /* [ 28], r/w, 0x1 */ + uint32_t pu_usbpll_mmdiv : 1; /* [ 29], r/w, 0x0 */ + uint32_t reserved_30_31 : 2; /* [31:30], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } wifi_pll_cfg10; + + /* 0x83C : wifi_pll_cfg11 */ + union { + struct { + uint32_t usbpll_sdmin : 19; /* [18: 0], r/w, 0x28000 */ + uint32_t reserved_19_31 : 13; /* [31:19], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } wifi_pll_cfg11; + + /* 0x840 : wifi_pll_cfg12 */ + union { + struct { + uint32_t usbpll_ssc_cnt : 9; /* [ 8: 0], r/w, 0xf0 */ + uint32_t reserved_9_31 : 23; /* [31: 9], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } wifi_pll_cfg12; + + /* 0x844 : wifi_pll_cfg13 */ + union { + struct { + uint32_t wifipll_resv : 16; /* [15: 0], r/w, 0x0 */ + uint32_t reserved_16_20 : 5; /* [20:16], rsvd, 0x0 */ + uint32_t usbpll_dl_ctrl : 1; /* [ 21], r/w, 0x0 */ + uint32_t wifipll_dl_ctrl_30_bz_adc : 1; /* [ 22], r/w, 0x0 */ + uint32_t wifipll_dl_ctrl_30 : 1; /* [ 23], r/w, 0x0 */ + uint32_t wifipll_dl_ctrl_20 : 1; /* [ 24], r/w, 0x0 */ + uint32_t wifipll_dl_ctrl_12 : 1; /* [ 25], r/w, 0x0 */ + uint32_t wifipll_dl_ctrl_10 : 1; /* [ 26], r/w, 0x0 */ + uint32_t wifipll_dl_ctrl_8 : 1; /* [ 27], r/w, 0x0 */ + uint32_t wifipll_dl_ctrl_6 : 1; /* [ 28], r/w, 0x0 */ + uint32_t wifipll_dl_ctrl_5 : 1; /* [ 29], r/w, 0x0 */ + uint32_t wifipll_dl_ctrl_4 : 1; /* [ 30], r/w, 0x0 */ + uint32_t wifipll_dl_ctrl_2 : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } wifi_pll_cfg13; + + /* 0x848 reserved */ + uint8_t RESERVED0x848[92]; + + /* 0x8A4 : gauge */ + union { + struct { + uint32_t gauge_reserve : 3; /* [ 2: 0], r/w, 0x0 */ + uint32_t gauge_ictrl_adc : 2; /* [ 4: 3], r/w, 0x1 */ + uint32_t gauge_dem_en : 1; /* [ 5], r/w, 0x1 */ + uint32_t gauge_ckb_en : 1; /* [ 6], r/w, 0x0 */ + uint32_t gauge_chop_phas : 1; /* [ 7], r/w, 0x1 */ + uint32_t gauge_chop_freq : 3; /* [10: 8], r/w, 0x1 */ + uint32_t gauge_chop_en : 1; /* [ 11], r/w, 0x1 */ + uint32_t gauge_sel_edge : 1; /* [ 12], r/w, 0x0 */ + uint32_t gauge_quan_gain : 2; /* [14:13], r/w, 0x1 */ + uint32_t gauge_sdm_pu : 1; /* [ 15], r/w, 0x0 */ + uint32_t gauge_channel_sel : 1; /* [ 16], r/w, 0x0 */ + uint32_t gauge_channel_en : 1; /* [ 17], r/w, 0x0 */ + uint32_t gauge_lp_mode : 1; /* [ 18], r/w, 0x0 */ + uint32_t reserved_19 : 1; /* [ 19], rsvd, 0x0 */ + uint32_t tmux_gauge_power : 3; /* [22:20], r/w, 0x0 */ + uint32_t ten_gauge_power : 1; /* [ 23], r/w, 0x0 */ + uint32_t ntc_bias_sel : 4; /* [27:24], r/w, 0x8 */ + uint32_t ntc_bias_en : 1; /* [ 28], r/w, 0x0 */ + uint32_t gauge_ldo_pu : 1; /* [ 29], r/w, 0x0 */ + uint32_t gauge_vcm_pu : 1; /* [ 30], r/w, 0x0 */ + uint32_t gauge_bg_pu : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gauge; + + /* 0x8a8 reserved */ + uint8_t RESERVED0x8a8[16]; + + /* 0x8B8 : gauge_rx_fifo_ctrl */ + union { + struct { + uint32_t gauge_rx_fifo_flush : 1; /* [ 0], w1p, 0x0 */ + uint32_t gauge_rxo_int_en : 1; /* [ 1], r/w, 0x0 */ + uint32_t gauge_rxu_int_en : 1; /* [ 2], r/w, 0x0 */ + uint32_t gauge_rxa_int_en : 1; /* [ 3], r/w, 0x0 */ + uint32_t gauge_rx_drq_en : 1; /* [ 4], r/w, 0x0 */ + uint32_t gauge_rx_data_res : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6_7 : 2; /* [ 7: 6], rsvd, 0x0 */ + uint32_t gauge_rx_ch_en : 1; /* [ 8], r/w, 0x0 */ + uint32_t reserved_9_13 : 5; /* [13: 9], rsvd, 0x0 */ + uint32_t gauge_rx_drq_cnt : 2; /* [15:14], r/w, 0x0 */ + uint32_t gauge_rx_trg_level : 3; /* [18:16], r/w, 0x1 */ + uint32_t reserved_19_23 : 5; /* [23:19], rsvd, 0x0 */ + uint32_t gauge_rx_data_mode : 2; /* [25:24], r/w, 0x3 */ + uint32_t reserved_26_31 : 6; /* [31:26], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gauge_rx_fifo_ctrl; + + /* 0x8BC : gauge_rx_fifo_status */ + union { + struct { + uint32_t reserved_0 : 1; /* [ 0], rsvd, 0x0 */ + uint32_t gauge_rxo_int : 1; /* [ 1], r, 0x0 */ + uint32_t gauge_rxu_int : 1; /* [ 2], r, 0x0 */ + uint32_t reserved_3 : 1; /* [ 3], rsvd, 0x0 */ + uint32_t gauge_rxa_int : 1; /* [ 4], r, 0x0 */ + uint32_t reserved_5_15 : 11; /* [15: 5], rsvd, 0x0 */ + uint32_t gauge_rxa_cnt : 3; /* [18:16], r, 0x0 */ + uint32_t reserved_19_23 : 5; /* [23:19], rsvd, 0x0 */ + uint32_t gauge_rxa : 1; /* [ 24], r, 0x0 */ + uint32_t reserved_25_31 : 7; /* [31:25], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gauge_rx_fifo_status; + + /* 0x8C0 : gauge_rx_fifo_data */ + union { + struct { + uint32_t gauge_rx_data : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } gauge_rx_fifo_data; + + /* 0x8C4 : gpio_cfg0 */ + union { + struct { + uint32_t reg_gpio_0_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_0_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_0_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_0_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_0_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_0_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_0_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_0_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_0_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_0_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_0_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_0_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_0_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_0_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_0_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_0_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg0; + + /* 0x8C8 : gpio_cfg1 */ + union { + struct { + uint32_t reg_gpio_1_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_1_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_1_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_1_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_1_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_1_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_1_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_1_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_1_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_1_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_1_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_1_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_1_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_1_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_1_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_1_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg1; + + /* 0x8CC : gpio_cfg2 */ + union { + struct { + uint32_t reg_gpio_2_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_2_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_2_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_2_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_2_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_2_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_2_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_2_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_2_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_2_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_2_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_2_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_2_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_2_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_2_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_2_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg2; + + /* 0x8D0 : gpio_cfg3 */ + union { + struct { + uint32_t reg_gpio_3_ie : 1; /* [ 0], r/w, 0x1 */ + uint32_t reg_gpio_3_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_3_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_3_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_3_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_3_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_3_func_sel : 5; /* [12: 8], r/w, 0xf */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_3_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_3_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_3_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_3_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_3_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_3_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_3_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_3_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_3_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg3; + + /* 0x8D4 : gpio_cfg4 */ + union { + struct { + uint32_t reg_gpio_4_ie : 1; /* [ 0], r/w, 0x1 */ + uint32_t reg_gpio_4_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_4_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_4_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_4_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_4_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_4_func_sel : 5; /* [12: 8], r/w, 0xf */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_4_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_4_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_4_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_4_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_4_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_4_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_4_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_4_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_4_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg4; + + /* 0x8D8 : gpio_cfg5 */ + union { + struct { + uint32_t reg_gpio_5_ie : 1; /* [ 0], r/w, 0x1 */ + uint32_t reg_gpio_5_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_5_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_5_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_5_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_5_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_5_func_sel : 5; /* [12: 8], r/w, 0xf */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_5_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_5_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_5_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_5_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_5_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_5_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_5_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_5_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_5_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg5; + + /* 0x8DC : gpio_cfg6 */ + union { + struct { + uint32_t reg_gpio_6_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_6_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_6_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_6_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_6_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_6_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_6_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_6_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_6_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_6_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_6_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_6_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_6_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_6_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_6_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_6_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg6; + + /* 0x8E0 : gpio_cfg7 */ + union { + struct { + uint32_t reg_gpio_7_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_7_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_7_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_7_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_7_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_7_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_7_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_7_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_7_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_7_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_7_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_7_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_7_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_7_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_7_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_7_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg7; + + /* 0x8E4 : gpio_cfg8 */ + union { + struct { + uint32_t reg_gpio_8_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_8_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_8_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_8_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_8_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_8_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_8_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_8_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_8_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_8_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_8_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_8_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_8_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_8_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_8_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_8_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg8; + + /* 0x8E8 : gpio_cfg9 */ + union { + struct { + uint32_t reg_gpio_9_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_9_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_9_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_9_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_9_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_9_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_9_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_9_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_9_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_9_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_9_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_9_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_9_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_9_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_9_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_9_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg9; + + /* 0x8EC : gpio_cfg10 */ + union { + struct { + uint32_t reg_gpio_10_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_10_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_10_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_10_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_10_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_10_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_10_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_10_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_10_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_10_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_10_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_10_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_10_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_10_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_10_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_10_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg10; + + /* 0x8F0 : gpio_cfg11 */ + union { + struct { + uint32_t reg_gpio_11_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_11_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_11_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_11_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_11_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_11_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_11_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_11_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_11_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_11_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_11_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_11_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_11_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_11_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_11_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_11_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg11; + + /* 0x8F4 : gpio_cfg12 */ + union { + struct { + uint32_t reg_gpio_12_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_12_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_12_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_12_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_12_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_12_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_12_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_12_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_12_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_12_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_12_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_12_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_12_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_12_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_12_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_12_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg12; + + /* 0x8F8 : gpio_cfg13 */ + union { + struct { + uint32_t reg_gpio_13_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_13_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_13_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_13_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_13_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_13_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_13_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_13_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_13_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_13_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_13_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_13_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_13_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_13_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_13_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_13_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg13; + + /* 0x8FC : gpio_cfg14 */ + union { + struct { + uint32_t reg_gpio_14_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_14_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_14_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_14_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_14_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_14_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_14_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_14_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_14_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_14_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_14_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_14_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_14_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_14_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_14_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_14_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg14; + + /* 0x900 : gpio_cfg15 */ + union { + struct { + uint32_t reg_gpio_15_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_15_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_15_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_15_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_15_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_15_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_15_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_15_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_15_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_15_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_15_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_15_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_15_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_15_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_15_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_15_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg15; + + /* 0x904 : gpio_cfg16 */ + union { + struct { + uint32_t reg_gpio_16_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_16_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_16_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_16_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_16_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_16_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_16_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_16_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_16_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_16_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_16_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_16_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_16_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_16_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_16_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_16_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg16; + + /* 0x908 : gpio_cfg17 */ + union { + struct { + uint32_t reg_gpio_17_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_17_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_17_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_17_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_17_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_17_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_17_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_17_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_17_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_17_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_17_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_17_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_17_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_17_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_17_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_17_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg17; + + /* 0x90C : gpio_cfg18 */ + union { + struct { + uint32_t reg_gpio_18_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_18_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_18_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_18_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_18_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_18_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_18_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_18_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_18_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_18_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_18_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_18_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_18_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_18_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_18_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_18_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg18; + + /* 0x910 : gpio_cfg19 */ + union { + struct { + uint32_t reg_gpio_19_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_19_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_19_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_19_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_19_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_19_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_19_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_19_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_19_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_19_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_19_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_19_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_19_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_19_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_19_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_19_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg19; + + /* 0x914 : gpio_cfg20 */ + union { + struct { + uint32_t reg_gpio_20_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_20_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_20_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_20_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_20_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_20_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_20_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_20_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_20_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_20_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_20_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_20_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_20_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_20_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_20_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_20_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg20; + + /* 0x918 : gpio_cfg21 */ + union { + struct { + uint32_t reg_gpio_21_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_21_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_21_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_21_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_21_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_21_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_21_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_21_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_21_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_21_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_21_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_21_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_21_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_21_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_21_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_21_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg21; + + /* 0x91C : gpio_cfg22 */ + union { + struct { + uint32_t reg_gpio_22_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_22_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_22_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_22_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_22_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_22_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_22_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_22_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_22_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_22_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_22_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_22_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_22_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_22_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_22_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_22_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg22; + + /* 0x920 : gpio_cfg23 */ + union { + struct { + uint32_t reg_gpio_23_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_23_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_23_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_23_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_23_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_23_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_23_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_23_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_23_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_23_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_23_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_23_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_23_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_23_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_23_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_23_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg23; + + /* 0x924 : gpio_cfg24 */ + union { + struct { + uint32_t reg_gpio_24_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_24_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_24_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_24_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_24_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_24_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_24_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_24_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_24_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_24_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_24_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_24_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_24_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_24_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_24_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_24_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg24; + + /* 0x928 : gpio_cfg25 */ + union { + struct { + uint32_t reg_gpio_25_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_25_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_25_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_25_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_25_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_25_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_25_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_25_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_25_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_25_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_25_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_25_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_25_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_25_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_25_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_25_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg25; + + /* 0x92C : gpio_cfg26 */ + union { + struct { + uint32_t reg_gpio_26_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_26_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_26_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_26_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_26_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_26_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_26_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_26_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_26_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_26_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_26_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_26_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_26_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_26_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_26_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_26_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg26; + + /* 0x930 : gpio_cfg27 */ + union { + struct { + uint32_t reg_gpio_27_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_27_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_27_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_27_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_27_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_27_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_27_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_27_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_27_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_27_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_27_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_27_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_27_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_27_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_27_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_27_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg27; + + /* 0x934 : gpio_cfg28 */ + union { + struct { + uint32_t reg_gpio_28_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_28_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_28_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_28_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_28_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_28_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_28_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_28_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_28_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_28_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_28_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_28_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_28_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_28_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_28_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_28_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg28; + + /* 0x938 : gpio_cfg29 */ + union { + struct { + uint32_t reg_gpio_29_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_29_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_29_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_29_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_29_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_29_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_29_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_29_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_29_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_29_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_29_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_29_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_29_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_29_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_29_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_29_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg29; + + /* 0x93C : gpio_cfg30 */ + union { + struct { + uint32_t reg_gpio_30_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_30_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_30_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_30_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_30_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_30_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_30_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_30_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_30_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_30_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_30_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_30_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_30_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_30_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_30_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_30_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg30; + + /* 0x940 : gpio_cfg31 */ + union { + struct { + uint32_t reg_gpio_31_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_31_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_31_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_31_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_31_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_31_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_31_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_31_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_31_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_31_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_31_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_31_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_31_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_31_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_31_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_31_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg31; + + /* 0x944 : gpio_cfg32 */ + union { + struct { + uint32_t reg_gpio_32_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_32_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_32_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_32_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_32_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_32_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_32_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_32_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_32_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_32_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_32_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_32_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_32_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_32_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_32_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_32_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg32; + + /* 0x948 : gpio_cfg33 */ + union { + struct { + uint32_t reg_gpio_33_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_33_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_33_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_33_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_33_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_33_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_33_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_33_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_33_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_33_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_33_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_33_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_33_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_33_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_33_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_33_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg33; + + /* 0x94C : gpio_cfg34 */ + union { + struct { + uint32_t reg_gpio_34_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_34_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_34_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_34_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_34_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_34_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_34_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_34_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_34_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_34_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_34_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_34_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_34_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_34_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_34_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_34_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg34; + + /* 0x950 : gpio_cfg35 */ + union { + struct { + uint32_t reg_gpio_35_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_35_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_35_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_35_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_35_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_35_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_35_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_35_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_35_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_35_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_35_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_35_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_35_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_35_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_35_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_35_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg35; + + /* 0x954 : gpio_cfg36 */ + union { + struct { + uint32_t reg_gpio_36_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_36_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_36_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_36_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_36_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_36_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_36_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_36_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_36_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_36_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_36_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_36_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_36_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_36_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_36_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_36_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg36; + + /* 0x958 : gpio_cfg37 */ + union { + struct { + uint32_t reg_gpio_37_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_37_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_37_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_37_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_37_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_37_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_37_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_37_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_37_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_37_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_37_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_37_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_37_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_37_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_37_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_37_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg37; + + /* 0x95C : gpio_cfg38 */ + union { + struct { + uint32_t reg_gpio_38_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_38_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_38_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_38_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_38_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_38_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_38_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_38_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_38_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_38_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_38_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_38_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_38_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_38_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_38_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_38_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg38; + + /* 0x960 : gpio_cfg39 */ + union { + struct { + uint32_t reg_gpio_39_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_39_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_39_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_39_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_39_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_39_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_39_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_39_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_39_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_39_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_39_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_39_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_39_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_39_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_39_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_39_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg39; + + /* 0x964 : gpio_cfg40 */ + union { + struct { + uint32_t reg_gpio_40_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_40_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_40_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_40_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_40_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_40_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_40_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_40_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_40_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_40_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_40_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_40_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_40_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_40_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_40_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_40_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg40; + + /* 0x968 : gpio_cfg41 */ + union { + struct { + uint32_t reg_gpio_41_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_41_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_41_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_41_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_41_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_41_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_41_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_41_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_41_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_41_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_41_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_41_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_41_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_41_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_41_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_41_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg41; + + /* 0x96C : gpio_cfg42 */ + union { + struct { + uint32_t reg_gpio_42_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_42_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_42_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_42_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_42_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_42_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_42_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_42_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_42_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_42_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_42_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_42_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_42_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_42_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_42_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_42_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg42; + + /* 0x970 : gpio_cfg43 */ + union { + struct { + uint32_t reg_gpio_43_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_43_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_43_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_43_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_43_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_43_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_43_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_43_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_43_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_43_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_43_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_43_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_43_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_43_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_43_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_43_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg43; + + /* 0x974 : gpio_cfg44 */ + union { + struct { + uint32_t reg_gpio_44_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_44_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_44_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_44_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_44_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_44_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_44_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_44_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_44_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_44_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_44_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_44_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_44_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_44_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_44_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_44_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg44; + + /* 0x978 : gpio_cfg45 */ + union { + struct { + uint32_t reg_gpio_45_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_45_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_45_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_45_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_45_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_gpio_45_oe : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t reg_gpio_45_func_sel : 5; /* [12: 8], r/w, 0xb */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_gpio_45_int_mode_set : 4; /* [19:16], r/w, 0x0 */ + uint32_t reg_gpio_45_int_clr : 1; /* [ 20], r/w, 0x0 */ + uint32_t gpio_45_int_stat : 1; /* [ 21], r, 0x0 */ + uint32_t reg_gpio_45_int_mask : 1; /* [ 22], r/w, 0x1 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t reg_gpio_45_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg_gpio_45_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg_gpio_45_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t reg_gpio_45_i : 1; /* [ 28], r, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t reg_gpio_45_mode : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg45; + + /* 0x97C : gpio_cfg46 */ + union { + struct { + uint32_t reg_gpio_46_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_46_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_46_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_46_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_46_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6_31 : 26; /* [31: 6], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg46; + + /* 0x980 : gpio_cfg47 */ + union { + struct { + uint32_t reg_gpio_47_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_47_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_47_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_47_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_47_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6_31 : 26; /* [31: 6], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg47; + + /* 0x984 : gpio_cfg48 */ + union { + struct { + uint32_t reg_gpio_48_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_48_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_48_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_48_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_48_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6_31 : 26; /* [31: 6], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg48; + + /* 0x988 : gpio_cfg49 */ + union { + struct { + uint32_t reg_gpio_49_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_49_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_49_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_49_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_49_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6_31 : 26; /* [31: 6], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg49; + + /* 0x98C : gpio_cfg50 */ + union { + struct { + uint32_t reg_gpio_50_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_50_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_50_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_50_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_50_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6_31 : 26; /* [31: 6], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg50; + + /* 0x990 : gpio_cfg51 */ + union { + struct { + uint32_t reg_gpio_51_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_51_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_51_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_51_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_51_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6_31 : 26; /* [31: 6], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg51; + + /* 0x994 : gpio_cfg52 */ + union { + struct { + uint32_t reg_gpio_52_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_52_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_52_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_52_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_52_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6_31 : 26; /* [31: 6], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg52; + + /* 0x998 : gpio_cfg53 */ + union { + struct { + uint32_t reg_gpio_53_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_53_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_53_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_53_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_53_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6_31 : 26; /* [31: 6], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg53; + + /* 0x99C : gpio_cfg54 */ + union { + struct { + uint32_t reg_gpio_54_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_54_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_54_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_54_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_54_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6_31 : 26; /* [31: 6], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg54; + + /* 0x9A0 : gpio_cfg55 */ + union { + struct { + uint32_t reg_gpio_55_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_55_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_55_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_55_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_55_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6_31 : 26; /* [31: 6], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg55; + + /* 0x9A4 : gpio_cfg56 */ + union { + struct { + uint32_t reg_gpio_56_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_56_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_56_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_56_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_56_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6_31 : 26; /* [31: 6], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg56; + + /* 0x9A8 : gpio_cfg57 */ + union { + struct { + uint32_t reg_gpio_57_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_57_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_57_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_57_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_57_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6_31 : 26; /* [31: 6], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg57; + + /* 0x9AC : gpio_cfg58 */ + union { + struct { + uint32_t reg_gpio_58_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_58_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_58_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_58_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_58_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6_31 : 26; /* [31: 6], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg58; + + /* 0x9B0 : gpio_cfg59 */ + union { + struct { + uint32_t reg_gpio_59_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_59_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_59_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_59_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_59_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6_31 : 26; /* [31: 6], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg59; + + /* 0x9B4 : gpio_cfg60 */ + union { + struct { + uint32_t reg_gpio_60_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_60_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_60_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_60_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_60_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6_31 : 26; /* [31: 6], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg60; + + /* 0x9B8 : gpio_cfg61 */ + union { + struct { + uint32_t reg_gpio_61_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_61_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_61_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_61_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_61_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6_31 : 26; /* [31: 6], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg61; + + /* 0x9BC : gpio_cfg62 */ + union { + struct { + uint32_t reg_gpio_62_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_62_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_62_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_62_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_62_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6_31 : 26; /* [31: 6], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg62; + + /* 0x9C0 : gpio_cfg63 */ + union { + struct { + uint32_t reg_gpio_63_ie : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_gpio_63_smt : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_gpio_63_drv : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_gpio_63_pu : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_gpio_63_pd : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6_31 : 26; /* [31: 6], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg63; + + /* 0x9c4 reserved */ + uint8_t RESERVED0x9c4[256]; + + /* 0xAC4 : gpio_cfg128 */ + union { + struct { + uint32_t reg2_gpio_0_i : 1; /* [ 0], r, 0x0 */ + uint32_t reg2_gpio_1_i : 1; /* [ 1], r, 0x0 */ + uint32_t reg2_gpio_2_i : 1; /* [ 2], r, 0x0 */ + uint32_t reg2_gpio_3_i : 1; /* [ 3], r, 0x0 */ + uint32_t reg2_gpio_4_i : 1; /* [ 4], r, 0x0 */ + uint32_t reg2_gpio_5_i : 1; /* [ 5], r, 0x0 */ + uint32_t reg2_gpio_6_i : 1; /* [ 6], r, 0x0 */ + uint32_t reg2_gpio_7_i : 1; /* [ 7], r, 0x0 */ + uint32_t reg2_gpio_8_i : 1; /* [ 8], r, 0x0 */ + uint32_t reg2_gpio_9_i : 1; /* [ 9], r, 0x0 */ + uint32_t reg2_gpio_10_i : 1; /* [ 10], r, 0x0 */ + uint32_t reg2_gpio_11_i : 1; /* [ 11], r, 0x0 */ + uint32_t reg2_gpio_12_i : 1; /* [ 12], r, 0x0 */ + uint32_t reg2_gpio_13_i : 1; /* [ 13], r, 0x0 */ + uint32_t reg2_gpio_14_i : 1; /* [ 14], r, 0x0 */ + uint32_t reg2_gpio_15_i : 1; /* [ 15], r, 0x0 */ + uint32_t reg2_gpio_16_i : 1; /* [ 16], r, 0x0 */ + uint32_t reg2_gpio_17_i : 1; /* [ 17], r, 0x0 */ + uint32_t reg2_gpio_18_i : 1; /* [ 18], r, 0x0 */ + uint32_t reg2_gpio_19_i : 1; /* [ 19], r, 0x0 */ + uint32_t reg2_gpio_20_i : 1; /* [ 20], r, 0x0 */ + uint32_t reg2_gpio_21_i : 1; /* [ 21], r, 0x0 */ + uint32_t reg2_gpio_22_i : 1; /* [ 22], r, 0x0 */ + uint32_t reg2_gpio_23_i : 1; /* [ 23], r, 0x0 */ + uint32_t reg2_gpio_24_i : 1; /* [ 24], r, 0x0 */ + uint32_t reg2_gpio_25_i : 1; /* [ 25], r, 0x0 */ + uint32_t reg2_gpio_26_i : 1; /* [ 26], r, 0x0 */ + uint32_t reg2_gpio_27_i : 1; /* [ 27], r, 0x0 */ + uint32_t reg2_gpio_28_i : 1; /* [ 28], r, 0x0 */ + uint32_t reg2_gpio_29_i : 1; /* [ 29], r, 0x0 */ + uint32_t reg2_gpio_30_i : 1; /* [ 30], r, 0x0 */ + uint32_t reg2_gpio_31_i : 1; /* [ 31], r, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg128; + + /* 0xAC8 : gpio_cfg129 */ + union { + struct { + uint32_t reg2_gpio_32_i : 1; /* [ 0], r, 0x0 */ + uint32_t reg2_gpio_33_i : 1; /* [ 1], r, 0x0 */ + uint32_t reg2_gpio_34_i : 1; /* [ 2], r, 0x0 */ + uint32_t reg2_gpio_35_i : 1; /* [ 3], r, 0x0 */ + uint32_t reg2_gpio_36_i : 1; /* [ 4], r, 0x0 */ + uint32_t reg2_gpio_37_i : 1; /* [ 5], r, 0x0 */ + uint32_t reg2_gpio_38_i : 1; /* [ 6], r, 0x0 */ + uint32_t reg2_gpio_39_i : 1; /* [ 7], r, 0x0 */ + uint32_t reg2_gpio_40_i : 1; /* [ 8], r, 0x0 */ + uint32_t reg2_gpio_41_i : 1; /* [ 9], r, 0x0 */ + uint32_t reg2_gpio_42_i : 1; /* [ 10], r, 0x0 */ + uint32_t reg2_gpio_43_i : 1; /* [ 11], r, 0x0 */ + uint32_t reg2_gpio_44_i : 1; /* [ 12], r, 0x0 */ + uint32_t reg2_gpio_45_i : 1; /* [ 13], r, 0x0 */ + uint32_t reserved_14_31 : 18; /* [31:14], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg129; + + /* 0xacc reserved */ + uint8_t RESERVED0xacc[24]; + + /* 0xAE4 : gpio_cfg136 */ + union { + struct { + uint32_t reg2_gpio_0_o : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg2_gpio_1_o : 1; /* [ 1], r/w, 0x0 */ + uint32_t reg2_gpio_2_o : 1; /* [ 2], r/w, 0x0 */ + uint32_t reg2_gpio_3_o : 1; /* [ 3], r/w, 0x0 */ + uint32_t reg2_gpio_4_o : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg2_gpio_5_o : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg2_gpio_6_o : 1; /* [ 6], r/w, 0x0 */ + uint32_t reg2_gpio_7_o : 1; /* [ 7], r/w, 0x0 */ + uint32_t reg2_gpio_8_o : 1; /* [ 8], r/w, 0x0 */ + uint32_t reg2_gpio_9_o : 1; /* [ 9], r/w, 0x0 */ + uint32_t reg2_gpio_10_o : 1; /* [ 10], r/w, 0x0 */ + uint32_t reg2_gpio_11_o : 1; /* [ 11], r/w, 0x0 */ + uint32_t reg2_gpio_12_o : 1; /* [ 12], r/w, 0x0 */ + uint32_t reg2_gpio_13_o : 1; /* [ 13], r/w, 0x0 */ + uint32_t reg2_gpio_14_o : 1; /* [ 14], r/w, 0x0 */ + uint32_t reg2_gpio_15_o : 1; /* [ 15], r/w, 0x0 */ + uint32_t reg2_gpio_16_o : 1; /* [ 16], r/w, 0x0 */ + uint32_t reg2_gpio_17_o : 1; /* [ 17], r/w, 0x0 */ + uint32_t reg2_gpio_18_o : 1; /* [ 18], r/w, 0x0 */ + uint32_t reg2_gpio_19_o : 1; /* [ 19], r/w, 0x0 */ + uint32_t reg2_gpio_20_o : 1; /* [ 20], r/w, 0x0 */ + uint32_t reg2_gpio_21_o : 1; /* [ 21], r/w, 0x0 */ + uint32_t reg2_gpio_22_o : 1; /* [ 22], r/w, 0x0 */ + uint32_t reg2_gpio_23_o : 1; /* [ 23], r/w, 0x0 */ + uint32_t reg2_gpio_24_o : 1; /* [ 24], r/w, 0x0 */ + uint32_t reg2_gpio_25_o : 1; /* [ 25], r/w, 0x0 */ + uint32_t reg2_gpio_26_o : 1; /* [ 26], r/w, 0x0 */ + uint32_t reg2_gpio_27_o : 1; /* [ 27], r/w, 0x0 */ + uint32_t reg2_gpio_28_o : 1; /* [ 28], r/w, 0x0 */ + uint32_t reg2_gpio_29_o : 1; /* [ 29], r/w, 0x0 */ + uint32_t reg2_gpio_30_o : 1; /* [ 30], r/w, 0x0 */ + uint32_t reg2_gpio_31_o : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg136; + + /* 0xAE8 : gpio_cfg137 */ + union { + struct { + uint32_t reg2_gpio_32_o : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg2_gpio_33_o : 1; /* [ 1], r/w, 0x0 */ + uint32_t reg2_gpio_34_o : 1; /* [ 2], r/w, 0x0 */ + uint32_t reg2_gpio_35_o : 1; /* [ 3], r/w, 0x0 */ + uint32_t reg2_gpio_36_o : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg2_gpio_37_o : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg2_gpio_38_o : 1; /* [ 6], r/w, 0x0 */ + uint32_t reg2_gpio_39_o : 1; /* [ 7], r/w, 0x0 */ + uint32_t reg2_gpio_40_o : 1; /* [ 8], r/w, 0x0 */ + uint32_t reg2_gpio_41_o : 1; /* [ 9], r/w, 0x0 */ + uint32_t reg2_gpio_42_o : 1; /* [ 10], r/w, 0x0 */ + uint32_t reg2_gpio_43_o : 1; /* [ 11], r/w, 0x0 */ + uint32_t reg2_gpio_44_o : 1; /* [ 12], r/w, 0x0 */ + uint32_t reg2_gpio_45_o : 1; /* [ 13], r/w, 0x0 */ + uint32_t reserved_14_31 : 18; /* [31:14], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg137; + + /* 0xAEC : gpio_cfg138 */ + union { + struct { + uint32_t reg2_gpio_0_set : 1; /* [ 0], w1p, 0x0 */ + uint32_t reg2_gpio_1_set : 1; /* [ 1], w1p, 0x0 */ + uint32_t reg2_gpio_2_set : 1; /* [ 2], w1p, 0x0 */ + uint32_t reg2_gpio_3_set : 1; /* [ 3], w1p, 0x0 */ + uint32_t reg2_gpio_4_set : 1; /* [ 4], w1p, 0x0 */ + uint32_t reg2_gpio_5_set : 1; /* [ 5], w1p, 0x0 */ + uint32_t reg2_gpio_6_set : 1; /* [ 6], w1p, 0x0 */ + uint32_t reg2_gpio_7_set : 1; /* [ 7], w1p, 0x0 */ + uint32_t reg2_gpio_8_set : 1; /* [ 8], w1p, 0x0 */ + uint32_t reg2_gpio_9_set : 1; /* [ 9], w1p, 0x0 */ + uint32_t reg2_gpio_10_set : 1; /* [ 10], w1p, 0x0 */ + uint32_t reg2_gpio_11_set : 1; /* [ 11], w1p, 0x0 */ + uint32_t reg2_gpio_12_set : 1; /* [ 12], w1p, 0x0 */ + uint32_t reg2_gpio_13_set : 1; /* [ 13], w1p, 0x0 */ + uint32_t reg2_gpio_14_set : 1; /* [ 14], w1p, 0x0 */ + uint32_t reg2_gpio_15_set : 1; /* [ 15], w1p, 0x0 */ + uint32_t reg2_gpio_16_set : 1; /* [ 16], w1p, 0x0 */ + uint32_t reg2_gpio_17_set : 1; /* [ 17], w1p, 0x0 */ + uint32_t reg2_gpio_18_set : 1; /* [ 18], w1p, 0x0 */ + uint32_t reg2_gpio_19_set : 1; /* [ 19], w1p, 0x0 */ + uint32_t reg2_gpio_20_set : 1; /* [ 20], w1p, 0x0 */ + uint32_t reg2_gpio_21_set : 1; /* [ 21], w1p, 0x0 */ + uint32_t reg2_gpio_22_set : 1; /* [ 22], w1p, 0x0 */ + uint32_t reg2_gpio_23_set : 1; /* [ 23], w1p, 0x0 */ + uint32_t reg2_gpio_24_set : 1; /* [ 24], w1p, 0x0 */ + uint32_t reg2_gpio_25_set : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg2_gpio_26_set : 1; /* [ 26], w1p, 0x0 */ + uint32_t reg2_gpio_27_set : 1; /* [ 27], w1p, 0x0 */ + uint32_t reg2_gpio_28_set : 1; /* [ 28], w1p, 0x0 */ + uint32_t reg2_gpio_29_set : 1; /* [ 29], w1p, 0x0 */ + uint32_t reg2_gpio_30_set : 1; /* [ 30], w1p, 0x0 */ + uint32_t reg2_gpio_31_set : 1; /* [ 31], w1p, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg138; + + /* 0xAF0 : gpio_cfg139 */ + union { + struct { + uint32_t reg2_gpio_32_set : 1; /* [ 0], w1p, 0x0 */ + uint32_t reg2_gpio_33_set : 1; /* [ 1], w1p, 0x0 */ + uint32_t reg2_gpio_34_set : 1; /* [ 2], w1p, 0x0 */ + uint32_t reg2_gpio_35_set : 1; /* [ 3], w1p, 0x0 */ + uint32_t reg2_gpio_36_set : 1; /* [ 4], w1p, 0x0 */ + uint32_t reg2_gpio_37_set : 1; /* [ 5], w1p, 0x0 */ + uint32_t reg2_gpio_38_set : 1; /* [ 6], w1p, 0x0 */ + uint32_t reg2_gpio_39_set : 1; /* [ 7], w1p, 0x0 */ + uint32_t reg2_gpio_40_set : 1; /* [ 8], w1p, 0x0 */ + uint32_t reg2_gpio_41_set : 1; /* [ 9], w1p, 0x0 */ + uint32_t reg2_gpio_42_set : 1; /* [ 10], w1p, 0x0 */ + uint32_t reg2_gpio_43_set : 1; /* [ 11], w1p, 0x0 */ + uint32_t reg2_gpio_44_set : 1; /* [ 12], w1p, 0x0 */ + uint32_t reg2_gpio_45_set : 1; /* [ 13], w1p, 0x0 */ + uint32_t reserved_14_31 : 18; /* [31:14], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg139; + + /* 0xAF4 : gpio_cfg140 */ + union { + struct { + uint32_t reg2_gpio_0_clr : 1; /* [ 0], w1p, 0x0 */ + uint32_t reg2_gpio_1_clr : 1; /* [ 1], w1p, 0x0 */ + uint32_t reg2_gpio_2_clr : 1; /* [ 2], w1p, 0x0 */ + uint32_t reg2_gpio_3_clr : 1; /* [ 3], w1p, 0x0 */ + uint32_t reg2_gpio_4_clr : 1; /* [ 4], w1p, 0x0 */ + uint32_t reg2_gpio_5_clr : 1; /* [ 5], w1p, 0x0 */ + uint32_t reg2_gpio_6_clr : 1; /* [ 6], w1p, 0x0 */ + uint32_t reg2_gpio_7_clr : 1; /* [ 7], w1p, 0x0 */ + uint32_t reg2_gpio_8_clr : 1; /* [ 8], w1p, 0x0 */ + uint32_t reg2_gpio_9_clr : 1; /* [ 9], w1p, 0x0 */ + uint32_t reg2_gpio_10_clr : 1; /* [ 10], w1p, 0x0 */ + uint32_t reg2_gpio_11_clr : 1; /* [ 11], w1p, 0x0 */ + uint32_t reg2_gpio_12_clr : 1; /* [ 12], w1p, 0x0 */ + uint32_t reg2_gpio_13_clr : 1; /* [ 13], w1p, 0x0 */ + uint32_t reg2_gpio_14_clr : 1; /* [ 14], w1p, 0x0 */ + uint32_t reg2_gpio_15_clr : 1; /* [ 15], w1p, 0x0 */ + uint32_t reg2_gpio_16_clr : 1; /* [ 16], w1p, 0x0 */ + uint32_t reg2_gpio_17_clr : 1; /* [ 17], w1p, 0x0 */ + uint32_t reg2_gpio_18_clr : 1; /* [ 18], w1p, 0x0 */ + uint32_t reg2_gpio_19_clr : 1; /* [ 19], w1p, 0x0 */ + uint32_t reg2_gpio_20_clr : 1; /* [ 20], w1p, 0x0 */ + uint32_t reg2_gpio_21_clr : 1; /* [ 21], w1p, 0x0 */ + uint32_t reg2_gpio_22_clr : 1; /* [ 22], w1p, 0x0 */ + uint32_t reg2_gpio_23_clr : 1; /* [ 23], w1p, 0x0 */ + uint32_t reg2_gpio_24_clr : 1; /* [ 24], w1p, 0x0 */ + uint32_t reg2_gpio_25_clr : 1; /* [ 25], w1p, 0x0 */ + uint32_t reg2_gpio_26_clr : 1; /* [ 26], w1p, 0x0 */ + uint32_t reg2_gpio_27_clr : 1; /* [ 27], w1p, 0x0 */ + uint32_t reg2_gpio_28_clr : 1; /* [ 28], w1p, 0x0 */ + uint32_t reg2_gpio_29_clr : 1; /* [ 29], w1p, 0x0 */ + uint32_t reg2_gpio_30_clr : 1; /* [ 30], w1p, 0x0 */ + uint32_t reg2_gpio_31_clr : 1; /* [ 31], w1p, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg140; + + /* 0xAF8 : gpio_cfg141 */ + union { + struct { + uint32_t reg2_gpio_32_clr : 1; /* [ 0], w1p, 0x0 */ + uint32_t reg2_gpio_33_clr : 1; /* [ 1], w1p, 0x0 */ + uint32_t reg2_gpio_34_clr : 1; /* [ 2], w1p, 0x0 */ + uint32_t reg2_gpio_35_clr : 1; /* [ 3], w1p, 0x0 */ + uint32_t reg2_gpio_36_clr : 1; /* [ 4], w1p, 0x0 */ + uint32_t reg2_gpio_37_clr : 1; /* [ 5], w1p, 0x0 */ + uint32_t reg2_gpio_38_clr : 1; /* [ 6], w1p, 0x0 */ + uint32_t reg2_gpio_39_clr : 1; /* [ 7], w1p, 0x0 */ + uint32_t reg2_gpio_40_clr : 1; /* [ 8], w1p, 0x0 */ + uint32_t reg2_gpio_41_clr : 1; /* [ 9], w1p, 0x0 */ + uint32_t reg2_gpio_42_clr : 1; /* [ 10], w1p, 0x0 */ + uint32_t reg2_gpio_43_clr : 1; /* [ 11], w1p, 0x0 */ + uint32_t reg2_gpio_44_clr : 1; /* [ 12], w1p, 0x0 */ + uint32_t reg2_gpio_45_clr : 1; /* [ 13], w1p, 0x0 */ + uint32_t reserved_14_31 : 18; /* [31:14], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg141; + + /* 0xAFC : gpio_cfg142 */ + union { + struct { + uint32_t cr_gpio_tx_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t cr_invert_code0_high : 1; /* [ 1], r/w, 0x0 */ + uint32_t cr_invert_code1_high : 1; /* [ 2], r/w, 0x0 */ + uint32_t reserved_3_6 : 4; /* [ 6: 3], rsvd, 0x0 */ + uint32_t cr_code_total_time : 9; /* [15: 7], r/w, 0x190 */ + uint32_t cr_code0_high_time : 8; /* [23:16], r/w, 0xc8 */ + uint32_t cr_code1_high_time : 8; /* [31:24], r/w, 0xc8 */ + } BF; + uint32_t WORD; + } gpio_cfg142; + + /* 0xB00 : gpio_cfg143 */ + union { + struct { + uint32_t cr_gpio_dma_tx_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t cr_gpio_dma_out_sel_latch : 1; /* [ 1], r/w, 0x0 */ + uint32_t gpio_tx_fifo_clr : 1; /* [ 2], w1c, 0x0 */ + uint32_t gpio_tx_end_clr : 1; /* [ 3], w1c, 0x0 */ + uint32_t gpio_tx_fifo_overflow : 1; /* [ 4], r, 0x0 */ + uint32_t gpio_tx_fifo_underflow : 1; /* [ 5], r, 0x0 */ + uint32_t reserved_6 : 1; /* [ 6], rsvd, 0x0 */ + uint32_t cr_gpio_dma_park_value : 1; /* [ 7], r/w, 0x0 */ + uint32_t gpio_tx_fifo_cnt : 8; /* [15: 8], r, 0x80 */ + uint32_t cr_gpio_tx_fifo_th : 7; /* [22:16], r/w, 0x0 */ + uint32_t cr_gpio_tx_end_mask : 1; /* [ 23], r/w, 0x1 */ + uint32_t cr_gpio_tx_fifo_mask : 1; /* [ 24], r/w, 0x1 */ + uint32_t cr_gpio_tx_fer_mask : 1; /* [ 25], r/w, 0x1 */ + uint32_t r_gpio_tx_end_int : 1; /* [ 26], r, 0x0 */ + uint32_t r_gpio_tx_fifo_int : 1; /* [ 27], r, 0x0 */ + uint32_t r_gpio_tx_fer_int : 1; /* [ 28], r, 0x0 */ + uint32_t cr_gpio_tx_end_en : 1; /* [ 29], r/w, 0x1 */ + uint32_t cr_gpio_tx_fifo_en : 1; /* [ 30], r/w, 0x1 */ + uint32_t cr_gpio_tx_fer_en : 1; /* [ 31], r/w, 0x1 */ + } BF; + uint32_t WORD; + } gpio_cfg143; + + /* 0xB04 : gpio_cfg144 */ + union { + struct { + uint32_t gpio_tx_data_to_fifo : 16; /* [15: 0], w, x */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } gpio_cfg144; +}; + +typedef volatile struct glb_reg glb_reg_t; + +#endif /* __GLB_REG_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/hbn_reg.h b/platforms/bl808_m0/vendor/psram/include/hbn_reg.h new file mode 100644 index 0000000..0209183 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/hbn_reg.h @@ -0,0 +1,896 @@ +/** + ****************************************************************************** + * @file hbn_reg.h + * @version V1.0 + * @date 2022-02-15 + * @brief This file is the description of.IP register + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __HBN_REG_H__ +#define __HBN_REG_H__ + +#include "bl808.h" + +/* 0x0 : HBN_CTL */ +#define HBN_CTL_OFFSET (0x0) +#define HBN_RTC_CTL HBN_RTC_CTL +#define HBN_RTC_CTL_POS (0U) +#define HBN_RTC_CTL_LEN (4U) +#define HBN_RTC_CTL_MSK (((1U << HBN_RTC_CTL_LEN) - 1) << HBN_RTC_CTL_POS) +#define HBN_RTC_CTL_UMSK (~(((1U << HBN_RTC_CTL_LEN) - 1) << HBN_RTC_CTL_POS)) +#define HBN_RTC_DLY_OPTION HBN_RTC_DLY_OPTION +#define HBN_RTC_DLY_OPTION_POS (4U) +#define HBN_RTC_DLY_OPTION_LEN (1U) +#define HBN_RTC_DLY_OPTION_MSK (((1U << HBN_RTC_DLY_OPTION_LEN) - 1) << HBN_RTC_DLY_OPTION_POS) +#define HBN_RTC_DLY_OPTION_UMSK (~(((1U << HBN_RTC_DLY_OPTION_LEN) - 1) << HBN_RTC_DLY_OPTION_POS)) +#define HBN_PU_LDO18IO_AON HBN_PU_LDO18IO_AON +#define HBN_PU_LDO18IO_AON_POS (5U) +#define HBN_PU_LDO18IO_AON_LEN (1U) +#define HBN_PU_LDO18IO_AON_MSK (((1U << HBN_PU_LDO18IO_AON_LEN) - 1) << HBN_PU_LDO18IO_AON_POS) +#define HBN_PU_LDO18IO_AON_UMSK (~(((1U << HBN_PU_LDO18IO_AON_LEN) - 1) << HBN_PU_LDO18IO_AON_POS)) +#define HBN_MODE HBN_MODE +#define HBN_MODE_POS (7U) +#define HBN_MODE_LEN (1U) +#define HBN_MODE_MSK (((1U << HBN_MODE_LEN) - 1) << HBN_MODE_POS) +#define HBN_MODE_UMSK (~(((1U << HBN_MODE_LEN) - 1) << HBN_MODE_POS)) +#define HBN_TRAP_MODE HBN_TRAP_MODE +#define HBN_TRAP_MODE_POS (8U) +#define HBN_TRAP_MODE_LEN (1U) +#define HBN_TRAP_MODE_MSK (((1U << HBN_TRAP_MODE_LEN) - 1) << HBN_TRAP_MODE_POS) +#define HBN_TRAP_MODE_UMSK (~(((1U << HBN_TRAP_MODE_LEN) - 1) << HBN_TRAP_MODE_POS)) +#define HBN_PWRDN_HBN_CORE HBN_PWRDN_HBN_CORE +#define HBN_PWRDN_HBN_CORE_POS (9U) +#define HBN_PWRDN_HBN_CORE_LEN (1U) +#define HBN_PWRDN_HBN_CORE_MSK (((1U << HBN_PWRDN_HBN_CORE_LEN) - 1) << HBN_PWRDN_HBN_CORE_POS) +#define HBN_PWRDN_HBN_CORE_UMSK (~(((1U << HBN_PWRDN_HBN_CORE_LEN) - 1) << HBN_PWRDN_HBN_CORE_POS)) +#define HBN_SW_RST HBN_SW_RST +#define HBN_SW_RST_POS (12U) +#define HBN_SW_RST_LEN (1U) +#define HBN_SW_RST_MSK (((1U << HBN_SW_RST_LEN) - 1) << HBN_SW_RST_POS) +#define HBN_SW_RST_UMSK (~(((1U << HBN_SW_RST_LEN) - 1) << HBN_SW_RST_POS)) +#define HBN_DIS_PWR_OFF_LDO11 HBN_DIS_PWR_OFF_LDO11 +#define HBN_DIS_PWR_OFF_LDO11_POS (13U) +#define HBN_DIS_PWR_OFF_LDO11_LEN (1U) +#define HBN_DIS_PWR_OFF_LDO11_MSK (((1U << HBN_DIS_PWR_OFF_LDO11_LEN) - 1) << HBN_DIS_PWR_OFF_LDO11_POS) +#define HBN_DIS_PWR_OFF_LDO11_UMSK (~(((1U << HBN_DIS_PWR_OFF_LDO11_LEN) - 1) << HBN_DIS_PWR_OFF_LDO11_POS)) +#define HBN_DIS_PWR_OFF_LDO11_RT HBN_DIS_PWR_OFF_LDO11_RT +#define HBN_DIS_PWR_OFF_LDO11_RT_POS (14U) +#define HBN_DIS_PWR_OFF_LDO11_RT_LEN (1U) +#define HBN_DIS_PWR_OFF_LDO11_RT_MSK (((1U << HBN_DIS_PWR_OFF_LDO11_RT_LEN) - 1) << HBN_DIS_PWR_OFF_LDO11_RT_POS) +#define HBN_DIS_PWR_OFF_LDO11_RT_UMSK (~(((1U << HBN_DIS_PWR_OFF_LDO11_RT_LEN) - 1) << HBN_DIS_PWR_OFF_LDO11_RT_POS)) +#define HBN_LDO11_RT_VOUT_SEL HBN_LDO11_RT_VOUT_SEL +#define HBN_LDO11_RT_VOUT_SEL_POS (15U) +#define HBN_LDO11_RT_VOUT_SEL_LEN (4U) +#define HBN_LDO11_RT_VOUT_SEL_MSK (((1U << HBN_LDO11_RT_VOUT_SEL_LEN) - 1) << HBN_LDO11_RT_VOUT_SEL_POS) +#define HBN_LDO11_RT_VOUT_SEL_UMSK (~(((1U << HBN_LDO11_RT_VOUT_SEL_LEN) - 1) << HBN_LDO11_RT_VOUT_SEL_POS)) +#define HBN_LDO11_AON_VOUT_SEL HBN_LDO11_AON_VOUT_SEL +#define HBN_LDO11_AON_VOUT_SEL_POS (19U) +#define HBN_LDO11_AON_VOUT_SEL_LEN (4U) +#define HBN_LDO11_AON_VOUT_SEL_MSK (((1U << HBN_LDO11_AON_VOUT_SEL_LEN) - 1) << HBN_LDO11_AON_VOUT_SEL_POS) +#define HBN_LDO11_AON_VOUT_SEL_UMSK (~(((1U << HBN_LDO11_AON_VOUT_SEL_LEN) - 1) << HBN_LDO11_AON_VOUT_SEL_POS)) +#define HBN_PU_DCDC_AON HBN_PU_DCDC_AON +#define HBN_PU_DCDC_AON_POS (23U) +#define HBN_PU_DCDC_AON_LEN (1U) +#define HBN_PU_DCDC_AON_MSK (((1U << HBN_PU_DCDC_AON_LEN) - 1) << HBN_PU_DCDC_AON_POS) +#define HBN_PU_DCDC_AON_UMSK (~(((1U << HBN_PU_DCDC_AON_LEN) - 1) << HBN_PU_DCDC_AON_POS)) +#define HBN_PU_DCDC18_AON HBN_PU_DCDC18_AON +#define HBN_PU_DCDC18_AON_POS (24U) +#define HBN_PU_DCDC18_AON_LEN (1U) +#define HBN_PU_DCDC18_AON_MSK (((1U << HBN_PU_DCDC18_AON_LEN) - 1) << HBN_PU_DCDC18_AON_POS) +#define HBN_PU_DCDC18_AON_UMSK (~(((1U << HBN_PU_DCDC18_AON_LEN) - 1) << HBN_PU_DCDC18_AON_POS)) +#define HBN_PWR_ON_OPTION HBN_PWR_ON_OPTION +#define HBN_PWR_ON_OPTION_POS (25U) +#define HBN_PWR_ON_OPTION_LEN (1U) +#define HBN_PWR_ON_OPTION_MSK (((1U << HBN_PWR_ON_OPTION_LEN) - 1) << HBN_PWR_ON_OPTION_POS) +#define HBN_PWR_ON_OPTION_UMSK (~(((1U << HBN_PWR_ON_OPTION_LEN) - 1) << HBN_PWR_ON_OPTION_POS)) +#define HBN_SRAM_SLP_OPTION HBN_SRAM_SLP_OPTION +#define HBN_SRAM_SLP_OPTION_POS (26U) +#define HBN_SRAM_SLP_OPTION_LEN (1U) +#define HBN_SRAM_SLP_OPTION_MSK (((1U << HBN_SRAM_SLP_OPTION_LEN) - 1) << HBN_SRAM_SLP_OPTION_POS) +#define HBN_SRAM_SLP_OPTION_UMSK (~(((1U << HBN_SRAM_SLP_OPTION_LEN) - 1) << HBN_SRAM_SLP_OPTION_POS)) +#define HBN_SRAM_SLP HBN_SRAM_SLP +#define HBN_SRAM_SLP_POS (27U) +#define HBN_SRAM_SLP_LEN (1U) +#define HBN_SRAM_SLP_MSK (((1U << HBN_SRAM_SLP_LEN) - 1) << HBN_SRAM_SLP_POS) +#define HBN_SRAM_SLP_UMSK (~(((1U << HBN_SRAM_SLP_LEN) - 1) << HBN_SRAM_SLP_POS)) +#define HBN_STATE HBN_STATE +#define HBN_STATE_POS (28U) +#define HBN_STATE_LEN (4U) +#define HBN_STATE_MSK (((1U << HBN_STATE_LEN) - 1) << HBN_STATE_POS) +#define HBN_STATE_UMSK (~(((1U << HBN_STATE_LEN) - 1) << HBN_STATE_POS)) + +/* 0x4 : HBN_TIME_L */ +#define HBN_TIME_L_OFFSET (0x4) +#define HBN_TIME_L HBN_TIME_L +#define HBN_TIME_L_POS (0U) +#define HBN_TIME_L_LEN (32U) +#define HBN_TIME_L_MSK (((1U << HBN_TIME_L_LEN) - 1) << HBN_TIME_L_POS) +#define HBN_TIME_L_UMSK (~(((1U << HBN_TIME_L_LEN) - 1) << HBN_TIME_L_POS)) + +/* 0x8 : HBN_TIME_H */ +#define HBN_TIME_H_OFFSET (0x8) +#define HBN_TIME_H HBN_TIME_H +#define HBN_TIME_H_POS (0U) +#define HBN_TIME_H_LEN (8U) +#define HBN_TIME_H_MSK (((1U << HBN_TIME_H_LEN) - 1) << HBN_TIME_H_POS) +#define HBN_TIME_H_UMSK (~(((1U << HBN_TIME_H_LEN) - 1) << HBN_TIME_H_POS)) + +/* 0xC : RTC_TIME_L */ +#define HBN_RTC_TIME_L_OFFSET (0xC) +#define HBN_RTC_TIME_LATCH_L HBN_RTC_TIME_LATCH_L +#define HBN_RTC_TIME_LATCH_L_POS (0U) +#define HBN_RTC_TIME_LATCH_L_LEN (32U) +#define HBN_RTC_TIME_LATCH_L_MSK (((1U << HBN_RTC_TIME_LATCH_L_LEN) - 1) << HBN_RTC_TIME_LATCH_L_POS) +#define HBN_RTC_TIME_LATCH_L_UMSK (~(((1U << HBN_RTC_TIME_LATCH_L_LEN) - 1) << HBN_RTC_TIME_LATCH_L_POS)) + +/* 0x10 : RTC_TIME_H */ +#define HBN_RTC_TIME_H_OFFSET (0x10) +#define HBN_RTC_TIME_LATCH_H HBN_RTC_TIME_LATCH_H +#define HBN_RTC_TIME_LATCH_H_POS (0U) +#define HBN_RTC_TIME_LATCH_H_LEN (8U) +#define HBN_RTC_TIME_LATCH_H_MSK (((1U << HBN_RTC_TIME_LATCH_H_LEN) - 1) << HBN_RTC_TIME_LATCH_H_POS) +#define HBN_RTC_TIME_LATCH_H_UMSK (~(((1U << HBN_RTC_TIME_LATCH_H_LEN) - 1) << HBN_RTC_TIME_LATCH_H_POS)) +#define HBN_RTC_TIME_LATCH HBN_RTC_TIME_LATCH +#define HBN_RTC_TIME_LATCH_POS (31U) +#define HBN_RTC_TIME_LATCH_LEN (1U) +#define HBN_RTC_TIME_LATCH_MSK (((1U << HBN_RTC_TIME_LATCH_LEN) - 1) << HBN_RTC_TIME_LATCH_POS) +#define HBN_RTC_TIME_LATCH_UMSK (~(((1U << HBN_RTC_TIME_LATCH_LEN) - 1) << HBN_RTC_TIME_LATCH_POS)) + +/* 0x14 : HBN_IRQ_MODE */ +#define HBN_IRQ_MODE_OFFSET (0x14) +#define HBN_PIN_WAKEUP_MODE HBN_PIN_WAKEUP_MODE +#define HBN_PIN_WAKEUP_MODE_POS (0U) +#define HBN_PIN_WAKEUP_MODE_LEN (4U) +#define HBN_PIN_WAKEUP_MODE_MSK (((1U << HBN_PIN_WAKEUP_MODE_LEN) - 1) << HBN_PIN_WAKEUP_MODE_POS) +#define HBN_PIN_WAKEUP_MODE_UMSK (~(((1U << HBN_PIN_WAKEUP_MODE_LEN) - 1) << HBN_PIN_WAKEUP_MODE_POS)) +#define HBN_PIN_WAKEUP_MASK HBN_PIN_WAKEUP_MASK +#define HBN_PIN_WAKEUP_MASK_POS (4U) +#define HBN_PIN_WAKEUP_MASK_LEN (9U) +#define HBN_PIN_WAKEUP_MASK_MSK (((1U << HBN_PIN_WAKEUP_MASK_LEN) - 1) << HBN_PIN_WAKEUP_MASK_POS) +#define HBN_PIN_WAKEUP_MASK_UMSK (~(((1U << HBN_PIN_WAKEUP_MASK_LEN) - 1) << HBN_PIN_WAKEUP_MASK_POS)) +#define HBN_REG_EN_HW_PU_PD HBN_REG_EN_HW_PU_PD +#define HBN_REG_EN_HW_PU_PD_POS (16U) +#define HBN_REG_EN_HW_PU_PD_LEN (1U) +#define HBN_REG_EN_HW_PU_PD_MSK (((1U << HBN_REG_EN_HW_PU_PD_LEN) - 1) << HBN_REG_EN_HW_PU_PD_POS) +#define HBN_REG_EN_HW_PU_PD_UMSK (~(((1U << HBN_REG_EN_HW_PU_PD_LEN) - 1) << HBN_REG_EN_HW_PU_PD_POS)) +#define HBN_IRQ_BOR_EN HBN_IRQ_BOR_EN +#define HBN_IRQ_BOR_EN_POS (18U) +#define HBN_IRQ_BOR_EN_LEN (1U) +#define HBN_IRQ_BOR_EN_MSK (((1U << HBN_IRQ_BOR_EN_LEN) - 1) << HBN_IRQ_BOR_EN_POS) +#define HBN_IRQ_BOR_EN_UMSK (~(((1U << HBN_IRQ_BOR_EN_LEN) - 1) << HBN_IRQ_BOR_EN_POS)) +#define HBN_IRQ_ACOMP0_EN HBN_IRQ_ACOMP0_EN +#define HBN_IRQ_ACOMP0_EN_POS (20U) +#define HBN_IRQ_ACOMP0_EN_LEN (2U) +#define HBN_IRQ_ACOMP0_EN_MSK (((1U << HBN_IRQ_ACOMP0_EN_LEN) - 1) << HBN_IRQ_ACOMP0_EN_POS) +#define HBN_IRQ_ACOMP0_EN_UMSK (~(((1U << HBN_IRQ_ACOMP0_EN_LEN) - 1) << HBN_IRQ_ACOMP0_EN_POS)) +#define HBN_IRQ_ACOMP1_EN HBN_IRQ_ACOMP1_EN +#define HBN_IRQ_ACOMP1_EN_POS (22U) +#define HBN_IRQ_ACOMP1_EN_LEN (2U) +#define HBN_IRQ_ACOMP1_EN_MSK (((1U << HBN_IRQ_ACOMP1_EN_LEN) - 1) << HBN_IRQ_ACOMP1_EN_POS) +#define HBN_IRQ_ACOMP1_EN_UMSK (~(((1U << HBN_IRQ_ACOMP1_EN_LEN) - 1) << HBN_IRQ_ACOMP1_EN_POS)) +#define HBN_PIN_WAKEUP_SEL HBN_PIN_WAKEUP_SEL +#define HBN_PIN_WAKEUP_SEL_POS (24U) +#define HBN_PIN_WAKEUP_SEL_LEN (3U) +#define HBN_PIN_WAKEUP_SEL_MSK (((1U << HBN_PIN_WAKEUP_SEL_LEN) - 1) << HBN_PIN_WAKEUP_SEL_POS) +#define HBN_PIN_WAKEUP_SEL_UMSK (~(((1U << HBN_PIN_WAKEUP_SEL_LEN) - 1) << HBN_PIN_WAKEUP_SEL_POS)) +#define HBN_PIN_WAKEUP_EN HBN_PIN_WAKEUP_EN +#define HBN_PIN_WAKEUP_EN_POS (27U) +#define HBN_PIN_WAKEUP_EN_LEN (1U) +#define HBN_PIN_WAKEUP_EN_MSK (((1U << HBN_PIN_WAKEUP_EN_LEN) - 1) << HBN_PIN_WAKEUP_EN_POS) +#define HBN_PIN_WAKEUP_EN_UMSK (~(((1U << HBN_PIN_WAKEUP_EN_LEN) - 1) << HBN_PIN_WAKEUP_EN_POS)) + +/* 0x18 : HBN_IRQ_STAT */ +#define HBN_IRQ_STAT_OFFSET (0x18) +#define HBN_IRQ_STAT HBN_IRQ_STAT +#define HBN_IRQ_STAT_POS (0U) +#define HBN_IRQ_STAT_LEN (32U) +#define HBN_IRQ_STAT_MSK (((1U << HBN_IRQ_STAT_LEN) - 1) << HBN_IRQ_STAT_POS) +#define HBN_IRQ_STAT_UMSK (~(((1U << HBN_IRQ_STAT_LEN) - 1) << HBN_IRQ_STAT_POS)) + +/* 0x1C : HBN_IRQ_CLR */ +#define HBN_IRQ_CLR_OFFSET (0x1C) +#define HBN_IRQ_CLR HBN_IRQ_CLR +#define HBN_IRQ_CLR_POS (0U) +#define HBN_IRQ_CLR_LEN (32U) +#define HBN_IRQ_CLR_MSK (((1U << HBN_IRQ_CLR_LEN) - 1) << HBN_IRQ_CLR_POS) +#define HBN_IRQ_CLR_UMSK (~(((1U << HBN_IRQ_CLR_LEN) - 1) << HBN_IRQ_CLR_POS)) + +/* 0x20 : HBN_PIR_CFG */ +#define HBN_PIR_CFG_OFFSET (0x20) +#define HBN_PIR_HPF_SEL HBN_PIR_HPF_SEL +#define HBN_PIR_HPF_SEL_POS (0U) +#define HBN_PIR_HPF_SEL_LEN (2U) +#define HBN_PIR_HPF_SEL_MSK (((1U << HBN_PIR_HPF_SEL_LEN) - 1) << HBN_PIR_HPF_SEL_POS) +#define HBN_PIR_HPF_SEL_UMSK (~(((1U << HBN_PIR_HPF_SEL_LEN) - 1) << HBN_PIR_HPF_SEL_POS)) +#define HBN_PIR_LPF_SEL HBN_PIR_LPF_SEL +#define HBN_PIR_LPF_SEL_POS (2U) +#define HBN_PIR_LPF_SEL_LEN (1U) +#define HBN_PIR_LPF_SEL_MSK (((1U << HBN_PIR_LPF_SEL_LEN) - 1) << HBN_PIR_LPF_SEL_POS) +#define HBN_PIR_LPF_SEL_UMSK (~(((1U << HBN_PIR_LPF_SEL_LEN) - 1) << HBN_PIR_LPF_SEL_POS)) +#define HBN_PIR_DIS HBN_PIR_DIS +#define HBN_PIR_DIS_POS (4U) +#define HBN_PIR_DIS_LEN (2U) +#define HBN_PIR_DIS_MSK (((1U << HBN_PIR_DIS_LEN) - 1) << HBN_PIR_DIS_POS) +#define HBN_PIR_DIS_UMSK (~(((1U << HBN_PIR_DIS_LEN) - 1) << HBN_PIR_DIS_POS)) +#define HBN_PIR_EN HBN_PIR_EN +#define HBN_PIR_EN_POS (7U) +#define HBN_PIR_EN_LEN (1U) +#define HBN_PIR_EN_MSK (((1U << HBN_PIR_EN_LEN) - 1) << HBN_PIR_EN_POS) +#define HBN_PIR_EN_UMSK (~(((1U << HBN_PIR_EN_LEN) - 1) << HBN_PIR_EN_POS)) +#define HBN_GPADC_CS HBN_GPADC_CS +#define HBN_GPADC_CS_POS (8U) +#define HBN_GPADC_CS_LEN (1U) +#define HBN_GPADC_CS_MSK (((1U << HBN_GPADC_CS_LEN) - 1) << HBN_GPADC_CS_POS) +#define HBN_GPADC_CS_UMSK (~(((1U << HBN_GPADC_CS_LEN) - 1) << HBN_GPADC_CS_POS)) + +/* 0x24 : HBN_PIR_VTH */ +#define HBN_PIR_VTH_OFFSET (0x24) +#define HBN_PIR_VTH HBN_PIR_VTH +#define HBN_PIR_VTH_POS (0U) +#define HBN_PIR_VTH_LEN (14U) +#define HBN_PIR_VTH_MSK (((1U << HBN_PIR_VTH_LEN) - 1) << HBN_PIR_VTH_POS) +#define HBN_PIR_VTH_UMSK (~(((1U << HBN_PIR_VTH_LEN) - 1) << HBN_PIR_VTH_POS)) + +/* 0x28 : HBN_PIR_INTERVAL */ +#define HBN_PIR_INTERVAL_OFFSET (0x28) +#define HBN_PIR_INTERVAL HBN_PIR_INTERVAL +#define HBN_PIR_INTERVAL_POS (0U) +#define HBN_PIR_INTERVAL_LEN (12U) +#define HBN_PIR_INTERVAL_MSK (((1U << HBN_PIR_INTERVAL_LEN) - 1) << HBN_PIR_INTERVAL_POS) +#define HBN_PIR_INTERVAL_UMSK (~(((1U << HBN_PIR_INTERVAL_LEN) - 1) << HBN_PIR_INTERVAL_POS)) + +/* 0x2C : HBN_BOR_CFG */ +#define HBN_BOR_CFG_OFFSET (0x2C) +#define HBN_BOD_SEL HBN_BOD_SEL +#define HBN_BOD_SEL_POS (0U) +#define HBN_BOD_SEL_LEN (1U) +#define HBN_BOD_SEL_MSK (((1U << HBN_BOD_SEL_LEN) - 1) << HBN_BOD_SEL_POS) +#define HBN_BOD_SEL_UMSK (~(((1U << HBN_BOD_SEL_LEN) - 1) << HBN_BOD_SEL_POS)) +#define HBN_BOD_VTH HBN_BOD_VTH +#define HBN_BOD_VTH_POS (1U) +#define HBN_BOD_VTH_LEN (3U) +#define HBN_BOD_VTH_MSK (((1U << HBN_BOD_VTH_LEN) - 1) << HBN_BOD_VTH_POS) +#define HBN_BOD_VTH_UMSK (~(((1U << HBN_BOD_VTH_LEN) - 1) << HBN_BOD_VTH_POS)) +#define HBN_PU_BOD HBN_PU_BOD +#define HBN_PU_BOD_POS (4U) +#define HBN_PU_BOD_LEN (1U) +#define HBN_PU_BOD_MSK (((1U << HBN_PU_BOD_LEN) - 1) << HBN_PU_BOD_POS) +#define HBN_PU_BOD_UMSK (~(((1U << HBN_PU_BOD_LEN) - 1) << HBN_PU_BOD_POS)) +#define HBN_R_BOD_OUT HBN_R_BOD_OUT +#define HBN_R_BOD_OUT_POS (5U) +#define HBN_R_BOD_OUT_LEN (1U) +#define HBN_R_BOD_OUT_MSK (((1U << HBN_R_BOD_OUT_LEN) - 1) << HBN_R_BOD_OUT_POS) +#define HBN_R_BOD_OUT_UMSK (~(((1U << HBN_R_BOD_OUT_LEN) - 1) << HBN_R_BOD_OUT_POS)) + +/* 0x30 : HBN_GLB */ +#define HBN_GLB_OFFSET (0x30) +#define HBN_ROOT_CLK_SEL HBN_ROOT_CLK_SEL +#define HBN_ROOT_CLK_SEL_POS (0U) +#define HBN_ROOT_CLK_SEL_LEN (2U) +#define HBN_ROOT_CLK_SEL_MSK (((1U << HBN_ROOT_CLK_SEL_LEN) - 1) << HBN_ROOT_CLK_SEL_POS) +#define HBN_ROOT_CLK_SEL_UMSK (~(((1U << HBN_ROOT_CLK_SEL_LEN) - 1) << HBN_ROOT_CLK_SEL_POS)) +#define HBN_UART_CLK_SEL HBN_UART_CLK_SEL +#define HBN_UART_CLK_SEL_POS (2U) +#define HBN_UART_CLK_SEL_LEN (1U) +#define HBN_UART_CLK_SEL_MSK (((1U << HBN_UART_CLK_SEL_LEN) - 1) << HBN_UART_CLK_SEL_POS) +#define HBN_UART_CLK_SEL_UMSK (~(((1U << HBN_UART_CLK_SEL_LEN) - 1) << HBN_UART_CLK_SEL_POS)) +#define HBN_F32K_SEL HBN_F32K_SEL +#define HBN_F32K_SEL_POS (3U) +#define HBN_F32K_SEL_LEN (2U) +#define HBN_F32K_SEL_MSK (((1U << HBN_F32K_SEL_LEN) - 1) << HBN_F32K_SEL_POS) +#define HBN_F32K_SEL_UMSK (~(((1U << HBN_F32K_SEL_LEN) - 1) << HBN_F32K_SEL_POS)) +#define HBN_RESET_EVENT HBN_RESET_EVENT +#define HBN_RESET_EVENT_POS (7U) +#define HBN_RESET_EVENT_LEN (6U) +#define HBN_RESET_EVENT_MSK (((1U << HBN_RESET_EVENT_LEN) - 1) << HBN_RESET_EVENT_POS) +#define HBN_RESET_EVENT_UMSK (~(((1U << HBN_RESET_EVENT_LEN) - 1) << HBN_RESET_EVENT_POS)) +#define HBN_CLR_RESET_EVENT HBN_CLR_RESET_EVENT +#define HBN_CLR_RESET_EVENT_POS (13U) +#define HBN_CLR_RESET_EVENT_LEN (1U) +#define HBN_CLR_RESET_EVENT_MSK (((1U << HBN_CLR_RESET_EVENT_LEN) - 1) << HBN_CLR_RESET_EVENT_POS) +#define HBN_CLR_RESET_EVENT_UMSK (~(((1U << HBN_CLR_RESET_EVENT_LEN) - 1) << HBN_CLR_RESET_EVENT_POS)) +#define HBN_UART_CLK_SEL2 HBN_UART_CLK_SEL2 +#define HBN_UART_CLK_SEL2_POS (15U) +#define HBN_UART_CLK_SEL2_LEN (1U) +#define HBN_UART_CLK_SEL2_MSK (((1U << HBN_UART_CLK_SEL2_LEN) - 1) << HBN_UART_CLK_SEL2_POS) +#define HBN_UART_CLK_SEL2_UMSK (~(((1U << HBN_UART_CLK_SEL2_LEN) - 1) << HBN_UART_CLK_SEL2_POS)) +#define HBN_SW_LDO11SOC_VOUT_SEL_AON HBN_SW_LDO11SOC_VOUT_SEL_AON +#define HBN_SW_LDO11SOC_VOUT_SEL_AON_POS (16U) +#define HBN_SW_LDO11SOC_VOUT_SEL_AON_LEN (4U) +#define HBN_SW_LDO11SOC_VOUT_SEL_AON_MSK (((1U << HBN_SW_LDO11SOC_VOUT_SEL_AON_LEN) - 1) << HBN_SW_LDO11SOC_VOUT_SEL_AON_POS) +#define HBN_SW_LDO11SOC_VOUT_SEL_AON_UMSK (~(((1U << HBN_SW_LDO11SOC_VOUT_SEL_AON_LEN) - 1) << HBN_SW_LDO11SOC_VOUT_SEL_AON_POS)) +#define HBN_SW_LDO11_RT_VOUT_SEL HBN_SW_LDO11_RT_VOUT_SEL +#define HBN_SW_LDO11_RT_VOUT_SEL_POS (24U) +#define HBN_SW_LDO11_RT_VOUT_SEL_LEN (4U) +#define HBN_SW_LDO11_RT_VOUT_SEL_MSK (((1U << HBN_SW_LDO11_RT_VOUT_SEL_LEN) - 1) << HBN_SW_LDO11_RT_VOUT_SEL_POS) +#define HBN_SW_LDO11_RT_VOUT_SEL_UMSK (~(((1U << HBN_SW_LDO11_RT_VOUT_SEL_LEN) - 1) << HBN_SW_LDO11_RT_VOUT_SEL_POS)) +#define HBN_SW_LDO11_AON_VOUT_SEL HBN_SW_LDO11_AON_VOUT_SEL +#define HBN_SW_LDO11_AON_VOUT_SEL_POS (28U) +#define HBN_SW_LDO11_AON_VOUT_SEL_LEN (4U) +#define HBN_SW_LDO11_AON_VOUT_SEL_MSK (((1U << HBN_SW_LDO11_AON_VOUT_SEL_LEN) - 1) << HBN_SW_LDO11_AON_VOUT_SEL_POS) +#define HBN_SW_LDO11_AON_VOUT_SEL_UMSK (~(((1U << HBN_SW_LDO11_AON_VOUT_SEL_LEN) - 1) << HBN_SW_LDO11_AON_VOUT_SEL_POS)) + +/* 0x34 : HBN_SRAM */ +#define HBN_SRAM_OFFSET (0x34) +#define HBN_RETRAM_RET HBN_RETRAM_RET +#define HBN_RETRAM_RET_POS (6U) +#define HBN_RETRAM_RET_LEN (1U) +#define HBN_RETRAM_RET_MSK (((1U << HBN_RETRAM_RET_LEN) - 1) << HBN_RETRAM_RET_POS) +#define HBN_RETRAM_RET_UMSK (~(((1U << HBN_RETRAM_RET_LEN) - 1) << HBN_RETRAM_RET_POS)) +#define HBN_RETRAM_SLP HBN_RETRAM_SLP +#define HBN_RETRAM_SLP_POS (7U) +#define HBN_RETRAM_SLP_LEN (1U) +#define HBN_RETRAM_SLP_MSK (((1U << HBN_RETRAM_SLP_LEN) - 1) << HBN_RETRAM_SLP_POS) +#define HBN_RETRAM_SLP_UMSK (~(((1U << HBN_RETRAM_SLP_LEN) - 1) << HBN_RETRAM_SLP_POS)) + +/* 0x38 : HBN_PAD_CTRL_0 */ +#define HBN_PAD_CTRL_0_OFFSET (0x38) +#define HBN_REG_AON_PAD_IE_SMT HBN_REG_AON_PAD_IE_SMT +#define HBN_REG_AON_PAD_IE_SMT_POS (0U) +#define HBN_REG_AON_PAD_IE_SMT_LEN (9U) +#define HBN_REG_AON_PAD_IE_SMT_MSK (((1U << HBN_REG_AON_PAD_IE_SMT_LEN) - 1) << HBN_REG_AON_PAD_IE_SMT_POS) +#define HBN_REG_AON_PAD_IE_SMT_UMSK (~(((1U << HBN_REG_AON_PAD_IE_SMT_LEN) - 1) << HBN_REG_AON_PAD_IE_SMT_POS)) +#define HBN_REG_AON_LED_SEL HBN_REG_AON_LED_SEL +#define HBN_REG_AON_LED_SEL_POS (10U) +#define HBN_REG_AON_LED_SEL_LEN (9U) +#define HBN_REG_AON_LED_SEL_MSK (((1U << HBN_REG_AON_LED_SEL_LEN) - 1) << HBN_REG_AON_LED_SEL_POS) +#define HBN_REG_AON_LED_SEL_UMSK (~(((1U << HBN_REG_AON_LED_SEL_LEN) - 1) << HBN_REG_AON_LED_SEL_POS)) +#define HBN_REG_EN_AON_CTRL_GPIO HBN_REG_EN_AON_CTRL_GPIO +#define HBN_REG_EN_AON_CTRL_GPIO_POS (20U) +#define HBN_REG_EN_AON_CTRL_GPIO_LEN (9U) +#define HBN_REG_EN_AON_CTRL_GPIO_MSK (((1U << HBN_REG_EN_AON_CTRL_GPIO_LEN) - 1) << HBN_REG_EN_AON_CTRL_GPIO_POS) +#define HBN_REG_EN_AON_CTRL_GPIO_UMSK (~(((1U << HBN_REG_EN_AON_CTRL_GPIO_LEN) - 1) << HBN_REG_EN_AON_CTRL_GPIO_POS)) +#define HBN_REG_AON_GPIO_ISO_MODE HBN_REG_AON_GPIO_ISO_MODE +#define HBN_REG_AON_GPIO_ISO_MODE_POS (31U) +#define HBN_REG_AON_GPIO_ISO_MODE_LEN (1U) +#define HBN_REG_AON_GPIO_ISO_MODE_MSK (((1U << HBN_REG_AON_GPIO_ISO_MODE_LEN) - 1) << HBN_REG_AON_GPIO_ISO_MODE_POS) +#define HBN_REG_AON_GPIO_ISO_MODE_UMSK (~(((1U << HBN_REG_AON_GPIO_ISO_MODE_LEN) - 1) << HBN_REG_AON_GPIO_ISO_MODE_POS)) + +/* 0x3C : HBN_PAD_CTRL_1 */ +#define HBN_PAD_CTRL_1_OFFSET (0x3C) +#define HBN_REG_AON_PAD_OE HBN_REG_AON_PAD_OE +#define HBN_REG_AON_PAD_OE_POS (0U) +#define HBN_REG_AON_PAD_OE_LEN (9U) +#define HBN_REG_AON_PAD_OE_MSK (((1U << HBN_REG_AON_PAD_OE_LEN) - 1) << HBN_REG_AON_PAD_OE_POS) +#define HBN_REG_AON_PAD_OE_UMSK (~(((1U << HBN_REG_AON_PAD_OE_LEN) - 1) << HBN_REG_AON_PAD_OE_POS)) +#define HBN_REG_AON_PAD_PD HBN_REG_AON_PAD_PD +#define HBN_REG_AON_PAD_PD_POS (10U) +#define HBN_REG_AON_PAD_PD_LEN (9U) +#define HBN_REG_AON_PAD_PD_MSK (((1U << HBN_REG_AON_PAD_PD_LEN) - 1) << HBN_REG_AON_PAD_PD_POS) +#define HBN_REG_AON_PAD_PD_UMSK (~(((1U << HBN_REG_AON_PAD_PD_LEN) - 1) << HBN_REG_AON_PAD_PD_POS)) +#define HBN_REG_AON_PAD_PU HBN_REG_AON_PAD_PU +#define HBN_REG_AON_PAD_PU_POS (20U) +#define HBN_REG_AON_PAD_PU_LEN (9U) +#define HBN_REG_AON_PAD_PU_MSK (((1U << HBN_REG_AON_PAD_PU_LEN) - 1) << HBN_REG_AON_PAD_PU_POS) +#define HBN_REG_AON_PAD_PU_UMSK (~(((1U << HBN_REG_AON_PAD_PU_LEN) - 1) << HBN_REG_AON_PAD_PU_POS)) + +/* 0x100 : HBN_RSV0 */ +#define HBN_RSV0_OFFSET (0x100) +#define HBN_RSV0 HBN_RSV0 +#define HBN_RSV0_POS (0U) +#define HBN_RSV0_LEN (32U) +#define HBN_RSV0_MSK (((1U << HBN_RSV0_LEN) - 1) << HBN_RSV0_POS) +#define HBN_RSV0_UMSK (~(((1U << HBN_RSV0_LEN) - 1) << HBN_RSV0_POS)) + +/* 0x104 : HBN_RSV1 */ +#define HBN_RSV1_OFFSET (0x104) +#define HBN_RSV1 HBN_RSV1 +#define HBN_RSV1_POS (0U) +#define HBN_RSV1_LEN (32U) +#define HBN_RSV1_MSK (((1U << HBN_RSV1_LEN) - 1) << HBN_RSV1_POS) +#define HBN_RSV1_UMSK (~(((1U << HBN_RSV1_LEN) - 1) << HBN_RSV1_POS)) + +/* 0x108 : HBN_RSV2 */ +#define HBN_RSV2_OFFSET (0x108) +#define HBN_RSV2 HBN_RSV2 +#define HBN_RSV2_POS (0U) +#define HBN_RSV2_LEN (32U) +#define HBN_RSV2_MSK (((1U << HBN_RSV2_LEN) - 1) << HBN_RSV2_POS) +#define HBN_RSV2_UMSK (~(((1U << HBN_RSV2_LEN) - 1) << HBN_RSV2_POS)) + +/* 0x10C : HBN_RSV3 */ +#define HBN_RSV3_OFFSET (0x10C) +#define HBN_RSV3 HBN_RSV3 +#define HBN_RSV3_POS (0U) +#define HBN_RSV3_LEN (32U) +#define HBN_RSV3_MSK (((1U << HBN_RSV3_LEN) - 1) << HBN_RSV3_POS) +#define HBN_RSV3_UMSK (~(((1U << HBN_RSV3_LEN) - 1) << HBN_RSV3_POS)) + +/* 0x200 : rc32k_ctrl0 */ +#define HBN_RC32K_CTRL0_OFFSET (0x200) +#define HBN_RC32K_CAL_DONE HBN_RC32K_CAL_DONE +#define HBN_RC32K_CAL_DONE_POS (0U) +#define HBN_RC32K_CAL_DONE_LEN (1U) +#define HBN_RC32K_CAL_DONE_MSK (((1U << HBN_RC32K_CAL_DONE_LEN) - 1) << HBN_RC32K_CAL_DONE_POS) +#define HBN_RC32K_CAL_DONE_UMSK (~(((1U << HBN_RC32K_CAL_DONE_LEN) - 1) << HBN_RC32K_CAL_DONE_POS)) +#define HBN_RC32K_RDY HBN_RC32K_RDY +#define HBN_RC32K_RDY_POS (1U) +#define HBN_RC32K_RDY_LEN (1U) +#define HBN_RC32K_RDY_MSK (((1U << HBN_RC32K_RDY_LEN) - 1) << HBN_RC32K_RDY_POS) +#define HBN_RC32K_RDY_UMSK (~(((1U << HBN_RC32K_RDY_LEN) - 1) << HBN_RC32K_RDY_POS)) +#define HBN_RC32K_CAL_INPROGRESS HBN_RC32K_CAL_INPROGRESS +#define HBN_RC32K_CAL_INPROGRESS_POS (2U) +#define HBN_RC32K_CAL_INPROGRESS_LEN (1U) +#define HBN_RC32K_CAL_INPROGRESS_MSK (((1U << HBN_RC32K_CAL_INPROGRESS_LEN) - 1) << HBN_RC32K_CAL_INPROGRESS_POS) +#define HBN_RC32K_CAL_INPROGRESS_UMSK (~(((1U << HBN_RC32K_CAL_INPROGRESS_LEN) - 1) << HBN_RC32K_CAL_INPROGRESS_POS)) +#define HBN_RC32K_CAL_DIV HBN_RC32K_CAL_DIV +#define HBN_RC32K_CAL_DIV_POS (3U) +#define HBN_RC32K_CAL_DIV_LEN (2U) +#define HBN_RC32K_CAL_DIV_MSK (((1U << HBN_RC32K_CAL_DIV_LEN) - 1) << HBN_RC32K_CAL_DIV_POS) +#define HBN_RC32K_CAL_DIV_UMSK (~(((1U << HBN_RC32K_CAL_DIV_LEN) - 1) << HBN_RC32K_CAL_DIV_POS)) +#define HBN_RC32K_CAL_PRECHARGE HBN_RC32K_CAL_PRECHARGE +#define HBN_RC32K_CAL_PRECHARGE_POS (5U) +#define HBN_RC32K_CAL_PRECHARGE_LEN (1U) +#define HBN_RC32K_CAL_PRECHARGE_MSK (((1U << HBN_RC32K_CAL_PRECHARGE_LEN) - 1) << HBN_RC32K_CAL_PRECHARGE_POS) +#define HBN_RC32K_CAL_PRECHARGE_UMSK (~(((1U << HBN_RC32K_CAL_PRECHARGE_LEN) - 1) << HBN_RC32K_CAL_PRECHARGE_POS)) +#define HBN_RC32K_DIG_CODE_FR_CAL HBN_RC32K_DIG_CODE_FR_CAL +#define HBN_RC32K_DIG_CODE_FR_CAL_POS (6U) +#define HBN_RC32K_DIG_CODE_FR_CAL_LEN (10U) +#define HBN_RC32K_DIG_CODE_FR_CAL_MSK (((1U << HBN_RC32K_DIG_CODE_FR_CAL_LEN) - 1) << HBN_RC32K_DIG_CODE_FR_CAL_POS) +#define HBN_RC32K_DIG_CODE_FR_CAL_UMSK (~(((1U << HBN_RC32K_DIG_CODE_FR_CAL_LEN) - 1) << HBN_RC32K_DIG_CODE_FR_CAL_POS)) +#define HBN_RC32K_VREF_DLY HBN_RC32K_VREF_DLY +#define HBN_RC32K_VREF_DLY_POS (16U) +#define HBN_RC32K_VREF_DLY_LEN (2U) +#define HBN_RC32K_VREF_DLY_MSK (((1U << HBN_RC32K_VREF_DLY_LEN) - 1) << HBN_RC32K_VREF_DLY_POS) +#define HBN_RC32K_VREF_DLY_UMSK (~(((1U << HBN_RC32K_VREF_DLY_LEN) - 1) << HBN_RC32K_VREF_DLY_POS)) +#define HBN_RC32K_ALLOW_CAL HBN_RC32K_ALLOW_CAL +#define HBN_RC32K_ALLOW_CAL_POS (18U) +#define HBN_RC32K_ALLOW_CAL_LEN (1U) +#define HBN_RC32K_ALLOW_CAL_MSK (((1U << HBN_RC32K_ALLOW_CAL_LEN) - 1) << HBN_RC32K_ALLOW_CAL_POS) +#define HBN_RC32K_ALLOW_CAL_UMSK (~(((1U << HBN_RC32K_ALLOW_CAL_LEN) - 1) << HBN_RC32K_ALLOW_CAL_POS)) +#define HBN_RC32K_EXT_CODE_EN HBN_RC32K_EXT_CODE_EN +#define HBN_RC32K_EXT_CODE_EN_POS (19U) +#define HBN_RC32K_EXT_CODE_EN_LEN (1U) +#define HBN_RC32K_EXT_CODE_EN_MSK (((1U << HBN_RC32K_EXT_CODE_EN_LEN) - 1) << HBN_RC32K_EXT_CODE_EN_POS) +#define HBN_RC32K_EXT_CODE_EN_UMSK (~(((1U << HBN_RC32K_EXT_CODE_EN_LEN) - 1) << HBN_RC32K_EXT_CODE_EN_POS)) +#define HBN_RC32K_CAL_EN HBN_RC32K_CAL_EN +#define HBN_RC32K_CAL_EN_POS (20U) +#define HBN_RC32K_CAL_EN_LEN (1U) +#define HBN_RC32K_CAL_EN_MSK (((1U << HBN_RC32K_CAL_EN_LEN) - 1) << HBN_RC32K_CAL_EN_POS) +#define HBN_RC32K_CAL_EN_UMSK (~(((1U << HBN_RC32K_CAL_EN_LEN) - 1) << HBN_RC32K_CAL_EN_POS)) +#define HBN_PU_RC32K HBN_PU_RC32K +#define HBN_PU_RC32K_POS (21U) +#define HBN_PU_RC32K_LEN (1U) +#define HBN_PU_RC32K_MSK (((1U << HBN_PU_RC32K_LEN) - 1) << HBN_PU_RC32K_POS) +#define HBN_PU_RC32K_UMSK (~(((1U << HBN_PU_RC32K_LEN) - 1) << HBN_PU_RC32K_POS)) +#define HBN_RC32K_CODE_FR_EXT HBN_RC32K_CODE_FR_EXT +#define HBN_RC32K_CODE_FR_EXT_POS (22U) +#define HBN_RC32K_CODE_FR_EXT_LEN (10U) +#define HBN_RC32K_CODE_FR_EXT_MSK (((1U << HBN_RC32K_CODE_FR_EXT_LEN) - 1) << HBN_RC32K_CODE_FR_EXT_POS) +#define HBN_RC32K_CODE_FR_EXT_UMSK (~(((1U << HBN_RC32K_CODE_FR_EXT_LEN) - 1) << HBN_RC32K_CODE_FR_EXT_POS)) + +/* 0x204 : xtal32k */ +#define HBN_XTAL32K_OFFSET (0x204) +#define HBN_XTAL32K_EXT_SEL HBN_XTAL32K_EXT_SEL +#define HBN_XTAL32K_EXT_SEL_POS (2U) +#define HBN_XTAL32K_EXT_SEL_LEN (1U) +#define HBN_XTAL32K_EXT_SEL_MSK (((1U << HBN_XTAL32K_EXT_SEL_LEN) - 1) << HBN_XTAL32K_EXT_SEL_POS) +#define HBN_XTAL32K_EXT_SEL_UMSK (~(((1U << HBN_XTAL32K_EXT_SEL_LEN) - 1) << HBN_XTAL32K_EXT_SEL_POS)) +#define HBN_XTAL32K_AMP_CTRL HBN_XTAL32K_AMP_CTRL +#define HBN_XTAL32K_AMP_CTRL_POS (3U) +#define HBN_XTAL32K_AMP_CTRL_LEN (2U) +#define HBN_XTAL32K_AMP_CTRL_MSK (((1U << HBN_XTAL32K_AMP_CTRL_LEN) - 1) << HBN_XTAL32K_AMP_CTRL_POS) +#define HBN_XTAL32K_AMP_CTRL_UMSK (~(((1U << HBN_XTAL32K_AMP_CTRL_LEN) - 1) << HBN_XTAL32K_AMP_CTRL_POS)) +#define HBN_XTAL32K_REG HBN_XTAL32K_REG +#define HBN_XTAL32K_REG_POS (5U) +#define HBN_XTAL32K_REG_LEN (2U) +#define HBN_XTAL32K_REG_MSK (((1U << HBN_XTAL32K_REG_LEN) - 1) << HBN_XTAL32K_REG_POS) +#define HBN_XTAL32K_REG_UMSK (~(((1U << HBN_XTAL32K_REG_LEN) - 1) << HBN_XTAL32K_REG_POS)) +#define HBN_XTAL32K_OUTBUF_STRE HBN_XTAL32K_OUTBUF_STRE +#define HBN_XTAL32K_OUTBUF_STRE_POS (7U) +#define HBN_XTAL32K_OUTBUF_STRE_LEN (1U) +#define HBN_XTAL32K_OUTBUF_STRE_MSK (((1U << HBN_XTAL32K_OUTBUF_STRE_LEN) - 1) << HBN_XTAL32K_OUTBUF_STRE_POS) +#define HBN_XTAL32K_OUTBUF_STRE_UMSK (~(((1U << HBN_XTAL32K_OUTBUF_STRE_LEN) - 1) << HBN_XTAL32K_OUTBUF_STRE_POS)) +#define HBN_XTAL32K_OTF_SHORT HBN_XTAL32K_OTF_SHORT +#define HBN_XTAL32K_OTF_SHORT_POS (8U) +#define HBN_XTAL32K_OTF_SHORT_LEN (1U) +#define HBN_XTAL32K_OTF_SHORT_MSK (((1U << HBN_XTAL32K_OTF_SHORT_LEN) - 1) << HBN_XTAL32K_OTF_SHORT_POS) +#define HBN_XTAL32K_OTF_SHORT_UMSK (~(((1U << HBN_XTAL32K_OTF_SHORT_LEN) - 1) << HBN_XTAL32K_OTF_SHORT_POS)) +#define HBN_XTAL32K_INV_STRE HBN_XTAL32K_INV_STRE +#define HBN_XTAL32K_INV_STRE_POS (9U) +#define HBN_XTAL32K_INV_STRE_LEN (2U) +#define HBN_XTAL32K_INV_STRE_MSK (((1U << HBN_XTAL32K_INV_STRE_LEN) - 1) << HBN_XTAL32K_INV_STRE_POS) +#define HBN_XTAL32K_INV_STRE_UMSK (~(((1U << HBN_XTAL32K_INV_STRE_LEN) - 1) << HBN_XTAL32K_INV_STRE_POS)) +#define HBN_XTAL32K_CAPBANK HBN_XTAL32K_CAPBANK +#define HBN_XTAL32K_CAPBANK_POS (11U) +#define HBN_XTAL32K_CAPBANK_LEN (6U) +#define HBN_XTAL32K_CAPBANK_MSK (((1U << HBN_XTAL32K_CAPBANK_LEN) - 1) << HBN_XTAL32K_CAPBANK_POS) +#define HBN_XTAL32K_CAPBANK_UMSK (~(((1U << HBN_XTAL32K_CAPBANK_LEN) - 1) << HBN_XTAL32K_CAPBANK_POS)) +#define HBN_XTAL32K_AC_CAP_SHORT HBN_XTAL32K_AC_CAP_SHORT +#define HBN_XTAL32K_AC_CAP_SHORT_POS (17U) +#define HBN_XTAL32K_AC_CAP_SHORT_LEN (1U) +#define HBN_XTAL32K_AC_CAP_SHORT_MSK (((1U << HBN_XTAL32K_AC_CAP_SHORT_LEN) - 1) << HBN_XTAL32K_AC_CAP_SHORT_POS) +#define HBN_XTAL32K_AC_CAP_SHORT_UMSK (~(((1U << HBN_XTAL32K_AC_CAP_SHORT_LEN) - 1) << HBN_XTAL32K_AC_CAP_SHORT_POS)) +#define HBN_PU_XTAL32K_BUF HBN_PU_XTAL32K_BUF +#define HBN_PU_XTAL32K_BUF_POS (18U) +#define HBN_PU_XTAL32K_BUF_LEN (1U) +#define HBN_PU_XTAL32K_BUF_MSK (((1U << HBN_PU_XTAL32K_BUF_LEN) - 1) << HBN_PU_XTAL32K_BUF_POS) +#define HBN_PU_XTAL32K_BUF_UMSK (~(((1U << HBN_PU_XTAL32K_BUF_LEN) - 1) << HBN_PU_XTAL32K_BUF_POS)) +#define HBN_PU_XTAL32K HBN_PU_XTAL32K +#define HBN_PU_XTAL32K_POS (19U) +#define HBN_PU_XTAL32K_LEN (1U) +#define HBN_PU_XTAL32K_MSK (((1U << HBN_PU_XTAL32K_LEN) - 1) << HBN_PU_XTAL32K_POS) +#define HBN_PU_XTAL32K_UMSK (~(((1U << HBN_PU_XTAL32K_LEN) - 1) << HBN_PU_XTAL32K_POS)) +#define HBN_XTAL32K_HIZ_EN HBN_XTAL32K_HIZ_EN +#define HBN_XTAL32K_HIZ_EN_POS (20U) +#define HBN_XTAL32K_HIZ_EN_LEN (1U) +#define HBN_XTAL32K_HIZ_EN_MSK (((1U << HBN_XTAL32K_HIZ_EN_LEN) - 1) << HBN_XTAL32K_HIZ_EN_POS) +#define HBN_XTAL32K_HIZ_EN_UMSK (~(((1U << HBN_XTAL32K_HIZ_EN_LEN) - 1) << HBN_XTAL32K_HIZ_EN_POS)) +#define HBN_DTEN_XTAL32K HBN_DTEN_XTAL32K +#define HBN_DTEN_XTAL32K_POS (22U) +#define HBN_DTEN_XTAL32K_LEN (1U) +#define HBN_DTEN_XTAL32K_MSK (((1U << HBN_DTEN_XTAL32K_LEN) - 1) << HBN_DTEN_XTAL32K_POS) +#define HBN_DTEN_XTAL32K_UMSK (~(((1U << HBN_DTEN_XTAL32K_LEN) - 1) << HBN_DTEN_XTAL32K_POS)) +#define HBN_TEN_XTAL32K HBN_TEN_XTAL32K +#define HBN_TEN_XTAL32K_POS (23U) +#define HBN_TEN_XTAL32K_LEN (1U) +#define HBN_TEN_XTAL32K_MSK (((1U << HBN_TEN_XTAL32K_LEN) - 1) << HBN_TEN_XTAL32K_POS) +#define HBN_TEN_XTAL32K_UMSK (~(((1U << HBN_TEN_XTAL32K_LEN) - 1) << HBN_TEN_XTAL32K_POS)) +#define HBN_F32K_SEL_RTC HBN_F32K_SEL_RTC +#define HBN_F32K_SEL_RTC_POS (24U) +#define HBN_F32K_SEL_RTC_LEN (1U) +#define HBN_F32K_SEL_RTC_MSK (((1U << HBN_F32K_SEL_RTC_LEN) - 1) << HBN_F32K_SEL_RTC_POS) +#define HBN_F32K_SEL_RTC_UMSK (~(((1U << HBN_F32K_SEL_RTC_LEN) - 1) << HBN_F32K_SEL_RTC_POS)) + +/* 0x208 : rtc_rst_ctrl */ +#define HBN_RTC_RST_CTRL_OFFSET (0x208) +#define HBN_RTC_RST_WAIT_CNT_RTC HBN_RTC_RST_WAIT_CNT_RTC +#define HBN_RTC_RST_WAIT_CNT_RTC_POS (0U) +#define HBN_RTC_RST_WAIT_CNT_RTC_LEN (16U) +#define HBN_RTC_RST_WAIT_CNT_RTC_MSK (((1U << HBN_RTC_RST_WAIT_CNT_RTC_LEN) - 1) << HBN_RTC_RST_WAIT_CNT_RTC_POS) +#define HBN_RTC_RST_WAIT_CNT_RTC_UMSK (~(((1U << HBN_RTC_RST_WAIT_CNT_RTC_LEN) - 1) << HBN_RTC_RST_WAIT_CNT_RTC_POS)) +#define HBN_RTC_RST_REFDIV_RTC HBN_RTC_RST_REFDIV_RTC +#define HBN_RTC_RST_REFDIV_RTC_POS (16U) +#define HBN_RTC_RST_REFDIV_RTC_LEN (3U) +#define HBN_RTC_RST_REFDIV_RTC_MSK (((1U << HBN_RTC_RST_REFDIV_RTC_LEN) - 1) << HBN_RTC_RST_REFDIV_RTC_POS) +#define HBN_RTC_RST_REFDIV_RTC_UMSK (~(((1U << HBN_RTC_RST_REFDIV_RTC_LEN) - 1) << HBN_RTC_RST_REFDIV_RTC_POS)) +#define HBN_RTC_RST_CTRL_MISC HBN_RTC_RST_CTRL_MISC +#define HBN_RTC_RST_CTRL_MISC_POS (19U) +#define HBN_RTC_RST_CTRL_MISC_LEN (13U) +#define HBN_RTC_RST_CTRL_MISC_MSK (((1U << HBN_RTC_RST_CTRL_MISC_LEN) - 1) << HBN_RTC_RST_CTRL_MISC_POS) +#define HBN_RTC_RST_CTRL_MISC_UMSK (~(((1U << HBN_RTC_RST_CTRL_MISC_LEN) - 1) << HBN_RTC_RST_CTRL_MISC_POS)) + +/* 0x20C : rtc_rst_ctrl2 */ +#define HBN_RTC_RST_CTRL2_OFFSET (0x20C) +#define HBN_RTC_RESV HBN_RTC_RESV +#define HBN_RTC_RESV_POS (0U) +#define HBN_RTC_RESV_LEN (8U) +#define HBN_RTC_RESV_MSK (((1U << HBN_RTC_RESV_LEN) - 1) << HBN_RTC_RESV_POS) +#define HBN_RTC_RESV_UMSK (~(((1U << HBN_RTC_RESV_LEN) - 1) << HBN_RTC_RESV_POS)) +#define HBN_REG_EN_HW_PU_RC32K HBN_REG_EN_HW_PU_RC32K +#define HBN_REG_EN_HW_PU_RC32K_POS (8U) +#define HBN_REG_EN_HW_PU_RC32K_LEN (1U) +#define HBN_REG_EN_HW_PU_RC32K_MSK (((1U << HBN_REG_EN_HW_PU_RC32K_LEN) - 1) << HBN_REG_EN_HW_PU_RC32K_POS) +#define HBN_REG_EN_HW_PU_RC32K_UMSK (~(((1U << HBN_REG_EN_HW_PU_RC32K_LEN) - 1) << HBN_REG_EN_HW_PU_RC32K_POS)) + +struct hbn_reg { + /* 0x0 : HBN_CTL */ + union { + struct { + uint32_t rtc_ctl : 4; /* [ 3: 0], r/w, 0x0 */ + uint32_t rtc_dly_option : 1; /* [ 4], r/w, 0x0 */ + uint32_t pu_ldo18io_aon : 1; /* [ 5], r/w, 0x1 */ + uint32_t reserved_6 : 1; /* [ 6], rsvd, 0x0 */ + uint32_t hbn_mode : 1; /* [ 7], w, 0x0 */ + uint32_t trap_mode : 1; /* [ 8], r, 0x0 */ + uint32_t pwrdn_hbn_core : 1; /* [ 9], r/w, 0x0 */ + uint32_t reserved_10_11 : 2; /* [11:10], rsvd, 0x0 */ + uint32_t sw_rst : 1; /* [ 12], r/w, 0x0 */ + uint32_t hbn_dis_pwr_off_ldo11 : 1; /* [ 13], r/w, 0x0 */ + uint32_t hbn_dis_pwr_off_ldo11_rt : 1; /* [ 14], r/w, 0x0 */ + uint32_t hbn_ldo11_rt_vout_sel : 4; /* [18:15], r/w, 0xa */ + uint32_t hbn_ldo11_aon_vout_sel : 4; /* [22:19], r/w, 0xa */ + uint32_t pu_dcdc_aon : 1; /* [ 23], r/w, 0x1 */ + uint32_t pu_dcdc18_aon : 1; /* [ 24], r/w, 0x1 */ + uint32_t pwr_on_option : 1; /* [ 25], r/w, 0x0 */ + uint32_t sram_slp_option : 1; /* [ 26], r/w, 0x0 */ + uint32_t sram_slp : 1; /* [ 27], r, 0x0 */ + uint32_t hbn_state : 4; /* [31:28], r, 0x0 */ + } BF; + uint32_t WORD; + } HBN_CTL; + + /* 0x4 : HBN_TIME_L */ + union { + struct { + uint32_t hbn_time_l : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } HBN_TIME_L; + + /* 0x8 : HBN_TIME_H */ + union { + struct { + uint32_t hbn_time_h : 8; /* [ 7: 0], r/w, 0x0 */ + uint32_t reserved_8_31 : 24; /* [31: 8], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } HBN_TIME_H; + + /* 0xC : RTC_TIME_L */ + union { + struct { + uint32_t rtc_time_latch_l : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } RTC_TIME_L; + + /* 0x10 : RTC_TIME_H */ + union { + struct { + uint32_t rtc_time_latch_h : 8; /* [ 7: 0], r, 0x0 */ + uint32_t reserved_8_30 : 23; /* [30: 8], rsvd, 0x0 */ + uint32_t rtc_time_latch : 1; /* [ 31], w, 0x0 */ + } BF; + uint32_t WORD; + } RTC_TIME_H; + + /* 0x14 : HBN_IRQ_MODE */ + union { + struct { + uint32_t hbn_pin_wakeup_mode : 4; /* [ 3: 0], r/w, 0x5 */ + uint32_t hbn_pin_wakeup_mask : 9; /* [12: 4], r/w, 0x0 */ + uint32_t reserved_13_15 : 3; /* [15:13], rsvd, 0x0 */ + uint32_t reg_en_hw_pu_pd : 1; /* [ 16], r/w, 0x1 */ + uint32_t reserved_17 : 1; /* [ 17], rsvd, 0x0 */ + uint32_t irq_bor_en : 1; /* [ 18], r/w, 0x0 */ + uint32_t reserved_19 : 1; /* [ 19], rsvd, 0x0 */ + uint32_t irq_acomp0_en : 2; /* [21:20], r/w, 0x0 */ + uint32_t irq_acomp1_en : 2; /* [23:22], r/w, 0x0 */ + uint32_t pin_wakeup_sel : 3; /* [26:24], r/w, 0x3 */ + uint32_t pin_wakeup_en : 1; /* [ 27], r/w, 0x0 */ + uint32_t reserved_28_31 : 4; /* [31:28], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } HBN_IRQ_MODE; + + /* 0x18 : HBN_IRQ_STAT */ + union { + struct { + uint32_t irq_stat : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } HBN_IRQ_STAT; + + /* 0x1C : HBN_IRQ_CLR */ + union { + struct { + uint32_t irq_clr : 32; /* [31: 0], w, 0x0 */ + } BF; + uint32_t WORD; + } HBN_IRQ_CLR; + + /* 0x20 : HBN_PIR_CFG */ + union { + struct { + uint32_t pir_hpf_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t pir_lpf_sel : 1; /* [ 2], r/w, 0x0 */ + uint32_t reserved_3 : 1; /* [ 3], rsvd, 0x0 */ + uint32_t pir_dis : 2; /* [ 5: 4], r/w, 0x0 */ + uint32_t reserved_6 : 1; /* [ 6], rsvd, 0x0 */ + uint32_t pir_en : 1; /* [ 7], r/w, 0x0 */ + uint32_t gpadc_cs : 1; /* [ 8], r/w, 0x0 */ + uint32_t reserved_9_31 : 23; /* [31: 9], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } HBN_PIR_CFG; + + /* 0x24 : HBN_PIR_VTH */ + union { + struct { + uint32_t pir_vth : 14; /* [13: 0], r/w, 0x3ff */ + uint32_t reserved_14_31 : 18; /* [31:14], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } HBN_PIR_VTH; + + /* 0x28 : HBN_PIR_INTERVAL */ + union { + struct { + uint32_t pir_interval : 12; /* [11: 0], r/w, 0xa3d */ + uint32_t reserved_12_31 : 20; /* [31:12], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } HBN_PIR_INTERVAL; + + /* 0x2C : HBN_BOR_CFG */ + union { + struct { + uint32_t bod_sel : 1; /* [ 0], r/w, 0x0 */ + uint32_t bod_vth : 3; /* [ 3: 1], r/w, 0x5 */ + uint32_t pu_bod : 1; /* [ 4], r/w, 0x0 */ + uint32_t r_bod_out : 1; /* [ 5], r, 0x0 */ + uint32_t reserved_6_31 : 26; /* [31: 6], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } HBN_BOR_CFG; + + /* 0x30 : HBN_GLB */ + union { + struct { + uint32_t hbn_root_clk_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t hbn_uart_clk_sel : 1; /* [ 2], r/w, 0x0 */ + uint32_t hbn_f32k_sel : 2; /* [ 4: 3], r/w, 0x0 */ + uint32_t reserved_5_6 : 2; /* [ 6: 5], rsvd, 0x0 */ + uint32_t hbn_reset_event : 6; /* [12: 7], r, 0x0 */ + uint32_t hbn_clr_reset_event : 1; /* [ 13], r/w, 0x0 */ + uint32_t reserved_14 : 1; /* [ 14], rsvd, 0x0 */ + uint32_t hbn_uart_clk_sel2 : 1; /* [ 15], r/w, 0x0 */ + uint32_t sw_ldo11soc_vout_sel_aon : 4; /* [19:16], r/w, 0xa */ + uint32_t reserved_20_23 : 4; /* [23:20], rsvd, 0x0 */ + uint32_t sw_ldo11_rt_vout_sel : 4; /* [27:24], r/w, 0xa */ + uint32_t sw_ldo11_aon_vout_sel : 4; /* [31:28], r/w, 0xa */ + } BF; + uint32_t WORD; + } HBN_GLB; + + /* 0x34 : HBN_SRAM */ + union { + struct { + uint32_t reserved_0_5 : 6; /* [ 5: 0], rsvd, 0x0 */ + uint32_t retram_ret : 1; /* [ 6], r/w, 0x0 */ + uint32_t retram_slp : 1; /* [ 7], r/w, 0x0 */ + uint32_t reserved_8_31 : 24; /* [31: 8], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } HBN_SRAM; + + /* 0x38 : HBN_PAD_CTRL_0 */ + union { + struct { + uint32_t reg_aon_pad_ie_smt : 9; /* [ 8: 0], r/w, 0x0 */ + uint32_t reserved_9 : 1; /* [ 9], rsvd, 0x0 */ + uint32_t reg_aon_led_sel : 9; /* [18:10], r/w, 0x0 */ + uint32_t reserved_19 : 1; /* [ 19], rsvd, 0x0 */ + uint32_t reg_en_aon_ctrl_gpio : 9; /* [28:20], r/w, 0x180 */ + uint32_t reserved_29_30 : 2; /* [30:29], rsvd, 0x0 */ + uint32_t reg_aon_gpio_iso_mode : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } HBN_PAD_CTRL_0; + + /* 0x3C : HBN_PAD_CTRL_1 */ + union { + struct { + uint32_t reg_aon_pad_oe : 9; /* [ 8: 0], r/w, 0x0 */ + uint32_t reserved_9 : 1; /* [ 9], rsvd, 0x0 */ + uint32_t reg_aon_pad_pd : 9; /* [18:10], r/w, 0x0 */ + uint32_t reserved_19 : 1; /* [ 19], rsvd, 0x0 */ + uint32_t reg_aon_pad_pu : 9; /* [28:20], r/w, 0x0 */ + uint32_t reserved_29_31 : 3; /* [31:29], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } HBN_PAD_CTRL_1; + + /* 0x40 reserved */ + uint8_t RESERVED0x40[192]; + + /* 0x100 : HBN_RSV0 */ + union { + struct { + uint32_t HBN_RSV0 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } HBN_RSV0; + + /* 0x104 : HBN_RSV1 */ + union { + struct { + uint32_t HBN_RSV1 : 32; /* [31: 0], r/w, 0xffffffff */ + } BF; + uint32_t WORD; + } HBN_RSV1; + + /* 0x108 : HBN_RSV2 */ + union { + struct { + uint32_t HBN_RSV2 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } HBN_RSV2; + + /* 0x10C : HBN_RSV3 */ + union { + struct { + uint32_t HBN_RSV3 : 32; /* [31: 0], r/w, 0xffffffff */ + } BF; + uint32_t WORD; + } HBN_RSV3; + + /* 0x110 reserved */ + uint8_t RESERVED0x110[240]; + + /* 0x200 : rc32k_ctrl0 */ + union { + struct { + uint32_t rc32k_cal_done : 1; /* [ 0], r, 0x1 */ + uint32_t rc32k_rdy : 1; /* [ 1], r, 0x1 */ + uint32_t rc32k_cal_inprogress : 1; /* [ 2], r, 0x0 */ + uint32_t rc32k_cal_div : 2; /* [ 4: 3], r/w, 0x3 */ + uint32_t rc32k_cal_precharge : 1; /* [ 5], r, 0x0 */ + uint32_t rc32k_dig_code_fr_cal : 10; /* [15: 6], r, 0x200 */ + uint32_t rc32k_vref_dly : 2; /* [17:16], r/w, 0x0 */ + uint32_t rc32k_allow_cal : 1; /* [ 18], r/w, 0x0 */ + uint32_t rc32k_ext_code_en : 1; /* [ 19], r/w, 0x1 */ + uint32_t rc32k_cal_en : 1; /* [ 20], r/w, 0x0 */ + uint32_t pu_rc32k : 1; /* [ 21], r/w, 0x1 */ + uint32_t rc32k_code_fr_ext : 10; /* [31:22], r/w, 0x12c */ + } BF; + uint32_t WORD; + } rc32k_ctrl0; + + /* 0x204 : xtal32k */ + union { + struct { + uint32_t reserved_0_1 : 2; /* [ 1: 0], rsvd, 0x0 */ + uint32_t xtal32k_ext_sel : 1; /* [ 2], r/w, 0x0 */ + uint32_t xtal32k_amp_ctrl : 2; /* [ 4: 3], r/w, 0x1 */ + uint32_t xtal32k_reg : 2; /* [ 6: 5], r/w, 0x1 */ + uint32_t xtal32k_outbuf_stre : 1; /* [ 7], r/w, 0x0 */ + uint32_t xtal32k_otf_short : 1; /* [ 8], r/w, 0x0 */ + uint32_t xtal32k_inv_stre : 2; /* [10: 9], r/w, 0x1 */ + uint32_t xtal32k_capbank : 6; /* [16:11], r/w, 0x20 */ + uint32_t xtal32k_ac_cap_short : 1; /* [ 17], r/w, 0x0 */ + uint32_t pu_xtal32k_buf : 1; /* [ 18], r/w, 0x1 */ + uint32_t pu_xtal32k : 1; /* [ 19], r/w, 0x0 */ + uint32_t xtal32k_hiz_en : 1; /* [ 20], r/w, 0x1 */ + uint32_t reserved_21 : 1; /* [ 21], rsvd, 0x0 */ + uint32_t dten_xtal32k : 1; /* [ 22], r/w, 0x0 */ + uint32_t ten_xtal32k : 1; /* [ 23], r/w, 0x0 */ + uint32_t f32k_sel_rtc : 1; /* [ 24], r/w, 0x0 */ + uint32_t reserved_25_31 : 7; /* [31:25], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } xtal32k; + + /* 0x208 : rtc_rst_ctrl */ + union { + struct { + uint32_t rtc_rst_wait_cnt_rtc : 16; /* [15: 0], r/w, 0x3c00 */ + uint32_t rtc_rst_refdiv_rtc : 3; /* [18:16], r/w, 0x4 */ + uint32_t rtc_rst_ctrl_misc : 13; /* [31:19], r/w, 0xa12 */ + } BF; + uint32_t WORD; + } rtc_rst_ctrl; + + /* 0x20C : rtc_rst_ctrl2 */ + union { + struct { + uint32_t rtc_resv : 8; /* [ 7: 0], r/w, 0x0 */ + uint32_t reg_en_hw_pu_rc32k : 1; /* [ 8], r/w, 0x0 */ + uint32_t reserved_9_31 : 23; /* [31: 9], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } rtc_rst_ctrl2; +}; + +typedef volatile struct hbn_reg hbn_reg_t; + +#endif /* __HBN_REG_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/mcu_misc_reg.h b/platforms/bl808_m0/vendor/psram/include/mcu_misc_reg.h new file mode 100644 index 0000000..bb835d4 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/mcu_misc_reg.h @@ -0,0 +1,352 @@ +/** + ****************************************************************************** + * @file mcu_misc_reg.h + * @version V1.0 + * @date 2021-07-12 + * @brief This file is the description of.IP register + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __MCU_MISC_REG_H__ +#define __MCU_MISC_REG_H__ + +#include "bl808.h" + +/* 0x0 : mcu_bus_cfg0 */ +#define MCU_MISC_MCU_BUS_CFG0_OFFSET (0x0) +#define MCU_MISC_REG_MCU_INFRA_TIMEOUT_EN MCU_MISC_REG_MCU_INFRA_TIMEOUT_EN +#define MCU_MISC_REG_MCU_INFRA_TIMEOUT_EN_POS (0U) +#define MCU_MISC_REG_MCU_INFRA_TIMEOUT_EN_LEN (1U) +#define MCU_MISC_REG_MCU_INFRA_TIMEOUT_EN_MSK (((1U << MCU_MISC_REG_MCU_INFRA_TIMEOUT_EN_LEN) - 1) << MCU_MISC_REG_MCU_INFRA_TIMEOUT_EN_POS) +#define MCU_MISC_REG_MCU_INFRA_TIMEOUT_EN_UMSK (~(((1U << MCU_MISC_REG_MCU_INFRA_TIMEOUT_EN_LEN) - 1) << MCU_MISC_REG_MCU_INFRA_TIMEOUT_EN_POS)) +#define MCU_MISC_REG_MCU_INFRA_TIMEOUT_CLR MCU_MISC_REG_MCU_INFRA_TIMEOUT_CLR +#define MCU_MISC_REG_MCU_INFRA_TIMEOUT_CLR_POS (1U) +#define MCU_MISC_REG_MCU_INFRA_TIMEOUT_CLR_LEN (1U) +#define MCU_MISC_REG_MCU_INFRA_TIMEOUT_CLR_MSK (((1U << MCU_MISC_REG_MCU_INFRA_TIMEOUT_CLR_LEN) - 1) << MCU_MISC_REG_MCU_INFRA_TIMEOUT_CLR_POS) +#define MCU_MISC_REG_MCU_INFRA_TIMEOUT_CLR_UMSK (~(((1U << MCU_MISC_REG_MCU_INFRA_TIMEOUT_CLR_LEN) - 1) << MCU_MISC_REG_MCU_INFRA_TIMEOUT_CLR_POS)) +#define MCU_MISC_STS_MCU_INFRA_TIMEOUT MCU_MISC_STS_MCU_INFRA_TIMEOUT +#define MCU_MISC_STS_MCU_INFRA_TIMEOUT_POS (16U) +#define MCU_MISC_STS_MCU_INFRA_TIMEOUT_LEN (1U) +#define MCU_MISC_STS_MCU_INFRA_TIMEOUT_MSK (((1U << MCU_MISC_STS_MCU_INFRA_TIMEOUT_LEN) - 1) << MCU_MISC_STS_MCU_INFRA_TIMEOUT_POS) +#define MCU_MISC_STS_MCU_INFRA_TIMEOUT_UMSK (~(((1U << MCU_MISC_STS_MCU_INFRA_TIMEOUT_LEN) - 1) << MCU_MISC_STS_MCU_INFRA_TIMEOUT_POS)) + +/* 0x4 : mcu_bus_cfg1 */ +#define MCU_MISC_MCU_BUS_CFG1_OFFSET (0x4) +#define MCU_MISC_REG_MCU1_HQOS MCU_MISC_REG_MCU1_HQOS +#define MCU_MISC_REG_MCU1_HQOS_POS (0U) +#define MCU_MISC_REG_MCU1_HQOS_LEN (1U) +#define MCU_MISC_REG_MCU1_HQOS_MSK (((1U << MCU_MISC_REG_MCU1_HQOS_LEN) - 1) << MCU_MISC_REG_MCU1_HQOS_POS) +#define MCU_MISC_REG_MCU1_HQOS_UMSK (~(((1U << MCU_MISC_REG_MCU1_HQOS_LEN) - 1) << MCU_MISC_REG_MCU1_HQOS_POS)) +#define MCU_MISC_REG_MCU1_AWQOS MCU_MISC_REG_MCU1_AWQOS +#define MCU_MISC_REG_MCU1_AWQOS_POS (1U) +#define MCU_MISC_REG_MCU1_AWQOS_LEN (1U) +#define MCU_MISC_REG_MCU1_AWQOS_MSK (((1U << MCU_MISC_REG_MCU1_AWQOS_LEN) - 1) << MCU_MISC_REG_MCU1_AWQOS_POS) +#define MCU_MISC_REG_MCU1_AWQOS_UMSK (~(((1U << MCU_MISC_REG_MCU1_AWQOS_LEN) - 1) << MCU_MISC_REG_MCU1_AWQOS_POS)) +#define MCU_MISC_REG_MCU1_ARQOS MCU_MISC_REG_MCU1_ARQOS +#define MCU_MISC_REG_MCU1_ARQOS_POS (2U) +#define MCU_MISC_REG_MCU1_ARQOS_LEN (1U) +#define MCU_MISC_REG_MCU1_ARQOS_MSK (((1U << MCU_MISC_REG_MCU1_ARQOS_LEN) - 1) << MCU_MISC_REG_MCU1_ARQOS_POS) +#define MCU_MISC_REG_MCU1_ARQOS_UMSK (~(((1U << MCU_MISC_REG_MCU1_ARQOS_LEN) - 1) << MCU_MISC_REG_MCU1_ARQOS_POS)) +#define MCU_MISC_REG_MCU_X2HS_SP_BYPASS MCU_MISC_REG_MCU_X2HS_SP_BYPASS +#define MCU_MISC_REG_MCU_X2HS_SP_BYPASS_POS (3U) +#define MCU_MISC_REG_MCU_X2HS_SP_BYPASS_LEN (1U) +#define MCU_MISC_REG_MCU_X2HS_SP_BYPASS_MSK (((1U << MCU_MISC_REG_MCU_X2HS_SP_BYPASS_LEN) - 1) << MCU_MISC_REG_MCU_X2HS_SP_BYPASS_POS) +#define MCU_MISC_REG_MCU_X2HS_SP_BYPASS_UMSK (~(((1U << MCU_MISC_REG_MCU_X2HS_SP_BYPASS_LEN) - 1) << MCU_MISC_REG_MCU_X2HS_SP_BYPASS_POS)) +#define MCU_MISC_REG_X_WTHRE_MCU2EXT MCU_MISC_REG_X_WTHRE_MCU2EXT +#define MCU_MISC_REG_X_WTHRE_MCU2EXT_POS (7U) +#define MCU_MISC_REG_X_WTHRE_MCU2EXT_LEN (2U) +#define MCU_MISC_REG_X_WTHRE_MCU2EXT_MSK (((1U << MCU_MISC_REG_X_WTHRE_MCU2EXT_LEN) - 1) << MCU_MISC_REG_X_WTHRE_MCU2EXT_POS) +#define MCU_MISC_REG_X_WTHRE_MCU2EXT_UMSK (~(((1U << MCU_MISC_REG_X_WTHRE_MCU2EXT_LEN) - 1) << MCU_MISC_REG_X_WTHRE_MCU2EXT_POS)) +#define MCU_MISC_REG_MCU_INFRA_ARB_MODE MCU_MISC_REG_MCU_INFRA_ARB_MODE +#define MCU_MISC_REG_MCU_INFRA_ARB_MODE_POS (16U) +#define MCU_MISC_REG_MCU_INFRA_ARB_MODE_LEN (1U) +#define MCU_MISC_REG_MCU_INFRA_ARB_MODE_MSK (((1U << MCU_MISC_REG_MCU_INFRA_ARB_MODE_LEN) - 1) << MCU_MISC_REG_MCU_INFRA_ARB_MODE_POS) +#define MCU_MISC_REG_MCU_INFRA_ARB_MODE_UMSK (~(((1U << MCU_MISC_REG_MCU_INFRA_ARB_MODE_LEN) - 1) << MCU_MISC_REG_MCU_INFRA_ARB_MODE_POS)) + +/* 0x14 : mcu_e907_rtc */ +#define MCU_MISC_MCU_E907_RTC_OFFSET (0x14) +#define MCU_MISC_REG_MCU_RTC_DIV MCU_MISC_REG_MCU_RTC_DIV +#define MCU_MISC_REG_MCU_RTC_DIV_POS (0U) +#define MCU_MISC_REG_MCU_RTC_DIV_LEN (10U) +#define MCU_MISC_REG_MCU_RTC_DIV_MSK (((1U << MCU_MISC_REG_MCU_RTC_DIV_LEN) - 1) << MCU_MISC_REG_MCU_RTC_DIV_POS) +#define MCU_MISC_REG_MCU_RTC_DIV_UMSK (~(((1U << MCU_MISC_REG_MCU_RTC_DIV_LEN) - 1) << MCU_MISC_REG_MCU_RTC_DIV_POS)) +#define MCU_MISC_REG_MCU_RTC_RST MCU_MISC_REG_MCU_RTC_RST +#define MCU_MISC_REG_MCU_RTC_RST_POS (30U) +#define MCU_MISC_REG_MCU_RTC_RST_LEN (1U) +#define MCU_MISC_REG_MCU_RTC_RST_MSK (((1U << MCU_MISC_REG_MCU_RTC_RST_LEN) - 1) << MCU_MISC_REG_MCU_RTC_RST_POS) +#define MCU_MISC_REG_MCU_RTC_RST_UMSK (~(((1U << MCU_MISC_REG_MCU_RTC_RST_LEN) - 1) << MCU_MISC_REG_MCU_RTC_RST_POS)) +#define MCU_MISC_REG_MCU_RTC_EN MCU_MISC_REG_MCU_RTC_EN +#define MCU_MISC_REG_MCU_RTC_EN_POS (31U) +#define MCU_MISC_REG_MCU_RTC_EN_LEN (1U) +#define MCU_MISC_REG_MCU_RTC_EN_MSK (((1U << MCU_MISC_REG_MCU_RTC_EN_LEN) - 1) << MCU_MISC_REG_MCU_RTC_EN_POS) +#define MCU_MISC_REG_MCU_RTC_EN_UMSK (~(((1U << MCU_MISC_REG_MCU_RTC_EN_LEN) - 1) << MCU_MISC_REG_MCU_RTC_EN_POS)) + +/* 0x100 : mcu_cfg1 */ +#define MCU_MISC_MCU_CFG1_OFFSET (0x100) +#define MCU_MISC_REG_MCU1_DFS_REQ MCU_MISC_REG_MCU1_DFS_REQ +#define MCU_MISC_REG_MCU1_DFS_REQ_POS (0U) +#define MCU_MISC_REG_MCU1_DFS_REQ_LEN (1U) +#define MCU_MISC_REG_MCU1_DFS_REQ_MSK (((1U << MCU_MISC_REG_MCU1_DFS_REQ_LEN) - 1) << MCU_MISC_REG_MCU1_DFS_REQ_POS) +#define MCU_MISC_REG_MCU1_DFS_REQ_UMSK (~(((1U << MCU_MISC_REG_MCU1_DFS_REQ_LEN) - 1) << MCU_MISC_REG_MCU1_DFS_REQ_POS)) +#define MCU_MISC_STS_MCU1_DFS_ACK MCU_MISC_STS_MCU1_DFS_ACK +#define MCU_MISC_STS_MCU1_DFS_ACK_POS (2U) +#define MCU_MISC_STS_MCU1_DFS_ACK_LEN (1U) +#define MCU_MISC_STS_MCU1_DFS_ACK_MSK (((1U << MCU_MISC_STS_MCU1_DFS_ACK_LEN) - 1) << MCU_MISC_STS_MCU1_DFS_ACK_POS) +#define MCU_MISC_STS_MCU1_DFS_ACK_UMSK (~(((1U << MCU_MISC_STS_MCU1_DFS_ACK_LEN) - 1) << MCU_MISC_STS_MCU1_DFS_ACK_POS)) +#define MCU_MISC_REG_MCU1_SRST_EN MCU_MISC_REG_MCU1_SRST_EN +#define MCU_MISC_REG_MCU1_SRST_EN_POS (4U) +#define MCU_MISC_REG_MCU1_SRST_EN_LEN (2U) +#define MCU_MISC_REG_MCU1_SRST_EN_MSK (((1U << MCU_MISC_REG_MCU1_SRST_EN_LEN) - 1) << MCU_MISC_REG_MCU1_SRST_EN_POS) +#define MCU_MISC_REG_MCU1_SRST_EN_UMSK (~(((1U << MCU_MISC_REG_MCU1_SRST_EN_LEN) - 1) << MCU_MISC_REG_MCU1_SRST_EN_POS)) +#define MCU_MISC_STS_MCU1_LPMD_B MCU_MISC_STS_MCU1_LPMD_B +#define MCU_MISC_STS_MCU1_LPMD_B_POS (10U) +#define MCU_MISC_STS_MCU1_LPMD_B_LEN (2U) +#define MCU_MISC_STS_MCU1_LPMD_B_MSK (((1U << MCU_MISC_STS_MCU1_LPMD_B_LEN) - 1) << MCU_MISC_STS_MCU1_LPMD_B_POS) +#define MCU_MISC_STS_MCU1_LPMD_B_UMSK (~(((1U << MCU_MISC_STS_MCU1_LPMD_B_LEN) - 1) << MCU_MISC_STS_MCU1_LPMD_B_POS)) +#define MCU_MISC_MCU1_WFI_FORCE MCU_MISC_MCU1_WFI_FORCE +#define MCU_MISC_MCU1_WFI_FORCE_POS (16U) +#define MCU_MISC_MCU1_WFI_FORCE_LEN (1U) +#define MCU_MISC_MCU1_WFI_FORCE_MSK (((1U << MCU_MISC_MCU1_WFI_FORCE_LEN) - 1) << MCU_MISC_MCU1_WFI_FORCE_POS) +#define MCU_MISC_MCU1_WFI_FORCE_UMSK (~(((1U << MCU_MISC_MCU1_WFI_FORCE_LEN) - 1) << MCU_MISC_MCU1_WFI_FORCE_POS)) +#define MCU_MISC_MCU1_NDM_RSTN_EN MCU_MISC_MCU1_NDM_RSTN_EN +#define MCU_MISC_MCU1_NDM_RSTN_EN_POS (28U) +#define MCU_MISC_MCU1_NDM_RSTN_EN_LEN (1U) +#define MCU_MISC_MCU1_NDM_RSTN_EN_MSK (((1U << MCU_MISC_MCU1_NDM_RSTN_EN_LEN) - 1) << MCU_MISC_MCU1_NDM_RSTN_EN_POS) +#define MCU_MISC_MCU1_NDM_RSTN_EN_UMSK (~(((1U << MCU_MISC_MCU1_NDM_RSTN_EN_LEN) - 1) << MCU_MISC_MCU1_NDM_RSTN_EN_POS)) +#define MCU_MISC_MCU1_HART_RSTN_EN MCU_MISC_MCU1_HART_RSTN_EN +#define MCU_MISC_MCU1_HART_RSTN_EN_POS (29U) +#define MCU_MISC_MCU1_HART_RSTN_EN_LEN (1U) +#define MCU_MISC_MCU1_HART_RSTN_EN_MSK (((1U << MCU_MISC_MCU1_HART_RSTN_EN_LEN) - 1) << MCU_MISC_MCU1_HART_RSTN_EN_POS) +#define MCU_MISC_MCU1_HART_RSTN_EN_UMSK (~(((1U << MCU_MISC_MCU1_HART_RSTN_EN_LEN) - 1) << MCU_MISC_MCU1_HART_RSTN_EN_POS)) + +/* 0x110 : mcu1_log1 */ +#define MCU_MISC_MCU1_LOG1_OFFSET (0x110) +#define MCU_MISC_STS_MCU1_MCAUSE MCU_MISC_STS_MCU1_MCAUSE +#define MCU_MISC_STS_MCU1_MCAUSE_POS (0U) +#define MCU_MISC_STS_MCU1_MCAUSE_LEN (32U) +#define MCU_MISC_STS_MCU1_MCAUSE_MSK (((1U << MCU_MISC_STS_MCU1_MCAUSE_LEN) - 1) << MCU_MISC_STS_MCU1_MCAUSE_POS) +#define MCU_MISC_STS_MCU1_MCAUSE_UMSK (~(((1U << MCU_MISC_STS_MCU1_MCAUSE_LEN) - 1) << MCU_MISC_STS_MCU1_MCAUSE_POS)) + +/* 0x114 : mcu1_log2 */ +#define MCU_MISC_MCU1_LOG2_OFFSET (0x114) +#define MCU_MISC_STS_MCU1_MINTSTATUS MCU_MISC_STS_MCU1_MINTSTATUS +#define MCU_MISC_STS_MCU1_MINTSTATUS_POS (0U) +#define MCU_MISC_STS_MCU1_MINTSTATUS_LEN (32U) +#define MCU_MISC_STS_MCU1_MINTSTATUS_MSK (((1U << MCU_MISC_STS_MCU1_MINTSTATUS_LEN) - 1) << MCU_MISC_STS_MCU1_MINTSTATUS_POS) +#define MCU_MISC_STS_MCU1_MINTSTATUS_UMSK (~(((1U << MCU_MISC_STS_MCU1_MINTSTATUS_LEN) - 1) << MCU_MISC_STS_MCU1_MINTSTATUS_POS)) + +/* 0x118 : mcu1_log3 */ +#define MCU_MISC_MCU1_LOG3_OFFSET (0x118) +#define MCU_MISC_STS_MCU1_MSTATUS MCU_MISC_STS_MCU1_MSTATUS +#define MCU_MISC_STS_MCU1_MSTATUS_POS (0U) +#define MCU_MISC_STS_MCU1_MSTATUS_LEN (32U) +#define MCU_MISC_STS_MCU1_MSTATUS_MSK (((1U << MCU_MISC_STS_MCU1_MSTATUS_LEN) - 1) << MCU_MISC_STS_MCU1_MSTATUS_POS) +#define MCU_MISC_STS_MCU1_MSTATUS_UMSK (~(((1U << MCU_MISC_STS_MCU1_MSTATUS_LEN) - 1) << MCU_MISC_STS_MCU1_MSTATUS_POS)) + +/* 0x11C : mcu1_log4 */ +#define MCU_MISC_MCU1_LOG4_OFFSET (0x11C) +#define MCU_MISC_STS_MCU1_SP MCU_MISC_STS_MCU1_SP +#define MCU_MISC_STS_MCU1_SP_POS (0U) +#define MCU_MISC_STS_MCU1_SP_LEN (1U) +#define MCU_MISC_STS_MCU1_SP_MSK (((1U << MCU_MISC_STS_MCU1_SP_LEN) - 1) << MCU_MISC_STS_MCU1_SP_POS) +#define MCU_MISC_STS_MCU1_SP_UMSK (~(((1U << MCU_MISC_STS_MCU1_SP_LEN) - 1) << MCU_MISC_STS_MCU1_SP_POS)) +#define MCU_MISC_STS_MCU1_PC MCU_MISC_STS_MCU1_PC +#define MCU_MISC_STS_MCU1_PC_POS (1U) +#define MCU_MISC_STS_MCU1_PC_LEN (31U) +#define MCU_MISC_STS_MCU1_PC_MSK (((1U << MCU_MISC_STS_MCU1_PC_LEN) - 1) << MCU_MISC_STS_MCU1_PC_POS) +#define MCU_MISC_STS_MCU1_PC_UMSK (~(((1U << MCU_MISC_STS_MCU1_PC_LEN) - 1) << MCU_MISC_STS_MCU1_PC_POS)) + +/* 0x120 : mcu1_log5 */ +#define MCU_MISC_MCU1_LOG5_OFFSET (0x120) +#define MCU_MISC_STS_MCU1_LOCKUP MCU_MISC_STS_MCU1_LOCKUP +#define MCU_MISC_STS_MCU1_LOCKUP_POS (24U) +#define MCU_MISC_STS_MCU1_LOCKUP_LEN (1U) +#define MCU_MISC_STS_MCU1_LOCKUP_MSK (((1U << MCU_MISC_STS_MCU1_LOCKUP_LEN) - 1) << MCU_MISC_STS_MCU1_LOCKUP_POS) +#define MCU_MISC_STS_MCU1_LOCKUP_UMSK (~(((1U << MCU_MISC_STS_MCU1_LOCKUP_LEN) - 1) << MCU_MISC_STS_MCU1_LOCKUP_POS)) +#define MCU_MISC_STS_MCU1_HALTED MCU_MISC_STS_MCU1_HALTED +#define MCU_MISC_STS_MCU1_HALTED_POS (25U) +#define MCU_MISC_STS_MCU1_HALTED_LEN (1U) +#define MCU_MISC_STS_MCU1_HALTED_MSK (((1U << MCU_MISC_STS_MCU1_HALTED_LEN) - 1) << MCU_MISC_STS_MCU1_HALTED_POS) +#define MCU_MISC_STS_MCU1_HALTED_UMSK (~(((1U << MCU_MISC_STS_MCU1_HALTED_LEN) - 1) << MCU_MISC_STS_MCU1_HALTED_POS)) +#define MCU_MISC_MCU1_NDM_RSTN_REQ MCU_MISC_MCU1_NDM_RSTN_REQ +#define MCU_MISC_MCU1_NDM_RSTN_REQ_POS (28U) +#define MCU_MISC_MCU1_NDM_RSTN_REQ_LEN (1U) +#define MCU_MISC_MCU1_NDM_RSTN_REQ_MSK (((1U << MCU_MISC_MCU1_NDM_RSTN_REQ_LEN) - 1) << MCU_MISC_MCU1_NDM_RSTN_REQ_POS) +#define MCU_MISC_MCU1_NDM_RSTN_REQ_UMSK (~(((1U << MCU_MISC_MCU1_NDM_RSTN_REQ_LEN) - 1) << MCU_MISC_MCU1_NDM_RSTN_REQ_POS)) +#define MCU_MISC_MCU1_HART_RSTN_REQ MCU_MISC_MCU1_HART_RSTN_REQ +#define MCU_MISC_MCU1_HART_RSTN_REQ_POS (29U) +#define MCU_MISC_MCU1_HART_RSTN_REQ_LEN (1U) +#define MCU_MISC_MCU1_HART_RSTN_REQ_MSK (((1U << MCU_MISC_MCU1_HART_RSTN_REQ_LEN) - 1) << MCU_MISC_MCU1_HART_RSTN_REQ_POS) +#define MCU_MISC_MCU1_HART_RSTN_REQ_UMSK (~(((1U << MCU_MISC_MCU1_HART_RSTN_REQ_LEN) - 1) << MCU_MISC_MCU1_HART_RSTN_REQ_POS)) + +/* 0x208 : irom1_misr_dataout_0 */ +#define MCU_MISC_IROM1_MISR_DATAOUT_0_OFFSET (0x208) + +/* 0x20C : irom1_misr_dataout_1 */ +#define MCU_MISC_IROM1_MISR_DATAOUT_1_OFFSET (0x20C) + +struct mcu_misc_reg { + /* 0x0 : mcu_bus_cfg0 */ + union { + struct { + uint32_t reg_mcu_infra_timeout_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_mcu_infra_timeout_clr : 1; /* [ 1], r/w, 0x0 */ + uint32_t reserved_2_15 : 14; /* [15: 2], rsvd, 0x0 */ + uint32_t sts_mcu_infra_timeout : 1; /* [ 16], r, 0x0 */ + uint32_t reserved_17_31 : 15; /* [31:17], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mcu_bus_cfg0; + + /* 0x4 : mcu_bus_cfg1 */ + union { + struct { + uint32_t reg_mcu1_hqos : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_mcu1_awqos : 1; /* [ 1], r/w, 0x0 */ + uint32_t reg_mcu1_arqos : 1; /* [ 2], r/w, 0x0 */ + uint32_t reg_mcu_x2hs_sp_bypass : 1; /* [ 3], r/w, 0x0 */ + uint32_t reserved_4_6 : 3; /* [ 6: 4], rsvd, 0x0 */ + uint32_t reg_x_wthre_mcu2ext : 2; /* [ 8: 7], r/w, 0x0 */ + uint32_t reserved_9_15 : 7; /* [15: 9], rsvd, 0x0 */ + uint32_t reg_mcu_infra_arb_mode : 1; /* [ 16], r/w, 0x0 */ + uint32_t reserved_17_31 : 15; /* [31:17], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mcu_bus_cfg1; + + /* 0x8 reserved */ + uint8_t RESERVED0x8[12]; + + /* 0x14 : mcu_e907_rtc */ + union { + struct { + uint32_t reg_mcu_rtc_div : 10; /* [ 9: 0], r/w, 0xa */ + uint32_t reserved_10_29 : 20; /* [29:10], rsvd, 0x0 */ + uint32_t reg_mcu_rtc_rst : 1; /* [ 30], r/w, 0x0 */ + uint32_t reg_mcu_rtc_en : 1; /* [ 31], r/w, 0x1 */ + } BF; + uint32_t WORD; + } mcu_e907_rtc; + + /* 0x18 reserved */ + uint8_t RESERVED0x18[232]; + + /* 0x100 : mcu_cfg1 */ + union { + struct { + uint32_t reg_mcu1_dfs_req : 1; /* [ 0], r/w, 0x0 */ + uint32_t reserved_1 : 1; /* [ 1], rsvd, 0x0 */ + uint32_t sts_mcu1_dfs_ack : 1; /* [ 2], r, 0x0 */ + uint32_t reserved_3 : 1; /* [ 3], rsvd, 0x0 */ + uint32_t reg_mcu1_srst_en : 2; /* [ 5: 4], r/w, 0x3 */ + uint32_t reserved_6_9 : 4; /* [ 9: 6], rsvd, 0x0 */ + uint32_t sts_mcu1_lpmd_b : 2; /* [11:10], r, 0x0 */ + uint32_t reserved_12_15 : 4; /* [15:12], rsvd, 0x0 */ + uint32_t MCU1_WFI_FORCE : 1; /* [ 16], r/w, 0x0 */ + uint32_t reserved_17_27 : 11; /* [27:17], rsvd, 0x0 */ + uint32_t mcu1_ndm_rstn_en : 1; /* [ 28], r/w, 0x0 */ + uint32_t mcu1_hart_rstn_en : 1; /* [ 29], r/w, 0x0 */ + uint32_t reserved_30_31 : 2; /* [31:30], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mcu_cfg1; + + /* 0x104 reserved */ + uint8_t RESERVED0x104[12]; + + /* 0x110 : mcu1_log1 */ + union { + struct { + uint32_t sts_mcu1_mcause : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } mcu1_log1; + + /* 0x114 : mcu1_log2 */ + union { + struct { + uint32_t sts_mcu1_mintstatus : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } mcu1_log2; + + /* 0x118 : mcu1_log3 */ + union { + struct { + uint32_t sts_mcu1_mstatus : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } mcu1_log3; + + /* 0x11C : mcu1_log4 */ + union { + struct { + uint32_t sts_mcu1_sp : 1; /* [ 0], r, 0x0 */ + uint32_t sts_mcu1_pc : 31; /* [31: 1], r, 0x0 */ + } BF; + uint32_t WORD; + } mcu1_log4; + + /* 0x120 : mcu1_log5 */ + union { + struct { + uint32_t reserved_0_23 : 24; /* [23: 0], rsvd, 0x0 */ + uint32_t sts_mcu1_lockup : 1; /* [ 24], r, 0x0 */ + uint32_t sts_mcu1_halted : 1; /* [ 25], r, 0x0 */ + uint32_t reserved_26_27 : 2; /* [27:26], rsvd, 0x0 */ + uint32_t mcu1_ndm_rstn_req : 1; /* [ 28], r, 0x0 */ + uint32_t mcu1_hart_rstn_req : 1; /* [ 29], r, 0x0 */ + uint32_t reserved_30_31 : 2; /* [31:30], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mcu1_log5; + + /* 0x124 reserved */ + uint8_t RESERVED0x124[228]; + + /* 0x208 : irom1_misr_dataout_0 */ + union { + struct { + uint32_t reserved_0_31 : 32; /* [31: 0], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } irom1_misr_dataout_0; + + /* 0x20C : irom1_misr_dataout_1 */ + union { + struct { + uint32_t reserved_0_31 : 32; /* [31: 0], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } irom1_misr_dataout_1; +}; + +typedef volatile struct mcu_misc_reg mcu_misc_reg_t; + +#endif /* __MCU_MISC_REG_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/misc.h b/platforms/bl808_m0/vendor/psram/include/misc.h new file mode 100644 index 0000000..50ea5cd --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/misc.h @@ -0,0 +1,131 @@ +/** + * @file misc.h + * @brief + * + * Copyright (c) 2021 Bouffalolab team + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + */ +#ifndef _MISC_H +#define _MISC_H + +#include +#include +#include +#include +#include +#include +#include "compiler/gcc.h" +#include "compiler/common.h" + +#ifdef BIT +#undef BIT +#define BIT(n) (1UL << (n)) +#else +#define BIT(n) (1UL << (n)) +#endif + +/** + * @brief Null Type definition + */ +#ifndef NULL +#define NULL 0 +#endif + +/** + * @brief Error type definition + */ +typedef enum { + SUCCESS = 0, + ERROR = 1, + TIMEOUT = 2, + INVALID = 3, /* invalid arguments */ + NORESC = 4 /* no resource or resource temperary unavailable */ +} BL_Err_Type; + +/** + * @brief Functional type definition + */ +typedef enum { + DISABLE = 0, + ENABLE = 1, +} BL_Fun_Type; + +/** + * @brief Status type definition + */ +typedef enum { + RESET = 0, + SET = 1, +} BL_Sts_Type; + +/** + * @brief Mask type definition + */ +typedef enum { + UNMASK = 0, + MASK = 1 +} BL_Mask_Type; + +/** + * @brief Logical status Type definition + */ +typedef enum { + LOGIC_LO = 0, + LOGIC_HI = !LOGIC_LO +} LogicalStatus; + +/** + * @brief Active status Type definition + */ +typedef enum { + DEACTIVE = 0, + ACTIVE = !DEACTIVE +} ActiveStatus; + +/** + * @brief Interrupt callback function type + */ +typedef void(intCallback_Type)(void); +typedef void (*pFunc)(void); + +#define ARCH_MemCpy arch_memcpy +#define ARCH_MemSet arch_memset +#define ARCH_MemCmp arch_memcmp +#define ARCH_MemCpy4 arch_memcpy4 +#define ARCH_MemCpy_Fast arch_memcpy_fast +#define ARCH_MemSet4 arch_memset4 + +#ifdef DEBUG +void check_failed(uint8_t *file, uint32_t line); +#define CHECK_PARAM(expr) ((expr) ? (void)0 : check_failed((uint8_t *)__FILE__, __LINE__)) +#else +#define CHECK_PARAM(expr) ((void)0) +#endif /* DEBUG */ + +void *arch_memcpy(void *dst, const void *src, uint32_t n); +void *arch_memset(void *s, uint8_t c, uint32_t n); +int arch_memcmp(const void *s1, const void *s2, uint32_t n); +uint32_t *arch_memcpy4(uint32_t *dst, const uint32_t *src, uint32_t n); +void *arch_memcpy_fast(void *pdst, const void *psrc, uint32_t n); +uint32_t *arch_memset4(uint32_t *dst, const uint32_t val, uint32_t n); +void memcopy_to_fifo(void *fifo_addr, uint8_t *data, uint32_t length); +void fifocopy_to_mem(void *fifo_addr, uint8_t *data, uint32_t length); +int arch_ctzll(uint64_t *val, uint32_t *bit); +int arch_clzll(uint64_t *val, uint32_t *bit); +int arch_ffsll(uint64_t *val, uint32_t *bit); +#endif diff --git a/platforms/bl808_m0/vendor/psram/include/mm_glb_reg.h b/platforms/bl808_m0/vendor/psram/include/mm_glb_reg.h new file mode 100644 index 0000000..29ab241 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/mm_glb_reg.h @@ -0,0 +1,734 @@ +/** + ****************************************************************************** + * @file mm_glb_reg.h + * @version V1.0 + * @date 2021-07-12 + * @brief This file is the description of.IP register + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __MM_GLB_REG_H__ +#define __MM_GLB_REG_H__ + +#include "bl808.h" + +/* 0x0 : mm_clk_ctrl_cpu */ +#define MM_GLB_MM_CLK_CTRL_CPU_OFFSET (0x0) +#define MM_GLB_REG_PLL_EN MM_GLB_REG_PLL_EN +#define MM_GLB_REG_PLL_EN_POS (0U) +#define MM_GLB_REG_PLL_EN_LEN (1U) +#define MM_GLB_REG_PLL_EN_MSK (((1U << MM_GLB_REG_PLL_EN_LEN) - 1) << MM_GLB_REG_PLL_EN_POS) +#define MM_GLB_REG_PLL_EN_UMSK (~(((1U << MM_GLB_REG_PLL_EN_LEN) - 1) << MM_GLB_REG_PLL_EN_POS)) +#define MM_GLB_REG_CPU_CLK_EN MM_GLB_REG_CPU_CLK_EN +#define MM_GLB_REG_CPU_CLK_EN_POS (1U) +#define MM_GLB_REG_CPU_CLK_EN_LEN (1U) +#define MM_GLB_REG_CPU_CLK_EN_MSK (((1U << MM_GLB_REG_CPU_CLK_EN_LEN) - 1) << MM_GLB_REG_CPU_CLK_EN_POS) +#define MM_GLB_REG_CPU_CLK_EN_UMSK (~(((1U << MM_GLB_REG_CPU_CLK_EN_LEN) - 1) << MM_GLB_REG_CPU_CLK_EN_POS)) +#define MM_GLB_REG_BCLK_EN MM_GLB_REG_BCLK_EN +#define MM_GLB_REG_BCLK_EN_POS (2U) +#define MM_GLB_REG_BCLK_EN_LEN (1U) +#define MM_GLB_REG_BCLK_EN_MSK (((1U << MM_GLB_REG_BCLK_EN_LEN) - 1) << MM_GLB_REG_BCLK_EN_POS) +#define MM_GLB_REG_BCLK_EN_UMSK (~(((1U << MM_GLB_REG_BCLK_EN_LEN) - 1) << MM_GLB_REG_BCLK_EN_POS)) +#define MM_GLB_REG_MM_CPU_CLK_EN MM_GLB_REG_MM_CPU_CLK_EN +#define MM_GLB_REG_MM_CPU_CLK_EN_POS (3U) +#define MM_GLB_REG_MM_CPU_CLK_EN_LEN (1U) +#define MM_GLB_REG_MM_CPU_CLK_EN_MSK (((1U << MM_GLB_REG_MM_CPU_CLK_EN_LEN) - 1) << MM_GLB_REG_MM_CPU_CLK_EN_POS) +#define MM_GLB_REG_MM_CPU_CLK_EN_UMSK (~(((1U << MM_GLB_REG_MM_CPU_CLK_EN_LEN) - 1) << MM_GLB_REG_MM_CPU_CLK_EN_POS)) +#define MM_GLB_REG_UART_CLK_SEL MM_GLB_REG_UART_CLK_SEL +#define MM_GLB_REG_UART_CLK_SEL_POS (4U) +#define MM_GLB_REG_UART_CLK_SEL_LEN (2U) +#define MM_GLB_REG_UART_CLK_SEL_MSK (((1U << MM_GLB_REG_UART_CLK_SEL_LEN) - 1) << MM_GLB_REG_UART_CLK_SEL_POS) +#define MM_GLB_REG_UART_CLK_SEL_UMSK (~(((1U << MM_GLB_REG_UART_CLK_SEL_LEN) - 1) << MM_GLB_REG_UART_CLK_SEL_POS)) +#define MM_GLB_REG_I2C_CLK_SEL MM_GLB_REG_I2C_CLK_SEL +#define MM_GLB_REG_I2C_CLK_SEL_POS (6U) +#define MM_GLB_REG_I2C_CLK_SEL_LEN (1U) +#define MM_GLB_REG_I2C_CLK_SEL_MSK (((1U << MM_GLB_REG_I2C_CLK_SEL_LEN) - 1) << MM_GLB_REG_I2C_CLK_SEL_POS) +#define MM_GLB_REG_I2C_CLK_SEL_UMSK (~(((1U << MM_GLB_REG_I2C_CLK_SEL_LEN) - 1) << MM_GLB_REG_I2C_CLK_SEL_POS)) +#define MM_GLB_REG_SPI_CLK_SEL MM_GLB_REG_SPI_CLK_SEL +#define MM_GLB_REG_SPI_CLK_SEL_POS (7U) +#define MM_GLB_REG_SPI_CLK_SEL_LEN (1U) +#define MM_GLB_REG_SPI_CLK_SEL_MSK (((1U << MM_GLB_REG_SPI_CLK_SEL_LEN) - 1) << MM_GLB_REG_SPI_CLK_SEL_POS) +#define MM_GLB_REG_SPI_CLK_SEL_UMSK (~(((1U << MM_GLB_REG_SPI_CLK_SEL_LEN) - 1) << MM_GLB_REG_SPI_CLK_SEL_POS)) +#define MM_GLB_REG_CPU_CLK_SEL MM_GLB_REG_CPU_CLK_SEL +#define MM_GLB_REG_CPU_CLK_SEL_POS (8U) +#define MM_GLB_REG_CPU_CLK_SEL_LEN (2U) +#define MM_GLB_REG_CPU_CLK_SEL_MSK (((1U << MM_GLB_REG_CPU_CLK_SEL_LEN) - 1) << MM_GLB_REG_CPU_CLK_SEL_POS) +#define MM_GLB_REG_CPU_CLK_SEL_UMSK (~(((1U << MM_GLB_REG_CPU_CLK_SEL_LEN) - 1) << MM_GLB_REG_CPU_CLK_SEL_POS)) +#define MM_GLB_REG_XCLK_CLK_SEL MM_GLB_REG_XCLK_CLK_SEL +#define MM_GLB_REG_XCLK_CLK_SEL_POS (10U) +#define MM_GLB_REG_XCLK_CLK_SEL_LEN (1U) +#define MM_GLB_REG_XCLK_CLK_SEL_MSK (((1U << MM_GLB_REG_XCLK_CLK_SEL_LEN) - 1) << MM_GLB_REG_XCLK_CLK_SEL_POS) +#define MM_GLB_REG_XCLK_CLK_SEL_UMSK (~(((1U << MM_GLB_REG_XCLK_CLK_SEL_LEN) - 1) << MM_GLB_REG_XCLK_CLK_SEL_POS)) +#define MM_GLB_REG_CPU_ROOT_CLK_SEL MM_GLB_REG_CPU_ROOT_CLK_SEL +#define MM_GLB_REG_CPU_ROOT_CLK_SEL_POS (11U) +#define MM_GLB_REG_CPU_ROOT_CLK_SEL_LEN (1U) +#define MM_GLB_REG_CPU_ROOT_CLK_SEL_MSK (((1U << MM_GLB_REG_CPU_ROOT_CLK_SEL_LEN) - 1) << MM_GLB_REG_CPU_ROOT_CLK_SEL_POS) +#define MM_GLB_REG_CPU_ROOT_CLK_SEL_UMSK (~(((1U << MM_GLB_REG_CPU_ROOT_CLK_SEL_LEN) - 1) << MM_GLB_REG_CPU_ROOT_CLK_SEL_POS)) +#define MM_GLB_REG_MMCPU0_CLK_EN MM_GLB_REG_MMCPU0_CLK_EN +#define MM_GLB_REG_MMCPU0_CLK_EN_POS (12U) +#define MM_GLB_REG_MMCPU0_CLK_EN_LEN (1U) +#define MM_GLB_REG_MMCPU0_CLK_EN_MSK (((1U << MM_GLB_REG_MMCPU0_CLK_EN_LEN) - 1) << MM_GLB_REG_MMCPU0_CLK_EN_POS) +#define MM_GLB_REG_MMCPU0_CLK_EN_UMSK (~(((1U << MM_GLB_REG_MMCPU0_CLK_EN_LEN) - 1) << MM_GLB_REG_MMCPU0_CLK_EN_POS)) +#define MM_GLB_REG_BCLK1X_SEL MM_GLB_REG_BCLK1X_SEL +#define MM_GLB_REG_BCLK1X_SEL_POS (13U) +#define MM_GLB_REG_BCLK1X_SEL_LEN (2U) +#define MM_GLB_REG_BCLK1X_SEL_MSK (((1U << MM_GLB_REG_BCLK1X_SEL_LEN) - 1) << MM_GLB_REG_BCLK1X_SEL_POS) +#define MM_GLB_REG_BCLK1X_SEL_UMSK (~(((1U << MM_GLB_REG_BCLK1X_SEL_LEN) - 1) << MM_GLB_REG_BCLK1X_SEL_POS)) +#define MM_GLB_REG_BCLK2X_DIV_ACT_PULSE MM_GLB_REG_BCLK2X_DIV_ACT_PULSE +#define MM_GLB_REG_BCLK2X_DIV_ACT_PULSE_POS (18U) +#define MM_GLB_REG_BCLK2X_DIV_ACT_PULSE_LEN (1U) +#define MM_GLB_REG_BCLK2X_DIV_ACT_PULSE_MSK (((1U << MM_GLB_REG_BCLK2X_DIV_ACT_PULSE_LEN) - 1) << MM_GLB_REG_BCLK2X_DIV_ACT_PULSE_POS) +#define MM_GLB_REG_BCLK2X_DIV_ACT_PULSE_UMSK (~(((1U << MM_GLB_REG_BCLK2X_DIV_ACT_PULSE_LEN) - 1) << MM_GLB_REG_BCLK2X_DIV_ACT_PULSE_POS)) +#define MM_GLB_REG_BCLK2X_DIV_BYPASS MM_GLB_REG_BCLK2X_DIV_BYPASS +#define MM_GLB_REG_BCLK2X_DIV_BYPASS_POS (19U) +#define MM_GLB_REG_BCLK2X_DIV_BYPASS_LEN (1U) +#define MM_GLB_REG_BCLK2X_DIV_BYPASS_MSK (((1U << MM_GLB_REG_BCLK2X_DIV_BYPASS_LEN) - 1) << MM_GLB_REG_BCLK2X_DIV_BYPASS_POS) +#define MM_GLB_REG_BCLK2X_DIV_BYPASS_UMSK (~(((1U << MM_GLB_REG_BCLK2X_DIV_BYPASS_LEN) - 1) << MM_GLB_REG_BCLK2X_DIV_BYPASS_POS)) +#define MM_GLB_STS_BCLK2X_PROT_DONE MM_GLB_STS_BCLK2X_PROT_DONE +#define MM_GLB_STS_BCLK2X_PROT_DONE_POS (20U) +#define MM_GLB_STS_BCLK2X_PROT_DONE_LEN (1U) +#define MM_GLB_STS_BCLK2X_PROT_DONE_MSK (((1U << MM_GLB_STS_BCLK2X_PROT_DONE_LEN) - 1) << MM_GLB_STS_BCLK2X_PROT_DONE_POS) +#define MM_GLB_STS_BCLK2X_PROT_DONE_UMSK (~(((1U << MM_GLB_STS_BCLK2X_PROT_DONE_LEN) - 1) << MM_GLB_STS_BCLK2X_PROT_DONE_POS)) +#define MM_GLB_REG_BCLK2X_SW_DONE_CNT MM_GLB_REG_BCLK2X_SW_DONE_CNT +#define MM_GLB_REG_BCLK2X_SW_DONE_CNT_POS (24U) +#define MM_GLB_REG_BCLK2X_SW_DONE_CNT_LEN (4U) +#define MM_GLB_REG_BCLK2X_SW_DONE_CNT_MSK (((1U << MM_GLB_REG_BCLK2X_SW_DONE_CNT_LEN) - 1) << MM_GLB_REG_BCLK2X_SW_DONE_CNT_POS) +#define MM_GLB_REG_BCLK2X_SW_DONE_CNT_UMSK (~(((1U << MM_GLB_REG_BCLK2X_SW_DONE_CNT_LEN) - 1) << MM_GLB_REG_BCLK2X_SW_DONE_CNT_POS)) +#define MM_GLB_CPU_CLK_SW_STATE MM_GLB_CPU_CLK_SW_STATE +#define MM_GLB_CPU_CLK_SW_STATE_POS (28U) +#define MM_GLB_CPU_CLK_SW_STATE_LEN (3U) +#define MM_GLB_CPU_CLK_SW_STATE_MSK (((1U << MM_GLB_CPU_CLK_SW_STATE_LEN) - 1) << MM_GLB_CPU_CLK_SW_STATE_POS) +#define MM_GLB_CPU_CLK_SW_STATE_UMSK (~(((1U << MM_GLB_CPU_CLK_SW_STATE_LEN) - 1) << MM_GLB_CPU_CLK_SW_STATE_POS)) + +/* 0x4 : mm_clk_cpu */ +#define MM_GLB_MM_CLK_CPU_OFFSET (0x4) +#define MM_GLB_REG_CPU_CLK_DIV MM_GLB_REG_CPU_CLK_DIV +#define MM_GLB_REG_CPU_CLK_DIV_POS (0U) +#define MM_GLB_REG_CPU_CLK_DIV_LEN (8U) +#define MM_GLB_REG_CPU_CLK_DIV_MSK (((1U << MM_GLB_REG_CPU_CLK_DIV_LEN) - 1) << MM_GLB_REG_CPU_CLK_DIV_POS) +#define MM_GLB_REG_CPU_CLK_DIV_UMSK (~(((1U << MM_GLB_REG_CPU_CLK_DIV_LEN) - 1) << MM_GLB_REG_CPU_CLK_DIV_POS)) +#define MM_GLB_REG_CNN_CLK_DIV_EN MM_GLB_REG_CNN_CLK_DIV_EN +#define MM_GLB_REG_CNN_CLK_DIV_EN_POS (8U) +#define MM_GLB_REG_CNN_CLK_DIV_EN_LEN (1U) +#define MM_GLB_REG_CNN_CLK_DIV_EN_MSK (((1U << MM_GLB_REG_CNN_CLK_DIV_EN_LEN) - 1) << MM_GLB_REG_CNN_CLK_DIV_EN_POS) +#define MM_GLB_REG_CNN_CLK_DIV_EN_UMSK (~(((1U << MM_GLB_REG_CNN_CLK_DIV_EN_LEN) - 1) << MM_GLB_REG_CNN_CLK_DIV_EN_POS)) +#define MM_GLB_REG_CNN_CLK_SEL MM_GLB_REG_CNN_CLK_SEL +#define MM_GLB_REG_CNN_CLK_SEL_POS (9U) +#define MM_GLB_REG_CNN_CLK_SEL_LEN (2U) +#define MM_GLB_REG_CNN_CLK_SEL_MSK (((1U << MM_GLB_REG_CNN_CLK_SEL_LEN) - 1) << MM_GLB_REG_CNN_CLK_SEL_POS) +#define MM_GLB_REG_CNN_CLK_SEL_UMSK (~(((1U << MM_GLB_REG_CNN_CLK_SEL_LEN) - 1) << MM_GLB_REG_CNN_CLK_SEL_POS)) +#define MM_GLB_REG_CNN_CLK_DIV MM_GLB_REG_CNN_CLK_DIV +#define MM_GLB_REG_CNN_CLK_DIV_POS (12U) +#define MM_GLB_REG_CNN_CLK_DIV_LEN (3U) +#define MM_GLB_REG_CNN_CLK_DIV_MSK (((1U << MM_GLB_REG_CNN_CLK_DIV_LEN) - 1) << MM_GLB_REG_CNN_CLK_DIV_POS) +#define MM_GLB_REG_CNN_CLK_DIV_UMSK (~(((1U << MM_GLB_REG_CNN_CLK_DIV_LEN) - 1) << MM_GLB_REG_CNN_CLK_DIV_POS)) +#define MM_GLB_REG_BCLK2X_DIV MM_GLB_REG_BCLK2X_DIV +#define MM_GLB_REG_BCLK2X_DIV_POS (16U) +#define MM_GLB_REG_BCLK2X_DIV_LEN (8U) +#define MM_GLB_REG_BCLK2X_DIV_MSK (((1U << MM_GLB_REG_BCLK2X_DIV_LEN) - 1) << MM_GLB_REG_BCLK2X_DIV_POS) +#define MM_GLB_REG_BCLK2X_DIV_UMSK (~(((1U << MM_GLB_REG_BCLK2X_DIV_LEN) - 1) << MM_GLB_REG_BCLK2X_DIV_POS)) +#define MM_GLB_REG_BCLK1X_DIV MM_GLB_REG_BCLK1X_DIV +#define MM_GLB_REG_BCLK1X_DIV_POS (24U) +#define MM_GLB_REG_BCLK1X_DIV_LEN (8U) +#define MM_GLB_REG_BCLK1X_DIV_MSK (((1U << MM_GLB_REG_BCLK1X_DIV_LEN) - 1) << MM_GLB_REG_BCLK1X_DIV_POS) +#define MM_GLB_REG_BCLK1X_DIV_UMSK (~(((1U << MM_GLB_REG_BCLK1X_DIV_LEN) - 1) << MM_GLB_REG_BCLK1X_DIV_POS)) + +/* 0x8 : dsp2_dp_clk */ +#define MM_GLB_DSP2_DP_CLK_OFFSET (0x8) +#define MM_GLB_REG_DSP2_CLK_DIV_EN MM_GLB_REG_DSP2_CLK_DIV_EN +#define MM_GLB_REG_DSP2_CLK_DIV_EN_POS (0U) +#define MM_GLB_REG_DSP2_CLK_DIV_EN_LEN (1U) +#define MM_GLB_REG_DSP2_CLK_DIV_EN_MSK (((1U << MM_GLB_REG_DSP2_CLK_DIV_EN_LEN) - 1) << MM_GLB_REG_DSP2_CLK_DIV_EN_POS) +#define MM_GLB_REG_DSP2_CLK_DIV_EN_UMSK (~(((1U << MM_GLB_REG_DSP2_CLK_DIV_EN_LEN) - 1) << MM_GLB_REG_DSP2_CLK_DIV_EN_POS)) +#define MM_GLB_REG_DSP2_CLK_SEL MM_GLB_REG_DSP2_CLK_SEL +#define MM_GLB_REG_DSP2_CLK_SEL_POS (1U) +#define MM_GLB_REG_DSP2_CLK_SEL_LEN (2U) +#define MM_GLB_REG_DSP2_CLK_SEL_MSK (((1U << MM_GLB_REG_DSP2_CLK_SEL_LEN) - 1) << MM_GLB_REG_DSP2_CLK_SEL_POS) +#define MM_GLB_REG_DSP2_CLK_SEL_UMSK (~(((1U << MM_GLB_REG_DSP2_CLK_SEL_LEN) - 1) << MM_GLB_REG_DSP2_CLK_SEL_POS)) +#define MM_GLB_REG_DSP2_CLK_DIV MM_GLB_REG_DSP2_CLK_DIV +#define MM_GLB_REG_DSP2_CLK_DIV_POS (8U) +#define MM_GLB_REG_DSP2_CLK_DIV_LEN (8U) +#define MM_GLB_REG_DSP2_CLK_DIV_MSK (((1U << MM_GLB_REG_DSP2_CLK_DIV_LEN) - 1) << MM_GLB_REG_DSP2_CLK_DIV_POS) +#define MM_GLB_REG_DSP2_CLK_DIV_UMSK (~(((1U << MM_GLB_REG_DSP2_CLK_DIV_LEN) - 1) << MM_GLB_REG_DSP2_CLK_DIV_POS)) +#define MM_GLB_REG_DP_CLK_DIV_EN MM_GLB_REG_DP_CLK_DIV_EN +#define MM_GLB_REG_DP_CLK_DIV_EN_POS (16U) +#define MM_GLB_REG_DP_CLK_DIV_EN_LEN (1U) +#define MM_GLB_REG_DP_CLK_DIV_EN_MSK (((1U << MM_GLB_REG_DP_CLK_DIV_EN_LEN) - 1) << MM_GLB_REG_DP_CLK_DIV_EN_POS) +#define MM_GLB_REG_DP_CLK_DIV_EN_UMSK (~(((1U << MM_GLB_REG_DP_CLK_DIV_EN_LEN) - 1) << MM_GLB_REG_DP_CLK_DIV_EN_POS)) +#define MM_GLB_REG_DP_CLK_SEL MM_GLB_REG_DP_CLK_SEL +#define MM_GLB_REG_DP_CLK_SEL_POS (17U) +#define MM_GLB_REG_DP_CLK_SEL_LEN (1U) +#define MM_GLB_REG_DP_CLK_SEL_MSK (((1U << MM_GLB_REG_DP_CLK_SEL_LEN) - 1) << MM_GLB_REG_DP_CLK_SEL_POS) +#define MM_GLB_REG_DP_CLK_SEL_UMSK (~(((1U << MM_GLB_REG_DP_CLK_SEL_LEN) - 1) << MM_GLB_REG_DP_CLK_SEL_POS)) +#define MM_GLB_REG_DP_CLK_DIV MM_GLB_REG_DP_CLK_DIV +#define MM_GLB_REG_DP_CLK_DIV_POS (20U) +#define MM_GLB_REG_DP_CLK_DIV_LEN (4U) +#define MM_GLB_REG_DP_CLK_DIV_MSK (((1U << MM_GLB_REG_DP_CLK_DIV_LEN) - 1) << MM_GLB_REG_DP_CLK_DIV_POS) +#define MM_GLB_REG_DP_CLK_DIV_UMSK (~(((1U << MM_GLB_REG_DP_CLK_DIV_LEN) - 1) << MM_GLB_REG_DP_CLK_DIV_POS)) + +/* 0xC : codec_clk */ +#define MM_GLB_CODEC_CLK_OFFSET (0xC) +#define MM_GLB_REG_H264_CLK_DIV_EN MM_GLB_REG_H264_CLK_DIV_EN +#define MM_GLB_REG_H264_CLK_DIV_EN_POS (8U) +#define MM_GLB_REG_H264_CLK_DIV_EN_LEN (1U) +#define MM_GLB_REG_H264_CLK_DIV_EN_MSK (((1U << MM_GLB_REG_H264_CLK_DIV_EN_LEN) - 1) << MM_GLB_REG_H264_CLK_DIV_EN_POS) +#define MM_GLB_REG_H264_CLK_DIV_EN_UMSK (~(((1U << MM_GLB_REG_H264_CLK_DIV_EN_LEN) - 1) << MM_GLB_REG_H264_CLK_DIV_EN_POS)) +#define MM_GLB_REG_H264_CLK_SEL MM_GLB_REG_H264_CLK_SEL +#define MM_GLB_REG_H264_CLK_SEL_POS (9U) +#define MM_GLB_REG_H264_CLK_SEL_LEN (2U) +#define MM_GLB_REG_H264_CLK_SEL_MSK (((1U << MM_GLB_REG_H264_CLK_SEL_LEN) - 1) << MM_GLB_REG_H264_CLK_SEL_POS) +#define MM_GLB_REG_H264_CLK_SEL_UMSK (~(((1U << MM_GLB_REG_H264_CLK_SEL_LEN) - 1) << MM_GLB_REG_H264_CLK_SEL_POS)) +#define MM_GLB_REG_H264_CLK_DIV MM_GLB_REG_H264_CLK_DIV +#define MM_GLB_REG_H264_CLK_DIV_POS (12U) +#define MM_GLB_REG_H264_CLK_DIV_LEN (3U) +#define MM_GLB_REG_H264_CLK_DIV_MSK (((1U << MM_GLB_REG_H264_CLK_DIV_LEN) - 1) << MM_GLB_REG_H264_CLK_DIV_POS) +#define MM_GLB_REG_H264_CLK_DIV_UMSK (~(((1U << MM_GLB_REG_H264_CLK_DIV_LEN) - 1) << MM_GLB_REG_H264_CLK_DIV_POS)) + +/* 0x10 : mm_clk_ctrl_peri */ +#define MM_GLB_MM_CLK_CTRL_PERI_OFFSET (0x10) +#define MM_GLB_REG_I2C0_CLK_DIV MM_GLB_REG_I2C0_CLK_DIV +#define MM_GLB_REG_I2C0_CLK_DIV_POS (0U) +#define MM_GLB_REG_I2C0_CLK_DIV_LEN (8U) +#define MM_GLB_REG_I2C0_CLK_DIV_MSK (((1U << MM_GLB_REG_I2C0_CLK_DIV_LEN) - 1) << MM_GLB_REG_I2C0_CLK_DIV_POS) +#define MM_GLB_REG_I2C0_CLK_DIV_UMSK (~(((1U << MM_GLB_REG_I2C0_CLK_DIV_LEN) - 1) << MM_GLB_REG_I2C0_CLK_DIV_POS)) +#define MM_GLB_REG_I2C0_CLK_DIV_EN MM_GLB_REG_I2C0_CLK_DIV_EN +#define MM_GLB_REG_I2C0_CLK_DIV_EN_POS (8U) +#define MM_GLB_REG_I2C0_CLK_DIV_EN_LEN (1U) +#define MM_GLB_REG_I2C0_CLK_DIV_EN_MSK (((1U << MM_GLB_REG_I2C0_CLK_DIV_EN_LEN) - 1) << MM_GLB_REG_I2C0_CLK_DIV_EN_POS) +#define MM_GLB_REG_I2C0_CLK_DIV_EN_UMSK (~(((1U << MM_GLB_REG_I2C0_CLK_DIV_EN_LEN) - 1) << MM_GLB_REG_I2C0_CLK_DIV_EN_POS)) +#define MM_GLB_REG_I2C0_CLK_EN MM_GLB_REG_I2C0_CLK_EN +#define MM_GLB_REG_I2C0_CLK_EN_POS (9U) +#define MM_GLB_REG_I2C0_CLK_EN_LEN (1U) +#define MM_GLB_REG_I2C0_CLK_EN_MSK (((1U << MM_GLB_REG_I2C0_CLK_EN_LEN) - 1) << MM_GLB_REG_I2C0_CLK_EN_POS) +#define MM_GLB_REG_I2C0_CLK_EN_UMSK (~(((1U << MM_GLB_REG_I2C0_CLK_EN_LEN) - 1) << MM_GLB_REG_I2C0_CLK_EN_POS)) +#define MM_GLB_REG_UART0_CLK_DIV_EN MM_GLB_REG_UART0_CLK_DIV_EN +#define MM_GLB_REG_UART0_CLK_DIV_EN_POS (16U) +#define MM_GLB_REG_UART0_CLK_DIV_EN_LEN (1U) +#define MM_GLB_REG_UART0_CLK_DIV_EN_MSK (((1U << MM_GLB_REG_UART0_CLK_DIV_EN_LEN) - 1) << MM_GLB_REG_UART0_CLK_DIV_EN_POS) +#define MM_GLB_REG_UART0_CLK_DIV_EN_UMSK (~(((1U << MM_GLB_REG_UART0_CLK_DIV_EN_LEN) - 1) << MM_GLB_REG_UART0_CLK_DIV_EN_POS)) +#define MM_GLB_REG_UART0_CLK_DIV MM_GLB_REG_UART0_CLK_DIV +#define MM_GLB_REG_UART0_CLK_DIV_POS (17U) +#define MM_GLB_REG_UART0_CLK_DIV_LEN (3U) +#define MM_GLB_REG_UART0_CLK_DIV_MSK (((1U << MM_GLB_REG_UART0_CLK_DIV_LEN) - 1) << MM_GLB_REG_UART0_CLK_DIV_POS) +#define MM_GLB_REG_UART0_CLK_DIV_UMSK (~(((1U << MM_GLB_REG_UART0_CLK_DIV_LEN) - 1) << MM_GLB_REG_UART0_CLK_DIV_POS)) +#define MM_GLB_REG_SPI_CLK_DIV_EN MM_GLB_REG_SPI_CLK_DIV_EN +#define MM_GLB_REG_SPI_CLK_DIV_EN_POS (23U) +#define MM_GLB_REG_SPI_CLK_DIV_EN_LEN (1U) +#define MM_GLB_REG_SPI_CLK_DIV_EN_MSK (((1U << MM_GLB_REG_SPI_CLK_DIV_EN_LEN) - 1) << MM_GLB_REG_SPI_CLK_DIV_EN_POS) +#define MM_GLB_REG_SPI_CLK_DIV_EN_UMSK (~(((1U << MM_GLB_REG_SPI_CLK_DIV_EN_LEN) - 1) << MM_GLB_REG_SPI_CLK_DIV_EN_POS)) +#define MM_GLB_REG_SPI_CLK_DIV MM_GLB_REG_SPI_CLK_DIV +#define MM_GLB_REG_SPI_CLK_DIV_POS (24U) +#define MM_GLB_REG_SPI_CLK_DIV_LEN (8U) +#define MM_GLB_REG_SPI_CLK_DIV_MSK (((1U << MM_GLB_REG_SPI_CLK_DIV_LEN) - 1) << MM_GLB_REG_SPI_CLK_DIV_POS) +#define MM_GLB_REG_SPI_CLK_DIV_UMSK (~(((1U << MM_GLB_REG_SPI_CLK_DIV_LEN) - 1) << MM_GLB_REG_SPI_CLK_DIV_POS)) + +/* 0x18 : mm_clk_ctrl_peri3 */ +#define MM_GLB_MM_CLK_CTRL_PERI3_OFFSET (0x18) +#define MM_GLB_REG_I2C1_CLK_DIV MM_GLB_REG_I2C1_CLK_DIV +#define MM_GLB_REG_I2C1_CLK_DIV_POS (0U) +#define MM_GLB_REG_I2C1_CLK_DIV_LEN (8U) +#define MM_GLB_REG_I2C1_CLK_DIV_MSK (((1U << MM_GLB_REG_I2C1_CLK_DIV_LEN) - 1) << MM_GLB_REG_I2C1_CLK_DIV_POS) +#define MM_GLB_REG_I2C1_CLK_DIV_UMSK (~(((1U << MM_GLB_REG_I2C1_CLK_DIV_LEN) - 1) << MM_GLB_REG_I2C1_CLK_DIV_POS)) +#define MM_GLB_REG_I2C1_CLK_DIV_EN MM_GLB_REG_I2C1_CLK_DIV_EN +#define MM_GLB_REG_I2C1_CLK_DIV_EN_POS (8U) +#define MM_GLB_REG_I2C1_CLK_DIV_EN_LEN (1U) +#define MM_GLB_REG_I2C1_CLK_DIV_EN_MSK (((1U << MM_GLB_REG_I2C1_CLK_DIV_EN_LEN) - 1) << MM_GLB_REG_I2C1_CLK_DIV_EN_POS) +#define MM_GLB_REG_I2C1_CLK_DIV_EN_UMSK (~(((1U << MM_GLB_REG_I2C1_CLK_DIV_EN_LEN) - 1) << MM_GLB_REG_I2C1_CLK_DIV_EN_POS)) +#define MM_GLB_REG_I2C1_CLK_EN MM_GLB_REG_I2C1_CLK_EN +#define MM_GLB_REG_I2C1_CLK_EN_POS (9U) +#define MM_GLB_REG_I2C1_CLK_EN_LEN (1U) +#define MM_GLB_REG_I2C1_CLK_EN_MSK (((1U << MM_GLB_REG_I2C1_CLK_EN_LEN) - 1) << MM_GLB_REG_I2C1_CLK_EN_POS) +#define MM_GLB_REG_I2C1_CLK_EN_UMSK (~(((1U << MM_GLB_REG_I2C1_CLK_EN_LEN) - 1) << MM_GLB_REG_I2C1_CLK_EN_POS)) +#define MM_GLB_REG_UART1_CLK_DIV_EN MM_GLB_REG_UART1_CLK_DIV_EN +#define MM_GLB_REG_UART1_CLK_DIV_EN_POS (16U) +#define MM_GLB_REG_UART1_CLK_DIV_EN_LEN (1U) +#define MM_GLB_REG_UART1_CLK_DIV_EN_MSK (((1U << MM_GLB_REG_UART1_CLK_DIV_EN_LEN) - 1) << MM_GLB_REG_UART1_CLK_DIV_EN_POS) +#define MM_GLB_REG_UART1_CLK_DIV_EN_UMSK (~(((1U << MM_GLB_REG_UART1_CLK_DIV_EN_LEN) - 1) << MM_GLB_REG_UART1_CLK_DIV_EN_POS)) +#define MM_GLB_REG_UART1_CLK_DIV MM_GLB_REG_UART1_CLK_DIV +#define MM_GLB_REG_UART1_CLK_DIV_POS (17U) +#define MM_GLB_REG_UART1_CLK_DIV_LEN (3U) +#define MM_GLB_REG_UART1_CLK_DIV_MSK (((1U << MM_GLB_REG_UART1_CLK_DIV_LEN) - 1) << MM_GLB_REG_UART1_CLK_DIV_POS) +#define MM_GLB_REG_UART1_CLK_DIV_UMSK (~(((1U << MM_GLB_REG_UART1_CLK_DIV_LEN) - 1) << MM_GLB_REG_UART1_CLK_DIV_POS)) + +/* 0x40 : mm_sw_sys_reset */ +#define MM_GLB_MM_SW_SYS_RESET_OFFSET (0x40) +#define MM_GLB_REG_CTRL_SYS_RESET MM_GLB_REG_CTRL_SYS_RESET +#define MM_GLB_REG_CTRL_SYS_RESET_POS (0U) +#define MM_GLB_REG_CTRL_SYS_RESET_LEN (1U) +#define MM_GLB_REG_CTRL_SYS_RESET_MSK (((1U << MM_GLB_REG_CTRL_SYS_RESET_LEN) - 1) << MM_GLB_REG_CTRL_SYS_RESET_POS) +#define MM_GLB_REG_CTRL_SYS_RESET_UMSK (~(((1U << MM_GLB_REG_CTRL_SYS_RESET_LEN) - 1) << MM_GLB_REG_CTRL_SYS_RESET_POS)) +#define MM_GLB_REG_CTRL_PWRON_RST MM_GLB_REG_CTRL_PWRON_RST +#define MM_GLB_REG_CTRL_PWRON_RST_POS (2U) +#define MM_GLB_REG_CTRL_PWRON_RST_LEN (1U) +#define MM_GLB_REG_CTRL_PWRON_RST_MSK (((1U << MM_GLB_REG_CTRL_PWRON_RST_LEN) - 1) << MM_GLB_REG_CTRL_PWRON_RST_POS) +#define MM_GLB_REG_CTRL_PWRON_RST_UMSK (~(((1U << MM_GLB_REG_CTRL_PWRON_RST_LEN) - 1) << MM_GLB_REG_CTRL_PWRON_RST_POS)) +#define MM_GLB_REG_CTRL_MMCPU0_RESET MM_GLB_REG_CTRL_MMCPU0_RESET +#define MM_GLB_REG_CTRL_MMCPU0_RESET_POS (8U) +#define MM_GLB_REG_CTRL_MMCPU0_RESET_LEN (1U) +#define MM_GLB_REG_CTRL_MMCPU0_RESET_MSK (((1U << MM_GLB_REG_CTRL_MMCPU0_RESET_LEN) - 1) << MM_GLB_REG_CTRL_MMCPU0_RESET_POS) +#define MM_GLB_REG_CTRL_MMCPU0_RESET_UMSK (~(((1U << MM_GLB_REG_CTRL_MMCPU0_RESET_LEN) - 1) << MM_GLB_REG_CTRL_MMCPU0_RESET_POS)) + +/* 0x44 : sw_reset_mm_peri */ +#define MM_GLB_SW_RESET_MM_PERI_OFFSET (0x44) +#define MM_GLB_SWRST_MM_MISC MM_GLB_SWRST_MM_MISC +#define MM_GLB_SWRST_MM_MISC_POS (0U) +#define MM_GLB_SWRST_MM_MISC_LEN (1U) +#define MM_GLB_SWRST_MM_MISC_MSK (((1U << MM_GLB_SWRST_MM_MISC_LEN) - 1) << MM_GLB_SWRST_MM_MISC_POS) +#define MM_GLB_SWRST_MM_MISC_UMSK (~(((1U << MM_GLB_SWRST_MM_MISC_LEN) - 1) << MM_GLB_SWRST_MM_MISC_POS)) +#define MM_GLB_SWRST_DMA MM_GLB_SWRST_DMA +#define MM_GLB_SWRST_DMA_POS (1U) +#define MM_GLB_SWRST_DMA_LEN (1U) +#define MM_GLB_SWRST_DMA_MSK (((1U << MM_GLB_SWRST_DMA_LEN) - 1) << MM_GLB_SWRST_DMA_POS) +#define MM_GLB_SWRST_DMA_UMSK (~(((1U << MM_GLB_SWRST_DMA_LEN) - 1) << MM_GLB_SWRST_DMA_POS)) +#define MM_GLB_SWRST_UART0 MM_GLB_SWRST_UART0 +#define MM_GLB_SWRST_UART0_POS (2U) +#define MM_GLB_SWRST_UART0_LEN (1U) +#define MM_GLB_SWRST_UART0_MSK (((1U << MM_GLB_SWRST_UART0_LEN) - 1) << MM_GLB_SWRST_UART0_POS) +#define MM_GLB_SWRST_UART0_UMSK (~(((1U << MM_GLB_SWRST_UART0_LEN) - 1) << MM_GLB_SWRST_UART0_POS)) +#define MM_GLB_SWRST_I2C0 MM_GLB_SWRST_I2C0 +#define MM_GLB_SWRST_I2C0_POS (3U) +#define MM_GLB_SWRST_I2C0_LEN (1U) +#define MM_GLB_SWRST_I2C0_MSK (((1U << MM_GLB_SWRST_I2C0_LEN) - 1) << MM_GLB_SWRST_I2C0_POS) +#define MM_GLB_SWRST_I2C0_UMSK (~(((1U << MM_GLB_SWRST_I2C0_LEN) - 1) << MM_GLB_SWRST_I2C0_POS)) +#define MM_GLB_SWRST_I2C1 MM_GLB_SWRST_I2C1 +#define MM_GLB_SWRST_I2C1_POS (4U) +#define MM_GLB_SWRST_I2C1_LEN (1U) +#define MM_GLB_SWRST_I2C1_MSK (((1U << MM_GLB_SWRST_I2C1_LEN) - 1) << MM_GLB_SWRST_I2C1_POS) +#define MM_GLB_SWRST_I2C1_UMSK (~(((1U << MM_GLB_SWRST_I2C1_LEN) - 1) << MM_GLB_SWRST_I2C1_POS)) +#define MM_GLB_SWRST_IPC MM_GLB_SWRST_IPC +#define MM_GLB_SWRST_IPC_POS (5U) +#define MM_GLB_SWRST_IPC_LEN (1U) +#define MM_GLB_SWRST_IPC_MSK (((1U << MM_GLB_SWRST_IPC_LEN) - 1) << MM_GLB_SWRST_IPC_POS) +#define MM_GLB_SWRST_IPC_UMSK (~(((1U << MM_GLB_SWRST_IPC_LEN) - 1) << MM_GLB_SWRST_IPC_POS)) +#define MM_GLB_SWRST_DMA2D MM_GLB_SWRST_DMA2D +#define MM_GLB_SWRST_DMA2D_POS (6U) +#define MM_GLB_SWRST_DMA2D_LEN (1U) +#define MM_GLB_SWRST_DMA2D_MSK (((1U << MM_GLB_SWRST_DMA2D_LEN) - 1) << MM_GLB_SWRST_DMA2D_POS) +#define MM_GLB_SWRST_DMA2D_UMSK (~(((1U << MM_GLB_SWRST_DMA2D_LEN) - 1) << MM_GLB_SWRST_DMA2D_POS)) +#define MM_GLB_SWRST_SPI MM_GLB_SWRST_SPI +#define MM_GLB_SWRST_SPI_POS (8U) +#define MM_GLB_SWRST_SPI_LEN (1U) +#define MM_GLB_SWRST_SPI_MSK (((1U << MM_GLB_SWRST_SPI_LEN) - 1) << MM_GLB_SWRST_SPI_POS) +#define MM_GLB_SWRST_SPI_UMSK (~(((1U << MM_GLB_SWRST_SPI_LEN) - 1) << MM_GLB_SWRST_SPI_POS)) +#define MM_GLB_SWRST_TIMER MM_GLB_SWRST_TIMER +#define MM_GLB_SWRST_TIMER_POS (9U) +#define MM_GLB_SWRST_TIMER_LEN (1U) +#define MM_GLB_SWRST_TIMER_MSK (((1U << MM_GLB_SWRST_TIMER_LEN) - 1) << MM_GLB_SWRST_TIMER_POS) +#define MM_GLB_SWRST_TIMER_UMSK (~(((1U << MM_GLB_SWRST_TIMER_LEN) - 1) << MM_GLB_SWRST_TIMER_POS)) +#define MM_GLB_SWRST_I2S0 MM_GLB_SWRST_I2S0 +#define MM_GLB_SWRST_I2S0_POS (10U) +#define MM_GLB_SWRST_I2S0_LEN (1U) +#define MM_GLB_SWRST_I2S0_MSK (((1U << MM_GLB_SWRST_I2S0_LEN) - 1) << MM_GLB_SWRST_I2S0_POS) +#define MM_GLB_SWRST_I2S0_UMSK (~(((1U << MM_GLB_SWRST_I2S0_LEN) - 1) << MM_GLB_SWRST_I2S0_POS)) +#define MM_GLB_SWRST_I2S1 MM_GLB_SWRST_I2S1 +#define MM_GLB_SWRST_I2S1_POS (11U) +#define MM_GLB_SWRST_I2S1_LEN (1U) +#define MM_GLB_SWRST_I2S1_MSK (((1U << MM_GLB_SWRST_I2S1_LEN) - 1) << MM_GLB_SWRST_I2S1_POS) +#define MM_GLB_SWRST_I2S1_UMSK (~(((1U << MM_GLB_SWRST_I2S1_LEN) - 1) << MM_GLB_SWRST_I2S1_POS)) +#define MM_GLB_SWRST_PDM0 MM_GLB_SWRST_PDM0 +#define MM_GLB_SWRST_PDM0_POS (12U) +#define MM_GLB_SWRST_PDM0_LEN (1U) +#define MM_GLB_SWRST_PDM0_MSK (((1U << MM_GLB_SWRST_PDM0_LEN) - 1) << MM_GLB_SWRST_PDM0_POS) +#define MM_GLB_SWRST_PDM0_UMSK (~(((1U << MM_GLB_SWRST_PDM0_LEN) - 1) << MM_GLB_SWRST_PDM0_POS)) +#define MM_GLB_SWRST_PDM1 MM_GLB_SWRST_PDM1 +#define MM_GLB_SWRST_PDM1_POS (13U) +#define MM_GLB_SWRST_PDM1_LEN (1U) +#define MM_GLB_SWRST_PDM1_MSK (((1U << MM_GLB_SWRST_PDM1_LEN) - 1) << MM_GLB_SWRST_PDM1_POS) +#define MM_GLB_SWRST_PDM1_UMSK (~(((1U << MM_GLB_SWRST_PDM1_LEN) - 1) << MM_GLB_SWRST_PDM1_POS)) +#define MM_GLB_SWRST_UART1 MM_GLB_SWRST_UART1 +#define MM_GLB_SWRST_UART1_POS (14U) +#define MM_GLB_SWRST_UART1_LEN (1U) +#define MM_GLB_SWRST_UART1_MSK (((1U << MM_GLB_SWRST_UART1_LEN) - 1) << MM_GLB_SWRST_UART1_POS) +#define MM_GLB_SWRST_UART1_UMSK (~(((1U << MM_GLB_SWRST_UART1_LEN) - 1) << MM_GLB_SWRST_UART1_POS)) +#define MM_GLB_SWRST_PUHS MM_GLB_SWRST_PUHS +#define MM_GLB_SWRST_PUHS_POS (15U) +#define MM_GLB_SWRST_PUHS_LEN (1U) +#define MM_GLB_SWRST_PUHS_MSK (((1U << MM_GLB_SWRST_PUHS_LEN) - 1) << MM_GLB_SWRST_PUHS_POS) +#define MM_GLB_SWRST_PUHS_UMSK (~(((1U << MM_GLB_SWRST_PUHS_LEN) - 1) << MM_GLB_SWRST_PUHS_POS)) + +/* 0x48 : sw_reset_dsp2_sub */ +#define MM_GLB_SW_RESET_DSP2_SUB_OFFSET (0x48) +#define MM_GLB_SWRST_DSP2_MISC MM_GLB_SWRST_DSP2_MISC +#define MM_GLB_SWRST_DSP2_MISC_POS (0U) +#define MM_GLB_SWRST_DSP2_MISC_LEN (1U) +#define MM_GLB_SWRST_DSP2_MISC_MSK (((1U << MM_GLB_SWRST_DSP2_MISC_LEN) - 1) << MM_GLB_SWRST_DSP2_MISC_POS) +#define MM_GLB_SWRST_DSP2_MISC_UMSK (~(((1U << MM_GLB_SWRST_DSP2_MISC_LEN) - 1) << MM_GLB_SWRST_DSP2_MISC_POS)) +#define MM_GLB_SWRST_DSP2_MAIN MM_GLB_SWRST_DSP2_MAIN +#define MM_GLB_SWRST_DSP2_MAIN_POS (1U) +#define MM_GLB_SWRST_DSP2_MAIN_LEN (1U) +#define MM_GLB_SWRST_DSP2_MAIN_MSK (((1U << MM_GLB_SWRST_DSP2_MAIN_LEN) - 1) << MM_GLB_SWRST_DSP2_MAIN_POS) +#define MM_GLB_SWRST_DSP2_MAIN_UMSK (~(((1U << MM_GLB_SWRST_DSP2_MAIN_LEN) - 1) << MM_GLB_SWRST_DSP2_MAIN_POS)) +#define MM_GLB_SWRST_DSP2_TSRC MM_GLB_SWRST_DSP2_TSRC +#define MM_GLB_SWRST_DSP2_TSRC_POS (2U) +#define MM_GLB_SWRST_DSP2_TSRC_LEN (1U) +#define MM_GLB_SWRST_DSP2_TSRC_MSK (((1U << MM_GLB_SWRST_DSP2_TSRC_LEN) - 1) << MM_GLB_SWRST_DSP2_TSRC_POS) +#define MM_GLB_SWRST_DSP2_TSRC_UMSK (~(((1U << MM_GLB_SWRST_DSP2_TSRC_LEN) - 1) << MM_GLB_SWRST_DSP2_TSRC_POS)) +#define MM_GLB_SWRST_DP_TSRC MM_GLB_SWRST_DP_TSRC +#define MM_GLB_SWRST_DP_TSRC_POS (3U) +#define MM_GLB_SWRST_DP_TSRC_LEN (1U) +#define MM_GLB_SWRST_DP_TSRC_MSK (((1U << MM_GLB_SWRST_DP_TSRC_LEN) - 1) << MM_GLB_SWRST_DP_TSRC_POS) +#define MM_GLB_SWRST_DP_TSRC_UMSK (~(((1U << MM_GLB_SWRST_DP_TSRC_LEN) - 1) << MM_GLB_SWRST_DP_TSRC_POS)) +#define MM_GLB_SWRST_NR3D_CTRL MM_GLB_SWRST_NR3D_CTRL +#define MM_GLB_SWRST_NR3D_CTRL_POS (4U) +#define MM_GLB_SWRST_NR3D_CTRL_LEN (1U) +#define MM_GLB_SWRST_NR3D_CTRL_MSK (((1U << MM_GLB_SWRST_NR3D_CTRL_LEN) - 1) << MM_GLB_SWRST_NR3D_CTRL_POS) +#define MM_GLB_SWRST_NR3D_CTRL_UMSK (~(((1U << MM_GLB_SWRST_NR3D_CTRL_LEN) - 1) << MM_GLB_SWRST_NR3D_CTRL_POS)) +#define MM_GLB_SWRST_DVP2BUSA MM_GLB_SWRST_DVP2BUSA +#define MM_GLB_SWRST_DVP2BUSA_POS (5U) +#define MM_GLB_SWRST_DVP2BUSA_LEN (1U) +#define MM_GLB_SWRST_DVP2BUSA_MSK (((1U << MM_GLB_SWRST_DVP2BUSA_LEN) - 1) << MM_GLB_SWRST_DVP2BUSA_POS) +#define MM_GLB_SWRST_DVP2BUSA_UMSK (~(((1U << MM_GLB_SWRST_DVP2BUSA_LEN) - 1) << MM_GLB_SWRST_DVP2BUSA_POS)) +#define MM_GLB_SWRST_DVP2BUSB MM_GLB_SWRST_DVP2BUSB +#define MM_GLB_SWRST_DVP2BUSB_POS (6U) +#define MM_GLB_SWRST_DVP2BUSB_LEN (1U) +#define MM_GLB_SWRST_DVP2BUSB_MSK (((1U << MM_GLB_SWRST_DVP2BUSB_LEN) - 1) << MM_GLB_SWRST_DVP2BUSB_POS) +#define MM_GLB_SWRST_DVP2BUSB_UMSK (~(((1U << MM_GLB_SWRST_DVP2BUSB_LEN) - 1) << MM_GLB_SWRST_DVP2BUSB_POS)) +#define MM_GLB_SWRST_DVP2BUSC MM_GLB_SWRST_DVP2BUSC +#define MM_GLB_SWRST_DVP2BUSC_POS (7U) +#define MM_GLB_SWRST_DVP2BUSC_LEN (1U) +#define MM_GLB_SWRST_DVP2BUSC_MSK (((1U << MM_GLB_SWRST_DVP2BUSC_LEN) - 1) << MM_GLB_SWRST_DVP2BUSC_POS) +#define MM_GLB_SWRST_DVP2BUSC_UMSK (~(((1U << MM_GLB_SWRST_DVP2BUSC_LEN) - 1) << MM_GLB_SWRST_DVP2BUSC_POS)) +#define MM_GLB_SWRST_DVP2BUSD MM_GLB_SWRST_DVP2BUSD +#define MM_GLB_SWRST_DVP2BUSD_POS (8U) +#define MM_GLB_SWRST_DVP2BUSD_LEN (1U) +#define MM_GLB_SWRST_DVP2BUSD_MSK (((1U << MM_GLB_SWRST_DVP2BUSD_LEN) - 1) << MM_GLB_SWRST_DVP2BUSD_POS) +#define MM_GLB_SWRST_DVP2BUSD_UMSK (~(((1U << MM_GLB_SWRST_DVP2BUSD_LEN) - 1) << MM_GLB_SWRST_DVP2BUSD_POS)) +#define MM_GLB_SWRST_MIPI MM_GLB_SWRST_MIPI +#define MM_GLB_SWRST_MIPI_POS (9U) +#define MM_GLB_SWRST_MIPI_LEN (1U) +#define MM_GLB_SWRST_MIPI_MSK (((1U << MM_GLB_SWRST_MIPI_LEN) - 1) << MM_GLB_SWRST_MIPI_POS) +#define MM_GLB_SWRST_MIPI_UMSK (~(((1U << MM_GLB_SWRST_MIPI_LEN) - 1) << MM_GLB_SWRST_MIPI_POS)) +#define MM_GLB_SWRST_DSP2_REG MM_GLB_SWRST_DSP2_REG +#define MM_GLB_SWRST_DSP2_REG_POS (16U) +#define MM_GLB_SWRST_DSP2_REG_LEN (1U) +#define MM_GLB_SWRST_DSP2_REG_MSK (((1U << MM_GLB_SWRST_DSP2_REG_LEN) - 1) << MM_GLB_SWRST_DSP2_REG_POS) +#define MM_GLB_SWRST_DSP2_REG_UMSK (~(((1U << MM_GLB_SWRST_DSP2_REG_LEN) - 1) << MM_GLB_SWRST_DSP2_REG_POS)) +#define MM_GLB_SWRST_DVP2BUSE MM_GLB_SWRST_DVP2BUSE +#define MM_GLB_SWRST_DVP2BUSE_POS (17U) +#define MM_GLB_SWRST_DVP2BUSE_LEN (1U) +#define MM_GLB_SWRST_DVP2BUSE_MSK (((1U << MM_GLB_SWRST_DVP2BUSE_LEN) - 1) << MM_GLB_SWRST_DVP2BUSE_POS) +#define MM_GLB_SWRST_DVP2BUSE_UMSK (~(((1U << MM_GLB_SWRST_DVP2BUSE_LEN) - 1) << MM_GLB_SWRST_DVP2BUSE_POS)) +#define MM_GLB_SWRST_DVP2BUSF MM_GLB_SWRST_DVP2BUSF +#define MM_GLB_SWRST_DVP2BUSF_POS (18U) +#define MM_GLB_SWRST_DVP2BUSF_LEN (1U) +#define MM_GLB_SWRST_DVP2BUSF_MSK (((1U << MM_GLB_SWRST_DVP2BUSF_LEN) - 1) << MM_GLB_SWRST_DVP2BUSF_POS) +#define MM_GLB_SWRST_DVP2BUSF_UMSK (~(((1U << MM_GLB_SWRST_DVP2BUSF_LEN) - 1) << MM_GLB_SWRST_DVP2BUSF_POS)) +#define MM_GLB_SWRST_DVP2BUSG MM_GLB_SWRST_DVP2BUSG +#define MM_GLB_SWRST_DVP2BUSG_POS (19U) +#define MM_GLB_SWRST_DVP2BUSG_LEN (1U) +#define MM_GLB_SWRST_DVP2BUSG_MSK (((1U << MM_GLB_SWRST_DVP2BUSG_LEN) - 1) << MM_GLB_SWRST_DVP2BUSG_POS) +#define MM_GLB_SWRST_DVP2BUSG_UMSK (~(((1U << MM_GLB_SWRST_DVP2BUSG_LEN) - 1) << MM_GLB_SWRST_DVP2BUSG_POS)) +#define MM_GLB_SWRST_DVP2BUSH MM_GLB_SWRST_DVP2BUSH +#define MM_GLB_SWRST_DVP2BUSH_POS (20U) +#define MM_GLB_SWRST_DVP2BUSH_LEN (1U) +#define MM_GLB_SWRST_DVP2BUSH_MSK (((1U << MM_GLB_SWRST_DVP2BUSH_LEN) - 1) << MM_GLB_SWRST_DVP2BUSH_POS) +#define MM_GLB_SWRST_DVP2BUSH_UMSK (~(((1U << MM_GLB_SWRST_DVP2BUSH_LEN) - 1) << MM_GLB_SWRST_DVP2BUSH_POS)) + +/* 0x4C : sw_reset_codec_sub */ +#define MM_GLB_SW_RESET_CODEC_SUB_OFFSET (0x4C) +#define MM_GLB_SWRST_CODEC_MISC MM_GLB_SWRST_CODEC_MISC +#define MM_GLB_SWRST_CODEC_MISC_POS (0U) +#define MM_GLB_SWRST_CODEC_MISC_LEN (1U) +#define MM_GLB_SWRST_CODEC_MISC_MSK (((1U << MM_GLB_SWRST_CODEC_MISC_LEN) - 1) << MM_GLB_SWRST_CODEC_MISC_POS) +#define MM_GLB_SWRST_CODEC_MISC_UMSK (~(((1U << MM_GLB_SWRST_CODEC_MISC_LEN) - 1) << MM_GLB_SWRST_CODEC_MISC_POS)) +#define MM_GLB_SWRST_MJPEG MM_GLB_SWRST_MJPEG +#define MM_GLB_SWRST_MJPEG_POS (1U) +#define MM_GLB_SWRST_MJPEG_LEN (1U) +#define MM_GLB_SWRST_MJPEG_MSK (((1U << MM_GLB_SWRST_MJPEG_LEN) - 1) << MM_GLB_SWRST_MJPEG_POS) +#define MM_GLB_SWRST_MJPEG_UMSK (~(((1U << MM_GLB_SWRST_MJPEG_LEN) - 1) << MM_GLB_SWRST_MJPEG_POS)) +#define MM_GLB_SWRST_H264 MM_GLB_SWRST_H264 +#define MM_GLB_SWRST_H264_POS (2U) +#define MM_GLB_SWRST_H264_LEN (1U) +#define MM_GLB_SWRST_H264_MSK (((1U << MM_GLB_SWRST_H264_LEN) - 1) << MM_GLB_SWRST_H264_POS) +#define MM_GLB_SWRST_H264_UMSK (~(((1U << MM_GLB_SWRST_H264_LEN) - 1) << MM_GLB_SWRST_H264_POS)) +#define MM_GLB_SWRST_MJPEG_DEC MM_GLB_SWRST_MJPEG_DEC +#define MM_GLB_SWRST_MJPEG_DEC_POS (3U) +#define MM_GLB_SWRST_MJPEG_DEC_LEN (1U) +#define MM_GLB_SWRST_MJPEG_DEC_MSK (((1U << MM_GLB_SWRST_MJPEG_DEC_LEN) - 1) << MM_GLB_SWRST_MJPEG_DEC_POS) +#define MM_GLB_SWRST_MJPEG_DEC_UMSK (~(((1U << MM_GLB_SWRST_MJPEG_DEC_LEN) - 1) << MM_GLB_SWRST_MJPEG_DEC_POS)) +#define MM_GLB_SWRST_CNN MM_GLB_SWRST_CNN +#define MM_GLB_SWRST_CNN_POS (4U) +#define MM_GLB_SWRST_CNN_LEN (1U) +#define MM_GLB_SWRST_CNN_MSK (((1U << MM_GLB_SWRST_CNN_LEN) - 1) << MM_GLB_SWRST_CNN_POS) +#define MM_GLB_SWRST_CNN_UMSK (~(((1U << MM_GLB_SWRST_CNN_LEN) - 1) << MM_GLB_SWRST_CNN_POS)) +#define MM_GLB_SWRST_VRAM MM_GLB_SWRST_VRAM +#define MM_GLB_SWRST_VRAM_POS (16U) +#define MM_GLB_SWRST_VRAM_LEN (1U) +#define MM_GLB_SWRST_VRAM_MSK (((1U << MM_GLB_SWRST_VRAM_LEN) - 1) << MM_GLB_SWRST_VRAM_POS) +#define MM_GLB_SWRST_VRAM_UMSK (~(((1U << MM_GLB_SWRST_VRAM_LEN) - 1) << MM_GLB_SWRST_VRAM_POS)) + +/* 0x50 : image_sensor_ctrl */ +#define MM_GLB_IMAGE_SENSOR_CTRL_OFFSET (0x50) +#define MM_GLB_RG_IS_RST_N MM_GLB_RG_IS_RST_N +#define MM_GLB_RG_IS_RST_N_POS (0U) +#define MM_GLB_RG_IS_RST_N_LEN (1U) +#define MM_GLB_RG_IS_RST_N_MSK (((1U << MM_GLB_RG_IS_RST_N_LEN) - 1) << MM_GLB_RG_IS_RST_N_POS) +#define MM_GLB_RG_IS_RST_N_UMSK (~(((1U << MM_GLB_RG_IS_RST_N_LEN) - 1) << MM_GLB_RG_IS_RST_N_POS)) + +/* 0x60 : tz_mm_clkrst */ +#define MM_GLB_TZ_MM_CLKRST_OFFSET (0x60) +#define MM_GLB_TZC_MM_SWRST_LOCK MM_GLB_TZC_MM_SWRST_LOCK +#define MM_GLB_TZC_MM_SWRST_LOCK_POS (0U) +#define MM_GLB_TZC_MM_SWRST_LOCK_LEN (1U) +#define MM_GLB_TZC_MM_SWRST_LOCK_MSK (((1U << MM_GLB_TZC_MM_SWRST_LOCK_LEN) - 1) << MM_GLB_TZC_MM_SWRST_LOCK_POS) +#define MM_GLB_TZC_MM_SWRST_LOCK_UMSK (~(((1U << MM_GLB_TZC_MM_SWRST_LOCK_LEN) - 1) << MM_GLB_TZC_MM_SWRST_LOCK_POS)) +#define MM_GLB_TZC_MM_SYS_RESET_LOCK MM_GLB_TZC_MM_SYS_RESET_LOCK +#define MM_GLB_TZC_MM_SYS_RESET_LOCK_POS (1U) +#define MM_GLB_TZC_MM_SYS_RESET_LOCK_LEN (1U) +#define MM_GLB_TZC_MM_SYS_RESET_LOCK_MSK (((1U << MM_GLB_TZC_MM_SYS_RESET_LOCK_LEN) - 1) << MM_GLB_TZC_MM_SYS_RESET_LOCK_POS) +#define MM_GLB_TZC_MM_SYS_RESET_LOCK_UMSK (~(((1U << MM_GLB_TZC_MM_SYS_RESET_LOCK_LEN) - 1) << MM_GLB_TZC_MM_SYS_RESET_LOCK_POS)) +#define MM_GLB_TZC_MM_PWRON_RST_LOCK MM_GLB_TZC_MM_PWRON_RST_LOCK +#define MM_GLB_TZC_MM_PWRON_RST_LOCK_POS (2U) +#define MM_GLB_TZC_MM_PWRON_RST_LOCK_LEN (1U) +#define MM_GLB_TZC_MM_PWRON_RST_LOCK_MSK (((1U << MM_GLB_TZC_MM_PWRON_RST_LOCK_LEN) - 1) << MM_GLB_TZC_MM_PWRON_RST_LOCK_POS) +#define MM_GLB_TZC_MM_PWRON_RST_LOCK_UMSK (~(((1U << MM_GLB_TZC_MM_PWRON_RST_LOCK_LEN) - 1) << MM_GLB_TZC_MM_PWRON_RST_LOCK_POS)) +#define MM_GLB_TZC_MM_CPU0_RESET_LOCK MM_GLB_TZC_MM_CPU0_RESET_LOCK +#define MM_GLB_TZC_MM_CPU0_RESET_LOCK_POS (3U) +#define MM_GLB_TZC_MM_CPU0_RESET_LOCK_LEN (1U) +#define MM_GLB_TZC_MM_CPU0_RESET_LOCK_MSK (((1U << MM_GLB_TZC_MM_CPU0_RESET_LOCK_LEN) - 1) << MM_GLB_TZC_MM_CPU0_RESET_LOCK_POS) +#define MM_GLB_TZC_MM_CPU0_RESET_LOCK_UMSK (~(((1U << MM_GLB_TZC_MM_CPU0_RESET_LOCK_LEN) - 1) << MM_GLB_TZC_MM_CPU0_RESET_LOCK_POS)) +#define MM_GLB_TZC_MM_CLK_LOCK MM_GLB_TZC_MM_CLK_LOCK +#define MM_GLB_TZC_MM_CLK_LOCK_POS (4U) +#define MM_GLB_TZC_MM_CLK_LOCK_LEN (1U) +#define MM_GLB_TZC_MM_CLK_LOCK_MSK (((1U << MM_GLB_TZC_MM_CLK_LOCK_LEN) - 1) << MM_GLB_TZC_MM_CLK_LOCK_POS) +#define MM_GLB_TZC_MM_CLK_LOCK_UMSK (~(((1U << MM_GLB_TZC_MM_CLK_LOCK_LEN) - 1) << MM_GLB_TZC_MM_CLK_LOCK_POS)) + +struct mm_glb_reg { + /* 0x0 : mm_clk_ctrl_cpu */ + union { + struct { + uint32_t reg_pll_en : 1; /* [ 0], r/w, 0x1 */ + uint32_t reg_cpu_clk_en : 1; /* [ 1], r/w, 0x1 */ + uint32_t reg_bclk_en : 1; /* [ 2], r/w, 0x1 */ + uint32_t reg_mm_cpu_clk_en : 1; /* [ 3], r/w, 0x1 */ + uint32_t reg_uart_clk_sel : 2; /* [ 5: 4], r/w, 0x0 */ + uint32_t reg_i2c_clk_sel : 1; /* [ 6], r/w, 0x0 */ + uint32_t reg_spi_clk_sel : 1; /* [ 7], r/w, 0x0 */ + uint32_t reg_cpu_clk_sel : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reg_xclk_clk_sel : 1; /* [ 10], r/w, 0x0 */ + uint32_t reg_cpu_root_clk_sel : 1; /* [ 11], r/w, 0x0 */ + uint32_t reg_mmcpu0_clk_en : 1; /* [ 12], r/w, 0x0 */ + uint32_t reg_bclk1x_sel : 2; /* [14:13], r/w, 0x0 */ + uint32_t reserved_15_17 : 3; /* [17:15], rsvd, 0x0 */ + uint32_t reg_bclk2x_div_act_pulse : 1; /* [ 18], w1p, 0x0 */ + uint32_t reg_bclk2x_div_bypass : 1; /* [ 19], r/w, 0x0 */ + uint32_t sts_bclk2x_prot_done : 1; /* [ 20], r, 0x1 */ + uint32_t reserved_21_23 : 3; /* [23:21], rsvd, 0x0 */ + uint32_t reg_bclk2x_sw_done_cnt : 4; /* [27:24], r/w, 0x5 */ + uint32_t cpu_clk_sw_state : 3; /* [30:28], r, 0x0 */ + uint32_t reserved_31 : 1; /* [ 31], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mm_clk_ctrl_cpu; + + /* 0x4 : mm_clk_cpu */ + union { + struct { + uint32_t reg_cpu_clk_div : 8; /* [ 7: 0], r/w, 0x0 */ + uint32_t reg_cnn_clk_div_en : 1; /* [ 8], r/w, 0x1 */ + uint32_t reg_cnn_clk_sel : 2; /* [10: 9], r/w, 0x0 */ + uint32_t reserved_11 : 1; /* [ 11], rsvd, 0x0 */ + uint32_t reg_cnn_clk_div : 3; /* [14:12], r/w, 0x0 */ + uint32_t reserved_15 : 1; /* [ 15], rsvd, 0x0 */ + uint32_t reg_bclk2x_div : 8; /* [23:16], r/w, 0x0 */ + uint32_t reg_bclk1x_div : 8; /* [31:24], r/w, 0x0 */ + } BF; + uint32_t WORD; + } mm_clk_cpu; + + /* 0x8 : dsp2_dp_clk */ + union { + struct { + uint32_t reg_dsp2_clk_div_en : 1; /* [ 0], r/w, 0x1 */ + uint32_t reg_dsp2_clk_sel : 2; /* [ 2: 1], r/w, 0x0 */ + uint32_t reserved_3_7 : 5; /* [ 7: 3], rsvd, 0x0 */ + uint32_t reg_dsp2_clk_div : 8; /* [15: 8], r/w, 0x0 */ + uint32_t reg_dp_clk_div_en : 1; /* [ 16], r/w, 0x1 */ + uint32_t reg_dp_clk_sel : 1; /* [ 17], r/w, 0x0 */ + uint32_t reserved_18_19 : 2; /* [19:18], rsvd, 0x0 */ + uint32_t reg_dp_clk_div : 4; /* [23:20], r/w, 0x0 */ + uint32_t reserved_24_31 : 8; /* [31:24], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } dsp2_dp_clk; + + /* 0xC : codec_clk */ + union { + struct { + uint32_t reserved_0_7 : 8; /* [ 7: 0], rsvd, 0x0 */ + uint32_t reg_h264_clk_div_en : 1; /* [ 8], r/w, 0x1 */ + uint32_t reg_h264_clk_sel : 2; /* [10: 9], r/w, 0x0 */ + uint32_t reserved_11 : 1; /* [ 11], rsvd, 0x0 */ + uint32_t reg_h264_clk_div : 3; /* [14:12], r/w, 0x0 */ + uint32_t reserved_15_31 : 17; /* [31:15], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } codec_clk; + + /* 0x10 : mm_clk_ctrl_peri */ + union { + struct { + uint32_t reg_i2c0_clk_div : 8; /* [ 7: 0], r/w, 0x0 */ + uint32_t reg_i2c0_clk_div_en : 1; /* [ 8], r/w, 0x1 */ + uint32_t reg_i2c0_clk_en : 1; /* [ 9], r/w, 0x1 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t reg_uart0_clk_div_en : 1; /* [ 16], r/w, 0x1 */ + uint32_t reg_uart0_clk_div : 3; /* [19:17], r/w, 0x0 */ + uint32_t reserved_20_22 : 3; /* [22:20], rsvd, 0x0 */ + uint32_t reg_spi_clk_div_en : 1; /* [ 23], r/w, 0x1 */ + uint32_t reg_spi_clk_div : 8; /* [31:24], r/w, 0x0 */ + } BF; + uint32_t WORD; + } mm_clk_ctrl_peri; + + /* 0x14 reserved */ + uint8_t RESERVED0x14[4]; + + /* 0x18 : mm_clk_ctrl_peri3 */ + union { + struct { + uint32_t reg_i2c1_clk_div : 8; /* [ 7: 0], r/w, 0x0 */ + uint32_t reg_i2c1_clk_div_en : 1; /* [ 8], r/w, 0x1 */ + uint32_t reg_i2c1_clk_en : 1; /* [ 9], r/w, 0x1 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t reg_uart1_clk_div_en : 1; /* [ 16], r/w, 0x1 */ + uint32_t reg_uart1_clk_div : 3; /* [19:17], r/w, 0x0 */ + uint32_t reserved_20_31 : 12; /* [31:20], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mm_clk_ctrl_peri3; + + /* 0x1c reserved */ + uint8_t RESERVED0x1c[36]; + + /* 0x40 : mm_sw_sys_reset */ + union { + struct { + uint32_t reg_ctrl_sys_reset : 1; /* [ 0], r/w, 0x0 */ + uint32_t reserved_1 : 1; /* [ 1], rsvd, 0x0 */ + uint32_t reg_ctrl_pwron_rst : 1; /* [ 2], r/w, 0x0 */ + uint32_t reserved_3_7 : 5; /* [ 7: 3], rsvd, 0x0 */ + uint32_t reg_ctrl_mmcpu0_reset : 1; /* [ 8], r/w, 0x1 */ + uint32_t reserved_9_31 : 23; /* [31: 9], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mm_sw_sys_reset; + + /* 0x44 : sw_reset_mm_peri */ + union { + struct { + uint32_t swrst_mm_misc : 1; /* [ 0], r/w, 0x0 */ + uint32_t swrst_dma : 1; /* [ 1], r/w, 0x0 */ + uint32_t swrst_uart0 : 1; /* [ 2], r/w, 0x0 */ + uint32_t swrst_i2c0 : 1; /* [ 3], r/w, 0x0 */ + uint32_t swrst_i2c1 : 1; /* [ 4], r/w, 0x0 */ + uint32_t swrst_ipc : 1; /* [ 5], r/w, 0x0 */ + uint32_t swrst_dma2d : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t swrst_spi : 1; /* [ 8], r/w, 0x0 */ + uint32_t swrst_timer : 1; /* [ 9], r/w, 0x0 */ + uint32_t swrst_i2s0 : 1; /* [ 10], r/w, 0x0 */ + uint32_t swrst_i2s1 : 1; /* [ 11], r/w, 0x0 */ + uint32_t swrst_pdm0 : 1; /* [ 12], r/w, 0x0 */ + uint32_t swrst_pdm1 : 1; /* [ 13], r/w, 0x0 */ + uint32_t swrst_uart1 : 1; /* [ 14], r/w, 0x0 */ + uint32_t swrst_pUHS : 1; /* [ 15], r/w, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sw_reset_mm_peri; + + /* 0x48 : sw_reset_dsp2_sub */ + union { + struct { + uint32_t swrst_dsp2_misc : 1; /* [ 0], r/w, 0x0 */ + uint32_t swrst_dsp2_main : 1; /* [ 1], r/w, 0x0 */ + uint32_t swrst_dsp2_tsrc : 1; /* [ 2], r/w, 0x0 */ + uint32_t swrst_dp_tsrc : 1; /* [ 3], r/w, 0x0 */ + uint32_t swrst_nr3d_ctrl : 1; /* [ 4], r/w, 0x0 */ + uint32_t swrst_dvp2busA : 1; /* [ 5], r/w, 0x0 */ + uint32_t swrst_dvp2busB : 1; /* [ 6], r/w, 0x0 */ + uint32_t swrst_dvp2busC : 1; /* [ 7], r/w, 0x0 */ + uint32_t swrst_dvp2busD : 1; /* [ 8], r/w, 0x0 */ + uint32_t swrst_mipi : 1; /* [ 9], r/w, 0x0 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t swrst_dsp2_reg : 1; /* [ 16], r/w, 0x0 */ + uint32_t swrst_dvp2busE : 1; /* [ 17], r/w, 0x0 */ + uint32_t swrst_dvp2busF : 1; /* [ 18], r/w, 0x0 */ + uint32_t swrst_dvp2busG : 1; /* [ 19], r/w, 0x0 */ + uint32_t swrst_dvp2busH : 1; /* [ 20], r/w, 0x0 */ + uint32_t reserved_21_31 : 11; /* [31:21], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sw_reset_dsp2_sub; + + /* 0x4C : sw_reset_codec_sub */ + union { + struct { + uint32_t swrst_codec_misc : 1; /* [ 0], r/w, 0x0 */ + uint32_t swrst_mjpeg : 1; /* [ 1], r/w, 0x0 */ + uint32_t swrst_h264 : 1; /* [ 2], r/w, 0x0 */ + uint32_t swrst_mjpeg_dec : 1; /* [ 3], r/w, 0x0 */ + uint32_t swrst_cnn : 1; /* [ 4], r/w, 0x0 */ + uint32_t reserved_5_15 : 11; /* [15: 5], rsvd, 0x0 */ + uint32_t swrst_vram : 1; /* [ 16], r/w, 0x0 */ + uint32_t reserved_17_31 : 15; /* [31:17], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sw_reset_codec_sub; + + /* 0x50 : image_sensor_ctrl */ + union { + struct { + uint32_t rg_is_rst_n : 1; /* [ 0], r/w, 0x1 */ + uint32_t reserved_1_31 : 31; /* [31: 1], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } image_sensor_ctrl; + + /* 0x54 reserved */ + uint8_t RESERVED0x54[12]; + + /* 0x60 : tz_mm_clkrst */ + union { + struct { + uint32_t tzc_mm_swrst_lock : 1; /* [ 0], r, 0x0 */ + uint32_t tzc_mm_sys_reset_lock : 1; /* [ 1], r, 0x0 */ + uint32_t tzc_mm_pwron_rst_lock : 1; /* [ 2], r, 0x0 */ + uint32_t tzc_mm_cpu0_reset_lock : 1; /* [ 3], r, 0x0 */ + uint32_t tzc_mm_clk_lock : 1; /* [ 4], r, 0x0 */ + uint32_t reserved_5_31 : 27; /* [31: 5], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } tz_mm_clkrst; +}; + +typedef volatile struct mm_glb_reg mm_glb_reg_t; + +#endif /* __MM_GLB_REG_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/mm_misc_reg.h b/platforms/bl808_m0/vendor/psram/include/mm_misc_reg.h new file mode 100644 index 0000000..f7425e4 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/mm_misc_reg.h @@ -0,0 +1,973 @@ +/** + ****************************************************************************** + * @file mm_misc_reg.h + * @version V1.0 + * @date 2021-07-12 + * @brief This file is the description of.IP register + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __MM_MISC_REG_H__ +#define __MM_MISC_REG_H__ + +#include "bl808.h" + +/* 0x0 : CPU0_Boot */ +#define MM_MISC_CPU0_BOOT_OFFSET (0x0) +#define MM_MISC_REG_CPU0_RVBA MM_MISC_REG_CPU0_RVBA +#define MM_MISC_REG_CPU0_RVBA_POS (0U) +#define MM_MISC_REG_CPU0_RVBA_LEN (32U) +#define MM_MISC_REG_CPU0_RVBA_MSK (((1U << MM_MISC_REG_CPU0_RVBA_LEN) - 1) << MM_MISC_REG_CPU0_RVBA_POS) +#define MM_MISC_REG_CPU0_RVBA_UMSK (~(((1U << MM_MISC_REG_CPU0_RVBA_LEN) - 1) << MM_MISC_REG_CPU0_RVBA_POS)) + +/* 0x8 : CPU_cfg */ +#define MM_MISC_CPU_CFG_OFFSET (0x8) +#define MM_MISC_REG_CPU0_APB_BASE MM_MISC_REG_CPU0_APB_BASE +#define MM_MISC_REG_CPU0_APB_BASE_POS (0U) +#define MM_MISC_REG_CPU0_APB_BASE_LEN (13U) +#define MM_MISC_REG_CPU0_APB_BASE_MSK (((1U << MM_MISC_REG_CPU0_APB_BASE_LEN) - 1) << MM_MISC_REG_CPU0_APB_BASE_POS) +#define MM_MISC_REG_CPU0_APB_BASE_UMSK (~(((1U << MM_MISC_REG_CPU0_APB_BASE_LEN) - 1) << MM_MISC_REG_CPU0_APB_BASE_POS)) +#define MM_MISC_CPU0_NDM_RSTN_EN MM_MISC_CPU0_NDM_RSTN_EN +#define MM_MISC_CPU0_NDM_RSTN_EN_POS (28U) +#define MM_MISC_CPU0_NDM_RSTN_EN_LEN (1U) +#define MM_MISC_CPU0_NDM_RSTN_EN_MSK (((1U << MM_MISC_CPU0_NDM_RSTN_EN_LEN) - 1) << MM_MISC_CPU0_NDM_RSTN_EN_POS) +#define MM_MISC_CPU0_NDM_RSTN_EN_UMSK (~(((1U << MM_MISC_CPU0_NDM_RSTN_EN_LEN) - 1) << MM_MISC_CPU0_NDM_RSTN_EN_POS)) +#define MM_MISC_CPU0_HART_RSTN_EN MM_MISC_CPU0_HART_RSTN_EN +#define MM_MISC_CPU0_HART_RSTN_EN_POS (29U) +#define MM_MISC_CPU0_HART_RSTN_EN_LEN (1U) +#define MM_MISC_CPU0_HART_RSTN_EN_MSK (((1U << MM_MISC_CPU0_HART_RSTN_EN_LEN) - 1) << MM_MISC_CPU0_HART_RSTN_EN_POS) +#define MM_MISC_CPU0_HART_RSTN_EN_UMSK (~(((1U << MM_MISC_CPU0_HART_RSTN_EN_LEN) - 1) << MM_MISC_CPU0_HART_RSTN_EN_POS)) + +/* 0xC : CPU_sts1 */ +#define MM_MISC_CPU_STS1_OFFSET (0xC) +#define MM_MISC_CPU0_LPMD_B MM_MISC_CPU0_LPMD_B +#define MM_MISC_CPU0_LPMD_B_POS (4U) +#define MM_MISC_CPU0_LPMD_B_LEN (2U) +#define MM_MISC_CPU0_LPMD_B_MSK (((1U << MM_MISC_CPU0_LPMD_B_LEN) - 1) << MM_MISC_CPU0_LPMD_B_POS) +#define MM_MISC_CPU0_LPMD_B_UMSK (~(((1U << MM_MISC_CPU0_LPMD_B_LEN) - 1) << MM_MISC_CPU0_LPMD_B_POS)) +#define MM_MISC_CPU0_RETIRE_PC_39_32 MM_MISC_CPU0_RETIRE_PC_39_32 +#define MM_MISC_CPU0_RETIRE_PC_39_32_POS (16U) +#define MM_MISC_CPU0_RETIRE_PC_39_32_LEN (8U) +#define MM_MISC_CPU0_RETIRE_PC_39_32_MSK (((1U << MM_MISC_CPU0_RETIRE_PC_39_32_LEN) - 1) << MM_MISC_CPU0_RETIRE_PC_39_32_POS) +#define MM_MISC_CPU0_RETIRE_PC_39_32_UMSK (~(((1U << MM_MISC_CPU0_RETIRE_PC_39_32_LEN) - 1) << MM_MISC_CPU0_RETIRE_PC_39_32_POS)) +#define MM_MISC_CPU0_RETIRE MM_MISC_CPU0_RETIRE +#define MM_MISC_CPU0_RETIRE_POS (24U) +#define MM_MISC_CPU0_RETIRE_LEN (1U) +#define MM_MISC_CPU0_RETIRE_MSK (((1U << MM_MISC_CPU0_RETIRE_LEN) - 1) << MM_MISC_CPU0_RETIRE_POS) +#define MM_MISC_CPU0_RETIRE_UMSK (~(((1U << MM_MISC_CPU0_RETIRE_LEN) - 1) << MM_MISC_CPU0_RETIRE_POS)) +#define MM_MISC_CPU0_PAD_HALTED MM_MISC_CPU0_PAD_HALTED +#define MM_MISC_CPU0_PAD_HALTED_POS (25U) +#define MM_MISC_CPU0_PAD_HALTED_LEN (1U) +#define MM_MISC_CPU0_PAD_HALTED_MSK (((1U << MM_MISC_CPU0_PAD_HALTED_LEN) - 1) << MM_MISC_CPU0_PAD_HALTED_POS) +#define MM_MISC_CPU0_PAD_HALTED_UMSK (~(((1U << MM_MISC_CPU0_PAD_HALTED_LEN) - 1) << MM_MISC_CPU0_PAD_HALTED_POS)) +#define MM_MISC_CPU0_NDM_RSTN_REQ MM_MISC_CPU0_NDM_RSTN_REQ +#define MM_MISC_CPU0_NDM_RSTN_REQ_POS (28U) +#define MM_MISC_CPU0_NDM_RSTN_REQ_LEN (1U) +#define MM_MISC_CPU0_NDM_RSTN_REQ_MSK (((1U << MM_MISC_CPU0_NDM_RSTN_REQ_LEN) - 1) << MM_MISC_CPU0_NDM_RSTN_REQ_POS) +#define MM_MISC_CPU0_NDM_RSTN_REQ_UMSK (~(((1U << MM_MISC_CPU0_NDM_RSTN_REQ_LEN) - 1) << MM_MISC_CPU0_NDM_RSTN_REQ_POS)) +#define MM_MISC_CPU0_HART_RSTN_REQ MM_MISC_CPU0_HART_RSTN_REQ +#define MM_MISC_CPU0_HART_RSTN_REQ_POS (29U) +#define MM_MISC_CPU0_HART_RSTN_REQ_LEN (1U) +#define MM_MISC_CPU0_HART_RSTN_REQ_MSK (((1U << MM_MISC_CPU0_HART_RSTN_REQ_LEN) - 1) << MM_MISC_CPU0_HART_RSTN_REQ_POS) +#define MM_MISC_CPU0_HART_RSTN_REQ_UMSK (~(((1U << MM_MISC_CPU0_HART_RSTN_REQ_LEN) - 1) << MM_MISC_CPU0_HART_RSTN_REQ_POS)) + +/* 0x10 : CPU_sts2 */ +#define MM_MISC_CPU_STS2_OFFSET (0x10) +#define MM_MISC_CPU0_RETIRE_PC_31_0 MM_MISC_CPU0_RETIRE_PC_31_0 +#define MM_MISC_CPU0_RETIRE_PC_31_0_POS (0U) +#define MM_MISC_CPU0_RETIRE_PC_31_0_LEN (32U) +#define MM_MISC_CPU0_RETIRE_PC_31_0_MSK (((1U << MM_MISC_CPU0_RETIRE_PC_31_0_LEN) - 1) << MM_MISC_CPU0_RETIRE_PC_31_0_POS) +#define MM_MISC_CPU0_RETIRE_PC_31_0_UMSK (~(((1U << MM_MISC_CPU0_RETIRE_PC_31_0_LEN) - 1) << MM_MISC_CPU0_RETIRE_PC_31_0_POS)) + +/* 0x18 : CPU_RTC */ +#define MM_MISC_CPU_RTC_OFFSET (0x18) +#define MM_MISC_C906_RTC_DIV MM_MISC_C906_RTC_DIV +#define MM_MISC_C906_RTC_DIV_POS (0U) +#define MM_MISC_C906_RTC_DIV_LEN (10U) +#define MM_MISC_C906_RTC_DIV_MSK (((1U << MM_MISC_C906_RTC_DIV_LEN) - 1) << MM_MISC_C906_RTC_DIV_POS) +#define MM_MISC_C906_RTC_DIV_UMSK (~(((1U << MM_MISC_C906_RTC_DIV_LEN) - 1) << MM_MISC_C906_RTC_DIV_POS)) +#define MM_MISC_C906_RTC_RST MM_MISC_C906_RTC_RST +#define MM_MISC_C906_RTC_RST_POS (30U) +#define MM_MISC_C906_RTC_RST_LEN (1U) +#define MM_MISC_C906_RTC_RST_MSK (((1U << MM_MISC_C906_RTC_RST_LEN) - 1) << MM_MISC_C906_RTC_RST_POS) +#define MM_MISC_C906_RTC_RST_UMSK (~(((1U << MM_MISC_C906_RTC_RST_LEN) - 1) << MM_MISC_C906_RTC_RST_POS)) +#define MM_MISC_C906_RTC_EN MM_MISC_C906_RTC_EN +#define MM_MISC_C906_RTC_EN_POS (31U) +#define MM_MISC_C906_RTC_EN_LEN (1U) +#define MM_MISC_C906_RTC_EN_MSK (((1U << MM_MISC_C906_RTC_EN_LEN) - 1) << MM_MISC_C906_RTC_EN_POS) +#define MM_MISC_C906_RTC_EN_UMSK (~(((1U << MM_MISC_C906_RTC_EN_LEN) - 1) << MM_MISC_C906_RTC_EN_POS)) + +/* 0x1C : tzc_mmsys_misc */ +#define MM_MISC_TZC_MMSYS_MISC_OFFSET (0x1C) +#define MM_MISC_TZC_MM_CPU0_LOCK MM_MISC_TZC_MM_CPU0_LOCK +#define MM_MISC_TZC_MM_CPU0_LOCK_POS (0U) +#define MM_MISC_TZC_MM_CPU0_LOCK_LEN (1U) +#define MM_MISC_TZC_MM_CPU0_LOCK_MSK (((1U << MM_MISC_TZC_MM_CPU0_LOCK_LEN) - 1) << MM_MISC_TZC_MM_CPU0_LOCK_POS) +#define MM_MISC_TZC_MM_CPU0_LOCK_UMSK (~(((1U << MM_MISC_TZC_MM_CPU0_LOCK_LEN) - 1) << MM_MISC_TZC_MM_CPU0_LOCK_POS)) +#define MM_MISC_TZC_MM_SRAM_LOCK MM_MISC_TZC_MM_SRAM_LOCK +#define MM_MISC_TZC_MM_SRAM_LOCK_POS (2U) +#define MM_MISC_TZC_MM_SRAM_LOCK_LEN (1U) +#define MM_MISC_TZC_MM_SRAM_LOCK_MSK (((1U << MM_MISC_TZC_MM_SRAM_LOCK_LEN) - 1) << MM_MISC_TZC_MM_SRAM_LOCK_POS) +#define MM_MISC_TZC_MM_SRAM_LOCK_UMSK (~(((1U << MM_MISC_TZC_MM_SRAM_LOCK_LEN) - 1) << MM_MISC_TZC_MM_SRAM_LOCK_POS)) + +/* 0x20 : peri_apb_ctrl */ +#define MM_MISC_PERI_APB_CTRL_OFFSET (0x20) +#define MM_MISC_REG_MMINFRA_BERR_INT_EN MM_MISC_REG_MMINFRA_BERR_INT_EN +#define MM_MISC_REG_MMINFRA_BERR_INT_EN_POS (0U) +#define MM_MISC_REG_MMINFRA_BERR_INT_EN_LEN (1U) +#define MM_MISC_REG_MMINFRA_BERR_INT_EN_MSK (((1U << MM_MISC_REG_MMINFRA_BERR_INT_EN_LEN) - 1) << MM_MISC_REG_MMINFRA_BERR_INT_EN_POS) +#define MM_MISC_REG_MMINFRA_BERR_INT_EN_UMSK (~(((1U << MM_MISC_REG_MMINFRA_BERR_INT_EN_LEN) - 1) << MM_MISC_REG_MMINFRA_BERR_INT_EN_POS)) +#define MM_MISC_REG_DSP2_BERR_INT_EN MM_MISC_REG_DSP2_BERR_INT_EN +#define MM_MISC_REG_DSP2_BERR_INT_EN_POS (1U) +#define MM_MISC_REG_DSP2_BERR_INT_EN_LEN (1U) +#define MM_MISC_REG_DSP2_BERR_INT_EN_MSK (((1U << MM_MISC_REG_DSP2_BERR_INT_EN_LEN) - 1) << MM_MISC_REG_DSP2_BERR_INT_EN_POS) +#define MM_MISC_REG_DSP2_BERR_INT_EN_UMSK (~(((1U << MM_MISC_REG_DSP2_BERR_INT_EN_LEN) - 1) << MM_MISC_REG_DSP2_BERR_INT_EN_POS)) +#define MM_MISC_REG_CODEC_BERR_INT_EN MM_MISC_REG_CODEC_BERR_INT_EN +#define MM_MISC_REG_CODEC_BERR_INT_EN_POS (2U) +#define MM_MISC_REG_CODEC_BERR_INT_EN_LEN (1U) +#define MM_MISC_REG_CODEC_BERR_INT_EN_MSK (((1U << MM_MISC_REG_CODEC_BERR_INT_EN_LEN) - 1) << MM_MISC_REG_CODEC_BERR_INT_EN_POS) +#define MM_MISC_REG_CODEC_BERR_INT_EN_UMSK (~(((1U << MM_MISC_REG_CODEC_BERR_INT_EN_LEN) - 1) << MM_MISC_REG_CODEC_BERR_INT_EN_POS)) +#define MM_MISC_REG_MMCPU_BERR_INT_EN MM_MISC_REG_MMCPU_BERR_INT_EN +#define MM_MISC_REG_MMCPU_BERR_INT_EN_POS (3U) +#define MM_MISC_REG_MMCPU_BERR_INT_EN_LEN (1U) +#define MM_MISC_REG_MMCPU_BERR_INT_EN_MSK (((1U << MM_MISC_REG_MMCPU_BERR_INT_EN_LEN) - 1) << MM_MISC_REG_MMCPU_BERR_INT_EN_POS) +#define MM_MISC_REG_MMCPU_BERR_INT_EN_UMSK (~(((1U << MM_MISC_REG_MMCPU_BERR_INT_EN_LEN) - 1) << MM_MISC_REG_MMCPU_BERR_INT_EN_POS)) +#define MM_MISC_REG_MM_X2HS_SP_BYPASS MM_MISC_REG_MM_X2HS_SP_BYPASS +#define MM_MISC_REG_MM_X2HS_SP_BYPASS_POS (8U) +#define MM_MISC_REG_MM_X2HS_SP_BYPASS_LEN (1U) +#define MM_MISC_REG_MM_X2HS_SP_BYPASS_MSK (((1U << MM_MISC_REG_MM_X2HS_SP_BYPASS_LEN) - 1) << MM_MISC_REG_MM_X2HS_SP_BYPASS_POS) +#define MM_MISC_REG_MM_X2HS_SP_BYPASS_UMSK (~(((1U << MM_MISC_REG_MM_X2HS_SP_BYPASS_LEN) - 1) << MM_MISC_REG_MM_X2HS_SP_BYPASS_POS)) +#define MM_MISC_RG_PCLK_FORCE_ON MM_MISC_RG_PCLK_FORCE_ON +#define MM_MISC_RG_PCLK_FORCE_ON_POS (16U) +#define MM_MISC_RG_PCLK_FORCE_ON_LEN (16U) +#define MM_MISC_RG_PCLK_FORCE_ON_MSK (((1U << MM_MISC_RG_PCLK_FORCE_ON_LEN) - 1) << MM_MISC_RG_PCLK_FORCE_ON_POS) +#define MM_MISC_RG_PCLK_FORCE_ON_UMSK (~(((1U << MM_MISC_RG_PCLK_FORCE_ON_LEN) - 1) << MM_MISC_RG_PCLK_FORCE_ON_POS)) + +/* 0x2C : mm_infra_qos_ctrl */ +#define MM_MISC_MM_INFRA_QOS_CTRL_OFFSET (0x2C) +#define MM_MISC_REG_MMCPU0_AWQOS MM_MISC_REG_MMCPU0_AWQOS +#define MM_MISC_REG_MMCPU0_AWQOS_POS (2U) +#define MM_MISC_REG_MMCPU0_AWQOS_LEN (1U) +#define MM_MISC_REG_MMCPU0_AWQOS_MSK (((1U << MM_MISC_REG_MMCPU0_AWQOS_LEN) - 1) << MM_MISC_REG_MMCPU0_AWQOS_POS) +#define MM_MISC_REG_MMCPU0_AWQOS_UMSK (~(((1U << MM_MISC_REG_MMCPU0_AWQOS_LEN) - 1) << MM_MISC_REG_MMCPU0_AWQOS_POS)) +#define MM_MISC_REG_MMCPU0_ARQOS MM_MISC_REG_MMCPU0_ARQOS +#define MM_MISC_REG_MMCPU0_ARQOS_POS (3U) +#define MM_MISC_REG_MMCPU0_ARQOS_LEN (1U) +#define MM_MISC_REG_MMCPU0_ARQOS_MSK (((1U << MM_MISC_REG_MMCPU0_ARQOS_LEN) - 1) << MM_MISC_REG_MMCPU0_ARQOS_POS) +#define MM_MISC_REG_MMCPU0_ARQOS_UMSK (~(((1U << MM_MISC_REG_MMCPU0_ARQOS_LEN) - 1) << MM_MISC_REG_MMCPU0_ARQOS_POS)) +#define MM_MISC_REG_H_WTHRE_MM2CONN MM_MISC_REG_H_WTHRE_MM2CONN +#define MM_MISC_REG_H_WTHRE_MM2CONN_POS (16U) +#define MM_MISC_REG_H_WTHRE_MM2CONN_LEN (2U) +#define MM_MISC_REG_H_WTHRE_MM2CONN_MSK (((1U << MM_MISC_REG_H_WTHRE_MM2CONN_LEN) - 1) << MM_MISC_REG_H_WTHRE_MM2CONN_POS) +#define MM_MISC_REG_H_WTHRE_MM2CONN_UMSK (~(((1U << MM_MISC_REG_H_WTHRE_MM2CONN_LEN) - 1) << MM_MISC_REG_H_WTHRE_MM2CONN_POS)) +#define MM_MISC_REG_H_WTHRE_CONN2MM MM_MISC_REG_H_WTHRE_CONN2MM +#define MM_MISC_REG_H_WTHRE_CONN2MM_POS (18U) +#define MM_MISC_REG_H_WTHRE_CONN2MM_LEN (2U) +#define MM_MISC_REG_H_WTHRE_CONN2MM_MSK (((1U << MM_MISC_REG_H_WTHRE_CONN2MM_LEN) - 1) << MM_MISC_REG_H_WTHRE_CONN2MM_POS) +#define MM_MISC_REG_H_WTHRE_CONN2MM_UMSK (~(((1U << MM_MISC_REG_H_WTHRE_CONN2MM_LEN) - 1) << MM_MISC_REG_H_WTHRE_CONN2MM_POS)) +#define MM_MISC_REG_X_WTHRE_MMHW2PA MM_MISC_REG_X_WTHRE_MMHW2PA +#define MM_MISC_REG_X_WTHRE_MMHW2PA_POS (20U) +#define MM_MISC_REG_X_WTHRE_MMHW2PA_LEN (2U) +#define MM_MISC_REG_X_WTHRE_MMHW2PA_MSK (((1U << MM_MISC_REG_X_WTHRE_MMHW2PA_LEN) - 1) << MM_MISC_REG_X_WTHRE_MMHW2PA_POS) +#define MM_MISC_REG_X_WTHRE_MMHW2PA_UMSK (~(((1U << MM_MISC_REG_X_WTHRE_MMHW2PA_LEN) - 1) << MM_MISC_REG_X_WTHRE_MMHW2PA_POS)) +#define MM_MISC_REG_X_WTHRE_MMHW2EXT MM_MISC_REG_X_WTHRE_MMHW2EXT +#define MM_MISC_REG_X_WTHRE_MMHW2EXT_POS (22U) +#define MM_MISC_REG_X_WTHRE_MMHW2EXT_LEN (2U) +#define MM_MISC_REG_X_WTHRE_MMHW2EXT_MSK (((1U << MM_MISC_REG_X_WTHRE_MMHW2EXT_LEN) - 1) << MM_MISC_REG_X_WTHRE_MMHW2EXT_POS) +#define MM_MISC_REG_X_WTHRE_MMHW2EXT_UMSK (~(((1U << MM_MISC_REG_X_WTHRE_MMHW2EXT_LEN) - 1) << MM_MISC_REG_X_WTHRE_MMHW2EXT_POS)) +#define MM_MISC_REG_X_WTHRE_PUHS MM_MISC_REG_X_WTHRE_PUHS +#define MM_MISC_REG_X_WTHRE_PUHS_POS (24U) +#define MM_MISC_REG_X_WTHRE_PUHS_LEN (2U) +#define MM_MISC_REG_X_WTHRE_PUHS_MSK (((1U << MM_MISC_REG_X_WTHRE_PUHS_LEN) - 1) << MM_MISC_REG_X_WTHRE_PUHS_POS) +#define MM_MISC_REG_X_WTHRE_PUHS_UMSK (~(((1U << MM_MISC_REG_X_WTHRE_PUHS_LEN) - 1) << MM_MISC_REG_X_WTHRE_PUHS_POS)) + +/* 0x40 : dma_clk_ctrl */ +#define MM_MISC_DMA_CLK_CTRL_OFFSET (0x40) +#define MM_MISC_DMA_CLK_EN MM_MISC_DMA_CLK_EN +#define MM_MISC_DMA_CLK_EN_POS (0U) +#define MM_MISC_DMA_CLK_EN_LEN (8U) +#define MM_MISC_DMA_CLK_EN_MSK (((1U << MM_MISC_DMA_CLK_EN_LEN) - 1) << MM_MISC_DMA_CLK_EN_POS) +#define MM_MISC_DMA_CLK_EN_UMSK (~(((1U << MM_MISC_DMA_CLK_EN_LEN) - 1) << MM_MISC_DMA_CLK_EN_POS)) + +/* 0x50 : vram_ctrl */ +#define MM_MISC_VRAM_CTRL_OFFSET (0x50) +#define MM_MISC_REG_SYSRAM_SET MM_MISC_REG_SYSRAM_SET +#define MM_MISC_REG_SYSRAM_SET_POS (0U) +#define MM_MISC_REG_SYSRAM_SET_LEN (1U) +#define MM_MISC_REG_SYSRAM_SET_MSK (((1U << MM_MISC_REG_SYSRAM_SET_LEN) - 1) << MM_MISC_REG_SYSRAM_SET_POS) +#define MM_MISC_REG_SYSRAM_SET_UMSK (~(((1U << MM_MISC_REG_SYSRAM_SET_LEN) - 1) << MM_MISC_REG_SYSRAM_SET_POS)) +#define MM_MISC_REG_H2PF_SRAM_REL MM_MISC_REG_H2PF_SRAM_REL +#define MM_MISC_REG_H2PF_SRAM_REL_POS (1U) +#define MM_MISC_REG_H2PF_SRAM_REL_LEN (2U) +#define MM_MISC_REG_H2PF_SRAM_REL_MSK (((1U << MM_MISC_REG_H2PF_SRAM_REL_LEN) - 1) << MM_MISC_REG_H2PF_SRAM_REL_POS) +#define MM_MISC_REG_H2PF_SRAM_REL_UMSK (~(((1U << MM_MISC_REG_H2PF_SRAM_REL_LEN) - 1) << MM_MISC_REG_H2PF_SRAM_REL_POS)) +#define MM_MISC_REG_VRAM_SRAM_REL MM_MISC_REG_VRAM_SRAM_REL +#define MM_MISC_REG_VRAM_SRAM_REL_POS (4U) +#define MM_MISC_REG_VRAM_SRAM_REL_LEN (1U) +#define MM_MISC_REG_VRAM_SRAM_REL_MSK (((1U << MM_MISC_REG_VRAM_SRAM_REL_LEN) - 1) << MM_MISC_REG_VRAM_SRAM_REL_POS) +#define MM_MISC_REG_VRAM_SRAM_REL_UMSK (~(((1U << MM_MISC_REG_VRAM_SRAM_REL_LEN) - 1) << MM_MISC_REG_VRAM_SRAM_REL_POS)) +#define MM_MISC_REG_DSPL2_SRAM_REL MM_MISC_REG_DSPL2_SRAM_REL +#define MM_MISC_REG_DSPL2_SRAM_REL_POS (6U) +#define MM_MISC_REG_DSPL2_SRAM_REL_LEN (1U) +#define MM_MISC_REG_DSPL2_SRAM_REL_MSK (((1U << MM_MISC_REG_DSPL2_SRAM_REL_LEN) - 1) << MM_MISC_REG_DSPL2_SRAM_REL_POS) +#define MM_MISC_REG_DSPL2_SRAM_REL_UMSK (~(((1U << MM_MISC_REG_DSPL2_SRAM_REL_LEN) - 1) << MM_MISC_REG_DSPL2_SRAM_REL_POS)) +#define MM_MISC_REG_BLAI_SRAM_REL MM_MISC_REG_BLAI_SRAM_REL +#define MM_MISC_REG_BLAI_SRAM_REL_POS (7U) +#define MM_MISC_REG_BLAI_SRAM_REL_LEN (1U) +#define MM_MISC_REG_BLAI_SRAM_REL_MSK (((1U << MM_MISC_REG_BLAI_SRAM_REL_LEN) - 1) << MM_MISC_REG_BLAI_SRAM_REL_POS) +#define MM_MISC_REG_BLAI_SRAM_REL_UMSK (~(((1U << MM_MISC_REG_BLAI_SRAM_REL_LEN) - 1) << MM_MISC_REG_BLAI_SRAM_REL_POS)) +#define MM_MISC_REG_H2PF_SRAM_SEL MM_MISC_REG_H2PF_SRAM_SEL +#define MM_MISC_REG_H2PF_SRAM_SEL_POS (8U) +#define MM_MISC_REG_H2PF_SRAM_SEL_LEN (3U) +#define MM_MISC_REG_H2PF_SRAM_SEL_MSK (((1U << MM_MISC_REG_H2PF_SRAM_SEL_LEN) - 1) << MM_MISC_REG_H2PF_SRAM_SEL_POS) +#define MM_MISC_REG_H2PF_SRAM_SEL_UMSK (~(((1U << MM_MISC_REG_H2PF_SRAM_SEL_LEN) - 1) << MM_MISC_REG_H2PF_SRAM_SEL_POS)) +#define MM_MISC_REG_VRAM_SRAM_SEL MM_MISC_REG_VRAM_SRAM_SEL +#define MM_MISC_REG_VRAM_SRAM_SEL_POS (12U) +#define MM_MISC_REG_VRAM_SRAM_SEL_LEN (1U) +#define MM_MISC_REG_VRAM_SRAM_SEL_MSK (((1U << MM_MISC_REG_VRAM_SRAM_SEL_LEN) - 1) << MM_MISC_REG_VRAM_SRAM_SEL_POS) +#define MM_MISC_REG_VRAM_SRAM_SEL_UMSK (~(((1U << MM_MISC_REG_VRAM_SRAM_SEL_LEN) - 1) << MM_MISC_REG_VRAM_SRAM_SEL_POS)) +#define MM_MISC_REG_DSPL2_SRAM_SEL MM_MISC_REG_DSPL2_SRAM_SEL +#define MM_MISC_REG_DSPL2_SRAM_SEL_POS (14U) +#define MM_MISC_REG_DSPL2_SRAM_SEL_LEN (1U) +#define MM_MISC_REG_DSPL2_SRAM_SEL_MSK (((1U << MM_MISC_REG_DSPL2_SRAM_SEL_LEN) - 1) << MM_MISC_REG_DSPL2_SRAM_SEL_POS) +#define MM_MISC_REG_DSPL2_SRAM_SEL_UMSK (~(((1U << MM_MISC_REG_DSPL2_SRAM_SEL_LEN) - 1) << MM_MISC_REG_DSPL2_SRAM_SEL_POS)) +#define MM_MISC_REG_BLAI_SRAM_SEL MM_MISC_REG_BLAI_SRAM_SEL +#define MM_MISC_REG_BLAI_SRAM_SEL_POS (15U) +#define MM_MISC_REG_BLAI_SRAM_SEL_LEN (1U) +#define MM_MISC_REG_BLAI_SRAM_SEL_MSK (((1U << MM_MISC_REG_BLAI_SRAM_SEL_LEN) - 1) << MM_MISC_REG_BLAI_SRAM_SEL_POS) +#define MM_MISC_REG_BLAI_SRAM_SEL_UMSK (~(((1U << MM_MISC_REG_BLAI_SRAM_SEL_LEN) - 1) << MM_MISC_REG_BLAI_SRAM_SEL_POS)) + +/* 0x60 : sram_parm */ +#define MM_MISC_SRAM_PARM_OFFSET (0x60) +#define MM_MISC_REG_SRAM_CPU_RAM_DVS MM_MISC_REG_SRAM_CPU_RAM_DVS +#define MM_MISC_REG_SRAM_CPU_RAM_DVS_POS (0U) +#define MM_MISC_REG_SRAM_CPU_RAM_DVS_LEN (4U) +#define MM_MISC_REG_SRAM_CPU_RAM_DVS_MSK (((1U << MM_MISC_REG_SRAM_CPU_RAM_DVS_LEN) - 1) << MM_MISC_REG_SRAM_CPU_RAM_DVS_POS) +#define MM_MISC_REG_SRAM_CPU_RAM_DVS_UMSK (~(((1U << MM_MISC_REG_SRAM_CPU_RAM_DVS_LEN) - 1) << MM_MISC_REG_SRAM_CPU_RAM_DVS_POS)) +#define MM_MISC_REG_SRAM_CPU_RAM_DVSE MM_MISC_REG_SRAM_CPU_RAM_DVSE +#define MM_MISC_REG_SRAM_CPU_RAM_DVSE_POS (4U) +#define MM_MISC_REG_SRAM_CPU_RAM_DVSE_LEN (1U) +#define MM_MISC_REG_SRAM_CPU_RAM_DVSE_MSK (((1U << MM_MISC_REG_SRAM_CPU_RAM_DVSE_LEN) - 1) << MM_MISC_REG_SRAM_CPU_RAM_DVSE_POS) +#define MM_MISC_REG_SRAM_CPU_RAM_DVSE_UMSK (~(((1U << MM_MISC_REG_SRAM_CPU_RAM_DVSE_LEN) - 1) << MM_MISC_REG_SRAM_CPU_RAM_DVSE_POS)) +#define MM_MISC_REG_SRAM_CPU_RAM_NAP MM_MISC_REG_SRAM_CPU_RAM_NAP +#define MM_MISC_REG_SRAM_CPU_RAM_NAP_POS (5U) +#define MM_MISC_REG_SRAM_CPU_RAM_NAP_LEN (1U) +#define MM_MISC_REG_SRAM_CPU_RAM_NAP_MSK (((1U << MM_MISC_REG_SRAM_CPU_RAM_NAP_LEN) - 1) << MM_MISC_REG_SRAM_CPU_RAM_NAP_POS) +#define MM_MISC_REG_SRAM_CPU_RAM_NAP_UMSK (~(((1U << MM_MISC_REG_SRAM_CPU_RAM_NAP_LEN) - 1) << MM_MISC_REG_SRAM_CPU_RAM_NAP_POS)) +#define MM_MISC_REG_SRAM_L2RAM_DVS MM_MISC_REG_SRAM_L2RAM_DVS +#define MM_MISC_REG_SRAM_L2RAM_DVS_POS (8U) +#define MM_MISC_REG_SRAM_L2RAM_DVS_LEN (4U) +#define MM_MISC_REG_SRAM_L2RAM_DVS_MSK (((1U << MM_MISC_REG_SRAM_L2RAM_DVS_LEN) - 1) << MM_MISC_REG_SRAM_L2RAM_DVS_POS) +#define MM_MISC_REG_SRAM_L2RAM_DVS_UMSK (~(((1U << MM_MISC_REG_SRAM_L2RAM_DVS_LEN) - 1) << MM_MISC_REG_SRAM_L2RAM_DVS_POS)) +#define MM_MISC_REG_SRAM_L2RAM_DVSE MM_MISC_REG_SRAM_L2RAM_DVSE +#define MM_MISC_REG_SRAM_L2RAM_DVSE_POS (12U) +#define MM_MISC_REG_SRAM_L2RAM_DVSE_LEN (1U) +#define MM_MISC_REG_SRAM_L2RAM_DVSE_MSK (((1U << MM_MISC_REG_SRAM_L2RAM_DVSE_LEN) - 1) << MM_MISC_REG_SRAM_L2RAM_DVSE_POS) +#define MM_MISC_REG_SRAM_L2RAM_DVSE_UMSK (~(((1U << MM_MISC_REG_SRAM_L2RAM_DVSE_LEN) - 1) << MM_MISC_REG_SRAM_L2RAM_DVSE_POS)) +#define MM_MISC_REG_SRAM_L2RAM_NAP MM_MISC_REG_SRAM_L2RAM_NAP +#define MM_MISC_REG_SRAM_L2RAM_NAP_POS (13U) +#define MM_MISC_REG_SRAM_L2RAM_NAP_LEN (1U) +#define MM_MISC_REG_SRAM_L2RAM_NAP_MSK (((1U << MM_MISC_REG_SRAM_L2RAM_NAP_LEN) - 1) << MM_MISC_REG_SRAM_L2RAM_NAP_POS) +#define MM_MISC_REG_SRAM_L2RAM_NAP_UMSK (~(((1U << MM_MISC_REG_SRAM_L2RAM_NAP_LEN) - 1) << MM_MISC_REG_SRAM_L2RAM_NAP_POS)) +#define MM_MISC_REG_SRAM_CDC_RAM_DVS MM_MISC_REG_SRAM_CDC_RAM_DVS +#define MM_MISC_REG_SRAM_CDC_RAM_DVS_POS (16U) +#define MM_MISC_REG_SRAM_CDC_RAM_DVS_LEN (4U) +#define MM_MISC_REG_SRAM_CDC_RAM_DVS_MSK (((1U << MM_MISC_REG_SRAM_CDC_RAM_DVS_LEN) - 1) << MM_MISC_REG_SRAM_CDC_RAM_DVS_POS) +#define MM_MISC_REG_SRAM_CDC_RAM_DVS_UMSK (~(((1U << MM_MISC_REG_SRAM_CDC_RAM_DVS_LEN) - 1) << MM_MISC_REG_SRAM_CDC_RAM_DVS_POS)) +#define MM_MISC_REG_SRAM_CDC_RAM_DVSE MM_MISC_REG_SRAM_CDC_RAM_DVSE +#define MM_MISC_REG_SRAM_CDC_RAM_DVSE_POS (20U) +#define MM_MISC_REG_SRAM_CDC_RAM_DVSE_LEN (1U) +#define MM_MISC_REG_SRAM_CDC_RAM_DVSE_MSK (((1U << MM_MISC_REG_SRAM_CDC_RAM_DVSE_LEN) - 1) << MM_MISC_REG_SRAM_CDC_RAM_DVSE_POS) +#define MM_MISC_REG_SRAM_CDC_RAM_DVSE_UMSK (~(((1U << MM_MISC_REG_SRAM_CDC_RAM_DVSE_LEN) - 1) << MM_MISC_REG_SRAM_CDC_RAM_DVSE_POS)) +#define MM_MISC_REG_SRAM_CDC_RAM_NAP MM_MISC_REG_SRAM_CDC_RAM_NAP +#define MM_MISC_REG_SRAM_CDC_RAM_NAP_POS (21U) +#define MM_MISC_REG_SRAM_CDC_RAM_NAP_LEN (1U) +#define MM_MISC_REG_SRAM_CDC_RAM_NAP_MSK (((1U << MM_MISC_REG_SRAM_CDC_RAM_NAP_LEN) - 1) << MM_MISC_REG_SRAM_CDC_RAM_NAP_POS) +#define MM_MISC_REG_SRAM_CDC_RAM_NAP_UMSK (~(((1U << MM_MISC_REG_SRAM_CDC_RAM_NAP_LEN) - 1) << MM_MISC_REG_SRAM_CDC_RAM_NAP_POS)) +#define MM_MISC_REG_SRAM_DSP2_RAM_DVS MM_MISC_REG_SRAM_DSP2_RAM_DVS +#define MM_MISC_REG_SRAM_DSP2_RAM_DVS_POS (24U) +#define MM_MISC_REG_SRAM_DSP2_RAM_DVS_LEN (4U) +#define MM_MISC_REG_SRAM_DSP2_RAM_DVS_MSK (((1U << MM_MISC_REG_SRAM_DSP2_RAM_DVS_LEN) - 1) << MM_MISC_REG_SRAM_DSP2_RAM_DVS_POS) +#define MM_MISC_REG_SRAM_DSP2_RAM_DVS_UMSK (~(((1U << MM_MISC_REG_SRAM_DSP2_RAM_DVS_LEN) - 1) << MM_MISC_REG_SRAM_DSP2_RAM_DVS_POS)) +#define MM_MISC_REG_SRAM_DSP2_RAM_DVSE MM_MISC_REG_SRAM_DSP2_RAM_DVSE +#define MM_MISC_REG_SRAM_DSP2_RAM_DVSE_POS (28U) +#define MM_MISC_REG_SRAM_DSP2_RAM_DVSE_LEN (1U) +#define MM_MISC_REG_SRAM_DSP2_RAM_DVSE_MSK (((1U << MM_MISC_REG_SRAM_DSP2_RAM_DVSE_LEN) - 1) << MM_MISC_REG_SRAM_DSP2_RAM_DVSE_POS) +#define MM_MISC_REG_SRAM_DSP2_RAM_DVSE_UMSK (~(((1U << MM_MISC_REG_SRAM_DSP2_RAM_DVSE_LEN) - 1) << MM_MISC_REG_SRAM_DSP2_RAM_DVSE_POS)) +#define MM_MISC_REG_SRAM_DSP2_RAM_NAP MM_MISC_REG_SRAM_DSP2_RAM_NAP +#define MM_MISC_REG_SRAM_DSP2_RAM_NAP_POS (29U) +#define MM_MISC_REG_SRAM_DSP2_RAM_NAP_LEN (1U) +#define MM_MISC_REG_SRAM_DSP2_RAM_NAP_MSK (((1U << MM_MISC_REG_SRAM_DSP2_RAM_NAP_LEN) - 1) << MM_MISC_REG_SRAM_DSP2_RAM_NAP_POS) +#define MM_MISC_REG_SRAM_DSP2_RAM_NAP_UMSK (~(((1U << MM_MISC_REG_SRAM_DSP2_RAM_NAP_LEN) - 1) << MM_MISC_REG_SRAM_DSP2_RAM_NAP_POS)) + +/* 0xA0 : MM_INT_STA0 */ +#define MM_MISC_MM_INT_STA0_OFFSET (0xA0) +#define MM_MISC_MM_INT_STA0 MM_MISC_MM_INT_STA0 +#define MM_MISC_MM_INT_STA0_POS (0U) +#define MM_MISC_MM_INT_STA0_LEN (32U) +#define MM_MISC_MM_INT_STA0_MSK (((1U << MM_MISC_MM_INT_STA0_LEN) - 1) << MM_MISC_MM_INT_STA0_POS) +#define MM_MISC_MM_INT_STA0_UMSK (~(((1U << MM_MISC_MM_INT_STA0_LEN) - 1) << MM_MISC_MM_INT_STA0_POS)) + +/* 0xA4 : MM_INT_MASK0 */ +#define MM_MISC_MM_INT_MASK0_OFFSET (0xA4) +#define MM_MISC_MM_INT_MASK0 MM_MISC_MM_INT_MASK0 +#define MM_MISC_MM_INT_MASK0_POS (0U) +#define MM_MISC_MM_INT_MASK0_LEN (32U) +#define MM_MISC_MM_INT_MASK0_MSK (((1U << MM_MISC_MM_INT_MASK0_LEN) - 1) << MM_MISC_MM_INT_MASK0_POS) +#define MM_MISC_MM_INT_MASK0_UMSK (~(((1U << MM_MISC_MM_INT_MASK0_LEN) - 1) << MM_MISC_MM_INT_MASK0_POS)) + +/* 0xA8 : MM_INT_CLR_0 */ +#define MM_MISC_MM_INT_CLR_0_OFFSET (0xA8) +#define MM_MISC_MM_INT_CLR0 MM_MISC_MM_INT_CLR0 +#define MM_MISC_MM_INT_CLR0_POS (0U) +#define MM_MISC_MM_INT_CLR0_LEN (32U) +#define MM_MISC_MM_INT_CLR0_MSK (((1U << MM_MISC_MM_INT_CLR0_LEN) - 1) << MM_MISC_MM_INT_CLR0_POS) +#define MM_MISC_MM_INT_CLR0_UMSK (~(((1U << MM_MISC_MM_INT_CLR0_LEN) - 1) << MM_MISC_MM_INT_CLR0_POS)) + +/* 0xAC : MM_INT_STA1 */ +#define MM_MISC_MM_INT_STA1_OFFSET (0xAC) +#define MM_MISC_MM_INT_STA1 MM_MISC_MM_INT_STA1 +#define MM_MISC_MM_INT_STA1_POS (0U) +#define MM_MISC_MM_INT_STA1_LEN (32U) +#define MM_MISC_MM_INT_STA1_MSK (((1U << MM_MISC_MM_INT_STA1_LEN) - 1) << MM_MISC_MM_INT_STA1_POS) +#define MM_MISC_MM_INT_STA1_UMSK (~(((1U << MM_MISC_MM_INT_STA1_LEN) - 1) << MM_MISC_MM_INT_STA1_POS)) + +/* 0xB0 : MM_INT_MASK1 */ +#define MM_MISC_MM_INT_MASK1_OFFSET (0xB0) +#define MM_MISC_MM_INT_MASK1 MM_MISC_MM_INT_MASK1 +#define MM_MISC_MM_INT_MASK1_POS (0U) +#define MM_MISC_MM_INT_MASK1_LEN (32U) +#define MM_MISC_MM_INT_MASK1_MSK (((1U << MM_MISC_MM_INT_MASK1_LEN) - 1) << MM_MISC_MM_INT_MASK1_POS) +#define MM_MISC_MM_INT_MASK1_UMSK (~(((1U << MM_MISC_MM_INT_MASK1_LEN) - 1) << MM_MISC_MM_INT_MASK1_POS)) + +/* 0xB4 : MM_INT_CLR_1 */ +#define MM_MISC_MM_INT_CLR_1_OFFSET (0xB4) +#define MM_MISC_MM_INT_CLR1 MM_MISC_MM_INT_CLR1 +#define MM_MISC_MM_INT_CLR1_POS (0U) +#define MM_MISC_MM_INT_CLR1_LEN (32U) +#define MM_MISC_MM_INT_CLR1_MSK (((1U << MM_MISC_MM_INT_CLR1_LEN) - 1) << MM_MISC_MM_INT_CLR1_POS) +#define MM_MISC_MM_INT_CLR1_UMSK (~(((1U << MM_MISC_MM_INT_CLR1_LEN) - 1) << MM_MISC_MM_INT_CLR1_POS)) + +/* 0xF0 : mmsys_debug_sel */ +#define MM_MISC_MMSYS_DEBUG_SEL_OFFSET (0xF0) +#define MM_MISC_MMSYS_DEBUG_SEL MM_MISC_MMSYS_DEBUG_SEL +#define MM_MISC_MMSYS_DEBUG_SEL_POS (0U) +#define MM_MISC_MMSYS_DEBUG_SEL_LEN (4U) +#define MM_MISC_MMSYS_DEBUG_SEL_MSK (((1U << MM_MISC_MMSYS_DEBUG_SEL_LEN) - 1) << MM_MISC_MMSYS_DEBUG_SEL_POS) +#define MM_MISC_MMSYS_DEBUG_SEL_UMSK (~(((1U << MM_MISC_MMSYS_DEBUG_SEL_LEN) - 1) << MM_MISC_MMSYS_DEBUG_SEL_POS)) + +/* 0xFC : mmsys_misc_dummy */ +#define MM_MISC_MMSYS_MISC_DUMMY_OFFSET (0xFC) +#define MM_MISC_PIR_CTRL_O MM_MISC_PIR_CTRL_O +#define MM_MISC_PIR_CTRL_O_POS (0U) +#define MM_MISC_PIR_CTRL_O_LEN (1U) +#define MM_MISC_PIR_CTRL_O_MSK (((1U << MM_MISC_PIR_CTRL_O_LEN) - 1) << MM_MISC_PIR_CTRL_O_POS) +#define MM_MISC_PIR_CTRL_O_UMSK (~(((1U << MM_MISC_PIR_CTRL_O_LEN) - 1) << MM_MISC_PIR_CTRL_O_POS)) +#define MM_MISC_LIGHT_SENSOR_CTRL_O MM_MISC_LIGHT_SENSOR_CTRL_O +#define MM_MISC_LIGHT_SENSOR_CTRL_O_POS (1U) +#define MM_MISC_LIGHT_SENSOR_CTRL_O_LEN (1U) +#define MM_MISC_LIGHT_SENSOR_CTRL_O_MSK (((1U << MM_MISC_LIGHT_SENSOR_CTRL_O_LEN) - 1) << MM_MISC_LIGHT_SENSOR_CTRL_O_POS) +#define MM_MISC_LIGHT_SENSOR_CTRL_O_UMSK (~(((1U << MM_MISC_LIGHT_SENSOR_CTRL_O_LEN) - 1) << MM_MISC_LIGHT_SENSOR_CTRL_O_POS)) +#define MM_MISC_IR_CUT_CTRL_O MM_MISC_IR_CUT_CTRL_O +#define MM_MISC_IR_CUT_CTRL_O_POS (2U) +#define MM_MISC_IR_CUT_CTRL_O_LEN (1U) +#define MM_MISC_IR_CUT_CTRL_O_MSK (((1U << MM_MISC_IR_CUT_CTRL_O_LEN) - 1) << MM_MISC_IR_CUT_CTRL_O_POS) +#define MM_MISC_IR_CUT_CTRL_O_UMSK (~(((1U << MM_MISC_IR_CUT_CTRL_O_LEN) - 1) << MM_MISC_IR_CUT_CTRL_O_POS)) +#define MM_MISC_DVP_SENSOR_PWDN MM_MISC_DVP_SENSOR_PWDN +#define MM_MISC_DVP_SENSOR_PWDN_POS (3U) +#define MM_MISC_DVP_SENSOR_PWDN_LEN (1U) +#define MM_MISC_DVP_SENSOR_PWDN_MSK (((1U << MM_MISC_DVP_SENSOR_PWDN_LEN) - 1) << MM_MISC_DVP_SENSOR_PWDN_POS) +#define MM_MISC_DVP_SENSOR_PWDN_UMSK (~(((1U << MM_MISC_DVP_SENSOR_PWDN_LEN) - 1) << MM_MISC_DVP_SENSOR_PWDN_POS)) +#define MM_MISC_DUMMY_REG MM_MISC_DUMMY_REG +#define MM_MISC_DUMMY_REG_POS (4U) +#define MM_MISC_DUMMY_REG_LEN (28U) +#define MM_MISC_DUMMY_REG_MSK (((1U << MM_MISC_DUMMY_REG_LEN) - 1) << MM_MISC_DUMMY_REG_POS) +#define MM_MISC_DUMMY_REG_UMSK (~(((1U << MM_MISC_DUMMY_REG_LEN) - 1) << MM_MISC_DUMMY_REG_POS)) + +/* 0x100 : DDR_debug */ +#define MM_MISC_DDR_DEBUG_OFFSET (0x100) +#define MM_MISC_DDR_CALIB_DONE MM_MISC_DDR_CALIB_DONE +#define MM_MISC_DDR_CALIB_DONE_POS (0U) +#define MM_MISC_DDR_CALIB_DONE_LEN (1U) +#define MM_MISC_DDR_CALIB_DONE_MSK (((1U << MM_MISC_DDR_CALIB_DONE_LEN) - 1) << MM_MISC_DDR_CALIB_DONE_POS) +#define MM_MISC_DDR_CALIB_DONE_UMSK (~(((1U << MM_MISC_DDR_CALIB_DONE_LEN) - 1) << MM_MISC_DDR_CALIB_DONE_POS)) + +/* 0x140 : mm_berr_cfg0 */ +#define MM_MISC_MM_BERR_CFG0_OFFSET (0x140) +#define MM_MISC_REG_DSP2_BERR_EN MM_MISC_REG_DSP2_BERR_EN +#define MM_MISC_REG_DSP2_BERR_EN_POS (0U) +#define MM_MISC_REG_DSP2_BERR_EN_LEN (3U) +#define MM_MISC_REG_DSP2_BERR_EN_MSK (((1U << MM_MISC_REG_DSP2_BERR_EN_LEN) - 1) << MM_MISC_REG_DSP2_BERR_EN_POS) +#define MM_MISC_REG_DSP2_BERR_EN_UMSK (~(((1U << MM_MISC_REG_DSP2_BERR_EN_LEN) - 1) << MM_MISC_REG_DSP2_BERR_EN_POS)) +#define MM_MISC_REG_CODEC_BERR_EN MM_MISC_REG_CODEC_BERR_EN +#define MM_MISC_REG_CODEC_BERR_EN_POS (8U) +#define MM_MISC_REG_CODEC_BERR_EN_LEN (3U) +#define MM_MISC_REG_CODEC_BERR_EN_MSK (((1U << MM_MISC_REG_CODEC_BERR_EN_LEN) - 1) << MM_MISC_REG_CODEC_BERR_EN_POS) +#define MM_MISC_REG_CODEC_BERR_EN_UMSK (~(((1U << MM_MISC_REG_CODEC_BERR_EN_LEN) - 1) << MM_MISC_REG_CODEC_BERR_EN_POS)) +#define MM_MISC_REG_MMCPU_BERR_EN MM_MISC_REG_MMCPU_BERR_EN +#define MM_MISC_REG_MMCPU_BERR_EN_POS (16U) +#define MM_MISC_REG_MMCPU_BERR_EN_LEN (1U) +#define MM_MISC_REG_MMCPU_BERR_EN_MSK (((1U << MM_MISC_REG_MMCPU_BERR_EN_LEN) - 1) << MM_MISC_REG_MMCPU_BERR_EN_POS) +#define MM_MISC_REG_MMCPU_BERR_EN_UMSK (~(((1U << MM_MISC_REG_MMCPU_BERR_EN_LEN) - 1) << MM_MISC_REG_MMCPU_BERR_EN_POS)) +#define MM_MISC_REG_MMINFRA_BERR_EN MM_MISC_REG_MMINFRA_BERR_EN +#define MM_MISC_REG_MMINFRA_BERR_EN_POS (24U) +#define MM_MISC_REG_MMINFRA_BERR_EN_LEN (5U) +#define MM_MISC_REG_MMINFRA_BERR_EN_MSK (((1U << MM_MISC_REG_MMINFRA_BERR_EN_LEN) - 1) << MM_MISC_REG_MMINFRA_BERR_EN_POS) +#define MM_MISC_REG_MMINFRA_BERR_EN_UMSK (~(((1U << MM_MISC_REG_MMINFRA_BERR_EN_LEN) - 1) << MM_MISC_REG_MMINFRA_BERR_EN_POS)) + +/* 0x144 : mm_berr_cfg1 */ +#define MM_MISC_MM_BERR_CFG1_OFFSET (0x144) +#define MM_MISC_REG_DSP2_BERR_CLR MM_MISC_REG_DSP2_BERR_CLR +#define MM_MISC_REG_DSP2_BERR_CLR_POS (0U) +#define MM_MISC_REG_DSP2_BERR_CLR_LEN (1U) +#define MM_MISC_REG_DSP2_BERR_CLR_MSK (((1U << MM_MISC_REG_DSP2_BERR_CLR_LEN) - 1) << MM_MISC_REG_DSP2_BERR_CLR_POS) +#define MM_MISC_REG_DSP2_BERR_CLR_UMSK (~(((1U << MM_MISC_REG_DSP2_BERR_CLR_LEN) - 1) << MM_MISC_REG_DSP2_BERR_CLR_POS)) +#define MM_MISC_REG_CODEC_BERR_CLR MM_MISC_REG_CODEC_BERR_CLR +#define MM_MISC_REG_CODEC_BERR_CLR_POS (1U) +#define MM_MISC_REG_CODEC_BERR_CLR_LEN (1U) +#define MM_MISC_REG_CODEC_BERR_CLR_MSK (((1U << MM_MISC_REG_CODEC_BERR_CLR_LEN) - 1) << MM_MISC_REG_CODEC_BERR_CLR_POS) +#define MM_MISC_REG_CODEC_BERR_CLR_UMSK (~(((1U << MM_MISC_REG_CODEC_BERR_CLR_LEN) - 1) << MM_MISC_REG_CODEC_BERR_CLR_POS)) +#define MM_MISC_REG_MMCPU_BERR_CLR MM_MISC_REG_MMCPU_BERR_CLR +#define MM_MISC_REG_MMCPU_BERR_CLR_POS (2U) +#define MM_MISC_REG_MMCPU_BERR_CLR_LEN (1U) +#define MM_MISC_REG_MMCPU_BERR_CLR_MSK (((1U << MM_MISC_REG_MMCPU_BERR_CLR_LEN) - 1) << MM_MISC_REG_MMCPU_BERR_CLR_POS) +#define MM_MISC_REG_MMCPU_BERR_CLR_UMSK (~(((1U << MM_MISC_REG_MMCPU_BERR_CLR_LEN) - 1) << MM_MISC_REG_MMCPU_BERR_CLR_POS)) +#define MM_MISC_REG_MMINFRA_BERR_CLR MM_MISC_REG_MMINFRA_BERR_CLR +#define MM_MISC_REG_MMINFRA_BERR_CLR_POS (3U) +#define MM_MISC_REG_MMINFRA_BERR_CLR_LEN (1U) +#define MM_MISC_REG_MMINFRA_BERR_CLR_MSK (((1U << MM_MISC_REG_MMINFRA_BERR_CLR_LEN) - 1) << MM_MISC_REG_MMINFRA_BERR_CLR_POS) +#define MM_MISC_REG_MMINFRA_BERR_CLR_UMSK (~(((1U << MM_MISC_REG_MMINFRA_BERR_CLR_LEN) - 1) << MM_MISC_REG_MMINFRA_BERR_CLR_POS)) +#define MM_MISC_REG_DSP2_BERR_LAST MM_MISC_REG_DSP2_BERR_LAST +#define MM_MISC_REG_DSP2_BERR_LAST_POS (8U) +#define MM_MISC_REG_DSP2_BERR_LAST_LEN (1U) +#define MM_MISC_REG_DSP2_BERR_LAST_MSK (((1U << MM_MISC_REG_DSP2_BERR_LAST_LEN) - 1) << MM_MISC_REG_DSP2_BERR_LAST_POS) +#define MM_MISC_REG_DSP2_BERR_LAST_UMSK (~(((1U << MM_MISC_REG_DSP2_BERR_LAST_LEN) - 1) << MM_MISC_REG_DSP2_BERR_LAST_POS)) +#define MM_MISC_REG_CODEC_BERR_LAST MM_MISC_REG_CODEC_BERR_LAST +#define MM_MISC_REG_CODEC_BERR_LAST_POS (9U) +#define MM_MISC_REG_CODEC_BERR_LAST_LEN (1U) +#define MM_MISC_REG_CODEC_BERR_LAST_MSK (((1U << MM_MISC_REG_CODEC_BERR_LAST_LEN) - 1) << MM_MISC_REG_CODEC_BERR_LAST_POS) +#define MM_MISC_REG_CODEC_BERR_LAST_UMSK (~(((1U << MM_MISC_REG_CODEC_BERR_LAST_LEN) - 1) << MM_MISC_REG_CODEC_BERR_LAST_POS)) +#define MM_MISC_REG_MMCPU_BERR_LAST MM_MISC_REG_MMCPU_BERR_LAST +#define MM_MISC_REG_MMCPU_BERR_LAST_POS (10U) +#define MM_MISC_REG_MMCPU_BERR_LAST_LEN (1U) +#define MM_MISC_REG_MMCPU_BERR_LAST_MSK (((1U << MM_MISC_REG_MMCPU_BERR_LAST_LEN) - 1) << MM_MISC_REG_MMCPU_BERR_LAST_POS) +#define MM_MISC_REG_MMCPU_BERR_LAST_UMSK (~(((1U << MM_MISC_REG_MMCPU_BERR_LAST_LEN) - 1) << MM_MISC_REG_MMCPU_BERR_LAST_POS)) +#define MM_MISC_REG_MMINFRA_BERR_LAST MM_MISC_REG_MMINFRA_BERR_LAST +#define MM_MISC_REG_MMINFRA_BERR_LAST_POS (11U) +#define MM_MISC_REG_MMINFRA_BERR_LAST_LEN (1U) +#define MM_MISC_REG_MMINFRA_BERR_LAST_MSK (((1U << MM_MISC_REG_MMINFRA_BERR_LAST_LEN) - 1) << MM_MISC_REG_MMINFRA_BERR_LAST_POS) +#define MM_MISC_REG_MMINFRA_BERR_LAST_UMSK (~(((1U << MM_MISC_REG_MMINFRA_BERR_LAST_LEN) - 1) << MM_MISC_REG_MMINFRA_BERR_LAST_POS)) +#define MM_MISC_STS_DSP2_BERR MM_MISC_STS_DSP2_BERR +#define MM_MISC_STS_DSP2_BERR_POS (16U) +#define MM_MISC_STS_DSP2_BERR_LEN (1U) +#define MM_MISC_STS_DSP2_BERR_MSK (((1U << MM_MISC_STS_DSP2_BERR_LEN) - 1) << MM_MISC_STS_DSP2_BERR_POS) +#define MM_MISC_STS_DSP2_BERR_UMSK (~(((1U << MM_MISC_STS_DSP2_BERR_LEN) - 1) << MM_MISC_STS_DSP2_BERR_POS)) +#define MM_MISC_STS_CODEC_BERR MM_MISC_STS_CODEC_BERR +#define MM_MISC_STS_CODEC_BERR_POS (17U) +#define MM_MISC_STS_CODEC_BERR_LEN (1U) +#define MM_MISC_STS_CODEC_BERR_MSK (((1U << MM_MISC_STS_CODEC_BERR_LEN) - 1) << MM_MISC_STS_CODEC_BERR_POS) +#define MM_MISC_STS_CODEC_BERR_UMSK (~(((1U << MM_MISC_STS_CODEC_BERR_LEN) - 1) << MM_MISC_STS_CODEC_BERR_POS)) +#define MM_MISC_STS_MMCPU_BERR MM_MISC_STS_MMCPU_BERR +#define MM_MISC_STS_MMCPU_BERR_POS (18U) +#define MM_MISC_STS_MMCPU_BERR_LEN (1U) +#define MM_MISC_STS_MMCPU_BERR_MSK (((1U << MM_MISC_STS_MMCPU_BERR_LEN) - 1) << MM_MISC_STS_MMCPU_BERR_POS) +#define MM_MISC_STS_MMCPU_BERR_UMSK (~(((1U << MM_MISC_STS_MMCPU_BERR_LEN) - 1) << MM_MISC_STS_MMCPU_BERR_POS)) +#define MM_MISC_STS_MMINFRA_BERR MM_MISC_STS_MMINFRA_BERR +#define MM_MISC_STS_MMINFRA_BERR_POS (19U) +#define MM_MISC_STS_MMINFRA_BERR_LEN (1U) +#define MM_MISC_STS_MMINFRA_BERR_MSK (((1U << MM_MISC_STS_MMINFRA_BERR_LEN) - 1) << MM_MISC_STS_MMINFRA_BERR_POS) +#define MM_MISC_STS_MMINFRA_BERR_UMSK (~(((1U << MM_MISC_STS_MMINFRA_BERR_LEN) - 1) << MM_MISC_STS_MMINFRA_BERR_POS)) +#define MM_MISC_STS_DSP2_BERR_WRITE MM_MISC_STS_DSP2_BERR_WRITE +#define MM_MISC_STS_DSP2_BERR_WRITE_POS (24U) +#define MM_MISC_STS_DSP2_BERR_WRITE_LEN (1U) +#define MM_MISC_STS_DSP2_BERR_WRITE_MSK (((1U << MM_MISC_STS_DSP2_BERR_WRITE_LEN) - 1) << MM_MISC_STS_DSP2_BERR_WRITE_POS) +#define MM_MISC_STS_DSP2_BERR_WRITE_UMSK (~(((1U << MM_MISC_STS_DSP2_BERR_WRITE_LEN) - 1) << MM_MISC_STS_DSP2_BERR_WRITE_POS)) +#define MM_MISC_STS_CODEC_BERR_WRITE MM_MISC_STS_CODEC_BERR_WRITE +#define MM_MISC_STS_CODEC_BERR_WRITE_POS (25U) +#define MM_MISC_STS_CODEC_BERR_WRITE_LEN (1U) +#define MM_MISC_STS_CODEC_BERR_WRITE_MSK (((1U << MM_MISC_STS_CODEC_BERR_WRITE_LEN) - 1) << MM_MISC_STS_CODEC_BERR_WRITE_POS) +#define MM_MISC_STS_CODEC_BERR_WRITE_UMSK (~(((1U << MM_MISC_STS_CODEC_BERR_WRITE_LEN) - 1) << MM_MISC_STS_CODEC_BERR_WRITE_POS)) +#define MM_MISC_STS_MMCPU_BERR_WRITE MM_MISC_STS_MMCPU_BERR_WRITE +#define MM_MISC_STS_MMCPU_BERR_WRITE_POS (26U) +#define MM_MISC_STS_MMCPU_BERR_WRITE_LEN (1U) +#define MM_MISC_STS_MMCPU_BERR_WRITE_MSK (((1U << MM_MISC_STS_MMCPU_BERR_WRITE_LEN) - 1) << MM_MISC_STS_MMCPU_BERR_WRITE_POS) +#define MM_MISC_STS_MMCPU_BERR_WRITE_UMSK (~(((1U << MM_MISC_STS_MMCPU_BERR_WRITE_LEN) - 1) << MM_MISC_STS_MMCPU_BERR_WRITE_POS)) +#define MM_MISC_STS_MMINFRA_BERR_WRITE MM_MISC_STS_MMINFRA_BERR_WRITE +#define MM_MISC_STS_MMINFRA_BERR_WRITE_POS (27U) +#define MM_MISC_STS_MMINFRA_BERR_WRITE_LEN (1U) +#define MM_MISC_STS_MMINFRA_BERR_WRITE_MSK (((1U << MM_MISC_STS_MMINFRA_BERR_WRITE_LEN) - 1) << MM_MISC_STS_MMINFRA_BERR_WRITE_POS) +#define MM_MISC_STS_MMINFRA_BERR_WRITE_UMSK (~(((1U << MM_MISC_STS_MMINFRA_BERR_WRITE_LEN) - 1) << MM_MISC_STS_MMINFRA_BERR_WRITE_POS)) + +/* 0x148 : mm_berr_cfg2 */ +#define MM_MISC_MM_BERR_CFG2_OFFSET (0x148) +#define MM_MISC_STS_DSP2_BERR_SRC MM_MISC_STS_DSP2_BERR_SRC +#define MM_MISC_STS_DSP2_BERR_SRC_POS (0U) +#define MM_MISC_STS_DSP2_BERR_SRC_LEN (3U) +#define MM_MISC_STS_DSP2_BERR_SRC_MSK (((1U << MM_MISC_STS_DSP2_BERR_SRC_LEN) - 1) << MM_MISC_STS_DSP2_BERR_SRC_POS) +#define MM_MISC_STS_DSP2_BERR_SRC_UMSK (~(((1U << MM_MISC_STS_DSP2_BERR_SRC_LEN) - 1) << MM_MISC_STS_DSP2_BERR_SRC_POS)) +#define MM_MISC_STS_DSP2_BERR_ID MM_MISC_STS_DSP2_BERR_ID +#define MM_MISC_STS_DSP2_BERR_ID_POS (8U) +#define MM_MISC_STS_DSP2_BERR_ID_LEN (4U) +#define MM_MISC_STS_DSP2_BERR_ID_MSK (((1U << MM_MISC_STS_DSP2_BERR_ID_LEN) - 1) << MM_MISC_STS_DSP2_BERR_ID_POS) +#define MM_MISC_STS_DSP2_BERR_ID_UMSK (~(((1U << MM_MISC_STS_DSP2_BERR_ID_LEN) - 1) << MM_MISC_STS_DSP2_BERR_ID_POS)) +#define MM_MISC_STS_CODEC_BERR_SRC MM_MISC_STS_CODEC_BERR_SRC +#define MM_MISC_STS_CODEC_BERR_SRC_POS (16U) +#define MM_MISC_STS_CODEC_BERR_SRC_LEN (3U) +#define MM_MISC_STS_CODEC_BERR_SRC_MSK (((1U << MM_MISC_STS_CODEC_BERR_SRC_LEN) - 1) << MM_MISC_STS_CODEC_BERR_SRC_POS) +#define MM_MISC_STS_CODEC_BERR_SRC_UMSK (~(((1U << MM_MISC_STS_CODEC_BERR_SRC_LEN) - 1) << MM_MISC_STS_CODEC_BERR_SRC_POS)) +#define MM_MISC_STS_CODEC_BERR_ID MM_MISC_STS_CODEC_BERR_ID +#define MM_MISC_STS_CODEC_BERR_ID_POS (24U) +#define MM_MISC_STS_CODEC_BERR_ID_LEN (1U) +#define MM_MISC_STS_CODEC_BERR_ID_MSK (((1U << MM_MISC_STS_CODEC_BERR_ID_LEN) - 1) << MM_MISC_STS_CODEC_BERR_ID_POS) +#define MM_MISC_STS_CODEC_BERR_ID_UMSK (~(((1U << MM_MISC_STS_CODEC_BERR_ID_LEN) - 1) << MM_MISC_STS_CODEC_BERR_ID_POS)) + +/* 0x14C : mm_berr_cfg3 */ +#define MM_MISC_MM_BERR_CFG3_OFFSET (0x14C) +#define MM_MISC_STS_MMCPU_BERR_SRC MM_MISC_STS_MMCPU_BERR_SRC +#define MM_MISC_STS_MMCPU_BERR_SRC_POS (0U) +#define MM_MISC_STS_MMCPU_BERR_SRC_LEN (1U) +#define MM_MISC_STS_MMCPU_BERR_SRC_MSK (((1U << MM_MISC_STS_MMCPU_BERR_SRC_LEN) - 1) << MM_MISC_STS_MMCPU_BERR_SRC_POS) +#define MM_MISC_STS_MMCPU_BERR_SRC_UMSK (~(((1U << MM_MISC_STS_MMCPU_BERR_SRC_LEN) - 1) << MM_MISC_STS_MMCPU_BERR_SRC_POS)) +#define MM_MISC_STS_MMCPU_BERR_ID MM_MISC_STS_MMCPU_BERR_ID +#define MM_MISC_STS_MMCPU_BERR_ID_POS (8U) +#define MM_MISC_STS_MMCPU_BERR_ID_LEN (4U) +#define MM_MISC_STS_MMCPU_BERR_ID_MSK (((1U << MM_MISC_STS_MMCPU_BERR_ID_LEN) - 1) << MM_MISC_STS_MMCPU_BERR_ID_POS) +#define MM_MISC_STS_MMCPU_BERR_ID_UMSK (~(((1U << MM_MISC_STS_MMCPU_BERR_ID_LEN) - 1) << MM_MISC_STS_MMCPU_BERR_ID_POS)) +#define MM_MISC_STS_MMINFRA_BERR_SRC MM_MISC_STS_MMINFRA_BERR_SRC +#define MM_MISC_STS_MMINFRA_BERR_SRC_POS (16U) +#define MM_MISC_STS_MMINFRA_BERR_SRC_LEN (5U) +#define MM_MISC_STS_MMINFRA_BERR_SRC_MSK (((1U << MM_MISC_STS_MMINFRA_BERR_SRC_LEN) - 1) << MM_MISC_STS_MMINFRA_BERR_SRC_POS) +#define MM_MISC_STS_MMINFRA_BERR_SRC_UMSK (~(((1U << MM_MISC_STS_MMINFRA_BERR_SRC_LEN) - 1) << MM_MISC_STS_MMINFRA_BERR_SRC_POS)) +#define MM_MISC_STS_MMINFRA_BERR_ID MM_MISC_STS_MMINFRA_BERR_ID +#define MM_MISC_STS_MMINFRA_BERR_ID_POS (24U) +#define MM_MISC_STS_MMINFRA_BERR_ID_LEN (6U) +#define MM_MISC_STS_MMINFRA_BERR_ID_MSK (((1U << MM_MISC_STS_MMINFRA_BERR_ID_LEN) - 1) << MM_MISC_STS_MMINFRA_BERR_ID_POS) +#define MM_MISC_STS_MMINFRA_BERR_ID_UMSK (~(((1U << MM_MISC_STS_MMINFRA_BERR_ID_LEN) - 1) << MM_MISC_STS_MMINFRA_BERR_ID_POS)) + +/* 0x150 : mm_berr_cfg4 */ +#define MM_MISC_MM_BERR_CFG4_OFFSET (0x150) +#define MM_MISC_STS_DSP2_BERR_ADDR MM_MISC_STS_DSP2_BERR_ADDR +#define MM_MISC_STS_DSP2_BERR_ADDR_POS (0U) +#define MM_MISC_STS_DSP2_BERR_ADDR_LEN (32U) +#define MM_MISC_STS_DSP2_BERR_ADDR_MSK (((1U << MM_MISC_STS_DSP2_BERR_ADDR_LEN) - 1) << MM_MISC_STS_DSP2_BERR_ADDR_POS) +#define MM_MISC_STS_DSP2_BERR_ADDR_UMSK (~(((1U << MM_MISC_STS_DSP2_BERR_ADDR_LEN) - 1) << MM_MISC_STS_DSP2_BERR_ADDR_POS)) + +/* 0x154 : mm_berr_cfg5 */ +#define MM_MISC_MM_BERR_CFG5_OFFSET (0x154) +#define MM_MISC_STS_CODEC_BERR_ADDR MM_MISC_STS_CODEC_BERR_ADDR +#define MM_MISC_STS_CODEC_BERR_ADDR_POS (0U) +#define MM_MISC_STS_CODEC_BERR_ADDR_LEN (32U) +#define MM_MISC_STS_CODEC_BERR_ADDR_MSK (((1U << MM_MISC_STS_CODEC_BERR_ADDR_LEN) - 1) << MM_MISC_STS_CODEC_BERR_ADDR_POS) +#define MM_MISC_STS_CODEC_BERR_ADDR_UMSK (~(((1U << MM_MISC_STS_CODEC_BERR_ADDR_LEN) - 1) << MM_MISC_STS_CODEC_BERR_ADDR_POS)) + +/* 0x158 : mm_berr_cfg6 */ +#define MM_MISC_MM_BERR_CFG6_OFFSET (0x158) +#define MM_MISC_STS_MMCPU_BERR_ADDR MM_MISC_STS_MMCPU_BERR_ADDR +#define MM_MISC_STS_MMCPU_BERR_ADDR_POS (0U) +#define MM_MISC_STS_MMCPU_BERR_ADDR_LEN (32U) +#define MM_MISC_STS_MMCPU_BERR_ADDR_MSK (((1U << MM_MISC_STS_MMCPU_BERR_ADDR_LEN) - 1) << MM_MISC_STS_MMCPU_BERR_ADDR_POS) +#define MM_MISC_STS_MMCPU_BERR_ADDR_UMSK (~(((1U << MM_MISC_STS_MMCPU_BERR_ADDR_LEN) - 1) << MM_MISC_STS_MMCPU_BERR_ADDR_POS)) + +/* 0x15C : mm_berr_cfg7 */ +#define MM_MISC_MM_BERR_CFG7_OFFSET (0x15C) +#define MM_MISC_STS_MMINFRA_BERR_ADDR MM_MISC_STS_MMINFRA_BERR_ADDR +#define MM_MISC_STS_MMINFRA_BERR_ADDR_POS (0U) +#define MM_MISC_STS_MMINFRA_BERR_ADDR_LEN (32U) +#define MM_MISC_STS_MMINFRA_BERR_ADDR_MSK (((1U << MM_MISC_STS_MMINFRA_BERR_ADDR_LEN) - 1) << MM_MISC_STS_MMINFRA_BERR_ADDR_POS) +#define MM_MISC_STS_MMINFRA_BERR_ADDR_UMSK (~(((1U << MM_MISC_STS_MMINFRA_BERR_ADDR_LEN) - 1) << MM_MISC_STS_MMINFRA_BERR_ADDR_POS)) + +struct mm_misc_reg { + /* 0x0 : CPU0_Boot */ + union { + struct { + uint32_t reg_cpu0_rvba : 32; /* [31: 0], r/w, 0x3eff0000 */ + } BF; + uint32_t WORD; + } CPU0_Boot; + + /* 0x4 reserved */ + uint8_t RESERVED0x4[4]; + + /* 0x8 : CPU_cfg */ + union { + struct { + uint32_t reg_cpu0_apb_base : 13; /* [12: 0], r/w, 0x1c */ + uint32_t reserved_13_27 : 15; /* [27:13], rsvd, 0x0 */ + uint32_t cpu0_ndm_rstn_en : 1; /* [ 28], r/w, 0x0 */ + uint32_t cpu0_hart_rstn_en : 1; /* [ 29], r/w, 0x0 */ + uint32_t reserved_30_31 : 2; /* [31:30], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } CPU_cfg; + + /* 0xC : CPU_sts1 */ + union { + struct { + uint32_t reserved_0_3 : 4; /* [ 3: 0], rsvd, 0x0 */ + uint32_t cpu0_lpmd_b : 2; /* [ 5: 4], r, 0x0 */ + uint32_t reserved_6_15 : 10; /* [15: 6], rsvd, 0x0 */ + uint32_t cpu0_retire_pc_39_32 : 8; /* [23:16], r, 0x0 */ + uint32_t cpu0_retire : 1; /* [ 24], r, 0x0 */ + uint32_t cpu0_pad_halted : 1; /* [ 25], r, 0x0 */ + uint32_t reserved_26_27 : 2; /* [27:26], rsvd, 0x0 */ + uint32_t cpu0_ndm_rstn_req : 1; /* [ 28], r, 0x0 */ + uint32_t cpu0_hart_rstn_req : 1; /* [ 29], r, 0x0 */ + uint32_t reserved_30_31 : 2; /* [31:30], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } CPU_sts1; + + /* 0x10 : CPU_sts2 */ + union { + struct { + uint32_t cpu0_retire_pc_31_0 : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } CPU_sts2; + + /* 0x14 reserved */ + uint8_t RESERVED0x14[4]; + + /* 0x18 : CPU_RTC */ + union { + struct { + uint32_t c906_rtc_div : 10; /* [ 9: 0], r/w, 0xa */ + uint32_t reserved_10_29 : 20; /* [29:10], rsvd, 0x0 */ + uint32_t c906_rtc_rst : 1; /* [ 30], r/w, 0x0 */ + uint32_t c906_rtc_en : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } CPU_RTC; + + /* 0x1C : tzc_mmsys_misc */ + union { + struct { + uint32_t tzc_mm_cpu0_lock : 1; /* [ 0], r, 0x0 */ + uint32_t reserved_1 : 1; /* [ 1], rsvd, 0x0 */ + uint32_t tzc_mm_sram_lock : 1; /* [ 2], r, 0x0 */ + uint32_t reserved_3_31 : 29; /* [31: 3], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } tzc_mmsys_misc; + + /* 0x20 : peri_apb_ctrl */ + union { + struct { + uint32_t reg_mminfra_berr_int_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_dsp2_berr_int_en : 1; /* [ 1], r/w, 0x0 */ + uint32_t reg_codec_berr_int_en : 1; /* [ 2], r/w, 0x0 */ + uint32_t reg_mmcpu_berr_int_en : 1; /* [ 3], r/w, 0x0 */ + uint32_t reserved_4_7 : 4; /* [ 7: 4], rsvd, 0x0 */ + uint32_t reg_mm_x2hs_sp_bypass : 1; /* [ 8], r/w, 0x0 */ + uint32_t reserved_9_15 : 7; /* [15: 9], rsvd, 0x0 */ + uint32_t rg_pclk_force_on : 16; /* [31:16], r/w, 0x0 */ + } BF; + uint32_t WORD; + } peri_apb_ctrl; + + /* 0x24 reserved */ + uint8_t RESERVED0x24[8]; + + /* 0x2C : mm_infra_qos_ctrl */ + union { + struct { + uint32_t reserved_0_1 : 2; /* [ 1: 0], rsvd, 0x0 */ + uint32_t reg_mmcpu0_awqos : 1; /* [ 2], r/w, 0x0 */ + uint32_t reg_mmcpu0_arqos : 1; /* [ 3], r/w, 0x0 */ + uint32_t reserved_4_15 : 12; /* [15: 4], rsvd, 0x0 */ + uint32_t reg_h_wthre_mm2conn : 2; /* [17:16], r/w, 0x0 */ + uint32_t reg_h_wthre_conn2mm : 2; /* [19:18], r/w, 0x0 */ + uint32_t reg_x_wthre_mmhw2pA : 2; /* [21:20], r/w, 0x0 */ + uint32_t reg_x_wthre_mmhw2ext : 2; /* [23:22], r/w, 0x0 */ + uint32_t reg_x_wthre_pUHS : 2; /* [25:24], r/w, 0x0 */ + uint32_t reserved_26_31 : 6; /* [31:26], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mm_infra_qos_ctrl; + + /* 0x30 reserved */ + uint8_t RESERVED0x30[16]; + + /* 0x40 : dma_clk_ctrl */ + union { + struct { + uint32_t dma_clk_en : 8; /* [ 7: 0], r/w, 0xff */ + uint32_t reserved_8_31 : 24; /* [31: 8], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } dma_clk_ctrl; + + /* 0x44 reserved */ + uint8_t RESERVED0x44[12]; + + /* 0x50 : vram_ctrl */ + union { + struct { + uint32_t reg_sysram_set : 1; /* [ 0], w1p, 0x0 */ + uint32_t reg_h2pf_sram_rel : 2; /* [ 2: 1], r/w, 0x0 */ + uint32_t reserved_3 : 1; /* [ 3], rsvd, 0x0 */ + uint32_t reg_vram_sram_rel : 1; /* [ 4], r/w, 0x0 */ + uint32_t reserved_5 : 1; /* [ 5], rsvd, 0x0 */ + uint32_t reg_dspl2_sram_rel : 1; /* [ 6], r/w, 0x0 */ + uint32_t reg_blai_sram_rel : 1; /* [ 7], r/w, 0x0 */ + uint32_t reg_h2pf_sram_sel : 3; /* [10: 8], r, 0x0 */ + uint32_t reserved_11 : 1; /* [ 11], rsvd, 0x0 */ + uint32_t reg_vram_sram_sel : 1; /* [ 12], r, 0x0 */ + uint32_t reserved_13 : 1; /* [ 13], rsvd, 0x0 */ + uint32_t reg_dspl2_sram_sel : 1; /* [ 14], r, 0x0 */ + uint32_t reg_blai_sram_sel : 1; /* [ 15], r, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } vram_ctrl; + + /* 0x54 reserved */ + uint8_t RESERVED0x54[12]; + + /* 0x60 : sram_parm */ + union { + struct { + uint32_t reg_sram_cpu_ram_dvs : 4; /* [ 3: 0], r/w, 0xc */ + uint32_t reg_sram_cpu_ram_dvse : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_sram_cpu_ram_nap : 1; /* [ 5], r/w, 0x0 */ + uint32_t reserved_6_7 : 2; /* [ 7: 6], rsvd, 0x0 */ + uint32_t reg_sram_l2ram_dvs : 4; /* [11: 8], r/w, 0xc */ + uint32_t reg_sram_l2ram_dvse : 1; /* [ 12], r/w, 0x0 */ + uint32_t reg_sram_l2ram_nap : 1; /* [ 13], r/w, 0x0 */ + uint32_t reserved_14_15 : 2; /* [15:14], rsvd, 0x0 */ + uint32_t reg_sram_cdc_ram_dvs : 4; /* [19:16], r/w, 0xc */ + uint32_t reg_sram_cdc_ram_dvse : 1; /* [ 20], r/w, 0x0 */ + uint32_t reg_sram_cdc_ram_nap : 1; /* [ 21], r/w, 0x0 */ + uint32_t reserved_22_23 : 2; /* [23:22], rsvd, 0x0 */ + uint32_t reg_sram_dsp2_ram_dvs : 4; /* [27:24], r/w, 0xc */ + uint32_t reg_sram_dsp2_ram_dvse : 1; /* [ 28], r/w, 0x0 */ + uint32_t reg_sram_dsp2_ram_nap : 1; /* [ 29], r/w, 0x0 */ + uint32_t reserved_30_31 : 2; /* [31:30], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sram_parm; + + /* 0x64 reserved */ + uint8_t RESERVED0x64[60]; + + /* 0xA0 : MM_INT_STA0 */ + union { + struct { + uint32_t mm_int_sta0 : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } MM_INT_STA0; + + /* 0xA4 : MM_INT_MASK0 */ + union { + struct { + uint32_t mm_int_mask0 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } MM_INT_MASK0; + + /* 0xA8 : MM_INT_CLR_0 */ + union { + struct { + uint32_t mm_int_clr0 : 32; /* [31: 0], w1p, 0x0 */ + } BF; + uint32_t WORD; + } MM_INT_CLR_0; + + /* 0xAC : MM_INT_STA1 */ + union { + struct { + uint32_t mm_int_sta1 : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } MM_INT_STA1; + + /* 0xB0 : MM_INT_MASK1 */ + union { + struct { + uint32_t mm_int_mask1 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } MM_INT_MASK1; + + /* 0xB4 : MM_INT_CLR_1 */ + union { + struct { + uint32_t mm_int_clr1 : 32; /* [31: 0], w1p, 0x0 */ + } BF; + uint32_t WORD; + } MM_INT_CLR_1; + + /* 0xb8 reserved */ + uint8_t RESERVED0xb8[56]; + + /* 0xF0 : mmsys_debug_sel */ + union { + struct { + uint32_t mmsys_debug_sel : 4; /* [ 3: 0], r/w, 0x0 */ + uint32_t reserved_4_31 : 28; /* [31: 4], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mmsys_debug_sel; + + /* 0xf4 reserved */ + uint8_t RESERVED0xf4[8]; + + /* 0xFC : mmsys_misc_dummy */ + union { + struct { + uint32_t PIR_ctrl_o : 1; /* [ 0], r/w, 0x0 */ + uint32_t Light_sensor_ctrl_o : 1; /* [ 1], r/w, 0x0 */ + uint32_t IR_cut_ctrl_o : 1; /* [ 2], r/w, 0x0 */ + uint32_t dvp_sensor_pwdn : 1; /* [ 3], r/w, 0x0 */ + uint32_t dummy_reg : 28; /* [31: 4], r/w, 0xfff0000 */ + } BF; + uint32_t WORD; + } mmsys_misc_dummy; + + /* 0x100 : DDR_debug */ + union { + struct { + uint32_t ddr_calib_done : 1; /* [ 0], r, 0x0 */ + uint32_t reserved_1_31 : 31; /* [31: 1], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } DDR_debug; + + /* 0x104 reserved */ + uint8_t RESERVED0x104[60]; + + /* 0x140 : mm_berr_cfg0 */ + union { + struct { + uint32_t reg_dsp2_berr_en : 3; /* [ 2: 0], r/w, 0x7 */ + uint32_t reserved_3_7 : 5; /* [ 7: 3], rsvd, 0x0 */ + uint32_t reg_codec_berr_en : 3; /* [10: 8], r/w, 0x7 */ + uint32_t reserved_11_15 : 5; /* [15:11], rsvd, 0x0 */ + uint32_t reg_mmcpu_berr_en : 1; /* [ 16], r/w, 0x1 */ + uint32_t reserved_17_23 : 7; /* [23:17], rsvd, 0x0 */ + uint32_t reg_mminfra_berr_en : 5; /* [28:24], r/w, 0x1f */ + uint32_t reserved_29_31 : 3; /* [31:29], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mm_berr_cfg0; + + /* 0x144 : mm_berr_cfg1 */ + union { + struct { + uint32_t reg_dsp2_berr_clr : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_codec_berr_clr : 1; /* [ 1], r/w, 0x0 */ + uint32_t reg_mmcpu_berr_clr : 1; /* [ 2], r/w, 0x0 */ + uint32_t reg_mminfra_berr_clr : 1; /* [ 3], r/w, 0x0 */ + uint32_t reserved_4_7 : 4; /* [ 7: 4], rsvd, 0x0 */ + uint32_t reg_dsp2_berr_last : 1; /* [ 8], r/w, 0x0 */ + uint32_t reg_codec_berr_last : 1; /* [ 9], r/w, 0x0 */ + uint32_t reg_mmcpu_berr_last : 1; /* [ 10], r/w, 0x0 */ + uint32_t reg_mminfra_berr_last : 1; /* [ 11], r/w, 0x0 */ + uint32_t reserved_12_15 : 4; /* [15:12], rsvd, 0x0 */ + uint32_t sts_dsp2_berr : 1; /* [ 16], r, 0x0 */ + uint32_t sts_codec_berr : 1; /* [ 17], r, 0x0 */ + uint32_t sts_mmcpu_berr : 1; /* [ 18], r, 0x0 */ + uint32_t sts_mminfra_berr : 1; /* [ 19], r, 0x0 */ + uint32_t reserved_20_23 : 4; /* [23:20], rsvd, 0x0 */ + uint32_t sts_dsp2_berr_write : 1; /* [ 24], r, 0x0 */ + uint32_t sts_codec_berr_write : 1; /* [ 25], r, 0x0 */ + uint32_t sts_mmcpu_berr_write : 1; /* [ 26], r, 0x0 */ + uint32_t sts_mminfra_berr_write : 1; /* [ 27], r, 0x0 */ + uint32_t reserved_28_31 : 4; /* [31:28], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mm_berr_cfg1; + + /* 0x148 : mm_berr_cfg2 */ + union { + struct { + uint32_t sts_dsp2_berr_src : 3; /* [ 2: 0], r, 0x0 */ + uint32_t reserved_3_7 : 5; /* [ 7: 3], rsvd, 0x0 */ + uint32_t sts_dsp2_berr_id : 4; /* [11: 8], r, 0x0 */ + uint32_t reserved_12_15 : 4; /* [15:12], rsvd, 0x0 */ + uint32_t sts_codec_berr_src : 3; /* [18:16], r, 0x0 */ + uint32_t reserved_19_23 : 5; /* [23:19], rsvd, 0x0 */ + uint32_t sts_codec_berr_id : 1; /* [ 24], r, 0x0 */ + uint32_t reserved_25_31 : 7; /* [31:25], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mm_berr_cfg2; + + /* 0x14C : mm_berr_cfg3 */ + union { + struct { + uint32_t sts_mmcpu_berr_src : 1; /* [ 0], r, 0x0 */ + uint32_t reserved_1_7 : 7; /* [ 7: 1], rsvd, 0x0 */ + uint32_t sts_mmcpu_berr_id : 4; /* [11: 8], r, 0x0 */ + uint32_t reserved_12_15 : 4; /* [15:12], rsvd, 0x0 */ + uint32_t sts_mminfra_berr_src : 5; /* [20:16], r, 0x0 */ + uint32_t reserved_21_23 : 3; /* [23:21], rsvd, 0x0 */ + uint32_t sts_mminfra_berr_id : 6; /* [29:24], r, 0x0 */ + uint32_t reserved_30_31 : 2; /* [31:30], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } mm_berr_cfg3; + + /* 0x150 : mm_berr_cfg4 */ + union { + struct { + uint32_t sts_dsp2_berr_addr : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } mm_berr_cfg4; + + /* 0x154 : mm_berr_cfg5 */ + union { + struct { + uint32_t sts_codec_berr_addr : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } mm_berr_cfg5; + + /* 0x158 : mm_berr_cfg6 */ + union { + struct { + uint32_t sts_mmcpu_berr_addr : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } mm_berr_cfg6; + + /* 0x15C : mm_berr_cfg7 */ + union { + struct { + uint32_t sts_mminfra_berr_addr : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } mm_berr_cfg7; +}; + +typedef volatile struct mm_misc_reg mm_misc_reg_t; + +#endif /* __MM_MISC_REG_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/pds_reg.h b/platforms/bl808_m0/vendor/psram/include/pds_reg.h new file mode 100644 index 0000000..c69a2a5 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/pds_reg.h @@ -0,0 +1,2628 @@ +/** + ****************************************************************************** + * @file pds_reg.h + * @version V1.0 + * @date 2021-09-10 + * @brief This file is the description of.IP register + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __PDS_REG_H__ +#define __PDS_REG_H__ + +#include "bl808.h" + +/* 0x0 : PDS_CTL */ +#define PDS_CTL_OFFSET (0x0) +#define PDS_START_PS PDS_START_PS +#define PDS_START_PS_POS (0U) +#define PDS_START_PS_LEN (1U) +#define PDS_START_PS_MSK (((1U << PDS_START_PS_LEN) - 1) << PDS_START_PS_POS) +#define PDS_START_PS_UMSK (~(((1U << PDS_START_PS_LEN) - 1) << PDS_START_PS_POS)) +#define PDS_CR_SLEEP_FOREVER PDS_CR_SLEEP_FOREVER +#define PDS_CR_SLEEP_FOREVER_POS (1U) +#define PDS_CR_SLEEP_FOREVER_LEN (1U) +#define PDS_CR_SLEEP_FOREVER_MSK (((1U << PDS_CR_SLEEP_FOREVER_LEN) - 1) << PDS_CR_SLEEP_FOREVER_POS) +#define PDS_CR_SLEEP_FOREVER_UMSK (~(((1U << PDS_CR_SLEEP_FOREVER_LEN) - 1) << PDS_CR_SLEEP_FOREVER_POS)) +#define PDS_CR_XTAL_FORCE_OFF PDS_CR_XTAL_FORCE_OFF +#define PDS_CR_XTAL_FORCE_OFF_POS (2U) +#define PDS_CR_XTAL_FORCE_OFF_LEN (1U) +#define PDS_CR_XTAL_FORCE_OFF_MSK (((1U << PDS_CR_XTAL_FORCE_OFF_LEN) - 1) << PDS_CR_XTAL_FORCE_OFF_POS) +#define PDS_CR_XTAL_FORCE_OFF_UMSK (~(((1U << PDS_CR_XTAL_FORCE_OFF_LEN) - 1) << PDS_CR_XTAL_FORCE_OFF_POS)) +#define PDS_CR_PDS_WIFI_SAVE_STATE PDS_CR_PDS_WIFI_SAVE_STATE +#define PDS_CR_PDS_WIFI_SAVE_STATE_POS (3U) +#define PDS_CR_PDS_WIFI_SAVE_STATE_LEN (1U) +#define PDS_CR_PDS_WIFI_SAVE_STATE_MSK (((1U << PDS_CR_PDS_WIFI_SAVE_STATE_LEN) - 1) << PDS_CR_PDS_WIFI_SAVE_STATE_POS) +#define PDS_CR_PDS_WIFI_SAVE_STATE_UMSK (~(((1U << PDS_CR_PDS_WIFI_SAVE_STATE_LEN) - 1) << PDS_CR_PDS_WIFI_SAVE_STATE_POS)) +#define PDS_CR_PDS_PD_DCDC11 PDS_CR_PDS_PD_DCDC11 +#define PDS_CR_PDS_PD_DCDC11_POS (4U) +#define PDS_CR_PDS_PD_DCDC11_LEN (1U) +#define PDS_CR_PDS_PD_DCDC11_MSK (((1U << PDS_CR_PDS_PD_DCDC11_LEN) - 1) << PDS_CR_PDS_PD_DCDC11_POS) +#define PDS_CR_PDS_PD_DCDC11_UMSK (~(((1U << PDS_CR_PDS_PD_DCDC11_LEN) - 1) << PDS_CR_PDS_PD_DCDC11_POS)) +#define PDS_CR_PDS_PD_BG_SYS PDS_CR_PDS_PD_BG_SYS +#define PDS_CR_PDS_PD_BG_SYS_POS (5U) +#define PDS_CR_PDS_PD_BG_SYS_LEN (1U) +#define PDS_CR_PDS_PD_BG_SYS_MSK (((1U << PDS_CR_PDS_PD_BG_SYS_LEN) - 1) << PDS_CR_PDS_PD_BG_SYS_POS) +#define PDS_CR_PDS_PD_BG_SYS_UMSK (~(((1U << PDS_CR_PDS_PD_BG_SYS_LEN) - 1) << PDS_CR_PDS_PD_BG_SYS_POS)) +#define PDS_CR_PDS_CTRL_GPIO_IE_PU_PD PDS_CR_PDS_CTRL_GPIO_IE_PU_PD +#define PDS_CR_PDS_CTRL_GPIO_IE_PU_PD_POS (6U) +#define PDS_CR_PDS_CTRL_GPIO_IE_PU_PD_LEN (1U) +#define PDS_CR_PDS_CTRL_GPIO_IE_PU_PD_MSK (((1U << PDS_CR_PDS_CTRL_GPIO_IE_PU_PD_LEN) - 1) << PDS_CR_PDS_CTRL_GPIO_IE_PU_PD_POS) +#define PDS_CR_PDS_CTRL_GPIO_IE_PU_PD_UMSK (~(((1U << PDS_CR_PDS_CTRL_GPIO_IE_PU_PD_LEN) - 1) << PDS_CR_PDS_CTRL_GPIO_IE_PU_PD_POS)) +#define PDS_CR_PDS_PD_DCDC18 PDS_CR_PDS_PD_DCDC18 +#define PDS_CR_PDS_PD_DCDC18_POS (7U) +#define PDS_CR_PDS_PD_DCDC18_LEN (1U) +#define PDS_CR_PDS_PD_DCDC18_MSK (((1U << PDS_CR_PDS_PD_DCDC18_LEN) - 1) << PDS_CR_PDS_PD_DCDC18_POS) +#define PDS_CR_PDS_PD_DCDC18_UMSK (~(((1U << PDS_CR_PDS_PD_DCDC18_LEN) - 1) << PDS_CR_PDS_PD_DCDC18_POS)) +#define PDS_CR_PDS_GATE_CLK PDS_CR_PDS_GATE_CLK +#define PDS_CR_PDS_GATE_CLK_POS (8U) +#define PDS_CR_PDS_GATE_CLK_LEN (1U) +#define PDS_CR_PDS_GATE_CLK_MSK (((1U << PDS_CR_PDS_GATE_CLK_LEN) - 1) << PDS_CR_PDS_GATE_CLK_POS) +#define PDS_CR_PDS_GATE_CLK_UMSK (~(((1U << PDS_CR_PDS_GATE_CLK_LEN) - 1) << PDS_CR_PDS_GATE_CLK_POS)) +#define PDS_CR_PDS_MEM_STBY PDS_CR_PDS_MEM_STBY +#define PDS_CR_PDS_MEM_STBY_POS (9U) +#define PDS_CR_PDS_MEM_STBY_LEN (1U) +#define PDS_CR_PDS_MEM_STBY_MSK (((1U << PDS_CR_PDS_MEM_STBY_LEN) - 1) << PDS_CR_PDS_MEM_STBY_POS) +#define PDS_CR_PDS_MEM_STBY_UMSK (~(((1U << PDS_CR_PDS_MEM_STBY_LEN) - 1) << PDS_CR_PDS_MEM_STBY_POS)) +#define PDS_CR_PDS_GLB_REG_RESET_PROTECT PDS_CR_PDS_GLB_REG_RESET_PROTECT +#define PDS_CR_PDS_GLB_REG_RESET_PROTECT_POS (10U) +#define PDS_CR_PDS_GLB_REG_RESET_PROTECT_LEN (1U) +#define PDS_CR_PDS_GLB_REG_RESET_PROTECT_MSK (((1U << PDS_CR_PDS_GLB_REG_RESET_PROTECT_LEN) - 1) << PDS_CR_PDS_GLB_REG_RESET_PROTECT_POS) +#define PDS_CR_PDS_GLB_REG_RESET_PROTECT_UMSK (~(((1U << PDS_CR_PDS_GLB_REG_RESET_PROTECT_LEN) - 1) << PDS_CR_PDS_GLB_REG_RESET_PROTECT_POS)) +#define PDS_CR_PDS_ISO_EN PDS_CR_PDS_ISO_EN +#define PDS_CR_PDS_ISO_EN_POS (11U) +#define PDS_CR_PDS_ISO_EN_LEN (1U) +#define PDS_CR_PDS_ISO_EN_MSK (((1U << PDS_CR_PDS_ISO_EN_LEN) - 1) << PDS_CR_PDS_ISO_EN_POS) +#define PDS_CR_PDS_ISO_EN_UMSK (~(((1U << PDS_CR_PDS_ISO_EN_LEN) - 1) << PDS_CR_PDS_ISO_EN_POS)) +#define PDS_CR_PDS_WAIT_XTAL_RDY PDS_CR_PDS_WAIT_XTAL_RDY +#define PDS_CR_PDS_WAIT_XTAL_RDY_POS (12U) +#define PDS_CR_PDS_WAIT_XTAL_RDY_LEN (1U) +#define PDS_CR_PDS_WAIT_XTAL_RDY_MSK (((1U << PDS_CR_PDS_WAIT_XTAL_RDY_LEN) - 1) << PDS_CR_PDS_WAIT_XTAL_RDY_POS) +#define PDS_CR_PDS_WAIT_XTAL_RDY_UMSK (~(((1U << PDS_CR_PDS_WAIT_XTAL_RDY_LEN) - 1) << PDS_CR_PDS_WAIT_XTAL_RDY_POS)) +#define PDS_CR_PDS_PWR_OFF PDS_CR_PDS_PWR_OFF +#define PDS_CR_PDS_PWR_OFF_POS (13U) +#define PDS_CR_PDS_PWR_OFF_LEN (1U) +#define PDS_CR_PDS_PWR_OFF_MSK (((1U << PDS_CR_PDS_PWR_OFF_LEN) - 1) << PDS_CR_PDS_PWR_OFF_POS) +#define PDS_CR_PDS_PWR_OFF_UMSK (~(((1U << PDS_CR_PDS_PWR_OFF_LEN) - 1) << PDS_CR_PDS_PWR_OFF_POS)) +#define PDS_CR_PDS_PD_XTAL PDS_CR_PDS_PD_XTAL +#define PDS_CR_PDS_PD_XTAL_POS (14U) +#define PDS_CR_PDS_PD_XTAL_LEN (1U) +#define PDS_CR_PDS_PD_XTAL_MSK (((1U << PDS_CR_PDS_PD_XTAL_LEN) - 1) << PDS_CR_PDS_PD_XTAL_POS) +#define PDS_CR_PDS_PD_XTAL_UMSK (~(((1U << PDS_CR_PDS_PD_XTAL_LEN) - 1) << PDS_CR_PDS_PD_XTAL_POS)) +#define PDS_CR_PDS_CTRL_SOC_ENB PDS_CR_PDS_CTRL_SOC_ENB +#define PDS_CR_PDS_CTRL_SOC_ENB_POS (15U) +#define PDS_CR_PDS_CTRL_SOC_ENB_LEN (1U) +#define PDS_CR_PDS_CTRL_SOC_ENB_MSK (((1U << PDS_CR_PDS_CTRL_SOC_ENB_LEN) - 1) << PDS_CR_PDS_CTRL_SOC_ENB_POS) +#define PDS_CR_PDS_CTRL_SOC_ENB_UMSK (~(((1U << PDS_CR_PDS_CTRL_SOC_ENB_LEN) - 1) << PDS_CR_PDS_CTRL_SOC_ENB_POS)) +#define PDS_CR_PDS_RST_SOC PDS_CR_PDS_RST_SOC +#define PDS_CR_PDS_RST_SOC_POS (16U) +#define PDS_CR_PDS_RST_SOC_LEN (1U) +#define PDS_CR_PDS_RST_SOC_MSK (((1U << PDS_CR_PDS_RST_SOC_LEN) - 1) << PDS_CR_PDS_RST_SOC_POS) +#define PDS_CR_PDS_RST_SOC_UMSK (~(((1U << PDS_CR_PDS_RST_SOC_LEN) - 1) << PDS_CR_PDS_RST_SOC_POS)) +#define PDS_CR_PDS_RC32M_OFF_DIS PDS_CR_PDS_RC32M_OFF_DIS +#define PDS_CR_PDS_RC32M_OFF_DIS_POS (17U) +#define PDS_CR_PDS_RC32M_OFF_DIS_LEN (1U) +#define PDS_CR_PDS_RC32M_OFF_DIS_MSK (((1U << PDS_CR_PDS_RC32M_OFF_DIS_LEN) - 1) << PDS_CR_PDS_RC32M_OFF_DIS_POS) +#define PDS_CR_PDS_RC32M_OFF_DIS_UMSK (~(((1U << PDS_CR_PDS_RC32M_OFF_DIS_LEN) - 1) << PDS_CR_PDS_RC32M_OFF_DIS_POS)) +#define PDS_CR_PDS_DCDC11_VSEL_EN PDS_CR_PDS_DCDC11_VSEL_EN +#define PDS_CR_PDS_DCDC11_VSEL_EN_POS (18U) +#define PDS_CR_PDS_DCDC11_VSEL_EN_LEN (1U) +#define PDS_CR_PDS_DCDC11_VSEL_EN_MSK (((1U << PDS_CR_PDS_DCDC11_VSEL_EN_LEN) - 1) << PDS_CR_PDS_DCDC11_VSEL_EN_POS) +#define PDS_CR_PDS_DCDC11_VSEL_EN_UMSK (~(((1U << PDS_CR_PDS_DCDC11_VSEL_EN_LEN) - 1) << PDS_CR_PDS_DCDC11_VSEL_EN_POS)) +#define PDS_CR_PDS_CTRL_USBPLL_PD PDS_CR_PDS_CTRL_USBPLL_PD +#define PDS_CR_PDS_CTRL_USBPLL_PD_POS (19U) +#define PDS_CR_PDS_CTRL_USBPLL_PD_LEN (1U) +#define PDS_CR_PDS_CTRL_USBPLL_PD_MSK (((1U << PDS_CR_PDS_CTRL_USBPLL_PD_LEN) - 1) << PDS_CR_PDS_CTRL_USBPLL_PD_POS) +#define PDS_CR_PDS_CTRL_USBPLL_PD_UMSK (~(((1U << PDS_CR_PDS_CTRL_USBPLL_PD_LEN) - 1) << PDS_CR_PDS_CTRL_USBPLL_PD_POS)) +#define PDS_CR_PDS_CTRL_AUPLL_PD PDS_CR_PDS_CTRL_AUPLL_PD +#define PDS_CR_PDS_CTRL_AUPLL_PD_POS (20U) +#define PDS_CR_PDS_CTRL_AUPLL_PD_LEN (1U) +#define PDS_CR_PDS_CTRL_AUPLL_PD_MSK (((1U << PDS_CR_PDS_CTRL_AUPLL_PD_LEN) - 1) << PDS_CR_PDS_CTRL_AUPLL_PD_POS) +#define PDS_CR_PDS_CTRL_AUPLL_PD_UMSK (~(((1U << PDS_CR_PDS_CTRL_AUPLL_PD_LEN) - 1) << PDS_CR_PDS_CTRL_AUPLL_PD_POS)) +#define PDS_CR_PDS_CTRL_CPUPLL_PD PDS_CR_PDS_CTRL_CPUPLL_PD +#define PDS_CR_PDS_CTRL_CPUPLL_PD_POS (21U) +#define PDS_CR_PDS_CTRL_CPUPLL_PD_LEN (1U) +#define PDS_CR_PDS_CTRL_CPUPLL_PD_MSK (((1U << PDS_CR_PDS_CTRL_CPUPLL_PD_LEN) - 1) << PDS_CR_PDS_CTRL_CPUPLL_PD_POS) +#define PDS_CR_PDS_CTRL_CPUPLL_PD_UMSK (~(((1U << PDS_CR_PDS_CTRL_CPUPLL_PD_LEN) - 1) << PDS_CR_PDS_CTRL_CPUPLL_PD_POS)) +#define PDS_CR_PDS_CTRL_WIFIPLL_PD PDS_CR_PDS_CTRL_WIFIPLL_PD +#define PDS_CR_PDS_CTRL_WIFIPLL_PD_POS (22U) +#define PDS_CR_PDS_CTRL_WIFIPLL_PD_LEN (1U) +#define PDS_CR_PDS_CTRL_WIFIPLL_PD_MSK (((1U << PDS_CR_PDS_CTRL_WIFIPLL_PD_LEN) - 1) << PDS_CR_PDS_CTRL_WIFIPLL_PD_POS) +#define PDS_CR_PDS_CTRL_WIFIPLL_PD_UMSK (~(((1U << PDS_CR_PDS_CTRL_WIFIPLL_PD_LEN) - 1) << PDS_CR_PDS_CTRL_WIFIPLL_PD_POS)) +#define PDS_CR_PDS_DCDC11_VOL PDS_CR_PDS_DCDC11_VOL +#define PDS_CR_PDS_DCDC11_VOL_POS (23U) +#define PDS_CR_PDS_DCDC11_VOL_LEN (5U) +#define PDS_CR_PDS_DCDC11_VOL_MSK (((1U << PDS_CR_PDS_DCDC11_VOL_LEN) - 1) << PDS_CR_PDS_DCDC11_VOL_POS) +#define PDS_CR_PDS_DCDC11_VOL_UMSK (~(((1U << PDS_CR_PDS_DCDC11_VOL_LEN) - 1) << PDS_CR_PDS_DCDC11_VOL_POS)) +#define PDS_CR_PDS_CTRL_RF PDS_CR_PDS_CTRL_RF +#define PDS_CR_PDS_CTRL_RF_POS (28U) +#define PDS_CR_PDS_CTRL_RF_LEN (2U) +#define PDS_CR_PDS_CTRL_RF_MSK (((1U << PDS_CR_PDS_CTRL_RF_LEN) - 1) << PDS_CR_PDS_CTRL_RF_POS) +#define PDS_CR_PDS_CTRL_RF_UMSK (~(((1U << PDS_CR_PDS_CTRL_RF_LEN) - 1) << PDS_CR_PDS_CTRL_RF_POS)) +#define PDS_CR_PDS_START_USE_TBTT_SLEEP PDS_CR_PDS_START_USE_TBTT_SLEEP +#define PDS_CR_PDS_START_USE_TBTT_SLEEP_POS (30U) +#define PDS_CR_PDS_START_USE_TBTT_SLEEP_LEN (1U) +#define PDS_CR_PDS_START_USE_TBTT_SLEEP_MSK (((1U << PDS_CR_PDS_START_USE_TBTT_SLEEP_LEN) - 1) << PDS_CR_PDS_START_USE_TBTT_SLEEP_POS) +#define PDS_CR_PDS_START_USE_TBTT_SLEEP_UMSK (~(((1U << PDS_CR_PDS_START_USE_TBTT_SLEEP_LEN) - 1) << PDS_CR_PDS_START_USE_TBTT_SLEEP_POS)) +#define PDS_CR_PDS_GPIO_ISO_MODE PDS_CR_PDS_GPIO_ISO_MODE +#define PDS_CR_PDS_GPIO_ISO_MODE_POS (31U) +#define PDS_CR_PDS_GPIO_ISO_MODE_LEN (1U) +#define PDS_CR_PDS_GPIO_ISO_MODE_MSK (((1U << PDS_CR_PDS_GPIO_ISO_MODE_LEN) - 1) << PDS_CR_PDS_GPIO_ISO_MODE_POS) +#define PDS_CR_PDS_GPIO_ISO_MODE_UMSK (~(((1U << PDS_CR_PDS_GPIO_ISO_MODE_LEN) - 1) << PDS_CR_PDS_GPIO_ISO_MODE_POS)) + +/* 0x4 : PDS_TIME1 */ +#define PDS_TIME1_OFFSET (0x4) +#define PDS_CR_SLEEP_DURATION PDS_CR_SLEEP_DURATION +#define PDS_CR_SLEEP_DURATION_POS (0U) +#define PDS_CR_SLEEP_DURATION_LEN (32U) +#define PDS_CR_SLEEP_DURATION_MSK (((1U << PDS_CR_SLEEP_DURATION_LEN) - 1) << PDS_CR_SLEEP_DURATION_POS) +#define PDS_CR_SLEEP_DURATION_UMSK (~(((1U << PDS_CR_SLEEP_DURATION_LEN) - 1) << PDS_CR_SLEEP_DURATION_POS)) + +/* 0xC : PDS_INT */ +#define PDS_INT_OFFSET (0xC) +#define PDS_RO_PDS_WAKE_INT PDS_RO_PDS_WAKE_INT +#define PDS_RO_PDS_WAKE_INT_POS (0U) +#define PDS_RO_PDS_WAKE_INT_LEN (1U) +#define PDS_RO_PDS_WAKE_INT_MSK (((1U << PDS_RO_PDS_WAKE_INT_LEN) - 1) << PDS_RO_PDS_WAKE_INT_POS) +#define PDS_RO_PDS_WAKE_INT_UMSK (~(((1U << PDS_RO_PDS_WAKE_INT_LEN) - 1) << PDS_RO_PDS_WAKE_INT_POS)) +#define PDS_RO_PDS_RF_DONE_INT PDS_RO_PDS_RF_DONE_INT +#define PDS_RO_PDS_RF_DONE_INT_POS (1U) +#define PDS_RO_PDS_RF_DONE_INT_LEN (1U) +#define PDS_RO_PDS_RF_DONE_INT_MSK (((1U << PDS_RO_PDS_RF_DONE_INT_LEN) - 1) << PDS_RO_PDS_RF_DONE_INT_POS) +#define PDS_RO_PDS_RF_DONE_INT_UMSK (~(((1U << PDS_RO_PDS_RF_DONE_INT_LEN) - 1) << PDS_RO_PDS_RF_DONE_INT_POS)) +#define PDS_RO_PDS_WIFI_TBTT_SLEEP_IRQ PDS_RO_PDS_WIFI_TBTT_SLEEP_IRQ +#define PDS_RO_PDS_WIFI_TBTT_SLEEP_IRQ_POS (2U) +#define PDS_RO_PDS_WIFI_TBTT_SLEEP_IRQ_LEN (1U) +#define PDS_RO_PDS_WIFI_TBTT_SLEEP_IRQ_MSK (((1U << PDS_RO_PDS_WIFI_TBTT_SLEEP_IRQ_LEN) - 1) << PDS_RO_PDS_WIFI_TBTT_SLEEP_IRQ_POS) +#define PDS_RO_PDS_WIFI_TBTT_SLEEP_IRQ_UMSK (~(((1U << PDS_RO_PDS_WIFI_TBTT_SLEEP_IRQ_LEN) - 1) << PDS_RO_PDS_WIFI_TBTT_SLEEP_IRQ_POS)) +#define PDS_RO_PDS_WIFI_TBTT_WAKEUP_IRQ PDS_RO_PDS_WIFI_TBTT_WAKEUP_IRQ +#define PDS_RO_PDS_WIFI_TBTT_WAKEUP_IRQ_POS (3U) +#define PDS_RO_PDS_WIFI_TBTT_WAKEUP_IRQ_LEN (1U) +#define PDS_RO_PDS_WIFI_TBTT_WAKEUP_IRQ_MSK (((1U << PDS_RO_PDS_WIFI_TBTT_WAKEUP_IRQ_LEN) - 1) << PDS_RO_PDS_WIFI_TBTT_WAKEUP_IRQ_POS) +#define PDS_RO_PDS_WIFI_TBTT_WAKEUP_IRQ_UMSK (~(((1U << PDS_RO_PDS_WIFI_TBTT_WAKEUP_IRQ_LEN) - 1) << PDS_RO_PDS_WIFI_TBTT_WAKEUP_IRQ_POS)) +#define PDS_CR_PDS_WAKE_INT_MASK PDS_CR_PDS_WAKE_INT_MASK +#define PDS_CR_PDS_WAKE_INT_MASK_POS (4U) +#define PDS_CR_PDS_WAKE_INT_MASK_LEN (1U) +#define PDS_CR_PDS_WAKE_INT_MASK_MSK (((1U << PDS_CR_PDS_WAKE_INT_MASK_LEN) - 1) << PDS_CR_PDS_WAKE_INT_MASK_POS) +#define PDS_CR_PDS_WAKE_INT_MASK_UMSK (~(((1U << PDS_CR_PDS_WAKE_INT_MASK_LEN) - 1) << PDS_CR_PDS_WAKE_INT_MASK_POS)) +#define PDS_CR_PDS_RF_DONE_INT_MASK PDS_CR_PDS_RF_DONE_INT_MASK +#define PDS_CR_PDS_RF_DONE_INT_MASK_POS (5U) +#define PDS_CR_PDS_RF_DONE_INT_MASK_LEN (1U) +#define PDS_CR_PDS_RF_DONE_INT_MASK_MSK (((1U << PDS_CR_PDS_RF_DONE_INT_MASK_LEN) - 1) << PDS_CR_PDS_RF_DONE_INT_MASK_POS) +#define PDS_CR_PDS_RF_DONE_INT_MASK_UMSK (~(((1U << PDS_CR_PDS_RF_DONE_INT_MASK_LEN) - 1) << PDS_CR_PDS_RF_DONE_INT_MASK_POS)) +#define PDS_CR_PDS_WIFI_TBTT_SLEEP_IRQ_MASK PDS_CR_PDS_WIFI_TBTT_SLEEP_IRQ_MASK +#define PDS_CR_PDS_WIFI_TBTT_SLEEP_IRQ_MASK_POS (6U) +#define PDS_CR_PDS_WIFI_TBTT_SLEEP_IRQ_MASK_LEN (1U) +#define PDS_CR_PDS_WIFI_TBTT_SLEEP_IRQ_MASK_MSK (((1U << PDS_CR_PDS_WIFI_TBTT_SLEEP_IRQ_MASK_LEN) - 1) << PDS_CR_PDS_WIFI_TBTT_SLEEP_IRQ_MASK_POS) +#define PDS_CR_PDS_WIFI_TBTT_SLEEP_IRQ_MASK_UMSK (~(((1U << PDS_CR_PDS_WIFI_TBTT_SLEEP_IRQ_MASK_LEN) - 1) << PDS_CR_PDS_WIFI_TBTT_SLEEP_IRQ_MASK_POS)) +#define PDS_CR_PDS_WIFI_TBTT_WAKEUP_IRQ_MASK PDS_CR_PDS_WIFI_TBTT_WAKEUP_IRQ_MASK +#define PDS_CR_PDS_WIFI_TBTT_WAKEUP_IRQ_MASK_POS (7U) +#define PDS_CR_PDS_WIFI_TBTT_WAKEUP_IRQ_MASK_LEN (1U) +#define PDS_CR_PDS_WIFI_TBTT_WAKEUP_IRQ_MASK_MSK (((1U << PDS_CR_PDS_WIFI_TBTT_WAKEUP_IRQ_MASK_LEN) - 1) << PDS_CR_PDS_WIFI_TBTT_WAKEUP_IRQ_MASK_POS) +#define PDS_CR_PDS_WIFI_TBTT_WAKEUP_IRQ_MASK_UMSK (~(((1U << PDS_CR_PDS_WIFI_TBTT_WAKEUP_IRQ_MASK_LEN) - 1) << PDS_CR_PDS_WIFI_TBTT_WAKEUP_IRQ_MASK_POS)) +#define PDS_CR_PDS_INT_CLR PDS_CR_PDS_INT_CLR +#define PDS_CR_PDS_INT_CLR_POS (8U) +#define PDS_CR_PDS_INT_CLR_LEN (1U) +#define PDS_CR_PDS_INT_CLR_MSK (((1U << PDS_CR_PDS_INT_CLR_LEN) - 1) << PDS_CR_PDS_INT_CLR_POS) +#define PDS_CR_PDS_INT_CLR_UMSK (~(((1U << PDS_CR_PDS_INT_CLR_LEN) - 1) << PDS_CR_PDS_INT_CLR_POS)) +#define PDS_CR_PDS_WAKEUP_SRC_EN PDS_CR_PDS_WAKEUP_SRC_EN +#define PDS_CR_PDS_WAKEUP_SRC_EN_POS (10U) +#define PDS_CR_PDS_WAKEUP_SRC_EN_LEN (11U) +#define PDS_CR_PDS_WAKEUP_SRC_EN_MSK (((1U << PDS_CR_PDS_WAKEUP_SRC_EN_LEN) - 1) << PDS_CR_PDS_WAKEUP_SRC_EN_POS) +#define PDS_CR_PDS_WAKEUP_SRC_EN_UMSK (~(((1U << PDS_CR_PDS_WAKEUP_SRC_EN_LEN) - 1) << PDS_CR_PDS_WAKEUP_SRC_EN_POS)) +#define PDS_RO_PDS_WAKEUP_EVENT PDS_RO_PDS_WAKEUP_EVENT +#define PDS_RO_PDS_WAKEUP_EVENT_POS (21U) +#define PDS_RO_PDS_WAKEUP_EVENT_LEN (11U) +#define PDS_RO_PDS_WAKEUP_EVENT_MSK (((1U << PDS_RO_PDS_WAKEUP_EVENT_LEN) - 1) << PDS_RO_PDS_WAKEUP_EVENT_POS) +#define PDS_RO_PDS_WAKEUP_EVENT_UMSK (~(((1U << PDS_RO_PDS_WAKEUP_EVENT_LEN) - 1) << PDS_RO_PDS_WAKEUP_EVENT_POS)) + +/* 0x10 : PDS_CTL2 */ +#define PDS_CTL2_OFFSET (0x10) +#define PDS_CR_PDS_FORCE_MM_PWR_OFF PDS_CR_PDS_FORCE_MM_PWR_OFF +#define PDS_CR_PDS_FORCE_MM_PWR_OFF_POS (1U) +#define PDS_CR_PDS_FORCE_MM_PWR_OFF_LEN (1U) +#define PDS_CR_PDS_FORCE_MM_PWR_OFF_MSK (((1U << PDS_CR_PDS_FORCE_MM_PWR_OFF_LEN) - 1) << PDS_CR_PDS_FORCE_MM_PWR_OFF_POS) +#define PDS_CR_PDS_FORCE_MM_PWR_OFF_UMSK (~(((1U << PDS_CR_PDS_FORCE_MM_PWR_OFF_LEN) - 1) << PDS_CR_PDS_FORCE_MM_PWR_OFF_POS)) +#define PDS_CR_PDS_FORCE_USB_PWR_OFF PDS_CR_PDS_FORCE_USB_PWR_OFF +#define PDS_CR_PDS_FORCE_USB_PWR_OFF_POS (3U) +#define PDS_CR_PDS_FORCE_USB_PWR_OFF_LEN (1U) +#define PDS_CR_PDS_FORCE_USB_PWR_OFF_MSK (((1U << PDS_CR_PDS_FORCE_USB_PWR_OFF_LEN) - 1) << PDS_CR_PDS_FORCE_USB_PWR_OFF_POS) +#define PDS_CR_PDS_FORCE_USB_PWR_OFF_UMSK (~(((1U << PDS_CR_PDS_FORCE_USB_PWR_OFF_LEN) - 1) << PDS_CR_PDS_FORCE_USB_PWR_OFF_POS)) +#define PDS_CR_PDS_FORCE_MM_ISO_EN PDS_CR_PDS_FORCE_MM_ISO_EN +#define PDS_CR_PDS_FORCE_MM_ISO_EN_POS (5U) +#define PDS_CR_PDS_FORCE_MM_ISO_EN_LEN (1U) +#define PDS_CR_PDS_FORCE_MM_ISO_EN_MSK (((1U << PDS_CR_PDS_FORCE_MM_ISO_EN_LEN) - 1) << PDS_CR_PDS_FORCE_MM_ISO_EN_POS) +#define PDS_CR_PDS_FORCE_MM_ISO_EN_UMSK (~(((1U << PDS_CR_PDS_FORCE_MM_ISO_EN_LEN) - 1) << PDS_CR_PDS_FORCE_MM_ISO_EN_POS)) +#define PDS_CR_PDS_FORCE_USB_ISO_EN PDS_CR_PDS_FORCE_USB_ISO_EN +#define PDS_CR_PDS_FORCE_USB_ISO_EN_POS (7U) +#define PDS_CR_PDS_FORCE_USB_ISO_EN_LEN (1U) +#define PDS_CR_PDS_FORCE_USB_ISO_EN_MSK (((1U << PDS_CR_PDS_FORCE_USB_ISO_EN_LEN) - 1) << PDS_CR_PDS_FORCE_USB_ISO_EN_POS) +#define PDS_CR_PDS_FORCE_USB_ISO_EN_UMSK (~(((1U << PDS_CR_PDS_FORCE_USB_ISO_EN_LEN) - 1) << PDS_CR_PDS_FORCE_USB_ISO_EN_POS)) +#define PDS_CR_PDS_FORCE_NP_PDS_RST PDS_CR_PDS_FORCE_NP_PDS_RST +#define PDS_CR_PDS_FORCE_NP_PDS_RST_POS (8U) +#define PDS_CR_PDS_FORCE_NP_PDS_RST_LEN (1U) +#define PDS_CR_PDS_FORCE_NP_PDS_RST_MSK (((1U << PDS_CR_PDS_FORCE_NP_PDS_RST_LEN) - 1) << PDS_CR_PDS_FORCE_NP_PDS_RST_POS) +#define PDS_CR_PDS_FORCE_NP_PDS_RST_UMSK (~(((1U << PDS_CR_PDS_FORCE_NP_PDS_RST_LEN) - 1) << PDS_CR_PDS_FORCE_NP_PDS_RST_POS)) +#define PDS_CR_PDS_FORCE_MM_PDS_RST PDS_CR_PDS_FORCE_MM_PDS_RST +#define PDS_CR_PDS_FORCE_MM_PDS_RST_POS (9U) +#define PDS_CR_PDS_FORCE_MM_PDS_RST_LEN (1U) +#define PDS_CR_PDS_FORCE_MM_PDS_RST_MSK (((1U << PDS_CR_PDS_FORCE_MM_PDS_RST_LEN) - 1) << PDS_CR_PDS_FORCE_MM_PDS_RST_POS) +#define PDS_CR_PDS_FORCE_MM_PDS_RST_UMSK (~(((1U << PDS_CR_PDS_FORCE_MM_PDS_RST_LEN) - 1) << PDS_CR_PDS_FORCE_MM_PDS_RST_POS)) +#define PDS_CR_PDS_FORCE_WB_PDS_RST PDS_CR_PDS_FORCE_WB_PDS_RST +#define PDS_CR_PDS_FORCE_WB_PDS_RST_POS (10U) +#define PDS_CR_PDS_FORCE_WB_PDS_RST_LEN (1U) +#define PDS_CR_PDS_FORCE_WB_PDS_RST_MSK (((1U << PDS_CR_PDS_FORCE_WB_PDS_RST_LEN) - 1) << PDS_CR_PDS_FORCE_WB_PDS_RST_POS) +#define PDS_CR_PDS_FORCE_WB_PDS_RST_UMSK (~(((1U << PDS_CR_PDS_FORCE_WB_PDS_RST_LEN) - 1) << PDS_CR_PDS_FORCE_WB_PDS_RST_POS)) +#define PDS_CR_PDS_FORCE_USB_PDS_RST PDS_CR_PDS_FORCE_USB_PDS_RST +#define PDS_CR_PDS_FORCE_USB_PDS_RST_POS (11U) +#define PDS_CR_PDS_FORCE_USB_PDS_RST_LEN (1U) +#define PDS_CR_PDS_FORCE_USB_PDS_RST_MSK (((1U << PDS_CR_PDS_FORCE_USB_PDS_RST_LEN) - 1) << PDS_CR_PDS_FORCE_USB_PDS_RST_POS) +#define PDS_CR_PDS_FORCE_USB_PDS_RST_UMSK (~(((1U << PDS_CR_PDS_FORCE_USB_PDS_RST_LEN) - 1) << PDS_CR_PDS_FORCE_USB_PDS_RST_POS)) +#define PDS_CR_PDS_FORCE_NP_MEM_STBY PDS_CR_PDS_FORCE_NP_MEM_STBY +#define PDS_CR_PDS_FORCE_NP_MEM_STBY_POS (12U) +#define PDS_CR_PDS_FORCE_NP_MEM_STBY_LEN (1U) +#define PDS_CR_PDS_FORCE_NP_MEM_STBY_MSK (((1U << PDS_CR_PDS_FORCE_NP_MEM_STBY_LEN) - 1) << PDS_CR_PDS_FORCE_NP_MEM_STBY_POS) +#define PDS_CR_PDS_FORCE_NP_MEM_STBY_UMSK (~(((1U << PDS_CR_PDS_FORCE_NP_MEM_STBY_LEN) - 1) << PDS_CR_PDS_FORCE_NP_MEM_STBY_POS)) +#define PDS_CR_PDS_FORCE_MM_MEM_STBY PDS_CR_PDS_FORCE_MM_MEM_STBY +#define PDS_CR_PDS_FORCE_MM_MEM_STBY_POS (13U) +#define PDS_CR_PDS_FORCE_MM_MEM_STBY_LEN (1U) +#define PDS_CR_PDS_FORCE_MM_MEM_STBY_MSK (((1U << PDS_CR_PDS_FORCE_MM_MEM_STBY_LEN) - 1) << PDS_CR_PDS_FORCE_MM_MEM_STBY_POS) +#define PDS_CR_PDS_FORCE_MM_MEM_STBY_UMSK (~(((1U << PDS_CR_PDS_FORCE_MM_MEM_STBY_LEN) - 1) << PDS_CR_PDS_FORCE_MM_MEM_STBY_POS)) +#define PDS_CR_PDS_FORCE_WB_MEM_STBY PDS_CR_PDS_FORCE_WB_MEM_STBY +#define PDS_CR_PDS_FORCE_WB_MEM_STBY_POS (14U) +#define PDS_CR_PDS_FORCE_WB_MEM_STBY_LEN (1U) +#define PDS_CR_PDS_FORCE_WB_MEM_STBY_MSK (((1U << PDS_CR_PDS_FORCE_WB_MEM_STBY_LEN) - 1) << PDS_CR_PDS_FORCE_WB_MEM_STBY_POS) +#define PDS_CR_PDS_FORCE_WB_MEM_STBY_UMSK (~(((1U << PDS_CR_PDS_FORCE_WB_MEM_STBY_LEN) - 1) << PDS_CR_PDS_FORCE_WB_MEM_STBY_POS)) +#define PDS_CR_PDS_FORCE_USB_MEM_STBY PDS_CR_PDS_FORCE_USB_MEM_STBY +#define PDS_CR_PDS_FORCE_USB_MEM_STBY_POS (15U) +#define PDS_CR_PDS_FORCE_USB_MEM_STBY_LEN (1U) +#define PDS_CR_PDS_FORCE_USB_MEM_STBY_MSK (((1U << PDS_CR_PDS_FORCE_USB_MEM_STBY_LEN) - 1) << PDS_CR_PDS_FORCE_USB_MEM_STBY_POS) +#define PDS_CR_PDS_FORCE_USB_MEM_STBY_UMSK (~(((1U << PDS_CR_PDS_FORCE_USB_MEM_STBY_LEN) - 1) << PDS_CR_PDS_FORCE_USB_MEM_STBY_POS)) +#define PDS_CR_PDS_FORCE_NP_GATE_CLK PDS_CR_PDS_FORCE_NP_GATE_CLK +#define PDS_CR_PDS_FORCE_NP_GATE_CLK_POS (16U) +#define PDS_CR_PDS_FORCE_NP_GATE_CLK_LEN (1U) +#define PDS_CR_PDS_FORCE_NP_GATE_CLK_MSK (((1U << PDS_CR_PDS_FORCE_NP_GATE_CLK_LEN) - 1) << PDS_CR_PDS_FORCE_NP_GATE_CLK_POS) +#define PDS_CR_PDS_FORCE_NP_GATE_CLK_UMSK (~(((1U << PDS_CR_PDS_FORCE_NP_GATE_CLK_LEN) - 1) << PDS_CR_PDS_FORCE_NP_GATE_CLK_POS)) +#define PDS_CR_PDS_FORCE_MM_GATE_CLK PDS_CR_PDS_FORCE_MM_GATE_CLK +#define PDS_CR_PDS_FORCE_MM_GATE_CLK_POS (17U) +#define PDS_CR_PDS_FORCE_MM_GATE_CLK_LEN (1U) +#define PDS_CR_PDS_FORCE_MM_GATE_CLK_MSK (((1U << PDS_CR_PDS_FORCE_MM_GATE_CLK_LEN) - 1) << PDS_CR_PDS_FORCE_MM_GATE_CLK_POS) +#define PDS_CR_PDS_FORCE_MM_GATE_CLK_UMSK (~(((1U << PDS_CR_PDS_FORCE_MM_GATE_CLK_LEN) - 1) << PDS_CR_PDS_FORCE_MM_GATE_CLK_POS)) +#define PDS_CR_PDS_FORCE_WB_GATE_CLK PDS_CR_PDS_FORCE_WB_GATE_CLK +#define PDS_CR_PDS_FORCE_WB_GATE_CLK_POS (18U) +#define PDS_CR_PDS_FORCE_WB_GATE_CLK_LEN (1U) +#define PDS_CR_PDS_FORCE_WB_GATE_CLK_MSK (((1U << PDS_CR_PDS_FORCE_WB_GATE_CLK_LEN) - 1) << PDS_CR_PDS_FORCE_WB_GATE_CLK_POS) +#define PDS_CR_PDS_FORCE_WB_GATE_CLK_UMSK (~(((1U << PDS_CR_PDS_FORCE_WB_GATE_CLK_LEN) - 1) << PDS_CR_PDS_FORCE_WB_GATE_CLK_POS)) +#define PDS_CR_PDS_FORCE_USB_GATE_CLK PDS_CR_PDS_FORCE_USB_GATE_CLK +#define PDS_CR_PDS_FORCE_USB_GATE_CLK_POS (19U) +#define PDS_CR_PDS_FORCE_USB_GATE_CLK_LEN (1U) +#define PDS_CR_PDS_FORCE_USB_GATE_CLK_MSK (((1U << PDS_CR_PDS_FORCE_USB_GATE_CLK_LEN) - 1) << PDS_CR_PDS_FORCE_USB_GATE_CLK_POS) +#define PDS_CR_PDS_FORCE_USB_GATE_CLK_UMSK (~(((1U << PDS_CR_PDS_FORCE_USB_GATE_CLK_LEN) - 1) << PDS_CR_PDS_FORCE_USB_GATE_CLK_POS)) + +/* 0x14 : PDS_CTL3 */ +#define PDS_CTL3_OFFSET (0x14) +#define PDS_CR_PDS_FORCE_MISC_PWR_OFF PDS_CR_PDS_FORCE_MISC_PWR_OFF +#define PDS_CR_PDS_FORCE_MISC_PWR_OFF_POS (1U) +#define PDS_CR_PDS_FORCE_MISC_PWR_OFF_LEN (1U) +#define PDS_CR_PDS_FORCE_MISC_PWR_OFF_MSK (((1U << PDS_CR_PDS_FORCE_MISC_PWR_OFF_LEN) - 1) << PDS_CR_PDS_FORCE_MISC_PWR_OFF_POS) +#define PDS_CR_PDS_FORCE_MISC_PWR_OFF_UMSK (~(((1U << PDS_CR_PDS_FORCE_MISC_PWR_OFF_LEN) - 1) << PDS_CR_PDS_FORCE_MISC_PWR_OFF_POS)) +#define PDS_CR_PDS_FORCE_MISC_ISO_EN PDS_CR_PDS_FORCE_MISC_ISO_EN +#define PDS_CR_PDS_FORCE_MISC_ISO_EN_POS (4U) +#define PDS_CR_PDS_FORCE_MISC_ISO_EN_LEN (1U) +#define PDS_CR_PDS_FORCE_MISC_ISO_EN_MSK (((1U << PDS_CR_PDS_FORCE_MISC_ISO_EN_LEN) - 1) << PDS_CR_PDS_FORCE_MISC_ISO_EN_POS) +#define PDS_CR_PDS_FORCE_MISC_ISO_EN_UMSK (~(((1U << PDS_CR_PDS_FORCE_MISC_ISO_EN_LEN) - 1) << PDS_CR_PDS_FORCE_MISC_ISO_EN_POS)) +#define PDS_CR_PDS_FORCE_MISC_PDS_RST PDS_CR_PDS_FORCE_MISC_PDS_RST +#define PDS_CR_PDS_FORCE_MISC_PDS_RST_POS (7U) +#define PDS_CR_PDS_FORCE_MISC_PDS_RST_LEN (1U) +#define PDS_CR_PDS_FORCE_MISC_PDS_RST_MSK (((1U << PDS_CR_PDS_FORCE_MISC_PDS_RST_LEN) - 1) << PDS_CR_PDS_FORCE_MISC_PDS_RST_POS) +#define PDS_CR_PDS_FORCE_MISC_PDS_RST_UMSK (~(((1U << PDS_CR_PDS_FORCE_MISC_PDS_RST_LEN) - 1) << PDS_CR_PDS_FORCE_MISC_PDS_RST_POS)) +#define PDS_CR_PDS_FORCE_MISC_MEM_STBY PDS_CR_PDS_FORCE_MISC_MEM_STBY +#define PDS_CR_PDS_FORCE_MISC_MEM_STBY_POS (10U) +#define PDS_CR_PDS_FORCE_MISC_MEM_STBY_LEN (1U) +#define PDS_CR_PDS_FORCE_MISC_MEM_STBY_MSK (((1U << PDS_CR_PDS_FORCE_MISC_MEM_STBY_LEN) - 1) << PDS_CR_PDS_FORCE_MISC_MEM_STBY_POS) +#define PDS_CR_PDS_FORCE_MISC_MEM_STBY_UMSK (~(((1U << PDS_CR_PDS_FORCE_MISC_MEM_STBY_LEN) - 1) << PDS_CR_PDS_FORCE_MISC_MEM_STBY_POS)) +#define PDS_CR_PDS_FORCE_MISC_GATE_CLK PDS_CR_PDS_FORCE_MISC_GATE_CLK +#define PDS_CR_PDS_FORCE_MISC_GATE_CLK_POS (13U) +#define PDS_CR_PDS_FORCE_MISC_GATE_CLK_LEN (1U) +#define PDS_CR_PDS_FORCE_MISC_GATE_CLK_MSK (((1U << PDS_CR_PDS_FORCE_MISC_GATE_CLK_LEN) - 1) << PDS_CR_PDS_FORCE_MISC_GATE_CLK_POS) +#define PDS_CR_PDS_FORCE_MISC_GATE_CLK_UMSK (~(((1U << PDS_CR_PDS_FORCE_MISC_GATE_CLK_LEN) - 1) << PDS_CR_PDS_FORCE_MISC_GATE_CLK_POS)) +#define PDS_CR_PDS_MM_ISO_EN PDS_CR_PDS_MM_ISO_EN +#define PDS_CR_PDS_MM_ISO_EN_POS (26U) +#define PDS_CR_PDS_MM_ISO_EN_LEN (1U) +#define PDS_CR_PDS_MM_ISO_EN_MSK (((1U << PDS_CR_PDS_MM_ISO_EN_LEN) - 1) << PDS_CR_PDS_MM_ISO_EN_POS) +#define PDS_CR_PDS_MM_ISO_EN_UMSK (~(((1U << PDS_CR_PDS_MM_ISO_EN_LEN) - 1) << PDS_CR_PDS_MM_ISO_EN_POS)) +#define PDS_CR_PDS_USB_ISO_EN PDS_CR_PDS_USB_ISO_EN +#define PDS_CR_PDS_USB_ISO_EN_POS (29U) +#define PDS_CR_PDS_USB_ISO_EN_LEN (1U) +#define PDS_CR_PDS_USB_ISO_EN_MSK (((1U << PDS_CR_PDS_USB_ISO_EN_LEN) - 1) << PDS_CR_PDS_USB_ISO_EN_POS) +#define PDS_CR_PDS_USB_ISO_EN_UMSK (~(((1U << PDS_CR_PDS_USB_ISO_EN_LEN) - 1) << PDS_CR_PDS_USB_ISO_EN_POS)) +#define PDS_CR_PDS_MISC_ISO_EN PDS_CR_PDS_MISC_ISO_EN +#define PDS_CR_PDS_MISC_ISO_EN_POS (30U) +#define PDS_CR_PDS_MISC_ISO_EN_LEN (1U) +#define PDS_CR_PDS_MISC_ISO_EN_MSK (((1U << PDS_CR_PDS_MISC_ISO_EN_LEN) - 1) << PDS_CR_PDS_MISC_ISO_EN_POS) +#define PDS_CR_PDS_MISC_ISO_EN_UMSK (~(((1U << PDS_CR_PDS_MISC_ISO_EN_LEN) - 1) << PDS_CR_PDS_MISC_ISO_EN_POS)) + +/* 0x18 : PDS_CTL4 */ +#define PDS_CTL4_OFFSET (0x18) +#define PDS_CR_PDS_NP_RESET PDS_CR_PDS_NP_RESET +#define PDS_CR_PDS_NP_RESET_POS (1U) +#define PDS_CR_PDS_NP_RESET_LEN (1U) +#define PDS_CR_PDS_NP_RESET_MSK (((1U << PDS_CR_PDS_NP_RESET_LEN) - 1) << PDS_CR_PDS_NP_RESET_POS) +#define PDS_CR_PDS_NP_RESET_UMSK (~(((1U << PDS_CR_PDS_NP_RESET_LEN) - 1) << PDS_CR_PDS_NP_RESET_POS)) +#define PDS_CR_PDS_NP_MEM_STBY PDS_CR_PDS_NP_MEM_STBY +#define PDS_CR_PDS_NP_MEM_STBY_POS (2U) +#define PDS_CR_PDS_NP_MEM_STBY_LEN (1U) +#define PDS_CR_PDS_NP_MEM_STBY_MSK (((1U << PDS_CR_PDS_NP_MEM_STBY_LEN) - 1) << PDS_CR_PDS_NP_MEM_STBY_POS) +#define PDS_CR_PDS_NP_MEM_STBY_UMSK (~(((1U << PDS_CR_PDS_NP_MEM_STBY_LEN) - 1) << PDS_CR_PDS_NP_MEM_STBY_POS)) +#define PDS_CR_PDS_NP_GATE_CLK PDS_CR_PDS_NP_GATE_CLK +#define PDS_CR_PDS_NP_GATE_CLK_POS (3U) +#define PDS_CR_PDS_NP_GATE_CLK_LEN (1U) +#define PDS_CR_PDS_NP_GATE_CLK_MSK (((1U << PDS_CR_PDS_NP_GATE_CLK_LEN) - 1) << PDS_CR_PDS_NP_GATE_CLK_POS) +#define PDS_CR_PDS_NP_GATE_CLK_UMSK (~(((1U << PDS_CR_PDS_NP_GATE_CLK_LEN) - 1) << PDS_CR_PDS_NP_GATE_CLK_POS)) +#define PDS_CR_PDS_MM_PWR_OFF PDS_CR_PDS_MM_PWR_OFF +#define PDS_CR_PDS_MM_PWR_OFF_POS (8U) +#define PDS_CR_PDS_MM_PWR_OFF_LEN (1U) +#define PDS_CR_PDS_MM_PWR_OFF_MSK (((1U << PDS_CR_PDS_MM_PWR_OFF_LEN) - 1) << PDS_CR_PDS_MM_PWR_OFF_POS) +#define PDS_CR_PDS_MM_PWR_OFF_UMSK (~(((1U << PDS_CR_PDS_MM_PWR_OFF_LEN) - 1) << PDS_CR_PDS_MM_PWR_OFF_POS)) +#define PDS_CR_PDS_MM_RESET PDS_CR_PDS_MM_RESET +#define PDS_CR_PDS_MM_RESET_POS (9U) +#define PDS_CR_PDS_MM_RESET_LEN (1U) +#define PDS_CR_PDS_MM_RESET_MSK (((1U << PDS_CR_PDS_MM_RESET_LEN) - 1) << PDS_CR_PDS_MM_RESET_POS) +#define PDS_CR_PDS_MM_RESET_UMSK (~(((1U << PDS_CR_PDS_MM_RESET_LEN) - 1) << PDS_CR_PDS_MM_RESET_POS)) +#define PDS_CR_PDS_MM_MEM_STBY PDS_CR_PDS_MM_MEM_STBY +#define PDS_CR_PDS_MM_MEM_STBY_POS (10U) +#define PDS_CR_PDS_MM_MEM_STBY_LEN (1U) +#define PDS_CR_PDS_MM_MEM_STBY_MSK (((1U << PDS_CR_PDS_MM_MEM_STBY_LEN) - 1) << PDS_CR_PDS_MM_MEM_STBY_POS) +#define PDS_CR_PDS_MM_MEM_STBY_UMSK (~(((1U << PDS_CR_PDS_MM_MEM_STBY_LEN) - 1) << PDS_CR_PDS_MM_MEM_STBY_POS)) +#define PDS_CR_PDS_MM_GATE_CLK PDS_CR_PDS_MM_GATE_CLK +#define PDS_CR_PDS_MM_GATE_CLK_POS (11U) +#define PDS_CR_PDS_MM_GATE_CLK_LEN (1U) +#define PDS_CR_PDS_MM_GATE_CLK_MSK (((1U << PDS_CR_PDS_MM_GATE_CLK_LEN) - 1) << PDS_CR_PDS_MM_GATE_CLK_POS) +#define PDS_CR_PDS_MM_GATE_CLK_UMSK (~(((1U << PDS_CR_PDS_MM_GATE_CLK_LEN) - 1) << PDS_CR_PDS_MM_GATE_CLK_POS)) +#define PDS_CR_PDS_WB_RESET PDS_CR_PDS_WB_RESET +#define PDS_CR_PDS_WB_RESET_POS (13U) +#define PDS_CR_PDS_WB_RESET_LEN (1U) +#define PDS_CR_PDS_WB_RESET_MSK (((1U << PDS_CR_PDS_WB_RESET_LEN) - 1) << PDS_CR_PDS_WB_RESET_POS) +#define PDS_CR_PDS_WB_RESET_UMSK (~(((1U << PDS_CR_PDS_WB_RESET_LEN) - 1) << PDS_CR_PDS_WB_RESET_POS)) +#define PDS_CR_PDS_WB_MEM_STBY PDS_CR_PDS_WB_MEM_STBY +#define PDS_CR_PDS_WB_MEM_STBY_POS (14U) +#define PDS_CR_PDS_WB_MEM_STBY_LEN (1U) +#define PDS_CR_PDS_WB_MEM_STBY_MSK (((1U << PDS_CR_PDS_WB_MEM_STBY_LEN) - 1) << PDS_CR_PDS_WB_MEM_STBY_POS) +#define PDS_CR_PDS_WB_MEM_STBY_UMSK (~(((1U << PDS_CR_PDS_WB_MEM_STBY_LEN) - 1) << PDS_CR_PDS_WB_MEM_STBY_POS)) +#define PDS_CR_PDS_WB_GATE_CLK PDS_CR_PDS_WB_GATE_CLK +#define PDS_CR_PDS_WB_GATE_CLK_POS (15U) +#define PDS_CR_PDS_WB_GATE_CLK_LEN (1U) +#define PDS_CR_PDS_WB_GATE_CLK_MSK (((1U << PDS_CR_PDS_WB_GATE_CLK_LEN) - 1) << PDS_CR_PDS_WB_GATE_CLK_POS) +#define PDS_CR_PDS_WB_GATE_CLK_UMSK (~(((1U << PDS_CR_PDS_WB_GATE_CLK_LEN) - 1) << PDS_CR_PDS_WB_GATE_CLK_POS)) +#define PDS_CR_PDS_USB_PWR_OFF PDS_CR_PDS_USB_PWR_OFF +#define PDS_CR_PDS_USB_PWR_OFF_POS (20U) +#define PDS_CR_PDS_USB_PWR_OFF_LEN (1U) +#define PDS_CR_PDS_USB_PWR_OFF_MSK (((1U << PDS_CR_PDS_USB_PWR_OFF_LEN) - 1) << PDS_CR_PDS_USB_PWR_OFF_POS) +#define PDS_CR_PDS_USB_PWR_OFF_UMSK (~(((1U << PDS_CR_PDS_USB_PWR_OFF_LEN) - 1) << PDS_CR_PDS_USB_PWR_OFF_POS)) +#define PDS_CR_PDS_USB_RESET PDS_CR_PDS_USB_RESET +#define PDS_CR_PDS_USB_RESET_POS (21U) +#define PDS_CR_PDS_USB_RESET_LEN (1U) +#define PDS_CR_PDS_USB_RESET_MSK (((1U << PDS_CR_PDS_USB_RESET_LEN) - 1) << PDS_CR_PDS_USB_RESET_POS) +#define PDS_CR_PDS_USB_RESET_UMSK (~(((1U << PDS_CR_PDS_USB_RESET_LEN) - 1) << PDS_CR_PDS_USB_RESET_POS)) +#define PDS_CR_PDS_USB_MEM_STBY PDS_CR_PDS_USB_MEM_STBY +#define PDS_CR_PDS_USB_MEM_STBY_POS (22U) +#define PDS_CR_PDS_USB_MEM_STBY_LEN (1U) +#define PDS_CR_PDS_USB_MEM_STBY_MSK (((1U << PDS_CR_PDS_USB_MEM_STBY_LEN) - 1) << PDS_CR_PDS_USB_MEM_STBY_POS) +#define PDS_CR_PDS_USB_MEM_STBY_UMSK (~(((1U << PDS_CR_PDS_USB_MEM_STBY_LEN) - 1) << PDS_CR_PDS_USB_MEM_STBY_POS)) +#define PDS_CR_PDS_USB_GATE_CLK PDS_CR_PDS_USB_GATE_CLK +#define PDS_CR_PDS_USB_GATE_CLK_POS (23U) +#define PDS_CR_PDS_USB_GATE_CLK_LEN (1U) +#define PDS_CR_PDS_USB_GATE_CLK_MSK (((1U << PDS_CR_PDS_USB_GATE_CLK_LEN) - 1) << PDS_CR_PDS_USB_GATE_CLK_POS) +#define PDS_CR_PDS_USB_GATE_CLK_UMSK (~(((1U << PDS_CR_PDS_USB_GATE_CLK_LEN) - 1) << PDS_CR_PDS_USB_GATE_CLK_POS)) +#define PDS_CR_PDS_MISC_PWR_OFF PDS_CR_PDS_MISC_PWR_OFF +#define PDS_CR_PDS_MISC_PWR_OFF_POS (24U) +#define PDS_CR_PDS_MISC_PWR_OFF_LEN (1U) +#define PDS_CR_PDS_MISC_PWR_OFF_MSK (((1U << PDS_CR_PDS_MISC_PWR_OFF_LEN) - 1) << PDS_CR_PDS_MISC_PWR_OFF_POS) +#define PDS_CR_PDS_MISC_PWR_OFF_UMSK (~(((1U << PDS_CR_PDS_MISC_PWR_OFF_LEN) - 1) << PDS_CR_PDS_MISC_PWR_OFF_POS)) +#define PDS_CR_PDS_MISC_RESET PDS_CR_PDS_MISC_RESET +#define PDS_CR_PDS_MISC_RESET_POS (25U) +#define PDS_CR_PDS_MISC_RESET_LEN (1U) +#define PDS_CR_PDS_MISC_RESET_MSK (((1U << PDS_CR_PDS_MISC_RESET_LEN) - 1) << PDS_CR_PDS_MISC_RESET_POS) +#define PDS_CR_PDS_MISC_RESET_UMSK (~(((1U << PDS_CR_PDS_MISC_RESET_LEN) - 1) << PDS_CR_PDS_MISC_RESET_POS)) +#define PDS_CR_PDS_MISC_MEM_STBY PDS_CR_PDS_MISC_MEM_STBY +#define PDS_CR_PDS_MISC_MEM_STBY_POS (26U) +#define PDS_CR_PDS_MISC_MEM_STBY_LEN (1U) +#define PDS_CR_PDS_MISC_MEM_STBY_MSK (((1U << PDS_CR_PDS_MISC_MEM_STBY_LEN) - 1) << PDS_CR_PDS_MISC_MEM_STBY_POS) +#define PDS_CR_PDS_MISC_MEM_STBY_UMSK (~(((1U << PDS_CR_PDS_MISC_MEM_STBY_LEN) - 1) << PDS_CR_PDS_MISC_MEM_STBY_POS)) +#define PDS_CR_PDS_MISC_GATE_CLK PDS_CR_PDS_MISC_GATE_CLK +#define PDS_CR_PDS_MISC_GATE_CLK_POS (27U) +#define PDS_CR_PDS_MISC_GATE_CLK_LEN (1U) +#define PDS_CR_PDS_MISC_GATE_CLK_MSK (((1U << PDS_CR_PDS_MISC_GATE_CLK_LEN) - 1) << PDS_CR_PDS_MISC_GATE_CLK_POS) +#define PDS_CR_PDS_MISC_GATE_CLK_UMSK (~(((1U << PDS_CR_PDS_MISC_GATE_CLK_LEN) - 1) << PDS_CR_PDS_MISC_GATE_CLK_POS)) + +/* 0x1C : pds_stat */ +#define PDS_STAT_OFFSET (0x1C) +#define PDS_RO_PDS_STATE PDS_RO_PDS_STATE +#define PDS_RO_PDS_STATE_POS (0U) +#define PDS_RO_PDS_STATE_LEN (5U) +#define PDS_RO_PDS_STATE_MSK (((1U << PDS_RO_PDS_STATE_LEN) - 1) << PDS_RO_PDS_STATE_POS) +#define PDS_RO_PDS_STATE_UMSK (~(((1U << PDS_RO_PDS_STATE_LEN) - 1) << PDS_RO_PDS_STATE_POS)) +#define PDS_RO_PDS_RF_STATE PDS_RO_PDS_RF_STATE +#define PDS_RO_PDS_RF_STATE_POS (8U) +#define PDS_RO_PDS_RF_STATE_LEN (5U) +#define PDS_RO_PDS_RF_STATE_MSK (((1U << PDS_RO_PDS_RF_STATE_LEN) - 1) << PDS_RO_PDS_RF_STATE_POS) +#define PDS_RO_PDS_RF_STATE_UMSK (~(((1U << PDS_RO_PDS_RF_STATE_LEN) - 1) << PDS_RO_PDS_RF_STATE_POS)) +#define PDS_RESET_EVENT PDS_RESET_EVENT +#define PDS_RESET_EVENT_POS (24U) +#define PDS_RESET_EVENT_LEN (3U) +#define PDS_RESET_EVENT_MSK (((1U << PDS_RESET_EVENT_LEN) - 1) << PDS_RESET_EVENT_POS) +#define PDS_RESET_EVENT_UMSK (~(((1U << PDS_RESET_EVENT_LEN) - 1) << PDS_RESET_EVENT_POS)) +#define PDS_CLR_RESET_EVENT PDS_CLR_RESET_EVENT +#define PDS_CLR_RESET_EVENT_POS (31U) +#define PDS_CLR_RESET_EVENT_LEN (1U) +#define PDS_CLR_RESET_EVENT_MSK (((1U << PDS_CLR_RESET_EVENT_LEN) - 1) << PDS_CLR_RESET_EVENT_POS) +#define PDS_CLR_RESET_EVENT_UMSK (~(((1U << PDS_CLR_RESET_EVENT_LEN) - 1) << PDS_CLR_RESET_EVENT_POS)) + +/* 0x20 : pds_ram1 */ +#define PDS_RAM1_OFFSET (0x20) +#define PDS_CR_OCRAM_SLP PDS_CR_OCRAM_SLP +#define PDS_CR_OCRAM_SLP_POS (0U) +#define PDS_CR_OCRAM_SLP_LEN (4U) +#define PDS_CR_OCRAM_SLP_MSK (((1U << PDS_CR_OCRAM_SLP_LEN) - 1) << PDS_CR_OCRAM_SLP_POS) +#define PDS_CR_OCRAM_SLP_UMSK (~(((1U << PDS_CR_OCRAM_SLP_LEN) - 1) << PDS_CR_OCRAM_SLP_POS)) +#define PDS_CR_OCRAM_RET PDS_CR_OCRAM_RET +#define PDS_CR_OCRAM_RET_POS (4U) +#define PDS_CR_OCRAM_RET_LEN (4U) +#define PDS_CR_OCRAM_RET_MSK (((1U << PDS_CR_OCRAM_RET_LEN) - 1) << PDS_CR_OCRAM_RET_POS) +#define PDS_CR_OCRAM_RET_UMSK (~(((1U << PDS_CR_OCRAM_RET_LEN) - 1) << PDS_CR_OCRAM_RET_POS)) +#define PDS_CR_PDS_RAM_CLK_CNT PDS_CR_PDS_RAM_CLK_CNT +#define PDS_CR_PDS_RAM_CLK_CNT_POS (8U) +#define PDS_CR_PDS_RAM_CLK_CNT_LEN (6U) +#define PDS_CR_PDS_RAM_CLK_CNT_MSK (((1U << PDS_CR_PDS_RAM_CLK_CNT_LEN) - 1) << PDS_CR_PDS_RAM_CLK_CNT_POS) +#define PDS_CR_PDS_RAM_CLK_CNT_UMSK (~(((1U << PDS_CR_PDS_RAM_CLK_CNT_LEN) - 1) << PDS_CR_PDS_RAM_CLK_CNT_POS)) +#define PDS_CR_PDS_RAM_CLK2_CNT PDS_CR_PDS_RAM_CLK2_CNT +#define PDS_CR_PDS_RAM_CLK2_CNT_POS (16U) +#define PDS_CR_PDS_RAM_CLK2_CNT_LEN (6U) +#define PDS_CR_PDS_RAM_CLK2_CNT_MSK (((1U << PDS_CR_PDS_RAM_CLK2_CNT_LEN) - 1) << PDS_CR_PDS_RAM_CLK2_CNT_POS) +#define PDS_CR_PDS_RAM_CLK2_CNT_UMSK (~(((1U << PDS_CR_PDS_RAM_CLK2_CNT_LEN) - 1) << PDS_CR_PDS_RAM_CLK2_CNT_POS)) +#define PDS_CR_PDS_CTRL_NP_RAM_CLK PDS_CR_PDS_CTRL_NP_RAM_CLK +#define PDS_CR_PDS_CTRL_NP_RAM_CLK_POS (24U) +#define PDS_CR_PDS_CTRL_NP_RAM_CLK_LEN (1U) +#define PDS_CR_PDS_CTRL_NP_RAM_CLK_MSK (((1U << PDS_CR_PDS_CTRL_NP_RAM_CLK_LEN) - 1) << PDS_CR_PDS_CTRL_NP_RAM_CLK_POS) +#define PDS_CR_PDS_CTRL_NP_RAM_CLK_UMSK (~(((1U << PDS_CR_PDS_CTRL_NP_RAM_CLK_LEN) - 1) << PDS_CR_PDS_CTRL_NP_RAM_CLK_POS)) +#define PDS_CR_PDS_CTRL_MM_RAM_CLK PDS_CR_PDS_CTRL_MM_RAM_CLK +#define PDS_CR_PDS_CTRL_MM_RAM_CLK_POS (25U) +#define PDS_CR_PDS_CTRL_MM_RAM_CLK_LEN (1U) +#define PDS_CR_PDS_CTRL_MM_RAM_CLK_MSK (((1U << PDS_CR_PDS_CTRL_MM_RAM_CLK_LEN) - 1) << PDS_CR_PDS_CTRL_MM_RAM_CLK_POS) +#define PDS_CR_PDS_CTRL_MM_RAM_CLK_UMSK (~(((1U << PDS_CR_PDS_CTRL_MM_RAM_CLK_LEN) - 1) << PDS_CR_PDS_CTRL_MM_RAM_CLK_POS)) +#define PDS_CR_PDS_CTRL_WB_RAM_CLK PDS_CR_PDS_CTRL_WB_RAM_CLK +#define PDS_CR_PDS_CTRL_WB_RAM_CLK_POS (26U) +#define PDS_CR_PDS_CTRL_WB_RAM_CLK_LEN (1U) +#define PDS_CR_PDS_CTRL_WB_RAM_CLK_MSK (((1U << PDS_CR_PDS_CTRL_WB_RAM_CLK_LEN) - 1) << PDS_CR_PDS_CTRL_WB_RAM_CLK_POS) +#define PDS_CR_PDS_CTRL_WB_RAM_CLK_UMSK (~(((1U << PDS_CR_PDS_CTRL_WB_RAM_CLK_LEN) - 1) << PDS_CR_PDS_CTRL_WB_RAM_CLK_POS)) +#define PDS_CR_PDS_CTRL_USB_RAM_CLK PDS_CR_PDS_CTRL_USB_RAM_CLK +#define PDS_CR_PDS_CTRL_USB_RAM_CLK_POS (27U) +#define PDS_CR_PDS_CTRL_USB_RAM_CLK_LEN (1U) +#define PDS_CR_PDS_CTRL_USB_RAM_CLK_MSK (((1U << PDS_CR_PDS_CTRL_USB_RAM_CLK_LEN) - 1) << PDS_CR_PDS_CTRL_USB_RAM_CLK_POS) +#define PDS_CR_PDS_CTRL_USB_RAM_CLK_UMSK (~(((1U << PDS_CR_PDS_CTRL_USB_RAM_CLK_LEN) - 1) << PDS_CR_PDS_CTRL_USB_RAM_CLK_POS)) +#define PDS_CR_PDS_CTRL_MISC_RAM_CLK PDS_CR_PDS_CTRL_MISC_RAM_CLK +#define PDS_CR_PDS_CTRL_MISC_RAM_CLK_POS (28U) +#define PDS_CR_PDS_CTRL_MISC_RAM_CLK_LEN (1U) +#define PDS_CR_PDS_CTRL_MISC_RAM_CLK_MSK (((1U << PDS_CR_PDS_CTRL_MISC_RAM_CLK_LEN) - 1) << PDS_CR_PDS_CTRL_MISC_RAM_CLK_POS) +#define PDS_CR_PDS_CTRL_MISC_RAM_CLK_UMSK (~(((1U << PDS_CR_PDS_CTRL_MISC_RAM_CLK_LEN) - 1) << PDS_CR_PDS_CTRL_MISC_RAM_CLK_POS)) +#define PDS_CR_PDS_CTRL_RAM_CLK2 PDS_CR_PDS_CTRL_RAM_CLK2 +#define PDS_CR_PDS_CTRL_RAM_CLK2_POS (30U) +#define PDS_CR_PDS_CTRL_RAM_CLK2_LEN (1U) +#define PDS_CR_PDS_CTRL_RAM_CLK2_MSK (((1U << PDS_CR_PDS_CTRL_RAM_CLK2_LEN) - 1) << PDS_CR_PDS_CTRL_RAM_CLK2_POS) +#define PDS_CR_PDS_CTRL_RAM_CLK2_UMSK (~(((1U << PDS_CR_PDS_CTRL_RAM_CLK2_LEN) - 1) << PDS_CR_PDS_CTRL_RAM_CLK2_POS)) +#define PDS_CR_PDS_CTRL_RAM_CLK PDS_CR_PDS_CTRL_RAM_CLK +#define PDS_CR_PDS_CTRL_RAM_CLK_POS (31U) +#define PDS_CR_PDS_CTRL_RAM_CLK_LEN (1U) +#define PDS_CR_PDS_CTRL_RAM_CLK_MSK (((1U << PDS_CR_PDS_CTRL_RAM_CLK_LEN) - 1) << PDS_CR_PDS_CTRL_RAM_CLK_POS) +#define PDS_CR_PDS_CTRL_RAM_CLK_UMSK (~(((1U << PDS_CR_PDS_CTRL_RAM_CLK_LEN) - 1) << PDS_CR_PDS_CTRL_RAM_CLK_POS)) + +/* 0x24 : PDS_CTL5 */ +#define PDS_CTL5_OFFSET (0x24) +#define PDS_CR_NP_WFI_MASK PDS_CR_NP_WFI_MASK +#define PDS_CR_NP_WFI_MASK_POS (0U) +#define PDS_CR_NP_WFI_MASK_LEN (1U) +#define PDS_CR_NP_WFI_MASK_MSK (((1U << PDS_CR_NP_WFI_MASK_LEN) - 1) << PDS_CR_NP_WFI_MASK_POS) +#define PDS_CR_NP_WFI_MASK_UMSK (~(((1U << PDS_CR_NP_WFI_MASK_LEN) - 1) << PDS_CR_NP_WFI_MASK_POS)) +#define PDS_CR_MM_WFI_MASK PDS_CR_MM_WFI_MASK +#define PDS_CR_MM_WFI_MASK_POS (2U) +#define PDS_CR_MM_WFI_MASK_LEN (1U) +#define PDS_CR_MM_WFI_MASK_MSK (((1U << PDS_CR_MM_WFI_MASK_LEN) - 1) << PDS_CR_MM_WFI_MASK_POS) +#define PDS_CR_MM_WFI_MASK_UMSK (~(((1U << PDS_CR_MM_WFI_MASK_LEN) - 1) << PDS_CR_MM_WFI_MASK_POS)) +#define PDS_CR_PICO_WFI_MASK PDS_CR_PICO_WFI_MASK +#define PDS_CR_PICO_WFI_MASK_POS (4U) +#define PDS_CR_PICO_WFI_MASK_LEN (1U) +#define PDS_CR_PICO_WFI_MASK_MSK (((1U << PDS_CR_PICO_WFI_MASK_LEN) - 1) << PDS_CR_PICO_WFI_MASK_POS) +#define PDS_CR_PICO_WFI_MASK_UMSK (~(((1U << PDS_CR_PICO_WFI_MASK_LEN) - 1) << PDS_CR_PICO_WFI_MASK_POS)) +#define PDS_CR_PDS_CTRL_USB33 PDS_CR_PDS_CTRL_USB33 +#define PDS_CR_PDS_CTRL_USB33_POS (8U) +#define PDS_CR_PDS_CTRL_USB33_LEN (1U) +#define PDS_CR_PDS_CTRL_USB33_MSK (((1U << PDS_CR_PDS_CTRL_USB33_LEN) - 1) << PDS_CR_PDS_CTRL_USB33_POS) +#define PDS_CR_PDS_CTRL_USB33_UMSK (~(((1U << PDS_CR_PDS_CTRL_USB33_LEN) - 1) << PDS_CR_PDS_CTRL_USB33_POS)) +#define PDS_CR_PDS_PD_LDO18IO PDS_CR_PDS_PD_LDO18IO +#define PDS_CR_PDS_PD_LDO18IO_POS (9U) +#define PDS_CR_PDS_PD_LDO18IO_LEN (1U) +#define PDS_CR_PDS_PD_LDO18IO_MSK (((1U << PDS_CR_PDS_PD_LDO18IO_LEN) - 1) << PDS_CR_PDS_PD_LDO18IO_POS) +#define PDS_CR_PDS_PD_LDO18IO_UMSK (~(((1U << PDS_CR_PDS_PD_LDO18IO_LEN) - 1) << PDS_CR_PDS_PD_LDO18IO_POS)) +#define PDS_CR_PDS_GPIO_KEEP_EN PDS_CR_PDS_GPIO_KEEP_EN +#define PDS_CR_PDS_GPIO_KEEP_EN_POS (16U) +#define PDS_CR_PDS_GPIO_KEEP_EN_LEN (3U) +#define PDS_CR_PDS_GPIO_KEEP_EN_MSK (((1U << PDS_CR_PDS_GPIO_KEEP_EN_LEN) - 1) << PDS_CR_PDS_GPIO_KEEP_EN_POS) +#define PDS_CR_PDS_GPIO_KEEP_EN_UMSK (~(((1U << PDS_CR_PDS_GPIO_KEEP_EN_LEN) - 1) << PDS_CR_PDS_GPIO_KEEP_EN_POS)) + +/* 0x28 : PDS_RAM2 */ +#define PDS_RAM2_OFFSET (0x28) +#define PDS_CR_WRAM_SLP PDS_CR_WRAM_SLP +#define PDS_CR_WRAM_SLP_POS (0U) +#define PDS_CR_WRAM_SLP_LEN (10U) +#define PDS_CR_WRAM_SLP_MSK (((1U << PDS_CR_WRAM_SLP_LEN) - 1) << PDS_CR_WRAM_SLP_POS) +#define PDS_CR_WRAM_SLP_UMSK (~(((1U << PDS_CR_WRAM_SLP_LEN) - 1) << PDS_CR_WRAM_SLP_POS)) +#define PDS_CR_WRAM_RET PDS_CR_WRAM_RET +#define PDS_CR_WRAM_RET_POS (10U) +#define PDS_CR_WRAM_RET_LEN (10U) +#define PDS_CR_WRAM_RET_MSK (((1U << PDS_CR_WRAM_RET_LEN) - 1) << PDS_CR_WRAM_RET_POS) +#define PDS_CR_WRAM_RET_UMSK (~(((1U << PDS_CR_WRAM_RET_LEN) - 1) << PDS_CR_WRAM_RET_POS)) + +/* 0x30 : pds_gpio_i_set */ +#define PDS_GPIO_I_SET_OFFSET (0x30) +#define PDS_CR_PDS_GPIO_IE_SET PDS_CR_PDS_GPIO_IE_SET +#define PDS_CR_PDS_GPIO_IE_SET_POS (0U) +#define PDS_CR_PDS_GPIO_IE_SET_LEN (3U) +#define PDS_CR_PDS_GPIO_IE_SET_MSK (((1U << PDS_CR_PDS_GPIO_IE_SET_LEN) - 1) << PDS_CR_PDS_GPIO_IE_SET_POS) +#define PDS_CR_PDS_GPIO_IE_SET_UMSK (~(((1U << PDS_CR_PDS_GPIO_IE_SET_LEN) - 1) << PDS_CR_PDS_GPIO_IE_SET_POS)) +#define PDS_CR_PDS_GPIO_PD_SET PDS_CR_PDS_GPIO_PD_SET +#define PDS_CR_PDS_GPIO_PD_SET_POS (3U) +#define PDS_CR_PDS_GPIO_PD_SET_LEN (3U) +#define PDS_CR_PDS_GPIO_PD_SET_MSK (((1U << PDS_CR_PDS_GPIO_PD_SET_LEN) - 1) << PDS_CR_PDS_GPIO_PD_SET_POS) +#define PDS_CR_PDS_GPIO_PD_SET_UMSK (~(((1U << PDS_CR_PDS_GPIO_PD_SET_LEN) - 1) << PDS_CR_PDS_GPIO_PD_SET_POS)) +#define PDS_CR_PDS_GPIO_PU_SET PDS_CR_PDS_GPIO_PU_SET +#define PDS_CR_PDS_GPIO_PU_SET_POS (6U) +#define PDS_CR_PDS_GPIO_PU_SET_LEN (3U) +#define PDS_CR_PDS_GPIO_PU_SET_MSK (((1U << PDS_CR_PDS_GPIO_PU_SET_LEN) - 1) << PDS_CR_PDS_GPIO_PU_SET_POS) +#define PDS_CR_PDS_GPIO_PU_SET_UMSK (~(((1U << PDS_CR_PDS_GPIO_PU_SET_LEN) - 1) << PDS_CR_PDS_GPIO_PU_SET_POS)) + +/* 0x34 : pds_gpio_pd_set */ +#define PDS_GPIO_PD_SET_OFFSET (0x34) +#define PDS_CR_PDS_GPIO_SET_INT_MASK PDS_CR_PDS_GPIO_SET_INT_MASK +#define PDS_CR_PDS_GPIO_SET_INT_MASK_POS (0U) +#define PDS_CR_PDS_GPIO_SET_INT_MASK_LEN (32U) +#define PDS_CR_PDS_GPIO_SET_INT_MASK_MSK (((1U << PDS_CR_PDS_GPIO_SET_INT_MASK_LEN) - 1) << PDS_CR_PDS_GPIO_SET_INT_MASK_POS) +#define PDS_CR_PDS_GPIO_SET_INT_MASK_UMSK (~(((1U << PDS_CR_PDS_GPIO_SET_INT_MASK_LEN) - 1) << PDS_CR_PDS_GPIO_SET_INT_MASK_POS)) + +/* 0x40 : pds_gpio_int */ +#define PDS_GPIO_INT_OFFSET (0x40) +#define PDS_GPIO_SET1_INT_CLR PDS_GPIO_SET1_INT_CLR +#define PDS_GPIO_SET1_INT_CLR_POS (2U) +#define PDS_GPIO_SET1_INT_CLR_LEN (1U) +#define PDS_GPIO_SET1_INT_CLR_MSK (((1U << PDS_GPIO_SET1_INT_CLR_LEN) - 1) << PDS_GPIO_SET1_INT_CLR_POS) +#define PDS_GPIO_SET1_INT_CLR_UMSK (~(((1U << PDS_GPIO_SET1_INT_CLR_LEN) - 1) << PDS_GPIO_SET1_INT_CLR_POS)) +#define PDS_GPIO_SET1_INT_MODE PDS_GPIO_SET1_INT_MODE +#define PDS_GPIO_SET1_INT_MODE_POS (4U) +#define PDS_GPIO_SET1_INT_MODE_LEN (4U) +#define PDS_GPIO_SET1_INT_MODE_MSK (((1U << PDS_GPIO_SET1_INT_MODE_LEN) - 1) << PDS_GPIO_SET1_INT_MODE_POS) +#define PDS_GPIO_SET1_INT_MODE_UMSK (~(((1U << PDS_GPIO_SET1_INT_MODE_LEN) - 1) << PDS_GPIO_SET1_INT_MODE_POS)) +#define PDS_GPIO_SET2_INT_CLR PDS_GPIO_SET2_INT_CLR +#define PDS_GPIO_SET2_INT_CLR_POS (10U) +#define PDS_GPIO_SET2_INT_CLR_LEN (1U) +#define PDS_GPIO_SET2_INT_CLR_MSK (((1U << PDS_GPIO_SET2_INT_CLR_LEN) - 1) << PDS_GPIO_SET2_INT_CLR_POS) +#define PDS_GPIO_SET2_INT_CLR_UMSK (~(((1U << PDS_GPIO_SET2_INT_CLR_LEN) - 1) << PDS_GPIO_SET2_INT_CLR_POS)) +#define PDS_GPIO_SET2_INT_MODE PDS_GPIO_SET2_INT_MODE +#define PDS_GPIO_SET2_INT_MODE_POS (12U) +#define PDS_GPIO_SET2_INT_MODE_LEN (4U) +#define PDS_GPIO_SET2_INT_MODE_MSK (((1U << PDS_GPIO_SET2_INT_MODE_LEN) - 1) << PDS_GPIO_SET2_INT_MODE_POS) +#define PDS_GPIO_SET2_INT_MODE_UMSK (~(((1U << PDS_GPIO_SET2_INT_MODE_LEN) - 1) << PDS_GPIO_SET2_INT_MODE_POS)) +#define PDS_GPIO_SET3_INT_CLR PDS_GPIO_SET3_INT_CLR +#define PDS_GPIO_SET3_INT_CLR_POS (18U) +#define PDS_GPIO_SET3_INT_CLR_LEN (1U) +#define PDS_GPIO_SET3_INT_CLR_MSK (((1U << PDS_GPIO_SET3_INT_CLR_LEN) - 1) << PDS_GPIO_SET3_INT_CLR_POS) +#define PDS_GPIO_SET3_INT_CLR_UMSK (~(((1U << PDS_GPIO_SET3_INT_CLR_LEN) - 1) << PDS_GPIO_SET3_INT_CLR_POS)) +#define PDS_GPIO_SET3_INT_MODE PDS_GPIO_SET3_INT_MODE +#define PDS_GPIO_SET3_INT_MODE_POS (20U) +#define PDS_GPIO_SET3_INT_MODE_LEN (4U) +#define PDS_GPIO_SET3_INT_MODE_MSK (((1U << PDS_GPIO_SET3_INT_MODE_LEN) - 1) << PDS_GPIO_SET3_INT_MODE_POS) +#define PDS_GPIO_SET3_INT_MODE_UMSK (~(((1U << PDS_GPIO_SET3_INT_MODE_LEN) - 1) << PDS_GPIO_SET3_INT_MODE_POS)) +#define PDS_GPIO_SET4_INT_CLR PDS_GPIO_SET4_INT_CLR +#define PDS_GPIO_SET4_INT_CLR_POS (26U) +#define PDS_GPIO_SET4_INT_CLR_LEN (1U) +#define PDS_GPIO_SET4_INT_CLR_MSK (((1U << PDS_GPIO_SET4_INT_CLR_LEN) - 1) << PDS_GPIO_SET4_INT_CLR_POS) +#define PDS_GPIO_SET4_INT_CLR_UMSK (~(((1U << PDS_GPIO_SET4_INT_CLR_LEN) - 1) << PDS_GPIO_SET4_INT_CLR_POS)) +#define PDS_GPIO_SET4_INT_MODE PDS_GPIO_SET4_INT_MODE +#define PDS_GPIO_SET4_INT_MODE_POS (28U) +#define PDS_GPIO_SET4_INT_MODE_LEN (4U) +#define PDS_GPIO_SET4_INT_MODE_MSK (((1U << PDS_GPIO_SET4_INT_MODE_LEN) - 1) << PDS_GPIO_SET4_INT_MODE_POS) +#define PDS_GPIO_SET4_INT_MODE_UMSK (~(((1U << PDS_GPIO_SET4_INT_MODE_LEN) - 1) << PDS_GPIO_SET4_INT_MODE_POS)) + +/* 0x44 : pds_gpio_stat */ +#define PDS_GPIO_STAT_OFFSET (0x44) +#define PDS_GPIO_INT_STAT PDS_GPIO_INT_STAT +#define PDS_GPIO_INT_STAT_POS (0U) +#define PDS_GPIO_INT_STAT_LEN (32U) +#define PDS_GPIO_INT_STAT_MSK (((1U << PDS_GPIO_INT_STAT_LEN) - 1) << PDS_GPIO_INT_STAT_POS) +#define PDS_GPIO_INT_STAT_UMSK (~(((1U << PDS_GPIO_INT_STAT_LEN) - 1) << PDS_GPIO_INT_STAT_POS)) + +/* 0x110 : cpu_core_cfg0 */ +#define PDS_CPU_CORE_CFG0_OFFSET (0x110) +#define PDS_REG_PICO_CLK_EN PDS_REG_PICO_CLK_EN +#define PDS_REG_PICO_CLK_EN_POS (28U) +#define PDS_REG_PICO_CLK_EN_LEN (1U) +#define PDS_REG_PICO_CLK_EN_MSK (((1U << PDS_REG_PICO_CLK_EN_LEN) - 1) << PDS_REG_PICO_CLK_EN_POS) +#define PDS_REG_PICO_CLK_EN_UMSK (~(((1U << PDS_REG_PICO_CLK_EN_LEN) - 1) << PDS_REG_PICO_CLK_EN_POS)) +#define PDS_E902_DFS_REQ PDS_E902_DFS_REQ +#define PDS_E902_DFS_REQ_POS (29U) +#define PDS_E902_DFS_REQ_LEN (1U) +#define PDS_E902_DFS_REQ_MSK (((1U << PDS_E902_DFS_REQ_LEN) - 1) << PDS_E902_DFS_REQ_POS) +#define PDS_E902_DFS_REQ_UMSK (~(((1U << PDS_E902_DFS_REQ_LEN) - 1) << PDS_E902_DFS_REQ_POS)) +#define PDS_E902_DFS_ACK PDS_E902_DFS_ACK +#define PDS_E902_DFS_ACK_POS (30U) +#define PDS_E902_DFS_ACK_LEN (1U) +#define PDS_E902_DFS_ACK_MSK (((1U << PDS_E902_DFS_ACK_LEN) - 1) << PDS_E902_DFS_ACK_POS) +#define PDS_E902_DFS_ACK_UMSK (~(((1U << PDS_E902_DFS_ACK_LEN) - 1) << PDS_E902_DFS_ACK_POS)) + +/* 0x114 : cpu_core_cfg1 */ +#define PDS_CPU_CORE_CFG1_OFFSET (0x114) +#define PDS_REG_PLL_SEL PDS_REG_PLL_SEL +#define PDS_REG_PLL_SEL_POS (4U) +#define PDS_REG_PLL_SEL_LEN (2U) +#define PDS_REG_PLL_SEL_MSK (((1U << PDS_REG_PLL_SEL_LEN) - 1) << PDS_REG_PLL_SEL_POS) +#define PDS_REG_PLL_SEL_UMSK (~(((1U << PDS_REG_PLL_SEL_LEN) - 1) << PDS_REG_PLL_SEL_POS)) +#define PDS_REG_MCU1_CLK_EN PDS_REG_MCU1_CLK_EN +#define PDS_REG_MCU1_CLK_EN_POS (8U) +#define PDS_REG_MCU1_CLK_EN_LEN (1U) +#define PDS_REG_MCU1_CLK_EN_MSK (((1U << PDS_REG_MCU1_CLK_EN_LEN) - 1) << PDS_REG_MCU1_CLK_EN_POS) +#define PDS_REG_MCU1_CLK_EN_UMSK (~(((1U << PDS_REG_MCU1_CLK_EN_LEN) - 1) << PDS_REG_MCU1_CLK_EN_POS)) + +/* 0x12C : cpu_core_cfg7 */ +#define PDS_CPU_CORE_CFG7_OFFSET (0x12C) +#define PDS_REG_PICO_DIV PDS_REG_PICO_DIV +#define PDS_REG_PICO_DIV_POS (0U) +#define PDS_REG_PICO_DIV_LEN (8U) +#define PDS_REG_PICO_DIV_MSK (((1U << PDS_REG_PICO_DIV_LEN) - 1) << PDS_REG_PICO_DIV_POS) +#define PDS_REG_PICO_DIV_UMSK (~(((1U << PDS_REG_PICO_DIV_LEN) - 1) << PDS_REG_PICO_DIV_POS)) +#define PDS_E902_LPMD_B PDS_E902_LPMD_B +#define PDS_E902_LPMD_B_POS (28U) +#define PDS_E902_LPMD_B_LEN (2U) +#define PDS_E902_LPMD_B_MSK (((1U << PDS_E902_LPMD_B_LEN) - 1) << PDS_E902_LPMD_B_POS) +#define PDS_E902_LPMD_B_UMSK (~(((1U << PDS_E902_LPMD_B_LEN) - 1) << PDS_E902_LPMD_B_POS)) +#define PDS_PICO_RST_MASK PDS_PICO_RST_MASK +#define PDS_PICO_RST_MASK_POS (31U) +#define PDS_PICO_RST_MASK_LEN (1U) +#define PDS_PICO_RST_MASK_MSK (((1U << PDS_PICO_RST_MASK_LEN) - 1) << PDS_PICO_RST_MASK_POS) +#define PDS_PICO_RST_MASK_UMSK (~(((1U << PDS_PICO_RST_MASK_LEN) - 1) << PDS_PICO_RST_MASK_POS)) + +/* 0x130 : cpu_core_cfg8 */ +#define PDS_CPU_CORE_CFG8_OFFSET (0x130) +#define PDS_E902_RTC_DIV PDS_E902_RTC_DIV +#define PDS_E902_RTC_DIV_POS (0U) +#define PDS_E902_RTC_DIV_LEN (10U) +#define PDS_E902_RTC_DIV_MSK (((1U << PDS_E902_RTC_DIV_LEN) - 1) << PDS_E902_RTC_DIV_POS) +#define PDS_E902_RTC_DIV_UMSK (~(((1U << PDS_E902_RTC_DIV_LEN) - 1) << PDS_E902_RTC_DIV_POS)) +#define PDS_E902_RTC_RST PDS_E902_RTC_RST +#define PDS_E902_RTC_RST_POS (30U) +#define PDS_E902_RTC_RST_LEN (1U) +#define PDS_E902_RTC_RST_MSK (((1U << PDS_E902_RTC_RST_LEN) - 1) << PDS_E902_RTC_RST_POS) +#define PDS_E902_RTC_RST_UMSK (~(((1U << PDS_E902_RTC_RST_LEN) - 1) << PDS_E902_RTC_RST_POS)) +#define PDS_E902_RTC_EN PDS_E902_RTC_EN +#define PDS_E902_RTC_EN_POS (31U) +#define PDS_E902_RTC_EN_LEN (1U) +#define PDS_E902_RTC_EN_MSK (((1U << PDS_E902_RTC_EN_LEN) - 1) << PDS_E902_RTC_EN_POS) +#define PDS_E902_RTC_EN_UMSK (~(((1U << PDS_E902_RTC_EN_LEN) - 1) << PDS_E902_RTC_EN_POS)) + +/* 0x134 : cpu_core_cfg9 */ +#define PDS_CPU_CORE_CFG9_OFFSET (0x134) +#define PDS_PICO_RTC_CNT_L PDS_PICO_RTC_CNT_L +#define PDS_PICO_RTC_CNT_L_POS (0U) +#define PDS_PICO_RTC_CNT_L_LEN (32U) +#define PDS_PICO_RTC_CNT_L_MSK (((1U << PDS_PICO_RTC_CNT_L_LEN) - 1) << PDS_PICO_RTC_CNT_L_POS) +#define PDS_PICO_RTC_CNT_L_UMSK (~(((1U << PDS_PICO_RTC_CNT_L_LEN) - 1) << PDS_PICO_RTC_CNT_L_POS)) + +/* 0x138 : cpu_core_cfg10 */ +#define PDS_CPU_CORE_CFG10_OFFSET (0x138) +#define PDS_PICO_RTC_CNT_H PDS_PICO_RTC_CNT_H +#define PDS_PICO_RTC_CNT_H_POS (0U) +#define PDS_PICO_RTC_CNT_H_LEN (32U) +#define PDS_PICO_RTC_CNT_H_MSK (((1U << PDS_PICO_RTC_CNT_H_LEN) - 1) << PDS_PICO_RTC_CNT_H_POS) +#define PDS_PICO_RTC_CNT_H_UMSK (~(((1U << PDS_PICO_RTC_CNT_H_LEN) - 1) << PDS_PICO_RTC_CNT_H_POS)) + +/* 0x140 : cpu_core_cfg12 */ +#define PDS_CPU_CORE_CFG12_OFFSET (0x140) +#define PDS_E902_IAHBL_BASE PDS_E902_IAHBL_BASE +#define PDS_E902_IAHBL_BASE_POS (0U) +#define PDS_E902_IAHBL_BASE_LEN (12U) +#define PDS_E902_IAHBL_BASE_MSK (((1U << PDS_E902_IAHBL_BASE_LEN) - 1) << PDS_E902_IAHBL_BASE_POS) +#define PDS_E902_IAHBL_BASE_UMSK (~(((1U << PDS_E902_IAHBL_BASE_LEN) - 1) << PDS_E902_IAHBL_BASE_POS)) +#define PDS_E902_IAHBL_MASK PDS_E902_IAHBL_MASK +#define PDS_E902_IAHBL_MASK_POS (16U) +#define PDS_E902_IAHBL_MASK_LEN (12U) +#define PDS_E902_IAHBL_MASK_MSK (((1U << PDS_E902_IAHBL_MASK_LEN) - 1) << PDS_E902_IAHBL_MASK_POS) +#define PDS_E902_IAHBL_MASK_UMSK (~(((1U << PDS_E902_IAHBL_MASK_LEN) - 1) << PDS_E902_IAHBL_MASK_POS)) + +/* 0x144 : cpu_core_cfg13 */ +#define PDS_CPU_CORE_CFG13_OFFSET (0x144) +#define PDS_E902_RST_ADDR PDS_E902_RST_ADDR +#define PDS_E902_RST_ADDR_POS (0U) +#define PDS_E902_RST_ADDR_LEN (32U) +#define PDS_E902_RST_ADDR_MSK (((1U << PDS_E902_RST_ADDR_LEN) - 1) << PDS_E902_RST_ADDR_POS) +#define PDS_E902_RST_ADDR_UMSK (~(((1U << PDS_E902_RST_ADDR_LEN) - 1) << PDS_E902_RST_ADDR_POS)) + +/* 0x148 : cpu_core_cfg14 */ +#define PDS_CPU_CORE_CFG14_OFFSET (0x148) +#define PDS_E906_RST_ADDR PDS_E906_RST_ADDR +#define PDS_E906_RST_ADDR_POS (0U) +#define PDS_E906_RST_ADDR_LEN (32U) +#define PDS_E906_RST_ADDR_MSK (((1U << PDS_E906_RST_ADDR_LEN) - 1) << PDS_E906_RST_ADDR_POS) +#define PDS_E906_RST_ADDR_UMSK (~(((1U << PDS_E906_RST_ADDR_LEN) - 1) << PDS_E906_RST_ADDR_POS)) + +/* 0x14C : tzc_pds */ +#define PDS_TZC_PDS_OFFSET (0x14C) +#define PDS_CR_E902_CFG_WR_LOCK PDS_CR_E902_CFG_WR_LOCK +#define PDS_CR_E902_CFG_WR_LOCK_POS (0U) +#define PDS_CR_E902_CFG_WR_LOCK_LEN (1U) +#define PDS_CR_E902_CFG_WR_LOCK_MSK (((1U << PDS_CR_E902_CFG_WR_LOCK_LEN) - 1) << PDS_CR_E902_CFG_WR_LOCK_POS) +#define PDS_CR_E902_CFG_WR_LOCK_UMSK (~(((1U << PDS_CR_E902_CFG_WR_LOCK_LEN) - 1) << PDS_CR_E902_CFG_WR_LOCK_POS)) +#define PDS_CR_E906_CFG_WR_LOCK PDS_CR_E906_CFG_WR_LOCK +#define PDS_CR_E906_CFG_WR_LOCK_POS (1U) +#define PDS_CR_E906_CFG_WR_LOCK_LEN (1U) +#define PDS_CR_E906_CFG_WR_LOCK_MSK (((1U << PDS_CR_E906_CFG_WR_LOCK_LEN) - 1) << PDS_CR_E906_CFG_WR_LOCK_POS) +#define PDS_CR_E906_CFG_WR_LOCK_UMSK (~(((1U << PDS_CR_E906_CFG_WR_LOCK_LEN) - 1) << PDS_CR_E906_CFG_WR_LOCK_POS)) + +/* 0x300 : rc32m_ctrl0 */ +#define PDS_RC32M_CTRL0_OFFSET (0x300) +#define PDS_RC32M_CAL_DONE PDS_RC32M_CAL_DONE +#define PDS_RC32M_CAL_DONE_POS (0U) +#define PDS_RC32M_CAL_DONE_LEN (1U) +#define PDS_RC32M_CAL_DONE_MSK (((1U << PDS_RC32M_CAL_DONE_LEN) - 1) << PDS_RC32M_CAL_DONE_POS) +#define PDS_RC32M_CAL_DONE_UMSK (~(((1U << PDS_RC32M_CAL_DONE_LEN) - 1) << PDS_RC32M_CAL_DONE_POS)) +#define PDS_RC32M_RDY PDS_RC32M_RDY +#define PDS_RC32M_RDY_POS (1U) +#define PDS_RC32M_RDY_LEN (1U) +#define PDS_RC32M_RDY_MSK (((1U << PDS_RC32M_RDY_LEN) - 1) << PDS_RC32M_RDY_POS) +#define PDS_RC32M_RDY_UMSK (~(((1U << PDS_RC32M_RDY_LEN) - 1) << PDS_RC32M_RDY_POS)) +#define PDS_RC32M_CAL_INPROGRESS PDS_RC32M_CAL_INPROGRESS +#define PDS_RC32M_CAL_INPROGRESS_POS (2U) +#define PDS_RC32M_CAL_INPROGRESS_LEN (1U) +#define PDS_RC32M_CAL_INPROGRESS_MSK (((1U << PDS_RC32M_CAL_INPROGRESS_LEN) - 1) << PDS_RC32M_CAL_INPROGRESS_POS) +#define PDS_RC32M_CAL_INPROGRESS_UMSK (~(((1U << PDS_RC32M_CAL_INPROGRESS_LEN) - 1) << PDS_RC32M_CAL_INPROGRESS_POS)) +#define PDS_RC32M_CAL_DIV PDS_RC32M_CAL_DIV +#define PDS_RC32M_CAL_DIV_POS (3U) +#define PDS_RC32M_CAL_DIV_LEN (2U) +#define PDS_RC32M_CAL_DIV_MSK (((1U << PDS_RC32M_CAL_DIV_LEN) - 1) << PDS_RC32M_CAL_DIV_POS) +#define PDS_RC32M_CAL_DIV_UMSK (~(((1U << PDS_RC32M_CAL_DIV_LEN) - 1) << PDS_RC32M_CAL_DIV_POS)) +#define PDS_RC32M_CAL_PRECHARGE PDS_RC32M_CAL_PRECHARGE +#define PDS_RC32M_CAL_PRECHARGE_POS (5U) +#define PDS_RC32M_CAL_PRECHARGE_LEN (1U) +#define PDS_RC32M_CAL_PRECHARGE_MSK (((1U << PDS_RC32M_CAL_PRECHARGE_LEN) - 1) << PDS_RC32M_CAL_PRECHARGE_POS) +#define PDS_RC32M_CAL_PRECHARGE_UMSK (~(((1U << PDS_RC32M_CAL_PRECHARGE_LEN) - 1) << PDS_RC32M_CAL_PRECHARGE_POS)) +#define PDS_RC32M_DIG_CODE_FR_CAL PDS_RC32M_DIG_CODE_FR_CAL +#define PDS_RC32M_DIG_CODE_FR_CAL_POS (6U) +#define PDS_RC32M_DIG_CODE_FR_CAL_LEN (8U) +#define PDS_RC32M_DIG_CODE_FR_CAL_MSK (((1U << PDS_RC32M_DIG_CODE_FR_CAL_LEN) - 1) << PDS_RC32M_DIG_CODE_FR_CAL_POS) +#define PDS_RC32M_DIG_CODE_FR_CAL_UMSK (~(((1U << PDS_RC32M_DIG_CODE_FR_CAL_LEN) - 1) << PDS_RC32M_DIG_CODE_FR_CAL_POS)) +#define PDS_RC32M_ALLOW_CAL PDS_RC32M_ALLOW_CAL +#define PDS_RC32M_ALLOW_CAL_POS (17U) +#define PDS_RC32M_ALLOW_CAL_LEN (1U) +#define PDS_RC32M_ALLOW_CAL_MSK (((1U << PDS_RC32M_ALLOW_CAL_LEN) - 1) << PDS_RC32M_ALLOW_CAL_POS) +#define PDS_RC32M_ALLOW_CAL_UMSK (~(((1U << PDS_RC32M_ALLOW_CAL_LEN) - 1) << PDS_RC32M_ALLOW_CAL_POS)) +#define PDS_RC32M_REFCLK_HALF PDS_RC32M_REFCLK_HALF +#define PDS_RC32M_REFCLK_HALF_POS (18U) +#define PDS_RC32M_REFCLK_HALF_LEN (1U) +#define PDS_RC32M_REFCLK_HALF_MSK (((1U << PDS_RC32M_REFCLK_HALF_LEN) - 1) << PDS_RC32M_REFCLK_HALF_POS) +#define PDS_RC32M_REFCLK_HALF_UMSK (~(((1U << PDS_RC32M_REFCLK_HALF_LEN) - 1) << PDS_RC32M_REFCLK_HALF_POS)) +#define PDS_RC32M_EXT_CODE_EN PDS_RC32M_EXT_CODE_EN +#define PDS_RC32M_EXT_CODE_EN_POS (19U) +#define PDS_RC32M_EXT_CODE_EN_LEN (1U) +#define PDS_RC32M_EXT_CODE_EN_MSK (((1U << PDS_RC32M_EXT_CODE_EN_LEN) - 1) << PDS_RC32M_EXT_CODE_EN_POS) +#define PDS_RC32M_EXT_CODE_EN_UMSK (~(((1U << PDS_RC32M_EXT_CODE_EN_LEN) - 1) << PDS_RC32M_EXT_CODE_EN_POS)) +#define PDS_RC32M_CAL_EN PDS_RC32M_CAL_EN +#define PDS_RC32M_CAL_EN_POS (20U) +#define PDS_RC32M_CAL_EN_LEN (1U) +#define PDS_RC32M_CAL_EN_MSK (((1U << PDS_RC32M_CAL_EN_LEN) - 1) << PDS_RC32M_CAL_EN_POS) +#define PDS_RC32M_CAL_EN_UMSK (~(((1U << PDS_RC32M_CAL_EN_LEN) - 1) << PDS_RC32M_CAL_EN_POS)) +#define PDS_RC32M_PD PDS_RC32M_PD +#define PDS_RC32M_PD_POS (21U) +#define PDS_RC32M_PD_LEN (1U) +#define PDS_RC32M_PD_MSK (((1U << PDS_RC32M_PD_LEN) - 1) << PDS_RC32M_PD_POS) +#define PDS_RC32M_PD_UMSK (~(((1U << PDS_RC32M_PD_LEN) - 1) << PDS_RC32M_PD_POS)) +#define PDS_RC32M_CODE_FR_EXT PDS_RC32M_CODE_FR_EXT +#define PDS_RC32M_CODE_FR_EXT_POS (22U) +#define PDS_RC32M_CODE_FR_EXT_LEN (8U) +#define PDS_RC32M_CODE_FR_EXT_MSK (((1U << PDS_RC32M_CODE_FR_EXT_LEN) - 1) << PDS_RC32M_CODE_FR_EXT_POS) +#define PDS_RC32M_CODE_FR_EXT_UMSK (~(((1U << PDS_RC32M_CODE_FR_EXT_LEN) - 1) << PDS_RC32M_CODE_FR_EXT_POS)) + +/* 0x304 : rc32m_ctrl1 */ +#define PDS_RC32M_CTRL1_OFFSET (0x304) +#define PDS_RC32M_TEST_EN PDS_RC32M_TEST_EN +#define PDS_RC32M_TEST_EN_POS (0U) +#define PDS_RC32M_TEST_EN_LEN (1U) +#define PDS_RC32M_TEST_EN_MSK (((1U << PDS_RC32M_TEST_EN_LEN) - 1) << PDS_RC32M_TEST_EN_POS) +#define PDS_RC32M_TEST_EN_UMSK (~(((1U << PDS_RC32M_TEST_EN_LEN) - 1) << PDS_RC32M_TEST_EN_POS)) +#define PDS_RC32M_SOFT_RST PDS_RC32M_SOFT_RST +#define PDS_RC32M_SOFT_RST_POS (1U) +#define PDS_RC32M_SOFT_RST_LEN (1U) +#define PDS_RC32M_SOFT_RST_MSK (((1U << PDS_RC32M_SOFT_RST_LEN) - 1) << PDS_RC32M_SOFT_RST_POS) +#define PDS_RC32M_SOFT_RST_UMSK (~(((1U << PDS_RC32M_SOFT_RST_LEN) - 1) << PDS_RC32M_SOFT_RST_POS)) +#define PDS_RC32M_CLK_SOFT_RST PDS_RC32M_CLK_SOFT_RST +#define PDS_RC32M_CLK_SOFT_RST_POS (2U) +#define PDS_RC32M_CLK_SOFT_RST_LEN (1U) +#define PDS_RC32M_CLK_SOFT_RST_MSK (((1U << PDS_RC32M_CLK_SOFT_RST_LEN) - 1) << PDS_RC32M_CLK_SOFT_RST_POS) +#define PDS_RC32M_CLK_SOFT_RST_UMSK (~(((1U << PDS_RC32M_CLK_SOFT_RST_LEN) - 1) << PDS_RC32M_CLK_SOFT_RST_POS)) +#define PDS_RC32M_CLK_INV PDS_RC32M_CLK_INV +#define PDS_RC32M_CLK_INV_POS (3U) +#define PDS_RC32M_CLK_INV_LEN (1U) +#define PDS_RC32M_CLK_INV_MSK (((1U << PDS_RC32M_CLK_INV_LEN) - 1) << PDS_RC32M_CLK_INV_POS) +#define PDS_RC32M_CLK_INV_UMSK (~(((1U << PDS_RC32M_CLK_INV_LEN) - 1) << PDS_RC32M_CLK_INV_POS)) +#define PDS_RC32M_CLK_FORCE_ON PDS_RC32M_CLK_FORCE_ON +#define PDS_RC32M_CLK_FORCE_ON_POS (4U) +#define PDS_RC32M_CLK_FORCE_ON_LEN (1U) +#define PDS_RC32M_CLK_FORCE_ON_MSK (((1U << PDS_RC32M_CLK_FORCE_ON_LEN) - 1) << PDS_RC32M_CLK_FORCE_ON_POS) +#define PDS_RC32M_CLK_FORCE_ON_UMSK (~(((1U << PDS_RC32M_CLK_FORCE_ON_LEN) - 1) << PDS_RC32M_CLK_FORCE_ON_POS)) +#define PDS_RC32M_RESERVED PDS_RC32M_RESERVED +#define PDS_RC32M_RESERVED_POS (24U) +#define PDS_RC32M_RESERVED_LEN (8U) +#define PDS_RC32M_RESERVED_MSK (((1U << PDS_RC32M_RESERVED_LEN) - 1) << PDS_RC32M_RESERVED_POS) +#define PDS_RC32M_RESERVED_UMSK (~(((1U << PDS_RC32M_RESERVED_LEN) - 1) << PDS_RC32M_RESERVED_POS)) + +/* 0x400 : pu_rst_clkpll */ +#define PDS_PU_RST_CLKPLL_OFFSET (0x400) +#define PDS_CR_PDS_PU_CLKPLL_SFREG PDS_CR_PDS_PU_CLKPLL_SFREG +#define PDS_CR_PDS_PU_CLKPLL_SFREG_POS (9U) +#define PDS_CR_PDS_PU_CLKPLL_SFREG_LEN (1U) +#define PDS_CR_PDS_PU_CLKPLL_SFREG_MSK (((1U << PDS_CR_PDS_PU_CLKPLL_SFREG_LEN) - 1) << PDS_CR_PDS_PU_CLKPLL_SFREG_POS) +#define PDS_CR_PDS_PU_CLKPLL_SFREG_UMSK (~(((1U << PDS_CR_PDS_PU_CLKPLL_SFREG_LEN) - 1) << PDS_CR_PDS_PU_CLKPLL_SFREG_POS)) +#define PDS_CR_PDS_PU_CLKPLL PDS_CR_PDS_PU_CLKPLL +#define PDS_CR_PDS_PU_CLKPLL_POS (10U) +#define PDS_CR_PDS_PU_CLKPLL_LEN (1U) +#define PDS_CR_PDS_PU_CLKPLL_MSK (((1U << PDS_CR_PDS_PU_CLKPLL_LEN) - 1) << PDS_CR_PDS_PU_CLKPLL_POS) +#define PDS_CR_PDS_PU_CLKPLL_UMSK (~(((1U << PDS_CR_PDS_PU_CLKPLL_LEN) - 1) << PDS_CR_PDS_PU_CLKPLL_POS)) + +/* 0x500 : usb_ctl */ +#define PDS_USB_CTL_OFFSET (0x500) +#define PDS_REG_USB_SW_RST_N PDS_REG_USB_SW_RST_N +#define PDS_REG_USB_SW_RST_N_POS (0U) +#define PDS_REG_USB_SW_RST_N_LEN (1U) +#define PDS_REG_USB_SW_RST_N_MSK (((1U << PDS_REG_USB_SW_RST_N_LEN) - 1) << PDS_REG_USB_SW_RST_N_POS) +#define PDS_REG_USB_SW_RST_N_UMSK (~(((1U << PDS_REG_USB_SW_RST_N_LEN) - 1) << PDS_REG_USB_SW_RST_N_POS)) +#define PDS_REG_USB_EXT_SUSP_N PDS_REG_USB_EXT_SUSP_N +#define PDS_REG_USB_EXT_SUSP_N_POS (1U) +#define PDS_REG_USB_EXT_SUSP_N_LEN (1U) +#define PDS_REG_USB_EXT_SUSP_N_MSK (((1U << PDS_REG_USB_EXT_SUSP_N_LEN) - 1) << PDS_REG_USB_EXT_SUSP_N_POS) +#define PDS_REG_USB_EXT_SUSP_N_UMSK (~(((1U << PDS_REG_USB_EXT_SUSP_N_LEN) - 1) << PDS_REG_USB_EXT_SUSP_N_POS)) +#define PDS_REG_USB_WAKEUP PDS_REG_USB_WAKEUP +#define PDS_REG_USB_WAKEUP_POS (2U) +#define PDS_REG_USB_WAKEUP_LEN (1U) +#define PDS_REG_USB_WAKEUP_MSK (((1U << PDS_REG_USB_WAKEUP_LEN) - 1) << PDS_REG_USB_WAKEUP_POS) +#define PDS_REG_USB_WAKEUP_UMSK (~(((1U << PDS_REG_USB_WAKEUP_LEN) - 1) << PDS_REG_USB_WAKEUP_POS)) +#define PDS_REG_USB_L1_WAKEUP PDS_REG_USB_L1_WAKEUP +#define PDS_REG_USB_L1_WAKEUP_POS (3U) +#define PDS_REG_USB_L1_WAKEUP_LEN (1U) +#define PDS_REG_USB_L1_WAKEUP_MSK (((1U << PDS_REG_USB_L1_WAKEUP_LEN) - 1) << PDS_REG_USB_L1_WAKEUP_POS) +#define PDS_REG_USB_L1_WAKEUP_UMSK (~(((1U << PDS_REG_USB_L1_WAKEUP_LEN) - 1) << PDS_REG_USB_L1_WAKEUP_POS)) +#define PDS_REG_USB_DRVBUS_POL PDS_REG_USB_DRVBUS_POL +#define PDS_REG_USB_DRVBUS_POL_POS (4U) +#define PDS_REG_USB_DRVBUS_POL_LEN (1U) +#define PDS_REG_USB_DRVBUS_POL_MSK (((1U << PDS_REG_USB_DRVBUS_POL_LEN) - 1) << PDS_REG_USB_DRVBUS_POL_POS) +#define PDS_REG_USB_DRVBUS_POL_UMSK (~(((1U << PDS_REG_USB_DRVBUS_POL_LEN) - 1) << PDS_REG_USB_DRVBUS_POL_POS)) +#define PDS_REG_USB_IDDIG PDS_REG_USB_IDDIG +#define PDS_REG_USB_IDDIG_POS (5U) +#define PDS_REG_USB_IDDIG_LEN (1U) +#define PDS_REG_USB_IDDIG_MSK (((1U << PDS_REG_USB_IDDIG_LEN) - 1) << PDS_REG_USB_IDDIG_POS) +#define PDS_REG_USB_IDDIG_UMSK (~(((1U << PDS_REG_USB_IDDIG_LEN) - 1) << PDS_REG_USB_IDDIG_POS)) + +/* 0x504 : usb_phy_ctrl */ +#define PDS_USB_PHY_CTRL_OFFSET (0x504) +#define PDS_REG_USB_PHY_PONRST PDS_REG_USB_PHY_PONRST +#define PDS_REG_USB_PHY_PONRST_POS (0U) +#define PDS_REG_USB_PHY_PONRST_LEN (1U) +#define PDS_REG_USB_PHY_PONRST_MSK (((1U << PDS_REG_USB_PHY_PONRST_LEN) - 1) << PDS_REG_USB_PHY_PONRST_POS) +#define PDS_REG_USB_PHY_PONRST_UMSK (~(((1U << PDS_REG_USB_PHY_PONRST_LEN) - 1) << PDS_REG_USB_PHY_PONRST_POS)) +#define PDS_REG_USB_PHY_OSCOUTEN PDS_REG_USB_PHY_OSCOUTEN +#define PDS_REG_USB_PHY_OSCOUTEN_POS (1U) +#define PDS_REG_USB_PHY_OSCOUTEN_LEN (1U) +#define PDS_REG_USB_PHY_OSCOUTEN_MSK (((1U << PDS_REG_USB_PHY_OSCOUTEN_LEN) - 1) << PDS_REG_USB_PHY_OSCOUTEN_POS) +#define PDS_REG_USB_PHY_OSCOUTEN_UMSK (~(((1U << PDS_REG_USB_PHY_OSCOUTEN_LEN) - 1) << PDS_REG_USB_PHY_OSCOUTEN_POS)) +#define PDS_REG_USB_PHY_XTLSEL PDS_REG_USB_PHY_XTLSEL +#define PDS_REG_USB_PHY_XTLSEL_POS (2U) +#define PDS_REG_USB_PHY_XTLSEL_LEN (2U) +#define PDS_REG_USB_PHY_XTLSEL_MSK (((1U << PDS_REG_USB_PHY_XTLSEL_LEN) - 1) << PDS_REG_USB_PHY_XTLSEL_POS) +#define PDS_REG_USB_PHY_XTLSEL_UMSK (~(((1U << PDS_REG_USB_PHY_XTLSEL_LEN) - 1) << PDS_REG_USB_PHY_XTLSEL_POS)) +#define PDS_REG_USB_PHY_OUTCLKSEL PDS_REG_USB_PHY_OUTCLKSEL +#define PDS_REG_USB_PHY_OUTCLKSEL_POS (4U) +#define PDS_REG_USB_PHY_OUTCLKSEL_LEN (1U) +#define PDS_REG_USB_PHY_OUTCLKSEL_MSK (((1U << PDS_REG_USB_PHY_OUTCLKSEL_LEN) - 1) << PDS_REG_USB_PHY_OUTCLKSEL_POS) +#define PDS_REG_USB_PHY_OUTCLKSEL_UMSK (~(((1U << PDS_REG_USB_PHY_OUTCLKSEL_LEN) - 1) << PDS_REG_USB_PHY_OUTCLKSEL_POS)) +#define PDS_REG_USB_PHY_PLLALIV PDS_REG_USB_PHY_PLLALIV +#define PDS_REG_USB_PHY_PLLALIV_POS (5U) +#define PDS_REG_USB_PHY_PLLALIV_LEN (1U) +#define PDS_REG_USB_PHY_PLLALIV_MSK (((1U << PDS_REG_USB_PHY_PLLALIV_LEN) - 1) << PDS_REG_USB_PHY_PLLALIV_POS) +#define PDS_REG_USB_PHY_PLLALIV_UMSK (~(((1U << PDS_REG_USB_PHY_PLLALIV_LEN) - 1) << PDS_REG_USB_PHY_PLLALIV_POS)) +#define PDS_REG_PU_USB20_PSW PDS_REG_PU_USB20_PSW +#define PDS_REG_PU_USB20_PSW_POS (6U) +#define PDS_REG_PU_USB20_PSW_LEN (1U) +#define PDS_REG_PU_USB20_PSW_MSK (((1U << PDS_REG_PU_USB20_PSW_LEN) - 1) << PDS_REG_PU_USB20_PSW_POS) +#define PDS_REG_PU_USB20_PSW_UMSK (~(((1U << PDS_REG_PU_USB20_PSW_LEN) - 1) << PDS_REG_PU_USB20_PSW_POS)) + +/* 0xA00 : touch channel, clock, ana config1 */ +#define PDS_TOUCH1_OFFSET (0xA00) +#define PDS_TOUCH_VREF_SEL PDS_TOUCH_VREF_SEL +#define PDS_TOUCH_VREF_SEL_POS (0U) +#define PDS_TOUCH_VREF_SEL_LEN (3U) +#define PDS_TOUCH_VREF_SEL_MSK (((1U << PDS_TOUCH_VREF_SEL_LEN) - 1) << PDS_TOUCH_VREF_SEL_POS) +#define PDS_TOUCH_VREF_SEL_UMSK (~(((1U << PDS_TOUCH_VREF_SEL_LEN) - 1) << PDS_TOUCH_VREF_SEL_POS)) +#define PDS_TOUCH_VLDO_SEL PDS_TOUCH_VLDO_SEL +#define PDS_TOUCH_VLDO_SEL_POS (3U) +#define PDS_TOUCH_VLDO_SEL_LEN (3U) +#define PDS_TOUCH_VLDO_SEL_MSK (((1U << PDS_TOUCH_VLDO_SEL_LEN) - 1) << PDS_TOUCH_VLDO_SEL_POS) +#define PDS_TOUCH_VLDO_SEL_UMSK (~(((1U << PDS_TOUCH_VLDO_SEL_LEN) - 1) << PDS_TOUCH_VLDO_SEL_POS)) +#define PDS_TOUCH_COMP_HYS_SEL PDS_TOUCH_COMP_HYS_SEL +#define PDS_TOUCH_COMP_HYS_SEL_POS (6U) +#define PDS_TOUCH_COMP_HYS_SEL_LEN (1U) +#define PDS_TOUCH_COMP_HYS_SEL_MSK (((1U << PDS_TOUCH_COMP_HYS_SEL_LEN) - 1) << PDS_TOUCH_COMP_HYS_SEL_POS) +#define PDS_TOUCH_COMP_HYS_SEL_UMSK (~(((1U << PDS_TOUCH_COMP_HYS_SEL_LEN) - 1) << PDS_TOUCH_COMP_HYS_SEL_POS)) +#define PDS_TOUCH_CURRENT_SEL PDS_TOUCH_CURRENT_SEL +#define PDS_TOUCH_CURRENT_SEL_POS (7U) +#define PDS_TOUCH_CURRENT_SEL_LEN (1U) +#define PDS_TOUCH_CURRENT_SEL_MSK (((1U << PDS_TOUCH_CURRENT_SEL_LEN) - 1) << PDS_TOUCH_CURRENT_SEL_POS) +#define PDS_TOUCH_CURRENT_SEL_UMSK (~(((1U << PDS_TOUCH_CURRENT_SEL_LEN) - 1) << PDS_TOUCH_CURRENT_SEL_POS)) +#define PDS_TOUCH_CLK_SEL PDS_TOUCH_CLK_SEL +#define PDS_TOUCH_CLK_SEL_POS (16U) +#define PDS_TOUCH_CLK_SEL_LEN (1U) +#define PDS_TOUCH_CLK_SEL_MSK (((1U << PDS_TOUCH_CLK_SEL_LEN) - 1) << PDS_TOUCH_CLK_SEL_POS) +#define PDS_TOUCH_CLK_SEL_UMSK (~(((1U << PDS_TOUCH_CLK_SEL_LEN) - 1) << PDS_TOUCH_CLK_SEL_POS)) +#define PDS_TOUCH_CLK_DIV_RATIO PDS_TOUCH_CLK_DIV_RATIO +#define PDS_TOUCH_CLK_DIV_RATIO_POS (17U) +#define PDS_TOUCH_CLK_DIV_RATIO_LEN (3U) +#define PDS_TOUCH_CLK_DIV_RATIO_MSK (((1U << PDS_TOUCH_CLK_DIV_RATIO_LEN) - 1) << PDS_TOUCH_CLK_DIV_RATIO_POS) +#define PDS_TOUCH_CLK_DIV_RATIO_UMSK (~(((1U << PDS_TOUCH_CLK_DIV_RATIO_LEN) - 1) << PDS_TOUCH_CLK_DIV_RATIO_POS)) +#define PDS_TOUCH_PCHARGE_HIGH PDS_TOUCH_PCHARGE_HIGH +#define PDS_TOUCH_PCHARGE_HIGH_POS (20U) +#define PDS_TOUCH_PCHARGE_HIGH_LEN (3U) +#define PDS_TOUCH_PCHARGE_HIGH_MSK (((1U << PDS_TOUCH_PCHARGE_HIGH_LEN) - 1) << PDS_TOUCH_PCHARGE_HIGH_POS) +#define PDS_TOUCH_PCHARGE_HIGH_UMSK (~(((1U << PDS_TOUCH_PCHARGE_HIGH_LEN) - 1) << PDS_TOUCH_PCHARGE_HIGH_POS)) +#define PDS_TOUCH_PCHARGE_LOW PDS_TOUCH_PCHARGE_LOW +#define PDS_TOUCH_PCHARGE_LOW_POS (23U) +#define PDS_TOUCH_PCHARGE_LOW_LEN (3U) +#define PDS_TOUCH_PCHARGE_LOW_MSK (((1U << PDS_TOUCH_PCHARGE_LOW_LEN) - 1) << PDS_TOUCH_PCHARGE_LOW_POS) +#define PDS_TOUCH_PCHARGE_LOW_UMSK (~(((1U << PDS_TOUCH_PCHARGE_LOW_LEN) - 1) << PDS_TOUCH_PCHARGE_LOW_POS)) +#define PDS_TOUCH_CONT_EN PDS_TOUCH_CONT_EN +#define PDS_TOUCH_CONT_EN_POS (26U) +#define PDS_TOUCH_CONT_EN_LEN (1U) +#define PDS_TOUCH_CONT_EN_MSK (((1U << PDS_TOUCH_CONT_EN_LEN) - 1) << PDS_TOUCH_CONT_EN_POS) +#define PDS_TOUCH_CONT_EN_UMSK (~(((1U << PDS_TOUCH_CONT_EN_LEN) - 1) << PDS_TOUCH_CONT_EN_POS)) +#define PDS_TOUCH_CYCLE_EN PDS_TOUCH_CYCLE_EN +#define PDS_TOUCH_CYCLE_EN_POS (27U) +#define PDS_TOUCH_CYCLE_EN_LEN (1U) +#define PDS_TOUCH_CYCLE_EN_MSK (((1U << PDS_TOUCH_CYCLE_EN_LEN) - 1) << PDS_TOUCH_CYCLE_EN_POS) +#define PDS_TOUCH_CYCLE_EN_UMSK (~(((1U << PDS_TOUCH_CYCLE_EN_LEN) - 1) << PDS_TOUCH_CYCLE_EN_POS)) +#define PDS_TOUCH_ULP_EN PDS_TOUCH_ULP_EN +#define PDS_TOUCH_ULP_EN_POS (28U) +#define PDS_TOUCH_ULP_EN_LEN (1U) +#define PDS_TOUCH_ULP_EN_MSK (((1U << PDS_TOUCH_ULP_EN_LEN) - 1) << PDS_TOUCH_ULP_EN_POS) +#define PDS_TOUCH_ULP_EN_UMSK (~(((1U << PDS_TOUCH_ULP_EN_LEN) - 1) << PDS_TOUCH_ULP_EN_POS)) +#define PDS_PU_TOUCH PDS_PU_TOUCH +#define PDS_PU_TOUCH_POS (30U) +#define PDS_PU_TOUCH_LEN (1U) +#define PDS_PU_TOUCH_MSK (((1U << PDS_PU_TOUCH_LEN) - 1) << PDS_PU_TOUCH_POS) +#define PDS_PU_TOUCH_UMSK (~(((1U << PDS_PU_TOUCH_LEN) - 1) << PDS_PU_TOUCH_POS)) + +/* 0xA04 : touch channel, clock, ana config2 */ +#define PDS_TOUCH2_OFFSET (0xA04) +#define PDS_TOUCH_CHANNEL_SEL PDS_TOUCH_CHANNEL_SEL +#define PDS_TOUCH_CHANNEL_SEL_POS (0U) +#define PDS_TOUCH_CHANNEL_SEL_LEN (4U) +#define PDS_TOUCH_CHANNEL_SEL_MSK (((1U << PDS_TOUCH_CHANNEL_SEL_LEN) - 1) << PDS_TOUCH_CHANNEL_SEL_POS) +#define PDS_TOUCH_CHANNEL_SEL_UMSK (~(((1U << PDS_TOUCH_CHANNEL_SEL_LEN) - 1) << PDS_TOUCH_CHANNEL_SEL_POS)) +#define PDS_TOUCH_CHANNEL0_HIGHZ_EN PDS_TOUCH_CHANNEL0_HIGHZ_EN +#define PDS_TOUCH_CHANNEL0_HIGHZ_EN_POS (4U) +#define PDS_TOUCH_CHANNEL0_HIGHZ_EN_LEN (1U) +#define PDS_TOUCH_CHANNEL0_HIGHZ_EN_MSK (((1U << PDS_TOUCH_CHANNEL0_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL0_HIGHZ_EN_POS) +#define PDS_TOUCH_CHANNEL0_HIGHZ_EN_UMSK (~(((1U << PDS_TOUCH_CHANNEL0_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL0_HIGHZ_EN_POS)) +#define PDS_TOUCH_CHANNEL1_HIGHZ_EN PDS_TOUCH_CHANNEL1_HIGHZ_EN +#define PDS_TOUCH_CHANNEL1_HIGHZ_EN_POS (5U) +#define PDS_TOUCH_CHANNEL1_HIGHZ_EN_LEN (1U) +#define PDS_TOUCH_CHANNEL1_HIGHZ_EN_MSK (((1U << PDS_TOUCH_CHANNEL1_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL1_HIGHZ_EN_POS) +#define PDS_TOUCH_CHANNEL1_HIGHZ_EN_UMSK (~(((1U << PDS_TOUCH_CHANNEL1_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL1_HIGHZ_EN_POS)) +#define PDS_TOUCH_CHANNEL2_HIGHZ_EN PDS_TOUCH_CHANNEL2_HIGHZ_EN +#define PDS_TOUCH_CHANNEL2_HIGHZ_EN_POS (6U) +#define PDS_TOUCH_CHANNEL2_HIGHZ_EN_LEN (1U) +#define PDS_TOUCH_CHANNEL2_HIGHZ_EN_MSK (((1U << PDS_TOUCH_CHANNEL2_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL2_HIGHZ_EN_POS) +#define PDS_TOUCH_CHANNEL2_HIGHZ_EN_UMSK (~(((1U << PDS_TOUCH_CHANNEL2_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL2_HIGHZ_EN_POS)) +#define PDS_TOUCH_CHANNEL3_HIGHZ_EN PDS_TOUCH_CHANNEL3_HIGHZ_EN +#define PDS_TOUCH_CHANNEL3_HIGHZ_EN_POS (7U) +#define PDS_TOUCH_CHANNEL3_HIGHZ_EN_LEN (1U) +#define PDS_TOUCH_CHANNEL3_HIGHZ_EN_MSK (((1U << PDS_TOUCH_CHANNEL3_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL3_HIGHZ_EN_POS) +#define PDS_TOUCH_CHANNEL3_HIGHZ_EN_UMSK (~(((1U << PDS_TOUCH_CHANNEL3_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL3_HIGHZ_EN_POS)) +#define PDS_TOUCH_CHANNEL4_HIGHZ_EN PDS_TOUCH_CHANNEL4_HIGHZ_EN +#define PDS_TOUCH_CHANNEL4_HIGHZ_EN_POS (8U) +#define PDS_TOUCH_CHANNEL4_HIGHZ_EN_LEN (1U) +#define PDS_TOUCH_CHANNEL4_HIGHZ_EN_MSK (((1U << PDS_TOUCH_CHANNEL4_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL4_HIGHZ_EN_POS) +#define PDS_TOUCH_CHANNEL4_HIGHZ_EN_UMSK (~(((1U << PDS_TOUCH_CHANNEL4_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL4_HIGHZ_EN_POS)) +#define PDS_TOUCH_CHANNEL5_HIGHZ_EN PDS_TOUCH_CHANNEL5_HIGHZ_EN +#define PDS_TOUCH_CHANNEL5_HIGHZ_EN_POS (9U) +#define PDS_TOUCH_CHANNEL5_HIGHZ_EN_LEN (1U) +#define PDS_TOUCH_CHANNEL5_HIGHZ_EN_MSK (((1U << PDS_TOUCH_CHANNEL5_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL5_HIGHZ_EN_POS) +#define PDS_TOUCH_CHANNEL5_HIGHZ_EN_UMSK (~(((1U << PDS_TOUCH_CHANNEL5_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL5_HIGHZ_EN_POS)) +#define PDS_TOUCH_CHANNEL6_HIGHZ_EN PDS_TOUCH_CHANNEL6_HIGHZ_EN +#define PDS_TOUCH_CHANNEL6_HIGHZ_EN_POS (10U) +#define PDS_TOUCH_CHANNEL6_HIGHZ_EN_LEN (1U) +#define PDS_TOUCH_CHANNEL6_HIGHZ_EN_MSK (((1U << PDS_TOUCH_CHANNEL6_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL6_HIGHZ_EN_POS) +#define PDS_TOUCH_CHANNEL6_HIGHZ_EN_UMSK (~(((1U << PDS_TOUCH_CHANNEL6_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL6_HIGHZ_EN_POS)) +#define PDS_TOUCH_CHANNEL7_HIGHZ_EN PDS_TOUCH_CHANNEL7_HIGHZ_EN +#define PDS_TOUCH_CHANNEL7_HIGHZ_EN_POS (11U) +#define PDS_TOUCH_CHANNEL7_HIGHZ_EN_LEN (1U) +#define PDS_TOUCH_CHANNEL7_HIGHZ_EN_MSK (((1U << PDS_TOUCH_CHANNEL7_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL7_HIGHZ_EN_POS) +#define PDS_TOUCH_CHANNEL7_HIGHZ_EN_UMSK (~(((1U << PDS_TOUCH_CHANNEL7_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL7_HIGHZ_EN_POS)) +#define PDS_TOUCH_CHANNEL8_HIGHZ_EN PDS_TOUCH_CHANNEL8_HIGHZ_EN +#define PDS_TOUCH_CHANNEL8_HIGHZ_EN_POS (12U) +#define PDS_TOUCH_CHANNEL8_HIGHZ_EN_LEN (1U) +#define PDS_TOUCH_CHANNEL8_HIGHZ_EN_MSK (((1U << PDS_TOUCH_CHANNEL8_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL8_HIGHZ_EN_POS) +#define PDS_TOUCH_CHANNEL8_HIGHZ_EN_UMSK (~(((1U << PDS_TOUCH_CHANNEL8_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL8_HIGHZ_EN_POS)) +#define PDS_TOUCH_CHANNEL9_HIGHZ_EN PDS_TOUCH_CHANNEL9_HIGHZ_EN +#define PDS_TOUCH_CHANNEL9_HIGHZ_EN_POS (13U) +#define PDS_TOUCH_CHANNEL9_HIGHZ_EN_LEN (1U) +#define PDS_TOUCH_CHANNEL9_HIGHZ_EN_MSK (((1U << PDS_TOUCH_CHANNEL9_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL9_HIGHZ_EN_POS) +#define PDS_TOUCH_CHANNEL9_HIGHZ_EN_UMSK (~(((1U << PDS_TOUCH_CHANNEL9_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL9_HIGHZ_EN_POS)) +#define PDS_TOUCH_CHANNEL10_HIGHZ_EN PDS_TOUCH_CHANNEL10_HIGHZ_EN +#define PDS_TOUCH_CHANNEL10_HIGHZ_EN_POS (14U) +#define PDS_TOUCH_CHANNEL10_HIGHZ_EN_LEN (1U) +#define PDS_TOUCH_CHANNEL10_HIGHZ_EN_MSK (((1U << PDS_TOUCH_CHANNEL10_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL10_HIGHZ_EN_POS) +#define PDS_TOUCH_CHANNEL10_HIGHZ_EN_UMSK (~(((1U << PDS_TOUCH_CHANNEL10_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL10_HIGHZ_EN_POS)) +#define PDS_TOUCH_CHANNEL11_HIGHZ_EN PDS_TOUCH_CHANNEL11_HIGHZ_EN +#define PDS_TOUCH_CHANNEL11_HIGHZ_EN_POS (15U) +#define PDS_TOUCH_CHANNEL11_HIGHZ_EN_LEN (1U) +#define PDS_TOUCH_CHANNEL11_HIGHZ_EN_MSK (((1U << PDS_TOUCH_CHANNEL11_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL11_HIGHZ_EN_POS) +#define PDS_TOUCH_CHANNEL11_HIGHZ_EN_UMSK (~(((1U << PDS_TOUCH_CHANNEL11_HIGHZ_EN_LEN) - 1) << PDS_TOUCH_CHANNEL11_HIGHZ_EN_POS)) + +/* 0xA08 : touch data process */ +#define PDS_TOUCH3_OFFSET (0xA08) +#define PDS_TOUCH_CHANNEL_CAL_EN PDS_TOUCH_CHANNEL_CAL_EN +#define PDS_TOUCH_CHANNEL_CAL_EN_POS (0U) +#define PDS_TOUCH_CHANNEL_CAL_EN_LEN (1U) +#define PDS_TOUCH_CHANNEL_CAL_EN_MSK (((1U << PDS_TOUCH_CHANNEL_CAL_EN_LEN) - 1) << PDS_TOUCH_CHANNEL_CAL_EN_POS) +#define PDS_TOUCH_CHANNEL_CAL_EN_UMSK (~(((1U << PDS_TOUCH_CHANNEL_CAL_EN_LEN) - 1) << PDS_TOUCH_CHANNEL_CAL_EN_POS)) +#define PDS_TOUCH_FORCE_VALUE_EN PDS_TOUCH_FORCE_VALUE_EN +#define PDS_TOUCH_FORCE_VALUE_EN_POS (1U) +#define PDS_TOUCH_FORCE_VALUE_EN_LEN (1U) +#define PDS_TOUCH_FORCE_VALUE_EN_MSK (((1U << PDS_TOUCH_FORCE_VALUE_EN_LEN) - 1) << PDS_TOUCH_FORCE_VALUE_EN_POS) +#define PDS_TOUCH_FORCE_VALUE_EN_UMSK (~(((1U << PDS_TOUCH_FORCE_VALUE_EN_LEN) - 1) << PDS_TOUCH_FORCE_VALUE_EN_POS)) +#define PDS_TOUCH_DATA_HYS_EN PDS_TOUCH_DATA_HYS_EN +#define PDS_TOUCH_DATA_HYS_EN_POS (2U) +#define PDS_TOUCH_DATA_HYS_EN_LEN (1U) +#define PDS_TOUCH_DATA_HYS_EN_MSK (((1U << PDS_TOUCH_DATA_HYS_EN_LEN) - 1) << PDS_TOUCH_DATA_HYS_EN_POS) +#define PDS_TOUCH_DATA_HYS_EN_UMSK (~(((1U << PDS_TOUCH_DATA_HYS_EN_LEN) - 1) << PDS_TOUCH_DATA_HYS_EN_POS)) +#define PDS_TOUCH_LTA_EN PDS_TOUCH_LTA_EN +#define PDS_TOUCH_LTA_EN_POS (4U) +#define PDS_TOUCH_LTA_EN_LEN (1U) +#define PDS_TOUCH_LTA_EN_MSK (((1U << PDS_TOUCH_LTA_EN_LEN) - 1) << PDS_TOUCH_LTA_EN_POS) +#define PDS_TOUCH_LTA_EN_UMSK (~(((1U << PDS_TOUCH_LTA_EN_LEN) - 1) << PDS_TOUCH_LTA_EN_POS)) +#define PDS_TOUCH_LTA_ORDER PDS_TOUCH_LTA_ORDER +#define PDS_TOUCH_LTA_ORDER_POS (5U) +#define PDS_TOUCH_LTA_ORDER_LEN (3U) +#define PDS_TOUCH_LTA_ORDER_MSK (((1U << PDS_TOUCH_LTA_ORDER_LEN) - 1) << PDS_TOUCH_LTA_ORDER_POS) +#define PDS_TOUCH_LTA_ORDER_UMSK (~(((1U << PDS_TOUCH_LTA_ORDER_LEN) - 1) << PDS_TOUCH_LTA_ORDER_POS)) +#define PDS_TOUCH_FLT_EN PDS_TOUCH_FLT_EN +#define PDS_TOUCH_FLT_EN_POS (8U) +#define PDS_TOUCH_FLT_EN_LEN (1U) +#define PDS_TOUCH_FLT_EN_MSK (((1U << PDS_TOUCH_FLT_EN_LEN) - 1) << PDS_TOUCH_FLT_EN_POS) +#define PDS_TOUCH_FLT_EN_UMSK (~(((1U << PDS_TOUCH_FLT_EN_LEN) - 1) << PDS_TOUCH_FLT_EN_POS)) +#define PDS_TOUCH_FLT_ORDER PDS_TOUCH_FLT_ORDER +#define PDS_TOUCH_FLT_ORDER_POS (9U) +#define PDS_TOUCH_FLT_ORDER_LEN (3U) +#define PDS_TOUCH_FLT_ORDER_MSK (((1U << PDS_TOUCH_FLT_ORDER_LEN) - 1) << PDS_TOUCH_FLT_ORDER_POS) +#define PDS_TOUCH_FLT_ORDER_UMSK (~(((1U << PDS_TOUCH_FLT_ORDER_LEN) - 1) << PDS_TOUCH_FLT_ORDER_POS)) +#define PDS_TOUCH_SELF_MUTUAL_SEL PDS_TOUCH_SELF_MUTUAL_SEL +#define PDS_TOUCH_SELF_MUTUAL_SEL_POS (12U) +#define PDS_TOUCH_SELF_MUTUAL_SEL_LEN (1U) +#define PDS_TOUCH_SELF_MUTUAL_SEL_MSK (((1U << PDS_TOUCH_SELF_MUTUAL_SEL_LEN) - 1) << PDS_TOUCH_SELF_MUTUAL_SEL_POS) +#define PDS_TOUCH_SELF_MUTUAL_SEL_UMSK (~(((1U << PDS_TOUCH_SELF_MUTUAL_SEL_LEN) - 1) << PDS_TOUCH_SELF_MUTUAL_SEL_POS)) +#define PDS_TOUCH_VLDO_CCSEL PDS_TOUCH_VLDO_CCSEL +#define PDS_TOUCH_VLDO_CCSEL_POS (13U) +#define PDS_TOUCH_VLDO_CCSEL_LEN (2U) +#define PDS_TOUCH_VLDO_CCSEL_MSK (((1U << PDS_TOUCH_VLDO_CCSEL_LEN) - 1) << PDS_TOUCH_VLDO_CCSEL_POS) +#define PDS_TOUCH_VLDO_CCSEL_UMSK (~(((1U << PDS_TOUCH_VLDO_CCSEL_LEN) - 1) << PDS_TOUCH_VLDO_CCSEL_POS)) +#define PDS_TEN_TOUCH PDS_TEN_TOUCH +#define PDS_TEN_TOUCH_POS (18U) +#define PDS_TEN_TOUCH_LEN (1U) +#define PDS_TEN_TOUCH_MSK (((1U << PDS_TEN_TOUCH_LEN) - 1) << PDS_TEN_TOUCH_POS) +#define PDS_TEN_TOUCH_UMSK (~(((1U << PDS_TEN_TOUCH_LEN) - 1) << PDS_TEN_TOUCH_POS)) + +/* 0xA0C : Touch_sleep_time */ +#define PDS_TOUCH_SLEEP_TIME_OFFSET (0xA0C) +#define PDS_TOUCH_SLEEP_CYCLE PDS_TOUCH_SLEEP_CYCLE +#define PDS_TOUCH_SLEEP_CYCLE_POS (0U) +#define PDS_TOUCH_SLEEP_CYCLE_LEN (23U) +#define PDS_TOUCH_SLEEP_CYCLE_MSK (((1U << PDS_TOUCH_SLEEP_CYCLE_LEN) - 1) << PDS_TOUCH_SLEEP_CYCLE_POS) +#define PDS_TOUCH_SLEEP_CYCLE_UMSK (~(((1U << PDS_TOUCH_SLEEP_CYCLE_LEN) - 1) << PDS_TOUCH_SLEEP_CYCLE_POS)) + +/* 0xA10 : touch_data_hystersis */ +#define PDS_TOUCH_DATA_HYSTERSIS_OFFSET (0xA10) +#define PDS_TOUCH_DATA_HYS PDS_TOUCH_DATA_HYS +#define PDS_TOUCH_DATA_HYS_POS (0U) +#define PDS_TOUCH_DATA_HYS_LEN (9U) +#define PDS_TOUCH_DATA_HYS_MSK (((1U << PDS_TOUCH_DATA_HYS_LEN) - 1) << PDS_TOUCH_DATA_HYS_POS) +#define PDS_TOUCH_DATA_HYS_UMSK (~(((1U << PDS_TOUCH_DATA_HYS_LEN) - 1) << PDS_TOUCH_DATA_HYS_POS)) + +/* 0xA14 : Channel_force_data_0 */ +#define PDS_CHANNEL_FORCE_DATA_0_OFFSET (0xA14) +#define PDS_TOUCH_FORCE_DATA_CH0 PDS_TOUCH_FORCE_DATA_CH0 +#define PDS_TOUCH_FORCE_DATA_CH0_POS (0U) +#define PDS_TOUCH_FORCE_DATA_CH0_LEN (16U) +#define PDS_TOUCH_FORCE_DATA_CH0_MSK (((1U << PDS_TOUCH_FORCE_DATA_CH0_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH0_POS) +#define PDS_TOUCH_FORCE_DATA_CH0_UMSK (~(((1U << PDS_TOUCH_FORCE_DATA_CH0_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH0_POS)) +#define PDS_TOUCH_FORCE_DATA_CH1 PDS_TOUCH_FORCE_DATA_CH1 +#define PDS_TOUCH_FORCE_DATA_CH1_POS (16U) +#define PDS_TOUCH_FORCE_DATA_CH1_LEN (16U) +#define PDS_TOUCH_FORCE_DATA_CH1_MSK (((1U << PDS_TOUCH_FORCE_DATA_CH1_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH1_POS) +#define PDS_TOUCH_FORCE_DATA_CH1_UMSK (~(((1U << PDS_TOUCH_FORCE_DATA_CH1_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH1_POS)) + +/* 0xA18 : Channel_force_data_1 */ +#define PDS_CHANNEL_FORCE_DATA_1_OFFSET (0xA18) +#define PDS_TOUCH_FORCE_DATA_CH2 PDS_TOUCH_FORCE_DATA_CH2 +#define PDS_TOUCH_FORCE_DATA_CH2_POS (0U) +#define PDS_TOUCH_FORCE_DATA_CH2_LEN (16U) +#define PDS_TOUCH_FORCE_DATA_CH2_MSK (((1U << PDS_TOUCH_FORCE_DATA_CH2_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH2_POS) +#define PDS_TOUCH_FORCE_DATA_CH2_UMSK (~(((1U << PDS_TOUCH_FORCE_DATA_CH2_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH2_POS)) +#define PDS_TOUCH_FORCE_DATA_CH3 PDS_TOUCH_FORCE_DATA_CH3 +#define PDS_TOUCH_FORCE_DATA_CH3_POS (16U) +#define PDS_TOUCH_FORCE_DATA_CH3_LEN (16U) +#define PDS_TOUCH_FORCE_DATA_CH3_MSK (((1U << PDS_TOUCH_FORCE_DATA_CH3_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH3_POS) +#define PDS_TOUCH_FORCE_DATA_CH3_UMSK (~(((1U << PDS_TOUCH_FORCE_DATA_CH3_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH3_POS)) + +/* 0xA1C : Channel_force_data_2 */ +#define PDS_CHANNEL_FORCE_DATA_2_OFFSET (0xA1C) +#define PDS_TOUCH_FORCE_DATA_CH4 PDS_TOUCH_FORCE_DATA_CH4 +#define PDS_TOUCH_FORCE_DATA_CH4_POS (0U) +#define PDS_TOUCH_FORCE_DATA_CH4_LEN (16U) +#define PDS_TOUCH_FORCE_DATA_CH4_MSK (((1U << PDS_TOUCH_FORCE_DATA_CH4_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH4_POS) +#define PDS_TOUCH_FORCE_DATA_CH4_UMSK (~(((1U << PDS_TOUCH_FORCE_DATA_CH4_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH4_POS)) +#define PDS_TOUCH_FORCE_DATA_CH5 PDS_TOUCH_FORCE_DATA_CH5 +#define PDS_TOUCH_FORCE_DATA_CH5_POS (16U) +#define PDS_TOUCH_FORCE_DATA_CH5_LEN (16U) +#define PDS_TOUCH_FORCE_DATA_CH5_MSK (((1U << PDS_TOUCH_FORCE_DATA_CH5_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH5_POS) +#define PDS_TOUCH_FORCE_DATA_CH5_UMSK (~(((1U << PDS_TOUCH_FORCE_DATA_CH5_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH5_POS)) + +/* 0xA20 : Channel_force_data_3 */ +#define PDS_CHANNEL_FORCE_DATA_3_OFFSET (0xA20) +#define PDS_TOUCH_FORCE_DATA_CH6 PDS_TOUCH_FORCE_DATA_CH6 +#define PDS_TOUCH_FORCE_DATA_CH6_POS (0U) +#define PDS_TOUCH_FORCE_DATA_CH6_LEN (16U) +#define PDS_TOUCH_FORCE_DATA_CH6_MSK (((1U << PDS_TOUCH_FORCE_DATA_CH6_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH6_POS) +#define PDS_TOUCH_FORCE_DATA_CH6_UMSK (~(((1U << PDS_TOUCH_FORCE_DATA_CH6_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH6_POS)) +#define PDS_TOUCH_FORCE_DATA_CH7 PDS_TOUCH_FORCE_DATA_CH7 +#define PDS_TOUCH_FORCE_DATA_CH7_POS (16U) +#define PDS_TOUCH_FORCE_DATA_CH7_LEN (16U) +#define PDS_TOUCH_FORCE_DATA_CH7_MSK (((1U << PDS_TOUCH_FORCE_DATA_CH7_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH7_POS) +#define PDS_TOUCH_FORCE_DATA_CH7_UMSK (~(((1U << PDS_TOUCH_FORCE_DATA_CH7_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH7_POS)) + +/* 0xA24 : Channel_force_data_4 */ +#define PDS_CHANNEL_FORCE_DATA_4_OFFSET (0xA24) +#define PDS_TOUCH_FORCE_DATA_CH8 PDS_TOUCH_FORCE_DATA_CH8 +#define PDS_TOUCH_FORCE_DATA_CH8_POS (0U) +#define PDS_TOUCH_FORCE_DATA_CH8_LEN (16U) +#define PDS_TOUCH_FORCE_DATA_CH8_MSK (((1U << PDS_TOUCH_FORCE_DATA_CH8_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH8_POS) +#define PDS_TOUCH_FORCE_DATA_CH8_UMSK (~(((1U << PDS_TOUCH_FORCE_DATA_CH8_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH8_POS)) +#define PDS_TOUCH_FORCE_DATA_CH9 PDS_TOUCH_FORCE_DATA_CH9 +#define PDS_TOUCH_FORCE_DATA_CH9_POS (16U) +#define PDS_TOUCH_FORCE_DATA_CH9_LEN (16U) +#define PDS_TOUCH_FORCE_DATA_CH9_MSK (((1U << PDS_TOUCH_FORCE_DATA_CH9_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH9_POS) +#define PDS_TOUCH_FORCE_DATA_CH9_UMSK (~(((1U << PDS_TOUCH_FORCE_DATA_CH9_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH9_POS)) + +/* 0xA28 : Channel_force_data_5 */ +#define PDS_CHANNEL_FORCE_DATA_5_OFFSET (0xA28) +#define PDS_TOUCH_FORCE_DATA_CH10 PDS_TOUCH_FORCE_DATA_CH10 +#define PDS_TOUCH_FORCE_DATA_CH10_POS (0U) +#define PDS_TOUCH_FORCE_DATA_CH10_LEN (16U) +#define PDS_TOUCH_FORCE_DATA_CH10_MSK (((1U << PDS_TOUCH_FORCE_DATA_CH10_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH10_POS) +#define PDS_TOUCH_FORCE_DATA_CH10_UMSK (~(((1U << PDS_TOUCH_FORCE_DATA_CH10_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH10_POS)) +#define PDS_TOUCH_FORCE_DATA_CH11 PDS_TOUCH_FORCE_DATA_CH11 +#define PDS_TOUCH_FORCE_DATA_CH11_POS (16U) +#define PDS_TOUCH_FORCE_DATA_CH11_LEN (16U) +#define PDS_TOUCH_FORCE_DATA_CH11_MSK (((1U << PDS_TOUCH_FORCE_DATA_CH11_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH11_POS) +#define PDS_TOUCH_FORCE_DATA_CH11_UMSK (~(((1U << PDS_TOUCH_FORCE_DATA_CH11_LEN) - 1) << PDS_TOUCH_FORCE_DATA_CH11_POS)) + +/* 0xA2C : Channel_vth_data_0 */ +#define PDS_CHANNEL_VTH_DATA_0_OFFSET (0xA2C) +#define PDS_TOUCH_VTH_DATA_CH0 PDS_TOUCH_VTH_DATA_CH0 +#define PDS_TOUCH_VTH_DATA_CH0_POS (0U) +#define PDS_TOUCH_VTH_DATA_CH0_LEN (8U) +#define PDS_TOUCH_VTH_DATA_CH0_MSK (((1U << PDS_TOUCH_VTH_DATA_CH0_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH0_POS) +#define PDS_TOUCH_VTH_DATA_CH0_UMSK (~(((1U << PDS_TOUCH_VTH_DATA_CH0_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH0_POS)) +#define PDS_TOUCH_VTH_DATA_CH1 PDS_TOUCH_VTH_DATA_CH1 +#define PDS_TOUCH_VTH_DATA_CH1_POS (8U) +#define PDS_TOUCH_VTH_DATA_CH1_LEN (8U) +#define PDS_TOUCH_VTH_DATA_CH1_MSK (((1U << PDS_TOUCH_VTH_DATA_CH1_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH1_POS) +#define PDS_TOUCH_VTH_DATA_CH1_UMSK (~(((1U << PDS_TOUCH_VTH_DATA_CH1_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH1_POS)) +#define PDS_TOUCH_VTH_DATA_CH2 PDS_TOUCH_VTH_DATA_CH2 +#define PDS_TOUCH_VTH_DATA_CH2_POS (16U) +#define PDS_TOUCH_VTH_DATA_CH2_LEN (8U) +#define PDS_TOUCH_VTH_DATA_CH2_MSK (((1U << PDS_TOUCH_VTH_DATA_CH2_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH2_POS) +#define PDS_TOUCH_VTH_DATA_CH2_UMSK (~(((1U << PDS_TOUCH_VTH_DATA_CH2_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH2_POS)) +#define PDS_TOUCH_VTH_DATA_CH3 PDS_TOUCH_VTH_DATA_CH3 +#define PDS_TOUCH_VTH_DATA_CH3_POS (24U) +#define PDS_TOUCH_VTH_DATA_CH3_LEN (8U) +#define PDS_TOUCH_VTH_DATA_CH3_MSK (((1U << PDS_TOUCH_VTH_DATA_CH3_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH3_POS) +#define PDS_TOUCH_VTH_DATA_CH3_UMSK (~(((1U << PDS_TOUCH_VTH_DATA_CH3_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH3_POS)) + +/* 0xA30 : Channel_vth_data_1 */ +#define PDS_CHANNEL_VTH_DATA_1_OFFSET (0xA30) +#define PDS_TOUCH_VTH_DATA_CH4 PDS_TOUCH_VTH_DATA_CH4 +#define PDS_TOUCH_VTH_DATA_CH4_POS (0U) +#define PDS_TOUCH_VTH_DATA_CH4_LEN (8U) +#define PDS_TOUCH_VTH_DATA_CH4_MSK (((1U << PDS_TOUCH_VTH_DATA_CH4_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH4_POS) +#define PDS_TOUCH_VTH_DATA_CH4_UMSK (~(((1U << PDS_TOUCH_VTH_DATA_CH4_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH4_POS)) +#define PDS_TOUCH_VTH_DATA_CH5 PDS_TOUCH_VTH_DATA_CH5 +#define PDS_TOUCH_VTH_DATA_CH5_POS (8U) +#define PDS_TOUCH_VTH_DATA_CH5_LEN (8U) +#define PDS_TOUCH_VTH_DATA_CH5_MSK (((1U << PDS_TOUCH_VTH_DATA_CH5_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH5_POS) +#define PDS_TOUCH_VTH_DATA_CH5_UMSK (~(((1U << PDS_TOUCH_VTH_DATA_CH5_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH5_POS)) +#define PDS_TOUCH_VTH_DATA_CH6 PDS_TOUCH_VTH_DATA_CH6 +#define PDS_TOUCH_VTH_DATA_CH6_POS (16U) +#define PDS_TOUCH_VTH_DATA_CH6_LEN (8U) +#define PDS_TOUCH_VTH_DATA_CH6_MSK (((1U << PDS_TOUCH_VTH_DATA_CH6_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH6_POS) +#define PDS_TOUCH_VTH_DATA_CH6_UMSK (~(((1U << PDS_TOUCH_VTH_DATA_CH6_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH6_POS)) +#define PDS_TOUCH_VTH_DATA_CH7 PDS_TOUCH_VTH_DATA_CH7 +#define PDS_TOUCH_VTH_DATA_CH7_POS (24U) +#define PDS_TOUCH_VTH_DATA_CH7_LEN (8U) +#define PDS_TOUCH_VTH_DATA_CH7_MSK (((1U << PDS_TOUCH_VTH_DATA_CH7_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH7_POS) +#define PDS_TOUCH_VTH_DATA_CH7_UMSK (~(((1U << PDS_TOUCH_VTH_DATA_CH7_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH7_POS)) + +/* 0xA34 : Channel_vth_data_2 */ +#define PDS_CHANNEL_VTH_DATA_2_OFFSET (0xA34) +#define PDS_TOUCH_VTH_DATA_CH8 PDS_TOUCH_VTH_DATA_CH8 +#define PDS_TOUCH_VTH_DATA_CH8_POS (0U) +#define PDS_TOUCH_VTH_DATA_CH8_LEN (8U) +#define PDS_TOUCH_VTH_DATA_CH8_MSK (((1U << PDS_TOUCH_VTH_DATA_CH8_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH8_POS) +#define PDS_TOUCH_VTH_DATA_CH8_UMSK (~(((1U << PDS_TOUCH_VTH_DATA_CH8_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH8_POS)) +#define PDS_TOUCH_VTH_DATA_CH9 PDS_TOUCH_VTH_DATA_CH9 +#define PDS_TOUCH_VTH_DATA_CH9_POS (8U) +#define PDS_TOUCH_VTH_DATA_CH9_LEN (8U) +#define PDS_TOUCH_VTH_DATA_CH9_MSK (((1U << PDS_TOUCH_VTH_DATA_CH9_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH9_POS) +#define PDS_TOUCH_VTH_DATA_CH9_UMSK (~(((1U << PDS_TOUCH_VTH_DATA_CH9_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH9_POS)) +#define PDS_TOUCH_VTH_DATA_CH10 PDS_TOUCH_VTH_DATA_CH10 +#define PDS_TOUCH_VTH_DATA_CH10_POS (16U) +#define PDS_TOUCH_VTH_DATA_CH10_LEN (8U) +#define PDS_TOUCH_VTH_DATA_CH10_MSK (((1U << PDS_TOUCH_VTH_DATA_CH10_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH10_POS) +#define PDS_TOUCH_VTH_DATA_CH10_UMSK (~(((1U << PDS_TOUCH_VTH_DATA_CH10_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH10_POS)) +#define PDS_TOUCH_VTH_DATA_CH11 PDS_TOUCH_VTH_DATA_CH11 +#define PDS_TOUCH_VTH_DATA_CH11_POS (24U) +#define PDS_TOUCH_VTH_DATA_CH11_LEN (8U) +#define PDS_TOUCH_VTH_DATA_CH11_MSK (((1U << PDS_TOUCH_VTH_DATA_CH11_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH11_POS) +#define PDS_TOUCH_VTH_DATA_CH11_UMSK (~(((1U << PDS_TOUCH_VTH_DATA_CH11_LEN) - 1) << PDS_TOUCH_VTH_DATA_CH11_POS)) + +/* 0xA38 : Channel_raw_data_0 */ +#define PDS_CHANNEL_RAW_DATA_0_OFFSET (0xA38) +#define PDS_TOUCH_RAW_DATA_CH0 PDS_TOUCH_RAW_DATA_CH0 +#define PDS_TOUCH_RAW_DATA_CH0_POS (0U) +#define PDS_TOUCH_RAW_DATA_CH0_LEN (16U) +#define PDS_TOUCH_RAW_DATA_CH0_MSK (((1U << PDS_TOUCH_RAW_DATA_CH0_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH0_POS) +#define PDS_TOUCH_RAW_DATA_CH0_UMSK (~(((1U << PDS_TOUCH_RAW_DATA_CH0_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH0_POS)) + +/* 0xA3C : Channel_raw_data_1 */ +#define PDS_CHANNEL_RAW_DATA_1_OFFSET (0xA3C) +#define PDS_TOUCH_RAW_DATA_CH1 PDS_TOUCH_RAW_DATA_CH1 +#define PDS_TOUCH_RAW_DATA_CH1_POS (0U) +#define PDS_TOUCH_RAW_DATA_CH1_LEN (16U) +#define PDS_TOUCH_RAW_DATA_CH1_MSK (((1U << PDS_TOUCH_RAW_DATA_CH1_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH1_POS) +#define PDS_TOUCH_RAW_DATA_CH1_UMSK (~(((1U << PDS_TOUCH_RAW_DATA_CH1_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH1_POS)) + +/* 0xA40 : Channel_raw_data_2 */ +#define PDS_CHANNEL_RAW_DATA_2_OFFSET (0xA40) +#define PDS_TOUCH_RAW_DATA_CH2 PDS_TOUCH_RAW_DATA_CH2 +#define PDS_TOUCH_RAW_DATA_CH2_POS (0U) +#define PDS_TOUCH_RAW_DATA_CH2_LEN (16U) +#define PDS_TOUCH_RAW_DATA_CH2_MSK (((1U << PDS_TOUCH_RAW_DATA_CH2_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH2_POS) +#define PDS_TOUCH_RAW_DATA_CH2_UMSK (~(((1U << PDS_TOUCH_RAW_DATA_CH2_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH2_POS)) + +/* 0xA44 : Channel_raw_data_3 */ +#define PDS_CHANNEL_RAW_DATA_3_OFFSET (0xA44) +#define PDS_TOUCH_RAW_DATA_CH3 PDS_TOUCH_RAW_DATA_CH3 +#define PDS_TOUCH_RAW_DATA_CH3_POS (0U) +#define PDS_TOUCH_RAW_DATA_CH3_LEN (16U) +#define PDS_TOUCH_RAW_DATA_CH3_MSK (((1U << PDS_TOUCH_RAW_DATA_CH3_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH3_POS) +#define PDS_TOUCH_RAW_DATA_CH3_UMSK (~(((1U << PDS_TOUCH_RAW_DATA_CH3_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH3_POS)) + +/* 0xA48 : Channel_raw_data_4 */ +#define PDS_CHANNEL_RAW_DATA_4_OFFSET (0xA48) +#define PDS_TOUCH_RAW_DATA_CH4 PDS_TOUCH_RAW_DATA_CH4 +#define PDS_TOUCH_RAW_DATA_CH4_POS (0U) +#define PDS_TOUCH_RAW_DATA_CH4_LEN (16U) +#define PDS_TOUCH_RAW_DATA_CH4_MSK (((1U << PDS_TOUCH_RAW_DATA_CH4_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH4_POS) +#define PDS_TOUCH_RAW_DATA_CH4_UMSK (~(((1U << PDS_TOUCH_RAW_DATA_CH4_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH4_POS)) + +/* 0xA4C : Channel_raw_data_5 */ +#define PDS_CHANNEL_RAW_DATA_5_OFFSET (0xA4C) +#define PDS_TOUCH_RAW_DATA_CH5 PDS_TOUCH_RAW_DATA_CH5 +#define PDS_TOUCH_RAW_DATA_CH5_POS (0U) +#define PDS_TOUCH_RAW_DATA_CH5_LEN (16U) +#define PDS_TOUCH_RAW_DATA_CH5_MSK (((1U << PDS_TOUCH_RAW_DATA_CH5_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH5_POS) +#define PDS_TOUCH_RAW_DATA_CH5_UMSK (~(((1U << PDS_TOUCH_RAW_DATA_CH5_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH5_POS)) + +/* 0xA50 : Channel_raw_data_6 */ +#define PDS_CHANNEL_RAW_DATA_6_OFFSET (0xA50) +#define PDS_TOUCH_RAW_DATA_CH6 PDS_TOUCH_RAW_DATA_CH6 +#define PDS_TOUCH_RAW_DATA_CH6_POS (0U) +#define PDS_TOUCH_RAW_DATA_CH6_LEN (16U) +#define PDS_TOUCH_RAW_DATA_CH6_MSK (((1U << PDS_TOUCH_RAW_DATA_CH6_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH6_POS) +#define PDS_TOUCH_RAW_DATA_CH6_UMSK (~(((1U << PDS_TOUCH_RAW_DATA_CH6_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH6_POS)) + +/* 0xA54 : Channel_raw_data_7 */ +#define PDS_CHANNEL_RAW_DATA_7_OFFSET (0xA54) +#define PDS_TOUCH_RAW_DATA_CH7 PDS_TOUCH_RAW_DATA_CH7 +#define PDS_TOUCH_RAW_DATA_CH7_POS (0U) +#define PDS_TOUCH_RAW_DATA_CH7_LEN (16U) +#define PDS_TOUCH_RAW_DATA_CH7_MSK (((1U << PDS_TOUCH_RAW_DATA_CH7_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH7_POS) +#define PDS_TOUCH_RAW_DATA_CH7_UMSK (~(((1U << PDS_TOUCH_RAW_DATA_CH7_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH7_POS)) + +/* 0xA58 : Channel_raw_data_8 */ +#define PDS_CHANNEL_RAW_DATA_8_OFFSET (0xA58) +#define PDS_TOUCH_RAW_DATA_CH8 PDS_TOUCH_RAW_DATA_CH8 +#define PDS_TOUCH_RAW_DATA_CH8_POS (0U) +#define PDS_TOUCH_RAW_DATA_CH8_LEN (16U) +#define PDS_TOUCH_RAW_DATA_CH8_MSK (((1U << PDS_TOUCH_RAW_DATA_CH8_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH8_POS) +#define PDS_TOUCH_RAW_DATA_CH8_UMSK (~(((1U << PDS_TOUCH_RAW_DATA_CH8_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH8_POS)) + +/* 0xA5C : Channel_raw_data_9 */ +#define PDS_CHANNEL_RAW_DATA_9_OFFSET (0xA5C) +#define PDS_TOUCH_RAW_DATA_CH9 PDS_TOUCH_RAW_DATA_CH9 +#define PDS_TOUCH_RAW_DATA_CH9_POS (0U) +#define PDS_TOUCH_RAW_DATA_CH9_LEN (16U) +#define PDS_TOUCH_RAW_DATA_CH9_MSK (((1U << PDS_TOUCH_RAW_DATA_CH9_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH9_POS) +#define PDS_TOUCH_RAW_DATA_CH9_UMSK (~(((1U << PDS_TOUCH_RAW_DATA_CH9_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH9_POS)) + +/* 0xA60 : Channel_raw_data_10 */ +#define PDS_CHANNEL_RAW_DATA_10_OFFSET (0xA60) +#define PDS_TOUCH_RAW_DATA_CH10 PDS_TOUCH_RAW_DATA_CH10 +#define PDS_TOUCH_RAW_DATA_CH10_POS (0U) +#define PDS_TOUCH_RAW_DATA_CH10_LEN (16U) +#define PDS_TOUCH_RAW_DATA_CH10_MSK (((1U << PDS_TOUCH_RAW_DATA_CH10_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH10_POS) +#define PDS_TOUCH_RAW_DATA_CH10_UMSK (~(((1U << PDS_TOUCH_RAW_DATA_CH10_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH10_POS)) + +/* 0xA64 : Channel_raw_data_11 */ +#define PDS_CHANNEL_RAW_DATA_11_OFFSET (0xA64) +#define PDS_TOUCH_RAW_DATA_CH11 PDS_TOUCH_RAW_DATA_CH11 +#define PDS_TOUCH_RAW_DATA_CH11_POS (0U) +#define PDS_TOUCH_RAW_DATA_CH11_LEN (16U) +#define PDS_TOUCH_RAW_DATA_CH11_MSK (((1U << PDS_TOUCH_RAW_DATA_CH11_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH11_POS) +#define PDS_TOUCH_RAW_DATA_CH11_UMSK (~(((1U << PDS_TOUCH_RAW_DATA_CH11_LEN) - 1) << PDS_TOUCH_RAW_DATA_CH11_POS)) + +/* 0xA68 : Channel_LTA_data_0 */ +#define PDS_CHANNEL_LTA_DATA_0_OFFSET (0xA68) +#define PDS_TOUCH_LTA_DATA_CH0 PDS_TOUCH_LTA_DATA_CH0 +#define PDS_TOUCH_LTA_DATA_CH0_POS (0U) +#define PDS_TOUCH_LTA_DATA_CH0_LEN (16U) +#define PDS_TOUCH_LTA_DATA_CH0_MSK (((1U << PDS_TOUCH_LTA_DATA_CH0_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH0_POS) +#define PDS_TOUCH_LTA_DATA_CH0_UMSK (~(((1U << PDS_TOUCH_LTA_DATA_CH0_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH0_POS)) + +/* 0xA6C : Channel_LTA_data_1 */ +#define PDS_CHANNEL_LTA_DATA_1_OFFSET (0xA6C) +#define PDS_TOUCH_LTA_DATA_CH1 PDS_TOUCH_LTA_DATA_CH1 +#define PDS_TOUCH_LTA_DATA_CH1_POS (0U) +#define PDS_TOUCH_LTA_DATA_CH1_LEN (16U) +#define PDS_TOUCH_LTA_DATA_CH1_MSK (((1U << PDS_TOUCH_LTA_DATA_CH1_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH1_POS) +#define PDS_TOUCH_LTA_DATA_CH1_UMSK (~(((1U << PDS_TOUCH_LTA_DATA_CH1_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH1_POS)) + +/* 0xA70 : Channel_LTA_data_2 */ +#define PDS_CHANNEL_LTA_DATA_2_OFFSET (0xA70) +#define PDS_TOUCH_LTA_DATA_CH2 PDS_TOUCH_LTA_DATA_CH2 +#define PDS_TOUCH_LTA_DATA_CH2_POS (0U) +#define PDS_TOUCH_LTA_DATA_CH2_LEN (16U) +#define PDS_TOUCH_LTA_DATA_CH2_MSK (((1U << PDS_TOUCH_LTA_DATA_CH2_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH2_POS) +#define PDS_TOUCH_LTA_DATA_CH2_UMSK (~(((1U << PDS_TOUCH_LTA_DATA_CH2_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH2_POS)) + +/* 0xA74 : Channel_LTA_data_3 */ +#define PDS_CHANNEL_LTA_DATA_3_OFFSET (0xA74) +#define PDS_TOUCH_LTA_DATA_CH3 PDS_TOUCH_LTA_DATA_CH3 +#define PDS_TOUCH_LTA_DATA_CH3_POS (0U) +#define PDS_TOUCH_LTA_DATA_CH3_LEN (16U) +#define PDS_TOUCH_LTA_DATA_CH3_MSK (((1U << PDS_TOUCH_LTA_DATA_CH3_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH3_POS) +#define PDS_TOUCH_LTA_DATA_CH3_UMSK (~(((1U << PDS_TOUCH_LTA_DATA_CH3_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH3_POS)) + +/* 0xA78 : Channel_LTA_data_4 */ +#define PDS_CHANNEL_LTA_DATA_4_OFFSET (0xA78) +#define PDS_TOUCH_LTA_DATA_CH4 PDS_TOUCH_LTA_DATA_CH4 +#define PDS_TOUCH_LTA_DATA_CH4_POS (0U) +#define PDS_TOUCH_LTA_DATA_CH4_LEN (16U) +#define PDS_TOUCH_LTA_DATA_CH4_MSK (((1U << PDS_TOUCH_LTA_DATA_CH4_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH4_POS) +#define PDS_TOUCH_LTA_DATA_CH4_UMSK (~(((1U << PDS_TOUCH_LTA_DATA_CH4_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH4_POS)) + +/* 0xA7C : Channel_LTA_data_5 */ +#define PDS_CHANNEL_LTA_DATA_5_OFFSET (0xA7C) +#define PDS_TOUCH_LTA_DATA_CH5 PDS_TOUCH_LTA_DATA_CH5 +#define PDS_TOUCH_LTA_DATA_CH5_POS (0U) +#define PDS_TOUCH_LTA_DATA_CH5_LEN (16U) +#define PDS_TOUCH_LTA_DATA_CH5_MSK (((1U << PDS_TOUCH_LTA_DATA_CH5_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH5_POS) +#define PDS_TOUCH_LTA_DATA_CH5_UMSK (~(((1U << PDS_TOUCH_LTA_DATA_CH5_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH5_POS)) + +/* 0xA80 : Channel_LTA_data_6 */ +#define PDS_CHANNEL_LTA_DATA_6_OFFSET (0xA80) +#define PDS_TOUCH_LTA_DATA_CH6 PDS_TOUCH_LTA_DATA_CH6 +#define PDS_TOUCH_LTA_DATA_CH6_POS (0U) +#define PDS_TOUCH_LTA_DATA_CH6_LEN (16U) +#define PDS_TOUCH_LTA_DATA_CH6_MSK (((1U << PDS_TOUCH_LTA_DATA_CH6_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH6_POS) +#define PDS_TOUCH_LTA_DATA_CH6_UMSK (~(((1U << PDS_TOUCH_LTA_DATA_CH6_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH6_POS)) + +/* 0xA84 : Channel_LTA_data_7 */ +#define PDS_CHANNEL_LTA_DATA_7_OFFSET (0xA84) +#define PDS_TOUCH_LTA_DATA_CH7 PDS_TOUCH_LTA_DATA_CH7 +#define PDS_TOUCH_LTA_DATA_CH7_POS (0U) +#define PDS_TOUCH_LTA_DATA_CH7_LEN (16U) +#define PDS_TOUCH_LTA_DATA_CH7_MSK (((1U << PDS_TOUCH_LTA_DATA_CH7_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH7_POS) +#define PDS_TOUCH_LTA_DATA_CH7_UMSK (~(((1U << PDS_TOUCH_LTA_DATA_CH7_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH7_POS)) + +/* 0xA88 : Channel_LTA_data_8 */ +#define PDS_CHANNEL_LTA_DATA_8_OFFSET (0xA88) +#define PDS_TOUCH_LTA_DATA_CH8 PDS_TOUCH_LTA_DATA_CH8 +#define PDS_TOUCH_LTA_DATA_CH8_POS (0U) +#define PDS_TOUCH_LTA_DATA_CH8_LEN (16U) +#define PDS_TOUCH_LTA_DATA_CH8_MSK (((1U << PDS_TOUCH_LTA_DATA_CH8_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH8_POS) +#define PDS_TOUCH_LTA_DATA_CH8_UMSK (~(((1U << PDS_TOUCH_LTA_DATA_CH8_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH8_POS)) + +/* 0xA8C : Channel_LTA_data_9 */ +#define PDS_CHANNEL_LTA_DATA_9_OFFSET (0xA8C) +#define PDS_TOUCH_LTA_DATA_CH9 PDS_TOUCH_LTA_DATA_CH9 +#define PDS_TOUCH_LTA_DATA_CH9_POS (0U) +#define PDS_TOUCH_LTA_DATA_CH9_LEN (16U) +#define PDS_TOUCH_LTA_DATA_CH9_MSK (((1U << PDS_TOUCH_LTA_DATA_CH9_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH9_POS) +#define PDS_TOUCH_LTA_DATA_CH9_UMSK (~(((1U << PDS_TOUCH_LTA_DATA_CH9_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH9_POS)) + +/* 0xA90 : Channel_LTA_data_10 */ +#define PDS_CHANNEL_LTA_DATA_10_OFFSET (0xA90) +#define PDS_TOUCH_LTA_DATA_CH10 PDS_TOUCH_LTA_DATA_CH10 +#define PDS_TOUCH_LTA_DATA_CH10_POS (0U) +#define PDS_TOUCH_LTA_DATA_CH10_LEN (16U) +#define PDS_TOUCH_LTA_DATA_CH10_MSK (((1U << PDS_TOUCH_LTA_DATA_CH10_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH10_POS) +#define PDS_TOUCH_LTA_DATA_CH10_UMSK (~(((1U << PDS_TOUCH_LTA_DATA_CH10_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH10_POS)) + +/* 0xA94 : Channel_LTA_data_11 */ +#define PDS_CHANNEL_LTA_DATA_11_OFFSET (0xA94) +#define PDS_TOUCH_LTA_DATA_CH11 PDS_TOUCH_LTA_DATA_CH11 +#define PDS_TOUCH_LTA_DATA_CH11_POS (0U) +#define PDS_TOUCH_LTA_DATA_CH11_LEN (16U) +#define PDS_TOUCH_LTA_DATA_CH11_MSK (((1U << PDS_TOUCH_LTA_DATA_CH11_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH11_POS) +#define PDS_TOUCH_LTA_DATA_CH11_UMSK (~(((1U << PDS_TOUCH_LTA_DATA_CH11_LEN) - 1) << PDS_TOUCH_LTA_DATA_CH11_POS)) + +/* 0xA98 : Channel_FLT_data_0 */ +#define PDS_CHANNEL_FLT_DATA_0_OFFSET (0xA98) +#define PDS_TOUCH_FLT_DATA_CH0 PDS_TOUCH_FLT_DATA_CH0 +#define PDS_TOUCH_FLT_DATA_CH0_POS (0U) +#define PDS_TOUCH_FLT_DATA_CH0_LEN (16U) +#define PDS_TOUCH_FLT_DATA_CH0_MSK (((1U << PDS_TOUCH_FLT_DATA_CH0_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH0_POS) +#define PDS_TOUCH_FLT_DATA_CH0_UMSK (~(((1U << PDS_TOUCH_FLT_DATA_CH0_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH0_POS)) + +/* 0xA9C : Channel_FLT_data_1 */ +#define PDS_CHANNEL_FLT_DATA_1_OFFSET (0xA9C) +#define PDS_TOUCH_FLT_DATA_CH1 PDS_TOUCH_FLT_DATA_CH1 +#define PDS_TOUCH_FLT_DATA_CH1_POS (0U) +#define PDS_TOUCH_FLT_DATA_CH1_LEN (16U) +#define PDS_TOUCH_FLT_DATA_CH1_MSK (((1U << PDS_TOUCH_FLT_DATA_CH1_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH1_POS) +#define PDS_TOUCH_FLT_DATA_CH1_UMSK (~(((1U << PDS_TOUCH_FLT_DATA_CH1_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH1_POS)) + +/* 0xAA0 : Channel_FLT_data_2 */ +#define PDS_CHANNEL_FLT_DATA_2_OFFSET (0xAA0) +#define PDS_TOUCH_FLT_DATA_CH2 PDS_TOUCH_FLT_DATA_CH2 +#define PDS_TOUCH_FLT_DATA_CH2_POS (0U) +#define PDS_TOUCH_FLT_DATA_CH2_LEN (16U) +#define PDS_TOUCH_FLT_DATA_CH2_MSK (((1U << PDS_TOUCH_FLT_DATA_CH2_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH2_POS) +#define PDS_TOUCH_FLT_DATA_CH2_UMSK (~(((1U << PDS_TOUCH_FLT_DATA_CH2_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH2_POS)) + +/* 0xAA4 : Channel_FLT_data_3 */ +#define PDS_CHANNEL_FLT_DATA_3_OFFSET (0xAA4) +#define PDS_TOUCH_FLT_DATA_CH3 PDS_TOUCH_FLT_DATA_CH3 +#define PDS_TOUCH_FLT_DATA_CH3_POS (0U) +#define PDS_TOUCH_FLT_DATA_CH3_LEN (16U) +#define PDS_TOUCH_FLT_DATA_CH3_MSK (((1U << PDS_TOUCH_FLT_DATA_CH3_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH3_POS) +#define PDS_TOUCH_FLT_DATA_CH3_UMSK (~(((1U << PDS_TOUCH_FLT_DATA_CH3_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH3_POS)) + +/* 0xAA8 : Channel_FLT_data_4 */ +#define PDS_CHANNEL_FLT_DATA_4_OFFSET (0xAA8) +#define PDS_TOUCH_FLT_DATA_CH4 PDS_TOUCH_FLT_DATA_CH4 +#define PDS_TOUCH_FLT_DATA_CH4_POS (0U) +#define PDS_TOUCH_FLT_DATA_CH4_LEN (16U) +#define PDS_TOUCH_FLT_DATA_CH4_MSK (((1U << PDS_TOUCH_FLT_DATA_CH4_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH4_POS) +#define PDS_TOUCH_FLT_DATA_CH4_UMSK (~(((1U << PDS_TOUCH_FLT_DATA_CH4_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH4_POS)) + +/* 0xAAC : Channel_FLT_data_5 */ +#define PDS_CHANNEL_FLT_DATA_5_OFFSET (0xAAC) +#define PDS_TOUCH_FLT_DATA_CH5 PDS_TOUCH_FLT_DATA_CH5 +#define PDS_TOUCH_FLT_DATA_CH5_POS (0U) +#define PDS_TOUCH_FLT_DATA_CH5_LEN (16U) +#define PDS_TOUCH_FLT_DATA_CH5_MSK (((1U << PDS_TOUCH_FLT_DATA_CH5_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH5_POS) +#define PDS_TOUCH_FLT_DATA_CH5_UMSK (~(((1U << PDS_TOUCH_FLT_DATA_CH5_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH5_POS)) + +/* 0xAB0 : Channel_FLT_data_6 */ +#define PDS_CHANNEL_FLT_DATA_6_OFFSET (0xAB0) +#define PDS_TOUCH_FLT_DATA_CH6 PDS_TOUCH_FLT_DATA_CH6 +#define PDS_TOUCH_FLT_DATA_CH6_POS (0U) +#define PDS_TOUCH_FLT_DATA_CH6_LEN (16U) +#define PDS_TOUCH_FLT_DATA_CH6_MSK (((1U << PDS_TOUCH_FLT_DATA_CH6_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH6_POS) +#define PDS_TOUCH_FLT_DATA_CH6_UMSK (~(((1U << PDS_TOUCH_FLT_DATA_CH6_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH6_POS)) + +/* 0xAB4 : Channel_FLT_data_7 */ +#define PDS_CHANNEL_FLT_DATA_7_OFFSET (0xAB4) +#define PDS_TOUCH_FLT_DATA_CH7 PDS_TOUCH_FLT_DATA_CH7 +#define PDS_TOUCH_FLT_DATA_CH7_POS (0U) +#define PDS_TOUCH_FLT_DATA_CH7_LEN (16U) +#define PDS_TOUCH_FLT_DATA_CH7_MSK (((1U << PDS_TOUCH_FLT_DATA_CH7_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH7_POS) +#define PDS_TOUCH_FLT_DATA_CH7_UMSK (~(((1U << PDS_TOUCH_FLT_DATA_CH7_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH7_POS)) + +/* 0xAB8 : Channel_FLT_data_8 */ +#define PDS_CHANNEL_FLT_DATA_8_OFFSET (0xAB8) +#define PDS_TOUCH_FLT_DATA_CH8 PDS_TOUCH_FLT_DATA_CH8 +#define PDS_TOUCH_FLT_DATA_CH8_POS (0U) +#define PDS_TOUCH_FLT_DATA_CH8_LEN (16U) +#define PDS_TOUCH_FLT_DATA_CH8_MSK (((1U << PDS_TOUCH_FLT_DATA_CH8_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH8_POS) +#define PDS_TOUCH_FLT_DATA_CH8_UMSK (~(((1U << PDS_TOUCH_FLT_DATA_CH8_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH8_POS)) + +/* 0xABC : Channel_FLT_data_9 */ +#define PDS_CHANNEL_FLT_DATA_9_OFFSET (0xABC) +#define PDS_TOUCH_FLT_DATA_CH9 PDS_TOUCH_FLT_DATA_CH9 +#define PDS_TOUCH_FLT_DATA_CH9_POS (0U) +#define PDS_TOUCH_FLT_DATA_CH9_LEN (16U) +#define PDS_TOUCH_FLT_DATA_CH9_MSK (((1U << PDS_TOUCH_FLT_DATA_CH9_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH9_POS) +#define PDS_TOUCH_FLT_DATA_CH9_UMSK (~(((1U << PDS_TOUCH_FLT_DATA_CH9_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH9_POS)) + +/* 0xAC0 : Channel_FLT_data_10 */ +#define PDS_CHANNEL_FLT_DATA_10_OFFSET (0xAC0) +#define PDS_TOUCH_FLT_DATA_CH10 PDS_TOUCH_FLT_DATA_CH10 +#define PDS_TOUCH_FLT_DATA_CH10_POS (0U) +#define PDS_TOUCH_FLT_DATA_CH10_LEN (16U) +#define PDS_TOUCH_FLT_DATA_CH10_MSK (((1U << PDS_TOUCH_FLT_DATA_CH10_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH10_POS) +#define PDS_TOUCH_FLT_DATA_CH10_UMSK (~(((1U << PDS_TOUCH_FLT_DATA_CH10_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH10_POS)) + +/* 0xAC4 : Channel_FLT_data_11 */ +#define PDS_CHANNEL_FLT_DATA_11_OFFSET (0xAC4) +#define PDS_TOUCH_FLT_DATA_CH11 PDS_TOUCH_FLT_DATA_CH11 +#define PDS_TOUCH_FLT_DATA_CH11_POS (0U) +#define PDS_TOUCH_FLT_DATA_CH11_LEN (16U) +#define PDS_TOUCH_FLT_DATA_CH11_MSK (((1U << PDS_TOUCH_FLT_DATA_CH11_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH11_POS) +#define PDS_TOUCH_FLT_DATA_CH11_UMSK (~(((1U << PDS_TOUCH_FLT_DATA_CH11_LEN) - 1) << PDS_TOUCH_FLT_DATA_CH11_POS)) + +/* 0xAC8 : touch_rsvd */ +#define PDS_TOUCH_RSVD_OFFSET (0xAC8) +#define PDS_TOUCH_RESERVED PDS_TOUCH_RESERVED +#define PDS_TOUCH_RESERVED_POS (0U) +#define PDS_TOUCH_RESERVED_LEN (8U) +#define PDS_TOUCH_RESERVED_MSK (((1U << PDS_TOUCH_RESERVED_LEN) - 1) << PDS_TOUCH_RESERVED_POS) +#define PDS_TOUCH_RESERVED_UMSK (~(((1U << PDS_TOUCH_RESERVED_LEN) - 1) << PDS_TOUCH_RESERVED_POS)) + +/* 0xACC : touch_int_setting */ +#define PDS_TOUCH_INT_SETTING_OFFSET (0xACC) +#define PDS_TOUCH_INT_CLR PDS_TOUCH_INT_CLR +#define PDS_TOUCH_INT_CLR_POS (0U) +#define PDS_TOUCH_INT_CLR_LEN (12U) +#define PDS_TOUCH_INT_CLR_MSK (((1U << PDS_TOUCH_INT_CLR_LEN) - 1) << PDS_TOUCH_INT_CLR_POS) +#define PDS_TOUCH_INT_CLR_UMSK (~(((1U << PDS_TOUCH_INT_CLR_LEN) - 1) << PDS_TOUCH_INT_CLR_POS)) +#define PDS_TOUCH_INT_MASK PDS_TOUCH_INT_MASK +#define PDS_TOUCH_INT_MASK_POS (16U) +#define PDS_TOUCH_INT_MASK_LEN (12U) +#define PDS_TOUCH_INT_MASK_MSK (((1U << PDS_TOUCH_INT_MASK_LEN) - 1) << PDS_TOUCH_INT_MASK_POS) +#define PDS_TOUCH_INT_MASK_UMSK (~(((1U << PDS_TOUCH_INT_MASK_LEN) - 1) << PDS_TOUCH_INT_MASK_POS)) +#define PDS_TOUCH_INT_EN PDS_TOUCH_INT_EN +#define PDS_TOUCH_INT_EN_POS (31U) +#define PDS_TOUCH_INT_EN_LEN (1U) +#define PDS_TOUCH_INT_EN_MSK (((1U << PDS_TOUCH_INT_EN_LEN) - 1) << PDS_TOUCH_INT_EN_POS) +#define PDS_TOUCH_INT_EN_UMSK (~(((1U << PDS_TOUCH_INT_EN_LEN) - 1) << PDS_TOUCH_INT_EN_POS)) + +/* 0xAD0 : touch_int_status */ +#define PDS_TOUCH_INT_STATUS_OFFSET (0xAD0) +#define PDS_TOUCH_INT_STATUS PDS_TOUCH_INT_STATUS +#define PDS_TOUCH_INT_STATUS_POS (0U) +#define PDS_TOUCH_INT_STATUS_LEN (12U) +#define PDS_TOUCH_INT_STATUS_MSK (((1U << PDS_TOUCH_INT_STATUS_LEN) - 1) << PDS_TOUCH_INT_STATUS_POS) +#define PDS_TOUCH_INT_STATUS_UMSK (~(((1U << PDS_TOUCH_INT_STATUS_LEN) - 1) << PDS_TOUCH_INT_STATUS_POS)) +#define PDS_TOUCH_END_FLAG PDS_TOUCH_END_FLAG +#define PDS_TOUCH_END_FLAG_POS (12U) +#define PDS_TOUCH_END_FLAG_LEN (1U) +#define PDS_TOUCH_END_FLAG_MSK (((1U << PDS_TOUCH_END_FLAG_LEN) - 1) << PDS_TOUCH_END_FLAG_POS) +#define PDS_TOUCH_END_FLAG_UMSK (~(((1U << PDS_TOUCH_END_FLAG_LEN) - 1) << PDS_TOUCH_END_FLAG_POS)) + +struct pds_reg { + /* 0x0 : PDS_CTL */ + union { + struct { + uint32_t pds_start_ps : 1; /* [ 0], w1p, 0x0 */ + uint32_t cr_sleep_forever : 1; /* [ 1], r/w, 0x0 */ + uint32_t cr_xtal_force_off : 1; /* [ 2], r/w, 0x0 */ + uint32_t cr_pds_wifi_save_state : 1; /* [ 3], r/w, 0x0 */ + uint32_t cr_pds_pd_dcdc11 : 1; /* [ 4], r/w, 0x0 */ + uint32_t cr_pds_pd_bg_sys : 1; /* [ 5], r/w, 0x0 */ + uint32_t cr_pds_ctrl_gpio_ie_pu_pd : 1; /* [ 6], r/w, 0x0 */ + uint32_t cr_pds_pd_dcdc18 : 1; /* [ 7], r/w, 0x0 */ + uint32_t cr_pds_gate_clk : 1; /* [ 8], r/w, 0x1 */ + uint32_t cr_pds_mem_stby : 1; /* [ 9], r/w, 0x1 */ + uint32_t cr_pds_glb_reg_reset_protect : 1; /* [ 10], r/w, 0x0 */ + uint32_t cr_pds_iso_en : 1; /* [ 11], r/w, 0x1 */ + uint32_t cr_pds_wait_xtal_rdy : 1; /* [ 12], r/w, 0x0 */ + uint32_t cr_pds_pwr_off : 1; /* [ 13], r/w, 0x1 */ + uint32_t cr_pds_pd_xtal : 1; /* [ 14], r/w, 0x1 */ + uint32_t cr_pds_ctrl_soc_enb : 1; /* [ 15], r/w, 0x0 */ + uint32_t cr_pds_rst_soc : 1; /* [ 16], r/w, 0x0 */ + uint32_t cr_pds_rc32m_off_dis : 1; /* [ 17], r/w, 0x0 */ + uint32_t cr_pds_dcdc11_vsel_en : 1; /* [ 18], r/w, 0x0 */ + uint32_t cr_pds_ctrl_usbpll_pd : 1; /* [ 19], r/w, 0x0 */ + uint32_t cr_pds_ctrl_aupll_pd : 1; /* [ 20], r/w, 0x0 */ + uint32_t cr_pds_ctrl_cpupll_pd : 1; /* [ 21], r/w, 0x0 */ + uint32_t cr_pds_ctrl_wifipll_pd : 1; /* [ 22], r/w, 0x0 */ + uint32_t cr_pds_dcdc11_vol : 5; /* [27:23], r/w, 0x8 */ + uint32_t cr_pds_ctrl_rf : 2; /* [29:28], r/w, 0x1 */ + uint32_t cr_pds_start_use_tbtt_sleep : 1; /* [ 30], r/w, 0x0 */ + uint32_t cr_pds_gpio_iso_mode : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } PDS_CTL; + + /* 0x4 : PDS_TIME1 */ + union { + struct { + uint32_t cr_sleep_duration : 32; /* [31: 0], r/w, 0xca8 */ + } BF; + uint32_t WORD; + } PDS_TIME1; + + /* 0x8 reserved */ + uint8_t RESERVED0x8[4]; + + /* 0xC : PDS_INT */ + union { + struct { + uint32_t ro_pds_wake_int : 1; /* [ 0], r, 0x0 */ + uint32_t ro_pds_rf_done_int : 1; /* [ 1], r, 0x0 */ + uint32_t ro_pds_wifi_tbtt_sleep_irq : 1; /* [ 2], r, 0x0 */ + uint32_t ro_pds_wifi_tbtt_wakeup_irq : 1; /* [ 3], r, 0x0 */ + uint32_t cr_pds_wake_int_mask : 1; /* [ 4], r/w, 0x0 */ + uint32_t cr_pds_rf_done_int_mask : 1; /* [ 5], r/w, 0x0 */ + uint32_t cr_pds_wifi_tbtt_sleep_irq_mask : 1; /* [ 6], r/w, 0x0 */ + uint32_t cr_pds_wifi_tbtt_wakeup_irq_mask : 1; /* [ 7], r/w, 0x0 */ + uint32_t cr_pds_int_clr : 1; /* [ 8], r/w, 0x0 */ + uint32_t reserved_9 : 1; /* [ 9], rsvd, 0x0 */ + uint32_t cr_pds_wakeup_src_en : 11; /* [20:10], r/w, 0x7ff */ + uint32_t ro_pds_wakeup_event : 11; /* [31:21], r, 0x0 */ + } BF; + uint32_t WORD; + } PDS_INT; + + /* 0x10 : PDS_CTL2 */ + union { + struct { + uint32_t reserved_0 : 1; /* [ 0], rsvd, 0x0 */ + uint32_t cr_pds_force_mm_pwr_off : 1; /* [ 1], r/w, 0x1 */ + uint32_t reserved_2 : 1; /* [ 2], rsvd, 0x0 */ + uint32_t cr_pds_force_usb_pwr_off : 1; /* [ 3], r/w, 0x0 */ + uint32_t reserved_4 : 1; /* [ 4], rsvd, 0x0 */ + uint32_t cr_pds_force_mm_iso_en : 1; /* [ 5], r/w, 0x1 */ + uint32_t reserved_6 : 1; /* [ 6], rsvd, 0x0 */ + uint32_t cr_pds_force_usb_iso_en : 1; /* [ 7], r/w, 0x0 */ + uint32_t cr_pds_force_np_pds_rst : 1; /* [ 8], r/w, 0x0 */ + uint32_t cr_pds_force_mm_pds_rst : 1; /* [ 9], r/w, 0x1 */ + uint32_t cr_pds_force_wb_pds_rst : 1; /* [ 10], r/w, 0x0 */ + uint32_t cr_pds_force_usb_pds_rst : 1; /* [ 11], r/w, 0x0 */ + uint32_t cr_pds_force_np_mem_stby : 1; /* [ 12], r/w, 0x0 */ + uint32_t cr_pds_force_mm_mem_stby : 1; /* [ 13], r/w, 0x1 */ + uint32_t cr_pds_force_wb_mem_stby : 1; /* [ 14], r/w, 0x0 */ + uint32_t cr_pds_force_usb_mem_stby : 1; /* [ 15], r/w, 0x0 */ + uint32_t cr_pds_force_np_gate_clk : 1; /* [ 16], r/w, 0x0 */ + uint32_t cr_pds_force_mm_gate_clk : 1; /* [ 17], r/w, 0x1 */ + uint32_t cr_pds_force_wb_gate_clk : 1; /* [ 18], r/w, 0x0 */ + uint32_t cr_pds_force_usb_gate_clk : 1; /* [ 19], r/w, 0x0 */ + uint32_t reserved_20_31 : 12; /* [31:20], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } PDS_CTL2; + + /* 0x14 : PDS_CTL3 */ + union { + struct { + uint32_t reserved_0 : 1; /* [ 0], rsvd, 0x0 */ + uint32_t cr_pds_force_misc_pwr_off : 1; /* [ 1], r/w, 0x0 */ + uint32_t reserved_2_3 : 2; /* [ 3: 2], rsvd, 0x0 */ + uint32_t cr_pds_force_misc_iso_en : 1; /* [ 4], r/w, 0x0 */ + uint32_t reserved_5_6 : 2; /* [ 6: 5], rsvd, 0x0 */ + uint32_t cr_pds_force_misc_pds_rst : 1; /* [ 7], r/w, 0x0 */ + uint32_t reserved_8_9 : 2; /* [ 9: 8], rsvd, 0x0 */ + uint32_t cr_pds_force_misc_mem_stby : 1; /* [ 10], r/w, 0x0 */ + uint32_t reserved_11_12 : 2; /* [12:11], rsvd, 0x0 */ + uint32_t cr_pds_force_misc_gate_clk : 1; /* [ 13], r/w, 0x0 */ + uint32_t reserved_14_25 : 12; /* [25:14], rsvd, 0x0 */ + uint32_t cr_pds_mm_iso_en : 1; /* [ 26], r/w, 0x1 */ + uint32_t reserved_27_28 : 2; /* [28:27], rsvd, 0x0 */ + uint32_t cr_pds_usb_iso_en : 1; /* [ 29], r/w, 0x1 */ + uint32_t cr_pds_misc_iso_en : 1; /* [ 30], r/w, 0x1 */ + uint32_t reserved_31 : 1; /* [ 31], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } PDS_CTL3; + + /* 0x18 : PDS_CTL4 */ + union { + struct { + uint32_t reserved_0 : 1; /* [ 0], rsvd, 0x0 */ + uint32_t cr_pds_np_reset : 1; /* [ 1], r/w, 0x1 */ + uint32_t cr_pds_np_mem_stby : 1; /* [ 2], r/w, 0x1 */ + uint32_t cr_pds_np_gate_clk : 1; /* [ 3], r/w, 0x1 */ + uint32_t reserved_4_7 : 4; /* [ 7: 4], rsvd, 0x0 */ + uint32_t cr_pds_mm_pwr_off : 1; /* [ 8], r/w, 0x1 */ + uint32_t cr_pds_mm_reset : 1; /* [ 9], r/w, 0x1 */ + uint32_t cr_pds_mm_mem_stby : 1; /* [ 10], r/w, 0x1 */ + uint32_t cr_pds_mm_gate_clk : 1; /* [ 11], r/w, 0x1 */ + uint32_t reserved_12 : 1; /* [ 12], rsvd, 0x0 */ + uint32_t cr_pds_wb_reset : 1; /* [ 13], r/w, 0x1 */ + uint32_t cr_pds_wb_mem_stby : 1; /* [ 14], r/w, 0x1 */ + uint32_t cr_pds_wb_gate_clk : 1; /* [ 15], r/w, 0x1 */ + uint32_t reserved_16_19 : 4; /* [19:16], rsvd, 0x0 */ + uint32_t cr_pds_usb_pwr_off : 1; /* [ 20], r/w, 0x1 */ + uint32_t cr_pds_usb_reset : 1; /* [ 21], r/w, 0x1 */ + uint32_t cr_pds_usb_mem_stby : 1; /* [ 22], r/w, 0x1 */ + uint32_t cr_pds_usb_gate_clk : 1; /* [ 23], r/w, 0x1 */ + uint32_t cr_pds_misc_pwr_off : 1; /* [ 24], r/w, 0x1 */ + uint32_t cr_pds_misc_reset : 1; /* [ 25], r/w, 0x1 */ + uint32_t cr_pds_misc_mem_stby : 1; /* [ 26], r/w, 0x1 */ + uint32_t cr_pds_misc_gate_clk : 1; /* [ 27], r/w, 0x1 */ + uint32_t reserved_28_31 : 4; /* [31:28], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } PDS_CTL4; + + /* 0x1C : pds_stat */ + union { + struct { + uint32_t ro_pds_state : 5; /* [ 4: 0], r, 0x0 */ + uint32_t reserved_5_7 : 3; /* [ 7: 5], rsvd, 0x0 */ + uint32_t ro_pds_rf_state : 5; /* [12: 8], r, 0x0 */ + uint32_t reserved_13_23 : 11; /* [23:13], rsvd, 0x0 */ + uint32_t pds_reset_event : 3; /* [26:24], r, 0x0 */ + uint32_t reserved_27_30 : 4; /* [30:27], rsvd, 0x0 */ + uint32_t pds_clr_reset_event : 1; /* [ 31], w1c, 0x0 */ + } BF; + uint32_t WORD; + } pds_stat; + + /* 0x20 : pds_ram1 */ + union { + struct { + uint32_t cr_ocram_slp : 4; /* [ 3: 0], r/w, 0x0 */ + uint32_t cr_ocram_ret : 4; /* [ 7: 4], r/w, 0x0 */ + uint32_t cr_pds_ram_clk_cnt : 6; /* [13: 8], r/w, 0x8 */ + uint32_t reserved_14_15 : 2; /* [15:14], rsvd, 0x0 */ + uint32_t cr_pds_ram_clk2_cnt : 6; /* [21:16], r/w, 0x18 */ + uint32_t reserved_22_23 : 2; /* [23:22], rsvd, 0x0 */ + uint32_t cr_pds_ctrl_np_ram_clk : 1; /* [ 24], r/w, 0x0 */ + uint32_t cr_pds_ctrl_mm_ram_clk : 1; /* [ 25], r/w, 0x0 */ + uint32_t cr_pds_ctrl_wb_ram_clk : 1; /* [ 26], r/w, 0x0 */ + uint32_t cr_pds_ctrl_usb_ram_clk : 1; /* [ 27], r/w, 0x0 */ + uint32_t cr_pds_ctrl_misc_ram_clk : 1; /* [ 28], r/w, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t cr_pds_ctrl_ram_clk2 : 1; /* [ 30], r/w, 0x0 */ + uint32_t cr_pds_ctrl_ram_clk : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } pds_ram1; + + /* 0x24 : PDS_CTL5 */ + union { + struct { + uint32_t cr_np_wfi_mask : 1; /* [ 0], r/w, 0x0 */ + uint32_t reserved_1 : 1; /* [ 1], rsvd, 0x0 */ + uint32_t cr_mm_wfi_mask : 1; /* [ 2], r/w, 0x0 */ + uint32_t reserved_3 : 1; /* [ 3], rsvd, 0x0 */ + uint32_t cr_pico_wfi_mask : 1; /* [ 4], r/w, 0x0 */ + uint32_t reserved_5_7 : 3; /* [ 7: 5], rsvd, 0x0 */ + uint32_t cr_pds_ctrl_usb33 : 1; /* [ 8], r/w, 0x0 */ + uint32_t cr_pds_pd_ldo18io : 1; /* [ 9], r/w, 0x0 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t cr_pds_gpio_keep_en : 3; /* [18:16], r/w, 0x7 */ + uint32_t reserved_19_31 : 13; /* [31:19], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } PDS_CTL5; + + /* 0x28 : PDS_RAM2 */ + union { + struct { + uint32_t cr_wram_slp : 10; /* [ 9: 0], r/w, 0x0 */ + uint32_t cr_wram_ret : 10; /* [19:10], r/w, 0x0 */ + uint32_t reserved_20_31 : 12; /* [31:20], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } PDS_RAM2; + + /* 0x2c reserved */ + uint8_t RESERVED0x2c[4]; + + /* 0x30 : pds_gpio_i_set */ + union { + struct { + uint32_t cr_pds_gpio_ie_set : 3; /* [ 2: 0], r/w, 0x0 */ + uint32_t cr_pds_gpio_pd_set : 3; /* [ 5: 3], r/w, 0x0 */ + uint32_t cr_pds_gpio_pu_set : 3; /* [ 8: 6], r/w, 0x0 */ + uint32_t reserved_9_31 : 23; /* [31: 9], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } pds_gpio_i_set; + + /* 0x34 : pds_gpio_pd_set */ + union { + struct { + uint32_t cr_pds_gpio_set_int_mask : 32; /* [31: 0], r/w, 0xffffffff */ + } BF; + uint32_t WORD; + } pds_gpio_pd_set; + + /* 0x38 reserved */ + uint8_t RESERVED0x38[8]; + + /* 0x40 : pds_gpio_int */ + union { + struct { + uint32_t reserved_0_1 : 2; /* [ 1: 0], rsvd, 0x0 */ + uint32_t pds_gpio_set1_int_clr : 1; /* [ 2], r/w, 0x0 */ + uint32_t reserved_3 : 1; /* [ 3], rsvd, 0x0 */ + uint32_t pds_gpio_set1_int_mode : 4; /* [ 7: 4], r/w, 0x0 */ + uint32_t reserved_8_9 : 2; /* [ 9: 8], rsvd, 0x0 */ + uint32_t pds_gpio_set2_int_clr : 1; /* [ 10], r/w, 0x0 */ + uint32_t reserved_11 : 1; /* [ 11], rsvd, 0x0 */ + uint32_t pds_gpio_set2_int_mode : 4; /* [15:12], r/w, 0x0 */ + uint32_t reserved_16_17 : 2; /* [17:16], rsvd, 0x0 */ + uint32_t pds_gpio_set3_int_clr : 1; /* [ 18], r/w, 0x0 */ + uint32_t reserved_19 : 1; /* [ 19], rsvd, 0x0 */ + uint32_t pds_gpio_set3_int_mode : 4; /* [23:20], r/w, 0x0 */ + uint32_t reserved_24_25 : 2; /* [25:24], rsvd, 0x0 */ + uint32_t pds_gpio_set4_int_clr : 1; /* [ 26], r/w, 0x0 */ + uint32_t reserved_27 : 1; /* [ 27], rsvd, 0x0 */ + uint32_t pds_gpio_set4_int_mode : 4; /* [31:28], r/w, 0x0 */ + } BF; + uint32_t WORD; + } pds_gpio_int; + + /* 0x44 : pds_gpio_stat */ + union { + struct { + uint32_t pds_gpio_int_stat : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } pds_gpio_stat; + + /* 0x48 reserved */ + uint8_t RESERVED0x48[200]; + + /* 0x110 : cpu_core_cfg0 */ + union { + struct { + uint32_t reserved_0_27 : 28; /* [27: 0], rsvd, 0x0 */ + uint32_t reg_pico_clk_en : 1; /* [ 28], r/w, 0x0 */ + uint32_t e902_dfs_req : 1; /* [ 29], r/w, 0x0 */ + uint32_t e902_dfs_ack : 1; /* [ 30], r, 0x0 */ + uint32_t reserved_31 : 1; /* [ 31], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } cpu_core_cfg0; + + /* 0x114 : cpu_core_cfg1 */ + union { + struct { + uint32_t reserved_0_3 : 4; /* [ 3: 0], rsvd, 0x0 */ + uint32_t reg_pll_sel : 2; /* [ 5: 4], r/w, 0x3 */ + uint32_t reserved_6_7 : 2; /* [ 7: 6], rsvd, 0x0 */ + uint32_t reg_mcu1_clk_en : 1; /* [ 8], r/w, 0x1 */ + uint32_t reserved_9_31 : 23; /* [31: 9], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } cpu_core_cfg1; + + /* 0x118 reserved */ + uint8_t RESERVED0x118[20]; + + /* 0x12C : cpu_core_cfg7 */ + union { + struct { + uint32_t reg_pico_div : 8; /* [ 7: 0], r/w, 0x1 */ + uint32_t reserved_8_27 : 20; /* [27: 8], rsvd, 0x0 */ + uint32_t e902_lpmd_b : 2; /* [29:28], r, 0x0 */ + uint32_t reserved_30 : 1; /* [ 30], rsvd, 0x0 */ + uint32_t pico_rst_mask : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } cpu_core_cfg7; + + /* 0x130 : cpu_core_cfg8 */ + union { + struct { + uint32_t e902_rtc_div : 10; /* [ 9: 0], r/w, 0xa */ + uint32_t reserved_10_29 : 20; /* [29:10], rsvd, 0x0 */ + uint32_t e902_rtc_rst : 1; /* [ 30], r/w, 0x0 */ + uint32_t e902_rtc_en : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } cpu_core_cfg8; + + /* 0x134 : cpu_core_cfg9 */ + union { + struct { + uint32_t pico_rtc_cnt_l : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } cpu_core_cfg9; + + /* 0x138 : cpu_core_cfg10 */ + union { + struct { + uint32_t pico_rtc_cnt_h : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } cpu_core_cfg10; + + /* 0x13c reserved */ + uint8_t RESERVED0x13c[4]; + + /* 0x140 : cpu_core_cfg12 */ + union { + struct { + uint32_t e902_iahbl_base : 12; /* [11: 0], r/w, 0x0 */ + uint32_t reserved_12_15 : 4; /* [15:12], rsvd, 0x0 */ + uint32_t e902_iahbl_mask : 12; /* [27:16], r/w, 0x0 */ + uint32_t reserved_28_31 : 4; /* [31:28], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } cpu_core_cfg12; + + /* 0x144 : cpu_core_cfg13 */ + union { + struct { + uint32_t e902_rst_addr : 32; /* [31: 0], r/w, 0x22010000 */ + } BF; + uint32_t WORD; + } cpu_core_cfg13; + + /* 0x148 : cpu_core_cfg14 */ + union { + struct { + uint32_t e906_rst_addr : 32; /* [31: 0], r/w, 0x90000000 */ + } BF; + uint32_t WORD; + } cpu_core_cfg14; + + /* 0x14C : tzc_pds */ + union { + struct { + uint32_t cr_e902_cfg_wr_lock : 1; /* [ 0], r/w, 0x0 */ + uint32_t cr_e906_cfg_wr_lock : 1; /* [ 1], r/w, 0x0 */ + uint32_t reserved_2_31 : 30; /* [31: 2], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } tzc_pds; + + /* 0x150 reserved */ + uint8_t RESERVED0x150[432]; + + /* 0x300 : rc32m_ctrl0 */ + union { + struct { + uint32_t rc32m_cal_done : 1; /* [ 0], r, 0x0 */ + uint32_t rc32m_rdy : 1; /* [ 1], r, 0x0 */ + uint32_t rc32m_cal_inprogress : 1; /* [ 2], r, 0x0 */ + uint32_t rc32m_cal_div : 2; /* [ 4: 3], r/w, 0x3 */ + uint32_t rc32m_cal_precharge : 1; /* [ 5], r, 0x0 */ + uint32_t rc32m_dig_code_fr_cal : 8; /* [13: 6], r, 0x0 */ + uint32_t reserved_14_16 : 3; /* [16:14], rsvd, 0x0 */ + uint32_t rc32m_allow_cal : 1; /* [ 17], r/w, 0x0 */ + uint32_t rc32m_refclk_half : 1; /* [ 18], r/w, 0x0 */ + uint32_t rc32m_ext_code_en : 1; /* [ 19], r/w, 0x1 */ + uint32_t rc32m_cal_en : 1; /* [ 20], r/w, 0x0 */ + uint32_t rc32m_pd : 1; /* [ 21], r/w, 0x0 */ + uint32_t rc32m_code_fr_ext : 8; /* [29:22], r/w, 0x60 */ + uint32_t reserved_30_31 : 2; /* [31:30], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } rc32m_ctrl0; + + /* 0x304 : rc32m_ctrl1 */ + union { + struct { + uint32_t rc32m_test_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t rc32m_soft_rst : 1; /* [ 1], r/w, 0x0 */ + uint32_t rc32m_clk_soft_rst : 1; /* [ 2], r/w, 0x0 */ + uint32_t rc32m_clk_inv : 1; /* [ 3], r/w, 0x0 */ + uint32_t rc32m_clk_force_on : 1; /* [ 4], r/w, 0x0 */ + uint32_t reserved_5_23 : 19; /* [23: 5], rsvd, 0x0 */ + uint32_t rc32m_reserved : 8; /* [31:24], r/w, 0xf */ + } BF; + uint32_t WORD; + } rc32m_ctrl1; + + /* 0x308 reserved */ + uint8_t RESERVED0x308[248]; + + /* 0x400 : pu_rst_clkpll */ + union { + struct { + uint32_t reserved_0_8 : 9; /* [ 8: 0], rsvd, 0x0 */ + uint32_t cr_pds_pu_clkpll_sfreg : 1; /* [ 9], r/w, 0x0 */ + uint32_t cr_pds_pu_clkpll : 1; /* [ 10], r/w, 0x0 */ + uint32_t reserved_11_31 : 21; /* [31:11], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } pu_rst_clkpll; + + /* 0x404 reserved */ + uint8_t RESERVED0x404[252]; + + /* 0x500 : usb_ctl */ + union { + struct { + uint32_t reg_usb_sw_rst_n : 1; /* [ 0], r/w, 0x1 */ + uint32_t reg_usb_ext_susp_n : 1; /* [ 1], r/w, 0x0 */ + uint32_t reg_usb_wakeup : 1; /* [ 2], r/w, 0x0 */ + uint32_t reg_usb_l1_wakeup : 1; /* [ 3], r/w, 0x0 */ + uint32_t reg_usb_drvbus_pol : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_usb_iddig : 1; /* [ 5], r/w, 0x1 */ + uint32_t reserved_6_31 : 26; /* [31: 6], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } usb_ctl; + + /* 0x504 : usb_phy_ctrl */ + union { + struct { + uint32_t reg_usb_phy_ponrst : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_usb_phy_oscouten : 1; /* [ 1], r/w, 0x0 */ + uint32_t reg_usb_phy_xtlsel : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reg_usb_phy_outclksel : 1; /* [ 4], r/w, 0x0 */ + uint32_t reg_usb_phy_pllaliv : 1; /* [ 5], r/w, 0x0 */ + uint32_t reg_pu_usb20_psw : 1; /* [ 6], r/w, 0x0 */ + uint32_t reserved_7_31 : 25; /* [31: 7], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } usb_phy_ctrl; + + /* 0x508 reserved */ + uint8_t RESERVED0x508[1272]; + + /* 0xA00 : touch channel, clock, ana config1 */ + union { + struct { + uint32_t touch_vref_sel : 3; /* [ 2: 0], r/w, 0x3 */ + uint32_t touch_vldo_sel : 3; /* [ 5: 3], r/w, 0x3 */ + uint32_t touch_comp_hys_sel : 1; /* [ 6], r/w, 0x0 */ + uint32_t touch_current_sel : 1; /* [ 7], r/w, 0x0 */ + uint32_t reserved_8_15 : 8; /* [15: 8], rsvd, 0x0 */ + uint32_t touch_clk_sel : 1; /* [ 16], r/w, 0x1 */ + uint32_t touch_clk_div_ratio : 3; /* [19:17], r/w, 0x1 */ + uint32_t touch_pcharge_high : 3; /* [22:20], r/w, 0x2 */ + uint32_t touch_pcharge_low : 3; /* [25:23], r/w, 0x1 */ + uint32_t touch_cont_en : 1; /* [ 26], r/w, 0x0 */ + uint32_t touch_cycle_en : 1; /* [ 27], r/w, 0x0 */ + uint32_t touch_ulp_en : 1; /* [ 28], r/w, 0x0 */ + uint32_t reserved_29 : 1; /* [ 29], rsvd, 0x0 */ + uint32_t pu_touch : 1; /* [ 30], r/w, 0x0 */ + uint32_t reserved_31 : 1; /* [ 31], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } touch1; + + /* 0xA04 : touch channel, clock, ana config2 */ + union { + struct { + uint32_t touch_channel_sel : 4; /* [ 3: 0], r/w, 0x0 */ + uint32_t touch_channel0_highz_en : 1; /* [ 4], r/w, 0x1 */ + uint32_t touch_channel1_highz_en : 1; /* [ 5], r/w, 0x1 */ + uint32_t touch_channel2_highz_en : 1; /* [ 6], r/w, 0x1 */ + uint32_t touch_channel3_highz_en : 1; /* [ 7], r/w, 0x1 */ + uint32_t touch_channel4_highz_en : 1; /* [ 8], r/w, 0x1 */ + uint32_t touch_channel5_highz_en : 1; /* [ 9], r/w, 0x1 */ + uint32_t touch_channel6_highz_en : 1; /* [ 10], r/w, 0x1 */ + uint32_t touch_channel7_highz_en : 1; /* [ 11], r/w, 0x1 */ + uint32_t touch_channel8_highz_en : 1; /* [ 12], r/w, 0x1 */ + uint32_t touch_channel9_highz_en : 1; /* [ 13], r/w, 0x1 */ + uint32_t touch_channel10_highz_en : 1; /* [ 14], r/w, 0x1 */ + uint32_t touch_channel11_highz_en : 1; /* [ 15], r/w, 0x1 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } touch2; + + /* 0xA08 : touch data process */ + union { + struct { + uint32_t touch_channel_cal_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t touch_force_value_en : 1; /* [ 1], r/w, 0x0 */ + uint32_t touch_data_hys_en : 1; /* [ 2], r/w, 0x0 */ + uint32_t reserved_3 : 1; /* [ 3], rsvd, 0x0 */ + uint32_t touch_lta_en : 1; /* [ 4], r/w, 0x0 */ + uint32_t touch_lta_order : 3; /* [ 7: 5], r/w, 0x3 */ + uint32_t touch_flt_en : 1; /* [ 8], r/w, 0x0 */ + uint32_t touch_flt_order : 3; /* [11: 9], r/w, 0x3 */ + uint32_t touch_self_mutual_sel : 1; /* [ 12], r/w, 0x0 */ + uint32_t touch_vldo_ccsel : 2; /* [14:13], r/w, 0x0 */ + uint32_t reserved_15_17 : 3; /* [17:15], rsvd, 0x0 */ + uint32_t ten_touch : 1; /* [ 18], r/w, 0x0 */ + uint32_t reserved_19_31 : 13; /* [31:19], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } touch3; + + /* 0xA0C : Touch_sleep_time */ + union { + struct { + uint32_t touch_sleep_cycle : 23; /* [22: 0], r/w, 0x7ffff */ + uint32_t reserved_23_31 : 9; /* [31:23], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Touch_sleep_time; + + /* 0xA10 : touch_data_hystersis */ + union { + struct { + uint32_t touch_data_hys : 9; /* [ 8: 0], r/w, 0x0 */ + uint32_t reserved_9_31 : 23; /* [31: 9], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } touch_data_hystersis; + + /* 0xA14 : Channel_force_data_0 */ + union { + struct { + uint32_t touch_force_data_ch0 : 16; /* [15: 0], r/w, 0x400 */ + uint32_t touch_force_data_ch1 : 16; /* [31:16], r/w, 0x400 */ + } BF; + uint32_t WORD; + } Channel_force_data_0; + + /* 0xA18 : Channel_force_data_1 */ + union { + struct { + uint32_t touch_force_data_ch2 : 16; /* [15: 0], r/w, 0x400 */ + uint32_t touch_force_data_ch3 : 16; /* [31:16], r/w, 0x400 */ + } BF; + uint32_t WORD; + } Channel_force_data_1; + + /* 0xA1C : Channel_force_data_2 */ + union { + struct { + uint32_t touch_force_data_ch4 : 16; /* [15: 0], r/w, 0x400 */ + uint32_t touch_force_data_ch5 : 16; /* [31:16], r/w, 0x400 */ + } BF; + uint32_t WORD; + } Channel_force_data_2; + + /* 0xA20 : Channel_force_data_3 */ + union { + struct { + uint32_t touch_force_data_ch6 : 16; /* [15: 0], r/w, 0x400 */ + uint32_t touch_force_data_ch7 : 16; /* [31:16], r/w, 0x400 */ + } BF; + uint32_t WORD; + } Channel_force_data_3; + + /* 0xA24 : Channel_force_data_4 */ + union { + struct { + uint32_t touch_force_data_ch8 : 16; /* [15: 0], r/w, 0x400 */ + uint32_t touch_force_data_ch9 : 16; /* [31:16], r/w, 0x400 */ + } BF; + uint32_t WORD; + } Channel_force_data_4; + + /* 0xA28 : Channel_force_data_5 */ + union { + struct { + uint32_t touch_force_data_ch10 : 16; /* [15: 0], r/w, 0x400 */ + uint32_t touch_force_data_ch11 : 16; /* [31:16], r/w, 0x400 */ + } BF; + uint32_t WORD; + } Channel_force_data_5; + + /* 0xA2C : Channel_vth_data_0 */ + union { + struct { + uint32_t touch_vth_data_ch0 : 8; /* [ 7: 0], r/w, 0x3f */ + uint32_t touch_vth_data_ch1 : 8; /* [15: 8], r/w, 0x3f */ + uint32_t touch_vth_data_ch2 : 8; /* [23:16], r/w, 0x3f */ + uint32_t touch_vth_data_ch3 : 8; /* [31:24], r/w, 0x3f */ + } BF; + uint32_t WORD; + } Channel_vth_data_0; + + /* 0xA30 : Channel_vth_data_1 */ + union { + struct { + uint32_t touch_vth_data_ch4 : 8; /* [ 7: 0], r/w, 0x1f */ + uint32_t touch_vth_data_ch5 : 8; /* [15: 8], r/w, 0x1f */ + uint32_t touch_vth_data_ch6 : 8; /* [23:16], r/w, 0x1f */ + uint32_t touch_vth_data_ch7 : 8; /* [31:24], r/w, 0x3f */ + } BF; + uint32_t WORD; + } Channel_vth_data_1; + + /* 0xA34 : Channel_vth_data_2 */ + union { + struct { + uint32_t touch_vth_data_ch8 : 8; /* [ 7: 0], r/w, 0x3f */ + uint32_t touch_vth_data_ch9 : 8; /* [15: 8], r/w, 0x3f */ + uint32_t touch_vth_data_ch10 : 8; /* [23:16], r/w, 0x3f */ + uint32_t touch_vth_data_ch11 : 8; /* [31:24], r/w, 0x3f */ + } BF; + uint32_t WORD; + } Channel_vth_data_2; + + /* 0xA38 : Channel_raw_data_0 */ + union { + struct { + uint32_t touch_raw_data_ch0 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_raw_data_0; + + /* 0xA3C : Channel_raw_data_1 */ + union { + struct { + uint32_t touch_raw_data_ch1 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_raw_data_1; + + /* 0xA40 : Channel_raw_data_2 */ + union { + struct { + uint32_t touch_raw_data_ch2 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_raw_data_2; + + /* 0xA44 : Channel_raw_data_3 */ + union { + struct { + uint32_t touch_raw_data_ch3 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_raw_data_3; + + /* 0xA48 : Channel_raw_data_4 */ + union { + struct { + uint32_t touch_raw_data_ch4 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_raw_data_4; + + /* 0xA4C : Channel_raw_data_5 */ + union { + struct { + uint32_t touch_raw_data_ch5 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_raw_data_5; + + /* 0xA50 : Channel_raw_data_6 */ + union { + struct { + uint32_t touch_raw_data_ch6 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_raw_data_6; + + /* 0xA54 : Channel_raw_data_7 */ + union { + struct { + uint32_t touch_raw_data_ch7 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_raw_data_7; + + /* 0xA58 : Channel_raw_data_8 */ + union { + struct { + uint32_t touch_raw_data_ch8 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_raw_data_8; + + /* 0xA5C : Channel_raw_data_9 */ + union { + struct { + uint32_t touch_raw_data_ch9 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_raw_data_9; + + /* 0xA60 : Channel_raw_data_10 */ + union { + struct { + uint32_t touch_raw_data_ch10 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_raw_data_10; + + /* 0xA64 : Channel_raw_data_11 */ + union { + struct { + uint32_t touch_raw_data_ch11 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_raw_data_11; + + /* 0xA68 : Channel_LTA_data_0 */ + union { + struct { + uint32_t touch_lta_data_ch0 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_LTA_data_0; + + /* 0xA6C : Channel_LTA_data_1 */ + union { + struct { + uint32_t touch_lta_data_ch1 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_LTA_data_1; + + /* 0xA70 : Channel_LTA_data_2 */ + union { + struct { + uint32_t touch_lta_data_ch2 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_LTA_data_2; + + /* 0xA74 : Channel_LTA_data_3 */ + union { + struct { + uint32_t touch_lta_data_ch3 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_LTA_data_3; + + /* 0xA78 : Channel_LTA_data_4 */ + union { + struct { + uint32_t touch_lta_data_ch4 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_LTA_data_4; + + /* 0xA7C : Channel_LTA_data_5 */ + union { + struct { + uint32_t touch_lta_data_ch5 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_LTA_data_5; + + /* 0xA80 : Channel_LTA_data_6 */ + union { + struct { + uint32_t touch_lta_data_ch6 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_LTA_data_6; + + /* 0xA84 : Channel_LTA_data_7 */ + union { + struct { + uint32_t touch_lta_data_ch7 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_LTA_data_7; + + /* 0xA88 : Channel_LTA_data_8 */ + union { + struct { + uint32_t touch_lta_data_ch8 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_LTA_data_8; + + /* 0xA8C : Channel_LTA_data_9 */ + union { + struct { + uint32_t touch_lta_data_ch9 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_LTA_data_9; + + /* 0xA90 : Channel_LTA_data_10 */ + union { + struct { + uint32_t touch_lta_data_ch10 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_LTA_data_10; + + /* 0xA94 : Channel_LTA_data_11 */ + union { + struct { + uint32_t touch_lta_data_ch11 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_LTA_data_11; + + /* 0xA98 : Channel_FLT_data_0 */ + union { + struct { + uint32_t touch_flt_data_ch0 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_FLT_data_0; + + /* 0xA9C : Channel_FLT_data_1 */ + union { + struct { + uint32_t touch_flt_data_ch1 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_FLT_data_1; + + /* 0xAA0 : Channel_FLT_data_2 */ + union { + struct { + uint32_t touch_flt_data_ch2 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_FLT_data_2; + + /* 0xAA4 : Channel_FLT_data_3 */ + union { + struct { + uint32_t touch_flt_data_ch3 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_FLT_data_3; + + /* 0xAA8 : Channel_FLT_data_4 */ + union { + struct { + uint32_t touch_flt_data_ch4 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_FLT_data_4; + + /* 0xAAC : Channel_FLT_data_5 */ + union { + struct { + uint32_t touch_flt_data_ch5 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_FLT_data_5; + + /* 0xAB0 : Channel_FLT_data_6 */ + union { + struct { + uint32_t touch_flt_data_ch6 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_FLT_data_6; + + /* 0xAB4 : Channel_FLT_data_7 */ + union { + struct { + uint32_t touch_flt_data_ch7 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_FLT_data_7; + + /* 0xAB8 : Channel_FLT_data_8 */ + union { + struct { + uint32_t touch_flt_data_ch8 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_FLT_data_8; + + /* 0xABC : Channel_FLT_data_9 */ + union { + struct { + uint32_t touch_flt_data_ch9 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_FLT_data_9; + + /* 0xAC0 : Channel_FLT_data_10 */ + union { + struct { + uint32_t touch_flt_data_ch10 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_FLT_data_10; + + /* 0xAC4 : Channel_FLT_data_11 */ + union { + struct { + uint32_t touch_flt_data_ch11 : 16; /* [15: 0], R, 0x0 */ + uint32_t reserved_16_31 : 16; /* [31:16], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } Channel_FLT_data_11; + + /* 0xAC8 : touch_rsvd */ + union { + struct { + uint32_t touch_reserved : 8; /* [ 7: 0], r/w, 0x0 */ + uint32_t reserved_8_31 : 24; /* [31: 8], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } touch_rsvd; + + /* 0xACC : touch_int_setting */ + union { + struct { + uint32_t touch_int_clr : 12; /* [11: 0], r/w, 0x0 */ + uint32_t reserved_12_15 : 4; /* [15:12], rsvd, 0x0 */ + uint32_t touch_int_mask : 12; /* [27:16], r/w, 0x0 */ + uint32_t reserved_28_30 : 3; /* [30:28], rsvd, 0x0 */ + uint32_t touch_int_en : 1; /* [ 31], r/w, 0x1 */ + } BF; + uint32_t WORD; + } touch_int_setting; + + /* 0xAD0 : touch_int_status */ + union { + struct { + uint32_t touch_int_status : 12; /* [11: 0], R, 0x0 */ + uint32_t touch_end_flag : 1; /* [ 12], R, 0x0 */ + uint32_t reserved_13_31 : 19; /* [31:13], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } touch_int_status; +}; + +typedef volatile struct pds_reg pds_reg_t; + +#endif /* __PDS_REG_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/psram_uhs_reg.h b/platforms/bl808_m0/vendor/psram/include/psram_uhs_reg.h new file mode 100644 index 0000000..622e41f --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/psram_uhs_reg.h @@ -0,0 +1,1568 @@ +/** + ****************************************************************************** + * @file psram_uhs_reg.h + * @version V1.0 + * @date 2021-07-13 + * @brief This file is the description of.IP register + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __PSRAM_UHS_REG_H__ +#define __PSRAM_UHS_REG_H__ + +#include "bl808.h" + +/* 0x0 : UHS_basic */ +#define PSRAM_UHS_UHS_BASIC_OFFSET (0x0) +#define PSRAM_UHS_REG_INIT_EN PSRAM_UHS_REG_INIT_EN +#define PSRAM_UHS_REG_INIT_EN_POS (0U) +#define PSRAM_UHS_REG_INIT_EN_LEN (1U) +#define PSRAM_UHS_REG_INIT_EN_MSK (((1U << PSRAM_UHS_REG_INIT_EN_LEN) - 1) << PSRAM_UHS_REG_INIT_EN_POS) +#define PSRAM_UHS_REG_INIT_EN_UMSK (~(((1U << PSRAM_UHS_REG_INIT_EN_LEN) - 1) << PSRAM_UHS_REG_INIT_EN_POS)) +#define PSRAM_UHS_REG_AF_EN PSRAM_UHS_REG_AF_EN +#define PSRAM_UHS_REG_AF_EN_POS (1U) +#define PSRAM_UHS_REG_AF_EN_LEN (1U) +#define PSRAM_UHS_REG_AF_EN_MSK (((1U << PSRAM_UHS_REG_AF_EN_LEN) - 1) << PSRAM_UHS_REG_AF_EN_POS) +#define PSRAM_UHS_REG_AF_EN_UMSK (~(((1U << PSRAM_UHS_REG_AF_EN_LEN) - 1) << PSRAM_UHS_REG_AF_EN_POS)) +#define PSRAM_UHS_REG_CONFIG_REQ PSRAM_UHS_REG_CONFIG_REQ +#define PSRAM_UHS_REG_CONFIG_REQ_POS (2U) +#define PSRAM_UHS_REG_CONFIG_REQ_LEN (1U) +#define PSRAM_UHS_REG_CONFIG_REQ_MSK (((1U << PSRAM_UHS_REG_CONFIG_REQ_LEN) - 1) << PSRAM_UHS_REG_CONFIG_REQ_POS) +#define PSRAM_UHS_REG_CONFIG_REQ_UMSK (~(((1U << PSRAM_UHS_REG_CONFIG_REQ_LEN) - 1) << PSRAM_UHS_REG_CONFIG_REQ_POS)) +#define PSRAM_UHS_REG_CONFIG_GNT PSRAM_UHS_REG_CONFIG_GNT +#define PSRAM_UHS_REG_CONFIG_GNT_POS (3U) +#define PSRAM_UHS_REG_CONFIG_GNT_LEN (1U) +#define PSRAM_UHS_REG_CONFIG_GNT_MSK (((1U << PSRAM_UHS_REG_CONFIG_GNT_LEN) - 1) << PSRAM_UHS_REG_CONFIG_GNT_POS) +#define PSRAM_UHS_REG_CONFIG_GNT_UMSK (~(((1U << PSRAM_UHS_REG_CONFIG_GNT_LEN) - 1) << PSRAM_UHS_REG_CONFIG_GNT_POS)) +#define PSRAM_UHS_REG_MODE_REG PSRAM_UHS_REG_MODE_REG +#define PSRAM_UHS_REG_MODE_REG_POS (8U) +#define PSRAM_UHS_REG_MODE_REG_LEN (8U) +#define PSRAM_UHS_REG_MODE_REG_MSK (((1U << PSRAM_UHS_REG_MODE_REG_LEN) - 1) << PSRAM_UHS_REG_MODE_REG_POS) +#define PSRAM_UHS_REG_MODE_REG_UMSK (~(((1U << PSRAM_UHS_REG_MODE_REG_LEN) - 1) << PSRAM_UHS_REG_MODE_REG_POS)) +#define PSRAM_UHS_REG_ADDRMB_MSK PSRAM_UHS_REG_ADDRMB_MSK +#define PSRAM_UHS_REG_ADDRMB_MSK_POS (16U) +#define PSRAM_UHS_REG_ADDRMB_MSK_LEN (8U) +#define PSRAM_UHS_REG_ADDRMB_MSK_MSK (((1U << PSRAM_UHS_REG_ADDRMB_MSK_LEN) - 1) << PSRAM_UHS_REG_ADDRMB_MSK_POS) +#define PSRAM_UHS_REG_ADDRMB_MSK_UMSK (~(((1U << PSRAM_UHS_REG_ADDRMB_MSK_LEN) - 1) << PSRAM_UHS_REG_ADDRMB_MSK_POS)) +#define PSRAM_UHS_REG_LINEAR_BND_B PSRAM_UHS_REG_LINEAR_BND_B +#define PSRAM_UHS_REG_LINEAR_BND_B_POS (28U) +#define PSRAM_UHS_REG_LINEAR_BND_B_LEN (4U) +#define PSRAM_UHS_REG_LINEAR_BND_B_MSK (((1U << PSRAM_UHS_REG_LINEAR_BND_B_LEN) - 1) << PSRAM_UHS_REG_LINEAR_BND_B_POS) +#define PSRAM_UHS_REG_LINEAR_BND_B_UMSK (~(((1U << PSRAM_UHS_REG_LINEAR_BND_B_LEN) - 1) << PSRAM_UHS_REG_LINEAR_BND_B_POS)) + +/* 0x4 : UHS_cmd */ +#define PSRAM_UHS_UHS_CMD_OFFSET (0x4) +#define PSRAM_UHS_REG_GLBR_PULSE PSRAM_UHS_REG_GLBR_PULSE +#define PSRAM_UHS_REG_GLBR_PULSE_POS (0U) +#define PSRAM_UHS_REG_GLBR_PULSE_LEN (1U) +#define PSRAM_UHS_REG_GLBR_PULSE_MSK (((1U << PSRAM_UHS_REG_GLBR_PULSE_LEN) - 1) << PSRAM_UHS_REG_GLBR_PULSE_POS) +#define PSRAM_UHS_REG_GLBR_PULSE_UMSK (~(((1U << PSRAM_UHS_REG_GLBR_PULSE_LEN) - 1) << PSRAM_UHS_REG_GLBR_PULSE_POS)) +#define PSRAM_UHS_REG_SRFI_PULSE PSRAM_UHS_REG_SRFI_PULSE +#define PSRAM_UHS_REG_SRFI_PULSE_POS (1U) +#define PSRAM_UHS_REG_SRFI_PULSE_LEN (1U) +#define PSRAM_UHS_REG_SRFI_PULSE_MSK (((1U << PSRAM_UHS_REG_SRFI_PULSE_LEN) - 1) << PSRAM_UHS_REG_SRFI_PULSE_POS) +#define PSRAM_UHS_REG_SRFI_PULSE_UMSK (~(((1U << PSRAM_UHS_REG_SRFI_PULSE_LEN) - 1) << PSRAM_UHS_REG_SRFI_PULSE_POS)) +#define PSRAM_UHS_REG_SRFO_PULSE PSRAM_UHS_REG_SRFO_PULSE +#define PSRAM_UHS_REG_SRFO_PULSE_POS (2U) +#define PSRAM_UHS_REG_SRFO_PULSE_LEN (1U) +#define PSRAM_UHS_REG_SRFO_PULSE_MSK (((1U << PSRAM_UHS_REG_SRFO_PULSE_LEN) - 1) << PSRAM_UHS_REG_SRFO_PULSE_POS) +#define PSRAM_UHS_REG_SRFO_PULSE_UMSK (~(((1U << PSRAM_UHS_REG_SRFO_PULSE_LEN) - 1) << PSRAM_UHS_REG_SRFO_PULSE_POS)) +#define PSRAM_UHS_REG_REGW_PULSE PSRAM_UHS_REG_REGW_PULSE +#define PSRAM_UHS_REG_REGW_PULSE_POS (3U) +#define PSRAM_UHS_REG_REGW_PULSE_LEN (1U) +#define PSRAM_UHS_REG_REGW_PULSE_MSK (((1U << PSRAM_UHS_REG_REGW_PULSE_LEN) - 1) << PSRAM_UHS_REG_REGW_PULSE_POS) +#define PSRAM_UHS_REG_REGW_PULSE_UMSK (~(((1U << PSRAM_UHS_REG_REGW_PULSE_LEN) - 1) << PSRAM_UHS_REG_REGW_PULSE_POS)) +#define PSRAM_UHS_REG_REGR_PULSE PSRAM_UHS_REG_REGR_PULSE +#define PSRAM_UHS_REG_REGR_PULSE_POS (4U) +#define PSRAM_UHS_REG_REGR_PULSE_LEN (1U) +#define PSRAM_UHS_REG_REGR_PULSE_MSK (((1U << PSRAM_UHS_REG_REGR_PULSE_LEN) - 1) << PSRAM_UHS_REG_REGR_PULSE_POS) +#define PSRAM_UHS_REG_REGR_PULSE_UMSK (~(((1U << PSRAM_UHS_REG_REGR_PULSE_LEN) - 1) << PSRAM_UHS_REG_REGR_PULSE_POS)) +#define PSRAM_UHS_STS_GLBR_DONE PSRAM_UHS_STS_GLBR_DONE +#define PSRAM_UHS_STS_GLBR_DONE_POS (8U) +#define PSRAM_UHS_STS_GLBR_DONE_LEN (1U) +#define PSRAM_UHS_STS_GLBR_DONE_MSK (((1U << PSRAM_UHS_STS_GLBR_DONE_LEN) - 1) << PSRAM_UHS_STS_GLBR_DONE_POS) +#define PSRAM_UHS_STS_GLBR_DONE_UMSK (~(((1U << PSRAM_UHS_STS_GLBR_DONE_LEN) - 1) << PSRAM_UHS_STS_GLBR_DONE_POS)) +#define PSRAM_UHS_STS_SRFI_DONE PSRAM_UHS_STS_SRFI_DONE +#define PSRAM_UHS_STS_SRFI_DONE_POS (9U) +#define PSRAM_UHS_STS_SRFI_DONE_LEN (1U) +#define PSRAM_UHS_STS_SRFI_DONE_MSK (((1U << PSRAM_UHS_STS_SRFI_DONE_LEN) - 1) << PSRAM_UHS_STS_SRFI_DONE_POS) +#define PSRAM_UHS_STS_SRFI_DONE_UMSK (~(((1U << PSRAM_UHS_STS_SRFI_DONE_LEN) - 1) << PSRAM_UHS_STS_SRFI_DONE_POS)) +#define PSRAM_UHS_STS_SRFO_DONE PSRAM_UHS_STS_SRFO_DONE +#define PSRAM_UHS_STS_SRFO_DONE_POS (10U) +#define PSRAM_UHS_STS_SRFO_DONE_LEN (1U) +#define PSRAM_UHS_STS_SRFO_DONE_MSK (((1U << PSRAM_UHS_STS_SRFO_DONE_LEN) - 1) << PSRAM_UHS_STS_SRFO_DONE_POS) +#define PSRAM_UHS_STS_SRFO_DONE_UMSK (~(((1U << PSRAM_UHS_STS_SRFO_DONE_LEN) - 1) << PSRAM_UHS_STS_SRFO_DONE_POS)) +#define PSRAM_UHS_STS_REGW_DONE PSRAM_UHS_STS_REGW_DONE +#define PSRAM_UHS_STS_REGW_DONE_POS (11U) +#define PSRAM_UHS_STS_REGW_DONE_LEN (1U) +#define PSRAM_UHS_STS_REGW_DONE_MSK (((1U << PSRAM_UHS_STS_REGW_DONE_LEN) - 1) << PSRAM_UHS_STS_REGW_DONE_POS) +#define PSRAM_UHS_STS_REGW_DONE_UMSK (~(((1U << PSRAM_UHS_STS_REGW_DONE_LEN) - 1) << PSRAM_UHS_STS_REGW_DONE_POS)) +#define PSRAM_UHS_STS_REGR_DONE PSRAM_UHS_STS_REGR_DONE +#define PSRAM_UHS_STS_REGR_DONE_POS (12U) +#define PSRAM_UHS_STS_REGR_DONE_LEN (1U) +#define PSRAM_UHS_STS_REGR_DONE_MSK (((1U << PSRAM_UHS_STS_REGR_DONE_LEN) - 1) << PSRAM_UHS_STS_REGR_DONE_POS) +#define PSRAM_UHS_STS_REGR_DONE_UMSK (~(((1U << PSRAM_UHS_STS_REGR_DONE_LEN) - 1) << PSRAM_UHS_STS_REGR_DONE_POS)) +#define PSRAM_UHS_STS_INIT_DONE PSRAM_UHS_STS_INIT_DONE +#define PSRAM_UHS_STS_INIT_DONE_POS (13U) +#define PSRAM_UHS_STS_INIT_DONE_LEN (1U) +#define PSRAM_UHS_STS_INIT_DONE_MSK (((1U << PSRAM_UHS_STS_INIT_DONE_LEN) - 1) << PSRAM_UHS_STS_INIT_DONE_POS) +#define PSRAM_UHS_STS_INIT_DONE_UMSK (~(((1U << PSRAM_UHS_STS_INIT_DONE_LEN) - 1) << PSRAM_UHS_STS_INIT_DONE_POS)) +#define PSRAM_UHS_STS_CONFIG_READ PSRAM_UHS_STS_CONFIG_READ +#define PSRAM_UHS_STS_CONFIG_READ_POS (24U) +#define PSRAM_UHS_STS_CONFIG_READ_LEN (8U) +#define PSRAM_UHS_STS_CONFIG_READ_MSK (((1U << PSRAM_UHS_STS_CONFIG_READ_LEN) - 1) << PSRAM_UHS_STS_CONFIG_READ_POS) +#define PSRAM_UHS_STS_CONFIG_READ_UMSK (~(((1U << PSRAM_UHS_STS_CONFIG_READ_LEN) - 1) << PSRAM_UHS_STS_CONFIG_READ_POS)) + +/* 0x8 : UHS_fifo_thre */ +#define PSRAM_UHS_UHS_FIFO_THRE_OFFSET (0x8) +#define PSRAM_UHS_REG_MASK_W_FIFO_CNT PSRAM_UHS_REG_MASK_W_FIFO_CNT +#define PSRAM_UHS_REG_MASK_W_FIFO_CNT_POS (0U) +#define PSRAM_UHS_REG_MASK_W_FIFO_CNT_LEN (16U) +#define PSRAM_UHS_REG_MASK_W_FIFO_CNT_MSK (((1U << PSRAM_UHS_REG_MASK_W_FIFO_CNT_LEN) - 1) << PSRAM_UHS_REG_MASK_W_FIFO_CNT_POS) +#define PSRAM_UHS_REG_MASK_W_FIFO_CNT_UMSK (~(((1U << PSRAM_UHS_REG_MASK_W_FIFO_CNT_LEN) - 1) << PSRAM_UHS_REG_MASK_W_FIFO_CNT_POS)) +#define PSRAM_UHS_REG_MASK_R_FIFO_REM PSRAM_UHS_REG_MASK_R_FIFO_REM +#define PSRAM_UHS_REG_MASK_R_FIFO_REM_POS (16U) +#define PSRAM_UHS_REG_MASK_R_FIFO_REM_LEN (16U) +#define PSRAM_UHS_REG_MASK_R_FIFO_REM_MSK (((1U << PSRAM_UHS_REG_MASK_R_FIFO_REM_LEN) - 1) << PSRAM_UHS_REG_MASK_R_FIFO_REM_POS) +#define PSRAM_UHS_REG_MASK_R_FIFO_REM_UMSK (~(((1U << PSRAM_UHS_REG_MASK_R_FIFO_REM_LEN) - 1) << PSRAM_UHS_REG_MASK_R_FIFO_REM_POS)) + +/* 0xC : UHS_manual */ +#define PSRAM_UHS_UHS_MANUAL_OFFSET (0xC) +#define PSRAM_UHS_REG_FORCE_CEB_LOW PSRAM_UHS_REG_FORCE_CEB_LOW +#define PSRAM_UHS_REG_FORCE_CEB_LOW_POS (0U) +#define PSRAM_UHS_REG_FORCE_CEB_LOW_LEN (1U) +#define PSRAM_UHS_REG_FORCE_CEB_LOW_MSK (((1U << PSRAM_UHS_REG_FORCE_CEB_LOW_LEN) - 1) << PSRAM_UHS_REG_FORCE_CEB_LOW_POS) +#define PSRAM_UHS_REG_FORCE_CEB_LOW_UMSK (~(((1U << PSRAM_UHS_REG_FORCE_CEB_LOW_LEN) - 1) << PSRAM_UHS_REG_FORCE_CEB_LOW_POS)) +#define PSRAM_UHS_REG_FORCE_CEB_HIGH PSRAM_UHS_REG_FORCE_CEB_HIGH +#define PSRAM_UHS_REG_FORCE_CEB_HIGH_POS (1U) +#define PSRAM_UHS_REG_FORCE_CEB_HIGH_LEN (1U) +#define PSRAM_UHS_REG_FORCE_CEB_HIGH_MSK (((1U << PSRAM_UHS_REG_FORCE_CEB_HIGH_LEN) - 1) << PSRAM_UHS_REG_FORCE_CEB_HIGH_POS) +#define PSRAM_UHS_REG_FORCE_CEB_HIGH_UMSK (~(((1U << PSRAM_UHS_REG_FORCE_CEB_HIGH_LEN) - 1) << PSRAM_UHS_REG_FORCE_CEB_HIGH_POS)) +#define PSRAM_UHS_REG_PSRAM_RESETB PSRAM_UHS_REG_PSRAM_RESETB +#define PSRAM_UHS_REG_PSRAM_RESETB_POS (2U) +#define PSRAM_UHS_REG_PSRAM_RESETB_LEN (1U) +#define PSRAM_UHS_REG_PSRAM_RESETB_MSK (((1U << PSRAM_UHS_REG_PSRAM_RESETB_LEN) - 1) << PSRAM_UHS_REG_PSRAM_RESETB_POS) +#define PSRAM_UHS_REG_PSRAM_RESETB_UMSK (~(((1U << PSRAM_UHS_REG_PSRAM_RESETB_LEN) - 1) << PSRAM_UHS_REG_PSRAM_RESETB_POS)) +#define PSRAM_UHS_REG_X16_MODE PSRAM_UHS_REG_X16_MODE +#define PSRAM_UHS_REG_X16_MODE_POS (3U) +#define PSRAM_UHS_REG_X16_MODE_LEN (1U) +#define PSRAM_UHS_REG_X16_MODE_MSK (((1U << PSRAM_UHS_REG_X16_MODE_LEN) - 1) << PSRAM_UHS_REG_X16_MODE_POS) +#define PSRAM_UHS_REG_X16_MODE_UMSK (~(((1U << PSRAM_UHS_REG_X16_MODE_LEN) - 1) << PSRAM_UHS_REG_X16_MODE_POS)) +#define PSRAM_UHS_REG_WRAP2INCR_EN PSRAM_UHS_REG_WRAP2INCR_EN +#define PSRAM_UHS_REG_WRAP2INCR_EN_POS (4U) +#define PSRAM_UHS_REG_WRAP2INCR_EN_LEN (1U) +#define PSRAM_UHS_REG_WRAP2INCR_EN_MSK (((1U << PSRAM_UHS_REG_WRAP2INCR_EN_LEN) - 1) << PSRAM_UHS_REG_WRAP2INCR_EN_POS) +#define PSRAM_UHS_REG_WRAP2INCR_EN_UMSK (~(((1U << PSRAM_UHS_REG_WRAP2INCR_EN_LEN) - 1) << PSRAM_UHS_REG_WRAP2INCR_EN_POS)) +#define PSRAM_UHS_REG_PCK_S_DIV PSRAM_UHS_REG_PCK_S_DIV +#define PSRAM_UHS_REG_PCK_S_DIV_POS (16U) +#define PSRAM_UHS_REG_PCK_S_DIV_LEN (3U) +#define PSRAM_UHS_REG_PCK_S_DIV_MSK (((1U << PSRAM_UHS_REG_PCK_S_DIV_LEN) - 1) << PSRAM_UHS_REG_PCK_S_DIV_POS) +#define PSRAM_UHS_REG_PCK_S_DIV_UMSK (~(((1U << PSRAM_UHS_REG_PCK_S_DIV_LEN) - 1) << PSRAM_UHS_REG_PCK_S_DIV_POS)) +#define PSRAM_UHS_REG_PCK_T_DIV PSRAM_UHS_REG_PCK_T_DIV +#define PSRAM_UHS_REG_PCK_T_DIV_POS (24U) +#define PSRAM_UHS_REG_PCK_T_DIV_LEN (8U) +#define PSRAM_UHS_REG_PCK_T_DIV_MSK (((1U << PSRAM_UHS_REG_PCK_T_DIV_LEN) - 1) << PSRAM_UHS_REG_PCK_T_DIV_POS) +#define PSRAM_UHS_REG_PCK_T_DIV_UMSK (~(((1U << PSRAM_UHS_REG_PCK_T_DIV_LEN) - 1) << PSRAM_UHS_REG_PCK_T_DIV_POS)) + +/* 0x10 : UHS_auto_fresh_1 */ +#define PSRAM_UHS_UHS_AUTO_FRESH_1_OFFSET (0x10) +#define PSRAM_UHS_REG_WIN_CYCLE PSRAM_UHS_REG_WIN_CYCLE +#define PSRAM_UHS_REG_WIN_CYCLE_POS (0U) +#define PSRAM_UHS_REG_WIN_CYCLE_LEN (28U) +#define PSRAM_UHS_REG_WIN_CYCLE_MSK (((1U << PSRAM_UHS_REG_WIN_CYCLE_LEN) - 1) << PSRAM_UHS_REG_WIN_CYCLE_POS) +#define PSRAM_UHS_REG_WIN_CYCLE_UMSK (~(((1U << PSRAM_UHS_REG_WIN_CYCLE_LEN) - 1) << PSRAM_UHS_REG_WIN_CYCLE_POS)) + +/* 0x14 : UHS_auto_fresh_2 */ +#define PSRAM_UHS_UHS_AUTO_FRESH_2_OFFSET (0x14) +#define PSRAM_UHS_REG_REFI_CYCLE PSRAM_UHS_REG_REFI_CYCLE +#define PSRAM_UHS_REG_REFI_CYCLE_POS (0U) +#define PSRAM_UHS_REG_REFI_CYCLE_LEN (16U) +#define PSRAM_UHS_REG_REFI_CYCLE_MSK (((1U << PSRAM_UHS_REG_REFI_CYCLE_LEN) - 1) << PSRAM_UHS_REG_REFI_CYCLE_POS) +#define PSRAM_UHS_REG_REFI_CYCLE_UMSK (~(((1U << PSRAM_UHS_REG_REFI_CYCLE_LEN) - 1) << PSRAM_UHS_REG_REFI_CYCLE_POS)) +#define PSRAM_UHS_REG_WIN_REF_CNT PSRAM_UHS_REG_WIN_REF_CNT +#define PSRAM_UHS_REG_WIN_REF_CNT_POS (16U) +#define PSRAM_UHS_REG_WIN_REF_CNT_LEN (13U) +#define PSRAM_UHS_REG_WIN_REF_CNT_MSK (((1U << PSRAM_UHS_REG_WIN_REF_CNT_LEN) - 1) << PSRAM_UHS_REG_WIN_REF_CNT_POS) +#define PSRAM_UHS_REG_WIN_REF_CNT_UMSK (~(((1U << PSRAM_UHS_REG_WIN_REF_CNT_LEN) - 1) << PSRAM_UHS_REG_WIN_REF_CNT_POS)) + +/* 0x18 : UHS_auto_fresh_3 */ +#define PSRAM_UHS_UHS_AUTO_FRESH_3_OFFSET (0x18) +#define PSRAM_UHS_REG_AUTO_REF_THRE PSRAM_UHS_REG_AUTO_REF_THRE +#define PSRAM_UHS_REG_AUTO_REF_THRE_POS (0U) +#define PSRAM_UHS_REG_AUTO_REF_THRE_LEN (12U) +#define PSRAM_UHS_REG_AUTO_REF_THRE_MSK (((1U << PSRAM_UHS_REG_AUTO_REF_THRE_LEN) - 1) << PSRAM_UHS_REG_AUTO_REF_THRE_POS) +#define PSRAM_UHS_REG_AUTO_REF_THRE_UMSK (~(((1U << PSRAM_UHS_REG_AUTO_REF_THRE_LEN) - 1) << PSRAM_UHS_REG_AUTO_REF_THRE_POS)) +#define PSRAM_UHS_AUTO_REFRESH_LEVEL PSRAM_UHS_AUTO_REFRESH_LEVEL +#define PSRAM_UHS_AUTO_REFRESH_LEVEL_POS (16U) +#define PSRAM_UHS_AUTO_REFRESH_LEVEL_LEN (12U) +#define PSRAM_UHS_AUTO_REFRESH_LEVEL_MSK (((1U << PSRAM_UHS_AUTO_REFRESH_LEVEL_LEN) - 1) << PSRAM_UHS_AUTO_REFRESH_LEVEL_POS) +#define PSRAM_UHS_AUTO_REFRESH_LEVEL_UMSK (~(((1U << PSRAM_UHS_AUTO_REFRESH_LEVEL_LEN) - 1) << PSRAM_UHS_AUTO_REFRESH_LEVEL_POS)) + +/* 0x1C : UHS_auto_fresh_4 */ +#define PSRAM_UHS_UHS_AUTO_FRESH_4_OFFSET (0x1C) +#define PSRAM_UHS_REG_BUST_CYCLE PSRAM_UHS_REG_BUST_CYCLE +#define PSRAM_UHS_REG_BUST_CYCLE_POS (0U) +#define PSRAM_UHS_REG_BUST_CYCLE_LEN (7U) +#define PSRAM_UHS_REG_BUST_CYCLE_MSK (((1U << PSRAM_UHS_REG_BUST_CYCLE_LEN) - 1) << PSRAM_UHS_REG_BUST_CYCLE_POS) +#define PSRAM_UHS_REG_BUST_CYCLE_UMSK (~(((1U << PSRAM_UHS_REG_BUST_CYCLE_LEN) - 1) << PSRAM_UHS_REG_BUST_CYCLE_POS)) + +/* 0x20 : UHS_psram_configure */ +#define PSRAM_UHS_UHS_PSRAM_CONFIGURE_OFFSET (0x20) +#define PSRAM_UHS_REG_UHS_LATENCY PSRAM_UHS_REG_UHS_LATENCY +#define PSRAM_UHS_REG_UHS_LATENCY_POS (0U) +#define PSRAM_UHS_REG_UHS_LATENCY_LEN (3U) +#define PSRAM_UHS_REG_UHS_LATENCY_MSK (((1U << PSRAM_UHS_REG_UHS_LATENCY_LEN) - 1) << PSRAM_UHS_REG_UHS_LATENCY_POS) +#define PSRAM_UHS_REG_UHS_LATENCY_UMSK (~(((1U << PSRAM_UHS_REG_UHS_LATENCY_LEN) - 1) << PSRAM_UHS_REG_UHS_LATENCY_POS)) +#define PSRAM_UHS_REG_UHS_DRIVE_ST PSRAM_UHS_REG_UHS_DRIVE_ST +#define PSRAM_UHS_REG_UHS_DRIVE_ST_POS (4U) +#define PSRAM_UHS_REG_UHS_DRIVE_ST_LEN (4U) +#define PSRAM_UHS_REG_UHS_DRIVE_ST_MSK (((1U << PSRAM_UHS_REG_UHS_DRIVE_ST_LEN) - 1) << PSRAM_UHS_REG_UHS_DRIVE_ST_POS) +#define PSRAM_UHS_REG_UHS_DRIVE_ST_UMSK (~(((1U << PSRAM_UHS_REG_UHS_DRIVE_ST_LEN) - 1) << PSRAM_UHS_REG_UHS_DRIVE_ST_POS)) +#define PSRAM_UHS_REG_UHS_BL_16 PSRAM_UHS_REG_UHS_BL_16 +#define PSRAM_UHS_REG_UHS_BL_16_POS (8U) +#define PSRAM_UHS_REG_UHS_BL_16_LEN (1U) +#define PSRAM_UHS_REG_UHS_BL_16_MSK (((1U << PSRAM_UHS_REG_UHS_BL_16_LEN) - 1) << PSRAM_UHS_REG_UHS_BL_16_POS) +#define PSRAM_UHS_REG_UHS_BL_16_UMSK (~(((1U << PSRAM_UHS_REG_UHS_BL_16_LEN) - 1) << PSRAM_UHS_REG_UHS_BL_16_POS)) +#define PSRAM_UHS_REG_UHS_BL_32 PSRAM_UHS_REG_UHS_BL_32 +#define PSRAM_UHS_REG_UHS_BL_32_POS (9U) +#define PSRAM_UHS_REG_UHS_BL_32_LEN (1U) +#define PSRAM_UHS_REG_UHS_BL_32_MSK (((1U << PSRAM_UHS_REG_UHS_BL_32_LEN) - 1) << PSRAM_UHS_REG_UHS_BL_32_POS) +#define PSRAM_UHS_REG_UHS_BL_32_UMSK (~(((1U << PSRAM_UHS_REG_UHS_BL_32_LEN) - 1) << PSRAM_UHS_REG_UHS_BL_32_POS)) +#define PSRAM_UHS_REG_UHS_BL_64 PSRAM_UHS_REG_UHS_BL_64 +#define PSRAM_UHS_REG_UHS_BL_64_POS (10U) +#define PSRAM_UHS_REG_UHS_BL_64_LEN (1U) +#define PSRAM_UHS_REG_UHS_BL_64_MSK (((1U << PSRAM_UHS_REG_UHS_BL_64_LEN) - 1) << PSRAM_UHS_REG_UHS_BL_64_POS) +#define PSRAM_UHS_REG_UHS_BL_64_UMSK (~(((1U << PSRAM_UHS_REG_UHS_BL_64_LEN) - 1) << PSRAM_UHS_REG_UHS_BL_64_POS)) + +/* 0x24 : UHS_psram_status */ +#define PSRAM_UHS_UHS_PSRAM_STATUS_OFFSET (0x24) +#define PSRAM_UHS_STS_UHS_LATENCY PSRAM_UHS_STS_UHS_LATENCY +#define PSRAM_UHS_STS_UHS_LATENCY_POS (0U) +#define PSRAM_UHS_STS_UHS_LATENCY_LEN (3U) +#define PSRAM_UHS_STS_UHS_LATENCY_MSK (((1U << PSRAM_UHS_STS_UHS_LATENCY_LEN) - 1) << PSRAM_UHS_STS_UHS_LATENCY_POS) +#define PSRAM_UHS_STS_UHS_LATENCY_UMSK (~(((1U << PSRAM_UHS_STS_UHS_LATENCY_LEN) - 1) << PSRAM_UHS_STS_UHS_LATENCY_POS)) +#define PSRAM_UHS_STS_UHS_DRIVE_ST PSRAM_UHS_STS_UHS_DRIVE_ST +#define PSRAM_UHS_STS_UHS_DRIVE_ST_POS (4U) +#define PSRAM_UHS_STS_UHS_DRIVE_ST_LEN (4U) +#define PSRAM_UHS_STS_UHS_DRIVE_ST_MSK (((1U << PSRAM_UHS_STS_UHS_DRIVE_ST_LEN) - 1) << PSRAM_UHS_STS_UHS_DRIVE_ST_POS) +#define PSRAM_UHS_STS_UHS_DRIVE_ST_UMSK (~(((1U << PSRAM_UHS_STS_UHS_DRIVE_ST_LEN) - 1) << PSRAM_UHS_STS_UHS_DRIVE_ST_POS)) +#define PSRAM_UHS_STS_UHS_BL_16 PSRAM_UHS_STS_UHS_BL_16 +#define PSRAM_UHS_STS_UHS_BL_16_POS (8U) +#define PSRAM_UHS_STS_UHS_BL_16_LEN (1U) +#define PSRAM_UHS_STS_UHS_BL_16_MSK (((1U << PSRAM_UHS_STS_UHS_BL_16_LEN) - 1) << PSRAM_UHS_STS_UHS_BL_16_POS) +#define PSRAM_UHS_STS_UHS_BL_16_UMSK (~(((1U << PSRAM_UHS_STS_UHS_BL_16_LEN) - 1) << PSRAM_UHS_STS_UHS_BL_16_POS)) +#define PSRAM_UHS_STS_UHS_BL_32 PSRAM_UHS_STS_UHS_BL_32 +#define PSRAM_UHS_STS_UHS_BL_32_POS (9U) +#define PSRAM_UHS_STS_UHS_BL_32_LEN (1U) +#define PSRAM_UHS_STS_UHS_BL_32_MSK (((1U << PSRAM_UHS_STS_UHS_BL_32_LEN) - 1) << PSRAM_UHS_STS_UHS_BL_32_POS) +#define PSRAM_UHS_STS_UHS_BL_32_UMSK (~(((1U << PSRAM_UHS_STS_UHS_BL_32_LEN) - 1) << PSRAM_UHS_STS_UHS_BL_32_POS)) +#define PSRAM_UHS_STS_UHS_BL_64 PSRAM_UHS_STS_UHS_BL_64 +#define PSRAM_UHS_STS_UHS_BL_64_POS (10U) +#define PSRAM_UHS_STS_UHS_BL_64_LEN (1U) +#define PSRAM_UHS_STS_UHS_BL_64_MSK (((1U << PSRAM_UHS_STS_UHS_BL_64_LEN) - 1) << PSRAM_UHS_STS_UHS_BL_64_POS) +#define PSRAM_UHS_STS_UHS_BL_64_UMSK (~(((1U << PSRAM_UHS_STS_UHS_BL_64_LEN) - 1) << PSRAM_UHS_STS_UHS_BL_64_POS)) + +/* 0x30 : UHS_timing_ctrl */ +#define PSRAM_UHS_UHS_TIMING_CTRL_OFFSET (0x30) +#define PSRAM_UHS_REG_TRC_CYCLE PSRAM_UHS_REG_TRC_CYCLE +#define PSRAM_UHS_REG_TRC_CYCLE_POS (0U) +#define PSRAM_UHS_REG_TRC_CYCLE_LEN (8U) +#define PSRAM_UHS_REG_TRC_CYCLE_MSK (((1U << PSRAM_UHS_REG_TRC_CYCLE_LEN) - 1) << PSRAM_UHS_REG_TRC_CYCLE_POS) +#define PSRAM_UHS_REG_TRC_CYCLE_UMSK (~(((1U << PSRAM_UHS_REG_TRC_CYCLE_LEN) - 1) << PSRAM_UHS_REG_TRC_CYCLE_POS)) +#define PSRAM_UHS_REG_TCPHR_CYCLE PSRAM_UHS_REG_TCPHR_CYCLE +#define PSRAM_UHS_REG_TCPHR_CYCLE_POS (8U) +#define PSRAM_UHS_REG_TCPHR_CYCLE_LEN (8U) +#define PSRAM_UHS_REG_TCPHR_CYCLE_MSK (((1U << PSRAM_UHS_REG_TCPHR_CYCLE_LEN) - 1) << PSRAM_UHS_REG_TCPHR_CYCLE_POS) +#define PSRAM_UHS_REG_TCPHR_CYCLE_UMSK (~(((1U << PSRAM_UHS_REG_TCPHR_CYCLE_LEN) - 1) << PSRAM_UHS_REG_TCPHR_CYCLE_POS)) +#define PSRAM_UHS_REG_TCPHW_CYCLE PSRAM_UHS_REG_TCPHW_CYCLE +#define PSRAM_UHS_REG_TCPHW_CYCLE_POS (16U) +#define PSRAM_UHS_REG_TCPHW_CYCLE_LEN (8U) +#define PSRAM_UHS_REG_TCPHW_CYCLE_MSK (((1U << PSRAM_UHS_REG_TCPHW_CYCLE_LEN) - 1) << PSRAM_UHS_REG_TCPHW_CYCLE_POS) +#define PSRAM_UHS_REG_TCPHW_CYCLE_UMSK (~(((1U << PSRAM_UHS_REG_TCPHW_CYCLE_LEN) - 1) << PSRAM_UHS_REG_TCPHW_CYCLE_POS)) +#define PSRAM_UHS_REG_TRFC_CYCLE PSRAM_UHS_REG_TRFC_CYCLE +#define PSRAM_UHS_REG_TRFC_CYCLE_POS (24U) +#define PSRAM_UHS_REG_TRFC_CYCLE_LEN (8U) +#define PSRAM_UHS_REG_TRFC_CYCLE_MSK (((1U << PSRAM_UHS_REG_TRFC_CYCLE_LEN) - 1) << PSRAM_UHS_REG_TRFC_CYCLE_POS) +#define PSRAM_UHS_REG_TRFC_CYCLE_UMSK (~(((1U << PSRAM_UHS_REG_TRFC_CYCLE_LEN) - 1) << PSRAM_UHS_REG_TRFC_CYCLE_POS)) + +/* 0x34 : UHS_rsvd_reg */ +#define PSRAM_UHS_UHS_RSVD_REG_OFFSET (0x34) +#define PSRAM_UHS_REG_MR0_7 PSRAM_UHS_REG_MR0_7 +#define PSRAM_UHS_REG_MR0_7_POS (0U) +#define PSRAM_UHS_REG_MR0_7_LEN (1U) +#define PSRAM_UHS_REG_MR0_7_MSK (((1U << PSRAM_UHS_REG_MR0_7_LEN) - 1) << PSRAM_UHS_REG_MR0_7_POS) +#define PSRAM_UHS_REG_MR0_7_UMSK (~(((1U << PSRAM_UHS_REG_MR0_7_LEN) - 1) << PSRAM_UHS_REG_MR0_7_POS)) +#define PSRAM_UHS_REG_MR2_2_0 PSRAM_UHS_REG_MR2_2_0 +#define PSRAM_UHS_REG_MR2_2_0_POS (1U) +#define PSRAM_UHS_REG_MR2_2_0_LEN (3U) +#define PSRAM_UHS_REG_MR2_2_0_MSK (((1U << PSRAM_UHS_REG_MR2_2_0_LEN) - 1) << PSRAM_UHS_REG_MR2_2_0_POS) +#define PSRAM_UHS_REG_MR2_2_0_UMSK (~(((1U << PSRAM_UHS_REG_MR2_2_0_LEN) - 1) << PSRAM_UHS_REG_MR2_2_0_POS)) +#define PSRAM_UHS_REG_MR2_7_6 PSRAM_UHS_REG_MR2_7_6 +#define PSRAM_UHS_REG_MR2_7_6_POS (4U) +#define PSRAM_UHS_REG_MR2_7_6_LEN (2U) +#define PSRAM_UHS_REG_MR2_7_6_MSK (((1U << PSRAM_UHS_REG_MR2_7_6_LEN) - 1) << PSRAM_UHS_REG_MR2_7_6_POS) +#define PSRAM_UHS_REG_MR2_7_6_UMSK (~(((1U << PSRAM_UHS_REG_MR2_7_6_LEN) - 1) << PSRAM_UHS_REG_MR2_7_6_POS)) + +/* 0xC0 : UHS_dbg_sel */ +#define PSRAM_UHS_UHS_DBG_SEL_OFFSET (0xC0) +#define PSRAM_UHS_REG_PSRAM_DBG_EN PSRAM_UHS_REG_PSRAM_DBG_EN +#define PSRAM_UHS_REG_PSRAM_DBG_EN_POS (0U) +#define PSRAM_UHS_REG_PSRAM_DBG_EN_LEN (1U) +#define PSRAM_UHS_REG_PSRAM_DBG_EN_MSK (((1U << PSRAM_UHS_REG_PSRAM_DBG_EN_LEN) - 1) << PSRAM_UHS_REG_PSRAM_DBG_EN_POS) +#define PSRAM_UHS_REG_PSRAM_DBG_EN_UMSK (~(((1U << PSRAM_UHS_REG_PSRAM_DBG_EN_LEN) - 1) << PSRAM_UHS_REG_PSRAM_DBG_EN_POS)) +#define PSRAM_UHS_REG_PSRAM_DBG_SEL PSRAM_UHS_REG_PSRAM_DBG_SEL +#define PSRAM_UHS_REG_PSRAM_DBG_SEL_POS (4U) +#define PSRAM_UHS_REG_PSRAM_DBG_SEL_LEN (4U) +#define PSRAM_UHS_REG_PSRAM_DBG_SEL_MSK (((1U << PSRAM_UHS_REG_PSRAM_DBG_SEL_LEN) - 1) << PSRAM_UHS_REG_PSRAM_DBG_SEL_POS) +#define PSRAM_UHS_REG_PSRAM_DBG_SEL_UMSK (~(((1U << PSRAM_UHS_REG_PSRAM_DBG_SEL_LEN) - 1) << PSRAM_UHS_REG_PSRAM_DBG_SEL_POS)) + +/* 0xF0 : UHS_dummy_reg */ +#define PSRAM_UHS_UHS_DUMMY_REG_OFFSET (0xF0) +#define PSRAM_UHS_REG_PSRAM_DUMMY_REG PSRAM_UHS_REG_PSRAM_DUMMY_REG +#define PSRAM_UHS_REG_PSRAM_DUMMY_REG_POS (0U) +#define PSRAM_UHS_REG_PSRAM_DUMMY_REG_LEN (32U) +#define PSRAM_UHS_REG_PSRAM_DUMMY_REG_MSK (((1U << PSRAM_UHS_REG_PSRAM_DUMMY_REG_LEN) - 1) << PSRAM_UHS_REG_PSRAM_DUMMY_REG_POS) +#define PSRAM_UHS_REG_PSRAM_DUMMY_REG_UMSK (~(((1U << PSRAM_UHS_REG_PSRAM_DUMMY_REG_LEN) - 1) << PSRAM_UHS_REG_PSRAM_DUMMY_REG_POS)) + +/* 0x100 : phy_cfg_00 */ +#define PSRAM_UHS_PHY_CFG_00_OFFSET (0x100) +#define PSRAM_UHS_DQS_RDY PSRAM_UHS_DQS_RDY +#define PSRAM_UHS_DQS_RDY_POS (0U) +#define PSRAM_UHS_DQS_RDY_LEN (1U) +#define PSRAM_UHS_DQS_RDY_MSK (((1U << PSRAM_UHS_DQS_RDY_LEN) - 1) << PSRAM_UHS_DQS_RDY_POS) +#define PSRAM_UHS_DQS_RDY_UMSK (~(((1U << PSRAM_UHS_DQS_RDY_LEN) - 1) << PSRAM_UHS_DQS_RDY_POS)) +#define PSRAM_UHS_CK_SR PSRAM_UHS_CK_SR +#define PSRAM_UHS_CK_SR_POS (8U) +#define PSRAM_UHS_CK_SR_LEN (2U) +#define PSRAM_UHS_CK_SR_MSK (((1U << PSRAM_UHS_CK_SR_LEN) - 1) << PSRAM_UHS_CK_SR_POS) +#define PSRAM_UHS_CK_SR_UMSK (~(((1U << PSRAM_UHS_CK_SR_LEN) - 1) << PSRAM_UHS_CK_SR_POS)) +#define PSRAM_UHS_CLK0_POLARITY PSRAM_UHS_CLK0_POLARITY +#define PSRAM_UHS_CLK0_POLARITY_POS (15U) +#define PSRAM_UHS_CLK0_POLARITY_LEN (1U) +#define PSRAM_UHS_CLK0_POLARITY_MSK (((1U << PSRAM_UHS_CLK0_POLARITY_LEN) - 1) << PSRAM_UHS_CLK0_POLARITY_POS) +#define PSRAM_UHS_CLK0_POLARITY_UMSK (~(((1U << PSRAM_UHS_CLK0_POLARITY_LEN) - 1) << PSRAM_UHS_CLK0_POLARITY_POS)) +#define PSRAM_UHS_CK_DLY_DRV PSRAM_UHS_CK_DLY_DRV +#define PSRAM_UHS_CK_DLY_DRV_POS (16U) +#define PSRAM_UHS_CK_DLY_DRV_LEN (4U) +#define PSRAM_UHS_CK_DLY_DRV_MSK (((1U << PSRAM_UHS_CK_DLY_DRV_LEN) - 1) << PSRAM_UHS_CK_DLY_DRV_POS) +#define PSRAM_UHS_CK_DLY_DRV_UMSK (~(((1U << PSRAM_UHS_CK_DLY_DRV_LEN) - 1) << PSRAM_UHS_CK_DLY_DRV_POS)) +#define PSRAM_UHS_CEN_SR PSRAM_UHS_CEN_SR +#define PSRAM_UHS_CEN_SR_POS (20U) +#define PSRAM_UHS_CEN_SR_LEN (2U) +#define PSRAM_UHS_CEN_SR_MSK (((1U << PSRAM_UHS_CEN_SR_LEN) - 1) << PSRAM_UHS_CEN_SR_POS) +#define PSRAM_UHS_CEN_SR_UMSK (~(((1U << PSRAM_UHS_CEN_SR_LEN) - 1) << PSRAM_UHS_CEN_SR_POS)) +#define PSRAM_UHS_CEN_DLY_DRV PSRAM_UHS_CEN_DLY_DRV +#define PSRAM_UHS_CEN_DLY_DRV_POS (28U) +#define PSRAM_UHS_CEN_DLY_DRV_LEN (4U) +#define PSRAM_UHS_CEN_DLY_DRV_MSK (((1U << PSRAM_UHS_CEN_DLY_DRV_LEN) - 1) << PSRAM_UHS_CEN_DLY_DRV_POS) +#define PSRAM_UHS_CEN_DLY_DRV_UMSK (~(((1U << PSRAM_UHS_CEN_DLY_DRV_LEN) - 1) << PSRAM_UHS_CEN_DLY_DRV_POS)) + +/* 0x104 : phy_cfg_04 */ +#define PSRAM_UHS_PHY_CFG_04_OFFSET (0x104) +#define PSRAM_UHS_DM1_SR PSRAM_UHS_DM1_SR +#define PSRAM_UHS_DM1_SR_POS (4U) +#define PSRAM_UHS_DM1_SR_LEN (2U) +#define PSRAM_UHS_DM1_SR_MSK (((1U << PSRAM_UHS_DM1_SR_LEN) - 1) << PSRAM_UHS_DM1_SR_POS) +#define PSRAM_UHS_DM1_SR_UMSK (~(((1U << PSRAM_UHS_DM1_SR_LEN) - 1) << PSRAM_UHS_DM1_SR_POS)) +#define PSRAM_UHS_DM1_DLY_DRV PSRAM_UHS_DM1_DLY_DRV +#define PSRAM_UHS_DM1_DLY_DRV_POS (12U) +#define PSRAM_UHS_DM1_DLY_DRV_LEN (4U) +#define PSRAM_UHS_DM1_DLY_DRV_MSK (((1U << PSRAM_UHS_DM1_DLY_DRV_LEN) - 1) << PSRAM_UHS_DM1_DLY_DRV_POS) +#define PSRAM_UHS_DM1_DLY_DRV_UMSK (~(((1U << PSRAM_UHS_DM1_DLY_DRV_LEN) - 1) << PSRAM_UHS_DM1_DLY_DRV_POS)) +#define PSRAM_UHS_DM0_SR PSRAM_UHS_DM0_SR +#define PSRAM_UHS_DM0_SR_POS (20U) +#define PSRAM_UHS_DM0_SR_LEN (2U) +#define PSRAM_UHS_DM0_SR_MSK (((1U << PSRAM_UHS_DM0_SR_LEN) - 1) << PSRAM_UHS_DM0_SR_POS) +#define PSRAM_UHS_DM0_SR_UMSK (~(((1U << PSRAM_UHS_DM0_SR_LEN) - 1) << PSRAM_UHS_DM0_SR_POS)) +#define PSRAM_UHS_DM0_DLY_DRV PSRAM_UHS_DM0_DLY_DRV +#define PSRAM_UHS_DM0_DLY_DRV_POS (28U) +#define PSRAM_UHS_DM0_DLY_DRV_LEN (4U) +#define PSRAM_UHS_DM0_DLY_DRV_MSK (((1U << PSRAM_UHS_DM0_DLY_DRV_LEN) - 1) << PSRAM_UHS_DM0_DLY_DRV_POS) +#define PSRAM_UHS_DM0_DLY_DRV_UMSK (~(((1U << PSRAM_UHS_DM0_DLY_DRV_LEN) - 1) << PSRAM_UHS_DM0_DLY_DRV_POS)) + +/* 0x108 : phy_cfg_08 */ +#define PSRAM_UHS_PHY_CFG_08_OFFSET (0x108) +#define PSRAM_UHS_DQ1_SR PSRAM_UHS_DQ1_SR +#define PSRAM_UHS_DQ1_SR_POS (0U) +#define PSRAM_UHS_DQ1_SR_LEN (2U) +#define PSRAM_UHS_DQ1_SR_MSK (((1U << PSRAM_UHS_DQ1_SR_LEN) - 1) << PSRAM_UHS_DQ1_SR_POS) +#define PSRAM_UHS_DQ1_SR_UMSK (~(((1U << PSRAM_UHS_DQ1_SR_LEN) - 1) << PSRAM_UHS_DQ1_SR_POS)) +#define PSRAM_UHS_DQ1_DLY_RX PSRAM_UHS_DQ1_DLY_RX +#define PSRAM_UHS_DQ1_DLY_RX_POS (8U) +#define PSRAM_UHS_DQ1_DLY_RX_LEN (4U) +#define PSRAM_UHS_DQ1_DLY_RX_MSK (((1U << PSRAM_UHS_DQ1_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ1_DLY_RX_POS) +#define PSRAM_UHS_DQ1_DLY_RX_UMSK (~(((1U << PSRAM_UHS_DQ1_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ1_DLY_RX_POS)) +#define PSRAM_UHS_DQ1_DLY_DRV PSRAM_UHS_DQ1_DLY_DRV +#define PSRAM_UHS_DQ1_DLY_DRV_POS (12U) +#define PSRAM_UHS_DQ1_DLY_DRV_LEN (4U) +#define PSRAM_UHS_DQ1_DLY_DRV_MSK (((1U << PSRAM_UHS_DQ1_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ1_DLY_DRV_POS) +#define PSRAM_UHS_DQ1_DLY_DRV_UMSK (~(((1U << PSRAM_UHS_DQ1_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ1_DLY_DRV_POS)) +#define PSRAM_UHS_DQ0_SR PSRAM_UHS_DQ0_SR +#define PSRAM_UHS_DQ0_SR_POS (16U) +#define PSRAM_UHS_DQ0_SR_LEN (2U) +#define PSRAM_UHS_DQ0_SR_MSK (((1U << PSRAM_UHS_DQ0_SR_LEN) - 1) << PSRAM_UHS_DQ0_SR_POS) +#define PSRAM_UHS_DQ0_SR_UMSK (~(((1U << PSRAM_UHS_DQ0_SR_LEN) - 1) << PSRAM_UHS_DQ0_SR_POS)) +#define PSRAM_UHS_DQ0_DLY_RX PSRAM_UHS_DQ0_DLY_RX +#define PSRAM_UHS_DQ0_DLY_RX_POS (24U) +#define PSRAM_UHS_DQ0_DLY_RX_LEN (4U) +#define PSRAM_UHS_DQ0_DLY_RX_MSK (((1U << PSRAM_UHS_DQ0_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ0_DLY_RX_POS) +#define PSRAM_UHS_DQ0_DLY_RX_UMSK (~(((1U << PSRAM_UHS_DQ0_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ0_DLY_RX_POS)) +#define PSRAM_UHS_DQ0_DLY_DRV PSRAM_UHS_DQ0_DLY_DRV +#define PSRAM_UHS_DQ0_DLY_DRV_POS (28U) +#define PSRAM_UHS_DQ0_DLY_DRV_LEN (4U) +#define PSRAM_UHS_DQ0_DLY_DRV_MSK (((1U << PSRAM_UHS_DQ0_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ0_DLY_DRV_POS) +#define PSRAM_UHS_DQ0_DLY_DRV_UMSK (~(((1U << PSRAM_UHS_DQ0_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ0_DLY_DRV_POS)) + +/* 0x10C : phy_cfg_0C */ +#define PSRAM_UHS_PHY_CFG_0C_OFFSET (0x10C) +#define PSRAM_UHS_DQ3_SR PSRAM_UHS_DQ3_SR +#define PSRAM_UHS_DQ3_SR_POS (0U) +#define PSRAM_UHS_DQ3_SR_LEN (2U) +#define PSRAM_UHS_DQ3_SR_MSK (((1U << PSRAM_UHS_DQ3_SR_LEN) - 1) << PSRAM_UHS_DQ3_SR_POS) +#define PSRAM_UHS_DQ3_SR_UMSK (~(((1U << PSRAM_UHS_DQ3_SR_LEN) - 1) << PSRAM_UHS_DQ3_SR_POS)) +#define PSRAM_UHS_DQ3_DLY_RX PSRAM_UHS_DQ3_DLY_RX +#define PSRAM_UHS_DQ3_DLY_RX_POS (8U) +#define PSRAM_UHS_DQ3_DLY_RX_LEN (4U) +#define PSRAM_UHS_DQ3_DLY_RX_MSK (((1U << PSRAM_UHS_DQ3_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ3_DLY_RX_POS) +#define PSRAM_UHS_DQ3_DLY_RX_UMSK (~(((1U << PSRAM_UHS_DQ3_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ3_DLY_RX_POS)) +#define PSRAM_UHS_DQ3_DLY_DRV PSRAM_UHS_DQ3_DLY_DRV +#define PSRAM_UHS_DQ3_DLY_DRV_POS (12U) +#define PSRAM_UHS_DQ3_DLY_DRV_LEN (4U) +#define PSRAM_UHS_DQ3_DLY_DRV_MSK (((1U << PSRAM_UHS_DQ3_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ3_DLY_DRV_POS) +#define PSRAM_UHS_DQ3_DLY_DRV_UMSK (~(((1U << PSRAM_UHS_DQ3_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ3_DLY_DRV_POS)) +#define PSRAM_UHS_DQ2_SR PSRAM_UHS_DQ2_SR +#define PSRAM_UHS_DQ2_SR_POS (16U) +#define PSRAM_UHS_DQ2_SR_LEN (2U) +#define PSRAM_UHS_DQ2_SR_MSK (((1U << PSRAM_UHS_DQ2_SR_LEN) - 1) << PSRAM_UHS_DQ2_SR_POS) +#define PSRAM_UHS_DQ2_SR_UMSK (~(((1U << PSRAM_UHS_DQ2_SR_LEN) - 1) << PSRAM_UHS_DQ2_SR_POS)) +#define PSRAM_UHS_DQ2_DLY_RX PSRAM_UHS_DQ2_DLY_RX +#define PSRAM_UHS_DQ2_DLY_RX_POS (24U) +#define PSRAM_UHS_DQ2_DLY_RX_LEN (4U) +#define PSRAM_UHS_DQ2_DLY_RX_MSK (((1U << PSRAM_UHS_DQ2_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ2_DLY_RX_POS) +#define PSRAM_UHS_DQ2_DLY_RX_UMSK (~(((1U << PSRAM_UHS_DQ2_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ2_DLY_RX_POS)) +#define PSRAM_UHS_DQ2_DLY_DRV PSRAM_UHS_DQ2_DLY_DRV +#define PSRAM_UHS_DQ2_DLY_DRV_POS (28U) +#define PSRAM_UHS_DQ2_DLY_DRV_LEN (4U) +#define PSRAM_UHS_DQ2_DLY_DRV_MSK (((1U << PSRAM_UHS_DQ2_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ2_DLY_DRV_POS) +#define PSRAM_UHS_DQ2_DLY_DRV_UMSK (~(((1U << PSRAM_UHS_DQ2_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ2_DLY_DRV_POS)) + +/* 0x110 : phy_cfg_10 */ +#define PSRAM_UHS_PHY_CFG_10_OFFSET (0x110) +#define PSRAM_UHS_DQ5_SR PSRAM_UHS_DQ5_SR +#define PSRAM_UHS_DQ5_SR_POS (0U) +#define PSRAM_UHS_DQ5_SR_LEN (2U) +#define PSRAM_UHS_DQ5_SR_MSK (((1U << PSRAM_UHS_DQ5_SR_LEN) - 1) << PSRAM_UHS_DQ5_SR_POS) +#define PSRAM_UHS_DQ5_SR_UMSK (~(((1U << PSRAM_UHS_DQ5_SR_LEN) - 1) << PSRAM_UHS_DQ5_SR_POS)) +#define PSRAM_UHS_DQ5_DLY_RX PSRAM_UHS_DQ5_DLY_RX +#define PSRAM_UHS_DQ5_DLY_RX_POS (8U) +#define PSRAM_UHS_DQ5_DLY_RX_LEN (4U) +#define PSRAM_UHS_DQ5_DLY_RX_MSK (((1U << PSRAM_UHS_DQ5_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ5_DLY_RX_POS) +#define PSRAM_UHS_DQ5_DLY_RX_UMSK (~(((1U << PSRAM_UHS_DQ5_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ5_DLY_RX_POS)) +#define PSRAM_UHS_DQ5_DLY_DRV PSRAM_UHS_DQ5_DLY_DRV +#define PSRAM_UHS_DQ5_DLY_DRV_POS (12U) +#define PSRAM_UHS_DQ5_DLY_DRV_LEN (4U) +#define PSRAM_UHS_DQ5_DLY_DRV_MSK (((1U << PSRAM_UHS_DQ5_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ5_DLY_DRV_POS) +#define PSRAM_UHS_DQ5_DLY_DRV_UMSK (~(((1U << PSRAM_UHS_DQ5_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ5_DLY_DRV_POS)) +#define PSRAM_UHS_DQ4_SR PSRAM_UHS_DQ4_SR +#define PSRAM_UHS_DQ4_SR_POS (16U) +#define PSRAM_UHS_DQ4_SR_LEN (2U) +#define PSRAM_UHS_DQ4_SR_MSK (((1U << PSRAM_UHS_DQ4_SR_LEN) - 1) << PSRAM_UHS_DQ4_SR_POS) +#define PSRAM_UHS_DQ4_SR_UMSK (~(((1U << PSRAM_UHS_DQ4_SR_LEN) - 1) << PSRAM_UHS_DQ4_SR_POS)) +#define PSRAM_UHS_DQ4_DLY_RX PSRAM_UHS_DQ4_DLY_RX +#define PSRAM_UHS_DQ4_DLY_RX_POS (24U) +#define PSRAM_UHS_DQ4_DLY_RX_LEN (4U) +#define PSRAM_UHS_DQ4_DLY_RX_MSK (((1U << PSRAM_UHS_DQ4_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ4_DLY_RX_POS) +#define PSRAM_UHS_DQ4_DLY_RX_UMSK (~(((1U << PSRAM_UHS_DQ4_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ4_DLY_RX_POS)) +#define PSRAM_UHS_DQ4_DLY_DRV PSRAM_UHS_DQ4_DLY_DRV +#define PSRAM_UHS_DQ4_DLY_DRV_POS (28U) +#define PSRAM_UHS_DQ4_DLY_DRV_LEN (4U) +#define PSRAM_UHS_DQ4_DLY_DRV_MSK (((1U << PSRAM_UHS_DQ4_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ4_DLY_DRV_POS) +#define PSRAM_UHS_DQ4_DLY_DRV_UMSK (~(((1U << PSRAM_UHS_DQ4_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ4_DLY_DRV_POS)) + +/* 0x114 : phy_cfg_14 */ +#define PSRAM_UHS_PHY_CFG_14_OFFSET (0x114) +#define PSRAM_UHS_DQ7_SR PSRAM_UHS_DQ7_SR +#define PSRAM_UHS_DQ7_SR_POS (0U) +#define PSRAM_UHS_DQ7_SR_LEN (2U) +#define PSRAM_UHS_DQ7_SR_MSK (((1U << PSRAM_UHS_DQ7_SR_LEN) - 1) << PSRAM_UHS_DQ7_SR_POS) +#define PSRAM_UHS_DQ7_SR_UMSK (~(((1U << PSRAM_UHS_DQ7_SR_LEN) - 1) << PSRAM_UHS_DQ7_SR_POS)) +#define PSRAM_UHS_DQ7_DLY_RX PSRAM_UHS_DQ7_DLY_RX +#define PSRAM_UHS_DQ7_DLY_RX_POS (8U) +#define PSRAM_UHS_DQ7_DLY_RX_LEN (4U) +#define PSRAM_UHS_DQ7_DLY_RX_MSK (((1U << PSRAM_UHS_DQ7_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ7_DLY_RX_POS) +#define PSRAM_UHS_DQ7_DLY_RX_UMSK (~(((1U << PSRAM_UHS_DQ7_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ7_DLY_RX_POS)) +#define PSRAM_UHS_DQ7_DLY_DRV PSRAM_UHS_DQ7_DLY_DRV +#define PSRAM_UHS_DQ7_DLY_DRV_POS (12U) +#define PSRAM_UHS_DQ7_DLY_DRV_LEN (4U) +#define PSRAM_UHS_DQ7_DLY_DRV_MSK (((1U << PSRAM_UHS_DQ7_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ7_DLY_DRV_POS) +#define PSRAM_UHS_DQ7_DLY_DRV_UMSK (~(((1U << PSRAM_UHS_DQ7_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ7_DLY_DRV_POS)) +#define PSRAM_UHS_DQ6_SR PSRAM_UHS_DQ6_SR +#define PSRAM_UHS_DQ6_SR_POS (16U) +#define PSRAM_UHS_DQ6_SR_LEN (2U) +#define PSRAM_UHS_DQ6_SR_MSK (((1U << PSRAM_UHS_DQ6_SR_LEN) - 1) << PSRAM_UHS_DQ6_SR_POS) +#define PSRAM_UHS_DQ6_SR_UMSK (~(((1U << PSRAM_UHS_DQ6_SR_LEN) - 1) << PSRAM_UHS_DQ6_SR_POS)) +#define PSRAM_UHS_DQ6_DLY_RX PSRAM_UHS_DQ6_DLY_RX +#define PSRAM_UHS_DQ6_DLY_RX_POS (24U) +#define PSRAM_UHS_DQ6_DLY_RX_LEN (4U) +#define PSRAM_UHS_DQ6_DLY_RX_MSK (((1U << PSRAM_UHS_DQ6_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ6_DLY_RX_POS) +#define PSRAM_UHS_DQ6_DLY_RX_UMSK (~(((1U << PSRAM_UHS_DQ6_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ6_DLY_RX_POS)) +#define PSRAM_UHS_DQ6_DLY_DRV PSRAM_UHS_DQ6_DLY_DRV +#define PSRAM_UHS_DQ6_DLY_DRV_POS (28U) +#define PSRAM_UHS_DQ6_DLY_DRV_LEN (4U) +#define PSRAM_UHS_DQ6_DLY_DRV_MSK (((1U << PSRAM_UHS_DQ6_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ6_DLY_DRV_POS) +#define PSRAM_UHS_DQ6_DLY_DRV_UMSK (~(((1U << PSRAM_UHS_DQ6_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ6_DLY_DRV_POS)) + +/* 0x118 : phy_cfg_18 */ +#define PSRAM_UHS_PHY_CFG_18_OFFSET (0x118) +#define PSRAM_UHS_DQ9_SR PSRAM_UHS_DQ9_SR +#define PSRAM_UHS_DQ9_SR_POS (0U) +#define PSRAM_UHS_DQ9_SR_LEN (2U) +#define PSRAM_UHS_DQ9_SR_MSK (((1U << PSRAM_UHS_DQ9_SR_LEN) - 1) << PSRAM_UHS_DQ9_SR_POS) +#define PSRAM_UHS_DQ9_SR_UMSK (~(((1U << PSRAM_UHS_DQ9_SR_LEN) - 1) << PSRAM_UHS_DQ9_SR_POS)) +#define PSRAM_UHS_DQ9_DLY_RX PSRAM_UHS_DQ9_DLY_RX +#define PSRAM_UHS_DQ9_DLY_RX_POS (8U) +#define PSRAM_UHS_DQ9_DLY_RX_LEN (4U) +#define PSRAM_UHS_DQ9_DLY_RX_MSK (((1U << PSRAM_UHS_DQ9_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ9_DLY_RX_POS) +#define PSRAM_UHS_DQ9_DLY_RX_UMSK (~(((1U << PSRAM_UHS_DQ9_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ9_DLY_RX_POS)) +#define PSRAM_UHS_DQ9_DLY_DRV PSRAM_UHS_DQ9_DLY_DRV +#define PSRAM_UHS_DQ9_DLY_DRV_POS (12U) +#define PSRAM_UHS_DQ9_DLY_DRV_LEN (4U) +#define PSRAM_UHS_DQ9_DLY_DRV_MSK (((1U << PSRAM_UHS_DQ9_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ9_DLY_DRV_POS) +#define PSRAM_UHS_DQ9_DLY_DRV_UMSK (~(((1U << PSRAM_UHS_DQ9_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ9_DLY_DRV_POS)) +#define PSRAM_UHS_DQ8_SR PSRAM_UHS_DQ8_SR +#define PSRAM_UHS_DQ8_SR_POS (16U) +#define PSRAM_UHS_DQ8_SR_LEN (2U) +#define PSRAM_UHS_DQ8_SR_MSK (((1U << PSRAM_UHS_DQ8_SR_LEN) - 1) << PSRAM_UHS_DQ8_SR_POS) +#define PSRAM_UHS_DQ8_SR_UMSK (~(((1U << PSRAM_UHS_DQ8_SR_LEN) - 1) << PSRAM_UHS_DQ8_SR_POS)) +#define PSRAM_UHS_DQ8_DLY_RX PSRAM_UHS_DQ8_DLY_RX +#define PSRAM_UHS_DQ8_DLY_RX_POS (24U) +#define PSRAM_UHS_DQ8_DLY_RX_LEN (4U) +#define PSRAM_UHS_DQ8_DLY_RX_MSK (((1U << PSRAM_UHS_DQ8_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ8_DLY_RX_POS) +#define PSRAM_UHS_DQ8_DLY_RX_UMSK (~(((1U << PSRAM_UHS_DQ8_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ8_DLY_RX_POS)) +#define PSRAM_UHS_DQ8_DLY_DRV PSRAM_UHS_DQ8_DLY_DRV +#define PSRAM_UHS_DQ8_DLY_DRV_POS (28U) +#define PSRAM_UHS_DQ8_DLY_DRV_LEN (4U) +#define PSRAM_UHS_DQ8_DLY_DRV_MSK (((1U << PSRAM_UHS_DQ8_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ8_DLY_DRV_POS) +#define PSRAM_UHS_DQ8_DLY_DRV_UMSK (~(((1U << PSRAM_UHS_DQ8_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ8_DLY_DRV_POS)) + +/* 0x11C : phy_cfg_1C */ +#define PSRAM_UHS_PHY_CFG_1C_OFFSET (0x11C) +#define PSRAM_UHS_DQ11_SR PSRAM_UHS_DQ11_SR +#define PSRAM_UHS_DQ11_SR_POS (0U) +#define PSRAM_UHS_DQ11_SR_LEN (2U) +#define PSRAM_UHS_DQ11_SR_MSK (((1U << PSRAM_UHS_DQ11_SR_LEN) - 1) << PSRAM_UHS_DQ11_SR_POS) +#define PSRAM_UHS_DQ11_SR_UMSK (~(((1U << PSRAM_UHS_DQ11_SR_LEN) - 1) << PSRAM_UHS_DQ11_SR_POS)) +#define PSRAM_UHS_DQ11_DLY_RX PSRAM_UHS_DQ11_DLY_RX +#define PSRAM_UHS_DQ11_DLY_RX_POS (8U) +#define PSRAM_UHS_DQ11_DLY_RX_LEN (4U) +#define PSRAM_UHS_DQ11_DLY_RX_MSK (((1U << PSRAM_UHS_DQ11_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ11_DLY_RX_POS) +#define PSRAM_UHS_DQ11_DLY_RX_UMSK (~(((1U << PSRAM_UHS_DQ11_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ11_DLY_RX_POS)) +#define PSRAM_UHS_DQ11_DLY_DRV PSRAM_UHS_DQ11_DLY_DRV +#define PSRAM_UHS_DQ11_DLY_DRV_POS (12U) +#define PSRAM_UHS_DQ11_DLY_DRV_LEN (4U) +#define PSRAM_UHS_DQ11_DLY_DRV_MSK (((1U << PSRAM_UHS_DQ11_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ11_DLY_DRV_POS) +#define PSRAM_UHS_DQ11_DLY_DRV_UMSK (~(((1U << PSRAM_UHS_DQ11_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ11_DLY_DRV_POS)) +#define PSRAM_UHS_DQ10_SR PSRAM_UHS_DQ10_SR +#define PSRAM_UHS_DQ10_SR_POS (16U) +#define PSRAM_UHS_DQ10_SR_LEN (2U) +#define PSRAM_UHS_DQ10_SR_MSK (((1U << PSRAM_UHS_DQ10_SR_LEN) - 1) << PSRAM_UHS_DQ10_SR_POS) +#define PSRAM_UHS_DQ10_SR_UMSK (~(((1U << PSRAM_UHS_DQ10_SR_LEN) - 1) << PSRAM_UHS_DQ10_SR_POS)) +#define PSRAM_UHS_DQ10_DLY_RX PSRAM_UHS_DQ10_DLY_RX +#define PSRAM_UHS_DQ10_DLY_RX_POS (24U) +#define PSRAM_UHS_DQ10_DLY_RX_LEN (4U) +#define PSRAM_UHS_DQ10_DLY_RX_MSK (((1U << PSRAM_UHS_DQ10_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ10_DLY_RX_POS) +#define PSRAM_UHS_DQ10_DLY_RX_UMSK (~(((1U << PSRAM_UHS_DQ10_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ10_DLY_RX_POS)) +#define PSRAM_UHS_DQ10_DLY_DRV PSRAM_UHS_DQ10_DLY_DRV +#define PSRAM_UHS_DQ10_DLY_DRV_POS (28U) +#define PSRAM_UHS_DQ10_DLY_DRV_LEN (4U) +#define PSRAM_UHS_DQ10_DLY_DRV_MSK (((1U << PSRAM_UHS_DQ10_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ10_DLY_DRV_POS) +#define PSRAM_UHS_DQ10_DLY_DRV_UMSK (~(((1U << PSRAM_UHS_DQ10_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ10_DLY_DRV_POS)) + +/* 0x120 : phy_cfg_20 */ +#define PSRAM_UHS_PHY_CFG_20_OFFSET (0x120) +#define PSRAM_UHS_DQ13_SR PSRAM_UHS_DQ13_SR +#define PSRAM_UHS_DQ13_SR_POS (0U) +#define PSRAM_UHS_DQ13_SR_LEN (2U) +#define PSRAM_UHS_DQ13_SR_MSK (((1U << PSRAM_UHS_DQ13_SR_LEN) - 1) << PSRAM_UHS_DQ13_SR_POS) +#define PSRAM_UHS_DQ13_SR_UMSK (~(((1U << PSRAM_UHS_DQ13_SR_LEN) - 1) << PSRAM_UHS_DQ13_SR_POS)) +#define PSRAM_UHS_DQ13_DLY_RX PSRAM_UHS_DQ13_DLY_RX +#define PSRAM_UHS_DQ13_DLY_RX_POS (8U) +#define PSRAM_UHS_DQ13_DLY_RX_LEN (4U) +#define PSRAM_UHS_DQ13_DLY_RX_MSK (((1U << PSRAM_UHS_DQ13_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ13_DLY_RX_POS) +#define PSRAM_UHS_DQ13_DLY_RX_UMSK (~(((1U << PSRAM_UHS_DQ13_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ13_DLY_RX_POS)) +#define PSRAM_UHS_DQ13_DLY_DRV PSRAM_UHS_DQ13_DLY_DRV +#define PSRAM_UHS_DQ13_DLY_DRV_POS (12U) +#define PSRAM_UHS_DQ13_DLY_DRV_LEN (4U) +#define PSRAM_UHS_DQ13_DLY_DRV_MSK (((1U << PSRAM_UHS_DQ13_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ13_DLY_DRV_POS) +#define PSRAM_UHS_DQ13_DLY_DRV_UMSK (~(((1U << PSRAM_UHS_DQ13_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ13_DLY_DRV_POS)) +#define PSRAM_UHS_DQ12_SR PSRAM_UHS_DQ12_SR +#define PSRAM_UHS_DQ12_SR_POS (16U) +#define PSRAM_UHS_DQ12_SR_LEN (2U) +#define PSRAM_UHS_DQ12_SR_MSK (((1U << PSRAM_UHS_DQ12_SR_LEN) - 1) << PSRAM_UHS_DQ12_SR_POS) +#define PSRAM_UHS_DQ12_SR_UMSK (~(((1U << PSRAM_UHS_DQ12_SR_LEN) - 1) << PSRAM_UHS_DQ12_SR_POS)) +#define PSRAM_UHS_DQ12_DLY_RX PSRAM_UHS_DQ12_DLY_RX +#define PSRAM_UHS_DQ12_DLY_RX_POS (24U) +#define PSRAM_UHS_DQ12_DLY_RX_LEN (4U) +#define PSRAM_UHS_DQ12_DLY_RX_MSK (((1U << PSRAM_UHS_DQ12_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ12_DLY_RX_POS) +#define PSRAM_UHS_DQ12_DLY_RX_UMSK (~(((1U << PSRAM_UHS_DQ12_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ12_DLY_RX_POS)) +#define PSRAM_UHS_DQ12_DLY_DRV PSRAM_UHS_DQ12_DLY_DRV +#define PSRAM_UHS_DQ12_DLY_DRV_POS (28U) +#define PSRAM_UHS_DQ12_DLY_DRV_LEN (4U) +#define PSRAM_UHS_DQ12_DLY_DRV_MSK (((1U << PSRAM_UHS_DQ12_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ12_DLY_DRV_POS) +#define PSRAM_UHS_DQ12_DLY_DRV_UMSK (~(((1U << PSRAM_UHS_DQ12_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ12_DLY_DRV_POS)) + +/* 0x124 : phy_cfg_24 */ +#define PSRAM_UHS_PHY_CFG_24_OFFSET (0x124) +#define PSRAM_UHS_DQ15_SR PSRAM_UHS_DQ15_SR +#define PSRAM_UHS_DQ15_SR_POS (0U) +#define PSRAM_UHS_DQ15_SR_LEN (2U) +#define PSRAM_UHS_DQ15_SR_MSK (((1U << PSRAM_UHS_DQ15_SR_LEN) - 1) << PSRAM_UHS_DQ15_SR_POS) +#define PSRAM_UHS_DQ15_SR_UMSK (~(((1U << PSRAM_UHS_DQ15_SR_LEN) - 1) << PSRAM_UHS_DQ15_SR_POS)) +#define PSRAM_UHS_DQ15_DLY_RX PSRAM_UHS_DQ15_DLY_RX +#define PSRAM_UHS_DQ15_DLY_RX_POS (8U) +#define PSRAM_UHS_DQ15_DLY_RX_LEN (4U) +#define PSRAM_UHS_DQ15_DLY_RX_MSK (((1U << PSRAM_UHS_DQ15_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ15_DLY_RX_POS) +#define PSRAM_UHS_DQ15_DLY_RX_UMSK (~(((1U << PSRAM_UHS_DQ15_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ15_DLY_RX_POS)) +#define PSRAM_UHS_DQ15_DLY_DRV PSRAM_UHS_DQ15_DLY_DRV +#define PSRAM_UHS_DQ15_DLY_DRV_POS (12U) +#define PSRAM_UHS_DQ15_DLY_DRV_LEN (4U) +#define PSRAM_UHS_DQ15_DLY_DRV_MSK (((1U << PSRAM_UHS_DQ15_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ15_DLY_DRV_POS) +#define PSRAM_UHS_DQ15_DLY_DRV_UMSK (~(((1U << PSRAM_UHS_DQ15_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ15_DLY_DRV_POS)) +#define PSRAM_UHS_DQ14_SR PSRAM_UHS_DQ14_SR +#define PSRAM_UHS_DQ14_SR_POS (16U) +#define PSRAM_UHS_DQ14_SR_LEN (2U) +#define PSRAM_UHS_DQ14_SR_MSK (((1U << PSRAM_UHS_DQ14_SR_LEN) - 1) << PSRAM_UHS_DQ14_SR_POS) +#define PSRAM_UHS_DQ14_SR_UMSK (~(((1U << PSRAM_UHS_DQ14_SR_LEN) - 1) << PSRAM_UHS_DQ14_SR_POS)) +#define PSRAM_UHS_DQ14_DLY_RX PSRAM_UHS_DQ14_DLY_RX +#define PSRAM_UHS_DQ14_DLY_RX_POS (24U) +#define PSRAM_UHS_DQ14_DLY_RX_LEN (4U) +#define PSRAM_UHS_DQ14_DLY_RX_MSK (((1U << PSRAM_UHS_DQ14_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ14_DLY_RX_POS) +#define PSRAM_UHS_DQ14_DLY_RX_UMSK (~(((1U << PSRAM_UHS_DQ14_DLY_RX_LEN) - 1) << PSRAM_UHS_DQ14_DLY_RX_POS)) +#define PSRAM_UHS_DQ14_DLY_DRV PSRAM_UHS_DQ14_DLY_DRV +#define PSRAM_UHS_DQ14_DLY_DRV_POS (28U) +#define PSRAM_UHS_DQ14_DLY_DRV_LEN (4U) +#define PSRAM_UHS_DQ14_DLY_DRV_MSK (((1U << PSRAM_UHS_DQ14_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ14_DLY_DRV_POS) +#define PSRAM_UHS_DQ14_DLY_DRV_UMSK (~(((1U << PSRAM_UHS_DQ14_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQ14_DLY_DRV_POS)) + +/* 0x128 : phy_cfg_28 */ +#define PSRAM_UHS_PHY_CFG_28_OFFSET (0x128) +#define PSRAM_UHS_DQS0N_DLY_RX PSRAM_UHS_DQS0N_DLY_RX +#define PSRAM_UHS_DQS0N_DLY_RX_POS (8U) +#define PSRAM_UHS_DQS0N_DLY_RX_LEN (4U) +#define PSRAM_UHS_DQS0N_DLY_RX_MSK (((1U << PSRAM_UHS_DQS0N_DLY_RX_LEN) - 1) << PSRAM_UHS_DQS0N_DLY_RX_POS) +#define PSRAM_UHS_DQS0N_DLY_RX_UMSK (~(((1U << PSRAM_UHS_DQS0N_DLY_RX_LEN) - 1) << PSRAM_UHS_DQS0N_DLY_RX_POS)) +#define PSRAM_UHS_DQS0_SR PSRAM_UHS_DQS0_SR +#define PSRAM_UHS_DQS0_SR_POS (12U) +#define PSRAM_UHS_DQS0_SR_LEN (2U) +#define PSRAM_UHS_DQS0_SR_MSK (((1U << PSRAM_UHS_DQS0_SR_LEN) - 1) << PSRAM_UHS_DQS0_SR_POS) +#define PSRAM_UHS_DQS0_SR_UMSK (~(((1U << PSRAM_UHS_DQS0_SR_LEN) - 1) << PSRAM_UHS_DQS0_SR_POS)) +#define PSRAM_UHS_DQS0_SEL PSRAM_UHS_DQS0_SEL +#define PSRAM_UHS_DQS0_SEL_POS (14U) +#define PSRAM_UHS_DQS0_SEL_LEN (2U) +#define PSRAM_UHS_DQS0_SEL_MSK (((1U << PSRAM_UHS_DQS0_SEL_LEN) - 1) << PSRAM_UHS_DQS0_SEL_POS) +#define PSRAM_UHS_DQS0_SEL_UMSK (~(((1U << PSRAM_UHS_DQS0_SEL_LEN) - 1) << PSRAM_UHS_DQS0_SEL_POS)) +#define PSRAM_UHS_DQS0_DLY_RX PSRAM_UHS_DQS0_DLY_RX +#define PSRAM_UHS_DQS0_DLY_RX_POS (20U) +#define PSRAM_UHS_DQS0_DLY_RX_LEN (4U) +#define PSRAM_UHS_DQS0_DLY_RX_MSK (((1U << PSRAM_UHS_DQS0_DLY_RX_LEN) - 1) << PSRAM_UHS_DQS0_DLY_RX_POS) +#define PSRAM_UHS_DQS0_DLY_RX_UMSK (~(((1U << PSRAM_UHS_DQS0_DLY_RX_LEN) - 1) << PSRAM_UHS_DQS0_DLY_RX_POS)) +#define PSRAM_UHS_DQS0_DLY_DRV PSRAM_UHS_DQS0_DLY_DRV +#define PSRAM_UHS_DQS0_DLY_DRV_POS (24U) +#define PSRAM_UHS_DQS0_DLY_DRV_LEN (4U) +#define PSRAM_UHS_DQS0_DLY_DRV_MSK (((1U << PSRAM_UHS_DQS0_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQS0_DLY_DRV_POS) +#define PSRAM_UHS_DQS0_DLY_DRV_UMSK (~(((1U << PSRAM_UHS_DQS0_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQS0_DLY_DRV_POS)) +#define PSRAM_UHS_DQS0_DIFF_DLY_RX PSRAM_UHS_DQS0_DIFF_DLY_RX +#define PSRAM_UHS_DQS0_DIFF_DLY_RX_POS (28U) +#define PSRAM_UHS_DQS0_DIFF_DLY_RX_LEN (4U) +#define PSRAM_UHS_DQS0_DIFF_DLY_RX_MSK (((1U << PSRAM_UHS_DQS0_DIFF_DLY_RX_LEN) - 1) << PSRAM_UHS_DQS0_DIFF_DLY_RX_POS) +#define PSRAM_UHS_DQS0_DIFF_DLY_RX_UMSK (~(((1U << PSRAM_UHS_DQS0_DIFF_DLY_RX_LEN) - 1) << PSRAM_UHS_DQS0_DIFF_DLY_RX_POS)) + +/* 0x12C : phy_cfg_2C */ +#define PSRAM_UHS_PHY_CFG_2C_OFFSET (0x12C) +#define PSRAM_UHS_IPP5UN_LPDDR PSRAM_UHS_IPP5UN_LPDDR +#define PSRAM_UHS_IPP5UN_LPDDR_POS (0U) +#define PSRAM_UHS_IPP5UN_LPDDR_LEN (1U) +#define PSRAM_UHS_IPP5UN_LPDDR_MSK (((1U << PSRAM_UHS_IPP5UN_LPDDR_LEN) - 1) << PSRAM_UHS_IPP5UN_LPDDR_POS) +#define PSRAM_UHS_IPP5UN_LPDDR_UMSK (~(((1U << PSRAM_UHS_IPP5UN_LPDDR_LEN) - 1) << PSRAM_UHS_IPP5UN_LPDDR_POS)) +#define PSRAM_UHS_EN_RX_FE PSRAM_UHS_EN_RX_FE +#define PSRAM_UHS_EN_RX_FE_POS (1U) +#define PSRAM_UHS_EN_RX_FE_LEN (1U) +#define PSRAM_UHS_EN_RX_FE_MSK (((1U << PSRAM_UHS_EN_RX_FE_LEN) - 1) << PSRAM_UHS_EN_RX_FE_POS) +#define PSRAM_UHS_EN_RX_FE_UMSK (~(((1U << PSRAM_UHS_EN_RX_FE_LEN) - 1) << PSRAM_UHS_EN_RX_FE_POS)) +#define PSRAM_UHS_EN_BIAS PSRAM_UHS_EN_BIAS +#define PSRAM_UHS_EN_BIAS_POS (2U) +#define PSRAM_UHS_EN_BIAS_LEN (1U) +#define PSRAM_UHS_EN_BIAS_MSK (((1U << PSRAM_UHS_EN_BIAS_LEN) - 1) << PSRAM_UHS_EN_BIAS_POS) +#define PSRAM_UHS_EN_BIAS_UMSK (~(((1U << PSRAM_UHS_EN_BIAS_LEN) - 1) << PSRAM_UHS_EN_BIAS_POS)) +#define PSRAM_UHS_DQS1N_DLY_RX PSRAM_UHS_DQS1N_DLY_RX +#define PSRAM_UHS_DQS1N_DLY_RX_POS (8U) +#define PSRAM_UHS_DQS1N_DLY_RX_LEN (4U) +#define PSRAM_UHS_DQS1N_DLY_RX_MSK (((1U << PSRAM_UHS_DQS1N_DLY_RX_LEN) - 1) << PSRAM_UHS_DQS1N_DLY_RX_POS) +#define PSRAM_UHS_DQS1N_DLY_RX_UMSK (~(((1U << PSRAM_UHS_DQS1N_DLY_RX_LEN) - 1) << PSRAM_UHS_DQS1N_DLY_RX_POS)) +#define PSRAM_UHS_DQS1_SR PSRAM_UHS_DQS1_SR +#define PSRAM_UHS_DQS1_SR_POS (12U) +#define PSRAM_UHS_DQS1_SR_LEN (2U) +#define PSRAM_UHS_DQS1_SR_MSK (((1U << PSRAM_UHS_DQS1_SR_LEN) - 1) << PSRAM_UHS_DQS1_SR_POS) +#define PSRAM_UHS_DQS1_SR_UMSK (~(((1U << PSRAM_UHS_DQS1_SR_LEN) - 1) << PSRAM_UHS_DQS1_SR_POS)) +#define PSRAM_UHS_DQS1_SEL PSRAM_UHS_DQS1_SEL +#define PSRAM_UHS_DQS1_SEL_POS (14U) +#define PSRAM_UHS_DQS1_SEL_LEN (2U) +#define PSRAM_UHS_DQS1_SEL_MSK (((1U << PSRAM_UHS_DQS1_SEL_LEN) - 1) << PSRAM_UHS_DQS1_SEL_POS) +#define PSRAM_UHS_DQS1_SEL_UMSK (~(((1U << PSRAM_UHS_DQS1_SEL_LEN) - 1) << PSRAM_UHS_DQS1_SEL_POS)) +#define PSRAM_UHS_DQS1_DLY_RX PSRAM_UHS_DQS1_DLY_RX +#define PSRAM_UHS_DQS1_DLY_RX_POS (20U) +#define PSRAM_UHS_DQS1_DLY_RX_LEN (4U) +#define PSRAM_UHS_DQS1_DLY_RX_MSK (((1U << PSRAM_UHS_DQS1_DLY_RX_LEN) - 1) << PSRAM_UHS_DQS1_DLY_RX_POS) +#define PSRAM_UHS_DQS1_DLY_RX_UMSK (~(((1U << PSRAM_UHS_DQS1_DLY_RX_LEN) - 1) << PSRAM_UHS_DQS1_DLY_RX_POS)) +#define PSRAM_UHS_DQS1_DLY_DRV PSRAM_UHS_DQS1_DLY_DRV +#define PSRAM_UHS_DQS1_DLY_DRV_POS (24U) +#define PSRAM_UHS_DQS1_DLY_DRV_LEN (4U) +#define PSRAM_UHS_DQS1_DLY_DRV_MSK (((1U << PSRAM_UHS_DQS1_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQS1_DLY_DRV_POS) +#define PSRAM_UHS_DQS1_DLY_DRV_UMSK (~(((1U << PSRAM_UHS_DQS1_DLY_DRV_LEN) - 1) << PSRAM_UHS_DQS1_DLY_DRV_POS)) +#define PSRAM_UHS_DQS1_DIFF_DLY_RX PSRAM_UHS_DQS1_DIFF_DLY_RX +#define PSRAM_UHS_DQS1_DIFF_DLY_RX_POS (28U) +#define PSRAM_UHS_DQS1_DIFF_DLY_RX_LEN (4U) +#define PSRAM_UHS_DQS1_DIFF_DLY_RX_MSK (((1U << PSRAM_UHS_DQS1_DIFF_DLY_RX_LEN) - 1) << PSRAM_UHS_DQS1_DIFF_DLY_RX_POS) +#define PSRAM_UHS_DQS1_DIFF_DLY_RX_UMSK (~(((1U << PSRAM_UHS_DQS1_DIFF_DLY_RX_LEN) - 1) << PSRAM_UHS_DQS1_DIFF_DLY_RX_POS)) + +/* 0x130 : phy_cfg_30 */ +#define PSRAM_UHS_PHY_CFG_30_OFFSET (0x130) +#define PSRAM_UHS_PHY_WL_DQ_DIG PSRAM_UHS_PHY_WL_DQ_DIG +#define PSRAM_UHS_PHY_WL_DQ_DIG_POS (0U) +#define PSRAM_UHS_PHY_WL_DQ_DIG_LEN (3U) +#define PSRAM_UHS_PHY_WL_DQ_DIG_MSK (((1U << PSRAM_UHS_PHY_WL_DQ_DIG_LEN) - 1) << PSRAM_UHS_PHY_WL_DQ_DIG_POS) +#define PSRAM_UHS_PHY_WL_DQ_DIG_UMSK (~(((1U << PSRAM_UHS_PHY_WL_DQ_DIG_LEN) - 1) << PSRAM_UHS_PHY_WL_DQ_DIG_POS)) +#define PSRAM_UHS_PHY_WL_DQ_ANA PSRAM_UHS_PHY_WL_DQ_ANA +#define PSRAM_UHS_PHY_WL_DQ_ANA_POS (4U) +#define PSRAM_UHS_PHY_WL_DQ_ANA_LEN (3U) +#define PSRAM_UHS_PHY_WL_DQ_ANA_MSK (((1U << PSRAM_UHS_PHY_WL_DQ_ANA_LEN) - 1) << PSRAM_UHS_PHY_WL_DQ_ANA_POS) +#define PSRAM_UHS_PHY_WL_DQ_ANA_UMSK (~(((1U << PSRAM_UHS_PHY_WL_DQ_ANA_LEN) - 1) << PSRAM_UHS_PHY_WL_DQ_ANA_POS)) +#define PSRAM_UHS_PHY_WL_DIG PSRAM_UHS_PHY_WL_DIG +#define PSRAM_UHS_PHY_WL_DIG_POS (8U) +#define PSRAM_UHS_PHY_WL_DIG_LEN (3U) +#define PSRAM_UHS_PHY_WL_DIG_MSK (((1U << PSRAM_UHS_PHY_WL_DIG_LEN) - 1) << PSRAM_UHS_PHY_WL_DIG_POS) +#define PSRAM_UHS_PHY_WL_DIG_UMSK (~(((1U << PSRAM_UHS_PHY_WL_DIG_LEN) - 1) << PSRAM_UHS_PHY_WL_DIG_POS)) +#define PSRAM_UHS_PHY_WL_ANA PSRAM_UHS_PHY_WL_ANA +#define PSRAM_UHS_PHY_WL_ANA_POS (12U) +#define PSRAM_UHS_PHY_WL_ANA_LEN (3U) +#define PSRAM_UHS_PHY_WL_ANA_MSK (((1U << PSRAM_UHS_PHY_WL_ANA_LEN) - 1) << PSRAM_UHS_PHY_WL_ANA_POS) +#define PSRAM_UHS_PHY_WL_ANA_UMSK (~(((1U << PSRAM_UHS_PHY_WL_ANA_LEN) - 1) << PSRAM_UHS_PHY_WL_ANA_POS)) +#define PSRAM_UHS_PHY_RL_DIG PSRAM_UHS_PHY_RL_DIG +#define PSRAM_UHS_PHY_RL_DIG_POS (16U) +#define PSRAM_UHS_PHY_RL_DIG_LEN (4U) +#define PSRAM_UHS_PHY_RL_DIG_MSK (((1U << PSRAM_UHS_PHY_RL_DIG_LEN) - 1) << PSRAM_UHS_PHY_RL_DIG_POS) +#define PSRAM_UHS_PHY_RL_DIG_UMSK (~(((1U << PSRAM_UHS_PHY_RL_DIG_LEN) - 1) << PSRAM_UHS_PHY_RL_DIG_POS)) +#define PSRAM_UHS_PHY_RL_ANA PSRAM_UHS_PHY_RL_ANA +#define PSRAM_UHS_PHY_RL_ANA_POS (20U) +#define PSRAM_UHS_PHY_RL_ANA_LEN (3U) +#define PSRAM_UHS_PHY_RL_ANA_MSK (((1U << PSRAM_UHS_PHY_RL_ANA_LEN) - 1) << PSRAM_UHS_PHY_RL_ANA_POS) +#define PSRAM_UHS_PHY_RL_ANA_UMSK (~(((1U << PSRAM_UHS_PHY_RL_ANA_LEN) - 1) << PSRAM_UHS_PHY_RL_ANA_POS)) +#define PSRAM_UHS_OE_TIMER PSRAM_UHS_OE_TIMER +#define PSRAM_UHS_OE_TIMER_POS (24U) +#define PSRAM_UHS_OE_TIMER_LEN (2U) +#define PSRAM_UHS_OE_TIMER_MSK (((1U << PSRAM_UHS_OE_TIMER_LEN) - 1) << PSRAM_UHS_OE_TIMER_POS) +#define PSRAM_UHS_OE_TIMER_UMSK (~(((1U << PSRAM_UHS_OE_TIMER_LEN) - 1) << PSRAM_UHS_OE_TIMER_POS)) +#define PSRAM_UHS_VREF_MODE PSRAM_UHS_VREF_MODE +#define PSRAM_UHS_VREF_MODE_POS (26U) +#define PSRAM_UHS_VREF_MODE_LEN (1U) +#define PSRAM_UHS_VREF_MODE_MSK (((1U << PSRAM_UHS_VREF_MODE_LEN) - 1) << PSRAM_UHS_VREF_MODE_POS) +#define PSRAM_UHS_VREF_MODE_UMSK (~(((1U << PSRAM_UHS_VREF_MODE_LEN) - 1) << PSRAM_UHS_VREF_MODE_POS)) +#define PSRAM_UHS_OE_CTRL_HW PSRAM_UHS_OE_CTRL_HW +#define PSRAM_UHS_OE_CTRL_HW_POS (27U) +#define PSRAM_UHS_OE_CTRL_HW_LEN (1U) +#define PSRAM_UHS_OE_CTRL_HW_MSK (((1U << PSRAM_UHS_OE_CTRL_HW_LEN) - 1) << PSRAM_UHS_OE_CTRL_HW_POS) +#define PSRAM_UHS_OE_CTRL_HW_UMSK (~(((1U << PSRAM_UHS_OE_CTRL_HW_LEN) - 1) << PSRAM_UHS_OE_CTRL_HW_POS)) +#define PSRAM_UHS_ODT_SEL PSRAM_UHS_ODT_SEL +#define PSRAM_UHS_ODT_SEL_POS (28U) +#define PSRAM_UHS_ODT_SEL_LEN (4U) +#define PSRAM_UHS_ODT_SEL_MSK (((1U << PSRAM_UHS_ODT_SEL_LEN) - 1) << PSRAM_UHS_ODT_SEL_POS) +#define PSRAM_UHS_ODT_SEL_UMSK (~(((1U << PSRAM_UHS_ODT_SEL_LEN) - 1) << PSRAM_UHS_ODT_SEL_POS)) + +/* 0x134 : phy_cfg_34 */ +#define PSRAM_UHS_PHY_CFG_34_OFFSET (0x134) +#define PSRAM_UHS_REG_TIMER_DQS_START PSRAM_UHS_REG_TIMER_DQS_START +#define PSRAM_UHS_REG_TIMER_DQS_START_POS (0U) +#define PSRAM_UHS_REG_TIMER_DQS_START_LEN (8U) +#define PSRAM_UHS_REG_TIMER_DQS_START_MSK (((1U << PSRAM_UHS_REG_TIMER_DQS_START_LEN) - 1) << PSRAM_UHS_REG_TIMER_DQS_START_POS) +#define PSRAM_UHS_REG_TIMER_DQS_START_UMSK (~(((1U << PSRAM_UHS_REG_TIMER_DQS_START_LEN) - 1) << PSRAM_UHS_REG_TIMER_DQS_START_POS)) +#define PSRAM_UHS_REG_TIMER_DQS_ARRAY_STOP PSRAM_UHS_REG_TIMER_DQS_ARRAY_STOP +#define PSRAM_UHS_REG_TIMER_DQS_ARRAY_STOP_POS (8U) +#define PSRAM_UHS_REG_TIMER_DQS_ARRAY_STOP_LEN (8U) +#define PSRAM_UHS_REG_TIMER_DQS_ARRAY_STOP_MSK (((1U << PSRAM_UHS_REG_TIMER_DQS_ARRAY_STOP_LEN) - 1) << PSRAM_UHS_REG_TIMER_DQS_ARRAY_STOP_POS) +#define PSRAM_UHS_REG_TIMER_DQS_ARRAY_STOP_UMSK (~(((1U << PSRAM_UHS_REG_TIMER_DQS_ARRAY_STOP_LEN) - 1) << PSRAM_UHS_REG_TIMER_DQS_ARRAY_STOP_POS)) +#define PSRAM_UHS_REG_TIMER_ARRAY_WRITE PSRAM_UHS_REG_TIMER_ARRAY_WRITE +#define PSRAM_UHS_REG_TIMER_ARRAY_WRITE_POS (16U) +#define PSRAM_UHS_REG_TIMER_ARRAY_WRITE_LEN (8U) +#define PSRAM_UHS_REG_TIMER_ARRAY_WRITE_MSK (((1U << PSRAM_UHS_REG_TIMER_ARRAY_WRITE_LEN) - 1) << PSRAM_UHS_REG_TIMER_ARRAY_WRITE_POS) +#define PSRAM_UHS_REG_TIMER_ARRAY_WRITE_UMSK (~(((1U << PSRAM_UHS_REG_TIMER_ARRAY_WRITE_LEN) - 1) << PSRAM_UHS_REG_TIMER_ARRAY_WRITE_POS)) +#define PSRAM_UHS_REG_TIMER_ARRAY_READ PSRAM_UHS_REG_TIMER_ARRAY_READ +#define PSRAM_UHS_REG_TIMER_ARRAY_READ_POS (24U) +#define PSRAM_UHS_REG_TIMER_ARRAY_READ_LEN (8U) +#define PSRAM_UHS_REG_TIMER_ARRAY_READ_MSK (((1U << PSRAM_UHS_REG_TIMER_ARRAY_READ_LEN) - 1) << PSRAM_UHS_REG_TIMER_ARRAY_READ_POS) +#define PSRAM_UHS_REG_TIMER_ARRAY_READ_UMSK (~(((1U << PSRAM_UHS_REG_TIMER_ARRAY_READ_LEN) - 1) << PSRAM_UHS_REG_TIMER_ARRAY_READ_POS)) + +/* 0x138 : phy_cfg_38 */ +#define PSRAM_UHS_PHY_CFG_38_OFFSET (0x138) +#define PSRAM_UHS_REG_TIMER_AUTO_REFRESH PSRAM_UHS_REG_TIMER_AUTO_REFRESH +#define PSRAM_UHS_REG_TIMER_AUTO_REFRESH_POS (0U) +#define PSRAM_UHS_REG_TIMER_AUTO_REFRESH_LEN (8U) +#define PSRAM_UHS_REG_TIMER_AUTO_REFRESH_MSK (((1U << PSRAM_UHS_REG_TIMER_AUTO_REFRESH_LEN) - 1) << PSRAM_UHS_REG_TIMER_AUTO_REFRESH_POS) +#define PSRAM_UHS_REG_TIMER_AUTO_REFRESH_UMSK (~(((1U << PSRAM_UHS_REG_TIMER_AUTO_REFRESH_LEN) - 1) << PSRAM_UHS_REG_TIMER_AUTO_REFRESH_POS)) +#define PSRAM_UHS_REG_TIMER_REG_WRITE PSRAM_UHS_REG_TIMER_REG_WRITE +#define PSRAM_UHS_REG_TIMER_REG_WRITE_POS (8U) +#define PSRAM_UHS_REG_TIMER_REG_WRITE_LEN (8U) +#define PSRAM_UHS_REG_TIMER_REG_WRITE_MSK (((1U << PSRAM_UHS_REG_TIMER_REG_WRITE_LEN) - 1) << PSRAM_UHS_REG_TIMER_REG_WRITE_POS) +#define PSRAM_UHS_REG_TIMER_REG_WRITE_UMSK (~(((1U << PSRAM_UHS_REG_TIMER_REG_WRITE_LEN) - 1) << PSRAM_UHS_REG_TIMER_REG_WRITE_POS)) +#define PSRAM_UHS_REG_TIMER_REG_READ PSRAM_UHS_REG_TIMER_REG_READ +#define PSRAM_UHS_REG_TIMER_REG_READ_POS (16U) +#define PSRAM_UHS_REG_TIMER_REG_READ_LEN (8U) +#define PSRAM_UHS_REG_TIMER_REG_READ_MSK (((1U << PSRAM_UHS_REG_TIMER_REG_READ_LEN) - 1) << PSRAM_UHS_REG_TIMER_REG_READ_POS) +#define PSRAM_UHS_REG_TIMER_REG_READ_UMSK (~(((1U << PSRAM_UHS_REG_TIMER_REG_READ_LEN) - 1) << PSRAM_UHS_REG_TIMER_REG_READ_POS)) +#define PSRAM_UHS_REG_TIMER_DQS_STOP PSRAM_UHS_REG_TIMER_DQS_STOP +#define PSRAM_UHS_REG_TIMER_DQS_STOP_POS (24U) +#define PSRAM_UHS_REG_TIMER_DQS_STOP_LEN (8U) +#define PSRAM_UHS_REG_TIMER_DQS_STOP_MSK (((1U << PSRAM_UHS_REG_TIMER_DQS_STOP_LEN) - 1) << PSRAM_UHS_REG_TIMER_DQS_STOP_POS) +#define PSRAM_UHS_REG_TIMER_DQS_STOP_UMSK (~(((1U << PSRAM_UHS_REG_TIMER_DQS_STOP_LEN) - 1) << PSRAM_UHS_REG_TIMER_DQS_STOP_POS)) + +/* 0x13C : phy_cfg_3C */ +#define PSRAM_UHS_PHY_CFG_3C_OFFSET (0x13C) +#define PSRAM_UHS_REG_TIMER_SELF_REFRESH1_IN PSRAM_UHS_REG_TIMER_SELF_REFRESH1_IN +#define PSRAM_UHS_REG_TIMER_SELF_REFRESH1_IN_POS (0U) +#define PSRAM_UHS_REG_TIMER_SELF_REFRESH1_IN_LEN (8U) +#define PSRAM_UHS_REG_TIMER_SELF_REFRESH1_IN_MSK (((1U << PSRAM_UHS_REG_TIMER_SELF_REFRESH1_IN_LEN) - 1) << PSRAM_UHS_REG_TIMER_SELF_REFRESH1_IN_POS) +#define PSRAM_UHS_REG_TIMER_SELF_REFRESH1_IN_UMSK (~(((1U << PSRAM_UHS_REG_TIMER_SELF_REFRESH1_IN_LEN) - 1) << PSRAM_UHS_REG_TIMER_SELF_REFRESH1_IN_POS)) +#define PSRAM_UHS_REG_TIMER_SELF_REFRESH1_EXIT PSRAM_UHS_REG_TIMER_SELF_REFRESH1_EXIT +#define PSRAM_UHS_REG_TIMER_SELF_REFRESH1_EXIT_POS (8U) +#define PSRAM_UHS_REG_TIMER_SELF_REFRESH1_EXIT_LEN (8U) +#define PSRAM_UHS_REG_TIMER_SELF_REFRESH1_EXIT_MSK (((1U << PSRAM_UHS_REG_TIMER_SELF_REFRESH1_EXIT_LEN) - 1) << PSRAM_UHS_REG_TIMER_SELF_REFRESH1_EXIT_POS) +#define PSRAM_UHS_REG_TIMER_SELF_REFRESH1_EXIT_UMSK (~(((1U << PSRAM_UHS_REG_TIMER_SELF_REFRESH1_EXIT_LEN) - 1) << PSRAM_UHS_REG_TIMER_SELF_REFRESH1_EXIT_POS)) +#define PSRAM_UHS_REG_TIMER_GLOBAL_RST PSRAM_UHS_REG_TIMER_GLOBAL_RST +#define PSRAM_UHS_REG_TIMER_GLOBAL_RST_POS (16U) +#define PSRAM_UHS_REG_TIMER_GLOBAL_RST_LEN (14U) +#define PSRAM_UHS_REG_TIMER_GLOBAL_RST_MSK (((1U << PSRAM_UHS_REG_TIMER_GLOBAL_RST_LEN) - 1) << PSRAM_UHS_REG_TIMER_GLOBAL_RST_POS) +#define PSRAM_UHS_REG_TIMER_GLOBAL_RST_UMSK (~(((1U << PSRAM_UHS_REG_TIMER_GLOBAL_RST_LEN) - 1) << PSRAM_UHS_REG_TIMER_GLOBAL_RST_POS)) + +/* 0x140 : phy_cfg_40 */ +#define PSRAM_UHS_PHY_CFG_40_OFFSET (0x140) +#define PSRAM_UHS_VREF_SEL PSRAM_UHS_VREF_SEL +#define PSRAM_UHS_VREF_SEL_POS (0U) +#define PSRAM_UHS_VREF_SEL_LEN (4U) +#define PSRAM_UHS_VREF_SEL_MSK (((1U << PSRAM_UHS_VREF_SEL_LEN) - 1) << PSRAM_UHS_VREF_SEL_POS) +#define PSRAM_UHS_VREF_SEL_UMSK (~(((1U << PSRAM_UHS_VREF_SEL_LEN) - 1) << PSRAM_UHS_VREF_SEL_POS)) +#define PSRAM_UHS_VREF_DQ_SEL PSRAM_UHS_VREF_DQ_SEL +#define PSRAM_UHS_VREF_DQ_SEL_POS (4U) +#define PSRAM_UHS_VREF_DQ_SEL_LEN (4U) +#define PSRAM_UHS_VREF_DQ_SEL_MSK (((1U << PSRAM_UHS_VREF_DQ_SEL_LEN) - 1) << PSRAM_UHS_VREF_DQ_SEL_POS) +#define PSRAM_UHS_VREF_DQ_SEL_UMSK (~(((1U << PSRAM_UHS_VREF_DQ_SEL_LEN) - 1) << PSRAM_UHS_VREF_DQ_SEL_POS)) +#define PSRAM_UHS_REG_UHS_DMY0 PSRAM_UHS_REG_UHS_DMY0 +#define PSRAM_UHS_REG_UHS_DMY0_POS (8U) +#define PSRAM_UHS_REG_UHS_DMY0_LEN (8U) +#define PSRAM_UHS_REG_UHS_DMY0_MSK (((1U << PSRAM_UHS_REG_UHS_DMY0_LEN) - 1) << PSRAM_UHS_REG_UHS_DMY0_POS) +#define PSRAM_UHS_REG_UHS_DMY0_UMSK (~(((1U << PSRAM_UHS_REG_UHS_DMY0_LEN) - 1) << PSRAM_UHS_REG_UHS_DMY0_POS)) +#define PSRAM_UHS_REG_UHS_DMY1 PSRAM_UHS_REG_UHS_DMY1 +#define PSRAM_UHS_REG_UHS_DMY1_POS (16U) +#define PSRAM_UHS_REG_UHS_DMY1_LEN (8U) +#define PSRAM_UHS_REG_UHS_DMY1_MSK (((1U << PSRAM_UHS_REG_UHS_DMY1_LEN) - 1) << PSRAM_UHS_REG_UHS_DMY1_POS) +#define PSRAM_UHS_REG_UHS_DMY1_UMSK (~(((1U << PSRAM_UHS_REG_UHS_DMY1_LEN) - 1) << PSRAM_UHS_REG_UHS_DMY1_POS)) +#define PSRAM_UHS_REG_UHS_PHY_TEN PSRAM_UHS_REG_UHS_PHY_TEN +#define PSRAM_UHS_REG_UHS_PHY_TEN_POS (24U) +#define PSRAM_UHS_REG_UHS_PHY_TEN_LEN (1U) +#define PSRAM_UHS_REG_UHS_PHY_TEN_MSK (((1U << PSRAM_UHS_REG_UHS_PHY_TEN_LEN) - 1) << PSRAM_UHS_REG_UHS_PHY_TEN_POS) +#define PSRAM_UHS_REG_UHS_PHY_TEN_UMSK (~(((1U << PSRAM_UHS_REG_UHS_PHY_TEN_LEN) - 1) << PSRAM_UHS_REG_UHS_PHY_TEN_POS)) +#define PSRAM_UHS_SOC_EN_AON PSRAM_UHS_SOC_EN_AON +#define PSRAM_UHS_SOC_EN_AON_POS (25U) +#define PSRAM_UHS_SOC_EN_AON_LEN (1U) +#define PSRAM_UHS_SOC_EN_AON_MSK (((1U << PSRAM_UHS_SOC_EN_AON_LEN) - 1) << PSRAM_UHS_SOC_EN_AON_POS) +#define PSRAM_UHS_SOC_EN_AON_UMSK (~(((1U << PSRAM_UHS_SOC_EN_AON_LEN) - 1) << PSRAM_UHS_SOC_EN_AON_POS)) +#define PSRAM_UHS_TEN_UHS_PHY PSRAM_UHS_TEN_UHS_PHY +#define PSRAM_UHS_TEN_UHS_PHY_POS (26U) +#define PSRAM_UHS_TEN_UHS_PHY_LEN (1U) +#define PSRAM_UHS_TEN_UHS_PHY_MSK (((1U << PSRAM_UHS_TEN_UHS_PHY_LEN) - 1) << PSRAM_UHS_TEN_UHS_PHY_POS) +#define PSRAM_UHS_TEN_UHS_PHY_UMSK (~(((1U << PSRAM_UHS_TEN_UHS_PHY_LEN) - 1) << PSRAM_UHS_TEN_UHS_PHY_POS)) +#define PSRAM_UHS_TEN_UHS_PHY_DIG PSRAM_UHS_TEN_UHS_PHY_DIG +#define PSRAM_UHS_TEN_UHS_PHY_DIG_POS (27U) +#define PSRAM_UHS_TEN_UHS_PHY_DIG_LEN (1U) +#define PSRAM_UHS_TEN_UHS_PHY_DIG_MSK (((1U << PSRAM_UHS_TEN_UHS_PHY_DIG_LEN) - 1) << PSRAM_UHS_TEN_UHS_PHY_DIG_POS) +#define PSRAM_UHS_TEN_UHS_PHY_DIG_UMSK (~(((1U << PSRAM_UHS_TEN_UHS_PHY_DIG_LEN) - 1) << PSRAM_UHS_TEN_UHS_PHY_DIG_POS)) +#define PSRAM_UHS_TX_CLKTREE_GATE_HW PSRAM_UHS_TX_CLKTREE_GATE_HW +#define PSRAM_UHS_TX_CLKTREE_GATE_HW_POS (29U) +#define PSRAM_UHS_TX_CLKTREE_GATE_HW_LEN (1U) +#define PSRAM_UHS_TX_CLKTREE_GATE_HW_MSK (((1U << PSRAM_UHS_TX_CLKTREE_GATE_HW_LEN) - 1) << PSRAM_UHS_TX_CLKTREE_GATE_HW_POS) +#define PSRAM_UHS_TX_CLKTREE_GATE_HW_UMSK (~(((1U << PSRAM_UHS_TX_CLKTREE_GATE_HW_LEN) - 1) << PSRAM_UHS_TX_CLKTREE_GATE_HW_POS)) +#define PSRAM_UHS_UHS_DC_TP_OUT_EN PSRAM_UHS_UHS_DC_TP_OUT_EN +#define PSRAM_UHS_UHS_DC_TP_OUT_EN_POS (30U) +#define PSRAM_UHS_UHS_DC_TP_OUT_EN_LEN (1U) +#define PSRAM_UHS_UHS_DC_TP_OUT_EN_MSK (((1U << PSRAM_UHS_UHS_DC_TP_OUT_EN_LEN) - 1) << PSRAM_UHS_UHS_DC_TP_OUT_EN_POS) +#define PSRAM_UHS_UHS_DC_TP_OUT_EN_UMSK (~(((1U << PSRAM_UHS_UHS_DC_TP_OUT_EN_LEN) - 1) << PSRAM_UHS_UHS_DC_TP_OUT_EN_POS)) +#define PSRAM_UHS_UHS_PHY_DQS_DIFF PSRAM_UHS_UHS_PHY_DQS_DIFF +#define PSRAM_UHS_UHS_PHY_DQS_DIFF_POS (31U) +#define PSRAM_UHS_UHS_PHY_DQS_DIFF_LEN (1U) +#define PSRAM_UHS_UHS_PHY_DQS_DIFF_MSK (((1U << PSRAM_UHS_UHS_PHY_DQS_DIFF_LEN) - 1) << PSRAM_UHS_UHS_PHY_DQS_DIFF_POS) +#define PSRAM_UHS_UHS_PHY_DQS_DIFF_UMSK (~(((1U << PSRAM_UHS_UHS_PHY_DQS_DIFF_LEN) - 1) << PSRAM_UHS_UHS_PHY_DQS_DIFF_POS)) + +/* 0x144 : phy_cfg_44 */ +#define PSRAM_UHS_PHY_CFG_44_OFFSET (0x144) +#define PSRAM_UHS_REG_TIMER_ARRAY_READ_BUSY PSRAM_UHS_REG_TIMER_ARRAY_READ_BUSY +#define PSRAM_UHS_REG_TIMER_ARRAY_READ_BUSY_POS (0U) +#define PSRAM_UHS_REG_TIMER_ARRAY_READ_BUSY_LEN (8U) +#define PSRAM_UHS_REG_TIMER_ARRAY_READ_BUSY_MSK (((1U << PSRAM_UHS_REG_TIMER_ARRAY_READ_BUSY_LEN) - 1) << PSRAM_UHS_REG_TIMER_ARRAY_READ_BUSY_POS) +#define PSRAM_UHS_REG_TIMER_ARRAY_READ_BUSY_UMSK (~(((1U << PSRAM_UHS_REG_TIMER_ARRAY_READ_BUSY_LEN) - 1) << PSRAM_UHS_REG_TIMER_ARRAY_READ_BUSY_POS)) +#define PSRAM_UHS_REG_TIMER_ARRAY_WRITE_BUSY PSRAM_UHS_REG_TIMER_ARRAY_WRITE_BUSY +#define PSRAM_UHS_REG_TIMER_ARRAY_WRITE_BUSY_POS (8U) +#define PSRAM_UHS_REG_TIMER_ARRAY_WRITE_BUSY_LEN (8U) +#define PSRAM_UHS_REG_TIMER_ARRAY_WRITE_BUSY_MSK (((1U << PSRAM_UHS_REG_TIMER_ARRAY_WRITE_BUSY_LEN) - 1) << PSRAM_UHS_REG_TIMER_ARRAY_WRITE_BUSY_POS) +#define PSRAM_UHS_REG_TIMER_ARRAY_WRITE_BUSY_UMSK (~(((1U << PSRAM_UHS_REG_TIMER_ARRAY_WRITE_BUSY_LEN) - 1) << PSRAM_UHS_REG_TIMER_ARRAY_WRITE_BUSY_POS)) +#define PSRAM_UHS_REG_TIMER_REG_READ_BUSY PSRAM_UHS_REG_TIMER_REG_READ_BUSY +#define PSRAM_UHS_REG_TIMER_REG_READ_BUSY_POS (16U) +#define PSRAM_UHS_REG_TIMER_REG_READ_BUSY_LEN (8U) +#define PSRAM_UHS_REG_TIMER_REG_READ_BUSY_MSK (((1U << PSRAM_UHS_REG_TIMER_REG_READ_BUSY_LEN) - 1) << PSRAM_UHS_REG_TIMER_REG_READ_BUSY_POS) +#define PSRAM_UHS_REG_TIMER_REG_READ_BUSY_UMSK (~(((1U << PSRAM_UHS_REG_TIMER_REG_READ_BUSY_LEN) - 1) << PSRAM_UHS_REG_TIMER_REG_READ_BUSY_POS)) +#define PSRAM_UHS_REG_TIMER_REG_WRITE_BUSY PSRAM_UHS_REG_TIMER_REG_WRITE_BUSY +#define PSRAM_UHS_REG_TIMER_REG_WRITE_BUSY_POS (24U) +#define PSRAM_UHS_REG_TIMER_REG_WRITE_BUSY_LEN (8U) +#define PSRAM_UHS_REG_TIMER_REG_WRITE_BUSY_MSK (((1U << PSRAM_UHS_REG_TIMER_REG_WRITE_BUSY_LEN) - 1) << PSRAM_UHS_REG_TIMER_REG_WRITE_BUSY_POS) +#define PSRAM_UHS_REG_TIMER_REG_WRITE_BUSY_UMSK (~(((1U << PSRAM_UHS_REG_TIMER_REG_WRITE_BUSY_LEN) - 1) << PSRAM_UHS_REG_TIMER_REG_WRITE_BUSY_POS)) + +/* 0x148 : phy_cfg_48 */ +#define PSRAM_UHS_PHY_CFG_48_OFFSET (0x148) +#define PSRAM_UHS_TMUX PSRAM_UHS_TMUX +#define PSRAM_UHS_TMUX_POS (0U) +#define PSRAM_UHS_TMUX_LEN (3U) +#define PSRAM_UHS_TMUX_MSK (((1U << PSRAM_UHS_TMUX_LEN) - 1) << PSRAM_UHS_TMUX_POS) +#define PSRAM_UHS_TMUX_UMSK (~(((1U << PSRAM_UHS_TMUX_LEN) - 1) << PSRAM_UHS_TMUX_POS)) +#define PSRAM_UHS_CHIP_EN_33 PSRAM_UHS_CHIP_EN_33 +#define PSRAM_UHS_CHIP_EN_33_POS (3U) +#define PSRAM_UHS_CHIP_EN_33_LEN (1U) +#define PSRAM_UHS_CHIP_EN_33_MSK (((1U << PSRAM_UHS_CHIP_EN_33_LEN) - 1) << PSRAM_UHS_CHIP_EN_33_POS) +#define PSRAM_UHS_CHIP_EN_33_UMSK (~(((1U << PSRAM_UHS_CHIP_EN_33_LEN) - 1) << PSRAM_UHS_CHIP_EN_33_POS)) +#define PSRAM_UHS_TMUX_UHS_PHY_DIG PSRAM_UHS_TMUX_UHS_PHY_DIG +#define PSRAM_UHS_TMUX_UHS_PHY_DIG_POS (4U) +#define PSRAM_UHS_TMUX_UHS_PHY_DIG_LEN (3U) +#define PSRAM_UHS_TMUX_UHS_PHY_DIG_MSK (((1U << PSRAM_UHS_TMUX_UHS_PHY_DIG_LEN) - 1) << PSRAM_UHS_TMUX_UHS_PHY_DIG_POS) +#define PSRAM_UHS_TMUX_UHS_PHY_DIG_UMSK (~(((1U << PSRAM_UHS_TMUX_UHS_PHY_DIG_LEN) - 1) << PSRAM_UHS_TMUX_UHS_PHY_DIG_POS)) +#define PSRAM_UHS_PSRAM_TYPE PSRAM_UHS_PSRAM_TYPE +#define PSRAM_UHS_PSRAM_TYPE_POS (8U) +#define PSRAM_UHS_PSRAM_TYPE_LEN (2U) +#define PSRAM_UHS_PSRAM_TYPE_MSK (((1U << PSRAM_UHS_PSRAM_TYPE_LEN) - 1) << PSRAM_UHS_PSRAM_TYPE_POS) +#define PSRAM_UHS_PSRAM_TYPE_UMSK (~(((1U << PSRAM_UHS_PSRAM_TYPE_LEN) - 1) << PSRAM_UHS_PSRAM_TYPE_POS)) +#define PSRAM_UHS_PU_UHS_PW1P8 PSRAM_UHS_PU_UHS_PW1P8 +#define PSRAM_UHS_PU_UHS_PW1P8_POS (11U) +#define PSRAM_UHS_PU_UHS_PW1P8_LEN (1U) +#define PSRAM_UHS_PU_UHS_PW1P8_MSK (((1U << PSRAM_UHS_PU_UHS_PW1P8_LEN) - 1) << PSRAM_UHS_PU_UHS_PW1P8_POS) +#define PSRAM_UHS_PU_UHS_PW1P8_UMSK (~(((1U << PSRAM_UHS_PU_UHS_PW1P8_LEN) - 1) << PSRAM_UHS_PU_UHS_PW1P8_POS)) +#define PSRAM_UHS_REG_TEST_DIV_SEL PSRAM_UHS_REG_TEST_DIV_SEL +#define PSRAM_UHS_REG_TEST_DIV_SEL_POS (12U) +#define PSRAM_UHS_REG_TEST_DIV_SEL_LEN (3U) +#define PSRAM_UHS_REG_TEST_DIV_SEL_MSK (((1U << PSRAM_UHS_REG_TEST_DIV_SEL_LEN) - 1) << PSRAM_UHS_REG_TEST_DIV_SEL_POS) +#define PSRAM_UHS_REG_TEST_DIV_SEL_UMSK (~(((1U << PSRAM_UHS_REG_TEST_DIV_SEL_LEN) - 1) << PSRAM_UHS_REG_TEST_DIV_SEL_POS)) +#define PSRAM_UHS_EN_RX_FE_HW PSRAM_UHS_EN_RX_FE_HW +#define PSRAM_UHS_EN_RX_FE_HW_POS (15U) +#define PSRAM_UHS_EN_RX_FE_HW_LEN (1U) +#define PSRAM_UHS_EN_RX_FE_HW_MSK (((1U << PSRAM_UHS_EN_RX_FE_HW_LEN) - 1) << PSRAM_UHS_EN_RX_FE_HW_POS) +#define PSRAM_UHS_EN_RX_FE_HW_UMSK (~(((1U << PSRAM_UHS_EN_RX_FE_HW_LEN) - 1) << PSRAM_UHS_EN_RX_FE_HW_POS)) +#define PSRAM_UHS_REG_TEST_MUX_SEL PSRAM_UHS_REG_TEST_MUX_SEL +#define PSRAM_UHS_REG_TEST_MUX_SEL_POS (16U) +#define PSRAM_UHS_REG_TEST_MUX_SEL_LEN (3U) +#define PSRAM_UHS_REG_TEST_MUX_SEL_MSK (((1U << PSRAM_UHS_REG_TEST_MUX_SEL_LEN) - 1) << PSRAM_UHS_REG_TEST_MUX_SEL_POS) +#define PSRAM_UHS_REG_TEST_MUX_SEL_UMSK (~(((1U << PSRAM_UHS_REG_TEST_MUX_SEL_LEN) - 1) << PSRAM_UHS_REG_TEST_MUX_SEL_POS)) +#define PSRAM_UHS_FORCE_FSM PSRAM_UHS_FORCE_FSM +#define PSRAM_UHS_FORCE_FSM_POS (19U) +#define PSRAM_UHS_FORCE_FSM_LEN (1U) +#define PSRAM_UHS_FORCE_FSM_MSK (((1U << PSRAM_UHS_FORCE_FSM_LEN) - 1) << PSRAM_UHS_FORCE_FSM_POS) +#define PSRAM_UHS_FORCE_FSM_UMSK (~(((1U << PSRAM_UHS_FORCE_FSM_LEN) - 1) << PSRAM_UHS_FORCE_FSM_POS)) +#define PSRAM_UHS_EN_RX_FE_DLY PSRAM_UHS_EN_RX_FE_DLY +#define PSRAM_UHS_EN_RX_FE_DLY_POS (20U) +#define PSRAM_UHS_EN_RX_FE_DLY_LEN (4U) +#define PSRAM_UHS_EN_RX_FE_DLY_MSK (((1U << PSRAM_UHS_EN_RX_FE_DLY_LEN) - 1) << PSRAM_UHS_EN_RX_FE_DLY_POS) +#define PSRAM_UHS_EN_RX_FE_DLY_UMSK (~(((1U << PSRAM_UHS_EN_RX_FE_DLY_LEN) - 1) << PSRAM_UHS_EN_RX_FE_DLY_POS)) + +/* 0x14C : phy_cfg_4C */ +#define PSRAM_UHS_PHY_CFG_4C_OFFSET (0x14C) +#define PSRAM_UHS_TOUT_UHS_PHY_DIG PSRAM_UHS_TOUT_UHS_PHY_DIG +#define PSRAM_UHS_TOUT_UHS_PHY_DIG_POS (0U) +#define PSRAM_UHS_TOUT_UHS_PHY_DIG_LEN (16U) +#define PSRAM_UHS_TOUT_UHS_PHY_DIG_MSK (((1U << PSRAM_UHS_TOUT_UHS_PHY_DIG_LEN) - 1) << PSRAM_UHS_TOUT_UHS_PHY_DIG_POS) +#define PSRAM_UHS_TOUT_UHS_PHY_DIG_UMSK (~(((1U << PSRAM_UHS_TOUT_UHS_PHY_DIG_LEN) - 1) << PSRAM_UHS_TOUT_UHS_PHY_DIG_POS)) +#define PSRAM_UHS_ODT_SEL_DLY PSRAM_UHS_ODT_SEL_DLY +#define PSRAM_UHS_ODT_SEL_DLY_POS (16U) +#define PSRAM_UHS_ODT_SEL_DLY_LEN (4U) +#define PSRAM_UHS_ODT_SEL_DLY_MSK (((1U << PSRAM_UHS_ODT_SEL_DLY_LEN) - 1) << PSRAM_UHS_ODT_SEL_DLY_POS) +#define PSRAM_UHS_ODT_SEL_DLY_UMSK (~(((1U << PSRAM_UHS_ODT_SEL_DLY_LEN) - 1) << PSRAM_UHS_ODT_SEL_DLY_POS)) +#define PSRAM_UHS_ODT_SEL_HW PSRAM_UHS_ODT_SEL_HW +#define PSRAM_UHS_ODT_SEL_HW_POS (20U) +#define PSRAM_UHS_ODT_SEL_HW_LEN (1U) +#define PSRAM_UHS_ODT_SEL_HW_MSK (((1U << PSRAM_UHS_ODT_SEL_HW_LEN) - 1) << PSRAM_UHS_ODT_SEL_HW_POS) +#define PSRAM_UHS_ODT_SEL_HW_UMSK (~(((1U << PSRAM_UHS_ODT_SEL_HW_LEN) - 1) << PSRAM_UHS_ODT_SEL_HW_POS)) + +/* 0x150 : phy_cfg_50 */ +#define PSRAM_UHS_PHY_CFG_50_OFFSET (0x150) +#define PSRAM_UHS_DQ_OE_UP_P_REG PSRAM_UHS_DQ_OE_UP_P_REG +#define PSRAM_UHS_DQ_OE_UP_P_REG_POS (0U) +#define PSRAM_UHS_DQ_OE_UP_P_REG_LEN (3U) +#define PSRAM_UHS_DQ_OE_UP_P_REG_MSK (((1U << PSRAM_UHS_DQ_OE_UP_P_REG_LEN) - 1) << PSRAM_UHS_DQ_OE_UP_P_REG_POS) +#define PSRAM_UHS_DQ_OE_UP_P_REG_UMSK (~(((1U << PSRAM_UHS_DQ_OE_UP_P_REG_LEN) - 1) << PSRAM_UHS_DQ_OE_UP_P_REG_POS)) +#define PSRAM_UHS_DQ_OE_UP_N_REG PSRAM_UHS_DQ_OE_UP_N_REG +#define PSRAM_UHS_DQ_OE_UP_N_REG_POS (4U) +#define PSRAM_UHS_DQ_OE_UP_N_REG_LEN (3U) +#define PSRAM_UHS_DQ_OE_UP_N_REG_MSK (((1U << PSRAM_UHS_DQ_OE_UP_N_REG_LEN) - 1) << PSRAM_UHS_DQ_OE_UP_N_REG_POS) +#define PSRAM_UHS_DQ_OE_UP_N_REG_UMSK (~(((1U << PSRAM_UHS_DQ_OE_UP_N_REG_LEN) - 1) << PSRAM_UHS_DQ_OE_UP_N_REG_POS)) +#define PSRAM_UHS_DQ_OE_MID_P_REG PSRAM_UHS_DQ_OE_MID_P_REG +#define PSRAM_UHS_DQ_OE_MID_P_REG_POS (8U) +#define PSRAM_UHS_DQ_OE_MID_P_REG_LEN (3U) +#define PSRAM_UHS_DQ_OE_MID_P_REG_MSK (((1U << PSRAM_UHS_DQ_OE_MID_P_REG_LEN) - 1) << PSRAM_UHS_DQ_OE_MID_P_REG_POS) +#define PSRAM_UHS_DQ_OE_MID_P_REG_UMSK (~(((1U << PSRAM_UHS_DQ_OE_MID_P_REG_LEN) - 1) << PSRAM_UHS_DQ_OE_MID_P_REG_POS)) +#define PSRAM_UHS_DQ_OE_MID_N_REG PSRAM_UHS_DQ_OE_MID_N_REG +#define PSRAM_UHS_DQ_OE_MID_N_REG_POS (12U) +#define PSRAM_UHS_DQ_OE_MID_N_REG_LEN (3U) +#define PSRAM_UHS_DQ_OE_MID_N_REG_MSK (((1U << PSRAM_UHS_DQ_OE_MID_N_REG_LEN) - 1) << PSRAM_UHS_DQ_OE_MID_N_REG_POS) +#define PSRAM_UHS_DQ_OE_MID_N_REG_UMSK (~(((1U << PSRAM_UHS_DQ_OE_MID_N_REG_LEN) - 1) << PSRAM_UHS_DQ_OE_MID_N_REG_POS)) +#define PSRAM_UHS_DQ_OE_DN_P_REG PSRAM_UHS_DQ_OE_DN_P_REG +#define PSRAM_UHS_DQ_OE_DN_P_REG_POS (16U) +#define PSRAM_UHS_DQ_OE_DN_P_REG_LEN (3U) +#define PSRAM_UHS_DQ_OE_DN_P_REG_MSK (((1U << PSRAM_UHS_DQ_OE_DN_P_REG_LEN) - 1) << PSRAM_UHS_DQ_OE_DN_P_REG_POS) +#define PSRAM_UHS_DQ_OE_DN_P_REG_UMSK (~(((1U << PSRAM_UHS_DQ_OE_DN_P_REG_LEN) - 1) << PSRAM_UHS_DQ_OE_DN_P_REG_POS)) +#define PSRAM_UHS_DQ_OE_DN_N_REG PSRAM_UHS_DQ_OE_DN_N_REG +#define PSRAM_UHS_DQ_OE_DN_N_REG_POS (20U) +#define PSRAM_UHS_DQ_OE_DN_N_REG_LEN (3U) +#define PSRAM_UHS_DQ_OE_DN_N_REG_MSK (((1U << PSRAM_UHS_DQ_OE_DN_N_REG_LEN) - 1) << PSRAM_UHS_DQ_OE_DN_N_REG_POS) +#define PSRAM_UHS_DQ_OE_DN_N_REG_UMSK (~(((1U << PSRAM_UHS_DQ_OE_DN_N_REG_LEN) - 1) << PSRAM_UHS_DQ_OE_DN_N_REG_POS)) +#define PSRAM_UHS_PHY_WL_CEN_ANA PSRAM_UHS_PHY_WL_CEN_ANA +#define PSRAM_UHS_PHY_WL_CEN_ANA_POS (24U) +#define PSRAM_UHS_PHY_WL_CEN_ANA_LEN (3U) +#define PSRAM_UHS_PHY_WL_CEN_ANA_MSK (((1U << PSRAM_UHS_PHY_WL_CEN_ANA_LEN) - 1) << PSRAM_UHS_PHY_WL_CEN_ANA_POS) +#define PSRAM_UHS_PHY_WL_CEN_ANA_UMSK (~(((1U << PSRAM_UHS_PHY_WL_CEN_ANA_LEN) - 1) << PSRAM_UHS_PHY_WL_CEN_ANA_POS)) + +struct psram_uhs_reg { + /* 0x0 : UHS_basic */ + union { + struct { + uint32_t reg_init_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_af_en : 1; /* [ 1], r/w, 0x0 */ + uint32_t reg_config_req : 1; /* [ 2], r/w, 0x0 */ + uint32_t reg_config_gnt : 1; /* [ 3], r, 0x0 */ + uint32_t reserved_4_7 : 4; /* [ 7: 4], rsvd, 0x0 */ + uint32_t reg_mode_reg : 8; /* [15: 8], r/w, 0x0 */ + uint32_t reg_addrMB_msk : 8; /* [23:16], r/w, 0x1f */ + uint32_t reserved_24_27 : 4; /* [27:24], rsvd, 0x0 */ + uint32_t reg_linear_bnd_b : 4; /* [31:28], r/w, 0xa */ + } BF; + uint32_t WORD; + } UHS_basic; + + /* 0x4 : UHS_cmd */ + union { + struct { + uint32_t reg_glbr_pulse : 1; /* [ 0], w1p, 0x0 */ + uint32_t reg_srfi_pulse : 1; /* [ 1], w1p, 0x0 */ + uint32_t reg_srfo_pulse : 1; /* [ 2], w1p, 0x0 */ + uint32_t reg_regw_pulse : 1; /* [ 3], w1p, 0x0 */ + uint32_t reg_regr_pulse : 1; /* [ 4], w1p, 0x0 */ + uint32_t reserved_5_7 : 3; /* [ 7: 5], rsvd, 0x0 */ + uint32_t sts_glbr_done : 1; /* [ 8], r, 0x0 */ + uint32_t sts_srfi_done : 1; /* [ 9], r, 0x0 */ + uint32_t sts_srfo_done : 1; /* [ 10], r, 0x0 */ + uint32_t sts_regw_done : 1; /* [ 11], r, 0x0 */ + uint32_t sts_regr_done : 1; /* [ 12], r, 0x0 */ + uint32_t sts_init_done : 1; /* [ 13], r, 0x0 */ + uint32_t reserved_14_23 : 10; /* [23:14], rsvd, 0x0 */ + uint32_t sts_config_read : 8; /* [31:24], r, 0x0 */ + } BF; + uint32_t WORD; + } UHS_cmd; + + /* 0x8 : UHS_fifo_thre */ + union { + struct { + uint32_t reg_mask_w_fifo_cnt : 16; /* [15: 0], r/w, 0x0 */ + uint32_t reg_mask_r_fifo_rem : 16; /* [31:16], r/w, 0x0 */ + } BF; + uint32_t WORD; + } UHS_fifo_thre; + + /* 0xC : UHS_manual */ + union { + struct { + uint32_t reg_force_ceb_low : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_force_ceb_high : 1; /* [ 1], r/w, 0x0 */ + uint32_t reg_psram_resetb : 1; /* [ 2], r/w, 0x1 */ + uint32_t reg_x16_mode : 1; /* [ 3], r/w, 0x1 */ + uint32_t reg_wrap2incr_en : 1; /* [ 4], r/w, 0x1 */ + uint32_t reserved_5_15 : 11; /* [15: 5], rsvd, 0x0 */ + uint32_t reg_pck_s_div : 3; /* [18:16], r/w, 0x0 */ + uint32_t reserved_19_23 : 5; /* [23:19], rsvd, 0x0 */ + uint32_t reg_pck_t_div : 8; /* [31:24], r/w, 0x40 */ + } BF; + uint32_t WORD; + } UHS_manual; + + /* 0x10 : UHS_auto_fresh_1 */ + union { + struct { + uint32_t reg_win_cycle : 28; /* [27: 0], r/w, 0x27100 */ + uint32_t reserved_28_31 : 4; /* [31:28], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } UHS_auto_fresh_1; + + /* 0x14 : UHS_auto_fresh_2 */ + union { + struct { + uint32_t reg_refi_cycle : 16; /* [15: 0], r/w, 0x27 */ + uint32_t reg_win_ref_cnt : 13; /* [28:16], r/w, 0x1000 */ + uint32_t reserved_29_31 : 3; /* [31:29], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } UHS_auto_fresh_2; + + /* 0x18 : UHS_auto_fresh_3 */ + union { + struct { + uint32_t reg_auto_ref_thre : 12; /* [11: 0], r/w, 0x0 */ + uint32_t reserved_12_15 : 4; /* [15:12], rsvd, 0x0 */ + uint32_t auto_refresh_level : 12; /* [27:16], r, 0x0 */ + uint32_t reserved_28_31 : 4; /* [31:28], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } UHS_auto_fresh_3; + + /* 0x1C : UHS_auto_fresh_4 */ + union { + struct { + uint32_t reg_bust_cycle : 7; /* [ 6: 0], r/w, 0x1d */ + uint32_t reserved_7_31 : 25; /* [31: 7], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } UHS_auto_fresh_4; + + /* 0x20 : UHS_psram_configure */ + union { + struct { + uint32_t reg_uhs_latency : 3; /* [ 2: 0], r/w, 0x5 */ + uint32_t reserved_3 : 1; /* [ 3], rsvd, 0x0 */ + uint32_t reg_uhs_drive_st : 4; /* [ 7: 4], r/w, 0xa */ + uint32_t reg_uhs_bl_16 : 1; /* [ 8], r/w, 0x0 */ + uint32_t reg_uhs_bl_32 : 1; /* [ 9], r/w, 0x0 */ + uint32_t reg_uhs_bl_64 : 1; /* [ 10], r/w, 0x0 */ + uint32_t reserved_11_31 : 21; /* [31:11], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } UHS_psram_configure; + + /* 0x24 : UHS_psram_status */ + union { + struct { + uint32_t sts_uhs_latency : 3; /* [ 2: 0], r, 0x5 */ + uint32_t reserved_3 : 1; /* [ 3], rsvd, 0x0 */ + uint32_t sts_uhs_drive_st : 4; /* [ 7: 4], r, 0xa */ + uint32_t sts_uhs_bl_16 : 1; /* [ 8], r, 0x0 */ + uint32_t sts_uhs_bl_32 : 1; /* [ 9], r, 0x0 */ + uint32_t sts_uhs_bl_64 : 1; /* [ 10], r, 0x0 */ + uint32_t reserved_11_31 : 21; /* [31:11], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } UHS_psram_status; + + /* 0x28 reserved */ + uint8_t RESERVED0x28[8]; + + /* 0x30 : UHS_timing_ctrl */ + union { + struct { + uint32_t reg_trc_cycle : 8; /* [ 7: 0], r/w, 0x0 */ + uint32_t reg_tcphr_cycle : 8; /* [15: 8], r/w, 0x0 */ + uint32_t reg_tcphw_cycle : 8; /* [23:16], r/w, 0x0 */ + uint32_t reg_trfc_cycle : 8; /* [31:24], r/w, 0x0 */ + } BF; + uint32_t WORD; + } UHS_timing_ctrl; + + /* 0x34 : UHS_rsvd_reg */ + union { + struct { + uint32_t reg_mr0_7 : 1; /* [ 0], r/w, 0x0 */ + uint32_t reg_mr2_2_0 : 3; /* [ 3: 1], r/w, 0x0 */ + uint32_t reg_mr2_7_6 : 2; /* [ 5: 4], r/w, 0x0 */ + uint32_t reserved_6_31 : 26; /* [31: 6], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } UHS_rsvd_reg; + + /* 0x38 reserved */ + uint8_t RESERVED0x38[136]; + + /* 0xC0 : UHS_dbg_sel */ + union { + struct { + uint32_t reg_psram_dbg_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t reserved_1_3 : 3; /* [ 3: 1], rsvd, 0x0 */ + uint32_t reg_psram_dbg_sel : 4; /* [ 7: 4], r/w, 0x0 */ + uint32_t reserved_8_31 : 24; /* [31: 8], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } UHS_dbg_sel; + + /* 0xc4 reserved */ + uint8_t RESERVED0xc4[44]; + + /* 0xF0 : UHS_dummy_reg */ + union { + struct { + uint32_t reg_psram_dummy_reg : 32; /* [31: 0], r/w, 0xffff0000 */ + } BF; + uint32_t WORD; + } UHS_dummy_reg; + + /* 0xf4 reserved */ + uint8_t RESERVED0xf4[12]; + + /* 0x100 : phy_cfg_00 */ + union { + struct { + uint32_t dqs_rdy : 1; /* [ 0], r, 0x0 */ + uint32_t reserved_1_7 : 7; /* [ 7: 1], rsvd, 0x0 */ + uint32_t ck_sr : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reserved_10_14 : 5; /* [14:10], rsvd, 0x0 */ + uint32_t clk0_polarity : 1; /* [ 15], r/w, 0x0 */ + uint32_t ck_dly_drv : 4; /* [19:16], r/w, 0x8 */ + uint32_t cen_sr : 2; /* [21:20], r/w, 0x0 */ + uint32_t reserved_22_27 : 6; /* [27:22], rsvd, 0x0 */ + uint32_t cen_dly_drv : 4; /* [31:28], r/w, 0x8 */ + } BF; + uint32_t WORD; + } phy_cfg_00; + + /* 0x104 : phy_cfg_04 */ + union { + struct { + uint32_t reserved_0_3 : 4; /* [ 3: 0], rsvd, 0x0 */ + uint32_t dm1_sr : 2; /* [ 5: 4], r/w, 0x0 */ + uint32_t reserved_6_11 : 6; /* [11: 6], rsvd, 0x0 */ + uint32_t dm1_dly_drv : 4; /* [15:12], r/w, 0x8 */ + uint32_t reserved_16_19 : 4; /* [19:16], rsvd, 0x0 */ + uint32_t dm0_sr : 2; /* [21:20], r/w, 0x0 */ + uint32_t reserved_22_27 : 6; /* [27:22], rsvd, 0x0 */ + uint32_t dm0_dly_drv : 4; /* [31:28], r/w, 0x8 */ + } BF; + uint32_t WORD; + } phy_cfg_04; + + /* 0x108 : phy_cfg_08 */ + union { + struct { + uint32_t dq1_sr : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t dq1_dly_rx : 4; /* [11: 8], r/w, 0x1 */ + uint32_t dq1_dly_drv : 4; /* [15:12], r/w, 0x8 */ + uint32_t dq0_sr : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_23 : 6; /* [23:18], rsvd, 0x0 */ + uint32_t dq0_dly_rx : 4; /* [27:24], r/w, 0x1 */ + uint32_t dq0_dly_drv : 4; /* [31:28], r/w, 0x8 */ + } BF; + uint32_t WORD; + } phy_cfg_08; + + /* 0x10C : phy_cfg_0C */ + union { + struct { + uint32_t dq3_sr : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t dq3_dly_rx : 4; /* [11: 8], r/w, 0x1 */ + uint32_t dq3_dly_drv : 4; /* [15:12], r/w, 0x8 */ + uint32_t dq2_sr : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_23 : 6; /* [23:18], rsvd, 0x0 */ + uint32_t dq2_dly_rx : 4; /* [27:24], r/w, 0x1 */ + uint32_t dq2_dly_drv : 4; /* [31:28], r/w, 0x8 */ + } BF; + uint32_t WORD; + } phy_cfg_0C; + + /* 0x110 : phy_cfg_10 */ + union { + struct { + uint32_t dq5_sr : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t dq5_dly_rx : 4; /* [11: 8], r/w, 0x1 */ + uint32_t dq5_dly_drv : 4; /* [15:12], r/w, 0x8 */ + uint32_t dq4_sr : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_23 : 6; /* [23:18], rsvd, 0x0 */ + uint32_t dq4_dly_rx : 4; /* [27:24], r/w, 0x1 */ + uint32_t dq4_dly_drv : 4; /* [31:28], r/w, 0x8 */ + } BF; + uint32_t WORD; + } phy_cfg_10; + + /* 0x114 : phy_cfg_14 */ + union { + struct { + uint32_t dq7_sr : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t dq7_dly_rx : 4; /* [11: 8], r/w, 0x1 */ + uint32_t dq7_dly_drv : 4; /* [15:12], r/w, 0x8 */ + uint32_t dq6_sr : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_23 : 6; /* [23:18], rsvd, 0x0 */ + uint32_t dq6_dly_rx : 4; /* [27:24], r/w, 0x1 */ + uint32_t dq6_dly_drv : 4; /* [31:28], r/w, 0x8 */ + } BF; + uint32_t WORD; + } phy_cfg_14; + + /* 0x118 : phy_cfg_18 */ + union { + struct { + uint32_t dq9_sr : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t dq9_dly_rx : 4; /* [11: 8], r/w, 0x1 */ + uint32_t dq9_dly_drv : 4; /* [15:12], r/w, 0x8 */ + uint32_t dq8_sr : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_23 : 6; /* [23:18], rsvd, 0x0 */ + uint32_t dq8_dly_rx : 4; /* [27:24], r/w, 0x1 */ + uint32_t dq8_dly_drv : 4; /* [31:28], r/w, 0x8 */ + } BF; + uint32_t WORD; + } phy_cfg_18; + + /* 0x11C : phy_cfg_1C */ + union { + struct { + uint32_t dq11_sr : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t dq11_dly_rx : 4; /* [11: 8], r/w, 0x1 */ + uint32_t dq11_dly_drv : 4; /* [15:12], r/w, 0x8 */ + uint32_t dq10_sr : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_23 : 6; /* [23:18], rsvd, 0x0 */ + uint32_t dq10_dly_rx : 4; /* [27:24], r/w, 0x1 */ + uint32_t dq10_dly_drv : 4; /* [31:28], r/w, 0x8 */ + } BF; + uint32_t WORD; + } phy_cfg_1C; + + /* 0x120 : phy_cfg_20 */ + union { + struct { + uint32_t dq13_sr : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t dq13_dly_rx : 4; /* [11: 8], r/w, 0x1 */ + uint32_t dq13_dly_drv : 4; /* [15:12], r/w, 0x8 */ + uint32_t dq12_sr : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_23 : 6; /* [23:18], rsvd, 0x0 */ + uint32_t dq12_dly_rx : 4; /* [27:24], r/w, 0x1 */ + uint32_t dq12_dly_drv : 4; /* [31:28], r/w, 0x8 */ + } BF; + uint32_t WORD; + } phy_cfg_20; + + /* 0x124 : phy_cfg_24 */ + union { + struct { + uint32_t dq15_sr : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t dq15_dly_rx : 4; /* [11: 8], r/w, 0x1 */ + uint32_t dq15_dly_drv : 4; /* [15:12], r/w, 0x8 */ + uint32_t dq14_sr : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_23 : 6; /* [23:18], rsvd, 0x0 */ + uint32_t dq14_dly_rx : 4; /* [27:24], r/w, 0x1 */ + uint32_t dq14_dly_drv : 4; /* [31:28], r/w, 0x8 */ + } BF; + uint32_t WORD; + } phy_cfg_24; + + /* 0x128 : phy_cfg_28 */ + union { + struct { + uint32_t reserved_0_7 : 8; /* [ 7: 0], rsvd, 0x0 */ + uint32_t dqs0n_dly_rx : 4; /* [11: 8], r/w, 0x3 */ + uint32_t dqs0_sr : 2; /* [13:12], r/w, 0x0 */ + uint32_t dqs0_sel : 2; /* [15:14], r/w, 0x0 */ + uint32_t reserved_16_19 : 4; /* [19:16], rsvd, 0x0 */ + uint32_t dqs0_dly_rx : 4; /* [23:20], r/w, 0x3 */ + uint32_t dqs0_dly_drv : 4; /* [27:24], r/w, 0x8 */ + uint32_t dqs0_diff_dly_rx : 4; /* [31:28], r/w, 0x3 */ + } BF; + uint32_t WORD; + } phy_cfg_28; + + /* 0x12C : phy_cfg_2C */ + union { + struct { + uint32_t ipp5un_lpddr : 1; /* [ 0], r/w, 0x0 */ + uint32_t en_rx_fe : 1; /* [ 1], r/w, 0x1 */ + uint32_t en_bias : 1; /* [ 2], r/w, 0x1 */ + uint32_t reserved_3_7 : 5; /* [ 7: 3], rsvd, 0x0 */ + uint32_t dqs1n_dly_rx : 4; /* [11: 8], r/w, 0x3 */ + uint32_t dqs1_sr : 2; /* [13:12], r/w, 0x0 */ + uint32_t dqs1_sel : 2; /* [15:14], r/w, 0x0 */ + uint32_t reserved_16_19 : 4; /* [19:16], rsvd, 0x0 */ + uint32_t dqs1_dly_rx : 4; /* [23:20], r/w, 0x3 */ + uint32_t dqs1_dly_drv : 4; /* [27:24], r/w, 0x8 */ + uint32_t dqs1_diff_dly_rx : 4; /* [31:28], r/w, 0x3 */ + } BF; + uint32_t WORD; + } phy_cfg_2C; + + /* 0x130 : phy_cfg_30 */ + union { + struct { + uint32_t phy_wl_dq_dig : 3; /* [ 2: 0], r/w, 0x0 */ + uint32_t reserved_3 : 1; /* [ 3], rsvd, 0x0 */ + uint32_t phy_wl_dq_ana : 3; /* [ 6: 4], r/w, 0x2 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t phy_wl_dig : 3; /* [10: 8], r/w, 0x0 */ + uint32_t reserved_11 : 1; /* [ 11], rsvd, 0x0 */ + uint32_t phy_wl_ana : 3; /* [14:12], r/w, 0x1 */ + uint32_t reserved_15 : 1; /* [ 15], rsvd, 0x0 */ + uint32_t phy_rl_dig : 4; /* [19:16], r/w, 0x3 */ + uint32_t phy_rl_ana : 3; /* [22:20], r/w, 0x3 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t oe_timer : 2; /* [25:24], r/w, 0x2 */ + uint32_t vref_mode : 1; /* [ 26], r/w, 0x0 */ + uint32_t oe_ctrl_hw : 1; /* [ 27], r/w, 0x1 */ + uint32_t odt_sel : 4; /* [31:28], r/w, 0xa */ + } BF; + uint32_t WORD; + } phy_cfg_30; + + /* 0x134 : phy_cfg_34 */ + union { + struct { + uint32_t reg_timer_dqs_start : 8; /* [ 7: 0], r/w, 0x1 */ + uint32_t reg_timer_dqs_array_stop : 8; /* [15: 8], r/w, 0x1 */ + uint32_t reg_timer_array_write : 8; /* [23:16], r/w, 0x0 */ + uint32_t reg_timer_array_read : 8; /* [31:24], r/w, 0x5 */ + } BF; + uint32_t WORD; + } phy_cfg_34; + + /* 0x138 : phy_cfg_38 */ + union { + struct { + uint32_t reg_timer_auto_refresh : 8; /* [ 7: 0], r/w, 0x7 */ + uint32_t reg_timer_reg_write : 8; /* [15: 8], r/w, 0x1 */ + uint32_t reg_timer_reg_read : 8; /* [23:16], r/w, 0x8 */ + uint32_t reg_timer_dqs_stop : 8; /* [31:24], r/w, 0x2 */ + } BF; + uint32_t WORD; + } phy_cfg_38; + + /* 0x13C : phy_cfg_3C */ + union { + struct { + uint32_t reg_timer_self_refresh1_in : 8; /* [ 7: 0], r/w, 0x8 */ + uint32_t reg_timer_self_refresh1_exit : 8; /* [15: 8], r/w, 0x8 */ + uint32_t reg_timer_global_rst : 14; /* [29:16], r/w, 0x272 */ + uint32_t reserved_30_31 : 2; /* [31:30], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } phy_cfg_3C; + + /* 0x140 : phy_cfg_40 */ + union { + struct { + uint32_t vref_sel : 4; /* [ 3: 0], r/w, 0x0 */ + uint32_t vref_dq_sel : 4; /* [ 7: 4], r/w, 0x0 */ + uint32_t reg_uhs_dmy0 : 8; /* [15: 8], r/w, 0x0 */ + uint32_t reg_uhs_dmy1 : 8; /* [23:16], r/w, 0xff */ + uint32_t reg_uhs_phy_ten : 1; /* [ 24], r/w, 0x0 */ + uint32_t soc_en_aon : 1; /* [ 25], r/w, 0x1 */ + uint32_t ten_uhs_phy : 1; /* [ 26], r/w, 0x0 */ + uint32_t ten_uhs_phy_dig : 1; /* [ 27], r/w, 0x0 */ + uint32_t reserved_28 : 1; /* [ 28], rsvd, 0x0 */ + uint32_t tx_clktree_gate_hw : 1; /* [ 29], r/w, 0x1 */ + uint32_t uhs_dc_tp_out_en : 1; /* [ 30], r/w, 0x0 */ + uint32_t uhs_phy_dqs_diff : 1; /* [ 31], r/w, 0x1 */ + } BF; + uint32_t WORD; + } phy_cfg_40; + + /* 0x144 : phy_cfg_44 */ + union { + struct { + uint32_t reg_timer_array_read_busy : 8; /* [ 7: 0], r/w, 0x8 */ + uint32_t reg_timer_array_write_busy : 8; /* [15: 8], r/w, 0x3 */ + uint32_t reg_timer_reg_read_busy : 8; /* [23:16], r/w, 0xb */ + uint32_t reg_timer_reg_write_busy : 8; /* [31:24], r/w, 0x4 */ + } BF; + uint32_t WORD; + } phy_cfg_44; + + /* 0x148 : phy_cfg_48 */ + union { + struct { + uint32_t tmux : 3; /* [ 2: 0], r/w, 0x0 */ + uint32_t chip_en_33 : 1; /* [ 3], r/w, 0x1 */ + uint32_t tmux_uhs_phy_dig : 3; /* [ 6: 4], r/w, 0x0 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t psram_type : 2; /* [ 9: 8], r/w, 0x1 */ + uint32_t reserved_10 : 1; /* [ 10], rsvd, 0x0 */ + uint32_t pu_uhs_pw1p8 : 1; /* [ 11], r/w, 0x1 */ + uint32_t reg_test_div_sel : 3; /* [14:12], r/w, 0x0 */ + uint32_t en_rx_fe_hw : 1; /* [ 15], r/w, 0x1 */ + uint32_t reg_test_mux_sel : 3; /* [18:16], r/w, 0x0 */ + uint32_t force_fsm : 1; /* [ 19], r/w, 0x0 */ + uint32_t en_rx_fe_dly : 4; /* [23:20], r/w, 0x2 */ + uint32_t reserved_24_31 : 8; /* [31:24], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } phy_cfg_48; + + /* 0x14C : phy_cfg_4C */ + union { + struct { + uint32_t tout_uhs_phy_dig : 16; /* [15: 0], r, 0x0 */ + uint32_t odt_sel_dly : 4; /* [19:16], r/w, 0x3 */ + uint32_t odt_sel_hw : 1; /* [ 20], r/w, 0x1 */ + uint32_t reserved_21_31 : 11; /* [31:21], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } phy_cfg_4C; + + /* 0x150 : phy_cfg_50 */ + union { + struct { + uint32_t dq_oe_up_p_reg : 3; /* [ 2: 0], r/w, 0x4 */ + uint32_t reserved_3 : 1; /* [ 3], rsvd, 0x0 */ + uint32_t dq_oe_up_n_reg : 3; /* [ 6: 4], r/w, 0x4 */ + uint32_t reserved_7 : 1; /* [ 7], rsvd, 0x0 */ + uint32_t dq_oe_mid_p_reg : 3; /* [10: 8], r/w, 0x4 */ + uint32_t reserved_11 : 1; /* [ 11], rsvd, 0x0 */ + uint32_t dq_oe_mid_n_reg : 3; /* [14:12], r/w, 0x4 */ + uint32_t reserved_15 : 1; /* [ 15], rsvd, 0x0 */ + uint32_t dq_oe_dn_p_reg : 3; /* [18:16], r/w, 0x4 */ + uint32_t reserved_19 : 1; /* [ 19], rsvd, 0x0 */ + uint32_t dq_oe_dn_n_reg : 3; /* [22:20], r/w, 0x4 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t phy_wl_cen_ana : 3; /* [26:24], r/w, 0x1 */ + uint32_t reserved_27_31 : 5; /* [31:27], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } phy_cfg_50; +}; + +typedef volatile struct psram_uhs_reg psram_uhs_reg_t; + +#endif /* __PSRAM_UHS_REG_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/sf_ctrl_reg.h b/platforms/bl808_m0/vendor/psram/include/sf_ctrl_reg.h new file mode 100644 index 0000000..b9d49c8 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/sf_ctrl_reg.h @@ -0,0 +1,3359 @@ +/** + ****************************************************************************** + * @file sf_ctrl_reg.h + * @version V1.0 + * @date 2021-07-13 + * @brief This file is the description of.IP register + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#ifndef __SF_CTRL_REG_H__ +#define __SF_CTRL_REG_H__ + +#include "bl808.h" + +/* 0x0 : sf_ctrl_0 */ +#define SF_CTRL_0_OFFSET (0x0) +#define SF_CTRL_SF_CLK_SF_RX_INV_SEL SF_CTRL_SF_CLK_SF_RX_INV_SEL +#define SF_CTRL_SF_CLK_SF_RX_INV_SEL_POS (2U) +#define SF_CTRL_SF_CLK_SF_RX_INV_SEL_LEN (1U) +#define SF_CTRL_SF_CLK_SF_RX_INV_SEL_MSK (((1U << SF_CTRL_SF_CLK_SF_RX_INV_SEL_LEN) - 1) << SF_CTRL_SF_CLK_SF_RX_INV_SEL_POS) +#define SF_CTRL_SF_CLK_SF_RX_INV_SEL_UMSK (~(((1U << SF_CTRL_SF_CLK_SF_RX_INV_SEL_LEN) - 1) << SF_CTRL_SF_CLK_SF_RX_INV_SEL_POS)) +#define SF_CTRL_SF_CLK_OUT_GATE_EN SF_CTRL_SF_CLK_OUT_GATE_EN +#define SF_CTRL_SF_CLK_OUT_GATE_EN_POS (3U) +#define SF_CTRL_SF_CLK_OUT_GATE_EN_LEN (1U) +#define SF_CTRL_SF_CLK_OUT_GATE_EN_MSK (((1U << SF_CTRL_SF_CLK_OUT_GATE_EN_LEN) - 1) << SF_CTRL_SF_CLK_OUT_GATE_EN_POS) +#define SF_CTRL_SF_CLK_OUT_GATE_EN_UMSK (~(((1U << SF_CTRL_SF_CLK_OUT_GATE_EN_LEN) - 1) << SF_CTRL_SF_CLK_OUT_GATE_EN_POS)) +#define SF_CTRL_SF_CLK_OUT_INV_SEL SF_CTRL_SF_CLK_OUT_INV_SEL +#define SF_CTRL_SF_CLK_OUT_INV_SEL_POS (4U) +#define SF_CTRL_SF_CLK_OUT_INV_SEL_LEN (1U) +#define SF_CTRL_SF_CLK_OUT_INV_SEL_MSK (((1U << SF_CTRL_SF_CLK_OUT_INV_SEL_LEN) - 1) << SF_CTRL_SF_CLK_OUT_INV_SEL_POS) +#define SF_CTRL_SF_CLK_OUT_INV_SEL_UMSK (~(((1U << SF_CTRL_SF_CLK_OUT_INV_SEL_LEN) - 1) << SF_CTRL_SF_CLK_OUT_INV_SEL_POS)) +#define SF_CTRL_SF_IF_READ_DLY_N SF_CTRL_SF_IF_READ_DLY_N +#define SF_CTRL_SF_IF_READ_DLY_N_POS (8U) +#define SF_CTRL_SF_IF_READ_DLY_N_LEN (3U) +#define SF_CTRL_SF_IF_READ_DLY_N_MSK (((1U << SF_CTRL_SF_IF_READ_DLY_N_LEN) - 1) << SF_CTRL_SF_IF_READ_DLY_N_POS) +#define SF_CTRL_SF_IF_READ_DLY_N_UMSK (~(((1U << SF_CTRL_SF_IF_READ_DLY_N_LEN) - 1) << SF_CTRL_SF_IF_READ_DLY_N_POS)) +#define SF_CTRL_SF_IF_READ_DLY_EN SF_CTRL_SF_IF_READ_DLY_EN +#define SF_CTRL_SF_IF_READ_DLY_EN_POS (11U) +#define SF_CTRL_SF_IF_READ_DLY_EN_LEN (1U) +#define SF_CTRL_SF_IF_READ_DLY_EN_MSK (((1U << SF_CTRL_SF_IF_READ_DLY_EN_LEN) - 1) << SF_CTRL_SF_IF_READ_DLY_EN_POS) +#define SF_CTRL_SF_IF_READ_DLY_EN_UMSK (~(((1U << SF_CTRL_SF_IF_READ_DLY_EN_LEN) - 1) << SF_CTRL_SF_IF_READ_DLY_EN_POS)) +#define SF_CTRL_SF_IF_INT SF_CTRL_SF_IF_INT +#define SF_CTRL_SF_IF_INT_POS (16U) +#define SF_CTRL_SF_IF_INT_LEN (1U) +#define SF_CTRL_SF_IF_INT_MSK (((1U << SF_CTRL_SF_IF_INT_LEN) - 1) << SF_CTRL_SF_IF_INT_POS) +#define SF_CTRL_SF_IF_INT_UMSK (~(((1U << SF_CTRL_SF_IF_INT_LEN) - 1) << SF_CTRL_SF_IF_INT_POS)) +#define SF_CTRL_SF_IF_INT_CLR SF_CTRL_SF_IF_INT_CLR +#define SF_CTRL_SF_IF_INT_CLR_POS (17U) +#define SF_CTRL_SF_IF_INT_CLR_LEN (1U) +#define SF_CTRL_SF_IF_INT_CLR_MSK (((1U << SF_CTRL_SF_IF_INT_CLR_LEN) - 1) << SF_CTRL_SF_IF_INT_CLR_POS) +#define SF_CTRL_SF_IF_INT_CLR_UMSK (~(((1U << SF_CTRL_SF_IF_INT_CLR_LEN) - 1) << SF_CTRL_SF_IF_INT_CLR_POS)) +#define SF_CTRL_SF_IF_INT_SET SF_CTRL_SF_IF_INT_SET +#define SF_CTRL_SF_IF_INT_SET_POS (18U) +#define SF_CTRL_SF_IF_INT_SET_LEN (1U) +#define SF_CTRL_SF_IF_INT_SET_MSK (((1U << SF_CTRL_SF_IF_INT_SET_LEN) - 1) << SF_CTRL_SF_IF_INT_SET_POS) +#define SF_CTRL_SF_IF_INT_SET_UMSK (~(((1U << SF_CTRL_SF_IF_INT_SET_LEN) - 1) << SF_CTRL_SF_IF_INT_SET_POS)) +#define SF_CTRL_SF_IF_32B_ADR_EN SF_CTRL_SF_IF_32B_ADR_EN +#define SF_CTRL_SF_IF_32B_ADR_EN_POS (19U) +#define SF_CTRL_SF_IF_32B_ADR_EN_LEN (1U) +#define SF_CTRL_SF_IF_32B_ADR_EN_MSK (((1U << SF_CTRL_SF_IF_32B_ADR_EN_LEN) - 1) << SF_CTRL_SF_IF_32B_ADR_EN_POS) +#define SF_CTRL_SF_IF_32B_ADR_EN_UMSK (~(((1U << SF_CTRL_SF_IF_32B_ADR_EN_LEN) - 1) << SF_CTRL_SF_IF_32B_ADR_EN_POS)) +#define SF_CTRL_SF_AES_DOUT_ENDIAN SF_CTRL_SF_AES_DOUT_ENDIAN +#define SF_CTRL_SF_AES_DOUT_ENDIAN_POS (20U) +#define SF_CTRL_SF_AES_DOUT_ENDIAN_LEN (1U) +#define SF_CTRL_SF_AES_DOUT_ENDIAN_MSK (((1U << SF_CTRL_SF_AES_DOUT_ENDIAN_LEN) - 1) << SF_CTRL_SF_AES_DOUT_ENDIAN_POS) +#define SF_CTRL_SF_AES_DOUT_ENDIAN_UMSK (~(((1U << SF_CTRL_SF_AES_DOUT_ENDIAN_LEN) - 1) << SF_CTRL_SF_AES_DOUT_ENDIAN_POS)) +#define SF_CTRL_SF_AES_DIN_ENDIAN SF_CTRL_SF_AES_DIN_ENDIAN +#define SF_CTRL_SF_AES_DIN_ENDIAN_POS (21U) +#define SF_CTRL_SF_AES_DIN_ENDIAN_LEN (1U) +#define SF_CTRL_SF_AES_DIN_ENDIAN_MSK (((1U << SF_CTRL_SF_AES_DIN_ENDIAN_LEN) - 1) << SF_CTRL_SF_AES_DIN_ENDIAN_POS) +#define SF_CTRL_SF_AES_DIN_ENDIAN_UMSK (~(((1U << SF_CTRL_SF_AES_DIN_ENDIAN_LEN) - 1) << SF_CTRL_SF_AES_DIN_ENDIAN_POS)) +#define SF_CTRL_SF_AES_KEY_ENDIAN SF_CTRL_SF_AES_KEY_ENDIAN +#define SF_CTRL_SF_AES_KEY_ENDIAN_POS (22U) +#define SF_CTRL_SF_AES_KEY_ENDIAN_LEN (1U) +#define SF_CTRL_SF_AES_KEY_ENDIAN_MSK (((1U << SF_CTRL_SF_AES_KEY_ENDIAN_LEN) - 1) << SF_CTRL_SF_AES_KEY_ENDIAN_POS) +#define SF_CTRL_SF_AES_KEY_ENDIAN_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_ENDIAN_LEN) - 1) << SF_CTRL_SF_AES_KEY_ENDIAN_POS)) +#define SF_CTRL_SF_AES_IV_ENDIAN SF_CTRL_SF_AES_IV_ENDIAN +#define SF_CTRL_SF_AES_IV_ENDIAN_POS (23U) +#define SF_CTRL_SF_AES_IV_ENDIAN_LEN (1U) +#define SF_CTRL_SF_AES_IV_ENDIAN_MSK (((1U << SF_CTRL_SF_AES_IV_ENDIAN_LEN) - 1) << SF_CTRL_SF_AES_IV_ENDIAN_POS) +#define SF_CTRL_SF_AES_IV_ENDIAN_UMSK (~(((1U << SF_CTRL_SF_AES_IV_ENDIAN_LEN) - 1) << SF_CTRL_SF_AES_IV_ENDIAN_POS)) +#define SF_CTRL_SF_ID SF_CTRL_SF_ID +#define SF_CTRL_SF_ID_POS (24U) +#define SF_CTRL_SF_ID_LEN (8U) +#define SF_CTRL_SF_ID_MSK (((1U << SF_CTRL_SF_ID_LEN) - 1) << SF_CTRL_SF_ID_POS) +#define SF_CTRL_SF_ID_UMSK (~(((1U << SF_CTRL_SF_ID_LEN) - 1) << SF_CTRL_SF_ID_POS)) + +/* 0x4 : sf_ctrl_1 */ +#define SF_CTRL_1_OFFSET (0x4) +#define SF_CTRL_SF_IF_SR_PAT_MASK SF_CTRL_SF_IF_SR_PAT_MASK +#define SF_CTRL_SF_IF_SR_PAT_MASK_POS (0U) +#define SF_CTRL_SF_IF_SR_PAT_MASK_LEN (8U) +#define SF_CTRL_SF_IF_SR_PAT_MASK_MSK (((1U << SF_CTRL_SF_IF_SR_PAT_MASK_LEN) - 1) << SF_CTRL_SF_IF_SR_PAT_MASK_POS) +#define SF_CTRL_SF_IF_SR_PAT_MASK_UMSK (~(((1U << SF_CTRL_SF_IF_SR_PAT_MASK_LEN) - 1) << SF_CTRL_SF_IF_SR_PAT_MASK_POS)) +#define SF_CTRL_SF_IF_SR_PAT SF_CTRL_SF_IF_SR_PAT +#define SF_CTRL_SF_IF_SR_PAT_POS (8U) +#define SF_CTRL_SF_IF_SR_PAT_LEN (8U) +#define SF_CTRL_SF_IF_SR_PAT_MSK (((1U << SF_CTRL_SF_IF_SR_PAT_LEN) - 1) << SF_CTRL_SF_IF_SR_PAT_POS) +#define SF_CTRL_SF_IF_SR_PAT_UMSK (~(((1U << SF_CTRL_SF_IF_SR_PAT_LEN) - 1) << SF_CTRL_SF_IF_SR_PAT_POS)) +#define SF_CTRL_SF_IF_SR_INT SF_CTRL_SF_IF_SR_INT +#define SF_CTRL_SF_IF_SR_INT_POS (16U) +#define SF_CTRL_SF_IF_SR_INT_LEN (1U) +#define SF_CTRL_SF_IF_SR_INT_MSK (((1U << SF_CTRL_SF_IF_SR_INT_LEN) - 1) << SF_CTRL_SF_IF_SR_INT_POS) +#define SF_CTRL_SF_IF_SR_INT_UMSK (~(((1U << SF_CTRL_SF_IF_SR_INT_LEN) - 1) << SF_CTRL_SF_IF_SR_INT_POS)) +#define SF_CTRL_SF_IF_SR_INT_EN SF_CTRL_SF_IF_SR_INT_EN +#define SF_CTRL_SF_IF_SR_INT_EN_POS (17U) +#define SF_CTRL_SF_IF_SR_INT_EN_LEN (1U) +#define SF_CTRL_SF_IF_SR_INT_EN_MSK (((1U << SF_CTRL_SF_IF_SR_INT_EN_LEN) - 1) << SF_CTRL_SF_IF_SR_INT_EN_POS) +#define SF_CTRL_SF_IF_SR_INT_EN_UMSK (~(((1U << SF_CTRL_SF_IF_SR_INT_EN_LEN) - 1) << SF_CTRL_SF_IF_SR_INT_EN_POS)) +#define SF_CTRL_SF_IF_SR_INT_SET SF_CTRL_SF_IF_SR_INT_SET +#define SF_CTRL_SF_IF_SR_INT_SET_POS (18U) +#define SF_CTRL_SF_IF_SR_INT_SET_LEN (1U) +#define SF_CTRL_SF_IF_SR_INT_SET_MSK (((1U << SF_CTRL_SF_IF_SR_INT_SET_LEN) - 1) << SF_CTRL_SF_IF_SR_INT_SET_POS) +#define SF_CTRL_SF_IF_SR_INT_SET_UMSK (~(((1U << SF_CTRL_SF_IF_SR_INT_SET_LEN) - 1) << SF_CTRL_SF_IF_SR_INT_SET_POS)) +#define SF_CTRL_SF_IF_0_ACK_LAT SF_CTRL_SF_IF_0_ACK_LAT +#define SF_CTRL_SF_IF_0_ACK_LAT_POS (20U) +#define SF_CTRL_SF_IF_0_ACK_LAT_LEN (3U) +#define SF_CTRL_SF_IF_0_ACK_LAT_MSK (((1U << SF_CTRL_SF_IF_0_ACK_LAT_LEN) - 1) << SF_CTRL_SF_IF_0_ACK_LAT_POS) +#define SF_CTRL_SF_IF_0_ACK_LAT_UMSK (~(((1U << SF_CTRL_SF_IF_0_ACK_LAT_LEN) - 1) << SF_CTRL_SF_IF_0_ACK_LAT_POS)) +#define SF_CTRL_SF_AHB2SIF_DISWRAP SF_CTRL_SF_AHB2SIF_DISWRAP +#define SF_CTRL_SF_AHB2SIF_DISWRAP_POS (23U) +#define SF_CTRL_SF_AHB2SIF_DISWRAP_LEN (1U) +#define SF_CTRL_SF_AHB2SIF_DISWRAP_MSK (((1U << SF_CTRL_SF_AHB2SIF_DISWRAP_LEN) - 1) << SF_CTRL_SF_AHB2SIF_DISWRAP_POS) +#define SF_CTRL_SF_AHB2SIF_DISWRAP_UMSK (~(((1U << SF_CTRL_SF_AHB2SIF_DISWRAP_LEN) - 1) << SF_CTRL_SF_AHB2SIF_DISWRAP_POS)) +#define SF_CTRL_SF_IF_REG_HOLD SF_CTRL_SF_IF_REG_HOLD +#define SF_CTRL_SF_IF_REG_HOLD_POS (24U) +#define SF_CTRL_SF_IF_REG_HOLD_LEN (1U) +#define SF_CTRL_SF_IF_REG_HOLD_MSK (((1U << SF_CTRL_SF_IF_REG_HOLD_LEN) - 1) << SF_CTRL_SF_IF_REG_HOLD_POS) +#define SF_CTRL_SF_IF_REG_HOLD_UMSK (~(((1U << SF_CTRL_SF_IF_REG_HOLD_LEN) - 1) << SF_CTRL_SF_IF_REG_HOLD_POS)) +#define SF_CTRL_SF_IF_REG_WP SF_CTRL_SF_IF_REG_WP +#define SF_CTRL_SF_IF_REG_WP_POS (25U) +#define SF_CTRL_SF_IF_REG_WP_LEN (1U) +#define SF_CTRL_SF_IF_REG_WP_MSK (((1U << SF_CTRL_SF_IF_REG_WP_LEN) - 1) << SF_CTRL_SF_IF_REG_WP_POS) +#define SF_CTRL_SF_IF_REG_WP_UMSK (~(((1U << SF_CTRL_SF_IF_REG_WP_LEN) - 1) << SF_CTRL_SF_IF_REG_WP_POS)) +#define SF_CTRL_SF_AHB2SIF_STOPPED SF_CTRL_SF_AHB2SIF_STOPPED +#define SF_CTRL_SF_AHB2SIF_STOPPED_POS (26U) +#define SF_CTRL_SF_AHB2SIF_STOPPED_LEN (1U) +#define SF_CTRL_SF_AHB2SIF_STOPPED_MSK (((1U << SF_CTRL_SF_AHB2SIF_STOPPED_LEN) - 1) << SF_CTRL_SF_AHB2SIF_STOPPED_POS) +#define SF_CTRL_SF_AHB2SIF_STOPPED_UMSK (~(((1U << SF_CTRL_SF_AHB2SIF_STOPPED_LEN) - 1) << SF_CTRL_SF_AHB2SIF_STOPPED_POS)) +#define SF_CTRL_SF_AHB2SIF_STOP SF_CTRL_SF_AHB2SIF_STOP +#define SF_CTRL_SF_AHB2SIF_STOP_POS (27U) +#define SF_CTRL_SF_AHB2SIF_STOP_LEN (1U) +#define SF_CTRL_SF_AHB2SIF_STOP_MSK (((1U << SF_CTRL_SF_AHB2SIF_STOP_LEN) - 1) << SF_CTRL_SF_AHB2SIF_STOP_POS) +#define SF_CTRL_SF_AHB2SIF_STOP_UMSK (~(((1U << SF_CTRL_SF_AHB2SIF_STOP_LEN) - 1) << SF_CTRL_SF_AHB2SIF_STOP_POS)) +#define SF_CTRL_SF_IF_FN_SEL SF_CTRL_SF_IF_FN_SEL +#define SF_CTRL_SF_IF_FN_SEL_POS (28U) +#define SF_CTRL_SF_IF_FN_SEL_LEN (1U) +#define SF_CTRL_SF_IF_FN_SEL_MSK (((1U << SF_CTRL_SF_IF_FN_SEL_LEN) - 1) << SF_CTRL_SF_IF_FN_SEL_POS) +#define SF_CTRL_SF_IF_FN_SEL_UMSK (~(((1U << SF_CTRL_SF_IF_FN_SEL_LEN) - 1) << SF_CTRL_SF_IF_FN_SEL_POS)) +#define SF_CTRL_SF_IF_EN SF_CTRL_SF_IF_EN +#define SF_CTRL_SF_IF_EN_POS (29U) +#define SF_CTRL_SF_IF_EN_LEN (1U) +#define SF_CTRL_SF_IF_EN_MSK (((1U << SF_CTRL_SF_IF_EN_LEN) - 1) << SF_CTRL_SF_IF_EN_POS) +#define SF_CTRL_SF_IF_EN_UMSK (~(((1U << SF_CTRL_SF_IF_EN_LEN) - 1) << SF_CTRL_SF_IF_EN_POS)) +#define SF_CTRL_SF_AHB2SIF_EN SF_CTRL_SF_AHB2SIF_EN +#define SF_CTRL_SF_AHB2SIF_EN_POS (30U) +#define SF_CTRL_SF_AHB2SIF_EN_LEN (1U) +#define SF_CTRL_SF_AHB2SIF_EN_MSK (((1U << SF_CTRL_SF_AHB2SIF_EN_LEN) - 1) << SF_CTRL_SF_AHB2SIF_EN_POS) +#define SF_CTRL_SF_AHB2SIF_EN_UMSK (~(((1U << SF_CTRL_SF_AHB2SIF_EN_LEN) - 1) << SF_CTRL_SF_AHB2SIF_EN_POS)) +#define SF_CTRL_SF_AHB2SRAM_EN SF_CTRL_SF_AHB2SRAM_EN +#define SF_CTRL_SF_AHB2SRAM_EN_POS (31U) +#define SF_CTRL_SF_AHB2SRAM_EN_LEN (1U) +#define SF_CTRL_SF_AHB2SRAM_EN_MSK (((1U << SF_CTRL_SF_AHB2SRAM_EN_LEN) - 1) << SF_CTRL_SF_AHB2SRAM_EN_POS) +#define SF_CTRL_SF_AHB2SRAM_EN_UMSK (~(((1U << SF_CTRL_SF_AHB2SRAM_EN_LEN) - 1) << SF_CTRL_SF_AHB2SRAM_EN_POS)) + +/* 0x8 : sf_if_sahb_0 */ +#define SF_CTRL_SF_IF_SAHB_0_OFFSET (0x8) +#define SF_CTRL_SF_IF_BUSY SF_CTRL_SF_IF_BUSY +#define SF_CTRL_SF_IF_BUSY_POS (0U) +#define SF_CTRL_SF_IF_BUSY_LEN (1U) +#define SF_CTRL_SF_IF_BUSY_MSK (((1U << SF_CTRL_SF_IF_BUSY_LEN) - 1) << SF_CTRL_SF_IF_BUSY_POS) +#define SF_CTRL_SF_IF_BUSY_UMSK (~(((1U << SF_CTRL_SF_IF_BUSY_LEN) - 1) << SF_CTRL_SF_IF_BUSY_POS)) +#define SF_CTRL_SF_IF_0_TRIG SF_CTRL_SF_IF_0_TRIG +#define SF_CTRL_SF_IF_0_TRIG_POS (1U) +#define SF_CTRL_SF_IF_0_TRIG_LEN (1U) +#define SF_CTRL_SF_IF_0_TRIG_MSK (((1U << SF_CTRL_SF_IF_0_TRIG_LEN) - 1) << SF_CTRL_SF_IF_0_TRIG_POS) +#define SF_CTRL_SF_IF_0_TRIG_UMSK (~(((1U << SF_CTRL_SF_IF_0_TRIG_LEN) - 1) << SF_CTRL_SF_IF_0_TRIG_POS)) +#define SF_CTRL_SF_IF_0_DAT_BYTE SF_CTRL_SF_IF_0_DAT_BYTE +#define SF_CTRL_SF_IF_0_DAT_BYTE_POS (2U) +#define SF_CTRL_SF_IF_0_DAT_BYTE_LEN (10U) +#define SF_CTRL_SF_IF_0_DAT_BYTE_MSK (((1U << SF_CTRL_SF_IF_0_DAT_BYTE_LEN) - 1) << SF_CTRL_SF_IF_0_DAT_BYTE_POS) +#define SF_CTRL_SF_IF_0_DAT_BYTE_UMSK (~(((1U << SF_CTRL_SF_IF_0_DAT_BYTE_LEN) - 1) << SF_CTRL_SF_IF_0_DAT_BYTE_POS)) +#define SF_CTRL_SF_IF_0_DMY_BYTE SF_CTRL_SF_IF_0_DMY_BYTE +#define SF_CTRL_SF_IF_0_DMY_BYTE_POS (12U) +#define SF_CTRL_SF_IF_0_DMY_BYTE_LEN (5U) +#define SF_CTRL_SF_IF_0_DMY_BYTE_MSK (((1U << SF_CTRL_SF_IF_0_DMY_BYTE_LEN) - 1) << SF_CTRL_SF_IF_0_DMY_BYTE_POS) +#define SF_CTRL_SF_IF_0_DMY_BYTE_UMSK (~(((1U << SF_CTRL_SF_IF_0_DMY_BYTE_LEN) - 1) << SF_CTRL_SF_IF_0_DMY_BYTE_POS)) +#define SF_CTRL_SF_IF_0_ADR_BYTE SF_CTRL_SF_IF_0_ADR_BYTE +#define SF_CTRL_SF_IF_0_ADR_BYTE_POS (17U) +#define SF_CTRL_SF_IF_0_ADR_BYTE_LEN (3U) +#define SF_CTRL_SF_IF_0_ADR_BYTE_MSK (((1U << SF_CTRL_SF_IF_0_ADR_BYTE_LEN) - 1) << SF_CTRL_SF_IF_0_ADR_BYTE_POS) +#define SF_CTRL_SF_IF_0_ADR_BYTE_UMSK (~(((1U << SF_CTRL_SF_IF_0_ADR_BYTE_LEN) - 1) << SF_CTRL_SF_IF_0_ADR_BYTE_POS)) +#define SF_CTRL_SF_IF_0_CMD_BYTE SF_CTRL_SF_IF_0_CMD_BYTE +#define SF_CTRL_SF_IF_0_CMD_BYTE_POS (20U) +#define SF_CTRL_SF_IF_0_CMD_BYTE_LEN (3U) +#define SF_CTRL_SF_IF_0_CMD_BYTE_MSK (((1U << SF_CTRL_SF_IF_0_CMD_BYTE_LEN) - 1) << SF_CTRL_SF_IF_0_CMD_BYTE_POS) +#define SF_CTRL_SF_IF_0_CMD_BYTE_UMSK (~(((1U << SF_CTRL_SF_IF_0_CMD_BYTE_LEN) - 1) << SF_CTRL_SF_IF_0_CMD_BYTE_POS)) +#define SF_CTRL_SF_IF_0_DAT_RW SF_CTRL_SF_IF_0_DAT_RW +#define SF_CTRL_SF_IF_0_DAT_RW_POS (23U) +#define SF_CTRL_SF_IF_0_DAT_RW_LEN (1U) +#define SF_CTRL_SF_IF_0_DAT_RW_MSK (((1U << SF_CTRL_SF_IF_0_DAT_RW_LEN) - 1) << SF_CTRL_SF_IF_0_DAT_RW_POS) +#define SF_CTRL_SF_IF_0_DAT_RW_UMSK (~(((1U << SF_CTRL_SF_IF_0_DAT_RW_LEN) - 1) << SF_CTRL_SF_IF_0_DAT_RW_POS)) +#define SF_CTRL_SF_IF_0_DAT_EN SF_CTRL_SF_IF_0_DAT_EN +#define SF_CTRL_SF_IF_0_DAT_EN_POS (24U) +#define SF_CTRL_SF_IF_0_DAT_EN_LEN (1U) +#define SF_CTRL_SF_IF_0_DAT_EN_MSK (((1U << SF_CTRL_SF_IF_0_DAT_EN_LEN) - 1) << SF_CTRL_SF_IF_0_DAT_EN_POS) +#define SF_CTRL_SF_IF_0_DAT_EN_UMSK (~(((1U << SF_CTRL_SF_IF_0_DAT_EN_LEN) - 1) << SF_CTRL_SF_IF_0_DAT_EN_POS)) +#define SF_CTRL_SF_IF_0_DMY_EN SF_CTRL_SF_IF_0_DMY_EN +#define SF_CTRL_SF_IF_0_DMY_EN_POS (25U) +#define SF_CTRL_SF_IF_0_DMY_EN_LEN (1U) +#define SF_CTRL_SF_IF_0_DMY_EN_MSK (((1U << SF_CTRL_SF_IF_0_DMY_EN_LEN) - 1) << SF_CTRL_SF_IF_0_DMY_EN_POS) +#define SF_CTRL_SF_IF_0_DMY_EN_UMSK (~(((1U << SF_CTRL_SF_IF_0_DMY_EN_LEN) - 1) << SF_CTRL_SF_IF_0_DMY_EN_POS)) +#define SF_CTRL_SF_IF_0_ADR_EN SF_CTRL_SF_IF_0_ADR_EN +#define SF_CTRL_SF_IF_0_ADR_EN_POS (26U) +#define SF_CTRL_SF_IF_0_ADR_EN_LEN (1U) +#define SF_CTRL_SF_IF_0_ADR_EN_MSK (((1U << SF_CTRL_SF_IF_0_ADR_EN_LEN) - 1) << SF_CTRL_SF_IF_0_ADR_EN_POS) +#define SF_CTRL_SF_IF_0_ADR_EN_UMSK (~(((1U << SF_CTRL_SF_IF_0_ADR_EN_LEN) - 1) << SF_CTRL_SF_IF_0_ADR_EN_POS)) +#define SF_CTRL_SF_IF_0_CMD_EN SF_CTRL_SF_IF_0_CMD_EN +#define SF_CTRL_SF_IF_0_CMD_EN_POS (27U) +#define SF_CTRL_SF_IF_0_CMD_EN_LEN (1U) +#define SF_CTRL_SF_IF_0_CMD_EN_MSK (((1U << SF_CTRL_SF_IF_0_CMD_EN_LEN) - 1) << SF_CTRL_SF_IF_0_CMD_EN_POS) +#define SF_CTRL_SF_IF_0_CMD_EN_UMSK (~(((1U << SF_CTRL_SF_IF_0_CMD_EN_LEN) - 1) << SF_CTRL_SF_IF_0_CMD_EN_POS)) +#define SF_CTRL_SF_IF_0_SPI_MODE SF_CTRL_SF_IF_0_SPI_MODE +#define SF_CTRL_SF_IF_0_SPI_MODE_POS (28U) +#define SF_CTRL_SF_IF_0_SPI_MODE_LEN (3U) +#define SF_CTRL_SF_IF_0_SPI_MODE_MSK (((1U << SF_CTRL_SF_IF_0_SPI_MODE_LEN) - 1) << SF_CTRL_SF_IF_0_SPI_MODE_POS) +#define SF_CTRL_SF_IF_0_SPI_MODE_UMSK (~(((1U << SF_CTRL_SF_IF_0_SPI_MODE_LEN) - 1) << SF_CTRL_SF_IF_0_SPI_MODE_POS)) +#define SF_CTRL_SF_IF_0_QPI_MODE_EN SF_CTRL_SF_IF_0_QPI_MODE_EN +#define SF_CTRL_SF_IF_0_QPI_MODE_EN_POS (31U) +#define SF_CTRL_SF_IF_0_QPI_MODE_EN_LEN (1U) +#define SF_CTRL_SF_IF_0_QPI_MODE_EN_MSK (((1U << SF_CTRL_SF_IF_0_QPI_MODE_EN_LEN) - 1) << SF_CTRL_SF_IF_0_QPI_MODE_EN_POS) +#define SF_CTRL_SF_IF_0_QPI_MODE_EN_UMSK (~(((1U << SF_CTRL_SF_IF_0_QPI_MODE_EN_LEN) - 1) << SF_CTRL_SF_IF_0_QPI_MODE_EN_POS)) + +/* 0xC : sf_if_sahb_1 */ +#define SF_CTRL_SF_IF_SAHB_1_OFFSET (0xC) +#define SF_CTRL_SF_IF_0_CMD_BUF_0 SF_CTRL_SF_IF_0_CMD_BUF_0 +#define SF_CTRL_SF_IF_0_CMD_BUF_0_POS (0U) +#define SF_CTRL_SF_IF_0_CMD_BUF_0_LEN (32U) +#define SF_CTRL_SF_IF_0_CMD_BUF_0_MSK (((1U << SF_CTRL_SF_IF_0_CMD_BUF_0_LEN) - 1) << SF_CTRL_SF_IF_0_CMD_BUF_0_POS) +#define SF_CTRL_SF_IF_0_CMD_BUF_0_UMSK (~(((1U << SF_CTRL_SF_IF_0_CMD_BUF_0_LEN) - 1) << SF_CTRL_SF_IF_0_CMD_BUF_0_POS)) + +/* 0x10 : sf_if_sahb_2 */ +#define SF_CTRL_SF_IF_SAHB_2_OFFSET (0x10) +#define SF_CTRL_SF_IF_0_CMD_BUF_1 SF_CTRL_SF_IF_0_CMD_BUF_1 +#define SF_CTRL_SF_IF_0_CMD_BUF_1_POS (0U) +#define SF_CTRL_SF_IF_0_CMD_BUF_1_LEN (32U) +#define SF_CTRL_SF_IF_0_CMD_BUF_1_MSK (((1U << SF_CTRL_SF_IF_0_CMD_BUF_1_LEN) - 1) << SF_CTRL_SF_IF_0_CMD_BUF_1_POS) +#define SF_CTRL_SF_IF_0_CMD_BUF_1_UMSK (~(((1U << SF_CTRL_SF_IF_0_CMD_BUF_1_LEN) - 1) << SF_CTRL_SF_IF_0_CMD_BUF_1_POS)) + +/* 0x14 : sf_if_iahb_0 */ +#define SF_CTRL_SF_IF_IAHB_0_OFFSET (0x14) +#define SF_CTRL_SF_IF_1_DMY_BYTE SF_CTRL_SF_IF_1_DMY_BYTE +#define SF_CTRL_SF_IF_1_DMY_BYTE_POS (12U) +#define SF_CTRL_SF_IF_1_DMY_BYTE_LEN (5U) +#define SF_CTRL_SF_IF_1_DMY_BYTE_MSK (((1U << SF_CTRL_SF_IF_1_DMY_BYTE_LEN) - 1) << SF_CTRL_SF_IF_1_DMY_BYTE_POS) +#define SF_CTRL_SF_IF_1_DMY_BYTE_UMSK (~(((1U << SF_CTRL_SF_IF_1_DMY_BYTE_LEN) - 1) << SF_CTRL_SF_IF_1_DMY_BYTE_POS)) +#define SF_CTRL_SF_IF_1_ADR_BYTE SF_CTRL_SF_IF_1_ADR_BYTE +#define SF_CTRL_SF_IF_1_ADR_BYTE_POS (17U) +#define SF_CTRL_SF_IF_1_ADR_BYTE_LEN (3U) +#define SF_CTRL_SF_IF_1_ADR_BYTE_MSK (((1U << SF_CTRL_SF_IF_1_ADR_BYTE_LEN) - 1) << SF_CTRL_SF_IF_1_ADR_BYTE_POS) +#define SF_CTRL_SF_IF_1_ADR_BYTE_UMSK (~(((1U << SF_CTRL_SF_IF_1_ADR_BYTE_LEN) - 1) << SF_CTRL_SF_IF_1_ADR_BYTE_POS)) +#define SF_CTRL_SF_IF_1_CMD_BYTE SF_CTRL_SF_IF_1_CMD_BYTE +#define SF_CTRL_SF_IF_1_CMD_BYTE_POS (20U) +#define SF_CTRL_SF_IF_1_CMD_BYTE_LEN (3U) +#define SF_CTRL_SF_IF_1_CMD_BYTE_MSK (((1U << SF_CTRL_SF_IF_1_CMD_BYTE_LEN) - 1) << SF_CTRL_SF_IF_1_CMD_BYTE_POS) +#define SF_CTRL_SF_IF_1_CMD_BYTE_UMSK (~(((1U << SF_CTRL_SF_IF_1_CMD_BYTE_LEN) - 1) << SF_CTRL_SF_IF_1_CMD_BYTE_POS)) +#define SF_CTRL_SF_IF_1_DAT_RW SF_CTRL_SF_IF_1_DAT_RW +#define SF_CTRL_SF_IF_1_DAT_RW_POS (23U) +#define SF_CTRL_SF_IF_1_DAT_RW_LEN (1U) +#define SF_CTRL_SF_IF_1_DAT_RW_MSK (((1U << SF_CTRL_SF_IF_1_DAT_RW_LEN) - 1) << SF_CTRL_SF_IF_1_DAT_RW_POS) +#define SF_CTRL_SF_IF_1_DAT_RW_UMSK (~(((1U << SF_CTRL_SF_IF_1_DAT_RW_LEN) - 1) << SF_CTRL_SF_IF_1_DAT_RW_POS)) +#define SF_CTRL_SF_IF_1_DAT_EN SF_CTRL_SF_IF_1_DAT_EN +#define SF_CTRL_SF_IF_1_DAT_EN_POS (24U) +#define SF_CTRL_SF_IF_1_DAT_EN_LEN (1U) +#define SF_CTRL_SF_IF_1_DAT_EN_MSK (((1U << SF_CTRL_SF_IF_1_DAT_EN_LEN) - 1) << SF_CTRL_SF_IF_1_DAT_EN_POS) +#define SF_CTRL_SF_IF_1_DAT_EN_UMSK (~(((1U << SF_CTRL_SF_IF_1_DAT_EN_LEN) - 1) << SF_CTRL_SF_IF_1_DAT_EN_POS)) +#define SF_CTRL_SF_IF_1_DMY_EN SF_CTRL_SF_IF_1_DMY_EN +#define SF_CTRL_SF_IF_1_DMY_EN_POS (25U) +#define SF_CTRL_SF_IF_1_DMY_EN_LEN (1U) +#define SF_CTRL_SF_IF_1_DMY_EN_MSK (((1U << SF_CTRL_SF_IF_1_DMY_EN_LEN) - 1) << SF_CTRL_SF_IF_1_DMY_EN_POS) +#define SF_CTRL_SF_IF_1_DMY_EN_UMSK (~(((1U << SF_CTRL_SF_IF_1_DMY_EN_LEN) - 1) << SF_CTRL_SF_IF_1_DMY_EN_POS)) +#define SF_CTRL_SF_IF_1_ADR_EN SF_CTRL_SF_IF_1_ADR_EN +#define SF_CTRL_SF_IF_1_ADR_EN_POS (26U) +#define SF_CTRL_SF_IF_1_ADR_EN_LEN (1U) +#define SF_CTRL_SF_IF_1_ADR_EN_MSK (((1U << SF_CTRL_SF_IF_1_ADR_EN_LEN) - 1) << SF_CTRL_SF_IF_1_ADR_EN_POS) +#define SF_CTRL_SF_IF_1_ADR_EN_UMSK (~(((1U << SF_CTRL_SF_IF_1_ADR_EN_LEN) - 1) << SF_CTRL_SF_IF_1_ADR_EN_POS)) +#define SF_CTRL_SF_IF_1_CMD_EN SF_CTRL_SF_IF_1_CMD_EN +#define SF_CTRL_SF_IF_1_CMD_EN_POS (27U) +#define SF_CTRL_SF_IF_1_CMD_EN_LEN (1U) +#define SF_CTRL_SF_IF_1_CMD_EN_MSK (((1U << SF_CTRL_SF_IF_1_CMD_EN_LEN) - 1) << SF_CTRL_SF_IF_1_CMD_EN_POS) +#define SF_CTRL_SF_IF_1_CMD_EN_UMSK (~(((1U << SF_CTRL_SF_IF_1_CMD_EN_LEN) - 1) << SF_CTRL_SF_IF_1_CMD_EN_POS)) +#define SF_CTRL_SF_IF_1_SPI_MODE SF_CTRL_SF_IF_1_SPI_MODE +#define SF_CTRL_SF_IF_1_SPI_MODE_POS (28U) +#define SF_CTRL_SF_IF_1_SPI_MODE_LEN (3U) +#define SF_CTRL_SF_IF_1_SPI_MODE_MSK (((1U << SF_CTRL_SF_IF_1_SPI_MODE_LEN) - 1) << SF_CTRL_SF_IF_1_SPI_MODE_POS) +#define SF_CTRL_SF_IF_1_SPI_MODE_UMSK (~(((1U << SF_CTRL_SF_IF_1_SPI_MODE_LEN) - 1) << SF_CTRL_SF_IF_1_SPI_MODE_POS)) +#define SF_CTRL_SF_IF_1_QPI_MODE_EN SF_CTRL_SF_IF_1_QPI_MODE_EN +#define SF_CTRL_SF_IF_1_QPI_MODE_EN_POS (31U) +#define SF_CTRL_SF_IF_1_QPI_MODE_EN_LEN (1U) +#define SF_CTRL_SF_IF_1_QPI_MODE_EN_MSK (((1U << SF_CTRL_SF_IF_1_QPI_MODE_EN_LEN) - 1) << SF_CTRL_SF_IF_1_QPI_MODE_EN_POS) +#define SF_CTRL_SF_IF_1_QPI_MODE_EN_UMSK (~(((1U << SF_CTRL_SF_IF_1_QPI_MODE_EN_LEN) - 1) << SF_CTRL_SF_IF_1_QPI_MODE_EN_POS)) + +/* 0x18 : sf_if_iahb_1 */ +#define SF_CTRL_SF_IF_IAHB_1_OFFSET (0x18) +#define SF_CTRL_SF_IF_1_CMD_BUF_0 SF_CTRL_SF_IF_1_CMD_BUF_0 +#define SF_CTRL_SF_IF_1_CMD_BUF_0_POS (0U) +#define SF_CTRL_SF_IF_1_CMD_BUF_0_LEN (32U) +#define SF_CTRL_SF_IF_1_CMD_BUF_0_MSK (((1U << SF_CTRL_SF_IF_1_CMD_BUF_0_LEN) - 1) << SF_CTRL_SF_IF_1_CMD_BUF_0_POS) +#define SF_CTRL_SF_IF_1_CMD_BUF_0_UMSK (~(((1U << SF_CTRL_SF_IF_1_CMD_BUF_0_LEN) - 1) << SF_CTRL_SF_IF_1_CMD_BUF_0_POS)) + +/* 0x1C : sf_if_iahb_2 */ +#define SF_CTRL_SF_IF_IAHB_2_OFFSET (0x1C) +#define SF_CTRL_SF_IF_1_CMD_BUF_1 SF_CTRL_SF_IF_1_CMD_BUF_1 +#define SF_CTRL_SF_IF_1_CMD_BUF_1_POS (0U) +#define SF_CTRL_SF_IF_1_CMD_BUF_1_LEN (32U) +#define SF_CTRL_SF_IF_1_CMD_BUF_1_MSK (((1U << SF_CTRL_SF_IF_1_CMD_BUF_1_LEN) - 1) << SF_CTRL_SF_IF_1_CMD_BUF_1_POS) +#define SF_CTRL_SF_IF_1_CMD_BUF_1_UMSK (~(((1U << SF_CTRL_SF_IF_1_CMD_BUF_1_LEN) - 1) << SF_CTRL_SF_IF_1_CMD_BUF_1_POS)) + +/* 0x20 : sf_if_status_0 */ +#define SF_CTRL_SF_IF_STATUS_0_OFFSET (0x20) +#define SF_CTRL_SF_IF_STATUS_0 SF_CTRL_SF_IF_STATUS_0 +#define SF_CTRL_SF_IF_STATUS_0_POS (0U) +#define SF_CTRL_SF_IF_STATUS_0_LEN (32U) +#define SF_CTRL_SF_IF_STATUS_0_MSK (((1U << SF_CTRL_SF_IF_STATUS_0_LEN) - 1) << SF_CTRL_SF_IF_STATUS_0_POS) +#define SF_CTRL_SF_IF_STATUS_0_UMSK (~(((1U << SF_CTRL_SF_IF_STATUS_0_LEN) - 1) << SF_CTRL_SF_IF_STATUS_0_POS)) + +/* 0x24 : sf_if_status_1 */ +#define SF_CTRL_SF_IF_STATUS_1_OFFSET (0x24) +#define SF_CTRL_SF_IF_STATUS_1 SF_CTRL_SF_IF_STATUS_1 +#define SF_CTRL_SF_IF_STATUS_1_POS (0U) +#define SF_CTRL_SF_IF_STATUS_1_LEN (32U) +#define SF_CTRL_SF_IF_STATUS_1_MSK (((1U << SF_CTRL_SF_IF_STATUS_1_LEN) - 1) << SF_CTRL_SF_IF_STATUS_1_POS) +#define SF_CTRL_SF_IF_STATUS_1_UMSK (~(((1U << SF_CTRL_SF_IF_STATUS_1_LEN) - 1) << SF_CTRL_SF_IF_STATUS_1_POS)) + +/* 0x28 : sf_aes */ +#define SF_CTRL_SF_AES_OFFSET (0x28) +#define SF_CTRL_SF_AES_EN SF_CTRL_SF_AES_EN +#define SF_CTRL_SF_AES_EN_POS (0U) +#define SF_CTRL_SF_AES_EN_LEN (1U) +#define SF_CTRL_SF_AES_EN_MSK (((1U << SF_CTRL_SF_AES_EN_LEN) - 1) << SF_CTRL_SF_AES_EN_POS) +#define SF_CTRL_SF_AES_EN_UMSK (~(((1U << SF_CTRL_SF_AES_EN_LEN) - 1) << SF_CTRL_SF_AES_EN_POS)) +#define SF_CTRL_SF_AES_MODE SF_CTRL_SF_AES_MODE +#define SF_CTRL_SF_AES_MODE_POS (1U) +#define SF_CTRL_SF_AES_MODE_LEN (2U) +#define SF_CTRL_SF_AES_MODE_MSK (((1U << SF_CTRL_SF_AES_MODE_LEN) - 1) << SF_CTRL_SF_AES_MODE_POS) +#define SF_CTRL_SF_AES_MODE_UMSK (~(((1U << SF_CTRL_SF_AES_MODE_LEN) - 1) << SF_CTRL_SF_AES_MODE_POS)) +#define SF_CTRL_SF_AES_BLK_MODE SF_CTRL_SF_AES_BLK_MODE +#define SF_CTRL_SF_AES_BLK_MODE_POS (3U) +#define SF_CTRL_SF_AES_BLK_MODE_LEN (1U) +#define SF_CTRL_SF_AES_BLK_MODE_MSK (((1U << SF_CTRL_SF_AES_BLK_MODE_LEN) - 1) << SF_CTRL_SF_AES_BLK_MODE_POS) +#define SF_CTRL_SF_AES_BLK_MODE_UMSK (~(((1U << SF_CTRL_SF_AES_BLK_MODE_LEN) - 1) << SF_CTRL_SF_AES_BLK_MODE_POS)) +#define SF_CTRL_SF_AES_XTS_KEY_OPT SF_CTRL_SF_AES_XTS_KEY_OPT +#define SF_CTRL_SF_AES_XTS_KEY_OPT_POS (4U) +#define SF_CTRL_SF_AES_XTS_KEY_OPT_LEN (1U) +#define SF_CTRL_SF_AES_XTS_KEY_OPT_MSK (((1U << SF_CTRL_SF_AES_XTS_KEY_OPT_LEN) - 1) << SF_CTRL_SF_AES_XTS_KEY_OPT_POS) +#define SF_CTRL_SF_AES_XTS_KEY_OPT_UMSK (~(((1U << SF_CTRL_SF_AES_XTS_KEY_OPT_LEN) - 1) << SF_CTRL_SF_AES_XTS_KEY_OPT_POS)) +#define SF_CTRL_SF_AES_STATUS SF_CTRL_SF_AES_STATUS +#define SF_CTRL_SF_AES_STATUS_POS (5U) +#define SF_CTRL_SF_AES_STATUS_LEN (27U) +#define SF_CTRL_SF_AES_STATUS_MSK (((1U << SF_CTRL_SF_AES_STATUS_LEN) - 1) << SF_CTRL_SF_AES_STATUS_POS) +#define SF_CTRL_SF_AES_STATUS_UMSK (~(((1U << SF_CTRL_SF_AES_STATUS_LEN) - 1) << SF_CTRL_SF_AES_STATUS_POS)) + +/* 0x2C : sf_ahb2sif_status */ +#define SF_CTRL_SF_AHB2SIF_STATUS_OFFSET (0x2C) +#define SF_CTRL_SF_AHB2SIF_STATUS SF_CTRL_SF_AHB2SIF_STATUS +#define SF_CTRL_SF_AHB2SIF_STATUS_POS (0U) +#define SF_CTRL_SF_AHB2SIF_STATUS_LEN (32U) +#define SF_CTRL_SF_AHB2SIF_STATUS_MSK (((1U << SF_CTRL_SF_AHB2SIF_STATUS_LEN) - 1) << SF_CTRL_SF_AHB2SIF_STATUS_POS) +#define SF_CTRL_SF_AHB2SIF_STATUS_UMSK (~(((1U << SF_CTRL_SF_AHB2SIF_STATUS_LEN) - 1) << SF_CTRL_SF_AHB2SIF_STATUS_POS)) + +/* 0x30 : sf_if_io_dly_0 */ +#define SF_CTRL_SF_IF_IO_DLY_0_OFFSET (0x30) +#define SF_CTRL_SF_CS_DLY_SEL SF_CTRL_SF_CS_DLY_SEL +#define SF_CTRL_SF_CS_DLY_SEL_POS (0U) +#define SF_CTRL_SF_CS_DLY_SEL_LEN (2U) +#define SF_CTRL_SF_CS_DLY_SEL_MSK (((1U << SF_CTRL_SF_CS_DLY_SEL_LEN) - 1) << SF_CTRL_SF_CS_DLY_SEL_POS) +#define SF_CTRL_SF_CS_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF_CS_DLY_SEL_LEN) - 1) << SF_CTRL_SF_CS_DLY_SEL_POS)) +#define SF_CTRL_SF_CS2_DLY_SEL SF_CTRL_SF_CS2_DLY_SEL +#define SF_CTRL_SF_CS2_DLY_SEL_POS (2U) +#define SF_CTRL_SF_CS2_DLY_SEL_LEN (2U) +#define SF_CTRL_SF_CS2_DLY_SEL_MSK (((1U << SF_CTRL_SF_CS2_DLY_SEL_LEN) - 1) << SF_CTRL_SF_CS2_DLY_SEL_POS) +#define SF_CTRL_SF_CS2_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF_CS2_DLY_SEL_LEN) - 1) << SF_CTRL_SF_CS2_DLY_SEL_POS)) +#define SF_CTRL_SF_CLK_OUT_DLY_SEL SF_CTRL_SF_CLK_OUT_DLY_SEL +#define SF_CTRL_SF_CLK_OUT_DLY_SEL_POS (8U) +#define SF_CTRL_SF_CLK_OUT_DLY_SEL_LEN (2U) +#define SF_CTRL_SF_CLK_OUT_DLY_SEL_MSK (((1U << SF_CTRL_SF_CLK_OUT_DLY_SEL_LEN) - 1) << SF_CTRL_SF_CLK_OUT_DLY_SEL_POS) +#define SF_CTRL_SF_CLK_OUT_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF_CLK_OUT_DLY_SEL_LEN) - 1) << SF_CTRL_SF_CLK_OUT_DLY_SEL_POS)) +#define SF_CTRL_SF_DQS_OE_DLY_SEL SF_CTRL_SF_DQS_OE_DLY_SEL +#define SF_CTRL_SF_DQS_OE_DLY_SEL_POS (26U) +#define SF_CTRL_SF_DQS_OE_DLY_SEL_LEN (2U) +#define SF_CTRL_SF_DQS_OE_DLY_SEL_MSK (((1U << SF_CTRL_SF_DQS_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF_DQS_OE_DLY_SEL_POS) +#define SF_CTRL_SF_DQS_OE_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF_DQS_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF_DQS_OE_DLY_SEL_POS)) +#define SF_CTRL_SF_DQS_DI_DLY_SEL SF_CTRL_SF_DQS_DI_DLY_SEL +#define SF_CTRL_SF_DQS_DI_DLY_SEL_POS (28U) +#define SF_CTRL_SF_DQS_DI_DLY_SEL_LEN (2U) +#define SF_CTRL_SF_DQS_DI_DLY_SEL_MSK (((1U << SF_CTRL_SF_DQS_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF_DQS_DI_DLY_SEL_POS) +#define SF_CTRL_SF_DQS_DI_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF_DQS_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF_DQS_DI_DLY_SEL_POS)) +#define SF_CTRL_SF_DQS_DO_DLY_SEL SF_CTRL_SF_DQS_DO_DLY_SEL +#define SF_CTRL_SF_DQS_DO_DLY_SEL_POS (30U) +#define SF_CTRL_SF_DQS_DO_DLY_SEL_LEN (2U) +#define SF_CTRL_SF_DQS_DO_DLY_SEL_MSK (((1U << SF_CTRL_SF_DQS_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF_DQS_DO_DLY_SEL_POS) +#define SF_CTRL_SF_DQS_DO_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF_DQS_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF_DQS_DO_DLY_SEL_POS)) + +/* 0x34 : sf_if_io_dly_1 */ +#define SF_CTRL_SF_IF_IO_DLY_1_OFFSET (0x34) +#define SF_CTRL_SF_IO_0_OE_DLY_SEL SF_CTRL_SF_IO_0_OE_DLY_SEL +#define SF_CTRL_SF_IO_0_OE_DLY_SEL_POS (0U) +#define SF_CTRL_SF_IO_0_OE_DLY_SEL_LEN (2U) +#define SF_CTRL_SF_IO_0_OE_DLY_SEL_MSK (((1U << SF_CTRL_SF_IO_0_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_0_OE_DLY_SEL_POS) +#define SF_CTRL_SF_IO_0_OE_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF_IO_0_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_0_OE_DLY_SEL_POS)) +#define SF_CTRL_SF_IO_0_DI_DLY_SEL SF_CTRL_SF_IO_0_DI_DLY_SEL +#define SF_CTRL_SF_IO_0_DI_DLY_SEL_POS (8U) +#define SF_CTRL_SF_IO_0_DI_DLY_SEL_LEN (2U) +#define SF_CTRL_SF_IO_0_DI_DLY_SEL_MSK (((1U << SF_CTRL_SF_IO_0_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_0_DI_DLY_SEL_POS) +#define SF_CTRL_SF_IO_0_DI_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF_IO_0_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_0_DI_DLY_SEL_POS)) +#define SF_CTRL_SF_IO_0_DO_DLY_SEL SF_CTRL_SF_IO_0_DO_DLY_SEL +#define SF_CTRL_SF_IO_0_DO_DLY_SEL_POS (16U) +#define SF_CTRL_SF_IO_0_DO_DLY_SEL_LEN (2U) +#define SF_CTRL_SF_IO_0_DO_DLY_SEL_MSK (((1U << SF_CTRL_SF_IO_0_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_0_DO_DLY_SEL_POS) +#define SF_CTRL_SF_IO_0_DO_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF_IO_0_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_0_DO_DLY_SEL_POS)) + +/* 0x38 : sf_if_io_dly_2 */ +#define SF_CTRL_SF_IF_IO_DLY_2_OFFSET (0x38) +#define SF_CTRL_SF_IO_1_OE_DLY_SEL SF_CTRL_SF_IO_1_OE_DLY_SEL +#define SF_CTRL_SF_IO_1_OE_DLY_SEL_POS (0U) +#define SF_CTRL_SF_IO_1_OE_DLY_SEL_LEN (2U) +#define SF_CTRL_SF_IO_1_OE_DLY_SEL_MSK (((1U << SF_CTRL_SF_IO_1_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_1_OE_DLY_SEL_POS) +#define SF_CTRL_SF_IO_1_OE_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF_IO_1_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_1_OE_DLY_SEL_POS)) +#define SF_CTRL_SF_IO_1_DI_DLY_SEL SF_CTRL_SF_IO_1_DI_DLY_SEL +#define SF_CTRL_SF_IO_1_DI_DLY_SEL_POS (8U) +#define SF_CTRL_SF_IO_1_DI_DLY_SEL_LEN (2U) +#define SF_CTRL_SF_IO_1_DI_DLY_SEL_MSK (((1U << SF_CTRL_SF_IO_1_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_1_DI_DLY_SEL_POS) +#define SF_CTRL_SF_IO_1_DI_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF_IO_1_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_1_DI_DLY_SEL_POS)) +#define SF_CTRL_SF_IO_1_DO_DLY_SEL SF_CTRL_SF_IO_1_DO_DLY_SEL +#define SF_CTRL_SF_IO_1_DO_DLY_SEL_POS (16U) +#define SF_CTRL_SF_IO_1_DO_DLY_SEL_LEN (2U) +#define SF_CTRL_SF_IO_1_DO_DLY_SEL_MSK (((1U << SF_CTRL_SF_IO_1_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_1_DO_DLY_SEL_POS) +#define SF_CTRL_SF_IO_1_DO_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF_IO_1_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_1_DO_DLY_SEL_POS)) + +/* 0x3C : sf_if_io_dly_3 */ +#define SF_CTRL_SF_IF_IO_DLY_3_OFFSET (0x3C) +#define SF_CTRL_SF_IO_2_OE_DLY_SEL SF_CTRL_SF_IO_2_OE_DLY_SEL +#define SF_CTRL_SF_IO_2_OE_DLY_SEL_POS (0U) +#define SF_CTRL_SF_IO_2_OE_DLY_SEL_LEN (2U) +#define SF_CTRL_SF_IO_2_OE_DLY_SEL_MSK (((1U << SF_CTRL_SF_IO_2_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_2_OE_DLY_SEL_POS) +#define SF_CTRL_SF_IO_2_OE_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF_IO_2_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_2_OE_DLY_SEL_POS)) +#define SF_CTRL_SF_IO_2_DI_DLY_SEL SF_CTRL_SF_IO_2_DI_DLY_SEL +#define SF_CTRL_SF_IO_2_DI_DLY_SEL_POS (8U) +#define SF_CTRL_SF_IO_2_DI_DLY_SEL_LEN (2U) +#define SF_CTRL_SF_IO_2_DI_DLY_SEL_MSK (((1U << SF_CTRL_SF_IO_2_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_2_DI_DLY_SEL_POS) +#define SF_CTRL_SF_IO_2_DI_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF_IO_2_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_2_DI_DLY_SEL_POS)) +#define SF_CTRL_SF_IO_2_DO_DLY_SEL SF_CTRL_SF_IO_2_DO_DLY_SEL +#define SF_CTRL_SF_IO_2_DO_DLY_SEL_POS (16U) +#define SF_CTRL_SF_IO_2_DO_DLY_SEL_LEN (2U) +#define SF_CTRL_SF_IO_2_DO_DLY_SEL_MSK (((1U << SF_CTRL_SF_IO_2_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_2_DO_DLY_SEL_POS) +#define SF_CTRL_SF_IO_2_DO_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF_IO_2_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_2_DO_DLY_SEL_POS)) + +/* 0x40 : sf_if_io_dly_4 */ +#define SF_CTRL_SF_IF_IO_DLY_4_OFFSET (0x40) +#define SF_CTRL_SF_IO_3_OE_DLY_SEL SF_CTRL_SF_IO_3_OE_DLY_SEL +#define SF_CTRL_SF_IO_3_OE_DLY_SEL_POS (0U) +#define SF_CTRL_SF_IO_3_OE_DLY_SEL_LEN (2U) +#define SF_CTRL_SF_IO_3_OE_DLY_SEL_MSK (((1U << SF_CTRL_SF_IO_3_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_3_OE_DLY_SEL_POS) +#define SF_CTRL_SF_IO_3_OE_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF_IO_3_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_3_OE_DLY_SEL_POS)) +#define SF_CTRL_SF_IO_3_DI_DLY_SEL SF_CTRL_SF_IO_3_DI_DLY_SEL +#define SF_CTRL_SF_IO_3_DI_DLY_SEL_POS (8U) +#define SF_CTRL_SF_IO_3_DI_DLY_SEL_LEN (2U) +#define SF_CTRL_SF_IO_3_DI_DLY_SEL_MSK (((1U << SF_CTRL_SF_IO_3_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_3_DI_DLY_SEL_POS) +#define SF_CTRL_SF_IO_3_DI_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF_IO_3_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_3_DI_DLY_SEL_POS)) +#define SF_CTRL_SF_IO_3_DO_DLY_SEL SF_CTRL_SF_IO_3_DO_DLY_SEL +#define SF_CTRL_SF_IO_3_DO_DLY_SEL_POS (16U) +#define SF_CTRL_SF_IO_3_DO_DLY_SEL_LEN (2U) +#define SF_CTRL_SF_IO_3_DO_DLY_SEL_MSK (((1U << SF_CTRL_SF_IO_3_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_3_DO_DLY_SEL_POS) +#define SF_CTRL_SF_IO_3_DO_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF_IO_3_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF_IO_3_DO_DLY_SEL_POS)) + +/* 0x44 : sf_reserved */ +#define SF_CTRL_SF_RESERVED_OFFSET (0x44) +#define SF_CTRL_SF_RESERVED SF_CTRL_SF_RESERVED +#define SF_CTRL_SF_RESERVED_POS (0U) +#define SF_CTRL_SF_RESERVED_LEN (32U) +#define SF_CTRL_SF_RESERVED_MSK (((1U << SF_CTRL_SF_RESERVED_LEN) - 1) << SF_CTRL_SF_RESERVED_POS) +#define SF_CTRL_SF_RESERVED_UMSK (~(((1U << SF_CTRL_SF_RESERVED_LEN) - 1) << SF_CTRL_SF_RESERVED_POS)) + +/* 0x48 : sf2_if_io_dly_0 */ +#define SF_CTRL_SF2_IF_IO_DLY_0_OFFSET (0x48) +#define SF_CTRL_SF2_CS_DLY_SEL SF_CTRL_SF2_CS_DLY_SEL +#define SF_CTRL_SF2_CS_DLY_SEL_POS (0U) +#define SF_CTRL_SF2_CS_DLY_SEL_LEN (2U) +#define SF_CTRL_SF2_CS_DLY_SEL_MSK (((1U << SF_CTRL_SF2_CS_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_CS_DLY_SEL_POS) +#define SF_CTRL_SF2_CS_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF2_CS_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_CS_DLY_SEL_POS)) +#define SF_CTRL_SF2_CS2_DLY_SEL SF_CTRL_SF2_CS2_DLY_SEL +#define SF_CTRL_SF2_CS2_DLY_SEL_POS (2U) +#define SF_CTRL_SF2_CS2_DLY_SEL_LEN (2U) +#define SF_CTRL_SF2_CS2_DLY_SEL_MSK (((1U << SF_CTRL_SF2_CS2_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_CS2_DLY_SEL_POS) +#define SF_CTRL_SF2_CS2_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF2_CS2_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_CS2_DLY_SEL_POS)) +#define SF_CTRL_SF2_CLK_OUT_DLY_SEL SF_CTRL_SF2_CLK_OUT_DLY_SEL +#define SF_CTRL_SF2_CLK_OUT_DLY_SEL_POS (8U) +#define SF_CTRL_SF2_CLK_OUT_DLY_SEL_LEN (2U) +#define SF_CTRL_SF2_CLK_OUT_DLY_SEL_MSK (((1U << SF_CTRL_SF2_CLK_OUT_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_CLK_OUT_DLY_SEL_POS) +#define SF_CTRL_SF2_CLK_OUT_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF2_CLK_OUT_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_CLK_OUT_DLY_SEL_POS)) +#define SF_CTRL_SF2_DQS_OE_DLY_SEL SF_CTRL_SF2_DQS_OE_DLY_SEL +#define SF_CTRL_SF2_DQS_OE_DLY_SEL_POS (26U) +#define SF_CTRL_SF2_DQS_OE_DLY_SEL_LEN (2U) +#define SF_CTRL_SF2_DQS_OE_DLY_SEL_MSK (((1U << SF_CTRL_SF2_DQS_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_DQS_OE_DLY_SEL_POS) +#define SF_CTRL_SF2_DQS_OE_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF2_DQS_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_DQS_OE_DLY_SEL_POS)) +#define SF_CTRL_SF2_DQS_DI_DLY_SEL SF_CTRL_SF2_DQS_DI_DLY_SEL +#define SF_CTRL_SF2_DQS_DI_DLY_SEL_POS (28U) +#define SF_CTRL_SF2_DQS_DI_DLY_SEL_LEN (2U) +#define SF_CTRL_SF2_DQS_DI_DLY_SEL_MSK (((1U << SF_CTRL_SF2_DQS_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_DQS_DI_DLY_SEL_POS) +#define SF_CTRL_SF2_DQS_DI_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF2_DQS_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_DQS_DI_DLY_SEL_POS)) +#define SF_CTRL_SF2_DQS_DO_DLY_SEL SF_CTRL_SF2_DQS_DO_DLY_SEL +#define SF_CTRL_SF2_DQS_DO_DLY_SEL_POS (30U) +#define SF_CTRL_SF2_DQS_DO_DLY_SEL_LEN (2U) +#define SF_CTRL_SF2_DQS_DO_DLY_SEL_MSK (((1U << SF_CTRL_SF2_DQS_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_DQS_DO_DLY_SEL_POS) +#define SF_CTRL_SF2_DQS_DO_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF2_DQS_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_DQS_DO_DLY_SEL_POS)) + +/* 0x4C : sf2_if_io_dly_1 */ +#define SF_CTRL_SF2_IF_IO_DLY_1_OFFSET (0x4C) +#define SF_CTRL_SF2_IO_0_OE_DLY_SEL SF_CTRL_SF2_IO_0_OE_DLY_SEL +#define SF_CTRL_SF2_IO_0_OE_DLY_SEL_POS (0U) +#define SF_CTRL_SF2_IO_0_OE_DLY_SEL_LEN (2U) +#define SF_CTRL_SF2_IO_0_OE_DLY_SEL_MSK (((1U << SF_CTRL_SF2_IO_0_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_0_OE_DLY_SEL_POS) +#define SF_CTRL_SF2_IO_0_OE_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF2_IO_0_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_0_OE_DLY_SEL_POS)) +#define SF_CTRL_SF2_IO_0_DI_DLY_SEL SF_CTRL_SF2_IO_0_DI_DLY_SEL +#define SF_CTRL_SF2_IO_0_DI_DLY_SEL_POS (8U) +#define SF_CTRL_SF2_IO_0_DI_DLY_SEL_LEN (2U) +#define SF_CTRL_SF2_IO_0_DI_DLY_SEL_MSK (((1U << SF_CTRL_SF2_IO_0_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_0_DI_DLY_SEL_POS) +#define SF_CTRL_SF2_IO_0_DI_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF2_IO_0_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_0_DI_DLY_SEL_POS)) +#define SF_CTRL_SF2_IO_0_DO_DLY_SEL SF_CTRL_SF2_IO_0_DO_DLY_SEL +#define SF_CTRL_SF2_IO_0_DO_DLY_SEL_POS (16U) +#define SF_CTRL_SF2_IO_0_DO_DLY_SEL_LEN (2U) +#define SF_CTRL_SF2_IO_0_DO_DLY_SEL_MSK (((1U << SF_CTRL_SF2_IO_0_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_0_DO_DLY_SEL_POS) +#define SF_CTRL_SF2_IO_0_DO_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF2_IO_0_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_0_DO_DLY_SEL_POS)) + +/* 0x50 : sf2_if_io_dly_2 */ +#define SF_CTRL_SF2_IF_IO_DLY_2_OFFSET (0x50) +#define SF_CTRL_SF2_IO_1_OE_DLY_SEL SF_CTRL_SF2_IO_1_OE_DLY_SEL +#define SF_CTRL_SF2_IO_1_OE_DLY_SEL_POS (0U) +#define SF_CTRL_SF2_IO_1_OE_DLY_SEL_LEN (2U) +#define SF_CTRL_SF2_IO_1_OE_DLY_SEL_MSK (((1U << SF_CTRL_SF2_IO_1_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_1_OE_DLY_SEL_POS) +#define SF_CTRL_SF2_IO_1_OE_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF2_IO_1_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_1_OE_DLY_SEL_POS)) +#define SF_CTRL_SF2_IO_1_DI_DLY_SEL SF_CTRL_SF2_IO_1_DI_DLY_SEL +#define SF_CTRL_SF2_IO_1_DI_DLY_SEL_POS (8U) +#define SF_CTRL_SF2_IO_1_DI_DLY_SEL_LEN (2U) +#define SF_CTRL_SF2_IO_1_DI_DLY_SEL_MSK (((1U << SF_CTRL_SF2_IO_1_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_1_DI_DLY_SEL_POS) +#define SF_CTRL_SF2_IO_1_DI_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF2_IO_1_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_1_DI_DLY_SEL_POS)) +#define SF_CTRL_SF2_IO_1_DO_DLY_SEL SF_CTRL_SF2_IO_1_DO_DLY_SEL +#define SF_CTRL_SF2_IO_1_DO_DLY_SEL_POS (16U) +#define SF_CTRL_SF2_IO_1_DO_DLY_SEL_LEN (2U) +#define SF_CTRL_SF2_IO_1_DO_DLY_SEL_MSK (((1U << SF_CTRL_SF2_IO_1_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_1_DO_DLY_SEL_POS) +#define SF_CTRL_SF2_IO_1_DO_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF2_IO_1_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_1_DO_DLY_SEL_POS)) + +/* 0x54 : sf2_if_io_dly_3 */ +#define SF_CTRL_SF2_IF_IO_DLY_3_OFFSET (0x54) +#define SF_CTRL_SF2_IO_2_OE_DLY_SEL SF_CTRL_SF2_IO_2_OE_DLY_SEL +#define SF_CTRL_SF2_IO_2_OE_DLY_SEL_POS (0U) +#define SF_CTRL_SF2_IO_2_OE_DLY_SEL_LEN (2U) +#define SF_CTRL_SF2_IO_2_OE_DLY_SEL_MSK (((1U << SF_CTRL_SF2_IO_2_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_2_OE_DLY_SEL_POS) +#define SF_CTRL_SF2_IO_2_OE_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF2_IO_2_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_2_OE_DLY_SEL_POS)) +#define SF_CTRL_SF2_IO_2_DI_DLY_SEL SF_CTRL_SF2_IO_2_DI_DLY_SEL +#define SF_CTRL_SF2_IO_2_DI_DLY_SEL_POS (8U) +#define SF_CTRL_SF2_IO_2_DI_DLY_SEL_LEN (2U) +#define SF_CTRL_SF2_IO_2_DI_DLY_SEL_MSK (((1U << SF_CTRL_SF2_IO_2_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_2_DI_DLY_SEL_POS) +#define SF_CTRL_SF2_IO_2_DI_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF2_IO_2_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_2_DI_DLY_SEL_POS)) +#define SF_CTRL_SF2_IO_2_DO_DLY_SEL SF_CTRL_SF2_IO_2_DO_DLY_SEL +#define SF_CTRL_SF2_IO_2_DO_DLY_SEL_POS (16U) +#define SF_CTRL_SF2_IO_2_DO_DLY_SEL_LEN (2U) +#define SF_CTRL_SF2_IO_2_DO_DLY_SEL_MSK (((1U << SF_CTRL_SF2_IO_2_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_2_DO_DLY_SEL_POS) +#define SF_CTRL_SF2_IO_2_DO_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF2_IO_2_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_2_DO_DLY_SEL_POS)) + +/* 0x58 : sf2_if_io_dly_4 */ +#define SF_CTRL_SF2_IF_IO_DLY_4_OFFSET (0x58) +#define SF_CTRL_SF2_IO_3_OE_DLY_SEL SF_CTRL_SF2_IO_3_OE_DLY_SEL +#define SF_CTRL_SF2_IO_3_OE_DLY_SEL_POS (0U) +#define SF_CTRL_SF2_IO_3_OE_DLY_SEL_LEN (2U) +#define SF_CTRL_SF2_IO_3_OE_DLY_SEL_MSK (((1U << SF_CTRL_SF2_IO_3_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_3_OE_DLY_SEL_POS) +#define SF_CTRL_SF2_IO_3_OE_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF2_IO_3_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_3_OE_DLY_SEL_POS)) +#define SF_CTRL_SF2_IO_3_DI_DLY_SEL SF_CTRL_SF2_IO_3_DI_DLY_SEL +#define SF_CTRL_SF2_IO_3_DI_DLY_SEL_POS (8U) +#define SF_CTRL_SF2_IO_3_DI_DLY_SEL_LEN (2U) +#define SF_CTRL_SF2_IO_3_DI_DLY_SEL_MSK (((1U << SF_CTRL_SF2_IO_3_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_3_DI_DLY_SEL_POS) +#define SF_CTRL_SF2_IO_3_DI_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF2_IO_3_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_3_DI_DLY_SEL_POS)) +#define SF_CTRL_SF2_IO_3_DO_DLY_SEL SF_CTRL_SF2_IO_3_DO_DLY_SEL +#define SF_CTRL_SF2_IO_3_DO_DLY_SEL_POS (16U) +#define SF_CTRL_SF2_IO_3_DO_DLY_SEL_LEN (2U) +#define SF_CTRL_SF2_IO_3_DO_DLY_SEL_MSK (((1U << SF_CTRL_SF2_IO_3_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_3_DO_DLY_SEL_POS) +#define SF_CTRL_SF2_IO_3_DO_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF2_IO_3_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF2_IO_3_DO_DLY_SEL_POS)) + +/* 0x5C : sf3_if_io_dly_0 */ +#define SF_CTRL_SF3_IF_IO_DLY_0_OFFSET (0x5C) +#define SF_CTRL_SF3_CS_DLY_SEL SF_CTRL_SF3_CS_DLY_SEL +#define SF_CTRL_SF3_CS_DLY_SEL_POS (0U) +#define SF_CTRL_SF3_CS_DLY_SEL_LEN (2U) +#define SF_CTRL_SF3_CS_DLY_SEL_MSK (((1U << SF_CTRL_SF3_CS_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_CS_DLY_SEL_POS) +#define SF_CTRL_SF3_CS_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF3_CS_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_CS_DLY_SEL_POS)) +#define SF_CTRL_SF3_CS2_DLY_SEL SF_CTRL_SF3_CS2_DLY_SEL +#define SF_CTRL_SF3_CS2_DLY_SEL_POS (2U) +#define SF_CTRL_SF3_CS2_DLY_SEL_LEN (2U) +#define SF_CTRL_SF3_CS2_DLY_SEL_MSK (((1U << SF_CTRL_SF3_CS2_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_CS2_DLY_SEL_POS) +#define SF_CTRL_SF3_CS2_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF3_CS2_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_CS2_DLY_SEL_POS)) +#define SF_CTRL_SF3_CLK_OUT_DLY_SEL SF_CTRL_SF3_CLK_OUT_DLY_SEL +#define SF_CTRL_SF3_CLK_OUT_DLY_SEL_POS (8U) +#define SF_CTRL_SF3_CLK_OUT_DLY_SEL_LEN (2U) +#define SF_CTRL_SF3_CLK_OUT_DLY_SEL_MSK (((1U << SF_CTRL_SF3_CLK_OUT_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_CLK_OUT_DLY_SEL_POS) +#define SF_CTRL_SF3_CLK_OUT_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF3_CLK_OUT_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_CLK_OUT_DLY_SEL_POS)) +#define SF_CTRL_SF3_DQS_OE_DLY_SEL SF_CTRL_SF3_DQS_OE_DLY_SEL +#define SF_CTRL_SF3_DQS_OE_DLY_SEL_POS (26U) +#define SF_CTRL_SF3_DQS_OE_DLY_SEL_LEN (2U) +#define SF_CTRL_SF3_DQS_OE_DLY_SEL_MSK (((1U << SF_CTRL_SF3_DQS_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_DQS_OE_DLY_SEL_POS) +#define SF_CTRL_SF3_DQS_OE_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF3_DQS_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_DQS_OE_DLY_SEL_POS)) +#define SF_CTRL_SF3_DQS_DI_DLY_SEL SF_CTRL_SF3_DQS_DI_DLY_SEL +#define SF_CTRL_SF3_DQS_DI_DLY_SEL_POS (28U) +#define SF_CTRL_SF3_DQS_DI_DLY_SEL_LEN (2U) +#define SF_CTRL_SF3_DQS_DI_DLY_SEL_MSK (((1U << SF_CTRL_SF3_DQS_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_DQS_DI_DLY_SEL_POS) +#define SF_CTRL_SF3_DQS_DI_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF3_DQS_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_DQS_DI_DLY_SEL_POS)) +#define SF_CTRL_SF3_DQS_DO_DLY_SEL SF_CTRL_SF3_DQS_DO_DLY_SEL +#define SF_CTRL_SF3_DQS_DO_DLY_SEL_POS (30U) +#define SF_CTRL_SF3_DQS_DO_DLY_SEL_LEN (2U) +#define SF_CTRL_SF3_DQS_DO_DLY_SEL_MSK (((1U << SF_CTRL_SF3_DQS_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_DQS_DO_DLY_SEL_POS) +#define SF_CTRL_SF3_DQS_DO_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF3_DQS_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_DQS_DO_DLY_SEL_POS)) + +/* 0x60 : sf3_if_io_dly_1 */ +#define SF_CTRL_SF3_IF_IO_DLY_1_OFFSET (0x60) +#define SF_CTRL_SF3_IO_0_OE_DLY_SEL SF_CTRL_SF3_IO_0_OE_DLY_SEL +#define SF_CTRL_SF3_IO_0_OE_DLY_SEL_POS (0U) +#define SF_CTRL_SF3_IO_0_OE_DLY_SEL_LEN (2U) +#define SF_CTRL_SF3_IO_0_OE_DLY_SEL_MSK (((1U << SF_CTRL_SF3_IO_0_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_0_OE_DLY_SEL_POS) +#define SF_CTRL_SF3_IO_0_OE_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF3_IO_0_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_0_OE_DLY_SEL_POS)) +#define SF_CTRL_SF3_IO_0_DI_DLY_SEL SF_CTRL_SF3_IO_0_DI_DLY_SEL +#define SF_CTRL_SF3_IO_0_DI_DLY_SEL_POS (8U) +#define SF_CTRL_SF3_IO_0_DI_DLY_SEL_LEN (2U) +#define SF_CTRL_SF3_IO_0_DI_DLY_SEL_MSK (((1U << SF_CTRL_SF3_IO_0_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_0_DI_DLY_SEL_POS) +#define SF_CTRL_SF3_IO_0_DI_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF3_IO_0_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_0_DI_DLY_SEL_POS)) +#define SF_CTRL_SF3_IO_0_DO_DLY_SEL SF_CTRL_SF3_IO_0_DO_DLY_SEL +#define SF_CTRL_SF3_IO_0_DO_DLY_SEL_POS (16U) +#define SF_CTRL_SF3_IO_0_DO_DLY_SEL_LEN (2U) +#define SF_CTRL_SF3_IO_0_DO_DLY_SEL_MSK (((1U << SF_CTRL_SF3_IO_0_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_0_DO_DLY_SEL_POS) +#define SF_CTRL_SF3_IO_0_DO_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF3_IO_0_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_0_DO_DLY_SEL_POS)) + +/* 0x64 : sf3_if_io_dly_2 */ +#define SF_CTRL_SF3_IF_IO_DLY_2_OFFSET (0x64) +#define SF_CTRL_SF3_IO_1_OE_DLY_SEL SF_CTRL_SF3_IO_1_OE_DLY_SEL +#define SF_CTRL_SF3_IO_1_OE_DLY_SEL_POS (0U) +#define SF_CTRL_SF3_IO_1_OE_DLY_SEL_LEN (2U) +#define SF_CTRL_SF3_IO_1_OE_DLY_SEL_MSK (((1U << SF_CTRL_SF3_IO_1_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_1_OE_DLY_SEL_POS) +#define SF_CTRL_SF3_IO_1_OE_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF3_IO_1_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_1_OE_DLY_SEL_POS)) +#define SF_CTRL_SF3_IO_1_DI_DLY_SEL SF_CTRL_SF3_IO_1_DI_DLY_SEL +#define SF_CTRL_SF3_IO_1_DI_DLY_SEL_POS (8U) +#define SF_CTRL_SF3_IO_1_DI_DLY_SEL_LEN (2U) +#define SF_CTRL_SF3_IO_1_DI_DLY_SEL_MSK (((1U << SF_CTRL_SF3_IO_1_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_1_DI_DLY_SEL_POS) +#define SF_CTRL_SF3_IO_1_DI_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF3_IO_1_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_1_DI_DLY_SEL_POS)) +#define SF_CTRL_SF3_IO_1_DO_DLY_SEL SF_CTRL_SF3_IO_1_DO_DLY_SEL +#define SF_CTRL_SF3_IO_1_DO_DLY_SEL_POS (16U) +#define SF_CTRL_SF3_IO_1_DO_DLY_SEL_LEN (2U) +#define SF_CTRL_SF3_IO_1_DO_DLY_SEL_MSK (((1U << SF_CTRL_SF3_IO_1_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_1_DO_DLY_SEL_POS) +#define SF_CTRL_SF3_IO_1_DO_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF3_IO_1_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_1_DO_DLY_SEL_POS)) + +/* 0x68 : sf3_if_io_dly_3 */ +#define SF_CTRL_SF3_IF_IO_DLY_3_OFFSET (0x68) +#define SF_CTRL_SF3_IO_2_OE_DLY_SEL SF_CTRL_SF3_IO_2_OE_DLY_SEL +#define SF_CTRL_SF3_IO_2_OE_DLY_SEL_POS (0U) +#define SF_CTRL_SF3_IO_2_OE_DLY_SEL_LEN (2U) +#define SF_CTRL_SF3_IO_2_OE_DLY_SEL_MSK (((1U << SF_CTRL_SF3_IO_2_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_2_OE_DLY_SEL_POS) +#define SF_CTRL_SF3_IO_2_OE_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF3_IO_2_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_2_OE_DLY_SEL_POS)) +#define SF_CTRL_SF3_IO_2_DI_DLY_SEL SF_CTRL_SF3_IO_2_DI_DLY_SEL +#define SF_CTRL_SF3_IO_2_DI_DLY_SEL_POS (8U) +#define SF_CTRL_SF3_IO_2_DI_DLY_SEL_LEN (2U) +#define SF_CTRL_SF3_IO_2_DI_DLY_SEL_MSK (((1U << SF_CTRL_SF3_IO_2_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_2_DI_DLY_SEL_POS) +#define SF_CTRL_SF3_IO_2_DI_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF3_IO_2_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_2_DI_DLY_SEL_POS)) +#define SF_CTRL_SF3_IO_2_DO_DLY_SEL SF_CTRL_SF3_IO_2_DO_DLY_SEL +#define SF_CTRL_SF3_IO_2_DO_DLY_SEL_POS (16U) +#define SF_CTRL_SF3_IO_2_DO_DLY_SEL_LEN (2U) +#define SF_CTRL_SF3_IO_2_DO_DLY_SEL_MSK (((1U << SF_CTRL_SF3_IO_2_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_2_DO_DLY_SEL_POS) +#define SF_CTRL_SF3_IO_2_DO_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF3_IO_2_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_2_DO_DLY_SEL_POS)) + +/* 0x6C : sf3_if_io_dly_4 */ +#define SF_CTRL_SF3_IF_IO_DLY_4_OFFSET (0x6C) +#define SF_CTRL_SF3_IO_3_OE_DLY_SEL SF_CTRL_SF3_IO_3_OE_DLY_SEL +#define SF_CTRL_SF3_IO_3_OE_DLY_SEL_POS (0U) +#define SF_CTRL_SF3_IO_3_OE_DLY_SEL_LEN (2U) +#define SF_CTRL_SF3_IO_3_OE_DLY_SEL_MSK (((1U << SF_CTRL_SF3_IO_3_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_3_OE_DLY_SEL_POS) +#define SF_CTRL_SF3_IO_3_OE_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF3_IO_3_OE_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_3_OE_DLY_SEL_POS)) +#define SF_CTRL_SF3_IO_3_DI_DLY_SEL SF_CTRL_SF3_IO_3_DI_DLY_SEL +#define SF_CTRL_SF3_IO_3_DI_DLY_SEL_POS (8U) +#define SF_CTRL_SF3_IO_3_DI_DLY_SEL_LEN (2U) +#define SF_CTRL_SF3_IO_3_DI_DLY_SEL_MSK (((1U << SF_CTRL_SF3_IO_3_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_3_DI_DLY_SEL_POS) +#define SF_CTRL_SF3_IO_3_DI_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF3_IO_3_DI_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_3_DI_DLY_SEL_POS)) +#define SF_CTRL_SF3_IO_3_DO_DLY_SEL SF_CTRL_SF3_IO_3_DO_DLY_SEL +#define SF_CTRL_SF3_IO_3_DO_DLY_SEL_POS (16U) +#define SF_CTRL_SF3_IO_3_DO_DLY_SEL_LEN (2U) +#define SF_CTRL_SF3_IO_3_DO_DLY_SEL_MSK (((1U << SF_CTRL_SF3_IO_3_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_3_DO_DLY_SEL_POS) +#define SF_CTRL_SF3_IO_3_DO_DLY_SEL_UMSK (~(((1U << SF_CTRL_SF3_IO_3_DO_DLY_SEL_LEN) - 1) << SF_CTRL_SF3_IO_3_DO_DLY_SEL_POS)) + +/* 0x70 : sf_ctrl_2 */ +#define SF_CTRL_2_OFFSET (0x70) +#define SF_CTRL_SF_IF_PAD_SEL SF_CTRL_SF_IF_PAD_SEL +#define SF_CTRL_SF_IF_PAD_SEL_POS (0U) +#define SF_CTRL_SF_IF_PAD_SEL_LEN (2U) +#define SF_CTRL_SF_IF_PAD_SEL_MSK (((1U << SF_CTRL_SF_IF_PAD_SEL_LEN) - 1) << SF_CTRL_SF_IF_PAD_SEL_POS) +#define SF_CTRL_SF_IF_PAD_SEL_UMSK (~(((1U << SF_CTRL_SF_IF_PAD_SEL_LEN) - 1) << SF_CTRL_SF_IF_PAD_SEL_POS)) +#define SF_CTRL_SF_IF_PAD_SEL_LOCK SF_CTRL_SF_IF_PAD_SEL_LOCK +#define SF_CTRL_SF_IF_PAD_SEL_LOCK_POS (3U) +#define SF_CTRL_SF_IF_PAD_SEL_LOCK_LEN (1U) +#define SF_CTRL_SF_IF_PAD_SEL_LOCK_MSK (((1U << SF_CTRL_SF_IF_PAD_SEL_LOCK_LEN) - 1) << SF_CTRL_SF_IF_PAD_SEL_LOCK_POS) +#define SF_CTRL_SF_IF_PAD_SEL_LOCK_UMSK (~(((1U << SF_CTRL_SF_IF_PAD_SEL_LOCK_LEN) - 1) << SF_CTRL_SF_IF_PAD_SEL_LOCK_POS)) +#define SF_CTRL_SF_IF_DTR_EN SF_CTRL_SF_IF_DTR_EN +#define SF_CTRL_SF_IF_DTR_EN_POS (4U) +#define SF_CTRL_SF_IF_DTR_EN_LEN (1U) +#define SF_CTRL_SF_IF_DTR_EN_MSK (((1U << SF_CTRL_SF_IF_DTR_EN_LEN) - 1) << SF_CTRL_SF_IF_DTR_EN_POS) +#define SF_CTRL_SF_IF_DTR_EN_UMSK (~(((1U << SF_CTRL_SF_IF_DTR_EN_LEN) - 1) << SF_CTRL_SF_IF_DTR_EN_POS)) +#define SF_CTRL_SF_IF_DQS_EN SF_CTRL_SF_IF_DQS_EN +#define SF_CTRL_SF_IF_DQS_EN_POS (5U) +#define SF_CTRL_SF_IF_DQS_EN_LEN (1U) +#define SF_CTRL_SF_IF_DQS_EN_MSK (((1U << SF_CTRL_SF_IF_DQS_EN_LEN) - 1) << SF_CTRL_SF_IF_DQS_EN_POS) +#define SF_CTRL_SF_IF_DQS_EN_UMSK (~(((1U << SF_CTRL_SF_IF_DQS_EN_LEN) - 1) << SF_CTRL_SF_IF_DQS_EN_POS)) +#define SF_CTRL_SF_IF_TRIG_WR_PROT SF_CTRL_SF_IF_TRIG_WR_PROT +#define SF_CTRL_SF_IF_TRIG_WR_PROT_POS (6U) +#define SF_CTRL_SF_IF_TRIG_WR_PROT_LEN (1U) +#define SF_CTRL_SF_IF_TRIG_WR_PROT_MSK (((1U << SF_CTRL_SF_IF_TRIG_WR_PROT_LEN) - 1) << SF_CTRL_SF_IF_TRIG_WR_PROT_POS) +#define SF_CTRL_SF_IF_TRIG_WR_PROT_UMSK (~(((1U << SF_CTRL_SF_IF_TRIG_WR_PROT_LEN) - 1) << SF_CTRL_SF_IF_TRIG_WR_PROT_POS)) +#define SF_CTRL_SF_ID_OFFSET_LOCK SF_CTRL_SF_ID_OFFSET_LOCK +#define SF_CTRL_SF_ID_OFFSET_LOCK_POS (7U) +#define SF_CTRL_SF_ID_OFFSET_LOCK_LEN (1U) +#define SF_CTRL_SF_ID_OFFSET_LOCK_MSK (((1U << SF_CTRL_SF_ID_OFFSET_LOCK_LEN) - 1) << SF_CTRL_SF_ID_OFFSET_LOCK_POS) +#define SF_CTRL_SF_ID_OFFSET_LOCK_UMSK (~(((1U << SF_CTRL_SF_ID_OFFSET_LOCK_LEN) - 1) << SF_CTRL_SF_ID_OFFSET_LOCK_POS)) +#define SF_CTRL_SF_AHB2SIF_REMAP_LOCK SF_CTRL_SF_AHB2SIF_REMAP_LOCK +#define SF_CTRL_SF_AHB2SIF_REMAP_LOCK_POS (25U) +#define SF_CTRL_SF_AHB2SIF_REMAP_LOCK_LEN (1U) +#define SF_CTRL_SF_AHB2SIF_REMAP_LOCK_MSK (((1U << SF_CTRL_SF_AHB2SIF_REMAP_LOCK_LEN) - 1) << SF_CTRL_SF_AHB2SIF_REMAP_LOCK_POS) +#define SF_CTRL_SF_AHB2SIF_REMAP_LOCK_UMSK (~(((1U << SF_CTRL_SF_AHB2SIF_REMAP_LOCK_LEN) - 1) << SF_CTRL_SF_AHB2SIF_REMAP_LOCK_POS)) +#define SF_CTRL_SF_AHB2SIF_REMAP SF_CTRL_SF_AHB2SIF_REMAP +#define SF_CTRL_SF_AHB2SIF_REMAP_POS (26U) +#define SF_CTRL_SF_AHB2SIF_REMAP_LEN (2U) +#define SF_CTRL_SF_AHB2SIF_REMAP_MSK (((1U << SF_CTRL_SF_AHB2SIF_REMAP_LEN) - 1) << SF_CTRL_SF_AHB2SIF_REMAP_POS) +#define SF_CTRL_SF_AHB2SIF_REMAP_UMSK (~(((1U << SF_CTRL_SF_AHB2SIF_REMAP_LEN) - 1) << SF_CTRL_SF_AHB2SIF_REMAP_POS)) +#define SF_CTRL_SF_IF_BK_SWAP SF_CTRL_SF_IF_BK_SWAP +#define SF_CTRL_SF_IF_BK_SWAP_POS (28U) +#define SF_CTRL_SF_IF_BK_SWAP_LEN (1U) +#define SF_CTRL_SF_IF_BK_SWAP_MSK (((1U << SF_CTRL_SF_IF_BK_SWAP_LEN) - 1) << SF_CTRL_SF_IF_BK_SWAP_POS) +#define SF_CTRL_SF_IF_BK_SWAP_UMSK (~(((1U << SF_CTRL_SF_IF_BK_SWAP_LEN) - 1) << SF_CTRL_SF_IF_BK_SWAP_POS)) +#define SF_CTRL_SF_IF_BK2_MODE SF_CTRL_SF_IF_BK2_MODE +#define SF_CTRL_SF_IF_BK2_MODE_POS (29U) +#define SF_CTRL_SF_IF_BK2_MODE_LEN (1U) +#define SF_CTRL_SF_IF_BK2_MODE_MSK (((1U << SF_CTRL_SF_IF_BK2_MODE_LEN) - 1) << SF_CTRL_SF_IF_BK2_MODE_POS) +#define SF_CTRL_SF_IF_BK2_MODE_UMSK (~(((1U << SF_CTRL_SF_IF_BK2_MODE_LEN) - 1) << SF_CTRL_SF_IF_BK2_MODE_POS)) +#define SF_CTRL_SF_IF_BK2_EN SF_CTRL_SF_IF_BK2_EN +#define SF_CTRL_SF_IF_BK2_EN_POS (30U) +#define SF_CTRL_SF_IF_BK2_EN_LEN (1U) +#define SF_CTRL_SF_IF_BK2_EN_MSK (((1U << SF_CTRL_SF_IF_BK2_EN_LEN) - 1) << SF_CTRL_SF_IF_BK2_EN_POS) +#define SF_CTRL_SF_IF_BK2_EN_UMSK (~(((1U << SF_CTRL_SF_IF_BK2_EN_LEN) - 1) << SF_CTRL_SF_IF_BK2_EN_POS)) +#define SF_CTRL_SF_IF_0_BK_SEL SF_CTRL_SF_IF_0_BK_SEL +#define SF_CTRL_SF_IF_0_BK_SEL_POS (31U) +#define SF_CTRL_SF_IF_0_BK_SEL_LEN (1U) +#define SF_CTRL_SF_IF_0_BK_SEL_MSK (((1U << SF_CTRL_SF_IF_0_BK_SEL_LEN) - 1) << SF_CTRL_SF_IF_0_BK_SEL_POS) +#define SF_CTRL_SF_IF_0_BK_SEL_UMSK (~(((1U << SF_CTRL_SF_IF_0_BK_SEL_LEN) - 1) << SF_CTRL_SF_IF_0_BK_SEL_POS)) + +/* 0x74 : sf_ctrl_3 */ +#define SF_CTRL_3_OFFSET (0x74) +#define SF_CTRL_SF_CMDS_2_WRAP_LEN SF_CTRL_SF_CMDS_2_WRAP_LEN +#define SF_CTRL_SF_CMDS_2_WRAP_LEN_POS (0U) +#define SF_CTRL_SF_CMDS_2_WRAP_LEN_LEN (4U) +#define SF_CTRL_SF_CMDS_2_WRAP_LEN_MSK (((1U << SF_CTRL_SF_CMDS_2_WRAP_LEN_LEN) - 1) << SF_CTRL_SF_CMDS_2_WRAP_LEN_POS) +#define SF_CTRL_SF_CMDS_2_WRAP_LEN_UMSK (~(((1U << SF_CTRL_SF_CMDS_2_WRAP_LEN_LEN) - 1) << SF_CTRL_SF_CMDS_2_WRAP_LEN_POS)) +#define SF_CTRL_SF_CMDS_2_EN SF_CTRL_SF_CMDS_2_EN +#define SF_CTRL_SF_CMDS_2_EN_POS (4U) +#define SF_CTRL_SF_CMDS_2_EN_LEN (1U) +#define SF_CTRL_SF_CMDS_2_EN_MSK (((1U << SF_CTRL_SF_CMDS_2_EN_LEN) - 1) << SF_CTRL_SF_CMDS_2_EN_POS) +#define SF_CTRL_SF_CMDS_2_EN_UMSK (~(((1U << SF_CTRL_SF_CMDS_2_EN_LEN) - 1) << SF_CTRL_SF_CMDS_2_EN_POS)) +#define SF_CTRL_SF_CMDS_2_BT_DLY SF_CTRL_SF_CMDS_2_BT_DLY +#define SF_CTRL_SF_CMDS_2_BT_DLY_POS (5U) +#define SF_CTRL_SF_CMDS_2_BT_DLY_LEN (3U) +#define SF_CTRL_SF_CMDS_2_BT_DLY_MSK (((1U << SF_CTRL_SF_CMDS_2_BT_DLY_LEN) - 1) << SF_CTRL_SF_CMDS_2_BT_DLY_POS) +#define SF_CTRL_SF_CMDS_2_BT_DLY_UMSK (~(((1U << SF_CTRL_SF_CMDS_2_BT_DLY_LEN) - 1) << SF_CTRL_SF_CMDS_2_BT_DLY_POS)) +#define SF_CTRL_SF_CMDS_2_BT_EN SF_CTRL_SF_CMDS_2_BT_EN +#define SF_CTRL_SF_CMDS_2_BT_EN_POS (8U) +#define SF_CTRL_SF_CMDS_2_BT_EN_LEN (1U) +#define SF_CTRL_SF_CMDS_2_BT_EN_MSK (((1U << SF_CTRL_SF_CMDS_2_BT_EN_LEN) - 1) << SF_CTRL_SF_CMDS_2_BT_EN_POS) +#define SF_CTRL_SF_CMDS_2_BT_EN_UMSK (~(((1U << SF_CTRL_SF_CMDS_2_BT_EN_LEN) - 1) << SF_CTRL_SF_CMDS_2_BT_EN_POS)) +#define SF_CTRL_SF_CMDS_2_WRAP_Q_INI SF_CTRL_SF_CMDS_2_WRAP_Q_INI +#define SF_CTRL_SF_CMDS_2_WRAP_Q_INI_POS (9U) +#define SF_CTRL_SF_CMDS_2_WRAP_Q_INI_LEN (1U) +#define SF_CTRL_SF_CMDS_2_WRAP_Q_INI_MSK (((1U << SF_CTRL_SF_CMDS_2_WRAP_Q_INI_LEN) - 1) << SF_CTRL_SF_CMDS_2_WRAP_Q_INI_POS) +#define SF_CTRL_SF_CMDS_2_WRAP_Q_INI_UMSK (~(((1U << SF_CTRL_SF_CMDS_2_WRAP_Q_INI_LEN) - 1) << SF_CTRL_SF_CMDS_2_WRAP_Q_INI_POS)) +#define SF_CTRL_SF_CMDS_2_WRAP_MODE SF_CTRL_SF_CMDS_2_WRAP_MODE +#define SF_CTRL_SF_CMDS_2_WRAP_MODE_POS (10U) +#define SF_CTRL_SF_CMDS_2_WRAP_MODE_LEN (2U) +#define SF_CTRL_SF_CMDS_2_WRAP_MODE_MSK (((1U << SF_CTRL_SF_CMDS_2_WRAP_MODE_LEN) - 1) << SF_CTRL_SF_CMDS_2_WRAP_MODE_POS) +#define SF_CTRL_SF_CMDS_2_WRAP_MODE_UMSK (~(((1U << SF_CTRL_SF_CMDS_2_WRAP_MODE_LEN) - 1) << SF_CTRL_SF_CMDS_2_WRAP_MODE_POS)) +#define SF_CTRL_SF_CMDS_2_WRAP_Q SF_CTRL_SF_CMDS_2_WRAP_Q +#define SF_CTRL_SF_CMDS_2_WRAP_Q_POS (12U) +#define SF_CTRL_SF_CMDS_2_WRAP_Q_LEN (1U) +#define SF_CTRL_SF_CMDS_2_WRAP_Q_MSK (((1U << SF_CTRL_SF_CMDS_2_WRAP_Q_LEN) - 1) << SF_CTRL_SF_CMDS_2_WRAP_Q_POS) +#define SF_CTRL_SF_CMDS_2_WRAP_Q_UMSK (~(((1U << SF_CTRL_SF_CMDS_2_WRAP_Q_LEN) - 1) << SF_CTRL_SF_CMDS_2_WRAP_Q_POS)) +#define SF_CTRL_SF_CMDS_1_WRAP_LEN SF_CTRL_SF_CMDS_1_WRAP_LEN +#define SF_CTRL_SF_CMDS_1_WRAP_LEN_POS (13U) +#define SF_CTRL_SF_CMDS_1_WRAP_LEN_LEN (4U) +#define SF_CTRL_SF_CMDS_1_WRAP_LEN_MSK (((1U << SF_CTRL_SF_CMDS_1_WRAP_LEN_LEN) - 1) << SF_CTRL_SF_CMDS_1_WRAP_LEN_POS) +#define SF_CTRL_SF_CMDS_1_WRAP_LEN_UMSK (~(((1U << SF_CTRL_SF_CMDS_1_WRAP_LEN_LEN) - 1) << SF_CTRL_SF_CMDS_1_WRAP_LEN_POS)) +#define SF_CTRL_SF_CMDS_1_EN SF_CTRL_SF_CMDS_1_EN +#define SF_CTRL_SF_CMDS_1_EN_POS (17U) +#define SF_CTRL_SF_CMDS_1_EN_LEN (1U) +#define SF_CTRL_SF_CMDS_1_EN_MSK (((1U << SF_CTRL_SF_CMDS_1_EN_LEN) - 1) << SF_CTRL_SF_CMDS_1_EN_POS) +#define SF_CTRL_SF_CMDS_1_EN_UMSK (~(((1U << SF_CTRL_SF_CMDS_1_EN_LEN) - 1) << SF_CTRL_SF_CMDS_1_EN_POS)) +#define SF_CTRL_SF_CMDS_1_WRAP_MODE SF_CTRL_SF_CMDS_1_WRAP_MODE +#define SF_CTRL_SF_CMDS_1_WRAP_MODE_POS (18U) +#define SF_CTRL_SF_CMDS_1_WRAP_MODE_LEN (2U) +#define SF_CTRL_SF_CMDS_1_WRAP_MODE_MSK (((1U << SF_CTRL_SF_CMDS_1_WRAP_MODE_LEN) - 1) << SF_CTRL_SF_CMDS_1_WRAP_MODE_POS) +#define SF_CTRL_SF_CMDS_1_WRAP_MODE_UMSK (~(((1U << SF_CTRL_SF_CMDS_1_WRAP_MODE_LEN) - 1) << SF_CTRL_SF_CMDS_1_WRAP_MODE_POS)) +#define SF_CTRL_SF_CMDS_CORE_EN SF_CTRL_SF_CMDS_CORE_EN +#define SF_CTRL_SF_CMDS_CORE_EN_POS (20U) +#define SF_CTRL_SF_CMDS_CORE_EN_LEN (1U) +#define SF_CTRL_SF_CMDS_CORE_EN_MSK (((1U << SF_CTRL_SF_CMDS_CORE_EN_LEN) - 1) << SF_CTRL_SF_CMDS_CORE_EN_POS) +#define SF_CTRL_SF_CMDS_CORE_EN_UMSK (~(((1U << SF_CTRL_SF_CMDS_CORE_EN_LEN) - 1) << SF_CTRL_SF_CMDS_CORE_EN_POS)) +#define SF_CTRL_SF_IF_1_ACK_LAT SF_CTRL_SF_IF_1_ACK_LAT +#define SF_CTRL_SF_IF_1_ACK_LAT_POS (29U) +#define SF_CTRL_SF_IF_1_ACK_LAT_LEN (3U) +#define SF_CTRL_SF_IF_1_ACK_LAT_MSK (((1U << SF_CTRL_SF_IF_1_ACK_LAT_LEN) - 1) << SF_CTRL_SF_IF_1_ACK_LAT_POS) +#define SF_CTRL_SF_IF_1_ACK_LAT_UMSK (~(((1U << SF_CTRL_SF_IF_1_ACK_LAT_LEN) - 1) << SF_CTRL_SF_IF_1_ACK_LAT_POS)) + +/* 0x78 : sf_if_iahb_3 */ +#define SF_CTRL_SF_IF_IAHB_3_OFFSET (0x78) +#define SF_CTRL_SF_IF_2_DMY_BYTE SF_CTRL_SF_IF_2_DMY_BYTE +#define SF_CTRL_SF_IF_2_DMY_BYTE_POS (12U) +#define SF_CTRL_SF_IF_2_DMY_BYTE_LEN (5U) +#define SF_CTRL_SF_IF_2_DMY_BYTE_MSK (((1U << SF_CTRL_SF_IF_2_DMY_BYTE_LEN) - 1) << SF_CTRL_SF_IF_2_DMY_BYTE_POS) +#define SF_CTRL_SF_IF_2_DMY_BYTE_UMSK (~(((1U << SF_CTRL_SF_IF_2_DMY_BYTE_LEN) - 1) << SF_CTRL_SF_IF_2_DMY_BYTE_POS)) +#define SF_CTRL_SF_IF_2_ADR_BYTE SF_CTRL_SF_IF_2_ADR_BYTE +#define SF_CTRL_SF_IF_2_ADR_BYTE_POS (17U) +#define SF_CTRL_SF_IF_2_ADR_BYTE_LEN (3U) +#define SF_CTRL_SF_IF_2_ADR_BYTE_MSK (((1U << SF_CTRL_SF_IF_2_ADR_BYTE_LEN) - 1) << SF_CTRL_SF_IF_2_ADR_BYTE_POS) +#define SF_CTRL_SF_IF_2_ADR_BYTE_UMSK (~(((1U << SF_CTRL_SF_IF_2_ADR_BYTE_LEN) - 1) << SF_CTRL_SF_IF_2_ADR_BYTE_POS)) +#define SF_CTRL_SF_IF_2_CMD_BYTE SF_CTRL_SF_IF_2_CMD_BYTE +#define SF_CTRL_SF_IF_2_CMD_BYTE_POS (20U) +#define SF_CTRL_SF_IF_2_CMD_BYTE_LEN (3U) +#define SF_CTRL_SF_IF_2_CMD_BYTE_MSK (((1U << SF_CTRL_SF_IF_2_CMD_BYTE_LEN) - 1) << SF_CTRL_SF_IF_2_CMD_BYTE_POS) +#define SF_CTRL_SF_IF_2_CMD_BYTE_UMSK (~(((1U << SF_CTRL_SF_IF_2_CMD_BYTE_LEN) - 1) << SF_CTRL_SF_IF_2_CMD_BYTE_POS)) +#define SF_CTRL_SF_IF_2_DAT_RW SF_CTRL_SF_IF_2_DAT_RW +#define SF_CTRL_SF_IF_2_DAT_RW_POS (23U) +#define SF_CTRL_SF_IF_2_DAT_RW_LEN (1U) +#define SF_CTRL_SF_IF_2_DAT_RW_MSK (((1U << SF_CTRL_SF_IF_2_DAT_RW_LEN) - 1) << SF_CTRL_SF_IF_2_DAT_RW_POS) +#define SF_CTRL_SF_IF_2_DAT_RW_UMSK (~(((1U << SF_CTRL_SF_IF_2_DAT_RW_LEN) - 1) << SF_CTRL_SF_IF_2_DAT_RW_POS)) +#define SF_CTRL_SF_IF_2_DAT_EN SF_CTRL_SF_IF_2_DAT_EN +#define SF_CTRL_SF_IF_2_DAT_EN_POS (24U) +#define SF_CTRL_SF_IF_2_DAT_EN_LEN (1U) +#define SF_CTRL_SF_IF_2_DAT_EN_MSK (((1U << SF_CTRL_SF_IF_2_DAT_EN_LEN) - 1) << SF_CTRL_SF_IF_2_DAT_EN_POS) +#define SF_CTRL_SF_IF_2_DAT_EN_UMSK (~(((1U << SF_CTRL_SF_IF_2_DAT_EN_LEN) - 1) << SF_CTRL_SF_IF_2_DAT_EN_POS)) +#define SF_CTRL_SF_IF_2_DMY_EN SF_CTRL_SF_IF_2_DMY_EN +#define SF_CTRL_SF_IF_2_DMY_EN_POS (25U) +#define SF_CTRL_SF_IF_2_DMY_EN_LEN (1U) +#define SF_CTRL_SF_IF_2_DMY_EN_MSK (((1U << SF_CTRL_SF_IF_2_DMY_EN_LEN) - 1) << SF_CTRL_SF_IF_2_DMY_EN_POS) +#define SF_CTRL_SF_IF_2_DMY_EN_UMSK (~(((1U << SF_CTRL_SF_IF_2_DMY_EN_LEN) - 1) << SF_CTRL_SF_IF_2_DMY_EN_POS)) +#define SF_CTRL_SF_IF_2_ADR_EN SF_CTRL_SF_IF_2_ADR_EN +#define SF_CTRL_SF_IF_2_ADR_EN_POS (26U) +#define SF_CTRL_SF_IF_2_ADR_EN_LEN (1U) +#define SF_CTRL_SF_IF_2_ADR_EN_MSK (((1U << SF_CTRL_SF_IF_2_ADR_EN_LEN) - 1) << SF_CTRL_SF_IF_2_ADR_EN_POS) +#define SF_CTRL_SF_IF_2_ADR_EN_UMSK (~(((1U << SF_CTRL_SF_IF_2_ADR_EN_LEN) - 1) << SF_CTRL_SF_IF_2_ADR_EN_POS)) +#define SF_CTRL_SF_IF_2_CMD_EN SF_CTRL_SF_IF_2_CMD_EN +#define SF_CTRL_SF_IF_2_CMD_EN_POS (27U) +#define SF_CTRL_SF_IF_2_CMD_EN_LEN (1U) +#define SF_CTRL_SF_IF_2_CMD_EN_MSK (((1U << SF_CTRL_SF_IF_2_CMD_EN_LEN) - 1) << SF_CTRL_SF_IF_2_CMD_EN_POS) +#define SF_CTRL_SF_IF_2_CMD_EN_UMSK (~(((1U << SF_CTRL_SF_IF_2_CMD_EN_LEN) - 1) << SF_CTRL_SF_IF_2_CMD_EN_POS)) +#define SF_CTRL_SF_IF_2_SPI_MODE SF_CTRL_SF_IF_2_SPI_MODE +#define SF_CTRL_SF_IF_2_SPI_MODE_POS (28U) +#define SF_CTRL_SF_IF_2_SPI_MODE_LEN (3U) +#define SF_CTRL_SF_IF_2_SPI_MODE_MSK (((1U << SF_CTRL_SF_IF_2_SPI_MODE_LEN) - 1) << SF_CTRL_SF_IF_2_SPI_MODE_POS) +#define SF_CTRL_SF_IF_2_SPI_MODE_UMSK (~(((1U << SF_CTRL_SF_IF_2_SPI_MODE_LEN) - 1) << SF_CTRL_SF_IF_2_SPI_MODE_POS)) +#define SF_CTRL_SF_IF_2_QPI_MODE_EN SF_CTRL_SF_IF_2_QPI_MODE_EN +#define SF_CTRL_SF_IF_2_QPI_MODE_EN_POS (31U) +#define SF_CTRL_SF_IF_2_QPI_MODE_EN_LEN (1U) +#define SF_CTRL_SF_IF_2_QPI_MODE_EN_MSK (((1U << SF_CTRL_SF_IF_2_QPI_MODE_EN_LEN) - 1) << SF_CTRL_SF_IF_2_QPI_MODE_EN_POS) +#define SF_CTRL_SF_IF_2_QPI_MODE_EN_UMSK (~(((1U << SF_CTRL_SF_IF_2_QPI_MODE_EN_LEN) - 1) << SF_CTRL_SF_IF_2_QPI_MODE_EN_POS)) + +/* 0x7C : sf_if_iahb_4 */ +#define SF_CTRL_SF_IF_IAHB_4_OFFSET (0x7C) +#define SF_CTRL_SF_IF_2_CMD_BUF_0 SF_CTRL_SF_IF_2_CMD_BUF_0 +#define SF_CTRL_SF_IF_2_CMD_BUF_0_POS (0U) +#define SF_CTRL_SF_IF_2_CMD_BUF_0_LEN (32U) +#define SF_CTRL_SF_IF_2_CMD_BUF_0_MSK (((1U << SF_CTRL_SF_IF_2_CMD_BUF_0_LEN) - 1) << SF_CTRL_SF_IF_2_CMD_BUF_0_POS) +#define SF_CTRL_SF_IF_2_CMD_BUF_0_UMSK (~(((1U << SF_CTRL_SF_IF_2_CMD_BUF_0_LEN) - 1) << SF_CTRL_SF_IF_2_CMD_BUF_0_POS)) + +/* 0x80 : sf_if_iahb_5 */ +#define SF_CTRL_SF_IF_IAHB_5_OFFSET (0x80) +#define SF_CTRL_SF_IF_2_CMD_BUF_1 SF_CTRL_SF_IF_2_CMD_BUF_1 +#define SF_CTRL_SF_IF_2_CMD_BUF_1_POS (0U) +#define SF_CTRL_SF_IF_2_CMD_BUF_1_LEN (32U) +#define SF_CTRL_SF_IF_2_CMD_BUF_1_MSK (((1U << SF_CTRL_SF_IF_2_CMD_BUF_1_LEN) - 1) << SF_CTRL_SF_IF_2_CMD_BUF_1_POS) +#define SF_CTRL_SF_IF_2_CMD_BUF_1_UMSK (~(((1U << SF_CTRL_SF_IF_2_CMD_BUF_1_LEN) - 1) << SF_CTRL_SF_IF_2_CMD_BUF_1_POS)) + +/* 0x84 : sf_if_iahb_6 */ +#define SF_CTRL_SF_IF_IAHB_6_OFFSET (0x84) +#define SF_CTRL_SF_IF_3_ADR_BYTE SF_CTRL_SF_IF_3_ADR_BYTE +#define SF_CTRL_SF_IF_3_ADR_BYTE_POS (17U) +#define SF_CTRL_SF_IF_3_ADR_BYTE_LEN (3U) +#define SF_CTRL_SF_IF_3_ADR_BYTE_MSK (((1U << SF_CTRL_SF_IF_3_ADR_BYTE_LEN) - 1) << SF_CTRL_SF_IF_3_ADR_BYTE_POS) +#define SF_CTRL_SF_IF_3_ADR_BYTE_UMSK (~(((1U << SF_CTRL_SF_IF_3_ADR_BYTE_LEN) - 1) << SF_CTRL_SF_IF_3_ADR_BYTE_POS)) +#define SF_CTRL_SF_IF_3_CMD_BYTE SF_CTRL_SF_IF_3_CMD_BYTE +#define SF_CTRL_SF_IF_3_CMD_BYTE_POS (20U) +#define SF_CTRL_SF_IF_3_CMD_BYTE_LEN (3U) +#define SF_CTRL_SF_IF_3_CMD_BYTE_MSK (((1U << SF_CTRL_SF_IF_3_CMD_BYTE_LEN) - 1) << SF_CTRL_SF_IF_3_CMD_BYTE_POS) +#define SF_CTRL_SF_IF_3_CMD_BYTE_UMSK (~(((1U << SF_CTRL_SF_IF_3_CMD_BYTE_LEN) - 1) << SF_CTRL_SF_IF_3_CMD_BYTE_POS)) +#define SF_CTRL_SF_IF_3_ADR_EN SF_CTRL_SF_IF_3_ADR_EN +#define SF_CTRL_SF_IF_3_ADR_EN_POS (26U) +#define SF_CTRL_SF_IF_3_ADR_EN_LEN (1U) +#define SF_CTRL_SF_IF_3_ADR_EN_MSK (((1U << SF_CTRL_SF_IF_3_ADR_EN_LEN) - 1) << SF_CTRL_SF_IF_3_ADR_EN_POS) +#define SF_CTRL_SF_IF_3_ADR_EN_UMSK (~(((1U << SF_CTRL_SF_IF_3_ADR_EN_LEN) - 1) << SF_CTRL_SF_IF_3_ADR_EN_POS)) +#define SF_CTRL_SF_IF_3_CMD_EN SF_CTRL_SF_IF_3_CMD_EN +#define SF_CTRL_SF_IF_3_CMD_EN_POS (27U) +#define SF_CTRL_SF_IF_3_CMD_EN_LEN (1U) +#define SF_CTRL_SF_IF_3_CMD_EN_MSK (((1U << SF_CTRL_SF_IF_3_CMD_EN_LEN) - 1) << SF_CTRL_SF_IF_3_CMD_EN_POS) +#define SF_CTRL_SF_IF_3_CMD_EN_UMSK (~(((1U << SF_CTRL_SF_IF_3_CMD_EN_LEN) - 1) << SF_CTRL_SF_IF_3_CMD_EN_POS)) +#define SF_CTRL_SF_IF_3_SPI_MODE SF_CTRL_SF_IF_3_SPI_MODE +#define SF_CTRL_SF_IF_3_SPI_MODE_POS (28U) +#define SF_CTRL_SF_IF_3_SPI_MODE_LEN (3U) +#define SF_CTRL_SF_IF_3_SPI_MODE_MSK (((1U << SF_CTRL_SF_IF_3_SPI_MODE_LEN) - 1) << SF_CTRL_SF_IF_3_SPI_MODE_POS) +#define SF_CTRL_SF_IF_3_SPI_MODE_UMSK (~(((1U << SF_CTRL_SF_IF_3_SPI_MODE_LEN) - 1) << SF_CTRL_SF_IF_3_SPI_MODE_POS)) +#define SF_CTRL_SF_IF_3_QPI_MODE_EN SF_CTRL_SF_IF_3_QPI_MODE_EN +#define SF_CTRL_SF_IF_3_QPI_MODE_EN_POS (31U) +#define SF_CTRL_SF_IF_3_QPI_MODE_EN_LEN (1U) +#define SF_CTRL_SF_IF_3_QPI_MODE_EN_MSK (((1U << SF_CTRL_SF_IF_3_QPI_MODE_EN_LEN) - 1) << SF_CTRL_SF_IF_3_QPI_MODE_EN_POS) +#define SF_CTRL_SF_IF_3_QPI_MODE_EN_UMSK (~(((1U << SF_CTRL_SF_IF_3_QPI_MODE_EN_LEN) - 1) << SF_CTRL_SF_IF_3_QPI_MODE_EN_POS)) + +/* 0x88 : sf_if_iahb_7 */ +#define SF_CTRL_SF_IF_IAHB_7_OFFSET (0x88) +#define SF_CTRL_SF_IF_3_CMD_BUF_0 SF_CTRL_SF_IF_3_CMD_BUF_0 +#define SF_CTRL_SF_IF_3_CMD_BUF_0_POS (0U) +#define SF_CTRL_SF_IF_3_CMD_BUF_0_LEN (32U) +#define SF_CTRL_SF_IF_3_CMD_BUF_0_MSK (((1U << SF_CTRL_SF_IF_3_CMD_BUF_0_LEN) - 1) << SF_CTRL_SF_IF_3_CMD_BUF_0_POS) +#define SF_CTRL_SF_IF_3_CMD_BUF_0_UMSK (~(((1U << SF_CTRL_SF_IF_3_CMD_BUF_0_LEN) - 1) << SF_CTRL_SF_IF_3_CMD_BUF_0_POS)) + +/* 0x8C : sf_if_iahb_8 */ +#define SF_CTRL_SF_IF_IAHB_8_OFFSET (0x8C) +#define SF_CTRL_SF_IF_3_CMD_BUF_1 SF_CTRL_SF_IF_3_CMD_BUF_1 +#define SF_CTRL_SF_IF_3_CMD_BUF_1_POS (0U) +#define SF_CTRL_SF_IF_3_CMD_BUF_1_LEN (32U) +#define SF_CTRL_SF_IF_3_CMD_BUF_1_MSK (((1U << SF_CTRL_SF_IF_3_CMD_BUF_1_LEN) - 1) << SF_CTRL_SF_IF_3_CMD_BUF_1_POS) +#define SF_CTRL_SF_IF_3_CMD_BUF_1_UMSK (~(((1U << SF_CTRL_SF_IF_3_CMD_BUF_1_LEN) - 1) << SF_CTRL_SF_IF_3_CMD_BUF_1_POS)) + +/* 0x90 : sf_if_iahb_9 */ +#define SF_CTRL_SF_IF_IAHB_9_OFFSET (0x90) +#define SF_CTRL_SF_IF_4_DMY_BYTE SF_CTRL_SF_IF_4_DMY_BYTE +#define SF_CTRL_SF_IF_4_DMY_BYTE_POS (12U) +#define SF_CTRL_SF_IF_4_DMY_BYTE_LEN (5U) +#define SF_CTRL_SF_IF_4_DMY_BYTE_MSK (((1U << SF_CTRL_SF_IF_4_DMY_BYTE_LEN) - 1) << SF_CTRL_SF_IF_4_DMY_BYTE_POS) +#define SF_CTRL_SF_IF_4_DMY_BYTE_UMSK (~(((1U << SF_CTRL_SF_IF_4_DMY_BYTE_LEN) - 1) << SF_CTRL_SF_IF_4_DMY_BYTE_POS)) +#define SF_CTRL_SF_IF_4_ADR_BYTE SF_CTRL_SF_IF_4_ADR_BYTE +#define SF_CTRL_SF_IF_4_ADR_BYTE_POS (17U) +#define SF_CTRL_SF_IF_4_ADR_BYTE_LEN (3U) +#define SF_CTRL_SF_IF_4_ADR_BYTE_MSK (((1U << SF_CTRL_SF_IF_4_ADR_BYTE_LEN) - 1) << SF_CTRL_SF_IF_4_ADR_BYTE_POS) +#define SF_CTRL_SF_IF_4_ADR_BYTE_UMSK (~(((1U << SF_CTRL_SF_IF_4_ADR_BYTE_LEN) - 1) << SF_CTRL_SF_IF_4_ADR_BYTE_POS)) +#define SF_CTRL_SF_IF_4_CMD_BYTE SF_CTRL_SF_IF_4_CMD_BYTE +#define SF_CTRL_SF_IF_4_CMD_BYTE_POS (20U) +#define SF_CTRL_SF_IF_4_CMD_BYTE_LEN (3U) +#define SF_CTRL_SF_IF_4_CMD_BYTE_MSK (((1U << SF_CTRL_SF_IF_4_CMD_BYTE_LEN) - 1) << SF_CTRL_SF_IF_4_CMD_BYTE_POS) +#define SF_CTRL_SF_IF_4_CMD_BYTE_UMSK (~(((1U << SF_CTRL_SF_IF_4_CMD_BYTE_LEN) - 1) << SF_CTRL_SF_IF_4_CMD_BYTE_POS)) +#define SF_CTRL_SF_IF_4_DAT_RW SF_CTRL_SF_IF_4_DAT_RW +#define SF_CTRL_SF_IF_4_DAT_RW_POS (23U) +#define SF_CTRL_SF_IF_4_DAT_RW_LEN (1U) +#define SF_CTRL_SF_IF_4_DAT_RW_MSK (((1U << SF_CTRL_SF_IF_4_DAT_RW_LEN) - 1) << SF_CTRL_SF_IF_4_DAT_RW_POS) +#define SF_CTRL_SF_IF_4_DAT_RW_UMSK (~(((1U << SF_CTRL_SF_IF_4_DAT_RW_LEN) - 1) << SF_CTRL_SF_IF_4_DAT_RW_POS)) +#define SF_CTRL_SF_IF_4_DAT_EN SF_CTRL_SF_IF_4_DAT_EN +#define SF_CTRL_SF_IF_4_DAT_EN_POS (24U) +#define SF_CTRL_SF_IF_4_DAT_EN_LEN (1U) +#define SF_CTRL_SF_IF_4_DAT_EN_MSK (((1U << SF_CTRL_SF_IF_4_DAT_EN_LEN) - 1) << SF_CTRL_SF_IF_4_DAT_EN_POS) +#define SF_CTRL_SF_IF_4_DAT_EN_UMSK (~(((1U << SF_CTRL_SF_IF_4_DAT_EN_LEN) - 1) << SF_CTRL_SF_IF_4_DAT_EN_POS)) +#define SF_CTRL_SF_IF_4_DMY_EN SF_CTRL_SF_IF_4_DMY_EN +#define SF_CTRL_SF_IF_4_DMY_EN_POS (25U) +#define SF_CTRL_SF_IF_4_DMY_EN_LEN (1U) +#define SF_CTRL_SF_IF_4_DMY_EN_MSK (((1U << SF_CTRL_SF_IF_4_DMY_EN_LEN) - 1) << SF_CTRL_SF_IF_4_DMY_EN_POS) +#define SF_CTRL_SF_IF_4_DMY_EN_UMSK (~(((1U << SF_CTRL_SF_IF_4_DMY_EN_LEN) - 1) << SF_CTRL_SF_IF_4_DMY_EN_POS)) +#define SF_CTRL_SF_IF_4_ADR_EN SF_CTRL_SF_IF_4_ADR_EN +#define SF_CTRL_SF_IF_4_ADR_EN_POS (26U) +#define SF_CTRL_SF_IF_4_ADR_EN_LEN (1U) +#define SF_CTRL_SF_IF_4_ADR_EN_MSK (((1U << SF_CTRL_SF_IF_4_ADR_EN_LEN) - 1) << SF_CTRL_SF_IF_4_ADR_EN_POS) +#define SF_CTRL_SF_IF_4_ADR_EN_UMSK (~(((1U << SF_CTRL_SF_IF_4_ADR_EN_LEN) - 1) << SF_CTRL_SF_IF_4_ADR_EN_POS)) +#define SF_CTRL_SF_IF_4_CMD_EN SF_CTRL_SF_IF_4_CMD_EN +#define SF_CTRL_SF_IF_4_CMD_EN_POS (27U) +#define SF_CTRL_SF_IF_4_CMD_EN_LEN (1U) +#define SF_CTRL_SF_IF_4_CMD_EN_MSK (((1U << SF_CTRL_SF_IF_4_CMD_EN_LEN) - 1) << SF_CTRL_SF_IF_4_CMD_EN_POS) +#define SF_CTRL_SF_IF_4_CMD_EN_UMSK (~(((1U << SF_CTRL_SF_IF_4_CMD_EN_LEN) - 1) << SF_CTRL_SF_IF_4_CMD_EN_POS)) +#define SF_CTRL_SF_IF_4_SPI_MODE SF_CTRL_SF_IF_4_SPI_MODE +#define SF_CTRL_SF_IF_4_SPI_MODE_POS (28U) +#define SF_CTRL_SF_IF_4_SPI_MODE_LEN (3U) +#define SF_CTRL_SF_IF_4_SPI_MODE_MSK (((1U << SF_CTRL_SF_IF_4_SPI_MODE_LEN) - 1) << SF_CTRL_SF_IF_4_SPI_MODE_POS) +#define SF_CTRL_SF_IF_4_SPI_MODE_UMSK (~(((1U << SF_CTRL_SF_IF_4_SPI_MODE_LEN) - 1) << SF_CTRL_SF_IF_4_SPI_MODE_POS)) +#define SF_CTRL_SF_IF_4_QPI_MODE_EN SF_CTRL_SF_IF_4_QPI_MODE_EN +#define SF_CTRL_SF_IF_4_QPI_MODE_EN_POS (31U) +#define SF_CTRL_SF_IF_4_QPI_MODE_EN_LEN (1U) +#define SF_CTRL_SF_IF_4_QPI_MODE_EN_MSK (((1U << SF_CTRL_SF_IF_4_QPI_MODE_EN_LEN) - 1) << SF_CTRL_SF_IF_4_QPI_MODE_EN_POS) +#define SF_CTRL_SF_IF_4_QPI_MODE_EN_UMSK (~(((1U << SF_CTRL_SF_IF_4_QPI_MODE_EN_LEN) - 1) << SF_CTRL_SF_IF_4_QPI_MODE_EN_POS)) + +/* 0x94 : sf_if_iahb_10 */ +#define SF_CTRL_SF_IF_IAHB_10_OFFSET (0x94) +#define SF_CTRL_SF_IF_4_CMD_BUF_0 SF_CTRL_SF_IF_4_CMD_BUF_0 +#define SF_CTRL_SF_IF_4_CMD_BUF_0_POS (0U) +#define SF_CTRL_SF_IF_4_CMD_BUF_0_LEN (32U) +#define SF_CTRL_SF_IF_4_CMD_BUF_0_MSK (((1U << SF_CTRL_SF_IF_4_CMD_BUF_0_LEN) - 1) << SF_CTRL_SF_IF_4_CMD_BUF_0_POS) +#define SF_CTRL_SF_IF_4_CMD_BUF_0_UMSK (~(((1U << SF_CTRL_SF_IF_4_CMD_BUF_0_LEN) - 1) << SF_CTRL_SF_IF_4_CMD_BUF_0_POS)) + +/* 0x98 : sf_if_iahb_11 */ +#define SF_CTRL_SF_IF_IAHB_11_OFFSET (0x98) +#define SF_CTRL_SF_IF_4_CMD_BUF_1 SF_CTRL_SF_IF_4_CMD_BUF_1 +#define SF_CTRL_SF_IF_4_CMD_BUF_1_POS (0U) +#define SF_CTRL_SF_IF_4_CMD_BUF_1_LEN (32U) +#define SF_CTRL_SF_IF_4_CMD_BUF_1_MSK (((1U << SF_CTRL_SF_IF_4_CMD_BUF_1_LEN) - 1) << SF_CTRL_SF_IF_4_CMD_BUF_1_POS) +#define SF_CTRL_SF_IF_4_CMD_BUF_1_UMSK (~(((1U << SF_CTRL_SF_IF_4_CMD_BUF_1_LEN) - 1) << SF_CTRL_SF_IF_4_CMD_BUF_1_POS)) + +/* 0x9C : sf_if_iahb_12 */ +#define SF_CTRL_SF_IF_IAHB_12_OFFSET (0x9C) +#define SF_CTRL_SF2_CLK_SF_RX_INV_SEL SF_CTRL_SF2_CLK_SF_RX_INV_SEL +#define SF_CTRL_SF2_CLK_SF_RX_INV_SEL_POS (2U) +#define SF_CTRL_SF2_CLK_SF_RX_INV_SEL_LEN (1U) +#define SF_CTRL_SF2_CLK_SF_RX_INV_SEL_MSK (((1U << SF_CTRL_SF2_CLK_SF_RX_INV_SEL_LEN) - 1) << SF_CTRL_SF2_CLK_SF_RX_INV_SEL_POS) +#define SF_CTRL_SF2_CLK_SF_RX_INV_SEL_UMSK (~(((1U << SF_CTRL_SF2_CLK_SF_RX_INV_SEL_LEN) - 1) << SF_CTRL_SF2_CLK_SF_RX_INV_SEL_POS)) +#define SF_CTRL_SF2_CLK_SF_RX_INV_SRC SF_CTRL_SF2_CLK_SF_RX_INV_SRC +#define SF_CTRL_SF2_CLK_SF_RX_INV_SRC_POS (3U) +#define SF_CTRL_SF2_CLK_SF_RX_INV_SRC_LEN (1U) +#define SF_CTRL_SF2_CLK_SF_RX_INV_SRC_MSK (((1U << SF_CTRL_SF2_CLK_SF_RX_INV_SRC_LEN) - 1) << SF_CTRL_SF2_CLK_SF_RX_INV_SRC_POS) +#define SF_CTRL_SF2_CLK_SF_RX_INV_SRC_UMSK (~(((1U << SF_CTRL_SF2_CLK_SF_RX_INV_SRC_LEN) - 1) << SF_CTRL_SF2_CLK_SF_RX_INV_SRC_POS)) +#define SF_CTRL_SF2_CLK_OUT_INV_SEL SF_CTRL_SF2_CLK_OUT_INV_SEL +#define SF_CTRL_SF2_CLK_OUT_INV_SEL_POS (4U) +#define SF_CTRL_SF2_CLK_OUT_INV_SEL_LEN (1U) +#define SF_CTRL_SF2_CLK_OUT_INV_SEL_MSK (((1U << SF_CTRL_SF2_CLK_OUT_INV_SEL_LEN) - 1) << SF_CTRL_SF2_CLK_OUT_INV_SEL_POS) +#define SF_CTRL_SF2_CLK_OUT_INV_SEL_UMSK (~(((1U << SF_CTRL_SF2_CLK_OUT_INV_SEL_LEN) - 1) << SF_CTRL_SF2_CLK_OUT_INV_SEL_POS)) +#define SF_CTRL_SF3_CLK_OUT_INV_SEL SF_CTRL_SF3_CLK_OUT_INV_SEL +#define SF_CTRL_SF3_CLK_OUT_INV_SEL_POS (5U) +#define SF_CTRL_SF3_CLK_OUT_INV_SEL_LEN (1U) +#define SF_CTRL_SF3_CLK_OUT_INV_SEL_MSK (((1U << SF_CTRL_SF3_CLK_OUT_INV_SEL_LEN) - 1) << SF_CTRL_SF3_CLK_OUT_INV_SEL_POS) +#define SF_CTRL_SF3_CLK_OUT_INV_SEL_UMSK (~(((1U << SF_CTRL_SF3_CLK_OUT_INV_SEL_LEN) - 1) << SF_CTRL_SF3_CLK_OUT_INV_SEL_POS)) +#define SF_CTRL_SF2_IF_READ_DLY_N SF_CTRL_SF2_IF_READ_DLY_N +#define SF_CTRL_SF2_IF_READ_DLY_N_POS (8U) +#define SF_CTRL_SF2_IF_READ_DLY_N_LEN (3U) +#define SF_CTRL_SF2_IF_READ_DLY_N_MSK (((1U << SF_CTRL_SF2_IF_READ_DLY_N_LEN) - 1) << SF_CTRL_SF2_IF_READ_DLY_N_POS) +#define SF_CTRL_SF2_IF_READ_DLY_N_UMSK (~(((1U << SF_CTRL_SF2_IF_READ_DLY_N_LEN) - 1) << SF_CTRL_SF2_IF_READ_DLY_N_POS)) +#define SF_CTRL_SF2_IF_READ_DLY_EN SF_CTRL_SF2_IF_READ_DLY_EN +#define SF_CTRL_SF2_IF_READ_DLY_EN_POS (11U) +#define SF_CTRL_SF2_IF_READ_DLY_EN_LEN (1U) +#define SF_CTRL_SF2_IF_READ_DLY_EN_MSK (((1U << SF_CTRL_SF2_IF_READ_DLY_EN_LEN) - 1) << SF_CTRL_SF2_IF_READ_DLY_EN_POS) +#define SF_CTRL_SF2_IF_READ_DLY_EN_UMSK (~(((1U << SF_CTRL_SF2_IF_READ_DLY_EN_LEN) - 1) << SF_CTRL_SF2_IF_READ_DLY_EN_POS)) +#define SF_CTRL_SF2_IF_READ_DLY_SRC SF_CTRL_SF2_IF_READ_DLY_SRC +#define SF_CTRL_SF2_IF_READ_DLY_SRC_POS (12U) +#define SF_CTRL_SF2_IF_READ_DLY_SRC_LEN (1U) +#define SF_CTRL_SF2_IF_READ_DLY_SRC_MSK (((1U << SF_CTRL_SF2_IF_READ_DLY_SRC_LEN) - 1) << SF_CTRL_SF2_IF_READ_DLY_SRC_POS) +#define SF_CTRL_SF2_IF_READ_DLY_SRC_UMSK (~(((1U << SF_CTRL_SF2_IF_READ_DLY_SRC_LEN) - 1) << SF_CTRL_SF2_IF_READ_DLY_SRC_POS)) + +/* 0xA0 : sf_id0_offset */ +#define SF_CTRL_SF_ID0_OFFSET_OFFSET (0xA0) +#define SF_CTRL_SF_ID0_OFFSET SF_CTRL_SF_ID0_OFFSET +#define SF_CTRL_SF_ID0_OFFSET_POS (0U) +#define SF_CTRL_SF_ID0_OFFSET_LEN (28U) +#define SF_CTRL_SF_ID0_OFFSET_MSK (((1U << SF_CTRL_SF_ID0_OFFSET_LEN) - 1) << SF_CTRL_SF_ID0_OFFSET_POS) +#define SF_CTRL_SF_ID0_OFFSET_UMSK (~(((1U << SF_CTRL_SF_ID0_OFFSET_LEN) - 1) << SF_CTRL_SF_ID0_OFFSET_POS)) + +/* 0xA4 : sf_id1_offset */ +#define SF_CTRL_SF_ID1_OFFSET_OFFSET (0xA4) +#define SF_CTRL_SF_ID1_OFFSET SF_CTRL_SF_ID1_OFFSET +#define SF_CTRL_SF_ID1_OFFSET_POS (0U) +#define SF_CTRL_SF_ID1_OFFSET_LEN (28U) +#define SF_CTRL_SF_ID1_OFFSET_MSK (((1U << SF_CTRL_SF_ID1_OFFSET_LEN) - 1) << SF_CTRL_SF_ID1_OFFSET_POS) +#define SF_CTRL_SF_ID1_OFFSET_UMSK (~(((1U << SF_CTRL_SF_ID1_OFFSET_LEN) - 1) << SF_CTRL_SF_ID1_OFFSET_POS)) + +/* 0xA8 : sf_bk2_id0_offset */ +#define SF_CTRL_SF_BK2_ID0_OFFSET_OFFSET (0xA8) +#define SF_CTRL_SF_BK2_ID0_OFFSET SF_CTRL_SF_BK2_ID0_OFFSET +#define SF_CTRL_SF_BK2_ID0_OFFSET_POS (0U) +#define SF_CTRL_SF_BK2_ID0_OFFSET_LEN (28U) +#define SF_CTRL_SF_BK2_ID0_OFFSET_MSK (((1U << SF_CTRL_SF_BK2_ID0_OFFSET_LEN) - 1) << SF_CTRL_SF_BK2_ID0_OFFSET_POS) +#define SF_CTRL_SF_BK2_ID0_OFFSET_UMSK (~(((1U << SF_CTRL_SF_BK2_ID0_OFFSET_LEN) - 1) << SF_CTRL_SF_BK2_ID0_OFFSET_POS)) + +/* 0xAC : sf_bk2_id1_offset */ +#define SF_CTRL_SF_BK2_ID1_OFFSET_OFFSET (0xAC) +#define SF_CTRL_SF_BK2_ID1_OFFSET SF_CTRL_SF_BK2_ID1_OFFSET +#define SF_CTRL_SF_BK2_ID1_OFFSET_POS (0U) +#define SF_CTRL_SF_BK2_ID1_OFFSET_LEN (28U) +#define SF_CTRL_SF_BK2_ID1_OFFSET_MSK (((1U << SF_CTRL_SF_BK2_ID1_OFFSET_LEN) - 1) << SF_CTRL_SF_BK2_ID1_OFFSET_POS) +#define SF_CTRL_SF_BK2_ID1_OFFSET_UMSK (~(((1U << SF_CTRL_SF_BK2_ID1_OFFSET_LEN) - 1) << SF_CTRL_SF_BK2_ID1_OFFSET_POS)) + +/* 0xB0 : sf_dbg */ +#define SF_CTRL_SF_DBG_OFFSET (0xB0) +#define SF_CTRL_SF_AUTOLOAD_ST SF_CTRL_SF_AUTOLOAD_ST +#define SF_CTRL_SF_AUTOLOAD_ST_POS (0U) +#define SF_CTRL_SF_AUTOLOAD_ST_LEN (5U) +#define SF_CTRL_SF_AUTOLOAD_ST_MSK (((1U << SF_CTRL_SF_AUTOLOAD_ST_LEN) - 1) << SF_CTRL_SF_AUTOLOAD_ST_POS) +#define SF_CTRL_SF_AUTOLOAD_ST_UMSK (~(((1U << SF_CTRL_SF_AUTOLOAD_ST_LEN) - 1) << SF_CTRL_SF_AUTOLOAD_ST_POS)) +#define SF_CTRL_SF_AUTOLOAD_ST_DONE SF_CTRL_SF_AUTOLOAD_ST_DONE +#define SF_CTRL_SF_AUTOLOAD_ST_DONE_POS (5U) +#define SF_CTRL_SF_AUTOLOAD_ST_DONE_LEN (1U) +#define SF_CTRL_SF_AUTOLOAD_ST_DONE_MSK (((1U << SF_CTRL_SF_AUTOLOAD_ST_DONE_LEN) - 1) << SF_CTRL_SF_AUTOLOAD_ST_DONE_POS) +#define SF_CTRL_SF_AUTOLOAD_ST_DONE_UMSK (~(((1U << SF_CTRL_SF_AUTOLOAD_ST_DONE_LEN) - 1) << SF_CTRL_SF_AUTOLOAD_ST_DONE_POS)) + +/* 0xC0 : sf_if2_ctrl_0 */ +#define SF_CTRL_SF_IF2_CTRL_0_OFFSET (0xC0) +#define SF_CTRL_SF_CLK_SF_IF2_RX_INV_SEL SF_CTRL_SF_CLK_SF_IF2_RX_INV_SEL +#define SF_CTRL_SF_CLK_SF_IF2_RX_INV_SEL_POS (2U) +#define SF_CTRL_SF_CLK_SF_IF2_RX_INV_SEL_LEN (1U) +#define SF_CTRL_SF_CLK_SF_IF2_RX_INV_SEL_MSK (((1U << SF_CTRL_SF_CLK_SF_IF2_RX_INV_SEL_LEN) - 1) << SF_CTRL_SF_CLK_SF_IF2_RX_INV_SEL_POS) +#define SF_CTRL_SF_CLK_SF_IF2_RX_INV_SEL_UMSK (~(((1U << SF_CTRL_SF_CLK_SF_IF2_RX_INV_SEL_LEN) - 1) << SF_CTRL_SF_CLK_SF_IF2_RX_INV_SEL_POS)) +#define SF_CTRL_SF_IF2_READ_DLY_N SF_CTRL_SF_IF2_READ_DLY_N +#define SF_CTRL_SF_IF2_READ_DLY_N_POS (8U) +#define SF_CTRL_SF_IF2_READ_DLY_N_LEN (3U) +#define SF_CTRL_SF_IF2_READ_DLY_N_MSK (((1U << SF_CTRL_SF_IF2_READ_DLY_N_LEN) - 1) << SF_CTRL_SF_IF2_READ_DLY_N_POS) +#define SF_CTRL_SF_IF2_READ_DLY_N_UMSK (~(((1U << SF_CTRL_SF_IF2_READ_DLY_N_LEN) - 1) << SF_CTRL_SF_IF2_READ_DLY_N_POS)) +#define SF_CTRL_SF_IF2_READ_DLY_EN SF_CTRL_SF_IF2_READ_DLY_EN +#define SF_CTRL_SF_IF2_READ_DLY_EN_POS (11U) +#define SF_CTRL_SF_IF2_READ_DLY_EN_LEN (1U) +#define SF_CTRL_SF_IF2_READ_DLY_EN_MSK (((1U << SF_CTRL_SF_IF2_READ_DLY_EN_LEN) - 1) << SF_CTRL_SF_IF2_READ_DLY_EN_POS) +#define SF_CTRL_SF_IF2_READ_DLY_EN_UMSK (~(((1U << SF_CTRL_SF_IF2_READ_DLY_EN_LEN) - 1) << SF_CTRL_SF_IF2_READ_DLY_EN_POS)) +#define SF_CTRL_SF_IF2_INT SF_CTRL_SF_IF2_INT +#define SF_CTRL_SF_IF2_INT_POS (16U) +#define SF_CTRL_SF_IF2_INT_LEN (1U) +#define SF_CTRL_SF_IF2_INT_MSK (((1U << SF_CTRL_SF_IF2_INT_LEN) - 1) << SF_CTRL_SF_IF2_INT_POS) +#define SF_CTRL_SF_IF2_INT_UMSK (~(((1U << SF_CTRL_SF_IF2_INT_LEN) - 1) << SF_CTRL_SF_IF2_INT_POS)) +#define SF_CTRL_SF_IF2_INT_CLR SF_CTRL_SF_IF2_INT_CLR +#define SF_CTRL_SF_IF2_INT_CLR_POS (17U) +#define SF_CTRL_SF_IF2_INT_CLR_LEN (1U) +#define SF_CTRL_SF_IF2_INT_CLR_MSK (((1U << SF_CTRL_SF_IF2_INT_CLR_LEN) - 1) << SF_CTRL_SF_IF2_INT_CLR_POS) +#define SF_CTRL_SF_IF2_INT_CLR_UMSK (~(((1U << SF_CTRL_SF_IF2_INT_CLR_LEN) - 1) << SF_CTRL_SF_IF2_INT_CLR_POS)) +#define SF_CTRL_SF_IF2_INT_SET SF_CTRL_SF_IF2_INT_SET +#define SF_CTRL_SF_IF2_INT_SET_POS (18U) +#define SF_CTRL_SF_IF2_INT_SET_LEN (1U) +#define SF_CTRL_SF_IF2_INT_SET_MSK (((1U << SF_CTRL_SF_IF2_INT_SET_LEN) - 1) << SF_CTRL_SF_IF2_INT_SET_POS) +#define SF_CTRL_SF_IF2_INT_SET_UMSK (~(((1U << SF_CTRL_SF_IF2_INT_SET_LEN) - 1) << SF_CTRL_SF_IF2_INT_SET_POS)) +#define SF_CTRL_SF_IF2_REPLACE_SF1 SF_CTRL_SF_IF2_REPLACE_SF1 +#define SF_CTRL_SF_IF2_REPLACE_SF1_POS (23U) +#define SF_CTRL_SF_IF2_REPLACE_SF1_LEN (1U) +#define SF_CTRL_SF_IF2_REPLACE_SF1_MSK (((1U << SF_CTRL_SF_IF2_REPLACE_SF1_LEN) - 1) << SF_CTRL_SF_IF2_REPLACE_SF1_POS) +#define SF_CTRL_SF_IF2_REPLACE_SF1_UMSK (~(((1U << SF_CTRL_SF_IF2_REPLACE_SF1_LEN) - 1) << SF_CTRL_SF_IF2_REPLACE_SF1_POS)) +#define SF_CTRL_SF_IF2_REPLACE_SF2 SF_CTRL_SF_IF2_REPLACE_SF2 +#define SF_CTRL_SF_IF2_REPLACE_SF2_POS (24U) +#define SF_CTRL_SF_IF2_REPLACE_SF2_LEN (1U) +#define SF_CTRL_SF_IF2_REPLACE_SF2_MSK (((1U << SF_CTRL_SF_IF2_REPLACE_SF2_LEN) - 1) << SF_CTRL_SF_IF2_REPLACE_SF2_POS) +#define SF_CTRL_SF_IF2_REPLACE_SF2_UMSK (~(((1U << SF_CTRL_SF_IF2_REPLACE_SF2_LEN) - 1) << SF_CTRL_SF_IF2_REPLACE_SF2_POS)) +#define SF_CTRL_SF_IF2_REPLACE_SF3 SF_CTRL_SF_IF2_REPLACE_SF3 +#define SF_CTRL_SF_IF2_REPLACE_SF3_POS (25U) +#define SF_CTRL_SF_IF2_REPLACE_SF3_LEN (1U) +#define SF_CTRL_SF_IF2_REPLACE_SF3_MSK (((1U << SF_CTRL_SF_IF2_REPLACE_SF3_LEN) - 1) << SF_CTRL_SF_IF2_REPLACE_SF3_POS) +#define SF_CTRL_SF_IF2_REPLACE_SF3_UMSK (~(((1U << SF_CTRL_SF_IF2_REPLACE_SF3_LEN) - 1) << SF_CTRL_SF_IF2_REPLACE_SF3_POS)) +#define SF_CTRL_SF_IF2_PAD_SEL SF_CTRL_SF_IF2_PAD_SEL +#define SF_CTRL_SF_IF2_PAD_SEL_POS (26U) +#define SF_CTRL_SF_IF2_PAD_SEL_LEN (2U) +#define SF_CTRL_SF_IF2_PAD_SEL_MSK (((1U << SF_CTRL_SF_IF2_PAD_SEL_LEN) - 1) << SF_CTRL_SF_IF2_PAD_SEL_POS) +#define SF_CTRL_SF_IF2_PAD_SEL_UMSK (~(((1U << SF_CTRL_SF_IF2_PAD_SEL_LEN) - 1) << SF_CTRL_SF_IF2_PAD_SEL_POS)) +#define SF_CTRL_SF_IF2_BK_SWAP SF_CTRL_SF_IF2_BK_SWAP +#define SF_CTRL_SF_IF2_BK_SWAP_POS (28U) +#define SF_CTRL_SF_IF2_BK_SWAP_LEN (1U) +#define SF_CTRL_SF_IF2_BK_SWAP_MSK (((1U << SF_CTRL_SF_IF2_BK_SWAP_LEN) - 1) << SF_CTRL_SF_IF2_BK_SWAP_POS) +#define SF_CTRL_SF_IF2_BK_SWAP_UMSK (~(((1U << SF_CTRL_SF_IF2_BK_SWAP_LEN) - 1) << SF_CTRL_SF_IF2_BK_SWAP_POS)) +#define SF_CTRL_SF_IF2_BK2_MODE SF_CTRL_SF_IF2_BK2_MODE +#define SF_CTRL_SF_IF2_BK2_MODE_POS (29U) +#define SF_CTRL_SF_IF2_BK2_MODE_LEN (1U) +#define SF_CTRL_SF_IF2_BK2_MODE_MSK (((1U << SF_CTRL_SF_IF2_BK2_MODE_LEN) - 1) << SF_CTRL_SF_IF2_BK2_MODE_POS) +#define SF_CTRL_SF_IF2_BK2_MODE_UMSK (~(((1U << SF_CTRL_SF_IF2_BK2_MODE_LEN) - 1) << SF_CTRL_SF_IF2_BK2_MODE_POS)) +#define SF_CTRL_SF_IF2_BK2_EN SF_CTRL_SF_IF2_BK2_EN +#define SF_CTRL_SF_IF2_BK2_EN_POS (30U) +#define SF_CTRL_SF_IF2_BK2_EN_LEN (1U) +#define SF_CTRL_SF_IF2_BK2_EN_MSK (((1U << SF_CTRL_SF_IF2_BK2_EN_LEN) - 1) << SF_CTRL_SF_IF2_BK2_EN_POS) +#define SF_CTRL_SF_IF2_BK2_EN_UMSK (~(((1U << SF_CTRL_SF_IF2_BK2_EN_LEN) - 1) << SF_CTRL_SF_IF2_BK2_EN_POS)) +#define SF_CTRL_SF_IF2_BK_SEL SF_CTRL_SF_IF2_BK_SEL +#define SF_CTRL_SF_IF2_BK_SEL_POS (31U) +#define SF_CTRL_SF_IF2_BK_SEL_LEN (1U) +#define SF_CTRL_SF_IF2_BK_SEL_MSK (((1U << SF_CTRL_SF_IF2_BK_SEL_LEN) - 1) << SF_CTRL_SF_IF2_BK_SEL_POS) +#define SF_CTRL_SF_IF2_BK_SEL_UMSK (~(((1U << SF_CTRL_SF_IF2_BK_SEL_LEN) - 1) << SF_CTRL_SF_IF2_BK_SEL_POS)) + +/* 0xC4 : sf_if2_ctrl_1 */ +#define SF_CTRL_SF_IF2_CTRL_1_OFFSET (0xC4) +#define SF_CTRL_SF_IF2_SR_PAT_MASK SF_CTRL_SF_IF2_SR_PAT_MASK +#define SF_CTRL_SF_IF2_SR_PAT_MASK_POS (0U) +#define SF_CTRL_SF_IF2_SR_PAT_MASK_LEN (8U) +#define SF_CTRL_SF_IF2_SR_PAT_MASK_MSK (((1U << SF_CTRL_SF_IF2_SR_PAT_MASK_LEN) - 1) << SF_CTRL_SF_IF2_SR_PAT_MASK_POS) +#define SF_CTRL_SF_IF2_SR_PAT_MASK_UMSK (~(((1U << SF_CTRL_SF_IF2_SR_PAT_MASK_LEN) - 1) << SF_CTRL_SF_IF2_SR_PAT_MASK_POS)) +#define SF_CTRL_SF_IF2_SR_PAT SF_CTRL_SF_IF2_SR_PAT +#define SF_CTRL_SF_IF2_SR_PAT_POS (8U) +#define SF_CTRL_SF_IF2_SR_PAT_LEN (8U) +#define SF_CTRL_SF_IF2_SR_PAT_MSK (((1U << SF_CTRL_SF_IF2_SR_PAT_LEN) - 1) << SF_CTRL_SF_IF2_SR_PAT_POS) +#define SF_CTRL_SF_IF2_SR_PAT_UMSK (~(((1U << SF_CTRL_SF_IF2_SR_PAT_LEN) - 1) << SF_CTRL_SF_IF2_SR_PAT_POS)) +#define SF_CTRL_SF_IF2_SR_INT SF_CTRL_SF_IF2_SR_INT +#define SF_CTRL_SF_IF2_SR_INT_POS (16U) +#define SF_CTRL_SF_IF2_SR_INT_LEN (1U) +#define SF_CTRL_SF_IF2_SR_INT_MSK (((1U << SF_CTRL_SF_IF2_SR_INT_LEN) - 1) << SF_CTRL_SF_IF2_SR_INT_POS) +#define SF_CTRL_SF_IF2_SR_INT_UMSK (~(((1U << SF_CTRL_SF_IF2_SR_INT_LEN) - 1) << SF_CTRL_SF_IF2_SR_INT_POS)) +#define SF_CTRL_SF_IF2_SR_INT_EN SF_CTRL_SF_IF2_SR_INT_EN +#define SF_CTRL_SF_IF2_SR_INT_EN_POS (17U) +#define SF_CTRL_SF_IF2_SR_INT_EN_LEN (1U) +#define SF_CTRL_SF_IF2_SR_INT_EN_MSK (((1U << SF_CTRL_SF_IF2_SR_INT_EN_LEN) - 1) << SF_CTRL_SF_IF2_SR_INT_EN_POS) +#define SF_CTRL_SF_IF2_SR_INT_EN_UMSK (~(((1U << SF_CTRL_SF_IF2_SR_INT_EN_LEN) - 1) << SF_CTRL_SF_IF2_SR_INT_EN_POS)) +#define SF_CTRL_SF_IF2_SR_INT_SET SF_CTRL_SF_IF2_SR_INT_SET +#define SF_CTRL_SF_IF2_SR_INT_SET_POS (18U) +#define SF_CTRL_SF_IF2_SR_INT_SET_LEN (1U) +#define SF_CTRL_SF_IF2_SR_INT_SET_MSK (((1U << SF_CTRL_SF_IF2_SR_INT_SET_LEN) - 1) << SF_CTRL_SF_IF2_SR_INT_SET_POS) +#define SF_CTRL_SF_IF2_SR_INT_SET_UMSK (~(((1U << SF_CTRL_SF_IF2_SR_INT_SET_LEN) - 1) << SF_CTRL_SF_IF2_SR_INT_SET_POS)) +#define SF_CTRL_SF_IF2_ACK_LAT SF_CTRL_SF_IF2_ACK_LAT +#define SF_CTRL_SF_IF2_ACK_LAT_POS (20U) +#define SF_CTRL_SF_IF2_ACK_LAT_LEN (3U) +#define SF_CTRL_SF_IF2_ACK_LAT_MSK (((1U << SF_CTRL_SF_IF2_ACK_LAT_LEN) - 1) << SF_CTRL_SF_IF2_ACK_LAT_POS) +#define SF_CTRL_SF_IF2_ACK_LAT_UMSK (~(((1U << SF_CTRL_SF_IF2_ACK_LAT_LEN) - 1) << SF_CTRL_SF_IF2_ACK_LAT_POS)) +#define SF_CTRL_SF_IF2_REG_HOLD SF_CTRL_SF_IF2_REG_HOLD +#define SF_CTRL_SF_IF2_REG_HOLD_POS (24U) +#define SF_CTRL_SF_IF2_REG_HOLD_LEN (1U) +#define SF_CTRL_SF_IF2_REG_HOLD_MSK (((1U << SF_CTRL_SF_IF2_REG_HOLD_LEN) - 1) << SF_CTRL_SF_IF2_REG_HOLD_POS) +#define SF_CTRL_SF_IF2_REG_HOLD_UMSK (~(((1U << SF_CTRL_SF_IF2_REG_HOLD_LEN) - 1) << SF_CTRL_SF_IF2_REG_HOLD_POS)) +#define SF_CTRL_SF_IF2_REG_WP SF_CTRL_SF_IF2_REG_WP +#define SF_CTRL_SF_IF2_REG_WP_POS (25U) +#define SF_CTRL_SF_IF2_REG_WP_LEN (1U) +#define SF_CTRL_SF_IF2_REG_WP_MSK (((1U << SF_CTRL_SF_IF2_REG_WP_LEN) - 1) << SF_CTRL_SF_IF2_REG_WP_POS) +#define SF_CTRL_SF_IF2_REG_WP_UMSK (~(((1U << SF_CTRL_SF_IF2_REG_WP_LEN) - 1) << SF_CTRL_SF_IF2_REG_WP_POS)) +#define SF_CTRL_SF_IF2_FN_SEL SF_CTRL_SF_IF2_FN_SEL +#define SF_CTRL_SF_IF2_FN_SEL_POS (28U) +#define SF_CTRL_SF_IF2_FN_SEL_LEN (1U) +#define SF_CTRL_SF_IF2_FN_SEL_MSK (((1U << SF_CTRL_SF_IF2_FN_SEL_LEN) - 1) << SF_CTRL_SF_IF2_FN_SEL_POS) +#define SF_CTRL_SF_IF2_FN_SEL_UMSK (~(((1U << SF_CTRL_SF_IF2_FN_SEL_LEN) - 1) << SF_CTRL_SF_IF2_FN_SEL_POS)) +#define SF_CTRL_SF_IF2_EN SF_CTRL_SF_IF2_EN +#define SF_CTRL_SF_IF2_EN_POS (29U) +#define SF_CTRL_SF_IF2_EN_LEN (1U) +#define SF_CTRL_SF_IF2_EN_MSK (((1U << SF_CTRL_SF_IF2_EN_LEN) - 1) << SF_CTRL_SF_IF2_EN_POS) +#define SF_CTRL_SF_IF2_EN_UMSK (~(((1U << SF_CTRL_SF_IF2_EN_LEN) - 1) << SF_CTRL_SF_IF2_EN_POS)) + +/* 0xC8 : sf_if2_sahb_0 */ +#define SF_CTRL_SF_IF2_SAHB_0_OFFSET (0xC8) +#define SF_CTRL_SF_IF2_BUSY SF_CTRL_SF_IF2_BUSY +#define SF_CTRL_SF_IF2_BUSY_POS (0U) +#define SF_CTRL_SF_IF2_BUSY_LEN (1U) +#define SF_CTRL_SF_IF2_BUSY_MSK (((1U << SF_CTRL_SF_IF2_BUSY_LEN) - 1) << SF_CTRL_SF_IF2_BUSY_POS) +#define SF_CTRL_SF_IF2_BUSY_UMSK (~(((1U << SF_CTRL_SF_IF2_BUSY_LEN) - 1) << SF_CTRL_SF_IF2_BUSY_POS)) +#define SF_CTRL_SF_IF2_0_TRIG SF_CTRL_SF_IF2_0_TRIG +#define SF_CTRL_SF_IF2_0_TRIG_POS (1U) +#define SF_CTRL_SF_IF2_0_TRIG_LEN (1U) +#define SF_CTRL_SF_IF2_0_TRIG_MSK (((1U << SF_CTRL_SF_IF2_0_TRIG_LEN) - 1) << SF_CTRL_SF_IF2_0_TRIG_POS) +#define SF_CTRL_SF_IF2_0_TRIG_UMSK (~(((1U << SF_CTRL_SF_IF2_0_TRIG_LEN) - 1) << SF_CTRL_SF_IF2_0_TRIG_POS)) +#define SF_CTRL_SF_IF2_0_DAT_BYTE SF_CTRL_SF_IF2_0_DAT_BYTE +#define SF_CTRL_SF_IF2_0_DAT_BYTE_POS (2U) +#define SF_CTRL_SF_IF2_0_DAT_BYTE_LEN (10U) +#define SF_CTRL_SF_IF2_0_DAT_BYTE_MSK (((1U << SF_CTRL_SF_IF2_0_DAT_BYTE_LEN) - 1) << SF_CTRL_SF_IF2_0_DAT_BYTE_POS) +#define SF_CTRL_SF_IF2_0_DAT_BYTE_UMSK (~(((1U << SF_CTRL_SF_IF2_0_DAT_BYTE_LEN) - 1) << SF_CTRL_SF_IF2_0_DAT_BYTE_POS)) +#define SF_CTRL_SF_IF2_0_DMY_BYTE SF_CTRL_SF_IF2_0_DMY_BYTE +#define SF_CTRL_SF_IF2_0_DMY_BYTE_POS (12U) +#define SF_CTRL_SF_IF2_0_DMY_BYTE_LEN (5U) +#define SF_CTRL_SF_IF2_0_DMY_BYTE_MSK (((1U << SF_CTRL_SF_IF2_0_DMY_BYTE_LEN) - 1) << SF_CTRL_SF_IF2_0_DMY_BYTE_POS) +#define SF_CTRL_SF_IF2_0_DMY_BYTE_UMSK (~(((1U << SF_CTRL_SF_IF2_0_DMY_BYTE_LEN) - 1) << SF_CTRL_SF_IF2_0_DMY_BYTE_POS)) +#define SF_CTRL_SF_IF2_0_ADR_BYTE SF_CTRL_SF_IF2_0_ADR_BYTE +#define SF_CTRL_SF_IF2_0_ADR_BYTE_POS (17U) +#define SF_CTRL_SF_IF2_0_ADR_BYTE_LEN (3U) +#define SF_CTRL_SF_IF2_0_ADR_BYTE_MSK (((1U << SF_CTRL_SF_IF2_0_ADR_BYTE_LEN) - 1) << SF_CTRL_SF_IF2_0_ADR_BYTE_POS) +#define SF_CTRL_SF_IF2_0_ADR_BYTE_UMSK (~(((1U << SF_CTRL_SF_IF2_0_ADR_BYTE_LEN) - 1) << SF_CTRL_SF_IF2_0_ADR_BYTE_POS)) +#define SF_CTRL_SF_IF2_0_CMD_BYTE SF_CTRL_SF_IF2_0_CMD_BYTE +#define SF_CTRL_SF_IF2_0_CMD_BYTE_POS (20U) +#define SF_CTRL_SF_IF2_0_CMD_BYTE_LEN (3U) +#define SF_CTRL_SF_IF2_0_CMD_BYTE_MSK (((1U << SF_CTRL_SF_IF2_0_CMD_BYTE_LEN) - 1) << SF_CTRL_SF_IF2_0_CMD_BYTE_POS) +#define SF_CTRL_SF_IF2_0_CMD_BYTE_UMSK (~(((1U << SF_CTRL_SF_IF2_0_CMD_BYTE_LEN) - 1) << SF_CTRL_SF_IF2_0_CMD_BYTE_POS)) +#define SF_CTRL_SF_IF2_0_DAT_RW SF_CTRL_SF_IF2_0_DAT_RW +#define SF_CTRL_SF_IF2_0_DAT_RW_POS (23U) +#define SF_CTRL_SF_IF2_0_DAT_RW_LEN (1U) +#define SF_CTRL_SF_IF2_0_DAT_RW_MSK (((1U << SF_CTRL_SF_IF2_0_DAT_RW_LEN) - 1) << SF_CTRL_SF_IF2_0_DAT_RW_POS) +#define SF_CTRL_SF_IF2_0_DAT_RW_UMSK (~(((1U << SF_CTRL_SF_IF2_0_DAT_RW_LEN) - 1) << SF_CTRL_SF_IF2_0_DAT_RW_POS)) +#define SF_CTRL_SF_IF2_0_DAT_EN SF_CTRL_SF_IF2_0_DAT_EN +#define SF_CTRL_SF_IF2_0_DAT_EN_POS (24U) +#define SF_CTRL_SF_IF2_0_DAT_EN_LEN (1U) +#define SF_CTRL_SF_IF2_0_DAT_EN_MSK (((1U << SF_CTRL_SF_IF2_0_DAT_EN_LEN) - 1) << SF_CTRL_SF_IF2_0_DAT_EN_POS) +#define SF_CTRL_SF_IF2_0_DAT_EN_UMSK (~(((1U << SF_CTRL_SF_IF2_0_DAT_EN_LEN) - 1) << SF_CTRL_SF_IF2_0_DAT_EN_POS)) +#define SF_CTRL_SF_IF2_0_DMY_EN SF_CTRL_SF_IF2_0_DMY_EN +#define SF_CTRL_SF_IF2_0_DMY_EN_POS (25U) +#define SF_CTRL_SF_IF2_0_DMY_EN_LEN (1U) +#define SF_CTRL_SF_IF2_0_DMY_EN_MSK (((1U << SF_CTRL_SF_IF2_0_DMY_EN_LEN) - 1) << SF_CTRL_SF_IF2_0_DMY_EN_POS) +#define SF_CTRL_SF_IF2_0_DMY_EN_UMSK (~(((1U << SF_CTRL_SF_IF2_0_DMY_EN_LEN) - 1) << SF_CTRL_SF_IF2_0_DMY_EN_POS)) +#define SF_CTRL_SF_IF2_0_ADR_EN SF_CTRL_SF_IF2_0_ADR_EN +#define SF_CTRL_SF_IF2_0_ADR_EN_POS (26U) +#define SF_CTRL_SF_IF2_0_ADR_EN_LEN (1U) +#define SF_CTRL_SF_IF2_0_ADR_EN_MSK (((1U << SF_CTRL_SF_IF2_0_ADR_EN_LEN) - 1) << SF_CTRL_SF_IF2_0_ADR_EN_POS) +#define SF_CTRL_SF_IF2_0_ADR_EN_UMSK (~(((1U << SF_CTRL_SF_IF2_0_ADR_EN_LEN) - 1) << SF_CTRL_SF_IF2_0_ADR_EN_POS)) +#define SF_CTRL_SF_IF2_0_CMD_EN SF_CTRL_SF_IF2_0_CMD_EN +#define SF_CTRL_SF_IF2_0_CMD_EN_POS (27U) +#define SF_CTRL_SF_IF2_0_CMD_EN_LEN (1U) +#define SF_CTRL_SF_IF2_0_CMD_EN_MSK (((1U << SF_CTRL_SF_IF2_0_CMD_EN_LEN) - 1) << SF_CTRL_SF_IF2_0_CMD_EN_POS) +#define SF_CTRL_SF_IF2_0_CMD_EN_UMSK (~(((1U << SF_CTRL_SF_IF2_0_CMD_EN_LEN) - 1) << SF_CTRL_SF_IF2_0_CMD_EN_POS)) +#define SF_CTRL_SF_IF2_0_SPI_MODE SF_CTRL_SF_IF2_0_SPI_MODE +#define SF_CTRL_SF_IF2_0_SPI_MODE_POS (28U) +#define SF_CTRL_SF_IF2_0_SPI_MODE_LEN (3U) +#define SF_CTRL_SF_IF2_0_SPI_MODE_MSK (((1U << SF_CTRL_SF_IF2_0_SPI_MODE_LEN) - 1) << SF_CTRL_SF_IF2_0_SPI_MODE_POS) +#define SF_CTRL_SF_IF2_0_SPI_MODE_UMSK (~(((1U << SF_CTRL_SF_IF2_0_SPI_MODE_LEN) - 1) << SF_CTRL_SF_IF2_0_SPI_MODE_POS)) +#define SF_CTRL_SF_IF2_0_QPI_MODE_EN SF_CTRL_SF_IF2_0_QPI_MODE_EN +#define SF_CTRL_SF_IF2_0_QPI_MODE_EN_POS (31U) +#define SF_CTRL_SF_IF2_0_QPI_MODE_EN_LEN (1U) +#define SF_CTRL_SF_IF2_0_QPI_MODE_EN_MSK (((1U << SF_CTRL_SF_IF2_0_QPI_MODE_EN_LEN) - 1) << SF_CTRL_SF_IF2_0_QPI_MODE_EN_POS) +#define SF_CTRL_SF_IF2_0_QPI_MODE_EN_UMSK (~(((1U << SF_CTRL_SF_IF2_0_QPI_MODE_EN_LEN) - 1) << SF_CTRL_SF_IF2_0_QPI_MODE_EN_POS)) + +/* 0xCC : sf_if2_sahb_1 */ +#define SF_CTRL_SF_IF2_SAHB_1_OFFSET (0xCC) +#define SF_CTRL_SF_IF2_0_CMD_BUF_0 SF_CTRL_SF_IF2_0_CMD_BUF_0 +#define SF_CTRL_SF_IF2_0_CMD_BUF_0_POS (0U) +#define SF_CTRL_SF_IF2_0_CMD_BUF_0_LEN (32U) +#define SF_CTRL_SF_IF2_0_CMD_BUF_0_MSK (((1U << SF_CTRL_SF_IF2_0_CMD_BUF_0_LEN) - 1) << SF_CTRL_SF_IF2_0_CMD_BUF_0_POS) +#define SF_CTRL_SF_IF2_0_CMD_BUF_0_UMSK (~(((1U << SF_CTRL_SF_IF2_0_CMD_BUF_0_LEN) - 1) << SF_CTRL_SF_IF2_0_CMD_BUF_0_POS)) + +/* 0xD0 : sf_if2_sahb_2 */ +#define SF_CTRL_SF_IF2_SAHB_2_OFFSET (0xD0) +#define SF_CTRL_SF_IF2_0_CMD_BUF_1 SF_CTRL_SF_IF2_0_CMD_BUF_1 +#define SF_CTRL_SF_IF2_0_CMD_BUF_1_POS (0U) +#define SF_CTRL_SF_IF2_0_CMD_BUF_1_LEN (32U) +#define SF_CTRL_SF_IF2_0_CMD_BUF_1_MSK (((1U << SF_CTRL_SF_IF2_0_CMD_BUF_1_LEN) - 1) << SF_CTRL_SF_IF2_0_CMD_BUF_1_POS) +#define SF_CTRL_SF_IF2_0_CMD_BUF_1_UMSK (~(((1U << SF_CTRL_SF_IF2_0_CMD_BUF_1_LEN) - 1) << SF_CTRL_SF_IF2_0_CMD_BUF_1_POS)) + +/* 0x100 : sf_ctrl_prot_en_rd */ +#define SF_CTRL_PROT_EN_RD_OFFSET (0x100) +#define SF_CTRL_ID0_EN_RD SF_CTRL_ID0_EN_RD +#define SF_CTRL_ID0_EN_RD_POS (1U) +#define SF_CTRL_ID0_EN_RD_LEN (1U) +#define SF_CTRL_ID0_EN_RD_MSK (((1U << SF_CTRL_ID0_EN_RD_LEN) - 1) << SF_CTRL_ID0_EN_RD_POS) +#define SF_CTRL_ID0_EN_RD_UMSK (~(((1U << SF_CTRL_ID0_EN_RD_LEN) - 1) << SF_CTRL_ID0_EN_RD_POS)) +#define SF_CTRL_ID1_EN_RD SF_CTRL_ID1_EN_RD +#define SF_CTRL_ID1_EN_RD_POS (2U) +#define SF_CTRL_ID1_EN_RD_LEN (1U) +#define SF_CTRL_ID1_EN_RD_MSK (((1U << SF_CTRL_ID1_EN_RD_LEN) - 1) << SF_CTRL_ID1_EN_RD_POS) +#define SF_CTRL_ID1_EN_RD_UMSK (~(((1U << SF_CTRL_ID1_EN_RD_LEN) - 1) << SF_CTRL_ID1_EN_RD_POS)) +#define SF_CTRL_SF_SEC_TZSID_LOCK SF_CTRL_SF_SEC_TZSID_LOCK +#define SF_CTRL_SF_SEC_TZSID_LOCK_POS (28U) +#define SF_CTRL_SF_SEC_TZSID_LOCK_LEN (1U) +#define SF_CTRL_SF_SEC_TZSID_LOCK_MSK (((1U << SF_CTRL_SF_SEC_TZSID_LOCK_LEN) - 1) << SF_CTRL_SF_SEC_TZSID_LOCK_POS) +#define SF_CTRL_SF_SEC_TZSID_LOCK_UMSK (~(((1U << SF_CTRL_SF_SEC_TZSID_LOCK_LEN) - 1) << SF_CTRL_SF_SEC_TZSID_LOCK_POS)) +#define SF_CTRL_SF_IF2_0_TRIG_WR_LOCK SF_CTRL_SF_IF2_0_TRIG_WR_LOCK +#define SF_CTRL_SF_IF2_0_TRIG_WR_LOCK_POS (29U) +#define SF_CTRL_SF_IF2_0_TRIG_WR_LOCK_LEN (1U) +#define SF_CTRL_SF_IF2_0_TRIG_WR_LOCK_MSK (((1U << SF_CTRL_SF_IF2_0_TRIG_WR_LOCK_LEN) - 1) << SF_CTRL_SF_IF2_0_TRIG_WR_LOCK_POS) +#define SF_CTRL_SF_IF2_0_TRIG_WR_LOCK_UMSK (~(((1U << SF_CTRL_SF_IF2_0_TRIG_WR_LOCK_LEN) - 1) << SF_CTRL_SF_IF2_0_TRIG_WR_LOCK_POS)) +#define SF_CTRL_SF_IF_0_TRIG_WR_LOCK SF_CTRL_SF_IF_0_TRIG_WR_LOCK +#define SF_CTRL_SF_IF_0_TRIG_WR_LOCK_POS (30U) +#define SF_CTRL_SF_IF_0_TRIG_WR_LOCK_LEN (1U) +#define SF_CTRL_SF_IF_0_TRIG_WR_LOCK_MSK (((1U << SF_CTRL_SF_IF_0_TRIG_WR_LOCK_LEN) - 1) << SF_CTRL_SF_IF_0_TRIG_WR_LOCK_POS) +#define SF_CTRL_SF_IF_0_TRIG_WR_LOCK_UMSK (~(((1U << SF_CTRL_SF_IF_0_TRIG_WR_LOCK_LEN) - 1) << SF_CTRL_SF_IF_0_TRIG_WR_LOCK_POS)) +#define SF_CTRL_SF_DBG_DIS SF_CTRL_SF_DBG_DIS +#define SF_CTRL_SF_DBG_DIS_POS (31U) +#define SF_CTRL_SF_DBG_DIS_LEN (1U) +#define SF_CTRL_SF_DBG_DIS_MSK (((1U << SF_CTRL_SF_DBG_DIS_LEN) - 1) << SF_CTRL_SF_DBG_DIS_POS) +#define SF_CTRL_SF_DBG_DIS_UMSK (~(((1U << SF_CTRL_SF_DBG_DIS_LEN) - 1) << SF_CTRL_SF_DBG_DIS_POS)) + +/* 0x104 : sf_ctrl_prot_en */ +#define SF_CTRL_PROT_EN_OFFSET (0x104) +#define SF_CTRL_ID0_EN SF_CTRL_ID0_EN +#define SF_CTRL_ID0_EN_POS (1U) +#define SF_CTRL_ID0_EN_LEN (1U) +#define SF_CTRL_ID0_EN_MSK (((1U << SF_CTRL_ID0_EN_LEN) - 1) << SF_CTRL_ID0_EN_POS) +#define SF_CTRL_ID0_EN_UMSK (~(((1U << SF_CTRL_ID0_EN_LEN) - 1) << SF_CTRL_ID0_EN_POS)) +#define SF_CTRL_ID1_EN SF_CTRL_ID1_EN +#define SF_CTRL_ID1_EN_POS (2U) +#define SF_CTRL_ID1_EN_LEN (1U) +#define SF_CTRL_ID1_EN_MSK (((1U << SF_CTRL_ID1_EN_LEN) - 1) << SF_CTRL_ID1_EN_POS) +#define SF_CTRL_ID1_EN_UMSK (~(((1U << SF_CTRL_ID1_EN_LEN) - 1) << SF_CTRL_ID1_EN_POS)) + +/* 0x200 : sf_aes_key_r0_0 */ +#define SF_CTRL_SF_AES_KEY_R0_0_OFFSET (0x200) +#define SF_CTRL_SF_AES_KEY_R0_0 SF_CTRL_SF_AES_KEY_R0_0 +#define SF_CTRL_SF_AES_KEY_R0_0_POS (0U) +#define SF_CTRL_SF_AES_KEY_R0_0_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R0_0_MSK (((1U << SF_CTRL_SF_AES_KEY_R0_0_LEN) - 1) << SF_CTRL_SF_AES_KEY_R0_0_POS) +#define SF_CTRL_SF_AES_KEY_R0_0_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R0_0_LEN) - 1) << SF_CTRL_SF_AES_KEY_R0_0_POS)) + +/* 0x204 : sf_aes_key_r0_1 */ +#define SF_CTRL_SF_AES_KEY_R0_1_OFFSET (0x204) +#define SF_CTRL_SF_AES_KEY_R0_1 SF_CTRL_SF_AES_KEY_R0_1 +#define SF_CTRL_SF_AES_KEY_R0_1_POS (0U) +#define SF_CTRL_SF_AES_KEY_R0_1_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R0_1_MSK (((1U << SF_CTRL_SF_AES_KEY_R0_1_LEN) - 1) << SF_CTRL_SF_AES_KEY_R0_1_POS) +#define SF_CTRL_SF_AES_KEY_R0_1_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R0_1_LEN) - 1) << SF_CTRL_SF_AES_KEY_R0_1_POS)) + +/* 0x208 : sf_aes_key_r0_2 */ +#define SF_CTRL_SF_AES_KEY_R0_2_OFFSET (0x208) +#define SF_CTRL_SF_AES_KEY_R0_2 SF_CTRL_SF_AES_KEY_R0_2 +#define SF_CTRL_SF_AES_KEY_R0_2_POS (0U) +#define SF_CTRL_SF_AES_KEY_R0_2_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R0_2_MSK (((1U << SF_CTRL_SF_AES_KEY_R0_2_LEN) - 1) << SF_CTRL_SF_AES_KEY_R0_2_POS) +#define SF_CTRL_SF_AES_KEY_R0_2_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R0_2_LEN) - 1) << SF_CTRL_SF_AES_KEY_R0_2_POS)) + +/* 0x20C : sf_aes_key_r0_3 */ +#define SF_CTRL_SF_AES_KEY_R0_3_OFFSET (0x20C) +#define SF_CTRL_SF_AES_KEY_R0_3 SF_CTRL_SF_AES_KEY_R0_3 +#define SF_CTRL_SF_AES_KEY_R0_3_POS (0U) +#define SF_CTRL_SF_AES_KEY_R0_3_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R0_3_MSK (((1U << SF_CTRL_SF_AES_KEY_R0_3_LEN) - 1) << SF_CTRL_SF_AES_KEY_R0_3_POS) +#define SF_CTRL_SF_AES_KEY_R0_3_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R0_3_LEN) - 1) << SF_CTRL_SF_AES_KEY_R0_3_POS)) + +/* 0x210 : sf_aes_key_r0_4 */ +#define SF_CTRL_SF_AES_KEY_R0_4_OFFSET (0x210) +#define SF_CTRL_SF_AES_KEY_R0_4 SF_CTRL_SF_AES_KEY_R0_4 +#define SF_CTRL_SF_AES_KEY_R0_4_POS (0U) +#define SF_CTRL_SF_AES_KEY_R0_4_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R0_4_MSK (((1U << SF_CTRL_SF_AES_KEY_R0_4_LEN) - 1) << SF_CTRL_SF_AES_KEY_R0_4_POS) +#define SF_CTRL_SF_AES_KEY_R0_4_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R0_4_LEN) - 1) << SF_CTRL_SF_AES_KEY_R0_4_POS)) + +/* 0x214 : sf_aes_key_r0_5 */ +#define SF_CTRL_SF_AES_KEY_R0_5_OFFSET (0x214) +#define SF_CTRL_SF_AES_KEY_R0_5 SF_CTRL_SF_AES_KEY_R0_5 +#define SF_CTRL_SF_AES_KEY_R0_5_POS (0U) +#define SF_CTRL_SF_AES_KEY_R0_5_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R0_5_MSK (((1U << SF_CTRL_SF_AES_KEY_R0_5_LEN) - 1) << SF_CTRL_SF_AES_KEY_R0_5_POS) +#define SF_CTRL_SF_AES_KEY_R0_5_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R0_5_LEN) - 1) << SF_CTRL_SF_AES_KEY_R0_5_POS)) + +/* 0x218 : sf_aes_key_r0_6 */ +#define SF_CTRL_SF_AES_KEY_R0_6_OFFSET (0x218) +#define SF_CTRL_SF_AES_KEY_R0_6 SF_CTRL_SF_AES_KEY_R0_6 +#define SF_CTRL_SF_AES_KEY_R0_6_POS (0U) +#define SF_CTRL_SF_AES_KEY_R0_6_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R0_6_MSK (((1U << SF_CTRL_SF_AES_KEY_R0_6_LEN) - 1) << SF_CTRL_SF_AES_KEY_R0_6_POS) +#define SF_CTRL_SF_AES_KEY_R0_6_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R0_6_LEN) - 1) << SF_CTRL_SF_AES_KEY_R0_6_POS)) + +/* 0x21C : sf_aes_key_r0_7 */ +#define SF_CTRL_SF_AES_KEY_R0_7_OFFSET (0x21C) +#define SF_CTRL_SF_AES_KEY_R0_7 SF_CTRL_SF_AES_KEY_R0_7 +#define SF_CTRL_SF_AES_KEY_R0_7_POS (0U) +#define SF_CTRL_SF_AES_KEY_R0_7_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R0_7_MSK (((1U << SF_CTRL_SF_AES_KEY_R0_7_LEN) - 1) << SF_CTRL_SF_AES_KEY_R0_7_POS) +#define SF_CTRL_SF_AES_KEY_R0_7_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R0_7_LEN) - 1) << SF_CTRL_SF_AES_KEY_R0_7_POS)) + +/* 0x220 : sf_aes_iv_r0_w0 */ +#define SF_CTRL_SF_AES_IV_R0_W0_OFFSET (0x220) +#define SF_CTRL_SF_AES_IV_R0_W0 SF_CTRL_SF_AES_IV_R0_W0 +#define SF_CTRL_SF_AES_IV_R0_W0_POS (0U) +#define SF_CTRL_SF_AES_IV_R0_W0_LEN (32U) +#define SF_CTRL_SF_AES_IV_R0_W0_MSK (((1U << SF_CTRL_SF_AES_IV_R0_W0_LEN) - 1) << SF_CTRL_SF_AES_IV_R0_W0_POS) +#define SF_CTRL_SF_AES_IV_R0_W0_UMSK (~(((1U << SF_CTRL_SF_AES_IV_R0_W0_LEN) - 1) << SF_CTRL_SF_AES_IV_R0_W0_POS)) + +/* 0x224 : sf_aes_iv_r0_w1 */ +#define SF_CTRL_SF_AES_IV_R0_W1_OFFSET (0x224) +#define SF_CTRL_SF_AES_IV_R0_W1 SF_CTRL_SF_AES_IV_R0_W1 +#define SF_CTRL_SF_AES_IV_R0_W1_POS (0U) +#define SF_CTRL_SF_AES_IV_R0_W1_LEN (32U) +#define SF_CTRL_SF_AES_IV_R0_W1_MSK (((1U << SF_CTRL_SF_AES_IV_R0_W1_LEN) - 1) << SF_CTRL_SF_AES_IV_R0_W1_POS) +#define SF_CTRL_SF_AES_IV_R0_W1_UMSK (~(((1U << SF_CTRL_SF_AES_IV_R0_W1_LEN) - 1) << SF_CTRL_SF_AES_IV_R0_W1_POS)) + +/* 0x228 : sf_aes_iv_r0_w2 */ +#define SF_CTRL_SF_AES_IV_R0_W2_OFFSET (0x228) +#define SF_CTRL_SF_AES_IV_R0_W2 SF_CTRL_SF_AES_IV_R0_W2 +#define SF_CTRL_SF_AES_IV_R0_W2_POS (0U) +#define SF_CTRL_SF_AES_IV_R0_W2_LEN (32U) +#define SF_CTRL_SF_AES_IV_R0_W2_MSK (((1U << SF_CTRL_SF_AES_IV_R0_W2_LEN) - 1) << SF_CTRL_SF_AES_IV_R0_W2_POS) +#define SF_CTRL_SF_AES_IV_R0_W2_UMSK (~(((1U << SF_CTRL_SF_AES_IV_R0_W2_LEN) - 1) << SF_CTRL_SF_AES_IV_R0_W2_POS)) + +/* 0x22C : sf_aes_iv_r0_w3 */ +#define SF_CTRL_SF_AES_IV_R0_W3_OFFSET (0x22C) +#define SF_CTRL_SF_AES_IV_R0_W3 SF_CTRL_SF_AES_IV_R0_W3 +#define SF_CTRL_SF_AES_IV_R0_W3_POS (0U) +#define SF_CTRL_SF_AES_IV_R0_W3_LEN (32U) +#define SF_CTRL_SF_AES_IV_R0_W3_MSK (((1U << SF_CTRL_SF_AES_IV_R0_W3_LEN) - 1) << SF_CTRL_SF_AES_IV_R0_W3_POS) +#define SF_CTRL_SF_AES_IV_R0_W3_UMSK (~(((1U << SF_CTRL_SF_AES_IV_R0_W3_LEN) - 1) << SF_CTRL_SF_AES_IV_R0_W3_POS)) + +/* 0x230 : sf_aes_r0_start */ +#define SF_CTRL_SF_AES_R0_START_OFFSET (0x230) +#define SF_CTRL_SF_AES_REGION_R0_START SF_CTRL_SF_AES_REGION_R0_START +#define SF_CTRL_SF_AES_REGION_R0_START_POS (0U) +#define SF_CTRL_SF_AES_REGION_R0_START_LEN (19U) +#define SF_CTRL_SF_AES_REGION_R0_START_MSK (((1U << SF_CTRL_SF_AES_REGION_R0_START_LEN) - 1) << SF_CTRL_SF_AES_REGION_R0_START_POS) +#define SF_CTRL_SF_AES_REGION_R0_START_UMSK (~(((1U << SF_CTRL_SF_AES_REGION_R0_START_LEN) - 1) << SF_CTRL_SF_AES_REGION_R0_START_POS)) +#define SF_CTRL_SF_AES_REGION_R0_HW_KEY_EN SF_CTRL_SF_AES_REGION_R0_HW_KEY_EN +#define SF_CTRL_SF_AES_REGION_R0_HW_KEY_EN_POS (29U) +#define SF_CTRL_SF_AES_REGION_R0_HW_KEY_EN_LEN (1U) +#define SF_CTRL_SF_AES_REGION_R0_HW_KEY_EN_MSK (((1U << SF_CTRL_SF_AES_REGION_R0_HW_KEY_EN_LEN) - 1) << SF_CTRL_SF_AES_REGION_R0_HW_KEY_EN_POS) +#define SF_CTRL_SF_AES_REGION_R0_HW_KEY_EN_UMSK (~(((1U << SF_CTRL_SF_AES_REGION_R0_HW_KEY_EN_LEN) - 1) << SF_CTRL_SF_AES_REGION_R0_HW_KEY_EN_POS)) +#define SF_CTRL_SF_AES_REGION_R0_EN SF_CTRL_SF_AES_REGION_R0_EN +#define SF_CTRL_SF_AES_REGION_R0_EN_POS (30U) +#define SF_CTRL_SF_AES_REGION_R0_EN_LEN (1U) +#define SF_CTRL_SF_AES_REGION_R0_EN_MSK (((1U << SF_CTRL_SF_AES_REGION_R0_EN_LEN) - 1) << SF_CTRL_SF_AES_REGION_R0_EN_POS) +#define SF_CTRL_SF_AES_REGION_R0_EN_UMSK (~(((1U << SF_CTRL_SF_AES_REGION_R0_EN_LEN) - 1) << SF_CTRL_SF_AES_REGION_R0_EN_POS)) +#define SF_CTRL_SF_AES_REGION_R0_LOCK SF_CTRL_SF_AES_REGION_R0_LOCK +#define SF_CTRL_SF_AES_REGION_R0_LOCK_POS (31U) +#define SF_CTRL_SF_AES_REGION_R0_LOCK_LEN (1U) +#define SF_CTRL_SF_AES_REGION_R0_LOCK_MSK (((1U << SF_CTRL_SF_AES_REGION_R0_LOCK_LEN) - 1) << SF_CTRL_SF_AES_REGION_R0_LOCK_POS) +#define SF_CTRL_SF_AES_REGION_R0_LOCK_UMSK (~(((1U << SF_CTRL_SF_AES_REGION_R0_LOCK_LEN) - 1) << SF_CTRL_SF_AES_REGION_R0_LOCK_POS)) + +/* 0x234 : sf_aes_r0_end */ +#define SF_CTRL_SF_AES_R0_END_OFFSET (0x234) +#define SF_CTRL_SF_AES_REGION_R0_END SF_CTRL_SF_AES_REGION_R0_END +#define SF_CTRL_SF_AES_REGION_R0_END_POS (0U) +#define SF_CTRL_SF_AES_REGION_R0_END_LEN (19U) +#define SF_CTRL_SF_AES_REGION_R0_END_MSK (((1U << SF_CTRL_SF_AES_REGION_R0_END_LEN) - 1) << SF_CTRL_SF_AES_REGION_R0_END_POS) +#define SF_CTRL_SF_AES_REGION_R0_END_UMSK (~(((1U << SF_CTRL_SF_AES_REGION_R0_END_LEN) - 1) << SF_CTRL_SF_AES_REGION_R0_END_POS)) + +/* 0x280 : sf_aes_key_r1_0 */ +#define SF_CTRL_SF_AES_KEY_R1_0_OFFSET (0x280) +#define SF_CTRL_SF_AES_KEY_R1_0 SF_CTRL_SF_AES_KEY_R1_0 +#define SF_CTRL_SF_AES_KEY_R1_0_POS (0U) +#define SF_CTRL_SF_AES_KEY_R1_0_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R1_0_MSK (((1U << SF_CTRL_SF_AES_KEY_R1_0_LEN) - 1) << SF_CTRL_SF_AES_KEY_R1_0_POS) +#define SF_CTRL_SF_AES_KEY_R1_0_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R1_0_LEN) - 1) << SF_CTRL_SF_AES_KEY_R1_0_POS)) + +/* 0x284 : sf_aes_key_r1_1 */ +#define SF_CTRL_SF_AES_KEY_R1_1_OFFSET (0x284) +#define SF_CTRL_SF_AES_KEY_R1_1 SF_CTRL_SF_AES_KEY_R1_1 +#define SF_CTRL_SF_AES_KEY_R1_1_POS (0U) +#define SF_CTRL_SF_AES_KEY_R1_1_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R1_1_MSK (((1U << SF_CTRL_SF_AES_KEY_R1_1_LEN) - 1) << SF_CTRL_SF_AES_KEY_R1_1_POS) +#define SF_CTRL_SF_AES_KEY_R1_1_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R1_1_LEN) - 1) << SF_CTRL_SF_AES_KEY_R1_1_POS)) + +/* 0x288 : sf_aes_key_r1_2 */ +#define SF_CTRL_SF_AES_KEY_R1_2_OFFSET (0x288) +#define SF_CTRL_SF_AES_KEY_R1_2 SF_CTRL_SF_AES_KEY_R1_2 +#define SF_CTRL_SF_AES_KEY_R1_2_POS (0U) +#define SF_CTRL_SF_AES_KEY_R1_2_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R1_2_MSK (((1U << SF_CTRL_SF_AES_KEY_R1_2_LEN) - 1) << SF_CTRL_SF_AES_KEY_R1_2_POS) +#define SF_CTRL_SF_AES_KEY_R1_2_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R1_2_LEN) - 1) << SF_CTRL_SF_AES_KEY_R1_2_POS)) + +/* 0x28C : sf_aes_key_r1_3 */ +#define SF_CTRL_SF_AES_KEY_R1_3_OFFSET (0x28C) +#define SF_CTRL_SF_AES_KEY_R1_3 SF_CTRL_SF_AES_KEY_R1_3 +#define SF_CTRL_SF_AES_KEY_R1_3_POS (0U) +#define SF_CTRL_SF_AES_KEY_R1_3_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R1_3_MSK (((1U << SF_CTRL_SF_AES_KEY_R1_3_LEN) - 1) << SF_CTRL_SF_AES_KEY_R1_3_POS) +#define SF_CTRL_SF_AES_KEY_R1_3_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R1_3_LEN) - 1) << SF_CTRL_SF_AES_KEY_R1_3_POS)) + +/* 0x290 : sf_aes_key_r1_4 */ +#define SF_CTRL_SF_AES_KEY_R1_4_OFFSET (0x290) +#define SF_CTRL_SF_AES_KEY_R1_4 SF_CTRL_SF_AES_KEY_R1_4 +#define SF_CTRL_SF_AES_KEY_R1_4_POS (0U) +#define SF_CTRL_SF_AES_KEY_R1_4_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R1_4_MSK (((1U << SF_CTRL_SF_AES_KEY_R1_4_LEN) - 1) << SF_CTRL_SF_AES_KEY_R1_4_POS) +#define SF_CTRL_SF_AES_KEY_R1_4_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R1_4_LEN) - 1) << SF_CTRL_SF_AES_KEY_R1_4_POS)) + +/* 0x294 : sf_aes_key_r1_5 */ +#define SF_CTRL_SF_AES_KEY_R1_5_OFFSET (0x294) +#define SF_CTRL_SF_AES_KEY_R1_5 SF_CTRL_SF_AES_KEY_R1_5 +#define SF_CTRL_SF_AES_KEY_R1_5_POS (0U) +#define SF_CTRL_SF_AES_KEY_R1_5_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R1_5_MSK (((1U << SF_CTRL_SF_AES_KEY_R1_5_LEN) - 1) << SF_CTRL_SF_AES_KEY_R1_5_POS) +#define SF_CTRL_SF_AES_KEY_R1_5_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R1_5_LEN) - 1) << SF_CTRL_SF_AES_KEY_R1_5_POS)) + +/* 0x298 : sf_aes_key_r1_6 */ +#define SF_CTRL_SF_AES_KEY_R1_6_OFFSET (0x298) +#define SF_CTRL_SF_AES_KEY_R1_6 SF_CTRL_SF_AES_KEY_R1_6 +#define SF_CTRL_SF_AES_KEY_R1_6_POS (0U) +#define SF_CTRL_SF_AES_KEY_R1_6_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R1_6_MSK (((1U << SF_CTRL_SF_AES_KEY_R1_6_LEN) - 1) << SF_CTRL_SF_AES_KEY_R1_6_POS) +#define SF_CTRL_SF_AES_KEY_R1_6_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R1_6_LEN) - 1) << SF_CTRL_SF_AES_KEY_R1_6_POS)) + +/* 0x29C : sf_aes_key_r1_7 */ +#define SF_CTRL_SF_AES_KEY_R1_7_OFFSET (0x29C) +#define SF_CTRL_SF_AES_KEY_R1_7 SF_CTRL_SF_AES_KEY_R1_7 +#define SF_CTRL_SF_AES_KEY_R1_7_POS (0U) +#define SF_CTRL_SF_AES_KEY_R1_7_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R1_7_MSK (((1U << SF_CTRL_SF_AES_KEY_R1_7_LEN) - 1) << SF_CTRL_SF_AES_KEY_R1_7_POS) +#define SF_CTRL_SF_AES_KEY_R1_7_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R1_7_LEN) - 1) << SF_CTRL_SF_AES_KEY_R1_7_POS)) + +/* 0x2A0 : sf_aes_iv_r1_w0 */ +#define SF_CTRL_SF_AES_IV_R1_W0_OFFSET (0x2A0) +#define SF_CTRL_SF_AES_IV_R1_W0 SF_CTRL_SF_AES_IV_R1_W0 +#define SF_CTRL_SF_AES_IV_R1_W0_POS (0U) +#define SF_CTRL_SF_AES_IV_R1_W0_LEN (32U) +#define SF_CTRL_SF_AES_IV_R1_W0_MSK (((1U << SF_CTRL_SF_AES_IV_R1_W0_LEN) - 1) << SF_CTRL_SF_AES_IV_R1_W0_POS) +#define SF_CTRL_SF_AES_IV_R1_W0_UMSK (~(((1U << SF_CTRL_SF_AES_IV_R1_W0_LEN) - 1) << SF_CTRL_SF_AES_IV_R1_W0_POS)) + +/* 0x2A4 : sf_aes_iv_r1_w1 */ +#define SF_CTRL_SF_AES_IV_R1_W1_OFFSET (0x2A4) +#define SF_CTRL_SF_AES_IV_R1_W1 SF_CTRL_SF_AES_IV_R1_W1 +#define SF_CTRL_SF_AES_IV_R1_W1_POS (0U) +#define SF_CTRL_SF_AES_IV_R1_W1_LEN (32U) +#define SF_CTRL_SF_AES_IV_R1_W1_MSK (((1U << SF_CTRL_SF_AES_IV_R1_W1_LEN) - 1) << SF_CTRL_SF_AES_IV_R1_W1_POS) +#define SF_CTRL_SF_AES_IV_R1_W1_UMSK (~(((1U << SF_CTRL_SF_AES_IV_R1_W1_LEN) - 1) << SF_CTRL_SF_AES_IV_R1_W1_POS)) + +/* 0x2A8 : sf_aes_iv_r1_w2 */ +#define SF_CTRL_SF_AES_IV_R1_W2_OFFSET (0x2A8) +#define SF_CTRL_SF_AES_IV_R1_W2 SF_CTRL_SF_AES_IV_R1_W2 +#define SF_CTRL_SF_AES_IV_R1_W2_POS (0U) +#define SF_CTRL_SF_AES_IV_R1_W2_LEN (32U) +#define SF_CTRL_SF_AES_IV_R1_W2_MSK (((1U << SF_CTRL_SF_AES_IV_R1_W2_LEN) - 1) << SF_CTRL_SF_AES_IV_R1_W2_POS) +#define SF_CTRL_SF_AES_IV_R1_W2_UMSK (~(((1U << SF_CTRL_SF_AES_IV_R1_W2_LEN) - 1) << SF_CTRL_SF_AES_IV_R1_W2_POS)) + +/* 0x2AC : sf_aes_iv_r1_w3 */ +#define SF_CTRL_SF_AES_IV_R1_W3_OFFSET (0x2AC) +#define SF_CTRL_SF_AES_IV_R1_W3 SF_CTRL_SF_AES_IV_R1_W3 +#define SF_CTRL_SF_AES_IV_R1_W3_POS (0U) +#define SF_CTRL_SF_AES_IV_R1_W3_LEN (32U) +#define SF_CTRL_SF_AES_IV_R1_W3_MSK (((1U << SF_CTRL_SF_AES_IV_R1_W3_LEN) - 1) << SF_CTRL_SF_AES_IV_R1_W3_POS) +#define SF_CTRL_SF_AES_IV_R1_W3_UMSK (~(((1U << SF_CTRL_SF_AES_IV_R1_W3_LEN) - 1) << SF_CTRL_SF_AES_IV_R1_W3_POS)) + +/* 0x2B0 : sf_aes_r1_start */ +#define SF_CTRL_SF_AES_R1_START_OFFSET (0x2B0) +#define SF_CTRL_SF_AES_R1_START SF_CTRL_SF_AES_R1_START +#define SF_CTRL_SF_AES_R1_START_POS (0U) +#define SF_CTRL_SF_AES_R1_START_LEN (19U) +#define SF_CTRL_SF_AES_R1_START_MSK (((1U << SF_CTRL_SF_AES_R1_START_LEN) - 1) << SF_CTRL_SF_AES_R1_START_POS) +#define SF_CTRL_SF_AES_R1_START_UMSK (~(((1U << SF_CTRL_SF_AES_R1_START_LEN) - 1) << SF_CTRL_SF_AES_R1_START_POS)) +#define SF_CTRL_SF_AES_R1_HW_KEY_EN SF_CTRL_SF_AES_R1_HW_KEY_EN +#define SF_CTRL_SF_AES_R1_HW_KEY_EN_POS (29U) +#define SF_CTRL_SF_AES_R1_HW_KEY_EN_LEN (1U) +#define SF_CTRL_SF_AES_R1_HW_KEY_EN_MSK (((1U << SF_CTRL_SF_AES_R1_HW_KEY_EN_LEN) - 1) << SF_CTRL_SF_AES_R1_HW_KEY_EN_POS) +#define SF_CTRL_SF_AES_R1_HW_KEY_EN_UMSK (~(((1U << SF_CTRL_SF_AES_R1_HW_KEY_EN_LEN) - 1) << SF_CTRL_SF_AES_R1_HW_KEY_EN_POS)) +#define SF_CTRL_SF_AES_R1_EN SF_CTRL_SF_AES_R1_EN +#define SF_CTRL_SF_AES_R1_EN_POS (30U) +#define SF_CTRL_SF_AES_R1_EN_LEN (1U) +#define SF_CTRL_SF_AES_R1_EN_MSK (((1U << SF_CTRL_SF_AES_R1_EN_LEN) - 1) << SF_CTRL_SF_AES_R1_EN_POS) +#define SF_CTRL_SF_AES_R1_EN_UMSK (~(((1U << SF_CTRL_SF_AES_R1_EN_LEN) - 1) << SF_CTRL_SF_AES_R1_EN_POS)) +#define SF_CTRL_SF_AES_R1_LOCK SF_CTRL_SF_AES_R1_LOCK +#define SF_CTRL_SF_AES_R1_LOCK_POS (31U) +#define SF_CTRL_SF_AES_R1_LOCK_LEN (1U) +#define SF_CTRL_SF_AES_R1_LOCK_MSK (((1U << SF_CTRL_SF_AES_R1_LOCK_LEN) - 1) << SF_CTRL_SF_AES_R1_LOCK_POS) +#define SF_CTRL_SF_AES_R1_LOCK_UMSK (~(((1U << SF_CTRL_SF_AES_R1_LOCK_LEN) - 1) << SF_CTRL_SF_AES_R1_LOCK_POS)) + +/* 0x2B4 : sf_aes_r1_end */ +#define SF_CTRL_SF_AES_R1_END_OFFSET (0x2B4) +#define SF_CTRL_SF_AES_R1_END SF_CTRL_SF_AES_R1_END +#define SF_CTRL_SF_AES_R1_END_POS (0U) +#define SF_CTRL_SF_AES_R1_END_LEN (19U) +#define SF_CTRL_SF_AES_R1_END_MSK (((1U << SF_CTRL_SF_AES_R1_END_LEN) - 1) << SF_CTRL_SF_AES_R1_END_POS) +#define SF_CTRL_SF_AES_R1_END_UMSK (~(((1U << SF_CTRL_SF_AES_R1_END_LEN) - 1) << SF_CTRL_SF_AES_R1_END_POS)) + +/* 0x300 : sf_aes_key_r2_0 */ +#define SF_CTRL_SF_AES_KEY_R2_0_OFFSET (0x300) +#define SF_CTRL_SF_AES_KEY_R2_0 SF_CTRL_SF_AES_KEY_R2_0 +#define SF_CTRL_SF_AES_KEY_R2_0_POS (0U) +#define SF_CTRL_SF_AES_KEY_R2_0_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R2_0_MSK (((1U << SF_CTRL_SF_AES_KEY_R2_0_LEN) - 1) << SF_CTRL_SF_AES_KEY_R2_0_POS) +#define SF_CTRL_SF_AES_KEY_R2_0_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R2_0_LEN) - 1) << SF_CTRL_SF_AES_KEY_R2_0_POS)) + +/* 0x304 : sf_aes_key_r2_1 */ +#define SF_CTRL_SF_AES_KEY_R2_1_OFFSET (0x304) +#define SF_CTRL_SF_AES_KEY_R2_1 SF_CTRL_SF_AES_KEY_R2_1 +#define SF_CTRL_SF_AES_KEY_R2_1_POS (0U) +#define SF_CTRL_SF_AES_KEY_R2_1_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R2_1_MSK (((1U << SF_CTRL_SF_AES_KEY_R2_1_LEN) - 1) << SF_CTRL_SF_AES_KEY_R2_1_POS) +#define SF_CTRL_SF_AES_KEY_R2_1_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R2_1_LEN) - 1) << SF_CTRL_SF_AES_KEY_R2_1_POS)) + +/* 0x308 : sf_aes_key_r2_2 */ +#define SF_CTRL_SF_AES_KEY_R2_2_OFFSET (0x308) +#define SF_CTRL_SF_AES_KEY_R2_2 SF_CTRL_SF_AES_KEY_R2_2 +#define SF_CTRL_SF_AES_KEY_R2_2_POS (0U) +#define SF_CTRL_SF_AES_KEY_R2_2_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R2_2_MSK (((1U << SF_CTRL_SF_AES_KEY_R2_2_LEN) - 1) << SF_CTRL_SF_AES_KEY_R2_2_POS) +#define SF_CTRL_SF_AES_KEY_R2_2_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R2_2_LEN) - 1) << SF_CTRL_SF_AES_KEY_R2_2_POS)) + +/* 0x30C : sf_aes_key_r2_3 */ +#define SF_CTRL_SF_AES_KEY_R2_3_OFFSET (0x30C) +#define SF_CTRL_SF_AES_KEY_R2_3 SF_CTRL_SF_AES_KEY_R2_3 +#define SF_CTRL_SF_AES_KEY_R2_3_POS (0U) +#define SF_CTRL_SF_AES_KEY_R2_3_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R2_3_MSK (((1U << SF_CTRL_SF_AES_KEY_R2_3_LEN) - 1) << SF_CTRL_SF_AES_KEY_R2_3_POS) +#define SF_CTRL_SF_AES_KEY_R2_3_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R2_3_LEN) - 1) << SF_CTRL_SF_AES_KEY_R2_3_POS)) + +/* 0x310 : sf_aes_key_r2_4 */ +#define SF_CTRL_SF_AES_KEY_R2_4_OFFSET (0x310) +#define SF_CTRL_SF_AES_KEY_R2_4 SF_CTRL_SF_AES_KEY_R2_4 +#define SF_CTRL_SF_AES_KEY_R2_4_POS (0U) +#define SF_CTRL_SF_AES_KEY_R2_4_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R2_4_MSK (((1U << SF_CTRL_SF_AES_KEY_R2_4_LEN) - 1) << SF_CTRL_SF_AES_KEY_R2_4_POS) +#define SF_CTRL_SF_AES_KEY_R2_4_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R2_4_LEN) - 1) << SF_CTRL_SF_AES_KEY_R2_4_POS)) + +/* 0x314 : sf_aes_key_r2_5 */ +#define SF_CTRL_SF_AES_KEY_R2_5_OFFSET (0x314) +#define SF_CTRL_SF_AES_KEY_R2_5 SF_CTRL_SF_AES_KEY_R2_5 +#define SF_CTRL_SF_AES_KEY_R2_5_POS (0U) +#define SF_CTRL_SF_AES_KEY_R2_5_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R2_5_MSK (((1U << SF_CTRL_SF_AES_KEY_R2_5_LEN) - 1) << SF_CTRL_SF_AES_KEY_R2_5_POS) +#define SF_CTRL_SF_AES_KEY_R2_5_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R2_5_LEN) - 1) << SF_CTRL_SF_AES_KEY_R2_5_POS)) + +/* 0x318 : sf_aes_key_r2_6 */ +#define SF_CTRL_SF_AES_KEY_R2_6_OFFSET (0x318) +#define SF_CTRL_SF_AES_KEY_R2_6 SF_CTRL_SF_AES_KEY_R2_6 +#define SF_CTRL_SF_AES_KEY_R2_6_POS (0U) +#define SF_CTRL_SF_AES_KEY_R2_6_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R2_6_MSK (((1U << SF_CTRL_SF_AES_KEY_R2_6_LEN) - 1) << SF_CTRL_SF_AES_KEY_R2_6_POS) +#define SF_CTRL_SF_AES_KEY_R2_6_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R2_6_LEN) - 1) << SF_CTRL_SF_AES_KEY_R2_6_POS)) + +/* 0x31C : sf_aes_key_r2_7 */ +#define SF_CTRL_SF_AES_KEY_R2_7_OFFSET (0x31C) +#define SF_CTRL_SF_AES_KEY_R2_7 SF_CTRL_SF_AES_KEY_R2_7 +#define SF_CTRL_SF_AES_KEY_R2_7_POS (0U) +#define SF_CTRL_SF_AES_KEY_R2_7_LEN (32U) +#define SF_CTRL_SF_AES_KEY_R2_7_MSK (((1U << SF_CTRL_SF_AES_KEY_R2_7_LEN) - 1) << SF_CTRL_SF_AES_KEY_R2_7_POS) +#define SF_CTRL_SF_AES_KEY_R2_7_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_R2_7_LEN) - 1) << SF_CTRL_SF_AES_KEY_R2_7_POS)) + +/* 0x320 : sf_aes_iv_r2_w0 */ +#define SF_CTRL_SF_AES_IV_R2_W0_OFFSET (0x320) +#define SF_CTRL_SF_AES_IV_R2_W0 SF_CTRL_SF_AES_IV_R2_W0 +#define SF_CTRL_SF_AES_IV_R2_W0_POS (0U) +#define SF_CTRL_SF_AES_IV_R2_W0_LEN (32U) +#define SF_CTRL_SF_AES_IV_R2_W0_MSK (((1U << SF_CTRL_SF_AES_IV_R2_W0_LEN) - 1) << SF_CTRL_SF_AES_IV_R2_W0_POS) +#define SF_CTRL_SF_AES_IV_R2_W0_UMSK (~(((1U << SF_CTRL_SF_AES_IV_R2_W0_LEN) - 1) << SF_CTRL_SF_AES_IV_R2_W0_POS)) + +/* 0x324 : sf_aes_iv_r2_w1 */ +#define SF_CTRL_SF_AES_IV_R2_W1_OFFSET (0x324) +#define SF_CTRL_SF_AES_IV_R2_W1 SF_CTRL_SF_AES_IV_R2_W1 +#define SF_CTRL_SF_AES_IV_R2_W1_POS (0U) +#define SF_CTRL_SF_AES_IV_R2_W1_LEN (32U) +#define SF_CTRL_SF_AES_IV_R2_W1_MSK (((1U << SF_CTRL_SF_AES_IV_R2_W1_LEN) - 1) << SF_CTRL_SF_AES_IV_R2_W1_POS) +#define SF_CTRL_SF_AES_IV_R2_W1_UMSK (~(((1U << SF_CTRL_SF_AES_IV_R2_W1_LEN) - 1) << SF_CTRL_SF_AES_IV_R2_W1_POS)) + +/* 0x328 : sf_aes_iv_r2_w2 */ +#define SF_CTRL_SF_AES_IV_R2_W2_OFFSET (0x328) +#define SF_CTRL_SF_AES_IV_R2_W2 SF_CTRL_SF_AES_IV_R2_W2 +#define SF_CTRL_SF_AES_IV_R2_W2_POS (0U) +#define SF_CTRL_SF_AES_IV_R2_W2_LEN (32U) +#define SF_CTRL_SF_AES_IV_R2_W2_MSK (((1U << SF_CTRL_SF_AES_IV_R2_W2_LEN) - 1) << SF_CTRL_SF_AES_IV_R2_W2_POS) +#define SF_CTRL_SF_AES_IV_R2_W2_UMSK (~(((1U << SF_CTRL_SF_AES_IV_R2_W2_LEN) - 1) << SF_CTRL_SF_AES_IV_R2_W2_POS)) + +/* 0x32C : sf_aes_iv_r2_w3 */ +#define SF_CTRL_SF_AES_IV_R2_W3_OFFSET (0x32C) +#define SF_CTRL_SF_AES_IV_R2_W3 SF_CTRL_SF_AES_IV_R2_W3 +#define SF_CTRL_SF_AES_IV_R2_W3_POS (0U) +#define SF_CTRL_SF_AES_IV_R2_W3_LEN (32U) +#define SF_CTRL_SF_AES_IV_R2_W3_MSK (((1U << SF_CTRL_SF_AES_IV_R2_W3_LEN) - 1) << SF_CTRL_SF_AES_IV_R2_W3_POS) +#define SF_CTRL_SF_AES_IV_R2_W3_UMSK (~(((1U << SF_CTRL_SF_AES_IV_R2_W3_LEN) - 1) << SF_CTRL_SF_AES_IV_R2_W3_POS)) + +/* 0x330 : sf_aes_r2_start */ +#define SF_CTRL_SF_AES_R2_START_OFFSET (0x330) +#define SF_CTRL_SF_AES_R2_START SF_CTRL_SF_AES_R2_START +#define SF_CTRL_SF_AES_R2_START_POS (0U) +#define SF_CTRL_SF_AES_R2_START_LEN (19U) +#define SF_CTRL_SF_AES_R2_START_MSK (((1U << SF_CTRL_SF_AES_R2_START_LEN) - 1) << SF_CTRL_SF_AES_R2_START_POS) +#define SF_CTRL_SF_AES_R2_START_UMSK (~(((1U << SF_CTRL_SF_AES_R2_START_LEN) - 1) << SF_CTRL_SF_AES_R2_START_POS)) +#define SF_CTRL_SF_AES_R2_HW_KEY_EN SF_CTRL_SF_AES_R2_HW_KEY_EN +#define SF_CTRL_SF_AES_R2_HW_KEY_EN_POS (29U) +#define SF_CTRL_SF_AES_R2_HW_KEY_EN_LEN (1U) +#define SF_CTRL_SF_AES_R2_HW_KEY_EN_MSK (((1U << SF_CTRL_SF_AES_R2_HW_KEY_EN_LEN) - 1) << SF_CTRL_SF_AES_R2_HW_KEY_EN_POS) +#define SF_CTRL_SF_AES_R2_HW_KEY_EN_UMSK (~(((1U << SF_CTRL_SF_AES_R2_HW_KEY_EN_LEN) - 1) << SF_CTRL_SF_AES_R2_HW_KEY_EN_POS)) +#define SF_CTRL_SF_AES_R2_EN SF_CTRL_SF_AES_R2_EN +#define SF_CTRL_SF_AES_R2_EN_POS (30U) +#define SF_CTRL_SF_AES_R2_EN_LEN (1U) +#define SF_CTRL_SF_AES_R2_EN_MSK (((1U << SF_CTRL_SF_AES_R2_EN_LEN) - 1) << SF_CTRL_SF_AES_R2_EN_POS) +#define SF_CTRL_SF_AES_R2_EN_UMSK (~(((1U << SF_CTRL_SF_AES_R2_EN_LEN) - 1) << SF_CTRL_SF_AES_R2_EN_POS)) +#define SF_CTRL_SF_AES_R2_LOCK SF_CTRL_SF_AES_R2_LOCK +#define SF_CTRL_SF_AES_R2_LOCK_POS (31U) +#define SF_CTRL_SF_AES_R2_LOCK_LEN (1U) +#define SF_CTRL_SF_AES_R2_LOCK_MSK (((1U << SF_CTRL_SF_AES_R2_LOCK_LEN) - 1) << SF_CTRL_SF_AES_R2_LOCK_POS) +#define SF_CTRL_SF_AES_R2_LOCK_UMSK (~(((1U << SF_CTRL_SF_AES_R2_LOCK_LEN) - 1) << SF_CTRL_SF_AES_R2_LOCK_POS)) + +/* 0x334 : sf_aes_r2_end */ +#define SF_CTRL_SF_AES_R2_END_OFFSET (0x334) +#define SF_CTRL_SF_AES_R2_END SF_CTRL_SF_AES_R2_END +#define SF_CTRL_SF_AES_R2_END_POS (0U) +#define SF_CTRL_SF_AES_R2_END_LEN (19U) +#define SF_CTRL_SF_AES_R2_END_MSK (((1U << SF_CTRL_SF_AES_R2_END_LEN) - 1) << SF_CTRL_SF_AES_R2_END_POS) +#define SF_CTRL_SF_AES_R2_END_UMSK (~(((1U << SF_CTRL_SF_AES_R2_END_LEN) - 1) << SF_CTRL_SF_AES_R2_END_POS)) + +struct sf_ctrl_reg { + /* 0x0 : sf_ctrl_0 */ + union { + struct { + uint32_t reserved_0_1 : 2; /* [ 1: 0], rsvd, 0x0 */ + uint32_t sf_clk_sf_rx_inv_sel : 1; /* [ 2], r/w, 0x1 */ + uint32_t sf_clk_out_gate_en : 1; /* [ 3], r/w, 0x1 */ + uint32_t sf_clk_out_inv_sel : 1; /* [ 4], r/w, 0x1 */ + uint32_t reserved_5_7 : 3; /* [ 7: 5], rsvd, 0x0 */ + uint32_t sf_if_read_dly_n : 3; /* [10: 8], r/w, 0x0 */ + uint32_t sf_if_read_dly_en : 1; /* [ 11], r/w, 0x0 */ + uint32_t reserved_12_15 : 4; /* [15:12], rsvd, 0x0 */ + uint32_t sf_if_int : 1; /* [ 16], r, 0x0 */ + uint32_t sf_if_int_clr : 1; /* [ 17], r/w, 0x1 */ + uint32_t sf_if_int_set : 1; /* [ 18], r/w, 0x0 */ + uint32_t sf_if_32b_adr_en : 1; /* [ 19], r/w, 0x0 */ + uint32_t sf_aes_dout_endian : 1; /* [ 20], r/w, 0x1 */ + uint32_t sf_aes_din_endian : 1; /* [ 21], r/w, 0x1 */ + uint32_t sf_aes_key_endian : 1; /* [ 22], r/w, 0x1 */ + uint32_t sf_aes_iv_endian : 1; /* [ 23], r/w, 0x1 */ + uint32_t sf_id : 8; /* [31:24], r/w, 0x1a */ + } BF; + uint32_t WORD; + } sf_ctrl_0; + + /* 0x4 : sf_ctrl_1 */ + union { + struct { + uint32_t sf_if_sr_pat_mask : 8; /* [ 7: 0], r/w, 0x0 */ + uint32_t sf_if_sr_pat : 8; /* [15: 8], r/w, 0x0 */ + uint32_t sf_if_sr_int : 1; /* [ 16], r, 0x0 */ + uint32_t sf_if_sr_int_en : 1; /* [ 17], r/w, 0x0 */ + uint32_t sf_if_sr_int_set : 1; /* [ 18], r/w, 0x0 */ + uint32_t reserved_19 : 1; /* [ 19], rsvd, 0x0 */ + uint32_t sf_if_0_ack_lat : 3; /* [22:20], r/w, 0x6 */ + uint32_t sf_ahb2sif_diswrap : 1; /* [ 23], r/w, 0x0 */ + uint32_t sf_if_reg_hold : 1; /* [ 24], r/w, 0x1 */ + uint32_t sf_if_reg_wp : 1; /* [ 25], r/w, 0x1 */ + uint32_t sf_ahb2sif_stopped : 1; /* [ 26], r, 0x0 */ + uint32_t sf_ahb2sif_stop : 1; /* [ 27], r/w, 0x0 */ + uint32_t sf_if_fn_sel : 1; /* [ 28], r/w, 0x1 */ + uint32_t sf_if_en : 1; /* [ 29], r/w, 0x1 */ + uint32_t sf_ahb2sif_en : 1; /* [ 30], r/w, 0x1 */ + uint32_t sf_ahb2sram_en : 1; /* [ 31], r/w, 0x1 */ + } BF; + uint32_t WORD; + } sf_ctrl_1; + + /* 0x8 : sf_if_sahb_0 */ + union { + struct { + uint32_t sf_if_busy : 1; /* [ 0], r, 0x0 */ + uint32_t sf_if_0_trig : 1; /* [ 1], r/w, 0x0 */ + uint32_t sf_if_0_dat_byte : 10; /* [11: 2], r/w, 0xff */ + uint32_t sf_if_0_dmy_byte : 5; /* [16:12], r/w, 0x0 */ + uint32_t sf_if_0_adr_byte : 3; /* [19:17], r/w, 0x2 */ + uint32_t sf_if_0_cmd_byte : 3; /* [22:20], r/w, 0x0 */ + uint32_t sf_if_0_dat_rw : 1; /* [ 23], r/w, 0x0 */ + uint32_t sf_if_0_dat_en : 1; /* [ 24], r/w, 0x1 */ + uint32_t sf_if_0_dmy_en : 1; /* [ 25], r/w, 0x0 */ + uint32_t sf_if_0_adr_en : 1; /* [ 26], r/w, 0x1 */ + uint32_t sf_if_0_cmd_en : 1; /* [ 27], r/w, 0x1 */ + uint32_t sf_if_0_spi_mode : 3; /* [30:28], r/w, 0x0 */ + uint32_t sf_if_0_qpi_mode_en : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_if_sahb_0; + + /* 0xC : sf_if_sahb_1 */ + union { + struct { + uint32_t sf_if_0_cmd_buf_0 : 32; /* [31: 0], r/w, 0x3000000 */ + } BF; + uint32_t WORD; + } sf_if_sahb_1; + + /* 0x10 : sf_if_sahb_2 */ + union { + struct { + uint32_t sf_if_0_cmd_buf_1 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_if_sahb_2; + + /* 0x14 : sf_if_iahb_0 */ + union { + struct { + uint32_t reserved_0_11 : 12; /* [11: 0], rsvd, 0x0 */ + uint32_t sf_if_1_dmy_byte : 5; /* [16:12], r/w, 0x0 */ + uint32_t sf_if_1_adr_byte : 3; /* [19:17], r/w, 0x2 */ + uint32_t sf_if_1_cmd_byte : 3; /* [22:20], r/w, 0x0 */ + uint32_t sf_if_1_dat_rw : 1; /* [ 23], r/w, 0x0 */ + uint32_t sf_if_1_dat_en : 1; /* [ 24], r/w, 0x1 */ + uint32_t sf_if_1_dmy_en : 1; /* [ 25], r/w, 0x0 */ + uint32_t sf_if_1_adr_en : 1; /* [ 26], r/w, 0x1 */ + uint32_t sf_if_1_cmd_en : 1; /* [ 27], r/w, 0x1 */ + uint32_t sf_if_1_spi_mode : 3; /* [30:28], r/w, 0x0 */ + uint32_t sf_if_1_qpi_mode_en : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_if_iahb_0; + + /* 0x18 : sf_if_iahb_1 */ + union { + struct { + uint32_t sf_if_1_cmd_buf_0 : 32; /* [31: 0], r/w, 0x3000000 */ + } BF; + uint32_t WORD; + } sf_if_iahb_1; + + /* 0x1C : sf_if_iahb_2 */ + union { + struct { + uint32_t sf_if_1_cmd_buf_1 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_if_iahb_2; + + /* 0x20 : sf_if_status_0 */ + union { + struct { + uint32_t sf_if_status_0 : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } sf_if_status_0; + + /* 0x24 : sf_if_status_1 */ + union { + struct { + uint32_t sf_if_status_1 : 32; /* [31: 0], r, 0x20000000 */ + } BF; + uint32_t WORD; + } sf_if_status_1; + + /* 0x28 : sf_aes */ + union { + struct { + uint32_t sf_aes_en : 1; /* [ 0], r/w, 0x0 */ + uint32_t sf_aes_mode : 2; /* [ 2: 1], r/w, 0x0 */ + uint32_t sf_aes_blk_mode : 1; /* [ 3], r/w, 0x0 */ + uint32_t sf_aes_xts_key_opt : 1; /* [ 4], r/w, 0x0 */ + uint32_t sf_aes_status : 27; /* [31: 5], r, 0x2 */ + } BF; + uint32_t WORD; + } sf_aes; + + /* 0x2C : sf_ahb2sif_status */ + union { + struct { + uint32_t sf_ahb2sif_status : 32; /* [31: 0], r, 0x1010003 */ + } BF; + uint32_t WORD; + } sf_ahb2sif_status; + + /* 0x30 : sf_if_io_dly_0 */ + union { + struct { + uint32_t sf_cs_dly_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t sf_cs2_dly_sel : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reserved_4_7 : 4; /* [ 7: 4], rsvd, 0x0 */ + uint32_t sf_clk_out_dly_sel : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reserved_10_25 : 16; /* [25:10], rsvd, 0x0 */ + uint32_t sf_dqs_oe_dly_sel : 2; /* [27:26], r/w, 0x0 */ + uint32_t sf_dqs_di_dly_sel : 2; /* [29:28], r/w, 0x0 */ + uint32_t sf_dqs_do_dly_sel : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_if_io_dly_0; + + /* 0x34 : sf_if_io_dly_1 */ + union { + struct { + uint32_t sf_io_0_oe_dly_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t sf_io_0_di_dly_sel : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t sf_io_0_do_dly_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_31 : 14; /* [31:18], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf_if_io_dly_1; + + /* 0x38 : sf_if_io_dly_2 */ + union { + struct { + uint32_t sf_io_1_oe_dly_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t sf_io_1_di_dly_sel : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t sf_io_1_do_dly_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_31 : 14; /* [31:18], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf_if_io_dly_2; + + /* 0x3C : sf_if_io_dly_3 */ + union { + struct { + uint32_t sf_io_2_oe_dly_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t sf_io_2_di_dly_sel : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t sf_io_2_do_dly_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_31 : 14; /* [31:18], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf_if_io_dly_3; + + /* 0x40 : sf_if_io_dly_4 */ + union { + struct { + uint32_t sf_io_3_oe_dly_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t sf_io_3_di_dly_sel : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t sf_io_3_do_dly_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_31 : 14; /* [31:18], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf_if_io_dly_4; + + /* 0x44 : sf_reserved */ + union { + struct { + uint32_t sf_reserved : 32; /* [31: 0], r/w, 0xffff */ + } BF; + uint32_t WORD; + } sf_reserved; + + /* 0x48 : sf2_if_io_dly_0 */ + union { + struct { + uint32_t sf2_cs_dly_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t sf2_cs2_dly_sel : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reserved_4_7 : 4; /* [ 7: 4], rsvd, 0x0 */ + uint32_t sf2_clk_out_dly_sel : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reserved_10_25 : 16; /* [25:10], rsvd, 0x0 */ + uint32_t sf2_dqs_oe_dly_sel : 2; /* [27:26], r/w, 0x0 */ + uint32_t sf2_dqs_di_dly_sel : 2; /* [29:28], r/w, 0x0 */ + uint32_t sf2_dqs_do_dly_sel : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf2_if_io_dly_0; + + /* 0x4C : sf2_if_io_dly_1 */ + union { + struct { + uint32_t sf2_io_0_oe_dly_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t sf2_io_0_di_dly_sel : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t sf2_io_0_do_dly_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_31 : 14; /* [31:18], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf2_if_io_dly_1; + + /* 0x50 : sf2_if_io_dly_2 */ + union { + struct { + uint32_t sf2_io_1_oe_dly_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t sf2_io_1_di_dly_sel : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t sf2_io_1_do_dly_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_31 : 14; /* [31:18], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf2_if_io_dly_2; + + /* 0x54 : sf2_if_io_dly_3 */ + union { + struct { + uint32_t sf2_io_2_oe_dly_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t sf2_io_2_di_dly_sel : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t sf2_io_2_do_dly_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_31 : 14; /* [31:18], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf2_if_io_dly_3; + + /* 0x58 : sf2_if_io_dly_4 */ + union { + struct { + uint32_t sf2_io_3_oe_dly_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t sf2_io_3_di_dly_sel : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t sf2_io_3_do_dly_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_31 : 14; /* [31:18], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf2_if_io_dly_4; + + /* 0x5C : sf3_if_io_dly_0 */ + union { + struct { + uint32_t sf3_cs_dly_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t sf3_cs2_dly_sel : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reserved_4_7 : 4; /* [ 7: 4], rsvd, 0x0 */ + uint32_t sf3_clk_out_dly_sel : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reserved_10_25 : 16; /* [25:10], rsvd, 0x0 */ + uint32_t sf3_dqs_oe_dly_sel : 2; /* [27:26], r/w, 0x0 */ + uint32_t sf3_dqs_di_dly_sel : 2; /* [29:28], r/w, 0x0 */ + uint32_t sf3_dqs_do_dly_sel : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf3_if_io_dly_0; + + /* 0x60 : sf3_if_io_dly_1 */ + union { + struct { + uint32_t sf3_io_0_oe_dly_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t sf3_io_0_di_dly_sel : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t sf3_io_0_do_dly_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_31 : 14; /* [31:18], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf3_if_io_dly_1; + + /* 0x64 : sf3_if_io_dly_2 */ + union { + struct { + uint32_t sf3_io_1_oe_dly_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t sf3_io_1_di_dly_sel : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t sf3_io_1_do_dly_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_31 : 14; /* [31:18], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf3_if_io_dly_2; + + /* 0x68 : sf3_if_io_dly_3 */ + union { + struct { + uint32_t sf3_io_2_oe_dly_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t sf3_io_2_di_dly_sel : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t sf3_io_2_do_dly_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_31 : 14; /* [31:18], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf3_if_io_dly_3; + + /* 0x6C : sf3_if_io_dly_4 */ + union { + struct { + uint32_t sf3_io_3_oe_dly_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t sf3_io_3_di_dly_sel : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t sf3_io_3_do_dly_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_31 : 14; /* [31:18], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf3_if_io_dly_4; + + /* 0x70 : sf_ctrl_2 */ + union { + struct { + uint32_t sf_if_pad_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2 : 1; /* [ 2], rsvd, 0x0 */ + uint32_t sf_if_pad_sel_lock : 1; /* [ 3], r/w, 0x0 */ + uint32_t sf_if_dtr_en : 1; /* [ 4], r/w, 0x0 */ + uint32_t sf_if_dqs_en : 1; /* [ 5], r/w, 0x0 */ + uint32_t sf_if_trig_wr_prot : 1; /* [ 6], r/w, 0x0 */ + uint32_t sf_id_offset_lock : 1; /* [ 7], r/w, 0x0 */ + uint32_t reserved_8_24 : 17; /* [24: 8], rsvd, 0x0 */ + uint32_t sf_ahb2sif_remap_lock : 1; /* [ 25], r/w, 0x0 */ + uint32_t sf_ahb2sif_remap : 2; /* [27:26], r/w, 0x0 */ + uint32_t sf_if_bk_swap : 1; /* [ 28], r/w, 0x0 */ + uint32_t sf_if_bk2_mode : 1; /* [ 29], r/w, 0x0 */ + uint32_t sf_if_bk2_en : 1; /* [ 30], r/w, 0x0 */ + uint32_t sf_if_0_bk_sel : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_ctrl_2; + + /* 0x74 : sf_ctrl_3 */ + union { + struct { + uint32_t sf_cmds_2_wrap_len : 4; /* [ 3: 0], r/w, 0x6 */ + uint32_t sf_cmds_2_en : 1; /* [ 4], r/w, 0x1 */ + uint32_t sf_cmds_2_bt_dly : 3; /* [ 7: 5], r/w, 0x2 */ + uint32_t sf_cmds_2_bt_en : 1; /* [ 8], r/w, 0x1 */ + uint32_t sf_cmds_2_wrap_q_ini : 1; /* [ 9], r/w, 0x0 */ + uint32_t sf_cmds_2_wrap_mode : 2; /* [11:10], r/w, 0x0 */ + uint32_t sf_cmds_2_wrap_q : 1; /* [ 12], r, 0x0 */ + uint32_t sf_cmds_1_wrap_len : 4; /* [16:13], r/w, 0x6 */ + uint32_t sf_cmds_1_en : 1; /* [ 17], r/w, 0x0 */ + uint32_t sf_cmds_1_wrap_mode : 2; /* [19:18], r/w, 0x0 */ + uint32_t sf_cmds_core_en : 1; /* [ 20], r/w, 0x1 */ + uint32_t reserved_21_28 : 8; /* [28:21], rsvd, 0x0 */ + uint32_t sf_if_1_ack_lat : 3; /* [31:29], r/w, 0x1 */ + } BF; + uint32_t WORD; + } sf_ctrl_3; + + /* 0x78 : sf_if_iahb_3 */ + union { + struct { + uint32_t reserved_0_11 : 12; /* [11: 0], rsvd, 0x0 */ + uint32_t sf_if_2_dmy_byte : 5; /* [16:12], r/w, 0x0 */ + uint32_t sf_if_2_adr_byte : 3; /* [19:17], r/w, 0x2 */ + uint32_t sf_if_2_cmd_byte : 3; /* [22:20], r/w, 0x0 */ + uint32_t sf_if_2_dat_rw : 1; /* [ 23], r/w, 0x1 */ + uint32_t sf_if_2_dat_en : 1; /* [ 24], r/w, 0x1 */ + uint32_t sf_if_2_dmy_en : 1; /* [ 25], r/w, 0x0 */ + uint32_t sf_if_2_adr_en : 1; /* [ 26], r/w, 0x1 */ + uint32_t sf_if_2_cmd_en : 1; /* [ 27], r/w, 0x1 */ + uint32_t sf_if_2_spi_mode : 3; /* [30:28], r/w, 0x0 */ + uint32_t sf_if_2_qpi_mode_en : 1; /* [ 31], r/w, 0x1 */ + } BF; + uint32_t WORD; + } sf_if_iahb_3; + + /* 0x7C : sf_if_iahb_4 */ + union { + struct { + uint32_t sf_if_2_cmd_buf_0 : 32; /* [31: 0], r/w, 0x38000000 */ + } BF; + uint32_t WORD; + } sf_if_iahb_4; + + /* 0x80 : sf_if_iahb_5 */ + union { + struct { + uint32_t sf_if_2_cmd_buf_1 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_if_iahb_5; + + /* 0x84 : sf_if_iahb_6 */ + union { + struct { + uint32_t reserved_0_16 : 17; /* [16: 0], rsvd, 0x0 */ + uint32_t sf_if_3_adr_byte : 3; /* [19:17], r/w, 0x0 */ + uint32_t sf_if_3_cmd_byte : 3; /* [22:20], r/w, 0x0 */ + uint32_t reserved_23_25 : 3; /* [25:23], rsvd, 0x0 */ + uint32_t sf_if_3_adr_en : 1; /* [ 26], r/w, 0x0 */ + uint32_t sf_if_3_cmd_en : 1; /* [ 27], r/w, 0x1 */ + uint32_t sf_if_3_spi_mode : 3; /* [30:28], r/w, 0x0 */ + uint32_t sf_if_3_qpi_mode_en : 1; /* [ 31], r/w, 0x1 */ + } BF; + uint32_t WORD; + } sf_if_iahb_6; + + /* 0x88 : sf_if_iahb_7 */ + union { + struct { + uint32_t sf_if_3_cmd_buf_0 : 32; /* [31: 0], r/w, 0xc0000000L */ + } BF; + uint32_t WORD; + } sf_if_iahb_7; + + /* 0x8C : sf_if_iahb_8 */ + union { + struct { + uint32_t sf_if_3_cmd_buf_1 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_if_iahb_8; + + /* 0x90 : sf_if_iahb_9 */ + union { + struct { + uint32_t reserved_0_11 : 12; /* [11: 0], rsvd, 0x0 */ + uint32_t sf_if_4_dmy_byte : 5; /* [16:12], r/w, 0x2 */ + uint32_t sf_if_4_adr_byte : 3; /* [19:17], r/w, 0x2 */ + uint32_t sf_if_4_cmd_byte : 3; /* [22:20], r/w, 0x0 */ + uint32_t sf_if_4_dat_rw : 1; /* [ 23], r/w, 0x0 */ + uint32_t sf_if_4_dat_en : 1; /* [ 24], r/w, 0x1 */ + uint32_t sf_if_4_dmy_en : 1; /* [ 25], r/w, 0x1 */ + uint32_t sf_if_4_adr_en : 1; /* [ 26], r/w, 0x1 */ + uint32_t sf_if_4_cmd_en : 1; /* [ 27], r/w, 0x1 */ + uint32_t sf_if_4_spi_mode : 3; /* [30:28], r/w, 0x0 */ + uint32_t sf_if_4_qpi_mode_en : 1; /* [ 31], r/w, 0x1 */ + } BF; + uint32_t WORD; + } sf_if_iahb_9; + + /* 0x94 : sf_if_iahb_10 */ + union { + struct { + uint32_t sf_if_4_cmd_buf_0 : 32; /* [31: 0], r/w, 0xeb000000L */ + } BF; + uint32_t WORD; + } sf_if_iahb_10; + + /* 0x98 : sf_if_iahb_11 */ + union { + struct { + uint32_t sf_if_4_cmd_buf_1 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_if_iahb_11; + + /* 0x9C : sf_if_iahb_12 */ + union { + struct { + uint32_t reserved_0_1 : 2; /* [ 1: 0], rsvd, 0x0 */ + uint32_t sf2_clk_sf_rx_inv_sel : 1; /* [ 2], r/w, 0x0 */ + uint32_t sf2_clk_sf_rx_inv_src : 1; /* [ 3], r/w, 0x0 */ + uint32_t sf2_clk_out_inv_sel : 1; /* [ 4], r/w, 0x1 */ + uint32_t sf3_clk_out_inv_sel : 1; /* [ 5], r/w, 0x1 */ + uint32_t reserved_6_7 : 2; /* [ 7: 6], rsvd, 0x0 */ + uint32_t sf2_if_read_dly_n : 3; /* [10: 8], r/w, 0x0 */ + uint32_t sf2_if_read_dly_en : 1; /* [ 11], r/w, 0x0 */ + uint32_t sf2_if_read_dly_src : 1; /* [ 12], r/w, 0x0 */ + uint32_t reserved_13_31 : 19; /* [31:13], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf_if_iahb_12; + + /* 0xA0 : sf_id0_offset */ + union { + struct { + uint32_t sf_id0_offset : 28; /* [27: 0], r/w, 0x0 */ + uint32_t reserved_28_31 : 4; /* [31:28], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf_id0_offset; + + /* 0xA4 : sf_id1_offset */ + union { + struct { + uint32_t sf_id1_offset : 28; /* [27: 0], r/w, 0x0 */ + uint32_t reserved_28_31 : 4; /* [31:28], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf_id1_offset; + + /* 0xA8 : sf_bk2_id0_offset */ + union { + struct { + uint32_t sf_bk2_id0_offset : 28; /* [27: 0], r/w, 0x0 */ + uint32_t reserved_28_31 : 4; /* [31:28], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf_bk2_id0_offset; + + /* 0xAC : sf_bk2_id1_offset */ + union { + struct { + uint32_t sf_bk2_id1_offset : 28; /* [27: 0], r/w, 0x0 */ + uint32_t reserved_28_31 : 4; /* [31:28], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf_bk2_id1_offset; + + /* 0xB0 : sf_dbg */ + union { + struct { + uint32_t sf_autoload_st : 5; /* [ 4: 0], r, 0x1 */ + uint32_t sf_autoload_st_done : 1; /* [ 5], r, 0x0 */ + uint32_t reserved_6_31 : 26; /* [31: 6], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf_dbg; + + /* 0xb4 reserved */ + uint8_t RESERVED0xb4[12]; + + /* 0xC0 : sf_if2_ctrl_0 */ + union { + struct { + uint32_t reserved_0_1 : 2; /* [ 1: 0], rsvd, 0x0 */ + uint32_t sf_clk_sf_if2_rx_inv_sel : 1; /* [ 2], r/w, 0x1 */ + uint32_t reserved_3_7 : 5; /* [ 7: 3], rsvd, 0x0 */ + uint32_t sf_if2_read_dly_n : 3; /* [10: 8], r/w, 0x0 */ + uint32_t sf_if2_read_dly_en : 1; /* [ 11], r/w, 0x0 */ + uint32_t reserved_12_15 : 4; /* [15:12], rsvd, 0x0 */ + uint32_t sf_if2_int : 1; /* [ 16], r, 0x0 */ + uint32_t sf_if2_int_clr : 1; /* [ 17], r/w, 0x1 */ + uint32_t sf_if2_int_set : 1; /* [ 18], r/w, 0x0 */ + uint32_t reserved_19_22 : 4; /* [22:19], rsvd, 0x0 */ + uint32_t sf_if2_replace_sf1 : 1; /* [ 23], r/w, 0x0 */ + uint32_t sf_if2_replace_sf2 : 1; /* [ 24], r/w, 0x0 */ + uint32_t sf_if2_replace_sf3 : 1; /* [ 25], r/w, 0x0 */ + uint32_t sf_if2_pad_sel : 2; /* [27:26], r/w, 0x0 */ + uint32_t sf_if2_bk_swap : 1; /* [ 28], r/w, 0x0 */ + uint32_t sf_if2_bk2_mode : 1; /* [ 29], r/w, 0x0 */ + uint32_t sf_if2_bk2_en : 1; /* [ 30], r/w, 0x0 */ + uint32_t sf_if2_bk_sel : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_if2_ctrl_0; + + /* 0xC4 : sf_if2_ctrl_1 */ + union { + struct { + uint32_t sf_if2_sr_pat_mask : 8; /* [ 7: 0], r/w, 0x0 */ + uint32_t sf_if2_sr_pat : 8; /* [15: 8], r/w, 0x0 */ + uint32_t sf_if2_sr_int : 1; /* [ 16], r, 0x0 */ + uint32_t sf_if2_sr_int_en : 1; /* [ 17], r/w, 0x0 */ + uint32_t sf_if2_sr_int_set : 1; /* [ 18], r/w, 0x0 */ + uint32_t reserved_19 : 1; /* [ 19], rsvd, 0x0 */ + uint32_t sf_if2_ack_lat : 3; /* [22:20], r/w, 0x6 */ + uint32_t reserved_23 : 1; /* [ 23], rsvd, 0x0 */ + uint32_t sf_if2_reg_hold : 1; /* [ 24], r/w, 0x1 */ + uint32_t sf_if2_reg_wp : 1; /* [ 25], r/w, 0x1 */ + uint32_t reserved_26_27 : 2; /* [27:26], rsvd, 0x0 */ + uint32_t sf_if2_fn_sel : 1; /* [ 28], r/w, 0x0 */ + uint32_t sf_if2_en : 1; /* [ 29], r/w, 0x1 */ + uint32_t reserved_30_31 : 2; /* [31:30], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf_if2_ctrl_1; + + /* 0xC8 : sf_if2_sahb_0 */ + union { + struct { + uint32_t sf_if2_busy : 1; /* [ 0], r, 0x0 */ + uint32_t sf_if2_0_trig : 1; /* [ 1], r/w, 0x0 */ + uint32_t sf_if2_0_dat_byte : 10; /* [11: 2], r/w, 0xff */ + uint32_t sf_if2_0_dmy_byte : 5; /* [16:12], r/w, 0x0 */ + uint32_t sf_if2_0_adr_byte : 3; /* [19:17], r/w, 0x2 */ + uint32_t sf_if2_0_cmd_byte : 3; /* [22:20], r/w, 0x0 */ + uint32_t sf_if2_0_dat_rw : 1; /* [ 23], r/w, 0x0 */ + uint32_t sf_if2_0_dat_en : 1; /* [ 24], r/w, 0x1 */ + uint32_t sf_if2_0_dmy_en : 1; /* [ 25], r/w, 0x0 */ + uint32_t sf_if2_0_adr_en : 1; /* [ 26], r/w, 0x1 */ + uint32_t sf_if2_0_cmd_en : 1; /* [ 27], r/w, 0x1 */ + uint32_t sf_if2_0_spi_mode : 3; /* [30:28], r/w, 0x0 */ + uint32_t sf_if2_0_qpi_mode_en : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_if2_sahb_0; + + /* 0xCC : sf_if2_sahb_1 */ + union { + struct { + uint32_t sf_if2_0_cmd_buf_0 : 32; /* [31: 0], r/w, 0x3000000 */ + } BF; + uint32_t WORD; + } sf_if2_sahb_1; + + /* 0xD0 : sf_if2_sahb_2 */ + union { + struct { + uint32_t sf_if2_0_cmd_buf_1 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_if2_sahb_2; + + /* 0xd4 reserved */ + uint8_t RESERVED0xd4[44]; + + /* 0x100 : sf_ctrl_prot_en_rd */ + union { + struct { + uint32_t reserved_0 : 1; /* [ 0], rsvd, 0x0 */ + uint32_t sf_ctrl_id0_en_rd : 1; /* [ 1], r, 0x1 */ + uint32_t sf_ctrl_id1_en_rd : 1; /* [ 2], r, 0x1 */ + uint32_t reserved_3_27 : 25; /* [27: 3], rsvd, 0x0 */ + uint32_t sf_sec_tzsid_lock : 1; /* [ 28], r, 0x0 */ + uint32_t sf_if2_0_trig_wr_lock : 1; /* [ 29], r, 0x0 */ + uint32_t sf_if_0_trig_wr_lock : 1; /* [ 30], r, 0x0 */ + uint32_t sf_dbg_dis : 1; /* [ 31], r, 0x0 */ + } BF; + uint32_t WORD; + } sf_ctrl_prot_en_rd; + + /* 0x104 : sf_ctrl_prot_en */ + union { + struct { + uint32_t reserved_0 : 1; /* [ 0], rsvd, 0x0 */ + uint32_t sf_ctrl_id0_en : 1; /* [ 1], r/w, 0x1 */ + uint32_t sf_ctrl_id1_en : 1; /* [ 2], r/w, 0x1 */ + uint32_t reserved_3_31 : 29; /* [31: 3], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf_ctrl_prot_en; + + /* 0x108 reserved */ + uint8_t RESERVED0x108[248]; + + /* 0x200 : sf_aes_key_r0_0 */ + union { + struct { + uint32_t sf_aes_key_r0_0 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r0_0; + + /* 0x204 : sf_aes_key_r0_1 */ + union { + struct { + uint32_t sf_aes_key_r0_1 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r0_1; + + /* 0x208 : sf_aes_key_r0_2 */ + union { + struct { + uint32_t sf_aes_key_r0_2 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r0_2; + + /* 0x20C : sf_aes_key_r0_3 */ + union { + struct { + uint32_t sf_aes_key_r0_3 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r0_3; + + /* 0x210 : sf_aes_key_r0_4 */ + union { + struct { + uint32_t sf_aes_key_r0_4 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r0_4; + + /* 0x214 : sf_aes_key_r0_5 */ + union { + struct { + uint32_t sf_aes_key_r0_5 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r0_5; + + /* 0x218 : sf_aes_key_r0_6 */ + union { + struct { + uint32_t sf_aes_key_r0_6 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r0_6; + + /* 0x21C : sf_aes_key_r0_7 */ + union { + struct { + uint32_t sf_aes_key_r0_7 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r0_7; + + /* 0x220 : sf_aes_iv_r0_w0 */ + union { + struct { + uint32_t sf_aes_iv_r0_w0 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_iv_r0_w0; + + /* 0x224 : sf_aes_iv_r0_w1 */ + union { + struct { + uint32_t sf_aes_iv_r0_w1 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_iv_r0_w1; + + /* 0x228 : sf_aes_iv_r0_w2 */ + union { + struct { + uint32_t sf_aes_iv_r0_w2 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_iv_r0_w2; + + /* 0x22C : sf_aes_iv_r0_w3 */ + union { + struct { + uint32_t sf_aes_iv_r0_w3 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_iv_r0_w3; + + /* 0x230 : sf_aes_r0_start */ + union { + struct { + uint32_t sf_aes_region_r0_start : 19; /* [18: 0], r/w, 0x0 */ + uint32_t reserved_19_28 : 10; /* [28:19], rsvd, 0x0 */ + uint32_t sf_aes_region_r0_hw_key_en : 1; /* [ 29], r/w, 0x0 */ + uint32_t sf_aes_region_r0_en : 1; /* [ 30], r/w, 0x0 */ + uint32_t sf_aes_region_r0_lock : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_r0_start; + + /* 0x234 : sf_aes_r0_end */ + union { + struct { + uint32_t sf_aes_region_r0_end : 19; /* [18: 0], r/w, 0x3fff */ + uint32_t reserved_19_31 : 13; /* [31:19], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_r0_end; + + /* 0x238 reserved */ + uint8_t RESERVED0x238[72]; + + /* 0x280 : sf_aes_key_r1_0 */ + union { + struct { + uint32_t sf_aes_key_r1_0 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r1_0; + + /* 0x284 : sf_aes_key_r1_1 */ + union { + struct { + uint32_t sf_aes_key_r1_1 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r1_1; + + /* 0x288 : sf_aes_key_r1_2 */ + union { + struct { + uint32_t sf_aes_key_r1_2 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r1_2; + + /* 0x28C : sf_aes_key_r1_3 */ + union { + struct { + uint32_t sf_aes_key_r1_3 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r1_3; + + /* 0x290 : sf_aes_key_r1_4 */ + union { + struct { + uint32_t sf_aes_key_r1_4 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r1_4; + + /* 0x294 : sf_aes_key_r1_5 */ + union { + struct { + uint32_t sf_aes_key_r1_5 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r1_5; + + /* 0x298 : sf_aes_key_r1_6 */ + union { + struct { + uint32_t sf_aes_key_r1_6 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r1_6; + + /* 0x29C : sf_aes_key_r1_7 */ + union { + struct { + uint32_t sf_aes_key_r1_7 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r1_7; + + /* 0x2A0 : sf_aes_iv_r1_w0 */ + union { + struct { + uint32_t sf_aes_iv_r1_w0 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_iv_r1_w0; + + /* 0x2A4 : sf_aes_iv_r1_w1 */ + union { + struct { + uint32_t sf_aes_iv_r1_w1 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_iv_r1_w1; + + /* 0x2A8 : sf_aes_iv_r1_w2 */ + union { + struct { + uint32_t sf_aes_iv_r1_w2 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_iv_r1_w2; + + /* 0x2AC : sf_aes_iv_r1_w3 */ + union { + struct { + uint32_t sf_aes_iv_r1_w3 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_iv_r1_w3; + + /* 0x2B0 : sf_aes_r1_start */ + union { + struct { + uint32_t sf_aes_r1_start : 19; /* [18: 0], r/w, 0x0 */ + uint32_t reserved_19_28 : 10; /* [28:19], rsvd, 0x0 */ + uint32_t sf_aes_r1_hw_key_en : 1; /* [ 29], r/w, 0x0 */ + uint32_t sf_aes_r1_en : 1; /* [ 30], r/w, 0x0 */ + uint32_t sf_aes_r1_lock : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_r1_start; + + /* 0x2B4 : sf_aes_r1_end */ + union { + struct { + uint32_t sf_aes_r1_end : 19; /* [18: 0], r/w, 0x3fff */ + uint32_t reserved_19_31 : 13; /* [31:19], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_r1_end; + + /* 0x2b8 reserved */ + uint8_t RESERVED0x2b8[72]; + + /* 0x300 : sf_aes_key_r2_0 */ + union { + struct { + uint32_t sf_aes_key_r2_0 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r2_0; + + /* 0x304 : sf_aes_key_r2_1 */ + union { + struct { + uint32_t sf_aes_key_r2_1 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r2_1; + + /* 0x308 : sf_aes_key_r2_2 */ + union { + struct { + uint32_t sf_aes_key_r2_2 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r2_2; + + /* 0x30C : sf_aes_key_r2_3 */ + union { + struct { + uint32_t sf_aes_key_r2_3 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r2_3; + + /* 0x310 : sf_aes_key_r2_4 */ + union { + struct { + uint32_t sf_aes_key_r2_4 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r2_4; + + /* 0x314 : sf_aes_key_r2_5 */ + union { + struct { + uint32_t sf_aes_key_r2_5 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r2_5; + + /* 0x318 : sf_aes_key_r2_6 */ + union { + struct { + uint32_t sf_aes_key_r2_6 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r2_6; + + /* 0x31C : sf_aes_key_r2_7 */ + union { + struct { + uint32_t sf_aes_key_r2_7 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_r2_7; + + /* 0x320 : sf_aes_iv_r2_w0 */ + union { + struct { + uint32_t sf_aes_iv_r2_w0 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_iv_r2_w0; + + /* 0x324 : sf_aes_iv_r2_w1 */ + union { + struct { + uint32_t sf_aes_iv_r2_w1 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_iv_r2_w1; + + /* 0x328 : sf_aes_iv_r2_w2 */ + union { + struct { + uint32_t sf_aes_iv_r2_w2 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_iv_r2_w2; + + /* 0x32C : sf_aes_iv_r2_w3 */ + union { + struct { + uint32_t sf_aes_iv_r2_w3 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_iv_r2_w3; + + /* 0x330 : sf_aes_r2_start */ + union { + struct { + uint32_t sf_aes_r2_start : 19; /* [18: 0], r/w, 0x0 */ + uint32_t reserved_19_28 : 10; /* [28:19], rsvd, 0x0 */ + uint32_t sf_aes_r2_hw_key_en : 1; /* [ 29], r/w, 0x0 */ + uint32_t sf_aes_r2_en : 1; /* [ 30], r/w, 0x0 */ + uint32_t sf_aes_r2_lock : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_r2_start; + + /* 0x334 : sf_aes_r2_end */ + union { + struct { + uint32_t sf_aes_r2_end : 19; /* [18: 0], r/w, 0x3fff */ + uint32_t reserved_19_31 : 13; /* [31:19], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_r2_end; +}; + +typedef volatile struct sf_ctrl_reg sf_ctrl_reg_t; + +/*Following is reg patch*/ + +/* 0x0 : sf_if_sahb_0 */ +#define SF_CTRL_IF_SAHB_0_OFFSET (0x0) +#define SF_CTRL_IF_BUSY SF_CTRL_IF_BUSY +#define SF_CTRL_IF_BUSY_POS (0U) +#define SF_CTRL_IF_BUSY_LEN (1U) +#define SF_CTRL_IF_BUSY_MSK (((1U << SF_CTRL_IF_BUSY_LEN) - 1) << SF_CTRL_IF_BUSY_POS) +#define SF_CTRL_IF_BUSY_UMSK (~(((1U << SF_CTRL_IF_BUSY_LEN) - 1) << SF_CTRL_IF_BUSY_POS)) +#define SF_CTRL_IF_0_TRIG SF_CTRL_IF_0_TRIG +#define SF_CTRL_IF_0_TRIG_POS (1U) +#define SF_CTRL_IF_0_TRIG_LEN (1U) +#define SF_CTRL_IF_0_TRIG_MSK (((1U << SF_CTRL_IF_0_TRIG_LEN) - 1) << SF_CTRL_IF_0_TRIG_POS) +#define SF_CTRL_IF_0_TRIG_UMSK (~(((1U << SF_CTRL_IF_0_TRIG_LEN) - 1) << SF_CTRL_IF_0_TRIG_POS)) +#define SF_CTRL_IF_0_DAT_BYTE SF_CTRL_IF_0_DAT_BYTE +#define SF_CTRL_IF_0_DAT_BYTE_POS (2U) +#define SF_CTRL_IF_0_DAT_BYTE_LEN (10U) +#define SF_CTRL_IF_0_DAT_BYTE_MSK (((1U << SF_CTRL_IF_0_DAT_BYTE_LEN) - 1) << SF_CTRL_IF_0_DAT_BYTE_POS) +#define SF_CTRL_IF_0_DAT_BYTE_UMSK (~(((1U << SF_CTRL_IF_0_DAT_BYTE_LEN) - 1) << SF_CTRL_IF_0_DAT_BYTE_POS)) +#define SF_CTRL_IF_0_DMY_BYTE SF_CTRL_IF_0_DMY_BYTE +#define SF_CTRL_IF_0_DMY_BYTE_POS (12U) +#define SF_CTRL_IF_0_DMY_BYTE_LEN (5U) +#define SF_CTRL_IF_0_DMY_BYTE_MSK (((1U << SF_CTRL_IF_0_DMY_BYTE_LEN) - 1) << SF_CTRL_IF_0_DMY_BYTE_POS) +#define SF_CTRL_IF_0_DMY_BYTE_UMSK (~(((1U << SF_CTRL_IF_0_DMY_BYTE_LEN) - 1) << SF_CTRL_IF_0_DMY_BYTE_POS)) +#define SF_CTRL_IF_0_ADR_BYTE SF_CTRL_IF_0_ADR_BYTE +#define SF_CTRL_IF_0_ADR_BYTE_POS (17U) +#define SF_CTRL_IF_0_ADR_BYTE_LEN (3U) +#define SF_CTRL_IF_0_ADR_BYTE_MSK (((1U << SF_CTRL_IF_0_ADR_BYTE_LEN) - 1) << SF_CTRL_IF_0_ADR_BYTE_POS) +#define SF_CTRL_IF_0_ADR_BYTE_UMSK (~(((1U << SF_CTRL_IF_0_ADR_BYTE_LEN) - 1) << SF_CTRL_IF_0_ADR_BYTE_POS)) +#define SF_CTRL_IF_0_CMD_BYTE SF_CTRL_IF_0_CMD_BYTE +#define SF_CTRL_IF_0_CMD_BYTE_POS (20U) +#define SF_CTRL_IF_0_CMD_BYTE_LEN (3U) +#define SF_CTRL_IF_0_CMD_BYTE_MSK (((1U << SF_CTRL_IF_0_CMD_BYTE_LEN) - 1) << SF_CTRL_IF_0_CMD_BYTE_POS) +#define SF_CTRL_IF_0_CMD_BYTE_UMSK (~(((1U << SF_CTRL_IF_0_CMD_BYTE_LEN) - 1) << SF_CTRL_IF_0_CMD_BYTE_POS)) +#define SF_CTRL_IF_0_DAT_RW SF_CTRL_IF_0_DAT_RW +#define SF_CTRL_IF_0_DAT_RW_POS (23U) +#define SF_CTRL_IF_0_DAT_RW_LEN (1U) +#define SF_CTRL_IF_0_DAT_RW_MSK (((1U << SF_CTRL_IF_0_DAT_RW_LEN) - 1) << SF_CTRL_IF_0_DAT_RW_POS) +#define SF_CTRL_IF_0_DAT_RW_UMSK (~(((1U << SF_CTRL_IF_0_DAT_RW_LEN) - 1) << SF_CTRL_IF_0_DAT_RW_POS)) +#define SF_CTRL_IF_0_DAT_EN SF_CTRL_IF_0_DAT_EN +#define SF_CTRL_IF_0_DAT_EN_POS (24U) +#define SF_CTRL_IF_0_DAT_EN_LEN (1U) +#define SF_CTRL_IF_0_DAT_EN_MSK (((1U << SF_CTRL_IF_0_DAT_EN_LEN) - 1) << SF_CTRL_IF_0_DAT_EN_POS) +#define SF_CTRL_IF_0_DAT_EN_UMSK (~(((1U << SF_CTRL_IF_0_DAT_EN_LEN) - 1) << SF_CTRL_IF_0_DAT_EN_POS)) +#define SF_CTRL_IF_0_DMY_EN SF_CTRL_IF_0_DMY_EN +#define SF_CTRL_IF_0_DMY_EN_POS (25U) +#define SF_CTRL_IF_0_DMY_EN_LEN (1U) +#define SF_CTRL_IF_0_DMY_EN_MSK (((1U << SF_CTRL_IF_0_DMY_EN_LEN) - 1) << SF_CTRL_IF_0_DMY_EN_POS) +#define SF_CTRL_IF_0_DMY_EN_UMSK (~(((1U << SF_CTRL_IF_0_DMY_EN_LEN) - 1) << SF_CTRL_IF_0_DMY_EN_POS)) +#define SF_CTRL_IF_0_ADR_EN SF_CTRL_IF_0_ADR_EN +#define SF_CTRL_IF_0_ADR_EN_POS (26U) +#define SF_CTRL_IF_0_ADR_EN_LEN (1U) +#define SF_CTRL_IF_0_ADR_EN_MSK (((1U << SF_CTRL_IF_0_ADR_EN_LEN) - 1) << SF_CTRL_IF_0_ADR_EN_POS) +#define SF_CTRL_IF_0_ADR_EN_UMSK (~(((1U << SF_CTRL_IF_0_ADR_EN_LEN) - 1) << SF_CTRL_IF_0_ADR_EN_POS)) +#define SF_CTRL_IF_0_CMD_EN SF_CTRL_IF_0_CMD_EN +#define SF_CTRL_IF_0_CMD_EN_POS (27U) +#define SF_CTRL_IF_0_CMD_EN_LEN (1U) +#define SF_CTRL_IF_0_CMD_EN_MSK (((1U << SF_CTRL_IF_0_CMD_EN_LEN) - 1) << SF_CTRL_IF_0_CMD_EN_POS) +#define SF_CTRL_IF_0_CMD_EN_UMSK (~(((1U << SF_CTRL_IF_0_CMD_EN_LEN) - 1) << SF_CTRL_IF_0_CMD_EN_POS)) +#define SF_CTRL_IF_0_SPI_MODE SF_CTRL_IF_0_SPI_MODE +#define SF_CTRL_IF_0_SPI_MODE_POS (28U) +#define SF_CTRL_IF_0_SPI_MODE_LEN (3U) +#define SF_CTRL_IF_0_SPI_MODE_MSK (((1U << SF_CTRL_IF_0_SPI_MODE_LEN) - 1) << SF_CTRL_IF_0_SPI_MODE_POS) +#define SF_CTRL_IF_0_SPI_MODE_UMSK (~(((1U << SF_CTRL_IF_0_SPI_MODE_LEN) - 1) << SF_CTRL_IF_0_SPI_MODE_POS)) +#define SF_CTRL_IF_0_QPI_MODE_EN SF_CTRL_IF_0_QPI_MODE_EN +#define SF_CTRL_IF_0_QPI_MODE_EN_POS (31U) +#define SF_CTRL_IF_0_QPI_MODE_EN_LEN (1U) +#define SF_CTRL_IF_0_QPI_MODE_EN_MSK (((1U << SF_CTRL_IF_0_QPI_MODE_EN_LEN) - 1) << SF_CTRL_IF_0_QPI_MODE_EN_POS) +#define SF_CTRL_IF_0_QPI_MODE_EN_UMSK (~(((1U << SF_CTRL_IF_0_QPI_MODE_EN_LEN) - 1) << SF_CTRL_IF_0_QPI_MODE_EN_POS)) + +/* 0x4 : sf_if_sahb_1 */ +#define SF_CTRL_IF_SAHB_1_OFFSET (0x4) +#define SF_CTRL_IF_0_CMD_BUF_0 SF_CTRL_IF_0_CMD_BUF_0 +#define SF_CTRL_IF_0_CMD_BUF_0_POS (0U) +#define SF_CTRL_IF_0_CMD_BUF_0_LEN (32U) +#define SF_CTRL_IF_0_CMD_BUF_0_MSK (((1U << SF_CTRL_IF_0_CMD_BUF_0_LEN) - 1) << SF_CTRL_IF_0_CMD_BUF_0_POS) +#define SF_CTRL_IF_0_CMD_BUF_0_UMSK (~(((1U << SF_CTRL_IF_0_CMD_BUF_0_LEN) - 1) << SF_CTRL_IF_0_CMD_BUF_0_POS)) + +/* 0x8 : sf_if_sahb_2 */ +#define SF_CTRL_IF_SAHB_2_OFFSET (0x8) +#define SF_CTRL_IF_0_CMD_BUF_1 SF_CTRL_IF_0_CMD_BUF_1 +#define SF_CTRL_IF_0_CMD_BUF_1_POS (0U) +#define SF_CTRL_IF_0_CMD_BUF_1_LEN (32U) +#define SF_CTRL_IF_0_CMD_BUF_1_MSK (((1U << SF_CTRL_IF_0_CMD_BUF_1_LEN) - 1) << SF_CTRL_IF_0_CMD_BUF_1_POS) +#define SF_CTRL_IF_0_CMD_BUF_1_UMSK (~(((1U << SF_CTRL_IF_0_CMD_BUF_1_LEN) - 1) << SF_CTRL_IF_0_CMD_BUF_1_POS)) + +struct sf_if_sahb_0_reg { + /* 0x0 : sf_if_sahb_0 */ + union { + struct { + uint32_t if_busy : 1; /* [ 0], r, 0x0 */ + uint32_t if_0_trig : 1; /* [ 1], r/w, 0x0 */ + uint32_t if_0_dat_byte : 10; /* [11: 2], r/w, 0xff */ + uint32_t if_0_dmy_byte : 5; /* [16:12], r/w, 0x0 */ + uint32_t if_0_adr_byte : 3; /* [19:17], r/w, 0x2 */ + uint32_t if_0_cmd_byte : 3; /* [22:20], r/w, 0x0 */ + uint32_t if_0_dat_rw : 1; /* [ 23], r/w, 0x0 */ + uint32_t if_0_dat_en : 1; /* [ 24], r/w, 0x1 */ + uint32_t if_0_dmy_en : 1; /* [ 25], r/w, 0x0 */ + uint32_t if_0_adr_en : 1; /* [ 26], r/w, 0x1 */ + uint32_t if_0_cmd_en : 1; /* [ 27], r/w, 0x1 */ + uint32_t if_0_spi_mode : 3; /* [30:28], r/w, 0x0 */ + uint32_t if_0_qpi_mode_en : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } if_sahb_0; + + /* 0x4 : sf_if_sahb_1 */ + union { + struct { + uint32_t if_0_cmd_buf_0 : 32; /* [31: 0], r/w, 0x3000000 */ + } BF; + uint32_t WORD; + } if_sahb_1; + + /* 0x8 : sf_if_sahb_2 */ + union { + struct { + uint32_t if_0_cmd_buf_1 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } if_sahb_2; +}; + +typedef volatile struct sf_if_sahb_0_reg sf_if_sahb_0_reg_t; + +#define SF_CTRL_IF1_SAHB_OFFSET 0x8 +#define SF_CTRL_IF2_SAHB_OFFSET 0xC8 + +/*Following is reg patch*/ + +/* 0x0 : if_io_dly_0 */ +#define SF_CTRL_IO_DLY_0_OFFSET (0x0) +#define SF_CTRL_CS_DLY_SEL SF_CTRL_CS_DLY_SEL +#define SF_CTRL_CS_DLY_SEL_POS (0U) +#define SF_CTRL_CS_DLY_SEL_LEN (2U) +#define SF_CTRL_CS_DLY_SEL_MSK (((1U << SF_CTRL_CS_DLY_SEL_LEN) - 1) << SF_CTRL_CS_DLY_SEL_POS) +#define SF_CTRL_CS_DLY_SEL_UMSK (~(((1U << SF_CTRL_CS_DLY_SEL_LEN) - 1) << SF_CTRL_CS_DLY_SEL_POS)) +#define SF_CTRL_CS2_DLY_SEL SF_CTRL_CS2_DLY_SEL +#define SF_CTRL_CS2_DLY_SEL_POS (2U) +#define SF_CTRL_CS2_DLY_SEL_LEN (2U) +#define SF_CTRL_CS2_DLY_SEL_MSK (((1U << SF_CTRL_CS2_DLY_SEL_LEN) - 1) << SF_CTRL_CS2_DLY_SEL_POS) +#define SF_CTRL_CS2_DLY_SEL_UMSK (~(((1U << SF_CTRL_CS2_DLY_SEL_LEN) - 1) << SF_CTRL_CS2_DLY_SEL_POS)) +#define SF_CTRL_CLK_OUT_DLY_SEL SF_CTRL_CLK_OUT_DLY_SEL +#define SF_CTRL_CLK_OUT_DLY_SEL_POS (8U) +#define SF_CTRL_CLK_OUT_DLY_SEL_LEN (2U) +#define SF_CTRL_CLK_OUT_DLY_SEL_MSK (((1U << SF_CTRL_CLK_OUT_DLY_SEL_LEN) - 1) << SF_CTRL_CLK_OUT_DLY_SEL_POS) +#define SF_CTRL_CLK_OUT_DLY_SEL_UMSK (~(((1U << SF_CTRL_CLK_OUT_DLY_SEL_LEN) - 1) << SF_CTRL_CLK_OUT_DLY_SEL_POS)) +#define SF_CTRL_DQS_OE_DLY_SEL SF_CTRL_DQS_OE_DLY_SEL +#define SF_CTRL_DQS_OE_DLY_SEL_POS (26U) +#define SF_CTRL_DQS_OE_DLY_SEL_LEN (2U) +#define SF_CTRL_DQS_OE_DLY_SEL_MSK (((1U << SF_CTRL_DQS_OE_DLY_SEL_LEN) - 1) << SF_CTRL_DQS_OE_DLY_SEL_POS) +#define SF_CTRL_DQS_OE_DLY_SEL_UMSK (~(((1U << SF_CTRL_DQS_OE_DLY_SEL_LEN) - 1) << SF_CTRL_DQS_OE_DLY_SEL_POS)) +#define SF_CTRL_DQS_DI_DLY_SEL SF_CTRL_DQS_DI_DLY_SEL +#define SF_CTRL_DQS_DI_DLY_SEL_POS (28U) +#define SF_CTRL_DQS_DI_DLY_SEL_LEN (2U) +#define SF_CTRL_DQS_DI_DLY_SEL_MSK (((1U << SF_CTRL_DQS_DI_DLY_SEL_LEN) - 1) << SF_CTRL_DQS_DI_DLY_SEL_POS) +#define SF_CTRL_DQS_DI_DLY_SEL_UMSK (~(((1U << SF_CTRL_DQS_DI_DLY_SEL_LEN) - 1) << SF_CTRL_DQS_DI_DLY_SEL_POS)) +#define SF_CTRL_DQS_DO_DLY_SEL SF_CTRL_DQS_DO_DLY_SEL +#define SF_CTRL_DQS_DO_DLY_SEL_POS (30U) +#define SF_CTRL_DQS_DO_DLY_SEL_LEN (2U) +#define SF_CTRL_DQS_DO_DLY_SEL_MSK (((1U << SF_CTRL_DQS_DO_DLY_SEL_LEN) - 1) << SF_CTRL_DQS_DO_DLY_SEL_POS) +#define SF_CTRL_DQS_DO_DLY_SEL_UMSK (~(((1U << SF_CTRL_DQS_DO_DLY_SEL_LEN) - 1) << SF_CTRL_DQS_DO_DLY_SEL_POS)) + +/* 0x4 : if_io_dly_1 */ +#define SF_CTRL_IO_DLY_1_OFFSET (0x4) +#define SF_CTRL_IO_0_OE_DLY_SEL SF_CTRL_IO_0_OE_DLY_SEL +#define SF_CTRL_IO_0_OE_DLY_SEL_POS (0U) +#define SF_CTRL_IO_0_OE_DLY_SEL_LEN (2U) +#define SF_CTRL_IO_0_OE_DLY_SEL_MSK (((1U << SF_CTRL_IO_0_OE_DLY_SEL_LEN) - 1) << SF_CTRL_IO_0_OE_DLY_SEL_POS) +#define SF_CTRL_IO_0_OE_DLY_SEL_UMSK (~(((1U << SF_CTRL_IO_0_OE_DLY_SEL_LEN) - 1) << SF_CTRL_IO_0_OE_DLY_SEL_POS)) +#define SF_CTRL_IO_0_DI_DLY_SEL SF_CTRL_IO_0_DI_DLY_SEL +#define SF_CTRL_IO_0_DI_DLY_SEL_POS (8U) +#define SF_CTRL_IO_0_DI_DLY_SEL_LEN (2U) +#define SF_CTRL_IO_0_DI_DLY_SEL_MSK (((1U << SF_CTRL_IO_0_DI_DLY_SEL_LEN) - 1) << SF_CTRL_IO_0_DI_DLY_SEL_POS) +#define SF_CTRL_IO_0_DI_DLY_SEL_UMSK (~(((1U << SF_CTRL_IO_0_DI_DLY_SEL_LEN) - 1) << SF_CTRL_IO_0_DI_DLY_SEL_POS)) +#define SF_CTRL_IO_0_DO_DLY_SEL SF_CTRL_IO_0_DO_DLY_SEL +#define SF_CTRL_IO_0_DO_DLY_SEL_POS (16U) +#define SF_CTRL_IO_0_DO_DLY_SEL_LEN (2U) +#define SF_CTRL_IO_0_DO_DLY_SEL_MSK (((1U << SF_CTRL_IO_0_DO_DLY_SEL_LEN) - 1) << SF_CTRL_IO_0_DO_DLY_SEL_POS) +#define SF_CTRL_IO_0_DO_DLY_SEL_UMSK (~(((1U << SF_CTRL_IO_0_DO_DLY_SEL_LEN) - 1) << SF_CTRL_IO_0_DO_DLY_SEL_POS)) + +/* 0x8 : if_io_dly_2 */ +#define SF_CTRL_IO_DLY_2_OFFSET (0x8) +#define SF_CTRL_IO_1_OE_DLY_SEL SF_CTRL_IO_1_OE_DLY_SEL +#define SF_CTRL_IO_1_OE_DLY_SEL_POS (0U) +#define SF_CTRL_IO_1_OE_DLY_SEL_LEN (2U) +#define SF_CTRL_IO_1_OE_DLY_SEL_MSK (((1U << SF_CTRL_IO_1_OE_DLY_SEL_LEN) - 1) << SF_CTRL_IO_1_OE_DLY_SEL_POS) +#define SF_CTRL_IO_1_OE_DLY_SEL_UMSK (~(((1U << SF_CTRL_IO_1_OE_DLY_SEL_LEN) - 1) << SF_CTRL_IO_1_OE_DLY_SEL_POS)) +#define SF_CTRL_IO_1_DI_DLY_SEL SF_CTRL_IO_1_DI_DLY_SEL +#define SF_CTRL_IO_1_DI_DLY_SEL_POS (8U) +#define SF_CTRL_IO_1_DI_DLY_SEL_LEN (2U) +#define SF_CTRL_IO_1_DI_DLY_SEL_MSK (((1U << SF_CTRL_IO_1_DI_DLY_SEL_LEN) - 1) << SF_CTRL_IO_1_DI_DLY_SEL_POS) +#define SF_CTRL_IO_1_DI_DLY_SEL_UMSK (~(((1U << SF_CTRL_IO_1_DI_DLY_SEL_LEN) - 1) << SF_CTRL_IO_1_DI_DLY_SEL_POS)) +#define SF_CTRL_IO_1_DO_DLY_SEL SF_CTRL_IO_1_DO_DLY_SEL +#define SF_CTRL_IO_1_DO_DLY_SEL_POS (16U) +#define SF_CTRL_IO_1_DO_DLY_SEL_LEN (2U) +#define SF_CTRL_IO_1_DO_DLY_SEL_MSK (((1U << SF_CTRL_IO_1_DO_DLY_SEL_LEN) - 1) << SF_CTRL_IO_1_DO_DLY_SEL_POS) +#define SF_CTRL_IO_1_DO_DLY_SEL_UMSK (~(((1U << SF_CTRL_IO_1_DO_DLY_SEL_LEN) - 1) << SF_CTRL_IO_1_DO_DLY_SEL_POS)) + +/* 0xc : if_io_dly_3 */ +#define SF_CTRL_IO_DLY_3_OFFSET (0xc) +#define SF_CTRL_IO_2_OE_DLY_SEL SF_CTRL_IO_2_OE_DLY_SEL +#define SF_CTRL_IO_2_OE_DLY_SEL_POS (0U) +#define SF_CTRL_IO_2_OE_DLY_SEL_LEN (2U) +#define SF_CTRL_IO_2_OE_DLY_SEL_MSK (((1U << SF_CTRL_IO_2_OE_DLY_SEL_LEN) - 1) << SF_CTRL_IO_2_OE_DLY_SEL_POS) +#define SF_CTRL_IO_2_OE_DLY_SEL_UMSK (~(((1U << SF_CTRL_IO_2_OE_DLY_SEL_LEN) - 1) << SF_CTRL_IO_2_OE_DLY_SEL_POS)) +#define SF_CTRL_IO_2_DI_DLY_SEL SF_CTRL_IO_2_DI_DLY_SEL +#define SF_CTRL_IO_2_DI_DLY_SEL_POS (8U) +#define SF_CTRL_IO_2_DI_DLY_SEL_LEN (2U) +#define SF_CTRL_IO_2_DI_DLY_SEL_MSK (((1U << SF_CTRL_IO_2_DI_DLY_SEL_LEN) - 1) << SF_CTRL_IO_2_DI_DLY_SEL_POS) +#define SF_CTRL_IO_2_DI_DLY_SEL_UMSK (~(((1U << SF_CTRL_IO_2_DI_DLY_SEL_LEN) - 1) << SF_CTRL_IO_2_DI_DLY_SEL_POS)) +#define SF_CTRL_IO_2_DO_DLY_SEL SF_CTRL_IO_2_DO_DLY_SEL +#define SF_CTRL_IO_2_DO_DLY_SEL_POS (16U) +#define SF_CTRL_IO_2_DO_DLY_SEL_LEN (2U) +#define SF_CTRL_IO_2_DO_DLY_SEL_MSK (((1U << SF_CTRL_IO_2_DO_DLY_SEL_LEN) - 1) << SF_CTRL_IO_2_DO_DLY_SEL_POS) +#define SF_CTRL_IO_2_DO_DLY_SEL_UMSK (~(((1U << SF_CTRL_IO_2_DO_DLY_SEL_LEN) - 1) << SF_CTRL_IO_2_DO_DLY_SEL_POS)) + +/* 0x10 : if_io_dly_4 */ +#define SF_CTRL_IO_DLY_4_OFFSET (0x10) +#define SF_CTRL_IO_3_OE_DLY_SEL SF_CTRL_IO_3_OE_DLY_SEL +#define SF_CTRL_IO_3_OE_DLY_SEL_POS (0U) +#define SF_CTRL_IO_3_OE_DLY_SEL_LEN (2U) +#define SF_CTRL_IO_3_OE_DLY_SEL_MSK (((1U << SF_CTRL_IO_3_OE_DLY_SEL_LEN) - 1) << SF_CTRL_IO_3_OE_DLY_SEL_POS) +#define SF_CTRL_IO_3_OE_DLY_SEL_UMSK (~(((1U << SF_CTRL_IO_3_OE_DLY_SEL_LEN) - 1) << SF_CTRL_IO_3_OE_DLY_SEL_POS)) +#define SF_CTRL_IO_3_DI_DLY_SEL SF_CTRL_IO_3_DI_DLY_SEL +#define SF_CTRL_IO_3_DI_DLY_SEL_POS (8U) +#define SF_CTRL_IO_3_DI_DLY_SEL_LEN (2U) +#define SF_CTRL_IO_3_DI_DLY_SEL_MSK (((1U << SF_CTRL_IO_3_DI_DLY_SEL_LEN) - 1) << SF_CTRL_IO_3_DI_DLY_SEL_POS) +#define SF_CTRL_IO_3_DI_DLY_SEL_UMSK (~(((1U << SF_CTRL_IO_3_DI_DLY_SEL_LEN) - 1) << SF_CTRL_IO_3_DI_DLY_SEL_POS)) +#define SF_CTRL_IO_3_DO_DLY_SEL SF_CTRL_IO_3_DO_DLY_SEL +#define SF_CTRL_IO_3_DO_DLY_SEL_POS (16U) +#define SF_CTRL_IO_3_DO_DLY_SEL_LEN (2U) +#define SF_CTRL_IO_3_DO_DLY_SEL_MSK (((1U << SF_CTRL_IO_3_DO_DLY_SEL_LEN) - 1) << SF_CTRL_IO_3_DO_DLY_SEL_POS) +#define SF_CTRL_IO_3_DO_DLY_SEL_UMSK (~(((1U << SF_CTRL_IO_3_DO_DLY_SEL_LEN) - 1) << SF_CTRL_IO_3_DO_DLY_SEL_POS)) + +struct sf_if_io_dly_0_reg { + /* 0x0 : if_io_dly_0 */ + union { + struct { + uint32_t cs_dly_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t cs2_dly_sel : 2; /* [ 3: 2], r/w, 0x0 */ + uint32_t reserved_4_7 : 4; /* [ 7: 4], rsvd, 0x0 */ + uint32_t clk_out_dly_sel : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reserved_10_25 : 16; /* [25:10], rsvd, 0x0 */ + uint32_t dqs_oe_dly_sel : 2; /* [27:26], r/w, 0x0 */ + uint32_t dqs_di_dly_sel : 2; /* [29:28], r/w, 0x0 */ + uint32_t dqs_do_dly_sel : 2; /* [31:30], r/w, 0x0 */ + } BF; + uint32_t WORD; + } io_dly_0; + + /* 0x4 : if_io_dly_1 */ + union { + struct { + uint32_t io_0_oe_dly_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t io_0_di_dly_sel : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t io_0_do_dly_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_31 : 14; /* [31:18], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } io_dly_1; + + /* 0x8 : if_io_dly_2 */ + union { + struct { + uint32_t io_1_oe_dly_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t io_1_di_dly_sel : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t io_1_do_dly_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_31 : 14; /* [31:18], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } io_dly_2; + + /* 0xc : if_io_dly_3 */ + union { + struct { + uint32_t io_2_oe_dly_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t io_2_di_dly_sel : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t io_2_do_dly_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_31 : 14; /* [31:18], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } io_dly_3; + + /* 0x10 : if_io_dly_4 */ + union { + struct { + uint32_t io_3_oe_dly_sel : 2; /* [ 1: 0], r/w, 0x0 */ + uint32_t reserved_2_7 : 6; /* [ 7: 2], rsvd, 0x0 */ + uint32_t io_3_di_dly_sel : 2; /* [ 9: 8], r/w, 0x0 */ + uint32_t reserved_10_15 : 6; /* [15:10], rsvd, 0x0 */ + uint32_t io_3_do_dly_sel : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_31 : 14; /* [31:18], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } io_dly_4; +}; + +typedef volatile struct sf_if_io_dly_0_reg sf_if_io_dly_0_reg_t; + +#define SF_CTRL_IF_IO_DLY_1_OFFSET 0x30 +#define SF_CTRL_IF_IO_DLY_2_OFFSET 0x48 +#define SF_CTRL_IF_IO_DLY_3_OFFSET 0x5C + +/*Following is reg patch*/ + +/* 0x0 : sf_aes_key_0 */ +#define SF_CTRL_SF_AES_KEY_0_OFFSET (0x0) +#define SF_CTRL_SF_AES_KEY_0 SF_CTRL_SF_AES_KEY_0 +#define SF_CTRL_SF_AES_KEY_0_POS (0U) +#define SF_CTRL_SF_AES_KEY_0_LEN (32U) +#define SF_CTRL_SF_AES_KEY_0_MSK (((1U << SF_CTRL_SF_AES_KEY_0_LEN) - 1) << SF_CTRL_SF_AES_KEY_0_POS) +#define SF_CTRL_SF_AES_KEY_0_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_0_LEN) - 1) << SF_CTRL_SF_AES_KEY_0_POS)) + +/* 0x4 : sf_aes_key_1 */ +#define SF_CTRL_SF_AES_KEY_1_OFFSET (0x4) +#define SF_CTRL_SF_AES_KEY_1 SF_CTRL_SF_AES_KEY_1 +#define SF_CTRL_SF_AES_KEY_1_POS (0U) +#define SF_CTRL_SF_AES_KEY_1_LEN (32U) +#define SF_CTRL_SF_AES_KEY_1_MSK (((1U << SF_CTRL_SF_AES_KEY_1_LEN) - 1) << SF_CTRL_SF_AES_KEY_1_POS) +#define SF_CTRL_SF_AES_KEY_1_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_1_LEN) - 1) << SF_CTRL_SF_AES_KEY_1_POS)) + +/* 0x8 : sf_aes_key_2 */ +#define SF_CTRL_SF_AES_KEY_2_OFFSET (0x8) +#define SF_CTRL_SF_AES_KEY_2 SF_CTRL_SF_AES_KEY_2 +#define SF_CTRL_SF_AES_KEY_2_POS (0U) +#define SF_CTRL_SF_AES_KEY_2_LEN (32U) +#define SF_CTRL_SF_AES_KEY_2_MSK (((1U << SF_CTRL_SF_AES_KEY_2_LEN) - 1) << SF_CTRL_SF_AES_KEY_2_POS) +#define SF_CTRL_SF_AES_KEY_2_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_2_LEN) - 1) << SF_CTRL_SF_AES_KEY_2_POS)) + +/* 0xc : sf_aes_key_3 */ +#define SF_CTRL_SF_AES_KEY_3_OFFSET (0xc) +#define SF_CTRL_SF_AES_KEY_3 SF_CTRL_SF_AES_KEY_3 +#define SF_CTRL_SF_AES_KEY_3_POS (0U) +#define SF_CTRL_SF_AES_KEY_3_LEN (32U) +#define SF_CTRL_SF_AES_KEY_3_MSK (((1U << SF_CTRL_SF_AES_KEY_3_LEN) - 1) << SF_CTRL_SF_AES_KEY_3_POS) +#define SF_CTRL_SF_AES_KEY_3_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_3_LEN) - 1) << SF_CTRL_SF_AES_KEY_3_POS)) + +/* 0x10 : sf_aes_key_4 */ +#define SF_CTRL_SF_AES_KEY_4_OFFSET (0x10) +#define SF_CTRL_SF_AES_KEY_4 SF_CTRL_SF_AES_KEY_4 +#define SF_CTRL_SF_AES_KEY_4_POS (0U) +#define SF_CTRL_SF_AES_KEY_4_LEN (32U) +#define SF_CTRL_SF_AES_KEY_4_MSK (((1U << SF_CTRL_SF_AES_KEY_4_LEN) - 1) << SF_CTRL_SF_AES_KEY_4_POS) +#define SF_CTRL_SF_AES_KEY_4_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_4_LEN) - 1) << SF_CTRL_SF_AES_KEY_4_POS)) + +/* 0x14 : sf_aes_key_5 */ +#define SF_CTRL_SF_AES_KEY_5_OFFSET (0x14) +#define SF_CTRL_SF_AES_KEY_5 SF_CTRL_SF_AES_KEY_5 +#define SF_CTRL_SF_AES_KEY_5_POS (0U) +#define SF_CTRL_SF_AES_KEY_5_LEN (32U) +#define SF_CTRL_SF_AES_KEY_5_MSK (((1U << SF_CTRL_SF_AES_KEY_5_LEN) - 1) << SF_CTRL_SF_AES_KEY_5_POS) +#define SF_CTRL_SF_AES_KEY_5_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_5_LEN) - 1) << SF_CTRL_SF_AES_KEY_5_POS)) + +/* 0x18 : sf_aes_key_6 */ +#define SF_CTRL_SF_AES_KEY_6_OFFSET (0x18) +#define SF_CTRL_SF_AES_KEY_6 SF_CTRL_SF_AES_KEY_6 +#define SF_CTRL_SF_AES_KEY_6_POS (0U) +#define SF_CTRL_SF_AES_KEY_6_LEN (32U) +#define SF_CTRL_SF_AES_KEY_6_MSK (((1U << SF_CTRL_SF_AES_KEY_6_LEN) - 1) << SF_CTRL_SF_AES_KEY_6_POS) +#define SF_CTRL_SF_AES_KEY_6_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_6_LEN) - 1) << SF_CTRL_SF_AES_KEY_6_POS)) + +/* 0x1c : sf_aes_key_7 */ +#define SF_CTRL_SF_AES_KEY_7_OFFSET (0x1c) +#define SF_CTRL_SF_AES_KEY_7 SF_CTRL_SF_AES_KEY_7 +#define SF_CTRL_SF_AES_KEY_7_POS (0U) +#define SF_CTRL_SF_AES_KEY_7_LEN (32U) +#define SF_CTRL_SF_AES_KEY_7_MSK (((1U << SF_CTRL_SF_AES_KEY_7_LEN) - 1) << SF_CTRL_SF_AES_KEY_7_POS) +#define SF_CTRL_SF_AES_KEY_7_UMSK (~(((1U << SF_CTRL_SF_AES_KEY_7_LEN) - 1) << SF_CTRL_SF_AES_KEY_7_POS)) + +/* 0x20 : sf_aes_iv_w0 */ +#define SF_CTRL_SF_AES_IV_W0_OFFSET (0x20) +#define SF_CTRL_SF_AES_IV_W0 SF_CTRL_SF_AES_IV_W0 +#define SF_CTRL_SF_AES_IV_W0_POS (0U) +#define SF_CTRL_SF_AES_IV_W0_LEN (32U) +#define SF_CTRL_SF_AES_IV_W0_MSK (((1U << SF_CTRL_SF_AES_IV_W0_LEN) - 1) << SF_CTRL_SF_AES_IV_W0_POS) +#define SF_CTRL_SF_AES_IV_W0_UMSK (~(((1U << SF_CTRL_SF_AES_IV_W0_LEN) - 1) << SF_CTRL_SF_AES_IV_W0_POS)) + +/* 0x24 : sf_aes_iv_w1 */ +#define SF_CTRL_SF_AES_IV_W1_OFFSET (0x24) +#define SF_CTRL_SF_AES_IV_W1 SF_CTRL_SF_AES_IV_W1 +#define SF_CTRL_SF_AES_IV_W1_POS (0U) +#define SF_CTRL_SF_AES_IV_W1_LEN (32U) +#define SF_CTRL_SF_AES_IV_W1_MSK (((1U << SF_CTRL_SF_AES_IV_W1_LEN) - 1) << SF_CTRL_SF_AES_IV_W1_POS) +#define SF_CTRL_SF_AES_IV_W1_UMSK (~(((1U << SF_CTRL_SF_AES_IV_W1_LEN) - 1) << SF_CTRL_SF_AES_IV_W1_POS)) + +/* 0x28 : sf_aes_iv_w2 */ +#define SF_CTRL_SF_AES_IV_W2_OFFSET (0x28) +#define SF_CTRL_SF_AES_IV_W2 SF_CTRL_SF_AES_IV_W2 +#define SF_CTRL_SF_AES_IV_W2_POS (0U) +#define SF_CTRL_SF_AES_IV_W2_LEN (32U) +#define SF_CTRL_SF_AES_IV_W2_MSK (((1U << SF_CTRL_SF_AES_IV_W2_LEN) - 1) << SF_CTRL_SF_AES_IV_W2_POS) +#define SF_CTRL_SF_AES_IV_W2_UMSK (~(((1U << SF_CTRL_SF_AES_IV_W2_LEN) - 1) << SF_CTRL_SF_AES_IV_W2_POS)) + +/* 0x2c : sf_aes_iv_w3 */ +#define SF_CTRL_SF_AES_IV_W3_OFFSET (0x2c) +#define SF_CTRL_SF_AES_IV_W3 SF_CTRL_SF_AES_IV_W3 +#define SF_CTRL_SF_AES_IV_W3_POS (0U) +#define SF_CTRL_SF_AES_IV_W3_LEN (32U) +#define SF_CTRL_SF_AES_IV_W3_MSK (((1U << SF_CTRL_SF_AES_IV_W3_LEN) - 1) << SF_CTRL_SF_AES_IV_W3_POS) +#define SF_CTRL_SF_AES_IV_W3_UMSK (~(((1U << SF_CTRL_SF_AES_IV_W3_LEN) - 1) << SF_CTRL_SF_AES_IV_W3_POS)) + +/* 0x30 : sf_aes_start */ +#define SF_CTRL_SF_AES_START_OFFSET (0x30) +#define SF_CTRL_SF_AES_REGION_START SF_CTRL_SF_AES_REGION_START +#define SF_CTRL_SF_AES_REGION_START_POS (0U) +#define SF_CTRL_SF_AES_REGION_START_LEN (19U) +#define SF_CTRL_SF_AES_REGION_START_MSK (((1U << SF_CTRL_SF_AES_REGION_START_LEN) - 1) << SF_CTRL_SF_AES_REGION_START_POS) +#define SF_CTRL_SF_AES_REGION_START_UMSK (~(((1U << SF_CTRL_SF_AES_REGION_START_LEN) - 1) << SF_CTRL_SF_AES_REGION_START_POS)) +#define SF_CTRL_SF_AES_REGION_HW_KEY_EN SF_CTRL_SF_AES_REGION_HW_KEY_EN +#define SF_CTRL_SF_AES_REGION_HW_KEY_EN_POS (29U) +#define SF_CTRL_SF_AES_REGION_HW_KEY_EN_LEN (1U) +#define SF_CTRL_SF_AES_REGION_HW_KEY_EN_MSK (((1U << SF_CTRL_SF_AES_REGION_HW_KEY_EN_LEN) - 1) << SF_CTRL_SF_AES_REGION_HW_KEY_EN_POS) +#define SF_CTRL_SF_AES_REGION_HW_KEY_EN_UMSK (~(((1U << SF_CTRL_SF_AES_REGION_HW_KEY_EN_LEN) - 1) << SF_CTRL_SF_AES_REGION_HW_KEY_EN_POS)) +#define SF_CTRL_SF_AES_REGION_EN SF_CTRL_SF_AES_REGION_EN +#define SF_CTRL_SF_AES_REGION_EN_POS (30U) +#define SF_CTRL_SF_AES_REGION_EN_LEN (1U) +#define SF_CTRL_SF_AES_REGION_EN_MSK (((1U << SF_CTRL_SF_AES_REGION_EN_LEN) - 1) << SF_CTRL_SF_AES_REGION_EN_POS) +#define SF_CTRL_SF_AES_REGION_EN_UMSK (~(((1U << SF_CTRL_SF_AES_REGION_EN_LEN) - 1) << SF_CTRL_SF_AES_REGION_EN_POS)) +#define SF_CTRL_SF_AES_REGION_LOCK SF_CTRL_SF_AES_REGION_LOCK +#define SF_CTRL_SF_AES_REGION_LOCK_POS (31U) +#define SF_CTRL_SF_AES_REGION_LOCK_LEN (1U) +#define SF_CTRL_SF_AES_REGION_LOCK_MSK (((1U << SF_CTRL_SF_AES_REGION_LOCK_LEN) - 1) << SF_CTRL_SF_AES_REGION_LOCK_POS) +#define SF_CTRL_SF_AES_REGION_LOCK_UMSK (~(((1U << SF_CTRL_SF_AES_REGION_LOCK_LEN) - 1) << SF_CTRL_SF_AES_REGION_LOCK_POS)) + +/* 0x34 : sf_aes_end */ +#define SF_CTRL_SF_AES_END_OFFSET (0x34) +#define SF_CTRL_SF_AES_REGION_END SF_CTRL_SF_AES_REGION_END +#define SF_CTRL_SF_AES_REGION_END_POS (0U) +#define SF_CTRL_SF_AES_REGION_END_LEN (19U) +#define SF_CTRL_SF_AES_REGION_END_MSK (((1U << SF_CTRL_SF_AES_REGION_END_LEN) - 1) << SF_CTRL_SF_AES_REGION_END_POS) +#define SF_CTRL_SF_AES_REGION_END_UMSK (~(((1U << SF_CTRL_SF_AES_REGION_END_LEN) - 1) << SF_CTRL_SF_AES_REGION_END_POS)) + +struct sf_ctrl_aes_region_reg { + /* 0x0 : sf_aes_key_0 */ + union { + struct { + uint32_t sf_aes_key_0 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_0; + + /* 0x4 : sf_aes_key_1 */ + union { + struct { + uint32_t sf_aes_key_1 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_1; + + /* 0x8 : sf_aes_key_2 */ + union { + struct { + uint32_t sf_aes_key_2 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_2; + + /* 0xc : sf_aes_key_3 */ + union { + struct { + uint32_t sf_aes_key_3 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_3; + + /* 0x10 : sf_aes_key_4 */ + union { + struct { + uint32_t sf_aes_key_4 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_4; + + /* 0x14 : sf_aes_key_5 */ + union { + struct { + uint32_t sf_aes_key_5 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_5; + + /* 0x18 : sf_aes_key_6 */ + union { + struct { + uint32_t sf_aes_key_6 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_6; + + /* 0x1c : sf_aes_key_7 */ + union { + struct { + uint32_t sf_aes_key_7 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_key_7; + + /* 0x20 : sf_aes_iv_w0 */ + union { + struct { + uint32_t sf_aes_iv_w0 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_iv_w0; + + /* 0x24 : sf_aes_iv_w1 */ + union { + struct { + uint32_t sf_aes_iv_w1 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_iv_w1; + + /* 0x28 : sf_aes_iv_w2 */ + union { + struct { + uint32_t sf_aes_iv_w2 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_iv_w2; + + /* 0x2c : sf_aes_iv_w3 */ + union { + struct { + uint32_t sf_aes_iv_w3 : 32; /* [31: 0], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_iv_w3; + + /* 0x30 : sf_aes_start */ + union { + struct { + uint32_t sf_aes_region_start : 19; /* [18: 0], r/w, 0x0 */ + uint32_t reserved_19_28 : 10; /* [28:19], rsvd, 0x0 */ + uint32_t sf_aes_region_hw_key_en : 1; /* [ 29], r/w, 0x0 */ + uint32_t sf_aes_region_en : 1; /* [ 30], r/w, 0x0 */ + uint32_t sf_aes_region_lock : 1; /* [ 31], r/w, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_start; + + /* 0x34 : sf_aes_end */ + union { + struct { + uint32_t sf_aes_region_end : 19; /* [18: 0], r/w, 0x3fff */ + uint32_t reserved_19_31 : 13; /* [31:19], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } sf_aes_end; +}; + +typedef volatile struct sf_ctrl_aes_region_reg sf_ctrl_aes_region_reg_t; + +#define SF_CTRL_AES_REGION_OFFSET 0x200 + +#endif /* __SF_CTRL_REG_H__ */ diff --git a/platforms/bl808_m0/vendor/psram/include/system_bl808.h b/platforms/bl808_m0/vendor/psram/include/system_bl808.h new file mode 100644 index 0000000..07e4e07 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/include/system_bl808.h @@ -0,0 +1,23 @@ +#ifndef __SYSTEM_BL808_H__ +#define __SYSTEM_BL808_H__ + +#define RV_EXCEPTION_NUM (16) +typedef uintptr_t (*exception_handler)(uintptr_t cause, uintptr_t val, uintptr_t *regs); +typedef void (*pFunc)(void); + +extern void System_Interrupt_Init(void); +extern void CPU_Interrupt_Enable(uint32_t irq_num); +extern void CPU_Interrupt_Disable(uint32_t irq_num); +extern void CPU_Interrupt_Pending_Clear(uint32_t irq_num); +void Interrupt_Handler_Register(IRQn_Type irq, pFunc interruptFun); +extern void System_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority); + +exception_handler exception_handler_install(uintptr_t vec, exception_handler handler); + +void riscv_savefpu(uintptr_t *regs); +void riscv_restorefpu(const uintptr_t *regs); + +int32_t drv_get_cpu_id(void); +int32_t drv_get_cpu_freq(int32_t idx); + +#endif diff --git a/platforms/bl808_m0/vendor/psram/src/bl808_glb_pll.c b/platforms/bl808_m0/vendor/psram/src/bl808_glb_pll.c new file mode 100644 index 0000000..5294bc8 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/src/bl808_glb_pll.c @@ -0,0 +1,3050 @@ +/** + ****************************************************************************** + * @file bl808_glb_pll.c + * @version V1.0 + * @date + * @brief This file is the standard driver c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +#include "bl808_clock.h" +#include "bl808_glb.h" +#include "bl808_aon.h" +#include "bl808_hbn.h" +#include "bl808_pds.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup GLB + * @{ + */ + +/** @defgroup GLB_Private_Macros + * @{ + */ +#define GLB_CLK_SET_DUMMY_WAIT \ + { \ + __NOP(); \ + __NOP(); \ + __NOP(); \ + __NOP(); \ + __NOP(); \ + __NOP(); \ + __NOP(); \ + __NOP(); \ + } +#define GLB_CLK_SET_DUMMY_TIMEOUT (0xFF) +#define GLB_FREQ_RC32M (32000000) + +/*@} end of group GLB_Private_Macros */ + +/** @defgroup GLB_Private_Types + * @{ + */ + +/*@} end of group GLB_Private_Types */ + +/** @defgroup GLB_Private_Variables + * @{ + */ + + + +/* WiFi PLL Config*/ +const GLB_WAC_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION wifiPllBasicCfg_32M_38P4M_40M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllIntFracSw = 0, /*!< pll_int_frac_sw */ + .clkpllIcp1u = 0, /*!< pll_icp_1u */ + .clkpllIcp5u = 2, /*!< pll_icp_5u */ + .clkpllRz = 3, /*!< pll_rz */ + .clkpllCz = 1, /*!< pll_cz */ + .clkpllC3 = 2, /*!< pll_c3 */ + .clkpllR4Short = 1, /*!< pll_r4_short */ + .clkpllC4En = 0, /*!< pll_r4_en */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 5, /*!< pll_vco_speed */ + .clkpllSdmCtrlHw = 1, /*!< pll_sdm_ctrl_hw */ + .clkpllSdmBypass = 1, /*!< pll_sdm_bypass */ +}; +const GLB_WAC_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION wifiPllBasicCfg_24M = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllIntFracSw = 0, /*!< pll_int_frac_sw */ + .clkpllIcp1u = 0, /*!< pll_icp_1u */ + .clkpllIcp5u = 2, /*!< pll_icp_5u */ + .clkpllRz = 3, /*!< pll_rz */ + .clkpllCz = 1, /*!< pll_cz */ + .clkpllC3 = 2, /*!< pll_c3 */ + .clkpllR4Short = 1, /*!< pll_r4_short */ + .clkpllC4En = 0, /*!< pll_r4_en */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 5, /*!< pll_vco_speed */ + .clkpllSdmCtrlHw = 1, /*!< pll_sdm_ctrl_hw */ + .clkpllSdmBypass = 1, /*!< pll_sdm_bypass */ +}; +const GLB_WAC_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION wifiPllBasicCfg_26M = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllIntFracSw = 1, /*!< pll_int_frac_sw */ + .clkpllIcp1u = 1, /*!< pll_icp_1u */ + .clkpllIcp5u = 0, /*!< pll_icp_5u */ + .clkpllRz = 5, /*!< pll_rz */ + .clkpllCz = 2, /*!< pll_cz */ + .clkpllC3 = 2, /*!< pll_c3 */ + .clkpllR4Short = 0, /*!< pll_r4_short */ + .clkpllC4En = 1, /*!< pll_r4_en */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 5, /*!< pll_vco_speed */ + .clkpllSdmCtrlHw = 0, /*!< pll_sdm_ctrl_hw */ + .clkpllSdmBypass = 0, /*!< pll_sdm_bypass */ +}; +const GLB_WAC_PLL_Cfg_Type ATTR_CLOCK_CONST_SECTION wifiPllCfg_960M[GLB_XTAL_MAX] = { + { NULL, 0x0 }, /*!< XTAL is None */ + { &wifiPllBasicCfg_24M, 0x1400000 }, /*!< XTAL is 24M */ + { &wifiPllBasicCfg_32M_38P4M_40M, 0x1E00000 }, /*!< XTAL is 32M */ + { &wifiPllBasicCfg_32M_38P4M_40M, 0x1900000 }, /*!< XTAL is 38.4M */ + { &wifiPllBasicCfg_32M_38P4M_40M, 0x1800000 }, /*!< XTAL is 40M */ + { &wifiPllBasicCfg_26M, 0x1276276 }, /*!< XTAL is 26M */ + { &wifiPllBasicCfg_32M_38P4M_40M, 0x1E00000 }, /*!< XTAL is RC32M */ +}; + +/* Audio PLL Config*/ +const GLB_WAC_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION audioPllBasicCfg_24M_26M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllIntFracSw = 1, /*!< pll_int_frac_sw */ + .clkpllIcp1u = 1, /*!< pll_icp_1u */ + .clkpllIcp5u = 0, /*!< pll_icp_5u */ + .clkpllRz = 5, /*!< pll_rz */ + .clkpllCz = 2, /*!< pll_cz */ + .clkpllC3 = 2, /*!< pll_c3 */ + .clkpllR4Short = 0, /*!< pll_r4_short */ + .clkpllC4En = 1, /*!< pll_r4_en */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 3, /*!< pll_vco_speed */ + .clkpllSdmCtrlHw = 0, /*!< pll_sdm_ctrl_hw */ + .clkpllSdmBypass = 0, /*!< pll_sdm_bypass */ +}; +const GLB_WAC_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION audioPllBasicCfg_32M_38P4M_40M = { + .clkpllRefdivRatio = 4, /*!< pll_refdiv_ratio */ + .clkpllIntFracSw = 1, /*!< pll_int_frac_sw */ + .clkpllIcp1u = 1, /*!< pll_icp_1u */ + .clkpllIcp5u = 0, /*!< pll_icp_5u */ + .clkpllRz = 5, /*!< pll_rz */ + .clkpllCz = 2, /*!< pll_cz */ + .clkpllC3 = 2, /*!< pll_c3 */ + .clkpllR4Short = 0, /*!< pll_r4_short */ + .clkpllC4En = 1, /*!< pll_r4_en */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 3, /*!< pll_vco_speed */ + .clkpllSdmCtrlHw = 0, /*!< pll_sdm_ctrl_hw */ + .clkpllSdmBypass = 0, /*!< pll_sdm_bypass */ +}; +const GLB_WAC_PLL_Cfg_Type ATTR_CLOCK_CONST_SECTION audioPllCfg_442P368M[GLB_XTAL_MAX] = { + { NULL, 0x0 }, /*!< XTAL is None */ + { &audioPllBasicCfg_24M_26M, 0x126E9 }, /*!< XTAL is 24M */ + { &audioPllBasicCfg_32M_38P4M_40M, 0x1BA5E }, /*!< XTAL is 32M */ + { &audioPllBasicCfg_32M_38P4M_40M, 0x170A3 }, /*!< XTAL is 38.4M */ + { &audioPllBasicCfg_32M_38P4M_40M, 0x161E5 }, /*!< XTAL is 40M */ + { &audioPllBasicCfg_24M_26M, 0x1103A }, /*!< XTAL is 26M */ + { &audioPllBasicCfg_32M_38P4M_40M, 0x1BA5E }, /*!< XTAL is RC32M */ +}; +const GLB_WAC_PLL_Cfg_Type ATTR_CLOCK_CONST_SECTION audioPllCfg_451P584M[GLB_XTAL_MAX] = { + { NULL, 0x0 }, /*!< XTAL is None */ + { &audioPllBasicCfg_24M_26M, 0x12D0E }, /*!< XTAL is 24M */ + { &audioPllBasicCfg_32M_38P4M_40M, 0x1C395 }, /*!< XTAL is 32M */ + { &audioPllBasicCfg_32M_38P4M_40M, 0x17851 }, /*!< XTAL is 38.4M */ + { &audioPllBasicCfg_32M_38P4M_40M, 0x16944 }, /*!< XTAL is 40M */ + { &audioPllBasicCfg_24M_26M, 0x115E5 }, /*!< XTAL is 26M */ + { &audioPllBasicCfg_32M_38P4M_40M, 0x1C395 }, /*!< XTAL is RC32M */ +}; + +/* CPU PLL Config*/ +const GLB_WAC_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION cpuPllBasicCfg_24M_26M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllIntFracSw = 1, /*!< pll_int_frac_sw */ + .clkpllIcp1u = 1, /*!< pll_icp_1u */ + .clkpllIcp5u = 0, /*!< pll_icp_5u */ + .clkpllRz = 5, /*!< pll_rz */ + .clkpllCz = 2, /*!< pll_cz */ + .clkpllC3 = 2, /*!< pll_c3 */ + .clkpllR4Short = 0, /*!< pll_r4_short */ + .clkpllC4En = 1, /*!< pll_r4_en */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 3, /*!< pll_vco_speed */ + .clkpllSdmCtrlHw = 0, /*!< pll_sdm_ctrl_hw */ + .clkpllSdmBypass = 0, /*!< pll_sdm_bypass */ +}; +const GLB_WAC_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION cpuPllBasicCfg_32M_38P4M_40M = { + .clkpllRefdivRatio = 4, /*!< pll_refdiv_ratio */ + .clkpllIntFracSw = 1, /*!< pll_int_frac_sw */ + .clkpllIcp1u = 1, /*!< pll_icp_1u */ + .clkpllIcp5u = 0, /*!< pll_icp_5u */ + .clkpllRz = 5, /*!< pll_rz */ + .clkpllCz = 2, /*!< pll_cz */ + .clkpllC3 = 2, /*!< pll_c3 */ + .clkpllR4Short = 0, /*!< pll_r4_short */ + .clkpllC4En = 1, /*!< pll_r4_en */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 3, /*!< pll_vco_speed */ + .clkpllSdmCtrlHw = 0, /*!< pll_sdm_ctrl_hw */ + .clkpllSdmBypass = 0, /*!< pll_sdm_bypass */ +}; +const GLB_WAC_PLL_Cfg_Type ATTR_CLOCK_CONST_SECTION cpuPllCfg_380M[GLB_XTAL_MAX] = { + { NULL, 0x0 }, /*!< XTAL is None */ + { &cpuPllBasicCfg_24M_26M, 0xFD55 }, /*!< XTAL is 24M */ + { &cpuPllBasicCfg_32M_38P4M_40M, 0x17C00 }, /*!< XTAL is 32M */ + { &cpuPllBasicCfg_32M_38P4M_40M, 0x13CAA }, /*!< XTAL is 38.4M */ + { &cpuPllBasicCfg_32M_38P4M_40M, 0x13000 }, /*!< XTAL is 40M */ + { &cpuPllBasicCfg_24M_26M, 0xE9D8 }, /*!< XTAL is 26M */ + { &cpuPllBasicCfg_32M_38P4M_40M, 0x17C00 }, /*!< XTAL is RC32M */ +}; +const GLB_WAC_PLL_Cfg_Type ATTR_CLOCK_CONST_SECTION cpuPllCfg_400M[GLB_XTAL_MAX] = { + { NULL, 0x0 }, /*!< XTAL is None */ + { &cpuPllBasicCfg_24M_26M, 0x10AAA }, /*!< XTAL is 24M */ + { &cpuPllBasicCfg_32M_38P4M_40M, 0x19000 }, /*!< XTAL is 32M */ + { &cpuPllBasicCfg_32M_38P4M_40M, 0x14D55 }, /*!< XTAL is 38.4M */ + { &cpuPllBasicCfg_32M_38P4M_40M, 0x14000 }, /*!< XTAL is 40M */ + { &cpuPllBasicCfg_24M_26M, 0xF627 }, /*!< XTAL is 26M */ + { &cpuPllBasicCfg_32M_38P4M_40M, 0x19000 }, /*!< XTAL is RC32M */ +}; +const GLB_WAC_PLL_Cfg_Type ATTR_CLOCK_CONST_SECTION cpuPllCfg_480M[GLB_XTAL_MAX] = { + { NULL, 0x0 }, /*!< XTAL is None */ + { &cpuPllBasicCfg_24M_26M, 0x14000 }, /*!< XTAL is 24M */ + { &cpuPllBasicCfg_32M_38P4M_40M, 0x1E000 }, /*!< XTAL is 32M */ + { &cpuPllBasicCfg_32M_38P4M_40M, 0x19000 }, /*!< XTAL is 38.4M */ + { &cpuPllBasicCfg_32M_38P4M_40M, 0x18000 }, /*!< XTAL is 40M */ + { &cpuPllBasicCfg_24M_26M, 0x12762 }, /*!< XTAL is 26M */ + { &cpuPllBasicCfg_32M_38P4M_40M, 0x1E000 }, /*!< XTAL is RC32M */ +}; + +/* MIPI PLL Config*/ +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION mipiPllBasicCfg_24M = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 5, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 0, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 0, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION mipiPllBasicCfg_32M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 5, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 0, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 0, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION mipiPllBasicCfg_38P4M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 5, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 0, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 0, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION mipiPllBasicCfg_40M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 5, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 0, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 0, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION mipiPllBasicCfg_26M = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 5, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 0, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 0, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_Cfg_Type ATTR_CLOCK_CONST_SECTION mipiPllCfg_1500M[GLB_XTAL_MAX] = { + { NULL, 0x0 }, /*!< XTAL is None */ + { &mipiPllBasicCfg_24M, 0x1F400 }, /*!< XTAL is 24M */ + { &mipiPllBasicCfg_32M, 0x2EE00 }, /*!< XTAL is 32M */ + { &mipiPllBasicCfg_38P4M, 0x27100 }, /*!< XTAL is 38.4M */ + { &mipiPllBasicCfg_40M, 0x25800 }, /*!< XTAL is 40M */ + { &mipiPllBasicCfg_26M, 0x1CD89 }, /*!< XTAL is 26M */ + { &mipiPllBasicCfg_32M, 0x2EE00 }, /*!< XTAL is RC32M */ +}; + +/* uhs PLL 2100 Config*/ +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll2100BasicCfg_24M = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 7, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 2100/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll2100BasicCfg_32M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 7, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 2100/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll2100BasicCfg_38P4M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 7, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 2100/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll2100BasicCfg_40M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 7, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 2100/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll2100BasicCfg_26M = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 7, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 2100/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_Cfg_Type ATTR_CLOCK_CONST_SECTION uhsPllCfg_2100M[GLB_XTAL_MAX] = { + { NULL, 0x0 }, /*!< XTAL is None */ + { &uhsPll2100BasicCfg_24M, 0x2BC00 }, /*!< XTAL is 24M */ + { &uhsPll2100BasicCfg_32M, 0x41A00 }, /*!< XTAL is 32M */ + { &uhsPll2100BasicCfg_38P4M, 0x36B00 }, /*!< XTAL is 38.4M */ + { &uhsPll2100BasicCfg_40M, 0x34800 }, /*!< XTAL is 40M */ + { &uhsPll2100BasicCfg_26M, 0x28627 }, /*!< XTAL is 26M */ + { &uhsPll2100BasicCfg_32M, 0x41A00 }, /*!< XTAL is RC32M */ +}; + +/* uhs PLL 1400 Config*/ +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll1400MCfg_24M = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 4, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 1400/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll1400MCfg_32M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 4, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 1400/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll1400MCfg_38P4M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 4, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 1400/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll1400MCfg_40M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 4, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 1400/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll1400MCfg_26M = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 4, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 1400/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_Cfg_Type ATTR_CLOCK_CONST_SECTION uhsPllCfg_1400M[GLB_XTAL_MAX] = { + { NULL, 0x0 }, /*!< XTAL is None */ + { &uhsPll1400MCfg_24M, 0x1D2AA }, /*!< XTAL is 24M */ + { &uhsPll1400MCfg_32M, 0x2BC00 }, /*!< XTAL is 32M */ + { &uhsPll1400MCfg_38P4M, 0x24755 }, /*!< XTAL is 38.4M */ + { &uhsPll1400MCfg_40M, 0x23000 }, /*!< XTAL is 40M */ + { &uhsPll1400MCfg_26M, 0x1AEC4 }, /*!< XTAL is 26M */ + { &uhsPll1400MCfg_32M, 0x2BC00 }, /*!< XTAL is RC32M */ +}; + +/* uhs PLL 1500 Config*/ +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll1500MCfg_24M = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 5, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 1500/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll1500MCfg_32M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 5, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 1500/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll1500MCfg_38P4M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 5, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 1500/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll1500MCfg_40M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 5, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 1500/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll1500MCfg_26M = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 5, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 1500/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_Cfg_Type ATTR_CLOCK_CONST_SECTION uhsPllCfg_1500M[GLB_XTAL_MAX] = { + { NULL, 0x0 }, /*!< XTAL is None */ + { &uhsPll1500MCfg_24M, 0x1F400 }, /*!< XTAL is 24M */ + { &uhsPll1500MCfg_32M, 0x2EE00 }, /*!< XTAL is 32M */ + { &uhsPll1500MCfg_38P4M, 0x27100 }, /*!< XTAL is 38.4M */ + { &uhsPll1500MCfg_40M, 0x25800 }, /*!< XTAL is 40M */ + { &uhsPll1500MCfg_26M, 0x1CD89 }, /*!< XTAL is 26M */ + { &uhsPll1500MCfg_32M, 0x2EE00 }, /*!< XTAL is RC32M */ +}; + +/* uhs PLL 1600 Config*/ +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll1600BasicCfg_24M = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 5, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 1600/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll1600BasicCfg_32M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 5, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 1600/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll1600BasicCfg_38P4M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 5, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 1600/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll1600BasicCfg_40M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 5, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 1600/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll1600BasicCfg_26M = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 5, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 1600/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_Cfg_Type ATTR_CLOCK_CONST_SECTION uhsPllCfg_1600M[GLB_XTAL_MAX] = { + { NULL, 0x0 }, /*!< XTAL is None */ + { &uhsPll1600BasicCfg_24M, 0x21555 }, /*!< XTAL is 24M */ + { &uhsPll1600BasicCfg_32M, 0x32000 }, /*!< XTAL is 32M */ + { &uhsPll1600BasicCfg_38P4M, 0x29AAA }, /*!< XTAL is 38.4M */ + { &uhsPll1600BasicCfg_40M, 0x28000 }, /*!< XTAL is 40M */ + { &uhsPll1600BasicCfg_26M, 0x1EC4E }, /*!< XTAL is 26M */ + { &uhsPll1600BasicCfg_32M, 0x32000 }, /*!< XTAL is RC32M */ +}; + +/* uhs PLL 400 Config*/ +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll400BasicCfg_24M = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 0, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 1, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 400/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll400BasicCfg_32M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 0, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 1, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 400/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll400BasicCfg_38P4M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 0, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 1, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 400/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll400BasicCfg_40M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 0, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 1, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 400/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll400BasicCfg_26M = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 0, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 1, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 400/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_Cfg_Type ATTR_CLOCK_CONST_SECTION uhsPllCfg_400M[GLB_XTAL_MAX] = { + { NULL, 0x0 }, /*!< XTAL is None */ + { &uhsPll400BasicCfg_24M, 0x8555 }, /*!< XTAL is 24M */ + { &uhsPll400BasicCfg_32M, 0xC800 }, /*!< XTAL is 32M */ + { &uhsPll400BasicCfg_38P4M, 0xA6AA }, /*!< XTAL is 38.4M */ + { &uhsPll400BasicCfg_40M, 0xA000 }, /*!< XTAL is 40M */ + { &uhsPll400BasicCfg_26M, 0x7B13 }, /*!< XTAL is 26M */ + { &uhsPll400BasicCfg_32M, 0xC800 }, /*!< XTAL is RC32M */ +}; + +/* uhs PLL 667 Config*/ +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll667BasicCfg_24M = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 0, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 1, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 667/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll667BasicCfg_32M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 1, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 667/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll667BasicCfg_38P4M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 1, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 667/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll667BasicCfg_40M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 1, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 667/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll667BasicCfg_26M = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 0, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 1, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 667/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_Cfg_Type ATTR_CLOCK_CONST_SECTION uhsPllCfg_667M[GLB_XTAL_MAX] = { + { NULL, 0x0 }, /*!< XTAL is None */ + { &uhsPll667BasicCfg_24M, 0xDE55 }, /*!< XTAL is 24M */ + { &uhsPll667BasicCfg_32M, 0x14D80 }, /*!< XTAL is 32M */ + { &uhsPll667BasicCfg_38P4M, 0x115EA }, /*!< XTAL is 38.4M */ + { &uhsPll667BasicCfg_40M, 0x10ACC }, /*!< XTAL is 40M */ + { &uhsPll667BasicCfg_26M, 0xCD3B }, /*!< XTAL is 26M */ + { &uhsPll667BasicCfg_32M, 0x14D80 }, /*!< XTAL is RC32M */ +}; + +/* uhs PLL 800 Config*/ +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll800BasicCfg_24M = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 2, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 800/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll800BasicCfg_32M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 2, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 800/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll800BasicCfg_38P4M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 2, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 800/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll800BasicCfg_40M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 2, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 800/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll800BasicCfg_26M = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 0, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 2, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 800/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_Cfg_Type ATTR_CLOCK_CONST_SECTION uhsPllCfg_800M[GLB_XTAL_MAX] = { + { NULL, 0x0 }, /*!< XTAL is None */ + { &uhsPll800BasicCfg_24M, 0x10AAA }, /*!< XTAL is 24M */ + { &uhsPll800BasicCfg_32M, 0x19000 }, /*!< XTAL is 32M */ + { &uhsPll800BasicCfg_38P4M, 0x14D55 }, /*!< XTAL is 38.4M */ + { &uhsPll800BasicCfg_40M, 0x14000 }, /*!< XTAL is 40M */ + { &uhsPll800BasicCfg_26M, 0xF627 }, /*!< XTAL is 26M */ + { &uhsPll800BasicCfg_32M, 0x19000 }, /*!< XTAL is RC32M */ +}; + +/* uhs PLL 1066 Config*/ +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll1066BasicCfg_24M = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 3, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 1066/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll1066BasicCfg_32M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 3, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 1066/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll1066BasicCfg_38P4M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 3, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 1066/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll1066BasicCfg_40M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 3, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 1066/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll1066BasicCfg_26M = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 1, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 3, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 1066/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_Cfg_Type ATTR_CLOCK_CONST_SECTION uhsPllCfg_1066M[GLB_XTAL_MAX] = { + { NULL, 0x0 }, /*!< XTAL is None */ + { &uhsPll1066BasicCfg_24M, 0x16355 }, /*!< XTAL is 24M */ + { &uhsPll1066BasicCfg_32M, 0x21500 }, /*!< XTAL is 32M */ + { &uhsPll1066BasicCfg_38P4M, 0x1BC2A }, /*!< XTAL is 38.4M */ + { &uhsPll1066BasicCfg_40M, 0x1AA66 }, /*!< XTAL is 40M */ + { &uhsPll1066BasicCfg_26M, 0x14800 }, /*!< XTAL is 26M */ + { &uhsPll1066BasicCfg_32M, 0x21500 }, /*!< XTAL is RC32M */ +}; + +/* uhs PLL 2000 Config*/ +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll2000BasicCfg_24M = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 7, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 2000/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll2000BasicCfg_32M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 7, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 2000/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll2000BasicCfg_38P4M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 7, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 2000/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll2000BasicCfg_40M = { + .clkpllRefdivRatio = 2, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 7, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 2000/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION uhsPll2000BasicCfg_26M = { + .clkpllRefdivRatio = 1, /*!< pll_refdiv_ratio */ + .clkpllSelSampleClk = 2, /*!< pll_sel_sample_clk */ + .clkpllVcoSpeed = 7, /*!< pll_vco_speed */ + .clkpllEvenDivEn = 1, /*!< pll_even_div_en */ + .clkpllEvenDivRatio = 2000/50, /*!< pll_even_div_ratio */ +}; +const GLB_MU_PLL_Cfg_Type ATTR_CLOCK_CONST_SECTION uhsPllCfg_2000M[GLB_XTAL_MAX] = { + { NULL, 0x0 }, /*!< XTAL is None */ + { &uhsPll2000BasicCfg_24M, 0x29AAA }, /*!< XTAL is 24M */ + { &uhsPll2000BasicCfg_32M, 0x3E800 }, /*!< XTAL is 32M */ + { &uhsPll2000BasicCfg_38P4M, 0x34155 }, /*!< XTAL is 38.4M */ + { &uhsPll2000BasicCfg_40M, 0x32000 }, /*!< XTAL is 40M */ + { &uhsPll2000BasicCfg_26M, 0x26762 }, /*!< XTAL is 26M */ + { &uhsPll2000BasicCfg_32M, 0x3E800 }, /*!< XTAL is RC32M */ +}; + +/*@} end of group GLB_Private_Variables */ + +/** @defgroup GLB_Global_Variables + * @{ + */ + +/*@} end of group GLB_Global_Variables */ + +/** @defgroup GLB_Private_Fun_Declaration + * @{ + */ + +/*@} end of group GLB_Private_Fun_Declaration */ + +/** @defgroup GLB_Private_Functions + * @{ + */ + +/*@} end of group GLB_Private_Functions */ + +/** @defgroup GLB_Public_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief set mcu muxpll 160M selection + * + * @param clkSel: clock selection + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Set_MCU_Muxpll_160M_Sel(GLB_MCU_MUXPLL_160M_CLK_SEL_Type clkSel) +{ + uint32_t tmpVal; + + CHECK_PARAM(IS_GLB_MCU_MUXPLL_160M_CLK_SEL_TYPE(clkSel)); + + tmpVal = BL_RD_REG(GLB_BASE, GLB_DIG_CLK_CFG1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_REG_TOP_MUXPLL_160M_SEL, clkSel); + BL_WR_REG(GLB_BASE, GLB_DIG_CLK_CFG1, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief get mcu muxpll 160M selection + * + * @param None + * + * @return 160M mux select value + * +*******************************************************************************/ +GLB_MCU_MUXPLL_160M_CLK_SEL_Type ATTR_CLOCK_SECTION GLB_Get_MCU_Muxpll_160M_Sel(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(GLB_BASE, GLB_DIG_CLK_CFG1); + return (GLB_MCU_MUXPLL_160M_CLK_SEL_Type)(BL_GET_REG_BITS_VAL(tmpVal, GLB_REG_TOP_MUXPLL_160M_SEL)); +} + +/****************************************************************************/ /** + * @brief set top muxpll 80M selection + * + * @param clkSel: clock selection + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Set_MCU_Muxpll_80M_Sel(GLB_MCU_MUXPLL_80M_CLK_SEL_Type clkSel) +{ + uint32_t tmpVal; + + CHECK_PARAM(IS_GLB_MCU_MUXPLL_80M_CLK_SEL_TYPE(clkSel)); + + tmpVal = BL_RD_REG(GLB_BASE, GLB_DIG_CLK_CFG1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_REG_TOP_MUXPLL_80M_SEL, clkSel); + BL_WR_REG(GLB_BASE, GLB_DIG_CLK_CFG1, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief get mcu muxpll 80M selection + * + * @param None + * + * @return 80M mux select value + * +*******************************************************************************/ +GLB_MCU_MUXPLL_80M_CLK_SEL_Type ATTR_CLOCK_SECTION GLB_Get_MCU_Muxpll_80M_Sel(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(GLB_BASE, GLB_DIG_CLK_CFG1); + return (GLB_MCU_MUXPLL_80M_CLK_SEL_Type)(BL_GET_REG_BITS_VAL(tmpVal, GLB_REG_TOP_MUXPLL_80M_SEL)); +} + +/****************************************************************************/ /** + * @brief set dsp muxpll 320M selection + * + * @param clkSel: clock selection + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Set_DSP_Muxpll_320M_Sel(GLB_DSP_MUXPLL_320M_CLK_SEL_Type clkSel) +{ + uint32_t tmpVal; + + CHECK_PARAM(IS_GLB_DSP_MUXPLL_320M_CLK_SEL_TYPE(clkSel)); + + tmpVal = BL_RD_REG(GLB_BASE, GLB_DIG_CLK_CFG1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_REG_MM_MUXPLL_320M_SEL, clkSel); + BL_WR_REG(GLB_BASE, GLB_DIG_CLK_CFG1, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief get dsp muxpll 320M selection + * + * @param None + * + * @return dsp 320M mux select value + * +*******************************************************************************/ +GLB_DSP_MUXPLL_320M_CLK_SEL_Type ATTR_CLOCK_SECTION GLB_Get_DSP_Muxpll_320M_Sel(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(GLB_BASE, GLB_DIG_CLK_CFG1); + return (GLB_DSP_MUXPLL_320M_CLK_SEL_Type)(BL_GET_REG_BITS_VAL(tmpVal, GLB_REG_MM_MUXPLL_320M_SEL)); +} + +/****************************************************************************/ /** + * @brief set dsp muxpll 240M selection + * + * @param clkSel: clock selection + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Set_DSP_Muxpll_240M_Sel(GLB_DSP_MUXPLL_240M_CLK_SEL_Type clkSel) +{ + uint32_t tmpVal; + + CHECK_PARAM(IS_GLB_DSP_MUXPLL_240M_CLK_SEL_TYPE(clkSel)); + + tmpVal = BL_RD_REG(GLB_BASE, GLB_DIG_CLK_CFG1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_REG_MM_MUXPLL_240M_SEL, clkSel); + BL_WR_REG(GLB_BASE, GLB_DIG_CLK_CFG1, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief get dsp muxpll 240M selection + * + * @param None + * + * @return dsp 240M mux select value + * +*******************************************************************************/ +GLB_DSP_MUXPLL_240M_CLK_SEL_Type ATTR_CLOCK_SECTION GLB_Get_DSP_Muxpll_240M_Sel(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(GLB_BASE, GLB_DIG_CLK_CFG1); + return (GLB_DSP_MUXPLL_240M_CLK_SEL_Type)(BL_GET_REG_BITS_VAL(tmpVal, GLB_REG_MM_MUXPLL_240M_SEL)); +} + +/****************************************************************************/ /** + * @brief set dsp muxpll 160M selection + * + * @param clkSel: clock selection + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Set_DSP_Muxpll_160M_Sel(GLB_DSP_MUXPLL_160M_CLK_SEL_Type clkSel) +{ + uint32_t tmpVal; + + CHECK_PARAM(IS_GLB_DSP_MUXPLL_160M_CLK_SEL_TYPE(clkSel)); + + tmpVal = BL_RD_REG(GLB_BASE, GLB_DIG_CLK_CFG1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_REG_MM_MUXPLL_160M_SEL, clkSel); + BL_WR_REG(GLB_BASE, GLB_DIG_CLK_CFG1, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief get dsp muxpll 160M selection + * + * @param None + * + * @return dsp 160M mux select value + * +*******************************************************************************/ +GLB_DSP_MUXPLL_160M_CLK_SEL_Type ATTR_CLOCK_SECTION GLB_Get_DSP_Muxpll_160M_Sel(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(GLB_BASE, GLB_DIG_CLK_CFG1); + return (GLB_DSP_MUXPLL_160M_CLK_SEL_Type)(BL_GET_REG_BITS_VAL(tmpVal, GLB_REG_MM_MUXPLL_160M_SEL)); +} + +/****************************************************************************/ /** + * @brief power on all PLL clock + * + * @param xtalType: XTAL frequency type + * @param pllType: only power on xtal + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Power_On_XTAL_And_PLL_CLK(GLB_XTAL_Type xtalType, GLB_PLL_Type pllType) +{ + uint32_t tmpVal; + GLB_CORE_ID_Type coreType; + HBN_MCU_XCLK_Type mcuXclkSel; + HBN_MCU_ROOT_CLK_Type mcuRootClkSel; + GLB_DSP_XCLK_Type dspXclkSel; + GLB_DSP_ROOT_CLK_Type dspRootClkSel; + volatile GLB_PLL_REF_CLK_Type refClk; + + CHECK_PARAM(IS_GLB_XTAL_TYPE(xtalType)); + CHECK_PARAM((pllType < (GLB_PLL_UHSPLL * 2))); + + if (xtalType == GLB_XTAL_NONE) { + return ERROR; + } + + if (xtalType != GLB_XTAL_RC32M) { + /* power on xtal first */ + AON_Power_On_XTAL(); + } + + coreType = GLB_Get_Core_Type(); + if ((GLB_CORE_ID_D0 == coreType)) { + /* D0 */ + /* Before config XTAL and PLL ,make sure root clk is from RC32M */ + dspXclkSel = GLB_Get_DSP_XCLK_Sel(); + dspRootClkSel = GLB_Get_DSP_ROOT_CLK_Sel(); + if ((dspXclkSel != GLB_DSP_XCLK_RC32M) || (dspRootClkSel != GLB_DSP_ROOT_CLK_XCLK)) { + GLB_Set_DSP_XCLK_Sel(GLB_DSP_XCLK_RC32M); + GLB_Set_DSP_ROOT_CLK_Sel(GLB_DSP_ROOT_CLK_XCLK); + } + GLB_Set_DSP_System_CLK_Div(0, 0); + } else { + /* M0 or LP or invalid(use M0 instead) */ + /* Before config XTAL and PLL ,make sure root clk is from RC32M */ + mcuXclkSel = HBN_Get_MCU_XCLK_Sel(); + mcuRootClkSel = HBN_Get_MCU_Root_CLK_Sel(); + if ((mcuXclkSel != HBN_MCU_XCLK_RC32M) || (mcuRootClkSel != HBN_MCU_ROOT_CLK_XCLK)) { + HBN_Set_MCU_XCLK_Sel(HBN_MCU_XCLK_RC32M); + HBN_Set_MCU_Root_CLK_Sel(HBN_MCU_ROOT_CLK_XCLK); + } + GLB_Set_MCU_System_CLK_Div(0, 0, 0); + } + + HBN_Set_Xtal_Type(xtalType); + + if (GLB_PLL_NONE == pllType) { + GLB_CLK_SET_DUMMY_WAIT; + return SUCCESS; + } + + if (xtalType == GLB_XTAL_RC32M) { + refClk = GLB_PLL_REFCLK_RC32M; + } else { + refClk = GLB_PLL_REFCLK_XTAL; + } + + /* power on wifipll */ + if (pllType & GLB_PLL_WIFIPLL) { + GLB_Power_Off_WAC_PLL(GLB_WAC_PLL_WIFIPLL); + GLB_WAC_PLL_Ref_Clk_Sel(GLB_WAC_PLL_WIFIPLL, refClk); + GLB_Power_On_WAC_PLL(GLB_WAC_PLL_WIFIPLL, &wifiPllCfg_960M[xtalType], 0); + } + + /* power on aupll */ + if (pllType & GLB_PLL_AUPLL) { + GLB_Power_Off_WAC_PLL(GLB_WAC_PLL_AUPLL); + GLB_WAC_PLL_Ref_Clk_Sel(GLB_WAC_PLL_AUPLL, refClk); + GLB_Power_On_WAC_PLL(GLB_WAC_PLL_AUPLL, &audioPllCfg_442P368M[xtalType], 0); + } + + /* power on cpupll */ + if (pllType & GLB_PLL_CPUPLL) { + GLB_Power_Off_WAC_PLL(GLB_WAC_PLL_CPUPLL); + GLB_WAC_PLL_Ref_Clk_Sel(GLB_WAC_PLL_CPUPLL, refClk); + GLB_Power_On_WAC_PLL(GLB_WAC_PLL_CPUPLL, &cpuPllCfg_380M[xtalType], 0); + } + + /* power on mipipll */ + if (pllType & GLB_PLL_MIPIPLL) { + GLB_Power_Off_MU_PLL(GLB_MU_PLL_MIPIPLL); + GLB_MU_PLL_Ref_Clk_Sel(GLB_MU_PLL_MIPIPLL, refClk); + GLB_Power_On_MU_PLL(GLB_MU_PLL_MIPIPLL, &mipiPllCfg_1500M[xtalType], 0); + } + + /* power on uhspll */ + if (pllType & GLB_PLL_UHSPLL) { + GLB_Power_Off_MU_PLL(GLB_MU_PLL_UHSPLL); + GLB_MU_PLL_Ref_Clk_Sel(GLB_MU_PLL_UHSPLL, refClk); + GLB_Power_On_MU_PLL(GLB_MU_PLL_UHSPLL, &uhsPllCfg_2100M[xtalType], 0); + } + + arch_delay_us(75); + + if (xtalType != GLB_XTAL_RC32M) { + /* if power on xtal, always set xclk from xtal */ + HBN_Set_MCU_XCLK_Sel(HBN_MCU_XCLK_XTAL); + GLB_Set_DSP_XCLK_Sel(GLB_DSP_XCLK_XTAL); + } + + /* enable all PLL clock output */ + /* GLB reg_pll_en = 1, cannot be zero */ + tmpVal = BL_RD_REG(GLB_BASE, GLB_SYS_CFG0); + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_REG_PLL_EN); + BL_WR_REG(GLB_BASE, GLB_SYS_CFG0, tmpVal); + /* MM_GLB reg_pll_en = 1, cannot be zero */ + tmpVal = BL_RD_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CTRL_CPU); + tmpVal = BL_SET_REG_BIT(tmpVal, MM_GLB_REG_PLL_EN); + BL_WR_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CTRL_CPU, tmpVal); + + GLB_CLK_SET_DUMMY_WAIT; + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief GLB power off wifi audio cpu PLL + * + * @param pllType: PLL XTAL type + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Power_Off_WAC_PLL(GLB_WAC_PLL_Type pllType) +{ + uint32_t REG_PLL_BASE_ADDRESS = 0; + uint32_t tmpVal = 0; + + CHECK_PARAM(IS_GLB_WAC_PLL_TYPE(pllType)); + + switch (pllType) { + case GLB_WAC_PLL_WIFIPLL: + REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_WIFI_PLL_CFG0_OFFSET; + break; + case GLB_WAC_PLL_AUPLL: + REG_PLL_BASE_ADDRESS = CCI_BASE + CCI_AUDIO_PLL_CFG0_OFFSET; + break; + case GLB_WAC_PLL_CPUPLL: + REG_PLL_BASE_ADDRESS = CCI_BASE + CCI_CPU_PLL_CFG0_OFFSET; + break; + default: + REG_PLL_BASE_ADDRESS = CCI_BASE + CCI_AUDIO_PLL_CFG0_OFFSET; + break; + } + + /* cfg0 : pu_aupll=0 */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_PU_AUPLL, 0); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + + /* cfg0 : pu_aupll_sfreg=0 */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_PU_AUPLL_SFREG, 0); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief GLB wifi audio cpu PLL ref clock select + * + * @param pllType: PLL XTAL type + * @param refClk: PLL ref clock select + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_WAC_PLL_Ref_Clk_Sel(GLB_WAC_PLL_Type pllType, GLB_PLL_REF_CLK_Type refClk) +{ + uint32_t REG_PLL_BASE_ADDRESS = 0; + uint32_t tmpVal = 0; + + CHECK_PARAM(IS_GLB_WAC_PLL_TYPE(pllType)); + CHECK_PARAM(IS_GLB_PLL_REF_CLK_TYPE(refClk)); + + switch (pllType) { + case GLB_WAC_PLL_WIFIPLL: + REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_WIFI_PLL_CFG0_OFFSET; + break; + case GLB_WAC_PLL_AUPLL: + REG_PLL_BASE_ADDRESS = CCI_BASE + CCI_AUDIO_PLL_CFG0_OFFSET; + break; + case GLB_WAC_PLL_CPUPLL: + REG_PLL_BASE_ADDRESS = CCI_BASE + CCI_CPU_PLL_CFG0_OFFSET; + break; + default: + REG_PLL_BASE_ADDRESS = CCI_BASE + CCI_AUDIO_PLL_CFG0_OFFSET; + break; + } + + /* xxxpll_refclk_sel */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 1); + if ((GLB_WAC_PLL_WIFIPLL == pllType) && (GLB_PLL_REFCLK_XTAL == refClk)) { + /* wifipll_refclk_sel different from other's pll, 1 means xtal */ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_REFCLK_SEL, 1); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_REFCLK_SEL, refClk); + } + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 1, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief GLB power on PLL + * + * @param pllType: PLL XTAL type + * @param cfg: GLB PLL configuration + * @param waitStable: wait PLL clock stable + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Power_On_WAC_PLL(GLB_WAC_PLL_Type pllType, const GLB_WAC_PLL_Cfg_Type *const cfg, uint8_t waitStable) +{ + uint32_t REG_PLL_BASE_ADDRESS = 0; + uint32_t tmpVal = 0; + + /* unknown */ + CHECK_PARAM(IS_GLB_WAC_PLL_TYPE(pllType)); + + switch (pllType) { + case GLB_WAC_PLL_WIFIPLL: + REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_WIFI_PLL_CFG0_OFFSET; + break; + case GLB_WAC_PLL_AUPLL: + REG_PLL_BASE_ADDRESS = CCI_BASE + CCI_AUDIO_PLL_CFG0_OFFSET; + break; + case GLB_WAC_PLL_CPUPLL: + REG_PLL_BASE_ADDRESS = CCI_BASE + CCI_CPU_PLL_CFG0_OFFSET; + break; + default: + REG_PLL_BASE_ADDRESS = CCI_BASE + CCI_AUDIO_PLL_CFG0_OFFSET; + break; + } + + /* Step1:config parameter */ + /* cfg1:Set aupll_refclk_sel and aupll_refdiv_ratio */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_REFDIV_RATIO, cfg->basicCfg->clkpllRefdivRatio); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 1, tmpVal); + + /* cfg2:Set aupll_int_frac_sw,aupll_icp_1u,aupll_icp_5u */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_INT_FRAC_SW, cfg->basicCfg->clkpllIntFracSw); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_ICP_1U, cfg->basicCfg->clkpllIcp1u); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_ICP_5U, cfg->basicCfg->clkpllIcp5u); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 2, tmpVal); + + /* cfg3:Set aupll_rz,aupll_cz,aupll_c3,aupll_r4_short,aupll_r4_en */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 3); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_RZ, cfg->basicCfg->clkpllRz); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_CZ, cfg->basicCfg->clkpllCz); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_C3, cfg->basicCfg->clkpllC3); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_R4_SHORT, cfg->basicCfg->clkpllR4Short); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_C4_EN, cfg->basicCfg->clkpllC4En); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 3, tmpVal); + + /* cfg4:Set aupll_sel_sample_clk */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 4); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_SEL_SAMPLE_CLK, cfg->basicCfg->clkpllSelSampleClk); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 4, tmpVal); + + /* cfg5:Set aupll_vco_speed */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 5); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_VCO_SPEED, cfg->basicCfg->clkpllVcoSpeed); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 5, tmpVal); + + /* cfg6:Set aupll_sdm_bypass,aupll_sdmin */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 6); + if (GLB_WAC_PLL_WIFIPLL == pllType) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_SDM_CTRL_HW, cfg->basicCfg->clkpllSdmCtrlHw); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_SDM_BYPASS, cfg->basicCfg->clkpllSdmBypass); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_SDMIN, cfg->clkpllSdmin); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_SDM_BYPASS, cfg->basicCfg->clkpllSdmBypass); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_SDMIN, cfg->clkpllSdmin); + } + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 6, tmpVal); + + /* Step2:config pu */ + /* cfg0 : pu_aupll_sfreg=1 */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_PU_AUPLL_SFREG, 1); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + + /* delay > 2us */ + arch_delay_us(3); + + /* cfg0 : pu_wifipll=1 */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_PU_AUPLL, 1); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + + /* delay > 2us */ + arch_delay_us(3); + + /* toggle sdm_reset (pulse 0 > 1us) */ + /* cfg0 : aupll_sdm_reset */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_SDM_RSTB, 1); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + arch_delay_us(2); + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_SDM_RSTB, 0); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + arch_delay_us(2); + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_SDM_RSTB, 1); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + + /* Step3:reset pll */ + /* cfg0 : toggle aupll_reset_fbdv, pulse 0 > 1us */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_FBDV_RSTB, 1); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + arch_delay_us(2); + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_FBDV_RSTB, 0); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + arch_delay_us(2); + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_FBDV_RSTB, 1); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + + /* aupll : cfg1, aupll_postdiv = 0x12 or 0x14 */ + if (GLB_WAC_PLL_AUPLL == pllType) { + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 1); + if ((cfg->clkpllSdmin==0x12D0E)||(cfg->clkpllSdmin==0x1C395)||(cfg->clkpllSdmin==0x17851)||(cfg->clkpllSdmin==0x16944)||(cfg->clkpllSdmin==0x115E5)) { + /* 451.548 */ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_POSTDIV, 0x14); + } else { + /* 442.368 */ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_POSTDIV, 0x12); + } + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 1, tmpVal); + } + + /* Step4:enable output clock */ + /* wifipll : cfg5, wifipll_vco_div3_en=1 */ + if (GLB_WAC_PLL_WIFIPLL == pllType) { + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 5); + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_WIFIPLL_VCO_DIV3_EN); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 5, tmpVal); + } + /* cfg8 : wifipll->wifipll_en_ctrl_hw=1 */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 8); + if (GLB_WAC_PLL_WIFIPLL == pllType) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_EN_CTRL_HW, 1); + } + /* cfg8 : wifipll/aupll/cpupll clock enable */ + switch (pllType) { + case GLB_WAC_PLL_WIFIPLL: + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_WIFIPLL_EN_DIV4); + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_WIFIPLL_EN_DIV5); + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_WIFIPLL_EN_DIV6); + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_WIFIPLL_EN_DIV8); + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_WIFIPLL_EN_DIV10); + break; + case GLB_WAC_PLL_AUPLL: + tmpVal = BL_SET_REG_BIT(tmpVal, CCI_AUPLL_EN_DIV1); + tmpVal = BL_SET_REG_BIT(tmpVal, CCI_AUPLL_EN_DIV2); + tmpVal = BL_SET_REG_BIT(tmpVal, CCI_AUPLL_EN_DIV2P5); + tmpVal = BL_SET_REG_BIT(tmpVal, CCI_AUPLL_EN_DIV5); + tmpVal = BL_SET_REG_BIT(tmpVal, CCI_AUPLL_EN_DIV6); + break; + case GLB_WAC_PLL_CPUPLL: + tmpVal = BL_SET_REG_BIT(tmpVal, CCI_CPUPLL_EN_DIV1); + tmpVal = BL_SET_REG_BIT(tmpVal, CCI_CPUPLL_EN_DIV2); + tmpVal = BL_SET_REG_BIT(tmpVal, CCI_CPUPLL_EN_DIV2P5); + tmpVal = BL_SET_REG_BIT(tmpVal, CCI_CPUPLL_EN_DIV4); + tmpVal = BL_SET_REG_BIT(tmpVal, CCI_CPUPLL_EN_DIV5); + break; + default: + break; + } + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 8, tmpVal); + + if (waitStable) { + /* Wait 1.5*30us */ + arch_delay_us(45); + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief GLB enable or disable USB clock + * + * @param enable: ENABLE or DISABLE + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Set_USB_CLK_From_WIFIPLL(uint8_t enable) +{ + uint32_t tmpVal = 0; + + /* pu_usbpll_mmdiv */ + tmpVal = BL_RD_REG(GLB_BASE, GLB_WIFI_PLL_CFG10); + if (enable) { + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_PU_USBPLL_MMDIV); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, GLB_PU_USBPLL_MMDIV); + } + BL_WR_REG(GLB_BASE, GLB_WIFI_PLL_CFG10, tmpVal); + + /* toggle usbpll_rstb */ + tmpVal = BL_RD_REG(GLB_BASE, GLB_WIFI_PLL_CFG10); + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_USBPLL_RSTB); + BL_WR_REG(GLB_BASE, GLB_WIFI_PLL_CFG10, tmpVal); + arch_delay_us(2); + tmpVal = BL_RD_REG(GLB_BASE, GLB_WIFI_PLL_CFG10); + tmpVal = BL_CLR_REG_BIT(tmpVal, GLB_USBPLL_RSTB); + BL_WR_REG(GLB_BASE, GLB_WIFI_PLL_CFG10, tmpVal); + arch_delay_us(2); + tmpVal = BL_RD_REG(GLB_BASE, GLB_WIFI_PLL_CFG10); + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_USBPLL_RSTB); + BL_WR_REG(GLB_BASE, GLB_WIFI_PLL_CFG10, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief GLB power off mipi uhs PLL + * + * @param pllType: PLL XTAL type + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Power_Off_MU_PLL(GLB_MU_PLL_Type pllType) +{ + uint32_t REG_PLL_BASE_ADDRESS = 0; + uint32_t tmpVal = 0; + + CHECK_PARAM(IS_GLB_Power_Off_MU_TYPE(pllType)); + + switch (pllType) { + case GLB_MU_PLL_MIPIPLL: + REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_MIPI_PLL_CFG0_OFFSET; + break; + case GLB_MU_PLL_UHSPLL: + REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_UHS_PLL_CFG0_OFFSET; + break; + default: + REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_MIPI_PLL_CFG0_OFFSET; + break; + } + + /* cfg0 : pu_aupll=0 */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_PU_AUPLL, 0); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + + /* cfg0 : pu_aupll_sfreg=0 */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_PU_AUPLL_SFREG, 0); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief GLB mipi uhs PLL ref clock select + * + * @param pllType: PLL XTAL type + * @param refClk: PLL ref clock select + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_MU_PLL_Ref_Clk_Sel(GLB_MU_PLL_Type pllType, GLB_PLL_REF_CLK_Type refClk) +{ + uint32_t REG_PLL_BASE_ADDRESS = 0; + uint32_t tmpVal = 0; + + CHECK_PARAM(IS_GLB_WAC_PLL_TYPE(pllType)); + CHECK_PARAM(IS_GLB_PLL_REF_CLK_TYPE(refClk)); + + switch (pllType) { + case GLB_MU_PLL_MIPIPLL: + REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_MIPI_PLL_CFG0_OFFSET; + break; + case GLB_MU_PLL_UHSPLL: + REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_UHS_PLL_CFG0_OFFSET; + break; + default: + REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_MIPI_PLL_CFG0_OFFSET; + break; + } + + /* xxxpll_refclk_sel */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_REFCLK_SEL, refClk); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 1, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief GLB power on PLL + * + * @param pllType: PLL XTAL type + * @param cfg: GLB PLL configuration + * @param waitStable: wait PLL stable + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Power_On_MU_PLL(GLB_MU_PLL_Type pllType, const GLB_MU_PLL_Cfg_Type *const cfg, uint8_t waitStable) +{ + uint32_t REG_PLL_BASE_ADDRESS = 0; + uint32_t tmpVal = 0; + + /* unknown */ + CHECK_PARAM(IS_GLB_WAC_PLL_TYPE(pllType)); + + switch (pllType) { + case GLB_MU_PLL_MIPIPLL: + REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_MIPI_PLL_CFG0_OFFSET; + break; + case GLB_MU_PLL_UHSPLL: + REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_UHS_PLL_CFG0_OFFSET; + break; + default: + REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_MIPI_PLL_CFG0_OFFSET; + break; + } + + /* Step1:config parameter */ + /* cfg1:Set aupll_refclk_sel and aupll_refdiv_ratio */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_REFDIV_RATIO, cfg->basicCfg->clkpllRefdivRatio); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 1, tmpVal); + + /* cfg4:Set aupll_sel_sample_clk */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 4); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_SEL_SAMPLE_CLK, cfg->basicCfg->clkpllSelSampleClk); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 4, tmpVal); + + /* cfg5:Set aupll_vco_speed */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 5); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_VCO_SPEED, cfg->basicCfg->clkpllVcoSpeed); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 5, tmpVal); + + /* cfg1: uhspll_even_div_en and uhspll_even_div_ratio */ + if (GLB_MU_PLL_UHSPLL == pllType) { + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_UHSPLL_EVEN_DIV_EN, cfg->basicCfg->clkpllEvenDivEn); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_UHSPLL_EVEN_DIV_RATIO, cfg->basicCfg->clkpllEvenDivRatio); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 1, tmpVal); + } + + /* cfg6:Set aupll_sdm_bypass,aupll_sdmin */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 6); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_SDMIN, cfg->clkpllSdmin); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 6, tmpVal); + + /* Step2:config pu */ + /* cfg0 : pu_aupll_sfreg=1 */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_PU_AUPLL_SFREG, 1); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + + /* delay > 2us */ + arch_delay_us(3); + + /* cfg0 : pu_wifipll=1 */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_PU_AUPLL, 1); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + + /* delay > 2us */ + arch_delay_us(3); + + /* toggle sdm_reset (pulse 0 > 1us) */ + /* cfg0 : aupll_sdm_reset */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_SDM_RSTB, 1); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + arch_delay_us(2); + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_SDM_RSTB, 0); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + arch_delay_us(2); + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_SDM_RSTB, 1); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + + /* Step3:reset pll */ + /* cfg0 : toggle aupll_reset_fbdv, pulse 0 > 1us */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_FBDV_RSTB, 1); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + arch_delay_us(2); + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_FBDV_RSTB, 0); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + arch_delay_us(2); + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, CCI_AUPLL_FBDV_RSTB, 1); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + + if (waitStable) { + /* Wait 1.5*30us */ + arch_delay_us(45); + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Set System clock divider + * + * @param mcuClkDiv: HCLK divider + * @param mcuPBclkDiv: BCLK divider + * @param lpClkDiv: LP clock divider + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Set_MCU_System_CLK_Div(uint8_t mcuClkDiv, uint8_t mcuPBclkDiv, uint8_t lpClkDiv) +{ + uint32_t tmpVal; + uint32_t timeout = 1024; + HBN_MCU_XCLK_Type xclkSel; + HBN_MCU_ROOT_CLK_Type rootClkSel; + + /* get root clock */ + xclkSel = HBN_Get_MCU_XCLK_Sel(); + rootClkSel = HBN_Get_MCU_Root_CLK_Sel(); + + if ((xclkSel != HBN_MCU_XCLK_RC32M) || (rootClkSel != HBN_MCU_ROOT_CLK_XCLK)) { + HBN_Set_MCU_XCLK_Sel(HBN_MCU_XCLK_RC32M); + HBN_Set_MCU_Root_CLK_Sel(HBN_MCU_ROOT_CLK_XCLK); + } + + /* config hclk_div=mcuClkDiv */ + tmpVal = BL_RD_REG(GLB_BASE, GLB_SYS_CFG0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_REG_HCLK_DIV, mcuClkDiv); + BL_WR_REG(GLB_BASE, GLB_SYS_CFG0, tmpVal); + + /* config bclk_div=mcuPBclkDiv */ + tmpVal = BL_RD_REG(GLB_BASE, GLB_SYS_CFG0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_REG_BCLK_DIV, mcuPBclkDiv); + BL_WR_REG(GLB_BASE, GLB_SYS_CFG0, tmpVal); + /* bclk act pulse */ + tmpVal = BL_RD_REG(GLB_BASE, GLB_SYS_CFG1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_REG_BCLK_DIV_ACT_PULSE, 1); + BL_WR_REG(GLB_BASE, GLB_SYS_CFG1, tmpVal); + + timeout = 1024; + do { + tmpVal = BL_RD_REG(GLB_BASE, GLB_SYS_CFG1); + tmpVal = BL_GET_REG_BITS_VAL(tmpVal, GLB_STS_BCLK_PROT_DONE); + } while ((--timeout) && (!tmpVal)); + if (!timeout) { + return ERROR; + } + + /* config lp clock div=lpClkDiv */ + tmpVal = BL_RD_REG(PDS_BASE, PDS_CPU_CORE_CFG7); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_REG_PICO_DIV, lpClkDiv); + BL_WR_REG(PDS_BASE, PDS_CPU_CORE_CFG7, tmpVal); + /* bclk act pulse */ + tmpVal = BL_RD_REG(GLB_BASE, GLB_SYS_CFG1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_REG_PICO_CLK_DIV_ACT_PULSE, 1); + BL_WR_REG(GLB_BASE, GLB_SYS_CFG1, tmpVal); + + timeout = 1024; + do { + tmpVal = BL_RD_REG(GLB_BASE, GLB_SYS_CFG1); + tmpVal = BL_GET_REG_BITS_VAL(tmpVal, GLB_STS_PICO_CLK_PROT_DONE); + } while ((--timeout) && (!tmpVal)); + if (!timeout) { + return ERROR; + } + + /* recover root clock */ + HBN_Set_MCU_XCLK_Sel(xclkSel); + HBN_Set_MCU_Root_CLK_Sel(rootClkSel); + + GLB_CLK_SET_DUMMY_WAIT; + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Get System clock divider + * + * @param mcuClkDiv: HCLK divider + * @param mcuPBclkDiv: BCLK divider + * @param lpClkDiv: LP clock divider + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Get_MCU_System_CLK_Div(uint8_t *mcuClkDiv, uint8_t *mcuPBclkDiv, uint8_t *lpClkDiv) +{ + *mcuClkDiv = BL_GET_REG_BITS_VAL(BL_RD_REG(GLB_BASE, GLB_SYS_CFG0), GLB_REG_HCLK_DIV); + *mcuPBclkDiv = BL_GET_REG_BITS_VAL(BL_RD_REG(GLB_BASE, GLB_SYS_CFG0), GLB_REG_BCLK_DIV); + *lpClkDiv = BL_GET_REG_BITS_VAL(BL_RD_REG(PDS_BASE, PDS_CPU_CORE_CFG7), PDS_REG_PICO_DIV); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Set mcu System clock + * + * @param clkFreq: mcu system clock type + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Set_MCU_System_CLK(GLB_MCU_SYS_CLK_Type clkFreq) +{ + uint32_t tmpVal; + HBN_MCU_XCLK_Type mcuXclkSel; + + CHECK_PARAM(IS_GLB_MCU_SYS_CLK_TYPE(clkFreq)); + + /* get xclk&&rootclk clock */ + mcuXclkSel = HBN_Get_MCU_XCLK_Sel(); + + /* change root clock to rc32m */ + HBN_Set_MCU_XCLK_Sel(HBN_MCU_XCLK_RC32M); + HBN_Set_MCU_Root_CLK_Sel(HBN_MCU_ROOT_CLK_XCLK); + GLB_Set_MCU_System_CLK_Div(0, 0, 0); + + /* select pll output clock before select root clock */ + tmpVal = BL_RD_REG(PDS_BASE, PDS_CPU_CORE_CFG1); + switch (clkFreq) { + case GLB_MCU_SYS_CLK_CPUPLL_400M: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_REG_PLL_SEL, 0); + break; + case GLB_MCU_SYS_CLK_WIFIPLL_240M: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_REG_PLL_SEL, 2); + break; + case GLB_MCU_SYS_CLK_WIFIPLL_320M: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_REG_PLL_SEL, 3); + break; + default: + break; + } + BL_WR_REG(PDS_BASE, PDS_CPU_CORE_CFG1, tmpVal); + + /* select root clock */ + switch (clkFreq) { + case GLB_MCU_SYS_CLK_RC32M: + GLB_Set_MCU_System_CLK_Div(0, 0, 0); + HBN_Set_MCU_XCLK_Sel(HBN_MCU_XCLK_RC32M); + HBN_Set_MCU_Root_CLK_Sel(HBN_MCU_ROOT_CLK_XCLK); + break; + case GLB_MCU_SYS_CLK_XTAL: + GLB_Set_MCU_System_CLK_Div(0, 0, 0); + HBN_Set_MCU_XCLK_Sel(HBN_MCU_XCLK_XTAL); + HBN_Set_MCU_Root_CLK_Sel(HBN_MCU_ROOT_CLK_XCLK); + break; + case GLB_MCU_SYS_CLK_CPUPLL_400M: + /* For high speed, set DIV first */ + GLB_Set_MCU_System_CLK_Div(1, 2, 1); + /* Set IROM 2T Access 0 since we use RC32M, unuseful now */ + /* MCU_MISC_IROM_2T_Access_Set(0); */ + /* unuseful for mcu, useful for dsp, just for safe */ + HBN_Set_MCU_Root_CLK_Sel(HBN_MCU_ROOT_CLK_PLL); + /* recover xclk */ + HBN_Set_MCU_XCLK_Sel(mcuXclkSel); + break; + case GLB_MCU_SYS_CLK_WIFIPLL_240M: + /* For high speed, set DIV first */ + GLB_Set_MCU_System_CLK_Div(0, 2, 1); + /* Set IROM 2T Access 0 since we use RC32M, unuseful now */ + /* MCU_MISC_IROM_2T_Access_Set(0); */ + /* unuseful for mcu, useful for dsp, just for safe */ + HBN_Set_MCU_Root_CLK_Sel(HBN_MCU_ROOT_CLK_PLL); + /* recover xclk */ + HBN_Set_MCU_XCLK_Sel(mcuXclkSel); + break; + case GLB_MCU_SYS_CLK_WIFIPLL_320M: + /* overclock, not recommended */ + /* For high speed, set DIV first */ + GLB_Set_MCU_System_CLK_Div(0, 3, 1); + /* Set IROM 2T Access 0 since we use RC32M, unuseful now */ + /* MCU_MISC_IROM_2T_Access_Set(0); */ + HBN_Set_MCU_Root_CLK_Sel(HBN_MCU_ROOT_CLK_PLL); + /* recover xclk */ + HBN_Set_MCU_XCLK_Sel(mcuXclkSel); + break; + default: + break; + } + + GLB_CLK_SET_DUMMY_WAIT; + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief select DSP0 DSP1 clock div + * + * @param dspClkDiv: mm glb cpu div + * @param dspBclkDiv: mm glb bclk2x div + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Set_DSP_System_CLK_Div(uint8_t dspClkDiv, uint8_t dspBclkDiv) +{ + uint32_t tmpVal = 0; + uint32_t timeout = 1024; + GLB_DSP_XCLK_Type dspXclkSel; + GLB_DSP_ROOT_CLK_Type dspRootClkSel; + + /* get root clock */ + dspXclkSel = GLB_Get_DSP_XCLK_Sel(); + dspRootClkSel = GLB_Get_DSP_ROOT_CLK_Sel(); + + /* change root clock to rc32m */ + if ((dspXclkSel != GLB_DSP_XCLK_RC32M) || (dspRootClkSel != GLB_DSP_ROOT_CLK_XCLK)) { + GLB_Set_DSP_XCLK_Sel(GLB_DSP_XCLK_RC32M); + GLB_Set_DSP_ROOT_CLK_Sel(GLB_DSP_ROOT_CLK_XCLK); + } + + /* set div */ + tmpVal = BL_RD_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CPU); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, MM_GLB_REG_BCLK2X_DIV, dspBclkDiv); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, MM_GLB_REG_CPU_CLK_DIV, dspClkDiv); + BL_WR_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CPU, tmpVal); + + tmpVal = BL_RD_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CTRL_CPU); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, MM_GLB_REG_BCLK2X_DIV_ACT_PULSE, 1); + BL_WR_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CTRL_CPU, tmpVal); + + do { + tmpVal = BL_RD_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CTRL_CPU); + tmpVal = BL_GET_REG_BITS_VAL(tmpVal, MM_GLB_STS_BCLK2X_PROT_DONE); + } while ((--timeout) && (!tmpVal)); + if (!timeout) { + return ERROR; + } + + /* recover root clock */ + GLB_Set_DSP_XCLK_Sel(dspXclkSel); + GLB_Set_DSP_ROOT_CLK_Sel(dspRootClkSel); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief get DSP0 DSP1 clock div + * + * @param dspClkDiv: mm glb cpu div + * @param dspBclkDiv: mm glb bclk2x div + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Get_DSP_System_CLK_Div(uint8_t *dspClkDiv, uint8_t *dspBclkDiv) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CPU); + *dspBclkDiv = BL_GET_REG_BITS_VAL(tmpVal, MM_GLB_REG_BCLK2X_DIV); + *dspClkDiv = BL_GET_REG_BITS_VAL(tmpVal, MM_GLB_REG_CPU_CLK_DIV); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Set dsp System clock + * + * @param clkFreq: dsp system clock type + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Set_DSP_System_CLK(GLB_DSP_SYS_CLK_Type clkFreq) +{ + GLB_DSP_XCLK_Type dspXclkSel; + + CHECK_PARAM(IS_GLB_DSP_SYS_CLK_TYPE(clkFreq)); + + /* get root clock */ + dspXclkSel = GLB_Get_DSP_XCLK_Sel(); + + /* Before config XTAL and PLL ,make sure root clk is from RC32M */ + GLB_Set_DSP_XCLK_Sel(GLB_DSP_XCLK_RC32M); + GLB_Set_DSP_ROOT_CLK_Sel(GLB_DSP_ROOT_CLK_XCLK); + GLB_Set_DSP_System_CLK_Div(0, 0); + + /* select pll output clock before select root clock */ + if (GLB_DSP_SYS_CLK_MM_WIFIPLL_240M == clkFreq) { + GLB_Set_DSP_MUXPLL_CLK_Sel(GLB_DSP_PLL_CLK_MUXPLL_240M); + } else if (GLB_DSP_SYS_CLK_MM_WIFIPLL_320M == clkFreq) { + GLB_Set_DSP_MUXPLL_CLK_Sel(GLB_DSP_PLL_CLK_MUXPLL_320M); + } else if (GLB_DSP_SYS_CLK_CPUPLL_400M == clkFreq) { + GLB_Set_DSP_MUXPLL_CLK_Sel(GLB_DSP_PLL_CLK_CPUPLL_400M); + } + + /* select root clock */ + switch (clkFreq) { + case GLB_DSP_SYS_CLK_RC32M: + GLB_Set_DSP_System_CLK_Div(0, 0); + GLB_Set_DSP_XCLK_Sel(GLB_DSP_XCLK_RC32M); + GLB_Set_DSP_ROOT_CLK_Sel(GLB_DSP_ROOT_CLK_XCLK); + break; + case GLB_DSP_SYS_CLK_XTAL: + GLB_Set_DSP_System_CLK_Div(0, 0); + GLB_Set_DSP_XCLK_Sel(GLB_DSP_XCLK_XTAL); + GLB_Set_DSP_ROOT_CLK_Sel(GLB_DSP_ROOT_CLK_XCLK); + break; + case GLB_DSP_SYS_CLK_MM_WIFIPLL_240M: + GLB_Set_DSP_System_CLK_Div(0, 1); + GLB_Set_DSP_Muxpll_240M_Sel(GLB_DSP_MUXPLL_SEL_WIFIPLL_240M); + GLB_Set_DSP_ROOT_CLK_Sel(GLB_DSP_ROOT_CLK_PLL); + /* recover xclk */ + GLB_Set_DSP_XCLK_Sel(dspXclkSel); + break; + case GLB_DSP_SYS_CLK_MM_WIFIPLL_320M: + GLB_Set_DSP_System_CLK_Div(0, 1); + GLB_Set_DSP_Muxpll_320M_Sel(GLB_DSP_MUXPLL_SEL_WIFIPLL_320M); + GLB_Set_DSP_ROOT_CLK_Sel(GLB_DSP_ROOT_CLK_PLL); + /* recover xclk */ + GLB_Set_DSP_XCLK_Sel(dspXclkSel); + break; + case GLB_DSP_SYS_CLK_CPUPLL_400M: + GLB_Set_DSP_System_CLK_Div(0, 1); + GLB_Set_DSP_ROOT_CLK_Sel(GLB_DSP_ROOT_CLK_PLL); + /* recover xclk */ + GLB_Set_DSP_XCLK_Sel(dspXclkSel); + break; + default: + break; + } + GLB_CLK_SET_DUMMY_WAIT; + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief select DSP0 pbus clock div + * + * @param dspBclkDiv: mm glb bclk2x div + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Set_DSP_PBCLK_Div(uint8_t dspPBclkDiv) +{ + uint32_t tmpVal = 0; + + /* set div */ + tmpVal = BL_RD_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CPU); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, MM_GLB_REG_BCLK1X_DIV, dspPBclkDiv); + BL_WR_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CPU, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief get DSP0 pbus clock div + * + * @param dspBclkDiv: mm glb bclk2x div + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Get_DSP_PBCLK_Div(uint8_t *dspPBclkDiv) +{ + *dspPBclkDiv = BL_GET_REG_BITS_VAL(BL_RD_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CPU), MM_GLB_REG_BCLK1X_DIV); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Set dsp pbus clock + * + * @param pbClkSel: dsp pbus clock type + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Set_DSP_PBCLK(GLB_DSP_SYS_PBCLK_Type pbClkSel) +{ + CHECK_PARAM(IS_GLB_DSP_SYS_PBCLK_TYPE(pbClkSel)); + + GLB_Set_DSP_PBCLK_Div(0); + + /* select pbroot clock */ + switch (pbClkSel) { + case GLB_DSP_SYS_PBCLK_RC32M: + GLB_Set_DSP_XCLK_Sel(GLB_DSP_XCLK_RC32M); + GLB_Set_DSP_PBCLK_Div(0); + GLB_Set_DSP_PBROOT_CLK_Sel(GLB_DSP_PBROOT_CLK_MM_XCLK); + break; + case GLB_DSP_SYS_PBCLK_XTAL: + GLB_Set_DSP_XCLK_Sel(GLB_DSP_XCLK_XTAL); + GLB_Set_DSP_PBCLK_Div(0); + GLB_Set_DSP_PBROOT_CLK_Sel(GLB_DSP_PBROOT_CLK_MM_XCLK); + break; + case GLB_DSP_SYS_PBCLK_MM_WIFIPLL_160M: + GLB_Set_DSP_Muxpll_160M_Sel(GLB_DSP_MUXPLL_SEL_WIFIPLL_160M); + GLB_Set_DSP_PBCLK_Div(0); + GLB_Set_DSP_PBROOT_CLK_Sel(GLB_DSP_PBROOT_CLK_MM_MUXPLL_160M); + break; + case GLB_DSP_SYS_PBCLK_CPUPLL_160M: + GLB_Set_DSP_Muxpll_160M_Sel(GLB_DSP_MUXPLL_SEL_CPUPLL_160M); + GLB_Set_DSP_PBCLK_Div(0); + GLB_Set_DSP_PBROOT_CLK_Sel(GLB_DSP_PBROOT_CLK_MM_MUXPLL_160M); + break; + case GLB_DSP_SYS_PBCLK_MM_WIFIPLL_240M: + GLB_Set_DSP_Muxpll_240M_Sel(GLB_DSP_MUXPLL_SEL_WIFIPLL_240M); + GLB_Set_DSP_PBCLK_Div(1); + GLB_Set_DSP_PBROOT_CLK_Sel(GLB_DSP_PBROOT_CLK_MM_MUXPLL_240M); + break; + default: + break; + } + GLB_CLK_SET_DUMMY_WAIT; + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief DSP0 clock enable + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_DSP0_Clock_Enable(void) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CTRL_CPU); + tmpVal = BL_SET_REG_BIT(tmpVal, MM_GLB_REG_MMCPU0_CLK_EN); + BL_WR_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CTRL_CPU, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief DSP0 clock disable + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_DSP0_Clock_Disable(void) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CTRL_CPU); + tmpVal = BL_CLR_REG_BIT(tmpVal, MM_GLB_REG_MMCPU0_CLK_EN); + BL_WR_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CTRL_CPU, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief get xclk clock source Select + * + * @param None + * + * @return xclk clock type selection + * +*******************************************************************************/ +GLB_DSP_XCLK_Type ATTR_CLOCK_SECTION GLB_Get_DSP_XCLK_Sel(void) +{ + return (GLB_DSP_XCLK_Type)(BL_GET_REG_BITS_VAL(BL_RD_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CTRL_CPU), MM_GLB_REG_XCLK_CLK_SEL)); +} + +/****************************************************************************/ /** + * @brief Select xclk clock source + * + * @param xclk: xclk clock type selection + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Set_DSP_XCLK_Sel(GLB_DSP_XCLK_Type xclk) +{ + uint32_t tmpVal; + + CHECK_PARAM(IS_GLB_DSP_XCLK_TYPE(xclk)); + + tmpVal = BL_RD_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CTRL_CPU); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, MM_GLB_REG_XCLK_CLK_SEL, xclk); + BL_WR_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CTRL_CPU, tmpVal); + GLB_CLK_SET_DUMMY_WAIT; + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief get DSP root clock + * + * @param None + * + * @return mm glb root clock type + * +*******************************************************************************/ +GLB_DSP_ROOT_CLK_Type ATTR_CLOCK_SECTION GLB_Get_DSP_ROOT_CLK_Sel(void) +{ + uint32_t tmpVal = 0; + uint32_t rootclk = 0; + + tmpVal = BL_RD_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CTRL_CPU); + rootclk = BL_GET_REG_BITS_VAL(tmpVal, MM_GLB_REG_CPU_ROOT_CLK_SEL); + if (0 == rootclk) { + /* xclk */ + return GLB_DSP_ROOT_CLK_XCLK; + } else { + /* pll */ + return GLB_DSP_ROOT_CLK_PLL; + } +} + +/****************************************************************************/ /** + * @brief select DSP root clock + * + * @param rootClk: mm glb root clock type + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Set_DSP_ROOT_CLK_Sel(GLB_DSP_ROOT_CLK_Type rootClk) +{ + uint32_t tmpVal; + + CHECK_PARAM(IS_GLB_DSP_ROOT_CLK_TYPE(rootClk)); + + tmpVal = BL_RD_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CTRL_CPU); + switch (rootClk) { + case GLB_DSP_ROOT_CLK_XCLK: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, MM_GLB_REG_CPU_ROOT_CLK_SEL, 0); + break; + case GLB_DSP_ROOT_CLK_PLL: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, MM_GLB_REG_CPU_ROOT_CLK_SEL, 1); + break; + default: + break; + } + BL_WR_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CTRL_CPU, tmpVal); + GLB_CLK_SET_DUMMY_WAIT; + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief select DSP muxpll clock + * + * @param pllClk: mm glb pll clock type + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Set_DSP_MUXPLL_CLK_Sel(GLB_DSP_PLL_CLK_Type pllClk) +{ + uint32_t tmpVal = 0; + + CHECK_PARAM(IS_GLB_DSP_PLL_CLK_TYPE(pllClk)); + + tmpVal = BL_RD_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CTRL_CPU); + switch (pllClk) { + case GLB_DSP_PLL_CLK_MUXPLL_240M: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, MM_GLB_REG_CPU_CLK_SEL, 0); + break; + case GLB_DSP_PLL_CLK_MUXPLL_320M: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, MM_GLB_REG_CPU_CLK_SEL, 1); + break; + case GLB_DSP_PLL_CLK_CPUPLL_400M: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, MM_GLB_REG_CPU_CLK_SEL, 2); + break; + default: + break; + } + BL_WR_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CTRL_CPU, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief get DSP pbroot clock + * + * @param None + * + * @return mm DSP pbroot clock type + * +*******************************************************************************/ +GLB_DSP_PBROOT_CLK_Type ATTR_CLOCK_SECTION GLB_Get_DSP_PBROOT_CLK_Sel(void) +{ + uint32_t tmpVal = 0; + uint32_t pbrootclk = 0; + + tmpVal = BL_RD_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CTRL_CPU); + pbrootclk = BL_GET_REG_BITS_VAL(tmpVal, MM_GLB_REG_BCLK1X_SEL); + switch (pbrootclk) { + case 0: + return GLB_DSP_PBROOT_CLK_MM_XCLK; + case 1: + return GLB_DSP_PBROOT_CLK_MM_XCLK; + case 2: + return GLB_DSP_PBROOT_CLK_MM_MUXPLL_160M; + case 3: + return GLB_DSP_PBROOT_CLK_MM_MUXPLL_240M; + default: + return GLB_DSP_PBROOT_CLK_MM_XCLK; + } +} + +/****************************************************************************/ /** + * @brief select DSP pbroot clock + * + * @param pbrootClk: mm DSP pbroot clock type + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Set_DSP_PBROOT_CLK_Sel(GLB_DSP_PBROOT_CLK_Type pbrootClk) +{ + uint32_t tmpVal; + + CHECK_PARAM(IS_GLB_DSP_PBROOT_CLK_TYPE(pbrootClk)); + + tmpVal = BL_RD_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CTRL_CPU); + switch (pbrootClk) { + case GLB_DSP_PBROOT_CLK_MM_XCLK: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, MM_GLB_REG_BCLK1X_SEL, 0); + break; + case GLB_DSP_PBROOT_CLK_MM_MUXPLL_160M: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, MM_GLB_REG_BCLK1X_SEL, 2); + break; + case GLB_DSP_PBROOT_CLK_MM_MUXPLL_240M: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, MM_GLB_REG_BCLK1X_SEL, 3); + break; + default: + break; + } + BL_WR_REG(MM_GLB_BASE, MM_GLB_MM_CLK_CTRL_CPU, tmpVal); + GLB_CLK_SET_DUMMY_WAIT; + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief set CPU reset address + * + * @param coreID: core type + * @param addr: reset address + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Set_CPU_Reset_Address(GLB_CORE_ID_Type coreID, uint32_t addr) +{ + CHECK_PARAM(IS_GLB_CORE_ID_TYPE(coreID)); + + switch (coreID) { + case GLB_CORE_ID_M0: + BL_WR_REG(PDS_BASE, PDS_CPU_CORE_CFG14, addr); + break; + case GLB_CORE_ID_D0: + BL_WR_REG(MM_MISC_BASE, MM_MISC_CPU0_BOOT, addr); + break; + case GLB_CORE_ID_LP: + BL_WR_REG(PDS_BASE, PDS_CPU_CORE_CFG13, addr); + break; + default: + return ERROR; + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief hold cpu + * + * @param coreID: core type + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Halt_CPU(GLB_CORE_ID_Type coreID) +{ + uint32_t tmpVal = 0; + + CHECK_PARAM(IS_GLB_CORE_ID_TYPE(coreID)); + + switch (coreID) { + case GLB_CORE_ID_M0: + PDS_Set_MCU0_Clock_Disable(); + arch_delay_us(1); + tmpVal = BL_RD_REG(GLB_BASE, GLB_SWRST_CFG2); + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_REG_CTRL_CPU_RESET); + BL_WR_REG(GLB_BASE, GLB_SWRST_CFG2, tmpVal); + break; + case GLB_CORE_ID_D0: + GLB_DSP0_Clock_Disable(); + arch_delay_us(1); + tmpVal = BL_RD_REG(MM_GLB_BASE, MM_GLB_MM_SW_SYS_RESET); + tmpVal = BL_SET_REG_BIT(tmpVal, MM_GLB_REG_CTRL_MMCPU0_RESET); + BL_WR_REG(MM_GLB_BASE, MM_GLB_MM_SW_SYS_RESET, tmpVal); + break; + case GLB_CORE_ID_LP: + PDS_Set_LP_Clock_Disable(); + arch_delay_us(1); + tmpVal = BL_RD_REG(GLB_BASE, GLB_SWRST_CFG2); + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_REG_CTRL_PICO_RESET); + BL_WR_REG(GLB_BASE, GLB_SWRST_CFG2, tmpVal); + break; + default: + return ERROR; + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief release cpu + * + * @param coreID: core type + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Release_CPU(GLB_CORE_ID_Type coreID) +{ + uint32_t tmpVal = 0; + + CHECK_PARAM(IS_GLB_CORE_ID_TYPE(coreID)); + + switch (coreID) { + case GLB_CORE_ID_M0: + PDS_Set_MCU0_Clock_Enable(); + arch_delay_us(1); + tmpVal = BL_RD_REG(GLB_BASE, GLB_SWRST_CFG2); + tmpVal = BL_CLR_REG_BIT(tmpVal, GLB_REG_CTRL_CPU_RESET); + BL_WR_REG(GLB_BASE, GLB_SWRST_CFG2, tmpVal); + break; + case GLB_CORE_ID_D0: + GLB_DSP0_Clock_Enable(); + arch_delay_us(1); + tmpVal = BL_RD_REG(MM_GLB_BASE, MM_GLB_MM_SW_SYS_RESET); + tmpVal = BL_CLR_REG_BIT(tmpVal, MM_GLB_REG_CTRL_MMCPU0_RESET); + BL_WR_REG(MM_GLB_BASE, MM_GLB_MM_SW_SYS_RESET, tmpVal); + break; + case GLB_CORE_ID_LP: + PDS_Set_LP_Clock_Enable(); + arch_delay_us(1); + tmpVal = BL_RD_REG(GLB_BASE, GLB_SWRST_CFG2); + tmpVal = BL_CLR_REG_BIT(tmpVal, GLB_REG_CTRL_PICO_RESET); + BL_WR_REG(GLB_BASE, GLB_SWRST_CFG2, tmpVal); + break; + default: + return ERROR; + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief set MTimer clock + * + * @param enable: enable or disable + * @param clkSel: clock selection + * @param div: divider + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Set_EMI_CLK(uint8_t enable, GLB_EMI_CLK_Type clkSel, uint32_t div) +{ + uint32_t tmpVal; + + CHECK_PARAM(IS_GLB_EMI_CLK_TYPE(clkSel)); + CHECK_PARAM((div <= 0x3)); + + /* disable EMI clock first */ + tmpVal = BL_RD_REG(GLB_BASE, GLB_EMI_CFG0); + tmpVal = BL_CLR_REG_BIT(tmpVal, GLB_REG_EMI_CLK_EN); + BL_WR_REG(GLB_BASE, GLB_EMI_CFG0, tmpVal); + + tmpVal = BL_RD_REG(GLB_BASE, GLB_EMI_CFG0); + switch (clkSel) { + case GLB_EMI_CLK_MCU_PBCLK: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_REG_EMI_CLK_SEL, 0); + break; + case GLB_EMI_CLK_CPUPLL_200M_CLK: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_REG_EMI_CLK_SEL, 4); + break; + case GLB_EMI_CLK_WIFIPLL_320M_CLK: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_REG_EMI_CLK_SEL, 2); + break; + case GLB_EMI_CLK_CPUPLL_400M_CLK: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_REG_EMI_CLK_SEL, 3); + break; + default: + break; + } + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_REG_EMI_CLK_DIV, div); + BL_WR_REG(GLB_BASE, GLB_EMI_CFG0, tmpVal); + + tmpVal = BL_RD_REG(GLB_BASE, GLB_EMI_CFG0); + if (enable) { + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_REG_EMI_CLK_EN); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, GLB_REG_EMI_CLK_EN); + } + BL_WR_REG(GLB_BASE, GLB_EMI_CFG0, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Clr_EMI_Reset_Gate(void) +{ + uint32_t tmpVal; + + /* clear EMI swrst bit */ + tmpVal = BL_RD_REG(GLB_BASE, GLB_SWRST_CFG0); + tmpVal = BL_CLR_REG_BIT(tmpVal, GLB_SWRST_S1_EXT_EMI_MISC); + BL_WR_REG(GLB_BASE, GLB_SWRST_CFG0, tmpVal); + + /* set EMI cgen bit */ + tmpVal = BL_RD_REG(GLB_BASE, GLB_CGEN_CFG2); + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_CGEN_S1_EXT_EMI_MISC); + BL_WR_REG(GLB_BASE, GLB_CGEN_CFG2, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief reconfigure WIFIPLL clock + * + * @param xtalType: XTAL frequency type + * @param pllCfg: PLL configuration + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Config_WIFI_PLL(GLB_XTAL_Type xtalType, const GLB_WAC_PLL_Cfg_Type * pllCfgList) +{ + GLB_PLL_REF_CLK_Type refClk; + + if (xtalType == GLB_XTAL_RC32M) { + refClk = GLB_PLL_REFCLK_RC32M; + } else { + refClk = GLB_PLL_REFCLK_XTAL; + } + + GLB_Power_Off_WAC_PLL(GLB_WAC_PLL_WIFIPLL); + GLB_WAC_PLL_Ref_Clk_Sel(GLB_WAC_PLL_WIFIPLL, refClk); + GLB_Power_On_WAC_PLL(GLB_WAC_PLL_WIFIPLL, &(pllCfgList[xtalType]), 0); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief reconfigure AUPLL clock + * + * @param xtalType: XTAL frequency type + * @param pllCfg: PLL configuration + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Config_AUDIO_PLL(GLB_XTAL_Type xtalType, const GLB_WAC_PLL_Cfg_Type * pllCfgList) +{ + GLB_PLL_REF_CLK_Type refClk; + + if (xtalType == GLB_XTAL_RC32M) { + refClk = GLB_PLL_REFCLK_RC32M; + } else { + refClk = GLB_PLL_REFCLK_XTAL; + } + + GLB_Power_Off_WAC_PLL(GLB_WAC_PLL_AUPLL); + GLB_WAC_PLL_Ref_Clk_Sel(GLB_WAC_PLL_AUPLL, refClk); + GLB_Power_On_WAC_PLL(GLB_WAC_PLL_AUPLL, &(pllCfgList[xtalType]), 0); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief reconfigure CPUPLL clock + * + * @param xtalType: XTAL frequency type + * @param pllCfg: PLL configuration + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Config_CPU_PLL(GLB_XTAL_Type xtalType, const GLB_WAC_PLL_Cfg_Type * pllCfgList) +{ + GLB_PLL_REF_CLK_Type refClk; + + if (xtalType == GLB_XTAL_RC32M) { + refClk = GLB_PLL_REFCLK_RC32M; + } else { + refClk = GLB_PLL_REFCLK_XTAL; + } + + GLB_Power_Off_WAC_PLL(GLB_WAC_PLL_CPUPLL); + GLB_WAC_PLL_Ref_Clk_Sel(GLB_WAC_PLL_CPUPLL, refClk); + GLB_Power_On_WAC_PLL(GLB_WAC_PLL_CPUPLL, &(pllCfgList[xtalType]), 0); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief reconfigure MIPIPLL clock + * + * @param xtalType: XTAL frequency type + * @param pllCfg: PLL configuration + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Config_MIPI_PLL(GLB_XTAL_Type xtalType, const GLB_MU_PLL_Cfg_Type * pllCfgList) +{ + GLB_PLL_REF_CLK_Type refClk; + + if (xtalType == GLB_XTAL_RC32M) { + refClk = GLB_PLL_REFCLK_RC32M; + } else { + refClk = GLB_PLL_REFCLK_XTAL; + } + + GLB_Power_Off_MU_PLL(GLB_MU_PLL_MIPIPLL); + GLB_MU_PLL_Ref_Clk_Sel(GLB_MU_PLL_MIPIPLL, refClk); + GLB_Power_On_MU_PLL(GLB_MU_PLL_MIPIPLL, &(pllCfgList[xtalType]), 0); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief reconfigure MIPIPLL clock div + * + * @param divEn: div enable + * @param divRatio: div ratio + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Config_MIPI_PLL_Div(uint8_t divEn, uint8_t divRatio) +{ + uint32_t REG_PLL_BASE_ADDRESS = 0; + uint32_t tmpVal = 0; + + REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_MIPI_PLL_CFG0_OFFSET; + + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_MIPIPLL_EVEN_DIV_EN, divEn); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_MIPIPLL_EVEN_DIV_RATIO, divRatio); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 1, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief reconfigure UHSPLL clock + * + * @param xtalType: XTAL frequency type + * @param pllCfg: PLL configuration + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Config_UHS_PLL(GLB_XTAL_Type xtalType, const GLB_MU_PLL_Cfg_Type * pllCfgList) +{ + GLB_PLL_REF_CLK_Type refClk; + + if (xtalType == GLB_XTAL_RC32M) { + refClk = GLB_PLL_REFCLK_RC32M; + } else { + refClk = GLB_PLL_REFCLK_XTAL; + } + + GLB_Power_Off_MU_PLL(GLB_MU_PLL_UHSPLL); + GLB_MU_PLL_Ref_Clk_Sel(GLB_MU_PLL_UHSPLL, refClk); + GLB_Power_On_MU_PLL(GLB_MU_PLL_UHSPLL, &(pllCfgList[xtalType]), 0); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief get core type + * + * @param None + * + * @return core type + * +*******************************************************************************/ +GLB_CORE_ID_Type ATTR_CLOCK_SECTION GLB_Get_Core_Type(void) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_WORD(CORE_ID_ADDRESS); + + switch (tmpVal) { + case CORE_ID_M0: + return GLB_CORE_ID_M0; + case CORE_ID_D0: + return GLB_CORE_ID_D0; + case CORE_ID_LP: + return GLB_CORE_ID_LP; + default: + return GLB_CORE_ID_INVALID; + } + + return GLB_CORE_ID_INVALID; +} + +/****************************************************************************/ /** + * @brief get first 1 from u64, then clear it + * + * @param val: target value + * @param bit: first 1 in bit + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +static BL_Err_Type GLB_Get_And_Clr_First_Set_From_U64(uint64_t *val, uint32_t *bit) +{ + if (!*val) { + return ERROR; + } + + for (uint8_t i = 0; i < 64; i++) { + if ((*val) & ((uint64_t)1 << i)) { + *bit = i; + (*val) &= ~((uint64_t)1 << i); + break; + } + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief hold IPs clock + * + * @param ips: GLB_AHB_CLOCK_IP_xxx | GLB_AHB_CLOCK_IP_xxx | ...... + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type GLB_PER_Clock_Gate(uint64_t ips) +{ + /* api request from cjy */ + + uint32_t tmpValCfg0 = 0; + uint32_t tmpValCfg1 = 0; + uint32_t tmpValCfg2 = 0; + uint32_t bitfield = 0; + + tmpValCfg0 = BL_RD_REG(GLB_BASE, GLB_CGEN_CFG0); + tmpValCfg1 = BL_RD_REG(GLB_BASE, GLB_CGEN_CFG1); + tmpValCfg2 = BL_RD_REG(GLB_BASE, GLB_CGEN_CFG2); + while (ips) { + if (SUCCESS == GLB_Get_And_Clr_First_Set_From_U64(&ips, &bitfield)) { + switch (bitfield) { + case GLB_AHB_CLOCK_IP_CPU: + tmpValCfg0 &= ~(1 << 0); + break; + case GLB_AHB_CLOCK_IP_SDU: + tmpValCfg0 &= ~(1 << 1); + break; + case GLB_AHB_CLOCK_IP_SEC: + tmpValCfg0 &= ~(1 << 2); + tmpValCfg1 &= ~(1 << 3); + tmpValCfg1 &= ~(1 << 4); + break; + case GLB_AHB_CLOCK_IP_DMA_0: + tmpValCfg0 &= ~(1 << 3); + tmpValCfg1 &= ~(1 << 12); + break; + case GLB_AHB_CLOCK_IP_DMA_1: + tmpValCfg0 &= ~(1 << 3); + break; + case GLB_AHB_CLOCK_IP_DMA_2: + tmpValCfg0 &= ~(1 << 3); + tmpValCfg2 &= ~(1 << 24); + break; + case GLB_AHB_CLOCK_IP_CCI: + tmpValCfg0 &= ~(1 << 4); + break; + case GLB_AHB_CLOCK_IP_RF_TOP: + tmpValCfg1 &= ~(1 << 1); + break; + case GLB_AHB_CLOCK_IP_GPIP: + tmpValCfg1 &= ~(1 << 2); + break; + case GLB_AHB_CLOCK_IP_TZC: + tmpValCfg1 &= ~(1 << 5); + break; + case GLB_AHB_CLOCK_IP_EF_CTRL: + tmpValCfg1 &= ~(1 << 7); + break; + case GLB_AHB_CLOCK_IP_SF_CTRL: + tmpValCfg1 &= ~(1 << 11); + break; + case GLB_AHB_CLOCK_IP_EMAC: + tmpValCfg2 &= ~(1 << 19); + tmpValCfg2 &= ~(1 << 23); + break; + case GLB_AHB_CLOCK_IP_UART0: + tmpValCfg1 &= ~(1 << 16); + break; + case GLB_AHB_CLOCK_IP_UART1: + tmpValCfg1 &= ~(1 << 17); + break; + case GLB_AHB_CLOCK_IP_UART2: + tmpValCfg1 &= ~(1 << 26); + break; + case GLB_AHB_CLOCK_IP_UART3: + break; + case GLB_AHB_CLOCK_IP_UART4: + break; + case GLB_AHB_CLOCK_IP_SPI: + tmpValCfg1 &= ~(1 << 18); + break; + case GLB_AHB_CLOCK_IP_I2C: + tmpValCfg1 &= ~(1 << 19); + break; + case GLB_AHB_CLOCK_IP_PWM: + tmpValCfg1 &= ~(1 << 20); + break; + case GLB_AHB_CLOCK_IP_TIMER: + tmpValCfg1 &= ~(1 << 21); + break; + case GLB_AHB_CLOCK_IP_IR: + tmpValCfg1 &= ~(1 << 22); + break; + case GLB_AHB_CLOCK_IP_CHECKSUM: + tmpValCfg1 &= ~(1 << 23); + break; + case GLB_AHB_CLOCK_IP_QDEC: + break; + case GLB_AHB_CLOCK_IP_KYS: + break; + case GLB_AHB_CLOCK_IP_I2S: + tmpValCfg1 &= ~(1 << 27); + break; + case GLB_AHB_CLOCK_IP_USB11: + break; + case GLB_AHB_CLOCK_IP_CAM: + break; + case GLB_AHB_CLOCK_IP_MJPEG: + break; + case GLB_AHB_CLOCK_IP_BT_BLE_NORMAL: + tmpValCfg2 &= ~(1 << 8); + break; + case GLB_AHB_CLOCK_IP_BT_BLE_LP: + break; + case GLB_AHB_CLOCK_IP_ZB_NORMAL: + tmpValCfg2 &= ~(1 << 9); + break; + case GLB_AHB_CLOCK_IP_ZB_LP: + break; + case GLB_AHB_CLOCK_IP_WIFI_NORMAL: + tmpValCfg2 &= ~(1 << 4); + break; + case GLB_AHB_CLOCK_IP_WIFI_LP: + break; + case GLB_AHB_CLOCK_IP_BT_BLE_2_NORMAL: + tmpValCfg2 &= ~(1 << 10); + break; + case GLB_AHB_CLOCK_IP_BT_BLE_2_LP: + break; + case GLB_AHB_CLOCK_IP_EMI_MISC: + tmpValCfg2 &= ~(1 << 16); + break; + case GLB_AHB_CLOCK_IP_PSRAM0_CTRL: + tmpValCfg2 &= ~(1 << 17); + break; + case GLB_AHB_CLOCK_IP_PSRAM1_CTRL: + tmpValCfg2 &= ~(1 << 18); + break; + case GLB_AHB_CLOCK_IP_USB20: + tmpValCfg1 &= ~(1 << 13); + break; + case GLB_AHB_CLOCK_IP_MIX2: + tmpValCfg2 &= ~(1 << 20); + break; + case GLB_AHB_CLOCK_IP_AUDIO: + tmpValCfg2 &= ~(1 << 21); + break; + case GLB_AHB_CLOCK_IP_SDH: + tmpValCfg2 &= ~(1 << 22); + break; + case GLB_AHB_CLOCK_IP_ZB2_NORMAL: + tmpValCfg2 &= ~(1 << 11); + break; + case GLB_AHB_CLOCK_IP_ZB2_LP: + break; + case GLB_AHB_CLOCK_IP_I2C1: + tmpValCfg1 &= ~(1 << 25); + break; + case GLB_AHB_CLOCK_IP_WIFI_PHY: + tmpValCfg0 &= ~(1 << 7); + break; + case GLB_AHB_CLOCK_IP_WIFI_MAC_PHY: + tmpValCfg0 &= ~(1 << 6); + break; + case GLB_AHB_CLOCK_IP_WIFI_PLATFORM: + tmpValCfg0 &= ~(1 << 5); + break; + case GLB_AHB_CLOCK_IP_LZ4: + tmpValCfg1 &= ~(1 << 29); + break; + case GLB_AHB_CLOCK_IP_AUPDM: + tmpValCfg1 &= ~(1 << 28); + break; + case GLB_AHB_CLOCK_IP_GAUGE: + tmpValCfg1 &= ~(1 << 0); + break; + default: + break; + } + } + } + BL_WR_REG(GLB_BASE, GLB_CGEN_CFG0, tmpValCfg0); + BL_WR_REG(GLB_BASE, GLB_CGEN_CFG1, tmpValCfg1); + BL_WR_REG(GLB_BASE, GLB_CGEN_CFG2, tmpValCfg2); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief release IPs clock + * + * @param ips: GLB_AHB_CLOCK_xxx | GLB_AHB_CLOCK_xxx | ...... (not GLB_AHB_CLOCK_IP_xxx) + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type GLB_PER_Clock_UnGate(uint64_t ips) +{ + /* api request from cjy */ + + uint32_t tmpValCfg0 = 0; + uint32_t tmpValCfg1 = 0; + uint32_t tmpValCfg2 = 0; + uint32_t bitfield = 0; + + tmpValCfg0 = BL_RD_REG(GLB_BASE, GLB_CGEN_CFG0); + tmpValCfg1 = BL_RD_REG(GLB_BASE, GLB_CGEN_CFG1); + tmpValCfg2 = BL_RD_REG(GLB_BASE, GLB_CGEN_CFG2); + while (ips) { + if (SUCCESS == GLB_Get_And_Clr_First_Set_From_U64(&ips, &bitfield)) { + switch (bitfield) { + case GLB_AHB_CLOCK_IP_CPU: + tmpValCfg0 |= (1 << 0); + break; + case GLB_AHB_CLOCK_IP_SDU: + tmpValCfg0 |= (1 << 1); + break; + case GLB_AHB_CLOCK_IP_SEC: + tmpValCfg0 |= (1 << 2); + tmpValCfg1 |= (1 << 3); + tmpValCfg1 |= (1 << 4); + break; + case GLB_AHB_CLOCK_IP_DMA_0: + tmpValCfg0 |= (1 << 3); + tmpValCfg1 |= (1 << 12); + break; + case GLB_AHB_CLOCK_IP_DMA_1: + tmpValCfg0 |= (1 << 3); + break; + case GLB_AHB_CLOCK_IP_DMA_2: + tmpValCfg0 |= (1 << 3); + tmpValCfg2 |= (1 << 24); + break; + case GLB_AHB_CLOCK_IP_CCI: + tmpValCfg0 |= (1 << 4); + break; + case GLB_AHB_CLOCK_IP_RF_TOP: + tmpValCfg1 |= (1 << 1); + break; + case GLB_AHB_CLOCK_IP_GPIP: + tmpValCfg1 |= (1 << 2); + break; + case GLB_AHB_CLOCK_IP_TZC: + tmpValCfg1 |= (1 << 5); + break; + case GLB_AHB_CLOCK_IP_EF_CTRL: + tmpValCfg1 |= (1 << 7); + break; + case GLB_AHB_CLOCK_IP_SF_CTRL: + tmpValCfg1 |= (1 << 11); + break; + case GLB_AHB_CLOCK_IP_EMAC: + tmpValCfg2 |= (1 << 19); + tmpValCfg2 |= (1 << 23); + break; + case GLB_AHB_CLOCK_IP_UART0: + tmpValCfg1 |= (1 << 16); + break; + case GLB_AHB_CLOCK_IP_UART1: + tmpValCfg1 |= (1 << 17); + break; + case GLB_AHB_CLOCK_IP_UART2: + tmpValCfg1 |= (1 << 26); + break; + case GLB_AHB_CLOCK_IP_UART3: + break; + case GLB_AHB_CLOCK_IP_UART4: + break; + case GLB_AHB_CLOCK_IP_SPI: + tmpValCfg1 |= (1 << 18); + break; + case GLB_AHB_CLOCK_IP_I2C: + tmpValCfg1 |= (1 << 19); + break; + case GLB_AHB_CLOCK_IP_PWM: + tmpValCfg1 |= (1 << 20); + break; + case GLB_AHB_CLOCK_IP_TIMER: + tmpValCfg1 |= (1 << 21); + break; + case GLB_AHB_CLOCK_IP_IR: + tmpValCfg1 |= (1 << 22); + break; + case GLB_AHB_CLOCK_IP_CHECKSUM: + tmpValCfg1 |= (1 << 23); + break; + case GLB_AHB_CLOCK_IP_QDEC: + break; + case GLB_AHB_CLOCK_IP_KYS: + break; + case GLB_AHB_CLOCK_IP_I2S: + tmpValCfg1 |= (1 << 23); + break; + case GLB_AHB_CLOCK_IP_USB11: + break; + case GLB_AHB_CLOCK_IP_CAM: + break; + case GLB_AHB_CLOCK_IP_MJPEG: + break; + case GLB_AHB_CLOCK_IP_BT_BLE_NORMAL: + tmpValCfg2 |= (1 << 8); + break; + case GLB_AHB_CLOCK_IP_BT_BLE_LP: + break; + case GLB_AHB_CLOCK_IP_ZB_NORMAL: + tmpValCfg2 |= (1 << 9); + break; + case GLB_AHB_CLOCK_IP_ZB_LP: + break; + case GLB_AHB_CLOCK_IP_WIFI_NORMAL: + tmpValCfg2 |= (1 << 4); + break; + case GLB_AHB_CLOCK_IP_WIFI_LP: + break; + case GLB_AHB_CLOCK_IP_BT_BLE_2_NORMAL: + tmpValCfg2 |= (1 << 10); + break; + case GLB_AHB_CLOCK_IP_BT_BLE_2_LP: + break; + case GLB_AHB_CLOCK_IP_EMI_MISC: + tmpValCfg2 |= (1 << 16); + break; + case GLB_AHB_CLOCK_IP_PSRAM0_CTRL: + tmpValCfg2 |= (1 << 17); + break; + case GLB_AHB_CLOCK_IP_PSRAM1_CTRL: + tmpValCfg2 |= (1 << 18); + break; + case GLB_AHB_CLOCK_IP_USB20: + tmpValCfg1 |= (1 << 13); + break; + case GLB_AHB_CLOCK_IP_MIX2: + tmpValCfg2 |= (1 << 20); + break; + case GLB_AHB_CLOCK_IP_AUDIO: + tmpValCfg2 |= (1 << 21); + break; + case GLB_AHB_CLOCK_IP_SDH: + tmpValCfg2 |= (1 << 22); + break; + case GLB_AHB_CLOCK_IP_ZB2_NORMAL: + tmpValCfg2 |= (1 << 11); + break; + case GLB_AHB_CLOCK_IP_ZB2_LP: + break; + case GLB_AHB_CLOCK_IP_I2C1: + tmpValCfg1 |= (1 << 25); + break; + case GLB_AHB_CLOCK_IP_WIFI_PHY: + tmpValCfg0 |= (1 << 7); + break; + case GLB_AHB_CLOCK_IP_WIFI_MAC_PHY: + tmpValCfg0 |= (1 << 6); + break; + case GLB_AHB_CLOCK_IP_WIFI_PLATFORM: + tmpValCfg0 |= (1 << 5); + break; + case GLB_AHB_CLOCK_IP_LZ4: + tmpValCfg1 |= (1 << 29); + break; + case GLB_AHB_CLOCK_IP_AUPDM: + tmpValCfg1 |= (1 << 28); + break; + case GLB_AHB_CLOCK_IP_GAUGE: + tmpValCfg1 |= (1 << 0); + break; + default: + break; + } + } + } + BL_WR_REG(GLB_BASE, GLB_CGEN_CFG0, tmpValCfg0); + BL_WR_REG(GLB_BASE, GLB_CGEN_CFG1, tmpValCfg1); + BL_WR_REG(GLB_BASE, GLB_CGEN_CFG2, tmpValCfg2); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief software reset + * + * @param swrst: reset num + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type GLB_AHB_MCU_Software_Reset(GLB_AHB_MCU_SW_Type swrst) +{ + uint32_t tmpVal = 0; + uint32_t bit = 0; + uint32_t regAddr = 0; + + CHECK_PARAM(IS_GLB_AHB_MCU_SW_TYPE(swrst)); + + if (swrst < 32) { + bit = swrst; + regAddr = GLB_BASE + GLB_SWRST_CFG0_OFFSET; + } else if (swrst < 64) { + bit = swrst - 32; + regAddr = GLB_BASE + GLB_SWRST_CFG1_OFFSET; + } else if (swrst < 96) { + bit = swrst - 64; + regAddr = GLB_BASE + GLB_SWRST_CFG2_OFFSET; + } + + tmpVal = BL_RD_WORD(regAddr); + tmpVal &= ~(1 << bit); + BL_WR_WORD(regAddr, tmpVal); + BL_DRV_DUMMY; + tmpVal = BL_RD_WORD(regAddr); + tmpVal |= (1 << bit); + BL_WR_WORD(regAddr, tmpVal); + BL_DRV_DUMMY; + tmpVal = BL_RD_WORD(regAddr); + tmpVal &= ~(1 << bit); + BL_WR_WORD(regAddr, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief software reset + * + * @param swrst: reset num + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type GLB_AHB_DSP_Software_Reset(GLB_AHB_DSP_SW_Type swrst) +{ + uint32_t tmpVal = 0; + uint32_t bit = 0; + uint32_t regAddr = 0; + + CHECK_PARAM(IS_GLB_AHB_DSP_SW_TYPE(swrst)); + + if (swrst < 32) { + bit = swrst; + regAddr = MM_GLB_BASE + MM_GLB_MM_SW_SYS_RESET_OFFSET; + } else if (swrst < 64) { + bit = swrst - 32; + regAddr = MM_GLB_BASE + MM_GLB_SW_RESET_MM_PERI_OFFSET; + } else if (swrst < 96) { + bit = swrst - 64; + regAddr = MM_GLB_BASE + MM_GLB_SW_RESET_DSP2_SUB_OFFSET; + } else if (swrst < 128) { + bit = swrst - 96; + regAddr = MM_GLB_BASE + MM_GLB_SW_RESET_CODEC_SUB_OFFSET; + } else if (swrst < 160) { + bit = swrst - 128; + regAddr = MM_GLB_BASE + MM_GLB_IMAGE_SENSOR_CTRL_OFFSET; + } + + tmpVal = BL_RD_WORD(regAddr); + tmpVal &= ~(1 << bit); + BL_WR_WORD(regAddr, tmpVal); + BL_DRV_DUMMY; + tmpVal = BL_RD_WORD(regAddr); + tmpVal |= (1 << bit); + BL_WR_WORD(regAddr, tmpVal); + BL_DRV_DUMMY; + tmpVal = BL_RD_WORD(regAddr); + tmpVal &= ~(1 << bit); + BL_WR_WORD(regAddr, tmpVal); + + return SUCCESS; +} + +/*@} end of group GLB_Public_Functions */ + +/*@} end of group GLB */ + +/*@} end of group BL808_Peripheral_Driver */ diff --git a/platforms/bl808_m0/vendor/psram/src/bl808_psram_uhs.c b/platforms/bl808_m0/vendor/psram/src/bl808_psram_uhs.c new file mode 100644 index 0000000..838c9b8 --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/src/bl808_psram_uhs.c @@ -0,0 +1,827 @@ +/** + ****************************************************************************** + * @file bl808_psram_uhs.c + * @version V1.0 + * @date + * @brief This file is the standard driver c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +#include "bl808_psram_uhs.h" +#include "bl808_common.h" +#include "bl808_glb.h" +#include "psram_uhs_reg.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup PSRAM_UHS + * @{ + */ + +/** @defgroup PSRAM_UHS_Private_Macros + * @{ + */ +#define PSRAM_UHS_RW_TIMEOUT 0xffffffff +/*@} end of group PSRAM_UHS_Private_Macros */ + +/** @defgroup PSRAM_UHS_Private_Types + * @{ + */ + +/*@} end of group PSRAM_UHS_Private_Types */ + +/** @defgroup PSRAM_UHS_Private_Variables + * @{ + */ + +/*@} end of group PSRAM_UHS_Private_Variables */ + +/** @defgroup PSRAM_UHS_Global_Variables + * @{ + */ + +/*@} end of group PSRAM_UHS_Global_Variables */ + +/** @defgroup PSRAM_UHS_Private_Fun_Declaration + * @{ + */ + +/*@} end of group PSRAM_UHS_Private_Fun_Declaration */ + +/** @defgroup PSRAM_UHS_Private_Functions + * @{ + */ + +/*@} end of group PSRAM_UHS_Private_Functions */ + +/** @defgroup PSRAM_UHS_Public_Functions + * @{ + */ +int config_uhs_phy(uint32_t datarate) +{ + uint32_t tmpVal = 0; + + if (datarate > 1866) { + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_30_OFFSET, 0xAA0A1323); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_34_OFFSET, 0x0b030404); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_38_OFFSET, 0x050e0419); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_3C_OFFSET, 0x0a6a1c1c); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_44_OFFSET, 0x0711070e); + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_PHY_WL_CEN_ANA, 1); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal); + + } else if (datarate > 1600) { + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_30_OFFSET, 0xAA283203); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_34_OFFSET, 0x0a020303); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_38_OFFSET, 0x040d0416); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_3C_OFFSET, 0x091e1818); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_44_OFFSET, 0x0710070d); + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_PHY_WL_CEN_ANA, 3); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal); + + } else if (datarate > 1066) { + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_30_OFFSET, 0xAA270212); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_34_OFFSET, 0x09020303); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_38_OFFSET, 0x040c0313); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_3C_OFFSET, 0x07d11515); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_44_OFFSET, 0x060f060c); + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_PHY_WL_CEN_ANA, 1); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal); + } else if (datarate > 800) { + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_30_OFFSET, 0xAA270212); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_34_OFFSET, 0x06010202); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_38_OFFSET, 0x0309020d); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_3C_OFFSET, 0x05360e0e); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_44_OFFSET, 0x050c0509); + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_PHY_WL_CEN_ANA, 1); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal); + + } else if (datarate > 666) { + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_30_OFFSET, 0xAA041020); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_34_OFFSET, 0x05000101); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_38_OFFSET, 0x0208010a); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_3C_OFFSET, 0x03e90b0b); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_44_OFFSET, 0x040b0408); + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_PHY_WL_CEN_ANA, 0); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal); + } else if (datarate > 400) { + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_30_OFFSET, 0xAA130010); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_34_OFFSET, 0x05000101); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_38_OFFSET, 0x02080108); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_3C_OFFSET, 0x03420909); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_44_OFFSET, 0x040b0408); + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_PHY_WL_CEN_ANA, 0); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal); + } else { + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_30_OFFSET, 0xAA020010); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_34_OFFSET, 0x04000101); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_38_OFFSET, 0x02070106); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_3C_OFFSET, 0x01f50606); + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_44_OFFSET, 0x040a0407); + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_PHY_WL_CEN_ANA, 0); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal); + } + return 0; +} + +static void power_up_ldo12uhs(void) +{ + uint32_t tmpVal = 0; + tmpVal = BL_RD_REG(GLB_BASE, GLB_LDO12UHS); + +#ifdef BL808D_REWORK + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_LDO12UHS_PULLDOWN, 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_LDO12UHS_PULLDOWN_SEL, 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_PU_LDO12UHS, 0); +#else + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_PU_LDO12UHS, 1); + BL_WR_REG(GLB_BASE, GLB_LDO12UHS, tmpVal); + arch_delay_us(300); + + tmpVal = BL_RD_REG(GLB_BASE, GLB_LDO12UHS); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_LDO12UHS_VOUT_SEL, 6); +#endif + BL_WR_REG(GLB_BASE, GLB_LDO12UHS, tmpVal); + arch_delay_us(1); +} + +static void set_cen_ck_ckn(void) +{ + uint32_t tmpVal = 0; + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_DQ_OE_MID_N_REG, 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_DQ_OE_MID_P_REG, 0); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal); + arch_delay_us(1); + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_40); + tmpVal &= 0xFFFCFFFF; + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_UHS_DMY0, 1); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_40, tmpVal); + arch_delay_us(1); +} + +static int set_or_uhs(uint32_t datarate) +{ + uint32_t tmpVal = 0; + uint32_t *uhs_phy_cfg_base_addr = (uint32_t *)(PSRAM_UHS_BASE + PSRAM_UHS_PHY_CFG_00_OFFSET); + // clang-format off + const static uint32_t uhs_phy_cfg_data[] ={ + 0x802b0200, 0x60206020, 0x70027002, 0x70027002, + 0x70027002, 0x70027002, 0x70027002, 0x70027002, + 0x70027002, 0x70027002, 0x26000000, 0x26000006, + }; + // clang-format on + + for (uint32_t i = 0; i < 12; i++) { + uhs_phy_cfg_base_addr[i] = uhs_phy_cfg_data[i]; + } + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_30); + tmpVal &= 0x08ffffff; + tmpVal |= 0x07000000; + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_30, tmpVal); + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_48); + tmpVal &= 0xfffffcff; + tmpVal |= 0x00000200; + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_48, tmpVal); + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_4C); + tmpVal &= 0xffe0ffff; + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_4C, tmpVal); + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50); + tmpVal &= 0xff88ff88; + tmpVal |= 0x00330033; + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal); + + arch_delay_us(1); + + return 0; +} +static void switch_to_ldo12uhs(void) +{ + uint32_t tmpVal = 0; + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_40); + tmpVal &= 0xFFCFFFFF; + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_40, tmpVal); + arch_delay_us(1); +} + +static void release_cen_ck_ckn(void) +{ + uint32_t tmpVal = 0; + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_40); + tmpVal &= 0xFFFCFEFF; +#ifdef BL808D_REWORK + tmpVal |= 0x10000; +#else + tmpVal |= 0x30000; +#endif + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_40, tmpVal); + arch_delay_us(1); + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_DQ_OE_MID_N_REG, 3); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_DQ_OE_MID_P_REG, 3); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal); + arch_delay_us(1); +} + +static void Psram_analog_init(uint32_t pck_freq) +{ + /* power on ldo12 */ + power_up_ldo12uhs(); + + /* set cen ck ckn */ + set_cen_ck_ckn(); + + /* + * overwrite default register content + * only support 2000M and 1500MHZ + */ + set_or_uhs(pck_freq); + + /* switch to ldo12 */ + switch_to_ldo12uhs(); + + /* release cen ck */ + release_cen_ck_ckn(); + + /* config phy paramater */ + config_uhs_phy(pck_freq); +} + +/****************************************************************************/ /** + * @brief Init Psram UHS ,set auto refresh cycle + * + * @param cfg: pck frequency unit is MHZ + * + * @return None + * +*******************************************************************************/ +void Psram_UHS_Init(PSRAM_UHS_Cfg_Type *cfg) +{ + uint32_t tmpVal = 0; + + CHECK_PARAM(IS_PSRAM_UHS_MEM_SIZE_TYPE(cfg->psramMemSize)); + CHECK_PARAM(IS_PSRAM_UHS_PAGE_SIZE_TYPE(cfg->psramPageSize)); + + if (cfg->pck_freq > 2300) { + /* max support 2300MHZ */ + while (1) + ; + } else if (cfg->pck_freq > 1600) { + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_UHS_TIMING_CTRL_OFFSET, 0x1a03000f); + } else { + BL_WR_WORD(PSRAM_UHS_BASE + PSRAM_UHS_UHS_TIMING_CTRL_OFFSET, 0x1202000b); + } + + Psram_analog_init(cfg->pck_freq); + + /* Wait 150 us */ + arch_delay_us(150); + + /* set refresh paramater */ + /* 1. auto refresh clock source is pck_t, Adjust pck_t_div so that the frequency is around ~50Mhz */ +/* tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_MANUAL); + tmpVal &= 0x00ffffff; + + if (cfg->pck_freq >= 2200) { + tmpVal |= 0x05000000; + } else if (cfg->pck_freq >= 2000) { + tmpVal |= 0x04000000; + } else if (cfg->pck_freq >= 1500) { + tmpVal |= 0x03000000; + } else if (cfg->pck_freq >= 1400) { + tmpVal |= 0x02000000; + } else if (cfg->pck_freq >= 666) { + tmpVal |= 0x01000000; + } + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_MANUAL, tmpVal); */ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_MANUAL); + tmpVal &= 0x00ffffff; + + if (cfg->pck_freq >= 2200) { + tmpVal |= 0x05000000; + } else if (cfg->pck_freq >= 1800) { + tmpVal |= 0x04000000; + } else if (cfg->pck_freq >= 1500) { + tmpVal |= 0x03000000; + } else if (cfg->pck_freq >= 1400) { + tmpVal |= 0x02000000; + } else if (cfg->pck_freq >= 666) { + tmpVal |= 0x01000000; + } + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_MANUAL, tmpVal); + + /* 2. setting refresh windows cycle count + * reg_win_cycle = refresh_window / Tpck_y + * + * refresh_window unit is ms + * when refresh tempotory > 85 + * refresh_window = 16 + * elsee + * refresh_window = 32 + */ + if (cfg->isHighTem == PSRAM_UHS_NORMAL_TEMP) { + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_AUTO_FRESH_1, 0x16e360); + } else { + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_AUTO_FRESH_1, 0xB71B0); + } + /* 3 & 4. setting refresh count in a windows fixed value 4096 in v0.2 + * calculate Average cycle between two auto-refresh + * reg_refi_cycle = reg_win_cycle / reg_win_ref_cnt + * */ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_AUTO_FRESH_2); + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_WIN_REF_CNT, 0x1000); + if (cfg->isHighTem == PSRAM_UHS_NORMAL_TEMP) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_REFI_CYCLE, (370)); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_REFI_CYCLE, (190)); + } + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_AUTO_FRESH_2, tmpVal); + + /* 5 setting single auto refresh time */ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_AUTO_FRESH_4); + // tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_BUST_CYCLE, (uint32_t)(90 / T_pck_t)); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_BUST_CYCLE, 5); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_AUTO_FRESH_4, tmpVal); + + /* 6 auto-refesh enable */ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC); + tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_AF_EN); + + /* 7&8 . set psram memory size and page size */ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_ADDRMB_MSK, cfg->psramMemSize); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_LINEAR_BND_B, cfg->psramPageSize); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal); + + /* 9. psram enable initial */ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC); + tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_INIT_EN); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal); +} + +/****************************************************************************/ /** + * @brief Read register for uhs + * + * @param reg_addr: read addr + * @param regVal: regVal + * + * @return success or not + * +*******************************************************************************/ +int PSram_UHS_Read_Reg(uint32_t reg_addr, uint8_t *regVal) +{ + uint32_t tmpVal = 0; + uint32_t cnt = 0; + + /* 1 generate requeset and wait authorization*/ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC); + tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_CONFIG_REQ); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal); + + do { + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC); + cnt++; + if (cnt > PSRAM_UHS_RW_TIMEOUT) + return -1; + } while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_UHS_REG_CONFIG_GNT)); + + /* 2 set mode reg */ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_MODE_REG, reg_addr); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal); + + /* 3 enable controller Rx*/ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD); + tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_REGR_PULSE); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD, tmpVal); + + cnt = 0; + + /* 4 wait read done */ + do { + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD); + cnt++; + if (cnt > PSRAM_UHS_RW_TIMEOUT) + return -1; + } while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_UHS_STS_REGR_DONE)); + + /* 5 steup up read data */ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD); + + *regVal = (uint8_t)(BL_GET_REG_BITS_VAL(tmpVal, PSRAM_UHS_STS_CONFIG_READ)); + + /* 6 cancel requeset singnal */ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC); + tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_CONFIG_REQ); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal); + + return 0; +} + +/****************************************************************************/ /** + * @brief write register for winbond PSRAM + * + * @param regCfg: wirte reg data + * + * @return None + * +*******************************************************************************/ +int PSram_UHS_Write_Reg(PSRAM_UHS_Write_Reg_Cfg_Type *regCfg) +{ + uint32_t tmpVal = 0; + uint32_t cnt = 0; + uint8_t regWriteList[] = { 0, 2 }; + uint8_t i = 0; + + CHECK_PARAM(IS_PSRAM_UHS_DRIVER_ST_TYPE(regCfg->driver_st)); + CHECK_PARAM(IS_PSRAM_UHS_WARP_BURST_TYPE(regCfg->burst_size)); + CHECK_PARAM(IS_PSRAM_UHS_LATENCY_TYPE(regCfg->lentency)); + + /* 1 congfi write reg*/ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_PSRAM_CONFIGURE); + + switch (regCfg->burst_size) { + case PSRAM_UHS_WARP_BURST_64: + tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_64); + tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_32); + tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_16); + break; + case PSRAM_UHS_WARP_BURST_32: + tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_16); + tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_32); + tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_64); + break; + case PSRAM_UHS_WARP_BURST_16: + tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_16); + tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_32); + tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_64); + break; + case PSRAM_UHS_WARP_BURST_NONE: + tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_16); + tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_32); + tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_UHS_BL_64); + break; + default: + return -1; + } + if (regCfg->driver_st != PSRAM_UHS_DRIVER_ST_NO_CHANGE) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_UHS_DRIVE_ST, regCfg->driver_st); + } + if (regCfg->lentency != PSRAM_UHS_LATENCY_NO_CHANGE) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_UHS_LATENCY, regCfg->lentency); + } + + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_PSRAM_CONFIGURE, tmpVal); + + /* 2 generate requeset and wait authorization */ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC); + tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_CONFIG_REQ); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal); + + do { + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC); + cnt++; + if (cnt > PSRAM_UHS_RW_TIMEOUT) + return -1; + } while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_UHS_REG_CONFIG_GNT)); + + for (i = 0; i < sizeof(regWriteList) / sizeof(uint8_t); i++) { + /* 3 set mode reg */ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_MODE_REG, regWriteList[i]); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal); + + /* 4 enable controller */ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD); + tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_REGW_PULSE); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD, tmpVal); + + cnt = 0; + + /* 5 wait write done */ + do { + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD); + cnt++; + if (cnt > PSRAM_UHS_RW_TIMEOUT) + return -1; + } while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_UHS_STS_REGW_DONE)); + } + + /* 6 cancel requeset singnal */ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC); + tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_CONFIG_REQ); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal); + + return 0; +} + +/****************************************************************************/ /** + * @brief Timing Reset + * + * @param reg_addr: reg_addr + * @param regCfg: wirte reg data + * + * @return None + * +*******************************************************************************/ +int PSram_UHS_Timing_Reset(void) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_40); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_UHS_DMY1, 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_UHS_DMY0, 1); + + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_40, tmpVal); + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_DQ_OE_MID_N_REG, 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_DQ_OE_MID_P_REG, 0); + + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal); + + arch_delay_us(1000); + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_40); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_UHS_DMY1, 3); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_UHS_DMY0, 0); + + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_40, tmpVal); + + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_DQ_OE_MID_N_REG, 4); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_DQ_OE_MID_P_REG, 4); + + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_PHY_CFG_50, tmpVal); + + return 0; +} + +/****************************************************************************/ /** + * @brief construct cmd wave for psram + * + * @param reg_addr: reg_addr + * @param regCfg: wirte reg data + * + * @return None + * +*******************************************************************************/ +int PSram_UHS_Construct_Cmd(PSRAM_UHS_CMD_Type cmd) +{ + uint32_t tmpVal = 0; + uint32_t cnt = 0; + + CHECK_PARAM(IS_PSRAM_UHS_CMD_TYPE(cmd)); + + /* generate requeset and wait authorization*/ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC); + tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_CONFIG_REQ); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal); + + do { + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC); + cnt++; + if (cnt > PSRAM_UHS_RW_TIMEOUT) + goto exit; + } while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_UHS_REG_CONFIG_GNT)); + + /* enable cmd generate */ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD); + + switch (cmd) { + case PSRAM_UHS_CMD_SELF_REFRESH_IN: + tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_SRFI_PULSE); + break; + case PSRAM_UHS_CMD_SELF_REFRESH_EXIT: + tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_SRFO_PULSE); + break; + case PSRAM_UHS_CMD_GLOBAL_RESET: + tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_GLBR_PULSE); + /* Wait 15 us for reset */ + arch_delay_us(15); + break; + case PSRAM_UHS_CMD_ZQ_CAL_LONG: + + /* 3 set mode reg */ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_MODE_REG, 5); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal); + + /* 4 enable controller */ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD); + tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_REGW_PULSE); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD, tmpVal); + + cnt = 0; + + /* 5 wait write done */ + do { + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD); + cnt++; + if (cnt > PSRAM_UHS_RW_TIMEOUT) + goto exit; + } while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_UHS_STS_REGW_DONE)); + + break; + case PSRAM_UHS_CMD_ZQ_CAL_SHORT: + + /* 3 set mode reg */ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_MODE_REG, 6); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal); + + /* 4 enable controller */ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD); + tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_REGW_PULSE); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD, tmpVal); + + cnt = 0; + + /* 5 wait write done */ + do { + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD); + cnt++; + if (cnt > PSRAM_UHS_RW_TIMEOUT) + goto exit; + } while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_UHS_STS_REGW_DONE)); + break; + case PSRAM_UHS_CMD_ZQ_CAL_RESET: + + /* 3 set mode reg */ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PSRAM_UHS_REG_MODE_REG, 7); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal); + + /* 4 enable controller */ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD); + tmpVal = BL_SET_REG_BIT(tmpVal, PSRAM_UHS_REG_REGW_PULSE); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD, tmpVal); + + cnt = 0; + + /* 5 wait write done */ + do { + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD); + cnt++; + if (cnt > PSRAM_UHS_RW_TIMEOUT) + goto exit; + } while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_UHS_STS_REGW_DONE)); + break; + default: + goto exit; + break; + } + + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD, tmpVal); + + cnt = 0; + + /* wait write done */ + switch (cmd) { + case PSRAM_UHS_CMD_SELF_REFRESH_IN: + do { + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD); + cnt++; + if (cnt > PSRAM_UHS_RW_TIMEOUT) + goto exit; + + } while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_UHS_STS_SRFI_DONE)); + break; + case PSRAM_UHS_CMD_SELF_REFRESH_EXIT: + do { + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD); + cnt++; + if (cnt > PSRAM_UHS_RW_TIMEOUT) + goto exit; + + } while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_UHS_STS_SRFO_DONE)); + break; + case PSRAM_UHS_CMD_GLOBAL_RESET: + do { + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_CMD); + cnt++; + if (cnt > PSRAM_UHS_RW_TIMEOUT) + goto exit; + + } while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_UHS_STS_GLBR_DONE)); + break; + default: + goto exit; + } + + /* 6 cancel requeset singnal */ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC); + tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_CONFIG_REQ); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal); + + return 0; + +exit: + /* 6 cancel requeset singnal */ + tmpVal = BL_RD_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC); + tmpVal = BL_CLR_REG_BIT(tmpVal, PSRAM_UHS_REG_CONFIG_REQ); + BL_WR_REG(PSRAM_UHS_BASE, PSRAM_UHS_UHS_BASIC, tmpVal); + + return -1; +} + +/** + * @brief defualt init for 64MB x16 UHS PSRAM + * user should enable UHS PSRAM PLL before call this function + * @param uhs_pll_clk The uhs pll frequency used + */ +void Psram_UHS_x16_Init(uint32_t uhs_pll_clk) +{ + PSRAM_UHS_Cfg_Type psramDefaultCfg = { + 2000, + PSRAM_MEM_SIZE_64MB, + PSRAM_PAGE_SIZE_2KB, + PSRAM_UHS_NORMAL_TEMP, + }; + + PSRAM_UHS_Write_Reg_Cfg_Type writeReg = { + PSRAM_UHS_DRIVER_ST_40_PDPU, + PSRAM_UHS_WARP_BURST_NONE, + PSRAM_UHS_LATENCY_W18_R37_MAX_FRE_1066_MHZ, + }; + + psramDefaultCfg.pck_freq = uhs_pll_clk; + + if ((uhs_pll_clk >= 2000) && (uhs_pll_clk <= 2300)) { + writeReg.lentency = PSRAM_UHS_LATENCY_W18_R37_MAX_FRE_1066_MHZ; + } else if ((uhs_pll_clk <= 1600) && (uhs_pll_clk > 1066)) { + writeReg.lentency = PSRAM_UHS_LATENCY_W14_R29_MAX_FRE_800_MHZ; + } else if ((uhs_pll_clk < 1067) && (uhs_pll_clk > 800)) { + writeReg.lentency = PSRAM_UHS_LATENCY_W10_R20_MAX_FRE_533_MHZ; + } else if ((uhs_pll_clk <= 800) && (uhs_pll_clk > 667)) { + writeReg.lentency = PSRAM_UHS_LATENCY_W6_R16_MAX_FRE_400_MHZ; + } else if ((uhs_pll_clk < 667) && (uhs_pll_clk > 400)) { + writeReg.lentency = PSRAM_UHS_LATENCY_W5_R13_MAX_FRE_333_MHZ; + } else if (uhs_pll_clk <= 400) { + writeReg.lentency = PSRAM_UHS_LATENCY_W5_R9_MAX_FRE_200_MHZ; + } + + /* first initial psram controller*/ + Psram_UHS_Init(&psramDefaultCfg); + + /* reset psram device*/ + PSram_UHS_Construct_Cmd(PSRAM_UHS_CMD_GLOBAL_RESET); + + arch_delay_us(100); + + /* write 1GHZ configuration to psram device */ + PSram_UHS_Write_Reg(&writeReg); +} + +/*@} end of group PSRAM_UHS_Public_Functions */ + +/*@} end of group PSRAM_UHS */ + +/*@} end of group BL808_Peripheral_Driver */ diff --git a/platforms/bl808_m0/vendor/psram/src/bl_psram.c b/platforms/bl808_m0/vendor/psram/src/bl_psram.c new file mode 100644 index 0000000..aef3c1e --- /dev/null +++ b/platforms/bl808_m0/vendor/psram/src/bl_psram.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016-2022 Bouffalolab. + * + * This file is part of + * *** Bouffalolab Software Dev Kit *** + * (see www.bouffalolab.com). + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "bl_psram.h" +#ifdef BL808 +#include +#include + +int bl_psram_init(void) +{ + GLB_Config_UHS_PLL(GLB_XTAL_40M, uhsPllCfg_2000M); + Psram_UHS_x16_Init(2000); + return 0; +} + +#elif defined(BL606P) +#include +int bl_psram_init(void) +{ + puts("--> dummy PSRAM init implemented\r\n"); + return 0; +} +#endif + diff --git a/platforms/bl808_m0/vendor/wifi/PATCHES.md b/platforms/bl808_m0/vendor/wifi/PATCHES.md new file mode 100644 index 0000000..bf8964e --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/PATCHES.md @@ -0,0 +1,33 @@ +# BL808 M0 WiFi Vendor Patches + +This directory is based on `sipeed/M1s_BL808_SDK` +`bf7e689cf49d57dd529e2492e5264ef602ed5b3c`. + +Keep this file in sync when changing files under `include/` or `src/`. + +## Header / build fixes + +- `include/lmac_msg.h`: removed the unused `wifi_mgmr_ext.h` include. +- `include/bl_rx.h`: removed the unused `wifi_mgmr_ext.h` include. +- `include/lmac_msg.h`: split `cfg_start_req_u_tlv_t` into a tagged + struct type and `extern` declaration. The definition lives in + `src/bl_globals.c`; the upstream flexible-array variable definition relied + on old `-fcommon` behaviour. +- `src/ipc_host.c`: fixed `ipc_emb2app_status_get()` and + `ipc_emb2app_rawstatus_get()` calls to match the no-argument declarations. + +## Runtime fixes + +- `src/ipc_host.c`: removed high-volume TX descriptor debug prints. +- `src/bl_msg_tx.c`: STA connect requests set `WPA_WPA2_IN_USE` and + `CONTROL_PORT_NO_ENC` when a PSK/PMK is supplied, so EAPOL can complete + before data encryption is enabled. +- `src/bl_msg_tx.c`: invalid/out-of-range auth type falls back to open-system + authentication. +- `src/bl_msg_tx.c`: AP start requests use 11b basic rates only, set + `DISABLE_HT`, mark WPA/WPA2 when a password is present, and size the rate + set from the actual local rate array. +- `src/bl_mod_params.c`: `ht_on=false` keeps the firmware in legacy 11bg mode. + The BL808 AP path emitted malformed HT Operation IEs with HT enabled. +- `src/bl_shim.c`: `bl_shim_sta_connect()` accepts PMK and frequency hints and + forwards them through `cfg80211_connect_params`. diff --git a/platforms/bl808_m0/vendor/wifi/README.md b/platforms/bl808_m0/vendor/wifi/README.md new file mode 100644 index 0000000..fe6e27c --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/README.md @@ -0,0 +1,92 @@ +# BL808 M0 WiFi vendor material + +Closed binaries and the minimum vendor C needed to drive them. The OpenWatt +M0 image links these in; all sequencing, lifetime management, and event +dispatch lives in `urt.driver.bl808.wifi`. + +## Provenance + +Extracted from [sipeed/M1s_BL808_SDK](https://github.com/sipeed/M1s_BL808_SDK) +at commit `bf7e689cf49d57dd529e2492e5264ef602ed5b3c` (2023-02-18). + +The SDK is a Sipeed fork of Bouffalo's `bl_iot_sdk`, frozen at this commit. +We re-fetch only when chasing a specific upstream change. + +## Layout + +``` +lib/ -- closed binary archives (verbatim) + libwifi.a (5.6 MB) -- WiFi MAC / LMAC / scan / AP / STA + libbl606p_phyrf.a (1.5 MB) -- PHY/RF driver, RF calibration + +include/ -- API contract with the blobs + lmac_msg.h, lmac_mac.h -- LMAC<->host message format + lmac_types.h + ipc_shared.h, ipc_compat.h -- shared-memory descriptor layout + reg_ipc_app.h, reg_access.h + bl_defs.h -- struct bl_hw central state + bl_cmds.h, bl_irqs.h, bl_msg_tx.h, bl_utils.h, bl_rx.h + bl_mod_params.h, bl_strs.h + bl60x_fw_api.h, bl_phy_api.h, rd.h + ipc_host.h + cfg80211.h, ieee80211.h, nl80211.h, errno.h -- Linux-style helper headers + list.h, utils_list.h, utils_tlv_bl.h + bl_os_adapter/ -- g_bl_ops_funcs struct + opaque handles + bl_os_adapter.h, bl_os_log.h, bl_os_private.h + bl_os_system.h, bl_os_type.h + lwip/pbuf.h -- LOCAL stub, see below + +src/ -- vendor C we keep and compile + ipc_host.c (12 KB) -- shared-memory ring management + bl_cmds.c (9 KB) -- command/reply correlation + bl_irqs.c (2 KB) -- IRQ bottom-half + bl_msg_tx.c (38 KB) -- RPC stubs (alloc msg, fill fields, send) + utils_list.c (10 KB) -- linked-list implementation +``` + +## What we do NOT pull in + +Dropped from the SDK entirely (and re-implemented in D where needed): + +- `wifi_mgmr*.c` (~5 KLoC) -- state machine, CLI, profile loading. The + `BuiltinWiFi`/`BuiltinWlan`/`BuiltinAp` BaseObject classes replace this. +- `bl_main.c` -- init sequencing. Handled by `urt.driver.bl808.wifi`. +- `bl_rx.c` -- event dispatch + callback registration. D switch instead. +- `bl_tx.c` -- TX path. Was lwIP-pbuf entangled; rewritten in D. +- `bl_utils.c` -- mostly RX-path helpers; the three functions we need + (`bl_ipc_init`, `bl_utils_pbuf_alloc`, `bl_utils_pbuf_free`, + `bl_utils_idx_lookup`) are provided by D as `extern(C)`. +- `wifi_netif.c`, `wifi_pkt_hooks.c` -- lwIP shims. +- `stateMachine*.c` -- generic FSM library. +- `wifi_hosal/` -- HAL glue we replace with D. +- AOS yloop, FreeRTOS, lwIP, wpa_supplicant -- entirely. + +## OS dependency + +`libwifi.a` does NOT reference any FreeRTOS symbol directly. All OS +primitives are funnelled through a single function-pointer table +`g_bl_ops_funcs` (defined in `bl_os_adapter/bl_os_adapter.h`). We supply +that table from D backed by urt -- no FreeRTOS in the build. + +## Patches applied to upstream + +Tracked in `PATCHES.md`. + +## The lwIP shim + +`include/lwip/pbuf.h` is OURS, not from the SDK. It provides a minimal +layout-compatible `struct pbuf` so `ipc_host.c` compiles without dragging +in lwIP. The D side allocates packet wrappers whose first fields match +this layout. + +## Resync procedure + +To pull a newer snapshot from upstream: + +1. Clone `sipeed/M1s_BL808_SDK` (or `bouffalolab/bl_iot_sdk` for newer + LMAC versions -- different protocol, expect breakage) into + `third_party/bouffalo_wifi/` (gitignored). +2. Diff `components/network/wifi_manager/bl60x_wifi_driver/` and + `components/network/wifi/` against this directory. +3. Re-apply the patches listed above. +4. Rebuild and smoke-test STA association before merging. diff --git a/platforms/bl808_m0/vendor/wifi/include/bl60x_fw_api.h b/platforms/bl808_m0/vendor/wifi/include/bl60x_fw_api.h new file mode 100644 index 0000000..8280991 --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/bl60x_fw_api.h @@ -0,0 +1,579 @@ +#ifndef __BL60x_FW_API_H__ +#define __BL60x_FW_API_H__ + +//#include +#include +#include "bl_os_private.h" + +/// Tasks types. +typedef enum wifi_fw_task_id +{ + TASK_NONE = (uint8_t) -1, + + /// MAC Management task. + TASK_MM = 0, + /// SCAN task + TASK_SCAN, + /// SCAN task + TASK_SCANU, + /// SCAN task + TASK_ME, + /// SM task + TASK_SM, + /// APM task + TASK_APM, + /// BAM task + TASK_BAM, + /// RXU task + TASK_RXU, + + TASK_CFG, + + // This is used to define the last task that is running on the EMB processor + TASK_LAST_EMB = TASK_CFG, + + // nX API task + TASK_API, + TASK_MAX, +} ke_task_id_t; + +/// For MAC HW States. +typedef enum hw_state_tag +{ + /// MAC HW IDLE State. + HW_IDLE = 0, + /// MAC HW RESERVED State. + HW_RESERVED, + /// MAC HW DOZE State. + HW_DOZE, + /// MAC HW ACTIVE State. + HW_ACTIVE +} hw_state_tag_t; + +/// Possible States of the MM STA Task. +typedef enum mm_state_tag +{ + /// MAC IDLE State. + MM_IDLE, + /// MAC ACTIVE State. + MM_ACTIVE, + /// MAC is going to IDLE + MM_GOING_TO_IDLE, + /// IDLE state internally controlled + MM_HOST_BYPASSED, + /// MAC Max Number of states. + MM_STATE_MAX +} mm_state_tag_t; + +/** + **************************************************************************************** + * @brief Builds the first message ID of a task + * @param[in] task Task identifier + * @return The identifier of the first message of the task + **************************************************************************************** + */ +#define KE_FIRST_MSG(task) (((task) << 10)) + +/// Message Identifier. The number of messages is limited to 0xFFFF. +/// The message ID is divided in two parts: +/// bits[15~8]: task index (no more than 255 tasks support) +/// bits[7~0]: message index(no more than 255 messages per task) +typedef enum wifi_fw_event_id +{ + /// RESET Request. + MM_RESET_REQ = KE_FIRST_MSG(TASK_MM), + /// RESET Confirmation. + MM_RESET_CFM, + /// START Request. + MM_START_REQ, + /// START Confirmation. + MM_START_CFM, + /// Read Version Request. + MM_VERSION_REQ, + /// Read Version Confirmation. + MM_VERSION_CFM, + /// ADD INTERFACE Request. + MM_ADD_IF_REQ, + /// ADD INTERFACE Confirmation. + MM_ADD_IF_CFM, + /// REMOVE INTERFACE Request. + MM_REMOVE_IF_REQ, + /// REMOVE INTERFACE Confirmation. + MM_REMOVE_IF_CFM, + /// STA ADD Request. + MM_STA_ADD_REQ, + /// STA ADD Confirm. + MM_STA_ADD_CFM, + /// STA DEL Request. + MM_STA_DEL_REQ, + /// STA DEL Confirm. + MM_STA_DEL_CFM, + /// CHANNEL CONFIGURATION Request. + MM_SET_CHANNEL_REQ, + /// CHANNEL CONFIGURATION Confirmation. + MM_SET_CHANNEL_CFM, + /// BEACON INTERVAL CONFIGURATION Request. + MM_SET_BEACON_INT_REQ, + /// BEACON INTERVAL CONFIGURATION Confirmation. + MM_SET_BEACON_INT_CFM, + /// BASIC RATES CONFIGURATION Request. + MM_SET_BASIC_RATES_REQ, + /// BASIC RATES CONFIGURATION Confirmation. + MM_SET_BASIC_RATES_CFM, + /// BSSID CONFIGURATION Request. + MM_SET_BSSID_REQ, + /// BSSID CONFIGURATION Confirmation. + MM_SET_BSSID_CFM, + /// EDCA PARAMETERS CONFIGURATION Request. + MM_SET_EDCA_REQ, + /// EDCA PARAMETERS CONFIGURATION Confirmation. + MM_SET_EDCA_CFM, + /// Request setting the VIF active state (i.e associated or AP started) + MM_SET_VIF_STATE_REQ, + /// Confirmation of the @ref MM_SET_VIF_STATE_REQ message. + MM_SET_VIF_STATE_CFM, + /// IDLE mode change Request. + MM_SET_IDLE_REQ, + /// IDLE mode change Confirm. + MM_SET_IDLE_CFM, + /// Indication of the primary TBTT to the upper MAC. Upon the reception of this + /// message the upper MAC has to push the beacon(s) to the beacon transmission queue. + MM_PRIMARY_TBTT_IND, + /// Indication of the secondary TBTT to the upper MAC. Upon the reception of this + /// message the upper MAC has to push the beacon(s) to the beacon transmission queue. + MM_SECONDARY_TBTT_IND, + /// Request to the LMAC to trigger the embedded logic analyzer and forward the debug + /// dump. + MM_DENOISE_REQ, + /// Set Power Save mode + MM_SET_PS_MODE_REQ, + /// Set Power Save mode confirmation + MM_SET_PS_MODE_CFM, + /// Request to add a channel context + MM_CHAN_CTXT_ADD_REQ, + /// Confirmation of the channel context addition + MM_CHAN_CTXT_ADD_CFM, + /// Request to delete a channel context + MM_CHAN_CTXT_DEL_REQ, + /// Confirmation of the channel context deletion + MM_CHAN_CTXT_DEL_CFM, + /// Request to link a channel context to a VIF + MM_CHAN_CTXT_LINK_REQ, + /// Confirmation of the channel context link + MM_CHAN_CTXT_LINK_CFM, + /// Request to unlink a channel context from a VIF + MM_CHAN_CTXT_UNLINK_REQ, + /// Confirmation of the channel context unlink + MM_CHAN_CTXT_UNLINK_CFM, + /// Request to update a channel context + MM_CHAN_CTXT_UPDATE_REQ, + /// Confirmation of the channel context update + MM_CHAN_CTXT_UPDATE_CFM, + /// Request to schedule a channel context + MM_CHAN_CTXT_SCHED_REQ, + /// Confirmation of the channel context scheduling + MM_CHAN_CTXT_SCHED_CFM, + /// Request to change the beacon template in LMAC + MM_BCN_CHANGE_REQ, + /// Confirmation of the beacon change + MM_BCN_CHANGE_CFM, + /// Request to update the TIM in the beacon (i.e to indicate traffic bufferized at AP) + MM_TIM_UPDATE_REQ, + /// Confirmation of the TIM update + MM_TIM_UPDATE_CFM, + /// Connection loss indication + MM_CONNECTION_LOSS_IND, + /// Channel context switch indication to the upper layers + MM_CHANNEL_SWITCH_IND, + /// Channel context pre-switch indication to the upper layers + MM_CHANNEL_PRE_SWITCH_IND, + /// Request to remain on channel or cancel remain on channel + MM_REMAIN_ON_CHANNEL_REQ, + /// Confirmation of the (cancel) remain on channel request + MM_REMAIN_ON_CHANNEL_CFM, + /// Remain on channel expired indication + MM_REMAIN_ON_CHANNEL_EXP_IND, + /// Indication of a PS state change of a peer device + MM_PS_CHANGE_IND, + /// Indication that some buffered traffic should be sent to the peer device + MM_TRAFFIC_REQ_IND, + /// Request to modify the STA Power-save mode options + MM_SET_PS_OPTIONS_REQ, + /// Confirmation of the PS options setting + MM_SET_PS_OPTIONS_CFM, + /// Indication of PS state change for a P2P VIF + MM_P2P_VIF_PS_CHANGE_IND, + /// Message containing channel information + MM_CHANNEL_SURVEY_IND, + /// Message containing Beamformer information + MM_BFMER_ENABLE_REQ, + /// Request to Start/Stop NOA - GO Only + MM_SET_P2P_NOA_REQ, + /// Request to Start/Stop Opportunistic PS - GO Only + MM_SET_P2P_OPPPS_REQ, + /// Start/Stop NOA Confirmation + MM_SET_P2P_NOA_CFM, + /// Start/Stop Opportunistic PS Confirmation + MM_SET_P2P_OPPPS_CFM, + /// P2P NoA Update Indication - GO Only + MM_P2P_NOA_UPD_IND, + /// Indication that RSSI is below or above the threshold + MM_RSSI_STATUS_IND, + /// Request to update the group information of a station + MM_MU_GROUP_UPDATE_REQ, + /// Confirmation of the @ref MM_MU_GROUP_UPDATE_REQ message + MM_MU_GROUP_UPDATE_CFM, + //Enable monitor mode + MM_MONITOR_REQ, + MM_MONITOR_CFM, + //Channel set under monitor mode + MM_MONITOR_CHANNEL_REQ, + MM_MONITOR_CHANNEL_CFM, + + /* + * Section of internal MM messages. No MM API messages should be defined below this point + */ + /// Internal request to force the HW going to IDLE + MM_FORCE_IDLE_REQ, + /// Message indicating that the switch to the scan channel is done + MM_SCAN_CHANNEL_START_IND, + /// Message indicating that the scan can end early + MM_SCAN_CHANNEL_END_EARLY, + /// Message indicating that the scan on the channel is finished + MM_SCAN_CHANNEL_END_IND, + + /// MAX number of messages + MM_MAX, + + /// Request to start the AP. + CFG_START_REQ = KE_FIRST_MSG(TASK_CFG), + CFG_START_CFM, + CFG_MAX, + + + /// Scanning start Request. + SCAN_START_REQ = KE_FIRST_MSG(TASK_SCAN), + /// Scanning start Confirmation. + SCAN_START_CFM, + /// End of scanning indication. + SCAN_DONE_IND, + /// Cancel scan request + SCAN_CANCEL_REQ, + /// Cancel scan confirmation + SCAN_CANCEL_CFM, + + /// Abort scan request + SCAN_ABORT_REQ, + SCAN_ABORT_CFM, + + /* + * Section of internal SCAN messages. No SCAN API messages should be defined below this point + */ + SCAN_TIMER, + + /// MAX number of messages + SCAN_MAX, + + /// Request to start the AP. + APM_START_REQ = KE_FIRST_MSG(TASK_APM), + /// Confirmation of the AP start. + APM_START_CFM, + /// Request to stop the AP. + APM_STOP_REQ, + /// Confirmation of the AP stop. + APM_STOP_CFM, + /// Nofity host that a station has joined the network + APM_STA_ADD_IND, + /// Nofity host that a station has left the network + APM_STA_DEL_IND, + /// Check sta connect timeout + APM_STA_CONNECT_TIMEOUT_IND, + /// Request to delete STA + APM_STA_DEL_REQ, + /// Confirmation of delete STA + APM_STA_DEL_CFM, + /// CONF MAX STA Request + APM_CONF_MAX_STA_REQ, + /// CONF MAX STA Confirm + APM_CONF_MAX_STA_CFM, + /// MAX number of messages + APM_MAX, + + /// BAM addition response timeout + BAM_ADD_BA_RSP_TIMEOUT_IND = KE_FIRST_MSG(TASK_BAM), + /// BAM Inactivity timeout + BAM_INACTIVITY_TIMEOUT_IND, + + /// Configuration request from host. + ME_CONFIG_REQ = KE_FIRST_MSG(TASK_ME), + /// Configuration confirmation. + ME_CONFIG_CFM, + /// Configuration request from host. + ME_CHAN_CONFIG_REQ, + /// Configuration confirmation. + ME_CHAN_CONFIG_CFM, + /// TKIP MIC failure indication. + ME_TKIP_MIC_FAILURE_IND, + /// Add a station to the FW (AP mode) + ME_STA_ADD_REQ, + /// Confirmation of the STA addition + ME_STA_ADD_CFM, + /// Delete a station from the FW (AP mode) + ME_STA_DEL_REQ, + /// Confirmation of the STA deletion + ME_STA_DEL_CFM, + /// Indication of a TX RA/TID queue credit update + ME_TX_CREDITS_UPDATE_IND, + /// Request indicating to the FW that there is traffic buffered on host + ME_TRAFFIC_IND_REQ, + /// Confirmation that the @ref ME_TRAFFIC_IND_REQ has been executed + ME_TRAFFIC_IND_CFM, + /// Request RC fixed rate + ME_RC_SET_RATE_REQ, + + /* + * Section of internal ME messages. No ME API messages should be defined below this point + */ + /// Internal request to indicate that a VIF needs to get the HW going to ACTIVE or IDLE + ME_SET_ACTIVE_REQ, + /// Confirmation that the switch to ACTIVE or IDLE has been executed + ME_SET_ACTIVE_CFM, + /// Internal request to indicate that a VIF desires to de-activate/activate the Power-Save mode + ME_SET_PS_DISABLE_REQ, + /// Confirmation that the PS state de-activate/activate has been executed + ME_SET_PS_DISABLE_CFM, + /// MAX number of messages + ME_MAX, + + /// Management frame reception indication + RXU_MGT_IND = KE_FIRST_MSG(TASK_RXU), + /// NULL frame reception indication + RXU_NULL_DATA, + + /// Scan request from host. + SCANU_START_REQ = KE_FIRST_MSG(TASK_SCANU), + /// Scanning start Confirmation. + SCANU_START_CFM, + /// Join request + SCANU_JOIN_REQ, + /// Join confirmation. + SCANU_JOIN_CFM, + /// Scan result indication. + SCANU_RESULT_IND, + /// Scan RAW Data Send from host + SCANU_RAW_SEND_REQ, + /// Scan result indication. + SCANU_RAW_SEND_CFM, + + /// MAX number of messages + SCANU_MAX, + + /// Request to connect to an AP + SM_CONNECT_REQ = KE_FIRST_MSG(TASK_SM), + /// Confirmation of connection + SM_CONNECT_CFM, + /// Indicates that the SM associated to the AP + SM_CONNECT_IND, + /// Request to disconnect + SM_DISCONNECT_REQ, + /// Confirmation of disconnection + SM_DISCONNECT_CFM, + /// Indicates that the SM disassociated the AP + SM_DISCONNECT_IND, + /// Timeout message for procedures requiring a response from peer + SM_RSP_TIMEOUT_IND, + /// Request to cancel connect when connecting + SM_CONNECT_ABORT_REQ, + /// Confirmation of connect abort + SM_CONNECT_ABORT_CFM, + /// Timeout message for requiring a SA Query Response from AP + SM_SA_QUERY_TIMEOUT_IND, + /// MAX number of messages + SM_MAX, +} ke_msg_id_t; + +/*--------------------------------------------------------------------*/ +/* Status Codes - these codes are used in bouffalolab fw actions */ +/* when an error action is taking place the status code can indicate */ +/* what the status code. */ +/* It is defined by bouffaloalb */ +/*--------------------------------------------------------------------*/ +#define WLAN_FW_SUCCESSFUL 0 +#define WLAN_FW_TX_AUTH_FRAME_ALLOCATE_FAIILURE 1 +#define WLAN_FW_AUTHENTICATION_FAIILURE 2 +#define WLAN_FW_AUTH_ALGO_FAIILURE 3 +#define WLAN_FW_TX_ASSOC_FRAME_ALLOCATE_FAIILURE 4 +#define WLAN_FW_ASSOCIATE_FAIILURE 5 +#define WLAN_FW_DEAUTH_BY_AP_WHEN_NOT_CONNECTION 6 +#define WLAN_FW_DEAUTH_BY_AP_WHEN_CONNECTION 7 +#define WLAN_FW_4WAY_HANDSHAKE_ERROR_PSK_TIMEOUT_FAILURE 8 +#define WLAN_FW_4WAY_HANDSHAKE_TX_DEAUTH_FRAME_TRANSMIT_FAILURE 9 +#define WLAN_FW_4WAY_HANDSHAKE_TX_DEAUTH_FRAME_ALLOCATE_FAIILURE 10 +#define WLAN_FW_AUTH_OR_ASSOC_RESPONSE_TIMEOUT_FAILURE 11 +#define WLAN_FW_SCAN_NO_BSSID_AND_CHANNEL 12 +#define WLAN_FW_CREATE_CHANNEL_CTX_FAILURE_WHEN_JOIN_NETWORK 13 +#define WLAN_FW_JOIN_NETWORK_FAILURE 14 +#define WLAN_FW_ADD_STA_FAILURE 15 +#define WLAN_FW_BEACON_LOSS 16 +#define WLAN_FW_JOIN_NETWORK_SECURITY_NOMATCH 17 +#define WLAN_FW_JOIN_NETWORK_WEPLEN_ERROR 18 +#define WLAN_FW_DISCONNECT_BY_USER_WITH_DEAUTH 19 +#define WLAN_FW_DISCONNECT_BY_USER_NO_DEAUTH 20 +#define WLAN_FW_DISCONNECT_BY_FW_PS_TX_NULLFRAME_FAILURE 21 +#define WLAN_FW_TRAFFIC_LOSS 22 +#define WLAN_FW_CONNECT_ABORT_BY_USER_WITH_DEAUTH 23 +#define WLAN_FW_CONNECT_ABORT_BY_USER_NO_DEAUTH 24 +#define WLAN_FW_CONNECT_ABORT_WHEN_JOINING_NETWORK 25 +#define WLAN_FW_CONNECT_ABORT_WHEN_SCANNING 26 + + +/*--------------------------------------------------------------------*/ +/* AP Mode Status Codes - these codes are used in bouffalolab fw actions */ +/* when an error action is taking place the status code can indicate */ +/* what the status code. */ +/* It is defined by bouffaloalb */ +/*--------------------------------------------------------------------*/ +#define WLAN_FW_APM_SUCCESSFUL 0 +#define WLAN_FW_APM_DELETESTA_BY_USER 1 +#define WLAN_FW_APM_DEATUH_BY_STA 2 +#define WLAN_FW_APM_DISASSOCIATE_BY_STA 3 +#define WLAN_FW_APM_DELETECONNECTION_TIMEOUT 4 +#define WLAN_FW_APM_DELETESTA_FOR_NEW_CONNECTION 5 +#define WLAN_FW_APM_DEAUTH_BY_AUTHENTICATOR 6 + +void bl60x_fw_xtal_capcode_set(uint8_t cap_in, uint8_t cap_out, uint8_t enable, uint8_t cap_in_max, uint8_t cap_out_max); +void bl60x_fw_xtal_capcode_update(uint8_t cap_in, uint8_t cap_out); +void bl60x_fw_xtal_capcode_restore(void); +void bl60x_fw_xtal_capcode_autofit(void); +void bl60x_fw_xtal_capcode_get(uint8_t *cap_in, uint8_t *cap_out); +//void bl60x_fw_rf_tx_power_table_set(bl_tx_pwr_tbl_t* pwr_table); +int bl60x_fw_password_hash(char *password, char *ssid, int ssidlength, char *output); +void bl60x_fw_rf_table_set(uint32_t* channel_div_table_in, uint16_t* channel_cnt_table_in, + uint16_t lo_fcal_div); + +void bl60x_fw_dump_data(void); +void bl60x_fw_dump_statistic(int forced); + +int bl60x_check_mac_status(int *is_ok); + +enum { + /// Background + API_AC_BK = 0, + /// Best-effort + API_AC_BE, + /// Video + API_AC_VI, + /// Voice + API_AC_VO, + /// Number of access categories + API_AC_MAX +}; + +int bl60x_edca_get(int ac, uint8_t *aifs, uint8_t *cwmin, uint8_t *cwmax, uint16_t *txop); + +/*Wi-Fi Firmware Entry*/ +void wifi_main(void *param); + +void bl_tpc_update_power_table(int8_t power_table_config[38]); +void bl_tpc_update_power_table_rate(int8_t power_table[24]); +void bl_tpc_update_power_table_channel_offset(int8_t power_table[14]); +void bl_tpc_update_power_rate_11b(int8_t power_rate_table[4]); +void bl_tpc_update_power_rate_11g(int8_t power_rate_table[8]); +void bl_tpc_update_power_rate_11n(int8_t power_rate_table[8]); +void bl_tpc_power_table_get(int8_t power_table_config[38]); + +void phy_cli_register(void); + + + +enum task_mm_cfg { + TASK_MM_CFG_KEEP_ALIVE_STATUS_ENABLED, + TASK_MM_CFG_KEEP_ALIVE_TIME_LAST_RECEIVED, + TASK_MM_CFG_KEEP_ALIVE_PACKET_COUNTER, +}; + +enum task_sm_cfg { + TASK_SM_CFG_AUTH_ASSOC_RETRY_LIMIT, +}; + +enum task_scan_cfg { + TASK_SCAN_CFG_DURATION_SCAN_PASSIVE, + TASK_SCAN_CFG_DURATION_SCAN_ACTIVE, + TASK_SCAN_CFG_DURATION_SCAN_JOIN_ACTIVE, +}; + +typedef enum{ + /**version part**/ + SM_CONNECTION_DATA_TLV_ID_VERSION, + /**Status part**/ + SM_CONNECTION_DATA_TLV_ID_STATUS_CODE, + SM_CONNECTION_DATA_TLV_ID_DHCPSTATUS, + /**frame part**/ + SM_CONNECTION_DATA_TLV_ID_AUTH_1, + SM_CONNECTION_DATA_TLV_ID_AUTH_2, + SM_CONNECTION_DATA_TLV_ID_AUTH_3, + SM_CONNECTION_DATA_TLV_ID_AUTH_4, + SM_CONNECTION_DATA_TLV_ID_ASSOC_REQ, + SM_CONNECTION_DATA_TLV_ID_ASSOC_RSP, + SM_CONNECTION_DATA_TLV_ID_4WAY_1, + SM_CONNECTION_DATA_TLV_ID_4WAY_2, + SM_CONNECTION_DATA_TLV_ID_4WAY_3, + SM_CONNECTION_DATA_TLV_ID_4WAY_4, + SM_CONNECTION_DATA_TLV_ID_2WAY_1, + SM_CONNECTION_DATA_TLV_ID_2WAY_2, + SM_CONNECTION_DATA_TLV_ID_DEAUTH, + /**striped frame part**/ + SM_CONNECTION_DATA_TLV_ID_STRIPED_AUTH_1, + SM_CONNECTION_DATA_TLV_ID_STRIPED_AUTH_2, + SM_CONNECTION_DATA_TLV_ID_STRIPED_AUTH_3, + SM_CONNECTION_DATA_TLV_ID_STRIPED_AUTH_4, + SM_CONNECTION_DATA_TLV_ID_STRIPED_AUTH_UNVALID, + SM_CONNECTION_DATA_TLV_ID_STRIPED_ASSOC_REQ, + SM_CONNECTION_DATA_TLV_ID_STRIPED_ASSOC_RSP, + SM_CONNECTION_DATA_TLV_ID_STRIPED_DEAUTH_FROM_REMOTE, + SM_CONNECTION_DATA_TLV_ID_STRIPED_DEASSOC_FROM_REMOTE, + SM_CONNECTION_DATA_TLV_ID_RESERVED, +} sm_connection_data_tlv_id_t; + +/* structure of a list element header */ +struct sm_tlv_list_hdr +{ + struct sm_tlv_list_hdr *next; +}; + +/* structure of a list */ +struct sm_tlv_list +{ + struct sm_tlv_list_hdr *first; + struct sm_tlv_list_hdr *last; +}; + +/* + * TLV ID数据以链表的形式存储在struct sm_connect_tlv_desc中, + * callback需要遍历这个链表来获取所有的数据 + */ +struct sm_connect_tlv_desc { + struct sm_tlv_list_hdr list_hdr; + sm_connection_data_tlv_id_t id; + uint16_t len; + uint8_t data[0]; +}; + +#ifdef TD_DIAGNOSIS_STA +typedef struct wifi_diagnosis_info +{ + uint32_t beacon_recv; + uint32_t beacon_loss; + uint32_t beacon_total; + uint64_t unicast_recv; + uint64_t unicast_send; + uint64_t multicast_recv; + uint64_t multicast_send; +}wifi_diagnosis_info_t; + +wifi_diagnosis_info_t *bl_diagnosis_get(void); +int wifi_td_diagnosis_init(void); +int wifi_td_diagnosis_deinit(void); +#endif + +#endif /*__BL60x_FW_API_H__*/ diff --git a/platforms/bl808_m0/vendor/wifi/include/bl_cmds.h b/platforms/bl808_m0/vendor/wifi/include/bl_cmds.h new file mode 100644 index 0000000..3186a00 --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/bl_cmds.h @@ -0,0 +1,75 @@ +#ifndef __RWNX_CMDS_H__ +#define __RWNX_CMDS_H__ + +#include "list.h" + +#include "lmac_types.h" +#include "lmac_msg.h" +#include "ipc_shared.h" +#include "bl_os_private.h" + +#define BIT(n) (0x1U << (n)) + +#define RWNX_CMD_FLAG_NONBLOCK BIT(0) +#define RWNX_CMD_FLAG_REQ_CFM BIT(1) +#define RWNX_CMD_FLAG_WAIT_PUSH BIT(2) +#define RWNX_CMD_FLAG_WAIT_ACK BIT(3) +#define RWNX_CMD_FLAG_WAIT_CFM BIT(4) +#define RWNX_CMD_FLAG_DONE BIT(5) + +/** + **************************************************************************************** + * + * @file bl_cmds.h + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + +#define RWNX_CMD_WAIT_COMPLETE(flags) \ + (!(flags & (RWNX_CMD_FLAG_WAIT_ACK | RWNX_CMD_FLAG_WAIT_CFM))) + +//TODO fix the follow ugly declare +struct bl_hw; +struct bl_cmd; +typedef int (*msg_cb_fct)(struct bl_hw *bl_hw, struct bl_cmd *cmd, struct ipc_e2a_msg *msg); + +#define RWNX_CMD_MAX_QUEUED 8 +struct bl_cmd { + struct list_head list; + ke_msg_id_t id; + ke_msg_id_t reqid; + struct lmac_msg *a2e_msg; + char *e2a_msg; + u32 tkn; + u16 flags; + + BL_EventGroup_t complete; + u32 result; +}; + +enum bl_cmd_mgr_state { + RWNX_CMD_MGR_STATE_DEINIT, + RWNX_CMD_MGR_STATE_INITED, + RWNX_CMD_MGR_STATE_CRASHED, +}; + +struct bl_cmd_mgr { + enum bl_cmd_mgr_state state; + u32 next_tkn; + u32 queue_sz; + u32 max_queue_sz; + + struct list_head cmds; + BL_Mutex_t lock; + + int (*queue)(struct bl_cmd_mgr *, struct bl_cmd *); + int (*llind)(struct bl_cmd_mgr *, struct bl_cmd *); + int (*msgind)(struct bl_cmd_mgr *, struct ipc_e2a_msg *, msg_cb_fct); + void (*print)(struct bl_cmd_mgr *); + void (*drain)(struct bl_cmd_mgr *); +}; + +void bl_cmd_mgr_init(struct bl_cmd_mgr *cmd_mgr); + +#endif diff --git a/platforms/bl808_m0/vendor/wifi/include/bl_defs.h b/platforms/bl808_m0/vendor/wifi/include/bl_defs.h new file mode 100644 index 0000000..8cd23ac --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/bl_defs.h @@ -0,0 +1,294 @@ +#ifndef __RWNX_DEFS_H__ +#define __RWNX_DEFS_H__ +#include "errno.h" +#include "ipc_host.h" +#include "ipc_shared.h" +#include "bl_cmds.h" +#include "bl_mod_params.h" + +#define ETH_ALEN 6 +/** + **************************************************************************************** + * + * @file bl_defs.h + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + +#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ + +#include "ieee80211.h" +#include "cfg80211.h" +#include "nl80211.h" + +//#define CONFIG_RWNX_DBG + +#define RWNX_RXBUFF_MAX (4 * 1) +#define IEEE80211_MIN_AMPDU_BUF 0x8 +#define IEEE80211_MAX_AMPDU_BUF 0x40 +#define NX_VIRT_DEV_MAX 2 +#define NX_REMOTE_STA_MAX CFG_STA_MAX +#define CONFIG_USER_MAX 1 +#define cpu_to_le16(v16) (v16) +#define cpu_to_le32(v32) (v32) +#define le16_to_cpu(v16) (v16) +#define le32_to_cpu(v32) (v32) +#define RWNX_TX_LIFETIME_MS 100 + +#define IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT 2 + +#define RWNX_HWTXHDR_ALIGN_SZ 4 +#define RWNX_HWTXHDR_ALIGN_MSK (RWNX_HWTXHDR_ALIGN_SZ - 1) +#define RWNX_HWTXHDR_ALIGN_PADS(x) \ + ((RWNX_HWTXHDR_ALIGN_SZ - ((x) & RWNX_HWTXHDR_ALIGN_MSK)) \ + & RWNX_HWTXHDR_ALIGN_MSK) + +#define REG_SW_SET_PROFILING(env, value) do{ }while(0) +#define REG_SW_CLEAR_PROFILING(env, value) do{ }while(0) + +enum { + SW_PROF_HOSTBUF_IDX = 12, + /****** IPC IRQs related signals ******/ + /* E2A direction */ + SW_PROF_IRQ_E2A_RXDESC = 16, // to make sure we let 16 bits available for LMAC FW + SW_PROF_IRQ_E2A_TXCFM, + SW_PROF_IRQ_E2A_DBG, + SW_PROF_IRQ_E2A_MSG, + SW_PROF_IPC_MSGPUSH, + SW_PROF_MSGALLOC, + SW_PROF_MSGIND, + SW_PROF_DBGIND, + + /* A2E direction */ + SW_PROF_IRQ_A2E_TXCFM_BACK, + + /****** Driver functions related signals ******/ + SW_PROF_WAIT_QUEUE_STOP, + SW_PROF_WAIT_QUEUE_WAKEUP, + SW_PROF_RWNXDATAIND, + SW_PROF_RWNX_IPC_IRQ_HDLR, + SW_PROF_RWNX_IPC_THR_IRQ_HDLR, + SW_PROF_IEEE80211RX, + SW_PROF_RWNX_PATTERN, + SW_PROF_MAX +}; + +/* + * * Maximum length of AMPDU that the STA can receive. + * * Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets) + * */ +enum ieee80211_max_ampdu_length_exp { + IEEE80211_HT_MAX_AMPDU_8K = 0, + IEEE80211_HT_MAX_AMPDU_16K = 1, + IEEE80211_HT_MAX_AMPDU_32K = 2, + IEEE80211_HT_MAX_AMPDU_64K = 3 +}; + + +/* U-APSD queues for WMM IEs sent by STA */ +#define IEEE80211_WMM_IE_STA_QOSINFO_AC_VO (1<<0) +#define IEEE80211_WMM_IE_STA_QOSINFO_AC_VI (1<<1) +#define IEEE80211_WMM_IE_STA_QOSINFO_AC_BK (1<<2) +#define IEEE80211_WMM_IE_STA_QOSINFO_AC_BE (1<<3) +#define IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK 0x0f +/** +* enum ieee80211_vht_mcs_support - VHT MCS support definitions +* @IEEE80211_VHT_MCS_SUPPORT_0_7: MCSes 0-7 are supported for the +* number of streams +* @IEEE80211_VHT_MCS_SUPPORT_0_8: MCSes 0-8 are supported +* @IEEE80211_VHT_MCS_SUPPORT_0_9: MCSes 0-9 are supported +* @IEEE80211_VHT_MCS_NOT_SUPPORTED: This number of streams isn't supported +* +* These definitions are used in each 2-bit subfield of the @rx_mcs_map +* and @tx_mcs_map fields of &struct ieee80211_vht_mcs_info, which are +* both split into 8 subfields by number of streams. These values indicate +* which MCSes are supported for the number of streams the value appears +* for. +*/ +enum ieee80211_vht_mcs_support { + IEEE80211_VHT_MCS_SUPPORT_0_7 = 0, + IEEE80211_VHT_MCS_SUPPORT_0_8 = 1, + IEEE80211_VHT_MCS_SUPPORT_0_9 = 2, + IEEE80211_VHT_MCS_NOT_SUPPORTED = 3, +}; + +enum RWNX_INTERFACE_STATUS { + RWNX_INTERFACE_STATUS_DOWN = 0, + RWNX_INTERFACE_STATUS_UP = 1, +}; + +struct bl_stats { + int cfm_balance; + unsigned long last_rx, last_tx; /* jiffies */ +}; + +struct bl_patternbuf { + u32 *buf; + u32 dma_addr; + int bufsz; +}; + +struct bl_dbginfo { + BL_Mutex_t mutex; + struct dbg_debug_dump_tag *buf; + u32 dma_addr; + int bufsz; +}; + +struct net_device_stats { + unsigned long rx_packets; + unsigned long tx_packets; + unsigned long rx_bytes; + unsigned long tx_bytes; + unsigned long rx_errors; + unsigned long tx_errors; + unsigned long rx_dropped; + unsigned long tx_dropped; + unsigned long multicast; + unsigned long collisions; + unsigned long rx_length_errors; + unsigned long rx_over_errors; + unsigned long rx_crc_errors; + unsigned long rx_frame_errors; + unsigned long rx_fifo_errors; + unsigned long rx_missed_errors; + unsigned long tx_aborted_errors; + unsigned long tx_carrier_errors; + unsigned long tx_fifo_errors; + unsigned long tx_heartbeat_errors; + unsigned long tx_window_errors; + unsigned long rx_compressed; + unsigned long tx_compressed; +}; + +/* + * Structure used to save information relative to the managed stations. + */ +struct bl_sta { + struct mac_addr sta_addr; + u8 is_used; + u8 sta_idx; /* Identifier of the station */ + u8 vif_idx; /* Identifier of the VIF (fw id) the station + belongs to */ + u8 vlan_idx; /* Identifier of the VLAN VIF (fw id) the station + belongs to (= vif_idx if no vlan in used) */ + uint8_t qos; + int8_t rssi; + uint8_t data_rate; + uint32_t tsflo; + uint32_t tsfhi; +}; + +/** + * struct bl_bcn - Information of the beacon in used (AP mode) + * + * @head: head portion of beacon (before TIM IE) + * @tail: tail portion of beacon (after TIM IE) + * @ies: extra IEs (not used ?) + * @head_len: length of head data + * @tail_len: length of tail data + * @ies_len: length of extra IEs data + * @tim_len: length of TIM IE + * @len: Total beacon len (head + tim + tail + extra) + * @dtim: dtim period + */ +struct bl_bcn { + u8 *head; + u8 *tail; + u8 *ies; + size_t head_len; + size_t tail_len; + size_t ies_len; + size_t tim_len; + size_t len; + u8 dtim; +}; + +/* + * Structure used to save information relative to the managed interfaces. + * This is also linked within the bl_hw vifs list. + * + */ +struct bl_vif { + struct list_head list; + struct netif *dev; + bool up; /* Indicate if associated netdev is up + (i.e. Interface is created at fw level) */ + union + { + struct + { + struct bl_sta *ap; /* Pointer to the peer STA entry allocated for + the AP */ + struct bl_sta *tdls_sta; /* Pointer to the TDLS station */ + } sta; + struct + { + struct list_head sta_list; /* List of STA connected to the AP */ + u8 bcmc_index; /* Index of the BCMC sta to use */ + } ap; + struct + { + struct bl_vif *master; /* pointer on master interface */ + struct bl_sta *sta_4a; + } ap_vlan; + }; +}; + +struct bl_hw { + int is_up; + struct bl_cmd_mgr cmd_mgr; + struct ipc_host_env_tag *ipc_env; /* store the IPC environment */ + struct list_head vifs; + struct bl_vif vif_table[NX_VIRT_DEV_MAX + NX_REMOTE_STA_MAX]; /* indexed with fw id */ + struct bl_sta sta_table[NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX]; + unsigned long drv_flags; + struct bl_mod_params *mod_params; + struct ieee80211_sta_ht_cap ht_cap; + int vif_index_sta; + int vif_index_ap; + + /*custom added id*/ + int sta_idx; + int ap_bcmc_idx; +#ifdef CFG_BL_STATISTIC + struct bl_stats stats; +#endif +}; + +struct ethhdr { + unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ + unsigned char h_source[ETH_ALEN]; /* source ether addr */ + __be16 h_proto; /* packet type ID field */ +} __attribute__((packed)); + +/// Definitions of the RF bands +enum +{ + /// 2.4GHz Band + PHY_BAND_2G4, + /// 5GHz band + PHY_BAND_5G, + /// Number of bands + PHY_BAND_MAX, +}; + +/// Definitions of the channel bandwidths +enum +{ + /// 20MHz BW + PHY_CHNL_BW_20, + /// 40MHz BW + PHY_CHNL_BW_40, + /// 80MHz BW + PHY_CHNL_BW_80, + /// 160MHz BW + PHY_CHNL_BW_160, + /// 80+80MHz BW + PHY_CHNL_BW_80P80, + /// Reserved BW + PHY_CHNL_BW_OTHER, +}; + +#endif diff --git a/platforms/bl808_m0/vendor/wifi/include/bl_irqs.h b/platforms/bl808_m0/vendor/wifi/include/bl_irqs.h new file mode 100644 index 0000000..36e8d56 --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/bl_irqs.h @@ -0,0 +1,23 @@ + +/** + **************************************************************************************** + * + * @file bl_irqs.h + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + +#ifndef _RWNX_IRQS_H_ +#define _RWNX_IRQS_H_ +#include +#include "bl_defs.h" + +int bl_irqs_init(struct bl_hw *bl_hw); +int bl_irqs_enable(void); +int bl_irqs_disable(void); +int bl_irqs_notify(void); +int bl_irq_wait_event(uint32_t tick); +void bl_irq_bottomhalf(struct bl_hw *bl_hw); + +#endif /* _RWNX_IRQS_H_ */ diff --git a/platforms/bl808_m0/vendor/wifi/include/bl_mod_params.h b/platforms/bl808_m0/vendor/wifi/include/bl_mod_params.h new file mode 100644 index 0000000..71d303d --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/bl_mod_params.h @@ -0,0 +1,43 @@ + +/** + **************************************************************************************** + * + * @file bl_mod_params.h + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + + +#ifndef _RWNX_MOD_PARAM_H_ +#define _RWNX_MOD_PARAM_H_ +#include "lmac_types.h" +#include "bl_defs.h" +#include "cfg80211.h" + +struct bl_mod_params { + bool ht_on; + bool vht_on; + int mcs_map; + int phy_cfg; + int uapsd_timeout; + bool sgi; + bool sgi80; + bool use_2040; + int listen_itv; + bool listen_bcmc; + int lp_clk_ppm; + bool ps_on; + int tx_lft; + int amsdu_maxnb; + int uapsd_queues; +}; + +extern struct bl_mod_params bl_mod_params; + +struct bl_hw; +void bl_enable_wapi(struct bl_hw *bl_hw); +void bl_enable_mfp(struct bl_hw *bl_hw); +int bl_handle_dynparams(struct bl_hw *bl_hw); + +#endif /* _RWNX_MOD_PARAM_H_ */ diff --git a/platforms/bl808_m0/vendor/wifi/include/bl_msg_tx.h b/platforms/bl808_m0/vendor/wifi/include/bl_msg_tx.h new file mode 100644 index 0000000..bfb9169 --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/bl_msg_tx.h @@ -0,0 +1,52 @@ +#ifndef __RWNX_MSG_TX_H__ +#define __RWNX_MSG_TX_H__ +#include "bl_defs.h" + +struct bl_send_scanu_para { + uint16_t *channels; + uint16_t channel_num; + struct mac_addr *bssid; + struct mac_ssid *ssid; + uint8_t *mac; + uint8_t scan_mode; + uint32_t duration_scan; +}; + +int bl_send_reset(struct bl_hw *bl_hw); +int bl_send_monitor_enable(struct bl_hw *bl_hw, struct mm_monitor_cfm *cfm); +int bl_send_monitor_disable(struct bl_hw *bl_hw, struct mm_monitor_cfm *cfm); +/* + * use_40MHZ: + * 0: Don't use 40MHZ + * 1: Use lower band as second band + * 2: Use higher band as second band + * */ +int bl_send_monitor_channel_set(struct bl_hw *bl_hw, struct mm_monitor_channel_cfm *cfm, int channel, int use_40Mhz); +int bl_send_version_req(struct bl_hw *bl_hw, struct mm_version_cfm *cfm); +int bl_send_me_config_req(struct bl_hw *bl_hw); +int bl_send_me_chan_config_req(struct bl_hw *bl_hw); +int bl_send_me_rate_config_req(struct bl_hw *bl_hw, uint8_t sta_idx, uint16_t fixed_rate_cfg); +int bl_send_start(struct bl_hw *bl_hw); +int bl_send_add_if(struct bl_hw *bl_hw, const unsigned char *mac, + enum nl80211_iftype iftype, bool p2p, struct mm_add_if_cfm *cfm); +int bl_send_remove_if(struct bl_hw *bl_hw, uint8_t inst_nbr); +int bl_send_scanu_req(struct bl_hw *bl_hw, struct bl_send_scanu_para *scanu_para); +int bl_send_scanu_raw_send(struct bl_hw *bl_hw, uint8_t *pkt, int len); +int bl_send_sm_connect_req(struct bl_hw *bl_hw, struct cfg80211_connect_params *sme, struct sm_connect_cfm *cfm); +int bl_send_sm_connect_abort_req(struct bl_hw *bl_hw, struct sm_connect_abort_cfm *cfm); +int bl_send_sm_disconnect_req(struct bl_hw *bl_hw); +int bl_send_mm_powersaving_req(struct bl_hw *bl_hw, int mode); +int bl_send_mm_denoise_req(struct bl_hw *bl_hw, int mode); +int bl_send_apm_start_req(struct bl_hw *bl_hw, struct apm_start_cfm *cfm, char *ssid, char *password, int channel, uint8_t vif_index, uint8_t hidden_ssid, uint16_t bcn_int); +int bl_send_apm_stop_req(struct bl_hw *bl_hw, uint8_t vif_idx); +int bl_send_apm_sta_del_req(struct bl_hw *bl_hw, struct apm_sta_del_cfm *cfm, uint8_t sta_idx, uint8_t vif_idx); +int bl_send_apm_conf_max_sta_req(struct bl_hw *bl_hw, uint8_t max_sta_supported); +int bl_send_cfg_task_req(struct bl_hw *bl_hw, uint32_t ops, uint32_t task, uint32_t element, uint32_t type, void *arg1, void *arg2); +int bl_send_channel_set_req(struct bl_hw *bl_hw, int channel); +void bl_msg_update_channel_cfg(const char *code); +int bl_msg_get_channel_nums(); +int bl_get_fixed_channels_is_valid(uint16_t *channels, uint16_t channel_num); +int bl_send_beacon_interval_set(struct bl_hw *bl_hw, struct mm_set_beacon_int_cfm *cfm, uint16_t beacon_int); +uint16_t phy_channel_to_freq(uint8_t band, int channel); +uint8_t phy_freq_to_channel(uint8_t band, uint16_t freq); +#endif diff --git a/platforms/bl808_m0/vendor/wifi/include/bl_os_adapter/bl_os_adapter.h b/platforms/bl808_m0/vendor/wifi/include/bl_os_adapter/bl_os_adapter.h new file mode 100644 index 0000000..0bdbeff --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/bl_os_adapter/bl_os_adapter.h @@ -0,0 +1,126 @@ +/**************************************************************************** + * components/platform/soc/bl602/bl602_os_adapter/bl602_os_adapter/include/bl_os_adapter/bl_os_adapter.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef _BL_OS_ADAPTER_H_ +#define _BL_OS_ADAPTER_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**************************************************************************** + * Definition + ****************************************************************************/ +#define BL_OS_TRUE (1) +#define BL_OS_FALSE (0) + +#define BL_OS_WAITING_FOREVER (0xffffffffUL) +#define BL_OS_NO_WAITING (0x0UL) + +#define BL_OS_ADAPTER_VERSION ((int)0x00000001) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct bl_ops_funcs +{ + int _version; + void (*_printf)(const char *fmt, ...); + void (*_puts)(const char *c); + void (*_assert)(const char *file, int line, const char *func, const char *expr); + int (*_init)(void); + uint32_t (*_enter_critical)(void); + void (*_exit_critical)(uint32_t level); + int (*_msleep)(long ms); + int (*_sleep)(unsigned int seconds); + BL_EventGroup_t (*_event_group_create)(void); + void (*_event_group_delete)(BL_EventGroup_t event); + uint32_t (*_event_group_send)(BL_EventGroup_t event, uint32_t bits); + uint32_t (*_event_group_wait)(BL_EventGroup_t event, + uint32_t bits_to_wait_for, + int clear_on_exit, + int wait_for_all_bits, + uint32_t block_time_tick); + int (*_event_register)(int type, void *cb, void *arg); + int (*_event_notify)(int evt, int val); + int (*_task_create)(const char *name, + void *entry, + uint32_t stack_depth, + void *param, + uint32_t prio, + BL_TaskHandle_t task_handle); + void (*_task_delete)(BL_TaskHandle_t task_handle); + BL_TaskHandle_t (*_task_get_current_task)(void); + BL_TaskHandle_t (*_task_notify_create)(void); + void (*_task_notify)(BL_TaskHandle_t task_handle); + void (*_task_wait)(BL_TaskHandle_t task_handle, uint32_t tick); + void (*_lock_gaint)(void); + void (*_unlock_gaint)(void); + void (*_irq_attach)(int32_t n, void *f, void *arg); + void (*_irq_enable)(int32_t n); + void (*_irq_disable)(int32_t n); + void *(*_workqueue_create)(void); + int (*_workqueue_submit_hp)(void *work, void *woker, void *argv, long tick); + int (*_workqueue_submit_lp)(void *work, void *woker, void *argv, long tick); + BL_Timer_t (*_timer_create)(void *func, void *argv); + int (*_timer_delete)(BL_Timer_t timerid, uint32_t tick); + int (*_timer_start_once)(BL_Timer_t timerid, long t_sec, long t_nsec); + int (*_timer_start_periodic)(BL_Timer_t timerid, long t_sec, long t_nsec); + BL_Sem_t (*_sem_create)(uint32_t init); + void (*_sem_delete)(BL_Sem_t semphr); + int32_t (*_sem_take)(BL_Sem_t semphr, uint32_t tick); + int32_t (*_sem_give)(BL_Sem_t semphr); + BL_Mutex_t (*_mutex_create)(void); + void (*_mutex_delete)(BL_Mutex_t mutex); + int32_t (*_mutex_lock)(BL_Mutex_t mutex); + int32_t (*_mutex_unlock)(BL_Mutex_t mutex); + BL_MessageQueue_t (*_queue_create)(uint32_t queue_len, uint32_t item_size); + void (*_queue_delete)(BL_MessageQueue_t queue); + int (*_queue_send_wait)(BL_MessageQueue_t queue, void *item, uint32_t len, uint32_t ticks, int prio); + int (*_queue_send)(BL_MessageQueue_t queue, void *item, uint32_t len); + int (*_queue_recv)(BL_MessageQueue_t queue, void *item, uint32_t len, uint32_t tick); + void *(*_malloc)(unsigned int size); + void (*_free)(void *p); + void *(*_zalloc)(unsigned int size); + uint64_t (*_get_time_ms)(void); + uint32_t (*_get_tick)(void); + void (*_log_write)(uint32_t level, const char *tag, const char *file, int line, const char *format, ...); + int (*_task_notify_isr)(BL_TaskHandle_t task_handle); + void (*_yield_from_isr)(int xYield); + unsigned int (*_ms_to_tick)(unsigned int ms); + BL_TimeOut_t (*_set_timeout)(void); + int (*_check_timeout)(BL_TimeOut_t xTimeOut, BL_TickType_t *xTicksToWait); +}; + +typedef struct bl_ops_funcs bl_ops_funcs_t; + +extern bl_ops_funcs_t g_bl_ops_funcs; + +#ifdef __cplusplus +} +#endif + +#endif /* _BL_OS_ADAPTER_H_ */ diff --git a/platforms/bl808_m0/vendor/wifi/include/bl_os_adapter/bl_os_log.h b/platforms/bl808_m0/vendor/wifi/include/bl_os_adapter/bl_os_log.h new file mode 100644 index 0000000..d8f49c6 --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/bl_os_adapter/bl_os_log.h @@ -0,0 +1,67 @@ +/**************************************************************************** + * components/platform/soc/bl602/bl602_os_adapter/bl602_os_adapter/include/bl_os_adapter/bl_os_log.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef _BL_OS_LOG_H_ +#define _BL_OS_LOG_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**************************************************************************** + * Definition + ****************************************************************************/ + +typedef enum _bl_os_log_leve +{ + LOG_LEVEL_ALL = 0, + LOG_LEVEL_DEBUG, + LOG_LEVEL_INFO, + LOG_LEVEL_WARN, + LOG_LEVEL_ERROR, + LOG_LEVEL_ASSERT, + LOG_LEVEL_NEVER, +} bl_os_log_level_t; + +#define bl_os_log_printf g_bl_ops_funcs._log_write + +#define bl_os_log_debug(M, ...) \ + bl_os_log_printf(LOG_LEVEL_DEBUG, NULL, __FILE__, __LINE__, M, ##__VA_ARGS__); + +#define bl_os_log_info(M, ...) \ + bl_os_log_printf(LOG_LEVEL_INFO, NULL, __FILE__, __LINE__, M, ##__VA_ARGS__); + +#define bl_os_log_warn(M, ...) \ + bl_os_log_printf(LOG_LEVEL_WARN, NULL, __FILE__, __LINE__, M, ##__VA_ARGS__); + +#define bl_os_log_error(M, ...) \ + bl_os_log_printf(LOG_LEVEL_ERROR, NULL, __FILE__, __LINE__, M, ##__VA_ARGS__); + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* _BL_OS_LOG_H_ */ \ No newline at end of file diff --git a/platforms/bl808_m0/vendor/wifi/include/bl_os_adapter/bl_os_private.h b/platforms/bl808_m0/vendor/wifi/include/bl_os_adapter/bl_os_private.h new file mode 100644 index 0000000..a4fee6e --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/bl_os_adapter/bl_os_private.h @@ -0,0 +1,44 @@ +/**************************************************************************** + * components/platform/soc/bl602/bl602_os_adapter/bl602_os_adapter/include/bl_os_adapter/bl_os_private.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef _BL_OS_PRIVATE_H_ +#define _BL_OS_PRIVATE_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**************************************************************************** + * Definition + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* _BL_OS_PRIVATE_H_ */ \ No newline at end of file diff --git a/platforms/bl808_m0/vendor/wifi/include/bl_os_adapter/bl_os_system.h b/platforms/bl808_m0/vendor/wifi/include/bl_os_adapter/bl_os_system.h new file mode 100644 index 0000000..1436d8b --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/bl_os_adapter/bl_os_system.h @@ -0,0 +1,780 @@ +/**************************************************************************** + * components/platform/soc/bl602/bl602_os_adapter/bl602_os_adapter/include/bl_os_adapter/bl_os_system.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef _BL_OS_SYSTEM_H_ +#define _BL_OS_SYSTEM_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**************************************************************************** + * Definition + ****************************************************************************/ + +/**************************************************************************** + * Name: assert + * + * Description: + * Validation program developer's expected result + * + * Input Parameters: + * file - configASSERT file + * line - configASSERT line + * func - configASSERT function + * expr - configASSERT condition + * + * Returned Value: + * None + * + ****************************************************************************/ + +#undef assert +#define assert(f) \ + do { \ + if (!(f)) { \ + g_bl_ops_funcs._assert(__FILE__, __LINE__, __FUNCTION__, #f); \ + } \ + } while (0) + +/**************************************************************************** + * Name: bl_os_enter_critical + * + * Description: + * Enter critical state + * Must be used in pair with bl_os_exit_critical + * + * Input Parameters: + * None + * + * Returned Value: + * CPU PS value + * + ****************************************************************************/ + +#define bl_os_enter_critical() \ + { \ + uint32_t _bl_os_flag; \ + _bl_os_flag = g_bl_ops_funcs._enter_critical(); \ + +/**************************************************************************** + * Name: bl_os_exit_critical + * + * Description: + * Exit from critical state + * Must be used in pair with bl_os_enter_critical + * + * Input Parameters: + * level - CPU PS value + * + * Returned Value: + * None + * + ****************************************************************************/ + +#define bl_os_exit_critical() \ + g_bl_ops_funcs._exit_critical(_bl_os_flag); \ + } \ + +/**************************************************************************** + * Name: bl_os_printf + * + * Description: + * Output format string and its arguments + * + * Input Parameters: + * format - format string + * + * Returned Value: + * 0 + * + ****************************************************************************/ + +#define bl_os_printf(M, ...) g_bl_ops_funcs._printf(M, ##__VA_ARGS__) + +/**************************************************************************** + * Name: bl_os_puts + * + * Description: + * Output format string + * + * Input Parameters: + * s - string + * + * Returned Value: + * 0 + * + ****************************************************************************/ + +#define bl_os_puts(S) g_bl_ops_funcs._puts(S) + +/**************************************************************************** + * Name: bl_os_msleep + * + * Description: + * Sleep in milliseconds + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#define bl_os_msleep g_bl_ops_funcs._msleep + +/**************************************************************************** + * Name: bl_os_sleep + * + * Description: + * Sleep in seconds + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#define bl_os_sleep g_bl_ops_funcs._sleep + +/**************************************************************************** + * Name: bl_os_event_group_create(FreeRTOS only) + * + * Description: + * Create event group + * + * Input Parameters: + * + * Returned Value: + * Event group data pointer + * + ****************************************************************************/ + +#define bl_os_event_group_create g_bl_ops_funcs._event_group_create + +/**************************************************************************** + * Name: bl_os_event_group_delete(FreeRTOS only) + * + * Description: + * Delete event group + * + * Input Parameters: + * + * Returned Value: + * Event group data pointer + * + ****************************************************************************/ + +#define bl_os_event_group_delete g_bl_ops_funcs._event_group_delete + +/**************************************************************************** + * Name: bl_os_event_group_send(FreeRTOS only) + * + * Description: + * Set bits within an event group + * + * Input Parameters: + * + * Returned Value: + * Event group data pointer + * + ****************************************************************************/ + +#define bl_os_event_group_send g_bl_ops_funcs._event_group_send + +/**************************************************************************** + * Name: bl_os_event_group_wait(FreeRTOS only) + * + * Description: + * block to wait for one or more bits to be set within a + * previously created event group. + * + * Input Parameters: + * + * Returned Value: + * Event group data pointer + * + ****************************************************************************/ + +#define bl_os_event_group_wait g_bl_ops_funcs._event_group_wait + +/**************************************************************************** + * Name: bl_os_event_register + * + * Description: + * Temporarily only provide EV_WIFI to fw, leave it blank here + * + * Input Parameters: + * + * Returned Value: + * Event group data pointer + * + ****************************************************************************/ + +#define bl_os_event_register g_bl_ops_funcs._event_register + +/**************************************************************************** + * Name: bl_os_event_notify + * + * Description: + * Post event to EV_WIFI + * + * Input Parameters: + * + * Returned Value: + * Event group data pointer + * + ****************************************************************************/ + +#define bl_os_event_notify g_bl_ops_funcs._event_notify + +/**************************************************************************** + * Name: bl_os_task_create + * + * Description: + * Create task + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#define bl_os_task_create g_bl_ops_funcs._task_create + +/**************************************************************************** + * Name: bl_os_task_delete + * + * Description: + * Delete task + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#define bl_os_task_delete g_bl_ops_funcs._task_delete + +/**************************************************************************** + * Name: bl_os_task_get_current_task + * + * Description: + * Get current task handle + * + * Input Parameters: + * + * Returned Value: + * TaskHandle_t + * + ****************************************************************************/ + +#define bl_os_task_get_current_task g_bl_ops_funcs._task_get_current_task + +/**************************************************************************** + * Name: bl_os_task_notify_create + * + * Description: + * Create task notify handle + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#define bl_os_task_notify_create g_bl_ops_funcs._task_notify_create + +/**************************************************************************** + * Name: bl_os_task_notify + * + * Description: + * Notify block task + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#define bl_os_task_notify g_bl_ops_funcs._task_notify + +/**************************************************************************** + * Name: bl_os_task_wait + * + * Description: + * Block task until notify + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#define bl_os_task_wait g_bl_ops_funcs._task_wait + +/**************************************************************************** + * Name: bl_os_irq_attach + * + * Description: + * Attach a irq callback + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#define bl_os_irq_attach g_bl_ops_funcs._irq_attach + +/**************************************************************************** + * Name: bl_os_irq_enable + * + * Description: + * Enable irq num + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#define bl_os_irq_enable g_bl_ops_funcs._irq_enable + +/**************************************************************************** + * Name: bl_os_irq_enable + * + * Description: + * Disable irq num + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#define bl_os_irq_disable g_bl_ops_funcs._irq_disable + +/**************************************************************************** + * Name: bl_os_workqueue_create + * + * Description: + * Create workqueue task + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#define bl_os_workqueue_create g_bl_ops_funcs._workqueue_create + +/**************************************************************************** + * Name: bl_os_workqueue_submit_hpwork + * + * Description: + * Start a task through high prio task + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#define bl_os_workqueue_submit_hp g_bl_ops_funcs._workqueue_submit_hp + +/**************************************************************************** + * Name: bl_os_workqueue_submit_hpwork + * + * Description: + * Start a task through lower prio task + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#define bl_os_workqueue_submit_lp g_bl_ops_funcs._workqueue_submit_lp + +/**************************************************************************** + * Name: bl_os_timer_create + * + * Description: + * Create a timer with callback and argv + * Input Parameters: + * func - Callback function after the timer expires + * argv - The parameters passed into the callback function + * + * Returned Value: + * Timer handle + * + ****************************************************************************/ + +#define bl_os_timer_create g_bl_ops_funcs._timer_create + +/**************************************************************************** + * Name: bl_os_timer_delete + * + * Description: + * Delete timer + * + * Input Parameters: + * timerid - timer handle + * tick - Specifies the time, in ticks, that the calling task should be + * held in the Blocked state to wait for the stop command to be + * successfully sent to the timer command queue + * + * Returned Value: + * + ****************************************************************************/ + +#define bl_os_timer_delete g_bl_ops_funcs._timer_delete + +/**************************************************************************** + * Name: bl_os_timer_start_once + * + * Description: + * The timer starts once + * Input Parameters: + * timerid - timer handle + * t_sec - Timer trigger period, in seconds + * t_nsec - Timer trigger period, in nanoseconds + * + * Returned Value: + * 0 - success + * 1 - fail + * + ****************************************************************************/ + +#define bl_os_timer_start_once g_bl_ops_funcs._timer_start_once + +/**************************************************************************** + * Name: bl_os_timer_start_once + * + * Description: + * The timer starts period + * Input Parameters: + * timerid - timer handle + * t_sec - Timer trigger period, in seconds + * t_nsec - Timer trigger period, in nanoseconds + * + * Returned Value: + * 0 - success + * 1 - fail + * + ****************************************************************************/ + +#define bl_os_timer_start_periodic g_bl_ops_funcs._timer_start_periodic + +/**************************************************************************** + * Name: bl_os_sem_create + * + * Description: + * Create and initialize semaphore + * + * Input Parameters: + * max - No mean + * init - semaphore initialization value + * + * Returned Value: + * Semaphore data pointer + * + ****************************************************************************/ + +#define bl_os_sem_create g_bl_ops_funcs._sem_create + +/**************************************************************************** + * Name: bl_os_sem_delete + * + * Description: + * Delete semaphore + * + * Input Parameters: + * semphr - Semaphore data pointer + * + * Returned Value: + * None + * + ****************************************************************************/ + +#define bl_os_sem_delete g_bl_ops_funcs._sem_delete\ + +/**************************************************************************** + * Name: bl_os_sem_take + * + * Description: + * Wait semaphore within a certain period of time + * + * Input Parameters: + * semphr - Semaphore data pointer + * ticks - Wait system ticks + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +#define bl_os_sem_take g_bl_ops_funcs._sem_take + +/**************************************************************************** + * Name: bl_os_sem_give + * + * Description: + * Post semaphore + * + * Input Parameters: + * semphr - Semaphore data pointer + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +#define bl_os_sem_give g_bl_ops_funcs._sem_give + +/**************************************************************************** + * Name: bl_os_mutex_create + * + * Description: + * Create mutex + * + * Input Parameters: + * None + * + * Returned Value: + * Mutex data pointer + * + ****************************************************************************/ + +#define bl_os_mutex_create g_bl_ops_funcs._mutex_create + +/**************************************************************************** + * Name: bl_os_mutex_delete + * + * Description: + * Delete mutex + * + * Input Parameters: + * mutex_data - mutex data pointer + * + * Returned Value: + * None + * + ****************************************************************************/ + +#define bl_os_mutex_delete g_bl_ops_funcs._mutex_delete + +/**************************************************************************** + * Name: bl_os_mutex_lock + * + * Description: + * Lock mutex + * + * Input Parameters: + * mutex_data - mutex data pointer + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +#define bl_os_mutex_lock g_bl_ops_funcs._mutex_lock + +/**************************************************************************** + * Name: bl_os_mutex_unlock + * + * Description: + * Lock mutex + * + * Input Parameters: + * mutex_data - mutex data pointer + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +#define bl_os_mutex_unlock g_bl_ops_funcs._mutex_unlock + +/**************************************************************************** + * Name: bl_os_mq_creat + * + * Description: + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#define bl_os_queue_create g_bl_ops_funcs._queue_create + +/**************************************************************************** + * Name: bl_os_mq_delete + * + * Description: + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#define bl_os_queue_delete g_bl_ops_funcs._queue_delete + +/**************************************************************************** + * Name: bl_os_mq_send_wait + * + * Description: + * Generic send message to queue within a certain period of time + * + * Input Parameters: + * queue - Message queue data pointer + * item - Message data pointer + * ticks - Wait ticks + * prio - Message priority + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +#define bl_os_queue_send_wait g_bl_ops_funcs._queue_send_wait + +/**************************************************************************** + * Name: bl_os_mq_send + * + * Description: + * Send message of low priority to queue within a certain period of time + * + * Input Parameters: + * queue - Message queue data pointer + * item - Message data pointer + * ticks - Wait ticks + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +#define bl_os_queue_send g_bl_ops_funcs._queue_send + +/**************************************************************************** + * Name: bl_os_mq_recv + * + * Description: + * Receive message from queue within a certain period of time + * + * Input Parameters: + * queue - Message queue data pointer + * item - Message data pointer + * ticks - Wait ticks + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +#define bl_os_queue_recv g_bl_ops_funcs._queue_recv + +/**************************************************************************** + * Name: bl_os_malloc + * + * Description: + * Allocate a block of memory + * + * Input Parameters: + * size - memory size + * + * Returned Value: + * Memory pointer + * + ****************************************************************************/ + +#define bl_os_malloc g_bl_ops_funcs._malloc + +/**************************************************************************** + * Name: bl_os_free + * + * Description: + * Free a block of memory + * + * Input Parameters: + * ptr - memory block + * + * Returned Value: + * No + * + ****************************************************************************/ + +#define bl_os_free g_bl_ops_funcs._free + +/**************************************************************************** + * Name: bl_os_zalloc + * + * Description: + * Allocate a block of memory + * + * Input Parameters: + * size - memory size + * + * Returned Value: + * Memory pointer + * + ****************************************************************************/ + +#define bl_os_zalloc g_bl_ops_funcs._zalloc + +/**************************************************************************** + * Name: bl_os_clock_gettime_ms + * + * Description: + * Get the current system clock, in milliseconds + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +#define bl_os_get_time_ms g_bl_ops_funcs._get_time_ms + +/**************************************************************************** + * Name: bl_os_get_tick + * + * Description: + * Get current system tick + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ +#define bl_os_get_tick g_bl_ops_funcs._get_tick + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* _BL_OS_SYSTEM_H_ */ diff --git a/platforms/bl808_m0/vendor/wifi/include/bl_os_adapter/bl_os_type.h b/platforms/bl808_m0/vendor/wifi/include/bl_os_adapter/bl_os_type.h new file mode 100644 index 0000000..a68647e --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/bl_os_adapter/bl_os_type.h @@ -0,0 +1,48 @@ +/**************************************************************************** + * components/platform/soc/bl602/bl602_os_adapter/bl602_os_adapter/include/bl_os_adapter/bl_os_type.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + + +#ifndef _BL_OS_TYPE_H_ +#define _BL_OS_TYPE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**************************************************************************** + * Definition + ****************************************************************************/ + +typedef void* BL_Timer_t; +typedef void* BL_TaskHandle_t; +typedef void* BL_Sem_t; +typedef void* BL_Mutex_t; +typedef void* BL_MessageQueue_t; +typedef void* BL_EventGroup_t; +typedef void* BL_TimeOut_t; +typedef uint32_t BL_TickType_t; + +#ifdef __cplusplus +} +#endif + +#endif /* _BL_OS_TYPE_H_ */ diff --git a/platforms/bl808_m0/vendor/wifi/include/bl_phy_api.h b/platforms/bl808_m0/vendor/wifi/include/bl_phy_api.h new file mode 100644 index 0000000..39e8d1f --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/bl_phy_api.h @@ -0,0 +1,70 @@ +#ifndef __BL_PHY_API_H__ +#define __BL_PHY_API_H__ + +void bl_mfg_phy_init(); +void bl_mfg_rf_cal(); +void bl_mfg_rx_start(); +void bl_mfg_rx_stop(); +void bl_mfg_channel_switch(uint8_t chan_no); +int8_t bl_mfg_tx11n_start_raw(uint8_t mcs_n, uint16_t frame_len, uint8_t pwr_dbm); +int8_t bl_mfg_tx11b_start_raw(uint8_t mcs_b, uint16_t frame_len, uint8_t pwr_dbm); +void bl_mfg_tx_stop(); +void phy_powroffset_set(int8_t power_offset[14]); + +#define RFTLV_TYPE_XTAL_MODE 0X0001 +#define RFTLV_TYPE_XTAL 0X0002 +#define RFTLV_TYPE_PWR_MODE 0X0003 +#define RFTLV_TYPE_PWR_TABLE 0X0004 +#define RFTLV_TYPE_PWR_TABLE_11B 0X0005 +#define RFTLV_TYPE_PWR_TABLE_11G 0X0006 +#define RFTLV_TYPE_PWR_TABLE_11N 0X0007 +#define RFTLV_TYPE_PWR_OFFSET 0X0008 +#define RFTLV_TYPE_CHAN_DIV_TAB 0X0009 +#define RFTLV_TYPE_CHAN_CNT_TAB 0X000A +#define RFTLV_TYPE_LO_FCAL_DIV 0X000B +#define RFTLV_TYPE_EN_TCAL 0X0020 +#define RFTLV_TYPE_LINEAR_OR_FOLLOW 0X0021 +#define RFTLV_TYPE_TCHANNELS 0X0022 +#define RFTLV_TYPE_TCHANNEL_OS 0X0023 +#define RFTLV_TYPE_TCHANNEL_OS_LOW 0X0024 +#define RFTLV_TYPE_TROOM_OS 0X0025 +#define RFTLV_TYPE_PWR_TABLE_BLE 0X0030 + +#define RFTLV_API_TYPE_XTAL_MODE RFTLV_TYPE_XTAL_MODE +#define RFTLV_API_TYPE_XTAL RFTLV_TYPE_XTAL +#define RFTLV_API_TYPE_PWR_MODE RFTLV_TYPE_PWR_MODE +#define RFTLV_API_TYPE_PWR_TABLE RFTLV_TYPE_PWR_TABLE +#define RFTLV_API_TYPE_PWR_TABLE_11B RFTLV_TYPE_PWR_TABLE_11B +#define RFTLV_API_TYPE_PWR_TABLE_11G RFTLV_TYPE_PWR_TABLE_11G +#define RFTLV_API_TYPE_PWR_TABLE_11N RFTLV_TYPE_PWR_TABLE_11N +#define RFTLV_API_TYPE_PWR_OFFSET RFTLV_TYPE_PWR_OFFSET +#define RFTLV_API_TYPE_CHAN_DIV_TAB RFTLV_TYPE_CHAN_DIV_TAB +#define RFTLV_API_TYPE_CHAN_CNT_TAB RFTLV_TYPE_CHAN_CNT_TAB +#define RFTLV_API_TYPE_LO_FCAL_DIV RFTLV_TYPE_LO_FCAL_DIV +#define RFTLV_API_TYPE_EN_TCAL RFTLV_TYPE_EN_TCAL +#define RFTLV_API_TYPE_LINEAR_OR_FOLLOW RFTLV_TYPE_LINEAR_OR_FOLLOW +#define RFTLV_API_TYPE_TCHANNELS RFTLV_TYPE_TCHANNELS +#define RFTLV_API_TYPE_TCHANNEL_OS RFTLV_TYPE_TCHANNEL_OS +#define RFTLV_API_TYPE_TCHANNEL_OS_LOW RFTLV_TYPE_TCHANNEL_OS_LOW +#define RFTLV_API_TYPE_TROOM_OS RFTLV_TYPE_TROOM_OS +#define RFTLV_API_TYPE_PWR_TABLE_BLE RFTLV_TYPE_PWR_TABLE_BLE + +/* + * input: + * tlv_addr: rftlv info address + * + * return : 1-valid, other-invalid + */ +int rftlv_valid(uint32_t tlv_addr); + +/* + * input: + * tlv_addr: rftlv info address + * type: type + * value_len: value max len + * value: point value + * return : ">0"-success, "<0"-invalid and end, "==0"-invalid and can next + */ +int rftlv_get(uint32_t tlv_addr, uint16_t type, uint32_t value_len, void *value); + +#endif diff --git a/platforms/bl808_m0/vendor/wifi/include/bl_rx.h b/platforms/bl808_m0/vendor/wifi/include/bl_rx.h new file mode 100644 index 0000000..9450aa9 --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/bl_rx.h @@ -0,0 +1,199 @@ + +/** + **************************************************************************************** + * + * @file bl_rx.h + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + +#ifndef _RWNX_RX_H_ +#define _RWNX_RX_H_ +#include "bl_defs.h" +#include "lmac_types.h" +// Removed: #include -- not needed for hw_rxhdr struct. + +enum rx_status_bits +{ + /// The buffer can be forwarded to the networking stack + RX_STAT_FORWARD = 1 << 0, + /// A new buffer has to be allocated + RX_STAT_ALLOC = 1 << 1, + /// The buffer has to be deleted + RX_STAT_DELETE = 1 << 2, + /// The length of the buffer has to be updated + RX_STAT_LEN_UPDATE = 1 << 3, + /// The length in the Ethernet header has to be updated + RX_STAT_ETH_LEN_UPDATE = 1 << 4, + /// Simple copy + RX_STAT_COPY = 1 << 5, +}; + +#define BL_RX_STATUS_AMSDU (1 << 0) +// XXX Value must not conflict with PBUF_FLAG_PUSH, etc in pbuf.h +#define PBUF_FLAG_AMSDU 0x80U + +/* + * Decryption status subfields. + * { + */ +#define RWNX_RX_HD_DECR_UNENC 0 // Frame unencrypted +#define RWNX_RX_HD_DECR_ICVFAIL 1 // WEP/TKIP ICV failure +#define RWNX_RX_HD_DECR_CCMPFAIL 2 // CCMP failure +#define RWNX_RX_HD_DECR_AMSDUDISCARD 3 // A-MSDU discarded at HW +#define RWNX_RX_HD_DECR_NULLKEY 4 // NULL key found +#define RWNX_RX_HD_DECR_WEPSUCCESS 5 // Security type WEP +#define RWNX_RX_HD_DECR_TKIPSUCCESS 6 // Security type TKIP +#define RWNX_RX_HD_DECR_CCMPSUCCESS 7 // Security type CCMP +// @} + +struct hw_vect { + /** Total length for the MPDU transfer */ + u32 len :16; + + u32 reserved : 8; + + /** AMPDU Status Information */ + u32 mpdu_cnt : 6; + u32 ampdu_cnt : 2; + + + /** TSF Low */ + __le32 tsf_lo; + /** TSF High */ + __le32 tsf_hi; + + /** Receive Vector 1a */ + u32 leg_length :12; + u32 leg_rate : 4; + u32 ht_length :16; + + /** Receive Vector 1b */ + u32 _ht_length : 4; // FIXME + u32 short_gi : 1; + u32 stbc : 2; + u32 smoothing : 1; + u32 mcs : 7; + u32 pre_type : 1; + u32 format_mod : 3; + u32 ch_bw : 2; + u32 n_sts : 3; + u32 lsig_valid : 1; + u32 sounding : 1; + u32 num_extn_ss : 2; + u32 aggregation : 1; + u32 fec_coding : 1; + u32 dyn_bw : 1; + u32 doze_not_allowed : 1; + + /** Receive Vector 1c */ + u32 antenna_set : 8; + u32 partial_aid : 9; + u32 group_id : 6; + u32 reserved_1c : 1; + s32 rssi1 : 8; + + /** Receive Vector 1d */ + s32 rssi2 : 8; + s32 rssi3 : 8; + s32 rssi4 : 8; + u32 reserved_1d : 8; + + /** Receive Vector 2a */ + u32 rcpi : 8; + u32 evm1 : 8; + u32 evm2 : 8; + u32 evm3 : 8; + + /** Receive Vector 2b */ + u32 evm4 : 8; + u32 reserved2b_1 : 8; + u32 reserved2b_2 : 8; + u32 reserved2b_3 : 8; + + /** Status **/ + u32 rx_vect2_valid : 1; + u32 resp_frame : 1; + /** Decryption Status */ + u32 decr_status : 3; + u32 rx_fifo_oflow : 1; + + /** Frame Unsuccessful */ + u32 undef_err : 1; + u32 phy_err : 1; + u32 fcs_err : 1; + u32 addr_mismatch : 1; + u32 ga_frame : 1; + u32 current_ac : 2; + + u32 frm_successful_rx : 1; + /** Descriptor Done */ + u32 desc_done_rx : 1; + /** Key Storage RAM Index */ + u32 key_sram_index : 10; + /** Key Storage RAM Index Valid */ + u32 key_sram_v : 1; + u32 type : 2; + u32 subtype : 4; +}; + +struct hw_rxhdr { + /** RX vector */ + struct hw_vect hwvect; + + /** PHY channel information 1 */ + u32 phy_band : 8; + u32 phy_channel_type : 8; + u32 phy_prim20_freq : 16; + /** PHY channel information 2 */ + u32 phy_center1_freq : 16; + u32 phy_center2_freq : 16; + /** RX flags */ + u32 flags_is_amsdu : 1; + u32 flags_is_80211_mpdu: 1; + u32 flags_is_4addr : 1; + u32 flags_new_peer : 1; + u32 flags_user_prio : 3; + u32 flags_rsvd0 : 1; + u32 flags_vif_idx : 8; // 0xFF if invalid VIF index + u32 flags_sta_idx : 8; // 0xFF if invalid STA index + u32 flags_dst_idx : 8; // 0xFF if unknown destination STA + /** Pattern indicating if the buffer is available for the driver */ + u32 pattern; + u32 payl_offset; + u32 reserved_pad[2]; + /*XXX wild buffer load for platform overwrite*/ + u32 wild[8]; +}; + +struct reason_code { + uint16_t reason_code; + const char *action; +}; + +typedef struct +{ + u16 noRsn : 1; + u16 wepStatic : 1; + u16 wepDynamic : 1; + u16 wpa : 1; + u16 wpaNone : 1; + u16 wpa2 : 1; + u16 cckm : 1; + u16 wapi : 1; + u16 wpa3 : 1; + u16 rsvd : 7; + +} SecurityMode_t; + +extern const u8 legrates_lut[]; + +int bl_txdatacfm(void *pthis, void *hostid); +void bl_prim_tbtt_ind(void *pthis); +void bl_sec_tbtt_ind(void *pthis); +void bl_rx_handle_msg(struct bl_hw *bl_hw, struct ipc_e2a_msg *msg); +void bl_rx_pkt_cb(uint8_t *pkt, int len, void *pkt_wrap, bl_rx_info_t *info); +const char* wifi_mgmr_get_sm_status_code_str(uint16_t status_code); + +#endif /* _RWNX_RX_H_ */ diff --git a/platforms/bl808_m0/vendor/wifi/include/bl_strs.h b/platforms/bl808_m0/vendor/wifi/include/bl_strs.h new file mode 100644 index 0000000..dc51da5 --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/bl_strs.h @@ -0,0 +1,25 @@ + +/** + **************************************************************************************** + * + * @file bl_strs.h + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + + +#ifndef _RWNX_STRS_H_ +#define _RWNX_STRS_H_ + +#include "lmac_msg.h" +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +#define RWNX_ID2STR(tag) (((MSG_T(tag) < ARRAY_SIZE(bl_id2str)) && \ + (bl_id2str[MSG_T(tag)]) && \ + ((bl_id2str[MSG_T(tag)])[MSG_I(tag)])) ? \ + (bl_id2str[MSG_T(tag)])[MSG_I(tag)] : "unknown") + +extern const char *const *bl_id2str[TASK_LAST_EMB + 1]; + +#endif /* _RWNX_STRS_H_ */ diff --git a/platforms/bl808_m0/vendor/wifi/include/bl_tx.h b/platforms/bl808_m0/vendor/wifi/include/bl_tx.h new file mode 100644 index 0000000..70b6423 --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/bl_tx.h @@ -0,0 +1,47 @@ +// Minimal bl_tx.h shim. +// +// The upstream bl_tx.h is heavily lwIP-pbuf entangled (function signatures +// take struct pbuf * / struct netif *). We dropped bl_tx.c and do the TX +// path in D. ipc_host.c still references struct bl_txhdr and bl_tx_resend() +// for its TX-confirm/error paths -- we provide just those declarations. + +#ifndef VENDOR_BL_TX_H +#define VENDOR_BL_TX_H + +#include "lmac_types.h" +#include "ipc_shared.h" +#include "bl_utils.h" +#include + +typedef void (*bl_custom_tx_callback_t)(void *cb_arg, bool tx_ok); + +struct bl_custom_tx_cfm { + bl_custom_tx_callback_t cb; + void *cb_arg; +}; + +union bl_hw_txstatus { + struct { + u32 tx_done : 1; + u32 retry_required : 1; + u32 sw_retry_required : 1; + u32 reserved : 29; + }; + u32 value; +}; + +// Layout must match vendor exactly: ipc_host.c reads custom_cfm.cb / +// cb_arg from the txhdr embedded in the TX buffer. +struct bl_txhdr { + struct utils_list_hdr item; + union bl_hw_txstatus status; + uint32_t *p; + struct hostdesc host; + struct bl_custom_tx_cfm custom_cfm; +}; + +// Provided by D side (urt.driver.bl808.wifi) -- re-queues the head of +// the TX list when LMAC reports a soft retry. +void bl_tx_resend(void); + +#endif diff --git a/platforms/bl808_m0/vendor/wifi/include/bl_utils.h b/platforms/bl808_m0/vendor/wifi/include/bl_utils.h new file mode 100644 index 0000000..7c6de4a --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/bl_utils.h @@ -0,0 +1,59 @@ +#ifndef __RWNX_UTILS_H__ +#define __RWNX_UTILS_H__ +#include "bl_defs.h" +#ifdef CONFIG_RWNX_DBG + +/** + **************************************************************************************** + * + * @file bl_utils.h + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + +#define RWNX_DBG os_printf +#else +#define RWNX_DBG(a...) do {} while (0) +#endif + +#define RWNX_FN_ENTRY_STR ">>> %s()\r\n", __func__ +#define RWNX_FN_LEAVE_STR "<<< %s()\r\n", __func__ + +#define RWNX_RXBUFF_PATTERN (0xCAFEFADE) +#define RWNX_RXBUFF_VALID_IDX(idx) ((idx) < RWNX_RXBUFF_MAX) +/* Used to ensure that hostid set to fw is never 0 */ +#define RWNX_RXBUFF_IDX_TO_HOSTID(idx) ((idx) + 1) +#define RWNX_RXBUFF_HOSTID_TO_IDX(hostid) ((hostid) - 1) +#define RWNX_RXBUFF_DMA_ADDR_GET(skbuff) \ + skbuff->payload + +/* + * Structure used to store information regarding E2A msg buffers in the driver + */ +struct bl_e2amsg_elem { + struct ipc_e2a_msg *msgbuf_ptr; + u32 dma_addr;//XXX only for 32-bit addr +}; + +/* + * Structure used to store information regarding Debug msg buffers in the driver + */ +struct bl_dbg_elem { + struct ipc_dbg_msg *dbgbuf_ptr; + u32 dma_addr; +}; + +/* + * Structure used to store information regarding E2A radar events in the driver + */ +struct bl_e2aradar_elem { + struct radar_pulse_array_desc *radarbuf_ptr; + u32 dma_addr; +}; + +int bl_ipc_init(struct bl_hw *bl_hw, struct ipc_shared_env_tag *ipc_shared_mem); +uint32_t* bl_utils_pbuf_alloc(void); +void bl_utils_pbuf_free(uint32_t *p); +int bl_utils_idx_lookup(struct bl_hw *bl_hw, uint8_t *mac); +#endif diff --git a/platforms/bl808_m0/vendor/wifi/include/cfg80211.h b/platforms/bl808_m0/vendor/wifi/include/cfg80211.h new file mode 100644 index 0000000..1396388 --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/cfg80211.h @@ -0,0 +1,327 @@ +#ifndef __CFG80211_H__ +#define __CFG80211_H__ +#include "ieee80211.h" +#include "nl80211.h" +#include "lmac_types.h" + + +/** + **************************************************************************************** + * + * @file cfg80211.h + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + +enum ieee80211_channel_flags { + IEEE80211_CHAN_DISABLED = 1<<0, + IEEE80211_CHAN_NO_IR = 1<<1, + /* hole at 1<<2 */ + IEEE80211_CHAN_RADAR = 1<<3, + IEEE80211_CHAN_NO_HT40PLUS = 1<<4, + IEEE80211_CHAN_NO_HT40MINUS = 1<<5, + IEEE80211_CHAN_NO_OFDM = 1<<6, + IEEE80211_CHAN_NO_80MHZ = 1<<7, + IEEE80211_CHAN_NO_160MHZ = 1<<8, + IEEE80211_CHAN_INDOOR_ONLY = 1<<9, + IEEE80211_CHAN_IR_CONCURRENT = 1<<10, + IEEE80211_CHAN_NO_20MHZ = 1<<11, + IEEE80211_CHAN_NO_10MHZ = 1<<12, +}; + +/** + * struct ieee80211_channel - channel definition + * + * This structure describes a single channel for use + * with cfg80211. + * + * @center_freq: center frequency in MHz + * @hw_value: hardware-specific value for the channel + * @flags: channel flags from &enum ieee80211_channel_flags. + * @orig_flags: channel flags at registration time, used by regulatory + * code to support devices with additional restrictions + * @band: band this channel belongs to. + * @max_antenna_gain: maximum antenna gain in dBi + * @max_power: maximum transmission power (in dBm) + * @max_reg_power: maximum regulatory transmission power (in dBm) + * @beacon_found: helper to regulatory code to indicate when a beacon + * has been found on this channel. Use regulatory_hint_found_beacon() + * to enable this, this is useful only on 5 GHz band. + * @orig_mag: internal use + * @orig_mpwr: internal use + * @dfs_state: current state of this channel. Only relevant if radar is required + * on this channel. + * @dfs_state_entered: timestamp (jiffies) when the dfs state was entered. + * @dfs_cac_ms: DFS CAC time in milliseconds, this is valid for DFS channels. + */ +struct ieee80211_channel { + enum nl80211_band band; + u16 center_freq; + u16 hw_value; + u32 flags; + int max_antenna_gain; + int max_power; + int max_reg_power; + bool beacon_found; + u32 orig_flags; + int orig_mag, orig_mpwr; + enum nl80211_dfs_state dfs_state; + unsigned long dfs_state_entered; + unsigned int dfs_cac_ms; +}; + +struct ieee80211_dot_d { + char *code; + int channel_num; + const struct ieee80211_channel *channels; +}; + +/** + * struct ieee80211_sta_ht_cap - STA's HT capabilities + * + * This structure describes most essential parameters needed + * to describe 802.11n HT capabilities for an STA. + * + * @ht_supported: is HT supported by the STA + * @cap: HT capabilities map as described in 802.11n spec + * @ampdu_factor: Maximum A-MPDU length factor + * @ampdu_density: Minimum A-MPDU spacing + * @mcs: Supported MCS rates + */ +struct ieee80211_sta_ht_cap { + u16 cap; /* use IEEE80211_HT_CAP_ */ + bool ht_supported; + u8 ampdu_factor; + u8 ampdu_density; + struct ieee80211_mcs_info mcs; +}; + +/* + * wireless hardware and networking interfaces structures + * and registration/helper functions + */ + +/** + * enum wiphy_flags - wiphy capability flags + * + * @WIPHY_FLAG_NETNS_OK: if not set, do not allow changing the netns of this + * wiphy at all + * @WIPHY_FLAG_PS_ON_BY_DEFAULT: if set to true, powersave will be enabled + * by default -- this flag will be set depending on the kernel's default + * on wiphy_new(), but can be changed by the driver if it has a good + * reason to override the default + * @WIPHY_FLAG_4ADDR_AP: supports 4addr mode even on AP (with a single station + * on a VLAN interface) + * @WIPHY_FLAG_4ADDR_STATION: supports 4addr mode even as a station + * @WIPHY_FLAG_CONTROL_PORT_PROTOCOL: This device supports setting the + * control port protocol ethertype. The device also honours the + * control_port_no_encrypt flag. + * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN. + * @WIPHY_FLAG_MESH_AUTH: The device supports mesh authentication by routing + * auth frames to userspace. See @NL80211_MESH_SETUP_USERSPACE_AUTH. + * @WIPHY_FLAG_SUPPORTS_SCHED_SCAN: The device supports scheduled scans. + * @WIPHY_FLAG_SUPPORTS_FW_ROAM: The device supports roaming feature in the + * firmware. + * @WIPHY_FLAG_AP_UAPSD: The device supports uapsd on AP. + * @WIPHY_FLAG_SUPPORTS_TDLS: The device supports TDLS (802.11z) operation. + * @WIPHY_FLAG_TDLS_EXTERNAL_SETUP: The device does not handle TDLS (802.11z) + * link setup/discovery operations internally. Setup, discovery and + * teardown packets should be sent through the @NL80211_CMD_TDLS_MGMT + * command. When this flag is not set, @NL80211_CMD_TDLS_OPER should be + * used for asking the driver/firmware to perform a TDLS operation. + * @WIPHY_FLAG_HAVE_AP_SME: device integrates AP SME + * @WIPHY_FLAG_REPORTS_OBSS: the device will report beacons from other BSSes + * when there are virtual interfaces in AP mode by calling + * cfg80211_report_obss_beacon(). + * @WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD: When operating as an AP, the device + * responds to probe-requests in hardware. + * @WIPHY_FLAG_OFFCHAN_TX: Device supports direct off-channel TX. + * @WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL: Device supports remain-on-channel call. + * @WIPHY_FLAG_SUPPORTS_5_10_MHZ: Device supports 5 MHz and 10 MHz channels. + * @WIPHY_FLAG_HAS_CHANNEL_SWITCH: Device supports channel switch in + * beaconing mode (AP, IBSS, Mesh, ...). + * @WIPHY_FLAG_HAS_STATIC_WEP: The device supports static WEP key installation + * before connection. + */ +enum wiphy_flags { + /* use hole at 0 */ + /* use hole at 1 */ + /* use hole at 2 */ + WIPHY_FLAG_NETNS_OK = BIT(3), + WIPHY_FLAG_PS_ON_BY_DEFAULT = BIT(4), + WIPHY_FLAG_4ADDR_AP = BIT(5), + WIPHY_FLAG_4ADDR_STATION = BIT(6), + WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7), + WIPHY_FLAG_IBSS_RSN = BIT(8), + WIPHY_FLAG_MESH_AUTH = BIT(10), + WIPHY_FLAG_SUPPORTS_SCHED_SCAN = BIT(11), + /* use hole at 12 */ + WIPHY_FLAG_SUPPORTS_FW_ROAM = BIT(13), + WIPHY_FLAG_AP_UAPSD = BIT(14), + WIPHY_FLAG_SUPPORTS_TDLS = BIT(15), + WIPHY_FLAG_TDLS_EXTERNAL_SETUP = BIT(16), + WIPHY_FLAG_HAVE_AP_SME = BIT(17), + WIPHY_FLAG_REPORTS_OBSS = BIT(18), + WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD = BIT(19), + WIPHY_FLAG_OFFCHAN_TX = BIT(20), + WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL = BIT(21), + WIPHY_FLAG_SUPPORTS_5_10_MHZ = BIT(22), + WIPHY_FLAG_HAS_CHANNEL_SWITCH = BIT(23), + WIPHY_FLAG_HAS_STATIC_WEP = BIT(24), +}; + +/** + * struct key_params - key information + * + * Information about a key + * + * @key: key material + * @key_len: length of key material + * @cipher: cipher suite selector + * @seq: sequence counter (IV/PN) for TKIP and CCMP keys, only used + * with the get_key() callback, must be in little endian, + * length given by @seq_len. + * @seq_len: length of @seq. + */ +struct key_params { + const u8 *key; + const u8 *seq; + int key_len; + int seq_len; + u32 cipher; +}; + +/** + * struct cfg80211_crypto_settings - Crypto settings + * @wpa_versions: indicates which, if any, WPA versions are enabled + * (from enum nl80211_wpa_versions) + * @cipher_group: group key cipher suite (or 0 if unset) + * @n_ciphers_pairwise: number of AP supported unicast ciphers + * @ciphers_pairwise: unicast key cipher suites + * @n_akm_suites: number of AKM suites + * @akm_suites: AKM suites + * @control_port: Whether user space controls IEEE 802.1X port, i.e., + * sets/clears %NL80211_STA_FLAG_AUTHORIZED. If true, the driver is + * required to assume that the port is unauthorized until authorized by + * user space. Otherwise, port is marked authorized by default. + * @control_port_ethertype: the control port protocol that should be + * allowed through even on unauthorized ports + * @control_port_no_encrypt: TRUE to prevent encryption of control port + * protocol frames. + * @wep_keys: static WEP keys, if not NULL points to an array of + * CFG80211_MAX_WEP_KEYS WEP keys + * @wep_tx_key: key index (0..3) of the default TX static WEP key + */ +struct cfg80211_crypto_settings { + u32 wpa_versions; + u32 cipher_group; + int n_ciphers_pairwise; + u32 ciphers_pairwise[NL80211_MAX_NR_CIPHER_SUITES]; + int n_akm_suites; + u32 akm_suites[NL80211_MAX_NR_AKM_SUITES]; + bool control_port; + __be16 control_port_ethertype; + bool control_port_no_encrypt; + struct key_params *wep_keys; + int wep_tx_key; +}; + +/** + * struct cfg80211_bss_select_adjust - BSS selection with RSSI adjustment. + * + * @band: band of BSS which should match for RSSI level adjustment. + * @delta: value of RSSI level adjustment. + */ +struct cfg80211_bss_select_adjust { + enum nl80211_band band; + s8 delta; +}; + +/** + * struct cfg80211_bss_selection - connection parameters for BSS selection. + * + * @behaviour: requested BSS selection behaviour. + * @param: parameters for requestion behaviour. + * @band_pref: preferred band for %NL80211_BSS_SELECT_ATTR_BAND_PREF. + * @adjust: parameters for %NL80211_BSS_SELECT_ATTR_RSSI_ADJUST. + */ +struct cfg80211_bss_selection { + enum nl80211_bss_select_attr behaviour; + union { + enum nl80211_band band_pref; + struct cfg80211_bss_select_adjust adjust; + } param; +}; + +/** + * struct cfg80211_connect_params - Connection parameters + * + * This structure provides information needed to complete IEEE 802.11 + * authentication and association. + * + * @channel: The channel to use or %NULL if not specified (auto-select based + * on scan results) + * @channel_hint: The channel of the recommended BSS for initial connection or + * %NULL if not specified + * @bssid: The AP BSSID or %NULL if not specified (auto-select based on scan + * results) + * @bssid_hint: The recommended AP BSSID for initial connection to the BSS or + * %NULL if not specified. Unlike the @bssid parameter, the driver is + * allowed to ignore this @bssid_hint if it has knowledge of a better BSS + * to use. + * @ssid: SSID + * @ssid_len: Length of ssid in octets + * @auth_type: Authentication type (algorithm) + * @ie: IEs for association request + * @ie_len: Length of assoc_ie in octets + * @privacy: indicates whether privacy-enabled APs should be used + * @mfp: indicate whether management frame protection is used + * @crypto: crypto settings + * @key_len: length of WEP key for shared key authentication + * @key_idx: index of WEP key for shared key authentication + * @key: WEP key for shared key authentication + * @flags: See &enum cfg80211_assoc_req_flags + * @bg_scan_period: Background scan period in seconds + * or -1 to indicate that default value is to be used. + * @ht_capa: HT Capabilities over-rides. Values set in ht_capa_mask + * will be used in ht_capa. Un-supported values will be ignored. + * @ht_capa_mask: The bits of ht_capa which are to be used. + * @vht_capa: VHT Capability overrides + * @vht_capa_mask: The bits of vht_capa which are to be used. + * @pbss: if set, connect to a PCP instead of AP. Valid for DMG + * networks. + * @bss_select: criteria to be used for BSS selection. + * @prev_bssid: previous BSSID, if not %NULL use reassociate frame. This is used + * to indicate a request to reassociate within the ESS instead of a request + * do the initial association with the ESS. When included, this is set to + * the BSSID of the current association, i.e., to the value that is + * included in the Current AP address field of the Reassociation Request + * frame. + */ +struct cfg80211_connect_params { + struct ieee80211_channel channel; + struct ieee80211_channel *channel_hint; + const u8 *bssid; + const u8 *bssid_hint; + const u8 *ssid; + size_t ssid_len; + enum nl80211_auth_type auth_type; + const u8 *ie; + size_t ie_len; + bool privacy; + enum nl80211_mfp mfp; + struct cfg80211_crypto_settings crypto; + const u8 *key; + const u8 *pmk; + u8 key_len, pmk_len, key_idx; + u32 flags; + int bg_scan_period; + struct ieee80211_ht_cap ht_capa; + struct ieee80211_ht_cap ht_capa_mask; + bool pbss; + struct cfg80211_bss_selection bss_select; + const u8 *prev_bssid; +}; + +#endif diff --git a/platforms/bl808_m0/vendor/wifi/include/errno.h b/platforms/bl808_m0/vendor/wifi/include/errno.h new file mode 100644 index 0000000..1c6bd0c --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/errno.h @@ -0,0 +1,151 @@ +#ifndef __ERRNO_H__ +#define __ERRNO_H__ +#define EPERM 1 +/** + **************************************************************************************** + * + * @file errno.h + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Argument list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ + + + +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale NFS file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +#define ENOMEDIUM 123 /* No medium found */ +#define EMEDIUMTYPE 124 /* Wrong medium type */ +#define ECANCELED 125 /* Operation Canceled */ +#define ENOKEY 126 /* Required key not available */ +#define EKEYEXPIRED 127 /* Key has expired */ +#define EKEYREVOKED 128 /* Key has been revoked */ +#define EKEYREJECTED 129 /* Key was rejected by service */ + +/* for robust mutexes */ +#define EOWNERDEAD 130 /* Owner died */ +#define ENOTRECOVERABLE 131 /* State not recoverable */ +#endif diff --git a/platforms/bl808_m0/vendor/wifi/include/ieee80211.h b/platforms/bl808_m0/vendor/wifi/include/ieee80211.h new file mode 100644 index 0000000..eb82af3 --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/ieee80211.h @@ -0,0 +1,510 @@ +#ifndef __IEEE80211_H__ +#define __IEEE80211_H__ +#include "lmac_types.h" + + +/** + **************************************************************************************** + * + * @file ieee80211.h + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + + +#ifndef cpu_to_le16 +#define cpu_to_le16(v16) (v16) +#endif + +#ifndef cpu_to_le32 +#define cpu_to_le32(v32) (v32) +#endif + +#define WLAN_SA_QUERY_TR_ID_LEN 2 +#define WLAN_MEMBERSHIP_LEN 8 +#define WLAN_USER_POSITION_LEN 16 + +#define FCS_LEN 4 + +#define IEEE80211_FCTL_VERS 0x0003 +#define IEEE80211_FCTL_FTYPE 0x000c +#define IEEE80211_FCTL_STYPE 0x00f0 +#define IEEE80211_FCTL_TODS 0x0100 +#define IEEE80211_FCTL_FROMDS 0x0200 +#define IEEE80211_FCTL_MOREFRAGS 0x0400 +#define IEEE80211_FCTL_RETRY 0x0800 +#define IEEE80211_FCTL_PM 0x1000 +#define IEEE80211_FCTL_MOREDATA 0x2000 +#define IEEE80211_FCTL_PROTECTED 0x4000 +#define IEEE80211_FCTL_ORDER 0x8000 +#define IEEE80211_FCTL_CTL_EXT 0x0f00 + +#define IEEE80211_SCTL_FRAG 0x000F +#define IEEE80211_SCTL_SEQ 0xFFF0 + +#define IEEE80211_FTYPE_MGMT 0x0000 +#define IEEE80211_FTYPE_CTL 0x0004 +#define IEEE80211_FTYPE_DATA 0x0008 +#define IEEE80211_FTYPE_EXT 0x000c + +/* management */ +#define IEEE80211_STYPE_ASSOC_REQ 0x0000 +#define IEEE80211_STYPE_ASSOC_RESP 0x0010 +#define IEEE80211_STYPE_REASSOC_REQ 0x0020 +#define IEEE80211_STYPE_REASSOC_RESP 0x0030 +#define IEEE80211_STYPE_PROBE_REQ 0x0040 +#define IEEE80211_STYPE_PROBE_RESP 0x0050 +#define IEEE80211_STYPE_BEACON 0x0080 +#define IEEE80211_STYPE_ATIM 0x0090 +#define IEEE80211_STYPE_DISASSOC 0x00A0 +#define IEEE80211_STYPE_AUTH 0x00B0 +#define IEEE80211_STYPE_DEAUTH 0x00C0 +#define IEEE80211_STYPE_ACTION 0x00D0 + +/* control */ +#define IEEE80211_STYPE_CTL_EXT 0x0060 +#define IEEE80211_STYPE_BACK_REQ 0x0080 +#define IEEE80211_STYPE_BACK 0x0090 +#define IEEE80211_STYPE_PSPOLL 0x00A0 +#define IEEE80211_STYPE_RTS 0x00B0 +#define IEEE80211_STYPE_CTS 0x00C0 +#define IEEE80211_STYPE_ACK 0x00D0 +#define IEEE80211_STYPE_CFEND 0x00E0 +#define IEEE80211_STYPE_CFENDACK 0x00F0 + +/* data */ +#define IEEE80211_STYPE_DATA 0x0000 +#define IEEE80211_STYPE_DATA_CFACK 0x0010 +#define IEEE80211_STYPE_DATA_CFPOLL 0x0020 +#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030 +#define IEEE80211_STYPE_NULLFUNC 0x0040 +#define IEEE80211_STYPE_CFACK 0x0050 +#define IEEE80211_STYPE_CFPOLL 0x0060 +#define IEEE80211_STYPE_CFACKPOLL 0x0070 +#define IEEE80211_STYPE_QOS_DATA 0x0080 +#define IEEE80211_STYPE_QOS_DATA_CFACK 0x0090 +#define IEEE80211_STYPE_QOS_DATA_CFPOLL 0x00A0 +#define IEEE80211_STYPE_QOS_DATA_CFACKPOLL 0x00B0 +#define IEEE80211_STYPE_QOS_NULLFUNC 0x00C0 +#define IEEE80211_STYPE_QOS_CFACK 0x00D0 +#define IEEE80211_STYPE_QOS_CFPOLL 0x00E0 +#define IEEE80211_STYPE_QOS_CFACKPOLL 0x00F0 + +/* extension, added by 802.11ad */ +#define IEEE80211_STYPE_DMG_BEACON 0x0000 + +/* control extension - for IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTL_EXT */ +#define IEEE80211_CTL_EXT_POLL 0x2000 +#define IEEE80211_CTL_EXT_SPR 0x3000 +#define IEEE80211_CTL_EXT_GRANT 0x4000 +#define IEEE80211_CTL_EXT_DMG_CTS 0x5000 +#define IEEE80211_CTL_EXT_DMG_DTS 0x6000 +#define IEEE80211_CTL_EXT_SSW 0x8000 +#define IEEE80211_CTL_EXT_SSW_FBACK 0x9000 +#define IEEE80211_CTL_EXT_SSW_ACK 0xa000 + + +#define IEEE80211_SN_MASK ((IEEE80211_SCTL_SEQ) >> 4) +#define IEEE80211_MAX_SN IEEE80211_SN_MASK +#define IEEE80211_SN_MODULO (IEEE80211_MAX_SN + 1) + + +/* 802.11n HT capabilities masks (for cap_info) */ +#define IEEE80211_HT_CAP_LDPC_CODING 0x0001 +#define IEEE80211_HT_CAP_SUP_WIDTH_20_40 0x0002 +#define IEEE80211_HT_CAP_SM_PS 0x000C +#define IEEE80211_HT_CAP_SM_PS_SHIFT 2 +#define IEEE80211_HT_CAP_GRN_FLD 0x0010 +#define IEEE80211_HT_CAP_SGI_20 0x0020 +#define IEEE80211_HT_CAP_SGI_40 0x0040 +#define IEEE80211_HT_CAP_TX_STBC 0x0080 +#define IEEE80211_HT_CAP_RX_STBC 0x0300 +#define IEEE80211_HT_CAP_RX_STBC_SHIFT 8 +#define IEEE80211_HT_CAP_DELAY_BA 0x0400 +#define IEEE80211_HT_CAP_MAX_AMSDU 0x0800 +#define IEEE80211_HT_CAP_DSSSCCK40 0x1000 +#define IEEE80211_HT_CAP_RESERVED 0x2000 +#define IEEE80211_HT_CAP_40MHZ_INTOLERANT 0x4000 +#define IEEE80211_HT_CAP_LSIG_TXOP_PROT 0x8000 + +/* 802.11n HT extended capabilities masks (for extended_ht_cap_info) */ +#define IEEE80211_HT_EXT_CAP_PCO 0x0001 +#define IEEE80211_HT_EXT_CAP_PCO_TIME 0x0006 +#define IEEE80211_HT_EXT_CAP_PCO_TIME_SHIFT 1 +#define IEEE80211_HT_EXT_CAP_MCS_FB 0x0300 +#define IEEE80211_HT_EXT_CAP_MCS_FB_SHIFT 8 +#define IEEE80211_HT_EXT_CAP_HTC_SUP 0x0400 +#define IEEE80211_HT_EXT_CAP_RD_RESPONDER 0x0800 + +/* 802.11n HT capability AMPDU settings (for ampdu_params_info) */ +#define IEEE80211_HT_AMPDU_PARM_FACTOR 0x03 +#define IEEE80211_HT_AMPDU_PARM_DENSITY 0x1C +#define IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT 2 + +#define IEEE80211_HT_MCS_MASK_LEN 10 + +/* cipher suite selectors */ +#define WLAN_CIPHER_SUITE_USE_GROUP 0x000FAC00 +#define WLAN_CIPHER_SUITE_WEP40 0x000FAC01 +#define WLAN_CIPHER_SUITE_TKIP 0x000FAC02 +/* reserved: 0x000FAC03 */ +#define WLAN_CIPHER_SUITE_CCMP 0x000FAC04 +#define WLAN_CIPHER_SUITE_WEP104 0x000FAC05 +#define WLAN_CIPHER_SUITE_AES_CMAC 0x000FAC06 +#define WLAN_CIPHER_SUITE_GCMP 0x000FAC08 +#define WLAN_CIPHER_SUITE_GCMP_256 0x000FAC09 +#define WLAN_CIPHER_SUITE_CCMP_256 0x000FAC0A +#define WLAN_CIPHER_SUITE_BIP_GMAC_128 0x000FAC0B +#define WLAN_CIPHER_SUITE_BIP_GMAC_256 0x000FAC0C +#define WLAN_CIPHER_SUITE_BIP_CMAC_256 0x000FAC0D + +#define WLAN_CAPABILITY_BSS (1<<0) +#define WLAN_CAPABILITY_IBSS (1<<1) +#define WLAN_CAPABILITY_CF_POLLABLE (1<<2) +#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3) +#define WLAN_CAPABILITY_PRIVACY (1<<4) +#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5) +#define WLAN_CAPABILITY_PBCC (1<<6) +#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7) +#define WLAN_CAPABILITY_SHORT_SLOT (1<<10) + +/* Reason codes */ +enum ieee80211_reasoncode { + WLAN_REASON_UNSPECIFIED = 1, + WLAN_REASON_PREV_AUTH_NOT_VALID = 2, + WLAN_REASON_DEAUTH_LEAVING = 3, + WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4, + WLAN_REASON_DISASSOC_AP_BUSY = 5, + WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6, + WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7, + WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8, + WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9, + /* 802.11h */ + WLAN_REASON_DISASSOC_BAD_POWER = 10, + WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11, + /* 802.11i */ + WLAN_REASON_INVALID_IE = 13, + WLAN_REASON_MIC_FAILURE = 14, + WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, + WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16, + WLAN_REASON_IE_DIFFERENT = 17, + WLAN_REASON_INVALID_GROUP_CIPHER = 18, + WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19, + WLAN_REASON_INVALID_AKMP = 20, + WLAN_REASON_UNSUPP_RSN_VERSION = 21, + WLAN_REASON_INVALID_RSN_IE_CAP = 22, + WLAN_REASON_IEEE8021X_FAILED = 23, + WLAN_REASON_CIPHER_SUITE_REJECTED = 24, + /* TDLS (802.11z) */ + WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE = 25, + WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED = 26, + /* 802.11e */ + WLAN_REASON_DISASSOC_UNSPECIFIED_QOS = 32, + WLAN_REASON_DISASSOC_QAP_NO_BANDWIDTH = 33, + WLAN_REASON_DISASSOC_LOW_ACK = 34, + WLAN_REASON_DISASSOC_QAP_EXCEED_TXOP = 35, + WLAN_REASON_QSTA_LEAVE_QBSS = 36, + WLAN_REASON_QSTA_NOT_USE = 37, + WLAN_REASON_QSTA_REQUIRE_SETUP = 38, + WLAN_REASON_QSTA_TIMEOUT = 39, + WLAN_REASON_QSTA_CIPHER_NOT_SUPP = 45, + /* 802.11s */ + WLAN_REASON_MESH_PEER_CANCELED = 52, + WLAN_REASON_MESH_MAX_PEERS = 53, + WLAN_REASON_MESH_CONFIG = 54, + WLAN_REASON_MESH_CLOSE = 55, + WLAN_REASON_MESH_MAX_RETRIES = 56, + WLAN_REASON_MESH_CONFIRM_TIMEOUT = 57, + WLAN_REASON_MESH_INVALID_GTK = 58, + WLAN_REASON_MESH_INCONSISTENT_PARAM = 59, + WLAN_REASON_MESH_INVALID_SECURITY = 60, + WLAN_REASON_MESH_PATH_ERROR = 61, + WLAN_REASON_MESH_PATH_NOFORWARD = 62, + WLAN_REASON_MESH_PATH_DEST_UNREACHABLE = 63, + WLAN_REASON_MAC_EXISTS_IN_MBSS = 64, + WLAN_REASON_MESH_CHAN_REGULATORY = 65, + WLAN_REASON_MESH_CHAN = 66, +}; + +/** + * struct ieee80211_mcs_info - MCS information + * @rx_mask: RX mask + * @rx_highest: highest supported RX rate. If set represents + * the highest supported RX data rate in units of 1 Mbps. + * If this field is 0 this value should not be used to + * consider the highest RX data rate supported. + * @tx_params: TX parameters + */ +struct ieee80211_mcs_info { + u8 rx_mask[IEEE80211_HT_MCS_MASK_LEN]; + __le16 rx_highest; + u8 tx_params; + u8 reserved[3]; +}; + +/** + * struct ieee80211_ht_cap - HT capabilities + * + * This structure is the "HT capabilities element" as + * described in 802.11n D5.0 7.3.2.57 + */ +struct ieee80211_ht_cap { + __le16 cap_info; + u8 ampdu_params_info; + + /* 16 bytes MCS information */ + struct ieee80211_mcs_info mcs; + + __le16 extended_ht_cap_info; + __le32 tx_BF_cap_info; + u8 antenna_selection_info; +}; + +struct ieee80211_mgmt { + __le16 frame_control; + __le16 duration; + u8 da[6]; + u8 sa[6]; + u8 bssid[6]; + __le16 seq_ctrl; + union { + struct { + __le16 auth_alg; + __le16 auth_transaction; + __le16 status_code; + /* possibly followed by Challenge text */ + u8 variable[0]; + } __attribute__((__packed__)) auth; + struct { + __le16 reason_code; + } __attribute__((__packed__)) deauth; + struct { + __le16 capab_info; + __le16 listen_interval; + /* followed by SSID and Supported rates */ + u8 variable[0]; + } __attribute__((__packed__)) assoc_req; + struct { + __le16 capab_info; + __le16 status_code; + __le16 aid; + /* followed by Supported rates */ + u8 variable[0]; + } __attribute__((__packed__)) assoc_resp, reassoc_resp; + struct { + __le16 capab_info; + __le16 listen_interval; + u8 current_ap[6]; + /* followed by SSID and Supported rates */ + u8 variable[0]; + } __attribute__((__packed__)) reassoc_req; + struct { + __le16 reason_code; + } __attribute__((__packed__)) disassoc; + struct { + __le64 timestamp; + __le16 beacon_int; + __le16 capab_info; + /* followed by some of SSID, Supported rates, + * FH Params, DS Params, CF Params, IBSS Params, TIM */ + u8 variable[0]; + } __attribute__((__packed__)) beacon; + struct { + /* only variable items: SSID, Supported rates */ + u8 variable[0]; + } __attribute__((__packed__)) probe_req; + struct { + __le64 timestamp; + __le16 beacon_int; + __le16 capab_info; + /* followed by some of SSID, Supported rates, + * FH Params, DS Params, CF Params, IBSS Params */ + u8 variable[0]; + } __attribute__((__packed__)) probe_resp; + struct { + u8 category; + union { + struct { + u8 action_code; + u8 dialog_token; + u8 status_code; + u8 variable[0]; + } __attribute__((__packed__)) wme_action; + struct{ + u8 action_code; + u8 variable[0]; + } __attribute__((__packed__)) chan_switch; + struct{ + u8 action_code; + //struct ieee80211_ext_chansw_ie data; + u8 variable[0]; + } __attribute__((__packed__)) ext_chan_switch; + struct{ + u8 action_code; + u8 dialog_token; + u8 element_id; + u8 length; + //struct ieee80211_msrment_ie msr_elem; + } __attribute__((__packed__)) measurement; + struct{ + u8 action_code; + u8 dialog_token; + __le16 capab; + __le16 timeout; + __le16 start_seq_num; + } __attribute__((__packed__)) addba_req; + struct{ + u8 action_code; + u8 dialog_token; + __le16 status; + __le16 capab; + __le16 timeout; + } __attribute__((__packed__)) addba_resp; + struct{ + u8 action_code; + __le16 params; + __le16 reason_code; + } __attribute__((__packed__)) delba; + struct { + u8 action_code; + u8 variable[0]; + } __attribute__((__packed__)) self_prot; + struct{ + u8 action_code; + u8 variable[0]; + } __attribute__((__packed__)) mesh_action; + struct { + u8 action; + u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN]; + } __attribute__((__packed__)) sa_query; + struct { + u8 action; + u8 smps_control; + } __attribute__((__packed__)) ht_smps; + struct { + u8 action_code; + u8 chanwidth; + } __attribute__((__packed__)) ht_notify_cw; + struct { + u8 action_code; + u8 dialog_token; + __le16 capability; + u8 variable[0]; + } __attribute__((__packed__)) tdls_discover_resp; + struct { + u8 action_code; + u8 operating_mode; + } __attribute__((__packed__)) vht_opmode_notif; + struct { + u8 action_code; + u8 membership[WLAN_MEMBERSHIP_LEN]; + u8 position[WLAN_USER_POSITION_LEN]; + } __attribute__((__packed__)) vht_group_notif; + struct { + u8 action_code; + u8 dialog_token; + u8 tpc_elem_id; + u8 tpc_elem_length; + //struct ieee80211_tpc_report_ie tpc; + } __attribute__((__packed__)) tpc_report; + struct { + u8 action_code; + u8 dialog_token; + u8 follow_up; + u8 tod[6]; + u8 toa[6]; + __le16 tod_error; + __le16 toa_error; + u8 variable[0]; + } __attribute__((__packed__)) ftm; + } u; + } __attribute__((__packed__)) action; + } u; +} __attribute__((packed, aligned(2))); + +/** + * ieee80211_is_beacon - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_BEACON + * @fc: frame control bytes in little-endian byteorder + */ +static inline bool ieee80211_is_beacon(__le16 fc) +{ + return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == + cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); +} + +/** + * ieee80211_is_deauth - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_DEAUTH + * @fc: frame control bytes in little-endian byteorder + */ +static inline bool ieee80211_is_deauth(__le16 fc) +{ + return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == + cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH); +} + +/** + * ieee80211_is_disassoc - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_DISASSOC + * @fc: frame control bytes in little-endian byteorder + */ +static inline bool ieee80211_is_disassoc(__le16 fc) +{ + return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == + cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DISASSOC); +} + +/** + * ieee80211_is_action - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ACTION + * @fc: frame control bytes in little-endian byteorder + */ +static inline bool ieee80211_is_action(__le16 fc) +{ + return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == + cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION); +} + +/** + * * ieee80211_is_probe_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_PROBE_RESP + * * @fc: frame control bytes in little-endian byteorder + * */ +static inline int ieee80211_is_probe_resp(__le16 fc) +{ + return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == + cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP); +} + +/** + * ieee80211_is_probe_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_PROBE_REQ + * @fc: frame control bytes in little-endian byteorder + */ +static inline bool ieee80211_is_probe_req(__le16 fc) +{ + return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == + cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ); +} + +/** + * ieee80211_is_data - check if type is IEEE80211_FTYPE_DATA + * @fc: frame control bytes in little-endian byteorder + */ +static inline bool ieee80211_is_data(__le16 fc) +{ + return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) == + cpu_to_le16(IEEE80211_FTYPE_DATA); +} + +/** + * ieee80211_is_data_qos - check if type is IEEE80211_FTYPE_DATA and IEEE80211_STYPE_QOS_DATA is set + * @fc: frame control bytes in little-endian byteorder + */ +static inline bool ieee80211_is_data_qos(__le16 fc) +{ + /* + * mask with QOS_DATA rather than IEEE80211_FCTL_STYPE as we just need + * to check the one bit + */ + return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_STYPE_QOS_DATA)) == + cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA); +} + +#endif diff --git a/platforms/bl808_m0/vendor/wifi/include/ipc_compat.h b/platforms/bl808_m0/vendor/wifi/include/ipc_compat.h new file mode 100644 index 0000000..d2b5eab --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/ipc_compat.h @@ -0,0 +1,50 @@ + +/** + **************************************************************************************** + * + * @file ipc_compat.h + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + + +#ifndef _IPC_H_ +#define _IPC_H_ + +#include "bl_os_private.h" + +#if 1 +#define __WARN() bl_os_printf("%s:%d\r\n", __func__, __LINE__) +#else +#define __WARN() +#endif + +#define WARN_ON(condition) ({ \ + int __ret_warn_on = !!(condition); \ + if (__ret_warn_on) \ + __WARN(); \ + __ret_warn_on; \ + }) + +#define WARN_ON_ONCE(condition) ({ \ + static bool __warned; \ + int __ret_warn_once = !!(condition); \ + \ + if (__ret_warn_once) \ + if (WARN_ON(!__warned)) \ + __warned = true; \ + __ret_warn_once; \ + }) + +#define __round_mask(x, y) ((__typeof__(x))((y)-1)) +#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1) +#define round_down(x, y) ((x) & ~__round_mask(x, y)) + +#if 1 +#define ASSERT_ERR(condition) assert(condition) +#else +#define ASSERT_ERR(condition) RT_ASSERT(condition) +#endif + +#endif /* _IPC_H_ */ diff --git a/platforms/bl808_m0/vendor/wifi/include/ipc_host.h b/platforms/bl808_m0/vendor/wifi/include/ipc_host.h new file mode 100644 index 0000000..b6fcf25 --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/ipc_host.h @@ -0,0 +1,198 @@ +#ifndef __IPC_HOST_H__ +#define __IPC_HOST_H__ +#include +#include "ipc_shared.h" + +enum ipc_host_desc_status +{ + /// Descriptor is IDLE + IPC_HOST_DESC_IDLE = 0, + /// Data can be forwarded + IPC_HOST_DESC_FORWARD, + /// Data has to be kept in UMAC memory + IPC_HOST_DESC_KEEP, + /// Delete stored packet + IPC_HOST_DESC_DELETE, + /// Update Frame Length status + IPC_HOST_DESC_LEN_UPDATE, +}; + + +/** + **************************************************************************************** + * + * @file ipc_host.h + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + +struct ipc_host_cb_tag +{ + /// WLAN driver call-back function: send_data_cfm + int (*send_data_cfm)(void *pthis, void *host_id); + + /// WLAN driver call-back function: recv_data_ind + uint8_t (*recv_data_ind)(void *pthis, void *host_id); + + /// WLAN driver call-back function: recv_radar_ind + uint8_t (*recv_radar_ind)(void *pthis, void *host_id); + + /// WLAN driver call-back function: recv_msg_ind + uint8_t (*recv_msg_ind)(void *pthis, void *host_id); + + /// WLAN driver call-back function: recv_msgack_ind + uint8_t (*recv_msgack_ind)(void *pthis, void *host_id); + + /// WLAN driver call-back function: recv_dbg_ind + uint8_t (*recv_dbg_ind)(void *pthis, void *host_id); + + /// WLAN driver call-back function: prim_tbtt_ind + void (*prim_tbtt_ind)(void *pthis); + + /// WLAN driver call-back function: sec_tbtt_ind + void (*sec_tbtt_ind)(void *pthis); + +}; + +/* + * Struct used to store information about host buffers (DMA Address and local pointer) + */ +struct ipc_hostbuf +{ + void *hostid; ///< ptr to hostbuf client (ipc_host client) structure + uint32_t dma_addr; ///< ptr to real hostbuf dma address +}; + + +/// Definition of the IPC Host environment structure. +struct ipc_host_env_tag +{ + /// Structure containing the callback pointers + struct ipc_host_cb_tag cb; + + /// Pointer to the shared environment + struct ipc_shared_env_tag *shared; + + // Array used to store the descriptor addresses + struct ipc_hostbuf ipc_host_rxdesc_array[IPC_RXDESC_CNT]; + // Index of the host RX descriptor array (ipc_shared environment) + uint8_t ipc_host_rxdesc_idx; + /// Store the number of RX Descriptors + uint8_t rxdesc_nb; + + // Index used for ipc_host_rxbuf_array to point to current buffer + uint8_t ipc_host_rxbuf_idx; + // Store the number of Rx Data buffers + uint32_t rx_bufnb; + // Store the size of the Rx Data buffers + uint32_t rx_bufsz; + + // Index used that points to the first free TX desc + uint32_t txdesc_free_idx; + // Index used that points to the first used TX desc + uint32_t txdesc_used_idx; + // Array storing the currently pushed host ids for the BK queue + void *tx_host_id0[NX_TXDESC_CNT0]; + // Pointer to the different host ids arrays, per IPC queue + void **tx_host_id; + // Pointer to the different TX descriptor arrays, per IPC queue + volatile struct txdesc_host *txdesc; + + /// Fields for Emb->App MSGs handling + // Global array used to store the hostid and hostbuf addresses for msg/ind + struct ipc_hostbuf ipc_host_msgbuf_array[IPC_MSGE2A_BUF_CNT]; + // Index of the MSG E2A buffers array to point to current buffer + uint8_t ipc_host_msge2a_idx; + // Store the number of E2A MSG buffers + uint32_t ipc_e2amsg_bufnb; + // Store the size of the E2A MSG buffers + uint32_t ipc_e2amsg_bufsz; + + /// E2A ACKs of A2E MSGs + uint8_t msga2e_cnt; + void *msga2e_hostid; + + /// Fields for Debug MSGs handling + // Global array used to store the hostid and hostbuf addresses for Debug messages + struct ipc_hostbuf ipc_host_dbgbuf_array[IPC_DBGBUF_CNT]; + // Index of the Debug messages buffers array to point to current buffer + uint8_t ipc_host_dbg_idx; + // Store the number of Debug messages buffers + uint32_t ipc_dbg_bufnb; + // Store the size of the Debug messages buffers + uint32_t ipc_dbg_bufsz; + + /// Pointer to the attached object (used in callbacks and register accesses) + void *pthis; +}; + +void ipc_host_init(struct ipc_host_env_tag *env, + struct ipc_host_cb_tag *cb, + struct ipc_shared_env_tag *shared_env_ptr, + void *pthis); +int ipc_host_msg_push(struct ipc_host_env_tag *env, void *msg_buf, uint16_t len); +uint32_t ipc_host_get_status(struct ipc_host_env_tag *env); +uint32_t ipc_host_get_rawstatus(struct ipc_host_env_tag *env); +volatile struct txdesc_host *ipc_host_txdesc_get(struct ipc_host_env_tag *env); +void ipc_host_txdesc_push(struct ipc_host_env_tag *env, void *host_id); +void ipc_host_irq(struct ipc_host_env_tag *env, uint32_t status); +void ipc_host_enable_irq(struct ipc_host_env_tag *env, uint32_t value); +void ipc_host_disable_irq(struct ipc_host_env_tag *env, uint32_t value); + +/** + ****************************************************************************** + * @brief Push a pre-allocated buffer descriptor for IPC MSGs (host side) + * + * This function is called at Init time to initialize all Emb2App messages + * buffers. Then each time embedded send a IPC message, this function is used + * to push back the same buffer once it has been handled. + * + * @param[in] env Pointer to the IPC host environment + * @param[in] hostid Address of buffer for host + * @param[in] hostbuf Address of buffer for embedded + * The length of this buffer should be predefined + * between host and emb statically. + * + ****************************************************************************** + */ +int ipc_host_msgbuf_push(struct ipc_host_env_tag *env, void *hostid, uint32_t hostbuf); + +void ipc_host_patt_addr_push(struct ipc_host_env_tag *env, uint32_t addr); + +/** + ****************************************************************************** + * @brief Push a pre-allocated buffer descriptor for Rx packet (host side) + * + * This function should be called by the host IRQ handler to supply the + * embedded side with new empty buffer. + * + * @param[in] env Pointer to the IPC host environment + * @param[in] hostid Packet ID used by the host (skbuff pointer on Linux) + * @param[in] hostbuf Pointer to the start of the buffer payload in the + * host memory (this may be inferred from the skbuff?) + * The length of this buffer should be predefined + * between host and emb statically (constant needed?). + * + ****************************************************************************** + */ +int ipc_host_rxbuf_push(struct ipc_host_env_tag *env, uint32_t hostid, uint32_t hostbuf); + +/** + ****************************************************************************** + * @brief Push a pre-allocated Descriptor + * + * This function should be called by the host IRQ handler to supply the + * embedded side with new empty buffer. + * + * @param[in] env Pointer to the IPC host environment + * @param[in] hostid Address of packet for host + * @param[in] hostbuf Pointer to the start of the buffer payload in the + * host memory. The length of this buffer should be + * predefined between host and emb statically. + * + ****************************************************************************** + */ +int ipc_host_rxdesc_push(struct ipc_host_env_tag *env, void *hostid, uint32_t hostbuf); +int ipc_host_txdesc_left(struct ipc_host_env_tag *env, const int queue_idx, const int user_pos); +#endif diff --git a/platforms/bl808_m0/vendor/wifi/include/ipc_shared.h b/platforms/bl808_m0/vendor/wifi/include/ipc_shared.h new file mode 100644 index 0000000..0bdf373 --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/ipc_shared.h @@ -0,0 +1,254 @@ + +/** + **************************************************************************************** + * + * @file ipc_shared.h + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + + +#ifndef _IPC_SHARED_H_ +#define _IPC_SHARED_H_ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include +#include "ipc_compat.h" +#include "lmac_types.h" +#include "lmac_mac.h" + +/* + * DEFINES AND MACROS + **************************************************************************************** + */ +#define CO_BIT(pos) (1U<<(pos)) +#define NX_TXQ_CNT 4 +#define CONFIG_USER_MAX 1 + +#define IPC_TXQUEUE_CNT NX_TXQ_CNT +#define NX_TXDESC_CNT0 CFG_TXDESC +#define NX_TXDESC_CNT1 CFG_TXDESC +#define NX_TXDESC_CNT2 CFG_TXDESC +#define NX_TXDESC_CNT3 CFG_TXDESC +#define NX_TXDESC_CNT4 CFG_TXDESC +/* + * Number of Host buffers available for Data Rx handling (through DMA) + */ +#define IPC_RXBUF_CNT 2 + +/* + * Number of shared descriptors available for Data RX handling + */ +#define IPC_RXDESC_CNT 2 + +/* + * Number of Host buffers available for Radar events handling (through DMA) + */ +#define IPC_RADARBUF_CNT 4 + +/* + * RX Data buffers size (in bytes) + */ +#define IPC_RXBUF_SIZE 2048 + +/* + * Number of Host buffers available for Emb->App MSGs sending (through DMA) + */ +#define IPC_MSGE2A_BUF_CNT 8 + +/* + * Number of Host buffers available for Debug Messages sending (through DMA) + */ +#define IPC_DBGBUF_CNT 4 + +/* + * Length used in MSGs structures + */ +#define IPC_A2E_MSG_BUF_SIZE 127 // size in 4-byte words +#define IPC_E2A_MSG_PARAM_SIZE (257 - 4 - 8)// size in 4-byte words +/* + * Debug messages buffers size (in bytes) + */ +#define IPC_DBG_PARAM_SIZE 256 + +/* + * Define used for Rx hostbuf validity. + * This value should appear only when hostbuf was used for a Reception. + */ +#define RX_DMA_OVER_PATTERN 0xAAAAAA00 + +/* + * Define used for MSG buffers validity. + * This value will be written only when a MSG buffer is used for sending from Emb to App. + */ +#define IPC_MSGE2A_VALID_PATTERN 0xADDEDE2A + +/* + * Define used for Debug messages buffers validity. + * This value will be written only when a DBG buffer is used for sending from Emb to App. + */ +#define IPC_DBG_VALID_PATTERN 0x000CACA0 + +/* + * Length of the receive vectors, in bytes + */ +#define DMA_HDR_PHYVECT_LEN 36 + +/* + * Maximum number of payload addresses and lengths present in the descriptor + */ +#define NX_TX_PAYLOAD_MAX 6 + +/* + **************************************************************************************** + */ +// c.f LMAC/src/tx/tx_swdesc.h +/// Descriptor filled by the Host +struct hostdesc +{ + /// allocated pbuf + uint32_t pbuf_addr; + /// Pointer to packet payload + uint32_t packet_addr; + /// Size of the payload + uint16_t packet_len; + + /// Address of the status descriptor in host memory (used for confirmation upload) + uint32_t status_addr; + /// Destination Address + struct mac_addr eth_dest_addr; + /// Source Address + struct mac_addr eth_src_addr; + /// Ethernet Type + uint16_t ethertype; + /// Buffer containing the PN to be used for this packet + uint16_t pn[4]; + /// Sequence Number used for transmission of this MPDU + uint16_t sn; + /// Timestamp of first transmission of this MPDU + uint16_t timestamp; + /// Packet TID (0xFF if not a QoS frame) + uint8_t tid; + /// Interface Id + uint8_t vif_idx; + /// Station Id (0xFF if station is unknown) + uint8_t staid; + /// TX flags + uint16_t flags; + uint32_t pbuf_chained_ptr[4]; //max 4 chained pbuf for one output ethernet packet + uint32_t pbuf_chained_len[4]; //max 4 chained pbuf for one output ethernet packet +}; + +struct txdesc_host +{ + uint32_t ready; + +#if defined(CFG_CHIP_BL808) + uint32_t eth_packet[1600/4]; +#endif + +#if defined(CFG_CHIP_BL606P) + uint32_t eth_packet[1600/4]; +#endif + + /// API of the embedded part + struct hostdesc host; + + uint32_t pad_txdesc[204/4]; + + uint32_t pad_buf[400/4]; +}; + +/// Structure containing the information about the PHY channel that is used +struct phy_channel_info +{ + /// PHY channel information 1 + uint32_t info1; + /// PHY channel information 2 + uint32_t info2; +}; + +/** + **************************************************************************************** + * @defgroup IPC_MISC IPC Misc + * @ingroup IPC + * @brief IPC miscellaneous functions + **************************************************************************************** + */ +/// Message structure for MSGs from Emb to App +struct ipc_e2a_msg +{ + ke_msg_id_t id; ///< Message id. + ke_task_id_t dummy_dest_id; ///< + ke_task_id_t dummy_src_id; ///< + uint32_t param_len; ///< Parameter embedded struct length. + uint32_t param[IPC_E2A_MSG_PARAM_SIZE]; ///< Parameter embedded struct. Must be word-aligned. + uint32_t pattern; ///< Used to stamp a valid MSG buffer +}; + +/// Message structure for MSGs from App to Emb. +/// Actually a sub-structure will be used when filling the messages. +struct ipc_a2e_msg +{ + uint32_t dummy_word; // used to cope with kernel message structure + uint32_t msg[IPC_A2E_MSG_BUF_SIZE]; // body of the msg +}; + +// Indexes are defined in the MIB shared structure + +struct ipc_shared_env_tag +{ + volatile struct ipc_a2e_msg msg_a2e_buf; // room for MSG to be sent from App to Emb + + /// Host buffer address for the TX payload descriptor pattern + volatile uint32_t pattern_addr; + + volatile struct txdesc_host txdesc0[NX_TXDESC_CNT0]; +}; + +extern struct ipc_shared_env_tag ipc_shared_env; + + +/* + * TYPE and STRUCT DEFINITIONS + **************************************************************************************** + */ + +/// IPC TX descriptor interrupt mask +#define IPC_IRQ_A2E_TXDESC 0xFF00 + +#define IPC_IRQ_A2E_TXDESC_FIRSTBIT (8) +#define IPC_IRQ_A2E_RXBUF_BACK CO_BIT(5) +#define IPC_IRQ_A2E_RXDESC_BACK CO_BIT(4) + +#define IPC_IRQ_A2E_MSG CO_BIT(1) +#define IPC_IRQ_A2E_DBG CO_BIT(0) + +#define IPC_IRQ_A2E_ALL (IPC_IRQ_A2E_TXDESC|IPC_IRQ_A2E_MSG|IPC_IRQ_A2E_DBG) + +// IRQs from emb to app +#define IPC_IRQ_E2A_TXCFM_POS 7 + +#define IPC_IRQ_E2A_TXCFM ((1 << NX_TXQ_CNT) - 1 ) << IPC_IRQ_E2A_TXCFM_POS + +#define IPC_IRQ_E2A_RADAR CO_BIT(6) +#define IPC_IRQ_E2A_TBTT_SEC CO_BIT(5) +#define IPC_IRQ_E2A_TBTT_PRIM CO_BIT(4) +#define IPC_IRQ_E2A_RXDESC CO_BIT(3) +#define IPC_IRQ_E2A_MSG_ACK CO_BIT(2) +#define IPC_IRQ_E2A_MSG CO_BIT(1) +#define IPC_IRQ_E2A_DBG CO_BIT(0) + +#define IPC_IRQ_E2A_ALL ( IPC_IRQ_E2A_TXCFM \ + | IPC_IRQ_E2A_RXDESC \ + | IPC_IRQ_E2A_MSG_ACK \ + | IPC_IRQ_E2A_MSG \ + | IPC_IRQ_E2A_DBG \ + | IPC_IRQ_E2A_TBTT_PRIM \ + | IPC_IRQ_E2A_TBTT_SEC \ + | IPC_IRQ_E2A_RADAR) +#endif // _IPC_SHARED_H_ diff --git a/platforms/bl808_m0/vendor/wifi/include/list.h b/platforms/bl808_m0/vendor/wifi/include/list.h new file mode 100644 index 0000000..b5c046c --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/list.h @@ -0,0 +1,518 @@ + +/** + **************************************************************************************** + * + * @file list.h + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + +#ifndef __WIFI_LIST_H__ +#define __WIFI_LIST_H__ + +/** + * @name from other kernel headers + */ +/*@{*/ + +#if 0 + +/** + * Casts a member of a structure out to the containing structure + * @param ptr the pointer to the member. + * @param type the type of the container struct this is embedded in. + * @param member the name of the member within the struct. + * + */ +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) +/*@}*/ +#else +/** + * Get offset of a member + */ +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif + +#define container_of(ptr, type, member) ((type *)((char *)(ptr) - offsetof(type, member))) +#endif + + +/* + * These are non-NULL pointers that will result in page faults + * under normal circumstances, used to verify that nobody uses + * non-initialized list entries. + */ +#define LIST_POISON1 ((void *) 0x00100100) +#define LIST_POISON2 ((void *) 0x00200200) + +/** + * Simple doubly linked list implementation. + * + * Some of the internal functions ("__xxx") are useful when + * manipulating whole lists rather than single entries, as + * sometimes we already know the next/prev entries and we can + * generate better code by using them directly rather than + * using the generic single-entry routines. + */ +struct list_head { + struct list_head *next, *prev; +}; + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + +#define INIT_LIST_HEAD(ptr) do { \ + (ptr)->next = (ptr); (ptr)->prev = (ptr); \ +} while (0) + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_add(struct list_head *new, + struct list_head *prev, + struct list_head *next) +{ + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} + +/** + * list_add - add a new entry + * @new: new entry to be added + * @head: list head to add it after + * + * Insert a new entry after the specified head. + * This is good for implementing stacks. + */ +static inline void list_add(struct list_head *new, struct list_head *head) +{ + __list_add(new, head, head->next); +} + +/** + * list_add_tail - add a new entry + * @new: new entry to be added + * @head: list head to add it before + * + * Insert a new entry before the specified head. + * This is useful for implementing queues. + */ +static inline void list_add_tail(struct list_head *new, struct list_head *head) +{ + __list_add(new, head->prev, head); +} + + +/* + * Delete a list entry by making the prev/next entries + * point to each other. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_del(struct list_head * prev, struct list_head * next) +{ + next->prev = prev; + prev->next = next; +} + +/** + * list_del - deletes entry from list. + * @entry: the element to delete from the list. + * Note: list_empty on entry does not return true after this, the entry is + * in an undefined state. + */ +static inline void list_del(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + entry->next = LIST_POISON1; + entry->prev = LIST_POISON2; +} + + + +/** + * list_del_init - deletes entry from list and reinitialize it. + * @entry: the element to delete from the list. + */ +static inline void list_del_init(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + INIT_LIST_HEAD(entry); +} + +/** + * list_move - delete from one list and add as another's head + * @list: the entry to move + * @head: the head that will precede our entry + */ +static inline void list_move(struct list_head *list, struct list_head *head) +{ + __list_del(list->prev, list->next); + list_add(list, head); +} + +/** + * list_move_tail - delete from one list and add as another's tail + * @list: the entry to move + * @head: the head that will follow our entry + */ +static inline void list_move_tail(struct list_head *list, + struct list_head *head) +{ + __list_del(list->prev, list->next); + list_add_tail(list, head); +} + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +static inline int list_empty(const struct list_head *head) +{ + return head->next == head; +} + +static inline void __list_splice(struct list_head *list, + struct list_head *head) +{ + struct list_head *first = list->next; + struct list_head *last = list->prev; + struct list_head *at = head->next; + + first->prev = head; + head->next = first; + + last->next = at; + at->prev = last; +} + +/** + * list_splice - join two lists + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static inline void list_splice(struct list_head *list, struct list_head *head) +{ + if (!list_empty(list)) + __list_splice(list, head); +} + +/** + * list_splice_init - join two lists and reinitialise the emptied list. + * @list: the new list to add. + * @head: the place to add it in the first list. + * + * The list at @list is reinitialised + */ +static inline void list_splice_init(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) { + __list_splice(list, head); + INIT_LIST_HEAD(list); + } +} + +/** + * list_entry - get the struct for this entry + * @ptr: the &struct list_head pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + */ +#define list_entry(ptr, type, member) \ + container_of(ptr, type, member) + +/** + * list_for_each - iterate over a list + * @pos: the &struct list_head to use as a loop counter. + * @head: the head for your list. + */ + +#define list_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); \ + pos = pos->next) + +/** + * __list_for_each - iterate over a list + * @pos: the &struct list_head to use as a loop counter. + * @head: the head for your list. + * + * This variant differs from list_for_each() in that it's the + * simplest possible list iteration code, no prefetching is done. + * Use this for code that knows the list to be very short (empty + * or 1 entry) most of the time. + */ +#define __list_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); pos = pos->next) + +/** + * list_for_each_prev - iterate over a list backwards + * @pos: the &struct list_head to use as a loop counter. + * @head: the head for your list. + */ +#define list_for_each_prev(pos, head) \ + for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \ + pos = pos->prev) + +/** + * list_for_each_safe - iterate over a list safe against removal of list entry + * @pos: the &struct list_head to use as a loop counter. + * @n: another &struct list_head to use as temporary storage + * @head: the head for your list. + */ +#define list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + +/** + * list_for_each_entry - iterate over list of given type + * @pos: the type * to use as a loop counter. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member)) + +/** + * list_for_each_entry_reverse - iterate backwards over list of given type. + * @pos: the type * to use as a loop counter. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry_reverse(pos, head, member) \ + for (pos = list_entry((head)->prev, typeof(*pos), member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.prev, typeof(*pos), member)) + +/** + * list_prepare_entry - prepare a pos entry for use as a start point in + * list_for_each_entry_continue + * @pos: the type * to use as a start point + * @head: the head of the list + * @member: the name of the list_struct within the struct. + */ +#define list_prepare_entry(pos, head, member) \ + ((pos) ? : list_entry(head, typeof(*pos), member)) + +/** + * list_for_each_entry_continue - iterate over list of given type + * continuing after existing point + * @pos: the type * to use as a loop counter. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry_continue(pos, head, member) \ + for (pos = list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member)) + +/** + * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry + * @pos: the type * to use as a loop counter. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry_safe(pos, n, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member), \ + n = list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, typeof(*n), member)) + +/** + * list_for_each_entry_safe_continue - iterate over list of given type + * continuing after existing point safe against removal of list entry + * @pos: the type * to use as a loop counter. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry_safe_continue(pos, n, head, member) \ + for (pos = list_entry(pos->member.next, typeof(*pos), member), \ + n = list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, typeof(*n), member)) + +/** + * list_for_each_entry_safe_reverse - iterate backwards over list of given type safe against + * removal of list entry + * @pos: the type * to use as a loop counter. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry_safe_reverse(pos, n, head, member) \ + for (pos = list_entry((head)->prev, typeof(*pos), member), \ + n = list_entry(pos->member.prev, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.prev, typeof(*n), member)) + + + + +/* + * Double linked lists with a single pointer list head. + * Mostly useful for hash tables where the two pointer list head is + * too wasteful. + * You lose the ability to access the tail in O(1). + */ + +struct hlist_head { + struct hlist_node *first; +}; + +struct hlist_node { + struct hlist_node *next, **pprev; +}; + +#define HLIST_HEAD_INIT { .first = NULL } +#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } +#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) +#define INIT_HLIST_NODE(ptr) ((ptr)->next = NULL, (ptr)->pprev = NULL) + +static inline int hlist_unhashed(const struct hlist_node *h) +{ + return !h->pprev; +} + +static inline int hlist_empty(const struct hlist_head *h) +{ + return !h->first; +} + +static inline void __hlist_del(struct hlist_node *n) +{ + struct hlist_node *next = n->next; + struct hlist_node **pprev = n->pprev; + *pprev = next; + if (next) + next->pprev = pprev; +} + +static inline void hlist_del(struct hlist_node *n) +{ + __hlist_del(n); + n->next = LIST_POISON1; + n->pprev = LIST_POISON2; +} + + +static inline void hlist_del_init(struct hlist_node *n) +{ + if (n->pprev) { + __hlist_del(n); + INIT_HLIST_NODE(n); + } +} + +static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) +{ + struct hlist_node *first = h->first; + n->next = first; + if (first) + first->pprev = &n->next; + h->first = n; + n->pprev = &h->first; +} + + + +/* next must be != NULL */ +static inline void hlist_add_before(struct hlist_node *n, + struct hlist_node *next) +{ + n->pprev = next->pprev; + n->next = next; + next->pprev = &n->next; + *(n->pprev) = n; +} + +static inline void hlist_add_after(struct hlist_node *n, + struct hlist_node *next) +{ + next->next = n->next; + n->next = next; + next->pprev = &n->next; + + if(next->next) + next->next->pprev = &next->next; +} + + + +#define hlist_entry(ptr, type, member) container_of(ptr,type,member) + +#define hlist_for_each(pos, head) \ + for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \ + pos = pos->next) + +#define hlist_for_each_safe(pos, n, head) \ + for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ + pos = n) + +/** + * hlist_for_each_entry - iterate over list of given type + * @tpos: the type * to use as a loop counter. + * @pos: the &struct hlist_node to use as a loop counter. + * @head: the head for your list. + * @member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry(tpos, pos, head, member) \ + for (pos = (head)->first; \ + pos && ({ prefetch(pos->next); 1;}) && \ + ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ + pos = pos->next) + +/** + * hlist_for_each_entry_continue - iterate over a hlist continuing after existing point + * @tpos: the type * to use as a loop counter. + * @pos: the &struct hlist_node to use as a loop counter. + * @member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry_continue(tpos, pos, member) \ + for (pos = (pos)->next; \ + pos && ({ prefetch(pos->next); 1;}) && \ + ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ + pos = pos->next) + +/** + * hlist_for_each_entry_from - iterate over a hlist continuing from existing point + * @tpos: the type * to use as a loop counter. + * @pos: the &struct hlist_node to use as a loop counter. + * @member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry_from(tpos, pos, member) \ + for (; pos && ({ prefetch(pos->next); 1;}) && \ + ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ + pos = pos->next) + +/** + * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry + * @tpos: the type * to use as a loop counter. + * @pos: the &struct hlist_node to use as a loop counter. + * @n: another &struct hlist_node to use as temporary storage + * @head: the head for your list. + * @member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \ + for (pos = (head)->first; \ + pos && ({ n = pos->next; 1; }) && \ + ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ + pos = n) + + +#endif diff --git a/platforms/bl808_m0/vendor/wifi/include/lmac_mac.h b/platforms/bl808_m0/vendor/wifi/include/lmac_mac.h new file mode 100644 index 0000000..1242559 --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/lmac_mac.h @@ -0,0 +1,522 @@ + +/** + **************************************************************************************** + * + * @file lmac_mac.h + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + + +#ifndef _MAC_H_ +#define _MAC_H_ + +/** + **************************************************************************************** + * @defgroup MAC MAC + * @ingroup COMMON + * @brief Common defines,structures + * + * This module contains defines commonaly used for MAC + * @{ + **************************************************************************************** + */ + +/* + * INCLUDE FILES + **************************************************************************************** + */ +#include "lmac_types.h" + + +/* + * DEFINES + **************************************************************************************** + */ +/// duration of a Time Unit in microseconds +#define TU_DURATION 1024 + +/// max number of channels in the 2.4 GHZ band +#define MAC_DOMAINCHANNEL_24G_MAX 14 + +/// max number of channels in the 5 GHZ band +#define MAC_DOMAINCHANNEL_5G_MAX 45 + +/// Mask to test if it's a basic rate - BIT(7) +#define MAC_BASIC_RATE 0x80 +/// Mask for extracting/checking word alignment +#define WORD_ALIGN 3 + +#define MAX_AMSDU_LENGTH 7935 + +/* + * MACRO DEFINITIONS + **************************************************************************************** + */ + +/** + **************************************************************************************** + * Compare two MAC addresses. + * The MAC addresses MUST be 16 bit aligned. + * @param[in] addr1_ptr Pointer to the first MAC address. + * @param[in] addr2_ptr Pointer to the second MAC address. + * @return True if equal, false if not. + **************************************************************************************** + */ +#define MAC_ADDR_CMP(addr1_ptr, addr2_ptr) \ + ((*(((u8*)(addr1_ptr)) + 0) == *(((u8*)(addr2_ptr)) + 0)) && \ + (*(((u8*)(addr1_ptr)) + 1) == *(((u8*)(addr2_ptr)) + 1)) && \ + (*(((u8*)(addr1_ptr)) + 2) == *(((u8*)(addr2_ptr)) + 2)) && \ + (*(((u8*)(addr1_ptr)) + 3) == *(((u8*)(addr2_ptr)) + 3)) && \ + (*(((u8*)(addr1_ptr)) + 4) == *(((u8*)(addr2_ptr)) + 4)) && \ + (*(((u8*)(addr1_ptr)) + 5) == *(((u8*)(addr2_ptr)) + 5))) + +/** + **************************************************************************************** + * Compare two MAC addresses whose alignment is not known. + * @param[in] __a1 Pointer to the first MAC address. + * @param[in] __a2 Pointer to the second MAC address. + * @return True if equal, false if not. + **************************************************************************************** + */ +#define MAC_ADDR_CMP_PACKED(__a1, __a2) \ + (memcmp(__a1, __a2, MAC_ADDR_LEN) == 0) + +/** + **************************************************************************************** + * Copy a MAC address. + * The MAC addresses MUST be 16 bit aligned. + * @param[in] addr1_ptr Pointer to the destination MAC address. + * @param[in] addr2_ptr Pointer to the source MAC address. + **************************************************************************************** + */ +#define MAC_ADDR_CPY(addr1_ptr, addr2_ptr) \ + *(((u16*)(addr1_ptr)) + 0) = *(((u16*)(addr2_ptr)) + 0); \ + *(((u16*)(addr1_ptr)) + 1) = *(((u16*)(addr2_ptr)) + 1); \ + *(((u16*)(addr1_ptr)) + 2) = *(((u16*)(addr2_ptr)) + 2) + +/** + **************************************************************************************** + * Compare two SSID. + * @param ssid1_ptr Pointer to the first SSID structure. + * @param ssid2_ptr Pointer to the second SSID structure. + * @return True if equal, false if not. + **************************************************************************************** + */ +#define MAC_SSID_CMP(ssid1_ptr,ssid2_ptr) \ + (((ssid1_ptr)->length == (ssid2_ptr)->length) && \ + (memcmp((&(ssid1_ptr)->array[0]), (&(ssid2_ptr)->array[0]), (ssid1_ptr)->length) == 0)) + +/// Check if MAC address is a group address: test the multicast bit. +#define MAC_ADDR_GROUP(mac_addr_ptr) ((*(mac_addr_ptr)) & 1) + +/// MAC address length in bytes. +#define MAC_ADDR_LEN 6 + +/// MAC address structure. +struct mac_addr +{ + /// Array of bytes that make up the MAC address. + u8_l array[MAC_ADDR_LEN]; +}; + +/// SSID maximum length. +#define MAC_SSID_LEN 32 + +/// SSID. +struct mac_ssid +{ + /// Actual length of the SSID. + u8_l length; + /// Array containing the SSID name. + u8_l array[MAC_SSID_LEN]; + u8_l array_tail[1];//for MAX SSID ISSUE +}; + +/// MAC RATE-SET +#define MAC_RATESET_LEN 12 +#define MAC_OFDM_PHY_RATESET_LEN 8 +#define MAC_EXT_RATES_OFF 8 +struct mac_rateset +{ + u8_l length; + u8_l array[MAC_RATESET_LEN]; +}; + +/// MAC RATES +#define MAC_MCS_WORD_CNT 3 +struct mac_rates +{ + /// MCS 0 to 76 + u32 mcs[MAC_MCS_WORD_CNT]; + /// Legacy rates (1Mbps to 54Mbps) + u16 legacy; +}; + +/// IV/EIV data +#define MAC_IV_LEN 4 +#define MAC_EIV_LEN 4 +struct rx_seciv +{ + u8 iv[MAC_IV_LEN]; + u8 ext_iv[MAC_EIV_LEN]; +}; + +/// MAC MCS SET +#define MAX_MCS_LEN 16 // 16 * 8 = 128 +struct mac_mcsset +{ + u8 length; + u8 array[MAX_MCS_LEN]; +}; + +/// MAC Secret Key +#define MAC_WEP_KEY_CNT 4 // Number of WEP keys per virtual device +#define MAC_WEP_KEY_LEN 13 // Max size of a WEP key (104/8 = 13) +struct mac_wep_key +{ + u8 array[MAC_WEP_KEY_LEN]; // Key material +}; + + +/// MAC Secret Key +#define MAC_SEC_KEY_LEN 32 // TKIP keys 256 bits (max length) with MIC keys +struct mac_sec_key +{ + u8_l length; // Key material length + u32_l array[MAC_SEC_KEY_LEN/4]; // Key material +}; + +/// MAC channel list +/// @todo: fix that number +#define MAC_MAX_CH 40 +struct mac_ch_list +{ + /// Number of channels in channel list. + u16 nbr; + /// List of the channels. + u8 list[MAC_MAX_CH]; +}; + + +struct mac_country_subband +{ + // First channel number of the triplet. + u8 first_chn; + // Max number of channel number for the triplet. + u8 nbr_of_chn; + // Maximum allowed transmit power. + u8 max_tx_power; +}; + +#define MAX_COUNTRY_LEN 3 +#define MAX_COUNTRY_SUBBAND 5 +struct mac_country +{ + // Length of the country string + u8 length; + // Country string 2 char. + u8 string[MAX_COUNTRY_LEN]; + // channel info triplet + struct mac_country_subband subband[MAX_COUNTRY_SUBBAND]; +}; + +/// MAC HT CAPABILITY +struct mac_htcapability +{ + u16_l ht_capa_info; + u8_l a_mpdu_param; + u8_l mcs_rate[MAX_MCS_LEN]; + u16_l ht_extended_capa; + u32_l tx_beamforming_capa; + u8_l asel_capa; +}; + +/// MAC VHT CAPABILITY +struct mac_vhtcapability +{ + u32_l vht_capa_info; + u16_l rx_mcs_map; + u16_l rx_highest; + u16_l tx_mcs_map; + u16_l tx_highest; +}; + + +/// MAC HT CAPABILITY +struct mac_htoprnelmt +{ + u8 prim_channel; + u8 ht_oper_1; + u16 ht_oper_2; + u16 ht_oper_3; + u8 mcs_rate[MAX_MCS_LEN]; + +}; + +/// MAC QOS CAPABILITY +struct mac_qoscapability +{ + u8 qos_info; +}; + +/// RSN information element +#define MAC_RAW_RSN_IE_LEN 34 +struct mac_raw_rsn_ie +{ + u8 data[2 + MAC_RAW_RSN_IE_LEN]; +}; + +#define MAC_RAW_ENC_LEN 0x1A +struct mac_wpa_frame +{ + u8 array[MAC_RAW_ENC_LEN]; +}; + +#define MAC_WME_PARAM_LEN 16 +struct mac_wmm_frame +{ + u8 array [MAC_WME_PARAM_LEN]; +}; + +/// BSS load element +struct mac_bss_load +{ + u16 sta_cnt; + u8 ch_utilization; + u16 avail_adm_capacity; +}; + +///EDCA Parameter Set Element +struct mac_edca_param_set +{ + u8 qos_info; + u32 ac_be_param_record; + u32 ac_bk_param_record; + u32 ac_vi_param_record; + u32 ac_vo_param_record; +}; + + +///MAC Twenty Forty BSS + +struct mac_twenty_fourty_bss +{ + u8 bss_coexistence; +}; + +/// MAC BA PARAMETERS +struct mac_ba_param +{ + struct mac_addr peer_sta_address; ///< Peer STA MAC Address to which BA is Setup + u16 buffer_size; ///< Number of buffers available for this BA + u16 start_sequence_number;///< Start Sequence Number of BA + u16 ba_timeout; ///< BA Setup timeout value + u8 dev_type; ///< BA Device Type Originator/Responder + u8 block_ack_policy; ///< BLOCK-ACK Policy Setup Immedaite/Delayed + u8 buffer_cnt; ///< Number of buffers required for BA Setup +}; + +/// MAC TS INFO field +struct mac_ts_info +{ + u8 traffic_type; + u8 ack_policy; + u8 access_policy; + u8 dir; + u8 tsid; + u8 user_priority; + bool aggregation; + bool apsd; + bool schedule; +}; + +/// MAC TSPEC PARAMETERS +struct mac_tspec_param +{ + struct mac_ts_info ts_info; + u16 nominal_msdu_size; + u16 max_msdu_size; + u32 min_service_interval; + u32 max_service_interval; + u32 inactivity_interval; + u32 short_inactivity_interval; + u32 service_start_time; + u32 max_burst_size; + u32 min_data_rate; + u32 mean_data_rate; + u32 min_phy_rate; + u32 peak_data_rate; + u32 delay_bound; + u16 medium_time; + u8 surplusbwallowance; +}; + +/// Scan result element, parsed from beacon or probe response frames. +struct mac_scan_result +{ + /// Network BSSID. + struct mac_addr bssid; + /// Network type (IBSS or ESS). + u16 bsstype; + /// Network channel number. + u16 ch_nbr; + /// Network beacon period. + u16 beacon_period; + u32 timestamp_high; + u32 timestamp_low; + u16 dtim_period; + u16 ibss_parameter; + u16 cap_info; + struct mac_rateset rate_set; + struct mac_bss_load bss_load; + u8 country_element[3]; + struct mac_edca_param_set edca_param; + struct mac_raw_rsn_ie rsn_ie; + struct mac_qoscapability qos_cap; + struct mac_htcapability ht_cap; + u8 sec_ch_oft; + struct mac_twenty_fourty_bss twenty_fourty_bss; + bool valid_flag; + u8 rssi; +}; + +/// Structure containing the information required to perform a measurement request +struct mac_request_set +{ + + u8 mode; /// +// Removed: #include -- pulls lwIP/wifi_hosal we don't link. +#include "lmac_mac.h" +#define MAX_PSK_PASS_PHRASE_LEN 64 + +/* + **************************************************************************************** + */ + +/// Power Save mode setting +enum mm_ps_mode_state +{ + MM_PS_MODE_OFF, + MM_PS_MODE_ON, + MM_PS_MODE_ON_DYN, +}; + +/// Status/error codes used in the MAC software. +enum +{ + CO_OK, + CO_FAIL, + CO_EMPTY, + CO_FULL, + CO_BAD_PARAM, + CO_NOT_FOUND, + CO_NO_MORE_ELT_AVAILABLE, + CO_NO_ELT_IN_USE, + CO_BUSY, + CO_OP_IN_PROGRESS, +}; + +/// WiFi Mode +typedef enum { + /// 802.ll b + WIFI_MODE_802_11B = 0x01, + /// 802.11 a + WIFI_MODE_802_11A = 0x02, + /// 802.11 g + WIFI_MODE_802_11G = 0x04, + /// 802.11n at 2.4GHz + WIFI_MODE_802_11N_2_4 = 0x08, + /// 802.11n at 5GHz + WIFI_MODE_802_11N_5 = 0x10, + /// 802.11ac at 5GHz + WIFI_MODE_802_11AC_5 = 0x20, + /// Reserved for future use + WIFI_MODE_RESERVED = 0x40, +} WiFi_Mode_t; + +/// Remain on channel operation codes +enum mm_remain_on_channel_op +{ + MM_ROC_OP_START = 0, + MM_ROC_OP_CANCEL, +}; + +#define DRV_TASK_ID 100 + +#define MSG_T(msg) (((msg) >> 10)) +#define MSG_I(msg) ((msg) & ((1<<10)-1)) + +/// The two following definitions are needed for message structure consistency +/// Structure of a list element header +/// Message structure. +struct lmac_msg +{ + ke_msg_id_t id; ///< Message id. + ke_task_id_t dest_id; ///< Destination kernel identifier. + ke_task_id_t src_id; ///< Source kernel identifier. + u32 param_len; ///< Parameter embedded struct length. + u32 param[]; ///< Parameter embedded struct. Must be word-aligned. +}; + +/// Interface types +enum +{ + /// ESS STA interface + MM_STA, + /// IBSS STA interface + MM_IBSS, + /// AP interface + MM_AP, + // Mesh Point interface + MM_MESH_POINT, +}; + +/// Maximum number of words in the configuration buffer +#define PHY_CFG_BUF_SIZE 16 + +/// Structure containing the parameters of the PHY configuration +struct phy_cfg_tag +{ + /// Buffer containing the parameters specific for the PHY used + u32_l parameters[PHY_CFG_BUF_SIZE]; +}; + +/// Structure containing the parameters of the @ref MM_MONITOR_CFM message. +struct mm_monitor_cfm +{ + uint32_t status; + uint32_t enable; + uint32_t data[8]; +}; + +/// Structure containing the parameters of the Trident PHY configuration +struct phy_trd_cfg_tag +{ + /// MDM type(nxm)(upper nibble) and MDM2RF path mapping(lower nibble) + u8_l path_mapping; + /// TX DC offset compensation + u32_l tx_dc_off_comp; +}; + +/// Structure containing the parameters of the Karst PHY configuration +struct phy_karst_cfg_tag +{ + /// TX IQ mismatch compensation in 2.4GHz + u32_l tx_iq_comp_2_4G[2]; + /// RX IQ mismatch compensation in 2.4GHz + u32_l rx_iq_comp_2_4G[2]; + /// TX IQ mismatch compensation in 5GHz + u32_l tx_iq_comp_5G[2]; + /// RX IQ mismatch compensation in 5GHz + u32_l rx_iq_comp_5G[2]; + /// RF path used by default (0 or 1) + u8_l path_used; +}; + +/// Structure containing the parameters of the @ref MM_START_REQ message +struct mm_start_req +{ + /// PHY configuration + struct phy_cfg_tag phy_cfg; + /// UAPSD timeout + u32_l uapsd_timeout; + /// Local LP clock accuracy (in ppm) + u16_l lp_clk_accuracy; +}; + +/// Structure containing the parameters of the @ref MM_SET_CHANNEL_REQ message +struct mm_set_channel_req +{ + /// Band (2.4GHz or 5GHz) + u8_l band; + /// Channel type: 20,40,80,160 or 80+80 MHz + u8_l type; + /// Frequency for Primary 20MHz channel (in MHz) + u16_l prim20_freq; + /// Frequency for Center of the contiguous channel or center of Primary 80+80 + u16_l center1_freq; + /// Frequency for Center of the non-contiguous secondary 80+80 + u16_l center2_freq; + /// Index of the RF for which the channel has to be set (0: operating (primary), 1: secondary + /// RF (used for additional radar detection). This parameter is reserved if no secondary RF + /// is available in the system + u8_l index; + /// Max tx power for this channel + s8_l tx_power; +}; + +/// Structure containing the parameters of the @ref MM_SET_CHANNEL_CFM message +struct mm_set_channel_cfm +{ + /// Radio index to be used in policy table + u8_l radio_idx; + /// TX power configured (in dBm) + s8_l power; +}; + +/// Structure containing the parameters of the @ref MM_SET_DTIM_REQ message +struct mm_set_dtim_req +{ + /// DTIM period + u8_l dtim_period; +}; + +/// Structure containing the parameters of the @ref MM_SET_POWER_REQ message +struct mm_set_power_req +{ + /// Index of the interface for which the parameter is configured + u8_l inst_nbr; + /// TX power (in dBm) + s8_l power; +}; + +/// Structure containing the parameters of the @ref MM_SET_POWER_CFM message +struct mm_set_power_cfm +{ + /// Radio index to be used in policy table + u8_l radio_idx; + /// TX power configured (in dBm) + s8_l power; +}; + +/// Structure containing the parameters of the @ref MM_SET_BEACON_INT_REQ message +struct mm_set_beacon_int_req +{ + /// Beacon interval + u16_l beacon_int; + /// Index of the interface for which the parameter is configured + u8_l inst_nbr; +}; + +/// Structure containing the parameters of the @ref MM_SET_BEACON_INT_CFM message +struct mm_set_beacon_int_cfm +{ + u8_l status; +}; + +/// Structure containing the parameters of the @ref MM_SET_BASIC_RATES_REQ message +struct mm_set_basic_rates_req +{ + /// Basic rate set (as expected by bssBasicRateSet field of Rates MAC HW register) + u32_l rates; + /// Index of the interface for which the parameter is configured + u8_l inst_nbr; + /// Band on which the interface will operate + u8_l band; +}; + +/// Structure containing the parameters of the @ref MM_SET_BSSID_REQ message +struct mm_set_bssid_req +{ + /// BSSID to be configured in HW + struct mac_addr bssid; + /// Index of the interface for which the parameter is configured + u8_l inst_nbr; +}; + +/// Structure containing the parameters of the @ref MM_ADD_IF_REQ message. +struct mm_add_if_req +{ + /// Type of the interface (AP, STA, ADHOC, ...) + u8_l type; + /// MAC ADDR of the interface to start + struct mac_addr addr; + /// P2P Interface + bool_l p2p; +}; + +/// Structure containing the parameters of the @ref MM_SET_EDCA_REQ message +struct mm_set_edca_req +{ + /// EDCA parameters of the queue (as expected by edcaACxReg HW register) + u32_l ac_param; + /// Flag indicating if UAPSD can be used on this queue + bool_l uapsd; + /// HW queue for which the parameters are configured + u8_l hw_queue; + /// Index of the interface for which the parameters are configured + u8_l inst_nbr; +}; + +struct mm_set_idle_req +{ + u8_l hw_idle; +}; + +/// Structure containing the parameters of the @ref MM_SET_MODE_REQ message +struct mm_set_mode_req +{ + /// abgnMode field of macCntrl1Reg register + u8_l abgnmode; +}; + +/// Structure containing the parameters of the @ref MM_SET_VIF_STATE_REQ message +struct mm_set_vif_state_req +{ + /// Association Id received from the AP (valid only if the VIF is of STA type) + u16_l aid; + /// Flag indicating if the VIF is active or not + bool_l active; + /// Interface index + u8_l inst_nbr; +}; + +/// Structure containing the parameters of the @ref MM_ADD_IF_CFM message. +struct mm_add_if_cfm +{ + /// Status of operation (different from 0 if unsuccessful) + u8_l status; + /// Interface index assigned by the LMAC + u8_l inst_nbr; +}; + +/// Structure containing the parameters of the @ref MM_REMOVE_IF_REQ message. +struct mm_remove_if_req +{ + /// Interface index assigned by the LMAC + u8_l inst_nbr; +}; + +/// Structure containing the parameters of the @ref MM_VERSION_CFM message. +struct mm_version_cfm +{ + /// Version of the LMAC FW + u32_l version_lmac; + /// Version1 of the MAC HW (as encoded in version1Reg MAC HW register) + u32_l version_machw_1; + /// Version2 of the MAC HW (as encoded in version2Reg MAC HW register) + u32_l version_machw_2; + /// Version1 of the PHY (depends on actual PHY) + u32_l version_phy_1; + /// Version2 of the PHY (depends on actual PHY) + u32_l version_phy_2; + /// Supported Features + u32_l features; +}; + +/// Structure containing the parameters of the @ref MM_STA_ADD_REQ message. +struct mm_sta_add_req +{ + /// PAID/GID + u32_l paid_gid; + /// Maximum A-MPDU size, in bytes, for HT frames + u16_l ampdu_size_max_ht; + /// MAC address of the station to be added + struct mac_addr mac_addr; + /// A-MPDU spacing, in us + u8_l ampdu_spacing_min; + /// Interface index + u8_l inst_nbr; +}; + +/// Structure containing the parameters of the @ref MM_STA_ADD_CFM message. +struct mm_sta_add_cfm +{ + /// Status of the operation (different from 0 if unsuccessful) + u8_l status; + /// Index assigned by the LMAC to the newly added station + u8_l sta_idx; + /// MAC HW index of the newly added station + u8_l hw_sta_idx; +}; + +/// Structure containing the parameters of the @ref MM_STA_DEL_REQ message. +struct mm_sta_del_req +{ + /// Index of the station to be deleted + u8_l sta_idx; +}; + +/// Structure containing the parameters of the @ref MM_STA_DEL_CFM message. +struct mm_sta_del_cfm +{ + /// Status of the operation (different from 0 if unsuccessful) + u8_l status; +}; + +/// Structure containing the parameters of the SET_POWER_MODE REQ message. +struct mm_setpowermode_req +{ + u8_l mode; + u8_l sta_idx; +}; + +/// Structure containing the parameters of the SET_POWER_MODE CFM message. +struct mm_setpowermode_cfm +{ + u8_l status; +}; + +/// Structure containing the parameters of the @ref MM_MONITOR_REQ message. +struct mm_monitor_req +{ + uint32_t enable; +}; + +/// Structure containing the parameters of the @ref MM_MONITOR_CHANNEL_REQ message. +struct mm_monitor_channel_req +{ + uint32_t freq; +}; + +/// Structure containing the parameters of the @ref MM_MONITOR_CHANNEL_CFM message. +struct mm_monitor_channel_cfm +{ + uint32_t status; + uint32_t freq; + uint32_t data[8]; +}; + +/// Structure containing the parameters of the @ref MM_CHAN_CTXT_ADD_REQ message +struct mm_chan_ctxt_add_req +{ + /// Band (2.4GHz or 5GHz) + u8_l band; + /// Channel type: 20,40,80,160 or 80+80 MHz + u8_l type; + /// Frequency for Primary 20MHz channel (in MHz) + u16_l prim20_freq; + /// Frequency for Center of the contiguous channel or center of Primary 80+80 + u16_l center1_freq; + /// Frequency for Center of the non-contiguous secondary 80+80 + u16_l center2_freq; + /// Max tx power for this channel + s8_l tx_power; +}; + +/// Structure containing the parameters of the @ref MM_CHAN_CTXT_ADD_REQ message +struct mm_chan_ctxt_add_cfm +{ + /// Status of the addition + u8_l status; + /// Index of the new channel context + u8_l index; +}; + + +/// Structure containing the parameters of the @ref MM_CHAN_CTXT_DEL_REQ message +struct mm_chan_ctxt_del_req +{ + /// Index of the new channel context to be deleted + u8_l index; +}; + + +/// Structure containing the parameters of the @ref MM_CHAN_CTXT_LINK_REQ message +struct mm_chan_ctxt_link_req +{ + /// VIF index + u8_l vif_index; + /// Channel context index + u8_l chan_index; + /// Indicate if this is a channel switch (unlink current ctx first if true) + u8_l chan_switch; +}; + +/// Structure containing the parameters of the @ref MM_CHAN_CTXT_UNLINK_REQ message +struct mm_chan_ctxt_unlink_req +{ + /// VIF index + u8_l vif_index; +}; + +/// Structure containing the parameters of the @ref MM_CHAN_CTXT_UPDATE_REQ message +struct mm_chan_ctxt_update_req +{ + /// Channel context index + u8_l chan_index; + /// Band (2.4GHz or 5GHz) + u8_l band; + /// Channel type: 20,40,80,160 or 80+80 MHz + u8_l type; + /// Frequency for Primary 20MHz channel (in MHz) + u16_l prim20_freq; + /// Frequency for Center of the contiguous channel or center of Primary 80+80 + u16_l center1_freq; + /// Frequency for Center of the non-contiguous secondary 80+80 + u16_l center2_freq; +}; + +/// Structure containing the parameters of the @ref MM_CHAN_CTXT_SCHED_REQ message +struct mm_chan_ctxt_sched_req +{ + /// VIF index + u8_l vif_index; + /// Channel context index + u8_l chan_index; + /// Type of the scheduling request (0: normal scheduling, 1: derogatory + /// scheduling) + u8_l type; +}; + +/// Structure containing the parameters of the @ref MM_CHANNEL_SWITCH_IND message +struct mm_channel_switch_ind +{ + /// Index of the channel context we will switch to + u8_l chan_index; + /// Indicate if the switch has been triggered by a Remain on channel request + bool_l roc; + /// VIF on which remain on channel operation has been started (if roc == 1) + u8_l vif_index; + /// Indicate if the switch has been triggered by a TDLS Remain on channel request + bool_l roc_tdls; +}; + +/// Structure containing the parameters of the @ref MM_CHANNEL_PRE_SWITCH_IND message +struct mm_channel_pre_switch_ind +{ + /// Index of the channel context we will switch to + u8_l chan_index; +}; + +/// Structure containing the parameters of the @ref MM_CONNECTION_LOSS_IND message. +struct mm_connection_loss_ind +{ + /// VIF instance number + u8_l inst_nbr; +}; + +/// Structure containing the parameters of the @ref MM_SET_PS_MODE_REQ message. +struct mm_set_ps_mode_req +{ + /// Power Save is activated or deactivated + u8_l new_state; +}; + +struct mm_set_denoise_req +{ + u8_l denoise_mode; +}; + +/// Structure containing the parameters of the @ref MM_BCN_CHANGE_REQ message. +#define BCN_MAX_CSA_CPT 2 +struct mm_bcn_change_req +{ + /// Pointer, in host memory, to the new beacon template + u32_l bcn_ptr; + /// Length of the beacon template + u16_l bcn_len; + /// Offset of the TIM IE in the beacon + u16_l tim_oft; + /// Length of the TIM IE + u8_l tim_len; + /// Index of the VIF for which the beacon is updated + u8_l inst_nbr; + /// Offset of CSA (channel switch announcement) counters (0 means no counter) + u8_l csa_oft[BCN_MAX_CSA_CPT]; +}; + + +/// Structure containing the parameters of the @ref MM_TIM_UPDATE_REQ message. +struct mm_tim_update_req +{ + /// Association ID of the STA the bit of which has to be updated (0 for BC/MC traffic) + u16_l aid; + /// Flag indicating the availability of data packets for the given STA + u8_l tx_avail; + /// Index of the VIF for which the TIM is updated + u8_l inst_nbr; +}; + +/// Structure containing the parameters of the @ref MM_REMAIN_ON_CHANNEL_REQ message. +struct mm_remain_on_channel_req +{ + /// Operation Code + u8_l op_code; + /// VIF Index + u8_l vif_index; + /// Band (2.4GHz or 5GHz) + u8_l band; + /// Channel type: 20,40,80,160 or 80+80 MHz + u8_l type; + /// Frequency for Primary 20MHz channel (in MHz) + u16_l prim20_freq; + /// Frequency for Center of the contiguous channel or center of Primary 80+80 + u16_l center1_freq; + /// Frequency for Center of the non-contiguous secondary 80+80 + u16_l center2_freq; + /// Duration (in ms) + u32_l duration_ms; + /// TX power (in dBm) + s8_l tx_power; +}; + +/// Structure containing the parameters of the @ref MM_REMAIN_ON_CHANNEL_CFM message +struct mm_remain_on_channel_cfm +{ + /// Operation Code + u8_l op_code; + /// Status of the operation + u8_l status; + /// Channel Context index + u8_l chan_ctxt_index; +}; + +/// Structure containing the parameters of the @ref MM_REMAIN_ON_CHANNEL_EXP_IND message +struct mm_remain_on_channel_exp_ind +{ + /// VIF Index + u8_l vif_index; + /// Channel Context index + u8_l chan_ctxt_index; +}; + +/// Structure containing the parameters of the @ref MM_SET_UAPSD_TMR_REQ message. +struct mm_set_uapsd_tmr_req +{ + /// action: Start or Stop the timer + u8_l action; + /// timeout value, in milliseconds + u32_l timeout; +}; + +/// Structure containing the parameters of the @ref MM_SET_UAPSD_TMR_CFM message. +struct mm_set_uapsd_tmr_cfm +{ + /// Status of the operation (different from 0 if unsuccessful) + u8_l status; +}; + + +/// Structure containing the parameters of the @ref MM_PS_CHANGE_IND message +struct mm_ps_change_ind +{ + /// Index of the peer device that is switching its PS state + u8_l sta_idx; + /// New PS state of the peer device (0: active, 1: sleeping) + u8_l ps_state; +}; + +/// Structure containing the parameters of the @ref MM_TRAFFIC_REQ_IND message +struct mm_traffic_req_ind +{ + /// Index of the peer device that needs traffic + u8_l sta_idx; + /// Number of packets that need to be sent (if 0, all buffered traffic shall be sent) + u8_l pkt_cnt; + /// Flag indicating if the traffic request concerns U-APSD queues or not + bool_l uapsd; +}; + +/// Structure containing the parameters of the @ref MM_SET_PS_OPTIONS_REQ message. +struct mm_set_ps_options_req +{ + /// VIF Index + u8_l vif_index; + /// Listen interval (0 if wake up shall be based on DTIM period) + u16_l listen_interval; + /// Flag indicating if we shall listen the BC/MC traffic or not + bool_l dont_listen_bc_mc; +}; + +/// Structure containing the parameters of the @ref MM_CSA_COUNTER_IND message +struct mm_csa_counter_ind +{ + /// Index of the VIF + u8_l vif_index; + /// Updated CSA counter value + u8_l csa_count; +}; + +/// Structure containing the parameters of the @ref MM_CHANNEL_SURVEY_IND message +struct mm_channel_survey_ind +{ + /// Frequency of the channel + u16_l freq; + /// Noise in dbm + s8_l noise_dbm; + /// Amount of time spent of the channel (in ms) + u32_l chan_time_ms; + /// Amount of time the primary channel was sensed busy + u32_l chan_time_busy_ms; +}; + +/// Structure containing the parameters of the @ref MM_CFG_RSSI_REQ message +struct mm_cfg_rssi_req +{ + /// Index of the VIF + u8_l vif_index; + /// RSSI threshold + s8_l rssi_thold; + /// RSSI hysteresis + u8_l rssi_hyst; +}; + +/// Structure containing the parameters of the @ref MM_RSSI_STATUS_IND message +struct mm_rssi_status_ind +{ + /// Index of the VIF + u8_l vif_index; + /// Status of the RSSI + bool_l rssi_status; + /// RSSI of current ind + s8_l rssi; +}; + +/// Maximum number of SSIDs in a scan request +#define SCAN_SSID_MAX 1 + +/// Maximum number of 2.4GHz channels +#define SCAN_CHANNEL_2G4 14 + +/// Maximum number of 5GHz channels +#define SCAN_CHANNEL_5G 28 + +/// Maximum number of channels in a scan request +#define SCAN_CHANNEL_MAX (SCAN_CHANNEL_2G4 + SCAN_CHANNEL_5G) + +/// Flag bits +#define SCAN_PASSIVE_BIT BIT(0) +#define SCAN_DISABLED_BIT BIT(1) + +/// Definition of a channel to be scanned +struct scan_chan_tag +{ + /// Frequency of the channel + u16_l freq; + /// RF band (0: 2.4GHz, 1: 5GHz) + u8_l band; + /// Bit field containing additional information about the channel + u8_l flags; + /// Max tx_power for this channel (dBm) + s8_l tx_power; +}; + +/// Structure containing the parameters of the @ref SCAN_START_REQ message +struct scan_start_req +{ + /// List of channel to be scanned + struct scan_chan_tag chan[SCAN_CHANNEL_MAX]; + /// List of SSIDs to be scanned + struct mac_ssid ssid[SCAN_SSID_MAX]; + /// BSSID to be scanned + struct mac_addr bssid; + /// MAC address used to send probe request + struct mac_addr mac; + /// Pointer (in host memory) to the additional IEs that need to be added to the ProbeReq + /// (following the SSID element) + u32_l add_ies; + /// Length of the additional IEs + u16_l add_ie_len; + /// Index of the VIF that is scanning + u8_l vif_idx; + /// Number of channels to scan + u8_l chan_cnt; + /// Number of SSIDs to scan for + u8_l ssid_cnt; + /// no CCK - For P2P frames not being sent at CCK rate in 2GHz band. + bool no_cck; +}; + +/// Structure containing the parameters of the @ref SCAN_START_CFM message +struct scan_start_cfm +{ + /// Status of the request + u8_l status; +}; + +/// Structure containing the parameters of the @ref SCANU_START_REQ message +struct scanu_start_req +{ + /// List of channel to be scanned + struct scan_chan_tag chan[SCAN_CHANNEL_MAX]; + /// List of SSIDs to be scanned + struct mac_ssid ssid[SCAN_SSID_MAX]; + /// BSSID to be scanned (or WILDCARD BSSID if no BSSID is searched in particular) + struct mac_addr bssid; + /// MAC address used to send probe request + struct mac_addr mac; + /// Address (in host memory) of the additional IEs that need to be added to the ProbeReq + /// (following the SSID element) + u32_l add_ies; + /// Length of the additional IEs + u16_l add_ie_len; + /// Index of the VIF that is scanning + u8_l vif_idx; + /// Number of channels to scan + u8_l chan_cnt; + /// Number of SSIDs to scan for + u8_l ssid_cnt; + /// no CCK - For P2P frames not being sent at CCK rate in 2GHz band. + bool no_cck; + /// MISC flags + uint32_t flags; + /// channel scan time + uint32_t duration_scan; +}; + +struct scanu_raw_send_req +{ + void *pkt; + uint32_t len; +}; + +struct scanu_raw_send_cfm +{ + uint32_t status; +}; + +/// Structure containing the parameters of the @ref SCANU_START_CFM message +struct scanu_start_cfm +{ + /// Status of the request + u8_l status; +}; + +/// Parameters of the @SCANU_RESULT_IND message +struct scanu_result_ind +{ + /// Length of the frame + uint16_t length; + /// Frame control field of the frame. + uint16_t framectrl; + /// Center frequency on which we received the packet + uint16_t center_freq; + /// PHY band + uint8_t band; + /// Index of the station that sent the frame. 0xFF if unknown. + uint8_t sta_idx; + /// Index of the VIF that received the frame. 0xFF if unknown. + uint8_t inst_nbr; + /// Source mac of the received frame. + uint8_t sa[6]; + /// timestamp of the received frame. + uint32_t tsflo; + uint32_t tsfhi; + /// RSSI of the received frame. + int8_t rssi; + ///Abs. PPM of the received frame + int8_t ppm_abs; + ///Rel. PPM of the received frame + int8_t ppm_rel; + /// Flags + uint8_t flags; + /// Date rate of the received frame. + uint8_t data_rate; + /// Frame payload. + uint32_t payload[]; +}; + +/// Structure containing the parameters of the message. +struct scanu_fast_req +{ + /// The SSID to scan in the channel. + struct mac_ssid ssid; + /// BSSID. + struct mac_addr bssid; + /// Probe delay. + u16_l probe_delay; + /// Minimum channel time. + u16_l minch_time; + /// Maximum channel time. + u16_l maxch_time; + /// The channel number to scan. + u16_l ch_nbr; +}; + + +/// Structure containing the parameters of the @ref ME_START_REQ message +struct me_config_req +{ + /// HT Capabilities + struct mac_htcapability ht_cap; + /// VHT Capabilities + struct mac_vhtcapability vht_cap; + /// Lifetime of packets sent under a BlockAck agreement (expressed in TUs) + u16_l tx_lft; + /// Boolean indicating if HT is supported or not + bool_l ht_supp; + /// Boolean indicating if VHT is supported or not + bool_l vht_supp; + /// Boolean indicating if PS mode shall be enabled or not + bool_l ps_on; +}; + +/// Structure containing the parameters of the @ref ME_CHAN_CONFIG_REQ message +struct me_chan_config_req +{ + /// List of 2.4GHz supported channels + struct scan_chan_tag chan2G4[SCAN_CHANNEL_2G4]; + /// Number of 2.4GHz channels in the list + u8_l chan2G4_cnt; +}; + +/// Structure containing the parameters of the @ref ME_SET_CONTROL_PORT_REQ message +struct me_set_control_port_req +{ + /// Index of the station for which the control port is opened + u8_l sta_idx; + /// Control port state + bool_l control_port_open; +}; + +/// Structure containing the parameters of the @ref ME_TKIP_MIC_FAILURE_IND message +struct me_tkip_mic_failure_ind +{ + /// Address of the sending STA + struct mac_addr addr; + /// TSC value + u64_l tsc; + /// Boolean indicating if the packet was a group or unicast one (true if group) + bool_l ga; + /// Key Id + u8_l keyid; + /// VIF index + u8_l vif_idx; +}; + +/// Structure containing the parameters of the @ref ME_STA_ADD_REQ message +struct me_sta_add_req +{ + /// MAC address of the station to be added + struct mac_addr mac_addr; + /// Supported legacy rates + struct mac_rateset rate_set; + /// HT Capabilities + struct mac_htcapability ht_cap; + /// VHT Capabilities + struct mac_vhtcapability vht_cap; + /// Flags giving additional information about the station + u32_l flags; + /// Association ID of the station + u16_l aid; + /// Bit field indicating which queues have U-APSD enabled + u8_l uapsd_queues; + /// Maximum size, in frames, of a APSD service period + u8_l max_sp_len; + /// Operation mode information (valid if bit @ref STA_OPMOD_NOTIF is + /// set in the flags) + u8_l opmode; + /// Index of the VIF the station is attached to + u8_l vif_idx; +#if (TDLS_ENABLE) + /// Whether the the station is TDLS station + bool_l tdls_sta; +#endif + uint32_t tsflo; + uint32_t tsfhi; + int8_t rssi; + uint8_t data_rate; +}; + +/// Structure containing the parameters of the @ref ME_STA_ADD_CFM message +struct me_sta_add_cfm +{ + /// Station index + u8_l sta_idx; + /// Status of the station addition + u8_l status; + /// PM state of the station + u8_l pm_state; +}; + +/// Structure containing the parameters of the @ref ME_STA_DEL_REQ message. +struct me_sta_del_req +{ + /// Index of the station to be deleted + u8_l sta_idx; +#if (TDLS_ENABLE) + /// Whether the the station is TDLS station + bool_l tdls_sta; +#endif +}; + +/// Structure containing the parameters of the @ref ME_TX_CREDITS_UPDATE_IND message. +struct me_tx_credits_update_ind +{ + /// Index of the station for which the credits are updated + u8_l sta_idx; + /// TID for which the credits are updated + u8_l tid; + /// Offset to be applied on the credit count + s8_l credits; +}; + +/// Structure containing the parameters of the @ref ME_TRAFFIC_IND_REQ message. +struct me_traffic_ind_req +{ + /// Index of the station for which UAPSD traffic is available on host + u8_l sta_idx; + /// Flag indicating the availability of UAPSD packets for the given STA + u8_l tx_avail; + /// Indicate if traffic is on uapsd-enabled queues + bool_l uapsd; +}; + +/// Structure containing the structure of a retry chain step +struct step +{ + /// Current calculated throughput + u32_l tp; + /// Index of the sample in the rate_stats table + u16_l idx; +}; + +/// Structure containing the rate control statistics +struct rc_rate_stats +{ + /// Number of attempts (per sampling interval) + u16_l attempts; + /// Number of success (per sampling interval) + u16_l success; + /// Estimated probability of success (EWMA) + u16_l probability; + /// Rate configuration of the sample + u16_l rate_config; + /// Number of times the sample has been skipped (per sampling interval) + u8_l sample_skipped; + /// Whether the old probability is available + bool_l old_prob_available; + /// Number of times the AMPDU has been retried with this rate + u8_l n_retry; + // Whether the rate can be used in the retry chain + bool_l rate_allowed; +}; + +/// Structure containing the parameters of the @ref ME_RC_SET_RATE_REQ message. +struct me_rc_set_rate_req +{ + /// Index of the station for which the fixed rate is set + u8_l sta_idx; + /// Rate configuration to be set + u16_l fixed_rate_cfg; + /// Force power table update + u16_l power_table_req; +}; + + +/// Structure containing the parameters of @ref SM_CONNECT_REQ message. +struct sm_connect_req +{ + /// SSID to connect to + struct mac_ssid ssid; + /// BSSID to connect to (if not specified, set this field to WILDCARD BSSID) + struct mac_addr bssid; + /// Channel on which we have to connect (if not specified, set -1 in the chan.freq field) + struct scan_chan_tag chan; + /// Connection flags (see @ref sm_connect_flags) + u32_l flags; + /// Control port Ethertype + u16_l ctrl_port_ethertype; +#if 0 + /// Length of the association request IEs + u16_l ie_len; +#endif + /// Listen interval to be used for this connection + u16_l listen_interval; + /// Flag indicating if the we have to wait for the BC/MC traffic after beacon or not + bool_l dont_wait_bcmc; + /// Authentication type + u8_l auth_type; + /// UAPSD queues (bit0: VO, bit1: VI, bit2: BE, bit3: BK) + u8_l uapsd_queues; + /// VIF index + u8_l vif_idx; + /// retry counter for auth/aossoc + u8_l counter_retry_auth_assoc; +#if 0 + /// Buffer containing the additional information elements to be put in the + /// association request + u32_l ie_buf[64]; +#endif + /// Enable embedded supplicant + bool is_supplicant_enabled; + //// Passphrase + uint8_t phrase[MAX_PSK_PASS_PHRASE_LEN]; + uint8_t phrase_pmk[MAX_PSK_PASS_PHRASE_LEN]; +}; + +/// Structure containing the parameters of the @ref SM_CONNECT_CFM message. +struct sm_connect_cfm +{ + /// Status. If 0, it means that the connection procedure will be performed and that + /// a subsequent @ref SM_CONNECT_IND message will be forwarded once the procedure is + /// completed + u8_l status; +}; + +#define SM_ASSOC_IE_LEN 800 +/// Structure containing the parameters of the @ref SM_CONNECT_IND message. +struct sm_connect_ind +{ + /// Status code of the connection procedure + u16_l status_code; + /// Reason code by AP + u16_l reason_code; + /// BSSID + struct mac_addr bssid; + /// Flag indicating if the indication refers to an internal roaming or from a host request + bool_l roamed; + /// Index of the VIF for which the association process is complete + u8_l vif_idx; + /// Index of the STA entry allocated for the AP + u8_l ap_idx; + /// Index of the LMAC channel context the connection is attached to + u8_l ch_idx; + /// Flag indicating if the AP is supporting QoS + bool_l qos; + /// ACM bits set in the AP WMM parameter element + u8_l acm; + /// Length of the AssocReq IEs + u16_l assoc_req_ie_len; + /// Length of the AssocRsp IEs + u16_l assoc_rsp_ie_len; + /// IE buffer + u32_l assoc_ie_buf[SM_ASSOC_IE_LEN/4]; + + u16_l aid; + u8_l band; + u16_l center_freq; + u8_l width; + u32_l center_freq1; + u32_l center_freq2; + + /// EDCA parameters + u32_l ac_param[AC_MAX]; + /// Pointer to the structure used for the diagnose module + struct sm_tlv_list connect_diagnose; +}; + +/// Structure containing the parameters of the @ref SM_DISCONNECT_REQ message. +struct sm_disconnect_req +{ + /// Index of the VIF. + u8_l vif_idx; +}; + +/// Structure containing the parameters of SM_ASSOCIATION_IND the message +struct sm_association_ind +{ + // MAC ADDR of the STA + struct mac_addr me_mac_addr; +}; + + +/// Structure containing the parameters of the @ref SM_DISCONNECT_IND message. +struct sm_disconnect_ind +{ + /// Status code of the disconnection procedure + u16_l status_code; + /// Reason of the disconnection. + u16_l reason_code; + /// Index of the VIF. + u8_l vif_idx; + /// FT over DS is ongoing + bool_l ft_over_ds; + /// Pointer to the structure used for the diagnose module + struct sm_tlv_list connect_diagnose; +}; + +/// Structure containing the parameters of the @ref SM_CONNECT_ABORT_REQ message. +struct sm_connect_abort_req +{ + /// Index of the VIF. + uint8_t vif_idx; +}; + +/// Structure containing the parameters of the @ref SM_CONNECT_ABORT_CFM message. +struct sm_connect_abort_cfm +{ + /// Status. If 0, it means that the disconnection procedure will be aborted and that + /// a subsequent @ref SM_DISCONNECT_IND message will be forwarded once the procedure is + /// completed. + /// If 1, it means that the scan procdure will be aborted. + uint8_t status; +}; + +// Patched: was a bare definition (`} cfg_start_req_u_tlv_t;`), relied on +// pre-gcc-10 -fcommon to merge per-TU defs. Modern gcc refuses to make a +// var with a flexible array member COMMON. Header declares the type + +// extern; the single definition lives in src/bl_globals.c. +struct cfg_start_req_u_tlv_s +{ + /// TASK + uint32_t task; + /// ELEMENT + uint32_t element; + /// length + uint32_t length; + /// buffer + uint32_t buf[]; +}; +extern struct cfg_start_req_u_tlv_s cfg_start_req_u_tlv_t; + +struct cfg_start_req +{ + /// TYPE: GET/SET/RESET/DUMP + uint32_t ops; + union { + /// struct for get ELEMENT + struct { + /// TASK + uint32_t task; + /// ELEMENT + uint32_t element; + } get[0]; + + /// struct for reset ELEMENT + struct { + /// TASK + uint32_t task; + /// ELEMENT + uint32_t element; + } reset[0]; + + /// struct for set ELEMENT with TLV based + struct { + /// TASK + uint32_t task; + /// ELEMENT + uint32_t element; + /// type + uint32_t type; + /// length + uint32_t length; + /// buffer + uint32_t buf[]; + } set[0]; + } u; +}; + +struct cfg_start_cfm +{ + /// Status of the AP starting procedure + uint8_t status; +}; + + +/// Structure containing the parameters of the @ref APM_START_REQ message. +struct apm_start_req +{ + /// Basic rate set + struct mac_rateset basic_rates; + /// Control channel on which we have to enable the AP + struct scan_chan_tag chan; + /// Center frequency of the first segment + u32_l center_freq1; + /// Center frequency of the second segment (only in 80+80 configuration) + u32_l center_freq2; + /// Width of channel + u8_l ch_width; + /// Hidden ssid + u8_l hidden_ssid; + /// Address, in host memory, to the beacon template + u32_l bcn_addr; + /// Length of the beacon template + u16_l bcn_len; + /// Offset of the TIM IE in the beacon + u16_l tim_oft; + /// Beacon interval + u16_l bcn_int; + /// Flags + u32_l flags; + /// Control port Ethertype + u16_l ctrl_port_ethertype; + /// Length of the TIM IE + u8_l tim_len; + /// Index of the VIF for which the AP is started + u8_l vif_idx; + /// Enable APM Embedded + bool apm_emb_enabled; + /// rate set + struct mac_rateset rate_set; + /// Beacon dtim period + uint8_t beacon_period; + /// Qos is supported + uint8_t qos_supported; + /// SSID of the AP + struct mac_ssid ssid; + /// AP Security type + uint8_t ap_sec_type; + /// AP Passphrase + uint8_t phrase[MAX_PSK_PASS_PHRASE_LEN]; + uint8_t phrase_tail[1]; + // Buf for storing IE + uint8_t bcn_buf_len; + uint8_t bcn_buf[64]; +}; + +/// Structure containing the parameters of the @ref APM_START_CFM message. +struct apm_start_cfm +{ + /// Status of the AP starting procedure + u8_l status; + /// Index of the VIF for which the AP is started + u8_l vif_idx; + /// Index of the channel context attached to the VIF + u8_l ch_idx; + /// Index of the STA used for BC/MC traffic + u8_l bcmc_idx; +}; + +/// Structure containing the parameters of the @ref APM_STOP_REQ message. +struct apm_stop_req +{ + /// Index of the VIF for which the AP has to be stopped + u8_l vif_idx; +}; + +/// Structure containing the parameters of the @ref APM_CONF_MAX_STA_REQ message. +struct apm_conf_max_sta_req +{ + /// max Stattion supported + u8_l max_sta_supported; +}; + +struct apm_sta_del_req +{ + /// Index of the AP VIF + u8_l vif_idx; + /// Index of the sta in AP mode + u8_l sta_idx; +}; + +/// Structure containing the parameters of the @ref APM_STOP_REQ message. +struct apm_sta_del_cfm +{ + /// Status of deleting sta procedure + u8_l status; + /// Index of the AP VIF + u8_l vif_idx; + /// Index of the sta in AP mode + u8_l sta_idx; +}; + +/// Structure containing the parameters of the @ref APM_STA_ADD_IND message. +struct apm_sta_add_ind +{ + /// Flags giving additional information about the station + uint32_t flags; + /// Station Mac address + struct mac_addr sta_addr; + /// Index of the VIF for which the sta joined + uint8_t vif_idx; + /// Station index + uint8_t sta_idx; + int8_t rssi; + uint32_t tsflo; + uint32_t tsfhi; + uint8_t data_rate; +}; + +/// Structure containing the parameters of the @ref APM_STA_DEL_IND message. +struct apm_sta_del_ind +{ + /// status of the apm_sta disconnection. + uint16_t status_code; + /// Reason of the apm_sta disconnection. + uint16_t reason_code; + /// Station index + uint8_t sta_idx; +}; + +/// Maximum length of the Mesh ID +#define MESH_MESHID_MAX_LEN (32) +#endif // LMAC_MSG_H_ diff --git a/platforms/bl808_m0/vendor/wifi/include/lmac_types.h b/platforms/bl808_m0/vendor/wifi/include/lmac_types.h new file mode 100644 index 0000000..24301d8 --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/lmac_types.h @@ -0,0 +1,59 @@ + +/** + **************************************************************************************** + * + * @file lmac_types.h + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + + +#ifndef _LMAC_INT_H_ +#define _LMAC_INT_H_ +#include +#include + + +/** + **************************************************************************************** + * @addtogroup CO_INT + * @ingroup COMMON + * @brief Common integer standard types (removes use of stdint) + * + * @{ + **************************************************************************************** + */ + + +/* + * DEFINES + **************************************************************************************** + */ + + +typedef uint8_t u8_l; +typedef int8_t s8_l; +typedef bool bool_l; +typedef uint16_t u16_l; +typedef int16_t s16_l; +typedef uint32_t u32_l; +typedef int32_t s32_l; +typedef uint64_t u64_l; + +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; + +typedef int32_t s32; +typedef int8_t s8; + +typedef uint64_t __le64; +typedef uint32_t __le32; +typedef uint16_t __le16; + +typedef uint32_t __be32; +typedef uint16_t __be16; + +/// @} CO_INT +#endif // _LMAC_INT_H_ diff --git a/platforms/bl808_m0/vendor/wifi/include/lwip/pbuf.h b/platforms/bl808_m0/vendor/wifi/include/lwip/pbuf.h new file mode 100644 index 0000000..a310546 --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/lwip/pbuf.h @@ -0,0 +1,39 @@ +// Minimal lwIP compat shim. +// +// The kept vendor sources (ipc_host.c, bl_defs.h) reference a couple of +// lwIP types as opaque holders. We don't link lwIP -- the D side allocates +// objects whose layout starts with these fields, and passes pointers +// through as `host_id` opaquely. +// +// Anything beyond struct pbuf / struct netif / err_t means a vendor source +// is touching lwIP for real, which means it shouldn't be in our kept set. + +#ifndef VENDOR_COMPAT_LWIP_PBUF_H +#define VENDOR_COMPAT_LWIP_PBUF_H + +#include + +typedef uint8_t u8_t; +typedef uint16_t u16_t; +typedef uint32_t u32_t; +typedef int8_t s8_t; +typedef int16_t s16_t; +typedef int32_t s32_t; +typedef int8_t err_t; + +// Only fields read by ipc_host.c's TX-confirm path. Layout-compatible with +// however the D side wraps a TX buffer. +struct pbuf +{ + struct pbuf *next; + void *payload; + u16_t tot_len; + u16_t len; + u8_t type; + u8_t flags; + u16_t ref; +}; + +struct netif; // pointer-only use in struct bl_vif + +#endif diff --git a/platforms/bl808_m0/vendor/wifi/include/nl80211.h b/platforms/bl808_m0/vendor/wifi/include/nl80211.h new file mode 100644 index 0000000..504cc6c --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/nl80211.h @@ -0,0 +1,153 @@ +#ifndef __NL80211_H__ +#define __NL80211_H__ + +#define NL80211_MAX_NR_CIPHER_SUITES 5 +#define NL80211_MAX_NR_AKM_SUITES 2 + + +/** + **************************************************************************************** + * + * @file nl80211.h + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + +enum nl80211_bss_select_attr { + __NL80211_BSS_SELECT_ATTR_INVALID, + NL80211_BSS_SELECT_ATTR_RSSI, + NL80211_BSS_SELECT_ATTR_BAND_PREF, + NL80211_BSS_SELECT_ATTR_RSSI_ADJUST, + + /* keep last */ + __NL80211_BSS_SELECT_ATTR_AFTER_LAST, + NL80211_BSS_SELECT_ATTR_MAX = __NL80211_BSS_SELECT_ATTR_AFTER_LAST - 1 +}; + +/** + * enum nl80211_auth_type - AuthenticationType + * + * @NL80211_AUTHTYPE_OPEN_SYSTEM: Open System authentication + * @NL80211_AUTHTYPE_SHARED_KEY: Shared Key authentication (WEP only) + * @NL80211_AUTHTYPE_FT: Fast BSS Transition (IEEE 802.11r) + * @NL80211_AUTHTYPE_NETWORK_EAP: Network EAP (some Cisco APs and mainly LEAP) + * @NL80211_AUTHTYPE_SAE: Simultaneous authentication of equals + * @NL80211_AUTHTYPE_FILS_SK: Fast Initial Link Setup shared key + * @NL80211_AUTHTYPE_FILS_SK_PFS: Fast Initial Link Setup shared key with PFS + * @NL80211_AUTHTYPE_FILS_PK: Fast Initial Link Setup public key + * @__NL80211_AUTHTYPE_NUM: internal + * @NL80211_AUTHTYPE_MAX: maximum valid auth algorithm + * @NL80211_AUTHTYPE_AUTOMATIC: determine automatically (if necessary by + * trying multiple times); this is invalid in netlink -- leave out + * the attribute for this on CONNECT commands. + */ +enum nl80211_auth_type { + NL80211_AUTHTYPE_OPEN_SYSTEM, + NL80211_AUTHTYPE_SHARED_KEY, + NL80211_AUTHTYPE_FT, + NL80211_AUTHTYPE_NETWORK_EAP, + NL80211_AUTHTYPE_SAE, + NL80211_AUTHTYPE_FILS_SK, + NL80211_AUTHTYPE_FILS_SK_PFS, + NL80211_AUTHTYPE_FILS_PK, + + /* keep last */ + __NL80211_AUTHTYPE_NUM, + NL80211_AUTHTYPE_MAX = __NL80211_AUTHTYPE_NUM - 1, + NL80211_AUTHTYPE_AUTOMATIC +}; + +/** + * enum nl80211_dfs_state - DFS states for channels + * + * Channel states used by the DFS code. + * + * @NL80211_DFS_USABLE: The channel can be used, but channel availability + * check (CAC) must be performed before using it for AP or IBSS. + * @NL80211_DFS_UNAVAILABLE: A radar has been detected on this channel, it + * is therefore marked as not available. + * @NL80211_DFS_AVAILABLE: The channel has been CAC checked and is available. + */ +enum nl80211_dfs_state { + NL80211_DFS_USABLE, + NL80211_DFS_UNAVAILABLE, + NL80211_DFS_AVAILABLE, +}; + +/** + * enum nl80211_band - Frequency band + * @NL80211_BAND_2GHZ: 2.4 GHz ISM band + * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz) + * @NL80211_BAND_60GHZ: around 60 GHz band (58.32 - 64.80 GHz) + * @NUM_NL80211_BANDS: number of bands, avoid using this in userspace + * since newer kernel versions may support more bands + */ +enum nl80211_band { + NL80211_BAND_2GHZ, + NL80211_BAND_5GHZ, + NL80211_BAND_60GHZ, + + NUM_NL80211_BANDS, +}; + +/** + * enum nl80211_iftype - (virtual) interface types + * + * @NL80211_IFTYPE_UNSPECIFIED: unspecified type, driver decides + * @NL80211_IFTYPE_ADHOC: independent BSS member + * @NL80211_IFTYPE_STATION: managed BSS member + * @NL80211_IFTYPE_AP: access point + * @NL80211_IFTYPE_AP_VLAN: VLAN interface for access points; VLAN interfaces + * are a bit special in that they must always be tied to a pre-existing + * AP type interface. + * @NL80211_IFTYPE_WDS: wireless distribution interface + * @NL80211_IFTYPE_MONITOR: monitor interface receiving all frames + * @NL80211_IFTYPE_MESH_POINT: mesh point + * @NL80211_IFTYPE_P2P_CLIENT: P2P client + * @NL80211_IFTYPE_P2P_GO: P2P group owner + * @NL80211_IFTYPE_P2P_DEVICE: P2P device interface type, this is not a netdev + * and therefore can't be created in the normal ways, use the + * %NL80211_CMD_START_P2P_DEVICE and %NL80211_CMD_STOP_P2P_DEVICE + * commands to create and destroy one + * @NL80211_IF_TYPE_OCB: Outside Context of a BSS + * This mode corresponds to the MIB variable dot11OCBActivated=true + * @NL80211_IFTYPE_NAN: NAN device interface type (not a netdev) + * @NL80211_IFTYPE_MAX: highest interface type number currently defined + * @NUM_NL80211_IFTYPES: number of defined interface types + * + * These values are used with the %NL80211_ATTR_IFTYPE + * to set the type of an interface. + * + */ +enum nl80211_iftype { + NL80211_IFTYPE_UNSPECIFIED, + NL80211_IFTYPE_ADHOC, + NL80211_IFTYPE_STATION, + NL80211_IFTYPE_AP, + NL80211_IFTYPE_AP_VLAN, + NL80211_IFTYPE_WDS, + NL80211_IFTYPE_MONITOR, + NL80211_IFTYPE_MESH_POINT, + NL80211_IFTYPE_P2P_CLIENT, + NL80211_IFTYPE_P2P_GO, + NL80211_IFTYPE_P2P_DEVICE, + NL80211_IFTYPE_OCB, + NL80211_IFTYPE_NAN, + + /* keep last */ + NUM_NL80211_IFTYPES, + NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1 +}; + +/** + * enum nl80211_mfp - Management frame protection state + * @NL80211_MFP_NO: Management frame protection not used + * @NL80211_MFP_REQUIRED: Management frame protection required + */ +enum nl80211_mfp { + NL80211_MFP_NO, + NL80211_MFP_REQUIRED, +}; + +#endif diff --git a/platforms/bl808_m0/vendor/wifi/include/rd.h b/platforms/bl808_m0/vendor/wifi/include/rd.h new file mode 100644 index 0000000..e69de29 diff --git a/platforms/bl808_m0/vendor/wifi/include/reg_access.h b/platforms/bl808_m0/vendor/wifi/include/reg_access.h new file mode 100644 index 0000000..ee89cf8 --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/reg_access.h @@ -0,0 +1,86 @@ + +/** + **************************************************************************************** + * + * @file reg_access.h + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + + +#ifndef REG_ACCESS_H_ +#define REG_ACCESS_H_ + +/***************************************************************************** + * Addresses within RWNX_ADDR_CPU + *****************************************************************************/ +#define RAM_LMAC_FW_ADDR 0x00000000 + +/***************************************************************************** + * Addresses within RWNX_ADDR_SYSTEM + *****************************************************************************/ +/* Shard RAM */ +#define SHARED_RAM_START_ADDR 0x00000000 + +/* IPC registers */ +#define IPC_REG_BASE_ADDR 0x00800000 + +/* System Controller Registers */ +#define SYSCTRL_SIGNATURE_ADDR 0x00900000 +#define SYSCTRL_MISC_CNTL_ADDR 0x009000E0 +#define BOOTROM_ENABLE BIT(4) +#define FPGA_B_RESET BIT(1) +#define SOFT_RESET BIT(0) + +/* MAC platform */ +#define NXMAC_SW_SET_PROFILING_ADDR 0x00B08564 +#define NXMAC_SW_CLEAR_PROFILING_ADDR 0x00B08568 + +/* Modem Status */ +#define MDM_HDMCONFIG_ADDR 0x00C00000 + +/* Modem Config */ +#define MDM_MEMCLKCTRL0_ADDR 0x00C00848 +#define MDM_CLKGATEFCTRL0_ADDR 0x00C00874 + +/* AGC (trident) */ +#define AGC_RWNXAGCCNTL_ADDR 0x00C02060 + +/* LDPC RAM*/ +#define PHY_LDPC_RAM_ADDR 0x00C09000 + +/* FCU (elma )*/ +#define FCU_RWNXFCAGCCNTL_ADDR 0x00C09034 + +/* AGC RAM */ +#define PHY_AGC_UCODE_ADDR 0x00C0A000 + +/* RIU */ +#define RIU_RWNXVERSION_ADDR 0x00C0B000 +#define RIU_RWNXDYNAMICCONFIG_ADDR 0x00C0B008 +#define RIU_AGCMEMBISTSTAT_ADDR 0x00C0B238 +#define RIU_AGCMEMSIGNATURESTAT_ADDR 0x00C0B23C +#define RIU_RWNXAGCCNTL_ADDR 0x00C0B390 + +/* FCU RAM */ +#define PHY_FCU_UCODE_ADDR 0x00C0E000 + +/* */ +#define FPGAB_MPIF_SEL_ADDR 0x00C10030 + +/***************************************************************************** + * Macros for generated register files + *****************************************************************************/ +/* Macros for IPC registers access (used in reg_ipc_app.h) */ +#define REG_IPC_APP_RD(env, INDEX) \ + (*(volatile u32*)((u8*)env + IPC_REG_BASE_ADDR + 4*(INDEX))) + +#define REG_IPC_APP_WR(env, INDEX, value) \ + (*(volatile u32*)((u8*)env + IPC_REG_BASE_ADDR + 4*(INDEX)) = value) + +/* Macro used in reg_mac_core.h */ +#define REG_PL_RD(addr) 0 +#define REG_PL_WR(addr, value) + +#endif /* REG_ACCESS_H_ */ diff --git a/platforms/bl808_m0/vendor/wifi/include/reg_ipc_app.h b/platforms/bl808_m0/vendor/wifi/include/reg_ipc_app.h new file mode 100644 index 0000000..831d27f --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/reg_ipc_app.h @@ -0,0 +1,303 @@ + +/** + **************************************************************************************** + * + * @file reg_ipc_app.h + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + + +#ifndef _REG_IPC_APP_H_ +#define _REG_IPC_APP_H_ + +#include "lmac_types.h" +#include "ipc_compat.h" +#include "reg_access.h" +#include "bl_os_private.h" + +#ifdef CFG_CHIP_BL602 +#define REG_WIFI_REG_BASE 0x44000000 +#endif +#ifdef CFG_CHIP_BL808 +#define REG_WIFI_REG_BASE 0x24000000 +#endif +#ifdef CFG_CHIP_BL606P +#define REG_WIFI_REG_BASE 0x24000000 +#endif + +#define REG_IPC_APP_DECODING_MASK 0x0000007F + +/** + * @brief APP2EMB_TRIGGER register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *  31:00      APP2EMB_TRIGGER   0x0
+ * 
+ */ +#define IPC_APP2EMB_TRIGGER_ADDR 0x12000000 +#define IPC_APP2EMB_TRIGGER_OFFSET 0x00000000 +#define IPC_APP2EMB_TRIGGER_INDEX 0x00000000 +#define IPC_APP2EMB_TRIGGER_RESET 0x00000000 + +#ifndef __INLINE +#define __INLINE inline +#endif + +static __INLINE u32 ipc_app2emb_trigger_get() +{ + return REG_IPC_APP_RD(REG_WIFI_REG_BASE, IPC_APP2EMB_TRIGGER_INDEX); +} + +static __INLINE void ipc_app2emb_trigger_set(u32 value) +{ + REG_IPC_APP_WR(REG_WIFI_REG_BASE, IPC_APP2EMB_TRIGGER_INDEX, value); +} + +// field definitions +#define IPC_APP2EMB_TRIGGER_MASK ((u32)0xFFFFFFFF) +#define IPC_APP2EMB_TRIGGER_LSB 0 +#define IPC_APP2EMB_TRIGGER_WIDTH ((u32)0x00000020) + +#define IPC_APP2EMB_TRIGGER_RST 0x0 + +static __INLINE u32 ipc_app2emb_trigger_getf() +{ + u32 localVal = REG_IPC_APP_RD(REG_WIFI_REG_BASE, IPC_APP2EMB_TRIGGER_INDEX); + ASSERT_ERR((localVal & ~((u32)0xFFFFFFFF)) == 0); + return (localVal >> 0); +} + +static __INLINE void ipc_app2emb_trigger_setf(u32 app2embtrigger) +{ + ASSERT_ERR((((u32)app2embtrigger << 0) & ~((u32)0xFFFFFFFF)) == 0); + REG_IPC_APP_WR(REG_WIFI_REG_BASE, IPC_APP2EMB_TRIGGER_INDEX, (u32)app2embtrigger << 0); +} + +/** + * @brief EMB2APP_RAWSTATUS register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *  31:00    EMB2APP_RAWSTATUS   0x0
+ * 
+ */ +#define IPC_EMB2APP_RAWSTATUS_ADDR 0x12000004 +#define IPC_EMB2APP_RAWSTATUS_OFFSET 0x00000004 +#define IPC_EMB2APP_RAWSTATUS_INDEX 0x00000001 +#define IPC_EMB2APP_RAWSTATUS_RESET 0x00000000 + +static __INLINE u32 ipc_emb2app_rawstatus_get() +{ + return REG_IPC_APP_RD(REG_WIFI_REG_BASE, IPC_EMB2APP_RAWSTATUS_INDEX); +} + +static __INLINE void ipc_emb2app_rawstatus_set(u32 value) +{ + REG_IPC_APP_WR(REG_WIFI_REG_BASE, IPC_EMB2APP_RAWSTATUS_INDEX, value); +} + +// field definitions +#define IPC_EMB2APP_RAWSTATUS_MASK ((u32)0xFFFFFFFF) +#define IPC_EMB2APP_RAWSTATUS_LSB 0 +#define IPC_EMB2APP_RAWSTATUS_WIDTH ((u32)0x00000020) + +#define IPC_EMB2APP_RAWSTATUS_RST 0x0 + +static __INLINE u32 ipc_emb2app_rawstatus_getf() +{ + u32 localVal = REG_IPC_APP_RD(REG_WIFI_REG_BASE, IPC_EMB2APP_RAWSTATUS_INDEX); + ASSERT_ERR((localVal & ~((u32)0xFFFFFFFF)) == 0); + return (localVal >> 0); +} + +/** + * @brief EMB2APP_ACK register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *  31:00          EMB2APP_ACK   0x0
+ * 
+ */ +#define IPC_EMB2APP_ACK_ADDR 0x12000008 +#define IPC_EMB2APP_ACK_OFFSET 0x00000008 +#define IPC_EMB2APP_ACK_INDEX 0x00000002 +#define IPC_EMB2APP_ACK_RESET 0x00000000 + +static __INLINE u32 ipc_emb2app_ack_get() +{ + return REG_IPC_APP_RD(REG_WIFI_REG_BASE, IPC_EMB2APP_ACK_INDEX); +} + +static __INLINE void ipc_emb2app_ack_clear(u32 value) +{ + REG_IPC_APP_WR(REG_WIFI_REG_BASE, IPC_EMB2APP_ACK_INDEX, value); +} + +// field definitions +#define IPC_EMB2APP_ACK_MASK ((u32)0xFFFFFFFF) +#define IPC_EMB2APP_ACK_LSB 0 +#define IPC_EMB2APP_ACK_WIDTH ((u32)0x00000020) + +#define IPC_EMB2APP_ACK_RST 0x0 + +static __INLINE u32 ipc_emb2app_ack_getf() +{ + u32 localVal = REG_IPC_APP_RD(REG_WIFI_REG_BASE, IPC_EMB2APP_ACK_INDEX); + ASSERT_ERR((localVal & ~((u32)0xFFFFFFFF)) == 0); + return (localVal >> 0); +} + +static __INLINE void ipc_emb2app_ack_clearf(u32 emb2appack) +{ + ASSERT_ERR((((u32)emb2appack << 0) & ~((u32)0xFFFFFFFF)) == 0); + REG_IPC_APP_WR(REG_WIFI_REG_BASE, IPC_EMB2APP_ACK_INDEX, (u32)emb2appack << 0); +} + +/** + * @brief EMB2APP_UNMASK_SET register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *  31:00       EMB2APP_UNMASK   0x0
+ * 
+ */ +#define IPC_EMB2APP_UNMASK_SET_ADDR 0x1200000C +#define IPC_EMB2APP_UNMASK_SET_OFFSET 0x0000000C +#define IPC_EMB2APP_UNMASK_SET_INDEX 0x00000003 +#define IPC_EMB2APP_UNMASK_SET_RESET 0x00000000 + +static __INLINE u32 ipc_emb2app_unmask_get() +{ + return REG_IPC_APP_RD(REG_WIFI_REG_BASE, IPC_EMB2APP_UNMASK_SET_INDEX); +} + +static __INLINE void ipc_emb2app_unmask_set(u32 value) +{ + REG_IPC_APP_WR(REG_WIFI_REG_BASE, IPC_EMB2APP_UNMASK_SET_INDEX, value); +} + +// field definitions +#define IPC_EMB2APP_UNMASK_MASK ((u32)0xFFFFFFFF) +#define IPC_EMB2APP_UNMASK_LSB 0 +#define IPC_EMB2APP_UNMASK_WIDTH ((u32)0x00000020) + +#define IPC_EMB2APP_UNMASK_RST 0x0 + +static __INLINE u32 ipc_emb2app_unmask_getf() +{ + u32 localVal = REG_IPC_APP_RD(REG_WIFI_REG_BASE, IPC_EMB2APP_UNMASK_SET_INDEX); + ASSERT_ERR((localVal & ~((u32)0xFFFFFFFF)) == 0); + return (localVal >> 0); +} + +static __INLINE void ipc_emb2app_unmask_setf(u32 emb2appunmask) +{ + ASSERT_ERR((((u32)emb2appunmask << 0) & ~((u32)0xFFFFFFFF)) == 0); + REG_IPC_APP_WR(REG_WIFI_REG_BASE, IPC_EMB2APP_UNMASK_SET_INDEX, (u32)emb2appunmask << 0); +} + +/** + * @brief EMB2APP_UNMASK_CLEAR register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *  31:00       EMB2APP_UNMASK   0x0
+ * 
+ */ +#define IPC_EMB2APP_UNMASK_CLEAR_ADDR 0x12000010 +#define IPC_EMB2APP_UNMASK_CLEAR_OFFSET 0x00000010 +#define IPC_EMB2APP_UNMASK_CLEAR_INDEX 0x00000004 +#define IPC_EMB2APP_UNMASK_CLEAR_RESET 0x00000000 + +static __INLINE void ipc_emb2app_unmask_clear(u32 value) +{ + REG_IPC_APP_WR(REG_WIFI_REG_BASE, IPC_EMB2APP_UNMASK_CLEAR_INDEX, value); +} + +// fields defined in symmetrical set/clear register +static __INLINE void ipc_emb2app_unmask_clearf(u32 emb2appunmask) +{ + ASSERT_ERR((((u32)emb2appunmask << 0) & ~((u32)0xFFFFFFFF)) == 0); + REG_IPC_APP_WR(REG_WIFI_REG_BASE, IPC_EMB2APP_UNMASK_CLEAR_INDEX, (u32)emb2appunmask << 0); +} + +/** + * @brief EMB2APP_STATUS register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *  31:00       EMB2APP_STATUS   0x0
+ * 
+ */ +#define IPC_EMB2APP_STATUS_ADDR 0x1200001C +#define IPC_EMB2APP_STATUS_OFFSET 0x0000001C +#define IPC_EMB2APP_STATUS_INDEX 0x00000007 +#define IPC_EMB2APP_STATUS_RESET 0x00000000 + +static __INLINE u32 ipc_emb2app_status_get() +{ + return REG_IPC_APP_RD(REG_WIFI_REG_BASE, IPC_EMB2APP_STATUS_INDEX); +} + +static __INLINE void ipc_emb2app_status_set(u32 value) +{ + REG_IPC_APP_WR(REG_WIFI_REG_BASE, IPC_EMB2APP_STATUS_INDEX, value); +} + +// field definitions +#define IPC_EMB2APP_STATUS_MASK ((u32)0xFFFFFFFF) +#define IPC_EMB2APP_STATUS_LSB 0 +#define IPC_EMB2APP_STATUS_WIDTH ((u32)0x00000020) + +#define IPC_EMB2APP_STATUS_RST 0x0 + +static __INLINE u32 ipc_emb2app_status_getf() +{ + u32 localVal = REG_IPC_APP_RD(REG_WIFI_REG_BASE, IPC_EMB2APP_STATUS_INDEX); + ASSERT_ERR((localVal & ~((u32)0xFFFFFFFF)) == 0); + return (localVal >> 0); +} + +/** + * @brief APP_SIGNATURE register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   ----------
+ *  31:00        APP_SIGNATURE   0x0
+ * 
+ */ +#define IPC_APP_SIGNATURE_ADDR 0x12000040 +#define IPC_APP_SIGNATURE_OFFSET 0x00000040 +#define IPC_APP_SIGNATURE_INDEX 0x00000010 +#define IPC_APP_SIGNATURE_RESET 0x00000000 + +static __INLINE u32 ipc_app_signature_get() +{ + return REG_IPC_APP_RD(REG_WIFI_REG_BASE, IPC_APP_SIGNATURE_INDEX); +} + +static __INLINE void ipc_app_signature_set(u32 value) +{ + REG_IPC_APP_WR(REG_WIFI_REG_BASE, IPC_APP_SIGNATURE_INDEX, value); +} + +// field definitions +#define IPC_APP_SIGNATURE_MASK ((u32)0xFFFFFFFF) +#define IPC_APP_SIGNATURE_LSB 0 +#define IPC_APP_SIGNATURE_WIDTH ((u32)0x00000020) + +#define IPC_APP_SIGNATURE_RST 0x0 + +static __INLINE u32 ipc_app_signature_getf() +{ + u32 localVal = REG_IPC_APP_RD(REG_WIFI_REG_BASE, IPC_APP_SIGNATURE_INDEX); + ASSERT_ERR((localVal & ~((u32)0xFFFFFFFF)) == 0); + return (localVal >> 0); +} + + +#endif // _REG_IPC_APP_H_ + diff --git a/platforms/bl808_m0/vendor/wifi/include/utils_list.h b/platforms/bl808_m0/vendor/wifi/include/utils_list.h new file mode 100644 index 0000000..e33bbe9 --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/utils_list.h @@ -0,0 +1,621 @@ + +/* + * Copyright (c) 2016-2022 Bouffalolab. + * + * This file is part of + * *** Bouffalolab Software Dev Kit *** + * (see www.bouffalolab.com). + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef _UTILS_LIST_H_ +#define _UTILS_LIST_H_ + +#include + +struct utils_list_hdr +{ + struct utils_list_hdr *next; +}; + +struct utils_list +{ + /// pointer to first element of the list + struct utils_list_hdr *first; + /// pointer to the last element + struct utils_list_hdr *last; +}; + + +/* + * FUNCTION DECLARATIONS + **************************************************************************************** + */ +/** + **************************************************************************************** + * @brief Initialize a list to defaults values. + * @param[in] list Pointer to the list structure. + **************************************************************************************** + */ +void utils_list_init(struct utils_list *list); + +/** + **************************************************************************************** + * @brief Initialize a pool to default values, and initialize the relative free list. + * + * @param[in] list Pointer to the list structure + * @param[in] pool Pointer to the pool to be initialized + * @param[in] elmt_size Size of one element of the pool + * @param[in] elmt_cnt Nb of elements available in the pool + * @param[in] default_value Pointer to the default value of each element (may be NULL) + **************************************************************************************** + */ +void utils_list_pool_init(struct utils_list *list, void *pool, size_t elmt_size, unsigned int elmt_cnt, void *default_value); + +/** + **************************************************************************************** + * @brief Add an element as last on the list. + * + * @param[in] list Pointer to the list structure + * @param[in] list_hdr Pointer to the header to add at the end of the list + **************************************************************************************** + */ +void utils_list_push_back(struct utils_list *list, + struct utils_list_hdr *list_hdr); + +/** + **************************************************************************************** + * @brief Add an element as first on the list. + * + * @param[in] list Pointer to the list structure + * @param[in] list_hdr Pointer to the header to add at the beginning of the list + **************************************************************************************** + */ +void utils_list_push_front(struct utils_list *list, struct utils_list_hdr *list_hdr); +/** + **************************************************************************************** + * @brief Extract the first element of the list. + * + * @param[in] list Pointer to the list structure + * + * @return The pointer to the element extracted, and NULL if the list is empty. + **************************************************************************************** + */ +struct utils_list_hdr *utils_list_pop_front(struct utils_list *list); + +/** + **************************************************************************************** + * @brief Search for a given element in the list, and extract it if found. + * + * @param[in] list Pointer to the list structure + * @param[in] list_hdr Pointer to the searched element + * + * @return CO_EMPTY if the list is empty, CO_FAIL if the element not found in the list, + * CO_OK else. + **************************************************************************************** + */ +void utils_list_extract(struct utils_list *list, struct utils_list_hdr *list_hdr); + +/** + **************************************************************************************** + * @brief Searched a given element in the list. + * + * @param[in] list Pointer to the list structure + * @param[in] list_hdr Pointer to the searched element + * + * @return true if the element is found in the list, false otherwise + **************************************************************************************** + */ +int utils_list_find(struct utils_list *list, struct utils_list_hdr *list_hdr); + +/** + **************************************************************************************** + * @brief Insert an element in a sorted list. + * + * This primitive use a comparison function from the parameter list to select where the + * element must be inserted. + * + * @param[in] list Pointer to the list. + * @param[in] element Pointer to the element to insert. + * @param[in] cmp Comparison function (return true if first element has to be inserted + * before the second one). + * + * @return Pointer to the element found and removed (NULL otherwise). + **************************************************************************************** + */ +void utils_list_insert(struct utils_list * const list, struct utils_list_hdr * const element, + int (*cmp)(struct utils_list_hdr const *elementA, + struct utils_list_hdr const *elementB)); + +/** + **************************************************************************************** + * @brief Insert an element in a sorted list after the provided element. + * + * This primitive use a comparison function from the parameter list to select where the + * element must be inserted. + * + * @param[in] list Pointer to the list. + * @param[in] prev_element Pointer to the element to find in the list + * @param[in] element Pointer to the element to insert. + * + * If prev_element is not found, the provided element is not inserted + **************************************************************************************** + */ +void utils_list_insert_after(struct utils_list * const list, struct utils_list_hdr * const prev_element, struct utils_list_hdr * const element); + +/** + **************************************************************************************** + * @brief Insert an element in a sorted list before the provided element. + * + * This primitive use a comparison function from the parameter list to select where the + * element must be inserted. + * + * @param[in] list Pointer to the list. + * @param[in] next_element Pointer to the element to find in the list + * @param[in] element Pointer to the element to insert. + * + * If next_element is not found, the provided element is not inserted + **************************************************************************************** + */ +void utils_list_insert_before(struct utils_list * const list, struct utils_list_hdr * const next_element, struct utils_list_hdr * const element); + +/** + **************************************************************************************** + * @brief Concatenate two lists. + * The resulting list is the list passed as the first parameter. The second list is + * emptied. + * + * @param[in] list1 First list (will get the result of the concatenation) + * @param[in] list2 Second list (will be emptied after the concatenation) + **************************************************************************************** + */ +void utils_list_concat(struct utils_list *list1, struct utils_list *list2); + +/** + **************************************************************************************** + * @brief Remove the element in the list after the provided element. + * + * This primitive removes an element in the list. It is assume that element is part of + * the list. + * + * @param[in] list Pointer to the list. + * @param[in] prev_element Pointer to the previous element. + * NULL if @p element is the first element in the list + * @param[in] element Pointer to the element to remove. + * + **************************************************************************************** + */ +void utils_list_remove(struct utils_list *list, struct utils_list_hdr *prev_element, struct utils_list_hdr *element); +/** + **************************************************************************************** + * @brief Test if the list is empty. + * + * @param[in] list Pointer to the list structure. + * + * @return true if the list is empty, false else otherwise. + **************************************************************************************** + */ +static inline int utils_list_is_empty(const struct utils_list *const list) +{ + return (NULL == list->first); +} + +/** + **************************************************************************************** + * @brief Return the number of element of the list. + * + * @param[in] list Pointer to the list structure. + * + * @return The number of elements in the list. + **************************************************************************************** + */ +unsigned int utils_list_cnt(const struct utils_list *const list); + +/** + **************************************************************************************** + * @brief Pick the first element from the list without removing it. + * + * @param[in] list Pointer to the list structure. + * + * @return First element address. Returns NULL pointer if the list is empty. + **************************************************************************************** + */ +static inline struct utils_list_hdr *utils_list_pick(const struct utils_list *const list) +{ + return list->first; +} + +static inline struct utils_list_hdr *utils_list_pick_last(const struct utils_list *const list) +{ + return list->last; +} + +static inline struct utils_list_hdr *utils_list_next(const struct utils_list_hdr *const list_hdr) +{ + return list_hdr->next; +} + + +/* + * Get offset of a member variable. + * + * @param[in] type the type of the struct this is embedded in. + * @param[in] member the name of the variable within the struct. + */ +#define utils_offsetof(type, member) ((size_t)&(((type *)0)->member)) + +/* + * Get the struct for this entry. + * + * @param[in] ptr the list head to take the element from. + * @param[in] type the type of the struct this is embedded in. + * @param[in] member the name of the variable within the struct. + */ +#define utils_container_of(ptr, type, member) \ + ((type *) ((char *) (ptr) - utils_offsetof(type, member))) + +/* for double link list */ +typedef struct utils_dlist_s { + struct utils_dlist_s *prev; + struct utils_dlist_s *next; +} utils_dlist_t; + +static inline void __utils_dlist_add(utils_dlist_t *node, utils_dlist_t *prev, utils_dlist_t *next) +{ + node->next = next; + node->prev = prev; + + prev->next = node; + next->prev = node; +} + +/* + * Get the struct for this entry. + * + * @param[in] addr the list head to take the element from. + * @param[in] type the type of the struct this is embedded in. + * @param[in] member the name of the utils_dlist_t within the struct. + */ +#define utils_dlist_entry(addr, type, member) \ + ((type *)((long)addr - utils_offsetof(type, member))) + + +static inline void utils_dlist_add(utils_dlist_t *node, utils_dlist_t *queue) +{ + __utils_dlist_add(node, queue, queue->next); +} + +static inline void utils_dlist_add_tail(utils_dlist_t *node, utils_dlist_t *queue) +{ + __utils_dlist_add(node, queue->prev, queue); +} + +static inline void utils_dlist_del(utils_dlist_t *node) +{ + utils_dlist_t *prev = node->prev; + utils_dlist_t *next = node->next; + + prev->next = next; + next->prev = prev; +} + +static inline void utils_dlist_init(utils_dlist_t *node) +{ + node->next = node->prev = node; +} + +static inline void INIT_UTILS_DLIST_HEAD(utils_dlist_t *list) +{ + list->next = list; + list->prev = list; +} + +static inline int utils_dlist_empty(const utils_dlist_t *head) +{ + return head->next == head; +} + +/* + * Initialise the list. + * + * @param[in] list the list to be inited. + */ +#define UTILS_DLIST_INIT(list) {&(list), &(list)} + +/* + * Get the first element from a list + * + * @param[in] ptr the list head to take the element from. + * @param[in] type the type of the struct this is embedded in. + * @param[in] member the name of the utils_dlist_t within the struct. + */ +#define utils_dlist_first_entry(ptr, type, member) \ + utils_dlist_entry((ptr)->next, type, member) + +/* + * Iterate over a list. + * + * @param[in] pos the &struct utils_dlist_t to use as a loop cursor. + * @param[in] head he head for your list. + */ +#define utils_dlist_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); pos = pos->next) + +/* + * Iterate over a list safe against removal of list entry. + * + * @param[in] pos the &struct utils_dlist_t to use as a loop cursor. + * @param[in] n another &struct utils_dlist_t to use as temporary storage. + * @param[in] head he head for your list. + */ +#define utils_dlist_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + +/* + * Iterate over list of given type. + * + * @param[in] queue he head for your list. + * @param[in] node the &struct utils_dlist_t to use as a loop cursor. + * @param[in] type the type of the struct this is embedded in. + * @param[in] member the name of the utils_dlist_t within the struct. + */ +#define utils_dlist_for_each_entry(queue, node, type, member) \ + for (node = utils_container_of((queue)->next, type, member); \ + &node->member != (queue); \ + node = utils_container_of(node->member.next, type, member)) + +/* + * Iterate over list of given type safe against removal of list entry. + * + * @param[in] queue the head for your list. + * @param[in] n the type * to use as a temp. + * @param[in] node the type * to use as a loop cursor. + * @param[in] type the type of the struct this is embedded in. + * @param[in] member the name of the utils_dlist_t within the struct. + */ +#define utils_dlist_for_each_entry_safe(queue, n, node, type, member) \ + for (node = utils_container_of((queue)->next, type, member), \ + n = (queue)->next ? (queue)->next->next : NULL; \ + &node->member != (queue); \ + node = utils_container_of(n, type, member), n = n ? n->next : NULL) + +/* + * Get the struct for this entry. + * @param[in] ptr the list head to take the element from. + * @param[in] type the type of the struct this is embedded in. + * @param[in] member the name of the variable within the struct. + */ +#define utils_list_entry(ptr, type, member) \ + utils_container_of(ptr, type, member) + + +/* + * Iterate backwards over list of given type. + * + * @param[in] pos the type * to use as a loop cursor. + * @param[in] head he head for your list. + * @param[in] member the name of the utils_dlist_t within the struct. + * @param[in] type the type of the struct this is embedded in. + */ +#define utils_dlist_for_each_entry_reverse(pos, head, member, type) \ + for (pos = utils_list_entry((head)->prev, type, member); \ + &pos->member != (head); \ + pos = utils_list_entry(pos->member.prev, type, member)) + + +/* + * Get the list length. + * + * @param[in] queue the head for your list. + */ +static inline int utils_dlist_entry_number(utils_dlist_t *queue) +{ + int num; + utils_dlist_t *cur = queue; + for (num=0;cur->next != queue;cur=cur->next, num++) + ; + + return num; +} + + + +/* + * Initialise the list. + * + * @param[in] name the list to be initialized. + */ +#define UTILS_DLIST_HEAD_INIT(name) { &(name), &(name) } + +/* + * Initialise the list. + * + * @param[in] name the list to be initialized. + */ +#define UTILS_DLIST_HEAD(name) \ + utils_dlist_t name = UTILS_DLIST_HEAD_INIT(name) + +/* for single link list */ +typedef struct utils_slist_s { + struct utils_slist_s *next; +} utils_slist_t; + +static inline void utils_slist_add(utils_slist_t *node, utils_slist_t *head) +{ + node->next = head->next; + head->next = node; +} + +static inline void utils_slist_add_tail(utils_slist_t *node, utils_slist_t *head) +{ + while (head->next) { + head = head->next; + } + + utils_slist_add(node, head); +} + +static inline void utils_slist_append(utils_slist_t *l, utils_slist_t *n) +{ + utils_slist_t *node; + + node = l; + while (node->next) node = node->next; + + /* append the node to the tail */ + node->next = n; + n->next = NULL; +} + +static inline void utils_slist_del(utils_slist_t *node, utils_slist_t *head) +{ + while (head->next) { + if (head->next == node) { + head->next = node->next; + break; + } + + head = head->next; + } +} + +static inline int utils_slist_empty(const utils_slist_t *head) +{ + return !head->next; +} + +static inline void utils_slist_init(utils_slist_t *head) +{ + head->next = 0; +} + +static inline utils_slist_t* utils_slist_first(utils_slist_t *l) +{ + return l->next; +} + +static inline utils_slist_t* utils_slist_tail(utils_slist_t *l) +{ + while (l->next) l = l->next; + + return l; +} + +static inline utils_slist_t* utils_slist_next(utils_slist_t *l) +{ + return l->next; +} + +/* +* Iterate over list of given type. +* +* @param[in] queue he head for your list. +* @param[in] node the type * to use as a loop cursor. +* @param[in] type the type of the struct this is embedded in. +* @param[in] member the name of the utils_slist_t within the struct. +*/ +#define utils_slist_for_each_entry(queue, node, type, member) \ + for (node = utils_container_of((queue)->next, type, member); \ + &node->member; \ + node = utils_container_of(node->member.next, type, member)) + +/* + * Iterate over list of given type safe against removal of list entry. + * + * @param[in] queue the head for your list. + * @param[in] tmp the type * to use as a temp. + * @param[in] node the type * to use as a loop cursor. + * @param[in] type the type of the struct this is embedded in. + * @param[in] member the name of the utils_slist_t within the struct. + */ +#define utils_slist_for_each_entry_safe(queue, tmp, node, type, member) \ + for (node = utils_container_of((queue)->next, type, member), \ + tmp = (queue)->next ? (queue)->next->next : NULL; \ + &node->member; \ + node = utils_container_of(tmp, type, member), tmp = tmp ? tmp->next : tmp) + +/* + * Initialise the list. + * + * @param[in] name the list to be initialized. + */ +#define UTILS_SLIST_HEAD_INIT(name) {0} + +/* + * Initialise the list. + * + * @param[in] name the list to be initialized. + */ +#define UTILS_SLIST_HEAD(name) \ + utils_slist_t name = UTILS_SLIST_HEAD_INIT(name) + +/* + * Get the struct for this entry. + * @param[in] addr the list head to take the element from. + * @param[in] type the type of the struct this is embedded in. + * @param[in] member the name of the utils_slist_t within the struct. + */ +#define utils_slist_entry(addr, type, member) ( \ + addr ? (type *)((long)addr - utils_offsetof(type, member)) : (type *)addr \ +) + +/* +* Get the first element from a list. +* +* @param[in] ptr the list head to take the element from. +* @param[in] type the type of the struct this is embedded in. +* @param[in] member the name of the utils_slist_t within the struct. +*/ +#define utils_slist_first_entry(ptr, type, member) \ + utils_slist_entry(utils_slist_next(ptr), type, member) + + +/* +* Get the last element from a list. +* +* @param[in] ptr the list head to take the element from. +* @param[in] type the type of the struct this is embedded in. +* @param[in] member the name of the utils_slist_t within the struct. +*/ +#define utils_slist_tail_entry(ptr, type, member) \ + utils_slist_entry(utils_slist_tail(ptr), type, member) + + +/* + * Get the list length. + * + * @param[in] queue the head for your list. + */ +static inline int utils_slist_entry_number(utils_slist_t *queue) +{ + int num; + utils_slist_t *cur = queue; + for (num=0;cur->next;cur=cur->next, num++) + ; + + return num; +} +#endif diff --git a/platforms/bl808_m0/vendor/wifi/include/utils_tlv_bl.h b/platforms/bl808_m0/vendor/wifi/include/utils_tlv_bl.h new file mode 100644 index 0000000..8ee870f --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/include/utils_tlv_bl.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2016-2022 Bouffalolab. + * + * This file is part of + * *** Bouffalolab Software Dev Kit *** + * (see www.bouffalolab.com). + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __UTILS_TLV_BL_H__ +#define __UTILS_TLV_BL_H__ +#include +#include + +#define CFG_ELEMENT_TYPE_SIZE_BOOLEAN (4) +#define CFG_ELEMENT_TYPE_SIZE_UINT32 (4) +#define UTILS_TLV_BL_ERROR_CODE_BUF_TOO_SMALL (-1) +#define UTILS_TLV_BL_ERROR_CODE_UNKOWN (-2) +// Wi-Fi CFG API +enum CFG_ELEMENT_TYPE { + CFG_ELEMENT_TYPE_UNKNOWN, + CFG_ELEMENT_TYPE_BOOLEAN, + CFG_ELEMENT_TYPE_SINT8, + CFG_ELEMENT_TYPE_UINT8, + CFG_ELEMENT_TYPE_SINT16, + CFG_ELEMENT_TYPE_UINT16, + CFG_ELEMENT_TYPE_SINT32, + CFG_ELEMENT_TYPE_UINT32, + CFG_ELEMENT_TYPE_STRING, +}; + +enum CFG_ELEMENT_TYPE_OPS +{ + CFG_ELEMENT_TYPE_OPS_SET, + CFG_ELEMENT_TYPE_OPS_GET, + CFG_ELEMENT_TYPE_OPS_RESET, + CFG_ELEMENT_TYPE_OPS_DUMP_DEBUG, + CFG_ELEMENT_TYPE_OPS_UNKNOWN, +}; + +int utils_tlv_bl_pack_bool(uint32_t *buf, int buf_sz, bool val); +int utils_tlv_bl_pack_uint8(uint32_t *buf, int buf_sz, uint8_t val); +int utils_tlv_bl_pack_int8(uint32_t *buf, int buf_sz, int8_t val); +int utils_tlv_bl_pack_uint16(uint32_t *buf, int buf_sz, uint16_t val); +int utils_tlv_bl_pack_int16(uint32_t *buf, int buf_sz, int16_t val); +int utils_tlv_bl_pack_uint32(uint32_t *buf, int buf_sz, uint32_t val); +int utils_tlv_bl_pack_int32(uint32_t *buf, int buf_sz, int32_t val); +int utils_tlv_bl_pack_string(uint32_t *buf, int buf_sz, const char *str); +int utils_tlv_bl_pack_auto(uint32_t *buf, int buf_sz, uint16_t type, void *arg1); + +int utils_tlv_bl_unpack_bool(uint32_t *buf, int buf_sz, bool *val); +int utils_tlv_bl_unpack_uint8(uint32_t *buf, int buf_sz, uint8_t *val); +int utils_tlv_bl_unpack_int8(uint32_t *buf, int buf_sz, int8_t *val); +int utils_tlv_bl_unpack_uint16(uint32_t *buf, int buf_sz, uint16_t *val); +int utils_tlv_bl_unpack_int16(uint32_t *buf, int buf_sz, int16_t *val); +int utils_tlv_bl_unpack_uint32(uint32_t *buf, int buf_sz, uint32_t *val); +int utils_tlv_bl_unpack_int32(uint32_t *buf, int buf_sz, int32_t *val); +int utils_tlv_bl_unpack_string(uint32_t *buf, int buf_sz, char *str, int size); +int utils_tlv_bl_unpack_auto(uint32_t *buf, int buf_sz, uint16_t type, void *arg1); +#endif diff --git a/platforms/bl808_m0/vendor/wifi/lib/libbl606p_phyrf.a b/platforms/bl808_m0/vendor/wifi/lib/libbl606p_phyrf.a new file mode 100644 index 0000000..3ff691a Binary files /dev/null and b/platforms/bl808_m0/vendor/wifi/lib/libbl606p_phyrf.a differ diff --git a/platforms/bl808_m0/vendor/wifi/lib/libwifi.a b/platforms/bl808_m0/vendor/wifi/lib/libwifi.a new file mode 100644 index 0000000..4fb9a4e Binary files /dev/null and b/platforms/bl808_m0/vendor/wifi/lib/libwifi.a differ diff --git a/platforms/bl808_m0/vendor/wifi/src/bl_cmds.c b/platforms/bl808_m0/vendor/wifi/src/bl_cmds.c new file mode 100644 index 0000000..5d8a494 --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/src/bl_cmds.c @@ -0,0 +1,278 @@ +#include +#include + +#include +#include "bl_cmds.h" +#include "bl_utils.h" +#include "bl_strs.h" + +// (Vendor had #undef'd bl_os_log_printf to silence cmd-path chatter; re-enabled +// here for bring-up so we can see push/wait/CFM events.) + +static void cmd_dump(const struct bl_cmd *cmd) +{ + // RWNX_ID2STR -> bl_id2str string tables aren't in our kept vendor sources; + // drop the rich dump and just print the numeric fields. + bl_os_log_debug("cmd_dump: tkn=%d flags=%04x result=%d id=%d reqid=%d\n", + cmd->tkn, cmd->flags, cmd->result, cmd->id, cmd->reqid); +} + +static void cmd_complete(struct bl_cmd_mgr *cmd_mgr, struct bl_cmd *cmd) +{ + bl_os_log_debug("[CMDS] CMD complete: %p\r\n", cmd); + + cmd_mgr->queue_sz--; + list_del(&cmd->list); + cmd->flags |= RWNX_CMD_FLAG_DONE; + if (cmd->flags & RWNX_CMD_FLAG_NONBLOCK) { + bl_os_log_debug("[CMDS] NONBLOCK CMD, free now %p\r\n", cmd); + bl_os_free(cmd); + } else { + if (RWNX_CMD_WAIT_COMPLETE(cmd->flags)) { + bl_os_log_debug("[CMDS] BLOCK EVENT is ready, complete now %p\r\n", cmd); + cmd->result = 0; + bl_os_event_group_send(cmd->complete, 0x1); + } + } +} + +static int cmd_mgr_queue(struct bl_cmd_mgr *cmd_mgr, struct bl_cmd *cmd) +{ + struct bl_hw *bl_hw = container_of(cmd_mgr, struct bl_hw, cmd_mgr); + struct bl_cmd *last; + bool defer_push = false; + uint32_t e; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + bl_os_mutex_lock(cmd_mgr->lock); + + if (cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) { + bl_os_log_debug("cmd queue crashed\r\n"); + cmd->result = EPIPE; + RWNX_DBG(RWNX_FN_LEAVE_STR); + bl_os_mutex_unlock(cmd_mgr->lock); + return -EPIPE; + } + + if (!list_empty(&cmd_mgr->cmds)) { + if (cmd_mgr->queue_sz == cmd_mgr->max_queue_sz) { + bl_os_log_debug("Too many cmds (%d) already queued\r\n", + cmd_mgr->max_queue_sz); + cmd->result = ENOMEM; + RWNX_DBG(RWNX_FN_LEAVE_STR); + bl_os_mutex_unlock(cmd_mgr->lock); + return -ENOMEM; + } + last = list_entry(cmd_mgr->cmds.prev, struct bl_cmd, list); + //FIXME comment out the following code block, since it is buggy +#if 1 + if (last->flags & (RWNX_CMD_FLAG_WAIT_ACK | RWNX_CMD_FLAG_WAIT_PUSH)) { +#if 0 // queue even NONBLOCK command. + if (cmd->flags & RWNX_CMD_FLAG_NONBLOCK) { + printk(KERN_CRIT"cmd queue busy\n"); + cmd->result = -EBUSY; + spin_unlock_bh(&cmd_mgr->lock); + RWNX_DBG(RWNX_FN_LEAVE_STR); + return -EBUSY; + } +#endif + cmd->flags |= RWNX_CMD_FLAG_WAIT_PUSH; + defer_push = true; + } +#endif + } + + cmd->flags |= RWNX_CMD_FLAG_WAIT_ACK; + if (cmd->flags & RWNX_CMD_FLAG_REQ_CFM) + cmd->flags |= RWNX_CMD_FLAG_WAIT_CFM; + + cmd->tkn = cmd_mgr->next_tkn++; + cmd->result = EINTR; + + if (!(cmd->flags & RWNX_CMD_FLAG_NONBLOCK)) { + cmd->complete = bl_os_event_group_create(); + } + + + list_add_tail(&cmd->list, &cmd_mgr->cmds); + cmd_mgr->queue_sz++; + bl_os_mutex_unlock(cmd_mgr->lock); + + if (!defer_push) { + bl_os_log_debug("pushing CMD, param_len is %d...\r\n", cmd->a2e_msg->param_len); + ipc_host_msg_push(bl_hw->ipc_env, cmd, sizeof(struct lmac_msg) + cmd->a2e_msg->param_len); + bl_os_free(cmd->a2e_msg); + } + + if (!(cmd->flags & RWNX_CMD_FLAG_NONBLOCK)) { + bl_os_log_debug("Waiting ACK...\r\n"); + e = bl_os_event_group_wait(cmd->complete, + (1 << 0), + BL_OS_TRUE, + BL_OS_FALSE, + BL_OS_WAITING_FOREVER); + if (e & (1 << 0)) { + bl_os_log_debug("cmd OK\r\n"); + } else { + bl_os_log_debug("cmd timed-out\r\n"); + cmd_dump(cmd); + bl_os_mutex_lock(cmd_mgr->lock); + cmd_mgr->state = RWNX_CMD_MGR_STATE_CRASHED; + if (!(cmd->flags & RWNX_CMD_FLAG_DONE)) { + cmd->result = ETIMEDOUT; + cmd_complete(cmd_mgr, cmd); + } + bl_os_mutex_unlock(cmd_mgr->lock); + } + bl_os_event_group_delete(cmd->complete);//detach after block read + } else { + bl_os_log_debug("No need to wait for CMD\r\n"); + cmd->result = 0; + } + RWNX_DBG(RWNX_FN_LEAVE_STR); + return 0; +} + +static void cmd_mgr_print(struct bl_cmd_mgr *cmd_mgr) +{ + struct bl_cmd *cur; + + bl_os_mutex_lock(cmd_mgr->lock); + RWNX_DBG("q_sz/max: %2d / %2d - next tkn: %d\r\n", + cmd_mgr->queue_sz, cmd_mgr->max_queue_sz, + cmd_mgr->next_tkn); + list_for_each_entry(cur, &cmd_mgr->cmds, list) { + cmd_dump(cur); + } + + bl_os_mutex_unlock(cmd_mgr->lock); +} + +static void cmd_mgr_drain(struct bl_cmd_mgr *cmd_mgr) +{ + struct bl_cmd *cur, *nxt; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + bl_os_mutex_lock(cmd_mgr->lock); + list_for_each_entry_safe(cur, nxt, &cmd_mgr->cmds, list) { + list_del(&cur->list); + cmd_mgr->queue_sz--; + if (!(cur->flags & RWNX_CMD_FLAG_NONBLOCK)) { + bl_os_event_group_send(cur->complete, 0x1); + } + } + bl_os_mutex_unlock(cmd_mgr->lock); +} + +static int cmd_mgr_llind(struct bl_cmd_mgr *cmd_mgr, struct bl_cmd *cmd) +{ + struct bl_cmd *cur, *acked = NULL, *next = NULL; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + bl_os_mutex_lock(cmd_mgr->lock); + list_for_each_entry(cur, &cmd_mgr->cmds, list) { + bl_os_log_debug("Search cmds list cmd %p vs cur %p...\r\n", cmd, cur); + if (!acked) { + bl_os_log_debug("Finding acked...\r\n"); + if (cur->tkn == cmd->tkn) { + bl_os_log_debug("Found acked\r\n"); + if (WARN_ON_ONCE(cur != cmd)) { + cmd_dump(cmd); + } + acked = cur; + continue; + } + } + if (cur->flags & RWNX_CMD_FLAG_WAIT_PUSH) { + bl_os_log_debug("Found WAIT_PUSH\r\n"); + next = cur; + break; + } + } + if (!acked) { + bl_os_log_debug("Error: acked cmd not found\r\n"); + } else { + cmd->flags &= ~RWNX_CMD_FLAG_WAIT_ACK; + if (RWNX_CMD_WAIT_COMPLETE(cmd->flags)) { + bl_os_log_debug("[BUG] should cmd complete allowed here?\r\n");//FIXME attention + cmd_complete(cmd_mgr, cmd);// XXX potential buggy + } else { + bl_os_log_debug("[IPC] Wait Until ACKED for cmd %p, flags %08X\r\n", cmd, cmd->flags); + } + } + if (next) { + struct bl_hw *bl_hw = container_of(cmd_mgr, struct bl_hw, cmd_mgr); + next->flags &= ~RWNX_CMD_FLAG_WAIT_PUSH; + bl_os_log_debug("Pushing new CMD in llind...\r\n"); + ipc_host_msg_push(bl_hw->ipc_env, next, + sizeof(struct lmac_msg) + next->a2e_msg->param_len); + bl_os_free(next->a2e_msg); + } + bl_os_mutex_unlock(cmd_mgr->lock); + + return 0; +} + +static int cmd_mgr_msgind(struct bl_cmd_mgr *cmd_mgr, struct ipc_e2a_msg *msg, msg_cb_fct cb) +{ + struct bl_hw *bl_hw = container_of(cmd_mgr, struct bl_hw, cmd_mgr); + struct bl_cmd *cmd; + bool found = false; + + /* The LMAC blob writes msg->id as 32 bits but only the low 16 bits hold + * the semantic message id; the high bits look like an auxiliary + * task/version tag. Probe shows id = 0x00090001 for MM_RESET_CFM (low + * 16 = 0x0001 matches MM_RESET_CFM = 1, high 16 = 0x0009). Mask both + * sides to 16 bits before comparison. */ + uint16_t msg_id_low = (uint16_t)(msg->id & 0xFFFF); + + bl_os_mutex_lock(cmd_mgr->lock); + list_for_each_entry(cmd, &cmd_mgr->cmds, list) { + if ((uint16_t)(cmd->reqid & 0xFFFF) == msg_id_low && + (cmd->flags & RWNX_CMD_FLAG_WAIT_CFM)) { + bl_os_log_debug("[IPC] Found cb %p for cmd %p , msg id %08X\r\n", cb, cmd, msg->id); + if (!cb || (cb && !cb(bl_hw, cmd, msg))) { + bl_os_log_debug("[IPC] NOT handed by static handler, cb %p\r\n", cb); + found = true; + cmd->flags &= ~RWNX_CMD_FLAG_WAIT_CFM; + + if (cmd->e2a_msg && msg->param_len) { + bl_os_log_debug("[IPC] copy back RSP to cmd %p, e2a_msg %p, len %d\r\n", + cmd, cmd->e2a_msg, msg->param_len); + memcpy(cmd->e2a_msg, &msg->param, msg->param_len); + } + + if (RWNX_CMD_WAIT_COMPLETE(cmd->flags)) { + cmd_complete(cmd_mgr, cmd); + } + + break; + } else { + bl_os_log_debug("[IPC] MSG is handled by static handler\r\n"); + } + } + } + bl_os_mutex_unlock(cmd_mgr->lock); + + if (!found && cb) + cb(bl_hw, NULL, msg); + + return 0; +} + +void bl_cmd_mgr_init(struct bl_cmd_mgr *cmd_mgr) +{ + INIT_LIST_HEAD(&cmd_mgr->cmds); + cmd_mgr->lock = bl_os_mutex_create(); + ASSERT_ERR(NULL != cmd_mgr->lock); + + cmd_mgr->max_queue_sz = RWNX_CMD_MAX_QUEUED; + cmd_mgr->queue = &cmd_mgr_queue; + cmd_mgr->print = &cmd_mgr_print; + cmd_mgr->drain = &cmd_mgr_drain; + cmd_mgr->llind = &cmd_mgr_llind; + cmd_mgr->msgind = &cmd_mgr_msgind; +} diff --git a/platforms/bl808_m0/vendor/wifi/src/bl_globals.c b/platforms/bl808_m0/vendor/wifi/src/bl_globals.c new file mode 100644 index 0000000..a7fd982 --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/src/bl_globals.c @@ -0,0 +1,18 @@ +// Glue file -- the single definition for vendor globals that were +// originally headed-defined and relied on pre-gcc-10 -fcommon behaviour. +// +// See README.md "Patches applied to upstream" for the full list. + +#include "lmac_msg.h" +#include "bl_tx.h" +#include + +// Header had a bare tentative def; modern gcc refuses to make a var with +// FAM into COMMON. Single definition lives here. +struct cfg_start_req_u_tlv_s cfg_start_req_u_tlv_t; + +// Originally in bl_tx.c (dropped -- TX path is implemented in D). These +// symbols are referenced from the bits of ipc_host.c we keep. +struct utils_list tx_list_bl; +int internel_cal_size_tx_desc; // informational (printed at IPC init) +int internel_cal_size_tx_hdr; diff --git a/platforms/bl808_m0/vendor/wifi/src/bl_irqs.c b/platforms/bl808_m0/vendor/wifi/src/bl_irqs.c new file mode 100644 index 0000000..910ed9e --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/src/bl_irqs.c @@ -0,0 +1,89 @@ + +/** + **************************************************************************************** + * + * @file bl_irqs.c + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + +#include "bl_defs.h" +#include "bl_irqs.h" +#include "ipc_host.h" +#include "bl_os_private.h" + +#define REG_SW_SET_PROFILING(env, value) do{ }while(0) +#define REG_SW_CLEAR_PROFILING(env, value) do{ }while(0) +#define REG_SW_CLEAR_HOSTBUF_IDX_PROFILING(env) do{ }while(0) +#define REG_SW_SET_HOSTBUF_IDX_PROFILING(env, val) do{ }while(0) +#define BIT_0 ( 1 << 0 ) +#define BIT_1 ( 1 << 1 ) + +static uint32_t time_irq_start __attribute__((unused)), time_irq_end __attribute__((unused)); + +static struct bl_hw *wifi_hw; +#ifdef RWNX_IRQS_DEBUG_ENABLE +#define RWNX_IRQS_DEBUG(...) \ +{ \ + bl_os_printf(__VA_ARGS__); \ +} +#else +#define RWNX_IRQS_DEBUG(...) do {} while(0) +#endif + +int bl_irqs_init(struct bl_hw *bl_hw) +{ + wifi_hw = bl_hw; + + return 0; +} + +int bl_irqs_enable(void) +{ + return 0; +} + +int bl_irqs_disable(void) +{ + return 0; +} + +void bl_irq_bottomhalf(struct bl_hw *bl_hw) +{ + u32 status, statuses = 0; +#ifdef CFG_BL_STATISTIC + unsigned long now = bl_os_get_time_ms(); +#endif + + REG_SW_SET_PROFILING(bl_hw, SW_PROF_RWNX_IPC_IRQ_HDLR); + status = ipc_host_get_rawstatus(bl_hw->ipc_env); + +redo: + while (status) { + statuses |= status; + /* All kinds of IRQs will be handled in one shot (RX, MSG, DBG, ...) + * this will ack IPC irqs not the cfpga irqs */ + ipc_host_irq(bl_hw->ipc_env, status); + status = ipc_host_get_rawstatus(bl_hw->ipc_env); + } + // bl_os_log_warn("[BH] Handle Event %08X\r\n", statuses); +#ifdef CFG_BL_STATISTIC + now = bl_os_get_time_ms(); + if (statuses & IPC_IRQ_E2A_RXDESC) { + bl_hw->stats.last_rx = now; + } + if (statuses & IPC_IRQ_E2A_TXCFM) { + bl_hw->stats.last_tx = now; + } +#endif + + REG_SW_CLEAR_PROFILING(bl_hw, SW_PROF_RWNX_IPC_IRQ_HDLR); + + ipc_host_enable_irq(bl_hw->ipc_env, IPC_IRQ_E2A_ALL); + /*we check irq status again, because we think there is corner case here*/ + status = ipc_host_get_rawstatus(bl_hw->ipc_env); + if (status) { + goto redo; + } +} diff --git a/platforms/bl808_m0/vendor/wifi/src/bl_mod_params.c b/platforms/bl808_m0/vendor/wifi/src/bl_mod_params.c new file mode 100644 index 0000000..5e4eef1 --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/src/bl_mod_params.c @@ -0,0 +1,65 @@ + +/** + **************************************************************************************** + * + * @file bl_mod_params.c + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + +#include "bl_defs.h" + +#define COMMON_PARAM(name, default_softmac, default_fullmac) \ + .name = default_fullmac, +#define SOFTMAC_PARAM(name, default) +#define FULLMAC_PARAM(name, default) .name = default, + +struct bl_mod_params bl_mod_params = { + /* common parameters */ + /* The BL808 AP path currently emits malformed HT Operation IEs when HT is + * enabled (sniffer shows garbage/bleed in IE 61). Keep AP/STA in legacy + * 11bg mode until the HT template state is understood. */ + COMMON_PARAM(ht_on, false, false) + COMMON_PARAM(vht_on, false, false) + COMMON_PARAM(mcs_map, IEEE80211_VHT_MCS_SUPPORT_0_7, IEEE80211_VHT_MCS_SUPPORT_0_7) + COMMON_PARAM(phy_cfg, 2, 2) + COMMON_PARAM(uapsd_timeout, 3000, 3000) + COMMON_PARAM(sgi, false, false) + COMMON_PARAM(sgi80, false, false) + COMMON_PARAM(listen_itv, 1, 1) + COMMON_PARAM(listen_bcmc, true, true) + COMMON_PARAM(lp_clk_ppm, 20, 20) + COMMON_PARAM(ps_on, false, false) + COMMON_PARAM(tx_lft, RWNX_TX_LIFETIME_MS, RWNX_TX_LIFETIME_MS) + COMMON_PARAM(amsdu_maxnb, NX_TX_PAYLOAD_MAX, NX_TX_PAYLOAD_MAX) + // By default, only enable UAPSD for Voice queue (see IEEE80211_DEFAULT_UAPSD_QUEUE comment) + COMMON_PARAM(uapsd_queues, 0, 0) +}; + +int bl_handle_dynparams(struct bl_hw *bl_hw) +{ + const int nss = 1; + + if (bl_hw->mod_params->phy_cfg < 0 || bl_hw->mod_params->phy_cfg > 5) + bl_hw->mod_params->phy_cfg = 2; + + if (bl_hw->mod_params->mcs_map < 0 || bl_hw->mod_params->mcs_map > 2) + bl_hw->mod_params->mcs_map = 0; + + /* HT capabilities */ + bl_hw->ht_cap.cap |= 1 << IEEE80211_HT_CAP_RX_STBC_SHIFT; + bl_hw->ht_cap.mcs.rx_highest = cpu_to_le16(65 * nss); + //Fixed leo disable MCS5/6/7 + bl_hw->ht_cap.mcs.rx_mask[0] = 0xFF; + + if (bl_hw->mod_params->sgi) { + bl_hw->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20; + bl_hw->ht_cap.mcs.rx_highest = cpu_to_le16(72 * nss); + } + bl_hw->ht_cap.cap |= IEEE80211_HT_CAP_SM_PS; + if (!bl_hw->mod_params->ht_on) + bl_hw->ht_cap.ht_supported = false; + + return 0; +} diff --git a/platforms/bl808_m0/vendor/wifi/src/bl_msg_tx.c b/platforms/bl808_m0/vendor/wifi/src/bl_msg_tx.c new file mode 100644 index 0000000..4ead52a --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/src/bl_msg_tx.c @@ -0,0 +1,1151 @@ +#include +#include +#include +#include + +#include "errno.h" +#include "bl_msg_tx.h" +#include "bl_utils.h" + +// field definitions +#define NXMAC_EN_DUPLICATE_DETECTION_BIT ((uint32_t)0x80000000) +#define NXMAC_EN_DUPLICATE_DETECTION_POS 31 +#define NXMAC_ACCEPT_UNKNOWN_BIT ((uint32_t)0x40000000) +#define NXMAC_ACCEPT_UNKNOWN_POS 30 +#define NXMAC_ACCEPT_OTHER_DATA_FRAMES_BIT ((uint32_t)0x20000000) +#define NXMAC_ACCEPT_OTHER_DATA_FRAMES_POS 29 +#define NXMAC_ACCEPT_QO_S_NULL_BIT ((uint32_t)0x10000000) +#define NXMAC_ACCEPT_QO_S_NULL_POS 28 +#define NXMAC_ACCEPT_QCFWO_DATA_BIT ((uint32_t)0x08000000) +#define NXMAC_ACCEPT_QCFWO_DATA_POS 27 +#define NXMAC_ACCEPT_Q_DATA_BIT ((uint32_t)0x04000000) +#define NXMAC_ACCEPT_Q_DATA_POS 26 +#define NXMAC_ACCEPT_CFWO_DATA_BIT ((uint32_t)0x02000000) +#define NXMAC_ACCEPT_CFWO_DATA_POS 25 +#define NXMAC_ACCEPT_DATA_BIT ((uint32_t)0x01000000) +#define NXMAC_ACCEPT_DATA_POS 24 +#define NXMAC_ACCEPT_OTHER_CNTRL_FRAMES_BIT ((uint32_t)0x00800000) +#define NXMAC_ACCEPT_OTHER_CNTRL_FRAMES_POS 23 +#define NXMAC_ACCEPT_CF_END_BIT ((uint32_t)0x00400000) +#define NXMAC_ACCEPT_CF_END_POS 22 +#define NXMAC_ACCEPT_ACK_BIT ((uint32_t)0x00200000) +#define NXMAC_ACCEPT_ACK_POS 21 +#define NXMAC_ACCEPT_CTS_BIT ((uint32_t)0x00100000) +#define NXMAC_ACCEPT_CTS_POS 20 +#define NXMAC_ACCEPT_RTS_BIT ((uint32_t)0x00080000) +#define NXMAC_ACCEPT_RTS_POS 19 +#define NXMAC_ACCEPT_PS_POLL_BIT ((uint32_t)0x00040000) +#define NXMAC_ACCEPT_PS_POLL_POS 18 +#define NXMAC_ACCEPT_BA_BIT ((uint32_t)0x00020000) +#define NXMAC_ACCEPT_BA_POS 17 +#define NXMAC_ACCEPT_BAR_BIT ((uint32_t)0x00010000) +#define NXMAC_ACCEPT_BAR_POS 16 +#define NXMAC_ACCEPT_OTHER_MGMT_FRAMES_BIT ((uint32_t)0x00008000) +#define NXMAC_ACCEPT_OTHER_MGMT_FRAMES_POS 15 +#define NXMAC_ACCEPT_ALL_BEACON_BIT ((uint32_t)0x00002000) +#define NXMAC_ACCEPT_ALL_BEACON_POS 13 +#define NXMAC_ACCEPT_NOT_EXPECTED_BA_BIT ((uint32_t)0x00001000) +#define NXMAC_ACCEPT_NOT_EXPECTED_BA_POS 12 +#define NXMAC_ACCEPT_DECRYPT_ERROR_FRAMES_BIT ((uint32_t)0x00000800) +#define NXMAC_ACCEPT_DECRYPT_ERROR_FRAMES_POS 11 +#define NXMAC_ACCEPT_BEACON_BIT ((uint32_t)0x00000400) +#define NXMAC_ACCEPT_BEACON_POS 10 +#define NXMAC_ACCEPT_PROBE_RESP_BIT ((uint32_t)0x00000200) +#define NXMAC_ACCEPT_PROBE_RESP_POS 9 +#define NXMAC_ACCEPT_PROBE_REQ_BIT ((uint32_t)0x00000100) +#define NXMAC_ACCEPT_PROBE_REQ_POS 8 +#define NXMAC_ACCEPT_MY_UNICAST_BIT ((uint32_t)0x00000080) +#define NXMAC_ACCEPT_MY_UNICAST_POS 7 +#define NXMAC_ACCEPT_UNICAST_BIT ((uint32_t)0x00000040) +#define NXMAC_ACCEPT_UNICAST_POS 6 +#define NXMAC_ACCEPT_ERROR_FRAMES_BIT ((uint32_t)0x00000020) +#define NXMAC_ACCEPT_ERROR_FRAMES_POS 5 +#define NXMAC_ACCEPT_OTHER_BSSID_BIT ((uint32_t)0x00000010) +#define NXMAC_ACCEPT_OTHER_BSSID_POS 4 +#define NXMAC_ACCEPT_BROADCAST_BIT ((uint32_t)0x00000008) +#define NXMAC_ACCEPT_BROADCAST_POS 3 +#define NXMAC_ACCEPT_MULTICAST_BIT ((uint32_t)0x00000004) +#define NXMAC_ACCEPT_MULTICAST_POS 2 +#define NXMAC_DONT_DECRYPT_BIT ((uint32_t)0x00000002) +#define NXMAC_DONT_DECRYPT_POS 1 +#define NXMAC_EXC_UNENCRYPTED_BIT ((uint32_t)0x00000001) +#define NXMAC_EXC_UNENCRYPTED_POS 0 + +static const struct mac_addr mac_addr_bcst = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; +static const struct mac_addr mac_addr_zero = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + +static const struct ieee80211_channel bl_channels_24_General[] = { + { .band = NL80211_BAND_2GHZ, .center_freq = 2412, .hw_value = 1, .max_power=20}, + { .band = NL80211_BAND_2GHZ, .center_freq = 2417, .hw_value = 2, .max_power=20}, + { .band = NL80211_BAND_2GHZ, .center_freq = 2422, .hw_value = 3, .max_power=20}, + { .band = NL80211_BAND_2GHZ, .center_freq = 2427, .hw_value = 4, .max_power=20}, + { .band = NL80211_BAND_2GHZ, .center_freq = 2432, .hw_value = 5, .max_power=20}, + { .band = NL80211_BAND_2GHZ, .center_freq = 2437, .hw_value = 6, .max_power=20}, + { .band = NL80211_BAND_2GHZ, .center_freq = 2442, .hw_value = 7, .max_power=20}, + { .band = NL80211_BAND_2GHZ, .center_freq = 2447, .hw_value = 8, .max_power=20}, + { .band = NL80211_BAND_2GHZ, .center_freq = 2452, .hw_value = 9, .max_power=20}, + { .band = NL80211_BAND_2GHZ, .center_freq = 2457, .hw_value = 10, .max_power=20}, + { .band = NL80211_BAND_2GHZ, .center_freq = 2462, .hw_value = 11, .max_power=20}, + { .band = NL80211_BAND_2GHZ, .center_freq = 2467, .hw_value = 12, .max_power=20}, + { .band = NL80211_BAND_2GHZ, .center_freq = 2472, .hw_value = 13, .max_power=20}, + { .band = NL80211_BAND_2GHZ, .center_freq = 2484, .hw_value = 14, .max_power=20}, +}; + +static const struct ieee80211_dot_d country_list[] = +{ + /*First Country is the default country*/ + { + .code = "CN", + .channel_num = 13, + .channels = bl_channels_24_General, + }, + { + .code = "JP", + .channel_num = 14, + .channels = bl_channels_24_General, + }, + { + .code = "US", + .channel_num = 11, + .channels = bl_channels_24_General, + }, + { + .code = "EU", + .channel_num = 13, + .channels = bl_channels_24_General, + }, +}; + +static int channel_num_default; +static const struct ieee80211_channel *channels_default; +static const struct ieee80211_dot_d *country_default; + +static int cfg80211_get_channel_list(const char *code, int *channel_num, const struct ieee80211_channel **channels, const struct ieee80211_dot_d **country_default) +{ + int i; + + for (i = 0; i < sizeof(country_list)/sizeof(country_list[0]); i++) { + if (0 == strcmp(country_list[i].code, code)) { + if(channel_num){ + *channel_num = country_list[i].channel_num; + } + if (channels) { + *channels = country_list[i].channels; + } + if (country_default) { + *country_default = &country_list[i]; + } + return 0; + } + } + /*NOT found code*/ + return -1; +} + +void bl_msg_update_channel_cfg(const char *code) +{ + if (cfg80211_get_channel_list(code, &channel_num_default, &channels_default, &country_default)) { + /*get channel list failed, so we set the default one*/ + channel_num_default = sizeof(bl_channels_24_General)/sizeof(bl_channels_24_General[0]); + channels_default = bl_channels_24_General; + country_default = &country_list[0]; + bl_os_printf("[WF] %s NOT found, using General instead, num of channel %d\r\n", code, channel_num_default); + } else { + bl_os_printf("[WF] country code %s used, num of channel %d\r\n", code, channel_num_default); + } + +} + +int bl_msg_get_channel_nums() +{ + return channel_num_default; +} + +int bl_get_fixed_channels_is_valid(uint16_t *channels, uint16_t channel_num) +{ + int i; + int channel; + + if (0 == channel_num) { + return 0; + } + + for (i = 0; i < channel_num; i++) { + channel = channels[i]; + if (0 == channel || (channel > bl_msg_get_channel_nums())) { + return 0; + } + } + + return 1; +} + +inline uint16_t phy_channel_to_freq(uint8_t band, int channel) +{ + uint16_t freq = 0xFFFF; + + do + { + //2.4.GHz + if (band == PHY_BAND_2G4) + { + // Check if the channel number is in the expected range + if ((channel < 1) || (channel > 14)) + break; + + // Compute the channel number + if (channel == 14) + freq = 2484; + else + freq = 2407 + channel * 5; + } + //5 GHz + else if (band == PHY_BAND_5G) + { + // Check if frequency is in the expected range + if ((channel < 1) || (channel > 165)) + break; + + // Compute the channel number + freq = 5000 + channel * 5; + } + } while(0); + + return (freq); +} + +inline uint8_t phy_freq_to_channel(uint8_t band, uint16_t freq) +{ + uint8_t channel = 0; + + do + { + //2.4.GHz + if (band == PHY_BAND_2G4) + { + // Check if the frequency is in the expected range + if ((freq < 2412) || (freq > 2484)) + break; + + if (freq == 2484) + channel = 14; + else + channel = (freq - 2407) / 5; + } +#if 0 + //5 GHz + else if (band == PHY_BAND_5G) + { + // Check if frequency is in the expected range (34-165) + if ((freq < 5170) || (freq > 5825)) + break; + + channel = (freq - 5000) / 5; + } +#endif + } while (0); + + return (channel); +} + +/** + **************************************************************************************** + * + * @file bl_msg_tx.c + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + +static inline void *bl_msg_zalloc(ke_msg_id_t const id, + ke_task_id_t const dest_id, + ke_task_id_t const src_id, + uint16_t const param_len) +{ + struct lmac_msg *msg; + + msg = (struct lmac_msg *)bl_os_malloc(sizeof(struct lmac_msg) + param_len); + if (msg == NULL) { + bl_os_printf("%s: msg allocation failed\n", __func__); + return NULL; + } + memset(msg, 0, sizeof(struct lmac_msg) + param_len); + + msg->id = id; + msg->dest_id = dest_id; + msg->src_id = src_id; + msg->param_len = param_len; + + return msg->param; +} + +static inline bool is_non_blocking_msg(int id) { + return ((id == MM_TIM_UPDATE_REQ) || (id == ME_RC_SET_RATE_REQ) || + (id == MM_BFMER_ENABLE_REQ) || (id == ME_TRAFFIC_IND_REQ)); +} + +#define BITS_PER_LONG 32 +#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) +/** + * test_bit - Determine whether a bit is set + * @nr: bit number to test + * @addr: Address to start counting from + */ +static inline int test_bit(int nr, const volatile unsigned long *addr) +{ + return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1))); +} + +static int bl_send_msg(struct bl_hw *bl_hw, const void *msg_params, + int reqcfm, ke_msg_id_t reqid, void *cfm) +{ + struct lmac_msg *msg; + struct bl_cmd *cmd; + bool nonblock; + int ret; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + msg = container_of((void *)msg_params, struct lmac_msg, param); + + if (!bl_hw->ipc_env) { + bl_os_printf("%s: bypassing (restart must have failed)\r\n", __func__); + bl_os_free(msg); + RWNX_DBG(RWNX_FN_LEAVE_STR); + return -EBUSY; + } + + nonblock = is_non_blocking_msg(msg->id); + + cmd = bl_os_malloc(sizeof(struct bl_cmd)); + if (NULL == cmd) { + bl_os_free(msg); + bl_os_printf("%s: failed to allocate mem for cmd, size is %d\r\n", __func__, sizeof(struct bl_cmd)); + return -ENOMEM; + } + memset(cmd, 0, sizeof(struct bl_cmd)); + cmd->result = EINTR; + cmd->id = msg->id; + cmd->reqid = reqid; + cmd->a2e_msg = msg; + cmd->e2a_msg = cfm; + if (nonblock) + cmd->flags = RWNX_CMD_FLAG_NONBLOCK; + if (reqcfm) + cmd->flags |= RWNX_CMD_FLAG_REQ_CFM; + ret = bl_hw->cmd_mgr.queue(&bl_hw->cmd_mgr, cmd); + + if (!nonblock) { + bl_os_free(cmd); + } else { + ret = cmd->result; + } + + RWNX_DBG(RWNX_FN_LEAVE_STR); + return ret; +} + +int bl_send_reset(struct bl_hw *bl_hw) +{ + void *void_param; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* RESET REQ has no parameter */ + void_param = bl_msg_zalloc(MM_RESET_REQ, TASK_MM, DRV_TASK_ID, 0); + if (!void_param) + return -ENOMEM; + + return bl_send_msg(bl_hw, void_param, 1, MM_RESET_CFM, NULL); +} + +int bl_send_monitor_enable(struct bl_hw *bl_hw, struct mm_monitor_cfm *cfm) +{ + struct mm_monitor_req *req; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + req = bl_msg_zalloc(MM_MONITOR_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_monitor_req)); + if (!req) + return -ENOMEM; + + req->enable = 1; + + return bl_send_msg(bl_hw, req, 1, MM_MONITOR_CFM, cfm); +} + +int bl_send_monitor_disable(struct bl_hw *bl_hw, struct mm_monitor_cfm *cfm) +{ + struct mm_monitor_req *req; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + req = bl_msg_zalloc(MM_MONITOR_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_monitor_req)); + if (!req) + return -ENOMEM; + + req->enable = 0; + + return bl_send_msg(bl_hw, req, 1, MM_MONITOR_CFM, cfm); +} + +int bl_send_beacon_interval_set(struct bl_hw *bl_hw, struct mm_set_beacon_int_cfm *cfm, uint16_t beacon_int) +{ + struct mm_set_beacon_int_req *req; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + req = bl_msg_zalloc(MM_SET_BEACON_INT_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_beacon_int_req)); + if (!req) + return -ENOMEM; + + req->beacon_int = beacon_int; + + return bl_send_msg(bl_hw, req, 1, MM_SET_BEACON_INT_CFM, cfm); +} + +//TODO we only support 2.4GHz +int bl_send_monitor_channel_set(struct bl_hw *bl_hw, struct mm_monitor_channel_cfm *cfm, int channel, int use_40Mhz) +{ + struct mm_monitor_channel_req *req; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + req = bl_msg_zalloc(MM_MONITOR_CHANNEL_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_monitor_channel_req)); + if (!req) { + return -ENOMEM; + } + + req->freq = phy_channel_to_freq(PHY_BAND_2G4, channel); + + return bl_send_msg(bl_hw, req, 1, MM_MONITOR_CHANNEL_CFM, cfm); +} + +int bl_send_version_req(struct bl_hw *bl_hw, struct mm_version_cfm *cfm) +{ + int ret; + void *void_param; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* VERSION REQ has no parameter */ + void_param = bl_msg_zalloc(MM_VERSION_REQ, TASK_MM, DRV_TASK_ID, 0); + if (!void_param) { + RWNX_DBG(RWNX_FN_LEAVE_STR); + return -ENOMEM; + } + ret = bl_send_msg(bl_hw, void_param, 1, MM_VERSION_CFM, cfm); + RWNX_DBG(RWNX_FN_LEAVE_STR); + return ret; +} + +int bl_send_me_config_req(struct bl_hw *bl_hw) +{ + struct me_config_req *req; + uint8_t *ht_mcs = (uint8_t *)&(bl_hw->ht_cap.mcs); + int i, ret; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* Build the ME_CONFIG_REQ message */ + req = bl_msg_zalloc(ME_CONFIG_REQ, TASK_ME, DRV_TASK_ID, + sizeof(struct me_config_req)); + if (!req) { + RWNX_DBG(RWNX_FN_LEAVE_STR); + return -ENOMEM; + } + + /* Set parameters for the ME_CONFIG_REQ message */ + bl_os_printf("[ME] HT supp %d, VHT supp %d\r\n", 1, 0); + + req->ht_supp = 1; + req->vht_supp = 0; + req->ht_cap.ht_capa_info = cpu_to_le16(bl_hw->ht_cap.cap); + + /*AMPDU MAX Length: + * 0x0:8K + * 0x1:16K + * 0x2:32K + * 0x3:64K + */ + req->ht_cap.a_mpdu_param = 0x3; + + for (i = 0; i < sizeof(bl_hw->ht_cap.mcs); i++) { + req->ht_cap.mcs_rate[i] = ht_mcs[i]; + } + req->ht_cap.ht_extended_capa = 0; + req->ht_cap.tx_beamforming_capa = 0; + req->ht_cap.asel_capa = 0; + + //TODO talk with firmware guys +#if 0 + req->vht_cap.vht_capa_info = cpu_to_le32(vht_cap->cap); + req->vht_cap.rx_highest = cpu_to_le16(vht_cap->vht_mcs.rx_highest); + req->vht_cap.rx_mcs_map = cpu_to_le16(vht_cap->vht_mcs.rx_mcs_map); + req->vht_cap.tx_highest = cpu_to_le16(vht_cap->vht_mcs.tx_highest); + req->vht_cap.tx_mcs_map = cpu_to_le16(vht_cap->vht_mcs.tx_mcs_map); +#endif + + req->ps_on = bl_hw->mod_params->ps_on; + req->tx_lft = bl_hw->mod_params->tx_lft; + + /* Send the ME_CONFIG_REQ message to LMAC FW */ + ret = bl_send_msg(bl_hw, req, 1, ME_CONFIG_CFM, NULL); + RWNX_DBG(RWNX_FN_LEAVE_STR); + return ret; +} + +static uint8_t passive_scan_flag(uint32_t flags) { + if (flags & (IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_RADAR)) + return SCAN_PASSIVE_BIT; + return 0; +} + +int bl_send_me_chan_config_req(struct bl_hw *bl_hw) +{ + struct me_chan_config_req *req; + int i; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* Build the ME_CHAN_CONFIG_REQ message */ + req = bl_msg_zalloc(ME_CHAN_CONFIG_REQ, TASK_ME, DRV_TASK_ID, + sizeof(struct me_chan_config_req)); + if (!req) + return -ENOMEM; + + req->chan2G4_cnt = 0; + for (i = 0; i < channel_num_default; i++) { + req->chan2G4[req->chan2G4_cnt].flags = 0; + if (channels_default[i].flags & IEEE80211_CHAN_DISABLED) + req->chan2G4[req->chan2G4_cnt].flags |= SCAN_DISABLED_BIT; + req->chan2G4[req->chan2G4_cnt].flags |= passive_scan_flag(channels_default[i].flags); + req->chan2G4[req->chan2G4_cnt].band = NL80211_BAND_2GHZ; + req->chan2G4[req->chan2G4_cnt].freq = channels_default[i].center_freq; + req->chan2G4[req->chan2G4_cnt].tx_power = channels_default[i].max_power; + req->chan2G4_cnt++; + if (req->chan2G4_cnt == SCAN_CHANNEL_2G4) + break; + } + + /* Send the ME_CHAN_CONFIG_REQ message to LMAC FW */ + return bl_send_msg(bl_hw, req, 1, ME_CHAN_CONFIG_CFM, NULL); +} + +int bl_send_me_rate_config_req(struct bl_hw *bl_hw, uint8_t sta_idx, uint16_t fixed_rate_cfg) +{ + struct me_rc_set_rate_req *req; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* Build the ME_RC_SET_RATE_REQ message */ + req = bl_msg_zalloc(ME_RC_SET_RATE_REQ, TASK_ME, DRV_TASK_ID, sizeof(struct me_rc_set_rate_req)); + if (!req) { + return -ENOMEM; + } + req->sta_idx = sta_idx; + req->fixed_rate_cfg = fixed_rate_cfg; + req->power_table_req = 1; + + return bl_send_msg(bl_hw, req, 0, 0, NULL); +} + +int bl_send_start(struct bl_hw *bl_hw) +{ + struct mm_start_req *start_req_param; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* Build the START REQ message */ + start_req_param = bl_msg_zalloc(MM_START_REQ, TASK_MM, DRV_TASK_ID, + sizeof(struct mm_start_req)); + if (!start_req_param) + return -ENOMEM; + + memset(&start_req_param->phy_cfg, 0, sizeof(start_req_param->phy_cfg)); + //XXX magic number + start_req_param->phy_cfg.parameters[0] = 0x1; + start_req_param->uapsd_timeout = (u32_l)bl_hw->mod_params->uapsd_timeout; + start_req_param->lp_clk_accuracy = (u16_l)bl_hw->mod_params->lp_clk_ppm; + + /* Send the START REQ message to LMAC FW */ + return bl_send_msg(bl_hw, start_req_param, 1, MM_START_CFM, NULL); +} + +int bl_send_add_if(struct bl_hw *bl_hw, const unsigned char *mac, + enum nl80211_iftype iftype, bool p2p, struct mm_add_if_cfm *cfm) +{ + struct mm_add_if_req *add_if_req_param; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* Build the ADD_IF_REQ message */ + add_if_req_param = bl_msg_zalloc(MM_ADD_IF_REQ, TASK_MM, DRV_TASK_ID, + sizeof(struct mm_add_if_req)); + if (!add_if_req_param) + return -ENOMEM; + + /* Set parameters for the ADD_IF_REQ message */ + memcpy(&(add_if_req_param->addr.array[0]), mac, ETH_ALEN); + switch (iftype) { + case NL80211_IFTYPE_P2P_CLIENT: + add_if_req_param->p2p = true; + __attribute__((fallthrough)); + // no break + case NL80211_IFTYPE_STATION: + add_if_req_param->type = MM_STA; + break; + + case NL80211_IFTYPE_ADHOC: + add_if_req_param->type = MM_IBSS; + break; + + case NL80211_IFTYPE_P2P_GO: + add_if_req_param->p2p = true; + __attribute__((fallthrough)); + // no break + case NL80211_IFTYPE_AP: + add_if_req_param->type = MM_AP; + break; + case NL80211_IFTYPE_MESH_POINT: + add_if_req_param->type = MM_MESH_POINT; + break; + case NL80211_IFTYPE_AP_VLAN: + return -1; + default: + add_if_req_param->type = MM_STA; + break; + } + + /* Send the ADD_IF_REQ message to LMAC FW */ + return bl_send_msg(bl_hw, add_if_req_param, 1, MM_ADD_IF_CFM, cfm); +} + +int bl_send_remove_if(struct bl_hw *bl_hw, uint8_t inst_nbr) +{ + struct mm_remove_if_req *remove_if_req_param; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + remove_if_req_param = bl_msg_zalloc(MM_REMOVE_IF_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_remove_if_req)); + if (!remove_if_req_param) { + return -ENOMEM; + } + remove_if_req_param->inst_nbr = inst_nbr; + + return bl_send_msg(bl_hw, remove_if_req_param, 1, MM_REMOVE_IF_CFM, NULL); +} + +int bl_send_scanu_req(struct bl_hw *bl_hw, struct bl_send_scanu_para *scanu_para) +{ + struct scanu_start_req *req; + int i, index; + uint8_t chan_flags = 0; + const struct ieee80211_channel *chan; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* Build the SCANU_START_REQ message */ + req = bl_msg_zalloc(SCANU_START_REQ, TASK_SCANU, DRV_TASK_ID, + sizeof(struct scanu_start_req)); + if (!req) { + return -ENOMEM; + } + + /* Set parameters */ + // Always use idx 0, because vif_idx in vif_entry could be 0, leading to probe_rep tx fail + req->vif_idx = 0; + if (0 == scanu_para->channel_num) { + req->chan_cnt = channel_num_default; + } else { + req->chan_cnt = scanu_para->channel_num; + } + + req->ssid_cnt = 1; + if (scanu_para->ssid != NULL && scanu_para->ssid->length) { + req->ssid[0].length = scanu_para->ssid->length; + memcpy(req->ssid[0].array, scanu_para->ssid->array, req->ssid[0].length); + } else { + req->ssid[0].length = 0; + //if specfied ssid, ignore user setting passive mode + if (req->ssid_cnt == 0 || scanu_para->scan_mode == SCAN_PASSIVE) + { + chan_flags |= SCAN_PASSIVE_BIT; + } + } + memcpy((uint8_t *)&(req->bssid), (uint8_t *)scanu_para->bssid, ETH_ALEN); + memcpy(&(req->mac), scanu_para->mac, ETH_ALEN); + req->no_cck = true;//FIXME params? talk with firmware guys + +#if 0 + for (i = 0; i < req->ssid_cnt; i++) { + int j; + for (j = 0; j < param->ssids[i].ssid_len; j++) + req->ssid[i].array[j] = param->ssids[i].ssid[j]; + req->ssid[i].length = param->ssids[i].ssid_len; + } +#endif + + //XXX custom ie can be added + req->add_ie_len = 0; + req->add_ies = 0; + + for (i = 0; i < req->chan_cnt; i++) { + index = (channel_num_default == req->chan_cnt) ? i : (scanu_para->channels[i] - 1); + chan = &(channels_default[index]); + + req->chan[i].band = chan->band; + req->chan[i].freq = chan->center_freq; + req->chan[i].flags = chan_flags | passive_scan_flag(chan->flags); + req->chan[i].tx_power = chan->max_reg_power; + } + + req->duration_scan = scanu_para->duration_scan; + + /* Send the SCANU_START_REQ message to LMAC FW */ + return bl_send_msg(bl_hw, req, 0, 0, NULL); +} + +int bl_send_scanu_raw_send(struct bl_hw *bl_hw, uint8_t *pkt, int len) +{ + struct scanu_raw_send_req *req; + struct scanu_raw_send_cfm cfm; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* Build the SCANU_RAW_SEND_REQ message */ + req = bl_msg_zalloc(SCANU_RAW_SEND_REQ, TASK_SCANU, DRV_TASK_ID, sizeof(struct scanu_raw_send_req)); + if (!req) { + return -ENOMEM; + } + + /* Set parameters */ + req->pkt = pkt; + req->len = len; + + /* Send the SCANU_RAW_SEND_REQ message to LMAC FW */ + return bl_send_msg(bl_hw, req, 1, SCANU_RAW_SEND_CFM, &cfm); +} + +static inline bool use_pairwise_key(struct cfg80211_crypto_settings *crypto) +{ + if ((crypto->cipher_group == WLAN_CIPHER_SUITE_WEP40) || + (crypto->cipher_group == WLAN_CIPHER_SUITE_WEP104)) + return false; + + return true; +} + +int bl_send_sm_connect_req(struct bl_hw *bl_hw, struct cfg80211_connect_params *sme, struct sm_connect_cfm *cfm) +{ + struct sm_connect_req *req; + int i; + u32_l flags = sme->flags; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* Build the SM_CONNECT_REQ message */ + req = bl_msg_zalloc(SM_CONNECT_REQ, TASK_SM, DRV_TASK_ID, + sizeof(struct sm_connect_req)); + if (!req) + return -ENOMEM; + + if (sme->key_len || sme->pmk_len) { + flags |= WPA_WPA2_IN_USE; + flags |= CONTROL_PORT_NO_ENC; + } + +#if 0 // useless + /* Set parameters for the SM_CONNECT_REQ message */ + if (sme->crypto.n_ciphers_pairwise && + ((sme->crypto.ciphers_pairwise[0] == WLAN_CIPHER_SUITE_WEP40) || + (sme->crypto.ciphers_pairwise[0] == WLAN_CIPHER_SUITE_TKIP) || + (sme->crypto.ciphers_pairwise[0] == WLAN_CIPHER_SUITE_WEP104))) + flags |= DISABLE_HT; + + if (sme->crypto.control_port) + flags |= CONTROL_PORT_HOST; + + if (sme->crypto.control_port_no_encrypt) + flags |= CONTROL_PORT_NO_ENC; + + if (use_pairwise_key(&sme->crypto)) + flags |= WPA_WPA2_IN_USE; + + if (sme->mfp == NL80211_MFP_REQUIRED) + flags |= MFP_IN_USE; + + if (sme->crypto.control_port_ethertype) + req->ctrl_port_ethertype = sme->crypto.control_port_ethertype; + else + req->ctrl_port_ethertype = ETH_P_PAE; +#endif + req->ctrl_port_ethertype = ETH_P_PAE; + + if (sme->bssid && !MAC_ADDR_CMP(sme->bssid, mac_addr_bcst.array) && !MAC_ADDR_CMP(sme->bssid, mac_addr_zero.array)) { + for (i=0;ibssid.array[i] = sme->bssid[i]; + } + else + req->bssid = mac_addr_bcst; + req->vif_idx = bl_hw->vif_index_sta; + if (sme->channel.center_freq) { + req->chan.band = sme->channel.band; + req->chan.freq = sme->channel.center_freq; + req->chan.flags = passive_scan_flag(sme->channel.flags); + } else { + req->chan.freq = (u16_l)-1; + } + for (i = 0; i < sme->ssid_len; i++) + req->ssid.array[i] = sme->ssid[i]; + req->ssid.length = sme->ssid_len; + req->flags = flags; +#if 0 // useless + if (WARN_ON(sme->ie_len > sizeof(req->ie_buf))) + return -EINVAL; + if (sme->ie_len) + memcpy(req->ie_buf, sme->ie, sme->ie_len); + req->ie_len = sme->ie_len; +#endif + req->listen_interval = bl_mod_params.listen_itv; + req->dont_wait_bcmc = !bl_mod_params.listen_bcmc; + + /* Set auth_type */ + if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC || + sme->auth_type > NL80211_AUTHTYPE_MAX) + req->auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM; + else + req->auth_type = sme->auth_type; + + /* Set UAPSD queues */ + req->uapsd_queues = bl_mod_params.uapsd_queues; + req->is_supplicant_enabled = 1; + if (sme->key_len) { + memcpy(req->phrase, sme->key, sme->key_len); + } + if (sme->pmk_len) { + memcpy(req->phrase_pmk, sme->pmk, sme->pmk_len); + } + + /* Send the SM_CONNECT_REQ message to LMAC FW */ + return bl_send_msg(bl_hw, req, 1, SM_CONNECT_CFM, cfm); +} + +int bl_send_sm_disconnect_req(struct bl_hw *bl_hw) +{ + struct sm_disconnect_req *req; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* Build the SM_DISCONNECT_REQ message */ + req = bl_msg_zalloc(SM_DISCONNECT_REQ, TASK_SM, DRV_TASK_ID, sizeof(struct sm_disconnect_req)); + if (!req) { + return -ENOMEM; + } + + /* Set parameters for the SM_DISCONNECT_REQ message */ + req->vif_idx = bl_hw->vif_index_sta; + + /* Send the SM_DISCONNECT_REQ message to LMAC FW */ + //return bl_send_msg(bl_hw, req, 1, SM_DISCONNECT_IND, NULL); + return bl_send_msg(bl_hw, req, 1, SM_DISCONNECT_CFM, NULL); +} + +int bl_send_sm_connect_abort_req(struct bl_hw *bl_hw, struct sm_connect_abort_cfm *cfm) +{ + struct sm_connect_abort_req *req; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + req = bl_msg_zalloc(SM_CONNECT_ABORT_REQ, TASK_SM, DRV_TASK_ID, sizeof(struct sm_connect_abort_req)); + if (!req) { + return -ENOMEM; + } + /* Set parameters for the SM_CONNECT_ABORT_REQ message */ + req->vif_idx = bl_hw->vif_index_sta; + + return bl_send_msg(bl_hw, req, 1, SM_CONNECT_ABORT_CFM, cfm); +} + +int bl_send_mm_powersaving_req(struct bl_hw *bl_hw, int mode) +{ + struct mm_set_ps_mode_req *req; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* Build the MM_SET_PS_MODE_REQ message */ + req = bl_msg_zalloc(MM_SET_PS_MODE_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_ps_mode_req)); + if (!req) { + return -ENOMEM; + } + + /* Set parameters for the MM_SET_PS_MODE_REQ message */ + req->new_state = mode; + + /* Send the MM_SET_PS_MODE_REQ message to LMAC FW */ + return bl_send_msg(bl_hw, req, 1, MM_SET_PS_MODE_CFM, NULL); +} + +int bl_send_mm_denoise_req(struct bl_hw *bl_hw, int mode) +{ + struct mm_set_denoise_req *req; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* Build the MM_DENOISE_REQ message */ + req = bl_msg_zalloc(MM_DENOISE_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_denoise_req)); + if (!req) { + return -ENOMEM; + } + + /* Set parameters for the MM_SET_PS_MODE_REQ message */ + req->denoise_mode = mode; + + /* Send the MM_SET_PS_MODE_REQ message to LMAC FW */ + return bl_send_msg(bl_hw, req, 1, MM_SET_PS_MODE_CFM, NULL); +} + +/* Country IE definition +MAC_COUNTRY_2G4_USA {7, 6, 'U', 'S', 32, 1, 11, 20} // X'10' FCC +MAC_COUNTRY_2G4_CANADA {7, 6, 'C', 'A', 32, 1, 11, 20} // X'20' DOC/IC +MAC_COUNTRY_2G4_EUROPE {7, 6, 'E', 'U', 32, 1, 13, 20} // X'30' ETSI +MAC_COUNTRY_2G4_SPAIN {7, 6, 'S', 'P', 32, 10, 2, 20} // X'31' +MAC_COUNTRY_2G4_FRANCE {7, 6, 'F', 'R', 32, 10, 4, 20} // X'32' +MAC_COUNTRY_2G4_JAPAN {7, 6, 'J', 'P', 32, 14, 1, 20} // X'40' +MAC_COUNTRY_2G4_CHINA {7, 6, 'C', 'N', 32, 1, 13, 20} // X'50' +*/ + +static int _fill_country_code_ie(uint8_t *buf, uint8_t buf_len_max) +{ + if (NULL == country_default || NULL == channels_default) { + return 0; + } + + // Tag: Country Informance + buf[0] = 7; + // Tag lenth + buf[1] = 6; + //Country Code + buf[2] = country_default->code[0]; + buf[3] = country_default->code[1]; + //Environment + buf[4] = 32;//Any + //First Channel + buf[5] = 1; + //Channel Num + buf[6] = buf[5] - 1 + country_default ->channel_num; + //Max power + buf[7] = channels_default->max_power; + + return 8; +} + +int bl_send_apm_start_req(struct bl_hw *bl_hw, struct apm_start_cfm *cfm, char *ssid, char *password, int channel, uint8_t vif_index, uint8_t hidden_ssid, uint16_t bcn_int) +{ + struct apm_start_req *req; + uint8_t rate[] = {0x82,0x84,0x8b,0x96}; + + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* Build the APM_START_REQ message */ + req = bl_msg_zalloc(APM_START_REQ, TASK_APM, DRV_TASK_ID, sizeof(struct apm_start_req)); + if (!req) { + return -ENOMEM; + } + + req->chan.band = NL80211_BAND_2GHZ; + req->chan.freq = phy_channel_to_freq(req->chan.band, channel); + req->chan.flags = 0; + req->chan.tx_power = 0; + + /* Set parameters for the APM_START_REQ message */ + req->center_freq1 = req->chan.freq; + req->center_freq2 = 0; + req->ch_width = PHY_CHNL_BW_20; + req->hidden_ssid = hidden_ssid; + req->bcn_addr = 0; + req->bcn_len = 0; + req->tim_oft = 0; + req->bcn_int = bcn_int; + req->flags = DISABLE_HT; + //req->ctrl_port_ethertype = ETH_P_PAE; + req->ctrl_port_ethertype = 0x8e88; + req->tim_len = 0x6; + req->vif_idx = vif_index; + + /*added for EMBEDED*/ +#if 0 + /// Enable APM Embedded + bool apm_emb_enabled; + /// rate set + struct mac_rateset rate_set; + /// Beacon dtim period + uint8_t beacon_period; + /// Qos is supported + uint8_t qos_supported; + /// SSID of the AP + struct mac_ssid ssid; + /// AP Security type + uint8_t ap_sec_type; + /// AP Passphrase + uint8_t phrase[MAX_PSK_PASS_PHRASE_LEN]; +#else + if (strlen(password)) { + req->ap_sec_type = 1; + req->flags |= WPA_WPA2_IN_USE; + } else { + req->ap_sec_type = 0; + } + req->apm_emb_enabled = 1; + memcpy(req->ssid.array, ssid, strlen(ssid));//FIXME potential buffer overflow + memcpy(req->phrase, password, strlen(password));//FIXME potential buffer overflow + req->ssid.length = strlen(ssid); + req->rate_set.length = sizeof(rate); + memcpy(req->rate_set.array, rate, req->rate_set.length); + req->beacon_period = 0x1; //force AP DTIM period + req->qos_supported = 1; +#endif + req->bcn_buf_len = _fill_country_code_ie(req->bcn_buf, sizeof(req->bcn_buf)); + + /* Send the APM_START_REQ message to LMAC FW */ + return bl_send_msg(bl_hw, req, 1, APM_START_CFM, cfm); +} + +int bl_send_apm_stop_req(struct bl_hw *bl_hw, uint8_t vif_idx) +{ + struct apm_stop_req *req; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* Build the APM_STOP_REQ message */ + req = bl_msg_zalloc(APM_STOP_REQ, TASK_APM, DRV_TASK_ID, sizeof(struct apm_stop_req)); + if (!req) { + return -ENOMEM; + } + + /* Set parameters for the APM_STOP_REQ message */ + req->vif_idx = vif_idx; + + /* Send the APM_STOP_REQ message to LMAC FW */ + return bl_send_msg(bl_hw, req, 1, APM_STOP_CFM, NULL); +} + +int bl_send_apm_sta_del_req(struct bl_hw *bl_hw, struct apm_sta_del_cfm *cfm, uint8_t sta_idx, uint8_t vif_idx) +{ + struct apm_sta_del_req *req; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* Build the APM_STOP_REQ message */ + req = bl_msg_zalloc(APM_STA_DEL_REQ, TASK_APM, DRV_TASK_ID, sizeof(struct apm_sta_del_req)); + if (!req) { + return -ENOMEM; + } + + /* Set parameters for the APM_STA_DEL_REQ message */ + req->vif_idx = vif_idx; + req->sta_idx = sta_idx; + + /* Send the APM_STA_DEL_REQ message to LMAC FW */ + return bl_send_msg(bl_hw, req, 1, APM_STA_DEL_CFM, cfm); +} + +int bl_send_apm_conf_max_sta_req(struct bl_hw *bl_hw, uint8_t max_sta_supported) +{ + struct apm_conf_max_sta_req *req; + + /* Build the APM_STOP_REQ message */ + req = bl_msg_zalloc(APM_CONF_MAX_STA_REQ, TASK_APM, DRV_TASK_ID, sizeof(struct apm_conf_max_sta_req)); + if (!req) { + return -ENOMEM; + } + + /* Set parameters for the APM_STOP_REQ message */ + req->max_sta_supported = max_sta_supported; + + /* Send the APM_STOP_REQ message to LMAC FW */ + return bl_send_msg(bl_hw, req, 1, APM_CONF_MAX_STA_CFM, NULL); +} + +int bl_send_cfg_task_req(struct bl_hw *bl_hw, uint32_t ops, uint32_t task, uint32_t element, uint32_t type, void *arg1, void *arg2) +{ + struct cfg_start_req *req; +#define ENTRY_BUF_SIZE (8) + + /* Build the APM_STOP_REQ message */ + //FIXME static allocated size + req = bl_msg_zalloc(CFG_START_REQ, TASK_CFG, DRV_TASK_ID, sizeof(struct cfg_start_req) + 32); + if (!req) { + return -ENOMEM; + } + + /* Set parameters for the APM_STOP_REQ message */ + req->ops = ops; + switch (req->ops) { + case CFG_ELEMENT_TYPE_OPS_SET: + { + req->u.set[0].task = task; + req->u.set[0].element = element; + req->u.set[0].type = type; + req->u.set[0].length = utils_tlv_bl_pack_auto( + req->u.set[0].buf, + ENTRY_BUF_SIZE, + type, + arg1 + ); + } + break; + case CFG_ELEMENT_TYPE_OPS_GET: + { + //TODO + } + break; + case CFG_ELEMENT_TYPE_OPS_RESET: + { + //TODO + } + break; + case CFG_ELEMENT_TYPE_OPS_DUMP_DEBUG: + { + req->u.set[0].task = task; + req->u.set[0].element = element; + req->u.set[0].length = 0; + } + break; + default: + { + /*empty here*/ + assert(0); + } + } + + /* Send the APM_STOP_REQ message to LMAC FW */ + return bl_send_msg(bl_hw, req, 1, CFG_START_CFM, NULL); +} + +int bl_send_channel_set_req(struct bl_hw *bl_hw, int channel) +{ + struct mm_set_channel_req *param; + struct mm_set_channel_cfm cfm; + + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + param = bl_msg_zalloc(MM_SET_CHANNEL_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_channel_req)); + if (!param) { + return -ENOMEM; + } + memset(&cfm, 0, sizeof(struct mm_set_channel_cfm)); + + param->band = PHY_BAND_2G4; + param->type = PHY_CHNL_BW_20; + param->prim20_freq = phy_channel_to_freq(param->band, channel); + param->center1_freq = phy_channel_to_freq(param->band, channel);//useless when bandwidth bigger than 20MHZ? + param->center2_freq = phy_channel_to_freq(param->band, channel);//useless when bandwidth bigger than 20MHZ? + param->index = 0; + param->tx_power = 15;//FIXME which value should be tx_power set? + + return bl_send_msg(bl_hw, param, 1, MM_SET_CHANNEL_CFM, &cfm); +} + diff --git a/platforms/bl808_m0/vendor/wifi/src/bl_shim.c b/platforms/bl808_m0/vendor/wifi/src/bl_shim.c new file mode 100644 index 0000000..80ad2cc --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/src/bl_shim.c @@ -0,0 +1,84 @@ +// Thin C-side wrappers around vendor calls whose request types pull in +// nested header material it would be tedious to mirror in D. Strictly +// struct-construction + a single bl_send_* call -- no policy. +// +// Roughly the role wifi_mgmr served in the upstream SDK, pared down to +// what OpenWatt's D driver actually needs. + +#include "bl_msg_tx.h" +#include "cfg80211.h" +#include "nl80211.h" +#include "bl_defs.h" +#include "ipc_host.h" +#include "bl_cmds.h" +#include "bl_os_private.h" + +// IPC callbacks live in D (urt.driver.bl808.wifi) with C linkage so the +// vendor cb table can point at them directly. +extern uint8_t bl_radarind(void *pthis, void *hostid); +extern uint8_t bl_msgackind(void *pthis, void *hostid); +extern uint8_t bl_dbgind(void *pthis, void *hostid); +extern int bl_txdatacfm(void *pthis, void *host_id); +extern void bl_prim_tbtt_ind(void *pthis); +extern void bl_sec_tbtt_ind(void *pthis); + +// Ported from vendor's bl_utils.c. Allocates the host-side IPC env via +// the OS adapter (-> D's urt heap), wires the cb table, hands both to +// ipc_host_init, then initialises the command manager. +int bl_shim_ipc_init(struct bl_hw *bl_hw, struct ipc_shared_env_tag *shared_mem) +{ + struct ipc_host_cb_tag cb = { + .send_data_cfm = bl_txdatacfm, + .recv_data_ind = NULL, + .recv_radar_ind = bl_radarind, + .recv_msg_ind = NULL, // vendor pattern: events arrive via bl_rx_e2a_handler + .recv_msgack_ind = bl_msgackind, + .recv_dbg_ind = bl_dbgind, + .prim_tbtt_ind = bl_prim_tbtt_ind, + .sec_tbtt_ind = bl_sec_tbtt_ind, + }; + + bl_hw->ipc_env = bl_os_malloc(sizeof(struct ipc_host_env_tag)); + if (!bl_hw->ipc_env) + return -1; + + ipc_host_init(bl_hw->ipc_env, &cb, shared_mem, bl_hw); + bl_cmd_mgr_init(&bl_hw->cmd_mgr); + return 0; +} + +int bl_shim_sta_connect(struct bl_hw *bl_hw, + const uint8_t *ssid, uint32_t ssid_len, + const uint8_t *bssid_or_null, + const char *psk, uint8_t psk_len, + const uint8_t *pmk, uint8_t pmk_len, + int auth_type, + uint16_t freq) +{ + struct sm_connect_cfm cfm = {0}; + struct cfg80211_connect_params sme = {0}; + + sme.ssid = ssid; + sme.ssid_len = ssid_len; + if (bssid_or_null) + sme.bssid = bssid_or_null; + sme.auth_type = auth_type; + if (psk_len) { + sme.key = (const uint8_t *)psk; + sme.key_len = psk_len; + } + if (pmk_len) { + sme.pmk = pmk; + sme.pmk_len = pmk_len; + } + if (freq) { + sme.channel.center_freq = freq; + sme.channel.band = 0; // 2.4 GHz + sme.channel.flags = 0; + } + + int r = bl_send_sm_connect_req(bl_hw, &sme, &cfm); + if (r) + return -1; + return cfm.status; +} diff --git a/platforms/bl808_m0/vendor/wifi/src/ipc_host.c b/platforms/bl808_m0/vendor/wifi/src/ipc_host.c new file mode 100644 index 0000000..f72fdc7 --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/src/ipc_host.c @@ -0,0 +1,396 @@ +#include +#include +#include +#include + +#include "ipc_host.h" +#include "reg_ipc_app.h" +#include "bl_cmds.h" +#include "bl_utils.h" +#include "bl_tx.h" +#include "bl_os_private.h" + +#define REG_SW_SET_PROFILING(env, value) do{ }while(0) +#define REG_SW_CLEAR_PROFILING(env, value) do{ }while(0) +#define REG_SW_CLEAR_HOSTBUF_IDX_PROFILING(env) do{ }while(0) +#define REG_SW_SET_HOSTBUF_IDX_PROFILING(env, val) do{ }while(0) +#define REG_SW_SET_PROFILING_CHAN(env, bit) do {} while (0) +#define REG_SW_CLEAR_PROFILING_CHAN(env, bit) do {} while (0) + +#undef os_printf +#define os_printf(...) do {} while(0) + +extern struct utils_list tx_list_bl; + +static const int nx_txdesc_cnt[] = +{ + NX_TXDESC_CNT0, + NX_TXDESC_CNT1, + NX_TXDESC_CNT2, + NX_TXDESC_CNT3, + #if NX_TXQ_CNT == 5 + NX_TXDESC_CNT4, + #endif +}; + +static const int nx_txdesc_cnt_msk[] = +{ + NX_TXDESC_CNT0 - 1, + NX_TXDESC_CNT1 - 1, + NX_TXDESC_CNT2 - 1, + NX_TXDESC_CNT3 - 1, + #if NX_TXQ_CNT == 5 + NX_TXDESC_CNT4 - 1, + #endif +}; + +void ipc_host_init(struct ipc_host_env_tag *env, + struct ipc_host_cb_tag *cb, + struct ipc_shared_env_tag *shared_env_ptr, + void *pthis) +{ +extern int internel_cal_size_tx_desc; +extern int internel_cal_size_tx_hdr; + bl_os_printf("[IPC] [TX] Low level size %d, driver size %d, total size %d\r\n", + internel_cal_size_tx_desc, + internel_cal_size_tx_hdr, + internel_cal_size_tx_desc + internel_cal_size_tx_hdr + ); + utils_list_init(&tx_list_bl); +#if 0 + +/** + **************************************************************************************** + * + * @file ipc_host.c + * Copyright (C) Bouffalo Lab 2016-2018 + * + **************************************************************************************** + */ + + memset(shared_env_ptr, 0, sizeof(struct ipc_shared_env_tag)); +#else +#if 0 + unsigned int * dst; + unsigned int size; + dst = (unsigned int *)shared_env_ptr; + size = (unsigned int)sizeof(struct ipc_shared_env_tag); + for (i=0; i < size; i+=4) + { + *dst++ = 0; + } +#endif +#endif + // Reset the IPC Host environment + memset(env, 0, sizeof(struct ipc_host_env_tag)); + + // Initialize the shared environment pointer + env->shared = shared_env_ptr; + + // Save the callbacks in our own environment + env->cb = *cb; + + // Save the pointer to the register base + env->pthis = pthis; + + // Initialize buffers numbers and buffers sizes needed for DMA Receptions + env->rx_bufnb = IPC_RXBUF_CNT; + env->rx_bufsz = IPC_RXBUF_SIZE; + env->rxdesc_nb = IPC_RXDESC_CNT; + env->ipc_e2amsg_bufnb = IPC_MSGE2A_BUF_CNT; + env->ipc_e2amsg_bufsz = sizeof(struct ipc_e2a_msg); + + // Initialize the pointers to the hostid arrays + env->tx_host_id = env->tx_host_id0; + + // Initialize the pointers to the TX descriptor arrays + env->txdesc = shared_env_ptr->txdesc0; + memset((void*)&(shared_env_ptr->txdesc0), 0, sizeof(shared_env_ptr->txdesc0)); +} + +int ipc_host_msg_push(struct ipc_host_env_tag *env, void *msg_buf, uint16_t len) +{ + int i; + uint32_t *src, *dst; + + REG_SW_SET_PROFILING(env->pthis, SW_PROF_IPC_MSGPUSH); + + ASSERT_ERR(!env->msga2e_hostid); + ASSERT_ERR(round_up(len, 4) <= sizeof(env->shared->msg_a2e_buf.msg)); + + // Copy the message into the IPC MSG buffer +#if 1 + src = (uint32_t*)((struct bl_cmd *)msg_buf)->a2e_msg; +#else + src = (uint32_t*) msg_buf; +#endif + dst = (uint32_t*)&(env->shared->msg_a2e_buf.msg); + + // Copy the message in the IPC queue + for (i=0; imsga2e_hostid = msg_buf; + + // Trigger the irq to send the message to EMB + ipc_app2emb_trigger_set(IPC_IRQ_A2E_MSG); + + REG_SW_CLEAR_PROFILING(env->pthis, SW_PROF_IPC_MSGPUSH); + + return 0; +} + +void ipc_host_patt_addr_push(struct ipc_host_env_tag *env, uint32_t addr) +{ + struct ipc_shared_env_tag *shared_env_ptr = env->shared; + + // Copy the address + shared_env_ptr->pattern_addr = addr; +} + +uint32_t ipc_host_get_status(struct ipc_host_env_tag *env) +{ + uint32_t status; + + // Patched: upstream passed env->shared but reg_ipc_app.h declares (). + // Other call site (line 335) already uses the no-arg form. Modern gcc + // rejects the K&R mismatch; behaviour is unchanged. + status = ipc_emb2app_status_get(); + + return status; +} + +uint32_t ipc_host_get_rawstatus(struct ipc_host_env_tag *env) +{ + uint32_t status; + + // Patched: same as above. + (void)env; + status = ipc_emb2app_rawstatus_get(); + + return status; +} + +static void ipc_host_msgack_handler(struct ipc_host_env_tag *env) +{ + void *hostid = env->msga2e_hostid; + + ASSERT_ERR(hostid); + ASSERT_ERR(env->msga2e_cnt == (((struct lmac_msg *)(&env->shared->msg_a2e_buf.msg))->src_id & 0xFF)); + + env->msga2e_hostid = NULL; + env->msga2e_cnt++; + env->cb.recv_msgack_ind(env->pthis, hostid); +} + +static void ipc_host_tx_cfm_handler(struct ipc_host_env_tag *env, const int queue_idx, const int user_pos) +{ + int ret; + bl_custom_tx_callback_t custom_tx_callback; + void *custom_tx_callback_arg; + // TX confirmation descriptors have been received + REG_SW_SET_PROFILING(env->pthis, SW_PROF_IRQ_E2A_TXCFM); + while (1) { + uint32_t used_idx = env->txdesc_used_idx; + void *host_id = env->tx_host_id[used_idx & nx_txdesc_cnt_msk[queue_idx]]; + struct pbuf *p = (struct pbuf*)host_id; + struct bl_txhdr *txhdr; + + // bl_os_log_info("[IRQ-BH] CFM handler host id: %p\r\n", host_id); + if (host_id == 0) { + // bl_os_log_info("[IRQ-BH] ipc_host_tx_cfm_handler break\r\n"); + break; + } + + // bl_os_log_info("[IRQ-BH] send_data_cfm cb\r\n"); + + txhdr = (struct bl_txhdr*)(((uint32_t)p->payload) + RWNX_HWTXHDR_ALIGN_PADS((uint32_t)p->payload)); + custom_tx_callback = txhdr->custom_cfm.cb; + custom_tx_callback_arg = txhdr->custom_cfm.cb_arg; + + ret = env->cb.send_data_cfm(env->pthis, host_id); + if (ret < 0) { + break; + } + // Reset the host id in the array + env->tx_host_id[used_idx & nx_txdesc_cnt_msk[queue_idx]] = 0; + /*current txdesc is confirmed, so increase the idx now*/ + env->txdesc_used_idx++; + + /*Notify tx status*/ + if (custom_tx_callback) { + custom_tx_callback(custom_tx_callback_arg, ret > 0); + } + + REG_SW_SET_PROFILING_CHAN(env->pthis, SW_PROF_CHAN_CTXT_CFM_HDL_BIT); + REG_SW_CLEAR_PROFILING_CHAN(env->pthis, SW_PROF_CHAN_CTXT_CFM_HDL_BIT); + } + + REG_SW_CLEAR_PROFILING(env->pthis, SW_PROF_IRQ_E2A_TXCFM); +} + +static void ipc_host_radar_handler(struct ipc_host_env_tag *env) +{ + /*empty here*/ +} + +static void ipc_host_dbg_handler(struct ipc_host_env_tag *env) +{ + // For profiling + REG_SW_SET_PROFILING(env->pthis, SW_PROF_IRQ_E2A_DBG); + + // LMAC has triggered an IT saying that a DBG message has been sent to upper layer. + // Then we first need to check the validity of the current buffer, and the validity + // of the next buffers too, because it is likely that several buffers have been + // filled within the time needed for this irq handling + // call the external function to indicate that a RX packet is received + while(env->cb.recv_dbg_ind(env->pthis, + env->ipc_host_dbgbuf_array[env->ipc_host_dbg_idx].hostid) == 0) + ; + + // For profiling + REG_SW_CLEAR_PROFILING(env->pthis, SW_PROF_IRQ_E2A_DBG); +} + +#if 1 +uint32_t used_issue = 0; +#endif + +volatile struct txdesc_host *ipc_host_txdesc_get(struct ipc_host_env_tag *env) +{ + volatile struct txdesc_host *txdesc_free; + uint32_t used_idx = env->txdesc_used_idx; + uint32_t free_idx = env->txdesc_free_idx; + + if (used_idx > free_idx) { + os_printf("[TX] used_idx case found, used:free %u:%u\r\n", used_idx, free_idx); + used_issue++; + } + + // Check if a free descriptor is available + if (free_idx != (used_idx + nx_txdesc_cnt[0])) + { + // Get the pointer to the first free descriptor + txdesc_free = env->txdesc + (free_idx & nx_txdesc_cnt_msk[0]); + if ((free_idx - used_idx) <= nx_txdesc_cnt[0]) { + /*empty here*/ + } else { + /*idx error*/ + while (1) { + os_printf("TX IPC HOST race condition\r\rn"); + } + } + } + else + { + txdesc_free = NULL; + } + return txdesc_free; +} + +int ipc_host_txdesc_left(struct ipc_host_env_tag *env, const int queue_idx, const int user_pos) +{ + uint32_t used_idx = env->txdesc_used_idx; + uint32_t free_idx = env->txdesc_free_idx; + + return nx_txdesc_cnt[queue_idx] - (free_idx - used_idx); +} + +void ipc_host_txdesc_push(struct ipc_host_env_tag *env, void *host_id) +{ + uint32_t free_idx = env->txdesc_free_idx & nx_txdesc_cnt_msk[0]; + volatile struct txdesc_host *txdesc_pushed = env->txdesc + free_idx; + + + // Descriptor is now ready + txdesc_pushed->ready = 0xFFFFFFFF; + + // Save the host id in the environment + env->tx_host_id[free_idx] = host_id; + + // Increment the index + env->txdesc_free_idx++; + + // trigger interrupt!!! + //REG_SW_SET_PROFILING(env->pthis, CO_BIT(queue_idx+SW_PROF_IRQ_A2E_TXDESC_FIRSTBIT)); + ipc_app2emb_trigger_setf(CO_BIT(IPC_IRQ_A2E_TXDESC_FIRSTBIT)); +} + +void ipc_host_irq(struct ipc_host_env_tag *env, uint32_t status) +{ + // Acknowledge the pending interrupts + ipc_emb2app_ack_clear(status); + // And re-read the status, just to be sure that the acknowledgment is + // effective when we start the interrupt handling + // XXX status reload + status |= ipc_emb2app_status_get(); + + // Optimized for only one IRQ at a time + if (status & IPC_IRQ_E2A_TXCFM) + { + int i; + + os_printf("[IRQ-BH] IPC_IRQ_E2A_TXCFM\r\n"); +#if 0 + spin_lock(&((struct bl_hw *)env->pthis)->tx_lock); +#endif + // handle the TX confirmation reception + for (i = 0; i < IPC_TXQUEUE_CNT; i++) { + uint32_t q_bit = CO_BIT(i + IPC_IRQ_E2A_TXCFM_POS); + if (status & q_bit) { + // handle the confirmation + os_printf("[IRQ-BH] CFM handler\r\n"); + ipc_host_tx_cfm_handler(env, i, 0); + } + } +#if 0 + spin_unlock(&((struct bl_hw *)env->pthis)->tx_lock); +#endif + } + void bl_tx_resend(void); + bl_tx_resend(); + + if (status & IPC_IRQ_E2A_RXDESC) { + os_printf("[IRQ-BH] IPC_IRQ_E2A_RXDESC\r\n"); + } + if (status & IPC_IRQ_E2A_MSG_ACK) { + os_printf("[IRQ-BH] IPC_IRQ_E2A_MSG_ACK\r\n"); + ipc_host_msgack_handler(env); + } + if (status & IPC_IRQ_E2A_RADAR) { + os_printf("[IRQ-BH] IPC_IRQ_E2A_RADAR\r\n"); + ipc_host_radar_handler(env); + } + if (status & IPC_IRQ_E2A_DBG) { + os_printf("[IRQ-BH] IPC_IRQ_E2A_DBG\r\n"); + ipc_host_dbg_handler(env); + } + if (status & IPC_IRQ_E2A_TBTT_PRIM) { + os_printf("[IRQ-BH] IPC_IRQ_E2A_TBTT_PRIM\r\n"); + env->cb.prim_tbtt_ind(env->pthis); + } + if (status & IPC_IRQ_E2A_TBTT_SEC) { + os_printf("[IRQ-BH] IPC_IRQ_E2A_TBTT_SEC\r\n"); + env->cb.sec_tbtt_ind(env->pthis); + } +} + +void ipc_host_enable_irq(struct ipc_host_env_tag *env, uint32_t value) +{ + // Enable the handled interrupts + ipc_emb2app_unmask_set(value); +} + +void ipc_host_disable_irq(struct ipc_host_env_tag *env, uint32_t value) +{ + // Enable the handled interrupts + ipc_emb2app_unmask_clear(value); +} + +void ipc_host_disable_irq_e2a(void) +{ + ipc_emb2app_unmask_clear(IPC_IRQ_E2A_ALL); +} + diff --git a/platforms/bl808_m0/vendor/wifi/src/utils_list.c b/platforms/bl808_m0/vendor/wifi/src/utils_list.c new file mode 100644 index 0000000..59c6d3a --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/src/utils_list.c @@ -0,0 +1,365 @@ + +/* + * Copyright (c) 2016-2022 Bouffalolab. + * + * This file is part of + * *** Bouffalolab Software Dev Kit *** + * (see www.bouffalolab.com). + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include +#include +#include + +void utils_list_init(struct utils_list *list) +{ + list->first = NULL; + list->last = NULL; +} + +void utils_list_pool_init(struct utils_list *list, void *pool, size_t elmt_size, unsigned int elmt_cnt, void *default_value) +{ + unsigned int i; + + // initialize the free list relative to the pool + utils_list_init(list); + + // Add each element of the pool to this list, and init them one by one + for (i = 0; i < elmt_cnt; i++) { + if (default_value) + { + memcpy(pool, default_value, elmt_size); + } + utils_list_push_back(list, (struct utils_list_hdr *) pool); + + // move to the next pool element + pool = (void *)((uint8_t *)pool + (unsigned int)elmt_size); + } +} + +void utils_list_push_back(struct utils_list *list, struct utils_list_hdr *list_hdr) +{ + // Sanity check + // FIXME assert error here + //ASSERT_ERR(list_hdr != NULL); + + // check if list is empty + if (utils_list_is_empty(list)) + { + // list empty => pushed element is also head + list->first = list_hdr; + } + else + { + // list not empty => update next of last + list->last->next = list_hdr; + } + + // add element at the end of the list + list->last = list_hdr; + list_hdr->next = NULL; +} + +void utils_list_push_front(struct utils_list *list, struct utils_list_hdr *list_hdr) +{ + // Sanity check + // FIXME assert error here + //ASSERT_ERR(list_hdr != NULL); + + // check if list is empty + if (utils_list_is_empty(list)) + { + // list empty => pushed element is also head + list->last = list_hdr; + } + + // add element at the beginning of the list + list_hdr->next = list->first; + list->first = list_hdr; +} + +struct utils_list_hdr *utils_list_pop_front(struct utils_list *list) +{ + struct utils_list_hdr *element; + + // check if list is empty + element = list->first; + if (element != NULL) + { + // The list isn't empty : extract the first element + list->first = list->first->next; + } + + return element; +} + +void utils_list_extract(struct utils_list *list, struct utils_list_hdr *list_hdr) +{ + struct utils_list_hdr *scan_list; + + // sanity check + // FIXME assert error here + //ASSERT_ERR(list != NULL); + + scan_list = list->first; + + // Check if list is empty or not + if (scan_list == NULL) + return; + + // check if searched element is first + if (scan_list == list_hdr) + { + // Extract first element + list->first = scan_list->next; + } + else + { + // Look for the element in the list + while ((scan_list->next != NULL) && (scan_list->next != list_hdr)) + { + scan_list = scan_list->next; + } + + // Check if element was found in the list + if (scan_list->next != NULL) + { + // check if the removed element is the last in the list + if (list->last == list_hdr) + { + // Last element will be extracted + list->last = scan_list; + } + // Extract the element from the list + scan_list->next = list_hdr->next; + } + } +} + +int utils_list_find(struct utils_list *list, struct utils_list_hdr *list_hdr) +{ + struct utils_list_hdr *tmp_list_hdr; + + // Go through the list to find the element + tmp_list_hdr = list->first; + while((tmp_list_hdr != list_hdr) && (tmp_list_hdr != NULL)) + { + tmp_list_hdr = tmp_list_hdr->next; + } + + return (tmp_list_hdr == list_hdr); +} + +unsigned int utils_list_cnt(const struct utils_list *const list) +{ + unsigned int cnt = 0; + struct utils_list_hdr *elt = utils_list_pick(list); + + // Go through the list to count the number of elements + while (elt != NULL) + { + cnt++; + elt = utils_list_next(elt); + } + + return(cnt); +} + +/** + **************************************************************************************** + * @brief Insert an element in a sorted list. + * + * This primitive use a comparison function from the parameter list to select where the + * element must be inserted. + * + * @param[in] list Pointer to the list. + * @param[in] element Pointer to the element to insert. + * @param[in] cmp Comparison function (return true if first element has to be inserted + * before the second one). + * + * @return Pointer to the element found and removed (NULL otherwise). + **************************************************************************************** + */ +void utils_list_insert(struct utils_list * const list, struct utils_list_hdr * const element, + int (*cmp)(struct utils_list_hdr const *elementA, struct utils_list_hdr const *elementB)) +{ + struct utils_list_hdr *prev = NULL; + struct utils_list_hdr *scan = list->first; + + for(;;) + { + // scan the list until the end or cmp() returns true + if (scan) + { + if (cmp(element, scan)) + { + // insert now + break; + } + prev = scan; + scan = scan->next; + } + else + { + // end of list + list->last = element; + break; + } + } + + element->next = scan; + + if (prev) + { + // second or more + prev->next = element; + } + else + { + // first message + list->first = element; + } +} + +void utils_list_insert_after(struct utils_list * const list, struct utils_list_hdr * const prev_element, struct utils_list_hdr * const element) +{ + struct utils_list_hdr *scan = list->first; + + if (prev_element == NULL) + { + // Insert the element in front on the list + utils_list_push_front(list, element); + } + else + { + // Look for prev_element in the list + while (scan) + { + if (scan == prev_element) + { + break; + } + + // Get next element + scan = scan->next; + } + + // If prev_element has been found, insert element + if (scan) + { + element->next = prev_element->next; + prev_element->next = element; + + if (element->next == NULL) + { + list->last = element; + } + } + } +} + +void utils_list_insert_before(struct utils_list * const list, struct utils_list_hdr * const next_element, struct utils_list_hdr * const element) +{ + if (next_element == NULL) + { + // Insert the element at the end of the list + utils_list_push_back(list, element); + } + else if (next_element == list->first) + { + // Insert the element in front of the list + utils_list_push_front(list, element); + } + else + { + struct utils_list_hdr *scan = list->first; + + // Look for next_element in the list + while (scan) + { + if (scan->next == next_element) + { + break; + } + + // Get next element + scan = scan->next; + } + + // Insert element after scan + if (scan) + { + element->next = next_element; + scan->next = element; + } + } +} + +void utils_list_concat(struct utils_list *list1, struct utils_list *list2) +{ + // If list2 is empty, don't do anything + if (list2->first != NULL) + { + // Check if list1 is empty + if (list1->first == NULL) + { + // If list1 is empty, list1 becomes list2 + *list1 = *list2; + } + else + { + // Otherwise, append list2 to list1 + list1->last->next = list2->first; + list1->last = list2->last; + } + // Clear list2 + list2->first = NULL; + } +} + + +void utils_list_remove(struct utils_list *list, struct utils_list_hdr *prev_element, struct utils_list_hdr *element) +{ + // sanity check + // FIXME assert error here + //ASSERT_ERR(list != NULL); + //ASSERT_ERR((prev_element == NULL) || (prev_element->next == element)); + //ASSERT_ERR(element != NULL); + + + if (prev_element == NULL) + { + list->first = element->next; + } + else + { + prev_element->next = element->next; + if (list->last == element) + list->last = prev_element; + } + + element->next = NULL; +} diff --git a/platforms/bl808_m0/vendor/wifi/src/utils_tlv_bl.c b/platforms/bl808_m0/vendor/wifi/src/utils_tlv_bl.c new file mode 100644 index 0000000..0ec23c4 --- /dev/null +++ b/platforms/bl808_m0/vendor/wifi/src/utils_tlv_bl.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2016-2022 Bouffalolab. + * + * This file is part of + * *** Bouffalolab Software Dev Kit *** + * (see www.bouffalolab.com). + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of Bouffalo Lab nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "utils_tlv_bl.h" + +int utils_tlv_bl_pack_bool(uint32_t *buf, int buf_sz, bool val) +{ + if (buf_sz < CFG_ELEMENT_TYPE_SIZE_BOOLEAN) { + return UTILS_TLV_BL_ERROR_CODE_BUF_TOO_SMALL; + } + *buf = val;//XXX caution for unaligned access + + return CFG_ELEMENT_TYPE_SIZE_BOOLEAN; +} + +int utils_tlv_bl_pack_uint32(uint32_t *buf, int buf_sz, uint32_t val) +{ + if (buf_sz < CFG_ELEMENT_TYPE_SIZE_UINT32) { + return UTILS_TLV_BL_ERROR_CODE_BUF_TOO_SMALL; + } + *buf = val;//XXX caution for unaligned access + + return CFG_ELEMENT_TYPE_SIZE_UINT32; +} + +int utils_tlv_bl_unpack_bool(uint32_t *buf, int buf_sz, bool *val) +{ + if (buf_sz < CFG_ELEMENT_TYPE_SIZE_BOOLEAN) { + return UTILS_TLV_BL_ERROR_CODE_BUF_TOO_SMALL; + } + *val = (*buf) ? true : false;// XXX caution for unaligned access + + return CFG_ELEMENT_TYPE_SIZE_BOOLEAN; +} + +int utils_tlv_bl_unpack_uint32(uint32_t *buf, int buf_sz, uint32_t *val) +{ + if (buf_sz < CFG_ELEMENT_TYPE_SIZE_UINT32) { + return UTILS_TLV_BL_ERROR_CODE_BUF_TOO_SMALL; + } + *val = (*buf);//XXX caution for unaligned access + + return CFG_ELEMENT_TYPE_SIZE_BOOLEAN; +} + +int utils_tlv_bl_pack_auto(uint32_t *buf, int buf_sz, uint16_t type, void *arg1) +{ + int ret = UTILS_TLV_BL_ERROR_CODE_UNKOWN; + + switch (type) { + case CFG_ELEMENT_TYPE_BOOLEAN: + { + ret = utils_tlv_bl_pack_bool(buf, buf_sz, *(bool*)arg1 ? true : false); + } + break; + case CFG_ELEMENT_TYPE_SINT8: + { + //TODO + } + break; + case CFG_ELEMENT_TYPE_UINT8: + { + //TODO + } + break; + case CFG_ELEMENT_TYPE_SINT16: + { + //TODO + } + break; + case CFG_ELEMENT_TYPE_UINT16: + { + //TODO + } + break; + case CFG_ELEMENT_TYPE_SINT32: + { + //TODO + } + break; + case CFG_ELEMENT_TYPE_UINT32: + { + ret = utils_tlv_bl_pack_uint32(buf, buf_sz, *(uint32_t*)arg1); + } + break; + case CFG_ELEMENT_TYPE_STRING: + { + //TODO + } + break; + default: + { + /*empty*/ + } + } + + return ret; +} + +int utils_tlv_bl_unpack_auto(uint32_t *buf, int buf_sz, uint16_t type, void *arg1) +{ + int ret = UTILS_TLV_BL_ERROR_CODE_UNKOWN; + + switch (type) { + case CFG_ELEMENT_TYPE_BOOLEAN: + { + bool val = true; + + ret = utils_tlv_bl_unpack_bool(buf, buf_sz, &val); + *(bool*)arg1 = val; + } + break; + case CFG_ELEMENT_TYPE_SINT8: + { + //TODO + } + break; + case CFG_ELEMENT_TYPE_UINT8: + { + //TODO + } + break; + case CFG_ELEMENT_TYPE_SINT16: + { + //TODO + } + break; + case CFG_ELEMENT_TYPE_UINT16: + { + //TODO + } + break; + case CFG_ELEMENT_TYPE_SINT32: + { + //TODO + } + break; + case CFG_ELEMENT_TYPE_UINT32: + { + uint32_t val = 0; + + ret = utils_tlv_bl_unpack_uint32(buf, buf_sz, &val); + *(uint32_t*)arg1 = val; + } + break; + case CFG_ELEMENT_TYPE_STRING: + { + //TODO + } + break; + default: + { + /*empty*/ + } + } + + return ret; +} diff --git a/platforms/rp2350/README.txt b/platforms/rp2350/README.txt new file mode 100644 index 0000000..f0212e7 --- /dev/null +++ b/platforms/rp2350/README.txt @@ -0,0 +1,90 @@ +RP2350 (Raspberry Pi) -- dual Cortex-M33 @ 150 MHz +================================================== + +520 KB SRAM, XIP from external QSPI flash. URT targets the Arm cores +(the chip also has dual Hazard3 RISC-V cores selectable at boot; URT +does not currently support that mode). + +Reference board: Raspberry Pi Pico 2. + +Setup +----- + +Toolchain (Ubuntu 22.04+): + + # D compiler -- LDC with the official upstream build. + curl -fsS https://dlang.org/install.sh | bash -s ldc + source ~/dlang/ldc-*/activate + + # ARM cross-toolchain and picolibc. + sudo apt-get install gcc-arm-none-eabi picolibc-arm-none-eabi + +Flash tool (picotool, for ELF -> UF2 conversion): + + sudo apt-get install build-essential cmake libusb-1.0-0-dev + git clone https://github.com/raspberrypi/picotool + cd picotool && mkdir build && cd build && cmake .. && make + sudo cp picotool /usr/local/bin/ + +Pre-built picotool binaries are also published at +https://github.com/raspberrypi/pico-sdk-tools/releases for those who +don't want to build from source. + +Windows: LDC installer from https://github.com/ldc-developers/ldc/releases; +ARM GNU Toolchain installer from +https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads; +picotool prebuilt from the pico-sdk-tools releases page noted above. + +Build the unittest image +------------------------ + +From the URT root: + + make PLATFORM=rp2350 CONFIG=unittest + +Outputs (in bin/rp2350_unittest/): + + urt_test ELF with debug symbols + urt_test.bin Raw binary + +Toolchain required: ldc, gcc-arm-none-eabi, picolibc-arm-none-eabi. +Linker script: rp2350.ld. + +Flash +----- + +The RP2350 has a USB mass-storage bootloader -- hold BOOTSEL while +plugging in USB to enter it. Drag-and-drop a .uf2 file onto the +mounted RPI-RP2 volume. + +Convert urt_test (the ELF, not the .bin) to UF2: + + picotool uf2 convert bin/rp2350_unittest/urt_test \ + bin/rp2350_unittest/urt_test.uf2 \ + --family rp2350-arm-s + +(Install picotool from https://github.com/raspberrypi/picotool.) + +Then drop urt_test.uf2 onto the RPI-RP2 volume. The board reboots and +runs immediately. + +Alternatively, flash directly via SWD with openocd + the Pi-supplied +config files (slower; UF2 is the path of least resistance). + +Console +------- + +UART0 (GP0=TX, GP1=RX on the Pico 2 header), 115200 baud, 8N1. Or use +the picoprobe firmware on a second Pico for SWD + virtual UART. + +The unittest harness prints results and halts. Tap RESET (or unplug/ +replug USB) to re-run. + +Notes +----- + +* boot2.S is included in URT's start sources -- a second-stage bootloader + that configures XIP for the QSPI flash chip on the Pico 2 board. Other + boards with different flash chips may need a different boot2. +* The RP2350 has secure/non-secure split (TrustZone-M). URT runs + entirely in secure mode; non-secure callable veneers are not set up. diff --git a/platforms/rp2350/rp2350.ld b/platforms/rp2350/rp2350.ld new file mode 100644 index 0000000..740a0fe --- /dev/null +++ b/platforms/rp2350/rp2350.ld @@ -0,0 +1,155 @@ +/* RP2350 (ARM Cortex-M33) linker script + * + * Raspberry Pi RP2350B — dual Cortex-M33 @ 150MHz, 520KB SRAM, XIP QSPI flash. + * + * Memory layout: + * BOOT2: 0x10000000, 256B (second-stage bootloader, copied to SRAM by ROM) + * FLASH: 0x10000100, ~4MB (XIP execute-in-place, read-only) + * SRAM: 0x20000000, 520KB (8 banks x 64KB + 8KB scratch) + * + * The RP2350 ROM loads the 256-byte boot2 block from the start of flash, + * executes it from SRAM to configure the QSPI interface, then jumps to + * the vector table at the start of .text. + */ + +ENTRY(Reset_Handler) + +/* Force-link newlib syscall stubs and D runtime symbols */ +EXTERN(_write _read _close _lseek _fstat _isatty _sbrk _exit _kill _getpid) +EXTERN(_Dmodule_ref __errno_location stdout) + +MEMORY +{ + /* Second-stage bootloader — first 256 bytes of flash */ + BOOT2 (rx) : ORIGIN = 0x10000000, LENGTH = 256 + /* Application flash — XIP, code and read-only data */ + FLASH (rx) : ORIGIN = 0x10000100, LENGTH = 4M - 256 + /* SRAM — all 8 banks contiguous (banks 0-7: 8 x 64KB = 512KB) + 8KB scratch */ + SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 520K +} + +SECTIONS +{ + /* Boot2 — second-stage bootloader for QSPI flash init */ + .boot2 : ALIGN(4) + { + KEEP(*(.boot2)) + } > BOOT2 + + /* Vector table must be first in FLASH (right after boot2) */ + .vector_table : ALIGN(4) + { + KEEP(*(.vector_table)) + } > FLASH + + .text : ALIGN(4) + { + *(.text .text.*) + } > FLASH + + .rodata : ALIGN(8) + { + *(.rodata .rodata.*) + } > FLASH + + .eh_frame : ALIGN(8) + { + __eh_frame_start = .; + KEEP(*(.eh_frame)) + KEEP(*(.eh_frame_hdr)) + } > FLASH + + .gcc_except_table : ALIGN(4) + { + *(.gcc_except_table .gcc_except_table.*) + } > FLASH + + .init_array : ALIGN(4) + { + __init_array_start = .; + KEEP(*(.init_array)) + __init_array_end = .; + } > FLASH + + /* ARM exception unwind tables */ + .ARM.exidx : ALIGN(4) + { + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } > FLASH + + .ARM.extab : ALIGN(4) + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + /* GOT in SRAM for fast access — LMA in FLASH, copied at startup */ + .got : ALIGN(4) + { + _got_load = LOADADDR(.got); + _got_start = .; + *(.got .got.*) + *(.got.plt) + _got_end = .; + } > SRAM AT > FLASH + + /* Initialized data — LMA in FLASH, copied to SRAM at startup */ + .data : ALIGN(4) + { + _data_start = .; + *(.data .data.*) + _data_end = .; + } > SRAM AT > FLASH + + _data_load = LOADADDR(.data); + __ram_load_addr = _data_load; + __ram_data_start__ = _data_start; + __ram_data_end__ = _data_end; + + /* Thread-local initialized data — LMA in FLASH, copied to SRAM at startup */ + .tdata : ALIGN(4) + { + _tdata_start = .; + *(.tdata .tdata.*) + _tdata_end = .; + } > SRAM AT > FLASH + + _tdata_load = LOADADDR(.tdata); + + /* Thread-local zero-initialized data */ + .tbss (NOLOAD) : ALIGN(4) + { + _tbss_start = .; + *(.tbss .tbss.*) + _tbss_end = .; + } > SRAM + + /* Zero-initialized data */ + .bss (NOLOAD) : ALIGN(4) + { + __bss_start__ = .; + _bss_start = .; + *(.bss .bss.*) + *(COMMON) + _bss_end = .; + __bss_end__ = .; + } > SRAM + + /* Heap grows up from end of BSS */ + __heap_start = _bss_end; + __heap_end = ORIGIN(SRAM) + LENGTH(SRAM) - 4K; + + /* Stack at top of SRAM (4KB reserved) */ + _stack_top = ORIGIN(SRAM) + LENGTH(SRAM); + _stack_low = ORIGIN(SRAM); + __StackTop = _stack_top; + + /DISCARD/ : + { + *(.comment) + *(.note.*) + *(.gnu.hash) + *(.gnu.linkonce.*) + } +} diff --git a/platforms/stm32/README.txt b/platforms/stm32/README.txt new file mode 100644 index 0000000..58161de --- /dev/null +++ b/platforms/stm32/README.txt @@ -0,0 +1,105 @@ +STM32 (STMicroelectronics) -- Cortex-M4F / Cortex-M7F +===================================================== + +Two PLATFORM aliases supported: + + stm4xx STM32F4 family (Cortex-M4F, FPv4-SP-D16) + stm7xx STM32F7 family (Cortex-M7F, FPv5-D16) + +Linker scripts: stm32_f4.ld and stm32_f7.ld respectively. Each is a +generic-ish memory map -- override flash/RAM sizes in the script if +your specific part has more or less than the defaults. + +Setup +----- + +Toolchain (Ubuntu 22.04+): + + # D compiler -- LDC with the official upstream build. + curl -fsS https://dlang.org/install.sh | bash -s ldc + source ~/dlang/ldc-*/activate + + # ARM cross-toolchain and picolibc. + sudo apt-get install gcc-arm-none-eabi picolibc-arm-none-eabi + +Flash tools (pick one; you do not need all three): + + # ST-LINK + STM32CubeProgrammer -- official ST tool, GUI + CLI. + # Download from https://www.st.com/en/development-tools/stm32cubeprog.html + # (free with registration). Adds STM32_Programmer_CLI to PATH. + + # OpenOCD with ST-LINK or J-Link -- open-source. + sudo apt-get install openocd + + # dfu-util for the ROM bootloader path. + sudo apt-get install dfu-util + +Windows: LDC installer from https://github.com/ldc-developers/ldc/releases; +ARM GNU Toolchain installer from +https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads; +STM32CubeProgrammer Windows installer (it also ships the ST-LINK USB +drivers, which you will need separately on first connect even with +OpenOCD). + +Build the unittest image +------------------------ + +From the URT root: + + make PLATFORM=stm4xx CONFIG=unittest + make PLATFORM=stm7xx CONFIG=unittest + +Outputs: + + bin/stm4xx_unittest/urt_test.bin + bin/stm7xx_unittest/urt_test.bin + +Toolchain required: ldc, gcc-arm-none-eabi, picolibc-arm-none-eabi. + +Flash +----- + +Three common paths: + +1. ST-LINK + STM32CubeProgrammer (GUI or CLI): + + STM32_Programmer_CLI -c port=SWD -d bin/stm4xx_unittest/urt_test.bin 0x08000000 -rst + +2. openocd + ST-LINK or J-Link: + + openocd -f interface/stlink.cfg -f target/stm32f4x.cfg \ + -c "program bin/stm4xx_unittest/urt_test.bin 0x08000000 verify reset exit" + + (Use target/stm32f7x.cfg for stm7xx.) + +3. DFU bootloader (ROM-resident on most parts): + + dfu-util -a 0 -s 0x08000000 -D bin/stm4xx_unittest/urt_test.bin + + Requires entering DFU mode -- typically BOOT0 high at reset. + +The reset vector and image base are at 0x08000000 in all three cases +(internal flash bank 1). + +Console +------- + +USART2 by default (PA2=TX, PA3=RX on most Nucleo and Discovery boards; +exposed via the ST-LINK USB-CDC bridge). 115200 baud, 8N1. Some boards +mux the ST-LINK VCP to USART3 instead; check the board user manual. + +The unittest harness prints results and halts. Tap RESET to re-run. + +Notes +----- + +* The default linker script assumes 1 MB flash + 192 KB RAM (a common + F4/F7 mid-range part). Edit the MEMORY block in stm32_f4.ld or + stm32_f7.ld for your specific MCU. +* No HAL, no LL drivers, no CubeMX -- URT brings its own start.S, + vector table stub, and minimal UART driver. If you need on-chip + peripherals beyond UART you will need to write them or pull in the + vendor headers manually. +* MFPU defaults: F4 = fpv4-sp-d16 (single-precision only), F7 = + fpv5-d16 (double-precision). The Makefile picks these per + STM32_VARIANT; override with MFPU=... if your part differs. diff --git a/platforms/stm32/stm32_f4.ld b/platforms/stm32/stm32_f4.ld new file mode 100644 index 0000000..6abcc35 --- /dev/null +++ b/platforms/stm32/stm32_f4.ld @@ -0,0 +1,147 @@ +/* STM32F4 (ARM Cortex-M4) linker script + * + * Default memory map for STM32F407VG (Discovery board): + * FLASH: 1MB at 0x08000000 + * RAM: 128KB at 0x20000000 (SRAM1 112KB + SRAM2 16KB contiguous) + * + * STM32F4 also has 64KB CCM RAM at 0x10000000 (no DMA access). + * Not used here -- add a DTCM region if you need it for stack/GOT. + * + * Adjust MEMORY sizes for your specific F4 variant. + */ + +ENTRY(Reset_Handler) + +EXTERN(_write _read _close _lseek _fstat _isatty _sbrk _exit _kill _getpid) +EXTERN(_Dmodule_ref __errno_location stdout) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1M + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K +} + +SECTIONS +{ + .vector_table : ALIGN(4) + { + KEEP(*(.vector_table)) + } > FLASH + + .text : ALIGN(4) + { + *(.text .text.*) + } > FLASH + + .rodata : ALIGN(8) + { + *(.rodata .rodata.*) + } > FLASH + + .eh_frame : ALIGN(8) + { + __eh_frame_start = .; + KEEP(*(.eh_frame)) + KEEP(*(.eh_frame_hdr)) + } > FLASH + + .gcc_except_table : ALIGN(4) + { + *(.gcc_except_table .gcc_except_table.*) + } > FLASH + + .init_array : ALIGN(4) + { + __init_array_start = .; + KEEP(*(.init_array)) + __init_array_end = .; + } > FLASH + + .ARM.exidx : ALIGN(4) + { + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } > FLASH + + .ARM.extab : ALIGN(4) + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + /* GOT in RAM for fast access -- LMA in FLASH, copied at startup */ + .got : ALIGN(4) + { + _got_load = LOADADDR(.got); + _got_start = .; + *(.got .got.*) + *(.got.plt) + _got_end = .; + } > RAM AT > FLASH + + /* Initialized data -- LMA in FLASH, copied to RAM at startup */ + .data : ALIGN(4) + { + _data_start = .; + *(.data .data.*) + _data_end = .; + } > RAM AT > FLASH + + _data_load = LOADADDR(.data); + __ram_load_addr = _data_load; + __ram_data_start__ = _data_start; + __ram_data_end__ = _data_end; + + /* @fast_data maps to .data on F4 (no DTCM region), so there is no + * .dtcm_data section. Define the symbols the shared startup copies as an + * empty range so its copy loop is a no-op here. */ + _dtcm_data_start = .; + _dtcm_data_end = .; + _dtcm_data_load = .; + + /* Thread-local initialized data -- LMA in FLASH, copied to RAM at startup */ + .tdata : ALIGN(4) + { + _tdata_start = .; + *(.tdata .tdata.*) + _tdata_end = .; + } > RAM AT > FLASH + + _tdata_load = LOADADDR(.tdata); + + /* Thread-local zero-initialized data */ + .tbss (NOLOAD) : ALIGN(4) + { + _tbss_start = .; + *(.tbss .tbss.*) + _tbss_end = .; + } > RAM + + /* Zero-initialized data */ + .bss (NOLOAD) : ALIGN(4) + { + __bss_start__ = .; + _bss_start = .; + *(.bss .bss.*) + *(COMMON) + _bss_end = .; + __bss_end__ = .; + } > RAM + + /* Heap grows up from end of BSS */ + __heap_start = _bss_end; + __heap_end = ORIGIN(RAM) + LENGTH(RAM) - 4K; + + /* Stack at top of RAM (4KB reserved) */ + _stack_top = ORIGIN(RAM) + LENGTH(RAM); + _stack_low = ORIGIN(RAM); + __StackTop = _stack_top; + + /DISCARD/ : + { + *(.comment) + *(.note.*) + *(.gnu.hash) + *(.gnu.linkonce.*) + } +} diff --git a/platforms/stm32/stm32_f7.ld b/platforms/stm32/stm32_f7.ld new file mode 100644 index 0000000..290abfb --- /dev/null +++ b/platforms/stm32/stm32_f7.ld @@ -0,0 +1,155 @@ +/* STM32F7 (ARM Cortex-M7) linker script + * + * Default memory map for STM32F746NG (Discovery board): + * FLASH: 1MB at 0x08000000 + * DTCM: 64KB at 0x20000000 (tightly-coupled, fast, no DMA) + * RAM: 256KB at 0x20010000 (SRAM1 240KB + SRAM2 16KB contiguous) + * + * DTCM is used for stack and GOT (zero-wait-state single-cycle access). + * Main RAM is used for .data, .bss, and heap. + * + * Adjust MEMORY sizes for your specific F7 variant. + */ + +ENTRY(Reset_Handler) + +EXTERN(_write _read _close _lseek _fstat _isatty _sbrk _exit _kill _getpid) +EXTERN(_Dmodule_ref __errno_location stdout) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1M + DTCM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 256K +} + +SECTIONS +{ + .vector_table : ALIGN(4) + { + KEEP(*(.vector_table)) + } > FLASH + + .text : ALIGN(4) + { + *(.text .text.*) + } > FLASH + + .rodata : ALIGN(8) + { + *(.rodata .rodata.*) + } > FLASH + + .eh_frame : ALIGN(8) + { + __eh_frame_start = .; + KEEP(*(.eh_frame)) + KEEP(*(.eh_frame_hdr)) + } > FLASH + + .gcc_except_table : ALIGN(4) + { + *(.gcc_except_table .gcc_except_table.*) + } > FLASH + + .init_array : ALIGN(4) + { + __init_array_start = .; + KEEP(*(.init_array)) + __init_array_end = .; + } > FLASH + + .ARM.exidx : ALIGN(4) + { + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } > FLASH + + .ARM.extab : ALIGN(4) + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + /* GOT in DTCM for fast access -- LMA in FLASH, copied at startup */ + .got : ALIGN(4) + { + _got_load = LOADADDR(.got); + _got_start = .; + *(.got .got.*) + *(.got.plt) + _got_end = .; + } > DTCM AT > FLASH + + /* Initialized data -- LMA in FLASH, copied to RAM at startup */ + .data : ALIGN(4) + { + _data_start = .; + *(.data .data.*) + _data_end = .; + } > RAM AT > FLASH + + _data_load = LOADADDR(.data); + __ram_load_addr = _data_load; + __ram_data_start__ = _data_start; + __ram_data_end__ = _data_end; + + /* @fast_data lands here on F7 -- DTCM for zero-wait access, LMA in FLASH, + * copied to DTCM at startup. Without an explicit home this is an orphan + * with LMA in RAM, which makes objcopy span flash..RAM and emit a + * multi-hundred-MB .bin. */ + .dtcm_data : ALIGN(4) + { + _dtcm_data_start = .; + *(.dtcm_data .dtcm_data.*) + _dtcm_data_end = .; + } > DTCM AT > FLASH + + _dtcm_data_load = LOADADDR(.dtcm_data); + + /* Thread-local initialized data in DTCM -- LMA in FLASH */ + .tdata : ALIGN(4) + { + _tdata_start = .; + *(.tdata .tdata.*) + _tdata_end = .; + } > DTCM AT > FLASH + + _tdata_load = LOADADDR(.tdata); + + /* Thread-local zero-initialized data */ + .tbss (NOLOAD) : ALIGN(4) + { + _tbss_start = .; + *(.tbss .tbss.*) + _tbss_end = .; + } > DTCM + + /* Zero-initialized data */ + .bss (NOLOAD) : ALIGN(4) + { + __bss_start__ = .; + _bss_start = .; + *(.bss .bss.*) + *(COMMON) + _bss_end = .; + __bss_end__ = .; + } > RAM + + /* Heap grows up from end of BSS in RAM */ + __heap_start = _bss_end; + __heap_end = ORIGIN(RAM) + LENGTH(RAM); + + /* Stack at top of DTCM (fast access) */ + _stack_top = ORIGIN(DTCM) + LENGTH(DTCM); + _stack_low = ORIGIN(DTCM); + __StackTop = _stack_top; + + /DISCARD/ : + { + *(.comment) + *(.note.*) + *(.gnu.hash) + *(.gnu.linkonce.*) + } +} diff --git a/src/core/atomic.d b/src/core/atomic.d new file mode 100644 index 0000000..5d5eb04 --- /dev/null +++ b/src/core/atomic.d @@ -0,0 +1,15 @@ +// Shadows LDC's core.atomic with non-intrinsic implementations. +// LDC's version uses LLVM atomic intrinsics (llvm_atomic_rmw_add etc.) which +// require hardware atomic support. Targets without native atomics (e.g. Xtensa) +// crash in LLVM instruction selection. This module provides plain load/store +// equivalents that are correct for single-core / cooperative-multitasking targets. +// +// Only included when uRT's import path (-I) precedes LDC's (post-switches). + +module core.atomic; + +nothrow @nogc @safe: + +public import urt.atomic : MemoryOrder, cas, + atomicLoad, atomicStore, atomicOp, atomicExchange, + atomicFetchAdd, atomicFetchSub, TailShared; diff --git a/src/object.d b/src/object.d new file mode 100644 index 0000000..a075132 --- /dev/null +++ b/src/object.d @@ -0,0 +1,1796 @@ +// Minimal object.d - replaces druntime's implicit root module. +// +// This file is the auditing frontier: every symbol added here is a +// symbol the compiler or linker demanded. Keep it as small as possible. +module object; + +static assert(__VERSION__ >= 2112, + "uRT requires DMD frontend 2.112+ (DMD ≥2.112, LDC ≥1.42). " ~ + "Older frontends use TypeInfo-based AA hooks incompatible with uRT's template-based AAs."); + +// ---------------------------------------------------------------------- +// Platform-dependent ABI flags (must match druntime's detection) +// ---------------------------------------------------------------------- + +version (X86_64) +{ + version (DigitalMars) version = WithArgTypes; + else version (Windows) {} // Win64 ABI doesn't need argTypes + else version = WithArgTypes; +} +else version (AArch64) +{ + version (OSX) {} + else version (iOS) {} + else version (TVOS) {} + else version (WatchOS) {} + else version = WithArgTypes; +} + +// ---------------------------------------------------------------------- +// Fundamental type aliases (compiler hardcodes references to these) +// ---------------------------------------------------------------------- + +alias size_t = typeof(int.sizeof); +alias ptrdiff_t = typeof(cast(void*)0 - cast(void*)0); +alias nullptr_t = typeof(null); +alias noreturn = typeof(*null); + +// needed so druntime's core.stdc.stdio compiles on AArch64 +version (AArch64) +{ + extern(C++, std) struct __va_list + { + void* __stack; + void* __gr_top; + void* __vr_top; + int __gr_offs; + int __vr_offs; + } +} + +version (Windows) + alias wchar wchar_t; +else version (Posix) + alias dchar wchar_t; +else version (WASI) + alias dchar wchar_t; +else version (FreeStanding) + alias dchar wchar_t; + +alias string = immutable(char)[]; +alias wstring = immutable(wchar)[]; +alias dstring = immutable(dchar)[]; + +alias hash_t = size_t; + +// Required by __importc_builtins.di for lazy module references in ImportC. +template imported(string name) +{ + mixin("import imported = " ~ name ~ ";"); +} + +// ---------------------------------------------------------------------- +// Primitive tools +// ---------------------------------------------------------------------- + +// TODO: move the functions here so object doesn't import these modules... +public import urt.lifetime : move, forward; +public import urt.meta : Alias, AliasSeq; +public import urt.util : min, max, swap; + +//alias Alias(alias a) = a; +//alias Alias(T) = T; +// +//alias AliasSeq(TList...) = TList; +// +//T min(T)(T a, T b) pure nothrow @nogc @safe +// => b < a ? b : a; +// +//T max(T)(T a, T b) pure nothrow @nogc @safe +// => b > a ? b : a; +// +//ref T swap(T)(ref T a, return ref T b) +//{ +// import urt.lifetime : move, moveEmplace; +// +// T t = a.move; +// b.move(a); +// t.move(b); +// return b; +//} +// +//T swap(T)(ref T a, T b) +//{ +// import urt.lifetime : move, moveEmplace; +// +// auto t = a.move; +// b.move(a); +// return t.move; +//} + +// ---------------------------------------------------------------------- +// ^^ helpers +// ---------------------------------------------------------------------- + +static if (__VERSION__ >= 2113) +{ + static import urt.atomic; + alias _d_atomicOp = urt.atomic.atomic_op; + + static import urt.math; + alias _d_pow = urt.math.pow; + + auto _d_sqrt(T)(T x) + { + // TODO: should we have a `float` one? + return urt.math.sqrt(x); + } +} + +// ---------------------------------------------------------------------- +// Object - root of the class hierarchy +// ---------------------------------------------------------------------- + +class Object +{ +@nogc: + static if (__VERSION__ >= 2113) + void* __monitor; + + size_t toHash() @trusted nothrow + { + size_t addr = cast(size_t) cast(void*) this; + return addr ^ (addr >>> 4); + } + + bool opEquals(Object rhs) + => this is rhs; + + int opCmp(Object rhs) + => 0; + + ptrdiff_t toString(char[] buffer) const nothrow + => try_copy_string(buffer, "Object"); +} + +// Free-function opEquals for class types - the compiler lowers `a == b` +// on class objects to a call to this function. +bool opEquals(LHS, RHS)(LHS lhs, RHS rhs) + if ((is(LHS : const Object) || is(LHS : const shared Object)) && + (is(RHS : const Object) || is(RHS : const shared Object))) +{ + static if (__traits(compiles, lhs.opEquals(rhs)) && __traits(compiles, rhs.opEquals(lhs))) + { + if (lhs is rhs) + return true; + if (lhs is null || rhs is null) + return false; + if (!lhs.opEquals(rhs)) + return false; + if (typeid(lhs) is typeid(rhs) || !__ctfe && typeid(lhs).opEquals(typeid(rhs))) + return true; + return rhs.opEquals(lhs); + } + else + return .opEquals!(Object, Object)(*cast(Object*) &lhs, *cast(Object*) &rhs); +} + +// ---------------------------------------------------------------------- +// TypeInfo - compiler generates references for typeid, AAs, etc. +// ---------------------------------------------------------------------- + +class TypeInfo +{ +@nogc: + size_t getHash(scope const void* p) @trusted nothrow const + => 0; + + bool equals(scope const void* p1, scope const void* p2) @trusted const + => p1 == p2; + + int compare(scope const void* p1, scope const void* p2) @trusted const + => 0; + + @property size_t tsize() nothrow pure const @safe @nogc + => 0; + + const(TypeInfo) next() nothrow pure const @nogc + => null; + + size_t[] offTi() nothrow const + => null; + + @property uint flags() nothrow pure const @safe @nogc + => 0; + + @property size_t talign() nothrow pure const @safe @nogc + => tsize; + + const(void)[] initializer() nothrow pure const @safe @nogc + => null; + + @property immutable(void)* rtInfo() nothrow pure const @safe @nogc + => null; + + version (WithArgTypes) + { + int argTypes(out TypeInfo arg1, out TypeInfo arg2) @safe nothrow + { + arg1 = null; + arg2 = null; + return 0; + } + } + + override size_t toHash() @trusted nothrow const + => 0; + + override bool opEquals(Object rhs) + => false; + + override int opCmp(Object rhs) + => 0; + + override ptrdiff_t toString(char[] buffer) const nothrow + => try_copy_string(buffer, "TypeInfo"); +} + +struct Interface +{ + TypeInfo_Class classinfo; + void*[] vtbl; + size_t offset; +} + +struct OffsetTypeInfo +{ + size_t offset; + TypeInfo ti; +} + +class TypeInfo_Class : TypeInfo +{ +@nogc: + byte[] m_init; + string name; + void*[] vtbl; + Interface[] interfaces; + TypeInfo_Class base; + void* destructor; + void function(Object) nothrow @nogc classInvariant; + + enum ClassFlags : ushort + { + isCOMclass = 0x1, + noPointers = 0x2, + hasOffTi = 0x4, + hasCtor = 0x8, + hasGetMembers = 0x10, + hasTypeInfo = 0x20, + isAbstract = 0x40, + isCPPclass = 0x80, + hasDtor = 0x100, + hasNameSig = 0x200, + } + ClassFlags m_flags; + ushort depth; + void* deallocator; + OffsetTypeInfo[] m_offTi; + void function(Object) @nogc defaultConstructor; + + immutable(void)* m_RTInfo; + override @property immutable(void)* rtInfo() nothrow pure const @safe { return m_RTInfo; } + + uint[4] nameSig; + + override @property size_t tsize() nothrow pure const @safe + { + return (void*).sizeof; + } +} + +// TypeInfo_Struct - compiler generates static instances for every struct type. +// Field layout must exactly match what the compiler emits. +class TypeInfo_Struct : TypeInfo +{ +@nogc: + override ptrdiff_t toString(char[] buffer) const nothrow + => try_copy_string(buffer, name); + + override size_t toHash() @trusted nothrow const + => hashOf(mangledName); + + override bool opEquals(Object o) + { + if (this is o) return true; + auto s = cast(const TypeInfo_Struct) o; + return s && this.mangledName == s.mangledName; + } + + override size_t getHash(scope const void* p) @trusted pure nothrow const + { + if (xtoHash) + return (*xtoHash)(p); + return 0; + } + + override bool equals(scope const void* p1, scope const void* p2) @trusted pure nothrow const + { + if (!p1 || !p2) return false; + if (xopEquals) + { + const dg = _member_func(p1, xopEquals); + return dg.xopEquals(p2); + } + return p1 == p2; + } + + override int compare(scope const void* p1, scope const void* p2) @trusted pure nothrow const + { + if (p1 == p2) return 0; + if (!p1) return -1; + if (!p2) return 1; + if (xopCmp) + { + const dg = _member_func(p1, xopCmp); + return dg.xopCmp(p2); + } + return 0; + } + + override @property size_t tsize() nothrow pure const + => initializer().length; + + override const(void)[] initializer() nothrow pure const @safe @nogc + => m_init; + + override @property uint flags() nothrow pure const + => m_flags; + + override @property size_t talign() nothrow pure const + => m_align; + + string mangledName; + + @property string name() nothrow const @trusted + => mangledName; // no demangling - avoids pulling in core.demangle + + void[] m_init; + + @safe pure nothrow + { + size_t function(in void*) @nogc xtoHash; + bool function(in void*, in void*) @nogc xopEquals; + int function(in void*, in void*) @nogc xopCmp; + ptrdiff_t function(in void*, const(char)[]) @nogc xtoString; + + enum StructFlags : uint + { + hasPointers = 0x1, + isDynamicType = 0x2, + } + StructFlags m_flags; + } + union + { + void function(void*) @nogc xdtor; + void function(void*, const TypeInfo_Struct) @nogc xdtorti; + } + void function(void*) xpostblit; + + uint m_align; + + version (WithArgTypes) + { + override int argTypes(out TypeInfo arg1, out TypeInfo arg2) + { + arg1 = m_arg1; + arg2 = m_arg2; + return 0; + } + + TypeInfo m_arg1; + TypeInfo m_arg2; + } + + override @property immutable(void)* rtInfo() nothrow pure const @safe @nogc + => m_RTInfo; + + immutable(void)* m_RTInfo; +} + +class TypeInfo_Enum : TypeInfo +{ +@nogc: + override size_t getHash(scope const void* p) const { return base.getHash(p); } + override bool equals(scope const void* p1, scope const void* p2) const { return base.equals(p1, p2); } + override int compare(scope const void* p1, scope const void* p2) const { return base.compare(p1, p2); } + override @property size_t tsize() nothrow pure const { return base.tsize; } + override const(TypeInfo) next() nothrow pure const @nogc { return base.next; } + override @property uint flags() nothrow pure const { return base.flags; } + override @property size_t talign() nothrow pure const { return base.talign; } + override @property immutable(void)* rtInfo() nothrow pure const @safe @nogc { return base.rtInfo; } + + override const(void)[] initializer() nothrow pure const @nogc + => m_init.length ? m_init : base.initializer(); + + version (WithArgTypes) + { + override int argTypes(out TypeInfo arg1, out TypeInfo arg2) + => base.argTypes(arg1, arg2); + } + + TypeInfo base; + string name; + void[] m_init; +} + +class TypeInfo_Pointer : TypeInfo +{ +@nogc: + override @property size_t tsize() nothrow pure const + => (void*).sizeof; + + override const(TypeInfo) next() nothrow pure const @nogc + => m_next; + + TypeInfo m_next; +} + +class TypeInfo_Array : TypeInfo +{ +@nogc: + override @property size_t tsize() nothrow pure const + => (void[]).sizeof; + + override const(TypeInfo) next() nothrow pure const @nogc + => value; + + TypeInfo value; +} + +// Built-in array TypeInfo subclasses - the compiler generates references to +// these for common array types. Empty subclasses are sufficient; the +// compiler fills in the `value` field. +class TypeInfo_Ah : TypeInfo_Array {} // ubyte[] +class TypeInfo_Ag : TypeInfo_Array {} // byte[] +class TypeInfo_Aa : TypeInfo_Array {} // char[] +class TypeInfo_Aaya : TypeInfo_Array {} // string[] +class TypeInfo_At : TypeInfo_Array {} // ushort[] +class TypeInfo_As : TypeInfo_Array {} // short[] +class TypeInfo_Au : TypeInfo_Array {} // wchar[] +class TypeInfo_Ak : TypeInfo_Array {} // uint[] +class TypeInfo_Ai : TypeInfo_Array {} // int[] +class TypeInfo_Aw : TypeInfo_Array {} // dchar[] +class TypeInfo_Am : TypeInfo_Array {} // ulong[] +class TypeInfo_Al : TypeInfo_Array {} // long[] +class TypeInfo_Af : TypeInfo_Array {} // float[] +class TypeInfo_Ad : TypeInfo_Array {} // double[] +class TypeInfo_Av : TypeInfo_Array {} // void[] + +class TypeInfo_StaticArray : TypeInfo +{ +@nogc: + override @property size_t tsize() nothrow pure const + => len * value.tsize; + + override const(TypeInfo) next() nothrow pure const @nogc + => value; + + TypeInfo value; + size_t len; +} + +class TypeInfo_Vector : TypeInfo +{ +@nogc: + override @property size_t tsize() nothrow pure const + => base.tsize; + + TypeInfo base; +} + +class TypeInfo_Function : TypeInfo +{ +@nogc: + override @property size_t tsize() nothrow pure const + => 0; + + TypeInfo next; + string deco; +} + +class TypeInfo_Delegate : TypeInfo +{ +@nogc: + override @property size_t tsize() nothrow pure const + { + alias dg = int delegate(); + return dg.sizeof; + } + + TypeInfo next; + string deco; +} + +class TypeInfo_Interface : TypeInfo +{ +@nogc: + override @property size_t tsize() nothrow pure const + => (void*).sizeof; + + TypeInfo_Class info; +} + +class TypeInfo_Tuple : TypeInfo +{ + TypeInfo[] elements; +} + +class TypeInfo_AssociativeArray : TypeInfo +{ +@nogc: + override ptrdiff_t toString(char[] buffer) const nothrow + { + if (!buffer.ptr) + return value.toString(null) + key.toString(null) + 2; + ptrdiff_t l = value.toString(buffer); + if (l < 0) + return l; + if (buffer.length < l + 2) + return -1; + buffer[l] = '['; + ptrdiff_t k = key.toString(buffer[l + 1 .. $]); + if (k < 0) + return k; + l += k + 2; + if (buffer.length < l) + return -1; + buffer[l - 1] = ']'; + return l; + } + + override bool opEquals(Object o) + { + if (this is o) return true; + auto c = cast(const TypeInfo_AssociativeArray) o; + return c && this.key == c.key && this.value == c.value; + } + + override bool equals(scope const void* p1, scope const void* p2) @trusted const + => xopEquals(p1, p2); + + override hash_t getHash(scope const void* p) nothrow @trusted const + => xtoHash(p); + + override @property size_t tsize() nothrow pure const + => (char[int]).sizeof; + + override const(void)[] initializer() const @trusted + => (cast(void*)null)[0 .. (char[int]).sizeof]; + + override const(TypeInfo) next() nothrow pure const @nogc { return value; } + override @property uint flags() nothrow pure const { return 1; } + + private static import urt.internal.aa; + alias Entry(K, V) = urt.internal.aa.Entry!(K, V); + + TypeInfo value; + TypeInfo key; + TypeInfo entry; + + bool function(scope const void* p1, scope const void* p2) nothrow @safe xopEquals; + hash_t function(scope const void*) nothrow @safe xtoHash; + + alias aaOpEqual(K, V) = urt.internal.aa._aaOpEqual!(K, V); + alias aaGetHash(K, V) = urt.internal.aa._aaGetHash!(K, V); + + override @property size_t talign() nothrow pure const + => (char[int]).alignof; +} + +class TypeInfo_Const : TypeInfo +{ +@nogc: + override size_t getHash(scope const void* p) const { return base.getHash(p); } + override bool equals(scope const void* p1, scope const void* p2) const { return base.equals(p1, p2); } + override int compare(scope const void* p1, scope const void* p2) const { return base.compare(p1, p2); } + override @property size_t tsize() nothrow pure const { return base.tsize; } + override const(TypeInfo) next() nothrow pure const @nogc { return base.next; } + override @property uint flags() nothrow pure const { return base.flags; } + override const(void)[] initializer() nothrow pure const @nogc { return base.initializer(); } + override @property size_t talign() nothrow pure const { return base.talign; } + + TypeInfo base; +} + +class TypeInfo_Invariant : TypeInfo_Const +{ +} + +class TypeInfo_Shared : TypeInfo_Const +{ +} + +class TypeInfo_Inout : TypeInfo_Const +{ +} + +// ---------------------------------------------------------------------- +// TypeInfo for built-in types - compiler references these by mangled name +// (e.g. TypeInfo_k for uint). Single-character suffixes follow D's type +// encoding: a=char, b=bool, d=double, f=float, g=byte, h=ubyte, +// i=int, k=uint, l=long, m=ulong, o=dchar, s=short, t=wchar, +// u=ushort, v=void, x=const, y=immutable. +// ---------------------------------------------------------------------- + +class TypeInfo_a : TypeInfo { override @property size_t tsize() nothrow pure const @safe @nogc { return char.sizeof; } } +class TypeInfo_b : TypeInfo { override @property size_t tsize() nothrow pure const @safe @nogc { return bool.sizeof; } } +class TypeInfo_d : TypeInfo { override @property size_t tsize() nothrow pure const @safe @nogc { return double.sizeof; } } +class TypeInfo_f : TypeInfo { override @property size_t tsize() nothrow pure const @safe @nogc { return float.sizeof; } } +class TypeInfo_g : TypeInfo { override @property size_t tsize() nothrow pure const @safe @nogc { return byte.sizeof; } } +class TypeInfo_h : TypeInfo { override @property size_t tsize() nothrow pure const @safe @nogc { return ubyte.sizeof; } } +class TypeInfo_i : TypeInfo { override @property size_t tsize() nothrow pure const @safe @nogc { return int.sizeof; } } +class TypeInfo_k : TypeInfo { override @property size_t tsize() nothrow pure const @safe @nogc { return uint.sizeof; } } +class TypeInfo_l : TypeInfo { override @property size_t tsize() nothrow pure const @safe @nogc { return long.sizeof; } } +class TypeInfo_m : TypeInfo { override @property size_t tsize() nothrow pure const @safe @nogc { return ulong.sizeof; } } +class TypeInfo_o : TypeInfo { override @property size_t tsize() nothrow pure const @safe @nogc { return dchar.sizeof; } } +class TypeInfo_s : TypeInfo { override @property size_t tsize() nothrow pure const @safe @nogc { return short.sizeof; } } +class TypeInfo_t : TypeInfo { override @property size_t tsize() nothrow pure const @safe @nogc { return wchar.sizeof; } } +class TypeInfo_u : TypeInfo { override @property size_t tsize() nothrow pure const @safe @nogc { return ushort.sizeof; } } +class TypeInfo_v : TypeInfo { override @property size_t tsize() nothrow pure const @safe @nogc { return 0; } } + +// Helper for TypeInfo_Struct delegate dispatch. +// Uses a union to overlay raw delegate ABI (ptr + funcptr) with typed delegate fields. +private struct _member_func +{ + union + { + struct + { + const void* ptr; + const void* funcptr; + } + + @safe pure nothrow + { + bool delegate(in void*) @nogc xopEquals; + int delegate(in void*) @nogc xopCmp; + } + } +} + +// ---------------------------------------------------------------------- +// __ArrayDtor - compiler lowers dynamic array destruction to this +// ---------------------------------------------------------------------- + +void __ArrayDtor(T)(scope T[] a) +{ + foreach_reverse (ref T e; a) + e.__xdtor(); +} + +// ---------------------------------------------------------------------- +// Compiler hook templates - array & AA literal lowering +// These are only called at runtime; CTFE evaluates literals directly. +// ---------------------------------------------------------------------- + +void* _d_arrayliteralTX(T)(size_t length) @trusted pure nothrow +{ + assert(false, "Array literals require druntime"); +} + +alias AssociativeArray(Key, Value) = Value[Key]; + +public import urt.internal.aa : _d_aaIn, _d_aaDel, _d_aaNew, _d_aaEqual, _d_assocarrayliteralTX; +public import urt.internal.aa : _d_aaLen, _d_aaGetY, _d_aaGetRvalueX, _d_aaApply, _d_aaApply2; + +private import urt.internal.aa : makeAA; + +// Lower an AA to a newaa struct for static initialization. +auto _aaAsStruct(K, V)(V[K] aa) @safe +{ + assert(__ctfe); + return makeAA!(K, V)(aa); +} + +Tret _d_arraycatnTX(Tret, Tarr...)(auto ref Tarr froms) @trusted +{ + assert(false, "Array concatenation requires druntime"); +} + + +T _d_newclassT(T)() @trusted + if (is(T == class)) +{ + assert(false, "new class requires druntime"); +/+ + if (__ctfe) + assert(false, "new class not supported at CTFE without druntime"); + + import urt.mem : alloc, memcpy; + + enum sz = __traits(classInstanceSize, T); + auto p = alloc(sz).ptr; + if (p is null) + assert(false, "out of memory in _d_newclassT"); + + auto initSym = __traits(initSymbol, T); + memcpy(p, initSym.ptr, sz); + return cast(T)cast(void*)p; ++/ +} + +ref Tarr _d_arrayappendcTX(Tarr : T[], T)(return ref scope Tarr px, size_t n) @trusted +{ + assert(false, "Array append requires druntime"); +} + +ref Tarr _d_arrayappendT(Tarr : T[], T)(return ref scope Tarr x, scope Tarr y) @trusted +{ + assert(false, "Array append requires druntime"); +} + +// ---------------------------------------------------------------------- +// Compiler hook templates - array operations, construction, etc. +// These are lowered by the compiler for various language constructs. +// ---------------------------------------------------------------------- + +T[] _d_newarrayT(T)(size_t length, bool isShared = false) @trusted +{ + import urt.mem.alloc : alloc; +// assert(false, "new array requires druntime"); + return cast(T[])alloc(T.sizeof * length); +} + +Tarr _d_newarraymTX(Tarr : U[], T, U)(size_t[] dims, bool isShared = false) @trusted +{ + assert(false, "new multi-dim array requires druntime"); +} + +T* _d_newitemT(T)() @trusted +{ + import urt.mem.alloc : alloc; +// assert(false, "new item requires druntime"); + return cast(T*)alloc(T.sizeof).ptr; +} + +T _d_newThrowable(T)() @trusted + if (is(T : Throwable)) +{ + assert(false, "new throwable requires druntime"); +} + +int __cmp(T)(scope const T[] lhs, scope const T[] rhs) @trusted +{ + immutable len = lhs.length <= rhs.length ? lhs.length : rhs.length; + foreach (i; 0 .. len) + { + if (lhs.ptr[i] < rhs.ptr[i]) + return -1; + if (lhs.ptr[i] > rhs.ptr[i]) + return 1; + } + return (lhs.length > rhs.length) - (lhs.length < rhs.length); +} + +bool __equals(T1, T2)(scope const T1[] lhs, scope const T2[] rhs) +nothrow @nogc pure @trusted +if (__traits(isScalar, T1) && __traits(isScalar, T2)) +{ + if (lhs.length != rhs.length) + return false; + static if (T1.sizeof == T2.sizeof + && (T1.sizeof >= 4 || __traits(isUnsigned, T1) == __traits(isUnsigned, T2)) + && !__traits(isFloating, T1) && !__traits(isFloating, T2)) + { + if (__ctfe) + { + foreach (i; 0 .. lhs.length) + if (lhs.ptr[i] != rhs.ptr[i]) return false; + return true; + } + else + { + import urt.mem : memcmp; + return !lhs.length || 0 == memcmp(cast(const void*) lhs.ptr, cast(const void*) rhs.ptr, lhs.length * T1.sizeof); + } + } + else + { + foreach (i; 0 .. lhs.length) + if (lhs.ptr[i] != rhs.ptr[i]) return false; + return true; + } +} + +bool __equals(T1, T2)(scope T1[] lhs, scope T2[] rhs) +if (!__traits(isScalar, T1) || !__traits(isScalar, T2)) +{ + if (lhs.length != rhs.length) + return false; + foreach (i; 0 .. lhs.length) + if (lhs[i] != rhs[i]) return false; + return true; +} + +TTo[] __ArrayCast(TFrom, TTo)(return scope TFrom[] from) @nogc pure @trusted +{ + const fromSize = from.length * TFrom.sizeof; + if (fromSize % TTo.sizeof != 0) + assert(false, "Array cast misalignment"); + return (cast(TTo*) from.ptr)[0 .. fromSize / TTo.sizeof]; +} + +Tarr _d_arrayctor(Tarr : T[], T)(return scope Tarr to, scope Tarr from) @trusted +{ + assert(false, "Array ctor requires druntime"); +} + +void _d_arraysetctor(Tarr : T[], T)(scope Tarr p, scope ref T value) @trusted +{ + assert(false, "Array set-ctor requires druntime"); +} + +Tarr _d_arrayassign_l(Tarr : T[], T)(return scope Tarr to, scope Tarr from) @trusted +{ + assert(false, "Array assign requires druntime"); +} + +Tarr _d_arrayassign_r(Tarr : T[], T)(return scope Tarr to, scope Tarr from) @trusted +{ + assert(false, "Array assign requires druntime"); +} + +void _d_arraysetassign(Tarr : T[], T)(return scope Tarr to, scope ref T value) @trusted +{ + assert(false, "Array set-assign requires druntime"); +} + +size_t _d_arraysetlengthT(Tarr : T[], T)(return ref scope Tarr arr, size_t newlength) @trusted +{ + assert(false, "Array setlength requires druntime"); +} + +// LDC wraps the above in a template namespace +template _d_arraysetlengthTImpl(Tarr : T[], T) +{ + size_t _d_arraysetlengthT(return scope ref Tarr arr, size_t newlength) @trusted pure nothrow + { + assert(false, "Array setlength requires druntime"); + } +} + +string _d_assert_fail(A...)(const scope string comp, auto ref const scope A a) +{ + return "assertion failure"; +} + +// ---------------------------------------------------------------------- +// Runtime hooks: assertions, array bounds checks +// These are referenced by compiler-generated code even in debug builds. +// ---------------------------------------------------------------------- + +extern(C) void _d_assert_msg(string msg, string file, uint line) nothrow @nogc +{ + import urt.exception : assert_handler; + assert_handler()(file, line, msg); +} + +extern(C) void _d_assertp(immutable(char)* file, uint line) nothrow @nogc @trusted +{ + import urt.mem : strlen; + import urt.exception : assert_handler; + auto f = file[0 .. file ? strlen(file) : 0]; + assert_handler()(f, line, null); +} + +extern(C) void _d_assert(string file, uint line) nothrow @nogc +{ + import urt.exception : assert_handler; + assert_handler()(file, line, null); +} + +extern(C) void _d_arraybounds_indexp(string file, uint line, size_t index, size_t length) nothrow @nogc +{ + import urt.exception : assert_handler; + assert_handler()(file, line, "array index out of bounds"); +} + +extern(C) void _d_arraybounds_slicep(string file, uint line, size_t lower, size_t upper, size_t length) nothrow @nogc +{ + import urt.exception : assert_handler; + assert_handler()(file, line, "array slice out of bounds"); +} + +extern(C) void _d_arrayboundsp(string file, uint line) nothrow @nogc +{ + import urt.exception : assert_handler; + assert_handler()(file, line, "array index out of bounds"); +} + +extern(C) void _d_arraybounds(string file, uint line) nothrow @nogc +{ + import urt.exception : assert_handler; + assert_handler()(file, line, "array index out of bounds"); +} + +// Unittest assert hooks - the compiler generates these for assert() inside +// unittest blocks instead of the regular _d_assertp/_d_assert_msg. +extern(C) void _d_unittestp(immutable(char)* file, uint line) nothrow @nogc @trusted +{ + import urt.mem : strlen; + import urt.exception : assert_handler; + auto f = file[0 .. file ? strlen(file) : 0]; + assert_handler()(f, line, "unittest assertion failure"); +} + +extern(C) void _d_unittest_msg(string msg, string file, uint line) nothrow @nogc @trusted +{ + import urt.exception : assert_handler; + assert_handler()(file, line, msg); +} + +extern(C) void _d_unittest(string file, uint line) nothrow @nogc +{ + import urt.exception : assert_handler; + assert_handler()(file, line, "unittest assertion failure"); +} + +// GC allocation hook - compiler lowers `new` to this. In our @nogc world +// it should never be called from production code; provided so unittest +// blocks that accidentally use `new` can at least link. +extern(C) void* _d_allocmemory(size_t sz) nothrow @nogc @trusted +{ + import urt.mem.alloc : alloc; + return alloc(sz).ptr; +} + +// ---------------------------------------------------------------------- +// LDC extern(C) runtime hooks +// LDC's codegen emits calls to old-style extern(C) functions for many +// operations where DMD uses template-based hooks. These stubs satisfy +// the linker. Implementations are provided where feasible; others +// assert(false) and must be fleshed out if the code path is hit. +// ---------------------------------------------------------------------- + +version (LDC) +{ + +// --- Bounds checks (LDC variants without 'p' suffix) ------------------- + +extern(C) void _d_arraybounds_index(string file, uint line, size_t index, size_t length) nothrow @nogc +{ + import urt.exception : assert_handler; + if (auto handler = assert_handler) + handler(file, line, "array index out of bounds"); + else + _halt(); +} + +extern(C) void _d_arraybounds_slice(string file, uint line, size_t lower, size_t upper, size_t length) nothrow @nogc +{ + import urt.exception : assert_handler; + if (auto handler = assert_handler) + handler(file, line, "array slice out of bounds"); + else + _halt(); +} + +// --- Array slice copy (LDC emits this for non-elaborate arr[] = other[]) - +// Bounds-checked memcpy: verifies dstlen == srclen, then copies raw bytes. + +extern(C) void _d_array_slice_copy(void* dst, size_t dstlen, void* src, size_t srclen, size_t elemsize) nothrow @nogc @trusted +{ + assert(dstlen == srclen, "array slice lengths don't match for copy"); + import urt.mem : memcpy; + memcpy(dst, src, dstlen * elemsize); +} + +// --- Class allocation and casting (old-style extern C) ----------------- + +extern(C) void* _d_allocclass(TypeInfo_Class ci) nothrow @nogc @trusted +{ + import urt.mem : alloc, memcpy; + auto init = ci.initializer; + auto p = alloc(init.length).ptr; + if (p !is null) + memcpy(p, init.ptr, init.length); + return p; +} + +extern(C) Object _d_dynamic_cast(Object o, TypeInfo_Class c) nothrow @nogc @trusted +{ + // Traverse classinfo chain to check if o is-a c + if (o is null) return null; + auto oc = typeid(o); + while (oc !is null) + { + if (oc is c) + return o; + oc = oc.base; + } + return null; +} + +extern(C) void* _d_interface_cast(void* p, TypeInfo_Class c) nothrow @nogc @trusted +{ + // TODO: full interface casting requires traversing the Interface[] table + // in the target object's classinfo to find the right vtable offset. + // For now, return null (cast fails). + return null; +} + +// --- Struct array equality (old-style) --------------------------------- + +extern(C) int _adEq2(void[] a1, void[] a2, TypeInfo ti) nothrow @nogc @trusted +{ + if (a1.length != a2.length) return 0; + import urt.mem : memcmp; + return memcmp(a1.ptr, a2.ptr, a1.length) == 0 ? 1 : 0; +} + +} // version (LDC) + +// --- Old-style array allocation (extern C) ------------------------------ + +extern(C) void[] _d_newarrayT(const TypeInfo ti, size_t length) nothrow @nogc @trusted +{ + import urt.mem.alloc : alloc; + auto elemsize = ti.next ? ti.next.tsize : 1; + return alloc(length * elemsize); +} + +extern(C) void[] _d_newarrayiT(const TypeInfo ti, size_t length) nothrow @nogc @trusted +{ + import urt.mem.alloc : alloc; + auto elemsize = ti.next ? ti.next.tsize : 1; + return alloc(length * elemsize); +} + +extern(C) void[] _d_newarrayU(const TypeInfo ti, size_t length) nothrow @nogc @trusted +{ + import urt.mem.alloc : alloc; + auto elemsize = ti.next ? ti.next.tsize : 1; + return alloc(length * elemsize); +} + +// Unconditional halt - avoids circular dependency with assert. +private void _halt() nothrow @nogc @trusted +{ + version (D_InlineAsm_X86_64) + asm nothrow @nogc { hlt; } + else version (D_InlineAsm_X86) + asm nothrow @nogc { hlt; } + else + *(cast(int*) null) = 0; // fallback: null deref +} + +void __move_post_blt(S)(ref S newLocation, ref S oldLocation) nothrow + if (is(S == struct)) +{ + static if (__traits(hasMember, S, "__xpostblit")) + newLocation.__xpostblit(); +} + +void __ArrayPostblit(T)(T[] a) +{ + foreach (ref e; a) + static if (__traits(hasMember, T, "__xpostblit")) + e.__xpostblit(); +} + +int __switch(T, caseLabels...)(const scope T[] condition) pure nothrow @safe @nogc +{ + foreach (i, s; caseLabels) + { + static if (is(typeof(s) : typeof(condition))) + { + if (condition == s) + return cast(int) i; + } + } + return -1; +} + +void __switch_error()(string file = __FILE__, size_t line = __LINE__) +{ + assert(false, "Final switch error"); +} + +template _d_delstructImpl(T) +{ + void _d_delstruct(ref T p) @trusted + { + p = null; + } +} + +nothrow @nogc @trusted pure extern(C) void _d_delThrowable(scope Throwable) {} + +// ---------------------------------------------------------------------- +// _arrayOp - compiler hook for vectorized array slice operations. +// DMD lowers `dest[] = a[] ^ b[]` to `_arrayOp!(T[], T[], T[], "^", "=")(dest, a, b)`. +// Args are in Reverse Polish Notation (RPN). +// ---------------------------------------------------------------------- + +template _arrayOp(Args...) +{ + static if (is(Args[0] == E[], E)) + { + alias T = E; + + T[] _arrayOp(T[] res, _Filter!(_is_type, Args[1 .. $]) args) nothrow @nogc @trusted + { + foreach (pos; 0 .. res.length) + mixin(_scalar_exp!(Args[1 .. $]) ~ ";"); + return res; + } + } +} + +// ---- _arrayOp helpers (all private, CTFE-only) ---- + +private template _Filter(alias pred, args...) +{ + static if (args.length == 0) + alias _Filter = AliasSeq!(); + else static if (pred!(args[0])) + alias _Filter = AliasSeq!(args[0], _Filter!(pred, args[1 .. $])); + else + alias _Filter = _Filter!(pred, args[1 .. $]); +} + +private enum _is_type(T) = true; +private enum _is_type(alias a) = false; + +private bool _is_unary_op(string op) pure nothrow @safe @nogc + => op.length > 0 && op[0] == 'u'; + +private bool _is_binary_op(string op) pure nothrow @safe @nogc +{ + if (op == "^^") return true; + if (op.length != 1) return false; + switch (op[0]) + { + case '+', '-', '*', '/', '%', '|', '&', '^': + return true; + default: + return false; + } +} + +private bool _is_binary_assign_op(string op) + => op.length >= 2 && op[$ - 1] == '=' && _is_binary_op(op[0 .. $ - 1]); + +// Convert size_t to string at CTFE. +private string _size_to_str(size_t num) pure @safe +{ + enum digits = "0123456789"; + if (num < 10) return digits[num .. num + 1]; + return _size_to_str(num / 10) ~ digits[num % 10 .. num % 10 + 1]; +} + +// Generate element-wise mixin expression from RPN args (CTFE-evaluated enum). +// Uses a fixed-size stack with depth counter to avoid dynamic array operations +// (which would require _d_arraysetlengthT at semantic analysis time). +private enum _scalar_exp(Args...) = () { + string[Args.length] stack; + size_t depth; + size_t args_idx; + + static if (is(Args[0] == U[], U)) + alias Type = U; + else + alias Type = Args[0]; + + foreach (i, arg; Args) + { + static if (is(arg == E[], E)) + { + stack[depth] = "args[" ~ _size_to_str(args_idx++) ~ "][pos]"; + ++depth; + } + else static if (is(arg)) + { + stack[depth] = "args[" ~ _size_to_str(args_idx++) ~ "]"; + ++depth; + } + else static if (_is_unary_op(arg)) + { + auto op = arg[0] == 'u' ? arg[1 .. $] : arg; + static if (is(Type : int)) + stack[depth - 1] = "cast(typeof(" ~ stack[depth - 1] ~ "))" ~ op ~ "cast(int)(" ~ stack[depth - 1] ~ ")"; + else + stack[depth - 1] = op ~ stack[depth - 1]; + } + else static if (arg == "=") + { + stack[depth - 1] = "res[pos] = cast(T)(" ~ stack[depth - 1] ~ ")"; + } + else static if (_is_binary_assign_op(arg)) + { + stack[depth - 1] = "res[pos] " ~ arg ~ " cast(T)(" ~ stack[depth - 1] ~ ")"; + } + else static if (_is_binary_op(arg)) + { + stack[depth - 2] = "(" ~ stack[depth - 2] ~ " " ~ arg ~ " " ~ stack[depth - 1] ~ ")"; + --depth; + } + } + return stack[0]; +}(); + +// ---------------------------------------------------------------------- +// _d_cast - dynamic class cast, walks TypeInfo_Class.base chain +// ---------------------------------------------------------------------- + +void* _d_cast(To, From)(From o) @trusted + if (is(From == class) && is(To == class)) +{ + if (o is null) return null; + auto ci = typeid(o); + auto target = typeid(To); + do + { + if (ci is target) return cast(void*) o; + ci = ci.base; + } + while (ci !is null); + return null; +} + +void* _d_cast(To, From)(From o) @trusted + if (is(From == class) && is(To == interface)) +{ + if (o is null) return null; + // Walk interface list - not implemented yet, fall back to null + assert(false, "Interface cast not yet implemented"); +} + +// ---------------------------------------------------------------------- +// Throwable / Exception / Error - exception hierarchy +// ---------------------------------------------------------------------- + +class Throwable : Object +{ + string msg; + Throwable next; + string file; + size_t line; + + private uint _refcount; + + @nogc @safe pure nothrow this(string msg, Throwable next = null) + { + this.msg = msg; + this.next = next; + } + + @nogc @safe pure nothrow this(string msg, string file, size_t line, Throwable next = null) + { + this.msg = msg; + this.file = file; + this.line = line; + this.next = next; + } + + const(char)[] message() const @nogc @safe pure nothrow + => msg; + + @system @nogc final pure nothrow ref uint refcount() return + => _refcount; + + static Throwable chainTogether(return scope Throwable e1, return scope Throwable e2) nothrow @nogc + { + if (!e1) + return e2; + if (!e2) + return e1; + for (auto e = e1; ; e = e.next) + { + if (!e.next) + { + e.next = e2; + break; + } + } + return e1; + } +} + +class Exception : Throwable +{ + @nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) + { + super(msg, file, line, next); + } +} + +class Error : Throwable +{ + Throwable bypassedException; + + @nogc @safe pure nothrow this(string msg, Throwable next = null) + { + super(msg, next); + } + + @nogc @safe pure nothrow this(string msg, string file, size_t line, Throwable next = null) + { + super(msg, file, line, next); + } +} + +// ---------------------------------------------------------------------- +// destroy - compiler generates calls for scope guards, etc. +// ---------------------------------------------------------------------- + +void destroy(bool initialize = true, T)(ref T obj) if (is(T == struct)) +{ + destruct_recurse(obj); + static if (initialize) + { + static if (__traits(isZeroInit, T)) + (cast(ubyte*)&obj)[0 .. T.sizeof] = 0; + else + { + auto init = __traits(initSymbol, T); + (cast(ubyte*)&obj)[0 .. T.sizeof] = (cast(const ubyte*)init.ptr)[0 .. T.sizeof]; + } + } +} + +// Destruct a struct by calling its __xdtor, but only if it truly belongs +// to this type (Bugzilla 14746). +void destruct_recurse(S)(ref S s) if (is(S == struct)) +{ + static if (__traits(hasMember, S, "__xdtor") && __traits(isSame, S, __traits(parent, s.__xdtor))) + s.__xdtor(); +} + +void destruct_recurse(E, size_t n)(ref E[n] arr) +{ + foreach_reverse (ref elem; arr) + destruct_recurse(elem); +} + +void destroy(bool initialize = true, T)(T obj) if (is(T == class)) +{ + static if (__traits(hasMember, T, "__xdtor")) + obj.__xdtor(); +} + +void destroy(bool initialize = true, T)(ref T obj) if (!is(T == struct) && !is(T == class)) +{ + static if (initialize) + obj = T.init; +} + +// ---------------------------------------------------------------------- +// .dup / .idup - array duplication properties +// ---------------------------------------------------------------------- + +@property immutable(T)[] idup(T)(T[] a) @trusted +{ + assert(__ctfe, "idup is only supported at compile time"); + // CTFE-compatible: the interpreter handles ~= natively. + // At runtime this would assert via _d_arrayappendcTX. + immutable(T)[] r; + foreach (ref e; a) + r ~= cast(immutable(T)) e; + return r; +} + +@property T[] dup(T)(const(T)[] a) @trusted +{ + assert(__ctfe, "dup is only supported at compile time"); + T[] r; + foreach (ref e; a) + r ~= cast(T) e; + return r; +} + +// ---------------------------------------------------------------------- +// Compiler-generated struct equality/comparison fallbacks +// ---------------------------------------------------------------------- + +bool _xopEquals(in void*, in void*) + => false; + +bool _xopCmp(in void*, in void*) + => false; + +// ---------------------------------------------------------------------- +// hashOf - used by AAs and anywhere .toHash is needed +// ---------------------------------------------------------------------- + +size_t hashOf(T)(auto ref T val, size_t seed = 0) pure nothrow @nogc @trusted +{ + import urt.hash : fnv1a, fnv1a64, fnv1_initial; + + static if (is(T : const(char)[])) + { + static if (is(size_t == uint)) + return fnv1a(cast(ubyte[])val, seed ? seed : fnv1_initial!uint); + else + return fnv1a64(cast(ubyte[])val, seed ? seed : fnv1_initial!ulong); + } + else static if (is(T V : V*)) + { + // Pointers - CTFE compatible + if (__ctfe) + { + if (val is null) + return seed; + assert(0, "Unable to hash non-null pointer at compile time"); + } + size_t v = cast(size_t)val; + return _fnv(v ^ (v >> 4), seed); + } + else static if (__traits(isIntegral, T)) + { + // Integers - CTFE compatible, no reinterpreting cast + static if (T.sizeof <= size_t.sizeof) + return _fnv(cast(size_t)val, seed); + else + return _fnv(cast(size_t)(val ^ (val >>> (size_t.sizeof * 8))), seed); + } + else static if (__traits(isFloating, T)) + { + // At CTFE we cannot reinterpret float bits; use lossy integer cast + // it'd be better if we could work out the magnitude and multipley the significant bits into an integer + if (__ctfe) + return _fnv(cast(size_t)cast(long)val, seed); + static if (is(size_t == uint)) + return fnv1a((cast(ubyte*)&val)[0..T.sizeof], seed ? seed : fnv1_initial!uint); + else + return fnv1a64((cast(ubyte*)&val)[0..T.sizeof], seed ? seed : fnv1_initial!uint); + } + else static if (is(T == struct)) + { + // Structs - hash each field (CTFE compatible) + size_t h = seed; + foreach (ref field; val.tupleof) + h = hashOf(field, h); + return h; + } + else static if (is(T == enum)) + { + static if (is(T EType == enum)) + return hashOf(cast(EType)val, seed); + else + return _fnv(0, seed); + } + else + return seed; +} + +private size_t _fnv(size_t val, size_t seed) pure nothrow @nogc @trusted +{ + import urt.hash : fnv1a, fnv1a64, fnv1_initial; + + // maybe it's better to write out the algorithm inline...? + if (__ctfe) + { + static if (is(size_t == uint)) + { + ubyte[4] bytes = [ val & 0xFF, (val >> 8) & 0xFF, (val >> 16) & 0xFF, (val >> 24) & 0xFF ]; + return fnv1a(bytes, seed ? seed : fnv1_initial!uint); + } + else + { + ubyte[8] bytes = [ val & 0xFF, (val >> 8) & 0xFF, (val >> 16) & 0xFF, (val >> 24) & 0xFF, + (val >> 32) & 0xFF, (val >> 40) & 0xFF, (val >> 48) & 0xFF, (val >> 56) & 0xFF ]; + return fnv1a64(bytes, seed ? seed : fnv1_initial!ulong); + } + } + static if (is(size_t == uint)) + return fnv1a((cast(ubyte*)&val)[0..4], seed ? seed : fnv1_initial!uint); + else + return fnv1a64((cast(ubyte*)&val)[0..8], seed ? seed : fnv1_initial!ulong); +} + +// ---------------------------------------------------------------------- +// ModuleInfo - compiler emits one per module with ctor/dtor/unittest info. +// Variable-sized: fields are packed after the header based on flag bits. +// ---------------------------------------------------------------------- + +enum +{ + MIctorstart = 0x1, + MIctordone = 0x2, + MIstandalone = 0x4, + MItlsctor = 0x8, + MItlsdtor = 0x10, + MIctor = 0x20, + MIdtor = 0x40, + MIxgetMembers = 0x80, + MIictor = 0x100, + MIunitTest = 0x200, + MIimportedModules = 0x400, + MIlocalClasses = 0x800, + MIname = 0x1000, +} + +struct ModuleInfo +{ + uint _flags; + uint _index; + +const: + private void* addr_of(int flag) return nothrow pure @nogc @trusted + { + void* p = cast(void*)&this + ModuleInfo.sizeof; + + if (flags & MItlsctor) + { + if (flag == MItlsctor) + return p; + p += (void function()).sizeof; + } + if (flags & MItlsdtor) + { + if (flag == MItlsdtor) + return p; + p += (void function()).sizeof; + } + if (flags & MIctor) + { + if (flag == MIctor) + return p; + p += (void function()).sizeof; + } + if (flags & MIdtor) + { + if (flag == MIdtor) + return p; + p += (void function()).sizeof; + } + if (flags & MIxgetMembers) + { + if (flag == MIxgetMembers) + return p; + p += (void*).sizeof; + } + if (flags & MIictor) + { + if (flag == MIictor) + return p; + p += (void function()).sizeof; + } + if (flags & MIunitTest) + { + if (flag == MIunitTest) + return p; + p += (void function()).sizeof; + } + if (flags & MIimportedModules) + { + if (flag == MIimportedModules) + return p; + p += size_t.sizeof + *cast(size_t*)p * (immutable(ModuleInfo)*).sizeof; + } + if (flags & MIlocalClasses) + { + if (flag == MIlocalClasses) + return p; + p += size_t.sizeof + *cast(size_t*)p * (TypeInfo_Class).sizeof; + } + if (true || flags & MIname) + { + if (flag == MIname) + return p; + } + assert(0); + } + + @property uint flags() nothrow pure @nogc + => _flags; + + @property void function() tlsctor() nothrow pure @nogc @trusted + => flags & MItlsctor ? *cast(typeof(return)*)addr_of(MItlsctor) : null; + + @property void function() tlsdtor() nothrow pure @nogc @trusted + => flags & MItlsdtor ? *cast(typeof(return)*)addr_of(MItlsdtor) : null; + + @property void function() ctor() nothrow pure @nogc @trusted + => flags & MIctor ? *cast(typeof(return)*)addr_of(MIctor) : null; + + @property void function() dtor() nothrow pure @nogc @trusted + => flags & MIdtor ? *cast(typeof(return)*)addr_of(MIdtor) : null; + + @property void function() ictor() nothrow pure @nogc @trusted + => flags & MIictor ? *cast(typeof(return)*)addr_of(MIictor) : null; + + @property void function() unitTest() nothrow pure @nogc @trusted + => flags & MIunitTest ? *cast(typeof(return)*)addr_of(MIunitTest) : null; + + @property immutable(ModuleInfo*)[] importedModules() return nothrow pure @nogc @trusted + { + if (flags & MIimportedModules) + { + auto p = cast(size_t*)addr_of(MIimportedModules); + return (cast(immutable(ModuleInfo*)*)(p + 1))[0 .. *p]; + } + return null; + } + + @property string name() nothrow @nogc @trusted + { + // LDC always emits the name after the packed fields, even without + // setting MIname. addr_of(MIname) handles this (see `true ||` guard). + auto p = cast(immutable char*)addr_of(MIname); + size_t len = 0; + while (p[len] != 0) ++len; + return p[0 .. len]; + } +} + +// ---------------------------------------------------------------------- +// Module registration - LDC uses _Dmodule_ref linked list +// +// On ELF targets the compiler generates .init_array entries that chain +// ModuleReference structs into _Dmodule_ref. On Linux, glibc's crt0 +// calls .init_array automatically. On bare-metal, start.S does it. +// ---------------------------------------------------------------------- + +version (Windows) {} +else + extern(C) __gshared void* _Dmodule_ref = null; + +version (linux) +{ + struct CompilerDSOData + { + size_t _version; + void** _slot; + immutable(ModuleInfo*)* _minfo_beg, _minfo_end; + } + + extern(C) __gshared immutable(ModuleInfo*)* _elf_minfo_beg; + extern(C) __gshared immutable(ModuleInfo*)* _elf_minfo_end; + + extern(C) void _d_dso_registry(CompilerDSOData* data) nothrow @nogc + { + if (data._version < 1) + return; + + if (*data._slot is null) + { + *data._slot = cast(void*)data; + _elf_minfo_beg = data._minfo_beg; + _elf_minfo_end = data._minfo_end; + } + else + { + *data._slot = null; + _elf_minfo_beg = null; + _elf_minfo_end = null; + } + } +} + +// ---------------------------------------------------------------------- +// TypeInfo for const/immutable char[] - compiler references by name +// ---------------------------------------------------------------------- + +class TypeInfo_Axa : TypeInfo_Array {} // const(char)[] +class TypeInfo_Aya : TypeInfo_Array {} // immutable(char)[] = string + +// ---------------------------------------------------------------------- +// _d_invariant - contract invariant hook (matches rt.invariant_ mangling) +// ---------------------------------------------------------------------- + +pragma(mangle, "_D2rt10invariant_12_d_invariantFC6ObjectZv") +void _d_invariant_impl(Object o) nothrow @nogc +{ + assert(o !is null); + auto c = typeid(o); + do + { + if (c.classInvariant) + c.classInvariant(o); + c = c.base; + } + while (c); +} + +// ---------------------------------------------------------------------- +// Compiler-generated memset intrinsics (struct initialization) +// ---------------------------------------------------------------------- + +private struct Bits128 { ulong[2] v; } +private struct Bits80 { ubyte[real.sizeof] v; } +private struct Bits160 { ubyte[2 * real.sizeof] v; } + +extern(C) nothrow @nogc @trusted +{ + short* _memset16(short* p, short value, size_t count) + { + foreach (i; 0 .. count) + p[i] = value; + return p; + } + + int* _memset32(int* p, int value, size_t count) + { + foreach (i; 0 .. count) + p[i] = value; + return p; + } + + long* _memset64(long* p, long value, size_t count) + { + foreach (i; 0 .. count) + p[i] = value; + return p; + } + + Bits80* _memset80(Bits80* p, Bits80 value, size_t count) + { + foreach (i; 0 .. count) + p[i] = value; + return p; + } + + Bits128* _memset128(Bits128* p, Bits128 value, size_t count) + { + foreach (i; 0 .. count) + p[i] = value; + return p; + } + + void[]* _memset128ii(void[]* p, void[] value, size_t count) + { + foreach (i; 0 .. count) + p[i] = value; + return p; + } + + Bits160* _memset160(Bits160* p, Bits160 value, size_t count) + { + foreach (i; 0 .. count) + p[i] = value; + return p; + } + + float* _memsetFloat(float* p, float value, size_t count) + { + foreach (i; 0 .. count) + p[i] = value; + return p; + } + + double* _memsetDouble(double* p, double value, size_t count) + { + foreach (i; 0 .. count) + p[i] = value; + return p; + } + + void* _memsetn(void* p, void* value, int count, size_t sizelem) + { + auto dst = cast(ubyte*) p; + auto src = cast(ubyte*) value; + foreach (_; 0 .. count) + { + foreach (j; 0 .. sizelem) + dst[j] = src[j]; + dst += sizelem; + } + return p; + } +} + +private ptrdiff_t try_copy_string(char[] buffer, const(char)[] src) pure nothrow @nogc +{ + if (buffer.ptr) + { + if (buffer.length < src.length) + return -1; + buffer[0 .. src.length] = src[]; + } + return src.length; +} diff --git a/src/std/math.d b/src/std/math.d new file mode 100644 index 0000000..0690df8 --- /dev/null +++ b/src/std/math.d @@ -0,0 +1,8 @@ +/// Minimal std.math stub - provides just the `pow` function that DMD's +/// `^^` operator lowering requires. Nothing else from Phobos is pulled in. +module std.math; + +// DMD lowers `a ^^ b` to `std.math.pow(a, b)`. +public import urt.math : pow; + +// TODO: do we need sqrt for `^^ 0.5`? diff --git a/src/urt/algorithm.d b/src/urt/algorithm.d index 14ecc1f..00090d7 100644 --- a/src/urt/algorithm.d +++ b/src/urt/algorithm.d @@ -1,6 +1,7 @@ module urt.algorithm; -import urt.traits : lvalueOf; +import urt.meta : AliasSeq; +import urt.traits : is_some_function, lvalue_of, Parameters, ReturnType, Unqual; import urt.util : swap; version = SmallSize; @@ -10,36 +11,44 @@ nothrow @nogc: auto compare(T, U)(auto ref T a, auto ref U b) { - static if (__traits(compiles, lvalueOf!T.opCmp(lvalueOf!U))) + static if (__traits(compiles, a.opCmp(b))) return a.opCmp(b); - else static if (__traits(compiles, lvalueOf!U.opCmp(lvalueOf!T))) + else static if (__traits(compiles, b.opCmp(a))) return -b.opCmp(a); - else static if (is(T : A[], A)) + else static if (is(T : A[], A) || is(U : B[], B)) { - import urt.traits : isPrimitive; + import urt.traits : is_primitive; + + static assert(is(T : A[], A) && is(U : B[], B), "TODO: compare an array with a not-array?"); auto ai = a.ptr; auto bi = b.ptr; - size_t len = a.length < b.length ? a.length : b.length; - static if (isPrimitive!A) + + // first compere the pointers... + if (ai !is bi) { - // compare strings - foreach (i; 0 .. len) + size_t len = a.length < b.length ? a.length : b.length; + static if (is_primitive!A) { - if (ai[i] != bi[i]) - return ai[i] < bi[i] ? -1 : 1; + // compare strings + foreach (i; 0 .. len) + { + if (ai[i] != bi[i]) + return ai[i] < bi[i] ? -1 : 1; + } } - } - else - { - // compare arrays - foreach (i; 0 .. len) + else { - auto cmp = compare(ai[i], bi[i]); - if (cmp != 0) - return cmp; + // compare arrays + foreach (i; 0 .. len) + { + if (auto cmp = compare(ai[i], bi[i])) + return cmp; + } } } + + // finally, compare the lengths if (a.length == b.length) return 0; return a.length < b.length ? -1 : 1; @@ -48,8 +57,39 @@ auto compare(T, U)(auto ref T a, auto ref U b) return a < b ? -1 : (a > b ? 1 : 0); } -size_t binarySearch(alias pred = void, T, Cmp...)(T[] arr, auto ref Cmp cmpArgs) +size_t binary_search(Pred)(const void[] arr, size_t stride, const void* value, auto ref Pred pred) + if (is_some_function!Pred && is(ReturnType!Pred == int) && is(Parameters!Pred == AliasSeq!(const void*, const void*))) { + debug assert(arr.length % stride == 0, "array length must be a multiple of stride"); + const count = arr.length / stride; + + const void* p = arr.ptr; + size_t low = 0; + size_t high = count; + while (low < high) + { + size_t mid = low + (high - low) / 2; + + // should we chase the first in a sequence of same values? + int cmp = pred(p + mid*stride, value); + if (cmp < 0) + low = mid + 1; + else + high = mid; + } + if (low == count) + return count; + if (pred(p + low*stride, value) == 0) + return low; + return count; +} + +size_t binary_search(alias pred = void, bool insert_pos = false, T, Cmp...)(T[] arr, auto ref Cmp cmp_args) + if (!is(Unqual!T == void)) +{ + static if (is(pred == void)) + static assert (cmp_args.length == 1, "binary_search without a predicate requires exactly one comparison argument"); + T* p = arr.ptr; size_t low = 0; size_t high = arr.length; @@ -59,7 +99,7 @@ size_t binarySearch(alias pred = void, T, Cmp...)(T[] arr, auto ref Cmp cmpArgs) static if (is(pred == void)) { // should we chase the first in a sequence of same values? - if (p[mid] < cmpArgs[0]) + if (p[mid] < cmp_args[0]) low = mid + 1; else high = mid; @@ -67,82 +107,104 @@ size_t binarySearch(alias pred = void, T, Cmp...)(T[] arr, auto ref Cmp cmpArgs) else { // should we chase the first in a sequence of same values? - int cmp = pred(p[mid], cmpArgs); + auto cmp = pred(p[mid], cmp_args); if (cmp < 0) low = mid + 1; else high = mid; } } - static if (is(pred == void)) + static if (insert_pos) { - if (p[low] == cmpArgs[0]) - return low; + return low; } else { - if (pred(p[low], cmpArgs) == 0) - return low; + if (low == arr.length) + return arr.length; + static if (is(pred == void)) + { + if (p[low] == cmp_args[0]) + return low; + } + else + { + if (pred(p[low], cmp_args) == 0) + return low; + } + return arr.length; } - return arr.length; } -void qsort(alias pred = void, T)(T[] arr) +void qsort(alias pred = void, T)(T[] arr) pure { + if (arr.length <= 1) + return; + version (SmallSize) + enum use_small_size_impl = true; + else + enum use_small_size_impl = false; + + if (!__ctfe && use_small_size_impl) { static if (is(pred == void)) - static if (__traits(compiles, lvalueOf!T.opCmp(lvalueOf!T))) - static int compare(const void* a, const void* b) nothrow @nogc + static if (__traits(compiles, lvalue_of!T.opCmp(lvalue_of!T))) + static int compare(const void* a, const void* b) pure nothrow @nogc => (*cast(const T*)a).opCmp(*cast(const T*)b); else - static int compare(const void* a, const void* b) nothrow @nogc + static int compare(const void* a, const void* b) pure nothrow @nogc => *cast(const T*)a < *cast(const T*)b ? -1 : *cast(const T*)a > *cast(const T*)b ? 1 : 0; else - static int compare(const void* a, const void* b) nothrow @nogc + static int compare(const void* a, const void* b) pure nothrow @nogc => pred(*cast(T*)a, *cast(T*)b); - qsort(arr[], T.sizeof, &compare, (void* a, void* b) nothrow @nogc { + qsort(arr[], T.sizeof, &compare, (void* a, void* b) pure nothrow @nogc { swap(*cast(T*)a, *cast(T*)b); }); } else { T* p = arr.ptr; - if (arr.length > 1) - { - size_t pivotIndex = arr.length / 2; - T* pivot = &p[pivotIndex]; + const n = cast(ptrdiff_t)arr.length; + + size_t pivotIndex = n / 2; + T* pivot = p + pivotIndex; - size_t i = 0; - size_t j = arr.length - 1; + size_t i = 0; + ptrdiff_t j = n - 1; - while (i <= j) + while (i <= j) + { + static if (is(pred == void)) { - static if (is(pred == void)) - { - while (p[i] < *pivot) i++; - while (p[j] > *pivot) j--; - } - else - { - while (pred(*cast(T*)&p[i], *cast(T*)pivot) < 0) i++; - while (pred(*cast(T*)&p[j], *cast(T*)pivot) > 0) j--; - } - if (i <= j) - { - swap(p[i], p[j]); - i++; - j--; - } + while (p[i] < *pivot) ++i; + while (p[j] > *pivot) --j; } + else + { + while (pred(p[i], *pivot) < 0) ++i; + while (pred(p[j], *pivot) > 0) --j; + } + if (i <= j) + { + // track pivot value across swaps + if (p + i == pivot) + pivot = p + j; + else if (p + j == pivot) + pivot = p + i; - if (j > 0) - qsort(p[0 .. j + 1]); - if (i < arr.length) - qsort(p[i .. arr.length]); + swap(p[i], p[j]); + ++i; + --j; + } } + + if (j >= 0) + qsort!pred(p[0 .. j + 1]); + if (i < n) + qsort!pred(p[i .. n]); } } @@ -151,7 +213,7 @@ unittest struct S { int x; - int opCmp(ref const S rh) const nothrow @nogc + int opCmp(ref const S rh) pure const nothrow @nogc => x < rh.x ? -1 : x > rh.x ? 1 : 0; } @@ -159,18 +221,18 @@ unittest qsort(arr); assert(arr == [-1, 3, 17, 30, 100]); - S[5] arr2 = [ S(3), S(100), S(-1), S(17), S(30)]; + S[5] arr2 = [ S(3), S(100), S(-1), S(17), S(30) ]; qsort(arr2); foreach (i, ref s; arr2) assert(s.x == arr[i]); // test binary search, not that they're sorted... - assert(binarySearch(arr, -1) == 0); - assert(binarySearch!(s => s.x < 30 ? -1 : s.x > 30 ? 1 : 0)(arr2) == 3); - assert(binarySearch(arr, 0) == arr.length); + assert(binary_search(arr, -1) == 0); + assert(binary_search!(s => s.x < 30 ? -1 : s.x > 30 ? 1 : 0)(arr2) == 3); + assert(binary_search(arr, 0) == arr.length); int[10] rep = [1, 10, 10, 10, 10, 10, 10, 10, 10, 100]; - assert(binarySearch(rep, 10) == 1); + assert(binary_search(rep, 10) == 1); } @@ -181,34 +243,36 @@ version (SmallSize) // just one generic implementation to minimise the code... // kinda slow though... look at all those multiplies! // maybe there's some way to make this faster :/ - void qsort(void[] arr, size_t elementSize, int function(const void* a, const void* b) nothrow @nogc compare, void function(void* a, void* b) nothrow @nogc swap) + void qsort(void[] arr, size_t element_size, int function(const void* a, const void* b) pure nothrow @nogc compare, void function(void* a, void* b) pure nothrow @nogc swap) pure { void* p = arr.ptr; - size_t length = arr.length / elementSize; - if (length > 1) - { - size_t pivotIndex = length / 2; - void* pivot = p + pivotIndex*elementSize; + size_t length = arr.length / element_size; + if (length <= 1) + return; - size_t i = 0; - size_t j = length - 1; + size_t pivot_index = length / 2; + size_t last = length - 1; + swap(p + pivot_index*element_size, p + last*element_size); - while (i <= j) + void* pivot = p + last*element_size; + + size_t partition = 0; + for (size_t k = 0; k < last; ++k) + { + void* elem = p + k*element_size; + if (compare(elem, pivot) < 0) { - while (compare(p + i*elementSize, pivot) < 0) i++; - while (compare(p + j*elementSize, pivot) > 0) j--; - if (i <= j) - { - swap(p + i*elementSize, p + j*elementSize); - i++; - j--; - } + if (k != partition) + swap(elem, p + partition*element_size); + ++partition; } - - if (j > 0) - qsort(p[0 .. (j + 1)*elementSize], elementSize, compare, swap); - if (i < length) - qsort(p[i*elementSize .. length*elementSize], elementSize, compare, swap); } + + swap(p + partition*element_size, p + last*element_size); + + if (partition > 1) + qsort(p[0 .. partition*element_size], element_size, compare, swap); + if (partition + 1 < length) + qsort(p[(partition + 1)*element_size .. length*element_size], element_size, compare, swap); } } diff --git a/src/urt/array.d b/src/urt/array.d index 8d9858c..35f285c 100644 --- a/src/urt/array.d +++ b/src/urt/array.d @@ -1,7 +1,10 @@ module urt.array; -import urt.mem; - +import urt.lifetime : move, emplace, moveEmplace; +import urt.mem : memcpy, memmove, memset; +import urt.mem.alloc; +import urt.mem.allocator : NoGCAllocator; +import urt.traits : is_some_char, is_primitive, is_trivial, Unqual; nothrow @nogc: @@ -79,40 +82,29 @@ ref inout(T)[N] takeBack(size_t N, T)(ref inout(T)[] arr) pure return t[0..N]; } -bool exists(T)(const(T)[] arr, auto ref const T el, size_t *pIndex = null) -{ - foreach (i, ref e; arr) - { - if (e.elCmp(el)) - { - if (pIndex) - *pIndex = i; - return true; - } - } - return false; -} - // TODO: I'd like it if these only had one arg (T) somehow... size_t findFirst(T, U)(const(T)[] arr, auto ref const U el) + if (!is_some_char!T) { size_t i = 0; - while (i < arr.length && !arr[i].elCmp(el)) + while (i < arr.length && !arr[i].el_cmp(el)) ++i; return i; } // TODO: I'd like it if these only had one arg (T) somehow... size_t findLast(T, U)(const(T)[] arr, auto ref const U el) + if (!is_some_char!T) { - ptrdiff_t last = length-1; - while (last >= 0 && !arr[last].elCmp(el)) + ptrdiff_t last = arr.length-1; + while (last >= 0 && !arr[last].el_cmp(el)) --last; - return last < 0 ? length : last; + return last < 0 ? arr.length : last; } // TODO: I'd like it if these only had one arg (T) somehow... size_t findFirst(T, U)(const(T)[] arr, U[] seq) + if (!is_some_char!T) { if (seq.length == 0) return 0; @@ -129,6 +121,7 @@ size_t findFirst(T, U)(const(T)[] arr, U[] seq) // TODO: I'd like it if these only had one arg (T) somehow... size_t findLast(T, U)(const(T)[] arr, U[] seq) + if (!is_some_char!T) { if (seq.length == 0) return arr.length; @@ -143,7 +136,8 @@ size_t findLast(T, U)(const(T)[] arr, U[] seq) return arr.length; } -size_t findFirst(T)(const(T)[] arr, bool delegate(auto ref const T) nothrow @nogc pred) +size_t findFirst(T)(const(T)[] arr, bool delegate(ref const T) nothrow @nogc pred) + if (!is_some_char!T) { size_t i = 0; while (i < arr.length && !pred(arr[i])) @@ -151,6 +145,39 @@ size_t findFirst(T)(const(T)[] arr, bool delegate(auto ref const T) nothrow @nog return i; } +bool contains(T, U)(const(T)[] arr, auto ref const U el, size_t *index = null) + if (!is_some_char!T) +{ + size_t i = findFirst(arr, el); + if (i == arr.length) + return false; + if (index) + *index = i; + return true; +} + +bool contains(T, U)(const(T)[] arr, U[] seq, size_t *index = null) + if (!is_some_char!T) +{ + size_t i = findFirst(arr, seq); + if (i == arr.length) + return false; + if (index) + *index = i; + return true; +} + +bool contains(T)(const(T)[] arr, bool delegate(ref const T) nothrow @nogc pred, size_t *index = null) + if (!is_some_char!T) +{ + size_t i = findFirst(arr, pred); + if (i == arr.length) + return false; + if (index) + *index = i; + return true; +} + ptrdiff_t indexOfElement(T, U)(const(T)[] arr, const(U)* el) { if (el < arr.ptr || el >= arr.ptr + arr.length) @@ -168,17 +195,153 @@ inout(T)* search(T)(inout(T)[] arr, bool delegate(ref const T) nothrow @nogc pre return null; } -U[] copyTo(T, U)(T[] arr, U[] dest) +// TODO: use is_trivially_copy_constructible! +private enum copy_use_memcpy(T, U) = is_trivial!T && is(Unqual!T == U); +private enum copy_use_memcpy(T) = copy_use_memcpy!(T, T); +// TODO: use is_trivially_move_constructible! +private enum move_use_memcpy(T, U) = is_trivial!T && is(Unqual!T == U); +private enum move_use_memcpy(T) = move_use_memcpy!(T, T); + +U[] copy_to(bool overlapping = false, bool move = false, T, U)(T[] arr, U[] dest) { + alias UT = Unqual!T; + enum same_type = is(UT == U); + enum both_byte = (is(UT == ubyte) || is(UT == byte) || is(UT == char) || is(UT == void)) && + (is(U == ubyte) || is(U == byte) || is(U == char) || is(U == void)); + + static assert (!overlapping || same_type, "overlapping copy must be same type"); + assert(dest.length >= arr.length); - dest[0 .. arr.length] = arr[]; + + if (__ctfe) + { + static if (same_type) + { + // handle overlapping copies correctly where src < dst + if (arr.ptr < dest.ptr) + { + for (ptrdiff_t i = ptrdiff_t(arr.length) - 1; i >= 0; --i) + dest[i] = arr[i]; + return dest[0 .. arr.length]; + } + } + for (size_t i = 0; i < arr.length; ++i) + dest[i] = arr[i]; + } + else + { + static if (!same_type && both_byte) + return copy_to!(overlapping, move)(cast(ubyte[])arr, cast(ubyte[])dest); + static if ((!move && copy_use_memcpy!(T, U)) || (move && move_use_memcpy!(T, U))) + { + static if (move && copy_use_memcpy!(T, U)) + return copy_to!(overlapping, false, T, U)(arr, dest); + else static if (overlapping) + memmove(dest.ptr, arr.ptr, arr.length * T.sizeof); + else + memcpy(dest.ptr, arr.ptr, arr.length * T.sizeof); + } + else static if (move) + { +// pragma(msg, "move: ", T, " --> ", U, is(T == class) ? " *** class" : ""); + static if (overlapping) + { + if (arr.ptr < dest.ptr && dest.ptr < arr.ptr + arr.length) + { + for (ptrdiff_t i = ptrdiff_t(arr.length) - 1; i >= 0; --i) + .move(arr[i], dest[i]); + return dest[0 .. arr.length]; + } + } + for (size_t i = 0; i < arr.length; ++i) + .move(arr[i], dest[i]); + } + else + { +// pragma(msg, "copy: ", T, " --> ", U, is(T == class) ? " *** class" : ""); + static if (overlapping) + { + if (arr.ptr < dest.ptr && dest.ptr < arr.ptr + arr.length) + { + for (ptrdiff_t i = ptrdiff_t(arr.length) - 1; i >= 0; --i) + dest[i] = arr[i]; + return dest[0 .. arr.length]; + } + } + else static if (same_type) + dest[] = arr[]; + else for (size_t i = 0; i < arr.length; ++i) + dest[i] = arr[i]; + } + } return dest[0 .. arr.length]; } +U[] move_to(bool overlapping = false, T, U)(T[] arr, U[] dest) + => copy_to!(overlapping, true, T, U)(arr, dest); + +void emplace_all(bool move = false, T, U)(T[] arr, U[] dest) +{ + assert(!__ctfe, "emplace_all should not be called at compile time"); + + static if (move && move_use_memcpy!(T, U)) + move_to(cast(Unqual!T[])arr, dest); + else static if ((!move && copy_use_memcpy!(T, U)) || (is(T : U) && is_trivial!U)) + copy_to(cast(Unqual!T[])arr, dest); + else static if (move) + { +// pragma(msg, "move-emplace: ", T, " --> ", U); + for (size_t i = 0; i < arr.length; ++i) + moveEmplace(arr[i], dest[i]); + } + else + { +// pragma(msg, "emplace: ", T, " --> ", U); + for (size_t i = 0; i < arr.length; ++i) + emplace!T(&dest[i], arr[i]); + } +} +void move_emplace_all(T, U)(T[] arr, U[] dest) + => emplace_all!(true, T, U)(arr, dest); -T[] duplicate(T)(const T[] src, NoGCAllocator allocator) nothrow @nogc +void destroy_all(bool initialize = true, T)(T[] arr) { - T[] r = cast(T[])allocator.alloc(src.length * T.sizeof); - r[] = src[]; + assert(!__ctfe, "destroy_all should not be called at compile time"); + + static if (is_trivial!T) + { + static if (initialize) + init_all(arr); + } + else + { + for (uint i = 0; i < arr.length; ++i) + destroy!initialize(arr[i]); + } +} + +void init_all(T)(T[] arr) +{ + assert(!__ctfe, "init_all should not be called at compile time"); + + static if (is_trivial!T) + { + static if (__traits(isZeroInit, T)) + memset(arr.ptr, 0, arr.length * T.sizeof); + else + arr[] = T.init; + } + else for (size_t i = 0; i < arr.length; ++i) + emplace!T(&arr[i]); +} + +T[] duplicate(T)(const T[] src, NoGCAllocator allocator = null) nothrow @nogc +{ + T[] r; + if (allocator) + r = cast(T[])allocator.alloc(src.length * T.sizeof); + else + r = cast(T[])alloc(src.length * T.sizeof); + emplace_all(src, r); return r; } @@ -189,6 +352,10 @@ struct Array(T, size_t EmbedCount = 0) { static assert(EmbedCount == 0, "Not without move semantics!"); + alias This = typeof(this); + + T* ptr; + // constructors // TODO: DELETE POSTBLIT! @@ -201,7 +368,7 @@ struct Array(T, size_t EmbedCount = 0) this = t[]; } - this(ref typeof(this) val) + this(ref This val) { this(val[]); } @@ -218,8 +385,7 @@ struct Array(T, size_t EmbedCount = 0) { debug assert(arr.length <= uint.max); reserve(arr.length); - for (uint i = 0; i < arr.length; ++i) - emplace!T(&ptr[i], arr.ptr[i]); + emplace_all(arr[], ptr[0..arr.length]); _length = cast(uint)arr.length; } @@ -247,7 +413,7 @@ struct Array(T, size_t EmbedCount = 0) ~this() { clear(); - if (hasAllocation()) + if (has_allocation()) free(ptr); } @@ -273,11 +439,12 @@ nothrow @nogc: void opAssign(U)(U[] arr) if (is(U : T)) { + // TODO: WHAT IF arr IS A SLICE OF THIS?!!? + debug assert(arr.length <= uint.max); clear(); reserve(arr.length); - for (uint i = 0; i < arr.length; ++i) - emplace!T(&ptr[i], arr.ptr[i]); + emplace_all(arr[], ptr[0 .. arr.length]); _length = cast(uint)arr.length; } @@ -288,7 +455,98 @@ nothrow @nogc: } // manipulation - ref Array!(T, EmbedCount) concat(Things...)(auto ref Things things); + static if (!is_some_char!T) + { + alias concat = append; // TODO: REMOVE THIS ALIAS, we phase out the old name... + + ref Array!(T, EmbedCount) append(Things...)(auto ref Things things) + { + size_t ext_len = 0; + static foreach (i; 0 .. things.length) + { + static if (is(Things[i] == U[], U) && is(U : T)) + ext_len += things[i].length; + else static if (is(Things[i] == U[N], U, size_t N) && is(U : T)) + ext_len += N; + else static if (is(Things[i] : T)) + ext_len += 1; + else + static assert(false, "Invalid type for concat"); + } + grow(_length + ext_len); + static foreach (i; 0 .. things.length) + { + static if (is(Things[i] == V[], V) && is(V : T)) + { + emplace_all(things[i][], ptr[_length .. _length + things[i].length]); + _length += cast(uint)things[i].length; + } + else static if (is(Things[i] == V[M], V, size_t M) && is(V : T)) + { + emplace_all(things[i][], ptr[_length .. _length + M]); + _length += cast(uint)M; + } + else static if (is(Things[i] : T)) + { + static if (is_trivial!T) + ptr[_length++] = things[i]; + else + emplace!T(&ptr[_length++], forward!(things[i])); + } + } + return this; + } + } + else + { + // char arrays are really just a string buffer, and so we'll expand the capability of concat to match what `MutableString` accepts... + static assert(is(T == char), "TODO: wchar and dchar"); // needs buffer length counting helpers + + // TODO: string's have this function `concat` which clears the string first, and that's different than Array + // we need to tighten this up! + ref Array!(T, EmbedCount) concat(Things...)(auto ref Things things) + { + pragma(inline, true); + clear(); + return append(forward!things); + } + + ref Array!(T, EmbedCount) append(Things...)(auto ref Things things) + { + import urt.string.format : _concat = concat_impl, normalise_args; + + auto args = normalise_args(things); + + size_t ext_len = _concat(null, args).length; + grow(_length + ext_len); + _concat(ptr[_length .. _length + ext_len], args); + _length += ext_len; + return this; + } + + ref Array!(T, EmbedCount) append_format(Things...)(const(char)[] format, auto ref Things args) + { + import urt.string.format : _format = format; + + size_t ext_len = _format(null, format, args).length; + grow(_length + ext_len); + _format(ptr[_length .. _length + ext_len], format, forward!args); + _length += ext_len; + return this; + } + } + + T[] extend(bool do_init = true)(size_t length) + { + assert(_length + length <= uint.max); + + size_t old_len = _length; + grow(_length + length); + static if (do_init) + init_all(ptr[_length .. _length + length]); + _length += cast(uint)length; + return ptr[old_len .. _length]; + } bool empty() const => _length == 0; @@ -306,7 +564,7 @@ nothrow @nogc: return ptr[_length - 1]; } - ref T pushFront() + ref T pushFront()() { static if (is(T == class) || is(T == interface)) return pushFront(null); @@ -315,33 +573,12 @@ nothrow @nogc: } ref T pushFront(U)(auto ref U item) if (is(U : T)) - { - static if (is(T == class) || is(T == interface)) - { - uint len = _length; - reserve(len + 1); - _length = len + 1; - for (uint i = len; i > 0; --i) - ptr[i] = ptr[i-1]; - ptr[0] = item; - return ptr[0]; - } - else - { - uint len = _length; - reserve(len + 1); - _length = len + 1; - for (uint i = len; i > 0; --i) - { - moveEmplace!T(ptr[i-1], ptr[i]); - destroy!false(ptr[i-1]); - } - emplace!T(&ptr[0], forward!item); - return ptr[0]; - } - } + => insert(0, forward!item); + ref T emplaceFront(Args...)(auto ref Args args) + if (!is(T == class) && !is(T == interface)) + => insertEmplace(0, forward!args); - ref T pushBack() + ref T pushBack()() { static if (is(T == class) || is(T == interface)) return pushBack(null); @@ -351,156 +588,111 @@ nothrow @nogc: ref T pushBack(U)(auto ref U item) if (is(U : T)) { + reserve(_length + 1); static if (is(T == class) || is(T == interface)) - { - uint len = _length; - reserve(len + 1); - _length = len + 1; - ptr[len] = item; - return ptr[len]; - } + return (ptr[_length++] = item); else - { - uint len = _length; - reserve(len + 1); - _length = len + 1; - emplace!T(&ptr[len], forward!item); - return ptr[len]; - } + return *emplace!T(&ptr[_length++], forward!item); } - - ref T emplaceFront(Args...)(auto ref Args args) - { - uint len = _length; - reserve(len + 1); - _length = len + 1; - for (uint i = len; i > 0; --i) - { - moveEmplace(ptr[i-1], ptr[i]); - destroy!false(ptr[i-1]); - } - emplace!T(&ptr[0], forward!args); - return ptr[0]; - } - ref T emplaceBack(Args...)(auto ref Args args) + if (!is(T == class) && !is(T == interface)) { - uint len = _length; - reserve(len + 1); - _length = len + 1; - emplace!T(&ptr[len], forward!args); - return ptr[len]; + reserve(_length + 1); + return *emplace!T(&ptr[_length++], forward!args); } - T popFront() + ref T insert(U)(size_t pos, auto ref U item) + if (is(U : T)) { - debug assert(_length > 0); - - // TODO: this should be removed and uses replaced with a queue container - static if (is(T == class) || is(T == interface)) - { - T copy = ptr[0]; - for (uint i = 1; i < _length; ++i) - ptr[i-1] = ptr[i]; - ptr[--_length] = null; - return copy; - } + assert(pos <= _length, "Insert position out of range"); + reserve(_length + 1); + static if (is_trivial!T) + memmove(ptr + pos + 1, ptr + pos, (_length++ - pos) * T.sizeof); else { - T copy = ptr[0].move; - for (uint i = 1; i < _length; ++i) + for (uint i = _length++; i > pos; --i) { + moveEmplace!T(ptr[i-1], ptr[i]); destroy!false(ptr[i-1]); - moveEmplace(ptr[i], ptr[i-1]); } - destroy!false(ptr[--_length]); - return copy.move; } + static if (is(T == class) || is(T == interface)) + return (ptr[pos] = item); + else + return *emplace!T(&ptr[pos], forward!item); } - T popBack() + ref T insertEmplace(Args...)(size_t pos, auto ref Args args) + if (!is(T == class) && !is(T == interface)) { - debug assert(_length > 0); - - static if (is(T == class) || is(T == interface)) - { - uint last = _length-1; - T copy = ptr[last]; - ptr[last] = null; - _length = last; - return copy; - } + assert(pos <= _length, "Insert position out of range"); + reserve(_length + 1); + static if (is_trivial!T) + memmove(ptr + pos + 1, ptr + pos, (_length++ - pos) * T.sizeof); else { - uint last = _length-1; - T copy = ptr[last].move; - destroy!false(ptr[last]); - _length = last; - return copy.move; + for (uint i = _length++; i > pos; --i) + { + moveEmplace!T(ptr[i-1], ptr[i]); + destroy!false(ptr[i-1]); + } } + return *emplace!T(&ptr[pos], forward!args); } - Array!T takeFront(size_t count) + T popFront() { - assert(false, "TODO"); + debug assert(_length > 0, "Range error"); + T r = ptr[0].move; + remove(0); + return r; } - Array!(T, N) takeFront(size_t N)() + T popBack() { - assert(false, "TODO"); + debug assert(_length > 0, "Range error"); + T r = ptr[_length - 1].move; + destroy!false(ptr[--_length]); + return r; } - Array!T takeBack(size_t count) + Array!T takeFront()(size_t count) { - assert(false, "TODO"); + auto r = Array!T(Reserve, count); + move_emplace_all(ptr[0 .. count], r.ptr[0 .. count]); + r._length = cast(uint)count; + remove(0, count); + return r; } - Array!(T, N) takeBack(size_t N)() + Array!T takeBack()(size_t count) { - assert(false, "TODO"); + auto r = Array!T(Reserve, count); + move_emplace_all(ptr[_length - count .. _length], r.ptr[0 .. count]); + r._length = cast(uint)count; + remove(_length - count, count); + return r; } - void remove(size_t i) + void remove(size_t i, size_t count = 1) { - debug assert(i < _length); - - static if (is(T == class) || is(T == interface)) - { - for (size_t j = i + 1; j < _length; ++j) - ptr[j-1] = ptr[j]; - ptr[--_length] = null; - } - else - { - destroy!false(ptr[i]); - for (size_t j = i + 1; j < _length; ++j) - { - emplace!T(&ptr[j-1], ptr[j].move); - destroy!false(ptr[j]); - } - --_length; - } + debug assert(i + count <= _length, "Range error"); + if (i < _length - count) + move_to!true(ptr[i + count .. _length], ptr[i .. _length - count]); + destroy_all!false(ptr[_length - count .. length]); + _length -= cast(uint)count; } - void remove(const(T)* pItem) { remove(ptr[0 .. _length].indexOfElement(pItem)); } void removeFirst(U)(ref const U item) { remove(ptr[0 .. _length].findFirst(item)); } - void removeSwapLast(size_t i) + void removeSwapLast(size_t i, size_t count = 1) { - assert(i < _length, "Range error"); - static if (is(T == class) || is(T == interface)) - { - ptr[i] = ptr[--_length]; - ptr[_length] = null; - } - else - { - destroy!false(ptr[i]); - emplace!T(&ptr[i], ptr[--_length].move); - destroy!false(ptr[_length]); - } + debug assert(i + count <= _length, "Range error"); + if (i < _length - count) + move_to!true(ptr[_length - count .. _length], ptr[i .. i + count]); + destroy_all!false(ptr[_length - count .. length]); + _length -= cast(uint)count; } - void removeSwapLast(const(T)* pItem) { removeSwapLast(ptr[0 .. _length].indexOfElement(pItem)); } void removeFirstSwapLast(U)(ref const U item) { removeSwapLast(ptr[0 .. _length].findFirst(item)); } @@ -513,154 +705,125 @@ nothrow @nogc: inout(void)[] getBuffer() inout { static if (EmbedCount > 0) - return ptr ? ptr[0 .. allocCount()] : embed[]; + return ptr ? ptr[0 .. alloc_count()] : embed[]; else - return ptr ? ptr[0 .. allocCount()] : null; + return ptr ? ptr[0 .. alloc_count()] : null; } - bool opCast(T : bool)() const + bool opCast(T : bool)() const pure => _length != 0; - size_t opDollar() const + size_t opDollar() const pure => _length; // full slice: arr[] - inout(T)[] opIndex() inout + inout(T)[] opIndex() inout pure => ptr[0 .. _length]; + void opIndexAssign(U)(U[] rh) + { + debug assert(rh.length == _length, "Range error"); + ptr[0 .. _length] = rh[]; + } + // array indexing: arr[i] - ref inout(T) opIndex(size_t i) inout + ref inout(T) opIndex(size_t i) inout pure { debug assert(i < _length, "Range error"); return ptr[i]; } // array slicing: arr[x .. y] - inout(T)[] opIndex(uint[2] i) inout + inout(T)[] opIndex(size_t[2] i) inout pure => ptr[i[0] .. i[1]]; - uint[2] opSlice(size_t dim : 0)(size_t x, size_t y) + void opIndexAssign(U)(U[] rh, size_t[2] i) { - debug assert(y <= _length, "Range error"); - return [cast(uint)x, cast(uint)y]; + debug assert(i[1] <= _length && i[1] - i[0] == rh.length, "Range error"); + ptr[i[0] .. i[1]] = rh[]; } - void opOpAssign(string op : "~", U)(auto ref U el) - if (is(U : T)) + size_t[2] opSlice(size_t dim : 0)(size_t x, size_t y) const pure { - pushBack(forward!el); + debug assert(y <= _length, "Range error"); + return [x, y]; } - void opOpAssign(string op : "~", U)(U[] arr) - if (is(U : T)) + void opOpAssign(string op : "~", U)(auto ref U rh) { - reserve(_length + arr.length); - foreach (ref e; arr) - pushBack(e); + append(forward!rh); } void reserve(size_t count) { - if (count > allocCount()) + if (count > alloc_count()) { debug assert(count <= uint.max, "Exceed maximum size"); - T* newArray = allocate(cast(uint)count); - - // TODO: POD should memcpy... (including class) - static if (is(T == class) || is(T == interface)) - { - for (uint i = 0; i < _length; ++i) - newArray[i] = ptr[i]; - } - else - { - for (uint i = 0; i < _length; ++i) - { - moveEmplace(ptr[i], newArray[i]); - destroy!false(ptr[i]); - } - } + T* new_array = allocate(cast(uint)count); + move_emplace_all(ptr[0 .. _length], new_array[0 .. _length]); + destroy_all!false(ptr[0 .. _length]); - if (hasAllocation()) + if (has_allocation()) free(ptr); - - ptr = newArray; + ptr = new_array; } } - void alloc(size_t count) - { - assert(false); - } - void resize(size_t count) { if (count == _length) return; - if (count < _length) { - static if (is(T == class) || is(T == interface)) - { - for (ptrdiff_t i = _length - 1; i >= count; --i) - ptr[i] = null; - } - else - { - for (ptrdiff_t i = _length - 1; i >= count; --i) - destroy!false(ptr[i]); - } + destroy_all!false(ptr[count .. _length]); _length = cast(uint)count; } else { reserve(count); - static if (is(T == class) || is(T == interface)) - { - foreach (i; _length .. count) - ptr[i] = null; - } - else - { - foreach (i; _length .. count) - emplace!T(&ptr[i]); - } + init_all(ptr[_length .. count]); _length = cast(uint)count; } } void clear() { - static if (!is(T == class) && !is(T == interface)) - for (uint i = 0; i < _length; ++i) - destroy!false(ptr[i]); + destroy_all!false(ptr[0 .. _length]); _length = 0; } + import urt.string.format : FormatArg, formatValue; + ptrdiff_t toString()(char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) const + => formatValue(ptr[0 .. _length], buffer, format, formatArgs); + + ptrdiff_t fromString()(const(char)[] s) + { + assert(false, "TODO"); + } + private: - T* ptr; uint _length; static if (EmbedCount > 0) T[EmbedCount] embed = void; - bool hasAllocation() const + bool has_allocation() const pure { static if (EmbedCount > 0) return ptr && ptr != embed.ptr; else return ptr !is null; } - uint allocCount() const - => hasAllocation() ? (cast(uint*)ptr)[-1] : EmbedCount; + uint alloc_count() const pure + => has_allocation() ? (cast(uint*)ptr)[-1] : EmbedCount; T* allocate(uint count) { enum AllocAlignment = T.alignof < 4 ? 4 : T.alignof; enum AllocPrefixBytes = T.sizeof < 4 ? 4 : T.sizeof; - void[] mem = defaultAllocator().alloc(AllocPrefixBytes + T.sizeof * count, AllocAlignment); + void[] mem = .alloc(AllocPrefixBytes + T.sizeof * count, AllocAlignment); T* array = cast(T*)(mem.ptr + AllocPrefixBytes); (cast(uint*)array)[-1] = count; return array; @@ -669,17 +832,27 @@ private: { enum AllocPrefixBytes = T.sizeof < 4 ? 4 : T.sizeof; - defaultAllocator().free((cast(void*)ptr - AllocPrefixBytes)[0 .. AllocPrefixBytes + T.sizeof * allocCount()]); + .free((cast(void*)ptr - AllocPrefixBytes)[0 .. AllocPrefixBytes + T.sizeof * alloc_count()]); } - pragma(inline, true) - static uint numToAlloc(uint i) + void grow(size_t target) { - // TODO: i'm sure we can imagine a better heuristic... - return i > 16 ? i * 2 : 16; + size_t cap = alloc_count(); + if (target <= cap) + return; + assert(target <= uint.max && cap < uint.max); + size_t new_cap = cap * 2; + if (new_cap < target) + new_cap = target; + if (new_cap > uint.max) + new_cap = uint.max; + reserve(new_cap); } - auto __debugExpanded() const pure => ptr[0 .. _length]; + version (Windows) + { + auto __debugExpanded() const pure => ptr[0 .. _length]; + } } // SharedArray is a ref-counted array which can be distributed @@ -689,7 +862,7 @@ struct SharedArray(T) this(this) { if (ptr) - incRef(); + inc_ref(); } this(typeof(null)) {} @@ -699,7 +872,7 @@ struct SharedArray(T) ptr = val.ptr; _length = val._length; if (ptr) - incRef(); + inc_ref(); } this(U)(U[] arr) @@ -721,11 +894,6 @@ struct SharedArray(T) nothrow @nogc: - void opAssign(typeof(null)) - { - clear(); - } - void opAssign(ref typeof(this) val) { clear(); @@ -733,23 +901,21 @@ nothrow @nogc: ptr = val.ptr; _length = val._length; if (ptr) - incRef(); + inc_ref(); } void opAssign(U)(U[] arr) if (is(U : T)) { debug assert(arr.length <= uint.max); - uint len = cast(uint)arr.length; + _length = cast(uint)arr.length; clear(); - _length = len; if (len > 0) { - ptr = allocate(len); - for (uint i = 0; i < len; ++i) - emplace!T(&ptr[i], arr.ptr[i]); + ptr = allocate(_length); + emplace_all(arr[], ptr[0 .. _length]); } else ptr = null; @@ -780,9 +946,9 @@ nothrow @nogc: // inout(void)[] getBuffer() inout // { // static if (EmbedCount > 0) -// return ptr ? ptr[0 .. allocCount()] : embed[]; +// return ptr ? ptr[0 .. alloc_count()] : embed[]; // else -// return ptr ? ptr[0 .. allocCount()] : null; +// return ptr ? ptr[0 .. alloc_count()] : null; // } bool opCast(T : bool)() const @@ -814,12 +980,9 @@ nothrow @nogc: void clear() { - static if (!is(T == class) && !is(T == interface)) - for (uint i = 0; i < _length; ++i) - ptr[i].destroy!false(); - + destroy_all!false(ptr[0 .. _length]); if (ptr) - decRef(); + dec_ref(); ptr = null; _length = 0; } @@ -828,12 +991,12 @@ private: T* ptr; uint _length; - void incRef() + void inc_ref() { ++(cast(uint*)ptr)[-1]; } - void decRef() + void dec_ref() { uint* rc = cast(uint*)ptr - 1; if (*rc == 0) @@ -846,7 +1009,7 @@ private: { enum AllocAlignment = T.alignof < uint.alignof ? uint.alignof : T.alignof; - void[] mem = defaultAllocator().alloc(AllocAlignment + T.sizeof * count, AllocAlignment); + void[] mem = .alloc(AllocAlignment + T.sizeof * count, AllocAlignment); T* array = cast(T*)(mem.ptr + AllocPrefixBytes); (cast(uint*)array)[-1] = 0; return array; @@ -855,7 +1018,7 @@ private: { enum AllocAlignment = T.alignof < uint.alignof ? uint.alignof : T.alignof; - defaultAllocator().free((cast(void*)ptr - AllocAlignment)[0 .. AllocAlignment + T.sizeof * allocCount()]); + .free((cast(void*)ptr - AllocAlignment)[0 .. AllocAlignment + T.sizeof * alloc_count()]); } } @@ -863,21 +1026,21 @@ private: private: pragma(inline, true) -bool elCmp(T)(const T a, const T b) +bool el_cmp(T)(const T a, const T b) if (is(T == class) || is(T == interface)) { return a is b; } pragma(inline, true) -bool elCmp(T)(const T a, const T b) +bool el_cmp(T)(const T a, const T b) if (is(T == U[], U)) { return a[] == b[]; } pragma(inline, true) -bool elCmp(T)(auto ref const T a, auto ref const T b) +bool el_cmp(T)(auto ref const T a, auto ref const T b) if (!is(T == class) && !is(T == interface) && !is(T == U[], U)) { return a == b; diff --git a/src/urt/async.d b/src/urt/async.d index fee575f..557f24a 100644 --- a/src/urt/async.d +++ b/src/urt/async.d @@ -20,7 +20,7 @@ Promise!(ReturnType!Fun)* async(alias Fun, size_t stackSize = DefaultStackSize, // TODO: nice to rework this; maybe make stackSize a not-template-arg, and receive a function call/closure object which stores the args Promise!(ReturnType!Fun)* async(size_t stackSize = DefaultStackSize, Fun, Args...)(Fun fun, auto ref Args args) - if (isSomeFunction!Fun) + if (is_some_function!Fun) { alias Result = ReturnType!Fun; Promise!Result* r = cast(Promise!Result*)defaultAllocator().alloc(Promise!Result.sizeof, Promise!Result.alignof); @@ -60,7 +60,7 @@ Promise!(ReturnType!Fun)* async(size_t stackSize = DefaultStackSize, Fun, Args.. void freePromise(T)(ref Promise!T* promise) { - assert(promise.state() != Promise!T.State.Pending, "Promise still pending!"); + assert(promise.state() != PromiseState.Pending, "Promise still pending!"); defaultAllocator().freeT(promise); promise = null; } @@ -79,20 +79,20 @@ void asyncUpdate() if (!t.event.ready()) continue; } - t.resume(); + t.call.fibre.resume(); } } -struct Promise(Result) +enum PromiseState { - enum State - { - Pending, - Ready, - Failed, - } + Pending, + Ready, + Failed +} +struct Promise(Result) +{ // construct using `async()` functions... this() @disable; this(ref typeof(this)) @disable; // disable copy constructor @@ -117,29 +117,29 @@ struct Promise(Result) } } - State state() const + PromiseState state() const { if (async.fibre.wasAborted()) - return State.Failed; + return PromiseState.Failed; else if (async.fibre.isFinished()) - return State.Ready; + return PromiseState.Ready; else - return State.Pending; + return PromiseState.Pending; } bool finished() const - => state() != State.Pending; + => state() != PromiseState.Pending; ref Result result() { - assert(state() == State.Ready, "Promise not fulfilled!"); + assert(state() == PromiseState.Ready, "Promise not fulfilled!"); static if (!is(Result == void)) return value; } void abort() { - assert(state() == State.Pending, "Promise already fulfilled!"); + assert(state() == PromiseState.Pending, "Promise already fulfilled!"); async.fibre.abort(); } @@ -180,11 +180,11 @@ unittest } auto p = async!fun(1, 2); - assert(p.state() == p.State.Ready); + assert(p.state() == PromiseState.Ready); assert(p.result() == 3); freePromise(p); p = async!fun(10, 20); - assert(p.state() == p.State.Ready); + assert(p.state() == PromiseState.Ready); assert(p.result() == 30); freePromise(p); @@ -201,13 +201,13 @@ unittest } auto p_yield = async(&fun_yield); - assert(p_yield.state() == p_yield.State.Pending); + assert(p_yield.state() == PromiseState.Pending); assert(val == 1); asyncUpdate(); - assert(p_yield.state() == p_yield.State.Pending); + assert(p_yield.state() == PromiseState.Pending); assert(val == 2); asyncUpdate(); - assert(p_yield.state() == p_yield.State.Ready); + assert(p_yield.state() == PromiseState.Ready); assert(val == 3); assert(p_yield.result() == 4); freePromise(p_yield); diff --git a/src/urt/atomic.d b/src/urt/atomic.d new file mode 100644 index 0000000..0cf07ca --- /dev/null +++ b/src/urt/atomic.d @@ -0,0 +1,869 @@ +module urt.atomic; + +enum MemoryOrder +{ + relaxed = 0, + consume = 1, + acquire = 2, + release = 3, + acq_rel = 4, + seq_cst = 5, + seq = 5, +} + +// DMD lowers to these names... +alias atomicLoad = atomic_load; +alias atomicStore = atomic_store; +alias atomicOp = atomic_op; +alias atomicExchange = atomic_exchange; +alias atomicFetchAdd = atomic_fetch_add; +alias atomicFetchSub = atomic_fetch_sub; + + +version (LDC) +{ + // ----------------------------------------------------------------------- + // LDC: LLVM intrinsics - architecture-generic + // ----------------------------------------------------------------------- + + nothrow @nogc @safe: + pragma(inline, true): + + T atomic_load(MemoryOrder ms = MemoryOrder.seq, T)(ref const T val) pure @trusted + if (!is(T == shared)) + { + alias A = _AtomicType!T; + A result = llvm_atomic_load!A(cast(shared A*)&val, _ordering!ms); + return *cast(inout(T)*)&result; + } + + TailShared!T atomic_load(MemoryOrder ms = MemoryOrder.seq, T)(auto ref shared const T val) pure @trusted + { + alias A = _AtomicType!T; + A result = llvm_atomic_load!A(cast(shared A*)&val, _ordering!ms); + return *cast(TailShared!T*)&result; + } + + void atomic_store(MemoryOrder ms = MemoryOrder.seq, T, V)(ref shared T val, V newval) pure @trusted + if (__traits(compiles, { *cast(T*)&val = newval; })) + { + alias A = _AtomicType!T; + T tmp = newval; + llvm_atomic_store!A(*cast(A*)&tmp, cast(shared A*)&val, _ordering!ms); + } + + TailShared!T atomic_op(string op, T, V1)(ref shared T val, V1 mod) pure @trusted + if (__traits(compiles, mixin("*cast(T*)&val" ~ op ~ "mod"))) + { + // use LLVM atomic RMW where possible + static if (__traits(isIntegral, T) && T.sizeof <= size_t.sizeof) + { + alias A = _AtomicType!T; + static if (op == "+=") + { + auto old = llvm_atomic_rmw_add!A(cast(shared A*)&val, cast(A)mod, _ordering!(MemoryOrder.seq)); + auto result = cast(T)(old + cast(A)mod); + return *cast(TailShared!T*)&result; + } + else static if (op == "-=") + { + auto old = llvm_atomic_rmw_sub!A(cast(shared A*)&val, cast(A)mod, _ordering!(MemoryOrder.seq)); + auto result = cast(T)(old - cast(A)mod); + return *cast(TailShared!T*)&result; + } + else + { + // CAS loop for other ops + return _cas_op_loop!(op, T, V1)(val, mod); + } + } + else + return _cas_op_loop!(op, T, V1)(val, mod); + } + + bool cas(T, V1, V2)(shared(T)* here, V1 ifThis, V2 writeThis) pure @trusted + { + alias A = _AtomicType!T; + T cmp = cast(T)ifThis; + T desired = cast(T)writeThis; + auto result = llvm_atomic_cmp_xchg!A(cast(shared A*)here, *cast(A*)&cmp, *cast(A*)&desired, + _ordering!(MemoryOrder.seq), _ordering!(MemoryOrder.seq), false); + return result.exchanged; + } + + T atomic_exchange(MemoryOrder ms = MemoryOrder.seq, T, V)(shared(T)* here, V exchangeWith) pure @trusted + { + alias A = _AtomicType!T; + T tmp = cast(T)exchangeWith; + A result = llvm_atomic_rmw_xchg!A(cast(shared A*)here, *cast(A*)&tmp, _ordering!ms); + return *cast(T*)&result; + } + + T atomic_fetch_add(MemoryOrder ms = MemoryOrder.seq, T)(ref shared T val, T mod) pure @trusted + if (__traits(isIntegral, T)) + { + alias A = _AtomicType!T; + return cast(T)llvm_atomic_rmw_add!A(cast(shared A*)&val, cast(A)mod, _ordering!ms); + } + + T atomic_fetch_sub(MemoryOrder ms = MemoryOrder.seq, T)(ref shared T val, T mod) pure @trusted + if (__traits(isIntegral, T)) + { + alias A = _AtomicType!T; + return cast(T)llvm_atomic_rmw_sub!A(cast(shared A*)&val, cast(A)mod, _ordering!ms); + } + + void atomic_fence(MemoryOrder ms = MemoryOrder.seq)() pure @trusted + { + llvm_memory_fence(_ordering!ms); + } + + void pause() pure @trusted + { + version (X86) + enum inst = "pause"; + else version (X86_64) + enum inst = "pause"; + else version (ARM) + { + static if (__traits(targetHasFeature, "v6k")) + enum inst = "yield"; + else + enum inst = null; + } + else version (AArch64) + enum inst = "yield"; + else + enum inst = null; + + static if (inst !is null) + asm pure nothrow @nogc @trusted { (inst); } + } + + // --- LDC private helpers --- + + private TailShared!T _cas_op_loop(string op, T, V1)(ref shared T val, V1 mod) pure @trusted + { + alias A = _AtomicType!T; + A current = llvm_atomic_load!A(cast(shared A*)&val, _ordering!(MemoryOrder.seq)); + while (true) + { + auto tmp = *cast(T*)¤t; + mixin("tmp " ~ op ~ " mod;"); + auto result = llvm_atomic_cmp_xchg!A(cast(shared A*)&val, current, *cast(A*)&tmp, + _ordering!(MemoryOrder.seq), _ordering!(MemoryOrder.seq), false); + if (result.exchanged) + return *cast(TailShared!T*)&tmp; + current = result.previousValue; + } + } + + private template _ordering(MemoryOrder ms) + { + static if (ms == MemoryOrder.acquire) + enum _ordering = AtomicOrdering.Acquire; + else static if (ms == MemoryOrder.release) + enum _ordering = AtomicOrdering.Release; + else static if (ms == MemoryOrder.acq_rel) + enum _ordering = AtomicOrdering.AcquireRelease; + else static if (ms == MemoryOrder.seq) + enum _ordering = AtomicOrdering.SequentiallyConsistent; + else // raw/relaxed/consume + enum _ordering = AtomicOrdering.Monotonic; + } + + private template _AtomicType(T) + { + static if (T.sizeof == ubyte.sizeof) + alias _AtomicType = ubyte; + else static if (T.sizeof == ushort.sizeof) + alias _AtomicType = ushort; + else static if (T.sizeof == uint.sizeof) + alias _AtomicType = uint; + else static if (T.sizeof == ulong.sizeof) + alias _AtomicType = ulong; + else + static assert(false, "Cannot atomically load/store type of size " ~ T.sizeof.stringof); + } + + // LLVM atomic intrinsic declarations + private: + + enum AtomicOrdering + { + Monotonic = 2, + Acquire = 4, + Release = 5, + AcquireRelease = 6, + SequentiallyConsistent = 7, + } + + enum SynchronizationScope + { + SingleThread = 0, + CrossThread = 1, + } + + struct CmpXchgResult(T) + { + T previousValue; + bool exchanged; + } + + pragma(LDC_atomic_load) + T llvm_atomic_load(T)(in shared T* ptr, AtomicOrdering ordering) pure @trusted; + + pragma(LDC_atomic_store) + void llvm_atomic_store(T)(T val, shared T* ptr, AtomicOrdering ordering) pure @trusted; + + pragma(LDC_atomic_rmw, "xchg") + T llvm_atomic_rmw_xchg(T)(shared T* ptr, T val, AtomicOrdering ordering) pure @trusted; + + pragma(LDC_atomic_rmw, "add") + T llvm_atomic_rmw_add(T)(in shared T* ptr, T val, AtomicOrdering ordering) pure @trusted; + + pragma(LDC_atomic_rmw, "sub") + T llvm_atomic_rmw_sub(T)(in shared T* ptr, T val, AtomicOrdering ordering) pure @trusted; + + pragma(LDC_atomic_cmp_xchg) + CmpXchgResult!T llvm_atomic_cmp_xchg(T)(shared T* ptr, T cmp, T val, + AtomicOrdering successOrdering, AtomicOrdering failureOrdering, bool weak) pure @trusted; + + pragma(LDC_fence) + void llvm_memory_fence(AtomicOrdering ordering) pure @trusted; +} +else version (D_InlineAsm_X86_64) +{ + // ----------------------------------------------------------------------- + // DMD x86_64: inline assembly + // ----------------------------------------------------------------------- + + nothrow @nogc @safe: + + T atomic_load(MemoryOrder ms = MemoryOrder.seq, T)(ref const T val) pure @trusted + if (!is(T == shared)) + { + static if (ms == MemoryOrder.seq) + { + // seq_cst load: use lock cmpxchg to get full barrier + size_t storage = void; + auto srcPtr = cast(size_t)&val; + + enum ValReg = SizedReg!(DX, T); + enum ResReg = SizedReg!(AX, T); + + mixin(simpleFormat!(q{ + asm pure nothrow @nogc @trusted + { + mov RCX, srcPtr; + mov %0, 0; + mov %1, 0; + lock; cmpxchg [RCX], %0; + lea RCX, storage; + mov [RCX], %1; + } + }, [ValReg, ResReg])); + + return *cast(T*)&storage; + } + else + return val; + } + + TailShared!T atomic_load(MemoryOrder ms = MemoryOrder.seq, T)(auto ref shared const T val) pure @trusted + { + return atomic_load!ms(*cast(const T*)&val); + } + + void atomic_store(MemoryOrder ms = MemoryOrder.seq, T, V)(ref shared T val, V newval) pure @trusted + if (__traits(compiles, { *cast(T*)&val = newval; })) + { + static if (ms == MemoryOrder.seq) + { + // seq_cst store: use xchg (has implicit lock) + auto destPtr = cast(size_t)cast(T*)&val; + T tmp = newval; + + enum ValReg = SizedReg!(AX, T); + + mixin(simpleFormat!(q{ + asm pure nothrow @nogc @trusted + { + mov %0, tmp; + mov RCX, destPtr; + lock; xchg [RCX], %0; + } + }, [ValReg])); + } + else + *cast(T*)&val = newval; + } + + TailShared!T atomic_op(string op, T, V1)(ref shared T val, V1 mod) pure @trusted + if (__traits(compiles, mixin("*cast(T*)&val" ~ op ~ "mod"))) + { + static if ((op == "+=" || op == "-=") && __traits(isIntegral, T) && T.sizeof <= size_t.sizeof) + { + auto ptr = cast(T*)&val; + static if (op == "+=") + { + T old = _asm_fetch_add!T(ptr, cast(T)mod); + return cast(TailShared!T)(old + cast(T)mod); + } + else + { + T old = _asm_fetch_add!T(ptr, cast(T)-cast(IntOrLong!T)mod); + return cast(TailShared!T)(old - cast(T)mod); + } + } + else + { + // CAS loop + auto ptr = cast(T*)&val; + while (true) + { + T current = *ptr; + T desired = current; + mixin("desired " ~ op ~ " mod;"); + if (_asm_cas!T(ptr, ¤t, desired)) + return *cast(TailShared!T*)&desired; + } + } + } + + bool cas(T, V1, V2)(shared(T)* here, V1 ifThis, V2 writeThis) pure @trusted + { + T cmp = cast(T)ifThis; + return _asm_cas!T(cast(T*)here, &cmp, cast(T)writeThis); + } + + T atomic_exchange(MemoryOrder ms = MemoryOrder.seq, T, V)(shared(T)* here, V exchangeWith) pure @trusted + { + auto ptr = cast(T*)here; + T tmp = cast(T)exchangeWith; + size_t storage = void; + auto destPtr = cast(size_t)ptr; + + enum DestReg = SizedReg!CX; + enum ValReg = SizedReg!(AX, T); + + mixin(simpleFormat!(q{ + asm pure nothrow @nogc @trusted + { + mov %1, tmp; + mov %0, destPtr; + lock; xchg [%0], %1; + lea %0, storage; + mov [%0], %1; + } + }, [DestReg, ValReg])); + + return *cast(T*)&storage; + } + + T atomic_fetch_add(MemoryOrder ms = MemoryOrder.seq, T)(ref shared T val, T mod) pure @trusted + if (__traits(isIntegral, T)) + { + return _asm_fetch_add!T(cast(T*)&val, mod); + } + + T atomic_fetch_sub(MemoryOrder ms = MemoryOrder.seq, T)(ref shared T val, T mod) pure @trusted + if (__traits(isIntegral, T)) + { + return _asm_fetch_add!T(cast(T*)&val, cast(T)-cast(IntOrLong!T)mod); + } + + void atomic_fence(MemoryOrder ms = MemoryOrder.seq)() pure @trusted + { + static if (ms != MemoryOrder.relaxed) + { + asm pure nothrow @nogc @trusted + { + mfence; + } + } + } + + void pause() pure @trusted + { + asm pure nothrow @nogc @trusted + { + pause; + } + } + + // --- DMD x86_64 private helpers --- + private: + + T _asm_fetch_add(T)(T* dest, T value) pure @trusted + { + size_t storage = void; + auto destPtr = cast(size_t)dest; + + enum DestReg = SizedReg!DX; + enum ValReg = SizedReg!(AX, T); + + mixin(simpleFormat!(q{ + asm pure nothrow @nogc @trusted + { + mov %1, value; + mov %0, destPtr; + lock; xadd [%0], %1; + lea %0, storage; + mov [%0], %1; + } + }, [DestReg, ValReg])); + + return *cast(T*)&storage; + } + + bool _asm_cas(T)(T* dest, T* compare, T value) pure @trusted + { + bool success; + auto destPtr = cast(size_t)dest; + auto cmpPtr = cast(size_t)compare; + + enum SrcReg = SizedReg!CX; + enum ValueReg = SizedReg!(DX, T); + enum CompareReg = SizedReg!(AX, T); + + mixin(simpleFormat!(q{ + asm pure nothrow @nogc @trusted + { + mov %1, value; + mov %0, cmpPtr; + mov %2, [%0]; + + mov %0, destPtr; + lock; cmpxchg [%0], %1; + + setz success; + mov %0, cmpPtr; + mov [%0], %2; + } + }, [SrcReg, ValueReg, CompareReg])); + + return success; + } +} +else version (D_InlineAsm_X86) +{ + // ----------------------------------------------------------------------- + // DMD x86 (32-bit): inline assembly + // ----------------------------------------------------------------------- + + nothrow @nogc @safe: + + T atomic_load(MemoryOrder ms = MemoryOrder.seq, T)(ref const T val) pure @trusted + if (!is(T == shared)) + { + static assert(T.sizeof <= 4, "64-bit atomicLoad not supported on 32-bit target"); + + static if (ms == MemoryOrder.seq) + { + size_t storage = void; + + enum ValReg = SizedReg!(DX, T); + enum ResReg = SizedReg!(AX, T); + + mixin(simpleFormat!(q{ + asm pure nothrow @nogc @trusted + { + mov ECX, val; + mov %0, 0; + mov %1, 0; + lock; cmpxchg [ECX], %0; + lea ECX, storage; + mov [ECX], %1; + } + }, [ValReg, ResReg])); + + return *cast(T*)&storage; + } + else + return val; + } + + TailShared!T atomic_load(MemoryOrder ms = MemoryOrder.seq, T)(auto ref shared const T val) pure @trusted + { + return atomic_load!ms(*cast(const T*)&val); + } + + void atomic_store(MemoryOrder ms = MemoryOrder.seq, T, V)(ref shared T val, V newval) pure @trusted + if (__traits(compiles, { *cast(T*)&val = newval; })) + { + static assert(T.sizeof <= 4, "64-bit atomicStore not supported on 32-bit target"); + + static if (ms == MemoryOrder.seq) + { + T tmp = newval; + enum ValReg = SizedReg!(AX, T); + + mixin(simpleFormat!(q{ + asm pure nothrow @nogc @trusted + { + mov %0, tmp; + mov ECX, val; + lock; xchg [ECX], %0; + } + }, [ValReg])); + } + else + *cast(T*)&val = newval; + } + + TailShared!T atomic_op(string op, T, V1)(ref shared T val, V1 mod) pure @trusted + if (__traits(compiles, mixin("*cast(T*)&val" ~ op ~ "mod"))) + { + static assert(T.sizeof <= 4, "64-bit atomicOp not supported on 32-bit target"); + + static if ((op == "+=" || op == "-=") && __traits(isIntegral, T) && T.sizeof <= 4) + { + auto ptr = cast(T*)&val; + static if (op == "+=") + { + T old = _asm_fetch_add!T(ptr, cast(T)mod); + return cast(TailShared!T)(old + cast(T)mod); + } + else + { + T old = _asm_fetch_add!T(ptr, cast(T)-cast(IntOrLong!T)mod); + return cast(TailShared!T)(old - cast(T)mod); + } + } + else + { + auto ptr = cast(T*)&val; + while (true) + { + T current = *ptr; + T desired = current; + mixin("desired " ~ op ~ " mod;"); + if (_asm_cas!T(ptr, ¤t, desired)) + return *cast(TailShared!T*)&desired; + } + } + } + + bool cas(T, V1, V2)(shared(T)* here, V1 ifThis, V2 writeThis) pure @trusted + { + static assert(T.sizeof <= 4, "64-bit cas not supported on 32-bit target"); + T cmp = cast(T)ifThis; + return _asm_cas!T(cast(T*)here, &cmp, cast(T)writeThis); + } + + T atomic_exchange(MemoryOrder ms = MemoryOrder.seq, T, V)(shared(T)* here, V exchangeWith) pure @trusted + { + static assert(T.sizeof <= 4, "64-bit atomicExchange not supported on 32-bit target"); + + auto ptr = cast(T*)here; + T tmp = cast(T)exchangeWith; + size_t storage = void; + + enum ValReg = SizedReg!(AX, T); + + mixin(simpleFormat!(q{ + asm pure nothrow @nogc @trusted + { + mov %0, tmp; + mov ECX, ptr; + lock; xchg [ECX], %0; + lea ECX, storage; + mov [ECX], %0; + } + }, [ValReg])); + + return *cast(T*)&storage; + } + + T atomic_fetch_add(MemoryOrder ms = MemoryOrder.seq, T)(ref shared T val, T mod) pure @trusted + if (__traits(isIntegral, T)) + { + static assert(T.sizeof <= 4, "64-bit atomicFetchAdd not supported on 32-bit target"); + return _asm_fetch_add!T(cast(T*)&val, mod); + } + + T atomic_fetch_sub(MemoryOrder ms = MemoryOrder.seq, T)(ref shared T val, T mod) pure @trusted + if (__traits(isIntegral, T)) + { + static assert(T.sizeof <= 4, "64-bit atomicFetchSub not supported on 32-bit target"); + return _asm_fetch_add!T(cast(T*)&val, cast(T)-cast(IntOrLong!T)mod); + } + + void atomic_fence(MemoryOrder ms = MemoryOrder.seq)() pure @trusted + { + static if (ms != MemoryOrder.relaxed) + { + // x86 without guaranteed SSE2 - mfence may not exist. + // lock; add is a full barrier on all x86. + asm pure nothrow @nogc @trusted + { + push EAX; + lock; add [ESP], 0; + pop EAX; + } + } + } + + void pause() pure @trusted + { + asm pure nothrow @nogc @trusted + { + pause; + } + } + + // --- DMD x86 private helpers --- + private: + + T _asm_fetch_add(T)(T* dest, T value) pure @trusted + { + size_t storage = void; + + enum DestReg = SizedReg!DX; + enum ValReg = SizedReg!(AX, T); + + mixin(simpleFormat!(q{ + asm pure nothrow @nogc @trusted + { + mov %1, value; + mov %0, dest; + lock; xadd [%0], %1; + lea %0, storage; + mov [%0], %1; + } + }, [DestReg, ValReg])); + + return *cast(T*)&storage; + } + + bool _asm_cas(T)(T* dest, T* compare, T value) pure @trusted + { + bool success; + + enum SrcReg = SizedReg!CX; + enum ValueReg = SizedReg!(DX, T); + enum CompareReg = SizedReg!(AX, T); + + mixin(simpleFormat!(q{ + asm pure nothrow @nogc @trusted + { + mov %1, value; + mov %0, compare; + mov %2, [%0]; + + mov %0, dest; + lock; cmpxchg [%0], %1; + + setz success; + mov %0, compare; + mov [%0], %2; + } + }, [SrcReg, ValueReg, CompareReg])); + + return success; + } +} +else +{ + // ----------------------------------------------------------------------- + // Fallback: plain load/store for single-core / cooperative-multitasking + // targets (e.g. Xtensa, bare-metal RISC-V) + // ----------------------------------------------------------------------- + + nothrow @nogc @safe: + + T atomic_load(MemoryOrder ms = MemoryOrder.seq, T)(ref const T val) pure @trusted + if (!is(T == shared)) + { + return val; + } + + TailShared!T atomic_load(MemoryOrder ms = MemoryOrder.seq, T)(auto ref shared const T val) pure @trusted + { + return *cast(TailShared!T*)&val; + } + + void atomic_store(MemoryOrder ms = MemoryOrder.seq, T, V)(ref shared T val, V newval) pure @trusted + if (__traits(compiles, { *cast(T*)&val = newval; })) + { + *cast(T*)&val = newval; + } + + TailShared!T atomic_op(string op, T, V1)(ref shared T val, V1 mod) pure @trusted + if (__traits(compiles, mixin("*cast(T*)&val" ~ op ~ "mod"))) + { + auto ptr = cast(T*)&val; + mixin("*ptr " ~ op ~ " mod;"); + return *cast(TailShared!T*)ptr; + } + + bool cas(T, V1, V2)(shared(T)* here, V1 ifThis, V2 writeThis) pure @trusted + { + auto ptr = cast(T*)here; + if (*ptr == ifThis) + { + *ptr = writeThis; + return true; + } + return false; + } + + T atomic_exchange(MemoryOrder ms = MemoryOrder.seq, T, V)(shared(T)* here, V exchangeWith) pure @trusted + { + auto ptr = cast(T*)here; + T old = *ptr; + *ptr = exchangeWith; + return old; + } + + T atomic_fetch_add(MemoryOrder ms = MemoryOrder.seq, T)(ref shared T val, T mod) pure @trusted + if (__traits(isIntegral, T)) + { + auto ptr = cast(T*)&val; + T old = *ptr; + *ptr += mod; + return old; + } + + T atomic_fetch_sub(MemoryOrder ms = MemoryOrder.seq, T)(ref shared T val, T mod) pure @trusted + if (__traits(isIntegral, T)) + { + auto ptr = cast(T*)&val; + T old = *ptr; + *ptr -= mod; + return old; + } + + void atomic_fence(MemoryOrder ms = MemoryOrder.seq)() pure @trusted {} + void pause() pure @trusted {} +} + + +// ----------------------------------------------------------------------- +// Shared helpers +// ----------------------------------------------------------------------- + +template TailShared(U) if (!is(U == shared)) +{ + alias TailShared = .TailShared!(shared U); +} + +template TailShared(S) if (is(S == shared)) +{ + static if (is(S U == shared U)) + { + static if (is(S : U)) + alias TailShared = U; + else + alias TailShared = S; + } + else + static assert(false); +} + +private: + +template IntOrLong(T) +{ + static if (T.sizeof > 4) + alias IntOrLong = long; + else + alias IntOrLong = int; +} + +// DMD inline-asm helpers (shared between x86 and x86_64) +version (D_InlineAsm_X86) + enum _have_dmd_asm = true; +else version (D_InlineAsm_X86_64) + enum _have_dmd_asm = true; +else + enum _have_dmd_asm = false; + +static if (_have_dmd_asm) +{ + enum : int + { + AX, BX, CX, DX, DI, SI, R8, R9 + } + + immutable string[4][8] registerNames = [ + ["AL", "AX", "EAX", "RAX"], + ["BL", "BX", "EBX", "RBX"], + ["CL", "CX", "ECX", "RCX"], + ["DL", "DX", "EDX", "RDX"], + ["DIL", "DI", "EDI", "RDI"], + ["SIL", "SI", "ESI", "RSI"], + ["R8B", "R8W", "R8D", "R8"], + ["R9B", "R9W", "R9D", "R9"], + ]; + + template RegIndex(T) + { + static if (T.sizeof == 1) + enum RegIndex = 0; + else static if (T.sizeof == 2) + enum RegIndex = 1; + else static if (T.sizeof == 4) + enum RegIndex = 2; + else static if (T.sizeof == 8) + enum RegIndex = 3; + else + static assert(false, "Invalid type"); + } + + enum SizedReg(int reg, T = size_t) = registerNames[reg][RegIndex!T]; + + // CTFE-only helper for building asm strings. Templated so it doesn't + // inherit the module-level @nogc (string concat is fine at compile time). + template simpleFormat(string format, string[] args) + { + enum simpleFormat = _simpleFormatImpl(format, args); + } + + string _simpleFormatImpl()(string format, const(string)[] args) pure @safe + { + string result; + outer: while (format.length) + { + foreach (i; 0 .. format.length) + { + if (format[i] == '%' || format[i] == '?') + { + bool isQ = format[i] == '?'; + result ~= format[0 .. i++]; + assert(i < format.length, "Invalid format string"); + if (format[i] == '%' || format[i] == '?') + { + assert(!isQ, "Invalid format string"); + result ~= format[i++]; + } + else + { + int index = 0; + assert(format[i] >= '0' && format[i] <= '9', "Invalid format string"); + while (i < format.length && format[i] >= '0' && format[i] <= '9') + index = index * 10 + (ubyte(format[i++]) - ubyte('0')); + if (!isQ) + result ~= args[index]; + else if (!args[index]) + { + size_t j = i; + for (; j < format.length;) + { + if (format[j++] == '\n') + break; + } + i = j; + } + } + format = format[i .. $]; + continue outer; + } + } + result ~= format; + break; + } + return result; + } +} diff --git a/src/urt/attribute.d b/src/urt/attribute.d index 081f11f..1731e53 100644 --- a/src/urt/attribute.d +++ b/src/urt/attribute.d @@ -4,9 +4,71 @@ version (GNU) public import gcc.attributes; version (LDC) public import ldc.attributes; - version (DigitalMars) { enum restrict; enum weak; } + +// The public imports above already provide the core compiler attributes: +// @section("name") explicit linker section placement +// @weak weak linkage +// @restrict pointer aliasing hint +// @optStrategy(...) optimization strategy override +// @llvmAttr(...) arbitrary LLVM function attribute (LDC) +// @assumeUsed prevent dead-stripping +// +// Aliases for commonly attributes: + +version (LDC) +{ + enum noinline = llvmAttr("noinline"); + enum always_inline = llvmAttr("alwaysinline"); + enum naked = llvmAttr("naked"); // no prologue/epilogue + enum cold = llvmAttr("cold"); // optimizer: rarely executed (layout hint) + enum hot = llvmAttr("hot"); // optimizer: frequently executed (layout hint) + enum used = assumeUsed; // prevent linker dead-stripping +} +else +{ + enum noinline; + enum always_inline; + enum naked; + enum cold; + enum hot; + enum used; +} + + +// --- Memory placement ----------------------------------- + +// @critical - code that must execute from internal SRAM. +// Use for ISRs, code that runs during flash erase/write, and paths +// that need deterministic latency (no cache-miss jitter). +// Default (no attribute) = XIP from flash via instruction cache. +version (Espressif) enum critical = section(".iram1"); +else version (Bouffalo) enum critical = section(".ramfunc"); +else version (STM32) enum critical = section(".ramfunc"); +else version (BK7231) enum critical = section(".ramfunc"); +else version (RP2350) enum critical = section(".ramfunc"); +else enum critical; + +// @persist - data that survives deep sleep / hibernate. +// Not initialized at startup - the whole point is retaining prior values. +// Only available on platforms with RTC or hibernate-capable memory. +version (Espressif) enum persist = section(".rtc_noinit"); +else version (BL808) enum persist = section(".hbn_ram"); +else enum persist; + +// @fast_data - data in the fastest available RAM (TCM/DTCM/SRAM). +// Use sparingly: these regions are small and shared with stack/GOT. +// Only meaningful on platforms with distinct fast/slow data regions. +version (STM32F7) enum fast_data = section(".dtcm_data"); +else version (Bouffalo) enum fast_data = section(".sram_data"); +else enum fast_data; + +// @bulk_data - large data in slow, abundant memory (PSRAM / ext RAM). +// Use for big buffers, caches, lookup tables where latency doesn't matter. +version (Espressif) enum bulk_data = section(".ext_ram.bss"); +else version (Bouffalo) enum bulk_data = section(".psram_data"); +else enum bulk_data; diff --git a/src/urt/conv.d b/src/urt/conv.d index 91f39ab..19f78f5 100644 --- a/src/urt/conv.d +++ b/src/urt/conv.d @@ -6,49 +6,67 @@ public import urt.string.format : toString; nothrow @nogc: - -// on error or not-a-number cases, bytesTaken will contain 0 -long parseInt(const(char)[] str, size_t* bytesTaken = null, int base = 10) pure +// Workaround for LLVM bug: riscv-isel hangs when stores into a stack buffer +// and memcmp on that buffer are visible in the same function with +// +unaligned-scalar-mem. Preventing inlining keeps them in separate functions. +// See: https://github.com/llvm/llvm-project/issues/XXXXX +pragma(inline, false) private bool streq(const(char)[] a, const(char)[] b) pure { - size_t i = 0; - bool neg = false; + if (a.length != b.length) + return false; + foreach (i; 0 .. a.length) + if (a[i] != b[i]) + return false; + return true; +} - if (str.length > 0) - { - char c = str.ptr[0]; - neg = c == '-'; - if (neg || c == '+') - i++; - } +// on error or not-a-number cases, bytes_taken will contain 0 - ulong value = str.ptr[i .. str.length].parseUint(bytesTaken, base); - if (bytesTaken && *bytesTaken != 0) - *bytesTaken += i; - return neg ? -cast(long)value : cast(long)value; +long parse_int(const(char)[] str, size_t* bytes_taken = null, uint base = 10) pure +{ + const(char)* s = str.ptr, e = s + str.length, p = s; + uint neg = parse_sign(p, e); + ulong value = p[0 .. e - p].parse_uint(bytes_taken, base); + if (bytes_taken && *bytes_taken != 0) + *bytes_taken += p - s; + return neg ? -long(value) : long(value); } -long parseIntWithDecimal(const(char)[] str, out ulong fixedPointDivisor, size_t* bytesTaken = null, int base = 10) pure +long parse_int_with_base(const(char)[] str, size_t* bytes_taken = null) pure { - size_t i = 0; - bool neg = false; + const(char)* s = str.ptr, e = s + str.length, p = s; + uint neg = parse_sign(p, e); + uint base = parse_base_prefix(p, e); + ulong i = p[0 .. e - p].parse_uint(bytes_taken, base); + if (bytes_taken && *bytes_taken != 0) + *bytes_taken += p - s; + return neg ? -long(i) : long(i); +} - if (str.length > 0) - { - char c = str.ptr[0]; - neg = c == '-'; - if (neg || c == '+') - i++; - } +long parse_int_with_exponent(const(char)[] str, out int exponent, size_t* bytes_taken = null, uint base = 10) pure +{ + const(char)* s = str.ptr, e = s + str.length, p = s; + uint neg = parse_sign(p, e); + ulong value = p[0 .. e - p].parse_uint_with_exponent(exponent, bytes_taken, base); + if (bytes_taken && *bytes_taken != 0) + *bytes_taken += p - s; + return neg ? -long(value) : long(value); +} - ulong value = str[i .. str.length].parseUintWithDecimal(fixedPointDivisor, bytesTaken, base); - if (bytesTaken && *bytesTaken != 0) - *bytesTaken += i; - return neg ? -cast(long)value : cast(long)value; +long parse_int_with_exponent_and_base(const(char)[] str, out int exponent, out uint base, size_t* bytes_taken = null) pure +{ + const(char)* s = str.ptr, e = s + str.length, p = s; + uint neg = parse_sign(p, e); + base = parse_base_prefix(p, e); + ulong value = p[0 .. e - p].parse_uint_with_exponent(exponent, bytes_taken, base); + if (bytes_taken && *bytes_taken != 0) + *bytes_taken += p - s; + return neg ? -long(value) : long(value); } -ulong parseUint(const(char)[] str, size_t* bytesTaken = null, int base = 10) pure +ulong parse_uint(const(char)[] str, size_t* bytes_taken = null, uint base = 10) pure { - assert(base > 1 && base <= 36, "Invalid base"); + debug assert(base > 1 && base <= 36, "Invalid base"); ulong value = 0; @@ -60,7 +78,7 @@ ulong parseUint(const(char)[] str, size_t* bytesTaken = null, int base = 10) pur for (; s < e; ++s) { uint digit = *s - '0'; - if (digit > 9) + if (digit >= base) break; value = value*base + digit; } @@ -69,99 +87,192 @@ ulong parseUint(const(char)[] str, size_t* bytesTaken = null, int base = 10) pur { for (; s < e; ++s) { - uint digit = getDigit(*s); + uint digit = get_digit(*s); if (digit >= base) break; value = value*base + digit; } } - if (bytesTaken) - *bytesTaken = s - str.ptr; + if (bytes_taken) + *bytes_taken = s - str.ptr; return value; } -ulong parseUintWithDecimal(const(char)[] str, out ulong fixedPointDivisor, size_t* bytesTaken = null, int base = 10) pure +ulong parse_uint_with_base(const(char)[] str, size_t* bytes_taken = null) pure { - assert(base > 1 && base <= 36, "Invalid base"); + const(char)* s = str.ptr, e = s + str.length, p = s; + uint base = parse_base_prefix(p, e); + ulong i = p[0 .. e - p].parse_uint(bytes_taken, base); + if (bytes_taken && *bytes_taken != 0) + *bytes_taken += p - s; + return i; +} - ulong value = 0; - ulong divisor = 1; +ulong parse_uint_with_exponent(const(char)[] str, out int exponent, size_t* bytes_taken = null, uint base = 10) pure +{ + debug assert(base > 1 && base <= 36, "Invalid base"); const(char)* s = str.ptr; const(char)* e = s + str.length; - // TODO: we could optimise the common base <= 10 case... + ulong value = 0; + int exp = 0; + uint digits = 0; + uint zero_seq = 0; + char c = void; for (; s < e; ++s) { - char c = *s; + c = *s; if (c == '.') { + if (s == str.ptr) + goto done; ++s; + exp = zero_seq; goto parse_decimal; } + else if (c == '0') + { + ++zero_seq; + continue; + } - uint digit = getDigit(c); + uint digit = get_digit(c); if (digit >= base) break; - value = value*base + digit; + + if (digits) + { + for (uint i = 0; i <= zero_seq; ++i) + value = value * base; + digits += zero_seq; + } + value += digit; + digits += 1; + zero_seq = 0; } - goto done; + + // number has no decimal point, tail zeroes are positive exp + if (!digits) + goto nothing; + + exp = zero_seq; + goto check_exp; parse_decimal: for (; s < e; ++s) { - uint digit = getDigit(*s); - if (digit >= base) + c = *s; + + if (c == '0') { - // if i == 1, then the first char was a '.' and the next was not numeric, so this is not a number! - if (s == str.ptr + 1) - s = str.ptr; + ++zero_seq; + continue; + } + + uint digit = get_digit(c); + if (digit >= base) break; + + if (digits) + { + for (uint i = 0; i <= zero_seq; ++i) + value = value * base; + digits += zero_seq; } - value = value*base + digit; - divisor *= base; + value += digit; + digits += 1; + exp -= 1 + zero_seq; + zero_seq = 0; + } + if (!digits) + goto nothing; + +check_exp: + // check for exponent part + if (s + 1 < e && ((*s | 0x20) == 'e')) + { + c = s[1]; + bool exp_neg = c == '-'; + if (exp_neg || c == '+') + { + if (s + 2 >= e || !s[2].is_numeric) + goto done; + s += 2; + } + else + { + if (!c.is_numeric) + goto done; + ++s; + } + + int exp_value = 0; + for (; s < e; ++s) + { + uint digit = *s - '0'; + if (digit > 9) + break; + exp_value = exp_value * 10 + digit; + } + exp += exp_neg ? -exp_value : exp_value; } done: - fixedPointDivisor = divisor; - if (bytesTaken) - *bytesTaken = s - str.ptr; + exponent = exp; + if (bytes_taken) + *bytes_taken = s - str.ptr; return value; + +nothing: + exp = 0; + goto done; } -ulong parseUintWithBase(const(char)[] str, size_t* bytesTaken = null) pure +ulong parse_uint_with_exponent_and_base(const(char)[] str, out int exponent, out uint base, size_t* bytes_taken = null) pure { - const(char)* p = str.ptr; - int base = parseBasePrefix(str); - ulong i = parseUint(str, bytesTaken, base); - if (bytesTaken && *bytesTaken != 0) - *bytesTaken += str.ptr - p; - return i; + const(char)* s = str.ptr, e = s + str.length, p = s; + base = parse_base_prefix(p, e); + ulong value = p[0 .. e - p].parse_uint_with_exponent(exponent, bytes_taken, base); + if (value && *bytes_taken != 0) + *bytes_taken += p - s; + return value; } - unittest { size_t taken; - ulong divisor; - assert(parseUint("123") == 123); - assert(parseInt("+123.456") == 123); - assert(parseInt("-123.456", null, 10) == -123); - assert(parseUintWithDecimal("123.456", divisor, null, 10) == 123456 && divisor == 1000); - assert(parseIntWithDecimal("123.456.789", divisor, &taken, 16) == 1193046 && taken == 7 && divisor == 4096); - assert(parseInt("11001", null, 2) == 25); - assert(parseIntWithDecimal("-AbCdE.f", divisor, null, 16) == -11259375 && divisor == 16); - assert(parseInt("123abc", &taken, 10) == 123 && taken == 3); - assert(parseInt("!!!", &taken, 10) == 0 && taken == 0); - assert(parseInt("-!!!", &taken, 10) == 0 && taken == 0); - assert(parseInt("Wow", &taken, 36) == 42368 && taken == 3); - assert(parseUintWithBase("0x100", &taken) == 0x100 && taken == 5); + assert(parse_uint("123") == 123); + assert(parse_int("+123.456") == 123); + assert(parse_int("-123.456", null, 10) == -123); + assert(parse_int("11001", null, 2) == 25); + assert(parse_int("123abc", &taken, 10) == 123 && taken == 3); + assert(parse_int("!!!", &taken, 10) == 0 && taken == 0); + assert(parse_int("-!!!", &taken, 10) == 0 && taken == 0); + assert(parse_int("Wow", &taken, 36) == 42368 && taken == 3); + assert(parse_uint_with_base("0x100", &taken) == 0x100 && taken == 5); + assert(parse_int_with_base("-0x100", &taken) == -0x100 && taken == 6); + + int e; + assert("0001023000".parse_uint_with_exponent(e, &taken, 10) == 1023 && e == 3 && taken == 10); + assert("0.0012003000".parse_uint_with_exponent(e, &taken, 10) == 12003 && e == -7 && taken == 12); + assert("00010.23000".parse_uint_with_exponent(e, &taken, 10) == 1023 && e == -2 && taken == 11); + assert("00012300.0".parse_uint_with_exponent(e, &taken, 10) == 123 && e == 2 && taken == 10); + assert("00100.00230".parse_uint_with_exponent(e, &taken, 10) == 1000023 && e == -4 && taken == 11); + assert("0.0".parse_uint_with_exponent(e, &taken, 10) == 0 && e == 0 && taken == 3); + assert(".01".parse_uint_with_exponent(e, &taken, 10) == 0 && e == 0 && taken == 0); + assert("10e2".parse_uint_with_exponent(e, &taken, 10) == 1 && e == 3 && taken == 4); + assert("0.01E+2".parse_uint_with_exponent(e, &taken, 10) == 1 && e == 0 && taken == 7); + assert("0.01E".parse_uint_with_exponent(e, &taken, 10) == 1 && e == -2 && taken == 4); + assert("0.01Ex".parse_uint_with_exponent(e, &taken, 10) == 1 && e == -2 && taken == 4); + assert("0.01E-".parse_uint_with_exponent(e, &taken, 10) == 1 && e == -2 && taken == 4); + assert("0.01E-x".parse_uint_with_exponent(e, &taken, 10) == 1 && e == -2 && taken == 4); } -int parseIntFast(ref const(char)[] text, out bool success) pure +int parse_int_fast(ref const(char)[] text, out bool success) pure { if (!text.length) return 0; @@ -210,30 +321,38 @@ unittest { bool success; const(char)[] text = "123"; - assert(parseIntFast(text, success) == 123 && success == true && text.empty); + assert(parse_int_fast(text, success) == 123 && success == true && text.empty); text = "-2147483648abc"; - assert(parseIntFast(text, success) == -2147483648 && success == true && text.length == 3); + assert(parse_int_fast(text, success) == -2147483648 && success == true && text.length == 3); text = "2147483648"; - assert(parseIntFast(text, success) == 0 && success == false); + assert(parse_int_fast(text, success) == 0 && success == false); text = "-2147483649"; - assert(parseIntFast(text, success) == 0 && success == false); + assert(parse_int_fast(text, success) == 0 && success == false); text = "2147483650"; - assert(parseIntFast(text, success) == 0 && success == false); + assert(parse_int_fast(text, success) == 0 && success == false); } -// on error or not-a-number, result will be nan and bytesTaken will contain 0 -double parseFloat(const(char)[] str, size_t* bytesTaken = null, int base = 10) pure +// on error or not-a-number, result will be nan and bytes_taken will contain 0 +double parse_float(const(char)[] str, size_t* bytes_taken = null, uint base = 10) pure { - // TODO: E-notation... - size_t taken = void; - ulong div = void; - long value = str.parseIntWithDecimal(div, &taken, base); - if (bytesTaken) - *bytesTaken = taken; + import urt.math : pow; + + int e; + size_t taken; + long mantissa = str.parse_int_with_exponent(e, &taken, base); + if (bytes_taken) + *bytes_taken = taken; if (taken == 0) return double.nan; - return cast(double)value / div; + + // TODO: the real work needs to happen here! + // we want all the bits of precision! + + if (__ctfe) + return mantissa * double(base)^^e; + else + return mantissa * pow(double(base), e); } unittest @@ -245,26 +364,115 @@ unittest } size_t taken; - assert(fcmp(parseFloat("123.456"), 123.456)); - assert(fcmp(parseFloat("+123.456"), 123.456)); - assert(fcmp(parseFloat("-123.456.789"), -123.456)); - assert(fcmp(parseFloat("1101.11", &taken, 2), 13.75) && taken == 7); - assert(parseFloat("xyz", &taken) is double.nan && taken == 0); + assert(fcmp(parse_float("123.456"), 123.456)); + assert(fcmp(parse_float("+123.456"), 123.456)); + assert(fcmp(parse_float("-123.456.789"), -123.456)); + assert(fcmp(parse_float("-123.456e10"), -1.23456e+12)); + assert(fcmp(parse_float("1101.11", &taken, 2), 13.75) && taken == 7); + assert(parse_float("xyz", &taken) is double.nan && taken == 0); +} + + +ptrdiff_t parse(T)(const char[] text, out T result) +{ + import urt.array : beginsWith; + import urt.traits; + + alias UT = Unqual!T; + + static if (is(UT == bool)) + { + if (text.beginsWith("true")) + { + result = true; + return 4; + } + result = false; + if (text.beginsWith("false")) + return 5; + return -1; + } + else static if (is_some_int!T) + { + size_t taken; + static if (is_signed_int!T) + long r = text.parse_int(&taken); + else + ulong r = text.parse_uint(&taken); + if (!taken) + return -1; + if (r >= T.min && r <= T.max) + { + result = cast(T)r; + return taken; + } + return -2; + } + else static if (is_some_float!T) + { + size_t taken; + double f = text.parse_float(&taken); + if (!taken) + return -1; + result = cast(T)f; + return taken; + } + else static if (is_enum!T) + { + static assert(false, "TODO: do we want to parse from enum keys?"); + // case-sensitive? + } + else static if (is(T == struct) && __traits(compiles, { result.fromString(text); })) + { + return result.fromString(text); + } + else + static assert(false, "Cannot parse " ~ T.stringof ~ " from string"); } +unittest +{ + { + bool r; + assert("true".parse(r) == 4 && r == true); + assert("false".parse(r) == 5 && r == false); + assert("wow".parse(r) == -1); + } + { + int r; + assert("-10".parse(r) == 3 && r == -10); + } + { + ubyte r; + assert("10".parse(r) == 2 && r == 10); + assert("-10".parse(r) == -1); + assert("257".parse(r) == -2); + } + { + float r; + assert("10".parse(r) == 2 && r == 10.0f); + assert("-2.5".parse(r) == 4 && r == -2.5f); + } + { + import urt.inet; + IPAddr r; + assert("10.0.0.1".parse(r) == 8 && r == IPAddr(10,0,0,1)); + } +} -ptrdiff_t formatInt(long value, char[] buffer, uint base = 10, uint width = 0, char fill = ' ', bool showSign = false) pure + +ptrdiff_t format_int(long value, char[] buffer, uint base = 10, uint width = 0, char fill = ' ', bool show_sign = false) pure { const bool neg = value < 0; - showSign |= neg; + show_sign |= neg; - if (buffer.ptr && buffer.length < showSign) + if (buffer.ptr && buffer.length < show_sign) return -1; ulong i = neg ? -value : value; - ptrdiff_t r = formatUint(i, buffer.ptr ? buffer.ptr[(width == 0 ? showSign : 0) .. buffer.length] : null, base, width, fill); - if (r < 0 || !showSign) + ptrdiff_t r = format_uint(i, buffer.ptr ? buffer.ptr[(width == 0 ? show_sign : 0) .. buffer.length] : null, base, width, fill); + if (r < 0 || !show_sign) return r; if (buffer.ptr) @@ -286,10 +494,10 @@ ptrdiff_t formatInt(long value, char[] buffer, uint base = 10, uint width = 0, c if (buffer.ptr[0] == fill) { // we don't need to shift it left... - size_t sgnOffset = 0; - while (buffer.ptr[sgnOffset + 1] == fill) - ++sgnOffset; - buffer.ptr[sgnOffset] = sgn; + size_t sgn_offset = 0; + while (buffer.ptr[sgn_offset + 1] == fill) + ++sgn_offset; + buffer.ptr[sgn_offset] = sgn; return r; } @@ -309,20 +517,20 @@ ptrdiff_t formatInt(long value, char[] buffer, uint base = 10, uint width = 0, c return r + 1; } -ptrdiff_t formatUint(ulong value, char[] buffer, uint base = 10, uint width = 0, char fill = ' ') pure +ptrdiff_t format_uint(ulong value, char[] buffer, uint base = 10, uint width = 0, char fill = ' ') pure { import urt.util : max; assert(base >= 2 && base <= 36, "Invalid base"); ulong i = value; - uint numLen = 0; + uint num_len = 0; char[64] t = void; if (i == 0) { if (buffer.length > 0) t.ptr[0] = '0'; - numLen = 1; + num_len = 1; } else { @@ -334,14 +542,14 @@ ptrdiff_t formatUint(ulong value, char[] buffer, uint base = 10, uint width = 0, if (buffer.ptr) { int d = cast(int)(i % base); - t.ptr[numLen] = cast(char)((d < 10 ? '0' : 'A' - 10) + d); + t.ptr[num_len] = cast(char)((d < 10 ? '0' : 'A' - 10) + d); } - ++numLen; + ++num_len; } } - uint len = max(numLen, width); - uint padding = width > numLen ? width - numLen : 0; + uint len = max(num_len, width); + uint padding = width > num_len ? width - num_len : 0; if (buffer.ptr) { @@ -351,7 +559,7 @@ ptrdiff_t formatUint(ulong value, char[] buffer, uint base = 10, uint width = 0, size_t offset = 0; while (padding--) buffer.ptr[offset++] = fill; - for (uint j = numLen; j > 0; ) + for (uint j = num_len; j > 0; ) buffer.ptr[offset++] = t[--j]; } return len; @@ -360,51 +568,98 @@ ptrdiff_t formatUint(ulong value, char[] buffer, uint base = 10, uint width = 0, unittest { char[64] buffer; - assert(formatInt(0, null) == 1); - assert(formatInt(14, null) == 2); - assert(formatInt(14, null, 16) == 1); - assert(formatInt(-14, null) == 3); - assert(formatInt(-14, null, 16) == 2); - assert(formatInt(-14, null, 16, 3, '0') == 3); - assert(formatInt(-123, null, 10, 6) == 6); - assert(formatInt(-123, null, 10, 3) == 4); - assert(formatInt(-123, null, 10, 2) == 4); - - size_t len = formatInt(0, buffer); - assert(buffer[0 .. len] == "0"); - len = formatInt(14, buffer); - assert(buffer[0 .. len] == "14"); - len = formatInt(14, buffer, 2); - assert(buffer[0 .. len] == "1110"); - len = formatInt(14, buffer, 8, 3); - assert(buffer[0 .. len] == " 16"); - len = formatInt(14, buffer, 16, 4, '0'); - assert(buffer[0 .. len] == "000E"); - len = formatInt(-14, buffer, 16, 3, '0'); - assert(buffer[0 .. len] == "-0E"); - len = formatInt(12345, buffer, 10, 3); - assert(buffer[0 .. len] == "12345"); - len = formatInt(-123, buffer, 10, 6); - assert(buffer[0 .. len] == " -123"); + assert(format_int(0, null) == 1); + assert(format_int(14, null) == 2); + assert(format_int(14, null, 16) == 1); + assert(format_int(-14, null) == 3); + assert(format_int(-14, null, 16) == 2); + assert(format_int(-14, null, 16, 3, '0') == 3); + assert(format_int(-123, null, 10, 6) == 6); + assert(format_int(-123, null, 10, 3) == 4); + assert(format_int(-123, null, 10, 2) == 4); + + size_t len = format_int(0, buffer); + assert(streq(buffer[0 .. len], "0")); + len = format_int(14, buffer); + assert(streq(buffer[0 .. len], "14")); + len = format_int(14, buffer, 2); + assert(streq(buffer[0 .. len], "1110")); + len = format_int(14, buffer, 8, 3); + assert(streq(buffer[0 .. len], " 16")); + len = format_int(14, buffer, 16, 4, '0'); + assert(streq(buffer[0 .. len], "000E")); + len = format_int(-14, buffer, 16, 3, '0'); + assert(streq(buffer[0 .. len], "-0E")); + len = format_int(12345, buffer, 10, 3); + assert(streq(buffer[0 .. len], "12345")); + len = format_int(-123, buffer, 10, 6); + assert(streq(buffer[0 .. len], " -123")); } -ptrdiff_t formatFloat(double value, char[] buffer, const(char)[] format = null) // pure +ptrdiff_t format_float(double value, char[] buffer, const(char)[] format = null) pure { // TODO: this function should be oblitereated and implemented natively... // CRT call can't CTFE, which is a shame - import core.stdc.stdio; import urt.string.format : concat; - char[16] fmt = void; char[64] result = void; - assert(format.length <= fmt.sizeof - 3, "Format string buffer overflow"); - concat(fmt, "%", format, "g\0"); - int len = snprintf(result.ptr, result.length, fmt.ptr, value); - if (len < 0) - return -2; + // parse format; precision is '.10' => 10 digits + int digits = 6; + size_t dot = format.findFirst('.'); + if (dot < format.length) + digits = cast(int)parse_uint(format[dot + 1 .. $]); + version (Windows) + { + import urt.internal.stdc.stdlib : _gcvt_s; + int err = _gcvt_s(result.ptr, result.length, value, digits); + if (err != 0) + return -2; + } + else + { + import urt.internal.stdc.stdlib : gcvt; + if (gcvt(value, digits, result.ptr) is null) + return -2; + } + size_t len = result.ptr.strlen(); + if (result[len - 1] == '.') + --len; // trim trailing '.' if no digits follow it + else + { + // normalise output - gcvt may emit something like "5.e-003" + // strip lone '.', strip leading zeroes, result: 5e-3 + foreach (i; 1 .. len) + { + if (result[i] != 'e' && result[i] != 'E') + continue; + + size_t e = i; + if (result[e - 1] == '.') + { + foreach (j; e .. len) + result[j - 1] = result[j]; + --len; + --e; + } + + size_t exp_d = e + 1; + if (exp_d < len && (result[exp_d] == '+' || result[exp_d] == '-')) + ++exp_d; + size_t zeros = 0; + while (exp_d + zeros + 1 < len && result[exp_d + zeros] == '0') + ++zeros; + if (zeros) + { + foreach (j; exp_d + zeros .. len) + result[j - zeros] = result[j]; + len -= zeros; + } + break; + } + } if (buffer.ptr) { if (len > buffer.length) @@ -414,6 +669,31 @@ ptrdiff_t formatFloat(double value, char[] buffer, const(char)[] format = null) return len; } +unittest +{ + import urt.io; + char[64] buf; + auto len = format_float(0.0, buf); + assert(buf[0..len] == "0"); + len = format_float(1.0, buf); + assert(buf[0..len] == "1"); + len = format_float(-1.0, buf); + assert(buf[0..len] == "-1"); + len = format_float(3.14159, buf); + assert(buf[0..len] == "3.14159"); + len = format_float(3.14159, buf, ".3"); + assert(buf[0..len] == "3.14"); + len = format_float(1.5, buf); + assert(buf[0..len] == "1.5"); + len = format_float(1e6, buf); + assert(buf[0..len] == "1e+6"); + len = format_float(1e6, buf, ".7"); + assert(buf[0..len] == "1000000"); + len = format_float(0.001, buf); + assert(buf[0..len] == "0.001" || buf[0..len] == "1e-3"); // i don't know why it emits e-3 :/ + len = format_float(-0.0, buf); + assert(buf[0..len] == "-0"); // do we want to print -0? +} template to(T) @@ -424,9 +704,9 @@ template to(T) { long to(const(char)[] str) { - int base = parseBasePrefix(str); + uint base = parse_base_prefix(str); size_t taken; - long r = parseInt(str, &taken, base); + long r = parse_int(str, &taken, base); assert(taken == str.length, "String is not numeric"); return r; } @@ -435,19 +715,19 @@ template to(T) { double to(const(char)[] str) { - int base = parseBasePrefix(str); + uint base = parse_base_prefix(str); size_t taken; - double r = parseFloat(str, &taken, base); + double r = parse_float(str, &taken, base); assert(taken == str.length, "String is not numeric"); return r; } } - else static if (isSomeInt!T) // call-through for other int types; reduce instantiation bloat + else static if (is_some_int!T) // call-through for other int types; reduce instantiation bloat { T to(const(char)[] str) => cast(T)to!long(str); } - else static if (isSomeFloat!T) // call-through for other float types; reduce instantiation bloat + else static if (is_some_float!T) // call-through for other float types; reduce instantiation bloat { T to(const(char)[] str) => cast(T)to!double(str); @@ -479,38 +759,46 @@ template to(T) private: -uint getDigit(char c) pure +// valid result is 0 .. 35; result is garbage outside that bound +uint get_digit(char c) pure { - uint zeroBase = c - '0'; - if (zeroBase < 10) - return zeroBase; - uint ABase = c - 'A'; - if (ABase < 26) - return ABase + 10; - uint aBase = c - 'a'; - if (aBase < 26) - return aBase + 10; - return -1; + uint zero_base = c - '0'; + if (zero_base < 10) + return zero_base; + uint a_base = (c | 0x20) - 'a'; + return 10 + (a_base & 0xFF); } -int parseBasePrefix(ref const(char)[] str) pure +uint parse_base_prefix(ref const(char)* str, const(char)* end) pure { - int base = 10; - if (str.length >= 2) + uint base = 10; + if (str + 2 <= end && str[0] == '0') { - if (str[0..2] == "0x") - base = 16, str = str[2..$]; - else if (str[0..2] == "0b") - base = 2, str = str[2..$]; - else if (str[0..2] == "0o") - base = 8, str = str[2..$]; + if (str[1] == 'x') + base = 16, str += 2; + else if (str[1] == 'b') + base = 2, str += 2; + else if (str[1] == 'o') + base = 8, str += 2; } return base; } +uint parse_sign(ref const(char)* str, const(char)* end) pure +{ + if (str == end) + return 0; + // NOTE: ascii is '+' = 43, '-' = 45 + uint neg = *str - '+'; + if (neg > 2 || neg == 1) + return 0; + ++str; + return neg; // neg is 0 (+) or 2 (-) +} + /+ -size_t formatStruct(T)(ref T value, char[] buffer) nothrow @nogc +size_t format_struct(T)(ref T value, char[] buffer) nothrow @nogc { import urt.string.format; @@ -518,7 +806,7 @@ size_t formatStruct(T)(ref T value, char[] buffer) nothrow @nogc alias args = value.tupleof; // alias args = AliasSeq!(value.tupleof); -// alias args = InterleaveSeparator!(", ", value.tupleof); +// alias args = INTERLEAVE_SEPARATOR!(", ", value.tupleof); // pragma(msg, args); return concat(buffer, args).length; } @@ -530,7 +818,7 @@ unittest Packet p; char[1024] buffer; - size_t len = formatStruct(p, buffer); + size_t len = format_struct(p, buffer); assert(buffer[0 .. len] == "Packet()"); } diff --git a/src/urt/crc.d b/src/urt/crc.d index 5010e3f..e45b6da 100644 --- a/src/urt/crc.d +++ b/src/urt/crc.d @@ -1,51 +1,54 @@ module urt.crc; -import urt.meta : intForWidth; -import urt.traits : isUnsignedInt; +import urt.meta : IntForWidth; +import urt.traits : is_unsigned_int; nothrow @nogc: enum Algorithm : ubyte { - CRC16_USB, - CRC16_MODBUS, - CRC16_KERMIT, - CRC16_XMODEM, - CRC16_CCITT_FALSE, - CRC16_ISO_HDLC, - CRC16_DNP, - CRC32_ISO_HDLC, - CRC32_CASTAGNOLI, - - CRC16_Default_ShortPacket = CRC16_KERMIT, // good default choice for small packets - CRC32_Default = CRC32_CASTAGNOLI, // has SSE4.2 hardware implementation - - // aliases - CRC16_BLUETOOTH = CRC16_KERMIT, - CRC16_CCITT_TRUE = CRC16_KERMIT, - CRC16_CCITT = CRC16_KERMIT, - CRC16_EZSP = CRC16_CCITT_FALSE, - CRC16_IBM_SDLC = CRC16_ISO_HDLC, - CRC32_NVME = CRC32_CASTAGNOLI, + crc8_smbus, + crc16_usb, + crc16_modbus, + crc16_kermit, + crc16_xmodem, + crc16_ccitt_false, + crc16_iso_hdlc, + crc16_dnp, + crc32_iso_hdlc, + crc32_castagnoli, + + crc8_itu_t = crc8_smbus, + crc8_autosar = crc8_smbus, + crc16_default_short_packet = crc16_kermit, // good default choice for small packets + crc32_default = crc32_castagnoli, // has SSE4.2 hardware implementation + + // aliases + crc16_bluetooth = crc16_kermit, + crc16_ccitt_true = crc16_kermit, + crc16_ccitt = crc16_kermit, + crc16_ezsp = crc16_ccitt_false, + crc16_ibm_sdlc = crc16_iso_hdlc, + crc32_nvme = crc32_castagnoli, } -struct CRCParams +struct crc_params { ubyte width; bool reflect; uint poly; uint initial; - uint finalXor; + uint final_xor; uint check; } -alias CRCTable(Algorithm algo) = CRCTable!(paramTable[algo].width, paramTable[algo].poly, paramTable[algo].reflect); -alias CRCType(Algorithm algo) = intForWidth!(paramTable[algo].width); +alias CRCType(Algorithm algo) = IntForWidth!(param_table[algo].width); +alias crc_table(Algorithm algo) = crc_table!(param_table[algo].width, param_table[algo].poly, param_table[algo].reflect); // compute a CRC with runtime parameters -T calculateCRC(T = uint)(const void[] data, ref const CRCParams params, ref const T[256] table) pure - if (isUnsignedInt!T) +T calculate_crc(T = uint)(const void[] data, ref const crc_params params, ref const T[256] table) pure + if (is_unsigned_int!T) { assert(params.width <= T.sizeof*8, "T is too small for the CRC width"); @@ -64,99 +67,203 @@ T calculateCRC(T = uint)(const void[] data, ref const CRCParams params, ref cons crc = cast(T)((crc << 8) ^ table[(crc >> 8) ^ b]); } - return crc ^ cast(T)params.finalXor; + return crc ^ cast(T)params.final_xor; } // compute a CRC with hard-coded parameters -T calculateCRC(Algorithm algo, T = CRCType!algo)(const void[] data, T initial = cast(T)paramTable[algo].initial^paramTable[algo].finalXor) pure - if (isUnsignedInt!T) +T calculate_crc(Algorithm algo, T = CRCType!algo)(const void[] data, T initial = cast(T)param_table[algo].initial^param_table[algo].final_xor) pure + if (!hardware_crc_support!(algo, T) && is_unsigned_int!T) { - enum CRCParams params = paramTable[algo]; + enum crc_params params = param_table[algo]; static assert(params.width <= T.sizeof*8, "T is too small for the CRC width"); - alias table = CRCTable!algo; + alias table = crc_table!algo; const ubyte[] bytes = cast(ubyte[])data; - static if (params.finalXor) - T crc = initial ^ params.finalXor; + static if (params.final_xor) + T crc = initial ^ params.final_xor; else T crc = initial; foreach (b; bytes) { - static if (params.reflect) + static if (params.width <= 8) + crc = table[crc ^ b]; + else static if (params.reflect) crc = (crc >> 8) ^ table[cast(ubyte)crc ^ b]; else crc = cast(T)((crc << 8) ^ table[(crc >> 8) ^ b]); } - static if (params.finalXor) - return T(crc ^ params.finalXor); + static if (params.final_xor) + return T(crc ^ params.final_xor); else return crc; } +T calculate_crc(Algorithm algo, T = CRCType!algo)(const void[] data, T initial = cast(T)param_table[algo].initial^param_table[algo].final_xor) pure + if (hardware_crc_support!(algo, T) && is_unsigned_int!T) +{ + version (Espressif) + { + enum crc_params params = param_table[algo]; + enum T fxor = cast(T)params.final_xor; + + const ubyte* ptr = cast(ubyte*)data.ptr; + uint len = cast(uint)data.length; + + static if (params.width == 32) + { + static if (params.reflect) + alias rom_crc = crc32_le; + else + alias rom_crc = crc32_be; + return cast(T)(~rom_crc(cast(uint)~(initial ^ fxor), ptr, len) ^ fxor); + } + else static if (params.width == 16) + { + static if (params.reflect) + alias rom_crc = crc16_le; + else + alias rom_crc = crc16_be; + return cast(T)(cast(ushort)(~rom_crc(cast(ushort)~(initial ^ fxor), ptr, len) ^ fxor)); + } + else static if (params.width == 8) + { + static if (params.reflect) + alias rom_crc = crc8_le; + else + alias rom_crc = crc8_be; + return cast(T)(cast(ubyte)(~rom_crc(cast(ubyte)~(initial ^ fxor), ptr, len) ^ fxor)); + } + } + else + static assert(false, "Hardware CRC support claimed, but not implemented for this platform"); +} + + // computes 2 CRC's for 2 points in the data stream... -T calculateCRC_2(Algorithm algo, T = intForWidth!(paramTable[algo].width*2))(const void[] data, uint earlyOffset) pure - if (isUnsignedInt!T) +T calculate_crc_2(Algorithm algo, T = IntForWidth!(param_table[algo].width*2))(const void[] data, uint early_offset) pure + if (!hardware_crc_support!(algo, T) && is_unsigned_int!T) { - enum CRCParams params = paramTable[algo]; + enum crc_params params = param_table[algo]; static assert(params.width * 2 <= T.sizeof*8, "T is too small for the CRC width"); - alias table = CRCTable!algo; + alias CT = CRCType!algo; + alias table = crc_table!algo; const ubyte[] bytes = cast(ubyte[])data; - T highCRC = 0; - T crc = cast(T)params.initial; + CT high_crc = 0; + CT crc = cast(CT)params.initial; size_t i = 0; for (; i < bytes.length; ++i) { - if (i == earlyOffset) + if (i == early_offset) { - highCRC = crc; + high_crc = crc; goto fast_loop; // skips a redundant loop entry check } - static if (params.reflect) + static if (params.width <= 8) + crc = table[crc ^ bytes[i]]; + else static if (params.reflect) crc = (crc >> 8) ^ table[cast(ubyte)crc ^ bytes[i]]; else - crc = cast(T)((crc << 8) ^ table[(crc >> 8) ^ bytes[i]]); + crc = cast(CT)((crc << 8) ^ table[(crc >> 8) ^ bytes[i]]); } goto done; // skip over the fast loop entry check (which will fail) for (; i < bytes.length; ++i) { fast_loop: - static if (params.reflect) + static if (params.width <= 8) + crc = table[crc ^ bytes[i]]; + else static if (params.reflect) crc = (crc >> 8) ^ table[cast(ubyte)crc ^ bytes[i]]; else - crc = cast(T)((crc << 8) ^ table[(crc >> 8) ^ bytes[i]]); + crc = cast(CT)((crc << 8) ^ table[(crc >> 8) ^ bytes[i]]); } done: - static if (params.finalXor) + static if (params.final_xor) { - crc ^= cast(T)params.finalXor; - highCRC ^= cast(T)params.finalXor; + crc ^= cast(CT)params.final_xor; + high_crc ^= cast(CT)params.final_xor; } static if (params.width <= 8) - return ushort(crc | highCRC << 8); + return cast(T)(cast(uint)crc | (cast(uint)high_crc << 8)); else static if (params.width <= 16) - return uint(crc | highCRC << 16); - else if (params.width <= 32) - return ulong(crc | highCRC << 32); + return cast(T)(cast(uint)crc | (cast(uint)high_crc << 16)); + else static if (params.width <= 32) + return cast(T)(cast(ulong)crc | (cast(ulong)high_crc << 32)); +} + +T calculate_crc_2(Algorithm algo, T = IntForWidth!(param_table[algo].width*2))(const void[] data, uint early_offset) pure + if (hardware_crc_support!(algo, T) && is_unsigned_int!T) +{ + version (Espressif) + { + enum crc_params params = param_table[algo]; + + const ubyte* buf = cast(ubyte*)data.ptr; + uint len = cast(uint)data.length; + + enum uint fxor = params.final_xor; + + static if (params.width == 32) + { + static if (params.reflect) + alias rom_crc = crc32_le; + else + alias rom_crc = crc32_be; + + uint raw_init = cast(uint)~(params.initial ^ fxor); + uint raw_early = rom_crc(raw_init, buf, early_offset); + uint early = ~raw_early ^ fxor; + uint full = ~rom_crc(raw_early, buf + early_offset, len - early_offset) ^ fxor; + return cast(T)(cast(ulong)full | (cast(ulong)early << 32)); + } + else static if (params.width == 16) + { + static if (params.reflect) + alias rom_crc = crc16_le; + else + alias rom_crc = crc16_be; + + ushort raw_init = cast(ushort)~(params.initial ^ fxor); + ushort raw_early = rom_crc(raw_init, buf, early_offset); + ushort early = cast(ushort)(~raw_early ^ fxor); + ushort full = cast(ushort)(~rom_crc(raw_early, buf + early_offset, len - early_offset) ^ fxor); + return cast(T)(cast(uint)full | (cast(uint)early << 16)); + } + else static if (params.width == 8) + { + static if (params.reflect) + alias rom_crc = crc8_le; + else + alias rom_crc = crc8_be; + + ubyte raw_init = cast(ubyte)~(params.initial ^ fxor); + ubyte raw_early = rom_crc(raw_init, buf, early_offset); + ubyte early = cast(ubyte)(~raw_early ^ fxor); + ubyte full = cast(ubyte)(~rom_crc(raw_early, buf + early_offset, len - early_offset) ^ fxor); + return cast(T)(cast(ushort)full | (cast(ushort)early << 8)); + } + } + else + static assert(false, "Hardware CRC support claimed, but not implemented for this platform"); } -T[256] generateCRCTable(T)(ref const CRCParams params) pure - if (isUnsignedInt!T) +T[256] generate_crc_table(T)(ref const crc_params params) pure + if (is_unsigned_int!T) { - enum typeWidth = T.sizeof * 8; - assert(params.width <= typeWidth && params.width > typeWidth/2, "CRC width must match the size of the type"); - T topBit = cast(T)(1 << (params.width - 1)); + enum type_width = T.sizeof * 8; + assert(params.width <= type_width && params.width > type_width/2, "CRC width must match the size of the type"); + T top_bit = cast(T)(1 << (params.width - 1)); T[256] table = void; @@ -169,7 +276,7 @@ T[256] generateCRCTable(T)(ref const CRCParams params) pure crc <<= (params.width - 8); // Shift to align with the polynomial width foreach (_; 0..8) { - if ((crc & topBit) != 0) + if ((crc & top_bit) != 0) crc = cast(T)((crc << 1) ^ params.poly); else crc <<= 1; @@ -189,42 +296,126 @@ unittest { immutable ubyte[9] checkData = ['1','2','3','4','5','6','7','8','9']; - assert(calculateCRC!(Algorithm.CRC16_MODBUS)(checkData[]) == paramTable[Algorithm.CRC16_MODBUS].check); - assert(calculateCRC!(Algorithm.CRC16_EZSP)(checkData[]) == paramTable[Algorithm.CRC16_EZSP].check); - assert(calculateCRC!(Algorithm.CRC16_KERMIT)(checkData[]) == paramTable[Algorithm.CRC16_KERMIT].check); - assert(calculateCRC!(Algorithm.CRC16_USB)(checkData[]) == paramTable[Algorithm.CRC16_USB].check); - assert(calculateCRC!(Algorithm.CRC16_XMODEM)(checkData[]) == paramTable[Algorithm.CRC16_XMODEM].check); - assert(calculateCRC!(Algorithm.CRC16_ISO_HDLC)(checkData[]) == paramTable[Algorithm.CRC16_ISO_HDLC].check); - assert(calculateCRC!(Algorithm.CRC16_DNP)(checkData[]) == paramTable[Algorithm.CRC16_DNP].check); - assert(calculateCRC!(Algorithm.CRC32_ISO_HDLC)(checkData[]) == paramTable[Algorithm.CRC32_ISO_HDLC].check); - assert(calculateCRC!(Algorithm.CRC32_CASTAGNOLI)(checkData[]) == paramTable[Algorithm.CRC32_CASTAGNOLI].check); - - // check that rolling CRC works... - ushort crc = calculateCRC!(Algorithm.CRC16_MODBUS)(checkData[0 .. 5]); - assert(calculateCRC!(Algorithm.CRC16_MODBUS)(checkData[5 .. 9], crc) == paramTable[Algorithm.CRC16_MODBUS].check); - crc = calculateCRC!(Algorithm.CRC16_ISO_HDLC)(checkData[0 .. 5]); - assert(calculateCRC!(Algorithm.CRC16_ISO_HDLC)(checkData[5 .. 9], crc) == paramTable[Algorithm.CRC16_ISO_HDLC].check); - uint crc32 = calculateCRC!(Algorithm.CRC32_ISO_HDLC)(checkData[0 .. 5]); - assert(calculateCRC!(Algorithm.CRC32_ISO_HDLC)(checkData[5 .. 9], crc32) == paramTable[Algorithm.CRC32_ISO_HDLC].check); + // verify all algorithms against their check values ("123456789") + assert(calculate_crc!(Algorithm.crc8_smbus)(checkData[]) == param_table[Algorithm.crc8_smbus].check); + assert(calculate_crc!(Algorithm.crc16_modbus)(checkData[]) == param_table[Algorithm.crc16_modbus].check); + assert(calculate_crc!(Algorithm.crc16_ezsp)(checkData[]) == param_table[Algorithm.crc16_ezsp].check); + assert(calculate_crc!(Algorithm.crc16_kermit)(checkData[]) == param_table[Algorithm.crc16_kermit].check); + assert(calculate_crc!(Algorithm.crc16_usb)(checkData[]) == param_table[Algorithm.crc16_usb].check); + assert(calculate_crc!(Algorithm.crc16_xmodem)(checkData[]) == param_table[Algorithm.crc16_xmodem].check); + assert(calculate_crc!(Algorithm.crc16_iso_hdlc)(checkData[]) == param_table[Algorithm.crc16_iso_hdlc].check); + assert(calculate_crc!(Algorithm.crc16_dnp)(checkData[]) == param_table[Algorithm.crc16_dnp].check); + assert(calculate_crc!(Algorithm.crc32_iso_hdlc)(checkData[]) == param_table[Algorithm.crc32_iso_hdlc].check); + assert(calculate_crc!(Algorithm.crc32_castagnoli)(checkData[]) == param_table[Algorithm.crc32_castagnoli].check); + + // rolling CRC: split at multiple points and verify accumulation + static foreach (split; 1 .. 9) + { + assert(calculate_crc!(Algorithm.crc8_smbus)(checkData[split .. 9], + calculate_crc!(Algorithm.crc8_smbus)(checkData[0 .. split])) == param_table[Algorithm.crc8_smbus].check); + assert(calculate_crc!(Algorithm.crc16_modbus)(checkData[split .. 9], + calculate_crc!(Algorithm.crc16_modbus)(checkData[0 .. split])) == param_table[Algorithm.crc16_modbus].check); + assert(calculate_crc!(Algorithm.crc16_kermit)(checkData[split .. 9], + calculate_crc!(Algorithm.crc16_kermit)(checkData[0 .. split])) == param_table[Algorithm.crc16_kermit].check); + assert(calculate_crc!(Algorithm.crc16_iso_hdlc)(checkData[split .. 9], + calculate_crc!(Algorithm.crc16_iso_hdlc)(checkData[0 .. split])) == param_table[Algorithm.crc16_iso_hdlc].check); + assert(calculate_crc!(Algorithm.crc16_xmodem)(checkData[split .. 9], + calculate_crc!(Algorithm.crc16_xmodem)(checkData[0 .. split])) == param_table[Algorithm.crc16_xmodem].check); + assert(calculate_crc!(Algorithm.crc16_ccitt_false)(checkData[split .. 9], + calculate_crc!(Algorithm.crc16_ccitt_false)(checkData[0 .. split])) == param_table[Algorithm.crc16_ccitt_false].check); + assert(calculate_crc!(Algorithm.crc32_iso_hdlc)(checkData[split .. 9], + calculate_crc!(Algorithm.crc32_iso_hdlc)(checkData[0 .. split])) == param_table[Algorithm.crc32_iso_hdlc].check); + } + + // empty data returns the default initial value + assert(calculate_crc!(Algorithm.crc8_smbus)(null) == 0x00); + assert(calculate_crc!(Algorithm.crc32_iso_hdlc)(null) == 0x0000_0000); + assert(calculate_crc!(Algorithm.crc16_kermit)(null) == 0x0000); + assert(calculate_crc!(Algorithm.crc16_iso_hdlc)(null) == 0x0000); + assert(calculate_crc!(Algorithm.crc16_xmodem)(null) == 0x0000); + assert(calculate_crc!(Algorithm.crc16_ccitt_false)(null) == 0xFFFF); + assert(calculate_crc!(Algorithm.crc16_modbus)(null) == 0xFFFF); + + // single byte + assert(calculate_crc!(Algorithm.crc32_iso_hdlc)("A") == 0xD3D9_9E8B); + + // dual CRC: verify both halves + // reflected, final_xor=0 + uint dual16_k = calculate_crc_2!(Algorithm.crc16_kermit)(checkData[], 5); + assert((dual16_k & 0xFFFF) == param_table[Algorithm.crc16_kermit].check); + assert((dual16_k >> 16) == calculate_crc!(Algorithm.crc16_kermit)(checkData[0 .. 5])); + + // reflected, final_xor=mask + uint dual16_h = calculate_crc_2!(Algorithm.crc16_iso_hdlc)(checkData[], 5); + assert((dual16_h & 0xFFFF) == param_table[Algorithm.crc16_iso_hdlc].check); + assert((dual16_h >> 16) == calculate_crc!(Algorithm.crc16_iso_hdlc)(checkData[0 .. 5])); + + ulong dual32 = calculate_crc_2!(Algorithm.crc32_iso_hdlc)(checkData[], 5); + assert((dual32 & 0xFFFF_FFFF) == param_table[Algorithm.crc32_iso_hdlc].check); + assert((dual32 >> 32) == calculate_crc!(Algorithm.crc32_iso_hdlc)(checkData[0 .. 5])); + + // unreflected, final_xor=0 + uint dual16_x = calculate_crc_2!(Algorithm.crc16_xmodem)(checkData[], 5); + assert((dual16_x & 0xFFFF) == param_table[Algorithm.crc16_xmodem].check); + assert((dual16_x >> 16) == calculate_crc!(Algorithm.crc16_xmodem)(checkData[0 .. 5])); + + // 8-bit unreflected + ushort dual8 = calculate_crc_2!(Algorithm.crc8_smbus)(checkData[], 5); + assert((dual8 & 0xFF) == param_table[Algorithm.crc8_smbus].check); + assert((dual8 >> 8) == calculate_crc!(Algorithm.crc8_smbus)(checkData[0 .. 5])); } private: -enum CRCParams[] paramTable = [ - CRCParams(16, true, 0x8005, 0xFFFF, 0xFFFF, 0xB4C8), // CRC16_USB - CRCParams(16, true, 0x8005, 0xFFFF, 0x0000, 0x4B37), // CRC16_MODBUS - CRCParams(16, true, 0x1021, 0x0000, 0x0000, 0x2189), // CRC16_KERMIT - CRCParams(16, false, 0x1021, 0x0000, 0x0000, 0x31C3), // CRC16_XMODEM - CRCParams(16, false, 0x1021, 0xFFFF, 0x0000, 0x29B1), // CRC16_CCITT_FALSE - CRCParams(16, true, 0x1021, 0xFFFF, 0xFFFF, 0x906E), // CRC16_ISO_HDLC - CRCParams(16, true, 0x3D65, 0x0000, 0xFFFF, 0xEA82), // CRC16_DNP - CRCParams(32, true, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, 0xCBF43926), // CRC32_ISO_HDLC - CRCParams(32, true, 0x1EDC6F41, 0xFFFFFFFF, 0xFFFFFFFF, 0xE3069283), // CRC32_CASTAGNOLI +version (Espressif) +{ + // ESP32 have CRC functions in the mask rom which we'll use where applicable + + version (ESP32_S2) enum has_rom_crc_be = false; + else enum has_rom_crc_be = true; + + private extern(C) pure nothrow @nogc + { + uint crc32_le(uint crc, const ubyte* buf, uint len); + ushort crc16_le(ushort crc, const ubyte* buf, uint len); + ubyte crc8_le(ubyte crc, const ubyte* buf, uint len); + static if (has_rom_crc_be) + { + uint crc32_be(uint crc, const ubyte* buf, uint len); + ushort crc16_be(ushort crc, const ubyte* buf, uint len); + ubyte crc8_be(ubyte crc, const ubyte* buf, uint len); + } + } + + private enum rom_crc_match(Algorithm algo) = ( + (param_table[algo].width == 32 && param_table[algo].poly == 0x04C1_1DB7) || + (param_table[algo].width == 16 && param_table[algo].poly == 0x1021) || + (param_table[algo].width == 8 && param_table[algo].poly == 0x07) + ); + + enum hardware_crc_support(Algorithm algo, T) = is(T == CRCType!algo) && rom_crc_match!algo && (param_table[algo].reflect || has_rom_crc_be); +} +else +{ + enum hardware_crc_support(Algorithm algo, T) = false; +} + +enum crc_params[] param_table = [ + crc_params( 8, false, 0x07, 0x0000, 0x0000, 0xF4), // crc8_smbus + crc_params(16, true, 0x8005, 0xFFFF, 0xFFFF, 0xB4C8), // crc16_usb + crc_params(16, true, 0x8005, 0xFFFF, 0x0000, 0x4B37), // crc16_modbus + crc_params(16, true, 0x1021, 0x0000, 0x0000, 0x2189), // crc16_kermit + crc_params(16, false, 0x1021, 0x0000, 0x0000, 0x31C3), // crc16_xmodem + crc_params(16, false, 0x1021, 0xFFFF, 0x0000, 0x29B1), // crc16_ccitt_false + crc_params(16, true, 0x1021, 0xFFFF, 0xFFFF, 0x906E), // crc16_iso_hdlc + crc_params(16, true, 0x3D65, 0x0000, 0xFFFF, 0xEA82), // crc16_dnp + crc_params(32, true, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, 0xCBF43926), // crc32_iso_hdlc + crc_params(32, true, 0x1EDC6F41, 0xFFFFFFFF, 0xFFFFFFFF, 0xE3069283), // crc32_castagnoli ]; // helper function to reflect bits (reverse bit order) -T reflect(T)(T value, ubyte bits) +T reflect(T)(T value, ubyte bits) pure { T result = 0; foreach (i; 0..bits) @@ -236,7 +427,7 @@ T reflect(T)(T value, ubyte bits) } // this minimises the number of table instantiations -template CRCTable(uint width, uint poly, bool reflect) +template crc_table(uint width, uint poly, bool reflect) { - __gshared immutable CRCTable = generateCRCTable!(intForWidth!width)(CRCParams(width, reflect, poly, 0, 0, 0)); + __gshared immutable crc_table = generate_crc_table!(IntForWidth!width)(crc_params(width, reflect, poly, 0, 0, 0)); } diff --git a/src/urt/crypto/aes.d b/src/urt/crypto/aes.d new file mode 100644 index 0000000..0998a71 --- /dev/null +++ b/src/urt/crypto/aes.d @@ -0,0 +1,317 @@ +module urt.crypto.aes; + +import urt.result; + +version (MbedTLS) +{ + extern (C) nothrow @nogc + { + int urt_gcm_encrypt(const(ubyte)* key, size_t key_len, + const(ubyte)* iv, size_t iv_len, + const(ubyte)* aad, size_t aad_len, + const(ubyte)* plaintext, size_t pt_len, + ubyte* ciphertext, + ubyte* tag, size_t tag_len); + + int urt_gcm_decrypt(const(ubyte)* key, size_t key_len, + const(ubyte)* iv, size_t iv_len, + const(ubyte)* aad, size_t aad_len, + const(ubyte)* ciphertext, size_t ct_len, + const(ubyte)* tag, size_t tag_len, + ubyte* plaintext); + } +} +else version (Windows) +{ + import core.sys.windows.bcrypt; + import core.sys.windows.ntdef : NTSTATUS; + pragma(lib, "Bcrypt"); + + // STATUS_AUTH_TAG_MISMATCH - returned by BCryptDecrypt when GCM tag verification fails. + private enum NTSTATUS STATUS_AUTH_TAG_MISMATCH = cast(NTSTATUS)0xC000A002; +} + +nothrow @nogc: + + +// AES-GCM authenticated encryption. Writes ciphertext (length == plaintext.length) +// and the authentication tag. +// +// key: 16, 24, or 32 bytes (AES-128/192/256). +// iv: any non-zero length; 12 bytes is the GCM-native size and the only one +// that doesn't trigger the GHASH-based IV reduction. +// aad: associated data - authenticated but not encrypted; may be empty. +// tag: 4..16 bytes (16 is standard). +Result aes_gcm_encrypt(const(ubyte)[] key, + const(ubyte)[] iv, + const(ubyte)[] aad, + const(ubyte)[] plaintext, + ubyte[] ciphertext, + ubyte[] tag) +{ + if (key.length != 16 && key.length != 24 && key.length != 32) + return InternalResult.invalid_parameter; + if (iv.length == 0 || ciphertext.length != plaintext.length || tag.length < 4 || tag.length > 16) + return InternalResult.invalid_parameter; + + version (MbedTLS) + { + int ret = urt_gcm_encrypt( + key.ptr, key.length, + iv.ptr, iv.length, + aad.length ? aad.ptr : null, aad.length, + plaintext.length ? plaintext.ptr : null, plaintext.length, + ciphertext.length ? ciphertext.ptr : null, + tag.ptr, tag.length); + return ret == 0 ? Result.success : Result(cast(uint)ret); + } + else version (Windows) + { + BCRYPT_ALG_HANDLE halg; + NTSTATUS status = BCryptOpenAlgorithmProvider(&halg, BCRYPT_AES_ALGORITHM.ptr, null, 0); + if (status != 0) + return Result(cast(uint)status); + scope(exit) BCryptCloseAlgorithmProvider(halg, 0); + + status = BCryptSetProperty(halg, BCRYPT_CHAINING_MODE.ptr, + cast(ubyte*)BCRYPT_CHAIN_MODE_GCM.ptr, + cast(uint)(BCRYPT_CHAIN_MODE_GCM.length * wchar.sizeof), 0); + if (status != 0) + return Result(cast(uint)status); + + BCRYPT_KEY_HANDLE hkey; + status = BCryptGenerateSymmetricKey(halg, &hkey, null, 0, + cast(ubyte*)key.ptr, cast(uint)key.length, 0); + if (status != 0) + return Result(cast(uint)status); + scope(exit) BCryptDestroyKey(hkey); + + BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO info; + info.cbSize = BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO.sizeof; + info.dwInfoVersion = BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO_VERSION; + info.pbNonce = cast(ubyte*)iv.ptr; + info.cbNonce = cast(uint)iv.length; + info.pbAuthData = aad.length ? cast(ubyte*)aad.ptr : null; + info.cbAuthData = cast(uint)aad.length; + info.pbTag = tag.ptr; + info.cbTag = cast(uint)tag.length; + + uint result_len; + status = BCryptEncrypt(hkey, + plaintext.length ? cast(ubyte*)plaintext.ptr : null, cast(uint)plaintext.length, + &info, + null, 0, + ciphertext.length ? ciphertext.ptr : null, cast(uint)ciphertext.length, + &result_len, 0); + return status == 0 ? Result.success : Result(cast(uint)status); + } + else + return InternalResult.unsupported; +} + + +// AES-GCM authenticated decryption with tag verification. +// On tag-verify failure returns a system-specific failure code; callers should +// treat any failure as authentication failure and discard `plaintext`. +Result aes_gcm_decrypt(const(ubyte)[] key, + const(ubyte)[] iv, + const(ubyte)[] aad, + const(ubyte)[] ciphertext, + const(ubyte)[] tag, + ubyte[] plaintext) +{ + if (key.length != 16 && key.length != 24 && key.length != 32) + return InternalResult.invalid_parameter; + if (iv.length == 0 || plaintext.length != ciphertext.length || tag.length < 4 || tag.length > 16) + return InternalResult.invalid_parameter; + + version (MbedTLS) + { + int ret = urt_gcm_decrypt( + key.ptr, key.length, + iv.ptr, iv.length, + aad.length ? aad.ptr : null, aad.length, + ciphertext.length ? ciphertext.ptr : null, ciphertext.length, + tag.ptr, tag.length, + plaintext.length ? plaintext.ptr : null); + return ret == 0 ? Result.success : Result(cast(uint)ret); + } + else version (Windows) + { + BCRYPT_ALG_HANDLE halg; + NTSTATUS status = BCryptOpenAlgorithmProvider(&halg, BCRYPT_AES_ALGORITHM.ptr, null, 0); + if (status != 0) + return Result(cast(uint)status); + scope(exit) BCryptCloseAlgorithmProvider(halg, 0); + + status = BCryptSetProperty(halg, BCRYPT_CHAINING_MODE.ptr, + cast(ubyte*)BCRYPT_CHAIN_MODE_GCM.ptr, + cast(uint)(BCRYPT_CHAIN_MODE_GCM.length * wchar.sizeof), 0); + if (status != 0) + return Result(cast(uint)status); + + BCRYPT_KEY_HANDLE hkey; + status = BCryptGenerateSymmetricKey(halg, &hkey, null, 0, + cast(ubyte*)key.ptr, cast(uint)key.length, 0); + if (status != 0) + return Result(cast(uint)status); + scope(exit) BCryptDestroyKey(hkey); + + BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO info; + info.cbSize = BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO.sizeof; + info.dwInfoVersion = BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO_VERSION; + info.pbNonce = cast(ubyte*)iv.ptr; + info.cbNonce = cast(uint)iv.length; + info.pbAuthData = aad.length ? cast(ubyte*)aad.ptr : null; + info.cbAuthData = cast(uint)aad.length; + info.pbTag = cast(ubyte*)tag.ptr; + info.cbTag = cast(uint)tag.length; + + uint result_len; + status = BCryptDecrypt(hkey, + ciphertext.length ? cast(ubyte*)ciphertext.ptr : null, cast(uint)ciphertext.length, + &info, + null, 0, + plaintext.length ? plaintext.ptr : null, cast(uint)plaintext.length, + &result_len, 0); + return status == 0 ? Result.success : Result(cast(uint)status); + } + else + return InternalResult.unsupported; +} + + +// Raw AES-ECB on a single 16-byte block (no padding, no IV). The building +// block for RFC 3394 key wrap; not a general-purpose cipher mode. key is +// 16/24/32 bytes. Returns unsupported when no AES backend is compiled in. +Result aes_ecb_encrypt(const(ubyte)[] key, ref const ubyte[16] input, ref ubyte[16] output) +{ + if (key.length != 16 && key.length != 24 && key.length != 32) + return InternalResult.invalid_parameter; + + version (MbedTLS) + { + import urt.internal.mbedtls : urt_aes_ecb_encrypt; + return urt_aes_ecb_encrypt(key.ptr, key.length, input.ptr, output.ptr) == 0 ? Result.success : InternalResult.failed; + } + else version (Windows) + return aes_ecb_block_win(key, input, output, false); + else + return InternalResult.unsupported; +} + +Result aes_ecb_decrypt(const(ubyte)[] key, ref const ubyte[16] input, ref ubyte[16] output) +{ + if (key.length != 16 && key.length != 24 && key.length != 32) + return InternalResult.invalid_parameter; + + version (MbedTLS) + { + import urt.internal.mbedtls : urt_aes_ecb_decrypt; + return urt_aes_ecb_decrypt(key.ptr, key.length, input.ptr, output.ptr) == 0 ? Result.success : InternalResult.failed; + } + else version (Windows) + return aes_ecb_block_win(key, input, output, true); + else + return InternalResult.unsupported; +} + +version (Windows) +private Result aes_ecb_block_win(const(ubyte)[] key, ref const ubyte[16] input, ref ubyte[16] output, bool decrypt) +{ + BCRYPT_ALG_HANDLE halg; + NTSTATUS status = BCryptOpenAlgorithmProvider(&halg, BCRYPT_AES_ALGORITHM.ptr, null, 0); + if (status != 0) + return Result(cast(uint)status); + scope(exit) BCryptCloseAlgorithmProvider(halg, 0); + + status = BCryptSetProperty(halg, BCRYPT_CHAINING_MODE.ptr, + cast(ubyte*)BCRYPT_CHAIN_MODE_ECB.ptr, + cast(uint)(BCRYPT_CHAIN_MODE_ECB.length * wchar.sizeof), 0); + if (status != 0) + return Result(cast(uint)status); + + BCRYPT_KEY_HANDLE hkey; + status = BCryptGenerateSymmetricKey(halg, &hkey, null, 0, cast(ubyte*)key.ptr, cast(uint)key.length, 0); + if (status != 0) + return Result(cast(uint)status); + scope(exit) BCryptDestroyKey(hkey); + + uint result_len; + if (decrypt) + status = BCryptDecrypt(hkey, cast(ubyte*)input.ptr, 16, null, null, 0, output.ptr, 16, &result_len, 0); + else + status = BCryptEncrypt(hkey, cast(ubyte*)input.ptr, 16, null, null, 0, output.ptr, 16, &result_len, 0); + return status == 0 ? Result.success : Result(cast(uint)status); +} + + +unittest +{ + // McGrew/Viega AES-GCM test vectors (FIPS 800-38D Annex B examples) + import urt.encoding : HexDecode; + + // Test 1: empty PT, empty AAD, AES-128 + { + auto key = HexDecode!"00000000000000000000000000000000"; + auto iv = HexDecode!"000000000000000000000000"; + auto expected_tag = HexDecode!"58e2fccefa7e3061367f1d57a4e7455a"; + + ubyte[16] tag; + auto r = aes_gcm_encrypt(key[], iv[], null, null, null, tag[]); + assert(r.succeeded); + assert(tag == expected_tag); + + // verify round-trip via decrypt with the produced tag + r = aes_gcm_decrypt(key[], iv[], null, null, tag[], null); + assert(r.succeeded); + } + + // Test 2: 16-byte zero PT, empty AAD, AES-128 + { + auto key = HexDecode!"00000000000000000000000000000000"; + auto iv = HexDecode!"000000000000000000000000"; + auto pt = HexDecode!"00000000000000000000000000000000"; + auto expected_ct = HexDecode!"0388dace60b6a392f328c2b971b2fe78"; + auto expected_tag = HexDecode!"ab6e47d42cec13bdf53a67b21257bddf"; + + ubyte[16] ct, tag; + auto r = aes_gcm_encrypt(key[], iv[], null, pt[], ct[], tag[]); + assert(r.succeeded); + assert(ct == expected_ct); + assert(tag == expected_tag); + + ubyte[16] pt_out; + r = aes_gcm_decrypt(key[], iv[], null, ct[], tag[], pt_out[]); + assert(r.succeeded); + assert(pt_out == pt); + } + + // Test 4: 60-byte PT (partial last block) + 20-byte AAD, AES-128 + { + auto key = HexDecode!"feffe9928665731c6d6a8f9467308308"; + auto iv = HexDecode!"cafebabefacedbaddecaf888"; + auto aad = HexDecode!"feedfacedeadbeeffeedfacedeadbeefabaddad2"; + auto pt = HexDecode!"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39"; + auto expected_ct = HexDecode!"42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091"; + auto expected_tag = HexDecode!"5bc94fbc3221a5db94fae95ae7121a47"; + + ubyte[60] ct; + ubyte[16] tag; + auto r = aes_gcm_encrypt(key[], iv[], aad[], pt[], ct[], tag[]); + assert(r.succeeded); + assert(ct == expected_ct); + assert(tag == expected_tag); + + ubyte[60] pt_out; + r = aes_gcm_decrypt(key[], iv[], aad[], ct[], tag[], pt_out[]); + assert(r.succeeded); + assert(pt_out == pt); + + // tag tamper should fail authentication + ubyte[16] bad_tag = tag; + bad_tag[0] ^= 1; + r = aes_gcm_decrypt(key[], iv[], aad[], ct[], bad_tag[], pt_out[]); + assert(r.failed); + } +} diff --git a/src/urt/crypto/aes_keywrap.d b/src/urt/crypto/aes_keywrap.d new file mode 100644 index 0000000..6c1c5c2 --- /dev/null +++ b/src/urt/crypto/aes_keywrap.d @@ -0,0 +1,131 @@ +// RFC 3394 AES Key Wrap (NIST AES-WRAP). Used by the WPA2 4-way handshake to +// protect the GTK in EAPOL-Key msg 3/4: the AP wraps the GTK with the KEK +// (bytes 16..31 of the PTK) and we unwrap it on receipt. +// +// The algorithm operates on 64-bit blocks. The wrapped output is 8 bytes +// longer than the plaintext (one extra block holds the integrity check +// value, default A6A6A6A6A6A6A6A6). +module urt.crypto.aes_keywrap; + +import urt.crypto.aes : aes_ecb_encrypt, aes_ecb_decrypt; +import urt.result : Result, InternalResult; + +nothrow @nogc: + + +private enum ubyte[8] DEFAULT_IV = [0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6]; + + +// RFC 3394 AES Key Wrap. On success, writes (plain.length + 8) bytes of +// wrapped key data to `cipher`. +Result aes_wrap(const(ubyte)[] kek, + const(ubyte)[] plain, + ubyte[] cipher) +{ + if (kek.length != 16 && kek.length != 24 && kek.length != 32) + return InternalResult.invalid_parameter; + if (plain.length < 16 || plain.length % 8 != 0) + return InternalResult.invalid_parameter; + if (cipher.length != plain.length + 8) + return InternalResult.invalid_parameter; + + size_t n = plain.length / 8; + ubyte[8] a = DEFAULT_IV; + cipher[8 .. $] = plain[]; + + ubyte[16] block = void; + for (size_t j = 0; j < 6; ++j) + { + for (size_t i = 1; i <= n; ++i) + { + block[0 .. 8] = a[]; + block[8 .. 16] = cipher[i * 8 .. (i + 1) * 8]; + + ubyte[16] enc = void; + Result r = aes_ecb_encrypt(kek, block, enc); + if (r.failed) + return r; + + a[] = enc[0 .. 8]; + size_t t = n * j + i; + a[7] ^= cast(ubyte)(t); + a[6] ^= cast(ubyte)(t >> 8); + a[5] ^= cast(ubyte)(t >> 16); + a[4] ^= cast(ubyte)(t >> 24); + cipher[i * 8 .. (i + 1) * 8] = enc[8 .. 16]; + } + } + + cipher[0 .. 8] = a[]; + return Result.success; +} + +Result aes_unwrap(const(ubyte)[] kek, + const(ubyte)[] cipher, + ubyte[] plain) +{ + if (kek.length != 16 && kek.length != 24 && kek.length != 32) + return InternalResult.invalid_parameter; + if (cipher.length < 24 || cipher.length % 8 != 0) + return InternalResult.invalid_parameter; + if (plain.length + 8 != cipher.length) + return InternalResult.invalid_parameter; + + size_t n = cipher.length / 8 - 1; // number of 64-bit plaintext blocks + + ubyte[8] a = void; + a[] = cipher[0 .. 8]; + plain[] = cipher[8 .. $]; + + ubyte[16] block = void; + for (int j = 5; j >= 0; --j) + { + for (size_t i = n; i >= 1; --i) + { + // A = MSB(64, AES-1(K, (A ^ t) | R[i])) where t = n*j + i + size_t t = n * cast(size_t)j + i; + // XOR t (big-endian, lowest 4 bytes are sufficient for our sizes) + a[7] ^= cast(ubyte)(t); + a[6] ^= cast(ubyte)(t >> 8); + a[5] ^= cast(ubyte)(t >> 16); + a[4] ^= cast(ubyte)(t >> 24); + + block[0 .. 8] = a[]; + block[8 .. 16] = plain[(i - 1) * 8 .. i * 8]; + + ubyte[16] dec = void; + Result r = aes_ecb_decrypt(kek, block, dec); + if (r.failed) + return r; + + a[] = dec[0 .. 8]; + plain[(i - 1) * 8 .. i * 8] = dec[8 .. 16]; + } + } + + // A must equal the IV for an authentic unwrap. Mismatch means the + // wrong KEK or a tampered ciphertext -- caller must discard plain. + foreach (i; 0 .. 8) + { + if (a[i] != DEFAULT_IV[i]) + return InternalResult.data_error; + } + + return Result.success; +} + + +unittest +{ + // RFC 3394 4.1: Wrap 128 bits of Key Data with a 128-bit KEK. + import urt.encoding : HexDecode; + + static immutable ubyte[16] kek = HexDecode!"000102030405060708090A0B0C0D0E0F"; + static immutable ubyte[16] plain = HexDecode!"00112233445566778899AABBCCDDEEFF"; + static immutable ubyte[24] cipher = HexDecode!"1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5"; + + ubyte[16] out_; + auto r = aes_unwrap(kek[], cipher[], out_[]); + assert(r.succeeded); + assert(out_ == plain); +} diff --git a/src/urt/crypto/chacha.d b/src/urt/crypto/chacha.d new file mode 100644 index 0000000..2f263db --- /dev/null +++ b/src/urt/crypto/chacha.d @@ -0,0 +1,299 @@ +module urt.crypto.chacha; + +import urt.endian : littleEndianToNative, nativeToLittleEndian; +import urt.mem; + +nothrow @nogc: + + +struct ChaChaContext +{ + uint[16] state; + union { + uint[16] keystream32; + ubyte[64] keystream8; + } + uint nonceLow; + ushort position; + ushort rounds; +} + + +void chacha_init_context(ref ChaChaContext ctx, ref const ubyte[16] key, ulong nonce, ulong counter = 0, uint rounds = 20) pure +{ + chacha_init_context(ctx, key, expandNonce(nonce), counter, rounds); +} + +void chacha_init_context(ref ChaChaContext ctx, ref const ubyte[32] key, ulong nonce, ulong counter = 0, uint rounds = 20) pure +{ + chacha_init_context(ctx, key, expandNonce(nonce), counter, rounds); +} + +void chacha_init_context(ref ChaChaContext ctx, ref const ubyte[16] key, ref const ubyte[12] nonce, ulong counter = 0, uint rounds = 20) pure +{ + ubyte[32] key256 = void; + key256[0 .. 16] = key[]; + key256[16 .. 32] = key[]; + chacha_init_context(ctx, key256, nonce, counter, rounds); +} + +void chacha_init_context(ref ChaChaContext ctx, ref const ubyte[32] key, ref const ubyte[12] nonce, ulong counter = 0, uint rounds = 20) pure +{ + // the number of rounds must be 8, 12 or 20 + assert (rounds == 8 || rounds == 12 || rounds == 20); + ctx.rounds = cast(ushort)rounds / 2; + + ctx.nonceLow = nonce[0..4].littleEndianToNative!uint; + + // the string "expand 32-byte k" in little-endian + enum uint[4] magic_constant = [ 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 ]; + + ctx.state[0] = magic_constant[0]; + ctx.state[1] = magic_constant[1]; + ctx.state[2] = magic_constant[2]; + ctx.state[3] = magic_constant[3]; + ctx.state[4] = key[0..4].littleEndianToNative!uint; + ctx.state[5] = key[4..8].littleEndianToNative!uint; + ctx.state[6] = key[8..12].littleEndianToNative!uint; + ctx.state[7] = key[12..16].littleEndianToNative!uint; + ctx.state[8] = key[16..20].littleEndianToNative!uint; + ctx.state[9] = key[20..24].littleEndianToNative!uint; + ctx.state[10] = key[24..28].littleEndianToNative!uint; + ctx.state[11] = key[28..32].littleEndianToNative!uint; + ctx.state[12] = cast(uint)counter; + ctx.state[13] = ctx.nonceLow | (counter >> 32); + ctx.state[14] = nonce[4..8].littleEndianToNative!uint; + ctx.state[15] = nonce[8..12].littleEndianToNative!uint; + + ctx.keystream32[] = 0; + + // set starting position to the end of the key buffer; there are no bytes to consume yet + ctx.position = 64; +} + +static void chacha_set_counter(ref ChaChaContext ctx, ulong counter) pure +{ + ctx.state[12] = cast(uint)counter; + ctx.state[13] = ctx.nonceLow | (counter >> 32); +} + +void chacha_free_context(ref ChaChaContext ctx) pure +{ + ctx.state[] = 0; + ctx.keystream32[] = 0; + ctx.position = 0; + ctx.nonceLow = 0; + ctx.rounds = 0; +} + +size_t chacha_update(ref ChaChaContext ctx, const ubyte[] input, ubyte[] output) pure +{ + import urt.util : min; + + size_t size = input.length; + assert(output.length >= size); + + size_t offset = 0; + if (ctx.position < 64) + { + size_t startBytes = min(size, 64 - ctx.position); + output[0 .. startBytes] = input[0 .. startBytes] ^ ctx.keystream8[ctx.position .. 64]; + ctx.position += startBytes; + size -= startBytes; + offset = startBytes; + } + while (size >= 64) + { + chacha_block_next(ctx); + output[offset .. offset + 64] = input[offset .. offset + 64] ^ ctx.keystream8[]; + offset += 64; + size -= 64; + } + if (size > 0) + { + chacha_block_next(ctx); + output[offset .. offset + size] = input[offset .. offset + size] ^ ctx.keystream8[0 .. size]; + ctx.position = cast(ushort)size; + } + + return input.length; +} + + +size_t chacha_crypt(const ubyte[] input, ubyte[] output, ref const ubyte[32] key, ulong nonce, ulong counter = 0) pure +{ + return chacha_crypt(input, output, key, expandNonce(nonce), counter); +} + +size_t chacha_crypt(const ubyte[] input, ubyte[] output, ref const ubyte[32] key, ref const ubyte[12] nonce, ulong counter = 0) pure +{ + assert(output.length >= input.length); + + ChaChaContext ctx; + ctx.chacha_init_context(key, nonce, counter); + size_t r = ctx.chacha_update(input, output); + ctx.chacha_free_context(); + return r; +} + + +private: + +ubyte[12] expandNonce(ulong nonce) pure +{ + ubyte[12] nonceBytes = void; + nonceBytes[0 .. 4] = 0; + nonceBytes[4 .. 12] = nativeToLittleEndian(nonce); + return nonceBytes; +} + +pragma(inline, true) +uint rotl32(int n)(uint x) pure + => (x << n) | (x >> (32 - n)); + +pragma(inline, true) +void chacha_quarter_round(uint a, uint b, uint c, uint d)(ref uint[16] state) pure +{ + state[a] += state[b]; state[d] = rotl32!16(state[d] ^ state[a]); + state[c] += state[d]; state[b] = rotl32!12(state[b] ^ state[c]); + state[a] += state[b]; state[d] = rotl32!8(state[d] ^ state[a]); + state[c] += state[d]; state[b] = rotl32!7(state[b] ^ state[c]); +} + +void chacha_block_next(ref ChaChaContext ctx) pure +{ + // this is where the crazy voodoo magic happens. + // mix the bytes a lot and hope that nobody finds out how to undo it. + ctx.keystream32 = ctx.state; + + // TODO: we might like to unroll this...? + foreach (i; 0 .. ctx.rounds) + { + chacha_quarter_round!(0, 4, 8, 12)(ctx.keystream32); + chacha_quarter_round!(1, 5, 9, 13)(ctx.keystream32); + chacha_quarter_round!(2, 6, 10, 14)(ctx.keystream32); + chacha_quarter_round!(3, 7, 11, 15)(ctx.keystream32); + + chacha_quarter_round!(0, 5, 10, 15)(ctx.keystream32); + chacha_quarter_round!(1, 6, 11, 12)(ctx.keystream32); + chacha_quarter_round!(2, 7, 8, 13)(ctx.keystream32); + chacha_quarter_round!(3, 4, 9, 14)(ctx.keystream32); + } + + ctx.keystream32[] += ctx.state[]; + + // increment counter + uint* counter = &ctx.state[12]; + counter[0]++; + if (counter[0] == 0) + { + // wrap around occured, increment higher 32 bits of counter + counter[1]++; + // limited to 2^64 blocks of 64 bytes each. + // if you want to process more than 1180591620717411303424 bytes, you have other problems. + // we could keep counting with counter[2] and counter[3] (nonce), but then we risk reusing the nonce which is very bad! + assert(counter[1] != 0); + } +} + + +unittest +{ + import urt.encoding; + + immutable ubyte[32] test1_key = HexDecode!"0000000000000000000000000000000000000000000000000000000000000000"; + immutable ubyte[12] test1_nonce = HexDecode!"000000000000000000000000"; + immutable ubyte[64] test1_input = 0; + immutable ubyte[64] test1_output = [ + 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90, 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28, + 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a, 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7, + 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d, 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37, + 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c, 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86 + ]; + + immutable ubyte[32] test2_key = HexDecode!"0000000000000000000000000000000000000000000000000000000000000001"; + immutable ubyte[12] test2_nonce = HexDecode!"000000000000000000000002"; + immutable ubyte[375] test2_input = [ + 0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d,0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45,0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e, + 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74,0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66,0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61,0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72, + 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66,0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46, + 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20, + 0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61,0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74,0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69, + 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49,0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20,0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, + 0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49,0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e,0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20,0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45,0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20,0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20, + 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20,0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63,0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61,0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e, + 0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f,0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c, + 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61,0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f + ]; + immutable ubyte[375] test2_output = [ + 0xa3, 0xfb, 0xf0, 0x7d, 0xf3, 0xfa, 0x2f, 0xde,0x4f, 0x37, 0x6c, 0xa2, 0x3e, 0x82, 0x73, 0x70, + 0x41, 0x60, 0x5d, 0x9f, 0x4f, 0x4f, 0x57, 0xbd,0x8c, 0xff, 0x2c, 0x1d, 0x4b, 0x79, 0x55, 0xec, + 0x2a, 0x97, 0x94, 0x8b, 0xd3, 0x72, 0x29, 0x15,0xc8, 0xf3, 0xd3, 0x37, 0xf7, 0xd3, 0x70, 0x05, + 0x0e, 0x9e, 0x96, 0xd6, 0x47, 0xb7, 0xc3, 0x9f,0x56, 0xe0, 0x31, 0xca, 0x5e, 0xb6, 0x25, 0x0d, + 0x40, 0x42, 0xe0, 0x27, 0x85, 0xec, 0xec, 0xfa,0x4b, 0x4b, 0xb5, 0xe8, 0xea, 0xd0, 0x44, 0x0e, + 0x20, 0xb6, 0xe8, 0xdb, 0x09, 0xd8, 0x81, 0xa7,0xc6, 0x13, 0x2f, 0x42, 0x0e, 0x52, 0x79, 0x50, + 0x42, 0xbd, 0xfa, 0x77, 0x73, 0xd8, 0xa9, 0x05,0x14, 0x47, 0xb3, 0x29, 0x1c, 0xe1, 0x41, 0x1c, + 0x68, 0x04, 0x65, 0x55, 0x2a, 0xa6, 0xc4, 0x05,0xb7, 0x76, 0x4d, 0x5e, 0x87, 0xbe, 0xa8, 0x5a, + 0xd0, 0x0f, 0x84, 0x49, 0xed, 0x8f, 0x72, 0xd0,0xd6, 0x62, 0xab, 0x05, 0x26, 0x91, 0xca, 0x66, + 0x42, 0x4b, 0xc8, 0x6d, 0x2d, 0xf8, 0x0e, 0xa4,0x1f, 0x43, 0xab, 0xf9, 0x37, 0xd3, 0x25, 0x9d, + 0xc4, 0xb2, 0xd0, 0xdf, 0xb4, 0x8a, 0x6c, 0x91,0x39, 0xdd, 0xd7, 0xf7, 0x69, 0x66, 0xe9, 0x28, + 0xe6, 0x35, 0x55, 0x3b, 0xa7, 0x6c, 0x5c, 0x87,0x9d, 0x7b, 0x35, 0xd4, 0x9e, 0xb2, 0xe6, 0x2b, + 0x08, 0x71, 0xcd, 0xac, 0x63, 0x89, 0x39, 0xe2,0x5e, 0x8a, 0x1e, 0x0e, 0xf9, 0xd5, 0x28, 0x0f, + 0xa8, 0xca, 0x32, 0x8b, 0x35, 0x1c, 0x3c, 0x76,0x59, 0x89, 0xcb, 0xcf, 0x3d, 0xaa, 0x8b, 0x6c, + 0xcc, 0x3a, 0xaf, 0x9f, 0x39, 0x79, 0xc9, 0x2b,0x37, 0x20, 0xfc, 0x88, 0xdc, 0x95, 0xed, 0x84, + 0xa1, 0xbe, 0x05, 0x9c, 0x64, 0x99, 0xb9, 0xfd,0xa2, 0x36, 0xe7, 0xe8, 0x18, 0xb0, 0x4b, 0x0b, + 0xc3, 0x9c, 0x1e, 0x87, 0x6b, 0x19, 0x3b, 0xfe,0x55, 0x69, 0x75, 0x3f, 0x88, 0x12, 0x8c, 0xc0, + 0x8a, 0xaa, 0x9b, 0x63, 0xd1, 0xa1, 0x6f, 0x80,0xef, 0x25, 0x54, 0xd7, 0x18, 0x9c, 0x41, 0x1f, + 0x58, 0x69, 0xca, 0x52, 0xc5, 0xb8, 0x3f, 0xa3,0x6f, 0xf2, 0x16, 0xb9, 0xc1, 0xd3, 0x00, 0x62, + 0xbe, 0xbc, 0xfd, 0x2d, 0xc5, 0xbc, 0xe0, 0x91,0x19, 0x34, 0xfd, 0xa7, 0x9a, 0x86, 0xf6, 0xe6, + 0x98, 0xce, 0xd7, 0x59, 0xc3, 0xff, 0x9b, 0x64,0x77, 0x33, 0x8f, 0x3d, 0xa4, 0xf9, 0xcd, 0x85, + 0x14, 0xea, 0x99, 0x82, 0xcc, 0xaf, 0xb3, 0x41,0xb2, 0x38, 0x4d, 0xd9, 0x02, 0xf3, 0xd1, 0xab, + 0x7a, 0xc6, 0x1d, 0xd2, 0x9c, 0x6f, 0x21, 0xba,0x5b, 0x86, 0x2f, 0x37, 0x30, 0xe3, 0x7c, 0xfd, + 0xc4, 0xfd, 0x80, 0x6c, 0x22, 0xf2, 0x21 + ]; + + immutable ubyte[32] test3_key = HexDecode!"c46ec1b18ce8a878725a37e780dfb7351f68ed2e194c79fbc6aebee1a667975d"; + enum ulong test3_nonce = 0x218268cfd531da1a; + immutable ubyte[127] test3_input = 0; + immutable ubyte[127] test3_output = [ + 0xf6, 0x3a, 0x89, 0xb7, 0x5c, 0x22, 0x71, 0xf9,0x36, 0x88, 0x16, 0x54, 0x2b, 0xa5, 0x2f, 0x06, + 0xed, 0x49, 0x24, 0x17, 0x92, 0x30, 0x2b, 0x00,0xb5, 0xe8, 0xf8, 0x0a, 0xe9, 0xa4, 0x73, 0xaf, + 0xc2, 0x5b, 0x21, 0x8f, 0x51, 0x9a, 0xf0, 0xfd,0xd4, 0x06, 0x36, 0x2e, 0x8d, 0x69, 0xde, 0x7f, + 0x54, 0xc6, 0x04, 0xa6, 0xe0, 0x0f, 0x35, 0x3f,0x11, 0x0f, 0x77, 0x1b, 0xdc, 0xa8, 0xab, 0x92, + 0xe5, 0xfb, 0xc3, 0x4e, 0x60, 0xa1, 0xd9, 0xa9,0xdb, 0x17, 0x34, 0x5b, 0x0a, 0x40, 0x27, 0x36, + 0x85, 0x3b, 0xf9, 0x10, 0xb0, 0x60, 0xbd, 0xf1,0xf8, 0x97, 0xb6, 0x29, 0x0f, 0x01, 0xd1, 0x38, + 0xae, 0x2c, 0x4c, 0x90, 0x22, 0x5b, 0xa9, 0xea,0x14, 0xd5, 0x18, 0xf5, 0x59, 0x29, 0xde, 0xa0, + 0x98, 0xca, 0x7a, 0x6c, 0xcf, 0xe6, 0x12, 0x27,0x05, 0x3c, 0x84, 0xe4, 0x9a, 0x4a, 0x33 + ]; + + ubyte[375] output = void; + + size_t ret = test1_input.chacha_crypt(output, test1_key, test1_nonce); + assert(ret == test1_input.length); + assert(output[0 .. test1_output.length] == test1_output[]); + + ChaChaContext ctx; + ctx.chacha_init_context(test2_key, test2_nonce, 1); + ret = ctx.chacha_update(test2_input[0 .. 17], output[0 .. 17]); + ret += ctx.chacha_update(test2_input[17 .. $], output[17 .. $]); + assert(ret == test2_input.length); + assert(output[0 .. test2_output.length] == test2_output[]); + + ret = test3_input.chacha_crypt(output, test3_key, test3_nonce); + assert(ret == test3_input.length); + assert(output[0 .. test3_output.length] == test3_output[]); +} diff --git a/src/urt/crypto/der.d b/src/urt/crypto/der.d new file mode 100644 index 0000000..42f769e --- /dev/null +++ b/src/urt/crypto/der.d @@ -0,0 +1,247 @@ +module urt.crypto.der; + +import urt.time : DateTime; + +nothrow @nogc: + + +// pre-encoded OID content bytes +static immutable ubyte[7] oid_ec_public_key = [0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01]; // 1.2.840.10045.2.1 +static immutable ubyte[8] oid_prime256v1 = [0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07]; // 1.2.840.10045.3.1.7 +static immutable ubyte[8] oid_sha256_ecdsa = [0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02]; // 1.2.840.10045.4.3.2 +static immutable ubyte[3] oid_common_name = [0x55, 0x04, 0x03]; // 2.5.4.3 + + +// Primitives... + +uint der_length_size(size_t len) pure +{ + if (len < 0x80) + return 1; + if (len < 0x100) + return 2; + return 3; +} + +// write tag + length header for known content size +ptrdiff_t der_header(ubyte[] buf, ubyte tag, size_t content_len) +{ + size_t n = 1 + der_length_size(content_len); + if (!buf.ptr) + return n; + if (buf.length < n) + return -1; + size_t pos = 0; + buf[pos++] = tag; + pos += put_length(buf[pos .. $], content_len); + return pos; +} + +// write tag + length + content +ptrdiff_t der_tlv(ubyte[] buf, ubyte tag, const(ubyte)[] content) +{ + size_t n = 1 + der_length_size(content.length) + content.length; + if (!buf.ptr) + return n; + if (buf.length < n) + return -1; + size_t pos = 0; + buf[pos++] = tag; + pos += put_length(buf[pos .. $], content.length); + buf[pos .. pos + content.length] = content[]; + return n; +} + +// INTEGER with leading-zero stripping and sign padding +ptrdiff_t der_integer(ubyte[] buf, const(ubyte)[] value) +{ + while (value.length > 1 && value[0] == 0) + value = value[1 .. $]; + bool pad = (value[0] & 0x80) != 0; + size_t content_len = (pad ? 1 : 0) + value.length; + size_t n = 1 + der_length_size(content_len) + content_len; + if (!buf.ptr) + return n; + if (buf.length < n) + return -1; + size_t pos = 0; + buf[pos++] = 0x02; + pos += put_length(buf[pos .. $], content_len); + if (pad) + buf[pos++] = 0; + buf[pos .. pos + value.length] = value[]; + return n; +} + +ptrdiff_t der_integer_small(ubyte[] buf, uint value) +{ + if (value == 0) + { + if (!buf.ptr) + return 3; + if (buf.length < 3) + return -1; + buf[0] = 0x02; + buf[1] = 0x01; + buf[2] = 0x00; + return 3; + } + ubyte[4] be = void; + uint n = 0; + for (uint v = value; v > 0; v >>= 8) + ++n; + for (uint i = 0; i < n; ++i) + be[i] = cast(ubyte)(value >> ((n - 1 - i) * 8)); + return der_integer(buf, be[0 .. n]); +} + + +// Composite structures... + +// SEQUENCE { INTEGER r, INTEGER s } from raw 64-byte ECDSA P-256 signature +ptrdiff_t der_ecdsa_sig(ubyte[] buf, const(ubyte)[] raw_sig) +{ + ptrdiff_t r_size = der_integer(null, raw_sig[0 .. 32]); + ptrdiff_t s_size = der_integer(null, raw_sig[32 .. 64]); + size_t content = r_size + s_size; + size_t total = 1 + der_length_size(content) + content; + if (!buf.ptr) + return total; + if (buf.length < total) + return -1; + size_t pos = 0; + buf[pos++] = 0x30; + pos += put_length(buf[pos .. $], content); + pos += der_integer(buf[pos .. $], raw_sig[0 .. 32]); + pos += der_integer(buf[pos .. $], raw_sig[32 .. 64]); + return total; +} + +ptrdiff_t der_utctime(ubyte[] buf, DateTime dt) +{ + enum size_t total = 15; // tag(1) + length(1) + content(13) + if (!buf.ptr) + return total; + if (buf.length < total) + return -1; + buf[0] = 0x17; + buf[1] = 13; + ubyte yr = cast(ubyte)(dt.year % 100); + ubyte mo = cast(ubyte)dt.month; + buf[2] = cast(ubyte)('0' + yr / 10); + buf[3] = cast(ubyte)('0' + yr % 10); + buf[4] = cast(ubyte)('0' + mo / 10); + buf[5] = cast(ubyte)('0' + mo % 10); + buf[6] = cast(ubyte)('0' + dt.day / 10); + buf[7] = cast(ubyte)('0' + dt.day % 10); + buf[8] = cast(ubyte)('0' + dt.hour / 10); + buf[9] = cast(ubyte)('0' + dt.hour % 10); + buf[10] = cast(ubyte)('0' + dt.minute / 10); + buf[11] = cast(ubyte)('0' + dt.minute % 10); + buf[12] = cast(ubyte)('0' + dt.second / 10); + buf[13] = cast(ubyte)('0' + dt.second % 10); + buf[14] = 'Z'; + return total; +} + +// X.500 Name with a single CN attribute: SEQUENCE { SET { SEQUENCE { OID, UTF8String } } } +ptrdiff_t der_name_cn(ubyte[] buf, const(char)[] cn) +{ + size_t oid_tlv = 1 + 1 + oid_common_name.length; + size_t utf8_tlv = 1 + der_length_size(cn.length) + cn.length; + size_t atv_content = oid_tlv + utf8_tlv; + size_t atv = 1 + der_length_size(atv_content) + atv_content; + size_t rdn = 1 + der_length_size(atv) + atv; + size_t total = 1 + der_length_size(rdn) + rdn; + if (!buf.ptr) + return total; + if (buf.length < total) + return -1; + size_t pos = 0; + buf[pos++] = 0x30; + pos += put_length(buf[pos .. $], rdn); + buf[pos++] = 0x31; + pos += put_length(buf[pos .. $], atv); + buf[pos++] = 0x30; + pos += put_length(buf[pos .. $], atv_content); + pos += der_tlv(buf[pos .. $], 0x06, oid_common_name[]); + pos += der_tlv(buf[pos .. $], 0x0c, cast(const(ubyte)[])cn); + return total; +} + +// SubjectPublicKeyInfo for EC P-256 uncompressed point +ptrdiff_t der_ec_pubkey_info(ubyte[] buf, const(ubyte)[] x, const(ubyte)[] y) +{ + size_t oid1_tlv = 1 + 1 + oid_ec_public_key.length; + size_t oid2_tlv = 1 + 1 + oid_prime256v1.length; + size_t alg_content = oid1_tlv + oid2_tlv; + size_t alg = 1 + der_length_size(alg_content) + alg_content; + + size_t bs_content = 1 + 1 + x.length + y.length; // unused_bits + 0x04 + x + y + size_t bs = 1 + der_length_size(bs_content) + bs_content; + + size_t spki_content = alg + bs; + size_t total = 1 + der_length_size(spki_content) + spki_content; + if (!buf.ptr) + return total; + if (buf.length < total) + return -1; + + size_t pos = 0; + buf[pos++] = 0x30; + pos += put_length(buf[pos .. $], spki_content); + + buf[pos++] = 0x30; + pos += put_length(buf[pos .. $], alg_content); + pos += der_tlv(buf[pos .. $], 0x06, oid_ec_public_key[]); + pos += der_tlv(buf[pos .. $], 0x06, oid_prime256v1[]); + + buf[pos++] = 0x03; + pos += put_length(buf[pos .. $], bs_content); + buf[pos++] = 0x00; + buf[pos++] = 0x04; + buf[pos .. pos + x.length] = x[]; + pos += x.length; + buf[pos .. pos + y.length] = y[]; + pos += y.length; + + return total; +} + +// AlgorithmIdentifier for sha256WithECDSA +ptrdiff_t der_sig_alg(ubyte[] buf) +{ + size_t oid_tlv = 1 + 1 + oid_sha256_ecdsa.length; + size_t total = 1 + der_length_size(oid_tlv) + oid_tlv; + if (!buf.ptr) + return total; + if (buf.length < total) + return -1; + size_t pos = 0; + buf[pos++] = 0x30; + pos += put_length(buf[pos .. $], oid_tlv); + pos += der_tlv(buf[pos .. $], 0x06, oid_sha256_ecdsa[]); + return total; +} + + +private: + +uint put_length(ubyte[] buf, size_t len) +{ + if (len < 0x80) + { + buf[0] = cast(ubyte)len; + return 1; + } + if (len < 0x100) + { + buf[0] = 0x81; + buf[1] = cast(ubyte)len; + return 2; + } + buf[0] = 0x82; + buf[1] = cast(ubyte)(len >> 8); + buf[2] = cast(ubyte)(len & 0xff); + return 3; +} diff --git a/src/urt/crypto/ecdh.d b/src/urt/crypto/ecdh.d new file mode 100644 index 0000000..7dbf631 --- /dev/null +++ b/src/urt/crypto/ecdh.d @@ -0,0 +1,130 @@ +module urt.crypto.ecdh; + +import urt.result; + +version (MbedTLS) + import urt.internal.mbedtls : urt_ecdh_p256_compute_shared; +else version (Windows) +{ + import core.sys.windows.bcrypt; + import core.sys.windows.ntdef : NTSTATUS; + pragma(lib, "Bcrypt"); + + // druntime gates this behind NTDDI_WINBLUE; declare directly so it's available + // regardless of the target's NTDDI_VERSION (the KDF itself works on Win8.1+). + private enum wstring BCRYPT_KDF_RAW_SECRET = "TRUNCATE"w; +} + +nothrow @nogc: + + +// ECDH P-256 shared-secret computation. +// +// priv_d: 32-byte big-endian private scalar. +// priv_xy: 64-byte own public key (X || Y, no leading 0x04). Required by the +// Windows BCrypt backend, which cannot derive it from the private +// scalar alone; the mbedtls backend ignores it. Callers tracking a +// P-256 keypair already have both halves available. +// peer_xy: 64-byte peer public key (X || Y, no leading 0x04). +// shared_x: 32-byte output - big-endian X coordinate of (priv_d * peer_point). +Result ecdh_p256_compute_shared(const(ubyte)[] priv_d, + const(ubyte)[] priv_xy, + const(ubyte)[] peer_xy, + ubyte[] shared_x) +{ + if (priv_d.length != 32 || peer_xy.length != 64 || shared_x.length != 32) + return InternalResult.invalid_parameter; + + version (MbedTLS) + { + int ret = urt_ecdh_p256_compute_shared( + priv_d.ptr, priv_d.length, + peer_xy.ptr, peer_xy.length, + shared_x.ptr); + return ret == 0 ? Result.success : Result(cast(uint)ret); + } + else version (Windows) + { + if (priv_xy.length != 64) + return InternalResult.invalid_parameter; + + BCRYPT_ALG_HANDLE halg; + NTSTATUS status = BCryptOpenAlgorithmProvider(&halg, BCRYPT_ECDH_P256_ALGORITHM.ptr, null, 0); + if (status != 0) + return Result(cast(uint)status); + scope(exit) BCryptCloseAlgorithmProvider(halg, 0); + + // BCRYPT_ECCKEY_BLOB: { Magic, cbKey=32 } then X[32] Y[32] d[32] + ubyte[104] priv_blob = void; + (cast(uint[])priv_blob[0 .. 8])[0] = BCRYPT_ECDH_PRIVATE_P256_MAGIC; + (cast(uint[])priv_blob[0 .. 8])[1] = 32; + priv_blob[8 .. 40] = priv_xy[0 .. 32]; // X + priv_blob[40 .. 72] = priv_xy[32 .. 64]; // Y + priv_blob[72 .. 104] = priv_d[]; // d + + // BCRYPT_NO_KEY_VALIDATION skips BCrypt's d*G==(X,Y) consistency check. + // Some Windows hosts reject otherwise-valid imports (observed with the + // RFC 5903 P-256 test vector); the shared-secret math doesn't depend on + // this check so bypassing it is safe for any caller that trusts its own d. + enum uint BCRYPT_NO_KEY_VALIDATION = 0x00000008; + + BCRYPT_KEY_HANDLE hpriv; + status = BCryptImportKeyPair(halg, null, BCRYPT_ECCPRIVATE_BLOB.ptr, &hpriv, + priv_blob.ptr, priv_blob.length, BCRYPT_NO_KEY_VALIDATION); + if (status != 0) + return Result(cast(uint)status); + scope(exit) BCryptDestroyKey(hpriv); + + // public blob: { Magic, cbKey=32 } then X[32] Y[32] + ubyte[72] pub_blob = void; + (cast(uint[])pub_blob[0 .. 8])[0] = BCRYPT_ECDH_PUBLIC_P256_MAGIC; + (cast(uint[])pub_blob[0 .. 8])[1] = 32; + pub_blob[8 .. 40] = peer_xy[0 .. 32]; + pub_blob[40 .. 72] = peer_xy[32 .. 64]; + + BCRYPT_KEY_HANDLE hpub; + status = BCryptImportKeyPair(halg, null, BCRYPT_ECCPUBLIC_BLOB.ptr, &hpub, + pub_blob.ptr, pub_blob.length, 0); + if (status != 0) + return Result(cast(uint)status); + scope(exit) BCryptDestroyKey(hpub); + + BCRYPT_SECRET_HANDLE hsecret; + status = BCryptSecretAgreement(hpriv, hpub, &hsecret, 0); + if (status != 0) + return Result(cast(uint)status); + scope(exit) BCryptDestroySecret(hsecret); + + // BCRYPT_KDF_RAW_SECRET returns the X coord in LITTLE-endian byte order. + // Everyone else (mbedtls, Tesla, NIST vectors) expects big-endian - reverse. + ubyte[32] tmp = void; + uint result_len; + status = BCryptDeriveKey(hsecret, BCRYPT_KDF_RAW_SECRET.ptr, null, + tmp.ptr, tmp.length, &result_len, 0); + if (status != 0) + return Result(cast(uint)status); + + foreach (i; 0 .. 32) + shared_x[i] = tmp[31 - i]; + return Result.success; + } + else + return InternalResult.unsupported; +} + + +unittest +{ + // RFC 5903 Section 8.1 (IKE Group 19, P-256) ECDH test vector + import urt.encoding : HexDecode; + + auto i_priv = HexDecode!"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433"; + auto i_pub = HexDecode!"dad0b65394221cf9b051e1feca57124565a55c5e3d6a66ac6ccb0ae69d5da873b6d1ac3639e83d2a35712f034cd7b62a0fab6671e51cc9b0d1d6f70f4a6ec3f5"; + auto r_pub = HexDecode!"d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab"; + auto expected_z = HexDecode!"d6840f6b42f6edafd13116e0e12565202fef8e9ece7dce03812464d04b9442de"; + + ubyte[32] shared_secret; + auto r = ecdh_p256_compute_shared(i_priv[], i_pub[], r_pub[], shared_secret[]); + assert(r.succeeded); + assert(shared_secret == expected_z); +} diff --git a/src/urt/crypto/pbkdf2.d b/src/urt/crypto/pbkdf2.d new file mode 100644 index 0000000..03f2cbe --- /dev/null +++ b/src/urt/crypto/pbkdf2.d @@ -0,0 +1,99 @@ +module urt.crypto.pbkdf2; + +import urt.digest.hmac : HMACContext, hmac_init, hmac_update, hmac_finalise; +import urt.digest.sha : SHA1Context; +import urt.result : Result, InternalResult; + +nothrow @nogc: + + +// PBKDF2-HMAC-SHA1 as used by WPA/WPA2-PSK to derive the 32-byte PMK from +// passphrase + SSID. The interface is generic over output length so callers can +// also use the standard test vectors without heap allocation. +Result pbkdf2_hmac_sha1(const(ubyte)[] passphrase, + const(ubyte)[] salt, + uint iterations, + ubyte[] output) +{ + if (passphrase.length == 0 || salt.length == 0 || iterations == 0 || output.length == 0) + return InternalResult.invalid_parameter; + + ubyte[SHA1Context.DigestLen] u = void; + ubyte[SHA1Context.DigestLen] block = void; + ubyte[4] counter_be = void; + + size_t pos; + uint counter = 1; + while (pos < output.length) + { + counter_be[0] = cast(ubyte)(counter >> 24); + counter_be[1] = cast(ubyte)(counter >> 16); + counter_be[2] = cast(ubyte)(counter >> 8); + counter_be[3] = cast(ubyte)counter; + + HMACContext!SHA1Context h; + hmac_init(h, passphrase); + hmac_update(h, salt); + hmac_update(h, counter_be[]); + u = hmac_finalise(h); + block[] = u[]; + + foreach (_; 1 .. iterations) + { + hmac_init(h, passphrase); + hmac_update(h, u[]); + u = hmac_finalise(h); + foreach (i; 0 .. block.length) + block[i] ^= u[i]; + } + + size_t n = output.length - pos; + if (n > block.length) + n = block.length; + output[pos .. pos + n] = block[0 .. n]; + pos += n; + counter++; + } + + return Result.success; +} + +Result wpa2_psk_to_pmk(const(char)[] passphrase, + const(char)[] ssid, + ubyte[] pmk) +{ + if (passphrase.length < 8 || passphrase.length > 63 || ssid.length == 0 || ssid.length > 32 || + pmk.length != 32) + return InternalResult.invalid_parameter; + + return pbkdf2_hmac_sha1(cast(const(ubyte)[])passphrase, + cast(const(ubyte)[])ssid, + 4096, + pmk); +} + + +unittest +{ + ubyte[20] out1; + assert(pbkdf2_hmac_sha1(cast(const(ubyte)[])"password", + cast(const(ubyte)[])"salt", + 1, + out1[])); + static immutable ubyte[20] expected1 = [ + 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71, 0xf3, 0xa9, + 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06, 0x2f, 0xe0, 0x37, 0xa6, + ]; + assert(out1 == expected1); + + ubyte[20] out2; + assert(pbkdf2_hmac_sha1(cast(const(ubyte)[])"password", + cast(const(ubyte)[])"salt", + 2, + out2[])); + static immutable ubyte[20] expected2 = [ + 0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c, 0xcd, 0x1e, + 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0, 0xd8, 0xde, 0x89, 0x57, + ]; + assert(out2 == expected2); +} diff --git a/src/urt/crypto/pem.d b/src/urt/crypto/pem.d new file mode 100644 index 0000000..1cc32e7 --- /dev/null +++ b/src/urt/crypto/pem.d @@ -0,0 +1,72 @@ +module urt.crypto.pem; + +import urt.array; +import urt.encoding; +import urt.mem; + +nothrow @nogc: + + +bool is_pem(const(char)[] data) + => data.length >= 11 && data[0 .. 11] == "-----BEGIN "; + +Array!char encode_pem(const(ubyte)[] der, const(char)[] label) +{ + Array!char result = "-----BEGIN "; + result ~= label; + result ~= "-----\n"; + + size_t enc_len = base64_encode_length(der.length); + if (enc_len > 256) + assert(false, "PEM encode: DER input too large for stack buffer"); + char[256] b64_buf = void; + base64_encode(der, b64_buf[0 .. enc_len]); + + size_t pos = 0; + while (pos < enc_len) + { + size_t line_len = enc_len - pos; + if (line_len > 64) + line_len = 64; + result ~= b64_buf[pos .. pos + line_len]; + result ~= "\n"; + pos += line_len; + } + + result ~= "-----END "; + result ~= label; + result ~= "-----\n"; + return result; +} + +Array!ubyte decode_pem(const(char)[] data) +{ + import urt.string; + + size_t start = data.findFirst('\n'); + if (start == data.length) + return Array!ubyte(); + data = data[start .. $].trimFront; + + size_t end = data.findFirst("-----END"); + if (end == data.length) + return Array!ubyte(); + data = data[0 .. end].trimBack; + + if (data.length == 0) + return Array!ubyte(); + + // strip whitespace from base64 content + auto b64 = Array!char(Reserve, data.length); + for (size_t i = 0; i < data.length; ++i) + if (!data[i].is_whitespace) + b64 ~= data[i]; + + auto result = Array!ubyte(Alloc, base64_decode_length(b64.length)); + ptrdiff_t decoded_len = base64_decode(b64[], result[]); + if (decoded_len < 0) + return Array!ubyte(); + + result.resize(decoded_len); + return result; +} diff --git a/src/urt/crypto/pki.d b/src/urt/crypto/pki.d new file mode 100644 index 0000000..00e3b7d --- /dev/null +++ b/src/urt/crypto/pki.d @@ -0,0 +1,1184 @@ +module urt.crypto.pki; + +import urt.array; +import urt.crypto.der; +import urt.crypto.pem; +import urt.digest.sha : SHA256Context, sha_init, sha_update, sha_finalise; +import urt.mem; +import urt.result; +import urt.string; +import urt.time; + +nothrow @nogc: + + +struct KeyPair +{ +nothrow @nogc: + version (MbedTLS) + { + mbedtls_pk_context pk; + } + else version (Windows) + { + BCRYPT_ALG_HANDLE halg; + BCRYPT_KEY_HANDLE hcng; + } + else version (FreeStanding) + { + // PKI backend not yet implemented for bare-metal + void* _stub; + } + else + static assert(false, "TODO"); + + bool valid() const pure + { + version (MbedTLS) + return pk.pk_info !is null; + else version (Windows) + return hcng !is null; + else + return false; + } +} + +struct CertRef +{ +nothrow @nogc: + version (MbedTLS) + { + mbedtls_x509_crt* crt; // heap-allocated via urt_x509_crt_new + } + else version (Windows) + { + PCCERT_CONTEXT context; + HCERTSTORE store; + NCRYPT_KEY_HANDLE hncrypt; // persisted NCrypt key for SChannel (set by associate_key) + } + + bool valid() const pure + { + version (MbedTLS) + return crt !is null; + else version (Windows) + return context !is null; + else + return false; + } +} + + +Result generate_keypair(out KeyPair kp) +{ + version (MbedTLS) + { + mbedtls_pk_init(&kp.pk); + int ret = urt_pk_gen_ec_p256_key(&kp.pk); + if (ret != 0) + { + mbedtls_pk_free(&kp.pk); + kp.pk = mbedtls_pk_context.init; + return Result(cast(uint)ret); + } + + return Result.success; + } + else version (Windows) + { + NTSTATUS status = BCryptOpenAlgorithmProvider(&kp.halg, BCRYPT_ECDSA_P256_ALGORITHM.ptr, null, 0); + if (status != 0) + return Result(cast(uint)status); + + status = BCryptGenerateKeyPair(kp.halg, &kp.hcng, 256, 0); + if (status != 0) + { + BCryptCloseAlgorithmProvider(kp.halg, 0); + kp.halg = null; + return Result(cast(uint)status); + } + + status = BCryptFinalizeKeyPair(kp.hcng, 0); + if (status != 0) + { + BCryptDestroyKey(kp.hcng); + kp.hcng = null; + BCryptCloseAlgorithmProvider(kp.halg, 0); + kp.halg = null; + return Result(cast(uint)status); + } + + return Result.success; + } + else + assert(0, "PKI: generate_keypair not implemented for this platform"); +} + +void free_keypair(ref KeyPair kp) +{ + version (MbedTLS) + { + mbedtls_pk_free(&kp.pk); + kp.pk = mbedtls_pk_context.init; + } + else version (Windows) + { + if (kp.hcng !is null) + BCryptDestroyKey(kp.hcng); + if (kp.halg !is null) + BCryptCloseAlgorithmProvider(kp.halg, 0); + kp.hcng = null; + kp.halg = null; + } +} + +version (MbedTLS) + alias create_self_signed = create_self_signed_portable; +else version (Windows) + alias create_self_signed = create_self_signed_win32; +else + alias create_self_signed = create_self_signed_portable; + +version (Windows) +{ + Result create_self_signed_win32(ref KeyPair key, out CertRef cert, const(char)[] cn, const(char)[] hostname = null, uint validity_days = 365) + { + // create a persisted NCrypt ECDSA P-256 key (SChannel requires persisted keys) + NCRYPT_PROV_HANDLE hprov; + SECURITY_STATUS ss = NCryptOpenStorageProvider(&hprov, MS_KEY_STORAGE_PROVIDER.ptr, 0); + if (ss != 0) + return Result(cast(uint)ss); + + wchar[48] name_buf = void; + generate_key_name(name_buf[]); + + NCRYPT_KEY_HANDLE hncrypt; + ss = NCryptCreatePersistedKey(hprov, &hncrypt, BCRYPT_ECDSA_P256_ALGORITHM.ptr, name_buf.ptr, 0, NCRYPT_OVERWRITE_KEY_FLAG); + NCryptFreeObject(hprov); + if (ss != 0) + return Result(cast(uint)ss); + + ss = NCryptFinalizeKey(hncrypt, 0); + if (ss != 0) + { + NCryptFreeObject(hncrypt); + return Result(cast(uint)ss); + } + + // encode subject name as DER + ubyte[128] name_der = void; + ptrdiff_t der_len = der_name_cn(name_der[], cn); + if (der_len <= 0) + { + NCryptDeleteKey(hncrypt, 0); + return InternalResult.data_error; + } + + CERT_NAME_BLOB subject_blob; + subject_blob.cbData = cast(DWORD)der_len; + subject_blob.pbData = name_der.ptr; + + // build SAN extension (Chrome requires SAN) + ubyte[512] san_der = void; + size_t pos = 2; // skip SEQUENCE header, fill in later + + void add_dns_name(scope const(char)[] name) + { + san_der[pos++] = 0x82; // dNSName [2] implicit + san_der[pos++] = cast(ubyte)name.length; + san_der[pos .. pos + name.length] = cast(const(ubyte)[])name[]; + pos += name.length; + } + + void add_ip(scope const(ubyte)[] addr) + { + san_der[pos++] = 0x87; // iPAddress [7] implicit + san_der[pos++] = cast(ubyte)addr.length; + san_der[pos .. pos + addr.length] = addr[]; + pos += addr.length; + } + + // CN as dNSName + add_dns_name(cn); + // localhost + loopback + add_dns_name("localhost"); + add_ip([127, 0, 0, 1]); + add_ip([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]); // ::1 + + // hostname.local (mDNS) + if (hostname.length > 0 && hostname.length + 6 < 128) + { + san_der[pos++] = 0x82; + san_der[pos++] = cast(ubyte)(hostname.length + 6); + san_der[pos .. pos + hostname.length] = cast(const(ubyte)[])hostname[]; + pos += hostname.length; + san_der[pos .. pos + 6] = cast(const(ubyte)[])".local"; + pos += 6; + } + + // TODO: add iPAddress SAN entries for all IP addresses the server is bound to. + // ...needs the server's bound addresses passed in or enumerated here! + + // SEQUENCE wrapper + san_der[0] = 0x30; + san_der[1] = cast(ubyte)(pos - 2); + DWORD san_len = cast(DWORD)pos; + + CERT_EXTENSION san_ext; + san_ext.pszObjId = cast(LPSTR)"2.5.29.17".ptr; // szOID_SUBJECT_ALT_NAME2 + san_ext.fCritical = FALSE; + san_ext.Value.cbData = san_len; + san_ext.Value.pbData = san_der.ptr; + + CERT_EXTENSIONS exts; + exts.cExtension = 1; + exts.rgExtension = &san_ext; + + // CertCreateSelfSignCertificate handles key association correctly for SChannel + auto pctx = CertCreateSelfSignCertificate(hncrypt, &subject_blob, 0, null, null, null, null, &exts); + if (pctx is null) + { + auto r = getlasterror_result(); + NCryptDeleteKey(hncrypt, 0); + return r; + } + + cert.context = pctx; + cert.store = null; + cert.hncrypt = hncrypt; + + return Result.success; + } +} + +private Result create_self_signed_portable(ref KeyPair key, out CertRef cert, const(char)[] cn, const(char)[] hostname = null, uint validity_days = 365) +{ + if (!key.valid) + return InternalResult.invalid_parameter; + + Array!ubyte pub_x, pub_y; + auto r = export_public_key_raw(key, pub_x, pub_y); + if (!r) + return r; + + auto now = getSysTime(); + auto not_before = getDateTime(now); + auto not_after = getDateTime(now + dur!"days"(validity_days)); + + // compute TBSCertificate field sizes + ptrdiff_t ver_inner = der_integer_small(null, 2); + ptrdiff_t ver = der_header(null, 0xa0, ver_inner) + ver_inner; + ptrdiff_t serial = der_integer_small(null, 1); + ptrdiff_t sig_alg_size = der_sig_alg(null); + ptrdiff_t issuer = der_name_cn(null, cn); + ptrdiff_t val_inner = der_utctime(null, not_before) + der_utctime(null, not_after); + ptrdiff_t validity = der_header(null, 0x30, val_inner) + val_inner; + ptrdiff_t subject = der_name_cn(null, cn); + ptrdiff_t pubkey = der_ec_pubkey_info(null, pub_x[], pub_y[]); + size_t tbs_content = ver + serial + sig_alg_size + issuer + validity + subject + pubkey; + size_t tbs_total = der_header(null, 0x30, tbs_content) + tbs_content; + + // write TBSCertificate + ubyte[512] tbs_buf = void; + size_t pos = 0; + pos += der_header(tbs_buf[pos .. $], 0x30, tbs_content); + pos += der_header(tbs_buf[pos .. $], 0xa0, ver_inner); + pos += der_integer_small(tbs_buf[pos .. $], 2); + pos += der_integer_small(tbs_buf[pos .. $], 1); + pos += der_sig_alg(tbs_buf[pos .. $]); + pos += der_name_cn(tbs_buf[pos .. $], cn); + pos += der_header(tbs_buf[pos .. $], 0x30, val_inner); + pos += der_utctime(tbs_buf[pos .. $], not_before); + pos += der_utctime(tbs_buf[pos .. $], not_after); + pos += der_name_cn(tbs_buf[pos .. $], cn); + pos += der_ec_pubkey_info(tbs_buf[pos .. $], pub_x[], pub_y[]); + + // hash and sign + SHA256Context sha; + sha_init(sha); + sha_update(sha, tbs_buf[0 .. tbs_total]); + ubyte[32] hash = sha_finalise(sha); + + Array!ubyte sig; + r = sign_hash(key, hash[], sig); + if (!r) + return r; + + // Certificate: SEQUENCE { tbs, sigAlgId, BIT STRING { ecdsa_sig } } + ptrdiff_t sig_der = der_ecdsa_sig(null, sig[]); + size_t bs_content = 1 + sig_der; // unused_bits + ecdsa_sig + size_t cert_content = tbs_total + sig_alg_size + 1 + der_length_size(bs_content) + bs_content; + size_t cert_total = der_header(null, 0x30, cert_content) + cert_content; + + ubyte[640] cert_buf = void; + pos = 0; + pos += der_header(cert_buf[pos .. $], 0x30, cert_content); + cert_buf[pos .. pos + tbs_total] = tbs_buf[0 .. tbs_total]; + pos += tbs_total; + pos += der_sig_alg(cert_buf[pos .. $]); + pos += der_header(cert_buf[pos .. $], 0x03, bs_content); + cert_buf[pos++] = 0x00; // unused bits + pos += der_ecdsa_sig(cert_buf[pos .. $], sig[]); + + return cert_buf[0 .. cert_total].load_certificate(cert); +} + +Result load_certificate(const(ubyte)[] cert_data, out CertRef cert) +{ + version (MbedTLS) + { + if (cert_data.length == 0) + return InternalResult.invalid_parameter; + + cert.crt = urt_x509_crt_new(); + if (cert.crt is null) + return InternalResult.invalid_parameter; + + // mbedtls_x509_crt_parse handles both PEM and DER. + // for PEM, the buffer must be null-terminated. + int ret; + if (is_pem(cast(const(char)[])cert_data)) + { + // add null terminator for mbedtls PEM parser + auto pem_buf = Array!ubyte(Alloc, cert_data.length + 1); + pem_buf.ptr[0 .. cert_data.length] = cert_data[]; + pem_buf.ptr[cert_data.length] = 0; + ret = mbedtls_x509_crt_parse(cert.crt, pem_buf.ptr, pem_buf.length); + } + else + ret = mbedtls_x509_crt_parse_der(cert.crt, cert_data.ptr, cert_data.length); + + if (ret != 0) + { + urt_x509_crt_delete(cert.crt); + cert.crt = null; + return Result(cast(uint)ret); + } + + return Result.success; + } + else version (Windows) + { + if (cert_data.length == 0) + return InternalResult.invalid_parameter; + + const(ubyte)[] der = cert_data; + Array!ubyte decoded; + + if (is_pem(cast(const(char)[])cert_data)) + { + decoded = decode_pem(cast(const(char)[])cert_data); + if (decoded.length == 0) + return InternalResult.data_error; + der = decoded[]; + } + + cert.store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 0, null); + if (cert.store is null) + return getlasterror_result(); + + if (!CertAddEncodedCertificateToStore(cert.store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + der.ptr, cast(DWORD)der.length, CERT_STORE_ADD_REPLACE_EXISTING, cast(PCCERT_CONTEXT*)&cert.context)) + { + auto r = getlasterror_result(); + CertCloseStore(cert.store, 0); + cert.store = null; + return r; + } + + return Result.success; + } + else + assert(0, "PKI: not implemented for this platform"); +} + +Result associate_key(ref CertRef cert, ref KeyPair key) +{ + version (MbedTLS) + { + // no-op: mbedtls doesn't require key-to-cert binding in a system store. + // the cert and key are passed separately to mbedtls_ssl_conf_own_cert. + if (!cert.valid || !key.valid) + return InternalResult.invalid_parameter; + return Result.success; + } + else version (Windows) + { + if (!cert.valid || !key.valid) + return InternalResult.invalid_parameter; + + // already associated (e.g., by CertCreateSelfSignCertificate) + if (cert.hncrypt !is null) + return Result.success; + + // SChannel requires the private key to be a named, persisted NCrypt key. + // Ephemeral BCrypt/NCrypt keys cause SEC_E_NO_CREDENTIALS (0x8009030E). + // Strategy: BCrypt blob → NCrypt temp (for PKCS8 export) → PKCS8 re-import + // with key name → persisted key → CERT_KEY_PROV_INFO_PROP_ID so SChannel + // can locate the key by provider + name. + + NCRYPT_PROV_HANDLE hprov; + SECURITY_STATUS ss = NCryptOpenStorageProvider(&hprov, MS_KEY_STORAGE_PROVIDER.ptr, 0); + if (ss != 0) + return Result(cast(uint)ss); + + // export BCrypt key as blob + ULONG blob_size = 0; + NTSTATUS status = BCryptExportKey(key.hcng, null, BCRYPT_ECCPRIVATE_BLOB.ptr, null, 0, &blob_size, 0); + if (status != 0) + { + NCryptFreeObject(hprov); + return Result(cast(uint)status); + } + + auto blob = Array!ubyte(Alloc, blob_size); + status = BCryptExportKey(key.hcng, null, BCRYPT_ECCPRIVATE_BLOB.ptr, blob.ptr, blob_size, &blob_size, 0); + if (status != 0) + { + NCryptFreeObject(hprov); + return Result(cast(uint)status); + } + + // import BCrypt blob into NCrypt (unfinalized so we can set export policy) + NCRYPT_KEY_HANDLE htemp; + ss = NCryptImportKey(hprov, null, BCRYPT_ECCPRIVATE_BLOB.ptr, null, &htemp, blob.ptr, blob_size, NCRYPT_DO_NOT_FINALIZE_FLAG); + if (ss != 0) + { + NCryptFreeObject(hprov); + return Result(cast(uint)ss); + } + + // allow plaintext export so we can re-export as PKCS8 + DWORD export_policy = NCRYPT_ALLOW_EXPORT_FLAG | NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG; + ss = NCryptSetProperty(htemp, NCRYPT_EXPORT_POLICY_PROPERTY.ptr, cast(ubyte*)&export_policy, DWORD.sizeof, 0); + if (ss != 0) + { + NCryptFreeObject(htemp); + NCryptFreeObject(hprov); + return Result(cast(uint)ss); + } + + ss = NCryptFinalizeKey(htemp, 0); + if (ss != 0) + { + NCryptFreeObject(htemp); + NCryptFreeObject(hprov); + return Result(cast(uint)ss); + } + + // export as PKCS8 - only PKCS8 supports named key import for persistence + ULONG pkcs8_size = 0; + ss = NCryptExportKey(htemp, null, NCRYPT_PKCS8_PRIVATE_KEY_BLOB.ptr, null, null, 0, &pkcs8_size, 0); + if (ss != 0) + { + NCryptFreeObject(htemp); + NCryptFreeObject(hprov); + return Result(cast(uint)ss); + } + + auto pkcs8 = Array!ubyte(Alloc, pkcs8_size); + ss = NCryptExportKey(htemp, null, NCRYPT_PKCS8_PRIVATE_KEY_BLOB.ptr, null, pkcs8.ptr, pkcs8_size, &pkcs8_size, 0); + NCryptFreeObject(htemp); + if (ss != 0) + { + NCryptFreeObject(hprov); + return Result(cast(uint)ss); + } + + // re-import PKCS8 with key name to create a persisted key + wchar[48] name_buf = void; + size_t name_len = generate_key_name(name_buf[]); + + NCryptBuffer nbuf; + nbuf.cbBuffer = cast(uint)((name_len + 1) * 2); // include null terminator, in bytes + nbuf.BufferType = NCRYPTBUFFER_PKCS_KEY_NAME; + nbuf.pvBuffer = cast(void*)name_buf.ptr; + + NCryptBufferDesc params; + params.ulVersion = 0; // NCRYPTBUFFER_VERSION + params.cBuffers = 1; + params.pBuffers = &nbuf; + + NCRYPT_KEY_HANDLE hkey; + ss = NCryptImportKey(hprov, null, NCRYPT_PKCS8_PRIVATE_KEY_BLOB.ptr, ¶ms, &hkey, pkcs8.ptr, pkcs8_size, NCRYPT_OVERWRITE_KEY_FLAG); + NCryptFreeObject(hprov); + if (ss != 0) + return Result(cast(uint)ss); + + // clean up any previously associated NCrypt key + if (cert.hncrypt !is null) + NCryptDeleteKey(cert.hncrypt, 0); + cert.hncrypt = hkey; + + // tell SChannel where to find the key: provider name + key name (CNG mode) + CRYPT_KEY_PROV_INFO prov_info; + prov_info.pwszContainerName = name_buf.ptr; + prov_info.pwszProvName = cast(wchar*)MS_KEY_STORAGE_PROVIDER.ptr; + prov_info.dwProvType = 0; // CNG key storage provider + prov_info.dwFlags = 0; + prov_info.cProvParam = 0; + prov_info.rgProvParam = null; + prov_info.dwKeySpec = 0; + + if (!CertSetCertificateContextProperty(cert.context, CERT_KEY_PROV_INFO_PROP_ID, 0, &prov_info)) + { + auto r = getlasterror_result(); + NCryptDeleteKey(cert.hncrypt, 0); + cert.hncrypt = null; + return r; + } + + return Result.success; + } + else + assert(0, "PKI: not implemented for this platform"); +} + +void free_cert(ref CertRef cert) +{ + version (MbedTLS) + { + if (cert.crt !is null) + urt_x509_crt_delete(cert.crt); + cert.crt = null; + } + else version (Windows) + { + if (cert.hncrypt !is null) + NCryptDeleteKey(cert.hncrypt, 0); + if (cert.context !is null) + CertFreeCertificateContext(cert.context); + if (cert.store !is null) + CertCloseStore(cert.store, 0); + cert.hncrypt = null; + cert.context = null; + cert.store = null; + } +} + +SysTime cert_expiry(ref const CertRef cert) +{ + version (MbedTLS) + { + // TODO: parse cert.crt.valid_to (mbedtls_x509_time) and convert to SysTime + return SysTime(); + } + else version (Windows) + { + if (cert.context is null || cert.context.pCertInfo is null) + return SysTime(); + return SysTime(*cast(ulong*)&cert.context.pCertInfo.NotAfter); + } + else + return SysTime(); +} + +inout(void)* native_cert_context(ref inout CertRef cert) +{ + version (MbedTLS) + return cast(inout(void)*)cert.crt; + else version (Windows) + return cast(inout(void)*)cert.context; + else + return null; +} + + +Result sign_hash(ref KeyPair kp, const(ubyte)[] hash, out Array!ubyte signature) +{ + version (MbedTLS) + { + if (!kp.valid) + return InternalResult.invalid_parameter; + + // mbedtls_pk_sign produces DER-encoded ECDSA signature. + // we need raw R||S format (64 bytes for P-256) to match the Windows contract. + ubyte[256] sig_buf = void; + size_t sig_len = 0; + int ret = urt_pk_sign(&kp.pk, + hash.ptr, hash.length, sig_buf.ptr, sig_buf.length, &sig_len); + if (ret != 0) + return Result(cast(uint)ret); + + // parse DER SEQUENCE { INTEGER r, INTEGER s } → raw R||S (32 bytes each) + signature = Array!ubyte(Alloc, 64); + if (!der_sig_to_raw(sig_buf[0 .. sig_len], signature.ptr[0 .. 64])) + { + signature = Array!ubyte(); + return InternalResult.data_error; + } + + return Result.success; + } + else version (Windows) + { + if (kp.hcng is null) + return InternalResult.invalid_parameter; + + ULONG sig_size = 0; + NTSTATUS status = BCryptSignHash(kp.hcng, null, cast(PUCHAR)hash.ptr, cast(ULONG)hash.length, null, 0, &sig_size, 0); + if (status != 0) + return Result(cast(uint)status); + + signature = Array!ubyte(Alloc, sig_size); + status = BCryptSignHash(kp.hcng, null, cast(PUCHAR)hash.ptr, cast(ULONG)hash.length, signature.ptr, sig_size, &sig_size, 0); + if (status != 0) + { + signature = Array!ubyte(); + return Result(cast(uint)status); + } + + signature.resize(sig_size); + return Result.success; + } + else + assert(0, "PKI: not implemented for this platform"); +} + +Result export_public_key_raw(ref KeyPair kp, out Array!ubyte x, out Array!ubyte y) +{ + version (MbedTLS) + { + if (!kp.valid) + return InternalResult.invalid_parameter; + + // export uncompressed point: 0x04 || X || Y + ubyte[65] pt_buf = void; // 1 + 32 + 32 for P-256 + size_t olen = 0; + int ret = urt_pk_export_pubkey_xy(&kp.pk, pt_buf.ptr, pt_buf.length, &olen); + if (ret != 0) + return Result(cast(uint)ret); + + if (olen != 65) // 0x04 + 32 + 32 + return InternalResult.data_error; + + x = Array!ubyte(Alloc, 32); + y = Array!ubyte(Alloc, 32); + x.ptr[0 .. 32] = pt_buf[1 .. 33]; + y.ptr[0 .. 32] = pt_buf[33 .. 65]; + return Result.success; + } + else version (Windows) + { + if (kp.hcng is null) + return InternalResult.invalid_parameter; + + ULONG blob_size = 0; + NTSTATUS status = BCryptExportKey(kp.hcng, null, BCRYPT_ECCPUBLIC_BLOB.ptr, null, 0, &blob_size, 0); + if (status != 0) + return Result(cast(uint)status); + + auto blob = Array!ubyte(Alloc, blob_size); + status = BCryptExportKey(kp.hcng, null, BCRYPT_ECCPUBLIC_BLOB.ptr, blob.ptr, blob_size, &blob_size, 0); + if (status != 0) + return Result(cast(uint)status); + + if (blob_size < 8) + return InternalResult.data_error; + + auto hdr = cast(BCRYPT_ECCKEY_BLOB*)blob.ptr; + ULONG key_len = hdr.cbKey; + if (blob_size < 8 + 2 * key_len) + return InternalResult.data_error; + + x = blob[8 .. 8 + key_len]; + y = blob[8 + key_len .. 8 + 2 * key_len]; + return Result.success; + } + else + assert(0, "PKI: not implemented for this platform"); +} + + +Array!ubyte generate_csr(ref KeyPair kp, const(char)[] cn) +{ + if (!kp.valid) + return Array!ubyte(); + + Array!ubyte pub_x, pub_y; + if (!export_public_key_raw(kp, pub_x, pub_y)) + return Array!ubyte(); + + // compute CertificationRequestInfo field sizes + ptrdiff_t ver = der_integer_small(null, 0); + ptrdiff_t subject = der_name_cn(null, cn); + ptrdiff_t pubkey = der_ec_pubkey_info(null, pub_x[], pub_y[]); + ptrdiff_t attrs = der_header(null, 0xa0, 0); // empty attributes [0] + size_t info_content = ver + subject + pubkey + attrs; + size_t info_total = der_header(null, 0x30, info_content) + info_content; + + // write CertificationRequestInfo + ubyte[512] info_buf = void; + size_t pos = 0; + pos += der_header(info_buf[pos .. $], 0x30, info_content); + pos += der_integer_small(info_buf[pos .. $], 0); + pos += der_name_cn(info_buf[pos .. $], cn); + pos += der_ec_pubkey_info(info_buf[pos .. $], pub_x[], pub_y[]); + pos += der_header(info_buf[pos .. $], 0xa0, 0); + + // hash and sign + SHA256Context sha; + sha_init(sha); + sha_update(sha, info_buf[0 .. info_total]); + ubyte[32] hash = sha_finalise(sha); + + Array!ubyte sig; + if (!sign_hash(kp, hash[], sig)) + return Array!ubyte(); + + // CertificationRequest: SEQUENCE { info, sigAlgId, BIT STRING { ecdsa_sig } } + ptrdiff_t sig_alg_size = der_sig_alg(null); + ptrdiff_t sig_der = der_ecdsa_sig(null, sig[]); + size_t bs_content = 1 + sig_der; + size_t csr_content = info_total + sig_alg_size + 1 + der_length_size(bs_content) + bs_content; + size_t csr_total = der_header(null, 0x30, csr_content) + csr_content; + + auto csr = Array!ubyte(Alloc, csr_total); + pos = 0; + pos += der_header(csr[pos .. $], 0x30, csr_content); + csr.ptr[pos .. pos + info_total] = info_buf[0 .. info_total]; + pos += info_total; + pos += der_sig_alg(csr[pos .. $]); + pos += der_header(csr[pos .. $], 0x03, bs_content); + csr.ptr[pos++] = 0x00; + pos += der_ecdsa_sig(csr[pos .. $], sig[]); + + return csr; +} + + +Result export_private_key(ref KeyPair kp, out Array!ubyte key_out) +{ + version (MbedTLS) + { + if (!kp.valid) + return InternalResult.invalid_parameter; + + // Extract raw d, X, Y from mbedtls pk context + ubyte[32] d = void; + ubyte[65] xy_buf = void; + size_t d_len = 0, xy_len = 0; + + int ret = urt_pk_export_privkey_d(&kp.pk, d.ptr, d.length, &d_len); + if (ret != 0) + return Result(cast(uint)ret); + + ret = urt_pk_export_pubkey_xy(&kp.pk, xy_buf.ptr, xy_buf.length, &xy_len); + if (ret != 0) + return Result(cast(uint)ret); + + // xy_buf is 0x04 || X[32] || Y[32] + return build_ec_sec1_der(d, xy_buf[1 .. 33], xy_buf[33 .. 65], key_out); + } + else version (Windows) + { + if (kp.hcng is null) + return InternalResult.invalid_parameter; + + // Export BCrypt blob: BCRYPT_ECCKEY_BLOB { magic, cbKey=32 } X[32] Y[32] d[32] + ULONG blob_size = 0; + NTSTATUS status = BCryptExportKey(kp.hcng, null, BCRYPT_ECCPRIVATE_BLOB.ptr, null, 0, &blob_size, 0); + if (status != 0) + return Result(cast(uint)status); + + auto blob = Array!ubyte(Alloc, blob_size); + status = BCryptExportKey(kp.hcng, null, BCRYPT_ECCPRIVATE_BLOB.ptr, blob.ptr, blob_size, &blob_size, 0); + if (status != 0) + return Result(cast(uint)status); + + if (blob_size < 8 + 32 * 3) + return InternalResult.data_error; + + // Build SEC 1 ECPrivateKey DER from the BCrypt blob components + return build_ec_sec1_der(blob[72 .. 104][0..32], blob[8 .. 40][0..32], blob[40 .. 72][0..32], key_out); + } + else + assert(0, "PKI: not implemented for this platform"); +} + +Result import_private_key(const(ubyte)[] key_data, out KeyPair kp) +{ + version (MbedTLS) + { + const(ubyte)[] der = key_data; + Array!ubyte decoded; + + if (is_pem(cast(const(char)[])key_data)) + { + decoded = decode_pem(cast(const(char)[])key_data); + if (decoded.length == 0) + return InternalResult.data_error; + der = decoded[]; + } + + ubyte[32] d = void, x = void, y = void; + if (!parse_ec_sec1_der(der, d, x, y)) + return InternalResult.data_error; + + // Build uncompressed point: 0x04 || X || Y + ubyte[65] xy = void; + xy[0] = 0x04; + xy[1 .. 33] = x[]; + xy[33 .. 65] = y[]; + + mbedtls_pk_init(&kp.pk); + int ret = urt_pk_import_ec_p256_key(&kp.pk, d.ptr, d.length, xy.ptr, xy.length); + if (ret != 0) + { + mbedtls_pk_free(&kp.pk); + kp.pk = mbedtls_pk_context.init; + return Result(cast(uint)ret); + } + + return Result.success; + } + else version (Windows) + { + const(ubyte)[] der = key_data; + Array!ubyte decoded; + + if (is_pem(cast(const(char)[])key_data)) + { + decoded = decode_pem(cast(const(char)[])key_data); + if (decoded.length == 0) + return InternalResult.data_error; + der = decoded[]; + } + + ubyte[32] d = void, x = void, y = void; + if (!parse_ec_sec1_der(der, d, x, y)) + return InternalResult.data_error; + + // Build BCRYPT_ECCKEY_BLOB: { magic(4), cbKey(4)=32 } X[32] Y[32] d[32] + ubyte[104] blob = void; + (cast(uint[])blob[0 .. 8])[0] = 0x34534345; // BCRYPT_ECDSA_PRIVATE_P256_MAGIC + (cast(uint[])blob[0 .. 8])[1] = 32; // cbKey + blob[8 .. 40] = x[]; + blob[40 .. 72] = y[]; + blob[72 .. 104] = d[]; + + NTSTATUS status = BCryptOpenAlgorithmProvider(&kp.halg, BCRYPT_ECDSA_P256_ALGORITHM.ptr, null, 0); + if (status == 0) + { + status = BCryptImportKeyPair(kp.halg, null, BCRYPT_ECCPRIVATE_BLOB.ptr, &kp.hcng, blob.ptr, 104, 0); + if (status == 0) + return Result.success; + BCryptCloseAlgorithmProvider(kp.halg, 0); + kp.halg = null; + } + return Result(cast(uint)status); + } + else + assert(0, "PKI: not implemented for this platform"); +} + +Result export_private_scalar(ref KeyPair kp, out ubyte[32] d) +{ + Array!ubyte der; + Result r = export_private_key(kp, der); + if (r.failed) + return r; + ubyte[32] x = void, y = void; + if (!parse_ec_sec1_der(der[], d, x, y)) + return InternalResult.data_error; + return Result.success; +} + +private: + +// Build SEC 1 ECPrivateKey DER (RFC 5915) for P-256 from raw components. +// Both platforms use this format for portable key storage. +// +// ECPrivateKey ::= SEQUENCE { +// INTEGER 1, +// OCTET STRING d[32], +// [0] { OID secp256r1 }, +// [1] { BIT STRING 04 || X || Y } +// } +Result build_ec_sec1_der(ref const ubyte[32] d, ref const ubyte[32] x, ref const ubyte[32] y, out Array!ubyte key_out) +{ + // compute sizes (pass null to measure) + size_t ver_size = der_integer_small(null, 1); // INTEGER 1 + size_t d_size = der_tlv(null, 0x04, d[]); // OCTET STRING d + size_t oid_size = der_tlv(null, 0x06, oid_prime256v1[]); // OID secp256r1 + size_t params_size = der_header(null, 0xa0, oid_size) + oid_size; // [0] { OID } + + enum size_t pt_len = 1 + 32 + 32; // 04 || X || Y + enum size_t bs_content = 1 + pt_len; // unused_bits + point + size_t bs_size = der_header(null, 0x03, bs_content) + bs_content; // BIT STRING + size_t pubkey_size = der_header(null, 0xa1, bs_size) + bs_size; // [1] { BIT STRING } + + size_t content = ver_size + d_size + params_size + pubkey_size; + size_t total = der_header(null, 0x30, content) + content; // outer SEQUENCE + + key_out = Array!ubyte(Alloc, total); + ubyte[] buf = key_out[]; + size_t pos = 0; + + pos += der_header(buf[pos .. $], 0x30, content); + pos += der_integer_small(buf[pos .. $], 1); + pos += der_tlv(buf[pos .. $], 0x04, d[]); + + // [0] EXPLICIT { OID secp256r1 } + pos += der_header(buf[pos .. $], 0xa0, oid_size); + pos += der_tlv(buf[pos .. $], 0x06, oid_prime256v1[]); + + // [1] EXPLICIT { BIT STRING { 04 || X || Y } } + pos += der_header(buf[pos .. $], 0xa1, bs_size); + pos += der_header(buf[pos .. $], 0x03, bs_content); + buf[pos++] = 0x00; // unused bits + buf[pos++] = 0x04; // uncompressed point + buf[pos .. pos + 32] = x[]; + pos += 32; + buf[pos .. pos + 32] = y[]; + pos += 32; + + assert(pos == total); + return Result.success; +} + +// Parse SEC 1 ECPrivateKey DER (RFC 5915) for P-256, extracting raw d, X, Y. +bool parse_ec_sec1_der(const(ubyte)[] der, ref ubyte[32] d, ref ubyte[32] x, ref ubyte[32] y) +{ + if (der.length < 2 || der[0] != 0x30) + return false; + + size_t pos = 1; + size_t seq_len; + if (!read_der_length(der, pos, seq_len)) + return false; + if (pos + seq_len > der.length) + return false; + size_t seq_end = pos + seq_len; + + // INTEGER 1 (version) + if (pos + 3 > seq_end || der[pos] != 0x02 || der[pos + 1] != 0x01 || der[pos + 2] != 0x01) + return false; + pos += 3; + + // OCTET STRING (private key d) + if (pos >= seq_end || der[pos] != 0x04) + return false; + ++pos; + size_t d_len; + if (!read_der_length(der, pos, d_len)) + return false; + if (d_len == 0 || d_len > 32 || pos + d_len > seq_end) + return false; + d[] = 0; + d[32 - d_len .. 32] = der[pos .. pos + d_len]; // right-align + pos += d_len; + + // optional [0] parameters - skip + if (pos < seq_end && der[pos] == 0xa0) + { + ++pos; + size_t param_len; + if (!read_der_length(der, pos, param_len)) + return false; + pos += param_len; + } + + // optional [1] public key + if (pos < seq_end && der[pos] == 0xa1) + { + ++pos; + size_t ctx_len; + if (!read_der_length(der, pos, ctx_len)) + return false; + size_t ctx_end = pos + ctx_len; + // BIT STRING + if (pos >= ctx_end || der[pos] != 0x03) + return false; + ++pos; + size_t bs_len; + if (!read_der_length(der, pos, bs_len)) + return false; + // unused bits (0) + 04 + X + Y = 66 bytes + if (bs_len != 66 || pos + bs_len > ctx_end) + return false; + if (der[pos] != 0x00 || der[pos + 1] != 0x04) + return false; + x[] = der[pos + 2 .. pos + 34]; + y[] = der[pos + 34 .. pos + 66]; + return true; + } + + // No public key in the SEC 1 structure - can't reconstruct without EC math + return false; +} + +bool read_der_length(const(ubyte)[] der, ref size_t pos, out size_t len) +{ + if (pos >= der.length) + return false; + ubyte b = der[pos++]; + if (b < 0x80) + { + len = b; + return true; + } + uint n = b & 0x7f; + if (n == 0 || n > 2 || pos + n > der.length) + return false; + len = 0; + for (uint i = 0; i < n; ++i) + len = (len << 8) | der[pos++]; + return true; +} + +version (Windows) +{ + import core.sys.windows.bcrypt; + import core.sys.windows.ntdef : NTSTATUS; + import core.sys.windows.wincrypt; + import core.sys.windows.windef; + + pragma(lib, "Bcrypt"); + pragma(lib, "Crypt32"); + pragma(lib, "Ncrypt"); + + alias SECURITY_STATUS = int; + alias NCRYPT_PROV_HANDLE = void*; + alias NCRYPT_KEY_HANDLE = void*; + + enum NCRYPT_OVERWRITE_KEY_FLAG = 0x00000080; + enum NCRYPT_DO_NOT_FINALIZE_FLAG = 0x00000400; + enum NCRYPT_ALLOW_EXPORT_FLAG = 0x00000001; + enum NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG = 0x00000002; + enum DWORD CERT_KEY_PROV_INFO_PROP_ID = 2; + enum DWORD NCRYPTBUFFER_PKCS_KEY_NAME = 45; + + enum LPCSTR CERT_STORE_PROV_MEMORY = cast(LPCSTR)2; + enum DWORD CERT_STORE_ADD_REPLACE_EXISTING = 3; + + struct CERT_EXTENSIONS + { + DWORD cExtension; + PCERT_EXTENSION rgExtension; + } + + immutable wchar[] MS_KEY_STORAGE_PROVIDER = "Microsoft Software Key Storage Provider\0"w; + immutable wchar[] NCRYPT_PKCS8_PRIVATE_KEY_BLOB = "PKCS8_PRIVATEKEY\0"w; + immutable wchar[] NCRYPT_EXPORT_POLICY_PROPERTY = "Export Policy\0"w; + + + struct CRYPT_KEY_PROV_INFO + { + wchar* pwszContainerName; + wchar* pwszProvName; + DWORD dwProvType; + DWORD dwFlags; + DWORD cProvParam; + void* rgProvParam; + DWORD dwKeySpec; + } + + struct NCryptBuffer + { + ULONG cbBuffer; + ULONG BufferType; + void* pvBuffer; + } + + struct NCryptBufferDesc + { + ULONG ulVersion; + ULONG cBuffers; + NCryptBuffer* pBuffers; + } + + extern(Windows) @nogc nothrow + { + BOOL CertAddEncodedCertificateToStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, const(BYTE)* pbCertEncoded, DWORD cbCertEncoded, DWORD dwAddDisposition, PCCERT_CONTEXT* ppCertContext); + BOOL CertSetCertificateContextProperty(PCCERT_CONTEXT pCertContext, DWORD dwPropId, DWORD dwFlags, const(void)* pvData); + SECURITY_STATUS NCryptOpenStorageProvider(NCRYPT_PROV_HANDLE* phProvider, const(wchar)* pszProviderName, DWORD dwFlags); + SECURITY_STATUS NCryptImportKey(NCRYPT_PROV_HANDLE hProvider, NCRYPT_KEY_HANDLE hImportKey, const(wchar)* pszBlobType, void* pParameterList, NCRYPT_KEY_HANDLE* phKey, BYTE* pbData, DWORD cbData, DWORD dwFlags); + SECURITY_STATUS NCryptFreeObject(NCRYPT_PROV_HANDLE hObject); + SECURITY_STATUS NCryptSetProperty(NCRYPT_KEY_HANDLE hObject, const(wchar)* pszProperty, ubyte* pbInput, DWORD cbInput, DWORD dwFlags); + SECURITY_STATUS NCryptFinalizeKey(NCRYPT_KEY_HANDLE hKey, DWORD dwFlags); + SECURITY_STATUS NCryptExportKey(NCRYPT_KEY_HANDLE hKey, NCRYPT_KEY_HANDLE hExportKey, const(wchar)* pszBlobType, void* pParameterList, BYTE* pbOutput, DWORD cbOutput, DWORD* pcbResult, DWORD dwFlags); + SECURITY_STATUS NCryptCreatePersistedKey(NCRYPT_PROV_HANDLE hProvider, NCRYPT_KEY_HANDLE* phKey, const(wchar)* pszAlgId, const(wchar)* pszKeyName, DWORD dwLegacyKeySpec, DWORD dwFlags); + SECURITY_STATUS NCryptDeleteKey(NCRYPT_KEY_HANDLE hKey, DWORD dwFlags); + + PCCERT_CONTEXT CertCreateSelfSignCertificate( + NCRYPT_KEY_HANDLE hCryptProvOrNCryptKey, + CERT_NAME_BLOB* pSubjectIssuerBlob, + DWORD dwFlags, + void* pKeyProvInfo, // PCRYPT_KEY_PROV_INFO + void* pSignatureAlgorithm, // PCRYPT_ALGORITHM_IDENTIFIER + void* pStartTime, // PSYSTEMTIME + void* pEndTime, // PSYSTEMTIME + void* pExtensions // PCERT_EXTENSIONS + ); + } + + size_t generate_key_name(wchar[] buf) + { + import urt.mem.temp : tconcat; + import urt.string.uni : uni_convert; + __gshared uint counter = 0; + size_t len = uni_convert(tconcat("openwatt_key_", counter++), buf); + buf[len] = 0; + return len; + } +} + +version (MbedTLS) +{ + import urt.internal.mbedtls; + + // convert DER-encoded ECDSA signature SEQUENCE { INTEGER r, INTEGER s } + // to raw R||S format (32 bytes each for P-256) + bool der_sig_to_raw(const(ubyte)[] der, ubyte[] raw) + { + if (raw.length < 64) + return false; + + raw[0 .. 64] = 0; + + size_t pos = 0; + + // SEQUENCE + if (pos >= der.length || der[pos++] != 0x30) + return false; + if (pos >= der.length) + return false; + + // sequence length (skip) + if (der[pos] & 0x80) + pos += 1 + (der[pos] & 0x7f); + else + ++pos; + + // parse two INTEGERs into raw[0..32] and raw[32..64] + foreach (i; 0 .. 2) + { + if (pos >= der.length || der[pos++] != 0x02) + return false; + if (pos >= der.length) + return false; + + size_t len = der[pos++]; + if (pos + len > der.length) + return false; + + auto integer = der[pos .. pos + len]; + pos += len; + + // strip leading zero padding (DER INTEGERs are signed, so positive values + // with high bit set get a 0x00 prefix) + while (integer.length > 32 && integer[0] == 0) + integer = integer[1 .. $]; + + if (integer.length > 32) + return false; + + // right-align into 32-byte field + size_t offset = 32 - integer.length; + raw[i * 32 + offset .. i * 32 + offset + integer.length] = integer[]; + } + + return true; + } +} diff --git a/src/urt/crypto/random.d b/src/urt/crypto/random.d new file mode 100644 index 0000000..66a5d85 --- /dev/null +++ b/src/urt/crypto/random.d @@ -0,0 +1,55 @@ +module urt.crypto.random; + +import urt.result; + +version (Espressif) +{ + // use the hardware RNG peripheral on ESP32 +} +else version (MbedTLS) +{ + import urt.internal.mbedtls; +} +else version (Windows) +{ + import core.sys.windows.bcrypt; + import core.sys.windows.ntdef : NTSTATUS; + pragma(lib, "Bcrypt"); +} + +nothrow @nogc: + + +Result crypto_random_bytes(ubyte[] dst) +{ + if (dst.length == 0) + return Result.success; + + version (Espressif) + { + esp_fill_random(dst.ptr, dst.length); + return Result.success; + } + else version (MbedTLS) + { + int ret = urt_rng_random(dst.ptr, dst.length); + return ret == 0 ? Result.success : Result(cast(uint)ret); + } + else version (Windows) + { + NTSTATUS status = BCryptGenRandom(null, dst.ptr, cast(uint)dst.length, BCRYPT_USE_SYSTEM_PREFERRED_RNG); + return status == 0 ? Result.success : Result(cast(uint)status); + } + else + return InternalResult.unsupported; +} + + +private: + +// classic ESP32 only: esp_fill_random is cryptographically strong only while the WiFi/BT radio is active +// pre-radio callers must bracket with bootloader_random_enable/disable! +version (Espressif) +{ + extern(C) void esp_fill_random(void* buf, size_t len) nothrow @nogc; +} diff --git a/src/urt/dbg.d b/src/urt/dbg.d index 8cc13d1..d5458db 100644 --- a/src/urt/dbg.d +++ b/src/urt/dbg.d @@ -55,48 +55,38 @@ else version (ARM) } } } -else - static assert(0, "TODO: Unsupported architecture"); - - -private: - -package(urt) void setupAssertHandler() +else version (RISCV64) { - import core.exception : assertHandler; - assertHandler = &urt_assert; + pragma(inline, true) + extern(C) void breakpoint() pure nothrow @nogc + { + debug asm pure nothrow @nogc + { + "ebreak"; + } + } } - -void urt_assert(string file, size_t line, string msg) nothrow @nogc +else version (RISCV32) { - import core.stdc.stdlib : exit; - - debug + pragma(inline, true) + extern(C) void breakpoint() pure nothrow @nogc { - import core.stdc.stdio; - - if (msg.length == 0) - msg = "Assertion failed"; - - version (Windows) + debug asm pure nothrow @nogc { - import core.sys.windows.winbase; - char[1024] buffer; - _snprintf(buffer.ptr, buffer.length, "%.*s(%d): %.*s\n", cast(int)file.length, file.ptr, cast(int)line, cast(int)msg.length, msg.ptr); - OutputDebugStringA(buffer.ptr); - - // Windows can have it at stdout aswell? - printf("%.*s(%d): %.*s\n", cast(int)file.length, file.ptr, cast(int)line, cast(int)msg.length, msg.ptr); + "ebreak"; } - else + } +} +else version (Xtensa) +{ + pragma(inline, true) + extern(C) void breakpoint() pure nothrow @nogc + { + debug asm pure nothrow @nogc { - // TODO: write to stderr would be better... - printf("%.*s(%d): %.*s\n", cast(int)file.length, file.ptr, cast(int)line, cast(int)msg.length, msg.ptr); + "break 1, 15"; } - - breakpoint(); -// exit(-1); // TODO: what if some systems don't support a software breakpoint? } - else - exit(-1); } +else + static assert(0, "TODO: Unsupported architecture"); diff --git a/src/urt/digest/hmac.d b/src/urt/digest/hmac.d new file mode 100644 index 0000000..ec372a0 --- /dev/null +++ b/src/urt/digest/hmac.d @@ -0,0 +1,104 @@ +module urt.digest.hmac; + +import urt.digest.sha; + +nothrow @nogc: + + +// Templated HMAC over any digest Context that exposes DigestLen + BlockBytes +// and works with sha_init/sha_update/sha_finalise. +struct HMACContext(Context) +{ + Context inner; + ubyte[Context.BlockBytes] outer_pad; +} + + +void hmac_init(Context)(ref HMACContext!Context hctx, const(ubyte)[] key) +{ + enum block = Context.BlockBytes; + + ubyte[block] key_block = 0; + if (key.length > block) + { + // RFC 2104: keys longer than block size are hashed first + Context tmp; + sha_init(tmp); + sha_update(tmp, key); + auto digest = sha_finalise(tmp); + key_block[0 .. Context.DigestLen] = digest[]; + } + else + key_block[0 .. key.length] = key[]; + + ubyte[block] inner_pad = void; + foreach (i; 0 .. block) + { + inner_pad[i] = key_block[i] ^ 0x36; + hctx.outer_pad[i] = key_block[i] ^ 0x5c; + } + + sha_init(hctx.inner); + sha_update(hctx.inner, inner_pad[]); +} + +void hmac_update(Context)(ref HMACContext!Context hctx, const(void)[] data) +{ + sha_update(hctx.inner, data); +} + +ubyte[Context.DigestLen] hmac_finalise(Context)(ref HMACContext!Context hctx) +{ + auto inner_digest = sha_finalise(hctx.inner); + + Context outer; + sha_init(outer); + sha_update(outer, hctx.outer_pad[]); + sha_update(outer, inner_digest[]); + return sha_finalise(outer); +} + + +// One-shot convenience. +ubyte[Context.DigestLen] hmac(Context)(const(ubyte)[] key, const(void)[] msg) +{ + HMACContext!Context h; + hmac_init(h, key); + hmac_update(h, msg); + return hmac_finalise(h); +} + + +unittest +{ + // RFC 4231 test vectors for HMAC-SHA-256 + + // TC1: 20-byte key (shorter than block) + static immutable ubyte[32] tc1_expected = [ + 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, 0xaf, 0xce, + 0xaf, 0x0b, 0xf1, 0x2b, 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7, + 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7, + ]; + ubyte[20] tc1_key = 0x0b; + auto tc1 = hmac!SHA256Context(tc1_key[], "Hi There"); + assert(tc1 == tc1_expected); + + // TC2: 4-byte ASCII key + static immutable ubyte[32] tc2_expected = [ + 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e, 0x6a, 0x04, 0x24, 0x26, + 0x08, 0x95, 0x75, 0xc7, 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83, + 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43, + ]; + auto tc2 = hmac!SHA256Context(cast(const(ubyte)[])"Jefe", "what do ya want for nothing?"); + assert(tc2 == tc2_expected); + + // TC6: 131-byte key (exercises hash-the-key branch) + static immutable ubyte[32] tc6_expected = [ + 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f, 0x0d, 0x8a, 0x26, 0xaa, + 0xcb, 0xf5, 0xb7, 0x7f, 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14, + 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54, + ]; + ubyte[131] tc6_key = 0xaa; + auto tc6 = hmac!SHA256Context(tc6_key[], "Test Using Larger Than Block-Size Key - Hash Key First"); + assert(tc6 == tc6_expected); +} diff --git a/src/urt/digest/md5.d b/src/urt/digest/md5.d index ef75d98..8771adc 100644 --- a/src/urt/digest/md5.d +++ b/src/urt/digest/md5.d @@ -5,178 +5,239 @@ import urt.endian; nothrow @nogc: // pure -struct MD5Context +version (Espressif) { - ulong size; // size of input in bytes - uint[4] buffer; // current accumulation of hash - ubyte[64] input; // input to be used in the next step + struct MD5Context + { + uint[4] buf; + uint[2] bits; + ubyte[64] input; + } - enum uint[4] initState = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 ]; -} + private extern(C) nothrow @nogc + { + void MD5Init(MD5Context* ctx); + void MD5Update(MD5Context* ctx, const ubyte* buf, uint len); + void MD5Final(ubyte* digest, MD5Context* ctx); + } -void md5Init(ref MD5Context ctx) -{ - ctx.size = 0; - ctx.buffer = MD5Context.initState; -} + void md5_init(ref MD5Context ctx) + { + MD5Init(&ctx); + } -void md5Update(ref MD5Context ctx, const void[] input) -{ - size_t offset = ctx.size % 64; - ctx.size += input.length; + void md5_update(ref MD5Context ctx, const void[] data) + { + MD5Update(&ctx, cast(const ubyte*)data.ptr, cast(uint)data.length); + } - size_t i = 64 - offset; - if (input.length < i) + ubyte[16] md5_finalise(ref MD5Context ctx) + { + ubyte[16] digest; + MD5Final(digest.ptr, &ctx); + return digest; + } +} +else +{ + struct MD5Context { - ctx.input[offset .. offset + input.length] = cast(ubyte[])input[]; - return; + ulong size; // size of input in bytes + uint[4] buffer; // current accumulation of hash + ubyte[64] input; // input to be used in the next step + + enum uint[4] initState = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 ]; } - ctx.input[offset .. 64] = cast(ubyte[])input[0 .. i]; + void md5_init(ref MD5Context ctx) + { + ctx.size = 0; + ctx.buffer = MD5Context.initState; + } - while (true) + void md5_update(ref MD5Context ctx, const void[] input) { - // The local variable `tmp` our 512-bit chunk separated into 32-bit words - // we can use in calculations - uint[16] tmp = void; - foreach (uint j; 0 .. 16) - tmp[j] = loadLittleEndian(cast(uint*)ctx.input.ptr + j); - md5Step(ctx.buffer, tmp); + size_t offset = ctx.size % 64; + ctx.size += input.length; - size_t tail = input.length - i; - if (tail < 64) + size_t i = 64 - offset; + if (input.length < i) { - ctx.input[0 .. tail] = (cast(ubyte*)input.ptr)[i .. input.length]; - break; + ctx.input[offset .. offset + input.length] = cast(ubyte[])input[]; + return; + } + + ctx.input[offset .. 64] = cast(ubyte[])input[0 .. i]; + + while (true) + { + uint[16] tmp = void; + foreach (uint j; 0 .. 16) + tmp[j] = loadLittleEndian(cast(uint*)ctx.input.ptr + j); + md5_step(ctx.buffer, tmp); + + size_t tail = input.length - i; + if (tail < 64) + { + ctx.input[0 .. tail] = (cast(ubyte*)input.ptr)[i .. input.length]; + break; + } + ctx.input[] = (cast(ubyte*)input.ptr)[i .. i + 64]; + i += 64; } - ctx.input[] = (cast(ubyte*)input.ptr)[i .. i + 64]; - i += 64; } -} -ubyte[16] md5Finalise(ref MD5Context ctx) -{ - uint[16] tmp = void; - uint offset = ctx.size % 64; - uint padding_length = offset < 56 ? 56 - offset : (56 + 64) - offset; - - // padding used to make the size (in bits) of the input congruent to 448 mod 512 - // TODO: on a large memory system, let's make this a global immutable? - ubyte[64] PADDING = void; - PADDING[0] = 0x80; - PADDING[1 .. padding_length] = 0; - - // Fill in the padding and undo the changes to size that resulted from the update - md5Update(ctx, PADDING[0 .. padding_length]); - ctx.size -= cast(ulong)padding_length; - - // Do a final update (internal to this function) - // Last two 32-bit words are the two halves of the size (converted from bytes to bits) - foreach (uint j; 0 .. 14) - tmp[j] = loadLittleEndian(cast(uint*)ctx.input.ptr + j); - - tmp[14] = cast(uint)(ctx.size*8); - tmp[15] = (ctx.size*8) >> 32; - - md5Step(ctx.buffer, tmp); - - uint[4] digest = void; - foreach (uint k; 0 .. 4) - storeLittleEndian(digest.ptr + k, ctx.buffer.ptr[k]); - return cast(ubyte[16])digest; -} + ubyte[16] md5_finalise(ref MD5Context ctx) + { + uint[16] tmp = void; + uint offset = ctx.size % 64; + uint padding_length = offset < 56 ? 56 - offset : (56 + 64) - offset; -unittest -{ - import urt.encoding; + ubyte[64] PADDING = void; + PADDING[0] = 0x80; + PADDING[1 .. padding_length] = 0; - MD5Context ctx; - md5Init(ctx); - auto digest = md5Finalise(ctx); - assert(digest == Hex!"d41d8cd98f00b204e9800998ecf8427e"); - - md5Init(ctx); - md5Update(ctx, "Hello, World!"); - digest = md5Finalise(ctx); - assert(digest == Hex!"65a8e27d8879283831b664bd8b7f0ad4"); -} + md5_update(ctx, PADDING[0 .. padding_length]); + ctx.size -= cast(ulong)padding_length; + foreach (uint j; 0 .. 14) + tmp[j] = loadLittleEndian(cast(uint*)ctx.input.ptr + j); -private: + tmp[14] = cast(uint)(ctx.size*8); + tmp[15] = (ctx.size*8) >> 32; -__gshared immutable ubyte[] S = [ - 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, - 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, - 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, - 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 -]; - -__gshared immutable uint[] K = [ - 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, - 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, - 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, - 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, - 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, - 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, - 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, - 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, - 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, - 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, - 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, - 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, - 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, - 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, - 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, - 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 -]; - -// rotates a 32-bit word left by n bits -uint rotateLeft(uint x, uint n) - => (x << n) | (x >> (32 - n)); - -// step on 512 bits of input with the main MD5 algorithm -void md5Step(ref uint[4] buffer, ref const uint[16] input) -{ - uint AA = buffer[0]; - uint BB = buffer[1]; - uint CC = buffer[2]; - uint DD = buffer[3]; + md5_step(ctx.buffer, tmp); + + uint[4] digest = void; + foreach (uint k; 0 .. 4) + storeLittleEndian(digest.ptr + k, ctx.buffer.ptr[k]); + return cast(ubyte[16])digest; + } - uint E; - uint j; +private: - foreach (uint i; 0 .. 64) + __gshared immutable ubyte[] S = [ + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 + ]; + + __gshared immutable uint[] K = [ + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + ]; + + // rotates a 32-bit word left by n bits + uint rotate_left(uint x, uint n) + => (x << n) | (x >> (32 - n)); + + // step on 512 bits of input with the main MD5 algorithm + void md5_step(ref uint[4] buffer, ref const uint[16] input) { - final switch(i / 16) + uint AA = buffer[0]; + uint BB = buffer[1]; + uint CC = buffer[2]; + uint DD = buffer[3]; + + uint E; + + uint j; + + foreach (uint i; 0 .. 64) { - case 0: - E = ((BB & CC) | (~BB & DD)); // F(BB, CC, DD); uint F(uint X, uint Y, uint Z) => ((X & Y) | (~X & Z)); - j = i; - break; - case 1: - E = ((BB & DD) | (CC & ~DD)); // G(BB, CC, DD); uint G(uint X, uint Y, uint Z) => ((X & Z) | (Y & ~Z)); - j = ((i*5) + 1) % 16; - break; - case 2: - E = (BB ^ CC ^ DD); // H(BB, CC, DD); uint H(uint X, uint Y, uint Z) => (X ^ Y ^ Z); - j = ((i*3) + 5) % 16; - break; - case 3: - E = (CC ^ (BB | ~DD)); // I(BB, CC, DD); uint I(uint X, uint Y, uint Z) => (Y ^ (X | ~Z)); - j = (i*7) % 16; - break; + final switch(i / 16) + { + case 0: + E = ((BB & CC) | (~BB & DD)); // F(BB, CC, DD); uint F(uint X, uint Y, uint Z) => ((X & Y) | (~X & Z)); + j = i; + break; + case 1: + E = ((BB & DD) | (CC & ~DD)); // G(BB, CC, DD); uint G(uint X, uint Y, uint Z) => ((X & Z) | (Y & ~Z)); + j = ((i*5) + 1) % 16; + break; + case 2: + E = (BB ^ CC ^ DD); // H(BB, CC, DD); uint H(uint X, uint Y, uint Z) => (X ^ Y ^ Z); + j = ((i*3) + 5) % 16; + break; + case 3: + E = (CC ^ (BB | ~DD)); // I(BB, CC, DD); uint I(uint X, uint Y, uint Z) => (Y ^ (X | ~Z)); + j = (i*7) % 16; + break; + } + + uint temp = DD; + DD = CC; + CC = BB; + BB = BB + rotate_left(AA + E + K[i] + input[j], S[i]); + AA = temp; } - uint temp = DD; - DD = CC; - CC = BB; - BB = BB + rotateLeft(AA + E + K[i] + input[j], S[i]); - AA = temp; + buffer[0] += AA; + buffer[1] += BB; + buffer[2] += CC; + buffer[3] += DD; } +} + +unittest +{ + import urt.encoding; + + MD5Context ctx; - buffer[0] += AA; - buffer[1] += BB; - buffer[2] += CC; - buffer[3] += DD; + // empty + md5_init(ctx); + auto digest = md5_finalise(ctx); + assert(digest == HexDecode!"d41d8cd98f00b204e9800998ecf8427e"); + + // single string + md5_init(ctx); + md5_update(ctx, "Hello, World!"); + digest = md5_finalise(ctx); + assert(digest == HexDecode!"65a8e27d8879283831b664bd8b7f0ad4"); + + // RFC 1321 test vectors + md5_init(ctx); + md5_update(ctx, "a"); + digest = md5_finalise(ctx); + assert(digest == HexDecode!"0cc175b9c0f1b6a831c399e269772661"); + + md5_init(ctx); + md5_update(ctx, "abc"); + digest = md5_finalise(ctx); + assert(digest == HexDecode!"900150983cd24fb0d6963f7d28e17f72"); + + md5_init(ctx); + md5_update(ctx, "message digest"); + digest = md5_finalise(ctx); + assert(digest == HexDecode!"f96b697d7cb7938d525a2f31aaf161d0"); + + // progressive: split across multiple updates + md5_init(ctx); + md5_update(ctx, "Hello, "); + md5_update(ctx, "World!"); + digest = md5_finalise(ctx); + assert(digest == HexDecode!"65a8e27d8879283831b664bd8b7f0ad4"); + + // data spanning multiple 64-byte blocks + md5_init(ctx); + md5_update(ctx, "12345678901234567890123456789012345678901234567890123456789012345678901234567890"); + digest = md5_finalise(ctx); + assert(digest == HexDecode!"57edf4a22be3c955ac49da2e2107b67a"); } diff --git a/src/urt/digest/sha.d b/src/urt/digest/sha.d index 196c835..9414178 100644 --- a/src/urt/digest/sha.d +++ b/src/urt/digest/sha.d @@ -2,147 +2,339 @@ module urt.digest.sha; import urt.endian; +version (Espressif) +{ + version (ESP32) {} else + version = Espressif_Modern; +} + nothrow @nogc: // pure struct SHA1Context { enum DigestBits = 160; + enum DigestLen = DigestBits / 8; + enum BlockBytes = 64; + + version (Espressif) + private SHA_CTX ctx; + else + { + enum DigestElements = DigestBits / 32; + + ubyte[64] data; + ulong bitlen; + uint datalen; + uint[DigestElements] state; + + alias transform = sha1_transform; + + enum uint[DigestElements] initState = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ]; + + __gshared immutable uint[4] K = [ 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 ]; + } +} +struct SHA224Context +{ + enum DigestBits = 224; enum DigestLen = DigestBits / 8; - enum DigestElements = DigestBits / 32; + enum BlockBytes = 64; - ubyte[64] data; - ulong bitlen; - uint datalen; - uint[DigestElements] state; + // TODO: ESP32 hardware SHA-224 should be possible by writing the SHA-224 IV to SHA_TEXT_BASE, + // triggering SHA_256_LOAD_REG, then running as SHA2_256 with truncated output. + version (Espressif_Modern) + private SHA_CTX ctx; + else + { + enum DigestElements = DigestBits / 32; + enum StateElements = 256 / 32; - alias transform = sha1Transform; + ubyte[64] data; + ulong bitlen; + uint datalen; + uint[StateElements] state; - enum uint[DigestElements] initState = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ]; + alias transform = sha256_transform; - __gshared immutable uint[4] K = [ 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 ]; + enum uint[StateElements] initState = [ 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, + 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ]; + } } struct SHA256Context { enum DigestBits = 256; - enum DigestLen = DigestBits / 8; - enum DigestElements = DigestBits / 32; - - ubyte[64] data; - ulong bitlen; - uint datalen; - uint[DigestElements] state; - - alias transform = sha256Transform; - - enum uint[DigestElements] initState = [ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, - 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ]; - - __gshared immutable uint[64] K = [ - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 - ]; -} + enum BlockBytes = 64; + version (Espressif) + private SHA_CTX ctx; + else + { + enum DigestElements = DigestBits / 32; + enum StateElements = DigestBits / 32; -void shaInit(Context)(ref Context ctx) -{ - ctx.datalen = 0; - ctx.bitlen = 0; - ctx.state = Context.initState; + ubyte[64] data; + ulong bitlen; + uint datalen; + uint[StateElements] state; + + alias transform = sha256_transform; + + enum uint[StateElements] initState = [ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ]; + } + version (Espressif_Modern) {} else { + __gshared immutable uint[64] K = [ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 + ]; + } } -void shaUpdate(Context)(ref Context ctx, const void[] input) +void sha_init(Context)(ref Context ctx) { - const(ubyte)[] data = cast(ubyte[])input; - - while (data.length > 0) + static if (esp_hardware!Context) { - if (ctx.datalen + data.length < 64) + version (ESP32) { - ctx.data[ctx.datalen .. ctx.datalen + data.length] = data[]; - ctx.datalen += cast(uint)data.length; - break; + ets_sha_enable(); + ets_sha_init(&ctx.ctx); } - - ctx.data[ctx.datalen .. 64] = data[0 .. 64 - ctx.datalen]; - data = data[64 - ctx.datalen .. $]; - ctx.bitlen += 512; + else + { + ets_sha_enable(); + static if (is(Context == SHA1Context)) + ets_sha_init(&ctx.ctx, SHA_TYPE.SHA1); + else static if (is(Context == SHA224Context)) + ets_sha_init(&ctx.ctx, SHA_TYPE.SHA2_224); + else + ets_sha_init(&ctx.ctx, SHA_TYPE.SHA2_256); + ets_sha_starts(&ctx.ctx, 0); + } + } + else + { ctx.datalen = 0; - Context.transform(ctx, ctx.data); + ctx.bitlen = 0; + ctx.state = Context.initState; } } -ubyte[Context.DigestLen] shaFinalise(Context)(ref Context ctx) +void sha_update(Context)(ref Context ctx, const void[] input) { - uint i = ctx.datalen; + static if (esp_hardware!Context) + { + version (ESP32) + { + static if (is(Context == SHA1Context)) + enum sha_type = SHA_TYPE.SHA1; + else + enum sha_type = SHA_TYPE.SHA2_256; + ets_sha_update(&ctx.ctx, sha_type, cast(const ubyte*)input.ptr, input.length * 8); + } + else + ets_sha_update(&ctx.ctx, cast(const ubyte*)input.ptr, cast(uint)input.length, true); + } + else + { + const(ubyte)[] data = cast(ubyte[])input; + + while (data.length > 0) + { + if (ctx.datalen + data.length < 64) + { + ctx.data[ctx.datalen .. ctx.datalen + data.length] = data[]; + ctx.datalen += cast(uint)data.length; + break; + } + + ctx.data[ctx.datalen .. 64] = data[0 .. 64 - ctx.datalen]; + data = data[64 - ctx.datalen .. $]; + ctx.bitlen += 512; + ctx.datalen = 0; + Context.transform(ctx, ctx.data); + } + } +} - // Pad whatever data is left in the buffer. - ctx.data[i++] = 0x80; - if (ctx.datalen > 56) +ubyte[Context.DigestLen] sha_finalise(Context)(ref Context ctx) +{ + static if (esp_hardware!Context) { - ctx.data[i .. 64] = 0x00; - Context.transform(ctx, ctx.data); - i = 0; + version (ESP32) + { + static if (is(Context == SHA1Context)) + enum sha_type = SHA_TYPE.SHA1; + else + enum sha_type = SHA_TYPE.SHA2_256; + ubyte[Context.DigestLen] digest; + ets_sha_finish(&ctx.ctx, sha_type, digest.ptr); + ets_sha_disable(); + return digest; + } + else + { + ubyte[Context.DigestLen] digest; + ets_sha_finish(&ctx.ctx, digest.ptr); + ets_sha_disable(); + return digest; + } } - ctx.data[i .. 56] = 0x00; + else + { + uint i = ctx.datalen; + + ctx.data[i++] = 0x80; + if (ctx.datalen >= 56) + { + ctx.data[i .. 64] = 0x00; + Context.transform(ctx, ctx.data); + i = 0; + } + ctx.data[i .. 56] = 0x00; - // Append to the padding the total message's length in bits and transform. - ctx.bitlen += ctx.datalen * 8; - ctx.data[56..64] = ctx.bitlen.nativeToBigEndian; - Context.transform(ctx, ctx.data); + ctx.bitlen += ctx.datalen * 8; + ctx.data[56..64] = ctx.bitlen.nativeToBigEndian; + Context.transform(ctx, ctx.data); - // Since this implementation uses little endian byte ordering and SHA uses big endian, - // reverse all the bytes when copying the final state to the output hash. - uint[Context.DigestElements] digest = void; - foreach (uint j; 0 .. Context.DigestElements) - digest[j] = byteReverse(ctx.state[j]); + uint[Context.DigestElements] digest = void; + foreach (uint j; 0 .. Context.DigestElements) + digest[j] = byte_reverse(ctx.state[j]); - return cast(ubyte[Context.DigestLen])digest; + return cast(ubyte[Context.DigestLen])digest; + } } unittest { import urt.encoding; + // SHA-1 SHA1Context ctx; - shaInit(ctx); - auto digest = shaFinalise(ctx); - assert(digest == Hex!"da39a3ee5e6b4b0d3255bfef95601890afd80709"); - - shaInit(ctx); - shaUpdate(ctx, "Hello, World!"); - digest = shaFinalise(ctx); - assert(digest == Hex!"0a0a9f2a6772942557ab5355d76af442f8f65e01"); + // empty + sha_init(ctx); + auto digest = sha_finalise(ctx); + assert(digest == HexDecode!"da39a3ee5e6b4b0d3255bfef95601890afd80709"); + + // single string + sha_init(ctx); + sha_update(ctx, "Hello, World!"); + digest = sha_finalise(ctx); + assert(digest == HexDecode!"0a0a9f2a6772942557ab5355d76af442f8f65e01"); + + // FIPS 180 test vectors + sha_init(ctx); + sha_update(ctx, "abc"); + digest = sha_finalise(ctx); + assert(digest == HexDecode!"a9993e364706816aba3e25717850c26c9cd0d89d"); + + // progressive + sha_init(ctx); + sha_update(ctx, "Hello, "); + sha_update(ctx, "World!"); + digest = sha_finalise(ctx); + assert(digest == HexDecode!"0a0a9f2a6772942557ab5355d76af442f8f65e01"); + + // multi-block (>64 bytes) + sha_init(ctx); + sha_update(ctx, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"); + digest = sha_finalise(ctx); + assert(digest == HexDecode!"84983e441c3bd26ebaae4aa1f95129e5e54670f1"); + + // SHA-224 + SHA224Context ctx3; + + // empty + sha_init(ctx3); + auto digest3 = sha_finalise(ctx3); + assert(digest3 == HexDecode!"d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f"); + + // FIPS 180 test vector + sha_init(ctx3); + sha_update(ctx3, "abc"); + digest3 = sha_finalise(ctx3); + assert(digest3 == HexDecode!"23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7"); + + // progressive + sha_init(ctx3); + sha_update(ctx3, "Hello, "); + sha_update(ctx3, "World!"); + auto digest3b = sha_finalise(ctx3); + sha_init(ctx3); + sha_update(ctx3, "Hello, World!"); + digest3 = sha_finalise(ctx3); + assert(digest3 == digest3b); + + // multi-block + sha_init(ctx3); + sha_update(ctx3, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"); + digest3 = sha_finalise(ctx3); + assert(digest3 == HexDecode!"75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525"); + + // SHA-256 SHA256Context ctx2; - shaInit(ctx2); - auto digest2 = shaFinalise(ctx2); - assert(digest2 == Hex!"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); - - shaInit(ctx2); - shaUpdate(ctx2, "Hello, World!"); - digest2 = shaFinalise(ctx2); - assert(digest2 == Hex!"dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f"); + + // empty + sha_init(ctx2); + auto digest2 = sha_finalise(ctx2); + assert(digest2 == HexDecode!"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); + + // single string + sha_init(ctx2); + sha_update(ctx2, "Hello, World!"); + digest2 = sha_finalise(ctx2); + assert(digest2 == HexDecode!"dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f"); + + // FIPS 180 test vectors + sha_init(ctx2); + sha_update(ctx2, "abc"); + digest2 = sha_finalise(ctx2); + assert(digest2 == HexDecode!"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); + + // progressive + sha_init(ctx2); + sha_update(ctx2, "Hello, "); + sha_update(ctx2, "World!"); + digest2 = sha_finalise(ctx2); + assert(digest2 == HexDecode!"dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f"); + + // multi-block + sha_init(ctx2); + sha_update(ctx2, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"); + digest2 = sha_finalise(ctx2); + assert(digest2 == HexDecode!"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"); } private: -uint ROTLEFT(uint a, uint b) => (a << b) | (a >> (32 - b)); -uint ROTRIGHT(uint a, uint b) => (a >> b) | (a << (32 - b)); +template esp_hardware(Context) +{ + version (Espressif_Modern) + enum esp_hardware = true; + else version (Espressif) + // SHA-224 hardware on ESP32 Classic would need SHA-256 with custom IV + // (see TODO on SHA224Context); fall through to software for now. + enum esp_hardware = !is(Context == SHA224Context); + else + enum esp_hardware = false; +} -void sha1Transform(ref SHA1Context ctx, const ubyte[] data) +version (Espressif) {} else +void sha1_transform(Context)(ref Context ctx, const ubyte[] data) { + static uint ROTLEFT(uint a, uint b) => (a << b) | (a >> (32 - b)); + uint a, b, c, d, e, i, j, t; uint[80] m = void; @@ -204,8 +396,11 @@ void sha1Transform(ref SHA1Context ctx, const ubyte[] data) ctx.state[4] += e; } -void sha256Transform(ref SHA256Context ctx, const ubyte[] data) +version (Espressif_Modern) {} else +void sha256_transform(Context)(ref Context ctx, const ubyte[] data) { + static uint ROTRIGHT(uint a, uint b) => (a >> b) | (a << (32 - b)); + static uint CH(uint x, uint y, uint z) => (x & y) ^ (~x & z); static uint MAJ(uint x, uint y, uint z) => (x & y) ^ (x & z) ^ (y & z); static uint EP0(uint x) => ROTRIGHT(x, 2) ^ ROTRIGHT(x, 13) ^ ROTRIGHT(x, 22); @@ -253,3 +448,56 @@ void sha256Transform(ref SHA256Context ctx, const ubyte[] data) ctx.state[6] += g; ctx.state[7] += h; } + + +// ESP32 (original) has a different ROM API from all later chips: +// - ets_sha_init takes no type; type passed to update/finish instead +// - ets_sha_update size is in bits, not bytes; no ets_sha_starts +// - smaller SHA_CTX struct +// - no SHA224 in ROM (only SHA1=0, SHA2_256=1) +version (Espressif): + +private extern(C) nothrow @nogc +{ + void ets_sha_enable(); + void ets_sha_disable(); + + version (Espressif_Modern) + { + int ets_sha_init(SHA_CTX* ctx, SHA_TYPE type); + int ets_sha_starts(SHA_CTX* ctx, ushort sha512_t); + void ets_sha_update(SHA_CTX* ctx, const ubyte* input, uint input_bytes, bool update_ctx); + int ets_sha_finish(SHA_CTX* ctx, ubyte* output); + } + else + { + void ets_sha_init(SHA_CTX* ctx); + void ets_sha_update(SHA_CTX* ctx, SHA_TYPE type, const ubyte* input, size_t input_bits); + void ets_sha_finish(SHA_CTX* ctx, SHA_TYPE type, ubyte* output); + } +} + +version (Espressif_Modern) +{ + private enum SHA_TYPE : int { SHA1 = 0, SHA2_224, SHA2_256 } + + private struct SHA_CTX + { + bool start; + bool in_hardware; + SHA_TYPE type; + uint[16] state; + ubyte[128] buffer; + uint[4] total_bits; + } +} +else +{ + private enum SHA_TYPE : int { SHA1 = 0, SHA2_256 } + + private struct SHA_CTX + { + bool start; + uint[4] total_input_bits; + } +} diff --git a/src/urt/driver/baremetal/exception.d b/src/urt/driver/baremetal/exception.d new file mode 100644 index 0000000..65ef50d --- /dev/null +++ b/src/urt/driver/baremetal/exception.d @@ -0,0 +1,156 @@ +/// Bare-metal exception/crash driver. +/// +/// Provides the stack-trace driver interface for bare-metal targets +/// (BK7231, BL618, BL808, RP2350, STM32, ...). No symbol resolution is +/// available on-device - addresses are printed raw; decode offline with +/// `addr2line -e `. +/// +/// Requires the compiler to keep the frame pointer live +/// (`-frame-pointer=all` on LDC). Without it the fp chain is garbage. +module urt.driver.baremetal.exception; + +version (BareMetal): + +import urt.attribute : noinline; +import urt.internal.exception : Resolved; + +nothrow @nogc: + +// Linker symbols bounding the valid stack range. Used by the fp-chain +// walker to stop dereferencing junk. Each bare-metal linker script in +// this tree defines both. _stack_low is the bottom of the stack reservation +// (not _bss_end -- on M0 the stack is in OCRAM while .bss is in PSRAM, so +// the two no longer share a region). +// +// These are absolute linker symbols with no storage -- only their addresses +// matter. Declaring as `char` (size 1, never read) and using `&sym` is the +// correct C/D pattern; declaring as `void*` would tell the compiler to +// dereference 4/8 bytes at the symbol's address (i.e. read past stack top). +extern(C) extern __gshared char _stack_top; +extern(C) extern __gshared char _stack_low; + + +// --- Shared fp-chain walker ------------------------------------------- +// +// RV64 / AArch64 / ARM-AAPCS all share the same prologue layout when +// -frame-pointer=all is in effect: +// fp[-1] = saved return address +// fp[-2] = saved previous frame pointer +// (indices in machine-word units; RV64 uses fp-8 / fp-16 in bytes). +// +// On 32-bit ARM AAPCS the layout is fp[0] = prev fp, fp[+1] = saved lr +// for Thumb prologues - we don't currently target that combo, so stick +// to the standard layout for now. +// +/// Walk the frame-pointer chain starting at `fp`, writing return addresses +/// into `out_addrs`. Returns the number of frames captured. +size_t walk_fp_chain(size_t fp, void*[] out_addrs) @trusted +{ + if (out_addrs.length == 0) + return 0; + + const stack_hi = cast(size_t) &_stack_top; + const stack_lo = cast(size_t) &_stack_low; + + size_t n = 0; + while (n < out_addrs.length) + { + if (fp < stack_lo || fp >= stack_hi || (fp & (size_t.sizeof - 1)) != 0) + break; + + const ret_addr = *cast(size_t*)(fp - size_t.sizeof); + const prev_fp = *cast(size_t*)(fp - 2 * size_t.sizeof); + + if (ret_addr == 0) + break; + + out_addrs[n++] = cast(void*) ret_addr; + + if (prev_fp == 0 || prev_fp <= fp) + break; + fp = prev_fp; + } + return n; +} + + +// --- Read own frame pointer ------------------------------------------- + +private size_t read_fp() @trusted +{ + size_t fp; + version (RISCV64) + asm nothrow @nogc @trusted { "mv %0, s0" : "=r"(fp); } + else version (RISCV32) + asm nothrow @nogc @trusted { "mv %0, s0" : "=r"(fp); } + else version (AArch64) + asm nothrow @nogc @trusted { "mov %0, x29" : "=r"(fp); } + else version (ARM) + asm nothrow @nogc @trusted { "mov %0, r11" : "=r"(fp); } + else version (Xtensa) + asm nothrow @nogc @trusted { "mov %0, a7" : "=r"(fp); } // Xtensa: a7 with -mno-serialize-volatile + else + fp = 0; // unknown arch - capture returns empty + return fp; +} + + +// --- Driver interface ------------------------------------------------- +// +// All three primitives assume they are called through a one-level public +// wrapper in urt.internal.exception (kept non-inlined via pragma(inline, +// false)). The wrapper's frame is accounted for in the skip counts. + +/// Capture the caller's call stack. First entry = return address of +/// the function that called the public `capture_trace` wrapper. +@noinline +size_t _capture_trace(void*[] addrs) @trusted +{ + // LLVM elides _capture_trace's prologue and reads s0 before saving it, + // so read_fp() returns the CALLER's fp -- not our own. With LTO/tail-call + // chains (eh_capture_here -> capture_trace -> _capture_trace all tail- + // calling), this collapses to whichever frame is the topmost non-tail- + // called caller. Walk from there directly; the old "step up once" + // overshot whenever the wrapper chain tail-called. + auto fp = read_fp(); + if (fp == 0) + return 0; + return walk_fp_chain(fp, addrs); +} + +/// Return the return address of the `skip`-th frame above the public +/// `caller_address` wrapper's caller. +@noinline +void* _caller_address(uint skip) @trusted +{ + // Same elision/tail-call pattern as _capture_trace: read_fp() returns + // the topmost non-tail-called caller's fp. With LLVM tail-calling the + // public capture_address wrapper, that is USER's fp directly. So + // buf[0] = USER's saved ra = inside USER's caller ← skip=0 wants this + // buf[1] = caller's caller ← skip=1 + auto fp = read_fp(); + if (fp == 0) + return null; + + void*[32] buf = void; + const need = skip + 1; + if (need > buf.length) + return null; + const got = walk_fp_chain(fp, buf[0 .. need]); + if (got < need) + return null; + return buf[skip]; +} + +/// On bare-metal we have no on-device symbol table. Always returns +/// false; decode the address offline with `addr2line`. +bool _resolve_address(void* addr, out Resolved r) @trusted +{ + return false; +} + +/// No on-device symbols - caller should treat `results[]` as empty. +bool _resolve_batch(const(void*)[] addrs, Resolved[] results) @trusted +{ + return false; +} diff --git a/src/urt/driver/bk7231/alloc.d b/src/urt/driver/bk7231/alloc.d new file mode 100644 index 0000000..af693c4 --- /dev/null +++ b/src/urt/driver/bk7231/alloc.d @@ -0,0 +1,38 @@ +module urt.driver.bk7231.alloc; + +import urt.mem.alloc : MemFlags; + +nothrow @nogc: + +enum has_realloc = false; +enum has_expand = false; +enum has_memsize = false; +enum has_exec = false; +enum has_retain = false; +enum has_memflags = false; + +void[] _alloc(size_t size, size_t alignment, MemFlags) pure +{ + import urt.util : align_down; + + size_t header_size = (void*).sizeof + alignment; + void* p = malloc(header_size + size); + if (p is null) + return null; + + size_t allocptr = align_down(cast(size_t)p + header_size, alignment); + (cast(void**)allocptr)[-1] = p; + return (cast(void*)allocptr)[0 .. size]; +} + +void _free(void* ptr) pure +{ + free((cast(void**)ptr)[-1]); +} + + +private: + +extern(C) void* malloc(size_t size) pure; +extern(C) void free(void* ptr) pure; + diff --git a/src/urt/driver/bk7231/gpio.d b/src/urt/driver/bk7231/gpio.d new file mode 100644 index 0000000..5234c1e --- /dev/null +++ b/src/urt/driver/bk7231/gpio.d @@ -0,0 +1,105 @@ +// BK7231 GPIO. Per-pin config registers at GPIO_BASE + pin*4 (function/ +// input/output/pull). A 2-bit perial-mode field per pin in GPIO_FUNC_CFG +// selects the peripheral when GMODE_FUNC_EN is set; only pins 0..15 have +// a perial-mode field. +// +// Pin numbering: linear 0..31. +// +// Software GPIO primitives are unimplemented (need full per-pin config +// bit definitions from the BK7231 reference manual). gpio_set_function +// works and is sufficient for UART pin mux today. +module urt.driver.bk7231.gpio; + +import core.volatile : volatileLoad, volatileStore; + +import urt.driver.gpio : Pull, DriveMode; + +@nogc nothrow: + + +enum uint num_gpio = 32; +enum bool has_pull_up = true; +enum bool has_pull_down = true; +enum bool has_open_drain = false; +enum bool has_pin_function_muxing = true; + + +uint gpio_count() => num_gpio; + + +void gpio_output_init(uint pin, bool initial = false, DriveMode mode = DriveMode.push_pull) +{ + assert(false, "bk7231 gpio: gpio_output_init not yet implemented"); +} + +void gpio_input_init(uint pin, Pull pull = Pull.none) +{ + assert(false, "bk7231 gpio: gpio_input_init not yet implemented"); +} + +void gpio_output_set(uint pin, bool value) +{ + assert(false, "bk7231 gpio: gpio_output_set not yet implemented"); +} + +void gpio_output_toggle(uint pin) +{ + assert(false, "bk7231 gpio: gpio_output_toggle not yet implemented"); +} + +bool gpio_input_read(uint pin) +{ + assert(false, "bk7231 gpio: gpio_input_read not yet implemented"); + return false; +} + +void gpio_set_pull(uint pin, Pull pull) +{ + assert(false, "bk7231 gpio: gpio_set_pull not yet implemented"); +} + +void gpio_release(uint pin) +{ + assert(false, "bk7231 gpio: gpio_release not yet implemented"); +} + +void gpio_set_function(uint pin, uint function_id, Pull pull = Pull.none, DriveMode mode = DriveMode.push_pull) +{ + assert(pin < 16, "bk7231 gpio: perial-mode field only exists for pins 0..15"); + assert(function_id < 4, "bk7231 gpio: perial mode is 2-bit (0..3)"); + assert(mode == DriveMode.push_pull, "bk7231 gpio: open-drain not supported"); + + uint cfg = GMODE_FUNC_EN | GMODE_OUTPUT_EN; + if (pull == Pull.up) + cfg |= GMODE_PULL_EN | GMODE_PULL_UP; + else if (pull == Pull.down) + cfg |= GMODE_PULL_EN; + reg_write(GPIO_BASE + pin * 4, cfg); + + uint func_cfg = reg_read(GPIO_FUNC_CFG); + func_cfg &= ~(0x3u << (pin * 2)); + func_cfg |= (function_id & 0x3u) << (pin * 2); + reg_write(GPIO_FUNC_CFG, func_cfg); +} + + +private: + +enum uint GPIO_BASE = 0x0080_2800; +enum uint GPIO_FUNC_CFG = GPIO_BASE + 32 * 4; + +// Bit positions inferred from SDK gpio_enable_second_function value 0x78. +enum uint GMODE_FUNC_EN = 1u << 3; +enum uint GMODE_OUTPUT_EN = 1u << 4; +enum uint GMODE_PULL_EN = 1u << 5; +enum uint GMODE_PULL_UP = 1u << 6; + +uint reg_read(uint addr) +{ + return volatileLoad(cast(uint*)(cast(size_t)addr)); +} + +void reg_write(uint addr, uint val) +{ + volatileStore(cast(uint*)(cast(size_t)addr), val); +} diff --git a/src/urt/driver/bk7231/irq.d b/src/urt/driver/bk7231/irq.d new file mode 100644 index 0000000..4735fc9 --- /dev/null +++ b/src/urt/driver/bk7231/irq.d @@ -0,0 +1,94 @@ +// BK7231 interrupt controller (shared by BK7231N and BK7231T) +// +// ARM968E-S uses a custom Beken interrupt controller (not ARM GIC/NVIC). +// The BK7231N ICU (Interrupt Control Unit) is at 0x0080_2000. +module urt.driver.bk7231.irq; + +import core.volatile; + +@nogc nothrow: + +enum bool has_plic = false; +enum bool has_nvic = false; +enum bool has_clic = false; +enum bool has_per_irq_control = true; +enum bool has_irq_priority = false; +enum bool has_wait_for_interrupt = false; +enum bool has_irq_diagnostics = false; +enum bool has_global_irq_state = true; +enum bool has_smp = false; +enum uint irq_max = 32; + +// ARMv5 CPSR: I=bit7 masks IRQ, F=bit6 masks FIQ. We report prior IRQ-enable +// state only; FIQ is treated as a hard-disable that callers don't toggle. +bool irq_disable() +{ + uint cpsr; + asm @nogc nothrow { "mrs %0, cpsr" : "=r" (cpsr); } + bool was_enabled = (cpsr & 0x80) == 0; + asm @nogc nothrow { "msr cpsr_c, %0" :: "r" (cpsr | 0xC0); } + return was_enabled; +} + +bool irq_enable() +{ + uint cpsr; + asm @nogc nothrow { "mrs %0, cpsr" : "=r" (cpsr); } + bool was_enabled = (cpsr & 0x80) == 0; + asm @nogc nothrow { "msr cpsr_c, %0" :: "r" (cpsr & ~0x80); } + return was_enabled; +} + +bool irq_set_enable(uint irq_num) +{ + auto en = cast(uint*)(cast(size_t)(icu_base + icu_int_enable)); + uint mask = volatileLoad(en); + bool prev = (mask & (1u << irq_num)) != 0; + volatileStore(en, mask | (1u << irq_num)); + return prev; +} + +bool irq_clear_enable(uint irq_num) +{ + auto en = cast(uint*)(cast(size_t)(icu_base + icu_int_enable)); + uint mask = volatileLoad(en); + bool prev = (mask & (1u << irq_num)) != 0; + volatileStore(en, mask & ~(1u << irq_num)); + return prev; +} + + +private: + +enum uint icu_base = 0x0080_2000; + +// ICU register offsets (from SDK icu.h) +enum +{ + icu_peri_clk_pwd = 2 * 4, // 0x08: peripheral clock power-down (1=off) + icu_clk_gating = 3 * 4, // 0x0C: peripheral clock gating + icu_int_enable = 16 * 4, // 0x40: interrupt enable mask (FIQ [31:16] | IRQ [15:0]) + icu_global_int = 17 * 4, // 0x44: global IRQ/FIQ enable + icu_int_raw = 18 * 4, // 0x48: raw interrupt status + icu_int_status = 19 * 4, // 0x4C: masked interrupt status + icu_arm_wakeup = 20 * 4, // 0x50: ARM wakeup enable +} + +// IRQ bit positions in icu_int_enable / icu_int_status +enum : uint +{ + IRQ_UART1 = 1 << 0, + IRQ_UART2 = 1 << 1, + IRQ_I2C1 = 1 << 2, + IRQ_IRDA = 1 << 3, + IRQ_I2C2 = 1 << 5, + IRQ_SPI = 1 << 6, + IRQ_GPIO = 1 << 7, + IRQ_TIMER = 1 << 8, + IRQ_PWM = 1 << 9, + IRQ_ADC = 1 << 11, + IRQ_SDIO = 1 << 12, + IRQ_SEC = 1 << 13, + IRQ_LA = 1 << 14, + IRQ_DMA = 1 << 15, +} diff --git a/src/urt/driver/bk7231/package.d b/src/urt/driver/bk7231/package.d new file mode 100644 index 0000000..0e35501 --- /dev/null +++ b/src/urt/driver/bk7231/package.d @@ -0,0 +1,32 @@ +// BK7231 platform package (ARM968E-S, ARMv5TE) +// +// Provides sys_init() as the single entry point for all +// hardware initialization. Called from start.S before main(). +module urt.driver.bk7231; + +public import urt.driver.bk7231.uart; +public import urt.driver.bk7231.irq; +public import urt.driver.bk7231.timer; + +import urt.driver.uart : UartConfig; + +@nogc nothrow: + +private extern(C) void __register_frame_info(const void*, void*); +private extern(C) extern const ubyte __eh_frame_start; +private ubyte[48] __eh_frame_object; + +extern(C) void sys_init() +{ + __register_frame_info(&__eh_frame_start, &__eh_frame_object); + + // Init UART1 (console) at default baud for early output + uart_hw_init(0, UartConfig.init); + + uart0_hw_puts("BK7231: sys_init\r\n"); + + // Init freerunning timer for monotonic clock + timer_hw_init(); + + uart0_hw_puts("BK7231: ready\r\n"); +} diff --git a/src/urt/driver/bk7231/start.S b/src/urt/driver/bk7231/start.S new file mode 100644 index 0000000..a22f40b --- /dev/null +++ b/src/urt/driver/bk7231/start.S @@ -0,0 +1,119 @@ +/* BK7231N (ARM968E-S, ARMv5TE) startup + * + * Boot flow: + * 1. Beken bootloader validates image, jumps to Reset_Handler + * 2. Reset_Handler runs: + * a. Set up stack pointer + * b. Copy .got from flash to SRAM + * c. Copy .data from flash to SRAM + * d. Copy .tdata from flash to SRAM + * e. Zero .bss + * f. Call sys_init (platform init) + * g. Run .init_array (D module constructors) + * h. Call main + * + * ARM968E-S has no vector table relocation (no VTOR). Exception vectors live + * at 0x00000000 (or 0xFFFF0000 if high-vectors enabled). The Beken bootloader + * owns the vector table; we install handlers via the SDK's IRQ registration API. + */ + + .arm + .cpu arm968e-s + .fpu softvfp + + .section .text, "ax" + .global Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + + /* -- Disable IRQs during init -- */ + mrs r0, cpsr + orr r0, r0, #0xC0 /* set I+F bits */ + msr cpsr_c, r0 + + /* -- Set up stack -- */ + ldr sp, =_stack_top + + /* -- Copy .got from flash (LMA) to SRAM (VMA) -- */ + ldr r0, =_got_start + ldr r1, =_got_load + ldr r2, =_got_end + cmp r0, r1 + beq .Lgot_done + b .Lgot_check +.Lgot_copy: + ldr r3, [r1], #4 + str r3, [r0], #4 +.Lgot_check: + cmp r0, r2 + blo .Lgot_copy +.Lgot_done: + + /* -- Copy .data from flash to SRAM -- */ + ldr r0, =_data_start + ldr r1, =_data_load + ldr r2, =_data_end + b .Ldata_check +.Ldata_copy: + ldr r3, [r1], #4 + str r3, [r0], #4 +.Ldata_check: + cmp r0, r2 + blo .Ldata_copy + + /* -- Copy .tdata from flash to SRAM -- */ + ldr r0, =_tdata_start + ldr r1, =_tdata_load + ldr r2, =_tdata_end + b .Ltdata_check +.Ltdata_copy: + ldr r3, [r1], #4 + str r3, [r0], #4 +.Ltdata_check: + cmp r0, r2 + blo .Ltdata_copy + + /* -- Zero .bss -- */ + ldr r0, =_bss_start + ldr r2, =_bss_end + mov r3, #0 + b .Lbss_check +.Lbss_zero: + str r3, [r0], #4 +.Lbss_check: + cmp r0, r2 + blo .Lbss_zero + + /* -- Platform init -- */ + bl sys_init + + /* -- Run .init_array (D module constructors) -- */ + ldr r4, =__init_array_start + ldr r5, =__init_array_end + b .Linit_check +.Linit_loop: + ldr r0, [r4], #4 + mov lr, pc + bx r0 +.Linit_check: + cmp r4, r5 + blo .Linit_loop + + /* -- Enter main (should never return) -- */ + bl main + +.Lhalt: + b .Lhalt + + .size Reset_Handler, . - Reset_Handler + +/* ================================================================ + * __aeabi_read_tp -- ARM EABI thread pointer for TLS access + * Single-threaded bare-metal: return fixed pointer to .tdata + * ================================================================ */ + .global __aeabi_read_tp + .type __aeabi_read_tp, %function +__aeabi_read_tp: + ldr r0, =_tdata_start + bx lr + .size __aeabi_read_tp, . - __aeabi_read_tp diff --git a/src/urt/driver/bk7231/syscalls.d b/src/urt/driver/bk7231/syscalls.d new file mode 100644 index 0000000..e89078f --- /dev/null +++ b/src/urt/driver/bk7231/syscalls.d @@ -0,0 +1,55 @@ +// BK7231 newlib/picolibc syscall stubs +// +// Minimal stubs to satisfy picolibc's syscall requirements. +// Same pattern as RP2350 -- most are no-ops for baremetal. +module urt.driver.bk7231.syscalls; + +@nogc nothrow: + +private extern(C) extern const void* __heap_start; +private extern(C) extern const void* __heap_end; + +private __gshared void* _heap_ptr; + +extern(C) void* _sbrk(ptrdiff_t incr) +{ + if (_heap_ptr is null) + _heap_ptr = cast(void*)&__heap_start; + + void* prev = _heap_ptr; + void* next = _heap_ptr + incr; + + if (next > cast(void*)&__heap_end) + return cast(void*)-1; + + _heap_ptr = next; + return prev; +} + +extern(C) int _write(int fd, const void* buf, size_t count) +{ + import urt.driver.bk7231.uart : uart0_hw_puts; + if (fd == 1 || fd == 2) + uart0_hw_puts((cast(const(char)*)buf)[0 .. count]); + return cast(int)count; +} + +extern(C) int _read(int, void*, size_t) { return 0; } +extern(C) int _close(int) { return -1; } +extern(C) int _lseek(int, int, int) { return 0; } +extern(C) int _fstat(int, void*) { return 0; } +extern(C) int _isatty(int) { return 1; } +extern(C) void _exit(int) { while (true) {} } +extern(C) int _kill(int, int) { return -1; } +extern(C) int _getpid() { return 1; } +extern(C) int usleep(uint) { return 0; } + +// DWARF unwinder stubs -- ARM uses EHABI, not DWARF. +// These satisfy link-time references from the exception personality code. +extern(C) void __register_frame_info(const void*, void*) {} +extern(C) size_t _Unwind_GetIPInfo(void*, int*) { return 0; } +extern(C) void _Unwind_SetGR(void*, int, size_t) {} +extern(C) void _Unwind_SetIP(void*, size_t) {} + +// ARM EHABI resume unwind -- called by LDC's exception propagation +extern(C) void _d_eh_resume_unwind(void*) {} diff --git a/src/urt/driver/bk7231/timer.d b/src/urt/driver/bk7231/timer.d new file mode 100644 index 0000000..e4c7815 --- /dev/null +++ b/src/urt/driver/bk7231/timer.d @@ -0,0 +1,143 @@ +// BK7231 timer driver (shared by BK7231N and BK7231T) +// +// The BK7231 timer/PWM block lives at PWM_NEW_BASE = 0x0080_2A00. +// Timers 0-2 run from 26MHz, timers 3-5 from 32kHz. +// +// We use Timer0 as a freerunning monotonic clock source at 26MHz. +// The counter counts up from 0 to the period register value, then wraps. +// With period = 0xFFFF_FFFF, it wraps every ~165s at 26MHz. +// +// Reading the current count is a two-step process: +// 1. Write (timer_index << 2) | 1 to READ_CTL +// 2. Poll READ_CTL until bit 0 clears +// 3. Read current count from READ_VALUE +// +// Register layout verified against Beken SDK: +// sdk/OpenBK7231N/platforms/bk7231n/bk7231n_os/beken378/driver/pwm/bk_timer.h +// sdk/OpenBK7231N/platforms/bk7231n/bk7231n_os/beken378/driver/pwm/bk_timer.c +module urt.driver.bk7231.timer; + +import core.volatile; + +@nogc nothrow: + + +// --- Timer/PWM base (from SDK pwm.h) -------------------------------- + +private enum uint PWM_NEW_BASE = 0x0080_2A00; + + +// --- Timer0-2 registers (26MHz group) -------------------------------- + +private enum : uint +{ + // Period/end-value registers (one per timer, writable) + TIMER0_PERIOD = PWM_NEW_BASE + 0 * 4, // 0x0080_2A00 + TIMER1_PERIOD = PWM_NEW_BASE + 1 * 4, // 0x0080_2A04 + TIMER2_PERIOD = PWM_NEW_BASE + 2 * 4, // 0x0080_2A08 + + // Shared control register for Timer0-2 + TIMER0_2_CTL = PWM_NEW_BASE + 3 * 4, // 0x0080_2A0C + + // Counter read-back registers (BK7231N/U; BK7231T has them in practice) + TIMER0_2_READ_CTL = PWM_NEW_BASE + 4 * 4, // 0x0080_2A10 + TIMER0_2_READ_VALUE = PWM_NEW_BASE + 5 * 4, // 0x0080_2A14 +} + + +// --- Timer0-2 control register bits ---------------------------------- + +private enum : uint +{ + TIMER0_EN = 1 << 0, + TIMER1_EN = 1 << 1, + TIMER2_EN = 1 << 2, + CLK_DIV_POS = 3, // 3-bit divider: actual_div = reg_val + 1 + CLK_DIV_MASK = 0x7 << 3, + TIMER0_INT = 1 << 7, // Timer0 interrupt flag (write 1 to clear) + TIMER1_INT = 1 << 8, + TIMER2_INT = 1 << 9, + INT_FLAG_MASK = 0x7 << 7, +} + + +// --- ICU clock power for timers -------------------------------------- +// From SDK icu.h: ICU_PERI_CLK_PWD = ICU_BASE + 2*4 = 0x0080_2008 + +private enum uint ICU_PERI_CLK_PWD = 0x0080_2008; +private enum uint PWD_TIMER_26M_CLK = 1 << 20; + + +// --- Public interface ------------------------------------------------ + +enum uint mtime_freq_hz = 26_000_000; +enum bool has_mtime = true; +enum bool has_rtc = false; +enum bool has_mcycle = false; +enum bool has_timer_stop = false; +enum bool has_oneshot_timer = false; + +private enum uint timer_freq_hz = mtime_freq_hz; + +private __gshared uint timer_high; +private __gshared uint timer_last; + +void timer_hw_init() +{ + // Enable 26MHz timer clock (clear power-down bit) + uint pwd = volatileLoad(cast(uint*)(cast(size_t)ICU_PERI_CLK_PWD)); + pwd &= ~PWD_TIMER_26M_CLK; + volatileStore(cast(uint*)(cast(size_t)ICU_PERI_CLK_PWD), pwd); + + // Set Timer0 period to maximum (freerunning) + volatileStore(cast(uint*)(cast(size_t)TIMER0_PERIOD), 0xFFFF_FFFF); + + // Configure control: enable Timer0, div=1 (CLK_DIV=0), clear interrupt flags + uint ctl = volatileLoad(cast(uint*)(cast(size_t)TIMER0_2_CTL)); + ctl &= ~(CLK_DIV_MASK | INT_FLAG_MASK); // div=0 means /1, clear int flags + ctl |= TIMER0_EN; + volatileStore(cast(uint*)(cast(size_t)TIMER0_2_CTL), ctl); + + timer_high = 0; + timer_last = 0; +} + +// Read the current Timer0 count via the READ_CTL/READ_VALUE mechanism. +// Hardware clears READ_CTL bit 0 when the snapshot is ready. +private uint timer0_read_count() +{ + enum uint read_ctl_addr = TIMER0_2_READ_CTL; + enum uint read_val_addr = TIMER0_2_READ_VALUE; + + // Trigger read for timer index 0: (index << 2) | 1 + volatileStore(cast(uint*)(cast(size_t)read_ctl_addr), (0 << 2) | 1); + + // Poll until hardware clears bit 0 (should be near-instant at 26MHz) + while (volatileLoad(cast(uint*)(cast(size_t)read_ctl_addr)) & 1) + {} + + return volatileLoad(cast(uint*)(cast(size_t)read_val_addr)); +} + +// Read monotonic 64-bit tick count. +// Must be called at least once per ~165 seconds (2^32 / 26MHz) to catch +// rollovers. The main loop at 20Hz guarantees this. +ulong mtime_read() +{ + uint now = timer0_read_count(); + if (now < timer_last) + ++timer_high; + timer_last = now; + return (cast(ulong)timer_high << 32) | now; +} + +alias TimerCallback = void function() @nogc nothrow; + +private __gshared TimerCallback tick_callback; + +void timer_set_periodic(uint period_us, TimerCallback cb) +{ + tick_callback = cb; + // TODO: configure Timer1 for periodic interrupt at period_us + // Requires IRQ vector dispatch in start.S (not yet implemented) +} diff --git a/src/urt/driver/bk7231/uart.d b/src/urt/driver/bk7231/uart.d new file mode 100644 index 0000000..ae8324d --- /dev/null +++ b/src/urt/driver/bk7231/uart.d @@ -0,0 +1,371 @@ +// BK7231 UART driver (shared by BK7231N and BK7231T) +// +// BK7231 has 2x UARTs: +// UART1 0x0080_2100 Log/console (TX=GPIO11, RX=GPIO10) +// UART2 0x0080_2200 Data/general purpose (TX=GPIO0, RX=GPIO1) +// +// Both have 128-byte TX/RX FIFOs. +// +// Register layout and init sequence verified against Beken SDK: +// sdk/OpenBK7231N/platforms/bk7231n/bk7231n_os/beken378/driver/uart/uart.h +// sdk/OpenBK7231N/platforms/bk7231n/bk7231n_os/beken378/driver/uart/uart_bk.c +module urt.driver.bk7231.uart; + +import core.volatile; + +import urt.driver.uart : FlowControl, Parity, StopBits, UartConfig; +import urt.driver.gpio : Pull, gpio_set_function; + +nothrow @nogc: + +enum num_uarts = 2; +enum uint uart_clock_hz = 26_000_000; +enum bool has_irq_driven_uart = false; +enum bool has_dma_driven_uart = false; + + +// --- Register offsets (from SDK uart.h) ------------------------------ + +private enum uint[2] uart_bases = [0x0080_2100, 0x0080_2200]; + +private enum : uint +{ + REG_CONFIG = 0x00, // Baud rate, data bits, parity, stop bits, TX/RX enable + REG_FIFO_CONFIG = 0x04, // FIFO thresholds, RX stop detect time + REG_FIFO_STATUS = 0x08, // FIFO counts and flags (read-only) + REG_FIFO_PORT = 0x0C, // Data read/write port + REG_INT_ENABLE = 0x10, // Interrupt enable + REG_INT_STATUS = 0x14, // Interrupt status (write 1 to clear) + REG_FLOW_CONFIG = 0x18, // Flow control + REG_WAKE_CONFIG = 0x1C, // Wakeup configuration +} + + +// --- CONFIG register (0x00) ------------------------------------------ + +private enum : uint +{ + CFG_TX_ENABLE = 1 << 0, + CFG_RX_ENABLE = 1 << 1, + CFG_IRDA = 1 << 2, + CFG_DATA_LEN_POS = 3, // 2 bits: 0=5, 1=6, 2=7, 3=8 + CFG_DATA_LEN_MASK = 0x3 << 3, + CFG_PARITY_EN = 1 << 5, + CFG_PARITY_ODD = 1 << 6, // 0=even, 1=odd + CFG_STOP_LEN_2 = 1 << 7, // 0=1 stop, 1=2 stop + CFG_CLK_DIV_POS = 8, // 13-bit baud divisor + CFG_CLK_DIV_MASK = 0x1FFF << 8, +} + + +// --- FIFO_CONFIG register (0x04) ------------------------------------- + +private enum : uint +{ + FIFO_TX_THRESHOLD_POS = 0, // 8 bits + FIFO_TX_THRESHOLD_MASK = 0xFF, + FIFO_RX_THRESHOLD_POS = 8, // 8 bits + FIFO_RX_THRESHOLD_MASK = 0xFF << 8, + FIFO_RX_STOP_TIME_POS = 16, // 3 bits: 0=32, 1=64, 2=128, 3=256 clks + FIFO_RX_STOP_TIME_MASK = 0x7 << 16, +} + + +// --- FIFO_STATUS register (0x08, read-only) -------------------------- + +private enum : uint +{ + STAT_TX_FIFO_COUNT_MASK = 0xFF, // bits [7:0] + STAT_RX_FIFO_COUNT_POS = 8, + STAT_RX_FIFO_COUNT_MASK = 0xFF << 8, // bits [15:8] + STAT_TX_FIFO_FULL = 1 << 16, + STAT_TX_FIFO_EMPTY = 1 << 17, + STAT_RX_FIFO_FULL = 1 << 18, + STAT_RX_FIFO_EMPTY = 1 << 19, + STAT_FIFO_WR_READY = 1 << 20, + STAT_FIFO_RD_READY = 1 << 21, +} + + +// --- INT_ENABLE (0x10) / INT_STATUS (0x14) --------------------------- +// Same bit layout for both registers. + +private enum : uint +{ + INT_TX_FIFO_NEED_WRITE = 1 << 0, + INT_RX_FIFO_NEED_READ = 1 << 1, + INT_RX_FIFO_OVERFLOW = 1 << 2, + INT_RX_PARITY_ERR = 1 << 3, + INT_RX_STOP_ERR = 1 << 4, + INT_TX_STOP_END = 1 << 5, + INT_RX_STOP_END = 1 << 6, + INT_RXD_WAKEUP = 1 << 7, + + INT_ALL_ERRORS = INT_RX_FIFO_OVERFLOW | INT_RX_PARITY_ERR | INT_RX_STOP_ERR, +} + + +// --- FLOW_CONFIG register (0x18) ------------------------------------- + +private enum : uint +{ + FLOW_LOW_CNT_POS = 0, // 8 bits: assert RTS below this count + FLOW_LOW_CNT_MASK = 0xFF, + FLOW_HIGH_CNT_POS = 8, // 8 bits: de-assert RTS above this count + FLOW_HIGH_CNT_MASK = 0xFF << 8, + FLOW_CTRL_EN = 1 << 16, + FLOW_RTS_POLARITY = 1 << 17, + FLOW_CTS_POLARITY = 1 << 18, +} + + +// --- Hardware constants ---------------------------------------------- + +private enum uint FIFO_DEPTH = 128; + +// SDK defaults (uart.h): TX_FIFO_THRD=0x40, RX_FIFO_THRD=0x30 +private enum uint SDK_TX_FIFO_THRESHOLD = 0x40; +private enum uint SDK_RX_FIFO_THRESHOLD = 0x30; +private enum uint SDK_RX_STOP_DETECT = 0; // 32 clock cycles + + +// --- ICU registers for UART clock control ---------------------------- +// From SDK icu.h: ICU_PERI_CLK_PWD = ICU_BASE + 2*4 + +private enum uint ICU_BASE = 0x0080_2000; +private enum uint ICU_PERI_CLK_PWD = ICU_BASE + 2 * 4; // 0x0080_2008 + +// Power-down bits (1=powered down, 0=running) +private enum uint PWD_UART1_CLK = 1 << 0; +private enum uint PWD_UART2_CLK = 1 << 1; + + +// UART pins are fixed by hardware; perial mode 0 is the only valid value. +private enum ubyte[2] default_tx_pins = [11, 0]; // UART1=GPIO11, UART2=GPIO0 +private enum ubyte[2] default_rx_pins = [10, 1]; // UART1=GPIO10, UART2=GPIO1 +private enum uint UART_PERIAL_MODE = 0; + + +// --- Register access helpers ----------------------------------------- + +private uint reg_read(uint addr) +{ + return volatileLoad(cast(uint*)(cast(size_t)addr)); +} + +private void reg_write(uint addr, uint val) +{ + volatileStore(cast(uint*)(cast(size_t)addr), val); +} + + +private bool gpio_setup_uart_pins(uint id, ref const UartConfig cfg) +{ + ubyte tx_pin = cfg.tx_gpio == ubyte.max ? default_tx_pins[id] : cfg.tx_gpio; + ubyte rx_pin = cfg.rx_gpio == ubyte.max ? default_rx_pins[id] : cfg.rx_gpio; + + if (tx_pin != default_tx_pins[id] || rx_pin != default_rx_pins[id]) + return false; + + gpio_set_function(tx_pin, UART_PERIAL_MODE, Pull.up); + gpio_set_function(rx_pin, UART_PERIAL_MODE, Pull.up); + return true; +} + + +// --- ICU clock control ----------------------------------------------- + +private void icu_uart_clock_enable(uint id) +{ + // Clear power-down bit to enable clock + uint pwd = reg_read(ICU_PERI_CLK_PWD); + pwd &= ~((id == 0) ? PWD_UART1_CLK : PWD_UART2_CLK); + reg_write(ICU_PERI_CLK_PWD, pwd); +} + +private void icu_uart_clock_disable(uint id) +{ + uint pwd = reg_read(ICU_PERI_CLK_PWD); + pwd |= (id == 0) ? PWD_UART1_CLK : PWD_UART2_CLK; + reg_write(ICU_PERI_CLK_PWD, pwd); +} + + +// --- Public API ------------------------------------------------------ + +bool uart_hw_init(uint id, UartConfig cfg) +{ + if (id >= num_uarts) + return false; + + immutable uint base = uart_bases[id]; + + // Step 1: Enable peripheral clock (SDK: CMD_CLK_PWR_UP) + icu_uart_clock_enable(id); + + // Step 2: Configure GPIO pins for UART function (SDK: CMD_GPIO_ENABLE_SECOND) + const pins_ok = gpio_setup_uart_pins(id, cfg); + if (!pins_ok) + return false; + + // Step 3: Disable TX/RX during configuration + reg_write(base + REG_CONFIG, 0); + + // Step 4: Configure FIFO thresholds and RX stop detect time + // SDK defaults: TX_FIFO_THRD=0x40, RX_FIFO_THRD=0x30, RX_STOP_DETECT=0 (32 clks) + reg_write(base + REG_FIFO_CONFIG, + (SDK_TX_FIFO_THRESHOLD << FIFO_TX_THRESHOLD_POS) + | (SDK_RX_FIFO_THRESHOLD << FIFO_RX_THRESHOLD_POS) + | (SDK_RX_STOP_DETECT << FIFO_RX_STOP_TIME_POS)); + + // Step 5: Disable flow control (enable only if requested) + uint flow = 0; + if (cfg.flow_control == FlowControl.hardware) + { + // Assert RTS when RX FIFO < 32, de-assert when > 96 + flow = FLOW_CTRL_EN + | (0x20 << FLOW_LOW_CNT_POS) + | (0x60 << FLOW_HIGH_CNT_POS); + } + reg_write(base + REG_FLOW_CONFIG, flow); + + // Step 6: Disable wakeup + reg_write(base + REG_WAKE_CONFIG, 0); + + // Step 7: Disable all interrupts (polled mode) + reg_write(base + REG_INT_ENABLE, 0); + + // Step 8: Clear any pending interrupt status + uint pending = reg_read(base + REG_INT_STATUS); + reg_write(base + REG_INT_STATUS, pending); + + // Step 9: Build CONFIG register and enable + // Baud divisor: clock / baud - 1 (SDK: uart_hw_init) + uint divisor = uart_clock_hz / cfg.baud_rate - 1; + + uint config = CFG_TX_ENABLE | CFG_RX_ENABLE; + + // Data length: 5=0, 6=1, 7=2, 8=3 + config |= ((cfg.data_bits - 5) & 0x3) << CFG_DATA_LEN_POS; + + if (cfg.parity != Parity.none) + { + config |= CFG_PARITY_EN; + if (cfg.parity == Parity.odd) + config |= CFG_PARITY_ODD; + } + + if (cfg.stop_bits == StopBits.two) + config |= CFG_STOP_LEN_2; + + config |= (divisor & 0x1FFF) << CFG_CLK_DIV_POS; + + reg_write(base + REG_CONFIG, config); + + return true; +} + +bool uart_hw_open(uint id, UartConfig cfg) +{ + return uart_hw_init(id, cfg); +} + +void uart_hw_close(uint id) +{ + if (id >= num_uarts) + return; + + immutable uint base = uart_bases[id]; + + // Disable all interrupts + reg_write(base + REG_INT_ENABLE, 0); + + // Disable TX and RX + uint config = reg_read(base + REG_CONFIG); + config &= ~(CFG_TX_ENABLE | CFG_RX_ENABLE); + reg_write(base + REG_CONFIG, config); +} + +ptrdiff_t uart_hw_read(uint id, void[] buffer) +{ + immutable uint base = uart_bases[id]; + auto buf = cast(ubyte[])buffer; + ptrdiff_t n = 0; + + while (n < buf.length) + { + if (reg_read(base + REG_FIFO_STATUS) & STAT_RX_FIFO_EMPTY) + break; + buf[n] = cast(ubyte)(reg_read(base + REG_FIFO_PORT) & 0xFF); + ++n; + } + return n; +} + +ptrdiff_t uart_hw_write(uint id, const(void)[] data) +{ + immutable uint base = uart_bases[id]; + auto buf = cast(const(ubyte)[])data; + ptrdiff_t n = 0; + + while (n < buf.length) + { + if (reg_read(base + REG_FIFO_STATUS) & STAT_TX_FIFO_FULL) + break; + reg_write(base + REG_FIFO_PORT, buf[n]); + ++n; + } + return n; +} + +void uart_hw_poll(uint id) +{ + // Polled FIFO mode: clear any accumulated error/status interrupts + // so they don't pile up even though we're not using interrupt mode. + immutable uint base = uart_bases[id]; + uint status = reg_read(base + REG_INT_STATUS); + if (status) + reg_write(base + REG_INT_STATUS, status); +} + +bool uart_hw_check_errors(uint id) +{ + immutable uint base = uart_bases[id]; + uint status = reg_read(base + REG_INT_STATUS); + uint errors = status & INT_ALL_ERRORS; + + if (errors) + { + // Clear the error flags by writing 1 + reg_write(base + REG_INT_STATUS, errors); + return true; + } + return false; +} + +ptrdiff_t uart_hw_rx_pending(uint id) +{ + uint status = reg_read(uart_bases[id] + REG_FIFO_STATUS); + return (status & STAT_RX_FIFO_COUNT_MASK) >> STAT_RX_FIFO_COUNT_POS; +} + +ptrdiff_t uart_hw_flush(uint id) +{ + immutable uint base = uart_bases[id]; + while (!(reg_read(base + REG_FIFO_STATUS) & STAT_TX_FIFO_EMPTY)) + {} + return 0; +} + +// Blocking puts for early boot (before the serial stream is up). +// Uses UART1 (the log/console UART) at 0x0080_2100. +void uart0_hw_puts(const(char)[] s) +{ + enum uint base = 0x0080_2100; + foreach (c; s) + { + while (reg_read(base + REG_FIFO_STATUS) & STAT_TX_FIFO_FULL) + {} + reg_write(base + REG_FIFO_PORT, cast(uint)c); + } +} diff --git a/src/urt/driver/bl618/irq.d b/src/urt/driver/bl618/irq.d new file mode 100644 index 0000000..0580f64 --- /dev/null +++ b/src/urt/driver/bl618/irq.d @@ -0,0 +1,756 @@ +// BL618 / BL808 M0 interrupt controller (T-Head E907 CLIC). +// +// The E907 has a Core Local Interrupt Controller at 0xE080_0000. Each IRQ has +// four bytes at CLICINT_BASE + irq*4: { IP, IE, ATTR, CTL }. Trap entry is +// dispatched via mtvt (CSR 0x307, standard CLIC) as a flat .word table of handler addresses, +// with mtvec in CLIC mode (mode 11) pointing at the exception/sync-trap +// handler. The per-IRQ stub _clic_dispatch (in start.S) uses T-Head ipush / +// ipop to push mepc/mcause/caller-saved GPRs across the handler call, which +// is what makes nesting safe (without it, the inner IRQ's mret would clobber +// the outer's mepc CSR; that bug bit us before). +// +// This module is shared by BL618 and BL808 M0 builds. The two parts have the +// same CLIC layout; per-board carve-outs live behind version(BL618) / +// version(BL808_M0) gates. +module urt.driver.bl618.irq; + +import core.volatile; + +@nogc nothrow: + + +// ==================================================================== +// Capability flags (read by urt.driver.irq facade) +// ==================================================================== + +enum bool has_plic = false; +enum bool has_nvic = false; +enum bool has_clic = true; +enum bool has_per_irq_control = true; +enum bool has_irq_priority = true; +enum bool has_wait_for_interrupt = true; +enum bool has_irq_diagnostics = true; +enum bool has_global_irq_state = true; +enum bool has_smp = false; + +// E907 CLIC supports up to 4096 IRQ lines architecturally; both BL618 and +// BL808 M0 wire 16 standard + 64 peripheral = 80 sources. Sources above the +// SoC's wired count are valid CLIC registers but will never raise. +enum uint irq_max = 80; + +// Standard RISC-V machine-mode interrupt cause indices. +enum IrqClass : uint +{ + software = 3, + timer = 7, + external = 11, +} + +alias IrqHandler = void function(uint irq) @nogc nothrow; + + +// ==================================================================== +// Global IRQ delivery (mstatus.MIE) +// ==================================================================== + +bool disable_interrupts() +{ + uint prev; + asm @nogc nothrow { "csrrci %0, mstatus, 0x8" : "=r" (prev); } + return (prev & 0x8) != 0; +} + +bool enable_interrupts() +{ + uint prev; + asm @nogc nothrow { "csrrsi %0, mstatus, 0x8" : "=r" (prev); } + return (prev & 0x8) != 0; +} + +bool set_interrupts(bool state) +{ + return state ? enable_interrupts() : disable_interrupts(); +} + +// Legacy aliases used by urt.driver.bl618.start.S / urt.system.d. +alias irq_disable = disable_interrupts; +alias irq_enable = enable_interrupts; + +void wait_for_interrupt() +{ + asm @nogc nothrow { "wfi"; } +} + + +// ==================================================================== +// Per-IRQ control +// ==================================================================== + +// Enable a single CLIC IRQ. Returns previous state. +// +// The T-Head CLIC will NOT deliver an IRQ whose CLICINTCTL priority is +// zero -- even with IE=1, SHV=1, IP=1, and mstatus.MIE set. Vendor's +// CPU_Interrupt_Enable in bl_iot_sdk's interrupt.c clamps the same way. +// We bump to the minimum-priority value (_clic_ctl_lsb); on E907 that's +// 0x10 because CLICINFO.CLICINTCTLBITS reports 4 (top 4 bits are RW +// priority, bottom 4 are RAO -- they read as 1 even after writing 0). +// So a "no priority" CTL reads as 0x0F, not 0x00. The check is +// `< _clic_ctl_lsb` (priority below minimum), not `== 0`. +bool irq_set_enable(uint irq) +{ + if (irq >= irq_max) + return false; + ubyte* ctl = clicint_byte(irq, ctl_offset); + if (volatileLoad(ctl) < _clic_ctl_lsb) + volatileStore(ctl, _clic_ctl_lsb); + ubyte* ie = clicint_byte(irq, ie_offset); + bool prev = (volatileLoad(ie) & 0x1) != 0; + volatileStore(ie, ubyte(1)); + return prev; +} + +bool irq_clear_enable(uint irq) +{ + if (irq >= irq_max) + return false; + ubyte* ie = clicint_byte(irq, ie_offset); + bool prev = (volatileLoad(ie) & 0x1) != 0; + volatileStore(ie, ubyte(0)); + return prev; +} + +// Overloads for IrqClass - matches urt.driver.bl808.irq's surface so +// urt.system.d (and other shared code) sees the same API on both cores. +bool enable_irq(IrqClass c) { return irq_set_enable(cast(uint)c); } +bool disable_irq(IrqClass c) { return irq_clear_enable(cast(uint)c); } + +bool irq_is_pending(uint irq) +{ + if (irq >= irq_max) + return false; + return (volatileLoad(clicint_byte(irq, ip_offset)) & 0x1) != 0; +} + +void irq_clear_pending(uint irq) +{ + if (irq >= irq_max) + return; + volatileStore(clicint_byte(irq, ip_offset), ubyte(0)); +} + +// Priority is the top (8 - NLBIT) bits of CTL; with NLBIT=0 (one level, no +// preemption) all 8 bits of CTL are priority. Higher value = higher priority. +void irq_set_priority(uint irq, ubyte priority) +{ + if (irq >= irq_max) + return; + volatileStore(clicint_byte(irq, ctl_offset), priority); +} + +// Set the trigger type for a peripheral IRQ. Default after clic_init is +// level-positive (0), which is what most peripherals need. +enum IrqTrigger : ubyte +{ + level_pos = 0b00, + edge_pos = 0b01, + level_neg = 0b10, + edge_neg = 0b11, +} + +void irq_set_trigger(uint irq, IrqTrigger trig) +{ + if (irq >= irq_max) + return; + ubyte* attr = clicint_byte(irq, attr_offset); + ubyte v = volatileLoad(attr); + v = cast(ubyte)((v & ~0b110) | ((cast(ubyte)trig & 0b11) << 1)); + volatileStore(attr, v); +} + + +// ==================================================================== +// Handler registration +// ==================================================================== + +// Install a handler for IRQ id. Returns the previous handler. +IrqHandler irq_set_handler(uint irq, IrqHandler handler) +{ + if (irq >= irq_max) + return null; + IrqHandler prev = _handlers[irq]; + _handlers[irq] = handler; + return prev; +} + + +// ==================================================================== +// Initialization +// ==================================================================== + +// Bring the CLIC into a known state: one priority level, no preemption, +// every line disabled with level-positive trigger and SHV=1. Read CLICINFO +// to learn how many CLICINTCTL bits are implemented (E907 reports 4 -> only +// the top 4 bits of CTL are RW) and cache the minimum-priority value for +// irq_set_enable's auto-bump. +// +// Called from sys_init (bl_common/system.d) before mstatus.MIE is enabled. +// MUST run before any irq_set_enable / irq_set_priority on a fresh boot -- +// otherwise stale CLIC state from a prior cycle could fire the moment MIE +// goes on, and the auto-bump would have no nlbits to shift against. +extern(C) void irq_init() +{ + // T-Head mexstatus.SPUSHEN | SPSWAPEN (bits 16-17 of CSR 0x7E1). Without + // these, th.ipush / th.ipop in _clic_dispatch are a silent no-op and the + // first IRQ wedges the chip. Vendor system_bl808.c sets the same bits. + asm @nogc nothrow + { + ` + li t0, 0x30000 + csrs 0x7E1, t0 + ` + : : : "t0"; + } + + // CLICCFG = 0: NLBIT=0 (single priority level, no preemption), NMBIT=0, + // NVBIT=0. We want preemption off until callers explicitly opt in. + volatileStore(cast(ubyte*)cast(size_t)clic_cfg, ubyte(0)); + + // CLICINFO[24:21] = CLICINTCTLBITS = number of CTL bits implemented from + // the top. E907 reports 4, so a CTL write of 1 (bit 0) stores 0 in the + // RAZ/WI bottom bits -- the line would never deliver. Compute the + // bottom-of-priority-field bit value so irq_set_enable can clamp to a + // true nonzero priority. Mirrors vendor's csi_vic_set_prio() arithmetic. + uint info = volatileLoad(cast(uint*)cast(size_t)clic_info); + uint ctlbits = (info >> 21) & 0xF; + if (ctlbits == 0 || ctlbits > 8) + ctlbits = 4; // E907 default; defensive fallback if CLICINFO is bogus + _clic_ctl_lsb = cast(ubyte)(1u << (8 - ctlbits)); + + foreach (uint i; 0 .. irq_max) + { + volatileStore(clicint_byte(i, ip_offset), ubyte(0)); + volatileStore(clicint_byte(i, ie_offset), ubyte(0)); + // SHV=1: hardware-vectored dispatch via mtvt[id] -> _clic_dispatch. + // SHV=0 routes through mtvec.base, which is _trap_exception (wrong + // path for interrupts -- it expects sync traps). TRIG=0 (level-pos) + // matches the vendor default. Vendor system_bl808.c does the same. + volatileStore(clicint_byte(i, attr_offset), ubyte(1)); + volatileStore(clicint_byte(i, ctl_offset), ubyte(0)); + } +} + + +// ==================================================================== +// Diagnostics +// ==================================================================== + +__gshared uint irq_count; +__gshared uint[irq_max] irq_histogram; + + +// ==================================================================== +// Dispatch (called from _clic_dispatch in start.S) +// ==================================================================== + +extern(C) void _irq_dispatch(uint cause) @nogc nothrow +{ + uint id = cause & 0x3FF; + ++irq_count; + if (id < irq_max) + { + ++irq_histogram[id]; + IrqHandler h = _handlers[id]; + if (h !is null) + h(id); + } +} + + +private: + +enum uint clic_base = 0xE080_0000; +enum uint clic_cfg = clic_base + 0x0000; // 1 byte +enum uint clic_info = clic_base + 0x0004; // 4 bytes +enum uint clic_mth = clic_base + 0x0008; // 4 bytes (MINTTHRESH) +enum uint clicint_base = clic_base + 0x1000; // 4 bytes per IRQ thereafter + +enum uint ip_offset = 0; +enum uint ie_offset = 1; +enum uint attr_offset = 2; +enum uint ctl_offset = 3; + +ubyte* clicint_byte(uint irq, uint field) +{ + return cast(ubyte*)cast(size_t)(clicint_base + irq * 4 + field); +} + +__gshared IrqHandler[irq_max] _handlers; + +// Minimum-nonzero CLICINTCTL value -- cached by irq_init() from CLICINFO. +// Pre-init fallback of 0x10 covers the E907 (4 implemented bits) so a stray +// irq_set_enable before irq_init still bumps to a valid priority. +__gshared ubyte _clic_ctl_lsb = 0x10; + + +// ==================================================================== +// Tests +// ==================================================================== +// +// Generic IRQ behaviour (global enable/disable round-trip, per-line +// enable/disable, handler table round-trip, diagnostics geometry, +// IrqGuard nesting) lives in urt.driver.irq's unittests and runs through +// this driver via the public-import facade. +// +// What lives here is everything that PROVES the CLIC trap path is wired +// correctly on real hardware: +// 1. CSR readback -- mtvt / mtvec.MODE / mexstatus, plus the +// content of __clic_vectors. Catches the +// "csrw silently went nowhere" class of +// bug (mtvt=0x7D7 vs 0x307 cost us two +// days; this test would have ended the +// hunt in seconds). +// 2. Force-IP positive -- vector 3 (MSWI) with IE=1, CTL>0, MIE=1 +// hits the installed D handler. +// 3. Force-IP negatives x3 -- removing any one of IE / CTL / MIE +// MUST swallow the IRQ. A negative test +// that fires would tell us the gate we +// think we have isn't actually there. +// 4. Distinct-vector routing-- two handlers on two vectors, each fires +// its own. Catches table aliasing / a +// stuck single-slot dispatcher. +// 5. Live hardware trap -- mtime/mtimecmp -> CLIC IRQ #7 -> the +// actual th.ipush / th.ipop trampoline, +// with a caller-saved register +// preservation check that no D-level test +// can mimic (the calling convention would +// hide the failure). + +extern(C) extern __gshared uint[irq_max] __clic_vectors; +extern(C) extern void _clic_dispatch(); + +unittest // CSR + vector-table state proves the CLIC trap path is wired +{ + // mtvt (CSR 0x307) must point at __clic_vectors. If this fails, the + // CSR number is wrong, the table moved, or start.S didn't reach the + // csrw -- every IRQ would dispatch through whatever happens to be at + // mtvt[id] (often address 0, which is what cost us two days). + uint mtvt_csr; + asm @nogc nothrow { "csrr %0, 0x307" : "=r" (mtvt_csr); } + assert(mtvt_csr == cast(uint)cast(size_t)&__clic_vectors[0], + "mtvt CSR does not point at __clic_vectors -- IRQs would vector through garbage"); + + // mtvec.MODE = 0b11 = CLIC mode. MODE 01 (vectored) would route IRQs + // through mtvec.base, where our _trap_exception sits -- it expects + // sync traps, not IRQs, and would dump-and-spin on every fire. + uint mtvec_csr; + asm @nogc nothrow { "csrr %0, mtvec" : "=r" (mtvec_csr); } + assert((mtvec_csr & 0x3) == 0x3, "mtvec MODE != 0b11 (CLIC)"); + + // T-Head mexstatus.SPUSHEN | SPSWAPEN (bits 16/17 of CSR 0x7E1). Without + // these, th.ipush / th.ipop are silent no-ops; the first nested IRQ + // clobbers the outer's mepc and mret returns to the wrong PC. + uint mexstatus; + asm @nogc nothrow { "csrr %0, 0x7E1" : "=r" (mexstatus); } + assert((mexstatus & 0x30000) == 0x30000, + "mexstatus.SPUSHEN|SPSWAPEN not set -- nested IRQs will corrupt mepc"); + + // Every live vector-table slot must dispatch through _clic_dispatch. + // A wrong entry would mean that specific IRQ id silently jumps into + // garbage or some unrelated handler. + uint expected = cast(uint)cast(size_t)&_clic_dispatch; + foreach (uint i; 0 .. irq_max) + assert(__clic_vectors[i] == expected, + "__clic_vectors entry doesn't point at _clic_dispatch"); +} + + +// ==================================================================== +// Force-IP CLIC plumbing (vector-agnostic; no peripheral needed) +// ==================================================================== +// +// The force-IP tests below are conditional. On BL808 M0 the CLIC IP byte +// appears to reflect peripheral pending state, but software writes to IP do +// not latch for otherwise-idle lines: IRQ3, IRQ12, IRQ16, and IRQ17 all read +// back 0 after an IP=1 write. Real peripheral delivery is still covered by +// the live mtime IRQ test below. + +enum uint force_test_vec = 16; +enum uint force_alt_vec = 17; + +__gshared uint _clic_probe_calls; +__gshared uint _clic_alt_probe_calls; +__gshared bool _force_ip_probe_done; +__gshared bool _force_ip_writable; + +void _clic_probe_handler(uint irq) @nogc nothrow +{ + ++_clic_probe_calls; + // Clear IP so a level-triggered re-fire can't loop us; the test source + // is just our IP=1 write, no peripheral to drain. + volatileStore(clicint_byte(irq, ip_offset), ubyte(0)); +} + +void _clic_alt_probe_handler(uint irq) @nogc nothrow +{ + ++_clic_alt_probe_calls; + volatileStore(clicint_byte(irq, ip_offset), ubyte(0)); +} + +// Hold mstatus.MIE off for the duration of the call so we can scribble on +// CLIC state without an in-flight IRQ landing mid-setup. Returns the prev +// state so the caller can restore it before testing delivery. +bool _quiesce_irq() +{ + return disable_interrupts(); +} + +void _spin_for_delivery() +{ + // ~50k nops at our running clock -- generous compared to the handful + // of cycles between IP=1 and dispatch on real hardware. + foreach (uint i; 0 .. 50_000) + asm @nogc nothrow { "nop"; } +} + +bool _force_ip_available() +{ + if (_force_ip_probe_done) + return _force_ip_writable; + + bool was_globally_on = disable_interrupts(); + ubyte prev_ip = volatileLoad(clicint_byte(force_test_vec, ip_offset)); + ubyte prev_ie = volatileLoad(clicint_byte(force_test_vec, ie_offset)); + ubyte prev_ctl = volatileLoad(clicint_byte(force_test_vec, ctl_offset)); + irq_set_enable(force_test_vec); + volatileStore(clicint_byte(force_test_vec, ip_offset), ubyte(0)); + volatileStore(clicint_byte(force_test_vec, ip_offset), ubyte(1)); + _force_ip_writable = (volatileLoad(clicint_byte(force_test_vec, ip_offset)) & 1) != 0; + volatileStore(clicint_byte(force_test_vec, ip_offset), prev_ip); + volatileStore(clicint_byte(force_test_vec, ie_offset), prev_ie); + volatileStore(clicint_byte(force_test_vec, ctl_offset), prev_ctl); + if (was_globally_on) + enable_interrupts(); + _force_ip_probe_done = true; + return _force_ip_writable; +} + +unittest // positive: IE=1, CTL>=lsb, MIE=1 -- handler runs, histogram increments +{ + if (!_force_ip_available()) + return; + + enum uint test_vec = force_test_vec; + + _clic_probe_calls = 0; + uint hist_before = irq_histogram[test_vec]; + + auto prev_handler = irq_set_handler(test_vec, &_clic_probe_handler); + scope (exit) irq_set_handler(test_vec, prev_handler); + + bool was_globally_on = enable_interrupts(); + bool was_line_on = irq_set_enable(test_vec); + scope (exit) + { + irq_clear_enable(test_vec); + if (!was_globally_on) + disable_interrupts(); + if (was_line_on) + irq_set_enable(test_vec); + } + + // Confirm the auto-bump landed -- if CTL stayed 0, dispatch would never + // happen (T-Head CLIC quirk) and we'd report a misleading delivery + // failure instead of "CTL bump is broken". + ubyte ctl_after = volatileLoad(clicint_byte(test_vec, ctl_offset)); + if (ctl_after < _clic_ctl_lsb) + { + import urt.io : writef; + writef("[irq-test vec={0} ctl_after={1,02X} clic_ctl_lsb={2,02X}]", + test_vec, ctl_after, _clic_ctl_lsb); + assert(false, "irq_set_enable failed to bump CLICINTCTL above zero"); + } + + volatileStore(clicint_byte(test_vec, ip_offset), ubyte(1)); + _spin_for_delivery(); + + if (_clic_probe_calls == 0) + { + import urt.io : writef; + writef("[irq-test-fail vec={0} calls={1} hist={2}->{3}]", + test_vec, _clic_probe_calls, hist_before, irq_histogram[test_vec]); + + enum uint alt_vec = force_alt_vec; + _clic_alt_probe_calls = 0; + uint alt_hist_before = irq_histogram[alt_vec]; + auto prev_alt_handler = irq_set_handler(alt_vec, &_clic_alt_probe_handler); + bool alt_was_line_on = irq_set_enable(alt_vec); + volatileStore(clicint_byte(alt_vec, ip_offset), ubyte(0)); + volatileStore(clicint_byte(alt_vec, ip_offset), ubyte(1)); + _spin_for_delivery(); + writef("[irq-alt-probe vec={0} calls={1} hist={2}->{3} was_on={4}]", + alt_vec, _clic_alt_probe_calls, alt_hist_before, irq_histogram[alt_vec], + alt_was_line_on ? 1 : 0); + volatileStore(clicint_byte(alt_vec, ip_offset), ubyte(0)); + irq_clear_enable(alt_vec); + if (alt_was_line_on) + irq_set_enable(alt_vec); + irq_set_handler(alt_vec, prev_alt_handler); + } + + assert(_clic_probe_calls >= 1, + "CLIC did not dispatch force-pended IRQ to handler"); + assert(irq_histogram[test_vec] > hist_before, + "_irq_dispatch did not record the force-pended IRQ in irq_histogram"); +} + +unittest // negative: IE=0 must swallow force-IP +{ + if (!_force_ip_available()) + return; + + enum uint test_vec = force_test_vec; + + _clic_probe_calls = 0; + + auto prev_handler = irq_set_handler(test_vec, &_clic_probe_handler); + scope (exit) irq_set_handler(test_vec, prev_handler); + + // Quiesce, then manually stage CTL>=lsb + IE=0 + MIE=1. If the gate + // is real, dispatch is impossible from here regardless of IP. + bool was_globally_on = _quiesce_irq(); + volatileStore(clicint_byte(test_vec, ctl_offset), _clic_ctl_lsb); + irq_clear_enable(test_vec); + enable_interrupts(); + scope (exit) + { + volatileStore(clicint_byte(test_vec, ip_offset), ubyte(0)); + irq_clear_enable(test_vec); + if (!was_globally_on) + disable_interrupts(); + } + + volatileStore(clicint_byte(test_vec, ip_offset), ubyte(1)); + _spin_for_delivery(); + + assert(_clic_probe_calls == 0, + "IE=0 did not gate delivery -- per-line enable is broken"); +} + +unittest // negative: CTL=0 must swallow force-IP even with IE=1, MIE=1 +{ + if (!_force_ip_available()) + return; + + // This test directly exercises the T-Head "priority 0 = silently + // dropped" behaviour. If it fails (handler fires), the auto-bump in + // irq_set_enable is unnecessary -- but more likely, something below + // us has rewritten CLICINTCTL[i] and broken the assumption. + enum uint test_vec = force_test_vec; + + _clic_probe_calls = 0; + + auto prev_handler = irq_set_handler(test_vec, &_clic_probe_handler); + scope (exit) irq_set_handler(test_vec, prev_handler); + + bool was_globally_on = _quiesce_irq(); + volatileStore(clicint_byte(test_vec, ctl_offset), ubyte(0)); + volatileStore(clicint_byte(test_vec, ie_offset), ubyte(1)); + enable_interrupts(); + scope (exit) + { + volatileStore(clicint_byte(test_vec, ip_offset), ubyte(0)); + irq_clear_enable(test_vec); + if (!was_globally_on) + disable_interrupts(); + } + + volatileStore(clicint_byte(test_vec, ip_offset), ubyte(1)); + _spin_for_delivery(); + + assert(_clic_probe_calls == 0, + "CTL=0 did not gate delivery -- T-Head priority-0 quirk no longer holds, or our model is wrong"); +} + +unittest // negative: MIE=0 must swallow force-IP even with IE=1, CTL>0 +{ + if (!_force_ip_available()) + return; + + enum uint test_vec = force_test_vec; + + _clic_probe_calls = 0; + + auto prev_handler = irq_set_handler(test_vec, &_clic_probe_handler); + scope (exit) irq_set_handler(test_vec, prev_handler); + + bool was_line_on = irq_set_enable(test_vec); + bool was_globally_on = disable_interrupts(); + scope (exit) + { + volatileStore(clicint_byte(test_vec, ip_offset), ubyte(0)); + irq_clear_enable(test_vec); + if (was_line_on) + irq_set_enable(test_vec); + if (was_globally_on) + enable_interrupts(); + } + + volatileStore(clicint_byte(test_vec, ip_offset), ubyte(1)); + _spin_for_delivery(); + + assert(_clic_probe_calls == 0, + "MIE=0 did not gate delivery -- mstatus.MIE handling is broken"); +} + + +// ==================================================================== +// Routing: two vectors, two handlers, each fires its own +// ==================================================================== + +__gshared uint _route_calls_a; +__gshared uint _route_calls_b; +__gshared uint _route_irq_seen_a; +__gshared uint _route_irq_seen_b; + +void _route_handler_a(uint irq) @nogc nothrow +{ + ++_route_calls_a; + _route_irq_seen_a = irq; + volatileStore(clicint_byte(irq, ip_offset), ubyte(0)); +} + +void _route_handler_b(uint irq) @nogc nothrow +{ + ++_route_calls_b; + _route_irq_seen_b = irq; + volatileStore(clicint_byte(irq, ip_offset), ubyte(0)); +} + +unittest // mtvt[a] and mtvt[b] independently route to their own handler +{ + if (!_force_ip_available()) + return; + + enum uint vec_a = force_test_vec; + enum uint vec_b = force_alt_vec; + + _route_calls_a = 0; + _route_calls_b = 0; + _route_irq_seen_a = ~0u; + _route_irq_seen_b = ~0u; + + auto prev_a = irq_set_handler(vec_a, &_route_handler_a); + auto prev_b = irq_set_handler(vec_b, &_route_handler_b); + scope (exit) + { + irq_set_handler(vec_a, prev_a); + irq_set_handler(vec_b, prev_b); + } + + bool was_globally_on = enable_interrupts(); + bool was_a_on = irq_set_enable(vec_a); + bool was_b_on = irq_set_enable(vec_b); + scope (exit) + { + irq_clear_enable(vec_a); + irq_clear_enable(vec_b); + if (!was_globally_on) + disable_interrupts(); + if (was_a_on) irq_set_enable(vec_a); + if (was_b_on) irq_set_enable(vec_b); + } + + volatileStore(clicint_byte(vec_a, ip_offset), ubyte(1)); + _spin_for_delivery(); + volatileStore(clicint_byte(vec_b, ip_offset), ubyte(1)); + _spin_for_delivery(); + + assert(_route_calls_a == 1, "handler A fired wrong number of times"); + assert(_route_calls_b == 1, "handler B fired wrong number of times"); + assert(_route_irq_seen_a == vec_a, "handler A dispatched with wrong vector id"); + assert(_route_irq_seen_b == vec_b, "handler B dispatched with wrong vector id"); +} + + +// ==================================================================== +// Live hardware trap (mtime -> CLIC IRQ #7 -> th.ipush trampoline) +// ==================================================================== +// +// Force-IP exercises the CLIC, but not the timer hardware and not the +// nested-IRQ safety property of th.ipush / th.ipop. This test arms a +// real mtimecmp fire and asserts both that the handler ran AND that a +// caller-saved register survived the trap. A bare sw/lw trampoline (no +// ipush) would silently corrupt t0 here and the test would fail with a +// clearly-attributed message. + +__gshared uint _timer_magic; + +void _timer_trap_probe_handler(uint /+irq+/) @nogc nothrow +{ + _timer_magic = 0xCAFE_F00D; + auto mtimecmp = cast(ulong*)cast(size_t)0xE000_4000; + volatileStore(mtimecmp, ulong.max); // disarm so we don't re-fire mid-cleanup +} + +unittest // mtime fires IRQ #7, _clic_dispatch preserves caller-saved t0 +{ + import urt.driver.bl618.timer : mtime_read; + + _timer_magic = 0; + uint hist_before = irq_histogram[IrqClass.timer]; + + auto prev_handler = irq_set_handler(IrqClass.timer, &_timer_trap_probe_handler); + scope (exit) irq_set_handler(IrqClass.timer, prev_handler); + + auto mtimecmp = cast(ulong*)cast(size_t)0xE000_4000; + volatileStore(mtimecmp, mtime_read() + 1_000); // 1ms at 1MHz mtime + + bool was_globally_on = enable_interrupts(); + bool was_irq7_on = irq_set_enable(IrqClass.timer); + scope (exit) + { + irq_clear_enable(IrqClass.timer); + if (!was_globally_on) + disable_interrupts(); + if (was_irq7_on) + irq_set_enable(IrqClass.timer); + } + + // Hold a known pattern in t0 across the spin. If th.ipush / th.ipop + // drops t0 (the most likely failure for caller-saved restore), the + // post-loop read shows the wrong value. Inline asm because nothing at + // D level can keep a value in a specific GPR across a function call. + // 1M iterations is plenty of grace past the 1ms mtime fire. + uint t0_after; + asm @nogc nothrow + { + ` + li t0, 0x12345678 + li t4, 1000000 + 1: + lw t1, %1 + li t2, 0xCAFEF00D + beq t1, t2, 2f + addi t4, t4, -1 + bnez t4, 1b + 2: + mv %0, t0 + ` + : "=r" (t0_after) + : "m" (_timer_magic) + : "t0", "t1", "t2", "t4", "memory"; + } + + if (_timer_magic != 0xCAFE_F00D || irq_histogram[IrqClass.timer] <= hist_before) + { + import urt.io : writef; + writef("[irq-timer-probe magic={0,08X} hist={1}->{2} t0={3,08X}]", + _timer_magic, hist_before, irq_histogram[IrqClass.timer], t0_after); + } + + assert(_timer_magic == 0xCAFE_F00D, "machine timer IRQ did not fire -- mtime/mtimecmp path broken"); + assert(t0_after == 0x12345678, + "caller-saved t0 clobbered across IRQ trap -- th.ipush/ipop not preserving GPRs"); + assert(irq_histogram[IrqClass.timer] > hist_before, + "_irq_dispatch did not record the timer trap in irq_histogram"); +} diff --git a/src/urt/driver/bl618/package.d b/src/urt/driver/bl618/package.d new file mode 100644 index 0000000..fdb5d92 --- /dev/null +++ b/src/urt/driver/bl618/package.d @@ -0,0 +1,11 @@ +// BL618 platform package (T-Head E907 RV32IMAFC). +// +// Re-exports the chip's peripheral drivers. sys_init lives in +// urt.driver.bl_common.system and is shared with BL808 M0 / D0. +module urt.driver.bl618; + +public import urt.driver.bl618.uart; +public import urt.driver.bl618.irq; +public import urt.driver.bl618.timer; +public import urt.driver.bl_common.trng; +public import urt.driver.bl_common.system; diff --git a/src/urt/driver/bl618/start.S b/src/urt/driver/bl618/start.S new file mode 100644 index 0000000..61a9c3a --- /dev/null +++ b/src/urt/driver/bl618/start.S @@ -0,0 +1,299 @@ +/* BL618 (T-Head E907 RV32IMAFC) startup + * + * Single-core startup -- no M0 handshake needed (unlike BL808). + * + * Boot flow: + * 1. CPU setup -- disable IRQ, enable extensions, FPU, trap vectors + * 2. Core regs -- gp, tp, sp + * 3. Section init -- .got, .tdata, .tbss, .bss, .data + * 4. Caches -- I-cache enable + * 5. Interrupts -- CLIC init, enable MIE + * 6. D runtime -- sys_init, .init_array, main + * + * T-Head custom CSR numbers: + * mxstatus = 0x7C0 (T-Head ISA extension enable) + * mhcr = 0x7C1 (hardware cache control) + * mhint = 0x7C5 (performance hints) + * mtvt = 0x307 (CLIC vector table base -- standard RISC-V CLIC) + * + * Trap dispatch: mtvec in CLIC mode (bits[1:0]=11) with base = _trap_exception + * for sync traps. IRQs go through mtvt[id] -- a flat .word table of handler + * addresses (here, every entry points at _clic_dispatch, the universal + * ipush/ipop trampoline). See urt.driver.bl618.irq for the runtime side. + */ +#define CSR_MXSTATUS 0x7C0 +#define CSR_MHCR 0x7C1 +#define CSR_MHINT 0x7C5 +#define CSR_MTVT 0x307 + + .section .text.entry, "ax" + .global _start + .type _start, @function + .align 2 + +_start: + /* -- 1. CPU setup ---------------------------------------------- */ + + csrc mstatus, 0x0008 /* clear MIE */ + + /* Enable T-Head ISA extensions (THEADISAEE + MM) */ + li t0, (1 << 22) | (1 << 15) + csrs CSR_MXSTATUS, t0 + + /* Enable FPU (FS = Initial) -- E907 has single-precision FPU */ + li t0, (1 << 13) + csrs mstatus, t0 + + /* mtvec in CLIC mode (mode 11). base = sync-trap handler; IRQs are + * dispatched via mtvt[id], not mtvec.base. */ + la t0, _trap_exception + ori t0, t0, 3 + csrw mtvec, t0 + + la t0, __clic_vectors + csrw CSR_MTVT, t0 + + /* -- 2. Core registers ----------------------------------------- */ + + .option push + .option norelax + la gp, __global_pointer$ + .option pop + la tp, _tdata_start + la sp, _stack_top + + /* -- 3. Section init ------------------------------------------- */ + + la a0, _ramfunc_start + la a1, _ramfunc_load + la a2, _ramfunc_end + bgeu a0, a2, .Lramfunc_done +.Lramfunc_copy: + lw t0, 0(a1) + sw t0, 0(a0) + addi a0, a0, 4 + addi a1, a1, 4 + bltu a0, a2, .Lramfunc_copy +.Lramfunc_done: + + la a0, _got_start + la a1, _got_load + la a2, _got_end + bgeu a0, a2, .Lgot_done +.Lgot_copy: + lw t0, 0(a1) + sw t0, 0(a0) + addi a0, a0, 4 + addi a1, a1, 4 + bltu a0, a2, .Lgot_copy +.Lgot_done: + + la a0, _sram_data_start + la a1, _sram_data_load + la a2, _sram_data_end + bgeu a0, a2, .Lsram_data_done +.Lsram_data_copy: + lw t0, 0(a1) + sw t0, 0(a0) + addi a0, a0, 4 + addi a1, a1, 4 + bltu a0, a2, .Lsram_data_copy +.Lsram_data_done: + + la a0, _tdata_start + la a1, _tdata_load + la a2, _tdata_end + bgeu a0, a2, .Ltdata_done +.Ltdata_copy: + lw t0, 0(a1) + sw t0, 0(a0) + addi a0, a0, 4 + addi a1, a1, 4 + bltu a0, a2, .Ltdata_copy +.Ltdata_done: + + la a0, _tbss_start + la a2, _tbss_end + bgeu a0, a2, .Ltbss_done +.Ltbss_zero: + sw zero, 0(a0) + addi a0, a0, 4 + bltu a0, a2, .Ltbss_zero +.Ltbss_done: + + la a0, _data_start + la a1, _data_load + la a2, _data_end + bgeu a0, a2, .Ldata_done +.Ldata_copy: + lw t0, 0(a1) + sw t0, 0(a0) + addi a0, a0, 4 + addi a1, a1, 4 + bltu a0, a2, .Ldata_copy +.Ldata_done: + + la a0, _bss_start + la a2, _bss_end + bgeu a0, a2, .Lbss_done +.Lbss_zero: + sw zero, 0(a0) + addi a0, a0, 4 + bltu a0, a2, .Lbss_zero +.Lbss_done: + + /* -- 4. Caches ------------------------------------------------- */ + + /* TODO: D-cache and branch prediction OFF -- we set only IE (bit 0). + * Vendor enables MHCR=0x103F (DE | WB | WA | RS | BPE | L0BTB) and + * MHINT=0x0C for D$ prefetch. Pure perf cost (~10x slower data on + * OCRAM/PSRAM, branches stall), visible under real traffic. Before + * flipping, configure SYSMAP CSRs so MMIO / DMA regions are + * uncacheable -- otherwise stale IPC reads / invisible DMA writes. */ + li t0, (1 << 0) /* I-cache enable */ + csrs CSR_MHCR, t0 + + /* -- 5. D runtime ---------------------------------------------- */ + /* IRQ bring-up + mstatus.MIE enable live in sys_init via irq_init() + + * irq_global_enable(). Keeping MIE off through the D ctor chain rules + * out spurious IRQs before subsystems are wired. */ + + call sys_init + + la s0, __init_array_start + la s1, __init_array_end + bgeu s0, s1, .Linit_done +.Linit_loop: + lw t0, 0(s0) + jalr t0 + addi s0, s0, 4 + bltu s0, s1, .Linit_loop +.Linit_done: + + /* Enter main -- urt/package.d's extern(C) main(int argc, char** argv). + * argc=0/argv=null so the D-side _Dmain sees an empty args slice. + * Zero fp so backtraces terminate cleanly at main; zero ra so a return + * from main traps (caught by _crash_handler). */ + li a0, 0 + li a1, 0 + li s0, 0 + li ra, 0 + j main + + .size _start, . - _start + + +/* -- CLIC vector table -- flat .word handler addresses -------------- + * + * Each entry is the address the CPU jumps to when CLIC dispatches the + * matching IRQ id. We point everything at _clic_dispatch so a single + * trampoline handles every line; the dispatcher reads mcause to learn + * which IRQ fired and looks up the registered handler in D-side state. + * + * Size must match urt.driver.bl618.irq.irq_max. */ + .section .rodata, "a" + .align 6 + .global __clic_vectors +__clic_vectors: + .rept 80 + .word _clic_dispatch + .endr + + +/* -- IRQ dispatch stub ---------------------------------------------- + * + * Entered from the CLIC hardware vector via mtvt[id]. The T-Head ipush + * instruction pushes caller-saved GPRs + mepc + mcause onto the stack + * (using mscratch as the IRQ stack pointer if non-zero). We clear MIE + * immediately so a single driver round-trip never nests until we've + * earned the right to. + * + * ipop pops everything and issues mret with hardware tail-chain. The + * mepc / mcause CSRs are restored from the stack, which is what makes + * nesting safe (vs a plain mret reading the live CSR, which a nested + * IRQ would have clobbered). */ + .section .text, "ax" + .align 2 + .global _clic_dispatch + .type _clic_dispatch, @function + .option push + .option arch, +xtheadint +_clic_dispatch: + th.ipush + csrci mstatus, 0x8 + csrr a0, mcause + andi a0, a0, 0x3FF + call _irq_dispatch + th.ipop + .size _clic_dispatch, . - _clic_dispatch + .option pop + + +/* -- Sync-trap (exception) handler ---------------------------------- + * + * mtvec.base in CLIC mode lands here for exceptions only (IRQs go through + * mtvt[id] above). Snapshot all GPRs into a stack frame matching the + * regs[] layout expected by bl_common.exception._crash_handler, then dump + * and spin. mtvec is redirected to a no-op so a double-fault here doesn't + * recurse. */ + .section .text, "ax" + .align 2 + .global _trap_exception + .type _trap_exception, @function +_trap_exception: + la t0, .Lcrash_spin2 + csrw mtvec, t0 + + addi sp, sp, -128 + sw ra, 0(sp) + sw sp, 4(sp) + sw gp, 8(sp) + sw tp, 12(sp) + sw t0, 16(sp) + sw t1, 20(sp) + sw t2, 24(sp) + sw s0, 28(sp) + sw s1, 32(sp) + sw a0, 36(sp) + sw a1, 40(sp) + sw a2, 44(sp) + sw a3, 48(sp) + sw a4, 52(sp) + sw a5, 56(sp) + sw a6, 60(sp) + sw a7, 64(sp) + sw s2, 68(sp) + sw s3, 72(sp) + sw s4, 76(sp) + sw s5, 80(sp) + sw s6, 84(sp) + sw s7, 88(sp) + sw s8, 92(sp) + sw s9, 96(sp) + sw s10,100(sp) + sw s11,104(sp) + sw t3, 108(sp) + sw t4, 112(sp) + sw t5, 116(sp) + sw t6, 120(sp) + + addi t0, sp, 128 + sw t0, 4(sp) + + mv a0, sp + csrr a1, mcause + csrr a2, mepc + csrr a3, mtval + + call _crash_handler + +.Lcrash_spin: + wfi + j .Lcrash_spin + + .align 2 +.Lcrash_spin2: + wfi + j .Lcrash_spin2 + + .size _trap_exception, . - _trap_exception diff --git a/src/urt/driver/bl618/syscalls.d b/src/urt/driver/bl618/syscalls.d new file mode 100644 index 0000000..a14f8fe --- /dev/null +++ b/src/urt/driver/bl618/syscalls.d @@ -0,0 +1,56 @@ +/// BL618 newlib/picolibc syscall stubs +/// +/// Minimal stubs to satisfy picolibc's syscall requirements. +/// Same pattern as BL808 - most are no-ops for baremetal. +module urt.driver.bl618.syscalls; + +@nogc nothrow: + +private extern(C) extern __gshared { + pragma(mangle, "__heap_start") void* _heap_start_ptr; + pragma(mangle, "__heap_end") void* _heap_end_ptr; +} + +private __gshared void* _heap_ptr; + +extern(C) void* _sbrk(ptrdiff_t incr) +{ + if (_heap_ptr is null) + _heap_ptr = cast(void*)&_heap_start_ptr; + + void* prev = _heap_ptr; + void* next = _heap_ptr + incr; + + if (next > cast(void*)&_heap_end_ptr) + return cast(void*)-1; + + _heap_ptr = next; + return prev; +} + +extern(C) int _write(int fd, const void* buf, size_t count) +{ + import urt.driver.bl618.uart : uart0_hw_puts; + if (fd == 1 || fd == 2) + uart0_hw_puts((cast(const(char)*) buf)[0 .. count]); + return cast(int) count; +} + +extern(C) int _read(int, void*, size_t) { return 0; } +extern(C) int _close(int) { return -1; } +extern(C) int _lseek(int, int, int) { return 0; } +extern(C) int _fstat(int, void*) { return 0; } +extern(C) int _isatty(int) { return 1; } +extern(C) void _exit(int) { while (true) {} } +extern(C) int _kill(int, int) { return -1; } +extern(C) int _getpid() { return 1; } + +// Picolibc's time() routes through gettimeofday(). Stubbed to "epoch" +// here -- callers that need wall-clock time should use the RTC/HBN path. +extern(C) int gettimeofday(void* tv, void* tz) { return 0; } + +// printf override: drop content. Wifi blob pulls printf transitively; +// routing through libc would drag stdout/vfprintf. We tried dumping the +// fmt string verbatim once -- mbedtls is a printf caller and its trace +// volume blocked the ecdh test. Silent return is what works. +extern(C) int printf(const(char)*, ...) { return 0; } diff --git a/src/urt/driver/bl618/timer.d b/src/urt/driver/bl618/timer.d new file mode 100644 index 0000000..cc87200 --- /dev/null +++ b/src/urt/driver/bl618/timer.d @@ -0,0 +1,214 @@ +// BL618 / BL808 M0 (E907) timer driver +// +// T-Head E907 (RV32IMAFC) has standard RISC-V mtime/mtimecmp exposed via the +// CORET block at 0xE0004000 (NOT the CLIC region at 0xE0800000 -- the two +// are separate peripherals on E907). MTIMECMP is at offset 0x000, MTIME at +// 0x7FFC. mtime runs at 1 MHz from the AON clock. +// +// Timer IRQ delivery is via CLIC line 7 (machine timer cause). The dispatch +// table in urt.driver.bl618.irq routes it here through _timer_irq_handler. +module urt.driver.bl618.timer; + +import core.volatile; +import urt.driver.bl618.irq : IrqClass, IrqHandler, + irq_set_enable, irq_clear_enable, + irq_set_handler, + enable_interrupts, disable_interrupts, + irq_count, irq_histogram; + +@nogc nothrow: + +enum uint mtime_freq_hz = 1_000_000; +enum bool has_mtime = true; +enum bool has_rtc = false; +enum bool has_mcycle = false; +enum bool has_timer_stop = true; +enum bool has_oneshot_timer = true; + +ulong mtime_read() +{ + uint hi1, lo, hi2; + do + { + asm @nogc nothrow { "rdtimeh %0" : "=r" (hi1); } + asm @nogc nothrow { "rdtime %0" : "=r" (lo); } + asm @nogc nothrow { "rdtimeh %0" : "=r" (hi2); } + } + while (hi1 != hi2); + return (ulong(hi1) << 32) | lo; +} + +alias TimerCallback = void function() @nogc nothrow; + +void timer_set_periodic(uint period_us, TimerCallback cb) +{ + tick_interval = period_us; + tick_callback = cb; + + irq_set_handler(IrqClass.timer, &_timer_irq_handler); + irq_set_enable(IrqClass.timer); + mtimecmp_write_oneshot(mtime_read() + period_us); +} + +void timer_stop() +{ + irq_clear_enable(IrqClass.timer); + irq_set_handler(IrqClass.timer, null); + mtimecmp_write_oneshot(ulong.max); + tick_callback = null; + tick_interval = 0; +} + +void _timer_irq_handler(uint /+irq+/) +{ + if (tick_interval > 0) + mtimecmp_write_oneshot(mtime_read() + tick_interval); + if (tick_callback !is null) + tick_callback(); +} + +// Schedule a single mtime fire at the given absolute tick. Used by +// urt.system.sleep for WFI-based wakeup, and by the common oneshot tests. +// Pass ulong.max to park the comparator (cancel). +void mtimecmp_write_oneshot(ulong value) +{ + auto lo = cast(uint*)cast(size_t)MTIMECMP_LO; + auto hi = cast(uint*)cast(size_t)MTIMECMP_HI; + + // Park high at 0xFFFFFFFF before touching low, so a stale low doesn't + // briefly match an old high and fire a spurious IRQ. + volatileStore(hi, 0xFFFF_FFFF); + volatileStore(lo, cast(uint)(value & 0xFFFF_FFFF)); + volatileStore(hi, cast(uint)(value >> 32)); +} + + +private: + +// T-Head E907 CORET (mtime / mtimecmp). Separate peripheral from CLIC. +enum uint CORET_BASE = 0xE000_4000; +enum uint MTIMECMP_LO = CORET_BASE + 0x0000; +enum uint MTIMECMP_HI = CORET_BASE + 0x0004; + +__gshared TimerCallback tick_callback; +__gshared uint tick_interval; + +ulong mtimecmp_read() +{ + auto lo = cast(uint*)cast(size_t)MTIMECMP_LO; + auto hi = cast(uint*)cast(size_t)MTIMECMP_HI; + + uint h1 = volatileLoad(hi); + uint l = volatileLoad(lo); + uint h2 = volatileLoad(hi); + if (h1 != h2) + l = volatileLoad(lo); + return (ulong(h2) << 32) | l; +} + + +// ==================================================================== +// Tests +// ==================================================================== + +unittest // mtime register advances +{ + ulong t0 = mtime_read(); + foreach (uint i; 0 .. 10_000) + asm @nogc nothrow { "nop"; } + ulong t1 = mtime_read(); + assert(t1 > t0, "mtime did not advance across a nop spin"); +} + +__gshared uint _periodic_test_calls; + +void _periodic_test_callback() @nogc nothrow +{ + ++_periodic_test_calls; +} + +unittest // periodic timer fires its callback repeatedly via the real IRQ path +{ + // Snapshot the live periodic config (sys_init installed a 50ms tick) so + // we can restore it after the test. + TimerCallback prev_cb = tick_callback; + uint prev_interval = tick_interval; + + timer_stop(); + + _periodic_test_calls = 0; + + // Snapshot dispatch counters BEFORE arming the test timer. The pair + // (irq_count, irq_histogram[7]) gives us proof that any callback + // increments below actually came through _irq_dispatch -- a path + // that bypassed dispatch (memory corruption, wrong handler table, + // somebody else calling our callback) would advance _periodic_test_calls + // without advancing these. + uint irq_count_before = irq_count; + uint hist7_before = irq_histogram[IrqClass.timer]; + + // 200us period -- short enough that ~2ms of waiting gets us a healthy + // ten-ish fires (test stays imperceptible), still long enough that + // handler entry/exit + re-arm don't pile up on themselves. + timer_set_periodic(200, &_periodic_test_callback); + scope (exit) + { + timer_stop(); + if (prev_cb !is null && prev_interval > 0) + timer_set_periodic(prev_interval, prev_cb); + } + + bool was_globally_on = enable_interrupts(); + scope (exit) if (!was_globally_on) disable_interrupts(); + + // Wait ~2ms. At 200us period we expect ~10 callback invocations; allow + // a floor of 5 to absorb IRQ latency / first-arm jitter. + ulong start = mtime_read(); + while (mtime_read() - start < 2_000) + asm @nogc nothrow { "nop"; } + + assert(_periodic_test_calls >= 5, + "periodic timer callback fired too few times -- IRQ delivery or re-arm broken"); + assert(irq_count > irq_count_before, + "_irq_dispatch never ran -- callback fired by some other path"); + assert(irq_histogram[IrqClass.timer] - hist7_before >= _periodic_test_calls, + "timer-vector histogram didn't advance with callback count -- dispatch is routing wrong vector"); +} + +unittest // timer_stop disarms -- no further callbacks after stop +{ + TimerCallback prev_cb = tick_callback; + uint prev_interval = tick_interval; + + timer_stop(); + + _periodic_test_calls = 0; + + timer_set_periodic(200, &_periodic_test_callback); // 200us + scope (exit) + { + timer_stop(); + if (prev_cb !is null && prev_interval > 0) + timer_set_periodic(prev_interval, prev_cb); + } + + bool was_globally_on = enable_interrupts(); + scope (exit) if (!was_globally_on) disable_interrupts(); + + // Let it tick a few times -- 1ms at 200us = ~5 fires + ulong start = mtime_read(); + while (mtime_read() - start < 1_000) + asm @nogc nothrow { "nop"; } + assert(_periodic_test_calls > 0, "timer never fired before stop"); + + timer_stop(); + uint after_stop = _periodic_test_calls; + + // Wait another 1ms -- count must NOT advance after stop + ulong stop_t = mtime_read(); + while (mtime_read() - stop_t < 1_000) + asm @nogc nothrow { "nop"; } + + assert(_periodic_test_calls == after_stop, + "timer fired after timer_stop -- IRQ not actually disabled"); +} diff --git a/src/urt/driver/bl618/uart.d b/src/urt/driver/bl618/uart.d new file mode 100644 index 0000000..edb278f --- /dev/null +++ b/src/urt/driver/bl618/uart.d @@ -0,0 +1,528 @@ +// BL618 / BL808-M0 UART driver +// +// Two UART peripherals share the same register-level IP block as BL808 D0: +// +// UART0 0x2000_A000 MCU domain default console (COM7 via BL702 bridge) +// UART1 0x2000_A100 MCU domain general purpose +// +// Used by both BL618 (single-core E907) and the BL808 M0 coprocessor. Both +// chips own the same UART0/1 instances in the MCU power domain. UART2/UART3 +// exist on BL808 but live in the MM domain (D0's side); not exposed here. +// +// Polled only. Interrupts on the E907 go through the CLIC, and OpenWatt's +// shared CLIC IRQ dispatch isn't wired up yet, so uart_hw_poll() must be +// called from the main loop. +// +// Early-boot path: m0_bringup() (and equivalently the BL618 start) can call +// uart0_early_init(tx_pin, rx_pin, baud) before sys_init runs, then use +// uart0_putc / uart0_puts / uart0_hex to emit progress markers from raw +// register writes. The full uart_hw_open() comes later from serial.d and +// re-applies pin config harmlessly. +module urt.driver.bl618.uart; + +import core.volatile; + +import urt.attribute : fast_data; +import urt.driver.uart : Parity, StopBits, UartConfig; + +nothrow @nogc: + + +// ---------------------------------------------------------------------------- +// Register definitions +// ---------------------------------------------------------------------------- + +enum num_uarts = 2; +enum uint uart_clock_hz = 40_000_000; +enum bool has_irq_driven_uart = false; +enum bool has_dma_driven_uart = false; + +private immutable uint[num_uarts] uart_base = [ + 0x2000_A000, // UART0 + 0x2000_A100, // UART1 +]; + +private enum : uint +{ + UTX_CONFIG = 0x00, + URX_CONFIG = 0x04, + BIT_PRD = 0x08, + DATA_CONFIG = 0x0C, + URX_RTO_TIMER = 0x18, + SW_MODE = 0x1C, + INT_STS = 0x20, + INT_MASK = 0x24, + INT_CLEAR = 0x28, + INT_EN = 0x2C, + STATUS = 0x30, + FIFO_CONFIG_0 = 0x80, + FIFO_CONFIG_1 = 0x84, + FIFO_WDATA = 0x88, + FIFO_RDATA = 0x8C, +} + +// UTX_CONFIG (0x00) +private enum : uint +{ + CR_UTX_EN = 1 << 0, + CR_UTX_FRM_EN = 1 << 2, + CR_UTX_PRT_EN = 1 << 4, + CR_UTX_PRT_SEL = 1 << 5, // 0=even, 1=odd + CR_UTX_BIT_CNT_D_SHIFT = 8, // [10:8] data bits, field value = bits - 1 + CR_UTX_BIT_CNT_D_MASK = 0x7 << 8, + CR_UTX_BIT_CNT_P_SHIFT = 11, // [12:11] stop bits (NOT [13:12] -- bit 13 is BIT_CNT_B/break) + CR_UTX_BIT_CNT_P_MASK = 0x3 << 11, +} + +// URX_CONFIG (0x04) +private enum : uint +{ + CR_URX_EN = 1 << 0, + CR_URX_PRT_EN = 1 << 4, + CR_URX_PRT_SEL = 1 << 5, + CR_URX_BIT_CNT_D_SHIFT = 8, + CR_URX_BIT_CNT_D_MASK = 0x7 << 8, +} + +// FIFO_CONFIG_0 (0x80) +private enum : uint +{ + TX_FIFO_CLR = 1 << 2, + RX_FIFO_CLR = 1 << 3, + TX_FIFO_OVERFLOW = 1 << 4, + TX_FIFO_UNDERFLOW = 1 << 5, + RX_FIFO_OVERFLOW = 1 << 6, + RX_FIFO_UNDERFLOW = 1 << 7, +} + +// FIFO_CONFIG_1 (0x84) +private enum : uint +{ + TX_FIFO_CNT_MASK = 0x3F, // [5:0] + RX_FIFO_CNT_SHIFT = 8, + RX_FIFO_CNT_MASK = 0x3F << 8, // [13:8] + TX_FIFO_TH_SHIFT = 16, + TX_FIFO_TH_MASK = 0x1F << 16, + RX_FIFO_TH_SHIFT = 24, + RX_FIFO_TH_MASK = 0x1F << 24, +} + +private enum uint INT_MASK_ALL = 0xFF; + +private enum uint RX_FIFO_THRESHOLD = 16; +private enum uint TX_FIFO_THRESHOLD = 8; +private enum uint RX_TIMEOUT_BITS = 80; + + +import urt.mem.ring : RingBuffer; +private alias Ring = RingBuffer!512; + + +// ---------------------------------------------------------------------------- +// Driver API +// ---------------------------------------------------------------------------- + +@fast_data private __gshared Ring[num_uarts] rx_ring; +@fast_data private __gshared Ring[num_uarts] tx_ring; +private __gshared bool[num_uarts] uart_open_flag; + +bool uart_hw_open(uint id, UartConfig cfg) +{ + if (id >= num_uarts) + return false; + + immutable base = uart_base[id]; + + auto tx_cfg = reg_read(base, UTX_CONFIG); + auto rx_cfg = reg_read(base, URX_CONFIG); + tx_cfg &= ~CR_UTX_EN; + rx_cfg &= ~CR_URX_EN; + reg_write(base, UTX_CONFIG, tx_cfg); + reg_write(base, URX_CONFIG, rx_cfg); + + immutable uint div = cast(uint)((cast(ulong)uart_clock_hz * 10 / cfg.baud_rate + 5) / 10); + reg_write(base, BIT_PRD, ((div - 1) << 16) | (div - 1)); + + tx_cfg &= ~(CR_UTX_BIT_CNT_D_MASK | CR_UTX_BIT_CNT_P_MASK | CR_UTX_PRT_EN | CR_UTX_PRT_SEL | CR_UTX_FRM_EN); + tx_cfg |= uint(cfg.data_bits - 1) << CR_UTX_BIT_CNT_D_SHIFT; + tx_cfg |= uint(cfg.stop_bits) << CR_UTX_BIT_CNT_P_SHIFT; + tx_cfg |= CR_UTX_FRM_EN; + if (cfg.parity != Parity.none) + { + tx_cfg |= CR_UTX_PRT_EN; + if (cfg.parity == Parity.odd) + tx_cfg |= CR_UTX_PRT_SEL; + } + + rx_cfg &= ~(CR_URX_BIT_CNT_D_MASK | CR_URX_PRT_EN | CR_URX_PRT_SEL); + rx_cfg |= uint(cfg.data_bits - 1) << CR_URX_BIT_CNT_D_SHIFT; + if (cfg.parity != Parity.none) + { + rx_cfg |= CR_URX_PRT_EN; + if (cfg.parity == Parity.odd) + rx_cfg |= CR_URX_PRT_SEL; + } + + rx_ring[id].purge(); + tx_ring[id].purge(); + + reg_write(base, INT_MASK, INT_MASK_ALL); + + auto fifo0 = reg_read(base, FIFO_CONFIG_0); + reg_write(base, FIFO_CONFIG_0, fifo0 | TX_FIFO_CLR | RX_FIFO_CLR); + + auto fifo1 = reg_read(base, FIFO_CONFIG_1); + fifo1 &= ~(TX_FIFO_TH_MASK | RX_FIFO_TH_MASK); + fifo1 |= TX_FIFO_THRESHOLD << TX_FIFO_TH_SHIFT; + fifo1 |= RX_FIFO_THRESHOLD << RX_FIFO_TH_SHIFT; + reg_write(base, FIFO_CONFIG_1, fifo1); + + reg_write(base, URX_RTO_TIMER, RX_TIMEOUT_BITS); + + tx_cfg |= CR_UTX_EN; + rx_cfg |= CR_URX_EN; + reg_write(base, UTX_CONFIG, tx_cfg); + reg_write(base, URX_CONFIG, rx_cfg); + + uart_open_flag[id] = true; + return true; +} + +void uart_hw_close(uint id) +{ + if (id >= num_uarts) + return; + + immutable base = uart_base[id]; + reg_write(base, INT_MASK, INT_MASK_ALL); + + auto tx_cfg = reg_read(base, UTX_CONFIG); + auto rx_cfg = reg_read(base, URX_CONFIG); + tx_cfg &= ~CR_UTX_EN; + rx_cfg &= ~CR_URX_EN; + reg_write(base, UTX_CONFIG, tx_cfg); + reg_write(base, URX_CONFIG, rx_cfg); + + uart_open_flag[id] = false; +} + +void uart_hw_poll(uint id) +{ + if (id >= num_uarts || !uart_open_flag[id]) + return; + drain_rx_fifo(id); + fill_tx_fifo(id); +} + +ptrdiff_t uart_hw_read(uint id, void[] buffer) +{ + if (id >= num_uarts) + return -1; + return cast(ptrdiff_t)rx_ring[id].read(buffer); +} + +ptrdiff_t uart_hw_write(uint id, const(void)[] data) +{ + if (id >= num_uarts) + return -1; + auto n = tx_ring[id].write(data); + fill_tx_fifo(id); + return cast(ptrdiff_t)n; +} + +ptrdiff_t uart_hw_rx_pending(uint id) +{ + if (id >= num_uarts) + return -1; + return cast(ptrdiff_t)rx_ring[id].pending; +} + +ptrdiff_t uart_hw_flush(uint id) +{ + if (id >= num_uarts) + return -1; + + immutable p = rx_ring[id].pending; + rx_ring[id].purge(); + + immutable base = uart_base[id]; + auto fifo0 = reg_read(base, FIFO_CONFIG_0); + reg_write(base, FIFO_CONFIG_0, fifo0 | RX_FIFO_CLR); + + return cast(ptrdiff_t)p; +} + +bool uart_hw_check_errors(uint id) +{ + if (id >= num_uarts) + return true; + + immutable base = uart_base[id]; + immutable fifo0 = reg_read(base, FIFO_CONFIG_0); + immutable errors = fifo0 & (TX_FIFO_OVERFLOW | TX_FIFO_UNDERFLOW | RX_FIFO_OVERFLOW | RX_FIFO_UNDERFLOW); + + if (errors != 0) + { + reg_write(base, FIFO_CONFIG_0, fifo0); + return true; + } + return false; +} + + +// ---------------------------------------------------------------------------- +// FIFO transfer +// ---------------------------------------------------------------------------- + +private: + +void drain_rx_fifo(uint id) +{ + immutable base = uart_base[id]; + ubyte[1] b = void; + + while (rx_ring[id].available > 0) + { + immutable avail = (reg_read(base, FIFO_CONFIG_1) & RX_FIFO_CNT_MASK) >> RX_FIFO_CNT_SHIFT; + if (avail == 0) + break; + b[0] = cast(ubyte)reg_read(base, FIFO_RDATA); + rx_ring[id].write(b); + } +} + +void fill_tx_fifo(uint id) +{ + immutable base = uart_base[id]; + ubyte[1] b = void; + + while (!tx_ring[id].empty) + { + immutable space = reg_read(base, FIFO_CONFIG_1) & TX_FIFO_CNT_MASK; + if (space == 0) + break; + tx_ring[id].read(b); + reg_write(base, FIFO_WDATA, cast(uint)b[0]); + } +} + + +// ---------------------------------------------------------------------------- +// Early-boot pin/signal/UART setup +// ---------------------------------------------------------------------------- +// +// Pin-to-slot mapping with UART swap groups enabled (start.d sets GPIO12-23 +// and GPIO36-45 swap bits in GLB_PARM_CFG0): +// +// GPIO 12..23 -> slot = (pin + 6) % 12 +// GPIO 36..45 -> slot = (pin + 6) % 12 +// otherwise -> slot = pin % 12 +// +// Slot 0..7 live in GLB_UART_CFG1, slot 8..11 in GLB_UART_CFG2. Each slot has +// a 4-bit field selecting which UART signal (UART0_TXD=2, UART0_RXD=3, ...) +// drives that pin. + +public: + +private enum uint GLB_BASE = 0x2000_0000; +private enum uint GLB_GPIO_CFG0_OFFSET = 0x8C4; +private enum uint GLB_UART_CFG1_OFFSET = 0x154; +private enum uint GLB_UART_CFG2_OFFSET = 0x158; +private enum uint HBN_GLB_ADDR = 0x2000_F030; + +// UART signal function codes (matches vendor GLB_UART_SIG_FUN_Type enum order) +enum uint UART0_TXD = 2; +enum uint UART0_RXD = 3; +enum uint UART1_TXD = 6; +enum uint UART1_RXD = 7; + +// Configure GPIO pad for UART alt-function, signal-route the slot to the +// requested UART signal, then bring UART0 up at the given baud, 8N1. +// Idempotent: safe to call again from uart_hw_open() once the driver proper +// is online. +void uart0_early_init(uint tx_pin, uint rx_pin, uint baud) +{ + // HBN UART_CLK_SEL = XCLK (enum 2 -> SEL2=1 at bit 15, SEL=0 at bit 2). + // XCLK is deterministically 40 MHz (XTAL) regardless of MCU_PBCLK state; + // see bouffalo-m0-clock-sources-at-boot. + uint h = mmio_read(HBN_GLB_ADDR); + h &= ~((uint(1) << 2) | (uint(1) << 15)); + h |= uint(1) << 15; + mmio_write(HBN_GLB_ADDR, h); + + gpio_config_uart_af(tx_pin, false); // TX: output via AF + gpio_config_uart_af(rx_pin, true); // RX: input via AF + uart_route_signal(pin_to_slot(tx_pin), UART0_TXD); + uart_route_signal(pin_to_slot(rx_pin), UART0_RXD); + uart0_regs_init(baud); +} + +private uint pin_to_slot(uint pin) +{ + if ((pin >= 12 && pin <= 23) || (pin >= 36 && pin <= 45)) + return (pin + 6) % 12; + return pin % 12; +} + +private void gpio_config_uart_af(uint pin, bool is_input) +{ + immutable addr = GLB_BASE + GLB_GPIO_CFG0_OFFSET + (pin << 2); + uint v = mmio_read(addr); + + // Disable output first (vendor order). + v &= ~(uint(1) << 6); // OE = 0 + mmio_write(addr, v); + + v = mmio_read(addr); + if (is_input) + { + v |= uint(1) << 0; // IE = 1 + v &= ~(uint(1) << 6); // OE = 0 (AF drives) + } + else + { + v &= ~uint(1); // IE = 0 + v &= ~(uint(1) << 6); // OE = 0 (AF drives) + } + + v |= uint(1) << 4; // PU = 1 + v &= ~(uint(1) << 5); // PD = 0 + v |= uint(1) << 1; // SMT = 1 + v = (v & ~(uint(0x3) << 2)) | (uint(1) << 2); // DRV = 1 + v = (v & ~(uint(0x1F) << 8)) | (uint(7) << 8); // FUNC_SEL = GPIO_FUN_UART + v = (v & ~(uint(0x3) << 30)) | (uint(0) << 30); // output value mode + + mmio_write(addr, v); +} + +private void uart_route_signal(uint slot, uint sig_fun) +{ + uint reg_off; + uint bit_off; + if (slot < 8) + { + reg_off = GLB_UART_CFG1_OFFSET; + bit_off = slot * 4; + } + else + { + reg_off = GLB_UART_CFG2_OFFSET; + bit_off = (slot - 8) * 4; + } + immutable addr = GLB_BASE + reg_off; + uint v = mmio_read(addr); + v = (v & ~(uint(0xF) << bit_off)) | ((sig_fun & 0xF) << bit_off); + mmio_write(addr, v); +} + +private void uart0_regs_init(uint baud) +{ + immutable base = uart_base[0]; + + // TX/RX off while reconfiguring + reg_write(base, UTX_CONFIG, reg_read(base, UTX_CONFIG) & ~CR_UTX_EN); + reg_write(base, URX_CONFIG, reg_read(base, URX_CONFIG) & ~CR_URX_EN); + + // Mask all IRQs + reg_write(base, INT_MASK, INT_MASK_ALL); + + // Baud divisor: round-to-nearest on a x10 scaled fraction + immutable uint div = cast(uint)((cast(ulong)uart_clock_hz * 10 / baud + 5) / 10); + reg_write(base, BIT_PRD, ((div - 1) << 16) | (div - 1)); + + // 8N1, framing on + uint tx = CR_UTX_FRM_EN | (uint(7) << CR_UTX_BIT_CNT_D_SHIFT) | (uint(1) << CR_UTX_BIT_CNT_P_SHIFT); + uint rx = uint(7) << CR_URX_BIT_CNT_D_SHIFT; + reg_write(base, UTX_CONFIG, tx); + reg_write(base, URX_CONFIG, rx); + + // Clear FIFOs + reg_write(base, FIFO_CONFIG_0, reg_read(base, FIFO_CONFIG_0) | TX_FIFO_CLR | RX_FIFO_CLR); + + // FIFO thresholds + uint f1 = reg_read(base, FIFO_CONFIG_1); + f1 &= ~(TX_FIFO_TH_MASK | RX_FIFO_TH_MASK); + f1 |= TX_FIFO_THRESHOLD << TX_FIFO_TH_SHIFT; + f1 |= RX_FIFO_THRESHOLD << RX_FIFO_TH_SHIFT; + reg_write(base, FIFO_CONFIG_1, f1); + + reg_write(base, URX_RTO_TIMER, RX_TIMEOUT_BITS); + + // Enable TX + RX + reg_write(base, UTX_CONFIG, reg_read(base, UTX_CONFIG) | CR_UTX_EN); + reg_write(base, URX_CONFIG, reg_read(base, URX_CONFIG) | CR_URX_EN); +} + + +// ---------------------------------------------------------------------------- +// Early-boot blocking putc/puts: usable from start.d before sys_init +// ---------------------------------------------------------------------------- + +void uart0_putc(char c) +{ + immutable base = uart_base[0]; + while ((reg_read(base, FIFO_CONFIG_1) & TX_FIFO_CNT_MASK) == 0) {} + reg_write(base, FIFO_WDATA, cast(uint)c); +} + +void uart0_hw_puts(const(char)[] s) +{ + foreach (c; s) + { + if (c == '\n') + uart0_putc('\r'); + uart0_putc(c); + } +} + +void uart0_print(const(char)* s) +{ + while (*s != 0) + { + if (*s == '\n') + uart0_putc('\r'); + uart0_putc(*s); + ++s; + } +} + +void uart0_hex(uint val) +{ + uart0_putc('0'); + uart0_putc('x'); + int start = 28; + while (start > 0 && ((val >> start) & 0xF) == 0) + start -= 4; + for (int i = start; i >= 0; i -= 4) + { + uint nibble = (val >> i) & 0xF; + uart0_putc(nibble < 10 ? cast(char)('0' + nibble) : cast(char)('a' + nibble - 10)); + } +} + + +// ---------------------------------------------------------------------------- +// Register access helpers +// ---------------------------------------------------------------------------- + +private: + +uint reg_read(uint base, uint offset) +{ + return volatileLoad(cast(uint*)cast(size_t)(base + offset)); +} + +void reg_write(uint base, uint offset, uint value) +{ + volatileStore(cast(uint*)cast(size_t)(base + offset), value); +} + +uint mmio_read(uint addr) +{ + return volatileLoad(cast(uint*)cast(size_t)addr); +} + +void mmio_write(uint addr, uint value) +{ + volatileStore(cast(uint*)cast(size_t)addr, value); +} diff --git a/src/urt/driver/bl808/hbn_ram.c b/src/urt/driver/bl808/hbn_ram.c new file mode 100644 index 0000000..1231682 --- /dev/null +++ b/src/urt/driver/bl808/hbn_ram.c @@ -0,0 +1,12 @@ +/* HBN RAM persistent storage - placed in .hbn_ram section by linker. + * Survives hibernate if VBAT is maintained. */ + +#include + +struct hbn_persist { + uint32_t magic; + int64_t utc_offset; /* HBN ticks from RTC epoch to Unix epoch */ +}; + +__attribute__((section(".hbn_ram"), used)) +struct hbn_persist _hbn_persist; diff --git a/src/urt/driver/bl808/i2c.d b/src/urt/driver/bl808/i2c.d new file mode 100644 index 0000000..06ce7c1 --- /dev/null +++ b/src/urt/driver/bl808/i2c.d @@ -0,0 +1,5 @@ +/// BL808 I2C peripheral +/// +/// Direct register access to BL808 I2C controller. +/// TODO: implement when needed for hardware I/O. +module urt.driver.bl808.i2c; diff --git a/src/urt/driver/bl808/ipc.d b/src/urt/driver/bl808/ipc.d new file mode 100644 index 0000000..83ef373 --- /dev/null +++ b/src/urt/driver/bl808/ipc.d @@ -0,0 +1,49 @@ +/// BL808 inter-processor communication +/// +/// Initializes XRAM ring buffers and provides typed send/receive +/// for peripheral commands and network frames. +module urt.driver.bl808.ipc; + +import urt.driver.bl808.xram; + +@nogc nothrow: + +/// Global ring buffer handles (initialized by ipc_init) +__gshared XramRing[RingId.max] rings; + +/// Initialize all XRAM ring buffers from the shared memory layout. +/// Call once at startup after M0 has initialized the XRAM region. +void ipc_init() +{ + // TODO: read ring layout from XRAM_BASE + // The M0 firmware sets up ring_pos structures at fixed offsets. + // For now this is a placeholder - actual offsets need to be + // determined by examining the running M0 firmware's XRAM layout. +} + +/// Send a peripheral command (GPIO/SPI/PWM/Flash) +bool peri_send(PeriType type, const(ubyte)[] payload) +{ + PeriHeader hdr; + hdr.type = type; + hdr.err = 0; + hdr.len = cast(ushort) payload.length; + + auto written = rings[RingId.peripheral].write((cast(ubyte*)&hdr)[0 .. 4]); + if (written != PeriHeader.sizeof) + return false; + + if (payload.length > 0) + { + written = rings[RingId.peripheral].write(payload); + if (written != payload.length) + return false; + } + return true; +} + +/// Receive a peripheral response header. Returns false if ring is empty. +bool peri_recv(ref PeriHeader hdr) +{ + return PeriHeader.sizeof == rings[RingId.peripheral].read((cast(ubyte*)&hdr)[0 .. 4]); +} diff --git a/src/urt/driver/bl808/irq.d b/src/urt/driver/bl808/irq.d new file mode 100644 index 0000000..ea805c1 --- /dev/null +++ b/src/urt/driver/bl808/irq.d @@ -0,0 +1,148 @@ +module urt.driver.bl808.irq; + +import core.volatile; + +nothrow @nogc: + +enum bool has_plic = true; +enum bool has_nvic = false; +enum bool has_clic = false; +enum bool has_per_irq_control = true; +enum bool has_irq_priority = false; +enum bool has_wait_for_interrupt = true; +enum bool has_irq_diagnostics = true; +enum bool has_global_irq_state = true; +enum bool has_smp = false; + + +// ================================================================ +// CPU interrupt control +// ================================================================ + +// Enable interrupt delivery. Returns previous state. +bool enable_interrupts() +{ + ulong prev; + asm nothrow @nogc { "csrrsi %0, mstatus, 0x8" : "=r" (prev); } + return (prev & 0x8) != 0; +} + +// Disable interrupt delivery. Returns previous state. +bool disable_interrupts() +{ + ulong prev; + asm nothrow @nogc { "csrrci %0, mstatus, 0x8" : "=r" (prev); } + return (prev & 0x8) != 0; +} + +// Set interrupt delivery state. Returns previous state. +bool set_interrupts(bool state) +{ + return state ? enable_interrupts() : disable_interrupts(); +} + +// Halt CPU until an interrupt is pending. Near-zero power. +void wait_for_interrupt() +{ + asm nothrow @nogc { "wfi"; } +} + +// ================================================================ +// Interrupt source control +// ================================================================ + +// Interrupt classes (mie register bits) +enum IrqClass : uint { software = 3, timer = 7, external = 11 } + +// Enable an interrupt class. Returns previous state. +bool enable_irq(IrqClass c) +{ + ulong prev; + asm nothrow @nogc { "csrrs %0, mie, %1" : "=r" (prev) : "r" (1UL << c); } + return (prev & (1UL << c)) != 0; +} + +// Disable an interrupt class. Returns previous state. +bool disable_irq(IrqClass c) +{ + ulong prev; + asm nothrow @nogc { "csrrc %0, mie, %1" : "=r" (prev) : "r" (1UL << c); } + return (prev & (1UL << c)) != 0; +} + +enum uint irq_max = 80; + +alias IrqHandler = void function(uint irq) nothrow @nogc; + +// Set the external interrupt handler. Receives the PLIC IRQ number. +// Returns the previous handler for chaining. +IrqHandler irq_set_handler(IrqHandler handler) +{ + auto prev = irq_handler; + irq_handler = handler; + return prev; +} + +// Enable an individual PLIC IRQ (set priority > 0 and enable bit) +bool enable_irq(uint irq) +{ + if (irq >= irq_max) + return false; + auto prio = cast(uint*)(plic_base + irq * 4); + volatileStore(prio, 1); + auto en = cast(uint*)(plic_enable + (irq / 32) * 4); + uint mask = 1U << (irq % 32); + uint prev = volatileLoad(en); + volatileStore(en, prev | mask); + return (prev & mask) != 0; +} + +// Disable an individual PLIC IRQ. Returns previous state. +bool disable_irq(uint irq) +{ + if (irq >= irq_max) + return false; + auto en = cast(uint*)(plic_enable + (irq / 32) * 4); + uint mask = 1U << (irq % 32); + uint prev = volatileLoad(en); + volatileStore(en, prev & ~mask); + return (prev & mask) != 0; +} + +private: + +enum ulong plic_base = 0xE000_0000; +enum ulong plic_enable = 0xE000_2000; + +__gshared IrqHandler irq_handler; + +public: + +// Diagnostic counters (temporary) +__gshared uint irq_count = 0; +__gshared uint[irq_max] irq_histogram; + +// PLIC bring-up. C906/D0 boots with the PLIC already in a usable state from +// the boot ROM, so for now this is a stub that satisfies the sys_init +// contract. When we start exposing per-IRQ priorities we'll move that setup +// here (cleared priorities, enable mask zeroed) -- mirrors the CLIC's +// irq_init in bl618/irq.d. +extern(C) void irq_init() {} + +package: + +// Called from start.S _trap_mext +extern(C) void _irq_dispatch(uint irq) +{ + ++irq_count; + if (irq < irq_max) + ++irq_histogram[irq]; + if (irq_handler !is null) + irq_handler(irq); +} + +// Called from start.S _trap_mtimer +extern(C) void _timer_irq_handler() +{ + // TODO: hook up to urt.time tick +} diff --git a/src/urt/driver/bl808/led.d b/src/urt/driver/bl808/led.d new file mode 100644 index 0000000..700ae48 --- /dev/null +++ b/src/urt/driver/bl808/led.d @@ -0,0 +1,92 @@ +// M1s Dock onboard WS2812B LED (pin 8), bit-banged via GPIO. +// +// Timing is calibrated for D0 (C906) running at 480 MHz; the loop body +// (addi + bnez compressed) costs ~2 cycles, hence the loop counts below. +// Move to a portable baremetal/ws2812 driver once another SoC needs it. +module urt.driver.bl808.led; + +import core.volatile : volatileStore; + +@nogc nothrow: + + +void ws2812_send(uint pin, ubyte r, ubyte g, ubyte b) +{ + ws2812_raw_set(pin, false); + ws2812_byte(pin, g); // GRB order + ws2812_byte(pin, r); + ws2812_byte(pin, b); + ws2812_raw_set(pin, false); + delay_loops(WS_RESET_US * 200); +} + +void led_set(ubyte r, ubyte g, ubyte b) => ws2812_send(WS2812_PIN, r, g, b); + +void led_red() { led_set(32, 0, 0); } +void led_green() { led_set(0, 32, 0); } +void led_blue() { led_set(0, 0, 32); } +void led_white() { led_set(16, 16, 16); } +void led_off() { led_set(0, 0, 0); } + + +private: + +// WS2812B spec: T0H=400ns, T0L=850ns, T1H=800ns, T1L=450ns (+/- 150ns). +// At 480MHz: 1 cycle ~= 2.08ns. Loop body ~= 2 cycles, so divide by 2. +enum uint WS2812_PIN = 8; // M1s Dock board +enum uint WS_T0H_LOOPS = 80; +enum uint WS_T0L_LOOPS = 170; +enum uint WS_T1H_LOOPS = 160; +enum uint WS_T1L_LOOPS = 90; +enum uint WS_RESET_US = 60; // >50us required by spec + +pragma(inline, true) +void delay_loops(ulong n) +{ + import ldc.llvmasm; + __asm!ulong(` + 1: addi $0, $0, -1 + bnez $0, 1b + `, "=r,0", n); +} + +enum uint GLB_BASE = 0x2000_0000; +enum uint GPIO_CFG_BASE = GLB_BASE + 0x8C4; +enum uint GPIO_FUN_SWGPIO = 11; +enum uint GPIO_OUTPUT_EN = 1u << 11; +enum uint GPIO_OUTPUT_HIGH = 1u << 17; + +pragma(inline, true) +void ws2812_raw_set(uint pin, bool high) +{ + // Direct cfg write -- the bit-bang is cycle-counted, so it skips the + // read-modify-write and asserts that the public gpio_output_set/init use. + uint cfg = GPIO_FUN_SWGPIO | GPIO_OUTPUT_EN; + if (high) + cfg |= GPIO_OUTPUT_HIGH; + volatileStore(cast(uint*)(GPIO_CFG_BASE + pin * 4), cfg); +} + +void ws2812_bit(uint pin, bool one) +{ + if (one) + { + ws2812_raw_set(pin, true); + delay_loops(WS_T1H_LOOPS); + ws2812_raw_set(pin, false); + delay_loops(WS_T1L_LOOPS); + } + else + { + ws2812_raw_set(pin, true); + delay_loops(WS_T0H_LOOPS); + ws2812_raw_set(pin, false); + delay_loops(WS_T0L_LOOPS); + } +} + +void ws2812_byte(uint pin, ubyte b) +{ + foreach (i; 0 .. 8) + ws2812_bit(pin, (b & (0x80 >> i)) != 0); +} diff --git a/src/urt/driver/bl808/package.d b/src/urt/driver/bl808/package.d new file mode 100644 index 0000000..5400923 --- /dev/null +++ b/src/urt/driver/bl808/package.d @@ -0,0 +1,12 @@ +/// BL808 D0 core platform package. +/// +/// Re-exports the D0 peripheral drivers. sys_init lives in +/// urt.driver.bl_common.system and is shared with M0 / BL618. +module urt.driver.bl808; + +public import urt.driver.bl808.uart; +public import urt.driver.bl808.irq; +public import urt.driver.bl808.timer; +public import urt.driver.bl808.xram; +public import urt.driver.bl808.ipc; +public import urt.driver.bl_common.system; diff --git a/src/urt/driver/bl808/spi.d b/src/urt/driver/bl808/spi.d new file mode 100644 index 0000000..3393b81 --- /dev/null +++ b/src/urt/driver/bl808/spi.d @@ -0,0 +1,5 @@ +/// BL808 SPI peripheral +/// +/// Direct register access to BL808 SPI controller. +/// TODO: implement when needed for hardware I/O. +module urt.driver.bl808.spi; diff --git a/src/urt/driver/bl808/start.S b/src/urt/driver/bl808/start.S new file mode 100644 index 0000000..60d3f72 --- /dev/null +++ b/src/urt/driver/bl808/start.S @@ -0,0 +1,420 @@ +/* BL808 D0 core (T-Head C906 RV64GC) startup + * + * Based on Bouffalo SDK startup.S + vectors.S, consolidated into + * a single file with no SDK header dependencies. + * + * Boot flow: + * 1. CPU setup — wait for M0, disable IRQ, extensions, FPU, trap vectors + * 2. Core regs — gp, tp, sp + * 3. Memory access — TZC release, clear PLIC + * 4. Section init — .got, .tdata, .tbss, .bss, .data + * 5. Caches — I-cache, D-cache, prefetch + * 6. Interrupts — dispatch table, enable MIE+MEIE + * 7. D runtime — sys_init, .init_array, main + * + * T-Head custom CSR numbers (not in standard riscv asm): + * mxstatus = 0x7C0 (T-Head ISA extension enable) + * mhcr = 0x7C1 (hardware cache control) + * mhint = 0x7C5 (performance hints — prefetch, AMR) + */ +#define CSR_MXSTATUS 0x7C0 +#define CSR_MHCR 0x7C1 +#define CSR_MHINT 0x7C5 + + .section .text.entry, "ax" + .global _start + .type _start, @function + .align 2 + +_start: + /* ── 1. CPU setup ─────────────────────────────────────────────── */ + + /* Wait for M0 to finish clock/peripheral init. + * M0 switches D0's CPU clock (XTAL→PLL) AFTER starting D0, which + * glitches the pipeline if we're executing. */ + li t0, 1000000 /* ~80ms at 24MHz, ~5ms at 400MHz */ +.Lwait_m0: + addi t0, t0, -1 + bnez t0, .Lwait_m0 + + /* Disable interrupts */ + csrc mstatus, 0x0008 /* MIE */ + csrc mstatus, 0x0002 /* SIE */ + + /* Enable T-Head ISA extensions (THEADISAEE + MM) */ + li t0, (1 << 22) | (1 << 15) + csrs CSR_MXSTATUS, t0 + + /* Enable FPU (FS = Initial) and vector unit (VS = Initial) */ + li t0, (1 << 13) | (1 << 23) + csrs mstatus, t0 + + /* Set trap vector table (vectored mode) */ + la t0, __vectors + ori t0, t0, 1 + csrw mtvec, t0 + + /* ── 2. Core registers ────────────────────────────────────────── */ + + .option push + .option norelax + la gp, __global_pointer$ + .option pop + la tp, _tdata_start + la sp, _stack_top + + /* ── 3. Memory access ─────────────────────────────────────────── */ + + /* TZC for D0 (CPU group + PSRAMA/B region enable) is configured by M0 + * in urt.driver.bl808_m0.start.tzc_config_for_d0() before this core is + * released from reset. Earlier versions cleared bit 16 of 0x20005380 + * here, which was wrong polarity (bit 16 is region-enable; clearing it + * disables PSRAM access). */ + + /* Clear PLIC interrupt enables and pending bits */ + li t0, 0xE0002000 /* PLIC enable base */ + li t1, 0xE0001000 /* PLIC pending base */ + li t2, 0 + li t3, 4 /* 4 words = 128 bits */ +.Lclear_plic: + sw t2, 0(t0) + sw t2, 0(t1) + addi t0, t0, 4 + addi t1, t1, 4 + addi t3, t3, -1 + bnez t3, .Lclear_plic + + /* ── 4. Section init ──────────────────────────────────────────── */ + + /* Copy .got from flash to SRAM (must come first — gp-relative access) */ + la t0, _got_load + la t1, _got_start + la t2, _got_end +.Lcopy_got: + bgeu t1, t2, .Lgot_done + ld t3, 0(t0) + sd t3, 0(t1) + addi t0, t0, 8 + addi t1, t1, 8 + j .Lcopy_got +.Lgot_done: + + /* Copy .sram_data from PSRAM (LMA) to SRAM (VMA) -- @fast_data globals. + * Empty when no @fast_data is in use; loop is a no-op. */ + la t0, _sram_data_load + la t1, _sram_data_start + la t2, _sram_data_end +.Lcopy_sram_data: + bgeu t1, t2, .Lsram_data_done + ld t3, 0(t0) + sd t3, 0(t1) + addi t0, t0, 8 + addi t1, t1, 8 + j .Lcopy_sram_data +.Lsram_data_done: + + /* Copy .tdata from flash to SRAM (TLS initialized data) */ + la t0, _tdata_load + la t1, _tdata_start + la t2, _tdata_end +.Lcopy_tdata: + bgeu t1, t2, .Ltdata_done + ld t3, 0(t0) + sd t3, 0(t1) + addi t0, t0, 8 + addi t1, t1, 8 + j .Lcopy_tdata +.Ltdata_done: + + /* Zero .tbss in SRAM (TLS zero-initialized data) */ + la t0, _tbss_start + la t1, _tbss_end +.Lzero_tbss: + bgeu t0, t1, .Ltbss_done + sd zero, 0(t0) + addi t0, t0, 8 + j .Lzero_tbss +.Ltbss_done: + + /* Zero BSS in PSRAM */ + la t0, _bss_start + la t1, _bss_end +.Lzero_bss: + bgeu t0, t1, .Lbss_done + sd zero, 0(t0) + addi t0, t0, 8 + j .Lzero_bss +.Lbss_done: + + /* Copy .data from flash to PSRAM */ + la t0, _data_load + la t1, _data_start + la t2, _data_end +.Lcopy_data: + bgeu t1, t2, .Ldata_done + ld t3, 0(t0) + sd t3, 0(t1) + addi t0, t0, 8 + addi t1, t1, 8 + j .Lcopy_data +.Ldata_done: + + /* ── 5. Caches ────────────────────────────────────────────────── */ + + li t0, 0x3 /* IE + DE */ + csrs CSR_MHCR, t0 + li t0, (1 << 2) | (1 << 8) | (1 << 12) + csrs CSR_MHINT, t0 + + /* ── 6. Interrupts ────────────────────────────────────────────── */ + + csrs mstatus, 0x0008 /* MIE */ + li t0, (1 << 11) /* MEIE */ + csrs mie, t0 + + /* ── 7. D runtime ─────────────────────────────────────────────── */ + + call sys_init + + /* .init_array — LDC module info registration */ + la t0, __init_array_start + la t1, __init_array_end +.Linit_array_loop: + bgeu t0, t1, .Linit_array_done + ld t2, 0(t0) + jalr ra, t2 + addi t0, t0, 8 + j .Linit_array_loop +.Linit_array_done: + + /* Enter main -- urt/package.d's extern(C) main(int argc, char** argv). + * argc=0/argv=null so the D-side _Dmain sees an empty args slice. + * Zero fp so backtraces terminate cleanly at main; zero ra so a return + * from main traps (caught by _crash_handler). */ + li a0, 0 + li a1, 0 + li s0, 0 + li ra, 0 + j main + + +/* ================================================================ + * Machine-mode trap vector table (vectored mode) + * + * mtvec[1:0] = 01 means: on interrupt with cause N, jump to + * mtvec_base + N * 4. Each entry is a single jump instruction. + * ================================================================ */ + + .section .text, "ax" + .align 6 + .global __vectors + .type __vectors, @object +__vectors: + .option push + .option norvc + j _trap_exception /* 0: exception (sync trap) */ + j _trap_default /* 1: S-mode software interrupt */ + j _trap_default /* 2: reserved */ + j _trap_msoft /* 3: M-mode software interrupt */ + j _trap_default /* 4: reserved */ + j _trap_default /* 5: S-mode timer */ + j _trap_default /* 6: reserved */ + j _trap_mtimer /* 7: M-mode timer */ + j _trap_default /* 8: reserved */ + j _trap_default /* 9: S-mode external */ + j _trap_default /* 10: reserved */ + j _trap_mext /* 11: M-mode external interrupt */ + .option pop + + +/* ================================================================ + * Trap handlers + * ================================================================ */ + + .align 2 +_trap_default: + j _trap_default + + .align 2 +_trap_msoft: + mret + +/* + * ISR save/restore macros. + * + * Integer caller-saved: ra, t0-t6, a0-a7 (16 regs × 8 = 128 bytes) + * FP caller-saved: ft0-ft11, fa0-fa7 (20 regs × 8 = 160 bytes) + * Total frame: 288 bytes + */ + +.macro ISR_SAVE + addi sp, sp, -288 + sd ra, 0(sp) + sd t0, 8(sp) + sd t1, 16(sp) + sd t2, 24(sp) + sd t3, 32(sp) + sd t4, 40(sp) + sd t5, 48(sp) + sd t6, 56(sp) + sd a0, 64(sp) + sd a1, 72(sp) + sd a2, 80(sp) + sd a3, 88(sp) + sd a4, 96(sp) + sd a5, 104(sp) + sd a6, 112(sp) + sd a7, 120(sp) + fsd ft0, 128(sp) + fsd ft1, 136(sp) + fsd ft2, 144(sp) + fsd ft3, 152(sp) + fsd ft4, 160(sp) + fsd ft5, 168(sp) + fsd ft6, 176(sp) + fsd ft7, 184(sp) + fsd ft8, 192(sp) + fsd ft9, 200(sp) + fsd ft10, 208(sp) + fsd ft11, 216(sp) + fsd fa0, 224(sp) + fsd fa1, 232(sp) + fsd fa2, 240(sp) + fsd fa3, 248(sp) + fsd fa4, 256(sp) + fsd fa5, 264(sp) + fsd fa6, 272(sp) + fsd fa7, 280(sp) +.endm + +.macro ISR_RESTORE + fld ft0, 128(sp) + fld ft1, 136(sp) + fld ft2, 144(sp) + fld ft3, 152(sp) + fld ft4, 160(sp) + fld ft5, 168(sp) + fld ft6, 176(sp) + fld ft7, 184(sp) + fld ft8, 192(sp) + fld ft9, 200(sp) + fld ft10, 208(sp) + fld ft11, 216(sp) + fld fa0, 224(sp) + fld fa1, 232(sp) + fld fa2, 240(sp) + fld fa3, 248(sp) + fld fa4, 256(sp) + fld fa5, 264(sp) + fld fa6, 272(sp) + fld fa7, 280(sp) + ld ra, 0(sp) + ld t0, 8(sp) + ld t1, 16(sp) + ld t2, 24(sp) + ld t3, 32(sp) + ld t4, 40(sp) + ld t5, 48(sp) + ld t6, 56(sp) + ld a0, 64(sp) + ld a1, 72(sp) + ld a2, 80(sp) + ld a3, 88(sp) + ld a4, 96(sp) + ld a5, 104(sp) + ld a6, 112(sp) + ld a7, 120(sp) + addi sp, sp, 288 +.endm + + .align 2 +_trap_mtimer: + ISR_SAVE + call _timer_irq_handler + ISR_RESTORE + mret + + .align 2 +_trap_mext: + ISR_SAVE + + /* Read PLIC claim register to get IRQ number */ + li t0, 0xE0200004 + lw a0, 0(t0) + beqz a0, .Lmext_done + + call _irq_dispatch + + /* Write IRQ number back to PLIC claim to complete */ + li t0, 0xE0200004 + sw a0, 0(t0) + +.Lmext_done: + ISR_RESTORE + mret + + .align 2 +_trap_exception: + /* Redirect mtvec to a simple spin so double-faults don't recurse */ + la t0, .Lcrash_spin2 + csrw mtvec, t0 + + /* Save ALL registers to stack for the crash handler */ + addi sp, sp, -256 + sd ra, 0(sp) + sd sp, 8(sp) /* saved sp (pre-exception value + 256) */ + sd gp, 16(sp) + sd tp, 24(sp) + sd t0, 32(sp) + sd t1, 40(sp) + sd t2, 48(sp) + sd s0, 56(sp) /* fp */ + sd s1, 64(sp) + sd a0, 72(sp) + sd a1, 80(sp) + sd a2, 88(sp) + sd a3, 96(sp) + sd a4, 104(sp) + sd a5, 112(sp) + sd a6, 120(sp) + sd a7, 128(sp) + sd s2, 136(sp) + sd s3, 144(sp) + sd s4, 152(sp) + sd s5, 160(sp) + sd s6, 168(sp) + sd s7, 176(sp) + sd s8, 184(sp) + sd s9, 192(sp) + sd s10, 200(sp) + sd s11, 208(sp) + sd t3, 216(sp) + sd t4, 224(sp) + sd t5, 232(sp) + sd t6, 240(sp) + + /* Fix saved sp to the value before our addi */ + addi t0, sp, 256 + sd t0, 8(sp) + + /* a0 = pointer to saved register block on stack */ + mv a0, sp + /* a1 = mcause */ + csrr a1, mcause + /* a2 = mepc (faulting PC) */ + csrr a2, mepc + /* a3 = mtval (faulting address/instruction) */ + csrr a3, mtval + + call _crash_handler + + /* If crash handler returns or double-faults, spin here */ +.Lcrash_spin: + wfi + j .Lcrash_spin + + /* Non-vectored mtvec target for double-fault: spin immediately */ + .align 2 +.Lcrash_spin2: + wfi + j .Lcrash_spin2 diff --git a/src/urt/driver/bl808/syscalls.d b/src/urt/driver/bl808/syscalls.d new file mode 100644 index 0000000..b6f8111 --- /dev/null +++ b/src/urt/driver/bl808/syscalls.d @@ -0,0 +1,85 @@ +/// BL808 newlib syscall stubs and POSIX networking stubs +/// +/// _write routes stdout/stderr to UART0. +/// Network stubs return -1 until replaced by XRAM WiFi IPC. +module urt.driver.bl808.syscalls; + +import urt.driver.bl808.uart; + +private: + +extern(C) extern __gshared { + pragma(mangle, "_bss_end") void* _bss_end_ptr; + pragma(mangle, "__heap_end") void* _heap_end_ptr; +} + +public: + +// ================================================================ +// newlib syscall stubs +// ================================================================ + +extern(C) int _close(int fd) @nogc nothrow { return -1; } +extern(C) int _read(int fd, void* buf, size_t n) @nogc nothrow { return 0; } + +extern(C) int _write(int fd, const(void)* buf, size_t n) @nogc nothrow +{ + if (fd == 1 || fd == 2) + uart0_hw_puts((cast(const(char)*) buf)[0 .. n]); + return cast(int) n; +} + +extern(C) int _lseek(int fd, int offset, int whence) @nogc nothrow { return 0; } +extern(C) int _fstat(int fd, void* st) @nogc nothrow { return 0; } +extern(C) int _isatty(int fd) @nogc nothrow { return 1; } + +extern(C) void* _sbrk(int incr) @nogc nothrow +{ + __gshared char* heap = null; + if (heap is null) + heap = cast(char*)&_bss_end_ptr; + char* new_heap = heap + incr; + if (new_heap > cast(char*)&_heap_end_ptr) + return cast(void*)-1; // ENOMEM + char* prev = heap; + heap = new_heap; + return prev; +} + +extern(C) void _exit(int code) @nogc nothrow { while (true) {} } +extern(C) int _kill(int pid, int sig) @nogc nothrow { return -1; } +extern(C) int _getpid() @nogc nothrow { return 1; } + +// newlib time() calls gettimeofday(). No RTC yet -- return 0 (epoch). +// Wall-clock-dependent code (cert expiry, etc.) sees Jan 1 1970 until M0 syncs time over IPC. +struct timeval { long tv_sec; long tv_usec; } +extern(C) int gettimeofday(timeval* tv, void* tz) @nogc nothrow +{ + if (tv !is null) + { + tv.tv_sec = 0; + tv.tv_usec = 0; + } + return 0; +} + +// ================================================================ +// POSIX networking stubs (replaced by XRAM WiFi IPC when ready) +// ================================================================ + +extern(C) int socket(int domain, int type, int protocol) @nogc nothrow { return -1; } +extern(C) int close(int fd) @nogc nothrow { return -1; } +extern(C) int poll(void* fds, uint nfds, int timeout) @nogc nothrow { return -1; } +extern(C) int _accept(int fd, void* addr, void* len) @nogc nothrow { return -1; } +extern(C) ptrdiff_t _recv(int fd, void* buf, size_t len, int flags) @nogc nothrow { return -1; } +extern(C) ptrdiff_t _recvfrom(int fd, void* buf, size_t len, int flags, void* src, void* al) @nogc nothrow { return -1; } +extern(C) ptrdiff_t _sendmsg(int fd, const(void)* msg, int flags) @nogc nothrow { return -1; } +extern(C) int _shutdown(int fd, int how) @nogc nothrow { return -1; } +extern(C) int _bind(int fd, const(void)* addr, uint len) @nogc nothrow { return -1; } +extern(C) int _listen(int fd, int backlog) @nogc nothrow { return -1; } +extern(C) int _connect(int fd, const(void)* addr, uint len) @nogc nothrow { return -1; } +extern(C) int setsockopt(int fd, int level, int name, const(void)* val, uint len) @nogc nothrow { return -1; } +extern(C) int getsockname(int fd, void* addr, uint* len) @nogc nothrow { return -1; } +extern(C) int getpeername(int fd, void* addr, uint* len) @nogc nothrow { return -1; } +extern(C) int getaddrinfo(const(char)* node, const(char)* service, const(void)* hints, void** res) @nogc nothrow { return -1; } +extern(C) void freeaddrinfo(void* res) @nogc nothrow {} diff --git a/src/urt/driver/bl808/timer.d b/src/urt/driver/bl808/timer.d new file mode 100644 index 0000000..00d9e50 --- /dev/null +++ b/src/urt/driver/bl808/timer.d @@ -0,0 +1,225 @@ +/// BL808 C906 timer support +/// +/// Two time sources: +/// +/// 1. mtime (RISC-V standard) - 1 MHz monotonic counter. +/// Read via rdtime. Survives WFI/clock scaling, resets on system reset. +/// Used for monotonic timekeeping (getTime / Duration / Timer). +/// +/// 2. HBN RTC - 32,768 Hz counter in the Hibernate block. +/// 40-bit, survives deep sleep (HBN) if VBAT is maintained. +/// Resets on full power cycle. Used with a stored UTC offset +/// for wall-clock time across sleep/wake cycles. +/// +/// CLINT layout (T-Head C906): +/// CORET_BASE = 0xE400_0000 (PLIC_BASE + 0x400_0000) +/// MTIMECMPL0 @ CORET_BASE + 0x4000 +/// MTIMECMPH0 @ CORET_BASE + 0x4004 +/// +/// HBN layout: +/// HBN_BASE = 0x2000_F000 +/// HBN_CTL @ +0x00 - bit 0: RTC enable +/// HBN_TIME_L @ +0x04 - compare value low (alarm) +/// HBN_TIME_H @ +0x08 - compare value high (alarm) +/// HBN_RTC_TIME_L @ +0x0C - latched counter low (read-only) +/// HBN_RTC_TIME_H @ +0x10 - latched counter high [7:0] + latch trigger [31] +module urt.driver.bl808.timer; + +import core.volatile; + +@nogc nothrow: + +// ================================================================ +// Hardware addresses +// ================================================================ + +private enum ulong CORET_BASE = 0xE400_0000; +private enum ulong MTIMECMPL0 = CORET_BASE + 0x4000; +private enum ulong MTIMECMPH0 = CORET_BASE + 0x4004; + +private enum ulong HBN_BASE = 0x2000_F000; +private enum ulong HBN_CTL = HBN_BASE + 0x00; +private enum ulong HBN_RTC_TIME_L = HBN_BASE + 0x0C; +private enum ulong HBN_RTC_TIME_H = HBN_BASE + 0x10; + +// ================================================================ +// mtime frequency +// +// The BL808 mtime counter runs at 1MHz (from the XTAL/PLL +// divided down). Confirm on hardware by measuring against +// a known delay or reading the clock tree registers. +// ================================================================ + +enum uint mtime_freq_hz = 1_000_000; +enum bool has_mtime = true; +enum bool has_rtc = true; +enum bool has_mcycle = true; +enum bool has_timer_stop = true; +enum bool has_oneshot_timer = true; + +// ================================================================ +// Time reading +// ================================================================ + +/// Read the monotonic mtime counter via rdtime. +/// Does not stop during WFI, unaffected by clock scaling. +ulong mtime_read() +{ + ulong t; + asm @nogc nothrow { "rdtime %0" : "=r" (t); } + return t; +} + +/// Read CPU cycle counter (for profiling, NOT timekeeping). +/// Stops during WFI, rate changes with clock scaling. +ulong mcycle_read() +{ + ulong c; + asm @nogc nothrow { "rdcycle %0" : "=r" (c); } + return c; +} + +// ================================================================ +// Timer interrupt (periodic tick) +// ================================================================ + +private __gshared ulong tick_interval = 0; +private __gshared void function() @nogc nothrow tick_callback = null; + +/// Set up a periodic timer interrupt. +/// interval_us: microseconds between ticks +/// callback: called from _timer_irq_handler (keep it short!) +void timer_set_periodic(ulong interval_us, void function() @nogc nothrow callback) +{ + import urt.driver.bl808.irq : IrqClass, enable_irq; + + tick_interval = interval_us; + tick_callback = callback; + + ulong now = mtime_read(); + mtimecmp_write(now + tick_interval); + enable_irq(IrqClass.timer); +} + +/// Stop the periodic timer +void timer_stop() +{ + import urt.driver.bl808.irq : IrqClass, disable_irq; + + disable_irq(IrqClass.timer); + mtimecmp_write(ulong.max); + tick_callback = null; +} + +/// Called from start.S _trap_mtimer. +/// Sets next deadline and invokes the user callback. +extern(C) void _timer_irq_handler() +{ + if (tick_interval > 0) + { + // Advance deadline relative to current compare value + // (not current time - avoids drift) + ulong cmp = mtimecmp_read(); + mtimecmp_write(cmp + tick_interval); + } + + if (tick_callback !is null) + tick_callback(); +} + +// ================================================================ +// MTIMECMP register access +// +// Split into two 32-bit writes. Write high word to max first +// to prevent a spurious interrupt when the low word is updated. +// ================================================================ + +/// Set mtimecmp for a one-shot wakeup (used by sleep). +/// The periodic timer handler will re-arm on the next tick if active. +void mtimecmp_write_oneshot(ulong value) +{ + mtimecmp_write(value); +} + +private void mtimecmp_write(ulong value) +{ + auto lo = cast(uint*)MTIMECMPL0; + auto hi = cast(uint*)MTIMECMPH0; + + // Write 0xFFFFFFFF to high first to prevent spurious fire + volatileStore(hi, 0xFFFF_FFFF); + volatileStore(lo, cast(uint)(value & 0xFFFF_FFFF)); + volatileStore(hi, cast(uint)(value >> 32)); +} + +private ulong mtimecmp_read() +{ + auto lo = cast(uint*)MTIMECMPL0; + auto hi = cast(uint*)MTIMECMPH0; + + // Read high-low-high to handle rollover + uint h1 = volatileLoad(hi); + uint l = volatileLoad(lo); + uint h2 = volatileLoad(hi); + if (h1 != h2) + l = volatileLoad(lo); + return (cast(ulong)h2 << 32) | l; +} + +// ================================================================ +// HBN RTC (32,768 Hz, 40-bit, survives hibernate) +// ================================================================ + +enum uint rtc_freq_hz = 32_768; + +/// Enable the HBN RTC counter (bit 0 of HBN_CTL). +/// Does NOT reset the counter - call rtc_reset() first if needed. +/// Note: read-modify-write on HBN_CTL is not interrupt-safe. +/// If called after interrupts are enabled, wrap with mstatus.MIE guard. +void rtc_enable() +{ + auto ctl = cast(uint*)HBN_CTL; + volatileStore(ctl, volatileLoad(ctl) | 0x01); +} + +/// Disable and reset the HBN RTC counter to zero. +/// Note: same mstatus.MIE guard applies - see rtc_enable(). +void rtc_reset() +{ + auto ctl = cast(uint*)HBN_CTL; + volatileStore(ctl, volatileLoad(ctl) & ~uint(0x01)); +} + +/// Read the 40-bit HBN RTC counter. +/// Latches the value first (toggle bit 31 of RTC_TIME_H), then reads. +ulong rtc_read() +{ + auto lo = cast(uint*)HBN_RTC_TIME_L; + auto hi = cast(uint*)HBN_RTC_TIME_H; + + // Latch: set bit 31, then clear it + uint h = volatileLoad(hi); + volatileStore(hi, h | (1u << 31)); + volatileStore(hi, h & ~(1u << 31)); + + uint l = volatileLoad(lo); + h = volatileLoad(hi); + return (ulong(h & 0xFF) << 32) | l; +} + +/// Convert RTC ticks (32,768 Hz) to seconds. +ulong rtc_ticks_to_sec(ulong ticks) +{ + return ticks / rtc_freq_hz; +} + +/// Convert seconds to RTC ticks. +ulong rtc_sec_to_ticks(ulong sec) +{ + return sec * rtc_freq_hz; +} + +// HBN persistence struct and accessor moved to urt.driver.bl_common.hbn so +// the M0 build can mirror D0's clock persistence without dragging in the +// rest of timer.d (which is D0-only). +public import urt.driver.bl_common.hbn : HbnPersist, hbn_persist; diff --git a/src/urt/driver/bl808/uart.d b/src/urt/driver/bl808/uart.d new file mode 100644 index 0000000..4d509e0 --- /dev/null +++ b/src/urt/driver/bl808/uart.d @@ -0,0 +1,587 @@ +// BL808 UART driver +// +// Four UART peripherals sharing the same register-level IP block (BL6xx/BL8xx): +// +// UART0 0x2000_A000 MCU domain M0's console (COM7 on M1s Dock) +// UART1 0x2000_A100 MCU domain General purpose +// UART2 0x2000_AA00 MCU domain Shares address with ISO11898 CAN (mutually exclusive) +// UART3 0x3000_2000 MM domain D0's console (COM8 on M1s Dock) +// +// M0 initializes UART0 before releasing D0. M0 initializes UART3 clock +// ("UART CLK select MM XCLK") shortly after starting D0. +// +// GPIO pin muxing is handled by M0 at boot. UART0/3 are pre-configured. +// UART1/2 require M0 cooperation or future GPIO mux support from D0. +// +// Interrupt availability from D0: +// UART3 - PLIC IRQ 20 (IRQ_NUM_BASE + 4), interrupt-driven +// UART0/1/2 - IRQs are in M0's PLIC domain, must be polled from D0 +// +// All UARTs use software ring buffers (512 bytes RX, 512 bytes TX). +// UART3 fills/drains them via ISR. UART0/1/2 require explicit uart_poll(). +module urt.driver.bl808.uart; + +import core.volatile; +import urt.driver.bl808.irq; + +import urt.driver.uart : Parity, StopBits, UartConfig; + +nothrow @nogc: + + +// ============================================================================== +// Register definitions +// ============================================================================== + +enum num_uarts = 4; +enum uint uart_clock_hz = 40_000_000; +enum bool has_irq_driven_uart = true; +enum bool has_dma_driven_uart = false; + +private immutable uint[num_uarts] uart_base = [ + 0x2000_A000, // UART0 + 0x2000_A100, // UART1 + 0x2000_AA00, // UART2 (shared with ISO11898 CAN) + 0x3000_2000, // UART3 +]; + +// D0 PLIC IRQ numbers (IRQ_NUM_BASE = 16 for D0) +private enum uint UART3_PLIC_IRQ = 20; // IRQ_NUM_BASE + 4 + +// Register offsets +private enum : uint +{ + UTX_CONFIG = 0x00, + URX_CONFIG = 0x04, + BIT_PRD = 0x08, + DATA_CONFIG = 0x0C, + UTX_IR_POSITION = 0x10, + URX_IR_POSITION = 0x14, + URX_RTO_TIMER = 0x18, + SW_MODE = 0x1C, + INT_STS = 0x20, + INT_MASK = 0x24, + INT_CLEAR = 0x28, + INT_EN = 0x2C, + STATUS = 0x30, + FIFO_CONFIG_0 = 0x80, + FIFO_CONFIG_1 = 0x84, + FIFO_WDATA = 0x88, + FIFO_RDATA = 0x8C, +} + +// UTX_CONFIG (0x00) bits +private enum : uint +{ + CR_UTX_EN = 1 << 0, + CR_UTX_CTS_EN = 1 << 1, + CR_UTX_FRM_EN = 1 << 2, + CR_UTX_LIN_EN = 1 << 3, + CR_UTX_PRT_EN = 1 << 4, + CR_UTX_PRT_SEL = 1 << 5, // 0 = even, 1 = odd + CR_UTX_BIT_CNT_D_SHIFT = 8, // [10:8] data bits, field value = data_bits - 1 + CR_UTX_BIT_CNT_D_MASK = 0x7 << 8, + CR_UTX_BIT_CNT_P_SHIFT = 11, // [12:11] stop bits (NOT [13:12] -- bit 13 is BIT_CNT_B/break) + CR_UTX_BIT_CNT_P_MASK = 0x3 << 11, +} + +// URX_CONFIG (0x04) bits +private enum : uint +{ + CR_URX_EN = 1 << 0, + CR_URX_PRT_EN = 1 << 4, + CR_URX_PRT_SEL = 1 << 5, + CR_URX_BIT_CNT_D_SHIFT = 8, + CR_URX_BIT_CNT_D_MASK = 0x7 << 8, +} + +// FIFO_CONFIG_0 (0x80) bits +private enum : uint +{ + DMA_TX_EN = 1 << 0, + DMA_RX_EN = 1 << 1, + TX_FIFO_CLR = 1 << 2, + RX_FIFO_CLR = 1 << 3, + TX_FIFO_OVERFLOW = 1 << 4, + TX_FIFO_UNDERFLOW = 1 << 5, + RX_FIFO_OVERFLOW = 1 << 6, + RX_FIFO_UNDERFLOW = 1 << 7, +} + +// FIFO_CONFIG_1 (0x84) bits +private enum : uint +{ + TX_FIFO_CNT_MASK = 0x3F, // [5:0] available TX slots + RX_FIFO_CNT_SHIFT = 8, + RX_FIFO_CNT_MASK = 0x3F << 8, // [13:8] available RX bytes + TX_FIFO_TH_SHIFT = 16, + TX_FIFO_TH_MASK = 0x1F << 16, // [20:16] + RX_FIFO_TH_SHIFT = 24, + RX_FIFO_TH_MASK = 0x1F << 24, // [28:24] +} + +// INT_STS / INT_MASK / INT_CLEAR / INT_EN bit positions +private enum : uint +{ + INT_UTX_END = 1 << 0, + INT_URX_END = 1 << 1, + INT_UTX_FIFO = 1 << 2, + INT_URX_FIFO = 1 << 3, + INT_URX_RTO = 1 << 4, + INT_URX_PCE = 1 << 5, + INT_UTX_FER = 1 << 6, + INT_URX_FER = 1 << 7, + INT_MASK_ALL = 0xFF, +} + +// FIFO depth +private enum UART_FIFO_MAX = 32; + +// RX FIFO threshold - interrupt fires when RX FIFO count >= this value. +// Set to 16 so we drain before the 32-byte FIFO overflows. +private enum RX_FIFO_THRESHOLD = 16; + +// TX FIFO threshold - interrupt fires when TX FIFO count >= this value +// (i.e., space is available). Set low so we refill aggressively. +private enum TX_FIFO_THRESHOLD = 8; + +// RX timeout - number of bit periods of silence before RX timeout interrupt. +// Catches partial frames shorter than RX_FIFO_THRESHOLD. +private enum RX_TIMEOUT_BITS = 80; // ~10 byte times at any baud rate + +// UART clock frequency - M0 sets all UARTs to XCLK = 40 MHz. +// TODO: read GLB_UART_CFG0 (GLB_BASE + 0x150) to determine actual clock +// source. Bits: [2:0] = divider, [4] = clock enable, [7] = clk_sel, +// [22] = clk_sel2. The 2-bit selector chooses between MCU PBCLK (0), +// 160 MHz PLL mux (1), or XCLK (2). Actual uart_clk = source / (div + 1). +private enum uint UART_CLK_HZ = 40_000_000; + + +// Software ring buffer - reuse urt.mem.ring with fixed 512-byte capacity. +import urt.mem.ring : RingBuffer; +private alias Ring = RingBuffer!512; + + +// ============================================================================== +// Driver API +// ============================================================================== + +// Per-UART state +private __gshared Ring[num_uarts] rx_ring; +private __gshared Ring[num_uarts] tx_ring; +private __gshared bool[num_uarts] uart_open_flag; +private __gshared IrqHandler prev_irq_handler; +private __gshared bool irq_handler_installed; + +// Open a UART: configure baud rate, frame format, clear FIFOs, enable TX+RX. +// UART3 gets interrupt-driven I/O. UART0/1/2 require uart_poll(). +// Returns false if id is out of range. +bool uart_hw_open(uint id, UartConfig cfg) +{ + if (id >= num_uarts) + return false; + + immutable base = uart_base[id]; + + // Disable TX and RX while reconfiguring + auto tx_cfg = reg_read(base, UTX_CONFIG); + auto rx_cfg = reg_read(base, URX_CONFIG); + tx_cfg &= ~CR_UTX_EN; + rx_cfg &= ~CR_URX_EN; + reg_write(base, UTX_CONFIG, tx_cfg); + reg_write(base, URX_CONFIG, rx_cfg); + + // Baud rate divisor + immutable uint div = cast(uint)((cast(ulong)UART_CLK_HZ * 10 / cfg.baud_rate + 5) / 10); + reg_write(base, BIT_PRD, ((div - 1) << 16) | (div - 1)); + + // TX config: data bits, stop bits, parity + tx_cfg &= ~(CR_UTX_BIT_CNT_D_MASK | CR_UTX_BIT_CNT_P_MASK | CR_UTX_PRT_EN | CR_UTX_PRT_SEL | CR_UTX_FRM_EN); + tx_cfg |= cast(uint)(cfg.data_bits - 1) << CR_UTX_BIT_CNT_D_SHIFT; + tx_cfg |= cast(uint)cfg.stop_bits << CR_UTX_BIT_CNT_P_SHIFT; + tx_cfg |= CR_UTX_FRM_EN; + if (cfg.parity != Parity.none) + { + tx_cfg |= CR_UTX_PRT_EN; + if (cfg.parity == Parity.odd) + tx_cfg |= CR_UTX_PRT_SEL; + } + + // RX config: data bits, parity (stop bits are TX-only in hardware) + rx_cfg &= ~(CR_URX_BIT_CNT_D_MASK | CR_URX_PRT_EN | CR_URX_PRT_SEL); + rx_cfg |= cast(uint)(cfg.data_bits - 1) << CR_URX_BIT_CNT_D_SHIFT; + if (cfg.parity != Parity.none) + { + rx_cfg |= CR_URX_PRT_EN; + if (cfg.parity == Parity.odd) + rx_cfg |= CR_URX_PRT_SEL; + } + + // Clear software ring buffers + rx_ring[id].purge(); + tx_ring[id].purge(); + + // Mask all interrupts initially + reg_write(base, INT_MASK, INT_MASK_ALL); + + // Clear FIFOs + auto fifo0 = reg_read(base, FIFO_CONFIG_0); + reg_write(base, FIFO_CONFIG_0, fifo0 | TX_FIFO_CLR | RX_FIFO_CLR); + + // Set FIFO thresholds + auto fifo1 = reg_read(base, FIFO_CONFIG_1); + fifo1 &= ~(TX_FIFO_TH_MASK | RX_FIFO_TH_MASK); + fifo1 |= TX_FIFO_THRESHOLD << TX_FIFO_TH_SHIFT; + fifo1 |= RX_FIFO_THRESHOLD << RX_FIFO_TH_SHIFT; + reg_write(base, FIFO_CONFIG_1, fifo1); + + // Set RX timeout + reg_write(base, URX_RTO_TIMER, RX_TIMEOUT_BITS); + + // Enable TX + RX + tx_cfg |= CR_UTX_EN; + rx_cfg |= CR_URX_EN; + reg_write(base, UTX_CONFIG, tx_cfg); + reg_write(base, URX_CONFIG, rx_cfg); + + uart_open_flag[id] = true; + + // UART3: set up interrupt-driven I/O + if (id == 3) + { + // Install our IRQ handler (chain with previous) + if (!irq_handler_installed) + { + prev_irq_handler = irq_set_handler(&uart_irq_handler); + irq_handler_installed = true; + } + + // Enable UART3 PLIC IRQ + enable_irq(UART3_PLIC_IRQ); + + // Unmask RX FIFO threshold + RX timeout interrupts + // TX FIFO interrupt is unmasked on demand when tx_ring has data + auto mask = reg_read(base, INT_MASK); + mask &= ~(INT_URX_FIFO | INT_URX_RTO); + reg_write(base, INT_MASK, mask); + + // Enable interrupt generation + reg_write(base, INT_EN, INT_URX_FIFO | INT_URX_RTO | INT_UTX_FIFO); + } + + return true; +} + +// Disable TX and RX, mask interrupts. +void uart_hw_close(uint id) +{ + assert(id < num_uarts); + + immutable base = uart_base[id]; + + // Mask all interrupts + reg_write(base, INT_MASK, INT_MASK_ALL); + + if (id == 3) + disable_irq(UART3_PLIC_IRQ); + + auto tx_cfg = reg_read(base, UTX_CONFIG); + auto rx_cfg = reg_read(base, URX_CONFIG); + tx_cfg &= ~CR_UTX_EN; + rx_cfg &= ~CR_URX_EN; + reg_write(base, UTX_CONFIG, tx_cfg); + reg_write(base, URX_CONFIG, rx_cfg); + + uart_open_flag[id] = false; +} + +// Poll hardware FIFOs and transfer to/from ring buffers. +// Required for UART0/1/2 (no D0 interrupt). Harmless for UART3. +void uart_hw_poll(uint id) +{ + if (id >= num_uarts || !uart_open_flag[id]) + return; + drain_rx_fifo(id); + fill_tx_fifo(id); +} + +// Non-blocking read: pull from RX ring buffer, return bytes read. +ptrdiff_t uart_hw_read(uint id, void[] buffer) +{ + if (id >= num_uarts) + return -1; + + immutable prev = disable_interrupts(); + auto n = rx_ring[id].read(buffer); + set_interrupts(prev); + return cast(ptrdiff_t)n; +} + +// Non-blocking write: push into TX ring buffer, kick TX if needed. +// Returns bytes accepted (may be less than data.length if ring is full). +ptrdiff_t uart_hw_write(uint id, const(void)[] data) +{ + if (id >= num_uarts) + return -1; + + immutable prev = disable_interrupts(); + + auto n = tx_ring[id].write(data); + + // Kick: fill hardware FIFO from ring + fill_tx_fifo(id); + + // For UART3, unmask TX FIFO interrupt so ISR continues draining + if (id == 3 && !tx_ring[id].empty) + { + auto mask = reg_read(uart_base[id], INT_MASK); + mask &= ~INT_UTX_FIFO; + reg_write(uart_base[id], INT_MASK, mask); + } + + set_interrupts(prev); + return cast(ptrdiff_t)n; +} + +// Return number of bytes available to read from RX ring. +ptrdiff_t uart_hw_rx_pending(uint id) +{ + if (id >= num_uarts) + return -1; + + immutable prev = disable_interrupts(); + auto p = rx_ring[id].pending; + set_interrupts(prev); + return cast(ptrdiff_t)p; +} + +// Clear RX ring buffer and hardware FIFO. Returns bytes discarded. +ptrdiff_t uart_hw_flush(uint id) +{ + if (id >= num_uarts) + return -1; + + immutable prev = disable_interrupts(); + + immutable p = rx_ring[id].pending; + rx_ring[id].purge(); + + // Also clear hardware RX FIFO + immutable base = uart_base[id]; + auto fifo0 = reg_read(base, FIFO_CONFIG_0); + reg_write(base, FIFO_CONFIG_0, fifo0 | RX_FIFO_CLR); + + set_interrupts(prev); + return cast(ptrdiff_t)p; +} + +// Check and clear FIFO error flags (overflow/underflow). +// Returns true if any error was detected. +bool uart_hw_check_errors(uint id) +{ + if (id >= num_uarts) + return true; + + immutable base = uart_base[id]; + immutable fifo0 = reg_read(base, FIFO_CONFIG_0); + immutable errors = fifo0 & (TX_FIFO_OVERFLOW | TX_FIFO_UNDERFLOW | RX_FIFO_OVERFLOW | RX_FIFO_UNDERFLOW); + + if (errors != 0) + { + // Clear error flags by writing them back + reg_write(base, FIFO_CONFIG_0, fifo0); + return true; + } + + return false; +} + + +// ============================================================================== +// Interrupt handler and FIFO transfer +// ============================================================================== + +private: + +// Drain hardware RX FIFO into software ring buffer. +void drain_rx_fifo(uint id) +{ + immutable base = uart_base[id]; + ubyte[1] b = void; + + while (rx_ring[id].available > 0) + { + immutable avail = (reg_read(base, FIFO_CONFIG_1) & RX_FIFO_CNT_MASK) >> RX_FIFO_CNT_SHIFT; + if (avail == 0) + break; + b[0] = cast(ubyte)reg_read(base, FIFO_RDATA); + rx_ring[id].write(b); + } +} + +// Fill hardware TX FIFO from software ring buffer. +void fill_tx_fifo(uint id) +{ + immutable base = uart_base[id]; + ubyte[1] b = void; + + while (!tx_ring[id].empty) + { + immutable space = reg_read(base, FIFO_CONFIG_1) & TX_FIFO_CNT_MASK; + if (space == 0) + break; + tx_ring[id].read(b); + reg_write(base, FIFO_WDATA, cast(uint)b[0]); + } +} + +// PLIC IRQ handler - services UART3 interrupts. +// Chains to previous handler for non-UART IRQs. +void uart_irq_handler(uint irq) +{ + if (irq == UART3_PLIC_IRQ) + { + immutable base = uart_base[3]; + immutable sts = reg_read(base, INT_STS); + immutable mask = reg_read(base, INT_MASK); + immutable active = sts & ~mask; + + // RX FIFO threshold or RX timeout - drain into ring + if (active & (INT_URX_FIFO | INT_URX_RTO)) + { + drain_rx_fifo(3); + if (active & INT_URX_RTO) + reg_write(base, INT_CLEAR, INT_URX_RTO); + } + + // TX FIFO has space - refill from ring + if (active & INT_UTX_FIFO) + { + fill_tx_fifo(3); + // If ring is drained, mask TX interrupt until more data arrives + if (tx_ring[3].empty) + { + auto m = reg_read(base, INT_MASK); + m |= INT_UTX_FIFO; + reg_write(base, INT_MASK, m); + } + } + } + else if (prev_irq_handler !is null) + prev_irq_handler(irq); +} + + +// ============================================================================== +// Early-boot debug output (used before driver is initialized) +// ============================================================================== + +public: + +private auto u0_cfg() { return cast(uint*)cast(ulong)(uart_base[0] + FIFO_CONFIG_1); } +private auto u0_wr() { return cast(uint*)cast(ulong)(uart_base[0] + FIFO_WDATA); } +private auto u3_cfg() { return cast(uint*)cast(ulong)(uart_base[3] + FIFO_CONFIG_1); } +private auto u3_wr() { return cast(uint*)cast(ulong)(uart_base[3] + FIFO_WDATA); } + +// -- UART0 (COM7, MCU domain) ------------------------------------------------ + +void uart0_putc(char c) +{ + while ((volatileLoad(u0_cfg) & 0x3F) == 0) {} + volatileStore(u0_wr, cast(uint)c); +} + +void uart0_hw_puts(const(char)[] s) +{ + foreach (c; s) + { + if (c == '\n') + uart0_putc('\r'); + uart0_putc(c); + } +} + +void uart0_print(const(char)* s) +{ + while (*s != 0) + { + if (*s == '\n') + uart0_putc('\r'); + uart0_putc(*s); + ++s; + } +} + +void uart0_hex(ulong val) +{ + uart0_putc('0'); + uart0_putc('x'); + int start = 60; + while (start > 0 && ((val >> start) & 0xF) == 0) + start -= 4; + for (int i = start; i >= 0; i -= 4) + { + uint nibble = cast(uint)((val >> i) & 0xF); + uart0_putc(nibble < 10 ? cast(char)('0' + nibble) : cast(char)('a' + nibble - 10)); + } +} + +// -- UART3 (COM8, MM domain - D0's console) ---------------------------------- + +void uart3_putc(char c) +{ + while ((volatileLoad(u3_cfg) & 0x3F) == 0) {} + volatileStore(u3_wr, cast(uint)c); +} + +void uart3_puts(const(char)[] s) +{ + foreach (c; s) + { + if (c == '\n') + uart3_putc('\r'); + uart3_putc(c); + } +} + +void uart3_print(const(char)* s) +{ + while (*s != 0) + { + if (*s == '\n') + uart3_putc('\r'); + uart3_putc(*s); + ++s; + } +} + +void uart3_hex(ulong val) +{ + uart3_putc('0'); + uart3_putc('x'); + int start = 60; + while (start > 0 && ((val >> start) & 0xF) == 0) + start -= 4; + for (int i = start; i >= 0; i -= 4) + { + uint nibble = cast(uint)((val >> i) & 0xF); + uart3_putc(nibble < 10 ? cast(char)('0' + nibble) : cast(char)('a' + nibble - 10)); + } +} + + +// ============================================================================== +// Register access helpers +// ============================================================================== + +private: + +uint reg_read(uint base, uint offset) +{ + return volatileLoad(cast(uint*)cast(ulong)(base + offset)); +} + +void reg_write(uint base, uint offset, uint value) +{ + volatileStore(cast(uint*)cast(ulong)(base + offset), value); +} diff --git a/src/urt/driver/bl808/xram.d b/src/urt/driver/bl808/xram.d new file mode 100644 index 0000000..6af9386 --- /dev/null +++ b/src/urt/driver/bl808/xram.d @@ -0,0 +1,225 @@ +/// BL808 XRAM inter-processor communication +/// +/// D0 ↔ M0 shared memory ring buffers at 0x2202_0000 (16KB). +/// Each ring has 16-bit head/tail cursors in shared memory, +/// requiring volatile access and memory barriers. +/// +/// Ring IDs (fixed by M0 firmware): +/// 0 = LOG_C906 D0 log output +/// 1 = LOG_E902 LP core log +/// 2 = NET Ethernet frames (WiFi bridge) +/// 3 = PERIPHERAL GPIO/SPI/PWM/Flash control +/// 4 = RPC Remote procedure calls +module urt.driver.bl808.xram; + +import core.volatile; + +@nogc nothrow: + +// ================================================================ +// Constants +// ================================================================ + +enum ulong XRAM_BASE = 0x2202_0000; +enum uint XRAM_SIZE = 16 * 1024; + +enum RingId : uint +{ + log_c906 = 0, + log_e902 = 1, + net = 2, + peripheral = 3, + rpc = 4, + max = 5, +} + +// ================================================================ +// Peripheral message header (4 bytes) +// Used on PERIPHERAL ring for GPIO/SPI/PWM/Flash ops +// ================================================================ + +struct PeriHeader +{ + ubyte type; + ubyte err; + ushort len; +} + +enum PeriType : ubyte +{ + flash = 0x31, + pwm = 0x32, + spi = 0x33, +} + +// ================================================================ +// Net message header (12 bytes) +// Used on NET ring for Ethernet frames and WiFi commands +// ================================================================ + +struct NetHeader +{ + ubyte[4] magic; // "ring" = [0x72, 0x69, 0x6e, 0x67] + ushort len; + ubyte type; // high nibble: msg type, low nibble: dev type + ubyte flag; + ushort crc16; + ushort reserved; +} + +enum NetMsgType : ubyte +{ + command = 0, + frame = 1, + sniffer_pkt = 2, +} + +// ================================================================ +// WiFi operation commands +// ================================================================ + +enum WifiOp : uint +{ + init_ = 0, + deinit = 1, + connect = 2, + disconnect = 3, + upload_stream = 4, +} + +struct WifiConnect +{ + char[32] ssid; + char[63] passwd; +} + +// ================================================================ +// Shared-memory ring buffer +// +// Layout in XRAM (set by M0 firmware): +// struct { uint16_t head, tail; uint32_t buffer_size; uint8_t buffer[]; } +// +// Head is advanced by the reader, tail by the writer. +// Both cores access these via volatile loads/stores. +// ================================================================ + +struct XramRing +{ + @nogc nothrow @trusted: + + ushort* head_ptr; + ushort* tail_ptr; + ubyte* buffer_ptr; + uint buffer_size; + + /// Bytes available to read + uint pending() + { + uint h = volatileLoad(head_ptr); + uint t = volatileLoad(tail_ptr); + if (t >= h) + return t - h; + else + return buffer_size - h + t; + } + + /// Bytes available to write + uint available() + { + uint h = volatileLoad(head_ptr); + uint t = volatileLoad(tail_ptr); + if (t >= h) + return buffer_size - t + h - 1; + else + return h - t - 1; + } + + bool empty() + { + return volatileLoad(head_ptr) == volatileLoad(tail_ptr); + } + + void reset() + { + volatileStore(head_ptr, cast(ushort) 0); + volatileStore(tail_ptr, cast(ushort) 0); + fence(); + } + + /// Read up to dst.length bytes from the ring. Returns bytes read. + uint read(ubyte[] dst) + { + fence(); // ensure we see latest writes from other core + + uint h = volatileLoad(head_ptr); + uint t = volatileLoad(tail_ptr); + uint avail = (t >= h) ? (t - h) : (buffer_size - h + t); + uint len = (dst.length < avail) ? cast(uint) dst.length : avail; + + if (len == 0) + return 0; + + uint first = buffer_size - h; + if (len <= first) + { + dst[0 .. len] = buffer_ptr[h .. h + len]; + h += len; + if (h == buffer_size) + h = 0; + } + else + { + dst[0 .. first] = buffer_ptr[h .. buffer_size]; + uint second = len - first; + dst[first .. len] = buffer_ptr[0 .. second]; + h = second; + } + + fence(); // ensure our reads complete before advancing head + volatileStore(head_ptr, cast(ushort) h); + return len; + } + + /// Write data to the ring. Returns bytes written. + uint write(const(ubyte)[] src) + { + uint h = volatileLoad(head_ptr); + uint t = volatileLoad(tail_ptr); + uint space = (t >= h) ? (buffer_size - t + h - 1) : (h - t - 1); + uint len = (src.length < space) ? cast(uint) src.length : space; + + if (len == 0) + return 0; + + uint tail_room = buffer_size - t; + if (len <= tail_room) + { + buffer_ptr[t .. t + len] = src[0 .. len]; + t += len; + if (t == buffer_size) + t = 0; + } + else + { + buffer_ptr[t .. buffer_size] = src[0 .. tail_room]; + uint second = len - tail_room; + buffer_ptr[0 .. second] = src[tail_room .. len]; + t = second; + } + + fence(); // ensure writes visible before advancing tail + volatileStore(tail_ptr, cast(ushort) t); + return len; + } +} + +/// Memory barrier - RISC-V fence instruction +private void fence() @nogc nothrow +{ + version (RISCV64) + asm @nogc nothrow { "fence rw, rw"; } + else version (RISCV32) + asm @nogc nothrow { "fence rw, rw"; } + else + asm @nogc nothrow { ""; } +} diff --git a/src/urt/driver/bl808_m0/bl_ops.d b/src/urt/driver/bl808_m0/bl_ops.d new file mode 100644 index 0000000..f483bbd --- /dev/null +++ b/src/urt/driver/bl808_m0/bl_ops.d @@ -0,0 +1,759 @@ +/// libwifi.a OS abstraction shim. +/// +/// The vendor LMAC blob (libwifi.a) routes every OS-flavoured call through +/// a single function-pointer table, g_bl_ops_funcs. The vendor SDK fills +/// it with FreeRTOS-backed implementations; we fill it with urt-backed +/// ones. Layout MUST match include/bl_os_adapter/bl_os_adapter.h exactly +/// -- the blob indexes the struct by offset. +/// +/// Threading model: cooperative single-thread with wifi_main running as a +/// urt fibre. Blob sync primitives are represented as stateful objects; calls +/// that would block yield an AwakenEvent, and ISR/host-side signals mutate the +/// primitive state so the host can resume the fibre when the event is ready. +/// +/// Anything not yet implemented returns conservative success/null where the +/// current open path requires it, and is hardened as more of the blob surface +/// is exercised. + +module urt.driver.bl808_m0.bl_ops; + +import urt.attribute : section; + +version (BL808_M0): + +import urt.mem.alloc : alloc, free, MemFlags; +import urt.mem : memset; +import urt.driver.bl618.irq : irq_disable, irq_enable, set_interrupts; +import urt.driver.bl618.timer : mtime_read, mtime_freq_hz; +import urt.fibre : Fibre, AwakenEvent, FibreEntryFunc, ResumeHandler, + yield, isInFibre; +import urt.util : InPlace; +import urt.lifetime : emplace; + +nothrow @nogc: + + +enum BL_OS_ADAPTER_VERSION = 0x00000001; + +extern (C): + +alias BL_TaskHandle_t = void*; +alias BL_EventGroup_t = void*; +alias BL_Timer_t = void*; +alias BL_Sem_t = void*; +alias BL_Mutex_t = void*; +alias BL_MessageQueue_t = void*; +alias BL_TimeOut_t = uint; +alias BL_TickType_t = uint; + +struct bl_ops_funcs_t +{ + int _version; + void function(const(char)*, ...) _printf; + void function(const(char)*) _puts; + void function(const(char)*, int, const(char)*, const(char)*) _assert; + int function() _init; + uint function() _enter_critical; + void function(uint) _exit_critical; + int function(long) _msleep; + int function(uint) _sleep; + BL_EventGroup_t function() _event_group_create; + void function(BL_EventGroup_t) _event_group_delete; + uint function(BL_EventGroup_t, uint) _event_group_send; + uint function(BL_EventGroup_t, uint, int, int, uint) _event_group_wait; + int function(int, void*, void*) _event_register; + int function(int, int) _event_notify; + int function(const(char)*, void*, uint, void*, uint, BL_TaskHandle_t) _task_create; + void function(BL_TaskHandle_t) _task_delete; + BL_TaskHandle_t function() _task_get_current_task; + BL_TaskHandle_t function() _task_notify_create; + void function(BL_TaskHandle_t) _task_notify; + void function(BL_TaskHandle_t, uint) _task_wait; + void function() _lock_gaint; + void function() _unlock_gaint; + void function(int, void*, void*) _irq_attach; + void function(int) _irq_enable; + void function(int) _irq_disable; + void* function() _workqueue_create; + int function(void*, void*, void*, long) _workqueue_submit_hp; + int function(void*, void*, void*, long) _workqueue_submit_lp; + BL_Timer_t function(void*, void*) _timer_create; + int function(BL_Timer_t, uint) _timer_delete; + int function(BL_Timer_t, long, long) _timer_start_once; + int function(BL_Timer_t, long, long) _timer_start_periodic; + BL_Sem_t function(uint) _sem_create; + void function(BL_Sem_t) _sem_delete; + int function(BL_Sem_t, uint) _sem_take; + int function(BL_Sem_t) _sem_give; + BL_Mutex_t function() _mutex_create; + void function(BL_Mutex_t) _mutex_delete; + int function(BL_Mutex_t) _mutex_lock; + int function(BL_Mutex_t) _mutex_unlock; + BL_MessageQueue_t function(uint, uint) _queue_create; + void function(BL_MessageQueue_t) _queue_delete; + int function(BL_MessageQueue_t, void*, uint, uint, int) _queue_send_wait; + int function(BL_MessageQueue_t, void*, uint) _queue_send; + int function(BL_MessageQueue_t, void*, uint, uint) _queue_recv; + void* function(uint) _malloc; + void function(void*) _free; + void* function(uint) _zalloc; + ulong function() _get_time_ms; + uint function() _get_tick; + void function(uint, const(char)*, const(char)*, int, const(char)*, ...) _log_write; + int function(BL_TaskHandle_t) _task_notify_isr; + void function(int) _yield_from_isr; + uint function(uint) _ms_to_tick; + BL_TimeOut_t function() _set_timeout; + int function(BL_TimeOut_t, BL_TickType_t*) _check_timeout; +} + + +import urt.driver.bl618.uart : uart0_hw_puts; + +void bl_ops_printf(const(char)* fmt, ...) +{ +} + +void bl_ops_puts(const(char)* s) +{ +} + +void bl_ops_log_write(uint level, const(char)* tag, const(char)* file, int line, const(char)* fmt, ...) +{ +} + +private size_t safe_cstr(const(char)* s) nothrow @nogc +{ + if (s is null) + return 0; + size_t addr = cast(size_t)s; + // M0 valid: flash 0x58000000+, OCRAM 0x22000000+/0x40000000+, TCM 0x6202F000+ + bool in_range = (addr >= 0x22000000 && addr < 0x80000000); + if (!in_range) + return 0; + ubyte first = cast(ubyte)s[0]; + if (first < 0x20 || first > 0x7E) + return 0; + size_t n = 0; + while (n < 256 && s[n] != 0) + ++n; + return n; +} + +void bl_ops_assert(const(char)* file, int line, const(char)* func, const(char)* expr) +{ + import urt.io : writef; + uart0_hw_puts("\n*** BLOB ASSERT: "); + print_strarg("file", file); + writef(":{0} ", line); + print_strarg("func", func); + print_strarg("expr", expr); + uart0_hw_puts(" ***\n"); + assert(false, "blob assert"); +} + +private void print_strarg(string label, const(char)* s) nothrow @nogc +{ + import urt.io : writef; + size_t n = safe_cstr(s); + if (n > 0) + uart0_hw_puts(s[0 .. n]); + else + writef("<{0}={1,08X} bogus>", label, cast(uint)cast(size_t)s); +} + +int bl_ops_init() { return 0; } + +// Critical sections -- global IRQ mask. Returns prior state in the low +// bit; symmetric with _exit_critical taking that token back. +uint bl_ops_enter_critical() +{ + return irq_disable() ? 1 : 0; +} + +void bl_ops_exit_critical(uint level) +{ + set_interrupts(level != 0); +} + +// Time / sleep. The blob treats "tick" values like an RTOS tick counter, +// and AP station timeout code compares them against constants such as +// 30000. Use a 1 kHz tick base so those constants retain their SDK meaning. +ulong bl_ops_get_time_ms() => mtime_read() / (mtime_freq_hz / 1000); +uint bl_ops_get_tick() => cast(uint)bl_ops_get_time_ms(); +uint bl_ops_ms_to_tick(uint ms) => ms; + +int bl_ops_msleep(long ms) +{ + if (ms <= 0) + return 0; + if (isInFibre()) + { + import urt.fibre : fibre_sleep = sleep; + import urt.time : msecs; + try + fibre_sleep(ms.msecs); + catch (Throwable) + assert(false, "wifi fibre msleep yield threw unexpectedly"); + return 0; + } + // Host context: no fibre to yield to. Honour the duration with a spin. + ulong target = mtime_read() + cast(ulong)ms * (mtime_freq_hz / 1000); + while (mtime_read() < target) {} + return 0; +} + +int bl_ops_sleep(uint s) => bl_ops_msleep(s * 1000L); + +BL_TimeOut_t bl_ops_set_timeout() => bl_ops_get_tick(); + +int bl_ops_check_timeout(BL_TimeOut_t start, BL_TickType_t* ticks_to_wait) +{ + if (ticks_to_wait is null) + return 0; + uint elapsed = bl_ops_get_tick() - start; + if (elapsed >= *ticks_to_wait) + return 1; + *ticks_to_wait -= elapsed; + return 0; +} + +// Memory +void* bl_ops_malloc(uint size) +{ + return alloc(size, uint.sizeof, MemFlags.dma).ptr; +} + +void bl_ops_free(void* p) +{ + if (p is null) + return; + // urt.mem.alloc.free only uses mem.ptr; length is irrelevant. + free(p[0 .. 1]); +} + +void* bl_ops_zalloc(uint size) +{ + void* p = alloc(size, uint.sizeof, MemFlags.dma).ptr; + if (p !is null) + memset(p, 0, size); + return p; +} + +// ---- Cooperative single-thread primitives ------------------------------ +// +// In our drain-on-update model there is no real concurrency between blob +// "tasks". Mutexes/semaphores/events become trivial counters/flags. If we +// later run the blob on top of urt fibres these grow real bodies. + +struct shim_mutex { uint locked; } +struct shim_sem { int count; int max; } +struct shim_event { uint bits; } + +BL_Mutex_t bl_ops_mutex_create() +{ + auto m = cast(shim_mutex*)bl_ops_zalloc(shim_mutex.sizeof); + return m; +} +void bl_ops_mutex_delete(BL_Mutex_t h) { bl_ops_free(h); } +int bl_ops_mutex_lock(BL_Mutex_t h) +{ + auto m = cast(shim_mutex*)h; + if (m is null) return -1; + m.locked = 1; + return 0; +} +int bl_ops_mutex_unlock(BL_Mutex_t h) +{ + auto m = cast(shim_mutex*)h; + if (m is null) return -1; + m.locked = 0; + return 0; +} + +BL_Sem_t bl_ops_sem_create(uint init) +{ + auto s = cast(shim_sem*)bl_ops_zalloc(shim_sem.sizeof); + if (s !is null) + s.count = cast(int)init; + return s; +} +void bl_ops_sem_delete(BL_Sem_t h) { bl_ops_free(h); } +int bl_ops_sem_take(BL_Sem_t h, uint ticks) +{ + auto s = cast(shim_sem*)h; + if (s is null) return -1; + + while (s.count == 0) + { + if (isInFibre()) + { + auto ev = InPlace!SemAwaken(s); + yield_nothrow(ev); + } + else if (!wifi_pump_one_for_host()) + return -1; + } + --s.count; + return 0; +} +int bl_ops_sem_give(BL_Sem_t h) +{ + auto s = cast(shim_sem*)h; + if (s is null) return -1; + ++s.count; + wifi_signal_ready(); + return 0; +} + +BL_EventGroup_t bl_ops_event_group_create() +{ + return cast(shim_event*)bl_ops_zalloc(shim_event.sizeof); +} +void bl_ops_event_group_delete(BL_EventGroup_t h) { bl_ops_free(h); } +uint bl_ops_event_group_send(BL_EventGroup_t h, uint bits) +{ + auto e = cast(shim_event*)h; + if (e is null) return 0; + e.bits |= bits; + wifi_signal_ready(); + return e.bits; +} +uint bl_ops_event_group_wait(BL_EventGroup_t h, uint wait_bits, int clear_on_exit, int wait_all, uint block_ticks) +{ + auto e = cast(shim_event*)h; + if (e is null) return 0; + + bool waitAll = wait_all != 0; + while (true) + { + uint got = e.bits & wait_bits; + if (waitAll ? (got == wait_bits) : (got != 0)) + { + if (clear_on_exit) + e.bits &= ~got; + return got; + } + + if (isInFibre()) + { + auto ev = InPlace!EventGroupAwaken(e, wait_bits, waitAll); + yield_nothrow(ev); + } + else if (!wifi_pump_one_for_host()) + return 0; + } +} + +int bl_ops_event_register(int type, void* cb, void* arg) { return 0; } +int bl_ops_event_notify(int evt, int val) { return 0; } + +// "Gaint" (giant) lock -- global serialising lock. Map to enter_critical. +void bl_ops_lock_gaint() +{ + irq_disable(); +} +void bl_ops_unlock_gaint() +{ + irq_enable(); +} + + +// ==================================================================== +// Fibre infrastructure for the wifi_main task. +// +// libwifi.a's wifi_main is a long-lived event loop that processes LMAC +// messages -- vendor SDK runs it as a FreeRTOS task. We run it as a +// single urt fibre. Blocking primitives (sem_take/event_group_wait/ +// queue_recv) yield to the main fibre when called from inside the +// wifi_main fibre, and pump the wifi fibre when called from host code +// (e.g. bl_send_reset waiting for MM_RESET_CFM). +// +// One fibre, one pending awaken event at a time. If we need more later +// (concurrent waiters) we extend; for now wifi_main is the only thing. +// ==================================================================== + +__gshared Fibre* _wifi_fibre; +__gshared AwakenEvent _wifi_pending_event; + +extern(D) +{ + alias WifiWakeCallback = void function() nothrow @nogc; + private __gshared WifiWakeCallback _wifi_wake_callback; + + public void wifi_set_wake_callback(WifiWakeCallback cb) + { + _wifi_wake_callback = cb; + } + + public void wifi_signal_ready() + { + auto cb = _wifi_wake_callback; + if (cb !is null) + cb(); + } +} + +private extern (D) ResumeHandler wifi_yield_handler(ref Fibre yielding, AwakenEvent ev) nothrow @nogc +{ + _wifi_pending_event = ev; + return null; +} + +/// nothrow wrapper around urt.fibre.yield. The only path yield() can +/// throw on is fibre-abort, which we never trigger. +private void yield_nothrow(AwakenEvent ev) nothrow @nogc +{ + try + yield(ev); + catch (Throwable) + assert(false, "wifi fibre yield threw unexpectedly"); +} + +/// Set to true once wifi_main has reached its event-loop entry (first +/// call to bl_sleep_check). Used by wifi_hw_open to pump wifi_main +/// through its init *before* writing A2E_TRIGGER -- otherwise vendor's +/// Configure-IPC step inside wifi_main clobbers our trigger bit and +/// the host's bl_send_reset is never seen. +public __gshared bool wifi_main_in_main_loop; + +/// Resume the wifi fibre if its awaken event is ready (or if it's just +/// been spawned and hasn't run yet). Safe to call repeatedly; a no-op +/// when the fibre is finished or blocked on an unsatisfied event. +public void wifi_fibre_pump() +{ + if (_wifi_fibre is null || _wifi_fibre.isFinished) + return; + if (_wifi_pending_event !is null && !_wifi_pending_event.ready()) + return; + _wifi_pending_event = null; + _wifi_fibre.resume(); +} + +/// Host-side pump step for sync waits (bl_ops_*_wait called from host +/// context, not from the fibre). Returns true if the fibre is still live; +/// false if dead and the wait must give up. +/// +/// All wifi_main wakes come from real IRQs (vec 70 mac_irq, vec 79 +/// bl_irq_handler) calling into the blob's natural shim chain +/// (sem_give/event_group_send/queue_send/task_notify), which makes the +/// appropriate AwakenEvent ready. No synthetic wakes, no manual A2E +/// dispatch -- if wifi_main doesn't progress, the real IRQ wiring is wrong +/// and that's the bug to fix. +private bool wifi_pump_one_for_host() +{ + if (_wifi_fibre is null || _wifi_fibre.isFinished) + return false; + wifi_fibre_pump(); + return true; +} + +// AwakenEvent subclasses -- one per blocking primitive. AwakenEvent's +// methods are extern(D) (inside an extern(C++) class), so our overrides +// have to drop back to D linkage from the file-level extern(C). +extern (C++) class SemAwaken : AwakenEvent +{ +extern(D) nothrow @nogc: + shim_sem* sem; + this(shim_sem* s) { sem = s; } + override bool ready() { return sem.count > 0; } +} + +extern (C++) class EventGroupAwaken : AwakenEvent +{ +extern(D) nothrow @nogc: + shim_event* ev; + uint mask; + bool wait_all; + this(shim_event* e, uint m, bool all) { ev = e; mask = m; wait_all = all; } + override bool ready() + { + uint got = ev.bits & mask; + return wait_all ? (got == mask) : (got != 0); + } +} + +extern (C++) class QueueAwaken : AwakenEvent +{ +extern(D) nothrow @nogc: + shim_queue* q; + this(shim_queue* x) { q = x; } + override bool ready() { return q.count > 0; } +} + +extern (C++) class TaskAwaken : AwakenEvent +{ +extern(D) nothrow @nogc: + shim_task* task; + this(shim_task* t) { task = t; } + override bool ready() { return task.notify_count > 0; } +} + + + +// Tasks. First task_create spawns the wifi fibre; subsequent calls are +// recorded but ignored (we only run wifi_main on this platform). +// +// FreeRTOS task notifications are a per-task counter: notify() increments, +// wait() decrements (blocking until non-zero). Used by wifi_main as its +// idle/wake primitive when an ISR has data to hand off. We have one task, +// so one shim_task is enough; the handle the blob passes is its address. + +struct shim_task +{ + uint notify_count; +} + +__gshared shim_task _wifi_task; + +int bl_ops_task_create(const(char)* name, void* entry, uint stack_depth, void* param, uint prio, BL_TaskHandle_t handle) +{ + if (_wifi_fibre !is null) + return 0; // already have one + + // FreeRTOS StackType_t is uint32_t -> stack_depth is words. Match + // the vendor's 1536 words = 6KB if smaller is passed, otherwise + // honour the caller's request. + size_t stack_bytes = stack_depth * 4; + if (stack_bytes < 6 * 1024) + stack_bytes = 6 * 1024; + + void[] mem = alloc(Fibre.sizeof, Fibre.alignof); + if (mem.ptr is null) + return -1; + _wifi_fibre = cast(Fibre*)mem.ptr; + emplace!Fibre(_wifi_fibre, cast(FibreEntryFunc)entry, &wifi_yield_handler, param, stack_bytes); + return 0; +} +void bl_ops_task_delete(BL_TaskHandle_t h) {} +BL_TaskHandle_t bl_ops_task_get_current() => cast(void*)&_wifi_task; +BL_TaskHandle_t bl_ops_task_notify_create() => cast(void*)&_wifi_task; + +void bl_ops_task_notify(BL_TaskHandle_t h) +{ + auto t = cast(shim_task*)h; + if (t is null) return; + ++t.notify_count; + wifi_signal_ready(); +} + +void bl_ops_task_wait(BL_TaskHandle_t h, uint ticks) +{ + auto t = cast(shim_task*)h; + if (t is null) + return; + while (t.notify_count == 0) + { + if (isInFibre()) + { + auto ev = InPlace!TaskAwaken(t); + yield_nothrow(ev); + } + else if (!wifi_pump_one_for_host()) + return; + } + --t.notify_count; +} + +// ISR variant -- on this platform we don't have preemption, so an "ISR +// notify" is the same as a task notify. Return 1 to indicate "would +// cause a context switch" (vendor's flag is purely informational here). +int bl_ops_task_notify_isr(BL_TaskHandle_t h) +{ + bl_ops_task_notify(h); + return 1; +} +void bl_ops_yield_from_isr(int yield) {} + +// Queues -- simple heap-allocated ring. SPSC is enough since we're +// cooperative. Capacity = queue_len * item_size bytes; head/tail are +// indices in items, not bytes. +struct shim_queue +{ + ubyte* buf; + uint item_size; + uint capacity; // number of items + uint head; // next write + uint tail; // next read + uint count; +} + +BL_MessageQueue_t bl_ops_queue_create(uint queue_len, uint item_size) +{ + auto q = cast(shim_queue*)bl_ops_zalloc(shim_queue.sizeof); + if (q is null) return null; + q.buf = cast(ubyte*)bl_ops_malloc(queue_len * item_size); + if (q.buf is null) { bl_ops_free(q); return null; } + q.item_size = item_size; + q.capacity = queue_len; + return q; +} +void bl_ops_queue_delete(BL_MessageQueue_t h) +{ + auto q = cast(shim_queue*)h; + if (q is null) return; + bl_ops_free(q.buf); + bl_ops_free(q); +} +int bl_ops_queue_send(BL_MessageQueue_t h, void* item, uint len) +{ + auto q = cast(shim_queue*)h; + if (q is null || q.count == q.capacity) return -1; + auto slot = q.buf + q.head * q.item_size; + slot[0 .. q.item_size] = (cast(ubyte*)item)[0 .. q.item_size]; + q.head = (q.head + 1) % q.capacity; + ++q.count; + wifi_signal_ready(); + return 0; +} +int bl_ops_queue_send_wait(BL_MessageQueue_t h, void* item, uint len, uint ticks, int prio) + => bl_ops_queue_send(h, item, len); +int bl_ops_queue_recv(BL_MessageQueue_t h, void* item, uint len, uint ticks) +{ + auto q = cast(shim_queue*)h; + if (q is null) return -1; + + while (q.count == 0) + { + if (isInFibre()) + { + auto ev = InPlace!QueueAwaken(q); + yield_nothrow(ev); + } + else if (!wifi_pump_one_for_host()) + return -1; + } + auto slot = q.buf + q.tail * q.item_size; + (cast(ubyte*)item)[0 .. q.item_size] = slot[0 .. q.item_size]; + q.tail = (q.tail + 1) % q.capacity; + --q.count; + return 0; +} + +// Timers -- record callback + period; we'll drive the firing logic from +// our update loop once that's wired. For now, creation succeeds but the +// timer never fires. +struct shim_timer +{ + extern(C) void function() nothrow @nogc cb; + void* arg; + ulong fire_at_us; + ulong period_us; + ubyte active; +} + +BL_Timer_t bl_ops_timer_create(void* func, void* arg) +{ + auto t = cast(shim_timer*)bl_ops_zalloc(shim_timer.sizeof); + if (t !is null) + { + t.cb = cast(typeof(shim_timer.cb))func; + t.arg = arg; + } + return t; +} +int bl_ops_timer_delete(BL_Timer_t h, uint ticks) +{ + bl_ops_free(h); + return 0; +} +int bl_ops_timer_start_once(BL_Timer_t h, long t_sec, long t_nsec) +{ + auto t = cast(shim_timer*)h; + if (t is null) return -1; + ulong us = cast(ulong)t_sec * 1_000_000UL + cast(ulong)t_nsec / 1000; + t.fire_at_us = mtime_read() + us; + t.period_us = 0; + t.active = 1; + return 0; +} +int bl_ops_timer_start_periodic(BL_Timer_t h, long t_sec, long t_nsec) +{ + auto t = cast(shim_timer*)h; + if (t is null) return -1; + ulong us = cast(ulong)t_sec * 1_000_000UL + cast(ulong)t_nsec / 1000; + t.fire_at_us = mtime_read() + us; + t.period_us = us; + t.active = 1; + return 0; +} + +void bl_ops_irq_attach(int n, void* f, void* arg) {} +void bl_ops_irq_enable(int n) {} +void bl_ops_irq_disable(int n) {} + +// Workqueues -- run submitted work synchronously for now. Two priority +// levels collapse to one. +void* bl_ops_workqueue_create() => cast(void*)1; // non-null sentinel +int bl_ops_workqueue_submit_hp(void* work, void* worker, void* argv, long tick) +{ + if (worker !is null) + { + alias work_fn = extern(C) void function(void*) nothrow @nogc; + (cast(work_fn)worker)(argv); + } + return 0; +} +int bl_ops_workqueue_submit_lp(void* work, void* worker, void* argv, long tick) + => bl_ops_workqueue_submit_hp(work, worker, argv, tick); + + +@section(".sram_data.wifi") __gshared bl_ops_funcs_t g_bl_ops_funcs = { + _version: BL_OS_ADAPTER_VERSION, + _printf: &bl_ops_printf, + _puts: &bl_ops_puts, + _assert: &bl_ops_assert, + _init: &bl_ops_init, + _enter_critical: &bl_ops_enter_critical, + _exit_critical: &bl_ops_exit_critical, + _msleep: &bl_ops_msleep, + _sleep: &bl_ops_sleep, + _event_group_create: &bl_ops_event_group_create, + _event_group_delete: &bl_ops_event_group_delete, + _event_group_send: &bl_ops_event_group_send, + _event_group_wait: &bl_ops_event_group_wait, + _event_register: &bl_ops_event_register, + _event_notify: &bl_ops_event_notify, + _task_create: &bl_ops_task_create, + _task_delete: &bl_ops_task_delete, + _task_get_current_task: &bl_ops_task_get_current, + _task_notify_create: &bl_ops_task_notify_create, + _task_notify: &bl_ops_task_notify, + _task_wait: &bl_ops_task_wait, + _lock_gaint: &bl_ops_lock_gaint, + _unlock_gaint: &bl_ops_unlock_gaint, + _irq_attach: &bl_ops_irq_attach, + _irq_enable: &bl_ops_irq_enable, + _irq_disable: &bl_ops_irq_disable, + _workqueue_create: &bl_ops_workqueue_create, + _workqueue_submit_hp: &bl_ops_workqueue_submit_hp, + _workqueue_submit_lp: &bl_ops_workqueue_submit_lp, + _timer_create: &bl_ops_timer_create, + _timer_delete: &bl_ops_timer_delete, + _timer_start_once: &bl_ops_timer_start_once, + _timer_start_periodic: &bl_ops_timer_start_periodic, + _sem_create: &bl_ops_sem_create, + _sem_delete: &bl_ops_sem_delete, + _sem_take: &bl_ops_sem_take, + _sem_give: &bl_ops_sem_give, + _mutex_create: &bl_ops_mutex_create, + _mutex_delete: &bl_ops_mutex_delete, + _mutex_lock: &bl_ops_mutex_lock, + _mutex_unlock: &bl_ops_mutex_unlock, + _queue_create: &bl_ops_queue_create, + _queue_delete: &bl_ops_queue_delete, + _queue_send_wait: &bl_ops_queue_send_wait, + _queue_send: &bl_ops_queue_send, + _queue_recv: &bl_ops_queue_recv, + _malloc: &bl_ops_malloc, + _free: &bl_ops_free, + _zalloc: &bl_ops_zalloc, + _get_time_ms: &bl_ops_get_time_ms, + _get_tick: &bl_ops_get_tick, + _log_write: &bl_ops_log_write, + _task_notify_isr: &bl_ops_task_notify_isr, + _yield_from_isr: &bl_ops_yield_from_isr, + _ms_to_tick: &bl_ops_ms_to_tick, + _set_timeout: &bl_ops_set_timeout, + _check_timeout: &bl_ops_check_timeout, +}; diff --git a/src/urt/driver/bl808_m0/start.S b/src/urt/driver/bl808_m0/start.S new file mode 100644 index 0000000..f8bc38a --- /dev/null +++ b/src/urt/driver/bl808_m0/start.S @@ -0,0 +1,460 @@ +/* BL808 M0 (T-Head E907 RV32IMAFC) startup + * + * System init core -- runs first out of reset on the M0 side of + * the BL808 dual-core SoC. Hands off to m0_bringup (D-side, start.d) + * before sys_init so HBN/PDS/clock/PLL setup and any D0/LP handshake + * happens before D module ctors run. + * + * Boot flow: + * 1. CPU setup -- disable IRQ, enable extensions, FPU, trap vectors, mtvt + * 2. Retention -- clear HBN/PDS sleep-state bits from prior wake + * 3. Core regs -- gp, tp, sp + * 4. Section init -- .got, .tdata, .tbss, .bss, .data + * 5. Caches -- I-cache enable + * 6. Interrupts -- dispatch table, enable MIE+MEIE + * 7. D runtime -- m0_bringup, sys_init, .init_array, main + * + * T-Head custom CSR numbers: + * mxstatus = 0x7C0 (T-Head ISA extension enable) + * mhcr = 0x7C1 (hardware cache control) + * mhint = 0x7C5 (performance hints) + * mtvt = 0x307 (CLIC vector table base -- standard RISC-V CLIC + * spec, NOT a T-Head custom CSR. Confirmed against + * vendor's riscv_encoding.h. Writing the wrong CSR + * leaves mtvt=0 and every IRQ vectors via address 0, + * hanging the chip silently.) + */ +#define CSR_MXSTATUS 0x7C0 +#define CSR_MHCR 0x7C1 +#define CSR_MHINT 0x7C5 +#define CSR_MTVT 0x307 + +/* Early-boot UART setup. Bouffalo Boot2 is mute (doesn't print, doesn't + * leave UART0 set up). The init block below uses pure MMIO writes -- no stack, + * no .got, no .bss needed -- so m0_bringup can emit the first readable line. + * + * M1s Dock: UART0 -> BL702 USB-CDC bridge on GPIO22 (TX) / GPIO21 (RX). + * 2 Mbaud from MCU PBCLK = XTAL = 40 MHz at cold-boot (no PLL yet). + * BL702 fakes the baud so divisor precision is cosmetic. + * + * UART0 base 0x2000_A000, FIFO_WDATA offset 0x88 -> 0x2000_A088. */ +#define UART0_FIFO_WDATA 0x2000A088 + + .section .text.entry, "ax" + .global _start + .type _start, @function + .align 2 + +_start: + /* -- 0. UART0 setup so markers transmit ---------------------- */ + /* Discovered via config matrix: at M0 cold-boot, MCU_PBCLK is at some + * unknown PLL-derived frequency (Boot2 left it that way). XCLK however + * is deterministically 40 MHz from XTAL, and the 160 MHz PLL is up. We + * pick XCLK because the divisor math is simple (40 MHz / 20 = 2 Mbaud) + * and the clock won't shift if downstream code touches the PLL. */ + + /* HBN_GLB (0x2000_F030): select UART_CLK = XCLK (enum 2 -> SEL2=1, SEL=0). + * 2-bit selector split across bit 15 (SEL2 = hi) and bit 2 (SEL = lo). */ + li t0, 0x2000F030 + lw t1, 0(t0) + li t2, 0xFFFF7FFB /* ~((1<<2)|(1<<15)) -- clear both selector bits */ + and t1, t1, t2 + li t2, (1 << 15) /* SEL2 = 1 */ + or t1, t1, t2 + sw t1, 0(t0) + + /* GLB_UART_CFG0 (0x2000_0150): enable UART peripheral clock, div = 0 */ + li t0, 0x20000150 + lw t1, 0(t0) + li t2, 0xFFFFFFF8 /* clear DIV bits 0-2 */ + and t1, t1, t2 + ori t1, t1, (1 << 4) /* CLK_EN */ + sw t1, 0(t0) + + /* GLB_PARM_CFG0 (0x2000_0510): UART swap groups bit 3 + bit 5 */ + li t0, 0x20000510 + lw t1, 0(t0) + ori t1, t1, (1 << 3) | (1 << 5) + sw t1, 0(t0) + + /* GPIO14 (TX) cfg @ 0x2000_08FC and GPIO15 (RX) cfg @ 0x2000_0900: + * IE=1, SMT=1, DRV=1, PU=1, OE=0, FUNC_SEL=7 (UART) -> 0x717 */ + li t1, 0x00000717 + li t0, 0x200008FC + sw t1, 0(t0) + li t0, 0x20000900 + sw t1, 0(t0) + + /* GLB_UART_CFG2 (0x2000_0158): slot 8 <- UART0_TXD(2), slot 9 <- UART0_RXD(3) */ + li t0, 0x20000158 + lw t1, 0(t0) + li t2, 0xFFFFFF00 + and t1, t1, t2 + li t2, (2 << 0) | (3 << 4) + or t1, t1, t2 + sw t1, 0(t0) + + /* UART0 BIT_PRD (0x2000_A008): 40 MHz / 2 Mbaud = 20. ((20-1)<<16)|(20-1) */ + li t0, 0x2000A008 + li t1, 0x00130013 + sw t1, 0(t0) + + /* UART0 UTX_CONFIG (0x2000_A000): + * bit 0 UTX_EN + * bit 2 UTX_FRM_EN + * bits 10:8 = 7 (data bits field = data_bits - 1 -> 8 data bits) + * bits 12:11 = 1 (stop bits) + * Total: 0xF05. NB the field encodings: BIT_CNT_D = bits-1, BIT_CNT_P at + * [12:11] (not [13:12] like the D0 driver has wrong). */ + li t0, 0x2000A000 + li t1, 0x00000F05 + sw t1, 0(t0) + + /* -- 1. CPU setup ---------------------------------------------- */ + + /* Disable interrupts */ + csrc mstatus, 0x0008 /* MIE */ + + /* Enable T-Head ISA extensions (THEADISAEE + MM) */ + li t0, (1 << 22) | (1 << 15) + csrs CSR_MXSTATUS, t0 + + /* Enable FPU (FS = Initial) -- E907 has single-precision FPU */ + li t0, (1 << 13) + csrs mstatus, t0 + + /* HBN/PDS retention bit clear -- wipe any sleep state left from prior HBN cycle */ + li t0, 0x2000F034 + lw t1, 0(t0) + li t2, 0xFFFFFF3F + and t1, t1, t2 + sw t1, 0(t0) + + li t0, 0x2000E020 + lw t1, 0(t0) + li t2, 0x3FFFFF00 + and t1, t1, t2 + sw t1, 0(t0) + + li t0, 0x2000E028 + lw t1, 0(t0) + li t2, 0xFFF00000 + and t1, t1, t2 + sw t1, 0(t0) + + /* mtvec in CLIC mode (bits[1:0]=11). base = sync-trap handler only; + * IRQs are dispatched via mtvt[id] entries, never through mtvec.base. */ + la t0, _trap_exception + ori t0, t0, 3 + csrw mtvec, t0 + + /* CLIC vector table base -- flat .word table of handler addresses. + * Every entry points at _clic_dispatch (ipush/ipop trampoline). */ + la t0, __clic_vectors + csrw CSR_MTVT, t0 + + /* -- 2. Core registers ----------------------------------------- */ + + .option push + .option norelax + la gp, __global_pointer$ + .option pop + la tp, _tdata_start + la sp, _stack_top + + /* -- 3. Section init ------------------------------------------- */ + + /* Copy .ramfunc from flash (LMA) to ITCM (VMA) -- @critical functions. + * Empty when the build has no @critical code; loop is then a no-op. */ + la a0, _ramfunc_start + la a1, _ramfunc_load + la a2, _ramfunc_end + bgeu a0, a2, .Lramfunc_done +.Lramfunc_copy: + lw t0, 0(a1) + sw t0, 0(a0) + addi a0, a0, 4 + addi a1, a1, 4 + bltu a0, a2, .Lramfunc_copy +.Lramfunc_done: + + /* Copy .got from flash (LMA) to OCRAM (VMA) */ + la a0, _got_start + la a1, _got_load + la a2, _got_end + bgeu a0, a2, .Lgot_done +.Lgot_copy: + lw t0, 0(a1) + sw t0, 0(a0) + addi a0, a0, 4 + addi a1, a1, 4 + bltu a0, a2, .Lgot_copy +.Lgot_done: + + /* Copy .sram_data_tail from flash (LMA) to WIFIRAM (VMA) -- WiFi-side + * @fast_data packed into the slack after the vendor .wifibss window. */ + la a0, _sram_data_tail_start + la a1, _sram_data_tail_load + la a2, _sram_data_tail_end + bgeu a0, a2, .Lsram_data_tail_done +.Lsram_data_tail_copy: + lw t0, 0(a1) + sw t0, 0(a0) + addi a0, a0, 4 + addi a1, a1, 4 + bltu a0, a2, .Lsram_data_tail_copy +.Lsram_data_tail_done: + + /* Copy .sram_data from flash (LMA) to OCRAM (VMA) -- @fast_data globals. + * Empty when no @fast_data is in use; loop is a no-op. */ + la a0, _sram_data_start + la a1, _sram_data_load + la a2, _sram_data_end + bgeu a0, a2, .Lsram_data_done +.Lsram_data_copy: + lw t0, 0(a1) + sw t0, 0(a0) + addi a0, a0, 4 + addi a1, a1, 4 + bltu a0, a2, .Lsram_data_copy +.Lsram_data_done: + + /* Copy .tdata from flash to DTCM */ + la a0, _tdata_start + la a1, _tdata_load + la a2, _tdata_end + bgeu a0, a2, .Ltdata_done +.Ltdata_copy: + lw t0, 0(a1) + sw t0, 0(a0) + addi a0, a0, 4 + addi a1, a1, 4 + bltu a0, a2, .Ltdata_copy +.Ltdata_done: + + /* Zero .tbss */ + la a0, _tbss_start + la a2, _tbss_end + bgeu a0, a2, .Ltbss_done +.Ltbss_zero: + sw zero, 0(a0) + addi a0, a0, 4 + bltu a0, a2, .Ltbss_zero +.Ltbss_done: + + /* Copy .data from flash to OCRAM */ + la a0, _data_start + la a1, _data_load + la a2, _data_end + bgeu a0, a2, .Ldata_done +.Ldata_copy: + lw t0, 0(a1) + sw t0, 0(a0) + addi a0, a0, 4 + addi a1, a1, 4 + bltu a0, a2, .Ldata_copy +.Ldata_done: + + /* Zero .bss */ + la a0, _bss_start + la a2, _bss_end + bgeu a0, a2, .Lbss_done +.Lbss_zero: + sw zero, 0(a0) + addi a0, a0, 4 + bltu a0, a2, .Lbss_zero +.Lbss_done: + + /* Zero .wifibss -- vendor WiFi shared/LMAC state. This section is + * NOLOAD in the linker script, but the SDK still clears it explicitly + * during start_load before wifi_main touches COMMON state. */ + la a0, __wifi_bss_start + la a2, __wifi_bss_end + bgeu a0, a2, .Lwifi_bss_done +.Lwifi_bss_zero: + sw zero, 0(a0) + addi a0, a0, 4 + bltu a0, a2, .Lwifi_bss_zero +.Lwifi_bss_done: + + /* -- 4. Caches ------------------------------------------------- */ + + /* D-cache and branch prediction are intentionally OFF -- we set + * only IE (bit 0). Vendor's csi_dcache_enable writes MHCR=0x103F + * (DE | WB | WA | RS | BPE | L0BTB), and MHINT=0x0C for D$ prefetch + + * write-buffer auto-merge. + * + * Functional: chip works either way, this is purely a perf cost -- + * data loads/stores hit SRAM directly (~10x slower on OCRAM, worse on + * PSRAM), and every conditional branch stalls the pipeline. Visible + * once wifi/TLS are running real traffic. + * + * Before flipping: we MUST first configure the SYSMAP CSRs to mark + * MMIO / DMA regions as uncacheable. Without that, enabling D-cache + * could return stale IPC status reads or hide DMA writes. Vendor sets + * SYSMAP via Tzc_Sec_PSRAMA_Access_Set_Not_Lock and friends before + * csi_dcache_enable. Our start.d:d0_image_load already brackets PSRAM + * writes with D-cache disable/enable, implying the original intent. */ + li t0, (1 << 0) /* IE: I-cache enable */ + csrs CSR_MHCR, t0 + + /* -- 5. Interrupts --------------------------------------------- */ + /* IRQ controller setup + mstatus.MIE enable are owned by sys_init + * (bl_common/system.d), which calls irq_init() then irq_global_enable() + * once every subsystem is in a known state. MIE stays off through + * m0_bringup -- chip init is pure MMIO and doesn't need IRQs. */ + + /* -- 6. D runtime ---------------------------------------------- */ + + /* M0 init: HBN/PDS/clock/PLL setup, D0/LP handshake (D-side) */ + call m0_bringup + + call sys_init + + /* Run .init_array (D module constructors, etc.) */ + la s0, __init_array_start + la s1, __init_array_end + bgeu s0, s1, .Linit_done +.Linit_loop: + lw t0, 0(s0) + jalr t0 + addi s0, s0, 4 + bltu s0, s1, .Linit_loop +.Linit_done: + + /* Enter main -- urt/package.d's extern(C) main(int argc, char** argv). + * argc=0/argv=null so the D-side _Dmain sees an empty args slice. + * Zero fp so stack walks terminate cleanly at main; zero ra so a return + * from main traps (caught by _crash_handler). */ + li a0, 0 + li a1, 0 + li s0, 0 + li ra, 0 + j main + + .size _start, . - _start + +/* -- CLIC vector table -- flat .word handler addresses -------------- + * + * Every entry points at _clic_dispatch; that trampoline reads mcause to + * learn the IRQ id and dispatches via the runtime handler table in D + * (urt.driver.bl618.irq). Size must match irq_max in that module. */ + .section .rodata, "a" + .align 6 + .global __clic_vectors +__clic_vectors: + .rept 80 + .word _clic_dispatch + .endr + +/* -- IRQ dispatch stub ---------------------------------------------- + * + * Entered from the CLIC hardware vector via mtvt[id]. ipush pushes + * caller-saved GPRs + mepc + mcause to the stack (T-Head custom; uses + * mscratch as the IRQ stack pointer if non-zero). We clear MIE + * immediately so a single ISR doesn't nest until we've earned the + * right to. ipop pops and issues mret with hardware tail-chaining. + * Restoring mepc/mcause from the stack (rather than relying on the + * live CSR) is what makes nesting safe -- the bare sw/lw + mret path + * corrupts the outer frame on nested IRQs. + * + * FPU save/restore: th.ipush handles ONLY integer regs. RISC-V ABI + * marks ft0-ft11 + fa0-fa7 as caller-saved; LDC can spill into them + * even for nominally-integer D code at -O2 (memcpy idiom, register + * pressure). Without this stanza, a timer IRQ firing during ecdh + * (which has scratch values live in f-regs) corrupts the interrupted + * code and ecdh hangs forever in a now-impossible loop condition. + * Vendor's trap_c does the same (riscv_savefpu / restorefpu around + * the dispatched handler). RV32F = 32 single-precision f-regs * 4 + * bytes = 128 bytes; allocate room on the IRQ stack between ipush + * and the handler call. */ + .section .text, "ax" + .align 2 + .global _clic_dispatch + .type _clic_dispatch, @function + .option push + .option arch, +xtheadint +_clic_dispatch: + th.ipush + csrr t0, mepc + la t1, __irq_sample_mepc + sw t0, 0(t1) + csrr t0, mcause + la t1, __irq_sample_mcause + sw t0, 0(t1) + mv t0, sp + la t1, __irq_sample_sp + sw t0, 0(t1) + csrci mstatus, 0x8 + csrr a0, mcause + andi a0, a0, 0x3FF + call _irq_dispatch + th.ipop + .size _clic_dispatch, . - _clic_dispatch + .option pop + +/* -- Exception (sync trap) -- save all regs + dump --------------- */ + .align 2 +_trap_exception: + /* Redirect mtvec to a spin so double-faults don't recurse */ + la t0, .Lcrash_spin2 + csrw mtvec, t0 + + /* Save all 31 GP regs for the crash handler. 31*4 = 124, frame + * rounded to 128 for 16-byte alignment. Layout matches D0: + * [0]=ra [1]=sp [2]=gp [3]=tp [4]=t0..[6]=t2 + * [7]=s0/fp [8]=s1 [9]=a0..[16]=a7 + * [17]=s2..[26]=s11 [27]=t3..[30]=t6 */ + addi sp, sp, -128 + sw ra, 0(sp) + sw sp, 4(sp) + sw gp, 8(sp) + sw tp, 12(sp) + sw t0, 16(sp) + sw t1, 20(sp) + sw t2, 24(sp) + sw s0, 28(sp) + sw s1, 32(sp) + sw a0, 36(sp) + sw a1, 40(sp) + sw a2, 44(sp) + sw a3, 48(sp) + sw a4, 52(sp) + sw a5, 56(sp) + sw a6, 60(sp) + sw a7, 64(sp) + sw s2, 68(sp) + sw s3, 72(sp) + sw s4, 76(sp) + sw s5, 80(sp) + sw s6, 84(sp) + sw s7, 88(sp) + sw s8, 92(sp) + sw s9, 96(sp) + sw s10,100(sp) + sw s11,104(sp) + sw t3, 108(sp) + sw t4, 112(sp) + sw t5, 116(sp) + sw t6, 120(sp) + + /* Fix saved sp to the pre-trap value */ + addi t0, sp, 128 + sw t0, 4(sp) + + /* a0 = regs*, a1 = mcause, a2 = mepc, a3 = mtval */ + mv a0, sp + csrr a1, mcause + csrr a2, mepc + csrr a3, mtval + + call _crash_handler + +.Lcrash_spin: + wfi + j .Lcrash_spin + + .align 2 +.Lcrash_spin2: + wfi + j .Lcrash_spin2 diff --git a/src/urt/driver/bl808_m0/start.d b/src/urt/driver/bl808_m0/start.d new file mode 100644 index 0000000..c8ea360 --- /dev/null +++ b/src/urt/driver/bl808_m0/start.d @@ -0,0 +1,263 @@ +// BL808 M0 chip init and D0 launch +// +// m0_bringup() runs from start.S before sys_init: chip-wide power, clocks, +// PSRAM, L2 partition, TZC, then D0 launch. D0's own start.S spins ~80ms +// waiting for M0 to finish clock setup, so launching it here (well before +// M0's main() loop comes up) is safe -- both cores run in parallel from +// that point, and M0's XRAM rings are ready by the time D0 needs IPC. +module urt.driver.bl808_m0.start; + +import core.volatile; +import urt.zip : gzip_uncompress; +import urt.driver.bl618.uart : uart0_early_init, uart0_hw_puts; + +@nogc nothrow: + +// M1s Dock: UART0 -> BL702 USB-CDC bridge on GPIO14 (TX) / GPIO15 (RX). +// Confirmed from bl_iot_sdk/customer_app/bl808/bl808_demo_linux/main.c#L74. +private enum uint M0_CONSOLE_TX_PIN = 14; +private enum uint M0_CONSOLE_RX_PIN = 15; +private enum uint M0_CONSOLE_BAUD = 2_000_000; + +extern(C) void m0_bringup() +{ + mm_domain_power_on(); + mm_clk_config(); + mcu2ext_bus_threshold(); + uart_signal_mux(); + uart0_early_init(M0_CONSOLE_TX_PIN, M0_CONSOLE_RX_PIN, M0_CONSOLE_BAUD); + uart0_hw_puts("\nBL808 M0: startup\n"); + wifi_em_carveout(); + psram_init(); + l2_sram_partition(); + tzc_config_for_d0(); + launch_d0(); +} + +private void launch_d0() +{ + d0_image_load(); + d0_mtimer_config(); + d0_halt(); + d0_set_boot_addr(); + d0_release(); +} + +private: + +enum uint PDS_CTL2 = 0x2000_E010; +enum uint MM_CLK_CTRL_CPU = 0x3000_7000; +enum uint MCU_MISC_MCU_BUS_CFG1 = 0x2000_9004; +enum uint GLB_PARM_CFG0 = 0x2000_0510; +enum uint MM_MISC_VRAM_CTRL = 0x3000_0050; +enum uint TZC_MM_BMX_TZMID = 0x2000_5300; +enum uint TZC_MM_BMX_TZMID_LOCK = 0x2000_5304; +enum uint TZC_PSRAMA_TZSRG_CTRL = 0x2000_5380; +enum uint TZC_PSRAMB_TZSRG_CTRL = 0x2000_53A0; +enum uint MM_MISC_CPU0_BOOT = 0x3000_0000; +enum uint MM_GLB_SW_SYS_RESET = 0x3000_7040; +enum uint MM_MISC_CPU_RTC = 0x3000_0018; + +enum uint D0_IMAGE_FLASH_ADDR = 0x5821_0000; // D0FW partition base (XIP-mapped) +enum uint D0_IMAGE_FLASH_SIZE = 0x0040_0000; // D0FW partition size +enum uint D0_PSRAM_LOAD_ADDR = 0x5010_0000; +enum uint D0_PSRAM_LOAD_SIZE = 0x0040_0000; // D0 CODE region in d0 linker script + +extern(C) void bl_psram_init(); + +pragma(inline, true) uint mmio_read(uint addr) +{ + return volatileLoad(cast(uint*)cast(size_t)addr); +} + +pragma(inline, true) void mmio_write(uint addr, uint val) +{ + volatileStore(cast(uint*)cast(size_t)addr, val); +} + +pragma(inline, true) void mmio_clear_bit(uint addr, uint bit) +{ + mmio_write(addr, mmio_read(addr) & ~(uint(1) << bit)); +} + +pragma(inline, true) void mmio_set_bit(uint addr, uint bit) +{ + mmio_write(addr, mmio_read(addr) | (uint(1) << bit)); +} + +pragma(inline, true) void mmio_set_field(uint addr, uint shift, uint mask, uint value) +{ + uint v = mmio_read(addr); + v = (v & ~(mask << shift)) | ((value & mask) << shift); + mmio_write(addr, v); +} + +pragma(inline, false) extern(C) void arch_delay_us(uint us) +{ + // E907 mtime runs at 1MHz so 1 tick == 1us. The low 32 bits roll over every + // ~71 minutes; we only ever wait microseconds, so unsigned wrap is harmless. + uint start, now; + asm @nogc nothrow { "rdtime %0" : "=r" (start); } + do + { + asm @nogc nothrow { "rdtime %0" : "=r" (now); } + } + while ((now - start) < us); +} + +// Carve 64KB of WRAM as WiFi MAC "Embedded Memory" (EM). Vendor's libwifi.a +// was built expecting this split when BLE is compiled in, and at least one +// community Sipeed-fork SDK confirms WiFi-AP fails silently without it -- +// beacons get queued into a buffer the RF DMA never reads. EM is LMAC's +// private DMA region; the CPU never touches it, so this does not collide +// with our linker layout. Done in m0_bringup before any other init so the +// SRAM controller settles before stack-heavy code runs. +// +// GLB_SRAM_CFG3 @ GLB_BASE + 0x60C, field GLB_EM_SEL [7:0]: +// 0x00 -> 160K WRAM + 0K EM (reset default; what crashed earlier was +// NOT this; see below) +// 0xFF -> 96K WRAM + 64K EM (vendor wifi+ble default) +// +// Previously failed when written from chip_post_init -- by that point the +// stack is live and writing the register while CPU is mid-routine appears +// to glitch SRAM. Running here from m0_bringup, with only the early start.S +// stack in DTCM aliasing, is the same place vendor calls equivalent code +// from System_Init. +void wifi_em_carveout() +{ + enum uint GLB_SRAM_CFG3 = 0x2000_060C; + mmio_set_field(GLB_SRAM_CFG3, 0, 0xFF, 0xFF); +} + +void mcu2ext_bus_threshold() +{ + // Vendor bl_sys_reduce_mcu2ext(): MCU_MISC.MCU_BUS_CFG1 + // REG_X_WTHRE_MCU2EXT = 3. + mmio_set_field(MCU_MISC_MCU_BUS_CFG1, 7, 0x3, 3); +} + +void mm_domain_power_on() +{ + // PDS_CTL2: ordered de-isolation/power-up sequence; bit 1 first, settle, then 5/17/13/9 + mmio_clear_bit(PDS_CTL2, 1); + arch_delay_us(45); + mmio_clear_bit(PDS_CTL2, 5); + mmio_clear_bit(PDS_CTL2, 17); + mmio_clear_bit(PDS_CTL2, 13); + mmio_clear_bit(PDS_CTL2, 9); +} + +void mm_clk_config() +{ + mmio_set_field(MM_CLK_CTRL_CPU, 10, 0x1, 1); // XCLK_CLK_SEL = XTAL + mmio_set_field(MM_CLK_CTRL_CPU, 13, 0x3, 2); // BCLK1X_SEL = 160MHz PLL + mmio_set_field(MM_CLK_CTRL_CPU, 11, 0x1, 1); // CPU_ROOT_CLK = PLL + mmio_set_field(MM_CLK_CTRL_CPU, 8, 0x3, 2); // CPU_CLK_SEL = 400MHz PLL + mmio_set_field(MM_CLK_CTRL_CPU, 4, 0x3, 3); // UART_CLK_SEL = XCLK + mmio_set_field(MM_CLK_CTRL_CPU, 6, 0x1, 1); // I2C_CLK_SEL = XCLK +} + +void uart_signal_mux() +{ + // UART_SWAP_SET: bit 3 = GPIO12-23 group, bit 5 = GPIO36-45 group + mmio_set_bit(GLB_PARM_CFG0, 3); + mmio_set_bit(GLB_PARM_CFG0, 5); +} + +void psram_init() +{ + bl_psram_init(); +} + +void l2_sram_partition() +{ + uint v = mmio_read(MM_MISC_VRAM_CTRL); + v |= uint(1) << 4; // L2_SRAM_REL = 1 (64KB L2, 0KB VRAM) + v &= ~(uint(0x3) << 1); // PF_SRAM_REL = 0 (192KB PFH) + v &= ~(uint(1) << 7); // APU_SRAM_REL = 0 (128KB APU) + v &= ~(uint(1) << 6); // DSP2_SRAM_REL = 0 (64KB DSP2) + mmio_write(MM_MISC_VRAM_CTRL, v); + + // commit bit must be a separate write after the partition fields settle + mmio_set_bit(MM_MISC_VRAM_CTRL, 0); +} + +void tzc_config_for_d0() +{ + mmio_set_bit(TZC_MM_BMX_TZMID, 0); + mmio_set_bit(TZC_MM_BMX_TZMID_LOCK, 0); + + uint a = mmio_read(TZC_PSRAMA_TZSRG_CTRL); + a = (a & ~uint(0x3)) | 0x1; // region 0 group = 1 (D0) + a |= uint(1) << 16; // region 0 enable + mmio_write(TZC_PSRAMA_TZSRG_CTRL, a); + + uint b = mmio_read(TZC_PSRAMB_TZSRG_CTRL); + b = (b & ~uint(0x3)) | 0x1; + b |= uint(1) << 16; + mmio_write(TZC_PSRAMB_TZSRG_CTRL, b); +} + +void d0_image_load() +{ + // T-Head MHCR (CSR 0x7C1): bit 0 = I-cache enable, bit 1 = D-cache enable. + // Disable D-cache around PSRAM writes so D0 sees fresh memory. + asm @nogc nothrow { "csrc 0x7C1, 0x2"; } + + // Detect gzip: id1=0x1F, id2=0x8B, method=deflate(8). Anything else is + // treated as a raw D0 image starting at offset 0. + const(ubyte)* flash = cast(const(ubyte)*)cast(size_t)D0_IMAGE_FLASH_ADDR; + if (flash[0] == 0x1F && flash[1] == 0x8B && flash[2] == 0x08) + gunzip_d0(flash); + else + raw_copy_d0(flash); + + asm @nogc nothrow { "csrs 0x7C1, 0x2"; } +} + +void raw_copy_d0(const(ubyte)* flash) +{ + uint* src = cast(uint*)flash; + uint* dst = cast(uint*)cast(size_t)D0_PSRAM_LOAD_ADDR; + uint words = D0_PSRAM_LOAD_SIZE / 4; + for (uint i = 0; i < words; ++i) + dst[i] = src[i]; +} + +void gunzip_d0(const(ubyte)* flash) +{ + // gzip_uncompress tolerates an oversized source slice -- it finds its own + // footer via uncompress's srcConsumed output. Source bound is the whole + // D0FW partition; anything past the actual gzip stream is junk and ignored. + const(void)[] src = flash[0 .. D0_IMAGE_FLASH_SIZE]; + void[] dst = (cast(void*)cast(size_t)D0_PSRAM_LOAD_ADDR)[0 .. D0_PSRAM_LOAD_SIZE]; + size_t out_len; + if (gzip_uncompress(src, dst, out_len).failed) + { + // No UART yet (sys_init runs after m0_bringup), nowhere to report. + // Halt -- watchdog will reset the board if enabled. + for (;;) {} + } +} + +void d0_mtimer_config() +{ + mmio_clear_bit(MM_MISC_CPU_RTC, 31); // disable while changing divider + mmio_set_field(MM_MISC_CPU_RTC, 0, 0x3FF, 39); // DIV = 39 for 10MHz from 400MHz + mmio_set_bit(MM_MISC_CPU_RTC, 31); // re-enable +} + +void d0_halt() +{ + mmio_set_bit(MM_GLB_SW_SYS_RESET, 8); +} + +void d0_set_boot_addr() +{ + mmio_write(MM_MISC_CPU0_BOOT, D0_PSRAM_LOAD_ADDR); +} + +void d0_release() +{ + mmio_clear_bit(MM_GLB_SW_SYS_RESET, 8); +} diff --git a/src/urt/driver/bl808_m0/wifi.d b/src/urt/driver/bl808_m0/wifi.d new file mode 100644 index 0000000..306bf22 --- /dev/null +++ b/src/urt/driver/bl808_m0/wifi.d @@ -0,0 +1,1225 @@ +module urt.driver.bl808_m0.wifi; + +version (BL808_M0): + +import urt.driver.bl808_m0.bl_ops; +import urt.driver.bl808_m0.wifi_lmac; +import urt.driver.bl808_m0.wifi_pm; +import urt.driver.bl808_m0.wifi_wpa; +import urt.attribute : fast_data, section; +import urt.driver.wifi; +import urt.driver.wpa.eapol; + +enum uint num_wifi = 1; +enum ubyte wifi_max_ap_clients = 5; + +nothrow @nogc: + + +// TODO(bl808-wifi) +// - AP WPA auth is single-client state; move it to per-STA state, enforce +// max_clients in the join path, and lift the current WPA max-clients=1 +// restriction. +// - Replace the hardcoded base MAC with the chip OTP/efuse MAC and derive +// STA/AP VIF MACs from it. +// - Push STA/AP connect and auth failure reasons up through the API/status +// path consistently. +// - Add GTK rekey support to the STA four-way path. +// - Handle msg-3 retransmit/replay and key reinstall rules with complete WPA +// semantics before adding more AKM/cipher suites. +// - Replace magic vendor offsets/probes with mirrored structs or static +// drift checks where possible, especially WifiConnectParmView, +// _wpa_parse_wpa_ie output layout, hwhdr offsets, and SM_CONNECT_IND tails. +// - Audit null-hwhdr RX VIF attribution in tcpip_stack_input. +// - Rework event delivery so connect/disconnect bounces cannot be coalesced +// by the generic baremetal polling layer. +// - Decide whether the blob timer shim needs real timer firing, not just +// recorded state. +// - Confirm bl_ops allocation/free semantics under AllocTracking and blob DMA +// use. +// - Revisit ISR/FPU save requirements for LDC-generated code. +// - Move AP-side WPA out of this driver once the shape settles. +// - Update vendor/wifi/PATCHES.md whenever vendor C divergences change. + + +// ==================================================================== +// WiFi driver API +// ==================================================================== + +void wifi_hw_set_wake_callback(void function() nothrow @nogc cb) +{ + urt.driver.bl808_m0.bl_ops.wifi_set_wake_callback(cb); +} + +bool wifi_hw_open(ubyte port, ref const WifiConfig cfg) +{ + import urt.driver.bl808_m0.bl_ops : bl_ops_task_create; + import urt.driver.uart : uart0_puts; + import urt.driver.bl618.irq : irq_set_handler, irq_set_enable; + import urt.driver.bl618.timer : mtime_read; + + if (port != 0) + return false; + _configured_channel = cfg.channel; + _current_channel = 0; + _sta_candidate_channel = 0; + + enum uint GLB_WIFI_PLL_CFG0 = 0x2000_0810; + enum uint PU_WIFIPLL_POSTDIV = 1u << 4; + { + uint pll0_pre = *cast(uint*)cast(size_t)GLB_WIFI_PLL_CFG0; + *cast(uint*)cast(size_t)GLB_WIFI_PLL_CFG0 = pll0_pre | PU_WIFIPLL_POSTDIV; + ulong start = mtime_read(); + while (mtime_read() - start < 100) {} + } + + bl_wifi_register_wpa_cb_internal(&_wpa_stub_table); + + install_msg_hdlrs(); + + if (bl_shim_ipc_init(&_bl_hw, &ipc_shared_env) != 0) + { + uart0_puts("wifi: ipc_init FAILED\n"); + return false; + } + ipc_emb2app_ack_clear(0xFFFFFFFF); + + if (bl_irqs_init(&_bl_hw) != 0) + { + uart0_puts("wifi: irqs_init FAILED\n"); + return false; + } + + { + auto reg = cast(uint*)cast(size_t)0x200003B0; + *reg = (*reg & ~0xFu) | 1u; + } + + ipc_emb2app_unmask_set(IPC_IRQ_E2A_ALL); + + irq_set_handler(70, &_wifi_mac_irq_thunk); + irq_set_handler(79, &_wifi_ipc_irq_thunk); + irq_set_enable(70); + irq_set_enable(79); + + { + byte[14] zero_offset = 0; + byte[4] tpc_11b = [0x14, 0x14, 0x14, 0x12]; + byte[8] tpc_11g = [0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0xe, 0xe]; + byte[8] tpc_11n = [0x12, 0x12, 0x12, 0x12, 0x12, 0x10, 0xe, 0xe]; + phy_powroffset_set(zero_offset.ptr); + bl_tpc_update_power_rate_11b(tpc_11b.ptr); + bl_tpc_update_power_rate_11g(tpc_11g.ptr); + bl_tpc_update_power_rate_11n(tpc_11n.ptr); + } + + wifi_hosal_pm_init(); + + void* fw_handle; + if (bl_ops_task_create("fw".ptr, cast(void*)&wifi_main, 1536, null, 30, fw_handle) != 0) + { + uart0_puts("wifi: spawn wifi_main FAILED\n"); + return false; + } + + { + import urt.driver.bl808_m0.bl_ops : wifi_fibre_pump, wifi_main_in_main_loop; + uint pumps; + while (!wifi_main_in_main_loop && pumps < 32) + { + wifi_fibre_pump(); + ++pumps; + } + if (!wifi_main_in_main_loop) + { + uart0_puts("wifi: wifi_main never reached event loop\n"); + return false; + } + } + + _bl_hw.mod_params = &bl_mod_params; + _bl_hw.vifs.next = &_bl_hw.vifs; + _bl_hw.vifs.prev = &_bl_hw.vifs; + + if (bl_send_reset(&_bl_hw) != 0) + { + uart0_puts("wifi: bl_send_reset FAILED\n"); + return false; + } + + { + import urt.driver.bl808_m0.bl_ops : wifi_fibre_pump; + import urt.driver.bl618.timer : mtime_read; + ulong start = mtime_read(); + while (mtime_read() - start < 5_000) + wifi_fibre_pump(); + } + + ubyte[128] version_cfm = 0; + if (bl_send_version_req(&_bl_hw, version_cfm.ptr) != 0) + { + uart0_puts("wifi: bl_send_version_req FAILED\n"); + return false; + } + + if (bl_handle_dynparams(&_bl_hw) != 0) + { + uart0_puts("wifi: bl_handle_dynparams FAILED\n"); + return false; + } + + if (bl_send_me_config_req(&_bl_hw) != 0) + { + uart0_puts("wifi: bl_send_me_config_req FAILED\n"); + return false; + } + + bl_msg_update_channel_cfg("CN".ptr); + + if (bl_send_me_chan_config_req(&_bl_hw) != 0) + { + uart0_puts("wifi: bl_send_me_chan_config_req FAILED\n"); + return false; + } + + if (bl_send_start(&_bl_hw) != 0) + { + uart0_puts("wifi: bl_send_start FAILED\n"); + return false; + } + + _bl_hw.is_up = 1; + return true; +} + +void wifi_hw_close(ubyte port) +{ + import urt.driver.bl618.irq : irq_clear_enable, irq_clear_pending, irq_set_handler; + + if (_bl_hw.vif_index_sta >= 0) + { + bl_send_remove_if(&_bl_hw, cast(ubyte)_bl_hw.vif_index_sta); + _bl_hw.vif_index_sta = -1; + } + if (_bl_hw.vif_index_ap >= 0) + { + bl_send_apm_stop_req(&_bl_hw, cast(ubyte)_bl_hw.vif_index_ap); + bl_send_remove_if(&_bl_hw, cast(ubyte)_bl_hw.vif_index_ap); + _bl_hw.vif_index_ap = -1; + } + + irq_clear_enable(70); + irq_clear_enable(79); + irq_clear_pending(70); + irq_clear_pending(79); + irq_set_handler(70, null); + irq_set_handler(79, null); + ipc_emb2app_unmask_set(0); + ipc_emb2app_ack_clear(0xFFFFFFFF); + if (_bl_hw.ipc_env !is null) + { + bl_ops_free(_bl_hw.ipc_env); + _bl_hw.ipc_env = null; + } + wifi_hosal_pm_deinit(); + ap_auth_reset(); + + _bl_hw.is_up = 0; + _event_cb = null; + _rx_cb = null; + _raw_rx_cb = null; + _wifi_evt_head = 0; + _wifi_evt_tail = 0; + _sta_ap_idx = ubyte.max; + _sta_pending_pmk[] = 0; + _sta_pending_pmk_hex[] = 0; + _sta_pending_pmk_hex_len = 0; + _sta_pending_tk_len = 0; + _sta_pending_gtk_len = 0; + _sta_pending_pair_rsc_len = 0; + _sta_pending_group_rsc_len = 0; + _sta_pending_keys = false; + _sta_pending_auth = false; + _sta_pending_auth_reason = 0; +} + +bool wifi_hw_set_mode(ubyte port, WifiMode mode) +{ + final switch (mode) + { + case WifiMode.none: + return tear_down_vif_ap() && tear_down_vif_sta(); + case WifiMode.monitor: + return wifi_set_monitor_mode(true); + case WifiMode.sta: + return ensure_vif_sta() && tear_down_vif_ap(); + case WifiMode.ap: + return ensure_vif_ap() && tear_down_vif_sta(); + case WifiMode.apsta: + if (_apsta_unsupported) + return false; + if (ensure_vif_sta() && ensure_vif_ap()) + return true; + _apsta_unsupported = true; + return false; + } +} + +bool wifi_hw_sta_configure(ubyte port, ref const WifiStaConfig cfg) +{ + _sta_last_auth_reason = 0; + _sta_status_message = null; + if (cfg.pmf_required) + { + _sta_last_auth_reason = cast(ushort)WpaHandshakeReason.pmf_required_unsupported; + _sta_status_message = wpa_handshake_reason_message(_sta_last_auth_reason); + return false; + } + if (cfg.ssid.length > _sta_cfg_ssid_buf.length) + { + _sta_status_message = "STA SSID is too long"; + return false; + } + if (cfg.password.length > _sta_cfg_pw_buf.length) + { + _sta_status_message = "STA password is too long"; + return false; + } + bool same_psk = _sta_cfg_ssid_len == cfg.ssid.length && + _sta_cfg_pw_len == cfg.password.length; + if (same_psk) + { + foreach (i; 0 .. cfg.ssid.length) + if (_sta_cfg_ssid_buf[i] != cast(ubyte)cfg.ssid[i]) + same_psk = false; + foreach (i; 0 .. cfg.password.length) + if (_sta_cfg_pw_buf[i] != cast(ubyte)cfg.password[i]) + same_psk = false; + } + _sta_cfg_ssid_buf[0 .. cfg.ssid.length] = cast(ubyte[])cfg.ssid; + _sta_cfg_ssid_len = cast(ubyte)cfg.ssid.length; + _sta_cfg_pw_buf[0 .. cfg.password.length] = cast(ubyte[])cfg.password; + _sta_cfg_pw_len = cast(ubyte)cfg.password.length; + _sta_cfg_bssid = cfg.bssid; + _sta_cfg_band = cfg.band; + _sta_cfg_pmf = cfg.pmf_required; + if (!same_psk) + { + _sta_pending_pmk_hex_len = 0; + _sta_candidate_channel = 0; + } + return true; +} + +const(char)[] wifi_hw_sta_status_message(ubyte port) +{ + if (_sta_status_message.length != 0) + return _sta_status_message; + if (_sta_last_auth_reason != 0) + return wpa_handshake_reason_message(_sta_last_auth_reason); + return null; +} + +bool wifi_hw_sta_connect(ubyte port) +{ + if (!ensure_vif_sta()) + return false; + + if (_sta_pending_pmk_hex_len == 0) + { + _sta_pending_pmk[] = 0; + _sta_pending_pmk_hex[] = 0; + } + if (_sta_cfg_pw_len >= 8 && _sta_pending_pmk_hex_len == 0) + { + import urt.crypto.pbkdf2 : wpa2_psk_to_pmk; + auto pw = cast(const(char)[])_sta_cfg_pw_buf[0 .. _sta_cfg_pw_len]; + auto ss = cast(const(char)[])_sta_cfg_ssid_buf[0 .. _sta_cfg_ssid_len]; + if (wpa2_psk_to_pmk(pw, ss, _sta_pending_pmk).succeeded) + { + static immutable string hexdig = "0123456789abcdef"; + foreach (i; 0 .. 32) + { + _sta_pending_pmk_hex[i*2 + 0] = cast(ubyte)hexdig[_sta_pending_pmk[i] >> 4]; + _sta_pending_pmk_hex[i*2 + 1] = cast(ubyte)hexdig[_sta_pending_pmk[i] & 0xF]; + } + _sta_pending_pmk_hex_len = 64; + } + } + + ubyte* bssid; + foreach (b; _sta_cfg_bssid) + { + if (b) { bssid = _sta_cfg_bssid.ptr; break; } + } + ushort freq = 0; + enum NL80211_AUTHTYPE_AUTOMATIC = 8; + + int r = bl_shim_sta_connect( + &_bl_hw, + _sta_cfg_ssid_buf.ptr, _sta_cfg_ssid_len, + bssid, + cast(char*)_sta_cfg_pw_buf.ptr, _sta_cfg_pw_len, + _sta_pending_pmk_hex.ptr, _sta_pending_pmk_hex_len, + NL80211_AUTHTYPE_AUTOMATIC, freq, + ); + if (r != 0) + { + queue_event(WifiEvent.sta_disconnected, null); + return false; + } + return true; +} + +bool wifi_hw_sta_disconnect(ubyte port) +{ + return bl_send_sm_disconnect_req(&_bl_hw) == 0; +} + +bool wifi_hw_ap_configure(ubyte port, ref const WifiApConfig cfg) +{ + if (!ensure_vif_ap()) + return false; + + if (cfg.ssid.length >= _ap_ssid_buf.length) + return false; + if (cfg.password.length >= _ap_pw_buf.length) + return false; + _ap_ssid_buf[0 .. cfg.ssid.length] = cast(ubyte[])cfg.ssid; + _ap_ssid_buf[cfg.ssid.length] = 0; + bool ap_open = cfg.auth == WifiAuth.open || cfg.password.length == 0; + if (!ap_open && cfg.max_clients > 1) + return false; + if (ap_open) + _ap_pw_buf[0] = 0; + else + { + _ap_pw_buf[0 .. cfg.password.length] = cast(ubyte[])cfg.password; + _ap_pw_buf[cfg.password.length] = 0; + } + ap_auth_reset(); + + apm_start_cfm cfm; + ubyte ap_max_clients = ap_open ? cfg.max_clients : 1; + if (ap_max_clients != 0 && !wifi_hw_ap_set_max_clients(port, ap_max_clients)) + return false; + + int r = bl_send_apm_start_req( + &_bl_hw, &cfm, + cast(char*)_ap_ssid_buf.ptr, + cast(char*)_ap_pw_buf.ptr, + cfg.channel == 0 ? 4 : cfg.channel, + cast(ubyte)_bl_hw.vif_index_ap, + cfg.hidden ? 1 : 0, + 100, + ); + if (r != 0 || cfm.status != 0) + return false; + _bl_hw.ap_bcmc_idx = cfm.bcmc_idx; + if (cfm.vif_idx < _bl_hw.vif_table.length) + _bl_hw.vif_table[cfm.vif_idx].variant.ap.bcmc_index = cfm.bcmc_idx; + + queue_event(WifiEvent.ap_started, null); + return true; +} + +bool wifi_hw_ap_set_max_clients(ubyte port, ubyte max_clients) +{ + if (port != 0 || !_bl_hw.is_up) + return false; + if (_ap_pw_buf[0] != 0 && max_clients > 1) + return false; + + ubyte max_sta = max_clients == 0 || max_clients > NX_REMOTE_STA_MAX + ? cast(ubyte)NX_REMOTE_STA_MAX + : max_clients; + int r = bl_send_apm_conf_max_sta_req(&_bl_hw, max_sta); + return r == 0; +} + +size_t wifi_hw_ap_get_clients(ubyte port, WifiStaInfo[] buf) +{ + size_t n; + foreach (i; 0 .. STA_TABLE_LEN) + { + if (n >= buf.length) break; + if (!_bl_hw.sta_table[i].is_used) continue; + buf[n].mac = _bl_hw.sta_table[i].sta_addr.array_; + buf[n].rssi = _bl_hw.sta_table[i].rssi; + ++n; + } + return n; +} + +bool wifi_hw_scan_start(ubyte port, ref const WifiScanConfig cfg) +{ + if (_scan_in_progress) + return false; + + _scan_results_count = 0; + _scan_in_progress = true; + + bl_send_scanu_para p; + if (cfg.channel != 0) + { + _scan_channel_one[0] = channel_to_freq(cfg.channel, cfg.band); + p.channels = _scan_channel_one.ptr; + p.channel_num = 1; + } + p.duration_scan = cfg.dwell_ms == 0 ? 110 : cfg.dwell_ms; + p.scan_mode = cfg.passive ? 1 : 0; + + if (bl_send_scanu_req(&_bl_hw, &p) != 0) + { + _scan_in_progress = false; + return false; + } + return true; +} + +void wifi_hw_scan_stop(ubyte port) +{ + _scan_in_progress = false; +} + +size_t wifi_hw_scan_get_results(ubyte port, WifiScanResult[] buf) +{ + size_t n = _scan_results_count; + if (n > buf.length) n = buf.length; + buf[0 .. n] = _scan_results[0 .. n]; + return n; +} + +bool wifi_hw_tx(ubyte port, WifiVif vif, const(ubyte)[] data) +{ + if (port != 0 || data.length < 14 || data.length > 1614 || _bl_hw.ipc_env is null) + return false; + + int fw_vif = fw_vif_index(vif); + if (fw_vif < 0) + return false; + + tx_slot* slot; + foreach (ref candidate; _tx_slots) + { + if (!candidate.used) + { + candidate.used = true; + slot = &candidate; + break; + } + } + if (slot is null) + return false; + + txdesc_host* txdesc = ipc_host_txdesc_get(_bl_hw.ipc_env); + if (txdesc is null) + { + slot.used = false; + return false; + } + + auto payload_len = data.length - 14; + if (payload_len > txdesc.eth_packet.sizeof) + { + slot.used = false; + return false; + } + + ubyte* dst = cast(ubyte*)txdesc.eth_packet.ptr; + foreach (i; 0 .. payload_len) + dst[i] = data[14 + i]; + + hostdesc host = hostdesc.init; + host.pbuf_addr = cast(uint)cast(size_t)&slot.pb; + host.packet_addr = 0x1111_1111; + host.packet_len = cast(ushort)payload_len; + host.status_addr = cast(uint)cast(size_t)&slot.hdr.status; + host.eth_dest_addr.array_[] = data[0 .. 6]; + host.eth_src_addr.array_[] = data[6 .. 12]; + host.ethertype = cast(ushort)(cast(ushort)data[12] | (cast(ushort)data[13] << 8)); + host.tid = 0; + host.vif_idx = cast(ubyte)(vif == WifiVif.sta ? 1 : 0); + int fw_staid = vif == WifiVif.sta + ? (_bl_hw.sta_idx >= 0 ? _bl_hw.sta_idx : cast(int)_sta_ap_idx) + : bl_utils_idx_lookup(&_bl_hw, cast(ubyte*)data.ptr); + if (fw_staid < 0 || fw_staid > ubyte.max) + { + slot.used = false; + return false; + } + host.staid = cast(ubyte)fw_staid; + host.flags = 0; + host.pbuf_chained_ptr[0] = cast(uint)cast(size_t)txdesc.eth_packet.ptr; + host.pbuf_chained_len[0] = cast(uint)payload_len; + + slot.pb = pbuf.init; + slot.pb.payload = &slot.hdr; + slot.pb.tot_len = cast(ushort)data.length; + slot.pb.len = cast(ushort)data.length; + slot.pb.ref_ = 1; + + slot.hdr = bl_txhdr.init; + slot.hdr.status = 0; + slot.hdr.p = cast(uint*)&slot.pb; + slot.hdr.host = host; + + txdesc.ready = 0; + txdesc.host = host; + + ipc_host_txdesc_push(_bl_hw.ipc_env, &slot.pb); + return true; +} + +void wifi_hw_set_rx_callback(ubyte port, WifiRxCallback cb) +{ + _rx_cb = cb; +} + +bool wifi_hw_raw_tx(ubyte port, const(ubyte)[] frame) +{ + return bl_send_scanu_raw_send(&_bl_hw, cast(ubyte*)frame.ptr, cast(int)frame.length) == 0; +} + +void wifi_hw_set_raw_rx_callback(ubyte port, WifiRawRxCallback cb) +{ + _raw_rx_cb = cb; +} + +bool wifi_hw_get_mac(ubyte port, WifiVif vif, ref ubyte[6] mac) +{ + int idx = vif == WifiVif.sta ? _bl_hw.vif_index_sta : _bl_hw.vif_index_ap; + if (idx < 0 || idx >= VIF_TABLE_LEN) + return false; + // bl_vif doesn't carry its own MAC; the add_if call passed one in. + // We saved it in _vif_mac_*. Return that. + mac = vif == WifiVif.sta ? _vif_mac_sta : _vif_mac_ap; + return true; +} + +ubyte wifi_hw_get_channel(ubyte port) +{ + return _current_channel; +} + +bool wifi_hw_set_channel(ubyte port, ubyte primary) +{ + // No live channel switch on BL808 - the LMAC owns its channel state + // via the active VIF (STA's connected BSS or APM's configured channel). + // Leaving unimplemented; channel changes go through the iface restart + // path on this platform. + return false; +} + +byte wifi_hw_get_rssi(ubyte port) +{ + // STA RSSI lands in sta_table[ap_idx].rssi via SM_CONNECT_IND. We + // saved ap_idx at connect time. + if (_sta_ap_idx >= STA_TABLE_LEN) return 0; + return _bl_hw.sta_table[_sta_ap_idx].rssi; +} + +bool wifi_hw_set_tx_power(ubyte port, byte power_dbm) +{ + // No direct vendor call; goes through mod_params at start time. + return false; +} + +void wifi_hw_set_event_callback(ubyte port, WifiEventCallback cb) +{ + _event_cb = cb; +} + +void wifi_hw_poll(ubyte port) +{ + if (_bl_hw.is_up && _bl_hw.ipc_env !is null) + bl_irq_bottomhalf(&_bl_hw); + wifi_fibre_pump(); + dispatch_queued_events(); + ap_auth_tick(); +} + + + +package: + +// ==================================================================== +// Module state +// ==================================================================== + +__gshared WifiRxCallback _rx_cb; +__gshared WifiRawRxCallback _raw_rx_cb; +__gshared WifiEventCallback _event_cb; + +struct WifiQueuedEvent +{ + WifiEvent event; + ubyte[6] mac; + bool has_mac; +} +enum size_t wifi_evt_cap = 16; +__gshared WifiQueuedEvent[wifi_evt_cap] _wifi_evt_queue; +__gshared uint _wifi_evt_head; +__gshared uint _wifi_evt_tail; + +@section(".sram_data.wifi") __gshared bl_hw _bl_hw; + +__gshared ubyte[6] _default_mac = [0xC0, 0x49, 0xEF, 0x00, 0x00, 0x01]; +__gshared ubyte[6] _vif_mac_sta; +__gshared ubyte[6] _vif_mac_ap; +__gshared ubyte _wifi_dummy_netif; + +__gshared ubyte[32] _sta_cfg_ssid_buf; +__gshared ubyte _sta_cfg_ssid_len; +__gshared ubyte[64] _sta_cfg_pw_buf; +__gshared ubyte _sta_cfg_pw_len; +__gshared ubyte[6] _sta_cfg_bssid; +__gshared WifiBand _sta_cfg_band; +__gshared bool _sta_cfg_pmf; +__gshared ubyte _sta_ap_idx = ubyte.max; +__gshared ubyte _sta_candidate_channel; +__gshared ubyte _configured_channel; + +__gshared ubyte[32] _sta_pending_pmk; +// The vendor STA connect struct expects the PMK as 64 ASCII hex bytes. +__gshared ubyte[64] _sta_pending_pmk_hex; +__gshared ubyte _sta_pending_pmk_hex_len; +__gshared ubyte[16] _sta_pending_tk; +__gshared ubyte[32] _sta_pending_gtk; +__gshared ubyte[6] _sta_pending_pair_rsc; +__gshared ubyte[6] _sta_pending_group_rsc; +__gshared ubyte _sta_pending_tk_len; +__gshared ubyte _sta_pending_gtk_len; +__gshared ubyte _sta_pending_pair_rsc_len; +__gshared ubyte _sta_pending_group_rsc_len; +__gshared ubyte _sta_pending_gtk_idx; +__gshared bool _sta_pending_keys; +__gshared bool _sta_pending_auth; +__gshared ushort _sta_pending_auth_reason; +__gshared ushort _sta_last_auth_reason; +__gshared const(char)[] _sta_status_message; + +__gshared ubyte[33] _ap_ssid_buf; +__gshared ubyte[65] _ap_pw_buf; + +__gshared bool _scan_in_progress; +__gshared WifiScanResult[16] _scan_results; +__gshared size_t _scan_results_count; +__gshared ushort[1] _scan_channel_one; + +__gshared ubyte _current_channel; + + +package: + +// ==================================================================== +// Blob callback surface +// ==================================================================== + +extern(C) int bl_utils_idx_lookup(bl_hw* hw, ubyte* mac) +{ + foreach (i; 0 .. STA_TABLE_LEN) + { + if (!hw.sta_table[i].is_used) + continue; + if (hw.sta_table[i].sta_addr.array_[] == mac[0..6]) + return cast(int)i; + } + return hw.ap_bcmc_idx; +} + +extern(C) void bl_utils_dump() {} + +extern(C) void bl_main_event_handle() +{ + bl_irq_bottomhalf(&_bl_hw); +} + +extern(C) int bl_supplicant_init(void* arg) { return 0; } + +extern(C) int bl_sleep_check(void* arg) +{ + __gshared uint call_count; + if (++call_count == 1) + { + import urt.driver.bl808_m0.bl_ops : wifi_main_in_main_loop; + wifi_main_in_main_loop = true; + } + return 0; +} + +extern(C) ubyte bl_radarind(void* pthis, void* hostid) { return 1; } + +extern(C) ubyte bl_msgackind(void* pthis, void* hostid) +{ + auto hw = cast(bl_hw*)pthis; + auto cmd = cast(bl_cmd*)hostid; + if (hw is null || cmd is null) + return 0; + hw.cmd_mgr.llind(&hw.cmd_mgr, cmd); + return 0; +} + +extern(C) ubyte bl_dbgind(void* pthis, void* hostid) { return 1; } +extern(C) int bl_txdatacfm(void* pthis, void* host_id) +{ + release_tx_slot(host_id); + return 1; +} +extern(C) void bl_prim_tbtt_ind(void* pthis) {} +extern(C) void bl_sec_tbtt_ind(void* pthis) {} + + +// ==================================================================== +// C ABI callbacks: IPC, IRQ, TX confirmation, and RX +// ==================================================================== + +extern(C) void bl_rx_e2a_handler(void* arg) +{ + ipc_e2a_msg* msg = cast(ipc_e2a_msg*)arg; + uint task = MSG_T(msg.id); + uint idx = MSG_I(msg.id); + + msg_cb_fct cb; + if (task < msg_hdlrs.length && idx < msg_hdlrs[task].length) + cb = msg_hdlrs[task][idx]; + + _bl_hw.cmd_mgr.msgind(&_bl_hw.cmd_mgr, msg, cb); +} + +extern(C) void mac_irq(); +extern(C) void bl_irq_handler(); + +extern(C) void phy_powroffset_set(byte* power_offset); +extern(C) void bl_tpc_update_power_rate_11b(byte* power_rate_table); +extern(C) void bl_tpc_update_power_rate_11g(byte* power_rate_table); +extern(C) void bl_tpc_update_power_rate_11n(byte* power_rate_table); +void _wifi_mac_irq_thunk(uint /+irq+/) @nogc nothrow +{ + mac_irq(); + wifi_signal_ready(); +} +void _wifi_ipc_irq_thunk(uint /+irq+/) @nogc nothrow +{ + bl_irq_handler(); + wifi_signal_ready(); +} + +extern(C) void bl_tx_resend() +{ +} + +private void release_tx_slot(void* host_id) +{ + if (host_id is null) + return; + + foreach (ref slot; _tx_slots) + { + if (cast(void*)&slot.pb == host_id) + { + bool sta_eapol = slot.hdr.host.ethertype == 0x8e88; + slot.used = false; + if (sta_eapol) + sta_flush_pending_auth(); + return; + } + } +} + +struct wifi_pkt +{ + uint[4] pkt; + void*[4] pbuf; + ushort[4] len; +} + +extern(C) int tcpip_stack_input(void* swdesc, ubyte status, void* hwhdr, uint msdu_offset, void* pkt, ubyte extra_status) +{ + import urt.driver.wifi : Wifi, WifiVif; + + auto wp = cast(wifi_pkt*)pkt; + + const(ubyte)* eth = null; + uint eth_len = 0; + ushort ethertype = 0; + uint rx_flags = hwhdr is null ? 0xFFFF_FFFF : *cast(uint*)cast(size_t)(cast(ubyte*)hwhdr + 64); + uint rx_payl_offset = hwhdr is null ? 0 : *cast(uint*)cast(size_t)(cast(ubyte*)hwhdr + 72); + ubyte rx_vif_idx = cast(ubyte)((rx_flags >> 8) & 0xff); + ubyte rx_sta_idx = cast(ubyte)((rx_flags >> 16) & 0xff); + WifiVif rx_vif = rx_vif_idx == 0xff && _bl_hw.vif_index_ap < 0 && _bl_hw.vif_index_sta >= 0 + ? WifiVif.sta + : wifi_vif_from_fw_index(rx_vif_idx); + + if (wp && wp.pkt[0] != 0 && wp.len[0] >= msdu_offset + 14) + { + eth = cast(const(ubyte)*)(cast(size_t)wp.pkt[0] + msdu_offset); + eth_len = cast(uint)wp.len[0] - msdu_offset; + ethertype = cast(ushort)((cast(ushort)eth[12] << 8) | eth[13]); + if (ethertype != eth_p_eapol && + rx_payl_offset != msdu_offset && + wp.len[0] >= rx_payl_offset + 14) + { + auto alt = cast(const(ubyte)*)(cast(size_t)wp.pkt[0] + rx_payl_offset); + ushort alt_ethertype = cast(ushort)((cast(ushort)alt[12] << 8) | alt[13]); + if (alt_ethertype == eth_p_eapol) + { + eth = alt; + eth_len = cast(uint)wp.len[0] - rx_payl_offset; + ethertype = alt_ethertype; + msdu_offset = rx_payl_offset; + } + } + + if (ethertype == eth_p_eapol && sta_wpa_owns_eapol_key(rx_vif, eth, eth_len)) + { + _wpa_sta_rx_eapol_real(cast(ubyte*)(eth + 6), cast(ubyte*)(eth + 14), eth_len - 14); + } + else if (_rx_cb !is null && eth_len <= 1518) + { + _rx_cb(Wifi(0), rx_vif, eth[0 .. eth_len]); + } + } + + return -1; +} + +struct crc32_stream_ctx { uint state; } +extern(C) void utils_crc32_stream_init(crc32_stream_ctx* ctx) +{ + if (ctx) ctx.state = 0; +} +extern(C) void utils_crc32_stream_feed_block(crc32_stream_ctx* ctx, const(ubyte)* data, uint len) {} +extern(C) uint utils_crc32_stream_results(crc32_stream_ctx* ctx) { return 0; } + +// ==================================================================== +@section(".sram_data.wifi") __gshared msg_cb_fct[MM_MAX_IDX] mm_hdlrs; +@fast_data __gshared msg_cb_fct[SCANU_MAX_IDX] scanu_hdlrs; +@fast_data __gshared msg_cb_fct[ME_MAX_IDX] me_hdlrs; +@fast_data __gshared msg_cb_fct[SM_MAX_IDX] sm_hdlrs; +@fast_data __gshared msg_cb_fct[APM_MAX_IDX] apm_hdlrs; +@section(".sram_data.wifi") __gshared msg_cb_fct[CFG_MAX_IDX] cfg_hdlrs; + + +// ==================================================================== +// LMAC message dispatch +// ==================================================================== + +@section(".sram_data.wifi") __gshared msg_cb_fct[][9] msg_hdlrs; + +private void install_msg_hdlrs() +{ + sm_hdlrs[MSG_I(SM_CONNECT_IND)] = &on_sm_connect_ind; + sm_hdlrs[MSG_I(SM_DISCONNECT_IND)] = &on_sm_disconnect_ind; + scanu_hdlrs[MSG_I(SCANU_START_CFM)] = &on_scanu_start_cfm; + scanu_hdlrs[MSG_I(SCANU_RESULT_IND)] = &on_scanu_result_ind; + apm_hdlrs[MSG_I(APM_STA_ADD_IND)] = &on_apm_sta_add_ind; + apm_hdlrs[MSG_I(APM_STA_DEL_IND)] = &on_apm_sta_del_ind; + apm_hdlrs[MSG_I(APM_STA_CONNECT_TIMEOUT_IND)] = &on_apm_sta_connect_timeout_ind; + + msg_hdlrs[TASK_MM] = mm_hdlrs[]; + msg_hdlrs[TASK_SCANU] = scanu_hdlrs[]; + msg_hdlrs[TASK_ME] = me_hdlrs[]; + msg_hdlrs[TASK_SM] = sm_hdlrs[]; + msg_hdlrs[TASK_APM] = apm_hdlrs[]; + msg_hdlrs[TASK_CFG] = cfg_hdlrs[]; +} + + +package void queue_event(WifiEvent event, const(void)* data) +{ + if (_wifi_evt_head - _wifi_evt_tail >= wifi_evt_cap) + _wifi_evt_tail++; + auto slot = &_wifi_evt_queue[_wifi_evt_head & (wifi_evt_cap - 1)]; + slot.event = event; + slot.has_mac = data !is null && + (event == WifiEvent.ap_sta_connected || event == WifiEvent.ap_sta_disconnected); + if (slot.has_mac) + slot.mac[] = (cast(const(ubyte)*)data)[0 .. 6]; + _wifi_evt_head++; +} + +private void dispatch_queued_events() +{ + if (_event_cb is null) + return; + + Wifi w = Wifi(0); + while (_wifi_evt_head != _wifi_evt_tail) + { + auto slot = &_wifi_evt_queue[_wifi_evt_tail & (wifi_evt_cap - 1)]; + _wifi_evt_tail++; + _event_cb(w, slot.event, slot.has_mac ? slot.mac.ptr : null); + } +} + +private int fw_vif_index(WifiVif vif) +{ + return vif == WifiVif.sta ? _bl_hw.vif_index_sta : _bl_hw.vif_index_ap; +} + +private WifiVif wifi_vif_from_fw_index(ubyte fw_vif_idx) +{ + if (fw_vif_idx == cast(ubyte)_bl_hw.vif_index_sta) + return WifiVif.sta; + return WifiVif.ap; +} + +private void sta_table_bind_ap(bl_hw* hw, const(sm_connect_ind_body)* body_) +{ + _sta_ap_idx = body_.ap_idx; + hw.sta_idx = body_.ap_idx; + if (body_.ap_idx < hw.sta_table.length) + { + auto sta = &hw.sta_table[body_.ap_idx]; + sta.sta_addr.array_ = body_.bssid; + sta.is_used = 1; + sta.sta_idx = body_.ap_idx; + sta.vif_idx = body_.vif_idx; + sta.vlan_idx = body_.vif_idx; + sta.qos = cast(ubyte)body_.qos; + } + if (body_.vif_idx < hw.vif_table.length && body_.ap_idx < hw.sta_table.length) + hw.vif_table[body_.vif_idx].variant.sta.ap = &hw.sta_table[body_.ap_idx]; +} + +private void sta_table_unbind_ap(bl_hw* hw, ubyte vif_idx) +{ + if (_sta_ap_idx < hw.sta_table.length) + hw.sta_table[_sta_ap_idx].is_used = 0; + if (vif_idx < hw.vif_table.length) + hw.vif_table[vif_idx].variant.sta.ap = null; + _sta_ap_idx = ubyte.max; + hw.sta_idx = -1; +} + +extern (C) int on_sm_connect_ind(bl_hw* hw, bl_cmd* cmd, ipc_e2a_msg* msg) +{ + auto body_ = cast(sm_connect_ind_body*)&msg.param[0]; + if (body_.status_code == 0) + { + if (body_.ap_idx >= hw.sta_table.length) + { + return 0; + } + + ushort freq = *cast(ushort*)(cast(ubyte*)&msg.param[0] + sm_connect_ind_body.sizeof + 800 + 4); + _current_channel = freq_to_channel(freq); + if (_current_channel == 0 && body_.ch_idx != 0xff) + _current_channel = cast(ubyte)(body_.ch_idx + 1); + sta_table_bind_ap(hw, body_); + queue_event(WifiEvent.sta_connected, body_); + } + else + { + sta_table_unbind_ap(hw, body_.vif_idx); + queue_event(WifiEvent.sta_disconnected, body_); + } + return 0; +} + +extern (C) int on_sm_disconnect_ind(bl_hw* hw, bl_cmd* cmd, ipc_e2a_msg* msg) +{ + auto body_ = cast(sm_disconnect_ind_body*)&msg.param[0]; + sta_table_unbind_ap(hw, body_.vif_idx); + queue_event(WifiEvent.sta_disconnected, body_); + return 0; +} + +extern (C) int on_scanu_result_ind(bl_hw* hw, bl_cmd* cmd, ipc_e2a_msg* msg) +{ + auto body_ = cast(scanu_result_ind_body*)&msg.param[0]; + + // Payload follows the body and contains the raw 802.11 frame starting + // at the MAC header. Beacon and probe-response have the same fixed + // layout: 24-byte MAC hdr + 8 ts + 2 bcn_int + 2 cap + IE list. + enum size_t HDR_FIXED = 24 + 12; + ubyte* p = cast(ubyte*)body_ + scanu_result_ind_body.sizeof; + int frame_len = body_.length; + + const(ubyte)[] ssid; + if (frame_len > HDR_FIXED + 2) + { + ubyte* ies = p + HDR_FIXED; + int ie_room = frame_len - cast(int)HDR_FIXED; + // SSID IE has id=0 and is conventionally first. + if (ie_room >= 2 && ies[0] == 0) + { + ubyte ssid_len = ies[1]; + if (ssid_len + 2 <= ie_room) + ssid = ies[2 .. 2 + ssid_len]; + } + } + + if (_scan_results_count >= _scan_results.length) + return 0; // buffer full -- silently drop + + auto r = &_scan_results[_scan_results_count++]; + r.bssid = body_.sa; + r.rssi = body_.rssi; + r.channel = freq_to_channel(body_.center_freq); + r.band = body_.band == 0 ? WifiBand.band_2g4 : WifiBand.band_5g; + r.bandwidth = WifiBandwidth.bw_20mhz; + r.auth = WifiAuth.open; + r.ssid_len = ssid.length > r.ssid_buf.length ? cast(ubyte)r.ssid_buf.length : cast(ubyte)ssid.length; + if (r.ssid_len) + r.ssid_buf[0 .. r.ssid_len] = cast(char[])ssid[0 .. r.ssid_len]; + if (ssid.length != 0 && + bytes_equal(ssid, _sta_cfg_ssid_buf[0 .. _sta_cfg_ssid_len]) && + r.channel != 0) + { + _sta_candidate_channel = r.channel; + } + + return 0; +} + +extern (C) int on_scanu_start_cfm(bl_hw* hw, bl_cmd* cmd, ipc_e2a_msg* msg) +{ + _scan_in_progress = false; + queue_event(WifiEvent.scan_done, null); + return 0; +} + +extern (C) int on_apm_sta_add_ind(bl_hw* hw, bl_cmd* cmd, ipc_e2a_msg* msg) +{ + auto body_ = cast(apm_sta_add_ind_body*)&msg.param[0]; + if (body_.sta_idx < hw.sta_table.length) + { + auto sta = &hw.sta_table[body_.sta_idx]; + sta.sta_addr.array_ = body_.sta_addr; + sta.is_used = 1; + sta.sta_idx = body_.sta_idx; + sta.vif_idx = body_.vif_idx; + sta.vlan_idx = body_.vif_idx; + sta.qos = cast(ubyte)((body_.flags & 1) != 0); + sta.rssi = body_.rssi; + sta.data_rate = body_.data_rate; + sta.tsflo = body_.tsflo; + sta.tsfhi = body_.tsfhi; + } + + if (!ap_auth_has_pmk()) + bl_wifi_auth_done_internal(body_.sta_idx, 0); + queue_event(WifiEvent.ap_sta_connected, body_.sta_addr.ptr); + return 0; +} + +extern (C) int on_apm_sta_del_ind(bl_hw* hw, bl_cmd* cmd, ipc_e2a_msg* msg) +{ + auto body_ = cast(apm_sta_del_ind_body*)&msg.param[0]; + ubyte[6] sta_mac = 0; + bool have_sta_mac = false; + if (body_.sta_idx < _bl_hw.sta_table.length) + { + sta_mac = _bl_hw.sta_table[body_.sta_idx].sta_addr.array_; + have_sta_mac = _bl_hw.sta_table[body_.sta_idx].is_used != 0; + _bl_hw.sta_table[body_.sta_idx].is_used = 0; + } + // DEL_IND body has no MAC, so copy it out of sta_table before clearing. + queue_event(WifiEvent.ap_sta_disconnected, have_sta_mac ? sta_mac.ptr : null); + return 0; +} + +extern (C) int on_apm_sta_connect_timeout_ind(bl_hw* hw, bl_cmd* cmd, ipc_e2a_msg* msg) +{ + return 0; +} + +private ubyte freq_to_channel(ushort mhz) pure +{ + if (mhz == 2484) + return 14; + if (mhz >= 2412 && mhz <= 2472) + return cast(ubyte)((mhz - 2412) / 5 + 1); + if (mhz >= 5180 && mhz <= 5825) + return cast(ubyte)((mhz - 5180) / 5 + 36); + return 0; +} + +package bool bytes_equal(const(ubyte)[] a, const(ubyte)[] b) pure nothrow @nogc +{ + if (a.length != b.length) + return false; + foreach (i; 0 .. a.length) + if (a[i] != b[i]) + return false; + return true; +} + +// ==================================================================== +// VIF lifecycle helpers +// ==================================================================== + +// Linux nl80211_iftype values used by bl_send_add_if. +private enum NL80211_IFTYPE_STATION = 2; +private enum NL80211_IFTYPE_AP = 3; +private enum NL80211_IFTYPE_MONITOR = 6; +private __gshared bool _apsta_unsupported; + +private bool ensure_vif_sta() +{ + if (_bl_hw.vif_index_sta >= 0) + return true; + mm_add_if_cfm cfm; + _vif_mac_sta = _default_mac; + int r = bl_send_add_if(&_bl_hw, _vif_mac_sta.ptr, NL80211_IFTYPE_STATION, false, &cfm); + if (r != 0 || cfm.status != 0) + return false; + _bl_hw.vif_index_sta = cfm.inst_nbr; + _bl_hw.vif_table[cfm.inst_nbr].dev = &_wifi_dummy_netif; + _bl_hw.vif_table[cfm.inst_nbr].up = true; + return true; +} + +private bool tear_down_vif_sta() +{ + if (_bl_hw.vif_index_sta < 0) + return true; + bl_send_remove_if(&_bl_hw, cast(ubyte)_bl_hw.vif_index_sta); + _bl_hw.vif_index_sta = -1; + return true; +} + +private bool ensure_vif_ap() +{ + if (_bl_hw.vif_index_ap >= 0) + return true; + mm_add_if_cfm cfm; + _vif_mac_ap = _default_mac; + _vif_mac_ap[5] ^= 0x80; // distinguish AP MAC from STA MAC + int r = bl_send_add_if(&_bl_hw, _vif_mac_ap.ptr, NL80211_IFTYPE_AP, false, &cfm); + if (r != 0 || cfm.status != 0) + return false; + _bl_hw.vif_index_ap = cfm.inst_nbr; + _bl_hw.vif_table[cfm.inst_nbr].dev = &_wifi_dummy_netif; + _bl_hw.vif_table[cfm.inst_nbr].up = true; + return true; +} + +private bool tear_down_vif_ap() +{ + if (_bl_hw.vif_index_ap < 0) + return true; + bl_send_apm_stop_req(&_bl_hw, cast(ubyte)_bl_hw.vif_index_ap); + bl_send_remove_if(&_bl_hw, cast(ubyte)_bl_hw.vif_index_ap); + _bl_hw.vif_index_ap = -1; + return true; +} + +private bool wifi_set_monitor_mode(bool enable) +{ + mm_monitor_cfm cfm; + int r = enable ? bl_send_monitor_enable(&_bl_hw, &cfm) + : bl_send_monitor_disable(&_bl_hw, &cfm); + return r == 0 && cfm.status == 0; +} + +private ushort channel_to_freq(ubyte ch, WifiBand band) pure +{ + if (band == WifiBand.band_5g || ch >= 36) + return cast(ushort)(5180 + (ch - 36) * 5); + if (ch == 14) + return 2484; + return cast(ushort)(2412 + (ch - 1) * 5); +} diff --git a/src/urt/driver/bl808_m0/wifi_lmac.d b/src/urt/driver/bl808_m0/wifi_lmac.d new file mode 100644 index 0000000..6e6ee8d --- /dev/null +++ b/src/urt/driver/bl808_m0/wifi_lmac.d @@ -0,0 +1,547 @@ +module urt.driver.bl808_m0.wifi_lmac; + +version (BL808_M0): + +import urt.attribute : section; + +nothrow @nogc: +extern(C): + + +// IPC shared memory. +// +// The LMAC owns ipc_shared_env -- a 9668-byte COMMON symbol inside +// libwifi.a, linker-placed in our BSS. We just take its address. +// +// ipc_host_env_tag is fully opaque -- C-side (bl_shim_ipc_init) builds +// and registers it; D only holds the pointer in bl_hw.ipc_env. +// ==================================================================== + +struct ipc_host_env_tag; // opaque + +// 9668 bytes; vendor places this in ram_wifi with the rest of .wifibss. +// lld does not reliably catch the libwifi COMMON selector for this symbol, so +// define a strong symbol in .wifi_ram; start.S clears the NOLOAD range. +struct ipc_shared_env_tag +{ + ubyte[9668] _opaque; +} +static assert(ipc_shared_env_tag.sizeof == 9668); + +@section(".wifi_ram") align(4) __gshared ipc_shared_env_tag ipc_shared_env; + +// REG_IPC_APP_RD(env, INDEX) addresses REG_WIFI_REG_BASE + IPC_REG_BASE_ADDR. +// The 0x12000000 constants in reg_ipc_app.h are not mapped on BL808 M0. +enum uint IPC_BASE = 0x2480_0000; +enum uint IPC_APP2EMB_TRIGGER_REG = IPC_BASE + 0x00; // app -> emb wake +enum uint IPC_EMB2APP_RAWSTATUS_REG = IPC_BASE + 0x04; // emb -> app raw bits +enum uint IPC_EMB2APP_ACK_REG = IPC_BASE + 0x08; // write-1-to-clear +enum uint IPC_EMB2APP_UNMASK_REG = IPC_BASE + 0x0C; // 1 = enable for that event class + +void ipc_emb2app_ack_clear(uint mask) +{ + *(cast(uint*)cast(size_t)IPC_EMB2APP_ACK_REG) = mask; +} + +// IPC E2A unmask: enabling a bit lets the LMAC raise the IPC IRQ for that +// event class. With this at 0, even a CLIC-enabled WIFI_IPC_PUBLIC_IRQn +// line never asserts. +void ipc_emb2app_unmask_set(uint mask) +{ + *(cast(uint*)cast(size_t)IPC_EMB2APP_UNMASK_REG) = mask; +} + +// Bitmask of all E2A event classes (mirrors IPC_IRQ_E2A_ALL in ipc_shared.h): +// TXCFM = ((1<>10), MSG_I(m) ((m)&((1<<10)-1)) +extern(D) uint MSG_T(uint id) pure { return id >> 10; } +extern(D) uint MSG_I(uint id) pure { return id & 0x3FF; } + +// vendor encoded task_id = first_msg(task) >> 10 +enum TASK_MM = 0; +enum TASK_SCAN = 1; +enum TASK_SCANU = 2; +enum TASK_ME = 3; +enum TASK_SM = 4; +enum TASK_APM = 5; +enum TASK_BAM = 6; +enum TASK_RXU = 7; +enum TASK_CFG = 8; + +// Per-task max message index (from MM_MAX, SM_MAX, etc.). We size the +// dispatch arrays here; if vendor adds new messages within the limit +// we already cover them. +enum MM_MAX_IDX = 80; +enum SCANU_MAX_IDX = 32; +enum ME_MAX_IDX = 32; +enum SM_MAX_IDX = 32; +enum APM_MAX_IDX = 32; +enum CFG_MAX_IDX = 16; + +// Message ids we explicitly dispatch (computed via vendor's KE_FIRST_MSG). +extern(D) uint ke_msg_id(uint task, uint idx) pure { return (task << 10) | idx; } +// bl60x_fw_api.h enum sm_msg_tag: +// 0=SM_CONNECT_REQ, 1=SM_CONNECT_CFM, 2=SM_CONNECT_IND, +// 3=SM_DISCONNECT_REQ, 4=SM_DISCONNECT_CFM, 5=SM_DISCONNECT_IND. +// STA logs showed unsolicited 0x1002 with cb=0x0; using the AP-style slots +// here dropped association completion on the floor. +enum SM_CONNECT_IND = ke_msg_id(TASK_SM, 2); // 0x1002 +enum SM_DISCONNECT_IND = ke_msg_id(TASK_SM, 5); // 0x1005 +enum SCANU_START_CFM = ke_msg_id(TASK_SCANU, 1); // 0x0801 +enum SCANU_RESULT_IND = ke_msg_id(TASK_SCANU, 4); // 0x0804 +// Per vendor bl60x_fw_api.h enum apm_msg_tag (starts at KE_FIRST_MSG(TASK_APM)): +// 0=APM_START_REQ, 1=APM_START_CFM, 2=APM_STOP_REQ, 3=APM_STOP_CFM, +// 4=APM_STA_ADD_IND, 5=APM_STA_DEL_IND, 6=APM_STA_CONNECT_TIMEOUT_IND, +// 7=APM_STA_DEL_REQ, 8=APM_STA_DEL_CFM, 9=APM_CONF_MAX_STA_REQ +// We previously had 8/9 here -- wrong slots, IND messages from LMAC fell on +// our null handlers. STA admissions were happening but the host never saw them. +enum APM_STA_ADD_IND = ke_msg_id(TASK_APM, 4); // 0x1404 +enum APM_STA_DEL_IND = ke_msg_id(TASK_APM, 5); // 0x1405 +enum APM_STA_CONNECT_TIMEOUT_IND = ke_msg_id(TASK_APM, 6); // 0x1406 + +// libwifi.a was compiled with -fshort-enums: ke_msg_id_t is uint16, +// ke_task_id_t is uint8. Total header = 8 bytes (NOT 16). Our vendor C +// compile now also passes -fshort-enums so the shared-mem layout matches. +// History: with int-enums (16-byte header), the blob read dest at byte 2 +// (= our id's third byte = 0) for every host msg, so ME_CONFIG_REQ +// (dest=ME=3) got routed to MM task (dest=0) and dropped. +struct ipc_e2a_msg +{ + ushort id; // 0-1 + ubyte dummy_dest_id; // 2 + ubyte dummy_src_id; // 3 + uint param_len; // 4-7 (naturally aligned) + uint[1] param; // 8+ + // uint pattern at the end of vendor struct -- we don't touch it +} + +alias msg_cb_fct = extern (C) int function(bl_hw*, bl_cmd*, ipc_e2a_msg*) nothrow @nogc; + +struct sm_connect_ind_body +{ + ushort status_code; + ushort reason_code; + ubyte[6] bssid; + bool roamed; + ubyte vif_idx; + ubyte ap_idx; + ubyte ch_idx; + bool qos; + ubyte acm; + ushort assoc_req_ie_len; + ushort assoc_rsp_ie_len; +} +static assert(sm_connect_ind_body.sizeof == 20); + +struct sm_disconnect_ind_body +{ + ushort status_code; + ushort reason_code; + ubyte vif_idx; +} + +struct scanu_result_ind_body +{ + ushort length; + ushort framectrl; + ushort center_freq; + ubyte band; + ubyte sta_idx; + ubyte inst_nbr; + ubyte[6] sa; + uint tsflo; + uint tsfhi; + byte rssi; + byte ppm_abs; + byte ppm_rel; + ubyte flags; + ubyte data_rate; +} + +struct apm_sta_add_ind_body +{ + uint flags; + ubyte[6] sta_addr; + ubyte vif_idx; + ubyte sta_idx; + byte rssi; + ubyte[3] _pad0; + uint tsflo; + uint tsfhi; + ubyte data_rate; +} + +struct apm_sta_del_ind_body +{ + ushort status_code; + ushort reason_code; + ubyte sta_idx; +} + +// Vendor C entry points we call (extern(C) bindings). +// ==================================================================== + +int bl_send_reset(bl_hw* bl_hw); +int bl_send_start(bl_hw* bl_hw); +int bl_send_version_req(bl_hw* bl_hw, void* cfm); +int bl_handle_dynparams(bl_hw* bl_hw); +int bl_send_me_config_req(bl_hw* bl_hw); +int bl_send_me_chan_config_req(bl_hw* bl_hw); + +// Sets static module-globals country_default + channels_default in bl_msg_tx.c. +// Must be called before any APM_START_REQ; otherwise the beacon's country IE is +// empty (length 0) and the LMAC silently refuses to transmit beacons. +void bl_msg_update_channel_cfg(const(char)* code); + +// Global bl_mod_params from vendor's bl_mod_params.c. Vendor's +// cfg80211_init wires bl_hw->mod_params = &bl_mod_params before any +// command that reads mod_params fields (handle_dynparams, me_config_req). +// Opaque to D; we just need its address. +extern __gshared int bl_mod_params; +int bl_send_add_if(bl_hw* bl_hw, const(ubyte)* mac, int iftype, bool p2p, mm_add_if_cfm* cfm); +int bl_send_remove_if(bl_hw* bl_hw, ubyte inst_nbr); +int bl_send_monitor_enable(bl_hw* bl_hw, mm_monitor_cfm* cfm); +int bl_send_monitor_disable(bl_hw* bl_hw, mm_monitor_cfm* cfm); +int bl_send_monitor_channel_set(bl_hw* bl_hw, mm_monitor_channel_cfm* cfm, int channel, int use_40mhz); +int bl_send_sm_disconnect_req(bl_hw* bl_hw); +int bl_send_channel_set_req(bl_hw* bl_hw, int channel); +int bl_send_scanu_req(bl_hw* bl_hw, bl_send_scanu_para* para); +int bl_send_scanu_raw_send(bl_hw* bl_hw, ubyte* pkt, int len); +int bl_send_apm_start_req(bl_hw* bl_hw, apm_start_cfm* cfm, char* ssid, char* password, + int channel, ubyte vif_index, ubyte hidden_ssid, ushort bcn_int); +int bl_send_apm_stop_req(bl_hw* bl_hw, ubyte vif_idx); +int bl_send_apm_conf_max_sta_req(bl_hw* bl_hw, ubyte max_sta_supported); + +// bl_shim.c -- wraps awkward vendor types with flat-arg helpers. +int bl_shim_sta_connect(bl_hw* bl_hw, const(ubyte)* ssid, uint ssid_len, + const(ubyte)* bssid_or_null, + const(char)* psk, ubyte psk_len, + const(ubyte)* pmk, ubyte pmk_len, + int auth_type, ushort freq); + +int bl_irqs_init(bl_hw* bl_hw); +void bl_irq_bottomhalf(bl_hw* bl_hw); + +// bl_shim.c -- ports vendor bl_utils.c's bl_ipc_init. Allocates the +// host env via the OS adapter (-> our urt heap), wires the cb table to +// our extern(C) D stubs, calls ipc_host_init + bl_cmd_mgr_init. +int bl_shim_ipc_init(bl_hw* bl_hw, ipc_shared_env_tag* shared_mem); + +// libwifi.a entry point. Long-lived task; we spawn it on a fibre and pump +// it from wifi_hw_poll. Param is unused by the blob (vendor SDK passes NULL). +void wifi_main(void* param); + +struct phy_channel_info +{ + uint info1; + uint info2; +} +static assert(phy_channel_info.sizeof == 8); + +// PHY/RF (from libbl606p_phyrf.a). phy_init is called from inside wifi_main +// by the blob with its own config arg -- do not call from host code. +void phy_get_channel(phy_channel_info* info, ubyte index); +ubyte phy_get_mac_freq(); +void phy_get_rf_gain_capab(byte* max, byte* min); +void rf_dump_status(); + + +// ==================================================================== +// Vendor message structs we touch directly (small / leaf only) +// ==================================================================== + +struct mm_add_if_cfm +{ + ubyte status; + ubyte inst_nbr; +} +static assert(mm_add_if_cfm.sizeof == 2); + +struct mm_monitor_cfm +{ + uint status; + uint enable; + uint[8] data; +} +static assert(mm_monitor_cfm.sizeof == 40); + +struct mm_monitor_channel_cfm +{ + uint status; + uint band; + uint freq; + uint center_freq1; + uint center_freq2; + uint type; +} + +struct apm_start_cfm +{ + ubyte status; + ubyte vif_idx; + ubyte ch_idx; + ubyte bcmc_idx; +} +static assert(apm_start_cfm.sizeof == 4); + +struct mac_addr +{ + ubyte[6] array_; +} + +struct utils_list_hdr +{ + utils_list_hdr* next; +} +static assert(utils_list_hdr.sizeof == 4); + +struct hostdesc +{ + uint pbuf_addr; + uint packet_addr; + ushort packet_len; + uint status_addr; + mac_addr eth_dest_addr; + mac_addr eth_src_addr; + ushort ethertype; + ushort[4] pn; + ushort sn; + ushort timestamp; + ubyte tid; + ubyte vif_idx; + ubyte staid; + ushort flags; + uint[4] pbuf_chained_ptr; + uint[4] pbuf_chained_len; +} +static assert(hostdesc.sizeof == 80); +static assert(hostdesc.status_addr.offsetof == 12); +static assert(hostdesc.eth_dest_addr.offsetof == 16); +static assert(hostdesc.flags.offsetof == 46); + +struct txdesc_host +{ + uint ready; + uint[1600 / 4] eth_packet; + hostdesc host; + uint[204 / 4] pad_txdesc; + uint[400 / 4] pad_buf; +} +static assert(txdesc_host.sizeof == 2288); + +struct pbuf +{ + pbuf* next; + void* payload; + ushort tot_len; + ushort len; + ubyte type; + ubyte flags; + ushort ref_; +} +static assert(pbuf.sizeof == 16); + +alias bl_custom_tx_callback_t = extern(C) void function(void* cb_arg, bool tx_ok) nothrow @nogc; + +struct bl_custom_tx_cfm +{ + bl_custom_tx_callback_t cb; + void* cb_arg; +} +static assert(bl_custom_tx_cfm.sizeof == 8); + +struct bl_txhdr +{ + utils_list_hdr item; + uint status; + uint* p; + hostdesc host; + bl_custom_tx_cfm custom_cfm; +} +static assert(bl_txhdr.sizeof == 100); + +struct tx_slot +{ + pbuf pb; + bl_txhdr hdr; + bool used; +} + +enum TXDESC_CNT0 = 4; + +@section(".sram_data.wifi") align(4) __gshared tx_slot[TXDESC_CNT0] _tx_slots; + +txdesc_host* ipc_host_txdesc_get(ipc_host_env_tag* env); +void ipc_host_txdesc_push(ipc_host_env_tag* env, void* host_id); + +struct mac_ssid +{ + ubyte length; + ubyte[32] array_; +} + +struct bl_send_scanu_para +{ + ushort* channels; + ushort channel_num; + mac_addr* bssid; + mac_ssid* ssid; + ubyte* mac; + ubyte scan_mode; + uint duration_scan; +} + + +// ==================================================================== +// struct bl_hw and its nested types -- the central vendor state object. +// +// Mirrored from bl_defs.h / bl_cmds.h / cfg80211.h / ieee80211.h for RV32 +// ilp32f with CFG_TXDESC=4, CFG_STA_MAX=5, CFG_BL_STATISTIC undefined. +// The static asserts at the bottom catch any drift from a vendor resync. +// ==================================================================== + +enum NX_VIRT_DEV_MAX = 2; +enum NX_REMOTE_STA_MAX = 5; +enum VIF_TABLE_LEN = NX_VIRT_DEV_MAX + NX_REMOTE_STA_MAX; // 7 +enum STA_TABLE_LEN = NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX; // 7 + +struct list_head +{ + list_head* next; + list_head* prev; +} + +struct ieee80211_mcs_info +{ + ubyte[10] rx_mask; + ushort rx_highest; + ubyte tx_params; + ubyte[3] reserved; +} + +struct ieee80211_sta_ht_cap +{ + ushort cap; + bool ht_supported; + ubyte ampdu_factor; + ubyte ampdu_density; + ieee80211_mcs_info mcs; +} + +struct bl_sta +{ + mac_addr sta_addr; + ubyte is_used; + ubyte sta_idx; + ubyte vif_idx; + ubyte vlan_idx; + ubyte qos; + byte rssi; + ubyte data_rate; + uint tsflo; + uint tsfhi; +} + +struct bl_vif +{ + list_head list; + void* dev; + bool up; + union variant_t + { + struct sta_t { bl_sta* ap; bl_sta* tdls_sta; } + struct ap_t { list_head sta_list; ubyte bcmc_index; } + struct ap_vlan_t { bl_vif* master; bl_sta* sta_4a; } + sta_t sta; + ap_t ap; + ap_vlan_t ap_vlan; + } + variant_t variant; +} + +enum bl_cmd_mgr_state : int +{ + DEINIT = 0, + INITED = 1, + CRASHED = 2, +} + +struct bl_cmd_mgr +{ + bl_cmd_mgr_state state; + uint next_tkn; + uint queue_sz; + uint max_queue_sz; + list_head cmds; + void* lock; + extern (C) int function(bl_cmd_mgr*, bl_cmd*) nothrow @nogc queue; + extern (C) int function(bl_cmd_mgr*, bl_cmd*) nothrow @nogc llind; + extern (C) int function(bl_cmd_mgr*, ipc_e2a_msg*, msg_cb_fct) nothrow @nogc msgind; + extern (C) void function(bl_cmd_mgr*) nothrow @nogc print; + extern (C) void function(bl_cmd_mgr*) nothrow @nogc drain; +} + +struct bl_cmd +{ + list_head list; + uint id; + uint reqid; + void* a2e_msg; // struct lmac_msg* + void* e2a_msg; + uint tkn; + ushort flags; + void* complete; // BL_EventGroup_t + uint result; +} + +struct bl_hw +{ + int is_up; + bl_cmd_mgr cmd_mgr; + ipc_host_env_tag* ipc_env; + list_head vifs; + bl_vif[VIF_TABLE_LEN] vif_table; + bl_sta[STA_TABLE_LEN] sta_table; + uint drv_flags; + void* mod_params; + ieee80211_sta_ht_cap ht_cap; + // Vif slots default to -1 (no VIF). Vendor C never writes these except + // through bl_send_add_if's CFM, so without this default the boot-time + // "set_mode(none)" path would tear-down phantom VIF 0 against LMAC. + int vif_index_sta = -1; + int vif_index_ap = -1; + int sta_idx; + int ap_bcmc_idx; +} + +// Drift checks against the vendor C build (RV32 ilp32f, CFG_TXDESC=4, +// CFG_STA_MAX=5, CFG_BL_STATISTIC undef). +static assert(bl_hw.sizeof == 476); +static assert(bl_hw.is_up.offsetof == 0); +static assert(bl_hw.cmd_mgr.offsetof == 4); +static assert(bl_hw.ipc_env.offsetof == 52); +static assert(bl_hw.vifs.offsetof == 56); +static assert(bl_hw.vif_table.offsetof == 64); +static assert(bl_hw.sta_table.offsetof == 260); +static assert(bl_hw.drv_flags.offsetof == 428); +static assert(bl_hw.mod_params.offsetof == 432); +static assert(bl_hw.ht_cap.offsetof == 436); +static assert(bl_hw.vif_index_sta.offsetof == 460); +static assert(bl_vif.sizeof == 28); +static assert(bl_sta.sizeof == 24); +static assert(bl_cmd_mgr.sizeof == 48); +static assert(list_head.sizeof == 8); +static assert(ieee80211_sta_ht_cap.sizeof == 22); + + +// ==================================================================== diff --git a/src/urt/driver/bl808_m0/wifi_pm.d b/src/urt/driver/bl808_m0/wifi_pm.d new file mode 100644 index 0000000..43b288c --- /dev/null +++ b/src/urt/driver/bl808_m0/wifi_pm.d @@ -0,0 +1,264 @@ +module urt.driver.bl808_m0.wifi_pm; + +version (BL808_M0): + +import urt.driver.bl808_m0.bl_ops : bl_ops_msleep; + +nothrow @nogc: +extern(C): + + +// wifi_hosal -- power management hooks called from libwifi.a. The SDK wires +// these through wifi_hosal_bl808.c to bl_pm.c before spawning wifi_main. +alias bl_pm_cb_t = extern(C) int function(void*) nothrow @nogc; + +private enum PM_DISABLE = 0; +private enum PM_ENABLE = 1; + +private enum WLAN_PM_EVENT_CONTROL = 0; +private enum WLAN_PM_EVENT_MAX = 6; + +private enum WLAN_CODE_PM_NOTIFY_START = 0; +private enum WLAN_CODE_PM_NOTIFY_STOP = 1; +private enum WLAN_CODE_PM_START = 2; +private enum WLAN_CODE_PM_STOP = 3; + +private enum PM_STATE_INITED = 0; +private enum PM_STATE_STOP = 1; +private enum PM_STATE_START = 2; +private enum PM_STATE_STOPPED = 3; +private enum PM_STATE_RUNNING = 4; + +private enum NODE_CAP_BIT_UAPSD_MODE = 1u << 0; +private enum NODE_CAP_BIT_MAC_IDLE = 1u << 1; +private enum NODE_CAP_BIT_MAC_DOZE = 1u << 2; +private enum NODE_CAP_BIT_RF_ONOFF = 1u << 3; +private enum NODE_CAP_BIT_WLAN_BLE_ABORT = 1u << 4; +private enum NODE_CAP_BIT_FORCE_SLEEP = 1u << 5; + +private enum PM_MODE_STA_NONE = 0; +private enum PM_MODE_STA_IDLE = 1; +private enum PM_MODE_STA_MESH = 2; +private enum PM_MODE_STA_DOZE = 3; +private enum PM_MODE_STA_COEX = 4; +private enum PM_MODE_STA_DOWN = 5; +private enum PM_MODE_AP_IDLE = 6; + +private struct PmNode +{ + int event; + uint code; + uint cap_bit; + ushort priority; + bl_pm_cb_t ops; + void* arg; + int enable; +} + +private __gshared PmNode[32] _pm_nodes; +private __gshared uint _pm_node_count; +private __gshared uint _pm_wlan_capacity; +private __gshared uint _pm_bt_capacity = 0xFFFF; +private __gshared int _pm_state = PM_STATE_INITED; + +int wifi_hosal_pm_init() +{ + foreach (i; 0 .. _pm_nodes.length) + _pm_nodes[i] = PmNode.init; + _pm_node_count = 0; + _pm_wlan_capacity = 0; + _pm_bt_capacity = 0xFFFF; + _pm_state = PM_STATE_INITED; + return 0; +} + +int wifi_hosal_pm_event_register(int event, uint code, uint cap_bit, ushort priority, bl_pm_cb_t ops, void* arg, int enable) +{ + if (event < 0 || event >= WLAN_PM_EVENT_MAX || _pm_node_count >= _pm_nodes.length) + return -1; + + uint pos = _pm_node_count++; + while (pos > 0 && priority < _pm_nodes[pos - 1].priority) + { + _pm_nodes[pos] = _pm_nodes[pos - 1]; + --pos; + } + + _pm_nodes[pos] = PmNode(event, code, cap_bit, priority, ops, arg, enable); + return 0; +} + +int wifi_hosal_pm_deinit() +{ + _pm_node_count = 0; + _pm_state = PM_STATE_INITED; + return 0; +} + +extern(D) private int pm_internal_process_event(int event, uint code) +{ + if (event != WLAN_PM_EVENT_CONTROL) + return 0; + + if (code == WLAN_CODE_PM_NOTIFY_START) + { + if (_pm_state != PM_STATE_INITED && _pm_state != PM_STATE_STOPPED) + return -1; + _pm_state = PM_STATE_START; + } + else if (code == WLAN_CODE_PM_NOTIFY_STOP) + { + if (_pm_state != PM_STATE_RUNNING) + return -1; + _pm_state = PM_STATE_STOP; + } + + return 0; +} + +int wifi_hosal_pm_post_event(int event, uint code, uint* retval) +{ + if (event < 0 || event >= WLAN_PM_EVENT_MAX) + return -1; + + if (retval) + *retval = 0; + + foreach (i; 0 .. _pm_node_count) + { + auto node = &_pm_nodes[i]; + if (!node.enable || node.event != event || node.code != code) + continue; + if (((_pm_wlan_capacity & node.cap_bit) == 0) || ((_pm_bt_capacity & node.cap_bit) == 0)) + continue; + if (event != WLAN_PM_EVENT_CONTROL && _pm_state != PM_STATE_RUNNING) + return -1; + if (node.ops) + { + int ret = node.ops(node.arg); + if (ret && retval) + *retval |= 1; + } + } + + int ret = pm_internal_process_event(event, code); + bl_ops_msleep(1); + return ret; +} + +int wifi_hosal_pm_state_run() +{ + final switch (_pm_state) + { + case PM_STATE_INITED: + return -1; + case PM_STATE_START: + _pm_state = PM_STATE_RUNNING; + return wifi_hosal_pm_post_event(WLAN_PM_EVENT_CONTROL, WLAN_CODE_PM_START, null); + case PM_STATE_STOP: + _pm_state = PM_STATE_STOPPED; + return wifi_hosal_pm_post_event(WLAN_PM_EVENT_CONTROL, WLAN_CODE_PM_STOP, null); + case PM_STATE_RUNNING: + return 0; + case PM_STATE_STOPPED: + return -1; + } +} + +int wifi_hosal_pm_capacity_set(int level) +{ + uint capacity; + final switch (level) + { + case PM_MODE_STA_NONE: + return -1; + case PM_MODE_STA_IDLE: + capacity = NODE_CAP_BIT_UAPSD_MODE | NODE_CAP_BIT_MAC_IDLE; + break; + case PM_MODE_STA_MESH: + capacity = NODE_CAP_BIT_UAPSD_MODE | NODE_CAP_BIT_MAC_IDLE | + NODE_CAP_BIT_WLAN_BLE_ABORT | NODE_CAP_BIT_FORCE_SLEEP; + break; + case PM_MODE_STA_DOZE: + capacity = NODE_CAP_BIT_UAPSD_MODE | NODE_CAP_BIT_MAC_IDLE | + NODE_CAP_BIT_MAC_DOZE | NODE_CAP_BIT_RF_ONOFF | + NODE_CAP_BIT_FORCE_SLEEP; + break; + case PM_MODE_STA_COEX: + capacity = NODE_CAP_BIT_UAPSD_MODE | NODE_CAP_BIT_MAC_IDLE | + NODE_CAP_BIT_MAC_DOZE | NODE_CAP_BIT_RF_ONOFF | + NODE_CAP_BIT_WLAN_BLE_ABORT; + break; + case PM_MODE_STA_DOWN: + capacity = NODE_CAP_BIT_MAC_IDLE | NODE_CAP_BIT_MAC_DOZE | + NODE_CAP_BIT_RF_ONOFF; + break; + case PM_MODE_AP_IDLE: + capacity = NODE_CAP_BIT_MAC_IDLE | NODE_CAP_BIT_MAC_DOZE; + break; + } + _pm_wlan_capacity = capacity; + return 0; +} + +int wifi_hosal_pm_event_switch(int event, uint code, int enable) +{ + int ret = -1; + foreach (i; 0 .. _pm_node_count) + { + auto node = &_pm_nodes[i]; + if (node.event == event && node.code == code) + { + node.enable = enable; + ret = 0; + } + } + return ret; +} + +int wifi_hosal_rf_turn_on(void* arg) +{ + // Mirrors the RF portion of vendor AON_LowPower_Exit_PDS0(). The blob + // calls this before rf_init and around RF/channel state transitions; a + // no-op here leaves the MAC alive but the analog RF path dark. + enum uint AON_RF_TOP_AON = 0x2000_F880; + enum uint AON_MISC = 0x2000_F808; + enum uint GLB_CGEN_CFG0 = 0x2000_0000; + enum uint PU_MBG = 1u << 0; + enum uint PU_LDO15RF = 1u << 1; + enum uint PU_SFREG = 1u << 2; + enum uint SW_WB_EN = 1u << 1; + + import urt.driver.bl618.timer : mtime_read; + static void delay_us(ulong us) + { + ulong start = mtime_read(); + while (mtime_read() - start < us) {} + } + + auto rf = cast(uint*)cast(size_t)AON_RF_TOP_AON; + uint v = *rf | PU_MBG; + *rf = v; + delay_us(20); + v |= PU_LDO15RF; + *rf = v; + delay_us(60); + v |= PU_SFREG; + *rf = v; + delay_us(20); + + auto misc = cast(uint*)cast(size_t)AON_MISC; + *misc = *misc | SW_WB_EN; + + auto cgen = cast(uint*)cast(size_t)GLB_CGEN_CFG0; + *cgen = *cgen | (1u << 6) | (1u << 7); + + return 0; +} + +int wifi_hosal_rf_turn_off(void* arg) +{ + // The blob calls this during normal channel/RF transitions; powering down + // here leaves the MAC alive while the analog RF path goes dark. + return 0; +} diff --git a/src/urt/driver/bl808_m0/wifi_wpa.d b/src/urt/driver/bl808_m0/wifi_wpa.d new file mode 100644 index 0000000..db0150a --- /dev/null +++ b/src/urt/driver/bl808_m0/wifi_wpa.d @@ -0,0 +1,774 @@ +module urt.driver.bl808_m0.wifi_wpa; + +version (BL808_M0): + +import urt.driver.bl808_m0.wifi; +import urt.driver.bl808_m0.wifi_lmac; +import urt.driver.wifi; +import urt.driver.wpa.eapol; + +nothrow @nogc: +package: + +// ==================================================================== +// WPA callback table and AP authenticator +// ==================================================================== + +struct wpa_funcs +{ +nothrow @nogc: + extern(C) bool function() wpa_sta_init; + extern(C) bool function() wpa_sta_deinit; + extern(C) void function(void* parm) wpa_sta_config; + extern(C) void function(void* parm) wpa_sta_connect; + extern(C) void function(ubyte reason_code) wpa_sta_disconnected_cb; + extern(C) int function(ubyte* src_addr, ubyte* buf, uint len) wpa_sta_rx_eapol; + extern(C) void* function(void* parm) wpa_ap_init; + extern(C) bool function(void* data) wpa_ap_deinit; + extern(C) bool function(void** sm, ubyte* mac, ubyte* wpa_ie, ubyte wpa_ie_len) wpa_ap_join; + extern(C) void function(void* wpa_sm, ubyte sta_idx) wpa_ap_sta_associated; + extern(C) bool function(void* sm) wpa_ap_remove; + extern(C) bool function(void* hapd_data, void* sm, ubyte* data, size_t data_len) wpa_ap_rx_eapol; + extern(C) int function(const(ubyte)* wpa_ie, size_t wpa_ie_len, void* data) wpa_parse_wpa_ie; + extern(C) void function(void* tlv_pack_cb) wpa_reg_diag_tlv_cb; + extern(C) ubyte* function(ubyte* bssid, ubyte* mac, ubyte* passphrase, uint sae_msg_type, size_t* sae_msg_len) wpa3_build_sae_msg; + extern(C) int function(ubyte* buf, size_t len, uint type, ushort status) wpa3_parse_sae_msg; + extern(C) void function() wpa3_clear_sae; +} + +extern(C) int bl_wifi_register_wpa_cb_internal(const(wpa_funcs)* cb); +extern(C) bool bl_wifi_auth_done_internal(ubyte sta_idx, ushort reason_code); +private __gshared ubyte _ap_hapd_sentinel; +private __gshared ubyte _ap_sm_sentinel; +private __gshared ubyte[6] _ap_auth_sta_mac; +private __gshared ubyte[6] _ap_auth_ap_mac; +private __gshared ubyte _ap_auth_sta_idx = ubyte.max; +private __gshared ubyte[32] _ap_auth_anonce; +private __gshared ubyte[8] _ap_auth_replay; +private __gshared ubyte[32] _ap_auth_pmk; +private __gshared ubyte[48] _ap_auth_ptk; +private __gshared ubyte[16] _ap_auth_gtk; +private __gshared ubyte[8] _ap_auth_group_rsc; +private __gshared bool _ap_auth_have_pmk; +private __gshared uint _ap_auth_msg1_count; +private __gshared uint _ap_auth_msg2_count; +private __gshared uint _ap_auth_msg3_count; +private __gshared uint _ap_auth_msg4_count; +private __gshared ubyte[14 + 160] _ap_auth_last_msg3; +private __gshared size_t _ap_auth_last_msg3_len; +private __gshared uint _ap_auth_msg3_retx; +private __gshared ulong _ap_auth_msg3_next_retx_us; + +void ap_auth_reset() +{ + _ap_auth_sta_idx = ubyte.max; + _ap_auth_have_pmk = false; + _ap_auth_msg1_count = 0; + _ap_auth_msg2_count = 0; + _ap_auth_msg3_count = 0; + _ap_auth_msg4_count = 0; + _ap_auth_last_msg3_len = 0; + _ap_auth_msg3_retx = 0; + _ap_auth_msg3_next_retx_us = 0; + _ap_auth_group_rsc[] = 0; + _ap_auth_ap_mac[] = 0; + _ap_auth_sta_mac[] = 0; +} + +private bool ap_install_keys() +{ + int pair_ret = bl_wifi_set_sta_key_internal( + cast(ubyte)_bl_hw.vif_index_ap, _ap_auth_sta_idx, + wpa_alg_ccmp, 0, 1, + null, 0, _ap_auth_ptk.ptr + 32, 16, + true); + + int group_ret = -1; + if (_bl_hw.ap_bcmc_idx >= 0) + group_ret = bl_wifi_set_sta_key_internal( + cast(ubyte)_bl_hw.vif_index_ap, cast(ubyte)_bl_hw.ap_bcmc_idx, + wpa_alg_ccmp, 1, 1, + _ap_auth_group_rsc.ptr, _ap_auth_group_rsc.length, + _ap_auth_gtk.ptr, _ap_auth_gtk.length, + false); + + return pair_ret == 0 && group_ret == 0; +} + +private bool ap_compute_pmk() +{ + import urt.crypto.pbkdf2 : wpa2_psk_to_pmk; + + size_t ssid_len; + while (ssid_len < _ap_ssid_buf.length && _ap_ssid_buf[ssid_len] != 0) ++ssid_len; + size_t pass_len; + while (pass_len < _ap_pw_buf.length && _ap_pw_buf[pass_len] != 0) ++pass_len; + if (ssid_len == 0 || pass_len < 8) + return false; + auto ssid = cast(const(char)[])_ap_ssid_buf[0 .. ssid_len]; + auto pass = cast(const(char)[])_ap_pw_buf[0 .. pass_len]; + _ap_auth_have_pmk = wpa2_psk_to_pmk(pass, ssid, _ap_auth_pmk).succeeded; + return _ap_auth_have_pmk; +} + +bool ap_auth_has_pmk() +{ + return _ap_auth_have_pmk; +} + +private void ap_mic(const(ubyte)[] kck, const(ubyte)[] frame, ref ubyte[16] out_mic) +{ + import urt.digest.hmac : HMACContext, hmac_init, hmac_update, hmac_finalise; + import urt.digest.sha : SHA1Context; + + HMACContext!SHA1Context h; + hmac_init(h, kck); + hmac_update(h, frame); + ubyte[SHA1Context.DigestLen] digest = hmac_finalise(h); + out_mic[] = digest[0 .. 16]; +} + +private bool ap_verify_mic(const(ubyte)[] kck, const(ubyte)[] frame, const(ubyte)[16] expected) +{ + import urt.driver.wpa.eapol : off_mic, eapol_key_mic_len; + + ubyte[256] scratch = void; + if (frame.length > scratch.length || frame.length < off_mic + eapol_key_mic_len) + return false; + scratch[0 .. frame.length] = frame[]; + scratch[off_mic .. off_mic + eapol_key_mic_len] = 0; + ubyte[16] computed; + ap_mic(kck, scratch[0 .. frame.length], computed); + ubyte diff; + foreach (i; 0 .. 16) + diff |= computed[i] ^ expected[i]; + return diff == 0; +} + +private void ap_inc_replay() +{ + foreach_reverse (i; 0 .. _ap_auth_replay.length) + { + _ap_auth_replay[i]++; + if (_ap_auth_replay[i] != 0) + break; + } +} + +private bool ap_send_msg1() +{ + import urt.crypto.random : crypto_random_bytes; + + if (_ap_auth_sta_idx == ubyte.max) + return false; + if (!crypto_random_bytes(_ap_auth_anonce[]).succeeded) + return false; + if (!_ap_auth_have_pmk && !ap_compute_pmk()) + return false; + _ap_auth_ap_mac[] = _vif_mac_ap[]; + + _ap_auth_replay[] = 0; + _ap_auth_replay[eapol_key_replay_len - 1] = cast(ubyte)(_ap_auth_msg1_count + 1); + + ubyte[8] zero_rsc = 0; + ubyte[128] eapol = void; + ushort key_info = key_info_type_pairwise | key_info_key_ack | key_info_ver_hmac_sha1_aes; + size_t eapol_len = encode_eapol_key(eapol[], + eapol_version_2004, key_desc_type_rsn, + key_info, 16, + _ap_auth_replay, _ap_auth_anonce, zero_rsc, + null); + if (eapol_len == 0) + return false; + + ubyte[14 + 128] frame = void; + frame[0 .. 6] = _ap_auth_sta_mac[]; + frame[6 .. 12] = _ap_auth_ap_mac[]; + frame[12] = 0x88; + frame[13] = 0x8e; + frame[14 .. 14 + eapol_len] = eapol[0 .. eapol_len]; + + bool ok = wifi_hw_tx(0, WifiVif.ap, frame[0 .. 14 + eapol_len]); + _ap_auth_msg1_count++; + return ok; +} + +private bool ap_send_msg3(const(ubyte)[] msg2_frame, ref const EapolKeyFrame msg2) +{ + import urt.crypto.aes_keywrap : aes_wrap; + import urt.crypto.random : crypto_random_bytes; + import urt.driver.wpa.crypto : wpa2_pmk_to_ptk; + + if (_ap_auth_sta_idx == ubyte.max || !_ap_auth_have_pmk) + return false; + + if (!wpa2_pmk_to_ptk(_ap_auth_pmk, _ap_auth_ap_mac, _ap_auth_sta_mac, + _ap_auth_anonce, msg2.key_nonce, _ap_auth_ptk[]).succeeded) + return false; + + if (!ap_verify_mic(_ap_auth_ptk[0 .. 16], msg2_frame, msg2.key_mic)) + return false; + + if (_ap_auth_msg3_count == 0) + { + if (!crypto_random_bytes(_ap_auth_gtk[]).succeeded) + return false; + } + + static immutable ubyte[22] rsn_ie = [ + 0x30, 0x14, + 0x01, 0x00, + 0x00, 0x0f, 0xac, 0x04, + 0x01, 0x00, + 0x00, 0x0f, 0xac, 0x04, + 0x01, 0x00, + 0x00, 0x0f, 0xac, 0x02, + 0x00, 0x00, + ]; + ubyte[56] key_plain = void; + size_t key_plain_len; + key_plain[key_plain_len .. key_plain_len + rsn_ie.length] = rsn_ie[]; + key_plain_len += rsn_ie.length; + key_plain[key_plain_len + 0] = 0xdd; + key_plain[key_plain_len + 1] = 0x16; + key_plain[key_plain_len + 2] = 0x00; + key_plain[key_plain_len + 3] = 0x0f; + key_plain[key_plain_len + 4] = 0xac; + key_plain[key_plain_len + 5] = 0x01; + key_plain[key_plain_len + 6] = 0x01; + key_plain[key_plain_len + 7] = 0x00; + key_plain[key_plain_len + 8 .. key_plain_len + 24] = _ap_auth_gtk[]; + key_plain_len += 24; + if ((key_plain_len & 7) != 0) + { + key_plain[key_plain_len++] = 0xdd; + while ((key_plain_len & 7) != 0) + key_plain[key_plain_len++] = 0; + } + + ubyte[64] wrapped = void; + auto wrapped_len = key_plain_len + 8; + if (!aes_wrap(_ap_auth_ptk[16 .. 32], key_plain[0 .. key_plain_len], wrapped[0 .. wrapped_len]).succeeded) + return false; + + ap_inc_replay(); + ushort key_info = key_info_type_pairwise | key_info_install | key_info_key_ack | + key_info_key_mic | key_info_secure | key_info_encr_key_data | key_info_ver_hmac_sha1_aes; + + ubyte[160] eapol = void; + size_t eapol_len = encode_eapol_key(eapol[], + eapol_version_2004, key_desc_type_rsn, + key_info, 16, + _ap_auth_replay, _ap_auth_anonce, _ap_auth_group_rsc, + wrapped[0 .. wrapped_len]); + if (eapol_len == 0) + return false; + + ubyte[16] mic; + ap_mic(_ap_auth_ptk[0 .. 16], eapol[0 .. eapol_len], mic); + patch_mic(eapol[0 .. eapol_len], mic); + + ubyte[14 + 160] frame = void; + frame[0 .. 6] = _ap_auth_sta_mac[]; + frame[6 .. 12] = _ap_auth_ap_mac[]; + frame[12] = 0x88; + frame[13] = 0x8e; + frame[14 .. 14 + eapol_len] = eapol[0 .. eapol_len]; + bool ok = wifi_hw_tx(0, WifiVif.ap, frame[0 .. 14 + eapol_len]); + _ap_auth_last_msg3[0 .. 14 + eapol_len] = frame[0 .. 14 + eapol_len]; + _ap_auth_last_msg3_len = 14 + eapol_len; + _ap_auth_msg3_retx = 0; + { + import urt.driver.bl618.timer : mtime_read; + _ap_auth_msg3_next_retx_us = mtime_read() + 500_000; + } + _ap_auth_msg3_count++; + return ok; +} + +extern(C) void* _wpa_ap_init(void* parm) + => &_ap_hapd_sentinel; + +extern(C) bool _wpa_ap_deinit(void*) + => true; + +extern(C) bool _wpa_ap_join(void** sm, ubyte* mac, ubyte* wpa_ie, ubyte wpa_ie_len) +{ + bool encrypted = wpa_ie !is null && wpa_ie_len > 0; + bool busy = encrypted && _ap_auth_sta_mac[] != typeof(_ap_auth_sta_mac).init + && (mac is null || _ap_auth_sta_mac[] != mac[0 .. 6]); + if (busy) + { + if (sm) *sm = null; + return false; + } + + if (mac) + _ap_auth_sta_mac[] = mac[0 .. 6]; + _ap_auth_sta_idx = ubyte.max; + if (sm && !encrypted) + *sm = null; + else if (sm) + *sm = &_ap_sm_sentinel; + return true; +} + +extern(C) void _wpa_ap_sta_associated(void* sm, ubyte sta_idx) +{ + _ap_auth_sta_idx = sta_idx; + if (sm !is null) + ap_send_msg1(); +} + +extern(C) bool _wpa_ap_remove(void* sm) +{ + if (sm !is null) + ap_auth_reset(); + return sm !is null; +} + +extern(C) bool _wpa_ap_rx_eapol(void*, void* sa, ubyte* data, size_t len) +{ + enum ushort reason_mic_failure = 14; + enum ushort reason_4way_timeout = 15; + + EapolKeyFrame key; + bool decoded = data !is null && decode_eapol_key(data[0 .. len], key); + bool is_msg2 = decoded && (key.key_info & key_info_key_mic) != 0 && + (key.key_info & key_info_key_ack) == 0 && + (key.key_info & key_info_secure) == 0; + bool is_msg4 = decoded && (key.key_info & key_info_key_mic) != 0 && + (key.key_info & key_info_key_ack) == 0 && + (key.key_info & key_info_secure) != 0; + if (is_msg2) + { + _ap_auth_msg2_count++; + if (!ap_send_msg3(data[0 .. len], key) && _ap_auth_sta_idx != ubyte.max) + bl_wifi_auth_done_internal(_ap_auth_sta_idx, reason_4way_timeout); + } + else if (is_msg4) + { + _ap_auth_msg4_count++; + bool mic_ok = ap_verify_mic(_ap_auth_ptk[0 .. 16], data[0 .. len], key.key_mic); + bool keys_ok = mic_ok && ap_install_keys(); + bool auth_ok = keys_ok && bl_wifi_auth_done_internal(_ap_auth_sta_idx, 0); + if (auth_ok) + _ap_auth_last_msg3_len = 0; + else if (_ap_auth_sta_idx != ubyte.max) + bl_wifi_auth_done_internal(_ap_auth_sta_idx, + mic_ok ? reason_4way_timeout : reason_mic_failure); + } + return true; +} +extern(C) int _wpa_parse_wpa_ie(const(ubyte)* ie, size_t len, void* data) +{ + if (ie is null || data is null || len < 22) + return -1; + + enum int wpa_proto_rsn = 1 << 1; + enum int wpa_key_mgmt_psk = 1 << 1; + enum int wifi_cipher_type_ccmp = 4; + enum int wifi_cipher_type_tkip = 3; + + bool is_rsn = ie[0] == 0x30; + if (!is_rsn || ie[1] + 2 > len) + return -1; + + size_t p = 2; + if (p + 2 > len) return -1; + p += 2; // version + if (p + 4 > len) return -1; + int group = ie[p + 3] == 2 ? wifi_cipher_type_tkip : + (ie[p + 3] == 4 ? wifi_cipher_type_ccmp : 0); + p += 4; + if (p + 2 > len) return -1; + ushort pair_count = cast(ushort)(ie[p] | (ie[p + 1] << 8)); + p += 2; + int pairwise; + foreach (_; 0 .. pair_count) + { + if (p + 4 > len) return -1; + if (ie[p + 3] == 4) pairwise = wifi_cipher_type_ccmp; + else if (ie[p + 3] == 2 && pairwise == 0) pairwise = wifi_cipher_type_tkip; + p += 4; + } + if (p + 2 > len) return -1; + ushort akm_count = cast(ushort)(ie[p] | (ie[p + 1] << 8)); + p += 2; + int key_mgmt; + foreach (_; 0 .. akm_count) + { + if (p + 4 > len) return -1; + if (ie[p + 3] == 2) key_mgmt |= wpa_key_mgmt_psk; + p += 4; + } + int caps; + if (p + 2 <= len) + caps = cast(int)(ie[p] | (ie[p + 1] << 8)); + + auto out_ = cast(int*)data; + out_[0] = wpa_proto_rsn; + out_[1] = pairwise; + out_[2] = group; + out_[3] = key_mgmt; + out_[4] = caps; + out_[5] = 0; // num_pmkid + out_[6] = 0; // pmkid pointer on rv32 + out_[7] = 0; // mgmt_group_cipher + + return pairwise != 0 && group != 0 && key_mgmt != 0 ? 0 : -1; +} + +extern(C) void _wpa_reg_diag_tlv_cb(void*) +{ +} + +extern(C) ubyte* _wpa3_build_sae_msg(ubyte*, ubyte*, ubyte*, uint, size_t* len) +{ + if (len) + *len = 0; + return null; +} + +extern(C) int _wpa3_parse_sae_msg(ubyte*, size_t, uint, ushort) + => -1; + +extern(C) void _wpa3_clear_sae() +{ +} + +// ==================================================================== +// STA WPA adapter +// ==================================================================== + +import urt.driver.wpa.supplicant : WpaKeyMgmt, WpaStaSupplicant, WpaSupplicantState; +import urt.driver.wpa.fourway : WpaHandshakeReason, wpa_handshake_reason_message; + +private __gshared WpaStaSupplicant _sta_supplicant; +private __gshared ubyte[32] _sta_rsn_ie_buf; +private __gshared size_t _sta_rsn_ie_len; +private __gshared ubyte _sta_vif_idx; +private __gshared ubyte _sta_sta_idx; +private __gshared ubyte[6] _sta_own_mac; +private __gshared ubyte[6] _sta_bssid; + +private bool mac_nonzero(const(ubyte)[] mac) +{ + foreach (b; mac) + if (b != 0) + return true; + return false; +} + +// libwifi extern bindings used by the supplicant hooks. +// wpa_alg_t values (from supplicant_api.h:42): WIFI_WPA_ALG_CCMP = 3. +private enum int wpa_alg_ccmp = 3; +// wifi_appie_wpa_rsn = 0 (from supplicant_api.h:35). +private enum ubyte wifi_appie_wpa_rsn = 0; +extern(C) int bl_wifi_set_appie_internal(ubyte vif_idx, ubyte appie_type, + ubyte* ie, ushort len, bool sta); +extern(C) bool bl_wifi_sta_is_ap_notify_completed_rsne_internal(); +extern(C) int bl_wifi_set_sta_key_internal(ubyte vif_idx, ubyte sta_idx, + int alg, int key_idx, int set_tx, + ubyte* seq, size_t seq_len, + ubyte* key, size_t key_len, + bool pairwise); + + +struct WifiConnectParmView +{ +nothrow @nogc: + private const(ubyte)* p; + + this(const(void)* parm) { p = cast(const(ubyte)*)parm; } + + @property ubyte vif_idx() const => p[0]; + @property ubyte sta_idx() const => p[1]; + @property const(ubyte)[] mac() const => p[2 .. 8]; + @property const(ubyte)[] bssid() const => p[8 .. 14]; + @property uint ssid_len() const => *cast(const(uint)*)(p + 16); + @property const(ubyte)[] ssid() const + { + size_t n = ssid_len; + if (n > 32) n = 32; + return p[20 .. 20 + n]; + } + @property ubyte proto() const => p[52]; + @property ushort key_mgmt() const => cast(ushort)(p[54] | (p[55] << 8)); + @property ubyte pairwise_cipher() const => p[56]; + @property ubyte group_cipher() const => p[57]; + @property const(char)[] passphrase() const + { + size_t n; + while (n < 64 && p[58 + n] != 0) ++n; + return cast(const(char)[])p[58 .. 58 + n]; + } + @property bool pmf_required() const => p[123] != 0; +} + + +private const(ubyte)[] build_wpa2_psk_rsn_ie() +{ + static immutable ubyte[8] short_template = [ + 0x30, 0x06, + 0x01, 0x00, + 0x00, 0x0f, 0xac, 0x04, + ]; + static immutable ubyte[22] full_template = [ + 0x30, 0x14, + 0x01, 0x00, + 0x00, 0x0f, 0xac, 0x04, + 0x01, 0x00, + 0x00, 0x0f, 0xac, 0x04, + 0x01, 0x00, + 0x00, 0x0f, 0xac, 0x02, + 0x00, 0x00, + ]; + + const(ubyte)[] template_ = bl_wifi_sta_is_ap_notify_completed_rsne_internal() + ? full_template[] + : short_template[]; + _sta_rsn_ie_buf[0 .. template_.length] = template_[]; + _sta_rsn_ie_len = template_.length; + return _sta_rsn_ie_buf[0 .. template_.length]; +} + + +extern(C) bool _wpa_sta_init_real() +{ + _sta_supplicant.state = WpaSupplicantState.idle; + return true; +} + +extern(C) bool _wpa_sta_deinit_real() +{ + _sta_supplicant.disconnected(0); + return true; +} + +extern(C) void _wpa_sta_config_real(void* parm) +{ + auto v = WifiConnectParmView(parm); + _sta_vif_idx = v.vif_idx; + _sta_sta_idx = v.sta_idx; + _sta_own_mac[] = v.mac[]; + _sta_bssid[] = v.bssid[]; + + WifiStaConfig cfg; + cfg.ssid = v.ssid.length != 0 + ? cast(const(char)[])v.ssid + : cast(const(char)[])_sta_cfg_ssid_buf[0 .. _sta_cfg_ssid_len]; + cfg.password = v.passphrase.length != 0 + ? v.passphrase + : cast(const(char)[])_sta_cfg_pw_buf[0 .. _sta_cfg_pw_len]; + cfg.bssid = _sta_bssid; + cfg.pmf_required = v.pmf_required; + + _sta_supplicant.hooks.send_eapol = &_sta_hook_send_eapol; + _sta_supplicant.hooks.install_pairwise_key = &_sta_hook_install_pairwise; + _sta_supplicant.hooks.install_group_key = &_sta_hook_install_group; + _sta_supplicant.hooks.auth_done = &_sta_hook_auth_done; + + auto cfg_result = _sta_pending_pmk_hex_len == 64 + ? _sta_supplicant.configure_precomputed(cfg, _sta_pending_pmk[]) + : _sta_supplicant.configure(cfg); + if (!cfg_result.succeeded) + { + if (_sta_supplicant.last_reason != 0) + _sta_hook_auth_done(_sta_supplicant.last_reason); + return; + } + + auto ie = build_wpa2_psk_rsn_ie(); + bl_wifi_set_appie_internal(v.vif_idx, wifi_appie_wpa_rsn, + cast(ubyte*)ie.ptr, cast(ushort)ie.length, true); + + _sta_supplicant.begin_association(_sta_own_mac, ie); + _sta_pending_keys = false; + _sta_pending_auth = false; + _sta_pending_auth_reason = 0; + _sta_pending_tk_len = 0; + _sta_pending_gtk_len = 0; +} + +extern(C) void _wpa_sta_connect_real(void* parm) +{ + auto v = WifiConnectParmView(parm); + if (mac_nonzero(v.bssid)) + _sta_bssid[] = v.bssid[]; + + if (_bl_hw.sta_idx < 0 && _sta_sta_idx < _bl_hw.sta_table.length) + { + _sta_ap_idx = _sta_sta_idx; + _bl_hw.sta_idx = _sta_sta_idx; + auto sta = &_bl_hw.sta_table[_sta_sta_idx]; + sta.sta_addr.array_ = _sta_bssid; + sta.is_used = 1; + sta.sta_idx = _sta_sta_idx; + sta.vif_idx = _sta_vif_idx; + sta.vlan_idx = _sta_vif_idx; + sta.qos = 1; + if (_sta_vif_idx < _bl_hw.vif_table.length) + _bl_hw.vif_table[_sta_vif_idx].variant.sta.ap = sta; + } + + _sta_supplicant.associated(_sta_bssid); +} + +extern(C) void _wpa_sta_disconnected_cb_real(ubyte reason) +{ + _sta_supplicant.disconnected(reason); + _sta_pending_keys = false; + _sta_pending_auth = false; +} + +extern(C) int _wpa_sta_rx_eapol_real(ubyte* src_addr, ubyte* buf, uint len) +{ + int rc = _sta_supplicant.receive_eapol(buf[0 .. len]); + return rc; +} + +bool sta_wpa_owns_eapol_key(WifiVif rx_vif, const(ubyte)* eth, uint eth_len) +{ + if (rx_vif != WifiVif.sta || eth is null || eth_len < 14 + eapol_hdr_len) + return false; + if (_sta_supplicant.profile.key_mgmt != WpaKeyMgmt.wpa2_psk) + return false; + + auto state = _sta_supplicant.state; + if (state != WpaSupplicantState.associated && + state != WpaSupplicantState.keying && + state != WpaSupplicantState.completed) + return false; + + if (eth[0 .. 6] != _sta_own_mac[] || eth[6 .. 12] != _sta_bssid[]) + return false; + + EapolKeyFrame key; + return decode_eapol_key(eth[14 .. eth_len], key) && + key.descriptor_type == key_desc_type_rsn; +} + + +bool _sta_hook_send_eapol(const(ubyte)[] eapol) +{ + ubyte[14 + 256] frame = void; + if (eapol.length > frame.length - 14) + return false; + frame[0 .. 6] = _sta_bssid[]; + frame[6 .. 12] = _sta_own_mac[]; + frame[12] = 0x88; + frame[13] = 0x8E; + frame[14 .. 14 + eapol.length] = eapol[]; + bool ok = wifi_hw_tx(0, WifiVif.sta, frame[0 .. 14 + eapol.length]); + return ok; +} + +bool _sta_hook_install_pairwise(const(ubyte)[] tk, const(ubyte)[] rsc) +{ + if (tk.length > _sta_pending_tk.length || rsc.length > _sta_pending_pair_rsc.length) + return false; + _sta_pending_tk_len = cast(ubyte)tk.length; + _sta_pending_pair_rsc_len = cast(ubyte)rsc.length; + _sta_pending_tk[0 .. tk.length] = tk[]; + if (rsc.length) + _sta_pending_pair_rsc[0 .. rsc.length] = rsc[]; + _sta_pending_keys = true; + return true; +} + +private bool sta_install_pending_pairwise() +{ + if (_sta_pending_tk_len == 0) + return false; + int ret = bl_wifi_set_sta_key_internal( + _sta_vif_idx, _sta_sta_idx, + wpa_alg_ccmp, 0, 1, + _sta_pending_pair_rsc_len ? _sta_pending_pair_rsc.ptr : null, _sta_pending_pair_rsc_len, + _sta_pending_tk.ptr, _sta_pending_tk_len, + true); + return ret == 0; +} + +bool _sta_hook_install_group(ubyte key_idx, const(ubyte)[] gtk, const(ubyte)[] rsc) +{ + if (gtk.length > _sta_pending_gtk.length || rsc.length > _sta_pending_group_rsc.length) + return false; + _sta_pending_gtk_idx = key_idx; + _sta_pending_gtk_len = cast(ubyte)gtk.length; + _sta_pending_group_rsc_len = cast(ubyte)rsc.length; + _sta_pending_gtk[0 .. gtk.length] = gtk[]; + if (rsc.length) + _sta_pending_group_rsc[0 .. rsc.length] = rsc[]; + _sta_pending_keys = true; + return true; +} + +private bool sta_install_pending_group() +{ + if (_sta_pending_gtk_len == 0) + return false; + int ret = bl_wifi_set_sta_key_internal( + _sta_vif_idx, _sta_sta_idx, + wpa_alg_ccmp, cast(int)_sta_pending_gtk_idx, 0, + _sta_pending_group_rsc_len ? _sta_pending_group_rsc.ptr : null, _sta_pending_group_rsc_len, + _sta_pending_gtk.ptr, _sta_pending_gtk_len, + false); + return ret == 0; +} + +bool _sta_hook_auth_done(ushort reason) +{ + _sta_pending_auth = true; + _sta_pending_auth_reason = reason; + _sta_last_auth_reason = reason; + _sta_status_message = wpa_handshake_reason_message(reason); + return true; +} + +void sta_flush_pending_auth() +{ + if (!_sta_pending_auth) + return; + if (_sta_pending_auth_reason == 0) + { + if (!_sta_pending_keys) + return; + if (!sta_install_pending_pairwise() || !sta_install_pending_group()) + return; + } + _sta_pending_keys = false; + _sta_pending_auth = false; + ushort reason = _sta_pending_auth_reason; + bool ok = bl_wifi_auth_done_internal(_sta_sta_idx, reason); + if (ok && reason == 0) + { + if (_current_channel == 0) + _current_channel = _sta_candidate_channel != 0 ? _sta_candidate_channel : _configured_channel; + queue_event(WifiEvent.sta_connected, null); + } +} + +void ap_auth_tick() +{ + import urt.driver.bl618.timer : mtime_read; + ulong now = mtime_read(); + if (_ap_auth_last_msg3_len != 0 && _ap_auth_msg4_count == 0 && + _ap_auth_msg3_retx < 3 && now >= _ap_auth_msg3_next_retx_us) + { + wifi_hw_tx(0, WifiVif.ap, _ap_auth_last_msg3[0 .. _ap_auth_last_msg3_len]); + _ap_auth_msg3_retx++; + _ap_auth_msg3_next_retx_us = now + 500_000; + } +} + + +__gshared wpa_funcs _wpa_stub_table = wpa_funcs( + &_wpa_sta_init_real, &_wpa_sta_deinit_real, + &_wpa_sta_config_real, &_wpa_sta_connect_real, + &_wpa_sta_disconnected_cb_real, &_wpa_sta_rx_eapol_real, + &_wpa_ap_init, &_wpa_ap_deinit, &_wpa_ap_join, &_wpa_ap_sta_associated, + &_wpa_ap_remove, &_wpa_ap_rx_eapol, &_wpa_parse_wpa_ie, &_wpa_reg_diag_tlv_cb, + &_wpa3_build_sae_msg, &_wpa3_parse_sae_msg, &_wpa3_clear_sae); + + diff --git a/src/urt/driver/bl_common/alloc.d b/src/urt/driver/bl_common/alloc.d new file mode 100644 index 0000000..4b3957b --- /dev/null +++ b/src/urt/driver/bl_common/alloc.d @@ -0,0 +1,495 @@ +// ===================================================================== +// Bouffalo unified multi-pool allocator (TLSF-backed) +// +// Shared across BL618, BL808 D0, and BL808 M0. Per-chip pool topology +// is selected by version branches inside; the public API and CRT +// overrides are identical across chips. +// +// Pool topologies (target end state): +// BL618: OCRAM cached (256K, fast/slow) + OCRAM DMA (64K, non-cache) +// BL808 D0: SRAM (64K, fastest/fast/dma) + PSRAM (61M, slow) +// BL808 M0: DTCM (4K, fastest) + OCRAM (160K, fast/dma) +// + PSRAM (1M, slow) +// +// The whole file is gated by `version (BouffaloUnifiedAlloc)`. A chip +// opts in only when ALL prerequisites are in place: +// 1. Its linker script emits ___heap_start/end symbols for +// every pool in its topology. +// 2. Its Makefile compiles TLSF (tlsf.c + tlsf.h vendored). +// 3. Its per-chip pool topology block below is filled in. +// 4. urt.mem.alloc routes the chip's version branch to this module. +// 5. The chip's old urt.driver..alloc stub is deleted. +// +// CRT override notes (critical for any chip that opts in): +// +// This module overrides extern(C) malloc/free/calloc/realloc so picolibc +// dlmalloc never gets pulled in -- vendor C (libwifi.a etc.) and picolibc +// internals (printf %f, strdup) all route through TLSF. Picolibc strong- +// aliases the public malloc/free onto __malloc_malloc/__malloc_free and +// its internals call the prefixed names directly, so we override BOTH +// public and prefixed forms to keep malloc.c.o out of the link. +// +// The override IS the whole point of this module being a unified +// allocator -- but it also means any build that compiles this file +// with BouffaloUnifiedAlloc set MUST be ready to route every libc-side +// malloc call through TLSF. Half-migrated builds will corrupt their +// own allocator routing. Hence the explicit per-chip opt-in below. +// ===================================================================== +module urt.driver.bl_common.alloc; + + +// Per-chip activation. Every Bouffalo build with linker pool symbols +// and TLSF compiled is enabled here. +version (BL808_M0) version = BouffaloUnifiedAlloc; +version (BL808) version = BouffaloUnifiedAlloc; +version (BL618) version = BouffaloUnifiedAlloc; + +version (BouffaloUnifiedAlloc): + + +import urt.attribute : fast_data; +import urt.mem.alloc : MemFlags; + +@nogc nothrow: + + +enum has_realloc = true; +enum has_expand = false; +enum has_memsize = true; +enum has_exec = false; +enum has_retain = false; +enum has_memflags = true; + + +void[] _alloc(size_t size, size_t alignment, MemFlags flags) pure +{ + alias Fn = void[] function(size_t, size_t, MemFlags) pure nothrow @nogc; + return (cast(Fn) &alloc_impl)(size, alignment, flags); +} + +void[] _realloc(void[] mem, size_t new_size, size_t alignment, MemFlags flags) pure +{ + alias Fn = void[] function(void[], size_t, size_t, MemFlags) pure nothrow @nogc; + return (cast(Fn) &realloc_impl)(mem, new_size, alignment, flags); +} + +void _free(void* ptr) pure +{ + alias Fn = void function(void*) pure nothrow @nogc; + (cast(Fn) &free_impl)(ptr); +} + +size_t _memsize(void* ptr) pure +{ + return tlsf_block_size(ptr); +} + + +// CRT overrides -- see header. Both public and __malloc_-prefixed forms +// are defined so picolibc's malloc.c.o stays out of the link. +extern(C) void* malloc(size_t size) nothrow @nogc +{ + void[] m = alloc_impl(size, size_t.sizeof, MemFlags.none); + return m.ptr; +} + +extern(C) void free(void* ptr) nothrow @nogc +{ + free_impl(ptr); +} + +pragma(mangle, "__malloc_malloc") +extern(C) void* malloc_internal(size_t size) nothrow @nogc +{ + return malloc(size); +} + +pragma(mangle, "__malloc_free") +extern(C) void free_internal(void* ptr) nothrow @nogc +{ + free(ptr); +} + +extern(C) void* calloc(size_t nmemb, size_t size) nothrow @nogc +{ + size_t total = nmemb * size; + void[] m = alloc_impl(total, size_t.sizeof, MemFlags.none); + if (m.ptr !is null) + (cast(ubyte*) m.ptr)[0 .. total] = 0; + return m.ptr; +} + +extern(C) void* realloc(void* ptr, size_t size) nothrow @nogc +{ + if (ptr is null) + return malloc(size); + if (size == 0) + { + free_impl(ptr); + return null; + } + // realloc_impl only reads mem.ptr; the slice length is irrelevant. + void[] r = realloc_impl(ptr[0 .. 1], size, size_t.sizeof, MemFlags.none); + return r.ptr; +} + + +// Pool count per chip (exposed so urt.system can size its loop). +version (BL808_M0) enum size_t num_pools = 3; +else version (BL808) enum size_t num_pools = 2; +else version (BL618) enum size_t num_pools = 2; +else static assert(false, "bl_common.alloc: unsupported chip"); + + +// Per-pool runtime stats for sysinfo. `largest_free` walks the pool's +// free-list (O(blocks)) -- only call this from infrequent paths like the +// console sysinfo command, not from hot allocator code. +struct PoolStats +{ + immutable(char)* name; + size_t total; + size_t used; + size_t peak_used; + size_t largest_free; +} + +void query_pool_stats(size_t idx, out PoolStats stats) nothrow @nogc +{ + init_pools(); + auto p = &_pools[idx]; + stats.name = p.name; + stats.total = p.size; + stats.used = p.used; + stats.peak_used = p.peak_used; + + size_t largest = 0; + tlsf_walk_pool(tlsf_get_pool(p.tlsf), &walker_max_free, &largest); + stats.largest_free = largest; +} + +private extern(C) void walker_max_free(void* ptr, size_t size, int used, void* user) nothrow @nogc +{ + if (used) + return; + auto lf = cast(size_t*)user; + if (size > *lf) + *lf = size; +} + + +private: + + +// ===================================================================== +// Per-chip pool topology +// +// Each chip defines: +// - pool index enum (DtcmIdx, OcramIdx, ...) +// - num_pools +// - linker boundary symbol externs +// - pool_for(MemFlags) -> index of best-matching pool +// - map_pools() -- populate _pools[] base/size/name from linker symbols +// ===================================================================== + +version (BL808_M0) +{ + enum size_t DtcmIdx = 0; + enum size_t OcramIdx = 1; + enum size_t PsramIdx = 2; + + extern(C) extern __gshared + { + pragma(mangle, "__dtcm_heap_start") void* _dtcm_heap_start; + pragma(mangle, "__dtcm_heap_end") void* _dtcm_heap_end; + pragma(mangle, "__ocram_heap_start") void* _ocram_heap_start; + pragma(mangle, "__ocram_heap_end") void* _ocram_heap_end; + pragma(mangle, "__psram_heap_start") void* _psram_heap_start; + pragma(mangle, "__psram_heap_end") void* _psram_heap_end; + } + + size_t pool_for(MemFlags flags) nothrow @nogc + { + // DMA cannot reach DTCM (CPU-local bus) and PSRAM is not DMA-clean + // on E907 -- so dma requests are pinned to OCRAM with no fallback. + if (flags & MemFlags.dma) + return OcramIdx; + + final switch (cast(MemFlags)(flags & 3)) + { + case MemFlags.none: return PsramIdx; + case MemFlags.fast: return OcramIdx; + case MemFlags.slow: return PsramIdx; + case MemFlags.fastest: return DtcmIdx; + case MemFlags.dma: assert(false); + } + } + + void map_pools() nothrow @nogc + { + _pools[DtcmIdx].base = cast(void*)&_dtcm_heap_start; + _pools[DtcmIdx].size = cast(size_t)&_dtcm_heap_end - cast(size_t)&_dtcm_heap_start; + _pools[DtcmIdx].name = "TCM"; + _pools[OcramIdx].base = cast(void*)&_ocram_heap_start; + _pools[OcramIdx].size = cast(size_t)&_ocram_heap_end - cast(size_t)&_ocram_heap_start; + _pools[OcramIdx].name = "SRAM"; + _pools[PsramIdx].base = cast(void*)&_psram_heap_start; + _pools[PsramIdx].size = cast(size_t)&_psram_heap_end - cast(size_t)&_psram_heap_start; + _pools[PsramIdx].name = "PSRAM"; + } +} +else version (BL808) +{ + // BL808 D0 (C906) topology: + // SRAM (64K) fastest + fast + dma (only fast on-chip SRAM, no DTCM) + // PSRAM (60M) slow / default + enum size_t SramIdx = 0; + enum size_t PsramIdx = 1; + + extern(C) extern __gshared + { + pragma(mangle, "__sram_heap_start") void* _sram_heap_start; + pragma(mangle, "__sram_heap_end") void* _sram_heap_end; + pragma(mangle, "__psram_heap_start") void* _psram_heap_start; + pragma(mangle, "__psram_heap_end") void* _psram_heap_end; + } + + size_t pool_for(MemFlags flags) nothrow @nogc + { + // D0 has no DTCM; SRAM is the fastest available memory and is + // also DMA-reachable from the D0-side bus matrix. + if (flags & MemFlags.dma) + return SramIdx; + + final switch (cast(MemFlags)(flags & 3)) + { + case MemFlags.none: return PsramIdx; + case MemFlags.fast: return SramIdx; + case MemFlags.slow: return PsramIdx; + case MemFlags.fastest: return SramIdx; + case MemFlags.dma: assert(false); + } + } + + void map_pools() nothrow @nogc + { + _pools[SramIdx].base = cast(void*)&_sram_heap_start; + _pools[SramIdx].size = cast(size_t)&_sram_heap_end - cast(size_t)&_sram_heap_start; + _pools[SramIdx].name = "SRAM"; + _pools[PsramIdx].base = cast(void*)&_psram_heap_start; + _pools[PsramIdx].size = cast(size_t)&_psram_heap_end - cast(size_t)&_psram_heap_start; + _pools[PsramIdx].name = "PSRAM"; + } +} +else version (BL618) +{ + // BL618 topology (no TCM; WRAM reserved for WiFi; PSRAM needs init): + // OCRAM cached (256K) fast / fastest / slow + // OCRAM DMA (64K) non-cache alias, DMA buffers + enum size_t OcramIdx = 0; + enum size_t DmaIdx = 1; + + extern(C) extern __gshared + { + pragma(mangle, "__ocram_heap_start") void* _ocram_heap_start; + pragma(mangle, "__ocram_heap_end") void* _ocram_heap_end; + pragma(mangle, "__dma_heap_start") void* _dma_heap_start; + pragma(mangle, "__dma_heap_end") void* _dma_heap_end; + } + + size_t pool_for(MemFlags flags) nothrow @nogc + { + // DMA must come from the non-cache alias; everything else from cached + // OCRAM (PSRAM isn't a pool until bl_psram_init is wired). + if (flags & MemFlags.dma) + return DmaIdx; + + final switch (cast(MemFlags)(flags & 3)) + { + case MemFlags.none: return OcramIdx; + case MemFlags.fast: return OcramIdx; + case MemFlags.fastest: return OcramIdx; + case MemFlags.slow: return OcramIdx; + case MemFlags.dma: assert(false); + } + } + + void map_pools() nothrow @nogc + { + _pools[OcramIdx].base = cast(void*)&_ocram_heap_start; + _pools[OcramIdx].size = cast(size_t)&_ocram_heap_end - cast(size_t)&_ocram_heap_start; + _pools[OcramIdx].name = "SRAM"; + _pools[DmaIdx].base = cast(void*)&_dma_heap_start; + _pools[DmaIdx].size = cast(size_t)&_dma_heap_end - cast(size_t)&_dma_heap_start; + _pools[DmaIdx].name = "DMA"; + } +} +else +{ + static assert(false, "bl_common.alloc: unsupported chip"); +} + + +// ===================================================================== +// Shared TLSF interface + impl (chip-independent) +// ===================================================================== + +alias tlsf_t = void*; +alias pool_t = void*; +alias tlsf_walker = extern(C) void function(void* ptr, size_t size, int used, void* user) nothrow @nogc; + +extern(C) tlsf_t tlsf_create(void* mem) pure; +extern(C) pool_t tlsf_add_pool(tlsf_t tlsf, void* mem, size_t bytes) pure; +extern(C) pool_t tlsf_get_pool(tlsf_t tlsf) pure; +extern(C) size_t tlsf_size() pure; +extern(C) void* tlsf_malloc(tlsf_t tlsf, size_t bytes) pure; +extern(C) void* tlsf_memalign(tlsf_t tlsf, size_t alignment, size_t bytes) pure; +extern(C) void* tlsf_realloc(tlsf_t tlsf, void* ptr, size_t size) pure; +extern(C) void tlsf_free(tlsf_t tlsf, void* p) pure; +extern(C) size_t tlsf_block_size(void* p) pure; +extern(C) void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void* user) pure; + +struct Pool +{ + void* base; + size_t size; + tlsf_t tlsf; + size_t used; + size_t peak_used; + immutable(char)* name; +} + +// TLSF control_t for vendor config (FL_INDEX_MAX=30, SL_INDEX_COUNT_LOG2=5, +// rv32) sums to 3188 bytes; round to 3200. init_pools asserts the real +// tlsf_size() fits, so a vendor bump that grows control_t fails loudly. +enum TLSF_CONTROL_BYTES = 3200; + +@fast_data align(16) __gshared ubyte[TLSF_CONTROL_BYTES][num_pools] _control; +@fast_data __gshared Pool[num_pools] _pools; +@fast_data __gshared bool _initialized; + + +void[] alloc_impl(size_t size, size_t alignment, MemFlags flags) nothrow @nogc +{ + init_pools(); + + bool dma = (flags & MemFlags.dma) != 0; + size_t primary = pool_for(flags); + + void* p = tlsf_memalign(_pools[primary].tlsf, alignment, size); + size_t allocated_in = primary; + if (p is null && !dma) + { + foreach (i, ref f; _pools) + { + if (i == primary) + continue; + p = tlsf_memalign(f.tlsf, alignment, size); + if (p !is null) + { + allocated_in = i; + log_failover(size, alignment, flags); + break; + } + } + } + + if (p !is null) + { + size_t block = tlsf_block_size(p); + _pools[allocated_in].used += block; + if (_pools[allocated_in].used > _pools[allocated_in].peak_used) + _pools[allocated_in].peak_used = _pools[allocated_in].used; + } + else + log_oom(size, alignment, flags); + + return p ? p[0 .. size] : null; +} + +void[] realloc_impl(void[] mem, size_t new_size, size_t alignment, MemFlags flags) nothrow @nogc +{ + if (mem.ptr is null) + return alloc_impl(new_size, alignment, flags); + if (new_size == 0) + { + free_impl(mem.ptr); + return null; + } + Pool* owner = pool_of(mem.ptr); + if (owner is null) + return null; + size_t old_block = tlsf_block_size(mem.ptr); + void* p = tlsf_realloc(owner.tlsf, mem.ptr, new_size); + if (p is null) + return null; + size_t new_block = tlsf_block_size(p); + owner.used = owner.used - old_block + new_block; + if (owner.used > owner.peak_used) + owner.peak_used = owner.used; + return p[0 .. new_size]; +} + +void free_impl(void* ptr) nothrow @nogc +{ + Pool* owner = pool_of(ptr); + if (owner is null) + return; + owner.used -= tlsf_block_size(ptr); + tlsf_free(owner.tlsf, ptr); +} + +void init_pools() nothrow @nogc +{ + if (_initialized) + return; + + assert(tlsf_size() <= TLSF_CONTROL_BYTES, "TLSF control_t larger than reserved buffer"); + + map_pools(); + + foreach (i, ref p; _pools) + { + p.tlsf = tlsf_create(&_control[i][0]); + tlsf_add_pool(p.tlsf, p.base, p.size); + } + + _initialized = true; +} + +Pool* pool_of(void* ptr) nothrow @nogc +{ + auto pi = cast(size_t)ptr; + foreach (ref p; _pools) + { + auto bi = cast(size_t)p.base; + if (pi >= bi && pi < bi + p.size) + return &p; + } + return null; +} + +void log_oom(size_t size, size_t alignment, MemFlags flags) nothrow @nogc +{ + __gshared bool reentrant; + if (reentrant) + return; + reentrant = true; + scope(exit) reentrant = false; + + import urt.log; + log_error("heap.alloc", "OOM! - size=", size, " align=", alignment, + " flags=", cast(int)flags); +} + +void log_failover(size_t size, size_t alignment, MemFlags flags) nothrow @nogc +{ + __gshared bool reentrant; + if (reentrant) + return; + reentrant = true; + scope(exit) reentrant = false; + + import urt.log; + log_debug("heap.alloc", "preferred pool full, fail to fallback - size=", + size, " align=", alignment, " flags=", cast(int)flags); +} diff --git a/src/urt/driver/bl_common/exception.d b/src/urt/driver/bl_common/exception.d new file mode 100644 index 0000000..d270e1d --- /dev/null +++ b/src/urt/driver/bl_common/exception.d @@ -0,0 +1,122 @@ +/// Bouffalo RISC-V crash handler (shared across BL618, BL808 D0 and BL808 M0). +/// +/// Called from _trap_exception in start.S. Prints exception info, register +/// dump, and stack backtrace to UART0. Requires -frame-pointer=all for +/// reliable backtrace. +/// +/// Register width follows size_t: 32-bit on E907 (BL618 / BL808 M0), +/// 64-bit on C906 (BL808 D0). The uart0_* sink is selected by +/// urt.driver.uart's version dispatch. +module urt.driver.bl_common.exception; + +import urt.driver.baremetal.exception : walk_fp_chain; +import urt.driver.uart; + +@nogc nothrow: + +// Register the .eh_frame section with the libgcc unwinder so a D throw +// (assertion failure, fibre abort, etc.) can walk the stack. Called from +// sys_init before anything that might raise; without it, the first throw +// loops inside libgcc looking for an unwind table and pegs the CPU. +extern(C) void exception_init() +{ + __register_frame_info(&__eh_frame_start, &__eh_frame_object); +} + + +private: + +extern(C) void __register_frame_info(const void*, void*); +extern(C) extern const ubyte __eh_frame_start; +__gshared ubyte[48] __eh_frame_object; // libgcc unwinder state -- opaque + +immutable const(char)*[16] exception_names = [ + "Instruction address misaligned", + "Instruction access fault", + "Illegal instruction", + "Breakpoint", + "Load address misaligned", + "Load access fault", + "Store address misaligned", + "Store access fault", + "Environment call from U-mode", + "Environment call from S-mode", + "Reserved", + "Environment call from M-mode", + "Instruction page fault", + "Load page fault", + "Reserved", + "Store page fault", +]; + +immutable const(char)*[31] rnames = [ + "ra ", "sp ", "gp ", "tp ", + "t0 ", "t1 ", "t2 ", + "s0 ", "s1 ", + "a0 ", "a1 ", "a2 ", "a3 ", + "a4 ", "a5 ", "a6 ", "a7 ", + "s2 ", "s3 ", "s4 ", "s5 ", + "s6 ", "s7 ", "s8 ", "s9 ", + "s10", "s11", + "t3 ", "t4 ", "t5 ", "t6 ", +]; + +public: + +/// regs[] layout matches the save order in _trap_exception (start.S): +/// [0]=ra [1]=sp [2]=gp [3]=tp [4]=t0..[6]=t2 +/// [7]=s0/fp [8]=s1 [9]=a0..[16]=a7 +/// [17]=s2..[26]=s11 [27]=t3..[30]=t6 +extern(C) void _crash_handler(size_t* regs, size_t mcause, size_t mepc, size_t mtval) @nogc nothrow +{ + uart0_print("\n\n*** CRASH ***\nException: "); + + size_t cause = mcause & (size_t.max >> 1); + if (cause < 16) + uart0_print(exception_names[cause]); + else + uart0_print("Unknown exception"); + + uart0_print(" (cause="); + uart0_hex(mcause); + uart0_print(")\n mepc = "); + uart0_hex(mepc); + uart0_print("\n mtval = "); + uart0_hex(mtval); + uart0_print("\n\nRegisters:\n"); + + foreach (i; 0 .. 31) + { + uart0_print(" "); + uart0_print(rnames[i]); + uart0_print(" = "); + uart0_hex(regs[i]); + if ((i % 4) == 3 || i == 30) + uart0_putc('\n'); + } + + uart0_print("\nBacktrace:\n [0] "); + uart0_hex(mepc); + uart0_print(" (faulting PC)\n"); + + void*[32] addrs = void; + const n = walk_fp_chain(regs[7], addrs[]); // s0 = frame pointer + + foreach (depth, addr; addrs[0 .. n]) + { + uart0_print(" ["); + const d = depth + 1; + if (d < 10) + uart0_putc(cast(char)('0' + d)); + else + { + uart0_putc(cast(char)('0' + d / 10)); + uart0_putc(cast(char)('0' + d % 10)); + } + uart0_print("] "); + uart0_hex(cast(size_t) addr); + uart0_putc('\n'); + } + + uart0_print("\n*** HALTED ***\n"); +} diff --git a/src/urt/driver/bl_common/gpio.d b/src/urt/driver/bl_common/gpio.d new file mode 100644 index 0000000..ceafb1c --- /dev/null +++ b/src/urt/driver/bl_common/gpio.d @@ -0,0 +1,123 @@ +// Bouffalo GPIO controller (BL618, BL808 D0, BL808 M0). +// +// Same register layout across all three; only the pin count differs. +// +// GPIO_CFG register at GLB_BASE + 0x8C4 + pin*4: +// bits[4:0] = function (11 = SWGPIO) +// bit[6] = input enable +// bit[11] = output enable +// bit[17] = output value +// bit[18] = input value (read-only) +// bit[24] = pull-up enable +// bit[25] = pull-down enable +module urt.driver.bl_common.gpio; + +import core.volatile : volatileLoad, volatileStore; + +import urt.driver.gpio : Pull, DriveMode; + +@nogc nothrow: + + +version (BL808_M0) enum uint num_gpio = 35; // shares the BL618 peripheral set +else version (BL618) enum uint num_gpio = 35; +else version (BL808) enum uint num_gpio = 47; // D0 sees all 47 pads +else static assert(false, "bl_common/gpio.d included on a non-Bouffalo target"); + +enum bool has_pull_up = true; +enum bool has_pull_down = true; +enum bool has_open_drain = false; +enum bool has_pin_function_muxing = true; + + +uint gpio_count() => num_gpio; + + +void gpio_output_init(uint pin, bool initial = false, DriveMode mode = DriveMode.push_pull) +{ + assert(pin < num_gpio, "bouffalo gpio: pin out of range"); + assert(mode == DriveMode.push_pull, "bouffalo gpio: open-drain not supported"); + uint cfg = GPIO_FUN_SWGPIO | GPIO_OUTPUT_EN; + if (initial) + cfg |= GPIO_OUTPUT_HIGH; + gpio_cfg_write(pin, cfg); +} + +void gpio_input_init(uint pin, Pull pull = Pull.none) +{ + assert(pin < num_gpio, "bouffalo gpio: pin out of range"); + gpio_cfg_write(pin, GPIO_FUN_SWGPIO | GPIO_INPUT_EN | (uint(pull) << 24)); +} + +void gpio_output_set(uint pin, bool value) +{ + assert(pin < num_gpio, "bouffalo gpio: pin out of range"); + uint cfg = gpio_cfg_read(pin) & ~GPIO_OUTPUT_HIGH; + if (value) + cfg |= GPIO_OUTPUT_HIGH; + gpio_cfg_write(pin, cfg); +} + +void gpio_output_toggle(uint pin) +{ + assert(pin < num_gpio, "bouffalo gpio: pin out of range"); + gpio_cfg_write(pin, gpio_cfg_read(pin) ^ GPIO_OUTPUT_HIGH); +} + +bool gpio_input_read(uint pin) +{ + assert(pin < num_gpio, "bouffalo gpio: pin out of range"); + return (gpio_cfg_read(pin) & GPIO_INPUT_VALUE) != 0; +} + +void gpio_set_pull(uint pin, Pull pull) +{ + assert(pin < num_gpio, "bouffalo gpio: pin out of range"); + uint cfg = gpio_cfg_read(pin) & ~(GPIO_PULL_UP | GPIO_PULL_DOWN); + gpio_cfg_write(pin, cfg | (uint(pull) << 24)); +} + +void gpio_release(uint pin) +{ + assert(pin < num_gpio, "bouffalo gpio: pin out of range"); + gpio_cfg_write(pin, GPIO_FUN_SWGPIO); +} + +void gpio_set_function(uint pin, uint function_id, Pull pull = Pull.none, DriveMode mode = DriveMode.push_pull) +{ + assert(pin < num_gpio, "bouffalo gpio: pin out of range"); + assert(function_id <= GPIO_FUN_MASK, "bouffalo gpio: function_id out of range (5-bit field)"); + assert(mode == DriveMode.push_pull, "bouffalo gpio: open-drain not supported"); + uint cfg = (function_id & GPIO_FUN_MASK) | GPIO_INPUT_EN | (uint(pull) << 24); + gpio_cfg_write(pin, cfg); +} + + +private: + +enum uint GLB_BASE = 0x2000_0000; +enum uint GPIO_CFG_BASE = GLB_BASE + 0x8C4; + +enum uint GPIO_FUN_SWGPIO = 11; +enum uint GPIO_FUN_MASK = 0x1Fu; +enum uint GPIO_INPUT_EN = 1u << 6; +enum uint GPIO_OUTPUT_EN = 1u << 11; +enum uint GPIO_OUTPUT_HIGH = 1u << 17; +enum uint GPIO_INPUT_VALUE = 1u << 18; +enum uint GPIO_PULL_UP = 1u << 24; +enum uint GPIO_PULL_DOWN = 1u << 25; + +// Pull values map directly to GPIO_CFG bits[25:24]: none=0, up=bit24, down=bit25. +static assert(Pull.none == 0 && Pull.up == 1 && Pull.down == 2); + +pragma(inline, true) +uint gpio_cfg_read(uint pin) +{ + return volatileLoad(cast(uint*)(GPIO_CFG_BASE + pin * 4)); +} + +pragma(inline, true) +void gpio_cfg_write(uint pin, uint value) +{ + volatileStore(cast(uint*)(GPIO_CFG_BASE + pin * 4), value); +} diff --git a/src/urt/driver/bl_common/hbn.d b/src/urt/driver/bl_common/hbn.d new file mode 100644 index 0000000..e686705 --- /dev/null +++ b/src/urt/driver/bl_common/hbn.d @@ -0,0 +1,41 @@ +// HBN (Hibernate) RAM persistence -- 4KB at 0x20010000, survives deep sleep +// if VBAT is maintained. Shared across all Bouffalo variants that expose the +// AON/HBN domain (BL618, BL808 D0, BL808 M0). On BL808 both cores reference +// the same struct at the start of .hbn_ram, so whichever core boots first +// can restore wall-clock state seeded by the other. +// +// Storage strategy: +// D0 build: storage defined in C (hbn_ram.c) and compiled into BAREMETAL +// alongside start.S. This file declares the symbol extern. +// M0 build: storage defined here in D via @persist, since the M0 +// BAREMETAL_SRCS does not include hbn_ram.c. The struct layout +// must match D0's C definition exactly. +module urt.driver.bl_common.hbn; + +import urt.attribute : persist, used; + +@nogc nothrow: + + +/// Persistent state across hibernate cycles. Layout must stay byte-identical +/// to `struct hbn_persist` in third_party/urt/src/urt/driver/bl808/hbn_ram.c. +struct HbnPersist +{ + enum uint HBN_MAGIC = 0x4F57_4254; // "OWBT" (OpenWatt Boot Time) + + uint magic; + long utc_offset; // HBN ticks from RTC epoch to Unix epoch +} + +/// Access the persistent state in HBN RAM. +HbnPersist* hbn_persist() => &_hbn_persist; + + +private: + +// @used pins the storage so --gc-sections keeps it even before any M0 +// consumer exists, mirroring D0's hbn_ram.c which uses __attribute__((used)). +version (BL808_M0) + extern(C) @persist @used __gshared HbnPersist _hbn_persist; +else + extern(C) extern __gshared HbnPersist _hbn_persist; diff --git a/src/urt/driver/bl_common/system.d b/src/urt/driver/bl_common/system.d new file mode 100644 index 0000000..dd87c6a --- /dev/null +++ b/src/urt/driver/bl_common/system.d @@ -0,0 +1,132 @@ +// Bouffalo sys_init -- single canonical bring-up called from start.S after +// section init. Owns the order in which subsystems come up: exception +// unwinder, IRQ controller, TRNG, chip-specific extras, then global IRQ +// enable, then the platform tick. +// +// Driver bring-up bodies live in their owning modules (exception_init, +// irq_init, trng_init, ...) -- this file only sequences them. +module urt.driver.bl_common.system; + +import urt.driver.uart; +import urt.driver.irq : irq_init, irq_global_enable; +import urt.driver.timer; +import urt.driver.bl_common.exception : exception_init; +import urt.driver.bl_common.trng; + +@nogc nothrow: + + +version (BL808_M0) private enum string chip_name = "BL808 M0"; +else version (BL808) private enum string chip_name = "BL808 D0"; +else version (BL618) private enum string chip_name = "BL618"; +else static assert(false, "bl_common/system.d included on a non-Bouffalo target"); + + +extern(C) void sys_init() +{ + exception_init(); + + uart0_hw_puts(chip_name ~ ": sys_init\n"); + + irq_init(); + + // SEC_ENG hardware RNG. trng_init is idempotent and lazily retried on + // first read, so a failure here only loses the eager bring-up -- mbedtls + // entropy poll still works as long as the block is reachable. + if (!trng_init()) + uart0_hw_puts(chip_name ~ ": TRNG init failed\n"); + + chip_post_init(); + + // mstatus.MIE on now that every controller is in a known state and + // every default handler is wired (or null-and-silent). After this + // point any irq_line_enable will actually deliver. + irq_global_enable(); + + timer_set_periodic(50_000, &tick_stub); + + uart0_hw_puts(chip_name ~ ": ready\n"); +} + + +version (BL808_M0) +{ + extern(C) __gshared uint __irq_sample_mepc; + extern(C) __gshared uint __irq_sample_mcause; + extern(C) __gshared uint __irq_sample_sp; + + extern(C) void ow_hang_watchdog_feed() + { + _wd_last_feed_us = mtime_read(); + ++_wd_feed_count; + } +} + + +private: + +void tick_stub() @nogc nothrow +{ + version (BL808_M0) + hang_watchdog_tick(); +} + +version (BL808_M0) +{ + __gshared ulong _wd_last_feed_us; + __gshared ulong _wd_next_report_us; + __gshared uint _wd_feed_count; + __gshared uint _wd_report_count; + + void hang_watchdog_tick() + { + ulong now = mtime_read(); + if (_wd_last_feed_us == 0) + { + _wd_last_feed_us = now; + _wd_next_report_us = now + 1_500_000; + return; + } + + if (now - _wd_last_feed_us < 1_500_000) + return; + if (now < _wd_next_report_us) + return; + + _wd_next_report_us = now + 1_000_000; + ++_wd_report_count; + + uart0_print("\n[wd hung feed="); + uart0_hex(_wd_feed_count); + uart0_print(" rpt="); + uart0_hex(_wd_report_count); + uart0_print(" mepc="); + uart0_hex(__irq_sample_mepc); + uart0_print(" mcause="); + uart0_hex(__irq_sample_mcause); + uart0_print(" sp="); + uart0_hex(__irq_sample_sp); + uart0_print("]\n"); + } +} + +// Chip-specific bring-up that doesn't belong in the shared sequence. +// Order matters: BL808_M0 must precede BL808 because the M0 build sets both +// flags, and BL808 D0 wants XRAM-IPC rings that M0 hasn't grown yet. +void chip_post_init() +{ + version (BL808_M0) + { + // UART already up via m0_bringup before sys_init. Nothing else yet. + } + else version (BL808) + { + // XRAM ring buffers for IPC with M0. + import urt.driver.bl808.ipc : ipc_init; + ipc_init(); + } + else version (BL618) + { + // Nothing chip-specific yet. + } +} diff --git a/src/urt/driver/bl_common/trng.d b/src/urt/driver/bl_common/trng.d new file mode 100644 index 0000000..3f738b4 --- /dev/null +++ b/src/urt/driver/bl_common/trng.d @@ -0,0 +1,149 @@ +// Bouffalo hardware TRNG driver (SEC_ENG block), shared across BL618 and BL808. +// +// Vendor reference: bl808_sec_eng.c Sec_Eng_Trng_{Enable,Read}. We don't +// pull in the whole sec_eng TU just for the TRNG -- the register layout is +// stable across the BL family and this is the only peripheral inside +// SEC_ENG we currently consume. +// +// SEC_ENG_BASE = 0x2000_4000 +// CTRL_0 @ +0x200 bits: 0=BUSY (r), 1=TRIG_1T (wo), 2=EN, 3=DOUT_CLR_1T (wo), +// 4=HT_ERROR (r), 9=INT_CLR_1T (wo) +// DOUT_0..7 @ +0x208..+0x224 32 bytes of output per Read +// +// On BL808 D0 the SEC_ENG path depends on M0 having opened a TZC window. If +// BUSY never clears on D0 the path isn't open and this needs to become an +// IPC RPC to M0's TRNG. +module urt.driver.bl_common.trng; + +import core.volatile; + +@nogc nothrow: + + +private enum uint SEC_ENG_BASE = 0x2000_4000; +private enum uint TRNG_CTRL_0 = SEC_ENG_BASE + 0x200; +private enum uint TRNG_DOUT_0 = SEC_ENG_BASE + 0x208; + +private enum uint BIT_BUSY = 1U << 0; +private enum uint BIT_TRIG = 1U << 1; +private enum uint BIT_EN = 1U << 2; +private enum uint BIT_DOUT_CLR = 1U << 3; +private enum uint BIT_INT_CLR = 1U << 9; +// Must stay set in polled mode -- TRNG raises SEC_TRNG_IRQn (#28) on every +// completion otherwise. Found by ecdh hang: with MIE on and this bit clear, +// the peripheral asserts its IRQ at the CLIC, IP latches on a line with +// IE=0 + null handler, and BUSY stops clearing on subsequent triggers. +// Matches vendor's Sec_Eng_Trng_Int_Disable in bl808_sec_eng.c. +private enum uint BIT_INT_MASK = 1U << 11; + +// Loose timeout for the BUSY wait: TRNG produces 32 bytes in tens of +// microseconds at the default reseed interval; this caps a real hang. +private enum uint BUSY_TIMEOUT = 100_000; + +private __gshared bool _enabled = false; + + +bool trng_init() +{ + if (_enabled) + return true; + + uint v = mmio_load(TRNG_CTRL_0); + v |= BIT_EN | BIT_INT_MASK; + mmio_store(TRNG_CTRL_0, v); + v |= BIT_INT_CLR; + mmio_store(TRNG_CTRL_0, v); + + if (!wait_not_busy()) + return false; + + v = mmio_load(TRNG_CTRL_0) | BIT_INT_CLR; + mmio_store(TRNG_CTRL_0, v); + + _enabled = true; + return true; +} + +// Read one 32-byte block. Returns false on timeout. Caller must have run +// trng_init() first -- sys_init does this for every Bouffalo build. +bool trng_read_block(ubyte[32] dst) +{ + uint v = mmio_load(TRNG_CTRL_0) | BIT_TRIG; + mmio_store(TRNG_CTRL_0, v); + + if (!wait_not_busy()) + return false; + + // Mirror vendor IRQ handler: clear INT after each completion so the + // peripheral's pending-IRQ state stays clean across back-to-back reads. + mmio_store(TRNG_CTRL_0, mmio_load(TRNG_CTRL_0) | BIT_INT_CLR); + + foreach (i; 0 .. 8) + { + const uint word = mmio_load(TRNG_DOUT_0 + i * 4); + const size_t off = i * 4; + dst[off + 0] = cast(ubyte)(word); + dst[off + 1] = cast(ubyte)(word >> 8); + dst[off + 2] = cast(ubyte)(word >> 16); + dst[off + 3] = cast(ubyte)(word >> 24); + } + + // Clear TRIG, then pulse DOUT_CLR so the next trigger starts fresh. + v = mmio_load(TRNG_CTRL_0) & ~BIT_TRIG; + mmio_store(TRNG_CTRL_0, v); + mmio_store(TRNG_CTRL_0, v | BIT_DOUT_CLR); + mmio_store(TRNG_CTRL_0, v); + + return true; +} + +// Fill an arbitrary-length buffer. +bool trng_read(ubyte[] dst) +{ + while (dst.length > 0) + { + ubyte[32] block = void; + if (!trng_read_block(block)) + return false; + + const size_t n = dst.length < 32 ? dst.length : 32; + dst[0 .. n] = block[0 .. n]; + dst = dst[n .. $]; + } + return true; +} + +// mbedtls entropy poll callback. urt/internal/mbedtls.c registers this as +// an MBEDTLS_ENTROPY_SOURCE_STRONG source when MBEDTLS_NO_PLATFORM_ENTROPY +// is defined (i.e. on every embedded config we ship). Through that, all +// crypto_random_bytes calls eventually pull from this TRNG. +extern(C) int urt_platform_entropy_poll(void* data, ubyte* output, size_t len, size_t* olen) +{ + if (!trng_read(output[0 .. len])) + { + *olen = 0; + return -1; + } + *olen = len; + return 0; +} + + +private: + +pragma(inline, true) uint mmio_load(uint addr) + => volatileLoad(cast(uint*)cast(size_t)addr); + +pragma(inline, true) void mmio_store(uint addr, uint val) + => volatileStore(cast(uint*)cast(size_t)addr, val); + +bool wait_not_busy() +{ + uint count = BUSY_TIMEOUT; + while ((mmio_load(TRNG_CTRL_0) & BIT_BUSY) != 0) + { + if (--count == 0) + return false; + } + return true; +} diff --git a/src/urt/driver/ble.d b/src/urt/driver/ble.d new file mode 100644 index 0000000..b78f570 --- /dev/null +++ b/src/urt/driver/ble.d @@ -0,0 +1,547 @@ +module urt.driver.ble; + +import urt.result : Result, InternalResult; +import urt.uuid : GUID; + +version (Windows) + public import urt.driver.windows.ble; +else version (Espressif) + public import urt.driver.esp32.ble; +else + enum uint num_ble = 0; + +nothrow @nogc: + + +// ==================================================================== +// Types +// ==================================================================== + +enum BLEError : ubyte +{ + none, + not_found, // device not found / unreachable + auth_failed, // pairing or encryption failure + timeout, // operation timed out + protocol, // ATT/GATT protocol error + access_denied, // insufficient permissions + internal, // platform-specific internal error +} + +enum BLERole : ubyte +{ + central, // scan + connect to peripherals + peripheral, // advertise + accept connections + observer, // scan only (no connections) + broadcaster, // advertise only (no connections) +} + +enum BLEAdvType : ubyte +{ + connectable, // ADV_IND: connectable, scannable, undirected + connectable_direct, // ADV_DIRECT_IND: connectable, directed + scannable, // ADV_SCAN_IND: scannable, not connectable + nonconnectable, // ADV_NONCONN_IND: not connectable, not scannable +} + +enum BLEAddrType : ubyte +{ + public_ = 0x00, + random_static = 0x01, + rpa_public = 0x02, // resolvable private, public identity + rpa_random = 0x03, // resolvable private, random identity +} + +enum BLEPhy : ubyte +{ + phy_1m = 0x01, // mandatory, 1 Mbit/s + phy_2m = 0x02, // optional, 2 Mbit/s + phy_coded = 0x03, // long range +} + +enum GattCharProps : ushort +{ + none = 0x0000, + broadcast = 0x0001, + read = 0x0002, + write_without_response = 0x0004, + write = 0x0008, + notify = 0x0010, + indicate = 0x0020, + authenticated_writes = 0x0040, + extended_properties = 0x0080, + reliable_write = 0x0100, +} + + +// --- Configuration structs --- + +struct BLEConfig +{ + byte tx_power; // dBm (0 = platform default) + BLEPhy preferred_phy; // preferred PHY (0 = platform default) +} + +struct BLEScanConfig +{ + bool active = true; // active scan (send SCAN_REQ for extra data) + ushort interval_ms = 100; // scan interval + ushort window_ms = 50; // scan window, <= interval + bool filter_duplicates; // suppress repeated advertisements +} + +struct BLEAdvConfig +{ + BLEAdvType adv_type; + ushort interval_ms = 100; // advertising interval + byte tx_power; // dBm (0 = default) + const(ubyte)[] adv_data; // raw AD structures (max 31 bytes) + const(ubyte)[] scan_rsp; // scan response data (max 31 bytes) +} + +struct BLEConnConfig +{ + ushort interval_min_ms = 7; // connection interval range + ushort interval_max_ms = 30; + ushort latency; // slave latency (number of skippable events) + ushort timeout_ms = 5000; // supervision timeout +} + +// Discovered advertisement report from scanning. +struct BLEAdvReport +{ + ubyte[6] addr; + BLEAddrType addr_type; + BLEAdvType adv_type; + byte rssi; // dBm (-128 = unknown) + byte tx_power; // dBm (-128 = not present) + ubyte data_len; + ubyte[62] data_buf; // adv_data + scan_rsp combined (max 31+31) + + const(ubyte)[] data() const pure nothrow @nogc + => data_buf[0 .. data_len]; +} + +// A discovered GATT characteristic on a connected device. +struct BLEGattChar +{ + ushort handle; // ATT handle for read/write + ushort cccd_handle; // Client Characteristic Config descriptor (0 = none) + GUID service_uuid; // owning service UUID + GUID char_uuid; // characteristic UUID + GattCharProps properties; +} + + +// --- Handles --- + +struct BLE +{ + ubyte port = ubyte.max; +} + +bool is_open(ref const BLE ble) +{ + return ble.port != ubyte.max; +} + +// Opaque connection handle. Lifetime: from connect callback (success) +// until disconnect callback fires. Do not use after disconnect. +struct BLEConn +{ + ubyte id = ubyte.max; +} + +bool is_valid(ref const BLEConn conn) +{ + return conn.id != ubyte.max; +} + +// Opaque advertising handle. Returned by ble_adv_start, used to stop +// a specific advertisement. Invalid after ble_adv_stop. +struct BLEAdv +{ + ubyte id = ubyte.max; +} + +bool is_valid(ref const BLEAdv adv) +{ + return adv.id != ubyte.max; +} + + +// --- Callbacks --- + +// Scan result received. Called once per advertisement/scan response. +// The report is only valid for the duration of the callback. +alias BLEScanCallback = void function(BLE ble, ref const BLEAdvReport report) nothrow @nogc; + +// Connection state change. On success: conn is valid, error is .none. +// On failure or disconnect: conn becomes invalid after callback returns. +alias BLEConnCallback = void function(BLE ble, BLEConn conn, bool connected, BLEError error) nothrow @nogc; + +// GATT service discovery complete. chars is only valid during callback. +// On error: chars.length == 0 and error != .none. +alias BLEDiscoverCallback = void function(BLE ble, BLEConn conn, const(BLEGattChar)[] chars, BLEError error) nothrow @nogc; + +// GATT read complete. data is only valid during callback. +alias BLEReadCallback = void function(BLE ble, BLEConn conn, ushort handle, const(ubyte)[] data, BLEError error) nothrow @nogc; + +// GATT write complete. +alias BLEWriteCallback = void function(BLE ble, BLEConn conn, ushort handle, BLEError error) nothrow @nogc; + +// Notification or indication received from a connected peripheral. +// data is only valid during callback. +alias BLENotifyCallback = void function(BLE ble, BLEConn conn, ushort handle, const(ubyte)[] data) nothrow @nogc; + +alias BLEWakeCallback = void function() nothrow @nogc; + + +// ==================================================================== +// Error type +// ==================================================================== + +BLEError ble_result(Result result) +{ + return cast(BLEError)result.system_code; +} + + +// ==================================================================== +// Implementation +// ==================================================================== + +// --- Lifecycle --- + +void ble_init() +{ + if (_init_refcount++ == 0) + { + // TODO: enable clocks/power for BLE peripheral block + } +} + +void ble_deinit() +{ + assert(_init_refcount > 0); + if (--_init_refcount == 0) + { + // TODO: disable clocks/power for BLE peripheral block + } +} + +Result ble_open(ref BLE ble, ubyte port, ref const BLEConfig cfg) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + { + if (port >= num_ble) + return InternalResult.invalid_parameter; + + if (!ble_hw_open(port, cfg)) + return InternalResult.failed; + + ble.port = port; + return Result.success; + } +} + +void ble_close(ref BLE ble) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + ble_hw_close(ble.port); + ble.port = ubyte.max; +} + +// --- Scanning (central/observer role) --- + +// Start scanning for advertisements. Reports are delivered via the +// scan callback set with ble_set_scan_callback(). Scanning continues +// until ble_scan_stop() is called or the radio is closed. +Result ble_scan_start(ref BLE ble, ref const BLEScanConfig cfg) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + { + if (!ble_hw_scan_start(ble.port, cfg)) + return InternalResult.failed; + return Result.success; + } +} + +void ble_scan_stop(ref BLE ble) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + ble_hw_scan_stop(ble.port); +} + +// --- Advertising (peripheral/broadcaster role) --- + +// Start advertising. Returns an opaque handle on success that can be +// passed to ble_adv_stop. Multiple advertisements may be active +// concurrently (platform permitting). For connectable advertisements, +// incoming connections are delivered via the connection callback. +BLEAdv ble_adv_start(ref BLE ble, ref const BLEAdvConfig cfg) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + return ble_hw_adv_start(ble.port, cfg); +} + +// Stop a specific advertisement. Pass the handle returned by +// ble_adv_start. The handle is invalid after this call. +void ble_adv_stop(ref BLE ble, BLEAdv adv) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + ble_hw_adv_stop(ble.port, adv); +} + +// --- Connection (central role) --- + +// Initiate a connection to a peripheral. Completion (success or failure) +// is delivered via the connection callback. Only one connect may be +// pending at a time per radio. +Result ble_connect(ref BLE ble, ref const ubyte[6] peer_addr, BLEAddrType addr_type, ref const BLEConnConfig cfg) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + { + if (!ble_hw_connect(ble.port, peer_addr, addr_type, cfg)) + return InternalResult.failed; + return Result.success; + } +} + +// Cancel a pending connection attempt. +void ble_connect_cancel(ref BLE ble) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + ble_hw_connect_cancel(ble.port); +} + +// Disconnect an established connection. The disconnect callback fires +// when teardown is complete. +Result ble_disconnect(ref BLE ble, BLEConn conn) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + { + if (!ble_hw_disconnect(ble.port, conn)) + return InternalResult.failed; + return Result.success; + } +} + +// --- GATT discovery --- + +// Discover all services and characteristics on a connected device. +// Results are delivered via the discover callback. Only one discovery +// may be active per connection at a time. +Result ble_gatt_discover(ref BLE ble, BLEConn conn) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + { + if (!ble_hw_gatt_discover(ble.port, conn)) + return InternalResult.failed; + return Result.success; + } +} + +// --- GATT read/write --- + +// Read a characteristic value by handle. Result is delivered via the +// read callback. Multiple reads may be in flight concurrently (up to +// a platform-defined limit). +Result ble_gatt_read(ref BLE ble, BLEConn conn, ushort handle) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + { + if (!ble_hw_gatt_read(ble.port, conn, handle)) + return InternalResult.failed; + return Result.success; + } +} + +// Write a characteristic value. If with_response is true, the write +// callback fires on completion; otherwise the write is fire-and-forget +// (Write Without Response / Write Command). +Result ble_gatt_write(ref BLE ble, BLEConn conn, ushort handle, const(ubyte)[] data, bool with_response = true) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + { + if (!ble_hw_gatt_write(ble.port, conn, handle, data, with_response)) + return InternalResult.failed; + return Result.success; + } +} + +// --- Notifications / Indications --- + +// Enable or disable notifications/indications on a characteristic. +// Writes the CCCD descriptor on the remote device. Incoming notifications +// are delivered via the notify callback. +Result ble_gatt_subscribe(ref BLE ble, BLEConn conn, ushort handle, bool enable) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + { + if (!ble_hw_gatt_subscribe(ble.port, conn, handle, enable)) + return InternalResult.failed; + return Result.success; + } +} + +// --- Queries --- + +Result ble_get_mac(ref BLE ble, ref ubyte[6] mac) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + { + if (!ble_hw_get_mac(ble.port, mac)) + return InternalResult.failed; + return Result.success; + } +} + +byte ble_get_rssi(ref BLE ble, BLEConn conn) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + return ble_hw_get_rssi(ble.port, conn); +} + +// --- Callbacks --- + +void ble_set_scan_callback(ref BLE ble, BLEScanCallback cb) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + ble_hw_set_scan_callback(ble.port, cb); +} + +void ble_set_conn_callback(ref BLE ble, BLEConnCallback cb) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + ble_hw_set_conn_callback(ble.port, cb); +} + +void ble_set_discover_callback(ref BLE ble, BLEDiscoverCallback cb) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + ble_hw_set_discover_callback(ble.port, cb); +} + +void ble_set_read_callback(ref BLE ble, BLEReadCallback cb) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + ble_hw_set_read_callback(ble.port, cb); +} + +void ble_set_write_callback(ref BLE ble, BLEWriteCallback cb) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + ble_hw_set_write_callback(ble.port, cb); +} + +void ble_set_notify_callback(ref BLE ble, BLENotifyCallback cb) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + ble_hw_set_notify_callback(ble.port, cb); +} + +void ble_set_wake_callback(ref BLE ble, BLEWakeCallback cb) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + ble_hw_set_wake_callback(ble.port, cb); +} + +// --- Poll --- + +// Drive completions for platforms that don't deliver events natively. +// Must be called periodically from the main loop. +void ble_poll(ref BLE ble) +{ + static if (num_ble == 0) + assert(false, "no BLE on this platform"); + else + ble_hw_poll(ble.port); +} + + +// ==================================================================== +// Tests +// ==================================================================== + +unittest +{ + static if (num_ble > 0) + { + BLE b; + BLEConfig cfg; + + ble_init(); + + // Out-of-range port + auto r = ble_open(b, cast(ubyte)num_ble, cfg); + assert(!r); + assert(!b.is_open); + + // Open/close each valid port + foreach (p; 0 .. num_ble) + { + BLE port; + auto r2 = ble_open(port, cast(ubyte)p, cfg); + assert(r2, "ble_open failed"); + assert(port.is_open); + assert(port.port == p); + + ble_poll(port); + + ble_close(port); + assert(!port.is_open); + } + + ble_deinit(); + } +} + + +private: + +__gshared ubyte _init_refcount; diff --git a/src/urt/driver/can.d b/src/urt/driver/can.d new file mode 100644 index 0000000..b03ce07 --- /dev/null +++ b/src/urt/driver/can.d @@ -0,0 +1,376 @@ +module urt.driver.can; + +import urt.result : Result, InternalResult; + +version (Espressif) + public import urt.driver.esp32.can; +else +{ + enum uint num_can = 0; + enum bool has_can_fd = false; +} + +nothrow @nogc: + + +enum CanError : ubyte +{ + none = 0, + bit = 1 << 0, // bit error (dominant/recessive mismatch) + stuff = 1 << 1, // bit stuffing violation + crc = 1 << 2, // CRC mismatch + form = 1 << 3, // fixed-form bit field violation + ack = 1 << 4, // no ACK from any receiver + overrun = 1 << 5, // RX FIFO overflow +} + +enum CanBusState : ubyte +{ + error_active, // TEC/REC < 128, normal operation + error_warning, // TEC or REC >= 96 + error_passive, // TEC or REC >= 128, can't send active error frames + bus_off, // TEC >= 256, node disconnected from bus +} + +struct CanConfig +{ + uint bitrate = 500_000; // nominal bitrate (bits/s) + uint data_bitrate; // FD data phase bitrate (0 = classic CAN only) + ubyte tx_gpio = ubyte.max; // GPIO pin for TX (max = platform default) + ubyte rx_gpio = ubyte.max; // GPIO pin for RX (max = platform default) + + // Bit timing (0 = auto-calculate from bitrate) + ubyte sjw; // synchronization jump width (1-4 TQ) + ubyte tseg1; // time segment 1 / prop + phase1 (1-16 TQ) + ubyte tseg2; // time segment 2 / phase2 (1-8 TQ) + ushort brp; // baud rate prescaler (1-1024) +} + +struct CanFrame +{ + uint id; // 11-bit standard or 29-bit extended + bool extended; // true = 29-bit ID, false = 11-bit + bool rtr; // remote transmission request + bool fd; // CAN FD frame (up to 64 bytes, DLC 9-15 = 12..64) + bool brs; // FD bit rate switch (data phase at data_bitrate) + ubyte dlc; // data length code (0-8 classic, 0-15 FD) + ubyte[8] data; // classic CAN payload (FD >8 bytes needs external buffer) +} + +struct CanFilter +{ + uint id; // ID to match + uint mask; // 1-bits = must match, 0-bits = don't care + bool extended; // match extended frames only + bool rtr; // match RTR frames only + bool match_all; // ignore id/mask, accept everything (default) +} + +// Called from ISR when a frame has been received. +alias CanRxCallback = void function(Can can, ref const CanFrame frame) nothrow @nogc; + +// Called from ISR when a TX mailbox becomes free. +alias CanTxCallback = void function(Can can) nothrow @nogc; + +// Called when bus state changes (error active/passive/bus-off). +alias CanBusStateCallback = void function(Can can, CanBusState state) nothrow @nogc; + +// Caller-owned transmit operation token. +struct CanTxOp +{ + enum Status : ubyte + { + idle, + pending, + complete, + cancelled, + error, + arbitration_lost, + } + + alias Callback = void function(Can* can, ref CanTxOp op) nothrow @nogc; + + Status status; + void* user_data; + Callback cb; + + bool is_pending() const => status == Status.pending; + bool is_done() const => status >= Status.complete; +} + +struct Can +{ + ubyte port = ubyte.max; +} + +bool is_open(ref const Can can) +{ + return can.port != ubyte.max; +} + + +// ════════════════════════════════════════════════════════════════════ +// Error type +// ════════════════════════════════════════════════════════════════════ + +CanError can_result(Result result) +{ + return cast(CanError)result.system_code; +} + + +// ════════════════════════════════════════════════════════════════════ +// Implementation +// ════════════════════════════════════════════════════════════════════ + +// Lifecycle + +void can_init() +{ + if (_init_refcount++ == 0) + { + // TODO: enable clocks/power for CAN peripheral block + } +} + +void can_deinit() +{ + assert(_init_refcount > 0); + if (--_init_refcount == 0) + { + // TODO: disable clocks/power for CAN peripheral block + } +} + +// Port operations + +Result can_open(ref Can can, ubyte port, ref const CanConfig cfg, CanRxCallback rx_cb = null) +{ + static if (num_can == 0) + assert(false, "no CAN on this platform"); + else + { + if (port >= num_can) + return InternalResult.invalid_parameter; + + if (!can_hw_open(port, cfg)) + return InternalResult.failed; + + can.port = port; + return Result.success; + } +} + +Result can_reconfigure(ref Can can, ref const CanConfig cfg) +{ + assert(false, "TODO: can_reconfigure (hot reconfigure)"); +} + +void can_close(ref Can can) +{ + static if (num_can == 0) + assert(false, "no CAN on this platform"); + else + can_hw_close(can.port); + can.port = ubyte.max; +} + +// Transmit + +Result can_transmit(ref Can can, ref const CanFrame frame, CanTxOp* op = null) +{ + static if (num_can == 0) + assert(false, "no CAN on this platform"); + else + { + bool ok = can_hw_transmit(can.port, frame); + if (op !is null) + { + op.status = ok ? CanTxOp.Status.complete : CanTxOp.Status.error; + if (op.cb !is null) + op.cb(&can, *op); + } + if (!ok) + return InternalResult.failed; + return Result.success; + } +} + +void can_tx_abort(ref Can can, CanTxOp* op) +{ + static if (num_can == 0) + assert(false, "no CAN on this platform"); + else + { + can_hw_tx_abort(can.port); + if (op !is null) + { + op.status = CanTxOp.Status.cancelled; + if (op.cb !is null) + op.cb(&can, *op); + } + } +} + +// Receive + +bool can_receive(ref Can can, out CanFrame frame) +{ + static if (num_can == 0) + assert(false, "no CAN on this platform"); + else + return can_hw_receive(can.port, frame); +} + +size_t can_rx_available(ref const Can can) +{ + static if (num_can == 0) + assert(false, "no CAN on this platform"); + else + return can_hw_rx_available(can.port); +} + +void can_rx_flush(ref Can can) +{ + static if (num_can == 0) + assert(false, "no CAN on this platform"); + else + can_hw_rx_flush(can.port); +} + +// Filters + +Result can_filter_set(ref Can can, ubyte slot, ref const CanFilter filter) +{ + assert(false, "TODO: can_filter_set"); +} + +Result can_filter_clear(ref Can can, ubyte slot) +{ + assert(false, "TODO: can_filter_clear"); +} + +void can_filter_clear_all(ref Can can) +{ + assert(false, "TODO: can_filter_clear_all"); +} + +// Bus status + +CanBusState can_bus_state(ref const Can can) +{ + static if (num_can == 0) + assert(false, "no CAN on this platform"); + else + return can_hw_bus_state(can.port); +} + +ubyte can_tx_error_count(ref const Can can) +{ + static if (num_can == 0) + assert(false, "no CAN on this platform"); + else + return can_hw_tx_error_count(can.port); +} + +ubyte can_rx_error_count(ref const Can can) +{ + static if (num_can == 0) + assert(false, "no CAN on this platform"); + else + return can_hw_rx_error_count(can.port); +} + +CanError can_check_errors(ref Can can) +{ + static if (num_can == 0) + assert(false, "no CAN on this platform"); + else + return can_hw_check_errors(can.port); +} + +// Bus recovery + +Result can_bus_recover(ref Can can) +{ + static if (num_can == 0) + assert(false, "no CAN on this platform"); + else + { + if (!can_hw_bus_recover(can.port)) + return InternalResult.failed; + return Result.success; + } +} + +// Callbacks + +void can_set_rx_callback(ref Can can, CanRxCallback cb) +{ + assert(false, "TODO: can_set_rx_callback"); +} + +void can_set_tx_callback(ref Can can, CanTxCallback cb) +{ + assert(false, "TODO: can_set_tx_callback"); +} + +void can_set_bus_state_callback(ref Can can, CanBusStateCallback cb) +{ + assert(false, "TODO: can_set_bus_state_callback"); +} + +// Poll (for polled mode - check HW FIFOs and invoke callbacks) + +void can_poll(ref Can can) +{ + static if (num_can == 0) + assert(false, "no CAN on this platform"); + else + can_hw_poll(can.port); +} + + +// ════════════════════════════════════════════════════════════════════ +// Tests +// ════════════════════════════════════════════════════════════════════ + +unittest +{ + static if (num_can > 0) + { + Can c; + CanConfig cfg; + + can_init(); + + // Out-of-range port + auto r = can_open(c, cast(ubyte)num_can, cfg); + assert(!r); + assert(!c.is_open); + + // Open/close each valid port + foreach (p; 0 .. num_can) + { + Can port; + auto r2 = can_open(port, cast(ubyte)p, cfg); + assert(r2, "can_open failed"); + assert(port.is_open); + assert(port.port == p); + + can_poll(port); + + assert(can_check_errors(port) == CanError.none); + + can_close(port); + assert(!port.is_open); + } + + can_deinit(); + } +} + + +private: + +__gshared ubyte _init_refcount; diff --git a/src/urt/driver/dot1x/eapol.d b/src/urt/driver/dot1x/eapol.d new file mode 100644 index 0000000..88f967b --- /dev/null +++ b/src/urt/driver/dot1x/eapol.d @@ -0,0 +1,56 @@ +module urt.driver.dot1x.eapol; + +nothrow @nogc: + + +private ushort be_u16(const(ubyte)* p) pure +{ + return cast(ushort)((cast(ushort)p[0] << 8) | p[1]); +} + +enum ushort eth_p_eapol = 0x888E; + +enum ubyte eapol_version_2001 = 1; +enum ubyte eapol_version_2004 = 2; + +enum ubyte eapol_type_packet = 0; +enum ubyte eapol_type_start = 1; +enum ubyte eapol_type_logoff = 2; +enum ubyte eapol_type_key = 3; + +enum size_t eapol_hdr_len = 4; // ver + type + body_len(2) + +struct EapolFrame +{ + ubyte version_; + ubyte type; + ushort body_length; + const(ubyte)[] body; +} + +bool decode_eapol(const(ubyte)[] frame, ref EapolFrame out_) +{ + if (frame.length < eapol_hdr_len) + return false; + + ushort body_len = be_u16(frame.ptr + 2); + if (cast(size_t)body_len + eapol_hdr_len > frame.length) + return false; + + out_.version_ = frame[0]; + out_.type = frame[1]; + out_.body_length = body_len; + out_.body = frame[eapol_hdr_len .. eapol_hdr_len + body_len]; + return true; +} + +size_t encode_eapol_header(ubyte[] dst, ubyte version_, ubyte type, size_t body_len) +{ + if (dst.length < eapol_hdr_len || body_len > ushort.max) + return 0; + dst[0] = version_; + dst[1] = type; + dst[2] = cast(ubyte)(body_len >> 8); + dst[3] = cast(ubyte)(body_len & 0xff); + return eapol_hdr_len; +} diff --git a/src/urt/driver/esp32/alloc.d b/src/urt/driver/esp32/alloc.d new file mode 100644 index 0000000..0568e56 --- /dev/null +++ b/src/urt/driver/esp32/alloc.d @@ -0,0 +1,137 @@ +module urt.driver.esp32.alloc; + +import urt.mem.alloc : MemFlags; + +nothrow @nogc: + +enum has_realloc = false; +enum has_expand = false; +enum has_memsize = true; +enum has_exec = true; +enum has_retain = true; +enum has_memflags = true; + +void[] _alloc(size_t size, size_t alignment, MemFlags flags) pure +{ + uint primary = _esp_caps[flags]; + void* p = heap_caps_aligned_alloc(alignment, size, primary); + if (p is null) + { + // Speed bits are a placement preference, not a requirement -- if the + // preferred pool can't satisfy, retry against the default heap (which + // covers all pools). DMA constraint must be preserved. + uint speed = flags & 3; + if (speed != 0) + { + uint fallback = (flags & MemFlags.dma) ? (CAP_DEFAULT | CAP_DMA) : CAP_DEFAULT; + if (fallback != primary) + { + p = heap_caps_aligned_alloc(alignment, size, fallback); + if (p !is null) + { + alias LogFn = void function(size_t, size_t, MemFlags) pure nothrow @nogc; + (cast(LogFn) &log_alloc_failover)(size, alignment, flags); + } + } + } + if (p is null) + { + alias LogFn = void function(size_t, size_t, MemFlags) pure nothrow @nogc; + (cast(LogFn) &log_alloc_oom)(size, alignment, flags); + } + } + return p ? p[0 .. size] : null; +} + +void _free(void* ptr) pure +{ + heap_caps_aligned_free(ptr); +} + +size_t _memsize(void* ptr) pure +{ + return heap_caps_get_allocated_size(ptr); +} + +void[] _alloc_exec(size_t size) pure +{ + void* p = heap_caps_aligned_alloc(8, size, CAP_INTERNAL); + return p ? p[0 .. size] : null; +} + +void _free_exec(void[] mem) pure +{ + heap_caps_aligned_free(mem.ptr); +} + +void[] _alloc_retain(size_t size) pure +{ + void* p = heap_caps_aligned_alloc(8, size, CAP_RTCRAM); + return p ? p[0 .. size] : null; +} + +void _free_retain(void[] mem) pure +{ + heap_caps_aligned_free(mem.ptr); +} + + +private: + +enum CAP_DMA = 1 << 3; +enum CAP_SPIRAM = 1 << 10; +enum CAP_INTERNAL = 1 << 11; +enum CAP_DEFAULT = 1 << 12; +enum CAP_RTCRAM = 1 << 15; + +// MemFlags [2:0] → ESP-IDF heap_caps +// [1:0] speed: 0=default, 1=fast, 2=slow, 3=fastest +// [2] dma +immutable uint[8] _esp_caps = [ + CAP_DEFAULT, // 0: default + CAP_DEFAULT | CAP_INTERNAL, // 1: fast + CAP_DEFAULT | CAP_SPIRAM, // 2: slow + CAP_DEFAULT | CAP_INTERNAL, // 3: fastest (no TCM on ESP32) + CAP_DEFAULT | CAP_DMA, // 4: dma + CAP_DEFAULT | CAP_DMA | CAP_INTERNAL, // 5: dma+fast + CAP_DEFAULT | CAP_DMA | CAP_SPIRAM, // 6: dma+slow + CAP_DEFAULT | CAP_DMA | CAP_INTERNAL, // 7: dma+fastest +]; + +extern(C) void* heap_caps_aligned_alloc(size_t alignment, size_t size, uint caps) pure; +extern(C) void heap_caps_aligned_free(void* ptr) pure; +extern(C) size_t heap_caps_get_allocated_size(void* ptr) pure; +extern(C) size_t heap_caps_get_free_size(uint caps) pure; +extern(C) size_t heap_caps_get_largest_free_block(uint caps) pure; + +void log_alloc_oom(size_t size, size_t alignment, MemFlags flags) nothrow @nogc +{ + __gshared bool reentrant; + if (reentrant) + return; + reentrant = true; + scope(exit) reentrant = false; + + import urt.log; + uint primary = _esp_caps[flags]; + log_error("heap.alloc", "OOM! - size=", size, " align=", alignment, " flags=", cast(int)flags, + " free=", heap_caps_get_free_size(primary), + " largest=", heap_caps_get_largest_free_block(primary), + " default-free=", heap_caps_get_free_size(CAP_DEFAULT), + " default-largest=", heap_caps_get_largest_free_block(CAP_DEFAULT)); +} + +void log_alloc_failover(size_t size, size_t alignment, MemFlags flags) nothrow @nogc +{ + __gshared bool reentrant; + if (reentrant) + return; + reentrant = true; + scope(exit) reentrant = false; + + import urt.log; + uint primary = _esp_caps[flags]; + log_debug("heap.alloc", "preferred pool full, fail to default - size=", size, " align=", alignment, " flags=", cast(int)flags, + " free=", heap_caps_get_free_size(primary), + " largest=", heap_caps_get_largest_free_block(primary)); +} diff --git a/src/urt/driver/esp32/ble.d b/src/urt/driver/esp32/ble.d new file mode 100644 index 0000000..9583693 --- /dev/null +++ b/src/urt/driver/esp32/ble.d @@ -0,0 +1,978 @@ +// ESP32 BLE driver -- D wrapper over NimBLE via C shim + direct calls +// +// The C shim (ow_shim.c) handles: +// - ow_ble_init/deinit: NimBLE host config struct, port init, host task +// - ow_ble_set_gap_callback: GAP event dispatch trampoline to D +// +// Everything else (scan, connect, GATT) calls NimBLE C API directly. +// +// BLE controller count per chip (ESP-IDF v6.0): +// ESP32, S3, C2, C3, C5, C6, H2: 1 S2, P4: 0 +module urt.driver.esp32.ble; + +import urt.driver.ble; + +import urt.uuid : GUID; + +nothrow @nogc: + + +version (ESP32) enum uint num_ble = 1; +else version (ESP32_S3) enum uint num_ble = 1; +else version (ESP32_C2) enum uint num_ble = 1; +else version (ESP32_C3) enum uint num_ble = 1; +else version (ESP32_C5) enum uint num_ble = 1; +else version (ESP32_C6) enum uint num_ble = 1; +else version (ESP32_H2) enum uint num_ble = 1; +else enum uint num_ble = 0; // S2, P4 + + +static if (num_ble > 0): + + +bool ble_hw_open(uint port, ref const BLEConfig cfg) +{ + if (port >= num_ble) + return false; + if (_opened) + return true; + + if (ow_ble_init() != 0) + return false; + + ow_ble_set_gap_callback(&gap_event_trampoline); + + _opened = true; + return true; +} + +void ble_hw_close(uint port) +{ + if (!_opened) + return; + + ble_hw_scan_stop(port); + ble_hw_adv_stop(port, BLEAdv.init); + + // disconnect all active connections + foreach (ref s; _sessions) + { + if (s.active) + ble_gap_terminate(s.nimble_handle, 0x13); // Remote User Terminated + } + + ow_ble_set_gap_callback(null); + ow_ble_deinit(); + + _opened = false; + _scan_cb = null; + _conn_cb = null; + _discover_cb = null; + _read_cb = null; + _write_cb = null; + _notify_cb = null; + _wake_cb = null; + _num_sessions = 0; +} + +// --- Scanning --- + +bool ble_hw_scan_start(uint port, ref const BLEScanConfig cfg) +{ + ble_gap_disc_params params; + params.itvl = cast(ushort)(cfg.interval_ms * 1000 / 625); // BLE units of 0.625ms + params.window = cast(ushort)(cfg.window_ms * 1000 / 625); + if (!cfg.active) + params.flags |= 0x02; // passive + if (cfg.filter_duplicates) + params.flags |= 0x04; // filter_duplicates + + if (ble_gap_disc(0, 0, ¶ms, &gap_event_trampoline, null) != 0) + return false; + return true; +} + +void ble_hw_scan_stop(uint port) +{ + ble_gap_disc_cancel(); +} + +// --- Advertising --- + +BLEAdv ble_hw_adv_start(uint port, ref const BLEAdvConfig cfg) +{ + if (cfg.adv_data.length > 0 && cfg.adv_data.length <= 31) + { + if (ble_gap_adv_set_data(cfg.adv_data.ptr, cast(int)cfg.adv_data.length) != 0) + return BLEAdv.init; + } + + if (cfg.scan_rsp.length > 0 && cfg.scan_rsp.length <= 31) + { + if (ble_gap_adv_rsp_set_data(cfg.scan_rsp.ptr, cast(int)cfg.scan_rsp.length) != 0) + return BLEAdv.init; + } + + ble_gap_adv_params params; + params.conn_mode = cfg.adv_type == BLEAdvType.connectable ? 2 : 0; // BLE_GAP_CONN_MODE_UND : NON + params.disc_mode = 2; // BLE_GAP_DISC_MODE_GEN + params.itvl_min = cast(ushort)(cfg.interval_ms * 1000 / 625); + params.itvl_max = params.itvl_min; + + if (ble_gap_adv_start(0, null, 0, ¶ms, &gap_event_trampoline, null) != 0) + return BLEAdv.init; + return BLEAdv(0); +} + +void ble_hw_adv_stop(uint port, BLEAdv) +{ + ble_gap_adv_stop(); +} + +// --- Connection --- + +bool ble_hw_connect(uint port, ref const ubyte[6] peer_addr, BLEAddrType addr_type, ref const BLEConnConfig cfg) +{ + if (_pending_connect) + return false; + + ble_addr_t addr; + addr.type = cast(ubyte)addr_type; + // NimBLE uses LSB-first byte order + foreach (i; 0 .. 6) + addr.val[i] = peer_addr[5 - i]; + + ble_gap_conn_params params; + params.itvl_min = cast(ushort)(cfg.interval_min_ms * 1000 / 1250); // units of 1.25ms + params.itvl_max = cast(ushort)(cfg.interval_max_ms * 1000 / 1250); + params.latency = cfg.latency; + params.supervision_timeout = cast(ushort)(cfg.timeout_ms / 10); // units of 10ms + params.min_ce_len = 0; + params.max_ce_len = 0; + + _pending_connect = true; + if (ble_gap_connect(0, &addr, 30_000, ¶ms, &gap_event_trampoline, null) != 0) + { + _pending_connect = false; + return false; + } + return true; +} + +void ble_hw_connect_cancel(uint port) +{ + ble_gap_conn_cancel(); + _pending_connect = false; +} + +bool ble_hw_disconnect(uint port, BLEConn conn) +{ + auto s = find_session(conn.id); + if (s is null) + return false; + + if (ble_gap_terminate(s.nimble_handle, 0x13) != 0) + return false; + return true; +} + +// --- GATT discovery --- + +bool ble_hw_gatt_discover(uint port, BLEConn conn) +{ + auto s = find_session(conn.id); + if (s is null) + return false; + + _discovering_conn = conn.id; + _discover_phase = DiscoverPhase.services; + s.num_chars = 0; + + if (ble_gattc_disc_all_svcs(s.nimble_handle, &svc_discover_cb, null) != 0) + return false; + return true; +} + +// --- GATT read/write --- + +bool ble_hw_gatt_read(uint port, BLEConn conn, ushort handle) +{ + auto s = find_session(conn.id); + if (s is null) + return false; + + if (ble_gattc_read(s.nimble_handle, handle, &gatt_read_cb, cast(void*)cast(size_t)conn.id) != 0) + return false; + return true; +} + +bool ble_hw_gatt_write(uint port, BLEConn conn, ushort handle, const(ubyte)[] data, bool with_response) +{ + auto s = find_session(conn.id); + if (s is null) + return false; + + if (with_response) + { + if (ble_gattc_write_flat(s.nimble_handle, handle, data.ptr, + cast(ushort)data.length, &gatt_write_cb, cast(void*)cast(size_t)conn.id) != 0) + return false; + } + else + { + if (ble_gattc_write_no_rsp_flat(s.nimble_handle, handle, + data.ptr, cast(ushort)data.length) != 0) + return false; + } + return true; +} + +// --- Notifications --- + +bool ble_hw_gatt_subscribe(uint port, BLEConn conn, ushort handle, bool enable) +{ + auto s = find_session(conn.id); + if (s is null) + return false; + + // find CCCD handle (handle + 1 by convention for standard GATT) + ushort cccd_handle = cast(ushort)(handle + 1); + + ubyte[2] cccd_value; + if (enable) + cccd_value[0] = 0x01; // enable notifications + + if (ble_gattc_write_flat(s.nimble_handle, cccd_handle, + cccd_value.ptr, 2, null, null) != 0) + return false; + return true; +} + +// --- Queries --- + +bool ble_hw_get_mac(uint port, ref ubyte[6] mac) +{ + ubyte addr_type; + if (ble_hs_id_infer_auto(0, &addr_type) != 0) + return false; + if (ble_hs_id_copy_addr(addr_type, mac.ptr, null) != 0) + return false; + return true; +} + +byte ble_hw_get_rssi(uint port, BLEConn conn) +{ + auto s = find_session(conn.id); + if (s is null) + return -128; + + byte rssi; + if (ble_gap_conn_rssi(s.nimble_handle, &rssi) != 0) + return -128; + return rssi; +} + +// --- Callbacks --- + +void ble_hw_set_scan_callback(uint port, BLEScanCallback cb) { _scan_cb = cb; } +void ble_hw_set_conn_callback(uint port, BLEConnCallback cb) { _conn_cb = cb; } +void ble_hw_set_discover_callback(uint port, BLEDiscoverCallback cb) { _discover_cb = cb; } +void ble_hw_set_read_callback(uint port, BLEReadCallback cb) { _read_cb = cb; } +void ble_hw_set_write_callback(uint port, BLEWriteCallback cb) { _write_cb = cb; } +void ble_hw_set_notify_callback(uint port, BLENotifyCallback cb) { _notify_cb = cb; } +void ble_hw_set_wake_callback(uint port, BLEWakeCallback cb) { _wake_cb = cb; } + +// --- Poll --- + +void ble_hw_poll(uint port) +{ + // Drain buffered events from NimBLE host task. + // Events are queued by GAP/GATT callbacks which run on the NimBLE task. + + auto ble = BLE(0); + + // scan results + while (_scan_queue.count > 0) + { + auto report = &_scan_queue.buf[_scan_queue.tail]; + if (_scan_cb !is null) + _scan_cb(ble, *report); + _scan_queue.tail = (_scan_queue.tail + 1) % _scan_queue.buf.length; + _scan_queue.count--; + } + + // control events (connect / disconnect / discovery) + while (_control_queue.count > 0) + { + auto e = &_control_queue.buf[_control_queue.tail]; + final switch (e.kind) + { + case ControlEventKind.connected: + if (_conn_cb !is null) + _conn_cb(ble, BLEConn(e.conn_id), true, BLEError.none); + break; + case ControlEventKind.connect_failed: + if (_conn_cb !is null) + _conn_cb(ble, BLEConn(e.conn_id), false, BLEError.timeout); + break; + case ControlEventKind.disconnected: + if (_conn_cb !is null) + _conn_cb(ble, BLEConn(e.conn_id), false, BLEError.none); + remove_session(e.conn_id); + break; + case ControlEventKind.discover_done: + if (_discover_cb !is null) + { + auto s = find_session(e.conn_id); + if (s !is null) + { + BLEGattChar[max_chars_per_session] chars = void; + foreach (i; 0 .. s.num_chars) + { + chars[i].handle = s.chars[i].handle; + chars[i].cccd_handle = s.chars[i].cccd_handle; + chars[i].service_uuid = s.chars[i].service_uuid; + chars[i].char_uuid = s.chars[i].char_uuid; + chars[i].properties = cast(GattCharProps)s.chars[i].properties; + } + _discover_cb(ble, BLEConn(e.conn_id), chars[0 .. s.num_chars], BLEError.none); + } + } + break; + case ControlEventKind.discover_failed: + if (_discover_cb !is null) + _discover_cb(ble, BLEConn(e.conn_id), null, BLEError.protocol); + break; + } + _control_queue.tail = (_control_queue.tail + 1) % _control_queue.buf.length; + _control_queue.count--; + } + + // GATT read/write completions + while (_gatt_queue.count > 0) + { + auto evt = &_gatt_queue.buf[_gatt_queue.tail]; + if (evt.is_read && _read_cb !is null) + _read_cb(ble, BLEConn(evt.conn_id), evt.handle, evt.data[0 .. evt.data_len], evt.error); + else if (!evt.is_read && _write_cb !is null) + _write_cb(ble, BLEConn(evt.conn_id), evt.handle, evt.error); + _gatt_queue.tail = (_gatt_queue.tail + 1) % _gatt_queue.buf.length; + _gatt_queue.count--; + } + + // notifications + while (_notify_queue.count > 0) + { + auto evt = &_notify_queue.buf[_notify_queue.tail]; + if (_notify_cb !is null) + _notify_cb(ble, BLEConn(evt.conn_id), evt.handle, evt.data[0 .. evt.data_len]); + _notify_queue.tail = (_notify_queue.tail + 1) % _notify_queue.buf.length; + _notify_queue.count--; + } +} + + +private: + +enum int ESP_OK = 0; +enum max_sessions = 4; +enum max_chars_per_session = 32; + +// --- Session table --- + +struct SessionCharInfo +{ + ushort handle; + ushort cccd_handle; + GUID service_uuid; + GUID char_uuid; + ushort properties; +} + +struct Session +{ + bool active; + ubyte id; // our BLEConn.id + ushort nimble_handle; // NimBLE connection handle + SessionCharInfo[max_chars_per_session] chars; + ubyte num_chars; +} + +Session* find_session(ubyte id) +{ + foreach (ref s; _sessions[0 .. _num_sessions]) + { + if (s.active && s.id == id) + return &s; + } + return null; +} + +Session* find_session_by_nimble(ushort nimble_handle) +{ + foreach (ref s; _sessions[0 .. _num_sessions]) + { + if (s.active && s.nimble_handle == nimble_handle) + return &s; + } + return null; +} + +Session* alloc_session(ushort nimble_handle) +{ + if (_num_sessions >= max_sessions) + return null; + auto s = &_sessions[_num_sessions++]; + s.active = true; + s.id = _next_conn_id++; + s.nimble_handle = nimble_handle; + s.num_chars = 0; + return s; +} + +void remove_session(ubyte id) +{ + foreach (i, ref s; _sessions[0 .. _num_sessions]) + { + if (s.id == id) + { + _sessions[i] = _sessions[_num_sessions - 1]; + _num_sessions--; + return; + } + } +} + +// --- Event ring buffers --- + +struct RingBuffer(T, uint N) +{ + T[N] buf; + uint head; + uint tail; + uint count; + + T* push() nothrow @nogc + { + if (count >= N) + return null; // drop oldest would be: tail = (tail + 1) % N; count--; + auto p = &buf[head]; + head = (head + 1) % N; + count++; + return p; + } +} + +struct GattCompletionEvent +{ + ubyte conn_id; + ushort handle; + bool is_read; + BLEError error; + ubyte data_len; + ubyte[247] data; +} + +struct NotifyEvent +{ + ubyte conn_id; + ushort handle; + ubyte data_len; + ubyte[247] data; +} + +enum ControlEventKind : ubyte { connected, connect_failed, disconnected, discover_done, discover_failed } + +struct ControlEvent +{ + ControlEventKind kind; + ubyte conn_id; +} + +// --- Module state --- + +__gshared bool _opened; +__gshared bool _pending_connect; +__gshared ubyte _next_conn_id; + +__gshared Session[max_sessions] _sessions; +__gshared ubyte _num_sessions; + +__gshared BLEScanCallback _scan_cb; +__gshared BLEConnCallback _conn_cb; +__gshared BLEDiscoverCallback _discover_cb; +__gshared BLEReadCallback _read_cb; +__gshared BLEWriteCallback _write_cb; +__gshared BLENotifyCallback _notify_cb; +__gshared BLEWakeCallback _wake_cb; + +void signal_wake() +{ + if (_wake_cb !is null) + _wake_cb(); +} + +// scan result ring buffer (set from NimBLE task, drained from main loop) +__gshared RingBuffer!(BLEAdvReport, 16) _scan_queue; + +// GATT completion ring buffer +__gshared RingBuffer!(GattCompletionEvent, 16) _gatt_queue; + +// notification ring buffer +__gshared RingBuffer!(NotifyEvent, 16) _notify_queue; + +// control events (connect / disconnect / discovery), set from NimBLE task +__gshared RingBuffer!(ControlEvent, 8) _control_queue; + +void push_control(ControlEventKind kind, ubyte conn_id) +{ + if (auto e = _control_queue.push()) + *e = ControlEvent(kind, conn_id); +} + +enum DiscoverPhase : ubyte { idle, services, chars } +__gshared DiscoverPhase _discover_phase; +__gshared ubyte _discovering_conn; + +// service discovery iteration state (used from NimBLE task callbacks) +__gshared ble_gatt_svc[16] _discovered_svcs; +__gshared ubyte _num_discovered_svcs; +__gshared ubyte _current_svc_idx; +__gshared GUID _current_svc_uuid; + + +// --- GAP event trampoline (called from NimBLE host task) --- + +extern(C) int gap_event_trampoline(ble_gap_event* event, void*) nothrow @nogc +{ + if (event is null) + return 0; + + switch (event.type) + { + case BLE_GAP_EVENT_DISC: + // scan result + auto report = _scan_queue.push(); + if (report !is null) + { + auto disc = &event.disc; + // NimBLE addr is LSB-first, we want MSB-first + foreach (i; 0 .. 6) + report.addr[i] = disc.addr.val[5 - i]; + report.addr_type = cast(BLEAddrType)disc.addr.type; + report.rssi = disc.rssi; + report.tx_power = -128; // not in base event + + ubyte len = disc.length_data > 62 ? 62 : disc.length_data; + report.data_len = len; + if (len > 0) + report.data_buf[0 .. len] = disc.data[0 .. len]; + + report.adv_type = disc.event_type == 0 ? BLEAdvType.connectable : BLEAdvType.nonconnectable; + } + signal_wake(); + return 0; + + case BLE_GAP_EVENT_CONNECT: + _pending_connect = false; + if (event.connect.status == 0) + { + auto s = alloc_session(event.connect.conn_handle); + if (s !is null) + push_control(ControlEventKind.connected, s.id); + } + else + push_control(ControlEventKind.connect_failed, ubyte.max); + signal_wake(); + return 0; + + case BLE_GAP_EVENT_DISCONNECT: + auto s = find_session_by_nimble(event.disconnect.conn.conn_handle); + if (s !is null) + { + push_control(ControlEventKind.disconnected, s.id); + s.active = false; + } + signal_wake(); + return 0; + + case BLE_GAP_EVENT_NOTIFY_RX: + auto s = find_session_by_nimble(event.notify_rx.conn_handle); + if (s !is null) + { + auto evt = _notify_queue.push(); + if (evt !is null) + { + evt.conn_id = s.id; + evt.handle = event.notify_rx.attr_handle; + auto om = event.notify_rx.om; + // copy mbuf chain to flat buffer + evt.data_len = 0; + while (om !is null && evt.data_len < evt.data.length) + { + ushort copy = om.om_len; + if (evt.data_len + copy > evt.data.length) + copy = cast(ushort)(evt.data.length - evt.data_len); + evt.data[evt.data_len .. evt.data_len + copy] = om.om_data[0 .. copy]; + evt.data_len += copy; + om = om.om_next; + } + } + } + signal_wake(); + return 0; + + default: + return 0; + } +} + +// --- GATT service discovery callback (NimBLE task) --- + +extern(C) int svc_discover_cb(ushort conn_handle, const(ble_gatt_error)* error, const(ble_gatt_svc)* service, void*) nothrow @nogc +{ + if (error !is null && error.status == 0 && service !is null) + { + // accumulate services + if (_num_discovered_svcs < _discovered_svcs.length) + _discovered_svcs[_num_discovered_svcs++] = *service; + return 0; + } + + // discovery complete (error.status != 0 means end of list or actual error) + if (_num_discovered_svcs == 0) + { + push_control(ControlEventKind.discover_done, _discovering_conn); + _discover_phase = DiscoverPhase.idle; + signal_wake(); + return 0; + } + + // start characteristic discovery for first service + _current_svc_idx = 0; + return discover_next_svc_chars(conn_handle); +} + +int discover_next_svc_chars(ushort conn_handle) nothrow @nogc +{ + while (_current_svc_idx < _num_discovered_svcs) + { + auto svc = &_discovered_svcs[_current_svc_idx]; + _current_svc_uuid = nimble_uuid_to_guid(&svc.uuid); + _discover_phase = DiscoverPhase.chars; + + if (ble_gattc_disc_all_chrs(conn_handle, svc.start_handle, svc.end_handle, + &chr_discover_cb, null) == 0) + return 0; + + _current_svc_idx++; + } + + // all services done + push_control(ControlEventKind.discover_done, _discovering_conn); + _discover_phase = DiscoverPhase.idle; + _num_discovered_svcs = 0; + signal_wake(); + return 0; +} + +// --- GATT characteristic discovery callback (NimBLE task) --- + +extern(C) int chr_discover_cb(ushort conn_handle, const(ble_gatt_error)* error, const(ble_gatt_chr)* chr, void*) nothrow @nogc +{ + if (error !is null && error.status == 0 && chr !is null) + { + auto s = find_session_by_nimble(conn_handle); + if (s !is null && s.num_chars < max_chars_per_session) + { + auto ci = &s.chars[s.num_chars++]; + ci.handle = chr.val_handle; + ci.cccd_handle = 0; // TODO: discover descriptors for CCCD + ci.service_uuid = _current_svc_uuid; + ci.char_uuid = nimble_uuid_to_guid(&chr.uuid); + ci.properties = chr.properties; + } + return 0; + } + + // this service's chars done, move to next + _current_svc_idx++; + return discover_next_svc_chars(conn_handle); +} + +// --- GATT read callback (NimBLE task) --- + +extern(C) int gatt_read_cb(ushort conn_handle, const(ble_gatt_error)* error, ble_gatt_attr* attr, void* cb_arg) nothrow @nogc +{ + ubyte conn_id = cast(ubyte)cast(size_t)cb_arg; + auto evt = _gatt_queue.push(); + if (evt is null) + return 0; + + evt.conn_id = conn_id; + evt.is_read = true; + + if (error !is null && error.status == 0 && attr !is null) + { + evt.handle = attr.handle; + evt.error = BLEError.none; + // copy mbuf to flat buffer + evt.data_len = 0; + auto om = attr.om; + while (om !is null && evt.data_len < evt.data.length) + { + ushort copy = om.om_len; + if (evt.data_len + copy > evt.data.length) + copy = cast(ushort)(evt.data.length - evt.data_len); + evt.data[evt.data_len .. evt.data_len + copy] = om.om_data[0 .. copy]; + evt.data_len += copy; + om = om.om_next; + } + } + else + { + evt.handle = attr !is null ? attr.handle : 0; + evt.error = BLEError.protocol; + evt.data_len = 0; + } + signal_wake(); + return 0; +} + +// --- GATT write callback (NimBLE task) --- + +extern(C) int gatt_write_cb(ushort conn_handle, const(ble_gatt_error)* error, ble_gatt_attr* attr, void* cb_arg) nothrow @nogc +{ + ubyte conn_id = cast(ubyte)cast(size_t)cb_arg; + auto evt = _gatt_queue.push(); + if (evt is null) + return 0; + + evt.conn_id = conn_id; + evt.handle = attr !is null ? attr.handle : 0; + evt.is_read = false; + evt.data_len = 0; + evt.error = (error !is null && error.status == 0) ? BLEError.none : BLEError.protocol; + signal_wake(); + return 0; +} + +// --- UUID conversion --- + +GUID nimble_uuid_to_guid(const(ble_uuid_any)* uuid) nothrow @nogc +{ + GUID g; + if (uuid.u.type == 16) // BLE_UUID_TYPE_16 + { + // BT SIG base: 0000xxxx-0000-1000-8000-00805F9B34FB + g.data1 = uuid.u16.value; + g.data3 = 0x1000; + g.data4 = [0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB]; + } + else if (uuid.u.type == 32) // BLE_UUID_TYPE_32 + { + g.data1 = uuid.u32.value; + g.data3 = 0x1000; + g.data4 = [0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB]; + } + else if (uuid.u.type == 128) // BLE_UUID_TYPE_128 + { + // NimBLE stores 128-bit UUIDs in little-endian byte order + auto v = uuid.u128.value; + g.data1 = v[12] | (cast(uint)v[13] << 8) | (cast(uint)v[14] << 16) | (cast(uint)v[15] << 24); + g.data2 = cast(ushort)(v[10] | (cast(ushort)v[11] << 8)); + g.data3 = cast(ushort)(v[8] | (cast(ushort)v[9] << 8)); + g.data4[0 .. 2] = v[6 .. 8]; // big-endian in GUID + g.data4[2 .. 8] = v[0 .. 6]; + } + return g; +} + + +// ==================================================================== +// NimBLE C API declarations +// ==================================================================== + +struct ble_addr_t +{ + ubyte type; + ubyte[6] val; +} + +struct ble_gap_disc_params +{ + ushort itvl; + ushort window; + ubyte filter_policy; + ubyte flags; // bit 0: limited, bit 1: passive, bit 2: filter_duplicates, bit 3: disable_observer_mode +} + +struct ble_gap_conn_params +{ + ushort scan_itvl; + ushort scan_window; + ushort itvl_min; + ushort itvl_max; + ushort latency; + ushort supervision_timeout; + ushort min_ce_len; + ushort max_ce_len; +} + +struct ble_gap_adv_params +{ + ubyte conn_mode; + ubyte disc_mode; + ushort itvl_min; + ushort itvl_max; + ubyte channel_map; + ubyte filter_policy; + ubyte high_duty_cycle; +} + +// NimBLE GAP event structure (simplified) +struct ble_gap_event +{ + ubyte type; + ubyte[3] _pad; + + struct ConnectData { int status; ushort conn_handle; } + struct DisconnectData { int reason; ble_gap_conn_desc conn; } + struct DiscData { ubyte event_type; ubyte length_data; ble_addr_t addr; byte rssi; const(ubyte)* data; ble_addr_t direct_addr; } + struct NotifyRxData { os_mbuf* om; ushort attr_handle; ushort conn_handle; ubyte indication; } + + union + { + ConnectData connect; + DisconnectData disconnect; + DiscData disc; + NotifyRxData notify_rx; + } +} + +struct ble_gap_conn_desc +{ + uint sec_state; + ble_addr_t our_id_addr; + ble_addr_t peer_id_addr; + ble_addr_t our_ota_addr; + ble_addr_t peer_ota_addr; + ushort conn_handle; + ushort conn_itvl; + ushort conn_latency; + ushort supervision_timeout; + ubyte role; + ubyte master_clock_accuracy; +} + +struct ble_gatt_error +{ + ushort status; + ushort att_handle; +} + +struct ble_uuid +{ + ubyte type; // 16, 32, or 128 +} + +struct ble_uuid16 +{ + ble_uuid u; + ushort value; +} + +struct ble_uuid32 +{ + ble_uuid u; + uint value; +} + +struct ble_uuid128 +{ + ble_uuid u; + ubyte[16] value; +} + +union ble_uuid_any +{ + ble_uuid u; + ble_uuid16 u16; + ble_uuid32 u32; + ble_uuid128 u128; +} + +struct ble_gatt_svc +{ + ushort start_handle; + ushort end_handle; + ble_uuid_any uuid; +} + +struct ble_gatt_chr +{ + ushort def_handle; + ushort val_handle; + ubyte properties; + ble_uuid_any uuid; +} + +struct ble_gatt_attr +{ + ushort handle; + ushort offset; + os_mbuf* om; +} + +// NimBLE mbuf +struct os_mbuf +{ + ubyte* om_data; + ubyte om_flags; + ubyte om_pkthdr_len; + ushort om_len; + void* om_omp; // os_mbuf_pool* (opaque) + os_mbuf* om_next; // SLIST_ENTRY(os_mbuf) - single ptr in practice +} + +// GAP event types +enum : ubyte +{ + BLE_GAP_EVENT_CONNECT = 0, + BLE_GAP_EVENT_DISCONNECT = 1, + BLE_GAP_EVENT_DISC = 7, + BLE_GAP_EVENT_NOTIFY_RX = 12, +} + +// C shim functions +extern(C) nothrow @nogc +{ + int ow_ble_init(); + void ow_ble_deinit(); + void ow_ble_set_gap_callback(int function(ble_gap_event*, void*) nothrow @nogc cb); +} + +// Direct NimBLE calls +extern(C) nothrow @nogc +{ + int ble_gap_disc(ubyte own_addr_type, int duration_ms, const(ble_gap_disc_params)* params, int function(ble_gap_event*, void*) cb, void* cb_arg); + int ble_gap_disc_cancel(); + int ble_gap_connect(ubyte own_addr_type, const(ble_addr_t)* peer_addr, int duration_ms, const(ble_gap_conn_params)* params, int function(ble_gap_event*, void*) cb, void* cb_arg); + int ble_gap_conn_cancel(); + int ble_gap_terminate(ushort conn_handle, ubyte hci_reason); + int ble_gap_conn_rssi(ushort conn_handle, byte* rssi); + + int ble_gap_adv_set_data(const(ubyte)* data, int data_len); + int ble_gap_adv_rsp_set_data(const(ubyte)* data, int data_len); + int ble_gap_adv_start(ubyte own_addr_type, const(ble_addr_t)* direct_addr, int duration_ms, const(ble_gap_adv_params)* params, int function(ble_gap_event*, void*) cb, void* cb_arg); + int ble_gap_adv_stop(); + + int ble_gattc_disc_all_svcs(ushort conn_handle, int function(ushort, const(ble_gatt_error)*, const(ble_gatt_svc)*, void*) cb, void* cb_arg); + int ble_gattc_disc_all_chrs(ushort conn_handle, ushort start_handle, ushort end_handle, int function(ushort, const(ble_gatt_error)*, const(ble_gatt_chr)*, void*) cb, void* cb_arg); + int ble_gattc_read(ushort conn_handle, ushort attr_handle, int function(ushort, const(ble_gatt_error)*, ble_gatt_attr*, void*) cb, void* cb_arg); + int ble_gattc_write_flat(ushort conn_handle, ushort attr_handle, const(void)* data, ushort data_len, int function(ushort, const(ble_gatt_error)*, ble_gatt_attr*, void*) cb, void* cb_arg); + int ble_gattc_write_no_rsp_flat(ushort conn_handle, ushort attr_handle, const(void)* data, ushort data_len); + + int ble_hs_id_infer_auto(int privacy, ubyte* out_addr_type); + int ble_hs_id_copy_addr(ubyte addr_type, ubyte* out_addr, int* out_is_nrpa); +} diff --git a/src/urt/driver/esp32/can.d b/src/urt/driver/esp32/can.d new file mode 100644 index 0000000..088ecda --- /dev/null +++ b/src/urt/driver/esp32/can.d @@ -0,0 +1,222 @@ +// ESP32 CAN (TWAI) driver -- thin D layer over ESP-IDF _v2 handle API +// +// Only ow_can_open is a C shim (bitrate table + config construction). +// All other calls go directly to the ESP-IDF twai_*_v2 functions. +// +// Controller count per chip (ESP-IDF v6.0): +// ESP32, S3, C3, H2: 1 C5, C6: 2 P4: 3 S2, C2, C61: 0 +module urt.driver.esp32.can; + +import urt.driver.can : CanConfig, CanFrame, CanError, CanBusState; + +nothrow @nogc: + + +// SOC_TWAI_CONTROLLER_NUM per chip variant (ESP-IDF v6.0 soc_caps.h) +version (ESP32) enum uint num_can = 1; +else version (ESP32_S3) enum uint num_can = 1; +else version (ESP32_P4) enum uint num_can = 3; +else version (ESP32_C3) enum uint num_can = 1; +else version (ESP32_C5) enum uint num_can = 2; +else version (ESP32_C6) enum uint num_can = 2; +else version (ESP32_H2) enum uint num_can = 1; +else enum uint num_can = 0; // S2, C2, C61 + +// SOC_TWAI_FD_SUPPORTED (ESP-IDF v6.0 soc_caps.h) +version (ESP32_C5) enum bool has_can_fd = true; +else enum bool has_can_fd = false; + + +static if (num_can > 0): + + +bool can_hw_open(uint port, ref const CanConfig cfg) +{ + if (port >= num_can) + return false; + if (_handles[port] !is null) + return true; + int tx = cfg.tx_gpio == ubyte.max ? -1 : cast(int)cfg.tx_gpio; + int rx = cfg.rx_gpio == ubyte.max ? -1 : cast(int)cfg.rx_gpio; + _handles[port] = ow_can_open(port, cfg.bitrate, tx, rx, + cfg.sjw, cfg.tseg1, cfg.tseg2, cfg.brp); + return _handles[port] !is null; +} + +void can_hw_close(uint port) +{ + if (port >= num_can || _handles[port] is null) + return; + twai_stop_v2(_handles[port]); + twai_driver_uninstall_v2(_handles[port]); + _handles[port] = null; +} + +bool can_hw_transmit(uint port, ref const CanFrame frame) +{ + if (port >= num_can || _handles[port] is null) + return false; + twai_message_t msg; + msg.flags = cast(uint)frame.extended | (cast(uint)frame.rtr << 1); + msg.identifier = frame.id; + msg.data_length_code = frame.dlc; + if (frame.dlc > 0) + msg.data[0 .. frame.dlc] = frame.data[0 .. frame.dlc]; + return twai_transmit_v2(_handles[port], &msg, 0) == ESP_OK; +} + +bool can_hw_receive(uint port, out CanFrame frame) +{ + if (port >= num_can || _handles[port] is null) + return false; + twai_message_t msg; + if (twai_receive_v2(_handles[port], &msg, 0) != ESP_OK) + return false; + frame.id = msg.identifier; + frame.extended = (msg.flags & 1) != 0; + frame.rtr = (msg.flags & 2) != 0; + frame.dlc = msg.data_length_code; + if (msg.data_length_code > 0) + frame.data[0 .. msg.data_length_code] = msg.data[0 .. msg.data_length_code]; + return true; +} + +CanError can_hw_check_errors(uint port) +{ + if (port >= num_can || _handles[port] is null) + return CanError.none; + uint alerts; + twai_read_alerts_v2(_handles[port], &alerts, 0); + CanError err = CanError.none; + if (alerts & 0x0200) // TWAI_ALERT_BUS_ERROR + err |= CanError.bit; + if (alerts & 0x4800) // TWAI_ALERT_RX_FIFO_OVERRUN | RX_QUEUE_FULL + err |= CanError.overrun; + if (alerts & 0x0400) // TWAI_ALERT_TX_FAILED + err |= CanError.ack; + return err; +} + +CanBusState can_hw_bus_state(uint port) +{ + if (port >= num_can || _handles[port] is null) + return CanBusState.bus_off; + twai_status_info_t info; + if (twai_get_status_info_v2(_handles[port], &info) != ESP_OK) + return CanBusState.bus_off; + if (info.state >= 2) // BUS_OFF or RECOVERING + return CanBusState.bus_off; + if (info.tx_error_counter >= 128 || info.rx_error_counter >= 128) + return CanBusState.error_passive; + if (info.tx_error_counter >= 96 || info.rx_error_counter >= 96) + return CanBusState.error_warning; + return CanBusState.error_active; +} + +ubyte can_hw_tx_error_count(uint port) +{ + if (port >= num_can || _handles[port] is null) + return 0; + twai_status_info_t info; + if (twai_get_status_info_v2(_handles[port], &info) != ESP_OK) + return 0; + return info.tx_error_counter > 255 ? 255 : cast(ubyte)info.tx_error_counter; +} + +ubyte can_hw_rx_error_count(uint port) +{ + if (port >= num_can || _handles[port] is null) + return 0; + twai_status_info_t info; + if (twai_get_status_info_v2(_handles[port], &info) != ESP_OK) + return 0; + return info.rx_error_counter > 255 ? 255 : cast(ubyte)info.rx_error_counter; +} + +size_t can_hw_rx_available(uint port) +{ + if (port >= num_can || _handles[port] is null) + return 0; + twai_status_info_t info; + if (twai_get_status_info_v2(_handles[port], &info) != ESP_OK) + return 0; + return cast(size_t)info.msgs_to_rx; +} + +void can_hw_rx_flush(uint port) +{ + if (port >= num_can || _handles[port] is null) + return; + twai_clear_receive_queue_v2(_handles[port]); +} + +void can_hw_tx_abort(uint port) +{ + if (port >= num_can || _handles[port] is null) + return; + twai_clear_transmit_queue_v2(_handles[port]); +} + +bool can_hw_bus_recover(uint port) +{ + if (port >= num_can || _handles[port] is null) + return false; + return twai_initiate_recovery_v2(_handles[port]) == ESP_OK; +} + +void can_hw_poll(uint port) +{ + // TWAI driver buffers RX internally +} + + +private: + +enum int ESP_OK = 0; + +// Opaque ESP-IDF TWAI handle +struct twai_obj_t {} +alias twai_handle_t = twai_obj_t*; + +// ESP-IDF twai_message_t (flags union flattened to uint) +struct twai_message_t +{ + uint flags; // bit 0: extd, bit 1: rtr, bit 2: ss, bit 3: self + uint identifier; + ubyte data_length_code; + ubyte[8] data; +} + +// ESP-IDF twai_status_info_t +struct twai_status_info_t +{ + int state; // 0=STOPPED, 1=RUNNING, 2=BUS_OFF, 3=RECOVERING + uint msgs_to_tx; + uint msgs_to_rx; + uint tx_error_counter; + uint rx_error_counter; + uint tx_failed_count; + uint rx_missed_count; + uint rx_overrun_count; + uint arb_lost_count; + uint bus_error_count; +} + +__gshared twai_handle_t[num_can] _handles; + +extern(C) nothrow @nogc +{ + // Shim -- bitrate table + config construction + install + start + twai_handle_t ow_can_open(uint port, uint bitrate, int tx_gpio, int rx_gpio, ubyte sjw, ubyte tseg1, ubyte tseg2, ushort brp); + + // Direct ESP-IDF v2 calls + int twai_stop_v2(twai_handle_t handle); + int twai_driver_uninstall_v2(twai_handle_t handle); + int twai_transmit_v2(twai_handle_t handle, const(twai_message_t)* message, uint ticks_to_wait); + int twai_receive_v2(twai_handle_t handle, twai_message_t* message, uint ticks_to_wait); + int twai_read_alerts_v2(twai_handle_t handle, uint* alerts, uint ticks_to_wait); + int twai_get_status_info_v2(twai_handle_t handle, twai_status_info_t* status_info); + int twai_initiate_recovery_v2(twai_handle_t handle); + int twai_clear_receive_queue_v2(twai_handle_t handle); + int twai_clear_transmit_queue_v2(twai_handle_t handle); +} diff --git a/src/urt/driver/esp32/exception.d b/src/urt/driver/esp32/exception.d new file mode 100644 index 0000000..b639efc --- /dev/null +++ b/src/urt/driver/esp32/exception.d @@ -0,0 +1,85 @@ +/// Espressif (ESP-IDF + FreeRTOS) exception driver. +/// +/// Stack-trace capture uses libgcc's `_Unwind_Backtrace` (pulled in +/// by the ESP-IDF toolchain). No on-device symbol resolution - +/// decode addresses offline with `xtensa-esp32-elf-addr2line` / +/// `riscv32-esp-elf-addr2line`. +module urt.driver.esp32.exception; + +version (Espressif): + +import urt.internal.exception : Resolved; + +nothrow @nogc: + + +// --- libgcc unwind bindings ------------------------------------------ + +private alias _Unwind_Trace_Fn = extern(C) int function(void* ctx, void* data) nothrow @nogc; +extern(C) private int _Unwind_Backtrace(_Unwind_Trace_Fn, void*) nothrow @nogc; +extern(C) private size_t _Unwind_GetIP(void*) nothrow @nogc; + + +// --- Driver interface ------------------------------------------------ + +// Capture the caller's call stack. First entry = return address of +// the function that called the public `capture_trace` wrapper. +size_t _capture_trace(void*[] addrs) @trusted +{ + if (addrs.length == 0) + return 0; + + struct State + { + void*[] out_addrs; + size_t count; + ubyte skip; + } + + extern(C) static int callback(void* ctx, void* data) nothrow @nogc + { + auto s = cast(State*) data; + if (s.skip > 0) { --s.skip; return 0; } + if (s.count >= s.out_addrs.length) return 1; + auto ip = _Unwind_GetIP(ctx); + if (!ip) return 1; + s.out_addrs[s.count++] = cast(void*) ip; + return 0; + } + + // Skip 2 frames: _Unwind_Backtrace's direct caller (_capture_trace + // itself) + the public wrapper in urt.internal.exception. + State state = State(addrs, 0, 2); + _Unwind_Backtrace(&callback, &state); + return state.count; +} + +// Return the return address of the `skip`-th frame above the public +// `caller_address` wrapper's caller. +void* _caller_address(uint skip) @trusted +{ + void*[32] buf = void; + const n = _capture_trace(buf[]); + // When _capture_trace is reached via _caller_address, _Unwind already + // skipped 2 (itself + wrapper) - but those skips were sized for the + // direct-call path. From _caller_address the buffer layout is: + // buf[0] = PC inside _caller_address (an extra intermediate) + // buf[1] = PC inside USER + // buf[2] = PC inside USER's caller ← skip=0 wants this + const want = skip + 2; + if (n <= want) + return null; + return buf[want]; +} + +// No on-device symbol table. Decode offline with addr2line. +bool _resolve_address(void* addr, out Resolved r) @trusted +{ + return false; +} + +// No on-device symbols - caller should treat `results[]` as empty. +bool _resolve_batch(const(void*)[], Resolved[]) @trusted +{ + return false; +} diff --git a/src/urt/driver/esp32/gpio.d b/src/urt/driver/esp32/gpio.d new file mode 100644 index 0000000..2869195 --- /dev/null +++ b/src/urt/driver/esp32/gpio.d @@ -0,0 +1,75 @@ +// ESP32 software GPIO via ESP-IDF (driver/gpio.h) through ow_shim.c. +// +// Peripheral function routing on ESP32 uses the GPIO matrix per-signal, +// not per-pin function selection, so has_pin_function_muxing = false +// and gpio_set_function is not provided. Peripheral drivers (UART, SPI, +// I2C, etc.) route their own signals via the IDF. +// +// Pin numbering: linear 0..SOC_GPIO_PIN_COUNT-1. The compile-time +// num_gpio is a conservative upper bound; gpio_count() returns the +// actual SOC_GPIO_PIN_COUNT for the active chip variant. +module urt.driver.esp32.gpio; + +import urt.driver.gpio : Pull, DriveMode; + +nothrow @nogc: + + +enum uint num_gpio = 64; +enum bool has_pull_up = true; +enum bool has_pull_down = true; +enum bool has_open_drain = false; +enum bool has_pin_function_muxing = false; + + +uint gpio_count() => ow_gpio_count(); + +void gpio_output_init(uint pin, bool initial = false, DriveMode mode = DriveMode.push_pull) +{ + assert(mode == DriveMode.push_pull, "esp32 gpio: open-drain not exposed via this API"); + ow_gpio_output_init(int(pin), initial ? 1 : 0); +} + +void gpio_input_init(uint pin, Pull pull = Pull.none) +{ + ow_gpio_input_init(int(pin), int(pull)); +} + +void gpio_output_set(uint pin, bool value) +{ + ow_gpio_output_set(int(pin), value ? 1 : 0); +} + +void gpio_output_toggle(uint pin) +{ + ow_gpio_output_set(int(pin), ow_gpio_input_read(int(pin)) ? 0 : 1); +} + +bool gpio_input_read(uint pin) +{ + return ow_gpio_input_read(int(pin)) != 0; +} + +void gpio_set_pull(uint pin, Pull pull) +{ + ow_gpio_set_pull(int(pin), int(pull)); +} + +void gpio_release(uint pin) +{ + ow_gpio_release(int(pin)); +} + + +private: + +extern(C) nothrow @nogc +{ + void ow_gpio_output_init(int pin, int initial); + void ow_gpio_input_init(int pin, int pull); + void ow_gpio_output_set(int pin, int value); + int ow_gpio_input_read(int pin); + void ow_gpio_set_pull(int pin, int pull); + void ow_gpio_release(int pin); + uint ow_gpio_count(); +} diff --git a/src/urt/driver/esp32/irq.d b/src/urt/driver/esp32/irq.d new file mode 100644 index 0000000..de4a83f --- /dev/null +++ b/src/urt/driver/esp32/irq.d @@ -0,0 +1,71 @@ +// ESP32 interrupt controller driver +// +// ESP-IDF manages interrupts via esp_intr_alloc(). Direct vector table +// access is discouraged since FreeRTOS owns it. Global disable/enable +// uses the FreeRTOS portMUX-based critical section directly. +module urt.driver.esp32.irq; + +import urt.internal.sys.freertos : portMUX_TYPE, portMUX_FREE_VAL, vPortEnterCritical, vPortExitCritical; + +nothrow @nogc: + + +enum bool has_plic = false; +enum bool has_nvic = false; +enum bool has_clic = false; +enum bool has_per_irq_control = false; // TODO: wire up esp_intr_alloc +enum bool has_irq_priority = false; // TODO: wire up esp_intr_alloc priority flags +enum bool has_wait_for_interrupt = true; +enum bool has_irq_diagnostics = false; + +// FreeRTOS critical sections are recursive (portENTER nests with a per-mux +// counter), so the return value is not a meaningful "prior global IRQ" bit +// the way it is on bare-metal. Callers must pair enter/exit, and IrqGuard +// does -- we always claim "was enabled" so the guard unconditionally exits. +enum bool has_global_irq_state = false; +enum bool has_smp = false; +enum uint irq_max = 32; + +bool irq_disable() +{ + vPortEnterCritical(&_irq_mux); + return true; +} + +bool irq_enable() +{ + vPortExitCritical(&_irq_mux); + return true; +} + +bool irq_set_enable(uint irq) +{ + assert(false, "TODO: use esp_intr_alloc"); +} + +bool irq_clear_enable(uint irq) +{ + assert(false, "TODO: use esp_intr_free"); +} + +void irq_set_priority(uint irq, ubyte priority) +{ + assert(false, "TODO: use esp_intr_set_in_iram / priority flags"); +} + +void wait_for_interrupt() +{ + ow_irq_wait(); +} + + +private: + +// Single global mux serves as the IRQ-disable lock. portENTER_CRITICAL +// is reentrant via the mux's internal count, so nested IrqGuards compose. +__gshared portMUX_TYPE _irq_mux = portMUX_TYPE(portMUX_FREE_VAL, 0); + +// wait_for_interrupt remains a C shim -- it's per-arch inline asm +// (waiti on Xtensa, wfi on RISC-V) that doesn't fit cleanly in a D +// binding. +extern(C) void ow_irq_wait() nothrow @nogc; diff --git a/src/urt/driver/esp32/main.c b/src/urt/driver/esp32/main.c new file mode 100644 index 0000000..14f350b --- /dev/null +++ b/src/urt/driver/esp32/main.c @@ -0,0 +1,57 @@ +// OpenWatt ESP-IDF entry point. +// ESP-IDF calls app_main() after FreeRTOS scheduler starts. +// .init_array (D module constructors) are called automatically by +// ESP-IDF startup before app_main, so we just call D's main(). + +#include "esp_event.h" +#include "nvs_flash.h" +#include "esp_task_wdt.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#ifdef OW_USE_LWIP +#include "esp_netif.h" +#endif + +extern int main(int argc, char **argv); + +void ow_watchdog_feed(void) +{ + esp_task_wdt_reset(); +} + +void app_main(void) +{ + // Initialize NVS -- required by WiFi for calibration data storage. + esp_err_t ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) + { + nvs_flash_erase(); + nvs_flash_init(); + } + + // Event loop is required for WIFI_EVENT delivery. + esp_event_loop_create_default(); + +#ifdef OW_USE_LWIP + // Bring up lwIP early -- D code may open sockets during startup before + // any WiFi/Ethernet interface is created. + esp_netif_init(); +#endif + + // Delay so early boot logs are visible on USB Serial/JTAG. + vTaskDelay(pdMS_TO_TICKS(500)); + + // Configure task watchdog: 5s timeout, panic+backtrace-dump on trigger. + // ESP-IDF may have already initialised the WDT for idle tasks; in that + // case reconfigure to apply our settings. + esp_task_wdt_config_t wdt_config = { + .timeout_ms = 5000, + .idle_core_mask = 0, + .trigger_panic = true, + }; + if (esp_task_wdt_init(&wdt_config) == ESP_ERR_INVALID_STATE) + esp_task_wdt_reconfigure(&wdt_config); + esp_task_wdt_add(NULL); + + main(0, (char **)0); +} diff --git a/src/urt/driver/esp32/ow_shim.c b/src/urt/driver/esp32/ow_shim.c new file mode 100644 index 0000000..6b21be7 --- /dev/null +++ b/src/urt/driver/esp32/ow_shim.c @@ -0,0 +1,675 @@ +// OpenWatt ESP-IDF shim -- the single C bridge between D and ESP-IDF. +// Wraps FreeRTOS macros, UART HAL inlines, and anything else that +// needs C headers or static-inline access. + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "hal/uart_hal.h" +#include "hal/uart_types.h" +#include "hal/uart_periph.h" +#include "esp_rom_gpio.h" +#include "esp_rom_serial_output.h" +#ifdef OW_USE_LWIP +#include "lwip/netdb.h" +#endif + +// ESP32-C3 ROM exports uart_tx_one_char but not esp_rom_uart_putc. +// Provide the missing symbol so the D object links. +#if defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(esp_rom_uart_putc) +void esp_rom_uart_putc(char c) { esp_rom_output_tx_one_char(c); } +#endif + +// -- errno accessor (picolibc uses _Thread_local errno, incompatible with emulated-TLS) -- + +#include + +int *ow_errno_location(void) +{ + return &errno; +} + +// -- WFI shim -- +// Single-instruction inline asm; bound from D as ow_irq_wait. The +// surrounding portENTER_CRITICAL pair is handled D-side via direct +// vPortEnterCritical/vPortExitCritical bindings -- no C wrapper needed. + +void ow_irq_wait(void) +{ +#if CONFIG_IDF_TARGET_ARCH_XTENSA + __asm__ volatile("waiti 0"); +#elif CONFIG_IDF_TARGET_ARCH_RISCV + __asm__ volatile("wfi"); +#endif +} + +// -- GPIO wrappers (software GPIO; peripheral function routing goes +// through ESP-IDF's signal matrix on a per-peripheral basis, not +// through this module). + +#include "driver/gpio.h" +#include "soc/gpio_num.h" + +// pull: 0=none, 1=up, 2=down (matches D Pull enum encoding) +static gpio_pull_mode_t ow_pull_to_idf(int pull) +{ + return (pull == 1) ? GPIO_PULLUP_ONLY : + (pull == 2) ? GPIO_PULLDOWN_ONLY : GPIO_FLOATING; +} + +void ow_gpio_output_init(int pin, int initial) +{ + gpio_reset_pin((gpio_num_t)pin); + gpio_set_direction((gpio_num_t)pin, GPIO_MODE_OUTPUT); + gpio_set_level((gpio_num_t)pin, initial); +} + +void ow_gpio_input_init(int pin, int pull) +{ + gpio_reset_pin((gpio_num_t)pin); + gpio_set_direction((gpio_num_t)pin, GPIO_MODE_INPUT); + gpio_set_pull_mode((gpio_num_t)pin, ow_pull_to_idf(pull)); +} + +void ow_gpio_output_set(int pin, int value) +{ + gpio_set_level((gpio_num_t)pin, value); +} + +int ow_gpio_input_read(int pin) +{ + return gpio_get_level((gpio_num_t)pin); +} + +void ow_gpio_set_pull(int pin, int pull) +{ + gpio_set_pull_mode((gpio_num_t)pin, ow_pull_to_idf(pull)); +} + +void ow_gpio_release(int pin) +{ + gpio_reset_pin((gpio_num_t)pin); +} + +uint32_t ow_gpio_count(void) +{ + return SOC_GPIO_PIN_COUNT; +} + + +// -- UART HAL wrappers -- + +#include "soc/soc_caps.h" +#include "hal/uart_ll.h" +#include "esp_private/periph_ctrl.h" +#define NUM_UARTS SOC_UART_NUM + +static uart_hal_context_t uart_ctx[NUM_UARTS]; +static bool uart_initialized[NUM_UARTS]; + +// D enums: StopBits { half=0, one=1, one_point_five=2, two=3 } +// Parity { none=0, even=1, odd=2, mark=3, space=4 } +// HAL enums: UART_STOP_BITS_1=1, _1_5=2, _2=3 +// UART_PARITY_DISABLE=0, _EVEN=2, _ODD=3 +static const uart_stop_bits_t stop_bits_map[] = { + UART_STOP_BITS_1, UART_STOP_BITS_1, UART_STOP_BITS_1_5, UART_STOP_BITS_2 +}; +static const uart_parity_t parity_map[] = { + UART_PARITY_DISABLE, UART_PARITY_EVEN, UART_PARITY_ODD, + UART_PARITY_DISABLE, UART_PARITY_DISABLE +}; + +int ow_uart_open(unsigned port, uint32_t baud_rate, uint8_t data_bits, + uint8_t stop_bits, uint8_t parity, + int8_t tx_gpio, int8_t rx_gpio) +{ + if (port >= NUM_UARTS) + return 0; + + // Enable peripheral clock before touching any registers + PERIPH_RCC_ATOMIC() + { + uart_ll_enable_bus_clock(port, true); + uart_ll_reset_register(port); + } + + // Set device pointer before calling hal_init (v6 API expects it pre-set) + uart_ctx[port].dev = UART_LL_GET_HW(port); + uart_hal_init(&uart_ctx[port], port); + + int __DECLARE_RCC_ATOMIC_ENV __attribute__((unused)); + uart_ll_set_sclk(uart_ctx[port].dev, UART_SCLK_DEFAULT); + uart_ll_set_baudrate(uart_ctx[port].dev, baud_rate, 80000000); + uart_ll_set_data_bit_num(uart_ctx[port].dev, data_bits - 5); + uart_ll_set_stop_bits(uart_ctx[port].dev, stop_bits < sizeof(stop_bits_map) ? stop_bits_map[stop_bits] : 1); + uart_ll_set_parity(uart_ctx[port].dev, parity < sizeof(parity_map)/sizeof(parity_map[0]) ? parity_map[parity] : UART_PARITY_DISABLE); + + uart_hal_rxfifo_rst(&uart_ctx[port]); + uart_hal_txfifo_rst(&uart_ctx[port]); + + // GPIO pin routing -- UART0 defaults (TX=43, RX=44) set by bootloader. + // For non-default pins or UART1/2, route via GPIO matrix. + if (tx_gpio >= 0) + { + esp_rom_gpio_pad_select_gpio(tx_gpio); + esp_rom_gpio_connect_out_signal(tx_gpio, + uart_periph_signal[port].pins[SOC_UART_PERIPH_SIGNAL_TX].signal, false, false); + } + if (rx_gpio >= 0) + { + esp_rom_gpio_pad_select_gpio(rx_gpio); + esp_rom_gpio_pad_pullup_only(rx_gpio); + esp_rom_gpio_connect_in_signal(rx_gpio, + uart_periph_signal[port].pins[SOC_UART_PERIPH_SIGNAL_RX].signal, false); + } + + uart_initialized[port] = true; + return 1; +} + +void ow_uart_close(unsigned port) +{ + if (port >= NUM_UARTS || !uart_initialized[port]) + return; + uart_hal_txfifo_rst(&uart_ctx[port]); + uart_hal_rxfifo_rst(&uart_ctx[port]); + PERIPH_RCC_ATOMIC() + { + uart_ll_enable_bus_clock(port, false); + } + uart_initialized[port] = false; +} + +int32_t ow_uart_read(unsigned port, uint8_t *buf, int32_t len) +{ + if (port >= NUM_UARTS || !uart_initialized[port]) + return 0; + int rd_len = (int)len; + uart_hal_read_rxfifo(&uart_ctx[port], buf, &rd_len); + return rd_len; +} + +int32_t ow_uart_write(unsigned port, const uint8_t *buf, int32_t len) +{ + if (port >= NUM_UARTS || !uart_initialized[port]) + return 0; + uint32_t written = 0; + uart_hal_write_txfifo(&uart_ctx[port], buf, (uint32_t)len, &written); + return (int32_t)written; +} + +int32_t ow_uart_rx_pending(unsigned port) +{ + if (port >= NUM_UARTS || !uart_initialized[port]) + return 0; + return (int32_t)uart_ll_get_rxfifo_len(uart_ctx[port].dev); +} + +int ow_uart_tx_idle(unsigned port) +{ + if (port >= NUM_UARTS || !uart_initialized[port]) + return 1; + return uart_ll_is_tx_idle(uart_ctx[port].dev) ? 1 : 0; +} + +int32_t ow_uart_flush(unsigned port) +{ + if (port >= NUM_UARTS || !uart_initialized[port]) + return 0; + while (!uart_ll_is_tx_idle(uart_ctx[port].dev)) + {} + return 0; +} + +// -- WiFi wrappers -- + +#if CONFIG_ESP_WIFI_ENABLED +#include "esp_wifi.h" +#include "esp_private/wifi.h" +#include "esp_event.h" +#include "esp_mac.h" + +static int ow_wifi_refcount; + +#ifdef OW_USE_LWIP +#include "esp_netif.h" + +static esp_netif_t *ow_wifi_netif_sta; +static esp_netif_t *ow_wifi_netif_ap; +#endif + +typedef void (*ow_wifi_event_cb_t)(int event_id, void *data, int data_len); + +static ow_wifi_event_cb_t ow_wifi_sta_cb; +static ow_wifi_event_cb_t ow_wifi_ap_cb; + +static void ow_wifi_event_handler(void *arg, esp_event_base_t base, int32_t event_id, void *event_data) +{ + if (base == WIFI_EVENT) + { + int data_len = 0; + if (event_id == WIFI_EVENT_STA_DISCONNECTED && event_data) + data_len = ((wifi_event_sta_disconnected_t *)event_data)->reason; + + switch (event_id) + { + case WIFI_EVENT_STA_CONNECTED: + case WIFI_EVENT_STA_DISCONNECTED: + case WIFI_EVENT_STA_START: + case WIFI_EVENT_STA_STOP: + if (ow_wifi_sta_cb) + ow_wifi_sta_cb(event_id, event_data, data_len); + break; + + case WIFI_EVENT_AP_START: + case WIFI_EVENT_AP_STOP: + case WIFI_EVENT_AP_STACONNECTED: + case WIFI_EVENT_AP_STADISCONNECTED: + if (ow_wifi_ap_cb) + ow_wifi_ap_cb(event_id, event_data, 0); + break; + } + } +#ifdef OW_USE_LWIP + else if (base == IP_EVENT) + { + if (event_id == IP_EVENT_STA_GOT_IP && ow_wifi_sta_cb) + ow_wifi_sta_cb(event_id, event_data, 0); + } +#endif +} + +int ow_wifi_init(void) +{ + if (ow_wifi_refcount++ > 0) + return 0; + + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + esp_err_t err = esp_wifi_init(&cfg); + if (err != ESP_OK) + { + ow_wifi_refcount--; + return (int)err; + } + + esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &ow_wifi_event_handler, NULL); + +#ifdef OW_USE_LWIP + // Create netifs before RX callbacks fire, so esp_netif_receive() has valid targets. + if (!ow_wifi_netif_sta) + ow_wifi_netif_sta = esp_netif_create_default_wifi_sta(); + if (!ow_wifi_netif_ap) + ow_wifi_netif_ap = esp_netif_create_default_wifi_ap(); + esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &ow_wifi_event_handler, NULL); +#endif + + return 0; +} + +void ow_wifi_deinit(void) +{ + if (--ow_wifi_refcount > 0) + return; + + esp_wifi_stop(); + esp_wifi_deinit(); + +#ifdef OW_USE_LWIP + if (ow_wifi_netif_sta) + { + esp_netif_destroy(ow_wifi_netif_sta); + ow_wifi_netif_sta = NULL; + } + if (ow_wifi_netif_ap) + { + esp_netif_destroy(ow_wifi_netif_ap); + ow_wifi_netif_ap = NULL; + } +#endif +} + +int ow_wifi_sta_config(const char *ssid, const char *password, const uint8_t *bssid) +{ + wifi_config_t cfg = {0}; + if (ssid) + { + size_t len = strlen(ssid); + if (len > sizeof(cfg.sta.ssid) - 1) len = sizeof(cfg.sta.ssid) - 1; + memcpy(cfg.sta.ssid, ssid, len); + } + if (password) + { + size_t len = strlen(password); + if (len > sizeof(cfg.sta.password) - 1) len = sizeof(cfg.sta.password) - 1; + memcpy(cfg.sta.password, password, len); + } + if (bssid) + { + memcpy(cfg.sta.bssid, bssid, 6); + cfg.sta.bssid_set = true; + } + + return esp_wifi_set_config(WIFI_IF_STA, &cfg) == ESP_OK ? 1 : 0; +} + +int ow_wifi_ap_config(const char *ssid, const char *password, uint8_t channel, uint8_t max_conn, uint8_t hidden) +{ + wifi_config_t cfg = {0}; + if (ssid) + { + size_t len = strlen(ssid); + if (len > sizeof(cfg.ap.ssid) - 1) len = sizeof(cfg.ap.ssid) - 1; + memcpy(cfg.ap.ssid, ssid, len); + cfg.ap.ssid_len = (uint8_t)len; + } + if (password) + { + size_t len = strlen(password); + if (len > sizeof(cfg.ap.password) - 1) len = sizeof(cfg.ap.password) - 1; + memcpy(cfg.ap.password, password, len); + cfg.ap.authmode = (len > 0) ? WIFI_AUTH_WPA2_PSK : WIFI_AUTH_OPEN; + } + else + cfg.ap.authmode = WIFI_AUTH_OPEN; + + cfg.ap.channel = channel; + cfg.ap.max_connection = max_conn > 0 ? max_conn : 4; + cfg.ap.ssid_hidden = hidden; + + return esp_wifi_set_config(WIFI_IF_AP, &cfg) == ESP_OK ? 1 : 0; +} + +int ow_wifi_ap_set_max_clients(uint8_t max_conn) +{ + wifi_config_t cfg = {0}; + + if (esp_wifi_get_config(WIFI_IF_AP, &cfg) != ESP_OK) + return 0; + + cfg.ap.max_connection = max_conn > 0 ? max_conn : 4; + return esp_wifi_set_config(WIFI_IF_AP, &cfg) == ESP_OK ? 1 : 0; +} + +// Ethernet frame RX callbacks -- one per netif (STA=0, AP=1). +// esp_wifi_internal_reg_rxcb gives us raw Ethernet frames before lwIP, +// so the bridge/routing layer sees all traffic. + +typedef void (*ow_wifi_rx_cb_t)(const uint8_t *data, int len, int iface); + +static ow_wifi_rx_cb_t ow_wifi_rx_callback; + +static esp_err_t ow_wifi_sta_rx(void *buffer, uint16_t len, void *eb) +{ + if (ow_wifi_rx_callback) + ow_wifi_rx_callback((const uint8_t *)buffer, len, 0); +#ifdef OW_USE_LWIP + return esp_netif_receive(ow_wifi_netif_sta, buffer, len, eb); +#else + // Internal stack consumes via ow_wifi_rx_callback; we own the eb buffer + // (esp_netif_receive normally frees it). + if (eb) + esp_wifi_internal_free_rx_buffer(eb); + return ESP_OK; +#endif +} + +static esp_err_t ow_wifi_ap_rx(void *buffer, uint16_t len, void *eb) +{ + if (ow_wifi_rx_callback) + ow_wifi_rx_callback((const uint8_t *)buffer, len, 1); +#ifdef OW_USE_LWIP + return esp_netif_receive(ow_wifi_netif_ap, buffer, len, eb); +#else + if (eb) + esp_wifi_internal_free_rx_buffer(eb); + return ESP_OK; +#endif +} + +int ow_wifi_set_rx_callback(ow_wifi_rx_cb_t cb) +{ + ow_wifi_rx_callback = cb; + esp_err_t err; + err = esp_wifi_internal_reg_rxcb(WIFI_IF_STA, cb ? &ow_wifi_sta_rx : NULL); + if (err != ESP_OK) + return 0; + err = esp_wifi_internal_reg_rxcb(WIFI_IF_AP, cb ? &ow_wifi_ap_rx : NULL); + return err == ESP_OK ? 1 : 0; +} + +void ow_wifi_set_sta_callback(ow_wifi_event_cb_t cb) +{ + ow_wifi_sta_cb = cb; +} + +void ow_wifi_set_ap_callback(ow_wifi_event_cb_t cb) +{ + ow_wifi_ap_cb = cb; +} + +// Promiscuous (monitor) mode wrappers. ESP-IDF's promiscuous mode coexists +// with STA/AP -- the radio's channel is what they all share. The callback +// fires for every 802.11 frame the radio decodes, including frames with +// FCS errors when the FCSFAIL filter bit is set. + +typedef void (*ow_wifi_promisc_cb_t)(int type, int rssi, int channel, + int rate, int fcs_fail, int len, + const uint8_t *payload); + +static ow_wifi_promisc_cb_t ow_wifi_promisc_callback; + +static void ow_wifi_promisc_trampoline(void *buf, wifi_promiscuous_pkt_type_t type) +{ + if (!ow_wifi_promisc_callback || !buf) + return; + const wifi_promiscuous_pkt_t *pkt = (const wifi_promiscuous_pkt_t *)buf; + const wifi_pkt_rx_ctrl_t *rx = &pkt->rx_ctrl; + ow_wifi_promisc_callback((int)type, (int)rx->rssi, (int)rx->channel, + (int)rx->rate, (int)rx->rx_state, (int)rx->sig_len, + pkt->payload); +} + +void ow_wifi_set_promiscuous_callback(ow_wifi_promisc_cb_t cb) +{ + ow_wifi_promisc_callback = cb; + esp_wifi_set_promiscuous_rx_cb(cb ? &ow_wifi_promisc_trampoline : NULL); +} + +int ow_wifi_set_promiscuous(int enable, uint32_t filter_mask) +{ + if (enable) + { + wifi_promiscuous_filter_t filt = { .filter_mask = filter_mask }; + esp_wifi_set_promiscuous_filter(&filt); + } + return esp_wifi_set_promiscuous(enable ? true : false) == ESP_OK ? 1 : 0; +} + +int ow_wifi_set_channel(int primary, int secondary) +{ + return esp_wifi_set_channel((uint8_t)primary, + (wifi_second_chan_t)secondary) == ESP_OK ? 1 : 0; +} + +// Inject a raw 802.11 frame. ifx selects WIFI_IF_STA (0) or WIFI_IF_AP (1). +// en_sys_seq=true lets the MAC fill the sequence number; the caller can +// still set destination/source MACs and frame control. Used by monitor-mode +// injection paths. +int ow_wifi_raw_tx(int ifx, const uint8_t *frame, int len, int en_sys_seq) +{ + return esp_wifi_80211_tx((wifi_interface_t)ifx, frame, len, + en_sys_seq ? true : false) == ESP_OK ? 1 : 0; +} +#else // !CONFIG_ESP_WIFI_ENABLED + +typedef void (*ow_wifi_event_cb_t)(int, void *, int); +typedef void (*ow_wifi_rx_cb_t)(const uint8_t *, int, int); +typedef void (*ow_wifi_promisc_cb_t)(int, int, int, int, int, int, const uint8_t *); + +int ow_wifi_init(void) { return -1; } +void ow_wifi_deinit(void) {} +int ow_wifi_sta_config(const char *s, const char *p, const uint8_t *b) { (void)s;(void)p;(void)b; return 0; } +int ow_wifi_ap_config(const char *s, const char *p, uint8_t c, uint8_t m, uint8_t h) { (void)s;(void)p;(void)c;(void)m;(void)h; return 0; } +int ow_wifi_ap_set_max_clients(uint8_t m) { (void)m; return 0; } +int ow_wifi_set_rx_callback(ow_wifi_rx_cb_t cb) { (void)cb; return 0; } +void ow_wifi_set_sta_callback(ow_wifi_event_cb_t cb) { (void)cb; } +void ow_wifi_set_ap_callback(ow_wifi_event_cb_t cb) { (void)cb; } +int ow_wifi_set_promiscuous(int enable, uint32_t filter_mask) { (void)enable;(void)filter_mask; return 0; } +void ow_wifi_set_promiscuous_callback(ow_wifi_promisc_cb_t cb) { (void)cb; } +int ow_wifi_set_channel(int p, int s) { (void)p;(void)s; return 0; } +int ow_wifi_raw_tx(int ifx, const uint8_t *frame, int len, int en) { (void)ifx;(void)frame;(void)len;(void)en; return 0; } + +#endif // CONFIG_ESP_WIFI_ENABLED + +// -- BLE (NimBLE) wrappers -- + +#if CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ENABLED +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" +#include "host/ble_hs.h" +#include "host/ble_gap.h" + +typedef int (*ow_gap_event_cb_t)(struct ble_gap_event *, void *); +static ow_gap_event_cb_t ow_gap_callback; + +static int ow_gap_event_dispatch(struct ble_gap_event *event, void *arg) +{ + if (ow_gap_callback) + return ow_gap_callback(event, arg); + return 0; +} + +static void ow_nimble_host_task(void *param) +{ + (void)param; + nimble_port_run(); + nimble_port_freertos_deinit(); +} + +int ow_ble_init(void) +{ + int rc = nimble_port_init(); + if (rc != 0) + return rc; + nimble_port_freertos_init(ow_nimble_host_task); + return 0; +} + +void ow_ble_deinit(void) +{ + nimble_port_stop(); + nimble_port_deinit(); +} + +void ow_ble_set_gap_callback(ow_gap_event_cb_t cb) +{ + ow_gap_callback = cb; +} + +#else // !BT_NIMBLE + +typedef int (*ow_gap_event_cb_t)(void *, void *); + +int ow_ble_init(void) { return -1; } +void ow_ble_deinit(void) {} +void ow_ble_set_gap_callback(ow_gap_event_cb_t cb) { (void)cb; } + +#endif // CONFIG_BT_NIMBLE_ENABLED + +// -- CAN (TWAI) driver -- +// +// Only ow_can_open lives here -- it builds the timing/general/filter config +// structs and does install+start. Everything else is called directly from D +// via the ESP-IDF _v2 handle API. + +#include "soc/soc_caps.h" +#if SOC_TWAI_SUPPORTED +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcpp" +#include "driver/twai.h" +#pragma GCC diagnostic pop + +twai_handle_t ow_can_open(unsigned port, uint32_t bitrate, int tx_gpio, int rx_gpio, uint8_t sjw, uint8_t tseg1, uint8_t tseg2, uint16_t brp) +{ + if (port >= SOC_TWAI_CONTROLLER_NUM) + return NULL; + + twai_timing_config_t timing; + if (brp > 0) + { + memset(&timing, 0, sizeof(timing)); + timing.clk_src = TWAI_CLK_SRC_DEFAULT; + timing.brp = brp; + timing.tseg_1 = tseg1; + timing.tseg_2 = tseg2; + timing.sjw = sjw; + } + else + { + switch (bitrate) + { + case 1000: timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_1KBITS(); break; + case 5000: timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_5KBITS(); break; + case 10000: timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_10KBITS(); break; + case 12500: timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_12_5KBITS(); break; + case 16000: timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_16KBITS(); break; + case 20000: timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_20KBITS(); break; + case 25000: timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_25KBITS(); break; + case 50000: timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_50KBITS(); break; + case 100000: timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_100KBITS(); break; + case 125000: timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_125KBITS(); break; + case 250000: timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_250KBITS(); break; + case 500000: timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_500KBITS(); break; + case 800000: timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_800KBITS(); break; + case 1000000: timing = (twai_timing_config_t)TWAI_TIMING_CONFIG_1MBITS(); break; + default: return NULL; + } + } + + twai_general_config_t general = TWAI_GENERAL_CONFIG_DEFAULT_V2( + port, tx_gpio, rx_gpio, TWAI_MODE_NORMAL); + general.alerts_enabled = TWAI_ALERT_BUS_ERROR | TWAI_ALERT_ERR_PASS + | TWAI_ALERT_ERR_ACTIVE | TWAI_ALERT_BUS_OFF | TWAI_ALERT_ABOVE_ERR_WARN + | TWAI_ALERT_BELOW_ERR_WARN | TWAI_ALERT_RX_FIFO_OVERRUN + | TWAI_ALERT_RX_QUEUE_FULL | TWAI_ALERT_ARB_LOST | TWAI_ALERT_TX_FAILED; + twai_filter_config_t filter = TWAI_FILTER_CONFIG_ACCEPT_ALL(); + + twai_handle_t handle = NULL; + if (twai_driver_install_v2(&general, &timing, &filter, &handle) != ESP_OK) + return NULL; + + if (twai_start_v2(handle) != ESP_OK) + { + twai_driver_uninstall_v2(handle); + return NULL; + } + + return handle; +} + +#else // !SOC_TWAI_SUPPORTED + +typedef struct twai_obj_t *twai_handle_t; + +twai_handle_t ow_can_open(unsigned, uint32_t, int, int, uint8_t, uint8_t, uint8_t, uint16_t) +{ + return (twai_handle_t)0; +} + +#endif // SOC_TWAI_SUPPORTED + +#ifdef OW_USE_LWIP +// -- lwIP netdb wrappers (link-order fix) -- +// D object references lwip_getaddrinfo/lwip_freeaddrinfo but the D object +// appears after liblwip.a in the link. These wrappers are in libmain.a +// which is linked with --whole-archive, ensuring they're always present. + +int ow_lwip_getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res) +{ + return lwip_getaddrinfo(nodename, servname, hints, res); +} + +void ow_lwip_freeaddrinfo(struct addrinfo *ai) +{ + lwip_freeaddrinfo(ai); +} +#endif diff --git a/src/urt/driver/esp32/timer.d b/src/urt/driver/esp32/timer.d new file mode 100644 index 0000000..625a2f6 --- /dev/null +++ b/src/urt/driver/esp32/timer.d @@ -0,0 +1,38 @@ +// ESP32 timer driver -- D wrapper over ESP-IDF timer APIs +// +// Uses esp_timer_get_time() for monotonic microsecond clock. +// Periodic tick uses FreeRTOS tick or esp_timer under the hood. +module urt.driver.esp32.timer; + +nothrow @nogc: + + +enum uint mtime_freq_hz = 1_000_000; // esp_timer_get_time returns microseconds +enum bool has_mtime = true; +enum bool has_rtc = false; +enum bool has_mcycle = false; +enum bool has_timer_stop = false; +enum bool has_oneshot_timer = false; + +ulong mtime_read() +{ + return cast(ulong)esp_timer_get_time(); +} + +alias TimerCallback = void function() nothrow @nogc; + +void timer_set_periodic(uint period_us, TimerCallback cb) +{ + tick_callback = cb; + // TODO: configure esp_timer or FreeRTOS tick for periodic callback +} + + +private: + +private __gshared TimerCallback tick_callback; + +extern(C) nothrow @nogc +{ + long esp_timer_get_time(); +} diff --git a/src/urt/driver/esp32/uart.d b/src/urt/driver/esp32/uart.d new file mode 100644 index 0000000..a752be7 --- /dev/null +++ b/src/urt/driver/esp32/uart.d @@ -0,0 +1,100 @@ +// ESP32 UART driver -- D wrapper over the C shim (ow_shim.c) +// +// The C shim calls ESP-IDF UART HAL directly (no FreeRTOS UART driver). +// GPIO pin routing is done via the ROM GPIO matrix. +// +// 3 UART ports: UART0 (console), UART1, UART2. +// UART0 TX/RX defaults set by bootloader (typically GPIO43/44 on S3). +module urt.driver.esp32.uart; + +import urt.driver.uart : Parity, StopBits, UartConfig; + +nothrow @nogc: + + +// SOC_UART_NUM per chip variant +version (ESP32) enum num_uarts = 3; +else version (ESP32_S3) enum num_uarts = 3; +else version (ESP32_P4) enum num_uarts = 6; +else version (ESP32_S2) enum num_uarts = 2; +else version (ESP32_C2) enum num_uarts = 2; +else version (ESP32_C3) enum num_uarts = 2; +else version (ESP32_C5) enum num_uarts = 2; +else version (ESP32_C6) enum num_uarts = 3; +else version (ESP32_H2) enum num_uarts = 2; +else static assert(false, "unknown Espressif chip -- add num_uarts"); + +enum uint uart_clock_hz = 80_000_000; +enum bool has_irq_driven_uart = false; +enum bool has_dma_driven_uart = false; + +bool uart_hw_open(uint id, ref const UartConfig cfg) +{ + if (id >= num_uarts) + return false; + byte tx = cfg.tx_gpio == ubyte.max ? -1 : cast(byte)cfg.tx_gpio; + byte rx = cfg.rx_gpio == ubyte.max ? -1 : cast(byte)cfg.rx_gpio; + return ow_uart_open(id, cfg.baud_rate, cfg.data_bits, cast(ubyte)cfg.stop_bits, cast(ubyte)cfg.parity, tx, rx) != 0; +} + +void uart_hw_close(uint id) +{ + ow_uart_close(id); +} + +ptrdiff_t uart_hw_read(uint id, void[] buffer) +{ + return ow_uart_read(id, cast(ubyte*)buffer.ptr, cast(int)buffer.length); +} + +ptrdiff_t uart_hw_write(uint id, const(void)[] data) +{ + return ow_uart_write(id, cast(const(ubyte)*)data.ptr, cast(int)data.length); +} + +void uart_hw_poll(uint id) +{ + // ESP32 UART HAL is polled via read/rx_pending -- no separate poll needed +} + +bool uart_hw_check_errors(uint id) +{ + // TODO: check UART error status register via HAL + return false; +} + +ptrdiff_t uart_hw_rx_pending(uint id) +{ + return ow_uart_rx_pending(id); +} + +ptrdiff_t uart_hw_flush(uint id) +{ + return ow_uart_flush(id); +} + +bool uart_tx_idle(uint id) +{ + return ow_uart_tx_idle(id) != 0; +} + +void uart0_hw_puts(const(char)[] s) +{ + foreach (ch; s) + esp_rom_uart_putc(ch); +} + +private: + +extern(C) nothrow @nogc +{ + void esp_rom_uart_putc(char c) nothrow @nogc; + + int ow_uart_open(uint port, uint baud_rate, ubyte data_bits, ubyte stop_bits, ubyte parity, byte tx_gpio, byte rx_gpio); + void ow_uart_close(uint port); + int ow_uart_read(uint port, ubyte* buf, int len); + int ow_uart_write(uint port, const(ubyte)* buf, int len); + int ow_uart_rx_pending(uint port); + int ow_uart_tx_idle(uint port); + int ow_uart_flush(uint port); +} diff --git a/src/urt/driver/esp32/wifi.d b/src/urt/driver/esp32/wifi.d new file mode 100644 index 0000000..6309055 --- /dev/null +++ b/src/urt/driver/esp32/wifi.d @@ -0,0 +1,521 @@ +// ESP32 WiFi driver -- D wrapper over C shim + direct ESP-IDF calls +// +// The C shim (ow_shim.c) handles: +// - ow_wifi_init/deinit: WIFI_INIT_CONFIG_DEFAULT macro, netif creation, +// event handler registration +// - ow_wifi_sta_config/ap_config: wifi_config_t struct construction +// - ow_wifi_set_rx_callback: RX trampolines that forward to D AND to +// esp_netif_receive (so lwIP still works) +// +// Everything else (mode, connect, disconnect, tx, mac, channel, power) +// calls ESP-IDF directly. +// +// ESP32 has one WiFi port (port 0). +module urt.driver.esp32.wifi; + +import urt.driver.wifi; + +nothrow @nogc: + + +version (ESP32) enum uint num_wifi = 1; +else version (ESP32_S2) enum uint num_wifi = 1; +else version (ESP32_S3) enum uint num_wifi = 1; +else version (ESP32_C2) enum uint num_wifi = 1; +else version (ESP32_C3) enum uint num_wifi = 1; +else version (ESP32_C5) enum uint num_wifi = 1; +else version (ESP32_C6) enum uint num_wifi = 1; +else enum uint num_wifi = 0; // H2 (BT/802.15.4 only), P4 (needs external) + +enum ubyte wifi_max_ap_clients = 10; + + +static if (num_wifi > 0): + + +bool wifi_hw_open(uint port, ref const WifiConfig cfg) +{ + if (_opened) + return false; + + if (ow_wifi_init() != 0) + return false; + + ow_wifi_set_sta_callback(&sta_event_trampoline); + ow_wifi_set_ap_callback(&ap_event_trampoline); + + if (cfg.tx_power != 0) + esp_wifi_set_max_tx_power(cfg.tx_power); + + if (esp_wifi_start() != ESP_OK) + { + ow_wifi_deinit(); + return false; + } + + _opened = true; + return true; +} + +void wifi_hw_close(uint port) +{ + if (!_opened) + return; + ow_wifi_set_rx_callback(null); + ow_wifi_set_sta_callback(null); + ow_wifi_set_ap_callback(null); + esp_wifi_stop(); + ow_wifi_deinit(); + _opened = false; + _event_cb = null; + _rx_cb = null; + _raw_rx_cb = null; + _wifi_evt_head = 0; + _wifi_evt_tail = 0; +} + +bool wifi_hw_set_mode(uint port, WifiMode mode) +{ + // ESP-IDF treats promiscuous as a flag orthogonal to STA/AP, so monitor + // here means "STA mode (radio on, channel controllable) with promiscuous + // enabled later via wifi_hw_set_raw_rx_callback". The driver brings the + // radio up in STA so esp_wifi_set_channel is accepted; without STA, the + // channel setter rejects the call with WIFI_NOT_INIT_OR_NOT_STARTED. + int hw_mode = mode == WifiMode.monitor + ? 1 // STA -- minimum mode that lets us set channel + enable promisc + : (mode == WifiMode.none ? 0 + : mode == WifiMode.sta ? 1 + : mode == WifiMode.ap ? 2 + : 3); // apsta + return esp_wifi_set_mode(hw_mode) == ESP_OK; +} + +bool wifi_hw_sta_configure(uint port, ref const WifiStaConfig cfg) +{ + _sta_status_message = null; + + if (cfg.ssid.length > 32) + { + _sta_status_message = "STA SSID is too long"; + return false; + } + if (cfg.password.length > 64) + { + _sta_status_message = "STA password is too long"; + return false; + } + if (cfg.pmf_required) + { + _sta_status_message = "STA PMF required is not supported"; + return false; + } + + // Stack buffers for null-termination (SSID max 32, password max 64) + char[33] ssid_z = 0; + char[65] pw_z = 0; + + if (cfg.ssid.length > 0 && cfg.ssid.length <= 32) + ssid_z[0 .. cfg.ssid.length] = cfg.ssid[]; + if (cfg.password.length > 0 && cfg.password.length <= 64) + pw_z[0 .. cfg.password.length] = cfg.password[]; + + bool has_bssid = cfg.bssid != typeof(cfg.bssid).init; + + if (ow_wifi_sta_config( + cfg.ssid.length > 0 ? ssid_z.ptr : null, + cfg.password.length > 0 ? pw_z.ptr : null, + has_bssid ? cfg.bssid.ptr : null) == 0) + { + _sta_status_message = "STA config rejected by ESP-IDF"; + return false; + } + + return true; +} + +const(char)[] wifi_hw_sta_status_message(uint port) +{ + if (_sta_status_message.length != 0) + return _sta_status_message; + return esp_wifi_sta_reason_message(_sta_disconnect_reason); +} + +bool wifi_hw_sta_connect(uint port) +{ + _sta_status_message = null; + _sta_disconnect_reason = 0; + auto rc = esp_wifi_connect(); + if (rc == ESP_OK) + return true; + _sta_status_message = esp_wifi_error_message(rc); + return false; +} + +bool wifi_hw_sta_disconnect(uint port) +{ + return esp_wifi_disconnect() == ESP_OK; +} + +bool wifi_hw_ap_configure(uint port, ref const WifiApConfig cfg) +{ + char[33] ssid_z = 0; + char[65] pw_z = 0; + + if (cfg.ssid.length > 0 && cfg.ssid.length <= 32) + ssid_z[0 .. cfg.ssid.length] = cfg.ssid[]; + if (cfg.password.length > 0 && cfg.password.length <= 64) + pw_z[0 .. cfg.password.length] = cfg.password[]; + + return ow_wifi_ap_config( + cfg.ssid.length > 0 ? ssid_z.ptr : null, + cfg.password.length > 0 ? pw_z.ptr : null, + cfg.channel, cfg.max_clients, cfg.hidden ? 1 : 0) != 0; +} + +bool wifi_hw_ap_set_max_clients(uint port, ubyte max_clients) +{ + if (port != 0 || max_clients > wifi_max_ap_clients) + return false; + return ow_wifi_ap_set_max_clients(max_clients) != 0; +} + +size_t wifi_hw_ap_get_clients(uint port, WifiStaInfo[] buf) +{ + // TODO: esp_wifi_ap_get_sta_list + return 0; +} + +// Scanning + +bool wifi_hw_scan_start(uint port, ref const WifiScanConfig cfg) +{ + // TODO: esp_wifi_scan_start + return false; +} + +void wifi_hw_scan_stop(uint port) +{ + // TODO: esp_wifi_scan_stop +} + +size_t wifi_hw_scan_get_results(uint port, WifiScanResult[] buf) +{ + // TODO: esp_wifi_scan_get_ap_records + return 0; +} + +// Frame TX/RX + +bool wifi_hw_tx(uint port, WifiVif vif, const(ubyte)[] data) +{ + if (data.length == 0) + return false; + return esp_wifi_internal_tx(cast(int)vif, cast(void*)data.ptr, cast(ushort)data.length) == ESP_OK; +} + +void wifi_hw_set_rx_callback(uint port, WifiRxCallback cb) +{ + _rx_cb = cb; + ow_wifi_set_rx_callback(cb !is null ? &rx_trampoline : null); +} + +// Raw 802.11 TX/RX + +bool wifi_hw_raw_tx(uint port, const(ubyte)[] frame) +{ + if (frame.length == 0 || frame.length > 1500) + return false; + // ifx = 0 (WIFI_IF_STA): always present in our monitor + sta + ap modes. + // en_sys_seq = 1: let the MAC fill the sequence number so injected frames + // don't collide with the radio's own outgoing sequence space. + return ow_wifi_raw_tx(0, frame.ptr, cast(int)frame.length, 1) != 0; +} + +void wifi_hw_set_raw_rx_callback(uint port, WifiRawRxCallback cb) +{ + _raw_rx_cb = cb; + + if (cb is null) + { + ow_wifi_set_promiscuous(0, 0); + ow_wifi_set_promiscuous_callback(null); + return; + } + + ow_wifi_set_promiscuous_callback(&promisc_trampoline); + // Filter: management + data + control + misc + FCS-fail. The FCSFAIL + // bit is what lets us see corrupted frames -- the discriminator we need + // for "is the antenna seeing anything at all" vs "frames are framing + // correctly but content is wrong". + enum uint WIFI_PROMIS_FILTER_MASK_ALL_WITH_FCSFAIL = 0xE00000FF; + ow_wifi_set_promiscuous(1, WIFI_PROMIS_FILTER_MASK_ALL_WITH_FCSFAIL); +} + +bool wifi_hw_set_channel(uint port, ubyte primary) +{ + // secondary=0 -> HT20 (no 40 MHz extension). The vast majority of 2.4GHz + // deployments are HT20; if we ever want HT40 we extend this signature. + return ow_wifi_set_channel(primary, 0) != 0; +} + +// Queries + +bool wifi_hw_get_mac(uint port, WifiVif vif, ref ubyte[6] mac) +{ + // ESP_MAC_WIFI_STA=0, ESP_MAC_WIFI_SOFTAP=1 + return esp_read_mac(mac.ptr, cast(int)vif) == ESP_OK; +} + +ubyte wifi_hw_get_channel(uint port) +{ + ubyte primary = void; + int second = void; + if (esp_wifi_get_channel(&primary, &second) != ESP_OK) + return 0; + return primary; +} + +byte wifi_hw_get_rssi(uint port) +{ + // TODO: esp_wifi_sta_get_ap_info -> rssi + return -127; +} + +bool wifi_hw_set_tx_power(uint port, byte power_dbm) +{ + return esp_wifi_set_max_tx_power(power_dbm) == ESP_OK; +} + +// Events + +void wifi_hw_set_event_callback(uint port, WifiEventCallback cb) +{ + _event_cb = cb; +} + +void wifi_hw_poll(uint port) +{ + if (_event_cb is null) + return; + + Wifi w = Wifi(0); + while (_wifi_evt_head != _wifi_evt_tail) + { + auto slot = &_wifi_evt_queue[_wifi_evt_tail & (wifi_evt_cap - 1)]; + _wifi_evt_tail++; + _event_cb(w, slot.event, slot.has_mac ? slot.mac.ptr : null); + } +} + + +private: + +enum int ESP_OK = 0; + +// ESP-IDF event IDs (from esp_wifi_types.h) +enum : int +{ + WIFI_EVENT_STA_START = 2, + WIFI_EVENT_STA_STOP = 3, + WIFI_EVENT_STA_CONNECTED = 4, + WIFI_EVENT_STA_DISCONNECTED = 5, + WIFI_EVENT_AP_START = 12, + WIFI_EVENT_AP_STOP = 13, + WIFI_EVENT_AP_STACONNECTED = 14, + WIFI_EVENT_AP_STADISCONNECTED = 15, +} + +__gshared bool _opened; +__gshared WifiEventCallback _event_cb; +__gshared WifiRxCallback _rx_cb; +__gshared WifiRawRxCallback _raw_rx_cb; +__gshared int _sta_disconnect_reason; +__gshared const(char)[] _sta_status_message; + +struct WifiQueuedEvent +{ + WifiEvent event; + ubyte[6] mac; + bool has_mac; +} +enum size_t wifi_evt_cap = 8; +__gshared WifiQueuedEvent[wifi_evt_cap] _wifi_evt_queue; +__gshared uint _wifi_evt_head; +__gshared uint _wifi_evt_tail; + +void push_wifi_evt(WifiEvent event, const ubyte* mac = null) nothrow @nogc +{ + if (_wifi_evt_head - _wifi_evt_tail >= wifi_evt_cap) + _wifi_evt_tail++; + auto slot = &_wifi_evt_queue[_wifi_evt_head & (wifi_evt_cap - 1)]; + slot.event = event; + slot.has_mac = mac !is null; + if (mac !is null) + slot.mac[] = mac[0 .. 6]; + _wifi_evt_head++; +} + +extern(C) void sta_event_trampoline(int event_id, void*, int data_len) nothrow @nogc +{ + if (event_id == WIFI_EVENT_STA_CONNECTED) + { + _sta_status_message = null; + _sta_disconnect_reason = 0; + push_wifi_evt(WifiEvent.sta_connected); + } + else if (event_id == WIFI_EVENT_STA_DISCONNECTED) + { + _sta_disconnect_reason = data_len; + _sta_status_message = null; + push_wifi_evt(WifiEvent.sta_disconnected); + } +} + +const(char)[] esp_wifi_error_message(int rc) nothrow @nogc +{ + switch (rc) + { + case ESP_OK: + return null; + default: + return "ESP-IDF rejected STA request"; + } +} + +const(char)[] esp_wifi_sta_reason_message(int reason) nothrow @nogc +{ + switch (reason) + { + case 0: + return null; + case 1: + return "Disconnected: unspecified reason"; + case 2: + return "Authentication expired"; + case 4: + return "Association expired"; + case 5: + return "AP has too many clients"; + case 6: + return "Not authenticated"; + case 7: + return "Not associated"; + case 8: + return "Association left"; + case 9: + return "Association requires authentication"; + case 13: + return "Invalid 802.11 information element"; + case 14: + return "WPA MIC failure"; + case 15: + return "WPA 4-way handshake timed out"; + case 16: + return "WPA group key update timed out"; + case 17: + return "WPA information element changed during handshake"; + case 18: + return "WPA group cipher is invalid"; + case 19: + return "WPA pairwise cipher is invalid"; + case 20: + return "WPA AKM suite is invalid"; + case 21: + return "Unsupported RSN information element version"; + case 22: + return "Invalid RSN capabilities"; + case 23: + return "802.1X authentication failed"; + case 24: + return "Cipher suite rejected"; + case 200: + return "AP beacon timed out"; + case 201: + return "Target AP not found"; + case 202: + return "Authentication failed"; + case 203: + return "Association failed"; + case 204: + return "WPA handshake timed out"; + case 205: + return "Connection failed"; + case 207: + return "Roaming"; + default: + return "Disconnected by WiFi driver"; + } +} + +extern(C) void ap_event_trampoline(int event_id, void* event_data, int) nothrow @nogc +{ + if (event_id == WIFI_EVENT_AP_START) + push_wifi_evt(WifiEvent.ap_started); + else if (event_id == WIFI_EVENT_AP_STOP) + push_wifi_evt(WifiEvent.ap_stopped); + else if (event_id == WIFI_EVENT_AP_STACONNECTED && event_data !is null) + push_wifi_evt(WifiEvent.ap_sta_connected, cast(ubyte*)event_data); + else if (event_id == WIFI_EVENT_AP_STADISCONNECTED && event_data !is null) + push_wifi_evt(WifiEvent.ap_sta_disconnected, cast(ubyte*)event_data); +} + +// RX trampoline -- called from C shim's esp_wifi_internal_reg_rxcb handler. +// The C shim also forwards to esp_netif_receive so lwIP still gets frames. +extern(C) void rx_trampoline(const(ubyte)* data, int len, int iface) nothrow @nogc +{ + if (_rx_cb !is null && len > 0) + _rx_cb(Wifi(0), cast(WifiVif)iface, data[0 .. len]); +} + +// Promiscuous trampoline -- called from C shim for every 802.11 frame the +// radio decodes (including FCS-fail frames when the filter bit is set). +// rx_state non-zero == FCS failed; we forward unchanged and let the +// subscriber decide what to do with broken frames. +extern(C) void promisc_trampoline(int type, int rssi, int channel, + int rate, int fcs_fail, int len, + const(ubyte)* payload) nothrow @nogc +{ + if (_raw_rx_cb is null || len <= 0 || payload is null) + return; + // Drop FCS-fail frames for now -- the raw RX callback signature has no + // place to surface the bad-FCS flag yet, and forwarding garbage frames + // confuses subscribers that assume valid framing. The driver-level RX + // dropped counter is bumped at the iface layer instead. + if (fcs_fail) + return; + _raw_rx_cb(Wifi(0), payload[0 .. len], cast(byte)rssi, cast(ubyte)channel); +} + +// C shim functions (ow_shim.c) -- needed for macros, complex structs, netif +extern(C) nothrow @nogc +{ + int ow_wifi_init(); + void ow_wifi_deinit(); + int ow_wifi_sta_config(const(char)* ssid, const(char)* password, const(ubyte)* bssid); + int ow_wifi_ap_config(const(char)* ssid, const(char)* password, ubyte channel, ubyte max_conn, ubyte hidden); + int ow_wifi_ap_set_max_clients(ubyte max_conn); + int ow_wifi_set_rx_callback(void function(const(ubyte)*, int, int) nothrow @nogc cb); + void ow_wifi_set_sta_callback(void function(int, void*, int) nothrow @nogc); + void ow_wifi_set_ap_callback(void function(int, void*, int) nothrow @nogc); + int ow_wifi_set_promiscuous(int enable, uint filter_mask); + void ow_wifi_set_promiscuous_callback( + void function(int type, int rssi, int channel, + int rate, int fcs_fail, int len, + const(ubyte)* payload) nothrow @nogc cb); + int ow_wifi_set_channel(int primary, int secondary); + int ow_wifi_raw_tx(int ifx, const(ubyte)* frame, int len, int en_sys_seq); +} + +// Direct ESP-IDF calls +extern(C) nothrow @nogc +{ + int esp_wifi_set_mode(int mode); + int esp_wifi_start(); + int esp_wifi_stop(); + int esp_wifi_connect(); + int esp_wifi_disconnect(); + int esp_wifi_set_max_tx_power(byte power); + int esp_wifi_get_channel(ubyte* primary, int* second); + int esp_read_mac(ubyte* mac, int type); + int esp_wifi_internal_tx(int ifx, void* buffer, ushort len); +} diff --git a/src/urt/driver/freertos/fibre.d b/src/urt/driver/freertos/fibre.d new file mode 100644 index 0000000..d48053c --- /dev/null +++ b/src/urt/driver/freertos/fibre.d @@ -0,0 +1,93 @@ +// FreeRTOS task-based fibre implementation. +// Each fibre is a FreeRTOS task that blocks on a task notification. +// co_switch does a notify-target + wait-for-notification handoff, +// giving us cooperative coroutine semantics on top of FreeRTOS. + +module urt.driver.freertos.fibre; + +import urt.fibre : cothread_t, coentry_t; +import urt.internal.sys.freertos; +import urt.mem; + +nothrow @nogc: + + +struct co_fibre_data +{ + void* user_data; + uint stack_size; + TaskHandle_t task_handle; + coentry_t coentry; +} + +co_fibre_data main_fibre_data; +cothread_t co_active_handle = null; + +inout(co_fibre_data)* co_get_fibre_data(inout cothread_t fibre) pure + => cast(co_fibre_data*)fibre; + +cothread_t co_active() +{ + if (!co_active_handle) + { + main_fibre_data.task_handle = xTaskGetCurrentTaskHandle(); + co_active_handle = &main_fibre_data; + } + return co_active_handle; +} + +void* co_data() + => (cast(co_fibre_data*)co_active_handle).user_data; + +cothread_t co_derive(void[] memory, coentry_t entry, void* data) +{ + return null; // not supported with FreeRTOS tasks +} + +extern(C) static void co_freertos_entry(void* param) nothrow @nogc +{ + co_active_handle = cast(cothread_t)param; // set TLS for this task + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); // block until first co_switch + (cast(co_fibre_data*)param).coentry(); +} + +cothread_t co_create(size_t stack_size, coentry_t entry, void* data) +{ + assert(stack_size <= uint.max, "Stack size too large"); + co_active(); // ensure main fibre initialized + + auto fdata = defaultAllocator().allocT!co_fibre_data(); + if (!fdata) return null; + + fdata.user_data = data; + fdata.stack_size = cast(uint)stack_size; + fdata.coentry = entry; + + UBaseType_t priority = uxTaskPriorityGet(null); + + if (xTaskCreate(&co_freertos_entry, "fibre", cast(uint)stack_size, + fdata, priority, &fdata.task_handle) != pdPASS) + { + defaultAllocator().freeT(fdata); + return null; + } + + return fdata; +} + +void co_delete(cothread_t handle) +{ + auto fdata = cast(co_fibre_data*)handle; + if (fdata && fdata != &main_fibre_data) + { + if (fdata.task_handle) + vTaskDelete(fdata.task_handle); + defaultAllocator().freeT(fdata); + } +} + +void co_switch(cothread_t handle) +{ + xTaskNotifyGive((cast(co_fibre_data*)handle).task_handle); + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); +} diff --git a/src/urt/driver/gpio.d b/src/urt/driver/gpio.d new file mode 100644 index 0000000..fabe9b2 --- /dev/null +++ b/src/urt/driver/gpio.d @@ -0,0 +1,85 @@ +// GPIO driver. Software-GPIO primitives plus per-pin function muxing +// for SoCs that support it (BL6xx, BL8xx, BK7231, RP2350, STM32). On +// targets that route via signal matrix (ESP32) or have no pin concept +// (Windows/POSIX without sysfs), has_pin_function_muxing is false and +// gpio_set_function is not declared. +// +// Pin numbering is a flat uint per SoC. STM32 packs port and pin as +// (port * 16 + pin_in_port) so PA9 = 9, PB3 = 19, PE15 = 79. Other +// SoCs use linear pin numbers from 0. +// +// num_gpio is a compile-time upper bound (exact on SoCs with fixed +// pin counts; on hosted targets like Linux SBC it is a static cap and +// gpio_count() returns the actual runtime number). +// +// Function bodies live in /gpio.d, pulled in by the version +// dispatch below. Each backend exports: +// uint gpio_count(); +// void gpio_output_init(uint pin, bool initial = false, DriveMode = push_pull); +// void gpio_input_init(uint pin, Pull = none); +// void gpio_output_set(uint pin, bool value); +// void gpio_output_toggle(uint pin); +// bool gpio_input_read(uint pin); +// void gpio_set_pull(uint pin, Pull); +// void gpio_release(uint pin); +// void gpio_set_function(uint pin, uint function_id, Pull = none, DriveMode = push_pull); +// +// function_id is opaque per chip; peripheral drivers know the right +// value. The peripheral owns I/O direction once muxed. +module urt.driver.gpio; + +version (Bouffalo) + public import urt.driver.bl_common.gpio; +else version (Beken) + public import urt.driver.bk7231.gpio; +else version (Espressif) + public import urt.driver.esp32.gpio; +else version (linux) + public import urt.driver.posix.gpio; +else +{ + enum uint num_gpio = 0; + enum bool has_pull_up = false; + enum bool has_pull_down = false; + enum bool has_open_drain = false; + enum bool has_pin_function_muxing = false; + + uint gpio_count() nothrow @nogc => 0; +} + +nothrow @nogc: + +enum Pull : ubyte +{ + none, + up, + down, +} + +enum DriveMode : ubyte +{ + push_pull, + open_drain, +} + + +unittest +{ + static assert(is(typeof(num_gpio) == uint)); + static assert(is(typeof(has_pull_up) == bool)); + static assert(is(typeof(has_pull_down) == bool)); + static assert(is(typeof(has_open_drain) == bool)); + static assert(is(typeof(has_pin_function_muxing) == bool)); + + // Pull encoding is load-bearing: bl808/bl618 backends shift the + // ordinal directly into GPIO_CFG bits[25:24]. + static assert(Pull.none == 0); + static assert(Pull.up == 1); + static assert(Pull.down == 2); + + static assert(DriveMode.push_pull == 0); + static assert(DriveMode.open_drain == 1); + + // gpio_count() is callable on every backend (returns 0 on fallback). + gpio_count(); +} diff --git a/src/urt/driver/irq.d b/src/urt/driver/irq.d new file mode 100644 index 0000000..aec589a --- /dev/null +++ b/src/urt/driver/irq.d @@ -0,0 +1,330 @@ +// Unified baremetal interrupt controller driver +// +// Normalizes the IRQ API across RISC-V PLIC, ARM NVIC, Beken ICU, etc. +// Platform drivers export capabilities; the baremetal layer re-exports +// them and provides a uniform function surface. +module urt.driver.irq; + +version (BL808_M0) + public import urt.driver.bl618.irq; +else version (BL808) + public import urt.driver.bl808.irq; +else version (BL618) + public import urt.driver.bl618.irq; +else version (Beken) + public import urt.driver.bk7231.irq; +else version (RP2350) + public import urt.driver.rp2350.irq; +else version (STM32) + public import urt.driver.stm32.irq; +else version (Espressif) + public import urt.driver.esp32.irq; +else +{ + enum bool has_plic = false; + enum bool has_nvic = false; + enum bool has_clic = false; + enum bool has_per_irq_control = false; + enum bool has_irq_priority = false; + enum bool has_wait_for_interrupt = false; + enum bool has_irq_diagnostics = false; + enum bool has_global_irq_state = false; + enum bool has_smp = false; + enum uint irq_max = 0; +} + +nothrow @nogc: + +alias IrqHandler = void function(uint irq) nothrow @nogc; + + +// ==================================================================== +// Driver API +// ==================================================================== + +// `irq_init()` -- platform driver brings the interrupt controller to a known +// state. Re-exported from the platform module via the public import above +// (signature: extern(C) void irq_init()). sys_init in bl_common/system.d +// calls this before any irq_line_enable and before irq_global_enable. + +// Global interrupt control + +// Disable all interrupt delivery. Returns previous state where the platform +// can report it (has_global_irq_state). FreeRTOS-style critical-section +// platforms always report "true" so IrqGuard pairs enter/exit cleanly. +bool irq_global_disable() +{ + static if (has_plic || has_clic) + return disable_interrupts(); + else static if (irq_max > 0) + return irq_disable(); + else + assert(false, "no IRQ controller"); +} + +// Enable all interrupt delivery. Returns previous state where the platform +// can report it; see irq_global_disable() for the FreeRTOS caveat. +bool irq_global_enable() +{ + static if (has_plic || has_clic) + return enable_interrupts(); + else static if (irq_max > 0) + return irq_enable(); + else + assert(false, "no IRQ controller"); +} + +// Set global interrupt state. Returns previous state. +bool irq_global_set(bool enabled) +{ + return enabled ? irq_global_enable() : irq_global_disable(); +} + +// RAII-style critical section guard. +// Usage: auto guard = irq_critical(); +struct IrqGuard +{ + private bool _prev; + @disable this(); + @disable this(this); + + ~this() nothrow @nogc + { + irq_global_set(_prev); + } +} + +IrqGuard irq_critical() +{ + IrqGuard g = void; + g._prev = irq_global_disable(); + return g; +} + +// Per-IRQ control + +// Enable a specific peripheral interrupt. Returns previous state. +bool irq_line_enable(uint irq) +{ + static if (has_per_irq_control) + { + static if (has_plic) + return enable_irq(irq); + else + return irq_set_enable(irq); + } + else + assert(false, "no per-IRQ control"); +} + +// Disable a specific peripheral interrupt. Returns previous state. +bool irq_line_disable(uint irq) +{ + static if (has_per_irq_control) + { + static if (has_plic) + return disable_irq(irq); + else + return irq_clear_enable(irq); + } + else + assert(false, "no per-IRQ control"); +} + +// Set priority for a peripheral interrupt (0 = highest). +void irq_line_set_priority(uint irq, ubyte priority) +{ + static if (has_irq_priority) + irq_set_priority(irq, priority); + else + assert(false, "no IRQ priority support"); +} + +// Handler registration + +// Install an interrupt handler. Returns the previous handler for chaining. +// PLIC delivers all external IRQs through a single line, so handlers are +// installed globally and the platform's claim/complete protocol routes to +// them. +static if (has_plic) +{ + IrqHandler irq_handler_set(IrqHandler handler) + { + return irq_set_handler(handler); + } +} + +// CLIC (and NVIC) maintains per-IRQ vectors. Each line gets its own handler; +// the dispatcher reads mcause / IPSR to pick which one to call. +static if (has_clic || has_nvic) +{ + IrqHandler irq_handler_set(uint irq, IrqHandler handler) + { + return irq_set_handler(irq, handler); + } +} + +// Power management + +// Halt CPU until an interrupt fires. Near-zero power draw. +void irq_wait() +{ + static if (has_wait_for_interrupt) + wait_for_interrupt(); + else + assert(false, "WFI not available"); +} + +// Diagnostics + +static if (has_irq_diagnostics) +{ + ref uint irq_total_count() + { + return irq_count; + } + + uint[] irq_hit_histogram() + { + return irq_histogram[]; + } +} + + +// ==================================================================== +// Tests +// ==================================================================== +// +// The desktop unittest binary has irq_max == 0 so every body below stays +// behind `static if (irq_max > 0)` and is gated out -- only the capability +// cross-asserts run there. On embedded unittest builds (rare; embedded +// targets are CONFIG=release by policy) these exercise the live CSR / MMIO +// surface and the trap entry path. + +unittest // capability cross-consistency +{ + static if (has_plic) static assert(has_per_irq_control); + static if (has_nvic) static assert(has_per_irq_control); + static if (has_clic) static assert(has_per_irq_control); + static if (has_irq_diagnostics) static assert(irq_max > 0); + // Diagnostics requires per-IRQ dispatch -- you can't increment a + // histogram if there's no per-line tag at trap entry. + static if (has_irq_diagnostics) + static assert(has_plic || has_clic || has_nvic); +} + +static if (irq_max > 0 && has_global_irq_state) +unittest // global enable/disable reports prior state symmetrically +{ + bool original = irq_global_disable(); + bool now = irq_global_disable(); + assert(!now, "second disable must observe MIE off"); + + irq_global_enable(); + bool en = irq_global_enable(); + assert(en, "second enable must observe MIE on"); + + irq_global_set(original); +} + +static if (irq_max > 0 && has_global_irq_state) +unittest // IrqGuard restores prior state across both polarities +{ + irq_global_enable(); + { + auto guard = irq_critical(); + bool inside = irq_global_disable(); + assert(!inside, "inside the guarded region, IRQs must remain off"); + } + bool after_on = irq_global_disable(); + assert(after_on, "guard must re-enable when entered with IRQs on"); + + irq_global_disable(); + { + auto guard = irq_critical(); + } + bool after_off = irq_global_disable(); + assert(!after_off, "guard must leave IRQs off when entered with IRQs off"); +} + +static if (irq_max > 0) +unittest // IrqGuard nests cleanly (covers FreeRTOS recursive-mux platforms too) +{ + auto outer = irq_critical(); + { + auto inner = irq_critical(); + { + auto innermost = irq_critical(); + } + } + // If destruction order or recursion accounting were wrong, a platform + // using a counted spinlock (ESP32 portMUX) would assert internally. +} + +static if (irq_max > 0 && has_per_irq_control) +unittest // per-IRQ enable / disable round-trip on an unwired slot +{ + enum uint slot = irq_max - 1; + + // Coerce to a known-off baseline first; some platform setters return + // void rather than the previous state. + irq_line_disable(slot); + + bool was = irq_line_enable(slot); + assert(!was, "freshly cleared slot must report off"); + + bool en = irq_line_enable(slot); + assert(en, "re-enable must report on"); + + bool dis = irq_line_disable(slot); + assert(dis, "disable after enable must report on"); + + bool again = irq_line_enable(slot); + assert(!again, "re-enable after disable must report off"); + + irq_line_disable(slot); +} + +static if (irq_max > 0 && has_per_irq_control) +unittest // out-of-range per-IRQ calls must not crash or touch foreign memory +{ + enum uint bad = irq_max + 1024; + bool e = irq_line_enable(bad); + bool d = irq_line_disable(bad); + assert(!e && !d, "out-of-range must be reported as 'was off'"); +} + +// Handler tables: only CLIC/NVIC expose per-line install. PLIC has a single +// global dispatcher so its irq_handler_set has a different signature. +static if (irq_max > 0 && (has_clic || has_nvic)) +unittest // handler registration swap reports the just-installed handler +{ + static void a(uint) {} + static void b(uint) {} + + enum uint slot = 7; // timer line on RISC-V; harmless on ARM unittest + + IrqHandler prior = irq_handler_set(slot, &a); + scope (exit) irq_handler_set(slot, prior); + + IrqHandler swap1 = irq_handler_set(slot, &b); + assert(swap1 is &a, "swap must surface the most recent install"); + + IrqHandler swap2 = irq_handler_set(slot, null); + assert(swap2 is &b); +} + +static if (irq_max > 0 && has_irq_diagnostics) +unittest // diagnostics expose the expected geometry and read stably +{ + uint[] hist = irq_hit_histogram(); + assert(hist.length == irq_max, + "histogram length must mirror irq_max"); + + // The counter is __gshared and only mutated from _irq_dispatch; reading + // it twice with IRQs off must yield identical values. + auto guard = irq_critical(); + uint a = irq_total_count(); + uint b = irq_total_count(); + assert(a == b, "diagnostics counter wobbled with IRQs disabled"); +} diff --git a/src/urt/driver/posix/alloc.d b/src/urt/driver/posix/alloc.d new file mode 100644 index 0000000..2f9de46 --- /dev/null +++ b/src/urt/driver/posix/alloc.d @@ -0,0 +1,56 @@ +module urt.driver.posix.alloc; + +import urt.mem.alloc : MemFlags; + +nothrow @nogc: + +enum has_realloc = false; +enum has_expand = false; +enum has_memsize = true; +enum has_exec = true; +enum has_retain = false; +enum has_memflags = false; + +void[] _alloc(size_t size, size_t alignment, MemFlags) pure +{ + void* p; + return posix_memalign(&p, alignment <= 8 ? 8 : alignment, size) ? null : p[0 .. size]; +} + +void _free(void* ptr) pure +{ + free(ptr); +} + + +size_t _memsize(void* ptr) pure +{ + return malloc_usable_size(ptr); +} + +void[] _alloc_exec(size_t size) pure +{ + void* p = mmap(null, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + return (p is MAP_FAILED) ? null : p[0 .. size]; +} + +void _free_exec(void[] mem) pure +{ + munmap(mem.ptr, mem.length); +} + + +private: + +extern(C) int posix_memalign(void** memptr, size_t alignment, size_t size) pure; +extern(C) size_t malloc_usable_size(void* ptr) pure; +extern(C) void* mmap(void* addr, size_t length, int prot, int flags, int fd, long offset) pure; +extern(C) int munmap(void* addr, size_t length) pure; +extern(C) void free(void* ptr) pure; + +enum PROT_READ = 0x1; +enum PROT_WRITE = 0x2; +enum PROT_EXEC = 0x4; +enum MAP_PRIVATE = 0x02; +enum MAP_ANONYMOUS = 0x20; +enum MAP_FAILED = cast(void*)-1; diff --git a/src/urt/driver/posix/exception.d b/src/urt/driver/posix/exception.d new file mode 100644 index 0000000..4b072e9 --- /dev/null +++ b/src/urt/driver/posix/exception.d @@ -0,0 +1,1077 @@ +/// POSIX exception driver - stack-trace capture/print via ELF + DWARF. +/// +/// Uses _Unwind_Backtrace (ARM/AArch64/RISC-V) or inline-asm RBP walking +/// (x86/x86_64) for capture. Symbol resolution via dladdr; file:line via +/// .debug_line (DWARF v3/4/5). Ported from druntime's +/// core.internal.backtrace.{dwarf,elf} and core.internal.elf.{io,dl}. +/// +/// The DWARF exception-handling runtime (_d_throw_exception, personality +/// function, etc.) lives in urt.internal.dwarfeh so it compiles on bare- +/// metal builds too where urt.driver.posix.exception is not in the source list. +module urt.driver.posix.exception; + +// Windows has its own driver; BareMetal has its own. Everything else +// (Linux, macOS, BSD) lands here. Compiled always (not just `debug`) +// so allocation-site tracking works in release builds. +version (Windows) {} else version (BareMetal) {} else: + +import urt.internal.exception : Resolved, StackTraceData, _d_createTrace, _d_isbaseof, terminate; + +import urt.mem : strlen, memcpy; + +import urt.internal.sys.posix; + +// =================================================================== +// !!! TODO !!! THREADING IS NOT SUPPORTED. +// +// dladdr is MT-safe but the static scratch buffers used by the +// DWARF .debug_line decoder (_dir_scratch, _file_scratch) and the +// ELF self-mapping state are not. Add a mutex or per-thread state +// before this program can use threads. +// =================================================================== + +private enum SEEK_END = 2; + +// --- _Unwind_Backtrace capture (ARM, AArch64, RISC-V) ------------ + +version (D_InlineAsm_X86_64) {} else version (D_InlineAsm_X86) {} else +{ + private alias _Unwind_Trace_Fn = extern(C) int function(void* ctx, void* data) nothrow @nogc; + + extern(C) private int _Unwind_Backtrace(_Unwind_Trace_Fn, void*) nothrow @nogc; + extern(C) private size_t _Unwind_GetIP(void*) nothrow @nogc; + + private struct UnwindState { StackTraceData* trace; ubyte skip; } + + extern(C) private int unwind_trace_callback(void* ctx, void* data) nothrow @nogc + { + auto s = cast(UnwindState*) data; + if (s.skip > 0) { s.skip--; return 0; } + if (s.trace.length >= 32) return 1; + auto ip = _Unwind_GetIP(ctx); + if (!ip) return 1; + s.trace.addrs[s.trace.length++] = cast(void*) ip; + return 0; + } + + private void unwind_backtrace(ref StackTraceData trace) nothrow @nogc @trusted + { + UnwindState state = UnwindState(&trace, 2); + _Unwind_Backtrace(&unwind_trace_callback, &state); + } +} + +// --- Minimal ELF types -------------------------------------------- + +version (D_LP64) +{ + private struct Elf_Ehdr + { + ubyte[16] e_ident; + ushort e_type; + ushort e_machine; + uint e_version; + ulong e_entry; + ulong e_phoff; + ulong e_shoff; + uint e_flags; + ushort e_ehsize; + ushort e_phentsize; + ushort e_phnum; + ushort e_shentsize; + ushort e_shnum; + ushort e_shstrndx; + } + + private struct Elf_Shdr + { + uint sh_name; + uint sh_type; + ulong sh_flags; + ulong sh_addr; + ulong sh_offset; + ulong sh_size; + uint sh_link; + uint sh_info; + ulong sh_addralign; + ulong sh_entsize; + } + + private struct Elf_Phdr + { + uint p_type; + uint p_flags; + ulong p_offset; + ulong p_vaddr; + ulong p_paddr; + ulong p_filesz; + ulong p_memsz; + ulong p_align; + } +} +else +{ + private struct Elf_Ehdr + { + ubyte[16] e_ident; + ushort e_type; + ushort e_machine; + uint e_version; + uint e_entry; + uint e_phoff; + uint e_shoff; + uint e_flags; + ushort e_ehsize; + ushort e_phentsize; + ushort e_phnum; + ushort e_shentsize; + ushort e_shnum; + ushort e_shstrndx; + } + + private struct Elf_Shdr + { + uint sh_name; + uint sh_type; + uint sh_flags; + uint sh_addr; + uint sh_offset; + uint sh_size; + uint sh_link; + uint sh_info; + uint sh_addralign; + uint sh_entsize; + } + + private struct Elf_Phdr + { + uint p_type; + uint p_offset; + uint p_vaddr; + uint p_paddr; + uint p_filesz; + uint p_memsz; + uint p_flags; + uint p_align; + } +} + +private enum EI_MAG0 = 0; +private enum EI_CLASS = 4; +private enum EI_DATA = 5; +private enum ELFMAG = "\x7fELF"; +private enum ET_DYN = 3; +private enum SHF_COMPRESSED = 0x800; + +version (D_LP64) + private enum ELFCLASS_NATIVE = 2; // ELFCLASS64 +else + private enum ELFCLASS_NATIVE = 1; // ELFCLASS32 + +version (LittleEndian) + private enum ELFDATA_NATIVE = 1; // ELFDATA2LSB +else + private enum ELFDATA_NATIVE = 2; // ELFDATA2MSB + +// --- dl_iterate_phdr for base address ----------------------------- + +private struct dl_phdr_info +{ + size_t dlpi_addr; + const(char)* dlpi_name; + const(Elf_Phdr)* dlpi_phdr; + ushort dlpi_phnum; +} + +private alias dl_iterate_phdr_callback_t = extern(C) int function(dl_phdr_info*, size_t, void*) nothrow @nogc; + +extern(C) private int dl_iterate_phdr(dl_iterate_phdr_callback_t callback, void* data) nothrow @nogc; + +private size_t get_executable_base_address() nothrow @nogc @trusted +{ + size_t result = 0; + + extern(C) static int callback(dl_phdr_info* info, size_t, void* data) nothrow @nogc + { + // First entry is the executable itself + *cast(size_t*) data = info.dlpi_addr; + return 1; // stop iteration + } + + dl_iterate_phdr(&callback, &result); + return result; +} + +// --- Memory-mapped file region ------------------------------------ + +private struct MappedRegion +{ + const(ubyte)* data; + size_t mapped_size; + +nothrow @nogc @trusted: + + static MappedRegion map(int fd, size_t offset, size_t length) + { + if (fd == -1 || length == 0) + return MappedRegion.init; + + auto pgsz = cast(size_t) sysconf(_SC_PAGE_SIZE); + if (cast(int) pgsz <= 0) + pgsz = 4096; + + const page_off = offset / pgsz; + const diff = offset - page_off * pgsz; + const needed = length + diff; + const pages = (needed + pgsz - 1) / pgsz; + const msize = pages * pgsz; + + auto p = mmap(null, msize, PROT_READ, MAP_PRIVATE, fd, cast(off_t)(page_off * pgsz)); + if (p is MAP_FAILED) + return MappedRegion.init; + + return MappedRegion(cast(const(ubyte)*) p + diff, msize); + } + + void unmap() + { + if (data !is null) + { + auto pgsz = cast(size_t) sysconf(_SC_PAGE_SIZE); + if (cast(int) pgsz <= 0) + pgsz = 4096; + // Align back to page boundary + auto base = cast(void*)(cast(size_t) data & ~(pgsz - 1)); + munmap(base, mapped_size); + data = null; + } + } +} + +// --- ELF self-reader ---------------------------------------------- + +private struct ElfSelf +{ + int fd = -1; + MappedRegion ehdr_region; + const(Elf_Ehdr)* ehdr; + +nothrow @nogc @trusted: + + static ElfSelf open() + { + ElfSelf self; + + // Read /proc/self/exe path + char[512] pathbuf = void; + auto n = readlink("/proc/self/exe", pathbuf.ptr, pathbuf.length - 1); + if (n <= 0) + return self; + pathbuf[n] = 0; + + self.fd = .open(pathbuf.ptr, O_RDONLY); + if (self.fd == -1) + return self; + + // Map the ELF header + self.ehdr_region = MappedRegion.map(self.fd, 0, Elf_Ehdr.sizeof); + if (self.ehdr_region.data is null) + { + .close(self.fd); + self.fd = -1; + return self; + } + + self.ehdr = cast(const(Elf_Ehdr)*) self.ehdr_region.data; + + // Validate ELF magic, class, and byte order + if (self.ehdr.e_ident[0..4] != cast(const(ubyte)[4]) ELFMAG + || self.ehdr.e_ident[EI_CLASS] != ELFCLASS_NATIVE + || self.ehdr.e_ident[EI_DATA] != ELFDATA_NATIVE) + { + self.close(); + return ElfSelf.init; + } + + return self; + } + + void close() + { + ehdr_region.unmap(); + ehdr = null; + if (fd != -1) { .close(fd); fd = -1; } + } + + bool valid() const { return fd != -1 && ehdr !is null; } + + /// Find a section by name, return its offset and size. + bool find_section(const(char)[] name, out size_t offset, out size_t size) + { + if (!valid()) + return false; + + // Map section headers + auto shdr_total = cast(size_t) ehdr.e_shnum * Elf_Shdr.sizeof; + auto shdr_region = MappedRegion.map(fd, cast(size_t) ehdr.e_shoff, shdr_total); + if (shdr_region.data is null) + return false; + scope(exit) shdr_region.unmap(); + + auto shdrs = (cast(const(Elf_Shdr)*) shdr_region.data)[0 .. ehdr.e_shnum]; + + // Map string table section + if (ehdr.e_shstrndx >= ehdr.e_shnum) + return false; + auto strtab_shdr = &shdrs[ehdr.e_shstrndx]; + auto strtab_region = MappedRegion.map(fd, + cast(size_t) strtab_shdr.sh_offset, + cast(size_t) strtab_shdr.sh_size); + if (strtab_region.data is null) + return false; + scope(exit) strtab_region.unmap(); + + auto strtab = cast(const(char)*) strtab_region.data; + + // Search for the named section + foreach (ref shdr; shdrs) + { + if (shdr.sh_name >= strtab_shdr.sh_size) + continue; + auto sec_name = strtab + shdr.sh_name; + auto sec_name_len = strlen(sec_name); + if (sec_name_len == name.length && sec_name[0 .. sec_name_len] == name) + { + if (shdr.sh_flags & SHF_COMPRESSED) + return false; // compressed debug sections not supported + offset = cast(size_t) shdr.sh_offset; + size = cast(size_t) shdr.sh_size; + return true; + } + } + return false; + } +} + +// --- DWARF .debug_line types and constants ------------------------ + +private struct LocationInfo +{ + int file = -1; + int line = -1; +} + +private struct SourceFile +{ + const(char)[] file; + size_t dir_index; // 1-based +} + +private struct LineNumberProgram +{ + ulong unit_length; + ushort dwarf_version; + ubyte address_size; + ubyte segment_selector_size; + ulong header_length; + ubyte minimum_instruction_length; + ubyte maximum_operations_per_instruction; + bool default_is_statement; + byte line_base; + ubyte line_range; + ubyte opcode_base; + const(ubyte)[] standard_opcode_lengths; + // Directory and file tables stored as slices into scratch buffers. + // The caller owns the scratch; the LineNumberProgram just borrows. + const(char)[][] include_directories; + size_t num_dirs; + SourceFile[] source_files; + size_t num_files; + const(ubyte)[] program; +} + +private struct StateMachine +{ + const(void)* address; + uint operation_index = 0; + uint file_index = 1; + int line = 1; + uint column = 0; + bool is_statement; + bool is_end_sequence = false; +} + +private enum StandardOpcode : ubyte +{ + extended_op = 0, + copy = 1, + advance_pc = 2, + advance_line = 3, + set_file = 4, + set_column = 5, + negate_statement = 6, + set_basic_block = 7, + const_add_pc = 8, + fixed_advance_pc = 9, + set_prologue_end = 10, + set_epilogue_begin = 11, + set_isa = 12, +} + +private enum ExtendedOpcode : ubyte +{ + end_sequence = 1, + set_address = 2, + define_file = 3, + set_discriminator = 4, +} + +// --- LEB128 and DWARF helpers ------------------------------------- + +private T dw_read(T)(ref const(ubyte)[] buf) nothrow @nogc @trusted +{ + if (buf.length < T.sizeof) + return T.init; + version (X86_64) + T result = *cast(const(T)*) buf.ptr; + else version (X86) + T result = *cast(const(T)*) buf.ptr; + else + { + T result = void; + memcpy(&result, buf.ptr, T.sizeof); + } + buf = buf[T.sizeof .. $]; + return result; +} + +private const(char)[] dw_read_stringz(ref const(ubyte)[] buf) nothrow @nogc @trusted +{ + auto p = cast(const(char)*) buf.ptr; + auto len = strlen(p); + buf = buf[len + 1 .. $]; + return p[0 .. len]; +} + +private ulong dw_read_uleb128(ref const(ubyte)[] buf) nothrow @nogc +{ + ulong val = 0; + uint shift = 0; + while (buf.length > 0) + { + ubyte b = buf[0]; buf = buf[1 .. $]; + val |= cast(ulong)(b & 0x7f) << shift; + if ((b & 0x80) == 0) break; + shift += 7; + } + return val; +} + +private long dw_read_sleb128(ref const(ubyte)[] buf) nothrow @nogc +{ + long val = 0; + uint shift = 0; + ubyte b; + while (buf.length > 0) + { + b = buf[0]; buf = buf[1 .. $]; + val |= cast(long)(b & 0x7f) << shift; + shift += 7; + if ((b & 0x80) == 0) break; + } + if (shift < 64 && (b & 0x40) != 0) + val |= -(cast(long) 1 << shift); + return val; +} + +// --- DWARF v5 entry format ---------------------------------------- + +private enum DW_LNCT : ushort +{ + path = 1, + directory_index = 2, +} + +private enum DW_FORM : ubyte +{ + data1 = 11, + data2 = 5, + data4 = 6, + data8 = 7, + data16 = 30, + string_ = 8, + strp = 14, + line_strp = 31, + udata = 15, + block = 9, + strx = 26, + strx1 = 37, + strx2 = 38, + strx3 = 39, + strx4 = 40, + sec_offset = 23, + sdata = 13, + flag = 12, + flag_present = 25, +} + +private struct EntryFormatPair +{ + DW_LNCT type; + DW_FORM form; +} + +/// Skip a DWARF form value we don't care about. +private void dw_skip_form(ref const(ubyte)[] data, DW_FORM form, bool is64bit) nothrow @nogc +{ + with (DW_FORM) switch (form) + { + case strp, line_strp, sec_offset: + data = data[is64bit ? 8 : 4 .. $]; break; + case data1, strx1, flag, flag_present: + data = data[1 .. $]; break; + case data2, strx2: + data = data[2 .. $]; break; + case strx3: + data = data[3 .. $]; break; + case data4, strx4: + data = data[4 .. $]; break; + case data8: + data = data[8 .. $]; break; + case data16: + data = data[16 .. $]; break; + case udata, strx, sdata: + dw_read_uleb128(data); break; + case block: + auto length = cast(size_t) dw_read_uleb128(data); + data = data[length .. $]; break; + default: + break; + } +} + +// --- Read DWARF line number program header ------------------------ + +// Scratch buffers allocated on the stack for directory/file tables. +// 256 entries each should be more than enough for any compilation unit. +private enum MAX_DIRS = 256; +private enum MAX_FILES = 512; + +private LineNumberProgram dw_read_line_number_program(ref const(ubyte)[] data) nothrow @nogc @trusted +{ + const original_data = data; + LineNumberProgram lp; + + bool is_64bit_dwarf = false; + lp.unit_length = dw_read!uint(data); + if (lp.unit_length == uint.max) + { + is_64bit_dwarf = true; + lp.unit_length = dw_read!ulong(data); + } + + const version_field_offset = cast(size_t)(data.ptr - original_data.ptr); + lp.dwarf_version = dw_read!ushort(data); + + if (lp.dwarf_version >= 5) + { + lp.address_size = dw_read!ubyte(data); + lp.segment_selector_size = dw_read!ubyte(data); + } + + lp.header_length = is_64bit_dwarf ? dw_read!ulong(data) : dw_read!uint(data); + + const min_insn_field_offset = cast(size_t)(data.ptr - original_data.ptr); + lp.minimum_instruction_length = dw_read!ubyte(data); + lp.maximum_operations_per_instruction = (lp.dwarf_version >= 4) ? dw_read!ubyte(data) : 1; + lp.default_is_statement = (dw_read!ubyte(data) != 0); + lp.line_base = dw_read!byte(data); + lp.line_range = dw_read!ubyte(data); + lp.opcode_base = dw_read!ubyte(data); + + lp.standard_opcode_lengths = data[0 .. lp.opcode_base - 1]; + data = data[lp.opcode_base - 1 .. $]; + + if (lp.dwarf_version >= 5) + { + // DWARF v5: directory format + entries + auto num_pairs = dw_read!ubyte(data); + EntryFormatPair[8] dir_fmt = void; + foreach (i; 0 .. num_pairs) + { + if (i < 8) + { + dir_fmt[i].type = cast(DW_LNCT) dw_read_uleb128(data); + dir_fmt[i].form = cast(DW_FORM) dw_read_uleb128(data); + } + } + + lp.num_dirs = cast(size_t) dw_read_uleb128(data); + // Caller must provide scratch buffers; we use __gshared static for simplicity. + foreach (d; 0 .. lp.num_dirs) + { + foreach (p; 0 .. num_pairs) + { + if (p < 8 && dir_fmt[p].type == DW_LNCT.path && dir_fmt[p].form == DW_FORM.string_) + { + if (d < MAX_DIRS) + _dir_scratch[d] = dw_read_stringz(data); + else + dw_read_stringz(data); + } + else if (p < 8) + dw_skip_form(data, dir_fmt[p].form, is_64bit_dwarf); + } + } + if (lp.num_dirs > MAX_DIRS) lp.num_dirs = MAX_DIRS; + lp.include_directories = _dir_scratch[0 .. lp.num_dirs]; + + // File format + entries + num_pairs = dw_read!ubyte(data); + EntryFormatPair[8] file_fmt = void; + foreach (i; 0 .. num_pairs) + { + if (i < 8) + { + file_fmt[i].type = cast(DW_LNCT) dw_read_uleb128(data); + file_fmt[i].form = cast(DW_FORM) dw_read_uleb128(data); + } + } + + lp.num_files = cast(size_t) dw_read_uleb128(data); + foreach (f; 0 .. lp.num_files) + { + SourceFile sf; + sf.file = ""; + foreach (p; 0 .. num_pairs) + { + if (p < 8 && file_fmt[p].type == DW_LNCT.path && file_fmt[p].form == DW_FORM.string_) + sf.file = dw_read_stringz(data); + else if (p < 8 && file_fmt[p].type == DW_LNCT.directory_index) + { + if (file_fmt[p].form == DW_FORM.data1) + sf.dir_index = dw_read!ubyte(data); + else if (file_fmt[p].form == DW_FORM.data2) + sf.dir_index = dw_read!ushort(data); + else if (file_fmt[p].form == DW_FORM.udata) + sf.dir_index = cast(size_t) dw_read_uleb128(data); + else + dw_skip_form(data, file_fmt[p].form, is_64bit_dwarf); + sf.dir_index++; // DWARF v5 indices are 0-based, normalize to 1-based + } + else if (p < 8) + dw_skip_form(data, file_fmt[p].form, is_64bit_dwarf); + } + if (f < MAX_FILES) + _file_scratch[f] = sf; + } + if (lp.num_files > MAX_FILES) lp.num_files = MAX_FILES; + lp.source_files = _file_scratch[0 .. lp.num_files]; + } + else + { + // DWARF v3/v4: NUL-terminated sequences + lp.num_dirs = 0; + while (data.length > 0 && data[0] != 0) + { + auto dir = dw_read_stringz(data); + if (lp.num_dirs < MAX_DIRS) + _dir_scratch[lp.num_dirs++] = dir; + } + if (data.length > 0) data = data[1 .. $]; // skip NUL terminator + lp.include_directories = _dir_scratch[0 .. lp.num_dirs]; + + lp.num_files = 0; + while (data.length > 0 && data[0] != 0) + { + SourceFile sf; + sf.file = dw_read_stringz(data); + sf.dir_index = cast(size_t) dw_read_uleb128(data); + dw_read_uleb128(data); // last modification time + dw_read_uleb128(data); // file length + if (lp.num_files < MAX_FILES) + _file_scratch[lp.num_files++] = sf; + } + if (data.length > 0) data = data[1 .. $]; // skip NUL terminator + lp.source_files = _file_scratch[0 .. lp.num_files]; + } + + const program_start = cast(size_t)(min_insn_field_offset + lp.header_length); + const program_end = cast(size_t)(version_field_offset + lp.unit_length); + if (program_start <= original_data.length && program_end <= original_data.length) + lp.program = original_data[program_start .. program_end]; + + data = (program_end <= original_data.length) ? original_data[program_end .. $] : null; + + return lp; +} + +// Static scratch buffers for DWARF parsing (debug-only, no allocator needed). +private __gshared const(char)[][MAX_DIRS] _dir_scratch; +private __gshared SourceFile[MAX_FILES] _file_scratch; + +// --- DWARF state machine - resolve addresses to file:line --------- + +private struct ResolvedLocation +{ + const(char)[] file; + const(char)[] dir; + int line = -1; +} + +/// Resolve an array of addresses to file:line using .debug_line data. +private void dw_resolve_addresses( + const(ubyte)[] debug_line_data, + const(void*)[] addresses, + ResolvedLocation[] results, + size_t base_address) nothrow @nogc @trusted +{ + size_t found = 0; + const num_addrs = addresses.length; + + while (debug_line_data.length > 0 && found < num_addrs) + { + auto lp = dw_read_line_number_program(debug_line_data); + if (lp.program.length == 0) + break; + + StateMachine machine; + machine.is_statement = lp.default_is_statement; + + LocationInfo last_loc = LocationInfo(-1, -1); + const(void)* last_address; + + const(ubyte)[] prog = lp.program; + while (prog.length > 0) + { + size_t advance_addr(size_t op_advance) + { + const inc = lp.minimum_instruction_length * + ((machine.operation_index + op_advance) / lp.maximum_operations_per_instruction); + machine.address += inc; + machine.operation_index = + (machine.operation_index + op_advance) % lp.maximum_operations_per_instruction; + return inc; + } + + void emit_row(bool is_end) + { + auto addr = machine.address + base_address; + + foreach (idx; 0 .. num_addrs) + { + if (results[idx].line != -1) + continue; + auto target = addresses[idx]; + + void apply_loc(LocationInfo loc) + { + auto file_idx = loc.file - (lp.dwarf_version < 5 ? 1 : 0); + if (file_idx >= 0 && file_idx < lp.num_files) + { + results[idx].file = lp.source_files[file_idx].file; + auto di = lp.source_files[file_idx].dir_index; + if (di > 0 && di <= lp.num_dirs) + results[idx].dir = lp.include_directories[di - 1]; + } + results[idx].line = loc.line; + found++; + } + + if (target == addr) + apply_loc(LocationInfo(machine.file_index, machine.line)); + else if (last_address !is null && target > last_address && target < addr) + apply_loc(last_loc); + } + + if (is_end) + last_address = null; + else + { + last_address = addr; + last_loc = LocationInfo(machine.file_index, machine.line); + } + } + + ubyte opcode = prog[0]; prog = prog[1 .. $]; + + if (opcode >= lp.opcode_base) + { + // Special opcode + opcode -= lp.opcode_base; + advance_addr(opcode / lp.line_range); + machine.line += lp.line_base + (opcode % lp.line_range); + emit_row(false); + } + else if (opcode == 0) + { + // Extended opcode + auto len = cast(size_t) dw_read_uleb128(prog); + if (prog.length == 0) break; + ubyte eopcode = prog[0]; prog = prog[1 .. $]; + + switch (eopcode) + { + case ExtendedOpcode.end_sequence: + machine.is_end_sequence = true; + emit_row(true); + machine = StateMachine.init; + machine.is_statement = lp.default_is_statement; + break; + case ExtendedOpcode.set_address: + machine.address = dw_read!(const(void)*)(prog); + machine.operation_index = 0; + break; + case ExtendedOpcode.set_discriminator: + dw_read_uleb128(prog); + break; + default: + if (len > 1) + prog = prog[len - 1 .. $]; + break; + } + } + else switch (opcode) with (StandardOpcode) + { + case copy: + emit_row(false); + break; + case advance_pc: + advance_addr(cast(size_t) dw_read_uleb128(prog)); + break; + case advance_line: + machine.line += cast(int) dw_read_sleb128(prog); + break; + case set_file: + machine.file_index = cast(uint) dw_read_uleb128(prog); + break; + case set_column: + machine.column = cast(uint) dw_read_uleb128(prog); + break; + case negate_statement: + machine.is_statement = !machine.is_statement; + break; + case set_basic_block: + break; + case const_add_pc: + advance_addr((255 - lp.opcode_base) / lp.line_range); + break; + case fixed_advance_pc: + machine.address += dw_read!ushort(prog); + machine.operation_index = 0; + break; + case set_prologue_end: + case set_epilogue_begin: + break; + case set_isa: + dw_read_uleb128(prog); + break; + default: + // Unknown standard opcode: skip according to standard_opcode_lengths + if (opcode > 0 && opcode <= lp.standard_opcode_lengths.length) + { + foreach (_; 0 .. lp.standard_opcode_lengths[opcode - 1]) + dw_read_uleb128(prog); + } + break; + } + } + } +} + + + + +// --- Driver interface -------------------------------------------------- +// +// All three primitives assume they are called through a one-level public +// wrapper in urt.internal.exception (kept non-inlined via pragma(inline, +// false)). The wrapper's frame is accounted for in the skip counts +// below. Direct callers (like _d_createTrace) get the same semantics +// because their frame substitutes for the wrapper's. + +/// Capture the caller's call stack. First entry = return address of +/// the function that called the public `capture_trace` wrapper. +size_t _capture_trace(void*[] addrs) nothrow @nogc @trusted +{ + if (addrs.length == 0) + return 0; + + version (D_InlineAsm_X86_64) + { + size_t bp; + asm nothrow @nogc { mov bp, RBP; } + // Walk from _capture_trace's own frame up, storing caller frames. + size_t n = 0; + // Skip one: our own frame so first captured is wrapper/caller. + if (bp) + { + auto next = *cast(size_t*) bp; + if (next > bp) bp = next; + else bp = 0; + } + while (n < addrs.length) + { + if (!bp) break; + auto next_bp = *cast(size_t*) bp; + if (!next_bp || next_bp <= bp) break; + auto retaddr = *cast(void**)(bp + size_t.sizeof); + if (!retaddr) break; + addrs[n++] = retaddr; + bp = next_bp; + } + return n; + } + else version (D_InlineAsm_X86) + { + size_t bp; + asm nothrow @nogc { mov bp, EBP; } + size_t n = 0; + if (bp) + { + auto next = *cast(size_t*) bp; + if (next > bp) bp = next; + else bp = 0; + } + while (n < addrs.length) + { + if (!bp) break; + auto next_bp = *cast(size_t*) bp; + if (!next_bp || next_bp <= bp) break; + auto retaddr = *cast(void**)(bp + size_t.sizeof); + if (!retaddr) break; + addrs[n++] = retaddr; + bp = next_bp; + } + return n; + } + else + { + StackTraceData tmp; + unwind_backtrace(tmp); // skips its own frames internally + auto n = tmp.length < addrs.length ? tmp.length : addrs.length; + addrs[0 .. n] = tmp.addrs[0 .. n]; + return n; + } +} + +/// Return the return address of the `skip`-th frame above the public +/// `caller_address` wrapper's caller. +void* _caller_address(uint skip) nothrow @nogc @trusted +{ + void*[32] buf = void; + const n = _capture_trace(buf[]); + // _capture_trace, when invoked from _caller_address, lays out: + // buf[0] = PC inside the public wrapper + // buf[1] = PC inside USER (the caller_address caller) + // buf[2] = PC inside USER's caller ← skip=0 wants this + const want = skip + 2; + if (n <= want) + return null; + return buf[want]; +} + +/// Resolve via dladdr (symbol name + offset). File/line is omitted - +/// per-address DWARF scans would re-parse .debug_line on every call. +/// For full file:line info, use `_resolve_batch`, which amortises one +/// scan across all frames. +/// Returned `name` slice is owned by dladdr-internal storage - consume +/// before the next call. +bool _resolve_address(void* addr, out Resolved r) nothrow @nogc @trusted +{ + Dl_info info = void; + if (!dladdr(addr, &info) || info.dli_sname is null) + return false; + r.name = info.dli_sname[0 .. strlen(info.dli_sname)]; + r.offset = cast(size_t) addr - cast(size_t) info.dli_saddr; + return true; +} + +// Persistent .debug_line mapping. The first _resolve_batch call opens +// /proc/self/exe, finds .debug_line, mmap()s it, and closes the fd. +// We never unmap - the slice handed back to callers via Resolved.file +// and Resolved.dir points into this region, and the API contract +// promises stability until the next _resolve_batch call. Holding the +// mapping for process lifetime is the cheapest way to satisfy that +// (a few MB of read-only file pages the OS can demand-page). +private __gshared bool _elf_init_attempted; +private __gshared const(ubyte)[] _persistent_debug_line; +private __gshared size_t _persistent_base_addr; + +private void ensure_debug_line_mapped() nothrow @nogc @trusted +{ + if (_elf_init_attempted) + return; + _elf_init_attempted = true; + + auto elf = ElfSelf.open(); + scope(exit) elf.close(); + if (!elf.valid()) + return; + + size_t dbg_offset, dbg_size; + if (!elf.find_section(".debug_line", dbg_offset, dbg_size)) + return; + + auto region = MappedRegion.map(elf.fd, dbg_offset, dbg_size); + if (region.data is null) + return; + // Intentionally not unmapped - kept for process lifetime. + + _persistent_debug_line = region.data[0 .. dbg_size]; + _persistent_base_addr = (elf.ehdr.e_type == ET_DYN) + ? get_executable_base_address() : cast(size_t) 0; +} + +/// Resolve many addresses in one pass: dladdr per address for symbol +/// name + offset, then a single DWARF .debug_line scan to fill file / +/// dir / line for all of them at once. +/// +/// String slices point into dladdr-internal storage, the static DWARF +/// scratch buffers (`_dir_scratch`, `_file_scratch`), or the persistent +/// .debug_line mapping. All three remain valid until the next +/// `_resolve_batch` call overwrites the scratch buffers; copy if you +/// need fields to outlive that. +bool _resolve_batch(const(void*)[] addrs, Resolved[] results) nothrow @nogc @trusted +{ + // Symbol + offset via dladdr (per-address; dladdr is O(1)-ish via + // the dynamic linker's hash tables). + bool any_resolved = false; + foreach (i, a; addrs) + { + Dl_info info = void; + if (dladdr(cast(void*) a, &info) && info.dli_sname !is null) + { + results[i].name = info.dli_sname[0 .. strlen(info.dli_sname)]; + results[i].offset = cast(size_t) a - cast(size_t) info.dli_saddr; + any_resolved = true; + } + } + + // File / line via one DWARF .debug_line scan covering all addrs. + // Failures here still leave dladdr-populated name/offset intact. + ensure_debug_line_mapped(); + if (_persistent_debug_line.length == 0) + return any_resolved; + + ResolvedLocation[32] locations; + const n = addrs.length > locations.length ? locations.length : addrs.length; + + dw_resolve_addresses( + _persistent_debug_line, + addrs[0 .. n], + locations[0 .. n], + _persistent_base_addr); + + foreach (i; 0 .. n) + { + if (locations[i].line >= 0) + { + results[i].file = locations[i].file; + results[i].dir = locations[i].dir; + results[i].line = cast(uint) locations[i].line; + any_resolved = true; + } + } + return any_resolved; +} diff --git a/src/urt/driver/posix/gpio.d b/src/urt/driver/posix/gpio.d new file mode 100644 index 0000000..71f4825 --- /dev/null +++ b/src/urt/driver/posix/gpio.d @@ -0,0 +1,131 @@ +// Linux GPIO via legacy /sys/class/gpio sysfs. Targets SBCs (Pi, Orange +// Pi, BeagleBone) where the kernel exposes pins as files. Pin numbering +// is the kernel's flat global GPIO number; each board documents its +// mapping. +// +// Sysfs is deprecated since Linux 4.8 in favour of gpio-cdev +// (/dev/gpiochipN ioctl) but ships in every shipping kernel. cdev +// backend is a future TODO. +// +// Limitations: no pull config (sysfs doesn't expose it; pulls come from +// device tree or external resistors), no peripheral muxing (kernel +// owns it), and one open/close per op (~10us each, fine for management +// rates). +module urt.driver.posix.gpio; + +import urt.driver.gpio : Pull, DriveMode; +import urt.file : File, FileOpenMode, save_file, open, close, read; +import urt.mem.temp : tconcat; + +nothrow @nogc: + + +enum uint num_gpio = 256; +enum bool has_pull_up = false; +enum bool has_pull_down = false; +enum bool has_open_drain = false; +enum bool has_pin_function_muxing = false; + + +// Walks /sys/class/gpio/gpiochip/{base,ngpio} for N in 0..64 (covers +// real SBCs incl. Pi 5 where chips are at 0 and 4) and returns +// max(base+ngpio). 0 means no GPIO chips registered in sysfs. +uint gpio_count() +{ + uint max_pin = 0; + foreach (i; 0 .. 64) + { + uint base, ngpio; + if (!read_uint_file(tconcat("/sys/class/gpio/gpiochip", i, "/base"), base)) + continue; + if (!read_uint_file(tconcat("/sys/class/gpio/gpiochip", i, "/ngpio"), ngpio)) + continue; + uint top = base + ngpio; + if (top > max_pin) + max_pin = top; + } + return max_pin; +} + +void gpio_output_init(uint pin, bool initial = false, DriveMode mode = DriveMode.push_pull) +{ + assert(mode == DriveMode.push_pull, "posix gpio: open-drain not supported via sysfs"); + save_file("/sys/class/gpio/export", tconcat(pin)); // EBUSY = already exported + // "low" / "high" atomically set direction=out plus initial value. + save_file(tconcat("/sys/class/gpio/gpio", pin, "/direction"), initial ? "high" : "low"); +} + +void gpio_input_init(uint pin, Pull pull = Pull.none) +{ + save_file("/sys/class/gpio/export", tconcat(pin)); + save_file(tconcat("/sys/class/gpio/gpio", pin, "/direction"), "in"); +} + +void gpio_output_set(uint pin, bool value) +{ + save_file(tconcat("/sys/class/gpio/gpio", pin, "/value"), value ? "1" : "0"); +} + +void gpio_output_toggle(uint pin) +{ + auto path = tconcat("/sys/class/gpio/gpio", pin, "/value"); + bool current; + if (!read_bool_file(path, current)) + return; + save_file(path, current ? "0" : "1"); +} + +bool gpio_input_read(uint pin) +{ + bool v; + return read_bool_file(tconcat("/sys/class/gpio/gpio", pin, "/value"), v) && v; +} + +void gpio_set_pull(uint pin, Pull pull) +{ +} + +void gpio_release(uint pin) +{ + save_file("/sys/class/gpio/unexport", tconcat(pin)); +} + + +private: + +bool read_bool_file(const(char)[] path, out bool value) +{ + File f; + if (!f.open(path, FileOpenMode.ReadExisting)) + return false; + ubyte[2] buf; + size_t n; + auto r = f.read(buf, n); + f.close(); + if (!r || n == 0) + return false; + value = buf[0] == '1'; + return true; +} + +bool read_uint_file(const(char)[] path, out uint value) +{ + File f; + if (!f.open(path, FileOpenMode.ReadExisting)) + return false; + ubyte[16] buf; + size_t n; + auto r = f.read(buf, n); + f.close(); + if (!r) + return false; + uint v = 0; + foreach (c; buf[0 .. n]) + { + if (c < '0' || c > '9') + break; + v = v * 10 + (c - '0'); + } + value = v; + return true; +} diff --git a/src/urt/driver/rp2350/alloc.d b/src/urt/driver/rp2350/alloc.d new file mode 100644 index 0000000..44d71e9 --- /dev/null +++ b/src/urt/driver/rp2350/alloc.d @@ -0,0 +1,37 @@ +module urt.driver.rp2350.alloc; + +import urt.mem.alloc : MemFlags; + +nothrow @nogc: + +enum has_realloc = false; +enum has_expand = false; +enum has_memsize = false; +enum has_exec = false; +enum has_retain = false; +enum has_memflags = false; + +void[] _alloc(size_t size, size_t alignment, MemFlags) pure +{ + import urt.util : align_down; + + size_t header_size = (void*).sizeof + alignment; + void* p = malloc(header_size + size); + if (p is null) + return null; + + size_t allocptr = align_down(cast(size_t)p + header_size, alignment); + (cast(void**)allocptr)[-1] = p; + return (cast(void*)allocptr)[0 .. size]; +} + +void _free(void* ptr) pure +{ + free((cast(void**)ptr)[-1]); +} + + +private: + +extern(C) void* malloc(size_t size) pure; +extern(C) void free(void* ptr) pure; diff --git a/src/urt/driver/rp2350/boot2.S b/src/urt/driver/rp2350/boot2.S new file mode 100644 index 0000000..4d9514b --- /dev/null +++ b/src/urt/driver/rp2350/boot2.S @@ -0,0 +1,69 @@ +/* RP2350 second-stage bootloader (boot2) + * + * The RP2350 ROM reads this 256-byte block from the start of QSPI flash, + * copies it to SRAM, and executes it. boot2's job is to configure the + * QSPI controller for XIP (execute-in-place), then return to the ROM + * which will then load the vector table from flash. + * + * This is a minimal stub that configures generic 03h SPI read mode. + * It works with any standard SPI flash but is slow (single-bit, no XIP cache). + * For production, replace with the Pico SDK's boot2_w25q080.S (or similar) + * which enables QSPI and continuous read mode for much better performance. + * + * The block must be exactly 256 bytes. The last 4 bytes are a CRC32 + * checksum of the first 252 bytes (verified by the ROM before execution). + */ + + .syntax unified + .cpu cortex-m33 + .thumb + + .section .boot2, "ax" + .global __boot2_entry + .type __boot2_entry, %function +__boot2_entry: + +/* SSI (Synopsys SSI / QSPI controller) registers */ +.equ SSI_BASE, 0x18000000 +.equ SSI_CTRLR0, 0x00 +.equ SSI_SSIENR, 0x08 /* SSI enable */ +.equ SSI_SPI_CTRLR0, 0xF4 /* SPI control register */ + +/* Configure SSI for standard SPI 03h read, 32-bit address+data frames */ + + /* Disable SSI while configuring */ + ldr r3, =SSI_BASE + movs r0, #0 + str r0, [r3, #SSI_SSIENR] + + /* CTRLR0: 8-bit data frames, SPI mode 0 (CPOL=0, CPHA=0) */ + movs r0, #0x07 /* DFS = 8-1 = 7 (8-bit frames) */ + movs r1, #0 + orr r0, r0, r1 /* TMOD=0 (TX+RX), FRF=0 (Motorola SPI) */ + str r0, [r3, #SSI_CTRLR0] + + /* SPI_CTRLR0: standard 03h read, 24-bit address, 8 wait cycles */ + movs r0, #0x03 /* INST_L=8bit (0x03), ADDR_L=24bit */ + lsls r1, r0, #0 + movs r0, #0x06 /* ADDR_L = 24 bits (6 * 4) */ + lsls r0, r0, #2 + orr r1, r1, r0 + /* TRANS_TYPE = 0 (instruction + address both in standard SPI) */ + str r1, [r3, #SSI_SPI_CTRLR0] + + /* Re-enable SSI */ + movs r0, #1 + str r0, [r3, #SSI_SSIENR] + + /* Return to ROM -- it will now use XIP to read the vector table */ + bx lr + + .size __boot2_entry, . - __boot2_entry + + /* Pad to 252 bytes (256 - 4 byte CRC32 at end) */ + .balign 256, 0x00 + /* CRC32 placeholder -- must be computed by the build tooling or + * flash programmer. The Pico SDK's pad_checksum tool does this. + * For now, set to zero -- will need post-processing before flashing. */ + + .size __boot2_entry, . - __boot2_entry diff --git a/src/urt/driver/rp2350/irq.d b/src/urt/driver/rp2350/irq.d new file mode 100644 index 0000000..c57c3b2 --- /dev/null +++ b/src/urt/driver/rp2350/irq.d @@ -0,0 +1,123 @@ +// RP2350 interrupt controller driver +// +// Cortex-M33 uses the standard ARM NVIC (Nested Vectored Interrupt Controller). +// RP2350 has 52 peripheral interrupts (IRQ 0-51). +module urt.driver.rp2350.irq; + +@nogc nothrow: + +enum bool has_plic = false; +enum bool has_nvic = true; +enum bool has_clic = false; +enum bool has_per_irq_control = true; +enum bool has_irq_priority = true; +enum bool has_wait_for_interrupt = false; +enum bool has_irq_diagnostics = false; +enum bool has_global_irq_state = true; +enum bool has_smp = false; +enum uint irq_max = 52; + +import core.volatile; + +// NVIC registers (ARM standard) +private enum ulong NVIC_ISER0 = 0xE000E100; // Interrupt Set Enable (2 words for 52 IRQs) +private enum ulong NVIC_ICER0 = 0xE000E180; // Interrupt Clear Enable +private enum ulong NVIC_ISPR0 = 0xE000E200; // Interrupt Set Pending +private enum ulong NVIC_ICPR0 = 0xE000E280; // Interrupt Clear Pending +private enum ulong NVIC_IPR0 = 0xE000E400; // Interrupt Priority (byte-accessible) + +// Cortex-M33 PRIMASK: bit 0 set means interrupts masked. Read it before +// mutating so callers (IrqGuard) can restore prior state. +bool irq_disable() +{ + uint primask; + asm @nogc nothrow + { + ` + mrs %0, primask + cpsid i + ` + : "=r" (primask); + } + return (primask & 1) == 0; +} + +bool irq_enable() +{ + uint primask; + asm @nogc nothrow + { + ` + mrs %0, primask + cpsie i + ` + : "=r" (primask); + } + return (primask & 1) == 0; +} + +// Enable a specific peripheral IRQ (0-51). Returns previous state. +bool irq_set_enable(uint irq_num) +{ + immutable reg = irq_num / 32; + immutable bit = irq_num % 32; + auto iser = cast(uint*)(NVIC_ISER0 + reg * 4); + bool prev = (volatileLoad(iser) & (1u << bit)) != 0; + volatileStore(iser, 1u << bit); + return prev; +} + +// Disable a specific peripheral IRQ. Returns previous state. +bool irq_clear_enable(uint irq_num) +{ + immutable reg = irq_num / 32; + immutable bit = irq_num % 32; + auto iser = cast(uint*)(NVIC_ISER0 + reg * 4); + bool prev = (volatileLoad(iser) & (1u << bit)) != 0; + volatileStore(cast(uint*)(NVIC_ICER0 + reg * 4), 1u << bit); + return prev; +} + +// Set priority for a peripheral IRQ (0 = highest, 255 = lowest) +// Cortex-M33 on RP2350 implements 4 priority bits (top 4 of 8) +void irq_set_priority(uint irq_num, ubyte priority) +{ + volatileStore(cast(ubyte*)(NVIC_IPR0 + irq_num), priority); +} + + +// Handler registration + +alias IrqHandler = void function(uint irq) @nogc nothrow; + +__gshared IrqHandler[irq_max] _handlers; + +// Install a handler for a peripheral IRQ (0..irq_max-1). Returns the previous. +// The flash vector table routes every peripheral vector at _nvic_dispatch, +// which recovers the active IRQ from IPSR and calls the registered handler. +IrqHandler irq_set_handler(uint irq, IrqHandler handler) +{ + if (irq >= irq_max) + return null; + IrqHandler prev = _handlers[irq]; + _handlers[irq] = handler; + return prev; +} + +// Common entry for every peripheral vector. A plain AAPCS function is a valid +// Cortex-M exception handler: on entry the core has stacked the caller context +// and set lr to EXC_RETURN, so the normal function return triggers exception +// return. IPSR holds the active exception number; peripheral IRQ n is exception +// n + 16. +extern(C) void _nvic_dispatch() +{ + uint ipsr; + asm @nogc nothrow { "mrs %0, ipsr" : "=r" (ipsr); } + uint irq = ipsr - 16; + if (irq < irq_max) + { + IrqHandler h = _handlers[irq]; + if (h !is null) + h(irq); + } +} diff --git a/src/urt/driver/rp2350/package.d b/src/urt/driver/rp2350/package.d new file mode 100644 index 0000000..b19fd8d --- /dev/null +++ b/src/urt/driver/rp2350/package.d @@ -0,0 +1,96 @@ +// RP2350 platform package (ARM Cortex-M33) +// +// Provides sys_init() as the single entry point for all +// hardware initialization. Called from start.S before main(). +module urt.driver.rp2350; + +public import urt.driver.rp2350.uart; +public import urt.driver.rp2350.irq; +public import urt.driver.rp2350.timer; + +import urt.driver.uart : UartConfig; +import core.volatile; + +@nogc nothrow: + +private extern(C) void __register_frame_info(const void*, void*); +private extern(C) extern const ubyte __eh_frame_start; +private ubyte[48] __eh_frame_object; // storage for libgcc (no-op on ARM EHABI) + +// RP2350 peripheral base addresses +enum ulong RESETS_BASE = 0x40020000; +enum ulong CLOCKS_BASE = 0x40010000; +enum ulong XOSC_BASE = 0x40048000; +enum ulong PLL_SYS_BASE = 0x40060000; +enum ulong SIO_BASE = 0xD0000000; +enum ulong IO_BANK0_BASE = 0x40028000; +enum ulong PADS_BANK0_BASE = 0x40038000; + +// Atomic set/clear/xor aliases (RP2350 address alias trick) +enum ulong REG_ALIAS_SET = 0x00002000; +enum ulong REG_ALIAS_CLR = 0x00003000; + +// RESETS register offsets +enum ulong RESETS_RESET = 0x00; +enum ulong RESETS_DONE = 0x08; + +// Reset bits for peripherals we need early +enum uint RESET_UART0 = 1 << 26; +enum uint RESET_UART1 = 1 << 27; +enum uint RESET_IO_BANK0 = 1 << 8; +enum uint RESET_PADS_BANK0 = 1 << 9; + +private void mmio_write(ulong addr, uint val) @nogc nothrow +{ + volatileStore(cast(uint*)addr, val); +} + +private uint mmio_read(ulong addr) @nogc nothrow +{ + return volatileLoad(cast(uint*)addr); +} + +// Take peripherals out of reset and wait for them to be ready +private void unreset_wait(uint bits) +{ + // Clear reset bits (take out of reset) + mmio_write(RESETS_BASE + RESETS_RESET + REG_ALIAS_CLR, bits); + // Wait for reset done + while ((mmio_read(RESETS_BASE + RESETS_DONE) & bits) != bits) + {} +} + +// Initialize all clocks, peripherals, and I/O needed at boot. +// Order matters: +// 1. Unreset GPIO and UART pads +// 2. Configure GPIO pins for UART0 +// 3. Initialize UART0 for console output +// 4. Set up SysTick timer +extern(C) void sys_init() +{ + __register_frame_info(&__eh_frame_start, &__eh_frame_object); + + // Bring up IO bank and pads, then UART0 + unreset_wait(RESET_IO_BANK0 | RESET_PADS_BANK0 | RESET_UART0); + + // GPIO0 = UART0 TX, GPIO1 = UART0 RX (function 2 on RP2350) + // IO_BANK0 GPIO_CTRL registers are at offset 0x04 + n*0x08 + enum ulong GPIO0_CTRL = IO_BANK0_BASE + 0x04; + enum ulong GPIO1_CTRL = IO_BANK0_BASE + 0x0C; + mmio_write(GPIO0_CTRL, 2); // FUNCSEL = UART + mmio_write(GPIO1_CTRL, 2); // FUNCSEL = UART + + // Init UART0 at default baud for early console + uart_hw_init(0, UartConfig.init); + + uart0_hw_puts("RP2350: sys_init\r\n"); + + // SysTick: 20Hz tick (50ms) for the main loop + // Default clock is ~150MHz after PLL init, but we're running on the + // ring oscillator (~6MHz) until clock init is implemented. + // SysTick reload = clock_hz / desired_hz - 1 + // At 6MHz ring osc: 6_000_000 / 20 - 1 = 299_999 + timer_init(299_999); + + uart0_hw_puts("RP2350: ready\r\n"); +} diff --git a/src/urt/driver/rp2350/start.S b/src/urt/driver/rp2350/start.S new file mode 100644 index 0000000..f201e82 --- /dev/null +++ b/src/urt/driver/rp2350/start.S @@ -0,0 +1,246 @@ +/* RP2350 (ARM Cortex-M33) startup + * + * Boot flow: + * 1. ROM bootloader loads 256-byte boot2 from flash, runs it from SRAM + * 2. boot2 configures QSPI flash for XIP, then returns to ROM + * 3. ROM reads vector table from flash: initial SP + Reset_Handler + * 4. Reset_Handler runs: + * a. Copy .got from flash to SRAM + * b. Copy .data from flash to SRAM + * c. Copy .tdata from flash to SRAM + * d. Zero .tbss + .bss + * e. Enable FPU (Cortex-M33 has optional FPv5-SP) + * f. Call sys_init (platform init) + * g. Run .init_array (D module constructors) + * h. Call main + * + * RP2350B register addresses: + * RESETS: 0x40020000 (peripheral reset control) + * CLOCKS: 0x40010000 + * SIO: 0xD0000000 (single-cycle I/O for GPIO, spinlocks) + * UART0: 0x40070000 + * UART1: 0x40078000 + */ + + .syntax unified + .cpu cortex-m33 + .fpu fpv5-sp-d16 + .thumb + +/* ================================================================ + * Vector table -- placed at start of FLASH (after boot2) + * Cortex-M reads entry 0 as initial SP, entry 1 as Reset_Handler + * ================================================================ */ + .section .vector_table, "a" + .global __vector_table + .type __vector_table, %object +__vector_table: + .word _stack_top /* 0: Initial stack pointer */ + .word Reset_Handler /* 1: Reset */ + .word NMI_Handler /* 2: NMI */ + .word HardFault_Handler /* 3: Hard fault */ + .word MemManage_Handler /* 4: MPU fault */ + .word BusFault_Handler /* 5: Bus fault */ + .word UsageFault_Handler /* 6: Usage fault */ + .word SecureFault_Handler /* 7: Secure fault (ARMv8-M) */ + .word 0 /* 8: Reserved */ + .word 0 /* 9: Reserved */ + .word 0 /* 10: Reserved */ + .word SVCall_Handler /* 11: SVCall */ + .word DebugMon_Handler /* 12: Debug monitor */ + .word 0 /* 13: Reserved */ + .word PendSV_Handler /* 14: PendSV */ + .word SysTick_Handler /* 15: SysTick */ + + /* IRQ 0-51 (RP2350 has 52 peripheral interrupts). Every peripheral + * vector routes to _nvic_dispatch, which recovers the IRQ from IPSR and + * calls the handler registered via irq_set_handler. */ + .rept 52 + .word _nvic_dispatch + .endr + + .size __vector_table, . - __vector_table + +/* ================================================================ + * Reset handler + * ================================================================ */ + .section .text, "ax" + .global Reset_Handler + .type Reset_Handler, %function + .thumb_func +Reset_Handler: + + /* -- Copy .got from flash (LMA) to SRAM (VMA) -- */ + ldr r0, =_got_start + ldr r1, =_got_load + ldr r2, =_got_end + cmp r0, r1 /* skip if VMA == LMA (not relocated) */ + beq .Lgot_done + b .Lgot_check +.Lgot_copy: + ldm r1!, {r3} + stm r0!, {r3} +.Lgot_check: + cmp r0, r2 + blo .Lgot_copy +.Lgot_done: + + /* -- Copy .data from flash to SRAM -- */ + ldr r0, =_data_start + ldr r1, =_data_load + ldr r2, =_data_end + b .Ldata_check +.Ldata_copy: + ldm r1!, {r3} + stm r0!, {r3} +.Ldata_check: + cmp r0, r2 + blo .Ldata_copy + + /* -- Copy .tdata from flash to SRAM -- */ + ldr r0, =_tdata_start + ldr r1, =_tdata_load + ldr r2, =_tdata_end + b .Ltdata_check +.Ltdata_copy: + ldm r1!, {r3} + stm r0!, {r3} +.Ltdata_check: + cmp r0, r2 + blo .Ltdata_copy + + /* -- Zero .tbss -- */ + ldr r0, =_tbss_start + ldr r2, =_tbss_end + movs r3, #0 + b .Ltbss_check +.Ltbss_zero: + stm r0!, {r3} +.Ltbss_check: + cmp r0, r2 + blo .Ltbss_zero + + /* -- Zero .bss -- */ + ldr r0, =_bss_start + ldr r2, =_bss_end + movs r3, #0 + b .Lbss_check +.Lbss_zero: + stm r0!, {r3} +.Lbss_check: + cmp r0, r2 + blo .Lbss_zero + + /* -- Enable FPU (CP10 + CP11 full access) -- */ + ldr r0, =0xE000ED88 /* CPACR */ + ldr r1, [r0] + orr r1, r1, #(0xF << 20) + str r1, [r0] + dsb + isb + + /* -- Platform init -- */ + bl sys_init + + /* -- Run .init_array (D module constructors) -- */ + ldr r4, =__init_array_start + ldr r5, =__init_array_end + b .Linit_check +.Linit_loop: + ldr r0, [r4] + blx r0 + adds r4, r4, #4 +.Linit_check: + cmp r4, r5 + blo .Linit_loop + + /* -- Enter main (should never return) -- */ + bl main + + /* If main returns, spin */ +.Lhalt: + wfi + b .Lhalt + + .size Reset_Handler, . - Reset_Handler + +/* ================================================================ + * Default exception/interrupt handlers (weak, overridable) + * ================================================================ */ + .thumb_func + .weak NMI_Handler + .type NMI_Handler, %function +NMI_Handler: + b . + + .thumb_func + .weak HardFault_Handler + .type HardFault_Handler, %function +HardFault_Handler: + b . + + .thumb_func + .weak MemManage_Handler + .type MemManage_Handler, %function +MemManage_Handler: + b . + + .thumb_func + .weak BusFault_Handler + .type BusFault_Handler, %function +BusFault_Handler: + b . + + .thumb_func + .weak UsageFault_Handler + .type UsageFault_Handler, %function +UsageFault_Handler: + b . + + .thumb_func + .weak SecureFault_Handler + .type SecureFault_Handler, %function +SecureFault_Handler: + b . + + .thumb_func + .weak SVCall_Handler + .type SVCall_Handler, %function +SVCall_Handler: + b . + + .thumb_func + .weak DebugMon_Handler + .type DebugMon_Handler, %function +DebugMon_Handler: + b . + + .thumb_func + .weak PendSV_Handler + .type PendSV_Handler, %function +PendSV_Handler: + b . + + .thumb_func + .weak SysTick_Handler + .type SysTick_Handler, %function +SysTick_Handler: + b . + + .thumb_func + .weak Default_Handler + .type Default_Handler, %function +Default_Handler: + b . + +/* ================================================================ + * __aeabi_read_tp -- ARM EABI thread pointer for TLS access + * Single-threaded bare-metal: return fixed pointer to .tdata + * ================================================================ */ + .global __aeabi_read_tp + .type __aeabi_read_tp, %function + .thumb_func +__aeabi_read_tp: + ldr r0, =_tdata_start + bx lr + .size __aeabi_read_tp, . - __aeabi_read_tp diff --git a/src/urt/driver/rp2350/syscalls.d b/src/urt/driver/rp2350/syscalls.d new file mode 100644 index 0000000..bb603b4 --- /dev/null +++ b/src/urt/driver/rp2350/syscalls.d @@ -0,0 +1,52 @@ +// RP2350 newlib/picolibc syscall stubs +// +// Minimal stubs to satisfy picolibc's syscall requirements. +// Same pattern as BL618 -- most are no-ops for baremetal. +module urt.driver.rp2350.syscalls; + +@nogc nothrow: + +private extern(C) extern const void* __heap_start; +private extern(C) extern const void* __heap_end; + +private __gshared void* _heap_ptr; + +extern(C) void* _sbrk(ptrdiff_t incr) +{ + if (_heap_ptr is null) + _heap_ptr = cast(void*)&__heap_start; + + void* prev = _heap_ptr; + void* next = _heap_ptr + incr; + + if (next > cast(void*)&__heap_end) + return cast(void*)-1; + + _heap_ptr = next; + return prev; +} + +extern(C) int _write(int fd, const void* buf, size_t count) +{ + import urt.driver.rp2350.uart : uart0_hw_puts; + if (fd == 1 || fd == 2) + uart0_hw_puts((cast(const(char)*)buf)[0 .. count]); + return cast(int)count; +} + +extern(C) int _read(int, void*, size_t) { return 0; } +extern(C) int _close(int) { return -1; } +extern(C) int _lseek(int, int, int) { return 0; } +extern(C) int _fstat(int, void*) { return 0; } +extern(C) int _isatty(int) { return 1; } +extern(C) void _exit(int) { while (true) {} } +extern(C) int _kill(int, int) { return -1; } +extern(C) int _getpid() { return 1; } + +// DWARF unwinder stubs -- ARM Cortex-M uses EHABI, not DWARF. +// These satisfy link-time references from the D runtime's exception +// personality code which assumes DWARF on all platforms. +extern(C) void __register_frame_info(const void*, void*) {} +extern(C) size_t _Unwind_GetIPInfo(void*, int*) { return 0; } +extern(C) void _Unwind_SetGR(void*, int, size_t) {} +extern(C) void _Unwind_SetIP(void*, size_t) {} diff --git a/src/urt/driver/rp2350/timer.d b/src/urt/driver/rp2350/timer.d new file mode 100644 index 0000000..e79c8ef --- /dev/null +++ b/src/urt/driver/rp2350/timer.d @@ -0,0 +1,80 @@ +// RP2350 timer driver +// +// Uses the ARM Cortex-M33 SysTick timer for the periodic main loop tick. +// SysTick is a 24-bit down-counter clocked from the processor clock. +// +// RP2350 also has a 64-bit microsecond timer at 0x400B_0000 (TIMER0) +// which can be used for wall-clock time -- not yet implemented here. +module urt.driver.rp2350.timer; + +import core.volatile; + +@nogc nothrow: + +enum uint mtime_freq_hz = 1_000_000; // TIMER0 runs at 1MHz (microsecond counter) +enum bool has_mtime = true; +enum bool has_rtc = false; +enum bool has_mcycle = false; +enum bool has_timer_stop = false; +enum bool has_oneshot_timer = false; + +// RP2350 TIMER0: 64-bit free-running microsecond counter at 0x400B_0000 +// Always enabled, always 1MHz. Read TIMELR first (latches TIMEHR). +private enum uint TIMER0_BASE = 0x400B_0000; +private enum uint TIMEHR = TIMER0_BASE + 0x08; // Time read high (latched on TIMELR read) +private enum uint TIMELR = TIMER0_BASE + 0x0C; // Time read low (triggers latch) + +// SysTick registers (ARM standard, part of the System Control Block) +private enum uint SYST_CSR = 0xE000_E010; +private enum uint SYST_RVR = 0xE000_E014; +private enum uint SYST_CVR = 0xE000_E018; + +private enum uint CSR_ENABLE = 1 << 0; +private enum uint CSR_TICKINT = 1 << 1; +private enum uint CSR_CLKSOURCE = 1 << 2; + +alias TimerCallback = void function() @nogc nothrow; + +private __gshared TimerCallback tick_callback; + +void timer_init(uint reload_value) +{ + volatileStore(cast(uint*)(cast(size_t)SYST_RVR), reload_value & 0x00FFFFFF); + volatileStore(cast(uint*)(cast(size_t)SYST_CVR), 0); + volatileStore(cast(uint*)(cast(size_t)SYST_CSR), CSR_ENABLE | CSR_TICKINT | CSR_CLKSOURCE); +} + +void timer_hw_init() +{ + // TIMER0 is always running at 1MHz on RP2350 -- nothing to init. +} + +// Read 64-bit monotonic microsecond counter. +// Must read TIMELR first -- this latches TIMEHR atomically. +ulong mtime_read() +{ + uint lo = volatileLoad(cast(uint*)(cast(size_t)TIMELR)); + uint hi = volatileLoad(cast(uint*)(cast(size_t)TIMEHR)); + return (cast(ulong)hi << 32) | lo; +} + +void timer_set_periodic(uint period_ticks, TimerCallback cb) +{ + tick_callback = cb; + // Use SysTick for periodic interrupts. + // period_ticks is in timer ticks (microseconds at 1MHz). + // SysTick runs from processor clock -- assume 150MHz after PLL init. + // Convert: systick_reload = period_us * 150 + uint reload = period_ticks * 150; + if (reload > 0x00FF_FFFF) + reload = 0x00FF_FFFF; // SysTick is 24-bit + volatileStore(cast(uint*)(cast(size_t)SYST_RVR), reload); + volatileStore(cast(uint*)(cast(size_t)SYST_CVR), 0); + volatileStore(cast(uint*)(cast(size_t)SYST_CSR), CSR_ENABLE | CSR_TICKINT | CSR_CLKSOURCE); +} + +extern(C) void SysTick_Handler() @nogc nothrow +{ + if (tick_callback !is null) + tick_callback(); +} diff --git a/src/urt/driver/rp2350/uart.d b/src/urt/driver/rp2350/uart.d new file mode 100644 index 0000000..ccee2a1 --- /dev/null +++ b/src/urt/driver/rp2350/uart.d @@ -0,0 +1,195 @@ +// RP2350 UART driver +// +// RP2350 has 2x PL011 UARTs: +// UART0 0x4007_0000 Default console (GPIO0=TX, GPIO1=RX) +// UART1 0x4007_8000 General purpose (GPIO4=TX, GPIO5=RX typical) +// +// PL011 register layout (ARM PrimeCell UART). +module urt.driver.rp2350.uart; + +import core.volatile; + +import urt.driver.uart : Parity, StopBits, UartConfig; + +nothrow @nogc: + +enum num_uarts = 2; +enum uint uart_clock_hz = 6_000_000; +enum bool has_irq_driven_uart = false; +enum bool has_dma_driven_uart = false; + +// PL011 register offsets +private enum +{ + UARTDR = 0x000, // Data register + UARTRSR = 0x004, // Receive status / error clear + UARTFR = 0x018, // Flag register + UARTILPR = 0x020, // IrDA low-power counter + UARTIBRD = 0x024, // Integer baud rate divisor + UARTFBRD = 0x028, // Fractional baud rate divisor + UARTLCR_H = 0x02C, // Line control + UARTCR = 0x030, // Control register + UARTIFLS = 0x034, // Interrupt FIFO level select + UARTIMSC = 0x038, // Interrupt mask set/clear + UARTRIS = 0x03C, // Raw interrupt status + UARTMIS = 0x040, // Masked interrupt status + UARTICR = 0x044, // Interrupt clear + UARTDMACR = 0x048, // DMA control +} + +// Flag register bits +private enum +{ + FR_TXFF = 1 << 5, // TX FIFO full + FR_RXFE = 1 << 4, // RX FIFO empty + FR_BUSY = 1 << 3, // UART busy transmitting +} + +// Control register bits +private enum +{ + CR_UARTEN = 1 << 0, // UART enable + CR_TXE = 1 << 8, // TX enable + CR_RXE = 1 << 9, // RX enable +} + +private ulong uart_base(uint id) +{ + return (id == 0) ? 0x40070000 : 0x40078000; +} + +private void uart_write_reg(ulong base, uint offset, uint val) +{ + volatileStore(cast(uint*)(base + offset), val); +} + +private uint uart_read_reg(ulong base, uint offset) +{ + return volatileLoad(cast(uint*)(base + offset)); +} + +// Assumed peripheral clock -- ring oscillator ~6MHz at boot. +// After PLL init this should be updated to the actual peri_clk frequency. +private __gshared uint peri_clk_hz = 6_000_000; + +bool uart_hw_init(uint id, UartConfig cfg) +{ + immutable base = uart_base(id); + + // Disable UART while configuring + uart_write_reg(base, UARTCR, 0); + + // Baud rate: BAUDDIV = peri_clk / (16 * baud) + // Integer part = BAUDDIV + // Fractional part = (frac * 64 + 0.5) + immutable uint bauddiv_x64 = (peri_clk_hz * 4) / cfg.baud_rate; + immutable uint ibrd = bauddiv_x64 / 64; + immutable uint fbrd = bauddiv_x64 % 64; + uart_write_reg(base, UARTIBRD, ibrd); + uart_write_reg(base, UARTFBRD, fbrd); + + // Line control: 8N1, FIFO enable + uint lcr = 0; + lcr |= (cfg.data_bits - 5) << 5; // WLEN: 5=0b00, 6=0b01, 7=0b10, 8=0b11 + lcr |= 1 << 4; // FEN: enable FIFOs + if (cfg.parity != Parity.none) + { + lcr |= 1 << 1; // PEN: parity enable + if (cfg.parity == Parity.even) + lcr |= 1 << 2; // EPS: even parity + } + if (cfg.stop_bits != StopBits.one) + lcr |= 1 << 3; // STP2: 2 stop bits + uart_write_reg(base, UARTLCR_H, lcr); + + // Enable UART, TX, RX + uart_write_reg(base, UARTCR, CR_UARTEN | CR_TXE | CR_RXE); + + return true; +} + +bool uart_hw_open(uint id, UartConfig cfg) +{ + return uart_hw_init(id, cfg); +} + +void uart_hw_close(uint id) +{ + uart_write_reg(uart_base(id), UARTCR, 0); +} + +ptrdiff_t uart_hw_read(uint id, void[] buffer) +{ + immutable base = uart_base(id); + auto buf = cast(ubyte[])buffer; + ptrdiff_t n = 0; + while (n < buf.length) + { + if (uart_read_reg(base, UARTFR) & FR_RXFE) + break; + buf[n] = cast(ubyte)(uart_read_reg(base, UARTDR) & 0xFF); + ++n; + } + return n; +} + +ptrdiff_t uart_hw_write(uint id, const(void)[] data) +{ + immutable base = uart_base(id); + auto buf = cast(const(ubyte)[])data; + ptrdiff_t n = 0; + while (n < buf.length) + { + if (uart_read_reg(base, UARTFR) & FR_TXFF) + break; + uart_write_reg(base, UARTDR, buf[n]); + ++n; + } + return n; +} + +void uart_hw_poll(uint id) +{ + // PL011 FIFOs handle buffering -- nothing to poll +} + +bool uart_hw_check_errors(uint id) +{ + immutable base = uart_base(id); + immutable rsr = uart_read_reg(base, UARTRSR); + if (rsr != 0) + { + uart_write_reg(base, UARTRSR, 0); // Clear errors + return true; + } + return false; +} + +ptrdiff_t uart_hw_rx_pending(uint id) +{ + // PL011 doesn't expose FIFO level directly in a simple way. + // Return 1 if data available, 0 otherwise. + if (uart_read_reg(uart_base(id), UARTFR) & FR_RXFE) + return 0; + return 1; +} + +ptrdiff_t uart_hw_flush(uint id) +{ + immutable base = uart_base(id); + while (uart_read_reg(base, UARTFR) & FR_BUSY) + {} + return 0; +} + +// Blocking puts for early boot (before the serial stream is up) +void uart0_hw_puts(const(char)[] s) +{ + enum ulong base = 0x40070000; + foreach (c; s) + { + while (volatileLoad(cast(uint*)(base + UARTFR)) & FR_TXFF) + {} + volatileStore(cast(uint*)(base + UARTDR), cast(uint)c); + } +} diff --git a/src/urt/driver/stm32/alloc.d b/src/urt/driver/stm32/alloc.d new file mode 100644 index 0000000..806bbd5 --- /dev/null +++ b/src/urt/driver/stm32/alloc.d @@ -0,0 +1,37 @@ +module urt.driver.stm32.alloc; + +import urt.mem.alloc : MemFlags; + +nothrow @nogc: + +enum has_realloc = false; +enum has_expand = false; +enum has_memsize = false; +enum has_exec = false; +enum has_retain = false; // TODO: backup SRAM +enum has_memflags = false; // TODO: TCM vs SRAM + +void[] _alloc(size_t size, size_t alignment, MemFlags) pure +{ + import urt.util : align_down; + + size_t header_size = (void*).sizeof + alignment; + void* p = malloc(header_size + size); + if (p is null) + return null; + + size_t allocptr = align_down(cast(size_t)p + header_size, alignment); + (cast(void**)allocptr)[-1] = p; + return (cast(void*)allocptr)[0 .. size]; +} + +void _free(void* ptr) pure +{ + free((cast(void**)ptr)[-1]); +} + + +private: + +extern(C) void* malloc(size_t size) pure; +extern(C) void free(void* ptr) pure; diff --git a/src/urt/driver/stm32/irq.d b/src/urt/driver/stm32/irq.d new file mode 100644 index 0000000..55719bb --- /dev/null +++ b/src/urt/driver/stm32/irq.d @@ -0,0 +1,127 @@ +// STM32 interrupt controller driver +// +// Cortex-M4/M7 use the standard ARM NVIC (Nested Vectored Interrupt Controller). +// STM32F4xx has up to 82 peripheral interrupts, STM32F7xx up to 98. +module urt.driver.stm32.irq; + +@nogc nothrow: + +enum bool has_plic = false; +enum bool has_nvic = true; +enum bool has_clic = false; +enum bool has_per_irq_control = true; +enum bool has_irq_priority = true; +enum bool has_wait_for_interrupt = false; +enum bool has_irq_diagnostics = false; +enum bool has_global_irq_state = true; +enum bool has_smp = false; + +version (STM32F7) + enum uint irq_max = 98; +else + enum uint irq_max = 82; + +import core.volatile; + +// NVIC registers (ARM standard) +private enum ulong NVIC_ISER0 = 0xE000E100; +private enum ulong NVIC_ICER0 = 0xE000E180; +private enum ulong NVIC_ISPR0 = 0xE000E200; +private enum ulong NVIC_ICPR0 = 0xE000E280; +private enum ulong NVIC_IPR0 = 0xE000E400; + +// Cortex-M PRIMASK: bit 0 set means interrupts masked. Read it before +// mutating so callers (including IrqGuard) can restore prior state. +bool irq_disable() +{ + uint primask; + asm @nogc nothrow + { + ` + mrs %0, primask + cpsid i + ` + : "=r" (primask); + } + return (primask & 1) == 0; +} + +bool irq_enable() +{ + uint primask; + asm @nogc nothrow + { + ` + mrs %0, primask + cpsie i + ` + : "=r" (primask); + } + return (primask & 1) == 0; +} + +bool irq_set_enable(uint irq_num) +{ + immutable reg = irq_num / 32; + immutable bit = irq_num % 32; + auto iser = cast(uint*)(NVIC_ISER0 + reg * 4); + bool prev = (volatileLoad(iser) & (1u << bit)) != 0; + volatileStore(iser, 1u << bit); + return prev; +} + +bool irq_clear_enable(uint irq_num) +{ + immutable reg = irq_num / 32; + immutable bit = irq_num % 32; + // NVIC mirrors enable state in ISER; reading ISER tells us prior bit + // regardless of which window (ISER vs ICER) we use to mutate it. + auto iser = cast(uint*)(NVIC_ISER0 + reg * 4); + bool prev = (volatileLoad(iser) & (1u << bit)) != 0; + volatileStore(cast(uint*)(NVIC_ICER0 + reg * 4), 1u << bit); + return prev; +} + +// Set priority for a peripheral IRQ (0 = highest, 255 = lowest) +// STM32F4/F7 implement 4 priority bits (top 4 of 8) +void irq_set_priority(uint irq_num, ubyte priority) +{ + volatileStore(cast(ubyte*)(NVIC_IPR0 + irq_num), priority); +} + + +// Handler registration + +alias IrqHandler = void function(uint irq) @nogc nothrow; + +__gshared IrqHandler[irq_max] _handlers; + +// Install a handler for a peripheral IRQ (0..irq_max-1). Returns the previous. +// The flash vector table routes every peripheral vector at _nvic_dispatch, +// which recovers the active IRQ from IPSR and calls the registered handler. +IrqHandler irq_set_handler(uint irq, IrqHandler handler) +{ + if (irq >= irq_max) + return null; + IrqHandler prev = _handlers[irq]; + _handlers[irq] = handler; + return prev; +} + +// Common entry for every peripheral vector. A plain AAPCS function is a valid +// Cortex-M exception handler: on entry the core has stacked the caller context +// and set lr to EXC_RETURN, so the normal function return triggers exception +// return. IPSR holds the active exception number; peripheral IRQ n is exception +// n + 16. +extern(C) void _nvic_dispatch() +{ + uint ipsr; + asm @nogc nothrow { "mrs %0, ipsr" : "=r" (ipsr); } + uint irq = ipsr - 16; + if (irq < irq_max) + { + IrqHandler h = _handlers[irq]; + if (h !is null) + h(irq); + } +} diff --git a/src/urt/driver/stm32/package.d b/src/urt/driver/stm32/package.d new file mode 100644 index 0000000..4137525 --- /dev/null +++ b/src/urt/driver/stm32/package.d @@ -0,0 +1,108 @@ +// STM32 platform package (ARM Cortex-M4/M7) +// +// Provides sys_init() as the single entry point for all +// hardware initialization. Called from start.S before main(). +// +// At reset, STM32 runs on HSI at 16 MHz (no PLL). +// sys_init brings up USART1 for console output and SysTick. +// PLL configuration for full-speed operation is not yet implemented. +module urt.driver.stm32; + +public import urt.driver.stm32.uart; +public import urt.driver.stm32.irq; +public import urt.driver.stm32.timer; + +import urt.driver.uart : UartConfig; +import core.volatile; + +@nogc nothrow: + +private extern(C) void __register_frame_info(const void*, void*); +private extern(C) extern const ubyte __eh_frame_start; +private ubyte[48] __eh_frame_object; + +// RCC base and clock enable registers (same for F4 and F7) +enum ulong RCC_BASE = 0x40023800; +enum ulong RCC_AHB1ENR = 0x30; +enum ulong RCC_APB2ENR = 0x44; + +// GPIO base addresses +enum ulong GPIOA_BASE = 0x40020000; + +// GPIO register offsets +enum ulong GPIO_MODER = 0x00; +enum ulong GPIO_OSPEEDR = 0x08; +enum ulong GPIO_AFRH = 0x24; + +// SCB registers for cache control (F7 only) +enum ulong SCB_CCR = 0xE000ED14; +enum ulong ICIALLU = 0xE000EF50; + +private void mmio_write(ulong addr, uint val) +{ + volatileStore(cast(uint*)addr, val); +} + +private uint mmio_read(ulong addr) +{ + return volatileLoad(cast(uint*)addr); +} + +private void mmio_set(ulong addr, uint bits) +{ + volatileStore(cast(uint*)addr, volatileLoad(cast(uint*)addr) | bits); +} + +private void mmio_rmw(ulong addr, uint clear_mask, uint set_bits) +{ + immutable val = volatileLoad(cast(uint*)addr); + volatileStore(cast(uint*)addr, (val & ~clear_mask) | set_bits); +} + +extern(C) void sys_init() +{ + __register_frame_info(&__eh_frame_start, &__eh_frame_object); + + // Enable GPIOA clock (AHB1ENR bit 0) + mmio_set(RCC_BASE + RCC_AHB1ENR, 1 << 0); + + // Enable USART1 clock (APB2ENR bit 4) + mmio_set(RCC_BASE + RCC_APB2ENR, 1 << 4); + + // Configure PA9 (USART1_TX) and PA10 (USART1_RX) as AF7 + // MODER: bits 19:18 = 0b10 (PA9 AF), bits 21:20 = 0b10 (PA10 AF) + mmio_rmw(GPIOA_BASE + GPIO_MODER, + (3u << 18) | (3u << 20), + (2u << 18) | (2u << 20)); + + // OSPEEDR: high speed for PA9/PA10 + mmio_set(GPIOA_BASE + GPIO_OSPEEDR, (3u << 18) | (3u << 20)); + + // AFRH: PA9 bits 7:4 = 7 (AF7), PA10 bits 11:8 = 7 (AF7) + mmio_rmw(GPIOA_BASE + GPIO_AFRH, + (0xFu << 4) | (0xFu << 8), + (7u << 4) | (7u << 8)); + + // Init UART0 (USART1) at default baud for early console + uart_hw_init(0, UartConfig.init); + + uart0_hw_puts("STM32: sys_init\r\n"); + + version (STM32F7) + { + // Enable instruction cache (D-cache needs DMA coherence handling) + asm @nogc nothrow { "dsb sy"; "isb"; } + mmio_write(ICIALLU, 0); + asm @nogc nothrow { "dsb sy"; "isb"; } + mmio_set(SCB_CCR, 1 << 17); + asm @nogc nothrow { "dsb sy"; "isb"; } + uart0_hw_puts("STM32F7: I-cache enabled\r\n"); + } + + // SysTick: 20 Hz tick (50ms) + // HSI = 16 MHz, AHB prescaler = 1 at reset + // Reload = 16_000_000 / 20 - 1 = 799_999 + timer_init(799_999); + + uart0_hw_puts("STM32: ready\r\n"); +} diff --git a/src/urt/driver/stm32/start.S b/src/urt/driver/stm32/start.S new file mode 100644 index 0000000..9e15869 --- /dev/null +++ b/src/urt/driver/stm32/start.S @@ -0,0 +1,221 @@ +/* STM32 (ARM Cortex-M4/M7) startup + * + * Shared between STM32F4xx and STM32F7xx. The assembler receives + * -mcpu=cortex-m4 or -mcpu=cortex-m7 from the Makefile, so no + * .cpu directive here. + * + * Boot flow: + * 1. Cortex-M reads vector table from flash: initial SP + Reset_Handler + * 2. Reset_Handler runs: + * a. Copy .got from flash to RAM + * b. Copy .data from flash to RAM + * c. Zero .bss + * d. Enable FPU (CP10 + CP11) + * e. Call sys_init (clock, GPIO, UART, cache) + * f. Run .init_array (D module constructors) + * g. Call main + */ + + .syntax unified + .thumb + +/* ================================================================ + * Vector table -- placed at start of FLASH + * Cortex-M reads entry 0 as initial SP, entry 1 as Reset_Handler + * ================================================================ */ + .section .vector_table, "a" + .global __vector_table + .type __vector_table, %object +__vector_table: + .word _stack_top /* 0: Initial stack pointer */ + .word Reset_Handler /* 1: Reset */ + .word NMI_Handler /* 2: NMI */ + .word HardFault_Handler /* 3: Hard fault */ + .word MemManage_Handler /* 4: MPU fault */ + .word BusFault_Handler /* 5: Bus fault */ + .word UsageFault_Handler /* 6: Usage fault */ + .word 0 /* 7: Reserved */ + .word 0 /* 8: Reserved */ + .word 0 /* 9: Reserved */ + .word 0 /* 10: Reserved */ + .word SVCall_Handler /* 11: SVCall */ + .word DebugMon_Handler /* 12: Debug monitor */ + .word 0 /* 13: Reserved */ + .word PendSV_Handler /* 14: PendSV */ + .word SysTick_Handler /* 15: SysTick */ + + /* IRQ 0-97 (98 entries covers both F4 82 and F7 98 IRQs). Every + * peripheral vector routes to _nvic_dispatch, which recovers the IRQ from + * IPSR and calls the handler registered via irq_set_handler. */ + .rept 98 + .word _nvic_dispatch + .endr + + .size __vector_table, . - __vector_table + +/* ================================================================ + * Reset handler + * ================================================================ */ + .section .text, "ax" + .global Reset_Handler + .type Reset_Handler, %function + .thumb_func +Reset_Handler: + + /* -- Copy .got from flash (LMA) to RAM (VMA) -- */ + ldr r0, =_got_start + ldr r1, =_got_load + ldr r2, =_got_end + cmp r0, r1 + beq .Lgot_done + b .Lgot_check +.Lgot_copy: + ldm r1!, {r3} + stm r0!, {r3} +.Lgot_check: + cmp r0, r2 + blo .Lgot_copy +.Lgot_done: + + /* -- Copy .data from flash to RAM -- */ + ldr r0, =_data_start + ldr r1, =_data_load + ldr r2, =_data_end + b .Ldata_check +.Ldata_copy: + ldm r1!, {r3} + stm r0!, {r3} +.Ldata_check: + cmp r0, r2 + blo .Ldata_copy + + /* -- Copy .dtcm_data from flash to DTCM (F7; empty no-op on F4) -- */ + ldr r0, =_dtcm_data_start + ldr r1, =_dtcm_data_load + ldr r2, =_dtcm_data_end + b .Ldtcm_check +.Ldtcm_copy: + ldm r1!, {r3} + stm r0!, {r3} +.Ldtcm_check: + cmp r0, r2 + blo .Ldtcm_copy + + /* -- Zero .bss -- */ + ldr r0, =_bss_start + ldr r2, =_bss_end + movs r3, #0 + b .Lbss_check +.Lbss_zero: + stm r0!, {r3} +.Lbss_check: + cmp r0, r2 + blo .Lbss_zero + + /* -- Enable FPU (CP10 + CP11 full access) -- */ + ldr r0, =0xE000ED88 /* CPACR */ + ldr r1, [r0] + orr r1, r1, #(0xF << 20) + str r1, [r0] + dsb + isb + + /* -- Platform init (clock, GPIO, UART, cache) -- */ + bl sys_init + + /* -- Run .init_array (D module constructors) -- */ + ldr r4, =__init_array_start + ldr r5, =__init_array_end + b .Linit_check +.Linit_loop: + ldr r0, [r4] + blx r0 + adds r4, r4, #4 +.Linit_check: + cmp r4, r5 + blo .Linit_loop + + /* -- Enter main (should never return) -- */ + bl main + + /* If main returns, spin */ +.Lhalt: + wfi + b .Lhalt + + .size Reset_Handler, . - Reset_Handler + +/* ================================================================ + * Default exception/interrupt handlers (weak, overridable) + * ================================================================ */ + .thumb_func + .weak NMI_Handler + .type NMI_Handler, %function +NMI_Handler: + b . + + .thumb_func + .weak HardFault_Handler + .type HardFault_Handler, %function +HardFault_Handler: + b . + + .thumb_func + .weak MemManage_Handler + .type MemManage_Handler, %function +MemManage_Handler: + b . + + .thumb_func + .weak BusFault_Handler + .type BusFault_Handler, %function +BusFault_Handler: + b . + + .thumb_func + .weak UsageFault_Handler + .type UsageFault_Handler, %function +UsageFault_Handler: + b . + + .thumb_func + .weak SVCall_Handler + .type SVCall_Handler, %function +SVCall_Handler: + b . + + .thumb_func + .weak DebugMon_Handler + .type DebugMon_Handler, %function +DebugMon_Handler: + b . + + .thumb_func + .weak PendSV_Handler + .type PendSV_Handler, %function +PendSV_Handler: + b . + + .thumb_func + .weak SysTick_Handler + .type SysTick_Handler, %function +SysTick_Handler: + b . + + .thumb_func + .weak Default_Handler + .type Default_Handler, %function +Default_Handler: + b . + +/* ================================================================ + * __aeabi_read_tp -- ARM EABI thread pointer for TLS access + * Single-threaded bare-metal: return fixed pointer to .tdata + * ================================================================ */ + .global __aeabi_read_tp + .type __aeabi_read_tp, %function + .thumb_func +__aeabi_read_tp: + ldr r0, =_tdata_start + bx lr + .size __aeabi_read_tp, . - __aeabi_read_tp diff --git a/src/urt/driver/stm32/syscalls.d b/src/urt/driver/stm32/syscalls.d new file mode 100644 index 0000000..3c5e95c --- /dev/null +++ b/src/urt/driver/stm32/syscalls.d @@ -0,0 +1,50 @@ +// STM32 newlib/picolibc syscall stubs +// +// Minimal stubs to satisfy picolibc's syscall requirements. +// Same pattern as RP2350 -- most are no-ops for baremetal. +module urt.driver.stm32.syscalls; + +@nogc nothrow: + +private extern(C) extern const void* __heap_start; +private extern(C) extern const void* __heap_end; + +private __gshared void* _heap_ptr; + +extern(C) void* _sbrk(ptrdiff_t incr) +{ + if (_heap_ptr is null) + _heap_ptr = cast(void*)&__heap_start; + + void* prev = _heap_ptr; + void* next = _heap_ptr + incr; + + if (next > cast(void*)&__heap_end) + return cast(void*)-1; + + _heap_ptr = next; + return prev; +} + +extern(C) int _write(int fd, const void* buf, size_t count) +{ + import urt.driver.stm32.uart : uart0_hw_puts; + if (fd == 1 || fd == 2) + uart0_hw_puts((cast(const(char)*)buf)[0 .. count]); + return cast(int)count; +} + +extern(C) int _read(int, void*, size_t) { return 0; } +extern(C) int _close(int) { return -1; } +extern(C) int _lseek(int, int, int) { return 0; } +extern(C) int _fstat(int, void*) { return 0; } +extern(C) int _isatty(int) { return 1; } +extern(C) void _exit(int) { while (true) {} } +extern(C) int _kill(int, int) { return -1; } +extern(C) int _getpid() { return 1; } + +// DWARF unwinder stubs -- ARM Cortex-M uses EHABI, not DWARF. +extern(C) void __register_frame_info(const void*, void*) {} +extern(C) size_t _Unwind_GetIPInfo(void*, int*) { return 0; } +extern(C) void _Unwind_SetGR(void*, int, size_t) {} +extern(C) void _Unwind_SetIP(void*, size_t) {} diff --git a/src/urt/driver/stm32/timer.d b/src/urt/driver/stm32/timer.d new file mode 100644 index 0000000..6712e15 --- /dev/null +++ b/src/urt/driver/stm32/timer.d @@ -0,0 +1,73 @@ +// STM32 timer driver +// +// Monotonic time via SysTick interpolation: the SysTick handler increments +// a tick counter, and mtime_read() combines the tick count with the current +// SysTick value for full 16 MHz resolution. +// +// SysTick keeps running during WFI (SLEEP mode) since AHB stays active, +// unlike DWT CYCCNT which stops on sleep. +module urt.driver.stm32.timer; + +import core.volatile; + +@nogc nothrow: + +enum uint mtime_freq_hz = 16_000_000; +enum bool has_mtime = true; +enum bool has_rtc = false; +enum bool has_mcycle = false; +enum bool has_timer_stop = false; +enum bool has_oneshot_timer = false; + +// SysTick registers (ARM standard) +private enum ulong SYST_CSR = 0xE000E010; +private enum ulong SYST_RVR = 0xE000E014; +private enum ulong SYST_CVR = 0xE000E018; + +private enum uint CSR_ENABLE = 1 << 0; +private enum uint CSR_TICKINT = 1 << 1; +private enum uint CSR_CLKSOURCE = 1 << 2; + +// 20 Hz tick: reload = 16_000_000 / 20 - 1 = 799_999 +private enum uint SYSTICK_RELOAD = 799_999; + +alias TimerCallback = void function() @nogc nothrow; + +private __gshared TimerCallback tick_callback; +private __gshared uint tick_count; + +void timer_init(uint reload_value) +{ + volatileStore(cast(uint*)SYST_RVR, reload_value & 0x00FFFFFF); + volatileStore(cast(uint*)SYST_CVR, 0); + volatileStore(cast(uint*)SYST_CSR, CSR_ENABLE | CSR_TICKINT | CSR_CLKSOURCE); +} + +void timer_set_periodic(uint period_us, TimerCallback cb) +{ + tick_callback = cb; + timer_init(period_us * 16); +} + +// Full-resolution monotonic time by combining SysTick overflow count with +// the current down-counter value. Retry loop handles the race where +// SysTick fires between reading tick_count and CVR. +ulong mtime_read() +{ + uint t1, cvr, t2; + do + { + t1 = volatileLoad(&tick_count); + cvr = volatileLoad(cast(uint*)SYST_CVR); + t2 = volatileLoad(&tick_count); + } + while (t1 != t2); + return cast(ulong)t1 * (SYSTICK_RELOAD + 1) + (SYSTICK_RELOAD - cvr); +} + +extern(C) void SysTick_Handler() @nogc nothrow +{ + volatileStore(&tick_count, volatileLoad(&tick_count) + 1); + if (tick_callback !is null) + tick_callback(); +} diff --git a/src/urt/driver/stm32/uart.d b/src/urt/driver/stm32/uart.d new file mode 100644 index 0000000..e6908a8 --- /dev/null +++ b/src/urt/driver/stm32/uart.d @@ -0,0 +1,260 @@ +// STM32 UART driver +// +// Supports both F4 (legacy SR/DR register layout) and F7 (ISR/RDR/TDR). +// USART1-6 on F4, USART1-6 + UART7-8 on F7. +// +// Default console: USART1 on PA9 (TX) / PA10 (RX), configured in sys_init. +module urt.driver.stm32.uart; + +import core.volatile; + +import urt.driver.uart : Parity, StopBits, UartConfig; + +nothrow @nogc: + +version (STM32F7) + enum uint num_uarts = 8; +else + enum uint num_uarts = 6; + +enum uint uart_clock_hz = 16_000_000; +enum bool has_irq_driven_uart = false; +enum bool has_dma_driven_uart = false; + +// F4 uses legacy register layout (SR/DR), F7 uses new layout (ISR/RDR/TDR). +// Register offsets and UE bit position differ; status bit positions are the same. +version (STM32F4) enum legacy_usart = true; +else enum legacy_usart = false; + +// Status bits (same positions in F4 SR and F7 ISR) +private enum +{ + ST_TXE = 1 << 7, + ST_RXNE = 1 << 5, + ST_TC = 1 << 6, + ST_ORE = 1 << 3, + ST_FE = 1 << 1, + ST_PE = 1 << 0, +} + +// CR1 bits shared between F4 and F7 +private enum +{ + CR1_TE = 1 << 3, + CR1_RE = 1 << 2, +} + +// F4: UE is bit 13 in CR1 at offset 0x0C +// F7: UE is bit 0 in CR1 at offset 0x00 +static if (legacy_usart) + private enum uint CR1_UE = 1 << 13; +else + private enum uint CR1_UE = 1 << 0; + +// Register offsets +static if (legacy_usart) +{ + private enum { SR = 0x00, DR = 0x04, BRR = 0x08, CR1 = 0x0C, CR2 = 0x10, CR3 = 0x14 } +} +else +{ + private enum { CR1 = 0x00, CR2 = 0x04, CR3 = 0x08, BRR = 0x0C, ISR = 0x1C, ICR = 0x20, RDR = 0x24, TDR = 0x28 } +} + +// USART base addresses (F4 and F7 share the same addresses for USART1-6) +private ulong uart_base(uint id) +{ + immutable ulong[8] bases = [ + 0x40011000, // USART1 (APB2) + 0x40004400, // USART2 (APB1) + 0x40004800, // USART3 (APB1) + 0x40004C00, // UART4 (APB1) + 0x40005000, // UART5 (APB1) + 0x40011400, // USART6 (APB2) + 0x40007800, // UART7 (APB1, F7 only) + 0x40007C00, // UART8 (APB1, F7 only) + ]; + return bases[id]; +} + +private void reg_write(ulong base, uint offset, uint val) +{ + volatileStore(cast(uint*)(base + offset), val); +} + +private uint reg_read(ulong base, uint offset) +{ + return volatileLoad(cast(uint*)(base + offset)); +} + +private uint read_status(ulong base) +{ + static if (legacy_usart) + return reg_read(base, SR); + else + return reg_read(base, ISR); +} + +private ubyte read_data(ulong base) +{ + static if (legacy_usart) + return cast(ubyte)(reg_read(base, DR) & 0xFF); + else + return cast(ubyte)(reg_read(base, RDR) & 0xFF); +} + +private void write_data(ulong base, ubyte val) +{ + static if (legacy_usart) + reg_write(base, DR, val); + else + reg_write(base, TDR, val); +} + +bool uart_hw_init(uint id, UartConfig cfg) +{ + immutable base = uart_base(id); + + // Disable UART while configuring + reg_write(base, CR1, 0); + + // Baud rate: BRR = fck / baud (16x oversampling) + immutable uint brr = uart_clock_hz / cfg.baud_rate; + reg_write(base, BRR, brr); + + // Line control: word length, parity, stop bits + uint cr1 = CR1_UE | CR1_TE | CR1_RE; + uint cr2 = 0; + + if (cfg.parity != Parity.none) + { + static if (legacy_usart) + cr1 |= 1 << 10; // PCE: parity enable + else + cr1 |= 1 << 10; // PCE: parity enable + if (cfg.parity == Parity.odd) + { + static if (legacy_usart) + cr1 |= 1 << 9; // PS: odd parity + else + cr1 |= 1 << 9; // PS: odd parity + } + // With parity, need M=1 (9 data bits) to keep 8 data + 1 parity + static if (legacy_usart) + cr1 |= 1 << 12; // M: word length 9 + else + cr1 |= 1 << 12; // M0: word length 9 + } + + if (cfg.stop_bits == StopBits.two) + cr2 |= 2 << 12; // STOP: 2 stop bits + else if (cfg.stop_bits == StopBits.half) + cr2 |= 1 << 12; // STOP: 0.5 stop bits + else if (cfg.stop_bits == StopBits.one_point_five) + cr2 |= 3 << 12; // STOP: 1.5 stop bits + + reg_write(base, CR2, cr2); + reg_write(base, CR3, 0); + reg_write(base, CR1, cr1); + + return true; +} + +bool uart_hw_open(uint id, UartConfig cfg) +{ + return uart_hw_init(id, cfg); +} + +void uart_hw_close(uint id) +{ + reg_write(uart_base(id), CR1, 0); +} + +ptrdiff_t uart_hw_read(uint id, void[] buffer) +{ + immutable base = uart_base(id); + auto buf = cast(ubyte[])buffer; + ptrdiff_t n = 0; + while (n < buf.length) + { + if (!(read_status(base) & ST_RXNE)) + break; + buf[n] = read_data(base); + ++n; + } + return n; +} + +ptrdiff_t uart_hw_write(uint id, const(void)[] data) +{ + immutable base = uart_base(id); + auto buf = cast(const(ubyte)[])data; + ptrdiff_t n = 0; + while (n < buf.length) + { + if (!(read_status(base) & ST_TXE)) + break; + write_data(base, buf[n]); + ++n; + } + return n; +} + +void uart_hw_poll(uint id) {} + +bool uart_hw_check_errors(uint id) +{ + immutable base = uart_base(id); + immutable st = read_status(base); + if (st & (ST_ORE | ST_FE | ST_PE)) + { + static if (legacy_usart) + { + // F4: read SR then DR to clear error flags + reg_read(base, DR); + } + else + { + // F7: write ICR to clear error flags + reg_write(base, ICR, ST_ORE | ST_FE | ST_PE); + } + return true; + } + return false; +} + +ptrdiff_t uart_hw_rx_pending(uint id) +{ + if (read_status(uart_base(id)) & ST_RXNE) + return 1; + return 0; +} + +ptrdiff_t uart_hw_flush(uint id) +{ + immutable base = uart_base(id); + while (!(read_status(base) & ST_TC)) + {} + return 0; +} + +// Blocking puts for early boot (before the serial stream is up) +void uart0_hw_puts(const(char)[] s) +{ + enum ulong base = 0x40011000; // USART1 + foreach (c; s) + { + static if (legacy_usart) + { + while (!(volatileLoad(cast(uint*)(base + SR)) & ST_TXE)) + {} + volatileStore(cast(uint*)(base + DR), cast(uint)c); + } + else + { + while (!(volatileLoad(cast(uint*)(base + ISR)) & ST_TXE)) + {} + volatileStore(cast(uint*)(base + TDR), cast(uint)c); + } + } +} diff --git a/src/urt/driver/timer.d b/src/urt/driver/timer.d new file mode 100644 index 0000000..4276051 --- /dev/null +++ b/src/urt/driver/timer.d @@ -0,0 +1,370 @@ +module urt.driver.timer; + +import urt.time : Duration, dur; +import urt.driver.irq : has_clic, has_per_irq_control; + +version (BL808_M0) + public import urt.driver.bl618.timer; +else version (BL808) + public import urt.driver.bl808.timer; +else version (BL618) + public import urt.driver.bl618.timer; +else version (Beken) + public import urt.driver.bk7231.timer; +else version (RP2350) + public import urt.driver.rp2350.timer; +else version (STM32) + public import urt.driver.stm32.timer; +else version (Espressif) + public import urt.driver.esp32.timer; +else +{ + enum uint mtime_freq_hz = 0; + enum bool has_mtime = false; + enum bool has_rtc = false; + enum bool has_mcycle = false; + enum bool has_timer_stop = false; + enum bool has_oneshot_timer = false; +} + +nothrow @nogc: + + +alias TimerCallback = void function() nothrow @nogc; + +// ==================================================================== +// Driver API +// ==================================================================== + +// Lifecycle + +void timer_init() +{ + if (_init_refcount++ == 0) + { + version (Beken) + timer_hw_init(); + } +} + +void timer_deinit() +{ + assert(_init_refcount > 0); + if (--_init_refcount == 0) + { + static if (has_timer_stop) + periodic_stop(); + static if (has_rtc) + rtc_stop(); + // TODO: disable timer IRQs at the interrupt controller level + } +} + +// Monotonic clock + +// Read the monotonic tick counter. Units are platform-specific; +// use mtime_freq_hz to convert to real time. +static if (has_mtime) + alias monotonic_read = mtime_read; +else +{ + ulong monotonic_read() + { + assert(false, "monotonic_read not available"); + } +} + +// Read CPU cycle counter (for profiling, NOT timekeeping). +// Stops during WFI, rate changes with clock scaling. +static if (has_mcycle) + alias cycle_read = mcycle_read; +else +{ + ulong cycle_read() + { + assert(false, "cycle_read not available"); + } +} + +// Periodic tick + +// Set up a periodic timer interrupt at the given interval. +void periodic_set(Duration interval, TimerCallback cb) +{ + static if (has_mtime) + { + ulong ticks = interval.as!"nsecs" * mtime_freq_hz / 1_000_000_000; + timer_set_periodic(cast(uint)ticks, cb); + } + else + assert(false, "TODO: periodic_set not available"); +} + +// Stop the periodic timer. +void periodic_stop() +{ + static if (has_timer_stop) + timer_stop(); + else + assert(false, "TODO: periodic_stop not available"); +} + +// One-shot wakeup + +// Schedule a one-shot interrupt at the given absolute tick value. +// Used by sleep() to wake from WFI. +void oneshot_set(ulong tick_value) +{ + static if (has_oneshot_timer) + mtimecmp_write_oneshot(tick_value); + else + assert(false, "TODO: oneshot_set not available"); +} + +// RTC (battery-backed real-time counter) + +// Enable the RTC counter. Does not reset it. +void rtc_start() +{ + static if (has_rtc) + rtc_enable(); + else + assert(false, "TODO: rtc_start not available"); +} + +// Disable and reset the RTC counter to zero. +void rtc_stop() +{ + static if (has_rtc) + rtc_reset(); + else + assert(false, "TODO: rtc_stop not available"); +} + +// Read the RTC tick counter. +static if (has_rtc) + alias rtc_now = rtc_read; +else +{ + ulong rtc_now() + { + assert(false, "TODO: rtc_now not available"); + } +} + +// Access persistent state in battery-retained RAM. +static if (has_rtc) +{ + HbnPersist* persistent_state() + { + return hbn_persist(); + } +} + + +// ==================================================================== +// Tests +// ==================================================================== +// +// Most of these are gated by capability flags so they collapse to no-ops +// on platforms that don't support the underlying surface (desktop, in +// particular, runs only the cross-asserts and the refcount test). + +unittest // capability cross-consistency +{ + static assert(mtime_freq_hz > 0 || !has_mtime, + "has_mtime requires a known mtime frequency"); + static assert(!has_mcycle || has_mtime, + "mcycle without mtime makes no sense in this codebase"); + static assert(!has_timer_stop || has_mtime, + "stoppable periodic implies an mtime source"); +} + +unittest // timer_init / timer_deinit refcount balances +{ + timer_init(); + timer_init(); + timer_deinit(); + timer_deinit(); + // If the refcount underflowed, the next timer_init would re-init the + // hardware redundantly; if it leaked, the matching deinit above would + // assert(_init_refcount > 0). Reaching this line means neither happened. +} + +static if (has_mtime) +unittest // monotonic_read is non-decreasing and actually advances +{ + timer_init(); + scope (exit) timer_deinit(); + + ulong t1 = monotonic_read(); + ulong t2 = monotonic_read(); + assert(t2 >= t1, "monotonic_read went backwards"); + + // Spin until the clock advances or we exhaust the budget. A clock that + // never advances is a more useful failure mode than a flake. + ulong start = monotonic_read(); + ulong observed = start; + foreach (_; 0 .. 1_000_000) + { + observed = monotonic_read(); + if (observed > start) + break; + } + assert(observed > start, "monotonic_read did not advance within 1M reads"); +} + +static if (has_mcycle) +unittest // cycle_read advances within a busy spin +{ + ulong c1 = cycle_read(); + ulong c2 = cycle_read(); + assert(c2 >= c1); + + ulong start = cycle_read(); + ulong observed = start; + foreach (_; 0 .. 10_000) + { + observed = cycle_read(); + if (observed > start) + break; + } + assert(observed > start, "cycle counter is stuck"); +} + +static if (has_oneshot_timer) +unittest // oneshot_set arm and cancel don't crash +{ + timer_init(); + scope (exit) timer_deinit(); + + ulong now = monotonic_read(); + // Arm well in the future so the fire-and-handler path is exercised by + // the periodic test below, not here. + oneshot_set(now + cast(ulong)mtime_freq_hz * 60); + oneshot_set(ulong.max); +} + +// Light-weight sanity check that periodic_set / periodic_stop don't crash. +// We can't easily assert delivery here because periodic_set is a platform- +// specific helper -- some platforms (BL618 during M0 bring-up) leave the +// IRQ enable commented out so the callback won't fire. The oneshot-based +// trap-entry test below covers delivery via the common API. +static if (has_mtime && has_timer_stop) +unittest // periodic_set / periodic_stop are safe to call back-to-back +{ + timer_init(); + scope (exit) timer_deinit(); + + periodic_set(dur!"msecs"(50), () @nogc nothrow {}); + periodic_stop(); +} + +// The big integration test: arm a oneshot, install a handler at the timer +// line, spin until it fires, verify the trap path doesn't corrupt the +// stack frame and the diagnostics counter increments. Built entirely on +// the common irq+timer API surface -- no platform helpers. +// +// Gated on has_clic because on CLIC the machine-timer cause arrives as +// ordinary IRQ line 7 through the per-line dispatch table, which is what +// irq_handler_set targets. PLIC routes the timer trap through its own +// path (start.S _trap_mtimer), so installing a handler at line 7 wouldn't +// reach it. NVIC's SysTick is a system exception, not a peripheral IRQ. +static if (has_mtime && has_oneshot_timer && has_clic && has_per_irq_control) +unittest // oneshot_set fires an IRQ, handler runs, trap doesn't trash stack +{ + import urt.driver.irq : irq_handler_set, irq_line_enable, irq_line_disable, + irq_global_enable, irq_global_set, + has_global_irq_state, has_irq_diagnostics, + IrqHandler; + import core.volatile : volatileLoad; + static if (has_irq_diagnostics) + import urt.driver.irq : irq_total_count; + + timer_init(); + scope (exit) timer_deinit(); + + // RISC-V machine-timer cause; standard across every CLIC platform. + enum uint timer_line = 7; + + __gshared uint fire_count; + fire_count = 0; + + static void handler(uint) @nogc nothrow + { + ++fire_count; + oneshot_set(ulong.max); // disarm so the trap doesn't keep re-firing + } + + IrqHandler prior_handler = irq_handler_set(timer_line, &handler); + scope (exit) irq_handler_set(timer_line, prior_handler); + + // Canary in the test's stack frame. If trap entry writes outside the + // saved frame (mis-aligned SP, wrong push count) this gets clobbered. + enum size_t canary_len = 256; + ubyte[canary_len] canary; + foreach (i, ref b; canary) + b = cast(ubyte)((i * 0x9Eu) ^ 0xA5u); + + static if (has_irq_diagnostics) + uint prior_total = irq_total_count(); + + bool prior_line = irq_line_enable(timer_line); + scope (exit) + { + if (!prior_line) + irq_line_disable(timer_line); + } + + static if (has_global_irq_state) + bool prior_global = irq_global_enable(); + else + irq_global_enable(); + + // Arm 10 ms in the future (10_000 ticks at 1 MHz mtime). + oneshot_set(monotonic_read() + 10_000); + + // Bounded busy wait -- 200 ms of mtime is generous slack for a 10 ms timer. + // volatileLoad keeps the optimizer from caching fire_count in a register; + // monotonic_read's inline-asm rdtime doesn't carry a memory clobber, so an + // ordinary __gshared load can otherwise be hoisted out of the loop. + ulong start_mt = monotonic_read(); + ulong budget = 200u * (cast(ulong)mtime_freq_hz / 1000u); + while (volatileLoad(&fire_count) == 0 && (monotonic_read() - start_mt) < budget) + {} + + static if (has_global_irq_state) + irq_global_set(prior_global); + + assert(volatileLoad(&fire_count) == 1, "oneshot_set did not deliver an IRQ"); + + foreach (i, b; canary) + assert(b == cast(ubyte)((i * 0x9Eu) ^ 0xA5u), + "stack canary clobbered across IRQ trap"); + + static if (has_irq_diagnostics) + assert(irq_total_count() > prior_total, + "diagnostics counter did not track delivered IRQ"); +} + +static if (has_rtc) +unittest // RTC counter non-decreasing; persistence struct accessible +{ + timer_init(); + scope (exit) timer_deinit(); + + rtc_start(); + + ulong r1 = rtc_now(); + ulong r2 = rtc_now(); + assert(r2 >= r1); + + auto p = persistent_state(); + assert(p !is null, + "persistent_state must return a valid pointer when RTC is up"); +} + + +private: + +__gshared ubyte _init_refcount; diff --git a/src/urt/driver/uart.d b/src/urt/driver/uart.d new file mode 100644 index 0000000..cfbec05 --- /dev/null +++ b/src/urt/driver/uart.d @@ -0,0 +1,472 @@ +module urt.driver.uart; + +import urt.result : Result, InternalResult; +import urt.time : Duration; + +version (BL808_M0) + public import urt.driver.bl618.uart; +else version (BL808) + public import urt.driver.bl808.uart; +else version (BL618) + public import urt.driver.bl618.uart; +else version (Beken) + public import urt.driver.bk7231.uart; +else version (RP2350) + public import urt.driver.rp2350.uart; +else version (STM32) + public import urt.driver.stm32.uart; +else version (Espressif) + public import urt.driver.esp32.uart; +else + enum uint num_uarts = 0; + +nothrow @nogc: + + +enum UartError : ubyte +{ + none = 0, + framing = 1 << 0, + parity = 1 << 1, + overrun = 1 << 2, + noise = 1 << 3, + break_ = 1 << 4, +} + +enum StopBits : ubyte +{ + half, + one, + one_point_five, + two, +} + +enum Parity : ubyte +{ + none, + even, + odd, + mark, + space +} + +enum FlowControl : ubyte +{ + none, + hardware, + software, + dsr_dtr, + + rts_cts = hardware, + xon_xoff = software +} + +enum DriveMode : ubyte +{ + polled, // caller must call uart_poll; no interrupts + interrupt, // IRQ-driven FIFO drain into software ring buffer + dma, // DMA circular RX, DMA one-shot TX + auto_, // driver picks best available (dma > interrupt > polled) +} + +struct Rs485Config +{ + bool enabled; + bool de_active_high = true; // DE pin polarity + ubyte de_gpio = ubyte.max; // GPIO pin for driver enable (max = auto/hardware) + ushort de_assert_us; // us to assert DE before first TX bit + ushort de_deassert_us; // us to hold DE after last TX bit + ushort turnaround_us; // minimum idle time between RX end and TX start +} + +struct UartConfig +{ + uint baud_rate = 115200; + ubyte data_bits = 8; + StopBits stop_bits = StopBits.one; + Parity parity = Parity.none; + FlowControl flow_control = FlowControl.none; + DriveMode drive_mode = DriveMode.auto_; + ubyte tx_gpio = ubyte.max; // GPIO pin for TX (max = platform default) + ubyte rx_gpio = ubyte.max; // GPIO pin for RX (max = platform default) + ubyte rts_gpio = ubyte.max; // GPIO pin for RTS (max = platform default) + ubyte cts_gpio = ubyte.max; // GPIO pin for CTS (max = platform default) + Rs485Config rs485; +} + +// Called from ISR/DMA when received data is available in the RX buffer. +// rx_avail: number of bytes ready to read. +alias UartRxCallback = void function(Uart uart, size_t rx_avail) nothrow @nogc; + +// Called from ISR/DMA when TX buffer space becomes available (e.g. FIFO +// drains below threshold). The callee should feed more data via uart_write. +// tx_avail: number of bytes that can be written to the TX buffer. +alias UartTxCallback = void function(Uart uart, size_t tx_avail) nothrow @nogc; + +// Called from ISR to pull the next chunk of data for an async transmit. +// offset: bytes already supplied so far (including initial buffer). +// The driver provides a buffer; the callee fills it and returns how many +// bytes were written. Called repeatedly until the transfer length is met. +alias UartTxSupplyCallback = size_t function(Uart uart, size_t offset, void[] buf) nothrow @nogc; + +// Called when the RX line has been idle for the configured threshold. +// Used for RS-485 frame boundary detection and bus arbitration. +alias UartLineIdleCallback = void function(Uart uart) nothrow @nogc; + +// Caller-owned write operation token. Pass to any write call to track +// completion and support cancellation. The driver writes status from +// ISR context; the caller polls it from main context. +struct UartWriteOp +{ + enum Status : ubyte + { + idle, // not submitted + pending, // driver is working on it + complete, // all bytes consumed / transmitted + cancelled, // cancelled via uart_write_cancel + error, // hardware error during transfer + } + + alias Callback = void function(Uart* uart, ref UartWriteOp op) nothrow @nogc; + + Status status; + size_t bytes_sent; // updated by driver as transfer progresses + void* user_data; + Callback cb; + + bool is_pending() const => status == Status.pending; + bool is_done() const => status >= Status.complete; +} + +struct Uart +{ + ubyte port = ubyte.max; +} + +bool is_open(ref const Uart uart) +{ + return uart.port != ubyte.max; +} + + +// ==================================================================== +// Error type +// ==================================================================== + +UartError uart_result(Result result) +{ + return cast(UartError)result.system_code; +} + + +// ==================================================================== +// Implementation +// ==================================================================== + +// Lifecycle + +void uart_init() +{ + if (_init_refcount++ == 0) + { + // TODO: enable clocks/power for UART peripheral block + } +} + +void uart_deinit() +{ + assert(_init_refcount > 0); + if (--_init_refcount == 0) + { + // TODO: disable clocks/power for UART peripheral block + } +} + +// Port operations + +Result uart_open(ref Uart uart, ubyte port, ref const UartConfig cfg, size_t buf_size = 0, UartRxCallback rx_cb = null, UartTxCallback tx_cb = null) +{ + static if (num_uarts == 0) + assert(false, "no UART on this platform"); + else + { + if (port >= num_uarts) + return InternalResult.invalid_parameter; + + if (!uart_hw_open(port, cfg)) + return InternalResult.failed; + + uart.port = port; + return Result.success; + } +} + +Result uart_reconfigure(ref Uart uart, ref const UartConfig cfg) +{ + assert(false, "TODO: uart_reconfigure (hot reconfigure)"); +} + +void uart_close(ref Uart uart) +{ + static if (num_uarts == 0) + assert(false, "no UART on this platform"); + else + uart_hw_close(uart.port); + uart.port = ubyte.max; +} + +// Single-byte I/O + +bool uart_putc(ref Uart uart, ubyte c) +{ + static if (num_uarts == 0) + assert(false, "no UART on this platform"); + else + return uart_hw_write(uart.port, (cast(void*)&c)[0 .. 1]) == 1; +} + +bool uart_getc(ref Uart uart, out ubyte c) +{ + static if (num_uarts == 0) + assert(false, "no UART on this platform"); + else + return uart_hw_read(uart.port, (cast(void*)&c)[0 .. 1]) == 1; +} + +// Bulk I/O + +ptrdiff_t uart_read(ref Uart uart, void[] buffer, Duration timeout = Duration.zero) +{ + static if (num_uarts == 0) + assert(false, "no UART on this platform"); + else + { + if (timeout != Duration.zero) + assert(false, "TODO: uart_read with timeout"); + uart_hw_poll(uart.port); + return uart_hw_read(uart.port, buffer); + } +} + +ptrdiff_t uart_write(ref Uart uart, const(void)[] data, UartWriteOp* op = null) +{ + static if (num_uarts == 0) + assert(false, "no UART on this platform"); + else + { + auto n = uart_hw_write(uart.port, data); + if (op !is null) + { + op.bytes_sent = n > 0 ? cast(size_t)n : 0; + op.status = n >= 0 ? UartWriteOp.Status.complete : UartWriteOp.Status.error; + if (op.cb !is null) + op.cb(&uart, *op); + } + return n; + } +} + +ptrdiff_t uart_writev(ref Uart uart, const(void[])[] buffers, UartWriteOp* op = null) +{ + static if (num_uarts == 0) + assert(false, "no UART on this platform"); + else + { + ptrdiff_t total = 0; + foreach (buf; buffers) + { + auto n = uart_hw_write(uart.port, buf); + if (n < 0) + { + if (op !is null) + { + op.bytes_sent = cast(size_t)total; + op.status = UartWriteOp.Status.error; + if (op.cb !is null) + op.cb(&uart, *op); + } + return n; + } + total += n; + if (n < buf.length) + break; + } + if (op !is null) + { + op.bytes_sent = cast(size_t)total; + op.status = UartWriteOp.Status.complete; + if (op.cb !is null) + op.cb(&uart, *op); + } + return total; + } +} + +ptrdiff_t uart_write_async(ref Uart uart, size_t total_len, UartTxSupplyCallback supply_cb, const(void)[] initial = null, UartWriteOp* op = null) +{ + assert(false, "TODO: uart_write_async (needs ISR integration)"); +} + +void uart_write_cancel(ref Uart uart, UartWriteOp* op) +{ + assert(false, "TODO: uart_write_cancel"); +} + +// Buffer queries + +size_t uart_rx_available(ref const Uart uart) +{ + static if (num_uarts == 0) + assert(false, "no UART on this platform"); + else + { + auto n = uart_hw_rx_pending(uart.port); + return n > 0 ? cast(size_t)n : 0; + } +} + +size_t uart_tx_available(ref const Uart uart) +{ + assert(false, "TODO: uart_tx_available"); +} + +size_t uart_tx_queued(ref const Uart uart) +{ + assert(false, "TODO: uart_tx_queued"); +} + +// Buffer control + +void uart_rx_flush(ref Uart uart) +{ + assert(false, "TODO: uart_rx_flush"); +} + +void uart_tx_flush(ref Uart uart) +{ + static if (num_uarts == 0) + assert(false, "no UART on this platform"); + else + uart_hw_flush(uart.port); +} + +void uart_tx_drain(ref Uart uart) +{ + assert(false, "TODO: uart_tx_drain (block until TX idle)"); +} + +void uart_tx_abort(ref Uart uart) +{ + assert(false, "TODO: uart_tx_abort"); +} + +// Line status + +bool uart_line_idle(ref const Uart uart) +{ + assert(false, "TODO: uart_line_idle"); +} + +void uart_set_idle_threshold(ref Uart uart, uint bit_times) +{ + assert(false, "TODO: uart_set_idle_threshold"); +} + +void uart_set_idle_callback(ref Uart uart, UartLineIdleCallback cb) +{ + assert(false, "TODO: uart_set_idle_callback"); +} + +// TX timing + +void uart_tx_gap(ref Uart uart, Duration gap) +{ + assert(false, "TODO: uart_tx_gap"); +} + +void uart_send_break(ref Uart uart, Duration duration) +{ + assert(false, "TODO: uart_send_break"); +} + +// Error and status + +UartError uart_check_errors(ref Uart uart) +{ + static if (num_uarts == 0) + assert(false, "no UART on this platform"); + else + return uart_hw_check_errors(uart.port) ? UartError.framing : UartError.none; +} + +void uart_poll(ref Uart uart) +{ + static if (num_uarts == 0) + assert(false, "no UART on this platform"); + else + uart_hw_poll(uart.port); +} + +// Early boot (pre-driver, polled, blocking) + +void uart0_putc(ubyte c) +{ + static if (num_uarts == 0) {} + else uart0_puts((cast(char*)&c)[0 .. 1]); +} + +void uart0_puts(const(char)[] s) +{ + static if (num_uarts == 0) {} + else uart0_hw_puts(s); +} + + +// ==================================================================== +// Tests +// ==================================================================== + +unittest +{ + static if (num_uarts > 0) + { + Uart u; + UartConfig cfg; + + uart_init(); + + // Out-of-range port + auto r = uart_open(u, cast(ubyte)num_uarts, cfg); + assert(!r); + assert(!u.is_open); + + // Open/close each valid port (skip port 0 -- it's usually the console) + foreach (p; 1 .. num_uarts) + { + Uart port; + auto r2 = uart_open(port, cast(ubyte)p, cfg); + assert(r2, "uart_open failed"); + assert(port.is_open); + assert(port.port == p); + + // RX should be empty on a freshly opened port + assert(uart_rx_available(port) == 0); + + // Poll should not crash + uart_poll(port); + + // Check errors on a clean port + assert(uart_check_errors(port) == UartError.none); + + uart_close(port); + assert(!port.is_open); + } + + uart_deinit(); + } +} + + +private: + +__gshared ubyte _init_refcount; diff --git a/src/urt/driver/wifi.d b/src/urt/driver/wifi.d new file mode 100644 index 0000000..ba5163b --- /dev/null +++ b/src/urt/driver/wifi.d @@ -0,0 +1,535 @@ +module urt.driver.wifi; + +import urt.result : Result, InternalResult; + +version (Espressif) + public import urt.driver.esp32.wifi; +else version (BL808_M0) + public import urt.driver.bl808_m0.wifi; +else + enum uint num_wifi = 0; + +nothrow @nogc: + + +static if (!__traits(compiles, wifi_max_ap_clients)) + enum ubyte wifi_max_ap_clients = ubyte.max; + +alias WifiWakeCallback = void function() nothrow @nogc; + +void wifi_set_wake_callback(WifiWakeCallback cb) +{ + static if (__traits(compiles, wifi_hw_set_wake_callback(cb))) + wifi_hw_set_wake_callback(cb); +} + + +// ==================================================================== +// Types +// ==================================================================== + +enum WifiError : ubyte +{ + none, + auth_failed, + no_ap, // target AP not found + assoc_failed, // association rejected + timeout, + tx_failed, + internal, +} + +// Virtual interface type within a radio. +enum WifiVif : ubyte +{ + sta, + ap, +} + +enum WifiMode : ubyte +{ + none, // radio off, no virtual interfaces active + monitor, // radio on, raw 802.11 only - no stack + sta, // station only + ap, // access point only + apsta, // concurrent AP + STA +} + +enum WifiAuth : ubyte +{ + open, + wep, + wpa_psk, + wpa2_psk, + wpa_wpa2_psk, + wpa3_psk, + wpa2_wpa3_psk, + wpa2_enterprise, + wpa3_enterprise, +} + +enum WifiBand : ubyte +{ + any, + band_2g4, // 2.4 GHz + band_5g, // 5 GHz + band_6g, // 6 GHz (Wi-Fi 6E) +} + +enum WifiBandwidth : ubyte +{ + bw_20mhz, + bw_40mhz, + bw_80mhz, + bw_160mhz, +} + +enum WifiEvent : ubyte +{ + sta_connected, + sta_disconnected, + ap_started, + ap_stopped, + ap_sta_connected, // a client joined our AP + ap_sta_disconnected, // a client left our AP + scan_done, +} + +struct WifiConfig +{ + byte tx_power; // dBm (0 = platform default) + ubyte channel; // fixed channel (0 = auto) + WifiBand band; + ubyte[2] country; // ISO 3166-1 alpha-2 (e.g. "US"), 0 = default +} + +struct WifiStaConfig +{ + const(char)[] ssid; + const(char)[] password; + ubyte[6] bssid; // filter by BSSID (all zeros = any) + WifiBand band; + bool pmf_required; // protected management frames +} + +struct WifiApConfig +{ + const(char)[] ssid; + const(char)[] password; + WifiAuth auth = WifiAuth.wpa2_wpa3_psk; + ubyte channel; // 0 = auto + ubyte max_clients = 4; + bool hidden; // suppress SSID broadcast + WifiBandwidth bandwidth; +} + +struct WifiScanConfig +{ + const(char)[] ssid; // filter by SSID (empty = all) + ubyte[6] bssid; // filter by BSSID (all zeros = any) + ubyte channel; // scan single channel (0 = all) + WifiBand band; + bool passive; // passive scan (listen only, no probe requests) + ushort dwell_ms; // per-channel dwell time (0 = platform default) +} + +struct WifiScanResult +{ + ubyte[6] bssid; + ubyte channel; + byte rssi; // dBm + WifiAuth auth; + WifiBand band; + WifiBandwidth bandwidth; + ubyte ssid_len; + char[32] ssid_buf; + + const(char)[] ssid() const pure nothrow @nogc + => ssid_buf[0 .. ssid_len]; +} + +struct WifiStaInfo +{ + ubyte[6] mac; + byte rssi; +} + +// Called from ISR/driver when an Ethernet frame is received on a +// virtual interface. Data includes the 14-byte Ethernet header. +alias WifiRxCallback = void function(Wifi wifi, WifiVif vif, const(ubyte)[] data) nothrow @nogc; + +// Called from ISR/driver when a raw 802.11 frame is received +// (promiscuous/monitor tap). Data is the full 802.11 frame +// starting at the MAC header. Delivered independently of the +// Ethernet RX callback - both can be active simultaneously. +alias WifiRawRxCallback = void function(Wifi wifi, const(ubyte)[] frame, byte rssi, ubyte channel) nothrow @nogc; + +// Called when a wifi event occurs. Replaces per-event callbacks +// to match the single-callback pattern used by the router layer. +alias WifiEventCallback = void function(Wifi wifi, WifiEvent event, const(void)* data) nothrow @nogc; + +struct Wifi +{ + ubyte port = ubyte.max; +} + +bool is_open(ref const Wifi wifi) +{ + return wifi.port != ubyte.max; +} + + +// ==================================================================== +// Error type +// ==================================================================== + +WifiError wifi_result(Result result) +{ + return cast(WifiError)result.system_code; +} + + +// ==================================================================== +// Implementation +// ==================================================================== + +// Lifecycle + +void wifi_init() +{ + if (_init_refcount++ == 0) + { + // TODO: enable clocks/power for WiFi peripheral block + } +} + +void wifi_deinit() +{ + assert(_init_refcount > 0); + if (--_init_refcount == 0) + { + // TODO: disable clocks/power for WiFi peripheral block + } +} + +// Radio operations + +Result wifi_open(ref Wifi wifi, ubyte port, ref const WifiConfig cfg) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + { + if (port >= num_wifi) + return InternalResult.invalid_parameter; + + if (!wifi_hw_open(port, cfg)) + return InternalResult.failed; + + wifi.port = port; + return Result.success; + } +} + +void wifi_close(ref Wifi wifi) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + wifi_hw_close(wifi.port); + wifi.port = ubyte.max; +} + +Result wifi_set_mode(ref Wifi wifi, WifiMode mode) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + { + if (!wifi_hw_set_mode(wifi.port, mode)) + return InternalResult.failed; + return Result.success; + } +} + +// Station (client) operations + +Result wifi_sta_configure(ref Wifi wifi, ref const WifiStaConfig cfg) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + { + if (!wifi_hw_sta_configure(wifi.port, cfg)) + return InternalResult.failed; + return Result.success; + } +} + +const(char)[] wifi_sta_status_message(ref Wifi wifi) +{ + static if (num_wifi == 0) + return null; + else + return wifi_hw_sta_status_message(wifi.port); +} + +// Begin association. Completion is signalled via WifiEvent.sta_connected +// or WifiEvent.sta_disconnected through the event callback. +Result wifi_sta_connect(ref Wifi wifi) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + { + if (!wifi_hw_sta_connect(wifi.port)) + return InternalResult.failed; + return Result.success; + } +} + +Result wifi_sta_disconnect(ref Wifi wifi) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + { + if (!wifi_hw_sta_disconnect(wifi.port)) + return InternalResult.failed; + return Result.success; + } +} + +// Access point operations + +Result wifi_ap_configure(ref Wifi wifi, ref const WifiApConfig cfg) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + { + if (!wifi_hw_ap_configure(wifi.port, cfg)) + return InternalResult.failed; + return Result.success; + } +} + +Result wifi_ap_set_max_clients(ref Wifi wifi, ubyte max_clients) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + { + if (!wifi_hw_ap_set_max_clients(wifi.port, max_clients)) + return InternalResult.failed; + return Result.success; + } +} + +// Query stations currently connected to our AP. +// Returns the number of entries written (up to buf.length). +size_t wifi_ap_get_clients(ref Wifi wifi, WifiStaInfo[] buf) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + return wifi_hw_ap_get_clients(wifi.port, buf); +} + +// Scanning + +Result wifi_scan_start(ref Wifi wifi, ref const WifiScanConfig cfg) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + { + if (!wifi_hw_scan_start(wifi.port, cfg)) + return InternalResult.failed; + return Result.success; + } +} + +void wifi_scan_stop(ref Wifi wifi) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + wifi_hw_scan_stop(wifi.port); +} + +// Retrieve scan results after WifiEvent.scan_done. +// Returns the number of entries written (up to buf.length). +size_t wifi_scan_get_results(ref Wifi wifi, WifiScanResult[] buf) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + return wifi_hw_scan_get_results(wifi.port, buf); +} + +// Frame TX/RX + +// Transmit an Ethernet frame (including 14-byte header) on a +// virtual interface. +Result wifi_tx(ref Wifi wifi, WifiVif vif, const(ubyte)[] data) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + { + if (!wifi_hw_tx(wifi.port, vif, data)) + return InternalResult.failed; + return Result.success; + } +} + +void wifi_set_rx_callback(ref Wifi wifi, WifiRxCallback cb) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + wifi_hw_set_rx_callback(wifi.port, cb); +} + +// Raw 802.11 frame TX/RX (monitor/promiscuous) + +// Transmit a raw 802.11 frame. Data must include the full MAC header. +// Requires monitor mode or promiscuous capability on the platform. +Result wifi_raw_tx(ref Wifi wifi, const(ubyte)[] frame) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + { + if (!wifi_hw_raw_tx(wifi.port, frame)) + return InternalResult.failed; + return Result.success; + } +} + +void wifi_set_raw_rx_callback(ref Wifi wifi, WifiRawRxCallback cb) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + wifi_hw_set_raw_rx_callback(wifi.port, cb); +} + +// Queries + +Result wifi_get_mac(ref Wifi wifi, WifiVif vif, ref ubyte[6] mac) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + { + if (!wifi_hw_get_mac(wifi.port, vif, mac)) + return InternalResult.failed; + return Result.success; + } +} + +Result wifi_set_channel(ref Wifi wifi, ubyte channel) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + { + if (!wifi_hw_set_channel(wifi.port, channel)) + return InternalResult.failed; + return Result.success; + } +} + +ubyte wifi_get_channel(ref const Wifi wifi) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + return wifi_hw_get_channel(wifi.port); +} + +// STA-only: signal strength of current connection. +byte wifi_get_rssi(ref Wifi wifi) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + return wifi_hw_get_rssi(wifi.port); +} + +Result wifi_set_tx_power(ref Wifi wifi, byte power_dbm) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + { + if (!wifi_hw_set_tx_power(wifi.port, power_dbm)) + return InternalResult.failed; + return Result.success; + } +} + +// Events + +void wifi_set_event_callback(ref Wifi wifi, WifiEventCallback cb) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + wifi_hw_set_event_callback(wifi.port, cb); +} + +// Poll (for platforms without native event delivery) + +void wifi_poll(ref Wifi wifi) +{ + static if (num_wifi == 0) + assert(false, "no WiFi on this platform"); + else + wifi_hw_poll(wifi.port); +} + + +// ==================================================================== +// Tests +// ==================================================================== + +unittest +{ + static if (num_wifi > 0) + { + Wifi w; + WifiConfig cfg; + + wifi_init(); + + // Out-of-range port + auto r = wifi_open(w, cast(ubyte)num_wifi, cfg); + assert(!r); + assert(!w.is_open); + + // Open/close each valid port + foreach (p; 0 .. num_wifi) + { + Wifi port; + auto r2 = wifi_open(port, cast(ubyte)p, cfg); + assert(r2, "wifi_open failed"); + assert(port.is_open); + assert(port.port == p); + + wifi_poll(port); + + wifi_close(port); + assert(!port.is_open); + } + + wifi_deinit(); + } +} + + +private: + +__gshared ubyte _init_refcount; diff --git a/src/urt/driver/windows/alloc.d b/src/urt/driver/windows/alloc.d new file mode 100644 index 0000000..4ebf83b --- /dev/null +++ b/src/urt/driver/windows/alloc.d @@ -0,0 +1,71 @@ +module urt.driver.windows.alloc; + +version (Windows): + +import urt.mem.alloc : MemFlags; + +nothrow @nogc: + + +enum has_realloc = true; +enum has_expand = true; +enum has_memsize = true; +enum has_exec = true; +enum has_retain = false; +enum has_memflags = false; + +void[] _alloc(size_t size, size_t alignment, MemFlags) pure +{ + void* p = _aligned_malloc(size, alignment); + return p ? p[0 .. size] : null; +} + +void _free(void* ptr) pure +{ + _aligned_free(ptr); +} + +void[] _realloc(void[] mem, size_t new_size, size_t alignment, MemFlags) pure +{ + void* p = _aligned_realloc(mem.ptr, new_size, alignment); + return p ? p[0 .. new_size] : null; +} + +void[] _expand(void[] mem, size_t new_size) pure +{ + if (new_size <= _aligned_msize(mem.ptr)) + return mem.ptr[0 .. new_size]; + return null; +} + +size_t _memsize(void* ptr) pure +{ + return _aligned_msize(ptr); +} + +void[] _alloc_exec(size_t size) pure +{ + void* p = VirtualAlloc(null, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + return p ? p[0 .. size] : null; +} + +void _free_exec(void[] mem) pure +{ + VirtualFree(mem.ptr, 0, MEM_RELEASE); +} + + +private: + +extern(C) void* _aligned_malloc(size_t size, size_t alignment) pure; +extern(C) void* _aligned_realloc(void* memblock, size_t size, size_t alignment) pure; +extern(C) void _aligned_free(void* memblock) pure; +extern(C) size_t _aligned_msize(void* memblock) pure; + +extern(Windows) void* VirtualAlloc(void* addr, size_t size, uint type, uint protect) pure; +extern(Windows) bool VirtualFree(void* addr, size_t size, uint type) pure; + +enum MEM_COMMIT = 0x1000; +enum MEM_RESERVE = 0x2000; +enum MEM_RELEASE = 0x8000; +enum PAGE_EXECUTE_READWRITE = 0x40; diff --git a/src/urt/driver/windows/ble.d b/src/urt/driver/windows/ble.d new file mode 100644 index 0000000..e4c3171 --- /dev/null +++ b/src/urt/driver/windows/ble.d @@ -0,0 +1,2053 @@ +// Windows BLE driver -- WinRT Bluetooth LE APIs +// +// Uses Windows.Devices.Bluetooth.* WinRT classes via COM vtable calls. +// All WinRT async operations are polled from ble_hw_poll(). WinRT +// callbacks (advertisements, notifications, connection status) fire on +// thread pool threads and are buffered into thread-safe queues, +// then delivered from ble_hw_poll() on the main loop. +// +// Windows has one BLE radio (port 0). Multiple radios are not +// distinguished by WinRT -- it uses the system default adapter. +module urt.driver.windows.ble; + +version (Windows): + +import urt.atomic : atomicFetchAdd, atomicFetchSub, atomicLoad, atomicStore; +import urt.log; +import urt.mem.allocator : defaultAllocator; +import urt.sync.mpmc : ThreadSafeQueue; +import urt.uuid : GUID; + +import urt.driver.ble; + +nothrow @nogc: + +alias log = Log!"ble"; + +enum uint num_ble = 1; + + +// ==================================================================== +// Driver API implementation +// ==================================================================== + +bool ble_hw_open(uint port, ref const BLEConfig cfg) +{ + if (_opened) + return true; + + if (!g_winrt.initialized && !g_winrt.init()) + { + log.error("WinRT initialization failed"); + return false; + } + + if (_completed_handler is null) + _completed_handler = defaultAllocator().allocT!AsyncCompletedHandler; + + _opened = true; + return true; +} + +void ble_hw_close(uint port) +{ + if (!_opened) + return; + + ble_hw_scan_stop(port); + stop_all_publishers(); + + // disconnect all sessions + foreach (ref s; _sessions[0 .. _num_sessions]) + { + if (s.active) + release_session(&s); + } + _num_sessions = 0; + + cleanup_connect(); + + _opened = false; + _scan_cb = null; + _conn_cb = null; + _discover_cb = null; + _read_cb = null; + _write_cb = null; + _notify_cb = null; + _wake_cb = null; +} + +// --- Scanning --- + +bool ble_hw_scan_start(uint port, ref const BLEScanConfig cfg) +{ + if (_watcher !is null) + return true; // already scanning + + _watcher = g_winrt.activate!IBluetoothLEAdvertisementWatcher( + "Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcher"w, + &IID_IBluetoothLEAdvertisementWatcher); + + if (_watcher is null) + { + log.error("failed to create advertisement watcher"); + return false; + } + + _watcher.put_ScanningMode(cfg.active ? BluetoothLEScanningMode.active : BluetoothLEScanningMode.passive); + + _adv_handler = defaultAllocator().allocT!AdvertisementReceivedHandler; + _adv_handler.callback = &on_advertisement_received; + + EventRegistrationToken token; + if (_watcher.add_Received(cast(IUnknown)_adv_handler, &token) < 0) + { + log.error("failed to subscribe to advertisements"); + return false; + } + _received_token = token; + + // register Stopped handler to detect unexpected watcher shutdown + atomicStore(_watcher_stopped, 0u); + _stopped_handler = defaultAllocator().allocT!WatcherStoppedHandler; + _stopped_handler.flag = &_watcher_stopped; + EventRegistrationToken stopped_token; + _watcher.add_Stopped(cast(IUnknown)_stopped_handler, &stopped_token); + _stopped_token = stopped_token; + + if (_watcher.Start() < 0) + { + log.error("failed to start scanner"); + return false; + } + + return true; +} + +void ble_hw_scan_stop(uint port) +{ + if (_watcher !is null) + { + _watcher.Stop(); + _watcher.remove_Received(_received_token); + _watcher.remove_Stopped(_stopped_token); + _watcher.Release(); + _watcher = null; + } + if (_adv_handler !is null) + { + defaultAllocator().freeT(_adv_handler); + _adv_handler = null; + } + if (_stopped_handler !is null) + { + defaultAllocator().freeT(_stopped_handler); + _stopped_handler = null; + } + atomicStore(_watcher_stopped, 0u); +} + +// --- Advertising --- + +BLEAdv ble_hw_adv_start(uint port, ref const BLEAdvConfig cfg) +{ + if (_num_publishers >= max_publishers) + return BLEAdv.init; + + auto publisher = g_winrt.activate!IBluetoothLEAdvertisementPublisher( + "Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementPublisher"w, + &IID_IBluetoothLEAdvertisementPublisher); + + if (publisher is null) + { + log.error("failed to create advertisement publisher"); + return BLEAdv.init; + } + + IBluetoothLEAdvertisement adv; + publisher.get_Advertisement(&adv); + + if (adv !is null) + { + set_adv_data_from_raw(adv, cfg.adv_data); + adv.Release(); + } + + if (publisher.Start() < 0) + { + log.error("failed to start advertising"); + publisher.Release(); + return BLEAdv.init; + } + + ubyte id = _next_adv_id++; + _publishers[_num_publishers++] = AdvSlot(id, publisher); + return BLEAdv(id); +} + +void ble_hw_adv_stop(uint port, BLEAdv adv) +{ + foreach (i, ref slot; _publishers[0 .. _num_publishers]) + { + if (slot.id == adv.id) + { + slot.publisher.Stop(); + slot.publisher.Release(); + _publishers[i] = _publishers[_num_publishers - 1]; + _num_publishers--; + return; + } + } +} + +// --- Connection --- + +bool ble_hw_connect(uint port, ref const ubyte[6] peer_addr, BLEAddrType addr_type, ref const BLEConnConfig cfg) +{ + if (_pending_connect.async_op !is null) + { + log.warning("connection already in progress"); + return false; + } + + if (_device_statics is null) + { + _device_statics = g_winrt.get_factory!IBluetoothLEDeviceStatics( + "Windows.Devices.Bluetooth.BluetoothLEDevice"w, + &IID_IBluetoothLEDeviceStatics); + + if (_device_statics is null) + { + log.error("failed to get BluetoothLEDevice statics"); + return false; + } + } + + ulong ble_addr = mac_to_ble_addr(peer_addr); + + IInspectable async_op; + if (_device_statics.FromBluetoothAddressAsync(ble_addr, &async_op) < 0 || async_op is null) + { + log.error("FromBluetoothAddressAsync failed"); + return false; + } + + register_completion(async_op); + _pending_connect.async_op = async_op; + _pending_connect.peer_addr = peer_addr; + return true; +} + +void ble_hw_connect_cancel(uint port) +{ + cleanup_connect(); +} + +bool ble_hw_disconnect(uint port, BLEConn conn) +{ + auto s = find_session(conn.id); + if (s is null) + return false; + + release_session(s); + remove_session(conn.id); + return true; +} + +// --- GATT discovery --- + +bool ble_hw_gatt_discover(uint port, BLEConn conn) +{ + auto s = find_session(conn.id); + if (s is null || s.device3 is null) + return false; + + IInspectable gatt_op; + s.device3.GetGattServicesWithCacheModeAsync(1, &gatt_op); // 1 = Uncached + if (gatt_op is null) + return false; + + register_completion(gatt_op); + _pending_discover.async_op = gatt_op; + _pending_discover.conn_id = conn.id; + _pending_discover.phase = DiscoverPhase.services; + s.num_chars = 0; + + return true; +} + +// --- GATT read/write --- + +bool ble_hw_gatt_read(uint port, BLEConn conn, ushort handle) +{ + if (_num_pending_gatt >= max_gatt_ops) + return false; + + auto s = find_session(conn.id); + if (s is null) + return false; + + auto gc = find_session_char(s, handle); + if (gc is null || gc.characteristic is null) + return false; + + IInspectable async_op; + gc.characteristic.ReadValueWithCacheModeAsync(1, &async_op); // Uncached + if (async_op is null) + return false; + + register_completion(async_op); + _pending_gatt[_num_pending_gatt++] = PendingGattOp( + async_op, conn.id, handle, GattOpType.read); + return true; +} + +bool ble_hw_gatt_write(uint port, BLEConn conn, ushort handle, const(ubyte)[] data, bool with_response) +{ + if (_num_pending_gatt >= max_gatt_ops) + return false; + + auto s = find_session(conn.id); + if (s is null) + return false; + + auto gc = find_session_char(s, handle); + if (gc is null || gc.characteristic is null) + return false; + + auto buf = defaultAllocator().allocT!MemoryBuffer; + if (buf is null) + return false; + + // clone data -- packet payload may be freed before async completes + ubyte* data_copy = cast(ubyte*)defaultAllocator().alloc(data.length).ptr; + if (data_copy is null && data.length > 0) + { + defaultAllocator().freeT(buf); + return false; + } + data_copy[0 .. data.length] = data[]; + buf.set(data_copy[0 .. data.length]); + + IInspectable async_op; + if (with_response) + gc.characteristic.WriteValueAsync(cast(IBuffer)buf, &async_op); + else + gc.characteristic.WriteValueWithOptionAsync(cast(IBuffer)buf, 1, &async_op); // WriteWithoutResponse + + if (async_op is null) + { + buf.Release(); // frees both MemoryBuffer and data_copy + return false; + } + + register_completion(async_op); + _pending_gatt[_num_pending_gatt++] = PendingGattOp( + async_op, conn.id, handle, + with_response ? GattOpType.write : GattOpType.write_no_response); + return true; +} + +// --- Notifications --- + +bool ble_hw_gatt_subscribe(uint port, BLEConn conn, ushort handle, bool enable) +{ + auto s = find_session(conn.id); + if (s is null) + return false; + + auto gc = find_session_char(s, handle); + if (gc is null || gc.characteristic is null) + return false; + + if (enable) + { + if (gc.notify_handler !is null) + return true; // already subscribed + + auto handler = defaultAllocator().allocT!GattValueChangedHandler; + handler.conn_id = conn.id; + handler.attr_handle = handle; + handler.callback = &on_gatt_notification; + + EventRegistrationToken token; + if (gc.characteristic.add_ValueChanged(cast(IUnknown)handler, &token) < 0) + { + defaultAllocator().freeT(handler); + return false; + } + gc.notify_handler = handler; + gc.notify_token = token; + + // write CCCD + GattCharacteristicProperties props; + gc.characteristic.get_CharacteristicProperties(&props); + + auto cccd_value = (props & GattCharacteristicProperties.notify) != 0 + ? GattClientCharacteristicConfigurationDescriptorValue.notify + : GattClientCharacteristicConfigurationDescriptorValue.indicate; + + IInspectable async_op; + gc.characteristic.WriteClientCharacteristicConfigurationDescriptorAsync(cccd_value, &async_op); + if (async_op !is null) + (cast(IUnknown)async_op).Release(); // fire and forget + } + else + { + if (gc.notify_handler is null) + return true; // not subscribed + + gc.characteristic.remove_ValueChanged(gc.notify_token); + defaultAllocator().freeT(gc.notify_handler); + gc.notify_handler = null; + + // write CCCD to disable + IInspectable async_op; + gc.characteristic.WriteClientCharacteristicConfigurationDescriptorAsync( + GattClientCharacteristicConfigurationDescriptorValue.none, &async_op); + if (async_op !is null) + (cast(IUnknown)async_op).Release(); // fire and forget + } + + return true; +} + +// --- Queries --- + +bool ble_hw_get_mac(uint port, ref ubyte[6] mac) +{ + // WinRT doesn't easily expose the local adapter MAC. + // Return a placeholder; the interface layer can override. + mac = [0, 0, 0, 0, 0, 0]; + return false; +} + +byte ble_hw_get_rssi(uint port, BLEConn conn) +{ + // WinRT doesn't provide per-connection RSSI queries + return -128; +} + +// --- Callbacks --- + +void ble_hw_set_scan_callback(uint port, BLEScanCallback cb) { _scan_cb = cb; } +void ble_hw_set_conn_callback(uint port, BLEConnCallback cb) { _conn_cb = cb; } +void ble_hw_set_discover_callback(uint port, BLEDiscoverCallback cb) { _discover_cb = cb; } +void ble_hw_set_read_callback(uint port, BLEReadCallback cb) { _read_cb = cb; } +void ble_hw_set_write_callback(uint port, BLEWriteCallback cb) { _write_cb = cb; } +void ble_hw_set_notify_callback(uint port, BLENotifyCallback cb) { _notify_cb = cb; } +void ble_hw_set_wake_callback(uint port, BLEWakeCallback cb) { _wake_cb = cb; } + +// --- Poll --- + +void ble_hw_poll(uint port) +{ + auto ble = BLE(0); + + // check if watcher stopped unexpectedly (e.g. radio disabled) + if (atomicLoad(_watcher_stopped) != 0) + { + log.warning("BLE scanner stopped unexpectedly"); + atomicStore(_watcher_stopped, 0u); + } + + // drain scan results + BLEAdvReport report = void; + while (_scan_ring.dequeue(&report)) + { + if (_scan_cb !is null) + _scan_cb(ble, report); + } + + // poll pending connection + poll_connect(ble); + + // poll GATT discovery + poll_discover(ble); + + // poll GATT read/write ops + poll_gatt(ble); + + // drain notification events + NotifyEvent evt = void; + while (_notify_ring.dequeue(&evt)) + { + if (_notify_cb !is null) + _notify_cb(ble, BLEConn(evt.conn_id), evt.handle, evt.data[0 .. evt.data_len]); + } + + // drain disconnection events + ubyte conn_id = void; + while (_disconn_ring.dequeue(&conn_id)) + { + auto s = find_session(conn_id); + if (s !is null) + { + if (_conn_cb !is null) + _conn_cb(ble, BLEConn(conn_id), false, BLEError.none); + release_session(s); + remove_session(conn_id); + } + } +} + + +// ==================================================================== +// Internal state +// ==================================================================== + +private: + +enum max_sessions = 8; +enum max_chars_per_session = 32; +enum max_gatt_ops = 8; +enum max_publishers = 8; + +struct AdvSlot +{ + ubyte id; + IBluetoothLEAdvertisementPublisher publisher; +} + +enum GattOpType : ubyte { read, write, write_no_response } +enum DiscoverPhase : ubyte { idle, services, chars } + +struct SessionChar +{ + ushort handle; + GUID service_uuid; + GUID char_uuid; + GattCharacteristicProperties properties; + IGattCharacteristic characteristic; + GattValueChangedHandler notify_handler; + EventRegistrationToken notify_token; +} + +struct WinSession +{ + bool active; + ubyte id; + IBluetoothLEDevice device; + IBluetoothLEDevice3 device3; + ConnectionStatusHandler conn_handler; + EventRegistrationToken conn_status_token; + SessionChar[max_chars_per_session] chars; + ubyte num_chars; +} + +struct PendingConnect +{ + IInspectable async_op; + ubyte[6] peer_addr; +} + +struct PendingDiscover +{ + IInspectable async_op; + IVectorView_IInspectable services; + uint service_count; + uint current_service; + GUID current_service_uuid; + ubyte conn_id; + DiscoverPhase phase; +} + +struct PendingGattOp +{ + IInspectable async_op; + ubyte conn_id; + ushort handle; + GattOpType op_type; +} + +struct NotifyEvent +{ + ubyte conn_id; + ushort handle; + ubyte data_len; + ubyte[247] data; +} + +// --- module-level state --- + +__gshared bool _opened; +__gshared ubyte _next_conn_id; + +// sessions +__gshared WinSession[max_sessions] _sessions; +__gshared ubyte _num_sessions; + +// callbacks +__gshared BLEScanCallback _scan_cb; +__gshared BLEConnCallback _conn_cb; +__gshared BLEDiscoverCallback _discover_cb; +__gshared BLEReadCallback _read_cb; +__gshared BLEWriteCallback _write_cb; +__gshared BLENotifyCallback _notify_cb; +__gshared BLEWakeCallback _wake_cb; +__gshared AsyncCompletedHandler _completed_handler; + +void signal_wake() +{ + if (_wake_cb !is null) + _wake_cb(); +} + +void register_completion(IInspectable async_op) +{ + if (async_op is null || _completed_handler is null) + return; + auto a = cast(IAsyncOperation_BluetoothLEDevice)cast(void*)async_op; + a.put_Completed(cast(IUnknown)_completed_handler); +} + +// scanner +__gshared IBluetoothLEAdvertisementWatcher _watcher; +__gshared AdvertisementReceivedHandler _adv_handler; +__gshared EventRegistrationToken _received_token; +__gshared WatcherStoppedHandler _stopped_handler; +__gshared EventRegistrationToken _stopped_token; +shared uint _watcher_stopped; + +// advertisers +__gshared AdvSlot[max_publishers] _publishers; +__gshared ubyte _num_publishers; +__gshared ubyte _next_adv_id; + +// device factory +__gshared IBluetoothLEDeviceStatics _device_statics; + +// pending connect +__gshared PendingConnect _pending_connect; + +// pending discover +__gshared PendingDiscover _pending_discover; + +// pending GATT ops +__gshared PendingGattOp[max_gatt_ops] _pending_gatt; +__gshared ubyte _num_pending_gatt; + +// thread-safe event queues (written from WinRT threads, read from main) +__gshared ThreadSafeQueue!(32, BLEAdvReport) _scan_ring; +__gshared ThreadSafeQueue!(32, NotifyEvent) _notify_ring; +__gshared ThreadSafeQueue!(8, ubyte) _disconn_ring; + + +// ==================================================================== +// Session management +// ==================================================================== + +WinSession* find_session(ubyte id) +{ + foreach (ref s; _sessions[0 .. _num_sessions]) + { + if (s.active && s.id == id) + return &s; + } + return null; +} + +SessionChar* find_session_char(WinSession* s, ushort handle) +{ + foreach (ref c; s.chars[0 .. s.num_chars]) + { + if (c.handle == handle) + return &c; + } + return null; +} + +WinSession* alloc_session() +{ + if (_num_sessions >= max_sessions) + return null; + + // find an ID not currently in use + ubyte id = _next_conn_id; + outer: foreach (_; 0 .. 256) + { + foreach (ref s; _sessions[0 .. _num_sessions]) + if (s.id == id) + { + id++; + continue outer; + } + break; + } + _next_conn_id = cast(ubyte)(id + 1); + + auto s = &_sessions[_num_sessions++]; + s.active = true; + s.id = id; + s.num_chars = 0; + return s; +} + +void remove_session(ubyte id) +{ + foreach (i, ref s; _sessions[0 .. _num_sessions]) + { + if (s.id == id) + { + _sessions[i] = _sessions[_num_sessions - 1]; + _num_sessions--; + return; + } + } +} + +void release_session(WinSession* s) +{ + if (s.device !is null && s.conn_handler !is null) + { + s.device.remove_ConnectionStatusChanged(s.conn_status_token); + defaultAllocator().freeT(s.conn_handler); + s.conn_handler = null; + } + + foreach (ref gc; s.chars[0 .. s.num_chars]) + { + if (gc.notify_handler !is null) + { + gc.characteristic.remove_ValueChanged(gc.notify_token); + defaultAllocator().freeT(gc.notify_handler); + gc.notify_handler = null; + } + if (gc.characteristic !is null) + { + gc.characteristic.Release(); + gc.characteristic = null; + } + } + + if (s.device3 !is null) + { + s.device3.Release(); + s.device3 = null; + } + if (s.device !is null) + { + s.device.Release(); + s.device = null; + } + s.active = false; +} + +void stop_all_publishers() +{ + foreach (ref slot; _publishers[0 .. _num_publishers]) + { + slot.publisher.Stop(); + slot.publisher.Release(); + } + _num_publishers = 0; +} + +void cleanup_connect() +{ + if (_pending_connect.async_op !is null) + { + _pending_connect.async_op.Release(); + _pending_connect.async_op = null; + } +} + + +// ==================================================================== +// Async polling (main thread) +// ==================================================================== + +void poll_connect(BLE ble) +{ + if (_pending_connect.async_op is null) + return; + + auto async_info = qi!IAsyncInfo(_pending_connect.async_op, &IID_IAsyncInfo); + if (async_info is null) + return; + scope(exit) async_info.Release(); + + AsyncStatus status; + async_info.get_Status(&status); + + if (status == AsyncStatus.started) + return; + + if (status != AsyncStatus.completed) + { + cleanup_connect(); + if (_conn_cb !is null) + _conn_cb(ble, BLEConn(ubyte.max), false, BLEError.not_found); + return; + } + + auto async_op = cast(IAsyncOperation_BluetoothLEDevice)cast(void*)_pending_connect.async_op; + IBluetoothLEDevice device; + async_op.GetResults(&device); + + auto peer_addr = _pending_connect.peer_addr; + cleanup_connect(); + + if (device is null) + { + if (_conn_cb !is null) + _conn_cb(ble, BLEConn(ubyte.max), false, BLEError.not_found); + return; + } + + auto s = alloc_session(); + if (s is null) + { + device.Release(); + if (_conn_cb !is null) + _conn_cb(ble, BLEConn(ubyte.max), false, BLEError.internal); + return; + } + + s.device = device; + s.device3 = qi!IBluetoothLEDevice3(device, &IID_IBluetoothLEDevice3); + + // register connection status handler + auto handler = defaultAllocator().allocT!ConnectionStatusHandler; + handler.conn_id = s.id; + handler.callback = &on_connection_status_changed; + s.device.add_ConnectionStatusChanged(cast(IUnknown)handler, &s.conn_status_token); + s.conn_handler = handler; + + log.info("connected to ", peer_addr); + + if (_conn_cb !is null) + _conn_cb(ble, BLEConn(s.id), true, BLEError.none); +} + +void poll_discover(BLE ble) +{ + if (_pending_discover.phase == DiscoverPhase.idle) + return; + if (_pending_discover.async_op is null && _pending_discover.services is null) + return; + if (_pending_discover.async_op is null) + return; + + auto async_info = qi!IAsyncInfo(_pending_discover.async_op, &IID_IAsyncInfo); + if (async_info is null) + return; + scope(exit) async_info.Release(); + + AsyncStatus status; + async_info.get_Status(&status); + + if (status == AsyncStatus.started) + return; + + IInspectable result_raw; + if (status == AsyncStatus.completed) + { + if (_pending_discover.services is null) + { + auto async_op = cast(IAsyncOperation_GattDeviceServicesResult)cast(void*)_pending_discover.async_op; + IGattDeviceServicesResult svc_result; + async_op.GetResults(&svc_result); + result_raw = cast(IInspectable)cast(void*)svc_result; + } + else + { + auto async_op = cast(IAsyncOperation_GattCharacteristicsResult)cast(void*)_pending_discover.async_op; + IGattCharacteristicsResult chr_result; + async_op.GetResults(&chr_result); + result_raw = cast(IInspectable)cast(void*)chr_result; + } + } + + // release async op + _pending_discover.async_op.Release(); + _pending_discover.async_op = null; + + auto conn_id = _pending_discover.conn_id; + auto s = find_session(conn_id); + + if (_pending_discover.services is null) + { + // phase 1: service list + if (result_raw is null) + { + finish_discover(ble, conn_id, BLEError.protocol); + return; + } + + auto svc_result = cast(IGattDeviceServicesResult)cast(void*)result_raw; + GattCommunicationStatus gatt_status; + svc_result.get_Status(&gatt_status); + + if (gatt_status != GattCommunicationStatus.success) + { + result_raw.Release(); + finish_discover(ble, conn_id, BLEError.protocol); + return; + } + + IInspectable services_raw; + svc_result.get_Services(&services_raw); + result_raw.Release(); + + if (services_raw is null) + { + finish_discover(ble, conn_id, BLEError.none); + return; + } + + auto services = cast(IVectorView_IInspectable)cast(void*)services_raw; + uint count; + services.get_Size(&count); + + _pending_discover.services = services; + _pending_discover.service_count = count; + _pending_discover.current_service = 0; + _pending_discover.phase = DiscoverPhase.chars; + + discover_next_service(); + } + else + { + // phase 2: characteristics for a service + if (result_raw !is null && s !is null) + { + auto chars_result = cast(IGattCharacteristicsResult)cast(void*)result_raw; + GattCommunicationStatus gatt_status; + chars_result.get_Status(&gatt_status); + + if (gatt_status == GattCommunicationStatus.success) + { + IInspectable chars_raw; + chars_result.get_Characteristics(&chars_raw); + if (chars_raw !is null) + { + auto chars = cast(IVectorView_IInspectable)cast(void*)chars_raw; + uint count; + chars.get_Size(&count); + + foreach (j; 0 .. count) + { + IInspectable char_raw; + chars.GetAt(j, &char_raw); + if (char_raw is null) + continue; + + auto chr = cast(IGattCharacteristic)cast(void*)char_raw; + if (s.num_chars < max_chars_per_session) + { + auto ci = &s.chars[s.num_chars++]; + chr.get_AttributeHandle(&ci.handle); + ci.service_uuid = _pending_discover.current_service_uuid; + chr.get_Uuid(&ci.char_uuid); + chr.get_CharacteristicProperties(&ci.properties); + ci.characteristic = chr; + } + else + (cast(IUnknown)chr).Release(); + } + chars_raw.Release(); + } + } + result_raw.Release(); + } + + _pending_discover.current_service++; + if (!discover_next_service()) + finish_discover(ble, conn_id, BLEError.none); + } +} + +bool discover_next_service() +{ + auto services = _pending_discover.services; + while (_pending_discover.current_service < _pending_discover.service_count) + { + IInspectable svc_raw; + services.GetAt(_pending_discover.current_service, &svc_raw); + if (svc_raw is null) + { + _pending_discover.current_service++; + continue; + } + + auto svc = cast(IGattDeviceService)cast(void*)svc_raw; + svc.get_Uuid(&_pending_discover.current_service_uuid); + + auto svc3 = qi!IGattDeviceService3(svc_raw, &IID_IGattDeviceService3); + svc_raw.Release(); + + if (svc3 is null) + { + _pending_discover.current_service++; + continue; + } + + IInspectable chars_op; + svc3.GetCharacteristicsAsync(&chars_op); + svc3.Release(); + + if (chars_op is null) + { + _pending_discover.current_service++; + continue; + } + + register_completion(chars_op); + _pending_discover.async_op = chars_op; + return true; + } + + // all done + if (_pending_discover.services !is null) + { + (cast(IUnknown)_pending_discover.services).Release(); + _pending_discover.services = null; + } + return false; +} + +void finish_discover(BLE ble, ubyte conn_id, BLEError error) +{ + if (_pending_discover.services !is null) + { + (cast(IUnknown)_pending_discover.services).Release(); + _pending_discover.services = null; + } + _pending_discover.phase = DiscoverPhase.idle; + + if (_discover_cb !is null) + { + auto s = find_session(conn_id); + if (s !is null && error == BLEError.none) + { + BLEGattChar[max_chars_per_session] chars = void; + foreach (i; 0 .. s.num_chars) + { + chars[i].handle = s.chars[i].handle; + chars[i].cccd_handle = 0; // WinRT handles CCCD internally + chars[i].service_uuid = s.chars[i].service_uuid; + chars[i].char_uuid = s.chars[i].char_uuid; + chars[i].properties = cast(GattCharProps)s.chars[i].properties; + } + _discover_cb(ble, BLEConn(conn_id), chars[0 .. s.num_chars], BLEError.none); + } + else + _discover_cb(ble, BLEConn(conn_id), null, error); + } +} + +void poll_gatt(BLE ble) +{ + uint i = 0; + while (i < _num_pending_gatt) + { + auto pg = &_pending_gatt[i]; + + auto async_info = qi!IAsyncInfo(pg.async_op, &IID_IAsyncInfo); + if (async_info is null) + { + i++; + continue; + } + + AsyncStatus status; + async_info.get_Status(&status); + async_info.Release(); + + if (status == AsyncStatus.started) + { + i++; + continue; + } + + auto conn = BLEConn(pg.conn_id); + bool success = false; + const(ubyte)[] data; + IBuffer value_buf; + + if (status == AsyncStatus.completed) + { + if (pg.op_type == GattOpType.read) + { + auto async_op = cast(IAsyncOperation_GattReadResult)cast(void*)pg.async_op; + IGattReadResult read_result; + async_op.GetResults(&read_result); + + if (read_result !is null) + { + GattCommunicationStatus gatt_status; + read_result.get_Status(&gatt_status); + if (gatt_status == GattCommunicationStatus.success) + { + read_result.get_Value(&value_buf); + data = get_buffer_bytes(value_buf); + success = true; + } + read_result.Release(); + } + } + else + { + auto async_op = cast(IAsyncOperation_GattCommunicationStatus)cast(void*)pg.async_op; + GattCommunicationStatus gatt_status; + async_op.GetResults(&gatt_status); + success = gatt_status == GattCommunicationStatus.success; + } + } + + // fire callback + if (pg.op_type == GattOpType.read) + { + if (_read_cb !is null) + _read_cb(ble, conn, pg.handle, data, success ? BLEError.none : BLEError.protocol); + } + else + { + if (_write_cb !is null) + _write_cb(ble, conn, pg.handle, success ? BLEError.none : BLEError.protocol); + } + + if (value_buf !is null) + value_buf.Release(); + pg.async_op.Release(); + + // compact array + --_num_pending_gatt; + if (i < _num_pending_gatt) + _pending_gatt[i] = _pending_gatt[_num_pending_gatt]; + // don't increment i -- swapped element needs checking + } +} + + +// ==================================================================== +// WinRT thread callbacks (fire on thread pool) +// ==================================================================== + +void on_advertisement_received(ubyte[6] addr, byte rssi, bool connectable, bool is_scan_response, const(ubyte)[] ad_payload) +{ + BLEAdvReport report = void; + report.addr = addr; + report.addr_type = BLEAddrType.public_; + report.adv_type = connectable ? BLEAdvType.connectable : BLEAdvType.nonconnectable; + report.rssi = rssi; + report.tx_power = -128; + ubyte len = ad_payload.length > 62 ? 62 : cast(ubyte)ad_payload.length; + report.data_len = len; + if (len > 0) + report.data_buf[0 .. len] = cast(const(ubyte)[])ad_payload[0 .. len]; + _scan_ring.enqueue(report); + signal_wake(); +} + +void on_gatt_notification(ubyte conn_id, ushort attr_handle, const(ubyte)[] data) +{ + NotifyEvent evt = void; + evt.conn_id = conn_id; + evt.handle = attr_handle; + ubyte len = data.length > 247 ? 247 : cast(ubyte)data.length; + evt.data_len = len; + if (len > 0) + evt.data[0 .. len] = cast(const(ubyte)[])data[0 .. len]; + _notify_ring.enqueue(evt); + signal_wake(); +} + +void on_connection_status_changed(ubyte conn_id, int status) +{ + if (status == 0) // Disconnected + { + _disconn_ring.enqueue(conn_id); + signal_wake(); + } +} + + +// ==================================================================== +// Helpers +// ==================================================================== + +T qi(T)(IUnknown obj, const(GUID)* iid) +{ + if (obj is null) + return null; + void* result; + HRESULT hr = obj.QueryInterface(iid, &result); + if (hr < 0) + return null; + return cast(T)cast(void*)result; +} + +ulong mac_to_ble_addr(ref const ubyte[6] mac) +{ + return (cast(ulong)mac[0] << 40) | (cast(ulong)mac[1] << 32) | + (cast(ulong)mac[2] << 24) | (cast(ulong)mac[3] << 16) | + (cast(ulong)mac[4] << 8) | mac[5]; +} + +void ble_addr_to_mac(ulong addr, ref ubyte[6] mac) +{ + mac[0] = cast(ubyte)(addr >> 40); + mac[1] = cast(ubyte)(addr >> 32); + mac[2] = cast(ubyte)(addr >> 24); + mac[3] = cast(ubyte)(addr >> 16); + mac[4] = cast(ubyte)(addr >> 8); + mac[5] = cast(ubyte)(addr); +} + +const(ubyte)[] get_buffer_bytes(IBuffer buf) +{ + if (buf is null) + return null; + + uint len; + if (buf.get_Length(&len) < 0) + return null; + if (len == 0) + return null; + + auto access = qi!IBufferByteAccess(buf, &IID_IBufferByteAccess); + if (access is null) + return null; + scope(exit) access.Release(); + + ubyte* ptr; + if (access.Buffer(&ptr) < 0 || ptr is null) + return null; + + return ptr[0 .. len]; +} + +void set_adv_data_from_raw(IBluetoothLEAdvertisement adv, const(ubyte)[] raw) +{ + uint offset = 0; + while (offset < raw.length) + { + if (offset + 1 >= raw.length) + break; + ubyte len = raw[offset++]; + if (len == 0 || offset + len > raw.length) + break; + ubyte ad_type = raw[offset]; + const(ubyte)[] ad_data = raw[offset + 1 .. offset + len]; + offset += len; + + // set local name if present + if (ad_type == 0x09 || ad_type == 0x08) // complete/shortened local name + { + wchar[64] wname = void; + uint wlen = cast(uint)ad_data.length; + if (wlen > 64) wlen = 64; + foreach (i; 0 .. wlen) + wname[i] = ad_data[i]; + HSTRING hname = g_winrt.make_string(wname[0 .. wlen]); + if (hname !is null) + { + adv.put_LocalName(hname); + g_winrt.WindowsDeleteString(hname); + } + } + } +} + + +// ==================================================================== +// WinRT bootstrap +// ==================================================================== + +struct WinRT +{ +nothrow @nogc: + bool initialized; + + import urt.internal.sys.windows.windef : HMODULE; + private HMODULE _lib; + + extern(Windows) HRESULT function(uint initType) RoInitialize; + extern(Windows) HRESULT function(HSTRING classId, IInspectable* instance) RoActivateInstance; + extern(Windows) HRESULT function(HSTRING classId, const(GUID)* iid, void** factory) RoGetActivationFactory; + extern(Windows) HRESULT function(const(wchar)* str, uint len, HSTRING* out_) WindowsCreateString; + extern(Windows) HRESULT function(HSTRING str) WindowsDeleteString; + extern(Windows) const(wchar)* function(HSTRING str, uint* len) WindowsGetStringRawBuffer; + + bool init() + { + import urt.internal.sys.windows.winbase : LoadLibrary, FreeLibrary, GetProcAddress; + + auto lib = LoadLibrary("combase.dll"); + if (!lib) + { + log.error("failed to load combase.dll"); + return false; + } + + RoInitialize = cast(typeof(RoInitialize)) GetProcAddress(lib, "RoInitialize"); + RoActivateInstance = cast(typeof(RoActivateInstance)) GetProcAddress(lib, "RoActivateInstance"); + RoGetActivationFactory = cast(typeof(RoGetActivationFactory)) GetProcAddress(lib, "RoGetActivationFactory"); + WindowsCreateString = cast(typeof(WindowsCreateString)) GetProcAddress(lib, "WindowsCreateString"); + WindowsDeleteString = cast(typeof(WindowsDeleteString)) GetProcAddress(lib, "WindowsDeleteString"); + WindowsGetStringRawBuffer = cast(typeof(WindowsGetStringRawBuffer)) GetProcAddress(lib, "WindowsGetStringRawBuffer"); + + if (!RoInitialize || !RoActivateInstance || !RoGetActivationFactory || + !WindowsCreateString || !WindowsDeleteString || !WindowsGetStringRawBuffer) + { + log.error("failed to resolve WinRT functions from combase.dll"); + FreeLibrary(lib); + return false; + } + + HRESULT hr = RoInitialize(1); // RO_INIT_MULTITHREADED + if (hr < 0 && hr != cast(HRESULT)0x80010106) // RPC_E_CHANGED_MODE is ok + { + log.error("RoInitialize failed: ", hr); + FreeLibrary(lib); + return false; + } + + _lib = lib; + initialized = true; + log.info("WinRT initialized"); + return true; + } + + HSTRING make_string(const(wchar)[] s) + { + HSTRING h; + if (WindowsCreateString(s.ptr, cast(uint)s.length, &h) < 0) + return null; + return h; + } + + T activate(T : IInspectable)(const(wchar)[] className, const(GUID)* iid) + { + HSTRING cls = make_string(className); + if (!cls) + return null; + scope(exit) WindowsDeleteString(cls); + + IInspectable inspectable; + if (RoActivateInstance(cls, &inspectable) < 0 || inspectable is null) + return null; + scope(exit) inspectable.Release(); + + void* result; + if (inspectable.QueryInterface(iid, &result) < 0) + return null; + return cast(T)cast(void*)result; + } + + T get_factory(T)(const(wchar)[] className, const(GUID)* iid) + { + HSTRING cls = make_string(className); + if (!cls) + return null; + scope(exit) WindowsDeleteString(cls); + + void* result; + if (RoGetActivationFactory(cls, iid, &result) < 0) + return null; + return cast(T)cast(void*)result; + } +} + +__gshared WinRT g_winrt; + + +// ==================================================================== +// COM/WinRT types and interfaces +// ==================================================================== + +alias HRESULT = int; +alias ULONG = uint; +alias BOOL = int; +alias HSTRING = void*; + +struct EventRegistrationToken { long value; } + +enum AsyncStatus : int { started = 0, completed = 1, canceled = 2, error = 3 } +enum BluetoothLEScanningMode : int { passive = 0, active = 1 } +enum GattCommunicationStatus : int { success = 0, unreachable = 1, protocol_error = 2, access_denied = 3 } + +enum GattCharacteristicProperties : uint +{ + none = 0, broadcast = 0x0001, read = 0x0002, write_without_response = 0x0004, + write = 0x0008, notify = 0x0010, indicate = 0x0020, + authenticated_signed_writes = 0x0040, extended_properties = 0x0080, + reliable_write = 0x0100, writable_auxiliaries = 0x0200, +} + +enum GattClientCharacteristicConfigurationDescriptorValue : int { none = 0, notify = 1, indicate = 2 } + +// GUIDs +static immutable IID_IUnknown = GUID(0x00000000, 0x0000, 0x0000, [0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46]); +static immutable IID_IInspectable = GUID(0xAF86E2E0, 0xB12D, 0x4C6A, [0x9C,0x5A,0xD7,0xAA,0x65,0x10,0x1E,0x90]); +static immutable IID_IAgileObject = GUID(0x94EA2B94, 0xE9CC, 0x49E0, [0xC0,0xFF,0xEE,0x64,0xCA,0x8F,0x5B,0x90]); +static immutable IID_IAsyncInfo = GUID(0x00000036, 0x0000, 0x0000, [0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46]); + +static immutable IID_IBluetoothLEAdvertisementWatcher = GUID(0xA6AC336F, 0xF3D3, 0x4297, [0x8D,0x6C,0xC8,0x1E,0xA6,0x62,0x3F,0x40]); +static immutable IID_IBluetoothLEAdvertisementReceivedEventArgs = GUID(0x27987DDF, 0xE596, 0x41BE, [0x8D,0x43,0x9E,0x67,0x31,0xD4,0xA9,0x13]); +static immutable IID_IBluetoothLEAdvertisementReceivedEventArgs2 = GUID(0x12D9C87B, 0x0399, 0x5F0E, [0xA3,0x48,0x53,0xB0,0x2B,0x6B,0x16,0x2E]); +static immutable IID_IBluetoothLEAdvertisement = GUID(0x066FB2B7, 0x33D1, 0x4E7D, [0x83,0x67,0xCF,0x81,0xD0,0xF7,0x96,0x53]); +static immutable IID_IBluetoothLEDevice = GUID(0xB5EE2F7B, 0x4AD8, 0x4642, [0xAC,0x48,0x80,0xA0,0xB5,0x00,0xE8,0x87]); +static immutable IID_IBluetoothLEDeviceStatics = GUID(0xC8CF1A19, 0xF0B6, 0x4BF0, [0x86,0x89,0x41,0x30,0x3D,0xE2,0xD9,0xF4]); +static immutable IID_IBluetoothLEDevice3 = GUID(0xAEE9E493, 0x44AC, 0x40DC, [0xAF,0x33,0xB2,0xC1,0x3C,0x01,0xCA,0x46]); +static immutable IID_IGattDeviceServicesResult = GUID(0x171DD3EE, 0x016D, 0x419D, [0x83,0x8A,0x57,0x6C,0xF4,0x75,0xA3,0xD8]); +static immutable IID_IGattDeviceService3 = GUID(0xB293A950, 0x0C53, 0x437C, [0xA9,0xB3,0x5C,0x32,0x10,0xC6,0xE5,0x69]); +static immutable IID_IGattCharacteristic = GUID(0x59CB50C1, 0x5934, 0x4F68, [0xA1,0x98,0xEB,0x86,0x4F,0xA4,0x4E,0x6B]); +static immutable IID_IGattReadResult = GUID(0x63A66F08, 0x1AEA, 0x4C4C, [0xA5,0x0F,0x97,0xBA,0xE4,0x74,0xB3,0x48]); +static immutable IID_IBluetoothLEAdvertisementPublisher = GUID(0xCDE820F9, 0xD9FA, 0x43D6, [0xA2,0x64,0xDD,0xD8,0xB7,0xDA,0x8B,0x78]); +static immutable IID_IBufferByteAccess = GUID(0x905A0FEF, 0xBC53, 0x11DF, [0x8C,0x49,0x00,0x1E,0x4F,0xC6,0x86,0xDA]); +static immutable IID_TypedEventHandler_Watcher_Received = GUID(0x90EB4ECA, 0xD465, 0x5EA0, [0xA6,0x1C,0x03,0x3C,0x8C,0x5E,0xCE,0xF2]); +static immutable IID_TypedEventHandler_Gatt_ValueChanged = GUID(0xC1F420F6, 0x6292, 0x5760, [0xA2,0xC9,0x9D,0xDF,0x98,0x68,0x3C,0xFC]); +static immutable IID_TypedEventHandler_Device_ConnectionStatus = GUID(0x24A901AD, 0x910F, 0x5C29, [0xB2,0x36,0x80,0x3C,0xC0,0x30,0x60,0xFE]); +static immutable IID_TypedEventHandler_Watcher_Stopped = GUID(0x9936A4DB, 0xDC99, 0x55C3, [0x9E,0x9B,0xBF,0x48,0x54,0xBD,0x9F,0x0B]); + +// IAsyncOperationCompletedHandler - one IID per T, from the Windows SDK headers +static immutable IID_AsyncCompleted_BluetoothLEDevice = GUID(0x9156b79f, 0xc54a, 0x5277, [0x8f,0x8b,0xd2,0xcc,0x43,0xc7,0xe0,0x04]); +static immutable IID_AsyncCompleted_GattDeviceServicesResult = GUID(0x74ab0892, 0xa631, 0x5d6c, [0xb1,0xb4,0xbd,0x2e,0x1a,0x74,0x1a,0x9b]); +static immutable IID_AsyncCompleted_GattCharacteristicsResult = GUID(0xd6a15475, 0x1e72, 0x5c56, [0x98,0xe8,0x88,0xf4,0xbc,0x3e,0x03,0x13]); +static immutable IID_AsyncCompleted_GattReadResult = GUID(0xd8992aa0, 0xeac2, 0x55b7, [0x92,0xc5,0x89,0x48,0x86,0xbe,0xb0,0xca]); +static immutable IID_AsyncCompleted_GattCommunicationStatus = GUID(0x2154117a, 0x978d, 0x59db, [0x99,0xcf,0x6b,0x69,0x0c,0xb3,0x38,0x9b]); + + +// --- COM interfaces --- + +extern(Windows): + +interface IUnknown +{ +nothrow @nogc: + HRESULT QueryInterface(const(GUID)* riid, void** ppv); + ULONG AddRef(); + ULONG Release(); +} + +interface IInspectable : IUnknown +{ +nothrow @nogc: + HRESULT GetIids(uint* count, GUID** iids); + HRESULT GetRuntimeClassName(HSTRING* name); + HRESULT GetTrustLevel(int* level); +} + +interface IAsyncInfo : IInspectable +{ +nothrow @nogc: + HRESULT get_Id(uint* id); + HRESULT get_Status(AsyncStatus* status); + HRESULT get_ErrorCode(HRESULT* code); + HRESULT Cancel(); + HRESULT Close(); +} + +interface IAsyncOperation_BluetoothLEDevice : IInspectable +{ +nothrow @nogc: + HRESULT put_Completed(IUnknown handler); + HRESULT get_Completed(IUnknown* handler); + HRESULT GetResults(IBluetoothLEDevice* result); +} + +interface IAsyncOperation_GattDeviceServicesResult : IInspectable +{ +nothrow @nogc: + HRESULT put_Completed(IUnknown handler); + HRESULT get_Completed(IUnknown* handler); + HRESULT GetResults(IGattDeviceServicesResult* result); +} + +interface IAsyncOperation_GattCharacteristicsResult : IInspectable +{ +nothrow @nogc: + HRESULT put_Completed(IUnknown handler); + HRESULT get_Completed(IUnknown* handler); + HRESULT GetResults(IGattCharacteristicsResult* result); +} + +interface IAsyncOperation_GattReadResult : IInspectable +{ +nothrow @nogc: + HRESULT put_Completed(IUnknown handler); + HRESULT get_Completed(IUnknown* handler); + HRESULT GetResults(IGattReadResult* result); +} + +interface IAsyncOperation_GattCommunicationStatus : IInspectable +{ +nothrow @nogc: + HRESULT put_Completed(IUnknown handler); + HRESULT get_Completed(IUnknown* handler); + HRESULT GetResults(GattCommunicationStatus* result); +} + +interface IBluetoothLEAdvertisementWatcher : IInspectable +{ +nothrow @nogc: + HRESULT get_MinSamplingInterval(long* value); + HRESULT get_MaxSamplingInterval(long* value); + HRESULT get_MinOutOfRangeTimeout(long* value); + HRESULT get_MaxOutOfRangeTimeout(long* value); + HRESULT get_Status(int* value); + HRESULT get_ScanningMode(BluetoothLEScanningMode* value); + HRESULT put_ScanningMode(BluetoothLEScanningMode value); + HRESULT get_SignalStrengthFilter(IInspectable* value); + HRESULT put_SignalStrengthFilter(IInspectable value); + HRESULT get_AdvertisementFilter(IInspectable* value); + HRESULT put_AdvertisementFilter(IInspectable value); + HRESULT Start(); + HRESULT Stop(); + HRESULT add_Received(IUnknown handler, EventRegistrationToken* token); + HRESULT remove_Received(EventRegistrationToken token); + HRESULT add_Stopped(IUnknown handler, EventRegistrationToken* token); + HRESULT remove_Stopped(EventRegistrationToken token); +} + +interface IBluetoothLEAdvertisementReceivedEventArgs : IInspectable +{ +nothrow @nogc: + HRESULT get_RawSignalStrengthInDBm(short* value); + HRESULT get_BluetoothAddress(ulong* value); + HRESULT get_AdvertisementType(int* value); + HRESULT get_Timestamp(long* value); + HRESULT get_Advertisement(IBluetoothLEAdvertisement* value); +} + +interface IBluetoothLEAdvertisementReceivedEventArgs2 : IInspectable +{ +nothrow @nogc: + HRESULT get_BluetoothAddressType(int* value); + HRESULT get_TransmitPowerLevelInDBm(IInspectable* value); + HRESULT get_IsAnonymous(BOOL* value); + HRESULT get_IsConnectable(BOOL* value); + HRESULT get_IsScannable(BOOL* value); + HRESULT get_IsDirected(BOOL* value); + HRESULT get_IsScanResponse(BOOL* value); +} + +interface IBluetoothLEAdvertisement : IInspectable +{ +nothrow @nogc: + HRESULT get_Flags(IInspectable* value); + HRESULT put_Flags(IInspectable value); + HRESULT get_LocalName(HSTRING* value); + HRESULT put_LocalName(HSTRING value); + HRESULT get_ServiceUuids(IInspectable* value); + HRESULT get_ManufacturerData(IInspectable* value); + HRESULT get_DataSections(IInspectable* value); + HRESULT GetManufacturerDataByCompanyId(ushort companyId, IInspectable* dataList); + HRESULT GetSectionsByType(ubyte type_, IInspectable* sectionList); +} + +interface IVectorView_IInspectable : IInspectable +{ +nothrow @nogc: + HRESULT GetAt(uint index, IInspectable* item); + HRESULT get_Size(uint* size); + HRESULT IndexOf(IInspectable value, uint* index, BOOL* found); + HRESULT GetMany(uint startIndex, uint capacity, IInspectable* items, uint* actual); +} + +interface IBuffer : IInspectable +{ +nothrow @nogc: + HRESULT get_Capacity(uint* value); + HRESULT get_Length(uint* value); + HRESULT put_Length(uint value); +} + +interface IBufferByteAccess : IUnknown +{ +nothrow @nogc: + HRESULT Buffer(ubyte** value); +} + +interface IGattDeviceServicesResult : IInspectable +{ +nothrow @nogc: + HRESULT get_Status(GattCommunicationStatus* value); + HRESULT get_ProtocolError(IInspectable* value); + HRESULT get_Services(IInspectable* value); +} + +interface IGattDeviceService : IInspectable +{ +nothrow @nogc: + HRESULT GetCharacteristics(GUID characteristicUuid, IInspectable* value); + HRESULT GetIncludedServices(GUID serviceUuid, IInspectable* value); + HRESULT get_DeviceId(HSTRING* value); + HRESULT get_Uuid(GUID* value); + HRESULT get_AttributeHandle(ushort* value); +} + +interface IGattDeviceService3 : IInspectable +{ +nothrow @nogc: + HRESULT get_DeviceAccessInformation(IInspectable* value); + HRESULT get_Session(IInspectable* value); + HRESULT get_SharingMode(int* value); + HRESULT RequestAccessAsync(IInspectable* operation); + HRESULT OpenAsync(int sharingMode, IInspectable* operation); + HRESULT GetCharacteristicsAsync(IInspectable* operation); + HRESULT GetCharacteristicsWithCacheModeAsync(int cacheMode, IInspectable* operation); + HRESULT GetCharacteristicsForUuidAsync(GUID uuid, IInspectable* operation); + HRESULT GetCharacteristicsForUuidWithCacheModeAsync(GUID uuid, int cacheMode, IInspectable* operation); + HRESULT GetIncludedServicesAsync(IInspectable* operation); + HRESULT GetIncludedServicesWithCacheModeAsync(int cacheMode, IInspectable* operation); +} + +interface IGattCharacteristicsResult : IInspectable +{ +nothrow @nogc: + HRESULT get_Status(GattCommunicationStatus* value); + HRESULT get_ProtocolError(IInspectable* value); + HRESULT get_Characteristics(IInspectable* value); +} + +interface IGattCharacteristic : IInspectable +{ +nothrow @nogc: + HRESULT GetDescriptors(GUID descriptorUuid, IInspectable* value); + HRESULT get_CharacteristicProperties(GattCharacteristicProperties* value); + HRESULT get_ProtectionLevel(int* value); + HRESULT put_ProtectionLevel(int value); + HRESULT get_UserDescription(HSTRING* value); + HRESULT get_Uuid(GUID* value); + HRESULT get_AttributeHandle(ushort* value); + HRESULT get_PresentationFormats(IInspectable* value); + HRESULT ReadValueAsync(IInspectable* operation); + HRESULT ReadValueWithCacheModeAsync(int cacheMode, IInspectable* operation); + HRESULT WriteValueAsync(IBuffer value, IInspectable* operation); + HRESULT WriteValueWithOptionAsync(IBuffer value, int writeOption, IInspectable* operation); + HRESULT ReadClientCharacteristicConfigurationDescriptorAsync(IInspectable* operation); + HRESULT WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue value, IInspectable* operation); + HRESULT add_ValueChanged(IUnknown handler, EventRegistrationToken* token); + HRESULT remove_ValueChanged(EventRegistrationToken token); +} + +interface IGattReadResult : IInspectable +{ +nothrow @nogc: + HRESULT get_Status(GattCommunicationStatus* value); + HRESULT get_Value(IBuffer* value); +} + +interface IGattValueChangedEventArgs : IInspectable +{ +nothrow @nogc: + HRESULT get_CharacteristicValue(IBuffer* value); + HRESULT get_Timestamp(long* value); +} + +interface IBluetoothLEAdvertisementPublisher : IInspectable +{ +nothrow @nogc: + HRESULT get_Status(int* value); + HRESULT get_Advertisement(IBluetoothLEAdvertisement* value); + HRESULT Start(); + HRESULT Stop(); + HRESULT add_StatusChanged(IUnknown handler, EventRegistrationToken* token); + HRESULT remove_StatusChanged(EventRegistrationToken token); +} + +interface IBluetoothLEDeviceStatics : IInspectable +{ +nothrow @nogc: + HRESULT FromIdAsync(HSTRING deviceId, IInspectable* operation); + HRESULT FromBluetoothAddressAsync(ulong bluetoothAddress, IInspectable* operation); + HRESULT GetDeviceSelector(HSTRING* selector); +} + +interface IBluetoothLEDevice : IInspectable +{ +nothrow @nogc: + HRESULT get_DeviceId(HSTRING* value); + HRESULT get_Name(HSTRING* value); + HRESULT get_GattServices(IInspectable* value); + HRESULT get_ConnectionStatus(int* value); + HRESULT get_BluetoothAddress(ulong* value); + HRESULT GetGattService(GUID serviceUuid, IInspectable* service); + HRESULT add_NameChanged(IUnknown handler, EventRegistrationToken* token); + HRESULT remove_NameChanged(EventRegistrationToken token); + HRESULT add_GattServicesChanged(IUnknown handler, EventRegistrationToken* token); + HRESULT remove_GattServicesChanged(EventRegistrationToken token); + HRESULT add_ConnectionStatusChanged(IUnknown handler, EventRegistrationToken* token); + HRESULT remove_ConnectionStatusChanged(EventRegistrationToken token); +} + +interface IBluetoothLEDevice3 : IInspectable +{ +nothrow @nogc: + HRESULT get_DeviceAccessInformation(IInspectable* value); + HRESULT RequestAccessAsync(IInspectable* operation); + HRESULT GetGattServicesAsync(IInspectable* operation); + HRESULT GetGattServicesWithCacheModeAsync(int cacheMode, IInspectable* operation); + HRESULT GetGattServicesForUuidAsync(GUID serviceUuid, IInspectable* operation); + HRESULT GetGattServicesForUuidWithCacheModeAsync(GUID serviceUuid, int cacheMode, IInspectable* operation); +} + +// Handler interfaces +interface IAsyncCompletedHandler : IUnknown { nothrow @nogc: HRESULT Invoke(IInspectable asyncInfo, AsyncStatus status); } +interface IAdvertisementReceivedHandler : IUnknown { nothrow @nogc: HRESULT Invoke(IInspectable sender, IInspectable args); } +interface IGattValueChangedHandler : IUnknown { nothrow @nogc: HRESULT Invoke(IInspectable sender, IInspectable args); } +interface IConnectionStatusHandler : IUnknown { nothrow @nogc: HRESULT Invoke(IInspectable sender, IInspectable args); } +interface IWatcherStoppedHandler : IUnknown { nothrow @nogc: HRESULT Invoke(IInspectable sender, IInspectable args); } + + +// ==================================================================== +// COM implementation classes +// ==================================================================== + +class ComObject : IInspectable +{ +nothrow @nogc: + protected shared uint _ref_count = 1; + + HRESULT QueryInterface(const(GUID)* riid, void** ppv) + { + if (*riid == IID_IUnknown || *riid == IID_IInspectable || *riid == IID_IAgileObject) + { + *ppv = cast(void*)cast(IUnknown)this; + AddRef(); + return 0; + } + *ppv = null; + return 0x80004002; // E_NOINTERFACE + } + + ULONG AddRef() { return atomicFetchAdd(_ref_count, 1) + 1; } + ULONG Release() + { + auto prev = atomicFetchSub(_ref_count, 1); + if (prev == 1) + { + defaultAllocator().freeT(this); + return 0; + } + return prev - 1; + } + + HRESULT GetIids(uint* count, GUID** iids) { *count = 0; *iids = null; return 0; } + HRESULT GetRuntimeClassName(HSTRING* name) { *name = null; return 0; } + HRESULT GetTrustLevel(int* level) { *level = 0; return 0; } +} + + +class MemoryBuffer : ComObject, IBuffer, IBufferByteAccess +{ +nothrow @nogc: + private ubyte* _data; + private uint _length; + private uint _capacity; + + void set(const(ubyte)[] data) + { + _data = cast(ubyte*)data.ptr; + _length = cast(uint)data.length; + _capacity = cast(uint)data.length; + } + + override ULONG Release() + { + auto prev = atomicFetchSub(_ref_count, 1); + if (prev == 1) + { + if (_data !is null) + defaultAllocator().free(_data[0 .. _capacity]); + defaultAllocator().freeT(this); + return 0; + } + return prev - 1; + } + + override HRESULT QueryInterface(const(GUID)* riid, void** ppv) + { + if (*riid == IID_IBufferByteAccess) + { + *ppv = cast(void*)cast(IBufferByteAccess)this; + AddRef(); + return 0; + } + return super.QueryInterface(riid, ppv); + } + + HRESULT get_Capacity(uint* value) { *value = _capacity; return 0; } + HRESULT get_Length(uint* value) { *value = _length; return 0; } + HRESULT put_Length(uint value) { _length = value; return 0; } + HRESULT Buffer(ubyte** value) { *value = _data; return 0; } +} + + +class AdvertisementReceivedHandler : ComObject, IAdvertisementReceivedHandler +{ +nothrow @nogc: + extern(D) void function(ubyte[6] addr, byte rssi, bool connectable, bool is_scan_response, const(ubyte)[] ad_payload) nothrow @nogc callback; + + override HRESULT QueryInterface(const(GUID)* riid, void** ppv) + { + if (*riid == IID_TypedEventHandler_Watcher_Received) + { + *ppv = cast(void*)cast(IUnknown)this; + AddRef(); + return 0; + } + return super.QueryInterface(riid, ppv); + } + + HRESULT Invoke(IInspectable sender, IInspectable args_raw) + { + if (!callback) + return 0; + + auto args = qi!IBluetoothLEAdvertisementReceivedEventArgs(args_raw, &IID_IBluetoothLEAdvertisementReceivedEventArgs); + if (args is null) + return 0; + scope(exit) args.Release(); + + ulong addr; + short rssi; + IBluetoothLEAdvertisement adv; + args.get_BluetoothAddress(&addr); + args.get_RawSignalStrengthInDBm(&rssi); + args.get_Advertisement(&adv); + + bool connectable = false; + bool is_scan_response = false; + auto args2 = qi!IBluetoothLEAdvertisementReceivedEventArgs2(args_raw, &IID_IBluetoothLEAdvertisementReceivedEventArgs2); + if (args2 !is null) + { + BOOL conn, scan_rsp; + args2.get_IsConnectable(&conn); + args2.get_IsScanResponse(&scan_rsp); + connectable = conn != 0; + is_scan_response = scan_rsp != 0; + args2.Release(); + } + + ubyte[6] mac; + ble_addr_to_mac(addr, mac); + + // serialize AD sections to raw bytes + ubyte[62] payload = void; + uint payload_len = serialize_adv(adv, payload[]); + if (adv !is null) + adv.Release(); + + callback(mac, cast(byte)rssi, connectable, is_scan_response, payload[0 .. payload_len]); + return 0; + } +} + + +class ConnectionStatusHandler : ComObject, IConnectionStatusHandler +{ +nothrow @nogc: + extern(D) void function(ubyte conn_id, int status) nothrow @nogc callback; + ubyte conn_id; + + override HRESULT QueryInterface(const(GUID)* riid, void** ppv) + { + if (*riid == IID_TypedEventHandler_Device_ConnectionStatus) + { + *ppv = cast(void*)cast(IUnknown)this; + AddRef(); + return 0; + } + return super.QueryInterface(riid, ppv); + } + + HRESULT Invoke(IInspectable sender, IInspectable args) + { + if (!callback) + return 0; + + // query connection status from sender (IBluetoothLEDevice) + auto dev = qi!IBluetoothLEDevice(sender, &IID_IBluetoothLEDevice); + if (dev !is null) + { + int conn_status; + dev.get_ConnectionStatus(&conn_status); + dev.Release(); + callback(conn_id, conn_status); + } + return 0; + } +} + + +class GattValueChangedHandler : ComObject, IGattValueChangedHandler +{ +nothrow @nogc: + extern(D) void function(ubyte conn_id, ushort attr_handle, const(ubyte)[] data) nothrow @nogc callback; + ubyte conn_id; + ushort attr_handle; + + override HRESULT QueryInterface(const(GUID)* riid, void** ppv) + { + if (*riid == IID_TypedEventHandler_Gatt_ValueChanged) + { + *ppv = cast(void*)cast(IUnknown)this; + AddRef(); + return 0; + } + return super.QueryInterface(riid, ppv); + } + + HRESULT Invoke(IInspectable sender, IInspectable args_raw) + { + if (!callback) + return 0; + + auto args = cast(IGattValueChangedEventArgs)cast(void*)args_raw; + if (args is null) + return 0; + + IBuffer value_buf; + args.get_CharacteristicValue(&value_buf); + const(ubyte)[] data = get_buffer_bytes(value_buf); + + callback(conn_id, attr_handle, data); + + if (value_buf !is null) + value_buf.Release(); + return 0; + } +} + + +class WatcherStoppedHandler : ComObject, IWatcherStoppedHandler +{ +nothrow @nogc: + shared(uint)* flag; + + override HRESULT QueryInterface(const(GUID)* riid, void** ppv) + { + if (*riid == IID_TypedEventHandler_Watcher_Stopped) + { + *ppv = cast(void*)cast(IUnknown)this; + AddRef(); + return 0; + } + return super.QueryInterface(riid, ppv); + } + + HRESULT Invoke(IInspectable sender, IInspectable args) + { + if (flag !is null) + atomicStore(*flag, 1u); + signal_wake(); + return 0; + } +} + + +class AsyncCompletedHandler : ComObject, IAsyncCompletedHandler +{ +nothrow @nogc: + override HRESULT QueryInterface(const(GUID)* riid, void** ppv) + { + if (*riid == IID_AsyncCompleted_BluetoothLEDevice || + *riid == IID_AsyncCompleted_GattDeviceServicesResult || + *riid == IID_AsyncCompleted_GattCharacteristicsResult || + *riid == IID_AsyncCompleted_GattReadResult || + *riid == IID_AsyncCompleted_GattCommunicationStatus) + { + *ppv = cast(void*)cast(IAsyncCompletedHandler)this; + AddRef(); + return 0; + } + return super.QueryInterface(riid, ppv); + } + + HRESULT Invoke(IInspectable asyncInfo, AsyncStatus status) + { + signal_wake(); + return 0; + } +} + + +// serialize WinRT advertisement to raw AD bytes [len][type][data]... +uint serialize_adv(IBluetoothLEAdvertisement adv, ubyte[] buf) +{ + if (adv is null) + return 0; + + uint offset = 0; + + // local name + HSTRING hname; + adv.get_LocalName(&hname); + if (hname !is null) + { + uint len; + const(wchar)* raw = g_winrt.WindowsGetStringRawBuffer(hname, &len); + if (raw && len > 0) + { + uint copy_len = len < 64 ? len : 64; + ubyte name_len = cast(ubyte)(copy_len + 1); + if (offset + 1 + name_len <= buf.length) + { + buf[offset++] = name_len; + buf[offset++] = 0x09; // complete local name + foreach (i; 0 .. copy_len) + buf[offset++] = cast(ubyte)raw[i]; + } + } + g_winrt.WindowsDeleteString(hname); + } + + // AD data sections + IInspectable sections_raw; + adv.get_DataSections(§ions_raw); + if (sections_raw !is null) + { + auto sections = cast(IVectorView_IInspectable)cast(void*)sections_raw; + uint count; + sections.get_Size(&count); + + foreach (i; 0 .. count) + { + IInspectable item; + sections.GetAt(i, &item); + if (item is null) + continue; + + auto section = cast(IBluetoothLEAdvertisementDataSection)cast(void*)item; + ubyte dt; + section.get_DataType(&dt); + + IBuffer dbuf; + section.get_Data(&dbuf); + const(ubyte)[] data = get_buffer_bytes(dbuf); + + if (data.length > 0) + { + ubyte sec_len = cast(ubyte)(data.length + 1); + if (offset + 1 + sec_len <= buf.length) + { + buf[offset++] = sec_len; + buf[offset++] = dt; + buf[offset .. offset + data.length] = cast(const(ubyte)[])data[]; + offset += cast(uint)data.length; + } + } + + if (dbuf !is null) + dbuf.Release(); + item.Release(); + } + sections_raw.Release(); + } + + return offset; +} + +interface IBluetoothLEAdvertisementDataSection : IInspectable +{ +nothrow @nogc: + HRESULT get_DataType(ubyte* value); + HRESULT put_DataType(ubyte value); + HRESULT get_Data(IBuffer* value); + HRESULT put_Data(IBuffer value); +} diff --git a/src/urt/driver/windows/exception.d b/src/urt/driver/windows/exception.d new file mode 100644 index 0000000..68b25d2 --- /dev/null +++ b/src/urt/driver/windows/exception.d @@ -0,0 +1,1590 @@ +/// Windows exception driver. +/// +/// Three compiler/arch flavours of EH runtime coexist, selected by inner +/// version blocks: +/// version (LDC) - MSVC C++ SEH (RaiseException + table-based unwind) +/// version (Win32) - DMD SEH (_d_framehandler chain walk) +/// version (Win64) - DMD DEH (RBP-chain + ._deh section tables) +/// +/// Stack-trace capture / symbol resolution uses DbgHelp (debug-only). +/// Ported from druntime. +module urt.driver.windows.exception; + +version (Windows): + +import urt.internal.exception : ClassInfo, Resolved, _d_isbaseof, _d_createTrace, terminate; + +nothrow @nogc: + + +// ====================================================================== +// Stack trace support (DbgHelp, debug only) +// ====================================================================== +// +// =================================================================== +// !!! TODO !!! THREADING IS NOT SUPPORTED. +// +// DbgHelp is NOT thread-safe. All calls to SymFromAddr, +// SymGetLineFromAddr64, SymInitialize, and StackWalk64 must be +// serialized with a CRITICAL_SECTION (or equivalent) before this +// program can use threads. The static scratch buffer inside +// _resolve_address is also shared across callers - replace with +// per-thread storage or a mutex when threading lands. +// =================================================================== + +// --- DbgHelp types --------------------------------------------------- + +private struct SYMBOL_INFOA +{ + uint SizeOfStruct; + uint TypeIndex; + ulong[2] Reserved; + uint Index; + uint Size; + ulong ModBase; + uint Flags; + ulong Value; + ulong Address; + uint Register; + uint Scope; + uint Tag; + uint NameLen; + uint MaxNameLen; + char[1] Name; // variable-length +} + +private struct IMAGEHLP_LINEA64 +{ + uint SizeOfStruct; + void* Key; + uint LineNumber; + const(char)* FileName; + ulong Address; +} + +// --- StackWalk64 types ----------------------------------------------- + +private alias HANDLE = void*; +private enum AddrModeFlat = 3; + +private struct ADDRESS64 +{ + ulong Offset; + ushort Segment; + uint Mode; +} + +private struct STACKFRAME64 +{ + ADDRESS64 AddrPC; + ADDRESS64 AddrReturn; + ADDRESS64 AddrFrame; + ADDRESS64 AddrStack; + ADDRESS64 AddrBStore; + void* FuncTableEntry; + ulong[4] Params; + int Far; + int Virtual; + ulong[3] Reserved; + ubyte[96] KdHelp; // KDHELP64, opaque +} + +// CONTEXT - opaque aligned buffer, accessed via offset constants. +version (Win64) +{ + private enum CONTEXT_SIZE = 1232; + private enum CTX_FLAGS_OFF = 48; + private enum CTX_IP_OFF = 248; // Rip + private enum CTX_SP_OFF = 152; // Rsp + private enum CTX_FP_OFF = 160; // Rbp + private enum CTX_FULL = 0x10000B; + private enum MACHINE_TYPE = 0x8664; // IMAGE_FILE_MACHINE_AMD64 +} +else +{ + private enum CONTEXT_SIZE = 716; + private enum CTX_FLAGS_OFF = 0; + private enum CTX_IP_OFF = 184; // Eip + private enum CTX_SP_OFF = 196; // Esp + private enum CTX_FP_OFF = 180; // Ebp + private enum CTX_FULL = 0x10007; + private enum MACHINE_TYPE = 0x014C; // IMAGE_FILE_MACHINE_I386 +} + +// --- Function pointer types ------------------------------------------ + +extern(Windows) nothrow @nogc +{ + private alias SymInitializeFn = int function(HANDLE, const(char)*, int); + private alias SymSetOptionsFn = uint function(uint); + private alias SymFromAddrFn = int function(HANDLE, ulong, ulong*, SYMBOL_INFOA*); + private alias SymGetLineFromAddr64Fn = int function(HANDLE, ulong, uint*, IMAGEHLP_LINEA64*); + private alias FuncTableAccessFn = void* function(HANDLE, ulong); + private alias GetModuleBaseFn = ulong function(HANDLE, ulong); + private alias StackWalk64Fn = int function( + uint machineType, HANDLE hProcess, HANDLE hThread, + STACKFRAME64* stackFrame, void* contextRecord, + void* readMemory, FuncTableAccessFn funcTableAccess, + GetModuleBaseFn getModuleBase, void* translateAddress); +} + +// --- Globals --------------------------------------------------------- + +private __gshared bool _dbg_inited; +private __gshared bool _dbg_available; +private __gshared HANDLE _dbg_process; +private __gshared SymFromAddrFn _sym_from_addr; +private __gshared SymGetLineFromAddr64Fn _sym_get_line; +private __gshared StackWalk64Fn _stack_walk64; +private __gshared FuncTableAccessFn _func_table_access64; +private __gshared GetModuleBaseFn _get_module_base64; + +// --- Initialization -------------------------------------------------- + +private void dbghelp_init() @trusted +{ + if (_dbg_inited) + return; + _dbg_inited = true; + + auto hDbg = loadLibraryA("dbghelp.dll"); + if (hDbg is null) + return; + + auto sym_init = cast(SymInitializeFn) getProcAddress(hDbg, "SymInitialize"); + auto sym_set_opt = cast(SymSetOptionsFn) getProcAddress(hDbg, "SymSetOptions"); + _sym_from_addr = cast(SymFromAddrFn) getProcAddress(hDbg, "SymFromAddr"); + _sym_get_line = cast(SymGetLineFromAddr64Fn) getProcAddress(hDbg, "SymGetLineFromAddr64"); + _stack_walk64 = cast(StackWalk64Fn) getProcAddress(hDbg, "StackWalk64"); + _func_table_access64 = cast(FuncTableAccessFn) getProcAddress(hDbg, "SymFunctionTableAccess64"); + _get_module_base64 = cast(GetModuleBaseFn) getProcAddress(hDbg, "SymGetModuleBase64"); + + if (sym_init is null || sym_set_opt is null || _sym_from_addr is null) + return; + + // SYMOPT_DEFERRED_LOAD | SYMOPT_LOAD_LINES + sym_set_opt(0x00000004 | 0x00000010); + + _dbg_process = cast(HANDLE) cast(size_t)-1; // GetCurrentProcess() pseudo-handle + if (!sym_init(_dbg_process, null, 1)) // fInvadeProcess = TRUE + return; + + _dbg_available = true; +} + +// --- Kernel32/ntdll imports ------------------------------------------ + +pragma(mangle, "LoadLibraryA") +extern(Windows) private void* loadLibraryA(const(char)*); + +pragma(mangle, "GetProcAddress") +extern(Windows) private void* getProcAddress(void*, const(char)*); + +pragma(mangle, "RtlCaptureStackBackTrace") +extern(Windows) private ushort rtlCaptureStackBackTrace( + uint FramesToSkip, uint FramesToCapture, void** BackTrace, uint* BackTraceHash); + +pragma(mangle, "RtlCaptureContext") +extern(Windows) private void rtlCaptureContext(void* contextRecord); + +pragma(mangle, "GetCurrentThread") +extern(Windows) private HANDLE getCurrentThread(); + +// --- StackWalk64 fallback -------------------------------------------- + +private size_t stack_walk64_capture(ref void*[32] addrs) @trusted +{ + dbghelp_init(); + + if (_stack_walk64 is null || _func_table_access64 is null || _get_module_base64 is null) + return 0; + + align(16) ubyte[CONTEXT_SIZE] ctx = 0; + *cast(uint*)(ctx.ptr + CTX_FLAGS_OFF) = CTX_FULL; + rtlCaptureContext(ctx.ptr); + + STACKFRAME64 sf; + version (Win64) + { + sf.AddrPC.Offset = *cast(ulong*)(ctx.ptr + CTX_IP_OFF); + sf.AddrFrame.Offset = *cast(ulong*)(ctx.ptr + CTX_FP_OFF); + sf.AddrStack.Offset = *cast(ulong*)(ctx.ptr + CTX_SP_OFF); + } + else + { + sf.AddrPC.Offset = *cast(uint*)(ctx.ptr + CTX_IP_OFF); + sf.AddrFrame.Offset = *cast(uint*)(ctx.ptr + CTX_FP_OFF); + sf.AddrStack.Offset = *cast(uint*)(ctx.ptr + CTX_SP_OFF); + } + sf.AddrPC.Mode = AddrModeFlat; + sf.AddrFrame.Mode = AddrModeFlat; + sf.AddrStack.Mode = AddrModeFlat; + + auto hThread = getCurrentThread(); + size_t n = 0; + + // Skip internal frames (_d_createTrace + stack_walk64_capture + RtlCaptureContext) + uint skip = 3; + + while (n < 32) + { + if (!_stack_walk64(MACHINE_TYPE, _dbg_process, hThread, + &sf, ctx.ptr, null, _func_table_access64, _get_module_base64, null)) + break; + if (sf.AddrPC.Offset == 0) + break; + if (skip > 0) + { + --skip; + continue; + } + addrs[n++] = cast(void*) cast(size_t) sf.AddrPC.Offset; + } + return n; +} + + +// --- Driver interface ------------------------------------------------- +// +// All three primitives assume they are called through a one-level public +// wrapper in urt.internal.exception (kept non-inlined via pragma(inline, +// false)). That wrapper's frame is accounted for in the skip counts +// below. Direct callers (like _d_createTrace) get the same semantics +// because their frame substitutes for the missing wrapper. + +/// Capture the caller's call stack. First entry = return address of the +/// function that called the public `capture_trace` wrapper. +size_t _capture_trace(void*[] addrs) @trusted +{ + if (addrs.length == 0) + return 0; + auto count = cast(uint) addrs.length; + // +2: skip _capture_trace itself + the public wrapper. addrs[0] + // is then the PC inside USER (where USER called capture_trace). + auto n = rtlCaptureStackBackTrace(2, count, addrs.ptr, null); + if (n == 0 && addrs.length >= 32) + { + void*[32] scratch = void; + auto k = stack_walk64_capture(scratch); + auto copy = k < addrs.length ? k : addrs.length; + addrs[0 .. copy] = scratch[0 .. copy]; + n = cast(ushort) copy; + } + return n; +} + +/// Return the return address of the `skip`-th frame above the public +/// `caller_address` wrapper's caller. `skip=0` is the call site of +/// that caller - useful from inside an allocator to find the alloc +/// site. +void* _caller_address(uint skip) @trusted +{ + void* addr; + // +3: skip _caller_address itself + public wrapper + USER's own + // frame. With skip=0 the returned PC is in USER's caller - the + // semantic the doc promises ("call site of the caller", useful for + // allocation-site tracking). + if (rtlCaptureStackBackTrace(skip + 3, 1, &addr, null) == 0) + return null; + return addr; +} + +/// Resolve addr to symbol + optional file + line via DbgHelp. +/// Returned slices are owned by a static buffer - copy if you need +/// them across another call. +bool _resolve_address(void* addr, out Resolved r) @trusted +{ + import urt.mem : strlen; + + dbghelp_init(); + if (!_dbg_available) + return false; + + static align(8) ubyte[SYMBOL_INFOA.sizeof + 256] sym_buf; + sym_buf[] = 0; + auto p_sym = cast(SYMBOL_INFOA*) sym_buf.ptr; + p_sym.SizeOfStruct = SYMBOL_INFOA.sizeof; + p_sym.MaxNameLen = 256; + + ulong disp; + if (!_sym_from_addr(_dbg_process, cast(ulong) addr, &disp, p_sym)) + return false; + r.name = p_sym.Name.ptr[0 .. strlen(p_sym.Name.ptr)]; + r.offset = cast(size_t) disp; + + uint disp32; + IMAGEHLP_LINEA64 line_info; + line_info.SizeOfStruct = IMAGEHLP_LINEA64.sizeof; + if (_sym_get_line !is null && + _sym_get_line(_dbg_process, cast(ulong) addr, &disp32, &line_info)) + { + r.file = line_info.FileName[0 .. strlen(line_info.FileName)]; + r.line = line_info.LineNumber; + } + return true; +} + +/// Resolve many addresses. DbgHelp has no batch primitive - loop. +/// Returns false if DbgHelp is unavailable; otherwise true (individual +/// failed entries stay `Resolved.init` thanks to `out` auto-zeroing). +bool _resolve_batch(const(void*)[] addrs, Resolved[] results) @trusted +{ + dbghelp_init(); + if (!_dbg_available) + return false; + foreach (i, a; addrs) + _resolve_address(cast(void*) a, results[i]); + return true; +} + +// ====================================================================== +// Exception-handling runtime (compiler-specific) +// ====================================================================== + +version (GDC) +{ + static assert(false, "GDC exception runtime not ported"); +} +else version (LDC) +{ + +// ---------------------------------------------------------------------- +// LDC MSVC SEH exception handling +// ---------------------------------------------------------------------- + + +// --- Windows ABI types --------------------------------------------------- + +private alias DWORD = uint; +private alias ULONG_PTR = size_t; + +extern(Windows) void RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, ULONG_PTR* lpArguments); + +// --- MSVC SEH structures ------------------------------------------------- + +// On Win64, type info pointers are 32-bit offsets from a heap base. +version (Win64) + private struct ImgPtr(T) { uint offset; } +else + private alias ImgPtr(T) = T*; + +private alias PMFN = ImgPtr!(void function(void*)); + +private struct TypeDescriptor +{ + uint hash; + void* spare; + char[1] name; // variable-size, zero-terminated +} + +private struct PMD +{ + int mdisp; + int pdisp; + int vdisp; +} + +private struct CatchableType +{ + uint properties; + ImgPtr!TypeDescriptor pType; + PMD thisDisplacement; + int sizeOrOffset; + PMFN copyFunction; +} + +private enum CT_IsSimpleType = 0x00000001; + +private struct CatchableTypeArray +{ + int nCatchableTypes; + ImgPtr!CatchableType[1] arrayOfCatchableTypes; // variable size +} + +private struct _ThrowInfo +{ + uint attributes; + PMFN pmfnUnwind; + PMFN pForwardCompat; + ImgPtr!CatchableTypeArray pCatchableTypeArray; +} + +private struct CxxExceptionInfo +{ + size_t Magic; + Throwable* pThrowable; + _ThrowInfo* ThrowInfo; + version (Win64) void* ImgBase; +} + +private enum int STATUS_MSC_EXCEPTION = 0xe0000000 | ('m' << 16) | ('s' << 8) | ('c' << 0); +private enum EXCEPTION_NONCONTINUABLE = 0x01; +private enum EH_MAGIC_NUMBER1 = 0x19930520; + + +// --- EH Heap (image-relative pointer support) ---------------------------- + +version (Win64) +{ + private struct EHHeap + { + nothrow @nogc: + + void* base; + size_t capacity; + size_t length; + + void initialize(size_t initial_capacity) + { + import urt.mem : alloc; + base = alloc(initial_capacity).ptr; + capacity = initial_capacity; + length = size_t.sizeof; // offset 0 reserved (null sentinel) + } + + size_t alloc(size_t size) + { + import urt.mem : alloc, memcpy; + auto offset = length; + enum align_mask = size_t.sizeof - 1; + auto new_length = (length + size + align_mask) & ~align_mask; + auto new_capacity = capacity; + while (new_length > new_capacity) + new_capacity *= 2; + if (new_capacity != capacity) + { + auto new_base = alloc(new_capacity).ptr; + memcpy(new_base, base, length); + // Old base leaks - may be referenced by in-flight exceptions. + base = new_base; + capacity = new_capacity; + } + length = new_length; + return offset; + } + } + + private __gshared EHHeap _eh_heap; + + private ImgPtr!T eh_malloc(T)(size_t size = T.sizeof) + { + return ImgPtr!T(cast(uint) _eh_heap.alloc(size)); + } + + private T* to_pointer(T)(ImgPtr!T img_ptr) + { + return cast(T*)(cast(ubyte*) _eh_heap.base + img_ptr.offset); + } +} +else // Win32 +{ + private ImgPtr!T eh_malloc(T)(size_t size = T.sizeof) + { + import urt.mem : alloc; + return cast(T*)alloc(size).ptr; + } + + private T* to_pointer(T)(T* img_ptr) + { + return img_ptr; + } +} + + +// --- ThrowInfo cache (simple linear-scan arrays) ------------------------- +// No mutex - OpenWatt's exception paths are single-threaded. + +private enum EH_CACHE_SIZE = 64; + +private __gshared ClassInfo[EH_CACHE_SIZE] _throw_info_keys; +private __gshared ImgPtr!_ThrowInfo[EH_CACHE_SIZE] _throw_info_vals; +private __gshared size_t _throw_info_len; + +private __gshared ClassInfo[EH_CACHE_SIZE] _catchable_keys; +private __gshared ImgPtr!CatchableType[EH_CACHE_SIZE] _catchable_vals; +private __gshared size_t _catchable_len; + +private __gshared bool _eh_initialized; + +private void ensure_eh_init() +{ + if (_eh_initialized) + return; + version (Win64) + _eh_heap.initialize(0x10000); + _eh_initialized = true; +} + + +// --- ThrowInfo generation ------------------------------------------------ + +private ImgPtr!CatchableType get_catchable_type(ClassInfo ti) +{ + import urt.mem : memcpy; + + foreach (i; 0 .. _catchable_len) + if (_catchable_keys[i] is ti) + return _catchable_vals[i]; + + const sz = TypeDescriptor.sizeof + ti.name.length + 1; + auto td = eh_malloc!TypeDescriptor(sz); + auto ptd = td.to_pointer; + + ptd.hash = 0; + ptd.spare = null; + ptd.name.ptr[0] = 'D'; + memcpy(ptd.name.ptr + 1, ti.name.ptr, ti.name.length); + ptd.name.ptr[ti.name.length + 1] = 0; + + auto ct = eh_malloc!CatchableType(); + ct.to_pointer[0] = CatchableType( + CT_IsSimpleType, td, PMD(0, -1, 0), + cast(int) size_t.sizeof, PMFN.init); + + if (_catchable_len < EH_CACHE_SIZE) + { + _catchable_keys[_catchable_len] = ti; + _catchable_vals[_catchable_len] = ct; + ++_catchable_len; + } + return ct; +} + +private ImgPtr!_ThrowInfo get_throw_info(ClassInfo ti) +{ + foreach (i; 0 .. _throw_info_len) + if (_throw_info_keys[i] is ti) + return _throw_info_vals[i]; + + int classes = 0; + for (ClassInfo tic = ti; tic !is null; tic = tic.base) + ++classes; + + const arr_size = int.sizeof + classes * ImgPtr!(CatchableType).sizeof; + ImgPtr!CatchableTypeArray cta = eh_malloc!CatchableTypeArray(arr_size); + to_pointer(cta).nCatchableTypes = classes; + + size_t c = 0; + for (ClassInfo tic = ti; tic !is null; tic = tic.base) + cta.to_pointer.arrayOfCatchableTypes.ptr[c++] = get_catchable_type(tic); + + auto tinf = eh_malloc!_ThrowInfo(); + *(tinf.to_pointer) = _ThrowInfo(0, PMFN.init, PMFN.init, cta); + + if (_throw_info_len < EH_CACHE_SIZE) + { + _throw_info_keys[_throw_info_len] = ti; + _throw_info_vals[_throw_info_len] = tinf; + ++_throw_info_len; + } + return tinf; +} + + +// --- Exception stack (thread-local) -------------------------------------- + +private struct ExceptionStack +{ +nothrow @nogc: + + void push(Throwable e) + { + if (_length == _cap) + grow(); + _p[_length++] = e; + } + + Throwable pop() + { + return _p[--_length]; + } + + void shrink(size_t sz) + { + while (_length > sz) + _p[--_length] = null; + } + + ref inout(Throwable) opIndex(size_t idx) inout + { + return _p[idx]; + } + + size_t find(Throwable e) + { + for (size_t i = _length; i > 0;) + if (_p[--i] is e) + return i; + return ~cast(size_t) 0; + } + + @property size_t length() const { return _length; } + +private: + + void grow() + { + import urt.mem : alloc, free, memcpy; + immutable ncap = _cap ? 2 * _cap : 16; + auto p = cast(Throwable*)alloc(ncap * size_t.sizeof).ptr; + if (_length > 0) + memcpy(p, _p, _length * size_t.sizeof); + if (_p !is null) + free((cast(void*)_p)[0 .. _cap * size_t.sizeof]); + _p = p; + _cap = ncap; + } + + size_t _length; + Throwable* _p; + size_t _cap; +} + +private ExceptionStack _exception_stack; + + +// --- Exception chaining -------------------------------------------------- + +private Throwable chain_exceptions(Throwable e, Throwable t) +{ + if (!cast(Error) e) + if (auto err = cast(Error) t) + { + err.bypassedException = e; + return err; + } + return Throwable.chainTogether(e, t); +} + + +// --- Core SEH API -------------------------------------------------------- + +extern(C) void _d_throw_exception(Throwable throwable) +{ + if (throwable is null || typeid(throwable) is null) + { + terminate(); + assert(0); + } + + auto refcount = throwable.refcount(); + if (refcount) + throwable.refcount() = refcount + 1; + + ensure_eh_init(); + + _exception_stack.push(throwable); + _d_createTrace(throwable, null); + + CxxExceptionInfo info; + info.Magic = EH_MAGIC_NUMBER1; + info.pThrowable = &throwable; + info.ThrowInfo = get_throw_info(typeid(throwable)).to_pointer; + version (Win64) + info.ImgBase = _eh_heap.base; + + RaiseException(STATUS_MSC_EXCEPTION, EXCEPTION_NONCONTINUABLE, + info.sizeof / size_t.sizeof, cast(ULONG_PTR*) &info); +} + +extern(C) Throwable _d_eh_enter_catch(void* ptr, ClassInfo catch_type) +{ + if (ptr is null) + return null; + + auto e = *(cast(Throwable*) ptr); + size_t pos = _exception_stack.find(e); + if (pos >= _exception_stack.length()) + return null; // not a D exception + + auto caught = e; + + // Chain inner unhandled exceptions as collateral + for (size_t p = pos + 1; p < _exception_stack.length(); ++p) + e = chain_exceptions(e, _exception_stack[p]); + _exception_stack.shrink(pos); + + if (e !is caught) + { + if (_d_isbaseof(typeid(e), catch_type)) + *cast(Throwable*) ptr = e; + else + _d_throw_exception(e); // rethrow collateral + } + return e; +} + +extern(C) bool _d_enter_cleanup(void* ptr) @trusted +{ + // Prevents LLVM from optimizing away cleanup (finally) blocks. + return true; +} + +extern(C) void _d_leave_cleanup(void* ptr) @trusted +{ +} + +} // version (LDC) +else version (Win32) +{ + +// ---------------------------------------------------------------------- +// DMD Win32 SEH-based exception handling +// ---------------------------------------------------------------------- + + +// ---------------------------------------------------------------------- +// Win32 SEH-based exception handling +// ---------------------------------------------------------------------- + +// Windows types (inlined to avoid core.sys.windows dependency) +alias DWORD = uint; +alias BYTE = ubyte; +alias PVOID = void*; +alias ULONG_PTR = size_t; + +enum size_t EXCEPTION_MAXIMUM_PARAMETERS = 15; +enum DWORD EXCEPTION_NONCONTINUABLE = 1; +enum EXCEPTION_UNWIND = 6; +enum EXCEPTION_COLLATERAL = 0x100; + +enum DWORD STATUS_DIGITAL_MARS_D_EXCEPTION = (3 << 30) | (1 << 29) | (0 << 28) | ('D' << 16) | 1; + +struct EXCEPTION_RECORD +{ + DWORD ExceptionCode; + DWORD ExceptionFlags; + EXCEPTION_RECORD* ExceptionRecord; + PVOID ExceptionAddress; + DWORD NumberParameters; + ULONG_PTR[EXCEPTION_MAXIMUM_PARAMETERS] ExceptionInformation; +} + +enum MAXIMUM_SUPPORTED_EXTENSION = 512; + +struct FLOATING_SAVE_AREA +{ + DWORD ControlWord, StatusWord, TagWord; + DWORD ErrorOffset, ErrorSelector; + DWORD DataOffset, DataSelector; + BYTE[80] RegisterArea; + DWORD Cr0NpxState; +} + +struct CONTEXT +{ + DWORD ContextFlags; + DWORD Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; + FLOATING_SAVE_AREA FloatSave; + DWORD SegGs, SegFs, SegEs, SegDs; + DWORD Edi, Esi, Ebx, Edx, Ecx, Eax; + DWORD Ebp, Eip, SegCs, EFlags, Esp, SegSs; + BYTE[MAXIMUM_SUPPORTED_EXTENSION] ExtendedRegisters; +} + +struct EXCEPTION_POINTERS +{ + EXCEPTION_RECORD* ExceptionRecord; + CONTEXT* ContextRecord; +} + +enum EXCEPTION_DISPOSITION +{ + ExceptionContinueExecution, + ExceptionContinueSearch, + ExceptionNestedException, + ExceptionCollidedUnwind, +} + +alias LanguageSpecificHandler = extern(C) + EXCEPTION_DISPOSITION function( + EXCEPTION_RECORD* exceptionRecord, + DEstablisherFrame* frame, + CONTEXT* context, + void* dispatcherContext); + +extern(Windows) void RaiseException(DWORD, DWORD, DWORD, void*); +extern(Windows) void RtlUnwind(void* targetFrame, void* targetIp, EXCEPTION_RECORD* pExceptRec, void* valueForEAX); + +extern(C) extern __gshared DWORD _except_list; // FS:[0] + +// Data structures - compiler-generated exception handler tables (Win32) + +struct DEstablisherFrame +{ + DEstablisherFrame* prev; + LanguageSpecificHandler handler; + DWORD table_index; + DWORD ebp; +} + +struct DHandlerInfo +{ + int prev_index; + uint cioffset; // offset to DCatchInfo data from start of table + void* finally_code; // pointer to finally code (!=null if try-finally) +} + +struct DHandlerTable +{ + void* fptr; // pointer to start of function + uint espoffset; + uint retoffset; + DHandlerInfo[1] handler_info; +} + +struct DCatchBlock +{ + ClassInfo type; + uint bpoffset; // EBP offset of catch var + void* code; // catch handler code pointer +} + +struct DCatchInfo +{ + uint ncatches; + DCatchBlock[1] catch_block; +} + +// InFlight exception list (per-stack, swapped on fiber switches) + +EXCEPTION_RECORD* inflight_exception_list = null; + +extern(C) void* _d_eh_swapContext(void* newContext) +{ + auto old = inflight_exception_list; + inflight_exception_list = cast(EXCEPTION_RECORD*) newContext; + return old; +} + +private EXCEPTION_RECORD* skip_collateral_exceptions(EXCEPTION_RECORD* n) @trusted +{ + while (n.ExceptionRecord && n.ExceptionFlags & EXCEPTION_COLLATERAL) + n = n.ExceptionRecord; + return n; +} + +// SEH to D exception translation + +private Throwable _d_translate_se_to_d_exception(EXCEPTION_RECORD* exceptionRecord, CONTEXT*) @trusted +{ + if (exceptionRecord.ExceptionCode == STATUS_DIGITAL_MARS_D_EXCEPTION) + return cast(Throwable) cast(void*)(exceptionRecord.ExceptionInformation[0]); + + // Non-D (hardware) exceptions: cannot create Error objects without GC. + terminate(); + assert(0); +} + +// _d_throwc - throw a D exception via Windows SEH + +private void throw_impl(Throwable h) @trusted +{ + auto refcount = h.refcount(); + if (refcount) + h.refcount() = refcount + 1; + + _d_createTrace(h, null); + RaiseException(STATUS_DIGITAL_MARS_D_EXCEPTION, EXCEPTION_NONCONTINUABLE, 1, cast(void*)&h); +} + +extern(C) void _d_throwc(Throwable h) @trusted +{ + version (D_InlineAsm_X86) + asm @nogc nothrow + { + naked; + enter 0, 0; + mov EAX, [EBP + 8]; + call throw_impl; + leave; + ret; + } +} + +// _d_framehandler - SEH frame handler called by OS for each frame. +// The handler table address is passed in EAX by compiler-generated thunks. + +extern(C) EXCEPTION_DISPOSITION _d_framehandler( + EXCEPTION_RECORD* exceptionRecord, + DEstablisherFrame* frame, + CONTEXT* context, + void* dispatcherContext) @trusted +{ + DHandlerTable* handler_table; + asm @nogc nothrow { mov handler_table, EAX; } + + if (exceptionRecord.ExceptionFlags & EXCEPTION_UNWIND) + { + // Unwind phase: call all finally blocks in this frame + _d_local_unwind(handler_table, frame, -1, &unwindCollisionExceptionHandler); + } + else + { + // Search phase: look for a matching catch handler + + EXCEPTION_RECORD* master = null; + ClassInfo master_class_info = null; + + int prev_ndx; + for (auto ndx = frame.table_index; ndx != -1; ndx = prev_ndx) + { + auto phi = &handler_table.handler_info.ptr[ndx]; + prev_ndx = phi.prev_index; + + if (phi.cioffset) + { + auto pci = cast(DCatchInfo*)(cast(ubyte*) handler_table + phi.cioffset); + auto ncatches = pci.ncatches; + + foreach (i; 0 .. ncatches) + { + auto pcb = &pci.catch_block.ptr[i]; + + // Walk the collateral exception chain to find the master + EXCEPTION_RECORD* er = exceptionRecord; + master = null; + master_class_info = null; + + for (;;) + { + if (er.ExceptionCode == STATUS_DIGITAL_MARS_D_EXCEPTION) + { + ClassInfo ci = (**(cast(ClassInfo**)(er.ExceptionInformation[0]))); + if (!master && !(er.ExceptionFlags & EXCEPTION_COLLATERAL)) + { + master = er; + master_class_info = ci; + break; + } + if (_d_isbaseof(ci, typeid(Error))) + { + master = er; + master_class_info = ci; + } + } + else + { + // Non-D exception - cannot translate without GC + terminate(); + } + + if (!(er.ExceptionFlags & EXCEPTION_COLLATERAL)) + break; + + if (er.ExceptionRecord) + er = er.ExceptionRecord; + else + er = inflight_exception_list; + } + + if (_d_isbaseof(master_class_info, pcb.type)) + { + // Found matching catch handler + + auto original_exception = skip_collateral_exceptions(exceptionRecord); + if (original_exception.ExceptionRecord is null + && !(exceptionRecord is inflight_exception_list)) + original_exception.ExceptionRecord = inflight_exception_list; + inflight_exception_list = exceptionRecord; + + // Global unwind: call finally blocks in intervening frames + _d_global_unwind(frame, exceptionRecord); + + // Local unwind: call finally blocks skipped in this frame + _d_local_unwind(handler_table, frame, ndx, + &searchCollisionExceptionHandler); + + frame.table_index = prev_ndx; + + // Build D exception chain from SEH records + EXCEPTION_RECORD* z = exceptionRecord; + Throwable prev = null; + Error master_error = null; + + for (;;) + { + Throwable w = _d_translate_se_to_d_exception(z, context); + if (z == master && (z.ExceptionFlags & EXCEPTION_COLLATERAL)) + master_error = cast(Error) w; + prev = Throwable.chainTogether(w, prev); + if (!(z.ExceptionFlags & EXCEPTION_COLLATERAL)) + break; + z = z.ExceptionRecord; + } + + Throwable pti; + if (master_error) + { + master_error.bypassedException = prev; + pti = master_error; + } + else + pti = prev; + + inflight_exception_list = z.ExceptionRecord; + + // Initialize catch variable and jump to handler + int regebp = cast(int)&frame.ebp; + *cast(Object*)(regebp + pcb.bpoffset) = pti; + + { + uint catch_esp; + alias fp_t = void function(); + fp_t catch_addr = cast(fp_t) pcb.code; + catch_esp = regebp - handler_table.espoffset - fp_t.sizeof; + asm @nogc nothrow + { + mov EAX, catch_esp; + mov ECX, catch_addr; + mov [EAX], ECX; + mov EBP, regebp; + mov ESP, EAX; + ret; + } + } + } + } + } + } + } + return EXCEPTION_DISPOSITION.ExceptionContinueSearch; +} + +// Exception filter for __try/__except around Dmain + +extern(C) int _d_exception_filter(EXCEPTION_POINTERS* eptrs, int retval, Object* exception_object) @trusted +{ + *exception_object = _d_translate_se_to_d_exception(eptrs.ExceptionRecord, eptrs.ContextRecord); + return retval; +} + +// Collision exception handlers + +extern(C) EXCEPTION_DISPOSITION searchCollisionExceptionHandler( + EXCEPTION_RECORD* exceptionRecord, + DEstablisherFrame*, + CONTEXT*, + void* dispatcherContext) @trusted +{ + if (!(exceptionRecord.ExceptionFlags & EXCEPTION_UNWIND)) + { + auto n = skip_collateral_exceptions(exceptionRecord); + n.ExceptionFlags |= EXCEPTION_COLLATERAL; + return EXCEPTION_DISPOSITION.ExceptionContinueSearch; + } + // Collision during SEARCH phase - restart from 'frame' + *(cast(void**) dispatcherContext) = dispatcherContext; // frame + return EXCEPTION_DISPOSITION.ExceptionCollidedUnwind; +} + +extern(C) EXCEPTION_DISPOSITION unwindCollisionExceptionHandler( + EXCEPTION_RECORD* exceptionRecord, + DEstablisherFrame* frame, + CONTEXT*, + void* dispatcherContext) @trusted +{ + if (!(exceptionRecord.ExceptionFlags & EXCEPTION_UNWIND)) + { + auto n = skip_collateral_exceptions(exceptionRecord); + n.ExceptionFlags |= EXCEPTION_COLLATERAL; + return EXCEPTION_DISPOSITION.ExceptionContinueSearch; + } + // Collision during UNWIND phase - restart from 'frame.prev' + *(cast(void**) dispatcherContext) = frame.prev; + return EXCEPTION_DISPOSITION.ExceptionCollidedUnwind; +} + +// Local unwind - run finally blocks in the current frame + +extern(C) void _d_local_unwind(DHandlerTable* handler_table, DEstablisherFrame* frame, int stop_index, LanguageSpecificHandler collision_handler) @trusted +{ + // Install collision handler on SEH chain + asm @nogc nothrow + { + push dword ptr -1; + push dword ptr 0; + push collision_handler; + push dword ptr FS:_except_list; + mov FS:_except_list, ESP; + } + + for (auto i = frame.table_index; i != -1 && i != stop_index;) + { + auto phi = &handler_table.handler_info.ptr[i]; + i = phi.prev_index; + + if (phi.finally_code) + { + auto catch_ebp = &frame.ebp; + auto blockaddr = phi.finally_code; + asm @nogc nothrow + { + push EBX; + mov EBX, blockaddr; + push EBP; + mov EBP, catch_ebp; + call EBX; + pop EBP; + pop EBX; + } + } + } + + // Remove collision handler from SEH chain + asm @nogc nothrow + { + pop FS:_except_list; + add ESP, 12; + } +} + +// Global unwind - thin wrapper around RtlUnwind + +extern(C) int _d_global_unwind(DEstablisherFrame* pFrame, EXCEPTION_RECORD* eRecord) @trusted +{ + asm @nogc nothrow + { + naked; + push EBP; + mov EBP, ESP; + push ECX; + push EBX; + push ESI; + push EDI; + push EBP; + push 0; + push dword ptr 12[EBP]; // eRecord + call __system_unwind; + jmp __unwind_exit; + __system_unwind: + push dword ptr 8[EBP]; // pFrame + call RtlUnwind; + __unwind_exit: + pop EBP; + pop EDI; + pop ESI; + pop EBX; + pop ECX; + mov ESP, EBP; + pop EBP; + ret; + } +} + +// Local unwind for goto/return across finally blocks + +extern(C) void _d_local_unwind2() @trusted +{ + asm @nogc nothrow + { + naked; + jmp _d_localUnwindForGoto; + } +} + +extern(C) void _d_localUnwindForGoto(DHandlerTable* handler_table, DEstablisherFrame* frame, int stop_index) @trusted +{ + _d_local_unwind(handler_table, frame, stop_index, &searchCollisionExceptionHandler); +} + +// Monitor handler stubs (for synchronized blocks) + +extern(C) EXCEPTION_DISPOSITION _d_monitor_handler(EXCEPTION_RECORD* exceptionRecord, DEstablisherFrame*, CONTEXT*, void*) @trusted +{ + if (exceptionRecord.ExceptionFlags & EXCEPTION_UNWIND) + { + // TODO: _d_monitorexit(cast(Object)cast(void*)frame.table_index); + } + return EXCEPTION_DISPOSITION.ExceptionContinueSearch; +} + +extern(C) void _d_monitor_prolog(void*, void*, Object) @trusted +{ + // TODO: _d_monitorenter(h); +} + +extern(C) void _d_monitor_epilog(void*, void*, Object) @trusted +{ + // TODO: _d_monitorexit(h); +} + + + +} // version (Win32) +else version (Win64) +{ + +// ---------------------------------------------------------------------- +// DMD Win64 - RBP-chain walking with ._deh section tables +// ---------------------------------------------------------------------- + + +// ---------------------------------------------------------------------- +// Win64 - RBP-chain walking with ._deh section tables +// ---------------------------------------------------------------------- + +// Data structures - compiler-generated exception handler tables + +struct DHandlerInfo +{ + uint offset; // offset from function address to start of guarded section + uint endoffset; // offset of end of guarded section + int prev_index; // previous table index + uint cioffset; // offset to DCatchInfo data from start of table (!=0 if try-catch) + size_t finally_offset; // offset to finally code to execute (!=0 if try-finally) +} + +struct DHandlerTable +{ + uint espoffset; // offset of ESP from EBP + uint retoffset; // offset from start of function to return code + size_t nhandlers; // dimension of handler_info[] + DHandlerInfo[1] handler_info; +} + +struct DCatchBlock +{ + ClassInfo type; // catch type + size_t bpoffset; // EBP offset of catch var + size_t codeoffset; // catch handler offset +} + +struct DCatchInfo +{ + size_t ncatches; // number of catch blocks + DCatchBlock[1] catch_block; +} + +struct FuncTable +{ + void* fptr; // pointer to start of function + DHandlerTable* handlertable; + uint fsize; // size of function in bytes +} + +// InFlight exception tracking (per-stack, swapped on fiber switches) + +private struct InFlight +{ + InFlight* next; + void* addr; + Throwable t; +} + +private __gshared InFlight* __inflight = null; + +extern(C) void* _d_eh_swapContext(void* newContext) +{ + auto old = __inflight; + __inflight = cast(InFlight*) newContext; + return old; +} + +// DEH section scanning - find exception handler tables in the binary + +version (Windows) + extern(C) extern __gshared ubyte __ImageBase; + +private __gshared immutable(FuncTable)* _deh_start; +private __gshared immutable(FuncTable)* _deh_end; + +private void ensure_deh_loaded() @trusted +{ + if (_deh_start !is null) + return; + + version (Windows) + { + auto section = find_pe_section(cast(void*) &__ImageBase, "._deh\0\0\0"); + if (section.length) + { + _deh_start = cast(immutable(FuncTable)*) section.ptr; + _deh_end = cast(immutable(FuncTable)*)(section.ptr + section.length); + } + } + else version (linux) + { + // TODO: ELF section scanning for .deh + } +} + +/// PE section lookup - duplicated from urt.package to avoid import cycle. +private void[] find_pe_section(void* imageBase, string name) @trusted +{ + if (name.length > 8) + return null; + + auto base = cast(ubyte*) imageBase; + if (base[0] != 0x4D || base[1] != 0x5A) + return null; + + auto lfanew = *cast(int*)(base + 0x3C); + auto pe = base + lfanew; + if (pe[0] != 'P' || pe[1] != 'E' || pe[2] != 0 || pe[3] != 0) + return null; + + auto fileHeader = pe + 4; + ushort numSections = *cast(ushort*)(fileHeader + 2); + ushort optHeaderSize = *cast(ushort*)(fileHeader + 16); + auto sections = fileHeader + 20 + optHeaderSize; + + foreach (i; 0 .. numSections) + { + auto sec = sections + i * 40; + auto secName = (cast(char*) sec)[0 .. 8]; + bool match = true; + foreach (j; 0 .. 8) + { + if (secName[j] != name[j]) + { + match = false; + break; + } + } + if (match) + { + auto virtualSize = *cast(uint*)(sec + 8); + auto virtualAddress = *cast(uint*)(sec + 12); + return (base + virtualAddress)[0 .. virtualSize]; + } + } + return null; +} + +// Handler table lookup + +immutable(FuncTable)* __eh_finddata(void* address) @trusted +{ + ensure_deh_loaded(); + if (_deh_start is null) + return null; + return __eh_finddata_range(address, _deh_start, _deh_end); +} + +immutable(FuncTable)* __eh_finddata_range(void* address, immutable(FuncTable)* pstart, immutable(FuncTable)* pend) @trusted +{ + for (auto ft = pstart; ; ft++) + { + Lagain: + if (ft >= pend) + break; + + version (Win64) + { + // MS Linker sometimes inserts zero padding between .obj sections + if (ft.fptr == null) + { + ft = cast(immutable(FuncTable)*)(cast(void**) ft + 1); + goto Lagain; + } + } + + immutable(void)* fptr = ft.fptr; + version (Win64) + { + // Follow JMP indirection from /DEBUG linker + if ((cast(ubyte*) fptr)[0] == 0xE9) + fptr = fptr + 5 + *cast(int*)(fptr + 1); + } + + if (fptr <= address && address < cast(void*)(cast(char*) fptr + ft.fsize)) + return ft; + } + return null; +} + +// Stack frame walking + +size_t __eh_find_caller(size_t regbp, size_t* pretaddr) @trusted +{ + size_t bp = *cast(size_t*) regbp; + + if (bp) + { + // Stack grows downward - new BP must be above old + if (bp <= regbp) + terminate(); + + *pretaddr = *cast(size_t*)(regbp + size_t.sizeof); + } + return bp; +} + +// _d_throwc - the core throw implementation (RBP-chain walking) + +alias fp_t = int function(); + +extern(C) void _d_throwc(Throwable h) @trusted +{ + size_t regebp; + + version (D_InlineAsm_X86) + asm nothrow @nogc { mov regebp, EBP; } + else version (D_InlineAsm_X86_64) + asm nothrow @nogc { mov regebp, RBP; } + + // Increment reference count if refcounted + auto refcount = h.refcount(); + if (refcount) + h.refcount() = refcount + 1; + + _d_createTrace(h, null); + + while (1) + { + size_t retaddr; + + regebp = __eh_find_caller(regebp, &retaddr); + if (!regebp) + break; + + auto func_table = __eh_finddata(cast(void*) retaddr); + auto handler_table = func_table ? func_table.handlertable : null; + if (!handler_table) + continue; + + auto funcoffset = cast(size_t) func_table.fptr; + version (Win64) + { + // Follow JMP indirection from /DEBUG linker + if ((cast(ubyte*) funcoffset)[0] == 0xE9) + funcoffset = funcoffset + 5 + *cast(int*)(funcoffset + 1); + } + + // Find start index for retaddr in handler table + auto dim = handler_table.nhandlers; + auto index = -1; + for (uint i = 0; i < dim; i++) + { + auto phi = &handler_table.handler_info.ptr[i]; + if (retaddr > funcoffset + phi.offset && + retaddr <= funcoffset + phi.endoffset) + index = i; + } + + // Handle inflight exception chaining + if (dim) + { + auto phi = &handler_table.handler_info.ptr[index + 1]; + auto prev = cast(InFlight*) &__inflight; + auto curr = prev.next; + + if (curr !is null && curr.addr == cast(void*)(funcoffset + phi.finally_offset)) + { + auto e = cast(Error) h; + if (e !is null && (cast(Error) curr.t) is null) + { + e.bypassedException = curr.t; + prev.next = curr.next; + } + else + { + h = Throwable.chainTogether(curr.t, h); + prev.next = curr.next; + } + } + } + + // Walk handler table entries + int prev_ndx; + for (auto ndx = index; ndx != -1; ndx = prev_ndx) + { + auto phi = &handler_table.handler_info.ptr[ndx]; + prev_ndx = phi.prev_index; + + if (phi.cioffset) + { + // Catch handler + auto pci = cast(DCatchInfo*)(cast(char*) handler_table + phi.cioffset); + auto ncatches = pci.ncatches; + + for (uint i = 0; i < ncatches; i++) + { + auto ci = **cast(ClassInfo**) h; + auto pcb = &pci.catch_block.ptr[i]; + + if (_d_isbaseof(ci, pcb.type)) + { + // Initialize catch variable + *cast(void**)(regebp + pcb.bpoffset) = cast(void*) h; + + // Jump to catch block - does not return + { + size_t catch_esp; + fp_t catch_addr; + + catch_addr = cast(fp_t)(funcoffset + pcb.codeoffset); + catch_esp = regebp - handler_table.espoffset - fp_t.sizeof; + + version (D_InlineAsm_X86) + asm nothrow @nogc + { + mov EAX, catch_esp; + mov ECX, catch_addr; + mov [EAX], ECX; + mov EBP, regebp; + mov ESP, EAX; + ret; + } + else version (D_InlineAsm_X86_64) + asm nothrow @nogc + { + mov RAX, catch_esp; + mov RCX, catch_esp; + mov RCX, catch_addr; + mov [RAX], RCX; + mov RBP, regebp; + mov RSP, RAX; + ret; + } + } + } + } + } + else if (phi.finally_offset) + { + // Finally block + auto blockaddr = cast(void*)(funcoffset + phi.finally_offset); + InFlight inflight; + + inflight.addr = blockaddr; + inflight.next = __inflight; + inflight.t = h; + __inflight = &inflight; + + version (D_InlineAsm_X86) + asm nothrow @nogc + { + push EBX; + mov EBX, blockaddr; + push EBP; + mov EBP, regebp; + call EBX; + pop EBP; + pop EBX; + } + else version (D_InlineAsm_X86_64) + asm nothrow @nogc + { + sub RSP, 8; + push RBX; + mov RBX, blockaddr; + push RBP; + mov RBP, regebp; + call RBX; + pop RBP; + pop RBX; + add RSP, 8; + } + + if (__inflight is &inflight) + __inflight = __inflight.next; + } + } + } + terminate(); +} + + +} // version (Win64) diff --git a/src/urt/driver/windows/fibre.d b/src/urt/driver/windows/fibre.d new file mode 100644 index 0000000..81aca31 --- /dev/null +++ b/src/urt/driver/windows/fibre.d @@ -0,0 +1,92 @@ +module urt.driver.windows.fibre; + +version (Windows): + +import urt.fibre : cothread_t, coentry_t; +import urt.mem; +import urt.internal.sys.windows.winbase; + +nothrow @nogc: + + +version (X86_64) +{ + import urt.system : NT_TIB, __readgsqword; + + void* GetCurrentFiber() + => cast(void*)__readgsqword(NT_TIB.FiberData.offsetof); + + void* GetFiberData() + => *cast(void**)__readgsqword(NT_TIB.FiberData.offsetof); +} +else version (X86) +{ + import urt.system : NT_TIB, __readfsdword; + + void* GetCurrentFiber() + => cast(void*)__readfsdword(NT_TIB.FiberData.offsetof); + + void* GetFiberData() + => *cast(void**)__readfsdword(NT_TIB.FiberData.offsetof); +} + +struct co_fibre_data +{ + void* fiber; + void* user_data; + uint stack_size; + coentry_t coentry; +} +co_fibre_data thread_fiber_data; + +inout(co_fibre_data)* co_get_fibre_data(inout cothread_t fibre) pure + => cast(co_fibre_data*)fibre; + +cothread_t co_active() +{ + if(!thread_fiber_data.fiber) + thread_fiber_data.fiber = ConvertThreadToFiber(&thread_fiber_data); + return GetFiberData(); +} + +void* co_data() + => (cast(co_fibre_data*)GetFiberData()).user_data; + +cothread_t co_derive(void[] memory, coentry_t entry, void* data) +{ + // Windows fibers do not allow users to supply their own memory + return null; +} + +cothread_t co_create(size_t stack_size, coentry_t entry, void* data) +{ + assert(stack_size <= uint.max, "Stack size too large"); + + co_active(); + + extern(Windows) static void co_thunk(void* codata) + { + (cast(co_fibre_data*)codata).coentry(); + assert(false, "Error: returned from fibre!"); + } + + auto fdata = defaultAllocator().allocT!co_fibre_data(); + fdata.user_data = data; + fdata.coentry = entry; + fdata.stack_size = cast(uint)stack_size; + fdata.fiber = CreateFiber(stack_size, &co_thunk, fdata); + return fdata; +} + +void co_delete(cothread_t cothread) +{ + auto fdata = cast(co_fibre_data*)cothread; + DeleteFiber(fdata.fiber); + defaultAllocator().freeT(fdata); +} + +void co_switch(cothread_t cothread) +{ + auto fdata = cast(co_fibre_data*)cothread; + SwitchToFiber(fdata.fiber); +} diff --git a/src/urt/driver/wpa/crypto.d b/src/urt/driver/wpa/crypto.d new file mode 100644 index 0000000..58f50e5 --- /dev/null +++ b/src/urt/driver/wpa/crypto.d @@ -0,0 +1,103 @@ +module urt.driver.wpa.crypto; + +import urt.digest.hmac : HMACContext, hmac_init, hmac_update, hmac_finalise; +import urt.digest.sha : SHA1Context; +import urt.result : Result, InternalResult; + +nothrow @nogc: + + +enum size_t wpa_pmk_len = 32; +enum size_t wpa_nonce_len = 32; +enum size_t wpa_ptk_len_ccmp = 48; + +// IEEE 802.11i SHA1 PRF. The label is NUL-terminated in the MAC input, matching +// wpa_supplicant's sha1_prf() and the "Pairwise key expansion" PTK derivation. +Result sha1_prf(const(ubyte)[] key, const(char)[] label, const(ubyte)[] data, ubyte[] output) +{ + if (key.length == 0 || label.length == 0 || output.length == 0) + return InternalResult.invalid_parameter; + + ubyte[SHA1Context.DigestLen] digest = void; + ubyte zero = 0; + ubyte counter = 0; + size_t pos; + + while (pos < output.length) + { + HMACContext!SHA1Context h; + hmac_init(h, key); + hmac_update(h, cast(const(ubyte)[])label); + hmac_update(h, (&zero)[0 .. 1]); + hmac_update(h, data); + hmac_update(h, (&counter)[0 .. 1]); + digest = hmac_finalise(h); + + size_t n = output.length - pos; + if (n > digest.length) + n = digest.length; + output[pos .. pos + n] = digest[0 .. n]; + pos += n; + counter++; + } + + return Result.success; +} + +// Build B = min(AP, STA MAC) || max(AP, STA MAC) || min(ANonce, SNonce) || +// max(ANonce, SNonce), then PRF(PMK, "Pairwise key expansion", B). +Result wpa2_pmk_to_ptk(const(ubyte)[wpa_pmk_len] pmk, + const(ubyte)[6] ap_mac, + const(ubyte)[6] sta_mac, + const(ubyte)[wpa_nonce_len] anonce, + const(ubyte)[wpa_nonce_len] snonce, + ubyte[] ptk) +{ + if (ptk.length == 0) + return InternalResult.invalid_parameter; + + ubyte[6 + 6 + wpa_nonce_len + wpa_nonce_len] seed = void; + size_t pos; + + if (lex_less(ap_mac[], sta_mac[])) + { + seed[pos .. pos + 6] = ap_mac[]; + pos += 6; + seed[pos .. pos + 6] = sta_mac[]; + pos += 6; + } + else + { + seed[pos .. pos + 6] = sta_mac[]; + pos += 6; + seed[pos .. pos + 6] = ap_mac[]; + pos += 6; + } + + if (lex_less(anonce[], snonce[])) + { + seed[pos .. pos + wpa_nonce_len] = anonce[]; + pos += wpa_nonce_len; + seed[pos .. pos + wpa_nonce_len] = snonce[]; + } + else + { + seed[pos .. pos + wpa_nonce_len] = snonce[]; + pos += wpa_nonce_len; + seed[pos .. pos + wpa_nonce_len] = anonce[]; + } + + return sha1_prf(pmk[], "Pairwise key expansion", seed[], ptk); +} + +private bool lex_less(const(ubyte)[] a, const(ubyte)[] b) +{ + foreach (i; 0 .. a.length) + { + if (a[i] < b[i]) + return true; + if (a[i] > b[i]) + return false; + } + return false; +} diff --git a/src/urt/driver/wpa/eapol.d b/src/urt/driver/wpa/eapol.d new file mode 100644 index 0000000..e42ade2 --- /dev/null +++ b/src/urt/driver/wpa/eapol.d @@ -0,0 +1,205 @@ +// WPA/WPA2 EAPOL-Key frame codec. +// +// Wire format (802.1X EAPOL + IEEE 802.11i Key Descriptor v2): +// 4-byte IEEE 802.1X header: +// ver (1), type (1), body_length (2 BE) +// [type 3 = EAPOL-Key; ver 1 = 2001, ver 2 = 2004 (used today)] +// 95-byte fixed key-descriptor body: +// descriptor_type (1) -- 2 = RSN (WPA2) +// key_info (2 BE) -- version | flags | key index +// key_length (2 BE) -- 16 for CCMP pairwise; 0 for group msg +// replay_counter (8 BE) -- echo back AP's value +// key_nonce (32) -- ANonce on msg 1, SNonce on msg 2 +// key_iv (16) -- zero in v2 (AES-CMAC/HMAC-SHA1) +// key_rsc (8) -- group key seq, BE +// key_id (8, reserved) -- zero +// key_mic (16) -- HMAC-SHA1(KCK, frame_with_zero_mic) +// key_data_length (2 BE) +// N-byte key_data: +// msg 2: STA's RSN IE +// msg 3: GTK KDE + group RSC + IGTK KDE if PMF, AES-key-wrapped with KEK +module urt.driver.wpa.eapol; + +public import urt.driver.dot1x.eapol; + +nothrow @nogc: + + +private ushort be_u16(const(ubyte)* p) pure +{ + return cast(ushort)((cast(ushort)p[0] << 8) | p[1]); +} + + +enum ubyte key_desc_type_rc4_hmac_md5 = 1; // WPA (no longer issued) +enum ubyte key_desc_type_rsn = 2; // WPA2 / RSN + +// key_info bitfield (host order): +enum ushort key_info_ver_hmac_md5_rc4 = 0x0001; +enum ushort key_info_ver_hmac_sha1_aes = 0x0002; +enum ushort key_info_ver_aes_cmac = 0x0003; +enum ushort key_info_ver_mask = 0x0007; +enum ushort key_info_type_pairwise = 0x0008; +enum ushort key_info_keyidx_shift = 4; +enum ushort key_info_keyidx_mask = 0x0030; +enum ushort key_info_install = 0x0040; +enum ushort key_info_key_ack = 0x0080; +enum ushort key_info_key_mic = 0x0100; +enum ushort key_info_secure = 0x0200; +enum ushort key_info_error = 0x0400; +enum ushort key_info_request = 0x0800; +enum ushort key_info_encr_key_data = 0x1000; +enum ushort key_info_smk_message = 0x2000; + +enum size_t key_desc_fixed_len = 95; // descriptor body without key_data +enum size_t eapol_key_fixed_len = eapol_hdr_len + key_desc_fixed_len; // 99 +enum size_t eapol_key_nonce_len = 32; +enum size_t eapol_key_mic_len = 16; +enum size_t eapol_key_replay_len = 8; +enum size_t eapol_key_rsc_len = 8; +enum size_t eapol_key_iv_len = 16; + +// Offsets within an EAPOL-Key frame, measured from the start of the 802.1X +// header (so the byte that holds the version is at offset 0). +enum size_t off_version = 0; +enum size_t off_type = 1; +enum size_t off_body_len = 2; // BE u16 +enum size_t off_desc_type = 4; +enum size_t off_key_info = 5; // BE u16 +enum size_t off_key_length = 7; // BE u16 +enum size_t off_replay = 9; +enum size_t off_nonce = 17; +enum size_t off_iv = 49; +enum size_t off_rsc = 65; +enum size_t off_key_id = 73; +enum size_t off_mic = 81; +enum size_t off_key_data_len = 97; // BE u16 +enum size_t off_key_data = 99; + + +struct EapolKeyFrame +{ + ubyte version_; + ubyte type; + ushort body_length; // bytes after the 4-byte 802.1X header + ubyte descriptor_type; + ushort key_info; + ushort key_length; + ubyte[eapol_key_replay_len] replay_counter; + ubyte[eapol_key_nonce_len] key_nonce; + ubyte[eapol_key_iv_len] key_iv; + ubyte[eapol_key_rsc_len] key_rsc; + ubyte[8] key_id; + ubyte[eapol_key_mic_len] key_mic; + ushort key_data_length; + const(ubyte)[] key_data; // borrowed slice into the source frame + +nothrow @nogc: + @property ushort version_bits() const => cast(ushort)(key_info & key_info_ver_mask); + @property bool pairwise() const => (key_info & key_info_type_pairwise) != 0; + @property ubyte key_index() const => cast(ubyte)((key_info & key_info_keyidx_mask) >> key_info_keyidx_shift); + @property bool install() const => (key_info & key_info_install) != 0; + @property bool key_ack() const => (key_info & key_info_key_ack) != 0; + @property bool key_mic_set() const => (key_info & key_info_key_mic) != 0; + @property bool secure() const => (key_info & key_info_secure) != 0; + @property bool error() const => (key_info & key_info_error) != 0; + @property bool request() const => (key_info & key_info_request) != 0; + @property bool encr_key_data() const => (key_info & key_info_encr_key_data) != 0; +} + + +// Parse an EAPOL-Key frame from the wire. `frame` is the full 802.1X payload +// (starting at the version byte; the ethernet header has already been +// consumed by the driver). Returns false on malformed input. +bool decode_eapol_key(const(ubyte)[] frame, ref EapolKeyFrame out_) +{ + if (frame.length < eapol_key_fixed_len) + return false; + + if (frame[off_type] != eapol_type_key) + return false; + + ushort body_len = be_u16(frame.ptr +off_body_len); + // body_len counts the bytes after the 802.1X header (descriptor + data). + if (cast(size_t)body_len + eapol_hdr_len > frame.length) + return false; + + out_.version_ = frame[off_version]; + out_.type = frame[off_type]; + out_.body_length = body_len; + out_.descriptor_type = frame[off_desc_type]; + out_.key_info = be_u16(frame.ptr +off_key_info); + out_.key_length = be_u16(frame.ptr +off_key_length); + out_.replay_counter[] = frame[off_replay .. off_replay + eapol_key_replay_len]; + out_.key_nonce[] = frame[off_nonce .. off_nonce + eapol_key_nonce_len]; + out_.key_iv[] = frame[off_iv .. off_iv + eapol_key_iv_len]; + out_.key_rsc[] = frame[off_rsc .. off_rsc + eapol_key_rsc_len]; + out_.key_id[] = frame[off_key_id .. off_key_id + 8]; + out_.key_mic[] = frame[off_mic .. off_mic + eapol_key_mic_len]; + + ushort kd_len = be_u16(frame.ptr +off_key_data_len); + out_.key_data_length = kd_len; + if (off_key_data + cast(size_t)kd_len > frame.length) + return false; + out_.key_data = frame[off_key_data .. off_key_data + kd_len]; + + return true; +} + + +// Build an EAPOL-Key frame into `dst`. Returns the number of bytes written, +// or 0 if the buffer is too small. MIC field is zero-filled; the caller is +// expected to compute the MIC over the written buffer and patch it in via +// the patch_mic() helper. +size_t encode_eapol_key(ubyte[] dst, + ubyte eapol_version, + ubyte descriptor_type, + ushort key_info, + ushort key_length, + const(ubyte)[eapol_key_replay_len] replay, + const(ubyte)[eapol_key_nonce_len] nonce, + const(ubyte)[eapol_key_rsc_len] rsc, + const(ubyte)[] key_data) +{ + size_t total = eapol_key_fixed_len + key_data.length; + if (dst.length < total) + return 0; + + dst[off_version] = eapol_version; + dst[off_type] = eapol_type_key; + + // body_length excludes the 4-byte 802.1X header. + ushort body_len = cast(ushort)(key_desc_fixed_len + key_data.length); + dst[off_body_len] = cast(ubyte)(body_len >> 8); + dst[off_body_len + 1] = cast(ubyte)(body_len & 0xff); + + dst[off_desc_type] = descriptor_type; + dst[off_key_info] = cast(ubyte)(key_info >> 8); + dst[off_key_info + 1] = cast(ubyte)(key_info & 0xff); + dst[off_key_length] = cast(ubyte)(key_length >> 8); + dst[off_key_length + 1] = cast(ubyte)(key_length & 0xff); + + dst[off_replay .. off_replay + eapol_key_replay_len] = replay[]; + dst[off_nonce .. off_nonce + eapol_key_nonce_len] = nonce[]; + dst[off_iv .. off_iv + eapol_key_iv_len] = 0; + dst[off_rsc .. off_rsc + eapol_key_rsc_len] = rsc[]; + dst[off_key_id .. off_key_id + 8] = 0; + dst[off_mic .. off_mic + eapol_key_mic_len] = 0; + + dst[off_key_data_len] = cast(ubyte)(key_data.length >> 8); + dst[off_key_data_len + 1] = cast(ubyte)(key_data.length & 0xff); + + if (key_data.length > 0) + dst[off_key_data .. off_key_data + key_data.length] = key_data[]; + + return total; +} + + +// Patch the MIC field into an already-encoded EAPOL-Key frame. +void patch_mic(ubyte[] frame, const(ubyte)[eapol_key_mic_len] mic) +{ + if (frame.length < off_mic + eapol_key_mic_len) + return; + frame[off_mic .. off_mic + eapol_key_mic_len] = mic[]; +} diff --git a/src/urt/driver/wpa/fourway.d b/src/urt/driver/wpa/fourway.d new file mode 100644 index 0000000..3d27a8b --- /dev/null +++ b/src/urt/driver/wpa/fourway.d @@ -0,0 +1,470 @@ +// IEEE 802.11i 4-way handshake (STA side). Drives the PMK-to-PTK derivation, +// MIC validation, GTK unwrap, and key install via host-provided hooks. +// +// Message flow (STA perspective): +// 1/4: receive ANonce from AP -> derive PTK, build msg 2/4 with SNonce + RSN +// IE, MIC over frame using KCK +// 3/4: validate MIC, AES-unwrap encrypted key_data with KEK, parse GTK KDE, +// install pairwise TK + group GTK via hooks, build msg 4/4 with MIC +// +// Key descriptor version 2 (HMAC-SHA1 MIC, AES key-wrap) handled here; +// version 3 (AES-CMAC, used for PMF) is planned but not yet implemented. +module urt.driver.wpa.fourway; + +import urt.crypto.aes_keywrap : aes_unwrap; +import urt.crypto.random : crypto_random_bytes; +import urt.driver.wpa.crypto; +import urt.digest.hmac; +import urt.digest.sha; +import urt.result : Result, InternalResult; + +import urt.driver.wpa.eapol; + +nothrow @nogc: + + +enum size_t wpa_kck_len = 16; +enum size_t wpa_kek_len = 16; +enum size_t wpa_tk_len_ccmp = 16; +enum size_t wpa_gtk_max_len = 32; +enum size_t wpa_max_eapol_len = 256; // typical handshake frame is ~120 bytes + +enum FourwayState : ubyte +{ + idle, // before assoc / after disconnect + awaiting_msg1, // assoc done, waiting for AP's first key frame + awaiting_msg3, // sent msg 2, waiting for AP's msg 3 + completed, // sent msg 4, keys installed + failed, +} + +enum WpaHandshakeReason : ushort +{ + none, + random_failed, + ptk_failed, + encode_failed, + tx_failed, + mic_failed, + nonce_mismatch, + malformed_key_data, + gtk_unwrap_failed, + gtk_missing, + pairwise_install_failed, + group_install_failed, + pmf_required_unsupported, +} + +struct FourwayHooks +{ + // Send a full EAPOL-Key 802.1X payload to the AP. The driver prepends + // the Ethernet header and submits to libwifi's TX path. Returns true on + // queued; false on error (handshake will fail). + bool delegate(const(ubyte)[] eapol_payload) nothrow @nogc send_eapol; + + // Install the pairwise TK (16 bytes CCMP). Returns true on success. + bool delegate(const(ubyte)[] tk) nothrow @nogc install_pairwise_key; + + // Install the group GTK. key_idx is 1..3, rsc is 6-byte sequence + // counter (sometimes shorter, pad with zeros to 6). + bool delegate(ubyte key_idx, const(ubyte)[] gtk, const(ubyte)[] rsc) nothrow @nogc install_group_key; + + // Notify the host that the handshake completed (success=true) or failed + // (success=false, reason carries a wpa-spec reason code). + void delegate(bool success, ushort reason) nothrow @nogc handshake_complete; +} + + +struct FourwayContext +{ + FourwayHooks hooks; + + // Long-lived material (set by configure / begin) + ubyte[wpa_pmk_len] pmk; + ubyte[6] own_mac; + ubyte[6] bssid; + // RSN IE we placed in the assoc request -- the AP echoes this in msg 3 + // key_data and uses it to MIC msg 2 from us. Live slice -- caller owns + // backing storage and must keep it valid for the handshake duration. + const(ubyte)[] sta_rsn_ie; + + // Per-handshake state + ubyte[wpa_nonce_len] anonce; + ubyte[wpa_nonce_len] snonce; + ubyte[wpa_ptk_len_ccmp] ptk; + ubyte[eapol_key_replay_len] last_replay; + ubyte[wpa_max_eapol_len] last_msg4; + size_t last_msg4_len; + FourwayState state; + +nothrow @nogc: + + void configure(const(ubyte)[wpa_pmk_len] pmk_, + const(ubyte)[6] own_mac_, + const(ubyte)[6] bssid_, + const(ubyte)[] sta_rsn_ie_) + { + pmk = pmk_; + own_mac = own_mac_; + bssid = bssid_; + sta_rsn_ie = sta_rsn_ie_; + state = FourwayState.idle; + } + + // Call after layer-2 association completed; arms the state machine for + // the AP's incoming msg 1. + void begin_association() + { + state = FourwayState.awaiting_msg1; + last_replay[] = 0; + last_msg4_len = 0; + } + + void reset(WpaHandshakeReason reason) + { + reset(cast(ushort)reason); + } + + void reset(ushort reason) + { + last_msg4_len = 0; + if (state != FourwayState.idle && state != FourwayState.failed) + { + state = FourwayState.failed; + if (hooks.handshake_complete) + hooks.handshake_complete(false, reason); + } + else + { + state = FourwayState.idle; + } + } + + @property const(ubyte)[] kck() const => ptk[0 .. wpa_kck_len]; + @property const(ubyte)[] kek() const => ptk[wpa_kck_len .. wpa_kck_len + wpa_kek_len]; + @property const(ubyte)[] tk() const => ptk[wpa_kck_len + wpa_kek_len .. $]; + + // Process an incoming EAPOL-Key frame. The frame is the 802.1X payload + // (the driver has already stripped the Ethernet header). Returns true if + // the frame was consumed by the handshake; false if not for us. + bool handle_eapol(const(ubyte)[] frame) + { + EapolKeyFrame f; + if (!decode_eapol_key(frame, f)) + return false; + if (f.descriptor_type != key_desc_type_rsn) + return false; + if (f.version_bits != key_info_ver_hmac_sha1_aes) + return false; + if (!f.pairwise || !f.key_ack) + return false; + + if (!f.key_mic_set) + return handle_msg1(frame, f); + else + return handle_msg3(frame, f); + } + +private: + + bool handle_msg1(const(ubyte)[] /*frame*/, ref const EapolKeyFrame f) + { + if (state != FourwayState.awaiting_msg1 && state != FourwayState.awaiting_msg3) + return false; + + // Stash ANonce, replay counter, generate SNonce, derive PTK. + anonce = f.key_nonce; + last_replay = f.replay_counter; + + if (!crypto_random_bytes(snonce[]).succeeded) + { + reset(WpaHandshakeReason.random_failed); + return true; + } + + auto r = wpa2_pmk_to_ptk(pmk, bssid, own_mac, anonce, snonce, ptk[]); + if (!r.succeeded) + { + reset(WpaHandshakeReason.ptk_failed); + return true; + } + + // Build msg 2/4. key_info: pairwise, MIC, version 2. + ushort key_info = key_info_type_pairwise | key_info_key_mic | key_info_ver_hmac_sha1_aes; + ubyte[8] zero_rsc = 0; + + ubyte[wpa_max_eapol_len] out_buf = void; + size_t out_len = encode_eapol_key(out_buf[], + eapol_version_2004, key_desc_type_rsn, + key_info, f.key_length, + last_replay, snonce, zero_rsc, + sta_rsn_ie); + if (out_len == 0) + { + reset(WpaHandshakeReason.encode_failed); + return true; + } + + ubyte[eapol_key_mic_len] mic; + compute_mic(kck, out_buf[0 .. out_len], mic); + patch_mic(out_buf[0 .. out_len], mic); + + if (!hooks.send_eapol(out_buf[0 .. out_len])) + { + reset(WpaHandshakeReason.tx_failed); + return true; + } + + state = FourwayState.awaiting_msg3; + return true; + } + + bool handle_msg3(const(ubyte)[] frame, ref const EapolKeyFrame f) + { + if (state != FourwayState.awaiting_msg3) + { + if (state == FourwayState.completed) + { + if (last_msg4_len != 0 && hooks.send_eapol) + hooks.send_eapol(last_msg4[0 .. last_msg4_len]); + return true; + } + else if (last_msg4_len != 0 && hooks.send_eapol) + { + hooks.send_eapol(last_msg4[0 .. last_msg4_len]); + return true; + } + else + { + return false; + } + } + + // Replay: must be > last (we treat == as a retransmit and just + // re-send the prior msg 2; not implemented yet, just drop). + if (compare_replay(f.replay_counter, last_replay) <= 0) + return true; + + // Verify MIC: compute over frame with the MIC field zeroed. + if (!verify_mic(kck, frame, f.key_mic)) + { + reset(WpaHandshakeReason.mic_failed); + return true; + } + + last_replay = f.replay_counter; + + // ANonce must match what AP sent in msg 1 (replay protection). + foreach (i; 0 .. wpa_nonce_len) + { + if (f.key_nonce[i] != anonce[i]) + { + reset(WpaHandshakeReason.nonce_mismatch); + return true; + } + } + + // AES-unwrap encrypted key_data with KEK. key_data_length must be + // a multiple of 8 and at least 24 (one wrapped block). + if (!f.encr_key_data || f.key_data.length < 24 || (f.key_data.length % 8) != 0) + { + reset(WpaHandshakeReason.malformed_key_data); + return true; + } + + ubyte[256] unwrapped_buf = void; + if (f.key_data.length < 24 || f.key_data.length > unwrapped_buf.length + 8) + { + reset(WpaHandshakeReason.malformed_key_data); + return true; + } + size_t unwrap_len = f.key_data.length - 8; // checked above + ubyte[] unwrapped = unwrapped_buf[0 .. unwrap_len]; + if (!aes_unwrap(kek, f.key_data, unwrapped).succeeded) + { + reset(WpaHandshakeReason.gtk_unwrap_failed); + return true; + } + + // Parse KDEs from the unwrapped key_data: walk the IE list, look + // for the GTK KDE (id 0xDD, OUI 00:0F:AC, KDE type 0x01). + ubyte[wpa_gtk_max_len] gtk = void; + size_t gtk_len; + ubyte gtk_key_id; + ubyte[6] gtk_rsc; + gtk_rsc[] = f.key_rsc[0 .. 6]; + bool gtk_found = parse_gtk_kde(unwrapped, gtk[], gtk_len, gtk_key_id); + if (!gtk_found) + { + reset(WpaHandshakeReason.gtk_missing); + return true; + } + + // Build msg 4/4. + ushort key_info = key_info_type_pairwise | key_info_key_mic | key_info_secure | key_info_ver_hmac_sha1_aes; + ubyte[wpa_nonce_len] zero_nonce = 0; + ubyte[8] zero_rsc = 0; + + ubyte[eapol_key_fixed_len] out_buf = void; + size_t out_len = encode_eapol_key(out_buf[], + eapol_version_2004, key_desc_type_rsn, + key_info, 0, + last_replay, zero_nonce, zero_rsc, + null); + if (out_len == 0) + { + reset(WpaHandshakeReason.encode_failed); + return true; + } + + ubyte[eapol_key_mic_len] mic; + compute_mic(kck, out_buf[0 .. out_len], mic); + patch_mic(out_buf[0 .. out_len], mic); + last_msg4[0 .. out_len] = out_buf[0 .. out_len]; + last_msg4_len = out_len; + + if (!hooks.send_eapol(out_buf[0 .. out_len])) + { + reset(WpaHandshakeReason.tx_failed); + return true; + } + // Install PTK/GTK after queueing msg 4. The BL808 firmware decides + // encryption policy on queued TX descriptors, so installing first can + // make the final control-port EAPOL disappear behind the new PTK. + if (!hooks.install_pairwise_key(tk)) + { + reset(WpaHandshakeReason.pairwise_install_failed); + return true; + } + if (!hooks.install_group_key(gtk_key_id, gtk[0 .. gtk_len], gtk_rsc[])) + { + reset(WpaHandshakeReason.group_install_failed); + return true; + } + + state = FourwayState.completed; + if (hooks.handshake_complete) + hooks.handshake_complete(true, 0); + return true; + } +} + + +const(char)[] wpa_handshake_reason_message(ushort reason) pure nothrow @nogc +{ + switch (cast(WpaHandshakeReason)reason) + { + case WpaHandshakeReason.none: return null; + case WpaHandshakeReason.random_failed: return "WPA handshake failed: random nonce generation failed"; + case WpaHandshakeReason.ptk_failed: return "WPA handshake failed: PTK derivation failed"; + case WpaHandshakeReason.encode_failed: return "WPA handshake failed: EAPOL frame encode failed"; + case WpaHandshakeReason.tx_failed: return "WPA handshake failed: EAPOL transmit failed"; + case WpaHandshakeReason.mic_failed: return "WPA handshake failed: key MIC verification failed"; + case WpaHandshakeReason.nonce_mismatch: return "WPA handshake failed: AP nonce changed during handshake"; + case WpaHandshakeReason.malformed_key_data: return "WPA handshake failed: malformed AP key data"; + case WpaHandshakeReason.gtk_unwrap_failed: return "WPA handshake failed: GTK unwrap failed"; + case WpaHandshakeReason.gtk_missing: return "WPA handshake failed: AP did not provide GTK"; + case WpaHandshakeReason.pairwise_install_failed: return "WPA handshake failed: pairwise key install failed"; + case WpaHandshakeReason.group_install_failed: return "WPA handshake failed: group key install failed"; + case WpaHandshakeReason.pmf_required_unsupported:return "WPA PMF-required networks are not supported yet"; + default: return "WPA handshake failed"; + } +} + + +private void compute_mic(const(ubyte)[] kck, + const(ubyte)[] frame, + ref ubyte[eapol_key_mic_len] out_mic) +{ + // HMAC-SHA1(KCK, frame_with_zero_mic). We feed the bytes around the MIC + // field; the caller passes a frame already zero-filled at off_mic..+16. + HMACContext!SHA1Context h; + hmac_init(h, kck); + hmac_update(h, frame); + ubyte[SHA1Context.DigestLen] digest = hmac_finalise(h); + out_mic[] = digest[0 .. eapol_key_mic_len]; +} + + +private bool verify_mic(const(ubyte)[] kck, + const(ubyte)[] frame, + const(ubyte)[eapol_key_mic_len] expected_mic) +{ + if (frame.length < off_mic + eapol_key_mic_len) + return false; + + // HMAC over frame with the MIC field zeroed. Copy frame into a scratch + // buffer so we don't mutate the caller's slice. + ubyte[wpa_max_eapol_len] scratch = void; + if (frame.length > scratch.length) + return false; + scratch[0 .. frame.length] = frame[]; + scratch[off_mic .. off_mic + eapol_key_mic_len] = 0; + + ubyte[eapol_key_mic_len] computed; + compute_mic(kck, scratch[0 .. frame.length], computed); + + // Constant-time compare to avoid leaking timing info on the MIC. + ubyte diff = 0; + foreach (i; 0 .. eapol_key_mic_len) + diff |= computed[i] ^ expected_mic[i]; + return diff == 0; +} + + +// Compare two 8-byte replay counters (big-endian). Returns -1 / 0 / 1. +private int compare_replay(const(ubyte)[eapol_key_replay_len] a, + const(ubyte)[eapol_key_replay_len] b) +{ + foreach (i; 0 .. eapol_key_replay_len) + { + if (a[i] < b[i]) return -1; + if (a[i] > b[i]) return 1; + } + return 0; +} + + +// Walk a buffer of EAPOL key-data IEs looking for the GTK KDE +// (id=0xDD, OUI=00:0F:AC, kde_type=0x01). Returns true on success and +// fills out_gtk + out_len + out_key_id. +private bool parse_gtk_kde(const(ubyte)[] data, + ubyte[] out_gtk, + ref size_t out_len, + ref ubyte out_key_id) +{ + size_t off = 0; + while (off + 2 <= data.length) + { + ubyte id = data[off]; + ubyte len = data[off + 1]; + if (off + 2 + len > data.length) + return false; + + if (id == 0xDD && len >= 6) + { + // Vendor-specific IE: OUI(3) + KDE type(1) + payload + if (data[off + 2] == 0x00 && data[off + 3] == 0x0F && data[off + 4] == 0xAC + && data[off + 5] == 0x01) + { + // GTK KDE payload: key_id/tx/reserved(1), reserved(1), GTK(N). + size_t body_off = off + 6; + size_t body_end = off + 2 + len; + if (body_end - body_off < 2) + return false; + out_key_id = data[body_off] & 0x03; + size_t gtk_len = body_end - body_off - 2; + if (gtk_len > out_gtk.length) + return false; + out_gtk[0 .. gtk_len] = data[body_off + 2 .. body_end]; + out_len = gtk_len; + return true; + } + } + + off += 2 + len; + if (id == 0xDD) + continue; + } + return false; +} diff --git a/src/urt/driver/wpa/package.d b/src/urt/driver/wpa/package.d new file mode 100644 index 0000000..b27dc50 --- /dev/null +++ b/src/urt/driver/wpa/package.d @@ -0,0 +1,5 @@ +module urt.driver.wpa; + +public import urt.driver.wpa.eapol; +public import urt.driver.wpa.fourway; +public import urt.driver.wpa.supplicant; diff --git a/src/urt/driver/wpa/supplicant.d b/src/urt/driver/wpa/supplicant.d new file mode 100644 index 0000000..386ef0b --- /dev/null +++ b/src/urt/driver/wpa/supplicant.d @@ -0,0 +1,232 @@ +// WPA STA-side supplicant. Holds the per-association keying state and bridges +// libwifi's wpa_funcs callbacks to the 4-way handshake state machine. Driver +// adapters (BL808, ESP32, ...) own a singleton WpaStaSupplicant and translate +// vendor-blob callbacks into method calls. +// +// Currently implements WPA2-PSK (CCMP, key descriptor v2). WPA3-SAE and +// EAP-TLS are planned extensions: factor an AKM trait out of the fourway +// dependency when the second AKM lands. +module urt.driver.wpa.supplicant; + +import urt.crypto.pbkdf2 : wpa2_psk_to_pmk; +import urt.driver.wpa.crypto : wpa_nonce_len, wpa_pmk_len; +import urt.driver.wifi : WifiAuth, WifiStaConfig; +import urt.result : Result, InternalResult; + +import urt.driver.wpa.fourway; + +nothrow @nogc: + + +enum WpaSupplicantState : ubyte +{ + idle, + configured, + associating, + associated, // assoc done, waiting for first EAPOL key frame + keying, // 4-way handshake in progress + completed, + failed, +} + +enum WpaKeyMgmt : ubyte +{ + none, + wpa2_psk, + sae, + enterprise, +} + +struct WpaStaProfile +{ + const(char)[] ssid; + const(char)[] passphrase; + ubyte[6] bssid; + bool pmf_required; + WpaKeyMgmt key_mgmt; +} + +// Driver-side hooks the supplicant calls during the 4-way handshake. The +// adapter populates these to bridge to libwifi (or whatever owns the link). +struct WpaSupplicantHooks +{ + bool function(ubyte key_idx, const(ubyte)[] key, const(ubyte)[] rsc) nothrow @nogc install_group_key; + bool function(const(ubyte)[] tk, const(ubyte)[] rsc) nothrow @nogc install_pairwise_key; + bool function(const(ubyte)[] eapol) nothrow @nogc send_eapol; + bool function(ushort reason_code) nothrow @nogc auth_done; +} + +struct WpaStaSupplicant +{ + WpaSupplicantState state; + WpaStaProfile profile; + WpaSupplicantHooks hooks; + ubyte[wpa_pmk_len] pmk; + ubyte[6] own_mac; + ushort last_reason; + uint rx_eapol_count; + uint tx_eapol_count; + + // 4-way handshake state. The supplicant pumps EAPOL frames into this and + // installs keys via the driver hooks when the handshake completes. + FourwayContext fourway; + +nothrow @nogc: + + Result configure(ref const WifiStaConfig cfg) + { + profile.ssid = cfg.ssid; + profile.passphrase = cfg.password; + profile.bssid = cfg.bssid; + profile.pmf_required = cfg.pmf_required; + profile.key_mgmt = infer_key_mgmt(cfg); + + if (profile.pmf_required) + { + state = WpaSupplicantState.failed; + last_reason = cast(ushort)WpaHandshakeReason.pmf_required_unsupported; + return InternalResult.unsupported; + } + + if (profile.key_mgmt == WpaKeyMgmt.wpa2_psk) + { + auto r = wpa2_psk_to_pmk(profile.passphrase, profile.ssid, pmk); + if (!r) + { + state = WpaSupplicantState.failed; + return r; + } + } + + state = WpaSupplicantState.configured; + return Result.success; + } + + Result configure_precomputed(ref const WifiStaConfig cfg, const(ubyte)[] pmk_) + { + if (pmk_.length != wpa_pmk_len) + { + state = WpaSupplicantState.failed; + return InternalResult.failed; + } + + profile.ssid = cfg.ssid; + profile.passphrase = cfg.password; + profile.bssid = cfg.bssid; + profile.pmf_required = cfg.pmf_required; + profile.key_mgmt = infer_key_mgmt(cfg); + + if (profile.pmf_required) + { + state = WpaSupplicantState.failed; + last_reason = cast(ushort)WpaHandshakeReason.pmf_required_unsupported; + return InternalResult.unsupported; + } + + if (profile.key_mgmt == WpaKeyMgmt.wpa2_psk) + pmk[] = pmk_[0 .. wpa_pmk_len]; + + state = WpaSupplicantState.configured; + return Result.success; + } + + void begin_association(const(ubyte)[6] local_mac, const(ubyte)[] sta_rsn_ie) + { + own_mac = local_mac; + state = WpaSupplicantState.associating; + last_reason = 0; + rx_eapol_count = 0; + tx_eapol_count = 0; + + if (profile.key_mgmt == WpaKeyMgmt.wpa2_psk) + { + fourway.configure(pmk, own_mac, profile.bssid, sta_rsn_ie); + fourway.hooks.send_eapol = &fourway_send_eapol; + fourway.hooks.install_pairwise_key = &fourway_install_pairwise; + fourway.hooks.install_group_key = &fourway_install_group; + fourway.hooks.handshake_complete = &fourway_complete; + } + } + + void associated(const(ubyte)[6] ap_mac) + { + if (state == WpaSupplicantState.failed) + { + if (hooks.auth_done) + hooks.auth_done(last_reason); + return; + } + + profile.bssid = ap_mac; + if (profile.key_mgmt == WpaKeyMgmt.none) + { + state = WpaSupplicantState.completed; + if (hooks.auth_done) + hooks.auth_done(0); + return; + } + + state = WpaSupplicantState.associated; + fourway.bssid = ap_mac; // in case bssid wasn't known at begin_association + fourway.begin_association(); + state = WpaSupplicantState.keying; + } + + int receive_eapol(const(ubyte)[] frame) + { + ++rx_eapol_count; + if (profile.key_mgmt != WpaKeyMgmt.wpa2_psk) + return -1; + return fourway.handle_eapol(frame) ? 0 : -1; + } + + void disconnected(ushort reason_code) + { + last_reason = reason_code; + fourway.hooks.handshake_complete = null; + state = WpaSupplicantState.failed; + fourway.reset(reason_code); + } + +private: + + bool fourway_send_eapol(const(ubyte)[] eapol) + { + if (hooks.send_eapol is null) return false; + ++tx_eapol_count; + return hooks.send_eapol(eapol); + } + + bool fourway_install_pairwise(const(ubyte)[] tk) + { + if (hooks.install_pairwise_key is null) return false; + ubyte[6] empty_rsc = 0; + return hooks.install_pairwise_key(tk, empty_rsc[]); + } + + bool fourway_install_group(ubyte key_idx, const(ubyte)[] gtk, const(ubyte)[] rsc) + { + if (hooks.install_group_key is null) return false; + return hooks.install_group_key(key_idx, gtk, rsc); + } + + void fourway_complete(bool success, ushort reason) + { + state = success ? WpaSupplicantState.completed : WpaSupplicantState.failed; + last_reason = reason; + if (hooks.auth_done) + hooks.auth_done(reason); + } +} + + +WpaKeyMgmt infer_key_mgmt(ref const WifiStaConfig cfg) +{ + if (cfg.password.length == 0) + return WpaKeyMgmt.none; + + // The current WifiStaConfig does not expose scan-selected AKM yet. For the + // first BL808 target, a passphrase means WPA2-PSK unless a later scan/RSN + // parser upgrades it to SAE or enterprise. + return WpaKeyMgmt.wpa2_psk; +} diff --git a/src/urt/encoding.d b/src/urt/encoding.d index 36ced1b..c748e7a 100644 --- a/src/urt/encoding.d +++ b/src/urt/encoding.d @@ -3,18 +3,28 @@ module urt.encoding; nothrow @nogc: -enum Hex(const char[] s) = (){ ubyte[s.length / 2] r; ptrdiff_t len = hex_decode(s, r); assert(len == r.sizeof, "Not a hex string!"); return r; }(); -enum Base64(const char[] s) = (){ ubyte[base64_decode_length(s)] r; ptrdiff_t len = base64_decode(s, r); assert(len == r.sizeof, "Not a base64 string!"); return r; }(); +enum Base64Decode(string str) = () { ubyte[base64_decode_length(str.length)] r; size_t len = base64_decode(str, r[]); assert(len == r.sizeof, "Not a base64 string: " ~ str); return r; }(); +enum HexDecode(string str) = () { ubyte[hex_decode_length(str.length)] r; size_t len = hex_decode(str, r[]); assert(len == r.sizeof, "Not a hex string: " ~ str); return r; }(); +enum URLDecode(string str) = () { char[url_decode_length(str)] r; size_t len = url_decode(str, r[]); assert(len == r.sizeof, "Not a URL encoded string: " ~ str); return r; }(); -ptrdiff_t base64_encode_length(size_t sourceLength) pure - => (sourceLength + 2) / 3 * 4; +size_t base64_encode_length(bool url = false)(size_t source_length) pure +{ + static if (url) + return (source_length * 4 + 2) / 3; // no padding + else + return (source_length + 2) / 3 * 4; +} + +size_t base64_encode_length(bool url = false)(const void[] data) pure + => base64_encode_length!url(data.length); -ptrdiff_t base64_encode(const void[] data, char[] result) pure +ptrdiff_t base64_encode(bool url = false)(const void[] data, char[] result) pure { + immutable(char)* table = url ? &base64url[0] : &base64[0]; auto src = cast(const(ubyte)[])data; size_t len = data.length; - size_t out_len = base64_encode_length(len); + size_t out_len = base64_encode_length!url(len); if (result.length < out_len) return -1; @@ -27,71 +37,111 @@ ptrdiff_t base64_encode(const void[] data, char[] result) pure ubyte b1 = src[i++]; ubyte b2 = src[i++]; - result[j++] = base64[b0 >> 2]; - result[j++] = base64[((b0 & 0x03) << 4) | (b1 >> 4)]; - result[j++] = base64[((b1 & 0x0F) << 2) | (b2 >> 6)]; - result[j++] = base64[b2 & 0x3F]; + result[j++] = table[b0 >> 2]; + result[j++] = table[((b0 & 0x03) << 4) | (b1 >> 4)]; + result[j++] = table[((b1 & 0x0F) << 2) | (b2 >> 6)]; + result[j++] = table[b2 & 0x3F]; } if (i < len) { ubyte b0 = src[i++]; - result[j++] = base64[b0 >> 2]; + result[j++] = table[b0 >> 2]; if (i < len) { ubyte b1 = src[i]; - result[j++] = base64[((b0 & 0x03) << 4) | (b1 >> 4)]; - result[j++] = base64[((b1 & 0x0F) << 2)]; + result[j++] = table[((b0 & 0x03) << 4) | (b1 >> 4)]; + result[j++] = table[((b1 & 0x0F) << 2)]; } else { - result[j++] = base64[((b0 & 0x03) << 4)]; - result[j++] = '='; + result[j++] = table[((b0 & 0x03) << 4)]; + static if (!url) + result[j++] = '='; } - result[j] = '='; + static if (!url) + result[j] = '='; } return out_len; } -ptrdiff_t base64_decode_length(size_t sourceLength) pure -=> sourceLength / 4 * 3; +size_t base64_decode_length(bool url = false)(size_t source_length) pure +{ + static if (url) + { + size_t remainder = source_length % 4; + return source_length / 4 * 3 + (remainder > 0 ? remainder - 1 : 0); + } + else + return source_length / 4 * 3; +} + +size_t base64_decode_length(bool url = false)(const char[] data) pure + => base64_decode_length!url(data.length); -ptrdiff_t base64_decode(const char[] data, void[] result) pure +ptrdiff_t base64_decode(bool url = false)(const char[] data, void[] result) pure { + static if (url) + { + enum uint offset = 45; + enum uint map_size = 78; + alias map = base64url_map; + } + else + { + enum uint offset = 43; + enum uint map_size = 80; + alias map = base64_map; + } + size_t len = data.length; auto dest = cast(ubyte[])result; - size_t out_len = base64_decode_length(len); - if (data[len - 1] == '=') - out_len--; - if (data[len - 2] == '=') - out_len--; + size_t out_len; + + static if (url) + { + size_t remainder = len % 4; + if (remainder == 1) + return -1; + out_len = len / 4 * 3 + (remainder > 0 ? remainder - 1 : 0); + } + else + { + out_len = len / 4 * 3; + if (len >= 1 && data[len - 1] == '=') + --out_len; + if (len >= 2 && data[len - 2] == '=') + --out_len; + } if (result.length < out_len) return -1; + static if (url) + size_t full_len = len / 4 * 4; + else + size_t full_len = len; + size_t i = 0; size_t j = 0; - while (i < len) + while (i < full_len) { - // TODO: this could be faster by using more memory, store a full 256-byte table and no comparisons... - uint b0 = data[i++] - 43; - uint b1 = data[i++] - 43; - uint b2 = data[i++] - 43; - uint b3 = data[i++] - 43; - if (b0 >= 80) + if (i > full_len - 4) return -1; - if (b1 >= 80) - return -1; - if (b2 >= 80) - return -1; - if (b3 >= 80) + + // TODO: this could be faster by using more memory, store a full 256-byte table and no comparisons... + uint b0 = data[i++] - offset; + uint b1 = data[i++] - offset; + uint b2 = data[i++] - offset; + uint b3 = data[i++] - offset; + if (b0 >= map_size || b1 >= map_size || b2 >= map_size || b3 >= map_size) return -1; - b0 = base64_map.ptr[b0]; - b1 = base64_map.ptr[b1]; - b2 = base64_map.ptr[b2]; - b3 = base64_map.ptr[b3]; + b0 = map[b0]; + b1 = map[b1]; + b2 = map[b2]; + b3 = map[b3]; dest[j++] = cast(ubyte)((b0 << 2) | (b1 >> 4)); if (b2 != 64) @@ -100,15 +150,56 @@ ptrdiff_t base64_decode(const char[] data, void[] result) pure dest[j++] = cast(ubyte)((b2 << 6) | b3); } + static if (url) + { + if (i < len) + { + uint b0 = data[i++] - offset; + uint b1 = data[i++] - offset; + if (b0 >= map_size || b1 >= map_size) + return -1; + b0 = map[b0]; + b1 = map[b1]; + dest[j++] = cast(ubyte)((b0 << 2) | (b1 >> 4)); + + if (i < len) + { + uint b2 = data[i] - offset; + if (b2 >= map_size) + return -1; + b2 = map[b2]; + dest[j++] = cast(ubyte)((b1 << 4) | (b2 >> 2)); + } + } + } + return out_len; } +size_t base64url_encode_length(size_t source_length) pure +=> base64_encode_length!true(source_length); + +size_t base64url_encode_length(const void[] data) pure +=> base64_encode_length!true(data); + +alias base64url_encode = base64_encode!true; + +size_t base64url_decode_length(size_t source_length) pure + => base64_decode_length!true(source_length); + +size_t base64url_decode_length(const char[] data) pure + => base64_decode_length!true(data); + +alias base64url_decode = base64_decode!true; + unittest { immutable ubyte[12] data = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C]; char[16] encoded = void; ubyte[12] decoded = void; + static assert(Base64Decode!"AQIDBAUGBwgJCgsM" == data[]); + size_t len = base64_encode(data, encoded); assert(len == 16); assert(encoded == "AQIDBAUGBwgJCgsM"); @@ -130,9 +221,81 @@ unittest assert(len == 10); assert(data[0..10] == decoded[0..10]); -// static assert(Base64!"012345" == [0x01, 0x23, 0x45]); + // base64url: different alphabet (+/ → -_) and no padding + // [0..3] all-62, [3..6] all-63, [6..9] mixed 62/63 + immutable ubyte[9] urldata = [0xFB, 0xEF, 0xBE, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xBF]; + + len = base64_encode(urldata[0..3], encoded[0..4]); + assert(len == 4); + assert(encoded[0..4] == "++++"); + len = base64url_encode(urldata[0..3], encoded[0..4]); + assert(len == 4); + assert(encoded[0..4] == "----"); + + len = base64_encode(urldata[3..6], encoded[0..4]); + assert(len == 4); + assert(encoded[0..4] == "////"); + len = base64url_encode(urldata[3..6], encoded[0..4]); + assert(len == 4); + assert(encoded[0..4] == "____"); + + len = base64_encode(urldata[6..9], encoded[0..4]); + assert(len == 4); + assert(encoded[0..4] == "+/+/"); + len = base64url_encode(urldata[6..9], encoded[0..4]); + assert(len == 4); + assert(encoded[0..4] == "-_-_"); + + // decode roundtrips + len = base64_decode("++++", decoded[0..3]); + assert(len == 3); + assert(decoded[0..3] == urldata[0..3]); + len = base64url_decode("----", decoded[0..3]); + assert(len == 3); + assert(decoded[0..3] == urldata[0..3]); + len = base64_decode("+/+/", decoded[0..3]); + assert(len == 3); + assert(decoded[0..3] == urldata[6..9]); + len = base64url_decode("-_-_", decoded[0..3]); + assert(len == 3); + assert(decoded[0..3] == urldata[6..9]); + + // padding vs no-padding: 1 byte → /w== vs _w + len = base64_encode(urldata[3..4], encoded[0..4]); + assert(len == 4); + assert(encoded[0..4] == "/w=="); + len = base64_decode(encoded[0..4], decoded[0..1]); + assert(len == 1); + assert(decoded[0] == 0xFF); + + len = base64url_encode(urldata[3..4], encoded[0..2]); + assert(len == 2); + assert(encoded[0..2] == "_w"); + len = base64url_decode(encoded[0..2], decoded[0..1]); + assert(len == 1); + assert(decoded[0] == 0xFF); + + // padding vs no-padding: 2 bytes → ++8= vs --8 + len = base64_encode(urldata[0..2], encoded[0..4]); + assert(len == 4); + assert(encoded[0..4] == "++8="); + len = base64_decode(encoded[0..4], decoded[0..2]); + assert(len == 2); + assert(decoded[0..2] == urldata[0..2]); + + len = base64url_encode(urldata[0..2], encoded[0..3]); + assert(len == 3); + assert(encoded[0..3] == "--8"); + len = base64url_decode(encoded[0..3], decoded[0..2]); + assert(len == 2); + assert(decoded[0..2] == urldata[0..2]); } +size_t hex_encode_length(size_t sourceLength) pure + => sourceLength * 2; + +size_t hex_encode_length(const void[] data) pure + => data.length * 2; ptrdiff_t hex_encode(const void[] data, char[] result) pure { @@ -142,9 +305,15 @@ ptrdiff_t hex_encode(const void[] data, char[] result) pure return toHexString(data, result).length; } +size_t hex_decode_length(size_t sourceLength) pure + => sourceLength / 2; + +size_t hex_decode_length(const char[] data) pure + => data.length / 2; + ptrdiff_t hex_decode(const char[] data, void[] result) pure { - import urt.string.ascii : isHex; + import urt.string.ascii : is_hex; if (data.length & 1) return -1; @@ -157,7 +326,7 @@ ptrdiff_t hex_decode(const char[] data, void[] result) pure { ubyte c0 = data[i]; ubyte c1 = data[i + 1]; - if (!c0.isHex || !c1.isHex) + if (!c0.is_hex || !c1.is_hex) return -1; if ((c0 | 0x20) >= 'a') @@ -180,25 +349,25 @@ unittest char[24] encoded = void; ubyte[12] decoded = void; + static assert(HexDecode!"0102030405060708090A0B0C" == data); + size_t len = hex_encode(data, encoded); assert(len == 24); assert(encoded == "0102030405060708090A0B0C"); len = hex_decode(encoded, decoded); assert(len == 12); assert(data == decoded); - - static assert(Hex!"012345" == [0x01, 0x23, 0x45]); } -ptrdiff_t url_encode_length(const char[] data) pure +size_t url_encode_length(const char[] data) pure { - import urt.string.ascii : isURL; + import urt.string.ascii : is_url; size_t len = 0; foreach (c; data) { - if (c.isURL || c == ' ') + if (c.is_url || c == ' ') ++len; else len += 3; @@ -208,14 +377,14 @@ ptrdiff_t url_encode_length(const char[] data) pure ptrdiff_t url_encode(const char[] data, char[] result) pure { - import urt.string.ascii : isURL, hexDigits; + import urt.string.ascii : is_url, hex_digits; size_t j = 0; for (size_t i = 0; i < data.length; ++i) { char c = data[i]; - if (c.isURL || c == ' ') + if (c.is_url || c == ' ') { if (j == result.length) return -1; @@ -226,15 +395,15 @@ ptrdiff_t url_encode(const char[] data, char[] result) pure if (j + 2 == result.length) return -1; result[j++] = '%'; - result[j++] = hexDigits[c >> 4]; - result[j++] = hexDigits[c & 0xF]; + result[j++] = hex_digits[c >> 4]; + result[j++] = hex_digits[c & 0xF]; } } return j; } -ptrdiff_t url_decode_length(const char[] data) pure +size_t url_decode_length(const char[] data) pure { size_t len = 0; for (size_t i = 0; i < data.length;) @@ -250,7 +419,7 @@ ptrdiff_t url_decode_length(const char[] data) pure ptrdiff_t url_decode(const char[] data, char[] result) pure { - import urt.string.ascii : isHex; + import urt.string.ascii : is_hex; size_t j = 0; for (size_t i = 0; i < data.length; ++i) @@ -268,7 +437,7 @@ ptrdiff_t url_decode(const char[] data, char[] result) pure ubyte c0 = data[i + 1]; ubyte c1 = data[i + 2]; - if (!c0.isHex || !c1.isHex) + if (!c0.is_hex || !c1.is_hex) return -1; i += 2; @@ -290,6 +459,8 @@ ptrdiff_t url_decode(const char[] data, char[] result) pure unittest { + static assert(URLDecode!"Hello%2C+World%21" == "Hello, World!"); + char[13] data = "Hello, World!"; char[17] encoded = void; char[13] decoded = void; @@ -308,10 +479,19 @@ unittest private: __gshared immutable char[64] base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -__gshared immutable ubyte[80] base64_map = [ 62, 0, 0, 0, 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 64, 0, 0, - 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, - 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, +__gshared immutable ubyte[80] base64_map = [ 62, 0, 0, 0, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 64, 0, 0, + 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, + 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 +]; + +__gshared immutable char[64] base64url = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; +__gshared immutable ubyte[78] base64url_map = [ 62, 0, 0, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 63, + 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 ]; diff --git a/src/urt/endian.d b/src/urt/endian.d index e76f671..904eb2d 100644 --- a/src/urt/endian.d +++ b/src/urt/endian.d @@ -4,20 +4,20 @@ import urt.processor; import urt.traits; public import urt.processor : LittleEndian; -public import urt.util : byteReverse; +public import urt.util : byte_reverse; pure nothrow @nogc: // load from byte arrays pragma(inline, true) T endianToNative(T, bool little)(ref const ubyte[1] bytes) - if (T.sizeof == 1 && isIntegral!T) + if (T.sizeof == 1 && is_integral!T) { return cast(T)bytes[0]; } ushort endianToNative(T, bool little)(ref const ubyte[2] bytes) - if (T.sizeof == 2 && isIntegral!T) + if (T.sizeof == 2 && is_integral!T) { if (__ctfe || !SupportUnalignedLoadStore) { @@ -33,12 +33,12 @@ ushort endianToNative(T, bool little)(ref const ubyte[2] bytes) static if (LittleEndian == little) return *cast(ushort*)bytes.ptr; else - return byteReverse(*cast(ushort*)bytes.ptr); + return byte_reverse(*cast(ushort*)bytes.ptr); } } uint endianToNative(T, bool little)(ref const ubyte[4] bytes) - if (T.sizeof == 4 && isIntegral!T) + if (T.sizeof == 4 && is_integral!T) { if (__ctfe || !SupportUnalignedLoadStore) { @@ -54,20 +54,20 @@ uint endianToNative(T, bool little)(ref const ubyte[4] bytes) static if (LittleEndian == little) return *cast(uint*)bytes.ptr; else - return byteReverse(*cast(uint*)bytes.ptr); + return byte_reverse(*cast(uint*)bytes.ptr); } } ulong endianToNative(T, bool little)(ref const ubyte[8] bytes) - if (T.sizeof == 8 && isIntegral!T) + if (T.sizeof == 8 && is_integral!T) { if (__ctfe || !SupportUnalignedLoadStore) { // ctfe can't do the memory reinterpreting static if (little) - return cast(T)(bytes[0] | bytes[1] << 8 | bytes[2] << 16 | bytes[3] << 24 | cast(ulong)bytes[4] << 32 | cast(ulong)bytes[5] << 40 | cast(ulong)bytes[6] << 48 | cast(ulong)bytes[7] << 56); + return cast(T)(bytes[0] | bytes[1] << 8 | bytes[2] << 16 | ulong(bytes[3]) << 24 | ulong(bytes[4]) << 32 | ulong(bytes[5]) << 40 | ulong(bytes[6]) << 48 | ulong(bytes[7]) << 56); else - return cast(T)(cast(ulong)bytes[0] << 56 | cast(ulong)bytes[1] << 48 | cast(ulong)bytes[2] << 40 | cast(ulong)bytes[3] << 32 | bytes[4] << 24 | bytes[5] << 16 | bytes[6] << 8 | bytes[7]); + return cast(T)(ulong(bytes[0]) << 56 | ulong(bytes[1]) << 48 | ulong(bytes[2]) << 40 | ulong(bytes[3]) << 32 | ulong(bytes[4]) << 24 | bytes[5] << 16 | bytes[6] << 8 | bytes[7]); } static if (SupportUnalignedLoadStore) { @@ -75,15 +75,15 @@ ulong endianToNative(T, bool little)(ref const ubyte[8] bytes) static if (LittleEndian == little) return *cast(ulong*)bytes.ptr; else - return byteReverse(*cast(ulong*)bytes.ptr); + return byte_reverse(*cast(ulong*)bytes.ptr); } } pragma(inline, true) T endianToNative(T, bool little)(ref const ubyte[T.sizeof] bytes) - if (!isIntegral!T && !is(T == struct) && !is(T == U[N], U, size_t N)) + if (!is_integral!T && !is(T == struct) && !is(T == U[N], U, size_t N)) { - import urt.meta : intForWidth; - alias U = intForWidth!(T.sizeof*8); + import urt.meta : IntForWidth; + alias U = IntForWidth!(T.sizeof*8); U u = endianToNative!(U, little)(bytes); return *cast(T*)&u; } @@ -96,12 +96,12 @@ T endianToNative(T, bool little)(ref const ubyte[T.sizeof] bytes) static assert(!is(U == class) && !is(U == interface) && !is(U == V*, V), T.stringof ~ " is not POD"); static if (U.sizeof == 1) - r = *cast(T*)&bytes; + return *cast(T*)&bytes; else { T r; - for (size_t i = 0, j = 0; i < N; ++i, j += T.sizeof) - r[i] = endianToNative!(U, little)(bytes.ptr[j .. j + T.sizeof][0 .. T.sizeof]); + for (size_t i = 0, j = 0; i < N; ++i, j += U.sizeof) + r[i] = endianToNative!(U, little)(bytes.ptr[j .. j + U.sizeof][0 .. U.sizeof]); return r; } } @@ -156,7 +156,7 @@ ubyte[2] nativeToEndian(bool little)(ushort u) static if (SupportUnalignedLoadStore) { static if (LittleEndian != little) - u = byteReverse(u); + u = byte_reverse(u); else pragma(inline, true); return *cast(ubyte[2]*)&u; @@ -176,7 +176,7 @@ ubyte[4] nativeToEndian(bool little)(uint u) static if (SupportUnalignedLoadStore) { static if (LittleEndian != little) - u = byteReverse(u); + u = byte_reverse(u); else pragma(inline, true); return *cast(ubyte[4]*)&u; @@ -196,7 +196,7 @@ ubyte[8] nativeToEndian(bool little)(ulong u) static if (SupportUnalignedLoadStore) { static if (LittleEndian != little) - u = byteReverse(u); + u = byte_reverse(u); else pragma(inline, true); return *cast(ubyte[8]*)&u; @@ -204,12 +204,11 @@ ubyte[8] nativeToEndian(bool little)(ulong u) } pragma(inline, true) auto nativeToEndian(bool little, T)(T val) - if (!isIntegral!T && !is(T == struct) && !is(T == U[N], U, size_t N)) + if (!is_integral!T && !is(T == struct) && !is(T == U[N], U, size_t N)) { - import urt.meta : intForWidth; - alias U = intForWidth!(T.sizeof*8); - U r = nativeToEndian!little(*cast(U*)&val); - return *cast(T*)&r; + import urt.meta : IntForWidth; + alias U = IntForWidth!(T.sizeof*8); + return nativeToEndian!little(*cast(U*)&val); } ubyte[T.sizeof] nativeToEndian(bool little, T)(auto ref const T data) @@ -261,36 +260,36 @@ ubyte[T.sizeof] nativeToLittleEndian(T)(auto ref const T data) // load/store from/to memory void storeBigEndian(T)(T* target, const T val) - if (isSomeInt!T || is(T == float)) + if (is_some_int!T || is(T == float) || is(T == double)) { version (BigEndian) *target = val; else - *target = byteReverse(val); + *target = byte_reverse(val); } void storeLittleEndian(T)(T* target, const T val) - if (isSomeInt!T || is(T == float)) + if (is_some_int!T || is(T == float) || is(T == double)) { version (LittleEndian) *target = val; else - *target = byteReverse(val); + *target = byte_reverse(val); } T loadBigEndian(T)(const(T)* src) - if (isSomeInt!T || is(T == float)) + if (is_some_int!T || is(T == float) || is(T == double)) { version (BigEndian) return *src; else - return byteReverse(*src); + return byte_reverse(*src); } T loadLittleEndian(T)(const(T)* src) - if (isSomeInt!T || is(T == float)) + if (is_some_int!T || is(T == float) || is(T == double)) { version (LittleEndian) return *src; else - return byteReverse(*src); + return byte_reverse(*src); } diff --git a/src/urt/exception.d b/src/urt/exception.d new file mode 100644 index 0000000..9740307 --- /dev/null +++ b/src/urt/exception.d @@ -0,0 +1,108 @@ +/// Assert handler registration for uRT. +module urt.exception; + +import urt.attribute : noinline; + +nothrow @nogc: + + +alias AssertHandler = void function(string file, size_t line, string msg) nothrow @nogc; + +AssertHandler assert_handler() @property nothrow @nogc @trusted + => _assert_handler; + +void assert_handler(AssertHandler handler) @property nothrow @nogc @trusted +{ + if (handler is null) + _assert_handler = &urt_assert; + else + _assert_handler = handler; +} + + +private: + +__gshared AssertHandler _assert_handler = &urt_assert; + +@noinline +void urt_assert(string file, size_t line, string msg) nothrow @nogc +{ + if (msg.length == 0) + msg = "Assertion failed"; + + version (BareMetal) + { + import urt.driver.uart : uart0_puts; + import urt.internal.exception : capture_trace; + import urt.mem.temp : tconcat; + + uart0_puts(tconcat("\n*** ASSERT: ", msg, " at ", file, ':', line, '\n')); + + // Skip frame[0] -- with capture_trace as a real frame (defeat_tco), + // its saved ra points back into urt_assert itself, which is noise. + // Frame[1] is the assert site inside the calling function. + void*[16] addrs = void; + const n = capture_trace(addrs[]); + if (n > 1) + { + uart0_puts("Backtrace (resolve with addr2line):\n"); + enum digits = size_t.sizeof * 2; + char[4 + digits + 1] hex_buf = void; + hex_buf[0 .. 4] = " 0x"; + hex_buf[$ - 1] = '\n'; + foreach (addr; addrs[1 .. n]) + { + size_t v = cast(size_t) addr; + foreach_reverse (j; 4 .. 4 + digits) + { + const ubyte nib = v & 0xF; + hex_buf[j] = cast(char)(nib < 10 ? '0' + nib : 'a' + nib - 10); + v >>= 4; + } + uart0_puts(hex_buf[]); + } + } + + while (true) {} + } + else version (Espressif) + { + import urt.io : writef_to, WriteTarget; + writef_to!(WriteTarget.stdout, true)("*** ASSERT: {2} at {0}:{1}", file, line, msg); + import urt.internal.stdc.stdlib : exit; + exit(-1); + } + else + { + debug + { + import urt.io : write_to, WriteTarget; + import urt.dbg; + import urt.internal.exception : capture_trace, print_trace; + + version (Windows) + write_to!(WriteTarget.debugstring, true)(file, '(', line, "): ", msg); + + // an assert fired from the print/resolve machinery below must not recurse. + __gshared bool in_assert; + if (!in_assert) + { + in_assert = true; + write_to!(WriteTarget.stderr, true)("*** ASSERT: ", file, '(', line, "): ", msg); + + void*[32] addrs = void; + const n = capture_trace(addrs[]); + if (n > 1) + print_trace(addrs[1 .. n]); + in_assert = false; + } + + breakpoint(); + } + else + { + import urt.internal.stdc.stdlib : exit; + exit(-1); + } + } +} diff --git a/src/urt/fibre.d b/src/urt/fibre.d index 574e551..535acec 100644 --- a/src/urt/fibre.d +++ b/src/urt/fibre.d @@ -2,7 +2,7 @@ module urt.fibre; import urt.mem; import urt.time; -import urt.util : isAligned, max; +import urt.util : is_aligned, max; version (Windows) version = UseWindowsFibreAPI; @@ -37,24 +37,24 @@ alias YieldHandler = ResumeHandler function(ref Fibre yielding, AwakenEvent awak struct Fibre { -@nogc: +nothrow @nogc: this() @disable; this(ref typeof(this)) @disable; // disable copy this(typeof(this)) @disable; // disable move - this(size_t stackSize) nothrow + this(size_t stackSize) { if (!mainFibre) mainFibre = co_active(); // TODO: i think it's a bug that this stuff isn't initialised! - isDelegate = false; + is_delegate = false; abortRequested = false; finished = true; // init in a state ready to be recycled... aborted = false; - static void fibreFunc() + static void fibreFunc() nothrow { import urt.system : abort; @@ -62,7 +62,7 @@ struct Fibre while (true) { try { - if (thisFibre.isDelegate) + if (thisFibre.is_delegate) { FibreEntryDelegate dg; dg.ptr = thisFibre.userData; @@ -84,6 +84,8 @@ struct Fibre } catch (Throwable e) { + import urt.io; + writef_to!(WriteTarget.stderr, true)("abort: {0}:{1} - {2}", e.file, e.line, e.msg); abort(); } @@ -100,14 +102,14 @@ struct Fibre fibre = co_create(stackSize, &fibreFunc, &this); } - this(FibreEntryDelegate fibreEntry, YieldHandler yieldHandler, size_t stackSize = DefaultStackSize) nothrow + this(FibreEntryDelegate fibreEntry, YieldHandler yieldHandler, size_t stackSize = DefaultStackSize) { this(cast(FibreEntryFunc)fibreEntry.funcptr, yieldHandler, fibreEntry.ptr, stackSize); - isDelegate = true; + is_delegate = true; } - this(FibreEntryFunc fibreEntry, YieldHandler yieldHandler, void* userData = null, size_t stackSize = DefaultStackSize) nothrow + this(FibreEntryFunc fibreEntry, YieldHandler yieldHandler, void* userData = null, size_t stackSize = DefaultStackSize) { this(stackSize); @@ -118,7 +120,7 @@ struct Fibre finished = false; } - ~this() nothrow + ~this() { assert(co_active() != fibre, "Can't delete the current fibre!"); @@ -131,12 +133,12 @@ struct Fibre co_delete(fibre); } - void resume() nothrow + void resume() { co_switch(fibre); } - void abort() nothrow + void abort() { assert(co_active() == mainFibre, "Can't abort when active; use urt.fibre.abort() instead."); @@ -145,31 +147,31 @@ struct Fibre co_switch(fibre); } - void recycle(FibreEntryDelegate fibreEntry) pure nothrow + void recycle(FibreEntryDelegate fibreEntry) pure { assert(isFinished(), "Can't recycle a fibre that hasn't finished yet!"); this.fibreEntry = cast(FibreEntryFunc)fibreEntry.funcptr; userData = fibreEntry.ptr; - isDelegate = true; + is_delegate = true; abortRequested = false; finished = false; aborted = false; } - void recycle(FibreEntryFunc fibreEntry, void* userData = null) pure nothrow + void recycle(FibreEntryFunc fibreEntry, void* userData = null) pure { assert(isFinished(), "Can't recycle a fibre that hasn't finished yet!"); this.fibreEntry = fibreEntry; this.userData = userData; - isDelegate = false; + is_delegate = false; abortRequested = false; finished = false; aborted = false; } - void reset() pure nothrow + void reset() pure { assert(isFinished(), "Can't restart a fibre that hasn't finished yet!"); @@ -178,13 +180,13 @@ struct Fibre aborted = false; } - bool isFinished() const pure nothrow + bool isFinished() const pure => finished; - bool wasAborted() const pure nothrow + bool wasAborted() const pure => aborted; - size_t stackSize() const pure nothrow + size_t stackSize() const pure { assert(fibre, "Fibre not created!"); auto fdata = co_get_fibre_data(fibre); @@ -198,7 +200,7 @@ private: YieldHandler yieldHandler; cothread_t fibre; - bool isDelegate; + bool is_delegate; bool abortRequested; bool finished; bool aborted; @@ -291,7 +293,7 @@ class AbortException : Exception } } -void* mainFibre = null; +__gshared void* mainFibre = null; AbortException abortException; @@ -337,95 +339,13 @@ unittest //------------------------------------------- nothrow: -alias cothread_t = void*; -alias coentry_t = void function() @nogc; +package alias cothread_t = void*; +package alias coentry_t = void function() nothrow @nogc; version (UseWindowsFibreAPI) -{ - import core.sys.windows.winbase; - - version (X86_64) - { - import urt.system : NT_TIB, __readgsqword; - - void* GetCurrentFiber() - => cast(void*)__readgsqword(NT_TIB.FiberData.offsetof); - - void* GetFiberData() - => *cast(void**)__readgsqword(NT_TIB.FiberData.offsetof); - } - else version (X86) - { - import urt.system : NT_TIB, __readfsdword; - - void* GetCurrentFiber() - => cast(void*)__readfsdword(NT_TIB.FiberData.offsetof); - - void* GetFiberData() - => *cast(void**)__readfsdword(NT_TIB.FiberData.offsetof); - } - - struct co_fibre_data - { - void* fiber; - void* user_data; - uint stack_size; - coentry_t coentry; - } - co_fibre_data thread_fiber_data; - - private inout(co_fibre_data)* co_get_fibre_data(inout cothread_t fibre) pure - => cast(co_fibre_data*)fibre; - - cothread_t co_active() - { - if(!thread_fiber_data.fiber) - thread_fiber_data.fiber = ConvertThreadToFiber(&thread_fiber_data); - return GetFiberData(); - } - - void* co_data() - => (cast(co_fibre_data*)GetFiberData()).user_data; - - cothread_t co_derive(void[] memory, coentry_t entry, void* data) - { - // Windows fibers do not allow users to supply their own memory - return null; - } - - cothread_t co_create(size_t stack_size, coentry_t entry, void* data) - { - assert(stack_size <= uint.max, "Stack size too large"); - - co_active(); - - extern(Windows) static void co_thunk(void* codata) - { - (cast(co_fibre_data*)codata).coentry(); - assert(false, "Error: returned from fibre!"); - } - - auto fdata = defaultAllocator().allocT!co_fibre_data(); - fdata.user_data = data; - fdata.coentry = entry; - fdata.stack_size = cast(uint)stack_size; - fdata.fiber = CreateFiber(stack_size, &co_thunk, fdata); - return fdata; - } - - void co_delete(cothread_t cothread) - { - auto fdata = cast(co_fibre_data*)cothread; - DeleteFiber(fdata.fiber); - defaultAllocator().freeT(fdata); - } - - void co_switch(cothread_t cothread) - { - auto fdata = cast(co_fibre_data*)cothread; - SwitchToFiber(fdata.fiber); - } -} + public import urt.driver.windows.fibre; +else version (FreeRTOS) + public import urt.driver.freertos.fibre; else { align(16) struct co_fibre_data @@ -570,7 +490,7 @@ else void co_init_stack(void* base, void* top, coentry_t entry) { - assert(isAligned!16(base) && isAligned!16(top), "Stack must be aligned to 16 bytes"); + assert(is_aligned!16(base) && is_aligned!16(top), "Stack must be aligned to 16 bytes"); void** sp = cast(void**)top; // seek to top of stack *--sp = &crash; // crash if entrypoint returns @@ -741,7 +661,7 @@ else void co_init_stack(void* base, void* top, coentry_t entry) { - assert(isAligned!16(base) && isAligned!16(top), "Stack must be aligned to 16 bytes"); + assert(is_aligned!16(base) && is_aligned!16(top), "Stack must be aligned to 16 bytes"); void** p = cast(void**)base; p[8] = cast(void*)top; // starting sp @@ -751,10 +671,13 @@ else pragma(inline, false) extern(C) void co_swap(cothread_t newCtx, cothread_t oldCtx) @naked { - // just for thumb-1, thumb-2 can to the 32bit thing below.. somehow... apparently...? + // thumb-mode: compiler is generating Thumb instructions (Cortex-M micros) + // thumb2: ISA supports Thumb-2 (true for both Cortex-M4+ and Cortex-A7+) + // We check thumb (active mode), not thumb2 (capability), to avoid + // using the Thumb path on full ARM cores that can use stmia with sp. static if (ProcFeatures.thumb && !ProcFeatures.thumb2) { - static assert(false, "TODO: this needs to be tested somehow... thumb instructions are offset by 1 byte."); + static assert(false, "TODO: Thumb-1 context switch needs testing"); asm nothrow @nogc { ` @@ -776,7 +699,29 @@ else ldmia r0!, {r4-r7} ldmia r1!, {pc} ` - // bx lr ; TODO: why is this even here? the prior instruction loads `pc`... maybe it's a hint to the branch predictor? +// bx lr ; TODO: why is this even here? the prior instruction loads `pc`... maybe it's a hint to the branch predictor? + : // no outputs + : // "r"(newCtx), "r"(oldCtx) // function is @naked, so the ABI takes care of this + : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "sp", "lr", "memory"; + } + } + else static if (ProcFeatures.thumb) + { + // Thumb mode (Cortex-M): SP cannot appear in stm/ldm register lists. + // Layout: [r4..r11](0-28), [sp](32), [lr/pc](36) - matches co_init_stack + asm nothrow @nogc + { + ` + stmia r1!, {r4-r11} + mov r2, sp + str r2, [r1] + str lr, [r1, #4] + ldmia r0!, {r4-r11} + ldr r2, [r0] + ldr r3, [r0, #4] + mov sp, r2 + bx r3 + ` : // no outputs : // "r"(newCtx), "r"(oldCtx) // function is @naked, so the ABI takes care of this : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "sp", "lr", "memory"; @@ -784,6 +729,7 @@ else } else { + // ARM mode: SP can appear in stm/ldm asm nothrow @nogc { ` @@ -804,7 +750,7 @@ else void co_init_stack(void* base, void* top, coentry_t entry) { - assert(isAligned!16(base) && isAligned!16(top), "Stack must be aligned to 16 bytes"); + assert(is_aligned!16(base) && is_aligned!16(top), "Stack must be aligned to 16 bytes"); void** p = cast(void**)base; p[0] = cast(void*)top; // x16 (stack pointer) @@ -850,6 +796,350 @@ else } } } + else version (RISCV64) + { + // RISC-V 64-bit: callee-saved sp, ra, s0-s11 (14 regs × 8 bytes) + // With D extension: also fs0-fs11 (12 regs × 8 bytes) + version (D_HardFloat) + enum SaveStateLen = 26; // 14 integer + 12 FP + else + enum SaveStateLen = 14; + + void co_init_stack(void* base, void* top, coentry_t entry) + { + assert(is_aligned!16(base) && is_aligned!16(top), "Stack must be aligned to 16 bytes"); + + void** p = cast(void**)base; + p[0] = cast(void*)top; // starting sp + p[1] = entry; // starting ra (entry point) + p[2] = cast(void*)top; // starting s0 (frame pointer) + } + + version (D_HardFloat) + { + pragma(inline, false) + extern(C) void co_swap(cothread_t newCtx, cothread_t oldCtx) @naked + { + asm nothrow @nogc + { + ` + sd sp, 0(a1) + sd ra, 8(a1) + sd s0, 16(a1) + sd s1, 24(a1) + sd s2, 32(a1) + sd s3, 40(a1) + sd s4, 48(a1) + sd s5, 56(a1) + sd s6, 64(a1) + sd s7, 72(a1) + sd s8, 80(a1) + sd s9, 88(a1) + sd s10, 96(a1) + sd s11, 104(a1) + fsd fs0, 112(a1) + fsd fs1, 120(a1) + fsd fs2, 128(a1) + fsd fs3, 136(a1) + fsd fs4, 144(a1) + fsd fs5, 152(a1) + fsd fs6, 160(a1) + fsd fs7, 168(a1) + fsd fs8, 176(a1) + fsd fs9, 184(a1) + fsd fs10, 192(a1) + fsd fs11, 200(a1) + ld sp, 0(a0) + ld s0, 16(a0) + ld s1, 24(a0) + ld s2, 32(a0) + ld s3, 40(a0) + ld s4, 48(a0) + ld s5, 56(a0) + ld s6, 64(a0) + ld s7, 72(a0) + ld s8, 80(a0) + ld s9, 88(a0) + ld s10, 96(a0) + ld s11, 104(a0) + fld fs0, 112(a0) + fld fs1, 120(a0) + fld fs2, 128(a0) + fld fs3, 136(a0) + fld fs4, 144(a0) + fld fs5, 152(a0) + fld fs6, 160(a0) + fld fs7, 168(a0) + fld fs8, 176(a0) + fld fs9, 184(a0) + fld fs10, 192(a0) + fld fs11, 200(a0) + ld ra, 8(a0) + ret + ` + : // no outputs + : // a0=newCtx, a1=oldCtx (@naked, ABI handles register assignment) + : "memory"; + } + } + } + else + { + pragma(inline, false) + extern(C) void co_swap(cothread_t newCtx, cothread_t oldCtx) @naked + { + asm nothrow @nogc + { + ` + sd sp, 0(a1) + sd ra, 8(a1) + sd s0, 16(a1) + sd s1, 24(a1) + sd s2, 32(a1) + sd s3, 40(a1) + sd s4, 48(a1) + sd s5, 56(a1) + sd s6, 64(a1) + sd s7, 72(a1) + sd s8, 80(a1) + sd s9, 88(a1) + sd s10, 96(a1) + sd s11, 104(a1) + ld sp, 0(a0) + ld s0, 16(a0) + ld s1, 24(a0) + ld s2, 32(a0) + ld s3, 40(a0) + ld s4, 48(a0) + ld s5, 56(a0) + ld s6, 64(a0) + ld s7, 72(a0) + ld s8, 80(a0) + ld s9, 88(a0) + ld s10, 96(a0) + ld s11, 104(a0) + ld ra, 8(a0) + ret + ` + : // no outputs + : // a0=newCtx, a1=oldCtx (@naked, ABI handles register assignment) + : "memory"; + } + } + } + } + else version (RISCV32) + { + // SaveStateLen must be defined before co_active_buffer (line 444) + version (RISCV32E) + enum SaveStateLen = 4; // RV32E: sp, ra, s0-s1 + else version (D_HardFloat) + enum SaveStateLen = 26; // RV32I: 14 integer + 12 FP + else + enum SaveStateLen = 14; // RV32I: sp, ra, s0-s11 + + version (RISCV32E) + { + void co_init_stack(void* base, void* top, coentry_t entry) + { + assert(is_aligned!16(base) && is_aligned!16(top), "Stack must be aligned to 16 bytes"); + + void** p = cast(void**)base; + p[0] = cast(void*)top; // starting sp + p[1] = entry; // starting ra (entry point) + p[2] = cast(void*)top; // starting s0 (frame pointer) + } + + pragma(inline, false) + extern(C) void co_swap(cothread_t newCtx, cothread_t oldCtx) @naked + { + asm nothrow @nogc + { + ` + sw sp, 0(a1) + sw ra, 4(a1) + sw s0, 8(a1) + sw s1, 12(a1) + lw sp, 0(a0) + lw s0, 8(a0) + lw s1, 12(a0) + lw ra, 4(a0) + ret + ` + : // no outputs + : // a0=newCtx, a1=oldCtx (@naked, ABI handles register assignment) + : "memory"; + } + } + } + else + { + + void co_init_stack(void* base, void* top, coentry_t entry) + { + assert(is_aligned!16(base) && is_aligned!16(top), "Stack must be aligned to 16 bytes"); + + void** p = cast(void**)base; + p[0] = cast(void*)top; // starting sp + p[1] = entry; // starting ra (entry point) + p[2] = cast(void*)top; // starting s0 (frame pointer) + } + + version (D_HardFloat) + { + pragma(inline, false) + extern(C) void co_swap(cothread_t newCtx, cothread_t oldCtx) @naked + { + asm nothrow @nogc + { + ` + sw sp, 0(a1) + sw ra, 4(a1) + sw s0, 8(a1) + sw s1, 12(a1) + sw s2, 16(a1) + sw s3, 20(a1) + sw s4, 24(a1) + sw s5, 28(a1) + sw s6, 32(a1) + sw s7, 36(a1) + sw s8, 40(a1) + sw s9, 44(a1) + sw s10, 48(a1) + sw s11, 52(a1) + fsw fs0, 56(a1) + fsw fs1, 60(a1) + fsw fs2, 64(a1) + fsw fs3, 68(a1) + fsw fs4, 72(a1) + fsw fs5, 76(a1) + fsw fs6, 80(a1) + fsw fs7, 84(a1) + fsw fs8, 88(a1) + fsw fs9, 92(a1) + fsw fs10, 96(a1) + fsw fs11, 100(a1) + lw sp, 0(a0) + lw s0, 8(a0) + lw s1, 12(a0) + lw s2, 16(a0) + lw s3, 20(a0) + lw s4, 24(a0) + lw s5, 28(a0) + lw s6, 32(a0) + lw s7, 36(a0) + lw s8, 40(a0) + lw s9, 44(a0) + lw s10, 48(a0) + lw s11, 52(a0) + flw fs0, 56(a0) + flw fs1, 60(a0) + flw fs2, 64(a0) + flw fs3, 68(a0) + flw fs4, 72(a0) + flw fs5, 76(a0) + flw fs6, 80(a0) + flw fs7, 84(a0) + flw fs8, 88(a0) + flw fs9, 92(a0) + flw fs10, 96(a0) + flw fs11, 100(a0) + lw ra, 4(a0) + ret + ` + : // no outputs + : // a0=newCtx, a1=oldCtx (@naked, ABI handles register assignment) + : "memory"; + } + } + } + else + { + pragma(inline, false) + extern(C) void co_swap(cothread_t newCtx, cothread_t oldCtx) @naked + { + asm nothrow @nogc + { + ` + sw sp, 0(a1) + sw ra, 4(a1) + sw s0, 8(a1) + sw s1, 12(a1) + sw s2, 16(a1) + sw s3, 20(a1) + sw s4, 24(a1) + sw s5, 28(a1) + sw s6, 32(a1) + sw s7, 36(a1) + sw s8, 40(a1) + sw s9, 44(a1) + sw s10, 48(a1) + sw s11, 52(a1) + lw sp, 0(a0) + lw s0, 8(a0) + lw s1, 12(a0) + lw s2, 16(a0) + lw s3, 20(a0) + lw s4, 24(a0) + lw s5, 28(a0) + lw s6, 32(a0) + lw s7, 36(a0) + lw s8, 40(a0) + lw s9, 44(a0) + lw s10, 48(a0) + lw s11, 52(a0) + lw ra, 4(a0) + ret + ` + : // no outputs + : // a0=newCtx, a1=oldCtx (@naked, ABI handles register assignment) + : "memory"; + } + } + } + } + } + else version (Xtensa) + { + // Xtensa call0 ABI: callee-saved a0 (return addr), a1 (sp), a12-a15 + // TODO: if windowed ABI is used, need register window spill (entry/retw) + enum SaveStateLen = 6; + + void co_init_stack(void* base, void* top, coentry_t entry) + { + assert(is_aligned!16(base) && is_aligned!16(top), "Stack must be aligned to 16 bytes"); + + void** p = cast(void**)base; + p[0] = cast(void*)top; // starting a1 (sp) + p[1] = entry; // starting a0 (return address) + } + + pragma(inline, false) + extern(C) void co_swap(cothread_t newCtx, cothread_t oldCtx) @naked + { + asm nothrow @nogc + { + ` + s32i a1, a3, 0 + s32i a0, a3, 4 + s32i a12, a3, 8 + s32i a13, a3, 12 + s32i a14, a3, 16 + s32i a15, a3, 20 + l32i a1, a2, 0 + l32i a12, a2, 8 + l32i a13, a2, 12 + l32i a14, a2, 16 + l32i a15, a2, 20 + l32i a0, a2, 4 + ret + ` + : // no outputs + : // a2=newCtx, a3=oldCtx (@naked, call0 ABI) + : "memory"; + } + } + } else static assert(false, "TODO: implement for other architectures!"); } diff --git a/src/urt/file.d b/src/urt/file.d index e7ec4d3..94c3af4 100644 --- a/src/urt/file.d +++ b/src/urt/file.d @@ -12,10 +12,10 @@ alias SystemTime = void; version(Windows) { - import core.sys.windows.winbase; - import core.sys.windows.windows; - import core.sys.windows.windef : MAX_PATH; - import core.sys.windows.winnt; + import urt.internal.sys.windows.winbase; + import urt.internal.sys.windows; + import urt.internal.sys.windows.windef : MAX_PATH; + import urt.internal.sys.windows.winnt; import urt.string : twstringz; // TODO: remove this when LDC/GDC are up to date... @@ -26,12 +26,8 @@ version(Windows) } else version (Posix) { - import core.stdc.errno; - import core.sys.posix.dirent; - import core.sys.posix.fcntl; - import core.sys.posix.stdlib; - import core.sys.posix.sys.stat; - import core.sys.posix.unistd; + import urt.internal.sys.posix; + import urt.internal.stdc.errno; import urt.mem.temp : tconcat; import urt.string : tstringz; @@ -43,6 +39,11 @@ else version (Posix) enum POSIX_FADV_RANDOM = 1; enum POSIX_FADV_SEQUENTIAL = 2; extern(C) int posix_fadvise(int fd, off_t offset, off_t len, int advice) nothrow @nogc; + extern(C) int rename(scope const char*, scope const char*) nothrow @nogc; +} +else version (FreeStanding) +{ + // No filesystem on bare-metal } else { @@ -107,8 +108,10 @@ struct File void* handle = INVALID_HANDLE_VALUE; else version (Posix) int fd = -1; + else version (FreeStanding) + int fd = -1; else - static assert(0, "Not implemented"); + static assert(0, "File: not implemented for this platform"); } bool file_exists(const(char)[] path) @@ -120,12 +123,11 @@ bool file_exists(const(char)[] path) } else version (Posix) { - import core.sys.posix.sys.stat; stat_t st; return stat(path.tstringz, &st) == 0 && S_ISREG(st.st_mode); } else - static assert(0, "Not implemented"); + return false; } Result delete_file(const(char)[] path) @@ -133,17 +135,17 @@ Result delete_file(const(char)[] path) version (Windows) { if (!DeleteFileW(path.twstringz)) - return Win32Result(GetLastError()); + return getlasterror_result(); } else version (Posix) { if (unlink(path.tstringz) == -1) - return PosixResult(errno); + return errno_result(); } else - static assert(0, "Not implemented"); + return InternalResult.unsupported; // no filesystem on this platform - return Result.Success; + return Result.success; } Result rename_file(const(char)[] oldPath, const(char)[] newPath) @@ -151,18 +153,17 @@ Result rename_file(const(char)[] oldPath, const(char)[] newPath) version (Windows) { if (!MoveFileW(oldPath.twstringz, newPath.twstringz)) - return Win32Result(GetLastError()); + return getlasterror_result(); } else version (Posix) { - import core.sys.posix.stdio; - if (int result = rename(oldPath.tstringz, newPath.tstringz)!= 0) - return PosixResult(result); + if (int result = rename(oldPath.tstringz, newPath.tstringz) != 0) + return posix_result(result); } else - static assert(0, "Not implemented"); + return InternalResult.unsupported; // no filesystem on this platform - return Result.Success; + return Result.success; } Result copy_file(const(char)[] oldPath, const(char)[] newPath, bool overwriteExisting = false) @@ -170,7 +171,7 @@ Result copy_file(const(char)[] oldPath, const(char)[] newPath, bool overwriteExi version (Windows) { if (!CopyFileW(oldPath.twstringz, newPath.twstringz, !overwriteExisting)) - return Win32Result(GetLastError()); + return getlasterror_result(); } else version (Posix) { @@ -178,9 +179,9 @@ Result copy_file(const(char)[] oldPath, const(char)[] newPath, bool overwriteExi assert(false); } else - static assert(0, "Not implemented"); + return InternalResult.unsupported; // no filesystem on this platform - return Result.Success; + return Result.success; } Result get_path(ref const File file, ref char[] buffer) @@ -193,11 +194,11 @@ Result get_path(ref const File file, ref char[] buffer) DWORD dwPathLen = tmp.length - 1; DWORD result = GetFinalPathNameByHandleW(cast(HANDLE)file.handle, tmp.ptr, dwPathLen, FILE_NAME_OPENED); if (result == 0 || result > dwPathLen) - return Win32Result(GetLastError()); + return getlasterror_result(); - size_t pathLen = tmp[0..result].uniConvert(buffer); + size_t pathLen = tmp[0..result].uni_convert(buffer); if (!pathLen) - return InternalResult(InternalCode.BufferTooSmall); + return InternalResult.buffer_too_small; if (buffer.length >= 4 && buffer[0..4] == `\\?\`) buffer = buffer[4..pathLen]; else @@ -210,10 +211,10 @@ Result get_path(ref const File file, ref char[] buffer) char[PATH_MAX] src = void; int r = fcntl(file.fd, F_GETPATH, src.ptr); if (r == -1) - return PosixResult(errno); + return errno_result(); size_t l = strlen(src.ptr); if (l > buffer.length) - return InternalResult(InternalCode.BufferTooSmall); + return InternalResult.buffer_too_small; buffer[0..l] = src[0..l]; buffer = buffer[0..l]; } @@ -221,18 +222,18 @@ Result get_path(ref const File file, ref char[] buffer) { ptrdiff_t r = readlink(tconcat("/proc/self/fd/", file.fd, '\0').ptr, buffer.ptr, buffer.length); if (r == -1) - return PosixResult(errno); + return errno_result(); if (r == buffer.length) { // TODO: if r == buffer.length, truncation MAY have occurred, but also maybe not... // is there any way to fix this? for now, we'll just assume it did and return an error - return InternalResult(InternalCode.BufferTooSmall); + return InternalResult.buffer_too_small; } buffer = buffer[0..r]; } else - static assert(0, "Not implemented"); - return Result.Success; + return InternalResult.unsupported; // no filesystem on this platform + return Result.success; } Result set_file_times(ref File file, const SystemTime* createTime, const SystemTime* accessTime, const SystemTime* writeTime); @@ -243,7 +244,7 @@ Result get_file_attributes(const(char)[] path, out FileAttributes outAttributes) { WIN32_FILE_ATTRIBUTE_DATA attrData = void; if (!GetFileAttributesExW(path.twstringz, GET_FILEEX_INFO_LEVELS.GetFileExInfoStandard, &attrData)) - return Win32Result(GetLastError()); + return getlasterror_result(); outAttributes.attributes = FileAttributeFlag.None; if ((attrData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) == FILE_ATTRIBUTE_HIDDEN) @@ -268,9 +269,9 @@ Result get_file_attributes(const(char)[] path, out FileAttributes outAttributes) assert(false); } else - static assert(0, "Not implemented"); + return InternalResult.unsupported; // no filesystem on this platform - return Result.Success; + return Result.success; } Result get_attributes(ref const File file, out FileAttributes outAttributes) @@ -282,9 +283,9 @@ Result get_attributes(ref const File file, out FileAttributes outAttributes) FILE_BASIC_INFO basicInfo = void; FILE_STANDARD_INFO standardInfo = void; if (!GetFileInformationByHandleEx(cast(HANDLE)file.handle, FILE_INFO_BY_HANDLE_CLASS.FileBasicInfo, &basicInfo, FILE_BASIC_INFO.sizeof)) - return Win32Result(GetLastError()); + return getlasterror_result(); if (!GetFileInformationByHandleEx(cast(HANDLE)file.handle, FILE_INFO_BY_HANDLE_CLASS.FileStandardInfo, &standardInfo, FILE_STANDARD_INFO.sizeof)) - return Win32Result(GetLastError()); + return getlasterror_result(); outAttributes.attributes = FileAttributeFlag.None; if ((basicInfo.FileAttributes & FILE_ATTRIBUTE_HIDDEN) == FILE_ATTRIBUTE_HIDDEN) @@ -303,7 +304,7 @@ Result get_attributes(ref const File file, out FileAttributes outAttributes) outAttributes.accessTime = SysTime(basicInfo.LastAccessTime.QuadPart); outAttributes.writeTime = SysTime(basicInfo.LastWriteTime.QuadPart); - return Result.Success; + return Result.success; +/ } else version (Posix) @@ -312,18 +313,21 @@ Result get_attributes(ref const File file, out FileAttributes outAttributes) assert(false); } else - static assert(0, "Not implemented"); + return InternalResult.unsupported; // no filesystem on this platform - return InternalResult(InternalCode.Unsupported); + return InternalResult.unsupported; } void[] load_file(const(char)[] path, NoGCAllocator allocator = defaultAllocator()) { File f; Result r = f.open(path, FileOpenMode.ReadExisting); - if (!r && r.get_FileResult == FileResult.NotFound) - return null; - assert(r, "TODO: handle error"); + if (!r) + { + if (r.file_result == FileResult.NotFound) + return null; + return null; // TODO: are there any errors we can handle? + } ulong size = f.get_size(); assert(size <= size_t.max, "File is too large"); void[] buffer = allocator.alloc(cast(size_t)size); @@ -334,6 +338,47 @@ void[] load_file(const(char)[] path, NoGCAllocator allocator = defaultAllocator( return buffer[0..bytesRead]; } +Result save_file(const(char)[] path, const(void)[] data) +{ + File f; + Result r = f.open(path, FileOpenMode.WriteTruncate); + if (!r) + return r; + size_t written; + r = f.write(data, written); + f.close(); + if (!r) + return r; + if (written != data.length) + return InternalResult.failed; + return Result.success; +} + +Result create_directory(const(char)[] path) +{ + Result r; + version (Windows) + { + if (CreateDirectoryW(path.twstringz, null)) + return Result.success; + r = getlasterror_result(); + } + else version (Posix) + { + if (!urt.internal.sys.posix.mkdir(tconcat(path, "\0").ptr, 493 /* 0755 */) != 0) + return Result.success; + r = errno_result(); + } + else + { + return InternalResult.unsupported; // no filesystem on this platform + } + + if (r == InternalResult.already_exists) + return Result.success; + return r; +} + Result open(ref File file, const(char)[] path, FileOpenMode mode, FileOpenFlags openFlags = FileOpenFlags.None) { version (Windows) @@ -379,7 +424,7 @@ Result open(ref File file, const(char)[] path, FileOpenMode mode, FileOpenFlags dwCreationDisposition = OPEN_ALWAYS; break; default: - return InternalResult(InternalCode.InvalidParameter); + return InternalResult.invalid_parameter; } uint dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; @@ -392,7 +437,7 @@ Result open(ref File file, const(char)[] path, FileOpenMode mode, FileOpenFlags file.handle = CreateFileW(path.twstringz, dwDesiredAccess, dwShareMode, null, dwCreationDisposition, dwFlagsAndAttributes, null); if (file.handle == INVALID_HANDLE_VALUE) - return Win32Result(GetLastError()); + return getlasterror_result(); if (mode == FileOpenMode.WriteAppend || mode == FileOpenMode.ReadWriteAppend) SetFilePointer(file.handle, 0, null, FILE_END); @@ -429,7 +474,7 @@ Result open(ref File file, const(char)[] path, FileOpenMode mode, FileOpenFlags flags = O_RDWR | O_APPEND | O_CREAT; break; default: - return InternalResult(InternalCode.InvalidParameter); + return InternalResult.invalid_parameter; } flags |= O_CLOEXEC; @@ -439,9 +484,9 @@ Result open(ref File file, const(char)[] path, FileOpenMode mode, FileOpenFlags flags |= O_DIRECT; } - int fd = core.sys.posix.fcntl.open(path.tstringz, flags, 0b110_110_110); + int fd = urt.internal.sys.posix.open(path.tstringz, flags, 0b110_110_110); if (fd < 0) - return PosixResult(errno); + return errno_result(); file.fd = fd; version (Darwin) { @@ -465,9 +510,9 @@ Result open(ref File file, const(char)[] path, FileOpenMode mode, FileOpenFlags lseek(file.fd, 0, SEEK_END); } else - static assert(0, "Not implemented"); + return InternalResult.unsupported; // no filesystem on this platform - return Result.Success; + return Result.success; } bool is_open(ref const File file) @@ -477,7 +522,7 @@ bool is_open(ref const File file) else version (Posix) return file.fd != -1; else - static assert(0, "Not implemented"); + return false; } void close(ref File file) @@ -493,11 +538,9 @@ void close(ref File file) { if (file.fd == -1) return; - core.sys.posix.unistd.close(file.fd); + urt.internal.sys.posix.close(file.fd); file.fd = -1; } - else - static assert(0, "Not implemented"); } ulong get_size(ref const File file) @@ -517,7 +560,7 @@ ulong get_size(ref const File file) return fs.st_size; } else - static assert(0, "Not implemented"); + return 0; } Result set_size(ref File file, ulong size) @@ -532,7 +575,7 @@ Result set_size(ref File file, ulong size) if (size > curFileSize) { if (!file.set_pos(curFileSize)) - return Win32Result(GetLastError()); + return getlasterror_result(); // zero-fill char[4096] buf = void; @@ -555,19 +598,19 @@ Result set_size(ref File file, ulong size) else { if (!file.set_pos(size)) - return Win32Result(GetLastError()); + return getlasterror_result(); if (!SetEndOfFile(file.handle)) - return Win32Result(GetLastError()); + return getlasterror_result(); } } else version (Posix) { if (ftruncate(file.fd, size)) - return PosixResult(errno); + return errno_result(); } else - static assert(0, "Not implemented"); - return Result.Success; + return InternalResult.unsupported; // no filesystem on this platform + return Result.success; } ulong get_pos(ref const File file) @@ -583,7 +626,7 @@ ulong get_pos(ref const File file) else version (Posix) return lseek(file.fd, 0, SEEK_CUR); else - static assert(0, "Not implemented"); + return 0; } Result set_pos(ref File file, ulong offset) @@ -593,17 +636,17 @@ Result set_pos(ref File file, ulong offset) LARGE_INTEGER liDistanceToMove = void; liDistanceToMove.QuadPart = offset; if (!SetFilePointerEx(file.handle, liDistanceToMove, null, FILE_BEGIN)) - return Win32Result(GetLastError()); + return getlasterror_result(); } else version (Posix) { off_t rc = lseek(file.fd, offset, SEEK_SET); if (rc < 0) - return PosixResult(errno); + return errno_result(); } else - static assert(0, "Not implemented"); - return Result.Success; + return InternalResult.unsupported; // no filesystem on this platform + return Result.success; } Result read(ref File file, void[] buffer, out size_t bytesRead) @@ -616,20 +659,20 @@ Result read(ref File file, void[] buffer, out size_t bytesRead) if (!ReadFile(file.handle, buffer.ptr, cast(uint)min(buffer.length, uint.max), &dwBytesRead, null)) { DWORD lastError = GetLastError(); - return (lastError == ERROR_BROKEN_PIPE) ? Result.Success : Win32Result(lastError); + return (lastError == ERROR_BROKEN_PIPE) ? Result.success : win32_result(lastError); } bytesRead = dwBytesRead; } else version (Posix) { - ptrdiff_t n = core.sys.posix.unistd.read(file.fd, buffer.ptr, buffer.length); + ptrdiff_t n = urt.internal.sys.posix.read(file.fd, buffer.ptr, buffer.length); if (n < 0) - return PosixResult(errno); + return errno_result(); bytesRead = n; } else - static assert(0, "Not implemented"); - return Result.Success; + return InternalResult.unsupported; // no filesystem on this platform + return Result.success; } Result read_at(ref File file, void[] buffer, ulong offset, out size_t bytesRead) @@ -637,7 +680,7 @@ Result read_at(ref File file, void[] buffer, ulong offset, out size_t bytesRead) version (Windows) { if (buffer.length > DWORD.max) - return InternalResult(InternalCode.InvalidParameter); + return InternalResult.invalid_parameter; OVERLAPPED o; o.Offset = cast(DWORD)offset; @@ -646,8 +689,9 @@ Result read_at(ref File file, void[] buffer, ulong offset, out size_t bytesRead) DWORD dwBytesRead; if (!ReadFile(file.handle, buffer.ptr, cast(DWORD)buffer.length, &dwBytesRead, &o)) { - if (GetLastError() != ERROR_HANDLE_EOF) - return Win32Result(GetLastError()); + Result error = getlasterror_result(); + if (error.system_code != ERROR_HANDLE_EOF) + return error; } bytesRead = dwBytesRead; } @@ -655,12 +699,12 @@ Result read_at(ref File file, void[] buffer, ulong offset, out size_t bytesRead) { ssize_t n = pread(file.fd, buffer.ptr, buffer.length, offset); if (n < 0) - return PosixResult(errno); + return errno_result(); bytesRead = n; } else - static assert(0, "Not implemented"); - return Result.Success; + return InternalResult.unsupported; // no filesystem on this platform + return Result.success; } Result write(ref File file, const(void)[] data, out size_t bytesWritten) @@ -669,19 +713,19 @@ Result write(ref File file, const(void)[] data, out size_t bytesWritten) { DWORD dwBytesWritten; if (!WriteFile(file.handle, data.ptr, cast(uint)data.length, &dwBytesWritten, null)) - return Win32Result(GetLastError()); + return getlasterror_result(); bytesWritten = dwBytesWritten; } else version (Posix) { - ptrdiff_t n = core.sys.posix.unistd.write(file.fd, data.ptr, data.length); + ptrdiff_t n = urt.internal.sys.posix.write(file.fd, data.ptr, data.length); if (n < 0) - return PosixResult(errno); + return errno_result(); bytesWritten = n; } else - static assert(0, "Not implemented"); - return Result.Success; + return InternalResult.unsupported; // no filesystem on this platform + return Result.success; } Result write_at(ref File file, const(void)[] data, ulong offset, out size_t bytesWritten) @@ -689,7 +733,7 @@ Result write_at(ref File file, const(void)[] data, ulong offset, out size_t byte version (Windows) { if (data.length > DWORD.max) - return InternalResult(InternalCode.InvalidParameter); + return InternalResult.invalid_parameter; OVERLAPPED o; o.Offset = cast(DWORD)offset; @@ -697,19 +741,19 @@ Result write_at(ref File file, const(void)[] data, ulong offset, out size_t byte DWORD dwBytesWritten; if (!WriteFile(file.handle, data.ptr, cast(DWORD)data.length, &dwBytesWritten, &o)) - return Win32Result(GetLastError()); + return getlasterror_result(); bytesWritten = dwBytesWritten; } else version (Posix) { ptrdiff_t n = pwrite(file.fd, data.ptr, data.length, offset); if (n < 0) - return PosixResult(errno); + return errno_result(); bytesWritten = n; } else - static assert(0, "Not implemented"); - return Result.Success; + return InternalResult.unsupported; // no filesystem on this platform + return Result.success; } Result flush(ref File file) @@ -717,23 +761,23 @@ Result flush(ref File file) version (Windows) { if (!FlushFileBuffers(file.handle)) - return Win32Result(GetLastError()); + return getlasterror_result(); } else version (Posix) { if (fsync(file.fd)) - return PosixResult(errno); + return errno_result(); } else - static assert(0, "Not implemented"); - return Result.Success; + return InternalResult.unsupported; // no filesystem on this platform + return Result.success; } -FileResult get_FileResult(Result result) +FileResult file_result(Result result) { version (Windows) { - switch (result.systemCode) + switch (result.system_code) { case ERROR_SUCCESS: return FileResult.Success; case ERROR_DISK_FULL: return FileResult.DiskFull; @@ -748,7 +792,7 @@ FileResult get_FileResult(Result result) else version (Posix) { static assert(EAGAIN == EWOULDBLOCK, "Expect EGAIN and EWOULDBLOCK are the same value"); - switch (result.systemCode) + switch (result.system_code) { case 0: return FileResult.Success; case ENOSPC: return FileResult.DiskFull; @@ -760,7 +804,7 @@ FileResult get_FileResult(Result result) } } else - static assert(0, "Not implemented"); + return FileResult.Failure; // no filesystem on this platform } Result get_temp_filename(ref char[] buffer, const(char)[] dstDir, const(char)[] prefix) @@ -771,46 +815,36 @@ Result get_temp_filename(ref char[] buffer, const(char)[] dstDir, const(char)[] wchar[MAX_PATH] tmp = void; if (!GetTempFileNameW(dstDir.twstringz, prefix.twstringz, 0, tmp.ptr)) - return Win32Result(GetLastError()); + return getlasterror_result(); size_t resLen = wcslen(tmp.ptr); - resLen = tmp[((dstDir.length == 0 && tmp[0] == '\\') ? 1 : 0)..resLen].uniConvert(buffer); + resLen = tmp[((dstDir.length == 0 && tmp[0] == '\\') ? 1 : 0)..resLen].uni_convert(buffer); if (resLen == 0) { DeleteFileW(tmp.ptr); - return InternalResult(InternalCode.BufferTooSmall); + return InternalResult.buffer_too_small; } buffer = buffer[0 .. resLen]; } else version (Posix) { // Construct a format string which will be the supplied dir with prefix and 8 generated random characters - char[] fn = tconcat(dstDir, (dstDir.length && dstDir[$-1] != '/') ? "/" : "", prefix, "XXXXXX\0"); + char[] fn = cast(char[])tconcat(dstDir, (dstDir.length && dstDir[$-1] != '/') ? "/" : "", prefix, "XXXXXX\0"); File file; file.fd = mkstemp(fn.ptr); if (file.fd == -1) - return PosixResult(errno); + return errno_result(); Result r = get_path(file, buffer); - core.sys.posix.unistd.close(file.fd); + urt.internal.sys.posix.close(file.fd); return r; } else - static assert(0, "Not implemented"); - return Result.Success; -} - -version (Windows) -{ - Result Win32Result(uint err) - => Result(err); -} -else version (Posix) -{ - Result PosixResult(int err) - => Result(err); + return InternalResult.unsupported; // no filesystem on this platform + return Result.success; } -unittest +version (FreeStanding) {} +else unittest { import urt.string; @@ -831,4 +865,32 @@ unittest assert(!file.is_open); assert(filename.delete_file()); + + // create a temp file with known content + filename = buffer[]; + assert(get_temp_filename(filename, "", "stat_test")); + + assert(file.open(filename, FileOpenMode.WriteTruncate)); + + // write exactly 42 bytes + ubyte[42] data; + size_t written; + assert(file.write(data[], written)); + assert(written == 42); + + // get_size exercises fstat + st_size + assert(file.get_size() == 42); + + // set_size exercises ftruncate, then fstat again + assert(file.set_size(100)); + assert(file.get_size() == 100); + + file.close(); + + // file_exists exercises stat + S_ISREG + st_mode + assert(file_exists(filename)); + + // clean up and verify + assert(filename.delete_file()); + assert(!file_exists(filename)); } diff --git a/src/urt/format/json.d b/src/urt/format/json.d index 544fbdf..3067f76 100644 --- a/src/urt/format/json.d +++ b/src/urt/format/json.d @@ -5,6 +5,7 @@ import urt.conv; import urt.lifetime; import urt.kvp; import urt.mem.allocator; +import urt.si.unit; import urt.string; import urt.string.format; @@ -13,38 +14,19 @@ public import urt.variant; nothrow @nogc: -Variant parseJson(const(char)[] text) +Variant parse_json(const(char)[] text) { - return parseNode(text); + return parse_node(text); } -ptrdiff_t writeJson(ref const Variant val, char[] buffer, bool dense = false, uint level = 0, uint indent = 2) +ptrdiff_t write_json(ref const Variant val, char[] buffer, bool dense = false, uint level = 0, uint indent = 2) { final switch (val.type) { case Variant.Type.Null: - if (!buffer.ptr) - return 4; - if (buffer.length < 4) - return -1; - buffer[0 .. 4] = "null"; - return 4; - - case Variant.Type.False: - if (!buffer.ptr) - return 5; - if (buffer.length < 5) - return -1; - buffer[0 .. 5] = "false"; - return 5; - case Variant.Type.True: - if (!buffer.ptr) - return 4; - if (buffer.length < 4) - return -1; - buffer[0 .. 4] = "true"; - return 4; + case Variant.Type.False: + return val.toString(buffer, null, null); case Variant.Type.Map: case Variant.Type.Array: @@ -52,6 +34,8 @@ ptrdiff_t writeJson(ref const Variant val, char[] buffer, bool dense = false, ui { ptrdiff_t len; size_t itemCount = val.type == Variant.Type.Map ? val.count /2 : val.count; + if (itemCount == 0) + return 2; // "[]" / "{}" if (dense) { // open/close brackets + comma-space separators @@ -76,9 +60,9 @@ ptrdiff_t writeJson(ref const Variant val, char[] buffer, bool dense = false, ui int inc = val.type == Variant.Type.Map ? 2 : 1; for (uint i = 0; i < val.count; i += inc) { - len += writeJson(val.value.n[i], null, dense, level + indent, indent); + len += write_json(val.value.n[i], null, dense, level + indent, indent); if (val.type == Variant.Type.Map) - len += writeJson(val.value.n[i + 1], null, dense, level + indent, indent); + len += write_json(val.value.n[i + 1], null, dense, level + indent, indent); } return len; } @@ -86,6 +70,12 @@ ptrdiff_t writeJson(ref const Variant val, char[] buffer, bool dense = false, ui ptrdiff_t written = 0; if (!buffer.append(written, val.type == Variant.Type.Map ? '{' : '[')) return -1; + if (val.count == 0) + { + if (!buffer.append(written, val.type == Variant.Type.Map ? '}' : ']')) + return -1; + return written; + } int inc = val.type == Variant.Type.Map ? 2 : 1; for (uint i = 0; i < val.count; i += inc) { @@ -99,7 +89,7 @@ ptrdiff_t writeJson(ref const Variant val, char[] buffer, bool dense = false, ui if (!buffer.newline(written, level + indent)) return -1; } - ptrdiff_t len = writeJson(val.value.n[i], buffer[written .. $], dense, level + indent, indent); + ptrdiff_t len = write_json(val.value.n[i], buffer[written .. $], dense, level + indent, indent); if (len < 0) return -1; written += len; @@ -107,7 +97,7 @@ ptrdiff_t writeJson(ref const Variant val, char[] buffer, bool dense = false, ui { if (!buffer.append(written, ':') || (!dense && !buffer.append(written, ' '))) return -1; - len = writeJson(val.value.n[i + 1], buffer[written .. $], dense, level + indent, indent); + len = write_json(val.value.n[i + 1], buffer[written .. $], dense, level + indent, indent); if (len < 0) return -1; written += len; @@ -119,40 +109,159 @@ ptrdiff_t writeJson(ref const Variant val, char[] buffer, bool dense = false, ui return -1; return written; - case Variant.Type.String: + case Variant.Type.Buffer: + if (!val.isString) + { + import urt.encoding; + + // emit raw buffer as base64 + const data = val.asBuffer(); + size_t enc_len = base64_encode_length(data.length); + if (buffer.ptr) + { + if (buffer.length < 2 + enc_len) + return -1; + buffer[0] = '"'; + ptrdiff_t r = data.base64_encode(buffer[1 .. 1 + enc_len]); + if (r != enc_len) + return -2; + buffer[1 + enc_len] = '"'; + } + return 2 + enc_len; + } + const char[] s = val.asString(); - if (buffer.ptr) + + if (!buffer.ptr) { - if (buffer.length < s.length + 2) + size_t len = 0; + foreach (c; s) + { + if (c < 0x20) + { + if (c == '\n' || c == '\r' || c == '\t' || c == '\b' || c == '\f') + len += 2; + else + len += 6; + } + else if (c == '"' || c == '\\') + len += 2; + else + len += 1; + } + return len + 2; + } + + if (buffer.length < s.length + 2) + return -1; + + buffer[0] = '"'; + // escape strings + size_t offset = 1; + foreach (c; s) + { + char sub = void; + if (c < 0x20) + { + if (c == '\n') + sub = 'n'; + else if (c == '\r') + sub = 'r'; + else if (c == '\t') + sub = 't'; + else if (c == '\b') + sub = 'b'; + else if (c == '\f') + sub = 'f'; + else + { + if (buffer.length < offset + 7) + return -1; + buffer[offset .. offset + 4] = "\\u00"; + offset += 4; + buffer[offset++] = hex_digits[c >> 4]; + buffer[offset++] = hex_digits[c & 0xF]; + continue; + } + } + else if (c == '"' || c == '\\') + sub = c; + else + { + if (buffer.length < offset + 2) + return -1; + buffer[offset++] = c; + continue; + } + + // write escape sequence + if (buffer.length < offset + 3) return -1; - buffer[0] = '"'; - buffer[1 .. 1 + s.length] = s[]; - buffer[1 + s.length] = '"'; + buffer[offset++] = '\\'; + buffer[offset++] = sub; } - return s.length + 2; + buffer[offset++] = '"'; + return offset; case Variant.Type.Number: import urt.conv; - if (val.isQuantity()) - assert(false, "TODO: implement quantity formatting for JSON"); + char[] number_buffer = buffer; + bool is_q = val.isQuantity(); + size_t u_len = 0; + float pre_scale = void; + if (is_q) + { + if (buffer.ptr) + { + if (buffer.length < 15) // {"q":x,"u":"x"} + return -1; + number_buffer = buffer[5..$]; + } + u_len = val.get_unit.format_unit(null, pre_scale, true); // TODO: should we give false (force pre-scale) here? + if (u_len <= 0) + return u_len; + + // TODO: apply the prescale... (if we change the above bool to false) + } + size_t len = 0; if (val.isDouble()) - return val.asDouble().formatFloat(buffer); + len += val.asDouble().format_float(number_buffer); + else if (val.isUlong()) + len += val.asUlong().format_uint(number_buffer); + else + len += val.asLong().format_int(number_buffer); + if (len <= 0 || !is_q) + return len; - // TODO: parse args? - //format + size_t result_len = 5 + len + 6 + u_len + 2; // {"q":x,"u":"x"} + if (!buffer.ptr) + return result_len; + if (buffer.length < result_len) + return -1; - if (val.isUlong()) - return val.asUlong().formatUint(buffer); - return val.asLong().formatInt(buffer); + size_t offset = 5 + len; + buffer[0..5] = "{\"q\":"; + buffer[offset..offset + 6] = ",\"u\":\""; + val.get_unit.format_unit(buffer[offset + 6..$], pre_scale, true); // TODO: should we give false (force pre-scale) here? + buffer[result_len-2..result_len] = "\"}"; + return result_len; case Variant.Type.User: - // in order to text-ify a user type, we probably need a hash table of text-ify functions, which - // we can lookup by the typeId... - // the tricky bit is, we need to init the table based on instantiations of constructors for each T... - // maybe an object with static constructor for each instantiation, which will hook it into the table? - assert(false, "TODO..."); + // for custom types, we'll use the type's regular string format into a json string + if (!buffer.ptr) + return val.toString(null, null, null) + 2; + if (buffer.length < 1) + return -1; + buffer[0] = '\"'; + ptrdiff_t len = val.toString(buffer[1 .. $], null, null); + if (len < 0) + return len; + if (buffer.length < len + 2) + return -1; + buffer[1 + len] = '\"'; + return len + 2; } } @@ -179,7 +288,7 @@ unittest ] }`; - Variant root = parseJson(doc); + Variant root = parse_json(doc); // check the data was parsed correctly... assert(root["nothing"].isNull); @@ -197,18 +306,18 @@ unittest char[1024] buffer = void; // check the dense writer... - assert(root["children"].writeJson(null, true) == 61); - assert(root["children"].writeJson(buffer, true) == 61); + assert(root["children"].write_json(null, true) == 61); + assert(root["children"].write_json(buffer, true) == 61); assert(buffer[0 .. 61] == `[{"name":"Jane Doe", "age":12}, {"name":"Jack Doe", "age":8}]`); // check the expanded writer - assert(root["children"].writeJson(null, false, 0, 1) == 83); - assert(root["children"].writeJson(buffer, false, 0, 1) == 83); + assert(root["children"].write_json(null, false, 0, 1) == 83); + assert(root["children"].write_json(buffer, false, 0, 1) == 83); assert(buffer[0 .. 83] == "[\n {\n \"name\": \"Jane Doe\",\n \"age\": 12\n },\n {\n \"name\": \"Jack Doe\",\n \"age\": 8\n }\n]"); // check indentation works properly - assert(root["children"].writeJson(null, false, 0, 2) == 95); - assert(root["children"].writeJson(buffer, false, 0, 2) == 95); + assert(root["children"].write_json(null, false, 0, 2) == 95); + assert(root["children"].write_json(buffer, false, 0, 2) == 95); assert(buffer[0 .. 95] == "[\n {\n \"name\": \"Jane Doe\",\n \"age\": 12\n },\n {\n \"name\": \"Jack Doe\",\n \"age\": 8\n }\n]"); // fabricate a JSON object @@ -220,7 +329,7 @@ unittest assert(write[0].asInt == 42); assert(write[1]["wow"].isTrue); assert(write[1]["bogus"].asBool == false); - assert(write.writeJson(buffer, true) == 33); + assert(write.write_json(buffer, true) == 33); assert(buffer[0 .. 33] == "[42, {\"wow\":true, \"bogus\":false}]"); } @@ -244,7 +353,7 @@ ptrdiff_t newline(char[] buffer, ref ptrdiff_t offset, int level) return true; } -Variant parseNode(ref const(char)[] text) +Variant parse_node(ref const(char)[] text) { text = text.trimFront(); @@ -269,20 +378,56 @@ Variant parseNode(ref const(char)[] text) { assert(text.length > 1); size_t i = 1; + Array!(char, 0) tmp; // TODO: needs a generous stack buffer! while (i < text.length && text[i] != '"') { - // TODO: we need to collapse the escape sequence, so we need to copy the string somewhere >_< - // ...overwrite the source buffer? if (text[i] == '\\') { - assert(i + 1 < text.length); - i += 2; + if (tmp.empty) + { + tmp.reserve(256); + tmp = text[1 .. i]; + } + if (++i == text.length) + break; + if (text[i] == 'u') + { + import urt.conv : parse_uint; + if (++i + 4 >= text.length) + break; + size_t taken; + ulong code = text[i .. i + 4].parse_uint(&taken, 16); + if (taken != 4) + break; + i += 4; + dchar c = cast(dchar)code; + if ((c >> 11) == 0x1B) + { + if (code >= 0xDC00) + break; // low surrogate without preceding high surrogate + if (i + 6 >= text.length || text[i] != '\\' || text[i+1] != 'u') + break; + code = text[i + 2 .. i + 6].parse_uint(&taken, 16); + if (taken != 4 || (code >> 10) != 0x37) + break; + c = 0x10000 + ((c & 0x3FF) << 10 | (cast(uint)code & 0x3FF)); + i += 6; + } + tmp ~= c; + } + else + goto do_concat; + } + else if (!tmp.empty) + { + do_concat: + tmp ~= text[i++]; } else - i++; + ++i; } assert(i < text.length); - Variant node = Variant(text[1 .. i]); + Variant node = Variant(tmp.empty ? text[1 .. i] : tmp[]); text = text[i + 1 .. $]; return node; } @@ -307,7 +452,7 @@ Variant parseNode(ref const(char)[] text) else expectComma = true; - tmp ~= parseNode(text); + tmp ~= parse_node(text); if (!isArray) { assert(tmp.back().isString()); @@ -315,7 +460,7 @@ Variant parseNode(ref const(char)[] text) text = text.trimFront; assert(text.length > 0 && text[0] == ':'); text = text[1 .. $].trimFront; - tmp ~= parseNode(text); + tmp ~= parse_node(text); } } assert(text.length > 0); @@ -326,33 +471,30 @@ Variant parseNode(ref const(char)[] text) r.flags = Variant.Flags.Map; return r; } - else if (text[0].isNumeric || (text[0] == '-' && text.length > 1 && text[1].isNumeric)) + else if (text[0].is_numeric || (text[0] == '-' && text.length > 1 && text[1].is_numeric)) { - bool neg = text[0] == '-'; size_t taken = void; - ulong div = void; - ulong value = text[neg .. $].parseUintWithDecimal(div, &taken, 10); + int e = void; + long value = text.parse_int_with_exponent(e, &taken, 10); assert(taken > 0); - text = text[taken + neg .. $]; + text = text[taken .. $]; - if (div > 1) - { - double d = cast(double)value; - if (neg) - d = -d; - d /= div; - return Variant(d); - } - else + // let's work out if value*10^^e is an integer? + bool is_integer = e >= 0; + for (; e > 0; --e) { - if (neg) + if (value < 0 ? (value < long.min / 10) : (value > long.max / 10)) { - assert(value <= long.max + 1); - return Variant(-cast(long)value); + is_integer = false; + break; } - else - return Variant(value); + value *= 10; } + + if (is_integer) + return Variant(value); + else + return Variant(value * 10.0^^e); } else assert(false, "Invalid JSON!"); diff --git a/src/urt/hash.d b/src/urt/hash.d index 7c068e6..35d9dbb 100644 --- a/src/urt/hash.d +++ b/src/urt/hash.d @@ -6,27 +6,28 @@ version = BranchIsFasterThanMod; nothrow @nogc: -alias fnv1aHash = fnv1Hash!(uint, true); -alias fnv1aHash64 = fnv1Hash!(ulong, true); +alias fnv1a = fnv1!(uint, true); +alias fnv1a64 = fnv1!(ulong, true); -T fnv1Hash(T, bool alternate)(const ubyte[] s) pure nothrow @nogc +template fnv1_initial(T) +{ + static if (is(T == ushort)) + enum T fnv1_initial = 0x811C; + else static if (is(T == uint)) + enum T fnv1_initial = 0x811C9DC5; + else static if (is(T == ulong)) + enum T fnv1_initial = 0xCBF29CE484222325; +} + +T fnv1(T, bool alternate)(const ubyte[] s, T hash = fnv1_initial!T) pure nothrow @nogc if (is(T == ushort) || is(T == uint) || is(T == ulong)) { static if (is(T == ushort)) - { - enum T prime = 0x0101; // 16-bit FNV prime - T hash = 0x811C; // 16-bit FNV offset basis - } + enum T prime = 0x0101; else static if (is(T == uint)) - { - enum T prime = 0x01000193; // 32-bit FNV prime - T hash = 0x811C9DC5; // 32-bit FNV offset basis - } + enum T prime = 0x01000193; else static if (is(T == ulong)) - { - enum T prime = 0x100000001B3; // 64-bit FNV prime - T hash = 0XCBF29CE484222325; // 64-bit FNV offset basis - } + enum T prime = 0x100000001B3; const ubyte* p = s.ptr; for (size_t i = 0; i < s.length; ++i) @@ -47,111 +48,157 @@ T fnv1Hash(T, bool alternate)(const ubyte[] s) pure nothrow @nogc unittest { - enum hash = fnv1aHash(cast(ubyte[])"hello world"); + enum hash = fnv1a(cast(ubyte[])"hello world"); static assert(hash == 0xD58B3FA7); + + enum h1 = fnv1a(cast(ubyte[])"hello "); + enum h2 = fnv1a(cast(ubyte[])"world", h1); + static assert(h2 == hash); } -uint adler32(const void[] data) +version (Espressif) { - enum A32_BASE = 65521; + private extern(C) uint mz_adler32(uint adler, const ubyte* ptr, size_t buf_len) pure nothrow @nogc; - assert(data.length <= int.max, "Data length must be less than or equal to int.max"); + uint adler32(const void[] data, uint init = 1) pure + { + return mz_adler32(init, cast(const ubyte*)data.ptr, data.length); + } +} +else +{ + uint adler32(const void[] data, uint init = 1) pure + { + enum A32_BASE = 65521; - uint s1 = 1; - uint s2 = 0; + assert(data.length <= int.max, "Data length must be less than or equal to int.max"); - version (SmallSize) - { - foreach (ubyte b; cast(ubyte[])data) + uint s1 = init & 0xFFFF; + uint s2 = (init >> 16) & 0xFFFF; + + version (SmallSize) { - version (BranchIsFasterThanMod) + foreach (ubyte b; cast(ubyte[])data) { - s1 += b; - s2 += s1; - if (s1 >= A32_BASE) - s1 -= A32_BASE; - if (s2 >= A32_BASE) - s2 -= A32_BASE; + version (BranchIsFasterThanMod) + { + s1 += b; + s2 += s1; + if (s1 >= A32_BASE) + s1 -= A32_BASE; + if (s2 >= A32_BASE) + s2 -= A32_BASE; + } + else + { + s1 = (s1 + b) % A32_BASE; + s2 = (s2 + s1) % A32_BASE; + } } - else + } + else + { + enum A32_NMAX = 5552; + + const(ubyte)* buf = cast(const ubyte*)data.ptr; + int length = cast(int)data.length; + + while (length > 0) { - s1 = (s1 + b) % A32_BASE; - s2 = (s2 + s1) % A32_BASE; + int k = length < A32_NMAX ? length : A32_NMAX; + int i; + + for (i = k / 16; i; --i, buf += 16) + { + s1 += buf[0]; + s2 += s1; + s1 += buf[1]; + s2 += s1; + s1 += buf[2]; + s2 += s1; + s1 += buf[3]; + s2 += s1; + s1 += buf[4]; + s2 += s1; + s1 += buf[5]; + s2 += s1; + s1 += buf[6]; + s2 += s1; + s1 += buf[7]; + s2 += s1; + + s1 += buf[8]; + s2 += s1; + s1 += buf[9]; + s2 += s1; + s1 += buf[10]; + s2 += s1; + s1 += buf[11]; + s2 += s1; + s1 += buf[12]; + s2 += s1; + s1 += buf[13]; + s2 += s1; + s1 += buf[14]; + s2 += s1; + s1 += buf[15]; + s2 += s1; + } + + for (i = k & 0xF; i; --i) + { + s1 += *buf++; + s2 += s1; + } + + s1 %= A32_BASE; + s2 %= A32_BASE; + + length -= k; } } + + return (s2 << 16) | s1; } - else - { - enum A32_NMAX = 5552; +} - const(ubyte)* buf = cast(const ubyte*)data.ptr; - int length = cast(int)data.length; +unittest +{ + // empty data + assert(adler32(null) == 1); - while (length > 0) - { - int k = length < A32_NMAX ? length : A32_NMAX; - int i; + // RFC 1950 test vectors + assert(adler32("Wikipedia") == 0x11E6_0398); - for (i = k / 16; i; --i, buf += 16) - { - s1 += buf[0]; - s2 += s1; - s1 += buf[1]; - s2 += s1; - s1 += buf[2]; - s2 += s1; - s1 += buf[3]; - s2 += s1; - s1 += buf[4]; - s2 += s1; - s1 += buf[5]; - s2 += s1; - s1 += buf[6]; - s2 += s1; - s1 += buf[7]; - s2 += s1; - - s1 += buf[8]; - s2 += s1; - s1 += buf[9]; - s2 += s1; - s1 += buf[10]; - s2 += s1; - s1 += buf[11]; - s2 += s1; - s1 += buf[12]; - s2 += s1; - s1 += buf[13]; - s2 += s1; - s1 += buf[14]; - s2 += s1; - s1 += buf[15]; - s2 += s1; - } + // single byte + assert(adler32("a") == 0x0062_0062); - for (i = k & 0xF; i; --i) - { - s1 += *buf++; - s2 += s1; - } + // full string + assert(adler32("Hello, World!") == 0x1F9E_046A); - s1 %= A32_BASE; - s2 %= A32_BASE; + // progressive accumulation + uint a1 = adler32("Hello, "); + assert(a1 == 0x09EE_0241); + assert(adler32("World!", a1) == 0x1F9E_046A); - length -= k; - } - } + // all zeros + ubyte[1024] zeros; + assert(adler32(zeros[]) == 0x0400_0001); - return (s2 << 16) | s1; + // known value: "123456789" + assert(adler32("123456789") == 0x091E_01DE); } -ushort internet_checksum(const void[] data, ushort initial = 0xFFFF) +// NOTE: progressive accumulation via `initial` works only when prior chunks have even length!!! +// odd-length chunks misalign the 16-bit word pairing. fixing this requires carrying a pending byte between calls :/ +// maybe there's some way to protect against misuse? +ushort internet_checksum(const void[] data, ushort initial = 0xFFFF) pure { auto bytes = cast(const(const ubyte)[])data; - uint sum = ~initial; + uint sum = initial ^ 0xFFFF; while (bytes.length > 1) { sum += (bytes.ptr[0] << 8) | bytes.ptr[1]; @@ -165,3 +212,49 @@ ushort internet_checksum(const void[] data, ushort initial = 0xFFFF) return cast(ushort)~sum; } + +unittest +{ + // Empty input: checksum of nothing is 0xFFFF (~0). + assert(internet_checksum(null) == 0xFFFF); + + // RFC 1071 §B vector. + static immutable ubyte[8] rfc1071 = [0x00, 0x01, 0xF2, 0x03, 0xF4, 0xF5, 0xF6, 0xF7]; + assert(internet_checksum(rfc1071[]) == 0x220D); + + // Real IPv4 header (checksum field zeroed). + static immutable ubyte[20] ip_hdr = [ + 0x45, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x06, 0x00, 0x00, + 0xC0, 0xA8, 0x00, 0xC8, 0xC0, 0xA8, 0x03, 0x0C, + ]; + ushort cs = internet_checksum(ip_hdr[]); + assert(cs == 0xF5A7); + + // Patching the computed checksum back in must verify to zero. + ubyte[20] verified = ip_hdr; + verified[10] = cast(ubyte)(cs >> 8); + verified[11] = cast(ubyte)cs; + assert(internet_checksum(verified[]) == 0); + + // Progressive accumulation across even-length chunks must match all-at-once. + ushort first = internet_checksum(ip_hdr[0 .. 10]); + ushort whole = internet_checksum(ip_hdr[10 .. $], first); + assert(whole == cs); + + // Odd-length input: trailing byte is treated as the high byte of a 16-bit word. + static immutable ubyte[3] odd = [0xAA, 0xBB, 0xCC]; + assert(internet_checksum(odd[]) == 0x8943); + + // Chained checksum across two buffers must equal the concatenated buffer's + // checksum, when the prior result is passed directly as `initial`. (This + // is the pseudo-header + segment pattern used by TCP/UDP.) + static immutable ubyte[6] part_a = [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC]; + static immutable ubyte[6] part_b = [0xDE, 0xF0, 0x11, 0x22, 0x33, 0x44]; + ubyte[12] joined; + joined[0 .. 6] = part_a; + joined[6 .. 12] = part_b; + ushort partial = internet_checksum(part_a[]); + ushort chained = internet_checksum(part_b[], partial); + assert(chained == internet_checksum(joined[])); +} diff --git a/src/urt/inet.d b/src/urt/inet.d index 969def7..7f5af5a 100644 --- a/src/urt/inet.d +++ b/src/urt/inet.d @@ -11,11 +11,11 @@ nothrow @nogc: enum AddressFamily : byte { - Unknown = -1, - Unspecified = 0, - Unix, - IPv4, - IPv6, + unknown = -1, + unspecified = 0, + unix, + ipv4, + ipv6, } enum WellKnownPort : ushort @@ -34,8 +34,8 @@ enum WellKnownPort : ushort MDNS = 5353, } -enum IPAddr IPAddrLit(string addr) = () { IPAddr a; size_t taken = a.fromString(addr); assert(taken == addr.length, "Not an IPv4 address"); return a; }(); -//enum IPv6Addr IPv6AddrLit(string addr) = () { IPv6Addr a; size_t taken = a.fromString(addr); assert(taken == addr.length, "Not an IPv6 address"); return a; }(); +enum IPAddr IPAddrLit(string addr) = () { IPAddr a; size_t taken = a.fromString(addr); assert(taken == addr.length, "Not an ipv4 address"); return a; }(); +enum IPv6Addr IPv6AddrLit(string addr) = () { IPv6Addr a; size_t taken = a.fromString(addr); assert(taken == addr.length, "Not an ipv6 address"); return a; }(); struct IPAddr { @@ -56,13 +56,13 @@ nothrow @nogc: this.b = b; } - bool isMulticast() const pure + bool is_multicast() const pure => (b[0] & 0xF0) == 224; - bool isLoopback() const pure + bool is_loopback() const pure => b[0] == 127; - bool isLinkLocal() const pure + bool is_link_local() const pure => (b[0] == 169 && b[1] == 254); - bool isPrivate() const pure + bool is_private() const pure => (b[0] == 192 && b[1] == 168) || b[0] == 10 || (b[0] == 172 && (b[1] & 0xF) == 16); bool opCast(T : bool)() const pure @@ -74,6 +74,16 @@ nothrow @nogc: bool opEquals(const(ubyte)[4] bytes) const pure => b == bytes; + int opCmp(ref const IPAddr rhs) const pure + { + uint a = loadBigEndian(&address), b = loadBigEndian(&rhs.address); + if (a < b) + return -1; + else if (a > b) + return 1; + return 0; + } + IPAddr opUnary(string op : "~")() const pure { IPAddr r; @@ -97,26 +107,26 @@ nothrow @nogc: size_t toHash() const pure { - import urt.hash : fnv1aHash, fnv1aHash64; + import urt.hash : fnv1a, fnv1a64; static if (size_t.sizeof > 4) - return fnv1aHash64(b[]); + return fnv1a64(b[]); else - return fnv1aHash(b[]); + return fnv1a(b[]); } - ptrdiff_t toString(char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) const pure + ptrdiff_t toString(char[] buffer, const(char)[], const(FormatArg)[]) const pure { - char[15] stackBuffer = void; - char[] tmp = buffer.length < stackBuffer.sizeof ? stackBuffer : buffer; + char[15] stack_buffer = void; + char[] tmp = buffer.length < stack_buffer.sizeof ? stack_buffer : buffer; size_t offset = 0; for (int i = 0; i < 4; i++) { if (i > 0) tmp[offset++] = '.'; - offset += b[i].formatInt(tmp[offset..$]); + offset += b[i].format_uint(tmp[offset..$]); } - if (buffer.ptr && tmp.ptr == stackBuffer.ptr) + if (buffer.ptr && tmp.ptr == stack_buffer.ptr) { if (buffer.length < offset) return -1; @@ -129,22 +139,22 @@ nothrow @nogc: { ubyte[4] t; size_t offset = 0, len; - ulong i = s[offset..$].parseInt(&len); + ulong i = s[offset..$].parse_uint(&len); offset += len; if (len == 0 || i > 255 || s.length < offset + 1 || s[offset++] != '.') return -1; t[0] = cast(ubyte)i; - i = s[offset..$].parseInt(&len); + i = s[offset..$].parse_uint(&len); offset += len; if (len == 0 || i > 255 || s.length < offset + 1 || s[offset++] != '.') return -1; t[1] = cast(ubyte)i; - i = s[offset..$].parseInt(&len); + i = s[offset..$].parse_uint(&len); offset += len; if (len == 0 || i > 255 || s.length < offset + 1 || s[offset++] != '.') return -1; t[2] = cast(ubyte)i; - i = s[offset..$].parseInt(&len); + i = s[offset..$].parse_uint(&len); offset += len; if (len == 0 || i > 255) return -1; @@ -153,14 +163,17 @@ nothrow @nogc: return offset; } - auto __debugOverview() + version (Windows) { - import urt.mem; - char[] buffer = cast(char[])tempAllocator.alloc(15); - ptrdiff_t len = toString(buffer, null, null); - return buffer[0 .. len]; + auto __debugOverview() + { + import urt.mem; + char[] buffer = debug_alloc!char(15); + ptrdiff_t len = toString(buffer, null, null); + return buffer[0 .. len]; + } + auto __debugExpanded() => b[]; } - auto __debugExpanded() => b[]; } @@ -180,13 +193,13 @@ nothrow @nogc: this.s = s; } - bool isGlobal() const pure + bool is_global() const pure => (s[0] & 0xE000) == 0x2000; - bool isLinkLocal() const pure + bool is_link_local() const pure => (s[0] & 0xFFC0) == 0xFE80; - bool isMulticast() const pure + bool is_multicast() const pure => (s[0] & 0xFF00) == 0xFF00; - bool isUniqueLocal() const pure + bool is_unique_local() const pure => (s[0] & 0xFE00) == 0xFC00; bool opCast(T : bool)() const pure @@ -198,6 +211,18 @@ nothrow @nogc: bool opEquals(const(ushort)[8] words) const pure => s == words; + int opCmp(ref const IPv6Addr rhs) const pure + { + for (int i = 0; i < 8; i++) + { + if (s[i] < rhs.s[i]) + return -1; + else if (s[i] > rhs.s[i]) + return 1; + } + return 0; + } + IPv6Addr opUnary(string op : "~")() const pure { IPv6Addr r; @@ -206,7 +231,7 @@ nothrow @nogc: return r; } - IPv6Addr opBinary(string op)(const IPv6Addr rhs) pure + IPv6Addr opBinary(string op)(const IPv6Addr rhs) const pure if (op == "&" || op == "|" || op == "^") { IPv6Addr t; @@ -224,19 +249,19 @@ nothrow @nogc: size_t toHash() const pure { - import urt.hash : fnv1aHash, fnv1aHash64; + import urt.hash : fnv1a, fnv1a64; static if (size_t.sizeof > 4) - return fnv1aHash64(cast(ubyte[])s[]); + return fnv1a64(cast(ubyte[])s[]); else - return fnv1aHash(cast(ubyte[])s[]); + return fnv1a(cast(ubyte[])s[]); } - ptrdiff_t toString(char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) const pure + ptrdiff_t toString(char[] buffer, const(char)[] format, const(FormatArg)[] format_args) const pure { import urt.string.ascii; // find consecutive zeroes... - int skipFrom = 0; + int skip_from = 0; int[8] z; for (int i = 0; i < 8; i++) { @@ -247,15 +272,15 @@ nothrow @nogc: if (z[j] != 0) { ++z[j]; - if (z[j] > z[skipFrom]) - skipFrom = j; + if (z[j] > z[skip_from]) + skip_from = j; } else break; } z[i] = 1; - if (z[i] > z[skipFrom]) - skipFrom = i; + if (z[i] > z[skip_from]) + skip_from = i; } } @@ -266,16 +291,16 @@ nothrow @nogc: { if (i > 0) tmp[offset++] = ':'; - if (z[skipFrom] > 1 && i == skipFrom) + if (z[skip_from] > 1 && i == skip_from) { if (i == 0) tmp[offset++] = ':'; - i += z[skipFrom]; + i += z[skip_from]; if (i == 8) tmp[offset++] = ':'; continue; } - offset += s[i].formatInt(tmp[offset..$], 16); + offset += s[i].format_uint(tmp[offset..$], 16); ++i; } @@ -284,48 +309,87 @@ nothrow @nogc: if (buffer.length < offset) return -1; foreach (i, c; tmp[0 .. offset]) - buffer[i] = c.toLower; + buffer[i] = c.to_lower; } return offset; } ptrdiff_t fromString(const(char)[] str) { - ushort[8] t; - size_t offset = 0; - assert(false); + ushort[8][2] t = void; + ubyte[2] count; + int part = 0; + + size_t offset = 0, len; + while (offset < str.length) + { + if (offset < str.length - 1 && str[offset] == ':' && str[offset + 1] == ':') + { + if (part != 0) + return -1; + part = 1; + offset += 2; + if (offset == str.length) + break; + } + else if (count[part] > 0) + { + if (str[offset] != ':') + break; + if (++offset == str.length) + return -1; + } + if (str[offset] == ':') + return -1; + ulong i = str[offset..$].parse_uint(&len, 16); + if (len == 0) + break; + if (i > ushort.max || count[0] + count[1] == 8) + return -1; + t[part][count[part]++] = cast(ushort)i; + offset += len; + } + if (part == 0 && count[0] != 8) + return -1; + + s[0 .. count[0]] = t[0][0 .. count[0]]; + s[count[0] .. 8 - count[1]] = 0; + s[8 - count[1] .. 8] = t[1][0 .. count[1]]; return offset; } - auto __debugOverview() + version (Windows) { - import urt.mem; - char[] buffer = cast(char[])tempAllocator.alloc(39); - ptrdiff_t len = toString(buffer, null, null); - return buffer[0 .. len]; + auto __debugOverview() + { + import urt.mem; + char[] buffer = debug_alloc!char(39); + ptrdiff_t len = toString(buffer, null, null); + return buffer[0 .. len]; + } + auto __debugExpanded() => s[]; } - auto __debugExpanded() => s[]; } -struct IPSubnet +struct IPNetworkAddress { nothrow @nogc: - enum multicast = IPSubnet(IPAddr(224, 0, 0, 0), 4); - enum loopback = IPSubnet(IPAddr(127, 0, 0, 0), 8); - enum linkLocal = IPSubnet(IPAddr(169, 254, 0, 0), 16); - enum privateA = IPSubnet(IPAddr(10, 0, 0, 0), 8); - enum privateB = IPSubnet(IPAddr(172, 16, 0, 0), 12); - enum privateC = IPSubnet(IPAddr(192, 168, 0, 0), 16); + enum multicast = IPNetworkAddress(IPAddr(224, 0, 0, 0), 4); + enum loopback = IPNetworkAddress(IPAddr(127, 0, 0, 0), 8); + enum linklocal = IPNetworkAddress(IPAddr(169, 254, 0, 0), 16); + enum private_a = IPNetworkAddress(IPAddr(10, 0, 0, 0), 8); + enum private_b = IPNetworkAddress(IPAddr(172, 16, 0, 0), 12); + enum private_c = IPNetworkAddress(IPAddr(192, 168, 0, 0), 16); // TODO: ya know, this is gonna align to 4-bytes anyway... // we could store the actual mask in the native endian, and then clz to recover the prefix len in one opcode IPAddr addr; IPAddr mask; - ubyte prefixLen() @property const pure + ubyte prefix_len() @property const pure => clz(~loadBigEndian(&mask.address)); - void prefixLen(ubyte len) @property pure + void prefix_len(ubyte len) @property pure { if (len == 0) mask.address = 0; @@ -333,36 +397,36 @@ nothrow @nogc: storeBigEndian(&mask.address, 0xFFFFFFFF << (32 - len)); } - this(IPAddr addr, ubyte prefixLen) + this(IPAddr addr, ubyte prefix_len) { this.addr = addr; - this.prefixLen = prefixLen; + this.prefix_len = prefix_len; } - IPAddr netMask() const pure + IPAddr net_mask() const pure => mask; bool contains(IPAddr ip) const pure - => (ip & netMask()) == addr; + => (ip & mask) == get_network(); - IPAddr getNetwork(IPAddr ip) const pure - => ip & mask; - IPAddr getLocal(IPAddr ip) const pure - => ip & ~mask; + IPAddr get_network() const pure + => addr & mask; + IPAddr get_local() const pure + => addr & ~mask; size_t toHash() const pure - => addr.toHash() ^ prefixLen; + => addr.toHash() ^ prefix_len; - ptrdiff_t toString(char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) const pure + ptrdiff_t toString(char[] buffer, const(char)[] format, const(FormatArg)[] format_args) const pure { - char[18] stackBuffer = void; - char[] tmp = buffer.length < stackBuffer.sizeof ? stackBuffer : buffer; + char[18] stack_buffer = void; + char[] tmp = buffer.length < stack_buffer.sizeof ? stack_buffer : buffer; size_t offset = addr.toString(tmp, null, null); tmp[offset++] = '/'; - offset += prefixLen.formatInt(tmp[offset..$]); + offset += prefix_len.format_uint(tmp[offset..$]); - if (buffer.ptr && tmp.ptr == stackBuffer.ptr) + if (buffer.ptr && tmp.ptr == stack_buffer.ptr) { if (buffer.length < offset) return -1; @@ -378,80 +442,91 @@ nothrow @nogc: if (taken < 0 || s.length <= taken + 1 || s[taken++] != '/') return -1; size_t t; - ulong plen = s[taken..$].parseInt(&t); + ulong plen = s[taken..$].parse_uint(&t); if (t == 0 || plen > 32) return -1; addr = a; - prefixLen = cast(ubyte)plen; + prefix_len = cast(ubyte)plen; return taken + t; } - auto __debugOverview() + version (Windows) { - import urt.mem; - char[] buffer = cast(char[])tempAllocator.alloc(18); - ptrdiff_t len = toString(buffer, null, null); - return buffer[0 .. len]; + auto __debugOverview() + { + import urt.mem; + char[] buffer = debug_alloc!char(18); + ptrdiff_t len = toString(buffer, null, null); + return buffer[0 .. len]; + } } } -struct IPv6Subnet +struct IPv6NetworkAddress { nothrow @nogc: - enum global = IPv6Subnet(IPv6Addr(0x2000, 0, 0, 0, 0, 0, 0, 0), 3); - enum linkLocal = IPv6Subnet(IPv6Addr(0xFE80, 0, 0, 0, 0, 0, 0, 0), 10); - enum multicast = IPv6Subnet(IPv6Addr(0xFF00, 0, 0, 0, 0, 0, 0, 0), 8); - enum uniqueLocal = IPv6Subnet(IPv6Addr(0xFC00, 0, 0, 0, 0, 0, 0, 0), 7); + enum global = IPv6NetworkAddress(IPv6Addr(0x2000, 0, 0, 0, 0, 0, 0, 0), 3); + enum linklocal = IPv6NetworkAddress(IPv6Addr(0xFE80, 0, 0, 0, 0, 0, 0, 0), 10); + enum multicast = IPv6NetworkAddress(IPv6Addr(0xFF00, 0, 0, 0, 0, 0, 0, 0), 8); + enum uniquelocal = IPv6NetworkAddress(IPv6Addr(0xFC00, 0, 0, 0, 0, 0, 0, 0), 7); IPv6Addr addr; - ubyte prefixLen; + ubyte prefix_len; - this(IPv6Addr addr, ubyte prefixLen) + this(IPv6Addr addr, ubyte prefix_len) { this.addr = addr; - this.prefixLen = prefixLen; + this.prefix_len = prefix_len; } - IPv6Addr netMask() const pure + IPv6Addr net_mask() const pure { IPv6Addr r; - int i, j = prefixLen / 16; + int i, j = prefix_len / 16; while (i < j) r.s[i++] = 0xFFFF; - r.s[i++] = cast(ushort)(0xFFFF << (16 - (prefixLen % 16))); - while (i < 8) r.s[i++] = 0; + if (j < 8) + { + r.s[i++] = cast(ushort)(0xFFFF << (16 - (prefix_len % 16))); + while (i < 8) r.s[i++] = 0; + } return r; } bool contains(IPv6Addr ip) const pure { - uint n = prefixLen / 16; + uint n = prefix_len / 16; uint i = 0; for (; i < n; ++i) if (ip.s[i] != addr.s[i]) return false; - if (prefixLen % 16) + if (prefix_len % 16) { - uint s = 16 - (prefixLen % 16); + uint s = 16 - (prefix_len % 16); if (ip.s[i] >> s != addr.s[i] >> s) return false; } return true; } + IPv6Addr get_network() const pure + => addr & net_mask(); + IPv6Addr get_local() const pure + => addr & ~net_mask(); + size_t toHash() const pure - => addr.toHash() ^ prefixLen; + => addr.toHash() ^ prefix_len; - ptrdiff_t toString(char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) const pure + ptrdiff_t toString(char[] buffer, const(char)[] format, const(FormatArg)[] format_args) const pure { - char[42] stackBuffer = void; - char[] tmp = buffer.length < stackBuffer.sizeof ? stackBuffer : buffer; + char[42] stack_buffer = void; + char[] tmp = buffer.length < stack_buffer.sizeof ? stack_buffer : buffer; size_t offset = addr.toString(tmp, null, null); tmp[offset++] = '/'; - offset += prefixLen.formatInt(tmp[offset..$]); + offset += prefix_len.format_uint(tmp[offset..$]); - if (buffer.ptr && tmp.ptr == stackBuffer.ptr) + if (buffer.ptr && tmp.ptr == stack_buffer.ptr) { if (buffer.length < offset) return -1; @@ -467,20 +542,23 @@ nothrow @nogc: if (taken < 0 || s.length <= taken + 1 || s[taken++] != '/') return -1; size_t t; - ulong plen = s[taken..$].parseInt(&t); - if (t == 0 || plen > 32) + ulong plen = s[taken..$].parse_uint(&t); + if (t == 0 || plen > 128) return -1; addr = a; - prefixLen = cast(ubyte)plen; + prefix_len = cast(ubyte)plen; return taken + t; } - auto __debugOverview() + version (Windows) { - import urt.mem; - char[] buffer = cast(char[])tempAllocator.alloc(42); - ptrdiff_t len = toString(buffer, null, null); - return buffer[0 .. len]; + auto __debugOverview() + { + import urt.mem; + char[] buffer = debug_alloc!char(42); + ptrdiff_t len = toString(buffer, null, null); + return buffer[0 .. len]; + } } } @@ -503,7 +581,7 @@ nothrow @nogc: { IPv6Addr addr; ushort port; - uint flowInfo; + uint flow_info; uint scopeId; } struct Addr @@ -517,37 +595,89 @@ nothrow @nogc: this(IPAddr addr, ushort port) { - family = AddressFamily.IPv4; + family = AddressFamily.ipv4; this._a.ipv4.addr = addr; this._a.ipv4.port = port; } - this(IPv6Addr addr, ushort port) + this(IPv6Addr addr, ushort port, int flow_info = 0, uint scopeId = 0) { - family = AddressFamily.IPv6; + family = AddressFamily.ipv6; this._a.ipv6.addr = addr; this._a.ipv6.port = port; + this._a.ipv6.flow_info = flow_info; + this._a.ipv6.scopeId = scopeId; + } + + inout(IPv4)* as_ipv4() inout pure + => family == AddressFamily.ipv4 ? &_a.ipv4 : null; + + inout(IPv6)* as_ipv6() inout pure + => family == AddressFamily.ipv6 ? &_a.ipv6 : null; + + bool opCast(T : bool)() const pure + => family > AddressFamily.Unspecified; + + bool opEquals(ref const InetAddress rhs) const pure + { + if (family != rhs.family) + return false; + switch (family) + { + case AddressFamily.ipv4: + return _a.ipv4 == rhs._a.ipv4; + case AddressFamily.ipv6: + return _a.ipv6 == rhs._a.ipv6; + default: + return true; + } + } + + int opCmp(ref const InetAddress rhs) const pure + { + if (family != rhs.family) + return family < rhs.family ? -1 : 1; + switch (family) + { + case AddressFamily.ipv4: + int c = _a.ipv4.addr.opCmp(rhs._a.ipv4.addr); + return c != 0 ? c : _a.ipv4.port - rhs._a.ipv4.port; + case AddressFamily.ipv6: + int c = _a.ipv6.addr.opCmp(rhs._a.ipv6.addr); + if (c != 0) + return c; + if (_a.ipv6.port == rhs._a.ipv6.port) + { + if (_a.ipv6.flow_info == rhs._a.ipv6.flow_info) + return _a.ipv6.scopeId - rhs._a.ipv6.scopeId; + return _a.ipv6.flow_info - rhs._a.ipv6.flow_info; + } + return _a.ipv6.port - rhs._a.ipv6.port; + default: + return 0; + } + return 0; } size_t toHash() const pure { - if (family == AddressFamily.IPv4) + if (family == AddressFamily.ipv4) return _a.ipv4.addr.toHash() ^ _a.ipv4.port; else return _a.ipv6.addr.toHash() ^ _a.ipv6.port; } - ptrdiff_t toString(char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) const pure + ptrdiff_t toString(char[] buffer, const(char)[] format, const(FormatArg)[] format_args) const pure { - char[47] stackBuffer = void; - char[] tmp = buffer.length < stackBuffer.sizeof ? stackBuffer : buffer; + char[47] stack_buffer = void; + char[] tmp = buffer.length < stack_buffer.sizeof ? stack_buffer : buffer; size_t offset = void; - if (family == AddressFamily.IPv4) + if (family == AddressFamily.ipv4) { offset = _a.ipv4.addr.toString(tmp, null, null); tmp[offset++] = ':'; - offset += _a.ipv4.port.formatInt(tmp[offset..$]); + offset += _a.ipv4.port.format_uint(tmp[offset..$]); } else { @@ -555,10 +685,10 @@ nothrow @nogc: offset = 1 + _a.ipv6.addr.toString(tmp[1 .. $], null, null); tmp[offset++] = ']'; tmp[offset++] = ':'; - offset += _a.ipv6.port.formatInt(tmp[offset..$]); + offset += _a.ipv6.port.format_uint(tmp[offset..$]); } - if (buffer.ptr && tmp.ptr == stackBuffer.ptr) + if (buffer.ptr && tmp.ptr == stack_buffer.ptr) { if (buffer.length < offset) return -1; @@ -577,10 +707,10 @@ nothrow @nogc: // take address if (s.length >= 4 && (s[1] == '.' || s[2] == '.' || s[3] == '.')) - af = AddressFamily.IPv4; + af = AddressFamily.ipv4; else - af = AddressFamily.IPv6; - if (af == AddressFamily.IPv4) + af = AddressFamily.ipv6; + if (af == AddressFamily.ipv4) { taken = a4.fromString(s); if (taken < 0) @@ -602,8 +732,8 @@ nothrow @nogc: if (s.length > taken && s[taken] == ':') { size_t t; - ulong p = s[++taken..$].parseInt(&t); - if (t == 0 || p > 0xFFFF) + ulong p = s[++taken..$].parse_uint(&t); + if (t == 0 || p > ushort.max) return -1; taken += t; port = cast(ushort)p; @@ -611,7 +741,7 @@ nothrow @nogc: // success! store results.. family = af; - if (af == AddressFamily.IPv4) + if (af == AddressFamily.ipv4) { _a.ipv4.addr = a4; _a.ipv4.port = port; @@ -620,18 +750,21 @@ nothrow @nogc: { _a.ipv6.addr = a6; _a.ipv6.port = port; - _a.ipv6.flowInfo = 0; + _a.ipv6.flow_info = 0; _a.ipv6.scopeId = 0; } return taken; } - auto __debugOverview() + version (Windows) { - import urt.mem; - char[] buffer = cast(char[])tempAllocator.alloc(47); - ptrdiff_t len = toString(buffer, null, null); - return buffer[0 .. len]; + auto __debugOverview() + { + import urt.mem; + char[] buffer = debug_alloc!char(47); + ptrdiff_t len = toString(buffer, null, null); + return buffer[0 .. len]; + } } } @@ -641,8 +774,12 @@ unittest char[64] tmp; assert(~IPAddr(255, 255, 248, 0) == IPAddr(0, 0, 7, 255)); + assert((IPAddr(255, 255, 248, 0) & IPAddr(255, 0, 255, 255)) == IPAddr(255, 0, 248, 0)); + assert((IPAddr(255, 255, 248, 0) | IPAddr(255, 0, 255, 255)) == IPAddr(255, 255, 255, 255)); assert((IPAddr(255, 255, 248, 0) ^ IPAddr(255, 0, 255, 255)) == IPAddr(0, 255, 7, 255)); - assert(IPSubnet(IPAddr(), 21).netMask() == IPAddr(0xFF, 0xFF, 0xF8, 0)); + assert(IPNetworkAddress(IPAddr(), 21).net_mask() == IPAddr(0xFF, 0xFF, 0xF8, 0)); + assert(IPNetworkAddress(IPAddr(192, 168, 0, 10), 24).get_network() == IPAddr(192, 168, 0, 0)); + assert(IPNetworkAddress(IPAddr(192, 168, 0, 10), 24).get_local() == IPAddr(0, 0, 0, 10)); assert(tmp[0 .. IPAddr(192, 168, 0, 1).toString(tmp, null, null)] == "192.168.0.1"); assert(tmp[0 .. IPAddr(0, 0, 0, 0).toString(tmp, null, null)] == "0.0.0.0"); @@ -653,16 +790,24 @@ unittest addr |= IPAddr(1, 2, 3, 4); assert(addr == IPAddr(1, 2, 3, 4)); - assert(tmp[0 .. IPSubnet(IPAddr(192, 168, 0, 0), 24).toString(tmp, null, null)] == "192.168.0.0/24"); - assert(tmp[0 .. IPSubnet(IPAddr(0, 0, 0, 0), 0).toString(tmp, null, null)] == "0.0.0.0/0"); + assert(tmp[0 .. IPNetworkAddress(IPAddr(192, 168, 0, 0), 24).toString(tmp, null, null)] == "192.168.0.0/24"); + assert(tmp[0 .. IPNetworkAddress(IPAddr(0, 0, 0, 0), 0).toString(tmp, null, null)] == "0.0.0.0/0"); - IPSubnet subnet; - assert(subnet.fromString("192.168.0.0/24") == 14 && subnet == IPSubnet(IPAddr(192, 168, 0, 0), 24)); - assert(subnet.fromString("0.0.0.0/0") == 9 && subnet == IPSubnet(IPAddr(0, 0, 0, 0), 0)); + IPNetworkAddress subnet; + assert(subnet.fromString("192.168.0.0/24") == 14 && subnet == IPNetworkAddress(IPAddr(192, 168, 0, 0), 24)); + assert(subnet.fromString("0.0.0.0/0") == 9 && subnet == IPNetworkAddress(IPAddr(0, 0, 0, 0), 0)); + assert(subnet.fromString("1.2.3.4") == -1); + assert(subnet.fromString("1.2.3.4/33") == -1); + assert(subnet.fromString("1.2.3.4/a") == -1); assert(~IPv6Addr(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFF0, 0, 0, 0) == IPv6Addr(0, 0, 0, 0, 0xF, 0xFFFF, 0xFFFF, 0xFFFF)); + assert((IPv6Addr(0xFFFF, 0, 1, 2, 3, 4, 5, 6) & IPv6Addr(0xFF00, 0, 3, 0, 0, 0, 0, 2)) == IPv6Addr(0xFF00, 0, 1, 0, 0, 0, 0, 2)); + assert((IPv6Addr(0xFFFF, 0, 1, 2, 3, 4, 5, 6) | IPv6Addr(0xFF00, 0, 3, 0, 0, 0, 0, 2)) == IPv6Addr(0xFFFF, 0, 3, 2, 3, 4, 5, 6)); assert((IPv6Addr(0xFFFF, 0, 1, 2, 3, 4, 5, 6) ^ IPv6Addr(0xFF00, 0, 3, 0, 0, 0, 0, 2)) == IPv6Addr(0xFF, 0, 2, 2, 3, 4, 5, 4)); - assert(IPv6Subnet(IPv6Addr(), 21).netMask() == IPv6Addr(0xFFFF, 0xF800, 0, 0, 0, 0, 0, 0)); + assert(IPv6NetworkAddress(IPv6Addr(), 21).net_mask() == IPv6Addr(0xFFFF, 0xF800, 0, 0, 0, 0, 0, 0)); + assert(IPv6NetworkAddress(IPv6Addr.loopback, 64).get_network() == IPv6Addr.any); + assert(IPv6NetworkAddress(IPv6Addr(0x2001, 0xdb8, 0, 1, 0, 0, 0, 1), 32).get_network() == IPv6Addr(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0)); + assert(IPv6NetworkAddress(IPv6Addr(0x2001, 0xdb8, 0, 1, 0, 0, 0, 1), 32).get_local() == IPv6Addr(0, 0, 0, 1, 0, 0, 0, 1)); assert(tmp[0 .. IPv6Addr(0x2001, 0xdb8, 0, 1, 0, 0, 0, 1).toString(tmp, null, null)] == "2001:db8:0:1::1"); assert(tmp[0 .. IPv6Addr(0x2001, 0xdb8, 0, 0, 1, 0, 0, 1).toString(tmp, null, null)] == "2001:db8::1:0:0:1"); @@ -670,17 +815,40 @@ unittest assert(tmp[0 .. IPv6Addr(0, 0, 0, 0, 0, 0, 0, 1).toString(tmp, null, null)] == "::1"); assert(tmp[0 .. IPv6Addr(0, 0, 0, 0, 0, 0, 0, 0).toString(tmp, null, null)] == "::"); -// IPv6Addr addr6; -// assert(addr6.fromString("::2") == 3 && addr6 == IPv6Addr(0, 0, 0, 0, 0, 0, 0, 2)); -// assert(addr6.fromString("1::2") == 3 && addr6 == IPv6Addr(1, 0, 0, 0, 0, 0, 0, 2)); -// assert(addr6.fromString("2001:db8::1/24") == 14 && addr6 == IPv6Addr(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)); - - assert(tmp[0 .. IPv6Subnet(IPv6Addr(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 24).toString(tmp, null, null)] == "2001:db8::1/24"); - assert(tmp[0 .. IPv6Subnet(IPv6Addr(), 0).toString(tmp, null, null)] == "::/0"); - -// IPv6Subnet subnet6; -// assert(subnet6.fromString("2001:db8::1/24") == 14 && subnet6 == IPv6Subnet(IPv6Addr(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 24)); -// assert(subnet6.fromString("::/0") == 4 && subnet6 == IPv6Subnet(IPv6Addr(), 0)); + IPv6Addr addr6; + assert(addr6.fromString("::") == 2 && addr6.s[] == [0,0,0,0,0,0,0,0]); + assert(addr6.fromString("1::") == 3 && addr6.s[] == [1,0,0,0,0,0,0,0]); + assert(addr6.fromString("::2") == 3 && addr6.s[] == [0,0,0,0,0,0,0,2]); + assert(addr6.fromString("1::2") == 4 && addr6.s[] == [1,0,0,0,0,0,0,2]); + assert(addr6.fromString("1:FFFF::2") == 9 && addr6.s[] == [1,0xFFFF,0,0,0,0,0,2]); + assert(addr6.fromString("1:2:3:4:5:6:7:8") == 15 && addr6.s[] == [1,2,3,4,5,6,7,8]); + assert(addr6.fromString("1:2:3:4") == -1); + assert(addr6.fromString("1:2:3:4:5:6:7:8:9") == -1); + assert(addr6.fromString("1:2:3:4:5:6:7:8:") == -1); + assert(addr6.fromString("10000::2") == -1); + assert(addr6.fromString(":2") == -1); + assert(addr6.fromString("2:") == -1); + assert(addr6.fromString(":2:") == -1); + assert(addr6.fromString(":2::") == -1); + assert(addr6.fromString(":2::1") == -1); + assert(addr6.fromString("::2:") == -1); + assert(addr6.fromString("1::2:") == -1); + assert(addr6.fromString("1:::2") == -1); + assert(addr6.fromString("::G") == 2 && addr6 == IPv6Addr(0, 0, 0, 0, 0, 0, 0, 0)); + assert(addr6.fromString("1::2.3") == 4 && addr6 == IPv6Addr(1, 0, 0, 0, 0, 0, 0, 2)); + assert(addr6.fromString("1::2 4") == 4 && addr6 == IPv6Addr(1, 0, 0, 0, 0, 0, 0, 2)); + assert(addr6.fromString("2001:db8::1/24") == 11 && addr6 == IPv6Addr(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)); + + + assert(tmp[0 .. IPv6NetworkAddress(IPv6Addr(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 24).toString(tmp, null, null)] == "2001:db8::1/24"); + assert(tmp[0 .. IPv6NetworkAddress(IPv6Addr(), 0).toString(tmp, null, null)] == "::/0"); + + IPv6NetworkAddress subnet6; + assert(subnet6.fromString("2001:db8::1/24") == 14 && subnet6 == IPv6NetworkAddress(IPv6Addr(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 24)); + assert(subnet6.fromString("::/0") == 4 && subnet6 == IPv6NetworkAddress(IPv6Addr(), 0)); + assert(subnet6.fromString("1::2") == -1); + assert(subnet6.fromString("1::2/129") == -1); + assert(subnet6.fromString("1::2/a") == -1); assert(tmp[0 .. InetAddress(IPAddr(192, 168, 0, 1), 12345).toString(tmp, null, null)] == "192.168.0.1:12345"); assert(tmp[0 .. InetAddress(IPAddr(10, 0, 0, 0), 21).toString(tmp, null, null)] == "10.0.0.0:21"); @@ -692,6 +860,82 @@ unittest assert(address.fromString("192.168.0.1:21") == 14 && address == InetAddress(IPAddr(192, 168, 0, 1), 21)); assert(address.fromString("10.0.0.1:12345") == 14 && address == InetAddress(IPAddr(10, 0, 0, 1), 12345)); -// assert(address.fromString("[2001:db8:0:1::1]:12345") == 14 && address == InetAddress(IPv6Addr(0x2001, 0xdb8, 0, 1, 0, 0, 0, 1), 12345)); -// assert(address.fromString("[::]:21") == 14 && address == InetAddress(IPv6Addr(), 21)); + assert(address.fromString("[2001:db8:0:1::1]:12345") == 23 && address == InetAddress(IPv6Addr(0x2001, 0xdb8, 0, 1, 0, 0, 0, 1), 12345)); + assert(address.fromString("[::]:21") == 7 && address == InetAddress(IPv6Addr(), 21)); + assert(address.fromString("[::]:a") == -1); + assert(address.fromString("[::]:65536") == -1); + + // IPAddr sorting tests + { + IPAddr[8] expected = [ + IPAddr(0, 0, 0, 0), + IPAddr(1, 2, 3, 4), + IPAddr(1, 2, 3, 5), + IPAddr(1, 2, 4, 4), + IPAddr(10, 0, 0, 1), + IPAddr(127, 0, 0, 1), + IPAddr(192, 168, 1, 1), + IPAddr(255, 255, 255, 255), + ]; + + for (size_t i = 0; i < expected.length - 1; ++i) + { + assert(expected[i].opCmp(expected[i]) == 0, "IPAddr self-comparison failed"); + assert(expected[i].opCmp(expected[i+1]) < 0, "IPAddr sorting is incorrect"); + assert(expected[i+1].opCmp(expected[i]) > 0, "IPAddr sorting is incorrect"); + } + } + + // IPv6Addr sorting tests + { + IPv6Addr[14] expected = [ + IPv6Addr(0, 0, 0, 0, 0, 0, 0, 0), // :: + IPv6Addr(0, 0, 0, 0, 0, 0, 0, 1), // ::1 + IPv6Addr(0, 0, 0, 0, 0, 0, 0, 2), // ::2 + IPv6Addr(0, 0, 0, 0, 0, 0, 9, 0), // ::9:0 + IPv6Addr(0, 0, 0, 0, 0, 8, 0, 0), // ::8:0:0 + IPv6Addr(0, 0, 0, 0, 7, 0, 0, 0), // ::7:0:0:0 + IPv6Addr(0, 0, 0, 6, 0, 0, 0, 0), // 0:0:0:6:: + IPv6Addr(0, 0, 5, 0, 0, 0, 0, 0), // 0:0:5:: + IPv6Addr(0, 4, 0, 0, 0, 0, 0, 0), // 0:4:: + IPv6Addr(1, 0, 0, 0, 0, 0, 0, 0), // 1:: + IPv6Addr(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), + IPv6Addr(0x2001, 0xdb8, 0, 0, 0, 0, 0, 2), + IPv6Addr(0xfe80, 0, 0, 0, 0, 0, 0, 1), + IPv6Addr(0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff), + ]; + + for (size_t i = 0; i < expected.length - 1; ++i) + { + assert(expected[i].opCmp(expected[i]) == 0, "IPv6Addr self-comparison failed"); + assert(expected[i].opCmp(expected[i+1]) < 0, "IPv6Addr sorting is incorrect"); + assert(expected[i+1].opCmp(expected[i]) > 0, "IPv6Addr sorting is incorrect"); + } + } + + // InetAddress sorting tests + { + InetAddress[10] expected = [ + // ipv4 sorted first + InetAddress(IPAddr(10, 0, 0, 1), 80), + InetAddress(IPAddr(127, 0, 0, 1), 8080), + InetAddress(IPAddr(192, 168, 1, 1), 80), + InetAddress(IPAddr(192, 168, 1, 1), 443), + + // ipv6 sorted next + InetAddress(IPv6Addr(1, 0, 0, 0, 0, 0, 0, 0), 1024), + InetAddress(IPv6Addr(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 80, 0, 0), + InetAddress(IPv6Addr(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 433, 1, 1), + InetAddress(IPv6Addr(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 8080, 0, 0), // flow=0, scope=0 + InetAddress(IPv6Addr(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 8080, 0, 1), // flow=0, scope=1 + InetAddress(IPv6Addr(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 8080, 1, 0), // flow=1, scope=0 + ]; + + for (size_t i = 0; i < expected.length - 1; ++i) + { + assert(expected[i].opCmp(expected[i]) == 0, "InetAddress self-comparison failed"); + assert(expected[i].opCmp(expected[i+1]) < 0, "InetAddress sorting is incorrect"); + assert(expected[i+1].opCmp(expected[i]) > 0, "InetAddress sorting is incorrect"); + } + } } diff --git a/src/urt/internal/aa.d b/src/urt/internal/aa.d new file mode 100644 index 0000000..c8e2fa6 --- /dev/null +++ b/src/urt/internal/aa.d @@ -0,0 +1,1048 @@ +/** + * template implementation of associative arrays. + * + * Copyright: Copyright Digital Mars 2000 - 2015, Steven Schveighoffer 2022. + * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). + * Authors: Martin Nowak, Steven Schveighoffer, Rainer Schuetze + * + * Source: $(DRUNTIMESRC core/internal/_newaa.d) + * + * derived from rt/aaA.d + */ +module urt.internal.aa; + +/// AA version for debuggers, bump whenever changing the layout +immutable int _aaVersion = 1; + +import urt.internal.traits : substInout; + +// grow threshold +private enum GROW_NUM = 4; +private enum GROW_DEN = 5; +// shrink threshold +private enum SHRINK_NUM = 1; +private enum SHRINK_DEN = 8; +// grow factor +private enum GROW_FAC = 4; +// growing the AA doubles it's size, so the shrink threshold must be +// smaller than half the grow threshold to have a hysteresis +static assert(GROW_FAC * SHRINK_NUM * GROW_DEN < GROW_NUM * SHRINK_DEN); +// initial load factor (for literals), mean of both thresholds +private enum INIT_NUM = (GROW_DEN * SHRINK_NUM + GROW_NUM * SHRINK_DEN) / 2; +private enum INIT_DEN = SHRINK_DEN * GROW_DEN; + +private enum INIT_NUM_BUCKETS = 8; +// magic hash constants to distinguish empty, deleted, and filled buckets +private enum HASH_EMPTY = 0; +private enum HASH_DELETED = 0x1; +private enum HASH_FILLED_MARK = size_t(1) << 8 * size_t.sizeof - 1; + +/// AA wrapper +struct AA(K, V) +{ + Impl!(K,V)* impl; + alias impl this; + + @property bool empty() const pure nothrow @nogc @safe + { + pragma(inline, true); + return impl is null || !impl.length; + } + @property size_t length() const pure nothrow @nogc @safe + { + pragma(inline, true); + return impl is null ? 0 : impl.length; + } +} + +/// like urt.internal.traits.Unconst, but stripping inout, too +private template Unconstify(T : const U, U) +{ + static if (is(U == inout V, V)) + alias Unconstify = V; + else + alias Unconstify = U; +} + +ref _refAA(K, V)(ref V[K] aa) @trusted +{ + pragma(inline, true); + return *(cast(AA!(substInout!K, substInout!V)*)&aa); +} + +auto _toAA(K, V)(const V[K] aa) @trusted +{ + pragma(inline, true); + return *(cast(const(AA!(K, V))*)&aa); +} + +auto _toAA(K, V)(inout V[K] aa) @trusted +{ + pragma(inline, true); + return *(cast(inout(AA!(K, V))*)&aa); +} + +// for backward compatibility, but should be deprecated +auto _toAA(K, V)(shared const V[K] aa) @trusted +{ + pragma(inline, true); + return *(cast(AA!(K, V)*)&aa); +} + +// for backward compatibility, but should be deprecated +auto _toAA(K, V)(shared V[K] aa) @trusted +{ + pragma(inline, true); + return *(cast(AA!(K, V)*)&aa); +} + +// resolve ambiguity for immutable converting to const and shared const +auto _toAA(K, V)(immutable V[K] aa) @trusted +{ + pragma(inline, true); + return *(cast(AA!(K, V)*)&aa); +} + +static struct Entry(K, V) +{ + K key; + V value; +} + +// backward compatibility conversions +private ref compat_key(K, K2)(ref K2 key) +{ + pragma(inline, true); + static if (is(K2 == const(char)[]) && is(K == string)) + return (ref (ref return K2 k2) @trusted => *cast(string*)&k2)(key); + else + return key; +} + +private void _aaMove(V)(ref V src, ref V dst) @trusted +{ + import urt.mem : memcpy, memset; + // move without postblit!? + memcpy(&dst, &src, V.sizeof); + static if (__traits(isZeroInit, V)) + memset(&src, 0, V.sizeof); + else + memcpy(&src, &V.init, V.sizeof); +} + +// mimick behaviour of rt.aaA for initialization +Entry!(K, V)* _newEntry(K, V)(ref K key, ref V value) +{ + static if (__traits(compiles, new Entry!(K, V)(key, value))) + { + auto entry = new Entry!(K, V)(key, value); + } + else static if (__traits(compiles, { K k; new Entry!(K, V)(k); })) + { + auto entry = new Entry!(K, V)(key); + _aaMove(value, entry.value); + } + else + { + auto entry = new Entry!(K, V); + _aaMove(key, entry.key); + _aaMove(value, entry.value); + } + return entry; +} + +// mimick behaviour of rt.aaA for initialization +Entry!(K, V)* _newEntry(K, V, K2)(ref K2 key) +{ + static if (__traits(compiles, new Entry!(K, V)(key)) && + !(is(V == struct) && __traits(isNested, V))) // not detected by "compiles" + { + auto entry = new Entry!(K, V)(key); + } + else static if (__traits(compiles, { K2 k; new Entry!(K, V)(k, V.init); })) + { + // with disabled ctor for V + auto entry = new Entry!(K, V)(key, V.init); + } + else + { + // with disabled ctor for K and V + auto entry = new Entry!(K, V); + entry.key = key; + } + static if (!__traits(isZeroInit, V)) + { + () @trusted { (cast(ubyte*)&entry.value)[0..V.sizeof] = 0; }(); + } + return entry; +} + +template pure_hashOf(K) +{ + static if (__traits(compiles, function hash_t(scope const ref K key) pure nothrow @nogc @trusted { return hashOf(cast()key); })) + { + // avoid wrapper call in debug builds if pure nothrow @nogc is inferred + pragma(inline, true) + hash_t pure_hashOf(scope const ref K key) @trusted { return hashOf(cast()key); } + } + else + { + // for backward compatibility, do not require const in hashOf() + hash_t wrap_hashOf(K)(scope const ref K key) @trusted { return hashOf(cast()key); } + enum pure_hashOf = cast(hash_t function(scope ref const K key) pure nothrow @nogc @safe) &wrap_hashOf!K; + } +} + +// for backward compatibilty pretend the comparison is @safe, pure, etc +// this also breaks cyclic inference on recursive data types +template pure_keyEqual(K1, K2 = K1) +{ + static if (__traits(compiles, function bool(ref const K1 k1, ref const K2 k2) pure nothrow @nogc @trusted { return cast()k1 == cast()k2; })) + { + // avoid wrapper call in debug builds if pure nothrow @nogc is inferred + pragma(inline, true) + bool pure_keyEqual(ref const K1 k1, ref const K2 k2) @trusted { return cast()k1 == cast()k2; } + } + else + { + bool keyEqual(ref const K1 k1, ref const K2 k2) @trusted { return cast()k1 == cast()k2; } + enum pure_keyEqual = cast(bool function(ref const K1, ref const K2) pure nothrow @nogc @safe) &keyEqual; + } +} + +private struct Impl(K, V) +{ +private: + alias Bucket = .Bucket!(K, V); + + this(size_t sz /* = INIT_NUM_BUCKETS */) nothrow + { + buckets = alloc_buckets(sz); + first_used = cast(uint) buckets.length; + + // only for binary compatibility + entry_ti = typeid(Entry!(K, V)); + hash_fn = delegate size_t (scope ref const K key) nothrow pure @nogc @safe { + return pure_hashOf!K(key); + }; + + key_sz = cast(uint) K.sizeof; + val_sz = cast(uint) V.sizeof; + val_off = cast(uint) talign(key_sz, V.alignof); + + enum ctflags = () { + import urt.internal.traits; + Impl.Flags flags; + static if (__traits(hasPostblit, K)) + flags |= flags.key_has_postblit; + static if (hasIndirections!K || hasIndirections!V) + flags |= flags.has_pointers; + return flags; + } (); + flags = ctflags; + } + + Bucket[] buckets; + uint used; + uint deleted; + const(TypeInfo) entry_ti; // only for binary compatibility + uint first_used; + immutable uint key_sz; // only for binary compatibility + immutable uint val_sz; // only for binary compatibility + immutable uint val_off; // only for binary compatibility + Flags flags; // only for binary compatibility + size_t delegate(scope ref const K) nothrow pure @nogc @safe hash_fn; + + enum Flags : ubyte + { + none = 0x0, + key_has_postblit = 0x1, + has_pointers = 0x2, + } + + @property size_t length() const pure nothrow @nogc @safe + { + pragma(inline, true); + assert(used >= deleted); + return used - deleted; + } + + @property size_t dim() const pure nothrow @nogc @safe + { + pragma(inline, true); + return buckets.length; + } + + @property size_t mask() const pure nothrow @nogc @safe + { + pragma(inline, true); + return dim - 1; + } + + // find the first slot to insert a value with hash + size_t find_slot_insert(size_t hash) const pure nothrow @nogc @safe + { + for (size_t i = hash & mask, j = 1;; ++j) + { + if (!buckets[i].filled) + return i; + i = (i + j) & mask; + } + } + + // lookup a key + inout(Bucket)* find_slot_lookup(K2)(size_t hash, scope ref const K2 key) inout pure @safe nothrow + { + for (size_t i = hash & mask, j = 1;; ++j) + { + auto b = &buckets[i]; // avoid multiple bounds checks + if (b.hash == hash && b.entry) + if (pure_keyEqual!(K2, K)(key, b.entry.key)) + return b; + if (b.empty) + return null; + i = (i + j) & mask; + } + } + + void grow() pure nothrow @safe + { + // If there are so many deleted entries, that growing would push us + // below the shrink threshold, we just purge deleted entries instead. + if (length * SHRINK_DEN < GROW_FAC * dim * SHRINK_NUM) + resize(dim); + else + resize(GROW_FAC * dim); + } + + void shrink() pure nothrow @safe + { + if (dim > INIT_NUM_BUCKETS) + resize(dim / GROW_FAC); + } + + void resize(size_t ndim) pure nothrow @safe + { + auto obuckets = buckets; + buckets = alloc_buckets(ndim); + + foreach (ref b; obuckets[first_used .. $]) + if (b.filled) + buckets[find_slot_insert(b.hash)] = b; + + first_used = 0; + used -= deleted; + deleted = 0; + obuckets.length = 0; // safe to free b/c impossible to reference, but doesn't really free + } + + void clear() pure nothrow + { + // clear all data, but don't change bucket array length + buckets[first_used .. $] = Bucket.init; + deleted = used = 0; + first_used = cast(uint) dim; + } + + size_t calc_hash(K2)(ref K2 key) const nothrow pure @nogc @safe + { + static if(is(K2* : K*)) // ref compatible? + hash_t hash = pure_hashOf!K(key); + else + hash_t hash = pure_hashOf!K2(key); + // highest bit is set to distinguish empty/deleted from filled buckets + return mix(hash) | HASH_FILLED_MARK; + } + + static Bucket[] alloc_buckets(size_t dim) pure nothrow @safe + { + // could allocate with BlkAttr.NO_INTERIOR, but that does not combine + // well with arrays and type info for precise scanning + return new Bucket[dim]; + } +} + +//============================================================================== +// Bucket +//------------------------------------------------------------------------------ + +private struct Bucket(K, V) +{ +private pure nothrow @nogc: + size_t hash; + Entry!(K, V)* entry; + + @property bool empty() const + { + pragma(inline, true); + return hash == HASH_EMPTY; + } + + @property bool deleted() const + { + pragma(inline, true); + return hash == HASH_DELETED; + } + + @property bool filled() const @safe + { + pragma(inline, true); + return cast(ptrdiff_t) hash < 0; + } +} + +//============================================================================== +// Helper functions +//------------------------------------------------------------------------------ + +private size_t talign(size_t tsize, size_t algn) @safe pure nothrow @nogc +{ + immutable mask = algn - 1; + assert(!(mask & algn)); + return (tsize + mask) & ~mask; +} + +// mix hash to "fix" bad hash functions +private size_t mix(size_t h) @safe pure nothrow @nogc +{ + // final mix function of MurmurHash2 + enum m = 0x5bd1e995; + h ^= h >> 13; + h *= m; + h ^= h >> 15; + return h; +} + +private size_t next_pow2(const size_t n) pure nothrow @nogc @safe +{ + import urt.internal.bitop : bsr; + + if (!n) + return 1; + + const is_power_of_2 = !((n - 1) & n); + return 1 << (bsr(n) + !is_power_of_2); +} + +pure nothrow @nogc unittest +{ + // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 + foreach (const n, const pow2; [1, 1, 2, 4, 4, 8, 8, 8, 8, 16]) + assert(next_pow2(n) == pow2); +} + +//============================================================================== +// API Implementation +//------------------------------------------------------------------------------ + +/** Allocate associative array data. + * Called for `new SomeAA` expression. + * Returns: + * A new associative array. + * Note: + * not supported in CTFE + */ +V[K] _d_aaNew(K, V)() +{ + AA!(K, V) aa; + aa.impl = new Impl!(K,V)(INIT_NUM_BUCKETS); + return *cast(V[K]*)&aa; +} + +/// Determine number of entries in associative array. +/// Note: +/// emulated by the compiler during CTFE +size_t _d_aaLen(K, V)(inout V[K] a) +{ + auto aa = _toAA!(K, V)(a); + return aa ? aa.length : 0; +} + +/****************************** + * Lookup key in aa. + * Called only from implementation of (aa[key]) expressions when value is mutable. + * Params: + * aa = associative array + * key = reference to the key value + * found = returns whether the key was found or a new entry was added + * Returns: + * if key was in the aa, a mutable pointer to the existing value. + * If key was not in the aa, a mutable pointer to newly inserted value which + * is set to zero + */ +V* _d_aaGetY(K, V, T : V1[K1], K1, V1, K2)(auto ref scope T aa, auto ref K2 key, out bool found) +{ + ref aax = cast(V[K])cast(V1[K1])aa; // remove outer const from T + return _aaGetX!(K, V)(aax, key, found); +} + +/****************************** + * Lookup key in aa. + * Called only from implementation of require, update and _d_aaGetY + * Params: + * a = associative array + * key = reference to the key value + * found = true if the value was found + * Returns: + * if key was in the aa, a mutable pointer to the existing value. + * If key was not in the aa, a mutable pointer to newly inserted value which + * is set to V.init + */ +V* _aaGetX(K, V, K2)(auto ref scope V[K] a, auto ref K2 key, out bool found) +{ + ref aa = _refAA!(K, V)(a); + + // lazily alloc implementation + if (aa is null) + { + aa.impl = new Impl!(K, V)(INIT_NUM_BUCKETS); + } + + ref key2 = compat_key!(K)(key); + + // get hash and bucket for key + immutable hash = aa.calc_hash(key2); + + // found a value => return it + if (auto p = aa.find_slot_lookup(hash, key2)) + { + found = true; + return &p.entry.value; + } + + auto pi = aa.find_slot_insert(hash); + if (aa.buckets[pi].deleted) + --aa.deleted; + // check load factor and possibly grow + else if (++aa.used * GROW_DEN > aa.dim * GROW_NUM) + { + aa.grow(); + pi = aa.find_slot_insert(hash); + assert(aa.buckets[pi].empty); + } + + // update search cache and allocate entry + aa.first_used = min(aa.first_used, cast(uint)pi); + ref p = aa.buckets[pi]; + p.hash = hash; + p.entry = _newEntry!(K, V)(key2); + return &p.entry.value; +} + +/****************************** + * Lookup key in aa. + * Called only from implementation of (aa[key]) expressions when value is not mutable. + * Params: + * aa = associative array + * key = key value + * Returns: + * pointer to value if present, null otherwise + */ +auto _d_aaGetRvalueX(K, V, K2)(inout V[K] aa, auto ref scope K2 key) +{ + return _d_aaIn(aa, key); +} + +/// ditto +auto _d_aaGetRvalueX(K, V, K2)(shared(V[K]) aa, auto ref scope K2 key) +{ + // accept shared for backward compatibility, should be deprecated + return cast(shared(V)*)_d_aaIn(cast(V[K]) aa, key); +} + +/// ditto +auto _d_aaGetRvalueX(K, V, K2)(shared const(V[K]) aa, auto ref scope K2 key) +{ + // accept shared for backward compatibility, should be deprecated + return cast(const shared(V)*)_d_aaIn(cast(V[K]) aa, key); +} + +/// ditto +auto _d_aaGetRvalueX(K, V, K2)(immutable(V[K]) aa, auto ref scope K2 key) +{ + // resolve ambiguity for immutable converting to const and shared const + return _d_aaIn((() @trusted => cast(V[K]) aa) (), key); +} + +/*********************************** + * Creates a new associative array of the same size and copies the contents of + * the associative array into it. + * Params: + * a = The associative array. + */ +auto _aaDup(T : V[K], K, V)(T a) +{ + auto aa = _toAA!(K, V)(a); + immutable len = aa.length; + if (len == 0) + return null; + + auto impl = new Impl!(K, V)(aa.dim); + // copy the entries + bool same_hash = aa.hash_fn == impl.hash_fn; // can be different if coming from template/rt + foreach (b; aa.buckets[aa.first_used .. $]) + { + if (!b.filled) + continue; + hash_t hash = same_hash ? b.hash : impl.calc_hash(b.entry.key); + auto pi = impl.find_slot_insert(hash); + auto p = &impl.buckets[pi]; + p.hash = hash; + p.entry = new Entry!(K, V)(b.entry.key, b.entry.value); + impl.first_used = min(impl.first_used, cast(uint)pi); + } + impl.used = cast(uint) len; + return () @trusted { return *cast(Unconstify!V[K]*)&impl; }(); +} + +/****************************** + * Lookup key in aa. + * Called only from implementation of (key in aa) expressions. + * Params: + * a = associative array opaque pointer + * key = reference to the key value + * Returns: + * pointer to value if present, null otherwise + */ +auto _d_aaIn(T : V[K], K, V, K2)(inout T a, auto ref scope K2 key) +{ + auto aa = _toAA!(K, V)(a); + if (aa.empty) + return null; + + ref key2 = compat_key!(K)(key); + + immutable hash = aa.calc_hash(key2); + if (auto p = aa.find_slot_lookup(hash, key2)) + return &p.entry.value; + return null; +} + +// fake purity for backward compatibility with runtime hooks +private extern(C) bool gc_inFinalizer() pure nothrow @safe; + +/// Delete entry scope const AA, return true if it was present +auto _d_aaDel(T : V[K], K, V, K2)(T a, auto ref K2 key) +{ + auto aa = _toAA!(K, V)(a); + if (aa.empty) + return false; + + ref key2 = compat_key!(K)(key); + + immutable hash = aa.calc_hash(key2); + if (auto p = aa.find_slot_lookup(hash, key2)) + { + // clear entry + p.hash = HASH_DELETED; + p.entry = null; + + ++aa.deleted; + // `shrink` reallocates, and allocating from a finalizer leads to + // InvalidMemoryError: https://issues.dlang.org/show_bug.cgi?id=21442 + if (aa.length * SHRINK_DEN < aa.dim * SHRINK_NUM && !__ctfe && !gc_inFinalizer()) + aa.shrink(); + + return true; + } + return false; +} + +/// Remove all elements from AA. +void _aaClear(K, V)(V[K] a) +{ + auto aa = _toAA!(K, V)(a); + if (!aa.empty) + { + aa.clear(); + } +} + +/// Rehash AA +V[K] _aaRehash(K, V)(V[K] a) +{ + auto aa = _toAA!(K, V)(a); + if (!aa.empty) + aa.resize(next_pow2(INIT_DEN * aa.length / INIT_NUM)); + return a; +} + +/// Return a GC allocated array of all values +auto _aaValues(K, V)(inout V[K] a) +{ + auto aa = _toAA!(K, V)(a); + if (aa.empty) + return null; + + static if (__traits(compiles, { V val = aa.buckets[0].entry.value; } )) + V[] res; // if value has no const indirections + else + typeof([aa.buckets[0].entry.value]) res; // as mutable as it can get + res = new typeof(res[0])[aa.length]; + + if (false) // never execute, but infer function attributes from this operation + res ~= aa.buckets[0].entry.value; + + size_t i = 0; + foreach (b; aa.buckets[aa.first_used .. $]) + { + if (!b.filled) + continue; + import urt.lifetime; + () @trusted { copyEmplace(b.entry.value, res[i++]); }(); + } + return res; +} + +/// Return a GC allocated array of all keys +auto _aaKeys(K, V)(inout V[K] a) +{ + auto aa = _toAA!(K, V)(a); + if (aa.empty) + return null; + + static if (__traits(compiles, { K key = aa.buckets[0].entry.key; } )) + K[] res; // if key has no const indirections + else + typeof([aa.buckets[0].entry.key]) res; // as mutable as it can get + res = new typeof(res[0])[aa.length]; + + if (false) // never execute, but infer function attributes from this operation + res ~= aa.buckets[0].entry.key; + + size_t i = 0; + foreach (b; aa.buckets[aa.first_used .. $]) + { + if (!b.filled) + continue; + // res ~= b.entry.key; + import urt.lifetime; + () @trusted { copyEmplace(b.entry.key, res[i++]); }(); + } + return res; +} + +/// foreach opApply over all values +/// Note: +/// emulated by the compiler during CTFE +int _d_aaApply(K, V, DG)(inout V[K] a, DG dg) +{ + auto aa = () @trusted { return cast(AA!(K, V))_toAA!(K, V)(a); }(); + if (aa.empty) + return 0; + + foreach (b; aa.buckets) + { + if (!b.filled) + continue; + if (auto res = dg(b.entry.value)) + return res; + } + return 0; +} + +int _d_aaApply(K, V, DG)(shared V[K] a, DG dg) +{ + return _d_aaApply!(K, V, DG)(cast(V[K]) a, dg); +} + +int _d_aaApply(K, V, DG)(shared const V[K] a, DG dg) +{ + return _d_aaApply!(K, V, DG)(cast(const V[K]) a, dg); +} + +int _d_aaApply(K, V, DG)(immutable V[K] a, DG dg) +{ + return _d_aaApply!(K, V, DG)(cast(const V[K]) a, dg); +} + +/// foreach opApply over all key/value pairs +/// Note: +/// emulated by the compiler during CTFE +int _d_aaApply2(K, V, DG)(inout V[K] a, DG dg) +{ + auto aa = () @trusted { return cast(AA!(K, V))_toAA!(K, V)(a); }(); + if (aa.empty) + return 0; + + foreach (b; aa.buckets) + { + if (!b.filled) + continue; + if (auto res = dg(b.entry.key, b.entry.value)) + return res; + } + return 0; +} + +int _d_aaApply2(K, V, DG)(shared V[K] a, DG dg) +{ + return _d_aaApply2!(K, V, DG)(cast(V[K]) a, dg); +} + +int _d_aaApply2(K, V, DG)(shared const V[K] a, DG dg) +{ + return _d_aaApply2!(K, V, DG)(cast(const V[K]) a, dg); +} + +int _d_aaApply2(K, V, DG)(immutable V[K] a, DG dg) +{ + return _d_aaApply2!(K, V, DG)(cast(const V[K]) a, dg); +} + +/** Construct an associative array of type ti from corresponding keys and values. + * Called for an AA literal `[k1:v1, k2:v2]`. + * Params: + * keys = array of keys + * vals = array of values + * Returns: + * A new associative array opaque pointer, or null if `keys` is empty. + */ +Impl!(K, V)* _d_assocarrayliteralTX(K, V)(K[] keys, V[] vals) +{ + assert(keys.length == vals.length); + + immutable length = keys.length; + + if (!length) + return null; + + auto aa = new Impl!(K, V)(next_pow2(INIT_DEN * length / INIT_NUM)); + size_t duplicates = 0; + foreach (i; 0 .. length) + { + immutable hash = aa.calc_hash(keys[i]); + + auto p = aa.find_slot_lookup!K(hash, keys[i]); + if (p) + { + static if (__traits(compiles, p.entry.value = vals[i])) // immutable? + p.entry.value = vals[i]; + else + p.entry = _newEntry!(K, V)(keys[i], vals[i]); + duplicates++; + continue; + } + auto pi = aa.find_slot_insert(hash); + p = &aa.buckets[pi]; + p.hash = hash; + p.entry = _newEntry!(K, V)(keys[i], vals[i]); // todo: move key and value? + aa.first_used = min(aa.first_used, cast(uint)pi); + } + aa.used = cast(uint) (length - duplicates); + return aa; +} + +/// compares 2 AAs for equality +bool _aaEqual(T : AA!(K, V), K, V)(scope T aa1, scope T aa2) +{ + if (aa1 is aa2) + return true; + + immutable len = aa1.length; + if (len != aa2.length) + return false; + + if (!len) // both empty + return true; + + bool same_hash = aa1.hash_fn == aa2.hash_fn; // can be different if coming from template/rt + // compare the entries + foreach (b1; aa1.buckets[aa1.first_used .. $]) + { + if (!b1.filled) + continue; + hash_t hash = same_hash ? b1.hash : aa2.calc_hash(b1.entry.key); + auto pb2 = aa2.find_slot_lookup!K(hash, b1.entry.key); + if (pb2 is null || !pure_keyEqual!(V, V)(b1.entry.value, pb2.entry.value)) // rarely, inference on opEqual breaks builds here + return false; + } + return true; +} + +/// compares 2 AAs for equality (compiler hook) +bool _d_aaEqual(K, V)(scope const V[K] a1, scope const V[K] a2) +{ + scope aa1 = _toAA!(K, V)(a1); + scope aa2 = _toAA!(K, V)(a2); + return _aaEqual(aa1, aa2); +} + +/// callback from TypeInfo_AssociativeArray.equals (ignore const for now) +bool _aaOpEqual(K, V)(scope /* const */ AA!(K, V)* aa1, scope /* const */ AA!(K, V)* aa2) +{ + return _aaEqual(*aa1, *aa2); +} + +/// compute a hash callback from TypeInfo_AssociativeArray.xtoHash (ignore scope const for now) +hash_t _aaGetHash(K, V)(/* scope const */ AA!(K, V)* paa) +{ + const aa = *paa; + + if (aa.empty) + return 0; + + size_t h; + foreach (b; aa.buckets) + { + // use addition here, so that hash is independent of element order + if (b.filled) + h += hashOf(pure_hashOf!V(b.entry.value), pure_hashOf!K(b.entry.key)); + } + + return h; +} + +/** + * _aaRange implements a ForwardRange + */ +struct AARange(K, V) +{ + alias Key = substInout!K; + alias Value = substInout!V; + + Impl!(Key, Value)* impl; + size_t idx; + alias impl this; +} + +AARange!(K, V) _aaRange(K, V)(V[K] a) +{ + auto aa = _toAA!(K, V)(a); + if (!aa) + return AARange!(K, V)(); + + foreach (i; aa.first_used .. aa.dim) + { + if (aa.buckets[i].filled) + return AARange!(K, V)(aa, i); + } + return AARange!(K, V)(aa, aa.dim); +} + +bool _aaRangeEmpty(K, V)(AARange!(K, V) r) +{ + return r.impl is null || r.idx >= r.dim; +} + +K* _aaRangeFrontKey(K, V)(AARange!(K, V) r) +{ + assert(!_aaRangeEmpty(r)); + if (r.idx >= r.dim) + return null; + auto entry = r.buckets[r.idx].entry; + return entry is null ? null : &r.buckets[r.idx].entry.key; +} + +V* _aaRangeFrontValue(K, V)(AARange!(K, V) r) +{ + assert(!_aaRangeEmpty(r)); + if (r.idx >= r.dim) + return null; + + auto entry = r.buckets[r.idx].entry; + return entry is null ? null : &r.buckets[r.idx].entry.value; +} + +void _aaRangePopFront(K, V)(ref AARange!(K, V) r) +{ + if (r.idx >= r.dim) return; + for (++r.idx; r.idx < r.dim; ++r.idx) + { + if (r.buckets[r.idx].filled) + break; + } +} + +// test postblit for AA literals +// Disabled: uses core.memory/GC and AA syntax that can't resolve inside +// this module when compiled as source (circular object ↔ newaa import). +version (none) unittest +{ + import core.memory; + + static struct T + { + ubyte field; + static size_t postblit, dtor; + this(this) + { + ++postblit; + } + + ~this() + { + ++dtor; + } + } + + T t; + auto aa1 = [0 : t, 1 : t]; + assert(T.dtor == 2 && T.postblit == 4); + aa1[0] = t; + assert(T.dtor == 3 && T.postblit == 5); + + T.dtor = 0; + T.postblit = 0; + + auto aa2 = [0 : t, 1 : t, 0 : t]; // literal with duplicate key => value overwritten + assert(T.dtor == 4 && T.postblit == 6); + + T.dtor = 0; + T.postblit = 0; + + auto aa3 = [t : 0]; + assert(T.dtor == 1 && T.postblit == 2); + aa3[t] = 1; + assert(T.dtor == 1 && T.postblit == 2); + aa3.remove(t); + assert(T.dtor == 1 && T.postblit == 2); + aa3[t] = 2; + assert(T.dtor == 1 && T.postblit == 3); + + // dtor will be called by GC finalizers + aa1 = null; + aa2 = null; + aa3 = null; + auto dtor1 = typeid(TypeInfo_AssociativeArray.Entry!(int, T)).xdtor; + GC.runFinalizers((cast(char*)dtor1)[0 .. 1]); + auto dtor2 = typeid(TypeInfo_AssociativeArray.Entry!(T, int)).xdtor; + GC.runFinalizers((cast(char*)dtor2)[0 .. 1]); + assert(T.dtor == 7 && T.postblit == 3); +} + +// create a binary-compatible AA structure that can be used directly as an +// associative array. +// NOTE: this must only be called during CTFE +AA!(K, V) makeAA(K, V)(V[K] src) @trusted +{ + assert(__ctfe, "makeAA Must only be called at compile time"); + // Iterate the built-in AA directly - .keys/.values are UFCS properties + // that require druntime hooks we don't provide. + K[] keys; + V[] values; + foreach (k, v; src) + { + keys ~= k; + values ~= v; + } + auto impl = _d_assocarrayliteralTX!(K, V)(keys, values); + return AA!(K, V)(impl); +} + +// Disabled: AA-indexing lowering inside this module creates a circular +// import (object → core.internal.newaa → object) that prevents template +// resolution when compiled as source rather than a pre-compiled library. +version (none) unittest +{ + static struct Foo + { + ubyte x; + double d; + } + static int[Foo] utaa = [Foo(1, 2.0) : 5]; + auto k = Foo(1, 2.0); + // verify that getHash doesn't match hashOf for Foo + assert(typeid(Foo).getHash(&k) != hashOf(k)); + assert(utaa[Foo(1, 2.0)] == 5); +} diff --git a/src/urt/internal/bitop.d b/src/urt/internal/bitop.d new file mode 100644 index 0000000..cb68fe7 --- /dev/null +++ b/src/urt/internal/bitop.d @@ -0,0 +1,283 @@ +// TODO: DISSOLVE THIS FILE... +module urt.internal.bitop; + +nothrow @nogc @safe: + +version (D_InlineAsm_X86_64) + version = AsmX86; +else version (D_InlineAsm_X86) + version = AsmX86; + +version (X86_64) + version = AnyX86; +else version (X86) + version = AnyX86; + +// Use to implement 64-bit bitops on 32-bit arch. +private union Split64 +{ + ulong u64; + struct + { + version (LittleEndian) + { + uint lo; + uint hi; + } + else + { + uint hi; + uint lo; + } + } + + pragma(inline, true) + this(ulong u64) @safe pure nothrow @nogc + { + if (__ctfe) + { + lo = cast(uint) u64; + hi = cast(uint) (u64 >>> 32); + } + else + this.u64 = u64; + } +} + +/** + * Scans the bits in v starting with bit 0, looking + * for the first set bit. + * Returns: + * The bit number of the first bit set. + * The return value is undefined if v is zero. + */ +int bsf(uint v) pure +{ + pragma(inline, false); // so intrinsic detection will work + return softBsf!uint(v); +} + +/// ditto +int bsf(ulong v) pure +{ + static if (size_t.sizeof == ulong.sizeof) // 64 bit code gen + { + pragma(inline, false); // so intrinsic detection will work + return softBsf!ulong(v); + } + else + { + const sv = Split64(v); + return (sv.lo == 0)? + bsf(sv.hi) + 32 : + bsf(sv.lo); + } +} + +/** + * Scans the bits in v from the most significant bit + * to the least significant bit, looking + * for the first set bit. + * Returns: + * The bit number of the first bit set. + * The return value is undefined if v is zero. + */ +int bsr(uint v) pure +{ + pragma(inline, false); // so intrinsic detection will work + return softBsr!uint(v); +} + +/// ditto +int bsr(ulong v) pure +{ + static if (size_t.sizeof == ulong.sizeof) // 64 bit code gen + { + pragma(inline, false); // so intrinsic detection will work + return softBsr!ulong(v); + } + else + { + const sv = Split64(v); + return (sv.hi == 0)? + bsr(sv.lo) : + bsr(sv.hi) + 32; + } +} + +private alias softBsf(N) = softScan!(N, true); +private alias softBsr(N) = softScan!(N, false); + +private int softScan(N, bool forward)(N v) pure + if (is(N == uint) || is(N == ulong)) +{ + if (!v) + return -1; + + enum mask(ulong lo) = forward ? cast(N) lo : cast(N)~lo; + enum inc(int up) = forward ? up : -up; + + N x; + int ret; + static if (is(N == ulong)) + { + x = v & mask!0x0000_0000_FFFF_FFFFL; + if (x) + { + v = x; + ret = forward ? 0 : 63; + } + else + ret = forward ? 32 : 31; + + x = v & mask!0x0000_FFFF_0000_FFFFL; + if (x) + v = x; + else + ret += inc!16; + } + else static if (is(N == uint)) + { + x = v & mask!0x0000_FFFF; + if (x) + { + v = x; + ret = forward ? 0 : 31; + } + else + ret = forward ? 16 : 15; + } + else + static assert(false); + + x = v & mask!0x00FF_00FF_00FF_00FFL; + if (x) + v = x; + else + ret += inc!8; + + x = v & mask!0x0F0F_0F0F_0F0F_0F0FL; + if (x) + v = x; + else + ret += inc!4; + + x = v & mask!0x3333_3333_3333_3333L; + if (x) + v = x; + else + ret += inc!2; + + x = v & mask!0x5555_5555_5555_5555L; + if (!x) + ret += inc!1; + + return ret; +} + +/** + * Tests the bit. + */ +int bt(const scope size_t* p, size_t bitnum) pure @system +{ + static if (size_t.sizeof == 8) + return ((p[bitnum >> 6] & (1L << (bitnum & 63)))) != 0; + else static if (size_t.sizeof == 4) + return ((p[bitnum >> 5] & (1 << (bitnum & 31)))) != 0; + else + static assert(0); +} + +/** + * Tests and complements the bit. + */ +int btc(size_t* p, size_t bitnum) pure @system; + +/** + * Tests and resets (sets to 0) the bit. + */ +int btr(size_t* p, size_t bitnum) pure @system; + +/** + * Tests and sets the bit. + */ +int bts(size_t* p, size_t bitnum) pure @system; + +/** + * Swaps bytes in a 2 byte ushort. + */ +pragma(inline, false) +ushort byteswap(ushort x) pure +{ + return cast(ushort) (((x >> 8) & 0xFF) | ((x << 8) & 0xFF00u)); +} + +/** + * Swaps bytes in a 4 byte uint end-to-end. + */ +uint bswap(uint v) pure; + +/** + * Swaps bytes in an 8 byte ulong end-to-end. + */ +ulong bswap(ulong v) pure; + +version (DigitalMars) version (AnyX86) @system // not pure +{ + ubyte inp(uint port_address); + ushort inpw(uint port_address); + uint inpl(uint port_address); + ubyte outp(uint port_address, ubyte value); + ushort outpw(uint port_address, ushort value); + uint outpl(uint port_address, uint value); +} + +/** + * Calculates the number of set bits in an integer. + */ +int popcnt(uint x) pure +{ + return softPopcnt!uint(x); +} + +/// ditto +int popcnt(ulong x) pure +{ + static if (size_t.sizeof == uint.sizeof) + { + const sx = Split64(x); + return softPopcnt!uint(sx.lo) + softPopcnt!uint(sx.hi); + } + else static if (size_t.sizeof == ulong.sizeof) + { + return softPopcnt!ulong(x); + } + else + static assert(false); +} + +version (DigitalMars) version (AnyX86) +{ + ushort _popcnt( ushort x ) pure; + int _popcnt( uint x ) pure; + version (X86_64) + { + int _popcnt( ulong x ) pure; + } +} + +private int softPopcnt(N)(N x) pure + if (is(N == uint) || is(N == ulong)) +{ + enum mask1 = cast(N) 0x5555_5555_5555_5555L; + x = x - ((x>>1) & mask1); + enum mask2a = cast(N) 0xCCCC_CCCC_CCCC_CCCCL; + enum mask2b = cast(N) 0x3333_3333_3333_3333L; + x = ((x & mask2a)>>2) + (x & mask2b); + enum mask4 = cast(N) 0x0F0F_0F0F_0F0F_0F0FL; + x = (x + (x >> 4)) & mask4; + enum shiftbits = is(N == uint)? 24 : 56; + enum maskMul = cast(N) 0x0101_0101_0101_0101L; + x = (x * maskMul) >> shiftbits; + return cast(int) x; +} diff --git a/src/urt/internal/dwarfeh.d b/src/urt/internal/dwarfeh.d new file mode 100644 index 0000000..71a4f87 --- /dev/null +++ b/src/urt/internal/dwarfeh.d @@ -0,0 +1,779 @@ +/// DWARF / Itanium-ABI exception-handling runtime. +/// +/// Shared between DMD-Linux and LDC on every non-Windows target +/// (including bare-metal LDC like BL808). pragma(mangle) picks the +/// compiler-specific symbol names: +/// DMD: _d_throwdwarf, __dmd_begin_catch, __dmd_personality_v0 +/// LDC: _d_throw_exception, _d_eh_enter_catch, _d_eh_personality +/// +/// Lives in urt.internal (not urt.driver.posix) so it compiles on bare-metal +/// builds whose Makefile source list excludes urt/driver/posix/**. +/// +/// Ported from druntime rt/dwarfeh.d. +module urt.internal.dwarfeh; + +version (Windows) {} else: + +import urt.internal.exception : ClassInfo, _d_isbaseof, _d_createTrace; + + +// --------------------------------------------------------------------- +// DWARF exception handling (shared by DMD and LDC) +// +// Uses the GCC/DWARF unwinder (libgcc_s / libunwind). +// pragma(mangle) selects the compiler-specific symbol names: +// DMD: _d_throwdwarf, __dmd_begin_catch, __dmd_personality_v0 +// LDC: _d_throw_exception, _d_eh_enter_catch, _d_eh_personality +// +// Ported from druntime rt/dwarfeh.d. +// Copyright: Digital Mars 2015-2016 (original), uRT authors (port). +// License: Boost Software License 1.0 +// --------------------------------------------------------------------- + +// --- libunwind / libgcc_s bindings ----------------------------------- + +private: + +alias _Unwind_Ptr = size_t; +alias _Unwind_Word = size_t; +alias _Unwind_Exception_Class = ulong; +alias _uleb128_t = size_t; +alias _sleb128_t = ptrdiff_t; + +alias _Unwind_Reason_Code = int; +enum +{ + _URC_NO_REASON = 0, + _URC_FOREIGN_EXCEPTION_CAUGHT = 1, + _URC_FATAL_PHASE2_ERROR = 2, + _URC_FATAL_PHASE1_ERROR = 3, + _URC_NORMAL_STOP = 4, + _URC_END_OF_STACK = 5, + _URC_HANDLER_FOUND = 6, + _URC_INSTALL_CONTEXT = 7, + _URC_CONTINUE_UNWIND = 8, +} + +alias _Unwind_Action = int; +enum : _Unwind_Action +{ + _UA_SEARCH_PHASE = 1, + _UA_CLEANUP_PHASE = 2, + _UA_HANDLER_FRAME = 4, + _UA_FORCE_UNWIND = 8, +} + +alias _Unwind_Exception_Cleanup_Fn = extern(C) void function( + _Unwind_Reason_Code, _Unwind_Exception*); + +version (X86_64) +{ + align(16) struct _Unwind_Exception + { + _Unwind_Exception_Class exception_class; + _Unwind_Exception_Cleanup_Fn exception_cleanup; + _Unwind_Word private_1; + _Unwind_Word private_2; + } +} +else +{ + align(8) struct _Unwind_Exception + { + _Unwind_Exception_Class exception_class; + _Unwind_Exception_Cleanup_Fn exception_cleanup; + _Unwind_Word private_1; + _Unwind_Word private_2; + } +} + +struct _Unwind_Context; + +extern(C) nothrow @nogc +{ + _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception*); + void _Unwind_DeleteException(_Unwind_Exception*); + _Unwind_Word _Unwind_GetGR(_Unwind_Context*, int); + void _Unwind_SetGR(_Unwind_Context*, int, _Unwind_Word); + _Unwind_Ptr _Unwind_GetIP(_Unwind_Context*); + _Unwind_Ptr _Unwind_GetIPInfo(_Unwind_Context*, int*); + void _Unwind_SetIP(_Unwind_Context*, _Unwind_Ptr); + void* _Unwind_GetLanguageSpecificData(_Unwind_Context*); + _Unwind_Ptr _Unwind_GetRegionStart(_Unwind_Context*); +} + + +// --- ARM EABI unwinder types ---------------------------------------- + +version (ARM) +{ + alias _Unwind_State = int; + enum : _Unwind_State + { + _US_VIRTUAL_UNWIND_FRAME = 0, + _US_UNWIND_FRAME_STARTING = 1, + _US_UNWIND_FRAME_RESUME = 2, + _US_ACTION_MASK = 3, + _US_FORCE_UNWIND = 8, + } + + extern(C) void _Unwind_Complete(_Unwind_Exception*) nothrow @nogc; +} + +// --- EH register numbers (architecture-specific) -------------------- + +version (X86_64) +{ + enum eh_exception_regno = 0; + enum eh_selector_regno = 1; +} +else version (X86) +{ + enum eh_exception_regno = 0; + enum eh_selector_regno = 2; +} +else version (AArch64) +{ + enum eh_exception_regno = 0; + enum eh_selector_regno = 1; +} +else version (ARM) +{ + enum eh_exception_regno = 0; + enum eh_selector_regno = 1; +} +else version (RISCV64) +{ + enum eh_exception_regno = 10; + enum eh_selector_regno = 11; +} +else version (RISCV32) +{ + enum eh_exception_regno = 10; + enum eh_selector_regno = 11; +} +else version (Xtensa) +{ + enum eh_exception_regno = 2; // a2 + enum eh_selector_regno = 3; // a3 +} +else + static assert(0, "Unknown EH register numbers for this architecture"); + +// --- DWARF encoding constants --------------------------------------- + +enum +{ + DW_EH_PE_FORMAT_MASK = 0x0F, + DW_EH_PE_APPL_MASK = 0x70, + DW_EH_PE_indirect = 0x80, + + DW_EH_PE_omit = 0xFF, + DW_EH_PE_ptr = 0x00, + DW_EH_PE_uleb128 = 0x01, + DW_EH_PE_udata2 = 0x02, + DW_EH_PE_udata4 = 0x03, + DW_EH_PE_udata8 = 0x04, + DW_EH_PE_sleb128 = 0x09, + DW_EH_PE_sdata2 = 0x0A, + DW_EH_PE_sdata4 = 0x0B, + DW_EH_PE_sdata8 = 0x0C, + + DW_EH_PE_absptr = 0x00, + DW_EH_PE_pcrel = 0x10, + DW_EH_PE_textrel = 0x20, + DW_EH_PE_datarel = 0x30, + DW_EH_PE_funcrel = 0x40, + DW_EH_PE_aligned = 0x50, +} + +// --- DMD exception class identifier --------------------------------- + +enum _Unwind_Exception_Class dmd_exception_class = + (cast(_Unwind_Exception_Class)'D' << 56) | + (cast(_Unwind_Exception_Class)'M' << 48) | + (cast(_Unwind_Exception_Class)'D' << 40) | + (cast(_Unwind_Exception_Class)'D' << 24); + +// --- Compiler-specific symbol names --------------------------------- + +version (LDC) +{ + private enum throw_mangle = "_d_throw_exception"; + private enum catch_mangle = "_d_eh_enter_catch"; + private enum personality_mangle = "_d_eh_personality"; +} +else +{ + private enum throw_mangle = "_d_throwdwarf"; + private enum catch_mangle = "__dmd_begin_catch"; + private enum personality_mangle = "__dmd_personality_v0"; +} + +// --- ExceptionHeader ------------------------------------------------ + +struct ExceptionHeader +{ + Throwable object; + _Unwind_Exception exception_object; + + int handler; + const(ubyte)* language_specific_data; + _Unwind_Ptr landing_pad; + + ExceptionHeader* next; + + static ExceptionHeader* stack; // thread-local chain + static ExceptionHeader ehstorage; // pre-allocated (one per thread) + + static ExceptionHeader* create(Throwable o) nothrow @nogc + { + import urt.mem.alloc : alloc; + auto eh = &ehstorage; + if (eh.object) + { + eh = cast(ExceptionHeader*)alloc(ExceptionHeader.sizeof).ptr; + if (!eh) + dwarf_terminate(__LINE__); + } + eh.object = o; + eh.exception_object.exception_class = dmd_exception_class; + return eh; + } + + static void release(ExceptionHeader* eh) nothrow @nogc + { + import urt.mem.alloc : free; + *eh = ExceptionHeader.init; + if (eh != &ehstorage) + free(eh[0..1]); + } + + void push() nothrow @nogc + { + next = stack; + stack = &this; + } + + static ExceptionHeader* pop() nothrow @nogc + { + auto eh = stack; + stack = eh.next; + return eh; + } + + static ExceptionHeader* to_exception_header(_Unwind_Exception* eo) nothrow @nogc + { + return cast(ExceptionHeader*)(cast(void*) eo - ExceptionHeader.exception_object.offsetof); + } +} + +// --- Helpers -------------------------------------------------------- + +_Unwind_Ptr read_unaligned(T, bool consume)(ref const(ubyte)* p) nothrow @nogc @trusted +{ + import urt.processor : SupportUnalignedLoadStore; + static if (SupportUnalignedLoadStore) + T value = *cast(T*) p; + else + { + import urt.mem : memcpy; + T value = void; + memcpy(&value, p, T.sizeof); + } + + static if (consume) + p += T.sizeof; + return cast(_Unwind_Ptr) value; +} + +_uleb128_t u_leb128(const(ubyte)** p) nothrow @nogc +{ + auto q = *p; + _uleb128_t result = 0; + uint shift = 0; + while (1) + { + ubyte b = *q++; + result |= cast(_uleb128_t)(b & 0x7F) << shift; + if ((b & 0x80) == 0) + break; + shift += 7; + } + *p = q; + return result; +} + +_sleb128_t s_leb128(const(ubyte)** p) nothrow @nogc +{ + auto q = *p; + ubyte b; + _sleb128_t result = 0; + uint shift = 0; + while (1) + { + b = *q++; + result |= cast(_sleb128_t)(b & 0x7F) << shift; + shift += 7; + if ((b & 0x80) == 0) + break; + } + if (shift < result.sizeof * 8 && (b & 0x40)) + result |= -(cast(_sleb128_t)1 << shift); + *p = q; + return result; +} + +void dwarf_terminate(uint line) nothrow @nogc +{ + import urt.io : writef_to, WriteTarget; + import urt.internal.stdc.stdlib : abort; + writef_to!(WriteTarget.stderr, true)("dwarfeh({0}) fatal error", line); + abort(); +} + +// --- LSDA scanning -------------------------------------------------- + +enum LsdaResult +{ + not_found, + foreign, + corrupt, + no_action, + cleanup, + handler, +} + +ClassInfo get_class_info(_Unwind_Exception* exception_object, const(ubyte)* current_lsd) nothrow @nogc +{ + ExceptionHeader* eh = ExceptionHeader.to_exception_header(exception_object); + Throwable ehobject = eh.object; + for (ExceptionHeader* ehn = eh.next; ehn; ehn = ehn.next) + { + if (current_lsd != ehn.language_specific_data) + break; + Error e = cast(Error) ehobject; + if (e is null || (cast(Error) ehn.object) !is null) + ehobject = ehn.object; + } + return typeid(ehobject); +} + +int action_table_lookup(_Unwind_Exception* exception_object, uint action_record_ptr, const(ubyte)* p_action_table, const(ubyte)* tt, + ubyte ttype, _Unwind_Exception_Class exception_class, const(ubyte)* lsda) nothrow @nogc +{ + ClassInfo thrown_type; + if (exception_class == dmd_exception_class) + thrown_type = get_class_info(exception_object, lsda); + + for (auto ap = p_action_table + action_record_ptr - 1; 1; ) + { + auto type_filter = s_leb128(&ap); + auto apn = ap; + auto next_record_ptr = s_leb128(&ap); + + if (type_filter <= 0) + return -1; + + _Unwind_Ptr entry; + const(ubyte)* tt2; + switch (ttype & DW_EH_PE_FORMAT_MASK) + { + case DW_EH_PE_sdata2: entry = read_unaligned!(short, false)(tt2 = tt - type_filter * 2); break; + case DW_EH_PE_udata2: entry = read_unaligned!(ushort, false)(tt2 = tt - type_filter * 2); break; + case DW_EH_PE_sdata4: entry = read_unaligned!(int, false)(tt2 = tt - type_filter * 4); break; + case DW_EH_PE_udata4: entry = read_unaligned!(uint, false)(tt2 = tt - type_filter * 4); break; + case DW_EH_PE_sdata8: entry = read_unaligned!(long, false)(tt2 = tt - type_filter * 8); break; + case DW_EH_PE_udata8: entry = read_unaligned!(ulong, false)(tt2 = tt - type_filter * 8); break; + case DW_EH_PE_ptr: if (size_t.sizeof == 8) + goto case DW_EH_PE_udata8; + else + goto case DW_EH_PE_udata4; + default: + return -1; + } + if (!entry) + return -1; + + switch (ttype & DW_EH_PE_APPL_MASK) + { + case DW_EH_PE_absptr: + break; + case DW_EH_PE_pcrel: + entry += cast(_Unwind_Ptr) tt2; + break; + default: + return -1; + } + if (ttype & DW_EH_PE_indirect) + entry = *cast(_Unwind_Ptr*) entry; + + ClassInfo ci = cast(ClassInfo) cast(void*) entry; + + // D exception - check class hierarchy + if (exception_class == dmd_exception_class && _d_isbaseof(thrown_type, ci)) + return cast(int) type_filter; + + if (!next_record_ptr) + return 0; + + ap = apn + next_record_ptr; + } + assert(0); // unreachable - all paths return inside the loop +} + +LsdaResult scan_lsda(const(ubyte)* lsda, _Unwind_Ptr ip, _Unwind_Exception_Class exception_class, bool cleanups_only, bool prefer_handler, + _Unwind_Exception* exception_object, out _Unwind_Ptr landing_pad, out int handler) nothrow @nogc +{ + auto p = lsda; + if (!p) + return LsdaResult.no_action; + + _Unwind_Ptr dw_pe_value(ubyte pe) + { + switch (pe) + { + case DW_EH_PE_sdata2: return read_unaligned!(short, true)(p); + case DW_EH_PE_udata2: return read_unaligned!(ushort, true)(p); + case DW_EH_PE_sdata4: return read_unaligned!(int, true)(p); + case DW_EH_PE_udata4: return read_unaligned!(uint, true)(p); + case DW_EH_PE_sdata8: return read_unaligned!(long, true)(p); + case DW_EH_PE_udata8: return read_unaligned!(ulong, true)(p); + case DW_EH_PE_sleb128: return cast(_Unwind_Ptr) s_leb128(&p); + case DW_EH_PE_uleb128: return cast(_Unwind_Ptr) u_leb128(&p); + case DW_EH_PE_ptr: if (size_t.sizeof == 8) + goto case DW_EH_PE_udata8; + else + goto case DW_EH_PE_udata4; + default: + dwarf_terminate(__LINE__); + return 0; + } + } + + ubyte lp_start = *p++; + + _Unwind_Ptr lp_base = 0; + if (lp_start != DW_EH_PE_omit) + lp_base = dw_pe_value(lp_start); + + ubyte ttype = *p++; + _Unwind_Ptr tt_base = 0; + _Unwind_Ptr tt_offset = 0; + if (ttype != DW_EH_PE_omit) + { + tt_base = u_leb128(&p); + tt_offset = (p - lsda) + tt_base; + } + + ubyte call_site_format = *p++; + _Unwind_Ptr call_site_table_size = dw_pe_value(DW_EH_PE_uleb128); + + _Unwind_Ptr ip_offset = ip - lp_base; + bool no_action = false; + auto tt = lsda + tt_offset; + const(ubyte)* p_action_table = p + call_site_table_size; + + while (1) + { + if (p >= p_action_table) + { + if (p == p_action_table) + break; + return LsdaResult.corrupt; + } + + _Unwind_Ptr call_site_start = dw_pe_value(call_site_format); + _Unwind_Ptr call_site_range = dw_pe_value(call_site_format); + _Unwind_Ptr call_site_lp = dw_pe_value(call_site_format); + _uleb128_t action_record_ptr_val = u_leb128(&p); + + if (ip_offset < call_site_start) + break; + + if (ip_offset < call_site_start + call_site_range) + { + if (action_record_ptr_val) + { + if (cleanups_only) + continue; + + auto h = action_table_lookup(exception_object, cast(uint) action_record_ptr_val, + p_action_table, tt, ttype, exception_class, lsda); + if (h < 0) + return LsdaResult.corrupt; + if (h == 0) + continue; + + no_action = false; + landing_pad = call_site_lp; + handler = h; + } + else if (call_site_lp) + { + if (prefer_handler && handler) + continue; + no_action = false; + landing_pad = call_site_lp; + handler = 0; + } + else + no_action = true; + } + } + + if (no_action) + return LsdaResult.no_action; + + if (landing_pad) + return handler ? LsdaResult.handler : LsdaResult.cleanup; + + return LsdaResult.not_found; +} + +// --- Public API ------------------------------------------------------ + +pragma(mangle, catch_mangle) +extern(C) Throwable dwarfeh_begin_catch(_Unwind_Exception* exception_object) nothrow @nogc +{ + version (ARM) version (LDC) + _Unwind_Complete(exception_object); + + ExceptionHeader* eh = ExceptionHeader.to_exception_header(exception_object); + auto o = eh.object; + eh.object = null; + + if (eh != ExceptionHeader.pop()) + dwarf_terminate(__LINE__); + + _Unwind_DeleteException(&eh.exception_object); + return o; +} + +extern(C) void* _d_eh_swapContextDwarf(void* newContext) nothrow @nogc +{ + auto old = ExceptionHeader.stack; + ExceptionHeader.stack = cast(ExceptionHeader*) newContext; + return old; +} + +pragma(mangle, throw_mangle) +extern(C) void dwarfeh_throw(Throwable o) +{ + import urt.io : writeln_err, writef_to, WriteTarget; + import urt.internal.stdc.stdlib : abort; + + ExceptionHeader* eh = ExceptionHeader.create(o); + eh.push(); + + auto refcount = o.refcount(); + if (refcount) + o.refcount() = refcount + 1; + + extern(C) static void exception_cleanup(_Unwind_Reason_Code reason, + _Unwind_Exception* eo) nothrow @nogc + { + switch (reason) + { + case _URC_FOREIGN_EXCEPTION_CAUGHT: + case _URC_NO_REASON: + ExceptionHeader.release(ExceptionHeader.to_exception_header(eo)); + break; + default: + dwarf_terminate(__LINE__); + } + } + + eh.exception_object.exception_cleanup = &exception_cleanup; + _d_createTrace(o, null); + + auto r = _Unwind_RaiseException(&eh.exception_object); + + // Should not return - if it did, the exception was not caught. + dwarfeh_begin_catch(&eh.exception_object); + writeln_err("uncaught exception reached top of stack"); + auto msg = o.msg; + if (msg.length) + writef_to!(WriteTarget.stderr, true)(" {0}", msg); + abort(); +} + +// Common personality implementation. +_Unwind_Reason_Code dwarfeh_personality_common(_Unwind_Action actions, _Unwind_Exception_Class exception_class, _Unwind_Exception* exception_object, _Unwind_Context* context) nothrow @nogc +{ + const(ubyte)* language_specific_data; + int handler; + _Unwind_Ptr landing_pad; + + language_specific_data = cast(const(ubyte)*) _Unwind_GetLanguageSpecificData(context); + auto Start = _Unwind_GetRegionStart(context); + + // Get IP; use _Unwind_GetIPInfo to handle signal frames correctly. + int ip_before_insn; + auto ip = _Unwind_GetIPInfo(context, &ip_before_insn); + if (!ip_before_insn) + --ip; + + auto result = scan_lsda(language_specific_data, ip - Start, exception_class, + (actions & _UA_FORCE_UNWIND) != 0, + (actions & _UA_SEARCH_PHASE) != 0, + exception_object, + landing_pad, + handler); + landing_pad += Start; + + final switch (result) + { + case LsdaResult.not_found: + dwarf_terminate(__LINE__); + assert(0); + + case LsdaResult.foreign: + dwarf_terminate(__LINE__); + assert(0); + + case LsdaResult.corrupt: + dwarf_terminate(__LINE__); + assert(0); + + case LsdaResult.no_action: + return _URC_CONTINUE_UNWIND; + + case LsdaResult.cleanup: + if (actions & _UA_SEARCH_PHASE) + return _URC_CONTINUE_UNWIND; + break; + + case LsdaResult.handler: + if (actions & _UA_SEARCH_PHASE) + { + if (exception_class == dmd_exception_class) + { + auto eh = ExceptionHeader.to_exception_header(exception_object); + eh.handler = handler; + eh.language_specific_data = language_specific_data; + eh.landing_pad = landing_pad; + } + return _URC_HANDLER_FOUND; + } + break; + } + + // Multiple exceptions in flight - chain them + if (exception_class == dmd_exception_class) + { + auto eh = ExceptionHeader.to_exception_header(exception_object); + auto current_lsd = language_specific_data; + bool bypassed = false; + + while (eh.next) + { + ExceptionHeader* ehn = eh.next; + + Error e = cast(Error) eh.object; + if (e !is null && !cast(Error) ehn.object) + { + current_lsd = ehn.language_specific_data; + eh = ehn; + bypassed = true; + continue; + } + + if (current_lsd != ehn.language_specific_data) + break; + + eh.object = Throwable.chainTogether(ehn.object, eh.object); + + if (ehn.handler != handler && !bypassed) + { + handler = ehn.handler; + eh.handler = handler; + eh.language_specific_data = language_specific_data; + eh.landing_pad = landing_pad; + } + + eh.next = ehn.next; + _Unwind_DeleteException(&ehn.exception_object); + } + + if (bypassed) + { + eh = ExceptionHeader.to_exception_header(exception_object); + Error e = cast(Error) eh.object; + auto ehn = eh.next; + e.bypassedException = ehn.object; + eh.next = ehn.next; + _Unwind_DeleteException(&ehn.exception_object); + } + } + + _Unwind_SetGR(context, eh_exception_regno, cast(_Unwind_Word) exception_object); + _Unwind_SetGR(context, eh_selector_regno, handler); + _Unwind_SetIP(context, landing_pad); + + return _URC_INSTALL_CONTEXT; +} + +// Personality function entry points. +// ARM EABI uses a different calling convention than the standard Itanium ABI. +// Bare-metal ARM uses DWARF EH, not ARM EHABI, so use the standard personality. +version (ARM) +{ + version (Beken) + enum UseArmEhabi = true; + else version (BareMetal) + enum UseArmEhabi = false; + else version (LDC) + enum UseArmEhabi = true; + else + enum UseArmEhabi = false; +} +else + enum UseArmEhabi = false; + +static if (UseArmEhabi) +{ + extern(C) _Unwind_Reason_Code _d_eh_personality(_Unwind_State state, _Unwind_Exception* exception_object, _Unwind_Context* context) nothrow @nogc + { + _Unwind_Action actions; + switch (state & _US_ACTION_MASK) + { + case _US_VIRTUAL_UNWIND_FRAME: + actions = _UA_SEARCH_PHASE; + break; + case _US_UNWIND_FRAME_STARTING: + actions = _UA_CLEANUP_PHASE; + break; + case _US_UNWIND_FRAME_RESUME: + return _URC_CONTINUE_UNWIND; + default: + dwarf_terminate(__LINE__); + return _URC_FATAL_PHASE1_ERROR; + } + if (state & _US_FORCE_UNWIND) + actions |= _UA_FORCE_UNWIND; + + return dwarfeh_personality_common(actions, exception_object.exception_class, + exception_object, context); + } +} +else +{ + pragma(mangle, personality_mangle) + extern(C) _Unwind_Reason_Code dwarfeh_personality(int ver, _Unwind_Action actions, _Unwind_Exception_Class exception_class, _Unwind_Exception* exception_object, _Unwind_Context* context) nothrow @nogc + { + if (ver != 1) + return _URC_FATAL_PHASE1_ERROR; + + return dwarfeh_personality_common(actions, exception_class, + exception_object, context); + } +} + +// LDC-only: trivial cleanup hooks (DWARF handles cleanup via personality). +version (LDC) +{ + extern(C) bool _d_enter_cleanup(void* ptr) nothrow @nogc @trusted => true; + extern(C) void _d_leave_cleanup(void* ptr) nothrow @nogc @trusted {} +} + diff --git a/src/urt/internal/exception.d b/src/urt/internal/exception.d new file mode 100644 index 0000000..fddc42c --- /dev/null +++ b/src/urt/internal/exception.d @@ -0,0 +1,539 @@ +module urt.internal.exception; + +version (Windows) + import urt.driver.windows.exception : _capture_trace, _caller_address, _resolve_address, _resolve_batch; +else version (Espressif) + import urt.driver.esp32.exception : _capture_trace, _caller_address, _resolve_address, _resolve_batch; +else version (BareMetal) + import urt.driver.baremetal.exception : _capture_trace, _caller_address, _resolve_address, _resolve_batch; +else + import urt.driver.posix.exception : _capture_trace, _caller_address, _resolve_address, _resolve_batch; + +nothrow @nogc: + + +// Public API + +// Resolved symbol information for a single return address. Fields are +// best-effort - any of them may be empty/zero if the driver can't +// supply them (no on-device symtab, stripped binary, missing DWARF). +// `name` is the raw symbol as the driver sees it - possibly D-mangled +// (`_D...`); pass through `demangle_symbol` before display. +// String slices are owned by driver static/TLS storage - copy before +// the next `_resolve_address`/`_resolve_batch` call. +struct Resolved +{ + const(char)[] name; + const(char)[] file; + const(char)[] dir; + uint line; + size_t offset; // addr - symbol_base +} + +// TCO-defeat anchor. Any wrapper that MUST be a real frame at runtime +// (because the fp walker is counting frames) calls defeat_tco() between +// the inner call and the return. A volatile write LLVM can't prove dead +// blocks both tail-call optimisation and prologue/frame elision. +private __gshared uint _tco_anchor; + +pragma(inline, false) +void defeat_tco() @trusted nothrow @nogc +{ + import core.volatile : volatileLoad, volatileStore; + volatileStore(&_tco_anchor, volatileLoad(&_tco_anchor) + 1); +} + +pragma(inline, false) +size_t capture_trace(void*[] addrs) @trusted +{ + auto r = _capture_trace(addrs); + defeat_tco(); + return r; +} + +pragma(inline, false) +void* caller_address(uint skip = 0) @trusted +{ + auto r = _caller_address(skip); + defeat_tco(); + return r; +} + +bool resolve_address(void* addr, out Resolved r) @trusted +{ + return _resolve_address(addr, r); +} + +bool resolve_batch(const(void*)[] addrs, Resolved[] results) @trusted +{ + assert(addrs.length == results.length); + return _resolve_batch(addrs, results); +} + +version (Tiny) +{ + const(char)[] demangle_symbol(const(char)[] mangled, char[]) @trusted + => mangled; +} +else +{ + const(char)[] demangle_symbol(const(char)[] mangled, char[] buf) @trusted + { + import urt.array : beginsWith; + import urt.conv : parse_uint; + import urt.mem : memcpy; + + if (mangled.length < 3 || !mangled.beginsWith("_D")) + return mangled; + + auto src = mangled[2 .. $]; + size_t pos = 0; + bool first = true; + + while (src.length > 0) + { + auto ch = src[0]; + + if (ch >= '1' && ch <= '9') + { + // LName: decimal length followed by that many characters + size_t taken; + size_t len = cast(size_t) parse_uint(src, &taken); + src = src[taken .. $]; + if (len > src.length || pos + len + 1 > buf.length) + break; + + if (!first) + buf[pos++] = '.'; + first = false; + + buf[pos .. pos + len] = src[0 .. len]; + pos += len; + src = src[len .. $]; + } + else if (ch == 'Q') + { + // Back reference: base-26 offset pointing to an earlier LName. + auto q_pos = cast(size_t)(src.ptr - mangled.ptr); + src = src[1 .. $]; + + size_t ref_val = 0; + while (src.length > 0 && src[0] >= 'A' && src[0] <= 'Z') + { + ref_val = ref_val * 26 + (src[0] - 'A'); + src = src[1 .. $]; + } + if (src.length > 0 && src[0] >= 'a' && src[0] <= 'z') + { + ref_val = ref_val * 26 + (src[0] - 'a'); + src = src[1 .. $]; + } + else + break; // malformed + + if (ref_val >= q_pos) + break; + auto target = mangled[q_pos - ref_val .. $]; + if (target.length == 0 || target[0] < '1' || target[0] > '9') + break; + + size_t taken; + size_t len = cast(size_t) parse_uint(target, &taken); + target = target[taken .. $]; + if (len > target.length || pos + len + 1 > buf.length) + break; + + if (!first) + buf[pos++] = '.'; + first = false; + + buf[pos .. pos + len] = target[0 .. len]; + pos += len; + } + else if (ch == '_' && src.length >= 3 && src[1] == '_' && (src[2] == 'T' || src[2] == 'U')) + { + // Template instance __T/__U: extract name, skip args until Z + src = src[3 .. $]; + + if (src.length > 0 && src[0] >= '1' && src[0] <= '9') + { + size_t taken; + size_t len = cast(size_t) parse_uint(src, &taken); + src = src[taken .. $]; + if (len <= src.length && pos + len + 1 <= buf.length) + { + if (!first) + buf[pos++] = '.'; + first = false; + + buf[pos .. pos + len] = src[0 .. len]; + pos += len; + src = src[len .. $]; + } + } + + int depth = 1; + while (src.length > 0 && depth > 0) + { + if (src[0] == 'Z') + --depth; + else if (src.length >= 3 && src[0] == '_' && src[1] == '_' && (src[2] == 'T' || src[2] == 'U')) + { + ++depth; + src = src[2 .. $]; + } + src = src[1 .. $]; + } + } + else if (ch == '0') + src = src[1 .. $]; // anonymous - skip + else + break; // type signature - done + } + + if (pos == 0) + return mangled; + + // Append $TypeSignature if there's anything left + if (src.length > 0 && pos + 1 + src.length <= buf.length) + { + buf[pos++] = '$'; + buf[pos .. pos + src.length] = src[]; + pos += src.length; + } + + return buf[0 .. pos]; + } +} + +// Print a captured trace to stderr. +// +// formats each frame as: `{dir}/{file}:{line} {name}+0x{offset} [0x{address}]` +// with graceful degradation: +// file:line missing → `??:?` +// symbol missing → drop the `name+0x...` component +// nothing resolved → ` 0x{address}` only +// Stops after emitting `_Dmain` / `main` to hide C runtime tail noise. +version (Tiny) +{ + void print_trace(const(void*)[] addrs) @trusted + { + import urt.io : writeln_err; + + enum addr_fmt = size_t.sizeof == 4 ? "08x" : "016x"; + foreach (addr; addrs) + writeln_err(" 0x", addr); + } +} +else +{ + void print_trace(const(void*)[] addrs) @trusted + { + import urt.io : write_err, writeln_err, writef_to, WriteTarget; + import urt.string : endsWith; + + if (addrs.length == 0) + return; + + const n = addrs.length > max_frames ? max_frames : addrs.length; + + Resolved[max_frames] results; + const have_symbols = _resolve_batch(addrs[0 .. n], results[0 .. n]); + + enum addr_fmt = size_t.sizeof == 4 ? "08x" : "016x"; + + if (!have_symbols) + { + foreach (addr; addrs[0 .. n]) + writeln_err(" 0x", addr); + return; + } + + // Skip internal throw machinery - start after the last matching frame. Matches LDC druntime behavior. + size_t start = 0; + foreach (i; 0 .. n) + { + auto name = results[i].name; + if (name.endsWith("_d_throw_exception") || name.endsWith("_d_throwdwarf")) + start = i + 1; + } + + foreach (i; start .. n) + { + auto addr = addrs[i]; + auto r = &results[i]; + const bool have_any = r.name.length > 0 || r.line > 0; + + if (!have_any) + { + writeln_err(" 0x", addr); + continue; + } + + // file:line (or ??:? when missing) + if (r.line > 0 && r.file.length > 0) + { + if (r.dir.length > 0) + { + const sep = (r.dir[$ - 1] == '/' || r.dir[$ - 1] == '\\') ? "" : "/"; + writef_to!(WriteTarget.stderr, false)(" {0}{1}{2}:{3}", r.dir, sep, r.file, r.line); + } + else + write_err(" ", r.file, ':', r.line); + } + else + write_err(" ??:?"); + + // symbol+offset (demangled) + if (r.name.length > 0) + { + char[512] dbuf = void; + auto dname = demangle_symbol(r.name, dbuf); + writef_to!(WriteTarget.stderr, false)(" {0}+0x{1,x}", dname, r.offset); + } + + writeln_err(" [0x", addr, ']'); + + // Stop at program entry - hides C runtime tail noise. + if (r.name == "_Dmain" || r.name == "main") + break; + } + } +} + +public void terminate() @trusted +{ + import urt.io : writeln_err; + writeln_err("Unhandled exception -- no catch handler found, terminating."); + + if (_tls_trace.length > 0) + { + writeln_err(" stack trace:"); + print_trace(_tls_trace.addrs[0 .. _tls_trace.length]); + } + + import urt.internal.stdc.stdlib : abort; + abort(); +} + + +// Shared state + +enum max_frames = 32; + +struct StackTraceData +{ + void*[max_frames] addrs; + ubyte length; +} + +private StackTraceData _tls_trace; // static = TLS in D + + +// Druntime hooks (extern(C), linker-visible) + +alias ClassInfo = TypeInfo_Class; + +extern(C) int _d_isbaseof(scope ClassInfo oc, scope const ClassInfo c) pure @trusted +{ + if (oc is c) + return true; + + do + { + if (oc.base is c) + return true; + + foreach (iface; oc.interfaces) + { + if (iface.classinfo is c || _d_isbaseof(iface.classinfo, c)) + return true; + } + + oc = oc.base; + } + while (oc); + + return false; +} + + +extern(C) void _d_createTrace(Throwable, void*) @trusted +{ + debug + _tls_trace.length = cast(ubyte) _capture_trace(_tls_trace.addrs[]); +} + +extern(C) void _d_printLastTrace(Throwable t) @trusted +{ + debug + { + import urt.io : writeln_err, writef_to, WriteTarget; + + if (_tls_trace.length == 0) + return; + + if (t !is null) + { + auto msg = t.msg; + writef_to!(WriteTarget.stderr, true)("Exception: {0}", msg); + } + + writeln_err(" stack trace:"); + print_trace(_tls_trace.addrs[0 .. _tls_trace.length]); + } +} + + +version (unittest) +{ + private bool eh_contains(const(char)[] haystack, const(char)[] needle) @trusted nothrow @nogc + { + if (needle.length == 0) + return true; + if (needle.length > haystack.length) + return false; + foreach (i; 0 .. haystack.length - needle.length + 1) + if (haystack[i .. i + needle.length] == needle) + return true; + return false; + } + + // Skip-count verification layers. Each calls defeat_tco() between the + // inner call and the return so LDC keeps the frame instead of tail- + // calling. Distinct, grep-friendly names make the resolved symbols + // easy to match. + + private void* eh_ca_layer_0(uint skip) @trusted nothrow @nogc + { + auto pc = caller_address(skip); + defeat_tco(); + return pc; + } + + private void* eh_ca_layer_1(uint skip) @trusted nothrow @nogc + { + auto pc = eh_ca_layer_0(skip); + defeat_tco(); + return pc; + } + + private void* eh_ca_layer_2(uint skip) @trusted nothrow @nogc + { + auto pc = eh_ca_layer_1(skip); + defeat_tco(); + return pc; + } + + // Demangler target - `.mangleof` gives us the real D-mangled form at + // compile time, so the test is stable across compilers. + private void eh_demangle_target() @trusted nothrow @nogc {} + + // Helper: this unittest function is what we expect to find as the + // caller in the capture_trace and skip-count tests below. defeat_tco + // keeps eh_capture_here as a real frame so the walker captures + // capture_trace's saved ra (= a PC inside eh_capture_here) as buf[0]. + private size_t eh_capture_here(void*[] buf) @trusted nothrow @nogc + { + auto n = capture_trace(buf); + defeat_tco(); + return n; + } +} + +unittest +{ + // capture_trace produces a non-empty trace whose first frame + // is in the function that called it (eh_capture_here). + + void*[max_frames] buf; + auto n = eh_capture_here(buf[]); + assert(n > 0); + foreach (addr; buf[0 .. n]) + assert(addr !is null); + + // First captured frame should resolve to the immediate caller - + // eh_capture_here. (Skipped on platforms with no symbol table.) + Resolved r; + if (resolve_address(buf[0], r)) + { + char[512] dbuf; + auto name = demangle_symbol(r.name, dbuf); + assert(eh_contains(name, "eh_capture_here"), name); + } + + // caller_address skip walks one frame per increment, starting + // from the caller of the function that called caller_address. + + // From eh_ca_layer_0: + // skip=0 → PC inside eh_ca_layer_1 (layer_0's caller) + // skip=1 → PC inside eh_ca_layer_2 (layer_1's caller) + // skip=2 → PC inside this unittest (layer_2's caller) + auto pc0 = eh_ca_layer_2(0); + auto pc1 = eh_ca_layer_2(1); + auto pc2 = eh_ca_layer_2(2); + + assert(pc0 !is null); + assert(pc1 !is null); + assert(pc2 !is null); + + // Distinct PCs - each skip level yields a different call site. + assert(pc0 != pc1); + assert(pc1 != pc2); + assert(pc0 != pc2); + + // Strong check via the symbol resolver. Bare-metal / ESP32 have no + // on-device symtab and silently skip - the distinct-PC check above + // is the strongest assertion they can verify. + char[512] name; + + if (resolve_address(pc0, r)) + { + auto mangle = demangle_symbol(r.name, name); + assert(eh_contains(mangle, "eh_ca_layer_1"), mangle); + } + if (resolve_address(pc1, r)) + { + auto mangle = demangle_symbol(r.name, name); + assert(eh_contains(mangle, "eh_ca_layer_2"), mangle); + } + + // demangler + + // Non-D / degenerate inputs pass through unchanged. This holds for both + // the real demangler and the Tiny stub (which returns input unchanged + // for everything), so these asserts always run. + assert(demangle_symbol("main", name) == "main"); + assert(demangle_symbol("", name) == ""); + assert(demangle_symbol("_D", name) == "_D"); + assert(demangle_symbol("?MyClass@@QAEXXZ", name) == "?MyClass@@QAEXXZ"); + + // Real demangling tests -- skipped on Tiny because the stub there just + // returns input unchanged (size optimisation; offline addr2line gives + // the symbol name anyway). + version (Tiny) {} + else + { + // Real D mangling via .mangleof - qualified path must contain the + // function name and at least one module-separator dot. + auto dem = demangle_symbol(eh_demangle_target.mangleof, name); + assert(eh_contains(dem, "eh_demangle_target"), dem); + bool has_dot = false; + foreach (c; dem) if (c == '.') + { + has_dot = true; + break; + } + assert(has_dot, dem); + + // Hand-crafted ABI-compliant manglings - parse must recover the + // qualified name prefix regardless of the trailing type signature. + assert(eh_contains(demangle_symbol("_D3foo3barFZv", name), "foo.bar")); + assert(eh_contains(demangle_symbol("_D3foo3bar3bazFZv", name), "foo.bar.baz")); + + // Malformed input must not crash - output is undefined but safe. + demangle_symbol("_D999zzz", name); // LName length overflows src + demangle_symbol("_D3fooQ", name); // Q back-ref with no offset + demangle_symbol("_D__T1aZ", name); // template with minimal content + } +} diff --git a/src/urt/internal/lifetime.d b/src/urt/internal/lifetime.d new file mode 100644 index 0000000..1f9c3a9 --- /dev/null +++ b/src/urt/internal/lifetime.d @@ -0,0 +1,121 @@ +module urt.internal.lifetime; + +import urt.lifetime : forward; + +/+ +emplaceRef is a package function for druntime internal use. It works like +emplace, but takes its argument by ref (as opposed to "by pointer"). +This makes it easier to use, easier to be safe, and faster in a non-inline +build. +Furthermore, emplaceRef optionally takes a type parameter, which specifies +the type we want to build. This helps to build qualified objects on mutable +buffer, without breaking the type system with unsafe casts. ++/ +void emplaceRef(T, UT, Args...)(ref UT chunk, auto ref Args args) +{ + static if (args.length == 0) + { + static assert(is(typeof({static T i;})), + "Cannot emplace a " ~ T.stringof ~ " because " ~ T.stringof ~ + ".this() is annotated with @disable."); + static if (is(T == class)) static assert(!__traits(isAbstractClass, T), + T.stringof ~ " is abstract and it can't be emplaced"); + emplaceInitializer(chunk); + } + else static if ( + !is(T == struct) && Args.length == 1 /* primitives, enums, arrays */ + || + Args.length == 1 && is(typeof({T t = forward!(args[0]);})) /* conversions */ + || + is(typeof(T(forward!args))) /* general constructors */) + { + static struct S + { + T payload; + this()(auto ref Args args) + { + static if (__traits(compiles, payload = forward!args)) + payload = forward!args; + else + payload = T(forward!args); + } + } + if (__ctfe) + { + static if (__traits(compiles, chunk = T(forward!args))) + chunk = T(forward!args); + else static if (args.length == 1 && __traits(compiles, chunk = forward!(args[0]))) + chunk = forward!(args[0]); + else assert(0, "CTFE emplace doesn't support " + ~ T.stringof ~ " from " ~ Args.stringof); + } + else + { + S* p = () @trusted { return cast(S*) &chunk; }(); + static if (UT.sizeof > 0) + emplaceInitializer(*p); + p.__ctor(forward!args); + } + } + else static if (is(typeof(chunk.__ctor(forward!args)))) + { + // This catches the rare case of local types that keep a frame pointer + emplaceInitializer(chunk); + chunk.__ctor(forward!args); + } + else + { + //We can't emplace. Try to diagnose a disabled postblit. + static assert(!(Args.length == 1 && is(Args[0] : T)), + "Cannot emplace a " ~ T.stringof ~ " because " ~ T.stringof ~ + ".this(this) is annotated with @disable."); + + //We can't emplace. + static assert(false, + T.stringof ~ " cannot be emplaced from " ~ Args[].stringof ~ "."); + } +} + +// ditto +static import urt.traits; +void emplaceRef(UT, Args...)(ref UT chunk, auto ref Args args) + if (is(UT == urt.traits.Unqual!UT)) +{ + emplaceRef!(UT, UT)(chunk, forward!args); +} + +/+ +Emplaces T.init. +In contrast to `emplaceRef(chunk)`, there are no checks for disabled default +constructors etc. ++/ +void emplaceInitializer(T)(scope ref T chunk) nothrow pure @trusted + if (!is(T == const) && !is(T == immutable) && !is(T == inout)) +{ + import urt.internal.traits : hasElaborateAssign; + + static if (__traits(isZeroInit, T)) + { + import urt.mem : memset; + memset(cast(void*) &chunk, 0, T.sizeof); + } + else static if (__traits(isScalar, T) || + T.sizeof <= 16 && !hasElaborateAssign!T && __traits(compiles, (){ T chunk; chunk = T.init; })) + { + chunk = T.init; + } + else static if (__traits(isStaticArray, T)) + { + // For static arrays there is no initializer symbol created. Instead, we emplace elements one-by-one. + foreach (i; 0 .. T.length) + { + emplaceInitializer(chunk[i]); + } + } + else + { + import urt.mem : memcpy; + const initializer = __traits(initSymbol, T); + memcpy(cast(void*)&chunk, initializer.ptr, initializer.length); + } +} diff --git a/src/urt/internal/mbedtls.c b/src/urt/internal/mbedtls.c new file mode 100644 index 0000000..59f548d --- /dev/null +++ b/src/urt/internal/mbedtls.c @@ -0,0 +1,474 @@ +// C wrappers for mbedtls - sizeof() for opaque types, and wrappers for +// functions that access internal struct layouts D cannot safely replicate. + +#if !defined(_WIN32) + +#include +#include +#include + +// mbedtls 4.x reorganised around PSA-Crypto. It moved a lot of classic +// primitive headers into (still callable but upstream- +// unstable) and deleted entropy/ctr_drbg/ssl_conf_rng entirely from IDF's +// build -- only PSA RNG is exposed there. We hide the divergence here so D +// only sees one urt_* API across all mbedtls versions. +#if MBEDTLS_VERSION_MAJOR >= 4 +#include +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#include +#include +#include +#endif +#include +#include +#include + + +// ===================================================================== +// sizeof() for opaque types -- D-side allocates these via urt_*_new/delete +// ===================================================================== + +size_t urt_sizeof_x509_crt(void) { return sizeof(mbedtls_x509_crt); } +size_t urt_sizeof_ssl_context(void) { return sizeof(mbedtls_ssl_context); } +size_t urt_sizeof_ssl_config(void) { return sizeof(mbedtls_ssl_config); } + + +// ===================================================================== +// RNG layer -- unified across 2.x/3.x/4.x +// +// 4.x: PSA owns the RNG (psa_crypto_init + psa_generate_random). +// <4 : classic entropy + CTR-DRBG, held module-static and lazily seeded. +// +// urt_rng_callback has the (void*, unsigned char*, size_t) shape that +// classic mbedtls APIs (ecdh_compute_shared, etc.) expect as f_rng; the +// p_rng parameter is unused and may be NULL. +// ===================================================================== + +#if MBEDTLS_VERSION_MAJOR >= 4 + +int urt_rng_init(void) +{ + static int initialised = 0; + if (initialised) + return 0; + psa_status_t s = psa_crypto_init(); + if (s != PSA_SUCCESS) + return (int)s; + initialised = 1; + return 0; +} + +int urt_rng_random(unsigned char *out, size_t len) +{ + int ret = urt_rng_init(); + if (ret != 0) + return ret; + psa_status_t s = psa_generate_random(out, len); + return (s == PSA_SUCCESS) ? 0 : (int)s; +} + +int urt_rng_callback(void *p_rng, unsigned char *out, size_t len) +{ + (void)p_rng; + return urt_rng_random(out, len); +} + +void urt_ssl_attach_rng(mbedtls_ssl_config *conf) +{ + // 4.x SSL pulls RNG from PSA internally -- nothing to wire. + (void)conf; +} + +#else + +static mbedtls_entropy_context _urt_entropy; +static mbedtls_ctr_drbg_context _urt_ctr_drbg; +static int _urt_rng_seeded = 0; + +/* When MBEDTLS_NO_PLATFORM_ENTROPY is set (embedded configs that strip the + * /dev/urandom/Windows-RNG auto-poll), mbedtls_entropy_init adds no sources + * and seed will fail with ENTROPY_SOURCE_FAILED. The platform must supply + * its own poll function -- on Bouffalo that's the SEC_ENG TRNG driver in + * urt.driver.bl_common.trng (declared extern(C) urt_platform_entropy_poll). */ +#if defined(MBEDTLS_NO_PLATFORM_ENTROPY) +extern int urt_platform_entropy_poll(void *data, unsigned char *output, + size_t len, size_t *olen); +#endif + +int urt_rng_init(void) +{ + if (_urt_rng_seeded) + return 0; + mbedtls_entropy_init(&_urt_entropy); +#if defined(MBEDTLS_NO_PLATFORM_ENTROPY) + int es = mbedtls_entropy_add_source(&_urt_entropy, urt_platform_entropy_poll, + NULL, 32, MBEDTLS_ENTROPY_SOURCE_STRONG); + if (es != 0) + { + mbedtls_entropy_free(&_urt_entropy); + return es; + } +#endif + mbedtls_ctr_drbg_init(&_urt_ctr_drbg); + int ret = mbedtls_ctr_drbg_seed(&_urt_ctr_drbg, mbedtls_entropy_func, + &_urt_entropy, NULL, 0); + if (ret != 0) + { + mbedtls_ctr_drbg_free(&_urt_ctr_drbg); + mbedtls_entropy_free(&_urt_entropy); + return ret; + } + _urt_rng_seeded = 1; + return 0; +} + +int urt_rng_random(unsigned char *out, size_t len) +{ + int ret = urt_rng_init(); + if (ret != 0) + return ret; + return mbedtls_ctr_drbg_random(&_urt_ctr_drbg, out, len); +} + +int urt_rng_callback(void *p_rng, unsigned char *out, size_t len) +{ + (void)p_rng; + return mbedtls_ctr_drbg_random(&_urt_ctr_drbg, out, len); +} + +void urt_ssl_attach_rng(mbedtls_ssl_config *conf) +{ + mbedtls_ssl_conf_rng(conf, mbedtls_ctr_drbg_random, &_urt_ctr_drbg); +} + +#endif + + +// ===================================================================== +// PK -- ECDSA P-256 generate / sign / import / export +// +// 4.x routes through PSA key handles bridged to mbedtls_pk_context via +// mbedtls_pk_copy_from_psa / mbedtls_pk_import_into_psa. +// <4 pokes mbedtls_ecp_keypair internals directly. +// ===================================================================== + +#if MBEDTLS_VERSION_MAJOR >= 4 + +// Build the standard P-256 ECDSA-SHA256 attributes used by all our keys. +static void _urt_p256_attr(psa_key_attributes_t *attr) +{ + *attr = psa_key_attributes_init(); + psa_set_key_type(attr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(attr, 256); + psa_set_key_usage_flags(attr, PSA_KEY_USAGE_SIGN_HASH + | PSA_KEY_USAGE_VERIFY_HASH + | PSA_KEY_USAGE_EXPORT); + psa_set_key_algorithm(attr, PSA_ALG_ECDSA(PSA_ALG_SHA_256)); +} + +int urt_pk_gen_ec_p256_key(mbedtls_pk_context *pk) +{ + int ret = urt_rng_init(); + if (ret != 0) + return ret; + + psa_key_attributes_t attr; + _urt_p256_attr(&attr); + + mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; + psa_status_t s = psa_generate_key(&attr, &key_id); + if (s != PSA_SUCCESS) + return (int)s; + + ret = mbedtls_pk_copy_from_psa(key_id, pk); + // pk_copy_from_psa copies the material; the source PSA key is now redundant. + psa_destroy_key(key_id); + return ret; +} + +int urt_pk_sign(mbedtls_pk_context *ctx, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t sig_size, size_t *sig_len) +{ + return mbedtls_pk_sign(ctx, MBEDTLS_MD_SHA256, + hash, hash_len, sig, sig_size, sig_len); +} + +int urt_pk_import_ec_p256_key(mbedtls_pk_context *pk, + const unsigned char *d, size_t d_len, + const unsigned char *xy, size_t xy_len) +{ + // P-256 private key is the 32-byte big-endian d. xy is recomputable. + (void)xy; (void)xy_len; + if (d_len != 32) + return MBEDTLS_ERR_PK_BAD_INPUT_DATA; + + int ret = urt_rng_init(); + if (ret != 0) + return ret; + + psa_key_attributes_t attr; + _urt_p256_attr(&attr); + + mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; + psa_status_t s = psa_import_key(&attr, d, d_len, &key_id); + if (s != PSA_SUCCESS) + return (int)s; + + ret = mbedtls_pk_copy_from_psa(key_id, pk); + psa_destroy_key(key_id); + return ret; +} + +int urt_pk_export_privkey_d(mbedtls_pk_context *pk, + unsigned char *buf, size_t buflen, + size_t *olen) +{ + if (buflen < 32) + return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; + + // Pull the key material out of pk into a fresh PSA handle, export, drop. + psa_key_attributes_t attr = psa_key_attributes_init(); + psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_EXPORT); + mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; + int ret = mbedtls_pk_import_into_psa(pk, &attr, &key_id); + if (ret != 0) + return ret; + + psa_status_t s = psa_export_key(key_id, buf, buflen, olen); + psa_destroy_key(key_id); + return (s == PSA_SUCCESS) ? 0 : (int)s; +} + +#else + +// Generate an ECDSA P-256 key into a pk context. +// Handles pk_setup + ecp_gen_key internally so D never needs to access +// mbedtls_ecp_keypair or mbedtls_ecp_group, whose layouts are version-dependent. +int urt_pk_gen_ec_p256_key(mbedtls_pk_context *pk) +{ + int ret = urt_rng_init(); + if (ret != 0) + return ret; + ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); + if (ret != 0) + return ret; + // mbedtls_pk_ec() is deprecated in 3.1+ but present in all 2.x and 3.x. + return mbedtls_ecp_gen_key(MBEDTLS_ECP_DP_SECP256R1, mbedtls_pk_ec(*pk), + urt_rng_callback, NULL); +} + +// Always signs with SHA-256. The md_type_t enum values changed between +// mbedtls 2.x and 3.x, so we resolve the correct value here in C. +int urt_pk_sign(mbedtls_pk_context *ctx, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t sig_size, size_t *sig_len) +{ +#if MBEDTLS_VERSION_MAJOR >= 3 + return mbedtls_pk_sign(ctx, MBEDTLS_MD_SHA256, hash, hash_len, + sig, sig_size, sig_len, urt_rng_callback, NULL); +#else + (void)sig_size; + return mbedtls_pk_sign(ctx, MBEDTLS_MD_SHA256, hash, hash_len, + sig, sig_len, urt_rng_callback, NULL); +#endif +} + +// Import raw EC P-256 key components (d, X, Y) into a pk context. +int urt_pk_import_ec_p256_key(mbedtls_pk_context *pk, + const unsigned char *d, size_t d_len, + const unsigned char *xy, size_t xy_len) +{ + int ret = mbedtls_pk_setup(pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); + if (ret != 0) + return ret; + + mbedtls_ecp_keypair *ec = mbedtls_pk_ec(*pk); + +#if MBEDTLS_VERSION_MAJOR >= 3 + ret = mbedtls_ecp_group_load(&ec->private_grp, MBEDTLS_ECP_DP_SECP256R1); + if (ret != 0) return ret; + ret = mbedtls_mpi_read_binary(&ec->private_d, d, d_len); + if (ret != 0) return ret; + // xy is 0x04 || X || Y (65 bytes) + ret = mbedtls_ecp_point_read_binary(&ec->private_grp, &ec->private_Q, xy, xy_len); +#else + ret = mbedtls_ecp_group_load(&ec->grp, MBEDTLS_ECP_DP_SECP256R1); + if (ret != 0) return ret; + ret = mbedtls_mpi_read_binary(&ec->d, d, d_len); + if (ret != 0) return ret; + ret = mbedtls_ecp_point_read_binary(&ec->grp, &ec->Q, xy, xy_len); +#endif + return ret; +} + +// Export the raw private key scalar d (32 bytes for P-256). +int urt_pk_export_privkey_d(mbedtls_pk_context *pk, + unsigned char *buf, size_t buflen, + size_t *olen) +{ + mbedtls_ecp_keypair *ec = mbedtls_pk_ec(*pk); +#if MBEDTLS_VERSION_MAJOR >= 3 + mbedtls_mpi *d = &ec->private_d; +#else + mbedtls_mpi *d = &ec->d; +#endif + size_t len = mbedtls_mpi_size(d); + if (buflen < len) + return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; + *olen = len; + return mbedtls_mpi_write_binary(d, buf, len); +} + +#endif + + +// Export the public key as an uncompressed EC point (0x04 || X || Y). +// mbedtls_pk_write_pubkey_der stays public in 4.x, so this needs no branch. +int urt_pk_export_pubkey_xy(mbedtls_pk_context *pk, + unsigned char *buf, size_t buflen, + size_t *olen) +{ + unsigned char der[256]; + int len = mbedtls_pk_write_pubkey_der(pk, der, sizeof(der)); + if (len < 0) + return len; + // SubjectPublicKeyInfo for P-256 ends with BIT STRING { 04 || X || Y } (65 bytes). + if (len < 65 || buflen < 65) + return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; + memcpy(buf, der + sizeof(der) - 65, 65); + *olen = 65; + return 0; +} + + +// ===================================================================== +// AES-GCM one-shot encrypt / decrypt +// ===================================================================== + +int urt_gcm_encrypt(const unsigned char *key, size_t key_len, + const unsigned char *iv, size_t iv_len, + const unsigned char *aad, size_t aad_len, + const unsigned char *plaintext, size_t pt_len, + unsigned char *ciphertext, + unsigned char *tag, size_t tag_len) +{ + mbedtls_gcm_context ctx; + mbedtls_gcm_init(&ctx); + int ret = mbedtls_gcm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, (unsigned)(key_len * 8)); + if (ret == 0) + ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT, pt_len, iv, iv_len, + aad, aad_len, plaintext, ciphertext, tag_len, tag); + mbedtls_gcm_free(&ctx); + return ret; +} + +int urt_gcm_decrypt(const unsigned char *key, size_t key_len, + const unsigned char *iv, size_t iv_len, + const unsigned char *aad, size_t aad_len, + const unsigned char *ciphertext, size_t ct_len, + const unsigned char *tag, size_t tag_len, + unsigned char *plaintext) +{ + mbedtls_gcm_context ctx; + mbedtls_gcm_init(&ctx); + int ret = mbedtls_gcm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, (unsigned)(key_len * 8)); + if (ret == 0) + ret = mbedtls_gcm_auth_decrypt(&ctx, ct_len, iv, iv_len, aad, aad_len, + tag, tag_len, ciphertext, plaintext); + mbedtls_gcm_free(&ctx); + return ret; +} + + +// ===================================================================== +// AES ECB single-block primitives (used by RFC 3394 key-wrap for the +// WPA2 4-way handshake GTK decryption). +// ===================================================================== + +int urt_aes_ecb_decrypt(const unsigned char *key, size_t key_len, + const unsigned char *cipher_block, + unsigned char *plain_block) +{ + mbedtls_aes_context ctx; + mbedtls_aes_init(&ctx); + int ret = mbedtls_aes_setkey_dec(&ctx, key, (unsigned)(key_len * 8)); + if (ret == 0) + ret = mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_DECRYPT, cipher_block, plain_block); + mbedtls_aes_free(&ctx); + return ret; +} + +int urt_aes_ecb_encrypt(const unsigned char *key, size_t key_len, + const unsigned char *plain_block, + unsigned char *cipher_block) +{ + mbedtls_aes_context ctx; + mbedtls_aes_init(&ctx); + int ret = mbedtls_aes_setkey_enc(&ctx, key, (unsigned)(key_len * 8)); + if (ret == 0) + ret = mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, plain_block, cipher_block); + mbedtls_aes_free(&ctx); + return ret; +} + + +// ===================================================================== +// ECDH P-256 raw shared-secret +// ===================================================================== + +// priv_d: 32-byte big-endian private scalar. +// peer_xy: 64-byte uncompressed peer point (X || Y, no 0x04 prefix). +// shared_x_out: 32 bytes -- big-endian X coordinate of (priv_d * peer_point). +int urt_ecdh_p256_compute_shared(const unsigned char *priv_d, size_t priv_len, + const unsigned char *peer_xy, size_t peer_xy_len, + unsigned char *shared_x_out) +{ + if (priv_len != 32 || peer_xy_len != 64) + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + + int ret = urt_rng_init(); + if (ret != 0) + return ret; + + mbedtls_ecp_group grp; + mbedtls_mpi d, z; + mbedtls_ecp_point Q; + + mbedtls_ecp_group_init(&grp); + mbedtls_mpi_init(&d); + mbedtls_mpi_init(&z); + mbedtls_ecp_point_init(&Q); + + ret = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1); + if (ret == 0) + ret = mbedtls_mpi_read_binary(&d, priv_d, priv_len); + if (ret == 0) + { + unsigned char point[65]; + point[0] = 0x04; + memcpy(point + 1, peer_xy, 64); + ret = mbedtls_ecp_point_read_binary(&grp, &Q, point, sizeof(point)); + } + if (ret == 0) + ret = mbedtls_ecdh_compute_shared(&grp, &z, &Q, &d, urt_rng_callback, NULL); + if (ret == 0) + ret = mbedtls_mpi_write_binary(&z, shared_x_out, 32); + + mbedtls_ecp_point_free(&Q); + mbedtls_mpi_free(&z); + mbedtls_mpi_free(&d); + mbedtls_ecp_group_free(&grp); + return ret; +} + +#endif diff --git a/src/urt/internal/mbedtls.d b/src/urt/internal/mbedtls.d new file mode 100644 index 0000000..89facd2 --- /dev/null +++ b/src/urt/internal/mbedtls.d @@ -0,0 +1,208 @@ +// minimal D bindings for mbedtls - only what pki.d and tls.d need +module urt.internal.mbedtls; + +version (MbedTLS): + +// Host posix builds link against system mbedtls. Embedded targets (esp%) +// inherit mbedtls from their platform SDK -- no pragma(lib) needed. +version (Posix) +{ + pragma(lib, "mbedtls"); + pragma(lib, "mbedx509"); + pragma(lib, "mbedcrypto"); +} + +nothrow @nogc: +extern(C): + + +// --- RNG (from urt/internal/mbedtls.c) --- +// +// Unified wrapper for the version-fragile entropy + CTR-DRBG / PSA dance. +// 4.x: backed by psa_generate_random; <4: classic entropy + CTR-DRBG seeded +// once and held module-static. Always idempotent and lazily initialised -- +// callers may invoke urt_rng_init() up front or simply call urt_rng_random() +// which inits on demand. +int urt_rng_init(); +int urt_rng_random(ubyte* output, size_t len); +int urt_rng_callback(void* p_rng, ubyte* output, size_t len); // f_rng-shaped, p_rng ignored + + +// --- PK (public key abstraction) --- + +struct mbedtls_pk_info_t; // opaque + +struct mbedtls_pk_context +{ + const(mbedtls_pk_info_t)* pk_info; + void* pk_ctx; +} + +void mbedtls_pk_init(mbedtls_pk_context* ctx); +void mbedtls_pk_free(mbedtls_pk_context* ctx); + + +// --- PK ECDSA P-256 helpers (from urt/internal/mbedtls.c) --- +// +// These wrap operations whose signatures or internal struct access patterns +// shift across mbedtls 2.x/3.x/4.x. The shim absorbs the divergence and +// drives RNG internally via urt_rng_*, so the D side never passes f_rng/p_rng. + +int urt_pk_gen_ec_p256_key(mbedtls_pk_context* pk); +int urt_pk_sign(mbedtls_pk_context* ctx, const(ubyte)* hash, size_t hash_len, + ubyte* sig, size_t sig_size, size_t* sig_len); +int urt_pk_import_ec_p256_key(mbedtls_pk_context* pk, + const(ubyte)* d, size_t d_len, + const(ubyte)* xy, size_t xy_len); +int urt_pk_export_privkey_d(mbedtls_pk_context* pk, ubyte* buf, size_t buflen, size_t* olen); +int urt_pk_export_pubkey_xy(mbedtls_pk_context* pk, ubyte* buf, size_t buflen, size_t* olen); + + +// --- ECDH P-256 (from urt/internal/mbedtls.c) --- + +int urt_ecdh_p256_compute_shared(const(ubyte)* priv_d, size_t priv_len, + const(ubyte)* peer_xy, size_t peer_xy_len, + ubyte* shared_x_out); + + +// --- AES-GCM one-shot (from urt/internal/mbedtls.c) --- + +int urt_gcm_encrypt(const(ubyte)* key, size_t key_len, + const(ubyte)* iv, size_t iv_len, + const(ubyte)* aad, size_t aad_len, + const(ubyte)* plaintext, size_t pt_len, + ubyte* ciphertext, + ubyte* tag, size_t tag_len); + +int urt_gcm_decrypt(const(ubyte)* key, size_t key_len, + const(ubyte)* iv, size_t iv_len, + const(ubyte)* aad, size_t aad_len, + const(ubyte)* ciphertext, size_t ct_len, + const(ubyte)* tag, size_t tag_len, + ubyte* plaintext); + + +// --- AES single-block ECB (RFC 3394 key-wrap building blocks) --- + +int urt_aes_ecb_decrypt(const(ubyte)* key, size_t key_len, + const(ubyte)* cipher_block, + ubyte* plain_block); +int urt_aes_ecb_encrypt(const(ubyte)* key, size_t key_len, + const(ubyte)* plain_block, + ubyte* cipher_block); + + +// --- X.509 certificate --- + +// mbedtls_x509_crt is complex (~200+ bytes). We only use it through pointers +// allocated via urt/internal/mbedtls.c (urt_x509_crt_new/delete). +struct mbedtls_x509_crt; + +void mbedtls_x509_crt_init(mbedtls_x509_crt* crt); +void mbedtls_x509_crt_free(mbedtls_x509_crt* crt); +int mbedtls_x509_crt_parse_der(mbedtls_x509_crt* chain, const(ubyte)* buf, size_t buflen); +int mbedtls_x509_crt_parse(mbedtls_x509_crt* chain, const(ubyte)* buf, size_t buflen); + + +// --- SSL/TLS --- + +struct mbedtls_ssl_context; +struct mbedtls_ssl_config; + +enum MBEDTLS_SSL_IS_CLIENT = 0; +enum MBEDTLS_SSL_IS_SERVER = 1; +enum MBEDTLS_SSL_TRANSPORT_STREAM = 0; +enum MBEDTLS_SSL_PRESET_DEFAULT = 0; + +enum MBEDTLS_ERR_SSL_WANT_READ = -0x6900; +enum MBEDTLS_ERR_SSL_WANT_WRITE = -0x6880; +enum MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY = -0x7880; + +void mbedtls_ssl_init(mbedtls_ssl_context* ssl); +void mbedtls_ssl_free(mbedtls_ssl_context* ssl); +int mbedtls_ssl_setup(mbedtls_ssl_context* ssl, const(mbedtls_ssl_config)* conf); +void mbedtls_ssl_set_bio(mbedtls_ssl_context* ssl, void* p_bio, int function(void*, const(ubyte)*, size_t) nothrow @nogc f_send, int function(void*, ubyte*, size_t) nothrow @nogc f_recv, void* f_recv_timeout); +int mbedtls_ssl_handshake(mbedtls_ssl_context* ssl); +int mbedtls_ssl_read(mbedtls_ssl_context* ssl, ubyte* buf, size_t len); +int mbedtls_ssl_write(mbedtls_ssl_context* ssl, const(ubyte)* buf, size_t len); +int mbedtls_ssl_close_notify(mbedtls_ssl_context* ssl); +int mbedtls_ssl_set_hostname(mbedtls_ssl_context* ssl, const(char)* hostname); + +void mbedtls_ssl_config_init(mbedtls_ssl_config* conf); +void mbedtls_ssl_config_free(mbedtls_ssl_config* conf); +int mbedtls_ssl_config_defaults(mbedtls_ssl_config* conf, int endpoint, int transport, int preset); +void mbedtls_ssl_conf_ca_chain(mbedtls_ssl_config* conf, mbedtls_x509_crt* ca_chain, void* ca_crl); +int mbedtls_ssl_conf_own_cert(mbedtls_ssl_config* conf, mbedtls_x509_crt* own_cert, mbedtls_pk_context* pk_key); +void mbedtls_ssl_conf_authmode(mbedtls_ssl_config* conf, int authmode); + +alias mbedtls_ssl_conf_sni_cb = int function(void* p_info, mbedtls_ssl_context* ssl, const(ubyte)* name, size_t name_len) nothrow @nogc; +void mbedtls_ssl_conf_sni(mbedtls_ssl_config* conf, mbedtls_ssl_conf_sni_cb f_sni, void* p_sni); + +// Wires the configured RNG into an SSL config. No-op on 4.x (SSL pulls from +// PSA internally); calls mbedtls_ssl_conf_rng with the module-static CTR-DRBG +// on <4. +void urt_ssl_attach_rng(mbedtls_ssl_config* conf); + +enum MBEDTLS_SSL_VERIFY_NONE = 0; +enum MBEDTLS_SSL_VERIFY_OPTIONAL = 1; +enum MBEDTLS_SSL_VERIFY_REQUIRED = 2; + + +// --- sizeof() from urt/internal/mbedtls.c (opaque types too complex to replicate) --- + +size_t urt_sizeof_x509_crt(); +size_t urt_sizeof_ssl_context(); +size_t urt_sizeof_ssl_config(); + +import urt.mem.alloc; + +mbedtls_x509_crt* urt_x509_crt_new() +{ + auto ctx = cast(mbedtls_x509_crt*)alloc(urt_sizeof_x509_crt()).ptr; + if (ctx) + mbedtls_x509_crt_init(ctx); + return ctx; +} + +void urt_x509_crt_delete(mbedtls_x509_crt* crt) +{ + if (crt) + { + mbedtls_x509_crt_free(crt); + free((cast(void*)crt)[0..urt_sizeof_x509_crt()]); + } +} + +mbedtls_ssl_context* urt_ssl_new() +{ + auto ctx = cast(mbedtls_ssl_context*)alloc(urt_sizeof_ssl_context()).ptr; + if (ctx) + mbedtls_ssl_init(ctx); + return ctx; +} + +void urt_ssl_delete(mbedtls_ssl_context* ssl) +{ + if (ssl) + { + mbedtls_ssl_free(ssl); + free((cast(void*)ssl)[0..urt_sizeof_ssl_context()]); + } +} + +mbedtls_ssl_config* urt_ssl_config_new() +{ + auto ctx = cast(mbedtls_ssl_config*)alloc(urt_sizeof_ssl_config()).ptr; + if (ctx) + mbedtls_ssl_config_init(ctx); + return ctx; +} + +void urt_ssl_config_delete(mbedtls_ssl_config* conf) +{ + if (conf) + { + mbedtls_ssl_config_free(conf); + free((cast(void*)conf)[0..urt_sizeof_ssl_config()]); + } +} diff --git a/src/urt/internal/os.c b/src/urt/internal/os.c index d6b9c02..8841d6b 100644 --- a/src/urt/internal/os.c +++ b/src/urt/internal/os.c @@ -2,10 +2,21 @@ #if defined(__linux) # define _DEFAULT_SOURCE +# include # include # include +# include # include # include # include # include +# include +# include +# include +# include + +// EWOULDBLOCK is #define EWOULDBLOCK EAGAIN on Linux - ImportC cannot resolve +// chained macros, so re-define as a plain integer. +# undef EWOULDBLOCK +# define EWOULDBLOCK 11 /* same as EAGAIN on Linux */ #endif diff --git a/src/urt/internal/stdc/errno.d b/src/urt/internal/stdc/errno.d new file mode 100644 index 0000000..459f9e7 --- /dev/null +++ b/src/urt/internal/stdc/errno.d @@ -0,0 +1,2487 @@ +/** + * D header file for C99. + * + * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_errno.h.html, _errno.h) + * + * Copyright: Copyright Sean Kelly 2005 - 2009. + * License: Distributed under the + * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). + * (See accompanying file LICENSE) + * Authors: Sean Kelly, Alex Rønne Petersen + * Source: $(DRUNTIMESRC core/stdc/_errno.d) + * Standards: ISO/IEC 9899:1999 (E) + */ + +module urt.internal.stdc.errno; + +version (OSX) + version = Darwin; +else version (iOS) + version = Darwin; +else version (TVOS) + version = Darwin; +else version (WatchOS) + version = Darwin; + +version (ARM) version = ARM_Any; +version (AArch64) version = ARM_Any; +version (HPPA) version = HPPA_Any; +version (MIPS32) version = MIPS_Any; +version (MIPS64) version = MIPS_Any; +version (PPC) version = PPC_Any; +version (PPC64) version = PPC_Any; +version (RISCV32) version = RISCV_Any; +version (RISCV64) version = RISCV_Any; +version (S390) version = IBMZ_Any; +version (SPARC) version = SPARC_Any; +version (SPARC64) version = SPARC_Any; +version (SystemZ) version = IBMZ_Any; +version (X86) version = X86_Any; +version (X86_64) version = X86_Any; + +// Picolibc forked from newlib and shares its errno constant values. +// The accessor differs (picolibc uses a plain global, newlib uses __errno()), +version (CRuntime_Picolibc) version = NewlibCompat; +version (CRuntime_Newlib) version = NewlibCompat; + +@trusted: // Only manipulates errno. +nothrow: +@nogc: + +version (CRuntime_Microsoft) +{ + extern(C) + { + ref int _errno(); + alias errno = _errno; + } +} +else version (CRuntime_Glibc) +{ + extern(C) + { + ref int __errno_location(); + alias errno = __errno_location; + } +} +else version (CRuntime_Musl) +{ + extern(C) + { + ref int __errno_location(); + alias errno = __errno_location; + } +} +else version (CRuntime_Picolibc) +{ + version (FreeRTOS) + { + // On FreeRTOS, picolibc defines errno as _Thread_local which conflicts + // with emulated-TLS. Use a C shim to access it indirectly. + extern(C) int* ow_errno_location() nothrow @nogc; + @property ref int errno() nothrow @nogc { return *ow_errno_location(); } + } + else + { + // Bare-metal single-threaded: errno is a plain global. + extern(C) extern int errno; + } +} +else version (CRuntime_Newlib) +{ + extern(C) + { + ref int __errno(); + alias errno = __errno; + } +} +else version (OpenBSD) +{ + // https://github.com/openbsd/src/blob/master/include/errno.h + extern(C) + { + ref int __errno(); + alias errno = __errno; + } +} +else version (NetBSD) +{ + // https://github.com/NetBSD/src/blob/trunk/include/errno.h + extern(C) + { + ref int __errno(); + alias errno = __errno; + } +} +else version (FreeBSD) +{ + extern(C) + { + ref int __error(); + alias errno = __error; + } +} +else version (DragonFlyBSD) +{ + extern(C) + { + pragma(mangle, "errno") int __errno; + ref int __error() { + return __errno; + } + alias errno = __error; + } +} +else version (CRuntime_Bionic) +{ + extern(C) + { + ref int __errno(); + alias errno = __errno; + } +} +else version (CRuntime_UClibc) +{ + extern(C) + { + ref int __errno_location(); + alias errno = __errno_location; + } +} +else version (Darwin) +{ + extern(C) + { + ref int __error(); + alias errno = __error; + } +} +else version (Solaris) +{ + extern(C) + { + ref int ___errno(); + alias errno = ___errno; + } +} +else version (Haiku) +{ + // https://github.com/haiku/haiku/blob/master/headers/posix/errno.h + extern(C) + { + ref int _errnop(); + alias errno = _errnop; + } +} +else +{ + /// + extern(C) pragma(mangle, "getErrno") @property int errno(); + /// + extern(C) pragma(mangle, "setErrno") @property int errno(int n); +} + +extern(C): + + +version (CRuntime_Microsoft) +{ + enum EPERM = 1; /// Operation not permitted + enum ENOENT = 2; /// No such file or directory + enum ESRCH = 3; /// No such process + enum EINTR = 4; /// Interrupted system call + enum EIO = 5; /// I/O error + enum ENXIO = 6; /// No such device or address + enum E2BIG = 7; /// Argument list too long + enum ENOEXEC = 8; /// Exec format error + enum EBADF = 9; /// Bad file number + enum ECHILD = 10; /// No child processes + enum EAGAIN = 11; /// Try again + enum ENOMEM = 12; /// Out of memory + enum EACCES = 13; /// Permission denied + enum EFAULT = 14; /// Bad address + enum EBUSY = 16; /// Device or resource busy + enum EEXIST = 17; /// File exists + enum EXDEV = 18; /// Cross-device link + enum ENODEV = 19; /// No such device + enum ENOTDIR = 20; /// Not a directory + enum EISDIR = 21; /// Is a directory + enum EINVAL = 22; /// Invalid argument + enum ENFILE = 23; /// File table overflow + enum EMFILE = 24; /// Too many open files + enum ENOTTY = 25; /// Not a typewriter + enum EFBIG = 27; /// File too large + enum ENOSPC = 28; /// No space left on device + enum ESPIPE = 29; /// Illegal seek + enum EROFS = 30; /// Read-only file system + enum EMLINK = 31; /// Too many links + enum EPIPE = 32; /// Broken pipe + enum EDOM = 33; /// Math argument out of domain of func + enum ERANGE = 34; /// Math result not representable + enum EDEADLK = 36; /// Resource deadlock would occur + enum ENAMETOOLONG = 38; /// File name too long + enum ENOLCK = 39; /// No record locks available + enum ENOSYS = 40; /// Function not implemented + enum ENOTEMPTY = 41; /// Directory not empty + enum EILSEQ = 42; /// Illegal byte sequence + enum EDEADLOCK = EDEADLK; /// Resource deadlock would occur + + // POSIX compatibility + // See_Also: https://docs.microsoft.com/en-us/cpp/c-runtime-library/errno-constants + enum EADDRINUSE = 100; + enum EADDRNOTAVAIL = 101; + enum EAFNOSUPPORT = 102; + enum EALREADY = 103; + enum EBADMSG = 104; + enum ECANCELED = 105; + enum ECONNABORTED = 106; + enum ECONNREFUSED = 107; + enum ECONNRESET = 108; + enum EDESTADDRREQ = 109; + enum EHOSTUNREACH = 110; + enum EIDRM = 111; + enum EINPROGRESS = 112; + enum EISCONN = 113; + enum ELOOP = 114; + enum EMSGSIZE = 115; + enum ENETDOWN = 116; + enum ENETRESET = 117; + enum ENETUNREACH = 118; + enum ENOBUFS = 119; + enum ENODATA = 120; + enum ENOLINK = 121; + enum ENOMSG = 122; + enum ENOPROTOOPT = 123; + enum ENOSR = 124; + enum ENOSTR = 125; + enum ENOTCONN = 126; + enum ENOTRECOVERABLE = 127; + enum ENOTSOCK = 128; + enum ENOTSUP = 129; + enum EOPNOTSUPP = 130; + enum EOTHER = 131; + enum EOVERFLOW = 132; + enum EOWNERDEAD = 133; + enum EPROTO = 134; + enum EPROTONOSUPPORT = 135; + enum EPROTOTYPE = 136; + enum ETIME = 137; + enum ETIMEDOUT = 138; + enum ETXTBSY = 139; + enum EWOULDBLOCK = 140; +} +else version (NewlibCompat) +{ + enum EPERM = 1; + enum ENOENT = 2; + enum ESRCH = 3; + enum EINTR = 4; + enum EIO = 5; + enum ENXIO = 6; + enum E2BIG = 7; + enum ENOEXEC = 8; + enum EBADF = 9; + enum ECHILD = 10; + enum EAGAIN = 11; + enum ENOMEM = 12; + enum EACCES = 13; + enum EFAULT = 14; + enum EBUSY = 16; + enum EEXIST = 17; + enum EXDEV = 18; + enum ENODEV = 19; + enum ENOTDIR = 20; + enum EISDIR = 21; + enum EINVAL = 22; + enum ENFILE = 23; + enum EMFILE = 24; + enum ENOTTY = 25; + enum ETXTBSY = 26; + enum EFBIG = 27; + enum ENOSPC = 28; + enum ESPIPE = 29; + enum EROFS = 30; + enum EMLINK = 31; + enum EPIPE = 32; + enum EDOM = 33; + enum ERANGE = 34; + enum ENOMSG = 35; + enum EIDRM = 36; + enum EDEADLK = 45; + enum ENOLCK = 46; + enum ENOSTR = 60; + enum ENODATA = 61; + enum ETIME = 62; + enum ENOSR = 63; + enum ENOLINK = 67; + enum EPROTO = 71; + enum EMULTIHOP = 74; + enum EBADMSG = 77; + enum EFTYPE = 79; + enum ENOSYS = 88; + enum ENOTEMPTY = 90; + enum ENAMETOOLONG = 91; + enum ELOOP = 92; + enum EOPNOTSUPP = 95; + enum EPFNOSUPPORT = 96; + enum ECONNRESET = 104; + enum ENOBUFS = 105; + enum EAFNOSUPPORT = 106; + enum EPROTOTYPE = 107; + enum ENOTSOCK = 108; + enum ENOPROTOOPT = 109; + enum ECONNREFUSED = 111; + enum EADDRINUSE = 112; + enum ECONNABORTED = 113; + enum ENETUNREACH = 114; + enum ENETDOWN = 115; + enum ETIMEDOUT = 116; + enum EHOSTDOWN = 117; + enum EHOSTUNREACH = 118; + enum EINPROGRESS = 119; + enum EALREADY = 120; + enum EDESTADDRREQ = 121; + enum EMSGSIZE = 122; + enum EPROTONOSUPPORT = 123; + enum EADDRNOTAVAIL = 125; + enum ENETRESET = 126; + enum EISCONN = 127; + enum ENOTCONN = 128; + enum ETOOMANYREFS = 129; + enum EDQUOT = 132; + enum ESTALE = 133; + enum ENOTSUP = 134; + enum EILSEQ = 138; + enum EOVERFLOW = 139; + enum ECANCELED = 140; + enum ENOTRECOVERABLE = 141; + enum EOWNERDEAD = 142; + + enum EWOULDBLOCK = EAGAIN; + + enum __ELASTERROR = 2000; + + // Linux errno extensions + version (Cygwin) + { + enum ENOTBLK = 15; + enum ECHRNG = 37; + enum EL2NSYNC = 38; + enum EL3HLT = 39; + enum EL3RST = 40; + enum ELNRNG = 41; + enum EUNATCH = 42; + enum ENOCSI = 43; + enum EL2HLT = 44; + enum EBADE = 50; + enum EBADR = 51; + enum EXFULL = 52; + enum ENOANO = 53; + enum EBADRQC = 54; + enum EBADSLT = 55; + enum EDEADLOCK = 56; + enum EBFONT = 57; + enum ENONET = 64; + enum ENOPKG = 65; + enum EREMOTE = 66; + enum EADV = 68; + enum ESRMNT = 69; + enum ECOMM = 70; + enum ELBIN = 75; + enum EDOTDOT = 76; + enum ENOTUNIQ = 80; + enum EBADFD = 81; + enum EREMCHG = 82; + enum ELIBACC = 83; + enum ELIBBAD = 84; + enum ELIBSCN = 85; + enum ELIBMAX = 86; + enum ELIBEXEC = 87; + enum ENMFILE = 89; + enum ESHUTDOWN = 110; + enum ESOCKTNOSUPPORT = 124; + enum EPROCLIM = 130; + enum EUSERS = 131; + enum ENOMEDIUM = 135; + enum ENOSHARE = 136; + enum ECASECLASH = 137; + enum ESTRPIPE = 143; + } +} +else version (linux) +{ + enum EPERM = 1; /// + enum ENOENT = 2; /// + enum ESRCH = 3; /// + enum EINTR = 4; /// + enum EIO = 5; /// + enum ENXIO = 6; /// + enum E2BIG = 7; /// + enum ENOEXEC = 8; /// + enum EBADF = 9; /// + enum ECHILD = 10; /// + enum EAGAIN = 11; /// + enum ENOMEM = 12; /// + enum EACCES = 13; /// + enum EFAULT = 14; /// + enum ENOTBLK = 15; /// + enum EBUSY = 16; /// + enum EEXIST = 17; /// + enum EXDEV = 18; /// + enum ENODEV = 19; /// + enum ENOTDIR = 20; /// + enum EISDIR = 21; /// + enum EINVAL = 22; /// + enum ENFILE = 23; /// + enum EMFILE = 24; /// + enum ENOTTY = 25; /// + enum ETXTBSY = 26; /// + enum EFBIG = 27; /// + enum ENOSPC = 28; /// + enum ESPIPE = 29; /// + enum EROFS = 30; /// + enum EMLINK = 31; /// + enum EPIPE = 32; /// + enum EDOM = 33; /// + enum ERANGE = 34; /// + + version (X86_Any) + { + enum EDEADLK = 35; /// + enum ENAMETOOLONG = 36; /// + enum ENOLCK = 37; /// + enum ENOSYS = 38; /// + enum ENOTEMPTY = 39; /// + enum ELOOP = 40; /// + enum EWOULDBLOCK = EAGAIN; /// + enum ENOMSG = 42; /// + enum EIDRM = 43; /// + enum ECHRNG = 44; /// + enum EL2NSYNC = 45; /// + enum EL3HLT = 46; /// + enum EL3RST = 47; /// + enum ELNRNG = 48; /// + enum EUNATCH = 49; /// + enum ENOCSI = 50; /// + enum EL2HLT = 51; /// + enum EBADE = 52; /// + enum EBADR = 53; /// + enum EXFULL = 54; /// + enum ENOANO = 55; /// + enum EBADRQC = 56; /// + enum EBADSLT = 57; /// + enum EDEADLOCK = EDEADLK; /// + enum EBFONT = 59; /// + enum ENOSTR = 60; /// + enum ENODATA = 61; /// + enum ETIME = 62; /// + enum ENOSR = 63; /// + enum ENONET = 64; /// + enum ENOPKG = 65; /// + enum EREMOTE = 66; /// + enum ENOLINK = 67; /// + enum EADV = 68; /// + enum ESRMNT = 69; /// + enum ECOMM = 70; /// + enum EPROTO = 71; /// + enum EMULTIHOP = 72; /// + enum EDOTDOT = 73; /// + enum EBADMSG = 74; /// + enum EOVERFLOW = 75; /// + enum ENOTUNIQ = 76; /// + enum EBADFD = 77; /// + enum EREMCHG = 78; /// + enum ELIBACC = 79; /// + enum ELIBBAD = 80; /// + enum ELIBSCN = 81; /// + enum ELIBMAX = 82; /// + enum ELIBEXEC = 83; /// + enum EILSEQ = 84; /// + enum ERESTART = 85; /// + enum ESTRPIPE = 86; /// + enum EUSERS = 87; /// + enum ENOTSOCK = 88; /// + enum EDESTADDRREQ = 89; /// + enum EMSGSIZE = 90; /// + enum EPROTOTYPE = 91; /// + enum ENOPROTOOPT = 92; /// + enum EPROTONOSUPPORT = 93; /// + enum ESOCKTNOSUPPORT = 94; /// + enum EOPNOTSUPP = 95; /// + enum ENOTSUP = EOPNOTSUPP; /// + enum EPFNOSUPPORT = 96; /// + enum EAFNOSUPPORT = 97; /// + enum EADDRINUSE = 98; /// + enum EADDRNOTAVAIL = 99; /// + enum ENETDOWN = 100; /// + enum ENETUNREACH = 101; /// + enum ENETRESET = 102; /// + enum ECONNABORTED = 103; /// + enum ECONNRESET = 104; /// + enum ENOBUFS = 105; /// + enum EISCONN = 106; /// + enum ENOTCONN = 107; /// + enum ESHUTDOWN = 108; /// + enum ETOOMANYREFS = 109; /// + enum ETIMEDOUT = 110; /// + enum ECONNREFUSED = 111; /// + enum EHOSTDOWN = 112; /// + enum EHOSTUNREACH = 113; /// + enum EALREADY = 114; /// + enum EINPROGRESS = 115; /// + enum ESTALE = 116; /// + enum EUCLEAN = 117; /// + enum ENOTNAM = 118; /// + enum ENAVAIL = 119; /// + enum EISNAM = 120; /// + enum EREMOTEIO = 121; /// + enum EDQUOT = 122; /// + enum ENOMEDIUM = 123; /// + enum EMEDIUMTYPE = 124; /// + enum ECANCELED = 125; /// + enum ENOKEY = 126; /// + enum EKEYEXPIRED = 127; /// + enum EKEYREVOKED = 128; /// + enum EKEYREJECTED = 129; /// + enum EOWNERDEAD = 130; /// + enum ENOTRECOVERABLE = 131; /// + enum ERFKILL = 132; /// + enum EHWPOISON = 133; /// + } + else version (ARM_Any) + { + enum EDEADLK = 35; /// + enum ENAMETOOLONG = 36; /// + enum ENOLCK = 37; /// + enum ENOSYS = 38; /// + enum ENOTEMPTY = 39; /// + enum ELOOP = 40; /// + enum EWOULDBLOCK = EAGAIN; /// + enum ENOMSG = 42; /// + enum EIDRM = 43; /// + enum ECHRNG = 44; /// + enum EL2NSYNC = 45; /// + enum EL3HLT = 46; /// + enum EL3RST = 47; /// + enum ELNRNG = 48; /// + enum EUNATCH = 49; /// + enum ENOCSI = 50; /// + enum EL2HLT = 51; /// + enum EBADE = 52; /// + enum EBADR = 53; /// + enum EXFULL = 54; /// + enum ENOANO = 55; /// + enum EBADRQC = 56; /// + enum EBADSLT = 57; /// + enum EDEADLOCK = EDEADLK; /// + enum EBFONT = 59; /// + enum ENOSTR = 60; /// + enum ENODATA = 61; /// + enum ETIME = 62; /// + enum ENOSR = 63; /// + enum ENONET = 64; /// + enum ENOPKG = 65; /// + enum EREMOTE = 66; /// + enum ENOLINK = 67; /// + enum EADV = 68; /// + enum ESRMNT = 69; /// + enum ECOMM = 70; /// + enum EPROTO = 71; /// + enum EMULTIHOP = 72; /// + enum EDOTDOT = 73; /// + enum EBADMSG = 74; /// + enum EOVERFLOW = 75; /// + enum ENOTUNIQ = 76; /// + enum EBADFD = 77; /// + enum EREMCHG = 78; /// + enum ELIBACC = 79; /// + enum ELIBBAD = 80; /// + enum ELIBSCN = 81; /// + enum ELIBMAX = 82; /// + enum ELIBEXEC = 83; /// + enum EILSEQ = 84; /// + enum ERESTART = 85; /// + enum ESTRPIPE = 86; /// + enum EUSERS = 87; /// + enum ENOTSOCK = 88; /// + enum EDESTADDRREQ = 89; /// + enum EMSGSIZE = 90; /// + enum EPROTOTYPE = 91; /// + enum ENOPROTOOPT = 92; /// + enum EPROTONOSUPPORT = 93; /// + enum ESOCKTNOSUPPORT = 94; /// + enum EOPNOTSUPP = 95; /// + enum ENOTSUP = EOPNOTSUPP; /// + enum EPFNOSUPPORT = 96; /// + enum EAFNOSUPPORT = 97; /// + enum EADDRINUSE = 98; /// + enum EADDRNOTAVAIL = 99; /// + enum ENETDOWN = 100; /// + enum ENETUNREACH = 101; /// + enum ENETRESET = 102; /// + enum ECONNABORTED = 103; /// + enum ECONNRESET = 104; /// + enum ENOBUFS = 105; /// + enum EISCONN = 106; /// + enum ENOTCONN = 107; /// + enum ESHUTDOWN = 108; /// + enum ETOOMANYREFS = 109; /// + enum ETIMEDOUT = 110; /// + enum ECONNREFUSED = 111; /// + enum EHOSTDOWN = 112; /// + enum EHOSTUNREACH = 113; /// + enum EALREADY = 114; /// + enum EINPROGRESS = 115; /// + enum ESTALE = 116; /// + enum EUCLEAN = 117; /// + enum ENOTNAM = 118; /// + enum ENAVAIL = 119; /// + enum EISNAM = 120; /// + enum EREMOTEIO = 121; /// + enum EDQUOT = 122; /// + enum ENOMEDIUM = 123; /// + enum EMEDIUMTYPE = 124; /// + enum ECANCELED = 125; /// + enum ENOKEY = 126; /// + enum EKEYEXPIRED = 127; /// + enum EKEYREVOKED = 128; /// + enum EKEYREJECTED = 129; /// + enum EOWNERDEAD = 130; /// + enum ENOTRECOVERABLE = 131; /// + enum ERFKILL = 132; /// + enum EHWPOISON = 133; /// + } + else version (HPPA_Any) + { + enum ENOMSG = 35; /// + enum EIDRM = 36; /// + enum ECHRNG = 37; /// + enum EL2NSYNC = 38; /// + enum EL3HLT = 39; /// + enum EL3RST = 40; /// + enum ELNRNG = 41; /// + enum EUNATCH = 42; /// + enum ENOCSI = 43; /// + enum EL2HLT = 44; /// + enum EDEADLK = 45; /// + enum EDEADLOCK = EDEADLK; /// + enum ENOLCK = 46; /// + enum EILSEQ = 47; /// + enum ENONET = 50; /// + enum ENODATA = 51; /// + enum ETIME = 52; /// + enum ENOSR = 53; /// + enum ENOSTR = 54; /// + enum ENOPKG = 55; /// + enum ENOLINK = 57; /// + enum EADV = 58; /// + enum ESRMNT = 59; /// + enum ECOMM = 60; /// + enum EPROTO = 61; /// + enum EMULTIHOP = 64; /// + enum EDOTDOT = 66; /// + enum EBADMSG = 67; /// + enum EUSERS = 68; /// + enum EDQUOT = 69; /// + enum ESTALE = 70; /// + enum EREMOTE = 71; /// + enum EOVERFLOW = 72; /// + enum EBADE = 160; /// + enum EBADR = 161; /// + enum EXFULL = 162; /// + enum ENOANO = 163; /// + enum EBADRQC = 164; /// + enum EBADSLT = 165; /// + enum EBFONT = 166; /// + enum ENOTUNIQ = 167; /// + enum EBADFD = 168; /// + enum EREMCHG = 169; /// + enum ELIBACC = 170; /// + enum ELIBBAD = 171; /// + enum ELIBSCN = 172; /// + enum ELIBMAX = 173; /// + enum ELIBEXEC = 174; /// + enum ERESTART = 175; /// + enum ESTRPIPE = 176; /// + enum EUCLEAN = 177; /// + enum ENOTNAM = 178; /// + enum ENAVAIL = 179; /// + enum EISNAM = 180; /// + enum EREMOTEIO = 181; /// + enum ENOMEDIUM = 182; /// + enum EMEDIUMTYPE = 183; /// + enum ENOKEY = 184; /// + enum EKEYEXPIRED = 185; /// + enum EKEYREVOKED = 186; /// + enum EKEYREJECTED = 187; /// + enum ENOSYM = 215; /// + enum ENOTSOCK = 216; /// + enum EDESTADDRREQ = 217; /// + enum EMSGSIZE = 218; /// + enum EPROTOTYPE = 219; /// + enum ENOPROTOOPT = 220; /// + enum EPROTONOSUPPORT = 221; /// + enum ESOCKTNOSUPPORT = 221; /// + enum EOPNOTSUPP = 223; /// + enum EPFNOSUPPORT = 224; /// + enum EAFNOSUPPORT = 225; /// + enum EADDRINUSE = 226; /// + enum EADDRNOTAVAIL = 227; /// + enum ENETDOWN = 228; /// + enum ENETUNREACH = 229; /// + enum ENETRESET = 230; /// + enum ECONNABORTED = 231; /// + enum ECONNRESET = 232; /// + enum ENOBUFS = 233; /// + enum EISCONN = 234; /// + enum ENOTCONN = 235; /// + enum ESHUTDOWN = 236; /// + enum ETOOMANYREFS = 237; /// + enum ETIMEDOUT = 238; /// + enum ECONNREFUSED = 239; /// + enum EREFUSED = ECONNREFUSED; /// + enum EREMOTERELEASE = 240; /// + enum EHOSTDOWN = 241; /// + enum EHOSTUNREACH = 242; /// + enum EALREADY = 244; /// + enum EINPROGRESS = 245; /// + enum EWOULDBLOCK = EAGAIN; /// + enum ENOTEMPTY = 247; /// + enum ENAMETOOLONG = 248; /// + enum ELOOP = 249; /// + enum ENOSYS = 251; /// + enum ECANCELLED = 253; /// + enum ECANCELED = ECANCELLED; /// + enum EOWNERDEAD = 254; /// + enum ENOTRECOVERABLE = 255; /// + enum ERFKILL = 256; /// + enum EHWPOISON = 257; /// + } + else version (MIPS_Any) + { + enum ENOMSG = 35; /// + enum EIDRM = 36; /// + enum ECHRNG = 37; /// + enum EL2NSYNC = 38; /// + enum EL3HLT = 39; /// + enum EL3RST = 40; /// + enum ELNRNG = 41; /// + enum EUNATCH = 42; /// + enum ENOCSI = 43; /// + enum EL2HLT = 44; /// + enum EDEADLK = 45; /// + enum ENOLCK = 46; /// + enum EBADE = 50; /// + enum EBADR = 51; /// + enum EXFULL = 52; /// + enum ENOANO = 53; /// + enum EBADRQC = 54; /// + enum EBADSLT = 55; /// + enum EDEADLOCK = 56; /// + enum EBFONT = 59; /// + enum ENOSTR = 60; /// + enum ENODATA = 61; /// + enum ETIME = 62; /// + enum ENOSR = 63; /// + enum ENONET = 64; /// + enum ENOPKG = 65; /// + enum EREMOTE = 66; /// + enum ENOLINK = 67; /// + enum EADV = 68; /// + enum ESRMNT = 69; /// + enum ECOMM = 70; /// + enum EPROTO = 71; /// + enum EDOTDOT = 73; /// + enum EMULTIHOP = 74; /// + enum EBADMSG = 77; /// + enum ENAMETOOLONG = 78; /// + enum EOVERFLOW = 79; /// + enum ENOTUNIQ = 80; /// + enum EBADFD = 81; /// + enum EREMCHG = 82; /// + enum ELIBACC = 83; /// + enum ELIBBAD = 84; /// + enum ELIBSCN = 85; /// + enum ELIBMAX = 86; /// + enum ELIBEXEC = 87; /// + enum EILSEQ = 88; /// + enum ENOSYS = 89; /// + enum ELOOP = 90; /// + enum ERESTART = 91; /// + enum ESTRPIPE = 92; /// + enum ENOTEMPTY = 93; /// + enum EUSERS = 94; /// + enum ENOTSOCK = 95; /// + enum EDESTADDRREQ = 96; /// + enum EMSGSIZE = 97; /// + enum EPROTOTYPE = 98; /// + enum ENOPROTOOPT = 99; /// + enum EPROTONOSUPPORT = 120; /// + enum ESOCKTNOSUPPORT = 121; /// + enum EOPNOTSUPP = 122; /// + enum ENOTSUP = EOPNOTSUPP; /// + enum EPFNOSUPPORT = 123; /// + enum EAFNOSUPPORT = 124; /// + enum EADDRINUSE = 125; /// + enum EADDRNOTAVAIL = 126; /// + enum ENETDOWN = 127; /// + enum ENETUNREACH = 128; /// + enum ENETRESET = 129; /// + enum ECONNABORTED = 130; /// + enum ECONNRESET = 131; /// + enum ENOBUFS = 132; /// + enum EISCONN = 133; /// + enum ENOTCONN = 134; /// + enum EUCLEAN = 135; /// + enum ENOTNAM = 137; /// + enum ENAVAIL = 138; /// + enum EISNAM = 139; /// + enum EREMOTEIO = 140; /// + enum EINIT = 141; /// + enum EREMDEV = 142; /// + enum ESHUTDOWN = 143; /// + enum ETOOMANYREFS = 144; /// + enum ETIMEDOUT = 145; /// + enum ECONNREFUSED = 146; /// + enum EHOSTDOWN = 147; /// + enum EHOSTUNREACH = 148; /// + enum EWOULDBLOCK = EAGAIN; /// + enum EALREADY = 149; /// + enum EINPROGRESS = 150; /// + enum ESTALE = 151; /// + enum ECANCELED = 158; /// + enum ENOMEDIUM = 159; /// + enum EMEDIUMTYPE = 160; /// + enum ENOKEY = 161; /// + enum EKEYEXPIRED = 162; /// + enum EKEYREVOKED = 163; /// + enum EKEYREJECTED = 164; /// + enum EOWNERDEAD = 165; /// + enum ENOTRECOVERABLE = 166; /// + enum ERFKILL = 167; /// + enum EHWPOISON = 168; /// + enum EDQUOT = 1133; /// + } + else version (PPC_Any) + { + enum EDEADLK = 35; /// + enum ENAMETOOLONG = 36; /// + enum ENOLCK = 37; /// + enum ENOSYS = 38; /// + enum ENOTEMPTY = 39; /// + enum ELOOP = 40; /// + enum EWOULDBLOCK = EAGAIN; /// + enum ENOMSG = 42; /// + enum EIDRM = 43; /// + enum ECHRNG = 44; /// + enum EL2NSYNC = 45; /// + enum EL3HLT = 46; /// + enum EL3RST = 47; /// + enum ELNRNG = 48; /// + enum EUNATCH = 49; /// + enum ENOCSI = 50; /// + enum EL2HLT = 51; /// + enum EBADE = 52; /// + enum EBADR = 53; /// + enum EXFULL = 54; /// + enum ENOANO = 55; /// + enum EBADRQC = 56; /// + enum EBADSLT = 57; /// + enum EDEADLOCK = 58; /// + enum EBFONT = 59; /// + enum ENOSTR = 60; /// + enum ENODATA = 61; /// + enum ETIME = 62; /// + enum ENOSR = 63; /// + enum ENONET = 64; /// + enum ENOPKG = 65; /// + enum EREMOTE = 66; /// + enum ENOLINK = 67; /// + enum EADV = 68; /// + enum ESRMNT = 69; /// + enum ECOMM = 70; /// + enum EPROTO = 71; /// + enum EMULTIHOP = 72; /// + enum EDOTDOT = 73; /// + enum EBADMSG = 74; /// + enum EOVERFLOW = 75; /// + enum ENOTUNIQ = 76; /// + enum EBADFD = 77; /// + enum EREMCHG = 78; /// + enum ELIBACC = 79; /// + enum ELIBBAD = 80; /// + enum ELIBSCN = 81; /// + enum ELIBMAX = 82; /// + enum ELIBEXEC = 83; /// + enum EILSEQ = 84; /// + enum ERESTART = 85; /// + enum ESTRPIPE = 86; /// + enum EUSERS = 87; /// + enum ENOTSOCK = 88; /// + enum EDESTADDRREQ = 89; /// + enum EMSGSIZE = 90; /// + enum EPROTOTYPE = 91; /// + enum ENOPROTOOPT = 92; /// + enum EPROTONOSUPPORT = 93; /// + enum ESOCKTNOSUPPORT = 94; /// + enum EOPNOTSUPP = 95; /// + enum ENOTSUP = EOPNOTSUPP; /// + enum EPFNOSUPPORT = 96; /// + enum EAFNOSUPPORT = 97; /// + enum EADDRINUSE = 98; /// + enum EADDRNOTAVAIL = 99; /// + enum ENETDOWN = 100; /// + enum ENETUNREACH = 101; /// + enum ENETRESET = 102; /// + enum ECONNABORTED = 103; /// + enum ECONNRESET = 104; /// + enum ENOBUFS = 105; /// + enum EISCONN = 106; /// + enum ENOTCONN = 107; /// + enum ESHUTDOWN = 108; /// + enum ETOOMANYREFS = 109; /// + enum ETIMEDOUT = 110; /// + enum ECONNREFUSED = 111; /// + enum EHOSTDOWN = 112; /// + enum EHOSTUNREACH = 113; /// + enum EALREADY = 114; /// + enum EINPROGRESS = 115; /// + enum ESTALE = 116; /// + enum EUCLEAN = 117; /// + enum ENOTNAM = 118; /// + enum ENAVAIL = 119; /// + enum EISNAM = 120; /// + enum EREMOTEIO = 121; /// + enum EDQUOT = 122; /// + enum ENOMEDIUM = 123; /// + enum EMEDIUMTYPE = 124; /// + enum ECANCELED = 125; /// + enum ENOKEY = 126; /// + enum EKEYEXPIRED = 127; /// + enum EKEYREVOKED = 128; /// + enum EKEYREJECTED = 129; /// + enum EOWNERDEAD = 130; /// + enum ENOTRECOVERABLE = 131; /// + enum ERFKILL = 132; /// + enum EHWPOISON = 133; /// + } + else version (RISCV_Any) + { + enum EDEADLK = 35; /// + enum ENAMETOOLONG = 36; /// + enum ENOLCK = 37; /// + enum ENOSYS = 38; /// + enum ENOTEMPTY = 39; /// + enum ELOOP = 40; /// + enum EWOULDBLOCK = EAGAIN; /// + enum ENOMSG = 42; /// + enum EIDRM = 43; /// + enum ECHRNG = 44; /// + enum EL2NSYNC = 45; /// + enum EL3HLT = 46; /// + enum EL3RST = 47; /// + enum ELNRNG = 48; /// + enum EUNATCH = 49; /// + enum ENOCSI = 50; /// + enum EL2HLT = 51; /// + enum EBADE = 52; /// + enum EBADR = 53; /// + enum EXFULL = 54; /// + enum ENOANO = 55; /// + enum EBADRQC = 56; /// + enum EBADSLT = 57; /// + enum EDEADLOCK = EDEADLK; /// + enum EBFONT = 59; /// + enum ENOSTR = 60; /// + enum ENODATA = 61; /// + enum ETIME = 62; /// + enum ENOSR = 63; /// + enum ENONET = 64; /// + enum ENOPKG = 65; /// + enum EREMOTE = 66; /// + enum ENOLINK = 67; /// + enum EADV = 68; /// + enum ESRMNT = 69; /// + enum ECOMM = 70; /// + enum EPROTO = 71; /// + enum EMULTIHOP = 72; /// + enum EDOTDOT = 73; /// + enum EBADMSG = 74; /// + enum EOVERFLOW = 75; /// + enum ENOTUNIQ = 76; /// + enum EBADFD = 77; /// + enum EREMCHG = 78; /// + enum ELIBACC = 79; /// + enum ELIBBAD = 80; /// + enum ELIBSCN = 81; /// + enum ELIBMAX = 82; /// + enum ELIBEXEC = 83; /// + enum EILSEQ = 84; /// + enum ERESTART = 85; /// + enum ESTRPIPE = 86; /// + enum EUSERS = 87; /// + enum ENOTSOCK = 88; /// + enum EDESTADDRREQ = 89; /// + enum EMSGSIZE = 90; /// + enum EPROTOTYPE = 91; /// + enum ENOPROTOOPT = 92; /// + enum EPROTONOSUPPORT = 93; /// + enum ESOCKTNOSUPPORT = 94; /// + enum EOPNOTSUPP = 95; /// + enum EPFNOSUPPORT = 96; /// + enum EAFNOSUPPORT = 97; /// + enum EADDRINUSE = 98; /// + enum EADDRNOTAVAIL = 99; /// + enum ENETDOWN = 100; /// + enum ENETUNREACH = 101; /// + enum ENETRESET = 102; /// + enum ECONNABORTED = 103; /// + enum ECONNRESET = 104; /// + enum ENOBUFS = 105; /// + enum EISCONN = 106; /// + enum ENOTCONN = 107; /// + enum ESHUTDOWN = 108; /// + enum ETOOMANYREFS = 109; /// + enum ETIMEDOUT = 110; /// + enum ECONNREFUSED = 111; /// + enum EHOSTDOWN = 112; /// + enum EHOSTUNREACH = 113; /// + enum EALREADY = 114; /// + enum EINPROGRESS = 115; /// + enum ESTALE = 116; /// + enum EUCLEAN = 117; /// + enum ENOTNAM = 118; /// + enum ENAVAIL = 119; /// + enum EISNAM = 120; /// + enum EREMOTEIO = 121; /// + enum EDQUOT = 122; /// + enum ENOMEDIUM = 123; /// + enum EMEDIUMTYPE = 124; /// + enum ECANCELED = 125; /// + enum ENOKEY = 126; /// + enum EKEYEXPIRED = 127; /// + enum EKEYREVOKED = 128; /// + enum EKEYREJECTED = 129; /// + enum EOWNERDEAD = 130; /// + enum ENOTRECOVERABLE = 131; /// + enum ERFKILL = 132; /// + enum EHWPOISON = 133; /// + } + else version (SPARC_Any) + { + enum EWOULDBLOCK = EAGAIN; /// + enum EINPROGRESS = 36; /// + enum EALREADY = 37; /// + enum ENOTSOCK = 38; /// + enum EDESTADDRREQ = 39; /// + enum EMSGSIZE = 40; /// + enum EPROTOTYPE = 41; /// + enum ENOPROTOOPT = 42; /// + enum EPROTONOSUPPORT = 43; /// + enum ESOCKTNOSUPPORT = 44; /// + enum EOPNOTSUPP = 45; /// + enum ENOTSUP = EOPNOTSUPP; /// + enum EPFNOSUPPORT = 46; /// + enum EAFNOSUPPORT = 47; /// + enum EADDRINUSE = 48; /// + enum EADDRNOTAVAIL = 49; /// + enum ENETDOWN = 50; /// + enum ENETUNREACH = 51; /// + enum ENETRESET = 52; /// + enum ECONNABORTED = 53; /// + enum ECONNRESET = 54; /// + enum ENOBUFS = 55; /// + enum EISCONN = 56; /// + enum ENOTCONN = 57; /// + enum ESHUTDOWN = 58; /// + enum ETOOMANYREFS = 59; /// + enum ETIMEDOUT = 60; /// + enum ECONNREFUSED = 61; /// + enum ELOOP = 62; /// + enum ENAMETOOLONG = 63; /// + enum EHOSTDOWN = 64; /// + enum EHOSTUNREACH = 65; /// + enum ENOTEMPTY = 66; /// + enum EPROCLIM = 67; /// + enum EUSERS = 68; /// + enum EDQUOT = 69; /// + enum ESTALE = 70; /// + enum EREMOTE = 71; /// + enum ENOSTR = 72; /// + enum ETIME = 73; /// + enum ENOSR = 74; /// + enum ENOMSG = 75; /// + enum EBADMSG = 76; /// + enum EIDRM = 77; /// + enum EDEADLK = 78; /// + enum ENOLCK = 79; /// + enum ENONET = 80; /// + enum ERREMOTE = 81; /// + enum ENOLINK = 82; /// + enum EADV = 83; /// + enum ESRMNT = 84; /// + enum ECOMM = 85; /// + enum EPROTO = 86; /// + enum EMULTIHOP = 87; /// + enum EDOTDOT = 88; /// + enum EREMCHG = 89; /// + enum ENOSYS = 90; /// + enum ESTRPIPE = 91; /// + enum EOVERFLOW = 92; /// + enum EBADFD = 93; /// + enum ECHRNG = 94; /// + enum EL2NSYNC = 95; /// + enum EL3HLT = 96; /// + enum EL3RST = 97; /// + enum ELNRNG = 98; /// + enum EUNATCH = 99; /// + enum ENOCSI = 100; /// + enum EL2HLT = 101; /// + enum EBADE = 102; /// + enum EBADR = 103; /// + enum EXFULL = 104; /// + enum ENOANO = 105; /// + enum EBADRQC = 106; /// + enum EBADSLT = 107; /// + enum EDEADLOCK = 108; /// + enum EBFONT = 109; /// + enum ELIBEXEC = 110; /// + enum ENODATA = 111; /// + enum ELIBBAD = 112; /// + enum ENOPKG = 113; /// + enum ELIBACC = 114; /// + enum ENOTUNIQ = 115; /// + enum ERESTART = 116; /// + enum EUCLEAN = 117; /// + enum ENOTNAM = 118; /// + enum ENAVAIL = 119; /// + enum EISNAM = 120; /// + enum EREMOTEIO = 121; /// + enum EILSEQ = 122; /// + enum ELIBMAX = 123; /// + enum ELIBSCN = 124; /// + enum ENOMEDIUM = 125; /// + enum EMEDIUMTYPE = 126; /// + enum ECANCELED = 127; /// + enum ENOKEY = 128; /// + enum EKEYEXPIRED = 129; /// + enum EKEYREVOKED = 130; /// + enum EKEYREJECTED = 131; /// + enum EOWNERDEAD = 132; /// + enum ENOTRECOVERABLE = 133; /// + enum ERFKILL = 134; /// + enum EHWPOISON = 135; /// + } + else version (IBMZ_Any) + { + enum EDEADLK = 35; /// + enum ENAMETOOLONG = 36; /// + enum ENOLCK = 37; /// + enum ENOSYS = 38; /// + enum ENOTEMPTY = 39; /// + enum ELOOP = 40; /// + enum EWOULDBLOCK = EAGAIN; /// + enum ENOMSG = 42; /// + enum EIDRM = 43; /// + enum ECHRNG = 44; /// + enum EL2NSYNC = 45; /// + enum EL3HLT = 46; /// + enum EL3RST = 47; /// + enum ELNRNG = 48; /// + enum EUNATCH = 49; /// + enum ENOCSI = 50; /// + enum EL2HLT = 51; /// + enum EBADE = 52; /// + enum EBADR = 53; /// + enum EXFULL = 54; /// + enum ENOANO = 55; /// + enum EBADRQC = 56; /// + enum EBADSLT = 57; /// + enum EDEADLOCK = EDEADLK; /// + enum EBFONT = 59; /// + enum ENOSTR = 60; /// + enum ENODATA = 61; /// + enum ETIME = 62; /// + enum ENOSR = 63; /// + enum ENONET = 64; /// + enum ENOPKG = 65; /// + enum EREMOTE = 66; /// + enum ENOLINK = 67; /// + enum EADV = 68; /// + enum ESRMNT = 69; /// + enum ECOMM = 70; /// + enum EPROTO = 71; /// + enum EMULTIHOP = 72; /// + enum EDOTDOT = 73; /// + enum EBADMSG = 74; /// + enum EOVERFLOW = 75; /// + enum ENOTUNIQ = 76; /// + enum EBADFD = 77; /// + enum EREMCHG = 78; /// + enum ELIBACC = 79; /// + enum ELIBBAD = 80; /// + enum ELIBSCN = 81; /// + enum ELIBMAX = 82; /// + enum ELIBEXEC = 83; /// + enum EILSEQ = 84; /// + enum ERESTART = 85; /// + enum ESTRPIPE = 86; /// + enum EUSERS = 87; /// + enum ENOTSOCK = 88; /// + enum EDESTADDRREQ = 89; /// + enum EMSGSIZE = 90; /// + enum EPROTOTYPE = 91; /// + enum ENOPROTOOPT = 92; /// + enum EPROTONOSUPPORT = 93; /// + enum ESOCKTNOSUPPORT = 94; /// + enum EOPNOTSUPP = 95; /// + enum ENOTSUP = EOPNOTSUPP; /// + enum EPFNOSUPPORT = 96; /// + enum EAFNOSUPPORT = 97; /// + enum EADDRINUSE = 98; /// + enum EADDRNOTAVAIL = 99; /// + enum ENETDOWN = 100; /// + enum ENETUNREACH = 101; /// + enum ENETRESET = 102; /// + enum ECONNABORTED = 103; /// + enum ECONNRESET = 104; /// + enum ENOBUFS = 105; /// + enum EISCONN = 106; /// + enum ENOTCONN = 107; /// + enum ESHUTDOWN = 108; /// + enum ETOOMANYREFS = 109; /// + enum ETIMEDOUT = 110; /// + enum ECONNREFUSED = 111; /// + enum EHOSTDOWN = 112; /// + enum EHOSTUNREACH = 113; /// + enum EALREADY = 114; /// + enum EINPROGRESS = 115; /// + enum ESTALE = 116; /// + enum EUCLEAN = 117; /// + enum ENOTNAM = 118; /// + enum ENAVAIL = 119; /// + enum EISNAM = 120; /// + enum EREMOTEIO = 121; /// + enum EDQUOT = 122; /// + enum ENOMEDIUM = 123; /// + enum EMEDIUMTYPE = 124; /// + enum ECANCELED = 125; /// + enum ENOKEY = 126; /// + enum EKEYEXPIRED = 127; /// + enum EKEYREVOKED = 128; /// + enum EKEYREJECTED = 129; /// + enum EOWNERDEAD = 130; /// + enum ENOTRECOVERABLE = 131; /// + enum ERFKILL = 132; /// + enum EHWPOISON = 133; /// + } + else version (LoongArch64) + { + enum EDEADLK = 35; /// + enum ENAMETOOLONG = 36; /// + enum ENOLCK = 37; /// + enum ENOSYS = 38; /// + enum ENOTEMPTY = 39; /// + enum ELOOP = 40; /// + enum EWOULDBLOCK = EAGAIN; /// + enum ENOMSG = 42; /// + enum EIDRM = 43; /// + enum ECHRNG = 44; /// + enum EL2NSYNC = 45; /// + enum EL3HLT = 46; /// + enum EL3RST = 47; /// + enum ELNRNG = 48; /// + enum EUNATCH = 49; /// + enum ENOCSI = 50; /// + enum EL2HLT = 51; /// + enum EBADE = 52; /// + enum EBADR = 53; /// + enum EXFULL = 54; /// + enum ENOANO = 55; /// + enum EBADRQC = 56; /// + enum EBADSLT = 57; /// + enum EDEADLOCK = EDEADLK; /// + enum EBFONT = 59; /// + enum ENOSTR = 60; /// + enum ENODATA = 61; /// + enum ETIME = 62; /// + enum ENOSR = 63; /// + enum ENONET = 64; /// + enum ENOPKG = 65; /// + enum EREMOTE = 66; /// + enum ENOLINK = 67; /// + enum EADV = 68; /// + enum ESRMNT = 69; /// + enum ECOMM = 70; /// + enum EPROTO = 71; /// + enum EMULTIHOP = 72; /// + enum EDOTDOT = 73; /// + enum EBADMSG = 74; /// + enum EOVERFLOW = 75; /// + enum ENOTUNIQ = 76; /// + enum EBADFD = 77; /// + enum EREMCHG = 78; /// + enum ELIBACC = 79; /// + enum ELIBBAD = 80; /// + enum ELIBSCN = 81; /// + enum ELIBMAX = 82; /// + enum ELIBEXEC = 83; /// + enum EILSEQ = 84; /// + enum ERESTART = 85; /// + enum ESTRPIPE = 86; /// + enum EUSERS = 87; /// + enum ENOTSOCK = 88; /// + enum EDESTADDRREQ = 89; /// + enum EMSGSIZE = 90; /// + enum EPROTOTYPE = 91; /// + enum ENOPROTOOPT = 92; /// + enum EPROTONOSUPPORT = 93; /// + enum ESOCKTNOSUPPORT = 94; /// + enum EOPNOTSUPP = 95; /// + enum ENOTSUP = EOPNOTSUPP; /// + enum EPFNOSUPPORT = 96; /// + enum EAFNOSUPPORT = 97; /// + enum EADDRINUSE = 98; /// + enum EADDRNOTAVAIL = 99; /// + enum ENETDOWN = 100; /// + enum ENETUNREACH = 101; /// + enum ENETRESET = 102; /// + enum ECONNABORTED = 103; /// + enum ECONNRESET = 104; /// + enum ENOBUFS = 105; /// + enum EISCONN = 106; /// + enum ENOTCONN = 107; /// + enum ESHUTDOWN = 108; /// + enum ETOOMANYREFS = 109; /// + enum ETIMEDOUT = 110; /// + enum ECONNREFUSED = 111; /// + enum EHOSTDOWN = 112; /// + enum EHOSTUNREACH = 113; /// + enum EALREADY = 114; /// + enum EINPROGRESS = 115; /// + enum ESTALE = 116; /// + enum EUCLEAN = 117; /// + enum ENOTNAM = 118; /// + enum ENAVAIL = 119; /// + enum EISNAM = 120; /// + enum EREMOTEIO = 121; /// + enum EDQUOT = 122; /// + enum ENOMEDIUM = 123; /// + enum EMEDIUMTYPE = 124; /// + enum ECANCELED = 125; /// + enum ENOKEY = 126; /// + enum EKEYEXPIRED = 127; /// + enum EKEYREVOKED = 128; /// + enum EKEYREJECTED = 129; /// + enum EOWNERDEAD = 130; /// + enum ENOTRECOVERABLE = 131; /// + enum ERFKILL = 132; /// + enum EHWPOISON = 133; /// + } + else + { + static assert(false, "Architecture not supported."); + } +} +else version (Darwin) +{ + enum EPERM = 1; /// Operation not permitted + enum ENOENT = 2; /// No such file or directory + enum ESRCH = 3; /// No such process + enum EINTR = 4; /// Interrupted system call + enum EIO = 5; /// Input/output error + enum ENXIO = 6; /// Device not configured + enum E2BIG = 7; /// Argument list too long + enum ENOEXEC = 8; /// Exec format error + enum EBADF = 9; /// Bad file descriptor + enum ECHILD = 10; /// No child processes + enum EDEADLK = 11; /// Resource deadlock avoided + enum ENOMEM = 12; /// Cannot allocate memory + enum EACCES = 13; /// Permission denied + enum EFAULT = 14; /// Bad address + enum EBUSY = 16; /// Device busy + enum EEXIST = 17; /// File exists + enum EXDEV = 18; /// Cross-device link + enum ENODEV = 19; /// Operation not supported by device + enum ENOTDIR = 20; /// Not a directory + enum EISDIR = 21; /// Is a directory + enum EINVAL = 22; /// Invalid argument + enum ENFILE = 23; /// Too many open files in system + enum EMFILE = 24; /// Too many open files + enum ENOTTY = 25; /// Inappropriate ioctl for device + enum ETXTBSY = 26; /// Text file busy + enum EFBIG = 27; /// File too large + enum ENOSPC = 28; /// No space left on device + enum ESPIPE = 29; /// Illegal seek + enum EROFS = 30; /// Read-only file system + enum EMLINK = 31; /// Too many links + enum EPIPE = 32; /// Broken pipe + enum EDOM = 33; /// Numerical argument out of domain + enum ERANGE = 34; /// Result too large + enum EAGAIN = 35; /// Resource temporarily unavailable + enum EWOULDBLOCK = EAGAIN; /// Operation would block + enum EINPROGRESS = 36; /// Operation now in progress + enum EALREADY = 37; /// Operation already in progress + enum ENOTSOCK = 38; /// Socket operation on non-socket + enum EDESTADDRREQ = 39; /// Destination address required + enum EMSGSIZE = 40; /// Message too long + enum EPROTOTYPE = 41; /// Protocol wrong type for socket + enum ENOPROTOOPT = 42; /// Protocol not available + enum EPROTONOSUPPORT = 43; /// Protocol not supported + enum ENOTSUP = 45; /// Operation not supported + enum EOPNOTSUPP = ENOTSUP; /// Operation not supported on socket + enum EAFNOSUPPORT = 47; /// Address family not supported by protocol family + enum EADDRINUSE = 48; /// Address already in use + enum EADDRNOTAVAIL = 49; /// Can't assign requested address + enum ENETDOWN = 50; /// Network is down + enum ENETUNREACH = 51; /// Network is unreachable + enum ENETRESET = 52; /// Network dropped connection on reset + enum ECONNABORTED = 53; /// Software caused connection abort + enum ECONNRESET = 54; /// Connection reset by peer + enum ENOBUFS = 55; /// No buffer space available + enum EISCONN = 56; /// Socket is already connected + enum ENOTCONN = 57; /// Socket is not connected + enum ETIMEDOUT = 60; /// Operation timed out + enum ECONNREFUSED = 61; /// Connection refused + enum ELOOP = 62; /// Too many levels of symbolic links + enum ENAMETOOLONG = 63; /// File name too long + enum EHOSTUNREACH = 65; /// No route to host + enum ENOTEMPTY = 66; /// Directory not empty + enum EDQUOT = 69; /// Disc quota exceeded + enum ESTALE = 70; /// Stale NFS file handle + enum ENOLCK = 77; /// No locks available + enum ENOSYS = 78; /// Function not implemented + enum EOVERFLOW = 84; /// Value too large to be stored in data type + enum ECANCELED = 89; /// Operation canceled + enum EIDRM = 90; /// Identifier removed + enum ENOMSG = 91; /// No message of desired type + enum EILSEQ = 92; /// Illegal byte sequence + enum EBADMSG = 94; /// Bad message + enum EMULTIHOP = 95; /// Reserved + enum ENODATA = 96; /// No message available on STREAM + enum ENOLINK = 97; /// Reserved + enum ENOSR = 98; /// No STREAM resources + enum ENOSTR = 99; /// Not a STREAM + enum EPROTO = 100; /// Protocol error + enum ETIME = 101; /// STREAM ioctl timeout + enum ELAST = 101; /// Must be equal largest errno +} +else version (FreeBSD) +{ + enum EPERM = 1; /// Operation not permitted + enum ENOENT = 2; /// No such file or directory + enum ESRCH = 3; /// No such process + enum EINTR = 4; /// Interrupted system call + enum EIO = 5; /// Input/output error + enum ENXIO = 6; /// Device not configured + enum E2BIG = 7; /// Argument list too long + enum ENOEXEC = 8; /// Exec format error + enum EBADF = 9; /// Bad file descriptor + enum ECHILD = 10; /// No child processes + enum EDEADLK = 11; /// Resource deadlock avoided + enum ENOMEM = 12; /// Cannot allocate memory + enum EACCES = 13; /// Permission denied + enum EFAULT = 14; /// Bad address + enum ENOTBLK = 15; /// Block device required + enum EBUSY = 16; /// Device busy + enum EEXIST = 17; /// File exists + enum EXDEV = 18; /// Cross-device link + enum ENODEV = 19; /// Operation not supported by device + enum ENOTDIR = 20; /// Not a directory + enum EISDIR = 21; /// Is a directory + enum EINVAL = 22; /// Invalid argument + enum ENFILE = 23; /// Too many open files in system + enum EMFILE = 24; /// Too many open files + enum ENOTTY = 25; /// Inappropriate ioctl for device + enum ETXTBSY = 26; /// Text file busy + enum EFBIG = 27; /// File too large + enum ENOSPC = 28; /// No space left on device + enum ESPIPE = 29; /// Illegal seek + enum EROFS = 30; /// Read-only file system + enum EMLINK = 31; /// Too many links + enum EPIPE = 32; /// Broken pipe + enum EDOM = 33; /// Numerical argument out of domain + enum ERANGE = 34; /// Result too large + enum EAGAIN = 35; /// Resource temporarily unavailable + enum EWOULDBLOCK = EAGAIN; /// Operation would block + enum EINPROGRESS = 36; /// Operation now in progress + enum EALREADY = 37; /// Operation already in progress + enum ENOTSOCK = 38; /// Socket operation on non-socket + enum EDESTADDRREQ = 39; /// Destination address required + enum EMSGSIZE = 40; /// Message too long + enum EPROTOTYPE = 41; /// Protocol wrong type for socket + enum ENOPROTOOPT = 42; /// Protocol not available + enum EPROTONOSUPPORT = 43; /// Protocol not supported + enum ENOTSUP = 45; /// Operation not supported + enum EOPNOTSUPP = ENOTSUP; /// Operation not supported on socket + enum EAFNOSUPPORT = 47; /// Address family not supported by protocol family + enum EADDRINUSE = 48; /// Address already in use + enum EADDRNOTAVAIL = 49; /// Can't assign requested address + enum ENETDOWN = 50; /// Network is down + enum ENETUNREACH = 51; /// Network is unreachable + enum ENETRESET = 52; /// Network dropped connection on reset + enum ECONNABORTED = 53; /// Software caused connection abort + enum ECONNRESET = 54; /// Connection reset by peer + enum ENOBUFS = 55; /// No buffer space available + enum EISCONN = 56; /// Socket is already connected + enum ENOTCONN = 57; /// Socket is not connected + enum ESHUTDOWN = 58; /// Can't send after socket shutdown + enum ETOOMANYREFS = 59; /// Too many refrences; can't splice + enum ETIMEDOUT = 60; /// Operation timed out + enum ECONNREFUSED = 61; /// Connection refused + enum ELOOP = 62; /// Too many levels of symbolic links + enum ENAMETOOLONG = 63; /// File name too long + enum EHOSTUNREACH = 65; /// No route to host + enum ENOTEMPTY = 66; /// Directory not empty + enum EPROCLIM = 67; /// Too many processes + enum EUSERS = 68; /// Too many users + enum EDQUOT = 69; /// Disc quota exceeded + enum ESTALE = 70; /// Stale NFS file handle + enum EREMOTE = 71; /// Too many levels of remote in path + enum EBADRPC = 72; /// RPC struct is bad + enum ERPCMISMATCH = 73; /// RPC version wrong + enum EPROGUNAVAIL = 74; /// RPC prog. not avail + enum EPROGMISMATCH = 75; /// Program version wrong + enum EPROCUNAVAIL = 76; /// Bad procedure for program + enum ENOLCK = 77; /// No locks available + enum ENOSYS = 78; /// Function not implemented + enum EFTYPE = 79; /// Inappropriate file type or format + enum EAUTH = 80; /// Authentication error + enum ENEEDAUTH = 81; /// Need authenticator + enum EIDRM = 82; /// Itendifier removed + enum ENOMSG = 83; /// No message of desired type + enum EOVERFLOW = 84; /// Value too large to be stored in data type + enum ECANCELED = 85; /// Operation canceled + enum EILSEQ = 86; /// Illegal byte sequence + enum ENOATTR = 87; /// Attribute not found + enum EDOOFUS = 88; /// Programming error + enum EBADMSG = 89; /// Bad message + enum EMULTIHOP = 90; /// Multihop attempted + enum ENOLINK = 91; /// Link has been severed + enum EPROTO = 92; /// Protocol error + enum ELAST = 92; /// Must be equal largest errno +} +else version (NetBSD) +{ + // http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/sys/errno.h + enum EPERM = 1; + enum ENOENT = 2; + enum ESRCH = 3; + enum EINTR = 4; + enum EIO = 5; + enum ENXIO = 6; + enum E2BIG = 7; + enum ENOEXEC = 8; + enum EBADF = 9; + enum ECHILD = 10; + enum EDEADLK = 11; + /// + enum ENOMEM = 12; + enum EACCES = 13; + enum EFAULT = 14; + enum ENOTBLK = 15; + enum EBUSY = 16; + enum EEXIST = 17; + enum EXDEV = 18; + enum ENODEV = 19; + enum ENOTDIR = 20; + enum EISDIR = 21; + enum EINVAL = 22; + enum ENFILE = 23; + enum EMFILE = 24; + enum ENOTTY = 25; + enum ETXTBSY = 26; + enum EFBIG = 27; + enum ENOSPC = 28; + enum ESPIPE = 29; + enum EROFS = 30; + enum EMLINK = 31; + enum EPIPE = 32; + /// + enum EDOM = 33; + enum ERANGE = 34; + + /// + enum EAGAIN = 35; + enum EWOULDBLOCK = EAGAIN; + enum EINPROGRESS = 36; + enum EALREADY = 37; + + /// + enum ENOTSOCK = 38; + enum EDESTADDRREQ = 39; + enum EMSGSIZE = 40; + enum EPROTOTYPE = 41; + enum ENOPROTOOPT = 42; + enum EPROTONOSUPPORT = 43; + enum ESOCKTNOSUPPORT = 44; + enum EOPNOTSUPP = 45; + enum EPFNOSUPPORT = 46; + enum EAFNOSUPPORT = 47; + enum EADDRINUSE = 48; + enum EADDRNOTAVAIL = 49; + + /// + enum ENETDOWN = 50; + enum ENETUNREACH = 51; + enum ENETRESET = 52; + enum ECONNABORTED = 53; + enum ECONNRESET = 54; + enum ENOBUFS = 55; + enum EISCONN = 56; + enum ENOTCONN = 57; + enum ESHUTDOWN = 58; + enum ETOOMANYREFS = 59; + enum ETIMEDOUT = 60; + enum ECONNREFUSED = 61; + enum ELOOP = 62; + enum ENAMETOOLONG = 63; + + /// + enum EHOSTDOWN = 64; + enum EHOSTUNREACH = 65; + enum ENOTEMPTY = 66; + + /// + enum EPROCLIM = 67; + enum EUSERS = 68; + enum EDQUOT = 69; + + /// + enum ESTALE = 70; + enum EREMOTE = 71; + enum EBADRPC = 72; + enum ERPCMISMATCH = 73; + enum EPROGUNAVAIL = 74; + enum EPROGMISMATCH = 75; + enum EPROCUNAVAIL = 76; + + enum ENOLCK = 77; + enum ENOSYS = 78; + + enum EFTYPE = 79; + enum EAUTH = 80; + enum ENEEDAUTH = 81; + + /// + enum EIDRM = 82; + enum ENOMSG = 83; + enum EOVERFLOW = 84; + /// + enum EILSEQ = 85; + + /// + enum ENOTSUP = 86; + + /// + enum ECANCELED = 87; + + /// + enum EBADMSG = 88; + + /// + enum ENODATA = 89; + enum ENOSR = 90; + enum ENOSTR = 91; + enum ETIME = 92; + + /// + enum ENOATTR = 93; + + /// + enum EMULTIHOP = 94; + enum ENOLINK = 95; + enum EPROTO = 96; +} +else version (OpenBSD) +{ + enum EPERM = 1; /// Operation not permitted + enum ENOENT = 2; /// No such file or directory + enum ESRCH = 3; /// No such process + enum EINTR = 4; /// Interrupted system call + enum EIO = 5; /// Input/output error + enum ENXIO = 6; /// Device not configured + enum E2BIG = 7; /// Argument list too long + enum ENOEXEC = 8; /// Exec format error + enum EBADF = 9; /// Bad file descriptor + enum ECHILD = 10; /// No child processes + enum EDEADLK = 11; /// Resource deadlock avoided + enum ENOMEM = 12; /// Cannot allocate memory + enum EACCES = 13; /// Permission denied + enum EFAULT = 14; /// Bad address + enum ENOTBLK = 15; /// Block device required + enum EBUSY = 16; /// Device busy + enum EEXIST = 17; /// File exists + enum EXDEV = 18; /// Cross-device link + enum ENODEV = 19; /// Operation not supported by device + enum ENOTDIR = 20; /// Not a directory + enum EISDIR = 21; /// Is a directory + enum EINVAL = 22; /// Invalid argument + enum ENFILE = 23; /// Too many open files in system + enum EMFILE = 24; /// Too many open files + enum ENOTTY = 25; /// Inappropriate ioctl for device + enum ETXTBSY = 26; /// Text file busy + enum EFBIG = 27; /// File too large + enum ENOSPC = 28; /// No space left on device + enum ESPIPE = 29; /// Illegal seek + enum EROFS = 30; /// Read-only file system + enum EMLINK = 31; /// Too many links + enum EPIPE = 32; /// Broken pipe + enum EDOM = 33; /// Numerical argument out of domain + enum ERANGE = 34; /// Result too large + enum EAGAIN = 35; /// Resource temporarily unavailable + enum EWOULDBLOCK = EAGAIN; /// Operation would block + enum EINPROGRESS = 36; /// Operation now in progress + enum EALREADY = 37; /// Operation already in progress + enum ENOTSOCK = 38; /// Socket operation on non-socket + enum EDESTADDRREQ = 39; /// Destination address required + enum EMSGSIZE = 40; /// Message too long + enum EPROTOTYPE = 41; /// Protocol wrong type for socket + enum ENOPROTOOPT = 42; /// Protocol not available + enum EPROTONOSUPPORT = 43; /// Protocol not supported + enum ESOCKTNOSUPPORT = 44; /// Socket type not supported + enum EOPNOTSUPP = 45; /// Operation not supported + enum EPFNOSUPPORT = 46; /// Protocol family not supported + enum EAFNOSUPPORT = 47; /// Address family not supported by protocol family + enum EADDRINUSE = 48; /// Address already in use + enum EADDRNOTAVAIL = 49; /// Can't assign requested address + enum ENETDOWN = 50; /// Network is down + enum ENETUNREACH = 51; /// Network is unreachable + enum ENETRESET = 52; /// Network dropped connection on reset + enum ECONNABORTED = 53; /// Software caused connection abort + enum ECONNRESET = 54; /// Connection reset by peer + enum ENOBUFS = 55; /// No buffer space available + enum EISCONN = 56; /// Socket is already connected + enum ENOTCONN = 57; /// Socket is not connected + enum ESHUTDOWN = 58; /// Can't send after socket shutdown + enum ETOOMANYREFS = 59; /// Too many references: can't splice + enum ETIMEDOUT = 60; /// Operation timed out + enum ECONNREFUSED = 61; /// Connection refused + enum ELOOP = 62; /// Too many levels of symbolic links + enum ENAMETOOLONG = 63; /// File name too long + enum EHOSTDOWN = 64; /// Host is down + enum EHOSTUNREACH = 65; /// No route to host + enum ENOTEMPTY = 66; /// Directory not empty + enum EPROCLIM = 67; /// Too many processes + enum EUSERS = 68; /// Too many users + enum EDQUOT = 69; /// Disk quota exceeded + enum ESTALE = 70; /// Stale NFS file handle + enum EREMOTE = 71; /// Too many levels of remote in path + enum EBADRPC = 72; /// RPC struct is bad + enum ERPCMISMATCH = 73; /// RPC version wrong + enum EPROGUNAVAIL = 74; /// RPC program not available + enum EPROGMISMATCH = 75; /// Program version wrong + enum EPROCUNAVAIL = 76; /// Bad procedure for program + enum ENOLCK = 77; /// No locks available + enum ENOSYS = 78; /// Function not implemented + enum EFTYPE = 79; /// Inappropriate file type or format + enum EAUTH = 80; /// Authentication error + enum ENEEDAUTH = 81; /// Need authenticator + enum EIPSEC = 82; /// IPsec processing failure + enum ENOATTR = 83; /// Attribute not found + enum EILSEQ = 84; /// Illegal byte sequence + enum ENOMEDIUM = 85; /// No medium found + enum EMEDIUMTYPE = 86; /// Wrong medium type + enum EOVERFLOW = 87; /// Value too large to be stored in data type + enum ECANCELED = 88; /// Operation canceled + enum EIDRM = 89; /// Identifier removed + enum ENOMSG = 90; /// No message of desired type + enum ENOTSUP = 91; /// Not supported + enum EBADMSG = 92; /// Bad message + enum ENOTRECOVERABLE = 93; /// State not recoverable + enum EOWNERDEAD = 94; /// Previous owner died + enum EPROTO = 95; /// Protocol error + enum ELAST = 95; /// Must be equal largest errno +} +else version (DragonFlyBSD) +{ + enum EPERM = 1; + enum ENOENT = 2; + enum ESRCH = 3; + enum EINTR = 4; + enum EIO = 5; + enum ENXIO = 6; + enum E2BIG = 7; + enum ENOEXEC = 8; + enum EBADF = 9; + enum ECHILD = 10; + enum EDEADLK = 11; + enum ENOMEM = 12; + enum EACCES = 13; + enum EFAULT = 14; + enum ENOTBLK = 15; + enum EBUSY = 16; + enum EEXIST = 17; + enum EXDEV = 18; + enum ENODEV = 19; + enum ENOTDIR = 20; + enum EISDIR = 21; + enum EINVAL = 22; + enum ENFILE = 23; + enum EMFILE = 24; + enum ENOTTY = 25; + enum ETXTBSY = 26; + enum EFBIG = 27; + enum ENOSPC = 28; + enum ESPIPE = 29; + enum EROFS = 30; + enum EMLINK = 31; + enum EPIPE = 32; + enum EDOM = 33; + enum ERANGE = 34; + enum EAGAIN = 35; + enum EWOULDBLOCK = EAGAIN; + enum EINPROGRESS = 36; + enum EALREADY = 37; + enum ENOTSOCK = 38; + enum EDESTADDRREQ = 39; + enum EMSGSIZE = 40; + enum EPROTOTYPE = 41; + enum ENOPROTOOPT = 42; + enum EPROTONOSUPPORT = 43; + enum ENOTSUP = 45; + enum EOPNOTSUPP = ENOTSUP; + enum EPFNOSUPPORT = 46; + enum EAFNOSUPPORT = 47; + enum EADDRINUSE = 48; + enum EADDRNOTAVAIL = 49; + enum ENETDOWN = 50; + enum ENETUNREACH = 51; + enum ENETRESET = 52; + enum ECONNABORTED = 53; + enum ECONNRESET = 54; + enum ENOBUFS = 55; + enum EISCONN = 56; + enum ENOTCONN = 57; + enum ESHUTDOWN = 58; + enum ETOOMANYREFS = 59; + enum ETIMEDOUT = 60; + enum ECONNREFUSED = 61; + enum ELOOP = 62; + enum ENAMETOOLONG = 63; + enum EHOSTUNREACH = 65; + enum ENOTEMPTY = 66; + enum EPROCLIM = 67; + enum EUSERS = 68; + enum EDQUOT = 69; + enum ESTALE = 70; + enum EREMOTE = 71; + enum EBADRPC = 72; + enum ERPCMISMATCH = 73; + enum EPROGUNAVAIL = 74; + enum EPROGMISMATCH = 75; + enum EPROCUNAVAIL = 76; + enum ENOLCK = 77; + enum ENOSYS = 78; + enum EFTYPE = 79; + enum EAUTH = 80; + enum ENEEDAUTH = 81; + enum EIDRM = 82; + enum ENOMSG = 83; + enum EOVERFLOW = 84; + enum ECANCELED = 85; + enum EILSEQ = 86; + enum ENOATTR = 87; + enum EDOOFUS = 88; + enum EBADMSG = 89; + enum EMULTIHOP = 90; + enum ENOLINK = 91; + enum EPROTO = 92; + enum ENOMEDIUM = 93; + enum EUNUSED94 = 94; + enum EUNUSED95 = 95; + enum EUNUSED96 = 96; + enum EUNUSED97 = 97; + enum EUNUSED98 = 98; + enum EASYNC = 99; + enum ELAST = 99; +} +else version (Solaris) +{ + enum EPERM = 1; /// Not super-user + enum ENOENT = 2; /// No such file or directory + enum ESRCH = 3; /// No such process + enum EINTR = 4; /// interrupted system call + enum EIO = 5; /// I/O error + enum ENXIO = 6; /// No such device or address + enum E2BIG = 7; /// Arg list too long + enum ENOEXEC = 8; /// Exec format error + enum EBADF = 9; /// Bad file number + enum ECHILD = 10; /// No children + enum EAGAIN = 11; /// Resource temporarily unavailable + enum ENOMEM = 12; /// Not enough core + enum EACCES = 13; /// Permission denied + enum EFAULT = 14; /// Bad address + enum ENOTBLK = 15; /// Block device required + enum EBUSY = 16; /// Mount device busy + enum EEXIST = 17; /// File exists + enum EXDEV = 18; /// Cross-device link + enum ENODEV = 19; /// No such device + enum ENOTDIR = 20; /// Not a directory + enum EISDIR = 21; /// Is a directory + enum EINVAL = 22; /// Invalid argument + enum ENFILE = 23; /// File table overflow + enum EMFILE = 24; /// Too many open files + enum ENOTTY = 25; /// Inappropriate ioctl for device + enum ETXTBSY = 26; /// Text file busy + enum EFBIG = 27; /// File too large + enum ENOSPC = 28; /// No space left on device + enum ESPIPE = 29; /// Illegal seek + enum EROFS = 30; /// Read only file system + enum EMLINK = 31; /// Too many links + enum EPIPE = 32; /// Broken pipe + enum EDOM = 33; /// Math arg out of domain of func + enum ERANGE = 34; /// Math result not representable + enum ENOMSG = 35; /// No message of desired type + enum EIDRM = 36; /// Identifier removed + enum ECHRNG = 37; /// Channel number out of range + enum EL2NSYNC = 38; /// Level 2 not synchronized + enum EL3HLT = 39; /// Level 3 halted + enum EL3RST = 40; /// Level 3 reset + enum ELNRNG = 41; /// Link number out of range + enum EUNATCH = 42; /// Protocol driver not attached + enum ENOCSI = 43; /// No CSI structure available + enum EL2HLT = 44; /// Level 2 halted + enum EDEADLK = 45; /// Deadlock condition. + enum ENOLCK = 46; /// No record locks available. + enum ECANCELED = 47; /// Operation canceled + enum ENOTSUP = 48; /// Operation not supported + enum EDQUOT = 49; /// Disc quota exceeded + enum EBADE = 50; /// invalid exchange + enum EBADR = 51; /// invalid request descriptor + enum EXFULL = 52; /// exchange full + enum ENOANO = 53; /// no anode + enum EBADRQC = 54; /// invalid request code + enum EBADSLT = 55; /// invalid slot + enum EDEADLOCK = 56; /// file locking deadlock error + enum EBFONT = 57; /// bad font file fmt + enum EOWNERDEAD = 58; /// process died with the lock + enum ENOTRECOVERABLE = 59; /// lock is not recoverable + enum ENOSTR = 60; /// Device not a stream + enum ENODATA = 61; /// no data (for no delay io) + enum ETIME = 62; /// timer expired + enum ENOSR = 63; /// out of streams resources + enum ENONET = 64; /// Machine is not on the network + enum ENOPKG = 65; /// Package not installed + enum EREMOTE = 66; /// The object is remote + enum ENOLINK = 67; /// the link has been severed + enum EADV = 68; /// advertise error + enum ESRMNT = 69; /// srmount error + enum ECOMM = 70; /// Communication error on send + enum EPROTO = 71; /// Protocol error + enum ELOCKUNMAPPED = 72; /// locked lock was unmapped + enum ENOTACTIVE = 73; /// Facility is not active + enum EMULTIHOP = 74; /// multihop attempted + enum EBADMSG = 77; /// trying to read unreadable message + enum ENAMETOOLONG = 78; /// path name is too long + enum EOVERFLOW = 79; /// value too large to be stored in data type + enum ENOTUNIQ = 80; /// given log. name not unique + enum EBADFD = 81; /// f.d. invalid for this operation + enum EREMCHG = 82; /// Remote address changed + enum ELIBACC = 83; /// Can't access a needed shared lib. + enum ELIBBAD = 84; /// Accessing a corrupted shared lib. + enum ELIBSCN = 85; /// .lib section in a.out corrupted. + enum ELIBMAX = 86; /// Attempting to link in too many libs. + enum ELIBEXEC = 87; /// Attempting to exec a shared library. + enum EILSEQ = 88; /// Illegal byte sequence. + enum ENOSYS = 89; /// Unsupported file system operation + enum ELOOP = 90; /// Symbolic link loop + enum ERESTART = 91; /// Restartable system call + enum ESTRPIPE = 92; /// if pipe/FIFO, don't sleep in stream head + enum ENOTEMPTY = 93; /// directory not empty + enum EUSERS = 94; /// Too many users (for UFS) + enum ENOTSOCK = 95; /// Socket operation on non-socket + enum EDESTADDRREQ = 96; /// Destination address required + enum EMSGSIZE = 97; /// Message too long + enum EPROTOTYPE = 98; /// Protocol wrong type for socket + enum ENOPROTOOPT = 99; /// Protocol not available + enum EPROTONOSUPPORT = 120; /// Protocol not supported + enum ESOCKTNOSUPPORT = 121; /// Socket type not supported + enum EOPNOTSUPP = 122; /// Operation not supported on socket + enum EPFNOSUPPORT = 123; /// Protocol family not supported + enum EAFNOSUPPORT = 124; /// Address family not supported by the protocol family + enum EADDRINUSE = 125; /// Address already in use + enum EADDRNOTAVAIL = 126; /// Can't assign requested address + enum ENETDOWN = 127; /// Network is down + enum ENETUNREACH = 128; /// Network is unreachable + enum ENETRESET = 129; /// Network dropped connection because of reset + enum ECONNABORTED = 130; /// Software caused connection abort + enum ECONNRESET = 131; /// Connection reset by peer + enum ENOBUFS = 132; /// No buffer space available + enum EISCONN = 133; /// Socket is already connected + enum ENOTCONN = 134; /// Socket is not connected + enum ESHUTDOWN = 143; /// Can't send after socket shutdown + enum ETOOMANYREFS = 144; /// Too many references: can't splice + enum ETIMEDOUT = 145; /// Connection timed out + enum ECONNREFUSED = 146; /// Connection refused + enum EHOSTDOWN = 147; /// Host is down + enum EHOSTUNREACH = 148; /// No route to host + enum EWOULDBLOCK = EAGAIN; /// Resource temporarily unavailable + enum EALREADY = 149; /// operation already in progress + enum EINPROGRESS = 150; /// operation now in progress + enum ESTALE = 151; /// Stale NFS file handle +} +else version (Haiku) +{ + // https://github.com/haiku/haiku/blob/master/headers/os/support/Errors.h + // https://github.com/haiku/haiku/blob/master/headers/build/os/support/Errors.h + import core.stdc.limits : INT_MIN; + enum B_GENERAL_ERROR_BASE = INT_MIN; + enum B_OS_ERROR_BASE = (B_GENERAL_ERROR_BASE + 0x1000); + enum B_APP_ERROR_BASE = (B_GENERAL_ERROR_BASE + 0x2000); + enum B_INTERFACE_ERROR_BASE = (B_GENERAL_ERROR_BASE + 0x3000); + enum B_MEDIA_ERROR_BASE = (B_GENERAL_ERROR_BASE + 0x4000); + /* - 0x41ff */ + enum B_TRANSLATION_ERROR_BASE = (B_GENERAL_ERROR_BASE + 0x4800); + /* - 0x48ff */ + enum B_MIDI_ERROR_BASE = (B_GENERAL_ERROR_BASE + 0x5000); + enum B_STORAGE_ERROR_BASE = (B_GENERAL_ERROR_BASE + 0x6000); + enum B_POSIX_ERROR_BASE = (B_GENERAL_ERROR_BASE + 0x7000); + enum B_MAIL_ERROR_BASE = (B_GENERAL_ERROR_BASE + 0x8000); + enum B_PRINT_ERROR_BASE = (B_GENERAL_ERROR_BASE + 0x9000); + enum B_DEVICE_ERROR_BASE = (B_GENERAL_ERROR_BASE + 0xa000); + + /* General Errors */ + enum B_NO_MEMORY = (B_GENERAL_ERROR_BASE + 0); + enum B_IO_ERROR = (B_GENERAL_ERROR_BASE + 1); + enum B_PERMISSION_DENIED = (B_GENERAL_ERROR_BASE + 2); + enum B_BAD_INDEX = (B_GENERAL_ERROR_BASE + 3); + enum B_BAD_TYPE = (B_GENERAL_ERROR_BASE + 4); + enum B_BAD_VALUE = (B_GENERAL_ERROR_BASE + 5); + enum B_MISMATCHED_VALUES = (B_GENERAL_ERROR_BASE + 6); + enum B_NAME_NOT_FOUND = (B_GENERAL_ERROR_BASE + 7); + enum B_NAME_IN_USE = (B_GENERAL_ERROR_BASE + 8); + enum B_TIMED_OUT = (B_GENERAL_ERROR_BASE + 9); + enum B_INTERRUPTED = (B_GENERAL_ERROR_BASE + 10); + enum B_WOULD_BLOCK = (B_GENERAL_ERROR_BASE + 11); + enum B_CANCELED = (B_GENERAL_ERROR_BASE + 12); + enum B_NO_INIT = (B_GENERAL_ERROR_BASE + 13); + enum B_NOT_INITIALIZED = (B_GENERAL_ERROR_BASE + 13); + enum B_BUSY = (B_GENERAL_ERROR_BASE + 14); + enum B_NOT_ALLOWED = (B_GENERAL_ERROR_BASE + 15); + enum B_BAD_DATA = (B_GENERAL_ERROR_BASE + 16); + enum B_DONT_DO_THAT = (B_GENERAL_ERROR_BASE + 17); + + enum B_ERROR = (-1); + enum B_OK = (int(0)); + enum B_NO_ERROR = (int(0)); + + /* Kernel Kit Errors */ + enum B_BAD_SEM_ID = (B_OS_ERROR_BASE + 0); + enum B_NO_MORE_SEMS = (B_OS_ERROR_BASE + 1); + + enum B_BAD_THREAD_ID = (B_OS_ERROR_BASE + 0x100); + enum B_NO_MORE_THREADS = (B_OS_ERROR_BASE + 0x101); + enum B_BAD_THREAD_STATE = (B_OS_ERROR_BASE + 0x102); + enum B_BAD_TEAM_ID = (B_OS_ERROR_BASE + 0x103); + enum B_NO_MORE_TEAMS = (B_OS_ERROR_BASE + 0x104); + + enum B_BAD_PORT_ID = (B_OS_ERROR_BASE + 0x200); + enum B_NO_MORE_PORTS = (B_OS_ERROR_BASE + 0x201); + + enum B_BAD_IMAGE_ID = (B_OS_ERROR_BASE + 0x300); + enum B_BAD_ADDRESS = (B_OS_ERROR_BASE + 0x301); + enum B_NOT_AN_EXECUTABLE = (B_OS_ERROR_BASE + 0x302); + enum B_MISSING_LIBRARY = (B_OS_ERROR_BASE + 0x303); + enum B_MISSING_SYMBOL = (B_OS_ERROR_BASE + 0x304); + enum B_UNKNOWN_EXECUTABLE = (B_OS_ERROR_BASE + 0x305); + enum B_LEGACY_EXECUTABLE = (B_OS_ERROR_BASE + 0x306); + + enum B_DEBUGGER_ALREADY_INSTALLED = (B_OS_ERROR_BASE + 0x400); + + /* Application Kit Errors */ + enum B_BAD_REPLY = (B_APP_ERROR_BASE + 0); + enum B_DUPLICATE_REPLY = (B_APP_ERROR_BASE + 1); + enum B_MESSAGE_TO_SELF = (B_APP_ERROR_BASE + 2); + enum B_BAD_HANDLER = (B_APP_ERROR_BASE + 3); + enum B_ALREADY_RUNNING = (B_APP_ERROR_BASE + 4); + enum B_LAUNCH_FAILED = (B_APP_ERROR_BASE + 5); + enum B_AMBIGUOUS_APP_LAUNCH = (B_APP_ERROR_BASE + 6); + enum B_UNKNOWN_MIME_TYPE = (B_APP_ERROR_BASE + 7); + enum B_BAD_SCRIPT_SYNTAX = (B_APP_ERROR_BASE + 8); + enum B_LAUNCH_FAILED_NO_RESOLVE_LINK = (B_APP_ERROR_BASE + 9); + enum B_LAUNCH_FAILED_EXECUTABLE = (B_APP_ERROR_BASE + 10); + enum B_LAUNCH_FAILED_APP_NOT_FOUND = (B_APP_ERROR_BASE + 11); + enum B_LAUNCH_FAILED_APP_IN_TRASH = (B_APP_ERROR_BASE + 12); + enum B_LAUNCH_FAILED_NO_PREFERRED_APP = (B_APP_ERROR_BASE + 13); + enum B_LAUNCH_FAILED_FILES_APP_NOT_FOUND = (B_APP_ERROR_BASE + 14); + enum B_BAD_MIME_SNIFFER_RULE = (B_APP_ERROR_BASE + 15); + enum B_NOT_A_MESSAGE = (B_APP_ERROR_BASE + 16); + enum B_SHUTDOWN_CANCELLED = (B_APP_ERROR_BASE + 17); + enum B_SHUTTING_DOWN = (B_APP_ERROR_BASE + 18); + + /* Storage Kit/File System Errors */ + enum B_FILE_ERROR = (B_STORAGE_ERROR_BASE + 0); + enum B_FILE_NOT_FOUND = (B_STORAGE_ERROR_BASE + 1); + /* deprecated: use B_ENTRY_NOT_FOUND instead */ + enum B_FILE_EXISTS = (B_STORAGE_ERROR_BASE + 2); + enum B_ENTRY_NOT_FOUND = (B_STORAGE_ERROR_BASE + 3); + enum B_NAME_TOO_LONG = (B_STORAGE_ERROR_BASE + 4); + enum B_NOT_A_DIRECTORY = (B_STORAGE_ERROR_BASE + 5); + enum B_DIRECTORY_NOT_EMPTY = (B_STORAGE_ERROR_BASE + 6); + enum B_DEVICE_FULL = (B_STORAGE_ERROR_BASE + 7); + enum B_READ_ONLY_DEVICE = (B_STORAGE_ERROR_BASE + 8); + enum B_IS_A_DIRECTORY = (B_STORAGE_ERROR_BASE + 9); + enum B_NO_MORE_FDS = (B_STORAGE_ERROR_BASE + 10); + enum B_CROSS_DEVICE_LINK = (B_STORAGE_ERROR_BASE + 11); + enum B_LINK_LIMIT = (B_STORAGE_ERROR_BASE + 12); + enum B_BUSTED_PIPE = (B_STORAGE_ERROR_BASE + 13); + enum B_UNSUPPORTED = (B_STORAGE_ERROR_BASE + 14); + enum B_PARTITION_TOO_SMALL = (B_STORAGE_ERROR_BASE + 15); + enum B_PARTIAL_READ = (B_STORAGE_ERROR_BASE + 16); + enum B_PARTIAL_WRITE = (B_STORAGE_ERROR_BASE + 17); + + /* POSIX Errors */ + enum B_USE_POSITIVE_POSIX_ERRORS = false; + + static if (B_USE_POSITIVE_POSIX_ERRORS) + { + enum B_TO_POSIX_ERROR(int code) = -code; + } + else + { + enum B_TO_POSIX_ERROR(int code) = code; + } + alias B_FROM_POSIX_ERROR = B_TO_POSIX_ERROR; + + enum B_POSIX_ENOMEM = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 0); + enum E2BIG = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 1); + enum ECHILD = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 2); + enum EDEADLK = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 3); + enum EFBIG = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 4); + enum EMLINK = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 5); + enum ENFILE = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 6); + enum ENODEV = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 7); + enum ENOLCK = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 8); + enum ENOSYS = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 9); + enum ENOTTY = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 10); + enum ENXIO = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 11); + enum ESPIPE = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 12); + enum ESRCH = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 13); + enum EFPOS = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 14); + enum ESIGPARM = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 15); + enum EDOM = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 16); + enum ERANGE = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 17); + enum EPROTOTYPE = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 18); + enum EPROTONOSUPPORT = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 19); + enum EPFNOSUPPORT = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 20); + enum EAFNOSUPPORT = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 21); + enum EADDRINUSE = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 22); + enum EADDRNOTAVAIL = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 23); + enum ENETDOWN = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 24); + enum ENETUNREACH = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 25); + enum ENETRESET = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 26); + enum ECONNABORTED = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 27); + enum ECONNRESET = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 28); + enum EISCONN = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 29); + enum ENOTCONN = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 30); + enum ESHUTDOWN = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 31); + enum ECONNREFUSED = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 32); + enum EHOSTUNREACH = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 33); + enum ENOPROTOOPT = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 34); + enum ENOBUFS = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 35); + enum EINPROGRESS = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 36); + enum EALREADY = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 37); + enum EILSEQ = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 38); + enum ENOMSG = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 39); + enum ESTALE = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 40); + enum EOVERFLOW = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 41); + enum EMSGSIZE = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 42); + enum EOPNOTSUPP = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 43); + enum ENOTSOCK = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 44); + enum EHOSTDOWN = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 45); + enum EBADMSG = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 46); + enum ECANCELED = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 47); + enum EDESTADDRREQ = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 48); + enum EDQUOT = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 49); + enum EIDRM = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 50); + enum EMULTIHOP = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 51); + enum ENODATA = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 52); + enum ENOLINK = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 53); + enum ENOSR = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 54); + enum ENOSTR = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 55); + enum ENOTSUP = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 56); + enum EPROTO = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 57); + enum ETIME = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 58); + enum ETXTBSY = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 59); + enum ENOATTR = B_TO_POSIX_ERROR!(B_POSIX_ERROR_BASE + 60); + + /* B_NO_MEMORY (0x80000000) can't be negated, so it needs special handling */ + static if (B_USE_POSITIVE_POSIX_ERRORS) + enum ENOMEM = B_POSIX_ENOMEM; + else + enum ENOMEM = B_NO_MEMORY; + + /* POSIX errors that can be mapped to BeOS error codes */ + enum EACCES = B_TO_POSIX_ERROR!(B_PERMISSION_DENIED); + enum EINTR = B_TO_POSIX_ERROR!(B_INTERRUPTED); + enum EIO = B_TO_POSIX_ERROR!(B_IO_ERROR); + enum EBUSY = B_TO_POSIX_ERROR!(B_BUSY); + enum EFAULT = B_TO_POSIX_ERROR!(B_BAD_ADDRESS); + enum ETIMEDOUT = B_TO_POSIX_ERROR!(B_TIMED_OUT); + enum EAGAIN = B_TO_POSIX_ERROR!(B_WOULD_BLOCK) /* SysV compatibility */; + enum EWOULDBLOCK = B_TO_POSIX_ERROR!(B_WOULD_BLOCK) /* BSD compatibility */; + enum EBADF = B_TO_POSIX_ERROR!(B_FILE_ERROR); + enum EEXIST = B_TO_POSIX_ERROR!(B_FILE_EXISTS); + enum EINVAL = B_TO_POSIX_ERROR!(B_BAD_VALUE); + enum ENAMETOOLONG = B_TO_POSIX_ERROR!(B_NAME_TOO_LONG); + enum ENOENT = B_TO_POSIX_ERROR!(B_ENTRY_NOT_FOUND); + enum EPERM = B_TO_POSIX_ERROR!(B_NOT_ALLOWED); + enum ENOTDIR = B_TO_POSIX_ERROR!(B_NOT_A_DIRECTORY); + enum EISDIR = B_TO_POSIX_ERROR!(B_IS_A_DIRECTORY); + enum ENOTEMPTY = B_TO_POSIX_ERROR!(B_DIRECTORY_NOT_EMPTY); + enum ENOSPC = B_TO_POSIX_ERROR!(B_DEVICE_FULL); + enum EROFS = B_TO_POSIX_ERROR!(B_READ_ONLY_DEVICE); + enum EMFILE = B_TO_POSIX_ERROR!(B_NO_MORE_FDS); + enum EXDEV = B_TO_POSIX_ERROR!(B_CROSS_DEVICE_LINK); + enum ELOOP = B_TO_POSIX_ERROR!(B_LINK_LIMIT); + enum ENOEXEC = B_TO_POSIX_ERROR!(B_NOT_AN_EXECUTABLE); + enum EPIPE = B_TO_POSIX_ERROR!(B_BUSTED_PIPE); + + /* new error codes that can be mapped to POSIX errors */ + enum B_BUFFER_OVERFLOW = B_FROM_POSIX_ERROR!(EOVERFLOW); + enum B_TOO_MANY_ARGS = B_FROM_POSIX_ERROR!(E2BIG); + enum B_FILE_TOO_LARGE = B_FROM_POSIX_ERROR!(EFBIG); + enum B_RESULT_NOT_REPRESENTABLE = B_FROM_POSIX_ERROR!(ERANGE); + enum B_DEVICE_NOT_FOUND = B_FROM_POSIX_ERROR!(ENODEV); + enum B_NOT_SUPPORTED = B_FROM_POSIX_ERROR!(EOPNOTSUPP); + + /* Media Kit Errors */ + enum B_STREAM_NOT_FOUND = (B_MEDIA_ERROR_BASE + 0); + enum B_SERVER_NOT_FOUND = (B_MEDIA_ERROR_BASE + 1); + enum B_RESOURCE_NOT_FOUND = (B_MEDIA_ERROR_BASE + 2); + enum B_RESOURCE_UNAVAILABLE = (B_MEDIA_ERROR_BASE + 3); + enum B_BAD_SUBSCRIBER = (B_MEDIA_ERROR_BASE + 4); + enum B_SUBSCRIBER_NOT_ENTERED = (B_MEDIA_ERROR_BASE + 5); + enum B_BUFFER_NOT_AVAILABLE = (B_MEDIA_ERROR_BASE + 6); + enum B_LAST_BUFFER_ERROR = (B_MEDIA_ERROR_BASE + 7); + + enum B_MEDIA_SYSTEM_FAILURE = (B_MEDIA_ERROR_BASE + 100); + enum B_MEDIA_BAD_NODE = (B_MEDIA_ERROR_BASE + 101); + enum B_MEDIA_NODE_BUSY = (B_MEDIA_ERROR_BASE + 102); + enum B_MEDIA_BAD_FORMAT = (B_MEDIA_ERROR_BASE + 103); + enum B_MEDIA_BAD_BUFFER = (B_MEDIA_ERROR_BASE + 104); + enum B_MEDIA_TOO_MANY_NODES = (B_MEDIA_ERROR_BASE + 105); + enum B_MEDIA_TOO_MANY_BUFFERS = (B_MEDIA_ERROR_BASE + 106); + enum B_MEDIA_NODE_ALREADY_EXISTS = (B_MEDIA_ERROR_BASE + 107); + enum B_MEDIA_BUFFER_ALREADY_EXISTS = (B_MEDIA_ERROR_BASE + 108); + enum B_MEDIA_CANNOT_SEEK = (B_MEDIA_ERROR_BASE + 109); + enum B_MEDIA_CANNOT_CHANGE_RUN_MODE = (B_MEDIA_ERROR_BASE + 110); + enum B_MEDIA_APP_ALREADY_REGISTERED = (B_MEDIA_ERROR_BASE + 111); + enum B_MEDIA_APP_NOT_REGISTERED = (B_MEDIA_ERROR_BASE + 112); + enum B_MEDIA_CANNOT_RECLAIM_BUFFERS = (B_MEDIA_ERROR_BASE + 113); + enum B_MEDIA_BUFFERS_NOT_RECLAIMED = (B_MEDIA_ERROR_BASE + 114); + enum B_MEDIA_TIME_SOURCE_STOPPED = (B_MEDIA_ERROR_BASE + 115); + enum B_MEDIA_TIME_SOURCE_BUSY = (B_MEDIA_ERROR_BASE + 116); + enum B_MEDIA_BAD_SOURCE = (B_MEDIA_ERROR_BASE + 117); + enum B_MEDIA_BAD_DESTINATION = (B_MEDIA_ERROR_BASE + 118); + enum B_MEDIA_ALREADY_CONNECTED = (B_MEDIA_ERROR_BASE + 119); + enum B_MEDIA_NOT_CONNECTED = (B_MEDIA_ERROR_BASE + 120); + enum B_MEDIA_BAD_CLIP_FORMAT = (B_MEDIA_ERROR_BASE + 121); + enum B_MEDIA_ADDON_FAILED = (B_MEDIA_ERROR_BASE + 122); + enum B_MEDIA_ADDON_DISABLED = (B_MEDIA_ERROR_BASE + 123); + enum B_MEDIA_CHANGE_IN_PROGRESS = (B_MEDIA_ERROR_BASE + 124); + enum B_MEDIA_STALE_CHANGE_COUNT = (B_MEDIA_ERROR_BASE + 125); + enum B_MEDIA_ADDON_RESTRICTED = (B_MEDIA_ERROR_BASE + 126); + enum B_MEDIA_NO_HANDLER = (B_MEDIA_ERROR_BASE + 127); + enum B_MEDIA_DUPLICATE_FORMAT = (B_MEDIA_ERROR_BASE + 128); + enum B_MEDIA_REALTIME_DISABLED = (B_MEDIA_ERROR_BASE + 129); + enum B_MEDIA_REALTIME_UNAVAILABLE = (B_MEDIA_ERROR_BASE + 130); + + /* Mail Kit Errors */ + enum B_MAIL_NO_DAEMON = (B_MAIL_ERROR_BASE + 0); + enum B_MAIL_UNKNOWN_USER = (B_MAIL_ERROR_BASE + 1); + enum B_MAIL_WRONG_PASSWORD = (B_MAIL_ERROR_BASE + 2); + enum B_MAIL_UNKNOWN_HOST = (B_MAIL_ERROR_BASE + 3); + enum B_MAIL_ACCESS_ERROR = (B_MAIL_ERROR_BASE + 4); + enum B_MAIL_UNKNOWN_FIELD = (B_MAIL_ERROR_BASE + 5); + enum B_MAIL_NO_RECIPIENT = (B_MAIL_ERROR_BASE + 6); + enum B_MAIL_INVALID_MAIL = (B_MAIL_ERROR_BASE + 7); + + /* Printing Errors */ + enum B_NO_PRINT_SERVER = (B_PRINT_ERROR_BASE + 0); + + /* Device Kit Errors */ + enum B_DEV_INVALID_IOCTL = (B_DEVICE_ERROR_BASE + 0); + enum B_DEV_NO_MEMORY = (B_DEVICE_ERROR_BASE + 1); + enum B_DEV_BAD_DRIVE_NUM = (B_DEVICE_ERROR_BASE + 2); + enum B_DEV_NO_MEDIA = (B_DEVICE_ERROR_BASE + 3); + enum B_DEV_UNREADABLE = (B_DEVICE_ERROR_BASE + 4); + enum B_DEV_FORMAT_ERROR = (B_DEVICE_ERROR_BASE + 5); + enum B_DEV_TIMEOUT = (B_DEVICE_ERROR_BASE + 6); + enum B_DEV_RECALIBRATE_ERROR = (B_DEVICE_ERROR_BASE + 7); + enum B_DEV_SEEK_ERROR = (B_DEVICE_ERROR_BASE + 8); + enum B_DEV_ID_ERROR = (B_DEVICE_ERROR_BASE + 9); + enum B_DEV_READ_ERROR = (B_DEVICE_ERROR_BASE + 10); + enum B_DEV_WRITE_ERROR = (B_DEVICE_ERROR_BASE + 11); + enum B_DEV_NOT_READY = (B_DEVICE_ERROR_BASE + 12); + enum B_DEV_MEDIA_CHANGED = (B_DEVICE_ERROR_BASE + 13); + enum B_DEV_MEDIA_CHANGE_REQUESTED = (B_DEVICE_ERROR_BASE + 14); + enum B_DEV_RESOURCE_CONFLICT = (B_DEVICE_ERROR_BASE + 15); + enum B_DEV_CONFIGURATION_ERROR = (B_DEVICE_ERROR_BASE + 16); + enum B_DEV_DISABLED_BY_USER = (B_DEVICE_ERROR_BASE + 17); + enum B_DEV_DOOR_OPEN = (B_DEVICE_ERROR_BASE + 18); + + enum B_DEV_INVALID_PIPE = (B_DEVICE_ERROR_BASE + 19); + enum B_DEV_CRC_ERROR = (B_DEVICE_ERROR_BASE + 20); + enum B_DEV_STALLED = (B_DEVICE_ERROR_BASE + 21); + enum B_DEV_BAD_PID = (B_DEVICE_ERROR_BASE + 22); + enum B_DEV_UNEXPECTED_PID = (B_DEVICE_ERROR_BASE + 23); + enum B_DEV_DATA_OVERRUN = (B_DEVICE_ERROR_BASE + 24); + enum B_DEV_DATA_UNDERRUN = (B_DEVICE_ERROR_BASE + 25); + enum B_DEV_FIFO_OVERRUN = (B_DEVICE_ERROR_BASE + 26); + enum B_DEV_FIFO_UNDERRUN = (B_DEVICE_ERROR_BASE + 27); + enum B_DEV_PENDING = (B_DEVICE_ERROR_BASE + 28); + enum B_DEV_MULTIPLE_ERRORS = (B_DEVICE_ERROR_BASE + 29); + enum B_DEV_TOO_LATE = (B_DEVICE_ERROR_BASE + 30); + + /* Translation Kit Errors */ + enum B_TRANSLATION_BASE_ERROR = (B_TRANSLATION_ERROR_BASE + 0); + enum B_NO_TRANSLATOR = (B_TRANSLATION_ERROR_BASE + 1); + enum B_ILLEGAL_DATA = (B_TRANSLATION_ERROR_BASE + 2); +} +else version (WASI) +{ + enum EPERM = 1; + enum ENOENT = 2; + enum ESRCH = 3; + enum EINTR = 4; + enum EIO = 5; + enum ENXIO = 6; + enum E2BIG = 7; + enum ENOEXEC = 8; + enum EBADF = 9; + enum ECHILD = 10; + enum EAGAIN = 11; + enum ENOMEM = 12; + enum EACCES = 13; + enum EFAULT = 14; + enum ENOTBLK = 15; + enum EBUSY = 16; + enum EEXIST = 17; + enum EXDEV = 18; + enum ENODEV = 19; + enum ENOTDIR = 20; + enum EISDIR = 21; + enum EINVAL = 22; + enum ENFILE = 23; + enum EMFILE = 24; + enum ENOTTY = 25; + enum ETXTBSY = 26; + enum EFBIG = 27; + enum ENOSPC = 28; + enum ESPIPE = 29; + enum EROFS = 30; + enum EMLINK = 31; + enum EPIPE = 32; + enum EDOM = 33; + enum ERANGE = 34; + enum EDEADLK = 35; + enum ENAMETOOLONG = 36; + enum ENOLCK = 37; + enum ENOSYS = 38; + enum ENOTEMPTY = 39; + enum ELOOP = 40; + enum EWOULDBLOCK = EAGAIN; + enum ENOMSG = 42; + enum EIDRM = 43; + enum ECHRNG = 44; + enum EL2NSYNC = 45; + enum EL3HLT = 46; + enum EL3RST = 47; + enum ELNRNG = 48; + enum EUNATCH = 49; + enum ENOCSI = 50; + enum EL2HLT = 51; + enum EBADE = 52; + enum EBADR = 53; + enum EXFULL = 54; + enum ENOANO = 55; + enum EBADRQC = 56; + enum EBADSLT = 57; + enum EDEADLOCK = EDEADLK; + enum EBFONT = 59; + enum ENOSTR = 60; + enum ENODATA = 61; + enum ETIME = 62; + enum ENOSR = 63; + enum ENONET = 64; + enum ENOPKG = 65; + enum EREMOTE = 66; + enum ENOLINK = 67; + enum EADV = 68; + enum ESRMNT = 69; + enum ECOMM = 70; + enum EPROTO = 71; + enum EMULTIHOP = 72; + enum EDOTDOT = 73; + enum EBADMSG = 74; + enum EOVERFLOW = 75; + enum ENOTUNIQ = 76; + enum EBADFD = 77; + enum EREMCHG = 78; + enum ELIBACC = 79; + enum ELIBBAD = 80; + enum ELIBSCN = 81; + enum ELIBMAX = 82; + enum ELIBEXEC = 83; + enum EILSEQ = 84; + enum ERESTART = 85; + enum ESTRPIPE = 86; + enum EUSERS = 87; + enum ENOTSOCK = 88; + enum EDESTADDRREQ = 89; + enum EMSGSIZE = 90; + enum EPROTOTYPE = 91; + enum ENOPROTOOPT = 92; + enum EPROTONOSUPPORT = 93; + enum ESOCKTNOSUPPORT = 94; + enum EOPNOTSUPP = 95; + enum ENOTSUP = EOPNOTSUPP; + enum EPFNOSUPPORT = 96; + enum EAFNOSUPPORT = 97; + enum EADDRINUSE = 98; + enum EADDRNOTAVAIL = 99; + enum ENETDOWN = 100; + enum ENETUNREACH = 101; + enum ENETRESET = 102; + enum ECONNABORTED = 103; + enum ECONNRESET = 104; + enum ENOBUFS = 105; + enum EISCONN = 106; + enum ENOTCONN = 107; + enum ESHUTDOWN = 108; + enum ETOOMANYREFS = 109; + enum ETIMEDOUT = 110; + enum ECONNREFUSED = 111; + enum EHOSTDOWN = 112; + enum EHOSTUNREACH = 113; + enum EALREADY = 114; + enum EINPROGRESS = 115; + enum ESTALE = 116; + enum EUCLEAN = 117; + enum ENOTNAM = 118; + enum ENAVAIL = 119; + enum EISNAM = 120; + enum EREMOTEIO = 121; + enum EDQUOT = 122; + enum ENOMEDIUM = 123; + enum EMEDIUMTYPE = 124; + enum ECANCELED = 125; + enum ENOKEY = 126; + enum EKEYEXPIRED = 127; + enum EKEYREVOKED = 128; + enum EKEYREJECTED = 129; + enum EOWNERDEAD = 130; + enum ENOTRECOVERABLE = 131; + enum ERFKILL = 132; + enum EHWPOISON = 133; +} +else version (FreeStanding) +{ + // no errno on bare metal +} +else +{ + static assert(false, "Unsupported platform"); +} diff --git a/src/urt/internal/stdc/stdio.d b/src/urt/internal/stdc/stdio.d new file mode 100644 index 0000000..7aabfa3 --- /dev/null +++ b/src/urt/internal/stdc/stdio.d @@ -0,0 +1,111 @@ +// Minimal C stdio bindings - only what URT actually uses. +// FILE is opaque; we never dereference its fields. + +module urt.internal.stdc.stdio; + +struct FILE; + +extern(C) nothrow @nogc: + +size_t fread(scope void* ptr, size_t size, size_t nmemb, FILE* stream); +size_t fwrite(scope const void* ptr, size_t size, size_t nmemb, FILE* stream); +int fgetc(FILE* stream); +char* fgets(char* s, int n, FILE* stream); +int feof(FILE* stream); +int ferror(FILE* stream); +int fflush(FILE* stream); + +version (CRuntime_Microsoft) +{ + FILE* __acrt_iob_func(int hnd); + + FILE* stdin()() { return __acrt_iob_func(0); } + FILE* stdout()() { return __acrt_iob_func(1); } + FILE* stderr()() { return __acrt_iob_func(2); } +} +else version (CRuntime_Glibc) +{ + extern __gshared FILE* stdin; + extern __gshared FILE* stdout; + extern __gshared FILE* stderr; +} +else version (Darwin) +{ + private extern __gshared FILE* __stdinp; + private extern __gshared FILE* __stdoutp; + private extern __gshared FILE* __stderrp; + + alias stdin = __stdinp; + alias stdout = __stdoutp; + alias stderr = __stderrp; +} +else version (FreeBSD) +{ + private extern __gshared FILE* __stdinp; + private extern __gshared FILE* __stdoutp; + private extern __gshared FILE* __stderrp; + + alias stdin = __stdinp; + alias stdout = __stdoutp; + alias stderr = __stderrp; +} +else version (DragonFlyBSD) +{ + private extern __gshared FILE* __stdinp; + private extern __gshared FILE* __stdoutp; + private extern __gshared FILE* __stderrp; + + alias stdin = __stdinp; + alias stdout = __stdoutp; + alias stderr = __stderrp; +} +else version (CRuntime_Musl) +{ + extern __gshared FILE* stdin; + extern __gshared FILE* stdout; + extern __gshared FILE* stderr; +} +else version (CRuntime_UClibc) +{ + extern __gshared FILE* stdin; + extern __gshared FILE* stdout; + extern __gshared FILE* stderr; +} +else version (CRuntime_Bionic) +{ + private extern __gshared FILE[3] __sF; + + @property FILE* stdin()() { return &__sF[0]; } + @property FILE* stdout()() { return &__sF[1]; } + @property FILE* stderr()() { return &__sF[2]; } +} +else version (CRuntime_Newlib) +{ + private struct _reent + { + int _errno; + FILE* _stdin; + FILE* _stdout; + FILE* _stderr; + } + + private extern(C) _reent* __getreent(); + + @property FILE* stdin()() { return __getreent()._stdin; } + @property FILE* stdout()() { return __getreent()._stdout; } + @property FILE* stderr()() { return __getreent()._stderr; } +} +else version (WASI) +{ + extern __gshared FILE* stdin; + extern __gshared FILE* stdout; + extern __gshared FILE* stderr; +} +else version (FreeStanding) +{ + // no stdio streams - io.d uses UART directly +} +else +{ + static assert(false, "Unsupported platform"); +} diff --git a/src/urt/internal/stdc/stdlib.d b/src/urt/internal/stdc/stdlib.d new file mode 100644 index 0000000..960d32e --- /dev/null +++ b/src/urt/internal/stdc/stdlib.d @@ -0,0 +1,12 @@ +// Minimal C stdlib bindings - only what URT actually uses. + +module urt.internal.stdc.stdlib; + +extern(C) nothrow @nogc: + +noreturn abort() @safe; +noreturn exit(int status); + +pure char* gcvt(double value, int ndigit, char* buf); +version (Windows) + pure int _gcvt_s(const char* buffer, size_t size_in_bytes, double value, int digits); diff --git a/src/urt/internal/sys/freertos/package.d b/src/urt/internal/sys/freertos/package.d new file mode 100644 index 0000000..3a7fe14 --- /dev/null +++ b/src/urt/internal/sys/freertos/package.d @@ -0,0 +1,108 @@ +module urt.internal.sys.freertos; + +// Config assumptions (true for ESP-IDF and Bouffalo SDK): +// - configUSE_16_BIT_TICKS = 0 (TickType_t = uint32_t) +// - portBASE_TYPE size = 4 (BaseType_t = int32_t) +// If a future port violates these, this module must be revised. + +version (FreeRTOS): +nothrow @nogc: + + +alias TickType_t = uint; +alias BaseType_t = int; +alias UBaseType_t = uint; + +alias QueueHandle_t = void*; +alias SemaphoreHandle_t = void*; +alias TaskHandle_t = void*; +alias EventGroupHandle_t = void*; +alias EventBits_t = TickType_t; + +enum uint portMUX_FREE_VAL = 0xB33FFFFF; + +// SMP-aware spinlock used by portENTER_CRITICAL on ESP-IDF FreeRTOS. +// Default-init (zero owner is wrong) is patched by giving owner a default +// value of portMUX_FREE_VAL -- so a zero-initialised portMUX_TYPE is in +// the "unlocked" state, no explicit constructor needed. +// (Non-debug layout; CONFIG_FREERTOS_PORTMUX_DEBUG adds two more fields +// we don't need.) +struct portMUX_TYPE +{ + uint owner = portMUX_FREE_VAL; + uint count; +} + +alias TaskFunction_t = extern(C) void function(void*) nothrow @nogc; + +enum eNotifyAction : int +{ + eNoAction = 0, + eSetBits, + eIncrement, + eSetValueWithOverwrite, + eSetValueWithoutOverwrite, +} + +enum BaseType_t pdPASS = 1; +enum BaseType_t pdFAIL = 0; +enum BaseType_t pdTRUE = 1; +enum BaseType_t pdFALSE = 0; + +enum TickType_t portMAX_DELAY = TickType_t.max; +enum ubyte queueQUEUE_TYPE_MUTEX = 1; +enum BaseType_t queueSEND_TO_BACK = 0; +enum TickType_t semGIVE_BLOCK_TIME = 0; +enum UBaseType_t tskDEFAULT_INDEX_TO_NOTIFY = 0; + + +extern(C) +{ + // queue / semaphore (queue.c) + QueueHandle_t xQueueCreateMutex(ubyte ucQueueType); + QueueHandle_t xQueueCreateCountingSemaphore(UBaseType_t uxMaxCount, UBaseType_t uxInitialCount); + BaseType_t xQueueSemaphoreTake(QueueHandle_t xQueue, TickType_t xTicksToWait); + BaseType_t xQueueGenericSend(QueueHandle_t xQueue, const(void)* pvItemToQueue, TickType_t xTicksToWait, BaseType_t xCopyPosition); + void vQueueDelete(QueueHandle_t xQueue); + + BaseType_t xTaskCreatePinnedToCore(TaskFunction_t pxTaskCode, const(char)* pcName, uint usStackDepth, void* pvParameters, UBaseType_t uxPriority, TaskHandle_t* pxCreatedTask, BaseType_t xCoreID); + void vTaskDelete(TaskHandle_t xTaskToDelete); + TaskHandle_t xTaskGetCurrentTaskHandle(); + UBaseType_t uxTaskPriorityGet(TaskHandle_t xTask); + + // task notifications -- generic forms (the macros xTaskNotifyGive and + // ulTaskNotifyTake expand to these with default index/value args). + BaseType_t xTaskGenericNotify(TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint ulValue, eNotifyAction eAction, uint* pulPreviousNotificationValue); + uint ulTaskGenericNotifyTake(UBaseType_t uxIndexToWaitOn, BaseType_t xClearCountOnExit, TickType_t xTicksToWait); + + // critical sections (portmacro). portENTER_CRITICAL(mux) on ESP-IDF + // expands ultimately to vPortEnterCritical(mux); same for exit. + void vPortEnterCritical(portMUX_TYPE* mux); + void vPortExitCritical(portMUX_TYPE* mux); + + // event groups (event_groups.c). Requires configUSE_EVENT_GROUPS=1. + EventGroupHandle_t xEventGroupCreate(); + void vEventGroupDelete(EventGroupHandle_t xEventGroup); + EventBits_t xEventGroupSetBits(EventGroupHandle_t xEventGroup, EventBits_t uxBitsToSet); + EventBits_t xEventGroupClearBits(EventGroupHandle_t xEventGroup, EventBits_t uxBitsToClear); + EventBits_t xEventGroupGetBitsFromISR(EventGroupHandle_t xEventGroup); + EventBits_t xEventGroupWaitBits(EventGroupHandle_t xEventGroup, EventBits_t uxBitsToWaitFor, BaseType_t xClearOnExit, BaseType_t xWaitForAllBits, TickType_t xTicksToWait); +} + +pragma(inline, true) +BaseType_t xTaskNotifyGive(TaskHandle_t task) + => xTaskGenericNotify(task, tskDEFAULT_INDEX_TO_NOTIFY, 0, eNotifyAction.eIncrement, null); + +pragma(inline, true) +uint ulTaskNotifyTake(BaseType_t clear_on_exit, TickType_t ticks) + => ulTaskGenericNotifyTake(tskDEFAULT_INDEX_TO_NOTIFY, clear_on_exit, ticks); + +enum BaseType_t tskNO_AFFINITY = -1; + +pragma(inline, true) +BaseType_t xTaskCreate(TaskFunction_t code, const(char)* name, uint stack_depth, void* params, UBaseType_t priority, TaskHandle_t* task) + => xTaskCreatePinnedToCore(code, name, stack_depth, params, priority, task, tskNO_AFFINITY); + +pragma(inline, true) +EventBits_t xEventGroupGetBits(EventGroupHandle_t group) + => xEventGroupGetBitsFromISR(group); diff --git a/src/urt/internal/sys/posix/package.d b/src/urt/internal/sys/posix/package.d new file mode 100644 index 0000000..c9b2ef8 --- /dev/null +++ b/src/urt/internal/sys/posix/package.d @@ -0,0 +1,336 @@ +// Minimal POSIX bindings — only what URT actually uses. +// Replaces imports of core.sys.posix.* to avoid druntime's transitive +// core.stdc.stdio dependency (stdint → wchar_ → stdio). + +module urt.internal.sys.posix; + +version (Posix): +extern(C) nothrow @nogc: + +// ── types ── + +alias off_t = long; +alias mode_t = uint; +alias ssize_t = ptrdiff_t; +alias time_t = long; +alias clockid_t = int; +alias blkcnt_t = long; +alias dev_t = ulong; +alias ino_t = ulong; +alias uid_t = uint; +alias gid_t = uint; + +version (X86) +{ + alias blksize_t = int; + alias nlink_t = uint; +} +else version (X86_64) +{ + alias blksize_t = long; + alias nlink_t = ulong; +} +else version (AArch64) +{ + alias blksize_t = int; + alias nlink_t = uint; +} +else version (ARM) +{ + alias blksize_t = int; + alias nlink_t = uint; +} +else version (RISCV32) +{ + alias blksize_t = int; + alias nlink_t = uint; +} +else version (RISCV64) +{ + alias blksize_t = int; + alias nlink_t = uint; +} +else + static assert(false, "POSIX type aliases not defined for this arch"); + +// ── fcntl ── + +enum O_RDONLY = 0x0; +enum O_WRONLY = 0x1; +enum O_RDWR = 0x2; +enum O_CREAT = 0x40; +enum O_TRUNC = 0x200; +enum O_APPEND = 0x400; +enum O_NOCTTY = 0x100; +enum O_NDELAY = 0x800; // same as O_NONBLOCK +enum O_CLOEXEC = 0x80000; + +version (linux) + enum O_DIRECT = 0x4000; + +version (X86) +{ + // glibc x86: largefile64 redirects + int open64(scope const char* pathname, int flags, ...); + alias open = open64; +} +else + int open(scope const char* pathname, int flags, ...); +int fcntl(int fd, int cmd, ...); + +version (Darwin) +{ + enum F_NOCACHE = 48; + enum F_GETPATH = 50; +} + +enum F_GETFL = 3; +enum F_SETFL = 4; +enum O_NONBLOCK = 0x800; + +// ── unistd ── + +int close(int fd); +int unlink(scope const char* pathname); +ssize_t read(int fd, void* buf, size_t count); +ssize_t write(int fd, const void* buf, size_t count); +version (X86) +{ + off_t lseek64(int fd, off_t offset, int whence); + alias lseek = lseek64; + int ftruncate64(int fd, off_t length); + alias ftruncate = ftruncate64; +} +else +{ + off_t lseek(int fd, off_t offset, int whence); + int ftruncate(int fd, off_t length); +} +ssize_t readlink(scope const char* path, char* buf, size_t bufsiz); +version (X86) +{ + ssize_t pread64(int fd, void* buf, size_t count, off_t offset); + alias pread = pread64; + ssize_t pwrite64(int fd, const void* buf, size_t count, off_t offset); + alias pwrite = pwrite64; +} +else +{ + ssize_t pread(int fd, void* buf, size_t count, off_t offset); + ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset); +} +int fsync(int fd); +int usleep(uint usec); +long sysconf(int name); +int gethostname(char* name, size_t len); + +enum _SC_PAGE_SIZE = 30; +enum _SC_PHYS_PAGES = 85; + +enum STDIN_FILENO = 0; +enum STDOUT_FILENO = 1; +enum STDERR_FILENO = 2; +int isatty(int fd); + +// ── sys/stat ── + +version (X86_64) +{ + // x86_64 is unique: nlink before mode, long blksize/blocks, long[3] tail + struct stat_t + { + dev_t st_dev; + ino_t st_ino; + nlink_t st_nlink; + mode_t st_mode; + uid_t st_uid; + gid_t st_gid; + uint __pad0; + dev_t st_rdev; + off_t st_size; + long st_blksize; + long st_blocks; + timespec st_atim; + timespec st_mtim; + timespec st_ctim; + long[3] __unused; + } + static assert(stat_t.sizeof == 144); +} +else version (X86) version = OldStatLayout; +else version (ARM) version = OldStatLayout; +else version (AArch64) version = NewStatLayout; +else version (RISCV32) version = NewStatLayout; +else version (RISCV64) version = NewStatLayout; +else + static assert(false, "stat_t not defined for this arch"); + +version (NewStatLayout) +{ + // AArch64, RISCV32, RISCV64: new kernel stat layout + struct stat_t + { + dev_t st_dev; + ino_t st_ino; + mode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + dev_t st_rdev; + ulong __pad1; + off_t st_size; + blksize_t st_blksize; + int __pad2; + blkcnt_t st_blocks; + timespec st_atim; + timespec st_mtim; + timespec st_ctim; + int[2] __unused; + } + static assert(stat_t.sizeof == 128); +} + +version (OldStatLayout) +{ + // X86, ARM: old glibc stat layout with __USE_FILE_OFFSET64 + private struct __timespec32 { int tv_sec; int tv_nsec; } + struct stat_t + { + dev_t st_dev; + ushort __pad1; + uint __st_ino; + mode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + dev_t st_rdev; + ushort __pad2; + off_t st_size; + blksize_t st_blksize; + blkcnt_t st_blocks; + version (CRuntime_Musl) + { + __timespec32 __st_atim32; + __timespec32 __st_mtim32; + __timespec32 __st_ctim32; + } + ino_t st_ino; + timespec st_atim; + timespec st_mtim; + timespec st_ctim; + } +} + +bool S_ISREG(mode_t mode) + => (mode & 0xF000) == 0x8000; + +version (X86) +{ + int stat64(scope const char* pathname, stat_t* buf); + alias stat = stat64; + int fstat64(int fd, stat_t* buf); + alias fstat = fstat64; + int mkstemp64(char* tmpl); + alias mkstemp = mkstemp64; +} +else +{ + int stat(scope const char* pathname, stat_t* buf); + int fstat(int fd, stat_t* buf); + int mkstemp(char* tmpl); +} +int mkdir(scope const char* pathname, mode_t mode); +pure int posix_memalign(void** memptr, size_t alignment, size_t size); + +// ── time ── + +struct timespec +{ + time_t tv_sec; + long tv_nsec; +} + +struct tm +{ + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + long tm_gmtoff; + const(char)* tm_zone; +} + +enum CLOCK_REALTIME = 0; +enum CLOCK_MONOTONIC = 1; + +int clock_gettime(clockid_t clk_id, timespec* tp); +int clock_settime(clockid_t clk_id, const timespec* tp); +tm* gmtime_r(scope const time_t* timep, tm* result); +time_t mktime(tm* tp); + +// ── sys/mman ── + +enum PROT_READ = 0x1; +enum MAP_PRIVATE = 0x02; +enum MAP_FAILED = cast(void*)-1; + +void* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset); +int munmap(void* addr, size_t length); + +// ── dlfcn ── + +struct Dl_info +{ + const(char)* dli_fname; + void* dli_fbase; + const(char)* dli_sname; + void* dli_saddr; +} + +int dladdr(scope const void* addr, Dl_info* info); + +// ── netinet/in ── +// in6_addr and sockaddr_in6 are provided by ImportC (urt.internal.os) +// on platforms that use it. Defined here as fallback for others. + +version (none) +{ + struct in6_addr + { + ubyte[16] s6_addr; + } + + struct sockaddr_in6 + { + ushort sin6_family; + ushort sin6_port; + uint sin6_flowinfo; + in6_addr sin6_addr; + uint sin6_scope_id; + } +} + +// ── poll ── + +struct pollfd +{ + int fd; + short events; + short revents; +} + +enum POLLIN = 0x001; +enum POLLPRI = 0x002; +enum POLLOUT = 0x004; +enum POLLERR = 0x008; +enum POLLHUP = 0x010; +enum POLLNVAL = 0x020; +enum POLLRDNORM = 0x040; +enum POLLWRNORM = 0x100; + +int poll(pollfd* fds, size_t nfds, int timeout); diff --git a/src/urt/internal/sys/posix/termios.d b/src/urt/internal/sys/posix/termios.d new file mode 100644 index 0000000..c322114 --- /dev/null +++ b/src/urt/internal/sys/posix/termios.d @@ -0,0 +1,107 @@ +// Minimal termios bindings for Linux. + +module urt.internal.sys.posix.termios; + +version (linux): +extern(C) nothrow @nogc: + +alias cc_t = ubyte; +alias speed_t = uint; +alias tcflag_t = uint; + +enum NCCS = 32; + +struct termios +{ + tcflag_t c_iflag; + tcflag_t c_oflag; + tcflag_t c_lflag; + tcflag_t c_cflag; + cc_t c_line; + cc_t[NCCS] c_cc; + speed_t c_ispeed; + speed_t c_ospeed; +} + +// c_iflag +enum IGNBRK = 0x01; +enum BRKINT = 0x02; +enum PARMRK = 0x08; +enum ISTRIP = 0x20; +enum INLCR = 0x40; +enum IGNCR = 0x80; +enum ICRNL = 0x100; +enum IXON = 0x400; +enum IXOFF = 0x1000; +enum IXANY = 0x800; + +// c_oflag +enum OPOST = 0x01; +enum ONLCR = 0x04; + +// c_cflag +enum CSIZE = 0x30; +enum CS5 = 0x00; +enum CS6 = 0x10; +enum CS7 = 0x20; +enum CS8 = 0x30; +enum CSTOPB = 0x40; +enum CREAD = 0x80; +enum PARENB = 0x100; +enum PARODD = 0x200; +enum CLOCAL = 0x800; +enum CRTSCTS = 0x80000000; + +// c_lflag +enum ISIG = 0x01; +enum ICANON = 0x02; +enum ECHO = 0x08; +enum ECHOE = 0x10; +enum ECHONL = 0x40; +enum IEXTEN = 0x8000; + +// c_cc indices +enum VMIN = 6; +enum VTIME = 5; + +// tcsetattr actions +enum TCSANOW = 0; +enum TCSAFLUSH = 2; + +// tcflush queue selectors +enum TCIFLUSH = 0; +enum TCOFLUSH = 1; +enum TCIOFLUSH = 2; + +// baud rates +enum B0 = 0x0; +enum B50 = 0x1; +enum B75 = 0x2; +enum B110 = 0x3; +enum B134 = 0x4; +enum B150 = 0x5; +enum B200 = 0x6; +enum B300 = 0x7; +enum B600 = 0x8; +enum B1200 = 0x9; +enum B1800 = 0xA; +enum B2400 = 0xB; +enum B4800 = 0xC; +enum B9600 = 0xD; +enum B19200 = 0xE; +enum B38400 = 0xF; +enum B57600 = 0x1001; +enum B115200 = 0x1002; +enum B230400 = 0x1003; +enum B460800 = 0x1004; +enum B500000 = 0x1005; +enum B576000 = 0x1006; +enum B921600 = 0x1007; + +int tcgetattr(int fd, termios* t); +int tcsetattr(int fd, int action, const termios* t); +int tcflush(int fd, int queue); +speed_t cfgetispeed(const termios* t); +speed_t cfgetospeed(const termios* t); +int cfsetispeed(termios* t, speed_t speed); +int cfsetospeed(termios* t, speed_t speed); diff --git a/src/urt/internal/sys/windows/basetsd.d b/src/urt/internal/sys/windows/basetsd.d new file mode 100644 index 0000000..b881b5a --- /dev/null +++ b/src/urt/internal/sys/windows/basetsd.d @@ -0,0 +1,141 @@ +/** + * Windows API header module + * + * Translated from MinGW API for MS-Windows 3.12 + * + * Authors: Stewart Gordon + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(DRUNTIMESRC core/sys/windows/_basetsd.d) + */ +module urt.internal.sys.windows.basetsd; +version (Windows): + +// [SnakE 2009-02-23] Moved HANDLE definition here from winnt.d to avoid +// 'forwatd template reference' to CPtr from winnt.d caused by a circular +// import. +alias HANDLE = void*; + +alias HANDLE* PHANDLE, LPHANDLE; + +// helper for aligned structs +// alignVal 0 means the default align. +// _alignSpec as parameter does not pollute namespace. +package mixin template AlignedStr(int alignVal, string name, string memberlist, + string _alignSpec = !alignVal ? "align" : "align("~alignVal.stringof~")" ) +{ + mixin( _alignSpec ~ " struct " ~ name ~" { " ~ _alignSpec ~":"~ memberlist~" }" ); +} + +version (CoreUnittest) { + private mixin AlignedStr!(16, "_Test_Aligned_Str", q{char a; char b;}); + private mixin AlignedStr!(0, "_Test_NoAligned_Str", q{char a; char b;}); +} + +version (Win64) { + alias long __int3264; +enum ulong ADDRESS_TAG_BIT = 0x40000000000; + + alias long INT_PTR, LONG_PTR; + alias long* PINT_PTR, PLONG_PTR; + alias ulong UINT_PTR, ULONG_PTR, HANDLE_PTR; + alias ulong* PUINT_PTR, PULONG_PTR; + alias int HALF_PTR; + alias int* PHALF_PTR; + alias uint UHALF_PTR; + alias uint* PUHALF_PTR; + + uint HandleToULong()(void* h) { return(cast(uint) cast(ULONG_PTR) h); } + int HandleToLong()(void* h) { return(cast(int) cast(LONG_PTR) h); } + void* ULongToHandle()(uint h) { return(cast(void*) cast(UINT_PTR) h); } + void* LongToHandle()(int h) { return(cast(void*) cast(INT_PTR) h); } + uint PtrToUlong()(void* p) { return(cast(uint) cast(ULONG_PTR) p); } + uint PtrToUint()(void* p) { return(cast(uint) cast(UINT_PTR) p); } + ushort PtrToUshort()(void* p) { return(cast(ushort) cast(uint) cast(ULONG_PTR) p); } + int PtrToLong()(void* p) { return(cast(int) cast(LONG_PTR) p); } + int PtrToInt()(void* p) { return(cast(int) cast(INT_PTR) p); } + short PtrToShort()(void* p) { return(cast(short) cast(int) cast(LONG_PTR) p); } + void* IntToPtr()(int i) { return(cast(void*) cast(INT_PTR) i); } + void* UIntToPtr()(uint ui) { return(cast(void*) cast(UINT_PTR) ui); } + void* LongToPtr()(int l) { return(cast(void*) cast(LONG_PTR) l); } + void* ULongToPtr()(uint ul) { return(cast(void*) cast(ULONG_PTR) ul); } + +} else { + alias int __int3264; +enum uint ADDRESS_TAG_BIT = 0x80000000; + + alias int INT_PTR, LONG_PTR; + alias int* PINT_PTR, PLONG_PTR; + alias uint UINT_PTR, ULONG_PTR, HANDLE_PTR; + alias uint* PUINT_PTR, PULONG_PTR; + alias short HALF_PTR; + alias short* PHALF_PTR; + alias ushort UHALF_PTR; + alias ushort* PUHALF_PTR; + + uint HandleToUlong()(HANDLE h) { return cast(uint) h; } + int HandleToLong()(HANDLE h) { return cast(int) h; } + HANDLE LongToHandle()(LONG_PTR h) { return cast(HANDLE)h; } + uint PtrToUlong(const(void)* p) { return cast(uint) p; } + uint PtrToUint(const(void)* p) { return cast(uint) p; } + int PtrToInt(const(void)* p) { return cast(int) p; } + ushort PtrToUshort(const(void)* p) { return cast(ushort) p; } + short PtrToShort(const(void)* p) { return cast(short) p; } + void* IntToPtr()(int i) { return cast(void*) i; } + void* UIntToPtr()(uint ui) { return cast(void*) ui; } + alias IntToPtr LongToPtr; + alias UIntToPtr ULongToPtr; +} + +alias UIntToPtr UintToPtr, UlongToPtr; + +enum : UINT_PTR { + MAXUINT_PTR = UINT_PTR.max +} + +enum : INT_PTR { + MAXINT_PTR = INT_PTR.max, + MININT_PTR = INT_PTR.min +} + +enum : ULONG_PTR { + MAXULONG_PTR = ULONG_PTR.max +} + +enum : LONG_PTR { + MAXLONG_PTR = LONG_PTR.max, + MINLONG_PTR = LONG_PTR.min +} + +enum : UHALF_PTR { + MAXUHALF_PTR = UHALF_PTR.max +} + +enum : HALF_PTR { + MAXHALF_PTR = HALF_PTR.max, + MINHALF_PTR = HALF_PTR.min +} + +alias byte INT8; +alias byte* PINT8; +alias ubyte UINT8; +alias ubyte* PUINT8; + +alias short INT16; +alias short* PINT16; +alias ushort UINT16; +alias ushort* PUINT16; + +alias int LONG32, INT32; +alias int* PLONG32, PINT32; +alias uint ULONG32, DWORD32, UINT32; +alias uint* PULONG32, PDWORD32, PUINT32; + +alias ULONG_PTR SIZE_T, DWORD_PTR; +alias ULONG_PTR* PSIZE_T, PDWORD_PTR; +alias LONG_PTR SSIZE_T; +alias LONG_PTR* PSSIZE_T; + +alias long LONG64, INT64; +alias long* PLONG64, PINT64; +alias ulong ULONG64, DWORD64, UINT64; +alias ulong* PULONG64, PDWORD64, PUINT64; diff --git a/src/urt/internal/sys/windows/basetyps.d b/src/urt/internal/sys/windows/basetyps.d new file mode 100644 index 0000000..d6cee67 --- /dev/null +++ b/src/urt/internal/sys/windows/basetyps.d @@ -0,0 +1,27 @@ +/** + * Windows API header module + * + * Translated from MinGW API for MS-Windows 3.10 + * + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(DRUNTIMESRC core/sys/windows/_basetyps.d) + */ +module urt.internal.sys.windows.basetyps; +version (Windows): + +import urt.internal.sys.windows.windef, urt.internal.sys.windows.basetsd; + +align(1) struct GUID { // size is 16 + align(1): + DWORD Data1; + WORD Data2; + WORD Data3; + BYTE[8] Data4; +} +alias GUID UUID, /*IID, CLSID, */FMTID, uuid_t; +alias IID = const(GUID); +alias CLSID = const(GUID); + +alias GUID* LPGUID, LPCLSID, LPIID; +alias const(GUID)* LPCGUID, REFGUID, REFIID, REFCLSID, REFFMTID; +alias uint error_status_t, PROPID; diff --git a/src/urt/internal/sys/windows/ntdef.d b/src/urt/internal/sys/windows/ntdef.d new file mode 100644 index 0000000..a80762d --- /dev/null +++ b/src/urt/internal/sys/windows/ntdef.d @@ -0,0 +1,85 @@ +/** + * Windows API header module + * + * Translated from MinGW Windows headers + * + * Authors: Stewart Gordon + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(DRUNTIMESRC core/sys/windows/_ntdef.d) + */ +module urt.internal.sys.windows.ntdef; +version (Windows): + +import urt.internal.sys.windows.basetsd, urt.internal.sys.windows.subauth, urt.internal.sys.windows.windef, urt.internal.sys.windows.winnt; + +enum uint + OBJ_INHERIT = 0x0002, + OBJ_PERMANENT = 0x0010, + OBJ_EXCLUSIVE = 0x0020, + OBJ_CASE_INSENSITIVE = 0x0040, + OBJ_OPENIF = 0x0080, + OBJ_OPENLINK = 0x0100, + OBJ_VALID_ATTRIBUTES = 0x01F2; + +void InitializeObjectAttributes(OBJECT_ATTRIBUTES* p, UNICODE_STRING* n, + uint a, HANDLE r, void* s) { + with (*p) { + Length = OBJECT_ATTRIBUTES.sizeof; + RootDirectory = r; + Attributes = a; + ObjectName = n; + SecurityDescriptor = s; + SecurityQualityOfService = null; + } +} + +pragma(inline, true) @safe pure nothrow @nogc { + bool NT_SUCCESS()(NTSTATUS Status) { return Status >= 0; } + bool NT_INFORMATION()(NTSTATUS Status) { return ((cast(ULONG) Status) >> 30) == 1; } + bool NT_WARNING()(NTSTATUS Status) { return ((cast(ULONG) Status) >> 30) == 2; } + bool NT_ERROR()(NTSTATUS Status) { return ((cast(ULONG) Status) >> 30) == 3; } +} + +/* In MinGW, NTSTATUS, UNICODE_STRING, STRING and their associated pointer + * type aliases are defined in ntdef.h, ntsecapi.h and subauth.h, each of + * which checks that none of the others is already included. + */ +alias int NTSTATUS; +alias int* PNTSTATUS; + +struct UNICODE_STRING { + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; +} +alias UNICODE_STRING* PUNICODE_STRING; +alias const(UNICODE_STRING)* PCUNICODE_STRING; + +struct STRING { + USHORT Length; + USHORT MaximumLength; + PCHAR Buffer; +} +alias STRING ANSI_STRING, OEM_STRING; +alias STRING* PSTRING, PANSI_STRING, POEM_STRING; + +alias LARGE_INTEGER PHYSICAL_ADDRESS; +alias LARGE_INTEGER* PPHYSICAL_ADDRESS; + +enum SECTION_INHERIT { + ViewShare = 1, + ViewUnmap +} + +/* In MinGW, this is defined in ntdef.h and ntsecapi.h, each of which checks + * that the other isn't already included. + */ +struct OBJECT_ATTRIBUTES { + ULONG Length = OBJECT_ATTRIBUTES.sizeof; + HANDLE RootDirectory; + PUNICODE_STRING ObjectName; + ULONG Attributes; + PVOID SecurityDescriptor; + PVOID SecurityQualityOfService; +} +alias OBJECT_ATTRIBUTES* POBJECT_ATTRIBUTES; diff --git a/src/urt/internal/sys/windows/ntsecapi.d b/src/urt/internal/sys/windows/ntsecapi.d new file mode 100644 index 0000000..bf372bf --- /dev/null +++ b/src/urt/internal/sys/windows/ntsecapi.d @@ -0,0 +1,796 @@ +/** + * Windows API header module + * + * Translated from MinGW Windows headers + * + * Authors: Stewart Gordon + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(DRUNTIMESRC core/sys/windows/_ntsecapi.d) + */ +module urt.internal.sys.windows.ntsecapi; +version (Windows): +pragma(lib, "advapi32"); + +version (ANSI) {} else version = Unicode; + +private import + urt.internal.sys.windows.basetyps, urt.internal.sys.windows.ntdef, urt.internal.sys.windows.windef, urt.internal.sys.windows.winnt, urt.internal.sys.windows.w32api; + +// FIXME: check types and grouping of constants +// FIXME: check Windows version support + +enum KERB_WRAP_NO_ENCRYPT = 0x80000001; + +enum LOGON_GUEST = 0x00000001; +enum LOGON_NOENCRYPTION = 0x00000002; +enum LOGON_CACHED_ACCOUNT = 0x00000004; +enum LOGON_USED_LM_PASSWORD = 0x00000008; +enum LOGON_EXTRA_SIDS = 0x00000020; +enum LOGON_SUBAUTH_SESSION_KEY = 0x00000040; +enum LOGON_SERVER_TRUST_ACCOUNT = 0x00000080; +enum LOGON_NTLMV2_ENABLED = 0x00000100; +enum LOGON_RESOURCE_GROUPS = 0x00000200; +enum LOGON_PROFILE_PATH_RETURNED = 0x00000400; +enum LOGON_GRACE_LOGON = 0x01000000; + +enum { + LSA_MODE_PASSWORD_PROTECTED = 1, + LSA_MODE_INDIVIDUAL_ACCOUNTS, + LSA_MODE_MANDATORY_ACCESS, + LSA_MODE_LOG_FULL +} + +bool LSA_SUCCESS()(int x) { return x >= 0; } + +/* TOTHINKABOUT: These constants don't have ANSI/Unicode versioned + * aliases. Should we merge them anyway? + */ +const char[] MICROSOFT_KERBEROS_NAME_A = "Kerberos"; +const wchar[] MICROSOFT_KERBEROS_NAME_W = "Kerberos"; +const char[] MSV1_0_PACKAGE_NAME = "MICROSOFT_AUTHENTICATION_PACKAGE_V1_0"; +const wchar[] MSV1_0_PACKAGE_NAMEW = "MICROSOFT_AUTHENTICATION_PACKAGE_V1_0"; + +enum MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT = 32; +enum MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT = 2048; +enum MSV1_0_CLEARTEXT_PASSWORD_ALLOWED = 2; +enum MSV1_0_CRED_LM_PRESENT = 1; +enum MSV1_0_CRED_NT_PRESENT = 2; +enum MSV1_0_CRED_VERSION = 0; +enum MSV1_0_DONT_TRY_GUEST_ACCOUNT = 16; +enum MSV1_0_MAX_NTLM3_LIFE = 1800; +enum MSV1_0_MAX_AVL_SIZE = 64000; +enum MSV1_0_MNS_LOGON = 16777216; + +enum size_t + MSV1_0_CHALLENGE_LENGTH = 8, + MSV1_0_LANMAN_SESSION_KEY_LENGTH = 8, + MSV1_0_NTLM3_RESPONSE_LENGTH = 16, + MSV1_0_NTLM3_OWF_LENGTH = 16, + MSV1_0_NTLM3_INPUT_LENGTH = MSV1_0_NTLM3_RESPONSE.sizeof + - MSV1_0_NTLM3_RESPONSE_LENGTH, + MSV1_0_OWF_PASSWORD_LENGTH = 16, + MSV1_0_PACKAGE_NAMEW_LENGTH = MSV1_0_PACKAGE_NAMEW.sizeof + - WCHAR.sizeof; + +enum MSV1_0_RETURN_USER_PARAMETERS = 8; +enum MSV1_0_RETURN_PASSWORD_EXPIRY = 64; +enum MSV1_0_RETURN_PROFILE_PATH = 512; +enum MSV1_0_SUBAUTHENTICATION_DLL_EX = 1048576; +enum MSV1_0_SUBAUTHENTICATION_DLL = 0xff000000; +enum MSV1_0_SUBAUTHENTICATION_DLL_SHIFT = 24; +enum MSV1_0_SUBAUTHENTICATION_DLL_RAS = 2; +enum MSV1_0_SUBAUTHENTICATION_DLL_IIS = 132; +enum MSV1_0_SUBAUTHENTICATION_FLAGS = 0xff000000; +enum MSV1_0_TRY_GUEST_ACCOUNT_ONLY = 256; +enum MSV1_0_TRY_SPECIFIED_DOMAIN_ONLY = 1024; +enum MSV1_0_UPDATE_LOGON_STATISTICS = 4; +enum MSV1_0_USE_CLIENT_CHALLENGE = 128; +enum MSV1_0_USER_SESSION_KEY_LENGTH = 16; + +const char[] + MSV1_0_SUBAUTHENTICATION_KEY + = `System\CurrentControlSet\Control\Lsa\MSV1_0`, + MSV1_0_SUBAUTHENTICATION_VALUE = "Auth"; + +enum ACCESS_MASK + POLICY_VIEW_LOCAL_INFORMATION = 0x0001, + POLICY_VIEW_AUDIT_INFORMATION = 0x0002, + POLICY_GET_PRIVATE_INFORMATION = 0x0004, + POLICY_TRUST_ADMIN = 0x0008, + POLICY_CREATE_ACCOUNT = 0x0010, + POLICY_CREATE_SECRET = 0x0020, + POLICY_CREATE_PRIVILEGE = 0x0040, + POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x0080, + POLICY_SET_AUDIT_REQUIREMENTS = 0x0100, + POLICY_AUDIT_LOG_ADMIN = 0x0200, + POLICY_SERVER_ADMIN = 0x0400, + POLICY_LOOKUP_NAMES = 0x0800, + + POLICY_READ = STANDARD_RIGHTS_READ | 0x0006, + POLICY_WRITE = STANDARD_RIGHTS_WRITE | 0x07F8, + POLICY_EXECUTE = STANDARD_RIGHTS_EXECUTE | 0x0801, + POLICY_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | 0x0FFF; + +enum POLICY_AUDIT_EVENT_UNCHANGED = 0; +enum POLICY_AUDIT_EVENT_SUCCESS = 1; +enum POLICY_AUDIT_EVENT_FAILURE = 2; +enum POLICY_AUDIT_EVENT_NONE = 4; +enum POLICY_AUDIT_EVENT_MASK = 7; + +enum { + POLICY_LOCATION_LOCAL = 1, + POLICY_LOCATION_DS +} + +enum : uint { + POLICY_MACHINE_POLICY_LOCAL = 0, + POLICY_MACHINE_POLICY_DEFAULTED, + POLICY_MACHINE_POLICY_EXPLICIT, + POLICY_MACHINE_POLICY_UNKNOWN = 0xFFFFFFFF +} + + +enum POLICY_QOS_SCHANEL_REQUIRED = 0x0001; +enum POLICY_QOS_OUTBOUND_INTEGRITY = 0x0002; +enum POLICY_QOS_OUTBOUND_CONFIDENTIALITY = 0x0004; +enum POLICY_QOS_INBOUND_INTEGREITY = 0x0008; +enum POLICY_QOS_INBOUND_CONFIDENTIALITY = 0x0010; +enum POLICY_QOS_ALLOW_LOCAL_ROOT_CERT_STORE = 0x0020; +enum POLICY_QOS_RAS_SERVER_ALLOWED = 0x0040; +enum POLICY_QOS_DHCP_SERVER_ALLOWD = 0x0080; + +enum POLICY_KERBEROS_FORWARDABLE = 1; +enum POLICY_KERBEROS_PROXYABLE = 2; +enum POLICY_KERBEROS_RENEWABLE = 4; +enum POLICY_KERBEROS_POSTDATEABLE = 8; + +const char[] + SAM_PASSWORD_CHANGE_NOTIFY_ROUTINE = "PasswordChangeNotify", + SAM_INIT_NOTIFICATION_ROUTINE = "InitializeChangeNotify", + SAM_PASSWORD_FILTER_ROUTINE = "PasswordFilter"; + +const TCHAR[] + SE_INTERACTIVE_LOGON_NAME = "SeInteractiveLogonRight", + SE_NETWORK_LOGON_NAME = "SeNetworkLogonRight", + SE_BATCH_LOGON_NAME = "SeBatchLogonRight", + SE_SERVICE_LOGON_NAME = "SeServiceLogonRight"; + +enum { + TRUST_ATTRIBUTE_NON_TRANSITIVE = 1, + TRUST_ATTRIBUTE_UPLEVEL_ONLY = 2, + TRUST_ATTRIBUTE_TREE_PARENT = 4194304, + TRUST_ATTRIBUTES_VALID = -16580609 +} + +enum { + TRUST_AUTH_TYPE_NONE, + TRUST_AUTH_TYPE_NT4OWF, + TRUST_AUTH_TYPE_CLEAR +} + +enum { + TRUST_DIRECTION_DISABLED, + TRUST_DIRECTION_INBOUND, + TRUST_DIRECTION_OUTBOUND, + TRUST_DIRECTION_BIDIRECTIONAL +} + +enum { + TRUST_TYPE_DOWNLEVEL = 1, + TRUST_TYPE_UPLEVEL, + TRUST_TYPE_MIT, + TRUST_TYPE_DCE +} + +alias UNICODE_STRING LSA_UNICODE_STRING; +alias UNICODE_STRING* PLSA_UNICODE_STRING; +alias STRING LSA_STRING; +alias STRING* PLSA_STRING; + +enum MSV1_0_LOGON_SUBMIT_TYPE { + MsV1_0InteractiveLogon = 2, + MsV1_0Lm20Logon, + MsV1_0NetworkLogon, + MsV1_0SubAuthLogon, + MsV1_0WorkstationUnlockLogon = 7 +} +alias MSV1_0_LOGON_SUBMIT_TYPE* PMSV1_0_LOGON_SUBMIT_TYPE; + +enum MSV1_0_PROFILE_BUFFER_TYPE { + MsV1_0InteractiveProfile = 2, + MsV1_0Lm20LogonProfile, + MsV1_0SmartCardProfile +} +alias MSV1_0_PROFILE_BUFFER_TYPE* PMSV1_0_PROFILE_BUFFER_TYPE; + + +enum MSV1_0_AVID { + MsvAvEOL, + MsvAvNbComputerName, + MsvAvNbDomainName, + MsvAvDnsComputerName, + MsvAvDnsDomainName +} + +enum MSV1_0_PROTOCOL_MESSAGE_TYPE { + MsV1_0Lm20ChallengeRequest = 0, + MsV1_0Lm20GetChallengeResponse, + MsV1_0EnumerateUsers, + MsV1_0GetUserInfo, + MsV1_0ReLogonUsers, + MsV1_0ChangePassword, + MsV1_0ChangeCachedPassword, + MsV1_0GenericPassthrough, + MsV1_0CacheLogon, + MsV1_0SubAuth, + MsV1_0DeriveCredential, + MsV1_0CacheLookup +} +alias MSV1_0_PROTOCOL_MESSAGE_TYPE* PMSV1_0_PROTOCOL_MESSAGE_TYPE; + +enum POLICY_LSA_SERVER_ROLE { + PolicyServerRoleBackup = 2, + PolicyServerRolePrimary +} +alias POLICY_LSA_SERVER_ROLE* PPOLICY_LSA_SERVER_ROLE; + +enum POLICY_SERVER_ENABLE_STATE { + PolicyServerEnabled = 2, + PolicyServerDisabled +} +alias POLICY_SERVER_ENABLE_STATE* PPOLICY_SERVER_ENABLE_STATE; + +enum POLICY_INFORMATION_CLASS { + PolicyAuditLogInformation = 1, + PolicyAuditEventsInformation, + PolicyPrimaryDomainInformation, + PolicyPdAccountInformation, + PolicyAccountDomainInformation, + PolicyLsaServerRoleInformation, + PolicyReplicaSourceInformation, + PolicyDefaultQuotaInformation, + PolicyModificationInformation, + PolicyAuditFullSetInformation, + PolicyAuditFullQueryInformation, + PolicyDnsDomainInformation, + PolicyEfsInformation +} +alias POLICY_INFORMATION_CLASS* PPOLICY_INFORMATION_CLASS; + +enum POLICY_AUDIT_EVENT_TYPE { + AuditCategorySystem, + AuditCategoryLogon, + AuditCategoryObjectAccess, + AuditCategoryPrivilegeUse, + AuditCategoryDetailedTracking, + AuditCategoryPolicyChange, + AuditCategoryAccountManagement, + AuditCategoryDirectoryServiceAccess, + AuditCategoryAccountLogon +} +alias POLICY_AUDIT_EVENT_TYPE* PPOLICY_AUDIT_EVENT_TYPE; + +enum POLICY_LOCAL_INFORMATION_CLASS { + PolicyLocalAuditEventsInformation = 1, + PolicyLocalPdAccountInformation, + PolicyLocalAccountDomainInformation, + PolicyLocalLsaServerRoleInformation, + PolicyLocalReplicaSourceInformation, + PolicyLocalModificationInformation, + PolicyLocalAuditFullSetInformation, + PolicyLocalAuditFullQueryInformation, + PolicyLocalDnsDomainInformation, + PolicyLocalIPSecReferenceInformation, + PolicyLocalMachinePasswordInformation, + PolicyLocalQualityOfServiceInformation, + PolicyLocalPolicyLocationInformation +} +alias POLICY_LOCAL_INFORMATION_CLASS* PPOLICY_LOCAL_INFORMATION_CLASS; + +enum POLICY_DOMAIN_INFORMATION_CLASS { + PolicyDomainIPSecReferenceInformation = 1, + PolicyDomainQualityOfServiceInformation, + PolicyDomainEfsInformation, + PolicyDomainPublicKeyInformation, + PolicyDomainPasswordPolicyInformation, + PolicyDomainLockoutInformation, + PolicyDomainKerberosTicketInformation +} +alias POLICY_DOMAIN_INFORMATION_CLASS* PPOLICY_DOMAIN_INFORMATION_CLASS; + +enum SECURITY_LOGON_TYPE { + Interactive = 2, + Network, + Batch, + Service, + Proxy, + Unlock +} +alias SECURITY_LOGON_TYPE* PSECURITY_LOGON_TYPE; + +enum TRUSTED_INFORMATION_CLASS { + TrustedDomainNameInformation = 1, + TrustedControllersInformation, + TrustedPosixOffsetInformation, + TrustedPasswordInformation, + TrustedDomainInformationBasic, + TrustedDomainInformationEx, + TrustedDomainAuthInformation, + TrustedDomainFullInformation +} +alias TRUSTED_INFORMATION_CLASS* PTRUSTED_INFORMATION_CLASS; + +struct DOMAIN_PASSWORD_INFORMATION { + USHORT MinPasswordLength; + USHORT PasswordHistoryLength; + ULONG PasswordProperties; + LARGE_INTEGER MaxPasswordAge; + LARGE_INTEGER MinPasswordAge; +} +alias DOMAIN_PASSWORD_INFORMATION* PDOMAIN_PASSWORD_INFORMATION; + +struct LSA_ENUMERATION_INFORMATION { + PSID Sid; +} +alias LSA_ENUMERATION_INFORMATION* PLSA_ENUMERATION_INFORMATION; + +alias OBJECT_ATTRIBUTES LSA_OBJECT_ATTRIBUTES; +alias OBJECT_ATTRIBUTES* PLSA_OBJECT_ATTRIBUTES; + +struct LSA_TRUST_INFORMATION { + LSA_UNICODE_STRING Name; + PSID Sid; +} +alias LSA_TRUST_INFORMATION TRUSTED_DOMAIN_INFORMATION_BASIC; +alias LSA_TRUST_INFORMATION* PLSA_TRUST_INFORMATION; +/* in MinGW (further down the code): + * typedef PLSA_TRUST_INFORMATION *PTRUSTED_DOMAIN_INFORMATION_BASIC; + * but it doesn't look right.... + */ +alias LSA_TRUST_INFORMATION** PTRUSTED_DOMAIN_INFORMATION_BASIC; + +struct LSA_REFERENCED_DOMAIN_LIST { + ULONG Entries; + PLSA_TRUST_INFORMATION Domains; +} +alias LSA_REFERENCED_DOMAIN_LIST* PLSA_REFERENCED_DOMAIN_LIST; + +struct LSA_TRANSLATED_SID { + SID_NAME_USE Use; + ULONG RelativeId; + LONG DomainIndex; +} +alias LSA_TRANSLATED_SID* PLSA_TRANSLATED_SID; + +struct LSA_TRANSLATED_NAME { + SID_NAME_USE Use; + LSA_UNICODE_STRING Name; + LONG DomainIndex; +} +alias LSA_TRANSLATED_NAME* PLSA_TRANSLATED_NAME; + +struct MSV1_0_INTERACTIVE_LOGON { + MSV1_0_LOGON_SUBMIT_TYPE MessageType; + UNICODE_STRING LogonDomainName; + UNICODE_STRING UserName; + UNICODE_STRING Password; +} +alias MSV1_0_INTERACTIVE_LOGON* PMSV1_0_INTERACTIVE_LOGON; + +struct MSV1_0_INTERACTIVE_PROFILE { + MSV1_0_PROFILE_BUFFER_TYPE MessageType; + USHORT LogonCount; + USHORT BadPasswordCount; + LARGE_INTEGER LogonTime; + LARGE_INTEGER LogoffTime; + LARGE_INTEGER KickOffTime; + LARGE_INTEGER PasswordLastSet; + LARGE_INTEGER PasswordCanChange; + LARGE_INTEGER PasswordMustChange; + UNICODE_STRING LogonScript; + UNICODE_STRING HomeDirectory; + UNICODE_STRING FullName; + UNICODE_STRING ProfilePath; + UNICODE_STRING HomeDirectoryDrive; + UNICODE_STRING LogonServer; + ULONG UserFlags; +} +alias MSV1_0_INTERACTIVE_PROFILE* PMSV1_0_INTERACTIVE_PROFILE; + +struct MSV1_0_LM20_LOGON { + MSV1_0_LOGON_SUBMIT_TYPE MessageType; + UNICODE_STRING LogonDomainName; + UNICODE_STRING UserName; + UNICODE_STRING Workstation; + UCHAR[MSV1_0_CHALLENGE_LENGTH] ChallengeToClient; + STRING CaseSensitiveChallengeResponse; + STRING CaseInsensitiveChallengeResponse; + ULONG ParameterControl; +} +alias MSV1_0_LM20_LOGON* PMSV1_0_LM20_LOGON; + +//static if (_WIN32_WINNT >= 0x500) { + struct MSV1_0_SUBAUTH_LOGON { + MSV1_0_LOGON_SUBMIT_TYPE MessageType; + UNICODE_STRING LogonDomainName; + UNICODE_STRING UserName; + UNICODE_STRING Workstation; + UCHAR[MSV1_0_CHALLENGE_LENGTH] ChallengeToClient; + STRING AuthenticationInfo1; + STRING AuthenticationInfo2; + ULONG ParameterControl; + ULONG SubAuthPackageId; + } + alias MSV1_0_SUBAUTH_LOGON* PMSV1_0_SUBAUTH_LOGON; +//} + +struct MSV1_0_LM20_LOGON_PROFILE { + MSV1_0_PROFILE_BUFFER_TYPE MessageType; + LARGE_INTEGER KickOffTime; + LARGE_INTEGER LogoffTime; + ULONG UserFlags; + UCHAR[MSV1_0_USER_SESSION_KEY_LENGTH] UserSessionKey; + UNICODE_STRING LogonDomainName; + UCHAR[MSV1_0_LANMAN_SESSION_KEY_LENGTH] LanmanSessionKey; + UNICODE_STRING LogonServer; + UNICODE_STRING UserParameters; +} +alias MSV1_0_LM20_LOGON_PROFILE* PMSV1_0_LM20_LOGON_PROFILE; + +struct MSV1_0_SUPPLEMENTAL_CREDENTIAL { + ULONG Version; + ULONG Flags; + UCHAR[MSV1_0_OWF_PASSWORD_LENGTH] LmPassword; + UCHAR[MSV1_0_OWF_PASSWORD_LENGTH] NtPassword; +} +alias MSV1_0_SUPPLEMENTAL_CREDENTIAL* PMSV1_0_SUPPLEMENTAL_CREDENTIAL; + +struct MSV1_0_NTLM3_RESPONSE { + UCHAR[MSV1_0_NTLM3_RESPONSE_LENGTH] Response; + UCHAR RespType; + UCHAR HiRespType; + USHORT Flags; + ULONG MsgWord; + ULONGLONG TimeStamp; + UCHAR[MSV1_0_CHALLENGE_LENGTH] ChallengeFromClient; + ULONG AvPairsOff; + UCHAR _Buffer; + UCHAR* Buffer() return { return &_Buffer; } +} +alias MSV1_0_NTLM3_RESPONSE* PMSV1_0_NTLM3_RESPONSE; + +struct MSV1_0_AV_PAIR { + USHORT AvId; + USHORT AvLen; +} +alias MSV1_0_AV_PAIR* PMSV1_0_AV_PAIR; + +struct MSV1_0_CHANGEPASSWORD_REQUEST { + MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType; + UNICODE_STRING DomainName; + UNICODE_STRING AccountName; + UNICODE_STRING OldPassword; + UNICODE_STRING NewPassword; + BOOLEAN Impersonating; +} +alias MSV1_0_CHANGEPASSWORD_REQUEST* PMSV1_0_CHANGEPASSWORD_REQUEST; + +struct MSV1_0_CHANGEPASSWORD_RESPONSE { + MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType; + BOOLEAN PasswordInfoValid; + DOMAIN_PASSWORD_INFORMATION DomainPasswordInfo; +} +alias MSV1_0_CHANGEPASSWORD_RESPONSE* PMSV1_0_CHANGEPASSWORD_RESPONSE; + +struct MSV1_0_SUBAUTH_REQUEST { + MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType; + ULONG SubAuthPackageId; + ULONG SubAuthInfoLength; + PUCHAR SubAuthSubmitBuffer; +} +alias MSV1_0_SUBAUTH_REQUEST* PMSV1_0_SUBAUTH_REQUEST; + +struct MSV1_0_SUBAUTH_RESPONSE { + MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType; + ULONG SubAuthInfoLength; + PUCHAR SubAuthReturnBuffer; +} +alias MSV1_0_SUBAUTH_RESPONSE* PMSV1_0_SUBAUTH_RESPONSE; + +enum MSV1_0_DERIVECRED_TYPE_SHA1 = 0; + +struct MSV1_0_DERIVECRED_REQUEST { + MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType; + LUID LogonId; + ULONG DeriveCredType; + ULONG DeriveCredInfoLength; + UCHAR _DeriveCredSubmitBuffer; + UCHAR* DeriveCredSubmitBuffer() return { return &_DeriveCredSubmitBuffer; } +} +alias MSV1_0_DERIVECRED_REQUEST* PMSV1_0_DERIVECRED_REQUEST; + +struct MSV1_0_DERIVECRED_RESPONSE { + MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType; + ULONG DeriveCredInfoLength; + UCHAR _DeriveCredReturnBuffer; + UCHAR* DeriveCredReturnBuffer() return { return &_DeriveCredReturnBuffer; } +} +alias MSV1_0_DERIVECRED_RESPONSE* PMSV1_0_DERIVECRED_RESPONSE; + +alias uint LSA_ENUMERATION_HANDLE, LSA_OPERATIONAL_MODE, + POLICY_AUDIT_EVENT_OPTIONS; +alias uint* PLSA_ENUMERATION_HANDLE, PLSA_OPERATIONAL_MODE, + PPOLICY_AUDIT_EVENT_OPTIONS; + +struct POLICY_PRIVILEGE_DEFINITION { + LSA_UNICODE_STRING Name; + LUID LocalValue; +} +alias POLICY_PRIVILEGE_DEFINITION* PPOLICY_PRIVILEGE_DEFINITION; + +struct POLICY_AUDIT_LOG_INFO { + ULONG AuditLogPercentFull; + ULONG MaximumLogSize; + LARGE_INTEGER AuditRetentionPeriod; + BOOLEAN AuditLogFullShutdownInProgress; + LARGE_INTEGER TimeToShutdown; + ULONG NextAuditRecordId; +} +alias POLICY_AUDIT_LOG_INFO* PPOLICY_AUDIT_LOG_INFO; + +struct POLICY_AUDIT_EVENTS_INFO { + BOOLEAN AuditingMode; + PPOLICY_AUDIT_EVENT_OPTIONS EventAuditingOptions; + ULONG MaximumAuditEventCount; +} +alias POLICY_AUDIT_EVENTS_INFO* PPOLICY_AUDIT_EVENTS_INFO; + +struct POLICY_ACCOUNT_DOMAIN_INFO { + LSA_UNICODE_STRING DomainName; + PSID DomainSid; +} +alias POLICY_ACCOUNT_DOMAIN_INFO* PPOLICY_ACCOUNT_DOMAIN_INFO; + +struct POLICY_PRIMARY_DOMAIN_INFO { + LSA_UNICODE_STRING Name; + PSID Sid; +} +alias POLICY_PRIMARY_DOMAIN_INFO* PPOLICY_PRIMARY_DOMAIN_INFO; + +struct POLICY_DNS_DOMAIN_INFO { + LSA_UNICODE_STRING Name; + LSA_UNICODE_STRING DnsDomainName; + LSA_UNICODE_STRING DnsTreeName; + GUID DomainGuid; + PSID Sid; +} +alias POLICY_DNS_DOMAIN_INFO* PPOLICY_DNS_DOMAIN_INFO; + +struct POLICY_PD_ACCOUNT_INFO { + LSA_UNICODE_STRING Name; +} +alias POLICY_PD_ACCOUNT_INFO* PPOLICY_PD_ACCOUNT_INFO; + +struct POLICY_LSA_SERVER_ROLE_INFO { + POLICY_LSA_SERVER_ROLE LsaServerRole; +} +alias POLICY_LSA_SERVER_ROLE_INFO* PPOLICY_LSA_SERVER_ROLE_INFO; + +struct POLICY_REPLICA_SOURCE_INFO { + LSA_UNICODE_STRING ReplicaSource; + LSA_UNICODE_STRING ReplicaAccountName; +} +alias POLICY_REPLICA_SOURCE_INFO* PPOLICY_REPLICA_SOURCE_INFO; + +struct POLICY_DEFAULT_QUOTA_INFO { + QUOTA_LIMITS QuotaLimits; +} +alias POLICY_DEFAULT_QUOTA_INFO* PPOLICY_DEFAULT_QUOTA_INFO; + +struct POLICY_MODIFICATION_INFO { + LARGE_INTEGER ModifiedId; + LARGE_INTEGER DatabaseCreationTime; +} +alias POLICY_MODIFICATION_INFO* PPOLICY_MODIFICATION_INFO; + +struct POLICY_AUDIT_FULL_SET_INFO { + BOOLEAN ShutDownOnFull; +} +alias POLICY_AUDIT_FULL_SET_INFO* PPOLICY_AUDIT_FULL_SET_INFO; + +struct POLICY_AUDIT_FULL_QUERY_INFO { + BOOLEAN ShutDownOnFull; + BOOLEAN LogIsFull; +} +alias POLICY_AUDIT_FULL_QUERY_INFO* PPOLICY_AUDIT_FULL_QUERY_INFO; + +struct POLICY_EFS_INFO { + ULONG InfoLength; + PUCHAR EfsBlob; +} +alias POLICY_EFS_INFO* PPOLICY_EFS_INFO; + +struct POLICY_LOCAL_IPSEC_REFERENCE_INFO { + LSA_UNICODE_STRING ObjectPath; +} +alias POLICY_LOCAL_IPSEC_REFERENCE_INFO* PPOLICY_LOCAL_IPSEC_REFERENCE_INFO; + +struct POLICY_LOCAL_MACHINE_PASSWORD_INFO { + LARGE_INTEGER PasswordChangeInterval; +} +alias POLICY_LOCAL_MACHINE_PASSWORD_INFO* PPOLICY_LOCAL_MACHINE_PASSWORD_INFO; + +struct POLICY_LOCAL_POLICY_LOCATION_INFO { + ULONG PolicyLocation; +} +alias POLICY_LOCAL_POLICY_LOCATION_INFO* PPOLICY_LOCAL_POLICY_LOCATION_INFO; + +struct POLICY_LOCAL_QUALITY_OF_SERVICE_INFO{ + ULONG QualityOfService; +} +alias POLICY_LOCAL_QUALITY_OF_SERVICE_INFO + POLICY_DOMAIN_QUALITY_OF_SERVICE_INFO; +alias POLICY_LOCAL_QUALITY_OF_SERVICE_INFO* + PPOLICY_LOCAL_QUALITY_OF_SERVICE_INFO, + PPOLICY_DOMAIN_QUALITY_OF_SERVICE_INFO; + +struct POLICY_DOMAIN_PUBLIC_KEY_INFO { + ULONG InfoLength; + PUCHAR PublicKeyInfo; +} +alias POLICY_DOMAIN_PUBLIC_KEY_INFO* PPOLICY_DOMAIN_PUBLIC_KEY_INFO; + +struct POLICY_DOMAIN_LOCKOUT_INFO { + LARGE_INTEGER LockoutDuration; + LARGE_INTEGER LockoutObservationWindow; + USHORT LockoutThreshold; +} +alias POLICY_DOMAIN_LOCKOUT_INFO* PPOLICY_DOMAIN_LOCKOUT_INFO; + +struct POLICY_DOMAIN_PASSWORD_INFO { + USHORT MinPasswordLength; + USHORT PasswordHistoryLength; + ULONG PasswordProperties; + LARGE_INTEGER MaxPasswordAge; + LARGE_INTEGER MinPasswordAge; +} +alias POLICY_DOMAIN_PASSWORD_INFO* PPOLICY_DOMAIN_PASSWORD_INFO; + +struct POLICY_DOMAIN_KERBEROS_TICKET_INFO { + ULONG AuthenticationOptions; + LARGE_INTEGER MinTicketAge; + LARGE_INTEGER MaxTicketAge; + LARGE_INTEGER MaxRenewAge; + LARGE_INTEGER ProxyLifetime; + LARGE_INTEGER ForceLogoff; +} +alias POLICY_DOMAIN_KERBEROS_TICKET_INFO* PPOLICY_DOMAIN_KERBEROS_TICKET_INFO; + +alias LSA_HANDLE = HANDLE; +alias LSA_HANDLE* PLSA_HANDLE; + +struct TRUSTED_DOMAIN_NAME_INFO { + LSA_UNICODE_STRING Name; +} +alias TRUSTED_DOMAIN_NAME_INFO* PTRUSTED_DOMAIN_NAME_INFO; + +struct TRUSTED_CONTROLLERS_INFO { + ULONG Entries; + PLSA_UNICODE_STRING Names; +} +alias TRUSTED_CONTROLLERS_INFO* PTRUSTED_CONTROLLERS_INFO; + +struct TRUSTED_POSIX_OFFSET_INFO { + ULONG Offset; +} +alias TRUSTED_POSIX_OFFSET_INFO* PTRUSTED_POSIX_OFFSET_INFO; + +struct TRUSTED_PASSWORD_INFO { + LSA_UNICODE_STRING Password; + LSA_UNICODE_STRING OldPassword; +} +alias TRUSTED_PASSWORD_INFO* PTRUSTED_PASSWORD_INFO; + +struct TRUSTED_DOMAIN_INFORMATION_EX { + LSA_UNICODE_STRING Name; + LSA_UNICODE_STRING FlatName; + PSID Sid; + ULONG TrustDirection; + ULONG TrustType; + ULONG TrustAttributes; +} +alias TRUSTED_DOMAIN_INFORMATION_EX* PTRUSTED_DOMAIN_INFORMATION_EX; + +struct LSA_AUTH_INFORMATION { + LARGE_INTEGER LastUpdateTime; + ULONG AuthType; + ULONG AuthInfoLength; + PUCHAR AuthInfo; +} +alias LSA_AUTH_INFORMATION* PLSA_AUTH_INFORMATION; + +struct TRUSTED_DOMAIN_AUTH_INFORMATION { + ULONG IncomingAuthInfos; + PLSA_AUTH_INFORMATION IncomingAuthenticationInformation; + PLSA_AUTH_INFORMATION IncomingPreviousAuthenticationInformation; + ULONG OutgoingAuthInfos; + PLSA_AUTH_INFORMATION OutgoingAuthenticationInformation; + PLSA_AUTH_INFORMATION OutgoingPreviousAuthenticationInformation; +} +alias TRUSTED_DOMAIN_AUTH_INFORMATION* PTRUSTED_DOMAIN_AUTH_INFORMATION; + +struct TRUSTED_DOMAIN_FULL_INFORMATION { + TRUSTED_DOMAIN_INFORMATION_EX Information; + TRUSTED_POSIX_OFFSET_INFO PosixOffset; + TRUSTED_DOMAIN_AUTH_INFORMATION AuthInformation; +} +alias TRUSTED_DOMAIN_FULL_INFORMATION* PTRUSTED_DOMAIN_FULL_INFORMATION; + +extern (Windows) nothrow @nogc { + NTSTATUS LsaAddAccountRights(LSA_HANDLE, PSID, PLSA_UNICODE_STRING, + ULONG); + NTSTATUS LsaCallAuthenticationPackage(HANDLE, ULONG, PVOID, ULONG, + PVOID*, PULONG, PNTSTATUS); + NTSTATUS LsaClose(LSA_HANDLE); + NTSTATUS LsaConnectUntrusted(PHANDLE); + NTSTATUS LsaCreateTrustedDomainEx(LSA_HANDLE, + PTRUSTED_DOMAIN_INFORMATION_EX, PTRUSTED_DOMAIN_AUTH_INFORMATION, + ACCESS_MASK, PLSA_HANDLE); + NTSTATUS LsaDeleteTrustedDomain(LSA_HANDLE, PSID); + NTSTATUS LsaDeregisterLogonProcess(HANDLE); + NTSTATUS LsaEnumerateAccountRights(LSA_HANDLE, PSID, PLSA_UNICODE_STRING*, + PULONG); + NTSTATUS LsaEnumerateAccountsWithUserRight(LSA_HANDLE, + PLSA_UNICODE_STRING, PVOID*, PULONG); + NTSTATUS LsaEnumerateTrustedDomains(LSA_HANDLE, PLSA_ENUMERATION_HANDLE, + PVOID*, ULONG, PULONG); + NTSTATUS LsaEnumerateTrustedDomainsEx(LSA_HANDLE, PLSA_ENUMERATION_HANDLE, + TRUSTED_INFORMATION_CLASS, PVOID*, ULONG, PULONG); + NTSTATUS LsaFreeMemory(PVOID); + NTSTATUS LsaFreeReturnBuffer(PVOID); + NTSTATUS LsaLogonUser(HANDLE, PLSA_STRING, SECURITY_LOGON_TYPE, ULONG, + PVOID, ULONG, PTOKEN_GROUPS, PTOKEN_SOURCE, PVOID*, PULONG, PLUID, + PHANDLE, PQUOTA_LIMITS, PNTSTATUS); + NTSTATUS LsaLookupAuthenticationPackage(HANDLE, PLSA_STRING, PULONG); + NTSTATUS LsaLookupNames(LSA_HANDLE, ULONG, PLSA_UNICODE_STRING, + PLSA_REFERENCED_DOMAIN_LIST*, PLSA_TRANSLATED_SID*); + NTSTATUS LsaLookupSids(LSA_HANDLE, ULONG, PSID*, + PLSA_REFERENCED_DOMAIN_LIST*, PLSA_TRANSLATED_NAME*); + ULONG LsaNtStatusToWinError(NTSTATUS); + NTSTATUS LsaOpenPolicy(PLSA_UNICODE_STRING, PLSA_OBJECT_ATTRIBUTES, + ACCESS_MASK, PLSA_HANDLE); + NTSTATUS LsaQueryDomainInformationPolicy(LSA_HANDLE, + POLICY_DOMAIN_INFORMATION_CLASS, PVOID*); + NTSTATUS LsaQueryInformationPolicy(LSA_HANDLE, POLICY_INFORMATION_CLASS, + PVOID*); + NTSTATUS LsaQueryLocalInformationPolicy(LSA_HANDLE, + POLICY_LOCAL_INFORMATION_CLASS, PVOID*); + NTSTATUS LsaQueryTrustedDomainInfo(LSA_HANDLE, PSID, + TRUSTED_INFORMATION_CLASS, PVOID*); + NTSTATUS LsaQueryTrustedDomainInfoByName(LSA_HANDLE, PLSA_UNICODE_STRING, + TRUSTED_INFORMATION_CLASS, PVOID*); + NTSTATUS LsaRegisterLogonProcess(PLSA_STRING, PHANDLE, + PLSA_OPERATIONAL_MODE); + NTSTATUS LsaRemoveAccountRights(LSA_HANDLE, PSID, BOOLEAN, + PLSA_UNICODE_STRING, ULONG); + NTSTATUS LsaRetrievePrivateData(LSA_HANDLE, PLSA_UNICODE_STRING, + PLSA_UNICODE_STRING*); + NTSTATUS LsaSetDomainInformationPolicy(LSA_HANDLE, + POLICY_DOMAIN_INFORMATION_CLASS, PVOID); + NTSTATUS LsaSetInformationPolicy(LSA_HANDLE, POLICY_INFORMATION_CLASS, + PVOID); + NTSTATUS LsaSetLocalInformationPolicy(LSA_HANDLE, + POLICY_LOCAL_INFORMATION_CLASS, PVOID); + NTSTATUS LsaSetTrustedDomainInformation(LSA_HANDLE, PSID, + TRUSTED_INFORMATION_CLASS, PVOID); + NTSTATUS LsaSetTrustedDomainInfoByName(LSA_HANDLE, PLSA_UNICODE_STRING, + TRUSTED_INFORMATION_CLASS, PVOID); + NTSTATUS LsaStorePrivateData(LSA_HANDLE, PLSA_UNICODE_STRING, + PLSA_UNICODE_STRING); +} + +alias NTSTATUS function(PUNICODE_STRING, ULONG, PUNICODE_STRING) + PSAM_PASSWORD_NOTIFICATION_ROUTINE; +alias BOOLEAN function() PSAM_INIT_NOTIFICATION_ROUTINE; +alias BOOLEAN function(PUNICODE_STRING, PUNICODE_STRING, + PUNICODE_STRING, BOOLEAN) PSAM_PASSWORD_FILTER_ROUTINE; diff --git a/src/urt/internal/sys/windows/ntsecpkg.d b/src/urt/internal/sys/windows/ntsecpkg.d new file mode 100644 index 0000000..6a2dc69 --- /dev/null +++ b/src/urt/internal/sys/windows/ntsecpkg.d @@ -0,0 +1,445 @@ +/** + * Windows API header module + * + * Translated from MinGW Windows headers + * + * Authors: Ellery Newcomer + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(DRUNTIMESRC core/sys/windows/_ntsecpkg.d) + */ +module urt.internal.sys.windows.ntsecpkg; +version (Windows): + +import urt.internal.sys.windows.windef, urt.internal.sys.windows.ntsecapi, urt.internal.sys.windows.security, urt.internal.sys.windows.ntdef, urt.internal.sys.windows.sspi; +import urt.internal.sys.windows.basetyps : GUID; +import urt.internal.sys.windows.winbase; + +extern(Windows): + +enum :ULONG{ + ISC_REQ_DELEGATE = 1, + ISC_REQ_MUTUAL_AUTH = 2, + ISC_REQ_REPLAY_DETECT = 4, + ISC_REQ_SEQUENCE_DETECT = 8, + ISC_REQ_CONFIDENTIALITY = 16, + ISC_REQ_USE_SESSION_KEY = 32, + ISC_REQ_PROMPT_FOR_CREDS = 64, + ISC_REQ_USE_SUPPLIED_CREDS = 128, + ISC_REQ_ALLOCATE_MEMORY = 256, + ISC_REQ_USE_DCE_STYLE = 512, + ISC_REQ_DATAGRAM = 1024, + ISC_REQ_CONNECTION = 2048, + ISC_REQ_EXTENDED_ERROR = 16384, + ISC_REQ_STREAM = 32768, + ISC_REQ_INTEGRITY = 65536, + ISC_REQ_MANUAL_CRED_VALIDATION = 524288, + ISC_REQ_HTTP = 268435456, +} + +enum ISC_RET_EXTENDED_ERROR = 16384; + +enum :ULONG{ + ASC_REQ_DELEGATE = 1, + ASC_REQ_MUTUAL_AUTH = 2, + ASC_REQ_REPLAY_DETECT = 4, + ASC_REQ_SEQUENCE_DETECT = 8, + ASC_REQ_CONFIDENTIALITY = 16, + ASC_REQ_USE_SESSION_KEY = 32, + ASC_REQ_ALLOCATE_MEMORY = 256, + ASC_REQ_USE_DCE_STYLE = 512, + ASC_REQ_DATAGRAM = 1024, + ASC_REQ_CONNECTION = 2048, + ASC_REQ_EXTENDED_ERROR = 32768, + ASC_REQ_STREAM = 65536, + ASC_REQ_INTEGRITY = 131072, +} + +enum SECURITY_NATIVE_DREP = 16; +enum SECURITY_NETWORK_DREP = 0; + +enum :ULONG{ + SECPKG_STATE_ENCRYPTION_PERMITTED = 0x01, + SECPKG_STATE_STRONG_ENCRYPTION_PERMITTED = 0x02, + SECPKG_STATE_DOMAIN_CONTROLLER = 0x04, + SECPKG_STATE_WORKSTATION = 0x08, + SECPKG_STATE_STANDALONE = 0x10, +} + +/* enum definitions for Secure Service Provider/Authentication Packages */ +enum LSA_TOKEN_INFORMATION_TYPE { + LsaTokenInformationNull, + LsaTokenInformationV1 +} +alias LSA_TOKEN_INFORMATION_TYPE* PLSA_TOKEN_INFORMATION_TYPE; +enum SECPKG_EXTENDED_INFORMATION_CLASS +{ + SecpkgGssInfo = 1, + SecpkgContextThunks, + SecpkgMutualAuthLevel, + SecpkgMaxInfo +} +enum SECPKG_NAME_TYPE { + SecNameSamCompatible, + SecNameAlternateId, + SecNameFlat, + SecNameDN +} + +/* struct definitions for SSP/AP */ +struct SECPKG_PRIMARY_CRED { + LUID LogonId; + UNICODE_STRING DownlevelName; + UNICODE_STRING DomainName; + UNICODE_STRING Password; + UNICODE_STRING OldPassword; + PSID UserSid; + ULONG Flags; + UNICODE_STRING DnsDomainName; + UNICODE_STRING Upn; + UNICODE_STRING LogonServer; + UNICODE_STRING Spare1; + UNICODE_STRING Spare2; + UNICODE_STRING Spare3; + UNICODE_STRING Spare4; +} +alias SECPKG_PRIMARY_CRED* PSECPKG_PRIMARY_CRED; +struct SECPKG_SUPPLEMENTAL_CRED { + UNICODE_STRING PackageName; + ULONG CredentialSize; + PUCHAR Credentials; +} +alias SECPKG_SUPPLEMENTAL_CRED* PSECPKG_SUPPLEMENTAL_CRED; +struct SECPKG_SUPPLEMENTAL_CRED_ARRAY { + ULONG CredentialCount; + SECPKG_SUPPLEMENTAL_CRED[1] Credentials; +} +alias SECPKG_SUPPLEMENTAL_CRED_ARRAY* PSECPKG_SUPPLEMENTAL_CRED_ARRAY; +struct SECPKG_PARAMETERS { + ULONG Version; + ULONG MachineState; + ULONG SetupMode; + PSID DomainSid; + UNICODE_STRING DomainName; + UNICODE_STRING DnsDomainName; + GUID DomainGuid; +} +alias SECPKG_PARAMETERS* PSECPKG_PARAMETERS,PSECPKG_EVENT_DOMAIN_CHANGE; +alias SECPKG_PARAMETERS SECPKG_EVENT_DOMAIN_CHANGE; +struct SECPKG_CLIENT_INFO { + LUID LogonId; + ULONG ProcessID; + ULONG ThreadID; + BOOLEAN HasTcbPrivilege; + BOOLEAN Impersonating; + BOOLEAN Restricted; +} +alias SECPKG_CLIENT_INFO* PSECPKG_CLIENT_INFO; +struct SECURITY_USER_DATA { + SECURITY_STRING UserName; + SECURITY_STRING LogonDomainName; + SECURITY_STRING LogonServer; + PSID pSid; +} +alias SECURITY_USER_DATA* PSECURITY_USER_DATA,PSecurityUserData; +alias SECURITY_USER_DATA SecurityUserData; +struct SECPKG_GSS_INFO { + ULONG EncodedIdLength; + UCHAR[4] EncodedId; +} +alias SECPKG_GSS_INFO* PSECPKG_GSS_INFO; +struct SECPKG_CONTEXT_THUNKS { + ULONG InfoLevelCount; + ULONG[1] Levels; +} +alias SECPKG_CONTEXT_THUNKS* PSECPKG_CONTEXT_THUNKS; +struct SECPKG_MUTUAL_AUTH_LEVEL { + ULONG MutualAuthLevel; +} +alias SECPKG_MUTUAL_AUTH_LEVEL* PSECPKG_MUTUAL_AUTH_LEVEL; +struct SECPKG_CALL_INFO { + ULONG ProcessId; + ULONG ThreadId; + ULONG Attributes; + ULONG CallCount; +} +alias SECPKG_CALL_INFO* PSECPKG_CALL_INFO; +struct SECPKG_EXTENDED_INFORMATION { + SECPKG_EXTENDED_INFORMATION_CLASS Class; + union _Info{ + SECPKG_GSS_INFO GssInfo; + SECPKG_CONTEXT_THUNKS ContextThunks; + SECPKG_MUTUAL_AUTH_LEVEL MutualAuthLevel; + } + _Info Info; +} +alias SECPKG_EXTENDED_INFORMATION* PSECPKG_EXTENDED_INFORMATION; + +/* callbacks implemented by SSP/AP dlls and called by the LSA */ +alias void function(ULONG_PTR, ULONG_PTR, PSecBuffer, + PSecBuffer) PLSA_CALLBACK_FUNCTION; + +/* misc typedefs used in the below prototypes */ +alias PVOID* PLSA_CLIENT_REQUEST; +alias ULONG_PTR LSA_SEC_HANDLE; +alias LSA_SEC_HANDLE* PLSA_SEC_HANDLE; +alias LPTHREAD_START_ROUTINE SEC_THREAD_START; +alias PSECURITY_ATTRIBUTES SEC_ATTRS; + +/* functions used by SSP/AP obtainable by dispatch tables */ +alias NTSTATUS function(ULONG, PLSA_CALLBACK_FUNCTION) PLSA_REGISTER_CALLBACK; +alias NTSTATUS function(PLUID) PLSA_CREATE_LOGON_SESSION; +alias NTSTATUS function(PLUID) PLSA_DELETE_LOGON_SESSION; +alias NTSTATUS function(PLUID, ULONG, PLSA_STRING, + PLSA_STRING) PLSA_ADD_CREDENTIAL; +alias NTSTATUS function(PLUID, ULONG, PULONG, BOOLEAN, + PLSA_STRING, PULONG, PLSA_STRING) PLSA_GET_CREDENTIALS; +alias NTSTATUS function(PLUID, ULONG, PLSA_STRING) PLSA_DELETE_CREDENTIAL; +alias PVOID function(ULONG) PLSA_ALLOCATE_LSA_HEAP; +alias void function(PVOID) PLSA_FREE_LSA_HEAP; +alias NTSTATUS function(PLSA_CLIENT_REQUEST, + ULONG, PVOID*) PLSA_ALLOCATE_CLIENT_BUFFER; +alias NTSTATUS function(PLSA_CLIENT_REQUEST, PVOID) PLSA_FREE_CLIENT_BUFFER; +alias NTSTATUS function(PLSA_CLIENT_REQUEST, ULONG, + PVOID, PVOID) PLSA_COPY_TO_CLIENT_BUFFER; +alias NTSTATUS function(PLSA_CLIENT_REQUEST, + ULONG, PVOID, PVOID) PLSA_COPY_FROM_CLIENT_BUFFER; +alias NTSTATUS function() PLSA_IMPERSONATE_CLIENT; +alias NTSTATUS function() PLSA_UNLOAD_PACKAGE; +alias NTSTATUS function(HANDLE, PHANDLE) PLSA_DUPLICATE_HANDLE; +alias NTSTATUS function(PLUID, ULONG, + PVOID, BOOLEAN) PLSA_SAVE_SUPPLEMENTAL_CREDENTIALS; +alias HANDLE function(SEC_ATTRS, ULONG, SEC_THREAD_START, + PVOID, ULONG, PULONG) PLSA_CREATE_THREAD; +alias NTSTATUS function(PSECPKG_CLIENT_INFO) PLSA_GET_CLIENT_INFO; +alias HANDLE function(SEC_THREAD_START, PVOID, + ULONG, ULONG, ULONG, ULONG, HANDLE) PLSA_REGISTER_NOTIFICATION; +alias NTSTATUS function(HANDLE) PLSA_CANCEL_NOTIFICATION; +alias NTSTATUS function(PSecBuffer, PSecBuffer) PLSA_MAP_BUFFER; +alias NTSTATUS function(PLUID, PTOKEN_SOURCE, + SECURITY_LOGON_TYPE, SECURITY_IMPERSONATION_LEVEL, LSA_TOKEN_INFORMATION_TYPE, + PVOID, PTOKEN_GROUPS, PUNICODE_STRING, PUNICODE_STRING, PUNICODE_STRING, + PUNICODE_STRING, PHANDLE, PNTSTATUS) PLSA_CREATE_TOKEN; +alias void function(NTSTATUS, NTSTATUS, PUNICODE_STRING, + PUNICODE_STRING, PUNICODE_STRING, PSID, SECURITY_LOGON_TYPE, + PTOKEN_SOURCE, PLUID) PLSA_AUDIT_LOGON; +alias NTSTATUS function(PUNICODE_STRING, PVOID, ULONG, + PVOID*, PULONG, PNTSTATUS) PLSA_CALL_PACKAGE; +alias BOOLEAN function(PSECPKG_CALL_INFO) PLSA_GET_CALL_INFO; +alias NTSTATUS function(PUNICODE_STRING, PVOID, PVOID, + ULONG, PVOID*, PULONG, PNTSTATUS) PLSA_CALL_PACKAGEEX; +alias PVOID function(ULONG, ULONG) PLSA_CREATE_SHARED_MEMORY; +alias PVOID function(PVOID, ULONG) PLSA_ALLOCATE_SHARED_MEMORY; +alias void function(PVOID, PVOID) PLSA_FREE_SHARED_MEMORY; +alias BOOLEAN function(PVOID) PLSA_DELETE_SHARED_MEMORY; +alias NTSTATUS function(PSECURITY_STRING, SECPKG_NAME_TYPE, + PSECURITY_STRING, BOOLEAN, ULONG, PVOID*) PLSA_OPEN_SAM_USER; +alias NTSTATUS function(PVOID, PVOID *, PULONG, + PVOID *, PULONG) PLSA_GET_USER_CREDENTIALS; +alias NTSTATUS function(PVOID, PUCHAR *, PULONG) PLSA_GET_USER_AUTH_DATA; +alias NTSTATUS function(PVOID) PLSA_CLOSE_SAM_USER; +alias NTSTATUS function(PVOID, ULONG, + SECURITY_IMPERSONATION_LEVEL, PTOKEN_SOURCE, SECURITY_LOGON_TYPE, + PUNICODE_STRING, PHANDLE, PLUID, PUNICODE_STRING, PNTSTATUS) PLSA_CONVERT_AUTH_DATA_TO_TOKEN; +alias NTSTATUS function(PCHAR, ULONG_PTR, ULONG_PTR, + PSecBuffer, PSecBuffer) PLSA_CLIENT_CALLBACK; +alias NTSTATUS function(PSECPKG_PRIMARY_CRED, PSECPKG_SUPPLEMENTAL_CRED_ARRAY) PLSA_UPDATE_PRIMARY_CREDENTIALS; +alias NTSTATUS function(PSECURITY_STRING, + SECPKG_NAME_TYPE, PSECURITY_STRING, PUCHAR *, PULONG, PUNICODE_STRING) PLSA_GET_AUTH_DATA_FOR_USER; +alias NTSTATUS function(ULONG, BOOLEAN, + PUNICODE_STRING, PUNICODE_STRING, ULONG, PUNICODE_STRING, PUNICODE_STRING, + PULONG) PLSA_CRACK_SINGLE_NAME; +alias NTSTATUS function(ULONG, BOOLEAN, + PUNICODE_STRING, PUNICODE_STRING, PUNICODE_STRING, NTSTATUS) PLSA_AUDIT_ACCOUNT_LOGON; +alias NTSTATUS function(PUNICODE_STRING, PVOID, + PVOID, ULONG, PVOID*, PULONG, PNTSTATUS) PLSA_CALL_PACKAGE_PASSTHROUGH; + +/* Dispatch tables of functions used by SSP/AP */ +struct SECPKG_DLL_FUNCTIONS { + PLSA_ALLOCATE_LSA_HEAP AllocateHeap; + PLSA_FREE_LSA_HEAP FreeHeap; + PLSA_REGISTER_CALLBACK RegisterCallback; +} +alias SECPKG_DLL_FUNCTIONS* PSECPKG_DLL_FUNCTIONS; +struct LSA_DISPATCH_TABLE { + PLSA_CREATE_LOGON_SESSION CreateLogonSession; + PLSA_DELETE_LOGON_SESSION DeleteLogonSession; + PLSA_ADD_CREDENTIAL AddCredential; + PLSA_GET_CREDENTIALS GetCredentials; + PLSA_DELETE_CREDENTIAL DeleteCredential; + PLSA_ALLOCATE_LSA_HEAP AllocateLsaHeap; + PLSA_FREE_LSA_HEAP FreeLsaHeap; + PLSA_ALLOCATE_CLIENT_BUFFER AllocateClientBuffer; + PLSA_FREE_CLIENT_BUFFER FreeClientBuffer; + PLSA_COPY_TO_CLIENT_BUFFER CopyToClientBuffer; + PLSA_COPY_FROM_CLIENT_BUFFER CopyFromClientBuffer; +} +alias LSA_DISPATCH_TABLE* PLSA_DISPATCH_TABLE; +struct LSA_SECPKG_FUNCTION_TABLE { + PLSA_CREATE_LOGON_SESSION CreateLogonSession; + PLSA_DELETE_LOGON_SESSION DeleteLogonSession; + PLSA_ADD_CREDENTIAL AddCredential; + PLSA_GET_CREDENTIALS GetCredentials; + PLSA_DELETE_CREDENTIAL DeleteCredential; + PLSA_ALLOCATE_LSA_HEAP AllocateLsaHeap; + PLSA_FREE_LSA_HEAP FreeLsaHeap; + PLSA_ALLOCATE_CLIENT_BUFFER AllocateClientBuffer; + PLSA_FREE_CLIENT_BUFFER FreeClientBuffer; + PLSA_COPY_TO_CLIENT_BUFFER CopyToClientBuffer; + PLSA_COPY_FROM_CLIENT_BUFFER CopyFromClientBuffer; + PLSA_IMPERSONATE_CLIENT ImpersonateClient; + PLSA_UNLOAD_PACKAGE UnloadPackage; + PLSA_DUPLICATE_HANDLE DuplicateHandle; + PLSA_SAVE_SUPPLEMENTAL_CREDENTIALS SaveSupplementalCredentials; + PLSA_CREATE_THREAD CreateThread; + PLSA_GET_CLIENT_INFO GetClientInfo; + PLSA_REGISTER_NOTIFICATION RegisterNotification; + PLSA_CANCEL_NOTIFICATION CancelNotification; + PLSA_MAP_BUFFER MapBuffer; + PLSA_CREATE_TOKEN CreateToken; + PLSA_AUDIT_LOGON AuditLogon; + PLSA_CALL_PACKAGE CallPackage; + PLSA_FREE_LSA_HEAP FreeReturnBuffer; + PLSA_GET_CALL_INFO GetCallInfo; + PLSA_CALL_PACKAGEEX CallPackageEx; + PLSA_CREATE_SHARED_MEMORY CreateSharedMemory; + PLSA_ALLOCATE_SHARED_MEMORY AllocateSharedMemory; + PLSA_FREE_SHARED_MEMORY FreeSharedMemory; + PLSA_DELETE_SHARED_MEMORY DeleteSharedMemory; + PLSA_OPEN_SAM_USER OpenSamUser; + PLSA_GET_USER_CREDENTIALS GetUserCredentials; + PLSA_GET_USER_AUTH_DATA GetUserAuthData; + PLSA_CLOSE_SAM_USER CloseSamUser; + PLSA_CONVERT_AUTH_DATA_TO_TOKEN ConvertAuthDataToToken; + PLSA_CLIENT_CALLBACK ClientCallback; + PLSA_UPDATE_PRIMARY_CREDENTIALS UpdateCredentials; + PLSA_GET_AUTH_DATA_FOR_USER GetAuthDataForUser; + PLSA_CRACK_SINGLE_NAME CrackSingleName; + PLSA_AUDIT_ACCOUNT_LOGON AuditAccountLogon; + PLSA_CALL_PACKAGE_PASSTHROUGH CallPackagePassthrough; +} +alias LSA_SECPKG_FUNCTION_TABLE* PLSA_SECPKG_FUNCTION_TABLE; + +/* functions implemented by SSP/AP obtainable by dispatch tables */ +alias NTSTATUS function(ULONG, PLSA_DISPATCH_TABLE, + PLSA_STRING, PLSA_STRING, PLSA_STRING *) PLSA_AP_INITIALIZE_PACKAGE; +alias NTSTATUS function(LPWSTR, LPWSTR, LPWSTR, LPWSTR, + DWORD, DWORD, PHANDLE) PLSA_AP_LOGON_USER; +alias NTSTATUS function(PUNICODE_STRING, PVOID, ULONG, + PVOID *, PULONG, PNTSTATUS) PLSA_AP_CALL_PACKAGE; +alias void function(PLUID) PLSA_AP_LOGON_TERMINATED; +alias NTSTATUS function(PLSA_CLIENT_REQUEST, + PVOID, PVOID, ULONG, PVOID *, PULONG, PNTSTATUS) PLSA_AP_CALL_PACKAGE_UNTRUSTED; +alias NTSTATUS function(PUNICODE_STRING, + PVOID, PVOID, ULONG, PVOID *, PULONG, PNTSTATUS) PLSA_AP_CALL_PACKAGE_PASSTHROUGH; +alias NTSTATUS function(PLSA_CLIENT_REQUEST, + SECURITY_LOGON_TYPE, PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS, + PLSA_TOKEN_INFORMATION_TYPE, PVOID *, PUNICODE_STRING *, PUNICODE_STRING *, + PUNICODE_STRING *) PLSA_AP_LOGON_USER_EX; +alias NTSTATUS function(PLSA_CLIENT_REQUEST, + SECURITY_LOGON_TYPE, PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS, + PLSA_TOKEN_INFORMATION_TYPE, PVOID *, PUNICODE_STRING *, PUNICODE_STRING *, + PUNICODE_STRING *, PSECPKG_PRIMARY_CRED, PSECPKG_SUPPLEMENTAL_CRED_ARRAY *) PLSA_AP_LOGON_USER_EX2; +alias NTSTATUS function(ULONG_PTR, PSECPKG_PARAMETERS, + PLSA_SECPKG_FUNCTION_TABLE) SpInitializeFn; +alias NTSTATUS function() SpShutDownFn; +alias NTSTATUS function(PSecPkgInfoW) SpGetInfoFn; +alias NTSTATUS function(SECURITY_LOGON_TYPE, + PUNICODE_STRING, PSECPKG_PRIMARY_CRED, PSECPKG_SUPPLEMENTAL_CRED) SpAcceptCredentialsFn; +alias NTSTATUS function(PUNICODE_STRING, ULONG, + PLUID, PVOID, PVOID, PVOID, PLSA_SEC_HANDLE, PTimeStamp) SpAcquireCredentialsHandleFn; +alias NTSTATUS function(LSA_SEC_HANDLE, ULONG, PVOID) SpQueryCredentialsAttributesFn; +alias NTSTATUS function(LSA_SEC_HANDLE) SpFreeCredentialsHandleFn; +alias NTSTATUS function(LSA_SEC_HANDLE, PSecBuffer) SpSaveCredentialsFn; +alias NTSTATUS function(LSA_SEC_HANDLE, PSecBuffer) SpGetCredentialsFn; +alias NTSTATUS function(LSA_SEC_HANDLE, PSecBuffer) SpDeleteCredentialsFn; +alias NTSTATUS function(LSA_SEC_HANDLE, LSA_SEC_HANDLE, + PUNICODE_STRING, ULONG, ULONG, PSecBufferDesc, PLSA_SEC_HANDLE, PSecBufferDesc, + PULONG, PTimeStamp, PBOOLEAN, PSecBuffer) SpInitLsaModeContextFn; +alias NTSTATUS function(LSA_SEC_HANDLE, + LSA_SEC_HANDLE, PSecBufferDesc, ULONG, ULONG, PLSA_SEC_HANDLE, PSecBufferDesc, + PULONG, PTimeStamp, PBOOLEAN, PSecBuffer) SpAcceptLsaModeContextFn; +alias NTSTATUS function(LSA_SEC_HANDLE) SpDeleteContextFn; +alias NTSTATUS function(LSA_SEC_HANDLE, PSecBufferDesc) SpApplyControlTokenFn; +alias NTSTATUS function(PLUID, ULONG, PSecurityUserData *) SpGetUserInfoFn; +alias NTSTATUS function(SECPKG_EXTENDED_INFORMATION_CLASS, PSECPKG_EXTENDED_INFORMATION *) SpGetExtendedInformationFn; +alias NTSTATUS function(LSA_SEC_HANDLE, ULONG, PVOID) SpQueryContextAttributesFn; +alias NTSTATUS function(LSA_SEC_HANDLE, PUNICODE_STRING, + PUNICODE_STRING, ULONG, PVOID, PVOID, PVOID, PTimeStamp) SpAddCredentialsFn; +alias NTSTATUS function( + SECPKG_EXTENDED_INFORMATION_CLASS, PSECPKG_EXTENDED_INFORMATION) SpSetExtendedInformationFn; +alias NTSTATUS function(ULONG, PSECPKG_DLL_FUNCTIONS, + PVOID *) SpInstanceInitFn; +alias NTSTATUS function(LSA_SEC_HANDLE, PSecBuffer) SpInitUserModeContextFn; +alias NTSTATUS function(LSA_SEC_HANDLE, ULONG, + PSecBufferDesc, ULONG) SpMakeSignatureFn; +alias NTSTATUS function(LSA_SEC_HANDLE, PSecBufferDesc, + ULONG, PULONG) SpVerifySignatureFn; +alias NTSTATUS function(LSA_SEC_HANDLE, ULONG, PSecBufferDesc, + ULONG) SpSealMessageFn; +alias NTSTATUS function(LSA_SEC_HANDLE, PSecBufferDesc, + ULONG, PULONG) SpUnsealMessageFn; +alias NTSTATUS function(LSA_SEC_HANDLE, PHANDLE) SpGetContextTokenFn; +alias NTSTATUS function(LSA_SEC_HANDLE, PSecBufferDesc) SpCompleteAuthTokenFn; +alias NTSTATUS function(PSecBuffer, PSecBuffer) SpFormatCredentialsFn; +alias NTSTATUS function(ULONG, PUCHAR, PULONG, + PVOID *) SpMarshallSupplementalCredsFn; +alias NTSTATUS function(LSA_SEC_HANDLE, ULONG, + PSecBuffer, PHANDLE) SpExportSecurityContextFn; +alias NTSTATUS function(PSecBuffer, HANDLE, + PLSA_SEC_HANDLE) SpImportSecurityContextFn; + +/* Dispatch tables of functions implemented by SSP/AP */ +struct SECPKG_FUNCTION_TABLE { + PLSA_AP_INITIALIZE_PACKAGE InitializePackage; + PLSA_AP_LOGON_USER LogonUser; + PLSA_AP_CALL_PACKAGE CallPackage; + PLSA_AP_LOGON_TERMINATED LogonTerminated; + PLSA_AP_CALL_PACKAGE_UNTRUSTED CallPackageUntrusted; + PLSA_AP_CALL_PACKAGE_PASSTHROUGH CallPackagePassthrough; + PLSA_AP_LOGON_USER_EX LogonUserEx; + PLSA_AP_LOGON_USER_EX2 LogonUserEx2; + SpInitializeFn *Initialize; + SpShutDownFn *Shutdown; + SpGetInfoFn *GetInfo; + SpAcceptCredentialsFn *AcceptCredentials; + SpAcquireCredentialsHandleFn *AcquireCredentialsHandle; + SpQueryCredentialsAttributesFn *QueryCredentialsAttributes; + SpFreeCredentialsHandleFn *FreeCredentialsHandle; + SpSaveCredentialsFn *SaveCredentials; + SpGetCredentialsFn *GetCredentials; + SpDeleteCredentialsFn *DeleteCredentials; + SpInitLsaModeContextFn *InitLsaModeContext; + SpAcceptLsaModeContextFn *AcceptLsaModeContext; + SpDeleteContextFn *DeleteContext; + SpApplyControlTokenFn *ApplyControlToken; + SpGetUserInfoFn *GetUserInfo; + SpGetExtendedInformationFn *GetExtendedInformation; + SpQueryContextAttributesFn *QueryContextAttributes; + SpAddCredentialsFn *AddCredentials; + SpSetExtendedInformationFn *SetExtendedInformation; +} +alias SECPKG_FUNCTION_TABLE* PSECPKG_FUNCTION_TABLE; + +struct SECPKG_USER_FUNCTION_TABLE { + SpInstanceInitFn *InstanceInit; + SpInitUserModeContextFn *InitUserModeContext; + SpMakeSignatureFn *MakeSignature; + SpVerifySignatureFn *VerifySignature; + SpSealMessageFn *SealMessage; + SpUnsealMessageFn *UnsealMessage; + SpGetContextTokenFn *GetContextToken; + SpQueryContextAttributesFn *QueryContextAttributes; + SpCompleteAuthTokenFn *CompleteAuthToken; + SpDeleteContextFn *DeleteUserModeContext; + SpFormatCredentialsFn *FormatCredentials; + SpMarshallSupplementalCredsFn *MarshallSupplementalCreds; + SpExportSecurityContextFn *ExportContext; + SpImportSecurityContextFn *ImportContext; +} +alias SECPKG_USER_FUNCTION_TABLE* PSECPKG_USER_FUNCTION_TABLE; + +/* Entry points to SSP/AP */ +alias NTSTATUS function(ULONG, PULONG, + PSECPKG_FUNCTION_TABLE *, PULONG) SpLsaModeInitializeFn; +alias NTSTATUS function(ULONG, PULONG, + PSECPKG_USER_FUNCTION_TABLE *, PULONG) SpUserModeInitializeFn; diff --git a/src/urt/internal/sys/windows/package.d b/src/urt/internal/sys/windows/package.d new file mode 100644 index 0000000..91631b0 --- /dev/null +++ b/src/urt/internal/sys/windows/package.d @@ -0,0 +1,13 @@ +/// Slim umbrella - re-exports only the vendored Windows modules. +module urt.internal.sys.windows; + +public import urt.internal.sys.windows.w32api; +public import urt.internal.sys.windows.basetsd; +public import urt.internal.sys.windows.basetyps; +public import urt.internal.sys.windows.windef; +public import urt.internal.sys.windows.winnt; +public import urt.internal.sys.windows.winbase; +public import urt.internal.sys.windows.wincon; +public import urt.internal.sys.windows.winerror; +public import urt.internal.sys.windows.winsock2; +public import urt.internal.sys.windows.winuser; diff --git a/src/urt/internal/sys/windows/schannel.d b/src/urt/internal/sys/windows/schannel.d new file mode 100644 index 0000000..10a83e9 --- /dev/null +++ b/src/urt/internal/sys/windows/schannel.d @@ -0,0 +1,106 @@ +/** + * Windows API header module + * + * Translated from MinGW Windows headers + * + * Authors: Stewart Gordon + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(DRUNTIMESRC core/sys/windows/_schannel.d) + */ +module urt.internal.sys.windows.schannel; +version (Windows): + +import urt.internal.sys.windows.wincrypt; +import urt.internal.sys.windows.windef; + +enum DWORD SCHANNEL_CRED_VERSION = 4; +enum SCHANNEL_SHUTDOWN = 1; +/* Comment from MinGW + ? Do these belong here or in wincrypt.h + */ +enum : DWORD { + AUTHTYPE_CLIENT = 1, + AUTHTYPE_SERVER = 2 +} + +enum DWORD + SP_PROT_PCT1_SERVER = 0x01, + SP_PROT_PCT1_CLIENT = 0x02, + SP_PROT_SSL2_SERVER = 0x04, + SP_PROT_SSL2_CLIENT = 0x08, + SP_PROT_SSL3_SERVER = 0x10, + SP_PROT_SSL3_CLIENT = 0x20, + SP_PROT_TLS1_SERVER = 0x40, + SP_PROT_TLS1_CLIENT = 0x80, + SP_PROT_PCT1 = SP_PROT_PCT1_CLIENT | SP_PROT_PCT1_SERVER, + SP_PROT_TLS1 = SP_PROT_TLS1_CLIENT | SP_PROT_TLS1_SERVER, + SP_PROT_SSL2 = SP_PROT_SSL2_CLIENT | SP_PROT_SSL2_SERVER, + SP_PROT_SSL3 = SP_PROT_SSL3_CLIENT | SP_PROT_SSL3_SERVER; + +enum DWORD + SCH_CRED_NO_SYSTEM_MAPPER = 0x0002, + SCH_CRED_NO_SERVERNAME_CHECK = 0x0004, + SCH_CRED_MANUAL_CRED_VALIDATION = 0x0008, + SCH_CRED_NO_DEFAULT_CREDS = 0x0010, + SCH_CRED_AUTO_CRED_VALIDATION = 0x0020, + SCH_CRED_USE_DEFAULT_CREDS = 0x0040, + SCH_CRED_REVOCATION_CHECK_END_CERT = 0x0100, + SCH_CRED_REVOCATION_CHECK_CHAIN = 0x0200, + SCH_CRED_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT = 0x0400, + SCH_CRED_IGNORE_NO_REVOCATION_CHECK = 0x0800, + SCH_CRED_IGNORE_REVOCATION_OFFLINE = 0x1000; + +// No definition - presumably an opaque structure +struct _HMAPPER; + +struct SCHANNEL_CRED { + DWORD dwVersion = SCHANNEL_CRED_VERSION; + DWORD cCreds; + PCCERT_CONTEXT* paCred; + HCERTSTORE hRootStore; + DWORD cMappers; + _HMAPPER** aphMappers; + DWORD cSupportedAlgs; + ALG_ID* palgSupportedAlgs; + DWORD grbitEnabledProtocols; + DWORD dwMinimumCypherStrength; + DWORD dwMaximumCypherStrength; + DWORD dwSessionLifespan; + DWORD dwFlags; + DWORD reserved; +} +alias SCHANNEL_CRED* PSCHANNEL_CRED; + +struct SecPkgCred_SupportedAlgs { + DWORD cSupportedAlgs; + ALG_ID* palgSupportedAlgs; +} +alias SecPkgCred_SupportedAlgs* PSecPkgCred_SupportedAlgs; + +struct SecPkgCred_CypherStrengths { + DWORD dwMinimumCypherStrength; + DWORD dwMaximumCypherStrength; +} +alias SecPkgCred_CypherStrengths* PSecPkgCred_CypherStrengths; + +struct SecPkgCred_SupportedProtocols { + DWORD grbitProtocol; +} +alias SecPkgCred_SupportedProtocols* PSecPkgCred_SupportedProtocols; + +struct SecPkgContext_IssuerListInfoEx { + PCERT_NAME_BLOB aIssuers; + DWORD cIssuers; +} +alias SecPkgContext_IssuerListInfoEx* PSecPkgContext_IssuerListInfoEx; + +struct SecPkgContext_ConnectionInfo { + DWORD dwProtocol; + ALG_ID aiCipher; + DWORD dwCipherStrength; + ALG_ID aiHash; + DWORD dwHashStrength; + ALG_ID aiExch; + DWORD dwExchStrength; +} +alias SecPkgContext_ConnectionInfo* PSecPkgContext_ConnectionInfo; diff --git a/src/urt/internal/sys/windows/sdkddkver.d b/src/urt/internal/sys/windows/sdkddkver.d new file mode 100644 index 0000000..7cb696a --- /dev/null +++ b/src/urt/internal/sys/windows/sdkddkver.d @@ -0,0 +1,155 @@ +/** + * Windows API header module + * + * Translated from Windows SDK API + * + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(DRUNTIMESRC core/sys/windows/sdkddkver.d) + */ +module urt.internal.sys.windows.sdkddkver; +version (Windows): + +import urt.internal.sys.windows.w32api; + +enum _WIN32_WINNT_NT4 = 0x0400; +enum _WIN32_WINNT_WIN2K = 0x0500; +enum _WIN32_WINNT_WINXP = 0x0501; +enum _WIN32_WINNT_WS03 = 0x0502; +enum _WIN32_WINNT_WIN6 = 0x0600; +enum _WIN32_WINNT_VISTA = 0x0600; +enum _WIN32_WINNT_WS08 = 0x0600; +enum _WIN32_WINNT_LONGHORN = 0x0600; +enum _WIN32_WINNT_WIN7 = 0x0601; +enum _WIN32_WINNT_WIN8 = 0x0602; +enum _WIN32_WINNT_WINBLUE = 0x0603; +enum _WIN32_WINNT_WINTHRESHOLD = 0x0A00; +enum _WIN32_WINNT_WIN10 = 0x0A00; + +enum _WIN32_IE_IE20 = 0x0200; +enum _WIN32_IE_IE30 = 0x0300; +enum _WIN32_IE_IE302 = 0x0302; +enum _WIN32_IE_IE40 = 0x0400; +enum _WIN32_IE_IE401 = 0x0401; +enum _WIN32_IE_IE50 = 0x0500; +enum _WIN32_IE_IE501 = 0x0501; +enum _WIN32_IE_IE55 = 0x0550; +enum _WIN32_IE_IE60 = 0x0600; +enum _WIN32_IE_IE60SP1 = 0x0601; +enum _WIN32_IE_IE60SP2 = 0x0603; +enum _WIN32_IE_IE70 = 0x0700; +enum _WIN32_IE_IE80 = 0x0800; +enum _WIN32_IE_IE90 = 0x0900; +enum _WIN32_IE_IE100 = 0x0A00; +enum _WIN32_IE_IE110 = 0x0A00; + +enum _WIN32_IE_NT4 = _WIN32_IE_IE20; +enum _WIN32_IE_NT4SP1 = _WIN32_IE_IE20; +enum _WIN32_IE_NT4SP2 = _WIN32_IE_IE20; +enum _WIN32_IE_NT4SP3 = _WIN32_IE_IE302; +enum _WIN32_IE_NT4SP4 = _WIN32_IE_IE401; +enum _WIN32_IE_NT4SP5 = _WIN32_IE_IE401; +enum _WIN32_IE_NT4SP6 = _WIN32_IE_IE50; +enum _WIN32_IE_WIN98 = _WIN32_IE_IE401; +enum _WIN32_IE_WIN98SE = _WIN32_IE_IE50; +enum _WIN32_IE_WINME = _WIN32_IE_IE55; +enum _WIN32_IE_WIN2K = _WIN32_IE_IE501; +enum _WIN32_IE_WIN2KSP1 = _WIN32_IE_IE501; +enum _WIN32_IE_WIN2KSP2 = _WIN32_IE_IE501; +enum _WIN32_IE_WIN2KSP3 = _WIN32_IE_IE501; +enum _WIN32_IE_WIN2KSP4 = _WIN32_IE_IE501; +enum _WIN32_IE_XP = _WIN32_IE_IE60; +enum _WIN32_IE_XPSP1 = _WIN32_IE_IE60SP1; +enum _WIN32_IE_XPSP2 = _WIN32_IE_IE60SP2; +enum _WIN32_IE_WS03 = 0x0602; +enum _WIN32_IE_WS03SP1 = _WIN32_IE_IE60SP2; +enum _WIN32_IE_WIN6 = _WIN32_IE_IE70; +enum _WIN32_IE_LONGHORN = _WIN32_IE_IE70; +enum _WIN32_IE_WIN7 = _WIN32_IE_IE80; +enum _WIN32_IE_WIN8 = _WIN32_IE_IE100; +enum _WIN32_IE_WINBLUE = _WIN32_IE_IE100; +enum _WIN32_IE_WINTHRESHOLD = _WIN32_IE_IE110; +enum _WIN32_IE_WIN10 = _WIN32_IE_IE110; + + +enum NTDDI_WIN2K = 0x05000000; +enum NTDDI_WIN2KSP1 = 0x05000100; +enum NTDDI_WIN2KSP2 = 0x05000200; +enum NTDDI_WIN2KSP3 = 0x05000300; +enum NTDDI_WIN2KSP4 = 0x05000400; + +enum NTDDI_WINXP = 0x05010000; +enum NTDDI_WINXPSP1 = 0x05010100; +enum NTDDI_WINXPSP2 = 0x05010200; +enum NTDDI_WINXPSP3 = 0x05010300; +enum NTDDI_WINXPSP4 = 0x05010400; + +enum NTDDI_WS03 = 0x05020000; +enum NTDDI_WS03SP1 = 0x05020100; +enum NTDDI_WS03SP2 = 0x05020200; +enum NTDDI_WS03SP3 = 0x05020300; +enum NTDDI_WS03SP4 = 0x05020400; + +enum NTDDI_WIN6 = 0x06000000; +enum NTDDI_WIN6SP1 = 0x06000100; +enum NTDDI_WIN6SP2 = 0x06000200; +enum NTDDI_WIN6SP3 = 0x06000300; +enum NTDDI_WIN6SP4 = 0x06000400; + +enum NTDDI_VISTA = NTDDI_WIN6; +enum NTDDI_VISTASP1 = NTDDI_WIN6SP1; +enum NTDDI_VISTASP2 = NTDDI_WIN6SP2; +enum NTDDI_VISTASP3 = NTDDI_WIN6SP3; +enum NTDDI_VISTASP4 = NTDDI_WIN6SP4; + +enum NTDDI_LONGHORN = NTDDI_VISTA; + +enum NTDDI_WS08 = NTDDI_WIN6SP1; +enum NTDDI_WS08SP2 = NTDDI_WIN6SP2; +enum NTDDI_WS08SP3 = NTDDI_WIN6SP3; +enum NTDDI_WS08SP4 = NTDDI_WIN6SP4; + +enum NTDDI_WIN7 = 0x06010000; +enum NTDDI_WIN8 = 0x06020000; +enum NTDDI_WINBLUE = 0x06030000; +enum NTDDI_WINTHRESHOLD = 0x0A000000; +enum NTDDI_WIN10 = 0x0A000000; +enum NTDDI_WIN10_TH2 = 0x0A000001; +enum NTDDI_WIN10_RS1 = 0x0A000002; +enum NTDDI_WIN10_RS2 = 0x0A000003; +enum NTDDI_WIN10_RS3 = 0x0A000004; +enum NTDDI_WIN10_RS4 = 0x0A000005; +enum NTDDI_WIN10_RS5 = 0x0A000006; +enum NTDDI_WIN10_19H1 = 0x0A000007; +enum NTDDI_WIN10_VB = 0x0A000008; +enum NTDDI_WIN10_MN = 0x0A000009; +enum NTDDI_WIN10_FE = 0x0A00000A; +enum NTDDI_WIN10_CO = 0x0A00000B; +enum NTDDI_WIN10_NI = 0x0A00000C; +enum NTDDI_WIN10_CU = 0x0A00000D; +enum NTDDI_WIN11_ZN = 0x0A00000E; +enum NTDDI_WIN11_GA = 0x0A00000F; +enum NTDDI_WIN11_GE = 0x0A000010; + +enum WDK_NTDDI_VERSION = NTDDI_WIN11_GE; + +enum OSVERSION_MASK = 0xFFFF0000U; +enum SPVERSION_MASK = 0x0000FF00; +enum SUBVERSION_MASK = 0x000000FF; + +pragma(inline, true) nothrow @nogc pure @safe { + uint OSVER(uint Version) => Version & OSVERSION_MASK; + uint SPVER(uint Version) => (Version & SPVERSION_MASK) >> 8; + uint SUBVER(uint Version) => Version & SUBVERSION_MASK; + + uint NTDDI_VERSION_FROM_WIN32_WINNT2(uint Version) => Version * 0x10000; + alias NTDDI_VERSION_FROM_WIN32_WINNT = NTDDI_VERSION_FROM_WIN32_WINNT2; +} + + +static if (_WIN32_WINNT < _WIN32_WINNT_WIN10) { + enum NTDDI_VERSION = NTDDI_VERSION_FROM_WIN32_WINNT(_WIN32_WINNT); +} else { + enum NTDDI_VERSION = WDK_NTDDI_VERSION; +} + +enum WINVER = _WIN32_WINNT; diff --git a/src/urt/internal/sys/windows/security.d b/src/urt/internal/sys/windows/security.d new file mode 100644 index 0000000..5efa509 --- /dev/null +++ b/src/urt/internal/sys/windows/security.d @@ -0,0 +1,119 @@ +/** + * Windows API header module + * + * Translated from MinGW Windows headers + * + * Authors: Ellery Newcomer, John Colvin + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(DRUNTIMESRC core/sys/windows/_security.d) + */ +module urt.internal.sys.windows.security; +version (Windows): + +enum : SECURITY_STATUS +{ + SEC_E_OK = 0x00000000, + SEC_E_INSUFFICIENT_MEMORY = 0x80090300, + SEC_E_INVALID_HANDLE = 0x80090301, + SEC_E_UNSUPPORTED_FUNCTION = 0x80090302, + SEC_E_TARGET_UNKNOWN = 0x80090303, + SEC_E_INTERNAL_ERROR = 0x80090304, + SEC_E_SECPKG_NOT_FOUND = 0x80090305, + SEC_E_NOT_OWNER = 0x80090306, + SEC_E_CANNOT_INSTALL = 0x80090307, + SEC_E_INVALID_TOKEN = 0x80090308, + SEC_E_CANNOT_PACK = 0x80090309, + SEC_E_QOP_NOT_SUPPORTED = 0x8009030A, + SEC_E_NO_IMPERSONATION = 0x8009030B, + SEC_E_LOGON_DENIED = 0x8009030C, + SEC_E_UNKNOWN_CREDENTIALS = 0x8009030D, + SEC_E_NO_CREDENTIALS = 0x8009030E, + SEC_E_MESSAGE_ALTERED = 0x8009030F, + SEC_E_OUT_OF_SEQUENCE = 0x80090310, + SEC_E_NO_AUTHENTICATING_AUTHORITY = 0x80090311, + SEC_E_BAD_PKGID = 0x80090316, + SEC_E_CONTEXT_EXPIRED = 0x80090317, + SEC_E_INCOMPLETE_MESSAGE = 0x80090318, + SEC_E_INCOMPLETE_CREDENTIALS = 0x80090320, + SEC_E_BUFFER_TOO_SMALL = 0x80090321, + SEC_E_WRONG_PRINCIPAL = 0x80090322, + SEC_E_TIME_SKEW = 0x80090324, + SEC_E_UNTRUSTED_ROOT = 0x80090325, + SEC_E_ILLEGAL_MESSAGE = 0x80090326, + SEC_E_CERT_UNKNOWN = 0x80090327, + SEC_E_CERT_EXPIRED = 0x80090328, + SEC_E_ENCRYPT_FAILURE = 0x80090329, + SEC_E_DECRYPT_FAILURE = 0x80090330, + SEC_E_ALGORITHM_MISMATCH = 0x80090331, + SEC_E_SECURITY_QOS_FAILED = 0x80090332, + SEC_E_UNFINISHED_CONTEXT_DELETED = 0x80090333, + SEC_E_NO_TGT_REPLY = 0x80090334, + SEC_E_NO_IP_ADDRESSES = 0x80090335, + SEC_E_WRONG_CREDENTIAL_HANDLE = 0x80090336, + SEC_E_CRYPTO_SYSTEM_INVALID = 0x80090337, + SEC_E_MAX_REFERRALS_EXCEEDED = 0x80090338, + SEC_E_MUST_BE_KDC = 0x80090339, + SEC_E_STRONG_CRYPTO_NOT_SUPPORTED = 0x8009033A, + SEC_E_TOO_MANY_PRINCIPALS = 0x8009033B, + SEC_E_NO_PA_DATA = 0x8009033C, + SEC_E_PKINIT_NAME_MISMATCH = 0x8009033D, + SEC_E_SMARTCARD_LOGON_REQUIRED = 0x8009033E, + SEC_E_SHUTDOWN_IN_PROGRESS = 0x8009033F, + SEC_E_KDC_INVALID_REQUEST = 0x80090340, + SEC_E_KDC_UNABLE_TO_REFER = 0x80090341, + SEC_E_KDC_UNKNOWN_ETYPE = 0x80090342, + SEC_E_UNSUPPORTED_PREAUTH = 0x80090343, + SEC_E_DELEGATION_REQUIRED = 0x80090345, + SEC_E_BAD_BINDINGS = 0x80090346, + SEC_E_MULTIPLE_ACCOUNTS = 0x80090347, + SEC_E_NO_KERB_KEY = 0x80090348, + SEC_E_CERT_WRONG_USAGE = 0x80090349, + SEC_E_DOWNGRADE_DETECTED = 0x80090350, + SEC_E_SMARTCARD_CERT_REVOKED = 0x80090351, + SEC_E_ISSUING_CA_UNTRUSTED = 0x80090352, + SEC_E_REVOCATION_OFFLINE_C = 0x80090353, + SEC_E_PKINIT_CLIENT_FAILURE = 0x80090354, + SEC_E_SMARTCARD_CERT_EXPIRED = 0x80090355, + SEC_E_NO_S4U_PROT_SUPPORT = 0x80090356, + SEC_E_CROSSREALM_DELEGATION_FAILURE = 0x80090357, + SEC_E_REVOCATION_OFFLINE_KDC = 0x80090358, + SEC_E_ISSUING_CA_UNTRUSTED_KDC = 0x80090359, + SEC_E_KDC_CERT_EXPIRED = 0x8009035A, + SEC_E_KDC_CERT_REVOKED = 0x8009035B, + SEC_E_INVALID_PARAMETER = 0x8009035D, + SEC_E_DELEGATION_POLICY = 0x8009035E, + SEC_E_POLICY_NLTM_ONLY = 0x8009035F, + SEC_E_NO_CONTEXT = 0x80090361, + SEC_E_PKU2U_CERT_FAILURE = 0x80090362, + SEC_E_MUTUAL_AUTH_FAILED = 0x80090363, + SEC_E_ONLY_HTTPS_ALLOWED = 0x80090365, + SEC_E_APPLICATION_PROTOCOL_MISMATCH = 0x80090367, + SEC_E_INVALID_UPN_NAME = 0x80090369, + SEC_E_EXT_BUFFER_TOO_SMALL = 0x8009036A, + SEC_E_INSUFFICIENT_BUFFERS = 0x8009036B, + SEC_E_NO_SPM = SEC_E_INTERNAL_ERROR, + SEC_E_NOT_SUPPORTED = SEC_E_UNSUPPORTED_FUNCTION +} +enum : SECURITY_STATUS +{ + SEC_I_CONTINUE_NEEDED = 0x00090312, + SEC_I_COMPLETE_NEEDED = 0x00090313, + SEC_I_COMPLETE_AND_CONTINUE = 0x00090314, + SEC_I_LOCAL_LOGON = 0x00090315, + SEC_I_GENERIC_EXTENSION_RECEIVED = 0x00090316, + SEC_I_CONTEXT_EXPIRED = 0x00090317, + SEC_I_INCOMPLETE_CREDENTIALS = 0x00090320, + SEC_I_RENEGOTIATE = 0x00090321, + SEC_I_NO_LSA_CONTEXT = 0x00090323, + SEC_I_SIGNATURE_NEEDED = 0x0009035C, + SEC_I_NO_RENEGOTIATION = 0x00090360, + SEC_I_MESSAGE_FRAGMENT = 0x00090364, + SEC_I_CONTINUE_NEEDED_MESSAGE_OK = 0x00090366, + SEC_I_ASYNC_CALL_PENDING = 0x00090368, +} + +/* always a char */ +alias SEC_CHAR = char; +alias SEC_WCHAR = wchar; + +alias SECURITY_STATUS = int; diff --git a/src/urt/internal/sys/windows/sspi.d b/src/urt/internal/sys/windows/sspi.d new file mode 100644 index 0000000..d085c4a --- /dev/null +++ b/src/urt/internal/sys/windows/sspi.d @@ -0,0 +1,381 @@ +/** + * Windows API header module + * + * Translated from MinGW Windows headers + * + * Authors: Ellery Newcomer + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(DRUNTIMESRC core/sys/windows/_sspi.d) + */ +module urt.internal.sys.windows.sspi; +version (Windows): + +version (ANSI) {} else version = Unicode; + +import urt.internal.sys.windows.windef; +import urt.internal.sys.windows.ntdef; +import urt.internal.sys.windows.w32api; +import urt.internal.sys.windows.security; +import urt.internal.sys.windows.ntsecapi; +import urt.internal.sys.windows.subauth; + +enum :ULONG{ + SECPKG_CRED_INBOUND = 1, + SECPKG_CRED_OUTBOUND = 2, + SECPKG_CRED_BOTH = (SECPKG_CRED_OUTBOUND|SECPKG_CRED_INBOUND), + SECPKG_CRED_ATTR_NAMES = 1, +} + +enum :ULONG{ + SECPKG_FLAG_INTEGRITY = 1, + SECPKG_FLAG_PRIVACY = 2, + SECPKG_FLAG_TOKEN_ONLY = 4, + SECPKG_FLAG_DATAGRAM = 8, + SECPKG_FLAG_CONNECTION = 16, + SECPKG_FLAG_MULTI_REQUIRED = 32, + SECPKG_FLAG_CLIENT_ONLY = 64, + SECPKG_FLAG_EXTENDED_ERROR = 128, + SECPKG_FLAG_IMPERSONATION = 256, + SECPKG_FLAG_ACCEPT_WIN32_NAME = 512, + SECPKG_FLAG_STREAM = 1024, +} + +enum :ULONG{ + SECPKG_ATTR_AUTHORITY = 6, + SECPKG_ATTR_CONNECTION_INFO = 90, + SECPKG_ATTR_ISSUER_LIST = 80, + SECPKG_ATTR_ISSUER_LIST_EX = 89, + SECPKG_ATTR_KEY_INFO = 5, + SECPKG_ATTR_LIFESPAN = 2, + SECPKG_ATTR_LOCAL_CERT_CONTEXT = 84, + SECPKG_ATTR_LOCAL_CRED = 82, + SECPKG_ATTR_NAMES = 1, + SECPKG_ATTR_PROTO_INFO = 7, + SECPKG_ATTR_REMOTE_CERT_CONTEXT = 83, + SECPKG_ATTR_REMOTE_CRED = 81, + SECPKG_ATTR_SIZES = 0, + SECPKG_ATTR_STREAM_SIZES = 4, +} + +enum :ULONG{ + SECBUFFER_EMPTY = 0, + SECBUFFER_DATA = 1, + SECBUFFER_TOKEN = 2, + SECBUFFER_PKG_PARAMS = 3, + SECBUFFER_MISSING = 4, + SECBUFFER_EXTRA = 5, + SECBUFFER_STREAM_TRAILER = 6, + SECBUFFER_STREAM_HEADER = 7, + SECBUFFER_PADDING = 9, + SECBUFFER_STREAM = 10, + SECBUFFER_READONLY = 0x80000000, + SECBUFFER_ATTRMASK = 0xf0000000, +} + +enum UNISP_NAME_A = "Microsoft Unified Security Protocol Provider"; +enum UNISP_NAME_W = "Microsoft Unified Security Protocol Provider"w; +enum SECBUFFER_VERSION = 0; + +alias UNICODE_STRING SECURITY_STRING; +alias UNICODE_STRING* PSECURITY_STRING; + +extern(Windows): + +struct SecHandle { + ULONG_PTR dwLower; + ULONG_PTR dwUpper; +} +alias SecHandle* PSecHandle; +struct SecBuffer { + ULONG cbBuffer; + ULONG BufferType; + PVOID pvBuffer; +} +alias SecBuffer* PSecBuffer; +alias SecHandle CredHandle; +alias PSecHandle PCredHandle; +alias SecHandle CtxtHandle; +alias PSecHandle PCtxtHandle; +struct SECURITY_INTEGER { + uint LowPart; + int HighPart; +} +alias SECURITY_INTEGER TimeStamp; +alias SECURITY_INTEGER* PTimeStamp; +struct SecBufferDesc { + ULONG ulVersion; + ULONG cBuffers; + PSecBuffer pBuffers; +} +alias SecBufferDesc* PSecBufferDesc; +struct SecPkgContext_StreamSizes { + ULONG cbHeader; + ULONG cbTrailer; + ULONG cbMaximumMessage; + ULONG cBuffers; + ULONG cbBlockSize; +} +alias SecPkgContext_StreamSizes* PSecPkgContext_StreamSizes; +struct SecPkgContext_Sizes { + ULONG cbMaxToken; + ULONG cbMaxSignature; + ULONG cbBlockSize; + ULONG cbSecurityTrailer; +} +alias SecPkgContext_Sizes* PSecPkgContext_Sizes; +struct SecPkgContext_AuthorityW { + SEC_WCHAR* sAuthorityName; +} +alias SecPkgContext_AuthorityW* PSecPkgContext_AuthorityW; +struct SecPkgContext_AuthorityA { + SEC_CHAR* sAuthorityName; +} +alias SecPkgContext_AuthorityA* PSecPkgContext_AuthorityA; +struct SecPkgContext_KeyInfoW { + SEC_WCHAR* sSignatureAlgorithmName; + SEC_WCHAR* sEncryptAlgorithmName; + ULONG KeySize; + ULONG SignatureAlgorithm; + ULONG EncryptAlgorithm; +} +alias SecPkgContext_KeyInfoW* PSecPkgContext_KeyInfoW; +struct SecPkgContext_KeyInfoA { + SEC_CHAR* sSignatureAlgorithmName; + SEC_CHAR* sEncryptAlgorithmName; + ULONG KeySize; + ULONG SignatureAlgorithm; + ULONG EncryptAlgorithm; +} +alias SecPkgContext_KeyInfoA* PSecPkgContext_KeyInfoA; +struct SecPkgContext_LifeSpan { + TimeStamp tsStart; + TimeStamp tsExpiry; +} +alias SecPkgContext_LifeSpan* PSecPkgContext_LifeSpan; +struct SecPkgContext_NamesW { + SEC_WCHAR* sUserName; +} +alias SecPkgContext_NamesW* PSecPkgContext_NamesW; +struct SecPkgContext_NamesA { + SEC_CHAR* sUserName; +} +alias SecPkgContext_NamesA* PSecPkgContext_NamesA; +struct SecPkgInfoW { + ULONG fCapabilities; + USHORT wVersion; + USHORT wRPCID; + ULONG cbMaxToken; + SEC_WCHAR* Name; + SEC_WCHAR* Comment; +} +alias SecPkgInfoW* PSecPkgInfoW; +struct SecPkgInfoA { + ULONG fCapabilities; + USHORT wVersion; + USHORT wRPCID; + ULONG cbMaxToken; + SEC_CHAR* Name; + SEC_CHAR* Comment; +} +alias SecPkgInfoA* PSecPkgInfoA; +/* supported only in win2k+, so it should be a PSecPkgInfoW */ +/* PSDK does not say it has ANSI/Unicode versions */ +struct SecPkgContext_PackageInfo { + PSecPkgInfoW PackageInfo; +} +alias SecPkgContext_PackageInfo* PSecPkgContext_PackageInfo; +struct SecPkgCredentials_NamesW { + SEC_WCHAR* sUserName; +} +alias SecPkgCredentials_NamesW* PSecPkgCredentials_NamesW; +struct SecPkgCredentials_NamesA { + SEC_CHAR* sUserName; +} +alias SecPkgCredentials_NamesA* PSecPkgCredentials_NamesA; + +/* TODO: missing type in SDK */ +alias void function() SEC_GET_KEY_FN; + +alias SECURITY_STATUS function(PULONG,PSecPkgInfoW*) ENUMERATE_SECURITY_PACKAGES_FN_W; +alias SECURITY_STATUS function(PULONG,PSecPkgInfoA*) ENUMERATE_SECURITY_PACKAGES_FN_A; +alias SECURITY_STATUS function(PCredHandle,ULONG,PVOID) QUERY_CREDENTIALS_ATTRIBUTES_FN_W; +alias SECURITY_STATUS function(PCredHandle,ULONG,PVOID) QUERY_CREDENTIALS_ATTRIBUTES_FN_A; +alias SECURITY_STATUS function(SEC_WCHAR*,SEC_WCHAR*,ULONG,PLUID,PVOID,SEC_GET_KEY_FN,PVOID,PCredHandle,PTimeStamp) ACQUIRE_CREDENTIALS_HANDLE_FN_W; +alias SECURITY_STATUS function(SEC_CHAR*,SEC_CHAR*,ULONG,PLUID,PVOID,SEC_GET_KEY_FN,PVOID,PCredHandle,PTimeStamp) ACQUIRE_CREDENTIALS_HANDLE_FN_A; +alias SECURITY_STATUS function(PCredHandle) FREE_CREDENTIALS_HANDLE_FN; +alias SECURITY_STATUS function(PCredHandle,PCtxtHandle,SEC_WCHAR*,ULONG,ULONG,ULONG,PSecBufferDesc,ULONG,PCtxtHandle,PSecBufferDesc,PULONG,PTimeStamp) INITIALIZE_SECURITY_CONTEXT_FN_W; +alias SECURITY_STATUS function(PCredHandle,PCtxtHandle,SEC_CHAR*,ULONG,ULONG,ULONG,PSecBufferDesc,ULONG,PCtxtHandle,PSecBufferDesc,PULONG,PTimeStamp) INITIALIZE_SECURITY_CONTEXT_FN_A; +alias SECURITY_STATUS function(PCredHandle,PCtxtHandle,PSecBufferDesc,ULONG,ULONG,PCtxtHandle,PSecBufferDesc,PULONG,PTimeStamp) ACCEPT_SECURITY_CONTEXT_FN; +alias SECURITY_STATUS function(PCtxtHandle,PSecBufferDesc) COMPLETE_AUTH_TOKEN_FN; +alias SECURITY_STATUS function(PCtxtHandle) DELETE_SECURITY_CONTEXT_FN; +alias SECURITY_STATUS function(PCtxtHandle,PSecBufferDesc) APPLY_CONTROL_TOKEN_FN_W; +alias SECURITY_STATUS function(PCtxtHandle,PSecBufferDesc) APPLY_CONTROL_TOKEN_FN_A; +alias SECURITY_STATUS function(PCtxtHandle,ULONG,PVOID) QUERY_CONTEXT_ATTRIBUTES_FN_A; +alias SECURITY_STATUS function(PCtxtHandle,ULONG,PVOID) QUERY_CONTEXT_ATTRIBUTES_FN_W; +alias SECURITY_STATUS function(PCtxtHandle) IMPERSONATE_SECURITY_CONTEXT_FN; +alias SECURITY_STATUS function(PCtxtHandle) REVERT_SECURITY_CONTEXT_FN; +alias SECURITY_STATUS function(PCtxtHandle,ULONG,PSecBufferDesc,ULONG) MAKE_SIGNATURE_FN; +alias SECURITY_STATUS function(PCtxtHandle,PSecBufferDesc,ULONG,PULONG) VERIFY_SIGNATURE_FN; +alias SECURITY_STATUS function(PVOID) FREE_CONTEXT_BUFFER_FN; +alias SECURITY_STATUS function(SEC_CHAR*,PSecPkgInfoA*) QUERY_SECURITY_PACKAGE_INFO_FN_A; +alias SECURITY_STATUS function(PCtxtHandle,HANDLE*) QUERY_SECURITY_CONTEXT_TOKEN_FN; +alias SECURITY_STATUS function(SEC_WCHAR*,PSecPkgInfoW*) QUERY_SECURITY_PACKAGE_INFO_FN_W; +alias SECURITY_STATUS function(PCtxtHandle,ULONG,PSecBufferDesc,ULONG) ENCRYPT_MESSAGE_FN; +alias SECURITY_STATUS function(PCtxtHandle,PSecBufferDesc,ULONG,PULONG) DECRYPT_MESSAGE_FN; + +/* No, it really is FreeCredentialsHandle, see the thread beginning + * http://sourceforge.net/mailarchive/message.php?msg_id=4321080 for a + * discovery discussion. */ +struct SecurityFunctionTableW{ + uint dwVersion; + ENUMERATE_SECURITY_PACKAGES_FN_W EnumerateSecurityPackagesW; + QUERY_CREDENTIALS_ATTRIBUTES_FN_W QueryCredentialsAttributesW; + ACQUIRE_CREDENTIALS_HANDLE_FN_W AcquireCredentialsHandleW; + FREE_CREDENTIALS_HANDLE_FN FreeCredentialsHandle; + void* Reserved2; + INITIALIZE_SECURITY_CONTEXT_FN_W InitializeSecurityContextW; + ACCEPT_SECURITY_CONTEXT_FN AcceptSecurityContext; + COMPLETE_AUTH_TOKEN_FN CompleteAuthToken; + DELETE_SECURITY_CONTEXT_FN DeleteSecurityContext; + APPLY_CONTROL_TOKEN_FN_W ApplyControlTokenW; + QUERY_CONTEXT_ATTRIBUTES_FN_W QueryContextAttributesW; + IMPERSONATE_SECURITY_CONTEXT_FN ImpersonateSecurityContext; + REVERT_SECURITY_CONTEXT_FN RevertSecurityContext; + MAKE_SIGNATURE_FN MakeSignature; + VERIFY_SIGNATURE_FN VerifySignature; + FREE_CONTEXT_BUFFER_FN FreeContextBuffer; + QUERY_SECURITY_PACKAGE_INFO_FN_W QuerySecurityPackageInfoW; + void* Reserved3; + void* Reserved4; + void* Reserved5; + void* Reserved6; + void* Reserved7; + void* Reserved8; + QUERY_SECURITY_CONTEXT_TOKEN_FN QuerySecurityContextToken; + ENCRYPT_MESSAGE_FN EncryptMessage; + DECRYPT_MESSAGE_FN DecryptMessage; +} +alias SecurityFunctionTableW* PSecurityFunctionTableW; +struct SecurityFunctionTableA{ + uint dwVersion; + ENUMERATE_SECURITY_PACKAGES_FN_A EnumerateSecurityPackagesA; + QUERY_CREDENTIALS_ATTRIBUTES_FN_A QueryCredentialsAttributesA; + ACQUIRE_CREDENTIALS_HANDLE_FN_A AcquireCredentialsHandleA; + FREE_CREDENTIALS_HANDLE_FN FreeCredentialsHandle; + void* Reserved2; + INITIALIZE_SECURITY_CONTEXT_FN_A InitializeSecurityContextA; + ACCEPT_SECURITY_CONTEXT_FN AcceptSecurityContext; + COMPLETE_AUTH_TOKEN_FN CompleteAuthToken; + DELETE_SECURITY_CONTEXT_FN DeleteSecurityContext; + APPLY_CONTROL_TOKEN_FN_A ApplyControlTokenA; + QUERY_CONTEXT_ATTRIBUTES_FN_A QueryContextAttributesA; + IMPERSONATE_SECURITY_CONTEXT_FN ImpersonateSecurityContext; + REVERT_SECURITY_CONTEXT_FN RevertSecurityContext; + MAKE_SIGNATURE_FN MakeSignature; + VERIFY_SIGNATURE_FN VerifySignature; + FREE_CONTEXT_BUFFER_FN FreeContextBuffer; + QUERY_SECURITY_PACKAGE_INFO_FN_A QuerySecurityPackageInfoA; + void* Reserved3; + void* Reserved4; + void* Unknown1; + void* Unknown2; + void* Unknown3; + void* Unknown4; + void* Unknown5; + ENCRYPT_MESSAGE_FN EncryptMessage; + DECRYPT_MESSAGE_FN DecryptMessage; +} +alias SecurityFunctionTableA* PSecurityFunctionTableA; +alias PSecurityFunctionTableA function() INIT_SECURITY_INTERFACE_A; +alias PSecurityFunctionTableW function() INIT_SECURITY_INTERFACE_W; + +SECURITY_STATUS FreeCredentialsHandle(PCredHandle); +SECURITY_STATUS EnumerateSecurityPackagesA(PULONG,PSecPkgInfoA*); +SECURITY_STATUS EnumerateSecurityPackagesW(PULONG,PSecPkgInfoW*); +SECURITY_STATUS AcquireCredentialsHandleA(SEC_CHAR*,SEC_CHAR*,ULONG,PLUID,PVOID,SEC_GET_KEY_FN,PVOID,PCredHandle,PTimeStamp); +SECURITY_STATUS AcquireCredentialsHandleW(SEC_WCHAR*,SEC_WCHAR*,ULONG,PLUID,PVOID,SEC_GET_KEY_FN,PVOID,PCredHandle,PTimeStamp); +SECURITY_STATUS AcceptSecurityContext(PCredHandle,PCtxtHandle,PSecBufferDesc,ULONG,ULONG,PCtxtHandle,PSecBufferDesc,PULONG,PTimeStamp); +SECURITY_STATUS InitializeSecurityContextA(PCredHandle,PCtxtHandle,SEC_CHAR*,ULONG,ULONG,ULONG,PSecBufferDesc,ULONG,PCtxtHandle,PSecBufferDesc,PULONG,PTimeStamp); +SECURITY_STATUS InitializeSecurityContextW(PCredHandle,PCtxtHandle,SEC_WCHAR*,ULONG,ULONG,ULONG,PSecBufferDesc,ULONG,PCtxtHandle,PSecBufferDesc,PULONG,PTimeStamp); +SECURITY_STATUS FreeContextBuffer(PVOID); +SECURITY_STATUS QueryContextAttributesA(PCtxtHandle,ULONG,PVOID); +SECURITY_STATUS QueryContextAttributesW(PCtxtHandle,ULONG,PVOID); +SECURITY_STATUS QueryCredentialsAttributesA(PCredHandle,ULONG,PVOID); +SECURITY_STATUS QueryCredentialsAttributesW(PCredHandle,ULONG,PVOID); +static if (_WIN32_WINNT >= 0x500){ + SECURITY_STATUS QuerySecurityContextToken(PCtxtHandle,HANDLE*); +} +SECURITY_STATUS DecryptMessage(PCtxtHandle,PSecBufferDesc,ULONG,PULONG); +SECURITY_STATUS EncryptMessage(PCtxtHandle,ULONG,PSecBufferDesc,ULONG); +SECURITY_STATUS DeleteSecurityContext(PCtxtHandle); +SECURITY_STATUS CompleteAuthToken(PCtxtHandle,PSecBufferDesc); +SECURITY_STATUS ApplyControlTokenA(PCtxtHandle,PSecBufferDesc); +SECURITY_STATUS ApplyControlTokenW(PCtxtHandle,PSecBufferDesc); +SECURITY_STATUS ImpersonateSecurityContext(PCtxtHandle); +SECURITY_STATUS RevertSecurityContext(PCtxtHandle); +SECURITY_STATUS MakeSignature(PCtxtHandle,ULONG,PSecBufferDesc,ULONG); +SECURITY_STATUS VerifySignature(PCtxtHandle,PSecBufferDesc,ULONG,PULONG); +SECURITY_STATUS QuerySecurityPackageInfoA(SEC_CHAR*,PSecPkgInfoA*); +SECURITY_STATUS QuerySecurityPackageInfoW(SEC_WCHAR*,PSecPkgInfoW*); +PSecurityFunctionTableA InitSecurityInterfaceA(); +PSecurityFunctionTableW InitSecurityInterfaceW(); + +version (Unicode) { + alias UNISP_NAME_W UNISP_NAME; + alias SecPkgInfoW SecPkgInfo; + alias PSecPkgInfoW PSecPkgInfo; + alias SecPkgCredentials_NamesW SecPkgCredentials_Names; + alias PSecPkgCredentials_NamesW PSecPkgCredentials_Names; + alias SecPkgContext_AuthorityW SecPkgContext_Authority; + alias PSecPkgContext_AuthorityW PSecPkgContext_Authority; + alias SecPkgContext_KeyInfoW SecPkgContext_KeyInfo; + alias PSecPkgContext_KeyInfoW PSecPkgContext_KeyInfo; + alias SecPkgContext_NamesW SecPkgContext_Names; + alias PSecPkgContext_NamesW PSecPkgContext_Names; + alias SecurityFunctionTableW SecurityFunctionTable; + alias PSecurityFunctionTableW PSecurityFunctionTable; + alias AcquireCredentialsHandleW AcquireCredentialsHandle; + alias EnumerateSecurityPackagesW EnumerateSecurityPackages; + alias InitializeSecurityContextW InitializeSecurityContext; + alias QueryContextAttributesW QueryContextAttributes; + alias QueryCredentialsAttributesW QueryCredentialsAttributes; + alias QuerySecurityPackageInfoW QuerySecurityPackageInfo; + alias ApplyControlTokenW ApplyControlToken; + alias ENUMERATE_SECURITY_PACKAGES_FN_W ENUMERATE_SECURITY_PACKAGES_FN; + alias QUERY_CREDENTIALS_ATTRIBUTES_FN_W QUERY_CREDENTIALS_ATTRIBUTES_FN; + alias ACQUIRE_CREDENTIALS_HANDLE_FN_W ACQUIRE_CREDENTIALS_HANDLE_FN; + alias INITIALIZE_SECURITY_CONTEXT_FN_W INITIALIZE_SECURITY_CONTEXT_FN; + alias APPLY_CONTROL_TOKEN_FN_W APPLY_CONTROL_TOKEN_FN; + alias QUERY_CONTEXT_ATTRIBUTES_FN_W QUERY_CONTEXT_ATTRIBUTES_FN; + alias QUERY_SECURITY_PACKAGE_INFO_FN_W QUERY_SECURITY_PACKAGE_INFO_FN; + alias INIT_SECURITY_INTERFACE_W INIT_SECURITY_INTERFACE; +}else{ + alias UNISP_NAME_A UNISP_NAME; + alias SecPkgInfoA SecPkgInfo; + alias PSecPkgInfoA PSecPkgInfo; + alias SecPkgCredentials_NamesA SecPkgCredentials_Names; + alias PSecPkgCredentials_NamesA PSecPkgCredentials_Names; + alias SecPkgContext_AuthorityA SecPkgContext_Authority; + alias PSecPkgContext_AuthorityA PSecPkgContext_Authority; + alias SecPkgContext_KeyInfoA SecPkgContext_KeyInfo; + alias PSecPkgContext_KeyInfoA PSecPkgContext_KeyInfo; + alias SecPkgContext_NamesA SecPkgContext_Names; + alias PSecPkgContext_NamesA PSecPkgContext_Names; + alias SecurityFunctionTableA SecurityFunctionTable; + alias PSecurityFunctionTableA PSecurityFunctionTable; + alias AcquireCredentialsHandleA AcquireCredentialsHandle; + alias EnumerateSecurityPackagesA EnumerateSecurityPackages; + alias InitializeSecurityContextA InitializeSecurityContext; + alias QueryContextAttributesA QueryContextAttributes; + alias QueryCredentialsAttributesA QueryCredentialsAttributes; + alias QuerySecurityPackageInfoA QuerySecurityPackageInfo; + alias ApplyControlTokenA ApplyControlToken; + alias ENUMERATE_SECURITY_PACKAGES_FN_A ENUMERATE_SECURITY_PACKAGES_FN; + alias QUERY_CREDENTIALS_ATTRIBUTES_FN_A QUERY_CREDENTIALS_ATTRIBUTES_FN; + alias ACQUIRE_CREDENTIALS_HANDLE_FN_A ACQUIRE_CREDENTIALS_HANDLE_FN; + alias INITIALIZE_SECURITY_CONTEXT_FN_A INITIALIZE_SECURITY_CONTEXT_FN; + alias APPLY_CONTROL_TOKEN_FN_A APPLY_CONTROL_TOKEN_FN; + alias QUERY_CONTEXT_ATTRIBUTES_FN_A QUERY_CONTEXT_ATTRIBUTES_FN; + alias QUERY_SECURITY_PACKAGE_INFO_FN_A QUERY_SECURITY_PACKAGE_INFO_FN; + alias INIT_SECURITY_INTERFACE_A INIT_SECURITY_INTERFACE; +} diff --git a/src/urt/internal/sys/windows/subauth.d b/src/urt/internal/sys/windows/subauth.d new file mode 100644 index 0000000..fc43416 --- /dev/null +++ b/src/urt/internal/sys/windows/subauth.d @@ -0,0 +1,275 @@ +/** + * Windows API header module + * + * Translated from MinGW Windows headers + * + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(DRUNTIMESRC core/sys/windows/_subauth.d) + */ +module urt.internal.sys.windows.subauth; +version (Windows): + +import urt.internal.sys.windows.ntdef, urt.internal.sys.windows.windef; + +/+ +alias LONG NTSTATUS; +alias NTSTATUS* PNTSTATUS; ++/ + +enum : ULONG { + MSV1_0_PASSTHRU = 1, + MSV1_0_GUEST_LOGON = 2 +} + +// USER_ALL_INFORMATION.WhichFields (Undocumented) +enum ULONG + MSV1_0_VALIDATION_LOGOFF_TIME = 1, + MSV1_0_VALIDATION_KICKOFF_TIME = 2, + MSV1_0_VALIDATION_LOGON_SERVER = 4, + MSV1_0_VALIDATION_LOGON_DOMAIN = 8, + MSV1_0_VALIDATION_SESSION_KEY = 16, + MSV1_0_VALIDATION_USER_FLAGS = 32, + MSV1_0_VALIDATION_USER_ID = 64; + +// ?ActionsPerformed? (Undocumented) +enum MSV1_0_SUBAUTH_ACCOUNT_DISABLED = 1; +enum MSV1_0_SUBAUTH_PASSWORD = 2; +enum MSV1_0_SUBAUTH_WORKSTATIONS = 4; +enum MSV1_0_SUBAUTH_LOGON_HOURS = 8; +enum MSV1_0_SUBAUTH_ACCOUNT_EXPIRY = 16; +enum MSV1_0_SUBAUTH_PASSWORD_EXPIRY = 32; +enum MSV1_0_SUBAUTH_ACCOUNT_TYPE = 64; +enum MSV1_0_SUBAUTH_LOCKOUT = 128; + +enum NEXT_FREE_ACCOUNT_CONTROL_BIT = 131072; + +enum SAM_DAYS_PER_WEEK = 7; +enum SAM_HOURS_PER_WEEK = 168; +enum SAM_MINUTES_PER_WEEK = 10080; + +enum : NTSTATUS { + STATUS_SUCCESS = 0, + STATUS_INVALID_INFO_CLASS = 0xC0000003, + STATUS_NO_SUCH_USER = 0xC0000064, + STATUS_WRONG_PASSWORD = 0xC000006A, + STATUS_PASSWORD_RESTRICTION = 0xC000006C, + STATUS_LOGON_FAILURE = 0xC000006D, + STATUS_ACCOUNT_RESTRICTION = 0xC000006E, + STATUS_INVALID_LOGON_HOURS = 0xC000006F, + STATUS_INVALID_WORKSTATION = 0xC0000070, + STATUS_PASSWORD_EXPIRED = 0xC0000071, + STATUS_ACCOUNT_DISABLED = 0xC0000072, + STATUS_INSUFFICIENT_RESOURCES = 0xC000009A, + STATUS_ACCOUNT_EXPIRED = 0xC0000193, + STATUS_PASSWORD_MUST_CHANGE = 0xC0000224, + STATUS_ACCOUNT_LOCKED_OUT = 0xC0000234 +} + +// Note: undocumented in MSDN +// USER_ALL_INFORMATION.UserAccountControl +enum ULONG + USER_ACCOUNT_DISABLED = 1, + USER_HOME_DIRECTORY_REQUIRED = 2, + USER_PASSWORD_NOT_REQUIRED = 4, + USER_TEMP_DUPLICATE_ACCOUNT = 8, + USER_NORMAL_ACCOUNT = 16, + USER_MNS_LOGON_ACCOUNT = 32, + USER_INTERDOMAIN_TRUST_ACCOUNT = 64, + USER_WORKSTATION_TRUST_ACCOUNT = 128, + USER_SERVER_TRUST_ACCOUNT = 256, + USER_DONT_EXPIRE_PASSWORD = 512, + USER_ACCOUNT_AUTO_LOCKED = 1024, + USER_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 2048, + USER_SMARTCARD_REQUIRED = 4096, + USER_TRUSTED_FOR_DELEGATION = 8192, + USER_NOT_DELEGATED = 16384, + USER_USE_DES_KEY_ONLY = 32768, + USER_DONT_REQUIRE_PREAUTH = 65536, + + USER_MACHINE_ACCOUNT_MASK = 448, + USER_ACCOUNT_TYPE_MASK = 472, + USER_ALL_PARAMETERS = 2097152; + +/+ +struct UNICODE_STRING { + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; +} +alias UNICODE_STRING* PUNICODE_STRING; + +struct STRING { + USHORT Length; + USHORT MaximumLength; + PCHAR Buffer; +} +alias STRING* PSTRING; ++/ + +alias SAM_HANDLE = HANDLE; +alias SAM_HANDLE* PSAM_HANDLE; + +struct OLD_LARGE_INTEGER { + ULONG LowPart; + LONG HighPart; +} +alias OLD_LARGE_INTEGER* POLD_LARGE_INTEGER; + +enum NETLOGON_LOGON_INFO_CLASS { + NetlogonInteractiveInformation = 1, + NetlogonNetworkInformation, + NetlogonServiceInformation, + NetlogonGenericInformation, + NetlogonInteractiveTransitiveInformation, + NetlogonNetworkTransitiveInformation, + NetlogonServiceTransitiveInformation +} + + +enum CYPHER_BLOCK_LENGTH = 8; +enum USER_SESSION_KEY_LENGTH = CYPHER_BLOCK_LENGTH * 2; +enum CLEAR_BLOCK_LENGTH = 8; + +struct CYPHER_BLOCK { + CHAR[CYPHER_BLOCK_LENGTH] data = 0; +} +alias CYPHER_BLOCK* PCYPHER_BLOCK; + +struct CLEAR_BLOCK { + CHAR[CLEAR_BLOCK_LENGTH] data = 0; +} +alias CLEAR_BLOCK* PCLEAR_BLOCK; + +struct LM_OWF_PASSWORD { + CYPHER_BLOCK[2] data; +} +alias LM_OWF_PASSWORD* PLM_OWF_PASSWORD; + +struct USER_SESSION_KEY { + CYPHER_BLOCK[2] data; +} +alias USER_SESSION_KEY* PUSER_SESSION_KEY; + +alias CLEAR_BLOCK LM_CHALLENGE; +alias LM_CHALLENGE* PLM_CHALLENGE; + +alias LM_OWF_PASSWORD NT_OWF_PASSWORD; +alias NT_OWF_PASSWORD* PNT_OWF_PASSWORD; +alias LM_CHALLENGE NT_CHALLENGE; +alias NT_CHALLENGE* PNT_CHALLENGE; + +struct LOGON_HOURS { + USHORT UnitsPerWeek; + PUCHAR LogonHours; +} +alias LOGON_HOURS* PLOGON_HOURS; + +struct SR_SECURITY_DESCRIPTOR { + ULONG Length; + PUCHAR SecurityDescriptor; +} +alias SR_SECURITY_DESCRIPTOR* PSR_SECURITY_DESCRIPTOR; + +align(4): +struct USER_ALL_INFORMATION { + LARGE_INTEGER LastLogon; + LARGE_INTEGER LastLogoff; + LARGE_INTEGER PasswordLastSet; + LARGE_INTEGER AccountExpires; + LARGE_INTEGER PasswordCanChange; + LARGE_INTEGER PasswordMustChange; + UNICODE_STRING UserName; + UNICODE_STRING FullName; + UNICODE_STRING HomeDirectory; + UNICODE_STRING HomeDirectoryDrive; + UNICODE_STRING ScriptPath; + UNICODE_STRING ProfilePath; + UNICODE_STRING AdminComment; + UNICODE_STRING WorkStations; + UNICODE_STRING UserComment; + UNICODE_STRING Parameters; + UNICODE_STRING LmPassword; + UNICODE_STRING NtPassword; + UNICODE_STRING PrivateData; + SR_SECURITY_DESCRIPTOR SecurityDescriptor; + ULONG UserId; + ULONG PrimaryGroupId; + ULONG UserAccountControl; + ULONG WhichFields; + LOGON_HOURS LogonHours; + USHORT BadPasswordCount; + USHORT LogonCount; + USHORT CountryCode; + USHORT CodePage; + BOOLEAN LmPasswordPresent; + BOOLEAN NtPasswordPresent; + BOOLEAN PasswordExpired; + BOOLEAN PrivateDataSensitive; +} +alias USER_ALL_INFORMATION* PUSER_ALL_INFORMATION; +align: + +struct MSV1_0_VALIDATION_INFO { + LARGE_INTEGER LogoffTime; + LARGE_INTEGER KickoffTime; + UNICODE_STRING LogonServer; + UNICODE_STRING LogonDomainName; + USER_SESSION_KEY SessionKey; + BOOLEAN Authoritative; + ULONG UserFlags; + ULONG WhichFields; + ULONG UserId; +} +alias MSV1_0_VALIDATION_INFO* PMSV1_0_VALIDATION_INFO; + +struct NETLOGON_LOGON_IDENTITY_INFO { + UNICODE_STRING LogonDomainName; + ULONG ParameterControl; + OLD_LARGE_INTEGER LogonId; + UNICODE_STRING UserName; + UNICODE_STRING Workstation; +} +alias NETLOGON_LOGON_IDENTITY_INFO* PNETLOGON_LOGON_IDENTITY_INFO; + +struct NETLOGON_INTERACTIVE_INFO { + NETLOGON_LOGON_IDENTITY_INFO Identity; + LM_OWF_PASSWORD LmOwfPassword; + NT_OWF_PASSWORD NtOwfPassword; +} +alias NETLOGON_INTERACTIVE_INFO* PNETLOGON_INTERACTIVE_INFO; + +struct NETLOGON_GENERIC_INFO { + NETLOGON_LOGON_IDENTITY_INFO Identity; + UNICODE_STRING PackageName; + ULONG DataLength; + PUCHAR LogonData; +} +alias NETLOGON_GENERIC_INFO* PNETLOGON_GENERIC_INFO; + +struct NETLOGON_NETWORK_INFO { + NETLOGON_LOGON_IDENTITY_INFO Identity; + LM_CHALLENGE LmChallenge; + STRING NtChallengeResponse; + STRING LmChallengeResponse; +} +alias NETLOGON_NETWORK_INFO* PNETLOGON_NETWORK_INFO; + +struct NETLOGON_SERVICE_INFO { + NETLOGON_LOGON_IDENTITY_INFO Identity; + LM_OWF_PASSWORD LmOwfPassword; + NT_OWF_PASSWORD NtOwfPassword; +} +alias NETLOGON_SERVICE_INFO* PNETLOGON_SERVICE_INFO; + +extern (Windows) { +NTSTATUS Msv1_0SubAuthenticationRoutine(NETLOGON_LOGON_INFO_CLASS,PVOID, + ULONG,PUSER_ALL_INFORMATION,PULONG,PULONG, + PBOOLEAN,PLARGE_INTEGER,PLARGE_INTEGER); +NTSTATUS Msv1_0SubAuthenticationFilter(NETLOGON_LOGON_INFO_CLASS,PVOID, + ULONG,PUSER_ALL_INFORMATION,PULONG,PULONG, + PBOOLEAN,PLARGE_INTEGER,PLARGE_INTEGER); +NTSTATUS Msv1_0SubAuthenticationRoutineGeneric(PVOID,ULONG,PULONG,PVOID*); +NTSTATUS Msv1_0SubAuthenticationRoutineEx(NETLOGON_LOGON_INFO_CLASS,PVOID, + ULONG,PUSER_ALL_INFORMATION,SAM_HANDLE, + PMSV1_0_VALIDATION_INFO,PULONG); +} diff --git a/src/urt/internal/sys/windows/w32api.d b/src/urt/internal/sys/windows/w32api.d new file mode 100644 index 0000000..94ed9ac --- /dev/null +++ b/src/urt/internal/sys/windows/w32api.d @@ -0,0 +1,138 @@ +/** + * Windows API header module + * + * Translated from MinGW API for MS-Windows 4.0 + * + * Authors: Stewart Gordon + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(DRUNTIMESRC core/sys/windows/_w32api.d) + */ +module urt.internal.sys.windows.w32api; +version (Windows): + +import urt.internal.sys.windows.sdkddkver; + +version (ANSI) {} else version = Unicode; + +enum __W32API_VERSION = 3.17; +enum __W32API_MAJOR_VERSION = 3; +enum __W32API_MINOR_VERSION = 17; + +enum Windows95 = 0x0400; +enum Windows98 = 0x0410; +enum WindowsME = 0x0500; + +enum WindowsNT4 = 0x0400; +enum Windows2000 = 0x0500; +enum WindowsXP = 0x0501; +enum Windows2003 = 0x0502; +enum WindowsVista = 0x0600; +enum Windows7 = 0x0601; +enum Windows8 = 0x0602; + +enum IE3 = 0x0300; +enum IE301 = 0x0300; +enum IE302 = 0x0300; +enum IE4 = 0x0400; +enum IE401 = 0x0401; +enum IE5 = 0x0500; +enum IE5a = 0x0500; +enum IE5b = 0x0500; +enum IE501 = 0x0501; +enum IE55 = 0x0501; +enum IE56 = 0x0560; +enum IE6 = 0x0600; +enum IE601 = 0x0601; +enum IE602 = 0x0603; +enum IE7 = 0x0700; +enum IE8 = 0x0800; +enum IE9 = 0x0900; +enum IE10 = 0x0A00; + +/* These version identifiers are used to specify the minimum version of Windows that an + * application will support. + * + * Previously the minimum Windows 9x and Windows NT versions could be specified. However, since + * Windows 9x is no longer supported, either by Microsoft or by DMD, this distinction has been + * removed in order to simplify the bindings. + */ +version (Windows11) { + enum uint _WIN32_WINNT = _WIN32_WINNT_WIN10; +} else version (Windows10) { + enum uint _WIN32_WINNT = _WIN32_WINNT_WIN10; +} else version (Windows8_1) { // also Windows2012R2 + enum uint _WIN32_WINNT = _WIN32_WINNT_WINBLUE; +} else version (Windows8) { // also Windows2012 + enum uint _WIN32_WINNT = _WIN32_WINNT_WIN8; +} else version (Windows7) { // also Windows2008R2 + enum uint _WIN32_WINNT = _WIN32_WINNT_WIN7; +} else version (WindowsVista) { // also Windows2008 + enum uint _WIN32_WINNT = _WIN32_WINNT_VISTA; +} else version (Windows2003) { // also WindowsHomeServer, WindowsXP64 + enum uint _WIN32_WINNT = _WIN32_WINNT_WS03; +} else version (WindowsXP) { + enum uint _WIN32_WINNT = _WIN32_WINNT_WINXP; +} else version (Windows2000) { + // Current DMD doesn't support any version of Windows older than XP, + // but third-party compilers could use this + enum uint _WIN32_WINNT = _WIN32_WINNT_WIN2K; +} else { + enum uint _WIN32_WINNT = _WIN32_WINNT_WIN7; +} + +version (IE11) { + enum uint _WIN32_IE = _WIN32_IE_IE110; +} else version (IE10) { + enum uint _WIN32_IE = _WIN32_IE_IE100; +} else version (IE9) { + enum uint _WIN32_IE = _WIN32_IE_IE90; +} else version (IE8) { + enum uint _WIN32_IE = _WIN32_IE_IE80; +} else version (IE7) { + enum uint _WIN32_IE = _WIN32_IE_IE70; +} else version (IE602) { + enum uint _WIN32_IE = _WIN32_IE_IE60SP2; +} else version (IE601) { + enum uint _WIN32_IE = _WIN32_IE_IE60SP1; +} else version (IE6) { + enum uint _WIN32_IE = _WIN32_IE_IE60; +} else version (IE56) { + enum uint _WIN32_IE = _WIN32_IE_IE60; +} else version (IE55) { + enum uint _WIN32_IE = _WIN32_IE_IE55; +} else version (IE501) { + enum uint _WIN32_IE = _WIN32_IE_IE501; +} else version (IE5) { + enum uint _WIN32_IE = _WIN32_IE_IE50; +} else version (IE401) { + enum uint _WIN32_IE = _WIN32_IE_IE401; +} else version (IE4) { + enum uint _WIN32_IE = _WIN32_IE_IE40; +} else version (IE3) { + enum uint _WIN32_IE = _WIN32_IE_IE30; +} else static if (_WIN32_WINNT >= _WIN32_WINNT_WIN2K) { + enum uint _WIN32_IE = _WIN32_IE_IE60; +} else static if (_WIN32_WINNT >= Windows98) { //NOTE: _WIN32_WINNT will never be set this low + enum uint _WIN32_IE = _WIN32_IE_IE40; +} else { + enum uint _WIN32_IE = 0; +} + +debug (WindowsUnitTest) { + unittest { + printf("Windows NT version: %03x\n", _WIN32_WINNT); + printf("IE version: %03x\n", _WIN32_IE); + } +} + +version (Unicode) { + enum bool _WIN32_UNICODE = true; + package template DECLARE_AW(string name) { + mixin("alias " ~ name ~ "W " ~ name ~ ";"); + } +} else { + enum bool _WIN32_UNICODE = false; + package template DECLARE_AW(string name) { + mixin("alias " ~ name ~ "A " ~ name ~ ";"); + } +} diff --git a/src/urt/internal/sys/windows/winbase.d b/src/urt/internal/sys/windows/winbase.d new file mode 100644 index 0000000..59d208c --- /dev/null +++ b/src/urt/internal/sys/windows/winbase.d @@ -0,0 +1,2941 @@ +/** + * Windows API header module + * + * Translated from MinGW API for MS-Windows 3.10 + * + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(DRUNTIMESRC core/sys/windows/_winbase.d) + */ +module urt.internal.sys.windows.winbase; +version (Windows): + +version (ANSI) {} else version = Unicode; +pragma(lib, "kernel32"); + +/** +Translation Notes: +The following macros are obsolete, and have no effect. + +LockSegment(w), MakeProcInstance(p, i), UnlockResource(h), UnlockSegment(w) +FreeModule(m), FreeProcInstance(p), GetFreeSpace(w), DefineHandleTable(w) +SetSwapAreaSize(w), LimitEmsPages(n), Yield() + +// These are not required for DMD. + +//FIXME: +// #ifndef UNDER_CE + int WinMain(HINSTANCE, HINSTANCE, LPSTR, int); +#else + int WinMain(HINSTANCE, HINSTANCE, LPWSTR, int); +#endif +int wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int); + +*/ + +import urt.internal.sys.windows.windef; +import urt.internal.sys.windows.basetyps, urt.internal.sys.windows.w32api, urt.internal.sys.windows.winnt; + +// FIXME: +//alias void va_list; +//import urt.internal.stdc : va_list; +import urt.mem : memset, memcpy, memmove; + + +// COMMPROP structure, used by GetCommProperties() +// ----------------------------------------------- + +// Communications provider type +enum : DWORD { + PST_UNSPECIFIED, + PST_RS232, + PST_PARALLELPORT, + PST_RS422, + PST_RS423, + PST_RS449, + PST_MODEM, // = 6 + PST_FAX = 0x0021, + PST_SCANNER = 0x0022, + PST_NETWORK_BRIDGE = 0x0100, + PST_LAT = 0x0101, + PST_TCPIP_TELNET = 0x0102, + PST_X25 = 0x0103 +} + +// Max baud rate +enum : DWORD { + BAUD_075 = 0x00000001, + BAUD_110 = 0x00000002, + BAUD_134_5 = 0x00000004, + BAUD_150 = 0x00000008, + BAUD_300 = 0x00000010, + BAUD_600 = 0x00000020, + BAUD_1200 = 0x00000040, + BAUD_1800 = 0x00000080, + BAUD_2400 = 0x00000100, + BAUD_4800 = 0x00000200, + BAUD_7200 = 0x00000400, + BAUD_9600 = 0x00000800, + BAUD_14400 = 0x00001000, + BAUD_19200 = 0x00002000, + BAUD_38400 = 0x00004000, + BAUD_56K = 0x00008000, + BAUD_128K = 0x00010000, + BAUD_115200 = 0x00020000, + BAUD_57600 = 0x00040000, + BAUD_USER = 0x10000000 +} + +// Comm capabilities +enum : DWORD { + PCF_DTRDSR = 0x0001, + PCF_RTSCTS = 0x0002, + PCF_RLSD = 0x0004, + PCF_PARITY_CHECK = 0x0008, + PCF_XONXOFF = 0x0010, + PCF_SETXCHAR = 0x0020, + PCF_TOTALTIMEOUTS = 0x0040, + PCF_INTTIMEOUTS = 0x0080, + PCF_SPECIALCHARS = 0x0100, + PCF_16BITMODE = 0x0200 +} + +enum : DWORD { + SP_PARITY = 1, + SP_BAUD = 2, + SP_DATABITS = 4, + SP_STOPBITS = 8, + SP_HANDSHAKING = 16, + SP_PARITY_CHECK = 32, + SP_RLSD = 64 +} + +enum : DWORD { + DATABITS_5 = 1, + DATABITS_6 = 2, + DATABITS_7 = 4, + DATABITS_8 = 8, + DATABITS_16 = 16, + DATABITS_16X = 32 +} + +enum : WORD { + STOPBITS_10 = 0x0001, + STOPBITS_15 = 0x0002, + STOPBITS_20 = 0x0004, + PARITY_NONE = 0x0100, + PARITY_ODD = 0x0200, + PARITY_EVEN = 0x0400, + PARITY_MARK = 0x0800, + PARITY_SPACE = 0x1000 +} + +// used by dwServiceMask +enum SP_SERIALCOMM = 1; + +struct COMMPROP { + WORD wPacketLength; + WORD wPacketVersion; + DWORD dwServiceMask; + DWORD dwReserved1; + DWORD dwMaxTxQueue; + DWORD dwMaxRxQueue; + DWORD dwMaxBaud; + DWORD dwProvSubType; + DWORD dwProvCapabilities; + DWORD dwSettableParams; + DWORD dwSettableBaud; + WORD wSettableData; + WORD wSettableStopParity; + DWORD dwCurrentTxQueue; + DWORD dwCurrentRxQueue; + DWORD dwProvSpec1; + DWORD dwProvSpec2; + WCHAR _wcProvChar = 0; + + WCHAR* wcProvChar() return { return &_wcProvChar; } +} +alias COMMPROP* LPCOMMPROP; + +// ---------- + +// for DEBUG_EVENT +enum : DWORD { + EXCEPTION_DEBUG_EVENT = 1, + CREATE_THREAD_DEBUG_EVENT, + CREATE_PROCESS_DEBUG_EVENT, + EXIT_THREAD_DEBUG_EVENT, + EXIT_PROCESS_DEBUG_EVENT, + LOAD_DLL_DEBUG_EVENT, + UNLOAD_DLL_DEBUG_EVENT, + OUTPUT_DEBUG_STRING_EVENT, + RIP_EVENT +} + +enum HFILE HFILE_ERROR = cast(HFILE) (-1); + +// for SetFilePointer() +enum : DWORD { + FILE_BEGIN = 0, + FILE_CURRENT = 1, + FILE_END = 2 +} +enum DWORD INVALID_SET_FILE_POINTER = -1; + + +// for OpenFile() +deprecated enum : UINT { + OF_READ = 0, + OF_WRITE = 0x0001, + OF_READWRITE = 0x0002, + OF_SHARE_COMPAT = 0, + OF_SHARE_EXCLUSIVE = 0x0010, + OF_SHARE_DENY_WRITE = 0x0020, + OF_SHARE_DENY_READ = 0x0030, + OF_SHARE_DENY_NONE = 0x0040, + OF_PARSE = 0x0100, + OF_DELETE = 0x0200, + OF_VERIFY = 0x0400, + OF_CANCEL = 0x0800, + OF_CREATE = 0x1000, + OF_PROMPT = 0x2000, + OF_EXIST = 0x4000, + OF_REOPEN = 0x8000 +} + +enum : DWORD { + NMPWAIT_NOWAIT = 1, + NMPWAIT_WAIT_FOREVER = -1, + NMPWAIT_USE_DEFAULT_WAIT = 0 +} + +// for ClearCommError() +enum DWORD + CE_RXOVER = 0x0001, + CE_OVERRUN = 0x0002, + CE_RXPARITY = 0x0004, + CE_FRAME = 0x0008, + CE_BREAK = 0x0010, + CE_TXFULL = 0x0100, + CE_PTO = 0x0200, + CE_IOE = 0x0400, + CE_DNS = 0x0800, + CE_OOP = 0x1000, + CE_MODE = 0x8000; + +// for CopyProgressRoutine callback. +enum : DWORD { + PROGRESS_CONTINUE = 0, + PROGRESS_CANCEL = 1, + PROGRESS_STOP = 2, + PROGRESS_QUIET = 3 +} + +enum : DWORD { + CALLBACK_CHUNK_FINISHED = 0, + CALLBACK_STREAM_SWITCH = 1 +} + +// CopyFileEx() +enum : DWORD { + COPY_FILE_FAIL_IF_EXISTS = 1, + COPY_FILE_RESTARTABLE = 2 +} + +enum : DWORD { + FILE_MAP_COPY = 1, + FILE_MAP_WRITE = 2, + FILE_MAP_READ = 4, + FILE_MAP_ALL_ACCESS = 0x000F001F +} + +enum : DWORD { + MUTEX_ALL_ACCESS = 0x001f0001, + MUTEX_MODIFY_STATE = 0x00000001, + SEMAPHORE_ALL_ACCESS = 0x001f0003, + SEMAPHORE_MODIFY_STATE = 0x00000002, + EVENT_ALL_ACCESS = 0x001f0003, + EVENT_MODIFY_STATE = 0x00000002 +} + +// CreateNamedPipe() +enum : DWORD { + PIPE_ACCESS_INBOUND = 1, + PIPE_ACCESS_OUTBOUND = 2, + PIPE_ACCESS_DUPLEX = 3 +} + +enum DWORD + PIPE_TYPE_BYTE = 0, + PIPE_TYPE_MESSAGE = 4, + PIPE_READMODE_BYTE = 0, + PIPE_READMODE_MESSAGE = 2, + PIPE_WAIT = 0, + PIPE_NOWAIT = 1; + +// GetNamedPipeInfo() +enum DWORD + PIPE_CLIENT_END = 0, + PIPE_SERVER_END = 1; + +enum DWORD PIPE_UNLIMITED_INSTANCES = 255; + +// dwCreationFlags for CreateProcess() and CreateProcessAsUser() +enum : DWORD { + DEBUG_PROCESS = 0x00000001, + DEBUG_ONLY_THIS_PROCESS = 0x00000002, + CREATE_SUSPENDED = 0x00000004, + DETACHED_PROCESS = 0x00000008, + CREATE_NEW_CONSOLE = 0x00000010, + NORMAL_PRIORITY_CLASS = 0x00000020, + IDLE_PRIORITY_CLASS = 0x00000040, + HIGH_PRIORITY_CLASS = 0x00000080, + REALTIME_PRIORITY_CLASS = 0x00000100, + CREATE_NEW_PROCESS_GROUP = 0x00000200, + CREATE_UNICODE_ENVIRONMENT = 0x00000400, + CREATE_SEPARATE_WOW_VDM = 0x00000800, + CREATE_SHARED_WOW_VDM = 0x00001000, + CREATE_FORCEDOS = 0x00002000, + BELOW_NORMAL_PRIORITY_CLASS = 0x00004000, + ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000, + CREATE_BREAKAWAY_FROM_JOB = 0x01000000, + CREATE_WITH_USERPROFILE = 0x02000000, + CREATE_DEFAULT_ERROR_MODE = 0x04000000, + CREATE_NO_WINDOW = 0x08000000, + PROFILE_USER = 0x10000000, + PROFILE_KERNEL = 0x20000000, + PROFILE_SERVER = 0x40000000 +} + +enum DWORD CONSOLE_TEXTMODE_BUFFER = 1; + +// CreateFile() +enum : DWORD { + CREATE_NEW = 1, + CREATE_ALWAYS, + OPEN_EXISTING, + OPEN_ALWAYS, + TRUNCATE_EXISTING +} + +// CreateFile() +enum DWORD + FILE_FLAG_WRITE_THROUGH = 0x80000000, + FILE_FLAG_OVERLAPPED = 0x40000000, + FILE_FLAG_NO_BUFFERING = 0x20000000, + FILE_FLAG_RANDOM_ACCESS = 0x10000000, + FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000, + FILE_FLAG_DELETE_ON_CLOSE = 0x04000000, + FILE_FLAG_BACKUP_SEMANTICS = 0x02000000, + FILE_FLAG_POSIX_SEMANTICS = 0x01000000, + FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000, + FILE_FLAG_OPEN_NO_RECALL = 0x00100000; + +static if (_WIN32_WINNT >= 0x500) { +enum DWORD FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000; +} + +// for CreateFile() +enum DWORD + SECURITY_ANONYMOUS = SECURITY_IMPERSONATION_LEVEL.SecurityAnonymous<<16, + SECURITY_IDENTIFICATION = SECURITY_IMPERSONATION_LEVEL.SecurityIdentification<<16, + SECURITY_IMPERSONATION = SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation<<16, + SECURITY_DELEGATION = SECURITY_IMPERSONATION_LEVEL.SecurityDelegation<<16, + SECURITY_CONTEXT_TRACKING = 0x00040000, + SECURITY_EFFECTIVE_ONLY = 0x00080000, + SECURITY_SQOS_PRESENT = 0x00100000, + SECURITY_VALID_SQOS_FLAGS = 0x001F0000; + +// for GetFinalPathNameByHandle() +enum DWORD + VOLUME_NAME_DOS = 0x0, + VOLUME_NAME_GUID = 0x1, + VOLUME_NAME_NT = 0x2, + VOLUME_NAME_NONE = 0x4, + FILE_NAME_NORMALIZED = 0x0, + FILE_NAME_OPENED = 0x8; + +// Thread exit code +enum DWORD STILL_ACTIVE = 0x103; + +/* ??? The only documentation of this seems to be about Windows CE and to + * state what _doesn't_ support it. + */ +enum DWORD FIND_FIRST_EX_CASE_SENSITIVE = 1; + +// GetBinaryType() +enum : DWORD { + SCS_32BIT_BINARY = 0, + SCS_DOS_BINARY, + SCS_WOW_BINARY, + SCS_PIF_BINARY, + SCS_POSIX_BINARY, + SCS_OS216_BINARY +} + +enum size_t + MAX_COMPUTERNAME_LENGTH = 15, + HW_PROFILE_GUIDLEN = 39, + MAX_PROFILE_LEN = 80; + +// HW_PROFILE_INFO +enum DWORD + DOCKINFO_UNDOCKED = 1, + DOCKINFO_DOCKED = 2, + DOCKINFO_USER_SUPPLIED = 4, + DOCKINFO_USER_UNDOCKED = DOCKINFO_USER_SUPPLIED | DOCKINFO_UNDOCKED, + DOCKINFO_USER_DOCKED = DOCKINFO_USER_SUPPLIED | DOCKINFO_DOCKED; + +// DriveType(), RealDriveType() +enum : int { + DRIVE_UNKNOWN = 0, + DRIVE_NO_ROOT_DIR, + DRIVE_REMOVABLE, + DRIVE_FIXED, + DRIVE_REMOTE, + DRIVE_CDROM, + DRIVE_RAMDISK +} + +// GetFileType() +enum : DWORD { + FILE_TYPE_UNKNOWN = 0, + FILE_TYPE_DISK, + FILE_TYPE_CHAR, + FILE_TYPE_PIPE, + FILE_TYPE_REMOTE = 0x8000 +} + +// Get/SetHandleInformation() +enum DWORD + HANDLE_FLAG_INHERIT = 0x01, + HANDLE_FLAG_PROTECT_FROM_CLOSE = 0x02; + +enum : DWORD { + STD_INPUT_HANDLE = 0xFFFFFFF6, + STD_OUTPUT_HANDLE = 0xFFFFFFF5, + STD_ERROR_HANDLE = 0xFFFFFFF4 +} + +@trusted enum HANDLE INVALID_HANDLE_VALUE = cast(HANDLE) (-1); + +enum : DWORD { + GET_TAPE_MEDIA_INFORMATION = 0, + GET_TAPE_DRIVE_INFORMATION = 1 +} + +enum : DWORD { + SET_TAPE_MEDIA_INFORMATION = 0, + SET_TAPE_DRIVE_INFORMATION = 1 +} + +// SetThreadPriority()/GetThreadPriority() +enum : int { + THREAD_PRIORITY_IDLE = -15, + THREAD_PRIORITY_LOWEST = -2, + THREAD_PRIORITY_BELOW_NORMAL = -1, + THREAD_PRIORITY_NORMAL = 0, + THREAD_PRIORITY_ABOVE_NORMAL = 1, + THREAD_PRIORITY_HIGHEST = 2, + THREAD_PRIORITY_TIME_CRITICAL = 15, + THREAD_PRIORITY_ERROR_RETURN = 2147483647 +} + +enum : DWORD { + TIME_ZONE_ID_UNKNOWN, + TIME_ZONE_ID_STANDARD, + TIME_ZONE_ID_DAYLIGHT, + TIME_ZONE_ID_INVALID = 0xFFFFFFFF +} + +enum DWORD + FS_CASE_SENSITIVE = 1, + FS_CASE_IS_PRESERVED = 2, + FS_UNICODE_STORED_ON_DISK = 4, + FS_PERSISTENT_ACLS = 8, + FS_FILE_COMPRESSION = 16, + FS_VOL_IS_COMPRESSED = 32768; + +// Flags for GlobalAlloc +enum UINT + GMEM_FIXED = 0, + GMEM_MOVEABLE = 0x0002, + GMEM_ZEROINIT = 0x0040, + GPTR = 0x0040, + GHND = 0x0042, + GMEM_MODIFY = 0x0080, // used only for GlobalRealloc + GMEM_VALID_FLAGS = 0x7F72; + +/+ // Obselete flags (Win16 only) + GMEM_NOCOMPACT=16; + GMEM_NODISCARD=32; + GMEM_DISCARDABLE=256; + GMEM_NOT_BANKED=4096; + GMEM_LOWER=4096; + GMEM_SHARE=8192; + GMEM_DDESHARE=8192; + + GMEM_LOCKCOUNT=255; + +// for GlobalFlags() + GMEM_DISCARDED = 16384; + GMEM_INVALID_HANDLE = 32768; + + GMEM_NOTIFY = 16384; ++/ + +enum UINT + LMEM_FIXED = 0, + LMEM_MOVEABLE = 0x0002, + LMEM_NONZEROLPTR = 0, + NONZEROLPTR = 0, + LMEM_NONZEROLHND = 0x0002, + NONZEROLHND = 0x0002, + LMEM_DISCARDABLE = 0x0F00, + LMEM_NOCOMPACT = 0x0010, + LMEM_NODISCARD = 0x0020, + LMEM_ZEROINIT = 0x0040, + LPTR = 0x0040, + LHND = 0x0042, + LMEM_MODIFY = 0x0080, + LMEM_LOCKCOUNT = 0x00FF, + LMEM_DISCARDED = 0x4000, + LMEM_INVALID_HANDLE = 0x8000; + + + +// used in EXCEPTION_RECORD +enum : DWORD { + STATUS_WAIT_0 = 0, + STATUS_ABANDONED_WAIT_0 = 0x00000080, + STATUS_USER_APC = 0x000000C0, + STATUS_TIMEOUT = 0x00000102, + STATUS_PENDING = 0x00000103, + + STATUS_SEGMENT_NOTIFICATION = 0x40000005, + STATUS_GUARD_PAGE_VIOLATION = 0x80000001, + STATUS_DATATYPE_MISALIGNMENT = 0x80000002, + STATUS_BREAKPOINT = 0x80000003, + STATUS_SINGLE_STEP = 0x80000004, + + STATUS_ACCESS_VIOLATION = 0xC0000005, + STATUS_IN_PAGE_ERROR = 0xC0000006, + STATUS_INVALID_HANDLE = 0xC0000008, + + STATUS_NO_MEMORY = 0xC0000017, + STATUS_ILLEGAL_INSTRUCTION = 0xC000001D, + STATUS_NONCONTINUABLE_EXCEPTION = 0xC0000025, + STATUS_INVALID_DISPOSITION = 0xC0000026, + STATUS_ARRAY_BOUNDS_EXCEEDED = 0xC000008C, + STATUS_FLOAT_DENORMAL_OPERAND = 0xC000008D, + STATUS_FLOAT_DIVIDE_BY_ZERO = 0xC000008E, + STATUS_FLOAT_INEXACT_RESULT = 0xC000008F, + STATUS_FLOAT_INVALID_OPERATION = 0xC0000090, + STATUS_FLOAT_OVERFLOW = 0xC0000091, + STATUS_FLOAT_STACK_CHECK = 0xC0000092, + STATUS_FLOAT_UNDERFLOW = 0xC0000093, + STATUS_INTEGER_DIVIDE_BY_ZERO = 0xC0000094, + STATUS_INTEGER_OVERFLOW = 0xC0000095, + STATUS_PRIVILEGED_INSTRUCTION = 0xC0000096, + STATUS_STACK_OVERFLOW = 0xC00000FD, + STATUS_CONTROL_C_EXIT = 0xC000013A, + STATUS_DLL_INIT_FAILED = 0xC0000142, + STATUS_DLL_INIT_FAILED_LOGOFF = 0xC000026B, + + CONTROL_C_EXIT = STATUS_CONTROL_C_EXIT, + + EXCEPTION_ACCESS_VIOLATION = STATUS_ACCESS_VIOLATION, + EXCEPTION_DATATYPE_MISALIGNMENT = STATUS_DATATYPE_MISALIGNMENT, + EXCEPTION_BREAKPOINT = STATUS_BREAKPOINT, + EXCEPTION_SINGLE_STEP = STATUS_SINGLE_STEP, + EXCEPTION_ARRAY_BOUNDS_EXCEEDED = STATUS_ARRAY_BOUNDS_EXCEEDED, + EXCEPTION_FLT_DENORMAL_OPERAND = STATUS_FLOAT_DENORMAL_OPERAND, + EXCEPTION_FLT_DIVIDE_BY_ZERO = STATUS_FLOAT_DIVIDE_BY_ZERO, + EXCEPTION_FLT_INEXACT_RESULT = STATUS_FLOAT_INEXACT_RESULT, + EXCEPTION_FLT_INVALID_OPERATION = STATUS_FLOAT_INVALID_OPERATION, + EXCEPTION_FLT_OVERFLOW = STATUS_FLOAT_OVERFLOW, + EXCEPTION_FLT_STACK_CHECK = STATUS_FLOAT_STACK_CHECK, + EXCEPTION_FLT_UNDERFLOW = STATUS_FLOAT_UNDERFLOW, + EXCEPTION_INT_DIVIDE_BY_ZERO = STATUS_INTEGER_DIVIDE_BY_ZERO, + EXCEPTION_INT_OVERFLOW = STATUS_INTEGER_OVERFLOW, + EXCEPTION_PRIV_INSTRUCTION = STATUS_PRIVILEGED_INSTRUCTION, + EXCEPTION_IN_PAGE_ERROR = STATUS_IN_PAGE_ERROR, + EXCEPTION_ILLEGAL_INSTRUCTION = STATUS_ILLEGAL_INSTRUCTION, + EXCEPTION_NONCONTINUABLE_EXCEPTION = STATUS_NONCONTINUABLE_EXCEPTION, + EXCEPTION_STACK_OVERFLOW = STATUS_STACK_OVERFLOW, + EXCEPTION_INVALID_DISPOSITION = STATUS_INVALID_DISPOSITION, + EXCEPTION_GUARD_PAGE = STATUS_GUARD_PAGE_VIOLATION, + EXCEPTION_INVALID_HANDLE = STATUS_INVALID_HANDLE +} + +// for PROCESS_HEAP_ENTRY +enum WORD + PROCESS_HEAP_REGION = 1, + PROCESS_HEAP_UNCOMMITTED_RANGE = 2, + PROCESS_HEAP_ENTRY_BUSY = 4, + PROCESS_HEAP_ENTRY_MOVEABLE = 16, + PROCESS_HEAP_ENTRY_DDESHARE = 32; + +// for LoadLibraryEx() +enum DWORD + DONT_RESOLVE_DLL_REFERENCES = 0x01, // not for WinME and earlier + LOAD_LIBRARY_AS_DATAFILE = 0x02, + LOAD_WITH_ALTERED_SEARCH_PATH = 0x08, + LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x10; // only for XP and later + +// for LockFile() +enum DWORD + LOCKFILE_FAIL_IMMEDIATELY = 1, + LOCKFILE_EXCLUSIVE_LOCK = 2; + +enum MAXIMUM_WAIT_OBJECTS = 64; +enum MAXIMUM_SUSPEND_COUNT = 0x7F; + +enum WAIT_OBJECT_0 = 0; +enum WAIT_ABANDONED_0 = 128; + +//const WAIT_TIMEOUT=258; // also in winerror.h + +enum : DWORD { + WAIT_IO_COMPLETION = 0x000000C0, + WAIT_ABANDONED = 0x00000080, + WAIT_FAILED = 0xFFFFFFFF +} + +// PurgeComm() +enum DWORD + PURGE_TXABORT = 1, + PURGE_RXABORT = 2, + PURGE_TXCLEAR = 4, + PURGE_RXCLEAR = 8; + +// ReadEventLog() +enum DWORD + EVENTLOG_SEQUENTIAL_READ = 1, + EVENTLOG_SEEK_READ = 2, + EVENTLOG_FORWARDS_READ = 4, + EVENTLOG_BACKWARDS_READ = 8; + +// ReportEvent() +enum : WORD { + EVENTLOG_SUCCESS = 0, + EVENTLOG_ERROR_TYPE = 1, + EVENTLOG_WARNING_TYPE = 2, + EVENTLOG_INFORMATION_TYPE = 4, + EVENTLOG_AUDIT_SUCCESS = 8, + EVENTLOG_AUDIT_FAILURE = 16 +} + +// FormatMessage() +enum DWORD + FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x0100, + FORMAT_MESSAGE_IGNORE_INSERTS = 0x0200, + FORMAT_MESSAGE_FROM_STRING = 0x0400, + FORMAT_MESSAGE_FROM_HMODULE = 0x0800, + FORMAT_MESSAGE_FROM_SYSTEM = 0x1000, + FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x2000; + +enum DWORD FORMAT_MESSAGE_MAX_WIDTH_MASK = 255; + +// also in ddk/ntapi.h +// To restore default error mode, call SetErrorMode(0) +enum { + SEM_FAILCRITICALERRORS = 0x0001, + SEM_NOGPFAULTERRORBOX = 0x0002, + SEM_NOALIGNMENTFAULTEXCEPT = 0x0004, + SEM_NOOPENFILEERRORBOX = 0x8000 +} +// end ntapi.h + +enum { + SLE_ERROR = 1, + SLE_MINORERROR, + SLE_WARNING +} + +enum SHUTDOWN_NORETRY = 1; + +// Return type for exception filters. +enum : LONG { + EXCEPTION_EXECUTE_HANDLER = 1, + EXCEPTION_CONTINUE_EXECUTION = -1, + EXCEPTION_CONTINUE_SEARCH = 0 +} + +enum : ATOM { + MAXINTATOM = 0xC000, + INVALID_ATOM = 0 +} + +enum IGNORE = 0; +enum INFINITE = 0xFFFFFFFF; + +// EscapeCommFunction() +enum { + SETXOFF = 1, + SETXON, + SETRTS, + CLRRTS, + SETDTR, + CLRDTR, // = 6 + SETBREAK = 8, + CLRBREAK = 9 +} + + +// for SetCommMask() +enum DWORD + EV_RXCHAR = 0x0001, + EV_RXFLAG = 0x0002, + EV_TXEMPTY = 0x0004, + EV_CTS = 0x0008, + EV_DSR = 0x0010, + EV_RLSD = 0x0020, + EV_BREAK = 0x0040, + EV_ERR = 0x0080, + EV_RING = 0x0100, + EV_PERR = 0x0200, + EV_RX80FULL = 0x0400, + EV_EVENT1 = 0x0800, + EV_EVENT2 = 0x1000; + +// GetCommModemStatus() +enum DWORD + MS_CTS_ON = 0x0010, + MS_DSR_ON = 0x0020, + MS_RING_ON = 0x0040, + MS_RLSD_ON = 0x0080; + + +// DCB +enum : BYTE { + NOPARITY = 0, + ODDPARITY, + EVENPARITY, + MARKPARITY, + SPACEPARITY +} +// DCB +enum : BYTE { + ONESTOPBIT = 0, + ONE5STOPBITS, + TWOSTOPBITS +} +// DCB +enum : DWORD { + CBR_110 = 110, + CBR_300 = 300, + CBR_600 = 600, + CBR_1200 = 1200, + CBR_2400 = 2400, + CBR_4800 = 4800, + CBR_9600 = 9600, + CBR_14400 = 14400, + CBR_19200 = 19200, + CBR_38400 = 38400, + CBR_56000 = 56000, + CBR_57600 = 57600, + CBR_115200 = 115200, + CBR_128000 = 128000, + CBR_256000 = 256000 +} +// DCB, 2-bit bitfield +enum { + DTR_CONTROL_DISABLE = 0, + DTR_CONTROL_ENABLE, + DTR_CONTROL_HANDSHAKE +} + +// DCB, 2-bit bitfield +enum { + RTS_CONTROL_DISABLE = 0, + RTS_CONTROL_ENABLE, + RTS_CONTROL_HANDSHAKE, + RTS_CONTROL_TOGGLE, +} + +// WIN32_STREAM_ID +enum : DWORD { + BACKUP_INVALID = 0, + BACKUP_DATA, + BACKUP_EA_DATA, + BACKUP_SECURITY_DATA, + BACKUP_ALTERNATE_DATA, + BACKUP_LINK, + BACKUP_PROPERTY_DATA, + BACKUP_OBJECT_ID, + BACKUP_REPARSE_DATA, + BACKUP_SPARSE_BLOCK +} + +// WIN32_STREAM_ID +enum : DWORD { + STREAM_NORMAL_ATTRIBUTE = 0, + STREAM_MODIFIED_WHEN_READ = 1, + STREAM_CONTAINS_SECURITY = 2, + STREAM_CONTAINS_PROPERTIES = 4 +} + +// STARTUPINFO +enum DWORD + STARTF_USESHOWWINDOW = 0x0001, + STARTF_USESIZE = 0x0002, + STARTF_USEPOSITION = 0x0004, + STARTF_USECOUNTCHARS = 0x0008, + STARTF_USEFILLATTRIBUTE = 0x0010, + STARTF_RUNFULLSCREEN = 0x0020, + STARTF_FORCEONFEEDBACK = 0x0040, + STARTF_FORCEOFFFEEDBACK = 0x0080, + STARTF_USESTDHANDLES = 0x0100, + STARTF_USEHOTKEY = 0x0200; + +// ??? +enum { + TC_NORMAL = 0, + TC_HARDERR = 1, + TC_GP_TRAP = 2, + TC_SIGNAL = 3 +} + +/+ These seem to be Windows CE-specific +enum { + AC_LINE_OFFLINE = 0, + AC_LINE_ONLINE = 1, + AC_LINE_BACKUP_POWER = 2, + AC_LINE_UNKNOWN = 255 +} + +enum { + BATTERY_FLAG_HIGH = 1, + BATTERY_FLAG_LOW = 2, + BATTERY_FLAG_CRITICAL = 4, + BATTERY_FLAG_CHARGING = 8, + BATTERY_FLAG_NO_BATTERY = 128, + BATTERY_FLAG_UNKNOWN = 255, + BATTERY_PERCENTAGE_UNKNOWN = 255, + BATTERY_LIFE_UNKNOWN = 0xFFFFFFFF +} ++/ + +// ??? +enum HINSTANCE_ERROR = 32; + +// returned from GetFileSize() +enum DWORD INVALID_FILE_SIZE = 0xFFFFFFFF; + +enum DWORD TLS_OUT_OF_INDEXES = 0xFFFFFFFF; + +// GetWriteWatch() +enum DWORD WRITE_WATCH_FLAG_RESET = 1; + +// for LogonUser() +enum : DWORD { + LOGON32_LOGON_INTERACTIVE = 2, + LOGON32_LOGON_NETWORK = 3, + LOGON32_LOGON_BATCH = 4, + LOGON32_LOGON_SERVICE = 5, + LOGON32_LOGON_UNLOCK = 7 +} + +// for LogonUser() +enum : DWORD { + LOGON32_PROVIDER_DEFAULT, + LOGON32_PROVIDER_WINNT35, + LOGON32_PROVIDER_WINNT40, + LOGON32_PROVIDER_WINNT50 +} + +// for MoveFileEx() +enum DWORD + MOVEFILE_REPLACE_EXISTING = 1, + MOVEFILE_COPY_ALLOWED = 2, + MOVEFILE_DELAY_UNTIL_REBOOT = 4, + MOVEFILE_WRITE_THROUGH = 8; + +// DefineDosDevice() +enum DWORD + DDD_RAW_TARGET_PATH = 1, + DDD_REMOVE_DEFINITION = 2, + DDD_EXACT_MATCH_ON_REMOVE = 4; + +static if (_WIN32_WINNT >= 0x500) { + enum : DWORD { + LOGON32_LOGON_NETWORK_CLEARTEXT = 8, + LOGON32_LOGON_NEW_CREDENTIALS = 9 + } + + // ReplaceFile() +enum DWORD + REPLACEFILE_WRITE_THROUGH = 1, + REPLACEFILE_IGNORE_MERGE_ERRORS = 2; +} + +static if (_WIN32_WINNT >= 0x501) { +enum DWORD + GET_MODULE_HANDLE_EX_FLAG_PIN = 1, + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT = 2, + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS = 4; + + // for ACTCTX +enum DWORD + ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID = 0x01, + ACTCTX_FLAG_LANGID_VALID = 0x02, + ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID = 0x04, + ACTCTX_FLAG_RESOURCE_NAME_VALID = 0x08, + ACTCTX_FLAG_SET_PROCESS_DEFAULT = 0x10, + ACTCTX_FLAG_APPLICATION_NAME_VALID = 0x20, + ACTCTX_FLAG_HMODULE_VALID = 0x80; + + // DeactivateActCtx() +enum DWORD DEACTIVATE_ACTCTX_FLAG_FORCE_EARLY_DEACTIVATION = 1; + // FindActCtxSectionString() +enum DWORD FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX = 1; + // QueryActCtxW() +enum DWORD + QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX = 0x04, + QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE = 0x08, + QUERY_ACTCTX_FLAG_ACTCTX_IS_ADDRESS = 0x10; + + enum { + LOGON_WITH_PROFILE = 1, + LOGON_NETCREDENTIALS_ONLY + } +} + +// ---- + +struct FILETIME { + DWORD dwLowDateTime; + DWORD dwHighDateTime; +} +alias FILETIME* PFILETIME, LPFILETIME; + +struct BY_HANDLE_FILE_INFORMATION { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD dwVolumeSerialNumber; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + DWORD nNumberOfLinks; + DWORD nFileIndexHigh; + DWORD nFileIndexLow; +} +alias BY_HANDLE_FILE_INFORMATION* LPBY_HANDLE_FILE_INFORMATION; + +struct DCB { + DWORD DCBlength = DCB.sizeof; + DWORD BaudRate; +/+ + DWORD fBinary:1; // Binary Mode (skip EOF check) + DWORD fParity:1; // Enable parity checking + DWORD fOutxCtsFlow:1; // CTS handshaking on output + DWORD fOutxDsrFlow:1; // DSR handshaking on output + DWORD fDtrControl:2; // DTR Flow control + DWORD fDsrSensitivity:1; // DSR Sensitivity + DWORD fTXContinueOnXoff:1; // Continue TX when Xoff sent + DWORD fOutX:1; // Enable output X-ON/X-OFF + DWORD fInX:1; // Enable input X-ON/X-OFF + DWORD fErrorChar:1; // Enable Err Replacement + DWORD fNull:1; // Enable Null stripping + DWORD fRtsControl:2; // Rts Flow control + DWORD fAbortOnError:1; // Abort all reads and writes on Error + DWORD fDummy2:17; // Reserved ++/ + uint _bf; + bool fBinary(bool f) { _bf = (_bf & ~0x0001) | f; return f; } + bool fParity(bool f) { _bf = (_bf & ~0x0002) | (f<<1); return f; } + bool fOutxCtsFlow(bool f) { _bf = (_bf & ~0x0004) | (f<<2); return f; } + bool fOutxDsrFlow(bool f) { _bf = (_bf & ~0x0008) | (f<<3); return f; } + byte fDtrControl(byte x) { _bf = (_bf & ~0x0030) | (x<<4); return cast(byte)(x & 3); } + bool fDsrSensitivity(bool f) { _bf = (_bf & ~0x0040) | (f<<6); return f; } + bool fTXContinueOnXoff(bool f) { _bf = (_bf & ~0x0080) | (f<<7); return f; } + bool fOutX(bool f) { _bf = (_bf & ~0x0100) | (f<<8); return f; } + bool fInX(bool f) { _bf = (_bf & ~0x0200) | (f<<9); return f; } + bool fErrorChar(bool f) { _bf = (_bf & ~0x0400) | (f<<10); return f; } + bool fNull(bool f) { _bf = (_bf & ~0x0800) | (f<<11); return f; } + byte fRtsControl(byte x) { _bf = (_bf & ~0x3000) | (x<<12); return cast(byte)(x & 3); } + bool fAbortOnError(bool f) { _bf = (_bf & ~0x4000) | (f<<14); return f; } + + bool fBinary() { return cast(bool) (_bf & 1); } + bool fParity() { return cast(bool) (_bf & 2); } + bool fOutxCtsFlow() { return cast(bool) (_bf & 4); } + bool fOutxDsrFlow() { return cast(bool) (_bf & 8); } + byte fDtrControl() { return cast(byte) ((_bf & (32+16))>>4); } + bool fDsrSensitivity() { return cast(bool) (_bf & 64); } + bool fTXContinueOnXoff()() { return cast(bool) (_bf & 128); } + bool fOutX() { return cast(bool) (_bf & 256); } + bool fInX() { return cast(bool) (_bf & 512); } + bool fErrorChar() { return cast(bool) (_bf & 1024); } + bool fNull() { return cast(bool) (_bf & 2048); } + byte fRtsControl() { return cast(byte) ((_bf & (4096+8192))>>12); } + bool fAbortOnError() { return cast(bool) (_bf & 16384); } + + WORD wReserved; + WORD XonLim; + WORD XoffLim; + BYTE ByteSize; + BYTE Parity; + BYTE StopBits; + char XonChar = 0; + char XoffChar = 0; + char ErrorChar = 0; + char EofChar = 0; + char EvtChar = 0; + WORD wReserved1; +} +alias DCB* LPDCB; + +struct COMMCONFIG { + DWORD dwSize = COMMCONFIG.sizeof; + WORD wVersion; + WORD wReserved; + DCB dcb; + DWORD dwProviderSubType; + DWORD dwProviderOffset; + DWORD dwProviderSize; + WCHAR _wcProviderData = 0; + + WCHAR* wcProviderData() return { return &_wcProviderData; } +} +alias COMMCONFIG* LPCOMMCONFIG; + +struct COMMTIMEOUTS { + DWORD ReadIntervalTimeout; + DWORD ReadTotalTimeoutMultiplier; + DWORD ReadTotalTimeoutConstant; + DWORD WriteTotalTimeoutMultiplier; + DWORD WriteTotalTimeoutConstant; +} +alias COMMTIMEOUTS* LPCOMMTIMEOUTS; + +struct COMSTAT { +/+ + DWORD fCtsHold:1; + DWORD fDsrHold:1; + DWORD fRlsdHold:1; + DWORD fXoffHold:1; + DWORD fXoffSent:1; + DWORD fEof:1; + DWORD fTxim:1; + DWORD fReserved:25; ++/ + DWORD _bf; + bool fCtsHold(bool f) { _bf = (_bf & ~1) | f; return f; } + bool fDsrHold(bool f) { _bf = (_bf & ~2) | (f<<1); return f; } + bool fRlsdHold(bool f) { _bf = (_bf & ~4) | (f<<2); return f; } + bool fXoffHold(bool f) { _bf = (_bf & ~8) | (f<<3); return f; } + bool fXoffSent(bool f) { _bf = (_bf & ~16) | (f<<4); return f; } + bool fEof(bool f) { _bf = (_bf & ~32) | (f<<5); return f; } + bool fTxim(bool f) { _bf = (_bf & ~64) | (f<<6); return f; } + + bool fCtsHold() { return cast(bool) (_bf & 1); } + bool fDsrHold() { return cast(bool) (_bf & 2); } + bool fRlsdHold()() { return cast(bool) (_bf & 4); } + bool fXoffHold()() { return cast(bool) (_bf & 8); } + bool fXoffSent()() { return cast(bool) (_bf & 16); } + bool fEof() { return cast(bool) (_bf & 32); } + bool fTxim() { return cast(bool) (_bf & 64); } + + DWORD cbInQue; + DWORD cbOutQue; +} +alias COMSTAT* LPCOMSTAT; + +struct CREATE_PROCESS_DEBUG_INFO { + HANDLE hFile; + HANDLE hProcess; + HANDLE hThread; + LPVOID lpBaseOfImage; + DWORD dwDebugInfoFileOffset; + DWORD nDebugInfoSize; + LPVOID lpThreadLocalBase; + LPTHREAD_START_ROUTINE lpStartAddress; + LPVOID lpImageName; + WORD fUnicode; +} +alias CREATE_PROCESS_DEBUG_INFO* LPCREATE_PROCESS_DEBUG_INFO; + +struct CREATE_THREAD_DEBUG_INFO { + HANDLE hThread; + LPVOID lpThreadLocalBase; + LPTHREAD_START_ROUTINE lpStartAddress; +} +alias CREATE_THREAD_DEBUG_INFO* LPCREATE_THREAD_DEBUG_INFO; + +struct EXCEPTION_DEBUG_INFO { + EXCEPTION_RECORD ExceptionRecord; + DWORD dwFirstChance; +} +alias EXCEPTION_DEBUG_INFO* LPEXCEPTION_DEBUG_INFO; + +struct EXIT_THREAD_DEBUG_INFO { + DWORD dwExitCode; +} +alias EXIT_THREAD_DEBUG_INFO* LPEXIT_THREAD_DEBUG_INFO; + +struct EXIT_PROCESS_DEBUG_INFO { + DWORD dwExitCode; +} +alias EXIT_PROCESS_DEBUG_INFO* LPEXIT_PROCESS_DEBUG_INFO; + +struct LOAD_DLL_DEBUG_INFO { + HANDLE hFile; + LPVOID lpBaseOfDll; + DWORD dwDebugInfoFileOffset; + DWORD nDebugInfoSize; + LPVOID lpImageName; + WORD fUnicode; +} +alias LOAD_DLL_DEBUG_INFO* LPLOAD_DLL_DEBUG_INFO; + +struct UNLOAD_DLL_DEBUG_INFO { + LPVOID lpBaseOfDll; +} +alias UNLOAD_DLL_DEBUG_INFO* LPUNLOAD_DLL_DEBUG_INFO; + +struct OUTPUT_DEBUG_STRING_INFO { + LPSTR lpDebugStringData; + WORD fUnicode; + WORD nDebugStringLength; +} +alias OUTPUT_DEBUG_STRING_INFO* LPOUTPUT_DEBUG_STRING_INFO; + +struct RIP_INFO { + DWORD dwError; + DWORD dwType; +} +alias RIP_INFO* LPRIP_INFO; + +struct DEBUG_EVENT { + DWORD dwDebugEventCode; + DWORD dwProcessId; + DWORD dwThreadId; + union { + EXCEPTION_DEBUG_INFO Exception; + CREATE_THREAD_DEBUG_INFO CreateThread; + CREATE_PROCESS_DEBUG_INFO CreateProcessInfo; + EXIT_THREAD_DEBUG_INFO ExitThread; + EXIT_PROCESS_DEBUG_INFO ExitProcess; + LOAD_DLL_DEBUG_INFO LoadDll; + UNLOAD_DLL_DEBUG_INFO UnloadDll; + OUTPUT_DEBUG_STRING_INFO DebugString; + RIP_INFO RipInfo; + } +} +alias DEBUG_EVENT* LPDEBUG_EVENT; + +struct OVERLAPPED { + ULONG_PTR Internal; + ULONG_PTR InternalHigh; + union { + struct { + DWORD Offset; + DWORD OffsetHigh; + } + PVOID Pointer; + } + HANDLE hEvent; +} +alias OVERLAPPED* POVERLAPPED, LPOVERLAPPED; + +struct STARTUPINFOA { + DWORD cb = STARTUPINFOA.sizeof; + LPSTR lpReserved; + LPSTR lpDesktop; + LPSTR lpTitle; + DWORD dwX; + DWORD dwY; + DWORD dwXSize; + DWORD dwYSize; + DWORD dwXCountChars; + DWORD dwYCountChars; + DWORD dwFillAttribute; + DWORD dwFlags; + WORD wShowWindow; + WORD cbReserved2; + PBYTE lpReserved2; + HANDLE hStdInput; + HANDLE hStdOutput; + HANDLE hStdError; +} +alias STARTUPINFOA* LPSTARTUPINFOA; + +struct STARTUPINFOW { + DWORD cb = STARTUPINFOW.sizeof; + LPWSTR lpReserved; + LPWSTR lpDesktop; + LPWSTR lpTitle; + DWORD dwX; + DWORD dwY; + DWORD dwXSize; + DWORD dwYSize; + DWORD dwXCountChars; + DWORD dwYCountChars; + DWORD dwFillAttribute; + DWORD dwFlags; + WORD wShowWindow; + WORD cbReserved2; + PBYTE lpReserved2; + HANDLE hStdInput; + HANDLE hStdOutput; + HANDLE hStdError; +} +alias STARTUPINFOW STARTUPINFO_W; +alias STARTUPINFOW* LPSTARTUPINFOW, LPSTARTUPINFO_W; + +struct PROCESS_INFORMATION { + HANDLE hProcess; + HANDLE hThread; + DWORD dwProcessId; + DWORD dwThreadId; +} +alias PROCESS_INFORMATION* PPROCESS_INFORMATION, LPPROCESS_INFORMATION; + +/* +struct CRITICAL_SECTION_DEBUG { + WORD Type; + WORD CreatorBackTraceIndex; + CRITICAL_SECTION* CriticalSection; + LIST_ENTRY ProcessLocksList; + DWORD EntryCount; + DWORD ContentionCount; + DWORD[2] Spare; +} +alias CRITICAL_SECTION_DEBUG* PCRITICAL_SECTION_DEBUG; + +struct CRITICAL_SECTION { + PCRITICAL_SECTION_DEBUG DebugInfo; + LONG LockCount; + LONG RecursionCount; + HANDLE OwningThread; + HANDLE LockSemaphore; + DWORD SpinCount; +} +alias CRITICAL_SECTION* PCRITICAL_SECTION, LPCRITICAL_SECTION; +*/ + +alias CRITICAL_SECTION_DEBUG = RTL_CRITICAL_SECTION_DEBUG; +alias CRITICAL_SECTION_DEBUG* PCRITICAL_SECTION_DEBUG; + +alias CRITICAL_SECTION = RTL_CRITICAL_SECTION; +alias CRITICAL_SECTION* PCRITICAL_SECTION, LPCRITICAL_SECTION; + +struct SYSTEMTIME { + WORD wYear; + WORD wMonth; + WORD wDayOfWeek; + WORD wDay; + WORD wHour; + WORD wMinute; + WORD wSecond; + WORD wMilliseconds; +} +alias SYSTEMTIME* LPSYSTEMTIME; + +struct WIN32_FILE_ATTRIBUTE_DATA { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; +} +alias WIN32_FILE_ATTRIBUTE_DATA* LPWIN32_FILE_ATTRIBUTE_DATA; + +struct WIN32_FIND_DATAA { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; +// #ifdef _WIN32_WCE +// DWORD dwOID; +// #else + DWORD dwReserved0; + DWORD dwReserved1; +// #endif + CHAR[MAX_PATH] cFileName = 0; +// #ifndef _WIN32_WCE + CHAR[14] cAlternateFileName = 0; +// #endif +} +alias WIN32_FIND_DATAA* PWIN32_FIND_DATAA, LPWIN32_FIND_DATAA; + +struct WIN32_FIND_DATAW { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; +// #ifdef _WIN32_WCE +// DWORD dwOID; +// #else + DWORD dwReserved0; + DWORD dwReserved1; +// #endif + WCHAR[MAX_PATH] cFileName = 0; +// #ifndef _WIN32_WCE + WCHAR[14] cAlternateFileName = 0; +// #endif +} +alias WIN32_FIND_DATAW* PWIN32_FIND_DATAW, LPWIN32_FIND_DATAW; + +struct WIN32_STREAM_ID { + DWORD dwStreamId; + DWORD dwStreamAttributes; + LARGE_INTEGER Size; + DWORD dwStreamNameSize; + WCHAR _cStreamName = 0; + + WCHAR* cStreamName() return { return &_cStreamName; } +} +alias WIN32_STREAM_ID* LPWIN32_STREAM_ID; + +static if (_WIN32_WINNT >= 0x601) { + enum FINDEX_INFO_LEVELS { + FindExInfoStandard, + FindExInfoBasic, + FindExInfoMaxInfoLevel, + } +} else { + enum FINDEX_INFO_LEVELS { + FindExInfoStandard, + FindExInfoMaxInfoLevel, + } +} + +enum FINDEX_SEARCH_OPS { + FindExSearchNameMatch, + FindExSearchLimitToDirectories, + FindExSearchLimitToDevices, + FindExSearchMaxSearchOp +} + +enum ACL_INFORMATION_CLASS { + AclRevisionInformation = 1, + AclSizeInformation +} + +struct HW_PROFILE_INFOA { + DWORD dwDockInfo; + CHAR[HW_PROFILE_GUIDLEN] szHwProfileGuid = 0; + CHAR[MAX_PROFILE_LEN] szHwProfileName = 0; +} +alias HW_PROFILE_INFOA* LPHW_PROFILE_INFOA; + +struct HW_PROFILE_INFOW { + DWORD dwDockInfo; + WCHAR[HW_PROFILE_GUIDLEN] szHwProfileGuid = 0; + WCHAR[MAX_PROFILE_LEN] szHwProfileName = 0; +} +alias HW_PROFILE_INFOW* LPHW_PROFILE_INFOW; + +/* ??? MSDN documents this only for Windows CE/Mobile, but it's used by + * GetFileAttributesEx, which is in desktop Windows. + */ +enum GET_FILEEX_INFO_LEVELS { + GetFileExInfoStandard, + GetFileExMaxInfoLevel +} + +import urt.internal.sys.windows.sdkddkver : NTDDI_VERSION, NTDDI_LONGHORN; + +static if (NTDDI_VERSION >= NTDDI_LONGHORN) +{ + enum FILE_INFO_BY_HANDLE_CLASS + { + FileBasicInfo, + FileStandardInfo, + FileNameInfo, + FileRenameInfo, + FileDispositionInfo, + FileAllocationInfo, + FileEndOfFileInfo, + FileStreamInfo, + FileCompressionInfo, + FileAttributeTagInfo, + FileIdBothDirectoryInfo, + FileIdBothDirectoryRestartInfo, + FileIoPriorityHintInfo, + FileRemoteProtocolInfo, + FileFullDirectoryInfo, + FileFullDirectoryRestartInfo, +// static if (NTDDI_VERSION >= NTDDI_WIN8) +// { + FileStorageInfo, + FileAlignmentInfo, + FileIdInfo, + FileIdExtdDirectoryInfo, + FileIdExtdDirectoryRestartInfo, +// } +// static if (NTDDI_VERSION >= NTDDI_WIN10_RS1) +// { + FileDispositionInfoEx, + FileRenameInfoEx, +// } +// static if (NTDDI_VERSION >= NTDDI_WIN10_19H1) +// { + FileCaseSensitiveInfo, + FileNormalizedNameInfo, +// } + MaximumFileInfoByHandleClass + } + alias PFILE_INFO_BY_HANDLE_CLASS = FILE_INFO_BY_HANDLE_CLASS*; +} + +struct SYSTEM_INFO { + union { + DWORD dwOemId; + struct { + WORD wProcessorArchitecture; + WORD wReserved; + } + } + DWORD dwPageSize; + PVOID lpMinimumApplicationAddress; + PVOID lpMaximumApplicationAddress; + DWORD_PTR dwActiveProcessorMask; + DWORD dwNumberOfProcessors; + DWORD dwProcessorType; + DWORD dwAllocationGranularity; + WORD wProcessorLevel; + WORD wProcessorRevision; +} +alias SYSTEM_INFO* LPSYSTEM_INFO; + +static if (_WIN32_WINNT >= 0x500) { + struct SYSTEM_POWER_STATUS { + BYTE ACLineStatus; + BYTE BatteryFlag; + BYTE BatteryLifePercent; + BYTE Reserved1; + DWORD BatteryLifeTime; + DWORD BatteryFullLifeTime; + } + alias SYSTEM_POWER_STATUS* LPSYSTEM_POWER_STATUS; +} + +struct TIME_ZONE_INFORMATION { + LONG Bias; + WCHAR[32] StandardName = 0; + SYSTEMTIME StandardDate; + LONG StandardBias; + WCHAR[32] DaylightName = 0; + SYSTEMTIME DaylightDate; + LONG DaylightBias; +} +alias TIME_ZONE_INFORMATION* LPTIME_ZONE_INFORMATION; + +// Does not exist in Windows headers, only MSDN +// documentation (for TIME_ZONE_INFORMATION). +// Provided solely for compatibility with the old +// urt.internal.sys.windows.windows +struct REG_TZI_FORMAT { + LONG Bias; + LONG StandardBias; + LONG DaylightBias; + SYSTEMTIME StandardDate; + SYSTEMTIME DaylightDate; +} + +// MSDN documents this, possibly erroneously, as Win2000+. +struct MEMORYSTATUS { + DWORD dwLength; + DWORD dwMemoryLoad; + SIZE_T dwTotalPhys; + SIZE_T dwAvailPhys; + SIZE_T dwTotalPageFile; + SIZE_T dwAvailPageFile; + SIZE_T dwTotalVirtual; + SIZE_T dwAvailVirtual; +} +alias MEMORYSTATUS* LPMEMORYSTATUS; + +static if (_WIN32_WINNT >= 0x500) { + struct MEMORYSTATUSEX { + DWORD dwLength; + DWORD dwMemoryLoad; + DWORDLONG ullTotalPhys; + DWORDLONG ullAvailPhys; + DWORDLONG ullTotalPageFile; + DWORDLONG ullAvailPageFile; + DWORDLONG ullTotalVirtual; + DWORDLONG ullAvailVirtual; + DWORDLONG ullAvailExtendedVirtual; + } + alias MEMORYSTATUSEX* LPMEMORYSTATUSEX; +} + +struct LDT_ENTRY { + WORD LimitLow; + WORD BaseLow; + struct { + BYTE BaseMid; + BYTE Flags1; + BYTE Flags2; + BYTE BaseHi; + + byte Type(byte f) { Flags1 = cast(BYTE) ((Flags1 & 0xE0) | f); return cast(byte)(f & 0x1F); } + byte Dpl(byte f) { Flags1 = cast(BYTE) ((Flags1 & 0x9F) | (f<<5)); return cast(byte)(f & 3); } + bool Pres(bool f) { Flags1 = cast(BYTE) ((Flags1 & 0x7F) | (f<<7)); return f; } + + byte LimitHi(byte f) { Flags2 = cast(BYTE) ((Flags2 & 0xF0) | (f&0x0F)); return cast(byte)(f & 0x0F); } + bool Sys(bool f) { Flags2 = cast(BYTE) ((Flags2 & 0xEF) | (f<<4)); return f; } + // Next bit is reserved + bool Default_Big(bool f) { Flags2 = cast(BYTE) ((Flags2 & 0xBF) | (f<<6)); return f; } + bool Granularity(bool f) { Flags2 = cast(BYTE) ((Flags2 & 0x7F) | (f<<7)); return f; } + + byte Type() { return cast(byte) (Flags1 & 0x1F); } + byte Dpl() { return cast(byte) ((Flags1 & 0x60)>>5); } + bool Pres() { return cast(bool) (Flags1 & 0x80); } + + byte LimitHi() { return cast(byte) (Flags2 & 0x0F); } + bool Sys() { return cast(bool) (Flags2 & 0x10); } + bool Default_Big()() { return cast(bool) (Flags2 & 0x40); } + bool Granularity()() { return cast(bool) (Flags2 & 0x80); } + } +/+ + union HighWord { + struct Bytes { + BYTE BaseMid; + BYTE Flags1; + BYTE Flags2; + BYTE BaseHi; + } + struct Bits { + DWORD BaseMid:8; + DWORD Type:5; + DWORD Dpl:2; + DWORD Pres:1; + DWORD LimitHi:4; + DWORD Sys:1; + DWORD Reserved_0:1; + DWORD Default_Big:1; + DWORD Granularity:1; + DWORD BaseHi:8; + } + } ++/ +} +alias LDT_ENTRY* PLDT_ENTRY, LPLDT_ENTRY; + +/* As with the other memory management functions and structures, MSDN's + * Windows version info shall be taken with a cup of salt. + */ +struct PROCESS_HEAP_ENTRY { + PVOID lpData; + DWORD cbData; + BYTE cbOverhead; + BYTE iRegionIndex; + WORD wFlags; + union { + struct _Block { + HANDLE hMem; + DWORD[3] dwReserved; + } + _Block Block; + struct _Region { + DWORD dwCommittedSize; + DWORD dwUnCommittedSize; + LPVOID lpFirstBlock; + LPVOID lpLastBlock; + } + _Region Region; + } +} +alias PROCESS_HEAP_ENTRY* LPPROCESS_HEAP_ENTRY; + +struct OFSTRUCT { + BYTE cBytes = OFSTRUCT.sizeof; + BYTE fFixedDisk; + WORD nErrCode; + WORD Reserved1; + WORD Reserved2; + CHAR[128] szPathName = 0; // const OFS_MAXPATHNAME = 128; +} +alias OFSTRUCT* LPOFSTRUCT, POFSTRUCT; + +/* ??? MSDN documents this only for Windows CE, but it's used by + * ImageGetCertificateData, which is in desktop Windows. + */ +struct WIN_CERTIFICATE { + DWORD dwLength; + WORD wRevision; + WORD wCertificateType; + BYTE _bCertificate; + + BYTE* bCertificate() return { return &_bCertificate; } +} +alias WIN_CERTIFICATE* LPWIN_CERTIFICATE; + +static if (_WIN32_WINNT >= 0x500) { + enum COMPUTER_NAME_FORMAT { + ComputerNameNetBIOS, + ComputerNameDnsHostname, + ComputerNameDnsDomain, + ComputerNameDnsFullyQualified, + ComputerNamePhysicalNetBIOS, + ComputerNamePhysicalDnsHostname, + ComputerNamePhysicalDnsDomain, + ComputerNamePhysicalDnsFullyQualified, + ComputerNameMax + } +} + +static if (_WIN32_WINNT >= 0x501) { + struct ACTCTXA { + ULONG cbSize = this.sizeof; + DWORD dwFlags; + LPCSTR lpSource; + USHORT wProcessorArchitecture; + LANGID wLangId; + LPCSTR lpAssemblyDirectory; + LPCSTR lpResourceName; + LPCSTR lpApplicationName; + HMODULE hModule; + } + alias ACTCTXA* PACTCTXA; + alias const(ACTCTXA)* PCACTCTXA; + + struct ACTCTXW { + ULONG cbSize = this.sizeof; + DWORD dwFlags; + LPCWSTR lpSource; + USHORT wProcessorArchitecture; + LANGID wLangId; + LPCWSTR lpAssemblyDirectory; + LPCWSTR lpResourceName; + LPCWSTR lpApplicationName; + HMODULE hModule; + } + alias ACTCTXW* PACTCTXW; + alias const(ACTCTXW)* PCACTCTXW; + + struct ACTCTX_SECTION_KEYED_DATA { + ULONG cbSize = this.sizeof; + ULONG ulDataFormatVersion; + PVOID lpData; + ULONG ulLength; + PVOID lpSectionGlobalData; + ULONG ulSectionGlobalDataLength; + PVOID lpSectionBase; + ULONG ulSectionTotalLength; + HANDLE hActCtx; + HANDLE ulAssemblyRosterIndex; + } + alias ACTCTX_SECTION_KEYED_DATA* PACTCTX_SECTION_KEYED_DATA; + alias const(ACTCTX_SECTION_KEYED_DATA)* PCACTCTX_SECTION_KEYED_DATA; + + enum MEMORY_RESOURCE_NOTIFICATION_TYPE { + LowMemoryResourceNotification, + HighMemoryResourceNotification + } + +} // (_WIN32_WINNT >= 0x501) + +static if (_WIN32_WINNT >= 0x410) { + /* apparently used only by SetThreadExecutionState (Win2000+) + * and DDK functions (version compatibility not established) + */ + alias DWORD EXECUTION_STATE; +} + +// CreateSymbolicLink, GetFileInformationByHandleEx +static if (_WIN32_WINNT >= 0x600) { + enum { + SYMBOLIC_LINK_FLAG_DIRECTORY = 0x1, + SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE = 0x2 + } + + struct FILE_BASIC_INFO + { + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + DWORD FileAttributes; + } + alias PFILE_BASIC_INFO = FILE_BASIC_INFO*; + + struct FILE_STANDARD_INFO + { + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + DWORD NumberOfLinks; + BOOLEAN DeletePending; + BOOLEAN Directory; + } + alias PFILE_STANDARD_INFO = FILE_STANDARD_INFO*; +} + +// Callbacks +extern (Windows) { + alias DWORD function(LPVOID) LPTHREAD_START_ROUTINE; + alias DWORD function(LARGE_INTEGER, LARGE_INTEGER, LARGE_INTEGER, LARGE_INTEGER, + DWORD, DWORD, HANDLE, HANDLE, LPVOID) LPPROGRESS_ROUTINE; + alias void function(PVOID) LPFIBER_START_ROUTINE; + + alias BOOL function(HMODULE, LPCSTR, LPCSTR, WORD, LONG_PTR) ENUMRESLANGPROCA; + alias BOOL function(HMODULE, LPCWSTR, LPCWSTR, WORD, LONG_PTR) ENUMRESLANGPROCW; + alias BOOL function(HMODULE, LPCSTR, LPSTR, LONG_PTR) ENUMRESNAMEPROCA; + alias BOOL function(HMODULE, LPCWSTR, LPWSTR, LONG_PTR) ENUMRESNAMEPROCW; + alias BOOL function(HMODULE, LPSTR, LONG_PTR) ENUMRESTYPEPROCA; + alias BOOL function(HMODULE, LPWSTR, LONG_PTR) ENUMRESTYPEPROCW; + alias void function(DWORD, DWORD, LPOVERLAPPED) LPOVERLAPPED_COMPLETION_ROUTINE; + alias LONG function(LPEXCEPTION_POINTERS) PTOP_LEVEL_EXCEPTION_FILTER; + alias PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER; + + alias void function(ULONG_PTR) PAPCFUNC; + alias void function(PVOID, DWORD, DWORD) PTIMERAPCROUTINE; + + static if (_WIN32_WINNT >= 0x500) { + alias void function(PVOID, BOOLEAN) WAITORTIMERCALLBACK; + } +} + +LPTSTR MAKEINTATOM()(ushort i) { + return cast(LPTSTR) cast(size_t) i; +} + +extern (Windows) nothrow @nogc { + // The following Win16 functions are obselete in Win32. + int _hread(HFILE, LPVOID, int); + int _hwrite(HFILE, LPCSTR, int); + HFILE _lclose(HFILE); + HFILE _lcreat(LPCSTR, int); + LONG _llseek(HFILE, LONG, int); + HFILE _lopen(LPCSTR, int); + UINT _lread(HFILE, LPVOID, UINT); + UINT _lwrite(HFILE, LPCSTR, UINT); + SIZE_T GlobalCompact(DWORD); + VOID GlobalFix(HGLOBAL); + + // MSDN contradicts itself on GlobalFlags: + // "This function is provided only for compatibility with 16-bit versions of Windows." + // but also requires Windows 2000 or above + UINT GlobalFlags(HGLOBAL); + VOID GlobalUnfix(HGLOBAL); + BOOL GlobalUnWire(HGLOBAL); + PVOID GlobalWire(HGLOBAL); + SIZE_T LocalCompact(UINT); + UINT LocalFlags(HLOCAL); + SIZE_T LocalShrink(HLOCAL, UINT); + + /+ + //-------------------------------------- + // These functions are problematic + + version (UseNtoSKernel) {}else { + /* CAREFUL: These are exported from ntoskrnl.exe and declared in winddk.h + as __fastcall functions, but are exported from kernel32.dll as __stdcall */ + static if (_WIN32_WINNT >= 0x501) { + VOID InitializeSListHead(PSLIST_HEADER); + } + LONG InterlockedCompareExchange(LPLONG, LONG, LONG); + // PVOID WINAPI InterlockedCompareExchangePointer(PVOID*, PVOID, PVOID); + (PVOID)InterlockedCompareExchange((LPLONG)(d) (PVOID)InterlockedCompareExchange((LPLONG)(d), (LONG)(e), (LONG)(c)) + LONG InterlockedDecrement(LPLONG); + LONG InterlockedExchange(LPLONG, LONG); + // PVOID WINAPI InterlockedExchangePointer(PVOID*, PVOID); + (PVOID)InterlockedExchange((LPLONG)((PVOID)InterlockedExchange((LPLONG)(t), (LONG)(v)) + LONG InterlockedExchangeAdd(LPLONG, LONG); + + static if (_WIN32_WINNT >= 0x501) { + PSLIST_ENTRY InterlockedFlushSList(PSLIST_HEADER); + } + LONG InterlockedIncrement(LPLONG); + static if (_WIN32_WINNT >= 0x501) { + PSLIST_ENTRY InterlockedPopEntrySList(PSLIST_HEADER); + PSLIST_ENTRY InterlockedPushEntrySList(PSLIST_HEADER, PSLIST_ENTRY); + } + } // #endif // __USE_NTOSKRNL__ + //-------------------------------------- + +/ + + LONG InterlockedIncrement(LPLONG lpAddend); + LONG InterlockedDecrement(LPLONG lpAddend); + LONG InterlockedExchange(LPLONG Target, LONG Value); + LONG InterlockedExchangeAdd(LPLONG Addend, LONG Value); + LONG InterlockedCompareExchange(LONG *Destination, LONG Exchange, LONG Comperand); + + ATOM AddAtomA(LPCSTR); + ATOM AddAtomW(LPCWSTR); + BOOL AreFileApisANSI(); + BOOL Beep(DWORD, DWORD); + HANDLE BeginUpdateResourceA(LPCSTR, BOOL); + HANDLE BeginUpdateResourceW(LPCWSTR, BOOL); + BOOL BuildCommDCBA(LPCSTR, LPDCB); + BOOL BuildCommDCBW(LPCWSTR, LPDCB); + BOOL BuildCommDCBAndTimeoutsA(LPCSTR, LPDCB, LPCOMMTIMEOUTS); + BOOL BuildCommDCBAndTimeoutsW(LPCWSTR, LPDCB, LPCOMMTIMEOUTS); + BOOL CallNamedPipeA(LPCSTR, PVOID, DWORD, PVOID, DWORD, PDWORD, DWORD); + BOOL CallNamedPipeW(LPCWSTR, PVOID, DWORD, PVOID, DWORD, PDWORD, DWORD); + BOOL CancelDeviceWakeupRequest(HANDLE); + BOOL CheckTokenMembership(HANDLE, PSID, PBOOL); + BOOL ClearCommBreak(HANDLE); + BOOL ClearCommError(HANDLE, PDWORD, LPCOMSTAT); + BOOL CloseHandle(HANDLE) @trusted; + BOOL CommConfigDialogA(LPCSTR, HWND, LPCOMMCONFIG); + BOOL CommConfigDialogW(LPCWSTR, HWND, LPCOMMCONFIG); + LONG CompareFileTime(const(FILETIME)*, const(FILETIME)*); + BOOL ContinueDebugEvent(DWORD, DWORD, DWORD); + BOOL CopyFileA(LPCSTR, LPCSTR, BOOL); + BOOL CopyFileW(LPCWSTR, LPCWSTR, BOOL); + BOOL CopyFileExA(LPCSTR, LPCSTR, LPPROGRESS_ROUTINE, LPVOID, LPBOOL, DWORD); + BOOL CopyFileExW(LPCWSTR, LPCWSTR, LPPROGRESS_ROUTINE, LPVOID, LPBOOL, DWORD); + + alias RtlMoveMemory = memmove; + alias RtlCopyMemory = memcpy; + pragma(inline, true) void RtlFillMemory(PVOID Destination, SIZE_T Length, BYTE Fill) pure { memset(Destination, Fill, Length); } + pragma(inline, true) void RtlZeroMemory(PVOID Destination, SIZE_T Length) pure { memset(Destination, 0, Length); } + alias MoveMemory = RtlMoveMemory; + alias CopyMemory = RtlCopyMemory; + alias FillMemory = RtlFillMemory; + alias ZeroMemory = RtlZeroMemory; + + BOOL CreateDirectoryA(LPCSTR, LPSECURITY_ATTRIBUTES); + BOOL CreateDirectoryW(LPCWSTR, LPSECURITY_ATTRIBUTES); + BOOL CreateDirectoryExA(LPCSTR, LPCSTR, LPSECURITY_ATTRIBUTES); + BOOL CreateDirectoryExW(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES); + HANDLE CreateEventA(LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCSTR); + HANDLE CreateEventW(LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCWSTR); + HANDLE CreateFileA(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE); + HANDLE CreateFileW(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE); + HANDLE CreateIoCompletionPort(HANDLE, HANDLE, ULONG_PTR, DWORD); + HANDLE CreateMailslotA(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES); + HANDLE CreateMailslotW(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES); + HANDLE CreateMutexA(LPSECURITY_ATTRIBUTES, BOOL, LPCSTR); + HANDLE CreateMutexW(LPSECURITY_ATTRIBUTES, BOOL, LPCWSTR); + BOOL CreatePipe(PHANDLE, PHANDLE, LPSECURITY_ATTRIBUTES, DWORD); + BOOL CreateProcessA(LPCSTR, LPSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, PVOID, LPCSTR, LPSTARTUPINFOA, LPPROCESS_INFORMATION); + BOOL CreateProcessW(LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, PVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION); + HANDLE CreateSemaphoreA(LPSECURITY_ATTRIBUTES, LONG, LONG, LPCSTR) @trusted; + HANDLE CreateSemaphoreW(LPSECURITY_ATTRIBUTES, LONG, LONG, LPCWSTR) @trusted; + HANDLE CreateThread(LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, PVOID, DWORD, PDWORD); + BOOL DebugActiveProcess(DWORD); + void DebugBreak(); + ATOM DeleteAtom(ATOM); + void DeleteCriticalSection(PCRITICAL_SECTION); + BOOL DeleteFileA(LPCSTR); + BOOL DeleteFileW(LPCWSTR); + BOOL DisableThreadLibraryCalls(HMODULE); + BOOL DosDateTimeToFileTime(WORD, WORD, LPFILETIME); + BOOL DuplicateHandle(HANDLE, HANDLE, HANDLE, PHANDLE, DWORD, BOOL, DWORD); + BOOL EndUpdateResourceA(HANDLE, BOOL); + BOOL EndUpdateResourceW(HANDLE, BOOL); + void EnterCriticalSection(LPCRITICAL_SECTION); + void EnterCriticalSection(shared(CRITICAL_SECTION)*); + BOOL EnumResourceLanguagesA(HMODULE, LPCSTR, LPCSTR, ENUMRESLANGPROC, LONG_PTR); + BOOL EnumResourceLanguagesW(HMODULE, LPCWSTR, LPCWSTR, ENUMRESLANGPROC, LONG_PTR); + BOOL EnumResourceNamesA(HMODULE, LPCSTR, ENUMRESNAMEPROC, LONG_PTR); + BOOL EnumResourceNamesW(HMODULE, LPCWSTR, ENUMRESNAMEPROC, LONG_PTR); + BOOL EnumResourceTypesA(HMODULE, ENUMRESTYPEPROC, LONG_PTR); + BOOL EnumResourceTypesW(HMODULE, ENUMRESTYPEPROC, LONG_PTR); + BOOL EscapeCommFunction(HANDLE, DWORD); + void ExitProcess(UINT); // Never returns + void ExitThread(DWORD); // Never returns + DWORD ExpandEnvironmentStringsA(LPCSTR, LPSTR, DWORD); + DWORD ExpandEnvironmentStringsW(LPCWSTR, LPWSTR, DWORD); + void FatalAppExitA(UINT, LPCSTR); + void FatalAppExitW(UINT, LPCWSTR); + void FatalExit(int); + BOOL FileTimeToDosDateTime(const(FILETIME)*, LPWORD, LPWORD); + BOOL FileTimeToLocalFileTime(const(FILETIME)*, LPFILETIME); + BOOL FileTimeToSystemTime(const(FILETIME)*, LPSYSTEMTIME); + ATOM FindAtomA(LPCSTR); + ATOM FindAtomW(LPCWSTR); + BOOL FindClose(HANDLE); + BOOL FindCloseChangeNotification(HANDLE); + HANDLE FindFirstChangeNotificationA(LPCSTR, BOOL, DWORD); + HANDLE FindFirstChangeNotificationW(LPCWSTR, BOOL, DWORD); + HANDLE FindFirstFileA(LPCSTR, LPWIN32_FIND_DATAA); + HANDLE FindFirstFileW(LPCWSTR, LPWIN32_FIND_DATAW); + BOOL FindNextChangeNotification(HANDLE); + BOOL FindNextFileA(HANDLE, LPWIN32_FIND_DATAA); + BOOL FindNextFileW(HANDLE, LPWIN32_FIND_DATAW); + HRSRC FindResourceA(HMODULE, LPCSTR, LPCSTR); + HRSRC FindResourceW(HINSTANCE, LPCWSTR, LPCWSTR); + HRSRC FindResourceExA(HINSTANCE, LPCSTR, LPCSTR, WORD); + HRSRC FindResourceExW(HINSTANCE, LPCWSTR, LPCWSTR, WORD); + BOOL FlushFileBuffers(HANDLE); + BOOL FlushInstructionCache(HANDLE, PCVOID, SIZE_T); +// DWORD FormatMessageA(DWORD, PCVOID, DWORD, DWORD, LPSTR, DWORD, va_list*); +// DWORD FormatMessageW(DWORD, PCVOID, DWORD, DWORD, LPWSTR, DWORD, va_list*); + BOOL FreeEnvironmentStringsA(LPSTR); + BOOL FreeEnvironmentStringsW(LPWSTR); + BOOL FreeLibrary(HMODULE); + void FreeLibraryAndExitThread(HMODULE, DWORD); // never returns + BOOL FreeResource(HGLOBAL); + UINT GetAtomNameA(ATOM, LPSTR, int); + UINT GetAtomNameW(ATOM, LPWSTR, int); + LPSTR GetCommandLineA(); + LPWSTR GetCommandLineW(); + BOOL GetCommConfig(HANDLE, LPCOMMCONFIG, PDWORD); + BOOL GetCommMask(HANDLE, PDWORD); + BOOL GetCommModemStatus(HANDLE, PDWORD); + BOOL GetCommProperties(HANDLE, LPCOMMPROP); + BOOL GetCommState(HANDLE, LPDCB); + BOOL GetCommTimeouts(HANDLE, LPCOMMTIMEOUTS); + BOOL GetComputerNameA(LPSTR, PDWORD); + BOOL GetComputerNameW(LPWSTR, PDWORD); + DWORD GetCurrentDirectoryA(DWORD, LPSTR); + DWORD GetCurrentDirectoryW(DWORD, LPWSTR); + HANDLE GetCurrentProcess(); + DWORD GetCurrentProcessId(); + HANDLE GetCurrentThread(); +/* In MinGW: +#ifdef _WIN32_WCE +extern DWORD GetCurrentThreadId(void); +#else +WINBASEAPI DWORD WINAPI GetCurrentThreadId(void); +#endif +*/ + DWORD GetCurrentThreadId(); + + alias GetTickCount GetCurrentTime; + + BOOL GetDefaultCommConfigA(LPCSTR, LPCOMMCONFIG, PDWORD); + BOOL GetDefaultCommConfigW(LPCWSTR, LPCOMMCONFIG, PDWORD); + BOOL GetDiskFreeSpaceA(LPCSTR, PDWORD, PDWORD, PDWORD, PDWORD); + BOOL GetDiskFreeSpaceW(LPCWSTR, PDWORD, PDWORD, PDWORD, PDWORD); + BOOL GetDiskFreeSpaceExA(LPCSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER); + BOOL GetDiskFreeSpaceExW(LPCWSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER); + UINT GetDriveTypeA(LPCSTR); + UINT GetDriveTypeW(LPCWSTR); + LPSTR GetEnvironmentStringsA(); + LPWSTR GetEnvironmentStringsW(); + DWORD GetEnvironmentVariableA(LPCSTR, LPSTR, DWORD); + DWORD GetEnvironmentVariableW(LPCWSTR, LPWSTR, DWORD); + BOOL GetExitCodeProcess(HANDLE, PDWORD); + BOOL GetExitCodeThread(HANDLE, PDWORD); + DWORD GetFileAttributesA(LPCSTR); + DWORD GetFileAttributesW(LPCWSTR); + BOOL GetFileInformationByHandle(HANDLE, LPBY_HANDLE_FILE_INFORMATION); + DWORD GetFileSize(HANDLE, PDWORD); + BOOL GetFileTime(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME); + DWORD GetFileType(HANDLE); + DWORD GetFinalPathNameByHandleA(HANDLE, LPSTR, DWORD, DWORD); + DWORD GetFinalPathNameByHandleW(HANDLE, LPWSTR, DWORD, DWORD); + DWORD GetFullPathNameA(LPCSTR, DWORD, LPSTR, LPSTR*); + DWORD GetFullPathNameW(LPCWSTR, DWORD, LPWSTR, LPWSTR*); + DWORD GetLastError() @trusted; + void GetLocalTime(LPSYSTEMTIME); + DWORD GetLogicalDrives(); + DWORD GetLogicalDriveStringsA(DWORD, LPSTR); + DWORD GetLogicalDriveStringsW(DWORD, LPWSTR); + BOOL GetMailslotInfo(HANDLE, PDWORD, PDWORD, PDWORD, PDWORD); + DWORD GetModuleFileNameA(HINSTANCE, LPSTR, DWORD); + DWORD GetModuleFileNameW(HINSTANCE, LPWSTR, DWORD); + HMODULE GetModuleHandleA(LPCSTR); + HMODULE GetModuleHandleW(LPCWSTR); + BOOL GetNamedPipeHandleStateA(HANDLE, PDWORD, PDWORD, PDWORD, PDWORD, LPSTR, DWORD); + BOOL GetNamedPipeHandleStateW(HANDLE, PDWORD, PDWORD, PDWORD, PDWORD, LPWSTR, DWORD); + BOOL GetNamedPipeInfo(HANDLE, PDWORD, PDWORD, PDWORD, PDWORD); + BOOL GetOverlappedResult(HANDLE, LPOVERLAPPED, PDWORD, BOOL); + DWORD GetPriorityClass(HANDLE); + UINT GetPrivateProfileIntA(LPCSTR, LPCSTR, INT, LPCSTR); + UINT GetPrivateProfileIntW(LPCWSTR, LPCWSTR, INT, LPCWSTR); + DWORD GetPrivateProfileSectionA(LPCSTR, LPSTR, DWORD, LPCSTR); + DWORD GetPrivateProfileSectionW(LPCWSTR, LPWSTR, DWORD, LPCWSTR); + DWORD GetPrivateProfileSectionNamesA(LPSTR, DWORD, LPCSTR); + DWORD GetPrivateProfileSectionNamesW(LPWSTR, DWORD, LPCWSTR); + DWORD GetPrivateProfileStringA(LPCSTR, LPCSTR, LPCSTR, LPSTR, DWORD, LPCSTR); + DWORD GetPrivateProfileStringW(LPCWSTR, LPCWSTR, LPCWSTR, LPWSTR, DWORD, LPCWSTR); + BOOL GetPrivateProfileStructA(LPCSTR, LPCSTR, LPVOID, UINT, LPCSTR); + BOOL GetPrivateProfileStructW(LPCWSTR, LPCWSTR, LPVOID, UINT, LPCWSTR); + FARPROC GetProcAddress(HMODULE, LPCSTR); // 1st param wrongly HINSTANCE in MinGW + BOOL GetProcessAffinityMask(HANDLE, PDWORD_PTR, PDWORD_PTR); + DWORD GetProcessVersion(DWORD); + UINT GetProfileIntA(LPCSTR, LPCSTR, INT); + UINT GetProfileIntW(LPCWSTR, LPCWSTR, INT); + DWORD GetProfileSectionA(LPCSTR, LPSTR, DWORD); + DWORD GetProfileSectionW(LPCWSTR, LPWSTR, DWORD); + DWORD GetProfileStringA(LPCSTR, LPCSTR, LPCSTR, LPSTR, DWORD); + DWORD GetProfileStringW(LPCWSTR, LPCWSTR, LPCWSTR, LPWSTR, DWORD); + DWORD GetShortPathNameA(LPCSTR, LPSTR, DWORD); + DWORD GetShortPathNameW(LPCWSTR, LPWSTR, DWORD); + VOID GetStartupInfoA(LPSTARTUPINFOA); + VOID GetStartupInfoW(LPSTARTUPINFOW); + HANDLE GetStdHandle(DWORD); + UINT GetSystemDirectoryA(LPSTR, UINT); + UINT GetSystemDirectoryW(LPWSTR, UINT); + VOID GetSystemInfo(LPSYSTEM_INFO); + VOID GetSystemTime(LPSYSTEMTIME); + BOOL GetSystemTimeAdjustment(PDWORD, PDWORD, PBOOL); + void GetSystemTimeAsFileTime(LPFILETIME); + UINT GetTempFileNameA(LPCSTR, LPCSTR, UINT, LPSTR); + UINT GetTempFileNameW(LPCWSTR, LPCWSTR, UINT, LPWSTR); + DWORD GetTempPathA(DWORD, LPSTR); + DWORD GetTempPathW(DWORD, LPWSTR); + BOOL GetThreadContext(HANDLE, LPCONTEXT); + int GetThreadPriority(HANDLE); + BOOL GetThreadSelectorEntry(HANDLE, DWORD, LPLDT_ENTRY); + DWORD GetTickCount(); + DWORD GetTimeZoneInformation(LPTIME_ZONE_INFORMATION); + BOOL GetUserNameA (LPSTR, PDWORD); + BOOL GetUserNameW(LPWSTR, PDWORD); + DWORD GetVersion(); + BOOL GetVersionExA(LPOSVERSIONINFOA); + BOOL GetVersionExW(LPOSVERSIONINFOW); + BOOL GetVolumeInformationA(LPCSTR, LPSTR, DWORD, PDWORD, PDWORD, PDWORD, LPSTR, DWORD); + BOOL GetVolumeInformationW(LPCWSTR, LPWSTR, DWORD, PDWORD, PDWORD, PDWORD, LPWSTR, DWORD); + UINT GetWindowsDirectoryA(LPSTR, UINT); + UINT GetWindowsDirectoryW(LPWSTR, UINT); + DWORD GetWindowThreadProcessId(HWND, PDWORD); + ATOM GlobalAddAtomA(LPCSTR); + ATOM GlobalAddAtomW(LPCWSTR); + ATOM GlobalDeleteAtom(ATOM); + ATOM GlobalFindAtomA(LPCSTR); + ATOM GlobalFindAtomW(LPCWSTR); + UINT GlobalGetAtomNameA(ATOM, LPSTR, int); + UINT GlobalGetAtomNameW(ATOM, LPWSTR, int); + + bool HasOverlappedIoCompleted(LPOVERLAPPED lpOverlapped) { + return lpOverlapped.Internal != STATUS_PENDING; + } + + BOOL InitAtomTable(DWORD); + VOID InitializeCriticalSection(LPCRITICAL_SECTION) @trusted; + /* ??? The next two are allegedly obsolete and "supported only for + * backward compatibility with the 16-bit Windows API". Yet the + * replacements IsBadReadPtr and IsBadWritePtr are apparently Win2000+ + * only. Where's the mistake? + */ + BOOL IsBadHugeReadPtr(PCVOID, UINT_PTR); + BOOL IsBadHugeWritePtr(PVOID, UINT_PTR); + BOOL IsBadReadPtr(PCVOID, UINT_PTR); + BOOL IsBadStringPtrA(LPCSTR, UINT_PTR); + BOOL IsBadStringPtrW(LPCWSTR, UINT_PTR); + BOOL IsBadWritePtr(PVOID, UINT_PTR); + void LeaveCriticalSection(LPCRITICAL_SECTION); + void LeaveCriticalSection(shared(CRITICAL_SECTION)*); + HINSTANCE LoadLibraryA(LPCSTR); + HINSTANCE LoadLibraryW(LPCWSTR); + HINSTANCE LoadLibraryExA(LPCSTR, HANDLE, DWORD); + HINSTANCE LoadLibraryExW(LPCWSTR, HANDLE, DWORD); + DWORD LoadModule(LPCSTR, PVOID); + HGLOBAL LoadResource(HINSTANCE, HRSRC); + BOOL LocalFileTimeToFileTime(const(FILETIME)*, LPFILETIME); + BOOL LockFile(HANDLE, DWORD, DWORD, DWORD, DWORD); + PVOID LockResource(HGLOBAL); + + LPSTR lstrcatA(LPSTR, LPCSTR); + LPWSTR lstrcatW(LPWSTR, LPCWSTR); + int lstrcmpA(LPCSTR, LPCSTR); + int lstrcmpiA(LPCSTR, LPCSTR); + int lstrcmpiW(LPCWSTR, LPCWSTR); + int lstrcmpW(LPCWSTR, LPCWSTR); + LPSTR lstrcpyA(LPSTR, LPCSTR); + LPSTR lstrcpynA(LPSTR, LPCSTR, int); + LPWSTR lstrcpynW(LPWSTR, LPCWSTR, int); + LPWSTR lstrcpyW(LPWSTR, LPCWSTR); + int lstrlenA(LPCSTR); + int lstrlenW(LPCWSTR); + + BOOL MoveFileA(LPCSTR, LPCSTR); + BOOL MoveFileW(LPCWSTR, LPCWSTR); + int MulDiv(int, int, int); + HANDLE OpenEventA(DWORD, BOOL, LPCSTR); + HANDLE OpenEventW(DWORD, BOOL, LPCWSTR); + deprecated HFILE OpenFile(LPCSTR, LPOFSTRUCT, UINT); + HANDLE OpenMutexA(DWORD, BOOL, LPCSTR); + HANDLE OpenMutexW(DWORD, BOOL, LPCWSTR); + HANDLE OpenProcess(DWORD, BOOL, DWORD); + HANDLE OpenSemaphoreA(DWORD, BOOL, LPCSTR); + HANDLE OpenSemaphoreW(DWORD, BOOL, LPCWSTR); + void OutputDebugStringA(LPCSTR); + void OutputDebugStringW(LPCWSTR); + BOOL PeekNamedPipe(HANDLE, PVOID, DWORD, PDWORD, PDWORD, PDWORD); + BOOL PulseEvent(HANDLE); + BOOL PurgeComm(HANDLE, DWORD); + BOOL QueryPerformanceCounter(PLARGE_INTEGER); + BOOL QueryPerformanceFrequency(PLARGE_INTEGER); + DWORD QueueUserAPC(PAPCFUNC, HANDLE, ULONG_PTR); + void RaiseException(DWORD, DWORD, DWORD, const(ULONG_PTR)*); + BOOL ReadFile(HANDLE, PVOID, DWORD, PDWORD, LPOVERLAPPED); + BOOL ReadFileEx(HANDLE, PVOID, DWORD, LPOVERLAPPED, LPOVERLAPPED_COMPLETION_ROUTINE); + BOOL ReadProcessMemory(HANDLE, PCVOID, PVOID, SIZE_T, SIZE_T*); + BOOL ReleaseMutex(HANDLE); + BOOL ReleaseSemaphore(HANDLE, LONG, LPLONG); + BOOL RemoveDirectoryA(LPCSTR); + BOOL RemoveDirectoryW(LPCWSTR); +/* In MinGW: +#ifdef _WIN32_WCE +extern BOOL ResetEvent(HANDLE); +#else +WINBASEAPI BOOL WINAPI ResetEvent(HANDLE); +#endif +*/ + BOOL ResetEvent(HANDLE); + DWORD ResumeThread(HANDLE); + DWORD SearchPathA(LPCSTR, LPCSTR, LPCSTR, DWORD, LPSTR, LPSTR*); + DWORD SearchPathW(LPCWSTR, LPCWSTR, LPCWSTR, DWORD, LPWSTR, LPWSTR*); + BOOL SetCommBreak(HANDLE); + BOOL SetCommConfig(HANDLE, LPCOMMCONFIG, DWORD); + BOOL SetCommMask(HANDLE, DWORD); + BOOL SetCommState(HANDLE, LPDCB); + BOOL SetCommTimeouts(HANDLE, LPCOMMTIMEOUTS); + BOOL SetComputerNameA(LPCSTR); + BOOL SetComputerNameW(LPCWSTR); + BOOL SetCurrentDirectoryA(LPCSTR); + BOOL SetCurrentDirectoryW(LPCWSTR); + BOOL SetDefaultCommConfigA(LPCSTR, LPCOMMCONFIG, DWORD); + BOOL SetDefaultCommConfigW(LPCWSTR, LPCOMMCONFIG, DWORD); + BOOL SetEndOfFile(HANDLE); + BOOL SetEnvironmentVariableA(LPCSTR, LPCSTR); + BOOL SetEnvironmentVariableW(LPCWSTR, LPCWSTR); + UINT SetErrorMode(UINT); +/* In MinGW: +#ifdef _WIN32_WCE +extern BOOL SetEvent(HANDLE); +#else +WINBASEAPI BOOL WINAPI SetEvent(HANDLE); +#endif +*/ + BOOL SetEvent(HANDLE); + VOID SetFileApisToANSI(); + VOID SetFileApisToOEM(); + BOOL SetFileAttributesA(LPCSTR, DWORD); + BOOL SetFileAttributesW(LPCWSTR, DWORD); + DWORD SetFilePointer(HANDLE, LONG, PLONG, DWORD); + BOOL SetFileTime(HANDLE, const(FILETIME)*, const(FILETIME)*, const(FILETIME)*); + deprecated UINT SetHandleCount(UINT); + void SetLastError(DWORD); + void SetLastErrorEx(DWORD, DWORD); + BOOL SetLocalTime(const(SYSTEMTIME)*); + BOOL SetMailslotInfo(HANDLE, DWORD); + BOOL SetNamedPipeHandleState(HANDLE, PDWORD, PDWORD, PDWORD); + BOOL SetPriorityClass(HANDLE, DWORD); + BOOL SetStdHandle(DWORD, HANDLE); + BOOL SetSystemTime(const(SYSTEMTIME)*); + DWORD_PTR SetThreadAffinityMask(HANDLE, DWORD_PTR); + BOOL SetThreadContext(HANDLE, const(CONTEXT)*); + BOOL SetThreadPriority(HANDLE, int); + BOOL SetTimeZoneInformation(const(TIME_ZONE_INFORMATION)*); + LPTOP_LEVEL_EXCEPTION_FILTER SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER); + BOOL SetupComm(HANDLE, DWORD, DWORD); + BOOL SetVolumeLabelA(LPCSTR, LPCSTR); + BOOL SetVolumeLabelW(LPCWSTR, LPCWSTR); + + DWORD SizeofResource(HINSTANCE, HRSRC); + void Sleep(DWORD); + DWORD SleepEx(DWORD, BOOL); + DWORD SuspendThread(HANDLE); + BOOL SystemTimeToFileTime(const(SYSTEMTIME)*, LPFILETIME); + BOOL TerminateProcess(HANDLE, UINT); + BOOL TerminateThread(HANDLE, DWORD); + DWORD TlsAlloc(); + BOOL TlsFree(DWORD); + PVOID TlsGetValue(DWORD); + BOOL TlsSetValue(DWORD, PVOID); + BOOL TransactNamedPipe(HANDLE, PVOID, DWORD, PVOID, DWORD, PDWORD, LPOVERLAPPED); + BOOL TransmitCommChar(HANDLE, char); + LONG UnhandledExceptionFilter(LPEXCEPTION_POINTERS); + BOOL UnlockFile(HANDLE, DWORD, DWORD, DWORD, DWORD); + BOOL WaitCommEvent(HANDLE, PDWORD, LPOVERLAPPED); + BOOL WaitForDebugEvent(LPDEBUG_EVENT, DWORD); + DWORD WaitForMultipleObjects(DWORD, const(HANDLE)*, BOOL, DWORD); + DWORD WaitForMultipleObjectsEx(DWORD, const(HANDLE)*, BOOL, DWORD, BOOL); + DWORD WaitForSingleObject(HANDLE, DWORD); + DWORD WaitForSingleObjectEx(HANDLE, DWORD, BOOL); + BOOL WaitNamedPipeA(LPCSTR, DWORD); + BOOL WaitNamedPipeW(LPCWSTR, DWORD); + // undocumented on MSDN + BOOL WinLoadTrustProvider(GUID*); + BOOL WriteFile(HANDLE, PCVOID, DWORD, PDWORD, LPOVERLAPPED); + BOOL WriteFileEx(HANDLE, PCVOID, DWORD, LPOVERLAPPED, LPOVERLAPPED_COMPLETION_ROUTINE); + BOOL WritePrivateProfileSectionA(LPCSTR, LPCSTR, LPCSTR); + BOOL WritePrivateProfileSectionW(LPCWSTR, LPCWSTR, LPCWSTR); + BOOL WritePrivateProfileStringA(LPCSTR, LPCSTR, LPCSTR, LPCSTR); + BOOL WritePrivateProfileStringW(LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR); + BOOL WritePrivateProfileStructA(LPCSTR, LPCSTR, LPVOID, UINT, LPCSTR); + BOOL WritePrivateProfileStructW(LPCWSTR, LPCWSTR, LPVOID, UINT, LPCWSTR); + BOOL WriteProcessMemory(HANDLE, LPVOID, LPCVOID, SIZE_T, SIZE_T*); + BOOL WriteProfileSectionA(LPCSTR, LPCSTR); + BOOL WriteProfileSectionW(LPCWSTR, LPCWSTR); + BOOL WriteProfileStringA(LPCSTR, LPCSTR, LPCSTR); + BOOL WriteProfileStringW(LPCWSTR, LPCWSTR, LPCWSTR); + + /* Memory allocation functions. + * MSDN documents these erroneously as Win2000+; thus it is uncertain what + * version compatibility they really have. + */ + HGLOBAL GlobalAlloc(UINT, SIZE_T); + HGLOBAL GlobalDiscard(HGLOBAL); + HGLOBAL GlobalFree(HGLOBAL); + HGLOBAL GlobalHandle(PCVOID); + LPVOID GlobalLock(HGLOBAL); + VOID GlobalMemoryStatus(LPMEMORYSTATUS); + HGLOBAL GlobalReAlloc(HGLOBAL, SIZE_T, UINT); + SIZE_T GlobalSize(HGLOBAL); + BOOL GlobalUnlock(HGLOBAL); + PVOID HeapAlloc(HANDLE, DWORD, SIZE_T); + SIZE_T HeapCompact(HANDLE, DWORD); + HANDLE HeapCreate(DWORD, SIZE_T, SIZE_T); + BOOL HeapDestroy(HANDLE); + BOOL HeapFree(HANDLE, DWORD, PVOID); + BOOL HeapLock(HANDLE); + PVOID HeapReAlloc(HANDLE, DWORD, PVOID, SIZE_T); + SIZE_T HeapSize(HANDLE, DWORD, PCVOID); + BOOL HeapUnlock(HANDLE); + BOOL HeapValidate(HANDLE, DWORD, PCVOID); + BOOL HeapWalk(HANDLE, LPPROCESS_HEAP_ENTRY); + HLOCAL LocalAlloc(UINT, SIZE_T); + HLOCAL LocalDiscard(HLOCAL); + HLOCAL LocalFree(HLOCAL); + HLOCAL LocalHandle(LPCVOID); + PVOID LocalLock(HLOCAL); + HLOCAL LocalReAlloc(HLOCAL, SIZE_T, UINT); + SIZE_T LocalSize(HLOCAL); + BOOL LocalUnlock(HLOCAL); + PVOID VirtualAlloc(PVOID, SIZE_T, DWORD, DWORD); + PVOID VirtualAllocEx(HANDLE, PVOID, SIZE_T, DWORD, DWORD); + BOOL VirtualFree(PVOID, SIZE_T, DWORD); + BOOL VirtualFreeEx(HANDLE, PVOID, SIZE_T, DWORD); + BOOL VirtualLock(PVOID, SIZE_T); + BOOL VirtualProtect(PVOID, SIZE_T, DWORD, PDWORD); + BOOL VirtualProtectEx(HANDLE, PVOID, SIZE_T, DWORD, PDWORD); + SIZE_T VirtualQuery(LPCVOID, PMEMORY_BASIC_INFORMATION, SIZE_T); + SIZE_T VirtualQueryEx(HANDLE, LPCVOID, PMEMORY_BASIC_INFORMATION, SIZE_T); + BOOL VirtualUnlock(PVOID, SIZE_T); +// not in MinGW 4.0 - ??? + static if (_WIN32_WINNT >= 0x600) { + BOOL CancelIoEx(HANDLE, LPOVERLAPPED); + } + + BOOL CancelIo(HANDLE); + BOOL CancelWaitableTimer(HANDLE); + PVOID ConvertThreadToFiber(PVOID); + LPVOID CreateFiber(SIZE_T, LPFIBER_START_ROUTINE, LPVOID); + HANDLE CreateWaitableTimerA(LPSECURITY_ATTRIBUTES, BOOL, LPCSTR); + HANDLE CreateWaitableTimerW(LPSECURITY_ATTRIBUTES, BOOL, LPCWSTR); + void DeleteFiber(PVOID); + BOOL GetFileAttributesExA(LPCSTR, GET_FILEEX_INFO_LEVELS, PVOID); + BOOL GetFileAttributesExW(LPCWSTR, GET_FILEEX_INFO_LEVELS, PVOID); + DWORD GetLongPathNameA(LPCSTR, LPSTR, DWORD); + DWORD GetLongPathNameW(LPCWSTR, LPWSTR, DWORD); + BOOL InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION, DWORD); + BOOL IsDebuggerPresent(); + HANDLE OpenWaitableTimerA(DWORD, BOOL, LPCSTR); + HANDLE OpenWaitableTimerW(DWORD, BOOL, LPCWSTR); + DWORD QueryDosDeviceA(LPCSTR, LPSTR, DWORD); + DWORD QueryDosDeviceW(LPCWSTR, LPWSTR, DWORD); + BOOL SetWaitableTimer(HANDLE, const(LARGE_INTEGER)*, LONG, PTIMERAPCROUTINE, PVOID, BOOL); + void SwitchToFiber(PVOID); + + static if (_WIN32_WINNT >= 0x500) { + HANDLE OpenThread(DWORD, BOOL, DWORD); + } + + BOOL AccessCheck(PSECURITY_DESCRIPTOR, HANDLE, DWORD, PGENERIC_MAPPING, PPRIVILEGE_SET, PDWORD, PDWORD, PBOOL); + BOOL AccessCheckAndAuditAlarmA(LPCSTR, LPVOID, LPSTR, LPSTR, PSECURITY_DESCRIPTOR, DWORD, PGENERIC_MAPPING, BOOL, PDWORD, PBOOL, PBOOL); + BOOL AccessCheckAndAuditAlarmW(LPCWSTR, LPVOID, LPWSTR, LPWSTR, PSECURITY_DESCRIPTOR, DWORD, PGENERIC_MAPPING, BOOL, PDWORD, PBOOL, PBOOL); + BOOL AddAccessAllowedAce(PACL, DWORD, DWORD, PSID); + BOOL AddAccessDeniedAce(PACL, DWORD, DWORD, PSID); + BOOL AddAce(PACL, DWORD, DWORD, PVOID, DWORD); + BOOL AddAuditAccessAce(PACL, DWORD, DWORD, PSID, BOOL, BOOL); + BOOL AdjustTokenGroups(HANDLE, BOOL, PTOKEN_GROUPS, DWORD, PTOKEN_GROUPS, PDWORD); + BOOL AdjustTokenPrivileges(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD); + BOOL AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY, BYTE, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, PSID*); + BOOL AllocateLocallyUniqueId(PLUID); + BOOL AreAllAccessesGranted(DWORD, DWORD); + BOOL AreAnyAccessesGranted(DWORD, DWORD); + BOOL BackupEventLogA(HANDLE, LPCSTR); + BOOL BackupEventLogW(HANDLE, LPCWSTR); + BOOL BackupRead(HANDLE, LPBYTE, DWORD, LPDWORD, BOOL, BOOL, LPVOID*); + BOOL BackupSeek(HANDLE, DWORD, DWORD, LPDWORD, LPDWORD, LPVOID*); + BOOL BackupWrite(HANDLE, LPBYTE, DWORD, LPDWORD, BOOL, BOOL, LPVOID*); + BOOL ClearEventLogA(HANDLE, LPCSTR); + BOOL ClearEventLogW(HANDLE, LPCWSTR); + BOOL CloseEventLog(HANDLE); + BOOL ConnectNamedPipe(HANDLE, LPOVERLAPPED); + BOOL CopySid(DWORD, PSID, PSID); + HANDLE CreateNamedPipeA(LPCSTR, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, LPSECURITY_ATTRIBUTES); + HANDLE CreateNamedPipeW(LPCWSTR, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, LPSECURITY_ATTRIBUTES); + BOOL CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR, PSECURITY_DESCRIPTOR, PSECURITY_DESCRIPTOR*, BOOL, HANDLE, PGENERIC_MAPPING); + BOOL CreateProcessAsUserA(HANDLE, LPCSTR, LPSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, PVOID, LPCSTR, LPSTARTUPINFOA, LPPROCESS_INFORMATION); + BOOL CreateProcessAsUserW(HANDLE, LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, PVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION); + HANDLE CreateRemoteThread(HANDLE, LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD); + DWORD CreateTapePartition(HANDLE, DWORD, DWORD, DWORD); + BOOL DefineDosDeviceA(DWORD, LPCSTR, LPCSTR); + BOOL DefineDosDeviceW(DWORD, LPCWSTR, LPCWSTR); + BOOL DeleteAce(PACL, DWORD); + BOOL DeregisterEventSource(HANDLE); + BOOL DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR*); + BOOL DeviceIoControl(HANDLE, DWORD, PVOID, DWORD, PVOID, DWORD, PDWORD, POVERLAPPED); + BOOL DisconnectNamedPipe(HANDLE); + BOOL DuplicateToken(HANDLE, SECURITY_IMPERSONATION_LEVEL, PHANDLE); + BOOL DuplicateTokenEx(HANDLE, DWORD, LPSECURITY_ATTRIBUTES, SECURITY_IMPERSONATION_LEVEL, TOKEN_TYPE, PHANDLE); + BOOL EqualPrefixSid(PSID, PSID); + BOOL EqualSid(PSID, PSID); + DWORD EraseTape(HANDLE, DWORD, BOOL); + HANDLE FindFirstFileExA(LPCSTR, FINDEX_INFO_LEVELS, PVOID, FINDEX_SEARCH_OPS, PVOID, DWORD); + HANDLE FindFirstFileExW(LPCWSTR, FINDEX_INFO_LEVELS, PVOID, FINDEX_SEARCH_OPS, PVOID, DWORD); + BOOL FindFirstFreeAce(PACL, PVOID*); + PVOID FreeSid(PSID); + BOOL GetAce(PACL, DWORD, LPVOID*); + BOOL GetAclInformation(PACL, PVOID, DWORD, ACL_INFORMATION_CLASS); + BOOL GetBinaryTypeA(LPCSTR, PDWORD); + BOOL GetBinaryTypeW(LPCWSTR, PDWORD); + DWORD GetCompressedFileSizeA(LPCSTR, PDWORD); + DWORD GetCompressedFileSizeW(LPCWSTR, PDWORD); + BOOL GetCurrentHwProfileA(LPHW_PROFILE_INFOA); + BOOL GetCurrentHwProfileW(LPHW_PROFILE_INFOW); + BOOL GetFileSecurityA(LPCSTR, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, DWORD, PDWORD); + BOOL GetFileSecurityW(LPCWSTR, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, DWORD, PDWORD); + BOOL GetHandleInformation(HANDLE, PDWORD); + BOOL GetKernelObjectSecurity(HANDLE, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, DWORD, PDWORD); + DWORD GetLengthSid(PSID); + BOOL GetNumberOfEventLogRecords(HANDLE, PDWORD); + BOOL GetOldestEventLogRecord(HANDLE, PDWORD); + BOOL GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, DWORD, PDWORD); + BOOL GetProcessPriorityBoost(HANDLE, PBOOL); + BOOL GetProcessShutdownParameters(PDWORD, PDWORD); + BOOL GetProcessTimes(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME); + HWINSTA GetProcessWindowStation(); + BOOL GetProcessWorkingSetSize(HANDLE, PSIZE_T, PSIZE_T); + BOOL GetQueuedCompletionStatus(HANDLE, PDWORD, PULONG_PTR, LPOVERLAPPED*, DWORD); + BOOL GetSecurityDescriptorControl(PSECURITY_DESCRIPTOR, PSECURITY_DESCRIPTOR_CONTROL, PDWORD); + BOOL GetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR, LPBOOL, PACL*, LPBOOL); + BOOL GetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR, PSID*, LPBOOL); + DWORD GetSecurityDescriptorLength(PSECURITY_DESCRIPTOR); + BOOL GetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR, PSID*, LPBOOL); + BOOL GetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR, LPBOOL, PACL*, LPBOOL); + PSID_IDENTIFIER_AUTHORITY GetSidIdentifierAuthority(PSID); + DWORD GetSidLengthRequired(UCHAR); + PDWORD GetSidSubAuthority(PSID, DWORD); + PUCHAR GetSidSubAuthorityCount(PSID); + DWORD GetTapeParameters(HANDLE, DWORD, PDWORD, PVOID); + DWORD GetTapePosition(HANDLE, DWORD, PDWORD, PDWORD, PDWORD); + DWORD GetTapeStatus(HANDLE); + BOOL GetThreadPriorityBoost(HANDLE, PBOOL); + BOOL GetThreadTimes(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME); + BOOL GetTokenInformation(HANDLE, TOKEN_INFORMATION_CLASS, PVOID, DWORD, PDWORD); + BOOL ImpersonateLoggedOnUser(HANDLE); + BOOL ImpersonateNamedPipeClient(HANDLE); + BOOL ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL); + BOOL InitializeAcl(PACL, DWORD, DWORD); + DWORD SetCriticalSectionSpinCount(LPCRITICAL_SECTION, DWORD); + BOOL InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR, DWORD); + BOOL InitializeSid(PSID, PSID_IDENTIFIER_AUTHORITY, BYTE); + BOOL IsProcessorFeaturePresent(DWORD); + BOOL IsTextUnicode(PCVOID, int, LPINT); + BOOL IsValidAcl(PACL); + BOOL IsValidSecurityDescriptor(PSECURITY_DESCRIPTOR); + BOOL IsValidSid(PSID); + BOOL CreateWellKnownSid(WELL_KNOWN_SID_TYPE, PSID, PSID, PDWORD); + BOOL LockFileEx(HANDLE, DWORD, DWORD, DWORD, DWORD, LPOVERLAPPED); + BOOL LogonUserA(LPSTR, LPSTR, LPSTR, DWORD, DWORD, PHANDLE); + BOOL LogonUserW(LPWSTR, LPWSTR, LPWSTR, DWORD, DWORD, PHANDLE); + BOOL LookupAccountNameA(LPCSTR, LPCSTR, PSID, PDWORD, LPSTR, PDWORD, PSID_NAME_USE); + BOOL LookupAccountNameW(LPCWSTR, LPCWSTR, PSID, PDWORD, LPWSTR, PDWORD, PSID_NAME_USE); + BOOL LookupAccountSidA(LPCSTR, PSID, LPSTR, PDWORD, LPSTR, PDWORD, PSID_NAME_USE); + BOOL LookupAccountSidW(LPCWSTR, PSID, LPWSTR, PDWORD, LPWSTR, PDWORD, PSID_NAME_USE); + BOOL LookupPrivilegeDisplayNameA(LPCSTR, LPCSTR, LPSTR, PDWORD, PDWORD); + BOOL LookupPrivilegeDisplayNameW(LPCWSTR, LPCWSTR, LPWSTR, PDWORD, PDWORD); + BOOL LookupPrivilegeNameA(LPCSTR, PLUID, LPSTR, PDWORD); + BOOL LookupPrivilegeNameW(LPCWSTR, PLUID, LPWSTR, PDWORD); + BOOL LookupPrivilegeValueA(LPCSTR, LPCSTR, PLUID); + BOOL LookupPrivilegeValueW(LPCWSTR, LPCWSTR, PLUID); + BOOL MakeAbsoluteSD(PSECURITY_DESCRIPTOR, PSECURITY_DESCRIPTOR, PDWORD, PACL, PDWORD, PACL, PDWORD, PSID, PDWORD, PSID, PDWORD); + BOOL MakeSelfRelativeSD(PSECURITY_DESCRIPTOR, PSECURITY_DESCRIPTOR, PDWORD); + VOID MapGenericMask(PDWORD, PGENERIC_MAPPING); + BOOL MoveFileExA(LPCSTR, LPCSTR, DWORD); + BOOL MoveFileExW(LPCWSTR, LPCWSTR, DWORD); + BOOL NotifyChangeEventLog(HANDLE, HANDLE); + BOOL ObjectCloseAuditAlarmA(LPCSTR, PVOID, BOOL); + BOOL ObjectCloseAuditAlarmW(LPCWSTR, PVOID, BOOL); + BOOL ObjectDeleteAuditAlarmA(LPCSTR, PVOID, BOOL); + BOOL ObjectDeleteAuditAlarmW(LPCWSTR, PVOID, BOOL); + BOOL ObjectOpenAuditAlarmA(LPCSTR, PVOID, LPSTR, LPSTR, PSECURITY_DESCRIPTOR, HANDLE, DWORD, DWORD, PPRIVILEGE_SET, BOOL, BOOL, PBOOL); + BOOL ObjectOpenAuditAlarmW(LPCWSTR, PVOID, LPWSTR, LPWSTR, PSECURITY_DESCRIPTOR, HANDLE, DWORD, DWORD, PPRIVILEGE_SET, BOOL, BOOL, PBOOL); + BOOL ObjectPrivilegeAuditAlarmA(LPCSTR, PVOID, HANDLE, DWORD, PPRIVILEGE_SET, BOOL); + BOOL ObjectPrivilegeAuditAlarmW(LPCWSTR, PVOID, HANDLE, DWORD, PPRIVILEGE_SET, BOOL); + HANDLE OpenBackupEventLogA(LPCSTR, LPCSTR); + HANDLE OpenBackupEventLogW(LPCWSTR, LPCWSTR); + HANDLE OpenEventLogA(LPCSTR, LPCSTR); + HANDLE OpenEventLogW(LPCWSTR, LPCWSTR); + BOOL OpenProcessToken(HANDLE, DWORD, PHANDLE); + BOOL OpenThreadToken(HANDLE, DWORD, BOOL, PHANDLE); + BOOL PostQueuedCompletionStatus(HANDLE, DWORD, ULONG_PTR, LPOVERLAPPED); + DWORD PrepareTape(HANDLE, DWORD, BOOL); + BOOL PrivilegeCheck(HANDLE, PPRIVILEGE_SET, PBOOL); + BOOL PrivilegedServiceAuditAlarmA(LPCSTR, LPCSTR, HANDLE, PPRIVILEGE_SET, BOOL); + BOOL PrivilegedServiceAuditAlarmW(LPCWSTR, LPCWSTR, HANDLE, PPRIVILEGE_SET, BOOL); + BOOL ReadDirectoryChangesW(HANDLE, PVOID, DWORD, BOOL, DWORD, PDWORD, LPOVERLAPPED, LPOVERLAPPED_COMPLETION_ROUTINE); + BOOL ReadEventLogA(HANDLE, DWORD, DWORD, PVOID, DWORD, DWORD*, DWORD*); + BOOL ReadEventLogW(HANDLE, DWORD, DWORD, PVOID, DWORD, DWORD*, DWORD*); + BOOL ReadFileScatter(HANDLE, FILE_SEGMENT_ELEMENT*, DWORD, LPDWORD, LPOVERLAPPED); + HANDLE RegisterEventSourceA (LPCSTR, LPCSTR); + HANDLE RegisterEventSourceW(LPCWSTR, LPCWSTR); + BOOL ReportEventA(HANDLE, WORD, WORD, DWORD, PSID, WORD, DWORD, LPCSTR*, PVOID); + BOOL ReportEventW(HANDLE, WORD, WORD, DWORD, PSID, WORD, DWORD, LPCWSTR*, PVOID); + BOOL RevertToSelf(); + BOOL SetAclInformation(PACL, PVOID, DWORD, ACL_INFORMATION_CLASS); + BOOL SetFileSecurityA(LPCSTR, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR); + BOOL SetFileSecurityW(LPCWSTR, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR); + BOOL SetHandleInformation(HANDLE, DWORD, DWORD); + BOOL SetKernelObjectSecurity(HANDLE, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR); + BOOL SetPrivateObjectSecurity(SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, PSECURITY_DESCRIPTOR*, PGENERIC_MAPPING, HANDLE); + BOOL SetProcessAffinityMask(HANDLE, DWORD_PTR); + BOOL SetProcessPriorityBoost(HANDLE, BOOL); + BOOL SetProcessShutdownParameters(DWORD, DWORD); + BOOL SetProcessWorkingSetSize(HANDLE, SIZE_T, SIZE_T); + BOOL SetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR, BOOL, PACL, BOOL); + BOOL SetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR, PSID, BOOL); + BOOL SetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR, PSID, BOOL); + BOOL SetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR, BOOL, PACL, BOOL); + BOOL SetSystemTimeAdjustment(DWORD, BOOL); + DWORD SetTapeParameters(HANDLE, DWORD, PVOID); + DWORD SetTapePosition(HANDLE, DWORD, DWORD, DWORD, DWORD, BOOL); + BOOL SetThreadPriorityBoost(HANDLE, BOOL); + BOOL SetThreadToken(PHANDLE, HANDLE); + BOOL SetTokenInformation(HANDLE, TOKEN_INFORMATION_CLASS, PVOID, DWORD); + DWORD SignalObjectAndWait(HANDLE, HANDLE, DWORD, BOOL); + BOOL SwitchToThread(); + BOOL SystemTimeToTzSpecificLocalTime(LPTIME_ZONE_INFORMATION, LPSYSTEMTIME, LPSYSTEMTIME); + BOOL TzSpecificLocalTimeToSystemTime(LPTIME_ZONE_INFORMATION, LPSYSTEMTIME, LPSYSTEMTIME); + BOOL TryEnterCriticalSection(LPCRITICAL_SECTION); + BOOL TryEnterCriticalSection(shared(CRITICAL_SECTION)*); + BOOL UnlockFileEx(HANDLE, DWORD, DWORD, DWORD, LPOVERLAPPED); + BOOL UpdateResourceA(HANDLE, LPCSTR, LPCSTR, WORD, PVOID, DWORD); + BOOL UpdateResourceW(HANDLE, LPCWSTR, LPCWSTR, WORD, PVOID, DWORD); + BOOL WriteFileGather(HANDLE, FILE_SEGMENT_ELEMENT*, DWORD, LPDWORD, LPOVERLAPPED); + DWORD WriteTapemark(HANDLE, DWORD, DWORD, BOOL); + + static if (_WIN32_WINNT >= 0x500) { + BOOL AddAccessAllowedAceEx(PACL, DWORD, DWORD, DWORD, PSID); + BOOL AddAccessDeniedAceEx(PACL, DWORD, DWORD, DWORD, PSID); + PVOID AddVectoredExceptionHandler(ULONG, PVECTORED_EXCEPTION_HANDLER); + BOOL AllocateUserPhysicalPages(HANDLE, PULONG_PTR, PULONG_PTR); + BOOL AssignProcessToJobObject(HANDLE, HANDLE); + BOOL ChangeTimerQueueTimer(HANDLE,HANDLE,ULONG,ULONG); + LPVOID CreateFiberEx(SIZE_T, SIZE_T, DWORD, LPFIBER_START_ROUTINE, LPVOID); + HANDLE CreateFileMappingA(HANDLE, LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCSTR); + HANDLE CreateFileMappingW(HANDLE, LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCWSTR); + BOOL CreateHardLinkA(LPCSTR, LPCSTR, LPSECURITY_ATTRIBUTES); + BOOL CreateHardLinkW(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES); + HANDLE CreateJobObjectA(LPSECURITY_ATTRIBUTES, LPCSTR); + HANDLE CreateJobObjectW(LPSECURITY_ATTRIBUTES, LPCWSTR); + BOOL CreateProcessWithLogonW(LPCWSTR, LPCWSTR, LPCWSTR, DWORD, LPCWSTR, LPWSTR, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION); + HANDLE CreateTimerQueue(); + BOOL CreateTimerQueueTimer(PHANDLE, HANDLE, WAITORTIMERCALLBACK, PVOID, DWORD, DWORD, ULONG); + BOOL DeleteTimerQueue(HANDLE); + BOOL DeleteTimerQueueEx(HANDLE, HANDLE); + BOOL DeleteTimerQueueTimer(HANDLE, HANDLE, HANDLE); + BOOL DeleteVolumeMountPointA(LPCSTR); + BOOL DeleteVolumeMountPointW(LPCWSTR); + BOOL DnsHostnameToComputerNameA(LPCSTR, LPSTR, LPDWORD); + BOOL DnsHostnameToComputerNameW(LPCWSTR, LPWSTR, LPDWORD); + BOOL EncryptFileA(LPCSTR); + BOOL EncryptFileW(LPCWSTR); + BOOL FileEncryptionStatusA(LPCSTR, LPDWORD); + BOOL FileEncryptionStatusW(LPCWSTR, LPDWORD); + HANDLE FindFirstVolumeA(LPCSTR, DWORD); + HANDLE FindFirstVolumeMountPointA(LPSTR, LPSTR, DWORD); + HANDLE FindFirstVolumeMountPointW(LPWSTR, LPWSTR, DWORD); + HANDLE FindFirstVolumeW(LPCWSTR, DWORD); + BOOL FindNextVolumeA(HANDLE, LPCSTR, DWORD); + BOOL FindNextVolumeW(HANDLE, LPWSTR, DWORD); + BOOL FindNextVolumeMountPointA(HANDLE, LPSTR, DWORD); + BOOL FindNextVolumeMountPointW(HANDLE, LPWSTR, DWORD); + BOOL FindVolumeClose(HANDLE); + BOOL FindVolumeMountPointClose(HANDLE); + BOOL FlushViewOfFile(PCVOID, SIZE_T); + BOOL FreeUserPhysicalPages(HANDLE, PULONG_PTR, PULONG_PTR); + BOOL GetComputerNameExA(COMPUTER_NAME_FORMAT, LPSTR, LPDWORD); + BOOL GetComputerNameExW(COMPUTER_NAME_FORMAT, LPWSTR, LPDWORD); + BOOL GetFileSizeEx(HANDLE, PLARGE_INTEGER); + BOOL GetModuleHandleExA(DWORD, LPCSTR, HMODULE*); + BOOL GetModuleHandleExW(DWORD, LPCWSTR, HMODULE*); + HANDLE GetProcessHeap(); + DWORD GetProcessHeaps(DWORD, PHANDLE); + BOOL GetProcessIoCounters(HANDLE, PIO_COUNTERS); + BOOL GetSystemPowerStatus(LPSYSTEM_POWER_STATUS); + UINT GetSystemWindowsDirectoryA(LPSTR, UINT); + UINT GetSystemWindowsDirectoryW(LPWSTR, UINT); + BOOL GetVolumeNameForVolumeMountPointA(LPCSTR, LPSTR, DWORD); + BOOL GetVolumeNameForVolumeMountPointW(LPCWSTR, LPWSTR, DWORD); + BOOL GetVolumePathNameA(LPCSTR, LPSTR, DWORD); + BOOL GetVolumePathNameW(LPCWSTR, LPWSTR, DWORD); + BOOL GlobalMemoryStatusEx(LPMEMORYSTATUSEX); + BOOL IsBadCodePtr(FARPROC); + BOOL IsSystemResumeAutomatic(); + BOOL MapUserPhysicalPages(PVOID, ULONG_PTR, PULONG_PTR); + BOOL MapUserPhysicalPagesScatter(PVOID*, ULONG_PTR, PULONG_PTR); + PVOID MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T); + PVOID MapViewOfFileEx(HANDLE, DWORD, DWORD, DWORD, SIZE_T, PVOID); + HANDLE OpenFileMappingA(DWORD, BOOL, LPCSTR); + HANDLE OpenFileMappingW(DWORD, BOOL, LPCWSTR); + BOOL ProcessIdToSessionId(DWORD, DWORD*); + BOOL QueryInformationJobObject(HANDLE, JOBOBJECTINFOCLASS, LPVOID, DWORD, LPDWORD); + ULONG RemoveVectoredExceptionHandler(PVOID); + BOOL ReplaceFileA(LPCSTR, LPCSTR, LPCSTR, DWORD, LPVOID, LPVOID); + BOOL ReplaceFileW(LPCWSTR, LPCWSTR, LPCWSTR, DWORD, LPVOID, LPVOID); + BOOL SetComputerNameExA(COMPUTER_NAME_FORMAT, LPCSTR); + BOOL SetComputerNameExW(COMPUTER_NAME_FORMAT, LPCWSTR); + BOOL SetFilePointerEx(HANDLE, LARGE_INTEGER, PLARGE_INTEGER, DWORD); + BOOL SetInformationJobObject(HANDLE, JOBOBJECTINFOCLASS, LPVOID, DWORD); + BOOL SetSecurityDescriptorControl(PSECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL, SECURITY_DESCRIPTOR_CONTROL); + BOOL SetSystemPowerState(BOOL, BOOL); + EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE); + DWORD SetThreadIdealProcessor(HANDLE, DWORD); + BOOL SetVolumeMountPointA(LPCSTR, LPCSTR); + BOOL SetVolumeMountPointW(LPCWSTR, LPCWSTR); + BOOL TerminateJobObject(HANDLE, UINT); + BOOL UnmapViewOfFile(PCVOID); + BOOL UnregisterWait(HANDLE); + BOOL UnregisterWaitEx(HANDLE, HANDLE); + BOOL VerifyVersionInfoA(LPOSVERSIONINFOEXA, DWORD, DWORDLONG); + BOOL VerifyVersionInfoW(LPOSVERSIONINFOEXW, DWORD, DWORDLONG); + } + + static if (_WIN32_WINNT >= 0x501) { + BOOL ActivateActCtx(HANDLE, ULONG_PTR*); + void AddRefActCtx(HANDLE); + BOOL CheckNameLegalDOS8Dot3A(LPCSTR, LPSTR, DWORD, PBOOL, PBOOL); + BOOL CheckNameLegalDOS8Dot3W(LPCWSTR, LPSTR, DWORD, PBOOL, PBOOL); + BOOL CheckRemoteDebuggerPresent(HANDLE, PBOOL); + BOOL ConvertFiberToThread(); + HANDLE CreateActCtxA(PCACTCTXA); + HANDLE CreateActCtxW(PCACTCTXW); + HANDLE CreateMemoryResourceNotification(MEMORY_RESOURCE_NOTIFICATION_TYPE); + BOOL DeactivateActCtx(DWORD, ULONG_PTR); + BOOL DebugActiveProcessStop(DWORD); + BOOL DebugBreakProcess(HANDLE); + BOOL DebugSetProcessKillOnExit(BOOL); + BOOL FindActCtxSectionGuid(DWORD, const(GUID)*, ULONG, const(GUID)*, + PACTCTX_SECTION_KEYED_DATA); + BOOL FindActCtxSectionStringA(DWORD, const(GUID)*, ULONG, LPCSTR, + PACTCTX_SECTION_KEYED_DATA); + BOOL FindActCtxSectionStringW(DWORD, const(GUID)*, ULONG, LPCWSTR, + PACTCTX_SECTION_KEYED_DATA); + BOOL GetCurrentActCtx(HANDLE*); + VOID GetNativeSystemInfo(LPSYSTEM_INFO); + BOOL GetProcessHandleCount(HANDLE, PDWORD); + BOOL GetSystemRegistryQuota(PDWORD, PDWORD); + BOOL GetSystemTimes(LPFILETIME, LPFILETIME, LPFILETIME); + UINT GetSystemWow64DirectoryA(LPSTR, UINT); + UINT GetSystemWow64DirectoryW(LPWSTR, UINT); + BOOL GetThreadIOPendingFlag(HANDLE, PBOOL); + BOOL GetVolumePathNamesForVolumeNameA(LPCSTR, LPSTR, DWORD, PDWORD); + BOOL GetVolumePathNamesForVolumeNameW(LPCWSTR, LPWSTR, DWORD, PDWORD); + UINT GetWriteWatch(DWORD, PVOID, SIZE_T, PVOID*, PULONG_PTR, PULONG); + BOOL HeapQueryInformation(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T, PSIZE_T); + BOOL HeapSetInformation(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T); + BOOL IsProcessInJob(HANDLE, HANDLE, PBOOL); + BOOL IsWow64Process(HANDLE, PBOOL); + BOOL QueryActCtxW(DWORD, HANDLE, PVOID, ULONG, PVOID, SIZE_T, SIZE_T*); + BOOL QueryMemoryResourceNotification(HANDLE, PBOOL); + void ReleaseActCtx(HANDLE); + UINT ResetWriteWatch(LPVOID, SIZE_T); + BOOL SetFileShortNameA(HANDLE, LPCSTR); + BOOL SetFileShortNameW(HANDLE, LPCWSTR); + BOOL SetFileValidData(HANDLE, LONGLONG); + BOOL ZombifyActCtx(HANDLE); + } + + static if (_WIN32_WINNT >= 0x502) { + DWORD GetFirmwareEnvironmentVariableA(LPCSTR, LPCSTR, PVOID, DWORD); + DWORD GetFirmwareEnvironmentVariableW(LPCWSTR, LPCWSTR, PVOID, DWORD); + DWORD GetDllDirectoryA(DWORD, LPSTR); + DWORD GetDllDirectoryW(DWORD, LPWSTR); + DWORD GetThreadId(HANDLE); + DWORD GetProcessId(HANDLE); + HANDLE ReOpenFile(HANDLE, DWORD, DWORD, DWORD); + BOOL SetDllDirectoryA(LPCSTR); + BOOL SetDllDirectoryW(LPCWSTR); + BOOL SetFirmwareEnvironmentVariableA(LPCSTR, LPCSTR, PVOID, DWORD); + BOOL SetFirmwareEnvironmentVariableW(LPCWSTR, LPCWSTR, PVOID, DWORD); + } + + // ??? + static if (_WIN32_WINNT >= 0x510) { + VOID RestoreLastError(DWORD); + } + + static if (_WIN32_WINNT >= 0x600) { + BOOL CreateSymbolicLinkA(LPCSTR, LPCSTR, DWORD); + BOOL CreateSymbolicLinkW(LPCWSTR, LPCWSTR, DWORD); + BOOL GetFileInformationByHandleEx(HANDLE, FILE_INFO_BY_HANDLE_CLASS, LPVOID, DWORD); + } +} + +// For compatibility with old urt.internal.sys.windows.windows: +version (LittleEndian) nothrow @nogc +{ + BOOL QueryPerformanceCounter()(long* lpPerformanceCount) { return QueryPerformanceCounter(cast(PLARGE_INTEGER)lpPerformanceCount); } + BOOL QueryPerformanceFrequency()(long* lpFrequency) { return QueryPerformanceFrequency(cast(PLARGE_INTEGER)lpFrequency); } +} + +mixin DECLARE_AW!("STARTUPINFO"); +version (Unicode) { + //alias STARTUPINFOW STARTUPINFO; + alias WIN32_FIND_DATAW WIN32_FIND_DATA; + alias ENUMRESLANGPROCW ENUMRESLANGPROC; + alias ENUMRESNAMEPROCW ENUMRESNAMEPROC; + alias ENUMRESTYPEPROCW ENUMRESTYPEPROC; + alias AddAtomW AddAtom; + alias BeginUpdateResourceW BeginUpdateResource; + alias BuildCommDCBW BuildCommDCB; + alias BuildCommDCBAndTimeoutsW BuildCommDCBAndTimeouts; + alias CallNamedPipeW CallNamedPipe; + alias CommConfigDialogW CommConfigDialog; + alias CopyFileW CopyFile; + alias CopyFileExW CopyFileEx; + alias CreateDirectoryW CreateDirectory; + alias CreateDirectoryExW CreateDirectoryEx; + alias CreateEventW CreateEvent; + alias CreateFileW CreateFile; + alias CreateMailslotW CreateMailslot; + alias CreateMutexW CreateMutex; + alias CreateProcessW CreateProcess; + alias CreateSemaphoreW CreateSemaphore; + alias DeleteFileW DeleteFile; + alias EndUpdateResourceW EndUpdateResource; + alias EnumResourceLanguagesW EnumResourceLanguages; + alias EnumResourceNamesW EnumResourceNames; + alias EnumResourceTypesW EnumResourceTypes; + alias ExpandEnvironmentStringsW ExpandEnvironmentStrings; + alias FatalAppExitW FatalAppExit; + alias FindAtomW FindAtom; + alias FindFirstChangeNotificationW FindFirstChangeNotification; + alias FindFirstFileW FindFirstFile; + alias FindNextFileW FindNextFile; + alias FindResourceW FindResource; + alias FindResourceExW FindResourceEx; +// alias FormatMessageW FormatMessage; + alias FreeEnvironmentStringsW FreeEnvironmentStrings; + alias GetAtomNameW GetAtomName; + alias GetCommandLineW GetCommandLine; + alias GetComputerNameW GetComputerName; + alias GetCurrentDirectoryW GetCurrentDirectory; + alias GetDefaultCommConfigW GetDefaultCommConfig; + alias GetDiskFreeSpaceW GetDiskFreeSpace; + alias GetDiskFreeSpaceExW GetDiskFreeSpaceEx; + alias GetDriveTypeW GetDriveType; + alias GetEnvironmentStringsW GetEnvironmentStrings; + alias GetEnvironmentVariableW GetEnvironmentVariable; + alias GetFileAttributesW GetFileAttributes; + alias GetFullPathNameW GetFullPathName; + alias GetLogicalDriveStringsW GetLogicalDriveStrings; + alias GetModuleFileNameW GetModuleFileName; + alias GetModuleHandleW GetModuleHandle; + alias GetNamedPipeHandleStateW GetNamedPipeHandleState; + alias GetPrivateProfileIntW GetPrivateProfileInt; + alias GetPrivateProfileSectionW GetPrivateProfileSection; + alias GetPrivateProfileSectionNamesW GetPrivateProfileSectionNames; + alias GetPrivateProfileStringW GetPrivateProfileString; + alias GetPrivateProfileStructW GetPrivateProfileStruct; + alias GetProfileIntW GetProfileInt; + alias GetProfileSectionW GetProfileSection; + alias GetProfileStringW GetProfileString; + alias GetShortPathNameW GetShortPathName; + alias GetStartupInfoW GetStartupInfo; + alias GetSystemDirectoryW GetSystemDirectory; + alias GetTempFileNameW GetTempFileName; + alias GetTempPathW GetTempPath; + alias GetUserNameW GetUserName; + alias GetVersionExW GetVersionEx; + alias GetVolumeInformationW GetVolumeInformation; + alias GetWindowsDirectoryW GetWindowsDirectory; + alias GlobalAddAtomW GlobalAddAtom; + alias GlobalFindAtomW GlobalFindAtom; + alias GlobalGetAtomNameW GlobalGetAtomName; + alias IsBadStringPtrW IsBadStringPtr; + alias LoadLibraryW LoadLibrary; + alias LoadLibraryExW LoadLibraryEx; + alias lstrcatW lstrcat; + alias lstrcmpW lstrcmp; + alias lstrcmpiW lstrcmpi; + alias lstrcpyW lstrcpy; + alias lstrcpynW lstrcpyn; + alias lstrlenW lstrlen; + alias MoveFileW MoveFile; + alias OpenEventW OpenEvent; + alias OpenMutexW OpenMutex; + alias OpenSemaphoreW OpenSemaphore; + alias OutputDebugStringW OutputDebugString; + alias RemoveDirectoryW RemoveDirectory; + alias SearchPathW SearchPath; + alias SetComputerNameW SetComputerName; + alias SetCurrentDirectoryW SetCurrentDirectory; + alias SetDefaultCommConfigW SetDefaultCommConfig; + alias SetEnvironmentVariableW SetEnvironmentVariable; + alias SetFileAttributesW SetFileAttributes; + alias SetVolumeLabelW SetVolumeLabel; + alias WaitNamedPipeW WaitNamedPipe; + alias WritePrivateProfileSectionW WritePrivateProfileSection; + alias WritePrivateProfileStringW WritePrivateProfileString; + alias WritePrivateProfileStructW WritePrivateProfileStruct; + alias WriteProfileSectionW WriteProfileSection; + alias WriteProfileStringW WriteProfileString; + alias CreateWaitableTimerW CreateWaitableTimer; + alias GetFileAttributesExW GetFileAttributesEx; + alias GetLongPathNameW GetLongPathName; + alias QueryDosDeviceW QueryDosDevice; + + alias HW_PROFILE_INFOW HW_PROFILE_INFO; + alias AccessCheckAndAuditAlarmW AccessCheckAndAuditAlarm; + alias BackupEventLogW BackupEventLog; + alias ClearEventLogW ClearEventLog; + alias CreateNamedPipeW CreateNamedPipe; + alias CreateProcessAsUserW CreateProcessAsUser; + alias DefineDosDeviceW DefineDosDevice; + alias FindFirstFileExW FindFirstFileEx; + alias GetBinaryTypeW GetBinaryType; + alias GetCompressedFileSizeW GetCompressedFileSize; + alias GetFileSecurityW GetFileSecurity; + alias LogonUserW LogonUser; + alias LookupAccountNameW LookupAccountName; + alias LookupAccountSidW LookupAccountSid; + alias LookupPrivilegeDisplayNameW LookupPrivilegeDisplayName; + alias LookupPrivilegeNameW LookupPrivilegeName; + alias LookupPrivilegeValueW LookupPrivilegeValue; + alias MoveFileExW MoveFileEx; + alias ObjectCloseAuditAlarmW ObjectCloseAuditAlarm; + alias ObjectDeleteAuditAlarmW ObjectDeleteAuditAlarm; + alias ObjectOpenAuditAlarmW ObjectOpenAuditAlarm; + alias ObjectPrivilegeAuditAlarmW ObjectPrivilegeAuditAlarm; + alias OpenBackupEventLogW OpenBackupEventLog; + alias OpenEventLogW OpenEventLog; + alias PrivilegedServiceAuditAlarmW PrivilegedServiceAuditAlarm; + alias ReadEventLogW ReadEventLog; + alias RegisterEventSourceW RegisterEventSource; + alias ReportEventW ReportEvent; + alias SetFileSecurityW SetFileSecurity; + alias UpdateResourceW UpdateResource; + + static if (_WIN32_WINNT >= 0x500) { + alias CreateFileMappingW CreateFileMapping; + alias CreateHardLinkW CreateHardLink; + alias CreateJobObjectW CreateJobObject; + alias DeleteVolumeMountPointW DeleteVolumeMountPoint; + alias DnsHostnameToComputerNameW DnsHostnameToComputerName; + alias EncryptFileW EncryptFile; + alias FileEncryptionStatusW FileEncryptionStatus; + alias FindFirstVolumeW FindFirstVolume; + alias FindFirstVolumeMountPointW FindFirstVolumeMountPoint; + alias FindNextVolumeW FindNextVolume; + alias FindNextVolumeMountPointW FindNextVolumeMountPoint; + alias GetModuleHandleExW GetModuleHandleEx; + alias GetSystemWindowsDirectoryW GetSystemWindowsDirectory; + alias GetVolumeNameForVolumeMountPointW GetVolumeNameForVolumeMountPoint; + alias GetVolumePathNameW GetVolumePathName; + alias OpenFileMappingW OpenFileMapping; + alias ReplaceFileW ReplaceFile; + alias SetVolumeMountPointW SetVolumeMountPoint; + alias VerifyVersionInfoW VerifyVersionInfo; + } + + static if (_WIN32_WINNT >= 0x501) { + alias ACTCTXW ACTCTX; + alias CheckNameLegalDOS8Dot3W CheckNameLegalDOS8Dot3; + alias CreateActCtxW CreateActCtx; + alias FindActCtxSectionStringW FindActCtxSectionString; + alias GetSystemWow64DirectoryW GetSystemWow64Directory; + alias GetVolumePathNamesForVolumeNameW GetVolumePathNamesForVolumeName; + alias SetFileShortNameW SetFileShortName; + } + + static if (_WIN32_WINNT >= 0x502) { + alias SetFirmwareEnvironmentVariableW SetFirmwareEnvironmentVariable; + alias SetDllDirectoryW SetDllDirectory; + alias GetDllDirectoryW GetDllDirectory; + } + + static if (_WIN32_WINNT >= 0x600) { + alias CreateSymbolicLinkW CreateSymbolicLink; + } + +} else { + //alias STARTUPINFOA STARTUPINFO; + alias WIN32_FIND_DATAA WIN32_FIND_DATA; + alias ENUMRESLANGPROCW ENUMRESLANGPROC; + alias ENUMRESNAMEPROCW ENUMRESNAMEPROC; + alias ENUMRESTYPEPROCW ENUMRESTYPEPROC; + alias AddAtomA AddAtom; + alias BeginUpdateResourceA BeginUpdateResource; + alias BuildCommDCBA BuildCommDCB; + alias BuildCommDCBAndTimeoutsA BuildCommDCBAndTimeouts; + alias CallNamedPipeA CallNamedPipe; + alias CommConfigDialogA CommConfigDialog; + alias CopyFileA CopyFile; + alias CopyFileExA CopyFileEx; + alias CreateDirectoryA CreateDirectory; + alias CreateDirectoryExA CreateDirectoryEx; + alias CreateEventA CreateEvent; + alias CreateFileA CreateFile; + alias CreateMailslotA CreateMailslot; + alias CreateMutexA CreateMutex; + alias CreateProcessA CreateProcess; + alias CreateSemaphoreA CreateSemaphore; + alias DeleteFileA DeleteFile; + alias EndUpdateResourceA EndUpdateResource; + alias EnumResourceLanguagesA EnumResourceLanguages; + alias EnumResourceNamesA EnumResourceNames; + alias EnumResourceTypesA EnumResourceTypes; + alias ExpandEnvironmentStringsA ExpandEnvironmentStrings; + alias FatalAppExitA FatalAppExit; + alias FindAtomA FindAtom; + alias FindFirstChangeNotificationA FindFirstChangeNotification; + alias FindFirstFileA FindFirstFile; + alias FindNextFileA FindNextFile; + alias FindResourceA FindResource; + alias FindResourceExA FindResourceEx; +// alias FormatMessageA FormatMessage; + alias FreeEnvironmentStringsA FreeEnvironmentStrings; + alias GetAtomNameA GetAtomName; + alias GetCommandLineA GetCommandLine; + alias GetComputerNameA GetComputerName; + alias GetCurrentDirectoryA GetCurrentDirectory; + alias GetDefaultCommConfigA GetDefaultCommConfig; + alias GetDiskFreeSpaceA GetDiskFreeSpace; + alias GetDiskFreeSpaceExA GetDiskFreeSpaceEx; + alias GetDriveTypeA GetDriveType; + alias GetEnvironmentStringsA GetEnvironmentStrings; + alias GetEnvironmentVariableA GetEnvironmentVariable; + alias GetFileAttributesA GetFileAttributes; + alias GetFullPathNameA GetFullPathName; + alias GetLogicalDriveStringsA GetLogicalDriveStrings; + alias GetNamedPipeHandleStateA GetNamedPipeHandleState; + alias GetModuleHandleA GetModuleHandle; + alias GetModuleFileNameA GetModuleFileName; + alias GetPrivateProfileIntA GetPrivateProfileInt; + alias GetPrivateProfileSectionA GetPrivateProfileSection; + alias GetPrivateProfileSectionNamesA GetPrivateProfileSectionNames; + alias GetPrivateProfileStringA GetPrivateProfileString; + alias GetPrivateProfileStructA GetPrivateProfileStruct; + alias GetProfileIntA GetProfileInt; + alias GetProfileSectionA GetProfileSection; + alias GetProfileStringA GetProfileString; + alias GetShortPathNameA GetShortPathName; + alias GetStartupInfoA GetStartupInfo; + alias GetSystemDirectoryA GetSystemDirectory; + alias GetTempFileNameA GetTempFileName; + alias GetTempPathA GetTempPath; + alias GetUserNameA GetUserName; + alias GetVersionExA GetVersionEx; + alias GetVolumeInformationA GetVolumeInformation; + alias GetWindowsDirectoryA GetWindowsDirectory; + alias GlobalAddAtomA GlobalAddAtom; + alias GlobalFindAtomA GlobalFindAtom; + alias GlobalGetAtomNameA GlobalGetAtomName; + alias IsBadStringPtrA IsBadStringPtr; + alias LoadLibraryA LoadLibrary; + alias LoadLibraryExA LoadLibraryEx; + alias lstrcatA lstrcat; + alias lstrcmpA lstrcmp; + alias lstrcmpiA lstrcmpi; + alias lstrcpyA lstrcpy; + alias lstrcpynA lstrcpyn; + alias lstrlenA lstrlen; + alias MoveFileA MoveFile; + alias OpenEventA OpenEvent; + alias OpenMutexA OpenMutex; + alias OpenSemaphoreA OpenSemaphore; + alias OutputDebugStringA OutputDebugString; + alias RemoveDirectoryA RemoveDirectory; + alias SearchPathA SearchPath; + alias SetComputerNameA SetComputerName; + alias SetCurrentDirectoryA SetCurrentDirectory; + alias SetDefaultCommConfigA SetDefaultCommConfig; + alias SetEnvironmentVariableA SetEnvironmentVariable; + alias SetFileAttributesA SetFileAttributes; + alias SetVolumeLabelA SetVolumeLabel; + alias WaitNamedPipeA WaitNamedPipe; + alias WritePrivateProfileSectionA WritePrivateProfileSection; + alias WritePrivateProfileStringA WritePrivateProfileString; + alias WritePrivateProfileStructA WritePrivateProfileStruct; + alias WriteProfileSectionA WriteProfileSection; + alias WriteProfileStringA WriteProfileString; + alias CreateWaitableTimerA CreateWaitableTimer; + alias GetFileAttributesExA GetFileAttributesEx; + alias GetLongPathNameA GetLongPathName; + alias QueryDosDeviceA QueryDosDevice; + + alias HW_PROFILE_INFOA HW_PROFILE_INFO; + alias AccessCheckAndAuditAlarmA AccessCheckAndAuditAlarm; + alias BackupEventLogA BackupEventLog; + alias ClearEventLogA ClearEventLog; + alias CreateNamedPipeA CreateNamedPipe; + alias CreateProcessAsUserA CreateProcessAsUser; + alias DefineDosDeviceA DefineDosDevice; + alias FindFirstFileExA FindFirstFileEx; + alias GetBinaryTypeA GetBinaryType; + alias GetCompressedFileSizeA GetCompressedFileSize; + alias GetFileSecurityA GetFileSecurity; + alias LogonUserA LogonUser; + alias LookupAccountNameA LookupAccountName; + alias LookupAccountSidA LookupAccountSid; + alias LookupPrivilegeDisplayNameA LookupPrivilegeDisplayName; + alias LookupPrivilegeNameA LookupPrivilegeName; + alias LookupPrivilegeValueA LookupPrivilegeValue; + alias MoveFileExA MoveFileEx; + alias ObjectCloseAuditAlarmA ObjectCloseAuditAlarm; + alias ObjectDeleteAuditAlarmA ObjectDeleteAuditAlarm; + alias ObjectOpenAuditAlarmA ObjectOpenAuditAlarm; + alias ObjectPrivilegeAuditAlarmA ObjectPrivilegeAuditAlarm; + alias OpenBackupEventLogA OpenBackupEventLog; + alias OpenEventLogA OpenEventLog; + alias PrivilegedServiceAuditAlarmA PrivilegedServiceAuditAlarm; + alias ReadEventLogA ReadEventLog; + alias RegisterEventSourceA RegisterEventSource; + alias ReportEventA ReportEvent; + alias SetFileSecurityA SetFileSecurity; + alias UpdateResourceA UpdateResource; + + static if (_WIN32_WINNT >= 0x500) { + alias CreateFileMappingA CreateFileMapping; + alias CreateHardLinkA CreateHardLink; + alias CreateJobObjectA CreateJobObject; + alias DeleteVolumeMountPointA DeleteVolumeMountPoint; + alias DnsHostnameToComputerNameA DnsHostnameToComputerName; + alias EncryptFileA EncryptFile; + alias FileEncryptionStatusA FileEncryptionStatus; + alias FindFirstVolumeA FindFirstVolume; + alias FindFirstVolumeMountPointA FindFirstVolumeMountPoint; + alias FindNextVolumeA FindNextVolume; + alias FindNextVolumeMountPointA FindNextVolumeMountPoint; + alias GetModuleHandleExA GetModuleHandleEx; + alias GetSystemWindowsDirectoryA GetSystemWindowsDirectory; + alias GetVolumeNameForVolumeMountPointA GetVolumeNameForVolumeMountPoint; + alias GetVolumePathNameA GetVolumePathName; + alias OpenFileMappingA OpenFileMapping; + alias ReplaceFileA ReplaceFile; + alias SetVolumeMountPointA SetVolumeMountPoint; + alias VerifyVersionInfoA VerifyVersionInfo; + } + + static if (_WIN32_WINNT >= 0x501) { + alias ACTCTXA ACTCTX; + alias CheckNameLegalDOS8Dot3A CheckNameLegalDOS8Dot3; + alias CreateActCtxA CreateActCtx; + alias FindActCtxSectionStringA FindActCtxSectionString; + alias GetSystemWow64DirectoryA GetSystemWow64Directory; + alias GetVolumePathNamesForVolumeNameA GetVolumePathNamesForVolumeName; + alias SetFileShortNameA SetFileShortName; + } + + static if (_WIN32_WINNT >= 0x502) { + alias GetDllDirectoryA GetDllDirectory; + alias SetDllDirectoryA SetDllDirectory; + alias SetFirmwareEnvironmentVariableA SetFirmwareEnvironmentVariable; + } + + static if (_WIN32_WINNT >= 0x600) { + alias CreateSymbolicLinkA CreateSymbolicLink; + } +} + +alias STARTUPINFO* LPSTARTUPINFO; +alias WIN32_FIND_DATA* LPWIN32_FIND_DATA; + +alias HW_PROFILE_INFO* LPHW_PROFILE_INFO; + +static if (_WIN32_WINNT >= 0x501) { + alias ACTCTX* PACTCTX, PCACTCTX; +} diff --git a/src/urt/internal/sys/windows/wincon.d b/src/urt/internal/sys/windows/wincon.d new file mode 100644 index 0000000..d378237 --- /dev/null +++ b/src/urt/internal/sys/windows/wincon.d @@ -0,0 +1,316 @@ +/** + * Windows API header module + * + * Translated from MinGW Windows headers + * + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(DRUNTIMESRC core/sys/windows/_wincon.d) + */ +module urt.internal.sys.windows.wincon; +version (Windows): + +version (ANSI) {} else version = Unicode; +pragma(lib, "kernel32"); + +import urt.internal.sys.windows.w32api, urt.internal.sys.windows.windef; + +// FIXME: clean up Windows version support + +enum { + FOREGROUND_BLUE = 0x0001, + FOREGROUND_GREEN = 0x0002, + FOREGROUND_RED = 0x0004, + FOREGROUND_INTENSITY = 0x0008, + BACKGROUND_BLUE = 0x0010, + BACKGROUND_GREEN = 0x0020, + BACKGROUND_RED = 0x0040, + BACKGROUND_INTENSITY = 0x0080, + + COMMON_LVB_LEADING_BYTE = 0x0100, + COMMON_LVB_TRAILING_BYTE = 0x0200, + COMMON_LVB_GRID_HORIZONTAL = 0x0400, + COMMON_LVB_GRID_LVERTICAL = 0x0800, + COMMON_LVB_GRID_RVERTICAL = 0x1000, + COMMON_LVB_REVERSE_VIDEO = 0x4000, + COMMON_LVB_UNDERSCORE = 0x8000, + + COMMON_LVB_SBCSDBCS = 0x0300, +} + +static if (_WIN32_WINNT >= 0x501) { + enum { + CONSOLE_FULLSCREEN_MODE = 1, + CONSOLE_WINDOWED_MODE = 0 + } +} + +enum { + CTRL_C_EVENT = 0, + CTRL_BREAK_EVENT = 1, + CTRL_CLOSE_EVENT = 2, + CTRL_LOGOFF_EVENT = 5, + CTRL_SHUTDOWN_EVENT = 6 +} + +enum { + ENABLE_PROCESSED_INPUT = 1, + ENABLE_LINE_INPUT = 2, + ENABLE_ECHO_INPUT = 4, + ENABLE_WINDOW_INPUT = 8, + ENABLE_MOUSE_INPUT = 16, + ENABLE_INSERT_MODE = 32, + ENABLE_QUICK_EDIT_MODE = 64, + ENABLE_EXTENDED_FLAGS = 128, + ENABLE_AUTO_POSITION = 256, + ENABLE_VIRTUAL_TERMINAL_INPUT = 512 +} + +enum { + ENABLE_PROCESSED_OUTPUT = 1, + ENABLE_WRAP_AT_EOL_OUTPUT = 2, + ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4, + DISABLE_NEWLINE_AUTO_RETURN = 8, + ENABLE_LVB_GRID_WORLDWIDE = 16 +} + +enum { + KEY_EVENT = 1, + MOUSE_EVENT = 2, + WINDOW_BUFFER_SIZE_EVENT = 4, + MENU_EVENT = 8, + FOCUS_EVENT = 16 +} +enum { + RIGHT_ALT_PRESSED = 1, + LEFT_ALT_PRESSED = 2, + RIGHT_CTRL_PRESSED = 4, + LEFT_CTRL_PRESSED = 8, + SHIFT_PRESSED = 16, + NUMLOCK_ON = 32, + SCROLLLOCK_ON = 64, + CAPSLOCK_ON = 128, + ENHANCED_KEY = 256 +} +enum { + FROM_LEFT_1ST_BUTTON_PRESSED = 1, + RIGHTMOST_BUTTON_PRESSED = 2, + FROM_LEFT_2ND_BUTTON_PRESSED = 4, + FROM_LEFT_3RD_BUTTON_PRESSED = 8, + FROM_LEFT_4TH_BUTTON_PRESSED = 16 +} + +enum { + MOUSE_MOVED = 1, + DOUBLE_CLICK = 2, + MOUSE_WHEELED = 4 +} + +struct CHAR_INFO { + union _Char { + WCHAR UnicodeChar = 0; + CHAR AsciiChar; + } + union { + _Char Char; + WCHAR UnicodeChar; + CHAR AsciiChar; + } + WORD Attributes; +} +alias CHAR_INFO* PCHAR_INFO; + +struct SMALL_RECT { + SHORT Left; + SHORT Top; + SHORT Right; + SHORT Bottom; +} +alias SMALL_RECT* PSMALL_RECT; + +struct CONSOLE_CURSOR_INFO { + DWORD dwSize; + BOOL bVisible; +} +alias CONSOLE_CURSOR_INFO* PCONSOLE_CURSOR_INFO; + +struct COORD { + SHORT X; + SHORT Y; +} +alias COORD* PCOORD; + +struct CONSOLE_FONT_INFO { + DWORD nFont; + COORD dwFontSize; +} +alias CONSOLE_FONT_INFO* PCONSOLE_FONT_INFO; + +struct CONSOLE_SCREEN_BUFFER_INFO { + COORD dwSize; + COORD dwCursorPosition; + WORD wAttributes; + SMALL_RECT srWindow; + COORD dwMaximumWindowSize; +} +alias CONSOLE_SCREEN_BUFFER_INFO* PCONSOLE_SCREEN_BUFFER_INFO; + +alias extern(Windows) BOOL function(DWORD) nothrow PHANDLER_ROUTINE; + +struct KEY_EVENT_RECORD { + BOOL bKeyDown; + WORD wRepeatCount; + WORD wVirtualKeyCode; + WORD wVirtualScanCode; + union _uChar { + WCHAR UnicodeChar = 0; + CHAR AsciiChar; + } + union { + WCHAR UnicodeChar = 0; + CHAR AsciiChar; + _uChar uChar; + } + DWORD dwControlKeyState; +} +alias KEY_EVENT_RECORD* PKEY_EVENT_RECORD; + +struct MOUSE_EVENT_RECORD { + COORD dwMousePosition; + DWORD dwButtonState; + DWORD dwControlKeyState; + DWORD dwEventFlags; +} +alias MOUSE_EVENT_RECORD* PMOUSE_EVENT_RECORD; + +struct WINDOW_BUFFER_SIZE_RECORD { + COORD dwSize; +} +alias WINDOW_BUFFER_SIZE_RECORD* PWINDOW_BUFFER_SIZE_RECORD; + +struct MENU_EVENT_RECORD { + UINT dwCommandId; +} +alias MENU_EVENT_RECORD* PMENU_EVENT_RECORD; + +struct FOCUS_EVENT_RECORD { + BOOL bSetFocus; +} +alias FOCUS_EVENT_RECORD* PFOCUS_EVENT_RECORD; + +struct INPUT_RECORD { + WORD EventType; + union _Event { + KEY_EVENT_RECORD KeyEvent; + MOUSE_EVENT_RECORD MouseEvent; + WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent; + MENU_EVENT_RECORD MenuEvent; + FOCUS_EVENT_RECORD FocusEvent; + } + union { + KEY_EVENT_RECORD KeyEvent; + MOUSE_EVENT_RECORD MouseEvent; + WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent; + MENU_EVENT_RECORD MenuEvent; + FOCUS_EVENT_RECORD FocusEvent; + _Event Event; + } +} +alias INPUT_RECORD* PINPUT_RECORD; + +extern (Windows) nothrow @nogc: + +BOOL AllocConsole(); +HANDLE CreateConsoleScreenBuffer(DWORD, DWORD, const(SECURITY_ATTRIBUTES)*, DWORD, LPVOID); +BOOL FillConsoleOutputAttribute(HANDLE, WORD, DWORD, COORD, PDWORD); +BOOL FillConsoleOutputCharacterA(HANDLE, CHAR, DWORD, COORD, PDWORD); +BOOL FillConsoleOutputCharacterW(HANDLE, WCHAR, DWORD, COORD, PDWORD); +BOOL FlushConsoleInputBuffer(HANDLE); +BOOL FreeConsole(); +BOOL GenerateConsoleCtrlEvent(DWORD, DWORD); +UINT GetConsoleCP(); +BOOL GetConsoleCursorInfo(HANDLE, PCONSOLE_CURSOR_INFO); +BOOL GetConsoleMode(HANDLE,PDWORD); +UINT GetConsoleOutputCP(); +BOOL GetConsoleScreenBufferInfo(HANDLE, PCONSOLE_SCREEN_BUFFER_INFO); +DWORD GetConsoleTitleA(LPSTR, DWORD); +DWORD GetConsoleTitleW(LPWSTR, DWORD); +COORD GetLargestConsoleWindowSize(HANDLE); +BOOL GetNumberOfConsoleInputEvents(HANDLE, PDWORD); +BOOL GetNumberOfConsoleMouseButtons(PDWORD); +BOOL PeekConsoleInputA(HANDLE, PINPUT_RECORD, DWORD, PDWORD); +BOOL PeekConsoleInputW(HANDLE, PINPUT_RECORD, DWORD, PDWORD); +BOOL ReadConsoleA(HANDLE, PVOID, DWORD, PDWORD, PVOID); +BOOL ReadConsoleW(HANDLE, PVOID, DWORD, PDWORD, PVOID); +BOOL ReadConsoleInputA(HANDLE, PINPUT_RECORD, DWORD, PDWORD); +BOOL ReadConsoleInputW(HANDLE, PINPUT_RECORD, DWORD, PDWORD); +BOOL ReadConsoleOutputAttribute(HANDLE, LPWORD, DWORD, COORD, LPDWORD); +BOOL ReadConsoleOutputCharacterA(HANDLE, LPSTR, DWORD, COORD, PDWORD); +BOOL ReadConsoleOutputCharacterW(HANDLE, LPWSTR, DWORD, COORD, PDWORD); +BOOL ReadConsoleOutputA(HANDLE, PCHAR_INFO, COORD, COORD, PSMALL_RECT); +BOOL ReadConsoleOutputW(HANDLE, PCHAR_INFO, COORD, COORD, PSMALL_RECT); +BOOL ScrollConsoleScreenBufferA(HANDLE, const(SMALL_RECT)*, const(SMALL_RECT)*, COORD, const(CHAR_INFO)*); +BOOL ScrollConsoleScreenBufferW(HANDLE, const(SMALL_RECT)*, const(SMALL_RECT)*, COORD, const(CHAR_INFO)*); +BOOL SetConsoleActiveScreenBuffer(HANDLE); +BOOL SetConsoleCP(UINT); +BOOL SetConsoleCtrlHandler(PHANDLER_ROUTINE, BOOL); +BOOL SetConsoleCursorInfo(HANDLE, const(CONSOLE_CURSOR_INFO)*); +BOOL SetConsoleCursorPosition(HANDLE, COORD); + + +static if (_WIN32_WINNT >= 0x500) { +BOOL GetConsoleDisplayMode(LPDWORD); +HWND GetConsoleWindow(); +} + +static if (_WIN32_WINNT >= 0x501) { +BOOL AttachConsole(DWORD); +BOOL SetConsoleDisplayMode(HANDLE, DWORD, PCOORD); +enum DWORD ATTACH_PARENT_PROCESS = cast(DWORD)-1; +} + +BOOL SetConsoleMode(HANDLE, DWORD); +BOOL SetConsoleOutputCP(UINT); +BOOL SetConsoleScreenBufferSize(HANDLE, COORD); +BOOL SetConsoleTextAttribute(HANDLE, WORD); +BOOL SetConsoleTitleA(LPCSTR); +BOOL SetConsoleTitleW(LPCWSTR); +BOOL SetConsoleWindowInfo(HANDLE, BOOL, const(SMALL_RECT)*); +BOOL WriteConsoleA(HANDLE, PCVOID, DWORD, PDWORD, PVOID); +BOOL WriteConsoleW(HANDLE, PCVOID, DWORD, PDWORD, PVOID); +BOOL WriteConsoleInputA(HANDLE, const(INPUT_RECORD)*, DWORD, PDWORD); +BOOL WriteConsoleInputW(HANDLE, const(INPUT_RECORD)*, DWORD, PDWORD); +BOOL WriteConsoleOutputA(HANDLE, const(CHAR_INFO)*, COORD, COORD, PSMALL_RECT); +BOOL WriteConsoleOutputW(HANDLE, const(CHAR_INFO)*, COORD, COORD, PSMALL_RECT); +BOOL WriteConsoleOutputAttribute(HANDLE, const(WORD)*, DWORD, COORD, PDWORD); +BOOL WriteConsoleOutputCharacterA(HANDLE, LPCSTR, DWORD, COORD, PDWORD); +BOOL WriteConsoleOutputCharacterW(HANDLE, LPCWSTR, DWORD, COORD, PDWORD); + +version (Unicode) { + alias FillConsoleOutputCharacterW FillConsoleOutputCharacter; + alias GetConsoleTitleW GetConsoleTitle; + alias PeekConsoleInputW PeekConsoleInput; + alias ReadConsoleW ReadConsole; + alias ReadConsoleInputW ReadConsoleInput; + alias ReadConsoleOutputW ReadConsoleOutput; + alias ReadConsoleOutputCharacterW ReadConsoleOutputCharacter; + alias ScrollConsoleScreenBufferW ScrollConsoleScreenBuffer; + alias SetConsoleTitleW SetConsoleTitle; + alias WriteConsoleW WriteConsole; + alias WriteConsoleInputW WriteConsoleInput; + alias WriteConsoleOutputW WriteConsoleOutput; + alias WriteConsoleOutputCharacterW WriteConsoleOutputCharacter; +} else { + alias FillConsoleOutputCharacterA FillConsoleOutputCharacter; + alias GetConsoleTitleA GetConsoleTitle; + alias PeekConsoleInputA PeekConsoleInput; + alias ReadConsoleA ReadConsole; + alias ReadConsoleInputA ReadConsoleInput; + alias ReadConsoleOutputA ReadConsoleOutput; + alias ReadConsoleOutputCharacterA ReadConsoleOutputCharacter; + alias ScrollConsoleScreenBufferA ScrollConsoleScreenBuffer; + alias SetConsoleTitleA SetConsoleTitle; + alias WriteConsoleA WriteConsole; + alias WriteConsoleInputA WriteConsoleInput; + alias WriteConsoleOutputA WriteConsoleOutput; + alias WriteConsoleOutputCharacterA WriteConsoleOutputCharacter; +} diff --git a/src/urt/internal/sys/windows/wincrypt.d b/src/urt/internal/sys/windows/wincrypt.d new file mode 100644 index 0000000..38e00b5 --- /dev/null +++ b/src/urt/internal/sys/windows/wincrypt.d @@ -0,0 +1,902 @@ +/** + * Windows API header module + * + * Translated from MinGW Windows headers + * + * Authors: Stewart Gordon + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(DRUNTIMESRC core/sys/windows/_wincrypt.d) + */ +module urt.internal.sys.windows.wincrypt; +version (Windows): +pragma(lib, "advapi32"); + +version (ANSI) {} else version = Unicode; + +import urt.internal.sys.windows.w32api, urt.internal.sys.windows.winbase, urt.internal.sys.windows.windef; + +/* FIXME: + * Types of some constants + * Types of macros + * Inits of various "size" and "version" members + * Why are some #ifdefs commented out? + */ + +const TCHAR[] + MS_DEF_PROV = "Microsoft Base Cryptographic Provider v1.0", + MS_ENHANCED_PROV = "Microsoft Enhanced Cryptographic Provider v1.0", + MS_STRONG_PROV = "Microsoft Strong Cryptographic Provider", + MS_DEF_RSA_SIG_PROV = "Microsoft RSA Signature Cryptographic Provider", + MS_DEF_RSA_SCHANNEL_PROV = "Microsoft RSA SChannel Cryptographic Provider", + MS_DEF_DSS_PROV = "Microsoft Base DSS Cryptographic Provider", + MS_DEF_DSS_DH_PROV + = "Microsoft Base DSS and Diffie-Hellman Cryptographic Provider", + MS_ENH_DSS_DH_PROV + = "Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider", + MS_DEF_DH_SCHANNEL_PROV = "Microsoft DH SChannel Cryptographic Provider", + MS_SCARD_PROV = "Microsoft Base Smart Card Crypto Provider"; + +static if (_WIN32_WINNT > 0x501) { +const TCHAR[] MS_ENH_RSA_AES_PROV + = "Microsoft Enhanced RSA and AES Cryptographic Provider"; +} else static if (_WIN32_WINNT == 0x501) { +const TCHAR[] MS_ENH_RSA_AES_PROV + = "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)"; +} + +ALG_ID GET_ALG_CLASS()(ALG_ID x) { return x & 0xE000; } +ALG_ID GET_ALG_TYPE ()(ALG_ID x) { return x & 0x1E00; } +ALG_ID GET_ALG_SID ()(ALG_ID x) { return x & 0x01FF; } + +enum : ALG_ID { + ALG_CLASS_ANY = 0, + ALG_CLASS_SIGNATURE = 0x2000, + ALG_CLASS_MSG_ENCRYPT = 0x4000, + ALG_CLASS_DATA_ENCRYPT = 0x6000, + ALG_CLASS_HASH = 0x8000, + ALG_CLASS_KEY_EXCHANGE = 0xA000, + ALG_CLASS_ALL = 0xE000 +} + +enum : ALG_ID { + ALG_TYPE_ANY = 0, + ALG_TYPE_DSS = 0x0200, + ALG_TYPE_RSA = 0x0400, + ALG_TYPE_BLOCK = 0x0600, + ALG_TYPE_STREAM = 0x0800, + ALG_TYPE_DH = 0x0A00, + ALG_TYPE_SECURECHANNEL = 0x0C00 +} + +enum : ALG_ID { + ALG_SID_ANY = 0, + ALG_SID_RSA_ANY = 0, + ALG_SID_RSA_PKCS, + ALG_SID_RSA_MSATWORK, + ALG_SID_RSA_ENTRUST, + ALG_SID_RSA_PGP, // = 4 + ALG_SID_DSS_ANY = 0, + ALG_SID_DSS_PKCS, + ALG_SID_DSS_DMS, // = 2 + ALG_SID_DES = 1, + ALG_SID_3DES = 3, + ALG_SID_DESX, + ALG_SID_IDEA, + ALG_SID_CAST, + ALG_SID_SAFERSK64, + ALG_SID_SAFERSK128, + ALG_SID_3DES_112, + ALG_SID_SKIPJACK, + ALG_SID_TEK, + ALG_SID_CYLINK_MEK, + ALG_SID_RC5, // = 13 + ALG_SID_RC2 = 2, + ALG_SID_RC4 = 1, + ALG_SID_SEAL = 2, + ALG_SID_MD2 = 1, + ALG_SID_MD4, + ALG_SID_MD5, + ALG_SID_SHA, + ALG_SID_MAC, + ALG_SID_RIPEMD, + ALG_SID_RIPEMD160, + ALG_SID_SSL3SHAMD5, + ALG_SID_HMAC, + ALG_SID_TLS1PRF, // = 10 + ALG_SID_AES_128 = 14, + ALG_SID_AES_192, + ALG_SID_AES_256, + ALG_SID_AES, // = 17 + ALG_SID_EXAMPLE = 80 +} + +enum : ALG_ID { + CALG_MD2 = ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD2, + CALG_MD4 = ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD4, + CALG_MD5 = ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD5, + CALG_SHA = ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA, + CALG_SHA1 = CALG_SHA, + CALG_MAC = ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MAC, + CALG_3DES = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | 3, + CALG_CYLINK_MEK = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | 12, + CALG_SKIPJACK = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | 10, + CALG_KEA_KEYX = ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_STREAM | ALG_TYPE_DSS | 4, + CALG_RSA_SIGN = ALG_CLASS_SIGNATURE | ALG_TYPE_RSA | ALG_SID_RSA_ANY, + CALG_DSS_SIGN = ALG_CLASS_SIGNATURE | ALG_TYPE_DSS | ALG_SID_DSS_ANY, + CALG_RSA_KEYX = ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_RSA | ALG_SID_RSA_ANY, + CALG_DES = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_DES, + CALG_RC2 = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_RC2, + CALG_RC4 = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_STREAM | ALG_SID_RC4, + CALG_SEAL = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_STREAM | ALG_SID_SEAL, + CALG_DH_EPHEM = ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_STREAM | ALG_TYPE_DSS + | ALG_SID_DSS_DMS, + CALG_DESX = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_DESX, +// is undefined ALG_CLASS_DHASH in MinGW - presuming typo + CALG_TLS1PRF = ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_TLS1PRF, + CALG_AES_128 = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES_128, + CALG_AES_192 = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES_192, + CALG_AES_256 = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES_256, + CALG_AES = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES, +} + +enum { + CRYPT_VERIFYCONTEXT = 0xF0000000, +} + +enum { + CRYPT_NEWKEYSET = 8, + CRYPT_DELETEKEYSET = 16, + CRYPT_MACHINE_KEYSET = 32, + CRYPT_SILENT = 64, +} + +enum { + CRYPT_EXPORTABLE = 1, + CRYPT_USER_PROTECTED = 2, + CRYPT_CREATE_SALT = 4, + CRYPT_UPDATE_KEY = 8, +} + +enum { + SIMPLEBLOB = 1, + PUBLICKEYBLOB = 6, + PRIVATEKEYBLOB = 7, + PLAINTEXTKEYBLOB = 8, + OPAQUEKEYBLOB = 9, + PUBLICKEYBLOBEX = 10, + SYMMETRICWRAPKEYBLOB = 11, +} + +enum { + AT_KEYEXCHANGE = 1, + AT_SIGNATURE = 2, +} + +enum { + CRYPT_USERDATA = 1, +} + +enum { + PKCS5_PADDING = 1, +} + +enum { + CRYPT_MODE_CBC = 1, + CRYPT_MODE_ECB = 2, + CRYPT_MODE_OFB = 3, + CRYPT_MODE_CFB = 4, + CRYPT_MODE_CTS = 5, + CRYPT_MODE_CBCI = 6, + CRYPT_MODE_CFBP = 7, + CRYPT_MODE_OFBP = 8, + CRYPT_MODE_CBCOFM = 9, + CRYPT_MODE_CBCOFMI = 10, +} + +enum { + CRYPT_ENCRYPT = 1, + CRYPT_DECRYPT = 2, + CRYPT_EXPORT = 4, + CRYPT_READ = 8, + CRYPT_WRITE = 16, + CRYPT_MAC = 32, +} + +enum { + HP_ALGID = 1, + HP_HASHVAL = 2, + HP_HASHSIZE = 4, + HP_HMAC_INFO = 5, +} + +enum { + CRYPT_FAILED = FALSE, + CRYPT_SUCCEED = TRUE, +} + +bool RCRYPT_SUCCEEDED()(BOOL r) { return r==CRYPT_SUCCEED; } +bool RCRYPT_FAILED()(BOOL r) { return r==CRYPT_FAILED; } + +enum { + PP_ENUMALGS = 1, + PP_ENUMCONTAINERS = 2, + PP_IMPTYPE = 3, + PP_NAME = 4, + PP_VERSION = 5, + PP_CONTAINER = 6, + PP_CHANGE_PASSWORD = 7, + PP_KEYSET_SEC_DESCR = 8, + PP_CERTCHAIN = 9, + PP_KEY_TYPE_SUBTYPE = 10, + PP_PROVTYPE = 16, + PP_KEYSTORAGE = 17, + PP_APPLI_CERT = 18, + PP_SYM_KEYSIZE = 19, + PP_SESSION_KEYSIZE = 20, + PP_UI_PROMPT = 21, + PP_ENUMALGS_EX = 22, + PP_ENUMMANDROOTS = 25, + PP_ENUMELECTROOTS = 26, + PP_KEYSET_TYPE = 27, + PP_ADMIN_PIN = 31, + PP_KEYEXCHANGE_PIN = 32, + PP_SIGNATURE_PIN = 33, + PP_SIG_KEYSIZE_INC = 34, + PP_KEYX_KEYSIZE_INC = 35, + PP_UNIQUE_CONTAINER = 36, + PP_SGC_INFO = 37, + PP_USE_HARDWARE_RNG = 38, + PP_KEYSPEC = 39, + PP_ENUMEX_SIGNING_PROT = 40, +} + +enum { + CRYPT_FIRST = 1, + CRYPT_NEXT = 2, +} + +enum { + CRYPT_IMPL_HARDWARE = 1, + CRYPT_IMPL_SOFTWARE = 2, + CRYPT_IMPL_MIXED = 3, + CRYPT_IMPL_UNKNOWN = 4, +} + +enum { + PROV_RSA_FULL = 1, + PROV_RSA_SIG = 2, + PROV_DSS = 3, + PROV_FORTEZZA = 4, + PROV_MS_MAIL = 5, + PROV_SSL = 6, + PROV_STT_MER = 7, + PROV_STT_ACQ = 8, + PROV_STT_BRND = 9, + PROV_STT_ROOT = 10, + PROV_STT_ISS = 11, + PROV_RSA_SCHANNEL = 12, + PROV_DSS_DH = 13, + PROV_EC_ECDSA_SIG = 14, + PROV_EC_ECNRA_SIG = 15, + PROV_EC_ECDSA_FULL = 16, + PROV_EC_ECNRA_FULL = 17, + PROV_DH_SCHANNEL = 18, + PROV_SPYRUS_LYNKS = 20, + PROV_RNG = 21, + PROV_INTEL_SEC = 22, + PROV_RSA_AES = 24, + MAXUIDLEN = 64, +} + +enum { + CUR_BLOB_VERSION = 2, +} + +enum { + X509_ASN_ENCODING = 1, + PKCS_7_ASN_ENCODING = 65536, +} + +enum { + CERT_V1 = 0, + CERT_V2 = 1, + CERT_V3 = 2, +} + +enum { + CERT_E_CHAINING = (-2146762486), + CERT_E_CN_NO_MATCH = (-2146762481), + CERT_E_EXPIRED = (-2146762495), + CERT_E_PURPOSE = (-2146762490), + CERT_E_REVOCATION_FAILURE = (-2146762482), + CERT_E_REVOKED = (-2146762484), + CERT_E_ROLE = (-2146762493), + CERT_E_UNTRUSTEDROOT = (-2146762487), + CERT_E_UNTRUSTEDTESTROOT = (-2146762483), + CERT_E_VALIDITYPERIODNESTING = (-2146762494), + CERT_E_WRONG_USAGE = (-2146762480), + CERT_E_PATHLENCONST = (-2146762492), + CERT_E_CRITICAL = (-2146762491), + CERT_E_ISSUERCHAINING = (-2146762489), + CERT_E_MALFORMED = (-2146762488), + CRYPT_E_REVOCATION_OFFLINE = (-2146885613), + CRYPT_E_REVOKED = (-2146885616), + TRUST_E_BASIC_CONSTRAINTS = (-2146869223), + TRUST_E_CERT_SIGNATURE = (-2146869244), + TRUST_E_FAIL = (-2146762485), +} + +enum { + CERT_TRUST_NO_ERROR = 0, + CERT_TRUST_IS_NOT_TIME_VALID = 1, + CERT_TRUST_IS_NOT_TIME_NESTED = 2, + CERT_TRUST_IS_REVOKED = 4, + CERT_TRUST_IS_NOT_SIGNATURE_VALID = 8, + CERT_TRUST_IS_NOT_VALID_FOR_USAGE = 16, + CERT_TRUST_IS_UNTRUSTED_ROOT = 32, + CERT_TRUST_REVOCATION_STATUS_UNKNOWN = 64, + CERT_TRUST_IS_CYCLIC = 128, + CERT_TRUST_IS_PARTIAL_CHAIN = 65536, + CERT_TRUST_CTL_IS_NOT_TIME_VALID = 131072, + CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID = 262144, + CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE = 524288, +} + +enum { + CERT_TRUST_HAS_EXACT_MATCH_ISSUER = 1, + CERT_TRUST_HAS_KEY_MATCH_ISSUER = 2, + CERT_TRUST_HAS_NAME_MATCH_ISSUER = 4, + CERT_TRUST_IS_SELF_SIGNED = 8, + CERT_TRUST_IS_COMPLEX_CHAIN = 65536, +} + +enum { + CERT_CHAIN_POLICY_BASE = cast(LPCSTR) 1, + CERT_CHAIN_POLICY_AUTHENTICODE = cast(LPCSTR) 2, + CERT_CHAIN_POLICY_AUTHENTICODE_TS = cast(LPCSTR) 3, + CERT_CHAIN_POLICY_SSL = cast(LPCSTR) 4, + CERT_CHAIN_POLICY_BASIC_CONSTRAINTS = cast(LPCSTR) 5, + CERT_CHAIN_POLICY_NT_AUTH = cast(LPCSTR) 6, +} + +enum { + USAGE_MATCH_TYPE_AND = 0, + USAGE_MATCH_TYPE_OR = 1, +} + +enum { + CERT_SIMPLE_NAME_STR = 1, + CERT_OID_NAME_STR = 2, + CERT_X500_NAME_STR = 3, +} +enum { + CERT_NAME_STR_SEMICOLON_FLAG = 1073741824, + CERT_NAME_STR_CRLF_FLAG = 134217728, + CERT_NAME_STR_NO_PLUS_FLAG = 536870912, + CERT_NAME_STR_NO_QUOTING_FLAG = 268435456, + CERT_NAME_STR_REVERSE_FLAG = 33554432, + CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG = 131072, +} + +enum { + CERT_FIND_ANY = 0, + CERT_FIND_CERT_ID = 1048576, + CERT_FIND_CTL_USAGE = 655360, + CERT_FIND_ENHKEY_USAGE = 655360, + CERT_FIND_EXISTING = 851968, + CERT_FIND_HASH = 65536, + CERT_FIND_ISSUER_ATTR = 196612, + CERT_FIND_ISSUER_NAME = 131076, + CERT_FIND_ISSUER_OF = 786432, + CERT_FIND_KEY_IDENTIFIER = 983040, + CERT_FIND_KEY_SPEC = 589824, + CERT_FIND_MD5_HASH = 262144, + CERT_FIND_PROPERTY = 327680, + CERT_FIND_PUBLIC_KEY = 393216, + CERT_FIND_SHA1_HASH = 65536, + CERT_FIND_SIGNATURE_HASH = 917504, + CERT_FIND_SUBJECT_ATTR = 196615, + CERT_FIND_SUBJECT_CERT = 720896, + CERT_FIND_SUBJECT_NAME = 131079, + CERT_FIND_SUBJECT_STR_A = 458759, + CERT_FIND_SUBJECT_STR_W = 524295, + CERT_FIND_ISSUER_STR_A = 458756, + CERT_FIND_ISSUER_STR_W = 524292, +} + +enum { + CERT_FIND_OR_ENHKEY_USAGE_FLAG = 16, + CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG = 1, + CERT_FIND_NO_ENHKEY_USAGE_FLAG = 8, + CERT_FIND_VALID_ENHKEY_USAGE_FLAG = 32, + CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG = 2, +} + +enum { + CERT_CASE_INSENSITIVE_IS_RDN_ATTRS_FLAG = 2, + CERT_UNICODE_IS_RDN_ATTRS_FLAG = 1, + CERT_CHAIN_FIND_BY_ISSUER = 1, +} + +enum { + CERT_CHAIN_FIND_BY_ISSUER_COMPARE_KEY_FLAG = 1, + CERT_CHAIN_FIND_BY_ISSUER_COMPLEX_CHAIN_FLAG = 2, + CERT_CHAIN_FIND_BY_ISSUER_CACHE_ONLY_URL_FLAG = 4, + CERT_CHAIN_FIND_BY_ISSUER_LOCAL_MACHINE_FLAG = 8, + CERT_CHAIN_FIND_BY_ISSUER_NO_KEY_FLAG = 16384, + CERT_CHAIN_FIND_BY_ISSUER_CACHE_ONLY_FLAG = 32768, +} + +enum { + CERT_STORE_PROV_SYSTEM = 10, + CERT_SYSTEM_STORE_LOCAL_MACHINE = 131072, +} + +enum { + szOID_PKIX_KP_SERVER_AUTH = "4235600", + szOID_SERVER_GATED_CRYPTO = "4235658", + szOID_SGC_NETSCAPE = "2.16.840.1.113730.4.1", + szOID_PKIX_KP_CLIENT_AUTH = "1.3.6.1.5.5.7.3.2", +} + +enum { + CRYPT_NOHASHOID = 0x00000001, + CRYPT_NO_SALT = 0x10, + CRYPT_PREGEN = 0x40, +} + +enum { + CRYPT_RECIPIENT = 0x10, + CRYPT_INITIATOR = 0x40, + CRYPT_ONLINE = 0x80, + CRYPT_SF = 0x100, + CRYPT_CREATE_IV = 0x200, + CRYPT_KEK = 0x400, + CRYPT_DATA_KEY = 0x800, + CRYPT_VOLATILE = 0x1000, + CRYPT_SGCKEY = 0x2000, +} + +enum { + KP_IV = 0x00000001, + KP_SALT = 0x00000002, + KP_PADDING = 0x00000003, + KP_MODE = 0x00000004, + KP_MODE_BITS = 0x00000005, + KP_PERMISSIONS = 0x00000006, + KP_ALGID = 0x00000007, + KP_BLOCKLEN = 0x00000008, + KP_KEYLEN = 0x00000009, + KP_SALT_EX = 0x0000000a, + KP_P = 0x0000000b, + KP_G = 0x0000000c, + KP_Q = 0x0000000d, + KP_X = 0x0000000e, + KP_Y = 0x0000000f, + KP_RA = 0x00000010, + KP_RB = 0x00000011, + KP_INFO = 0x00000012, + KP_EFFECTIVE_KEYLEN = 0x00000013, + KP_SCHANNEL_ALG = 0x00000014, + KP_PUB_PARAMS = 0x00000027, +} + +enum { + CRYPT_FLAG_PCT1 = 0x0001, + CRYPT_FLAG_SSL2 = 0x0002, + CRYPT_FLAG_SSL3 = 0x0004, + CRYPT_FLAG_TLS1 = 0x0008, + CRYPT_FLAG_IPSEC = 0x0010, + CRYPT_FLAG_SIGNING = 0x0020, +} + +enum { + SCHANNEL_MAC_KEY = 0x00000000, + SCHANNEL_ENC_KEY = 0x00000001, +} + +enum { + INTERNATIONAL_USAGE = 0x00000001, +} + + +alias UINT ALG_ID; +alias ULONG_PTR HCRYPTPROV, HCRYPTKEY, HCRYPTHASH; +alias PVOID HCERTSTORE, HCRYPTMSG, HCERTCHAINENGINE; + +struct VTableProvStruc { + FARPROC FuncVerifyImage; +} +alias VTableProvStruc* PVTableProvStruc; + +struct _CRYPTOAPI_BLOB { + DWORD cbData; + BYTE* pbData; +} +alias _CRYPTOAPI_BLOB CRYPT_INTEGER_BLOB, CRYPT_UINT_BLOB, + CRYPT_OBJID_BLOB, CERT_NAME_BLOB, CERT_RDN_VALUE_BLOB, CERT_BLOB, + CRL_BLOB, DATA_BLOB, CRYPT_DATA_BLOB, CRYPT_HASH_BLOB, + CRYPT_DIGEST_BLOB, CRYPT_DER_BLOB, CRYPT_ATTR_BLOB; +alias _CRYPTOAPI_BLOB* PCRYPT_INTEGER_BLOB, PCRYPT_UINT_BLOB, + PCRYPT_OBJID_BLOB, PCERT_NAME_BLOB, PCERT_RDN_VALUE_BLOB, PCERT_BLOB, + PCRL_BLOB, PDATA_BLOB, PCRYPT_DATA_BLOB, PCRYPT_HASH_BLOB, + PCRYPT_DIGEST_BLOB, PCRYPT_DER_BLOB, PCRYPT_ATTR_BLOB; + +// not described in SDK; has the same layout as HTTPSPolicyCallbackData +struct SSL_EXTRA_CERT_CHAIN_POLICY_PARA { + DWORD cbStruct; + DWORD dwAuthType; + DWORD fdwChecks; + LPWSTR pwszServerName; +} +alias SSL_EXTRA_CERT_CHAIN_POLICY_PARA HTTPSPolicyCallbackData; +alias SSL_EXTRA_CERT_CHAIN_POLICY_PARA* PSSL_EXTRA_CERT_CHAIN_POLICY_PARA, + PHTTPSPolicyCallbackData; + +/* #if (_WIN32_WINNT>=0x500) */ +struct CERT_CHAIN_POLICY_PARA { + DWORD cbSize = CERT_CHAIN_POLICY_PARA.sizeof; + DWORD dwFlags; + void* pvExtraPolicyPara; +} +alias CERT_CHAIN_POLICY_PARA* PCERT_CHAIN_POLICY_PARA; + +struct CERT_CHAIN_POLICY_STATUS { + DWORD cbSize = CERT_CHAIN_POLICY_STATUS.sizeof; + DWORD dwError; + LONG lChainIndex; + LONG lElementIndex; + void* pvExtraPolicyStatus; +} +alias CERT_CHAIN_POLICY_STATUS* PCERT_CHAIN_POLICY_STATUS; +/* #endif */ + +struct CRYPT_ALGORITHM_IDENTIFIER { + LPSTR pszObjId; + CRYPT_OBJID_BLOB Parameters; +} +alias CRYPT_ALGORITHM_IDENTIFIER* PCRYPT_ALGORITHM_IDENTIFIER; + +struct CRYPT_BIT_BLOB { + DWORD cbData; + BYTE* pbData; + DWORD cUnusedBits; +} +alias CRYPT_BIT_BLOB* PCRYPT_BIT_BLOB; + +struct CERT_PUBLIC_KEY_INFO { + CRYPT_ALGORITHM_IDENTIFIER Algorithm; + CRYPT_BIT_BLOB PublicKey; +} +alias CERT_PUBLIC_KEY_INFO* PCERT_PUBLIC_KEY_INFO; + +struct CERT_EXTENSION { + LPSTR pszObjId; + BOOL fCritical; + CRYPT_OBJID_BLOB Value; +} +alias CERT_EXTENSION* PCERT_EXTENSION; + +struct CERT_INFO { + DWORD dwVersion; + CRYPT_INTEGER_BLOB SerialNumber; + CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm; + CERT_NAME_BLOB Issuer; + FILETIME NotBefore; + FILETIME NotAfter; + CERT_NAME_BLOB Subject; + CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo; + CRYPT_BIT_BLOB IssuerUniqueId; + CRYPT_BIT_BLOB SubjectUniqueId; + DWORD cExtension; + PCERT_EXTENSION rgExtension; +} +alias CERT_INFO* PCERT_INFO; + +struct CERT_CONTEXT { + DWORD dwCertEncodingType; + BYTE* pbCertEncoded; + DWORD cbCertEncoded; + PCERT_INFO pCertInfo; + HCERTSTORE hCertStore; +} +alias CERT_CONTEXT* PCERT_CONTEXT; +alias const(CERT_CONTEXT)* PCCERT_CONTEXT; + +struct CTL_USAGE { + DWORD cUsageIdentifier; + LPSTR* rgpszUsageIdentifier; +} +alias CTL_USAGE CERT_ENHKEY_USAGE; +alias CTL_USAGE* PCTRL_USAGE, PCERT_ENHKEY_USAGE; + +struct CERT_USAGE_MATCH { + DWORD dwType; + CERT_ENHKEY_USAGE Usage; +} +alias CERT_USAGE_MATCH* PCERT_USAGE_MATCH; +/* #if (_WIN32_WINNT>=0x500) */ + +struct CERT_CHAIN_PARA { + DWORD cbSize = CERT_CHAIN_PARA.sizeof; + CERT_USAGE_MATCH RequestedUsage; +//#if CERT_CHAIN_PARA_HAS_EXTRA_FIELDS + CERT_USAGE_MATCH RequestedIssuancePolicy; + DWORD dwUrlRetrievalTimeout; + BOOL fCheckRevocationFreshnessTime; + DWORD dwRevocationFreshnessTime; +//#endif +} +alias CERT_CHAIN_PARA* PCERT_CHAIN_PARA; + +extern (Windows) alias BOOL function(PCCERT_CONTEXT, void*) + PFN_CERT_CHAIN_FIND_BY_ISSUER_CALLBACK; + +struct CERT_CHAIN_FIND_BY_ISSUER_PARA { + DWORD cbSize = CERT_CHAIN_FIND_BY_ISSUER_PARA.sizeof; + LPCSTR pszUsageIdentifier; + DWORD dwKeySpec; + DWORD dwAcquirePrivateKeyFlags; + DWORD cIssuer; + CERT_NAME_BLOB* rgIssuer; + PFN_CERT_CHAIN_FIND_BY_ISSUER_CALLBACK pfnFIndCallback; + void* pvFindArg; + DWORD* pdwIssuerChainIndex; + DWORD* pdwIssuerElementIndex; +} +alias CERT_CHAIN_FIND_BY_ISSUER_PARA* PCERT_CHAIN_FIND_BY_ISSUER_PARA; +/* #endif */ + +struct CERT_TRUST_STATUS { + DWORD dwErrorStatus; + DWORD dwInfoStatus; +} +alias CERT_TRUST_STATUS* PCERT_TRUST_STATUS; + +struct CRL_ENTRY { + CRYPT_INTEGER_BLOB SerialNumber; + FILETIME RevocationDate; + DWORD cExtension; + PCERT_EXTENSION rgExtension; +} +alias CRL_ENTRY* PCRL_ENTRY; + +struct CRL_INFO { + DWORD dwVersion; + CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm; + CERT_NAME_BLOB Issuer; + FILETIME ThisUpdate; + FILETIME NextUpdate; + DWORD cCRLEntry; + PCRL_ENTRY rgCRLEntry; + DWORD cExtension; + PCERT_EXTENSION rgExtension; +} +alias CRL_INFO* PCRL_INFO; + +struct CRL_CONTEXT { + DWORD dwCertEncodingType; + BYTE* pbCrlEncoded; + DWORD cbCrlEncoded; + PCRL_INFO pCrlInfo; + HCERTSTORE hCertStore; +} +alias CRL_CONTEXT* PCRL_CONTEXT; +alias const(CRL_CONTEXT)* PCCRL_CONTEXT; + +struct CERT_REVOCATION_CRL_INFO { + DWORD cbSize = CERT_REVOCATION_CRL_INFO.sizeof; + PCCRL_CONTEXT pBaseCRLContext; + PCCRL_CONTEXT pDeltaCRLContext; + PCRL_ENTRY pCrlEntry; + BOOL fDeltaCrlEntry; +} +alias CERT_REVOCATION_CRL_INFO* PCERT_REVOCATION_CRL_INFO; + +struct CERT_REVOCATION_INFO { + DWORD cbSize = CERT_REVOCATION_INFO.sizeof; + DWORD dwRevocationResult; + LPCSTR pszRevocationOid; + LPVOID pvOidSpecificInfo; + BOOL fHasFreshnessTime; + DWORD dwFreshnessTime; + PCERT_REVOCATION_CRL_INFO pCrlInfo; +} +alias CERT_REVOCATION_INFO* PCERT_REVOCATION_INFO; + +/* #if (_WIN32_WINNT>=0x500) */ +struct CERT_CHAIN_ELEMENT { + DWORD cbSize = CERT_CHAIN_ELEMENT.sizeof; + PCCERT_CONTEXT pCertContext; + CERT_TRUST_STATUS TrustStatus; + PCERT_REVOCATION_INFO pRevocationInfo; + PCERT_ENHKEY_USAGE pIssuanceUsage; + PCERT_ENHKEY_USAGE pApplicationUsage; +} +alias CERT_CHAIN_ELEMENT* PCERT_CHAIN_ELEMENT; +/* #endif */ + +struct CRYPT_ATTRIBUTE { + LPSTR pszObjId; + DWORD cValue; + PCRYPT_ATTR_BLOB rgValue; +} +alias CRYPT_ATTRIBUTE* PCRYPT_ATTRIBUTE; + +struct CTL_ENTRY { + CRYPT_DATA_BLOB SubjectIdentifier; + DWORD cAttribute; + PCRYPT_ATTRIBUTE rgAttribute; +} +alias CTL_ENTRY* PCTL_ENTRY; + +struct CTL_INFO { + DWORD dwVersion; + CTL_USAGE SubjectUsage; + CRYPT_DATA_BLOB ListIdentifier; + CRYPT_INTEGER_BLOB SequenceNumber; + FILETIME ThisUpdate; + FILETIME NextUpdate; + CRYPT_ALGORITHM_IDENTIFIER SubjectAlgorithm; + DWORD cCTLEntry; + PCTL_ENTRY rgCTLEntry; + DWORD cExtension; + PCERT_EXTENSION rgExtension; +} +alias CTL_INFO* PCTL_INFO; + +struct CTL_CONTEXT { + DWORD dwMsgAndCertEncodingType; + BYTE* pbCtlEncoded; + DWORD cbCtlEncoded; + PCTL_INFO pCtlInfo; + HCERTSTORE hCertStore; + HCRYPTMSG hCryptMsg; + BYTE* pbCtlContent; + DWORD cbCtlContent; +} +alias CTL_CONTEXT* PCTL_CONTEXT; +alias const(CTL_CONTEXT)* PCCTL_CONTEXT; + +struct CERT_TRUST_LIST_INFO { + DWORD cbSize = CERT_TRUST_LIST_INFO.sizeof; + PCTL_ENTRY pCtlEntry; + PCCTL_CONTEXT pCtlContext; +} +alias CERT_TRUST_LIST_INFO* PCERT_TRUST_LIST_INFO; + +struct CERT_SIMPLE_CHAIN { + DWORD cbSize = CERT_SIMPLE_CHAIN.sizeof; + CERT_TRUST_STATUS TrustStatus; + DWORD cElement; + PCERT_CHAIN_ELEMENT* rgpElement; + PCERT_TRUST_LIST_INFO pTrustListInfo; + BOOL fHasRevocationFreshnessTime; + DWORD dwRevocationFreshnessTime; +} +alias CERT_SIMPLE_CHAIN* PCERT_SIMPLE_CHAIN; + +/* #if (_WIN32_WINNT>=0x500) */ +alias const(CERT_CHAIN_CONTEXT)* PCCERT_CHAIN_CONTEXT; +struct CERT_CHAIN_CONTEXT { + DWORD cbSize = CERT_CHAIN_CONTEXT.sizeof; + CERT_TRUST_STATUS TrustStatus; + DWORD cChain; + PCERT_SIMPLE_CHAIN* rgpChain; + DWORD cLowerQualityChainContext; + PCCERT_CHAIN_CONTEXT* rgpLowerQualityChainContext; + BOOL fHasRevocationFreshnessTime; + DWORD dwRevocationFreshnessTime; +} +alias CERT_CHAIN_CONTEXT* PCERT_CHAIN_CONTEXT; +/* #endif */ + +struct PROV_ENUMALGS { + ALG_ID aiAlgid; + DWORD dwBitLen; + DWORD dwNameLen; + CHAR[20] szName = 0; +} + +struct PUBLICKEYSTRUC { + BYTE bType; + BYTE bVersion; + WORD reserved; + ALG_ID aiKeyAlg; +} +alias PUBLICKEYSTRUC BLOBHEADER; + +struct RSAPUBKEY { + DWORD magic; + DWORD bitlen; + DWORD pubexp; +} + +struct HMAC_INFO { + ALG_ID HashAlgid; + BYTE* pbInnerString; + DWORD cbInnerString; + BYTE* pbOuterString; + DWORD cbOuterString; +} +alias HMAC_INFO* PHMAC_INFO; + +extern (Windows) nothrow @nogc { + BOOL CertCloseStore(HCERTSTORE, DWORD); + BOOL CertGetCertificateChain(HCERTCHAINENGINE, PCCERT_CONTEXT, LPFILETIME, + HCERTSTORE, PCERT_CHAIN_PARA, DWORD, LPVOID, PCCERT_CHAIN_CONTEXT*); + BOOL CertVerifyCertificateChainPolicy(LPCSTR, PCCERT_CHAIN_CONTEXT, + PCERT_CHAIN_POLICY_PARA, PCERT_CHAIN_POLICY_STATUS); + void CertFreeCertificateChain(PCCERT_CHAIN_CONTEXT); + DWORD CertNameToStrA(DWORD, PCERT_NAME_BLOB, DWORD, LPSTR, DWORD); + DWORD CertNameToStrW(DWORD, PCERT_NAME_BLOB, DWORD, LPWSTR, DWORD); + HCERTSTORE CertOpenSystemStoreA(HCRYPTPROV, LPCSTR); + HCERTSTORE CertOpenSystemStoreW(HCRYPTPROV, LPCWSTR); + HCERTSTORE CertOpenStore(LPCSTR, DWORD, HCRYPTPROV, DWORD, const(void)*); + PCCERT_CONTEXT CertFindCertificateInStore(HCERTSTORE, DWORD, DWORD, DWORD, +const(void)*, PCCERT_CONTEXT); + BOOL CertFreeCertificateContext(PCCERT_CONTEXT); + PCCERT_CONTEXT CertGetIssuerCertificateFromStore(HCERTSTORE, + PCCERT_CONTEXT, PCCERT_CONTEXT, DWORD*); + PCCERT_CHAIN_CONTEXT CertFindChainInStore(HCERTSTORE, DWORD, DWORD, DWORD, +const(void)*, PCCERT_CHAIN_CONTEXT); + + BOOL CryptAcquireContextA(HCRYPTPROV*, LPCSTR, LPCSTR, DWORD, DWORD); + BOOL CryptAcquireContextW(HCRYPTPROV*, LPCWSTR, LPCWSTR, DWORD, DWORD); + BOOL CryptContextAddRef(HCRYPTPROV, DWORD*, DWORD); + BOOL CryptReleaseContext(HCRYPTPROV, ULONG_PTR); + BOOL CryptGenKey(HCRYPTPROV, ALG_ID, DWORD, HCRYPTKEY*); + BOOL CryptDeriveKey(HCRYPTPROV, ALG_ID, HCRYPTHASH, DWORD, HCRYPTKEY*); + BOOL CryptDestroyKey(HCRYPTKEY); + static if (_WIN32_WINNT >= 0x500) { + BOOL CryptDuplicateHash(HCRYPTHASH, DWORD*, DWORD, HCRYPTHASH*); + BOOL CryptDuplicateKey(HCRYPTKEY, DWORD*, DWORD, HCRYPTKEY*); + } + BOOL CryptSetKeyParam(HCRYPTKEY, DWORD, PBYTE, DWORD); + BOOL CryptGetKeyParam(HCRYPTKEY, DWORD, PBYTE, PDWORD, DWORD); + BOOL CryptSetHashParam(HCRYPTHASH, DWORD, PBYTE, DWORD); + BOOL CryptGetHashParam(HCRYPTHASH, DWORD, PBYTE, PDWORD, DWORD); + BOOL CryptSetProvParam(HCRYPTPROV, DWORD, PBYTE, DWORD); + BOOL CryptGetProvParam(HCRYPTPROV, DWORD, PBYTE, PDWORD, DWORD); + BOOL CryptGenRandom(HCRYPTPROV, DWORD, PBYTE); + BOOL CryptGetUserKey(HCRYPTPROV, DWORD, HCRYPTKEY*); + BOOL CryptExportKey(HCRYPTKEY, HCRYPTKEY, DWORD, DWORD, PBYTE, PDWORD); + BOOL CryptImportKey(HCRYPTPROV, PBYTE, DWORD, HCRYPTKEY, DWORD, + HCRYPTKEY*); + BOOL CryptEncrypt(HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, PBYTE, PDWORD, + DWORD); + BOOL CryptDecrypt(HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, PBYTE, PDWORD); + BOOL CryptCreateHash(HCRYPTPROV, ALG_ID, HCRYPTKEY, DWORD, HCRYPTHASH*); + BOOL CryptHashData(HCRYPTHASH, PBYTE, DWORD, DWORD); + BOOL CryptHashSessionKey(HCRYPTHASH, HCRYPTKEY, DWORD); + BOOL CryptGetHashValue(HCRYPTHASH, DWORD, PBYTE, PDWORD); + BOOL CryptDestroyHash(HCRYPTHASH); + BOOL CryptSignHashA(HCRYPTHASH, DWORD, LPCSTR, DWORD, PBYTE, PDWORD); + BOOL CryptSignHashW(HCRYPTHASH, DWORD, LPCWSTR, DWORD, PBYTE, PDWORD); + BOOL CryptVerifySignatureA(HCRYPTHASH, PBYTE, DWORD, HCRYPTKEY, LPCSTR, + DWORD); + BOOL CryptVerifySignatureW(HCRYPTHASH, PBYTE, DWORD, HCRYPTKEY, LPCWSTR, + DWORD); + BOOL CryptSetProviderA(LPCSTR, DWORD); + BOOL CryptSetProviderW(LPCWSTR, DWORD); +} + +version (Unicode) { + alias CertNameToStrW CertNameToStr; + alias CryptAcquireContextW CryptAcquireContext; + alias CryptSignHashW CryptSignHash; + alias CryptVerifySignatureW CryptVerifySignature; + alias CryptSetProviderW CryptSetProvider; + alias CertOpenSystemStoreW CertOpenSystemStore; + /+alias CERT_FIND_SUBJECT_STR_W CERT_FIND_SUBJECT_STR; + alias CERT_FIND_ISSUER_STR_W CERT_FIND_ISSUER_STR;+/ +} else { + alias CertNameToStrA CertNameToStr; + alias CryptAcquireContextA CryptAcquireContext; + alias CryptSignHashA CryptSignHash; + alias CryptVerifySignatureA CryptVerifySignature; + alias CryptSetProviderA CryptSetProvider; + alias CertOpenSystemStoreA CertOpenSystemStore; + /+alias CERT_FIND_SUBJECT_STR_A CERT_FIND_SUBJECT_STR; + alias CERT_FIND_ISSUER_STR_A CERT_FIND_ISSUER_STR;+/ +} diff --git a/src/urt/internal/sys/windows/windef.d b/src/urt/internal/sys/windows/windef.d new file mode 100644 index 0000000..20767e1 --- /dev/null +++ b/src/urt/internal/sys/windows/windef.d @@ -0,0 +1,151 @@ +/** + * Windows API header module + * + * Translated from MinGW Windows headers + * + * Authors: Stewart Gordon + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(DRUNTIMESRC core/sys/windows/_windef.d) + */ +module urt.internal.sys.windows.windef; +version (Windows): + +public import urt.internal.sys.windows.winnt; +import urt.internal.sys.windows.w32api; + +enum size_t MAX_PATH = 260; + +pure nothrow @nogc { + ushort MAKEWORD(ubyte a, ubyte b) { + return cast(ushort) ((b << 8) | a); + } + + ushort MAKEWORD(ushort a, ushort b) { + assert((a & 0xFF00) == 0); + assert((b & 0xFF00) == 0); + return MAKEWORD(cast(ubyte)a, cast(ubyte)b); + } + + uint MAKELONG(ushort a, ushort b) { + return cast(uint) ((b << 16) | a); + } + + uint MAKELONG(uint a, uint b) { + assert((a & 0xFFFF0000) == 0); + assert((b & 0xFFFF0000) == 0); + return MAKELONG(cast(ushort)a, cast(ushort)b); + } + + ushort LOWORD(ulong l) { + return cast(ushort) l; + } + + ushort HIWORD(ulong l) { + return cast(ushort) (l >>> 16); + } + + ubyte LOBYTE(ushort w) { + return cast(ubyte) w; + } + + ubyte HIBYTE(ushort w) { + return cast(ubyte) (w >>> 8); + } +} + +enum NULL = null; +static assert (is(typeof({ + void test(int* p) {} + test(NULL); +}))); + +alias ubyte BYTE; +alias ubyte* PBYTE, LPBYTE; +alias ushort USHORT, WORD, ATOM; +alias ushort* PUSHORT, PWORD, LPWORD; +alias uint ULONG, DWORD, UINT, COLORREF; +alias uint* PULONG, PDWORD, LPDWORD, PUINT, LPUINT, LPCOLORREF; +alias int WINBOOL, BOOL, INT, LONG, HFILE, HRESULT; +alias int* PWINBOOL, LPWINBOOL, PBOOL, LPBOOL, PINT, LPINT, LPLONG; +alias float FLOAT; +alias float* PFLOAT; +alias const(void)* PCVOID, LPCVOID; + +alias UINT_PTR WPARAM; +alias LONG_PTR LPARAM, LRESULT; + +alias HHOOK = HANDLE; +alias HGLOBAL = HANDLE; +alias HLOCAL = HANDLE; +alias GLOBALHANDLE = HANDLE; +alias LOCALHANDLE = HANDLE; +alias HGDIOBJ = HANDLE; +alias HACCEL = HANDLE; +alias HBITMAP = HGDIOBJ; +alias HBRUSH = HGDIOBJ; +alias HCOLORSPACE = HANDLE; +alias HDC = HANDLE; +alias HGLRC = HANDLE; +alias HDESK = HANDLE; +alias HENHMETAFILE = HANDLE; +alias HFONT = HGDIOBJ; +alias HICON = HANDLE; +alias HINSTANCE = HANDLE; +alias HKEY = HANDLE; +alias HMENU = HANDLE; +alias HMETAFILE = HANDLE; +alias HMODULE = HANDLE; +alias HMONITOR = HANDLE; +alias HPALETTE = HANDLE; +alias HPEN = HGDIOBJ; +alias HRGN = HGDIOBJ; +alias HRSRC = HANDLE; +alias HSTR = HANDLE; +alias HTASK = HANDLE; +alias HWND = HANDLE; +alias HWINSTA = HANDLE; +alias HKL = HANDLE; +alias HCURSOR = HANDLE; +alias HKEY* PHKEY; + +static if (_WIN32_WINNT >= 0x500) { + alias HTERMINAL = HANDLE; + alias HWINEVENTHOOK = HANDLE; +} + +alias extern (Windows) INT_PTR function() nothrow FARPROC, NEARPROC, PROC; + +struct RECT { + LONG left; + LONG top; + LONG right; + LONG bottom; +} +alias RECT RECTL; +alias RECT* PRECT, NPRECT, LPRECT, PRECTL, LPRECTL; +alias const(RECT)* LPCRECT, LPCRECTL; + +struct POINT { + LONG x; + LONG y; +} +alias POINT POINTL; +alias POINT* PPOINT, NPPOINT, LPPOINT, PPOINTL, LPPOINTL; + +struct SIZE { + LONG cx; + LONG cy; +} +alias SIZE SIZEL; +alias SIZE* PSIZE, LPSIZE, PSIZEL, LPSIZEL; + +struct POINTS { + SHORT x; + SHORT y; +} +alias POINTS* PPOINTS, LPPOINTS; + +enum : BOOL { + FALSE = 0, + TRUE = 1 +} diff --git a/src/urt/internal/sys/windows/winerror.d b/src/urt/internal/sys/windows/winerror.d new file mode 100644 index 0000000..6178028 --- /dev/null +++ b/src/urt/internal/sys/windows/winerror.d @@ -0,0 +1,2312 @@ +/** + * Windows API header module + * + * Translated from MinGW Windows headers + * + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(DRUNTIMESRC core/sys/windows/_winerror.d) + */ +module urt.internal.sys.windows.winerror; +version (Windows): + +/* Comments from the Mingw header: + * WAIT_TIMEOUT is also defined in winbase.h + */ + +import urt.internal.sys.windows.windef; + +alias int SCODE; // was in urt.internal.sys.windows.wtypes. + +enum : uint { + ERROR_SUCCESS = 0, + NO_ERROR = 0, + ERROR_INVALID_FUNCTION, + ERROR_FILE_NOT_FOUND, + ERROR_PATH_NOT_FOUND, + ERROR_TOO_MANY_OPEN_FILES, + ERROR_ACCESS_DENIED, + ERROR_INVALID_HANDLE, + ERROR_ARENA_TRASHED, + ERROR_NOT_ENOUGH_MEMORY, + ERROR_INVALID_BLOCK, + ERROR_BAD_ENVIRONMENT, + ERROR_BAD_FORMAT, + ERROR_INVALID_ACCESS, + ERROR_INVALID_DATA, + ERROR_OUTOFMEMORY, + ERROR_INVALID_DRIVE, + ERROR_CURRENT_DIRECTORY, + ERROR_NOT_SAME_DEVICE, + ERROR_NO_MORE_FILES, + ERROR_WRITE_PROTECT, + ERROR_BAD_UNIT, + ERROR_NOT_READY, + ERROR_BAD_COMMAND, + ERROR_CRC, + ERROR_BAD_LENGTH, + ERROR_SEEK, + ERROR_NOT_DOS_DISK, + ERROR_SECTOR_NOT_FOUND, + ERROR_OUT_OF_PAPER, + ERROR_WRITE_FAULT, + ERROR_READ_FAULT, + ERROR_GEN_FAILURE, + ERROR_SHARING_VIOLATION, + ERROR_LOCK_VIOLATION, + ERROR_WRONG_DISK, // = 34 + ERROR_SHARING_BUFFER_EXCEEDED = 36, + ERROR_HANDLE_EOF = 38, + ERROR_HANDLE_DISK_FULL, // = 39 + ERROR_NOT_SUPPORTED = 50, + ERROR_REM_NOT_LIST, + ERROR_DUP_NAME, + ERROR_BAD_NETPATH, + ERROR_NETWORK_BUSY, + ERROR_DEV_NOT_EXIST, + ERROR_TOO_MANY_CMDS, + ERROR_ADAP_HDW_ERR, + ERROR_BAD_NET_RESP, + ERROR_UNEXP_NET_ERR, + ERROR_BAD_REM_ADAP, + ERROR_PRINTQ_FULL, + ERROR_NO_SPOOL_SPACE, + ERROR_PRINT_CANCELLED, + ERROR_NETNAME_DELETED, + ERROR_NETWORK_ACCESS_DENIED, + ERROR_BAD_DEV_TYPE, + ERROR_BAD_NET_NAME, + ERROR_TOO_MANY_NAMES, + ERROR_TOO_MANY_SESS, + ERROR_SHARING_PAUSED, + ERROR_REQ_NOT_ACCEP, + ERROR_REDIR_PAUSED, // = 72 + ERROR_FILE_EXISTS = 80, + ERROR_CANNOT_MAKE = 82, + ERROR_FAIL_I24, + ERROR_OUT_OF_STRUCTURES, + ERROR_ALREADY_ASSIGNED, + ERROR_INVALID_PASSWORD, + ERROR_INVALID_PARAMETER, + ERROR_NET_WRITE_FAULT, + ERROR_NO_PROC_SLOTS, // = 89 + ERROR_TOO_MANY_SEMAPHORES = 100, + ERROR_EXCL_SEM_ALREADY_OWNED, + ERROR_SEM_IS_SET, + ERROR_TOO_MANY_SEM_REQUESTS, + ERROR_INVALID_AT_INTERRUPT_TIME, + ERROR_SEM_OWNER_DIED, + ERROR_SEM_USER_LIMIT, + ERROR_DISK_CHANGE, + ERROR_DRIVE_LOCKED, + ERROR_BROKEN_PIPE, + ERROR_OPEN_FAILED, + ERROR_BUFFER_OVERFLOW, + ERROR_DISK_FULL, + ERROR_NO_MORE_SEARCH_HANDLES, + ERROR_INVALID_TARGET_HANDLE, // = 114 + ERROR_INVALID_CATEGORY = 117, + ERROR_INVALID_VERIFY_SWITCH, + ERROR_BAD_DRIVER_LEVEL, + ERROR_CALL_NOT_IMPLEMENTED, + ERROR_SEM_TIMEOUT, + ERROR_INSUFFICIENT_BUFFER, + ERROR_INVALID_NAME, + ERROR_INVALID_LEVEL, + ERROR_NO_VOLUME_LABEL, + ERROR_MOD_NOT_FOUND, + ERROR_PROC_NOT_FOUND, + ERROR_WAIT_NO_CHILDREN, + ERROR_CHILD_NOT_COMPLETE, + ERROR_DIRECT_ACCESS_HANDLE, + ERROR_NEGATIVE_SEEK, + ERROR_SEEK_ON_DEVICE, + ERROR_IS_JOIN_TARGET, + ERROR_IS_JOINED, + ERROR_IS_SUBSTED, + ERROR_NOT_JOINED, + ERROR_NOT_SUBSTED, + ERROR_JOIN_TO_JOIN, + ERROR_SUBST_TO_SUBST, + ERROR_JOIN_TO_SUBST, + ERROR_SUBST_TO_JOIN, + ERROR_BUSY_DRIVE, + ERROR_SAME_DRIVE, + ERROR_DIR_NOT_ROOT, + ERROR_DIR_NOT_EMPTY, + ERROR_IS_SUBST_PATH, + ERROR_IS_JOIN_PATH, + ERROR_PATH_BUSY, + ERROR_IS_SUBST_TARGET, + ERROR_SYSTEM_TRACE, + ERROR_INVALID_EVENT_COUNT, + ERROR_TOO_MANY_MUXWAITERS, + ERROR_INVALID_LIST_FORMAT, + ERROR_LABEL_TOO_LONG, + ERROR_TOO_MANY_TCBS, + ERROR_SIGNAL_REFUSED, + ERROR_DISCARDED, + ERROR_NOT_LOCKED, + ERROR_BAD_THREADID_ADDR, + ERROR_BAD_ARGUMENTS, + ERROR_BAD_PATHNAME, + ERROR_SIGNAL_PENDING, // = 162 + ERROR_MAX_THRDS_REACHED = 164, + ERROR_LOCK_FAILED = 167, + ERROR_BUSY = 170, + ERROR_CANCEL_VIOLATION = 173, + ERROR_ATOMIC_LOCKS_NOT_SUPPORTED, // = 174 + ERROR_INVALID_SEGMENT_NUMBER = 180, + ERROR_INVALID_ORDINAL = 182, + ERROR_ALREADY_EXISTS, // = 183 + ERROR_INVALID_FLAG_NUMBER = 186, + ERROR_SEM_NOT_FOUND, + ERROR_INVALID_STARTING_CODESEG, + ERROR_INVALID_STACKSEG, + ERROR_INVALID_MODULETYPE, + ERROR_INVALID_EXE_SIGNATURE, + ERROR_EXE_MARKED_INVALID, + ERROR_BAD_EXE_FORMAT, + ERROR_ITERATED_DATA_EXCEEDS_64k, + ERROR_INVALID_MINALLOCSIZE, + ERROR_DYNLINK_FROM_INVALID_RING, + ERROR_IOPL_NOT_ENABLED, + ERROR_INVALID_SEGDPL, + ERROR_AUTODATASEG_EXCEEDS_64k, + ERROR_RING2SEG_MUST_BE_MOVABLE, + ERROR_RELOC_CHAIN_XEEDS_SEGLIM, + ERROR_INFLOOP_IN_RELOC_CHAIN, + ERROR_ENVVAR_NOT_FOUND, // = 203 + ERROR_NO_SIGNAL_SENT = 205, + ERROR_FILENAME_EXCED_RANGE, + ERROR_RING2_STACK_IN_USE, + ERROR_META_EXPANSION_TOO_LONG, + ERROR_INVALID_SIGNAL_NUMBER, + ERROR_THREAD_1_INACTIVE, // = 210 + ERROR_LOCKED = 212, + ERROR_TOO_MANY_MODULES = 214, + ERROR_NESTING_NOT_ALLOWED, + ERROR_EXE_MACHINE_TYPE_MISMATCH, + ERROR_EXE_CANNOT_MODIFY_SIGNED_BINARY, + ERROR_EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY, // = 218 + ERROR_BAD_PIPE = 230, + ERROR_PIPE_BUSY, + ERROR_NO_DATA, + ERROR_PIPE_NOT_CONNECTED, + ERROR_MORE_DATA, // = 234 + ERROR_VC_DISCONNECTED = 240, + ERROR_INVALID_EA_NAME = 254, + ERROR_EA_LIST_INCONSISTENT, // = 255 + WAIT_TIMEOUT = 258, + ERROR_NO_MORE_ITEMS, // = 259 + ERROR_CANNOT_COPY = 266, + ERROR_DIRECTORY, // = 267 + ERROR_EAS_DIDNT_FIT = 275, + ERROR_EA_FILE_CORRUPT, + ERROR_EA_TABLE_FULL, + ERROR_INVALID_EA_HANDLE, // = 278 + ERROR_EAS_NOT_SUPPORTED = 282, + ERROR_NOT_OWNER = 288, + ERROR_TOO_MANY_POSTS = 298, + ERROR_PARTIAL_COPY, + ERROR_OPLOCK_NOT_GRANTED, + ERROR_INVALID_OPLOCK_PROTOCOL, + ERROR_DISK_TOO_FRAGMENTED, + ERROR_DELETE_PENDING, // = 303 + ERROR_MR_MID_NOT_FOUND = 317, + ERROR_SCOPE_NOT_FOUND, // = 318 + ERROR_INVALID_ADDRESS = 487, + ERROR_ARITHMETIC_OVERFLOW = 534, + ERROR_PIPE_CONNECTED, + ERROR_PIPE_LISTENING, // = 536 + ERROR_EA_ACCESS_DENIED = 994, + ERROR_OPERATION_ABORTED, + ERROR_IO_INCOMPLETE, + ERROR_IO_PENDING, + ERROR_NOACCESS, + ERROR_SWAPERROR, // = 999 + ERROR_STACK_OVERFLOW = 1001, + ERROR_INVALID_MESSAGE, + ERROR_CAN_NOT_COMPLETE, + ERROR_INVALID_FLAGS, + ERROR_UNRECOGNIZED_VOLUME, + ERROR_FILE_INVALID, + ERROR_FULLSCREEN_MODE, + ERROR_NO_TOKEN, + ERROR_BADDB, + ERROR_BADKEY, + ERROR_CANTOPEN, + ERROR_CANTREAD, + ERROR_CANTWRITE, + ERROR_REGISTRY_RECOVERED, + ERROR_REGISTRY_CORRUPT, + ERROR_REGISTRY_IO_FAILED, + ERROR_NOT_REGISTRY_FILE, + ERROR_KEY_DELETED, + ERROR_NO_LOG_SPACE, + ERROR_KEY_HAS_CHILDREN, + ERROR_CHILD_MUST_BE_VOLATILE, + ERROR_NOTIFY_ENUM_DIR, // = 1022 + ERROR_DEPENDENT_SERVICES_RUNNING = 1051, + ERROR_INVALID_SERVICE_CONTROL, + ERROR_SERVICE_REQUEST_TIMEOUT, + ERROR_SERVICE_NO_THREAD, + ERROR_SERVICE_DATABASE_LOCKED, + ERROR_SERVICE_ALREADY_RUNNING, + ERROR_INVALID_SERVICE_ACCOUNT, + ERROR_SERVICE_DISABLED, + ERROR_CIRCULAR_DEPENDENCY, + ERROR_SERVICE_DOES_NOT_EXIST, + ERROR_SERVICE_CANNOT_ACCEPT_CTRL, + ERROR_SERVICE_NOT_ACTIVE, + ERROR_FAILED_SERVICE_CONTROLLER_CONNECT, + ERROR_EXCEPTION_IN_SERVICE, + ERROR_DATABASE_DOES_NOT_EXIST, + ERROR_SERVICE_SPECIFIC_ERROR, + ERROR_PROCESS_ABORTED, + ERROR_SERVICE_DEPENDENCY_FAIL, + ERROR_SERVICE_LOGON_FAILED, + ERROR_SERVICE_START_HANG, + ERROR_INVALID_SERVICE_LOCK, + ERROR_SERVICE_MARKED_FOR_DELETE, + ERROR_SERVICE_EXISTS, + ERROR_ALREADY_RUNNING_LKG, + ERROR_SERVICE_DEPENDENCY_DELETED, + ERROR_BOOT_ALREADY_ACCEPTED, + ERROR_SERVICE_NEVER_STARTED, + ERROR_DUPLICATE_SERVICE_NAME, + ERROR_DIFFERENT_SERVICE_ACCOUNT, + ERROR_CANNOT_DETECT_DRIVER_FAILURE, + ERROR_CANNOT_DETECT_PROCESS_ABORT, + ERROR_NO_RECOVERY_PROGRAM, + ERROR_SERVICE_NOT_IN_EXE, + ERROR_NOT_SAFEBOOT_SERVICE, // = 1084 + ERROR_END_OF_MEDIA = 1100, + ERROR_FILEMARK_DETECTED, + ERROR_BEGINNING_OF_MEDIA, + ERROR_SETMARK_DETECTED, + ERROR_NO_DATA_DETECTED, + ERROR_PARTITION_FAILURE, + ERROR_INVALID_BLOCK_LENGTH, + ERROR_DEVICE_NOT_PARTITIONED, + ERROR_UNABLE_TO_LOCK_MEDIA, + ERROR_UNABLE_TO_UNLOAD_MEDIA, + ERROR_MEDIA_CHANGED, + ERROR_BUS_RESET, + ERROR_NO_MEDIA_IN_DRIVE, + ERROR_NO_UNICODE_TRANSLATION, + ERROR_DLL_INIT_FAILED, + ERROR_SHUTDOWN_IN_PROGRESS, + ERROR_NO_SHUTDOWN_IN_PROGRESS, + ERROR_IO_DEVICE, + ERROR_SERIAL_NO_DEVICE, + ERROR_IRQ_BUSY, + ERROR_MORE_WRITES, + ERROR_COUNTER_TIMEOUT, + ERROR_FLOPPY_ID_MARK_NOT_FOUND, + ERROR_FLOPPY_WRONG_CYLINDER, + ERROR_FLOPPY_UNKNOWN_ERROR, + ERROR_FLOPPY_BAD_REGISTERS, + ERROR_DISK_RECALIBRATE_FAILED, + ERROR_DISK_OPERATION_FAILED, + ERROR_DISK_RESET_FAILED, + ERROR_EOM_OVERFLOW, + ERROR_NOT_ENOUGH_SERVER_MEMORY, + ERROR_POSSIBLE_DEADLOCK, + ERROR_MAPPED_ALIGNMENT, // = 1132 + ERROR_SET_POWER_STATE_VETOED = 1140, + ERROR_SET_POWER_STATE_FAILED, + ERROR_TOO_MANY_LINKS, // = 1142 + ERROR_OLD_WIN_VERSION = 1150, + ERROR_APP_WRONG_OS, + ERROR_SINGLE_INSTANCE_APP, + ERROR_RMODE_APP, + ERROR_INVALID_DLL, + ERROR_NO_ASSOCIATION, + ERROR_DDE_FAIL, + ERROR_DLL_NOT_FOUND, + ERROR_NO_MORE_USER_HANDLES, + ERROR_MESSAGE_SYNC_ONLY, + ERROR_SOURCE_ELEMENT_EMPTY, + ERROR_DESTINATION_ELEMENT_FULL, + ERROR_ILLEGAL_ELEMENT_ADDRESS, + ERROR_MAGAZINE_NOT_PRESENT, + ERROR_DEVICE_REINITIALIZATION_NEEDED, + ERROR_DEVICE_REQUIRES_CLEANING, + ERROR_DEVICE_DOOR_OPEN, + ERROR_DEVICE_NOT_CONNECTED, + ERROR_NOT_FOUND, + ERROR_NO_MATCH, + ERROR_SET_NOT_FOUND, + ERROR_POINT_NOT_FOUND, + ERROR_NO_TRACKING_SERVICE, + ERROR_NO_VOLUME_ID, // = 1173 + ERROR_UNABLE_TO_REMOVE_REPLACED = 1175, + ERROR_UNABLE_TO_MOVE_REPLACEMENT, + ERROR_UNABLE_TO_MOVE_REPLACEMENT_2, + ERROR_JOURNAL_DELETE_IN_PROGRESS, + ERROR_JOURNAL_NOT_ACTIVE, + ERROR_POTENTIAL_FILE_FOUND, + ERROR_JOURNAL_ENTRY_DELETED, // = 1181 + ERROR_BAD_DEVICE = 1200, + ERROR_CONNECTION_UNAVAIL, + ERROR_DEVICE_ALREADY_REMEMBERED, + ERROR_NO_NET_OR_BAD_PATH, + ERROR_BAD_PROVIDER, + ERROR_CANNOT_OPEN_PROFILE, + ERROR_BAD_PROFILE, + ERROR_NOT_CONTAINER, + ERROR_EXTENDED_ERROR, + ERROR_INVALID_GROUPNAME, + ERROR_INVALID_COMPUTERNAME, + ERROR_INVALID_EVENTNAME, + ERROR_INVALID_DOMAINNAME, + ERROR_INVALID_SERVICENAME, + ERROR_INVALID_NETNAME, + ERROR_INVALID_SHARENAME, + ERROR_INVALID_PASSWORDNAME, + ERROR_INVALID_MESSAGENAME, + ERROR_INVALID_MESSAGEDEST, + ERROR_SESSION_CREDENTIAL_CONFLICT, + ERROR_REMOTE_SESSION_LIMIT_EXCEEDED, + ERROR_DUP_DOMAINNAME, + ERROR_NO_NETWORK, + ERROR_CANCELLED, + ERROR_USER_MAPPED_FILE, + ERROR_CONNECTION_REFUSED, + ERROR_GRACEFUL_DISCONNECT, + ERROR_ADDRESS_ALREADY_ASSOCIATED, + ERROR_ADDRESS_NOT_ASSOCIATED, + ERROR_CONNECTION_INVALID, + ERROR_CONNECTION_ACTIVE, + ERROR_NETWORK_UNREACHABLE, + ERROR_HOST_UNREACHABLE, + ERROR_PROTOCOL_UNREACHABLE, + ERROR_PORT_UNREACHABLE, + ERROR_REQUEST_ABORTED, + ERROR_CONNECTION_ABORTED, + ERROR_RETRY, + ERROR_CONNECTION_COUNT_LIMIT, + ERROR_LOGIN_TIME_RESTRICTION, + ERROR_LOGIN_WKSTA_RESTRICTION, + ERROR_INCORRECT_ADDRESS, + ERROR_ALREADY_REGISTERED, + ERROR_SERVICE_NOT_FOUND, + ERROR_NOT_AUTHENTICATED, + ERROR_NOT_LOGGED_ON, + ERROR_CONTINUE, + ERROR_ALREADY_INITIALIZED, + ERROR_NO_MORE_DEVICES, + ERROR_NO_SUCH_SITE, + ERROR_DOMAIN_CONTROLLER_EXISTS, + ERROR_ONLY_IF_CONNECTED, + ERROR_OVERRIDE_NOCHANGES, + ERROR_BAD_USER_PROFILE, + ERROR_NOT_SUPPORTED_ON_SBS, + ERROR_SERVER_SHUTDOWN_IN_PROGRESS, + ERROR_HOST_DOWN, + ERROR_NON_ACCOUNT_SID, + ERROR_NON_DOMAIN_SID, + ERROR_APPHELP_BLOCK, + ERROR_ACCESS_DISABLED_BY_POLICY, + ERROR_REG_NAT_CONSUMPTION, + ERROR_CSCSHARE_OFFLINE, + ERROR_PKINIT_FAILURE, + ERROR_SMARTCARD_SUBSYSTEM_FAILURE, + ERROR_DOWNGRADE_DETECTED, + SEC_E_SMARTCARD_CERT_REVOKED, + SEC_E_ISSUING_CA_UNTRUSTED, + SEC_E_REVOCATION_OFFLINE_C, + SEC_E_PKINIT_CLIENT_FAILUR, + SEC_E_SMARTCARD_CERT_EXPIRED, + ERROR_MACHINE_LOCKED, // = 1271 + ERROR_CALLBACK_SUPPLIED_INVALID_DATA = 1273, + ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED, + ERROR_DRIVER_BLOCKED, + ERROR_INVALID_IMPORT_OF_NON_DLL, + ERROR_ACCESS_DISABLED_WEBBLADE, + ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER, + ERROR_RECOVERY_FAILURE, + ERROR_ALREADY_FIBER, + ERROR_ALREADY_THREAD, + ERROR_STACK_BUFFER_OVERRUN, + ERROR_PARAMETER_QUOTA_EXCEEDED, + ERROR_DEBUGGER_INACTIVE, // = 1284 + ERROR_NOT_ALL_ASSIGNED = 1300, + ERROR_SOME_NOT_MAPPED, + ERROR_NO_QUOTAS_FOR_ACCOUNT, + ERROR_LOCAL_USER_SESSION_KEY, + ERROR_NULL_LM_PASSWORD, + ERROR_UNKNOWN_REVISION, + ERROR_REVISION_MISMATCH, + ERROR_INVALID_OWNER, + ERROR_INVALID_PRIMARY_GROUP, + ERROR_NO_IMPERSONATION_TOKEN, + ERROR_CANT_DISABLE_MANDATORY, + ERROR_NO_LOGON_SERVERS, + ERROR_NO_SUCH_LOGON_SESSION, + ERROR_NO_SUCH_PRIVILEGE, + ERROR_PRIVILEGE_NOT_HELD, + ERROR_INVALID_ACCOUNT_NAME, + ERROR_USER_EXISTS, + ERROR_NO_SUCH_USER, + ERROR_GROUP_EXISTS, + ERROR_NO_SUCH_GROUP, + ERROR_MEMBER_IN_GROUP, + ERROR_MEMBER_NOT_IN_GROUP, + ERROR_LAST_ADMIN, + ERROR_WRONG_PASSWORD, + ERROR_ILL_FORMED_PASSWORD, + ERROR_PASSWORD_RESTRICTION, + ERROR_LOGON_FAILURE, + ERROR_ACCOUNT_RESTRICTION, + ERROR_INVALID_LOGON_HOURS, + ERROR_INVALID_WORKSTATION, + ERROR_PASSWORD_EXPIRED, + ERROR_ACCOUNT_DISABLED, + ERROR_NONE_MAPPED, + ERROR_TOO_MANY_LUIDS_REQUESTED, + ERROR_LUIDS_EXHAUSTED, + ERROR_INVALID_SUB_AUTHORITY, + ERROR_INVALID_ACL, + ERROR_INVALID_SID, + ERROR_INVALID_SECURITY_DESCR, // = 1338 + ERROR_BAD_INHERITANCE_ACL = 1340, + ERROR_SERVER_DISABLED, + ERROR_SERVER_NOT_DISABLED, + ERROR_INVALID_ID_AUTHORITY, + ERROR_ALLOTTED_SPACE_EXCEEDED, + ERROR_INVALID_GROUP_ATTRIBUTES, + ERROR_BAD_IMPERSONATION_LEVEL, + ERROR_CANT_OPEN_ANONYMOUS, + ERROR_BAD_VALIDATION_CLASS, + ERROR_BAD_TOKEN_TYPE, + ERROR_NO_SECURITY_ON_OBJECT, + ERROR_CANT_ACCESS_DOMAIN_INFO, + ERROR_INVALID_SERVER_STATE, + ERROR_INVALID_DOMAIN_STATE, + ERROR_INVALID_DOMAIN_ROLE, + ERROR_NO_SUCH_DOMAIN, + ERROR_DOMAIN_EXISTS, + ERROR_DOMAIN_LIMIT_EXCEEDED, + ERROR_INTERNAL_DB_CORRUPTION, + ERROR_INTERNAL_ERROR, + ERROR_GENERIC_NOT_MAPPED, + ERROR_BAD_DESCRIPTOR_FORMAT, + ERROR_NOT_LOGON_PROCESS, + ERROR_LOGON_SESSION_EXISTS, + ERROR_NO_SUCH_PACKAGE, + ERROR_BAD_LOGON_SESSION_STATE, + ERROR_LOGON_SESSION_COLLISION, + ERROR_INVALID_LOGON_TYPE, + ERROR_CANNOT_IMPERSONATE, + ERROR_RXACT_INVALID_STATE, + ERROR_RXACT_COMMIT_FAILURE, + ERROR_SPECIAL_ACCOUNT, + ERROR_SPECIAL_GROUP, + ERROR_SPECIAL_USER, + ERROR_MEMBERS_PRIMARY_GROUP, + ERROR_TOKEN_ALREADY_IN_USE, + ERROR_NO_SUCH_ALIAS, + ERROR_MEMBER_NOT_IN_ALIAS, + ERROR_MEMBER_IN_ALIAS, + ERROR_ALIAS_EXISTS, + ERROR_LOGON_NOT_GRANTED, + ERROR_TOO_MANY_SECRETS, + ERROR_SECRET_TOO_LONG, + ERROR_INTERNAL_DB_ERROR, + ERROR_TOO_MANY_CONTEXT_IDS, + ERROR_LOGON_TYPE_NOT_GRANTED, + ERROR_NT_CROSS_ENCRYPTION_REQUIRED, + ERROR_NO_SUCH_MEMBER, + ERROR_INVALID_MEMBER, + ERROR_TOO_MANY_SIDS, + ERROR_LM_CROSS_ENCRYPTION_REQUIRED, + ERROR_NO_INHERITANCE, + ERROR_FILE_CORRUPT, + ERROR_DISK_CORRUPT, + ERROR_NO_USER_SESSION_KEY, + ERROR_LICENSE_QUOTA_EXCEEDED, + ERROR_WRONG_TARGET_NAME, + ERROR_MUTUAL_AUTH_FAILED, + ERROR_TIME_SKEW, + ERROR_CURRENT_DOMAIN_NOT_ALLOWED, + ERROR_INVALID_WINDOW_HANDLE, + ERROR_INVALID_MENU_HANDLE, + ERROR_INVALID_CURSOR_HANDLE, + ERROR_INVALID_ACCEL_HANDLE, + ERROR_INVALID_HOOK_HANDLE, + ERROR_INVALID_DWP_HANDLE, + ERROR_TLW_WITH_WSCHILD, + ERROR_CANNOT_FIND_WND_CLASS, + ERROR_WINDOW_OF_OTHER_THREAD, + ERROR_HOTKEY_ALREADY_REGISTERED, + ERROR_CLASS_ALREADY_EXISTS, + ERROR_CLASS_DOES_NOT_EXIST, + ERROR_CLASS_HAS_WINDOWS, + ERROR_INVALID_INDEX, + ERROR_INVALID_ICON_HANDLE, + ERROR_PRIVATE_DIALOG_INDEX, + ERROR_LISTBOX_ID_NOT_FOUND, + ERROR_NO_WILDCARD_CHARACTERS, + ERROR_CLIPBOARD_NOT_OPEN, + ERROR_HOTKEY_NOT_REGISTERED, + ERROR_WINDOW_NOT_DIALOG, + ERROR_CONTROL_ID_NOT_FOUND, + ERROR_INVALID_COMBOBOX_MESSAGE, + ERROR_WINDOW_NOT_COMBOBOX, + ERROR_INVALID_EDIT_HEIGHT, + ERROR_DC_NOT_FOUND, + ERROR_INVALID_HOOK_FILTER, + ERROR_INVALID_FILTER_PROC, + ERROR_HOOK_NEEDS_HMOD, + ERROR_GLOBAL_ONLY_HOOK, + ERROR_JOURNAL_HOOK_SET, + ERROR_HOOK_NOT_INSTALLED, + ERROR_INVALID_LB_MESSAGE, + ERROR_SETCOUNT_ON_BAD_LB, + ERROR_LB_WITHOUT_TABSTOPS, + ERROR_DESTROY_OBJECT_OF_OTHER_THREAD, + ERROR_CHILD_WINDOW_MENU, + ERROR_NO_SYSTEM_MENU, + ERROR_INVALID_MSGBOX_STYLE, + ERROR_INVALID_SPI_VALUE, + ERROR_SCREEN_ALREADY_LOCKED, + ERROR_HWNDS_HAVE_DIFF_PARENT, + ERROR_NOT_CHILD_WINDOW, + ERROR_INVALID_GW_COMMAND, + ERROR_INVALID_THREAD_ID, + ERROR_NON_MDICHILD_WINDOW, + ERROR_POPUP_ALREADY_ACTIVE, + ERROR_NO_SCROLLBARS, + ERROR_INVALID_SCROLLBAR_RANGE, + ERROR_INVALID_SHOWWIN_COMMAND, + ERROR_NO_SYSTEM_RESOURCES, + ERROR_NONPAGED_SYSTEM_RESOURCES, + ERROR_PAGED_SYSTEM_RESOURCES, + ERROR_WORKING_SET_QUOTA, + ERROR_PAGEFILE_QUOTA, + ERROR_COMMITMENT_LIMIT, + ERROR_MENU_ITEM_NOT_FOUND, + ERROR_INVALID_KEYBOARD_HANDLE, + ERROR_HOOK_TYPE_NOT_ALLOWED, + ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION, + ERROR_TIMEOUT, + ERROR_INVALID_MONITOR_HANDLE, // = 1461 + ERROR_EVENTLOG_FILE_CORRUPT = 1500, + ERROR_EVENTLOG_CANT_START, + ERROR_LOG_FILE_FULL, + ERROR_EVENTLOG_FILE_CHANGED, // = 1503 + ERROR_INSTALL_SERVICE_FAILURE = 1601, + ERROR_INSTALL_USEREXIT, + ERROR_INSTALL_FAILURE, + ERROR_INSTALL_SUSPEND, + ERROR_UNKNOWN_PRODUCT, + ERROR_UNKNOWN_FEATURE, + ERROR_UNKNOWN_COMPONENT, + ERROR_UNKNOWN_PROPERTY, + ERROR_INVALID_HANDLE_STATE, + ERROR_BAD_CONFIGURATION, + ERROR_INDEX_ABSENT, + ERROR_INSTALL_SOURCE_ABSENT, + ERROR_INSTALL_PACKAGE_VERSION, + ERROR_PRODUCT_UNINSTALLED, + ERROR_BAD_QUERY_SYNTAX, + ERROR_INVALID_FIELD, + ERROR_DEVICE_REMOVED, + ERROR_INSTALL_ALREADY_RUNNING, + ERROR_INSTALL_PACKAGE_OPEN_FAILED, + ERROR_INSTALL_PACKAGE_INVALID, + ERROR_INSTALL_UI_FAILURE, + ERROR_INSTALL_LOG_FAILURE, + ERROR_INSTALL_LANGUAGE_UNSUPPORTED, + ERROR_INSTALL_TRANSFORM_FAILURE, + ERROR_INSTALL_PACKAGE_REJECTED, + ERROR_FUNCTION_NOT_CALLED, + ERROR_FUNCTION_FAILED, + ERROR_INVALID_TABLE, + ERROR_DATATYPE_MISMATCH, + ERROR_UNSUPPORTED_TYPE, + ERROR_CREATE_FAILED, + ERROR_INSTALL_TEMP_UNWRITABLE, + ERROR_INSTALL_PLATFORM_UNSUPPORTED, + ERROR_INSTALL_NOTUSED, + ERROR_PATCH_PACKAGE_OPEN_FAILED, + ERROR_PATCH_PACKAGE_INVALID, + ERROR_PATCH_PACKAGE_UNSUPPORTED, + ERROR_PRODUCT_VERSION, + ERROR_INVALID_COMMAND_LINE, + ERROR_INSTALL_REMOTE_DISALLOWED, + ERROR_SUCCESS_REBOOT_INITIATED, + ERROR_PATCH_TARGET_NOT_FOUND, + ERROR_PATCH_PACKAGE_REJECTED, + ERROR_INSTALL_TRANSFORM_REJECTED, + ERROR_INSTALL_REMOTE_PROHIBITED, // = 1645 + RPC_S_INVALID_STRING_BINDING = 1700, + RPC_S_WRONG_KIND_OF_BINDING, + RPC_S_INVALID_BINDING, + RPC_S_PROTSEQ_NOT_SUPPORTED, + RPC_S_INVALID_RPC_PROTSEQ, + RPC_S_INVALID_STRING_UUID, + RPC_S_INVALID_ENDPOINT_FORMAT, + RPC_S_INVALID_NET_ADDR, + RPC_S_NO_ENDPOINT_FOUND, + RPC_S_INVALID_TIMEOUT, + RPC_S_OBJECT_NOT_FOUND, + RPC_S_ALREADY_REGISTERED, + RPC_S_TYPE_ALREADY_REGISTERED, + RPC_S_ALREADY_LISTENING, + RPC_S_NO_PROTSEQS_REGISTERED, + RPC_S_NOT_LISTENING, + RPC_S_UNKNOWN_MGR_TYPE, + RPC_S_UNKNOWN_IF, + RPC_S_NO_BINDINGS, + RPC_S_NO_PROTSEQS, + RPC_S_CANT_CREATE_ENDPOINT, + RPC_S_OUT_OF_RESOURCES, + RPC_S_SERVER_UNAVAILABLE, + RPC_S_SERVER_TOO_BUSY, + RPC_S_INVALID_NETWORK_OPTIONS, + RPC_S_NO_CALL_ACTIVE, + RPC_S_CALL_FAILED, + RPC_S_CALL_FAILED_DNE, + RPC_S_PROTOCOL_ERROR, // = 1728 + RPC_S_UNSUPPORTED_TRANS_SYN = 1730, + RPC_S_UNSUPPORTED_TYPE = 1732, + RPC_S_INVALID_TAG, + RPC_S_INVALID_BOUND, + RPC_S_NO_ENTRY_NAME, + RPC_S_INVALID_NAME_SYNTAX, + RPC_S_UNSUPPORTED_NAME_SYNTAX, // = 1737 + RPC_S_UUID_NO_ADDRESS = 1739, + RPC_S_DUPLICATE_ENDPOINT, + RPC_S_UNKNOWN_AUTHN_TYPE, + RPC_S_MAX_CALLS_TOO_SMALL, + RPC_S_STRING_TOO_LONG, + RPC_S_PROTSEQ_NOT_FOUND, + RPC_S_PROCNUM_OUT_OF_RANGE, + RPC_S_BINDING_HAS_NO_AUTH, + RPC_S_UNKNOWN_AUTHN_SERVICE, + RPC_S_UNKNOWN_AUTHN_LEVEL, + RPC_S_INVALID_AUTH_IDENTITY, + RPC_S_UNKNOWN_AUTHZ_SERVICE, + EPT_S_INVALID_ENTRY, + EPT_S_CANT_PERFORM_OP, + EPT_S_NOT_REGISTERED, + RPC_S_NOTHING_TO_EXPORT, + RPC_S_INCOMPLETE_NAME, + RPC_S_INVALID_VERS_OPTION, + RPC_S_NO_MORE_MEMBERS, + RPC_S_NOT_ALL_OBJS_UNEXPORTED, + RPC_S_INTERFACE_NOT_FOUND, + RPC_S_ENTRY_ALREADY_EXISTS, + RPC_S_ENTRY_NOT_FOUND, + RPC_S_NAME_SERVICE_UNAVAILABLE, + RPC_S_INVALID_NAF_ID, + RPC_S_CANNOT_SUPPORT, + RPC_S_NO_CONTEXT_AVAILABLE, + RPC_S_INTERNAL_ERROR, + RPC_S_ZERO_DIVIDE, + RPC_S_ADDRESS_ERROR, + RPC_S_FP_DIV_ZERO, + RPC_S_FP_UNDERFLOW, + RPC_S_FP_OVERFLOW, + RPC_X_NO_MORE_ENTRIES, + RPC_X_SS_CHAR_TRANS_OPEN_FAIL, + RPC_X_SS_CHAR_TRANS_SHORT_FILE, + RPC_X_SS_IN_NULL_CONTEXT, // = 1775 + RPC_X_SS_CONTEXT_DAMAGED = 1777, + RPC_X_SS_HANDLES_MISMATCH, + RPC_X_SS_CANNOT_GET_CALL_HANDLE, + RPC_X_NULL_REF_POINTER, + RPC_X_ENUM_VALUE_OUT_OF_RANGE, + RPC_X_BYTE_COUNT_TOO_SMALL, + RPC_X_BAD_STUB_DATA, + ERROR_INVALID_USER_BUFFER, + ERROR_UNRECOGNIZED_MEDIA, + ERROR_NO_TRUST_LSA_SECRET, + ERROR_NO_TRUST_SAM_ACCOUNT, + ERROR_TRUSTED_DOMAIN_FAILURE, + ERROR_TRUSTED_RELATIONSHIP_FAILURE, + ERROR_TRUST_FAILURE, + RPC_S_CALL_IN_PROGRESS, + ERROR_NETLOGON_NOT_STARTED, + ERROR_ACCOUNT_EXPIRED, + ERROR_REDIRECTOR_HAS_OPEN_HANDLES, + ERROR_PRINTER_DRIVER_ALREADY_INSTALLED, + ERROR_UNKNOWN_PORT, + ERROR_UNKNOWN_PRINTER_DRIVER, + ERROR_UNKNOWN_PRINTPROCESSOR, + ERROR_INVALID_SEPARATOR_FILE, + ERROR_INVALID_PRIORITY, + ERROR_INVALID_PRINTER_NAME, + ERROR_PRINTER_ALREADY_EXISTS, + ERROR_INVALID_PRINTER_COMMAND, + ERROR_INVALID_DATATYPE, + ERROR_INVALID_ENVIRONMENT, + RPC_S_NO_MORE_BINDINGS, + ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT, + ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT, + ERROR_NOLOGON_SERVER_TRUST_ACCOUNT, + ERROR_DOMAIN_TRUST_INCONSISTENT, + ERROR_SERVER_HAS_OPEN_HANDLES, + ERROR_RESOURCE_DATA_NOT_FOUND, + ERROR_RESOURCE_TYPE_NOT_FOUND, + ERROR_RESOURCE_NAME_NOT_FOUND, + ERROR_RESOURCE_LANG_NOT_FOUND, + ERROR_NOT_ENOUGH_QUOTA, + RPC_S_NO_INTERFACES, + RPC_S_CALL_CANCELLED, + RPC_S_BINDING_INCOMPLETE, + RPC_S_COMM_FAILURE, + RPC_S_UNSUPPORTED_AUTHN_LEVEL, + RPC_S_NO_PRINC_NAME, + RPC_S_NOT_RPC_ERROR, + RPC_S_UUID_LOCAL_ONLY, + RPC_S_SEC_PKG_ERROR, + RPC_S_NOT_CANCELLED, + RPC_X_INVALID_ES_ACTION, + RPC_X_WRONG_ES_VERSION, + RPC_X_WRONG_STUB_VERSION, + RPC_X_INVALID_PIPE_OBJECT, + RPC_X_WRONG_PIPE_ORDER, + RPC_X_WRONG_PIPE_VERSION, // = 1832 + RPC_S_GROUP_MEMBER_NOT_FOUND = 1898, + EPT_S_CANT_CREATE, + RPC_S_INVALID_OBJECT, + ERROR_INVALID_TIME, + ERROR_INVALID_FORM_NAME, + ERROR_INVALID_FORM_SIZE, + ERROR_ALREADY_WAITING, + ERROR_PRINTER_DELETED, + ERROR_INVALID_PRINTER_STATE, + ERROR_PASSWORD_MUST_CHANGE, + ERROR_DOMAIN_CONTROLLER_NOT_FOUND, + ERROR_ACCOUNT_LOCKED_OUT, + OR_INVALID_OXID, + OR_INVALID_OID, + OR_INVALID_SET, + RPC_S_SEND_INCOMPLETE, + RPC_S_INVALID_ASYNC_HANDLE, + RPC_S_INVALID_ASYNC_CALL, + RPC_X_PIPE_CLOSED, + RPC_X_PIPE_DISCIPLINE_ERROR, + RPC_X_PIPE_EMPTY, + ERROR_NO_SITENAME, + ERROR_CANT_ACCESS_FILE, + ERROR_CANT_RESOLVE_FILENAME, + RPC_S_ENTRY_TYPE_MISMATCH, + RPC_S_NOT_ALL_OBJS_EXPORTED, + RPC_S_INTERFACE_NOT_EXPORTED, + RPC_S_PROFILE_NOT_ADDED, + RPC_S_PRF_ELT_NOT_ADDED, + RPC_S_PRF_ELT_NOT_REMOVED, + RPC_S_GRP_ELT_NOT_ADDED, + RPC_S_GRP_ELT_NOT_REMOVED, + ERROR_KM_DRIVER_BLOCKED, + ERROR_CONTEXT_EXPIRED, + ERROR_PER_USER_TRUST_QUOTA_EXCEEDED, + ERROR_ALL_USER_TRUST_QUOTA_EXCEEDED, + ERROR_USER_DELETE_TRUST_QUOTA_EXCEEDED, // = 1934 + ERROR_INVALID_PIXEL_FORMAT = 2000, + ERROR_BAD_DRIVER, + ERROR_INVALID_WINDOW_STYLE, + ERROR_METAFILE_NOT_SUPPORTED, + ERROR_TRANSFORM_NOT_SUPPORTED, + ERROR_CLIPPING_NOT_SUPPORTED, // = 2005 + ERROR_INVALID_CMM = 2010, + ERROR_INVALID_PROFILE, + ERROR_TAG_NOT_FOUND, + ERROR_TAG_NOT_PRESENT, + ERROR_DUPLICATE_TAG, + ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE, + ERROR_PROFILE_NOT_FOUND, + ERROR_INVALID_COLORSPACE, + ERROR_ICM_NOT_ENABLED, + ERROR_DELETING_ICM_XFORM, + ERROR_INVALID_TRANSFORM, + ERROR_COLORSPACE_MISMATCH, + ERROR_INVALID_COLORINDEX, // = 2022 + ERROR_CONNECTED_OTHER_PASSWORD = 2108, + ERROR_CONNECTED_OTHER_PASSWORD_DEFAULT, // = 2109 + ERROR_BAD_USERNAME = 2202, + ERROR_NOT_CONNECTED = 2250, + ERROR_OPEN_FILES = 2401, + ERROR_ACTIVE_CONNECTIONS, // = 2402 + ERROR_DEVICE_IN_USE = 2404, + ERROR_UNKNOWN_PRINT_MONITOR = 3000, + ERROR_PRINTER_DRIVER_IN_USE, + ERROR_SPOOL_FILE_NOT_FOUND, + ERROR_SPL_NO_STARTDOC, + ERROR_SPL_NO_ADDJOB, + ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED, + ERROR_PRINT_MONITOR_ALREADY_INSTALLED, + ERROR_INVALID_PRINT_MONITOR, + ERROR_PRINT_MONITOR_IN_USE, + ERROR_PRINTER_HAS_JOBS_QUEUED, + ERROR_SUCCESS_REBOOT_REQUIRED, + ERROR_SUCCESS_RESTART_REQUIRED, + ERROR_PRINTER_NOT_FOUND, + ERROR_PRINTER_DRIVER_WARNED, + ERROR_PRINTER_DRIVER_BLOCKED, // = 3014 + ERROR_WINS_INTERNAL = 4000, + ERROR_CAN_NOT_DEL_LOCAL_WINS, + ERROR_STATIC_INIT, + ERROR_INC_BACKUP, + ERROR_FULL_BACKUP, + ERROR_REC_NON_EXISTENT, + ERROR_RPL_NOT_ALLOWED, // = 4006 + ERROR_DHCP_ADDRESS_CONFLICT = 4100, + ERROR_WMI_GUID_NOT_FOUND = 4200, + ERROR_WMI_INSTANCE_NOT_FOUND, + ERROR_WMI_ITEMID_NOT_FOUND, + ERROR_WMI_TRY_AGAIN, + ERROR_WMI_DP_NOT_FOUND, + ERROR_WMI_UNRESOLVED_INSTANCE_REF, + ERROR_WMI_ALREADY_ENABLED, + ERROR_WMI_GUID_DISCONNECTED, + ERROR_WMI_SERVER_UNAVAILABLE, + ERROR_WMI_DP_FAILED, + ERROR_WMI_INVALID_MOF, + ERROR_WMI_INVALID_REGINFO, + ERROR_WMI_ALREADY_DISABLED, + ERROR_WMI_READ_ONLY, + ERROR_WMI_SET_FAILURE, // = 4214 + ERROR_INVALID_MEDIA = 4300, + ERROR_INVALID_LIBRARY, + ERROR_INVALID_MEDIA_POOL, + ERROR_DRIVE_MEDIA_MISMATCH, + ERROR_MEDIA_OFFLINE, + ERROR_LIBRARY_OFFLINE, + ERROR_EMPTY, + ERROR_NOT_EMPTY, + ERROR_MEDIA_UNAVAILABLE, + ERROR_RESOURCE_DISABLED, + ERROR_INVALID_CLEANER, + ERROR_UNABLE_TO_CLEAN, + ERROR_OBJECT_NOT_FOUND, + ERROR_DATABASE_FAILURE, + ERROR_DATABASE_FULL, + ERROR_MEDIA_INCOMPATIBLE, + ERROR_RESOURCE_NOT_PRESENT, + ERROR_INVALID_OPERATION, + ERROR_MEDIA_NOT_AVAILABLE, + ERROR_DEVICE_NOT_AVAILABLE, + ERROR_REQUEST_REFUSED, + ERROR_INVALID_DRIVE_OBJECT, + ERROR_LIBRARY_FULL, + ERROR_MEDIUM_NOT_ACCESSIBLE, + ERROR_UNABLE_TO_LOAD_MEDIUM, + ERROR_UNABLE_TO_INVENTORY_DRIVE, + ERROR_UNABLE_TO_INVENTORY_SLOT, + ERROR_UNABLE_TO_INVENTORY_TRANSPORT, + ERROR_TRANSPORT_FULL, + ERROR_CONTROLLING_IEPORT, + ERROR_UNABLE_TO_EJECT_MOUNTED_MEDIA, + ERROR_CLEANER_SLOT_SET, + ERROR_CLEANER_SLOT_NOT_SET, + ERROR_CLEANER_CARTRIDGE_SPENT, + ERROR_UNEXPECTED_OMID, + ERROR_CANT_DELETE_LAST_ITEM, + ERROR_MESSAGE_EXCEEDS_MAX_SIZE, + ERROR_VOLUME_CONTAINS_SYS_FILES, + ERROR_INDIGENOUS_TYPE, + ERROR_NO_SUPPORTING_DRIVES, + ERROR_CLEANER_CARTRIDGE_INSTALLED, // = 4340 + ERROR_FILE_OFFLINE = 4350, + ERROR_REMOTE_STORAGE_NOT_ACTIVE, + ERROR_REMOTE_STORAGE_MEDIA_ERROR, // = 4352 + ERROR_NOT_A_REPARSE_POINT = 4390, + ERROR_REPARSE_ATTRIBUTE_CONFLICT, + ERROR_INVALID_REPARSE_DATA, + ERROR_REPARSE_TAG_INVALID, + ERROR_REPARSE_TAG_MISMATCH, // = 4394 + ERROR_VOLUME_NOT_SIS_ENABLED = 4500, + ERROR_DEPENDENT_RESOURCE_EXISTS = 5001, + ERROR_DEPENDENCY_NOT_FOUND, + ERROR_DEPENDENCY_ALREADY_EXISTS, + ERROR_RESOURCE_NOT_ONLINE, + ERROR_HOST_NODE_NOT_AVAILABLE, + ERROR_RESOURCE_NOT_AVAILABLE, + ERROR_RESOURCE_NOT_FOUND, + ERROR_SHUTDOWN_CLUSTER, + ERROR_CANT_EVICT_ACTIVE_NODE, + ERROR_OBJECT_ALREADY_EXISTS, + ERROR_OBJECT_IN_LIST, + ERROR_GROUP_NOT_AVAILABLE, + ERROR_GROUP_NOT_FOUND, + ERROR_GROUP_NOT_ONLINE, + ERROR_HOST_NODE_NOT_RESOURCE_OWNER, + ERROR_HOST_NODE_NOT_GROUP_OWNER, + ERROR_RESMON_CREATE_FAILED, + ERROR_RESMON_ONLINE_FAILED, + ERROR_RESOURCE_ONLINE, + ERROR_QUORUM_RESOURCE, + ERROR_NOT_QUORUM_CAPABLE, + ERROR_CLUSTER_SHUTTING_DOWN, + ERROR_INVALID_STATE, + ERROR_RESOURCE_PROPERTIES_STORED, + ERROR_NOT_QUORUM_CLASS, + ERROR_CORE_RESOURCE, + ERROR_QUORUM_RESOURCE_ONLINE_FAILED, + ERROR_QUORUMLOG_OPEN_FAILED, + ERROR_CLUSTERLOG_CORRUPT, + ERROR_CLUSTERLOG_RECORD_EXCEEDS_MAXSIZE, + ERROR_CLUSTERLOG_EXCEEDS_MAXSIZE, + ERROR_CLUSTERLOG_CHKPOINT_NOT_FOUND, + ERROR_CLUSTERLOG_NOT_ENOUGH_SPACE, + ERROR_QUORUM_OWNER_ALIVE, + ERROR_NETWORK_NOT_AVAILABLE, + ERROR_NODE_NOT_AVAILABLE, + ERROR_ALL_NODES_NOT_AVAILABLE, + ERROR_RESOURCE_FAILED, + ERROR_CLUSTER_INVALID_NODE, + ERROR_CLUSTER_NODE_EXISTS, + ERROR_CLUSTER_JOIN_IN_PROGRESS, + ERROR_CLUSTER_NODE_NOT_FOUND, + ERROR_CLUSTER_LOCAL_NODE_NOT_FOUND, + ERROR_CLUSTER_NETWORK_EXISTS, + ERROR_CLUSTER_NETWORK_NOT_FOUND, + ERROR_CLUSTER_NETINTERFACE_EXISTS, + ERROR_CLUSTER_NETINTERFACE_NOT_FOUND, + ERROR_CLUSTER_INVALID_REQUEST, + ERROR_CLUSTER_INVALID_NETWORK_PROVIDER, + ERROR_CLUSTER_NODE_DOWN, + ERROR_CLUSTER_NODE_UNREACHABLE, + ERROR_CLUSTER_NODE_NOT_MEMBER, + ERROR_CLUSTER_JOIN_NOT_IN_PROGRESS, + ERROR_CLUSTER_INVALID_NETWORK, // = 5054 + ERROR_CLUSTER_NODE_UP = 5056, + ERROR_CLUSTER_IPADDR_IN_USE, + ERROR_CLUSTER_NODE_NOT_PAUSED, + ERROR_CLUSTER_NO_SECURITY_CONTEXT, + ERROR_CLUSTER_NETWORK_NOT_INTERNAL, + ERROR_CLUSTER_NODE_ALREADY_UP, + ERROR_CLUSTER_NODE_ALREADY_DOWN, + ERROR_CLUSTER_NETWORK_ALREADY_ONLINE, + ERROR_CLUSTER_NETWORK_ALREADY_OFFLINE, + ERROR_CLUSTER_NODE_ALREADY_MEMBER, + ERROR_CLUSTER_LAST_INTERNAL_NETWORK, + ERROR_CLUSTER_NETWORK_HAS_DEPENDENTS, + ERROR_INVALID_OPERATION_ON_QUORUM, + ERROR_DEPENDENCY_NOT_ALLOWED, + ERROR_CLUSTER_NODE_PAUSED, + ERROR_NODE_CANT_HOST_RESOURCE, + ERROR_CLUSTER_NODE_NOT_READY, + ERROR_CLUSTER_NODE_SHUTTING_DOWN, + ERROR_CLUSTER_JOIN_ABORTED, + ERROR_CLUSTER_INCOMPATIBLE_VERSIONS, + ERROR_CLUSTER_MAXNUM_OF_RESOURCES_EXCEEDED, + ERROR_CLUSTER_SYSTEM_CONFIG_CHANGED, + ERROR_CLUSTER_RESOURCE_TYPE_NOT_FOUND, + ERROR_CLUSTER_RESTYPE_NOT_SUPPORTED, + ERROR_CLUSTER_RESNAME_NOT_FOUND, + ERROR_CLUSTER_NO_RPC_PACKAGES_REGISTERED, + ERROR_CLUSTER_OWNER_NOT_IN_PREFLIST, + ERROR_CLUSTER_DATABASE_SEQMISMATCH, + ERROR_RESMON_INVALID_STATE, + ERROR_CLUSTER_GUM_NOT_LOCKER, + ERROR_QUORUM_DISK_NOT_FOUND, + ERROR_DATABASE_BACKUP_CORRUPT, + ERROR_CLUSTER_NODE_ALREADY_HAS_DFS_ROOT, + ERROR_RESOURCE_PROPERTY_UNCHANGEABLE, // = 5089 + ERROR_CLUSTER_MEMBERSHIP_INVALID_STATE = 5890, + ERROR_CLUSTER_QUORUMLOG_NOT_FOUND, + ERROR_CLUSTER_MEMBERSHIP_HALT, + ERROR_CLUSTER_INSTANCE_ID_MISMATCH, + ERROR_CLUSTER_NETWORK_NOT_FOUND_FOR_IP, + ERROR_CLUSTER_PROPERTY_DATA_TYPE_MISMATCH, + ERROR_CLUSTER_EVICT_WITHOUT_CLEANUP, + ERROR_CLUSTER_PARAMETER_MISMATCH, + ERROR_NODE_CANNOT_BE_CLUSTERED, + ERROR_CLUSTER_WRONG_OS_VERSION, + ERROR_CLUSTER_CANT_CREATE_DUP_CLUSTER_NAME, + ERROR_CLUSCFG_ALREADY_COMMITTED, + ERROR_CLUSCFG_ROLLBACK_FAILED, + ERROR_CLUSCFG_SYSTEM_DISK_DRIVE_LETTER_CONFLICT, + ERROR_CLUSTER_OLD_VERSION, + ERROR_CLUSTER_MISMATCHED_COMPUTER_ACCT_NAME, // = 5905 + ERROR_ENCRYPTION_FAILED = 6000, + ERROR_DECRYPTION_FAILED, + ERROR_FILE_ENCRYPTED, + ERROR_NO_RECOVERY_POLICY, + ERROR_NO_EFS, + ERROR_WRONG_EFS, + ERROR_NO_USER_KEYS, + ERROR_FILE_NOT_ENCRYPTED, + ERROR_NOT_EXPORT_FORMAT, + ERROR_FILE_READ_ONLY, + ERROR_DIR_EFS_DISALLOWED, + ERROR_EFS_SERVER_NOT_TRUSTED, + ERROR_BAD_RECOVERY_POLICY, + ERROR_EFS_ALG_BLOB_TOO_BIG, + ERROR_VOLUME_NOT_SUPPORT_EFS, + ERROR_EFS_DISABLED, + ERROR_EFS_VERSION_NOT_SUPPORT, // = 6016 + ERROR_NO_BROWSER_SERVERS_FOUND = 6118, + SCHED_E_SERVICE_NOT_LOCALSYSTEM = 6200, + + ERROR_CTX_WINSTATION_NAME_INVALID = 7001, + ERROR_CTX_INVALID_PD, + ERROR_CTX_PD_NOT_FOUND, + ERROR_CTX_WD_NOT_FOUND, + ERROR_CTX_CANNOT_MAKE_EVENTLOG_ENTRY, + ERROR_CTX_SERVICE_NAME_COLLISION, + ERROR_CTX_CLOSE_PENDING, + ERROR_CTX_NO_OUTBUF, + ERROR_CTX_MODEM_INF_NOT_FOUND, + ERROR_CTX_INVALID_MODEMNAME, + ERROR_CTX_MODEM_RESPONSE_ERROR, + ERROR_CTX_MODEM_RESPONSE_TIMEOUT, + ERROR_CTX_MODEM_RESPONSE_NO_CARRIER, + ERROR_CTX_MODEM_RESPONSE_NO_DIALTONE, + ERROR_CTX_MODEM_RESPONSE_BUSY, + ERROR_CTX_MODEM_RESPONSE_VOICE, + ERROR_CTX_TD_ERROR, // = 7017 + ERROR_CTX_WINSTATION_NOT_FOUND = 7022, + ERROR_CTX_WINSTATION_ALREADY_EXISTS, + ERROR_CTX_WINSTATION_BUSY, + ERROR_CTX_BAD_VIDEO_MODE, // = 7025 + ERROR_CTX_GRAPHICS_INVALID = 7035, + ERROR_CTX_LOGON_DISABLED = 7037, + ERROR_CTX_NOT_CONSOLE, // = 7038 + ERROR_CTX_CLIENT_QUERY_TIMEOUT = 7040, + ERROR_CTX_CONSOLE_DISCONNECT, + ERROR_CTX_CONSOLE_CONNECT, // = 7042 + ERROR_CTX_SHADOW_DENIED = 7044, + ERROR_CTX_WINSTATION_ACCESS_DENIED, // = 7045 + ERROR_CTX_INVALID_WD = 7049, + ERROR_CTX_SHADOW_INVALID, + ERROR_CTX_SHADOW_DISABLED, + ERROR_CTX_CLIENT_LICENSE_IN_USE, + ERROR_CTX_CLIENT_LICENSE_NOT_SET, + ERROR_CTX_LICENSE_NOT_AVAILABLE, + ERROR_CTX_LICENSE_CLIENT_INVALID, + ERROR_CTX_LICENSE_EXPIRED, + ERROR_CTX_SHADOW_NOT_RUNNING, + ERROR_CTX_SHADOW_ENDED_BY_MODE_CHANGE, + ERROR_ACTIVATION_COUNT_EXCEEDED, // = 7059 + + FRS_ERR_INVALID_API_SEQUENCE = 8001, + FRS_ERR_STARTING_SERVICE, + FRS_ERR_STOPPING_SERVICE, + FRS_ERR_INTERNAL_API, + FRS_ERR_INTERNAL, + FRS_ERR_SERVICE_COMM, + FRS_ERR_INSUFFICIENT_PRIV, + FRS_ERR_AUTHENTICATION, + FRS_ERR_PARENT_INSUFFICIENT_PRIV, + FRS_ERR_PARENT_AUTHENTICATION, + FRS_ERR_CHILD_TO_PARENT_COMM, + FRS_ERR_PARENT_TO_CHILD_COMM, + FRS_ERR_SYSVOL_POPULATE, + FRS_ERR_SYSVOL_POPULATE_TIMEOUT, + FRS_ERR_SYSVOL_IS_BUSY, + FRS_ERR_SYSVOL_DEMOTE, + FRS_ERR_INVALID_SERVICE_PARAMETER, // = 8017 + ERROR_DS_NOT_INSTALLED = 8200, + ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY, + ERROR_DS_NO_ATTRIBUTE_OR_VALUE, + ERROR_DS_INVALID_ATTRIBUTE_SYNTAX, + ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED, + ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS, + ERROR_DS_BUSY, + ERROR_DS_UNAVAILABLE, + ERROR_DS_NO_RIDS_ALLOCATED, + ERROR_DS_NO_MORE_RIDS, + ERROR_DS_INCORRECT_ROLE_OWNER, + ERROR_DS_RIDMGR_INIT_ERROR, + ERROR_DS_OBJ_CLASS_VIOLATION, + ERROR_DS_CANT_ON_NON_LEAF, + ERROR_DS_CANT_ON_RDN, + ERROR_DS_CANT_MOD_OBJ_CLASS, + ERROR_DS_CROSS_DOM_MOVE_ERROR, + ERROR_DS_GC_NOT_AVAILABLE, + ERROR_SHARED_POLICY, + ERROR_POLICY_OBJECT_NOT_FOUND, + ERROR_POLICY_ONLY_IN_DS, + ERROR_PROMOTION_ACTIVE, + ERROR_NO_PROMOTION_ACTIVE, // = 8222 + ERROR_DS_OPERATIONS_ERROR = 8224, + ERROR_DS_PROTOCOL_ERROR, + ERROR_DS_TIMELIMIT_EXCEEDED, + ERROR_DS_SIZELIMIT_EXCEEDED, + ERROR_DS_ADMIN_LIMIT_EXCEEDED, + ERROR_DS_COMPARE_FALSE, + ERROR_DS_COMPARE_TRUE, + ERROR_DS_AUTH_METHOD_NOT_SUPPORTED, + ERROR_DS_STRONG_AUTH_REQUIRED, + ERROR_DS_INAPPROPRIATE_AUTH, + ERROR_DS_AUTH_UNKNOWN, + ERROR_DS_REFERRAL, + ERROR_DS_UNAVAILABLE_CRIT_EXTENSION, + ERROR_DS_CONFIDENTIALITY_REQUIRED, + ERROR_DS_INAPPROPRIATE_MATCHING, + ERROR_DS_CONSTRAINT_VIOLATION, + ERROR_DS_NO_SUCH_OBJECT, + ERROR_DS_ALIAS_PROBLEM, + ERROR_DS_INVALID_DN_SYNTAX, + ERROR_DS_IS_LEAF, + ERROR_DS_ALIAS_DEREF_PROBLEM, + ERROR_DS_UNWILLING_TO_PERFORM, + ERROR_DS_LOOP_DETECT, + ERROR_DS_NAMING_VIOLATION, + ERROR_DS_OBJECT_RESULTS_TOO_LARGE, + ERROR_DS_AFFECTS_MULTIPLE_DSAS, + ERROR_DS_SERVER_DOWN, + ERROR_DS_LOCAL_ERROR, + ERROR_DS_ENCODING_ERROR, + ERROR_DS_DECODING_ERROR, + ERROR_DS_FILTER_UNKNOWN, + ERROR_DS_PARAM_ERROR, + ERROR_DS_NOT_SUPPORTED, + ERROR_DS_NO_RESULTS_RETURNED, + ERROR_DS_CONTROL_NOT_FOUND, + ERROR_DS_CLIENT_LOOP, + ERROR_DS_REFERRAL_LIMIT_EXCEEDED, + ERROR_DS_SORT_CONTROL_MISSING, + ERROR_DS_OFFSET_RANGE_ERROR, // = 8262 + ERROR_DS_ROOT_MUST_BE_NC = 8301, + ERROR_DS_ADD_REPLICA_INHIBITED, + ERROR_DS_ATT_NOT_DEF_IN_SCHEMA, + ERROR_DS_MAX_OBJ_SIZE_EXCEEDED, + ERROR_DS_OBJ_STRING_NAME_EXISTS, + ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA, + ERROR_DS_RDN_DOESNT_MATCH_SCHEMA, + ERROR_DS_NO_REQUESTED_ATTS_FOUND, + ERROR_DS_USER_BUFFER_TO_SMALL, + ERROR_DS_ATT_IS_NOT_ON_OBJ, + ERROR_DS_ILLEGAL_MOD_OPERATION, + ERROR_DS_OBJ_TOO_LARGE, + ERROR_DS_BAD_INSTANCE_TYPE, + ERROR_DS_MASTERDSA_REQUIRED, + ERROR_DS_OBJECT_CLASS_REQUIRED, + ERROR_DS_MISSING_REQUIRED_ATT, + ERROR_DS_ATT_NOT_DEF_FOR_CLASS, + ERROR_DS_ATT_ALREADY_EXISTS, // = 8318 + ERROR_DS_CANT_ADD_ATT_VALUES = 8320, + ERROR_DS_SINGLE_VALUE_CONSTRAINT, + ERROR_DS_RANGE_CONSTRAINT, + ERROR_DS_ATT_VAL_ALREADY_EXISTS, + ERROR_DS_CANT_REM_MISSING_ATT, + ERROR_DS_CANT_REM_MISSING_ATT_VAL, + ERROR_DS_ROOT_CANT_BE_SUBREF, + ERROR_DS_NO_CHAINING, + ERROR_DS_NO_CHAINED_EVAL, + ERROR_DS_NO_PARENT_OBJECT, + ERROR_DS_PARENT_IS_AN_ALIAS, + ERROR_DS_CANT_MIX_MASTER_AND_REPS, + ERROR_DS_CHILDREN_EXIST, + ERROR_DS_OBJ_NOT_FOUND, + ERROR_DS_ALIASED_OBJ_MISSING, + ERROR_DS_BAD_NAME_SYNTAX, + ERROR_DS_ALIAS_POINTS_TO_ALIAS, + ERROR_DS_CANT_DEREF_ALIAS, + ERROR_DS_OUT_OF_SCOPE, + ERROR_DS_OBJECT_BEING_REMOVED, + ERROR_DS_CANT_DELETE_DSA_OBJ, + ERROR_DS_GENERIC_ERROR, + ERROR_DS_DSA_MUST_BE_INT_MASTER, + ERROR_DS_CLASS_NOT_DSA, + ERROR_DS_INSUFF_ACCESS_RIGHTS, + ERROR_DS_ILLEGAL_SUPERIOR, + ERROR_DS_ATTRIBUTE_OWNED_BY_SAM, + ERROR_DS_NAME_TOO_MANY_PARTS, + ERROR_DS_NAME_TOO_LONG, + ERROR_DS_NAME_VALUE_TOO_LONG, + ERROR_DS_NAME_UNPARSEABLE, + ERROR_DS_NAME_TYPE_UNKNOWN, + ERROR_DS_NOT_AN_OBJECT, + ERROR_DS_SEC_DESC_TOO_SHORT, + ERROR_DS_SEC_DESC_INVALID, + ERROR_DS_NO_DELETED_NAME, + ERROR_DS_SUBREF_MUST_HAVE_PARENT, + ERROR_DS_NCNAME_MUST_BE_NC, + ERROR_DS_CANT_ADD_SYSTEM_ONLY, + ERROR_DS_CLASS_MUST_BE_CONCRETE, + ERROR_DS_INVALID_DMD, + ERROR_DS_OBJ_GUID_EXISTS, + ERROR_DS_NOT_ON_BACKLINK, + ERROR_DS_NO_CROSSREF_FOR_NC, + ERROR_DS_SHUTTING_DOWN, + ERROR_DS_UNKNOWN_OPERATION, + ERROR_DS_INVALID_ROLE_OWNER, + ERROR_DS_COULDNT_CONTACT_FSMO, + ERROR_DS_CROSS_NC_DN_RENAME, + ERROR_DS_CANT_MOD_SYSTEM_ONLY, + ERROR_DS_REPLICATOR_ONLY, + ERROR_DS_OBJ_CLASS_NOT_DEFINED, + ERROR_DS_OBJ_CLASS_NOT_SUBCLASS, + ERROR_DS_NAME_REFERENCE_INVALID, + ERROR_DS_CROSS_REF_EXISTS, + ERROR_DS_CANT_DEL_MASTER_CROSSREF, + ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD, + ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX, + ERROR_DS_DUP_RDN, + ERROR_DS_DUP_OID, + ERROR_DS_DUP_MAPI_ID, + ERROR_DS_DUP_SCHEMA_ID_GUID, + ERROR_DS_DUP_LDAP_DISPLAY_NAME, + ERROR_DS_SEMANTIC_ATT_TEST, + ERROR_DS_SYNTAX_MISMATCH, + ERROR_DS_EXISTS_IN_MUST_HAVE, + ERROR_DS_EXISTS_IN_MAY_HAVE, + ERROR_DS_NONEXISTENT_MAY_HAVE, + ERROR_DS_NONEXISTENT_MUST_HAVE, + ERROR_DS_AUX_CLS_TEST_FAIL, + ERROR_DS_NONEXISTENT_POSS_SUP, + ERROR_DS_SUB_CLS_TEST_FAIL, + ERROR_DS_BAD_RDN_ATT_ID_SYNTAX, + ERROR_DS_EXISTS_IN_AUX_CLS, + ERROR_DS_EXISTS_IN_SUB_CLS, + ERROR_DS_EXISTS_IN_POSS_SUP, + ERROR_DS_RECALCSCHEMA_FAILED, + ERROR_DS_TREE_DELETE_NOT_FINISHED, + ERROR_DS_CANT_DELETE, + ERROR_DS_ATT_SCHEMA_REQ_ID, + ERROR_DS_BAD_ATT_SCHEMA_SYNTAX, + ERROR_DS_CANT_CACHE_ATT, + ERROR_DS_CANT_CACHE_CLASS, + ERROR_DS_CANT_REMOVE_ATT_CACHE, + ERROR_DS_CANT_REMOVE_CLASS_CACHE, + ERROR_DS_CANT_RETRIEVE_DN, + ERROR_DS_MISSING_SUPREF, + ERROR_DS_CANT_RETRIEVE_INSTANCE, + ERROR_DS_CODE_INCONSISTENCY, + ERROR_DS_DATABASE_ERROR, + ERROR_DS_GOVERNSID_MISSING, + ERROR_DS_MISSING_EXPECTED_ATT, + ERROR_DS_NCNAME_MISSING_CR_REF, + ERROR_DS_SECURITY_CHECKING_ERROR, + ERROR_DS_SCHEMA_NOT_LOADED, + ERROR_DS_SCHEMA_ALLOC_FAILED, + ERROR_DS_ATT_SCHEMA_REQ_SYNTAX, + ERROR_DS_GCVERIFY_ERROR, + ERROR_DS_DRA_SCHEMA_MISMATCH, + ERROR_DS_CANT_FIND_DSA_OBJ, + ERROR_DS_CANT_FIND_EXPECTED_NC, + ERROR_DS_CANT_FIND_NC_IN_CACHE, + ERROR_DS_CANT_RETRIEVE_CHILD, + ERROR_DS_SECURITY_ILLEGAL_MODIFY, + ERROR_DS_CANT_REPLACE_HIDDEN_REC, + ERROR_DS_BAD_HIERARCHY_FILE, + ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED, + ERROR_DS_CONFIG_PARAM_MISSING, + ERROR_DS_COUNTING_AB_INDICES_FAILED, + ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED, + ERROR_DS_INTERNAL_FAILURE, + ERROR_DS_UNKNOWN_ERROR, + ERROR_DS_ROOT_REQUIRES_CLASS_TOP, + ERROR_DS_REFUSING_FSMO_ROLES, + ERROR_DS_MISSING_FSMO_SETTINGS, + ERROR_DS_UNABLE_TO_SURRENDER_ROLES, + ERROR_DS_DRA_GENERIC, + ERROR_DS_DRA_INVALID_PARAMETER, + ERROR_DS_DRA_BUSY, + ERROR_DS_DRA_BAD_DN, + ERROR_DS_DRA_BAD_NC, + ERROR_DS_DRA_DN_EXISTS, + ERROR_DS_DRA_INTERNAL_ERROR, + ERROR_DS_DRA_INCONSISTENT_DIT, + ERROR_DS_DRA_CONNECTION_FAILED, + ERROR_DS_DRA_BAD_INSTANCE_TYPE, + ERROR_DS_DRA_OUT_OF_MEM, + ERROR_DS_DRA_MAIL_PROBLEM, + ERROR_DS_DRA_REF_ALREADY_EXISTS, + ERROR_DS_DRA_REF_NOT_FOUND, + ERROR_DS_DRA_OBJ_IS_REP_SOURCE, + ERROR_DS_DRA_DB_ERROR, + ERROR_DS_DRA_NO_REPLICA, + ERROR_DS_DRA_ACCESS_DENIED, + ERROR_DS_DRA_NOT_SUPPORTED, + ERROR_DS_DRA_RPC_CANCELLED, + ERROR_DS_DRA_SOURCE_DISABLED, + ERROR_DS_DRA_SINK_DISABLED, + ERROR_DS_DRA_NAME_COLLISION, + ERROR_DS_DRA_SOURCE_REINSTALLED, + ERROR_DS_DRA_MISSING_PARENT, + ERROR_DS_DRA_PREEMPTED, + ERROR_DS_DRA_ABANDON_SYNC, + ERROR_DS_DRA_SHUTDOWN, + ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET, + ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA, + ERROR_DS_DRA_EXTN_CONNECTION_FAILED, + ERROR_DS_INSTALL_SCHEMA_MISMATCH, + ERROR_DS_DUP_LINK_ID, + ERROR_DS_NAME_ERROR_RESOLVING, + ERROR_DS_NAME_ERROR_NOT_FOUND, + ERROR_DS_NAME_ERROR_NOT_UNIQUE, + ERROR_DS_NAME_ERROR_NO_MAPPING, + ERROR_DS_NAME_ERROR_DOMAIN_ONLY, + ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING, + ERROR_DS_CONSTRUCTED_ATT_MOD, + ERROR_DS_WRONG_OM_OBJ_CLASS, + ERROR_DS_DRA_REPL_PENDING, + ERROR_DS_DS_REQUIRED, + ERROR_DS_INVALID_LDAP_DISPLAY_NAME, + ERROR_DS_NON_BASE_SEARCH, + ERROR_DS_CANT_RETRIEVE_ATTS, + ERROR_DS_BACKLINK_WITHOUT_LINK, + ERROR_DS_EPOCH_MISMATCH, + ERROR_DS_SRC_NAME_MISMATCH, + ERROR_DS_SRC_AND_DST_NC_IDENTICAL, + ERROR_DS_DST_NC_MISMATCH, + ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC, + ERROR_DS_SRC_GUID_MISMATCH, + ERROR_DS_CANT_MOVE_DELETED_OBJECT, + ERROR_DS_PDC_OPERATION_IN_PROGRESS, + ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD, + ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION, + ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS, + ERROR_DS_NC_MUST_HAVE_NC_PARENT, + ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE, + ERROR_DS_DST_DOMAIN_NOT_NATIVE, + ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER, + ERROR_DS_CANT_MOVE_ACCOUNT_GROUP, + ERROR_DS_CANT_MOVE_RESOURCE_GROUP, + ERROR_DS_INVALID_SEARCH_FLAG, + ERROR_DS_NO_TREE_DELETE_ABOVE_NC, + ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE, + ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE, + ERROR_DS_SAM_INIT_FAILURE, + ERROR_DS_SENSITIVE_GROUP_VIOLATION, + ERROR_DS_CANT_MOD_PRIMARYGROUPID, + ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD, + ERROR_DS_NONSAFE_SCHEMA_CHANGE, + ERROR_DS_SCHEMA_UPDATE_DISALLOWED, + ERROR_DS_CANT_CREATE_UNDER_SCHEMA, + ERROR_DS_INSTALL_NO_SRC_SCH_VERSION, + ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE, + ERROR_DS_INVALID_GROUP_TYPE, + ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN, + ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN, + ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER, + ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER, + ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER, + ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER, + ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER, + ERROR_DS_HAVE_PRIMARY_MEMBERS, + ERROR_DS_STRING_SD_CONVERSION_FAILED, + ERROR_DS_NAMING_MASTER_GC, + ERROR_DS_LOOKUP_FAILURE, + ERROR_DS_COULDNT_UPDATE_SPNS, + ERROR_DS_CANT_RETRIEVE_SD, + ERROR_DS_KEY_NOT_UNIQUE, + ERROR_DS_WRONG_LINKED_ATT_SYNTAX, + ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD, + ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY, + ERROR_DS_CANT_START, + ERROR_DS_INIT_FAILURE, + ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION, + ERROR_DS_SOURCE_DOMAIN_IN_FOREST, + ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST, + ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED, + ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN, + ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER, + ERROR_DS_SRC_SID_EXISTS_IN_FOREST, + ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH, + ERROR_SAM_INIT_FAILURE, + ERROR_DS_DRA_SCHEMA_INFO_SHIP, + ERROR_DS_DRA_SCHEMA_CONFLICT, + ERROR_DS_DRA_EARLIER_SCHEMA_CONLICT, + ERROR_DS_DRA_OBJ_NC_MISMATCH, + ERROR_DS_NC_STILL_HAS_DSAS, + ERROR_DS_GC_REQUIRED, + ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY, + ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS, + ERROR_DS_CANT_ADD_TO_GC, + ERROR_DS_NO_CHECKPOINT_WITH_PDC, + ERROR_DS_SOURCE_AUDITING_NOT_ENABLED, + ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC, + ERROR_DS_INVALID_NAME_FOR_SPN, + ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS, + ERROR_DS_UNICODEPWD_NOT_IN_QUOTES, + ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED, + ERROR_DS_MUST_BE_RUN_ON_DST_DC, + ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER, + ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ, + ERROR_DS_INIT_FAILURE_CONSOLE, + ERROR_DS_SAM_INIT_FAILURE_CONSOLE, + ERROR_DS_FOREST_VERSION_TOO_HIGH, + ERROR_DS_DOMAIN_VERSION_TOO_HIGH, + ERROR_DS_FOREST_VERSION_TOO_LOW, + ERROR_DS_DOMAIN_VERSION_TOO_LOW, + ERROR_DS_INCOMPATIBLE_VERSION, + ERROR_DS_LOW_DSA_VERSION, + ERROR_DS_NO_BEHAVIOR_VERSION_IN_MIXEDDOMAIN, + ERROR_DS_NOT_SUPPORTED_SORT_ORDER, + ERROR_DS_NAME_NOT_UNIQUE, + ERROR_DS_MACHINE_ACCOUNT_CREATED_PRENT4, + ERROR_DS_OUT_OF_VERSION_STORE, + ERROR_DS_INCOMPATIBLE_CONTROLS_USED, + ERROR_DS_NO_REF_DOMAIN, + ERROR_DS_RESERVED_LINK_ID, + ERROR_DS_LINK_ID_NOT_AVAILABLE, + ERROR_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER, + ERROR_DS_MODIFYDN_DISALLOWED_BY_INSTANCE_TYPE, + ERROR_DS_NO_OBJECT_MOVE_IN_SCHEMA_NC, + ERROR_DS_MODIFYDN_DISALLOWED_BY_FLAG, + ERROR_DS_MODIFYDN_WRONG_GRANDPARENT, + ERROR_DS_NAME_ERROR_TRUST_REFERRAL, + ERROR_NOT_SUPPORTED_ON_STANDARD_SERVER, + ERROR_DS_CANT_ACCESS_REMOTE_PART_OF_AD, + ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE_V2, + ERROR_DS_THREAD_LIMIT_EXCEEDED, + ERROR_DS_NOT_CLOSEST, + ERROR_DS_CANT_DERIVE_SPN_WITHOUT_SERVER_REF, + ERROR_DS_SINGLE_USER_MODE_FAILED, + ERROR_DS_NTDSCRIPT_SYNTAX_ERROR, + ERROR_DS_NTDSCRIPT_PROCESS_ERROR, + ERROR_DS_DIFFERENT_REPL_EPOCHS, + ERROR_DS_DRS_EXTENSIONS_CHANGED, + ERROR_DS_REPLICA_SET_CHANGE_NOT_ALLOWED_ON_DISABLED_CR, + ERROR_DS_NO_MSDS_INTID, + ERROR_DS_DUP_MSDS_INTID, + ERROR_DS_EXISTS_IN_RDNATTID, + ERROR_DS_AUTHORIZATION_FAILED, + ERROR_DS_INVALID_SCRIPT, + ERROR_DS_REMOTE_CROSSREF_OP_FAILED, + ERROR_DS_CROSS_REF_BUSY, + ERROR_DS_CANT_DERIVE_SPN_FOR_DELETED_DOMAIN, + ERROR_DS_CANT_DEMOTE_WITH_WRITEABLE_NC, + ERROR_DS_DUPLICATE_ID_FOUND, + ERROR_DS_INSUFFICIENT_ATTR_TO_CREATE_OBJECT, + ERROR_DS_GROUP_CONVERSION_ERROR, + ERROR_DS_CANT_MOVE_APP_BASIC_GROUP, + ERROR_DS_CANT_MOVE_APP_QUERY_GROUP, + ERROR_DS_ROLE_NOT_VERIFIED, + ERROR_DS_WKO_CONTAINER_CANNOT_BE_SPECIAL, + ERROR_DS_DOMAIN_RENAME_IN_PROGRESS, + ERROR_DS_EXISTING_AD_CHILD_NC, // = 8613 + DNS_ERROR_RCODE_FORMAT_ERROR = 9001, + DNS_ERROR_RCODE_SERVER_FAILURE, + DNS_ERROR_RCODE_NAME_ERROR, + DNS_ERROR_RCODE_NOT_IMPLEMENTED, + DNS_ERROR_RCODE_REFUSED, + DNS_ERROR_RCODE_YXDOMAIN, + DNS_ERROR_RCODE_YXRRSET, + DNS_ERROR_RCODE_NXRRSET, + DNS_ERROR_RCODE_NOTAUTH, + DNS_ERROR_RCODE_NOTZONE, // = 9010 + DNS_ERROR_RCODE_BADSIG = 9016, + DNS_ERROR_RCODE_BADKEY, + DNS_ERROR_RCODE_BADTIME, // = 9018 + DNS_INFO_NO_RECORDS = 9501, + DNS_ERROR_BAD_PACKET, + DNS_ERROR_NO_PACKET, + DNS_ERROR_RCODE, + DNS_ERROR_UNSECURE_PACKET, // = 9505 + DNS_ERROR_INVALID_TYPE = 9551, + DNS_ERROR_INVALID_IP_ADDRESS, + DNS_ERROR_INVALID_PROPERTY, + DNS_ERROR_TRY_AGAIN_LATER, + DNS_ERROR_NOT_UNIQUE, + DNS_ERROR_NON_RFC_NAME, + DNS_STATUS_FQDN, + DNS_STATUS_DOTTED_NAME, + DNS_STATUS_SINGLE_PART_NAME, + DNS_ERROR_INVALID_NAME_CHAR, + DNS_ERROR_NUMERIC_NAME, + DNS_ERROR_NOT_ALLOWED_ON_ROOT_SERVER, + DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION, + DNS_ERROR_CANNOT_FIND_ROOT_HINTS, + DNS_ERROR_INCONSISTENT_ROOT_HINTS, // = 9565 + DNS_ERROR_ZONE_DOES_NOT_EXIST = 9601, + DNS_ERROR_NO_ZONE_INFO, + DNS_ERROR_INVALID_ZONE_OPERATION, + DNS_ERROR_ZONE_CONFIGURATION_ERROR, + DNS_ERROR_ZONE_HAS_NO_SOA_RECORD, + DNS_ERROR_ZONE_HAS_NO_NS_RECORDS, + DNS_ERROR_ZONE_LOCKED, + DNS_ERROR_ZONE_CREATION_FAILED, + DNS_ERROR_ZONE_ALREADY_EXISTS, + DNS_ERROR_AUTOZONE_ALREADY_EXISTS, + DNS_ERROR_INVALID_ZONE_TYPE, + DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP, + DNS_ERROR_ZONE_NOT_SECONDARY, + DNS_ERROR_NEED_SECONDARY_ADDRESSES, + DNS_ERROR_WINS_INIT_FAILED, + DNS_ERROR_NEED_WINS_SERVERS, + DNS_ERROR_NBSTAT_INIT_FAILED, + DNS_ERROR_SOA_DELETE_INVALID, + DNS_ERROR_FORWARDER_ALREADY_EXISTS, + DNS_ERROR_ZONE_REQUIRES_MASTER_IP, + DNS_ERROR_ZONE_IS_SHUTDOWN, // = 9621 + DNS_ERROR_PRIMARY_REQUIRES_DATAFILE = 9651, + DNS_ERROR_INVALID_DATAFILE_NAME, + DNS_ERROR_DATAFILE_OPEN_FAILURE, + DNS_ERROR_FILE_WRITEBACK_FAILED, + DNS_ERROR_DATAFILE_PARSING, // = 9655 + DNS_ERROR_RECORD_DOES_NOT_EXIST = 9701, + DNS_ERROR_RECORD_FORMAT, + DNS_ERROR_NODE_CREATION_FAILED, + DNS_ERROR_UNKNOWN_RECORD_TYPE, + DNS_ERROR_RECORD_TIMED_OUT, + DNS_ERROR_NAME_NOT_IN_ZONE, + DNS_ERROR_CNAME_LOOP, + DNS_ERROR_NODE_IS_CNAME, + DNS_ERROR_CNAME_COLLISION, + DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT, + DNS_ERROR_RECORD_ALREADY_EXISTS, + DNS_ERROR_SECONDARY_DATA, + DNS_ERROR_NO_CREATE_CACHE_DATA, + DNS_ERROR_NAME_DOES_NOT_EXIST, + DNS_WARNING_PTR_CREATE_FAILED, + DNS_WARNING_DOMAIN_UNDELETED, + DNS_ERROR_DS_UNAVAILABLE, + DNS_ERROR_DS_ZONE_ALREADY_EXISTS, + DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE, // = 9719 + DNS_INFO_AXFR_COMPLETE = 9751, + DNS_ERROR_AXFR, + DNS_INFO_ADDED_LOCAL_WINS, // = 9753 + DNS_STATUS_CONTINUE_NEEDED = 9801, + DNS_ERROR_NO_TCPIP = 9851, + DNS_ERROR_NO_DNS_SERVERS, // = 9852 + DNS_ERROR_DP_DOES_NOT_EXIST = 9901, + DNS_ERROR_DP_ALREADY_EXISTS, + DNS_ERROR_DP_NOT_ENLISTED, + DNS_ERROR_DP_ALREADY_ENLISTED, + DNS_ERROR_DP_NOT_AVAILABLE, // = 9905 + +/+ already in winsock2.d defined! + + WSABASEERR = 10000, + WSAEINTR = 10004, + WSAEBADF = 10009, + WSAEACCES = 10013, + WSAEFAULT, // = 10014 + WSAEINVAL = 10022, + WSAEMFILE = 10024, + WSAEWOULDBLOCK = 10035, + WSAEINPROGRESS, + WSAEALREADY, + WSAENOTSOCK, + WSAEDESTADDRREQ, + WSAEMSGSIZE, + WSAEPROTOTYPE, + WSAENOPROTOOPT, + WSAEPROTONOSUPPORT, + WSAESOCKTNOSUPPORT, + WSAEOPNOTSUPP, + WSAEPFNOSUPPORT, + WSAEAFNOSUPPORT, + WSAEADDRINUSE, + WSAEADDRNOTAVAIL, + WSAENETDOWN, + WSAENETUNREACH, + WSAENETRESET, + WSAECONNABORTED, + WSAECONNRESET, + WSAENOBUFS, + WSAEISCONN, + WSAENOTCONN, + WSAESHUTDOWN, + WSAETOOMANYREFS, + WSAETIMEDOUT, + WSAECONNREFUSED, + WSAELOOP, + WSAENAMETOOLONG, + WSAEHOSTDOWN, + WSAEHOSTUNREACH, + WSAENOTEMPTY, + WSAEPROCLIM, + WSAEUSERS, + WSAEDQUOT, + WSAESTALE, + WSAEREMOTE, // = 10071 + WSASYSNOTREADY = 10091, + WSAVERNOTSUPPORTED, + WSANOTINITIALISED, // = 10093 + WSAEDISCON = 10101, + WSAENOMORE, + WSAECANCELLED, + WSAEINVALIDPROCTABLE, + WSAEINVALIDPROVIDER, + WSAEPROVIDERFAILEDINIT, + WSASYSCALLFAILURE, + WSASERVICE_NOT_FOUND, + WSATYPE_NOT_FOUND, + WSA_E_NO_MORE, + WSA_E_CANCELLED, + WSAEREFUSED, // = 10112 + WSAHOST_NOT_FOUND = 11001, + WSATRY_AGAIN, + WSANO_RECOVERY, + WSANO_DATA, + WSA_QOS_RECEIVERS, + WSA_QOS_SENDERS, + WSA_QOS_NO_SENDERS, + WSA_QOS_NO_RECEIVERS, + WSA_QOS_REQUEST_CONFIRMED, + WSA_QOS_ADMISSION_FAILURE, + WSA_QOS_POLICY_FAILURE, + WSA_QOS_BAD_STYLE, + WSA_QOS_BAD_OBJECT, + WSA_QOS_TRAFFIC_CTRL_ERROR, + WSA_QOS_GENERIC_ERROR, + WSA_QOS_ESERVICETYPE, + WSA_QOS_EFLOWSPEC, + WSA_QOS_EPROVSPECBUF, + WSA_QOS_EFILTERSTYLE, + WSA_QOS_EFILTERTYPE, + WSA_QOS_EFILTERCOUNT, + WSA_QOS_EOBJLENGTH, + WSA_QOS_EFLOWCOUNT, + WSA_QOS_EUNKNOWNPSOBJ, + WSA_QOS_EPOLICYOBJ, + WSA_QOS_EFLOWDESC, + WSA_QOS_EPSFLOWSPEC, + WSA_QOS_EPSFILTERSPEC, + WSA_QOS_ESDMODEOBJ, + WSA_QOS_ESHAPERATEOBJ, + WSA_QOS_RESERVED_PETYPE, // = 11031 + ++/ + + ERROR_IPSEC_QM_POLICY_EXISTS = 13000, + ERROR_IPSEC_QM_POLICY_NOT_FOUND, + ERROR_IPSEC_QM_POLICY_IN_USE, + ERROR_IPSEC_MM_POLICY_EXISTS, + ERROR_IPSEC_MM_POLICY_NOT_FOUND, + ERROR_IPSEC_MM_POLICY_IN_USE, + ERROR_IPSEC_MM_FILTER_EXISTS, + ERROR_IPSEC_MM_FILTER_NOT_FOUND, + ERROR_IPSEC_TRANSPORT_FILTER_EXISTS, + ERROR_IPSEC_TRANSPORT_FILTER_NOT_FOUND, + ERROR_IPSEC_MM_AUTH_EXISTS, + ERROR_IPSEC_MM_AUTH_NOT_FOUND, + ERROR_IPSEC_MM_AUTH_IN_USE, + ERROR_IPSEC_DEFAULT_MM_POLICY_NOT_FOUND, + ERROR_IPSEC_DEFAULT_MM_AUTH_NOT_FOUND, + ERROR_IPSEC_DEFAULT_QM_POLICY_NOT_FOUND, + ERROR_IPSEC_TUNNEL_FILTER_EXISTS, + ERROR_IPSEC_TUNNEL_FILTER_NOT_FOUND, + ERROR_IPSEC_MM_FILTER_PENDING_DELETION, + ERROR_IPSEC_TRANSPORT_FILTER_PENDING_DELETION, + ERROR_IPSEC_TUNNEL_FILTER_PENDING_DELETION, + ERROR_IPSEC_MM_POLICY_PENDING_DELETION, + ERROR_IPSEC_MM_AUTH_PENDING_DELETION, + ERROR_IPSEC_QM_POLICY_PENDING_DELETION, + WARNING_IPSEC_MM_POLICY_PRUNED, + WARNING_IPSEC_QM_POLICY_PRUNED, // = 13025 + ERROR_IPSEC_IKE_AUTH_FAIL = 13801, + ERROR_IPSEC_IKE_ATTRIB_FAIL, + ERROR_IPSEC_IKE_NEGOTIATION_PENDING, + ERROR_IPSEC_IKE_GENERAL_PROCESSING_ERROR, + ERROR_IPSEC_IKE_TIMED_OUT, + ERROR_IPSEC_IKE_NO_CERT, + ERROR_IPSEC_IKE_SA_DELETED, + ERROR_IPSEC_IKE_SA_REAPED, + ERROR_IPSEC_IKE_MM_ACQUIRE_DROP, + ERROR_IPSEC_IKE_QM_ACQUIRE_DROP, + ERROR_IPSEC_IKE_QUEUE_DROP_MM, + ERROR_IPSEC_IKE_QUEUE_DROP_NO_MM, + ERROR_IPSEC_IKE_DROP_NO_RESPONSE, + ERROR_IPSEC_IKE_MM_DELAY_DROP, + ERROR_IPSEC_IKE_QM_DELAY_DROP, + ERROR_IPSEC_IKE_ERROR, + ERROR_IPSEC_IKE_CRL_FAILED, + ERROR_IPSEC_IKE_INVALID_KEY_USAGE, + ERROR_IPSEC_IKE_INVALID_CERT_TYPE, + ERROR_IPSEC_IKE_NO_PRIVATE_KEY, // = 13820 + ERROR_IPSEC_IKE_DH_FAIL = 13822, + ERROR_IPSEC_IKE_INVALID_HEADER = 13824, + ERROR_IPSEC_IKE_NO_POLICY, + ERROR_IPSEC_IKE_INVALID_SIGNATURE, + ERROR_IPSEC_IKE_KERBEROS_ERROR, + ERROR_IPSEC_IKE_NO_PUBLIC_KEY, + ERROR_IPSEC_IKE_PROCESS_ERR, + ERROR_IPSEC_IKE_PROCESS_ERR_SA, + ERROR_IPSEC_IKE_PROCESS_ERR_PROP, + ERROR_IPSEC_IKE_PROCESS_ERR_TRANS, + ERROR_IPSEC_IKE_PROCESS_ERR_KE, + ERROR_IPSEC_IKE_PROCESS_ERR_ID, + ERROR_IPSEC_IKE_PROCESS_ERR_CERT, + ERROR_IPSEC_IKE_PROCESS_ERR_CERT_REQ, + ERROR_IPSEC_IKE_PROCESS_ERR_HASH, + ERROR_IPSEC_IKE_PROCESS_ERR_SIG, + ERROR_IPSEC_IKE_PROCESS_ERR_NONCE, + ERROR_IPSEC_IKE_PROCESS_ERR_NOTIFY, + ERROR_IPSEC_IKE_PROCESS_ERR_DELETE, + ERROR_IPSEC_IKE_PROCESS_ERR_VENDOR, + ERROR_IPSEC_IKE_INVALID_PAYLOAD, + ERROR_IPSEC_IKE_LOAD_SOFT_SA, + ERROR_IPSEC_IKE_SOFT_SA_TORN_DOWN, + ERROR_IPSEC_IKE_INVALID_COOKIE, + ERROR_IPSEC_IKE_NO_PEER_CERT, + ERROR_IPSEC_IKE_PEER_CRL_FAILED, + ERROR_IPSEC_IKE_POLICY_CHANGE, + ERROR_IPSEC_IKE_NO_MM_POLICY, + ERROR_IPSEC_IKE_NOTCBPRIV, + ERROR_IPSEC_IKE_SECLOADFAIL, + ERROR_IPSEC_IKE_FAILSSPINIT, + ERROR_IPSEC_IKE_FAILQUERYSSP, + ERROR_IPSEC_IKE_SRVACQFAIL, + ERROR_IPSEC_IKE_SRVQUERYCRED, + ERROR_IPSEC_IKE_GETSPIFAIL, + ERROR_IPSEC_IKE_INVALID_FILTER, + ERROR_IPSEC_IKE_OUT_OF_MEMORY, + ERROR_IPSEC_IKE_ADD_UPDATE_KEY_FAILED, + ERROR_IPSEC_IKE_INVALID_POLICY, + ERROR_IPSEC_IKE_UNKNOWN_DOI, + ERROR_IPSEC_IKE_INVALID_SITUATION, + ERROR_IPSEC_IKE_DH_FAILURE, + ERROR_IPSEC_IKE_INVALID_GROUP, + ERROR_IPSEC_IKE_ENCRYPT, + ERROR_IPSEC_IKE_DECRYPT, + ERROR_IPSEC_IKE_POLICY_MATCH, + ERROR_IPSEC_IKE_UNSUPPORTED_ID, + ERROR_IPSEC_IKE_INVALID_HASH, + ERROR_IPSEC_IKE_INVALID_HASH_ALG, + ERROR_IPSEC_IKE_INVALID_HASH_SIZE, + ERROR_IPSEC_IKE_INVALID_ENCRYPT_ALG, + ERROR_IPSEC_IKE_INVALID_AUTH_ALG, + ERROR_IPSEC_IKE_INVALID_SIG, + ERROR_IPSEC_IKE_LOAD_FAILED, + ERROR_IPSEC_IKE_RPC_DELETE, + ERROR_IPSEC_IKE_BENIGN_REINIT, + ERROR_IPSEC_IKE_INVALID_RESPONDER_LIFETIME_NOTIFY, // = 13879 + ERROR_IPSEC_IKE_INVALID_CERT_KEYLEN = 13881, + ERROR_IPSEC_IKE_MM_LIMIT, + ERROR_IPSEC_IKE_NEGOTIATION_DISABLED, + ERROR_IPSEC_IKE_NEG_STATUS_END, + ERROR_SXS_SECTION_NOT_FOUND, + ERROR_SXS_CANT_GEN_ACTCTX, + ERROR_SXS_INVALID_ACTCTXDATA_FORMAT, + ERROR_SXS_ASSEMBLY_NOT_FOUND, + ERROR_SXS_MANIFEST_FORMAT_ERROR, + ERROR_SXS_MANIFEST_PARSE_ERROR, + ERROR_SXS_ACTIVATION_CONTEXT_DISABLED, + ERROR_SXS_KEY_NOT_FOUND, + ERROR_SXS_VERSION_CONFLICT, + ERROR_SXS_WRONG_SECTION_TYPE, + ERROR_SXS_THREAD_QUERIES_DISABLED, + ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET, + ERROR_SXS_UNKNOWN_ENCODING_GROUP, + ERROR_SXS_UNKNOWN_ENCODING, + ERROR_SXS_INVALID_XML_NAMESPACE_URI, + ERROR_SXS_ROOT_MANIFEST_DEPENDENCY_NOT_INSTALLED, + ERROR_SXS_LEAF_MANIFEST_DEPENDENCY_NOT_INSTALLED, + ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE, + ERROR_SXS_MANIFEST_MISSING_REQUIRED_DEFAULT_NAMESPACE, + ERROR_SXS_MANIFEST_INVALID_REQUIRED_DEFAULT_NAMESPACE, + ERROR_SXS_PRIVATE_MANIFEST_CROSS_PATH_WITH_REPARSE_POINT, + ERROR_SXS_DUPLICATE_DLL_NAME, + ERROR_SXS_DUPLICATE_WINDOWCLASS_NAME, + ERROR_SXS_DUPLICATE_CLSID, + ERROR_SXS_DUPLICATE_IID, + ERROR_SXS_DUPLICATE_TLBID, + ERROR_SXS_DUPLICATE_PROGID, + ERROR_SXS_DUPLICATE_ASSEMBLY_NAME, + ERROR_SXS_FILE_HASH_MISMATCH, + ERROR_SXS_POLICY_PARSE_ERROR, + ERROR_SXS_XML_E_MISSINGQUOTE, + ERROR_SXS_XML_E_COMMENTSYNTAX, + ERROR_SXS_XML_E_BADSTARTNAMECHAR, + ERROR_SXS_XML_E_BADNAMECHAR, + ERROR_SXS_XML_E_BADCHARINSTRING, + ERROR_SXS_XML_E_XMLDECLSYNTAX, + ERROR_SXS_XML_E_BADCHARDATA, + ERROR_SXS_XML_E_MISSINGWHITESPACE, + ERROR_SXS_XML_E_EXPECTINGTAGEND, + ERROR_SXS_XML_E_MISSINGSEMICOLON, + ERROR_SXS_XML_E_UNBALANCEDPAREN, + ERROR_SXS_XML_E_INTERNALERROR, + ERROR_SXS_XML_E_UNEXPECTED_WHITESPACE, + ERROR_SXS_XML_E_INCOMPLETE_ENCODING, + ERROR_SXS_XML_E_MISSING_PAREN, + ERROR_SXS_XML_E_EXPECTINGCLOSEQUOTE, + ERROR_SXS_XML_E_MULTIPLE_COLONS, + ERROR_SXS_XML_E_INVALID_DECIMAL, + ERROR_SXS_XML_E_INVALID_HEXIDECIMAL, + ERROR_SXS_XML_E_INVALID_UNICODE, + ERROR_SXS_XML_E_WHITESPACEORQUESTIONMARK, + ERROR_SXS_XML_E_UNEXPECTEDENDTAG, + ERROR_SXS_XML_E_UNCLOSEDTAG, + ERROR_SXS_XML_E_DUPLICATEATTRIBUTE, + ERROR_SXS_XML_E_MULTIPLEROOTS, + ERROR_SXS_XML_E_INVALIDATROOTLEVEL, + ERROR_SXS_XML_E_BADXMLDECL, + ERROR_SXS_XML_E_MISSINGROOT, + ERROR_SXS_XML_E_UNEXPECTEDEOF, + ERROR_SXS_XML_E_BADPEREFINSUBSET, + ERROR_SXS_XML_E_UNCLOSEDSTARTTAG, + ERROR_SXS_XML_E_UNCLOSEDENDTAG, + ERROR_SXS_XML_E_UNCLOSEDSTRING, + ERROR_SXS_XML_E_UNCLOSEDCOMMENT, + ERROR_SXS_XML_E_UNCLOSEDDECL, + ERROR_SXS_XML_E_UNCLOSEDCDATA, + ERROR_SXS_XML_E_RESERVEDNAMESPACE, + ERROR_SXS_XML_E_INVALIDENCODING, + ERROR_SXS_XML_E_INVALIDSWITCH, + ERROR_SXS_XML_E_BADXMLCASE, + ERROR_SXS_XML_E_INVALID_STANDALONE, + ERROR_SXS_XML_E_UNEXPECTED_STANDALONE, + ERROR_SXS_XML_E_INVALID_VERSION, + ERROR_SXS_XML_E_MISSINGEQUALS, + ERROR_SXS_PROTECTION_RECOVERY_FAILED, + ERROR_SXS_PROTECTION_PUBLIC_KEY_TOO_SHORT, + ERROR_SXS_PROTECTION_CATALOG_NOT_VALID, + ERROR_SXS_UNTRANSLATABLE_HRESULT, + ERROR_SXS_PROTECTION_CATALOG_FILE_MISSING, + ERROR_SXS_MISSING_ASSEMBLY_IDENTITY_ATTRIBUTE, + ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME // = 14080 +} + +enum : HRESULT { + S_OK = 0x00000000, + S_FALSE = 0x00000001, + + NOERROR = 0x00000000, + + E_PENDING = 0x8000000A, + E_NOTIMPL = 0x80004001, + E_NOINTERFACE = 0x80004002, + E_POINTER = 0x80004003, + E_ABORT = 0x80004004, + E_FAIL = 0x80004005, + E_ACCESSDENIED = 0x80070005, + E_HANDLE = 0x80070006, + E_OUTOFMEMORY = 0x8007000E, + E_INVALIDARG = 0x80070057, + E_UNEXPECTED = 0x8000FFFF, + + CO_E_INIT_TLS = 0x80004006, + CO_E_INIT_SHARED_ALLOCATOR = 0x80004007, + CO_E_INIT_MEMORY_ALLOCATOR = 0x80004008, + CO_E_INIT_CLASS_CACHE = 0x80004009, + CO_E_INIT_RPC_CHANNEL = 0x8000400A, + CO_E_INIT_TLS_SET_CHANNEL_CONTROL = 0x8000400B, + CO_E_INIT_TLS_CHANNEL_CONTROL = 0x8000400C, + CO_E_INIT_UNACCEPTED_USER_ALLOCATOR = 0x8000400D, + CO_E_INIT_SCM_MUTEX_EXISTS = 0x8000400E, + CO_E_INIT_SCM_FILE_MAPPING_EXISTS = 0x8000400F, + CO_E_INIT_SCM_MAP_VIEW_OF_FILE = 0x80004010, + CO_E_INIT_SCM_EXEC_FAILURE = 0x80004011, + CO_E_INIT_ONLY_SINGLE_THREADED = 0x80004012, + + RPC_E_CALL_REJECTED = 0x80010001, + RPC_E_CALL_CANCELED = 0x80010002, + RPC_E_CANTPOST_INSENDCALL = 0x80010003, + RPC_E_CANTCALLOUT_INASYNCCALL = 0x80010004, + RPC_E_CANTCALLOUT_INEXTERNALCALL = 0x80010005, + RPC_E_CONNECTION_TERMINATED = 0x80010006, + RPC_E_SERVER_DIED = 0x80010007, + RPC_E_CLIENT_DIED = 0x80010008, + RPC_E_INVALID_DATAPACKET = 0x80010009, + RPC_E_CANTTRANSMIT_CALL = 0x8001000A, + RPC_E_CLIENT_CANTMARSHAL_DATA = 0x8001000B, + RPC_E_CLIENT_CANTUNMARSHAL_DATA = 0x8001000C, + RPC_E_SERVER_CANTMARSHAL_DATA = 0x8001000D, + RPC_E_SERVER_CANTUNMARSHAL_DATA = 0x8001000E, + RPC_E_INVALID_DATA = 0x8001000F, + RPC_E_INVALID_PARAMETER = 0x80010010, + RPC_E_CANTCALLOUT_AGAIN = 0x80010011, + RPC_E_SERVER_DIED_DNE = 0x80010012, + RPC_E_SYS_CALL_FAILED = 0x80010100, + RPC_E_OUT_OF_RESOURCES = 0x80010101, + RPC_E_ATTEMPTED_MULTITHREAD = 0x80010102, + RPC_E_NOT_REGISTERED = 0x80010103, + RPC_E_FAULT = 0x80010104, + RPC_E_SERVERFAULT = 0x80010105, + RPC_E_CHANGED_MODE = 0x80010106, + RPC_E_INVALIDMETHOD = 0x80010107, + RPC_E_DISCONNECTED = 0x80010108, + RPC_E_RETRY = 0x80010109, + RPC_E_SERVERCALL_RETRYLATER = 0x8001010A, + RPC_E_SERVERCALL_REJECTED = 0x8001010B, + RPC_E_INVALID_CALLDATA = 0x8001010C, + RPC_E_CANTCALLOUT_ININPUTSYNCCALL = 0x8001010D, + RPC_E_WRONG_THREAD = 0x8001010E, + RPC_E_THREAD_NOT_INIT = 0x8001010F, + RPC_E_UNEXPECTED = 0x8001FFFF, + + DISP_E_UNKNOWNINTERFACE = 0x80020001, + DISP_E_MEMBERNOTFOUND = 0x80020003, + DISP_E_PARAMNOTFOUND = 0x80020004, + DISP_E_TYPEMISMATCH = 0x80020005, + DISP_E_UNKNOWNNAME = 0x80020006, + DISP_E_NONAMEDARGS = 0x80020007, + DISP_E_BADVARTYPE = 0x80020008, + DISP_E_EXCEPTION = 0x80020009, + DISP_E_OVERFLOW = 0x8002000A, + DISP_E_BADINDEX = 0x8002000B, + DISP_E_UNKNOWNLCID = 0x8002000C, + DISP_E_ARRAYISLOCKED = 0x8002000D, + DISP_E_BADPARAMCOUNT = 0x8002000E, + DISP_E_PARAMNOTOPTIONAL = 0x8002000F, + DISP_E_BADCALLEE = 0x80020010, + DISP_E_NOTACOLLECTION = 0x80020011, + DISP_E_DIVBYZERO = 0x80020012, + + TYPE_E_BUFFERTOOSMALL = 0x80028016, + TYPE_E_INVDATAREAD = 0x80028018, + TYPE_E_UNSUPFORMAT = 0x80028019, + TYPE_E_REGISTRYACCESS = 0x8002801C, + TYPE_E_LIBNOTREGISTERED = 0x8002801D, + TYPE_E_UNDEFINEDTYPE = 0x80028027, + TYPE_E_QUALIFIEDNAMEDISALLOWED = 0x80028028, + TYPE_E_INVALIDSTATE = 0x80028029, + TYPE_E_WRONGTYPEKIND = 0x8002802A, + TYPE_E_ELEMENTNOTFOUND = 0x8002802B, + TYPE_E_AMBIGUOUSNAME = 0x8002802C, + TYPE_E_NAMECONFLICT = 0x8002802D, + TYPE_E_UNKNOWNLCID = 0x8002802E, + TYPE_E_DLLFUNCTIONNOTFOUND = 0x8002802F, + TYPE_E_BADMODULEKIND = 0x800288BD, + TYPE_E_SIZETOOBIG = 0x800288C5, + TYPE_E_DUPLICATEID = 0x800288C6, + TYPE_E_INVALIDID = 0x800288CF, + TYPE_E_TYPEMISMATCH = 0x80028CA0, + TYPE_E_OUTOFBOUNDS = 0x80028CA1, + TYPE_E_IOERROR = 0x80028CA2, + TYPE_E_CANTCREATETMPFILE = 0x80028CA3, + TYPE_E_CANTLOADLIBRARY = 0x80029C4A, + TYPE_E_INCONSISTENTPROPFUNCS = 0x80029C83, + TYPE_E_CIRCULARTYPE = 0x80029C84, + + STG_E_INVALIDFUNCTION = 0x80030001, + STG_E_FILENOTFOUND = 0x80030002, + STG_E_PATHNOTFOUND = 0x80030003, + STG_E_TOOMANYOPENFILES = 0x80030004, + STG_E_ACCESSDENIED = 0x80030005, + STG_E_INVALIDHANDLE = 0x80030006, + STG_E_INSUFFICIENTMEMORY = 0x80030008, + STG_E_INVALIDPOINTER = 0x80030009, + STG_E_NOMOREFILES = 0x80030012, + STG_E_DISKISWRITEPROTECTED = 0x80030013, + STG_E_SEEKERROR = 0x80030019, + STG_E_WRITEFAULT = 0x8003001D, + STG_E_READFAULT = 0x8003001E, + STG_E_SHAREVIOLATION = 0x80030020, + STG_E_LOCKVIOLATION = 0x80030021, + STG_E_FILEALREADYEXISTS = 0x80030050, + STG_E_INVALIDPARAMETER = 0x80030057, + STG_E_MEDIUMFULL = 0x80030070, + STG_E_ABNORMALAPIEXIT = 0x800300FA, + STG_E_INVALIDHEADER = 0x800300FB, + STG_E_INVALIDNAME = 0x800300FC, + STG_E_UNKNOWN = 0x800300FD, + STG_E_UNIMPLEMENTEDFUNCTION = 0x800300FE, + STG_E_INVALIDFLAG = 0x800300FF, + STG_E_INUSE = 0x80030100, + STG_E_NOTCURRENT = 0x80030101, + STG_E_REVERTED = 0x80030102, + STG_E_CANTSAVE = 0x80030103, + STG_E_OLDFORMAT = 0x80030104, + STG_E_OLDDLL = 0x80030105, + STG_E_SHAREREQUIRED = 0x80030106, + STG_E_NOTFILEBASEDSTORAGE = 0x80030107, + STG_E_EXTANTMARSHALLINGS = 0x80030108, + STG_S_CONVERTED = 0x00030200, + + OLE_E_FIRST = 0x80040000, + OLE_S_FIRST = 0x00040000, + OLE_E_OLEVERB = 0x80040000, + OLE_S_USEREG = 0x00040000, + OLE_E_ADVF = 0x80040001, + OLE_S_STATIC = 0x00040001, + OLE_E_ENUM_NOMORE = 0x80040002, + OLE_S_MAC_CLIPFORMAT = 0x00040002, + OLE_E_ADVISENOTSUPPORTED = 0x80040003, + OLE_E_NOCONNECTION = 0x80040004, + OLE_E_NOTRUNNING = 0x80040005, + OLE_E_NOCACHE = 0x80040006, + OLE_E_BLANK = 0x80040007, + OLE_E_CLASSDIFF = 0x80040008, + OLE_E_CANT_GETMONIKER = 0x80040009, + OLE_E_CANT_BINDTOSOURCE = 0x8004000A, + OLE_E_STATIC = 0x8004000B, + OLE_E_PROMPTSAVECANCELLED = 0x8004000C, + OLE_E_INVALIDRECT = 0x8004000D, + OLE_E_WRONGCOMPOBJ = 0x8004000E, + OLE_E_INVALIDHWND = 0x8004000F, + OLE_E_NOT_INPLACEACTIVE = 0x80040010, + OLE_E_CANTCONVERT = 0x80040011, + OLE_E_NOSTORAGE = 0x80040012, + + DV_E_FORMATETC = 0x80040064, + DV_E_DVTARGETDEVICE = 0x80040065, + DV_E_STGMEDIUM = 0x80040066, + DV_E_STATDATA = 0x80040067, + DV_E_LINDEX = 0x80040068, + DV_E_TYMED = 0x80040069, + DV_E_CLIPFORMAT = 0x8004006A, + DV_E_DVASPECT = 0x8004006B, + DV_E_DVTARGETDEVICE_SIZE = 0x8004006C, + DV_E_NOIVIEWOBJECT = 0x8004006D, + + OLE_E_LAST = 0x800400FF, + OLE_S_LAST = 0x000400FF, + DRAGDROP_E_FIRST = 0x80040100, + DRAGDROP_S_FIRST = 0x00040100, + DRAGDROP_E_NOTREGISTERED = 0x80040100, + DRAGDROP_S_DROP = 0x00040100, + DRAGDROP_E_ALREADYREGISTERED = 0x80040101, + DRAGDROP_S_CANCEL = 0x00040101, + DRAGDROP_E_INVALIDHWND = 0x80040102, + DRAGDROP_S_USEDEFAULTCURSORS = 0x00040102, + DRAGDROP_E_LAST = 0x8004010F, + DRAGDROP_S_LAST = 0x0004010F, + CLASSFACTORY_E_FIRST = 0x80040110, + CLASSFACTORY_S_FIRST = 0x00040110, + CLASS_E_NOAGGREGATION = 0x80040110, + CLASS_E_CLASSNOTAVAILABLE = 0x80040111, + CLASSFACTORY_E_LAST = 0x8004011F, + CLASSFACTORY_S_LAST = 0x0004011F, + MARSHAL_E_FIRST = 0x80040120, + MARSHAL_S_FIRST = 0x00040120, + MARSHAL_E_LAST = 0x8004012F, + MARSHAL_S_LAST = 0x0004012F, + DATA_E_FIRST = 0x80040130, + DATA_S_FIRST = 0x00040130, + DATA_S_SAMEFORMATETC = 0x00040130, + DATA_E_LAST = 0x8004013F, + DATA_S_LAST = 0x0004013F, + VIEW_E_FIRST = 0x80040140, + VIEW_S_FIRST = 0x00040140, + VIEW_E_DRAW = 0x80040140, + VIEW_S_ALREADY_FROZEN = 0x00040140, + VIEW_E_LAST = 0x8004014F, + VIEW_S_LAST = 0x0004014F, + REGDB_E_FIRST = 0x80040150, + REGDB_S_FIRST = 0x00040150, + REGDB_E_READREGDB = 0x80040150, + REGDB_E_WRITEREGDB = 0x80040151, + REGDB_E_KEYMISSING = 0x80040152, + REGDB_E_INVALIDVALUE = 0x80040153, + REGDB_E_CLASSNOTREG = 0x80040154, + REGDB_E_IIDNOTREG = 0x80040155, + REGDB_E_LAST = 0x8004015F, + REGDB_S_LAST = 0x0004015F, + CACHE_E_FIRST = 0x80040170, + CACHE_S_FIRST = 0x00040170, + CACHE_E_NOCACHE_UPDATED = 0x80040170, + CACHE_S_FORMATETC_NOTSUPPORTED = 0x00040170, + CACHE_S_SAMECACHE = 0x00040171, + CACHE_S_SOMECACHES_NOTUPDATED = 0x00040172, + CACHE_E_LAST = 0x8004017F, + CACHE_S_LAST = 0x0004017F, + OLEOBJ_E_FIRST = 0x80040180, + OLEOBJ_S_FIRST = 0x00040180, + OLEOBJ_E_NOVERBS = 0x80040180, + OLEOBJ_S_INVALIDVERB = 0x00040180, + OLEOBJ_E_INVALIDVERB = 0x80040181, + OLEOBJ_S_CANNOT_DOVERB_NOW = 0x00040181, + OLEOBJ_S_INVALIDHWND = 0x00040182, + OLEOBJ_E_LAST = 0x8004018F, + OLEOBJ_S_LAST = 0x0004018F, + CLIENTSITE_E_FIRST = 0x80040190, + CLIENTSITE_S_FIRST = 0x00040190, + CLIENTSITE_E_LAST = 0x8004019F, + CLIENTSITE_S_LAST = 0x0004019F, + INPLACE_E_NOTUNDOABLE = 0x800401A0, + INPLACE_E_FIRST = 0x800401A0, + INPLACE_S_FIRST = 0x000401A0, + INPLACE_S_TRUNCATED = 0x000401A0, + INPLACE_E_NOTOOLSPACE = 0x800401A1, + INPLACE_E_LAST = 0x800401AF, + INPLACE_S_LAST = 0x000401AF, + ENUM_E_FIRST = 0x800401B0, + ENUM_S_FIRST = 0x000401B0, + ENUM_E_LAST = 0x800401BF, + ENUM_S_LAST = 0x000401BF, + CONVERT10_E_FIRST = 0x800401C0, + CONVERT10_S_FIRST = 0x000401C0, + CONVERT10_E_OLESTREAM_GET = 0x800401C0, + CONVERT10_S_NO_PRESENTATION = 0x000401C0, + CONVERT10_E_OLESTREAM_PUT = 0x800401C1, + CONVERT10_E_OLESTREAM_FMT = 0x800401C2, + CONVERT10_E_OLESTREAM_BITMAP_TO_DIB = 0x800401C3, + CONVERT10_E_STG_FMT = 0x800401C4, + CONVERT10_E_STG_NO_STD_STREAM = 0x800401C5, + CONVERT10_E_STG_DIB_TO_BITMAP = 0x800401C6, + CONVERT10_E_LAST = 0x800401CF, + CONVERT10_S_LAST = 0x000401CF, + CLIPBRD_E_FIRST = 0x800401D0, + CLIPBRD_S_FIRST = 0x000401D0, + CLIPBRD_E_CANT_OPEN = 0x800401D0, + CLIPBRD_E_CANT_EMPTY = 0x800401D1, + CLIPBRD_E_CANT_SET = 0x800401D2, + CLIPBRD_E_BAD_DATA = 0x800401D3, + CLIPBRD_E_CANT_CLOSE = 0x800401D4, + CLIPBRD_E_LAST = 0x800401DF, + CLIPBRD_S_LAST = 0x000401DF, + MK_E_FIRST = 0x800401E0, + MK_S_FIRST = 0x000401E0, + MK_E_CONNECTMANUALLY = 0x800401E0, + MK_E_EXCEEDEDDEADLINE = 0x800401E1, + MK_E_NEEDGENERIC = 0x800401E2, + MK_S_REDUCED_TO_SELF = 0x000401E2, + MK_E_UNAVAILABLE = 0x800401E3, + MK_E_SYNTAX = 0x800401E4, + MK_S_ME = 0x000401E4, + MK_E_NOOBJECT = 0x800401E5, + MK_S_HIM = 0x000401E5, + MK_E_INVALIDEXTENSION = 0x800401E6, + MK_S_US = 0x000401E6, + MK_E_INTERMEDIATEINTERFACENOTSUPPORTED = 0x800401E7, + MK_S_MONIKERALREADYREGISTERED = 0x000401E7, + MK_E_NOTBINDABLE = 0x800401E8, + MK_E_NOTBOUND = 0x800401E9, + MK_E_CANTOPENFILE = 0x800401EA, + MK_E_MUSTBOTHERUSER = 0x800401EB, + MK_E_NOINVERSE = 0x800401EC, + MK_E_NOSTORAGE = 0x800401ED, + MK_E_NOPREFIX = 0x800401EE, + MK_E_LAST = 0x800401EF, + MK_S_LAST = 0x000401EF, + MK_E_ENUMERATION_FAILED = 0x800401EF, + CO_E_FIRST = 0x800401F0, + CO_S_FIRST = 0x000401F0, + CO_E_NOTINITIALIZED = 0x800401F0, + CO_E_ALREADYINITIALIZED = 0x800401F1, + CO_E_CANTDETERMINECLASS = 0x800401F2, + CO_E_CLASSSTRING = 0x800401F3, + CO_E_IIDSTRING = 0x800401F4, + CO_E_APPNOTFOUND = 0x800401F5, + CO_E_APPSINGLEUSE = 0x800401F6, + CO_E_ERRORINAPP = 0x800401F7, + CO_E_DLLNOTFOUND = 0x800401F8, + CO_E_ERRORINDLL = 0x800401F9, + CO_E_WRONGOSFORAPP = 0x800401FA, + CO_E_OBJNOTREG = 0x800401FB, + CO_E_OBJISREG = 0x800401FC, + CO_E_OBJNOTCONNECTED = 0x800401FD, + CO_E_APPDIDNTREG = 0x800401FE, + CO_E_LAST = 0x800401FF, + CO_S_LAST = 0x000401FF, + CO_E_RELEASED = 0x800401FF, + + CO_E_CLASS_CREATE_FAILED = 0x80080001, + CO_E_SCM_ERROR = 0x80080002, + CO_E_SCM_RPC_FAILURE = 0x80080003, + CO_E_BAD_PATH = 0x80080004, + CO_E_SERVER_EXEC_FAILURE = 0x80080005, + CO_E_OBJSRV_RPC_FAILURE = 0x80080006, + MK_E_NO_NORMALIZED = 0x80080007, + CO_E_SERVER_STOPPING = 0x80080008, + MEM_E_INVALID_ROOT = 0x80080009, + MEM_E_INVALID_LINK = 0x80080010, + MEM_E_INVALID_SIZE = 0x80080011, + CO_S_NOTALLINTERFACES = 0x00080012, + + NTE_BAD_UID = 0x80090001, + NTE_BAD_HASH = 0x80090002, + NTE_BAD_KEY = 0x80090003, + NTE_BAD_LEN = 0x80090004, + NTE_BAD_DATA = 0x80090005, + NTE_BAD_SIGNATURE = 0x80090006, + NTE_BAD_VER = 0x80090007, + NTE_BAD_ALGID = 0x80090008, + NTE_BAD_FLAGS = 0x80090009, + NTE_BAD_TYPE = 0x8009000A, + NTE_BAD_KEY_STATE = 0x8009000B, + NTE_BAD_HASH_STATE = 0x8009000C, + NTE_NO_KEY = 0x8009000D, + NTE_NO_MEMORY = 0x8009000E, + NTE_EXISTS = 0x8009000F, + NTE_PERM = 0x80090010, + NTE_NOT_FOUND = 0x80090011, + NTE_DOUBLE_ENCRYPT = 0x80090012, + NTE_BAD_PROVIDER = 0x80090013, + NTE_BAD_PROV_TYPE = 0x80090014, + NTE_BAD_PUBLIC_KEY = 0x80090015, + NTE_BAD_KEYSET = 0x80090016, + NTE_PROV_TYPE_NOT_DEF = 0x80090017, + NTE_PROV_TYPE_ENTRY_BAD = 0x80090018, + NTE_KEYSET_NOT_DEF = 0x80090019, + NTE_KEYSET_ENTRY_BAD = 0x8009001A, + NTE_PROV_TYPE_NO_MATCH = 0x8009001B, + NTE_SIGNATURE_FILE_BAD = 0x8009001C, + NTE_PROVIDER_DLL_FAIL = 0x8009001D, + NTE_PROV_DLL_NOT_FOUND = 0x8009001E, + NTE_BAD_KEYSET_PARAM = 0x8009001F, + NTE_FAIL = 0x80090020, + NTE_SYS_ERR = 0x80090021 +} + + +enum : uint { + SEVERITY_SUCCESS = 0, + SEVERITY_ERROR = 1 +} + +enum : uint { + FACILITY_NULL = 0, + FACILITY_RPC, + FACILITY_DISPATCH, + FACILITY_STORAGE, + FACILITY_ITF, // = 4 + FACILITY_WIN32 = 7, + FACILITY_WINDOWS = 8, + FACILITY_CONTROL = 10, + FACILITY_NT_BIT = 0x10000000 +} + +// C Macros + +pure nothrow @nogc { + bool SUCCEEDED(HRESULT Status) { + return Status >= 0; + } + + bool FAILED(HRESULT Status) { + return Status < 0; + } + + bool IS_ERROR(HRESULT Status) { + return (Status >>> 31) == SEVERITY_ERROR; + } + + ushort HRESULT_CODE(HRESULT r) { + return cast(ushort) (r & 0xFFFF); + } + + ushort SCODE_CODE(SCODE r) { + return cast(ushort) (r & 0xFFFF); + } + + ushort HRESULT_FACILITY(HRESULT r) { + return cast(ushort) ((r>>16) & 0x1fff); + } + + ushort SCODE_FACILITY(SCODE r) { + return cast(ushort) ((r>>16) & 0x1fff); + } + + ushort HRESULT_SEVERITY(HRESULT r) { + return cast(ushort) ((r>>31) & 0x1); + } + + ushort SCODE_SEVERITY(SCODE r) { + return cast(ushort) ((r>>31) & 0x1); + } + + HRESULT MAKE_HRESULT(bool s, uint f, uint c) { + return (s << 31) | (f << 16) | c; + } + + SCODE MAKE_SCODE(bool s, uint f, uint c) { + return (s << 31) | (f << 16) | c; + } + + SCODE GetScode(HRESULT hr) { + return hr; + } + + HRESULT ResultFromScode(SCODE c) { + return c; + } + + HRESULT HRESULT_FROM_NT(HRESULT x) { + return x | FACILITY_NT_BIT; + } + + HRESULT HRESULT_FROM_WIN32(HRESULT x) { + return x ? (x & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000 : 0; + } + + HRESULT PropagateResult(HRESULT hrPrevious, SCODE scBase) { + return scBase; + } +} diff --git a/src/urt/internal/sys/windows/winnt.d b/src/urt/internal/sys/windows/winnt.d new file mode 100644 index 0000000..882b21d --- /dev/null +++ b/src/urt/internal/sys/windows/winnt.d @@ -0,0 +1,4321 @@ +/** + * Windows API header module + * + * Translated from MinGW API for MS-Windows 3.12 + * + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(DRUNTIMESRC core/sys/windows/_winnt.d) + */ +module urt.internal.sys.windows.winnt; +version (Windows): + +version (ANSI) {} else version = Unicode; + +public import urt.internal.sys.windows.basetsd, urt.internal.sys.windows.windef, urt.internal.sys.windows.winerror; +import urt.internal.sys.windows.w32api; + +/* Translation Notes: +The following macros are unneeded for D: +FIELD_OFFSET(t,f), CONTAINING_RECORD(address, type, field) +*/ + +alias void VOID; +alias char CHAR, CCHAR; +alias wchar WCHAR; +alias bool BOOLEAN; +alias byte FCHAR; +alias ubyte UCHAR; +alias short SHORT; +alias ushort LANGID, FSHORT; +alias uint LCID, FLONG, ACCESS_MASK; +alias long LONGLONG, USN; +alias ulong DWORDLONG, ULONGLONG; + +alias void* PVOID, LPVOID; +alias char* PSZ, PCHAR, PCCHAR, LPCH, PCH, LPSTR, PSTR; +alias wchar* PWCHAR, LPWCH, PWCH, LPWSTR, PWSTR; +alias bool* PBOOLEAN; +alias ubyte* PUCHAR; +alias short* PSHORT; +alias int* PLONG; +alias uint* PLCID, PACCESS_MASK; +alias long* PLONGLONG; +alias ulong* PDWORDLONG, PULONGLONG; + +// FIXME(MinGW) for __WIN64 +alias void* PVOID64; + +// const versions +alias const(char)* PCCH, LPCCH, PCSTR, LPCSTR; +alias const(wchar)* LPCWCH, PCWCH, LPCWSTR, PCWSTR; + +alias PSTR* PZPSTR; +alias PWSTR* PZPWSTR; + +version (Unicode) { + alias WCHAR TCHAR, _TCHAR; +} else { + alias CHAR TCHAR, _TCHAR; +} + +alias TCHAR TBYTE; +alias TCHAR* PTCH , PTBYTE, LPTCH , PTSTR , LPTSTR , LP, PTCHAR; +alias const(TCHAR)* PCTCH, LPCTCH, PCTSTR, LPCTSTR ; + +enum char ANSI_NULL = '\0'; +enum wchar UNICODE_NULL = '\0'; + +enum APPLICATION_ERROR_MASK = 0x20000000; +enum ERROR_SEVERITY_SUCCESS = 0x00000000; +enum ERROR_SEVERITY_INFORMATIONAL = 0x40000000; +enum ERROR_SEVERITY_WARNING = 0x80000000; +enum ERROR_SEVERITY_ERROR = 0xC0000000; + +// MinGW: also in ddk/ntifs.h +enum : USHORT { + COMPRESSION_FORMAT_NONE = 0x0000, + COMPRESSION_FORMAT_DEFAULT = 0x0001, + COMPRESSION_FORMAT_LZNT1 = 0x0002, + COMPRESSION_ENGINE_STANDARD = 0x0000, + COMPRESSION_ENGINE_MAXIMUM = 0x0100, + COMPRESSION_ENGINE_HIBER = 0x0200 +} + +// ACCESS_DENIED_OBJECT_ACE, etc +enum DWORD + ACE_OBJECT_TYPE_PRESENT = 0x00000001, + ACE_INHERITED_OBJECT_TYPE_PRESENT = 0x00000002; + +// ACE_HEADER.AceType +// also in ddk/ntifs.h +enum : BYTE { + ACCESS_ALLOWED_ACE_TYPE, + ACCESS_DENIED_ACE_TYPE, + SYSTEM_AUDIT_ACE_TYPE, + SYSTEM_ALARM_ACE_TYPE +} + +// ACE_HEADER.AceFlags +enum BYTE + OBJECT_INHERIT_ACE = 0x01, + CONTAINER_INHERIT_ACE = 0x02, + NO_PROPAGATE_INHERIT_ACE = 0x04, + INHERIT_ONLY_ACE = 0x08, + INHERITED_ACE = 0x10, + VALID_INHERIT_FLAGS = 0x1F, + SUCCESSFUL_ACCESS_ACE_FLAG = 0x40, + FAILED_ACCESS_ACE_FLAG = 0x80; + +// Access Mask Format +enum ACCESS_MASK + DELETE = 0x00010000, + READ_CONTROL = 0x00020000, + WRITE_DAC = 0x00040000, + WRITE_OWNER = 0x00080000, + SYNCHRONIZE = 0x00100000, + ACCESS_SYSTEM_SECURITY = 0x01000000, + MAXIMUM_ALLOWED = 0x02000000, + GENERIC_READ = 0x80000000, + GENERIC_WRITE = 0x40000000, + GENERIC_EXECUTE = 0x20000000, + GENERIC_ALL = 0x10000000, + STANDARD_RIGHTS_REQUIRED = 0x000F0000, + STANDARD_RIGHTS_READ = 0x00020000, + STANDARD_RIGHTS_WRITE = 0x00020000, + STANDARD_RIGHTS_EXECUTE = 0x00020000, + STANDARD_RIGHTS_ALL = 0x001F0000, + SPECIFIC_RIGHTS_ALL = 0x0000FFFF; + + +enum DWORD INVALID_FILE_ATTRIBUTES = -1; + +// MinGW: Also in ddk/winddk.h +enum DWORD + FILE_LIST_DIRECTORY = 0x00000001, + FILE_READ_DATA = 0x00000001, + FILE_ADD_FILE = 0x00000002, + FILE_WRITE_DATA = 0x00000002, + FILE_ADD_SUBDIRECTORY = 0x00000004, + FILE_APPEND_DATA = 0x00000004, + FILE_CREATE_PIPE_INSTANCE = 0x00000004, + FILE_READ_EA = 0x00000008, + FILE_READ_PROPERTIES = 0x00000008, + FILE_WRITE_EA = 0x00000010, + FILE_WRITE_PROPERTIES = 0x00000010, + FILE_EXECUTE = 0x00000020, + FILE_TRAVERSE = 0x00000020, + FILE_DELETE_CHILD = 0x00000040, + FILE_READ_ATTRIBUTES = 0x00000080, + FILE_WRITE_ATTRIBUTES = 0x00000100; + +enum DWORD + FILE_SHARE_READ = 0x00000001, + FILE_SHARE_WRITE = 0x00000002, + FILE_SHARE_DELETE = 0x00000004, + FILE_SHARE_VALID_FLAGS = 0x00000007; + +enum DWORD + FILE_ATTRIBUTE_READONLY = 0x00000001, + FILE_ATTRIBUTE_HIDDEN = 0x00000002, + FILE_ATTRIBUTE_SYSTEM = 0x00000004, + FILE_ATTRIBUTE_DIRECTORY = 0x00000010, + FILE_ATTRIBUTE_ARCHIVE = 0x00000020, + FILE_ATTRIBUTE_DEVICE = 0x00000040, + FILE_ATTRIBUTE_NORMAL = 0x00000080, + FILE_ATTRIBUTE_TEMPORARY = 0x00000100, + FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200, + FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400, + FILE_ATTRIBUTE_COMPRESSED = 0x00000800, + FILE_ATTRIBUTE_OFFLINE = 0x00001000, + FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000, + FILE_ATTRIBUTE_ENCRYPTED = 0x00004000, + FILE_ATTRIBUTE_VALID_FLAGS = 0x00007fb7, + FILE_ATTRIBUTE_VALID_SET_FLAGS = 0x000031a7; + +// These are not documented on MSDN +enum FILE_COPY_STRUCTURED_STORAGE = 0x00000041; +enum FILE_STRUCTURED_STORAGE = 0x00000441; + +// Nor are these +enum FILE_VALID_OPTION_FLAGS = 0x00ffffff; +enum FILE_VALID_PIPE_OPTION_FLAGS = 0x00000032; +enum FILE_VALID_MAILSLOT_OPTION_FLAGS = 0x00000032; +enum FILE_VALID_SET_FLAGS = 0x00000036; + +enum ULONG + FILE_SUPERSEDE = 0x00000000, + FILE_OPEN = 0x00000001, + FILE_CREATE = 0x00000002, + FILE_OPEN_IF = 0x00000003, + FILE_OVERWRITE = 0x00000004, + FILE_OVERWRITE_IF = 0x00000005, + FILE_MAXIMUM_DISPOSITION = 0x00000005; + +enum ULONG + FILE_DIRECTORY_FILE = 0x00000001, + FILE_WRITE_THROUGH = 0x00000002, + FILE_SEQUENTIAL_ONLY = 0x00000004, + FILE_NO_INTERMEDIATE_BUFFERING = 0x00000008, + FILE_SYNCHRONOUS_IO_ALERT = 0x00000010, + FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020, + FILE_NON_DIRECTORY_FILE = 0x00000040, + FILE_CREATE_TREE_CONNECTION = 0x00000080, + FILE_COMPLETE_IF_OPLOCKED = 0x00000100, + FILE_NO_EA_KNOWLEDGE = 0x00000200, + FILE_OPEN_FOR_RECOVERY = 0x00000400, + FILE_RANDOM_ACCESS = 0x00000800, + FILE_DELETE_ON_CLOSE = 0x00001000, + FILE_OPEN_BY_FILE_ID = 0x00002000, + FILE_OPEN_FOR_BACKUP_INTENT = 0x00004000, + FILE_NO_COMPRESSION = 0x00008000, + FILE_RESERVE_OPFILTER = 0x00100000, + FILE_OPEN_REPARSE_POINT = 0x00200000, + FILE_OPEN_NO_RECALL = 0x00400000, + FILE_OPEN_FOR_FREE_SPACE_QUERY = 0x00800000; + + +enum ACCESS_MASK + FILE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x01FF, + FILE_GENERIC_EXECUTE = STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES + | FILE_EXECUTE | SYNCHRONIZE, + FILE_GENERIC_READ = STANDARD_RIGHTS_READ | FILE_READ_DATA + | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE, + FILE_GENERIC_WRITE = STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA + | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA + | SYNCHRONIZE; + +// MinGW: end winddk.h +// MinGW: also in ddk/ntifs.h +enum DWORD + FILE_NOTIFY_CHANGE_FILE_NAME = 0x00000001, + FILE_NOTIFY_CHANGE_DIR_NAME = 0x00000002, + FILE_NOTIFY_CHANGE_NAME = 0x00000003, + FILE_NOTIFY_CHANGE_ATTRIBUTES = 0x00000004, + FILE_NOTIFY_CHANGE_SIZE = 0x00000008, + FILE_NOTIFY_CHANGE_LAST_WRITE = 0x00000010, + FILE_NOTIFY_CHANGE_LAST_ACCESS = 0x00000020, + FILE_NOTIFY_CHANGE_CREATION = 0x00000040, + FILE_NOTIFY_CHANGE_EA = 0x00000080, + FILE_NOTIFY_CHANGE_SECURITY = 0x00000100, + FILE_NOTIFY_CHANGE_STREAM_NAME = 0x00000200, + FILE_NOTIFY_CHANGE_STREAM_SIZE = 0x00000400, + FILE_NOTIFY_CHANGE_STREAM_WRITE = 0x00000800, + FILE_NOTIFY_VALID_MASK = 0x00000fff; + +enum DWORD + FILE_CASE_SENSITIVE_SEARCH = 0x00000001, + FILE_CASE_PRESERVED_NAMES = 0x00000002, + FILE_UNICODE_ON_DISK = 0x00000004, + FILE_PERSISTENT_ACLS = 0x00000008, + FILE_FILE_COMPRESSION = 0x00000010, + FILE_VOLUME_QUOTAS = 0x00000020, + FILE_SUPPORTS_SPARSE_FILES = 0x00000040, + FILE_SUPPORTS_REPARSE_POINTS = 0x00000080, + FILE_SUPPORTS_REMOTE_STORAGE = 0x00000100, + FS_LFN_APIS = 0x00004000, + FILE_VOLUME_IS_COMPRESSED = 0x00008000, + FILE_SUPPORTS_OBJECT_IDS = 0x00010000, + FILE_SUPPORTS_ENCRYPTION = 0x00020000, + FILE_NAMED_STREAMS = 0x00040000, + FILE_READ_ONLY_VOLUME = 0x00080000, + FILE_SEQUENTIAL_WRITE_ONCE = 0x00100000, + FILE_SUPPORTS_TRANSACTIONS = 0x00200000; + +// These are not documented on MSDN +enum ACCESS_MASK + IO_COMPLETION_QUERY_STATE = 1, + IO_COMPLETION_MODIFY_STATE = 2, + IO_COMPLETION_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 3; +// MinGW: end ntifs.h + +// MinGW: also in ddk/winddk.h +enum DWORD + DUPLICATE_CLOSE_SOURCE = 1, + DUPLICATE_SAME_ACCESS = 2, + DUPLICATE_SAME_ATTRIBUTES = 4; +// MinGW: end winddk.k + +enum DWORD + MAILSLOT_NO_MESSAGE = -1, + MAILSLOT_WAIT_FOREVER = -1; + +enum ACCESS_MASK + PROCESS_TERMINATE = 0x0001, + PROCESS_CREATE_THREAD = 0x0002, + PROCESS_SET_SESSIONID = 0x0004, + PROCESS_VM_OPERATION = 0x0008, + PROCESS_VM_READ = 0x0010, + PROCESS_VM_WRITE = 0x0020, + PROCESS_DUP_HANDLE = 0x0040, + PROCESS_CREATE_PROCESS = 0x0080, + PROCESS_SET_QUOTA = 0x0100, + PROCESS_SET_INFORMATION = 0x0200, + PROCESS_QUERY_INFORMATION = 0x0400, + PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x0FFF; + +enum ACCESS_MASK + THREAD_TERMINATE = 0x0001, + THREAD_SUSPEND_RESUME = 0x0002, + THREAD_GET_CONTEXT = 0x0008, + THREAD_SET_CONTEXT = 0x0010, + THREAD_SET_INFORMATION = 0x0020, + THREAD_QUERY_INFORMATION = 0x0040, + THREAD_SET_THREAD_TOKEN = 0x0080, + THREAD_IMPERSONATE = 0x0100, + THREAD_DIRECT_IMPERSONATION = 0x0200, + THREAD_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3FF; + +// These are not documented on MSDN +enum THREAD_BASE_PRIORITY_LOWRT = 15; +enum THREAD_BASE_PRIORITY_MAX = 2; +enum THREAD_BASE_PRIORITY_MIN = -2; +enum THREAD_BASE_PRIORITY_IDLE = -15; + +enum DWORD EXCEPTION_NONCONTINUABLE = 1; +enum size_t EXCEPTION_MAXIMUM_PARAMETERS = 15; + +// These are not documented on MSDN +enum ACCESS_MASK + MUTANT_QUERY_STATE = 1, + MUTANT_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | MUTANT_QUERY_STATE; + +enum ACCESS_MASK + TIMER_QUERY_STATE = 1, + TIMER_MODIFY_STATE = 2, + TIMER_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | TIMER_QUERY_STATE + | TIMER_MODIFY_STATE; + +enum SID_IDENTIFIER_AUTHORITY + SECURITY_NULL_SID_AUTHORITY = {[5: 0]}, + SECURITY_WORLD_SID_AUTHORITY = {[5: 1]}, + SECURITY_LOCAL_SID_AUTHORITY = {[5: 2]}, + SECURITY_CREATOR_SID_AUTHORITY = {[5: 3]}, + SECURITY_NON_UNIQUE_AUTHORITY = {[5: 4]}, + SECURITY_NT_AUTHORITY = {[5: 5]}, + SECURITY_MANDATORY_LABEL_AUTHORITY = {[5: 6]}; + +enum DWORD + SECURITY_NULL_RID = 0, + SECURITY_WORLD_RID = 0, + SECURITY_LOCAL_RID = 0, + SECURITY_CREATOR_OWNER_RID = 0, + SECURITY_CREATOR_GROUP_RID = 1, + SECURITY_DIALUP_RID = 1, + SECURITY_NETWORK_RID = 2, + SECURITY_BATCH_RID = 3, + SECURITY_INTERACTIVE_RID = 4, + SECURITY_LOGON_IDS_RID = 5, + SECURITY_SERVICE_RID = 6, + SECURITY_LOCAL_SYSTEM_RID = 18, + SECURITY_BUILTIN_DOMAIN_RID = 32, + SECURITY_PRINCIPAL_SELF_RID = 10, + SECURITY_CREATOR_OWNER_SERVER_RID = 2, + SECURITY_CREATOR_GROUP_SERVER_RID = 3, + SECURITY_LOGON_IDS_RID_COUNT = 3, + SECURITY_ANONYMOUS_LOGON_RID = 7, + SECURITY_PROXY_RID = 8, + SECURITY_ENTERPRISE_CONTROLLERS_RID = 9, + SECURITY_SERVER_LOGON_RID = SECURITY_ENTERPRISE_CONTROLLERS_RID, + SECURITY_AUTHENTICATED_USER_RID = 11, + SECURITY_RESTRICTED_CODE_RID = 12, + SECURITY_NT_NON_UNIQUE_RID = 21, + SID_REVISION = 1; + +enum : DWORD { + DOMAIN_USER_RID_ADMIN = 0x01F4, + DOMAIN_USER_RID_GUEST = 0x01F5, + DOMAIN_GROUP_RID_ADMINS = 0x0200, + DOMAIN_GROUP_RID_USERS = 0x0201, + DOMAIN_ALIAS_RID_ADMINS = 0x0220, + DOMAIN_ALIAS_RID_USERS = 0x0221, + DOMAIN_ALIAS_RID_GUESTS = 0x0222, + DOMAIN_ALIAS_RID_POWER_USERS = 0x0223, + DOMAIN_ALIAS_RID_ACCOUNT_OPS = 0x0224, + DOMAIN_ALIAS_RID_SYSTEM_OPS = 0x0225, + DOMAIN_ALIAS_RID_PRINT_OPS = 0x0226, + DOMAIN_ALIAS_RID_BACKUP_OPS = 0x0227, + DOMAIN_ALIAS_RID_REPLICATOR = 0x0228 +} + +enum : WORD { + SECURITY_MANDATORY_UNTRUSTED_RID = 0, + SECURITY_MANDATORY_LOW_RID = 0x1000, + SECURITY_MANDATORY_MEDIUM_RID = 0x2000, + SECURITY_MANDATORY_HIGH_RID = 0x3000, + SECURITY_MANDATORY_SYSTEM_RID = 0x4000, + SECURITY_MANDATORY_PROTECTED_PROCESS_RID = 0x5000, + SECURITY_MANDATORY_MAXIMUM_USER_RID = SECURITY_MANDATORY_SYSTEM_RID +} + +const TCHAR[] + SE_CREATE_TOKEN_NAME = "SeCreateTokenPrivilege", + SE_ASSIGNPRIMARYTOKEN_NAME = "SeAssignPrimaryTokenPrivilege", + SE_LOCK_MEMORY_NAME = "SeLockMemoryPrivilege", + SE_INCREASE_QUOTA_NAME = "SeIncreaseQuotaPrivilege", + SE_UNSOLICITED_INPUT_NAME = "SeUnsolicitedInputPrivilege", + SE_MACHINE_ACCOUNT_NAME = "SeMachineAccountPrivilege", + SE_TCB_NAME = "SeTcbPrivilege", + SE_SECURITY_NAME = "SeSecurityPrivilege", + SE_TAKE_OWNERSHIP_NAME = "SeTakeOwnershipPrivilege", + SE_LOAD_DRIVER_NAME = "SeLoadDriverPrivilege", + SE_SYSTEM_PROFILE_NAME = "SeSystemProfilePrivilege", + SE_SYSTEMTIME_NAME = "SeSystemtimePrivilege", + SE_PROF_SINGLE_PROCESS_NAME = "SeProfileSingleProcessPrivilege", + SE_INC_BASE_PRIORITY_NAME = "SeIncreaseBasePriorityPrivilege", + SE_CREATE_PAGEFILE_NAME = "SeCreatePagefilePrivilege", + SE_CREATE_PERMANENT_NAME = "SeCreatePermanentPrivilege", + SE_BACKUP_NAME = "SeBackupPrivilege", + SE_RESTORE_NAME = "SeRestorePrivilege", + SE_SHUTDOWN_NAME = "SeShutdownPrivilege", + SE_DEBUG_NAME = "SeDebugPrivilege", + SE_AUDIT_NAME = "SeAuditPrivilege", + SE_SYSTEM_ENVIRONMENT_NAME = "SeSystemEnvironmentPrivilege", + SE_CHANGE_NOTIFY_NAME = "SeChangeNotifyPrivilege", + SE_REMOTE_SHUTDOWN_NAME = "SeRemoteShutdownPrivilege", + SE_CREATE_GLOBAL_NAME = "SeCreateGlobalPrivilege", + SE_UNDOCK_NAME = "SeUndockPrivilege", + SE_MANAGE_VOLUME_NAME = "SeManageVolumePrivilege", + SE_IMPERSONATE_NAME = "SeImpersonatePrivilege", + SE_ENABLE_DELEGATION_NAME = "SeEnableDelegationPrivilege", + SE_SYNC_AGENT_NAME = "SeSyncAgentPrivilege", + SE_TRUSTED_CREDMAN_ACCESS_NAME = "SeTrustedCredManAccessPrivilege", + SE_RELABEL_NAME = "SeRelabelPrivilege", + SE_INCREASE_WORKING_SET_NAME = "SeIncreaseWorkingSetPrivilege", + SE_TIME_ZONE_NAME = "SeTimeZonePrivilege", + SE_CREATE_SYMBOLIC_LINK_NAME = "SeCreateSymbolicLinkPrivilege"; + +enum DWORD + SE_GROUP_MANDATORY = 0x00000001, + SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002, + SE_GROUP_ENABLED = 0x00000004, + SE_GROUP_OWNER = 0x00000008, + SE_GROUP_USE_FOR_DENY_ONLY = 0x00000010, + SE_GROUP_INTEGRITY = 0x00000020, + SE_GROUP_INTEGRITY_ENABLED = 0x00000040, + SE_GROUP_RESOURCE = 0x20000000, + SE_GROUP_LOGON_ID = 0xC0000000; + +// Primary language identifiers +enum : USHORT { + LANG_NEUTRAL, + LANG_ARABIC, + LANG_BULGARIAN, + LANG_CATALAN, + LANG_CHINESE, + LANG_CZECH, + LANG_DANISH, + LANG_GERMAN, + LANG_GREEK, + LANG_ENGLISH, + LANG_SPANISH, + LANG_FINNISH, + LANG_FRENCH, + LANG_HEBREW, + LANG_HUNGARIAN, + LANG_ICELANDIC, + LANG_ITALIAN, + LANG_JAPANESE, + LANG_KOREAN, + LANG_DUTCH, + LANG_NORWEGIAN, + LANG_POLISH, + LANG_PORTUGUESE, // = 0x16 + LANG_ROMANIAN = 0x18, + LANG_RUSSIAN, + LANG_CROATIAN, // = 0x1A + LANG_SERBIAN = 0x1A, + LANG_BOSNIAN = 0x1A, + LANG_SLOVAK, + LANG_ALBANIAN, + LANG_SWEDISH, + LANG_THAI, + LANG_TURKISH, + LANG_URDU, + LANG_INDONESIAN, + LANG_UKRAINIAN, + LANG_BELARUSIAN, + LANG_SLOVENIAN, + LANG_ESTONIAN, + LANG_LATVIAN, + LANG_LITHUANIAN, // = 0x27 + LANG_FARSI = 0x29, + LANG_PERSIAN = 0x29, + LANG_VIETNAMESE, + LANG_ARMENIAN, + LANG_AZERI, + LANG_BASQUE, + LANG_LOWER_SORBIAN, // = 0x2E + LANG_UPPER_SORBIAN = 0x2E, + LANG_MACEDONIAN, // = 0x2F + LANG_TSWANA = 0x32, + LANG_XHOSA = 0x34, + LANG_ZULU, + LANG_AFRIKAANS, + LANG_GEORGIAN, + LANG_FAEROESE, + LANG_HINDI, + LANG_MALTESE, + LANG_SAMI, + LANG_IRISH, // = 0x3C + LANG_MALAY = 0x3E, + LANG_KAZAK, + LANG_KYRGYZ, + LANG_SWAHILI, // = 0x41 + LANG_UZBEK = 0x43, + LANG_TATAR, + LANG_BENGALI, + LANG_PUNJABI, + LANG_GUJARATI, + LANG_ORIYA, + LANG_TAMIL, + LANG_TELUGU, + LANG_KANNADA, + LANG_MALAYALAM, + LANG_ASSAMESE, + LANG_MARATHI, + LANG_SANSKRIT, + LANG_MONGOLIAN, + LANG_TIBETAN, + LANG_WELSH, + LANG_KHMER, + LANG_LAO, // = 0x54 + LANG_GALICIAN = 0x56, + LANG_KONKANI, + LANG_MANIPURI, + LANG_SINDHI, + LANG_SYRIAC, + LANG_SINHALESE, // = 0x5B + LANG_INUKTITUT = 0x5D, + LANG_AMHARIC, + LANG_TAMAZIGHT, + LANG_KASHMIRI, + LANG_NEPALI, + LANG_FRISIAN, + LANG_PASHTO, + LANG_FILIPINO, + LANG_DIVEHI, // = 0x65 + LANG_HAUSA = 0x68, + LANG_YORUBA = 0x6A, + LANG_QUECHUA, + LANG_SOTHO, + LANG_BASHKIR, + LANG_LUXEMBOURGISH, + LANG_GREENLANDIC, + LANG_IGBO, // = 0x70 + LANG_TIGRIGNA = 0x73, + LANG_YI = 0x78, + LANG_MAPUDUNGUN = 0x7A, + LANG_MOHAWK = 0x7C, + LANG_BRETON = 0x7E, + LANG_UIGHUR = 0x80, + LANG_MAORI, + LANG_OCCITAN, + LANG_CORSICAN, + LANG_ALSATIAN, + LANG_YAKUT, + LANG_KICHE, + LANG_KINYARWANDA, + LANG_WOLOF, // = 0x88 + LANG_DARI = 0x8C, + LANG_MALAGASY, // = 0x8D + + LANG_SERBIAN_NEUTRAL = 0x7C1A, + LANG_BOSNIAN_NEUTRAL = 0x781A, + + LANG_INVARIANT = 0x7F +} + + +// Sublanguage identifiers +enum : USHORT { + SUBLANG_NEUTRAL, + SUBLANG_DEFAULT, + SUBLANG_SYS_DEFAULT, + SUBLANG_CUSTOM_DEFAULT, // = 3 + SUBLANG_UI_CUSTOM_DEFAULT = 3, + SUBLANG_CUSTOM_UNSPECIFIED, // = 4 + + SUBLANG_AFRIKAANS_SOUTH_AFRICA = 1, + SUBLANG_ALBANIAN_ALBANIA = 1, + SUBLANG_ALSATIAN_FRANCE = 1, + SUBLANG_AMHARIC_ETHIOPIA = 1, + + SUBLANG_ARABIC_SAUDI_ARABIA = 1, + SUBLANG_ARABIC_IRAQ, + SUBLANG_ARABIC_EGYPT, + SUBLANG_ARABIC_LIBYA, + SUBLANG_ARABIC_ALGERIA, + SUBLANG_ARABIC_MOROCCO, + SUBLANG_ARABIC_TUNISIA, + SUBLANG_ARABIC_OMAN, + SUBLANG_ARABIC_YEMEN, + SUBLANG_ARABIC_SYRIA, + SUBLANG_ARABIC_JORDAN, + SUBLANG_ARABIC_LEBANON, + SUBLANG_ARABIC_KUWAIT, + SUBLANG_ARABIC_UAE, + SUBLANG_ARABIC_BAHRAIN, + SUBLANG_ARABIC_QATAR, // = 16 + + SUBLANG_ARMENIAN_ARMENIA = 1, + SUBLANG_ASSAMESE_INDIA = 1, + + SUBLANG_AZERI_LATIN = 1, + SUBLANG_AZERI_CYRILLIC, // = 2 + + SUBLANG_BASHKIR_RUSSIA = 1, + SUBLANG_BASQUE_BASQUE = 1, + SUBLANG_BELARUSIAN_BELARUS = 1, + SUBLANG_BENGALI_INDIA = 1, + + SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN = 5, + SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC = 8, + + SUBLANG_BRETON_FRANCE = 1, + SUBLANG_BULGARIAN_BULGARIA = 1, + SUBLANG_CATALAN_CATALAN = 1, + + SUBLANG_CHINESE_TRADITIONAL = 1, + SUBLANG_CHINESE_SIMPLIFIED, + SUBLANG_CHINESE_HONGKONG, + SUBLANG_CHINESE_SINGAPORE, + SUBLANG_CHINESE_MACAU, // = 5 + + SUBLANG_CORSICAN_FRANCE = 1, + + SUBLANG_CROATIAN_CROATIA = 1, + SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN = 4, + + SUBLANG_CZECH_CZECH_REPUBLIC = 1, + SUBLANG_DANISH_DENMARK = 1, + SUBLANG_DIVEHI_MALDIVES = 1, + + SUBLANG_DUTCH = 1, + SUBLANG_DUTCH_BELGIAN, // = 2 + + SUBLANG_ENGLISH_US = 1, + SUBLANG_ENGLISH_UK, + SUBLANG_ENGLISH_AUS, + SUBLANG_ENGLISH_CAN, + SUBLANG_ENGLISH_NZ, + SUBLANG_ENGLISH_EIRE, // = 6 + SUBLANG_ENGLISH_IRELAND = 6, + SUBLANG_ENGLISH_SOUTH_AFRICA, + SUBLANG_ENGLISH_JAMAICA, + SUBLANG_ENGLISH_CARIBBEAN, + SUBLANG_ENGLISH_BELIZE, + SUBLANG_ENGLISH_TRINIDAD, + SUBLANG_ENGLISH_ZIMBABWE, + SUBLANG_ENGLISH_PHILIPPINES, // = 13 + SUBLANG_ENGLISH_INDIA = 16, + SUBLANG_ENGLISH_MALAYSIA, + SUBLANG_ENGLISH_SINGAPORE, // = 18 + + SUBLANG_ESTONIAN_ESTONIA = 1, + SUBLANG_FAEROESE_FAROE_ISLANDS = 1, + SUBLANG_FILIPINO_PHILIPPINES = 1, + SUBLANG_FINNISH_FINLAND = 1, + + SUBLANG_FRENCH = 1, + SUBLANG_FRENCH_BELGIAN, + SUBLANG_FRENCH_CANADIAN, + SUBLANG_FRENCH_SWISS, + SUBLANG_FRENCH_LUXEMBOURG, + SUBLANG_FRENCH_MONACO, // = 6 + + SUBLANG_FRISIAN_NETHERLANDS = 1, + SUBLANG_GALICIAN_GALICIAN = 1, + SUBLANG_GEORGIAN_GEORGIA = 1, + + SUBLANG_GERMAN = 1, + SUBLANG_GERMAN_SWISS, + SUBLANG_GERMAN_AUSTRIAN, + SUBLANG_GERMAN_LUXEMBOURG, + SUBLANG_GERMAN_LIECHTENSTEIN, // = 5 + + SUBLANG_GREEK_GREECE = 1, + SUBLANG_GREENLANDIC_GREENLAND = 1, + SUBLANG_GUJARATI_INDIA = 1, + SUBLANG_HAUSA_NIGERIA = 1, + SUBLANG_HEBREW_ISRAEL = 1, + SUBLANG_HINDI_INDIA = 1, + SUBLANG_HUNGARIAN_HUNGARY = 1, + SUBLANG_ICELANDIC_ICELAND = 1, + SUBLANG_IGBO_NIGERIA = 1, + SUBLANG_INDONESIAN_INDONESIA = 1, + + SUBLANG_INUKTITUT_CANADA = 1, + SUBLANG_INUKTITUT_CANADA_LATIN = 1, + + SUBLANG_IRISH_IRELAND = 1, + + SUBLANG_ITALIAN = 1, + SUBLANG_ITALIAN_SWISS, // = 2 + + SUBLANG_JAPANESE_JAPAN = 1, + + SUBLANG_KASHMIRI_INDIA = 2, + SUBLANG_KASHMIRI_SASIA = 2, + + SUBLANG_KAZAK_KAZAKHSTAN = 1, + SUBLANG_KHMER_CAMBODIA = 1, + SUBLANG_KICHE_GUATEMALA = 1, + SUBLANG_KINYARWANDA_RWANDA = 1, + SUBLANG_KONKANI_INDIA = 1, + SUBLANG_KOREAN = 1, + SUBLANG_KOREAN_JOHAB = 2, + SUBLANG_KYRGYZ_KYRGYZSTAN = 1, + SUBLANG_LAO_LAO_PDR = 1, + SUBLANG_LATVIAN_LATVIA = 1, + + SUBLANG_LITHUANIAN = 1, + SUBLANG_LITHUANIAN_LITHUANIA = 1, + + SUBLANG_LOWER_SORBIAN_GERMANY = 1, + SUBLANG_LUXEMBOURGISH_LUXEMBOURG = 1, + SUBLANG_MACEDONIAN_MACEDONIA = 1, + SUBLANG_MALAYALAM_INDIA = 1, + SUBLANG_MALTESE_MALTA = 1, + SUBLANG_MAORI_NEW_ZEALAND = 1, + SUBLANG_MAPUDUNGUN_CHILE = 1, + SUBLANG_MARATHI_INDIA = 1, + SUBLANG_MOHAWK_MOHAWK = 1, + + SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA = 1, + SUBLANG_MONGOLIAN_PRC, // = 2 + + SUBLANG_MALAY_MALAYSIA = 1, + SUBLANG_MALAY_BRUNEI_DARUSSALAM, // = 2 + + SUBLANG_NEPALI_NEPAL = 1, + SUBLANG_NEPALI_INDIA, // = 2 + + SUBLANG_NORWEGIAN_BOKMAL = 1, + SUBLANG_NORWEGIAN_NYNORSK, // = 2 + + SUBLANG_OCCITAN_FRANCE = 1, + SUBLANG_ORIYA_INDIA = 1, + SUBLANG_PASHTO_AFGHANISTAN = 1, + SUBLANG_PERSIAN_IRAN = 1, + SUBLANG_POLISH_POLAND = 1, + + SUBLANG_PORTUGUESE_BRAZILIAN = 1, + SUBLANG_PORTUGUESE = 2, + SUBLANG_PORTUGUESE_PORTUGAL, // = 2 + + SUBLANG_PUNJABI_INDIA = 1, + + SUBLANG_QUECHUA_BOLIVIA = 1, + SUBLANG_QUECHUA_ECUADOR, + SUBLANG_QUECHUA_PERU, // = 3 + + SUBLANG_ROMANIAN_ROMANIA = 1, + SUBLANG_ROMANSH_SWITZERLAND = 1, + SUBLANG_RUSSIAN_RUSSIA = 1, + + SUBLANG_SAMI_NORTHERN_NORWAY = 1, + SUBLANG_SAMI_NORTHERN_SWEDEN, + SUBLANG_SAMI_NORTHERN_FINLAND, // = 3 + SUBLANG_SAMI_SKOLT_FINLAND = 3, + SUBLANG_SAMI_INARI_FINLAND = 3, + SUBLANG_SAMI_LULE_NORWAY, + SUBLANG_SAMI_LULE_SWEDEN, + SUBLANG_SAMI_SOUTHERN_NORWAY, + SUBLANG_SAMI_SOUTHERN_SWEDEN, // = 7 + + SUBLANG_SANSKRIT_INDIA = 1, + + SUBLANG_SERBIAN_LATIN = 2, + SUBLANG_SERBIAN_CYRILLIC, // = 3 + SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_LATIN = 6, + SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_CYRILLIC = 7, + + SUBLANG_SINDHI_AFGHANISTAN = 2, + SUBLANG_SINHALESE_SRI_LANKA = 1, + SUBLANG_SOTHO_NORTHERN_SOUTH_AFRICA = 1, + SUBLANG_SLOVAK_SLOVAKIA = 1, + SUBLANG_SLOVENIAN_SLOVENIA = 1, + + SUBLANG_SPANISH = 1, + SUBLANG_SPANISH_MEXICAN, + SUBLANG_SPANISH_MODERN, + SUBLANG_SPANISH_GUATEMALA, + SUBLANG_SPANISH_COSTA_RICA, + SUBLANG_SPANISH_PANAMA, + SUBLANG_SPANISH_DOMINICAN_REPUBLIC, + SUBLANG_SPANISH_VENEZUELA, + SUBLANG_SPANISH_COLOMBIA, + SUBLANG_SPANISH_PERU, + SUBLANG_SPANISH_ARGENTINA, + SUBLANG_SPANISH_ECUADOR, + SUBLANG_SPANISH_CHILE, + SUBLANG_SPANISH_URUGUAY, + SUBLANG_SPANISH_PARAGUAY, + SUBLANG_SPANISH_BOLIVIA, + SUBLANG_SPANISH_EL_SALVADOR, + SUBLANG_SPANISH_HONDURAS, + SUBLANG_SPANISH_NICARAGUA, + SUBLANG_SPANISH_PUERTO_RICO, + SUBLANG_SPANISH_US, // = 21 + + SUBLANG_SWEDISH = 1, + SUBLANG_SWEDISH_SWEDEN = 1, + SUBLANG_SWEDISH_FINLAND, // = 2 + + SUBLANG_SYRIAC = 1, + SUBLANG_TAJIK_TAJIKISTAN = 1, + SUBLANG_TAMAZIGHT_ALGERIA_LATIN = 2, + SUBLANG_TAMIL_INDIA = 1, + SUBLANG_TATAR_RUSSIA = 1, + SUBLANG_TELUGU_INDIA = 1, + SUBLANG_THAI_THAILAND = 1, + SUBLANG_TIBETAN_PRC = 1, + SUBLANG_TIBETAN_BHUTAN = 2, + SUBLANG_TIGRIGNA_ERITREA = 1, + SUBLANG_TSWANA_SOUTH_AFRICA = 1, + SUBLANG_TURKISH_TURKEY = 1, + SUBLANG_TURKMEN_TURKMENISTAN = 1, + SUBLANG_UIGHUR_PRC = 1, + SUBLANG_UKRAINIAN_UKRAINE = 1, + SUBLANG_UPPER_SORBIAN_GERMANY = 1, + + SUBLANG_URDU_PAKISTAN = 1, + SUBLANG_URDU_INDIA, // = 2 + + SUBLANG_UZBEK_LATIN = 1, + SUBLANG_UZBEK_CYRILLIC, // = 2 + + SUBLANG_VIETNAMESE_VIETNAM = 1, + SUBLANG_WELSH_UNITED_KINGDOM = 1, + SUBLANG_WOLOF_SENEGAL = 1, + SUBLANG_YORUBA_NIGERIA = 1, + SUBLANG_XHOSA_SOUTH_AFRICA = 1, + SUBLANG_YAKUT_RUSSIA = 1, + SUBLANG_YI_PRC = 1, + SUBLANG_ZULU_SOUTH_AFRICA = 1 +} + +// This is not documented on MSDN +enum NLS_VALID_LOCALE_MASK = 1048575; + +// Sorting identifiers +enum : WORD { + SORT_DEFAULT = 0, + SORT_JAPANESE_XJIS = 0, + SORT_JAPANESE_UNICODE = 1, + SORT_CHINESE_BIG5 = 0, + SORT_CHINESE_PRCP = 0, + SORT_CHINESE_UNICODE = 1, + SORT_CHINESE_PRC = 2, + SORT_CHINESE_BOPOMOFO = 3, + SORT_KOREAN_KSC = 0, + SORT_KOREAN_UNICODE = 1, + SORT_GERMAN_PHONE_BOOK = 1, + SORT_HUNGARIAN_DEFAULT = 0, + SORT_HUNGARIAN_TECHNICAL = 1, + SORT_GEORGIAN_TRADITIONAL = 0, + SORT_GEORGIAN_MODERN = 1 +} + +pure nothrow @nogc { + WORD MAKELANGID()(/*USHORT*/uint p, /*USHORT*/ uint s) { return cast(WORD)((s << 10) | p); } + WORD PRIMARYLANGID()(/*WORD*/uint lgid) { return cast(WORD)(lgid & 0x3FF); } + WORD SUBLANGID()(/*WORD*/uint lgid) { return cast(WORD)(lgid >>> 10); } + + DWORD MAKELCID()(/*WORD*/uint lgid, /*WORD*/uint srtid) { return (cast(DWORD) srtid << 16) | cast(DWORD) lgid; } + // ??? + //DWORD MAKESORTLCID()(WORD lgid, WORD srtid, WORD ver) { return (MAKELCID(lgid, srtid)) | ((cast(DWORD)ver) << 20); } + WORD LANGIDFROMLCID()(LCID lcid) { return cast(WORD) lcid; } + WORD SORTIDFROMLCID()(LCID lcid) { return cast(WORD) ((lcid >>> 16) & 0x0F); } + WORD SORTVERSIONFROMLCID()(LCID lcid) { return cast(WORD) ((lcid >>> 20) & 0x0F); } +} + +enum WORD LANG_SYSTEM_DEFAULT = (SUBLANG_SYS_DEFAULT << 10) | LANG_NEUTRAL; +enum WORD LANG_USER_DEFAULT = (SUBLANG_DEFAULT << 10) | LANG_NEUTRAL; +enum DWORD LOCALE_NEUTRAL = (SORT_DEFAULT << 16) + | (SUBLANG_NEUTRAL << 10) | LANG_NEUTRAL; + +// --- +enum : BYTE { + ACL_REVISION = 2, + ACL_REVISION_DS = 4 +} + +// These are not documented on MSDN +enum : BYTE { + ACL_REVISION1 = 1, + ACL_REVISION2, + ACL_REVISION3, + ACL_REVISION4 // = 4 +} + +enum BYTE + MIN_ACL_REVISION = 2, + MAX_ACL_REVISION = 4; + +/+ +// These aren't necessary for D. +enum MINCHAR=0x80; +enum MAXCHAR=0x7f; +enum MINSHORT=0x8000; +enum MAXSHORT=0x7fff; +enum MINLONG=0x80000000; +enum MAXLONG=0x7fffffff; +enum MAXBYTE=0xff; +enum MAXWORD=0xffff; +enum MAXDWORD=0xffffffff; ++/ + +// SYSTEM_INFO.dwProcessorType +enum : DWORD { + PROCESSOR_INTEL_386 = 386, + PROCESSOR_INTEL_486 = 486, + PROCESSOR_INTEL_PENTIUM = 586, + PROCESSOR_MIPS_R4000 = 4000, + PROCESSOR_ALPHA_21064 = 21064, + PROCESSOR_INTEL_IA64 = 2200 +} + +// SYSTEM_INFO.wProcessorArchitecture +enum : WORD { + PROCESSOR_ARCHITECTURE_INTEL, + PROCESSOR_ARCHITECTURE_MIPS, + PROCESSOR_ARCHITECTURE_ALPHA, + PROCESSOR_ARCHITECTURE_PPC, + PROCESSOR_ARCHITECTURE_SHX, + PROCESSOR_ARCHITECTURE_ARM, + PROCESSOR_ARCHITECTURE_IA64, + PROCESSOR_ARCHITECTURE_ALPHA64, + PROCESSOR_ARCHITECTURE_MSIL, + PROCESSOR_ARCHITECTURE_AMD64, + PROCESSOR_ARCHITECTURE_IA32_ON_WIN64, // = 10 + PROCESSOR_ARCHITECTURE_UNKNOWN = 0xFFFF +} + +// IsProcessorFeaturePresent() +enum : DWORD { + PF_FLOATING_POINT_PRECISION_ERRATA, + PF_FLOATING_POINT_EMULATED, + PF_COMPARE_EXCHANGE_DOUBLE, + PF_MMX_INSTRUCTIONS_AVAILABLE, + PF_PPC_MOVEMEM_64BIT_OK, + PF_ALPHA_BYTE_INSTRUCTIONS, + PF_XMMI_INSTRUCTIONS_AVAILABLE, + PF_3DNOW_INSTRUCTIONS_AVAILABLE, + PF_RDTSC_INSTRUCTION_AVAILABLE, + PF_PAE_ENABLED, + PF_XMMI64_INSTRUCTIONS_AVAILABLE +} + +// MinGW: also in ddk/ntifs.h +enum : DWORD { + FILE_ACTION_ADDED = 1, + FILE_ACTION_REMOVED, + FILE_ACTION_MODIFIED, + FILE_ACTION_RENAMED_OLD_NAME, + FILE_ACTION_RENAMED_NEW_NAME, + FILE_ACTION_ADDED_STREAM, + FILE_ACTION_REMOVED_STREAM, + FILE_ACTION_MODIFIED_STREAM, + FILE_ACTION_REMOVED_BY_DELETE, + FILE_ACTION_ID_NOT_TUNNELLED, + FILE_ACTION_TUNNELLED_ID_COLLISION // = 11 +} +// MinGW: end ntifs.h + +enum DWORD + HEAP_NO_SERIALIZE = 0x01, + HEAP_GROWABLE = 0x02, + HEAP_GENERATE_EXCEPTIONS = 0x04, + HEAP_ZERO_MEMORY = 0x08, + HEAP_REALLOC_IN_PLACE_ONLY = 0x10, + HEAP_TAIL_CHECKING_ENABLED = 0x20, + HEAP_FREE_CHECKING_ENABLED = 0x40, + HEAP_DISABLE_COALESCE_ON_FREE = 0x80; + +// These are not documented on MSDN +enum HEAP_CREATE_ALIGN_16 = 0; +enum HEAP_CREATE_ENABLE_TRACING = 0x020000; +enum HEAP_MAXIMUM_TAG = 0x000FFF; +enum HEAP_PSEUDO_TAG_FLAG = 0x008000; +enum HEAP_TAG_SHIFT = 16; +// ??? +//MACRO #define HEAP_MAKE_TAG_FLAGS(b,o) ((DWORD)((b)+(o)<<16))) + +enum ACCESS_MASK + KEY_QUERY_VALUE = 0x000001, + KEY_SET_VALUE = 0x000002, + KEY_CREATE_SUB_KEY = 0x000004, + KEY_ENUMERATE_SUB_KEYS = 0x000008, + KEY_NOTIFY = 0x000010, + KEY_CREATE_LINK = 0x000020, + KEY_WRITE = 0x020006, + KEY_EXECUTE = 0x020019, + KEY_READ = 0x020019, + KEY_ALL_ACCESS = 0x0F003F; + +static if (_WIN32_WINNT >= 0x502) { +enum ACCESS_MASK + KEY_WOW64_64KEY = 0x000100, + KEY_WOW64_32KEY = 0x000200; +} + +enum DWORD + REG_WHOLE_HIVE_VOLATILE = 1, + REG_REFRESH_HIVE = 2, + REG_NO_LAZY_FLUSH = 4; + +enum DWORD + REG_OPTION_RESERVED = 0, + REG_OPTION_NON_VOLATILE = 0, + REG_OPTION_VOLATILE = 1, + REG_OPTION_CREATE_LINK = 2, + REG_OPTION_BACKUP_RESTORE = 4, + REG_OPTION_OPEN_LINK = 8, + REG_LEGAL_OPTION = 15; + +enum SECURITY_INFORMATION + OWNER_SECURITY_INFORMATION = 0x00000001, + GROUP_SECURITY_INFORMATION = 0x00000002, + DACL_SECURITY_INFORMATION = 0x00000004, + SACL_SECURITY_INFORMATION = 0x00000008, + LABEL_SECURITY_INFORMATION = 0x00000010, + UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000, + UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000, + PROTECTED_SACL_SECURITY_INFORMATION = 0x40000000, + PROTECTED_DACL_SECURITY_INFORMATION = 0x80000000; + +enum DWORD MAXIMUM_PROCESSORS = 32; + +// VirtualAlloc(), etc +// ------------------- + +enum : DWORD { + PAGE_NOACCESS = 0x0001, + PAGE_READONLY = 0x0002, + PAGE_READWRITE = 0x0004, + PAGE_WRITECOPY = 0x0008, + PAGE_EXECUTE = 0x0010, + PAGE_EXECUTE_READ = 0x0020, + PAGE_EXECUTE_READWRITE = 0x0040, + PAGE_EXECUTE_WRITECOPY = 0x0080, + PAGE_GUARD = 0x0100, + PAGE_NOCACHE = 0x0200 +} + +enum : DWORD { + MEM_COMMIT = 0x00001000, + MEM_RESERVE = 0x00002000, + MEM_DECOMMIT = 0x00004000, + MEM_RELEASE = 0x00008000, + MEM_FREE = 0x00010000, + MEM_PRIVATE = 0x00020000, + MEM_MAPPED = 0x00040000, + MEM_RESET = 0x00080000, + MEM_TOP_DOWN = 0x00100000, + MEM_WRITE_WATCH = 0x00200000, // MinGW (???): 98/Me + MEM_PHYSICAL = 0x00400000, + MEM_4MB_PAGES = 0x80000000 +} + +// MinGW: also in ddk/ntifs.h +// CreateFileMapping() +enum DWORD + SEC_BASED = 0x00200000, + SEC_NO_CHANGE = 0x00400000, + SEC_FILE = 0x00800000, + SEC_IMAGE = 0x01000000, + SEC_VLM = 0x02000000, + SEC_RESERVE = 0x04000000, + SEC_COMMIT = 0x08000000, + SEC_NOCACHE = 0x10000000, + MEM_IMAGE = SEC_IMAGE; +// MinGW: end ntifs.h + +// ??? +enum ACCESS_MASK + SECTION_QUERY = 0x000001, + SECTION_MAP_WRITE = 0x000002, + SECTION_MAP_READ = 0x000004, + SECTION_MAP_EXECUTE = 0x000008, + SECTION_EXTEND_SIZE = 0x000010, + SECTION_ALL_ACCESS = 0x0F001F; + +// These are not documented on MSDN +enum MESSAGE_RESOURCE_UNICODE = 1; +enum RTL_CRITSECT_TYPE = 0; +enum RTL_RESOURCE_TYPE = 1; + +// COFF file format +// ---------------- + +// IMAGE_FILE_HEADER.Characteristics +enum WORD + IMAGE_FILE_RELOCS_STRIPPED = 0x0001, + IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002, + IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004, + IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008, + IMAGE_FILE_AGGRESIVE_WS_TRIM = 0x0010, + IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020, + IMAGE_FILE_BYTES_REVERSED_LO = 0x0080, + IMAGE_FILE_32BIT_MACHINE = 0x0100, + IMAGE_FILE_DEBUG_STRIPPED = 0x0200, + IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400, + IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800, + IMAGE_FILE_SYSTEM = 0x1000, + IMAGE_FILE_DLL = 0x2000, + IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000, + IMAGE_FILE_BYTES_REVERSED_HI = 0x8000; + +// IMAGE_FILE_HEADER.Machine +enum : WORD { + IMAGE_FILE_MACHINE_UNKNOWN = 0x0000, + IMAGE_FILE_MACHINE_I386 = 0x014C, + IMAGE_FILE_MACHINE_R3000 = 0x0162, + IMAGE_FILE_MACHINE_R4000 = 0x0166, + IMAGE_FILE_MACHINE_R10000 = 0x0168, + IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x0169, + IMAGE_FILE_MACHINE_ALPHA = 0x0184, + IMAGE_FILE_MACHINE_SH3 = 0x01A2, + IMAGE_FILE_MACHINE_SH3DSP = 0x01A3, + IMAGE_FILE_MACHINE_SH4 = 0x01A6, + IMAGE_FILE_MACHINE_SH5 = 0x01A8, + IMAGE_FILE_MACHINE_ARM = 0x01C0, + IMAGE_FILE_MACHINE_THUMB = 0x01C2, + IMAGE_FILE_MACHINE_AM33 = 0x01D3, + IMAGE_FILE_MACHINE_POWERPC = 0x01F0, + IMAGE_FILE_MACHINE_POWERPCFP = 0x01F1, + IMAGE_FILE_MACHINE_IA64 = 0x0200, + IMAGE_FILE_MACHINE_MIPS16 = 0x0266, + IMAGE_FILE_MACHINE_MIPSFPU = 0x0366, + IMAGE_FILE_MACHINE_MIPSFPU16 = 0x0466, + IMAGE_FILE_MACHINE_EBC = 0x0EBC, + IMAGE_FILE_MACHINE_AMD64 = 0x8664, + IMAGE_FILE_MACHINE_M32R = 0x9041, + IMAGE_FILE_MACHINE_ARM64 = 0xAA64, +} + +// ??? +enum { + IMAGE_DOS_SIGNATURE = 0x5A4D, + IMAGE_OS2_SIGNATURE = 0x454E, + IMAGE_OS2_SIGNATURE_LE = 0x454C, + IMAGE_VXD_SIGNATURE = 0x454C, + IMAGE_NT_SIGNATURE = 0x4550 +} + +// IMAGE_OPTIONAL_HEADER.Magic +enum : WORD { + IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x010B, + IMAGE_ROM_OPTIONAL_HDR_MAGIC = 0x0107, + IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x020B +} + +// IMAGE_OPTIONAL_HEADER.Subsystem +enum : WORD { + IMAGE_SUBSYSTEM_UNKNOWN = 0, + IMAGE_SUBSYSTEM_NATIVE, + IMAGE_SUBSYSTEM_WINDOWS_GUI, + IMAGE_SUBSYSTEM_WINDOWS_CUI, // = 3 + IMAGE_SUBSYSTEM_OS2_CUI = 5, + IMAGE_SUBSYSTEM_POSIX_CUI = 7, + IMAGE_SUBSYSTEM_NATIVE_WINDOWS, + IMAGE_SUBSYSTEM_WINDOWS_CE_GUI, + IMAGE_SUBSYSTEM_EFI_APPLICATION, + IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER, + IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER, + IMAGE_SUBSYSTEM_EFI_ROM, + IMAGE_SUBSYSTEM_XBOX, // = 14 + IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16 +} + +// IMAGE_OPTIONAL_HEADER.DllCharacteristics +enum WORD + IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040, + IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080, + IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100, + IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200, + IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400, + IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800, + IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000, + IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000; + +// ??? +enum IMAGE_SEPARATE_DEBUG_SIGNATURE = 0x4944; + +enum size_t + IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16, + IMAGE_SIZEOF_ROM_OPTIONAL_HEADER = 56, + IMAGE_SIZEOF_STD_OPTIONAL_HEADER = 28, + IMAGE_SIZEOF_NT_OPTIONAL_HEADER = 224, + IMAGE_SIZEOF_SHORT_NAME = 8, + IMAGE_SIZEOF_SECTION_HEADER = 40, + IMAGE_SIZEOF_SYMBOL = 18, + IMAGE_SIZEOF_AUX_SYMBOL = 18, + IMAGE_SIZEOF_RELOCATION = 10, + IMAGE_SIZEOF_BASE_RELOCATION = 8, + IMAGE_SIZEOF_LINENUMBER = 6, + IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR = 60, + SIZEOF_RFPO_DATA = 16; + +PIMAGE_SECTION_HEADER IMAGE_FIRST_SECTION(PIMAGE_NT_HEADERS h) { + return cast(PIMAGE_SECTION_HEADER) + (cast(ubyte*) &h.OptionalHeader + h.FileHeader.SizeOfOptionalHeader); +} + +// ImageDirectoryEntryToDataEx() +enum : USHORT { + IMAGE_DIRECTORY_ENTRY_EXPORT = 0, + IMAGE_DIRECTORY_ENTRY_IMPORT, + IMAGE_DIRECTORY_ENTRY_RESOURCE, + IMAGE_DIRECTORY_ENTRY_EXCEPTION, + IMAGE_DIRECTORY_ENTRY_SECURITY, + IMAGE_DIRECTORY_ENTRY_BASERELOC, + IMAGE_DIRECTORY_ENTRY_DEBUG, + IMAGE_DIRECTORY_ENTRY_COPYRIGHT, // = 7 + IMAGE_DIRECTORY_ENTRY_ARCHITECTURE = 7, + IMAGE_DIRECTORY_ENTRY_GLOBALPTR, + IMAGE_DIRECTORY_ENTRY_TLS, + IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, + IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT, + IMAGE_DIRECTORY_ENTRY_IAT, + IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT, + IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR, // = 14 +} + +// IMAGE_SECTION_HEADER.Characteristics +enum DWORD + IMAGE_SCN_TYPE_REG = 0x00000000, + IMAGE_SCN_TYPE_DSECT = 0x00000001, + IMAGE_SCN_TYPE_NOLOAD = 0x00000002, + IMAGE_SCN_TYPE_GROUP = 0x00000004, + IMAGE_SCN_TYPE_NO_PAD = 0x00000008, + IMAGE_SCN_TYPE_COPY = 0x00000010, + IMAGE_SCN_CNT_CODE = 0x00000020, + IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040, + IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080, + IMAGE_SCN_LNK_OTHER = 0x00000100, + IMAGE_SCN_LNK_INFO = 0x00000200, + IMAGE_SCN_TYPE_OVER = 0x00000400, + IMAGE_SCN_LNK_REMOVE = 0x00000800, + IMAGE_SCN_LNK_COMDAT = 0x00001000, + IMAGE_SCN_MEM_FARDATA = 0x00008000, + IMAGE_SCN_GPREL = 0x00008000, + IMAGE_SCN_MEM_PURGEABLE = 0x00020000, + IMAGE_SCN_MEM_16BIT = 0x00020000, + IMAGE_SCN_MEM_LOCKED = 0x00040000, + IMAGE_SCN_MEM_PRELOAD = 0x00080000, + IMAGE_SCN_ALIGN_1BYTES = 0x00100000, + IMAGE_SCN_ALIGN_2BYTES = 0x00200000, + IMAGE_SCN_ALIGN_4BYTES = 0x00300000, + IMAGE_SCN_ALIGN_8BYTES = 0x00400000, + IMAGE_SCN_ALIGN_16BYTES = 0x00500000, + IMAGE_SCN_ALIGN_32BYTES = 0x00600000, + IMAGE_SCN_ALIGN_64BYTES = 0x00700000, + IMAGE_SCN_ALIGN_128BYTES = 0x00800000, + IMAGE_SCN_ALIGN_256BYTES = 0x00900000, + IMAGE_SCN_ALIGN_512BYTES = 0x00A00000, + IMAGE_SCN_ALIGN_1024BYTES = 0x00B00000, + IMAGE_SCN_ALIGN_2048BYTES = 0x00C00000, + IMAGE_SCN_ALIGN_4096BYTES = 0x00D00000, + IMAGE_SCN_ALIGN_8192BYTES = 0x00E00000, + IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000, + IMAGE_SCN_MEM_DISCARDABLE = 0x02000000, + IMAGE_SCN_MEM_NOT_CACHED = 0x04000000, + IMAGE_SCN_MEM_NOT_PAGED = 0x08000000, + IMAGE_SCN_MEM_SHARED = 0x10000000, + IMAGE_SCN_MEM_EXECUTE = 0x20000000, + IMAGE_SCN_MEM_READ = 0x40000000, + IMAGE_SCN_MEM_WRITE = 0x80000000; + +/* The following constants are mostlydocumented at + * http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/pecoff.doc + * but don't seem to be defined in the HTML docs. + */ +enum : SHORT { + IMAGE_SYM_UNDEFINED = 0, + IMAGE_SYM_ABSOLUTE = -1, + IMAGE_SYM_DEBUG = -2 +} + +enum : ubyte { + IMAGE_SYM_TYPE_NULL, + IMAGE_SYM_TYPE_VOID, + IMAGE_SYM_TYPE_CHAR, + IMAGE_SYM_TYPE_SHORT, + IMAGE_SYM_TYPE_INT, + IMAGE_SYM_TYPE_LONG, + IMAGE_SYM_TYPE_FLOAT, + IMAGE_SYM_TYPE_DOUBLE, + IMAGE_SYM_TYPE_STRUCT, + IMAGE_SYM_TYPE_UNION, + IMAGE_SYM_TYPE_ENUM, + IMAGE_SYM_TYPE_MOE, + IMAGE_SYM_TYPE_BYTE, + IMAGE_SYM_TYPE_WORD, + IMAGE_SYM_TYPE_UINT, + IMAGE_SYM_TYPE_DWORD // = 15 +} +enum IMAGE_SYM_TYPE_PCODE = 32768; // ??? + +enum : ubyte { + IMAGE_SYM_DTYPE_NULL, + IMAGE_SYM_DTYPE_POINTER, + IMAGE_SYM_DTYPE_FUNCTION, + IMAGE_SYM_DTYPE_ARRAY +} + +enum : BYTE { + IMAGE_SYM_CLASS_END_OF_FUNCTION = 0xFF, + IMAGE_SYM_CLASS_NULL = 0, + IMAGE_SYM_CLASS_AUTOMATIC, + IMAGE_SYM_CLASS_EXTERNAL, + IMAGE_SYM_CLASS_STATIC, + IMAGE_SYM_CLASS_REGISTER, + IMAGE_SYM_CLASS_EXTERNAL_DEF, + IMAGE_SYM_CLASS_LABEL, + IMAGE_SYM_CLASS_UNDEFINED_LABEL, + IMAGE_SYM_CLASS_MEMBER_OF_STRUCT, + IMAGE_SYM_CLASS_ARGUMENT, + IMAGE_SYM_CLASS_STRUCT_TAG, + IMAGE_SYM_CLASS_MEMBER_OF_UNION, + IMAGE_SYM_CLASS_UNION_TAG, + IMAGE_SYM_CLASS_TYPE_DEFINITION, + IMAGE_SYM_CLASS_UNDEFINED_STATIC, + IMAGE_SYM_CLASS_ENUM_TAG, + IMAGE_SYM_CLASS_MEMBER_OF_ENUM, + IMAGE_SYM_CLASS_REGISTER_PARAM, + IMAGE_SYM_CLASS_BIT_FIELD, // = 18 + IMAGE_SYM_CLASS_FAR_EXTERNAL = 68, + IMAGE_SYM_CLASS_BLOCK = 100, + IMAGE_SYM_CLASS_FUNCTION, + IMAGE_SYM_CLASS_END_OF_STRUCT, + IMAGE_SYM_CLASS_FILE, + IMAGE_SYM_CLASS_SECTION, + IMAGE_SYM_CLASS_WEAK_EXTERNAL,// = 105 + IMAGE_SYM_CLASS_CLR_TOKEN = 107 +} + +enum : BYTE { + IMAGE_COMDAT_SELECT_NODUPLICATES = 1, + IMAGE_COMDAT_SELECT_ANY, + IMAGE_COMDAT_SELECT_SAME_SIZE, + IMAGE_COMDAT_SELECT_EXACT_MATCH, + IMAGE_COMDAT_SELECT_ASSOCIATIVE, + IMAGE_COMDAT_SELECT_LARGEST, + IMAGE_COMDAT_SELECT_NEWEST // = 7 +} + +enum : DWORD { + IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY = 1, + IMAGE_WEAK_EXTERN_SEARCH_LIBRARY, + IMAGE_WEAK_EXTERN_SEARCH_ALIAS +} + +enum : WORD { + IMAGE_REL_I386_ABSOLUTE = 0x0000, + IMAGE_REL_I386_DIR16 = 0x0001, + IMAGE_REL_I386_REL16 = 0x0002, + IMAGE_REL_I386_DIR32 = 0x0006, + IMAGE_REL_I386_DIR32NB = 0x0007, + IMAGE_REL_I386_SEG12 = 0x0009, + IMAGE_REL_I386_SECTION = 0x000A, + IMAGE_REL_I386_SECREL = 0x000B, + IMAGE_REL_I386_TOKEN = 0x000C, + IMAGE_REL_I386_SECREL7 = 0x000D, + IMAGE_REL_I386_REL32 = 0x0014 +} + +enum : WORD { + IMAGE_REL_AMD64_ABSOLUTE = 0x0000, + IMAGE_REL_AMD64_ADDR64 = 0x0001, + IMAGE_REL_AMD64_ADDR32 = 0x0002, + IMAGE_REL_AMD64_ADDR32NB = 0x0003, + IMAGE_REL_AMD64_REL32 = 0x0004, + IMAGE_REL_AMD64_REL32_1 = 0x0005, + IMAGE_REL_AMD64_REL32_2 = 0x0006, + IMAGE_REL_AMD64_REL32_3 = 0x0007, + IMAGE_REL_AMD64_REL32_4 = 0x0008, + IMAGE_REL_AMD64_REL32_5 = 0x0009, + IMAGE_REL_AMD64_SECTION = 0x000A, + IMAGE_REL_AMD64_SECREL = 0x000B, + IMAGE_REL_AMD64_SECREL7 = 0x000C, + IMAGE_REL_AMD64_TOKEN = 0x000D, + IMAGE_REL_AMD64_SREL32 = 0x000E, + IMAGE_REL_AMD64_PAIR = 0x000F, + IMAGE_REL_AMD64_SSPAN32 = 0x0010 +} + +enum : WORD { + IMAGE_REL_IA64_ABSOLUTE = 0x0000, + IMAGE_REL_IA64_IMM14 = 0x0001, + IMAGE_REL_IA64_IMM22 = 0x0002, + IMAGE_REL_IA64_IMM64 = 0x0003, + IMAGE_REL_IA64_DIR32 = 0x0004, + IMAGE_REL_IA64_DIR64 = 0x0005, + IMAGE_REL_IA64_PCREL21B = 0x0006, + IMAGE_REL_IA64_PCREL21M = 0x0007, + IMAGE_REL_IA64_PCREL21F = 0x0008, + IMAGE_REL_IA64_GPREL22 = 0x0009, + IMAGE_REL_IA64_LTOFF22 = 0x000A, + IMAGE_REL_IA64_SECTION = 0x000B, + IMAGE_REL_IA64_SECREL22 = 0x000C, + IMAGE_REL_IA64_SECREL64I = 0x000D, + IMAGE_REL_IA64_SECREL32 = 0x000E, + IMAGE_REL_IA64_DIR32NB = 0x0010, + IMAGE_REL_IA64_SREL14 = 0x0011, + IMAGE_REL_IA64_SREL22 = 0x0012, + IMAGE_REL_IA64_SREL32 = 0x0013, + IMAGE_REL_IA64_UREL32 = 0x0014, + IMAGE_REL_IA64_PCREL60X = 0x0015, + IMAGE_REL_IA64_PCREL60B = 0x0016, + IMAGE_REL_IA64_PCREL60F = 0x0017, + IMAGE_REL_IA64_PCREL60I = 0x0018, + IMAGE_REL_IA64_PCREL60M = 0x0019, + IMAGE_REL_IA64_IMMGPREL64 = 0x001A, + IMAGE_REL_IA64_TOKEN = 0x001B, + IMAGE_REL_IA64_GPREL32 = 0x001C, + IMAGE_REL_IA64_ADDEND = 0x001F +} + +enum : WORD { + IMAGE_REL_SH3_ABSOLUTE = 0x0000, + IMAGE_REL_SH3_DIRECT16 = 0x0001, + IMAGE_REL_SH3_DIRECT32 = 0x0002, + IMAGE_REL_SH3_DIRECT8 = 0x0003, + IMAGE_REL_SH3_DIRECT8_WORD = 0x0004, + IMAGE_REL_SH3_DIRECT8_LONG = 0x0005, + IMAGE_REL_SH3_DIRECT4 = 0x0006, + IMAGE_REL_SH3_DIRECT4_WORD = 0x0007, + IMAGE_REL_SH3_DIRECT4_LONG = 0x0008, + IMAGE_REL_SH3_PCREL8_WORD = 0x0009, + IMAGE_REL_SH3_PCREL8_LONG = 0x000A, + IMAGE_REL_SH3_PCREL12_WORD = 0x000B, + IMAGE_REL_SH3_STARTOF_SECTION = 0x000C, + IMAGE_REL_SH3_SIZEOF_SECTION = 0x000D, + IMAGE_REL_SH3_SECTION = 0x000E, + IMAGE_REL_SH3_SECREL = 0x000F, + IMAGE_REL_SH3_DIRECT32_NB = 0x0010, + IMAGE_REL_SH3_GPREL4_LONG = 0x0011, + IMAGE_REL_SH3_TOKEN = 0x0012, + IMAGE_REL_SHM_PCRELPT = 0x0013, + IMAGE_REL_SHM_REFLO = 0x0014, + IMAGE_REL_SHM_REFHALF = 0x0015, + IMAGE_REL_SHM_RELLO = 0x0016, + IMAGE_REL_SHM_RELHALF = 0x0017, + IMAGE_REL_SHM_PAIR = 0x0018, + IMAGE_REL_SHM_NOMODE = 0x8000 +} + +enum : WORD { + IMAGE_REL_M32R_ABSOLUTE = 0x0000, + IMAGE_REL_M32R_ADDR32 = 0x0001, + IMAGE_REL_M32R_ADDR32NB = 0x0002, + IMAGE_REL_M32R_ADDR24 = 0x0003, + IMAGE_REL_M32R_GPREL16 = 0x0004, + IMAGE_REL_M32R_PCREL24 = 0x0005, + IMAGE_REL_M32R_PCREL16 = 0x0006, + IMAGE_REL_M32R_PCREL8 = 0x0007, + IMAGE_REL_M32R_REFHALF = 0x0008, + IMAGE_REL_M32R_REFHI = 0x0009, + IMAGE_REL_M32R_REFLO = 0x000A, + IMAGE_REL_M32R_PAIR = 0x000B, + IMAGE_REL_M32R_SECTION = 0x000C, + IMAGE_REL_M32R_SECREL = 0x000D, + IMAGE_REL_M32R_TOKEN = 0x000E +} + +enum : WORD { + IMAGE_REL_MIPS_ABSOLUTE = 0x0000, + IMAGE_REL_MIPS_REFHALF = 0x0001, + IMAGE_REL_MIPS_REFWORD = 0x0002, + IMAGE_REL_MIPS_JMPADDR = 0x0003, + IMAGE_REL_MIPS_REFHI = 0x0004, + IMAGE_REL_MIPS_REFLO = 0x0005, + IMAGE_REL_MIPS_GPREL = 0x0006, + IMAGE_REL_MIPS_LITERAL = 0x0007, + IMAGE_REL_MIPS_SECTION = 0x000A, + IMAGE_REL_MIPS_SECREL = 0x000B, + IMAGE_REL_MIPS_SECRELLO = 0x000C, + IMAGE_REL_MIPS_SECRELHI = 0x000D, + IMAGE_REL_MIPS_JMPADDR16 = 0x0010, + IMAGE_REL_MIPS_REFWORDNB = 0x0022, + IMAGE_REL_MIPS_PAIR = 0x0025 +} + + +enum : WORD { + IMAGE_REL_ALPHA_ABSOLUTE, + IMAGE_REL_ALPHA_REFLONG, + IMAGE_REL_ALPHA_REFQUAD, + IMAGE_REL_ALPHA_GPREL32, + IMAGE_REL_ALPHA_LITERAL, + IMAGE_REL_ALPHA_LITUSE, + IMAGE_REL_ALPHA_GPDISP, + IMAGE_REL_ALPHA_BRADDR, + IMAGE_REL_ALPHA_HINT, + IMAGE_REL_ALPHA_INLINE_REFLONG, + IMAGE_REL_ALPHA_REFHI, + IMAGE_REL_ALPHA_REFLO, + IMAGE_REL_ALPHA_PAIR, + IMAGE_REL_ALPHA_MATCH, + IMAGE_REL_ALPHA_SECTION, + IMAGE_REL_ALPHA_SECREL, + IMAGE_REL_ALPHA_REFLONGNB, + IMAGE_REL_ALPHA_SECRELLO, + IMAGE_REL_ALPHA_SECRELHI // = 18 +} + +enum : WORD { + IMAGE_REL_PPC_ABSOLUTE, + IMAGE_REL_PPC_ADDR64, + IMAGE_REL_PPC_ADDR32, + IMAGE_REL_PPC_ADDR24, + IMAGE_REL_PPC_ADDR16, + IMAGE_REL_PPC_ADDR14, + IMAGE_REL_PPC_REL24, + IMAGE_REL_PPC_REL14, + IMAGE_REL_PPC_TOCREL16, + IMAGE_REL_PPC_TOCREL14, + IMAGE_REL_PPC_ADDR32NB, + IMAGE_REL_PPC_SECREL, + IMAGE_REL_PPC_SECTION, + IMAGE_REL_PPC_IFGLUE, + IMAGE_REL_PPC_IMGLUE, + IMAGE_REL_PPC_SECREL16, + IMAGE_REL_PPC_REFHI, + IMAGE_REL_PPC_REFLO, + IMAGE_REL_PPC_PAIR // = 18 +} + +// ??? +enum IMAGE_REL_PPC_TYPEMASK = 0x00FF; +enum IMAGE_REL_PPC_NEG = 0x0100; +enum IMAGE_REL_PPC_BRTAKEN = 0x0200; +enum IMAGE_REL_PPC_BRNTAKEN = 0x0400; +enum IMAGE_REL_PPC_TOCDEFN = 0x0800; + +enum { + IMAGE_REL_BASED_ABSOLUTE, + IMAGE_REL_BASED_HIGH, + IMAGE_REL_BASED_LOW, + IMAGE_REL_BASED_HIGHLOW, + IMAGE_REL_BASED_HIGHADJ, + IMAGE_REL_BASED_MIPS_JMPADDR +} +// End of constants documented in pecoff.doc + +enum size_t IMAGE_ARCHIVE_START_SIZE = 8; + +const TCHAR[] + IMAGE_ARCHIVE_START = "!\n", + IMAGE_ARCHIVE_END = "`\n", + IMAGE_ARCHIVE_PAD = "\n", + IMAGE_ARCHIVE_LINKER_MEMBER = "/ ", + IMAGE_ARCHIVE_LONGNAMES_MEMBER = "// "; + +enum IMAGE_ORDINAL_FLAG32 = 0x80000000; + +ulong IMAGE_ORDINAL64()(ulong Ordinal) { return Ordinal & 0xFFFF; } +uint IMAGE_ORDINAL32()(uint Ordinal) { return Ordinal & 0xFFFF; } + +bool IMAGE_SNAP_BY_ORDINAL32(uint Ordinal) { + return (Ordinal & IMAGE_ORDINAL_FLAG32) != 0; +} + +enum ulong IMAGE_ORDINAL_FLAG64 = 0x8000000000000000; + +bool IMAGE_SNAP_BY_ORDINAL64(ulong Ordinal) { + return (Ordinal & IMAGE_ORDINAL_FLAG64) != 0; +} + +// ??? +enum IMAGE_RESOURCE_NAME_IS_STRING = 0x80000000; +enum IMAGE_RESOURCE_DATA_IS_DIRECTORY = 0x80000000; + +enum : DWORD { + IMAGE_DEBUG_TYPE_UNKNOWN, + IMAGE_DEBUG_TYPE_COFF, + IMAGE_DEBUG_TYPE_CODEVIEW, + IMAGE_DEBUG_TYPE_FPO, + IMAGE_DEBUG_TYPE_MISC, + IMAGE_DEBUG_TYPE_EXCEPTION, + IMAGE_DEBUG_TYPE_FIXUP, + IMAGE_DEBUG_TYPE_OMAP_TO_SRC, + IMAGE_DEBUG_TYPE_OMAP_FROM_SRC, + IMAGE_DEBUG_TYPE_BORLAND // = 9 +} + +enum : ubyte { + FRAME_FPO, + FRAME_TRAP, + FRAME_TSS, + FRAME_NONFPO +} + +// ??? +enum IMAGE_DEBUG_MISC_EXENAME = 1; + +// ??? +enum N_BTMASK = 0x000F; +enum N_TMASK = 0x0030; +enum N_TMASK1 = 0x00C0; +enum N_TMASK2 = 0x00F0; +enum N_BTSHFT = 4; +enum N_TSHIFT = 2; + +enum int + IS_TEXT_UNICODE_ASCII16 = 0x0001, + IS_TEXT_UNICODE_STATISTICS = 0x0002, + IS_TEXT_UNICODE_CONTROLS = 0x0004, + IS_TEXT_UNICODE_SIGNATURE = 0x0008, + IS_TEXT_UNICODE_REVERSE_ASCII16 = 0x0010, + IS_TEXT_UNICODE_REVERSE_STATISTICS = 0x0020, + IS_TEXT_UNICODE_REVERSE_CONTROLS = 0x0040, + IS_TEXT_UNICODE_REVERSE_SIGNATURE = 0x0080, + IS_TEXT_UNICODE_ILLEGAL_CHARS = 0x0100, + IS_TEXT_UNICODE_ODD_LENGTH = 0x0200, + IS_TEXT_UNICODE_NULL_BYTES = 0x1000, + IS_TEXT_UNICODE_UNICODE_MASK = 0x000F, + IS_TEXT_UNICODE_REVERSE_MASK = 0x00F0, + IS_TEXT_UNICODE_NOT_UNICODE_MASK = 0x0F00, + IS_TEXT_UNICODE_NOT_ASCII_MASK = 0xF000; + +enum DWORD + SERVICE_KERNEL_DRIVER = 0x0001, + SERVICE_FILE_SYSTEM_DRIVER = 0x0002, + SERVICE_ADAPTER = 0x0004, + SERVICE_RECOGNIZER_DRIVER = 0x0008, + SERVICE_WIN32_OWN_PROCESS = 0x0010, + SERVICE_WIN32_SHARE_PROCESS = 0x0020, + SERVICE_INTERACTIVE_PROCESS = 0x0100, + SERVICE_DRIVER = 0x000B, + SERVICE_WIN32 = 0x0030, + SERVICE_TYPE_ALL = 0x013F; + +enum : DWORD { + SERVICE_BOOT_START = 0, + SERVICE_SYSTEM_START = 1, + SERVICE_AUTO_START = 2, + SERVICE_DEMAND_START = 3, + SERVICE_DISABLED = 4 +} + +enum : DWORD { + SERVICE_ERROR_IGNORE = 0, + SERVICE_ERROR_NORMAL = 1, + SERVICE_ERROR_SEVERE = 2, + SERVICE_ERROR_CRITICAL = 3 +} + + +enum uint + SE_OWNER_DEFAULTED = 0x0001, + SE_GROUP_DEFAULTED = 0x0002, + SE_DACL_PRESENT = 0x0004, + SE_DACL_DEFAULTED = 0x0008, + SE_SACL_PRESENT = 0x0010, + SE_SACL_DEFAULTED = 0x0020, + SE_DACL_AUTO_INHERIT_REQ = 0x0100, + SE_SACL_AUTO_INHERIT_REQ = 0x0200, + SE_DACL_AUTO_INHERITED = 0x0400, + SE_SACL_AUTO_INHERITED = 0x0800, + SE_DACL_PROTECTED = 0x1000, + SE_SACL_PROTECTED = 0x2000, + SE_SELF_RELATIVE = 0x8000; + +enum SECURITY_IMPERSONATION_LEVEL { + SecurityAnonymous, + SecurityIdentification, + SecurityImpersonation, + SecurityDelegation +} +alias SECURITY_IMPERSONATION_LEVEL* PSECURITY_IMPERSONATION_LEVEL; + +alias BOOLEAN SECURITY_CONTEXT_TRACKING_MODE; +alias BOOLEAN* PSECURITY_CONTEXT_TRACKING_MODE; + +enum size_t SECURITY_DESCRIPTOR_MIN_LENGTH = 20; + +enum DWORD + SECURITY_DESCRIPTOR_REVISION = 1, + SECURITY_DESCRIPTOR_REVISION1 = 1; + +enum DWORD + SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001, + SE_PRIVILEGE_ENABLED = 0x00000002, + SE_PRIVILEGE_USED_FOR_ACCESS = 0x80000000; + +enum DWORD PRIVILEGE_SET_ALL_NECESSARY = 1; + +enum SECURITY_IMPERSONATION_LEVEL + SECURITY_MAX_IMPERSONATION_LEVEL = SECURITY_IMPERSONATION_LEVEL.SecurityDelegation, + DEFAULT_IMPERSONATION_LEVEL = SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation; + +enum BOOLEAN + SECURITY_DYNAMIC_TRACKING = true, + SECURITY_STATIC_TRACKING = false; + +// also in ddk/ntifs.h +enum DWORD + TOKEN_ASSIGN_PRIMARY = 0x0001, + TOKEN_DUPLICATE = 0x0002, + TOKEN_IMPERSONATE = 0x0004, + TOKEN_QUERY = 0x0008, + TOKEN_QUERY_SOURCE = 0x0010, + TOKEN_ADJUST_PRIVILEGES = 0x0020, + TOKEN_ADJUST_GROUPS = 0x0040, + TOKEN_ADJUST_DEFAULT = 0x0080, + + TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED + | TOKEN_ASSIGN_PRIMARY + | TOKEN_DUPLICATE + | TOKEN_IMPERSONATE + | TOKEN_QUERY + | TOKEN_QUERY_SOURCE + | TOKEN_ADJUST_PRIVILEGES + | TOKEN_ADJUST_GROUPS + | TOKEN_ADJUST_DEFAULT, + TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY, + TOKEN_WRITE = STANDARD_RIGHTS_WRITE + | TOKEN_ADJUST_PRIVILEGES + | TOKEN_ADJUST_GROUPS + | TOKEN_ADJUST_DEFAULT, + TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE; + +enum size_t TOKEN_SOURCE_LENGTH = 8; +// end ddk/ntifs.h + +enum : DWORD { + DLL_PROCESS_DETACH, + DLL_PROCESS_ATTACH, + DLL_THREAD_ATTACH, + DLL_THREAD_DETACH +} + +enum : DWORD { + DBG_CONTINUE = 0x00010002, + DBG_TERMINATE_THREAD = 0x40010003, + DBG_TERMINATE_PROCESS = 0x40010004, + DBG_CONTROL_C = 0x40010005, + DBG_CONTROL_BREAK = 0x40010008, + DBG_EXCEPTION_NOT_HANDLED = 0x80010001 +} + +enum : DWORD { + TAPE_ABSOLUTE_POSITION, + TAPE_LOGICAL_POSITION, + TAPE_PSEUDO_LOGICAL_POSITION +} + +enum : DWORD { + TAPE_REWIND, + TAPE_ABSOLUTE_BLOCK, + TAPE_LOGICAL_BLOCK, + TAPE_PSEUDO_LOGICAL_BLOCK, + TAPE_SPACE_END_OF_DATA, + TAPE_SPACE_RELATIVE_BLOCKS, + TAPE_SPACE_FILEMARKS, + TAPE_SPACE_SEQUENTIAL_FMKS, + TAPE_SPACE_SETMARKS, + TAPE_SPACE_SEQUENTIAL_SMKS +} + +enum DWORD + TAPE_DRIVE_FIXED = 0x00000001, + TAPE_DRIVE_SELECT = 0x00000002, + TAPE_DRIVE_INITIATOR = 0x00000004, + TAPE_DRIVE_ERASE_SHORT = 0x00000010, + TAPE_DRIVE_ERASE_LONG = 0x00000020, + TAPE_DRIVE_ERASE_BOP_ONLY = 0x00000040, + TAPE_DRIVE_ERASE_IMMEDIATE = 0x00000080, + TAPE_DRIVE_TAPE_CAPACITY = 0x00000100, + TAPE_DRIVE_TAPE_REMAINING = 0x00000200, + TAPE_DRIVE_FIXED_BLOCK = 0x00000400, + TAPE_DRIVE_VARIABLE_BLOCK = 0x00000800, + TAPE_DRIVE_WRITE_PROTECT = 0x00001000, + TAPE_DRIVE_EOT_WZ_SIZE = 0x00002000, + TAPE_DRIVE_ECC = 0x00010000, + TAPE_DRIVE_COMPRESSION = 0x00020000, + TAPE_DRIVE_PADDING = 0x00040000, + TAPE_DRIVE_REPORT_SMKS = 0x00080000, + TAPE_DRIVE_GET_ABSOLUTE_BLK = 0x00100000, + TAPE_DRIVE_GET_LOGICAL_BLK = 0x00200000, + TAPE_DRIVE_SET_EOT_WZ_SIZE = 0x00400000, + TAPE_DRIVE_EJECT_MEDIA = 0x01000000, + TAPE_DRIVE_CLEAN_REQUESTS = 0x02000000, + TAPE_DRIVE_SET_CMP_BOP_ONLY = 0x04000000, + TAPE_DRIVE_RESERVED_BIT = 0x80000000; + +enum DWORD + TAPE_DRIVE_LOAD_UNLOAD = 0x80000001, + TAPE_DRIVE_TENSION = 0x80000002, + TAPE_DRIVE_LOCK_UNLOCK = 0x80000004, + TAPE_DRIVE_REWIND_IMMEDIATE = 0x80000008, + TAPE_DRIVE_SET_BLOCK_SIZE = 0x80000010, + TAPE_DRIVE_LOAD_UNLD_IMMED = 0x80000020, + TAPE_DRIVE_TENSION_IMMED = 0x80000040, + TAPE_DRIVE_LOCK_UNLK_IMMED = 0x80000080, + TAPE_DRIVE_SET_ECC = 0x80000100, + TAPE_DRIVE_SET_COMPRESSION = 0x80000200, + TAPE_DRIVE_SET_PADDING = 0x80000400, + TAPE_DRIVE_SET_REPORT_SMKS = 0x80000800, + TAPE_DRIVE_ABSOLUTE_BLK = 0x80001000, + TAPE_DRIVE_ABS_BLK_IMMED = 0x80002000, + TAPE_DRIVE_LOGICAL_BLK = 0x80004000, + TAPE_DRIVE_LOG_BLK_IMMED = 0x80008000, + TAPE_DRIVE_END_OF_DATA = 0x80010000, + TAPE_DRIVE_RELATIVE_BLKS = 0x80020000, + TAPE_DRIVE_FILEMARKS = 0x80040000, + TAPE_DRIVE_SEQUENTIAL_FMKS = 0x80080000, + TAPE_DRIVE_SETMARKS = 0x80100000, + TAPE_DRIVE_SEQUENTIAL_SMKS = 0x80200000, + TAPE_DRIVE_REVERSE_POSITION = 0x80400000, + TAPE_DRIVE_SPACE_IMMEDIATE = 0x80800000, + TAPE_DRIVE_WRITE_SETMARKS = 0x81000000, + TAPE_DRIVE_WRITE_FILEMARKS = 0x82000000, + TAPE_DRIVE_WRITE_SHORT_FMKS = 0x84000000, + TAPE_DRIVE_WRITE_LONG_FMKS = 0x88000000, + TAPE_DRIVE_WRITE_MARK_IMMED = 0x90000000, + TAPE_DRIVE_FORMAT = 0xA0000000, + TAPE_DRIVE_FORMAT_IMMEDIATE = 0xC0000000, + TAPE_DRIVE_HIGH_FEATURES = 0x80000000; + +enum : DWORD { + TAPE_FIXED_PARTITIONS = 0, + TAPE_SELECT_PARTITIONS = 1, + TAPE_INITIATOR_PARTITIONS = 2 +} + +enum : DWORD { + TAPE_SETMARKS, + TAPE_FILEMARKS, + TAPE_SHORT_FILEMARKS, + TAPE_LONG_FILEMARKS +} + +enum : DWORD { + TAPE_ERASE_SHORT, + TAPE_ERASE_LONG +} + +enum : DWORD { + TAPE_LOAD, + TAPE_UNLOAD, + TAPE_TENSION, + TAPE_LOCK, + TAPE_UNLOCK, + TAPE_FORMAT +} + +enum : ULONG32 { + VER_PLATFORM_WIN32s, + VER_PLATFORM_WIN32_WINDOWS, + VER_PLATFORM_WIN32_NT +} + +enum : UCHAR { + VER_NT_WORKSTATION = 1, + VER_NT_DOMAIN_CONTROLLER, + VER_NT_SERVER +} + +enum USHORT + VER_SUITE_SMALLBUSINESS = 0x0001, + VER_SUITE_ENTERPRISE = 0x0002, + VER_SUITE_BACKOFFICE = 0x0004, + VER_SUITE_TERMINAL = 0x0010, + VER_SUITE_SMALLBUSINESS_RESTRICTED = 0x0020, + VER_SUITE_EMBEDDEDNT = 0x0040, + VER_SUITE_DATACENTER = 0x0080, + VER_SUITE_SINGLEUSERTS = 0x0100, + VER_SUITE_PERSONAL = 0x0200, + VER_SUITE_BLADE = 0x0400, + VER_SUITE_STORAGE_SERVER = 0x2000, + VER_SUITE_COMPUTE_SERVER = 0x4000; + +enum ULONG + WT_EXECUTEDEFAULT = 0x00000000, + WT_EXECUTEINIOTHREAD = 0x00000001, + WT_EXECUTEINWAITTHREAD = 0x00000004, + WT_EXECUTEONLYONCE = 0x00000008, + WT_EXECUTELONGFUNCTION = 0x00000010, + WT_EXECUTEINTIMERTHREAD = 0x00000020, + WT_EXECUTEINPERSISTENTTHREAD = 0x00000080, + WT_TRANSFER_IMPERSONATION = 0x00000100; + +static if (_WIN32_WINNT >= 0x500) { +enum DWORD + VER_MINORVERSION = 0x01, + VER_MAJORVERSION = 0x02, + VER_BUILDNUMBER = 0x04, + VER_PLATFORMID = 0x08, + VER_SERVICEPACKMINOR = 0x10, + VER_SERVICEPACKMAJOR = 0x20, + VER_SUITENAME = 0x40, + VER_PRODUCT_TYPE = 0x80; + + enum : DWORD { + VER_EQUAL = 1, + VER_GREATER, + VER_GREATER_EQUAL, + VER_LESS, + VER_LESS_EQUAL, + VER_AND, + VER_OR // = 7 + } +} + +static if (_WIN32_WINNT >= 0x501) { + enum : ULONG { + ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION = 1, + ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, + ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, + ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION, + ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION, + ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION, + ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION, // = 7 + ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES = 9 + } +} + +// Macros +BYTE BTYPE()(BYTE x) { return cast(BYTE) (x & N_BTMASK); } +bool ISPTR()(uint x) { return (x & N_TMASK) == (IMAGE_SYM_DTYPE_POINTER << N_BTSHFT); } +bool ISFCN()(uint x) { return (x & N_TMASK) == (IMAGE_SYM_DTYPE_FUNCTION << N_BTSHFT); } +bool ISARY()(uint x) { return (x & N_TMASK) == (IMAGE_SYM_DTYPE_ARRAY << N_BTSHFT); } +bool ISTAG(uint x) { + return x == IMAGE_SYM_CLASS_STRUCT_TAG + || x == IMAGE_SYM_CLASS_UNION_TAG + || x == IMAGE_SYM_CLASS_ENUM_TAG; +} +uint INCREF(uint x) { + return ((x & ~N_BTMASK) << N_TSHIFT) | (IMAGE_SYM_DTYPE_POINTER << N_BTSHFT) + | (x & N_BTMASK); +} +uint DECREF()(uint x) { return ((x >>> N_TSHIFT) & ~N_BTMASK) | (x & N_BTMASK); } + +enum DWORD TLS_MINIMUM_AVAILABLE = 64; + +enum ULONG + IO_REPARSE_TAG_RESERVED_ZERO = 0, + IO_REPARSE_TAG_RESERVED_ONE = 1, + IO_REPARSE_TAG_RESERVED_RANGE = IO_REPARSE_TAG_RESERVED_ONE, + IO_REPARSE_TAG_SYMBOLIC_LINK = IO_REPARSE_TAG_RESERVED_ZERO, + IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003, + IO_REPARSE_TAG_SYMLINK = 0xA000000C, + IO_REPARSE_TAG_VALID_VALUES = 0xE000FFFF; + +/* Although these are semantically boolean, they are documented and + * implemented to return ULONG; this behaviour is preserved for compatibility + */ +ULONG IsReparseTagMicrosoft()(ULONG x) { return x & 0x80000000; } +ULONG IsReparseTagHighLatency()(ULONG x) { return x & 0x40000000; } +ULONG IsReparseTagNameSurrogate()(ULONG x) { return x & 0x20000000; } + +bool IsReparseTagValid(ULONG x) { + return !(x & ~IO_REPARSE_TAG_VALID_VALUES) && (x > IO_REPARSE_TAG_RESERVED_RANGE); +} + +// Doesn't seem to make sense, but anyway.... +ULONG WT_SET_MAX_THREADPOOL_THREADS(ref ULONG Flags, ushort Limit) { + return Flags |= Limit << 16; +} + +import urt.internal.sys.windows.basetyps; +/* also in urt.internal.sys.windows.basetyps +struct GUID { + uint Data1; + ushort Data2; + ushort Data3; + ubyte Data4[8]; +} +alias GUID* REFGUID, LPGUID; +*/ + +struct GENERIC_MAPPING { + ACCESS_MASK GenericRead; + ACCESS_MASK GenericWrite; + ACCESS_MASK GenericExecute; + ACCESS_MASK GenericAll; +} +alias GENERIC_MAPPING* PGENERIC_MAPPING; + +struct ACE_HEADER { + BYTE AceType; + BYTE AceFlags; + WORD AceSize; +} +alias ACE_HEADER* PACE_HEADER; + +struct ACCESS_ALLOWED_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD SidStart; +} +alias ACCESS_ALLOWED_ACE* PACCESS_ALLOWED_ACE; + +struct ACCESS_DENIED_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD SidStart; +} +alias ACCESS_DENIED_ACE* PACCESS_DENIED_ACE; + +struct SYSTEM_AUDIT_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD SidStart; +} +alias SYSTEM_AUDIT_ACE *PSYSTEM_AUDIT_ACE; + +struct SYSTEM_ALARM_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD SidStart; +} +alias SYSTEM_ALARM_ACE* PSYSTEM_ALARM_ACE; + +struct ACCESS_ALLOWED_OBJECT_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD Flags; + GUID ObjectType; + GUID InheritedObjectType; + DWORD SidStart; +} +alias ACCESS_ALLOWED_OBJECT_ACE* PACCESS_ALLOWED_OBJECT_ACE; + +struct ACCESS_DENIED_OBJECT_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD Flags; + GUID ObjectType; + GUID InheritedObjectType; + DWORD SidStart; +} +alias ACCESS_DENIED_OBJECT_ACE* PACCESS_DENIED_OBJECT_ACE; + +struct SYSTEM_AUDIT_OBJECT_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD Flags; + GUID ObjectType; + GUID InheritedObjectType; + DWORD SidStart; +} +alias SYSTEM_AUDIT_OBJECT_ACE* PSYSTEM_AUDIT_OBJECT_ACE; + +struct SYSTEM_ALARM_OBJECT_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD Flags; + GUID ObjectType; + GUID InheritedObjectType; + DWORD SidStart; +} +alias SYSTEM_ALARM_OBJECT_ACE* PSYSTEM_ALARM_OBJECT_ACE; + +struct ACL { + BYTE AclRevision; + BYTE Sbz1; + WORD AclSize; + WORD AceCount; + WORD Sbz2; +} +alias ACL* PACL; + +struct ACL_REVISION_INFORMATION { + DWORD AclRevision; +} + +struct ACL_SIZE_INFORMATION { + DWORD AceCount; + DWORD AclBytesInUse; + DWORD AclBytesFree; +} + +version (X86) { + // ??? +enum SIZE_OF_80387_REGISTERS = 80; +enum CONTEXT_i386 = 0x010000; +enum CONTEXT_i486 = 0x010000; +enum CONTEXT_CONTROL = CONTEXT_i386 | 0x01; +enum CONTEXT_INTEGER = CONTEXT_i386 | 0x02; +enum CONTEXT_SEGMENTS = CONTEXT_i386 | 0x04; +enum CONTEXT_FLOATING_POINT = CONTEXT_i386 | 0x08; +enum CONTEXT_DEBUG_REGISTERS = CONTEXT_i386 | 0x10; +enum CONTEXT_EXTENDED_REGISTERS = CONTEXT_i386 | 0x20; +enum CONTEXT_FULL = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS; +enum CONTEXT_ALL = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | + CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | + CONTEXT_EXTENDED_REGISTERS; + +enum MAXIMUM_SUPPORTED_EXTENSION = 512; + + struct FLOATING_SAVE_AREA { + DWORD ControlWord; + DWORD StatusWord; + DWORD TagWord; + DWORD ErrorOffset; + DWORD ErrorSelector; + DWORD DataOffset; + DWORD DataSelector; + BYTE[80] RegisterArea; + DWORD Cr0NpxState; + } + + struct CONTEXT { + DWORD ContextFlags; + DWORD Dr0; + DWORD Dr1; + DWORD Dr2; + DWORD Dr3; + DWORD Dr6; + DWORD Dr7; + FLOATING_SAVE_AREA FloatSave; + DWORD SegGs; + DWORD SegFs; + DWORD SegEs; + DWORD SegDs; + DWORD Edi; + DWORD Esi; + DWORD Ebx; + DWORD Edx; + DWORD Ecx; + DWORD Eax; + DWORD Ebp; + DWORD Eip; + DWORD SegCs; + DWORD EFlags; + DWORD Esp; + DWORD SegSs; + BYTE[MAXIMUM_SUPPORTED_EXTENSION] ExtendedRegisters; + } + +} else version (X86_64) +{ +enum CONTEXT_AMD64 = 0x100000; + +enum CONTEXT_CONTROL = (CONTEXT_AMD64 | 0x1L); +enum CONTEXT_INTEGER = (CONTEXT_AMD64 | 0x2L); +enum CONTEXT_SEGMENTS = (CONTEXT_AMD64 | 0x4L); +enum CONTEXT_FLOATING_POINT = (CONTEXT_AMD64 | 0x8L); +enum CONTEXT_DEBUG_REGISTERS = (CONTEXT_AMD64 | 0x10L); + +enum CONTEXT_FULL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT); +enum CONTEXT_ALL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS); + +enum CONTEXT_EXCEPTION_ACTIVE = 0x8000000; +enum CONTEXT_SERVICE_ACTIVE = 0x10000000; +enum CONTEXT_EXCEPTION_REQUEST = 0x40000000; +enum CONTEXT_EXCEPTION_REPORTING = 0x80000000; + +enum INITIAL_MXCSR = 0x1f80; +enum INITIAL_FPCSR = 0x027f; + + align(16) struct M128A + { + ULONGLONG Low; + LONGLONG High; + } + alias M128A* PM128A; + + struct XMM_SAVE_AREA32 + { + WORD ControlWord; + WORD StatusWord; + BYTE TagWord; + BYTE Reserved1; + WORD ErrorOpcode; + DWORD ErrorOffset; + WORD ErrorSelector; + WORD Reserved2; + DWORD DataOffset; + WORD DataSelector; + WORD Reserved3; + DWORD MxCsr; + DWORD MxCsr_Mask; + M128A[8] FloatRegisters; + M128A[16] XmmRegisters; + BYTE[96] Reserved4; + } + alias XMM_SAVE_AREA32 PXMM_SAVE_AREA32; +enum LEGACY_SAVE_AREA_LENGTH = XMM_SAVE_AREA32.sizeof; + + align(16) struct CONTEXT + { + DWORD64 P1Home; + DWORD64 P2Home; + DWORD64 P3Home; + DWORD64 P4Home; + DWORD64 P5Home; + DWORD64 P6Home; + DWORD ContextFlags; + DWORD MxCsr; + WORD SegCs; + WORD SegDs; + WORD SegEs; + WORD SegFs; + WORD SegGs; + WORD SegSs; + DWORD EFlags; + DWORD64 Dr0; + DWORD64 Dr1; + DWORD64 Dr2; + DWORD64 Dr3; + DWORD64 Dr6; + DWORD64 Dr7; + DWORD64 Rax; + DWORD64 Rcx; + DWORD64 Rdx; + DWORD64 Rbx; + DWORD64 Rsp; + DWORD64 Rbp; + DWORD64 Rsi; + DWORD64 Rdi; + DWORD64 R8; + DWORD64 R9; + DWORD64 R10; + DWORD64 R11; + DWORD64 R12; + DWORD64 R13; + DWORD64 R14; + DWORD64 R15; + DWORD64 Rip; + union + { + XMM_SAVE_AREA32 FltSave; + XMM_SAVE_AREA32 FloatSave; + struct + { + M128A[2] Header; + M128A[8] Legacy; + M128A Xmm0; + M128A Xmm1; + M128A Xmm2; + M128A Xmm3; + M128A Xmm4; + M128A Xmm5; + M128A Xmm6; + M128A Xmm7; + M128A Xmm8; + M128A Xmm9; + M128A Xmm10; + M128A Xmm11; + M128A Xmm12; + M128A Xmm13; + M128A Xmm14; + M128A Xmm15; + } + } + M128A[26] VectorRegister; + DWORD64 VectorControl; + DWORD64 DebugControl; + DWORD64 LastBranchToRip; + DWORD64 LastBranchFromRip; + DWORD64 LastExceptionToRip; + DWORD64 LastExceptionFromRip; + } + +} else version(AArch64) { + enum CONTEXT_ARM64 = 0x400000; + + enum CONTEXT_CONTROL = (CONTEXT_ARM64 | 0x1L); + enum CONTEXT_INTEGER = (CONTEXT_ARM64 | 0x2L); + enum CONTEXT_SEGMENTS = (CONTEXT_ARM64 | 0x4L); + enum CONTEXT_FLOATING_POINT = (CONTEXT_ARM64 | 0x8L); + enum CONTEXT_DEBUG_REGISTERS = (CONTEXT_ARM64 | 0x10L); + + enum CONTEXT_FULL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT); + enum CONTEXT_ALL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS); + + enum ARM64_MAX_BREAKPOINTS = 8; + enum ARM64_MAX_WATCHPOINTS = 2; + + union ARM64_NT_NEON128 { + struct { + ULONGLONG Low; + LONGLONG High; + }; + double[2] D; + float[4] S; + WORD[8] H; + BYTE[16] B; + } + alias PARM64_NT_NEON128 = ARM64_NT_NEON128*; + + align(16) struct CONTEXT + { + DWORD ContextFlags; + DWORD Cpsr; + DWORD64[31] X; + DWORD64 Sp; + DWORD64 Pc; + + ARM64_NT_NEON128[32] V; + DWORD Fpcr; + + DWORD Fpsr; + + DWORD[ARM64_MAX_BREAKPOINTS] Bcr; + DWORD64[ARM64_MAX_BREAKPOINTS] Bvr; + DWORD[ARM64_MAX_WATCHPOINTS] Wcr; + DWORD64[ARM64_MAX_WATCHPOINTS] Wvr; + } +} else { + static assert(false, "Unsupported CPU"); + // Versions for PowerPC, Alpha, SHX, and MIPS removed. +} + +alias CONTEXT* PCONTEXT, LPCONTEXT; + +struct EXCEPTION_RECORD { + DWORD ExceptionCode; + DWORD ExceptionFlags; + EXCEPTION_RECORD* ExceptionRecord; + PVOID ExceptionAddress; + DWORD NumberParameters; + ULONG_PTR[EXCEPTION_MAXIMUM_PARAMETERS] ExceptionInformation; +} +alias EXCEPTION_RECORD* PEXCEPTION_RECORD, LPEXCEPTION_RECORD; + +struct EXCEPTION_POINTERS { + PEXCEPTION_RECORD ExceptionRecord; + PCONTEXT ContextRecord; +} +alias EXCEPTION_POINTERS* PEXCEPTION_POINTERS, LPEXCEPTION_POINTERS; + +union LARGE_INTEGER { + struct { + uint LowPart; + int HighPart; + } + long QuadPart; +} +alias LARGE_INTEGER* PLARGE_INTEGER; + +union ULARGE_INTEGER { + struct { + uint LowPart; + uint HighPart; + } + ulong QuadPart; +} +alias ULARGE_INTEGER* PULARGE_INTEGER; + +alias LARGE_INTEGER LUID; +alias LUID* PLUID; + +enum LUID SYSTEM_LUID = { QuadPart:999 }; + +align(4) struct LUID_AND_ATTRIBUTES { + LUID Luid; + DWORD Attributes; +} +alias LUID_AND_ATTRIBUTES* PLUID_AND_ATTRIBUTES; + +align(4) struct PRIVILEGE_SET { + DWORD PrivilegeCount; + DWORD Control; + LUID_AND_ATTRIBUTES _Privilege; + + LUID_AND_ATTRIBUTES* Privilege() return { return &_Privilege; } +} +alias PRIVILEGE_SET* PPRIVILEGE_SET; + +struct SECURITY_ATTRIBUTES { + DWORD nLength; + LPVOID lpSecurityDescriptor; + BOOL bInheritHandle; +} +alias SECURITY_ATTRIBUTES* PSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES; + +struct SECURITY_QUALITY_OF_SERVICE { + DWORD Length; + SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; + SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode; + BOOLEAN EffectiveOnly; +} +alias SECURITY_QUALITY_OF_SERVICE* PSECURITY_QUALITY_OF_SERVICE; + +alias PVOID PACCESS_TOKEN; + +struct SE_IMPERSONATION_STATE { + PACCESS_TOKEN Token; + BOOLEAN CopyOnOpen; + BOOLEAN EffectiveOnly; + SECURITY_IMPERSONATION_LEVEL Level; +} +alias SE_IMPERSONATION_STATE* PSE_IMPERSONATION_STATE; + +struct SID_IDENTIFIER_AUTHORITY { + BYTE[6] Value; +} +alias SID_IDENTIFIER_AUTHORITY* PSID_IDENTIFIER_AUTHORITY, LPSID_IDENTIFIER_AUTHORITY; + +alias PVOID PSID; + +struct SID { + BYTE Revision; + BYTE SubAuthorityCount; + SID_IDENTIFIER_AUTHORITY IdentifierAuthority; + DWORD _SubAuthority; + + DWORD* SubAuthority() return { return &_SubAuthority; } +} +alias SID* PISID; + +struct SID_AND_ATTRIBUTES { + PSID Sid; + DWORD Attributes; +} +alias SID_AND_ATTRIBUTES* PSID_AND_ATTRIBUTES; + +struct TOKEN_SOURCE { + CHAR[TOKEN_SOURCE_LENGTH] SourceName = 0; + LUID SourceIdentifier; +} +alias TOKEN_SOURCE* PTOKEN_SOURCE; + +struct TOKEN_CONTROL { + LUID TokenId; + LUID AuthenticationId; + LUID ModifiedId; + TOKEN_SOURCE TokenSource; +} +alias TOKEN_CONTROL* PTOKEN_CONTROL; + +struct TOKEN_DEFAULT_DACL { + PACL DefaultDacl; +} +alias TOKEN_DEFAULT_DACL* PTOKEN_DEFAULT_DACL; + +struct TOKEN_GROUPS { + DWORD GroupCount; + SID_AND_ATTRIBUTES _Groups; + + SID_AND_ATTRIBUTES* Groups() return { return &_Groups; } +} +alias TOKEN_GROUPS* PTOKEN_GROUPS, LPTOKEN_GROUPS; + +struct TOKEN_OWNER { + PSID Owner; +} +alias TOKEN_OWNER* PTOKEN_OWNER; +enum SECURITY_MAX_SID_SIZE = 68; + +struct TOKEN_PRIMARY_GROUP { + PSID PrimaryGroup; +} +alias TOKEN_PRIMARY_GROUP* PTOKEN_PRIMARY_GROUP; + +struct TOKEN_PRIVILEGES { + DWORD PrivilegeCount; + LUID_AND_ATTRIBUTES _Privileges; + + LUID_AND_ATTRIBUTES* Privileges() return { return &_Privileges; } +} +alias TOKEN_PRIVILEGES* PTOKEN_PRIVILEGES, LPTOKEN_PRIVILEGES; + +enum TOKEN_TYPE { + TokenPrimary = 1, + TokenImpersonation +} +alias TOKEN_TYPE* PTOKEN_TYPE; + +struct TOKEN_STATISTICS { + LUID TokenId; + LUID AuthenticationId; + LARGE_INTEGER ExpirationTime; + TOKEN_TYPE TokenType; + SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; + DWORD DynamicCharged; + DWORD DynamicAvailable; + DWORD GroupCount; + DWORD PrivilegeCount; + LUID ModifiedId; +} +alias TOKEN_STATISTICS* PTOKEN_STATISTICS; + +struct TOKEN_USER { + SID_AND_ATTRIBUTES User; +} +alias TOKEN_USER* PTOKEN_USER; + +struct TOKEN_MANDATORY_LABEL { + SID_AND_ATTRIBUTES Label; +} +alias PTOKEN_MANDATORY_LABEL = TOKEN_MANDATORY_LABEL*; +alias DWORD SECURITY_INFORMATION; +alias SECURITY_INFORMATION* PSECURITY_INFORMATION; +alias WORD SECURITY_DESCRIPTOR_CONTROL; +alias SECURITY_DESCRIPTOR_CONTROL* PSECURITY_DESCRIPTOR_CONTROL; + +struct SECURITY_DESCRIPTOR { + BYTE Revision; + BYTE Sbz1; + SECURITY_DESCRIPTOR_CONTROL Control; + PSID Owner; + PSID Group; + PACL Sacl; + PACL Dacl; +} +alias SECURITY_DESCRIPTOR* PSECURITY_DESCRIPTOR, PISECURITY_DESCRIPTOR; +enum TOKEN_ELEVATION_TYPE { + TokenElevationTypeDefault = 1, + TokenElevationTypeFull, + TokenElevationTypeLimited +} + +alias PTOKEN_ELEVATION_TYPE = TOKEN_ELEVATION_TYPE*; + +struct TOKEN_ELEVATION { + DWORD TokenIsElevated; +} +alias PTOKEN_ELEVATION = TOKEN_ELEVATION*; + +enum TOKEN_INFORMATION_CLASS { + TokenUser = 1, + TokenGroups, + TokenPrivileges, + TokenOwner, + TokenPrimaryGroup, + TokenDefaultDacl, + TokenSource, + TokenType, + TokenImpersonationLevel, + TokenStatistics, + TokenRestrictedSids, + TokenSessionId, + TokenGroupsAndPrivileges, + TokenSessionReference, + TokenSandBoxInert, + TokenAuditPolicy, + TokenOrigin, + TokenElevationType, + TokenLinkedToken, + TokenElevation, + TokenHasRestrictions, + TokenAccessInformation, + TokenVirtualizationAllowed, + TokenVirtualizationEnabled, + TokenIntegrityLevel, + TokenUIAccess, + TokenMandatoryPolicy, + TokenLogonSid, + TokenIsAppContainer, + TokenCapabilities, + TokenAppContainerSid, + TokenAppContainerNumber, + TokenUserClaimAttributes, + TokenDeviceClaimAttributes, + TokenRestrictedUserClaimAttributes, + TokenRestrictedDeviceClaimAttributes, + TokenDeviceGroups, + TokenRestrictedDeviceGroups, + TokenSecurityAttributes, + TokenIsRestricted, + TokenProcessTrustLevel, + MaxTokenInfoClass // MaxTokenInfoClass should always be the last enum +} + +enum SID_NAME_USE { + SidTypeUser = 1, + SidTypeGroup, + SidTypeDomain, + SidTypeAlias, + SidTypeWellKnownGroup, + SidTypeDeletedAccount, + SidTypeInvalid, + SidTypeUnknown, + SidTypeComputer +} +alias SID_NAME_USE* PSID_NAME_USE; + +enum WELL_KNOWN_SID_TYPE { + WinNullSid = 0, + WinWorldSid = 1, + WinLocalSid = 2, + WinCreatorOwnerSid = 3, + WinCreatorGroupSid = 4, + WinCreatorOwnerServerSid = 5, + WinCreatorGroupServerSid = 6, + WinNtAuthoritySid = 7, + WinDialupSid = 8, + WinNetworkSid = 9, + WinBatchSid = 10, + WinInteractiveSid = 11, + WinServiceSid = 12, + WinAnonymousSid = 13, + WinProxySid = 14, + WinEnterpriseControllersSid = 15, + WinSelfSid = 16, + WinAuthenticatedUserSid = 17, + WinRestrictedCodeSid = 18, + WinTerminalServerSid = 19, + WinRemoteLogonIdSid = 20, + WinLogonIdsSid = 21, + WinLocalSystemSid = 22, + WinLocalServiceSid = 23, + WinNetworkServiceSid = 24, + WinBuiltinDomainSid = 25, + WinBuiltinAdministratorsSid = 26, + WinBuiltinUsersSid = 27, + WinBuiltinGuestsSid = 28, + WinBuiltinPowerUsersSid = 29, + WinBuiltinAccountOperatorsSid = 30, + WinBuiltinSystemOperatorsSid = 31, + WinBuiltinPrintOperatorsSid = 32, + WinBuiltinBackupOperatorsSid = 33, + WinBuiltinReplicatorSid = 34, + WinBuiltinPreWindows2000CompatibleAccessSid = 35, + WinBuiltinRemoteDesktopUsersSid = 36, + WinBuiltinNetworkConfigurationOperatorsSid = 37, + WinAccountAdministratorSid = 38, + WinAccountGuestSid = 39, + WinAccountKrbtgtSid = 40, + WinAccountDomainAdminsSid = 41, + WinAccountDomainUsersSid = 42, + WinAccountDomainGuestsSid = 43, + WinAccountComputersSid = 44, + WinAccountControllersSid = 45, + WinAccountCertAdminsSid = 46, + WinAccountSchemaAdminsSid = 47, + WinAccountEnterpriseAdminsSid = 48, + WinAccountPolicyAdminsSid = 49, + WinAccountRasAndIasServersSid = 50, + WinNTLMAuthenticationSid = 51, + WinDigestAuthenticationSid = 52, + WinSChannelAuthenticationSid = 53, + WinThisOrganizationSid = 54, + WinOtherOrganizationSid = 55, + WinBuiltinIncomingForestTrustBuildersSid = 56, + WinBuiltinPerfMonitoringUsersSid = 57, + WinBuiltinPerfLoggingUsersSid = 58, + WinBuiltinAuthorizationAccessSid = 59, + WinBuiltinTerminalServerLicenseServersSid = 60, + WinBuiltinDCOMUsersSid = 61, + WinBuiltinIUsersSid = 62, + WinIUserSid = 63, + WinBuiltinCryptoOperatorsSid = 64, + WinUntrustedLabelSid = 65, + WinLowLabelSid = 66, + WinMediumLabelSid = 67, + WinHighLabelSid = 68, + WinSystemLabelSid = 69, + WinWriteRestrictedCodeSid = 70, + WinCreatorOwnerRightsSid = 71, + WinCacheablePrincipalsGroupSid = 72, + WinNonCacheablePrincipalsGroupSid = 73, + WinEnterpriseReadonlyControllersSid = 74, + WinAccountReadonlyControllersSid = 75, + WinBuiltinEventLogReadersGroup = 76, + WinNewEnterpriseReadonlyControllersSid = 77, + WinBuiltinCertSvcDComAccessGroup = 78, + WinMediumPlusLabelSid = 79, + WinLocalLogonSid = 80, + WinConsoleLogonSid = 81, + WinThisOrganizationCertificateSid = 82, + WinApplicationPackageAuthoritySid = 83, + WinBuiltinAnyPackageSid = 84, + WinCapabilityInternetClientSid = 85, + WinCapabilityInternetClientServerSid = 86, + WinCapabilityPrivateNetworkClientServerSid = 87, + WinCapabilityPicturesLibrarySid = 88, + WinCapabilityVideosLibrarySid = 89, + WinCapabilityMusicLibrarySid = 90, + WinCapabilityDocumentsLibrarySid = 91, + WinCapabilitySharedUserCertificatesSid = 92, + WinCapabilityEnterpriseAuthenticationSid = 93, + WinCapabilityRemovableStorageSid = 94 +} +struct QUOTA_LIMITS { + SIZE_T PagedPoolLimit; + SIZE_T NonPagedPoolLimit; + SIZE_T MinimumWorkingSetSize; + SIZE_T MaximumWorkingSetSize; + SIZE_T PagefileLimit; + LARGE_INTEGER TimeLimit; +} +alias QUOTA_LIMITS* PQUOTA_LIMITS; + +struct IO_COUNTERS { + ULONGLONG ReadOperationCount; + ULONGLONG WriteOperationCount; + ULONGLONG OtherOperationCount; + ULONGLONG ReadTransferCount; + ULONGLONG WriteTransferCount; + ULONGLONG OtherTransferCount; +} +alias IO_COUNTERS* PIO_COUNTERS; + +struct FILE_NOTIFY_INFORMATION { + DWORD NextEntryOffset; + DWORD Action; + DWORD FileNameLength = 0; + WCHAR _FileName = 0; + + WCHAR* FileName() return { return &_FileName; } +} +alias FILE_NOTIFY_INFORMATION* PFILE_NOTIFY_INFORMATION; + +struct TAPE_ERASE { + DWORD Type; + BOOLEAN Immediate; +} +alias TAPE_ERASE* PTAPE_ERASE; + +struct TAPE_GET_DRIVE_PARAMETERS { + BOOLEAN ECC; + BOOLEAN Compression; + BOOLEAN DataPadding; + BOOLEAN ReportSetmarks; + DWORD DefaultBlockSize; + DWORD MaximumBlockSize; + DWORD MinimumBlockSize; + DWORD MaximumPartitionCount; + DWORD FeaturesLow; + DWORD FeaturesHigh; + DWORD EOTWarningZoneSize; +} +alias TAPE_GET_DRIVE_PARAMETERS* PTAPE_GET_DRIVE_PARAMETERS; + +struct TAPE_GET_MEDIA_PARAMETERS { + LARGE_INTEGER Capacity; + LARGE_INTEGER Remaining; + DWORD BlockSize; + DWORD PartitionCount; + BOOLEAN WriteProtected; +} +alias TAPE_GET_MEDIA_PARAMETERS* PTAPE_GET_MEDIA_PARAMETERS; + +struct TAPE_GET_POSITION { + ULONG Type; + ULONG Partition; + ULONG OffsetLow; + ULONG OffsetHigh; +} +alias TAPE_GET_POSITION* PTAPE_GET_POSITION; + +struct TAPE_PREPARE { + DWORD Operation; + BOOLEAN Immediate; +} +alias TAPE_PREPARE* PTAPE_PREPARE; + +struct TAPE_SET_DRIVE_PARAMETERS { + BOOLEAN ECC; + BOOLEAN Compression; + BOOLEAN DataPadding; + BOOLEAN ReportSetmarks; + ULONG EOTWarningZoneSize; +} +alias TAPE_SET_DRIVE_PARAMETERS* PTAPE_SET_DRIVE_PARAMETERS; + +struct TAPE_SET_MEDIA_PARAMETERS { + ULONG BlockSize; +} +alias TAPE_SET_MEDIA_PARAMETERS* PTAPE_SET_MEDIA_PARAMETERS; + +struct TAPE_SET_POSITION { + DWORD Method; + DWORD Partition; + LARGE_INTEGER Offset; + BOOLEAN Immediate; +} +alias TAPE_SET_POSITION* PTAPE_SET_POSITION; + +struct TAPE_WRITE_MARKS { + DWORD Type; + DWORD Count; + BOOLEAN Immediate; +} +alias TAPE_WRITE_MARKS* PTAPE_WRITE_MARKS; + +struct TAPE_CREATE_PARTITION { + DWORD Method; + DWORD Count; + DWORD Size; +} +alias TAPE_CREATE_PARTITION* PTAPE_CREATE_PARTITION; + +struct MEMORY_BASIC_INFORMATION { + PVOID BaseAddress; + PVOID AllocationBase; + DWORD AllocationProtect; + SIZE_T RegionSize; + DWORD State; + DWORD Protect; + DWORD Type; +} +alias MEMORY_BASIC_INFORMATION* PMEMORY_BASIC_INFORMATION; + +struct MESSAGE_RESOURCE_ENTRY { + WORD Length; + WORD Flags; + BYTE _Text; + + BYTE* Text() return { return &_Text; } +} +alias MESSAGE_RESOURCE_ENTRY* PMESSAGE_RESOURCE_ENTRY; + +struct MESSAGE_RESOURCE_BLOCK { + DWORD LowId; + DWORD HighId; + DWORD OffsetToEntries; +} +alias MESSAGE_RESOURCE_BLOCK* PMESSAGE_RESOURCE_BLOCK; + +struct MESSAGE_RESOURCE_DATA { + DWORD NumberOfBlocks; + MESSAGE_RESOURCE_BLOCK _Blocks; + + MESSAGE_RESOURCE_BLOCK* Blocks() return { return &_Blocks; } +} +alias MESSAGE_RESOURCE_DATA* PMESSAGE_RESOURCE_DATA; + +struct LIST_ENTRY { + LIST_ENTRY* Flink; + LIST_ENTRY* Blink; +} +alias LIST_ENTRY* PLIST_ENTRY; +alias LIST_ENTRY _LIST_ENTRY; + +struct SINGLE_LIST_ENTRY { + SINGLE_LIST_ENTRY* Next; +} + +version (Win64) { + align (16) + struct SLIST_ENTRY { + SLIST_ENTRY* Next; + } +} else { + alias SINGLE_LIST_ENTRY SLIST_ENTRY; +} +alias SINGLE_LIST_ENTRY* PSINGLE_LIST_ENTRY, PSLIST_ENTRY; + +union SLIST_HEADER { + ULONGLONG Alignment; + struct { + SLIST_ENTRY Next; + WORD Depth; + WORD Sequence; + } +} +alias SLIST_HEADER* PSLIST_HEADER; + +struct RTL_CRITICAL_SECTION_DEBUG { + WORD Type; + WORD CreatorBackTraceIndex; + RTL_CRITICAL_SECTION* CriticalSection; + LIST_ENTRY ProcessLocksList; + DWORD EntryCount; + DWORD ContentionCount; + DWORD[2] Spare; +} +alias RTL_CRITICAL_SECTION_DEBUG* PRTL_CRITICAL_SECTION_DEBUG; +alias RTL_CRITICAL_SECTION_DEBUG _RTL_CRITICAL_SECTION_DEBUG; + +struct RTL_CRITICAL_SECTION { + PRTL_CRITICAL_SECTION_DEBUG DebugInfo; + LONG LockCount; + LONG RecursionCount; + HANDLE OwningThread; + HANDLE LockSemaphore; + ULONG_PTR SpinCount; + alias Reserved = SpinCount; +} +alias RTL_CRITICAL_SECTION* PRTL_CRITICAL_SECTION; +alias RTL_CRITICAL_SECTION _RTL_CRITICAL_SECTION; + +struct EVENTLOGRECORD { + DWORD Length; + DWORD Reserved; + DWORD RecordNumber; + DWORD TimeGenerated; + DWORD TimeWritten; + DWORD EventID; + WORD EventType; + WORD NumStrings; + WORD EventCategory; + WORD ReservedFlags; + DWORD ClosingRecordNumber; + DWORD StringOffset; + DWORD UserSidLength; + DWORD UserSidOffset; + DWORD DataLength; + DWORD DataOffset; +} +alias EVENTLOGRECORD* PEVENTLOGRECORD; + +struct OSVERSIONINFOA { + DWORD dwOSVersionInfoSize = OSVERSIONINFOA.sizeof; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformId; + CHAR[128] szCSDVersion = 0; +} +alias OSVERSIONINFOA* POSVERSIONINFOA, LPOSVERSIONINFOA; + +struct OSVERSIONINFOW { + DWORD dwOSVersionInfoSize = OSVERSIONINFOW.sizeof; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformId; + WCHAR[128] szCSDVersion = 0; +} +alias OSVERSIONINFOW* POSVERSIONINFOW, LPOSVERSIONINFOW; + +struct OSVERSIONINFOEXA { + DWORD dwOSVersionInfoSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformId; + CHAR[128] szCSDVersion = 0; + WORD wServicePackMajor; + WORD wServicePackMinor; + WORD wSuiteMask; + BYTE wProductType; + BYTE wReserved; +} +alias OSVERSIONINFOEXA* POSVERSIONINFOEXA, LPOSVERSIONINFOEXA; + +struct OSVERSIONINFOEXW { + DWORD dwOSVersionInfoSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformId; + WCHAR[128] szCSDVersion = 0; + WORD wServicePackMajor; + WORD wServicePackMinor; + WORD wSuiteMask; + BYTE wProductType; + BYTE wReserved; +} +alias OSVERSIONINFOEXW* POSVERSIONINFOEXW, LPOSVERSIONINFOEXW; + +align(2) struct IMAGE_VXD_HEADER { + WORD e32_magic; + BYTE e32_border; + BYTE e32_worder; + DWORD e32_level; + WORD e32_cpu; + WORD e32_os; + DWORD e32_ver; + DWORD e32_mflags; + DWORD e32_mpages; + DWORD e32_startobj; + DWORD e32_eip; + DWORD e32_stackobj; + DWORD e32_esp; + DWORD e32_pagesize; + DWORD e32_lastpagesize; + DWORD e32_fixupsize; + DWORD e32_fixupsum; + DWORD e32_ldrsize; + DWORD e32_ldrsum; + DWORD e32_objtab; + DWORD e32_objcnt; + DWORD e32_objmap; + DWORD e32_itermap; + DWORD e32_rsrctab; + DWORD e32_rsrccnt; + DWORD e32_restab; + DWORD e32_enttab; + DWORD e32_dirtab; + DWORD e32_dircnt; + DWORD e32_fpagetab; + DWORD e32_frectab; + DWORD e32_impmod; + DWORD e32_impmodcnt; + DWORD e32_impproc; + DWORD e32_pagesum; + DWORD e32_datapage; + DWORD e32_preload; + DWORD e32_nrestab; + DWORD e32_cbnrestab; + DWORD e32_nressum; + DWORD e32_autodata; + DWORD e32_debuginfo; + DWORD e32_debuglen; + DWORD e32_instpreload; + DWORD e32_instdemand; + DWORD e32_heapsize; + BYTE[12] e32_res3; + DWORD e32_winresoff; + DWORD e32_winreslen; + WORD e32_devid; + WORD e32_ddkver; +} +alias IMAGE_VXD_HEADER* PIMAGE_VXD_HEADER; + +align(4): +struct IMAGE_FILE_HEADER { + WORD Machine; + WORD NumberOfSections; + DWORD TimeDateStamp; + DWORD PointerToSymbolTable; + DWORD NumberOfSymbols; + WORD SizeOfOptionalHeader; + WORD Characteristics; +} +alias IMAGE_FILE_HEADER* PIMAGE_FILE_HEADER; +// const IMAGE_SIZEOF_FILE_HEADER = IMAGE_FILE_HEADER.sizeof; + +struct IMAGE_DATA_DIRECTORY { + DWORD VirtualAddress; + DWORD Size; +} +alias IMAGE_DATA_DIRECTORY* PIMAGE_DATA_DIRECTORY; + +struct IMAGE_OPTIONAL_HEADER32 { + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + DWORD BaseOfData; + DWORD ImageBase; + DWORD SectionAlignment; + DWORD FileAlignment; + WORD MajorOperatingSystemVersion; + WORD MinorOperatingSystemVersion; + WORD MajorImageVersion; + WORD MinorImageVersion; + WORD MajorSubsystemVersion; + WORD MinorSubsystemVersion; + DWORD Win32VersionValue; + DWORD SizeOfImage; + DWORD SizeOfHeaders; + DWORD CheckSum; + WORD Subsystem; + WORD DllCharacteristics; + DWORD SizeOfStackReserve; + DWORD SizeOfStackCommit; + DWORD SizeOfHeapReserve; + DWORD SizeOfHeapCommit; + DWORD LoaderFlags; + DWORD NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] DataDirectory; +} +alias IMAGE_OPTIONAL_HEADER32* PIMAGE_OPTIONAL_HEADER32; + +struct IMAGE_OPTIONAL_HEADER64 { + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + ULONGLONG ImageBase; + DWORD SectionAlignment; + DWORD FileAlignment; + WORD MajorOperatingSystemVersion; + WORD MinorOperatingSystemVersion; + WORD MajorImageVersion; + WORD MinorImageVersion; + WORD MajorSubsystemVersion; + WORD MinorSubsystemVersion; + DWORD Win32VersionValue; + DWORD SizeOfImage; + DWORD SizeOfHeaders; + DWORD CheckSum; + WORD Subsystem; + WORD DllCharacteristics; + ULONGLONG SizeOfStackReserve; + ULONGLONG SizeOfStackCommit; + ULONGLONG SizeOfHeapReserve; + ULONGLONG SizeOfHeapCommit; + DWORD LoaderFlags; + DWORD NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] DataDirectory; +} +alias IMAGE_OPTIONAL_HEADER64* PIMAGE_OPTIONAL_HEADER64; + +struct IMAGE_ROM_OPTIONAL_HEADER { + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + DWORD BaseOfData; + DWORD BaseOfBss; + DWORD GprMask; + DWORD[4] CprMask; + DWORD GpValue; +} +alias IMAGE_ROM_OPTIONAL_HEADER* PIMAGE_ROM_OPTIONAL_HEADER; + +align(2): +struct IMAGE_DOS_HEADER { + WORD e_magic; + WORD e_cblp; + WORD e_cp; + WORD e_crlc; + WORD e_cparhdr; + WORD e_minalloc; + WORD e_maxalloc; + WORD e_ss; + WORD e_sp; + WORD e_csum; + WORD e_ip; + WORD e_cs; + WORD e_lfarlc; + WORD e_ovno; + WORD[4] e_res; + WORD e_oemid; + WORD e_oeminfo; + WORD[10] e_res2; + LONG e_lfanew; +} +alias IMAGE_DOS_HEADER* PIMAGE_DOS_HEADER; + +struct IMAGE_OS2_HEADER { + WORD ne_magic; + CHAR ne_ver = 0; + CHAR ne_rev = 0; + WORD ne_enttab; + WORD ne_cbenttab; + LONG ne_crc; + WORD ne_flags; + WORD ne_autodata; + WORD ne_heap; + WORD ne_stack; + LONG ne_csip; + LONG ne_sssp; + WORD ne_cseg; + WORD ne_cmod; + WORD ne_cbnrestab; + WORD ne_segtab; + WORD ne_rsrctab; + WORD ne_restab; + WORD ne_modtab; + WORD ne_imptab; + LONG ne_nrestab; + WORD ne_cmovent; + WORD ne_align; + WORD ne_cres; + BYTE ne_exetyp; + BYTE ne_flagsothers; + WORD ne_pretthunks; + WORD ne_psegrefbytes; + WORD ne_swaparea; + WORD ne_expver; +} +alias IMAGE_OS2_HEADER* PIMAGE_OS2_HEADER; + +align(4) struct IMAGE_NT_HEADERS32 { + DWORD Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER32 OptionalHeader; +} +alias IMAGE_NT_HEADERS32* PIMAGE_NT_HEADERS32; + +align(4) struct IMAGE_NT_HEADERS64 { + DWORD Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER64 OptionalHeader; +} +alias IMAGE_NT_HEADERS64* PIMAGE_NT_HEADERS64; + +struct IMAGE_ROM_HEADERS { + IMAGE_FILE_HEADER FileHeader; + IMAGE_ROM_OPTIONAL_HEADER OptionalHeader; +} +alias IMAGE_ROM_HEADERS* PIMAGE_ROM_HEADERS; + +struct IMAGE_SECTION_HEADER { + BYTE[IMAGE_SIZEOF_SHORT_NAME] Name; + union _Misc { + DWORD PhysicalAddress; + DWORD VirtualSize; + } + _Misc Misc; + DWORD VirtualAddress; + DWORD SizeOfRawData; + DWORD PointerToRawData; + DWORD PointerToRelocations; + DWORD PointerToLinenumbers; + WORD NumberOfRelocations; + WORD NumberOfLinenumbers; + DWORD Characteristics; +} +alias IMAGE_SECTION_HEADER* PIMAGE_SECTION_HEADER; + +struct IMAGE_SYMBOL { + union _N { + BYTE[8] ShortName; + struct _Name { + DWORD Short; + DWORD Long; + } + _Name Name; + DWORD[2] LongName; // PBYTE[2] + } + _N N; + DWORD Value; + SHORT SectionNumber; + WORD Type; + BYTE StorageClass; + BYTE NumberOfAuxSymbols; +} +alias IMAGE_SYMBOL* PIMAGE_SYMBOL; + +union IMAGE_AUX_SYMBOL { + struct _Sym { + DWORD TagIndex; + union _Misc { + struct _LnSz { + WORD Linenumber; + WORD Size; + } + _LnSz LnSz; + DWORD TotalSize; + } + _Misc Misc; + union _FcnAry { + struct _Function { + DWORD PointerToLinenumber; + DWORD PointerToNextFunction; + } + _Function Function; + struct _Array { + WORD[4] Dimension; + } + _Array Array; + } + _FcnAry FcnAry; + WORD TvIndex; + } + _Sym Sym; + struct _File { + BYTE[IMAGE_SIZEOF_SYMBOL] Name; + } + _File File; + struct _Section { + DWORD Length; + WORD NumberOfRelocations; + WORD NumberOfLinenumbers; + DWORD CheckSum; + SHORT Number; + BYTE Selection; + } + _Section Section; +} +alias IMAGE_AUX_SYMBOL* PIMAGE_AUX_SYMBOL; + +struct IMAGE_COFF_SYMBOLS_HEADER { + DWORD NumberOfSymbols; + DWORD LvaToFirstSymbol; + DWORD NumberOfLinenumbers; + DWORD LvaToFirstLinenumber; + DWORD RvaToFirstByteOfCode; + DWORD RvaToLastByteOfCode; + DWORD RvaToFirstByteOfData; + DWORD RvaToLastByteOfData; +} +alias IMAGE_COFF_SYMBOLS_HEADER* PIMAGE_COFF_SYMBOLS_HEADER; + +struct IMAGE_RELOCATION { + union { + DWORD VirtualAddress; + DWORD RelocCount; + } + DWORD SymbolTableIndex; + WORD Type; +} +alias IMAGE_RELOCATION* PIMAGE_RELOCATION; + +align(4) struct IMAGE_BASE_RELOCATION { + DWORD VirtualAddress; + DWORD SizeOfBlock; +} +alias IMAGE_BASE_RELOCATION* PIMAGE_BASE_RELOCATION; + +align(2) struct IMAGE_LINENUMBER { + union _Type { + DWORD SymbolTableIndex; + DWORD VirtualAddress; + } + _Type Type; + WORD Linenumber; +} +alias IMAGE_LINENUMBER* PIMAGE_LINENUMBER; + +align(4): +struct IMAGE_ARCHIVE_MEMBER_HEADER { + BYTE[16] Name; + BYTE[12] Date; + BYTE[6] UserID; + BYTE[6] GroupID; + BYTE[8] Mode; + BYTE[10] Size; + BYTE[2] EndHeader; +} +alias IMAGE_ARCHIVE_MEMBER_HEADER* PIMAGE_ARCHIVE_MEMBER_HEADER; + +struct IMAGE_EXPORT_DIRECTORY { + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + DWORD Name; + DWORD Base; + DWORD NumberOfFunctions; + DWORD NumberOfNames; + DWORD AddressOfFunctions; + DWORD AddressOfNames; + DWORD AddressOfNameOrdinals; +} +alias IMAGE_EXPORT_DIRECTORY* PIMAGE_EXPORT_DIRECTORY; + +struct IMAGE_IMPORT_BY_NAME { + WORD Hint; + BYTE _Name; + + BYTE* Name() return { return &_Name; } +} +alias IMAGE_IMPORT_BY_NAME* PIMAGE_IMPORT_BY_NAME; + +struct IMAGE_THUNK_DATA32 { + union _u1 { + DWORD ForwarderString; + DWORD Function; + DWORD Ordinal; + DWORD AddressOfData; + } + _u1 u1; +} +alias IMAGE_THUNK_DATA32* PIMAGE_THUNK_DATA32; + +struct IMAGE_THUNK_DATA64 { + union _u1 { + ULONGLONG ForwarderString; + ULONGLONG Function; + ULONGLONG Ordinal; + ULONGLONG AddressOfData; + } + _u1 u1; +} +alias IMAGE_THUNK_DATA64* PIMAGE_THUNK_DATA64; + +struct IMAGE_IMPORT_DESCRIPTOR { + union { + DWORD Characteristics; + DWORD OriginalFirstThunk; + } + DWORD TimeDateStamp; + DWORD ForwarderChain; + DWORD Name; + DWORD FirstThunk; +} +alias IMAGE_IMPORT_DESCRIPTOR* PIMAGE_IMPORT_DESCRIPTOR; + +struct IMAGE_BOUND_IMPORT_DESCRIPTOR { + DWORD TimeDateStamp; + WORD OffsetModuleName; + WORD NumberOfModuleForwarderRefs; +} +alias IMAGE_BOUND_IMPORT_DESCRIPTOR* PIMAGE_BOUND_IMPORT_DESCRIPTOR; + +struct IMAGE_BOUND_FORWARDER_REF { + DWORD TimeDateStamp; + WORD OffsetModuleName; + WORD Reserved; +} +alias IMAGE_BOUND_FORWARDER_REF* PIMAGE_BOUND_FORWARDER_REF; + +struct IMAGE_TLS_DIRECTORY32 { + DWORD StartAddressOfRawData; + DWORD EndAddressOfRawData; + DWORD AddressOfIndex; + DWORD AddressOfCallBacks; + DWORD SizeOfZeroFill; + DWORD Characteristics; +} +alias IMAGE_TLS_DIRECTORY32* PIMAGE_TLS_DIRECTORY32; + +struct IMAGE_TLS_DIRECTORY64 { + ULONGLONG StartAddressOfRawData; + ULONGLONG EndAddressOfRawData; + ULONGLONG AddressOfIndex; + ULONGLONG AddressOfCallBacks; + DWORD SizeOfZeroFill; + DWORD Characteristics; +} +alias IMAGE_TLS_DIRECTORY64* PIMAGE_TLS_DIRECTORY64; + +struct IMAGE_RESOURCE_DIRECTORY { + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + WORD NumberOfNamedEntries; + WORD NumberOfIdEntries; +} +alias IMAGE_RESOURCE_DIRECTORY* PIMAGE_RESOURCE_DIRECTORY; + +struct IMAGE_RESOURCE_DIRECTORY_ENTRY { + union { + /+struct { + DWORD NameOffset:31; + DWORD NameIsString:1; + }+/ + DWORD Name; + WORD Id; + } + DWORD OffsetToData; + /+struct { + DWORD OffsetToDirectory:31; + DWORD DataIsDirectory:1; + }+/ + + uint NameOffset() { return Name & 0x7FFFFFFF; } + bool NameIsString() { return cast(bool)(Name & 0x80000000); } + uint OffsetToDirectory()() { return OffsetToData & 0x7FFFFFFF; } + bool DataIsDirectory() { return cast(bool)(OffsetToData & 0x80000000); } + + uint NameOffset(uint n) { + Name = (Name & 0x80000000) | (n & 0x7FFFFFFF); + return n & 0x7FFFFFFF; + } + + bool NameIsString(bool n) { + Name = (Name & 0x7FFFFFFF) | (n << 31); return n; + } + + uint OffsetToDirectory(uint o) { + OffsetToData = (OffsetToData & 0x80000000) | (o & 0x7FFFFFFF); + return o & 0x7FFFFFFF; + } + + bool DataIsDirectory(bool d) { + OffsetToData = (OffsetToData & 0x7FFFFFFF) | (d << 31); return d; + } +} +alias IMAGE_RESOURCE_DIRECTORY_ENTRY* PIMAGE_RESOURCE_DIRECTORY_ENTRY; + +struct IMAGE_RESOURCE_DIRECTORY_STRING { + WORD Length; + CHAR _NameString = 0; + + CHAR* NameString() return { return &_NameString; } +} +alias IMAGE_RESOURCE_DIRECTORY_STRING* PIMAGE_RESOURCE_DIRECTORY_STRING; + +struct IMAGE_RESOURCE_DIR_STRING_U { + WORD Length; + WCHAR _NameString = 0; + + WCHAR* NameString() return { return &_NameString; } +} +alias IMAGE_RESOURCE_DIR_STRING_U* PIMAGE_RESOURCE_DIR_STRING_U; + +struct IMAGE_RESOURCE_DATA_ENTRY { + DWORD OffsetToData; + DWORD Size; + DWORD CodePage; + DWORD Reserved; +} +alias IMAGE_RESOURCE_DATA_ENTRY* PIMAGE_RESOURCE_DATA_ENTRY; + +struct IMAGE_LOAD_CONFIG_DIRECTORY32 { + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + DWORD GlobalFlagsClear; + DWORD GlobalFlagsSet; + DWORD CriticalSectionDefaultTimeout; + DWORD DeCommitFreeBlockThreshold; + DWORD DeCommitTotalFreeThreshold; + PVOID LockPrefixTable; + DWORD MaximumAllocationSize; + DWORD VirtualMemoryThreshold; + DWORD ProcessHeapFlags; + DWORD[4] Reserved; +} +alias IMAGE_LOAD_CONFIG_DIRECTORY32* PIMAGE_LOAD_CONFIG_DIRECTORY32; + +struct IMAGE_LOAD_CONFIG_DIRECTORY64 { + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + DWORD GlobalFlagsClear; + DWORD GlobalFlagsSet; + DWORD CriticalSectionDefaultTimeout; + ULONGLONG DeCommitFreeBlockThreshold; + ULONGLONG DeCommitTotalFreeThreshold; + ULONGLONG LockPrefixTable; + ULONGLONG MaximumAllocationSize; + ULONGLONG VirtualMemoryThreshold; + ULONGLONG ProcessAffinityMask; + DWORD ProcessHeapFlags; + WORD CSDFlags; + WORD Reserved1; + ULONGLONG EditList; + DWORD[2] Reserved; +} +alias IMAGE_LOAD_CONFIG_DIRECTORY64* PIMAGE_LOAD_CONFIG_DIRECTORY64; + +version (Win64) { + alias IMAGE_LOAD_CONFIG_DIRECTORY64 IMAGE_LOAD_CONFIG_DIRECTORY; +} else { + alias IMAGE_LOAD_CONFIG_DIRECTORY32 IMAGE_LOAD_CONFIG_DIRECTORY; +} +alias IMAGE_LOAD_CONFIG_DIRECTORY* PIMAGE_LOAD_CONFIG_DIRECTORY; + +// Note versions for Alpha, Alpha64, ARM removed. +struct IMAGE_RUNTIME_FUNCTION_ENTRY { + DWORD BeginAddress; + DWORD EndAddress; + union { + DWORD UnwindInfoAddress; + DWORD UnwindData; + } +} +alias IMAGE_RUNTIME_FUNCTION_ENTRY* PIMAGE_RUNTIME_FUNCTION_ENTRY; + +struct IMAGE_CE_RUNTIME_FUNCTION_ENTRY { + uint FuncStart; + union { + ubyte PrologLen; + uint _bf; + } +/+ + unsigned int FuncLen:22; + unsigned int ThirtyTwoBit:1; + unsigned int ExceptionFlag:1; ++/ + uint FuncLen() { return (_bf >> 8) & 0x3FFFFF; } + bool ThirtyTwoBit() { return cast(bool)(_bf & 0x40000000); } + bool ExceptionFlag()() { return cast(bool)(_bf & 0x80000000); } + + uint FuncLen(uint f) { + _bf = (_bf & ~0x3FFFFF00) | ((f & 0x3FFFFF) << 8); return f & 0x3FFFFF; + } + + bool ThirtyTwoBit(bool t) { + _bf = (_bf & ~0x40000000) | (t << 30); return t; + } + + bool ExceptionFlag(bool e) { + _bf = (_bf & ~0x80000000) | (e << 31); return e; + } +} +alias IMAGE_CE_RUNTIME_FUNCTION_ENTRY* PIMAGE_CE_RUNTIME_FUNCTION_ENTRY; + +struct IMAGE_DEBUG_DIRECTORY { + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + DWORD Type; + DWORD SizeOfData; + DWORD AddressOfRawData; + DWORD PointerToRawData; +} +alias IMAGE_DEBUG_DIRECTORY* PIMAGE_DEBUG_DIRECTORY; + +struct FPO_DATA { + DWORD ulOffStart; + DWORD cbProcSize; + DWORD cdwLocals; + WORD cdwParams; + ubyte cbProlog; + ubyte _bf; +/+ + WORD cbRegs:3; + WORD fHasSEH:1; + WORD fUseBP:1; + WORD reserved:1; + WORD cbFrame:2; ++/ + ubyte cbRegs() { return cast(ubyte)(_bf & 0x07); } + bool fHasSEH() { return cast(bool)(_bf & 0x08); } + bool fUseBP() { return cast(bool)(_bf & 0x10); } + bool reserved()() { return cast(bool)(_bf & 0x20); } + ubyte cbFrame()() { return cast(ubyte)(_bf >> 6); } + + ubyte cbRegs(ubyte c) { + _bf = cast(ubyte) ((_bf & ~0x07) | (c & 0x07)); + return cast(ubyte)(c & 0x07); + } + + bool fHasSEH(bool f) { _bf = cast(ubyte)((_bf & ~0x08) | (f << 3)); return f; } + bool fUseBP(bool f) { _bf = cast(ubyte)((_bf & ~0x10) | (f << 4)); return f; } + bool reserved(bool r) { _bf = cast(ubyte)((_bf & ~0x20) | (r << 5)); return r; } + + ubyte cbFrame(ubyte c) { + _bf = cast(ubyte) ((_bf & ~0xC0) | ((c & 0x03) << 6)); + return cast(ubyte)(c & 0x03); + } +} +alias FPO_DATA* PFPO_DATA; + +struct IMAGE_DEBUG_MISC { + DWORD DataType; + DWORD Length; + BOOLEAN Unicode; + BYTE[3] Reserved; + BYTE _Data; + + BYTE* Data() return { return &_Data; } +} +alias IMAGE_DEBUG_MISC* PIMAGE_DEBUG_MISC; + +struct IMAGE_FUNCTION_ENTRY { + DWORD StartingAddress; + DWORD EndingAddress; + DWORD EndOfPrologue; +} +alias IMAGE_FUNCTION_ENTRY* PIMAGE_FUNCTION_ENTRY; + +struct IMAGE_FUNCTION_ENTRY64 { + ULONGLONG StartingAddress; + ULONGLONG EndingAddress; + union { + ULONGLONG EndOfPrologue; + ULONGLONG UnwindInfoAddress; + } +} +alias IMAGE_FUNCTION_ENTRY64* PIMAGE_FUNCTION_ENTRY64; + +struct IMAGE_SEPARATE_DEBUG_HEADER { + WORD Signature; + WORD Flags; + WORD Machine; + WORD Characteristics; + DWORD TimeDateStamp; + DWORD CheckSum; + DWORD ImageBase; + DWORD SizeOfImage; + DWORD NumberOfSections; + DWORD ExportedNamesSize; + DWORD DebugDirectorySize; + DWORD SectionAlignment; + DWORD[2] Reserved; +} +alias IMAGE_SEPARATE_DEBUG_HEADER* PIMAGE_SEPARATE_DEBUG_HEADER; + +enum SERVICE_NODE_TYPE { + DriverType = SERVICE_KERNEL_DRIVER, + FileSystemType = SERVICE_FILE_SYSTEM_DRIVER, + Win32ServiceOwnProcess = SERVICE_WIN32_OWN_PROCESS, + Win32ServiceShareProcess = SERVICE_WIN32_SHARE_PROCESS, + AdapterType = SERVICE_ADAPTER, + RecognizerType = SERVICE_RECOGNIZER_DRIVER +} + +enum SERVICE_LOAD_TYPE { + BootLoad = SERVICE_BOOT_START, + SystemLoad = SERVICE_SYSTEM_START, + AutoLoad = SERVICE_AUTO_START, + DemandLoad = SERVICE_DEMAND_START, + DisableLoad = SERVICE_DISABLED +} + +enum SERVICE_ERROR_TYPE { + IgnoreError = SERVICE_ERROR_IGNORE, + NormalError = SERVICE_ERROR_NORMAL, + SevereError = SERVICE_ERROR_SEVERE, + CriticalError = SERVICE_ERROR_CRITICAL +} +alias SERVICE_ERROR_TYPE _CM_ERROR_CONTROL_TYPE; + +//DAC: According to MSJ, 'UnderTheHood', May 1996, this +// structure is not documented in any official Microsoft header file. +alias void EXCEPTION_REGISTRATION_RECORD; + +align: +struct NT_TIB { + EXCEPTION_REGISTRATION_RECORD *ExceptionList; + PVOID StackBase; + PVOID StackLimit; + PVOID SubSystemTib; + union { + PVOID FiberData; + DWORD Version; + } + PVOID ArbitraryUserPointer; + NT_TIB *Self; +} +alias NT_TIB* PNT_TIB; + +struct REPARSE_DATA_BUFFER { + DWORD ReparseTag; + WORD ReparseDataLength; + WORD Reserved; + union { + struct _GenericReparseBuffer { + BYTE _DataBuffer; + + BYTE* DataBuffer() return { return &_DataBuffer; } + } + _GenericReparseBuffer GenericReparseBuffer; + struct _SymbolicLinkReparseBuffer { + WORD SubstituteNameOffset; + WORD SubstituteNameLength; + WORD PrintNameOffset; + WORD PrintNameLength; + // ??? This is in MinGW, but absent in MSDN docs + ULONG Flags; + WCHAR _PathBuffer = 0; + + WCHAR* PathBuffer() return { return &_PathBuffer; } + } + _SymbolicLinkReparseBuffer SymbolicLinkReparseBuffer; + struct _MountPointReparseBuffer { + WORD SubstituteNameOffset; + WORD SubstituteNameLength; + WORD PrintNameOffset; + WORD PrintNameLength; + WCHAR _PathBuffer = 0; + + WCHAR* PathBuffer() return { return &_PathBuffer; } + } + _MountPointReparseBuffer MountPointReparseBuffer; + } +} +alias REPARSE_DATA_BUFFER *PREPARSE_DATA_BUFFER; + +struct REPARSE_GUID_DATA_BUFFER { + DWORD ReparseTag; + WORD ReparseDataLength; + WORD Reserved; + GUID ReparseGuid; + struct _GenericReparseBuffer { + BYTE _DataBuffer; + + BYTE* DataBuffer() return { return &_DataBuffer; } + } + _GenericReparseBuffer GenericReparseBuffer; +} +alias REPARSE_GUID_DATA_BUFFER* PREPARSE_GUID_DATA_BUFFER; + +enum size_t + REPARSE_DATA_BUFFER_HEADER_SIZE = REPARSE_DATA_BUFFER.GenericReparseBuffer.offsetof, + REPARSE_GUID_DATA_BUFFER_HEADER_SIZE = REPARSE_GUID_DATA_BUFFER.GenericReparseBuffer.offsetof, + MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16384; + + +struct REPARSE_POINT_INFORMATION { + WORD ReparseDataLength; + WORD UnparsedNameLength; +} +alias REPARSE_POINT_INFORMATION* PREPARSE_POINT_INFORMATION; + +union FILE_SEGMENT_ELEMENT { + PVOID64 Buffer; + ULONGLONG Alignment; +} +alias FILE_SEGMENT_ELEMENT* PFILE_SEGMENT_ELEMENT; + +// JOBOBJECT_BASIC_LIMIT_INFORMATION.LimitFlags constants +enum DWORD + JOB_OBJECT_LIMIT_WORKINGSET = 0x0001, + JOB_OBJECT_LIMIT_PROCESS_TIME = 0x0002, + JOB_OBJECT_LIMIT_JOB_TIME = 0x0004, + JOB_OBJECT_LIMIT_ACTIVE_PROCESS = 0x0008, + JOB_OBJECT_LIMIT_AFFINITY = 0x0010, + JOB_OBJECT_LIMIT_PRIORITY_CLASS = 0x0020, + JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME = 0x0040, + JOB_OBJECT_LIMIT_SCHEDULING_CLASS = 0x0080, + JOB_OBJECT_LIMIT_PROCESS_MEMORY = 0x0100, + JOB_OBJECT_LIMIT_JOB_MEMORY = 0x0200, + JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION = 0x0400, + JOB_OBJECT_BREAKAWAY_OK = 0x0800, + JOB_OBJECT_SILENT_BREAKAWAY = 0x1000; + +// JOBOBJECT_BASIC_UI_RESTRICTIONS.UIRestrictionsClass constants +enum DWORD + JOB_OBJECT_UILIMIT_HANDLES = 0x0001, + JOB_OBJECT_UILIMIT_READCLIPBOARD = 0x0002, + JOB_OBJECT_UILIMIT_WRITECLIPBOARD = 0x0004, + JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS = 0x0008, + JOB_OBJECT_UILIMIT_DISPLAYSETTINGS = 0x0010, + JOB_OBJECT_UILIMIT_GLOBALATOMS = 0x0020, + JOB_OBJECT_UILIMIT_DESKTOP = 0x0040, + JOB_OBJECT_UILIMIT_EXITWINDOWS = 0x0080; + +// JOBOBJECT_SECURITY_LIMIT_INFORMATION.SecurityLimitFlags constants +enum DWORD + JOB_OBJECT_SECURITY_NO_ADMIN = 0x0001, + JOB_OBJECT_SECURITY_RESTRICTED_TOKEN = 0x0002, + JOB_OBJECT_SECURITY_ONLY_TOKEN = 0x0004, + JOB_OBJECT_SECURITY_FILTER_TOKENS = 0x0008; + +// JOBOBJECT_END_OF_JOB_TIME_INFORMATION.EndOfJobTimeAction constants +enum : DWORD { + JOB_OBJECT_TERMINATE_AT_END_OF_JOB, + JOB_OBJECT_POST_AT_END_OF_JOB +} + +enum : DWORD { + JOB_OBJECT_MSG_END_OF_JOB_TIME = 1, + JOB_OBJECT_MSG_END_OF_PROCESS_TIME, + JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT, + JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO, + JOB_OBJECT_MSG_NEW_PROCESS, + JOB_OBJECT_MSG_EXIT_PROCESS, + JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS, + JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT, + JOB_OBJECT_MSG_JOB_MEMORY_LIMIT +} + +enum JOBOBJECTINFOCLASS { + JobObjectBasicAccountingInformation = 1, + JobObjectBasicLimitInformation, + JobObjectBasicProcessIdList, + JobObjectBasicUIRestrictions, + JobObjectSecurityLimitInformation, + JobObjectEndOfJobTimeInformation, + JobObjectAssociateCompletionPortInformation, + JobObjectBasicAndIoAccountingInformation, + JobObjectExtendedLimitInformation, + JobObjectJobSetInformation, + MaxJobObjectInfoClass +} + +struct JOBOBJECT_BASIC_ACCOUNTING_INFORMATION { + LARGE_INTEGER TotalUserTime; + LARGE_INTEGER TotalKernelTime; + LARGE_INTEGER ThisPeriodTotalUserTime; + LARGE_INTEGER ThisPeriodTotalKernelTime; + DWORD TotalPageFaultCount; + DWORD TotalProcesses; + DWORD ActiveProcesses; + DWORD TotalTerminatedProcesses; +} +alias JOBOBJECT_BASIC_ACCOUNTING_INFORMATION* PJOBOBJECT_BASIC_ACCOUNTING_INFORMATION; + +struct JOBOBJECT_BASIC_LIMIT_INFORMATION { + LARGE_INTEGER PerProcessUserTimeLimit; + LARGE_INTEGER PerJobUserTimeLimit; + DWORD LimitFlags; + SIZE_T MinimumWorkingSetSize; + SIZE_T MaximumWorkingSetSize; + DWORD ActiveProcessLimit; + ULONG_PTR Affinity; + DWORD PriorityClass; + DWORD SchedulingClass; +} +alias JOBOBJECT_BASIC_LIMIT_INFORMATION* PJOBOBJECT_BASIC_LIMIT_INFORMATION; + +struct JOBOBJECT_BASIC_PROCESS_ID_LIST { + DWORD NumberOfAssignedProcesses; + DWORD NumberOfProcessIdsInList; + ULONG_PTR _ProcessIdList; + + ULONG_PTR* ProcessIdList() return { return &_ProcessIdList; } +} +alias JOBOBJECT_BASIC_PROCESS_ID_LIST* PJOBOBJECT_BASIC_PROCESS_ID_LIST; + +struct JOBOBJECT_BASIC_UI_RESTRICTIONS { + DWORD UIRestrictionsClass; +} +alias JOBOBJECT_BASIC_UI_RESTRICTIONS* PJOBOBJECT_BASIC_UI_RESTRICTIONS; + +struct JOBOBJECT_SECURITY_LIMIT_INFORMATION { + DWORD SecurityLimitFlags; + HANDLE JobToken; + PTOKEN_GROUPS SidsToDisable; + PTOKEN_PRIVILEGES PrivilegesToDelete; + PTOKEN_GROUPS RestrictedSids; +} +alias JOBOBJECT_SECURITY_LIMIT_INFORMATION* PJOBOBJECT_SECURITY_LIMIT_INFORMATION; + +struct JOBOBJECT_END_OF_JOB_TIME_INFORMATION { + DWORD EndOfJobTimeAction; +} +alias JOBOBJECT_END_OF_JOB_TIME_INFORMATION* PJOBOBJECT_END_OF_JOB_TIME_INFORMATION; + +struct JOBOBJECT_ASSOCIATE_COMPLETION_PORT { + PVOID CompletionKey; + HANDLE CompletionPort; +} +alias JOBOBJECT_ASSOCIATE_COMPLETION_PORT* PJOBOBJECT_ASSOCIATE_COMPLETION_PORT; + +struct JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION { + JOBOBJECT_BASIC_ACCOUNTING_INFORMATION BasicInfo; + IO_COUNTERS IoInfo; +} +alias JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION *PJOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION; + +struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION { + JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation; + IO_COUNTERS IoInfo; + SIZE_T ProcessMemoryLimit; + SIZE_T JobMemoryLimit; + SIZE_T PeakProcessMemoryUsed; + SIZE_T PeakJobMemoryUsed; +} +alias JOBOBJECT_EXTENDED_LIMIT_INFORMATION* PJOBOBJECT_EXTENDED_LIMIT_INFORMATION; + +struct JOBOBJECT_JOBSET_INFORMATION { + DWORD MemberLevel; +} +alias JOBOBJECT_JOBSET_INFORMATION* PJOBOBJECT_JOBSET_INFORMATION; + +// MinGW: Making these defines conditional on _WIN32_WINNT will break ddk includes +//static if (_WIN32_WINNT >= 0x500) { + +enum DWORD + ES_SYSTEM_REQUIRED = 0x00000001, + ES_DISPLAY_REQUIRED = 0x00000002, + ES_USER_PRESENT = 0x00000004, + ES_AWAYMODE_REQUIRED = 0x00000040, + ES_CONTINUOUS = 0x80000000; + +enum LATENCY_TIME { + LT_DONT_CARE, + LT_LOWEST_LATENCY +} +alias LATENCY_TIME* PLATENCY_TIME; + +enum SYSTEM_POWER_STATE { + PowerSystemUnspecified, + PowerSystemWorking, + PowerSystemSleeping1, + PowerSystemSleeping2, + PowerSystemSleeping3, + PowerSystemHibernate, + PowerSystemShutdown, + PowerSystemMaximum +} +alias SYSTEM_POWER_STATE* PSYSTEM_POWER_STATE; + +enum POWER_SYSTEM_MAXIMUM = SYSTEM_POWER_STATE.PowerSystemMaximum; + +enum POWER_ACTION { + PowerActionNone, + PowerActionReserved, + PowerActionSleep, + PowerActionHibernate, + PowerActionShutdown, + PowerActionShutdownReset, + PowerActionShutdownOff, + PowerActionWarmEject +} +alias POWER_ACTION* PPOWER_ACTION; + +static if (_WIN32_WINNT >= 0x600) { + enum SYSTEM_POWER_CONDITION { + PoAc, + PoDc, + PoHot, + PoConditionMaximum + } + alias SYSTEM_POWER_CONDITION* PSYSTEM_POWER_CONDITION; +} + +enum DEVICE_POWER_STATE { + PowerDeviceUnspecified, + PowerDeviceD0, + PowerDeviceD1, + PowerDeviceD2, + PowerDeviceD3, + PowerDeviceMaximum +} +alias DEVICE_POWER_STATE* PDEVICE_POWER_STATE; + +align(4): +struct BATTERY_REPORTING_SCALE { + DWORD Granularity; + DWORD Capacity; +} +alias BATTERY_REPORTING_SCALE* PBATTERY_REPORTING_SCALE; + +struct POWER_ACTION_POLICY { + POWER_ACTION Action; + ULONG Flags; + ULONG EventCode; +} +alias POWER_ACTION_POLICY* PPOWER_ACTION_POLICY; + +// POWER_ACTION_POLICY.Flags constants +enum ULONG + POWER_ACTION_QUERY_ALLOWED = 0x00000001, + POWER_ACTION_UI_ALLOWED = 0x00000002, + POWER_ACTION_OVERRIDE_APPS = 0x00000004, + POWER_ACTION_LIGHTEST_FIRST = 0x10000000, + POWER_ACTION_LOCK_CONSOLE = 0x20000000, + POWER_ACTION_DISABLE_WAKES = 0x40000000, + POWER_ACTION_CRITICAL = 0x80000000; + +// POWER_ACTION_POLICY.EventCode constants +enum ULONG + POWER_LEVEL_USER_NOTIFY_TEXT = 0x00000001, + POWER_LEVEL_USER_NOTIFY_SOUND = 0x00000002, + POWER_LEVEL_USER_NOTIFY_EXEC = 0x00000004, + POWER_USER_NOTIFY_BUTTON = 0x00000008, + POWER_USER_NOTIFY_SHUTDOWN = 0x00000010, + POWER_FORCE_TRIGGER_RESET = 0x80000000; + +enum size_t + DISCHARGE_POLICY_CRITICAL = 0, + DISCHARGE_POLICY_LOW = 1, + NUM_DISCHARGE_POLICIES = 4; + +enum : BYTE { + PO_THROTTLE_NONE, + PO_THROTTLE_CONSTANT, + PO_THROTTLE_DEGRADE, + PO_THROTTLE_ADAPTIVE, + PO_THROTTLE_MAXIMUM +} + +struct SYSTEM_POWER_LEVEL { + BOOLEAN Enable; + UCHAR[3] Spare; + ULONG BatteryLevel; + POWER_ACTION_POLICY PowerPolicy; + SYSTEM_POWER_STATE MinSystemState; +} +alias SYSTEM_POWER_LEVEL* PSYSTEM_POWER_LEVEL; + +struct SYSTEM_POWER_POLICY { + ULONG Revision; + POWER_ACTION_POLICY PowerButton; + POWER_ACTION_POLICY SleepButton; + POWER_ACTION_POLICY LidClose; + SYSTEM_POWER_STATE LidOpenWake; + ULONG Reserved; + POWER_ACTION_POLICY Idle; + ULONG IdleTimeout; + UCHAR IdleSensitivity; + UCHAR DynamicThrottle; + UCHAR[2] Spare2; + SYSTEM_POWER_STATE MinSleep; + SYSTEM_POWER_STATE MaxSleep; + SYSTEM_POWER_STATE ReducedLatencySleep; + ULONG WinLogonFlags; + ULONG Spare3; + ULONG DozeS4Timeout; + ULONG BroadcastCapacityResolution; + SYSTEM_POWER_LEVEL[NUM_DISCHARGE_POLICIES] DischargePolicy; + ULONG VideoTimeout; + BOOLEAN VideoDimDisplay; + ULONG[3] VideoReserved; + ULONG SpindownTimeout; + BOOLEAN OptimizeForPower; + UCHAR FanThrottleTolerance; + UCHAR ForcedThrottle; + UCHAR MinThrottle; + POWER_ACTION_POLICY OverThrottled; +} +alias SYSTEM_POWER_POLICY* PSYSTEM_POWER_POLICY; + +struct SYSTEM_POWER_CAPABILITIES { + BOOLEAN PowerButtonPresent; + BOOLEAN SleepButtonPresent; + BOOLEAN LidPresent; + BOOLEAN SystemS1; + BOOLEAN SystemS2; + BOOLEAN SystemS3; + BOOLEAN SystemS4; + BOOLEAN SystemS5; + BOOLEAN HiberFilePresent; + BOOLEAN FullWake; + BOOLEAN VideoDimPresent; + BOOLEAN ApmPresent; + BOOLEAN UpsPresent; + BOOLEAN ThermalControl; + BOOLEAN ProcessorThrottle; + UCHAR ProcessorMinThrottle; + UCHAR ProcessorMaxThrottle; + UCHAR[4] spare2; + BOOLEAN DiskSpinDown; + UCHAR[8] spare3; + BOOLEAN SystemBatteriesPresent; + BOOLEAN BatteriesAreShortTerm; + BATTERY_REPORTING_SCALE[3] BatteryScale; + SYSTEM_POWER_STATE AcOnLineWake; + SYSTEM_POWER_STATE SoftLidWake; + SYSTEM_POWER_STATE RtcWake; + SYSTEM_POWER_STATE MinDeviceWakeState; + SYSTEM_POWER_STATE DefaultLowLatencyWake; +} +alias SYSTEM_POWER_CAPABILITIES* PSYSTEM_POWER_CAPABILITIES; + +struct SYSTEM_BATTERY_STATE { + BOOLEAN AcOnLine; + BOOLEAN BatteryPresent; + BOOLEAN Charging; + BOOLEAN Discharging; + BOOLEAN[4] Spare1; + ULONG MaxCapacity; + ULONG RemainingCapacity; + ULONG Rate; + ULONG EstimatedTime; + ULONG DefaultAlert1; + ULONG DefaultAlert2; +} +alias SYSTEM_BATTERY_STATE* PSYSTEM_BATTERY_STATE; + +enum POWER_INFORMATION_LEVEL { + SystemPowerPolicyAc, + SystemPowerPolicyDc, + VerifySystemPolicyAc, + VerifySystemPolicyDc, + SystemPowerCapabilities, + SystemBatteryState, + SystemPowerStateHandler, + ProcessorStateHandler, + SystemPowerPolicyCurrent, + AdministratorPowerPolicy, + SystemReserveHiberFile, + ProcessorInformation, + SystemPowerInformation, + ProcessorStateHandler2, + LastWakeTime, + LastSleepTime, + SystemExecutionState, + SystemPowerStateNotifyHandler, + ProcessorPowerPolicyAc, + ProcessorPowerPolicyDc, + VerifyProcessorPowerPolicyAc, + VerifyProcessorPowerPolicyDc, + ProcessorPowerPolicyCurrent +} + +//#if 1 /* (WIN32_WINNT >= 0x0500) */ +struct SYSTEM_POWER_INFORMATION { + ULONG MaxIdlenessAllowed; + ULONG Idleness; + ULONG TimeRemaining; + UCHAR CoolingMode; +} +alias SYSTEM_POWER_INFORMATION* PSYSTEM_POWER_INFORMATION; +//#endif + +struct PROCESSOR_POWER_POLICY_INFO { + ULONG TimeCheck; + ULONG DemoteLimit; + ULONG PromoteLimit; + UCHAR DemotePercent; + UCHAR PromotePercent; + UCHAR[2] Spare; + uint _bf; + + bool AllowDemotion() { return cast(bool)(_bf & 1); } + bool AllowPromotion()() { return cast(bool)(_bf & 2); } + + bool AllowDemotion(bool a) { _bf = (_bf & ~1) | a; return a; } + bool AllowPromotion(bool a) { _bf = (_bf & ~2) | (a << 1); return a; } +/+ + ULONG AllowDemotion : 1; + ULONG AllowPromotion : 1; + ULONG Reserved : 30; ++/ +} +alias PROCESSOR_POWER_POLICY_INFO* PPROCESSOR_POWER_POLICY_INFO; + +struct PROCESSOR_POWER_POLICY { + ULONG Revision; + UCHAR DynamicThrottle; + UCHAR[3] Spare; + ULONG Reserved; + ULONG PolicyCount; + PROCESSOR_POWER_POLICY_INFO[3] Policy; +} +alias PROCESSOR_POWER_POLICY* PPROCESSOR_POWER_POLICY; + +struct ADMINISTRATOR_POWER_POLICY { + SYSTEM_POWER_STATE MinSleep; + SYSTEM_POWER_STATE MaxSleep; + ULONG MinVideoTimeout; + ULONG MaxVideoTimeout; + ULONG MinSpindownTimeout; + ULONG MaxSpindownTimeout; +} +alias ADMINISTRATOR_POWER_POLICY* PADMINISTRATOR_POWER_POLICY; + +//}//#endif /* _WIN32_WINNT >= 0x500 */ + +extern (Windows) { + alias void function(PVOID, DWORD, PVOID) PIMAGE_TLS_CALLBACK; + + static if (_WIN32_WINNT >= 0x500) { + alias LONG function(PEXCEPTION_POINTERS) PVECTORED_EXCEPTION_HANDLER; + alias void function(PVOID, BOOLEAN) WAITORTIMERCALLBACKFUNC; + } +} + +static if (_WIN32_WINNT >= 0x501) { + enum HEAP_INFORMATION_CLASS { + HeapCompatibilityInformation + } + + enum ACTIVATION_CONTEXT_INFO_CLASS { + ActivationContextBasicInformation = 1, + ActivationContextDetailedInformation, + AssemblyDetailedInformationInActivationContext, + FileInformationInAssemblyOfAssemblyInActivationContext + } + + align struct ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION { + DWORD ulFlags; + DWORD ulEncodedAssemblyIdentityLength; + DWORD ulManifestPathType; + DWORD ulManifestPathLength; + LARGE_INTEGER liManifestLastWriteTime; + DWORD ulPolicyPathType; + DWORD ulPolicyPathLength; + LARGE_INTEGER liPolicyLastWriteTime; + DWORD ulMetadataSatelliteRosterIndex; + DWORD ulManifestVersionMajor; + DWORD ulManifestVersionMinor; + DWORD ulPolicyVersionMajor; + DWORD ulPolicyVersionMinor; + DWORD ulAssemblyDirectoryNameLength; + PCWSTR lpAssemblyEncodedAssemblyIdentity; + PCWSTR lpAssemblyManifestPath; + PCWSTR lpAssemblyPolicyPath; + PCWSTR lpAssemblyDirectoryName; + } + alias ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION* + PACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION; + alias const(ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION)* + PCACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION; + + struct ACTIVATION_CONTEXT_DETAILED_INFORMATION { + DWORD dwFlags; + DWORD ulFormatVersion; + DWORD ulAssemblyCount; + DWORD ulRootManifestPathType; + DWORD ulRootManifestPathChars; + DWORD ulRootConfigurationPathType; + DWORD ulRootConfigurationPathChars; + DWORD ulAppDirPathType; + DWORD ulAppDirPathChars; + PCWSTR lpRootManifestPath; + PCWSTR lpRootConfigurationPath; + PCWSTR lpAppDirPath; + } + alias ACTIVATION_CONTEXT_DETAILED_INFORMATION* + PACTIVATION_CONTEXT_DETAILED_INFORMATION; + alias const(ACTIVATION_CONTEXT_DETAILED_INFORMATION)* + PCACTIVATION_CONTEXT_DETAILED_INFORMATION; + + struct ACTIVATION_CONTEXT_QUERY_INDEX { + ULONG ulAssemblyIndex; + ULONG ulFileIndexInAssembly; + } + alias ACTIVATION_CONTEXT_QUERY_INDEX* PACTIVATION_CONTEXT_QUERY_INDEX; + alias const(ACTIVATION_CONTEXT_QUERY_INDEX)* PCACTIVATION_CONTEXT_QUERY_INDEX; + + struct ASSEMBLY_FILE_DETAILED_INFORMATION { + DWORD ulFlags; + DWORD ulFilenameLength; + DWORD ulPathLength; + PCWSTR lpFileName; + PCWSTR lpFilePath; + } + alias ASSEMBLY_FILE_DETAILED_INFORMATION* + PASSEMBLY_FILE_DETAILED_INFORMATION; + alias const(ASSEMBLY_FILE_DETAILED_INFORMATION)* + PCASSEMBLY_FILE_DETAILED_INFORMATION; +} + +version (Unicode) { + alias OSVERSIONINFOW OSVERSIONINFO; + alias OSVERSIONINFOEXW OSVERSIONINFOEX; +} else { + alias OSVERSIONINFOA OSVERSIONINFO; + alias OSVERSIONINFOEXA OSVERSIONINFOEX; +} + +alias OSVERSIONINFO* POSVERSIONINFO, LPOSVERSIONINFO; +alias OSVERSIONINFOEX* POSVERSIONINFOEX, LPOSVERSIONINFOEX; + + +static if (_WIN32_WINNT >= 0x500) { + extern (Windows) ULONGLONG VerSetConditionMask(ULONGLONG, DWORD, BYTE); +} + +version (Win64) { +enum WORD IMAGE_NT_OPTIONAL_HDR_MAGIC = IMAGE_NT_OPTIONAL_HDR64_MAGIC; + + alias IMAGE_ORDINAL_FLAG64 IMAGE_ORDINAL_FLAG; + alias IMAGE_SNAP_BY_ORDINAL64 IMAGE_SNAP_BY_ORDINAL; + alias IMAGE_ORDINAL64 IMAGE_ORDINAL; + alias IMAGE_OPTIONAL_HEADER64 IMAGE_OPTIONAL_HEADER; + alias IMAGE_NT_HEADERS64 IMAGE_NT_HEADERS; + alias IMAGE_THUNK_DATA64 IMAGE_THUNK_DATA; + alias IMAGE_TLS_DIRECTORY64 IMAGE_TLS_DIRECTORY; +} else { +enum WORD IMAGE_NT_OPTIONAL_HDR_MAGIC = IMAGE_NT_OPTIONAL_HDR32_MAGIC; + + alias IMAGE_ORDINAL_FLAG32 IMAGE_ORDINAL_FLAG; + alias IMAGE_ORDINAL32 IMAGE_ORDINAL; + alias IMAGE_SNAP_BY_ORDINAL32 IMAGE_SNAP_BY_ORDINAL; + alias IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER; + alias IMAGE_NT_HEADERS32 IMAGE_NT_HEADERS; + alias IMAGE_THUNK_DATA32 IMAGE_THUNK_DATA; + alias IMAGE_TLS_DIRECTORY32 IMAGE_TLS_DIRECTORY; +} + +alias IMAGE_OPTIONAL_HEADER* PIMAGE_OPTIONAL_HEADER; +alias IMAGE_NT_HEADERS* PIMAGE_NT_HEADERS; +alias IMAGE_THUNK_DATA* PIMAGE_THUNK_DATA; +alias IMAGE_TLS_DIRECTORY* PIMAGE_TLS_DIRECTORY; + +// TODO: MinGW implements these in assembly. How to translate? +PVOID GetCurrentFiber(); +PVOID GetFiberData(); diff --git a/src/urt/internal/sys/windows/winsock2.d b/src/urt/internal/sys/windows/winsock2.d new file mode 100644 index 0000000..5ab3a7c --- /dev/null +++ b/src/urt/internal/sys/windows/winsock2.d @@ -0,0 +1,768 @@ +/* + Written by Christopher E. Miller + $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0). +*/ + + +module urt.internal.sys.windows.winsock2; +version (Windows): + +pragma(lib, "ws2_32"); + +extern(Windows): +nothrow: + +alias SOCKET = size_t; +alias socklen_t = int; + +enum SOCKET INVALID_SOCKET = cast(SOCKET)~0; +enum int SOCKET_ERROR = -1; + +enum WSADESCRIPTION_LEN = 256; +enum WSASYS_STATUS_LEN = 128; + +struct WSADATA +{ + ushort wVersion; + ushort wHighVersion; + char[WSADESCRIPTION_LEN + 1] szDescription = 0; + char[WSASYS_STATUS_LEN + 1] szSystemStatus = 0; + ushort iMaxSockets; + ushort iMaxUdpDg; + char* lpVendorInfo; +} +alias LPWSADATA = WSADATA*; + + +enum int IOCPARM_MASK = 0x7F; +enum int IOC_IN = cast(int)0x80000000; +enum int IOC_OUT = cast(int)0x40000000; +enum int FIONBIO = cast(int)(IOC_IN | ((uint.sizeof & IOCPARM_MASK) << 16) | (102 << 8) | 126); +enum int FIONREAD = cast(int)(IOC_OUT | ((uint.sizeof & IOCPARM_MASK) << 16) | (102 << 8) | 127); + +enum NI_MAXHOST = 1025; +enum NI_MAXSERV = 32; + +@nogc +{ +int WSAStartup(ushort wVersionRequested, LPWSADATA lpWSAData); +@trusted int WSACleanup(); +@trusted SOCKET socket(int af, int type, int protocol); +int ioctlsocket(SOCKET s, int cmd, uint* argp); +int bind(SOCKET s, const(sockaddr)* name, socklen_t namelen); +int connect(SOCKET s, const(sockaddr)* name, socklen_t namelen); +@trusted int listen(SOCKET s, int backlog); +SOCKET accept(SOCKET s, sockaddr* addr, socklen_t* addrlen); +@trusted int closesocket(SOCKET s); +@trusted int shutdown(SOCKET s, int how); +int getpeername(SOCKET s, sockaddr* name, socklen_t* namelen); +int getsockname(SOCKET s, sockaddr* name, socklen_t* namelen); +int send(SOCKET s, const(void)* buf, int len, int flags); +int sendto(SOCKET s, const(void)* buf, int len, int flags, const(sockaddr)* to, socklen_t tolen); +int recv(SOCKET s, void* buf, int len, int flags); +int recvfrom(SOCKET s, void* buf, int len, int flags, sockaddr* from, socklen_t* fromlen); +int getsockopt(SOCKET s, int level, int optname, void* optval, socklen_t* optlen); +int setsockopt(SOCKET s, int level, int optname, const(void)* optval, socklen_t optlen); +uint inet_addr(const char* cp); +int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* errorfds, const(timeval)* timeout); +char* inet_ntoa(in_addr ina); +hostent* gethostbyname(const char* name); +hostent* gethostbyaddr(const(void)* addr, int len, int type); +protoent* getprotobyname(const char* name); +protoent* getprotobynumber(int number); +servent* getservbyname(const char* name, const char* proto); +servent* getservbyport(int port, const char* proto); +} + +enum: int +{ + NI_NOFQDN = 0x01, + NI_NUMERICHOST = 0x02, + NI_NAMEREQD = 0x04, + NI_NUMERICSERV = 0x08, + NI_DGRAM = 0x10, +} + +@nogc +{ +int gethostname(const char* name, int namelen); +int getaddrinfo(const(char)* nodename, const(char)* servname, const(addrinfo)* hints, addrinfo** res); +void freeaddrinfo(addrinfo* ai); +int getnameinfo(const(sockaddr)* sa, socklen_t salen, char* host, uint hostlen, char* serv, uint servlen, int flags); +} + +enum WSABASEERR = 10000; + +enum: int +{ + /* + * Windows Sockets definitions of regular Microsoft C error constants + */ + WSAEINTR = (WSABASEERR+4), + WSAEBADF = (WSABASEERR+9), + WSAEACCES = (WSABASEERR+13), + WSAEFAULT = (WSABASEERR+14), + WSAEINVAL = (WSABASEERR+22), + WSAEMFILE = (WSABASEERR+24), + + /* + * Windows Sockets definitions of regular Berkeley error constants + */ + WSAEWOULDBLOCK = (WSABASEERR+35), + WSAEINPROGRESS = (WSABASEERR+36), + WSAEALREADY = (WSABASEERR+37), + WSAENOTSOCK = (WSABASEERR+38), + WSAEDESTADDRREQ = (WSABASEERR+39), + WSAEMSGSIZE = (WSABASEERR+40), + WSAEPROTOTYPE = (WSABASEERR+41), + WSAENOPROTOOPT = (WSABASEERR+42), + WSAEPROTONOSUPPORT = (WSABASEERR+43), + WSAESOCKTNOSUPPORT = (WSABASEERR+44), + WSAEOPNOTSUPP = (WSABASEERR+45), + WSAEPFNOSUPPORT = (WSABASEERR+46), + WSAEAFNOSUPPORT = (WSABASEERR+47), + WSAEADDRINUSE = (WSABASEERR+48), + WSAEADDRNOTAVAIL = (WSABASEERR+49), + WSAENETDOWN = (WSABASEERR+50), + WSAENETUNREACH = (WSABASEERR+51), + WSAENETRESET = (WSABASEERR+52), + WSAECONNABORTED = (WSABASEERR+53), + WSAECONNRESET = (WSABASEERR+54), + WSAENOBUFS = (WSABASEERR+55), + WSAEISCONN = (WSABASEERR+56), + WSAENOTCONN = (WSABASEERR+57), + WSAESHUTDOWN = (WSABASEERR+58), + WSAETOOMANYREFS = (WSABASEERR+59), + WSAETIMEDOUT = (WSABASEERR+60), + WSAECONNREFUSED = (WSABASEERR+61), + WSAELOOP = (WSABASEERR+62), + WSAENAMETOOLONG = (WSABASEERR+63), + WSAEHOSTDOWN = (WSABASEERR+64), + WSAEHOSTUNREACH = (WSABASEERR+65), + WSAENOTEMPTY = (WSABASEERR+66), + WSAEPROCLIM = (WSABASEERR+67), + WSAEUSERS = (WSABASEERR+68), + WSAEDQUOT = (WSABASEERR+69), + WSAESTALE = (WSABASEERR+70), + WSAEREMOTE = (WSABASEERR+71), + + /* + * Extended Windows Sockets error constant definitions + */ + WSASYSNOTREADY = (WSABASEERR+91), + WSAVERNOTSUPPORTED = (WSABASEERR+92), + WSANOTINITIALISED = (WSABASEERR+93), + + /* Authoritative Answer: Host not found */ + WSAHOST_NOT_FOUND = (WSABASEERR+1001), + HOST_NOT_FOUND = WSAHOST_NOT_FOUND, + + /* Non-Authoritative: Host not found, or SERVERFAIL */ + WSATRY_AGAIN = (WSABASEERR+1002), + TRY_AGAIN = WSATRY_AGAIN, + + /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ + WSANO_RECOVERY = (WSABASEERR+1003), + NO_RECOVERY = WSANO_RECOVERY, + + /* Valid name, no data record of requested type */ + WSANO_DATA = (WSABASEERR+1004), + NO_DATA = WSANO_DATA, + + /* no address, look for MX record */ + WSANO_ADDRESS = WSANO_DATA, + NO_ADDRESS = WSANO_ADDRESS +} + +/* + * Windows Sockets errors redefined as regular Berkeley error constants + */ +enum: int +{ + EWOULDBLOCK = WSAEWOULDBLOCK, + EINPROGRESS = WSAEINPROGRESS, + EALREADY = WSAEALREADY, + ENOTSOCK = WSAENOTSOCK, + EDESTADDRREQ = WSAEDESTADDRREQ, + EMSGSIZE = WSAEMSGSIZE, + EPROTOTYPE = WSAEPROTOTYPE, + ENOPROTOOPT = WSAENOPROTOOPT, + EPROTONOSUPPORT = WSAEPROTONOSUPPORT, + ESOCKTNOSUPPORT = WSAESOCKTNOSUPPORT, + EOPNOTSUPP = WSAEOPNOTSUPP, + EPFNOSUPPORT = WSAEPFNOSUPPORT, + EAFNOSUPPORT = WSAEAFNOSUPPORT, + EADDRINUSE = WSAEADDRINUSE, + EADDRNOTAVAIL = WSAEADDRNOTAVAIL, + ENETDOWN = WSAENETDOWN, + ENETUNREACH = WSAENETUNREACH, + ENETRESET = WSAENETRESET, + ECONNABORTED = WSAECONNABORTED, + ECONNRESET = WSAECONNRESET, + ENOBUFS = WSAENOBUFS, + EISCONN = WSAEISCONN, + ENOTCONN = WSAENOTCONN, + ESHUTDOWN = WSAESHUTDOWN, + ETOOMANYREFS = WSAETOOMANYREFS, + ETIMEDOUT = WSAETIMEDOUT, + ECONNREFUSED = WSAECONNREFUSED, + ELOOP = WSAELOOP, + ENAMETOOLONG = WSAENAMETOOLONG, + EHOSTDOWN = WSAEHOSTDOWN, + EHOSTUNREACH = WSAEHOSTUNREACH, + ENOTEMPTY = WSAENOTEMPTY, + EPROCLIM = WSAEPROCLIM, + EUSERS = WSAEUSERS, + EDQUOT = WSAEDQUOT, + ESTALE = WSAESTALE, + EREMOTE = WSAEREMOTE +} + +enum: int +{ + EAI_NONAME = WSAHOST_NOT_FOUND, +} + +int WSAGetLastError() @nogc @trusted; + + +enum: int +{ + AF_UNSPEC = 0, + + AF_UNIX = 1, + AF_INET = 2, + AF_IMPLINK = 3, + AF_PUP = 4, + AF_CHAOS = 5, + AF_NS = 6, + AF_IPX = AF_NS, + AF_ISO = 7, + AF_OSI = AF_ISO, + AF_ECMA = 8, + AF_DATAKIT = 9, + AF_CCITT = 10, + AF_SNA = 11, + AF_DECnet = 12, + AF_DLI = 13, + AF_LAT = 14, + AF_HYLINK = 15, + AF_APPLETALK = 16, + AF_NETBIOS = 17, + AF_VOICEVIEW = 18, + AF_FIREFOX = 19, + AF_UNKNOWN1 = 20, + AF_BAN = 21, + AF_ATM = 22, + AF_INET6 = 23, + AF_CLUSTER = 24, + AF_12844 = 25, + AF_IRDA = 26, + AF_NETDES = 28, + + AF_MAX = 29, + + + PF_UNSPEC = AF_UNSPEC, + + PF_UNIX = AF_UNIX, + PF_INET = AF_INET, + PF_IMPLINK = AF_IMPLINK, + PF_PUP = AF_PUP, + PF_CHAOS = AF_CHAOS, + PF_NS = AF_NS, + PF_IPX = AF_IPX, + PF_ISO = AF_ISO, + PF_OSI = AF_OSI, + PF_ECMA = AF_ECMA, + PF_DATAKIT = AF_DATAKIT, + PF_CCITT = AF_CCITT, + PF_SNA = AF_SNA, + PF_DECnet = AF_DECnet, + PF_DLI = AF_DLI, + PF_LAT = AF_LAT, + PF_HYLINK = AF_HYLINK, + PF_APPLETALK = AF_APPLETALK, + PF_VOICEVIEW = AF_VOICEVIEW, + PF_FIREFOX = AF_FIREFOX, + PF_UNKNOWN1 = AF_UNKNOWN1, + PF_BAN = AF_BAN, + PF_INET6 = AF_INET6, + + PF_MAX = AF_MAX, +} + + +enum: int +{ + SOL_SOCKET = 0xFFFF, +} + + +enum: int +{ + SO_DEBUG = 0x0001, + SO_ACCEPTCONN = 0x0002, + SO_REUSEADDR = 0x0004, + SO_KEEPALIVE = 0x0008, + SO_DONTROUTE = 0x0010, + SO_BROADCAST = 0x0020, + SO_USELOOPBACK = 0x0040, + SO_LINGER = 0x0080, + SO_DONTLINGER = ~SO_LINGER, + SO_OOBINLINE = 0x0100, + SO_SNDBUF = 0x1001, + SO_RCVBUF = 0x1002, + SO_SNDLOWAT = 0x1003, + SO_RCVLOWAT = 0x1004, + SO_SNDTIMEO = 0x1005, + SO_RCVTIMEO = 0x1006, + SO_ERROR = 0x1007, + SO_TYPE = 0x1008, + SO_EXCLUSIVEADDRUSE = ~SO_REUSEADDR, + + TCP_NODELAY = 1, + + IP_OPTIONS = 1, + + IP_HDRINCL = 2, + IP_TOS = 3, + IP_TTL = 4, + IP_MULTICAST_IF = 9, + IP_MULTICAST_TTL = 10, + IP_MULTICAST_LOOP = 11, + IP_ADD_MEMBERSHIP = 12, + IP_DROP_MEMBERSHIP = 13, + IP_DONTFRAGMENT = 14, + IP_ADD_SOURCE_MEMBERSHIP = 15, + IP_DROP_SOURCE_MEMBERSHIP = 16, + IP_BLOCK_SOURCE = 17, + IP_UNBLOCK_SOURCE = 18, + IP_PKTINFO = 19, + + IPV6_UNICAST_HOPS = 4, + IPV6_MULTICAST_IF = 9, + IPV6_MULTICAST_HOPS = 10, + IPV6_MULTICAST_LOOP = 11, + IPV6_ADD_MEMBERSHIP = 12, + IPV6_DROP_MEMBERSHIP = 13, + IPV6_JOIN_GROUP = IPV6_ADD_MEMBERSHIP, + IPV6_LEAVE_GROUP = IPV6_DROP_MEMBERSHIP, + IPV6_V6ONLY = 27, +} + + +/// Default FD_SETSIZE value. +/// In C/C++, it is redefinable by #define-ing the macro before #include-ing +/// winsock.h. In D, use the $(D FD_CREATE) function to allocate a $(D fd_set) +/// of an arbitrary size. +enum int FD_SETSIZE = 64; + + +struct fd_set_custom(uint SETSIZE) +{ + uint fd_count; + SOCKET[SETSIZE] fd_array; +} + +alias fd_set = fd_set_custom!FD_SETSIZE; + +// Removes. +void FD_CLR(SOCKET fd, fd_set* set) pure @nogc +{ + uint c = set.fd_count; + SOCKET* start = set.fd_array.ptr; + SOCKET* stop = start + c; + + for (; start != stop; start++) + { + if (*start == fd) + goto found; + } + return; //not found + + found: + for (++start; start != stop; start++) + { + *(start - 1) = *start; + } + + set.fd_count = c - 1; +} + + +// Tests. +int FD_ISSET(SOCKET fd, const(fd_set)* set) pure @nogc +{ +const(SOCKET)* start = set.fd_array.ptr; +const(SOCKET)* stop = start + set.fd_count; + + for (; start != stop; start++) + { + if (*start == fd) + return true; + } + return false; +} + + +// Adds. +void FD_SET(SOCKET fd, fd_set* set) pure @nogc +{ + uint c = set.fd_count; + set.fd_array.ptr[c] = fd; + set.fd_count = c + 1; +} + + +// Resets to zero. +void FD_ZERO(fd_set* set) pure @nogc +{ + set.fd_count = 0; +} + + +/// Creates a new $(D fd_set) with the specified capacity. +fd_set* FD_CREATE(uint capacity) pure +{ + // Take into account alignment (SOCKET may be 64-bit and require 64-bit alignment on 64-bit systems) + size_t size = (fd_set_custom!1).sizeof - SOCKET.sizeof + (SOCKET.sizeof * capacity); + auto data = new ubyte[size]; + auto set = cast(fd_set*)data.ptr; + FD_ZERO(set); + return set; +} + +struct linger +{ + ushort l_onoff; + ushort l_linger; +} + + +struct protoent +{ + char* p_name; + char** p_aliases; + short p_proto; +} + + +struct servent +{ + char* s_name; + char** s_aliases; + + version (Win64) + { + char* s_proto; + short s_port; + } + else version (Win32) + { + short s_port; + char* s_proto; + } +} + + +/+ +union in6_addr +{ + private union _u_t + { + ubyte[16] Byte; + ushort[8] Word; + } + _u_t u; +} + + +struct in_addr6 +{ + ubyte[16] s6_addr; +} ++/ + +@safe pure @nogc +{ + ushort htons(ushort x); + uint htonl(uint x); + ushort ntohs(ushort x); + uint ntohl(uint x); +} + + +enum: int +{ + SOCK_STREAM = 1, + SOCK_DGRAM = 2, + SOCK_RAW = 3, + SOCK_RDM = 4, + SOCK_SEQPACKET = 5, +} + + +enum: int +{ + IPPROTO_IP = 0, + IPPROTO_ICMP = 1, + IPPROTO_IGMP = 2, + IPPROTO_GGP = 3, + IPPROTO_TCP = 6, + IPPROTO_PUP = 12, + IPPROTO_UDP = 17, + IPPROTO_IDP = 22, + IPPROTO_IPV6 = 41, + IPPROTO_ND = 77, + IPPROTO_RAW = 255, + + IPPROTO_MAX = 256, +} + + +enum: int +{ + MSG_OOB = 0x1, + MSG_PEEK = 0x2, + MSG_DONTROUTE = 0x4 +} + + +enum: int +{ + SD_RECEIVE = 0, + SD_SEND = 1, + SD_BOTH = 2, +} + + +enum: uint +{ + INADDR_ANY = 0, + INADDR_LOOPBACK = 0x7F000001, + INADDR_BROADCAST = 0xFFFFFFFF, + INADDR_NONE = 0xFFFFFFFF, + ADDR_ANY = INADDR_ANY, +} + + +enum: int +{ + AI_PASSIVE = 0x1, // Socket address will be used in bind() call + AI_CANONNAME = 0x2, // Return canonical name in first ai_canonname + AI_NUMERICHOST = 0x4, // Nodename must be a numeric address string + AI_NUMERICSERV = 0x8, // Servicename must be a numeric port number + AI_DNS_ONLY = 0x10, // Restrict queries to unicast DNS only (no LLMNR, netbios, etc.) + AI_FORCE_CLEAR_TEXT = 0x20, // Force clear text DNS query + AI_BYPASS_DNS_CACHE = 0x40, // Bypass DNS cache + AI_RETURN_TTL = 0x80, // Return record TTL + AI_ALL = 0x0100, // Query both IP6 and IP4 with AI_V4MAPPED + AI_ADDRCONFIG = 0x0400, // Resolution only if global address configured + AI_V4MAPPED = 0x0800, // On v6 failure, query v4 and convert to V4MAPPED format + AI_NON_AUTHORITATIVE = 0x04000, // LUP_NON_AUTHORITATIVE + AI_SECURE = 0x08000, // LUP_SECURE + AI_RETURN_PREFERRED_NAMES = 0x010000, // LUP_RETURN_PREFERRED_NAMES + AI_FQDN = 0x00020000, // Return the FQDN in ai_canonname + AI_FILESERVER = 0x00040000, // Resolving fileserver name resolution + AI_DISABLE_IDN_ENCODING = 0x00080000, // Disable Internationalized Domain Names handling + AI_SECURE_WITH_FALLBACK = 0x00100000, // Forces clear text fallback if the secure DNS query fails + AI_EXCLUSIVE_CUSTOM_SERVERS = 0x00200000, // Use exclusively the custom DNS servers + AI_RETURN_RESPONSE_FLAGS = 0x10000000, // Requests extra information about the DNS results + AI_REQUIRE_SECURE = 0x20000000, // Forces the DNS query to be done over seucre protocols + AI_RESOLUTION_HANDLE = 0x40000000, // Request resolution handle + AI_EXTENDED = 0x80000000, // Indicates this is extended ADDRINFOEX(2/..) struct +} + + +struct timeval +{ + int tv_sec; + int tv_usec; +} + + +union in_addr +{ + private union _S_un_t + { + private struct _S_un_b_t + { + ubyte s_b1, s_b2, s_b3, s_b4; + } + _S_un_b_t S_un_b; + + private struct _S_un_w_t + { + ushort s_w1, s_w2; + } + _S_un_w_t S_un_w; + + uint S_addr; + } + _S_un_t S_un; + + uint s_addr; + + struct + { + ubyte s_net, s_host; + + union + { + ushort s_imp; + + struct + { + ubyte s_lh, s_impno; + } + } + } +} + + +union in6_addr +{ + private union _in6_u_t + { + ubyte[16] u6_addr8; + ushort[8] u6_addr16; + uint[4] u6_addr32; + } + _in6_u_t in6_u; + + ubyte[16] s6_addr8; + ushort[8] s6_addr16; + uint[4] s6_addr32; + + alias s6_addr = s6_addr8; +} + + +enum in6_addr IN6ADDR_ANY = { s6_addr8: [0] }; +enum in6_addr IN6ADDR_LOOPBACK = { s6_addr8: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] }; +//alias IN6ADDR_ANY_INIT = IN6ADDR_ANY; +//alias IN6ADDR_LOOPBACK_INIT = IN6ADDR_LOOPBACK; + +enum int INET_ADDRSTRLEN = 16; +enum int INET6_ADDRSTRLEN = 46; + + + + +struct sockaddr +{ + short sa_family; + ubyte[14] sa_data; +} +alias sockaddr SOCKADDR; +alias SOCKADDR* PSOCKADDR, LPSOCKADDR; + +struct sockaddr_storage +{ + short ss_family; + char[6] __ss_pad1 = void; + long __ss_align; + char[112] __ss_pad2 = void; +} +alias sockaddr_storage SOCKADDR_STORAGE; +alias SOCKADDR_STORAGE* PSOCKADDR_STORAGE; + +struct sockaddr_in +{ + short sin_family = AF_INET; + ushort sin_port; + in_addr sin_addr; + ubyte[8] sin_zero; +} +alias sockaddr_in SOCKADDR_IN; +alias SOCKADDR_IN* PSOCKADDR_IN, LPSOCKADDR_IN; + + +struct sockaddr_in6 +{ + short sin6_family = AF_INET6; + ushort sin6_port; + uint sin6_flowinfo; + in6_addr sin6_addr; + uint sin6_scope_id; +} + + +struct addrinfo +{ + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + size_t ai_addrlen; + char* ai_canonname; + sockaddr* ai_addr; + addrinfo* ai_next; +} + + +struct hostent +{ + char* h_name; + char** h_aliases; + short h_addrtype; + short h_length; + char** h_addr_list; + + + char* h_addr() @safe pure nothrow @nogc + { + return h_addr_list[0]; + } +} + +// Note: These are Winsock2!! +struct WSAOVERLAPPED; +alias LPWSAOVERLAPPED = WSAOVERLAPPED*; +alias LPWSAOVERLAPPED_COMPLETION_ROUTINE = void function(uint, uint, LPWSAOVERLAPPED, uint) nothrow @nogc; +int WSAIoctl(SOCKET s, uint dwIoControlCode, + void* lpvInBuffer, uint cbInBuffer, + void* lpvOutBuffer, uint cbOutBuffer, + uint* lpcbBytesReturned, + LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) @nogc; + + +enum IOC_VENDOR = 0x18000000; +enum SIO_KEEPALIVE_VALS = IOC_IN | IOC_VENDOR | 4; + +/* Argument structure for SIO_KEEPALIVE_VALS */ +struct tcp_keepalive +{ + uint onoff; + uint keepalivetime; + uint keepaliveinterval; +} + + +struct pollfd +{ + SOCKET fd; // Socket handle + short events; // Requested events to monitor + short revents; // Returned events indicating status +} +alias WSAPOLLFD = pollfd; +alias PWSAPOLLFD = pollfd*; +alias LPWSAPOLLFD = pollfd*; + +enum: short { + POLLRDNORM = 0x0100, + POLLRDBAND = 0x0200, + POLLIN = (POLLRDNORM | POLLRDBAND), + POLLPRI = 0x0400, + + POLLWRNORM = 0x0010, + POLLOUT = (POLLWRNORM), + POLLWRBAND = 0x0020, + + POLLERR = 0x0001, + POLLHUP = 0x0002, + POLLNVAL = 0x0004 +} + +int WSAPoll(LPWSAPOLLFD fdArray, uint fds, int timeout) @nogc; diff --git a/src/urt/internal/sys/windows/winuser.d b/src/urt/internal/sys/windows/winuser.d new file mode 100644 index 0000000..f542160 --- /dev/null +++ b/src/urt/internal/sys/windows/winuser.d @@ -0,0 +1,144 @@ +/// Minimal winuser bindings - only virtual key codes. +/// Full winuser.d was trimmed; GUI/display/font APIs removed. +module urt.internal.sys.windows.winuser; +version (Windows): + +enum { + VK_LBUTTON = 0x01, + VK_RBUTTON = 0x02, + VK_CANCEL = 0x03, + VK_MBUTTON = 0x04, + VK_XBUTTON1 = 0x05, + VK_XBUTTON2 = 0x06, + VK_BACK = 0x08, + VK_TAB = 0x09, + VK_CLEAR = 0x0C, + VK_RETURN = 0x0D, + VK_SHIFT = 0x10, + VK_CONTROL = 0x11, + VK_MENU = 0x12, + VK_PAUSE = 0x13, + VK_CAPITAL = 0x14, + VK_KANA = 0x15, + VK_HANGEUL = 0x15, + VK_HANGUL = 0x15, + VK_JUNJA = 0x17, + VK_FINAL = 0x18, + VK_HANJA = 0x19, + VK_KANJI = 0x19, + VK_ESCAPE = 0x1B, + VK_CONVERT = 0x1C, + VK_NONCONVERT = 0x1D, + VK_ACCEPT = 0x1E, + VK_MODECHANGE = 0x1F, + VK_SPACE = 0x20, + VK_PRIOR = 0x21, + VK_NEXT = 0x22, + VK_END = 0x23, + VK_HOME = 0x24, + VK_LEFT = 0x25, + VK_UP = 0x26, + VK_RIGHT = 0x27, + VK_DOWN = 0x28, + VK_SELECT = 0x29, + VK_PRINT = 0x2A, + VK_EXECUTE = 0x2B, + VK_SNAPSHOT = 0x2C, + VK_INSERT = 0x2D, + VK_DELETE = 0x2E, + VK_HELP = 0x2F, + VK_LWIN = 0x5B, + VK_RWIN = 0x5C, + VK_APPS = 0x5D, + VK_SLEEP = 0x5F, + VK_NUMPAD0 = 0x60, + VK_NUMPAD1 = 0x61, + VK_NUMPAD2 = 0x62, + VK_NUMPAD3 = 0x63, + VK_NUMPAD4 = 0x64, + VK_NUMPAD5 = 0x65, + VK_NUMPAD6 = 0x66, + VK_NUMPAD7 = 0x67, + VK_NUMPAD8 = 0x68, + VK_NUMPAD9 = 0x69, + VK_MULTIPLY = 0x6A, + VK_ADD = 0x6B, + VK_SEPARATOR = 0x6C, + VK_SUBTRACT = 0x6D, + VK_DECIMAL = 0x6E, + VK_DIVIDE = 0x6F, + VK_F1 = 0x70, + VK_F2 = 0x71, + VK_F3 = 0x72, + VK_F4 = 0x73, + VK_F5 = 0x74, + VK_F6 = 0x75, + VK_F7 = 0x76, + VK_F8 = 0x77, + VK_F9 = 0x78, + VK_F10 = 0x79, + VK_F11 = 0x7A, + VK_F12 = 0x7B, + VK_F13 = 0x7C, + VK_F14 = 0x7D, + VK_F15 = 0x7E, + VK_F16 = 0x7F, + VK_F17 = 0x80, + VK_F18 = 0x81, + VK_F19 = 0x82, + VK_F20 = 0x83, + VK_F21 = 0x84, + VK_F22 = 0x85, + VK_F23 = 0x86, + VK_F24 = 0x87, + VK_NUMLOCK = 0x90, + VK_SCROLL = 0x91, + VK_LSHIFT = 0xA0, + VK_RSHIFT = 0xA1, + VK_LCONTROL = 0xA2, + VK_RCONTROL = 0xA3, + VK_LMENU = 0xA4, + VK_RMENU = 0xA5, + VK_BROWSER_BACK = 0xA6, + VK_BROWSER_FORWARD = 0xA7, + VK_BROWSER_REFRESH = 0xA8, + VK_BROWSER_STOP = 0xA9, + VK_BROWSER_SEARCH = 0xAA, + VK_BROWSER_FAVORITES = 0xAB, + VK_BROWSER_HOME = 0xAC, + VK_VOLUME_MUTE = 0xAD, + VK_VOLUME_DOWN = 0xAE, + VK_VOLUME_UP = 0xAF, + VK_MEDIA_NEXT_TRACK = 0xB0, + VK_MEDIA_PREV_TRACK = 0xB1, + VK_MEDIA_STOP = 0xB2, + VK_MEDIA_PLAY_PAUSE = 0xB3, + VK_LAUNCH_MAIL = 0xB4, + VK_LAUNCH_MEDIA_SELECT = 0xB5, + VK_LAUNCH_APP1 = 0xB6, + VK_LAUNCH_APP2 = 0xB7, + VK_OEM_1 = 0xBA, + VK_OEM_PLUS = 0xBB, + VK_OEM_COMMA = 0xBC, + VK_OEM_MINUS = 0xBD, + VK_OEM_PERIOD = 0xBE, + VK_OEM_2 = 0xBF, + VK_OEM_3 = 0xC0, + VK_OEM_4 = 0xDB, + VK_OEM_5 = 0xDC, + VK_OEM_6 = 0xDD, + VK_OEM_7 = 0xDE, + VK_OEM_8 = 0xDF, + VK_OEM_102 = 0xE2, + VK_PROCESSKEY = 0xE5, + VK_PACKET = 0xE7, + VK_ATTN = 0xF6, + VK_CRSEL = 0xF7, + VK_EXSEL = 0xF8, + VK_EREOF = 0xF9, + VK_PLAY = 0xFA, + VK_ZOOM = 0xFB, + VK_NONAME = 0xFC, + VK_PA1 = 0xFD, + VK_OEM_CLEAR = 0xFE, +} diff --git a/src/urt/internal/traits.d b/src/urt/internal/traits.d new file mode 100644 index 0000000..067e87a --- /dev/null +++ b/src/urt/internal/traits.d @@ -0,0 +1,1227 @@ +// TODO: THIS NEEDS TO BE DISSOLVED... +module urt.internal.traits; + +import urt.traits; + +template Fields(T) +{ + static if (is(T == struct) || is(T == union)) + alias Fields = typeof(T.tupleof[0 .. $ - __traits(isNested, T)]); + else static if (is(T == class) || is(T == interface)) + alias Fields = typeof(T.tupleof); + else + alias Fields = AliasSeq!T; +} + +T trustedCast(T, U)(auto ref U u) @trusted pure nothrow +{ + return cast(T)u; +} + +template BaseElemOf(T) +{ + static if (is(OriginalType!T == E[N], E, size_t N)) + alias BaseElemOf = BaseElemOf!E; + else + alias BaseElemOf = T; +} + +unittest +{ + static assert(is(BaseElemOf!(int) == int)); + static assert(is(BaseElemOf!(int[1]) == int)); + static assert(is(BaseElemOf!(int[1][2]) == int)); + static assert(is(BaseElemOf!(int[1][]) == int[1][])); + static assert(is(BaseElemOf!(int[][1]) == int[])); + enum E : int[2]{ test = [0, 1] } + static assert(is(BaseElemOf!(E) == int)); +} + +// [For internal use] +template ModifyTypePreservingTQ(alias Modifier, T) +{ + static if (is(T U == immutable U)) alias ModifyTypePreservingTQ = immutable Modifier!U; + else static if (is(T U == shared inout const U)) alias ModifyTypePreservingTQ = shared inout const Modifier!U; + else static if (is(T U == shared inout U)) alias ModifyTypePreservingTQ = shared inout Modifier!U; + else static if (is(T U == shared const U)) alias ModifyTypePreservingTQ = shared const Modifier!U; + else static if (is(T U == shared U)) alias ModifyTypePreservingTQ = shared Modifier!U; + else static if (is(T U == inout const U)) alias ModifyTypePreservingTQ = inout const Modifier!U; + else static if (is(T U == inout U)) alias ModifyTypePreservingTQ = inout Modifier!U; + else static if (is(T U == const U)) alias ModifyTypePreservingTQ = const Modifier!U; + else alias ModifyTypePreservingTQ = Modifier!T; +} +@safe unittest +{ + alias Intify(T) = int; + static assert(is(ModifyTypePreservingTQ!(Intify, real) == int)); + static assert(is(ModifyTypePreservingTQ!(Intify, const real) == const int)); + static assert(is(ModifyTypePreservingTQ!(Intify, inout real) == inout int)); + static assert(is(ModifyTypePreservingTQ!(Intify, inout const real) == inout const int)); + static assert(is(ModifyTypePreservingTQ!(Intify, shared real) == shared int)); + static assert(is(ModifyTypePreservingTQ!(Intify, shared const real) == shared const int)); + static assert(is(ModifyTypePreservingTQ!(Intify, shared inout real) == shared inout int)); + static assert(is(ModifyTypePreservingTQ!(Intify, shared inout const real) == shared inout const int)); + static assert(is(ModifyTypePreservingTQ!(Intify, immutable real) == immutable int)); +} + +// Substitute all `inout` qualifiers that appears in T to `const` +template substInout(T) +{ + static if (is(T == immutable)) + { + alias substInout = T; + } + else static if (is(T : shared const U, U) || is(T : const U, U)) + { + // U is top-unqualified + mixin("alias substInout = " + ~ (is(T == shared) ? "shared " : "") + ~ (is(T == const) || is(T == inout) ? "const " : "") // substitute inout to const + ~ "substInoutForm!U;"); + } + else + static assert(0); +} + +private template substInoutForm(T) +{ + static if (is(T == struct) || is(T == class) || is(T == union) || is(T == interface)) + { + alias substInoutForm = T; // prevent matching to the form of alias-this-ed type + } + else static if (is(T == V[K], K, V)) alias substInoutForm = substInout!V[substInout!K]; + else static if (is(T == U[n], U, size_t n)) alias substInoutForm = substInout!U[n]; + else static if (is(T == U[], U)) alias substInoutForm = substInout!U[]; + else static if (is(T == U*, U)) alias substInoutForm = substInout!U*; + else alias substInoutForm = T; +} + +unittest +{ + // https://github.com/dlang/dmd/issues/21452 + struct S { int x; } + struct T { int x; alias x this; } + + enum EnumInt { a = 123 } + enum EnumUInt : uint { a = 123 } + enum EnumFloat : float { a = 123 } + enum EnumString : string { a = "123" } + enum EnumStringW : wstring { a = "123" } + enum EnumStruct : S { a = S(7) } + enum EnumAliasThis : T { a = T(7) } + enum EnumDArray : int[] { a = [1] } + enum EnumAArray : int[int] { a = [0 : 1] } + + static assert(substInout!(EnumInt).stringof == "EnumInt"); + static assert(substInout!(inout(EnumUInt)).stringof == "const(EnumUInt)"); + static assert(substInout!(EnumFloat).stringof == "EnumFloat"); + static assert(substInout!(EnumString).stringof == "EnumString"); + static assert(substInout!(inout(EnumStringW)).stringof == "const(EnumStringW)"); + static assert(substInout!(EnumStruct).stringof == "EnumStruct"); + static assert(substInout!(EnumAliasThis).stringof == "EnumAliasThis"); + static assert(substInout!(EnumDArray).stringof == "EnumDArray"); + static assert(substInout!(inout(EnumAArray)[int]).stringof == "const(EnumAArray)[int]"); +} + +/// used to declare an extern(D) function that is defined in a different module +template externDFunc(string fqn, T:FT*, FT) if (is(FT == function)) +{ + static if (is(FT RT == return) && is(FT Args == function)) + { + import core.demangle : mangleFunc; + enum decl = { + string s = "extern(D) RT externDFunc(Args)"; + foreach (attr; __traits(getFunctionAttributes, FT)) + s ~= " " ~ attr; + return s ~ ";"; + }(); + pragma(mangle, mangleFunc!T(fqn)) mixin(decl); + } + else + static assert(0); +} + +template staticIota(int beg, int end) +{ + static if (beg + 1 >= end) + { + static if (beg >= end) + { + alias staticIota = AliasSeq!(); + } + else + { + alias staticIota = AliasSeq!(+beg); + } + } + else + { + enum mid = beg + (end - beg) / 2; + alias staticIota = AliasSeq!(staticIota!(beg, mid), staticIota!(mid, end)); + } +} + +private struct __InoutWorkaroundStruct {} +@property T rvalueOf(T)(T val) { return val; } +@property T rvalueOf(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init); +@property ref T lvalueOf(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init); + +// taken from std.traits.isAssignable +template isAssignable(Lhs, Rhs = Lhs) +{ + enum isAssignable = __traits(compiles, lvalueOf!Lhs = rvalueOf!Rhs) && __traits(compiles, lvalueOf!Lhs = lvalueOf!Rhs); +} + +// taken from std.traits.isInnerClass +template isInnerClass(T) if (is(T == class)) +{ + static if (is(typeof(T.outer))) + { + template hasOuterMember(T...) + { + static if (T.length == 0) + enum hasOuterMember = false; + else + enum hasOuterMember = T[0] == "outer" || hasOuterMember!(T[1 .. $]); + } + enum isInnerClass = __traits(isSame, typeof(T.outer), __traits(parent, T)) && !hasOuterMember!(__traits(allMembers, T)); + } + else + enum isInnerClass = false; +} + +template dtorIsNothrow(T) +{ + enum dtorIsNothrow = is(typeof(function{T t=void;}) : void function() nothrow); +} + +// taken from std.meta.allSatisfy +template allSatisfy(alias F, T...) +{ + static foreach (Ti; T) + { + static if (!is(typeof(allSatisfy) == bool) && // not yet defined + !F!(Ti)) + { + enum allSatisfy = false; + } + } + static if (!is(typeof(allSatisfy) == bool)) // if not yet defined + { + enum allSatisfy = true; + } +} + +// taken from std.meta.anySatisfy +template anySatisfy(alias F, Ts...) +{ + static foreach (T; Ts) + { + static if (!is(typeof(anySatisfy) == bool) && // not yet defined + F!T) + { + enum anySatisfy = true; + } + } + static if (!is(typeof(anySatisfy) == bool)) // if not yet defined + { + enum anySatisfy = false; + } +} + +// simplified from std.traits.maxAlignment +template maxAlignment(Ts...) +if (Ts.length > 0) +{ + enum maxAlignment = + { + size_t result = 0; + static foreach (T; Ts) + if (T.alignof > result) result = T.alignof; + return result; + }(); +} + +template classInstanceAlignment(T) +if (is(T == class)) +{ + enum classInstanceAlignment = __traits(classInstanceAlignment, T); +} + +/// See $(REF hasElaborateMove, std,traits) +template hasElaborateMove(S) +{ + static if (__traits(isStaticArray, S)) + { + enum bool hasElaborateMove = S.sizeof && hasElaborateMove!(BaseElemOf!S); + } + else static if (is(S == struct)) + { + enum hasElaborateMove = (is(typeof(S.init.opPostMove(lvalueOf!S))) && + !is(typeof(S.init.opPostMove(rvalueOf!S)))) || + anySatisfy!(.hasElaborateMove, Fields!S); + } + else + { + enum bool hasElaborateMove = false; + } +} + +// std.traits.hasElaborateDestructor +template hasElaborateDestructor(S) +{ + static if (__traits(isStaticArray, S)) + { + enum bool hasElaborateDestructor = S.sizeof && hasElaborateDestructor!(BaseElemOf!S); + } + else static if (is(S == struct)) + { + // Once https://issues.dlang.org/show_bug.cgi?id=24865 is fixed, then + // this should be the implementation, but until that's fixed, we need the + // uncommented code. + // enum hasElaborateDestructor = __traits(hasMember, S, "__xdtor"); + + enum hasElaborateDestructor = hasDtor([__traits(allMembers, S)]); + } + else + { + enum bool hasElaborateDestructor = false; + } +} + +private bool hasDtor(string[] members) +{ + foreach (name; members) + { + if (name == "__xdtor") + return true; + } + + return false; +} + +@safe unittest +{ + static struct NoDestructor {} + static assert(!hasElaborateDestructor!NoDestructor); + static assert(!hasElaborateDestructor!(NoDestructor[42])); + static assert(!hasElaborateDestructor!(NoDestructor[0])); + static assert(!hasElaborateDestructor!(NoDestructor[])); + + static struct HasDestructor { ~this() {} } + static assert( hasElaborateDestructor!HasDestructor); + static assert( hasElaborateDestructor!(HasDestructor[42])); + static assert(!hasElaborateDestructor!(HasDestructor[0])); + static assert(!hasElaborateDestructor!(HasDestructor[])); + + static struct HasDestructor2 { HasDestructor s; } + static assert( hasElaborateDestructor!HasDestructor2); + static assert( hasElaborateDestructor!(HasDestructor2[42])); + static assert(!hasElaborateDestructor!(HasDestructor2[0])); + static assert(!hasElaborateDestructor!(HasDestructor2[])); + + static class HasFinalizer { ~this() {} } + static assert(!hasElaborateDestructor!HasFinalizer); + + static struct HasUnion { union { HasDestructor s; } } + static assert(!hasElaborateDestructor!HasUnion); + static assert(!hasElaborateDestructor!(HasUnion[42])); + static assert(!hasElaborateDestructor!(HasUnion[0])); + static assert(!hasElaborateDestructor!(HasUnion[])); + + static assert(!hasElaborateDestructor!int); + static assert(!hasElaborateDestructor!(int[0])); + static assert(!hasElaborateDestructor!(int[42])); + static assert(!hasElaborateDestructor!(int[])); +} + +// https://issues.dlang.org/show_bug.cgi?id=24865 +@safe unittest +{ + static struct S2 { ~this() {} } + static struct S3 { S2 field; } + static struct S6 { S3[0] field; } + + static assert( hasElaborateDestructor!S2); + static assert( hasElaborateDestructor!S3); + static assert(!hasElaborateDestructor!S6); +} + +// std.traits.hasElaborateCopyDestructor +template hasElaborateCopyConstructor(S) +{ + static if (__traits(isStaticArray, S)) + { + enum bool hasElaborateCopyConstructor = S.sizeof && hasElaborateCopyConstructor!(BaseElemOf!S); + } + else static if (is(S == struct)) + { + enum hasElaborateCopyConstructor = __traits(hasCopyConstructor, S) || __traits(hasPostblit, S); + } + else + { + enum bool hasElaborateCopyConstructor = false; + } +} + +@safe unittest +{ + static struct S + { + int x; + this(return scope ref typeof(this) rhs) { } + this(int x, int y) {} + } + + static assert( hasElaborateCopyConstructor!S); + static assert(!hasElaborateCopyConstructor!(S[0][1])); + + static struct S2 + { + int x; + this(int x, int y) {} + } + + static assert(!hasElaborateCopyConstructor!S2); + + static struct S3 + { + int x; + this(return scope ref typeof(this) rhs, int x = 42) { } + this(int x, int y) {} + } + + static assert( hasElaborateCopyConstructor!S3); + + static struct S4 { union { S s; } } + + static assert(!hasElaborateCopyConstructor!S4); +} + +template hasElaborateAssign(S) +{ + static if (__traits(isStaticArray, S)) + { + enum bool hasElaborateAssign = S.sizeof && hasElaborateAssign!(BaseElemOf!S); + } + else static if (is(S == struct)) + { + enum hasElaborateAssign = is(typeof(S.init.opAssign(rvalueOf!S))) || + is(typeof(S.init.opAssign(lvalueOf!S))); + } + else + { + enum bool hasElaborateAssign = false; + } +} + +unittest +{ + { + static struct S {} + static assert(!hasElaborateAssign!S); + static assert(!hasElaborateAssign!(S[10])); + static assert(!hasElaborateAssign!(S[0])); + static assert(!hasElaborateAssign!(S[])); + } + { + static struct S { int i; } + static assert(!hasElaborateAssign!S); + static assert(!hasElaborateAssign!(S[10])); + static assert(!hasElaborateAssign!(S[0])); + static assert(!hasElaborateAssign!(S[])); + } + { + static struct S { void opAssign(S) {} } + static assert( hasElaborateAssign!S); + static assert( hasElaborateAssign!(S[10])); + static assert(!hasElaborateAssign!(S[0])); + static assert(!hasElaborateAssign!(S[])); + } + { + static struct S { void opAssign(ref S) {} } + static assert( hasElaborateAssign!S); + static assert( hasElaborateAssign!(S[10])); + static assert(!hasElaborateAssign!(S[0])); + static assert(!hasElaborateAssign!(S[])); + } + { + static struct S { void opAssign(int) {} } + static assert(!hasElaborateAssign!S); + static assert(!hasElaborateAssign!(S[10])); + static assert(!hasElaborateAssign!(S[0])); + static assert(!hasElaborateAssign!(S[])); + } + { + static struct S { this(this) {} } + static assert( hasElaborateAssign!S); + static assert( hasElaborateAssign!(S[10])); + static assert(!hasElaborateAssign!(S[0])); + static assert(!hasElaborateAssign!(S[])); + } + // https://issues.dlang.org/show_bug.cgi?id=24834 + /+ + { + static struct S { this(ref S) {} } + static assert( hasElaborateAssign!S); + static assert( hasElaborateAssign!(S[10])); + static assert(!hasElaborateAssign!(S[0])); + static assert(!hasElaborateAssign!(S[])); + } + +/ + { + static struct S { ~this() {} } + static assert( hasElaborateAssign!S); + static assert( hasElaborateAssign!(S[10])); + static assert(!hasElaborateAssign!(S[0])); + static assert(!hasElaborateAssign!(S[])); + } + { + static struct S { @disable void opAssign(S); } + static assert(!hasElaborateAssign!S); + static assert(!hasElaborateAssign!(S[10])); + static assert(!hasElaborateAssign!(S[0])); + static assert(!hasElaborateAssign!(S[])); + } + { + static struct Member {} + static struct S { Member member; } + static assert(!hasElaborateAssign!S); + static assert(!hasElaborateAssign!(S[10])); + static assert(!hasElaborateAssign!(S[0])); + static assert(!hasElaborateAssign!(S[])); + } + { + static struct Member { void opAssign(Member) {} } + static struct S { Member member; } + static assert( hasElaborateAssign!S); + static assert( hasElaborateAssign!(S[10])); + static assert(!hasElaborateAssign!(S[0])); + static assert(!hasElaborateAssign!(S[])); + } + { + static struct Member {} + static struct S { Member member; void opAssign(S) {} } + static assert( hasElaborateAssign!S); + static assert( hasElaborateAssign!(S[10])); + static assert(!hasElaborateAssign!(S[0])); + static assert(!hasElaborateAssign!(S[])); + } + { + static struct Member { @disable void opAssign(Member); } + static struct S { Member member; } + static assert(!hasElaborateAssign!S); + static assert(!hasElaborateAssign!(S[10])); + static assert(!hasElaborateAssign!(S[0])); + static assert(!hasElaborateAssign!(S[])); + } + { + static struct Member { @disable void opAssign(Member); } + static struct S { Member member; void opAssign(S) {} } + static assert( hasElaborateAssign!S); + static assert( hasElaborateAssign!(S[10])); + static assert(!hasElaborateAssign!(S[0])); + static assert(!hasElaborateAssign!(S[])); + } + { + static struct Member { void opAssign(Member) {} } + static struct S { Member member; @disable void opAssign(S); } + static assert(!hasElaborateAssign!S); + static assert(!hasElaborateAssign!(S[10])); + static assert(!hasElaborateAssign!(S[0])); + static assert(!hasElaborateAssign!(S[])); + } + { + static struct Member { void opAssign(Member) {} } + static struct S { union { Member member; } } + static assert(!hasElaborateAssign!S); + static assert(!hasElaborateAssign!(S[10])); + static assert(!hasElaborateAssign!(S[0])); + static assert(!hasElaborateAssign!(S[])); + } + + static assert(!hasElaborateAssign!int); + static assert(!hasElaborateAssign!(string[])); + static assert(!hasElaborateAssign!Object); +} + +template hasIndirections(T) +{ + static if (is(T == enum)) + enum hasIndirections = hasIndirections!(OriginalType!T); + else static if (is(T == struct) || is(T == union)) + enum hasIndirections = anySatisfy!(.hasIndirections, typeof(T.tupleof)); + else static if (__traits(isAssociativeArray, T) || is(T == class) || is(T == interface)) + enum hasIndirections = true; + else static if (is(T == E[N], E, size_t N)) + enum hasIndirections = T.sizeof && (is(immutable E == immutable void) || hasIndirections!(BaseElemOf!E)); + else static if (isFunctionPointer!T) + enum hasIndirections = false; + else + enum hasIndirections = isPointer!T || isDelegate!T || isDynamicArray!T; +} + +@safe unittest +{ + static assert(!hasIndirections!int); + static assert(!hasIndirections!(const int)); + + static assert( hasIndirections!(int*)); + static assert( hasIndirections!(const int*)); + + static assert( hasIndirections!(int[])); + static assert(!hasIndirections!(int[42])); + static assert(!hasIndirections!(int[0])); + + static assert( hasIndirections!(int*)); + static assert( hasIndirections!(int*[])); + static assert( hasIndirections!(int*[42])); + static assert(!hasIndirections!(int*[0])); + + static assert( hasIndirections!string); + static assert( hasIndirections!(string[])); + static assert( hasIndirections!(string[42])); + static assert(!hasIndirections!(string[0])); + + static assert( hasIndirections!(void[])); + static assert( hasIndirections!(void[17])); + static assert(!hasIndirections!(void[0])); + + static assert( hasIndirections!(string[int])); + static assert( hasIndirections!(string[int]*)); + static assert( hasIndirections!(string[int][])); + static assert( hasIndirections!(string[int][12])); + static assert(!hasIndirections!(string[int][0])); + + static assert(!hasIndirections!(int function(string))); + static assert( hasIndirections!(int delegate(string))); + static assert(!hasIndirections!(const(int function(string)))); + static assert( hasIndirections!(const(int delegate(string)))); + static assert(!hasIndirections!(immutable(int function(string)))); + static assert( hasIndirections!(immutable(int delegate(string)))); + + static class C {} + static assert( hasIndirections!C); + + static interface I {} + static assert( hasIndirections!I); + + { + enum E : int { a } + static assert(!hasIndirections!E); + } + { + enum E : int* { a } + static assert( hasIndirections!E); + } + { + enum E : string { a = "" } + static assert( hasIndirections!E); + } + { + enum E : int[] { a = null } + static assert( hasIndirections!E); + } + { + enum E : int[3] { a = [1, 2, 3] } + static assert(!hasIndirections!E); + } + { + enum E : int*[3] { a = [null, null, null] } + static assert( hasIndirections!E); + } + { + enum E : int*[0] { a = int*[0].init } + static assert(!hasIndirections!E); + } + { + enum E : C { a = null } + static assert( hasIndirections!E); + } + { + enum E : I { a = null } + static assert( hasIndirections!E); + } + + { + static struct S {} + static assert(!hasIndirections!S); + + enum E : S { a = S.init } + static assert(!hasIndirections!S); + } + { + static struct S { int i; } + static assert(!hasIndirections!S); + + enum E : S { a = S.init } + static assert(!hasIndirections!S); + } + { + static struct S { C c; } + static assert( hasIndirections!S); + + enum E : S { a = S.init } + static assert( hasIndirections!S); + } + { + static struct S { int[] arr; } + static assert( hasIndirections!S); + + enum E : S { a = S.init } + static assert( hasIndirections!S); + } + { + int local; + struct S { void foo() { ++local; } } + static assert( hasIndirections!S); + + enum E : S { a = S.init } + static assert( hasIndirections!S); + } + + { + static union U {} + static assert(!hasIndirections!U); + } + { + static union U { int i; } + static assert(!hasIndirections!U); + } + { + static union U { C c; } + static assert( hasIndirections!U); + } + { + static union U { int[] arr; } + static assert( hasIndirections!U); + } +} + +// https://issues.dlang.org/show_bug.cgi?id=12000 +@safe unittest +{ + static struct S(T) + { + static assert(hasIndirections!T); + } + + static class A(T) + { + S!A a; + } + + A!int dummy; +} + +// https://github.com/dlang/dmd/issues/20812 +@safe unittest +{ + static assert(!hasIndirections!void); + static assert(!hasIndirections!(const void)); + static assert(!hasIndirections!(inout void)); + static assert(!hasIndirections!(immutable void)); + static assert(!hasIndirections!(shared void)); + + static assert( hasIndirections!(void*)); + static assert( hasIndirections!(const void*)); + static assert( hasIndirections!(inout void*)); + static assert( hasIndirections!(immutable void*)); + static assert( hasIndirections!(shared void*)); + + static assert( hasIndirections!(void[])); + static assert( hasIndirections!(const void[])); + static assert( hasIndirections!(inout void[])); + static assert( hasIndirections!(immutable void[])); + static assert( hasIndirections!(shared void[])); + + static assert( hasIndirections!(void[42])); + static assert( hasIndirections!(const void[42])); + static assert( hasIndirections!(inout void[42])); + static assert( hasIndirections!(immutable void[42])); + static assert( hasIndirections!(shared void[42])); + + static assert(!hasIndirections!(void[0])); + static assert(!hasIndirections!(const void[0])); + static assert(!hasIndirections!(inout void[0])); + static assert(!hasIndirections!(immutable void[0])); + static assert(!hasIndirections!(shared void[0])); +} + +template hasUnsharedIndirections(T) +{ + static if (is(T == immutable)) + enum hasUnsharedIndirections = false; + else static if (is(T == struct) || is(T == union)) + enum hasUnsharedIndirections = anySatisfy!(.hasUnsharedIndirections, Fields!T); + else static if (is(T : E[N], E, size_t N)) + enum hasUnsharedIndirections = is(E == void) ? false : hasUnsharedIndirections!E; + else static if (isFunctionPointer!T) + enum hasUnsharedIndirections = false; + else static if (isPointer!T) + enum hasUnsharedIndirections = !is(T : shared(U)*, U) && !is(T : immutable(U)*, U); + else static if (isDynamicArray!T) + enum hasUnsharedIndirections = !is(T : shared(V)[], V) && !is(T : immutable(V)[], V); + else static if (is(T == class) || is(T == interface)) + enum hasUnsharedIndirections = !is(T : shared(W), W); + else + enum hasUnsharedIndirections = isDelegate!T || __traits(isAssociativeArray, T); // TODO: how to handle these? +} + +unittest +{ + static struct Foo { shared(int)* val; } + + static assert(!hasUnsharedIndirections!(immutable(char)*)); + static assert(!hasUnsharedIndirections!(string)); + + static assert(!hasUnsharedIndirections!(Foo)); + static assert( hasUnsharedIndirections!(Foo*)); + static assert(!hasUnsharedIndirections!(shared(Foo)*)); + static assert(!hasUnsharedIndirections!(immutable(Foo)*)); + + int local; + struct HasContextPointer { int opCall() { return ++local; } } + static assert(hasIndirections!HasContextPointer); +} + +enum bool isAggregateType(T) = is(T == struct) || is(T == union) || + is(T == class) || is(T == interface); + +enum bool isPointer(T) = is(T == U*, U) && !isAggregateType!T; + +enum bool isDynamicArray(T) = is(DynamicArrayTypeOf!T) && !isAggregateType!T; + +template OriginalType(T) +{ + template Impl(T) + { + static if (is(T U == enum)) alias Impl = OriginalType!U; + else alias Impl = T; + } + + alias OriginalType = ModifyTypePreservingTQ!(Impl, T); +} + +template DynamicArrayTypeOf(T) +{ + static if (is(AliasThisTypeOf!T AT) && !is(AT[] == AT)) + alias X = DynamicArrayTypeOf!AT; + else + alias X = OriginalType!T; + + static if (is(Unqual!X : E[], E) && !is(typeof({ enum n = X.length; }))) + alias DynamicArrayTypeOf = X; + else + static assert(0, T.stringof ~ " is not a dynamic array"); +} + +private template AliasThisTypeOf(T) + if (isAggregateType!T) +{ + alias members = __traits(getAliasThis, T); + + static if (members.length == 1) + alias AliasThisTypeOf = typeof(__traits(getMember, T.init, members[0])); + else + static assert(0, T.stringof~" does not have alias this type"); +} + +template isFunctionPointer(T...) + if (T.length == 1) +{ + static if (is(T[0] U) || is(typeof(T[0]) U)) + { + static if (is(U F : F*) && is(F == function)) + enum bool isFunctionPointer = true; + else + enum bool isFunctionPointer = false; + } + else + enum bool isFunctionPointer = false; +} + +template isDelegate(T...) + if (T.length == 1) +{ + static if (is(typeof(& T[0]) U : U*) && is(typeof(& T[0]) U == delegate)) + { + // T is a (nested) function symbol. + enum bool isDelegate = true; + } + else static if (is(T[0] W) || is(typeof(T[0]) W)) + { + // T is an expression or a type. Take the type of it and examine. + enum bool isDelegate = is(W == delegate); + } + else + enum bool isDelegate = false; +} + +// std.meta.Filter +template Filter(alias pred, TList...) +{ + static if (TList.length == 0) + { + alias Filter = AliasSeq!(); + } + else static if (TList.length == 1) + { + static if (pred!(TList[0])) + alias Filter = AliasSeq!(TList[0]); + else + alias Filter = AliasSeq!(); + } + /* The next case speeds up compilation by reducing + * the number of Filter instantiations + */ + else static if (TList.length == 2) + { + static if (pred!(TList[0])) + { + static if (pred!(TList[1])) + alias Filter = AliasSeq!(TList[0], TList[1]); + else + alias Filter = AliasSeq!(TList[0]); + } + else + { + static if (pred!(TList[1])) + alias Filter = AliasSeq!(TList[1]); + else + alias Filter = AliasSeq!(); + } + } + else + { + alias Filter = + AliasSeq!( + Filter!(pred, TList[ 0 .. $/2]), + Filter!(pred, TList[$/2 .. $ ])); + } +} + +// std.meta.staticMap +template staticMap(alias F, T...) +{ + static if (T.length == 0) + { + alias staticMap = AliasSeq!(); + } + else static if (T.length == 1) + { + alias staticMap = AliasSeq!(F!(T[0])); + } + /* Cases 2 to 8 improve compile performance by reducing + * the number of recursive instantiations of staticMap + */ + else static if (T.length == 2) + { + alias staticMap = AliasSeq!(F!(T[0]), F!(T[1])); + } + else static if (T.length == 3) + { + alias staticMap = AliasSeq!(F!(T[0]), F!(T[1]), F!(T[2])); + } + else static if (T.length == 4) + { + alias staticMap = AliasSeq!(F!(T[0]), F!(T[1]), F!(T[2]), F!(T[3])); + } + else static if (T.length == 5) + { + alias staticMap = AliasSeq!(F!(T[0]), F!(T[1]), F!(T[2]), F!(T[3]), F!(T[4])); + } + else static if (T.length == 6) + { + alias staticMap = AliasSeq!(F!(T[0]), F!(T[1]), F!(T[2]), F!(T[3]), F!(T[4]), F!(T[5])); + } + else static if (T.length == 7) + { + alias staticMap = AliasSeq!(F!(T[0]), F!(T[1]), F!(T[2]), F!(T[3]), F!(T[4]), F!(T[5]), F!(T[6])); + } + else static if (T.length == 8) + { + alias staticMap = AliasSeq!(F!(T[0]), F!(T[1]), F!(T[2]), F!(T[3]), F!(T[4]), F!(T[5]), F!(T[6]), F!(T[7])); + } + else + { + alias staticMap = + AliasSeq!( + staticMap!(F, T[ 0 .. $/2]), + staticMap!(F, T[$/2 .. $ ])); + } +} + +// std.exception.assertCTFEable +version (CoreUnittest) package(core) +void assertCTFEable(alias dg)() +{ + static assert({ dg(); return true; }()); + dg(); +} + +// std.traits.FunctionTypeOf +/* +Get the function type from a callable object `func`. + +Using builtin `typeof` on a property function yields the types of the +property value, not of the property function itself. Still, +`FunctionTypeOf` is able to obtain function types of properties. + +Note: +Do not confuse function types with function pointer types; function types are +usually used for compile-time reflection purposes. + */ +template FunctionTypeOf(func...) +if (func.length == 1 /*&& isCallable!func*/) +{ + static if (is(typeof(& func[0]) Fsym : Fsym*) && is(Fsym == function) || is(typeof(& func[0]) Fsym == delegate)) + { + alias FunctionTypeOf = Fsym; // HIT: (nested) function symbol + } + else static if (is(typeof(& func[0].opCall) Fobj == delegate)) + { + alias FunctionTypeOf = Fobj; // HIT: callable object + } + else static if (is(typeof(& func[0].opCall) Ftyp : Ftyp*) && is(Ftyp == function)) + { + alias FunctionTypeOf = Ftyp; // HIT: callable type + } + else static if (is(func[0] T) || is(typeof(func[0]) T)) + { + static if (is(T == function)) + alias FunctionTypeOf = T; // HIT: function + else static if (is(T Fptr : Fptr*) && is(Fptr == function)) + alias FunctionTypeOf = Fptr; // HIT: function pointer + else static if (is(T Fdlg == delegate)) + alias FunctionTypeOf = Fdlg; // HIT: delegate + else + static assert(0); + } + else + static assert(0); +} + +@safe unittest +{ + class C + { + int value() @property { return 0; } + } + static assert(is( typeof(C.value) == int )); + static assert(is( FunctionTypeOf!(C.value) == function )); +} + +// Disabled: uses `new Callable` (GC allocation) which is unsupported in @nogc uRT build +version (none) +@system unittest +{ + int test(int a); + int propGet() @property; + int propSet(int a) @property; + int function(int) test_fp; + int delegate(int) test_dg; + static assert(is( typeof(test) == FunctionTypeOf!(typeof(test)) )); + static assert(is( typeof(test) == FunctionTypeOf!test )); + static assert(is( typeof(test) == FunctionTypeOf!test_fp )); + static assert(is( typeof(test) == FunctionTypeOf!test_dg )); + alias int GetterType() @property; + alias int SetterType(int) @property; + static assert(is( FunctionTypeOf!propGet == GetterType )); + static assert(is( FunctionTypeOf!propSet == SetterType )); + + interface Prop { int prop() @property; } + Prop prop; + static assert(is( FunctionTypeOf!(Prop.prop) == GetterType )); + static assert(is( FunctionTypeOf!(prop.prop) == GetterType )); + + class Callable { int opCall(int) { return 0; } } + auto call = new Callable; + static assert(is( FunctionTypeOf!call == typeof(test) )); + + struct StaticCallable { static int opCall(int) { return 0; } } + StaticCallable stcall_val; + StaticCallable* stcall_ptr; + static assert(is( FunctionTypeOf!stcall_val == typeof(test) )); + static assert(is( FunctionTypeOf!stcall_ptr == typeof(test) )); + + interface Overloads + { + void test(string); + real test(real); + int test(int); + int test() @property; + } + alias ov = __traits(getVirtualMethods, Overloads, "test"); + alias F_ov0 = FunctionTypeOf!(ov[0]); + alias F_ov1 = FunctionTypeOf!(ov[1]); + alias F_ov2 = FunctionTypeOf!(ov[2]); + alias F_ov3 = FunctionTypeOf!(ov[3]); + static assert(is(F_ov0* == void function(string))); + static assert(is(F_ov1* == real function(real))); + static assert(is(F_ov2* == int function(int))); + static assert(is(F_ov3* == int function() @property)); + + alias F_dglit = FunctionTypeOf!((int a){ return a; }); + static assert(is(F_dglit* : int function(int))); +} + +// std.traits.ReturnType +/* +Get the type of the return value from a function, +a pointer to function, a delegate, a struct +with an opCall, a pointer to a struct with an opCall, +or a class with an `opCall`. Please note that $(D_KEYWORD ref) +is not part of a type, but the attribute of the function +(see template $(LREF functionAttributes)). +*/ +template ReturnType(func...) +if (func.length == 1 /*&& isCallable!func*/) +{ + static if (is(FunctionTypeOf!func R == return)) + alias ReturnType = R; + else + static assert(0, "argument has no return type"); +} + +// +@safe unittest +{ + int foo(); + ReturnType!foo x; // x is declared as int +} + +@safe unittest +{ + struct G + { + int opCall (int i) { return 1;} + } + + alias ShouldBeInt = ReturnType!G; + static assert(is(ShouldBeInt == int)); + + G g; + static assert(is(ReturnType!g == int)); + + G* p; + alias pg = ReturnType!p; + static assert(is(pg == int)); + + class C + { + int opCall (int i) { return 1;} + } + + static assert(is(ReturnType!C == int)); + + C c; + static assert(is(ReturnType!c == int)); + + class Test + { + int prop() @property { return 0; } + } + alias R_Test_prop = ReturnType!(Test.prop); + static assert(is(R_Test_prop == int)); + + alias R_dglit = ReturnType!((int a) { return a; }); + static assert(is(R_dglit == int)); +} + +// std.traits.Parameters +/* +Get, as a tuple, the types of the parameters to a function, a pointer +to function, a delegate, a struct with an `opCall`, a pointer to a +struct with an `opCall`, or a class with an `opCall`. +*/ +template Parameters(func...) +if (func.length == 1 /*&& isCallable!func*/) +{ + static if (is(FunctionTypeOf!func P == function)) + alias Parameters = P; + else + static assert(0, "argument has no parameters"); +} + +// +@safe unittest +{ + int foo(int, long); + void bar(Parameters!foo); // declares void bar(int, long); + void abc(Parameters!foo[1]); // declares void abc(long); +} + +@safe unittest +{ + int foo(int i, bool b) { return 0; } + static assert(is(Parameters!foo == AliasSeq!(int, bool))); + static assert(is(Parameters!(typeof(&foo)) == AliasSeq!(int, bool))); + + struct S { real opCall(real r, int i) { return 0.0; } } + S s; + static assert(is(Parameters!S == AliasSeq!(real, int))); + static assert(is(Parameters!(S*) == AliasSeq!(real, int))); + static assert(is(Parameters!s == AliasSeq!(real, int))); + + class Test + { + int prop() @property { return 0; } + } + alias P_Test_prop = Parameters!(Test.prop); + static assert(P_Test_prop.length == 0); + + alias P_dglit = Parameters!((int a){}); + static assert(P_dglit.length == 1); + static assert(is(P_dglit[0] == int)); +} + +// Return `true` if `Type` has `member` that evaluates to `true` in a static if condition +enum isTrue(Type, string member) = __traits(compiles, { static if (__traits(getMember, Type, member)) {} else static assert(0); }); + +unittest +{ + static struct T + { + enum a = true; + enum b = false; + enum c = 1; + enum d = 45; + enum e = "true"; + enum f = ""; + enum g = null; + alias h = bool; + } + + static assert( isTrue!(T, "a")); + static assert(!isTrue!(T, "b")); + static assert( isTrue!(T, "c")); + static assert( isTrue!(T, "d")); + static assert( isTrue!(T, "e")); + static assert( isTrue!(T, "f")); + static assert(!isTrue!(T, "g")); + static assert(!isTrue!(T, "h")); +} + +template hasUDA(alias symbol, alias attribute) +{ + enum isAttr(T) = is(T == attribute); + + enum hasUDA = anySatisfy!(isAttr, __traits(getAttributes, symbol)); +} + +unittest +{ + enum SomeUDA; + + struct Test + { + int woUDA; + @SomeUDA int oneUDA; + @SomeUDA @SomeUDA int twoUDAs; + } + + static assert(hasUDA!(Test.oneUDA, SomeUDA)); + static assert(hasUDA!(Test.twoUDAs, SomeUDA)); + static assert(!hasUDA!(Test.woUDA, SomeUDA)); +} diff --git a/src/urt/io.d b/src/urt/io.d index 73fba66..2fae795 100644 --- a/src/urt/io.d +++ b/src/urt/io.d @@ -1,40 +1,81 @@ module urt.io; -import core.stdc.stdio; - - nothrow @nogc: -int write(const(char)[] str) -{ - return printf("%.*s", cast(int)str.length, str.ptr); -} -int writeln(const(char)[] str) +enum WriteTarget : ubyte { - return printf("%.*s\n", cast(int)str.length, str.ptr); + stdout = 0, + stderr = 1, + debugstring = 2, // Windows OutputDebugStringA } -int write(Args...)(ref Args args) - if (Args.length != 1 || !is(Args[0] : const(char)[])) +template write_to(WriteTarget target, bool newline = false) { - import urt.string.format; - import urt.mem.temp; + int write_to(const(char)[] str) + { + static if (target == WriteTarget.stdout || target == WriteTarget.stderr) + { + version (Espressif) + { + foreach (ch; str) + esp_rom_uart_putc(ch); + static if (newline) + esp_rom_uart_putc('\n'); + return cast(int) str.length; + } + else version (FreeStanding) + { + import urt.driver.uart : uart0_puts; + uart0_puts(str); + static if (newline) + uart0_puts("\n"); + return cast(int) str.length; + } + else + { + fwrite(str.ptr, 1, str.length, target == WriteTarget.stdout ? stdout : stderr); + if (newline) + fwrite("\n".ptr, 1, "\n".length, target == WriteTarget.stdout ? stdout : stderr); + return cast(int)(str.length + "\n".length); + } + } + else static if (target == WriteTarget.debugstring) + { + version (Windows) + { + import core.sys.windows.windows; + OutputDebugStringA(str.ptr); + static if (newline) + OutputDebugStringA("\n"); + return cast(int)str.length + newline; + } + else + { + // is stderr the best analogy on other platforms? + return write_to!(WriteTarget.stderr, newline)(str); + } + } + else + static assert(0, "Invalid WriteTarget"); + } - size_t len = concat(null, args).length; - const(char)[] t = concat(cast(char[])talloc(len), args); - return write(t); -} + int write_to(Args...)(ref Args args) + if (Args.length != 1 || !is(Args[0] : const(char)[])) + { + import urt.string.format; + import urt.mem.temp; -int writeln(Args...)(ref Args args) - if (Args.length != 1 || !is(Args[0] : const(char)[])) -{ - import urt.string.format; - import urt.mem.temp; - - return tconcat(args).writeln; + size_t len = concat(null, args).length; + const(char)[] t = concat(cast(char[])talloc(len), args); + return write_to(t); + } } -int writef(Args...)(const(char)[] fmt, ref Args args) +int writef_to(WriteTarget target, bool newline = false, Args...)(const(char)[] fmt, ref Args args) + if (Args.length == 0) + => write_to!(target, newline)(fmt); + +int writef_to(WriteTarget target, bool newline = false, Args...)(const(char)[] fmt, ref Args args) if (Args.length > 0) { import urt.string.format; @@ -42,23 +83,41 @@ int writef(Args...)(const(char)[] fmt, ref Args args) size_t len = format(null, fmt, args).length; const(char)[] t = format(cast(char[])talloc(len), fmt, args); - return write(t); + return write_to!(target, newline)(t); } -int writelnf(Args...)(const(char)[] fmt, ref Args args) - if (Args.length > 0) -{ - import urt.string.format; - import urt.mem.temp; +alias write = write_to!(WriteTarget.stdout, false); +alias writeln = write_to!(WriteTarget.stdout, true); +alias write_err = write_to!(WriteTarget.stderr, false); +alias writeln_err = write_to!(WriteTarget.stderr, true); +alias write_debug = write_to!(WriteTarget.debugstring, false); +alias writeln_debug = write_to!(WriteTarget.debugstring, true); - size_t len = format(null, fmt, args).length; - const(char)[] t = format(cast(char[])talloc(len), fmt, args); - return writeln(t); +void flush(WriteTarget target = WriteTarget.stdout)() nothrow @nogc +{ + version (Espressif) + { + // ROM UART writes are unbuffered + } + else version (FreeStanding) + { + // UART writes are unbuffered - nothing to flush + } + else + { + static if (target == WriteTarget.stdout || target == WriteTarget.stderr) + fflush(target == WriteTarget.stdout ? stdout : stderr); + } } +int writef(Args...)(ref Args args) + => writef_to!(WriteTarget.stdout, false)(args); +int writelnf(Args...)(ref Args args) + => writef_to!(WriteTarget.stdout, true)(args); + unittest { - writeln("Hello, World!"); + writeln("\nHello, World!"); writeln("Hello", " World!"); writelnf("Hello, World! {0}", "wow!"); @@ -69,3 +128,15 @@ unittest write("mister ", "robot "); writef("how do {0} do?\n", "you"); } + + +private: + +version (Espressif) +{ + // ROM UART putc -- in mask ROM, zero code size + extern(C) void esp_rom_uart_putc(char c) nothrow @nogc; +} +else version (FreeStanding) {} +else + import urt.internal.stdc.stdio : stdout, stderr, fwrite, fflush; diff --git a/src/urt/lifetime.d b/src/urt/lifetime.d index acb04d1..d08eb32 100644 --- a/src/urt/lifetime.d +++ b/src/urt/lifetime.d @@ -1,10 +1,9 @@ module urt.lifetime; +import urt.internal.lifetime : emplaceRef; // TODO: DESTROY THIS! T* emplace(T)(T* chunk) @safe pure { - import core.internal.lifetime : emplaceRef; - emplaceRef!T(*chunk); return chunk; } @@ -12,8 +11,6 @@ T* emplace(T)(T* chunk) @safe pure T* emplace(T, Args...)(T* chunk, auto ref Args args) if (is(T == struct) || Args.length == 1) { - import core.internal.lifetime : emplaceRef; - emplaceRef!T(*chunk, forward!args); return chunk; } @@ -21,7 +18,7 @@ T* emplace(T, Args...)(T* chunk, auto ref Args args) T emplace(T, Args...)(T chunk, auto ref Args args) if (is(T == class)) { - import core.internal.traits : isInnerClass; + import urt.internal.traits : isInnerClass; static assert(!__traits(isAbstractClass, T), T.stringof ~ " is abstract and it can't be emplaced"); @@ -73,8 +70,7 @@ T emplace(T, Args...)(void[] chunk, auto ref Args args) T* emplace(T, Args...)(void[] chunk, auto ref Args args) if (!is(T == class)) { - import core.internal.traits : Unqual; - import core.internal.lifetime : emplaceRef; + import urt.traits : Unqual; assert(chunk.length >= T.sizeof, "chunk size too small."); assert((cast(size_t) chunk.ptr) % T.alignof == 0, "emplace: Chunk is not aligned."); @@ -83,12 +79,11 @@ T* emplace(T, Args...)(void[] chunk, auto ref Args args) return cast(T*) chunk.ptr; } - /+ void copyEmplace(S, T)(ref S source, ref T target) @system if (is(immutable S == immutable T)) { - import core.internal.traits : BaseElemOf, hasElaborateCopyConstructor, Unconst, Unqual; + import urt.internal.traits : BaseElemOf, hasElaborateCopyConstructor, Unconst, Unqual; // cannot have the following as simple template constraint due to nested-struct special case... static if (!__traits(compiles, (ref S src) { T tgt = src; })) @@ -100,7 +95,7 @@ void copyEmplace(S, T)(ref S source, ref T target) @system void blit() { - import core.stdc.string : memcpy; + import urt.mem : memcpy; memcpy(cast(Unqual!(T)*) &target, cast(Unqual!(T)*) &source, T.sizeof); } @@ -203,7 +198,7 @@ T move(T)(return scope ref T source) nothrow @nogc private void moveImpl(T)(scope ref T target, return scope ref T source) nothrow @nogc { - import core.internal.traits : hasElaborateDestructor; + import urt.internal.traits : hasElaborateDestructor; static if (is(T == struct)) { @@ -225,7 +220,7 @@ private T moveImpl(T)(return scope ref T source) nothrow @nogc return trustedMoveImpl(source); } -private T trustedMoveImpl(T)(return scope ref T source) @trusted nothrow @nogc +private T trustedMoveImpl(T)(return scope ref T source) nothrow @nogc @trusted { T result = void; moveEmplaceImpl(result, source); @@ -242,7 +237,7 @@ private enum bool hasContextPointers(T) = { } else static if (is(T == struct)) { - import core.internal.traits : anySatisfy; + import urt.internal.traits : anySatisfy; return __traits(isNested, T) || anySatisfy!(hasContextPointers, typeof(T.tupleof)); } else return false; @@ -259,8 +254,8 @@ private void moveEmplaceImpl(T)(scope ref T target, return scope ref T source) @ // "Cannot move object with internal pointer unless `opPostMove` is defined."); // } - import core.internal.traits : hasElaborateAssign, isAssignable, hasElaborateMove, - hasElaborateDestructor, hasElaborateCopyConstructor; + import urt.internal.traits : hasElaborateAssign, isAssignable, hasElaborateMove, + hasElaborateDestructor, hasElaborateCopyConstructor; static if (is(T == struct)) { @@ -269,7 +264,7 @@ private void moveEmplaceImpl(T)(scope ref T target, return scope ref T source) @ static if (hasElaborateAssign!T || !isAssignable!T) { - import core.stdc.string : memcpy; + import urt.mem : memcpy; () @trusted { memcpy(&target, &source, T.sizeof); }(); } else @@ -327,20 +322,11 @@ void moveEmplace(T)(ref T source, ref T target) @system @nogc -//debug = PRINTF; - -debug(PRINTF) -{ - import core.stdc.stdio; -} - /// Implementation of `_d_delstruct` and `_d_delstructTrace` template _d_delstructImpl(T) { private void _d_delstructImpure(ref T p) { - debug(PRINTF) printf("_d_delstruct(%p)\n", p); - destroy(*p); p = null; } @@ -360,7 +346,7 @@ template _d_delstructImpl(T) * `@trusted` until the implementation can be brought up to modern D * expectations. */ - void _d_delstruct(ref T p) @trusted @nogc pure nothrow + void _d_delstruct(ref T p) nothrow @nogc pure @trusted { if (p) { @@ -392,7 +378,7 @@ template _d_delstructImpl(T) // wipes source after moving pragma(inline, true) -private void wipe(T, Init...)(return scope ref T source, ref const scope Init initializer) @trusted nothrow @nogc +private void wipe(T, Init...)(return scope ref T source, ref const scope Init initializer) nothrow @nogc @trusted if (!Init.length || ((Init.length == 1) && (is(immutable T == immutable Init[0])))) { @@ -406,7 +392,7 @@ if (!Init.length || } else static if (is(T == struct) && hasContextPointers!T) { - import core.internal.traits : anySatisfy; + import urt.internal.traits : anySatisfy; static if (anySatisfy!(hasContextPointers, typeof(T.tupleof))) { static foreach (i; 0 .. T.tupleof.length - __traits(isNested, T)) @@ -430,7 +416,7 @@ if (!Init.length || } else { - import core.internal.traits : hasElaborateAssign, isAssignable; + import urt.internal.traits : hasElaborateAssign, isAssignable; static if (Init.length) { static if (hasElaborateAssign!T || !isAssignable!T) @@ -449,7 +435,7 @@ if (!Init.length || T _d_newclassT(T)() @trusted if (is(T == class)) { - import core.internal.traits : hasIndirections; + import urt.internal.traits : hasIndirections; import core.exception : onOutOfMemoryError; import core.memory : pureMalloc; import core.memory : GC; @@ -478,27 +464,11 @@ T _d_newclassT(T)() @trusted attr |= BlkAttr.NO_SCAN; p = GC.malloc(init.length, attr, typeid(T)); - debug(PRINTF) printf(" p = %p\n", p); - } - - debug(PRINTF) - { - printf("p = %p\n", p); - printf("init.ptr = %p, len = %llu\n", init.ptr, cast(ulong)init.length); - printf("vptr = %p\n", *cast(void**) init); - printf("vtbl[0] = %p\n", (*cast(void***) init)[0]); - printf("vtbl[1] = %p\n", (*cast(void***) init)[1]); - printf("init[0] = %x\n", (cast(uint*) init)[0]); - printf("init[1] = %x\n", (cast(uint*) init)[1]); - printf("init[2] = %x\n", (cast(uint*) init)[2]); - printf("init[3] = %x\n", (cast(uint*) init)[3]); - printf("init[4] = %x\n", (cast(uint*) init)[4]); } // initialize it p[0 .. init.length] = init[]; - debug(PRINTF) printf("initialization done\n"); return cast(T) p; } @@ -541,7 +511,7 @@ T _d_newclassTTrace(T)(string file, int line, string funcname) @trusted T* _d_newitemT(T)() @trusted { import core.internal.lifetime : emplaceInitializer; - import core.internal.traits : hasIndirections; + import urt.internal.traits : hasIndirections; import core.memory : GC; auto flags = !hasIndirections!T ? GC.BlkAttr.NO_SCAN : GC.BlkAttr.NONE; @@ -587,7 +557,7 @@ version (D_ProfileGC) template TypeInfoSize(T) { - import core.internal.traits : hasElaborateDestructor; + import urt.internal.traits : hasElaborateDestructor; enum TypeInfoSize = hasElaborateDestructor!T ? size_t.sizeof : 0; } +/ diff --git a/src/urt/log.d b/src/urt/log.d index 71af7fd..e7a3bb7 100644 --- a/src/urt/log.d +++ b/src/urt/log.d @@ -1,8 +1,183 @@ module urt.log; -import urt.io; +import urt.mem.temp : tconcat, tconcat_impl, tformat; +import urt.string.format : normalise_args; +import urt.time; -enum Level +nothrow @nogc: + + +enum Severity : ubyte +{ + emergency = 0, + alert = 1, + critical = 2, + error = 3, + warning = 4, + notice = 5, + info = 6, + debug_ = 7, + trace = 8, +} + +immutable string[9] severity_names = [ + "Emergency", "Alert", "Critical", "Error", "Warning", "Notice", "Info", "Debug", "Trace" +]; + +struct LogMessage +{ + Severity severity; + const(char)[] tag; + const(char)[] object_name; + const(char)[] message; + MonoTime timestamp; +} + +struct LogFilter +{ + Severity max_severity = Severity.info; + const(char)[] tag_prefix; +} + +alias SinkOutputFn = void function(void* context, scope ref const LogMessage msg) nothrow @nogc; + +struct LogSinkHandle +{ + int index = -1; + bool valid() const pure nothrow @nogc + => index >= 0 && index < max_sinks; +} + +LogSinkHandle register_log_sink(SinkOutputFn output, void* context = null, LogFilter filter = LogFilter.init) +{ + foreach (i, ref sink; g_sinks) + { + if (!sink.active) + { + sink.output = output; + sink.context = context; + sink.filter = filter; + sink.enabled = true; + sink.active = true; + recalc_max_severity(); + return LogSinkHandle(cast(int)i); + } + } + return LogSinkHandle(-1); +} + +void unregister_log_sink(LogSinkHandle handle) +{ + if (!handle.valid) + return; + g_sinks[handle.index] = SinkSlot.init; + recalc_max_severity(); +} + +void set_sink_filter(LogSinkHandle handle, LogFilter filter) +{ + if (!handle.valid) + return; + g_sinks[handle.index].filter = filter; + recalc_max_severity(); +} + +void set_sink_enabled(LogSinkHandle handle, bool enabled) +{ + if (!handle.valid) + return; + g_sinks[handle.index].enabled = enabled; + recalc_max_severity(); +} + +void log_emergency(T...)(const(char)[] tag, ref T args) { write_log(Severity.emergency, tag, null, args); } +void log_alert(T...)(const(char)[] tag, ref T args) { write_log(Severity.alert, tag, null, args); } +void log_critical(T...)(const(char)[] tag, ref T args) { write_log(Severity.critical, tag, null, args); } +void log_error(T...)(const(char)[] tag, ref T args) { write_log(Severity.error, tag, null, args); } +void log_warning(T...)(const(char)[] tag, ref T args) { write_log(Severity.warning, tag, null, args); } +void log_notice(T...)(const(char)[] tag, ref T args) { write_log(Severity.notice, tag, null, args); } +void log_info(T...)(const(char)[] tag, ref T args) { write_log(Severity.info, tag, null, args); } + +void log_emergencyf(T...)(const(char)[] tag, const(char)[] fmt, ref T args) { write_logf(Severity.emergency, tag, null, fmt, args); } +void log_alertf(T...)(const(char)[] tag, const(char)[] fmt, ref T args) { write_logf(Severity.alert, tag, null, fmt, args); } +void log_criticalf(T...)(const(char)[] tag, const(char)[] fmt, ref T args) { write_logf(Severity.critical, tag, null, fmt, args); } +void log_errorf(T...)(const(char)[] tag, const(char)[] fmt, ref T args) { write_logf(Severity.error, tag, null, fmt, args); } +void log_warningf(T...)(const(char)[] tag, const(char)[] fmt, ref T args) { write_logf(Severity.warning, tag, null, fmt, args); } +void log_noticef(T...)(const(char)[] tag, const(char)[] fmt, ref T args) { write_logf(Severity.notice, tag, null, fmt, args); } +void log_infof(T...)(const(char)[] tag, const(char)[] fmt, ref T args) { write_logf(Severity.info, tag, null, fmt, args); } + +void log_debug(T...)(const(char)[] tag, ref T args) { write_log(Severity.debug_, tag, null, args); } +void log_trace(T...)(const(char)[] tag, ref T args) { write_log(Severity.trace, tag, null, args); } +void log_debugf(T...)(const(char)[] tag, const(char)[] fmt, ref T args) { write_logf(Severity.debug_, tag, null, fmt, args); } +void log_tracef(T...)(const(char)[] tag, const(char)[] fmt, ref T args) { write_logf(Severity.trace, tag, null, fmt, args); } + +// this can be declared in any scope to automatically prefix log messages with a tag (e.g. module name) +// eg: alias log = Log!"my.module"; +// log.warn("oh no!"); +template Log(string tag) +{ + void info(T...)(ref T args) { write_log(Severity.info, tag, null, args); } + void warning(T...)(ref T args) { write_log(Severity.warning, tag, null, args); } + void error(T...)(ref T args) { write_log(Severity.error, tag, null, args); } + void notice(T...)(ref T args) { write_log(Severity.notice, tag, null, args); } + void critical(T...)(ref T args) { write_log(Severity.critical, tag, null, args); } + void alert(T...)(ref T args) { write_log(Severity.alert, tag, null, args); } + void emergency(T...)(ref T args) { write_log(Severity.emergency, tag, null, args); } + + void infof(T...)(const(char)[] fmt, ref T args) { write_logf(Severity.info, tag, null, fmt, args); } + void warningf(T...)(const(char)[] fmt, ref T args) { write_logf(Severity.warning, tag, null, fmt, args); } + void errorf(T...)(const(char)[] fmt, ref T args) { write_logf(Severity.error, tag, null, fmt, args); } + void noticef(T...)(const(char)[] fmt, ref T args) { write_logf(Severity.notice, tag, null, fmt, args); } + void criticalf(T...)(const(char)[] fmt, ref T args) { write_logf(Severity.critical, tag, null, fmt, args); } + void alertf(T...)(const(char)[] fmt, ref T args) { write_logf(Severity.alert, tag, null, fmt, args); } + void emergencyf(T...)(const(char)[] fmt, ref T args) { write_logf(Severity.emergency, tag, null, fmt, args); } + + void debug_(T...)(ref T args) { write_log(Severity.debug_, tag, null, args); } + void trace(T...)(ref T args) { write_log(Severity.trace, tag, null, args); } + void debugf(T...)(const(char)[] fmt, ref T args) { write_logf(Severity.debug_, tag, null, fmt, args); } + void tracef(T...)(const(char)[] fmt, ref T args) { write_logf(Severity.trace, tag, null, fmt, args); } +} + +void write_log(T...)(Severity severity, const(char)[] tag, const(char)[] object_name, ref T args) +{ + if (severity > g_max_severity) + return; + import urt.string, urt.array; + static if (T.length == 1 && (is(T[0] : const(char)[]) || is(T[0] : const String) || is(T[0] : const MutableString!N, size_t N) || is(T[0] : const Array!char))) + auto msg = LogMessage(severity, tag, object_name, args[0][], getTime()); + else + auto msg = LogMessage(severity, tag, object_name, tconcat_impl(normalise_args(args)), getTime()); + write_log(msg); +} + +void write_logf(T...)(Severity severity, const(char)[] tag, const(char)[] object_name, const(char)[] fmt, ref T args) +{ + if (severity > g_max_severity) + return; + auto msg = LogMessage(severity, tag, object_name, tformat(fmt, args), getTime()); + write_log(msg); +} + +void write_log(scope ref const LogMessage msg) +{ + import urt.string : startsWith; + + foreach (ref sink; g_sinks) + { + if (!sink.active || !sink.enabled) + continue; + if (msg.severity > sink.filter.max_severity) + continue; + if (sink.filter.tag_prefix.length > 0 && !msg.tag.startsWith(sink.filter.tag_prefix)) + continue; + sink.output(sink.context, msg); + } +} + + +// --- backward compatibility (deprecated) --- + +enum Level : ubyte { Error = 0, Warning, @@ -10,7 +185,18 @@ enum Level Debug } -immutable string[] levelNames = [ "Error", "Warning", "Info", "Debug" ]; +immutable string[] levelNames = ["Error", "Warning", "Info", "Debug"]; + +Severity level_to_severity(Level level) +{ + final switch (level) + { + case Level.Error: return Severity.error; + case Level.Warning: return Severity.warning; + case Level.Info: return Severity.info; + case Level.Debug: return Severity.debug_; + } +} __gshared Level logLevel = Level.Info; @@ -26,14 +212,52 @@ void writeErrorf(T...)(const(char)[] format, ref T things) { writeLogf(Level.Err void writeLog(T...)(Level level, ref T things) { - if (level > logLevel) + Severity sev = level_to_severity(level); + if (sev > g_max_severity) return; - writeln(levelNames[level], ": ", things); + write_log(sev, null, null, things); } void writeLogf(T...)(Level level, const(char)[] format, ref T things) { - if (level > logLevel) - return; - writelnf("{-2}: {@-1}", things, levelNames[level], format); + write_logf(level_to_severity(level), null, null, format, things); +} + +alias LegacyLogSink = void function(Level level, scope const(char)[] message) nothrow @nogc; + +private void legacy_sink_adapter(void* context, scope ref const LogMessage msg) nothrow @nogc +{ + __gshared immutable Level[9] map = [Level.Error, Level.Error, Level.Error, Level.Error, Level.Warning, Level.Info, Level.Info, Level.Debug, Level.Debug]; + (cast(LegacyLogSink)context)(map[msg.severity], msg.message); +} + +LogSinkHandle register_log_sink(LegacyLogSink sink) + => register_log_sink(&legacy_sink_adapter, cast(void*)sink); + + +private: + +enum max_sinks = 16; + +struct SinkSlot +{ + SinkOutputFn output; + void* context; + LogFilter filter; + bool enabled; + bool active; +} + +__gshared SinkSlot[max_sinks] g_sinks; +__gshared Severity g_max_severity = Severity.info; + +void recalc_max_severity() +{ + Severity max_sev = Severity.emergency; + foreach (ref sink; g_sinks) + { + if (sink.active && sink.enabled && sink.filter.max_severity > max_sev) + max_sev = sink.filter.max_severity; + } + g_max_severity = max_sev; } diff --git a/src/urt/map.d b/src/urt/map.d index 732fc79..0e79d6b 100644 --- a/src/urt/map.d +++ b/src/urt/map.d @@ -42,14 +42,14 @@ struct AVLTree(K, V, alias Pred = DefCmp!K, Allocator = Mallocator) } size_t length() const nothrow - => numNodes; + => _num_modes; bool empty() const nothrow - => numNodes == 0; + => _num_modes == 0; void clear() nothrow { - destroy(pRoot); - pRoot = null; + destroy(_root); + _root = null; } V* insert(_K, _V)(auto ref _K key, auto ref _V val) @@ -167,11 +167,13 @@ struct AVLTree(K, V, alias Pred = DefCmp!K, Allocator = Mallocator) { Node* node = cast(Node*)Allocator.instance.alloc(Node.sizeof); emplace(&node.kvp, forward!key, forward!val); - node.left = node.right = null; - node.height = 1; - pRoot = insert(pRoot, node); + node._base.left = node._base.right = null; + node._base.height = 1; + node._base.key_offset = Node.kvp.offsetof + KVP!(K, V).key.offsetof; + _root = insert(_root, node); return node.kvp.value; } + /+ V& replace(K &&key, V &&val) { @@ -180,7 +182,7 @@ struct AVLTree(K, V, alias Pred = DefCmp!K, Allocator = Mallocator) epConstruct(&node.kvp) KVP(std::move(key), std::move(val)); node.left = node.right = null; node.height = 1; - pRoot = insert(pRoot, node); + _root = insert(_root, node); return node.kvp.value; } V& replace(const K &key, V &&val) @@ -190,7 +192,7 @@ struct AVLTree(K, V, alias Pred = DefCmp!K, Allocator = Mallocator) epConstruct(&node.kvp) KVP(key, std::move(val)); node.left = node.right = null; node.height = 1; - pRoot = insert(pRoot, node); + _root = insert(_root, node); return node.kvp.value; } V& replace(K &&key, const V &val) @@ -200,7 +202,7 @@ struct AVLTree(K, V, alias Pred = DefCmp!K, Allocator = Mallocator) epConstruct(&node.kvp) KVP(std::move(key), val); node.left = node.right = null; node.height = 1; - pRoot = insert(pRoot, node); + _root = insert(_root, node); return node.kvp.value; } V& replace(const K &key, const V &val) @@ -210,7 +212,7 @@ struct AVLTree(K, V, alias Pred = DefCmp!K, Allocator = Mallocator) epConstruct(&node.kvp) KVP(key, val); node.left = node.right = null; node.height = 1; - pRoot = insert(pRoot, node); + _root = insert(_root, node); return node.kvp.value; } @@ -221,7 +223,7 @@ struct AVLTree(K, V, alias Pred = DefCmp!K, Allocator = Mallocator) epConstruct(&node.kvp) KVP(std::move(kvp)); node.left = node.right = null; node.height = 1; - pRoot = insert(pRoot, node); + _root = insert(_root, node); return node.kvp.value; } V& replace(const KVP &kvp) @@ -231,19 +233,19 @@ struct AVLTree(K, V, alias Pred = DefCmp!K, Allocator = Mallocator) epConstruct(&node.kvp) KVP(kvp); node.left = node.right = null; node.height = 1; - pRoot = insert(pRoot, node); + _root = insert(_root, node); return node.kvp.value; } +/ void remove(_K)(ref const _K key) { - pRoot = deleteNode(pRoot, key); + _root = delete_node(_root, key); } inout(V)* get(_K)(ref const _K key) inout { - inout(Node)* n = find(pRoot, key); + inout(Node)* n = find(_root, key); return n ? &n.kvp.value : null; } @@ -289,288 +291,117 @@ struct AVLTree(K, V, alias Pred = DefCmp!K, Allocator = Mallocator) // TODO: why don't the const overloads work properly? auto keys() const nothrow - => Range!(IterateBy.Keys, true)(pRoot); + => Range!(IterateBy.Keys, true)(_root); auto values() nothrow - => Range!(IterateBy.Values)(pRoot); -// auto values() const nothrow -// => Range!(IterateBy.Values, true)(pRoot); + => Range!(IterateBy.Values)(_root); + auto values() const nothrow + => Range!(IterateBy.Values, true)(_root); auto opIndex() nothrow - => Range!(IterateBy.KVP)(pRoot); -// auto opIndex() const nothrow -// => Range!(IterateBy.KVP, true)(pRoot); - -private: -nothrow: - alias Node = AVLTreeNode!(K, V); + => Range!(IterateBy.KVP)(_root); + auto opIndex() const nothrow + => Range!(IterateBy.KVP, true)(_root); - size_t numNodes = 0; - Node* pRoot = null; - - static int height(const(Node)* n) pure + import urt.string.format : FormatArg, formatValue; + ptrdiff_t toString()(char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) const { - return n ? n.height : 0; - } + if (buffer.ptr is null) + { + // count the buffer size + size_t size = 2, comma = 0; + foreach (kvp; this) + { + size += comma; + comma = 1; + ptrdiff_t len = formatValue(kvp.key, buffer, format, formatArgs); + if (len < 0) + return len; + size += len + 1; + len = formatValue(kvp.value, buffer, format, formatArgs); + if (len < 0) + return len; + size += len; + } + return size; + } - static int maxHeight(const(Node)* n) pure - { - if (!n) - return 0; - if (n.left) + if (buffer.length < 2) + return -1; + buffer[0] = '{'; + + size_t offset = 1; + bool add_comma = false; + foreach (kvp; this) { - if (n.right) - return max(n.left.height, n.right.height); + if (add_comma) + { + if (offset >= buffer.length) + return -1; + buffer[offset++] = ','; + } else - return n.left.height; + add_comma = true; + ptrdiff_t len = formatValue(kvp.key, buffer[offset .. $], format, formatArgs); + if (len < 0) + return len; + offset += len; + if (offset >= buffer.length) + return -1; + buffer[offset++] = ':'; + len = formatValue(kvp.value, buffer[offset .. $], format, formatArgs); + if (len < 0) + return len; + offset += len; } - if (n.right) - return n.right.height; - return 0; - } - static int getBalance(Node* n) pure - { - return n ? height(n.left) - height(n.right) : 0; + if (offset >= buffer.length) + return -1; + buffer[offset++] = '}'; + return offset; } - static Node* rightRotate(Node* y) pure + ptrdiff_t fromString()(const(char)[] s) { - Node* x = y.left; - Node* T2 = x.right; - - // Perform rotation - x.right = y; - y.left = T2; - - // Update heights - y.height = maxHeight(y) + 1; - x.height = maxHeight(x) + 1; - - // Return new root - return x; + assert(false, "TODO"); } - static Node* leftRotate(Node* x) pure - { - Node* y = x.right; - Node* T2 = y.left; - - // Perform rotation - y.left = x; - x.right = T2; +private: +nothrow: + alias Node = AVLTreeNode!(K, V); - // Update heights - x.height = maxHeight(x) + 1; - y.height = maxHeight(y) + 1; + size_t _num_modes = 0; + Node* _root = null; - // Return new root - return y; - } + static ptrdiff_t compare_node(const void* a, const void* b) pure + => Pred(*cast(K*)a, *cast(K*)b); - static inout(Node)* find(_K)(inout(Node)* n, ref const _K key) + static void free_node(void* p) { - if (n is null) - return null; - ptrdiff_t c = Pred(n.kvp.key, key); - if (c > 0) - return find(n.left, key); - if (c < 0) - return find(n.right, key); - return n; + Allocator.instance.freeT(cast(Node*)p); } + static inout(Node)* find(_K)(inout(Node)* n, ref const _K key) pure + => cast(inout(Node)*)find_node(n.base, (a, b) => Pred(*cast(K*)a, *cast(_K*)b), &key); + void destroy(Node* n) { - if (n is null) - return; - - destroy(n.left); - destroy(n.right); - - Allocator.instance.freeT(n); - - --numNodes; + _num_modes -= destroy_node(n.base, &free_node); } Node* insert(Node* n, Node* newnode) { - // 1. Perform the normal BST rotation - if (n is null) - { - ++numNodes; - return newnode; - } - - ptrdiff_t c = Pred(newnode.kvp.key, n.kvp.key); - if (c < 0) - n.left = insert(n.left, newnode); - else if (c > 0) - n.right = insert(n.right, newnode); - else - { - newnode.left = n.left; - newnode.right = n.right; - newnode.height = n.height; - - Allocator.instance.freeT(n); - - return newnode; - } - - // 2. Update height of this ancestor Node - n.height = maxHeight(n) + 1; - - // 3. get the balance factor of this ancestor Node to check whether - // this Node became unbalanced - int balance = getBalance(n); - - // If this Node becomes unbalanced, then there are 4 cases - - if (balance > 1) - { - ptrdiff_t lc = Pred(newnode.kvp.key, n.left.kvp.key); - // Left Left Case - if (lc < 0) - return rightRotate(n); - - // Left Right Case - if (lc > 0) - { - n.left = leftRotate(n.left); - return rightRotate(n); - } - } - - if (balance < -1) - { - ptrdiff_t rc = Pred(newnode.kvp.key, n.right.kvp.key); - - // Right Right Case - if (rc > 0) - return leftRotate(n); - - // Right Left Case - if (rc < 0) - { - n.right = rightRotate(n.right); - return leftRotate(n); - } - } - - // return the (unchanged) Node pointer - return n; - } - - Node* deleteNode(_K)(Node* _pRoot, ref const _K key) - { - // STEP 1: PERFORM STANDARD BST DELETE - - if (_pRoot is null) - return _pRoot; - - ptrdiff_t c = Pred(_pRoot.kvp.key, key); - - // If the key to be deleted is smaller than the _pRoot's key, - // then it lies in left subtree - if (c > 0) - _pRoot.left = deleteNode(_pRoot.left, key); - - // If the key to be deleted is greater than the _pRoot's key, - // then it lies in right subtree - else if (c < 0) - _pRoot.right = deleteNode(_pRoot.right, key); - - // if key is same as _pRoot's key, then this is the Node - // to be deleted - else - _pRoot = doDelete(_pRoot); - - return rebalance(_pRoot); + return cast(Node*)insert_node(n.base, newnode.base, _num_modes, + &compare_node, + &free_node); } - Node* doDelete(Node* _pRoot) + Node* delete_node(_K)(Node* _pRoot, ref const _K key) { - // Node with only one child or no child - if ((_pRoot.left is null) || (_pRoot.right is null)) - { - Node* temp = _pRoot.left ? _pRoot.left : _pRoot.right; - - // No child case - if (temp is null) - { - temp = _pRoot; - _pRoot = null; - } - else // One child case - { - // TODO: FIX THIS!! - // this is copying the child node into the parent node because there is no parent pointer - // DO: add parent pointer, then fix up the parent's child pointer to the child, and do away with this pointless copy! - *_pRoot = (*temp).move; // Copy the contents of the non-empty child - } - - Allocator.instance.freeT(temp); - - --numNodes; - } - else - { - // Node with two children: we replace 'this' node with the next one in sequence... - - // get the in-order successor: the 'next' item is the far left node on the right hand side) - Node* next = _pRoot.right; - while (next.left !is null) // find the leftmost leaf - next = next.left; - + return cast(Node*).delete_node(_pRoot.base, &key, _num_modes, &compare_node, (void* from, void* to) { // Copy the in-order successor's data to this Node - _pRoot.kvp.key = next.kvp.key; // we can't move the key, because deleteNode still needs to be able to find it - _pRoot.kvp.value = next.kvp.value.move; - - // Delete the node we just shifted - _pRoot.right = deleteNode(_pRoot.right, next.kvp.key); - } - - return _pRoot; - } - - Node* rebalance(Node* _pRoot) - { - // If the tree had only one Node then return - if (_pRoot is null) - return null; - - // STEP 2: UPDATE HEIGHT OF THE CURRENT NODE - _pRoot.height = max(height(_pRoot.left), height(_pRoot.right)) + 1; - - // STEP 3: GET THE BALANCE FACTOR OF THIS NODE (to check whether - // this Node became unbalanced) - int balance = getBalance(_pRoot); - - // If this Node becomes unbalanced, then there are 4 cases - - // Left Left Case - if (balance > 1 && getBalance(_pRoot.left) >= 0) - return rightRotate(_pRoot); - - // Left Right Case - if (balance > 1 && getBalance(_pRoot.left) < 0) - { - _pRoot.left = leftRotate(_pRoot.left); - return rightRotate(_pRoot); - } - - // Right Right Case - if (balance < -1 && getBalance(_pRoot.right) <= 0) - return leftRotate(_pRoot); - - // Right Left Case - if (balance < -1 && getBalance(_pRoot.right) > 0) - { - _pRoot.right = rightRotate(_pRoot.right); - return leftRotate(_pRoot); - } - - return _pRoot; + (cast(Node*)to).kvp.key = (cast(Node*)from).kvp.key; // we can't move the key, because delete_node still needs to be able to find it + (cast(Node*)to).kvp.value = (cast(Node*)from).kvp.value.move; + }, &free_node); } // static Node* clone(Node* pOld) @@ -657,9 +488,7 @@ public: PN n; ref const(K) key() @property const pure => n.kvp.key; -// ref const(V) value() @property const pure -// => n.kvp.value; - ref V value() @property pure + ref inout(V) value() @property inout pure => n.kvp.value; } return KV(n); @@ -688,14 +517,37 @@ public: } } } +struct BaseNode +{ + BaseNode* left, right; + ushort key_offset; + ushort height; +} struct AVLTreeNode(K, V) { nothrow @nogc: - AVLTreeNode* left, right; + alias _base this; + + BaseNode _base; KVP!(K, V) kvp; - int height; + + inout(BaseNode)* base() inout pure @property + => &_base; + + inout(AVLTreeNode)* left() inout pure @property + => cast(inout(AVLTreeNode)*)_base.left; + void left(AVLTreeNode* node) pure @property + { + _base.left = node.base; + } + inout(AVLTreeNode)* right() inout pure @property + => cast(inout(AVLTreeNode)*)_base.right; + void right(AVLTreeNode* node) pure @property + { + _base.right = node.base; + } this() @disable; @@ -711,7 +563,7 @@ nothrow @nogc: left = rh.left; right = rh.right; kvp = rh.kvp; - height = rh.height; + _base.height = rh._base.height; } ref AVLTreeNode opAssign(ref AVLTreeNode rh) @@ -729,49 +581,6 @@ nothrow @nogc: } } -/+ -template -ptrdiff_t epStringify(Slice buffer, String epUnusedParam(format), const AVLTree &tree, const VarArg* epUnusedParam(pArgs)) -{ - size_t offset = 0; - if (buffer) - offset += String("{ ").copyTo(buffer); - else - offset += String("{ ").length; - - bool bFirst = true; - for (auto &&kvp : tree) - { - if (!bFirst) - { - if (buffer) - offset += String(", ").copyTo(buffer.drop(offset)); - else - offset += String(", ").length; - } - else - bFirst = false; - - if (buffer) - offset += epStringify(buffer.drop(offset), null, kvp, null); - else - offset += epStringify(null, null, kvp, null); - } - - if (buffer) - offset += String(" }").copyTo(buffer.drop(offset)); - else - offset += String(" }").length; - - return offset; -} -+/ - -//// Range retrieval -//template -//TreeRange> range(const AVLTree &input) { return TreeRange>(input); } - - unittest { @@ -900,7 +709,7 @@ unittest assert(map.get(2) is null); } - // Iteration (opApply) + // Iteration (range) { TestAVLTree map; map.insert(3, 30); @@ -908,25 +717,43 @@ unittest map.insert(2, 20); map.insert(4, 40); - int sumKeys = 0; - int sumValues = 0; - int count = 0; - // Iterate key-value pairs + int sumKeys = 0, sumValues = 0, count = 0; foreach (kv; map) { sumKeys += kv.key; sumValues += kv.value; count++; } + assert(count == 4); + assert(sumKeys == 1 + 2 + 3 + 4); + assert(sumValues == 10 + 20 + 30 + 40); + // Iterate const key-value pairs + ref const cmap = map; + sumKeys = sumValues = count = 0; + foreach (kv; cmap) + { + sumKeys += kv.key; + sumValues += kv.value; + count++; + } assert(count == 4); assert(sumKeys == 1 + 2 + 3 + 4); assert(sumValues == 10 + 20 + 30 + 40); - sumValues = 0; - count = 0; + // Iterate keys only + sumKeys = 0, count = 0; + foreach (v; map.keys) + { + sumKeys += v; + count++; + } + assert(count == 4); + assert(sumKeys == 1 + 2 + 3 + 4); + // Iterate values only + sumValues = 0, count = 0; foreach (v; map.values) { sumValues += v; @@ -935,6 +762,16 @@ unittest assert(count == 4); assert(sumValues == 10 + 20 + 30 + 40); + // Iterate const values only + sumValues = 0, count = 0; + foreach (v; cmap.values) + { + sumValues += v; + count++; + } + assert(count == 4); + assert(sumValues == 10 + 20 + 30 + 40); + // Test stopping iteration count = 0; foreach (k; map.keys) @@ -946,27 +783,6 @@ unittest assert(count == 2); // Should stop after 1 and 2 } - // Iteration (Iterator struct) - { - TestAVLTree map; - map.insert(3, 30); - map.insert(1, 10); - map.insert(2, 20); - map.insert(4, 40); - - foreach (kvp; map) // Uses Iterator internally - { - // Note: D's foreach over structs with opApply might not directly use the Iterator struct - // but opApply tests cover the iteration logic. - // This loop tests if the basic range primitives work. - // A direct Iterator test: - } - - // Test empty map iteration - TestAVLTree emptyMap; - assert(emptyMap[].empty); - } - // Test with string keys { alias StringMap = AVLTree!(const(char)[], int); @@ -997,3 +813,276 @@ unittest assert(count == 2); } } + + +private: + +alias CompFn = ptrdiff_t function(const void* a, const void* b) pure nothrow @nogc; +alias MoveFn = void function(void* from, void* to) nothrow @nogc; +alias DestroyFn = void function(void* a) nothrow @nogc; + +inout(void)* node_key(inout(BaseNode)* n) pure + => cast(inout(void)*)n + n.key_offset; + +ushort height(const(BaseNode)* n) pure +{ + return n ? n.height : 0; +} + +ushort max_height(const(BaseNode)* n) pure +{ + if (!n) + return 0; + if (n.left) + { + if (n.right) + return max(n.left.height, n.right.height); + else + return n.left.height; + } + if (n.right) + return n.right.height; + return 0; +} + +int get_balance(BaseNode* n) pure +{ + return n ? height(n.left) - height(n.right) : 0; +} + +BaseNode* right_rotate(BaseNode* y) pure +{ + BaseNode* x = y.left; + BaseNode* T2 = x.right; + + // Perform rotation + x.right = y; + y.left = T2; + + // Update heights + y.height = cast(ushort)(max_height(y) + 1); + x.height = cast(ushort)(max_height(x) + 1); + + // Return new root + return x; +} + +BaseNode* left_rotate(BaseNode* x) pure +{ + BaseNode* y = x.right; + BaseNode* T2 = y.left; + + // Perform rotation + y.left = x; + x.right = T2; + + // Update heights + x.height = cast(ushort)(max_height(x) + 1); + y.height = cast(ushort)(max_height(y) + 1); + + // Return new root + return y; +} + +BaseNode* rebalance(BaseNode* root) pure +{ + // If the tree had only one Node then return + if (root is null) + return null; + + // STEP 2: UPDATE HEIGHT OF THE CURRENT NODE + root.height = cast(ushort)(max(height(root.left), height(root.right)) + 1); + + // STEP 3: GET THE BALANCE FACTOR OF THIS NODE (to check whether + // this Node became unbalanced) + int balance = get_balance(root); + + // If this Node becomes unbalanced, then there are 4 cases + + // Left Left Case + if (balance > 1 && get_balance(root.left) >= 0) + return right_rotate(root); + + // Left Right Case + if (balance > 1 && get_balance(root.left) < 0) + { + root.left = left_rotate(root.left); + return right_rotate(root); + } + + // Right Right Case + if (balance < -1 && get_balance(root.right) <= 0) + return left_rotate(root); + + // Right Left Case + if (balance < -1 && get_balance(root.right) > 0) + { + root.right = right_rotate(root.right); + return left_rotate(root); + } + + return root; +} + +inout(BaseNode)* find_node(inout(BaseNode)* n, CompFn pred, const void* key) pure +{ + if (n is null) + return null; + ptrdiff_t c = pred(node_key(n), key); + if (c > 0) + return find_node(n.left, pred, key); + if (c < 0) + return find_node(n.right, pred, key); + return n; +} + +size_t destroy_node(BaseNode* n, DestroyFn free_fun) +{ + if (n is null) + return 0; + + size_t count = destroy_node(n.left, free_fun); + count += destroy_node(n.right, free_fun); + free_fun(n); + return count + 1; +} + +BaseNode* insert_node(BaseNode* n, BaseNode* newnode, ref size_t num_nodes, CompFn pred, DestroyFn free_fun) +{ + // 1. Perform the normal BST rotation + if (n is null) + { + ++num_nodes; + return newnode; + } + + ptrdiff_t c = pred(node_key(newnode), node_key(n)); + if (c < 0) + n.left = insert_node(n.left, newnode, num_nodes, pred, free_fun); + else if (c > 0) + n.right = insert_node(n.right, newnode, num_nodes, pred, free_fun); + else + { + newnode.left = n.left; + newnode.right = n.right; + newnode.height = n.height; + + free_fun(n); + + return newnode; + } + + // 2. Update height of this ancestor Node + n.height = cast(ushort)(max_height(n) + 1); + + // 3. get the balance factor of this ancestor Node to check whether + // this Node became unbalanced + int balance = get_balance(n); + + // If this Node becomes unbalanced, then there are 4 cases + + if (balance > 1) + { + ptrdiff_t lc = pred(node_key(newnode), node_key(n.left)); + // Left Left Case + if (lc < 0) + return right_rotate(n); + + // Left Right Case + if (lc > 0) + { + n.left = left_rotate(n.left); + return right_rotate(n); + } + } + + if (balance < -1) + { + ptrdiff_t rc = pred(node_key(newnode), node_key(n.right)); + + // Right Right Case + if (rc > 0) + return left_rotate(n); + + // Right Left Case + if (rc < 0) + { + n.right = right_rotate(n.right); + return left_rotate(n); + } + } + + // return the (unchanged) Node pointer + return n; +} + +BaseNode* delete_node(BaseNode* root, const void* key, ref size_t num_nodes, CompFn pred, MoveFn move_fun, DestroyFn free_fun) +{ + // STEP 1: PERFORM STANDARD BST DELETE + + if (root is null) + return root; + + ptrdiff_t c = pred(node_key(root), key); + + // If the key to be deleted is smaller than the root's key, + // then it lies in left subtree + if (c > 0) + root.left = delete_node(root.left, key, num_nodes, pred, move_fun, free_fun); + + // If the key to be deleted is greater than the root's key, + // then it lies in right subtree + else if (c < 0) + root.right = delete_node(root.right, key, num_nodes, pred, move_fun, free_fun); + + // if key is same as root's key, then this is the Node + // to be deleted + else + root = do_delete(root, num_nodes, pred, move_fun, free_fun); + + return rebalance(root); +} + +BaseNode* do_delete(BaseNode* root, ref size_t num_nodes, CompFn pred, MoveFn move_fun, DestroyFn free_fun) +{ + // Node with only one child or no child + if ((root.left is null) || (root.right is null)) + { + BaseNode* temp = root.left ? root.left : root.right; + + // No child case + if (temp is null) + { + temp = root; + root = null; + } + else // One child case + { + // TODO: FIX THIS!! + // this is copying the child node into the parent node because there is no parent pointer + // DO: add parent pointer, then fix up the parent's child pointer to the child, and do away with this pointless copy! + *root = (*temp).move; // Copy the tree structure (BaseNode fields) + move_fun(temp, root); // Copy the key/value data + } + + free_fun(temp); + + --num_nodes; + } + else + { + // Node with two children: we replace 'this' node with the next one in sequence... + + // get the in-order successor: the 'next' item is the far left node on the right hand side) + BaseNode* next = root.right; + while (next.left !is null) // find the leftmost leaf + next = next.left; + + move_fun(next, root); + + // Delete the node we just shifted + root.right = delete_node(root.right, node_key(next), num_nodes, pred, move_fun, free_fun); + } + + return root; +} diff --git a/src/urt/math.d b/src/urt/math.d index 236c867..d53626f 100644 --- a/src/urt/math.d +++ b/src/urt/math.d @@ -1,8 +1,9 @@ module urt.math; import urt.intrinsic; -import core.stdc.stdio; // For writeDebugf -import std.format; // For format + +// for arch where using FPU for int<->float conversions is preferred +//version = PreferFPUIntConv; version (LDC) version = GDC_OR_LDC; version (GNU) version = GDC_OR_LDC; @@ -62,8 +63,153 @@ extern(C) double exp(double x); double log(double x); double acos(double x); +// double pow(double x, double e); +} + +int float_is_integer(double f, out ulong i) +{ + version (PreferFPUIntConv) + { + if (!(f == f)) + return 0; // NaN + if (f < 0) + { + if (f < long.min) + return 0; // out of range + long t = cast(long)f; + if (cast(double)t != f) + return 0; // not an integer + i = cast(ulong)t; + return -1; + } + if (f >= ulong.max) + return 0; // out of range + ulong t = cast(ulong)f; + if (cast(double)t != f) + return 0; // not an integer + i = t; + return 1; + } + else + { + import urt.meta : bit_mask; + enum M = 52, E = 11, B = 1023; + + ulong u = *cast(const(ulong)*)&f; + int e = (u >> M) & bit_mask!E; + ulong m = u & bit_mask!M; + + if (e == bit_mask!E) + return 0; // NaN/Inf + if (e == 0) + { + if (m) + return 0; // denormal + i = 0; + return 1; // +/- 0 + } + int shift = e - B; + if (shift < 0) + return 0; // |f| < 1 + bool integral = shift >= M || (m & bit_mask(M - shift)) == 0; + if (!integral) + return 0; // not an integer + if (f < 0) + { + if (f < long.min) + return 0; // out of range + i = cast(ulong)cast(long)f; + return -1; + } + if (f >= ulong.max) + return 0; // out of range + i = cast(ulong)f; + return 1; + } +} + +unittest +{ + // this covers all the branches, but maybe test some extreme cases? + ulong i; + assert(float_is_integer(double.nan, i) == 0); + assert(float_is_integer(double.infinity, i) == 0); + assert(float_is_integer(-double.infinity, i) == 0); + assert(float_is_integer(double.max, i) == 0); + assert(float_is_integer(-double.max, i) == 0); + assert(float_is_integer(0.5, i) == 0); + assert(float_is_integer(1.5, i) == 0); + assert(float_is_integer(cast(double)ulong.max, i) == 0); + assert(float_is_integer(0.0, i) == 1 && i == 0); + assert(float_is_integer(-0.0, i) == 1 && i == 0); + assert(float_is_integer(200, i) == 1 && i == 200); + assert(float_is_integer(-200, i) == -1 && cast(long)i == -200); } +auto pow(B, E)(B base, E exp) @trusted +{ + enum isFloatB = is(B == float) || is(B == double) || is(B == real); + enum isFloatE = is(E == float) || is(E == double) || is(E == real); + + static if (isFloatB) + { + // Floating-point base + B result = B(1); + B b = base; + + static if (isFloatE) + { + // F ^^ F - handle integer-valued exponents (covers 99% of + // real-world `^^` uses: value^^2, 10.0^^e, etc.) + if (exp == 0) + return B(1); + long iexp = cast(long)exp; + if (cast(E)iexp == exp) + return _powfi!B(b, iexp); + // True non-integer exponent: not supported without libm. + assert(false, "Non-integer float exponent needs libm"); + } + else + { + // F ^^ I - binary exponentiation + return _powfi!B(b, long(exp)); + } + } + else + { + // I ^^ I - integer power + if (exp == 0) + return B(1); + B result = B(1); + B b = base; + auto e = cast(ulong) exp; + while (e > 0) + { + if (e & 1) + result *= b; + b *= b; + e >>= 1; + } + return result; + } +} +// binary exponentiation: float base, integer exponent. +private F _powfi(F)(F base, long exp) @trusted +{ + if (exp == 0) + return F(1); + bool neg = exp < 0; + ulong e = neg ? cast(ulong)(-exp) : cast(ulong) exp; + F result = F(1); + while (e > 0) + { + if (e & 1) + result *= base; + base *= base; + e >>= 1; + } + return neg ? F(1) / result : result; +} pragma(inline, true) bool addc(T = uint)(T a, T b, out T r, bool c_in) @@ -591,7 +737,10 @@ private T _divrem2x1_impl(T)(T[2] a, T b, out T rem) static if (is(T == uint)) { - static assert(false, "TODO!"); + // 32-bit: use 64-bit arithmetic directly + ulong dividend = (cast(ulong)a[1] << 32) | a[0]; + rem = cast(uint)(dividend % b); + return cast(uint)(dividend / b); } else { diff --git a/src/urt/mem/alloc.d b/src/urt/mem/alloc.d index 7408808..9d7308e 100644 --- a/src/urt/mem/alloc.d +++ b/src/urt/mem/alloc.d @@ -1,160 +1,232 @@ module urt.mem.alloc; -import core.stdc.stdlib; +import urt.mem; nothrow @nogc: -void[] alloc(size_t size) nothrow @nogc + +enum MemFlags : ubyte { + none = 0, + + // Speed bits are placement *preferences* + fast = 1, // prefer internal SRAM + slow = 2, // prefer external PSRAM + fastest = 3, // prefer TCM (single-cycle), else internal SRAM - // TODO: we might pin the length to a debug table somewhere... - return malloc(size)[0 .. size]; + dma = 0x4, // DMA-accessible (hard requirement) } -void[] allocAligned(size_t size, size_t alignment) nothrow @nogc -{ - import urt.util : isPowerOf2, max; - alignment = max(alignment, (void*).sizeof); - assert(isPowerOf2(alignment), "Alignment must be a power of two!"); +MemFlags mem_speed(MemFlags flags) pure => cast(MemFlags)(flags & 3); +bool mem_is_dma(MemFlags flags) pure => (flags & MemFlags.dma) != 0; - version (Windows) - { - import urt.util : alignDown; - // This is how Visual Studio's _aligned_malloc works... - // see C:\Program Files (x86)\Windows Kits\10\Source\10.0.15063.0\ucrt\heap\align.cpp - // - // This is implemented so memsize() can return the correct result. - // - size_t header_size = (void*).sizeof + alignment; - size_t total = header_size + size; +void[] alloc(size_t size, MemFlags flags = MemFlags.none) pure + => alloc(size, size_t.sizeof, flags); - void* mem = malloc(total); - if (mem is null) - return null; +void[] alloc(size_t size, size_t alignment, MemFlags flags = MemFlags.none) pure +{ + import urt.util : is_power_of_2; - size_t ptr = cast(size_t)mem; - size_t allocptr = alignDown(ptr + header_size, alignment); - (cast(void**)allocptr)[-1] = mem; + assert(is_power_of_2(alignment), "Alignment must be a power of two!"); - return (cast(void*)allocptr)[0 .. size]; - } - else version (Posix) + void[] mem = _alloc(size, alignment, flags); + version (AllocTracking) { - import core.sys.posix.stdlib; - void* mem; - return posix_memalign(&mem, alignment, size) ? null : mem[0 .. size]; + import urt.mem.tracking : track_alloc; + if (mem.ptr !is null) + { + alias TrackFn = void function(void*, size_t) pure nothrow @nogc; + (cast(TrackFn) &track_alloc)(mem.ptr, mem.length); + } } - else - { - void[] mem = malloc(size)[0 .. size]; - // HACK: just for now... - assert((cast(size_t)mem.ptr & (alignment - 1)) == 0, "Memory not aligned!"); - return mem; - } -} - -void[] realloc(void[] mem, size_t newSize) nothrow @nogc -{ - // TODO: we might pin the length to a debug table somewhere... - return core.stdc.stdlib.realloc(mem.ptr, newSize)[0 .. newSize]; + return mem; } -void[] reallocAligned(void[] mem, size_t newSize, size_t alignment) nothrow @nogc +void[] realloc(void[] mem, size_t new_size, size_t alignment = 8, MemFlags flags = MemFlags.none) pure { - import urt.util : isPowerOf2, min, max; - - alignment = max(alignment, (void*).sizeof); - assert(isPowerOf2(alignment), "Alignment must be a power of two!"); + import urt.util : min; - void[] newAlloc = newSize > 0 ? allocAligned(newSize, alignment) : null; - if (newAlloc !is null && mem !is null) + if (new_size == 0) { - size_t toCopy = min(mem.length, newSize); - newAlloc[0 .. toCopy] = mem[0 .. toCopy]; + free(mem); + return null; } - freeAligned(mem); - return newAlloc; -} + if (mem.ptr is null) + return alloc(new_size, alignment, flags); -// NOTE: This function is only compatible with allocAligned! -void[] expand(void[] mem, size_t newSize) nothrow @nogc -{ - version (Windows) + static if (has_realloc) { - if (mem.ptr is null) - return null; - void* ptr = (cast(void**)mem.ptr)[-1]; - size_t head = (cast(size_t)mem.ptr - cast(size_t)ptr); - void* r = _expand(ptr, head + newSize); - if (r is null) - return null; - return mem.ptr[0 .. newSize]; + void* old_ptr = mem.ptr; + void[] new_mem = _realloc(mem, new_size, alignment, flags); + version (AllocTracking) + { + import urt.mem.tracking : track_realloc; + if (new_mem.ptr !is null) + { + alias TrackFn = void function(void*, void*, size_t) pure nothrow @nogc; + (cast(TrackFn) &track_realloc)(old_ptr, new_mem.ptr, new_mem.length); + } + } + return new_mem; } else { - if (newSize <= memsize(mem.ptr)) - return mem.ptr[0 .. newSize]; - return null; + // Fallback path uses nested alloc/free, which are already hooked. + void[] new_mem = alloc(new_size, alignment, flags); + if (new_mem.ptr !is null) + { + size_t copy = min(mem.length, new_size); + new_mem[0 .. copy] = mem[0 .. copy]; + } + free(mem); + return new_mem; } } -void free(void[] mem) nothrow @nogc +void free(void[] mem) pure { - // maybe check the length passed to free matches the alloc? - // ... or you know, just don't do that. - - core.stdc.stdlib.free(mem.ptr); + if (mem.ptr is null) + return; + version (AllocTracking) + { + import urt.mem.tracking : untrack_alloc; + alias UntrackFn = void function(void*) pure nothrow @nogc; + (cast(UntrackFn) &untrack_alloc)(mem.ptr); + } + _free(mem.ptr); } -void freeAligned(void[] mem) nothrow @nogc +void[] expand(void[] mem, size_t new_size) pure { - version (Windows) + if (mem.ptr is null) + return null; + static if (has_expand) + return _expand(mem, new_size); + else static if (has_memsize) { - if (mem.ptr is null) - return; - void* p = (cast(void**)mem.ptr)[-1]; - core.stdc.stdlib.free(p); + if (new_size <= _memsize(mem.ptr)) + return mem.ptr[0 .. new_size]; + return null; } else - core.stdc.stdlib.free(mem.ptr); + assert(false, "unsupported"); } -size_t memsize(void* ptr) nothrow @nogc +size_t memsize(void* ptr) pure { - version (Windows) - { - if (ptr is null) - return 0; - void* mem = (cast(void**)ptr)[-1]; - return _msize(mem) - (cast(size_t)ptr - cast(size_t)mem); - } - else version (Posix) - return malloc_usable_size(ptr); - else version (Darwin) - return malloc_size(ptr); + if (ptr is null) + return 0; + static if (has_memsize) + return _memsize(ptr); else - assert(false, "Unsupported platform"); + assert(false, "unsupported"); } +void[] alloc_exec(size_t size) pure +{ + static if (has_exec) + return _alloc_exec(size); + else + return null; +} -unittest +void free_exec(void[] mem) pure { - void[] mem = allocAligned(16, 8); - size_t s = memsize(mem.ptr); - mem = expand(mem, 8); - mem = expand(mem, 16); - freeAligned(mem); + static if (has_exec) + { + if (mem.ptr !is null) + _free_exec(mem); + } } +void[] alloc_retain(size_t size) pure +{ + static if (has_retain) + return _alloc_retain(size); + else + return null; +} -version (Windows) +void free_retain(void[] mem) pure { - extern(C) void* _expand(void* memblock, size_t size) nothrow @nogc; - extern(C) size_t _msize(void* _Block); + static if (has_retain) + { + if (mem.ptr !is null) + _free_retain(mem); + } } -version (Posix) + +// pointer tagging utilities -- for containers to store flags in low 3 bits +// of 8-byte aligned pointers. the allocator itself returns clean pointers. +T* tag(T)(T* ptr, MemFlags flags) pure + => cast(T*)(cast(size_t)ptr | flags); + +T* untag(T)(T* ptr) pure + => cast(T*)(cast(size_t)ptr & ~cast(size_t)0x7); + +MemFlags get_flags(void* ptr) pure + => cast(MemFlags)(cast(size_t)ptr & 0x7); + + +version (Espressif) + public import urt.driver.esp32.alloc; +else version (Bouffalo) + public import urt.driver.bl_common.alloc; +else version (RP2350) + public import urt.driver.rp2350.alloc; +else version (BK7231N) + public import urt.driver.bk7231.alloc; +else version (BK7231T) + public import urt.driver.bk7231.alloc; +else version (STM32F4) + public import urt.driver.stm32.alloc; +else version (STM32F7) + public import urt.driver.stm32.alloc; +else version (Windows) + public import urt.driver.windows.alloc; +else version (Posix) + public import urt.driver.posix.alloc; +else + static assert(false, "No alloc driver for this platform"); + + +unittest { - extern(C) size_t malloc_usable_size(void *__ptr); + // basic alloc/free + void[] mem = alloc(32, 8); + assert(mem !is null); + assert((cast(size_t)mem.ptr & 0x7) == 0); // 8-byte aligned + assert(mem.length == 32); + free(mem); + + // alloc with flags (on desktop, flags are ignored but API works) + mem = alloc(64, 8, MemFlags.fast); + assert(mem !is null); + size_t s = memsize(mem.ptr); + assert(s >= 64); + free(mem); + + // realloc preserves data + mem = alloc(16, 8); + (cast(ubyte*)mem.ptr)[0 .. 16] = 0xAB; + mem = realloc(mem, 64); + assert(mem !is null); + assert((cast(ubyte*)mem.ptr)[0] == 0xAB); + free(mem); + + // expand + mem = alloc(16, 8); + void[] expanded = expand(mem, 8); + if (expanded !is null) + assert(expanded.ptr is mem.ptr); + free(mem); + + // pointer tagging utilities + void* p = mem.ptr; + enum test_flags = cast(MemFlags)(MemFlags.fast | MemFlags.dma); + void* tagged = tag(p, test_flags); + assert(get_flags(tagged) == test_flags); + assert(untag(tagged) is p); } diff --git a/src/urt/mem/allocator.d b/src/urt/mem/allocator.d index 75cadff..7c1ad50 100644 --- a/src/urt/mem/allocator.d +++ b/src/urt/mem/allocator.d @@ -2,28 +2,30 @@ module urt.mem.allocator; import urt.lifetime; +nothrow: + // TODO: this should be defined by platform/compiler/etc... enum DefaultAlign = size_t.sizeof; -NoGCAllocator defaultAllocator() nothrow @nogc +NoGCAllocator defaultAllocator() pure @nogc { - return Mallocator.instance; + return Mallocator.instance(); } -NoGCAllocator tempAllocator() nothrow @nogc +NoGCAllocator tempAllocator() pure @nogc { import urt.mem.temp; - - return TempAllocator.instance; + return TempAllocator.instance(); } class Allocator { - abstract void[] alloc(size_t bytes, size_t alignment = DefaultAlign) nothrow; +nothrow: + abstract void[] alloc(size_t bytes, size_t alignment = DefaultAlign) pure; - void[] realloc(void[] mem, size_t newSize, size_t alignment = DefaultAlign) nothrow + void[] realloc(void[] mem, size_t newSize, size_t alignment = DefaultAlign) pure { void[] newMem = alloc(newSize, alignment); if (newMem != null) @@ -37,16 +39,16 @@ class Allocator return newMem; } - void[] expand(void[] mem, size_t newSize) nothrow + void[] expand(void[] mem, size_t newSize) pure { return null; } - abstract void free(void[] mem) nothrow; + abstract void free(void[] mem) pure; // abstract size_t getUsableSize(void* p); // get the usable size for an allocation... - final T* allocT(T, Args...)(auto ref Args args) nothrow + final T* allocT(T, Args...)(auto ref Args args) if (!is(T == class)) { T* item = cast(T*)alloc(T.sizeof, T.alignof).ptr; @@ -59,7 +61,7 @@ class Allocator return item; } - final T allocT(T, Args...)(auto ref Args args) nothrow + final T allocT(T, Args...)(auto ref Args args) if (is(T == class)) { T item = cast(T)alloc(__traits(classInstanceSize, T), __traits(classInstanceAlignment, T)).ptr; @@ -72,7 +74,7 @@ class Allocator return item; } - final void freeT(T)(T* item) nothrow + final void freeT(T)(T* item) if (!is(T == class)) { try @@ -84,7 +86,7 @@ class Allocator free((cast(void*)item)[0..T.sizeof]); } - final void freeT(T)(T item) nothrow + final void freeT(T)(T item) if (is(T == class)) { try @@ -96,7 +98,7 @@ class Allocator free((cast(void*)item)[0..__traits(classInstanceSize, T)]); } - final T[] allocArray(T, Args...)(size_t count, auto ref Args args) nothrow + final T[] allocArray(T, Args...)(size_t count, auto ref Args args) if (!is(T == class)) { if (count == 0) @@ -114,7 +116,7 @@ class Allocator return items; } - final T[] reallocArray(T, Args...)(T[] arr, size_t newCount, auto ref Args args) nothrow + final T[] reallocArray(T, Args...)(T[] arr, size_t newCount, auto ref Args args) if (!is(T == class)) { if (newCount < arr.length) @@ -148,7 +150,7 @@ class Allocator return arr; } - final void freeArray(T)(T[] items) nothrow + final void freeArray(T)(T[] items) if (!is(T == class)) { try @@ -166,15 +168,21 @@ class Allocator class GCAllocator : Allocator { - static GCAllocator instance() nothrow @nogc => _instance; +nothrow: + static GCAllocator instance() pure @nogc + { + alias PureHack = GCAllocator function() pure nothrow @nogc; + static GCAllocator hack() nothrow @nogc => _instance; + return (cast(PureHack)&hack)(); + } - override void[] alloc(size_t bytes, size_t alignment = DefaultAlign) nothrow + override void[] alloc(size_t bytes, size_t alignment = DefaultAlign) pure { // TODO: can/should we enforce alignment? return new void[bytes]; } - override void free(void[] mem) nothrow + override void free(void[] mem) pure { // GC will take care of it... } @@ -185,9 +193,10 @@ private: class NoGCAllocator : Allocator { - abstract override void[] alloc(size_t bytes, size_t alignment = DefaultAlign) nothrow @nogc; +nothrow @nogc: + abstract override void[] alloc(size_t bytes, size_t alignment = DefaultAlign) pure; - override void[] realloc(void[] mem, size_t newSize, size_t alignment = DefaultAlign) nothrow @nogc + override void[] realloc(void[] mem, size_t newSize, size_t alignment = DefaultAlign) pure { void[] newMem = alloc(newSize, alignment); if (newMem != null) @@ -201,14 +210,14 @@ class NoGCAllocator : Allocator return newMem; } - override void[] expand(void[] mem, size_t newSize) nothrow @nogc + override void[] expand(void[] mem, size_t newSize) pure { return null; } - abstract override void free(void[] mem) nothrow @nogc; + abstract override void free(void[] mem) pure; - final T* allocT(T, Args...)(auto ref Args args) nothrow @nogc + final T* allocT(T, Args...)(auto ref Args args) if (!is(T == class)) { T* item = cast(T*)alloc(T.sizeof, T.alignof).ptr; @@ -221,7 +230,7 @@ class NoGCAllocator : Allocator return item; } - final T allocT(T, Args...)(auto ref Args args) nothrow @nogc + final T allocT(T, Args...)(auto ref Args args) if (is(T == class)) { T item = cast(T)alloc(__traits(classInstanceSize, T), __traits(classInstanceAlignment, T)).ptr; @@ -234,7 +243,7 @@ class NoGCAllocator : Allocator return item; } - final void freeT(T)(T* item) nothrow @nogc + final void freeT(T)(T* item) if (!is(T == class)) { try @@ -246,7 +255,7 @@ class NoGCAllocator : Allocator free((cast(void*)item)[0..T.sizeof]); } - final void freeT(T)(T item) nothrow @nogc + final void freeT(T)(T item) if (is(T == class)) { // HACK: since druntime can't actually destroy a @nogc class! @@ -262,7 +271,7 @@ class NoGCAllocator : Allocator free((cast(void*)item)[0..__traits(classInstanceSize, T)]); } - final T[] allocArray(T, Args...)(size_t count, auto ref Args args) nothrow @nogc + final T[] allocArray(T, Args...)(size_t count, auto ref Args args) if (!is(T == class)) { if (count == 0) @@ -279,7 +288,7 @@ class NoGCAllocator : Allocator return items; } - final T[] allocArray(T)(size_t count) nothrow @nogc + final T[] allocArray(T)(size_t count) if (is(T == class)) { if (count == 0) @@ -291,7 +300,7 @@ class NoGCAllocator : Allocator return items; } - final T[] reallocArray(T, Args...)(T[] arr, size_t newCount, auto ref Args args) nothrow @nogc + final T[] reallocArray(T, Args...)(T[] arr, size_t newCount, auto ref Args args) if (!is(T == class)) { if (newCount < arr.length) @@ -326,7 +335,7 @@ class NoGCAllocator : Allocator return arr; } - final void freeArray(T)(T[] items) nothrow @nogc + final void freeArray(T)(T[] items) if (!is(T == class)) { try @@ -341,7 +350,7 @@ class NoGCAllocator : Allocator free(cast(void[])items[]); } - final void freeArray(T)(T[] items) nothrow @nogc + final void freeArray(T)(T[] items) if (is(T == class)) { free(cast(void[])items[]); @@ -351,27 +360,33 @@ class NoGCAllocator : Allocator class Mallocator : NoGCAllocator { static import urt.mem.alloc; +nothrow @nogc: - static Mallocator instance() nothrow @nogc => _instance; + static Mallocator instance() pure + { + alias PureHack = Mallocator function() pure nothrow @nogc; + static Mallocator hack() nothrow @nogc => _instance; + return (cast(PureHack)&hack)(); + } - override void[] alloc(size_t size, size_t alignment = DefaultAlign) nothrow @nogc + override void[] alloc(size_t size, size_t alignment = DefaultAlign) pure { - return urt.mem.alloc.allocAligned(size, alignment); + return urt.mem.alloc.alloc(size, alignment); } - override void[] realloc(void[] mem, size_t newSize, size_t alignment = DefaultAlign) nothrow @nogc + override void[] realloc(void[] mem, size_t newSize, size_t alignment = DefaultAlign) pure { - return urt.mem.alloc.reallocAligned(mem, newSize, alignment); + return urt.mem.alloc.realloc(mem, newSize, alignment); } - override void[] expand(void[] mem, size_t newSize) nothrow + override void[] expand(void[] mem, size_t newSize) pure { return urt.mem.alloc.expand(mem, newSize); } - override void free(void[] mem) nothrow @nogc + override void free(void[] mem) pure { - urt.mem.alloc.freeAligned(mem); + urt.mem.alloc.free(mem); } private: @@ -381,25 +396,25 @@ private: class RegionAllocator : NoGCAllocator { import urt.mem.region; +nothrow @nogc: - static RegionAllocator getRegionAllocator(void[] region) pure nothrow @nogc + static RegionAllocator get_region_allocator(void[] region) pure { Region* r = makeRegion(region); return r.alloc!RegionAllocator(r); } - - this(Region* region) pure nothrow @nogc + this(Region* region) pure { this.region = region; } - override void[] alloc(size_t bytes, size_t alignment = DefaultAlign) pure nothrow @nogc + override void[] alloc(size_t bytes, size_t alignment = DefaultAlign) pure { return region.alloc(bytes, alignment); } - override void free(void[] mem) pure nothrow @nogc + override void free(void[] mem) pure { } @@ -434,7 +449,10 @@ unittest } } - Allocator a = new Mallocator; + import urt.util; + auto mallocator = InPlace!Mallocator(Default); + + Allocator a = mallocator; S* s = a.allocT!S(10); a.freeT(s); C c = a.allocT!C(); diff --git a/src/urt/mem/bitmap.d b/src/urt/mem/bitmap.d new file mode 100644 index 0000000..dc25025 --- /dev/null +++ b/src/urt/mem/bitmap.d @@ -0,0 +1,399 @@ +module urt.mem.bitmap; + +import urt.util; + +nothrow @nogc: + + +// Bitmap pool. The bitmap header sits at the head of the pool and holds two equal-size planes: +// in-use -> 1 = block is allocated +// stop -> 1 = last block of an allocation +// The header's blocks are pre-marked in-use so they can't be handed out. free() takes only the +// pointer; it scans the stop plane forward from the pointer's block to find the allocation's end. +// +// `_poolSize == 0` -> backing memory supplied at runtime via `init(mem)`. +// `_poolSize > 0` -> storage lives inline; call `init()` after construction. +struct BitmapPool(size_t _poolSize = 0, size_t blockSize = size_t.sizeof) +{ + static assert(blockSize > 0, "blockSize must be > 0"); + static assert(IsPowerOf2!blockSize, "blockSize must be a power of 2"); + + alias Word = size_t; + enum size_t word_bits = Word.sizeof * 8; + + static if (_poolSize > 0) + { + static assert(_poolSize % blockSize == 0, "_poolSize must be a multiple of blockSize"); + + enum size_t block_count = _poolSize / blockSize; + enum size_t plane_words = align_up(block_count, word_bits) / word_bits; + enum size_t bitmap_blocks = align_up(2 * plane_words * Word.sizeof, blockSize) / blockSize; + enum size_t usable_blocks = block_count - bitmap_blocks; + static assert(usable_blocks > 0, "pool too small: bitmap consumes the whole pool"); + + void[] data() => cast(void[])_data[]; + + void init() + { + init_planes(in_use_plane(), stop_plane(), block_count, bitmap_blocks); + } + } + else + { + size_t block_count() const => _block_count; + size_t plane_words() const => _plane_words; + size_t bitmap_blocks() const => _bitmap_blocks; + size_t usable_blocks() const => _block_count - _bitmap_blocks; + + void[] data() => _data; + + void init(void[] mem) + { + assert(mem.length >= blockSize, "pool too small"); + assert((cast(size_t)mem.ptr & (Word.alignof - 1)) == 0, "pool memory must be Word-aligned"); + + size_t nblocks = mem.length / blockSize; + size_t pwords = align_up(nblocks, word_bits) / word_bits; + size_t bblocks = align_up(2 * pwords * Word.sizeof, blockSize) / blockSize; + assert(nblocks > bblocks, "pool too small: bitmap consumes the whole pool"); + + _data = mem.ptr[0 .. nblocks * blockSize]; + _block_count = cast(uint)nblocks; + _plane_words = cast(uint)pwords; + _bitmap_blocks = cast(uint)bblocks; + + init_planes(in_use_plane(), stop_plane(), _block_count, _bitmap_blocks); + } + } + + void[] alloc(size_t bytes) + { + if (bytes == 0) + return null; + size_t n = align_up(bytes, blockSize) / blockSize; + size_t i = find_run(n); + if (i == size_t.max) + return null; + mark_in_use(i, n, true); + set_stop(i + n - 1); + return (cast(ubyte*)_data.ptr + i * blockSize)[0 .. bytes]; + } + + void free(void* p) + { + if (p is null) + return; + size_t off = cast(ubyte*)p - cast(ubyte*)_data.ptr; + debug + { + assert(off % blockSize == 0, "free pointer not aligned to a block"); + assert(off < _data.length, "free out of pool bounds"); + } + size_t i = off / blockSize; + size_t stop = find_stop(i); + debug assert(stop != size_t.max, "free: no stop bit found (invalid pointer)"); + clear_stop(stop); + mark_in_use(i, stop - i + 1, false); + } + + void free(void[] mem) + { + free(mem.ptr); + } + +private: + static if (_poolSize > 0) + align(Word.alignof) ubyte[_poolSize] _data = void; + else + { + void[] _data; + uint _block_count; + uint _plane_words; + uint _bitmap_blocks; + } + + Word[] in_use_plane() + { + return (cast(Word*)_data.ptr)[0 .. plane_words]; + } + + Word[] stop_plane() + { + return (cast(Word*)_data.ptr)[plane_words .. 2 * plane_words]; + } + + static void init_planes(Word[] in_use, Word[] stop, size_t blocks, size_t reserved) + { + in_use[] = 0; + stop[] = 0; + + size_t i = 0; + while (reserved >= word_bits) + { + in_use[i++] = ~Word(0); + reserved -= word_bits; + } + if (reserved) + in_use[i] = (Word(1) << reserved) - 1; + + // mark padding bits past `blocks` as in-use so the scanner won't pick them + size_t tail = blocks & (word_bits - 1); + if (tail) + in_use[$ - 1] |= ~((Word(1) << tail) - 1); + } + + // Find the lowest run of `n` free blocks. Strategy per word: + // - all-zero word: extend the pending cross-word run. + // - mixed word: combine pending + leading-free; then shift-OR within the word for an internal + // run; then record trailing-free for the next iteration. + // Shift-OR: with `free = ~w`, `acc = free & (free>>1) & ... & (free>>(n-1))` has bit b set iff + // bits b..b+n-1 of free are all 1, i.e. a run of n free blocks starts at b. ctz(acc) picks the + // lowest such start. Only viable for n <= word_bits; longer runs come from cross-word combining. + size_t find_run(size_t n) + { + Word[] bm = in_use_plane(); + + if (n == 1) + { + foreach (wi; 0 .. bm.length) + { + Word w = bm[wi]; + if (w != ~Word(0)) + return wi * word_bits + ctz!true(cast(Word)~w); + } + return size_t.max; + } + + size_t pending = 0; + size_t pending_start = 0; + + foreach (wi; 0 .. bm.length) + { + Word w = bm[wi]; + + if (w == 0) + { + if (pending == 0) + pending_start = wi * word_bits; + pending += word_bits; + if (pending >= n) + return pending_start; + continue; + } + + size_t leading = ctz(w); + if (pending + leading >= n) + return pending > 0 ? pending_start : wi * word_bits; + + if (n <= word_bits) + { + Word free = ~w; + Word acc = free; + for (size_t k = 1; k < n; ++k) + { + acc &= free >> k; + if (acc == 0) + break; + } + if (acc != 0) + return wi * word_bits + ctz!true(acc); + } + + size_t trail = clz(w); + if (trail > 0) + { + pending = trail; + pending_start = (wi + 1) * word_bits - trail; + } + else + pending = 0; + } + + return size_t.max; + } + + size_t find_stop(size_t start) + { + Word[] bm = stop_plane(); + size_t wi = start / word_bits; + size_t bi = start & (word_bits - 1); + + Word w = bm[wi] >> bi; + if (w != 0) + return start + ctz!true(w); + for (++wi; wi < bm.length; ++wi) + { + if (bm[wi] != 0) + return wi * word_bits + ctz!true(bm[wi]); + } + return size_t.max; + } + + void mark_in_use(size_t start, size_t n, bool set) + { + Word[] bm = in_use_plane(); + size_t end = start + n; + size_t wi = start / word_bits; + size_t bi = start & (word_bits - 1); + while (start < end) + { + size_t span = min(word_bits - bi, end - start); + Word mask = span == word_bits ? ~Word(0) : (((Word(1) << span) - 1) << bi); + if (set) + { + debug assert((bm[wi] & mask) == 0, "double-alloc: bits already set"); + bm[wi] |= mask; + } + else + { + debug assert((bm[wi] & mask) == mask, "double-free: bits already clear"); + bm[wi] &= ~mask; + } + start += span; + ++wi; + bi = 0; + } + } + + void set_stop(size_t i) + { + Word[] bm = stop_plane(); + bm[i / word_bits] |= Word(1) << (i & (word_bits - 1)); + } + + void clear_stop(size_t i) + { + Word[] bm = stop_plane(); + bm[i / word_bits] &= ~(Word(1) << (i & (word_bits - 1))); + } +} + + +unittest +{ + // 4 KiB / 8 B -> 512 blocks, 2 x 64-byte planes = 16 reserved blocks, 496 usable. + BitmapPool!(4096, 8) p; + p.init(); + + assert(p.block_count == 512); + assert(p.bitmap_blocks == 16); + assert(p.usable_blocks == 496); + + ubyte* base = cast(ubyte*)p.data.ptr; + ubyte* first = base + p.bitmap_blocks * 8; + + void[] a = p.alloc(8); + assert(a !is null && a.length == 8); + assert(cast(ubyte*)a.ptr == first); + + void[] b = p.alloc(8); + assert(cast(ubyte*)b.ptr == first + 8); + + p.free(a.ptr); + void[] c = p.alloc(8); + assert(c.ptr is a.ptr); + + void[] big = p.alloc(40); + assert(big !is null && big.length == 40); + p.free(big.ptr); + + p.free(b.ptr); + p.free(c.ptr); + + void[][496] all; + foreach (i; 0 .. 496) + { + all[i] = p.alloc(8); + assert(all[i] !is null); + } + assert(p.alloc(8) is null); + foreach (s; all) + p.free(s.ptr); + assert(p.alloc(8) !is null); +} + +unittest +{ + align(size_t.alignof) ubyte[1024] storage; + BitmapPool!(0, 16) p; + p.init(storage[]); + + assert(p.block_count == 64); + assert(p.usable_blocks > 0); + + void[] a = p.alloc(16); + void[] b = p.alloc(48); + assert(a !is null && b !is null); + p.free(a.ptr); + p.free(b.ptr); +} + +unittest +{ + // multi-block run that straddles a word boundary, then length-less free + BitmapPool!(2048, 4) p; + p.init(); + + void[][70] filler; + foreach (i; 0 .. 70) + filler[i] = p.alloc(4); + + void[] run = p.alloc(20); + assert(run !is null && run.length == 20); + + foreach (s; filler) + p.free(s.ptr); + p.free(run.ptr); + + // pool should be back to full availability + void[] big = p.alloc(256); + assert(big !is null); + p.free(big.ptr); +} + +unittest +{ + // Exercise the optimised find_run paths: long runs across many words and within-word runs + // hidden behind a dense alternating-bit pattern. + enum bs = 8; + BitmapPool!(8192, bs) p; + p.init(); + + // Long run spanning many words. + void[] big = p.alloc(bs * 200); + assert(big !is null && big.length == bs * 200); + p.free(big.ptr); + + // Biggest possible run. + void[] huge = p.alloc(bs * p.usable_blocks); + assert(huge !is null); + p.free(huge.ptr); + + // Fragment with alternating singles, then place a 2-block run somewhere valid. + void[][50] singles; + foreach (i; 0 .. 50) + singles[i] = p.alloc(bs); + foreach (i; 0 .. 50) + { + if (i & 1) + p.free(singles[i].ptr); + } + void[] two = p.alloc(bs * 2); + assert(two !is null); + p.free(two.ptr); + foreach (i; 0 .. 50) + { + if (!(i & 1)) + p.free(singles[i].ptr); + } + + // Run that requires combining trailing zeros of one word with leading zeros of the next. + void[][62] fill; + foreach (i; 0 .. 62) + fill[i] = p.alloc(bs); + void[] cross = p.alloc(bs * 4); + assert(cross !is null); + p.free(cross.ptr); + foreach (s; fill) + p.free(s.ptr); +} diff --git a/src/urt/mem/package.d b/src/urt/mem/package.d index 795a4e3..f187ef8 100644 --- a/src/urt/mem/package.d +++ b/src/urt/mem/package.d @@ -1,29 +1,220 @@ module urt.mem; -public import core.stdc.stddef : wchar_t; - +// TODO: remove these public imports, because this is pulled by object.d! public import urt.lifetime : emplace, moveEmplace, forward, move; +public import urt.mem.alloc; public import urt.mem.allocator; +nothrow @nogc: + + +version (LDC) + pragma(LDC_alloca) void* alloca(size_t size) pure @safe; +else + extern(C) void* alloca(size_t size) pure @trusted; extern(C) { nothrow @nogc: - void* alloca(size_t size); - void* memcpy(void* dest, const void* src, size_t n); - void* memmove(void* dest, const void* src, size_t n); - void* memset(void* s, int c, size_t n); - void* memzero(void* s, size_t n) => memset(s, 0, n); + void* memcpy(void* dest, const void* src, size_t n) pure; + void* memmove(void* dest, const void* src, size_t n) pure; + void* memset(void* s, int c, size_t n) pure; + void* memzero(void* s, size_t n) pure => memset(s, 0, n); + int memcmp(const void *s1, const void *s2, size_t n) pure; - size_t strlen(const char* s); - int strcmp(const char* s1, const char* s2); - char* strcpy(char* dest, const char* src); + size_t strlen(const char* s) pure; + int strcmp(const char* s1, const char* s2) pure; + char* strcpy(char* dest, const char* src) pure; char* strcat(char* dest, const char* src); - size_t wcslen(const wchar_t* s); -// wchar_t* wcscpy(wchar_t* dest, const wchar_t* src); + size_t wcslen(const wchar_t* s) pure; +// wchar_t* wcscpy(wchar_t* dest, const wchar_t* src) pure; // wchar_t* wcscat(wchar_t* dest, const wchar_t* src); -// wchar_t* wcsncpy(wchar_t* dest, const wchar_t* src, size_t n); +// wchar_t* wcsncpy(wchar_t* dest, const wchar_t* src, size_t n) pure; // wchar_t* wcsncat(wchar_t* dest, const wchar_t* src, size_t n); } + +T debug_alloc(T = void)() pure @trusted + if (is(T == class)) +{ + static T gc_alloc(size_t size) pure nothrow => new T; + return (cast(T function(size_t) pure nothrow @nogc)&gc_alloc)(size); +} +T* debug_alloc(T = void)() pure @trusted + if (!is(T == class)) +{ + static T* gc_alloc(size_t size) pure nothrow => new T; + return (cast(T* function(size_t) pure nothrow @nogc)&gc_alloc)(size); +} +T[] debug_alloc(T = void)(size_t size) pure @trusted +{ + static T[] gc_alloc(size_t size) pure nothrow => new T[size]; + return (cast(T[] function(size_t) pure nothrow @nogc)&gc_alloc)(size); +} + + +private: + +version(DigitalMars) +{ + // DMD lowers alloca(n) calls to __alloca(n) + extern(C) void* __alloca(int nbytes) + { + version (D_InlineAsm_X86) + { + asm nothrow @nogc + { + naked ; + mov EDX,ECX ; + mov EAX,4[ESP] ; // get nbytes + push EBX ; + push EDI ; + push ESI ; + + add EAX,15 ; + and EAX,0xFFFFFFF0 ; // round up to 16 byte boundary + jnz Abegin ; + mov EAX,16 ; // minimum allocation is 16 + Abegin: + mov ESI,EAX ; // ESI = nbytes + neg EAX ; + add EAX,ESP ; // EAX is now what the new ESP will be. + jae Aoverflow ; + } + version (Win32) + { + asm nothrow @nogc + { + // Touch guard pages to commit stack memory + mov ECX,EAX ; + mov EBX,ESI ; + L1: + test [ECX+EBX],EBX ; + sub EBX,0x1000 ; + jae L1 ; + test [ECX],EBX ; + } + } + asm nothrow @nogc + { + mov ECX,EBP ; + sub ECX,ESP ; + sub ECX,[EDX] ; + add [EDX],ESI ; + mov ESP,EAX ; + add EAX,ECX ; + mov EDI,ESP ; + add ESI,ESP ; + shr ECX,2 ; + rep ; + movsd ; + jmp done ; + + Aoverflow: + xor EAX,EAX ; + + done: + pop ESI ; + pop EDI ; + pop EBX ; + ret ; + } + } + else version (D_InlineAsm_X86_64) + { + version (Win64) + { + asm nothrow @nogc + { + naked ; + push RBX ; + push RDI ; + push RSI ; + mov RAX,RCX ; + add RAX,15 ; + and AL,0xF0 ; + test RAX,RAX ; + jnz Abegin ; + mov RAX,16 ; + Abegin: + mov RSI,RAX ; + neg RAX ; + add RAX,RSP ; + jae Aoverflow ; + + // Touch guard pages + mov RCX,RAX ; + mov RBX,RSI ; + L1: + test [RCX+RBX],RBX ; + sub RBX,0x1000 ; + jae L1 ; + test [RCX],RBX ; + + mov RCX,RBP ; + sub RCX,RSP ; + sub RCX,[RDX] ; + add [RDX],RSI ; + mov RSP,RAX ; + add RAX,RCX ; + mov RDI,RSP ; + add RSI,RSP ; + shr RCX,3 ; + rep ; + movsq ; + jmp done ; + + Aoverflow: + xor RAX,RAX ; + + done: + pop RSI ; + pop RDI ; + pop RBX ; + ret ; + } + } + else + { + asm nothrow @nogc + { + naked ; + mov RDX,RCX ; + mov RAX,RDI ; + add RAX,15 ; + and AL,0xF0 ; + test RAX,RAX ; + jnz Abegin ; + mov RAX,16 ; + Abegin: + mov RSI,RAX ; + neg RAX ; + add RAX,RSP ; + jae Aoverflow ; + + mov RCX,RBP ; + sub RCX,RSP ; + sub RCX,[RDX] ; + add [RDX],RSI ; + mov RSP,RAX ; + add RAX,RCX ; + mov RDI,RSP ; + add RSI,RSP ; + shr RCX,3 ; + rep ; + movsq ; + jmp done ; + + Aoverflow: + xor RAX,RAX ; + + done: + ret ; + } + } + } + else + static assert(0, "Unsupported architecture for __alloca"); + } +} diff --git a/src/urt/mem/region.d b/src/urt/mem/region.d index 9a4a228..386e661 100644 --- a/src/urt/mem/region.d +++ b/src/urt/mem/region.d @@ -2,11 +2,13 @@ module urt.mem.region; import urt.util; +nothrow @nogc: -static Region* makeRegion(void[] mem) pure nothrow @nogc + +static Region* makeRegion(void[] mem) pure { assert(mem.length >= Region.sizeof, "Memory block too small"); - Region* region = cast(Region*)mem.ptr.alignUp(Region.alignof); + Region* region = cast(Region*)mem.ptr.align_up(Region.alignof); size_t alignBytes = cast(void*)region - mem.ptr; if (size_t.sizeof > 4 && mem.length > uint.max + alignBytes + Region.sizeof) region.length = uint.max; @@ -21,7 +23,7 @@ struct Region void[] alloc(size_t size, size_t alignment = size_t.sizeof) pure nothrow @nogc { size_t ptr = cast(size_t)&this + Region.sizeof + offset; - size_t alignedPtr = ptr.alignUp(alignment); + size_t alignedPtr = ptr.align_up(alignment); size_t alignBytes = alignedPtr - ptr; if (offset + alignBytes + size > length) return null; diff --git a/src/urt/mem/ring.d b/src/urt/mem/ring.d index 2bfdb48..6396eab 100644 --- a/src/urt/mem/ring.d +++ b/src/urt/mem/ring.d @@ -84,7 +84,7 @@ private: // declare some stuff outside the template... -size_t read_ring(void[] buffer, const void[] data, ref uint readCur, const int writeCur, const size_t capacity) +size_t read_ring(void[] buffer, const void[] data, ref uint readCur, const uint writeCur, const size_t capacity) { if (writeCur >= readCur) { diff --git a/src/urt/mem/scratchpad.d b/src/urt/mem/scratchpad.d index 83a3abb..2a20c30 100644 --- a/src/urt/mem/scratchpad.d +++ b/src/urt/mem/scratchpad.d @@ -8,10 +8,10 @@ nothrow @nogc: enum size_t MaxScratchpadSize = 2048; enum size_t NumScratchBuffers = 4; -static assert(MaxScratchpadSize.isPowerOf2, "Scratchpad size must be a power of 2"); +static assert(MaxScratchpadSize.is_power_of_2, "Scratchpad size must be a power of 2"); -void[] allocScratchpad(size_t size = MaxScratchpadSize) +void[] alloc_scratchpad(size_t size = MaxScratchpadSize) { if (size > MaxScratchpadSize) { @@ -19,17 +19,17 @@ void[] allocScratchpad(size_t size = MaxScratchpadSize) return null; } - size = max(size.nextPowerOf2, WindowSize); + size = max(size.next_power_of_2, WindowSize); size_t maskBits = size / WindowSize; size_t mask = (1 << maskBits) - 1; - for (size_t page = 0; page < scratchpadAlloc.length; ++page) + for (size_t page = 0; page < scratchpad_alloc.length; ++page) { for (size_t window = 0; window < 8; window += maskBits) { - if ((scratchpadAlloc[page] & (mask << window)) == 0) + if ((scratchpad_alloc[page] & (mask << window)) == 0) { - scratchpadAlloc[page] |= mask << window; + scratchpad_alloc[page] |= mask << window; return scratchpad[page*MaxScratchpadSize + window*WindowSize .. page*MaxScratchpadSize + window*WindowSize + size]; } } @@ -40,7 +40,7 @@ void[] allocScratchpad(size_t size = MaxScratchpadSize) return null; } -void freeScratchpad(void[] mem) +void free_scratchpad(void[] mem) { size_t page = (cast(size_t)mem.ptr - cast(size_t)scratchpad.ptr) / MaxScratchpadSize; size_t window = (cast(size_t)mem.ptr - cast(size_t)scratchpad.ptr) % MaxScratchpadSize / WindowSize; @@ -48,8 +48,8 @@ void freeScratchpad(void[] mem) size_t maskBits = mem.length / WindowSize; size_t mask = (1 << maskBits) - 1; - assert((scratchpadAlloc[page] & (mask << window)) == (mask << window), "Freeing unallocated scratchpad memory!"); - scratchpadAlloc[page] &= ~(mask << window); + assert((scratchpad_alloc[page] & (mask << window)) == (mask << window), "Freeing unallocated scratchpad memory!"); + scratchpad_alloc[page] &= ~(mask << window); } private: @@ -57,31 +57,31 @@ private: enum WindowSize = MaxScratchpadSize / 8; __gshared ubyte[MaxScratchpadSize*NumScratchBuffers] scratchpad; -__gshared ubyte[NumScratchBuffers] scratchpadAlloc; +__gshared ubyte[NumScratchBuffers] scratchpad_alloc; unittest { - void[] t = allocScratchpad(MaxScratchpadSize); + void[] t = alloc_scratchpad(MaxScratchpadSize); assert(t.length == MaxScratchpadSize); - void[] t2 = allocScratchpad(MaxScratchpadSize / 2); + void[] t2 = alloc_scratchpad(MaxScratchpadSize / 2); assert(t2.length == MaxScratchpadSize / 2); - void[] t3 = allocScratchpad(MaxScratchpadSize / 2); + void[] t3 = alloc_scratchpad(MaxScratchpadSize / 2); assert(t3.length == MaxScratchpadSize / 2); - void[] t4 = allocScratchpad(MaxScratchpadSize / 4); + void[] t4 = alloc_scratchpad(MaxScratchpadSize / 4); assert(t4.length == MaxScratchpadSize / 4); - void[] t5 = allocScratchpad(MaxScratchpadSize / 8); + void[] t5 = alloc_scratchpad(MaxScratchpadSize / 8); assert(t5.length == MaxScratchpadSize / 8); - void[] t6 = allocScratchpad(MaxScratchpadSize / 4); + void[] t6 = alloc_scratchpad(MaxScratchpadSize / 4); assert(t6.length == MaxScratchpadSize / 4); - void[] t7 = allocScratchpad(MaxScratchpadSize / 8); + void[] t7 = alloc_scratchpad(MaxScratchpadSize / 8); assert(t7.length == MaxScratchpadSize / 8); - freeScratchpad(t); - freeScratchpad(t7); - freeScratchpad(t5); - freeScratchpad(t4); - freeScratchpad(t6); - freeScratchpad(t2); - freeScratchpad(t3); + free_scratchpad(t); + free_scratchpad(t7); + free_scratchpad(t5); + free_scratchpad(t4); + free_scratchpad(t6); + free_scratchpad(t2); + free_scratchpad(t3); } diff --git a/src/urt/mem/string.d b/src/urt/mem/string.d index a04f5e9..15ede1d 100644 --- a/src/urt/mem/string.d +++ b/src/urt/mem/string.d @@ -4,61 +4,58 @@ import urt.mem; import urt.string; -// TODO: THIS IS TEMP!! REMOVE ME!! -shared static this() -{ - initStringHeap(ushort.max); -} - - -struct StringCache -{ -} - struct CacheString { +nothrow @nogc: alias toString this; - this(typeof(null)) pure nothrow @nogc + this(typeof(null)) pure { offset = 0; } - string toString() const nothrow @nogc + string toString() const pure { - ushort len = *cast(ushort*)(stringHeap.ptr + offset); - return cast(string)stringHeap[offset + 2 .. offset + 2 + len]; + // HACK: deploy the pure hack! + static char[] pureHack() nothrow @nogc => stringHeap; + string heap = (cast(immutable(char[]) function() pure nothrow @nogc)&pureHack)(); + + ushort len = *cast(ushort*)(heap.ptr + offset); + return heap[offset + 2 .. offset + 2 + len]; } - immutable(char)* ptr() const nothrow @nogc - => cast(immutable(char)*)(stringHeap.ptr + offset + 2); + immutable(char)* ptr() const pure + => toString().ptr; + + size_t length() const pure + => toString().length; - size_t length() const nothrow @nogc - => *cast(ushort*)(stringHeap.ptr + offset); + string opIndex() const pure + => toString(); - bool opCast(T : bool)() const pure nothrow @nogc + bool opCast(T : bool)() const pure => offset != 0; - void opAssign(typeof(null)) pure nothrow @nogc + void opAssign(typeof(null)) pure { offset = 0; } - bool opEquals(const(char)[] rhs) const nothrow @nogc + bool opEquals(const(char)[] rhs) const pure { string s = toString(); - return s.length == rhs.length && (s.ptr == rhs.ptr || s[] == rhs[]); + return s.length == rhs.length && (s.ptr is rhs.ptr || s[] == rhs[]); } - size_t toHash() const nothrow @nogc + size_t toHash() const pure { import urt.hash; static if (size_t.sizeof == 4) - return fnv1aHash(cast(ubyte[])toString()); + return fnv1a(cast(ubyte[])toString()); else - return fnv1aHash64(cast(ubyte[])toString()); + return fnv1a64(cast(ubyte[])toString()); } private: @@ -69,29 +66,31 @@ private: this.offset = offset; } - auto __debugOverview() => toString; - auto __debugExpanded() => toString; - auto __debugStringView() => toString; + version (Windows) + { + auto __debugOverview() => toString; + auto __debugExpanded() => toString; + auto __debugStringView() => toString; + } } -void initStringHeap(uint stringHeapSize) nothrow +void init_string_heap(uint string_heap_size) nothrow @nogc { assert(stringHeapInitialised == false, "String heap already initialised!"); - assert(stringHeapSize <= ushort.max, "String heap too large!"); + assert(string_heap_size <= ushort.max, "String heap too large!"); - stringHeap = new char[stringHeapSize]; + stringHeap = defaultAllocator.allocArray!char(string_heap_size); // write the null string to the start - stringHeapCursor = 0; - stringHeap[stringHeapCursor++] = 0; - stringHeap[stringHeapCursor++] = 0; - numStrings = 1; + stringHeap[0..2] = 0; + stringHeapCursor = 2; stringHeapInitialised = true; } -void deinitStringHeap() nothrow +void deinit_string_heap() nothrow @nogc { + defaultAllocator.freeArray(stringHeap); } uint getStringHeapAllocated() nothrow @nogc @@ -104,44 +103,46 @@ uint getStringHeapRemaining() nothrow @nogc return cast(uint)stringHeap.length - stringHeapCursor; } -CacheString addString(const(char)[] str, bool dedup = true) nothrow @nogc +CacheString addString(const(char)[] str) pure nothrow @nogc { - // null string - if (str.length == 0) - return CacheString(0); + // HACK: even though this mutates global state, the string cache is immutable after it's emplaced + // so, multiple calls with the same source string will always return the same result! + static CacheString impl(const(char)[] str) nothrow @nogc + { + // null string + if (str.length == 0) + return CacheString(0); - assert(str.length < 2^^14, "String longer than max string len (32768 chars)"); + assert(str.length < 2^^14, "String longer than max string len (32768 chars)"); - if (dedup) - { // first we scan to see if it's already in here... - for (ushort i = 1; i < stringHeapCursor;) + for (ushort i = 2; i < stringHeapCursor;) { ushort offset = i; - ushort len = stringHeap[i++]; - if (len >= 128) - len = (len & 0x7F) | ((stringHeap[i++] << 7) & 0x7F); + ushort len = *cast(ushort*)(stringHeap.ptr + i); + i += 2; if (len == str.length && stringHeap[i .. i + len] == str[]) return CacheString(offset); - i += len; + i += len + (len & 1); } - } - if (stringHeapCursor & 1) - stringHeap[stringHeapCursor++] = '\0'; + // add the string to the heap... + assert(stringHeapCursor + str.length < stringHeap.length, "String heap overflow!"); - // add the string to the heap... - assert(stringHeapCursor + str.length < stringHeap.length, "String heap overflow!"); + char[] heap = stringHeap[stringHeapCursor .. $]; + ushort offset = stringHeapCursor; - ushort offset = stringHeapCursor; - str.makeString(stringHeap[stringHeapCursor .. $]); - stringHeapCursor += str.length + 2; - ++numStrings; + *cast(ushort*)heap.ptr = cast(ushort)str.length; + heap[2 .. 2 + str.length] = str[]; + stringHeapCursor += str.length + 2; + if (stringHeapCursor & 1) + stringHeap[stringHeapCursor++] = '\0'; - return CacheString(offset); + return CacheString(offset); + } + return (cast(CacheString function(const(char)[]) pure nothrow @nogc)&impl)(str); } - void* allocWithStringCache(size_t bytes, String[] cachedStrings, const(char[])[] strings) nothrow @nogc { import urt.mem.alloc; @@ -170,15 +171,20 @@ void* allocWithStringCache(size_t bytes, String[] cachedStrings, const(char[])[] class StringAllocator : NoGCAllocator { - override void[] alloc(size_t bytes, size_t alignment = 1) nothrow @nogc + override void[] alloc(size_t bytes, size_t alignment = 1) pure nothrow @nogc { - assert(stringHeapCursor + bytes < stringHeap.length, "String heap overflow!"); + static void[] impl(size_t bytes, size_t alignment) nothrow @nogc + { + assert(stringHeapCursor + bytes < stringHeap.length, "String heap overflow!"); - char[] heap = cast(char[])stringHeap; - return heap[stringHeapCursor .. stringHeapCursor + bytes]; + char[] heap = cast(char[])stringHeap; + return heap[stringHeapCursor .. stringHeapCursor + bytes]; + } + alias PureHack = void[] function(size_t, size_t) pure nothrow @nogc; + return (cast(PureHack)&impl)(bytes, alignment); } - override void free(void[] mem) nothrow @nogc + override void free(void[] mem) pure nothrow @nogc { // you don't free cached strings! } @@ -191,7 +197,6 @@ private: __gshared bool stringHeapInitialised = false; __gshared char[] stringHeap = null; __gshared ushort stringHeapCursor = 0; -__gshared uint numStrings = 0; unittest diff --git a/src/urt/mem/temp.d b/src/urt/mem/temp.d index 6f2d28b..a9ef919 100644 --- a/src/urt/mem/temp.d +++ b/src/urt/mem/temp.d @@ -1,14 +1,16 @@ module urt.mem.temp; +import urt.attribute : fast_data; import urt.mem; version = DebugTempAlloc; +nothrow @nogc: enum size_t TempMemSize = 4096; -void[] talloc(size_t size) nothrow @nogc +void[] talloc(size_t size) pure { debug version (DebugTempAlloc) { @@ -16,27 +18,36 @@ void[] talloc(size_t size) nothrow @nogc assert(InFormatFunction == false, "It is illegal to use the temp allocator inside string conversion functions. Consider using stack or scratchpad."); } - if (size >= TempMemSize / 2) - { - assert(false, "Requested temp memory size is too large"); - return null; - } - - if (allocOffset + size > TempMemSize) - allocOffset = 0; + assert(size <= TempMemSize / 2, "Requested temp memory size is too large"); - void[] mem = tempMem[allocOffset .. allocOffset + size]; - allocOffset += size; - - return mem; + void[] mem = tmem_tail(); + if (mem.length < size) + mem = tmem_reset(); + tmem_advance(size); + return mem[0 .. size]; } -void[] tallocAligned(size_t size, size_t alignment) nothrow @nogc +void[] talloc_aligned(size_t size, size_t alignment) pure { - assert(false); + import urt.util; + + debug assert(alignment != 0 && is_power_of_2(alignment), "alignment must be a power of two"); + assert(size <= TempMemSize / 2, "Requested temp memory size is too large"); + + void[] mem = tmem_tail(); + auto ptr = align_up(mem.ptr, alignment); + size_t adjust = ptr - mem.ptr; + if (adjust + size > mem.length) + { + mem = tmem_reset(); + ptr = align_up(mem.ptr, alignment); + adjust = ptr - mem.ptr; + } + tmem_advance(adjust + size); + return ptr[0 .. size]; } -void[] trealloc(void[] mem, size_t newSize) nothrow @nogc +void[] trealloc(void[] mem, size_t newSize) pure { if (newSize <= mem.length) return mem[0 .. newSize]; @@ -50,85 +61,142 @@ void[] trealloc(void[] mem, size_t newSize) nothrow @nogc return r; } -void[] treallocAligned(void[] mem, size_t newSize, size_t alignment) nothrow @nogc +void[] trealloc_aligned(void[] mem, size_t newSize, size_t alignment) pure { assert(false); } -void[] texpand(void[] mem, size_t newSize) nothrow @nogc +void[] texpand(void[] mem, size_t newSize) pure { - if (mem.ptr + mem.length != tempMem.ptr + allocOffset) + void[] tmem = tmem_tail(); + if (mem.ptr + mem.length != tmem.ptr) return null; ptrdiff_t grow = newSize - mem.length; - if (cast(size_t)(allocOffset + grow) > TempMemSize) + if (grow > tmem.length) return null; - allocOffset += grow; + tmem_advance(grow); return mem.ptr[0 .. newSize]; } -void tfree(void[] mem) nothrow @nogc +void tfree(void[] mem) pure { // maybe do some debug accounting...? } -char* tstringz(const(char)[] str) nothrow @nogc +char* tstringz(const(char)[] str) pure { - if (str.length > TempMemSize / 2) - return null; - - size_t len = str.length; - if (allocOffset + len + 1 > TempMemSize) - allocOffset = 0; + char* r = cast(char*)talloc(str.length + 1).ptr; + r[0 .. str.length] = str[]; + r[str.length] = '\0'; + return r; +} +char* tstringz(const(wchar)[] str) pure +{ + import urt.string.uni : uni_convert; + char* r = cast(char*)talloc(str.length*3 + 1).ptr; + size_t len = uni_convert(str, r[0 .. str.length*3]); + r[len] = '\0'; + return r; +} - char* r = cast(char*)tempMem.ptr + allocOffset; - r[0 .. len] = str[]; +wchar* twstringz(const(char)[] str) pure +{ + import urt.string.uni : uni_convert; + wchar* r = cast(wchar*)talloc(str.length*2 + 2).ptr; + size_t len = uni_convert(str, r[0 .. str.length]); r[len] = '\0'; - allocOffset += len + 1; + return r; +} +wchar* twstringz(const(wchar)[] str) pure +{ + wchar* r = cast(wchar*)talloc(str.length*2 + 2).ptr; + r[0 .. str.length] = str[]; + r[str.length] = '\0'; return r; } -char[] tstring(T)(auto ref T value) +const(char)[] tstring(T)(auto ref T value) { - import urt.string.format : toString; - ptrdiff_t r = toString(value, cast(char[])tempMem[allocOffset..$]); - if (r < 0) + import urt.string, urt.array; + static if (is(T : const(char)[]) || is(T : const String) || is(T : const MutableString!N, size_t N) || is(T : const Array!char)) + { + pragma(inline, true); + return value[]; + } + else { - allocOffset = 0; - r = toString(value, cast(char[])tempMem[0..TempMemSize / 2]); + import urt.string.format : toString; + char[] tmem = cast(char[])tmem_tail(); + ptrdiff_t r = toString(value, tmem); if (r < 0) { -// assert(false, "Formatted string is too large for the temp buffer!"); - return null; + tmem = cast(char[])tmem_reset(); + r = toString(value, tmem); + if (r < 0) + { +// assert(false, "Formatted string is too large for the temp buffer!"); + return null; + } } + const(char)[] result = tmem[0 .. r]; + tmem_advance(r); + return result; + } +} + +const(dchar)[] tdstring(T)(auto ref T value) +{ + static if (is(T : const(char)[]) || is(T : const(wchar)[]) || is(T : const(dchar)[])) + alias s = value; + else + char[] s = tstring(value); + import urt.string.uni : uni_convert; + dchar* r = cast(dchar*)talloc(s[].length*4).ptr; + size_t len = uni_convert(s[], r[0 .. s.length]); + return r[0 .. len]; +} + +const(char)[] tconcat(Args...)(ref Args args) +{ + import urt.string, urt.array; + static if (Args.length == 1 && (is(Args[0] : const(char)[]) || is(Args[0] : const String) || is(Args[0] : const MutableString!N, size_t N) || is(Args[0] : const Array!char))) + { + pragma(inline, true); + return args[0][]; + } + else + { + pragma(inline, true); + import urt.string.format : normalise_args; + return tconcat_impl(normalise_args(args)); } - char[] result = cast(char[])tempMem[allocOffset .. allocOffset + r]; - allocOffset += r; - return result; } -char[] tconcat(Args...)(ref Args args) +import urt.meta.tuple : Tuple; +const(char)[] tconcat_impl(Args...)(Tuple!Args args) { - import urt.string.format : concat; - char[] r = concat(cast(char[])tempMem[allocOffset..$], args); + import urt.string.format : concat_impl; + const(char)[] r = concat_impl(cast(char[])tempMem[alloc_offset..$], args); if (!r) { - allocOffset = 0; - r = concat(cast(char[])tempMem[0..TempMemSize / 2], args); + alloc_offset = 0; + r = concat_impl(cast(char[])tempMem[0..TempMemSize / 2], args); } - allocOffset += r.length; + alloc_offset += r.length; return r; } + char[] tformat(Args...)(const(char)[] fmt, ref Args args) { import urt.string.format : format; - char[] r = format(cast(char[])tempMem[allocOffset..$], fmt, args); + char[] r = format(cast(char[])tempMem[alloc_offset..$], fmt, args); if (!r) { - allocOffset = 0; + alloc_offset = 0; r = format(cast(char[])tempMem[0..TempMemSize / 2], fmt, args); } - allocOffset += r.length; + alloc_offset += r.length; return r; } @@ -136,15 +204,21 @@ char[] tformat(Args...)(const(char)[] fmt, ref Args args) class TempAllocator : NoGCAllocator { static import urt.mem.alloc; +nothrow @nogc: - static TempAllocator instance() nothrow @nogc => _instance; + static TempAllocator instance() pure + { + alias PureHack = TempAllocator function() pure nothrow @nogc; + static TempAllocator hack() nothrow @nogc => _instance; + return (cast(PureHack)&hack)(); + } - override void[] alloc(size_t bytes, size_t alignment = DefaultAlign) nothrow @nogc + override void[] alloc(size_t bytes, size_t alignment = DefaultAlign) pure { - return talloc(bytes); + return talloc_aligned(bytes, alignment); } - override void[] realloc(void[] mem, size_t newSize, size_t alignment = DefaultAlign) nothrow @nogc + override void[] realloc(void[] mem, size_t newSize, size_t alignment = DefaultAlign) pure { return trealloc(mem, newSize); // TODO... @@ -152,12 +226,12 @@ class TempAllocator : NoGCAllocator return null; } - override void[] expand(void[] mem, size_t newSize) nothrow + override void[] expand(void[] mem, size_t newSize) pure { return texpand(mem, newSize); } - override void free(void[] mem) nothrow @nogc + override void free(void[] mem) pure { tfree(mem); } @@ -169,5 +243,44 @@ private: private: -static void[TempMemSize] tempMem; -static ushort allocOffset = 0; +// TODO: we shpuld really have some indicator if the machine is multi-core or not... +// this is doomed the moment we light up the esp32's second core! +version (BareMetal) +{ + @fast_data align(size_t.alignof) __gshared void[TempMemSize] tempMem; + @fast_data __gshared ushort alloc_offset = 0; +} +else +{ + align(size_t.alignof) static void[TempMemSize] tempMem; + static ushort alloc_offset = 0; +} + +void[] tmem_tail() pure +{ + static void[] impl() nothrow @nogc + => tempMem[alloc_offset..$]; + alias PureHack = void[] function() pure nothrow @nogc; + return (cast(PureHack)&impl)(); +} + +void[] tmem_reset() pure +{ + static void[] impl() nothrow @nogc + { + alloc_offset = 0; + return tempMem[0..TempMemSize / 2]; + } + alias PureHack = void[] function() pure nothrow @nogc; + return (cast(PureHack)&impl)(); +} + +void tmem_advance(size_t n) pure +{ + static void impl(ushort n) nothrow @nogc + { + alloc_offset += n; + } + alias PureHack = void function(ushort) pure nothrow @nogc; + return (cast(PureHack)&impl)(cast(ushort)n); +} diff --git a/src/urt/mem/tracking.d b/src/urt/mem/tracking.d new file mode 100644 index 0000000..16ee6e4 --- /dev/null +++ b/src/urt/mem/tracking.d @@ -0,0 +1,413 @@ +/** + * Allocation tracking for leak detection. + * + * Enabled with `version = AllocTracking;`. When enabled, the central + * allocator (`urt.mem.alloc`) calls into this module on every + * alloc/realloc/free to record the caller's stack trace in a fixed-size + * open-addressed hash table keyed on pointer. + * + * The table uses static `__gshared` storage (no allocation of its own, + * which would recurse) and is NOT thread-safe. + * + * Typical workflow: + * 1. Boot the system, let all startup/immortal allocations settle. + * 2. Call `alloc_mark_baseline()` (via the console command + * `/system/alloc/mark`). + * 3. After running for a while, call `alloc_print_leaks(min_age, sink)` + * to see allocations made after the baseline that have been alive + * for at least `min_age`, grouped by call site. + */ +module urt.mem.tracking; + +version (AllocTracking): + +import urt.time : MonoTime, getTime, Duration; +import urt.internal.exception : capture_trace, resolve_address, resolve_batch, Resolved; + +nothrow @nogc: + + +// Tuning + +// Number of stack frames captured per allocation. +enum trace_depth = 6; + +// Maximum live allocations tracked. +// ~80 bytes per entry on 64-bit: 16384 * 80 = 1.25 MiB. +enum track_capacity = 16384; +static assert((track_capacity & (track_capacity - 1)) == 0, "track_capacity must be a power of two"); + +// Load factor ceiling (num/den). Linear probing degrades past ~70%. +enum track_max_load_num = 7; +enum track_max_load_den = 10; + +// Max unique call sites shown in a grouped leak dump. +enum max_groups = 256; + + +// Entry / storage + +struct Entry +{ + void* ptr; // null = empty, (void*)1 = tombstone + uint size; + uint serial; + MonoTime time; + void*[trace_depth] pcs; +} + +__gshared Entry[track_capacity] _table; +__gshared uint _live_count; +__gshared uint _serial_counter; +__gshared uint _baseline_serial; +__gshared ulong _tracked_bytes; +__gshared bool _table_full_warned; + + +// Tracking API -- called by urt.mem.alloc hooks + +void track_alloc(void* ptr, size_t size) +{ + if (ptr is null) + return; + + // Refuse inserts past the load factor -- linear probing gets pathological. + if (_live_count * track_max_load_den >= track_capacity * track_max_load_num) + { + warn_table_full(); + return; + } + + size_t slot = find_insert(ptr); + if (slot == size_t.max) + { + warn_table_full(); + return; + } + + bool was_live = _table[slot].ptr !is null && _table[slot].ptr !is tombstone; + if (was_live) + _tracked_bytes -= _table[slot].size; + else + _live_count++; + + _table[slot].ptr = ptr; + _table[slot].size = cast(uint) size; + _table[slot].serial = ++_serial_counter; + _table[slot].time = getTime(); + _table[slot].pcs[] = null; + capture_trace(_table[slot].pcs[]); + + _tracked_bytes += size; +} + +void untrack_alloc(void* ptr) +{ + if (ptr is null) + return; + size_t slot = find(ptr); + if (slot == size_t.max) + return; + _tracked_bytes -= _table[slot].size; + _table[slot].ptr = tombstone; + _table[slot].size = 0; + _live_count--; +} + +void track_realloc(void* old_ptr, void* new_ptr, size_t new_size) +{ + if (old_ptr is new_ptr) + { + if (new_ptr is null) + return; + size_t slot = find(new_ptr); + if (slot != size_t.max) + { + _tracked_bytes = _tracked_bytes - _table[slot].size + new_size; + _table[slot].size = cast(uint) new_size; + // Keep original serial/time/trace -- the allocation's identity hasn't changed. + } + else + track_alloc(new_ptr, new_size); + return; + } + untrack_alloc(old_ptr); + track_alloc(new_ptr, new_size); +} + + +// Baseline / stats + +void alloc_mark_baseline() +{ + _baseline_serial = _serial_counter; +} + +uint alloc_baseline() => _baseline_serial; + +void alloc_stats(out uint live_count, out ulong live_bytes, out uint capacity, out uint total_serial) +{ + live_count = _live_count; + live_bytes = _tracked_bytes; + capacity = track_capacity; + total_serial = _serial_counter; +} + + +// Report helpers + +// Return the first frame in `pcs` whose resolved symbol is NOT a known +// allocator wrapper. Falls back to the last non-null frame if every +// frame resolves to a wrapper. +void* top_user_pc(const(void*)[] pcs) +{ + void* fallback = null; + foreach (addr; pcs) + { + if (addr is null) + continue; + fallback = cast(void*) addr; + + Resolved r; + if (!resolve_address(cast(void*) addr, r)) + return cast(void*) addr; // unresolved -> assume user code + if (!is_wrapper_name(r.name)) + return cast(void*) addr; + } + return fallback; +} + +alias Sink = void delegate(const(char)[]) nothrow @nogc; + +// Sink-based stats dump. One sink call per line, no trailing newline. +void alloc_print_stats(scope Sink sink) +{ + import urt.mem.temp : tformat; + + sink(tformat("Live allocations: {0}", _live_count)); + sink(tformat("Live bytes: {0}", _tracked_bytes)); + sink(tformat("Table capacity: {0}", cast(uint) track_capacity)); + sink(tformat("Total allocs: {0} (serial)", _serial_counter)); + sink(tformat("Baseline: {0}", _baseline_serial)); + if (_table_full_warned) + sink("WARNING: tracking table has overflowed at least once -- some allocations untracked"); +} + +// Grouped leak dump. Shows allocations with `serial > baseline` that +// have been alive at least `min_age`, grouped by top-user PC. +void alloc_print_leaks(Duration min_age, scope Sink sink) +{ + print_candidates(_baseline_serial, min_age, "Leak candidates", sink); +} + +// Grouped dump of every currently-live allocation, ignoring baseline +// and age. Intended for shutdown/exit leak reports -- at shutdown +// anything still alive is effectively a leak. +void alloc_print_live(scope Sink sink) +{ + print_candidates(0, Duration.init, "Live allocations", sink); +} + +private void print_candidates(uint min_serial, Duration min_age, string kind, scope Sink sink) +{ + import urt.mem.temp : tconcat, tformat; + + struct Site + { + void* pc; + uint count; + ulong bytes; + MonoTime oldest; + } + + Site[max_groups] groups = void; + size_t ngroups = 0; + Site overflow; + overflow.pc = null; + overflow.count = 0; + overflow.bytes = 0; + + MonoTime now = getTime(); + + uint total_count = 0; + ulong total_bytes = 0; + + foreach (ref e; _table) + { + if (e.ptr is null || e.ptr is tombstone) + continue; + if (e.serial <= min_serial) + continue; + if (now - e.time < min_age) + continue; + + void* top = top_user_pc(e.pcs[]); + + size_t g = size_t.max; + foreach (i; 0 .. ngroups) + if (groups[i].pc is top) { g = i; break; } + + Site* s; + if (g == size_t.max) + { + if (ngroups < max_groups) + { + groups[ngroups].pc = top; + groups[ngroups].count = 0; + groups[ngroups].bytes = 0; + groups[ngroups].oldest = e.time; + s = &groups[ngroups]; + ngroups++; + } + else + s = &overflow; + } + else + s = &groups[g]; + + s.count++; + s.bytes += e.size; + if (e.time < s.oldest || s.oldest == MonoTime()) + s.oldest = e.time; + + total_count++; + total_bytes += e.size; + } + + if (total_count == 0) + { + sink(tformat("{0}: none (min serial {1}, min age {2})", kind, min_serial, min_age)); + return; + } + + // Sort by bytes descending -- insertion sort, ngroups is small. + foreach (i; 1 .. ngroups) + { + Site tmp = groups[i]; + size_t j = i; + while (j > 0 && groups[j - 1].bytes < tmp.bytes) + { + groups[j] = groups[j - 1]; + --j; + } + groups[j] = tmp; + } + + sink(tformat("{0}: {1} allocations, {2} bytes, {3} unique sites", + kind, total_count, total_bytes, + cast(uint) ngroups + (overflow.count > 0 ? 1 : 0))); + sink(""); + + // One batched resolve for all unique sites - on POSIX this folds + // what was N full DWARF .debug_line scans into a single scan. + void*[max_groups] addrs = void; + Resolved[max_groups] resolved; + foreach (i; 0 .. ngroups) + addrs[i] = groups[i].pc; + resolve_batch(addrs[0 .. ngroups], resolved[0 .. ngroups]); + + foreach (i; 0 .. ngroups) + { + Site s = groups[i]; + Duration age = now - s.oldest; + const r = &resolved[i]; + + sink(tformat(" {0} allocs, {1} bytes, oldest {2}", s.count, s.bytes, age)); + if (r.file.length > 0 && r.line > 0) + sink(tformat(" {0}({1}): {2}", r.file, r.line, r.name)); + else if (r.name.length > 0) + sink(tconcat(" ", r.name)); + else + sink(tconcat(" 0x", s.pc)); + } + + if (overflow.count > 0) + { + Duration age = now - overflow.oldest; + sink(tformat(" [overflow] {0} allocs, {1} bytes, oldest {2} (from > {3} unique sites)", + overflow.count, overflow.bytes, age, cast(uint) max_groups)); + } +} + + +private: + +enum void* tombstone = cast(void*) 1; + +// Prefixes of symbol names considered "allocator plumbing" and skipped +// when computing the top user frame. Extend as needed. +immutable string[] WRAPPER_PREFIXES = [ + "urt.mem.", + "urt.internal.exception.", // capture_trace itself lives here + "_d_new", + "_d_alloc", + "_d_array", + "_D3urt3mem", +]; + +bool is_wrapper_name(const(char)[] name) +{ + foreach (p; WRAPPER_PREFIXES) + { + if (name.length >= p.length && name[0 .. p.length] == p) + return true; + } + return false; +} + +void warn_table_full() +{ + if (_table_full_warned) + return; + _table_full_warned = true; + + import urt.io : writeln_err; + writeln_err("urt.mem.tracking: allocation table at capacity -- subsequent allocs untracked! Increase track_capacity in urt.mem.tracking."); +} + + +// Hash table primitives + +size_t hash_ptr(void* p) pure +{ + size_t x = cast(size_t) p >> 3; + return cast(size_t)(cast(ulong) x * 0x9E3779B97F4A7C15UL); +} + +size_t find(void* ptr) +{ + enum mask = cast(size_t)(track_capacity - 1); + size_t i = hash_ptr(ptr) & mask; + foreach (_; 0 .. track_capacity) + { + void* p = _table[i].ptr; + if (p is null) + return size_t.max; + if (p is ptr) + return i; + i = (i + 1) & mask; + } + return size_t.max; +} + +size_t find_insert(void* ptr) +{ + enum mask = cast(size_t)(track_capacity - 1); + size_t i = hash_ptr(ptr) & mask; + size_t first_tomb = size_t.max; + foreach (_; 0 .. track_capacity) + { + void* p = _table[i].ptr; + if (p is null) + return first_tomb != size_t.max ? first_tomb : i; + if (p is tombstone) + { + if (first_tomb == size_t.max) + first_tomb = i; + } + else if (p is ptr) + return i; + i = (i + 1) & mask; + } + return first_tomb; +} diff --git a/src/urt/meta/enuminfo.d b/src/urt/meta/enuminfo.d new file mode 100644 index 0000000..1a1ef5e --- /dev/null +++ b/src/urt/meta/enuminfo.d @@ -0,0 +1,394 @@ +module urt.meta.enuminfo; + +import urt.algorithm : binary_search, qsort; +import urt.traits :EnumType, is_enum, Unqual; +import urt.meta : Iota, STATIC_MAP; +import urt.variant; + +nothrow @nogc: + + +const(E)* enum_from_key(E)(const(char)[] key) pure + if (is_enum!E) + => enum_info!E.value_for(key); + +const(char)[] enum_key_from_value(E)(EnumType!E value) pure + if (is_enum!E) + => enum_info!E.key_for(value); + +const(char)[] enum_key_by_decl_index(E)(size_t value) pure + if (is_enum!E) + => enum_info!E.key_by_decl_index(value); + +struct VoidEnumInfo +{ + import urt.algorithm : binary_search; +nothrow @nogc: + + // keys and values are sorted for binary search + ushort count; + ushort stride; + uint type_hash; + + const(char)[] key_for(const void* value, int function(const void* a, const void* b) pure nothrow @nogc pred) const pure + { + size_t i = binary_search(_values[0 .. count*stride], stride, value, pred); + if (i < count) + return get_key(_lookup_tables[count + i]); + return null; + } + + const(char)[] key_for(const void* value, int delegate(const void* a, const void* b) pure nothrow @nogc pred) const pure + { + size_t i = binary_search(_values[0 .. count*stride], stride, value, pred); + if (i < count) + return get_key(_lookup_tables[count + i]); + return null; + } + + const(char)[] key_by_decl_index(size_t i) const pure + { + assert(i < count, "Declaration index out of range"); + return get_key(_lookup_tables[count*2 + i]); + } + + const(char)[] key_by_sorted_index(size_t i) const pure + { + assert(i < count, "Declaration index out of range"); + return get_key(i); + } + + Variant value_for(const(char)[] key) const pure + { + size_t i = binary_search!key_compare(_keys[0 .. count], key, _string_buffer); + if (i == count) + return Variant(); + i = _lookup_tables[i]; + return _get_value(_values + i*stride, &this); + } + + bool contains(const(char)[] key) const pure + { + size_t i = binary_search!key_compare(_keys[0 .. count], key, _string_buffer); + return i < count; + } + +private: + const void* _values; + const ushort* _keys; + const char* _string_buffer; + + // these tables map between indices of keys and values + const ubyte* _lookup_tables; + + const GetFun _get_value; + + this(ubyte count, ushort stride, uint type_hash, inout void* values, inout ushort* keys, inout char* strings, inout ubyte* lookup, GetFun get_value) inout pure + { + this.count = count; + this.stride = stride; + this.type_hash = type_hash; + this._keys = keys; + this._values = values; + this._string_buffer = strings; + this._lookup_tables = lookup; + this._get_value = get_value; + } + + const(char)[] get_key(size_t i) const pure + { + const(char)* s = _string_buffer + _keys[i]; + return s[0 .. s.key_length]; + } +} + +template EnumInfo(E) +{ + static assert (is(E == Unqual!E), "EnumInfo can only be instantiated with unqualified types!"); + + static if (is(E == void)) + alias EnumInfo = VoidEnumInfo; + else + { + struct EnumInfo + { + import urt.algorithm : binary_search; + nothrow @nogc: + + static assert (EnumInfo.sizeof == EnumInfo.sizeof, "Template EnumInfo must not add any members!"); + + static if (is(E T == enum)) + alias V = T; + else + static assert(false, E.string ~ " is not an enum type!"); + + // keys and values are sorted for binary search + union { + VoidEnumInfo _base; + struct { + ubyte[VoidEnumInfo._values.offsetof] _pad; + const E* _values; // shadows the _values in _base with a typed version + } + } + alias _base this; + + inout(VoidEnumInfo*) make_void() inout pure + => &_base; + + this(ubyte count, uint type_hash, inout(E)* values, inout ushort* keys, inout char* strings, inout ubyte* lookup) inout pure + { + _base = inout(VoidEnumInfo)(count, E.sizeof, type_hash, values, keys, strings, lookup, cast(GetFun)&get_value!V); + } + + const(E)[] values() const pure + => _values[0 .. count]; + + const(char)[] key_for(V value) const pure + { + size_t i = binary_search(values[0 .. count], value); + if (i < count) + return get_key(_lookup_tables[count + i]); + return null; + } + + const(char)[] key_by_decl_index(size_t i) const pure + => _base.key_by_decl_index(i); + + const(char)[] key_by_sorted_index(size_t i) const pure + => _base.key_by_sorted_index(i); + + const(E)* value_for(const(char)[] key) const pure + { + size_t i = binary_search!key_compare(_keys[0 .. count], key, _string_buffer); + if (i == count) + return null; + return _values + _lookup_tables[i]; + } + + bool contains(const(char)[] key) const pure + => _base.contains(key); + } + } +} + +template enum_info(E) + if (is(E == enum)) +{ + static assert (is(E == Unqual!E), "EnumInfo can only be instantiated with unqualified types!"); + + enum ubyte num_items = enum_members.length; + static assert(num_items <= ubyte.max, "Too many enum items!"); + + __gshared immutable enum_info = immutable(EnumInfo!E)( + num_items, + fnv1a(cast(ubyte[])E.stringof), + _values.ptr, + _keys.ptr, + _strings.ptr, + _lookup.ptr + ); + +private: + import urt.algorithm : binary_search, compare, qsort; + import urt.hash : fnv1a; + import urt.string.uni : uni_compare; + + // keys and values are sorted for binary search + __gshared immutable E[num_items] _values = [ STATIC_MAP!(GetValue, iota) ]; + + // keys are stored as offsets info the string buffer + __gshared immutable ushort[num_items] _keys = () { + ushort[num_items] key_offsets; + size_t offset = 2; + foreach (i; 0 .. num_items) + { + const(char)[] key = by_key[i].k; + key_offsets[i] = cast(ushort)offset; + offset += 2 + key.length; + if (key.length & 1) + offset += 1; // align to 2 bytes + } + return key_offsets; + }(); + + // build the string buffer + __gshared immutable char[total_strings] _strings = () { + char[total_strings] str_data; + char* ptr = str_data.ptr; + foreach (i; 0 .. num_items) + { + const(char)[] key = by_key[i].k; + version (LittleEndian) + { + *ptr++ = key.length & 0xFF; + *ptr++ = (key.length >> 8) & 0xFF; + } + else + { + *ptr++ = (key.length >> 8) & 0xFF; + *ptr++ = key.length & 0xFF; + } + ptr[0 .. key.length] = key[]; + ptr += key.length; + if (key.length & 1) + *ptr++ = 0; // align to 2 bytes + } + return str_data; + }(); + + // these tables map between indices of keys and values + __gshared immutable ubyte[num_items * 3] _lookup = [ STATIC_MAP!(GetKeyRedirect, iota), + STATIC_MAP!(GetValRedirect, iota), + STATIC_MAP!(GetKeyOrig, iota) ]; + + // a whole bunch of nonsense to build the tables... + struct KI + { + string k; + ubyte i; + } + struct VI + { + E v; + ubyte i; + } + + alias iota = Iota!(enum_members.length); + enum enum_members = __traits(allMembers, E); + enum by_key = (){ KI[num_items] r = [ STATIC_MAP!(MakeKI, iota) ]; r.qsort!((ref a, ref b) => uni_compare(a.k, b.k)); return r; }(); + enum by_value = (){ VI[num_items] r = [ STATIC_MAP!(MakeVI, iota) ]; r.qsort!((ref a, ref b) => compare(a.v, b.v)); return r; }(); + enum inv_key = (){ KI[num_items] bk = by_key; ubyte[num_items] r; foreach (ubyte i, ref ki; bk) r[ki.i] = i; return r; }(); + enum inv_val = (){ VI[num_items] bv = by_value; ubyte[num_items] r; foreach (ubyte i, ref vi; bv) r[vi.i] = i; return r; }(); + + // calculate the total size of the string buffer + enum total_strings = () { + size_t total = 0; + static foreach (k; enum_members) + total += 2 + k.length + (k.length & 1); + return total; + }(); + + enum MakeKI(ushort i) = KI(trim_key!(enum_members[i]), i); + enum MakeVI(ushort i) = VI(__traits(getMember, E, enum_members[i]), i); + enum GetValue(size_t i) = by_value[i].v; + enum GetKeyRedirect(size_t i) = inv_val[by_key[i].i]; + enum GetValRedirect(size_t i) = inv_key[by_value[i].i]; + enum GetKeyOrig(size_t i) = inv_key[i]; +} + +VoidEnumInfo* make_enum_info(T)(const(char)[] name, const(char)[][] keys, T[] values) +{ + import urt.algorithm; + import urt.hash : fnv1a; + import urt.mem.allocator; + import urt.string; + import urt.string.uni; + import urt.util; + + assert(keys.length == values.length, "keys and values must have the same length"); + assert(keys.length <= ubyte.max, "Too many enum items!"); + + size_t count = keys.length; + + struct VI(T) + { + T v; + ubyte i; + } + + // first we'll sort the keys and values for binary searching + // we need to associate their original indices for the lookup tables + auto ksort = tempAllocator().allocArray!(VI!(const(char)[]))(count); + auto vsort = tempAllocator().allocArray!(VI!T)(count); + foreach (i; 0 .. count) + { + ksort[i] = VI!(const(char)[])(keys[i], cast(ubyte)i); + vsort[i] = VI!T(values[i], cast(ubyte)i); + } + ksort.qsort!((ref a, ref b) => uni_compare(a.v, b.v)); + vsort.qsort!((ref a, ref b) => compare(a.v, b.v)); + + // build the reverse lookup tables + ubyte[] inv_k = tempAllocator().allocArray!ubyte(count); + ubyte[] inv_v = tempAllocator().allocArray!ubyte(count); + foreach (i, ref ki; ksort) + inv_k[ki.i] = cast(ubyte)i; + foreach (i, ref vi; vsort) + inv_v[vi.i] = cast(ubyte)i; + + // count the string memory + size_t total_string; + foreach (i; 0 .. count) + total_string += 2 + keys[i].length + (keys[i].length & 1); + + // calculate the total size + size_t total_size = VoidEnumInfo.sizeof + T.sizeof*count; + total_size += (total_size & 1) + ushort.sizeof*count + count*3; + total_size += (total_size & 1) + total_string; + + // allocate a buffer and assign all the sub-buffers + void[] info = defaultAllocator().alloc(total_size); + VoidEnumInfo* result = cast(VoidEnumInfo*)info.ptr; + T* value_ptr = cast(T*)&result[1]; + char* str_data = cast(char*)&value_ptr[count]; + if (cast(size_t)str_data & 1) + *str_data++ = 0; // align to 2 bytes + ushort* key_ptr = cast(ushort*)str_data; + ubyte* lookup = cast(ubyte*)&key_ptr[count]; + str_data = cast(char*)&lookup[count*3]; + if (cast(size_t)str_data & 1) + *str_data++ = 0; // align to 2 bytes + char* str_ptr = str_data + 2; + + // populate the enum info data + foreach (i; 0 .. count) + { + value_ptr[i] = vsort[i].v; + + // write the string data and store the key offset + const(char)[] key = ksort[i].v; + key_ptr[i] = cast(ushort)(str_ptr - str_data); + writeString(str_ptr, key); + if (key.length & 1) + (str_ptr++)[key.length] = 0; // align to 2 bytes + str_ptr += 2 + key.length; + + lookup[i] = inv_v[ksort[i].i]; + lookup[count + i] = inv_k[vsort[i].i]; + lookup[count*2 + i] = inv_k[i]; + } + + // build and return the object + return new(*result) VoidEnumInfo(cast(ubyte)keys.length, cast(ushort)T.sizeof, fnv1a(cast(ubyte[])name), value_ptr, key_ptr, str_data, lookup, cast(GetFun)&get_value!T); +} + + +private: + +alias GetFun = Variant function(const(void)*, const(VoidEnumInfo)*) pure; + +Variant get_value(T)(const(void)* ptr, const(VoidEnumInfo)* info) + => Variant(*cast(T*)ptr, info); + +import urt.string : trim; +enum trim_key(string key) = key.trim!(c => c == '_'); + +ushort key_length(const(char)* key) pure +{ + if (__ctfe) + { + version (LittleEndian) + return key[-2] | cast(ushort)(key[-1] << 8); + else + return key[-1] | cast(ushort)(key[-2] << 8); + } + else + return *cast(ushort*)(key - 2); +} + +int key_compare(ushort a, const(char)[] b, const(char)* strings) pure +{ + import urt.string.uni : uni_compare; + const(char)* s = strings + a; + return uni_compare(s[0 .. s.key_length], b); +} diff --git a/src/urt/meta/nullable.d b/src/urt/meta/nullable.d index 3d981cc..98f29fd 100644 --- a/src/urt/meta/nullable.d +++ b/src/urt/meta/nullable.d @@ -9,8 +9,8 @@ template Nullable(T) { struct Nullable { - enum T NullValue = null; - T value = NullValue; + enum T null_value = null; + T value = null_value; this(T v) { @@ -18,7 +18,7 @@ template Nullable(T) } bool opCast(T : bool)() const - => value !is NullValue; + => value !is null_value; bool opEquals(typeof(null)) const => value is null; @@ -42,16 +42,16 @@ template Nullable(T) } template Nullable(T) - if (isBoolean!T) + if (is_boolean!T) { struct Nullable { - enum ubyte NullValue = 0xFF; - private ubyte _value = NullValue; + enum ubyte null_value = 0xFF; + private ubyte _value = null_value; this(typeof(null)) { - _value = NullValue; + _value = null_value; } this(T v) { @@ -62,27 +62,27 @@ template Nullable(T) => _value == 1; bool opCast(T : bool)() const - => _value != NullValue; + => _value != null_value; bool opEquals(typeof(null)) const - => _value == NullValue; + => _value == null_value; bool opEquals(T v) const => _value == cast(ubyte)v; void opAssign(typeof(null)) { - _value = NullValue; + _value = null_value; } void opAssign(U)(U v) if (is(U : T)) { - assert(v != NullValue); + assert(v != null_value); _value = cast(ubyte)v; } ptrdiff_t toString(char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) const nothrow @nogc { - if (value == NullValue) + if (value == null_value) return formatValue(null, buffer, format, formatArgs); else return formatValue(value, buffer, format, formatArgs); @@ -91,16 +91,16 @@ template Nullable(T) } template Nullable(T) - if (isSomeInt!T) + if (is_some_int!T) { struct Nullable { - enum T NullValue = isSignedInt!T ? T.min : T.max; - T value = NullValue; + enum T null_value = is_signed_int!T ? T.min : T.max; + T value = null_value; this(typeof(null)) { - value = NullValue; + value = null_value; } this(T v) { @@ -108,27 +108,27 @@ template Nullable(T) } bool opCast(T : bool)() const - => value != NullValue; + => value != null_value; bool opEquals(typeof(null)) const - => value == NullValue; + => value == null_value; bool opEquals(T v) const - => value != NullValue && value == v; + => value != null_value && value == v; void opAssign(typeof(null)) { - value = NullValue; + value = null_value; } void opAssign(U)(U v) if (is(U : T)) { - assert(v != NullValue); + assert(v != null_value); value = v; } ptrdiff_t toString(char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) const nothrow @nogc { - if (value == NullValue) + if (value == null_value) return formatValue(null, buffer, format, formatArgs); else return formatValue(value, buffer, format, formatArgs); @@ -137,16 +137,16 @@ template Nullable(T) } template Nullable(T) - if (isSomeFloat!T) + if (is_some_float!T) { struct Nullable { - enum T NullValue = T.nan; - T value = NullValue; + enum T null_value = T.nan; + T value = null_value; this(typeof(null)) { - value = NullValue; + value = null_value; } this(T v) { @@ -154,16 +154,16 @@ template Nullable(T) } bool opCast(T : bool)() const - => value !is NullValue; + => value !is null_value; bool opEquals(typeof(null)) const - => value is NullValue; + => value is null_value; bool opEquals(T v) const => value == v; // because nan doesn't compare with anything void opAssign(typeof(null)) { - value = NullValue; + value = null_value; } void opAssign(U)(U v) if (is(U : T)) @@ -173,7 +173,7 @@ template Nullable(T) ptrdiff_t toString(char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) const nothrow @nogc { - if (value is NullValue) + if (value is null_value) return formatValue(null, buffer, format, formatArgs); else return formatValue(value, buffer, format, formatArgs); @@ -189,42 +189,42 @@ template Nullable(T) struct Nullable { T value = void; - bool isValue = false; + bool is_value = false; this(typeof(null)) { - isValue = false; + is_value = false; } this(T v) { moveEmplace(v, value); - isValue = true; + is_value = true; } ~this() { - if (isValue) + if (is_value) value.destroy(); } bool opCast(T : bool)() const - => isValue; + => is_value; bool opEquals(typeof(null)) const - => !isValue; + => !is_value; bool opEquals(T v) const - => isValue && value == v; + => is_value && value == v; void opAssign(typeof(null)) { - if (isValue) + if (is_value) value.destroy(); - isValue = false; + is_value = false; } void opAssign(U)(U v) if (is(U : T)) { - if (!isValue) + if (!is_value) moveEmplace(v, value); else value = v; @@ -232,7 +232,7 @@ template Nullable(T) ptrdiff_t toString(char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) const nothrow @nogc { - if (!isValue) + if (!is_value) return formatValue(null, buffer, format, formatArgs); else return formatValue(value, buffer, format, formatArgs); @@ -246,39 +246,39 @@ template Nullable(T) struct Nullable { T value; - bool isValue; + bool is_value; this(typeof(null)) { - isValue = false; + is_value = false; } this(T v) { value = v; - isValue = true; + is_value = true; } bool opCast(T : bool)() const - => isValue; + => is_value; bool opEquals(typeof(null)) const - => !isValue; + => !is_value; bool opEquals(T v) const - => isValue && value == v; + => is_value && value == v; void opAssign(typeof(null)) { - isValue = false; + is_value = false; } void opAssign(T v) { value = v; - isValue = true; + is_value = true; } ptrdiff_t toString(char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) const nothrow @nogc { - if (!isValue) + if (!is_value) return formatValue(null, buffer, format, formatArgs); else return formatValue(value, buffer, format, formatArgs); diff --git a/src/urt/meta/package.d b/src/urt/meta/package.d index faa2941..62bf1a2 100644 --- a/src/urt/meta/package.d +++ b/src/urt/meta/package.d @@ -1,90 +1,160 @@ module urt.meta; +import urt.traits : is_callable, is_enum, EnumType, Unqual; + +nothrow @nogc: alias Alias(alias a) = a; alias Alias(T) = T; alias AliasSeq(TList...) = TList; -template intForWidth(size_t width, bool signed = false) +template Iota(ptrdiff_t start, ptrdiff_t end) +{ + static assert(start <= end, "start must be less than or equal to end"); + alias Iota = AliasSeq!(); + static foreach (i; start .. end) + Iota = AliasSeq!(Iota, i); +} +alias Iota(size_t end) = Iota!(0, end); + +auto make_delegate(Fun)(Fun fun) pure + if (is_callable!Fun) +{ + import urt.traits : is_function_pointer, ReturnType, Parameters; + + static if (is_function_pointer!fun) + { + struct Hack + { + static if (is(Fun : R function(Args) pure nothrow @nogc, R, Args...)) + ReturnType!Fun call(Parameters!Fun args) pure nothrow @nogc => (cast(ReturnType!Fun function(Parameters!Fun args) pure nothrow @nogc)&this)(args); + else static if (is(Fun : R function(Args) nothrow @nogc, R, Args...)) + ReturnType!Fun call(Parameters!Fun args) nothrow @nogc => (cast(ReturnType!Fun function(Parameters!Fun args) nothrow @nogc)&this)(args); + else static if (is(Fun : R function(Args) pure @nogc, R, Args...)) + ReturnType!Fun call(Parameters!Fun args) pure @nogc => (cast(ReturnType!Fun function(Parameters!Fun args) pure @nogc)&this)(args); + else static if (is(Fun : R function(Args) pure nothrow, R, Args...)) + ReturnType!Fun call(Parameters!Fun args) pure nothrow => (cast(ReturnType!Fun function(Parameters!Fun args) pure nothrow)&this)(args); + else static if (is(Fun : R function(Args) pure, R, Args...)) + ReturnType!Fun call(Parameters!Fun args) pure => (cast(ReturnType!Fun function(Parameters!Fun args) pure)&this)(args); + else static if (is(Fun : R function(Args) nothrow, R, Args...)) + ReturnType!Fun call(Parameters!Fun args) nothrow => (cast(ReturnType!Fun function(Parameters!Fun args) nothrow)&this)(args); + else static if (is(Fun : R function(Args) @nogc, R, Args...)) + ReturnType!Fun call(Parameters!Fun args) @nogc => (cast(ReturnType!Fun function(Parameters!Fun args) @nogc)&this)(args); + else static if (is(Fun : R function(Args), R, Args...)) + ReturnType!Fun call(Parameters!Fun args) => (cast(ReturnType!Fun function(Parameters!Fun args))&this)(args); + } + Hack hack; + auto dg = &hack.call; + dg.ptr = fun; + return dg; + } + else static if (is(Fun == delegate)) + return fun; + else + static assert(false, "Unsupported type for make_delegate"); +} + +ulong bit_mask(size_t bits) pure +{ + return (1UL << bits) - 1; +} + +template bit_mask(size_t bits, bool signed = false) { - static if (width <= 8 && !signed) - alias intForWidth = ubyte; - else static if (width <= 8 && signed) - alias intForWidth = byte; - else static if (width <= 16 && !signed) - alias intForWidth = ushort; - else static if (width <= 16 && signed) - alias intForWidth = short; - else static if (width <= 32 && !signed) - alias intForWidth = uint; - else static if (width <= 32 && signed) - alias intForWidth = int; - else static if (width <= 64 && !signed) - alias intForWidth = ulong; - else static if (width <= 64 && signed) - alias intForWidth = long; + static assert(bits <= 64, "bit_mask only supports up to 64 bits"); + static if (bits == 64) + enum IntForWidth!(64, signed) bit_mask = ~0UL; + else + enum IntForWidth!(bits, signed) bit_mask = (1UL << bits) - 1; } -template staticMap(alias fun, args...) +template IntForWidth(size_t bits, bool signed = false) { - alias staticMap = AliasSeq!(); + static if (bits <= 8 && !signed) + alias IntForWidth = ubyte; + else static if (bits <= 8 && signed) + alias IntForWidth = byte; + else static if (bits <= 16 && !signed) + alias IntForWidth = ushort; + else static if (bits <= 16 && signed) + alias IntForWidth = short; + else static if (bits <= 32 && !signed) + alias IntForWidth = uint; + else static if (bits <= 32 && signed) + alias IntForWidth = int; + else static if (bits <= 64 && !signed) + alias IntForWidth = ulong; + else static if (bits <= 64 && signed) + alias IntForWidth = long; +} + +alias TypeForOp(string op, U) = typeof(mixin(op ~ "U()")); +alias TypeForOp(string op, A, B) = typeof(mixin("A()" ~ op ~ "B()")); + +template STATIC_MAP(alias fun, args...) +{ + alias STATIC_MAP = AliasSeq!(); static foreach (arg; args) - staticMap = AliasSeq!(staticMap, fun!arg); + STATIC_MAP = AliasSeq!(STATIC_MAP, fun!arg); +} + +template STATIC_UNROLL(alias array) +{ + static if (is(typeof(array) : T[], T)) + { + alias STATIC_UNROLL = AliasSeq!(); + static foreach (i; 0 .. array.length) + STATIC_UNROLL = AliasSeq!(STATIC_UNROLL, array[i]); + } + else + static assert(false, "STATIC_UNROLL requires an array"); } -template staticIndexOf(args...) +template STATIC_FILTER(alias filter, args...) +{ + alias STATIC_FILTER = AliasSeq!(); + static foreach (arg; args) + static if (filter!arg) + STATIC_FILTER = AliasSeq!(STATIC_FILTER, arg); +} + +template static_index_of(args...) if (args.length >= 1) { - enum staticIndexOf = { + enum static_index_of = { static foreach (idx, arg; args[1 .. $]) - static if (isSame!(args[0], arg)) + static if (is_same!(args[0], arg)) // `if (__ctfe)` is redundant here but avoids the "Unreachable code" warning. if (__ctfe) return idx; return -1; }(); } -template InterleaveSeparator(alias sep, Args...) +template INTERLEAVE_SEPARATOR(alias sep, Args...) { - alias InterleaveSeparator = AliasSeq!(); + alias INTERLEAVE_SEPARATOR = AliasSeq!(); static foreach (i, A; Args) static if (i > 0) - InterleaveSeparator = AliasSeq!(InterleaveSeparator, sep, A); + INTERLEAVE_SEPARATOR = AliasSeq!(INTERLEAVE_SEPARATOR, sep, A); else - InterleaveSeparator = AliasSeq!(A); + INTERLEAVE_SEPARATOR = AliasSeq!(A); } -template EnumKeys(E) -{ - static assert(is(E == enum), "EnumKeys only works with enums!"); - __gshared immutable string[EnumStrings.length] EnumKeys = [ EnumStrings ]; - private alias EnumStrings = __traits(allMembers, E); -} - -E enumFromString(E)(const(char)[] key) -if (is(E == enum)) -{ - foreach (i, k; EnumKeys!E) - if (key[] == k[]) - return cast(E)i; - return cast(E)-1; -} - private: -template isSame(alias a, alias b) +template is_same(alias a, alias b) { static if (!is(typeof(&a && &b)) // at least one is an rvalue - && __traits(compiles, { enum isSame = a == b; })) // c-t comparable - enum isSame = a == b; + && __traits(compiles, { enum is_same = a == b; })) // c-t comparable + enum is_same = a == b; else - enum isSame = __traits(isSame, a, b); + enum is_same = __traits(isSame, a, b); } // TODO: remove after https://github.com/dlang/dmd/pull/11320 and https://issues.dlang.org/show_bug.cgi?id=21889 are fixed -template isSame(A, B) +template is_same(A, B) { - enum isSame = is(A == B); + enum is_same = is(A == B); } diff --git a/src/urt/meta/tuple.d b/src/urt/meta/tuple.d index a2fe66f..f29e758 100644 --- a/src/urt/meta/tuple.d +++ b/src/urt/meta/tuple.d @@ -64,20 +64,20 @@ template Tuple(Specs...) // Returns Specs for a subtuple this[from .. to] preserving field // names if any. - alias sliceSpecs(size_t from, size_t to) = staticMap!(expandSpec, fieldSpecs[from .. to]); + alias sliceSpecs(size_t from, size_t to) = STATIC_MAP!(expandSpec, fieldSpecs[from .. to]); struct Tuple { nothrow @nogc: - alias Types = staticMap!(extractType, fieldSpecs); + alias Types = STATIC_MAP!(extractType, fieldSpecs); private alias _Fields = Specs; /** * The names of the `Tuple`'s components. Unnamed fields have empty names. */ - alias fieldNames = staticMap!(extractName, fieldSpecs); + alias fieldNames = STATIC_MAP!(extractName, fieldSpecs); /** * Use `t.expand` for a `Tuple` `t` to expand it into its @@ -369,7 +369,7 @@ template Tuple(Specs...) } import std.range : roundRobin, iota; - alias NewTupleT = Tuple!(staticMap!(GetItem, aliasSeqOf!( + alias NewTupleT = Tuple!(STATIC_MAP!(GetItem, aliasSeqOf!( roundRobin(iota(nT), iota(nT, 2*nT))))); return *(() @trusted => cast(NewTupleT*)&this)(); } @@ -545,7 +545,7 @@ template Tuple(Specs...) } else { - formattedWrite(sink, fmt.nested, staticMap!(sharedToString, this.expand)); + formattedWrite(sink, fmt.nested, STATIC_MAP!(sharedToString, this.expand)); } } else if (fmt.spec == 's') diff --git a/src/urt/package.d b/src/urt/package.d index 354632b..5ac2f72 100644 --- a/src/urt/package.d +++ b/src/urt/package.d @@ -16,20 +16,328 @@ public import urt.processor; public import urt.meta : Alias, AliasSeq; public import urt.util : min, max, swap; +import urt.io; + +version (Windows) +{ + private enum crt = __traits(getTargetInfo, "cppRuntimeLibrary"); + static if (crt) + pragma(lib, crt); + pragma(lib, "kernel32"); +} + private: -pragma(crt_constructor) -void crt_bootup() +// ---------------------------------------------------------------------- +// C entry point - replaces druntime's rt/dmain2.d +// +// We initialize uRT subsystems, scan the PE .minfo section for +// ModuleInfo records, run module constructors, call the D main +// (_Dmain), then run destructors. +// ---------------------------------------------------------------------- + +extern(C) int main(int argc, char** argv) nothrow @nogc @trusted { - import urt.time : initClock; - initClock(); + import urt.mem; - import urt.rand; - initRand(); + import urt.mem.string : init_string_heap, deinit_string_heap; + init_string_heap(ushort.max); + + import urt.time : init_clock; + init_clock(); + + import urt.driver.uart : uart_init, uart_deinit; + uart_init(); - import urt.dbg : setupAssertHandler; - setupAssertHandler(); + import urt.rand; + init_rand(); import urt.string.string : initStringAllocators; initStringAllocators(); + + string* args = cast(string*)alloca(string.sizeof * argc); + string[] d_args = args[0 .. argc]; + foreach (i; 0 .. argc) + d_args[i] = cast(string)argv[i][0 .. argv[i].strlen]; + + auto modules = get_module_infos(); + run_module_ctors(modules); + + version (unittest) + { + import urt.internal.stdc.stdlib : exit; + + size_t executed, passed; + foreach (m; modules) + { + if (m is null) continue; + if (auto fp = cast(void function() nothrow @nogc) m.unitTest) + { + write_err(" running: ", m.name, " ... "); + flush!(WriteTarget.stderr)(); + ++executed; + if (run_test(fp)) + ++passed; + else + writeln_err("FAIL"); + } + } + + if (executed > 0) + writeln_err(passed, '/', executed, " modules passed unittests", ); + else + writeln_err("No unittest functions found!"); + + flush!(WriteTarget.stderr)(); + run_module_dtors(modules); + int result = executed > 0 && passed == executed ? 0 : 1; + + version (FreeStanding) + { + import urt.internal.stdc.stdlib : abort; + writeln_err("Process restarting..."); + abort(); + } + } + else + { + int result = call_dmain(d_args); + + flush!(WriteTarget.stdout)(); + } + + run_module_dtors(modules); + + uart_deinit(); + + deinit_string_heap(); + + return result; +} + +version (unittest) +{ + // separated from main() because DMD cannot mix alloca() and exception handling + bool run_test(void function() nothrow @nogc test) nothrow @nogc @trusted + { + try + { + test(); + writeln_err("ok"); + return true; + } + catch (Throwable t) + { + writeln_err(t.msg); + return false; + } + } +} +else +{ + extern(C) int _Dmain(scope string[] args) @nogc; + + int call_dmain(scope string[] args) nothrow @nogc @trusted + { + int result; + try + result = _Dmain(args); + catch (Throwable t) + { + writeln_err("Uncaught exception: ", t.msg); + result = 1; + } + return result; + } +} + +// ---------------------------------------------------------------------- +// Module constructor/destructor execution +// ---------------------------------------------------------------------- + +alias Fn = void function() nothrow @nogc; + +void run_module_ctors(immutable(ModuleInfo*)[] modules) nothrow @nogc @trusted +{ + // order-independent constructors first + foreach (m; modules) + { + if (m is null) + continue; + if (auto fp = cast(Fn) m.ictor) + fp(); + } + + // then regular constructors + foreach (m; modules) + { + if (m is null) + continue; + if (auto fp = cast(Fn) m.ctor) + fp(); + } + + // TLS constructors + foreach (m; modules) + { + if (m is null) + continue; + if (auto fp = cast(Fn) m.tlsctor) + fp(); + } +} + +void run_module_dtors(immutable(ModuleInfo*)[] modules) nothrow @nogc @trusted +{ + // TLS destructors + foreach_reverse (m; modules) + { + if (m is null) + continue; + if (auto fp = cast(Fn) m.tlsdtor) + fp(); + } + + // regular destructors + foreach_reverse (m; modules) + { + if (m is null) + continue; + if (auto fp = cast(Fn) m.dtor) + fp(); + } +} + +immutable(ModuleInfo*)[] get_module_infos() nothrow @nogc @trusted +{ + version (Windows) + { + auto section = find_pe_section(cast(void*)&__ImageBase, ".minfo"); + if (!section.length) + return null; + return (cast(immutable(ModuleInfo*)*)section.ptr)[0 .. section.length / (void*).sizeof]; + } + else version (linux) + { + // DMD path: _d_dso_registry stashed the .minfo section boundaries + if (_elf_minfo_beg !is null) + return _elf_minfo_beg[0 .. _elf_minfo_end - _elf_minfo_beg]; + + // LDC path: read __minfo section via linker-generated symbols + version (LDC) + { + if (&__start___minfo !is null && &__stop___minfo !is null) + return (&__start___minfo)[0 .. &__stop___minfo - &__start___minfo]; + } + + return null; + } + else + { + // Freestanding/bare-metal: walk _Dmodule_ref linked list. + // Populated by .init_array at startup. + if (_Dmodule_ref is null) + return null; + + size_t count = 0; + for (auto p = _Dmodule_ref; p !is null; p = p.next) + ++count; + + import urt.mem.allocator : Mallocator; + auto arr = Mallocator.instance.allocArray!(void*)(count); + auto p = _Dmodule_ref; + foreach (i; 0 .. count) { arr[i] = cast(void*)p.mod; p = p.next; } + return cast(immutable(ModuleInfo*)[])arr; + } +} + +// ---------------------------------------------------------------------- +// PE .minfo section scanning - finds compiler-generated ModuleInfo pointers. +// Inline PE parsing to avoid core.sys.windows struct __init dependencies. +// ---------------------------------------------------------------------- + +version (Windows) +{ + extern(C) extern __gshared ubyte __ImageBase; + + void[] find_pe_section(void* image_base, string name) nothrow @nogc @trusted + { + if (name.length > 8) return null; + + auto base = cast(ubyte*) image_base; + + // DOS header: e_magic at offset 0 (2 bytes), e_lfanew at offset 0x3C (4 bytes) + if (base[0] != 0x4D || base[1] != 0x5A) // 'MZ' + return null; + + auto lfanew = *cast(int*)(base + 0x3C); + auto pe = base + lfanew; + + // PE signature check + if (pe[0] != 'P' || pe[1] != 'E' || pe[2] != 0 || pe[3] != 0) + return null; + + // COFF file header starts at pe+4 + // NumberOfSections at offset 2 (2 bytes) + // SizeOfOptionalHeader at offset 16 (2 bytes) + auto file_header = pe + 4; + ushort num_sections = *cast(ushort*)(file_header + 2); + ushort opt_header_size = *cast(ushort*)(file_header + 16); + + // Section headers start after optional header + auto sections = file_header + 20 + opt_header_size; + + // Each IMAGE_SECTION_HEADER is 40 bytes: + // Name[8] at offset 0 + // VirtualSize at offset 8 + // VirtualAddress at offset 12 + foreach (i; 0 .. num_sections) + { + auto sec = sections + i * 40; + auto sec_name = (cast(char*) sec)[0 .. 8]; + + bool match = true; + foreach (j; 0 .. name.length) + { + if (sec_name[j] != name[j]) + { + match = false; + break; + } + } + if (match && (name.length == 8 || sec_name[name.length] == 0)) + { + auto virtual_size = *cast(uint*)(sec + 8); + auto virtual_address = *cast(uint*)(sec + 12); + return (base + virtual_address)[0 .. virtual_size]; + } + } + return null; + } +} +else version (linux) +{ + // Stashed by _d_dso_registry in object.d from ELF .init_array callback (DMD) + extern(C) extern __gshared immutable(ModuleInfo*)* _elf_minfo_beg; + extern(C) extern __gshared immutable(ModuleInfo*)* _elf_minfo_end; + + version (LDC) + { + // LDC emits ModuleInfo pointers into the __minfo ELF section but does + // not generate .init_array calls to _d_dso_registry. The linker + // generates __start___minfo / __stop___minfo boundary symbols for us. + extern(C) extern __gshared immutable(ModuleInfo*) __start___minfo; + extern(C) extern __gshared immutable(ModuleInfo*) __stop___minfo; + } +} +else +{ + // Freestanding/bare-metal: LDC chains ModuleReference structs into + // this linked list via .init_array at startup. + struct ModuleReference + { + ModuleReference* next; + immutable(ModuleInfo)* mod; + } + extern(C) extern __gshared ModuleReference* _Dmodule_ref; } diff --git a/src/urt/platform.d b/src/urt/platform.d index 6db5f2c..ca97907 100644 --- a/src/urt/platform.d +++ b/src/urt/platform.d @@ -17,15 +17,31 @@ version (visionOS) version = Darwin; -version (Windows) - enum string Platform = "Windows"; -else version (linux) - enum string Platform = "Linux"; -else version (Darwin) - enum string Platform = "Darwin"; -else version (FreeBSD) - enum string Platform = "FreeBSD"; -else version (FreeStanding) - enum string Platform = "Bare-metal"; -else - static assert(0, "Unsupported platform"); +// Platform identity -- specific chip name where known, generic fallback otherwise + +version (ESP8266) enum string Platform = "ESP8266"; +else version (ESP32) enum string Platform = "ESP32"; +else version (ESP32_S2) enum string Platform = "ESP32-S2"; +else version (ESP32_S3) enum string Platform = "ESP32-S3"; +else version (ESP32_C2) enum string Platform = "ESP32-C2"; +else version (ESP32_C3) enum string Platform = "ESP32-C3"; +else version (ESP32_C5) enum string Platform = "ESP32-C5"; +else version (ESP32_C6) enum string Platform = "ESP32-C6"; +else version (ESP32_H2) enum string Platform = "ESP32-H2"; +else version (ESP32_P4) enum string Platform = "ESP32-P4"; +else version (BL808_M0) enum string Platform = "BL808-M0"; +else version (BL808) enum string Platform = "BL808"; +else version (BL618) enum string Platform = "BL618"; +else version (BK7231N) enum string Platform = "BK7231N"; +else version (BK7231T) enum string Platform = "BK7231T"; +else version (RP2350) enum string Platform = "RP2350"; +else version (STM32F4) enum string Platform = "STM32F4"; +else version (STM32F7) enum string Platform = "STM32F7"; +else version (Windows) enum string Platform = "Windows"; +else version (linux) enum string Platform = "Linux"; +else version (Darwin) enum string Platform = "macOS"; +else version (FreeBSD) enum string Platform = "FreeBSD"; +else version (FreeRTOS) enum string Platform = "FreeRTOS"; +else version (BareMetal) enum string Platform = "bare-metal"; +else version (FreeStanding) enum string Platform = "bare-metal"; +else enum string Platform = "unknown"; diff --git a/src/urt/processor.d b/src/urt/processor.d index 4acc356..0f7ba27 100644 --- a/src/urt/processor.d +++ b/src/urt/processor.d @@ -1,22 +1,45 @@ module urt.processor; +enum Endian : byte +{ + Native = -1, // specifies the native/working endian + Little = 0, + Big = 1 +} + version (LittleEndian) +{ enum LittleEndian = true; + enum BigEndian = false; + enum Endian proc_endian = Endian.Little; +} else +{ enum LittleEndian = false; + enum BigEndian = true; + enum Endian proc_endian = Endian.Big; +} version (X86_64) { version = Intel; enum string ProcessorFamily = "x86_64"; + enum string ProcessorName = "x86_64"; } else version (X86) { version = Intel; enum string ProcessorFamily = "x86"; + enum string ProcessorName = "x86"; } else version (AArch64) +{ enum string ProcessorFamily = "ARM64"; + version (LDC) + enum string ProcessorName = __traits(targetCPU); + else + enum string ProcessorName = "aarch64"; +} else version (ARM) { enum string ProcessorFamily = "ARM"; @@ -63,11 +86,125 @@ else version (ARM) enum ProcFeatures = ProcFeaturesT(); } else version (RISCV64) +{ enum string ProcessorFamily = "RISCV64"; + + // Synthesize ISA string: "RV64I" + single-letter extensions in canonical order + enum string ProcessorName = "RV64I" + ~ (ProcFeatures.m ? "M" : "") + ~ (ProcFeatures.a ? "A" : "") + ~ (ProcFeatures.f ? "F" : "") + ~ (ProcFeatures.d ? "D" : "") + ~ (ProcFeatures.c ? "C" : "") + ~ (ProcFeatures.v ? "V" : "") + ~ (ProcFeatures.h ? "H" : "") + ~ (ProcFeatures.xtheadba ? " (T-Head)" : ""); + + struct ProcFeaturesT + { + // Standard extensions + bool a = __traits(targetHasFeature, "a"); // Atomic instructions + bool c = __traits(targetHasFeature, "c"); // Compressed instructions + bool d = __traits(targetHasFeature, "d"); // Double-precision float + bool f = __traits(targetHasFeature, "f"); // Single-precision float + bool h = __traits(targetHasFeature, "h"); // Hypervisor + bool m = __traits(targetHasFeature, "m"); // Integer multiply/divide + bool v = __traits(targetHasFeature, "v"); // Vector extension (RVV 1.0) + // Bit manipulation + bool zba = __traits(targetHasFeature, "zba"); // Address generation + bool zbb = __traits(targetHasFeature, "zbb"); // Basic bit manipulation + bool zbs = __traits(targetHasFeature, "zbs"); // Single-bit instructions + // System + bool zicsr = __traits(targetHasFeature, "zicsr"); // CSR instructions + bool zifencei = __traits(targetHasFeature, "zifencei"); // Instruction-fetch fence + // T-Head vendor extensions (BL808 C906, etc.) + bool xtheadba = __traits(targetHasFeature, "xtheadba"); // Address calculation + bool xtheadbb = __traits(targetHasFeature, "xtheadbb"); // Basic bit manipulation + bool xtheadbs = __traits(targetHasFeature, "xtheadbs"); // Single-bit instructions + bool xtheadcmo = __traits(targetHasFeature, "xtheadcmo"); // Cache management + bool xtheadcondmov = __traits(targetHasFeature, "xtheadcondmov"); // Conditional move + bool xtheadmac = __traits(targetHasFeature, "xtheadmac"); // Multiply-accumulate + bool xtheadmemidx = __traits(targetHasFeature, "xtheadmemidx"); // Indexed memory ops + bool xtheadmempair = __traits(targetHasFeature, "xtheadmempair"); // Paired memory ops + bool xtheadsync = __traits(targetHasFeature, "xtheadsync"); // Multicore sync + bool xtheadvdot = __traits(targetHasFeature, "xtheadvdot"); // Vector dot product + } + enum ProcFeatures = ProcFeaturesT(); +} else version (RISCV32) +{ enum string ProcessorFamily = "RISCV"; + + // Synthesize ISA string: "RV32I" or "RV32E" + extensions + enum string ProcessorName = "RV32" + ~ (ProcFeatures.e ? 'E' : 'I') + ~ (ProcFeatures.m ? "M" : "") + ~ (ProcFeatures.a ? "A" : "") + ~ (ProcFeatures.f ? "F" : "") + ~ (ProcFeatures.d ? "D" : "") + ~ (ProcFeatures.c ? "C" : "") + ~ (ProcFeatures.v ? "V" : ""); + + struct ProcFeaturesT + { + // Standard extensions + bool e = __traits(targetHasFeature, "e"); // RV32E: 16 registers only + bool a = __traits(targetHasFeature, "a"); // Atomic instructions + bool c = __traits(targetHasFeature, "c"); // Compressed instructions + bool d = __traits(targetHasFeature, "d"); // Double-precision float + bool f = __traits(targetHasFeature, "f"); // Single-precision float + bool m = __traits(targetHasFeature, "m"); // Integer multiply/divide + bool v = __traits(targetHasFeature, "v"); // Vector extension (RVV 1.0) + // Bit manipulation + bool zba = __traits(targetHasFeature, "zba"); // Address generation + bool zbb = __traits(targetHasFeature, "zbb"); // Basic bit manipulation + bool zbs = __traits(targetHasFeature, "zbs"); // Single-bit instructions + // System + bool zicsr = __traits(targetHasFeature, "zicsr"); // CSR instructions + bool zifencei = __traits(targetHasFeature, "zifencei"); // Instruction-fetch fence + } + enum ProcFeatures = ProcFeaturesT(); +} else version (Xtensa) +{ enum string ProcessorFamily = "Xtensa"; + + // Synthesize name from key features + enum string ProcessorName = "Xtensa" + ~ (ProcFeatures.windowed ? " Windowed" : " Call0") + ~ (ProcFeatures.fp ? (ProcFeatures.dfpaccel ? " DP" : " SP") : "") + ~ (ProcFeatures.mac16 ? " MAC16" : ""); + + struct ProcFeaturesT + { + // Core ISA options + bool density = __traits(targetHasFeature, "density"); // Density (16-bit) instructions + bool loop = __traits(targetHasFeature, "loop"); // Zero-overhead loops + bool windowed = __traits(targetHasFeature, "windowed"); // Windowed registers (vs call0 ABI) + bool boolean_ = __traits(targetHasFeature, "bool"); // Boolean registers + bool sext = __traits(targetHasFeature, "sext"); // Sign extend instruction + bool nsa = __traits(targetHasFeature, "nsa"); // Normalization shift amount + bool clamps = __traits(targetHasFeature, "clamps"); // Clamp signed + bool minmax = __traits(targetHasFeature, "minmax"); // Min/max instructions + // Multiply/divide + bool mul16 = __traits(targetHasFeature, "mul16"); // 16-bit multiply + bool mul32 = __traits(targetHasFeature, "mul32"); // 32-bit multiply + bool mul32high = __traits(targetHasFeature, "mul32high"); // 32-bit multiply high + bool div32 = __traits(targetHasFeature, "div32"); // 32-bit divide + bool mac16 = __traits(targetHasFeature, "mac16"); // 16-bit MAC (ESP32 LX6) + // Floating point + bool fp = __traits(targetHasFeature, "fp"); // Single-precision float + bool dfpaccel = __traits(targetHasFeature, "dfpaccel"); // Double-precision FP acceleration + // System + bool exception_ = __traits(targetHasFeature, "exception"); // Exception handling + bool interrupt = __traits(targetHasFeature, "interrupt"); // Interrupt handling + bool highpriinterrupts = __traits(targetHasFeature, "highpriinterrupts"); // High-priority interrupts + bool debug_ = __traits(targetHasFeature, "debug"); // Debug support + bool threadptr = __traits(targetHasFeature, "threadptr"); // Thread pointer register + bool coprocessor = __traits(targetHasFeature, "coprocessor"); // Coprocessor interface + } + enum ProcFeatures = ProcFeaturesT(); +} else static assert(0, "Unsupported processor"); @@ -81,10 +218,23 @@ else version (ARM) { enum SupportUnalignedLoadStore = !ProcFeatures.strict_align; } +else version (RISCV64) +{ + enum SupportUnalignedLoadStore = __traits(targetHasFeature, "unaligned-scalar-mem"); +} +else version (RISCV32) +{ + enum SupportUnalignedLoadStore = __traits(targetHasFeature, "unaligned-scalar-mem"); +} else { - // TODO: I think MIPS R6 can do native unalogned loads/stores - enum SupportUnalignedLoadStore = false; + // No arch-level feature flag available (Xtensa, MIPS, etc.) + // Platforms that support unaligned access set -d-version=SupportUnaligned in Makefile + // (e.g., ESP32-S3 Xtensa LX7 has hardware unaligned load/store) + version (SupportUnaligned) + enum SupportUnalignedLoadStore = true; + else + enum SupportUnalignedLoadStore = false; } // Different arch may define this differently... diff --git a/src/urt/rand.d b/src/urt/rand.d index b4b0f1e..c54cd25 100644 --- a/src/urt/rand.d +++ b/src/urt/rand.d @@ -55,7 +55,7 @@ private: rng.state = rng.state * PCG_DEFAULT_MULTIPLIER_64 + rng.inc; } - package void initRand() + package void init_rand() { import urt.time; srand(getTime().ticks, cast(size_t)&globalRand); diff --git a/src/urt/range/package.d b/src/urt/range/package.d index 06de7f0..94af160 100644 --- a/src/urt/range/package.d +++ b/src/urt/range/package.d @@ -8,23 +8,23 @@ template map(fun...) { /** Params: - r = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives) + r = an $(REF_ALTTEXT input range, is_input_range, std,range,primitives) Returns: A range with each fun applied to all the elements. If there is more than one fun, the element type will be `Tuple` containing one element for each fun. */ auto map(Range)(Range r) - if (isInputRange!(Unqual!Range)) + if (is_input_range!(Unqual!Range)) { - import urt.meta : AliasSeq, staticMap; + import urt.meta : AliasSeq, STATIC_MAP; alias RE = ElementType!(Range); static if (fun.length > 1) { import std.functional : adjoin; - import urt.meta : staticIndexOf; + import urt.meta : static_index_of; - alias _funs = staticMap!(unaryFun, fun); + alias _funs = STATIC_MAP!(unaryFun, fun); alias _fun = adjoin!_funs; // Once https://issues.dlang.org/show_bug.cgi?id=5710 is fixed @@ -56,7 +56,7 @@ private struct MapResult(alias fun, Range) alias R = Unqual!Range; R _input; - static if (isBidirectionalRange!R) + static if (is_bidirectional_range!R) { @property auto ref back()() { @@ -101,7 +101,7 @@ private struct MapResult(alias fun, Range) return fun(_input.front); } - static if (isRandomAccessRange!R) + static if (is_random_access_range!R) { static if (is(typeof(Range.init[ulong.max]))) private alias opIndex_t = ulong; @@ -147,7 +147,7 @@ private struct MapResult(alias fun, Range) } } - static if (isForwardRange!R) + static if (is_forward_range!R) { @property auto save() { @@ -160,9 +160,9 @@ private struct MapResult(alias fun, Range) template reduce(fun...) if (fun.length >= 1) { - import urt.meta : staticMap; + import urt.meta : STATIC_MAP; - alias binfuns = staticMap!(binaryFun, fun); + alias binfuns = STATIC_MAP!(binaryFun, fun); static if (fun.length > 1) import urt.meta.tuple : tuple, isTuple; @@ -182,24 +182,21 @@ template reduce(fun...) Returns: the final result of the accumulator applied to the iterable - - Throws: `Exception` if `r` is empty +/ auto reduce(R)(R r) if (isIterable!R) { - import std.exception : enforce; - alias E = Select!(isInputRange!R, ElementType!R, ForeachType!R); - alias Args = staticMap!(ReduceSeedType!E, binfuns); + alias E = Select!(is_input_range!R, ElementType!R, ForeachType!R); + alias Args = STATIC_MAP!(ReduceSeedType!E, binfuns); - static if (isInputRange!R) + static if (is_input_range!R) { // no need to throw if range is statically known to be non-empty static if (!__traits(compiles, { static assert(r.length > 0); })) - enforce(!r.empty, "Cannot reduce an empty input range w/o an explicit seed value."); + assert(!r.empty, "Cannot reduce an empty input range w/o an explicit seed value."); Args result = r.front; r.popFront(); @@ -245,7 +242,7 @@ template reduce(fun...) private auto reducePreImpl(R, Args...)(R r, ref Args args) { - alias Result = staticMap!(Unqual, Args); + alias Result = STATIC_MAP!(Unqual, Args); static if (is(Result == Args)) alias result = args; else @@ -259,7 +256,7 @@ template reduce(fun...) import std.algorithm.internal : algoFormat; static assert(Args.length == fun.length, algoFormat("Seed %s does not have the correct amount of fields (should be %s)", Args.stringof, fun.length)); - alias E = Select!(isInputRange!R, ElementType!R, ForeachType!R); + alias E = Select!(is_input_range!R, ElementType!R, ForeachType!R); static if (mustInitialize) bool initialized = false; @@ -279,7 +276,7 @@ template reduce(fun...) static if (mustInitialize) if (initialized == false) { - import core.internal.lifetime : emplaceRef; + import urt.lifetime : emplaceRef; foreach (i, f; binfuns) emplaceRef!(Args[i])(args[i], e); initialized = true; @@ -309,7 +306,7 @@ template fold(fun...) { /** Params: - r = the $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to fold + r = the $(REF_ALTTEXT input range, is_input_range, std,range,primitives) to fold seeds = the initial values of each accumulator (optional), one for each predicate Returns: Either the accumulated result for a single predicate, or a @@ -323,7 +320,7 @@ template fold(fun...) } else { - import std.typecons : tuple; + import urt.meta : tuple; return reduce!fun(tuple(seeds), r); } } diff --git a/src/urt/range/primitives.d b/src/urt/range/primitives.d index b9789cd..f5ddec8 100644 --- a/src/urt/range/primitives.d +++ b/src/urt/range/primitives.d @@ -3,44 +3,44 @@ module urt.range.primitives; import urt.traits; -enum bool isInputRange(R) = +enum bool is_input_range(R) = is(typeof(R.init) == R) && is(typeof((R r) { return r.empty; } (R.init)) == bool) && (is(typeof((return ref R r) => r.front)) || is(typeof(ref (return ref R r) => r.front))) && !is(typeof((R r) { return r.front; } (R.init)) == void) && is(typeof((R r) => r.popFront)); -enum bool isInputRange(R, E) = - .isInputRange!R && isQualifierConvertible!(ElementType!R, E); +enum bool is_input_range(R, E) = + .is_input_range!R && isQualifierConvertible!(ElementType!R, E); -enum bool isForwardRange(R) = isInputRange!R +enum bool is_forward_range(R) = is_input_range!R && is(typeof((R r) { return r.save; } (R.init)) == R); -enum bool isForwardRange(R, E) = - .isForwardRange!R && isQualifierConvertible!(ElementType!R, E); +enum bool is_forward_range(R, E) = + .is_forward_range!R && isQualifierConvertible!(ElementType!R, E); -enum bool isBidirectionalRange(R) = isForwardRange!R +enum bool is_bidirectional_range(R) = is_forward_range!R && is(typeof((R r) => r.popBack)) && (is(typeof((return ref R r) => r.back)) || is(typeof(ref (return ref R r) => r.back))) && is(typeof(R.init.back.init) == ElementType!R); -enum bool isBidirectionalRange(R, E) = - .isBidirectionalRange!R && isQualifierConvertible!(ElementType!R, E); +enum bool is_bidirectional_range(R, E) = + .is_bidirectional_range!R && isQualifierConvertible!(ElementType!R, E); -enum bool isRandomAccessRange(R) = - is(typeof(lvalueOf!R[1]) == ElementType!R) +enum bool is_random_access_range(R) = + is(typeof(lvalue_of!R[1]) == ElementType!R) && !(isAutodecodableString!R && !isAggregateType!R) - && isForwardRange!R - && (isBidirectionalRange!R || isInfinite!R) + && is_forward_range!R + && (is_bidirectional_range!R || isInfinite!R) && (hasLength!R || isInfinite!R) - && (isInfinite!R || !is(typeof(lvalueOf!R[$ - 1])) - || is(typeof(lvalueOf!R[$ - 1]) == ElementType!R)); -enum bool isRandomAccessRange(R, E) = - .isRandomAccessRange!R && isQualifierConvertible!(ElementType!R, E); + && (isInfinite!R || !is(typeof(lvalue_of!R[$ - 1])) + || is(typeof(lvalue_of!R[$ - 1]) == ElementType!R)); +enum bool is_random_access_range(R, E) = + .is_random_access_range!R && isQualifierConvertible!(ElementType!R, E); // is this in the wrong place? should this be a general traits for arrays and stuff too? template ElementType(R) { - static if (is(typeof(lvalueOf!R.front))) - alias ElementType = typeof(lvalueOf!R.front); + static if (is(typeof(lvalue_of!R.front))) + alias ElementType = typeof(lvalue_of!R.front); else static if (is(R : T[], T)) alias ElementType = T; else diff --git a/src/urt/result.d b/src/urt/result.d index 564b15c..d39959c 100644 --- a/src/urt/result.d +++ b/src/urt/result.d @@ -3,73 +3,136 @@ module urt.result; nothrow @nogc: -enum InternalCode +struct Result { - Success = 0, - BufferTooSmall, - InvalidParameter, - Unsupported +nothrow @nogc: + enum success = Result(); + + uint system_code = 0; + + bool opCast(T : bool)() const + => system_code == 0; + + bool succeeded() const + => system_code == 0; + bool failed() const + => system_code != 0; } -struct Result +struct SizeResult { nothrow @nogc: - enum Success = Result(); + this(size_t size) + { + debug assert(size <= ptrdiff_t.max, "Size too large to fit in a signed integer!"); + this.size = size; + } + this(Result result) + { + static if (size_t.sizeof == 4) + assert(cast(int)result.system_code >= 0, "Negative result codes not supported on 32-bit machines!"); + this.size = -cast(ptrdiff_t)result.system_code; + } - uint systemCode = 0; + ptrdiff_t size = 0; bool opCast(T : bool)() const - => systemCode == 0; + => size >= 0; bool succeeded() const - => systemCode == 0; + => size >= 0; bool failed() const - => systemCode != 0; + => size < 0; + + Result result() const + => size >= 0 ? Result.success : Result(cast(uint)-size); } +struct StringResult +{ +nothrow @nogc: + enum success = StringResult(); + + const(char)[] message = null; + + bool opCast(T : bool)() const + => message is null; + + bool succeeded() const + => message is null; + bool failed() const + => message !is null; +} + +// TODO: should we have a way to convert Result to StringResult, so we can format error messages? + + +version (Posix) version = Errno; +version (CRuntime_Picolibc) version = Errno; +version (CRuntime_Newlib) version = Errno; version (Windows) { - import core.sys.windows.windows; + import urt.internal.sys.windows; - Result InternalResult(InternalCode code) + enum InternalResult : Result { - switch (code) - { - case InternalCode.Success: - return Result(); - case InternalCode.BufferTooSmall: - return Result(ERROR_INSUFFICIENT_BUFFER); - case InternalCode.InvalidParameter: - return Result(ERROR_INVALID_PARAMETER); - default: - return Result(ERROR_INVALID_FUNCTION); // InternalCode.Unsupported - } + success = Result.success, + failed = Result(ERROR_GEN_FAILURE), + buffer_too_small = Result(ERROR_INSUFFICIENT_BUFFER), + invalid_parameter = Result(ERROR_INVALID_PARAMETER), + data_error = Result(ERROR_INVALID_DATA), + unsupported = Result(ERROR_NOT_SUPPORTED), + out_of_range = Result(ERROR_ARITHMETIC_OVERFLOW), + already_exists = Result(ERROR_ALREADY_EXISTS), + timeout = Result(ERROR_TIMEOUT), + aborted = Result(ERROR_OPERATION_ABORTED), + no_memory = Result(ERROR_NOT_ENOUGH_MEMORY), } - Result Win32Result(uint err) + Result win32_result(uint err) => Result(err); + Result getlasterror_result() + => Result(GetLastError()); } -else version (Posix) +else version (Errno) { - import core.stdc.errno; - Result InternalResult(InternalCode code) + import urt.internal.stdc.errno; + + enum InternalResult : Result { - switch (code) - { - case InternalCode.Success: - return Result(); - case InternalCode.BufferTooSmall: - return Result(ERANGE); - case InternalCode.InvalidParameter: - return Result(EINVAL); - default: - return Result(ENOTSUP); // InternalCode.Unsupported - } + success = Result.success, + failed = Result(EIO), + buffer_too_small = Result(ERANGE), + invalid_parameter = Result(EINVAL), + data_error = Result(EILSEQ), + unsupported = Result(ENOTSUP), + out_of_range = Result(ERANGE), + already_exists = Result(EEXIST), + timeout = Result(ETIMEDOUT), + aborted = Result(EINTR), + no_memory = Result(ENOMEM), } - Result PosixResult(int err) + Result posix_result(int err) => Result(err); - Result ErrnoResult() + Result errno_result() => Result(errno); } +else version (FreeStanding) +{ + enum InternalResult : Result + { + success = Result.success, + failed = Result(1), + buffer_too_small = Result(2), + invalid_parameter = Result(3), + data_error = Result(4), + unsupported = Result(5), + out_of_range = Result(6), + already_exists = Result(7), + timeout = Result(8), + aborted = Result(9), + no_memory = Result(10), + } +} diff --git a/src/urt/si/quantity.d b/src/urt/si/quantity.d index 33462df..dc8eb7e 100644 --- a/src/urt/si/quantity.d +++ b/src/urt/si/quantity.d @@ -1,14 +1,22 @@ module urt.si.quantity; +import urt.meta : TypeForOp; import urt.si.unit; +import urt.traits; nothrow @nogc: -alias VarQuantity = Quantity!(double); +alias VarQuantity = Quantity!double; alias Scalar = Quantity!(double, ScaledUnit()); alias Metres = Quantity!(double, ScaledUnit(Metre)); alias Seconds = Quantity!(double, ScaledUnit(Second)); +alias Volts = Quantity!(double, ScaledUnit(Volt)); +alias Amps = Quantity!(double, ScaledUnit(Ampere)); +alias AmpHours = Quantity!(double, AmpereHour); +alias Watts = Quantity!(double, ScaledUnit(Watt)); +alias Kilowatts = Quantity!(double, Kilowatt); +alias WattHours = Quantity!(double, WattHour); struct Quantity(T, ScaledUnit _unit = ScaledUnit(uint.max)) @@ -20,22 +28,45 @@ nothrow @nogc: enum Dynamic = _unit.pack == uint.max; enum IsCompatible(ScaledUnit U) = _unit.unit == U.unit; - T value; + T value = 0; static if (Dynamic) ScaledUnit unit; else alias unit = _unit; + static if (is_some_float!T) + { + enum nan = This(T.nan); + enum infinity = This(T.infinity); + enum epsilon = This(T.epsilon); + enum max = This(T.max); + enum min_normal = This(T.min_normal); + } + else static if (is_some_int!T) + { + enum min = This(T.min); + enum max = This(T.max); + } + bool isCompatible(U, ScaledUnit _U)(Quantity!(U, _U) compatibleWith) const pure if (is(U : T)) => unit.unit == compatibleWith.unit.unit; - this(T value) pure + static if (Dynamic) { - static if (Dynamic) - this.unit = ScaledUnit(); - this.value = value; + this(T value, ScaledUnit unit = ScaledUnit()) pure + { + this.unit = unit; + this.value = value; + } + } + else + { + this(T value) pure + { + this.value = value; + } } this(U, ScaledUnit _U)(Quantity!(U, _U) b) pure @@ -49,10 +80,21 @@ nothrow @nogc: else { static if (b.Dynamic) - assert(isCompatible(b), "Incompatible unit!"); + { + static if (is_some_float!T) + { + if (!isCompatible(b)) + { + value = T.nan; + return; + } + } + else + assert(isCompatible(b), "Incompatible units!"); + } else - static assert(IsCompatible!_U, "Incompatible unit: ", unit, " and ", b.unit); - value = adjustScale(b); + static assert(IsCompatible!_U, "Incompatible units: ", unit.toString, " and ", b.unit.toString); + value = adjust_scale(b); } } @@ -61,13 +103,14 @@ nothrow @nogc: static if (Dynamic) unit = Scalar; else - static assert(unit == Unit(), "Incompatible unit: ", unit, " and Scalar"); + static assert(unit == Unit(), "Incompatible units: ", unit.toString, " and Scalar"); this.value = value; } void opAssign(U, ScaledUnit _U)(Quantity!(U, _U) b) pure - if (is(U : T)) { + static assert(__traits(compiles, value = b.value), "cannot implicitly convert ScaledUnit of type `", U, "` to `", T, "`"); + static if (Dynamic) { unit = b.unit; @@ -76,37 +119,45 @@ nothrow @nogc: else { static if (b.Dynamic) - assert(isCompatible(b), "Incompatible unit!"); + assert(isCompatible(b), "Incompatible units!"); else - static assert(IsCompatible!_U, "Incompatible unit: ", unit, " and ", b.unit); - value = adjustScale(b); + static assert(IsCompatible!_U, "Incompatible units: ", unit.toString, " and ", b.unit.toString); + value = adjust_scale(b); } } - auto opBinary(string op, U)(U value) const pure - if ((op == "+" || op == "-") && is(U : T)) + auto opUnary(string op)() const pure + if (op == "+" || op == "-") { + alias RT = Quantity!(TypeForOp!(op, T), _unit); static if (Dynamic) - assert(unit == Scalar); + return RT(mixin(op ~ "value"), unit); else - static assert(unit == Unit(), "Incompatible unit: ", unit, " and Scalar"); - return mixin("this.value " ~ op ~ " value"); + return RT(mixin(op ~ "value")); } + auto opBinary(string op, U)(U value) const pure + if ((op == "+" || op == "-") && is(U : T)) + => opBinary!op(Quantity!(U, ScaledUnit())(value)); + auto opBinary(string op, U, ScaledUnit _U)(Quantity!(U, _U) b) const pure if ((op == "+" || op == "-") && is(U : T)) { + // TODO: what unit should be result take? + // for float T, I reckon maybe the MAX exponent? + // for int types... we need to do some special shit to manage overflows! + // HACK: for now, we just scale to the left-hand size... :/ static if (!Dynamic && !b.Dynamic && unit == Unit() && b.unit == Unit()) return mixin("value " ~ op ~ " b.value"); else { static if (Dynamic || b.Dynamic) - assert(isCompatible(b), "Incompatible unit!"); + assert(isCompatible(b), "Incompatible units!"); else - static assert(IsCompatible!_U, "Incompatible unit: ", unit, " and ", b.unit); + static assert(IsCompatible!_U, "Incompatible units: ", unit.toString, " and ", b.unit.toString); - This r; - r.value = mixin("value " ~ op ~ " adjustScale(b)"); + Quantity!(TypeForOp!(op, T, U), _unit) r; + r.value = mixin("value " ~ op ~ " adjust_scale(b)"); static if (Dynamic) r.unit = unit; return r; @@ -120,11 +171,12 @@ nothrow @nogc: return mixin("this.value " ~ op ~ " value"); else { - This r; - r.value = mixin("this.value " ~ op ~ " value"); + alias RT = TypeForOp!(op, T, U); + RT v = mixin("this.value " ~ op ~ " value"); static if (Dynamic) - r.unit = unit; - return r; + return Quantity!RT(v, unit); + else + return Quantity!(RT, unit)(v); } } @@ -135,33 +187,63 @@ nothrow @nogc: return mixin("value " ~ op ~ " b.value"); else { + // TODO: if the unit product is invalid, then we need to decide a target scaling factor... static if (Dynamic || b.Dynamic) - { - Quantity!T r; - r.unit = mixin("unit " ~ op ~ " b.unit"); - } + const u = mixin("unit " ~ op ~ " b.unit"); else - Quantity!(T, mixin("unit " ~ op ~ " b.unit")) r; + enum u = mixin("unit " ~ op ~ " b.unit"); - // TODO: if the unit product is invalid, then we apply the scaling factor... - // ... but which side should we scale to? probably the left I guess... + alias RT = TypeForOp!(op, T, U); + RT v = mixin("value " ~ op ~ " b.value"); - r.value = mixin("value " ~ op ~ " b.value"); - return r; + static if (Dynamic || b.Dynamic) + return Quantity!RT(v, u); + else + return Quantity!(RT, u)(v); } } - void opOpAssign(string op, U)(U value) pure - if (is(U : T)) + void opOpAssign(string op)(T value) pure { + // TODO: in D; ubyte += int is allowed, so we should cast the result to T this = opBinary!op(value); } void opOpAssign(string op, U, ScaledUnit _U)(Quantity!(U, _U) b) pure { + // TODO: in D; ubyte += int is allowed, so we should cast the result to T this = opBinary!op(b); } + bool opCast(T : bool)() const pure + => value != 0; + + // not clear if this should return the raw value, or the normalised value...? +// T opCast(T)() const pure +// if (is_some_float!T || is_some_int!T) +// { +// assert(unit.pack == 0, "Non-scalar unit can't cast to scalar"); +// assert(false, "TODO: should we be applying the scale to this result?"); +// return cast(T)value; +// } + + T opCast(T)() const pure + if (is(T == Quantity!(U, _U), U, ScaledUnit _U)) + { + static if (is(T == Quantity!(U, _U), U, ScaledUnit _U)) + { + T r; + static if (Dynamic || T.Dynamic) + assert(isCompatible(r), "Incompatible units!"); + else + static assert(IsCompatible!_U, "Incompatible units: ", r.unit.toString, " and ", unit.toString); + r.value = cast(U)r.adjust_scale(this); + static if (T.Dynamic) + r.unit = unit; + return r; + } + } + bool opEquals(U)(U value) const pure if (is(U : T)) { @@ -185,14 +267,14 @@ nothrow @nogc: // can't compare mismatch unit types... i think? static if (Dynamic || rh.Dynamic) - assert(isCompatible(rh), "Incompatible unit!"); + assert(isCompatible(rh), "Incompatible units!"); else - static assert(IsCompatible!_U, "Incompatible unit: ", unit, " and ", rh.unit); + static assert(IsCompatible!_U, "Incompatible units: ", unit.toString, " and ", rh.unit.toString); // TODO: meeting in the middle is only better if the signs are opposite // otherwise we should just scale to the left... static if (Dynamic && rh.Dynamic) - { + {{ // if the scale values are both dynamic, it should be more precise if we meet in the middle... auto lScale = unit.scale(); auto lTrans = unit.offset(); @@ -200,9 +282,9 @@ nothrow @nogc: auto rTrans = rh.unit.offset(); lhs = lhs*lScale + lTrans; rhs = rhs*rScale + rTrans; - } + }} else - rhs = adjustScale(rh); + rhs = adjust_scale(rh); compare: static if (epsilon == 0) @@ -222,41 +304,136 @@ nothrow @nogc: } } -private: - T adjustScale(U, ScaledUnit _U)(Quantity!(U, _U) b) const pure + auto normalise() const pure { static if (Dynamic) { - auto lScale = unit.scale!true(); - auto lTrans = unit.offset!true(); + Quantity!T r; + r.unit = ScaledUnit(unit.unit); } else - { - enum lScale = unit.scale!true(); - enum lTrans = unit.offset!true(); - } - static if (b.Dynamic) - { - auto rScale = b.unit.scale(); - auto rTrans = b.unit.offset(); - } + Quantity!(T, ScaledUnit(unit.unit)) r; + r.value = r.adjust_scale(this); + return r; + } + + Quantity!Ty adjust_scale(Ty = T)(ScaledUnit su) const pure + { + Quantity!Ty r; + r.unit = su; + assert(r.isCompatible(this), "Incompatible units!"); + if (su == unit) + r.value = cast(Ty)this.value; else + r.value = r.adjust_scale(this); + return r; + } + + import urt.string.format : FormatArg; + ptrdiff_t toString(char[] buffer, const(char)[], const(FormatArg)[]) const + { + import urt.conv : format_float; + + double v = value; + ScaledUnit u = unit; + + if (u.pack) { - enum rScale = b.unit.scale(); - enum rTrans = b.unit.offset(); + // round upward to the nearest ^3 + if (u.siScale) + { + int x = u.exp; + if (u.unit.pack == 0) + { + if (x == -3) + { + v *= 0.1; + u = ScaledUnit(Unit(), x + 1); + } + else if (x != -2) + { + v *= u.scale(); + u = ScaledUnit(); + } + } + else + { + x = (x + 33) % 3; + if (x != 0) + { + u = ScaledUnit(u.unit, u.exp + (3 - x)); + if (x == 1) + v *= 0.01; + else + v *= 0.1; + } + } + } } - static if (Dynamic || b.Dynamic) + ptrdiff_t l = format_float(v, buffer); + if (l < 0) + return l; + + if (u.pack) { - auto scale = lScale*rScale; - auto trans = lTrans + lScale*rTrans; + ptrdiff_t l2 = u.toString(buffer.ptr ? buffer.ptr[l .. buffer.length] : null, null, null); + if (l2 < 0) + return l2; + l += l2; } + + return l; + } + + ptrdiff_t fromString(const(char)[] s) + { + return -1; + } + +private: + T adjust_scale(U, ScaledUnit _U)(Quantity!(U, _U) b) const pure + { + static if (!Dynamic && !b.Dynamic && unit == b.unit) + return cast(T)b.value; else { - enum scale = lScale*rScale; - enum trans = lTrans + lScale*rTrans; + if (unit == b.unit) + return cast(T)b.value; + + static if (Dynamic) + { + auto lScale = unit.scale!true(); + auto lTrans = unit.offset!true(); + } + else + { + enum lScale = unit.scale!true(); + enum lTrans = unit.offset!true(); + } + static if (b.Dynamic) + { + auto rScale = b.unit.scale(); + auto rTrans = b.unit.offset(); + } + else + { + enum rScale = b.unit.scale(); + enum rTrans = b.unit.offset(); + } + + static if (Dynamic || b.Dynamic) + { + auto scale = lScale*rScale; + auto trans = lTrans + lScale*rTrans; + } + else + { + enum scale = lScale*rScale; + enum trans = lTrans + lScale*rTrans; + } + return cast(T)(b.value*scale + trans); } - return cast(T)(b.value*scale + trans); } } @@ -344,4 +521,60 @@ unittest assert(DegreesK(200).opEquals!epsilon(DegreesF(-99.67))); assert(DegreesC(100).opEquals!epsilon(DegreesF(212))); assert(DegreesF(100).opEquals!epsilon(DegreesC(37.77777777777777))); + + // nan property exists for float Quantities (both typed and Dynamic) + { + Metres nan_m = Metres.nan; + assert(nan_m.value != nan_m.value); // NaN != NaN + + VarQuantity nan_v = VarQuantity.nan; + assert(nan_v.value != nan_v.value); + } + static assert(!__traits(compiles, Quantity!(int, ScaledUnit(Metre)).nan)); +} + + +VarQuantity parse_quantity(const(char)[] text, size_t* bytes_taken = null) nothrow +{ + import urt.si.unit; + import urt.conv; + + int e; + uint base; + size_t taken; + long raw_value = text.parse_int_with_exponent_and_base(e, base, &taken); + if (taken == 0) + { + if (bytes_taken) + *bytes_taken = 0; + return VarQuantity(double.nan); + } + + // we parsed a number! + auto r = VarQuantity(e == 0 ? raw_value : raw_value * double(base)^^e); + + if (taken < text.length) + { + // try and parse a unit... + ScaledUnit su; + float pre_scale; + ptrdiff_t unit_taken = su.parse_unit(text[taken .. $], pre_scale, false); + if (unit_taken > 0) + { + taken += unit_taken; + r = VarQuantity(r.value * pre_scale, su); + } + } + if (bytes_taken) + *bytes_taken = taken; + return r; +} + +unittest +{ + import urt.si.unit; + + size_t taken; + assert("10V".parse_quantity(&taken) == Volts(10) && taken == 3); + assert("10.2e+2Wh".parse_quantity(&taken) == WattHours(1020) && taken == 9); } diff --git a/src/urt/si/unit.d b/src/urt/si/unit.d index cf40a9e..184b7e6 100644 --- a/src/urt/si/unit.d +++ b/src/urt/si/unit.d @@ -1,5 +1,8 @@ module urt.si.unit; +import urt.array; +import urt.string; + nothrow @nogc: @@ -29,6 +32,9 @@ nothrow @nogc: // +enum ScaledUnit unit(const(char)[] desc) = () { ScaledUnit r; float f; ptrdiff_t e = r.parse_unit(desc, f); assert(e > 0, "Invalid unit"); assert(f == 1, "Unit requires pre-scale"); return r; }(); + + // base units enum Metre = Unit(UnitType.Length); enum Kilogram = Unit(UnitType.Mass); @@ -39,6 +45,9 @@ enum Candela = Unit(UnitType.Luma); enum Radian = Unit(UnitType.Angle); // non-si units +enum Minute = ScaledUnit(Second, ScaleFactor.Minute); +enum Hour = ScaledUnit(Second, ScaleFactor.Hour); +enum Day = ScaledUnit(Second, ScaleFactor.Day); enum Inch = ScaledUnit(Metre, ScaleFactor.Inch); enum Foot = ScaledUnit(Metre, ScaleFactor.Foot); enum Mile = ScaledUnit(Metre, ScaleFactor.Mile); @@ -60,7 +69,11 @@ enum CubicMetre = Metre^^3; enum Litre = ScaledUnit(CubicMetre, -3); enum Gram = ScaledUnit(Kilogram, -3); enum Milligram = ScaledUnit(Kilogram, -6); +enum Nanosecond = ScaledUnit(Second, -9); enum Hertz = Cycle / Second; +enum Kilohertz = ScaledUnit(Hertz, SiPrefix.Kilo); +enum Megahertz = ScaledUnit(Hertz, SiPrefix.Mega); +enum Gigahertz = ScaledUnit(Hertz, SiPrefix.Giga); enum Newton = Kilogram * Metre / Second^^2; enum Pascal = Newton / Metre^^2; enum PSI = ScaledUnit(Pascal, ScaleFactor.PSI); @@ -69,7 +82,9 @@ enum Watt = Joule / Second; enum Kilowatt = ScaledUnit(Watt, 3); enum AmpereHour = ScaledUnit(Coulomb, ScaleFactor.Hour); enum WattHour = ScaledUnit(Joule, ScaleFactor.Hour); -//enum KilowattHour = TODO: ONOES! Our system can't encode kilowatt-hours! This is disaster!! +enum KilowattHour = ScaledUnit(WattHour, SiPrefix.Kilo); +enum MegawattHour = ScaledUnit(WattHour, SiPrefix.Mega); +enum GigawattHour = ScaledUnit(WattHour, SiPrefix.Giga); enum Coulomb = Ampere * Second; enum Volt = Watt / Ampere; enum Ohm = Volt / Ampere; @@ -96,7 +111,18 @@ enum UnitType : ubyte struct Unit { -nothrow @nogc: +nothrow: + // debug/ctfe helper + string toString() pure + { + char[32] t = void; + ptrdiff_t l = toString(t, null, null); + if (l < 0) + return "Invalid unit"; // OR JUST COULDN'T STRINGIFY! + return t[0..l].idup; + } + +@nogc: uint pack; @@ -225,82 +251,40 @@ nothrow @nogc: this = this.opBinary!op(rh); } - ptrdiff_t toString(char[] buffer) const + import urt.string.format : FormatArg; + ptrdiff_t toString(char[] buffer, const(char)[], const(FormatArg)[]) const pure { - immutable string[24] si = [ -// "da", "h", "k", "10k", "100k", "M", "10M", "100M", "G", "10G", "100G", "T", "10T", "100T", "P", "10P", "100P", "E", "10E", "100E", "Z", "10Z", "100Z", "Y" - "10", "100", "k", "10k", "100k", "M", "10M", "100M", "G", "10G", "100G", "T", "10T", "100T", "P", "10P", "100P", "E", "10E", "100E", "Z", "10Z", "100Z", "Y" - ]; - immutable string[24] si_inv = [ -// "d", "c", "m", "100μ", "10μ", "μ", "100n", "10n", "n", "100p", "10p", "p", "100f", "10f", "f", "100a", "10a", "a", "100z", "10z", "z", "100y", "10y", "y" - "100m", "10m", "m", "100μ", "10μ", "μ", "100n", "10n", "n", "100p", "10p", "p", "100f", "10f", "f", "100a", "10a", "a", "100z", "10z", "z", "100y", "10y", "y" - ]; - - ptrdiff_t len = 0; - - // ⁰¹⁻²³⁴⁵⁶⁷⁸⁹·° - -// if (q(0).exponent == 0) -// { -// // if we have a scaling factor... what do we write? -//// if (sf) ... -// len = 0; -// return len; -// } -// -// auto name = this in unitNames; -// if (name) -// { -// len = name.length; -// buffer[0 .. len] = *name; -// return len; -// } -// -// int f = sf(); -// name = unit() in unitNames; -// -// if ((name || q(1).exponent == 0) && f <= 24) -// { -// if (f > 0) -// { -// ref immutable string[24] prefix = inv ? si_inv : si; -// -// uint scale = f - 1; -// if (q(0).measure == UnitType.Mass) -// scale += 3; -// -// len = prefix[scale].length; -// buffer[0 .. len] = prefix[scale][]; -// } -// -// if (name) -// { -// buffer[len .. len + name.length] = *name; -// len += name.length; -// } -// else -// { -// immutable string[UnitType.max + 1] unit_name = [ "g", "m", "s", "A", "K", "cd", "cy" ]; -// -// string uname = unit_name[q(0).measure]; -// buffer[len .. len + uname.length] = uname[]; -// len += uname.length; -// } -// -// if (q(0).measure != 1) -// { -// buffer[len++] = '^'; -// len += q(0).exponent.toString(buffer[len .. $]); -// } -// -// } -// else -// { -// // multiple terms, or an odd scale factor... -// // TODO... -// assert(false); -// } + assert(false, "TODO"); + } + + ptrdiff_t fromString(const(char)[] s) pure + { + if (s.length == 0) + { + pack = 0; + return 0; + } + Unit r; + size_t len = s.length; + bool invert; + char sep; + while (const(char)[] unit = s.split!('/', '*')(sep)) + { + int p = unit.take_power(); + if (p == 0) + return -1; // invalid power + + if (const Unit* u = unit in unitMap) + r *= (*u) ^^ (invert ? -p : p); + else + { + assert(false, "TODO?"); + } + if (sep == '/') + invert = true; + } + this = r; return len; } @@ -353,9 +337,14 @@ unittest enum ScaleFactor : ubyte { + // prefix-mode factors (contiguous low range): ee field encodes an SI prefix + // (none/k/M/G); no exponentiation other than ^^-1 Minute = 0, Hour, Day, + Cycles, + + // power-mode factors: ee field encodes a power exponent (1..4); no SI prefix Inch, Foot, Mile, @@ -366,11 +355,23 @@ enum ScaleFactor : ubyte UKFluidOunce, UKGallon, PSI, - Cycles, Degrees, } static assert(ScaleFactor.max < 15); +enum LastPrefixModeFactor = ScaleFactor.Cycles; + +bool is_prefix_mode(ScaleFactor f) pure + => f <= LastPrefixModeFactor; + +enum SiPrefix : ubyte +{ + None = 0, // 10^^0 + Kilo, // 10^^3 + Mega, // 10^^6 + Giga, // 10^^9 +} + enum ExtendedScaleFactor : ubyte { Res1 = 0, // what here? @@ -381,7 +382,18 @@ enum ExtendedScaleFactor : ubyte struct ScaledUnit { -nothrow @nogc: +nothrow: + // debug/ctfe helper + string toString() pure + { + char[32] t = void; + ptrdiff_t l = toString(t, null, null); + if (l < 0) + return "Invalid unit"; // OR JUST COULDN'T STRINGIFY! + return t[0..l].idup; + } + +@nogc: uint pack; @@ -392,6 +404,8 @@ nothrow @nogc: this(Unit u, ScaleFactor sf, int e = 1) pure { + debug assert(!is_prefix_mode(sf) || e == 1 || e == -1, "Prefix-mode ScaleFactor only supports e == ±1; use the SiPrefix overload for prefixed units"); + pack = u.pack; if (e == 0) @@ -405,6 +419,12 @@ nothrow @nogc: pack |= 0x01000000 | (sf << 25) | ((e - 1) << 29); } + this(ScaledUnit base, SiPrefix prefix) pure + { + debug assert(!base.siScale() && !base.isExtended() && is_prefix_mode(base.sf()), "SI prefix only valid on prefix-mode extended ScaledUnit"); + pack = (base.pack & ~(3U << 29)) | (uint(prefix) << 29); + } + this(Unit u, ExtendedScaleFactor scaleFactor, bool inverse = false) pure { pack = u.pack | 0x1F000000 | (scaleFactor << 29) | (inverse << 31); @@ -432,12 +452,12 @@ nothrow @nogc: return unit == b.unit; } - double scale(bool inv = false)() const pure + double scale(bool invert = false)() const pure { if (siScale) { int e = exp(); - if (inv) + if (invert) e = -e; if (uint(e + 9) < 19) return sciScaleFactor[e + 9]; @@ -445,9 +465,18 @@ nothrow @nogc: } if (isExtended()) - return extScaleFactor[(pack >> 29) ^ (inv << 2)]; + return extScaleFactor[(pack >> 29) ^ (invert << 2)]; + + ScaleFactor f = sf(); + uint inv = (pack >> 31) ^ invert; + + if (is_prefix_mode(f)) + { + double s = scaleFactor[0][f] * prefixScale[(pack >> 29) & 3]; + return inv ? 1.0 / s : s; + } - double s = scaleFactor[(pack >> 31) ^ inv][sf()]; + double s = scaleFactor[inv][f]; for (uint i = ((pack >> 29) & 3); i > 0; --i) s *= s; return s; @@ -484,6 +513,8 @@ nothrow @nogc: // if it's extended, we can't exponentiate these units... assert(!isExtended(), "Temperature units can't be multiplied"); + assert(!is_prefix_mode(sf()), "Prefix-mode units only support exponents of ±1"); + int f = decodeExp[pack >> 29] * e; if (uint(f + 4) > 8) @@ -549,6 +580,17 @@ nothrow @nogc: assert(!isExtended(), "Temperature units can't be multiplied"); assert(sf() == b.sf(), "Can't combine mismatching arbitrary units"); + if (is_prefix_mode(sf())) + { + // prefix-mode factors don't compose; division of identical scales cancels + static if (op == "/") + { + if ((pack & 0xFF000000) == (b.pack & 0xFF000000)) + return ScaledUnit(u); + } + assert(false, "Prefix-mode units don't compose with multiplication"); + } + static if (op == "*") int e = decodeExp[f >> 5] + decodeExp[bf >> 5]; else @@ -574,9 +616,288 @@ nothrow @nogc: bool opEquals(Unit rh) const pure => (pack & 0xFF000000) ? false : unit == rh; + alias parseUnit = parse_unit; // TODO: DELETE ME!!! + ptrdiff_t parse_unit(const(char)[] s, out float pre_scale, bool allow_unit_scale = true) pure + { + import urt.conv : parse_uint_with_exponent; + + pre_scale = 1; + + if (s.length == 0) + { + pack = 0; + return 0; + } + + size_t len = s.length; + if (s[0] == '-') + { + if (s.length == 1) + return -1; + pre_scale = -1; + s = s[1 .. $]; + } + + ScaledUnit r; + bool invert; + char sep; + while (const(char)[] term = s.split!(['/', '*'], false, false)(&sep)) + { + int p = term.take_power(); + if (p == 0) + return -1; // invalid exponent + if (term.length == 0) + return -1; + + size_t offset = 0; + + // parse the scale factor + int e = 0; + if (term[0].is_numeric) + { + if (!allow_unit_scale) + return -1; // no numeric scale factor allowed + ulong sf = term.parse_uint_with_exponent(e, &offset); + pre_scale *= sf; + } + + if (offset == term.length) + r *= ScaledUnit(Unit(), e); + else if (const ScaledUnit* su = term[offset .. $] in noScaleUnitMap) + { + r *= (*su) ^^ (invert ? -p : p); + pre_scale *= 10.0^^e; + } + else + { + // try and parse SI prefix... + switch (term[offset]) + { + case 'Y': e += 24; ++offset; break; + case 'Z': e += 21; ++offset; break; + case 'E': e += 18; ++offset; break; + case 'P': e += 15; ++offset; break; + case 'T': e += 12; ++offset; break; + case 'G': e += 9; ++offset; break; + case 'M': e += 6; ++offset; break; + case 'k': e += 3; ++offset; break; + case 'h': e += 2; ++offset; break; + case 'c': e -= 2; ++offset; break; + case 'u': e -= 6; ++offset; break; + case 'n': e -= 9; ++offset; break; + case 'p': e -= 12; ++offset; break; + case 'f': e -= 15; ++offset; break; + case 'a': e -= 18; ++offset; break; + case 'z': e -= 21; ++offset; break; + case 'y': e -= 24; ++offset; break; + case 'm': + // can confuse with metres... so gotta check... + if (offset + 1 < term.length) + e -= 3, ++offset; + break; + case 'd': + if (offset + 1 < term.length && term[offset + 1] == 'a') + { + e += 1, offset += 2; + break; + } + e -= 1, ++offset; + break; + default: + if (offset + "µ".length < term.length && term[offset .. offset + "µ".length] == "µ") + e -= 6, offset += "µ".length; + break; + } + if (offset == term.length) + return -1; + + term = term[offset .. $]; + if (const Unit* u = term in unitMap) + { + if (term == "kg") + { + // we alrady parsed the 'k', so this string must have been "kkg", which is nonsense + return -1; + } + r *= ScaledUnit((*u) ^^ (invert ? -p : p), e); + } + else if (const ScaledUnit* su = term in scaledUnitMap) + r *= ScaledUnit(su.unit, su.exp + e) ^^ (invert ? -p : p); + else if (const ScaledUnit* su = term in noScaleUnitMapSI) + { + // if SI exponent fits in our 2-bit prefix table (none / k / M / G), encode the prefix into the ScaledUnit exponent + // TODO: should we round e4,5->3 with 10-100x scaling, rather than 10,000-100,000x scaling as would be applied below? + if (!su.siScale() && !su.isExtended() && is_prefix_mode(su.sf()) && (e == 0 || e == 3 || e == 6 || e == 9)) + { + SiPrefix prefix = cast(SiPrefix)(e / 3); + r *= ScaledUnit(*su, prefix) ^^ (invert ? -p : p); + } + else + { + r *= (*su) ^^ (invert ? -p : p); + pre_scale *= 10.0^^e; + } + } + else + return -1; // string was not taken? + } + + if (sep == '/') + invert = true; + } + this = r; + return len; + } + + import urt.string.format : FormatArg; + ptrdiff_t format_unit(char[] buffer, out float pre_scale, bool allow_unit_scale = true) const pure + { + assert(allow_unit_scale == true, "TODO: support for no-scale formatting (require pre-scale)"); + pre_scale = 1; + + if (!unit.pack) + { + if (siScale && exp == -2) + { + if (buffer.ptr) + { + if (buffer.length == 0) + return -1; + buffer[0] = '%'; + } + return 1; + } + else if (siScale && exp == -3) + { + enum pm_len = "‰".length; + if (buffer.ptr) + { + if (buffer.length < pm_len) + return -1; + buffer[0..pm_len] = "‰"; + } + return pm_len; + } + else + assert(false, "TODO!"); // how (or should?) we encode a scale as a unit type? + } + + size_t len = 0; + if (siScale) + { + int x = exp; + if (x != 0) + { + // for scale factors between SI units, we'll normalise to the next higher unit... + int y = (x + 33) % 3; + if (y != 0) + { + if (y == 1) + { + if (buffer.ptr) + { + if (buffer.length < 2) + return -1; + buffer[0..2] = "10"; + } + --x; + len += 2; + } + else + { + if (buffer.ptr) + { + if (buffer.length < 3) + return -1; + buffer[0..3] = "100"; + } + x -= 2; + len += 3; + } + } + assert(x >= -30, "TODO: handle this very small case"); + + if (x != 0) + { + if (buffer.ptr) + { + if (buffer.length <= len) + return -1; + buffer[len] = "qryzafpnum kMGTPEZYRQ"[x/3 + 10]; + } + ++len; + } + } + + if (const string* name = unit in unitNames) + { + if (buffer.ptr) + { + if (buffer.length < len + name.length) + return -1; + buffer[len .. len + name.length] = *name; + } + len += name.length; + } + else + { + // synth a unit name... + assert(false, "TODO"); + } + } + else + { + if (const string* name = this in scaledUnitNames) + { + if (buffer.ptr) + { + if (buffer.length < len + name.length) + return -1; + buffer[len .. len + name.length] = *name; + } + len += name.length; + } + else + { + // what now? + assert(false, "TODO"); + } + } + return len; + } + + ptrdiff_t toString(char[] buffer, const(char)[], const(FormatArg)[]) const pure + { + float pre_scale; + ptrdiff_t r = format_unit(buffer, pre_scale, true); + if (pre_scale != 1) + return -1; + return r; + } + + ptrdiff_t fromString(const(char)[] s) pure + { + float scale; + ptrdiff_t r = parse_unit(s, scale); + if (scale != 1) + return -1; + return r; + } + size_t toHash() const pure => pack; + version (Windows) + { + auto __debugOverview() + { + import urt.mem; + char[] buffer = debug_alloc!char(32); + ptrdiff_t len = toString(buffer, null, null); + return buffer[0 .. len]; + } + } + package: this(uint pack) pure { @@ -619,6 +940,25 @@ unittest assert(Metre * Inch == ScaledUnit(Metre^^2, ScaleFactor.Inch)); assert(Metre / Inch == ScaledUnit(Unit(), ScaleFactor.Inch, -1)); + + // bit-stability check + assert(WattHour.unit == Joule); + + // prefix-mode extended units (hybrid SI prefix + named ScaleFactor) + assert(WattHour.scale() == 3600.0); + assert(KilowattHour.scale() == 3600.0 * 1000); + assert(MegawattHour.scale() == 3600.0 * 1e6); + assert(GigawattHour.scale() == 3600.0 * 1e9); + + // inversion of prefix-mode extended units + assert((WattHour^^-1).scale() == 1.0 / 3600); + assert((KilowattHour^^-1).scale() == 1.0 / (3600.0 * 1000)); + + // Hertz family (Cycles scale factor): kHz/MHz/GHz scale = Hz scale × prefix + assert(Kilohertz.scale() == Hertz.scale() * 1e3); + assert(Megahertz.scale() == Hertz.scale() * 1e6); + assert(Gigahertz.scale() == Hertz.scale() * 1e9); + assert((Kilohertz^^-1).scale() == 1.0 / (Hertz.scale() * 1e3)); } @@ -632,41 +972,43 @@ immutable ubyte[9] encodeExp = [ 7, 6, 5, 4, 0, 0, 1, 2, 3 ]; immutable double[19] sciScaleFactor = [ 1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9 ]; immutable double[16][2] scaleFactor = [ [ - 60, // Minute - 3600, // Hour - 86400, // Day - 0.0254, // Inch - 0.3048, // Foot - 1609.344, // Mile + 60, // Minute + 3600, // Hour + 86400, // Day + 2*PI, // Cycles + 0.0254, // Inch + 0.3048, // Foot + 1609.344, // Mile 453.59237 / 16, // Ounce - 453.59237, // Pound + 453.59237, // Pound 3.785411784 / 128, // USFluidOunce 3.785411784, // USGallon 4.54609 / 160, // UKFluidOunce - 4.54609, // UKGallon + 4.54609, // UKGallon 6894.7572931683, // PSI => 4.4482216152605/(0.0254*0.0254) - 2*PI, // Cycles - PI/180, // Degrees - double.nan // extended... + PI/180, // Degrees + double.nan // extended... ], [ - 1/60, // Minute - 1/3600, // Hour - 1/86400, // Day - 1/0.0254, // Inch - 1/0.3048, // Foot + 1/60.0, // Minute + 1/3600.0, // Hour + 1/86400.0, // Day + 1/(2*PI), // Cycles + 1/0.0254, // Inch + 1/0.3048, // Foot 1/1609.344, // Mile 16/453.59237, // Ounce 1/453.59237, // Pound 128/3.785411784, // USFluidOunce 1/3.785411784, // USGallon 160/4.54609, // UKFluidOunce - 1/4.54609, // UKGallon + 1/4.54609, // UKGallon 1/6894.7572931683, // PSI - 1/(2*PI), // Cycles - 180/PI, // Degrees - double.nan // extended... + 180/PI, // Degrees + double.nan // extended... ] ]; +immutable double[4] prefixScale = [ 1.0, 1e3, 1e6, 1e9 ]; + immutable double[8] extScaleFactor = [ 0, // Res1 1, // Celsius @@ -688,39 +1030,41 @@ immutable double[4] tempOffsets = [ (-273.15*9)/5 + 32 // K -> F ]; -immutable string[ScaledUnit] unitNames = [ +immutable string[Unit] unitNames = [ + Metre : "m", + Metre^^2 : "m²", + Metre^^3 : "m³", + Kilogram : "kg", + Second : "s", + Ampere : "A", + Kelvin : "K", + Candela : "cd", + Radian : "rad", - // ⁰¹⁻²³⁴⁵⁶⁷⁸⁹·° + // derived units + Newton : "N", + Pascal : "Pa", + Joule : "J", + Watt : "W", + Coulomb : "C", + Volt : "V", + Ohm : "Ω", + Farad : "F", + Siemens : "S", + Weber : "Wb", + Tesla : "T", + Henry : "H", + Lumen : "lm", + Lux : "lx", +]; - // base units - ScaledUnit() : "", - ScaledUnit(Metre) : "m", - ScaledUnit(Kilogram) : "kg", - ScaledUnit(Second) : "s", - ScaledUnit(Ampere) : "A", - ScaledUnit(Kelvin) : "°K", - ScaledUnit(Candela) : "cd", - ScaledUnit(Radian) : "rad", +immutable string[ScaledUnit] scaledUnitNames = [ + Minute : "min", +// Minute : "mins", + Hour : "hr", +// Hour : "hrs", + Day : "day", - // derived units - ScaledUnit(SquareMetre) : "m²", - ScaledUnit(CubicMetre) : "m³", - ScaledUnit(Newton) : "N", - ScaledUnit(Pascal) : "Pa", - ScaledUnit(Joule) : "J", - ScaledUnit(Watt) : "W", - ScaledUnit(Coulomb) : "C", - ScaledUnit(Volt) : "V", - ScaledUnit(Ohm) : "Ω", - ScaledUnit(Farad) : "F", - ScaledUnit(Siemens) : "S", - ScaledUnit(Weber) : "Wb", - ScaledUnit(Tesla) : "T", - ScaledUnit(Henry) : "H", - ScaledUnit(Lumen) : "lm", - ScaledUnit(Lux) : "lx", - - // scaled units Inch : "in", Foot : "ft", Mile : "mi", @@ -740,8 +1084,154 @@ immutable string[ScaledUnit] unitNames = [ Gram : "g", Milligram : "mg", Hertz : "Hz", + Kilohertz : "kHz", + Megahertz : "MHz", + Gigahertz : "GHz", PSI : "psi", Kilowatt : "kW", AmpereHour : "Ah", WattHour : "Wh", + KilowattHour : "kWh", + MegawattHour : "MWh", + GigawattHour : "GWh", +]; + +immutable Unit[string] unitMap = [ + // base units + "m" : Metre, + "kg" : Kilogram, + "s" : Second, + "A" : Ampere, + "K" : Kelvin, + "cd" : Candela, + "rad" : Radian, + + // derived units + "N" : Newton, + "Pa" : Pascal, + "J" : Joule, + "W" : Watt, + "C" : Coulomb, + "V" : Volt, + "Ω" : Ohm, + "F" : Farad, + "S" : Siemens, + "Wb" : Weber, + "T" : Tesla, + "H" : Henry, + "lm" : Lumen, + "lx" : Lux, + + // questionable... :/ + "VA" : Watt, + "var" : Watt, +]; + +immutable ScaledUnit[string] noScaleUnitMap = [ + "min" : Minute, + "mins" : Minute, + "hr" : Hour, + "hrs" : Hour, + "day" : Day, + "days" : Day, + "'" : Inch, + "in" : Inch, + "\"" : Foot, + "ft" : Foot, + "mi" : Mile, + "oz" : Ounce, + // TODO: us/uk floz/gallon? + "lb" : Pound, + "°" : Degree, + "deg" : Degree, + "°C" : Celsius, + "°F" : Fahrenheit, + "cy" : Cycle, + "psi" : PSI, + "%" : Percent, + "‰" : Permille, + "‱" : ScaledUnit(Unit(), -4), + "ppm" : ScaledUnit(Unit(), -6), +]; + +// these can have SI prefixes +immutable ScaledUnit[string] scaledUnitMap = [ + "l" : Litre, + "g" : Gram, ]; + +// these can have SI prefixes, but scale must be converted to coefficient +immutable ScaledUnit[string] noScaleUnitMapSI = [ + "Ah" : AmpereHour, + "Wh" : WattHour, + "Hz" : Hertz, + + // questionable... :/ + "VAh" : WattHour, + "varh" : WattHour, +]; + +int take_power(ref const(char)[] s) pure +{ + size_t e = s.findFirst('^'); + if (e < s.length) + { + const(char)[] p = s[e+1..$]; + s = s[0..e]; + if (s.length == 0 || p.length == 0) + return 0; + if (p[0] == '-') + { + if (p.length != 2 || uint(p[2] - '0') > 4) + return 0; + return -(p[2] - '0'); + } + if (p.length != 1 || uint(p[1] - '0') > 4) + return 0; + return p[2] - '0'; + } + else if (s.length > 2) + { + if (s[$-2..$] == "¹") + { + if (s.length > 5 && s[$-5..$-2] == "⁻") + { + s = s[0..$-5]; + return -1; + } + s = s[0..$-2]; + return 1; + } + if (s[$-2..$] == "²") + { + if (s.length > 5 && s[$-5..$-2] == "⁻") + { + s = s[0..$-5]; + return -2; + } + s = s[0..$-2]; + return 2; + } + if (s[$-2..$] == "³") + { + if (s.length > 5 && s[$-5..$-2] == "⁻") + { + s = s[0..$-5]; + return -3; + } + s = s[0..$-2]; + return 3; + } + } + else if (s.length > 3 && s[$-3..$] == "⁴") + { + if (s.length > 6 && s[$-6..$-3] == "⁻") + { + s = s[0..$-6]; + return -4; + } + s = s[0..$-3]; + return 4; + } + return 1; +} diff --git a/src/urt/socket.d b/src/urt/socket.d index 800f72d..8ef8f8a 100644 --- a/src/urt/socket.d +++ b/src/urt/socket.d @@ -6,13 +6,57 @@ public import urt.mem; public import urt.result; public import urt.time; -version (Windows) +version (UseInternalIPStack) + version = SocketCallbacks; +else version (BareMetal) + version = SocketCallbacks; +else version (Windows) + version = WinSock; + +version (SocketCallbacks) +{ + alias SocketHandle = int; + enum INVALID_SOCKET = -1; + + struct SocketBackend + { + nothrow @nogc: + SocketResult function(AddressFamily, SocketType, Protocol, out Socket) create; + SocketResult function(Socket) close; + SocketResult function(Socket, ref const InetAddress) bind; + SocketResult function(Socket, uint) listen; + SocketResult function(Socket, ref const InetAddress) connect; + SocketResult function(Socket, out Socket, InetAddress*) accept; + SocketResult function(Socket, SocketShutdownMode) shutdown; + SocketResult function(Socket, const(InetAddress)*, MsgFlags, const(void[])[], size_t*) sendmsg; + SocketResult function(Socket, void[], MsgFlags, size_t*) recv; + SocketResult function(Socket, void[], MsgFlags, InetAddress*, size_t*) recvfrom; + SocketResult function(Socket, out size_t) pending; + SocketResult function(PollFd[], Duration, out uint) poll; + SocketResult function(Socket, SocketOption, const(void)*, size_t) set_option; + SocketResult function(Socket, SocketOption, void*, size_t) get_option; + SocketResult function(Socket, out InetAddress) get_peer_name; + SocketResult function(Socket, out InetAddress) get_socket_name; + SocketResult function(char*, size_t) get_hostname; + SocketResult function(const(char)[], const(char)[], AddressInfo*, AddressInfoResolver*) get_address_info; + bool function(AddressInfoResolver*, out AddressInfo) next_address; + void function(AddressInfoResolver*) free_address_info; + } + + __gshared SocketBackend* _socket_backend; + + void register_socket_backend(SocketBackend* backend) nothrow @nogc + { + _socket_backend = backend; + } +} +else version (WinSock) { // TODO: this is in core.sys.windows.winsock2; why do I need it here? pragma(lib, "ws2_32"); - import core.sys.windows.windows; - import core.sys.windows.winsock2 : + import urt.internal.sys.windows; + import urt.internal.sys.windows.winsock2 : _bind = bind, _listen = listen, _connect = connect, _accept = accept, _send = send, _sendto = sendto, _recv = recv, _recvfrom = recvfrom, _shutdown = shutdown; @@ -20,23 +64,23 @@ version (Windows) version = HasIPv6; alias SocketHandle = SOCKET; + + enum IPV6_RECVPKTINFO = 49; + enum IPV6_PKTINFO = 50; } else version (Posix) { - import core.stdc.errno; - import core.sys.posix.fcntl; - import core.sys.posix.poll; - import core.sys.posix.unistd : close, gethostname; import urt.internal.os; // use ImportC to import system C headers... - import core.sys.posix.netinet.in_ : sockaddr_in6; alias _bind = urt.internal.os.bind, _listen = urt.internal.os.listen, _connect = urt.internal.os.connect, - _accept = urt.internal.os.accept, _send = urt.internal.os.send, _sendto = urt.internal.os.sendto, - _recv = urt.internal.os.recv, _recvfrom = urt.internal.os.recvfrom, _shutdown = urt.internal.os.shutdown; - alias _poll = core.sys.posix.poll.poll; + _accept = urt.internal.os.accept, _send = urt.internal.os.send, _sendto = urt.internal.os.sendto, _sendmsg = urt.internal.os.sendmsg, + _recv = urt.internal.os.recv, _recvfrom = urt.internal.os.recvfrom, _shutdown = urt.internal.os.shutdown, + _close = urt.internal.os.close, _poll = urt.internal.os.poll; + version = BSDSockets; version = HasUnixSocket; version = HasIPv6; + version = Errno; alias SocketHandle = int; enum INVALID_SOCKET = -1; @@ -49,6 +93,143 @@ else version (Posix) enum AF_BRIDGE = 7; // Multiprotocol bridge enum AF_INET6 = 10; // IP version 6 } +else version (lwIP) +{ + // lwIP BSD socket API -- constants and structs match lwIP defaults + version = BSDSockets; + version = HasIPv6; + version = Errno; + + alias SocketHandle = int; + enum INVALID_SOCKET = -1; + + enum AF_UNSPEC = 0; + enum AF_UNIX = 1; + enum AF_INET = 2; + enum AF_INET6 = 10; + + enum SOCK_STREAM = 1; + enum SOCK_DGRAM = 2; + enum SOCK_RAW = 3; + + enum IPPROTO_IP = 0; + enum IPPROTO_ICMP = 1; + enum IPPROTO_TCP = 6; + enum IPPROTO_UDP = 17; + enum IPPROTO_IPV6 = 41; + enum IPPROTO_RAW = 255; + + enum SOL_SOCKET = 0xFFF; + + enum MSG_PEEK = 0x01; + + enum SHUT_RD = 0; + enum SHUT_WR = 1; + enum SHUT_RDWR = 2; + + // fcntl constants for non-blocking mode + enum F_GETFL = 3; + enum F_SETFL = 4; + enum O_NONBLOCK = 1; + + // socket options + enum SO_REUSEADDR = 0x0004; + enum SO_KEEPALIVE = 0x0008; + enum SO_LINGER = 0x0080; + enum SO_SNDBUF = 0x1001; + enum SO_RCVBUF = 0x1002; + enum SO_ERROR = 0x1007; + enum TCP_NODELAY = 0x01; + enum TCP_KEEPIDLE = 0x03; + enum TCP_KEEPINTVL = 0x04; + enum TCP_KEEPCNT = 0x05; + enum IP_ADD_MEMBERSHIP = 3; + enum IP_MULTICAST_TTL = 5; + enum IP_MULTICAST_LOOP = 7; + + alias socklen_t = uint; + struct in_addr { uint s_addr; } + struct in6_addr { ubyte[16] s6_addr; } + struct sockaddr { ubyte sa_len; ubyte sa_family; ubyte[14] sa_data; } + struct sockaddr_in { ubyte sin_len; ubyte sin_family; ushort sin_port; in_addr sin_addr; ubyte[8] sin_zero; } + struct sockaddr_in6 { ubyte sin6_len; ubyte sin6_family; ushort sin6_port; uint sin6_flowinfo; in6_addr sin6_addr; uint sin6_scope_id; } + struct sockaddr_storage { ubyte s2_len; ubyte ss_family; ubyte[2] s2_data1; uint[3] s2_data2; uint[3] s2_data3; } + struct linger { int l_onoff; int l_linger; } + struct ip_mreq { in_addr imr_multiaddr; in_addr imr_interface; } + struct iovec { void* iov_base; size_t iov_len; } + struct msghdr { void* msg_name; socklen_t msg_namelen; iovec* msg_iov; int msg_iovlen; void* msg_control; socklen_t msg_controllen; int msg_flags; } + + enum POLLRDNORM = 0x10; + enum POLLWRNORM = 0x80; + enum POLLERR = 0x04; + enum POLLHUP = 0x200; + enum POLLNVAL = 0x08; + + enum AI_PASSIVE = 0x01; + enum AI_CANONNAME = 0x02; + enum AI_NUMERICHOST = 0x04; + enum AI_NUMERICSERV = 0x08; + enum AI_V4MAPPED = 0x10; + enum AI_ALL = 0x20; + enum AI_ADDRCONFIG = 0x40; + + struct pollfd { int fd; short events; short revents; } + struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; socklen_t ai_addrlen; sockaddr* ai_addr; char* ai_canonname; addrinfo* ai_next; } + + // lwIP socket functions -- actual symbol names are lwip_* prefixed + extern(C) nothrow @nogc + { + int lwip_poll(pollfd*, uint, int); + SocketHandle lwip_socket(int, int, int); + int lwip_bind(SocketHandle, const(sockaddr)*, socklen_t); + int lwip_listen(SocketHandle, int); + int lwip_connect(SocketHandle, const(sockaddr)*, socklen_t); + SocketHandle lwip_accept(SocketHandle, sockaddr*, socklen_t*); + ptrdiff_t lwip_send(SocketHandle, const(void)*, size_t, int); + ptrdiff_t lwip_sendto(SocketHandle, const(void)*, size_t, int, const(sockaddr)*, socklen_t); + ptrdiff_t lwip_sendmsg(SocketHandle, const(msghdr)*, int); + ptrdiff_t lwip_recv(SocketHandle, void*, size_t, int); + ptrdiff_t lwip_recvfrom(SocketHandle, void*, size_t, int, sockaddr*, socklen_t*); + int lwip_shutdown(SocketHandle, int); + int lwip_setsockopt(SocketHandle, int, int, const(void)*, socklen_t); + int lwip_getsockopt(SocketHandle, int, int, void*, socklen_t*); + int lwip_getsockname(SocketHandle, sockaddr*, socklen_t*); + int lwip_getpeername(SocketHandle, sockaddr*, socklen_t*); + int ow_lwip_getaddrinfo(const(char)*, const(char)*, const(addrinfo)*, addrinfo**); + void ow_lwip_freeaddrinfo(addrinfo*); + int lwip_close(int); + int lwip_fcntl(int, int, int); + int lwip_ioctl(int, int, void*); + } + + enum FIONBIO = 0x8004667e; // _IOW('f', 126, unsigned long) + enum FIONREAD = 0x4004667f; // _IOR('f', 127, unsigned long) + + // Aliases so the rest of the codebase uses POSIX names + alias _poll = lwip_poll; + alias socket = lwip_socket; + alias _bind = lwip_bind; + alias _listen = lwip_listen; + alias _connect = lwip_connect; + alias _accept = lwip_accept; + alias _send = lwip_send; + alias _sendto = lwip_sendto; + alias _sendmsg = lwip_sendmsg; + alias _recv = lwip_recv; + alias _recvfrom = lwip_recvfrom; + alias _shutdown = lwip_shutdown; + alias setsockopt = lwip_setsockopt; + alias getsockopt = lwip_getsockopt; + alias getsockname = lwip_getsockname; + alias getpeername = lwip_getpeername; + alias getaddrinfo = ow_lwip_getaddrinfo; + alias freeaddrinfo = ow_lwip_freeaddrinfo; + alias _close = lwip_close; + alias fcntl = lwip_fcntl; + alias ioctlsocket = lwip_ioctl; + + int gethostname(char*, size_t) nothrow @nogc { return -1; } +} else static assert(false, "Platform not supported"); @@ -57,119 +238,127 @@ nothrow @nogc: enum SocketResult { - Success, - Failure, - WouldBlock, - NoBuffer, - NetworkDown, - ConnectionRefused, - ConnectionReset, - ConnectionAborted, - ConnectionClosed, - Interrupted, - InvalidSocket, - InvalidArgument, + success, + failure, + would_block, + no_buffer, + network_down, + network_unreachable, + host_unreachable, + connection_refused, + connection_reset, + connection_aborted, + connection_closed, + address_in_use, + address_not_available, + timed_out, + not_connected, + already_connected, + permission_denied, + interrupted, + invalid_socket, + invalid_argument, } enum SocketType : byte { - Unknown = -1, - Stream = 0, - Datagram, - Raw, + unknown = -1, + stream = 0, + datagram, + raw, } enum Protocol : byte { - Unknown = -1, - TCP = 0, - UDP, - IP, - ICMP, - Raw, + unknown = -1, + tcp = 0, + udp, + ip, + icmp, + raw, } enum SocketShutdownMode : ubyte { - Read, - Write, - ReadWrite + read, + write, + read_write } enum SocketOption : ubyte { // not traditionally a 'socket option', but this is way more convenient - NonBlocking, + non_blocking, // Socket options - KeepAlive, - Linger, - RandomizePort, - SendBufferLength, - RecvBufferLength, - ReuseAddress, - NoSigPipe, - Error, + keep_alive, + linger, + randomize_port, + send_buffer_length, + recv_buffer_length, + reuse_address, + no_sig_pPipe, + error, // IP options - FirstIpOption, - Multicast = FirstIpOption, - MulticastLoopback, - MulticastTTL, + first_ip_option, + multicast = first_ip_option, + multicast_loopback, + multicast_ttl, + ip_pktinfo, // IPv6 options - FirstIpv6Option, + first_ipv6_option, + ipv6_pktinfo = first_ipv6_option, // ICMP options - FirstIcmpOption = FirstIpv6Option, + first_icmp_option, // ICMPv6 options - FirstIcmpv6Option = FirstIcmpOption, + first_icmpv6_option = first_icmp_option, // TCP options - FirstTcpOption = FirstIcmpv6Option, - TCP_KeepIdle = FirstTcpOption, - TCP_KeepIntvl, - TCP_KeepCnt, - TCP_KeepAlive, // Apple: similar to KeepIdle - TCP_NoDelay, - + first_tcp_option = first_icmpv6_option, + tcp_keep_idle = first_tcp_option, + tcp_keep_intvl, + tcp_keep_cnt, + tcp_keep_alive, // Apple: similar to KeepIdle + tcp_no_delay, // UDP options - FirstUdpOption, + first_udp_option, } enum MsgFlags : ubyte { - None = 0, - OOB = 1 << 0, - Peek = 1 << 1, - Confirm = 1 << 2, - NoSig = 1 << 3, + none = 0, + peek = 1 << 0, + confirm = 1 << 1, + no_sig = 1 << 2, //... } enum AddressInfoFlags : ubyte { - None = 0, - Passive = 1 << 0, - CanonName = 1 << 1, - NumericHost = 1 << 2, - NumericServ = 1 << 3, - All = 1 << 4, - AddrConfig = 1 << 5, - V4Mapped = 1 << 6, - FQDN = 1 << 7, + none = 0, + passive = 1 << 0, + canon_name = 1 << 1, + numeric_host = 1 << 2, + numeric_serv = 1 << 3, + all = 1 << 4, + addr_config = 1 << 5, + v4_mapped = 1 << 6, + fqdn = 1 << 7, } enum PollEvents : ubyte { - None = 0, - Read = 1 << 0, - Write = 1 << 1, - Error = 1 << 2, - HangUp = 1 << 3, - Invalid = 1 << 4, + none = 0, + read = 1 << 0, + write = 1 << 1, + error = 1 << 2, + hangup = 1 << 3, + invalid = 1 << 4, } @@ -182,495 +371,850 @@ nothrow @nogc: void opAssign(typeof(null)) { handle = invalid.handle; } -private: SocketHandle handle = INVALID_SOCKET; } Result create_socket(AddressFamily af, SocketType type, Protocol proto, out Socket socket) { - version (HasUnixSocket) {} else - assert(af != AddressFamily.Unix, "Unix sockets not supported on this platform!"); + version (SocketCallbacks) + return Result(_socket_backend.create(af, type, proto, socket)); + else + { + version (HasUnixSocket) {} else + assert(af != AddressFamily.unix, "Unix sockets not supported on this platform!"); - socket.handle = .socket(s_addressFamily[af], s_socketType[type], s_protocol[proto]); - if (socket == Socket.invalid) - return socket_getlasterror(); - return Result.Success; + socket.handle = .socket(s_addressFamily[af], s_socketType[type], s_protocol[proto]); + if (socket == Socket.invalid) + return socket_getlasterror(); + + return Result.success; + } } Result close(Socket socket) { - version (Windows) - int result = closesocket(socket.handle); - else version (Posix) - int result = close(socket.handle); + version (SocketCallbacks) + return Result(_socket_backend.close(socket)); else - assert(false, "Not implemented!"); - if (result < 0) - return socket_getlasterror(); - -// { -// LockGuard lock(s_noSignalMut); -// s_noSignal.Erase(socket); -// } - - return Result.Success; + { + int result; + version (WinSock) + result = closesocket(socket.handle); + else version (BSDSockets) + result = _close(socket.handle); + else + assert(false, "Not implemented!"); + if (result < 0) + return socket_getlasterror(); + return Result.success; + } } Result shutdown(Socket socket, SocketShutdownMode how) { - int t = int(how); - switch (how) + version (SocketCallbacks) + return Result(_socket_backend.shutdown(socket, how)); + else { - version (Windows) - { - case SocketShutdownMode.Read: t = SD_RECEIVE; break; - case SocketShutdownMode.Write: t = SD_SEND; break; - case SocketShutdownMode.ReadWrite: t = SD_BOTH; break; - } - else version (Posix) + int t = int(how); + switch (how) { - case SocketShutdownMode.Read: t = SHUT_RD; break; - case SocketShutdownMode.Write: t = SHUT_WR; break; - case SocketShutdownMode.ReadWrite: t = SHUT_RDWR; break; + version (WinSock) + { + case SocketShutdownMode.read: t = SD_RECEIVE; break; + case SocketShutdownMode.write: t = SD_SEND; break; + case SocketShutdownMode.read_write: t = SD_BOTH; break; + } + else version (BSDSockets) + { + case SocketShutdownMode.read: t = SHUT_RD; break; + case SocketShutdownMode.write: t = SHUT_WR; break; + case SocketShutdownMode.read_write: t = SHUT_RDWR; break; + } + default: + assert(false, "Invalid `how`"); } - default: - assert(false, "Invalid `how`"); - } - if (_shutdown(socket.handle, t) < 0) - return socket_getlasterror(); - return Result.Success; + if (_shutdown(socket.handle, t) < 0) + return socket_getlasterror(); + return Result.success; + } } Result bind(Socket socket, ref const InetAddress address) { - ubyte[512] buffer = void; - size_t addrLen; - sockaddr* sockAddr = make_sockaddr(address, buffer, addrLen); - assert(sockAddr, "Invalid socket address"); + version (SocketCallbacks) + return Result(_socket_backend.bind(socket, address)); + else + { + ubyte[512] buffer = void; + size_t addr_len; + sockaddr* sock_addr = make_sockaddr(address, buffer, addr_len); + assert(sock_addr, "Invalid socket address"); - if (_bind(socket.handle, sockAddr, cast(int)addrLen) < 0) - return socket_getlasterror(); - return Result.Success; + if (_bind(socket.handle, sock_addr, cast(int)addr_len) < 0) + return socket_getlasterror(); + return Result.success; + } } Result listen(Socket socket, uint backlog = -1) { - if (_listen(socket.handle, int(backlog & 0x7FFFFFFF)) < 0) - return socket_getlasterror(); - return Result.Success; + version (SocketCallbacks) + return Result(_socket_backend.listen(socket, backlog)); + else + { + if (_listen(socket.handle, int(backlog & 0x7FFFFFFF)) < 0) + return socket_getlasterror(); + return Result.success; + } } Result connect(Socket socket, ref const InetAddress address) { - ubyte[512] buffer = void; - size_t addrLen; - sockaddr* sockAddr = make_sockaddr(address, buffer, addrLen); - assert(sockAddr, "Invalid socket address"); + version (SocketCallbacks) + return Result(_socket_backend.connect(socket, address)); + else + { + ubyte[512] buffer = void; + size_t addr_len; + sockaddr* sock_addr = make_sockaddr(address, buffer, addr_len); + assert(sock_addr, "Invalid socket address"); - if (_connect(socket.handle, sockAddr, cast(int)addrLen) < 0) - return socket_getlasterror(); - return Result.Success; + if (_connect(socket.handle, sock_addr, cast(int)addr_len) < 0) + return socket_getlasterror(); + return Result.success; + } } -Result accept(Socket socket, out Socket connection, InetAddress* connectingSocketAddress = null) +Result accept(Socket socket, out Socket connection, InetAddress* remote_address = null, InetAddress* local_address = null) { - char[sockaddr_storage.sizeof] buffer = void; - sockaddr* addr = cast(sockaddr*)buffer.ptr; - socklen_t size = buffer.sizeof; + version (SocketCallbacks) + { + Result r = Result(_socket_backend.accept(socket, connection, remote_address)); + if (!r) + return r; + if (local_address) + return get_socket_name(connection, *local_address); + return Result.success; + } + else + { + char[sockaddr_storage.sizeof] buffer = void; + sockaddr* addr = cast(sockaddr*)buffer.ptr; + socklen_t size = buffer.sizeof; - connection.handle = _accept(socket.handle, addr, &size); - if (connection == Socket.invalid) - return socket_getlasterror(); - else if (connectingSocketAddress) - *connectingSocketAddress = make_InetAddress(addr); - return Result.Success; + connection.handle = _accept(socket.handle, addr, &size); + if (connection == Socket.invalid) + return socket_getlasterror(); + if (remote_address) + *remote_address = make_InetAddress(addr); + if (local_address) + { + if (getsockname(connection.handle, addr, &size) < 0) + return socket_getlasterror(); + *local_address = make_InetAddress(addr); + } + // platforms are inconsistent regarding whether accept inherits the listening socket's blocking mode + // for consistentency, we always set blocking on the accepted socket + connection.set_socket_option(SocketOption.non_blocking, false); + return Result.success; + } } -Result send(Socket socket, const(void)[] message, MsgFlags flags = MsgFlags.None, size_t* bytesSent = null) +Result send(Socket socket, const(void)[] message, MsgFlags flags = MsgFlags.none, size_t* bytes_sent = null) { - Result r = Result.Success; + version (SocketCallbacks) + return sendmsg(socket, null, flags, null, bytes_sent, (&message)[0..1]); + else + return send(socket, flags, bytes_sent, (&message)[0..1]); +} - ptrdiff_t sent = _send(socket.handle, message.ptr, cast(int)message.length, map_message_flags(flags)); - if (sent < 0) +Result send(Socket socket, MsgFlags flags, size_t* bytes_sent, const void[][] buffers...) +{ + version (SocketCallbacks) + return sendmsg(socket, null, flags, null, bytes_sent, buffers); + else version (WinSock) { - r = socket_getlasterror(); - sent = 0; + uint sent; + WSABUF[32] bufs = void; + assert(buffers.length <= bufs.length, "Too many buffers!"); + + uint n = 0; + foreach(buffer; buffers) + { + if (buffer.length == 0) + continue; + assert(buffer.length <= uint.max, "Buffer too large!"); + bufs[n].buf = cast(char*)buffer.ptr; + bufs[n++].len = cast(uint)buffer.length; + } + if (n > 0) + { + int rc = WSASend(socket.handle, bufs.ptr, n, &sent, /+map_message_flags(flags)+/ 0, null, null); // there are no meaningful flags on Windows + if (rc == SOCKET_ERROR) + return socket_getlasterror(); + } + if (bytes_sent) + *bytes_sent = sent; + return Result.success; } - if (bytesSent) - *bytesSent = sent; - return r; + else + return sendmsg(socket, null, flags, null, bytes_sent, buffers); } -Result sendto(Socket socket, const(void)[] message, MsgFlags flags = MsgFlags.None, const InetAddress* address = null, size_t* bytesSent = null) +Result sendto(Socket socket, const(void)[] message, MsgFlags flags = MsgFlags.none, const InetAddress* address = null, size_t* bytes_sent = null) { - ubyte[sockaddr_storage.sizeof] tmp = void; - size_t addrLen; - sockaddr* sockAddr = null; - if (address) - { - sockAddr = make_sockaddr(*address, tmp, addrLen); - assert(sockAddr, "Invalid socket address"); - } + version (SocketCallbacks) + return sendmsg(socket, address, flags, null, bytes_sent, (&message)[0..1]); + else version (WinSock) + return sendto(socket, address, bytes_sent, (&message)[0..1]); + else + return sendmsg(socket, address, flags, null, bytes_sent, (&message)[0..1]); +} - Result r = Result.Success; - ptrdiff_t sent = _sendto(socket.handle, message.ptr, cast(int)message.length, map_message_flags(flags), sockAddr, cast(int)addrLen); - if (sent < 0) +Result sendto(Socket socket, const InetAddress* address, size_t* bytes_sent, const void[][] buffers...) +{ + version (SocketCallbacks) + return sendmsg(socket, address, MsgFlags.none, null, bytes_sent, buffers); + else version (WinSock) { - r = socket_getlasterror(); - sent = 0; + ubyte[sockaddr_storage.sizeof] tmp = void; + size_t addr_len; + sockaddr* sock_addr = null; + if (address) + { + sock_addr = make_sockaddr(*address, tmp, addr_len); + assert(sock_addr, "Invalid socket address"); + } + + uint sent; + WSABUF[32] bufs = void; + assert(buffers.length <= bufs.length, "Too many buffers!"); + + uint n = 0; + foreach(buffer; buffers) + { + if (buffer.length == 0) + continue; + assert(buffer.length <= uint.max, "Buffer too large!"); + bufs[n].buf = cast(char*)buffer.ptr; + bufs[n++].len = cast(uint)buffer.length; + } + if (n > 0) + { + int r = WSASendTo(socket.handle, bufs.ptr, n, &sent, /+map_message_flags(flags)+/ 0, sock_addr, cast(int)addr_len, null, null); // there are no meaningful flags on Windows + if (r == SOCKET_ERROR) + return socket_getlasterror(); + } + if (bytes_sent) + *bytes_sent = sent; + return Result.success; } - if (bytesSent) - *bytesSent = sent; - return r; + else + return sendmsg(socket, address, MsgFlags.none, null, bytes_sent, buffers); } -Result recv(Socket socket, void[] buffer, MsgFlags flags = MsgFlags.None, size_t* bytesReceived) +Result sendmsg(Socket socket, const InetAddress* address, MsgFlags flags, const(void)[] control, size_t* bytes_sent, const void[][] buffers) { - Result r = Result.Success; - ptrdiff_t bytes = _recv(socket.handle, buffer.ptr, cast(int)buffer.length, map_message_flags(flags)); - if (bytes > 0) - *bytesReceived = bytes; + version (SocketCallbacks) + return Result(_socket_backend.sendmsg(socket, address, flags, buffers, bytes_sent)); else { - *bytesReceived = 0; - if (bytes == 0) + ubyte[sockaddr_storage.sizeof] tmp = void; + size_t addr_len; + sockaddr* sock_addr = null; + if (address) { - // if we request 0 bytes, we receive 0 bytes, and it doesn't imply end-of-stream - if (buffer.length > 0) + sock_addr = make_sockaddr(*address, tmp, addr_len); + assert(sock_addr, "Invalid socket address"); + } + + version (WinSock) + { + uint sent; + WSAMSG msg; + WSABUF[32] bufs = void; + assert(buffers.length <= bufs.length, "Too many buffers!"); + + uint n = 0; + foreach(buffer; buffers) { - // a graceful disconnection occurred - // TODO: !!! - r = ConnectionClosedResult; -// r = InternalResult(InternalCode.RemoteDisconnected); + if (buffer.length == 0) + continue; + assert(buffer.length <= uint.max, "Buffer too large!"); + bufs[n].buf = cast(char*)buffer.ptr; + bufs[n++].len = cast(uint)buffer.length; + } + if (n > 0) + { + msg.name = sock_addr; + msg.namelen = cast(int)addr_len; + msg.lpBuffers = bufs.ptr; + msg.dwBufferCount = n; + msg.Control.buf = cast(char*)control.ptr; + msg.Control.len = cast(uint)control.length; + msg.dwFlags = 0; + + int rc = WSASendMsg(socket.handle, &msg, /+map_message_flags(flags)+/ 0, &sent, null, null); // there are no meaningful flags on Windows + if (rc == SOCKET_ERROR) + return socket_getlasterror(); } } else { - Result error = socket_getlasterror(); - // TODO: Do we want a better way to distinguish between receiving a 0-length packet vs no-data (which looks like an error)? - // Is a zero-length packet possible to detect in TCP streams? Makes more sense for recvfrom... - SocketResult sr = get_SocketResult(error); - if (sr != SocketResult.WouldBlock) - r = error; + ptrdiff_t sent; + msghdr hdr; + iovec[32] iov = void; + assert(buffers.length <= iov.length, "Too many buffers!"); + + size_t n = 0; + foreach(buffer; buffers) + { + if (buffer.length == 0) + continue; + assert(buffer.length <= uint.max, "Buffer too large!"); + iov[n].iov_base = cast(void*)buffer.ptr; + iov[n++].iov_len = buffer.length; + } + if (n > 0) + { + hdr.msg_name = sock_addr; + hdr.msg_namelen = cast(socklen_t)addr_len; + hdr.msg_iov = iov.ptr; + hdr.msg_iovlen = cast(typeof(hdr.msg_iovlen))n; + hdr.msg_control = cast(void*)control.ptr; + hdr.msg_controllen = cast(typeof(hdr.msg_controllen))control.length; + hdr.msg_flags = 0; + + sent = _sendmsg(socket.handle, &hdr, map_message_flags(flags)); + if (sent < 0) + return socket_getlasterror(); + } } + if (bytes_sent) + *bytes_sent = sent; + return Result.success; } - return r; } -Result recvfrom(Socket socket, void[] buffer, MsgFlags flags = MsgFlags.None, InetAddress* senderAddress = null, size_t* bytesReceived) +Result pending(Socket socket, out size_t bytes_available) { - char[sockaddr_storage.sizeof] addrBuffer = void; - sockaddr* addr = cast(sockaddr*)addrBuffer.ptr; - socklen_t size = addrBuffer.sizeof; - - Result r = Result.Success; - ptrdiff_t bytes = _recvfrom(socket.handle, buffer.ptr, cast(int)buffer.length, map_message_flags(flags), addr, &size); - if (bytes >= 0) - *bytesReceived = bytes; + version (SocketCallbacks) + return Result(_socket_backend.pending(socket, bytes_available)); else { - *bytesReceived = 0; - - Result error = socket_getlasterror(); - SocketResult sockRes = get_SocketResult(error); - if (sockRes != SocketResult.NoBuffer && // buffers full - sockRes != SocketResult.ConnectionRefused && // posix error - sockRes != SocketResult.ConnectionReset) // !!! windows may report this error, but it appears to mean something different on posix - r = error; + version (WinSock) + { + import urt.internal.sys.windows.winsock2 : ioctlsocket, FIONREAD; + uint avail; + if (ioctlsocket(socket.handle, FIONREAD, &avail) != 0) + return socket_getlasterror(); + bytes_available = avail; + } + else version (Posix) + { + import urt.internal.os : ioctl; + int avail; + if (ioctl(socket.handle, 0x541B, &avail) < 0) // FIONREAD + return socket_getlasterror(); + bytes_available = avail; + } + else version (lwIP) + { + uint avail; + if (ioctlsocket(socket.handle, FIONREAD, &avail) != 0) + return socket_getlasterror(); + bytes_available = avail; + } + else + static assert(false, "Platform not supported"); + return Result.success; } - if (r && senderAddress) - *senderAddress = make_InetAddress(addr); - return r; } -Result set_socket_option(Socket socket, SocketOption option, const(void)* optval, size_t optlen) +Result recv(Socket socket, void[] buffer, MsgFlags flags = MsgFlags.none, size_t* bytes_received) { - Result r = Result.Success; - - // check the option appears to be the proper datatype - const OptInfo* optInfo = &s_socketOptions[option]; - assert(optInfo.rtType != OptType.Unsupported, "Socket option is unsupported on this platform!"); - assert(optlen == s_optTypeRtSize[optInfo.rtType], "Socket option has incorrect payload size!"); - - // special case for non-blocking - // this is not strictly a 'socket option', but this rather simplifies our API - if (option == SocketOption.NonBlocking) + version (SocketCallbacks) + return Result(_socket_backend.recv(socket, buffer, flags, bytes_received)); + else { - bool value = *cast(const(bool)*)optval; - version (Windows) + Result r = Result.success; + ptrdiff_t bytes = _recv(socket.handle, buffer.ptr, cast(int)buffer.length, map_message_flags(flags)); + if (bytes > 0) + *bytes_received = bytes; + else { - uint opt = value ? 1 : 0; - r.systemCode = ioctlsocket(socket.handle, FIONBIO, &opt); + *bytes_received = 0; + if (bytes == 0) + { + // if we request 0 bytes, we receive 0 bytes, and it doesn't imply end-of-stream + if (buffer.length > 0) + { + // a graceful disconnection occurred + // TODO: !!! + r = ConnectionClosedResult; +// r = InternalResult(InternalCode.RemoteDisconnected); + } + } + else + { + Result error = socket_getlasterror(); + // TODO: Do we want a better way to distinguish between receiving a 0-length packet vs no-data (which looks like an error)? + // Is a zero-length packet possible to detect in TCP streams? Makes more sense for recvfrom... + SocketResult sr = socket_result(error); + if (sr != SocketResult.would_block) + r = error; + } } - else version (Posix) + return r; + } +} + +Result recvfrom(Socket socket, void[] buffer, MsgFlags flags = MsgFlags.none, InetAddress* sender_address = null, size_t* bytes_received, InetAddress* local_address = null) +{ + version (SocketCallbacks) + { + assert(local_address is null, "local_address not supported on callback backend"); + return Result(_socket_backend.recvfrom(socket, buffer, flags, sender_address, bytes_received)); + } + else + { + char[sockaddr_storage.sizeof] addr_buffer = void; + sockaddr* addr = cast(sockaddr*)addr_buffer.ptr; + + if (local_address) { - int flags = fcntl(socket.handle, F_GETFL, 0); - r.systemCode = fcntl(socket.handle, F_SETFL, value ? (flags | O_NONBLOCK) : (flags & ~O_NONBLOCK)); + version (WinSock) + { + assert(WSARecvMsg, "WSARecvMsg not available!"); + + void[1500] ctrl = void; // HUGE BUFFER! + + WSABUF msg_buf; + msg_buf.buf = cast(char*)buffer.ptr; + msg_buf.len = cast(uint)buffer.length; + + WSAMSG msg; + msg.name = addr; + msg.namelen = addr_buffer.sizeof; + msg.lpBuffers = &msg_buf; + msg.dwBufferCount = 1; + msg.Control.buf = cast(char*)ctrl.ptr; + msg.Control.len = cast(uint)ctrl.length; + msg.dwFlags = 0; + uint bytes; + int r = WSARecvMsg(socket.handle, &msg, &bytes, null, null); + if (r == 0) + *bytes_received = bytes; + else + { + *bytes_received = 0; + goto fail; + } + + // parse the control messages + *local_address = InetAddress(); + for (WSACMSGHDR* c = WSA_CMSG_FIRSTHDR(&msg); c != null; c = WSA_CMSG_NXTHDR(&msg, c)) + { + if (c.cmsg_level == IPPROTO_IP && c.cmsg_type == IP_PKTINFO) + { + IN_PKTINFO* pk = cast(IN_PKTINFO*)WSA_CMSG_DATA(c); + *local_address = InetAddress(make_IPAddr(pk.ipi_addr), 0); // TODO: be nice to populate the listening port... + // pk.ipi_ifindex = receiving interface index + } + if (c.cmsg_level == IPPROTO_IPV6 && c.cmsg_type == IPV6_PKTINFO) + { + IN6_PKTINFO* pk6 = cast(IN6_PKTINFO*)WSA_CMSG_DATA(c); + *local_address = InetAddress(make_IPv6Addr(pk6.ipi6_addr), 0); // TODO: be nice to populate the listening port... + // pk6.ipi6_ifindex = receiving interface index + } + } + } + else + { + assert(false, "TODO: call recvmsg and all that..."); + } } else - assert(false, "Not implemented!"); - return r; + { + socklen_t size = addr_buffer.sizeof; + ptrdiff_t bytes = _recvfrom(socket.handle, buffer.ptr, cast(int)buffer.length, map_message_flags(flags), addr, &size); + if (bytes >= 0) + *bytes_received = bytes; + else + { + *bytes_received = 0; + goto fail; + } + } + + if (sender_address) + *sender_address = make_InetAddress(addr); + return Result.success; + + fail: + Result error = socket_getlasterror(); + SocketResult sockRes = socket_result(error); + if (sockRes != SocketResult.no_buffer && // buffers full + sockRes != SocketResult.connection_refused && // posix error + sockRes != SocketResult.connection_reset) // !!! windows may report this error, but it appears to mean something different on posix + return error; + return Result.success; } +} -// // Convenience for socket-level no signal since some platforms only support message flag -// if (option == SocketOption.NoSigPipe) -// { -// LockGuard!SharedMutex lock(s_noSignalMut); -// s_noSignal.InsertOrAssign(socket.handle, *cast(const(bool)*)optval); -// -// if (optInfo.platformType == OptType.Unsupported) -// return r; -// } - - // determine the option 'level' - OptLevel level = get_optlevel(option); - version (HasIPv6) {} else - assert(level != OptLevel.IPv6 && level != OptLevel.ICMPv6, "Platform does not support IPv6!"); - - // platforms don't all agree on option data formats! - const(void)* arg = optval; - int itmp = void; - linger ling = void; - if (optInfo.rtType != optInfo.platformType) +Result set_socket_option(Socket socket, SocketOption option, const(void)* optval, size_t optlen) +{ + version (SocketCallbacks) + return Result(_socket_backend.set_option(socket, option, optval, optlen)); + else { - switch (optInfo.rtType) + Result r = Result.success; + + // check the option appears to be the proper datatype + const OptInfo* opt_info = &s_socketOptions[option]; + assert(opt_info.rt_type != OptType.unsupported, "Socket option is unsupported on this platform!"); + assert(optlen == s_optTypeRtSize[opt_info.rt_type], "Socket option has incorrect payload size!"); + + // special case for non-blocking + // this is not strictly a 'socket option', but this rather simplifies our API + if (option == SocketOption.non_blocking) { - // TODO: there are more converstions necessary as options/platforms are added - case OptType.Bool: + bool value = *cast(const(bool)*)optval; + version (WinSock) { - const bool value = *cast(const(bool)*)optval; - switch (optInfo.platformType) + uint opt = value ? 1 : 0; + r.system_code = ioctlsocket(socket.handle, FIONBIO, &opt); + } + else version (BSDSockets) + { + version (lwIP) { - case OptType.Int: - itmp = value ? 1 : 0; - arg = &itmp; - break; - default: assert(false, "Unexpected"); + // lwIP's fcntl has quirks with F_SETFL; use ioctlsocket(FIONBIO) instead. + int opt = value ? 1 : 0; + r.system_code = ioctlsocket(socket.handle, FIONBIO, &opt); + } + else + { + int flags = fcntl(socket.handle, F_GETFL, 0); + r.system_code = fcntl(socket.handle, F_SETFL, value ? (flags | O_NONBLOCK) : (flags & ~O_NONBLOCK)); } - break; } - case OptType.Duration: + else + assert(false, "Not implemented!"); + return r; + } + +// // Convenience for socket-level no signal since some platforms only support message flag +// if (option == SocketOption.NoSigPipe) +// { +// LockGuard!SharedMutex lock(s_noSignalMut); +// s_noSignal.InsertOrAssign(socket.handle, *cast(const(bool)*)optval); +// +// if (opt_info.platform_type == OptType.unsupported) +// return r; +// } + + // determine the option 'level' + OptLevel level = get_optlevel(option); + version (HasIPv6) {} else + assert(level != OptLevel.ipv6 && level != OptLevel.icmpv6, "Platform does not support IPv6!"); + + // platforms don't all agree on option data formats! + const(void)* arg = optval; + int itmp = void; + linger ling = void; + if (opt_info.rt_type != opt_info.platform_type) + { + switch (opt_info.rt_type) { - const Duration value = *cast(const(Duration)*)optval; - switch (optInfo.platformType) + // TODO: there are more converstions necessary as options/platforms are added + case OptType.bool_: { - case OptType.Seconds: - itmp = cast(int)value.as!"seconds"; - arg = &itmp; - break; - case OptType.Milliseconds: - itmp = cast(int)value.as!"msecs"; - arg = &itmp; - break; - case OptType.Linger: - itmp = cast(int)value.as!"seconds"; - ling = linger(!!itmp, cast(ushort)itmp); - arg = &ling; - break; - default: assert(false, "Unexpected"); + const bool value = *cast(const(bool)*)optval; + switch (opt_info.platform_type) + { + case OptType.int_: + itmp = value ? 1 : 0; + arg = &itmp; + break; + default: assert(false, "Unexpected"); + } + break; } - break; + case OptType.duration: + { + const Duration value = *cast(const(Duration)*)optval; + switch (opt_info.platform_type) + { + case OptType.seconds: + itmp = cast(int)value.as!"seconds"; + arg = &itmp; + break; + case OptType.milliseconds: + itmp = cast(int)value.as!"msecs"; + arg = &itmp; + break; + case OptType.linger: + itmp = cast(int)value.as!"seconds"; + ling = linger(!!itmp, cast(typeof(linger.l_linger))itmp); + arg = &ling; + break; + default: assert(false, "Unexpected"); + } + break; + } + default: + assert(false, "Unexpected!"); } - default: - assert(false, "Unexpected!"); } - } - // set the option - r.systemCode = setsockopt(socket.handle, s_sockOptLevel[level], optInfo.option, cast(const(char)*)arg, s_optTypePlatformSize[optInfo.platformType]); + // set the option + r.system_code = setsockopt(socket.handle, s_sockOptLevel[level], opt_info.option, cast(const(char)*)arg, s_optTypePlatformSize[opt_info.platform_type]); - return r; + return r; + } } Result set_socket_option(Socket socket, SocketOption option, bool value) { - const OptInfo* optInfo = &s_socketOptions[option]; - if (optInfo.rtType == OptType.Unsupported) - return InternalResult(InternalCode.Unsupported); - assert(optInfo.rtType == OptType.Bool, "Incorrect value type for option"); - return set_socket_option(socket, option, &value, bool.sizeof); + version (SocketCallbacks) + return set_socket_option(socket, option, &value, bool.sizeof); + else + { + const OptInfo* opt_info = &s_socketOptions[option]; + if (opt_info.rt_type == OptType.unsupported) + return InternalResult.unsupported; + assert(opt_info.rt_type == OptType.bool_, "Incorrect value type for option"); + return set_socket_option(socket, option, &value, bool.sizeof); + } } Result set_socket_option(Socket socket, SocketOption option, int value) { - const OptInfo* optInfo = &s_socketOptions[option]; - if (optInfo.rtType == OptType.Unsupported) - return InternalResult(InternalCode.Unsupported); - assert(optInfo.rtType == OptType.Int, "Incorrect value type for option"); - return set_socket_option(socket, option, &value, int.sizeof); + version (SocketCallbacks) + return set_socket_option(socket, option, &value, int.sizeof); + else + { + const OptInfo* opt_info = &s_socketOptions[option]; + if (opt_info.rt_type == OptType.unsupported) + return InternalResult.unsupported; + assert(opt_info.rt_type == OptType.int_, "Incorrect value type for option"); + return set_socket_option(socket, option, &value, int.sizeof); + } } Result set_socket_option(Socket socket, SocketOption option, Duration value) { - const OptInfo* optInfo = &s_socketOptions[option]; - if (optInfo.rtType == OptType.Unsupported) - return InternalResult(InternalCode.Unsupported); - assert(optInfo.rtType == OptType.Duration, "Incorrect value type for option"); - return set_socket_option(socket, option, &value, Duration.sizeof); + version (SocketCallbacks) + return set_socket_option(socket, option, &value, Duration.sizeof); + else + { + const OptInfo* opt_info = &s_socketOptions[option]; + if (opt_info.rt_type == OptType.unsupported) + return InternalResult.unsupported; + assert(opt_info.rt_type == OptType.duration, "Incorrect value type for option"); + return set_socket_option(socket, option, &value, Duration.sizeof); + } } Result set_socket_option(Socket socket, SocketOption option, IPAddr value) { - const OptInfo* optInfo = &s_socketOptions[option]; - if (optInfo.rtType == OptType.Unsupported) - return InternalResult(InternalCode.Unsupported); - assert(optInfo.rtType == OptType.INAddress, "Incorrect value type for option"); - return set_socket_option(socket, option, &value, IPAddr.sizeof); + version (SocketCallbacks) + return set_socket_option(socket, option, &value, IPAddr.sizeof); + else + { + const OptInfo* opt_info = &s_socketOptions[option]; + if (opt_info.rt_type == OptType.unsupported) + return InternalResult.unsupported; + assert(opt_info.rt_type == OptType.inet_addr, "Incorrect value type for option"); + return set_socket_option(socket, option, &value, IPAddr.sizeof); + } } Result set_socket_option(Socket socket, SocketOption option, ref MulticastGroup value) { - const OptInfo* optInfo = &s_socketOptions[option]; - if (optInfo.rtType == OptType.Unsupported) - return InternalResult(InternalCode.Unsupported); - assert(optInfo.rtType == OptType.MulticastGroup, "Incorrect value type for option"); - return set_socket_option(socket, option, &value, MulticastGroup.sizeof); + version (SocketCallbacks) + return set_socket_option(socket, option, &value, MulticastGroup.sizeof); + else + { + const OptInfo* opt_info = &s_socketOptions[option]; + if (opt_info.rt_type == OptType.unsupported) + return InternalResult.unsupported; + assert(opt_info.rt_type == OptType.multicast_group, "Incorrect value type for option"); + return set_socket_option(socket, option, &value, MulticastGroup.sizeof); + } } Result get_socket_option(Socket socket, SocketOption option, void* output, size_t outputlen) { - Result r = Result.Success; + version (SocketCallbacks) + return Result(_socket_backend.get_option(socket, option, output, outputlen)); + else + { + Result r = Result.success; - // check the option appears to be the proper datatype - const OptInfo* optInfo = &s_socketOptions[option]; - assert(optInfo.rtType != OptType.Unsupported, "Socket option is unsupported on this platform!"); - assert(outputlen == s_optTypeRtSize[optInfo.rtType], "Socket option has incorrect payload size!"); + // check the option appears to be the proper datatype + const OptInfo* opt_info = &s_socketOptions[option]; + assert(opt_info.rt_type != OptType.unsupported, "Socket option is unsupported on this platform!"); + assert(outputlen == s_optTypeRtSize[opt_info.rt_type], "Socket option has incorrect payload size!"); - assert(option != SocketOption.NonBlocking, "Socket option NonBlocking cannot be get"); + assert(option != SocketOption.non_blocking, "Socket option NonBlocking cannot be get"); - // determine the option 'level' - OptLevel level = get_optlevel(option); - version (HasIPv6) - assert(level != OptLevel.IPv6 && level != OptLevel.ICMPv6, "Platform does not support IPv6!"); + // determine the option 'level' + OptLevel level = get_optlevel(option); + version (HasIPv6) {} else + assert(level != OptLevel.ipv6 && level != OptLevel.icmpv6, "Platform does not support IPv6!"); - // platforms don't all agree on option data formats! - void* arg = output; - int itmp = 0; - linger ling = { 0, 0 }; - if (optInfo.rtType != optInfo.platformType) - { - switch (optInfo.platformType) + // platforms don't all agree on option data formats! + void* arg = output; + int itmp = 0; + linger ling = { 0, 0 }; + if (opt_info.rt_type != opt_info.platform_type) { - case OptType.Int: - case OptType.Seconds: - case OptType.Milliseconds: + switch (opt_info.platform_type) { - arg = &itmp; - break; - } - case OptType.Linger: - { - arg = &ling; - break; + case OptType.int_: + case OptType.seconds: + case OptType.milliseconds: + { + arg = &itmp; + break; + } + case OptType.linger: + { + arg = &ling; + break; + } + default: + assert(false, "Unexpected!"); } - default: - assert(false, "Unexpected!"); } - } - socklen_t writtenLen = s_optTypePlatformSize[optInfo.platformType]; - // get the option - r.systemCode = getsockopt(socket.handle, s_sockOptLevel[level], optInfo.option, cast(char*)arg, &writtenLen); + socklen_t writtenLen = s_optTypePlatformSize[opt_info.platform_type]; + // get the option + r.system_code = getsockopt(socket.handle, s_sockOptLevel[level], opt_info.option, cast(char*)arg, &writtenLen); - if (optInfo.rtType != optInfo.platformType) - { - switch (optInfo.rtType) + if (opt_info.rt_type != opt_info.platform_type) { - // TODO: there are more converstions necessary as options/platforms are added - case OptType.Bool: + switch (opt_info.rt_type) { - bool* value = cast(bool*)output; - switch (optInfo.platformType) + // TODO: there are more converstions necessary as options/platforms are added + case OptType.bool_: { - case OptType.Int: - *value = !!itmp; - break; - default: assert(false, "Unexpected"); + bool* value = cast(bool*)output; + switch (opt_info.platform_type) + { + case OptType.int_: + *value = !!itmp; + break; + default: assert(false, "Unexpected"); + } + break; } - break; - } - case OptType.Duration: - { - Duration* value = cast(Duration*)output; - switch (optInfo.platformType) + case OptType.duration: { - case OptType.Seconds: - *value = seconds(itmp); - break; - case OptType.Milliseconds: - *value = msecs(itmp); - break; - case OptType.Linger: - *value = seconds(ling.l_linger); - break; - default: assert(false, "Unexpected"); + Duration* value = cast(Duration*)output; + switch (opt_info.platform_type) + { + case OptType.seconds: + *value = seconds(itmp); + break; + case OptType.milliseconds: + *value = msecs(itmp); + break; + case OptType.linger: + *value = seconds(ling.l_linger); + break; + default: assert(false, "Unexpected"); + } + break; } - break; + default: + assert(false, "Unexpected!"); } - default: - assert(false, "Unexpected!"); } - } - assert(optInfo.rtType != OptType.INAddress, "TODO: uncomment this block... for some reason, this block causes DMD to do a bad codegen!"); + assert(opt_info.rt_type != OptType.inet_addr, "TODO: uncomment this block... for some reason, this block causes DMD to do a bad codegen!"); /+ - // Options expected in network-byte order - switch (optInfo.rtType) - { - case OptType.INAddress: + // Options expected in network-byte order + switch (opt_info.rt_type) { - IPAddr* addr = cast(IPAddr*)output; - addr.address = loadBigEndian(&addr.address()); - break; + case OptType.INAddress: + { + IPAddr* addr = cast(IPAddr*)output; + addr.address = loadBigEndian(&addr.address()); + break; + } + default: + break; } - default: - break; - } +/ - return r; + return r; + } } Result get_socket_option(Socket socket, SocketOption option, out bool output) { - const OptInfo* optInfo = &s_socketOptions[option]; - if (optInfo.rtType == OptType.Unsupported) - return InternalResult(InternalCode.Unsupported); - assert(optInfo.rtType == OptType.Bool, "Incorrect value type for option"); - return get_socket_option(socket, option, &output, bool.sizeof); + version (SocketCallbacks) + return get_socket_option(socket, option, &output, bool.sizeof); + else + { + const OptInfo* opt_info = &s_socketOptions[option]; + if (opt_info.rt_type == OptType.unsupported) + return InternalResult.unsupported; + assert(opt_info.rt_type == OptType.bool_, "Incorrect value type for option"); + return get_socket_option(socket, option, &output, bool.sizeof); + } } Result get_socket_option(Socket socket, SocketOption option, out int output) { - const OptInfo* optInfo = &s_socketOptions[option]; - if (optInfo.rtType == OptType.Unsupported) - return InternalResult(InternalCode.Unsupported); - assert(optInfo.rtType == OptType.Int, "Incorrect value type for option"); - return get_socket_option(socket, option, &output, int.sizeof); + version (SocketCallbacks) + return get_socket_option(socket, option, &output, int.sizeof); + else + { + const OptInfo* opt_info = &s_socketOptions[option]; + if (opt_info.rt_type == OptType.unsupported) + return InternalResult.unsupported; + assert(opt_info.rt_type == OptType.int_, "Incorrect value type for option"); + return get_socket_option(socket, option, &output, int.sizeof); + } } Result get_socket_option(Socket socket, SocketOption option, out Duration output) { - const OptInfo* optInfo = &s_socketOptions[option]; - if (optInfo.rtType == OptType.Unsupported) - return InternalResult(InternalCode.Unsupported); - assert(optInfo.rtType == OptType.Duration, "Incorrect value type for option"); - return get_socket_option(socket, option, &output, Duration.sizeof); + version (SocketCallbacks) + return get_socket_option(socket, option, &output, Duration.sizeof); + else + { + const OptInfo* opt_info = &s_socketOptions[option]; + if (opt_info.rt_type == OptType.unsupported) + return InternalResult.unsupported; + assert(opt_info.rt_type == OptType.duration, "Incorrect value type for option"); + return get_socket_option(socket, option, &output, Duration.sizeof); + } } Result get_socket_option(Socket socket, SocketOption option, out IPAddr output) { - const OptInfo* optInfo = &s_socketOptions[option]; - if (optInfo.rtType == OptType.Unsupported) - return InternalResult(InternalCode.Unsupported); - assert(optInfo.rtType == OptType.INAddress, "Incorrect value type for option"); - return get_socket_option(socket, option, &output, IPAddr.sizeof); + version (SocketCallbacks) + return get_socket_option(socket, option, &output, IPAddr.sizeof); + else + { + const OptInfo* opt_info = &s_socketOptions[option]; + if (opt_info.rt_type == OptType.unsupported) + return InternalResult.unsupported; + assert(opt_info.rt_type == OptType.inet_addr, "Incorrect value type for option"); + return get_socket_option(socket, option, &output, IPAddr.sizeof); + } } Result set_keepalive(Socket socket, bool enable, Duration keepIdle, Duration keepInterval, int keepCount) { - version (Windows) + version (WinSock) { tcp_keepalive alive; alive.onoff = enable ? 1 : 0; @@ -680,71 +1224,85 @@ Result set_keepalive(Socket socket, bool enable, Duration keepIdle, Duration kee uint bytesReturned = 0; if (WSAIoctl(socket.handle, SIO_KEEPALIVE_VALS, &alive, alive.sizeof, null, 0, &bytesReturned, null, null) < 0) return socket_getlasterror(); - return Result.Success; + return Result.success; } else { - Result res = set_socket_option(socket, SocketOption.KeepAlive, enable); - if (!enable || res != Result.Success) + Result res = set_socket_option(socket, SocketOption.keep_alive, enable); + if (!enable || res != Result.success) return res; version (Darwin) { // OSX doesn't support setting keep-alive interval and probe count. - return set_socket_option(socket, SocketOption.TCP_KeepAlive, keepIdle); + return set_socket_option(socket, SocketOption.tcp_keep_alive, keepIdle); } else { - res = set_socket_option(socket, SocketOption.TCP_KeepIdle, keepIdle); - if (res != Result.Success) + res = set_socket_option(socket, SocketOption.tcp_keep_idle, keepIdle); + if (res != Result.success) return res; - res = set_socket_option(socket, SocketOption.TCP_KeepIntvl, keepInterval); - if (res != Result.Success) + res = set_socket_option(socket, SocketOption.tcp_keep_intvl, keepInterval); + if (res != Result.success) return res; - return set_socket_option(socket, SocketOption.TCP_KeepCnt, keepCount); + return set_socket_option(socket, SocketOption.tcp_keep_cnt, keepCount); } } } Result get_peer_name(Socket socket, out InetAddress name) { - char[sockaddr_storage.sizeof] buffer; - sockaddr* addr = cast(sockaddr*)buffer; - socklen_t bufferLen = buffer.sizeof; - - int fail = getpeername(socket.handle, addr, &bufferLen); - if (fail == 0) - name = make_InetAddress(addr); + version (SocketCallbacks) + return Result(_socket_backend.get_peer_name(socket, name)); else - return socket_getlasterror(); - return Result.Success; + { + char[sockaddr_storage.sizeof] buffer; + sockaddr* addr = cast(sockaddr*)buffer; + socklen_t bufferLen = buffer.sizeof; + + int fail = getpeername(socket.handle, addr, &bufferLen); + if (fail == 0) + name = make_InetAddress(addr); + else + return socket_getlasterror(); + return Result.success; + } } Result get_socket_name(Socket socket, out InetAddress name) { - char[sockaddr_storage.sizeof] buffer; - sockaddr* addr = cast(sockaddr*)buffer; - socklen_t bufferLen = buffer.sizeof; - - int fail = getsockname(socket.handle, addr, &bufferLen); - if (fail == 0) - name = make_InetAddress(addr); + version (SocketCallbacks) + return Result(_socket_backend.get_socket_name(socket, name)); else - return socket_getlasterror(); - return Result.Success; + { + char[sockaddr_storage.sizeof] buffer; + sockaddr* addr = cast(sockaddr*)buffer; + socklen_t bufferLen = buffer.sizeof; + + int fail = getsockname(socket.handle, addr, &bufferLen); + if (fail == 0) + name = make_InetAddress(addr); + else + return socket_getlasterror(); + return Result.success; + } } Result get_hostname(char* name, size_t len) { - int fail = gethostname(name, cast(int)len); - if (fail) - return socket_getlasterror(); - return Result.Success; + version (SocketCallbacks) + return Result(_socket_backend.get_hostname(name, len)); + else + { + int fail = gethostname(name, cast(int)len); + if (fail) + return socket_getlasterror(); + return Result.success; + } } Result get_address_info(const(char)[] nodeName, const(char)[] service, AddressInfo* hints, out AddressInfoResolver result) { - import urt.array : findFirst; - import urt.mem.temp : tstringz; + import urt.string : findFirst; size_t colon = nodeName.findFirst(':'); if (colon < nodeName.length) @@ -754,72 +1312,89 @@ Result get_address_info(const(char)[] nodeName, const(char)[] service, AddressIn nodeName = nodeName[0 .. colon]; } - addrinfo tmpHints; - if (hints) + version (SocketCallbacks) { - // translate hints... - tmpHints.ai_flags = map_addrinfo_flags(hints.flags); - tmpHints.ai_family = s_addressFamily[hints.family]; - tmpHints.ai_socktype = s_socketType[hints.sockType]; - tmpHints.ai_protocol = s_protocol[hints.protocol]; - tmpHints.ai_canonname = cast(char*)hints.canonName; // HAX! - tmpHints.ai_addrlen = 0; - tmpHints.ai_addr = null; - tmpHints.ai_next = null; + // Backend fills the resolver with a defaultAllocator-allocated + // array of AddressInfo entries (sentinel-terminated). + return Result(_socket_backend.get_address_info(nodeName, service, hints, &result)); } + else + { + import urt.mem.temp : tstringz; - addrinfo* res; - int err = getaddrinfo(nodeName.tstringz, service ? service.tstringz : null, hints ? &tmpHints : null, &res); - if (err != 0) - return Result(err); + addrinfo tmpHints; + if (hints) + { + // translate hints... + tmpHints.ai_flags = map_addrinfo_flags(hints.flags); + tmpHints.ai_family = s_addressFamily[hints.family]; + tmpHints.ai_socktype = s_socketType[hints.sock_type]; + tmpHints.ai_protocol = s_protocol[hints.protocol]; + tmpHints.ai_canonname = cast(char*)hints.canon_name; // HAX! + tmpHints.ai_addrlen = 0; + tmpHints.ai_addr = null; + tmpHints.ai_next = null; + } + + addrinfo* res; + int err = getaddrinfo(nodeName.tstringz, service ? service.tstringz : null, hints ? &tmpHints : null, &res); + if (err != 0) + return Result(err); - // if it was used previously - if (result.m_internal[0]) - freeaddrinfo(cast(addrinfo*)result.m_internal[0]); + // if it was used previously + if (result.m_internal[0]) + freeaddrinfo(cast(addrinfo*)result.m_internal[0]); - result.m_internal[0] = res; - result.m_internal[1] = res; + result.m_internal[0] = res; + result.m_internal[1] = res; - return Result.Success; + return Result.success; + } } Result poll(PollFd[] pollFds, Duration timeout, out uint numEvents) { - enum MaxFds = 512; - assert(pollFds.length <= MaxFds, "Too many fds!"); - version (Windows) - WSAPOLLFD[MaxFds] fds; - else version (Posix) - pollfd[MaxFds] fds; - for (size_t i = 0; i < pollFds.length; ++i) - { - fds[i].fd = pollFds[i].socket.handle; - fds[i].revents = 0; - fds[i].events = ((pollFds[i].requestEvents & PollEvents.Read) ? POLLRDNORM : 0) | - ((pollFds[i].requestEvents & PollEvents.Write) ? POLLWRNORM : 0); - } - version (Windows) - int r = WSAPoll(fds.ptr, cast(uint)pollFds.length, timeout.ticks < 0 ? -1 : cast(int)timeout.as!"msecs"); - else version (Posix) - int r = _poll(fds.ptr, pollFds.length, timeout.ticks < 0 ? -1 : cast(int)timeout.as!"msecs"); + version (SocketCallbacks) + return Result(_socket_backend.poll(pollFds, timeout, numEvents)); else - assert(false, "Not implemented!"); - if (r < 0) - { - numEvents = 0; - return socket_getlasterror(); - } - numEvents = r; - for (size_t i = 0; i < pollFds.length; ++i) { - pollFds[i].returnEvents = cast(PollEvents)( - ((fds[i].revents & POLLRDNORM) ? PollEvents.Read : 0) | - ((fds[i].revents & POLLWRNORM) ? PollEvents.Write : 0) | - ((fds[i].revents & POLLERR) ? PollEvents.Error : 0) | - ((fds[i].revents & POLLHUP) ? PollEvents.HangUp : 0) | - ((fds[i].revents & POLLNVAL) ? PollEvents.Invalid : 0)); + enum MaxFds = 512; + assert(pollFds.length <= MaxFds, "Too many fds!"); + version (WinSock) + WSAPOLLFD[MaxFds] fds; + else + pollfd[MaxFds] fds; + for (size_t i = 0; i < pollFds.length; ++i) + { + fds[i].fd = pollFds[i].socket.handle; + fds[i].revents = 0; + fds[i].events = cast(short)(((pollFds[i].request_events & PollEvents.read) ? POLLRDNORM : 0) | + ((pollFds[i].request_events & PollEvents.write) ? POLLWRNORM : 0)); + } + int r; + version (WinSock) + r = WSAPoll(fds.ptr, cast(uint)pollFds.length, timeout.ticks < 0 ? -1 : cast(int)timeout.as!"msecs"); + else version (BSDSockets) + r = _poll(fds.ptr, cast(uint)pollFds.length, timeout.ticks < 0 ? -1 : cast(int)timeout.as!"msecs"); + else + assert(false, "Not implemented!"); + if (r < 0) + { + numEvents = 0; + return socket_getlasterror(); + } + numEvents = r; + for (size_t i = 0; i < pollFds.length; ++i) + { + pollFds[i].return_events = cast(PollEvents)( + ((fds[i].revents & POLLRDNORM) ? PollEvents.read : 0) | + ((fds[i].revents & POLLWRNORM) ? PollEvents.write : 0) | + ((fds[i].revents & POLLERR) ? PollEvents.error : 0) | + ((fds[i].revents & POLLHUP) ? PollEvents.hangup : 0) | + ((fds[i].revents & POLLNVAL) ? PollEvents.invalid : 0)); + } + return Result.success; } - return Result.Success; } Result poll(ref PollFd pollFd, Duration timeout, out uint numEvents) @@ -831,9 +1406,9 @@ struct AddressInfo { AddressInfoFlags flags; AddressFamily family; - SocketType sockType; + SocketType sock_type; Protocol protocol; - const(char)* canonName; // Note: this memory is valid until the next call to `next_address`, or until `AddressInfoResolver` is destroyed + const(char)* canon_name; // Note: this memory is valid until the next call to `next_address`, or until `AddressInfoResolver` is destroyed InetAddress address; } @@ -853,7 +1428,12 @@ nothrow @nogc: ~this() { if (m_internal[0]) - freeaddrinfo(cast(addrinfo*)m_internal[0]); + { + version (SocketCallbacks) + _socket_backend.free_address_info(&this); + else + freeaddrinfo(cast(addrinfo*)m_internal[0]); + } } // TODO: this should be a MOVE ONLY assignment! @@ -875,16 +1455,21 @@ nothrow @nogc: if (!m_internal[1]) return false; - addrinfo* info = cast(addrinfo*)(m_internal[1]); - m_internal[1] = info.ai_next; - - addressInfo.flags = AddressInfoFlags.None; // info.ai_flags is only used for 'hints' - addressInfo.family = map_address_family(info.ai_family); - addressInfo.sockType = cast(int)info.ai_socktype ? map_socket_type(info.ai_socktype) : SocketType.Unknown; - addressInfo.protocol = map_protocol(info.ai_protocol); - addressInfo.canonName = info.ai_canonname; - addressInfo.address = make_InetAddress(info.ai_addr); - return true; + version (SocketCallbacks) + return _socket_backend.next_address(&this, addressInfo); + else + { + addrinfo* info = cast(addrinfo*)(m_internal[1]); + m_internal[1] = info.ai_next; + + addressInfo.flags = AddressInfoFlags.none; // info.ai_flags is only used for 'hints' + addressInfo.family = map_address_family(info.ai_family); + addressInfo.sock_type = cast(int)info.ai_socktype ? map_socket_type(info.ai_socktype) : SocketType.unknown; + addressInfo.protocol = map_protocol(info.ai_protocol); + addressInfo.canon_name = info.ai_canonname; + addressInfo.address = make_InetAddress(info.ai_addr); + return true; + } } void*[2] m_internal = [ null, null ]; @@ -893,135 +1478,199 @@ nothrow @nogc: struct PollFd { Socket socket; - PollEvents requestEvents; - PollEvents returnEvents; - void* userData; + PollEvents request_events; + PollEvents return_events; + void* user_data; } -Result socket_getlasterror() -{ - version (Windows) - return Result(WSAGetLastError()); - else - return Result(errno); -} - Result get_socket_error(Socket socket) { - Result r; - socklen_t optlen = r.systemCode.sizeof; - int callResult = getsockopt(socket.handle, SOL_SOCKET, SO_ERROR, cast(char*)&r.systemCode, &optlen); - if (callResult) - r.systemCode = callResult; - return r; + version (SocketCallbacks) + { + int err; + Result r = get_socket_option(socket, SocketOption.error, err); + if (r) + r.system_code = err; + return r; + } + else + { + Result r; + socklen_t optlen = r.system_code.sizeof; + int callResult = getsockopt(socket.handle, SOL_SOCKET, SO_ERROR, cast(char*)&r.system_code, &optlen); + if (callResult) + r.system_code = callResult; + return r; + } } // TODO: !!! -enum Result ConnectionClosedResult = Result(-12345); -SocketResult get_SocketResult(Result result) -{ - if (result) - return SocketResult.Success; - if (result.systemCode == ConnectionClosedResult.systemCode) - return SocketResult.ConnectionClosed; - version (Windows) - { - if (result.systemCode == WSAEWOULDBLOCK) - return SocketResult.WouldBlock; - if (result.systemCode == WSAEINPROGRESS) - return SocketResult.WouldBlock; - if (result.systemCode == WSAENOBUFS) - return SocketResult.NoBuffer; - if (result.systemCode == WSAENETDOWN) - return SocketResult.NetworkDown; - if (result.systemCode == WSAECONNREFUSED) - return SocketResult.ConnectionRefused; - if (result.systemCode == WSAECONNRESET) - return SocketResult.ConnectionReset; - if (result.systemCode == WSAEINTR) - return SocketResult.Interrupted; - if (result.systemCode == WSAENOTSOCK) - return SocketResult.InvalidSocket; - if (result.systemCode == WSAEINVAL) - return SocketResult.InvalidArgument; - } - else version (Posix) +enum Result ConnectionClosedResult = Result(-12345); +SocketResult socket_result(Result result) +{ + version (SocketCallbacks) + return cast(SocketResult)result.system_code; + else { - static if (EAGAIN != EWOULDBLOCK) - if (result.systemCode == EAGAIN) - return SocketResult.WouldBlock; - if (result.systemCode == EWOULDBLOCK) - return SocketResult.WouldBlock; - if (result.systemCode == EINPROGRESS) - return SocketResult.WouldBlock; - if (result.systemCode == ENOMEM) - return SocketResult.NoBuffer; - if (result.systemCode == ENETDOWN) - return SocketResult.NetworkDown; - if (result.systemCode == ECONNREFUSED) - return SocketResult.ConnectionRefused; - if (result.systemCode == ECONNRESET) - return SocketResult.ConnectionReset; - if (result.systemCode == EINTR) - return SocketResult.Interrupted; - if (result.systemCode == EINVAL) - return SocketResult.InvalidArgument; + if (result) + return SocketResult.success; + if (result.system_code == ConnectionClosedResult.system_code) + return SocketResult.connection_closed; + else version (WinSock) + { + if (result.system_code == WSAEWOULDBLOCK) + return SocketResult.would_block; + if (result.system_code == WSAEINPROGRESS) + return SocketResult.would_block; + if (result.system_code == WSAENOBUFS) + return SocketResult.no_buffer; + if (result.system_code == WSAENETDOWN) + return SocketResult.network_down; + if (result.system_code == WSAENETUNREACH) + return SocketResult.network_unreachable; + if (result.system_code == WSAEHOSTUNREACH) + return SocketResult.host_unreachable; + if (result.system_code == WSAECONNREFUSED) + return SocketResult.connection_refused; + if (result.system_code == WSAECONNRESET) + return SocketResult.connection_reset; + if (result.system_code == WSAECONNABORTED) + return SocketResult.connection_aborted; + if (result.system_code == WSAEADDRINUSE) + return SocketResult.address_in_use; + if (result.system_code == WSAEADDRNOTAVAIL) + return SocketResult.address_not_available; + if (result.system_code == WSAETIMEDOUT) + return SocketResult.timed_out; + if (result.system_code == WSAENOTCONN) + return SocketResult.not_connected; + if (result.system_code == WSAEISCONN) + return SocketResult.already_connected; + if (result.system_code == WSAEACCES) + return SocketResult.permission_denied; + if (result.system_code == WSAEINTR) + return SocketResult.interrupted; + if (result.system_code == WSAENOTSOCK) + return SocketResult.invalid_socket; + if (result.system_code == WSAEINVAL) + return SocketResult.invalid_argument; + } + else version (Errno) + { + import urt.internal.stdc.errno; + static if (EAGAIN != EWOULDBLOCK) + if (result.system_code == EAGAIN) + return SocketResult.would_block; + if (result.system_code == EWOULDBLOCK) + return SocketResult.would_block; + if (result.system_code == EINPROGRESS) + return SocketResult.would_block; + if (result.system_code == ENOMEM) + return SocketResult.no_buffer; + if (result.system_code == ENETDOWN) + return SocketResult.network_down; + if (result.system_code == ENETUNREACH) + return SocketResult.network_unreachable; + if (result.system_code == EHOSTUNREACH) + return SocketResult.host_unreachable; + if (result.system_code == ECONNREFUSED) + return SocketResult.connection_refused; + if (result.system_code == ECONNRESET) + return SocketResult.connection_reset; + if (result.system_code == ECONNABORTED) + return SocketResult.connection_aborted; + if (result.system_code == EADDRINUSE) + return SocketResult.address_in_use; + if (result.system_code == EADDRNOTAVAIL) + return SocketResult.address_not_available; + if (result.system_code == ETIMEDOUT) + return SocketResult.timed_out; + if (result.system_code == ENOTCONN) + return SocketResult.not_connected; + if (result.system_code == EISCONN) + return SocketResult.already_connected; + if (result.system_code == EACCES) + return SocketResult.permission_denied; + if (result.system_code == EINTR) + return SocketResult.interrupted; + if (result.system_code == EINVAL) + return SocketResult.invalid_argument; + } + return SocketResult.failure; } - return SocketResult.Failure; } +private: -sockaddr* make_sockaddr(ref const InetAddress address, ubyte[] buffer, out size_t addrLen) +version (SocketCallbacks) {} else { + +Result socket_getlasterror() +{ + version (WinSock) + return Result(WSAGetLastError()); + else version (Errno) + return errno_result(); + else + static assert(false, "socket_getlasterror not implemented for this platform"); +} + +sockaddr* make_sockaddr(ref const InetAddress address, ubyte[] buffer, out size_t addr_len) { - sockaddr* sockAddr = cast(sockaddr*)buffer.ptr; + sockaddr* sock_addr = cast(sockaddr*)buffer.ptr; switch (address.family) { - case AddressFamily.IPv4: + case AddressFamily.ipv4: { - addrLen = sockaddr_in.sizeof; + addr_len = sockaddr_in.sizeof; if (buffer.length < sockaddr_in.sizeof) return null; - sockaddr_in* ain = cast(sockaddr_in*)sockAddr; + sockaddr_in* ain = cast(sockaddr_in*)sock_addr; memzero(ain, sockaddr_in.sizeof); - ain.sin_family = s_addressFamily[AddressFamily.IPv4]; - version (Windows) + version (lwIP) + ain.sin_len = sockaddr_in.sizeof; + ain.sin_family = s_addressFamily[AddressFamily.ipv4]; + version (WinSock) { ain.sin_addr.S_un.S_un_b.s_b1 = address._a.ipv4.addr.b[0]; ain.sin_addr.S_un.S_un_b.s_b2 = address._a.ipv4.addr.b[1]; ain.sin_addr.S_un.S_un_b.s_b3 = address._a.ipv4.addr.b[2]; ain.sin_addr.S_un.S_un_b.s_b4 = address._a.ipv4.addr.b[3]; } - else version (Posix) + else version (BSDSockets) ain.sin_addr.s_addr = address._a.ipv4.addr.address; else assert(false, "Not implemented!"); storeBigEndian(&ain.sin_port, ushort(address._a.ipv4.port)); break; } - case AddressFamily.IPv6: + case AddressFamily.ipv6: { version (HasIPv6) { - addrLen = sockaddr_in6.sizeof; + addr_len = sockaddr_in6.sizeof; if (buffer.length < sockaddr_in6.sizeof) return null; - sockaddr_in6* ain6 = cast(sockaddr_in6*)sockAddr; + sockaddr_in6* ain6 = cast(sockaddr_in6*)sock_addr; memzero(ain6, sockaddr_in6.sizeof); - ain6.sin6_family = s_addressFamily[AddressFamily.IPv6]; + version (lwIP) + ain6.sin6_len = sockaddr_in6.sizeof; + ain6.sin6_family = s_addressFamily[AddressFamily.ipv6]; storeBigEndian(&ain6.sin6_port, cast(ushort)address._a.ipv6.port); - storeBigEndian(cast(uint*)&ain6.sin6_flowinfo, address._a.ipv6.flowInfo); + storeBigEndian(cast(uint*)&ain6.sin6_flowinfo, address._a.ipv6.flow_info); storeBigEndian(cast(uint*)&ain6.sin6_scope_id, address._a.ipv6.scopeId); for (int a = 0; a < 8; ++a) { - version (Windows) + version (WinSock) storeBigEndian(&ain6.sin6_addr.in6_u.u6_addr16[a], address._a.ipv6.addr.s[a]); else version (Posix) - storeBigEndian(cast(ushort*)ain6.sin6_addr.s6_addr + a, address._a.ipv6.addr.s[a]); + storeBigEndian(&ain6.sin6_addr.__in6_u.__u6_addr16[a], address._a.ipv6.addr.s[a]); + else version (BSDSockets) + storeBigEndian(cast(ushort*)&ain6.sin6_addr.s6_addr[a * 2], address._a.ipv6.addr.s[a]); else assert(false, "Not implemented!"); } @@ -1030,17 +1679,17 @@ sockaddr* make_sockaddr(ref const InetAddress address, ubyte[] buffer, out size_ assert(false, "Platform does not support IPv6!"); break; } - case AddressFamily.Unix: + case AddressFamily.unix: { // version (HasUnixSocket) // { -// addrLen = sockaddr_un.sizeof; +// addr_len = sockaddr_un.sizeof; // if (buffer.length < sockaddr_un.sizeof) // return null; // -// sockaddr_un* aun = cast(sockaddr_un*)sockAddr; +// sockaddr_un* aun = cast(sockaddr_un*)sock_addr; // memzero(aun, sockaddr_un.sizeof); -// aun.sun_family = s_addressFamily[AddressFamily.Unix]; +// aun.sun_family = s_addressFamily[AddressFamily.unix]; // // memcpy(aun.sun_path, address.un.path, UNIX_PATH_LEN); // break; @@ -1050,70 +1699,51 @@ sockaddr* make_sockaddr(ref const InetAddress address, ubyte[] buffer, out size_ } default: { - sockAddr = null; - addrLen = 0; + sock_addr = null; + addr_len = 0; assert(false, "Unsupported address family"); break; } } - return sockAddr; + return sock_addr; } -InetAddress make_InetAddress(const(sockaddr)* sockAddress) +InetAddress make_InetAddress(const(sockaddr)* sock_address) { InetAddress addr; - addr.family = map_address_family(sockAddress.sa_family); + addr.family = map_address_family(sock_address.sa_family); switch (addr.family) { - case AddressFamily.IPv4: + case AddressFamily.ipv4: { - const sockaddr_in* ain = cast(const(sockaddr_in)*)sockAddress; + const sockaddr_in* ain = cast(const(sockaddr_in)*)sock_address; addr._a.ipv4.port = loadBigEndian(&ain.sin_port); - version (Windows) - { - addr._a.ipv4.addr.b[0] = ain.sin_addr.S_un.S_un_b.s_b1; - addr._a.ipv4.addr.b[1] = ain.sin_addr.S_un.S_un_b.s_b2; - addr._a.ipv4.addr.b[2] = ain.sin_addr.S_un.S_un_b.s_b3; - addr._a.ipv4.addr.b[3] = ain.sin_addr.S_un.S_un_b.s_b4; - } - else version (Posix) - addr._a.ipv4.addr.address = ain.sin_addr.s_addr; - else - assert(false, "Not implemented!"); + addr._a.ipv4.addr = make_IPAddr(ain.sin_addr); break; } - case AddressFamily.IPv6: + case AddressFamily.ipv6: { version (HasIPv6) { - const sockaddr_in6* ain6 = cast(const(sockaddr_in6)*)sockAddress; + const sockaddr_in6* ain6 = cast(const(sockaddr_in6)*)sock_address; addr._a.ipv6.port = loadBigEndian(&ain6.sin6_port); - addr._a.ipv6.flowInfo = loadBigEndian(cast(const(uint)*)&ain6.sin6_flowinfo); + addr._a.ipv6.flow_info = loadBigEndian(cast(const(uint)*)&ain6.sin6_flowinfo); addr._a.ipv6.scopeId = loadBigEndian(cast(const(uint)*)&ain6.sin6_scope_id); - - for (int a = 0; a < 8; ++a) - { - version (Windows) - addr._a.ipv6.addr.s[a] = loadBigEndian(&ain6.sin6_addr.in6_u.u6_addr16[a]); - else version (Posix) - addr._a.ipv6.addr.s[a] = loadBigEndian(cast(const(ushort)*)ain6.sin6_addr.s6_addr + a); - else - assert(false, "Not implemented!"); - } + addr._a.ipv6.addr = make_IPv6Addr(ain6.sin6_addr); } else assert(false, "Platform does not support IPv6!"); break; } - case AddressFamily.Unix: + case AddressFamily.unix: { // version (HasUnixSocket) // { -// const sockaddr_un* aun = cast(const(sockaddr_un)*)sockAddress; +// const sockaddr_un* aun = cast(const(sockaddr_un)*)sock_address; // // memcpy(addr.un.path, aun.sun_path, UNIX_PATH_LEN); // if (UNIX_PATH_LEN < UnixPathLen) @@ -1131,33 +1761,64 @@ InetAddress make_InetAddress(const(sockaddr)* sockAddress) return addr; } +IPAddr make_IPAddr(ref const in_addr in4) +{ + IPAddr addr; + version (WinSock) + { + addr.b[0] = in4.S_un.S_un_b.s_b1; + addr.b[1] = in4.S_un.S_un_b.s_b2; + addr.b[2] = in4.S_un.S_un_b.s_b3; + addr.b[3] = in4.S_un.S_un_b.s_b4; + } + else version (BSDSockets) + addr.address = in4.s_addr; + else + assert(false, "Not implemented!"); + return addr; +} -private: +IPv6Addr make_IPv6Addr(ref const in6_addr in6) +{ + IPv6Addr addr; + for (int a = 0; a < 8; ++a) + { + version (WinSock) + addr.s[a] = loadBigEndian(&in6.in6_u.u6_addr16[a]); + else version (Posix) + addr.s[a] = loadBigEndian(&in6.__in6_u.__u6_addr16[a]); + else version (BSDSockets) + addr.s[a] = loadBigEndian(cast(const(ushort)*)&in6.s6_addr[a * 2]); + else + assert(false, "Not implemented!"); + } + return addr; +} enum OptLevel : ubyte { - Socket, - IP, - IPv6, - ICMP, - ICMPv6, - TCP, - UDP, + socket, + ip, + ipv6, + icmp, + icmpv6, + tcp, + udp, } enum OptType : ubyte { - Unsupported, - Bool, - Int, - Seconds, - Milliseconds, - Duration, - INAddress, // IPAddr + in_addr - //IN6Address, // IPv6Addr + in6_addr - MulticastGroup, // MulticastGroup + ip_mreq - //MulticastGroupIPv6, // MulticastGroupIPv6? + ipv6_mreq - Linger, + unsupported, + bool_, + int_, + seconds, + milliseconds, + duration, + inet_addr, // IPAddr + in_addr + //inet6_addr, // IPv6Addr + in6_addr + multicast_group, // MulticastGroup + ip_mreq + //multicast_group_ipv6, // MulticastGroupIPv6? + ipv6_mreq + linger, // etc... } @@ -1169,11 +1830,16 @@ __gshared immutable ubyte[] s_optTypePlatformSize = [ 0, 0, int.sizeof, int.size struct OptInfo { short option; - OptType rtType; - OptType platformType; + OptType rt_type; + OptType platform_type; } -__gshared immutable ushort[AddressFamily.max+1] s_addressFamily = [ +version (lwIP) + alias sa_family_t = ubyte; +else + alias sa_family_t = ushort; + +__gshared immutable sa_family_t[AddressFamily.max+1] s_addressFamily = [ AF_UNSPEC, AF_UNIX, AF_INET, @@ -1182,15 +1848,15 @@ __gshared immutable ushort[AddressFamily.max+1] s_addressFamily = [ AddressFamily map_address_family(int addressFamily) { if (addressFamily == AF_INET) - return AddressFamily.IPv4; + return AddressFamily.ipv4; else if (addressFamily == AF_INET6) - return AddressFamily.IPv6; + return AddressFamily.ipv6; else if (addressFamily == AF_UNIX) - return AddressFamily.Unix; + return AddressFamily.unix; else if (addressFamily == AF_UNSPEC) - return AddressFamily.Unspecified; + return AddressFamily.unspecified; assert(false, "Unsupported address family"); - return AddressFamily.Unknown; + return AddressFamily.unknown; } __gshared immutable int[SocketType.max+1] s_socketType = [ @@ -1201,13 +1867,13 @@ __gshared immutable int[SocketType.max+1] s_socketType = [ SocketType map_socket_type(int sockType) { if (sockType == SOCK_STREAM) - return SocketType.Stream; + return SocketType.stream; else if (sockType == SOCK_DGRAM) - return SocketType.Datagram; + return SocketType.datagram; else if (sockType == SOCK_RAW) - return SocketType.Raw; + return SocketType.raw; assert(false, "Unsupported socket type"); - return SocketType.Unknown; + return SocketType.unknown; } __gshared immutable int[Protocol.max+1] s_protocol = [ @@ -1220,17 +1886,17 @@ __gshared immutable int[Protocol.max+1] s_protocol = [ Protocol map_protocol(int protocol) { if (protocol == IPPROTO_TCP) - return Protocol.TCP; + return Protocol.tcp; else if (protocol == IPPROTO_UDP) - return Protocol.UDP; + return Protocol.udp; else if (protocol == IPPROTO_IP) - return Protocol.IP; + return Protocol.ip; else if (protocol == IPPROTO_ICMP) - return Protocol.ICMP; + return Protocol.icmp; else if (protocol == IPPROTO_RAW) - return Protocol.Raw; + return Protocol.raw; assert(false, "Unsupported protocol"); - return Protocol.Unknown; + return Protocol.unknown; } version (linux) @@ -1258,71 +1924,101 @@ else ]; } -version (Windows) // BS_NETWORK_WINDOWS_VERSION >= _WIN32_WINNT_VISTA +version (WinSock) // BS_NETWORK_WINDOWS_VERSION >= _WIN32_WINNT_VISTA { __gshared immutable OptInfo[SocketOption.max] s_socketOptions = [ - OptInfo( -1, OptType.Bool, OptType.Bool ), // NonBlocking - OptInfo( SO_KEEPALIVE, OptType.Bool, OptType.Int ), - OptInfo( SO_LINGER, OptType.Duration, OptType.Linger ), - OptInfo( -1, OptType.Unsupported, OptType.Unsupported ), -// OptInfo( SO_RANDOMIZE_PORT, OptType.Bool, OptType.Int ), // TODO: BS_NETWORK_WINDOWS_VERSION >= _WIN32_WINNT_VISTA - OptInfo( SO_SNDBUF, OptType.Int, OptType.Int ), - OptInfo( SO_RCVBUF, OptType.Int, OptType.Int ), - OptInfo( SO_REUSEADDR, OptType.Bool, OptType.Int ), - OptInfo( -1, OptType.Bool, OptType.Unsupported ), // NoSignalPipe - OptInfo( SO_ERROR, OptType.Int, OptType.Int ), - OptInfo( IP_ADD_MEMBERSHIP, OptType.MulticastGroup, OptType.MulticastGroup ), - OptInfo( IP_MULTICAST_LOOP, OptType.Bool, OptType.Int ), - OptInfo( IP_MULTICAST_TTL, OptType.Int, OptType.Int ), - OptInfo( -1, OptType.Unsupported, OptType.Unsupported ), - OptInfo( -1, OptType.Unsupported, OptType.Unsupported ), - OptInfo( -1, OptType.Unsupported, OptType.Unsupported ), - OptInfo( -1, OptType.Unsupported, OptType.Unsupported ), - OptInfo( TCP_NODELAY, OptType.Bool, OptType.Int ), + OptInfo( -1, OptType.bool_, OptType.bool_ ), // NonBlocking + OptInfo( SO_KEEPALIVE, OptType.bool_, OptType.int_ ), + OptInfo( SO_LINGER, OptType.duration, OptType.linger ), + OptInfo( -1, OptType.unsupported, OptType.unsupported ), +// OptInfo( SO_RANDOMIZE_PORT, OptType.bool_, OptType.int_ ), // TODO: BS_NETWORK_WINDOWS_VERSION >= _WIN32_WINNT_VISTA + OptInfo( SO_SNDBUF, OptType.int_, OptType.int_ ), + OptInfo( SO_RCVBUF, OptType.int_, OptType.int_ ), + OptInfo( SO_REUSEADDR, OptType.bool_, OptType.int_ ), + OptInfo( -1, OptType.bool_, OptType.unsupported ), // NoSignalPipe + OptInfo( SO_ERROR, OptType.int_, OptType.int_ ), + OptInfo( IP_ADD_MEMBERSHIP, OptType.multicast_group, OptType.multicast_group ), + OptInfo( IP_MULTICAST_LOOP, OptType.bool_, OptType.int_ ), + OptInfo( IP_MULTICAST_TTL, OptType.int_, OptType.int_ ), + OptInfo( IP_PKTINFO, OptType.bool_, OptType.int_ ), + OptInfo( IPV6_RECVPKTINFO, OptType.bool_, OptType.int_ ), + OptInfo( -1, OptType.unsupported, OptType.unsupported ), + OptInfo( -1, OptType.unsupported, OptType.unsupported ), + OptInfo( -1, OptType.unsupported, OptType.unsupported ), + OptInfo( -1, OptType.unsupported, OptType.unsupported ), + OptInfo( TCP_NODELAY, OptType.bool_, OptType.int_ ), ]; } else version (linux) // BS_NETWORK_WINDOWS_VERSION >= _WIN32_WINNT_VISTA { __gshared immutable OptInfo[SocketOption.max] s_socketOptions = [ - OptInfo( -1, OptType.Bool, OptType.Bool ), // NonBlocking - OptInfo( SO_KEEPALIVE, OptType.Bool, OptType.Int ), - OptInfo( SO_LINGER, OptType.Duration, OptType.Linger ), - OptInfo( -1, OptType.Unsupported, OptType.Unsupported ), - OptInfo( SO_SNDBUF, OptType.Int, OptType.Int ), - OptInfo( SO_RCVBUF, OptType.Int, OptType.Int ), - OptInfo( SO_REUSEADDR, OptType.Bool, OptType.Int ), - OptInfo( -1, OptType.Bool, OptType.Unsupported ), // NoSignalPipe - OptInfo( SO_ERROR, OptType.Int, OptType.Int ), - OptInfo( IP_ADD_MEMBERSHIP, OptType.MulticastGroup, OptType.MulticastGroup ), - OptInfo( IP_MULTICAST_LOOP, OptType.Bool, OptType.Int ), - OptInfo( IP_MULTICAST_TTL, OptType.Int, OptType.Int ), - OptInfo( TCP_KEEPIDLE, OptType.Duration, OptType.Seconds ), - OptInfo( TCP_KEEPINTVL, OptType.Duration, OptType.Seconds ), - OptInfo( TCP_KEEPCNT, OptType.Int, OptType.Int ), - OptInfo( -1, OptType.Unsupported, OptType.Unsupported ), - OptInfo( TCP_NODELAY, OptType.Bool, OptType.Int ), + OptInfo( -1, OptType.bool_, OptType.bool_ ), // NonBlocking + OptInfo( SO_KEEPALIVE, OptType.bool_, OptType.int_ ), + OptInfo( SO_LINGER, OptType.duration, OptType.linger ), + OptInfo( -1, OptType.unsupported, OptType.unsupported ), + OptInfo( SO_SNDBUF, OptType.int_, OptType.int_ ), + OptInfo( SO_RCVBUF, OptType.int_, OptType.int_ ), + OptInfo( SO_REUSEADDR, OptType.bool_, OptType.int_ ), + OptInfo( -1, OptType.bool_, OptType.unsupported ), // NoSignalPipe + OptInfo( SO_ERROR, OptType.int_, OptType.int_ ), + OptInfo( IP_ADD_MEMBERSHIP, OptType.multicast_group, OptType.multicast_group ), + OptInfo( IP_MULTICAST_LOOP, OptType.bool_, OptType.int_ ), + OptInfo( IP_MULTICAST_TTL, OptType.int_, OptType.int_ ), + OptInfo( IP_PKTINFO, OptType.bool_, OptType.int_ ), + OptInfo( IPV6_RECVPKTINFO, OptType.bool_, OptType.int_ ), + OptInfo( TCP_KEEPIDLE, OptType.duration, OptType.seconds ), + OptInfo( TCP_KEEPINTVL, OptType.duration, OptType.seconds ), + OptInfo( TCP_KEEPCNT, OptType.int_, OptType.int_ ), + OptInfo( -1, OptType.unsupported, OptType.unsupported ), + OptInfo( TCP_NODELAY, OptType.bool_, OptType.int_ ), ]; } else version (Darwin) { __gshared immutable OptInfo[SocketOption.max] s_socketOptions = [ - OptInfo( -1, OptType.Bool, OptType.Bool ), // NonBlocking - OptInfo( SO_KEEPALIVE, OptType.Bool, OptType.Int ), + OptInfo( -1, OptType.bool_, OptType.bool_ ), // NonBlocking + OptInfo( SO_KEEPALIVE, OptType.bool_, OptType.int_ ), OptInfo( SO_LINGER, OptType.Duration, OptType.Linger ), - OptInfo( -1, OptType.Unsupported, OptType.Unsupported ), - OptInfo( SO_SNDBUF, OptType.Int, OptType.Int ), - OptInfo( SO_RCVBUF, OptType.Int, OptType.Int ), - OptInfo( SO_REUSEADDR, OptType.Bool, OptType.Int ), - OptInfo( SO_NOSIGPIPE, OptType.Bool, OptType.Int ), - OptInfo( SO_ERROR, OptType.Int, OptType.Int ), - OptInfo( IP_ADD_MEMBERSHIP, OptType.MulticastGroup, OptType.MulticastGroup ), - OptInfo( IP_MULTICAST_LOOP, OptType.Bool, OptType.Int ), - OptInfo( IP_MULTICAST_TTL, OptType.Int, OptType.Int ), - OptInfo( -1, OptType.Unsupported, OptType.Unsupported ), - OptInfo( -1, OptType.Unsupported, OptType.Unsupported ), - OptInfo( -1, OptType.Unsupported, OptType.Unsupported ), - OptInfo( TCP_KEEPALIVE, OptType.Duration, OptType.Seconds ), - OptInfo( TCP_NODELAY, OptType.Bool, OptType.Int ), + OptInfo( -1, OptType.unsupported, OptType.unsupported ), + OptInfo( SO_SNDBUF, OptType.int_, OptType.int_ ), + OptInfo( SO_RCVBUF, OptType.int_, OptType.int_ ), + OptInfo( SO_REUSEADDR, OptType.bool_, OptType.int_ ), + OptInfo( SO_NOSIGPIPE, OptType.bool_, OptType.int_ ), + OptInfo( SO_ERROR, OptType.int_, OptType.int_ ), + OptInfo( IP_ADD_MEMBERSHIP, OptType.multicast_group, OptType.multicast_group ), + OptInfo( IP_MULTICAST_LOOP, OptType.bool_, OptType.int_ ), + OptInfo( IP_MULTICAST_TTL, OptType.int_, OptType.int_ ), + OptInfo( IP_PKTINFO, OptType.bool_, OptType.int_ ), + OptInfo( IPV6_RECVPKTINFO, OptType.bool_, OptType.int_ ), + OptInfo( -1, OptType.unsupported, OptType.unsupported ), + OptInfo( -1, OptType.unsupported, OptType.unsupported ), + OptInfo( -1, OptType.unsupported, OptType.unsupported ), + OptInfo( TCP_KEEPALIVE, OptType.duration, OptType.seconds ), + OptInfo( TCP_NODELAY, OptType.bool_, OptType.int_ ), + ]; +} +else version (lwIP) +{ + __gshared immutable OptInfo[SocketOption.max] s_socketOptions = [ + OptInfo( -1, OptType.bool_, OptType.bool_ ), // NonBlocking + OptInfo( SO_KEEPALIVE, OptType.bool_, OptType.int_ ), + OptInfo( SO_LINGER, OptType.duration, OptType.linger ), + OptInfo( -1, OptType.unsupported, OptType.unsupported ), // RandomizePort + OptInfo( SO_SNDBUF, OptType.int_, OptType.int_ ), + OptInfo( SO_RCVBUF, OptType.int_, OptType.int_ ), + OptInfo( SO_REUSEADDR, OptType.bool_, OptType.int_ ), + OptInfo( -1, OptType.unsupported, OptType.unsupported ), // NoSigPipe + OptInfo( SO_ERROR, OptType.int_, OptType.int_ ), + OptInfo( IP_ADD_MEMBERSHIP, OptType.multicast_group, OptType.multicast_group ), + OptInfo( IP_MULTICAST_LOOP, OptType.bool_, OptType.int_ ), + OptInfo( IP_MULTICAST_TTL, OptType.int_, OptType.int_ ), + OptInfo( -1, OptType.unsupported, OptType.unsupported ), // IP_PKTINFO + OptInfo( -1, OptType.unsupported, OptType.unsupported ), // IPV6_PKTINFO + OptInfo( TCP_KEEPIDLE, OptType.duration, OptType.seconds ), + OptInfo( TCP_KEEPINTVL, OptType.duration, OptType.seconds ), + OptInfo( TCP_KEEPCNT, OptType.int_, OptType.int_ ), + OptInfo( -1, OptType.unsupported, OptType.unsupported ), // TcpKeepAlive (Apple) + OptInfo( TCP_NODELAY, OptType.bool_, OptType.int_ ), ]; } else @@ -1331,12 +2027,11 @@ else int map_message_flags(MsgFlags flags) { int r = 0; - if (flags & MsgFlags.OOB) r |= MSG_OOB; - if (flags & MsgFlags.Peek) r |= MSG_PEEK; + if (flags & MsgFlags.peek) r |= MSG_PEEK; version (linux) { - if (flags & MsgFlags.Confirm) r |= MSG_CONFIRM; - if (flags & MsgFlags.NoSig) r |= MSG_NOSIGNAL; + if (flags & MsgFlags.confirm) r |= MSG_CONFIRM; + if (flags & MsgFlags.no_sig) r |= MSG_NOSIGNAL; } return r; } @@ -1344,38 +2039,65 @@ int map_message_flags(MsgFlags flags) int map_addrinfo_flags(AddressInfoFlags flags) { int r = 0; - if (flags & AddressInfoFlags.Passive) r |= AI_PASSIVE; - if (flags & AddressInfoFlags.CanonName) r |= AI_CANONNAME; - if (flags & AddressInfoFlags.NumericHost) r |= AI_NUMERICHOST; - if (flags & AddressInfoFlags.NumericServ) r |= AI_NUMERICSERV; - if (flags & AddressInfoFlags.All) r |= AI_ALL; - if (flags & AddressInfoFlags.AddrConfig) r |= AI_ADDRCONFIG; - if (flags & AddressInfoFlags.V4Mapped) r |= AI_V4MAPPED; - version (Windows) - if (flags & AddressInfoFlags.FQDN) r |= AI_FQDN; + if (flags & AddressInfoFlags.passive) r |= AI_PASSIVE; + if (flags & AddressInfoFlags.canon_name) r |= AI_CANONNAME; + if (flags & AddressInfoFlags.numeric_host) r |= AI_NUMERICHOST; + if (flags & AddressInfoFlags.numeric_serv) r |= AI_NUMERICSERV; + if (flags & AddressInfoFlags.all) r |= AI_ALL; + if (flags & AddressInfoFlags.addr_config) r |= AI_ADDRCONFIG; + if (flags & AddressInfoFlags.v4_mapped) r |= AI_V4MAPPED; + version (WinSock) + if (flags & AddressInfoFlags.fqdn) r |= AI_FQDN; return r; } OptLevel get_optlevel(SocketOption opt) { - if (opt < SocketOption.FirstIpOption) return OptLevel.Socket; - else if (opt < SocketOption.FirstIpv6Option) return OptLevel.IP; - else if (opt < SocketOption.FirstIcmpOption) return OptLevel.IPv6; - else if (opt < SocketOption.FirstIcmpv6Option) return OptLevel.ICMP; - else if (opt < SocketOption.FirstTcpOption) return OptLevel.ICMPv6; - else if (opt < SocketOption.FirstUdpOption) return OptLevel.TCP; - else return OptLevel.UDP; + if (opt < SocketOption.first_ip_option) return OptLevel.socket; + else if (opt < SocketOption.first_ipv6_option) return OptLevel.ip; + else if (opt < SocketOption.first_icmp_option) return OptLevel.ipv6; + else if (opt < SocketOption.first_icmpv6_option) return OptLevel.icmp; + else if (opt < SocketOption.first_tcp_option) return OptLevel.icmpv6; + else if (opt < SocketOption.first_udp_option) return OptLevel.tcp; + else return OptLevel.udp; } -version (Windows) +version (WinSock) { pragma(crt_constructor) void crt_bootup() { WSADATA wsaData; - int result = WSAStartup(MAKEWORD(2, 2), &wsaData); + int result = WSAStartup(0x0202, &wsaData); // what if this fails??? + + // this is truly the worst thing I ever wrote!! + enum SIO_GET_EXTENSION_FUNCTION_POINTER = 0xC8000006; + struct GUID { uint Data1; ushort Data2, Data3; ubyte[8] Data4; } + __gshared immutable GUID WSAID_WSASENDMSG = GUID(0xA441E712, 0x754F, 0x43CA, [0x84,0xA7,0x0D,0xEE,0x44,0xCF,0x60,0x6D]); + __gshared immutable GUID WSAID_WSARECVMSG = GUID(0xF689D7C8, 0x6F1F, 0x436B, [0x8A,0x53,0xE5,0x4F,0xE3,0x51,0xC3,0x22]); + + Socket dummy; + uint bytes = 0; + if (!create_socket(AddressFamily.ipv4, SocketType.datagram, Protocol.udp, dummy)) + goto FAIL; + if (WSAIoctl(dummy.handle, SIO_GET_EXTENSION_FUNCTION_POINTER, cast(void*)&WSAID_WSASENDMSG, cast(uint)GUID.sizeof, + &WSASendMsg, cast(uint)WSASendMsgFn.sizeof, &bytes, null, null) != 0) + goto FAIL; + assert(bytes == WSASendMsgFn.sizeof); + if (WSAIoctl(dummy.handle, SIO_GET_EXTENSION_FUNCTION_POINTER, cast(void*)&WSAID_WSARECVMSG, cast(uint)GUID.sizeof, + &WSARecvMsg, cast(uint)WSARecvMsgFn.sizeof, &bytes, null, null) != 0) + goto FAIL; + assert(bytes == WSARecvMsgFn.sizeof); + dummy.close(); + if (!WSASendMsg || !WSARecvMsg) + goto FAIL; + return; + + FAIL: + import urt.log; + writeWarning("Failed to get WSASendMsg/WSARecvMsg function pointers - sendmsg() won't work, recvfrom() won't be able to report the dst address"); } pragma(crt_destructor) @@ -1390,47 +2112,101 @@ version (Windows) // TODO: REMOVE ME - pushed to druntime... -version (Windows) +version (WinSock) { // stuff that's missing from the windows headers... - enum: int { + enum : int + { AI_NUMERICSERV = 0x0008, AI_ALL = 0x0100, AI_V4MAPPED = 0x0800, AI_FQDN = 0x4000, } - struct pollfd + struct ip_mreq + { + in_addr imr_multiaddr; + in_addr imr_interface; + } + + struct WSAMSG { - SOCKET fd; // Socket handle - SHORT events; // Requested events to monitor - SHORT revents; // Returned events indicating status + LPSOCKADDR name; + int namelen; + LPWSABUF lpBuffers; + uint dwBufferCount; + WSABUF Control; + uint dwFlags; } - alias WSAPOLLFD = pollfd; - alias PWSAPOLLFD = pollfd*; - alias LPWSAPOLLFD = pollfd*; - - enum: short { - POLLRDNORM = 0x0100, - POLLRDBAND = 0x0200, - POLLIN = (POLLRDNORM | POLLRDBAND), - POLLPRI = 0x0400, - - POLLWRNORM = 0x0010, - POLLOUT = (POLLWRNORM), - POLLWRBAND = 0x0020, - - POLLERR = 0x0001, - POLLHUP = 0x0002, - POLLNVAL = 0x0004 + alias LPWSAMSG = WSAMSG*; + + struct WSABUF + { + uint len; + char* buf; } + alias LPWSABUF = WSABUF*; - extern(Windows) int WSAPoll(LPWSAPOLLFD fdArray, uint fds, int timeout); + alias WSASendMsgFn = extern(Windows) int function(SOCKET s, LPWSAMSG lpMsg, uint dwFlags, uint* lpNumberOfBytesSent, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); + alias WSARecvMsgFn = extern(Windows) int function(SOCKET s, LPWSAMSG lpMsg, uint* lpdwNumberOfBytesRecvd, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); + __gshared WSASendMsgFn WSASendMsg; + __gshared WSARecvMsgFn WSARecvMsg; - struct ip_mreq + struct IN_PKTINFO { - in_addr imr_multiaddr; - in_addr imr_interface; + in_addr ipi_addr; + uint ipi_ifindex; + } + struct IN6_PKTINFO + { + in6_addr ipi6_addr; + uint ipi6_ifindex; + } + + struct WSACMSGHDR + { + size_t cmsg_len; + int cmsg_level; + int cmsg_type; } + alias LPWSACMSGHDR = WSACMSGHDR*; + + LPWSACMSGHDR WSA_CMSG_FIRSTHDR(LPWSAMSG msg) + => msg.Control.len >= WSACMSGHDR.sizeof ? cast(LPWSACMSGHDR)msg.Control.buf : null; + + LPWSACMSGHDR WSA_CMSG_NXTHDR(LPWSAMSG msg, LPWSACMSGHDR cmsg) + { + if (!cmsg) + return WSA_CMSG_FIRSTHDR(msg); + if (cast(ubyte*)cmsg + WSA_CMSGHDR_ALIGN(cmsg.cmsg_len) + WSACMSGHDR.sizeof > cast(ubyte*)msg.Control.buf + msg.Control.len) + return null; + return cast(LPWSACMSGHDR)(cast(ubyte*)cmsg + WSA_CMSGHDR_ALIGN(cmsg.cmsg_len)); + } + + void* WSA_CMSG_DATA(LPWSACMSGHDR cmsg) + => cast(ubyte*)cmsg + WSA_CMSGDATA_ALIGN(WSACMSGHDR.sizeof); + + size_t WSA_CMSGHDR_ALIGN(size_t length) + => (length + WSACMSGHDR.alignof-1) & ~(WSACMSGHDR.alignof-1); + + size_t WSA_CMSGDATA_ALIGN(size_t length) + => (length + size_t.alignof-1) & ~(size_t.alignof-1); + + struct WSAOVERLAPPED + { + uint Internal; + uint InternalHigh; + uint Offset; + uint OffsetHigh; + HANDLE hEvent; + } + alias LPWSAOVERLAPPED = WSAOVERLAPPED*; + + alias LPWSAOVERLAPPED_COMPLETION_ROUTINE = void function(uint dwError, uint cbTransferred, LPWSAOVERLAPPED lpOverlapped, uint dwFlags); + + extern(Windows) int WSASend(SOCKET s, LPWSABUF lpBuffers, uint dwBufferCount, uint* lpNumberOfBytesSent, uint dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); + extern(Windows) int WSASendTo(SOCKET s, LPWSABUF lpBuffers, uint dwBufferCount, uint* lpNumberOfBytesSent, uint dwFlags, const(sockaddr)* lpTo, int iTolen, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); } + +} // SocketCallbacks diff --git a/src/urt/string/ansi.d b/src/urt/string/ansi.d index eac1150..6828cf1 100644 --- a/src/urt/string/ansi.d +++ b/src/urt/string/ansi.d @@ -68,33 +68,101 @@ enum ANSI_RESET = "\x1b[0m"; nothrow @nogc: -size_t parseANSICode(const(char)[] text) +size_t parse_ansi_code(const(char)[] text) { - import urt.string.ascii : isNumeric; + import urt.string.ascii : is_numeric; if (text.length < 3 || text[0] != '\x1b') return 0; if (text[1] != '[' && text[1] != 'O') return 0; size_t i = 2; - for (; i < text.length && (text[i].isNumeric || text[i] == ';'); ++i) + for (; i < text.length && (text[i].is_numeric || text[i] == ';'); ++i) {} if (i == text.length) return 0; return i + 1; } -char[] stripDecoration(char[] text) pure +size_t visible_width(const(char)[] text) { - return stripDecoration(text, text); + import urt.string.uni : uni_seq_len; + + size_t width = 0; + size_t i = 0; + while (i < text.length) + { + if (text[i] == '\x1b' && i + 1 < text.length && text[i + 1] == '[') + { + i += 2; + while (i < text.length && text[i] != 'm') + ++i; + if (i < text.length) + ++i; + } + else + { + ++width; + i += uni_seq_len(text[i .. $]); + } + } + return width; +} + +const(char)[] visible_slice(const(char)[] text, char[] buf, size_t start = 0, size_t end = size_t.max) +{ + import urt.string.uni : uni_seq_len; + + size_t out_pos = 0; + size_t visible = 0; + + for (size_t i = 0; i < text.length; ) + { + if (text[i] == '\x1b' && i + 1 < text.length && text[i + 1] == '[') + { + size_t seq_start = i; + i += 2; + while (i < text.length && text[i] != 'm') + ++i; + if (i < text.length) + ++i; + size_t seq_len = i - seq_start; + if (out_pos + seq_len <= buf.length) + { + buf[out_pos .. out_pos + seq_len] = text[seq_start .. i]; + out_pos += seq_len; + } + } + else + { + size_t ch_len = uni_seq_len(text[i .. $]); + if (visible >= start && visible < end) + { + if (out_pos + ch_len <= buf.length) + { + buf[out_pos .. out_pos + ch_len] = text[i .. i + ch_len]; + out_pos += ch_len; + } + } + ++visible; + i += ch_len; + } + } + + return buf[0 .. out_pos]; +} + +char[] strip_decoration(char[] text) pure +{ + return strip_decoration(text, text); } -char[] stripDecoration(const(char)[] text, char[] buffer) pure +char[] strip_decoration(const(char)[] text, char[] buffer) pure { size_t len = text.length, outLen = 0; char* dst = buffer.ptr; const(char)* src = text.ptr; - bool writeOutput = text.ptr != buffer.ptr; + bool write_output = text.ptr != buffer.ptr; for (size_t i = 0; i < len;) { char c = src[i]; @@ -106,11 +174,11 @@ char[] stripDecoration(const(char)[] text, char[] buffer) pure if (j < len && src[j] == 'm') { i = j + 1; - writeOutput = true; + write_output = true; continue; } } - if (BranchMoreExpensiveThanStore || writeOutput) + if (BranchMoreExpensiveThanStore || write_output) dst[outLen] = c; // skip stores where unnecessary (probably the common case) ++outLen; } diff --git a/src/urt/string/ascii.d b/src/urt/string/ascii.d index 5541d3a..36f814f 100644 --- a/src/urt/string/ascii.d +++ b/src/urt/string/ascii.d @@ -2,14 +2,14 @@ module urt.string.ascii; -char[] toLower(const(char)[] str) pure nothrow +char[] to_lower(const(char)[] str) pure nothrow { - return toLower(str, new char[str.length]); + return to_lower(str, new char[str.length]); } -char[] toUpper(const(char)[] str) pure nothrow +char[] to_upper(const(char)[] str) pure nothrow { - return toUpper(str, new char[str.length]); + return to_upper(str, new char[str.length]); } @@ -17,7 +17,7 @@ nothrow @nogc: // some character category flags... // 1 = alpha, 2 = numeric, 4 = white, 8 = newline, 10 = control, 20 = ???, 40 = url, 80 = hex -__gshared immutable ubyte[128] charDetails = [ +private __gshared immutable ubyte[128] char_details = [ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x14, 0x18, 0x10, 0x10, 0x18, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, @@ -28,20 +28,20 @@ __gshared immutable ubyte[128] charDetails = [ 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x00, 0x00, 0x00, 0x40, 0x10 ]; -__gshared immutable char[16] hexDigits = "0123456789ABCDEF"; +__gshared immutable char[16] hex_digits = "0123456789ABCDEF"; -bool isSpace(char c) pure => c < 128 && (charDetails[c] & 4); -bool isNewline(char c) pure => c < 128 && (charDetails[c] & 8); -bool isWhitespace(char c) pure => c < 128 && (charDetails[c] & 0xC); -bool isAlpha(char c) pure => c < 128 && (charDetails[c] & 1); -bool isNumeric(char c) pure => cast(uint)(c - '0') <= 9; -bool isAlphaNumeric(char c) pure => c < 128 && (charDetails[c] & 3); -bool isHex(char c) pure => c < 128 && (charDetails[c] & 0x80); -bool isControlChar(char c) pure => c < 128 && (charDetails[c] & 0x10); -bool isURL(char c) pure => c < 128 && (charDetails[c] & 0x40); +bool is_space(char c) pure => c < 128 && (char_details[c] & 4); +bool is_newline(char c) pure => c < 128 && (char_details[c] & 8); +bool is_whitespace(char c) pure => c < 128 && (char_details[c] & 0xC); +bool is_alpha(char c) pure => c < 128 && (char_details[c] & 1); +bool is_numeric(char c) pure => cast(uint)(c - '0') <= 9; +bool is_alpha_numeric(char c) pure => c < 128 && (char_details[c] & 3); +bool is_hex(char c) pure => c < 128 && (char_details[c] & 0x80); +bool is_control_char(char c) pure => c < 128 && (char_details[c] & 0x10); +bool is_url(char c) pure => c < 128 && (char_details[c] & 0x40); -char toLower(char c) pure +char to_lower(char c) pure { // this is the typical way; which is faster on a weak arch? // if (c >= 'A' && c <= 'Z') @@ -53,7 +53,7 @@ char toLower(char c) pure return c; } -char toUpper(char c) pure +char to_upper(char c) pure { // this is the typical way; which is faster on a weak arch? // if (c >= 'a' && c <= 'z') @@ -65,26 +65,62 @@ char toUpper(char c) pure return c; } -char[] toLower(const(char)[] str, char[] buffer) pure +char[] to_lower(const(char)[] str, char[] buffer) pure { + if (buffer.length < str.length) + return null; foreach (i; 0 .. str.length) - buffer[i] = toLower(str[i]); - return buffer; + buffer[i] = str[i].to_lower; + return buffer[0..str.length]; } -char[] toUpper(const(char)[] str, char[] buffer) pure +char[] to_upper(const(char)[] str, char[] buffer) pure { + if (buffer.length < str.length) + return null; foreach (i; 0 .. str.length) - buffer[i] = toUpper(str[i]); - return buffer; + buffer[i] = str[i].to_upper; + return buffer[0..str.length]; } -char[] toLower(char[] str) pure +char[] to_lower(char[] str) pure { - return toLower(str, str); + return to_lower(str, str); } -char[] toUpper(char[] str) pure +char[] to_upper(char[] str) pure { - return toUpper(str, str); + return to_upper(str, str); } + +ptrdiff_t cmp(bool case_insensitive = false)(const(char)[] a, const(char)[] b) pure +{ + if (a.length != b.length) + return a.length - b.length; + static if (case_insensitive) + { + for (size_t i = 0; i < a.length; ++i) + { + char ca = a[i].to_lower; + char cb = b[i].to_lower; + if (ca != cb) + return ca - cb; + } + } + else + { + for (size_t i = 0; i < a.length; ++i) + if (a[i] != b[i]) + return a[i] - b[i]; + } + return 0; +} + +ptrdiff_t icmp(const(char)[] a, const(char)[] b) pure + => cmp!true(a, b); + +bool eq(const(char)[] a, const(char)[] b) pure + => cmp(a, b) == 0; + +bool ieq(const(char)[] a, const(char)[] b) pure + => cmp!true(a, b) == 0; diff --git a/src/urt/string/format.d b/src/urt/string/format.d index 6016615..d4f924f 100644 --- a/src/urt/string/format.d +++ b/src/urt/string/format.d @@ -1,99 +1,138 @@ module urt.string.format; -import urt.conv : parseIntFast; +import urt.conv : parse_int_fast; import urt.string; import urt.traits; import urt.util; public import urt.mem.temp : tformat, tconcat, tstring; - nothrow @nogc: debug { + // format functions are not re-entrant! static bool InFormatFunction = false; } alias StringifyFunc = ptrdiff_t delegate(char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) nothrow @nogc; -alias IntifyFunc = ptrdiff_t delegate() nothrow @nogc; +struct Arg +{ + StringifyFunc fn; +} -ptrdiff_t toString(T)(auto ref T value, char[] buffer) +struct Format { - import urt.string.format : FormatArg; + this(T)(ref const T value, const(char)[] format) pure nothrow @nogc + { + fn = get_to_string_func(value); + fmt = format; + } + + StringifyFunc fn; + const(char)[] fmt; +} +ptrdiff_t toString(T)(ref const T value, char[] buffer, const(char)[] format = null, const(FormatArg)[] formatArgs = null) +{ debug InFormatFunction = true; - FormatArg a = FormatArg(value); - ptrdiff_t r = a.getString(buffer, null, null); + ptrdiff_t r = get_to_string_func(value)(buffer, format, formatArgs); debug InFormatFunction = false; return r; } -char[] concat(Args...)(char[] buffer, auto ref Args args) +alias formatValue = toString; // TODO: remove me? + +auto normalise_args(Args...)(ref const Args args) { - static if (Args.length == 0) + import urt.meta.tuple : Tuple; + alias NormalisedArgs = NormaliseArgs!Args; + Tuple!(NormalisedArgs) result = void; + +// pragma(msg, "[ ", Args, " ] --> [ ", NormalisedArgs, " ]"); + + static foreach (i; 0 .. Args.length) { + static if (is(NormalisedArgs[i] == char) || is(NormalisedArgs[i] == Format)) + result[i] = args[i]; + else static if (is(NormalisedArgs[i] == Arg)) + result[i] = Arg(get_to_string_func(args[i])); + else static if (is(NormalisedArgs[i] == Array!char) || is(NormalisedArgs[i] == String) || is(NormalisedArgs[i] == MutableString!N, size_t N)) + static assert(false, "use container[] at the callsite!"); + else + result[i] = args[i][]; + } + return result; +} + +char[] concat(Args...)(char[] buffer, auto ref const Args args) +{ + pragma(inline, true); + + alias NormalisedArgs = NormaliseArgs!Args; + + static if (Args.length == 0) return buffer.ptr[0 .. 0]; + else + return concat_impl(buffer, normalise_args(forward!args)); +} + +import urt.meta.tuple : Tuple; +char[] concat_impl(Args...)(char[] buffer, Tuple!Args args) +{ + size_t[Args.length] lens = void; + size_t length = 0; + static foreach (i; 0 .. Args.length) + { + static if (is(Args[i] == char)) + length += 1; + else static if (is(Args[i] == Arg)) + { + lens[i] = args[i].fn(null, null, null); + length += lens[i]; + } + else static if (is(Args[i] == Format)) + { + lens[i] = args[i].fn(null, args[i].fmt, null); + length += lens[i]; + } + else + { + lens[i] = args[i].length; + length += lens[i]; + } } - else static if ((Args.length == 1 && allAreStrings!Args) || allConstCorrectStrings!Args) + if (buffer.ptr) { - // this implementation handles pure string concatenations - if (!buffer.ptr) + if (length > buffer.length) + return null; + char* p = buffer.ptr; + static foreach (i; 0 .. Args.length) { - size_t length = 0; - static foreach (i, s; args) + static if (is(Args[i] == char)) + *p++ = args[i]; + else static if (is(Args[i] == Arg)) { - static if (is(typeof(s) : char)) - length += 1; - else - length += s.length; + args[i].fn(p[0..lens[i]], null, null); + p += lens[i]; } - return (cast(char*)null)[0 .. length]; - } - size_t offset = 0; - static foreach (i, s; args) - { - static if (is(typeof(s) : char)) + else static if (is(Args[i] == Format)) { - if (buffer.length < offset + 1) - return null; - buffer.ptr[offset++] = s; + args[i].fn(p[0..lens[i]], args[i].fmt, null); + p += lens[i]; } else { - if (buffer.length < offset + s.length) - return null; - buffer.ptr[offset .. offset + s.length] = s.ptr[0 .. s.length]; - offset += s.length; + p[0..lens[i]] = args[i].ptr[0..lens[i]]; + p += lens[i]; } } - return buffer.ptr[0 .. offset]; - } - static if (allAreStrings!Args) - { - // TODO: why can't inline this?! -// pragma(inline, true); - - // avoid duplicate instantiations with different attributes... - return concat!(constCorrectedStrings!Args)(buffer, args); - } - else - { - // this implementation handles all the other kinds of things! - - debug if (!__ctfe) InFormatFunction = true; - FormatArg[Args.length] argFuncs; - // TODO: no need to collect int-ify functions in the arg set... - static foreach(i, arg; args) - argFuncs[i] = FormatArg(arg); - char[] r = concatImpl(buffer, argFuncs); - debug if (!__ctfe) InFormatFunction = false; - return r; } + return buffer.ptr[0 .. length]; } -char[] format(Args...)(char[] buffer, const(char)[] fmt, ref Args args) +char[] format(Args...)(char[] buffer, const(char)[] fmt, auto ref Args args) { debug InFormatFunction = true; FormatArg[Args.length] argArr = void; @@ -104,553 +143,696 @@ char[] format(Args...)(char[] buffer, const(char)[] fmt, ref Args args) return r; } -ptrdiff_t formatValue(T)(auto ref T value, char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) -{ - static if (is(typeof(&value.toString) : StringifyFunc)) - return value.toString(buffer, format, formatArgs); - else - return value.defFormat.toString(buffer, format, formatArgs); -} - struct FormatArg { - enum IsAggregate(T) = is(T == struct) || is(T == class); - private this(T)(ref T value) pure nothrow @nogc { - static if (IsAggregate!T && is(typeof(&value.toString) : StringifyFunc)) - toString = &value.toString; - else static if (IsAggregate!T && __traits(compiles, value.toString(buffer, "format", cast(FormatArg[])null) == 0)) - { - // wrap in a delegate that adjusts for format + args... - static assert(false); - } - else static if (IsAggregate!T && __traits(compiles, value.toString(buffer, "format") == 0)) - { - // wrap in a delegate that adjusts for format... - static assert(false); - } - else static if (IsAggregate!T && __traits(compiles, value.toString(buffer) == 0)) - { - // wrap in a delegate... - static assert(false); - } - else static if (IsAggregate!T && __traits(compiles, value.toString((const(char)[]){}) == 0)) - { - // version with a sink function... - // wrap in a delegate that adjusts for format + args... - static assert(false); - } - else - toString = &defFormat(value).toString; + getString = get_to_string_func(value); - static if (is(typeof(&defFormat(value).toInt))) - toInt = &defFormat(value).toInt; - else - toInt = null; + static if (can_default_int!T) + _to_int_fun = &DefInt!T.to_int; } - ptrdiff_t getString(char[] buffer, const(char)[] format, const(FormatArg)[] args) const nothrow @nogc - { - return toString(buffer, format, args); - } + StringifyFunc getString; + ptrdiff_t getLength(const(char)[] format, const(FormatArg)[] args) const nothrow @nogc - { - return toString(null, format, args); - } + => getString(null, format, args); - bool canInt() const nothrow @nogc - { - return toInt != null; - } - ptrdiff_t getInt() const nothrow @nogc + bool canInt() const pure nothrow @nogc + => _to_int_fun !is null; + + ptrdiff_t getInt() const pure nothrow @nogc { - return toInt(); + ptrdiff_t delegate() pure nothrow @nogc to_int; + to_int.ptr = getString.ptr; + to_int.funcptr = _to_int_fun; + return to_int(); } private: - // TODO: we could assert that the delegate pointers match, and only store it once... - StringifyFunc toString; - IntifyFunc toInt; + // only store the function pointer, since 'this' will be common + ptrdiff_t function() pure nothrow @nogc _to_int_fun; } private: -pragma(inline, true) -DefFormat!T* defFormat(T)(ref const(T) value) pure nothrow @nogc +import urt.array; +enum is_some_string(T) = is(T == char) || is(T : const char[]) || is(T : const(String)) || is(T : const(MutableString!N), size_t N) || is(T : const(Array!(char, N)), size_t N); + +template num_string_args(Args...) { - return cast(DefFormat!T*)&value; + static if (Args.length == 0) + enum num_string_args = 0; + else static if (is_some_string!(Args[0])) + enum num_string_args = 1 + num_string_args!(Args[1 .. $]); + else + enum num_string_args = 0; } -ptrdiff_t defToString(T)(ref const(T) value, char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) nothrow @nogc +template NormaliseArgs(Args...) { - return (cast(DefFormat!T*)&value).toString(buffer, format, formatArgs); + import urt.meta : AliasSeq; + alias NormaliseArgs = AliasSeq!(); + static foreach (Arg; Args) + NormaliseArgs = AliasSeq!(NormaliseArgs, NormaliseOthers!(NormaliseConst!Arg)); } -struct DefFormat(T) +template NormaliseOthers(T) { - T value; + static if (is(T : const(char)[]) || is(T == char)) + alias NormaliseOthers = T; + else static if (is(T == String) || is(T == Array!char) || is(T == MutableString!N, size_t N)) + alias NormaliseOthers = const(char)[]; + else + alias NormaliseOthers = Arg; +} - ptrdiff_t toString(char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) const nothrow @nogc - { - static if (is(T == typeof(null))) - { - if (!buffer.ptr) - return 4; - if (buffer.length < 4) - return -1; - buffer[0 .. 4] = "null"; - return 4; - } - else static if (is(T == bool)) - { - size_t len = value ? 4 : 5; - if (!buffer.ptr) - return len; - if (buffer.length < len) - return -1; - buffer[0 .. len] = value ? "true" : "false"; - return len; - } - else static if (is(T == char) || is(T == wchar) || is(T == dchar)) - { - if (is(T == char) || value <= 0x7F) - { - if (buffer.ptr) - { - if (buffer.length < 1) - return -1; - buffer[0] = cast(char)value; - } - return 1; - } - else if (value <= 0x7FF) +template NormaliseConst(T) +{ + static if (is(T == const(U), U) || is(T == immutable(U), U)) + alias NormaliseConst = NormaliseConst!U; + else static if (is(T == immutable(U)[], U) || is(T == U[], U)) + alias NormaliseConst = const(U)[]; + else static if (is(T == U[N], U, size_t N)) + alias NormaliseConst = const(U)[]; + else + alias NormaliseConst = T; +} + +alias StringifyFuncReduced = ptrdiff_t delegate(char[] buffer, const(char)[] format) nothrow @nogc; +alias StringifyFuncReduced2 = ptrdiff_t delegate(char[] buffer) nothrow @nogc; + +enum can_default_int(T) = is_some_int!T || is(T == bool); + +template to_string_overload_index(T) +{ + static if (!is(T == Unqual!T)) // minimise redundant instantiations + enum to_string_overload_index = to_string_overload_index!(Unqual!T); + else + enum to_string_overload_index = () { + static if (__traits(hasMember, T, "toString")) { - if (buffer.ptr) + // multiple passes so that we correctly preference the overload with more arguments... + static foreach (i, overload; __traits(getOverloads, T, "toString", true)) { - if (buffer.length < 2) - return -1; - buffer[0] = cast(char)(0xC0 | (value >> 6)); - buffer[1] = cast(char)(0x80 | (value & 0x3F)); + static if (is(typeof(&overload) : typeof(StringifyFunc.funcptr))) + return i; + else static if (is(typeof(&overload!()) : typeof(StringifyFunc.funcptr))) + return i; } - return 2; - } - else if (value <= 0xFFFF) - { - if (buffer.ptr) + static foreach (i, overload; __traits(getOverloads, T, "toString", true)) { - if (buffer.length < 3) - return -1; - buffer[0] = cast(char)(0xE0 | (value >> 12)); - buffer[1] = cast(char)(0x80 | ((value >> 6) & 0x3F)); - buffer[2] = cast(char)(0x80 | (value & 0x3F)); + static if (is(typeof(&overload) : typeof(StringifyFuncReduced.funcptr))) + return i; + else static if (is(typeof(&overload!()) : typeof(StringifyFuncReduced.funcptr))) + return i; } - return 3; - } - else if (value <= 0x10FFFF) - { - if (buffer.ptr) + static foreach (i, overload; __traits(getOverloads, T, "toString", true)) { - if (buffer.length < 4) - return -1; - buffer[0] = cast(char)(0xF0 | (value >> 18)); - buffer[1] = cast(char)(0x80 | ((value >> 12) & 0x3F)); - buffer[2] = cast(char)(0x80 | ((value >> 6) & 0x3F)); - buffer[3] = cast(char)(0x80 | (value & 0x3F)); + static if (is(typeof(&overload) : typeof(StringifyFuncReduced2.funcptr))) + return i; + else static if (is(typeof(&overload!()) : typeof(StringifyFuncReduced2.funcptr))) + return i; } - return 4; } + return -1; + }(); +} + +StringifyFunc get_to_string_func(T)(ref T value) +{ + enum overload_index = to_string_overload_index!T; + + static if (overload_index >= 0) + { + alias overload = __traits(getOverloads, T, "toString", true)[overload_index]; + static if (__traits(isTemplate, overload)) + alias to_string = overload!(); + else + alias to_string = overload; + + // TODO: we can't alias the __traits(child) expression, so we need to repeat it everywhere! + + alias method_type = typeof(&__traits(child, value, to_string)); + + static if (is(method_type : StringifyFunc)) + return &__traits(child, value, to_string); + + else static if (is(method_type : StringifyFuncReduced) || is(method_type : StringifyFuncReduced2)) + { + StringifyFunc d; + static if (is(T == struct)) + d.ptr = &value; else - { - assert(false, "Invalid code point"); - return 0; - } + d.ptr = cast(void*)value; + static if (is(method_type : StringifyFuncReduced)) + d.funcptr = &ToStringShim.shim1!T; + else + d.funcptr = &ToStringShim.shim2!T; + return d; } - else static if (is(T == double) || is(T == float)) - { - import urt.conv : formatFloat, formatInt; - char[16] tmp = void; - if (format.length && format[0] == '*') - { - bool success; - size_t arg = format[1..$].parseIntFast(success); - if (!success || !formatArgs[arg].canInt) - return -2; - size_t width = formatArgs[arg].getInt; - size_t len = width.formatInt(tmp); - format = tmp[0..len]; - } - return formatFloat(value, buffer, format); - } - else static if (is(T == ulong) || is(T == long)) + // TODO: do we want to support toString variants with sink instead of buffer? + + return null; + } + else static if (is_unsigned_int!T && T.sizeof <= size_t.sizeof) + { + StringifyFunc fn; + fn.ptr = cast(void*)size_t(value); + fn.funcptr = &DefFormat!size_t.toString; + return fn; + } + else static if (is_signed_int!T && T.sizeof <= size_t.sizeof) + { + StringifyFunc fn; + fn.ptr = cast(void*)cast(size_t)ptrdiff_t(value); + fn.funcptr = &DefFormat!ptrdiff_t.toString; + return fn; + } + else static if (is_some_char!T) + { + StringifyFunc fn; + fn.ptr = cast(void*)cast(size_t)dchar(value); + fn.funcptr = &DefFormat!dchar.toString; + return fn; + } + else static if (T.sizeof <= size_t.sizeof) + { + StringifyFunc fn; + *cast(Unqual!T*)&fn.ptr = value; + fn.funcptr = &DefFormat!T.toString; + return fn; + } + else + return &(cast(DefFormat!T*)&value).toString; +} + +struct ToStringShim +{ + ptrdiff_t shim1(T)(char[] buffer, const(char)[] format, const(FormatArg)[]) + { + static if (is(T == struct)) + ref T _this = *cast(T*)&this; + else + T _this = cast(T)cast(void*)&this; + return _this.toString(buffer, format); + } + ptrdiff_t shim2(T)(char[] buffer, const(char)[], const(FormatArg)[]) + { + static if (is(T == struct)) + ref T _this = *cast(T*)&this; + else + T _this = cast(T)cast(void*)&this; + return _this.toString(buffer); + } +} + +struct DefInt(T) +{ + static if (T.sizeof > size_t.sizeof) + T value; + + ptrdiff_t to_int() const pure nothrow @nogc + { + static if (T.sizeof <= size_t.sizeof) { - import urt.conv : formatInt, formatUint; + size_t bits = cast(size_t)cast(void*)&this; + ref T value = *cast(T*)&bits; + } - // TODO: what formats are interesting for ints? + static if (T.max > ptrdiff_t.max) + debug assert(value <= ptrdiff_t.max); + return cast(ptrdiff_t)value; + } +} - bool leadingZeroes = false; - bool toLower = false; - bool varLen = false; - ptrdiff_t padding = 0; - uint base = 10; +ptrdiff_t defToString(T)(ref const(T) value, char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) nothrow @nogc + => get_to_string_func(value)(buffer, format, formatArgs); - static if (is(T == long)) +template DefFormat(T) +{ + static if (is(T == const U, U) || is(T == immutable U, U)) + alias DefFormat = DefFormat!U; + else static if (is(T == const(U)[], U) || is(T == immutable(U)[], U)) + alias DefFormat = DefFormat!(U[]); + else struct DefFormat + { + static assert(!is(T == const), "How did this slip through?"); + + static if (T.sizeof > size_t.sizeof) + const T value; + + ptrdiff_t toString(char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) const nothrow @nogc + { + static if (T.sizeof <= size_t.sizeof) { - bool showSign = false; - if (format.length && format[0] == '+') - { - showSign = true; - format.popFront; - } + size_t bits = cast(size_t)cast(void*)&this; + ref T value = *cast(T*)&bits; } - if (format.length && format[0] == '0') + + static if (is(T == U[N], U, size_t N)) + return defToString!(U[])(value[], buffer, format, formatArgs); + else static if (is(T : String) || is(T : MutableString!N, size_t N) || is(T : Array!(char, N), size_t N)) + return defToString!(char[])(value[], buffer, format, formatArgs); + else static if (is(T == typeof(null))) { - leadingZeroes = true; - format.popFront; + if (!buffer.ptr) + return 4; + if (buffer.length < 4) + return -1; + buffer[0 .. 4] = "null"; + return 4; } - if (format.length && format[0] == '*') + else static if (is(T == bool)) { - varLen = true; - format.popFront; + size_t len = value ? 4 : 5; + if (!buffer.ptr) + return len; + if (buffer.length < len) + return -1; + buffer[0 .. len] = value ? "true" : "false"; + return len; } - if (format.length && format[0].isNumeric) + else static if (is(T == char) || is(T == wchar) || is(T == dchar)) { - bool success; - padding = format.parseIntFast(success); - if (varLen) + if (is(T == char) || value <= 0x7F) { - if (padding < 0 || !formatArgs[padding].canInt) - return -2; - padding = formatArgs[padding].getInt; + if (buffer.ptr) + { + if (buffer.length < 1) + return -1; + buffer[0] = cast(char)value; + } + return 1; + } + else if (value <= 0x7FF) + { + if (buffer.ptr) + { + if (buffer.length < 2) + return -1; + buffer[0] = cast(char)(0xC0 | (value >> 6)); + buffer[1] = cast(char)(0x80 | (value & 0x3F)); + } + return 2; + } + else if (value <= 0xFFFF) + { + if (buffer.ptr) + { + if (buffer.length < 3) + return -1; + buffer[0] = cast(char)(0xE0 | (value >> 12)); + buffer[1] = cast(char)(0x80 | ((value >> 6) & 0x3F)); + buffer[2] = cast(char)(0x80 | (value & 0x3F)); + } + return 3; + } + else if (value <= 0x10FFFF) + { + if (buffer.ptr) + { + if (buffer.length < 4) + return -1; + buffer[0] = cast(char)(0xF0 | (value >> 18)); + buffer[1] = cast(char)(0x80 | ((value >> 12) & 0x3F)); + buffer[2] = cast(char)(0x80 | ((value >> 6) & 0x3F)); + buffer[3] = cast(char)(0x80 | (value & 0x3F)); + } + return 4; + } + else + { + assert(false, "Invalid code point"); + return 0; } } - if (format.length) + else static if (is(T == double) || is(T == float)) { - char b = format[0] | 0x20; - if (b == 'x') + import urt.conv : format_float, format_int; + + char[16] tmp = void; + if (format.length && format[0] == '*') { - base = 16; - toLower = format[0] == 'x' && buffer.ptr; + bool success; + size_t arg = format[1..$].parse_int_fast(success); + if (!success || !formatArgs[arg].canInt) + return -2; + size_t width = formatArgs[arg].getInt; + size_t len = width.format_int(tmp); + format = tmp[0..len]; } - else if (b == 'b') - base = 2; - else if (b == 'o') - base = 8; - else if (b == 'd') - base = 10; - format.popFront; + return format_float(value, buffer, format); } - - static if (is(T == long)) - size_t len = formatInt(value, buffer, base, cast(uint)padding, leadingZeroes ? '0' : ' ', showSign); - else - size_t len = formatUint(value, buffer, base, cast(uint)padding, leadingZeroes ? '0' : ' '); - - if (toLower && len > 0) + else static if (is(T == ulong) || is(T == long)) { - for (size_t i = 0; i < len; ++i) - if (cast(uint)(buffer.ptr[i] - 'A') < 26) - buffer.ptr[i] |= 0x20; + return format_int(value, is(T == long), buffer, format, formatArgs); } - - return len; - } - else static if (is(T == ubyte) || is(T == ushort) || is(T == uint)) - { - return defToString(ulong(value), buffer, format, formatArgs); - } - else static if (is(T == byte) || is(T == short) || is(T == int)) - { - return defToString(long(value), buffer, format, formatArgs); - } - else static if (is(T == const(char)*) || is(T == const(char*))) - { - const char[] t = value[0 .. value.strlen]; - return t.defToString(buffer, format, formatArgs); - } - else static if (is(T : const(U)*, U)) - { - static assert(size_t.sizeof == 4 || size_t.sizeof == 8); - enum Fmt = "0" ~ (size_t.sizeof == 4 ? "8" : "16") ~ "X"; - size_t p = cast(size_t)value; - return p.defToString(buffer, Fmt, null); - } - else static if (is(T == const char[])) - { - bool leftJustify = false; - bool varLen = false; - ptrdiff_t width = value.length; - if (format.length && format[0] == '-') + else static if (is(T == ubyte) || is(T == ushort) || is(T == uint)) { - leftJustify = true; - format.popFront; + return defToString(ulong(value), buffer, format, formatArgs); } - if (format.length && format[0] == '*') + else static if (is(T == byte) || is(T == short) || is(T == int)) { - varLen = true; - format.popFront; + return defToString(long(value), buffer, format, formatArgs); } - if (varLen && (!format.length || !format[0].isNumeric)) - return -2; - if (format.length && format[0].isNumeric) + else static if (is(T == const(char)*)) + { + const char[] t = value[0 .. value.strlen]; + return t.defToString(buffer, format, formatArgs); + } + else static if (is(T : const(U)*, U)) { - bool success; - width = format.parseIntFast(success); - if (varLen) + static assert(size_t.sizeof == 4 || size_t.sizeof == 8); + enum ptr_fmt = size_t.sizeof == 4 ? "08X" : "016X"; + size_t p = cast(size_t)value; + return p.defToString(buffer, ptr_fmt, null); + } + else static if (is(T == char[])) + { + bool leftJustify = false; + bool varLen = false; + ptrdiff_t width = value.length; + if (format.length && format[0] == '-') { - if (width < 0 || !formatArgs[width].canInt) - return -2; - width = formatArgs[width].getInt; + leftJustify = true; + format.popFront; + } + if (format.length && format[0] == '*') + { + varLen = true; + format.popFront; + } + if (varLen && (!format.length || !format[0].is_numeric)) + return -2; + if (format.length && format[0].is_numeric) + { + bool success; + width = format.parse_int_fast(success); + if (varLen) + { + if (width < 0 || !formatArgs[width].canInt) + return -2; + width = formatArgs[width].getInt; + } + if (width < value.length) + width = value.length; } - if (width < value.length) - width = value.length; - } - if (!buffer.ptr) - return width; - if (buffer.length < width) - return -1; + if (!buffer.ptr) + return width; + if (buffer.length < width) + return -1; - // TODO: accept padd string in the formatSpec? + // TODO: accept padd string in the formatSpec? - size_t padding = width - value.length; - size_t pad = 0, len = 0; - if (!leftJustify && padding > 0) - { - pad = buffer.length < padding ? buffer.length : padding; - buffer[0 .. pad] = ' '; - buffer.takeFront(pad); + size_t padding = width - value.length; + size_t pad = 0, len = 0; + if (!leftJustify && padding > 0) + { + pad = buffer.length < padding ? buffer.length : padding; + buffer[0 .. pad] = ' '; + buffer.takeFront(pad); + } + len = buffer.length < value.length ? buffer.length : value.length; + buffer[0 .. len] = value[0 .. len]; + if (padding > 0 && leftJustify) + { + buffer.takeFront(len); + pad = buffer.length < padding ? buffer.length : padding; + buffer[0 .. pad] = ' '; + } + return pad + len; } - len = buffer.length < value.length ? buffer.length : value.length; - buffer[0 .. len] = value[0 .. len]; - if (padding > 0 && leftJustify) +// else static if (is(T == wchar[])) +// { +// } +// else static if (is (T == U[], U : dchar)) +// { +// // TODO: UTF ENCODE... +// } + else static if (is(T == void[])) { - buffer.takeFront(len); - pad = buffer.length < padding ? buffer.length : padding; - buffer[0 .. pad] = ' '; - } - return pad + len; - } - else static if (is(T : const char[])) - { - return defToString!(const char[])(cast(const char[])value[], buffer, format, formatArgs); - } -// else static if (is(T : const(wchar)[])) -// { -// } -// else static if (is (T : const(U)[], U : dchar)) -// { -// // TODO: UTF ENCODE... -// } - else static if (is(T == void[]) || is(T == const(void)[])) - { - if (!value.length) - return 0; + if (!value.length) + return 0; - int grp1 = 1, grp2 = 0; - if (format.length && format[0].isNumeric) - { - bool success; - grp1 = cast(int)format.parseIntFast(success); - if (success && format.length > 0 && format[0] == ':' && - format.length > 1 && format[1].isNumeric) + int grp1 = 1, grp2 = 0; + if (format.length && format[0].is_numeric) { - format.popFront(); - grp2 = cast(int)format.parseIntFast(success); + bool success; + grp1 = cast(int)format.parse_int_fast(success); + if (success && format.length > 0 && format[0] == ':' && + format.length > 1 && format[1].is_numeric) + { + format.popFront(); + grp2 = cast(int)format.parse_int_fast(success); + } + if (!success) + return -2; } - if (!success) - return -2; - } - if (!buffer.ptr) - { - size_t len = value.length*2; - if (grp1) - len += (value.length-1) / grp1; - return len; - } + if (!buffer.ptr) + { + size_t len = value.length*2; + if (grp1) + len += (value.length-1) / grp1; + return len; + } - char[] hex = toHexString(cast(ubyte[])value, buffer, grp1, grp2); - return hex.length; - } - else static if (is(T : const U[], U)) - { - // arrays of other stuff - size_t len = 1; - if (buffer.ptr) - { - if (buffer.length < 1) + char[] hex = toHexString(cast(ubyte[])value, buffer, grp1, grp2); + if (!hex.ptr) return -1; - buffer[0] = '['; + return hex.length; } - - for (size_t i = 0; i < value.length; ++i) + else static if (is(T : const U[], U)) { - if (i > 0) + // arrays of other stuff + size_t len = 1; + if (buffer.ptr) + { + if (buffer.length < 1) + return -1; + buffer[0] = '['; + } + + for (size_t i = 0; i < value.length; ++i) { + if (i > 0) + { + if (buffer.ptr) + { + if (len == buffer.length) + return -1; + buffer[len] = ','; + } + ++len; + } + + FormatArg arg = FormatArg(value[i]); if (buffer.ptr) { - if (len == buffer.length) - return -1; - buffer[len] = ','; + ptrdiff_t argLen = arg.getString(buffer.ptr[len .. buffer.length], format, formatArgs); + if (argLen < 0) + return argLen; + len += argLen; } - ++len; + else + len += arg.getLength(format, formatArgs); } - FormatArg arg = FormatArg(value[i]); if (buffer.ptr) { - ptrdiff_t argLen = arg.getString(buffer.ptr[len .. buffer.length], format, formatArgs); - if (argLen < 0) - return argLen; - len += argLen; + if (len == buffer.length) + return -1; + buffer[len] = ']'; } - else - len += arg.getLength(format, formatArgs); + return ++len; } - - if (buffer.ptr) + else static if (is(T B == enum)) { - if (len == buffer.length) - return -1; - buffer[len] = ']'; - } - return ++len; - } - else static if (is(T B == enum)) - { - // TODO: optimise short enums with a TABLE! + import urt.conv : format_int; + import urt.meta.enuminfo : enum_key_from_value; - // TODO: should probably return FQN ??? - string key = null; - val: switch (value) - { - static foreach (i, KeyName; __traits(allMembers, T)) + const(char)[] key = enum_key_from_value!T(value); + + // TODO: should probably return FQN ??? + if (key) { - static if (!EnumKeyIsDuplicate!(T, i)) + size_t len = T.stringof.length + 1 + key.length; + if (buffer.ptr) { - case __traits(getMember, T, KeyName): - key = KeyName; - break val; + if (buffer.length < len) + return -1; + buffer[0 .. T.stringof.length] = T.stringof; + buffer[T.stringof.length] = '.'; + buffer[T.stringof.length + 1 .. len] = key[]; } + return len; } - default: - if (!buffer.ptr) - return T.stringof.length + 2 + defToString!B(cast(B)value, null, null, null); - if (buffer.length < T.stringof.length + 2) - return -1; - buffer[0 .. T.stringof.length] = T.stringof; - buffer[T.stringof.length] = '('; - ptrdiff_t len = defToString!B(*cast(B*)&value, buffer[T.stringof.length + 1 .. $], null, null); - if (len < 0) - return len; - len = T.stringof.length + 2 + len; - if (buffer.length < len) - return -1; - buffer[len - 1] = ')'; + char[24] val = void; + ptrdiff_t len = format_int(long(value), val[]); + if (len <= 0) return len; - } - - size_t len = T.stringof.length + 1 + key.length; - if (!buffer.ptr) - return len; - - if (buffer.length < len) - return -1; - buffer[0 .. T.stringof.length] = T.stringof; - buffer[T.stringof.length] = '.'; - buffer[T.stringof.length + 1 .. len] = key[]; - return len; - } - else static if (is(T == class)) - { - try - { - const(char)[] t = (cast()value).toString(); + size_t total_len = T.stringof.length + 2 + len; if (!buffer.ptr) - return t.length; - if (buffer.length < t.length) - return -1; - buffer[0 .. t.length] = t[]; - return t.length; - } - catch (Exception) - return -1; - } - else static if (is(T == const)) - { - return defToString!(Unqual!T)(cast()value, buffer, format, formatArgs); - } - else static if (is(T == struct)) - { - // general structs - if (buffer.ptr) - { - if (buffer.length < T.stringof.length + 2) + return total_len; + if (buffer.length < total_len) return -1; buffer[0 .. T.stringof.length] = T.stringof; buffer[T.stringof.length] = '('; + buffer[T.stringof.length + 1 .. total_len - 1] = val[0 .. len]; + buffer[total_len - 1] = ')'; + return total_len; + } + else static if (is(T == class)) + { + return value.toString(buffer, format, formatArgs); } + else static if (is(T == struct)) + { + static assert(!__traits(hasMember, T, "toString"), "Struct with custom toString not properly selected!"); - size_t len = T.stringof.length + 1; - static foreach (i; 0 .. value.tupleof.length) - {{ - static if (i > 0) + // general structs + if (buffer.ptr) { + if (buffer.length < T.stringof.length + 2) + return -1; + buffer[0 .. T.stringof.length] = T.stringof; + buffer[T.stringof.length] = '('; + } + + size_t len = T.stringof.length + 1; + static foreach (i; 0 .. value.tupleof.length) + {{ + static if (i > 0) + { + if (buffer.ptr) + { + if (len + 2 > buffer.length) + return -1; + buffer[len .. len + 2] = ", "; + } + len += 2; + } + + FormatArg arg = FormatArg(value.tupleof[i]); if (buffer.ptr) { - if (len + 2 > buffer.length) - return -1; - buffer[len .. len + 2] = ", "; + ptrdiff_t argLen = arg.getString(buffer.ptr[len .. buffer.length], null, null); + if (argLen < 0) + return argLen; + len += argLen; } - len += 2; - } + else + len += arg.getLength(null, null); + + }} - FormatArg arg = FormatArg(value.tupleof[i]); if (buffer.ptr) { - ptrdiff_t argLen = arg.getString(buffer.ptr[len .. buffer.length], null, null); - if (argLen < 0) - return argLen; - len += argLen; + if (len == buffer.length) + return -1; + buffer[len] = ')'; } - else - len += arg.getLength(null, null); - - }} - - if (buffer.ptr) + return ++len; + } + else static if (is(T == function)) { - if (len == buffer.length) - return -1; - buffer[len] = ')'; + assert(false, "TODO"); + return 0; + } + else static if (is(T == delegate)) + { + assert(false, "TODO"); + return 0; } - return ++len; + else + static assert(false, "Not implemented for type: ", T.stringof); } - else - static assert(false, "Not implemented for type: ", T.stringof); } +} + +ptrdiff_t format_int(ulong value, bool signed, char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) +{ + import urt.conv : format_int, format_uint; + + // TODO: what formats are interesting for ints? - static if (isSomeInt!T || is(T == bool)) + bool show_sign = false; + bool leadingZeroes = false; + bool to_lower = false; + bool varLen = false; + ptrdiff_t padding = 0; + uint base = 10; + + if (signed && format.length && format[0] == '+') + { + show_sign = true; + format.popFront; + } + if (format.length && format[0] == '0') { - ptrdiff_t toInt() const pure nothrow @nogc + leadingZeroes = true; + format.popFront; + } + if (format.length && format[0] == '*') + { + varLen = true; + format.popFront; + } + if (format.length && format[0].is_numeric) + { + bool success; + padding = format.parse_int_fast(success); + if (varLen) + { + if (padding < 0 || !formatArgs[padding].canInt) + return -2; + padding = formatArgs[padding].getInt; + } + } + if (format.length) + { + char b = format[0] | 0x20; + if (b == 'x') { - static if (T.max > ptrdiff_t.max) - debug assert(value <= ptrdiff_t.max); - return cast(ptrdiff_t)value; + base = 16; + to_lower = format[0] == 'x' && buffer.ptr; } + else if (b == 'b') + base = 2; + else if (b == 'o') + base = 8; + else if (b == 'd') + base = 10; + format.popFront; } + + ptrdiff_t len; + if (signed) + len = format_int(cast(ptrdiff_t)value, buffer, base, cast(uint)padding, leadingZeroes ? '0' : ' ', show_sign); + else + len = format_uint(value, buffer, base, cast(uint)padding, leadingZeroes ? '0' : ' '); + + if (to_lower && len > 0) + { + for (size_t i = 0; i < len; ++i) + if (cast(uint)(buffer.ptr[i] - 'A') < 26) + buffer.ptr[i] |= 0x20; + } + + return len; } -char[] concatImpl(char[] buffer, const(FormatArg)[] args) nothrow @nogc +char[] concat_impl(char[] buffer, const(StringifyFunc)[] args) nothrow @nogc { size_t len = 0; foreach (a; args) { - ptrdiff_t r = a.getString(buffer.ptr ? buffer[len..$] : null, null, null); + ptrdiff_t r = a(buffer.ptr ? buffer[len..$] : null, null, null); if (r < 0) return null; len += r; @@ -744,7 +926,7 @@ ptrdiff_t parseFormat(ref const(char)[] format, ref char[] buffer, const(FormatA // get the arg index bool success; - arg = format.parseIntFast(success); + arg = format.parse_int_fast(success); if (!success) { assert(false, "Invalid format string: Number expected!"); @@ -807,7 +989,7 @@ ptrdiff_t parseFormat(ref const(char)[] format, ref char[] buffer, const(FormatA // } bool success; - ptrdiff_t index = formatSpec.parseIntFast(success); + ptrdiff_t index = formatSpec.parse_int_fast(success); // if (varRef) // { // if (arg < 0 || !args[arg].canInt) @@ -861,6 +1043,8 @@ ptrdiff_t parseFormat(ref const(char)[] format, ref char[] buffer, const(FormatA if (bytes < 0) return -2; char[] t = formatImpl(buffer, indirectFormat.ptr[0 .. bytes], args); + if (!t.ptr) + return -1; len = t.length; } else @@ -916,40 +1100,6 @@ unittest } - - -// a template that tests is all template args are a char array, or a char -template allAreStrings(Args...) -{ - static if (Args.length == 1) - enum allAreStrings = is(Args[0] : const(char[])) || is(isSomeChar!(Args[0])); - else - enum allAreStrings = (is(Args[0] : const(char[])) || is(isSomeChar!(Args[0]))) && allAreStrings!(Args[1 .. $]); -} - -template allConstCorrectStrings(Args...) -{ - static if (Args.length == 1) - enum allConstCorrectStrings = is(Args[0] == const(char[])) || is(Args[0] == const char); - else - enum allConstCorrectStrings = (is(Args[0] == const(char[])) || is(Args[0] == const char)) && allConstCorrectStrings!(Args[1 .. $]); -} - -template constCorrectedStrings(Args...) -{ - import urt.meta : AliasSeq; - alias constCorrectedStrings = AliasSeq!(); - static foreach (Ty; Args) - { - static if (is(Ty : const(char)[])) - constCorrectedStrings = AliasSeq!(constCorrectedStrings, const(char[])); - else static if (isSomeChar!Ty) - constCorrectedStrings = AliasSeq!(constCorrectedStrings, const(char)); - else - static assert(false, "Argument must be a char array or a char: ", T); - } -} - template EnumKeyIsDuplicate(Enum, size_t item) { alias Elements = __traits(allMembers, Enum); diff --git a/src/urt/string/package.d b/src/urt/string/package.d index c4abc6f..2c6484c 100644 --- a/src/urt/string/package.d +++ b/src/urt/string/package.d @@ -1,132 +1,253 @@ module urt.string; +import urt.string.uni; +import urt.traits : is_some_char; + public import urt.string.ascii; public import urt.string.string; public import urt.string.tailstring; // seful string operations defined elsewhere public import urt.array : empty, popFront, popBack, takeFront, takeBack; -public import urt.mem : strlen; - +public import urt.mem : strlen, wcslen; +public import urt.mem.temp : tstringz, twstringz; -enum TempStringBufferLen = 1024; -enum TempStringMaxLen = TempStringBufferLen / 2; +nothrow @nogc: -static char[TempStringBufferLen] s_tempStringBuffer; -static size_t s_tempStringBufferPos = 0; +inout(char)[] c_string(inout(char)* cstr) pure + => cstr ? cstr[0 .. cstr.strlen] : null; -char[] allocTempString(size_t len) nothrow @nogc +size_t strlen_s(const(char)[] s) pure { - assert(len <= TempStringMaxLen); + size_t len = 0; + while (len < s.length && s[len] != '\0') + ++len; + return len; +} - if (len <= TempStringBufferLen - s_tempStringBufferPos) +ptrdiff_t cmp(bool case_insensitive = false, T, U)(const(T)[] a, const(U)[] b) pure +{ + static if (case_insensitive) + return uni_compare_i(a, b); + else { - char[] s = s_tempStringBuffer[s_tempStringBufferPos .. s_tempStringBufferPos + len]; - s_tempStringBufferPos += len; - return s; + static if (is(T == U)) + { + if (a.length != b.length) + return a.length - b.length; + } + return uni_compare(a, b); } - s_tempStringBufferPos = len; - return s_tempStringBuffer[0 .. len]; } -char* tstringz(const(char)[] str) nothrow @nogc -{ - char[] buffer = allocTempString(str.length + 1); - buffer[0..str.length] = str[]; - buffer[str.length] = 0; - return buffer.ptr; -} +ptrdiff_t icmp(T, U)(const(T)[] a, const(U)[] b) pure + => cmp!true(a, b); -wchar* twstringz(const(char)[] str) nothrow @nogc +bool eq(const(char)[] a, const(char)[] b) pure + => cmp(a, b) == 0; + +bool ieq(const(char)[] a, const(char)[] b) pure + => cmp!true(a, b) == 0; + +size_t findFirst(bool case_insensitive = false, T, U)(const(T)[] s, const U c) + if (is_some_char!T && is_some_char!U) { - wchar[] buffer = cast(wchar[])allocTempString((str.length + 1) * 2); + static if (is(U == char)) + assert(c <= 0x7F, "Invalid UTF character"); + else static if (is(U == wchar)) + assert(c < 0xD800 || c >= 0xE000, "Invalid UTF character"); - // TODO: actually decode UTF8 into UTF16!! + // TODO: what if `c` is 'ß'? do we find "ss" in case-insensitive mode? + // and if `c` is 's', do we match 'ß'? - foreach (i, c; str) - buffer[i] = c; - buffer[str.length] = 0; - return buffer.ptr; + static if (case_insensitive) + const U lc = cast(U)c.uni_case_fold(); + else + alias lc = c; + + size_t i = 0; + while (i < s.length) + { + static if (U.sizeof <= T.sizeof) + { + enum l = 1; + dchar d = s[i]; + } + else + { + size_t l; + dchar d = next_dchar(s[i..$], l); + } + static if (case_insensitive) + { + static if (is(U == char)) + { + // only fold the ascii characters, since lc is known to be ascii + if (uint(d - 'A') < 26) + d |= 0x20; + } + else + d = d.uni_case_fold(); + } + if (d == lc) + break; + i += l; + } + return i; } -ptrdiff_t cmp(const(char)[] a, const(char)[] b) pure nothrow @nogc +size_t find_first_i(T, U)(const(T)[] s, U c) + if (is_some_char!T && is_some_char!U) + => findFirst!true(s, c); + +size_t findLast(bool case_insensitive = false, T, U)(const(T)[] s, const U c) + if (is_some_char!T && is_some_char!U) { - if (a.length != b.length) - return a.length - b.length; - for (size_t i = 0; i < a.length; ++i) + static assert(case_insensitive == false, "TODO"); + + static if (is(U == char)) + assert(c <= 0x7F, "Invalid unicode character"); + else static if (is(U == wchar)) + assert(c >= 0xD800 && c < 0xE000, "Invalid unicode character"); + + ptrdiff_t last = s.length-1; + while (last >= 0) { - ptrdiff_t diff = a[i] - b[i]; - if (diff) - return diff; + static if (U.sizeof <= T.sizeof) + { + if (s[last] == c) + return cast(size_t)last; + --last; + } + else + { + // this is tricky, because we need to seek backwards to the start of surrogate sequences + assert(false, "TODO"); + } } - return 0; + return s.length; } -ptrdiff_t icmp(const(char)[] a, const(char)[] b) pure nothrow @nogc +size_t find_last_i(T, U)(const(T)[] s, U c) + if (is_some_char!T && is_some_char!U) + => findLast!true(s, c); + +size_t findFirst(bool case_insensitive = false, T, U)(const(T)[] s, const(U)[] t) + if (is_some_char!T && is_some_char!U) { - if (a.length != b.length) - return a.length - b.length; - for (size_t i = 0; i < a.length; ++i) + if (t.length == 0) + return 0; + + // fast-path for one-length tokens + size_t l = t.uni_seq_len(); + if (l == t.length) { - ptrdiff_t diff = toLower(a[i]) - toLower(b[i]); - if (diff) - return diff; + dchar c = t.next_dchar(l); + if (c < 0x80) + return findFirst!case_insensitive(s, cast(char)c); + if (c < 0x10000) + return findFirst!case_insensitive(s, cast(wchar)c); + return findFirst!case_insensitive(s, c); } - return 0; + + size_t offset = 0; + while (offset < s.length) + { + + static if (case_insensitive) + int c = uni_compare_i(s[offset .. $], t); + else + int c = uni_compare(s[offset .. $], t); + if (c == int.max || c == 0) + return offset; + if (c == int.min) + return s.length; + offset += s[offset .. $].uni_seq_len(); + } + return s.length; +} + +size_t find_first_i(T, U)(const(T)[] s, const(U)[] t) + if (is_some_char!T && is_some_char!U) + => findFirst!true(s, t); + +size_t findLast(bool case_insensitive = false, T, U)(const(T)[] s, const(U)[] t) + if (is_some_char!T && is_some_char!U) +{ + // this is tricky, because we need to seek backwards to the start of surrogate sequences + assert(false, "TODO"); } -bool ieq(const(char)[] a, const(char)[] b) pure nothrow @nogc - => icmp(a, b) == 0; +size_t find_last_i(T, U)(const(T)[] s, const(U)[] t) + if (is_some_char!T && is_some_char!U) + => findLast!true(s, t); -bool startsWith(const(char)[] s, const(char)[] prefix) pure nothrow @nogc +bool contains(bool case_insensitive = false, T, U)(const(T)[] s, U c, size_t *offset = null) + if (is_some_char!T && is_some_char!U) +{ + size_t i = findFirst!case_insensitive(s, c); + if (i == s.length) + return false; + if (offset) + *offset = i; + return true; +} + +bool contains(bool case_insensitive = false, T, U)(const(T)[] s, const(U)[] t, size_t *offset = null) + if (is_some_char!T && is_some_char!U) +{ + size_t i = findFirst!case_insensitive(s, t); + if (i == s.length) + return false; + if (offset) + *offset = i; + return true; +} + +bool contains_i(T, U)(const(T)[] s, U c, size_t *offset = null) + if (is_some_char!T && is_some_char!U) + => contains!true(s, c, offset); + +bool contains_i(T, U)(const(T)[] s, const(U)[] t, size_t *offset = null) + if (is_some_char!T && is_some_char!U) + => contains!true(s, t, offset); + +bool startsWith(const(char)[] s, const(char)[] prefix) pure { if (s.length < prefix.length) return false; - return s[0 .. prefix.length] == prefix[]; + return cmp(s[0 .. prefix.length], prefix) == 0; } -bool endsWith(const(char)[] s, const(char)[] suffix) pure nothrow @nogc +bool endsWith(const(char)[] s, const(char)[] suffix) pure { if (s.length < suffix.length) return false; - return s[$ - suffix.length .. $] == suffix[]; + return cmp(s[$ - suffix.length .. $], suffix) == 0; } -inout(char)[] trim(bool Front = true, bool Back = true)(inout(char)[] s) pure nothrow @nogc +inout(char)[] trim(alias pred = is_whitespace, bool Front = true, bool Back = true)(inout(char)[] s) pure { size_t first = 0, last = s.length; static if (Front) { - while (first < s.length && isWhitespace(s.ptr[first])) + while (first < s.length && pred(s.ptr[first])) ++first; } static if (Back) { - while (last > first && isWhitespace(s.ptr[last - 1])) + while (last > first && pred(s.ptr[last - 1])) --last; } return s.ptr[first .. last]; } -alias trimFront = trim!(true, false); +alias trimFront(alias pred = is_whitespace) = trim!(pred, true, false); -alias trimBack = trim!(false, true); +alias trimBack(alias pred = is_whitespace) = trim!(pred, false, true); -inout(char)[] trimComment(char Delimiter)(inout(char)[] s) -{ - size_t i = 0; - for (; i < s.length; ++i) - { - if (s[i] == Delimiter) - break; - } - while(i > 0 && (s[i-1] == ' ' || s[i-1] == '\t')) - --i; - return s[0 .. i]; -} - -inout(char)[] takeLine(ref inout(char)[] s) pure nothrow @nogc +inout(char)[] takeLine(ref inout(char)[] s) pure { for (size_t i = 0; i < s.length; ++i) { @@ -148,20 +269,26 @@ inout(char)[] takeLine(ref inout(char)[] s) pure nothrow @nogc return t; } -inout(char)[] split(char Separator, bool HandleQuotes = true)(ref inout(char)[] s) +inout(char)[] split(char[] separators, bool handle_quotes = true, bool do_trim = true)(ref inout(char)[] s, char* separator = null) pure { - static if (HandleQuotes) + static if (handle_quotes) int inQuotes = 0; else enum inQuotes = false; size_t i = 0; - for (; i < s.length; ++i) + loop: for (; i < s.length; ++i) { - if (s[i] == Separator && !inQuotes) - break; - - static if (HandleQuotes) + static foreach (sep; separators) + { + if (s[i] == sep && !inQuotes) + { + if (separator) + *separator = s[i]; + break loop; + } + } + static if (handle_quotes) { if (s[i] == '"' && !(inQuotes & 0x6)) inQuotes = 1 - inQuotes; @@ -171,40 +298,29 @@ inout(char)[] split(char Separator, bool HandleQuotes = true)(ref inout(char)[] inQuotes = 4 - inQuotes; } } - inout(char)[] t = s[0 .. i].trimBack; - s = i < s.length ? s[i+1 .. $].trimFront : null; + static if (do_trim) + { + inout(char)[] t = s[0 .. i].trimBack; + s = i < s.length ? s[i+1 .. $].trimFront : null; + } + else + { + inout(char)[] t = s[0 .. i]; + s = i < s.length ? s[i+1 .. $] : null; + } return t; } -inout(char)[] split(Separator...)(ref inout(char)[] s, out char sep) +alias split(char separator, bool handle_quotes = true, bool do_trim = true) = split!([separator], handle_quotes, do_trim); + +// TODO: deprecate this one... +inout(char)[] split(separators...)(ref inout(char)[] s, out char sep) pure { sep = '\0'; - int inQuotes = 0; - size_t i = 0; - loop: for (; i < s.length; ++i) - { - static foreach (S; Separator) - { - static assert(is(typeof(S) == char), "Only single character separators supported"); - if (s[i] == S && !inQuotes) - { - sep = s[i]; - break loop; - } - } - if (s[i] == '"' && !(inQuotes & 0x6)) - inQuotes = 1 - inQuotes; - else if (s[i] == '\'' && !(inQuotes & 0x5)) - inQuotes = 2 - inQuotes; - else if (s[i] == '`' && !(inQuotes & 0x3)) - inQuotes = 4 - inQuotes; - } - inout(char)[] t = s[0 .. i].trimBack; - s = i < s.length ? s[i+1 .. $].trimFront : null; - return t; + return split!([separators], true, true)(s, &sep); } -char[] unQuote(const(char)[] s, char[] buffer) pure nothrow @nogc +char[] unQuote(const(char)[] s, char[] buffer) pure { // TODO: should this scan and match quotes rather than assuming there are no rogue closing quotes in the middle of the string? if (s.empty) @@ -223,18 +339,18 @@ char[] unQuote(const(char)[] s, char[] buffer) pure nothrow @nogc return buffer; } -char[] unQuote(char[] s) pure nothrow @nogc +char[] unQuote(char[] s) pure { return unQuote(s, s); } -char[] unQuote(const(char)[] s) nothrow @nogc +char[] unQuote(const(char)[] s) { import urt.mem.temp : talloc; return unQuote(s, cast(char[])talloc(s.length)); } -char[] unEscape(inout(char)[] s, char[] buffer) pure nothrow @nogc +char[] unEscape(inout(char)[] s, char[] buffer) pure { if (s.empty) return null; @@ -266,17 +382,17 @@ char[] unEscape(inout(char)[] s, char[] buffer) pure nothrow @nogc return buffer[0..len]; } -char[] unEscape(char[] s) pure nothrow @nogc +char[] unEscape(char[] s) pure { return unEscape(s, s); } -char[] toHexString(const(void[]) data, char[] buffer, uint group = 0, uint secondaryGroup = 0, const(char)[] seps = " -") pure nothrow @nogc +char[] toHexString(const(void[]) data, char[] buffer, uint group = 0, uint secondaryGroup = 0, const(char)[] seps = " -") pure { - import urt.util : isPowerOf2; - assert(group.isPowerOf2); - assert(secondaryGroup.isPowerOf2); + import urt.util : is_power_of_2; + assert(group.is_power_of_2); + assert(secondaryGroup.is_power_of_2); assert((secondaryGroup == 0 && seps.length > 0) || seps.length > 1, "Secondary grouping requires additional separator"); if (data.length == 0) @@ -296,8 +412,8 @@ char[] toHexString(const(void[]) data, char[] buffer, uint group = 0, uint secon size_t offset = 0; for (size_t i = 0; true; ) { - buffer[offset++] = hexDigits[src[i] >> 4]; - buffer[offset++] = hexDigits[src[i] & 0xF]; + buffer[offset++] = hex_digits[src[i] >> 4]; + buffer[offset++] = hex_digits[src[i] & 0xF]; bool sep = (i & mask) == mask; if (++i == data.length) @@ -307,7 +423,7 @@ char[] toHexString(const(void[]) data, char[] buffer, uint group = 0, uint secon } } -char[] toHexString(const(ubyte[]) data, uint group = 0, uint secondaryGroup = 0, const(char)[] seps = " -") nothrow @nogc +char[] toHexString(const(ubyte[]) data, uint group = 0, uint secondaryGroup = 0, const(char)[] seps = " -") { import urt.mem.temp; @@ -319,7 +435,7 @@ char[] toHexString(const(ubyte[]) data, uint group = 0, uint secondaryGroup = 0, unittest { - ubyte[] data = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF]; + ubyte[8] data = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF]; assert(data.toHexString(0) == "0123456789ABCDEF"); assert(data.toHexString(1) == "01 23 45 67 89 AB CD EF"); assert(data.toHexString(2) == "0123 4567 89AB CDEF"); @@ -329,17 +445,476 @@ unittest } -bool wildcardMatch(const(char)[] wildcard, const(char)[] value) +// Pattern grammar: +// * - Match zero or more characters +// ? - Match exactly one character +// # - Match exactly one digit (0-9) +// ~T - Token T is optional (matches with or without T) +// \C - Escape character C (literal match) +// Examples: +// "h*o" matches "hello", "ho" +// "h?llo" matches "hello", "hallo" but not "hllo" +// "v#.#" matches "v1.2", "v3.7" but not "va.b" +// "~ab" matches "ab", "b" +// "h\*o" matches "h*o" literally +bool wildcard_match(const(char)[] wildcard, const(char)[] value, bool value_wildcard = false, bool case_insensitive = false) pure { - // TODO: write this function... + const(char)* a = wildcard.ptr, ae = a + wildcard.length, b = value.ptr, be = b + value.length; - // HACK: we just use this for tail wildcards right now... - for (size_t i = 0; i < wildcard.length; ++i) + static inout(char)* skip_wilds(inout(char)* p, const(char)* pe) { - if (wildcard[i] == '*') - return true; - if (wildcard[i] != value[i]) + while (p < pe) + { + if (*p == '*') + ++p; + else if (*p == '~') + { + one_more: + if (++p < pe) + { + if (*p == '~') + goto one_more; + if (*p++ == '\\' && p < pe) + ++p; + } + } + else break; + } + // HACK: skip trailing slash (handle a degenerate case) + if (p == pe - 1 && *p == '\\') + ++p; + return p; + } + + struct BacktrackState + { + const(char)* a, b; + } + BacktrackState[64] backtrack_stack = void; + size_t backtrack_depth = 0; + + char ca_orig = void, cb_orig = void, ca = void, cb = void; + + while (a < ae && b < be) + { + ca_orig = *a, cb_orig = *b; + + // handle wildcards + if (ca_orig == '*') + { + a = skip_wilds(++a, ae); + if (a == ae) // tail star matches everything + return true; + + const(char)[] a_remain = a[0 .. ae - a]; + for (; b <= be; ++b) + { + if (wildcard_match(a_remain, b[0 .. be - b], value_wildcard, case_insensitive)) + return true; + } return false; + } + + // handle optionals + if (ca_orig == '~') + { + while (++a < ae && *a == '~') {} + if (a == ae) + break; + + if (backtrack_depth < backtrack_stack.length) + { + backtrack_stack[backtrack_depth].a = a + (*a == '\\' ? 2 : 1); + backtrack_stack[backtrack_depth].b = b; + ++backtrack_depth; + } + continue; + } + + // handle escape + ca = ca_orig, cb = cb_orig; + if (ca == '\\') + { + if (++a < ae) + ca = *a; + else + break; + } + + // handle value wildcards + if (value_wildcard) + { + if (cb_orig == '*') + { + b = skip_wilds(++b, be); + if (b == be) // tail star matches everything + return true; + + const(char)[] b_remain = b[0 .. be - b]; + for (; a <= ae; ++a) + { + if (wildcard_match(a[0 .. ae - a], b_remain, true, case_insensitive)) + return true; + } + return false; + } + if (cb_orig == '~') + { + while (++b < be && *b == '~') {} + if (b == be) + break; + + if (backtrack_depth < backtrack_stack.length) + { + backtrack_stack[backtrack_depth].a = a; + backtrack_stack[backtrack_depth].b = b + (*b == '\\' ? 2 : 1); + ++backtrack_depth; + } + continue; + } + if (cb == '\\') + { + if (++b < be) + cb = *b; + else + break; + } + if (cb_orig == '#') + { + if (ca.is_numeric || ca_orig == '#') + goto advance; + } + } + + // compare next char + if (ca_orig == '#') + { + if (cb.is_numeric) + goto advance; + } + else if ((case_insensitive ? ca.to_lower == cb.to_lower : ca == cb) || (ca_orig == '?') || (value_wildcard && cb_orig == '?')) + goto advance; + + try_backtrack: + if (backtrack_depth == 0) + return false; + + --backtrack_depth; + a = backtrack_stack[backtrack_depth].a; + b = backtrack_stack[backtrack_depth].b; + continue; + + advance: + ++a, ++b; + } + + // check the strings are equal... + if (a == ae) + { + if (value_wildcard) + b = skip_wilds(b, be); + if (b == be) + return true; } - return wildcard.length == value.length; + else if (b == be && skip_wilds(a, ae) == ae) + return true; + + goto try_backtrack; +} + +bool wildcard_match_i(const(char)[] wildcard, const(char)[] value, bool value_wildcard = false) pure + => wildcard_match(wildcard, value, value_wildcard, true); + + +unittest +{ + // test findFirst + assert("hello".findFirst('e') == 1); + assert("hello".findFirst('a') == 5); + assert("hello".findFirst("e") == 1); + assert("hello".findFirst("ll") == 2); + assert("hello".findFirst("lo") == 3); + assert("hello".findFirst("la") == 5); + assert("hello".findFirst("low") == 5); + assert("héllo".findFirst('é') == 1); + assert("héllo"w.findFirst('é') == 1); + assert("héllo".findFirst("éll") == 1); + assert("héllo".findFirst('a') == 6); + assert("héllo".findFirst("la") == 6); + assert("hello".find_first_i('E') == 1); + assert("HELLO".find_first_i("e") == 1); + assert("hello".find_first_i("LL") == 2); + assert("héllo".find_first_i('É') == 1); + assert("HÉLLO".find_first_i("é") == 1); + assert("HÉLLO".find_first_i("éll") == 1); + + assert("HÉLLO".contains('É')); + assert(!"HÉLLO".contains('A')); + assert("HÉLLO".contains_i("éll")); + + // test wildcard_match + assert(wildcard_match("hello", "hello")); + assert(!wildcard_match("hello", "world")); + assert(wildcard_match("h*o", "hello")); + assert(wildcard_match("h*", "hello")); + assert(wildcard_match("*o", "hello")); + assert(wildcard_match("*", "hello")); + assert(wildcard_match("h?llo", "hello")); + assert(!wildcard_match("h?llo", "hllo")); + assert(wildcard_match("h??lo", "hello")); + assert(!wildcard_match("a*b", "axxxc")); + + // test optional - basic cases + assert(wildcard_match("~ab", "b")); + assert(wildcard_match("~ab", "ab")); + assert(wildcard_match("a~b", "a")); + assert(wildcard_match("a~b", "ab")); + assert(!wildcard_match("~ab", "a")); + assert(!wildcard_match("a~b", "b")); + assert(!wildcard_match("a~b", "ac")); + + // optional - multiple optionals + assert(wildcard_match("~a~b", "")); + assert(wildcard_match("~a~b", "a")); + assert(wildcard_match("~a~b", "b")); + assert(wildcard_match("~a~b", "ab")); + assert(!wildcard_match("~a~b", "ba")); + assert(wildcard_match("~a~b~c", "")); + assert(wildcard_match("~a~b~c", "ac")); + assert(wildcard_match("~a~b~c", "abc")); + + // optional with wildcards + assert(wildcard_match("~a*", "")); + assert(wildcard_match("~a*", "a")); + assert(wildcard_match("~a*", "abc")); + assert(wildcard_match("*~a", "")); + assert(wildcard_match("*~a", "a")); + assert(wildcard_match("*~a", "xya")); + assert(wildcard_match("a~b*c", "ac")); + assert(wildcard_match("a~b*c", "abc")); + assert(wildcard_match("a~b*c", "abxc")); + assert(wildcard_match("a~b*c", "axbc")); + assert(!wildcard_match("a*~bc", "a")); + assert(wildcard_match("a*~bc", "ac")); + assert(wildcard_match("a*~bc", "abc")); + assert(wildcard_match("a*~bc", "axbc")); + + // optional with ? + assert(wildcard_match("~a?", "a")); + assert(wildcard_match("~a?", "x")); + assert(wildcard_match("~a?", "ax")); + assert(wildcard_match("?~a", "x")); + assert(wildcard_match("?~a", "xa")); + assert(wildcard_match("?~a", "a")); + assert(wildcard_match("?~a", "aa")); + + // optional with # + assert(wildcard_match("~a#", "5")); + assert(wildcard_match("~a#", "a5")); + assert(!wildcard_match("~a#", "a")); + assert(!wildcard_match("~a#", "ax")); + assert(wildcard_match("v~#.#", "v.5")); + assert(wildcard_match("v~#.#", "v1.5")); + + // optional with escape + assert(wildcard_match("~\\*", "")); + assert(wildcard_match("~\\*", "*")); + assert(!wildcard_match("~\\*", "x")); + assert(wildcard_match("a~\\*b", "ab")); + assert(wildcard_match("a~\\*b", "a*b")); + assert(!wildcard_match("a~\\*b", "axb")); + + // double optional ~~ + assert(wildcard_match("~~a", "")); + assert(wildcard_match("~~a", "a")); + assert(!wildcard_match("~~a", "aa")); + + // degenerates + assert(wildcard_match("a\\", "a")); + assert(!wildcard_match("a\\", "")); + assert(!wildcard_match("a\\", "x")); + assert(wildcard_match("a~", "a")); + assert(!wildcard_match("a~", "")); + assert(!wildcard_match("a~", "x")); + assert(wildcard_match("a~\\", "a")); + assert(!wildcard_match("a~\\", "")); + assert(!wildcard_match("a~\\", "x")); + + // optional with value_wildcard - basic + assert(wildcard_match("~b", "", true)); + assert(wildcard_match("~b", "b", true)); + assert(wildcard_match("", "~b", true)); + assert(wildcard_match("b", "~b", true)); + assert(wildcard_match("ab", "~ab", true)); + assert(wildcard_match("ab", "~a~b", true)); + assert(wildcard_match("~ab", "ab", true)); + assert(wildcard_match("~ab", "~ab", true)); + assert(wildcard_match("~ab", "~a~b", true)); + assert(wildcard_match("a~b", "~ab", true)); + assert(wildcard_match("a~b", "~a~b", true)); + assert(wildcard_match("~a~b", "~ab", true)); + assert(wildcard_match("~a~b", "~a~b", true)); + + // optional with value_wildcard - with wildcards on rhs + assert(wildcard_match("~a", "*", true)); + assert(wildcard_match("~ab", "*", true)); + assert(wildcard_match("~a~b", "*", true)); + assert(wildcard_match("*", "~a", true)); + assert(wildcard_match("*", "~ab", true)); + assert(wildcard_match("*", "~a~b", true)); + assert(wildcard_match("~a", "?", true)); + assert(wildcard_match("?", "~a", true)); + assert(wildcard_match("~ab", "?", true)); + assert(wildcard_match("~ab", "?b", true)); + assert(wildcard_match("~ab", "a?", true)); + assert(wildcard_match("~ab", "??", true)); + assert(wildcard_match("?", "~ab", true)); + assert(wildcard_match("?b", "~ab", true)); + assert(wildcard_match("a?", "~ab", true)); + assert(wildcard_match("??", "~ab", true)); + assert(wildcard_match("~ab", "?b", true)); + assert(wildcard_match("~abc", "?c", true)); + assert(wildcard_match("~a*", "*", true)); + assert(wildcard_match("*~a", "*", true)); + assert(wildcard_match("*", "~a*", true)); + assert(wildcard_match("*", "*~a", true)); + assert(wildcard_match("ab", "*~c", true)); + assert(wildcard_match("abc", "a?~c", true)); + + // optional on both sides with wildcards + assert(wildcard_match("~a*", "*~b", true)); + assert(wildcard_match("a~b*", "*~cd", true)); + assert(wildcard_match("~ab", "*b", true)); + assert(wildcard_match("~ab", "*ab", true)); + assert(wildcard_match("x~ab", "*ab", true)); + assert(wildcard_match("*b", "~ab", true)); + assert(wildcard_match("*ab", "~ab", true)); + assert(wildcard_match("*ab", "x~ab", true)); + assert(wildcard_match("~a~b", "~c~d", true)); + assert(wildcard_match("~a~b", "~c~da", true)); + assert(wildcard_match("~a~b", "~c~db", true)); + assert(wildcard_match("~a~b", "~c~dab", true)); + assert(wildcard_match("~a~bc", "~c~d", true)); + assert(wildcard_match("~a~bd", "~c~d", true)); + assert(wildcard_match("~a~bcd", "~c~d", true)); + assert(wildcard_match("*a~bc*d", "xxacxxd", true)); + assert(!wildcard_match("*a~bc*de", "xxabcxxd", true)); + assert(!wildcard_match("*a~bc*d", "xxabcxxde", true)); + assert(wildcard_match("*a~bc*d", "~x~x~a~c~x~x~d", true)); + + // case insensitive with optional + assert(wildcard_match_i("~a", "A")); + assert(wildcard_match_i("~aB", "Ab")); + assert(wildcard_match_i("A~b", "aB")); + + // multiple wildcards + assert(wildcard_match("*l*o", "hello")); + assert(wildcard_match("h*l*o", "hello")); + assert(wildcard_match("h*l*", "hello")); + assert(wildcard_match("*e*l*", "hello")); + assert(wildcard_match("*h*e*l*l*o*", "hello")); + + // wildcards with sequences in between + assert(wildcard_match("h*ll*", "hello")); + assert(wildcard_match("*el*", "hello")); + assert(wildcard_match("h*el*o", "hello")); + assert(!wildcard_match("h*el*x", "hello")); + assert(wildcard_match("*lo", "hello")); + assert(!wildcard_match("*lx", "hello")); + + // mixed wildcards and single matches + assert(wildcard_match("h?*o", "hello")); + assert(wildcard_match("h*?o", "hello")); + assert(wildcard_match("?e*o", "hello")); + assert(wildcard_match("h?ll?", "hello")); + assert(!wildcard_match("h?ll?", "hllo")); + + // overlapping wildcards + assert(wildcard_match("**hello", "hello")); + assert(wildcard_match("hello**", "hello")); + assert(wildcard_match("h**o", "hello")); + assert(wildcard_match("*?*", "hello")); + assert(wildcard_match("?*?", "hello")); + assert(!wildcard_match("?*?", "x")); + assert(wildcard_match("?*?", "xx")); + + // escape sequences + assert(wildcard_match("\\*", "*")); + assert(wildcard_match("\\?", "?")); + assert(wildcard_match("\\#", "#")); + assert(wildcard_match("\\\\", "\\")); + assert(!wildcard_match("\\*", "a")); + assert(!wildcard_match("\\?", "a")); + assert(!wildcard_match("\\#", "5")); + assert(wildcard_match("h\\*o", "h*o")); + assert(!wildcard_match("h\\*o", "hello")); + assert(wildcard_match("\\*\\?\\\\", "*?\\")); + assert(wildcard_match("a\\*b*c", "a*bxyzc")); + assert(wildcard_match("*\\**", "hello*world")); + + // edge cases + assert(wildcard_match("", "")); + assert(!wildcard_match("", "a")); + assert(wildcard_match("*", "")); + assert(wildcard_match("**", "")); + assert(!wildcard_match("?", "")); + assert(wildcard_match("a*b*c", "abc")); + assert(wildcard_match("a*b*c", "aXbYc")); + assert(wildcard_match("a*b*c", "aXXbYYc")); + + // value_wildcard tests - bidirectional matching + assert(wildcard_match("hello", "h*o", true)); + assert(wildcard_match("h*o", "hello", true)); + assert(wildcard_match("h?llo", "he?lo", true)); + assert(wildcard_match("h\\*o", "h\\*o", true)); + assert(wildcard_match("test*", "*test", true)); + + // both sides have wildcards + assert(wildcard_match("h*o", "h*o", true)); + assert(wildcard_match("*hello*", "*world*", true)); + assert(wildcard_match("a*b*c", "a*b*c", true)); + assert(wildcard_match("*", "*", true)); + assert(wildcard_match("?", "?", true)); + + // complex interplay - wildcards matching wildcards + assert(wildcard_match("a*c", "a?c", true)); + assert(wildcard_match("a?c", "a*c", true)); + assert(wildcard_match("*abc", "?abc", true)); + assert(wildcard_match("abc*", "abc?", true)); + + // multiple wildcards on both sides + assert(wildcard_match("a*b*c", "a?b?c", true)); + assert(wildcard_match("*a*b*", "?a?b?", true)); + assert(wildcard_match("a**b", "a*b", true)); + assert(wildcard_match("a*b", "a**b", true)); + + // wildcards at different positions + assert(wildcard_match("*test", "test*", true)); + assert(wildcard_match("test*end", "*end", true)); + assert(wildcard_match("*middle*", "start*", true)); + + // edge cases with value_wildcard + assert(wildcard_match("", "", true)); + assert(wildcard_match("*", "", true)); + assert(wildcard_match("", "*", true)); + assert(wildcard_match("**", "*", true)); + assert(wildcard_match("*", "**", true)); + + // digit wildcard tests + assert(wildcard_match("#", "0")); + assert(wildcard_match("#", "5")); + assert(wildcard_match("#", "9")); + assert(!wildcard_match("#", "a")); + assert(!wildcard_match("#", "A")); + assert(!wildcard_match("#", "")); + assert(!wildcard_match("#", "12")); + assert(!wildcard_match("#", "#")); + assert(wildcard_match("#", "#", true)); + assert(!wildcard_match("#", "\\#", true)); + assert(wildcard_match("v#.#", "v1.2")); + assert(!wildcard_match("v#.#", "va.b")); + assert(!wildcard_match("v#.#", "v1.")); + assert(wildcard_match("port-##", "port-42")); + assert(wildcard_match("#*#", "123")); + assert(!wildcard_match("#*#", "abc")); } diff --git a/src/urt/string/regex.d b/src/urt/string/regex.d new file mode 100644 index 0000000..20b05d7 --- /dev/null +++ b/src/urt/string/regex.d @@ -0,0 +1,952 @@ +module urt.string.regex; + +import urt.mem.allocator; + +nothrow @nogc: + + +struct RegexMatch +{ + const(char)[] full; + const(char)[][Regex.MaxGroups] captures; + ubyte num_captures; +} + +bool regex_match(const(char)[] text, const(char)[] pattern, ref RegexMatch result) +{ + Regex re = regex_compile(pattern, tempAllocator()); + if (!re.valid) + return false; + return re.exec(text, result); +} + +// Compiled regex program. Single contiguous allocation for all instructions +// and character class data. Compile with regex_compile(), run with exec(). +// +// Supported syntax: +// . any character +// \d \D digit / non-digit +// \s \S whitespace / non-whitespace +// \w \W word char [a-zA-Z0-9_] / non-word +// \. \\ etc literal escapes +// [abc] character class +// [^abc] negated character class +// [a-z] character range in class +// * + ? greedy quantifiers +// *? +? ?? non-greedy (lazy) quantifiers +// (...) capture group (first group returned) +// (a|b) alternation +// ^ $ anchors (start/end of text) +struct Regex +{ +nothrow @nogc: + + enum MaxGroups = 8; + + bool valid() const + => data.ptr !is null; + + // Execute against text. Unanchored unless pattern used ^. + bool exec(const(char)[] text, ref RegexMatch result) const + { + if (!valid) + return false; + + ref const Header hdr = *cast(const(Header)*)data.ptr; + const(Inst)[] code = (cast(const(Inst)*)(data.ptr + Header.sizeof))[0 .. hdr.num_insts]; + const(ClassRange)[] ranges = (cast(const(ClassRange)*)(data.ptr + Header.sizeof + hdr.num_insts * Inst.sizeof))[0 .. hdr.num_ranges]; + const(ClassDef)[] classes = (cast(const(ClassDef)*)(data.ptr + Header.sizeof + hdr.num_insts * Inst.sizeof + hdr.num_ranges * ClassRange.sizeof))[0 .. hdr.num_classes]; + + struct Thread + { + ushort ipc, pos; + ushort[MaxGroups] gs, ge; + } + + Thread[512] stack = void; + ushort sp; + + foreach (start; 0 .. hdr.anchored ? 1 : text.length + 1) + { + sp = 0; + Thread t; + t.ipc = 0; + t.pos = cast(ushort)start; + t.gs[] = ushort.max; + t.ge[] = ushort.max; + + bool matched = false; + + while (true) + { + if (t.ipc >= code.length) + break; + + Inst inst = code[t.ipc]; + + final switch (inst.op) with (Op) + { + case literal: + if (t.pos < text.length && text[t.pos] == inst.operand) + ++t.pos, ++t.ipc; + else + goto backtrack; + break; + case any: + if (t.pos < text.length) + ++t.pos, ++t.ipc; + else + goto backtrack; + break; + case digit: + if (t.pos < text.length && is_digit(text[t.pos])) + ++t.pos, ++t.ipc; + else + goto backtrack; + break; + case not_digit: + if (t.pos < text.length && !is_digit(text[t.pos])) + ++t.pos, ++t.ipc; + else + goto backtrack; + break; + case space: + if (t.pos < text.length && is_space(text[t.pos])) + ++t.pos, ++t.ipc; + else + goto backtrack; + break; + case not_space: + if (t.pos < text.length && !is_space(text[t.pos])) + ++t.pos, ++t.ipc; + else + goto backtrack; + break; + case word: + if (t.pos < text.length && is_word(text[t.pos])) + ++t.pos, ++t.ipc; + else + goto backtrack; + break; + case not_word: + if (t.pos < text.length && !is_word(text[t.pos])) + ++t.pos, ++t.ipc; + else + goto backtrack; + break; + case char_class: + if (t.pos < text.length && match_class(classes, ranges, inst.operand, text[t.pos])) + ++t.pos, ++t.ipc; + else + goto backtrack; + break; + case anchor_start: + if (t.pos == 0) + ++t.ipc; + else + goto backtrack; + break; + case anchor_end: + if (t.pos == text.length) + ++t.ipc; + else + goto backtrack; + break; + case group_open: + if (inst.operand < MaxGroups) + t.gs[inst.operand] = t.pos; + ++t.ipc; + break; + case group_close: + if (inst.operand < MaxGroups) + t.ge[inst.operand] = t.pos; + ++t.ipc; + break; + case split: + if (sp < stack.length) + { + stack[sp] = t; + if (inst.operand == 0) + { + stack[sp].ipc = inst.aux; + ++t.ipc; + } + else + { + stack[sp].ipc = cast(ushort)(t.ipc + 1); + t.ipc = inst.aux; + } + ++sp; + } + else + goto backtrack; + break; + case jump: + t.ipc = inst.aux; + break; + case Op.match: + matched = true; + break; + } + + if (matched) + break; + continue; + + backtrack: + if (sp == 0) + break; + t = stack[--sp]; + } + + if (matched) + { + result.full = text[start .. t.pos]; + result.num_captures = 0; + foreach (g; 0 .. hdr.num_groups) + { + if (g >= MaxGroups) + break; + if (t.gs[g] != ushort.max && t.ge[g] != ushort.max) + { + result.captures[g] = text[t.gs[g] .. t.ge[g]]; + result.num_captures = cast(ubyte)(g + 1); + } + else + result.captures[g] = null; + } + return true; + } + } + + return false; + } + +private: + const(ubyte)[] data; // Header ~ Inst[] ~ ClassRange[] ~ ClassDef[] + + struct Header + { + ushort num_insts; + ubyte num_classes; + ubyte num_ranges; + ubyte num_groups; + bool anchored; + } + + enum Op : ubyte + { + literal, any, digit, not_digit, space, not_space, word, not_word, + char_class, anchor_start, anchor_end, group_open, group_close, + split, jump, match, + } + + struct Inst + { + Op op; + ubyte operand; + ushort aux; + } + + struct ClassRange + { + char lo, hi; + } + + struct ClassDef + { + ubyte start, count; + bool negated; + } + + static bool is_digit(char ch) { return ch >= '0' && ch <= '9'; } + static bool is_space(char ch) { return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'; } + static bool is_word(char ch) { return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || is_digit(ch) || ch == '_'; } + + static bool match_class(const(ClassDef)[] classes, const(ClassRange)[] ranges, ubyte idx, char ch) + { + if (idx >= classes.length) + return false; + ref const ClassDef cd = classes[idx]; + bool found = false; + foreach (i; cd.start .. cd.start + cd.count) + { + if (ch >= ranges[i].lo && ch <= ranges[i].hi) + { + found = true; + break; + } + } + return cd.negated ? !found : found; + } +} + + +Regex regex_compile(const(char)[] pattern, NoGCAllocator allocator = defaultAllocator()) +{ + import urt.mem : memcpy; + + alias Op = Regex.Op; + alias Inst = Regex.Inst; + alias ClassRange = Regex.ClassRange; + alias ClassDef = Regex.ClassDef; + + // TODO: replace these stack buffers with Array!N when it works... + Inst[256] code = void; + ClassRange[128] class_ranges = void; + ClassDef[32] class_defs = void; + ubyte num_classes, total_ranges, num_groups; + ushort pc; + bool anchored; + + bool emit(Op op, ubyte operand = 0, ushort aux = 0) + { + if (pc >= code.length - 1) + return false; + code[pc++] = Inst(op, operand, aux); + return true; + } + + bool shift_code(ushort start, ushort end, ushort n) + { + if (end + n >= code.length) + return false; + for (ushort i = cast(ushort)(end + n - 1); i >= start + n; --i) + code[i] = code[cast(ushort)(i - n)]; + for (ushort i = 0; i < end + n; ++i) + { + if (code[i].op == Op.split || code[i].op == Op.jump) + { + if (code[i].aux >= start && code[i].aux < end) + code[i].aux += n; + } + } + pc += n; + return true; + } + + struct GroupFrame + { + ushort group_pc; + ubyte group_id; + ubyte num_jumps; + ushort[8] jump_pcs; + ushort last_split; + bool has_alt; + } + GroupFrame[16] gframes = void; + ubyte gdepth; + + Regex fail; + + size_t pi = 0; + while (pi < pattern.length) + { + ushort atom_start = pc; + char c = pattern[pi++]; + + switch (c) + { + case '^': + if (!emit(Op.anchor_start)) + return fail; + continue; + case '$': + if (!emit(Op.anchor_end)) + return fail; + continue; + + case '|': + { + // Alternation: a|b|c compiles as cascading splits: + // split(alt1, L1) → alt1 → jump(end) → L1: split(alt2, L2) → alt2 → jump(end) → L2: alt3 → end + // First | inserts a split before alt1. Subsequent | patch the previous split's aux. + if (gdepth == 0) + return fail; + ref GroupFrame gf = gframes[gdepth - 1]; + + // Emit jump to skip over remaining alternatives (patched at ')') + if (!emit(Op.jump)) + return fail; + if (gf.num_jumps < gf.jump_pcs.length) + gf.jump_pcs[gf.num_jumps++] = cast(ushort)(pc - 1); + + // Insert a split before the current alternative. + // For a|b: split(a, b). For a|b|c: split(a, split(b, c)). + // Each | inserts a split before its preceding alternative that + // points forward to the next one. + { + // Find where the current alternative started - it's right after + // the previous split (or after group_open for the first alt). + ushort split_pos; + if (!gf.has_alt) + split_pos = cast(ushort)(gf.group_pc + 1); // after group_open + else + split_pos = cast(ushort)(gf.last_split + 1); // after previous split + + if (!shift_code(split_pos, pc, 1)) + return fail; + code[split_pos] = Inst(Op.split, 0, pc); // aux = start of next alt + gf.last_split = split_pos; + + // Fix jump_pcs that shifted + foreach (ref jp; gf.jump_pcs[0 .. gf.num_jumps]) + { + if (jp >= split_pos) + ++jp; + } + } + gf.has_alt = true; + continue; + } + + case '.': + if (!emit(Op.any)) + return fail; + break; + + case '\\': + if (pi >= pattern.length) + return fail; + switch (pattern[pi++]) + { + case 'd': + if (!emit(Op.digit)) + return fail; + break; + case 'D': + if (!emit(Op.not_digit)) + return fail; + break; + case 's': + if (!emit(Op.space)) + return fail; + break; + case 'S': + if (!emit(Op.not_space)) + return fail; + break; + case 'w': + if (!emit(Op.word)) + return fail; + break; + case 'W': + if (!emit(Op.not_word)) + return fail; + break; + default: + if (!emit(Op.literal, cast(ubyte)pattern[pi-1])) + return fail; + break; + } + break; + + case '[': + { + if (num_classes >= class_defs.length) + return fail; + bool negated = pi < pattern.length && pattern[pi] == '^'; + if (negated) + ++pi; + ubyte rs = total_ranges; + while (pi < pattern.length && pattern[pi] != ']') + { + if (total_ranges >= class_ranges.length) + return fail; + char lo = pattern[pi++]; + if (lo == '\\' && pi < pattern.length) + lo = pattern[pi++]; + if (pi + 1 < pattern.length && pattern[pi] == '-' && pattern[pi+1] != ']') + { + ++pi; + char hi = pattern[pi++]; + if (hi == '\\' && pi < pattern.length) + hi = pattern[pi++]; + class_ranges[total_ranges++] = ClassRange(lo, hi); + } + else + class_ranges[total_ranges++] = ClassRange(lo, lo); + } + if (pi < pattern.length) + ++pi; + class_defs[num_classes] = ClassDef(rs, cast(ubyte)(total_ranges - rs), negated); + if (!emit(Op.char_class, num_classes++)) + return fail; + break; + } + + case '(': + { + if (gdepth >= gframes.length) + return fail; + ubyte gid = num_groups++; + gframes[gdepth] = GroupFrame.init; + gframes[gdepth].group_id = gid; + gframes[gdepth].group_pc = pc; + ++gdepth; + if (!emit(Op.group_open, gid)) + return fail; + continue; + } + + case ')': + { + if (gdepth == 0) + return fail; + --gdepth; + ref GroupFrame gf = gframes[gdepth]; + + // Patch all | jumps to land on the group_close (not past it) + foreach (ref jp; gf.jump_pcs[0 .. gf.num_jumps]) + code[jp].aux = pc; + + if (!emit(Op.group_close, gf.group_id)) + return fail; + + atom_start = gf.group_pc; + break; + } + + default: + if (!emit(Op.literal, cast(ubyte)c)) + return fail; + break; + } + + // Quantifier + if (pi < pattern.length && (pattern[pi] == '*' || pattern[pi] == '+' || pattern[pi] == '?')) + { + char q = pattern[pi++]; + bool is_lazy = pi < pattern.length && pattern[pi] == '?'; + if (is_lazy) + ++pi; + + ushort body_start = atom_start; + ushort body_end = pc; + ubyte lazy_flag = is_lazy ? 1 : 0; + + if (q == '*') + { + if (!shift_code(body_start, body_end, 1)) + return fail; + ushort after = cast(ushort)(pc + 1); + code[body_start] = Inst(Op.split, lazy_flag, after); + if (!emit(Op.jump, 0, body_start)) + return fail; + } + else if (q == '+') + { + if (!emit(Op.split, lazy_flag, cast(ushort)(pc + 1))) + return fail; + code[pc - 1] = Inst(Op.split, lazy_flag, cast(ushort)(pc + 1)); + if (!emit(Op.jump, 0, body_start)) + return fail; + } + else // '?' + { + if (!shift_code(body_start, body_end, 1)) + return fail; + code[body_start] = Inst(Op.split, lazy_flag, pc); + } + } + } + + if (gdepth != 0) + return fail; // unclosed group + + if (!emit(Op.match)) + return fail; + + anchored = pattern.length > 0 && pattern[0] == '^'; + + // Pack into single allocation: Header ~ Inst[pc] ~ ClassRange[total_ranges] ~ ClassDef[num_classes] + size_t size = Regex.Header.sizeof + pc * Inst.sizeof + total_ranges * ClassRange.sizeof + num_classes * ClassDef.sizeof; + ubyte[] buf = cast(ubyte[])allocator.alloc(size); + if (!buf) + return fail; + + Regex.Header* hdr = cast(Regex.Header*)buf.ptr; + hdr.num_insts = pc; + hdr.num_classes = num_classes; + hdr.num_ranges = total_ranges; + hdr.num_groups = num_groups; + hdr.anchored = anchored; + + size_t off = Regex.Header.sizeof; + memcpy(buf.ptr + off, code.ptr, pc * Inst.sizeof); + off += pc * Inst.sizeof; + memcpy(buf.ptr + off, class_ranges.ptr, total_ranges * ClassRange.sizeof); + off += total_ranges * ClassRange.sizeof; + memcpy(buf.ptr + off, class_defs.ptr, num_classes * ClassDef.sizeof); + + Regex result; + result.data = cast(const(ubyte)[])buf; + return result; +} + + +unittest +{ + RegexMatch m; + + // -- Literals -- + + assert(regex_match("hello world", "world", m)); + assert(m.full == "world"); + assert(m.num_captures == 0); + + assert(regex_match("abc", "abc", m)); + assert(m.full == "abc"); + + assert(!regex_match("hello world", "xyz", m)); + + // match at start, middle, end + assert(regex_match("abc", "a", m)); + assert(m.full == "a"); + assert(regex_match("abc", "b", m)); + assert(m.full == "b"); + assert(regex_match("abc", "c", m)); + assert(m.full == "c"); + + // -- Dot (any char) -- + + assert(regex_match("abc", "a.c", m)); + assert(m.full == "abc"); + + assert(!regex_match("ac", "a.c", m)); // dot requires exactly one char + + assert(regex_match("a\tc", "a.c", m)); // dot matches tab + assert(m.full == "a\tc"); + + // -- Character classes -- + + assert(regex_match("test123", "[0-9]+", m)); + assert(m.full == "123"); + + assert(regex_match("abc123", "[^a-z]+", m)); // negated + assert(m.full == "123"); + + assert(regex_match("x", "[xyz]", m)); + assert(m.full == "x"); + + assert(!regex_match("a", "[xyz]", m)); + + assert(regex_match("B", "[A-Za-z]", m)); // multiple ranges + assert(m.full == "B"); + + assert(regex_match("-", "[a\\-z]", m)); // escaped - in class + assert(m.full == "-"); + + // -- Escape sequences -- + + assert(regex_match("foo 42 bar", `\d+`, m)); + assert(m.full == "42"); + + assert(regex_match("hello world", `\w+`, m)); + assert(m.full == "hello"); + + assert(regex_match("key: value", `\s+`, m)); + assert(m.full == " "); + + // negated escapes + assert(regex_match("abc 123", `\D+`, m)); + assert(m.full == "abc "); + + assert(regex_match("abc 123", `\S+`, m)); + assert(m.full == "abc"); + + assert(regex_match(" abc", `\W+`, m)); + assert(m.full == " "); + + // escaped special characters + assert(regex_match("a.b", `a\.b`, m)); + assert(m.full == "a.b"); + + assert(!regex_match("axb", `a\.b`, m)); + + assert(regex_match("(hi)", `\(hi\)`, m)); + assert(m.full == "(hi)"); + + assert(regex_match("a*b", `a\*b`, m)); + assert(m.full == "a*b"); + + assert(regex_match("a|b", `a\|b`, m)); + assert(m.full == "a|b"); + + assert(regex_match("a\\b", `a\\b`, m)); + assert(m.full == "a\\b"); + + assert(regex_match("[x]", `\[x\]`, m)); + assert(m.full == "[x]"); + + // -- Anchors -- + + assert(regex_match("hello", "^hello$", m)); + assert(m.full == "hello"); + + assert(!regex_match("say hello", "^hello", m)); + assert(regex_match("say hello", "hello$", m)); + assert(m.full == "hello"); + + assert(!regex_match("hello!", "^hello$", m)); + + // ^ on empty string + assert(regex_match("", "^$", m)); + assert(m.full == ""); + + // -- Simple groups (no alternation) -- + + assert(regex_match("abc", "(abc)", m)); + assert(m.full == "abc"); + assert(m.num_captures == 1); + assert(m.captures[0] == "abc"); + + assert(regex_match("abc", "a(b)c", m)); + assert(m.full == "abc"); + assert(m.captures[0] == "b"); + + // -- Alternation -- + + // two branches + assert(regex_match("true", "(true|false)", m)); + assert(m.captures[0] == "true"); + + assert(regex_match("false", "(true|false)", m)); + assert(m.captures[0] == "false"); + + assert(!regex_match("maybe", "^(true|false)$", m)); + + // three branches + assert(regex_match("red", "(red|green|blue)", m)); + assert(m.captures[0] == "red"); + + assert(regex_match("green", "(red|green|blue)", m)); + assert(m.captures[0] == "green"); + + assert(regex_match("blue", "(red|green|blue)", m)); + assert(m.captures[0] == "blue"); + + assert(!regex_match("yellow", "^(red|green|blue)$", m)); + + // alternation with shared prefix/suffix + assert(regex_match("foobar", "(foo|foobar)", m)); + // greedy: tries foo first, succeeds - but we're not anchored, so full match is "foo" + assert(m.captures[0] == "foo"); + + // alternation with surrounding literal + assert(regex_match("catdog", "cat(and|or)?dog", m)); // no "and"/"or", ? makes it optional + assert(m.full == "catdog"); + + assert(regex_match("catanddog", "cat(and|or)dog", m)); + assert(m.captures[0] == "and"); + + assert(regex_match("catordog", "cat(and|or)dog", m)); + assert(m.captures[0] == "or"); + + // -- Greedy quantifiers: *, +, ? -- + + // * - zero or more + assert(regex_match("aaa", "a*", m)); + assert(m.full == "aaa"); + + assert(regex_match("bbb", "a*", m)); // zero-length match at start + assert(m.full == ""); + + assert(regex_match("", "a*", m)); // empty string, zero-length match + assert(m.full == ""); + + // + - one or more + assert(regex_match("aaa", "a+", m)); + assert(m.full == "aaa"); + + assert(!regex_match("bbb", "a+", m)); + + assert(regex_match("baaab", "a+", m)); + assert(m.full == "aaa"); + + // ? - zero or one + assert(regex_match("colour", "colou?r", m)); + assert(m.full == "colour"); + + assert(regex_match("color", "colou?r", m)); + assert(m.full == "color"); + + // greedy * consumes as much as possible + assert(regex_match("bold", "<.*>", m)); + assert(m.full == "bold"); + + // -- Lazy quantifiers: *?, +?, ?? -- + + // lazy * - shortest match + assert(regex_match("bold", "<.*?>", m)); + assert(m.full == ""); + + // lazy + - at least one, but shortest + assert(regex_match("aaa", "a+?", m)); + assert(m.full == "a"); + + // lazy ? - prefer zero + assert(regex_match("ab", "a??b", m)); + assert(m.full == "ab"); // a?? tries empty first but needs 'b', backtracks to 'a' + + // -- Quantifier on groups -- + + // group with + + assert(regex_match("ababab", "(ab)+", m)); + assert(m.full == "ababab"); + // last capture of the repeated group + assert(m.captures[0] == "ab"); + + // group with * + assert(regex_match("xyzxyz", "(xyz)*", m)); + assert(m.full == "xyzxyz"); + + // group with ? + assert(regex_match("foobar", "(foo)?bar", m)); + assert(m.full == "foobar"); + assert(m.captures[0] == "foo"); + + assert(regex_match("bar", "(foo)?bar", m)); + assert(m.full == "bar"); + + // alternation group with quantifier + assert(regex_match("abcabc", "(abc|def)+", m)); + assert(m.full == "abcabc"); + + assert(regex_match("abcdef", "(abc|def)+", m)); + assert(m.full == "abcdef"); + + // -- Nested groups -- + + assert(regex_match("abc", "((a)(b)(c))", m)); + assert(m.num_captures == 4); + assert(m.captures[0] == "abc"); // outer group + assert(m.captures[1] == "a"); + assert(m.captures[2] == "b"); + assert(m.captures[3] == "c"); + + // nested with alternation + assert(regex_match("ab", "((a|x)(b|y))", m)); + assert(m.captures[0] == "ab"); + assert(m.captures[1] == "a"); + assert(m.captures[2] == "b"); + + // -- Quantifier + class interactions -- + + assert(regex_match("abc123def", "[a-z]+", m)); + assert(m.full == "abc"); + + assert(regex_match("abc123def", "[a-z]+?", m)); // lazy + assert(m.full == "a"); + + assert(regex_match("123", "[0-9]?", m)); + assert(m.full == "1"); + + assert(regex_match("abc", "[0-9]?", m)); // zero-length match + assert(m.full == ""); + + // -- Quantifier + escape interactions -- + + assert(regex_match(" \t ", `\s+`, m)); + assert(m.full == " \t "); + + assert(regex_match("hello123world", `\w+\d+\w+`, m)); + assert(m.full == "hello123world"); + + // -- Complex scraping patterns -- + + assert(regex_match("voltage: 52.3V", `voltage:\s*(\d+\.\d+)`, m)); + assert(m.captures[0] == "52.3"); + + assert(regex_match("active", `(\w+)`, m)); + assert(m.captures[0] == "active"); + + assert(regex_match("power: 1500W", `power:\s*(\d+)`, m)); + assert(m.captures[0] == "1500"); + + assert(regex_match("temp=25.6C", `temp=(\d+\.?\d*)`, m)); + assert(m.captures[0] == "25.6"); + + // multiple captures in a real pattern + assert(regex_match("error 404: not found", `(\w+)\s+(\d+):\s+(.+)`, m)); + assert(m.num_captures == 3); + assert(m.captures[0] == "error"); + assert(m.captures[1] == "404"); + assert(m.captures[2] == "not found"); + + // key=value extraction + assert(regex_match("host=192.168.1.1 port=502", `(\w+)=(\S+)`, m)); + assert(m.captures[0] == "host"); + assert(m.captures[1] == "192.168.1.1"); + + // CSV-like: extract fields + assert(regex_match("42,hello,true", `^(\d+),(\w+),(true|false)`, m)); + assert(m.captures[0] == "42"); + assert(m.captures[1] == "hello"); + assert(m.captures[2] == "true"); + + // -- Compile once, match many -- + + Regex re = regex_compile(`(\d+)\s*([A-Z]+)`); + assert(re.valid); + + assert(re.exec("reading: 42 V", m)); + assert(m.num_captures == 2); + assert(m.captures[0] == "42"); + assert(m.captures[1] == "V"); + + assert(re.exec("other: 100 MW", m)); + assert(m.captures[0] == "100"); + assert(m.captures[1] == "MW"); + + assert(!re.exec("no numbers here", m)); + + // -- Edge cases -- + + // empty text, empty pattern + assert(regex_match("", "", m)); + assert(m.full == ""); + + // empty pattern matches empty at start of any text + assert(regex_match("abc", "", m)); + assert(m.full == ""); + + // no captures + assert(regex_match("abc", `\w+`, m)); + assert(m.num_captures == 0); + + // unmatched parens should fail to compile + assert(!regex_compile("abc)").valid); + assert(!regex_compile("(abc").valid); + + // pattern with only anchors + assert(regex_match("", "^$", m)); + assert(!regex_match("x", "^$", m)); + + // .* at start - heavy backtracking but should work + assert(regex_match("the end", ".*end", m)); + assert(m.full == "the end"); + + // .* with capture + assert(regex_match("key: value here", `(\w+):\s*(.*)$`, m)); + assert(m.captures[0] == "key"); + assert(m.captures[1] == "value here"); + + // single char edge + assert(regex_match("x", "x", m)); + assert(m.full == "x"); + + assert(!regex_match("", "x", m)); + + // quantifier on dot + assert(regex_match("abc", ".+", m)); + assert(m.full == "abc"); + + assert(regex_match("a", ".+", m)); + assert(m.full == "a"); + + assert(!regex_match("", ".+", m)); + + assert(regex_match("", ".*", m)); + assert(m.full == ""); +} diff --git a/src/urt/string/string.d b/src/urt/string/string.d index b1281cd..1c39296 100644 --- a/src/urt/string/string.d +++ b/src/urt/string/string.d @@ -3,7 +3,7 @@ module urt.string.string; import urt.lifetime : forward, move; import urt.mem; import urt.mem.string : CacheString; -import urt.hash : fnv1aHash, fnv1aHash64; +import urt.hash : fnv1a, fnv1a64; import urt.string.tailstring : TailString; public import urt.array : Alloc_T, Alloc, Reserve_T, Reserve, Concat_T, Concat; @@ -23,16 +23,70 @@ enum StringAlloc : ubyte TempString, // allocates in the temp ring buffer; could be overwritten at any time! // these must be last... (because comparison logic) - StringCache, // writes to the immutable string cache - StringCacheDedup, // writes to the immutable string cache with de-duplication + StringCache, // writes to the immutable string cache with de-duplication } struct StringAllocator { - char* delegate(ushort bytes, void* userData) nothrow @nogc alloc; - void delegate(char* s) nothrow @nogc free; + char* delegate(ushort bytes, void* userData) pure nothrow @nogc alloc; + void delegate(char* s) pure nothrow @nogc free; } +struct StringCacheBuilder +{ +nothrow @nogc: + this(char[] buffer) pure + { + assert(buffer.length >= 2 && buffer.length <= ushort.max, "Invalid buffer length"); + buffer[0..2] = 0; + this._buffer = buffer; + this._offset = 2; + } + + ushort add_string(const(char)[] s) pure + { + if (s.length == 0) + return 0; + + assert(s.length <= MaxStringLen, "String too long"); + assert(_offset + s.length + 2 + (s.length & 1) <= _buffer.length, "Not enough space in buffer"); + if (__ctfe) + { + version (LittleEndian) + { + _buffer[_offset + 0] = cast(char)(s.length & 0xFF); + _buffer[_offset + 1] = cast(char)(s.length >> 8); + } + else + { + _buffer[_offset + 0] = cast(char)(s.length >> 8); + _buffer[_offset + 1] = cast(char)(s.length & 0xFF); + } + } + else + *cast(ushort*)(_buffer.ptr + _offset) = cast(ushort)s.length; + + ushort result = cast(ushort)(_offset + 2); + _buffer[result .. result + s.length] = s[]; + _offset = cast(ushort)(result + s.length); + if (_offset & 1) + _buffer[_offset++] = '\0'; + return result; + } + + size_t used() const pure + => _offset; + + size_t remaining() const pure + => _buffer.length - _offset; + + bool full() const pure + => _offset == _buffer.length; + +private: + char[] _buffer; + ushort _offset; +} //enum String StringLit(string s) = s.makeString; template StringLit(const(char)[] lit, bool zeroTerminate = true) @@ -58,16 +112,16 @@ template StringLit(const(char)[] lit, bool zeroTerminate = true) return buffer; }(); pragma(aligned, 2) - private __gshared literal = LiteralData; + private __gshared immutable literal = LiteralData; - enum String StringLit = String(literal.ptr + 2, false); + enum StringLit = immutable(String)(literal.ptr + 2, false); } - String makeString(const(char)[] s) nothrow { if (s.length == 0) return String(null); + assert(__ctfe, "only for compile-time use"); return makeString(s, new char[2 + s.length]); } @@ -87,11 +141,11 @@ String makeString(const(char)[] s, StringAlloc allocator, void* userData = null) { return String(writeString(cast(char*)tempAllocator().alloc(2 + s.length, 2).ptr + 2, s), false); } - else if (allocator >= StringAlloc.StringCache) + else if (allocator == StringAlloc.StringCache) { import urt.mem.string : CacheString, addString; - CacheString cs = s.addString(allocator == StringAlloc.StringCacheDedup); + CacheString cs = s.addString(); return String(cs.ptr, false); } assert(false, "Invalid string allocator"); @@ -118,12 +172,51 @@ String makeString(const(char)[] s, char[] buffer) nothrow @nogc return String(writeString(buffer.ptr + 2, s), false); } +char* writeString(char* buffer, const(char)[] str) pure nothrow @nogc +{ + // TODO: assume the calling code has confirmed the length is within spec + if (__ctfe) + { + version (LittleEndian) + { + buffer[-2] = cast(char)(str.length & 0xFF); + buffer[-1] = cast(char)(str.length >> 8); + } + else + { + buffer[-2] = cast(char)(str.length >> 8); + buffer[-1] = cast(char)(str.length & 0xFF); + } + } + else + (cast(ushort*)buffer)[-1] = cast(ushort)str.length; + buffer[0 .. str.length] = str[]; + return buffer; +} + +String as_string(const(char)* s) pure nothrow @nogc + => String(s, false); + +inout(char)[] as_dstring(inout(char)* s) pure nothrow @nogc +{ + debug assert(s !is null); + + if (__ctfe) + { + version (LittleEndian) + ushort len = cast(ushort)(s[-2] | (s[-1] << 8)); + else + ushort len = cast(ushort)(s[-1] | (s[-2] << 8)); + return s[0 .. len]; + } + else + return s[0 .. (cast(ushort*)s)[-1]]; +} struct String { nothrow @nogc: - - alias toString this; + alias This = typeof(this); const(char)* ptr; @@ -132,21 +225,19 @@ nothrow @nogc: this.ptr = null; } - this(ref inout typeof(this) rhs) inout pure + this(ref inout This rhs) inout pure { ptr = rhs.ptr; - if (ptr) + if (!ptr) + return; + if (ushort* rc = ((cast(ushort*)ptr)[-1] >> 15) ? cast(ushort*)ptr - 2 : null) { - ushort* rc = ((cast(ushort*)ptr)[-1] >> 15) ? cast(ushort*)ptr - 2 : null; - if (rc) - { - assert((*rc & 0x3FFF) < 0x3FFF, "Reference count overflow"); - ++*rc; - } + assert((*rc & 0x3FFF) < 0x3FFF, "Reference count overflow"); + ++*rc; } } - this(size_t Embed)(MutableString!Embed str) inout //pure TODO: PUT THIS BACK!! + this(size_t Embed)(MutableString!Embed str) inout pure { if (!str.ptr) return; @@ -156,7 +247,7 @@ nothrow @nogc: if (Embed > 0 && str.ptr == str.embed.ptr + 2) { // clone the string - this(writeString(stringAllocators[0].alloc(cast(ushort)str.length, null), str[]), true); + this(writeString(get_string_allocator(0).alloc(cast(ushort)str.length, null), str[]), true); return; } } @@ -177,7 +268,7 @@ nothrow @nogc: ptr = cs.ptr; } - ~this() + ~this() pure { if (ptr) decRef(); @@ -188,7 +279,20 @@ nothrow @nogc: // TODO: I made this return ushort, but normally length() returns size_t ushort length() const pure - => ptr ? ((cast(ushort*)ptr)[-1] & 0x7FFF) : 0; + { + if (__ctfe) + { + version (LittleEndian) + return ptr ? cast(ushort)(ptr[-2] | (ptr[-1] << 8)) & 0x7FFF : 0; + else + return ptr ? cast(ushort)((ptr[-1] | (ptr[-2] << 8)) & 0x7FFF) : 0; + } + else + return ptr ? ((cast(ushort*)ptr)[-1] & 0x7FFF) : 0; + } + + bool empty() const pure + => length() == 0; bool opCast(T : bool)() const pure => ptr != null && ((cast(ushort*)ptr)[-1] & 0x7FFF) != 0; @@ -218,7 +322,6 @@ nothrow @nogc: ptr = cs.ptr; } - bool opEquals(const(char)[] rhs) const pure { if (!ptr) @@ -227,6 +330,15 @@ nothrow @nogc: return len == rhs.length && (ptr == rhs.ptr || ptr[0 .. len] == rhs[]); } + int opEquals(ref const String rhs) const pure + => opEquals(rhs[]); + + int opEquals(size_t N)(ref const MutableString!N rhs) const pure + => opEquals(rhs[]); + + int opEquals(size_t N)(ref const Array!N rhs) const pure + => opEquals(rhs[]); + int opCmp(const(char)[] rhs) const pure { import urt.algorithm : compare; @@ -235,14 +347,24 @@ nothrow @nogc: return compare(ptr[0 .. length()], rhs); } + int opCmp(ref const String rhs) const pure + => opCmp(rhs[]); + + int opCmp(size_t N)(ref const MutableString!N rhs) const pure + => opCmp(rhs[]); + + int opCmp(size_t N)(ref const Array!N rhs) const pure + => opCmp(rhs[]); + size_t toHash() const pure { if (!ptr) return 0; + ushort len = (cast(ushort*)ptr)[-1] & 0x7FFF; static if (size_t.sizeof == 4) - return fnv1aHash(cast(ubyte[])ptr[0 .. length]); + return fnv1a(cast(ubyte[])ptr[0 .. len]); else - return fnv1aHash64(cast(ubyte[])ptr[0 .. length]); + return fnv1a64(cast(ubyte[])ptr[0 .. len]); } const(char)[] opIndex() const pure @@ -263,11 +385,10 @@ nothrow @nogc: size_t opDollar() const pure => length(); -private: - auto __debugOverview() const pure { debug return ptr[0 .. length].debugExcapeString(); else return ptr[0 .. length]; } - auto __debugExpanded() const pure => ptr[0 .. length]; - auto __debugStringView() const pure => ptr[0 .. length]; + bool has_rc() const pure + => ptr && ((cast(ushort*)ptr)[-1] >> 15) != 0; +private: ushort* refCounter() const pure => ((cast(ushort*)ptr)[-1] >> 15) ? cast(ushort*)ptr - 2 : null; @@ -280,12 +401,12 @@ private: } } - void decRef() + void decRef() pure { if (ushort* rc = refCounter()) { if ((*rc & 0x3FFF) == 0) - stringAllocators[*rc >> 14].free(cast(char*)ptr); + get_string_allocator(*rc >> 14).free(cast(char*)ptr); else --*rc; } @@ -297,6 +418,13 @@ private: if (refCounted) *cast(ushort*)(ptr - 2) |= 0x8000; } + + version (Windows) + { + auto __debugOverview() const pure => ptr ? ptr[0 .. length].debugExcapeString() : null; + auto __debugExpanded() const pure => ptr ? ptr[0 .. length] : null; + auto __debugStringView() const pure => ptr ? ptr[0 .. length] : null; + } } unittest @@ -315,7 +443,9 @@ unittest assert(!emptyLit); // opCast!bool // Test makeString (default allocator) - String s1 = makeString("World"); + // TODO: reinstate the GC for debug allocations... +// String s1 = makeString("World"); + String s1 = StringLit!"World"; assert(s1.length == 5); assert(s1 == "World"); @@ -338,6 +468,7 @@ unittest assert(nullStr == ""); assert(!nullStr); + // TODO: reinstate once GC makeString is available // Test assignment and reference counting (basic check) String s3 = s1; // s3 references the same data as s1 assert(s3.ptr == s1.ptr); @@ -347,7 +478,7 @@ unittest assert(s3.length == 5); // Test equality - String s4 = makeString("World"); + String s4 = StringLit!"World"; assert(s3 == s4); // Different allocations, same content assert(s3 != "world"); // Case sensitive assert(s3 != "Worl"); @@ -414,8 +545,6 @@ nothrow @nogc: static assert(Embed == 0, "Not without move semantics!"); - alias toString this; - char* ptr; // TODO: DELETE POSTBLIT! @@ -470,12 +599,12 @@ nothrow @nogc: append(forward!things); } - this(Args...)(Format_T, auto ref Args args) + this(Args...)(Format_T, const(char)[] format, auto ref Args args) { - format(forward!args); + this.format(format, forward!args); } - ~this() + ~this() pure { freeStringBuffer(ptr); } @@ -487,9 +616,57 @@ nothrow @nogc: ushort length() const pure => ptr ? ((cast(ushort*)ptr)[-1] & 0x7FFF) : 0; + bool empty() const pure + => length() == 0; + bool opCast(T : bool)() const pure => ptr != null && ((cast(ushort*)ptr)[-1] & 0x7FFF) != 0; + bool opEquals(const(char)[] rhs) const pure + { + if (!ptr) + return rhs.length == 0; + ushort len = (cast(ushort*)ptr)[-1] & 0x7FFF; + return len == rhs.length && (ptr == rhs.ptr || ptr[0 .. len] == rhs[]); + } + + int opEquals(ref const String rhs) const pure + => opEquals(rhs[]); + + int opEquals(size_t N)(ref const MutableString!N rhs) const pure + => opEquals(rhs[]); + + int opEquals(size_t N)(ref const Array!N rhs) const pure + => opEquals(rhs[]); + + int opCmp(const(char)[] rhs) const pure + { + import urt.algorithm : compare; + if (!ptr) + return rhs.length == 0 ? 0 : -1; + return compare(ptr[0 .. length], rhs); + } + + int opCmp(ref const String rhs) const pure + => opCmp(rhs[]); + + int opCmp(size_t N)(ref const MutableString!N rhs) const pure + => opCmp(rhs[]); + + int opCmp(size_t N)(ref const Array!N rhs) const pure + => opCmp(rhs[]); + + size_t toHash() const pure + { + if (!ptr) + return 0; + ushort len = (cast(ushort*)ptr)[-1] & 0x7FFF; + static if (size_t.sizeof == 4) + return fnv1a(cast(ubyte[])ptr[0 .. len]); + else + return fnv1a64(cast(ubyte[])ptr[0 .. len]); + } + void opAssign(ref const typeof(this) rh) { opAssign(rh[]); @@ -499,11 +676,6 @@ nothrow @nogc: opAssign(rh[]); } - void opAssign(typeof(null)) - { - clear(); - } - void opAssign(char c) { reserve(1); @@ -597,78 +769,54 @@ nothrow @nogc: ref MutableString!Embed append(Things...)(auto ref Things things) { - insert(length(), forward!things); - return this; + import urt.string.format : normalise_args; + return insert_impl(length(), normalise_args(things)); } - ref MutableString!Embed appendFormat(Things...)(auto ref Things things) + ref MutableString!Embed append_format(Things...)(const(char)[] format, auto ref Things args) { - insertFormat(length(), forward!things); - return this; + return insert_format(length(), format, forward!args); } ref MutableString!Embed concat(Things...)(auto ref Things things) { + import urt.string.format : normalise_args; if (ptr) writeLength(0); - insert(0, forward!things); - return this; + return insert_impl(0, normalise_args(things)); } - ref MutableString!Embed format(Args...)(auto ref Args args) + ref MutableString!Embed format(Args...)(const(char)[] format, auto ref Args args) { if (ptr) writeLength(0); - insertFormat(0, forward!args); - return this; + return insert_format(0, format, forward!args); } ref MutableString!Embed insert(Things...)(size_t offset, auto ref Things things) { - import urt.string.format : _concat = concat; - import urt.util : max, nextPowerOf2; - - char* oldPtr = ptr; - size_t oldLen = length(); - - size_t insertLen = _concat(null, things).length; - size_t newLen = oldLen + insertLen; - if (newLen == oldLen) - return this; - debug assert(newLen <= MaxStringLen, "String too long"); - - size_t oldAlloc = allocated(); - ptr = newLen <= oldAlloc ? oldPtr : allocStringBuffer(max(16, cast(ushort)newLen + 4).nextPowerOf2 - 4); - memmove(ptr + offset + insertLen, oldPtr + offset, oldLen - offset); - _concat(ptr[offset .. offset + insertLen], forward!things); - writeLength(newLen); - - if (oldPtr && ptr != oldPtr) - { - ptr[0 .. offset] = oldPtr[0 .. offset]; - freeStringBuffer(oldPtr); - } - return this; + import urt.string.format : normalise_args; + auto args = normalise_args(things); + return insert_impl(offset, args); } - ref MutableString!Embed insertFormat(Things...)(size_t offset, auto ref Things things) + ref MutableString!Embed insert_format(Things...)(size_t offset, const(char)[] format, auto ref Things args) { import urt.string.format : _format = format; - import urt.util : max, nextPowerOf2; char* oldPtr = ptr; size_t oldLen = length(); - size_t insertLen = _format(null, things).length; + size_t insertLen = _format(null, format, args).length; size_t newLen = oldLen + insertLen; if (newLen == oldLen) return this; debug assert(newLen <= MaxStringLen, "String too long"); size_t oldAlloc = allocated(); - ptr = newLen <= oldAlloc ? oldPtr : allocStringBuffer(max(16, cast(ushort)newLen + 4).nextPowerOf2 - 4); + ptr = newLen <= oldAlloc ? oldPtr : allocStringBuffer(grow_capacity(newLen, oldAlloc)); memmove(ptr + offset + insertLen, oldPtr + offset, oldLen - offset); - _format(ptr[offset .. offset + insertLen], forward!things); + _format(ptr[offset .. offset + insertLen], format, forward!args); writeLength(newLen); if (oldPtr && ptr != oldPtr) @@ -747,6 +895,20 @@ private: return (cast(ushort*)ptr)[-2]; } + static ushort grow_capacity(size_t target, size_t current) pure + { + import urt.util : next_power_of_2; + size_t doubled = (current + 4) * 2; + size_t total = target + 4; + if (total <= doubled) + total = next_power_of_2(total); + if (total < 16) + total = 16; + if (total > MaxStringLen + 4) + total = MaxStringLen + 4; + return cast(ushort)(total - 4); + } + void writeLength(size_t len) { (cast(ushort*)ptr)[-1] = cast(ushort)len; @@ -762,7 +924,7 @@ private: return buffer + 4; } - void freeStringBuffer(char* buffer) + void freeStringBuffer(char* buffer) pure { if (!buffer) return; @@ -773,9 +935,40 @@ private: defaultAllocator().free(buffer[0 .. 4 + *cast(ushort*)buffer]); } - auto __debugOverview() const pure { debug return ptr[0 .. length].debugExcapeString(); else return ptr[0 .. length]; } - auto __debugExpanded() const pure => ptr[0 .. length]; - auto __debugStringView() const pure => ptr[0 .. length]; + import urt.meta.tuple : Tuple; + ref MutableString!Embed insert_impl(Things...)(size_t offset, Tuple!Things args) + { + import urt.string.format : concat_impl; + + char* oldPtr = ptr; + size_t oldLen = length(); + + size_t insertLen = concat_impl(null, args).length; + size_t newLen = oldLen + insertLen; + if (newLen == oldLen) + return this; + debug assert(newLen <= MaxStringLen, "String too long"); + + size_t oldAlloc = allocated(); + ptr = newLen <= oldAlloc ? oldPtr : allocStringBuffer(grow_capacity(newLen, oldAlloc)); + memmove(ptr + offset + insertLen, oldPtr + offset, oldLen - offset); + concat_impl(ptr[offset .. offset + insertLen], args); + writeLength(newLen); + + if (oldPtr && ptr != oldPtr) + { + ptr[0 .. offset] = oldPtr[0 .. offset]; + freeStringBuffer(oldPtr); + } + return this; + } + + version (Windows) + { + auto __debugOverview() const pure => ptr ? ptr[0 .. length].debugExcapeString() : null; + auto __debugExpanded() const pure => ptr ? ptr[0 .. length] : null; + auto __debugStringView() const pure => ptr ? ptr[0 .. length] : null; + } } unittest @@ -792,6 +985,9 @@ unittest assert(s == "Hello, world!\n"); assert(s.length == 14); + s = null; + assert(s.length == 0); + MutableString!0 s_long; s_long.reserve(4567); s_long = "Start"; @@ -824,11 +1020,11 @@ unittest m.append(" Text"); assert(m == "X! More Text"); - // appendFormat + // append_format m.clear(); - m.appendFormat("Value: {0}", 123); + m.append_format("Value: {0}", 123); assert(m == "Value: 123"); - m.appendFormat(", String: {0}", "abc"); + m.append_format(", String: {0}", "abc"); assert(m == "Value: 123, String: abc"); // concat @@ -849,13 +1045,13 @@ unittest m.insert(m.length, "!"); // End (same as append) assert(m == "My Super String!"); - // insertFormat + // insert_format m = "Data"; - m.insertFormat(0, "[{0}] ", 1); + m.insert_format(0, "[{0}] ", 1); assert(m == "[1] Data"); - m.insertFormat(4, "\\{{0}\\}", "fmt"); + m.insert_format(4, "\\{{0}\\}", "fmt"); assert(m == "[1] {fmt}Data"); - m.insertFormat(m.length, " End"); + m.insert_format(m.length, " End"); assert(m == "[1] {fmt}Data End"); // erase @@ -933,48 +1129,50 @@ private: __gshared StringAllocator[4] stringAllocators; static assert(stringAllocators.length <= 4, "Only 2 bits reserved to store allocator index"); -char* writeString(char* buffer, const(char)[] str) pure nothrow @nogc +ref StringAllocator get_string_allocator(uint i) pure nothrow @nogc { - // TODO: assume the calling code has confirmed the length is within spec - (cast(ushort*)buffer)[-1] = cast(ushort)str.length; - buffer[0 .. str.length] = str[]; - return buffer; + alias PureHack = ref StringAllocator function(uint i) pure nothrow @nogc; + static ref StringAllocator get_allocator(uint i) nothrow @nogc { return stringAllocators[i]; }; + return (cast(PureHack)&get_allocator)(i); } -package(urt) void initStringAllocators() +package(urt) void initStringAllocators() nothrow @nogc { - stringAllocators[StringAlloc.Default].alloc = (ushort bytes, void* userData) { - char* buffer = cast(char*)defaultAllocator().alloc(bytes + 4, ushort.alignof).ptr; + alias PureAlloc = void[] delegate(size_t, size_t) pure nothrow @nogc; + alias PureFree = void delegate(void[]) pure nothrow @nogc; + + stringAllocators[StringAlloc.Default].alloc = (ushort bytes, void* userData) pure { + char* buffer = cast(char*)(cast(PureAlloc)&defaultAllocator().alloc)(bytes + 4, ushort.alignof).ptr; *cast(ushort*)buffer = StringAlloc.Default << 14; // allocator = default, rc = 0 return buffer + 4; }; - stringAllocators[StringAlloc.Default].free = (char* str) { + stringAllocators[StringAlloc.Default].free = (char* str) pure { ushort len = (cast(ushort*)str)[-1] & 0x7FFF; str -= 4; - defaultAllocator().free(str[0 .. 4 + len]); + (cast(PureFree)&defaultAllocator().free)(str[0 .. 4 + len]); }; - stringAllocators[StringAlloc.Explicit].alloc = (ushort bytes, void* userData) { + stringAllocators[StringAlloc.Explicit].alloc = (ushort bytes, void* userData) pure { NoGCAllocator a = cast(NoGCAllocator)userData; - char* buffer = cast(char*)a.alloc(size_t.sizeof*2 + bytes, size_t.alignof).ptr; + char* buffer = cast(char*)(cast(PureAlloc)&a.alloc)(size_t.sizeof*2 + bytes, size_t.alignof).ptr; *cast(NoGCAllocator*)buffer = a; buffer += size_t.sizeof*2; (cast(ushort*)buffer)[-2] = StringAlloc.Explicit << 14; // allocator = explicit, rc = 0 return buffer; }; - stringAllocators[StringAlloc.Explicit].free = (char* str) { + stringAllocators[StringAlloc.Explicit].free = (char* str) pure { NoGCAllocator a = *cast(NoGCAllocator*)(str - size_t.sizeof*2); ushort len = (cast(ushort*)str)[-1] & 0x7FFF; str -= size_t.sizeof*2; - a.free(str[0 .. size_t.sizeof*2 + len]); + (cast(PureFree)&a.free)(str[0 .. size_t.sizeof*2 + len]); }; } -debug +version (Windows) { - char[] debugExcapeString(const char[] s) pure nothrow + char[] debugExcapeString(const char[] s) pure nothrow @nogc { - char[] t = new char[s.length*2]; + char[] t = debug_alloc!char(s.length*2); int d; foreach (i; 0 .. s.length) { diff --git a/src/urt/string/tailstring.d b/src/urt/string/tailstring.d index 3664342..383ac30 100644 --- a/src/urt/string/tailstring.d +++ b/src/urt/string/tailstring.d @@ -23,7 +23,7 @@ struct TailString(T) else { const(char)* thisptr = cast(const(char)*)&this; - const(char)* sptr = s.ptr - (s.ptr[-1] < 128 ? 1 : 2); + const(char)* sptr = s.ptr - 2; assert(sptr > thisptr && sptr - thisptr <= offset.max, "!!"); offset = cast(ubyte)(sptr - thisptr); } @@ -39,7 +39,7 @@ struct TailString(T) if (offset == 0) return null; const(char)* ptr = (cast(const(char)*)&this) + offset; - return ptr[0] < 128 ? ptr + 1 : ptr + 2; + return ptr + 2; } size_t length() const nothrow @nogc @@ -64,7 +64,7 @@ struct TailString(T) else { const(char)* thisptr = cast(const(char)*)&this; - const(char)* sptr = s.ptr - (s.ptr[-1] < 128 ? 1 : 2); + const(char)* sptr = s.ptr - 2; assert(sptr > thisptr && sptr - thisptr <= offset.max, "!!"); offset = cast(ubyte)(sptr - thisptr); } @@ -81,9 +81,9 @@ struct TailString(T) import urt.hash; static if (size_t.sizeof == 4) - return fnv1aHash(cast(ubyte[])toString()); + return fnv1a(cast(ubyte[])toString()); else - return fnv1aHash64(cast(ubyte[])toString()); + return fnv1a64(cast(ubyte[])toString()); } private: @@ -94,9 +94,12 @@ private: this.offset = offset; } - auto __debugOverview() => toString; - auto __debugExpanded() => toString; - auto __debugStringView() => toString; + version (Windows) + { + auto __debugOverview() => toString; + auto __debugExpanded() => toString; + auto __debugStringView() => toString; + } } diff --git a/src/urt/string/uni.d b/src/urt/string/uni.d index ee9b551..03d38c6 100644 --- a/src/urt/string/uni.d +++ b/src/urt/string/uni.d @@ -1,18 +1,155 @@ module urt.string.uni; -nothrow @nogc: +import urt.string.ascii : to_lower, to_upper; +import urt.traits : is_some_char; +pure nothrow @nogc: -size_t uniConvert(const(char)[] s, wchar[] buffer) + +size_t uni_seq_len(const(char)[] str) +{ + debug assert(str.length > 0); + + const(char)* s = str.ptr; + if (s[0] < 0x80) // 1-byte sequence: 0xxxxxxx + return 1; + else if ((s[0] & 0xE0) == 0xC0) // 2-byte sequence: 110xxxxx 10xxxxxx + return (str.length >= 2 && (s[1] & 0xC0) == 0x80) ? 2 : 1; + else if ((s[0] & 0xF0) == 0xE0) // 3-byte sequence: 1110xxxx 10xxxxxx 10xxxxxx + return (str.length >= 3 && (s[1] & 0xC0) == 0x80 && (s[2] & 0xC0) == 0x80) ? 3 : + (str.length >= 2 && (s[1] & 0xC0) == 0x80) ? 2 : 1; + else if ((s[0] & 0xF8) == 0xF0) // 4-byte sequence: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + return (str.length >= 4 && (s[1] & 0xC0) == 0x80 && (s[2] & 0xC0) == 0x80 && (s[3] & 0xC0) == 0x80) ? 4 : + (str.length >= 3 && (s[1] & 0xC0) == 0x80 && (s[2] & 0xC0) == 0x80) ? 3 : + (str.length >= 2 && (s[1] & 0xC0) == 0x80) ? 2 : 1; + return 1; // Invalid UTF-8 sequence +} + +size_t uni_seq_len(const(wchar)[] str) +{ + debug assert(str.length > 0); + + const(wchar)* s = str.ptr; + if (s[0] >= 0xD800 && s[0] < 0xDC00 && str.length >= 2 && s[1] >= 0xDC00 && s[1] < 0xE000) + return 2; // Surrogate pair: 110110xxxxxxxxxx 110111xxxxxxxxxx + return 1; +} + +pragma(inline, true) +size_t uni_seq_len(const(dchar)[] s) + => 1; + +size_t uni_strlen(C)(const(C)[] s) + if (is_some_char!C) +{ + static if (is(C == dchar)) + { + pragma(inline, true); + return s.length; + } + else + { + size_t count = 0; + while (s.length) + { + size_t l = s.uni_seq_len; + s = s[l .. $]; + ++count; + } + return count; + } +} + +dchar next_dchar(const(char)[] s, out size_t seq_len) +{ + assert(s.length > 0); + + const(char)* p = s.ptr; + if ((*p & 0x80) == 0) // 1-byte sequence: 0xxxxxxx + { + seq_len = 1; + return *p; + } + else if ((*p & 0xE0) == 0xC0) // 2-byte sequence: 110xxxxx 10xxxxxx + { + if (s.length >= 2 && (p[1] & 0xC0) == 0x80) + { + seq_len = 2; + return ((p[0] & 0x1F) << 6) | (p[1] & 0x3F); + } + } + else if ((*p & 0xF0) == 0xE0) // 3-byte sequence: 1110xxxx 10xxxxxx 10xxxxxx + { + if (s.length >= 3 && (p[1] & 0xC0) == 0x80 && (p[2] & 0xC0) == 0x80) + { + seq_len = 3; + return ((p[0] & 0x0F) << 12) | ((p[1] & 0x3F) << 6) | (p[2] & 0x3F); + } + // check for seq_len == 2 error cases + if (s.length >= 2 && (p[1] & 0xC0) == 0x80) + { + seq_len = 2; + return 0xFFFD; + } + } + else if ((*p & 0xF8) == 0xF0) // 4-byte sequence: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + { + if (s.length >= 4 && (p[1] & 0xC0) == 0x80 && (p[2] & 0xC0) == 0x80 && (p[3] & 0xC0) == 0x80) + { + seq_len = 4; + return ((p[0] & 0x07) << 18) | ((p[1] & 0x3F) << 12) | ((p[2] & 0x3F) << 6) | (p[3] & 0x3F); + } + // check for seq_len == 2..3 error cases + if (s.length >= 2 && (p[1] & 0xC0) == 0x80) + { + if (s.length == 2 || (p[2] & 0xC0) != 0x80) + seq_len = 2; + else + seq_len = 3; + return 0xFFFD; + } + } + seq_len = 1; + return 0xFFFD; // Invalid UTF-8 sequence +} + +dchar next_dchar(const(wchar)[] s, out size_t seq_len) +{ + assert(s.length > 0); + + const(wchar)* p = s.ptr; + if (p[0] < 0xD800 || p[0] >= 0xE000) + { + seq_len = 1; + return p[0]; + } + if (p[0] < 0xDC00 && s.length >= 2 && p[1] >= 0xDC00 && p[1] < 0xE000) // Surrogate pair: 110110xxxxxxxxxx 110111xxxxxxxxxx + { + seq_len = 2; + return 0x10000 + ((p[0] - 0xD800) << 10) + (p[1] - 0xDC00); + } + seq_len = 1; + return 0xFFFD; // Invalid UTF-16 sequence +} + +pragma(inline, true) +dchar next_dchar(const(dchar)[] s, out size_t seq_len) +{ + assert(s.length > 0); + seq_len = 1; + return s[0]; +} + +size_t uni_convert(const(char)[] s, wchar[] buffer) { const(char)* p = s.ptr; const(char)* pend = p + s.length; wchar* b = buffer.ptr; - wchar* bEnd = buffer.ptr + buffer.length; + wchar* bend = buffer.ptr + buffer.length; while (p < pend) { - if (b >= bEnd) + if (b >= bend) return 0; // End of output buffer if ((*p & 0x80) == 0) // 1-byte sequence: 0xxxxxxx *b++ = *p++; @@ -32,7 +169,7 @@ size_t uniConvert(const(char)[] s, wchar[] buffer) } else if ((*p & 0xF8) == 0xF0) // 4-byte sequence: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx { - if (p + 3 >= pend || b + 1 >= bEnd) + if (p + 3 >= pend || b + 1 >= bend) return 0; // Unexpected end of input/output dchar codepoint = ((p[0] & 0x07) << 18) | ((p[1] & 0x3F) << 12) | ((p[2] & 0x3F) << 6) | (p[3] & 0x3F); codepoint -= 0x10000; @@ -47,16 +184,16 @@ size_t uniConvert(const(char)[] s, wchar[] buffer) return b - buffer.ptr; } -size_t uniConvert(const(char)[] s, dchar[] buffer) +size_t uni_convert(const(char)[] s, dchar[] buffer) { const(char)* p = s.ptr; const(char)* pend = p + s.length; dchar* b = buffer.ptr; - dchar* bEnd = buffer.ptr + buffer.length; + dchar* bend = buffer.ptr + buffer.length; while (p < pend) { - if (b >= bEnd) + if (b >= bend) return 0; if ((*p & 0x80) == 0) // 1-byte sequence: 0xxxxxxx *b++ = *p++; @@ -84,16 +221,16 @@ size_t uniConvert(const(char)[] s, dchar[] buffer) return b - buffer.ptr; } -size_t uniConvert(const(wchar)[] s, char[] buffer) +size_t uni_convert(const(wchar)[] s, char[] buffer) { const(wchar)* p = s.ptr; const(wchar)* pend = p + s.length; char* b = buffer.ptr; - char* bEnd = buffer.ptr + buffer.length; + char* bend = buffer.ptr + buffer.length; while (p < pend) { - if (b >= bEnd) + if (b >= bend) return 0; // End of output buffer if (p[0] >= 0xD800) { @@ -103,7 +240,7 @@ size_t uniConvert(const(wchar)[] s, char[] buffer) return 0; // Unexpected end of input if (p[0] < 0xDC00) // Surrogate pair: 110110xxxxxxxxxx 110111xxxxxxxxxx { - if (b + 3 >= bEnd) + if (b + 3 >= bend) return 0; // End of output buffer dchar codepoint = 0x10000 + ((p[0] - 0xD800) << 10) + (p[1] - 0xDC00); b[0] = 0xF0 | (codepoint >> 18); @@ -120,7 +257,7 @@ size_t uniConvert(const(wchar)[] s, char[] buffer) *b++ = cast(char)*p++; else if (*p < 0x800) // 2-byte sequence: 110xxxxx 10xxxxxx { - if (b + 1 >= bEnd) + if (b + 1 >= bend) return 0; // End of output buffer b[0] = 0xC0 | cast(char)(*p >> 6); b[1] = 0x80 | (*p++ & 0x3F); @@ -129,7 +266,7 @@ size_t uniConvert(const(wchar)[] s, char[] buffer) else // 3-byte sequence: 1110xxxx 10xxxxxx 10xxxxxx { three_byte_seq: - if (b + 2 >= bEnd) + if (b + 2 >= bend) return 0; // End of output buffer b[0] = 0xE0 | (*p >> 12); b[1] = 0x80 | ((*p >> 6) & 0x3F); @@ -140,24 +277,24 @@ size_t uniConvert(const(wchar)[] s, char[] buffer) return b - buffer.ptr; } -size_t uniConvert(const(wchar)[] s, dchar[] buffer) +size_t uni_convert(const(wchar)[] s, dchar[] buffer) { const(wchar)* p = s.ptr; const(wchar)* pend = p + s.length; dchar* b = buffer.ptr; - dchar* bEnd = buffer.ptr + buffer.length; + dchar* bend = buffer.ptr + buffer.length; while (p < pend) { - if (b >= bEnd) + if (b >= bend) return 0; // End of output buffer - if (p[0] >= 0xD800 && p[0] < 0xE000) + if ((p[0] >> 11) == 0x1B) { if (p + 1 >= pend) return 0; // Unexpected end of input - if (p[0] < 0xDC00) // Surrogate pair: 110110xxxxxxxxxx 110111xxxxxxxxxx + if (p[0] < 0xDC00 && (p[1] >> 10) == 0x37) // Surrogate pair: 110110xxxxxxxxxx 110111xxxxxxxxxx { - *b++ = 0x10000 + ((p[0] - 0xD800) << 10) + (p[1] - 0xDC00); + *b++ = 0x10000 + ((p[0] & 0x3FF) << 10 | (p[1] & 0x3FF)); p += 2; continue; } @@ -168,22 +305,22 @@ size_t uniConvert(const(wchar)[] s, dchar[] buffer) return b - buffer.ptr; } -size_t uniConvert(const(dchar)[] s, char[] buffer) +size_t uni_convert(const(dchar)[] s, char[] buffer) { const(dchar)* p = s.ptr; const(dchar)* pend = p + s.length; char* b = buffer.ptr; - char* bEnd = buffer.ptr + buffer.length; + char* bend = buffer.ptr + buffer.length; while (p < pend) { - if (b >= bEnd) + if (b >= bend) return 0; // End of output buffer if (*p < 0x80) // 1-byte sequence: 0xxxxxxx *b++ = cast(char)*p++; else if (*p < 0x800) // 2-byte sequence: 110xxxxx 10xxxxxx { - if (b + 1 >= bEnd) + if (b + 1 >= bend) return 0; // End of output buffer b[0] = 0xC0 | cast(char)(*p >> 6); b[1] = 0x80 | (*p++ & 0x3F); @@ -191,7 +328,7 @@ size_t uniConvert(const(dchar)[] s, char[] buffer) } else if (*p < 0x10000) // 3-byte sequence: 1110xxxx 10xxxxxx 10xxxxxx { - if (b + 2 >= bEnd) + if (b + 2 >= bend) return 0; // End of output buffer b[0] = 0xE0 | cast(char)(*p >> 12); b[1] = 0x80 | ((*p >> 6) & 0x3F); @@ -200,7 +337,7 @@ size_t uniConvert(const(dchar)[] s, char[] buffer) } else if (*p < 0x110000) // 4-byte sequence: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx { - if (b + 3 >= bEnd) + if (b + 3 >= bend) return 0; // End of output buffer b[0] = 0xF0 | (*p >> 18); b[1] = 0x80 | ((*p >> 12) & 0x3F); @@ -214,22 +351,22 @@ size_t uniConvert(const(dchar)[] s, char[] buffer) return b - buffer.ptr; } -size_t uniConvert(const(dchar)[] s, wchar[] buffer) +size_t uni_convert(const(dchar)[] s, wchar[] buffer) { const(dchar)* p = s.ptr; const(dchar)* pend = p + s.length; wchar* b = buffer.ptr; - wchar* bEnd = buffer.ptr + buffer.length; + wchar* bend = buffer.ptr + buffer.length; while (p < pend) { - if (b >= bEnd) + if (b >= bend) return 0; // End of output buffer if (*p < 0x10000) *b++ = cast(wchar)*p++; else if (*p < 0x110000) { - if (b + 1 >= bEnd) + if (b + 1 >= bend) return 0; // End of output buffer dchar codepoint = *p++ - 0x10000; b[0] = 0xD800 | (codepoint >> 10); @@ -242,10 +379,507 @@ size_t uniConvert(const(dchar)[] s, wchar[] buffer) return b - buffer.ptr; } +char uni_to_lower(char c) + => c.to_lower(); + +dchar uni_to_lower(dchar c) +{ + if (uint(c - 'A') < 26) + return c | 0x20; + + // TODO: this is a deep rabbit-hole! (and the approach might not be perfect) + + if (c < 0xFF) + { + if (c >= 0xC0) // Latin-1 Supplement + return g_to_lower_latin_1.ptr[c - 0xC0]; + } + else if (c <= 0x556) + { + if (c >= 0x370) + { + if (c < 0x400) // Greek and Coptic + return 0x300 | g_to_lower_greek.ptr[c - 0x370]; + else if (c < 0x460) // Cyrillic + { + if (c < 0x410) + return c + 0x50; + else if (c < 0x430) + return c + 0x20; + } + else if (c < 0x530) // Cyrillic Supplement + { + if (c >= 0x482 && c < 0x48A) // exceptions + return c; + return c | 1; + } + else if (c >= 0x531) // Armenian + return c + 0x30; + } + else if (c < 0x180) // Latin Extended-A + return (0x100 | g_to_lower_latin_extended_a.ptr[c - 0xFF]) - 1; + } + else if (c <= 0x1CB0) // Georgian + { + if (c >= 0x1C90) + return c - 0x0BC0; // Mtavruli -> Mkhedruli + else if (c >= 0x10A0 && c <= 0x10C5) + return c + 0x1C60; // Asomtavruli -> Nuskhuri + } + else if (c >= 0x1E00) + { + if (c < 0x1F00) // Latin Extended Additional + { + if (c >= 0x1E96 && c < 0x1EA0) // exceptions + { + if (c == 0x1E9E) // 'ẞ' -> 'ß' + return 0xDF; + return c; + } + return c | 1; + } + else if (c <= 0x1FFC) // Greek Extended + { + if (c < 0x1F70) + return c & ~0x8; + return 0x1F00 | g_to_lower_greek_extended.ptr[c - 0x1F70]; + } + else if (c < 0x2CE4) + { + if (c >= 0x2C80) // Coptic + return c | 1; + } + } + return c; +} + +char uni_to_upper(char c) + => c.to_upper(); + +dchar uni_to_upper(dchar c) +{ + if (uint(c - 'a') < 26) + return c ^ 0x20; + + // TODO: this is a deep rabbit-hole! (and the approach might not be perfect) + + if (c < 0xFF) + { + if (c == 0xDF) // 'ß' -> 'ẞ' + return 0x1E9E; + if (c >= 0xC0) // Latin-1 Supplement + return g_to_upper_latin_1.ptr[c - 0xC0]; + } + else if (c <= 0x586) + { + if (c >= 0x370) + { + if (c < 0x400) // Greek and Coptic + return 0x300 | g_to_upper_greek.ptr[c - 0x370]; + else if (c < 0x460) // Cyrillic + { + if (c >= 0x450) + return c - 0x50; + else if (c >= 0x430) + return c - 0x20; + } + else if (c < 0x530) // Cyrillic Supplement + { + if (c >= 0x482 && c < 0x48A) // exceptions + return c; + return c & ~1; + } + else if (c >= 0x561) // Armenian + return c - 0x30; + } + else if (c < 0x180) // Latin Extended-A + return 0x100 | g_to_upper_latin_extended_a.ptr[c - 0xFF]; + } + else if (c <= 0x10F0) // Georgian + { + if (c >= 0x10D0) + return c + 0x0BC0; // Mkhedruli -> Mtavruli + } + else if (c >= 0x1E00) + { + if (c < 0x1F00) // Latin Extended Additional + { + if (c >= 0x1E96 && c < 0x1EA0) // exceptions + return c; + return c & ~1; + } + else if (c <= 0x1FFC) // Greek Extended + { + if (c < 0x1F70) + return c | 0x8; + return 0x1F00 | g_to_upper_greek_extended.ptr[c - 0x1F70]; + } + else if (c < 0x2CE4) + { + if (c >= 0x2C80) // Coptic + return c & ~1; + } + else if (c <= 0x2D25) // Georgian + { + if(c >= 0x2D00) + return c - 0x1C60; // Nuskhuri -> Asomtavruli + } + } + return c; +} + +char uni_case_fold(char c) + => c.to_lower(); + +dchar uni_case_fold(dchar c) +{ + // case-folding is stronger than to_lower, there may be many misc cases... + if (c >= 0x3C2) // Greek has bonus case-folding... + { + if (c < 0x3FA) + return 0x300 | g_case_fold_greek.ptr[c - 0x3C2]; + } + else if (c == 'ſ') // TODO: pointless? it's in the spec... + return 's'; + return uni_to_lower(c); +} + +int uni_compare(T, U)(const(T)[] s1, const(U)[] s2) + if (is_some_char!T && is_some_char!U) +{ + const(T)* p1 = s1.ptr; + const(T)* p1end = p1 + s1.length; + const(U)* p2 = s2.ptr; + const(U)* p2end = p2 + s2.length; + + // TODO: this is crude and insufficient; doesn't handle compound diacritics, etc (needs a NFKC normalisation step) + + while (true) + { + // return int.min/max in the case that the strings are a sub-string of the other so the caller can detect this case + if (p1 >= p1end) + return p2 < p2end ? int.min : 0; + if (p2 >= p2end) + return int.max; + + dchar a = *p1, b = *p2; + + if (a < 0x80) + { + if (a != b) + return int(a) - int(b); + ++p1; + p2 += b < 0x80 ? 1 : p2[0 .. p2end - p2].uni_seq_len; + } + else if (b < 0x80) + { + if (a != b) + return int(a) - int(b); + p1 += p1[0 .. p1end - p1].uni_seq_len; + ++p2; + } + else + { + size_t al, bl; + a = next_dchar(p1[0 .. p1end - p1], al); + b = next_dchar(p2[0 .. p2end - p2], bl); + if (a != b) + return cast(int)a - cast(int)b; + p1 += al; + p2 += bl; + } + } +} + +int uni_compare_i(T, U)(const(T)[] s1, const(U)[] s2) + if (is_some_char!T && is_some_char!U) +{ + const(T)* p1 = s1.ptr; + const(T)* p1end = p1 + s1.length; + const(U)* p2 = s2.ptr; + const(U)* p2end = p2 + s2.length; + + // TODO: this is crude and insufficient; doesn't handle compound diacritics, etc (needs a NFKC normalisation step) + // that said, it's also overkill for embedded use! + + size_t al, bl; + while (p1 < p1end && p2 < p2end) + { + dchar a = *p1; + dchar b = void; + if (a < 0x80) + { + // ascii fast-path + a = (cast(char)a).to_lower; + b = *p2; + if (uint(b - 'A') < 26) + b |= 0x20; + if (a != b) + { + if (b >= 0x80) + { + // `b` is not ascii; break-out to the slow path... + al = 1; + goto uni_compare_load_b; + } + return cast(int)a - cast(int)b; + } + ++p1; + ++p2; + } + else + { + a = next_dchar(p1[0 .. p1end - p1], al).uni_case_fold; + uni_compare_load_b: + b = next_dchar(p2[0 .. p2end - p2], bl).uni_case_fold; + uni_compare_a_b: + if (a != b) + { + // it is _SO UNFORTUNATE_ that the ONLY special-case letter in all of unicode is german 'ß' (0xDF)!! + if (b == 0xDF) + { + if (a != 's') + return cast(int)a - cast(int)'s'; + if (++p1 == p1end) + return -1; // only one 's', so the a-side is a shorter string + a = next_dchar(p1[0 .. p1end - p1], al).uni_case_fold; + b = 's'; + p2 += bl - 1; + bl = 1; + goto uni_compare_a_b; + } + else if (a == 0xDF) + { + if (b != 's') + return cast(int)'s' - cast(int)b; + if (++p2 == p2end) + return 1; // only one 's', so the b-side is a shorter string + a = 's'; + p1 += al - 1; + al = 1; + goto uni_compare_load_b; + } + return cast(int)a - cast(int)b; + } + p1 += al; + p2 += bl; + } + } + + // return int.min/max in the case that the strings are a sub-string of the other so the caller can detect this case + return (p1 < p1end) ? int.max : (p2 < p2end) ? int.min : 0; +} + + +private: + +// this is a helper to crush character maps into single byte arrays... +ubyte[N] map_chars(size_t N)(ubyte function(wchar) pure nothrow @nogc translate, wchar[N] map) +{ + if (__ctfe) + { + ubyte[N] result; + foreach (i; 0 .. N) + result[i] = translate(map[i]); + return result; + } + else + assert(false, "Not for runtime!"); +} + +// lookup tables for case conversion +__gshared immutable g_to_lower_latin_1 = map_chars(c => cast(ubyte)c, to_lower_latin[0 .. 0x3F]); +__gshared immutable g_to_upper_latin_1 = map_chars(c => cast(ubyte)c, to_upper_latin[0 .. 0x3F]); +__gshared immutable g_to_lower_latin_extended_a = map_chars(c => cast(ubyte)(c + 1), to_lower_latin[0x3F .. 0xC0]); // calculate `(0x100 | table[n]) - 1` at runtime +__gshared immutable g_to_upper_latin_extended_a = map_chars(c => cast(ubyte)c, to_upper_latin[0x3F .. 0xC0]); // calculate `0x100 | table[n]` at runtime +__gshared immutable g_to_lower_greek = map_chars(c => cast(ubyte)c, to_lower_greek); // calculate `0x300 | table[n]` at runtime +__gshared immutable g_to_upper_greek = map_chars(c => cast(ubyte)c, to_upper_greek); // calculate `0x300 | table[n]` at runtime +__gshared immutable g_case_fold_greek = map_chars(c => cast(ubyte)c, case_fold_greek); // calculate `0x300 | table[n]` at runtime +__gshared immutable g_to_lower_greek_extended = map_chars(c => cast(ubyte)c, to_lower_greek_extended); // calculate `0x1F00 | table[n]` at runtime +__gshared immutable g_to_upper_greek_extended = map_chars(c => cast(ubyte)c, to_upper_greek_extended); // calculate `0x1F00 | table[n]` at runtime + +// Latin-1 Supplement and Latin Extended-A +enum wchar[0x180 - 0xC0] to_lower_latin = [ + 'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', + 'ð', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', 0xD7,'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'þ', 'ß', + 'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', + 'ð', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', 0xF7,'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'þ', 'ÿ', + 'ā', 'ā', 'ă', 'ă', 'ą', 'ą', 'ć', 'ć', 'ĉ', 'ĉ', 'ċ', 'ċ', 'č', 'č', 'ď', 'ď', + 'đ', 'đ', 'ē', 'ē', 'ĕ', 'ĕ', 'ė', 'ė', 'ę', 'ę', 'ě', 'ě', 'ĝ', 'ĝ', 'ğ', 'ğ', + 'ġ', 'ġ', 'ģ', 'ģ', 'ĥ', 'ĥ', 'ħ', 'ħ', 'ĩ', 'ĩ', 'ī', 'ī', 'ĭ', 'ĭ', 'į', 'į', + 0x130,0x131,'ij', 'ij', 'ĵ', 'ĵ', 'ķ', 'ķ',0x138,'ĺ', 'ĺ', 'ļ', 'ļ', 'ľ', 'ľ', 'ŀ', + 'ŀ', 'ł', 'ł', 'ń', 'ń', 'ņ', 'ņ', 'ň', 'ň',0x149,'ŋ', 'ŋ', 'ō', 'ō', 'ŏ', 'ŏ', + 'ő', 'ő', 'œ', 'œ', 'ŕ', 'ŕ', 'ŗ', 'ŗ', 'ř', 'ř', 'ś', 'ś', 'ŝ', 'ŝ', 'ş', 'ş', + 'š', 'š', 'ţ', 'ţ', 'ť', 'ť', 'ŧ', 'ŧ', 'ũ', 'ũ', 'ū', 'ū', 'ŭ', 'ŭ', 'ů', 'ů', + 'ű', 'ű', 'ų', 'ų', 'ŵ', 'ŵ', 'ŷ', 'ŷ', 'ÿ', 'ź', 'ź', 'ż', 'ż', 'ž', 'ž', 'ſ' +]; + +enum wchar[0x180 - 0xC0] to_upper_latin = [ + 'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', + 'Ð', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 0xD7,'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'Þ', 'ẞ', + 'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', + 'Ð', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 0xF7,'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'Þ', 'Ÿ', + 'Ā', 'Ā', 'Ă', 'Ă', 'Ą', 'Ą', 'Ć', 'Ć', 'Ĉ', 'Ĉ', 'Ċ', 'Ċ', 'Č', 'Č', 'Ď', 'Ď', + 'Đ', 'Đ', 'Ē', 'Ē', 'Ĕ', 'Ĕ', 'Ė', 'Ė', 'Ę', 'Ę', 'Ě', 'Ě', 'Ĝ', 'Ĝ', 'Ğ', 'Ğ', + 'Ġ', 'Ġ', 'Ģ', 'Ģ', 'Ĥ', 'Ĥ', 'Ħ', 'Ħ', 'Ĩ', 'Ĩ', 'Ī', 'Ī', 'Ĭ', 'Ĭ', 'Į', 'Į', + 0x130,0x131,'IJ', 'IJ', 'Ĵ', 'Ĵ', 'Ķ', 'Ķ',0x138,'Ĺ', 'Ĺ', 'Ļ', 'Ļ', 'Ľ', 'Ľ', 'Ŀ', + 'Ŀ', 'Ł', 'Ł', 'Ń', 'Ń', 'Ņ', 'Ņ', 'Ň', 'Ň',0x149,'Ŋ', 'Ŋ', 'Ō', 'Ō', 'Ŏ', 'Ŏ', + 'Ő', 'Ő', 'Œ', 'Œ', 'Ŕ', 'Ŕ', 'Ŗ', 'Ŗ', 'Ř', 'Ř', 'Ś', 'Ś', 'Ŝ', 'Ŝ', 'Ş', 'Ş', + 'Š', 'Š', 'Ţ', 'Ţ', 'Ť', 'Ť', 'Ŧ', 'Ŧ', 'Ũ', 'Ũ', 'Ū', 'Ū', 'Ŭ', 'Ŭ', 'Ů', 'Ů', + 'Ű', 'Ű', 'Ų', 'Ų', 'Ŵ', 'Ŵ', 'Ŷ', 'Ŷ', 'Ÿ', 'Ź', 'Ź', 'Ż', 'Ż', 'Ž', 'Ž', 'S' +]; + +// Greek and Coptic +enum wchar[0x400 - 0x370] to_lower_greek = [ + 'ͱ', 'ͱ', 'ͳ', 'ͳ',0x374,0x375,'ͷ','ͷ',0x378,0x379,0x37A,'ͻ','ͼ','ͽ',0x37E,'ϳ', +0x380,0x381,0x382,0x383,0x384,0x385,'ά',0x387,'έ','ή','ί',0x38B,'ό',0x38D,'ύ', 'ώ', + 0x390,'α', 'β', 'γ', 'δ', 'ε', 'ζ', 'η', 'θ', 'ι', 'κ', 'λ', 'μ', 'ν', 'ξ', 'ο', + 'π', 'ρ',0x3A2,'σ', 'τ', 'υ', 'φ', 'χ', 'ψ', 'ω', 'ϊ', 'ϋ', 'ά', 'έ', 'ή', 'ί', + 0x3B0,'α', 'β', 'γ', 'δ', 'ε', 'ζ', 'η', 'θ', 'ι', 'κ', 'λ', 'μ', 'ν', 'ξ', 'ο', + 'π', 'ρ', 'ς', 'σ', 'τ', 'υ', 'φ', 'χ', 'ψ', 'ω', 'ϊ', 'ϋ', 'ό', 'ύ', 'ώ', 'ϗ', + 'ϐ', 'ϑ', 'υ', 'ύ', 'ϋ', 'ϕ', 'ϖ', 'ϗ', 'ϙ', 'ϙ', 'ϛ', 'ϛ', 'ϝ', 'ϝ', 'ϟ', 'ϟ', + 'ϡ', 'ϡ', 'ϣ', 'ϣ', 'ϥ', 'ϥ', 'ϧ', 'ϧ', 'ϩ', 'ϩ', 'ϫ', 'ϫ', 'ϭ', 'ϭ', 'ϯ', 'ϯ', + 'ϰ', 'ϱ', 'ϲ', 'ϳ', 'θ', 'ϵ',0x3F6,'ϸ', 'ϸ', 'ϲ', 'ϻ', 'ϻ',0x3FC,'ͻ', 'ͼ', 'ͽ' +]; + +enum wchar[0x400 - 0x370] to_upper_greek = [ + 'Ͱ', 'Ͱ', 'Ͳ', 'Ͳ',0x374,0x375,'Ͷ','Ͷ',0x378,0x379,0x37A,'Ͻ','Ͼ','Ͽ',0x37E,'Ϳ', +0x380,0x381,0x382,0x383,0x384,0x385,'Ά',0x387,'Έ','Ή','Ί',0x38B,'Ό',0x38D,'Ύ', 'Ώ', + 0x390,'Α', 'Β', 'Γ', 'Δ', 'Ε', 'Ζ', 'Η', 'Θ', 'Ι', 'Κ', 'Λ', 'Μ', 'Ν', 'Ξ', 'Ο', + 'Π', 'Ρ',0x3A2,'Σ', 'Τ', 'Υ', 'Φ', 'Χ', 'Ψ', 'Ω', 'Ϊ', 'Ϋ', 'Ά', 'Έ', 'Ή', 'Ί', + 0x3B0,'Α', 'Β', 'Γ', 'Δ', 'Ε', 'Ζ', 'Η', 'Θ', 'Ι', 'Κ', 'Λ', 'Μ', 'Ν', 'Ξ', 'Ο', + 'Π', 'Ρ', 'Σ', 'Σ', 'Τ', 'Υ', 'Φ', 'Χ', 'Ψ', 'Ω', 'Ϊ', 'Ϋ', 'Ό', 'Ύ', 'Ώ', 'Ϗ', + 'Β','Θ',0x3D2,0x3D3,0x3D4,'Φ','Π', 'Ϗ', 'Ϙ', 'Ϙ', 'Ϛ', 'Ϛ', 'Ϝ', 'Ϝ', 'Ϟ', 'Ϟ', + 'Ϡ', 'Ϡ', 'Ϣ', 'Ϣ', 'Ϥ', 'Ϥ', 'Ϧ', 'Ϧ', 'Ϩ', 'Ϩ', 'Ϫ', 'Ϫ', 'Ϭ', 'Ϭ', 'Ϯ', 'Ϯ', + 'Κ', 'Ρ', 'Ϲ', 'Ϳ', 'ϴ', 'Ε',0x3F6,'Ϸ', 'Ϸ', 'Ϲ', 'Ϻ', 'Ϻ',0x3FC,'Ͻ', 'Ͼ', 'Ͽ' +]; + +enum wchar[0x3FA - 0x3C2] case_fold_greek = [ + 'σ', 'σ', 'τ', 'υ', 'φ', 'χ', 'ψ', 'ω', 'ϊ', 'ϋ', 'ό', 'ύ', 'ώ', 'ϗ', + 'β', 'θ', 'υ', 'ύ', 'ϋ', 'φ', 'π', 'ϗ', 'ϙ', 'ϙ', 'ϛ', 'ϛ', 'ϝ', 'ϝ', 'ϟ', 'ϟ', + 'ϡ', 'ϡ', 'ϣ', 'ϣ', 'ϥ', 'ϥ', 'ϧ', 'ϧ', 'ϩ', 'ϩ', 'ϫ', 'ϫ', 'ϭ', 'ϭ', 'ϯ', 'ϯ', + 'κ', 'ρ', 'σ', 'ϳ', 'θ', 'ε',0x3F6,'ϸ', 'ϸ', 'σ' +]; + +enum wchar[0x1FFD - 0x1F70] to_lower_greek_extended = [ + 'ὰ', 'ά', 'ὲ', 'έ', 'ὴ', 'ή', 'ὶ', 'ί', 'ὸ', 'ό', 'ὺ', 'ύ', 'ὼ', 'ώ', 0x1F7E,0x1F7F, + 'ᾀ', 'ᾁ', 'ᾂ', 'ᾃ', 'ᾄ', 'ᾅ', 'ᾆ', 'ᾇ', 'ᾀ', 'ᾁ', 'ᾂ', 'ᾃ', 'ᾄ', 'ᾅ', 'ᾆ', 'ᾇ', + 'ᾐ', 'ᾑ', 'ᾒ', 'ᾓ', 'ᾔ', 'ᾕ', 'ᾖ', 'ᾗ', 'ᾐ', 'ᾑ', 'ᾒ', 'ᾓ', 'ᾔ', 'ᾕ', 'ᾖ', 'ᾗ', + 'ᾠ', 'ᾡ', 'ᾢ', 'ᾣ', 'ᾤ', 'ᾥ', 'ᾦ', 'ᾧ', 'ᾠ', 'ᾡ', 'ᾢ', 'ᾣ', 'ᾤ', 'ᾥ', 'ᾦ', 'ᾧ', + 'ᾰ', 'ᾱ', 'ᾲ', 'ᾳ', 'ᾴ', 0x1FB5, 'ᾶ', 'ᾷ', 'ᾰ', 'ᾱ', 'ὰ', 'ά', 'ᾳ', 0x1FBD,0x1FBE,0x1FBF, +0x1FC0,0x1FC1,'ῂ', 'ῃ', 'ῄ', 0x1FC5, 'ῆ', 'ῇ', 'ὲ', 'έ', 'ὴ', 'ή', 'ῃ', 0x1FCD,0x1FCE,0x1FCF, + 'ῐ', 'ῑ', 'ῒ', 'ΐ', 0x1FD4,0x1FD5, 'ῖ', 'ῗ', 'ῐ', 'ῑ', 'ὶ', 'ί',0x1FDC,0x1FDD,0x1FDE,0x1FDF, + 'ῠ', 'ῡ', 'ῢ', 'ΰ', 'ῤ', 'ῥ', 'ῦ', 'ῧ', 'ῠ', 'ῡ', 'ὺ', 'ύ', 'ῥ', 0x1FED,0x1FEE,0x1FEF, +0x1FF0,0x1FF1,'ῲ', 'ῳ', 'ῴ', 0x1FF5, 'ῶ', 'ῷ', 'ὸ', 'ό', 'ὼ', 'ώ', 'ῳ' +]; + +enum wchar[0x1FFD - 0x1F70] to_upper_greek_extended = [ + 'Ὰ', 'Ά', 'Ὲ', 'Έ', 'Ὴ', 'Ή', 'Ὶ', 'Ί', 'Ὸ', 'Ό', 'Ὺ', 'Ύ', 'Ὼ', 'Ώ', 0x1F7E,0x1F7F, + 'ᾈ', 'ᾉ', 'ᾊ', 'ᾋ', 'ᾌ', 'ᾍ', 'ᾎ', 'ᾏ', 'ᾈ', 'ᾉ', 'ᾊ', 'ᾋ', 'ᾌ', 'ᾍ', 'ᾎ', 'ᾏ', + 'ᾘ', 'ᾙ', 'ᾚ', 'ᾛ', 'ᾜ', 'ᾝ', 'ᾞ', 'ᾟ', 'ᾘ', 'ᾙ', 'ᾚ', 'ᾛ', 'ᾜ', 'ᾝ', 'ᾞ', 'ᾟ', + 'ᾨ', 'ᾩ', 'ᾪ', 'ᾫ', 'ᾬ', 'ᾭ', 'ᾮ', 'ᾯ', 'ᾨ', 'ᾩ', 'ᾪ', 'ᾫ', 'ᾬ', 'ᾭ', 'ᾮ', 'ᾯ', + 'Ᾰ', 'Ᾱ', 0x1FB2, 'ᾼ', 0x1FB4,0x1FB5,0x1FB6,0x1FB7, 'Ᾰ', 'Ᾱ', 'Ὰ', 'Ά', 'ᾼ', 0x1FBD,0x1FBE,0x1FBF, +0x1FC0,0x1FC1,0x1FC2, 'ῌ', 0x1FC4,0x1FC5,0x1FC6,0x1FC7, 'Ὲ', 'Έ', 'Ὴ', 'Ή', 'ῌ', 0x1FCD,0x1FCE,0x1FCF, + 'Ῐ', 'Ῑ', 0x1FD2,0x1FD3,0x1FD4,0x1FD5,0x1FD6,0x1FD7, 'Ῐ', 'Ῑ', 'Ὶ', 'Ί',0x1FDC,0x1FDD,0x1FDE,0x1FDF, + 'Ῠ', 'Ῡ', 0x1FE2,0x1FE3,0x1FE4, 'Ῥ', 0x1FE6,0x1FE7, 'Ῠ', 'Ῡ', 'Ὺ', 'Ύ', 'Ῥ', 0x1FED,0x1FEE,0x1FEF, +0x1FF0,0x1FF1,0x1FF2, 'ῼ', 0x1FF4,0x1FF5,0x1FF6,0x1FF7, 'Ὸ', 'Ό', 'Ὼ', 'Ώ', 'ῼ' +]; + +// NOTE: Cyrillic is runtime calculable, no tables required! + + unittest { - immutable dstring unicodeTest = + immutable ushort[5] surrogates = [ 0xD800, 0xD800, 0xDC00, 0xD800, 0x0020 ]; + + // test uni_seq_len functions + assert(uni_seq_len("Hello, World!") == 1); + assert(uni_seq_len("ñowai!") == 2); + assert(uni_seq_len("你好") == 3); + assert(uni_seq_len("😊wow!") == 4); + assert(uni_seq_len("\xFFHello") == 1); + assert(uni_seq_len("\xC2") == 1); + assert(uni_seq_len("\xC2Hello") == 1); + assert(uni_seq_len("\xE2") == 1); + assert(uni_seq_len("\xE2Hello") == 1); + assert(uni_seq_len("\xE2\x82") == 2); + assert(uni_seq_len("\xE2\x82Hello") == 2); + assert(uni_seq_len("\xF0") == 1); + assert(uni_seq_len("\xF0Hello") == 1); + assert(uni_seq_len("\xF0\x9F") == 2); + assert(uni_seq_len("\xF0\x9FHello") == 2); + assert(uni_seq_len("\xF0\x9F\x98") == 3); + assert(uni_seq_len("\xF0\x9F\x98Hello") == 3); + assert(uni_seq_len("Hello, World!"w) == 1); + assert(uni_seq_len("ñowai!"w) == 1); + assert(uni_seq_len("你好"w) == 1); + assert(uni_seq_len("😊wow!"w) == 2); + assert(uni_seq_len(cast(wchar[])surrogates[0..1]) == 1); + assert(uni_seq_len(cast(wchar[])surrogates[0..2]) == 1); + assert(uni_seq_len(cast(wchar[])surrogates[2..3]) == 1); + assert(uni_seq_len(cast(wchar[])surrogates[3..5]) == 1); + assert(uni_seq_len("😊wow!"d) == 1); + + // test uni_strlen + assert(uni_strlen("Hello, World!") == 13); + assert(uni_strlen("ñowai!") == 6); + assert(uni_strlen("你好") == 2); + assert(uni_strlen("😊wow!") == 5); + assert(uni_strlen("\xFFHello") == 6); + assert(uni_strlen("\xC2") == 1); + assert(uni_strlen("\xC2Hello") == 6); + assert(uni_strlen("\xE2") == 1); + assert(uni_strlen("\xE2Hello") == 6); + assert(uni_strlen("\xE2\x82") == 1); + assert(uni_strlen("\xE2\x82Hello") == 6); + assert(uni_strlen("\xF0") == 1); + assert(uni_strlen("\xF0Hello") == 6); + assert(uni_strlen("\xF0\x9F") == 1); + assert(uni_strlen("\xF0\x9FHello") == 6); + assert(uni_strlen("\xF0\x9F\x98") == 1); + assert(uni_strlen("\xF0\x9F\x98Hello") == 6); + assert(uni_strlen("Hello, World!"w) == 13); + assert(uni_strlen("ñowai!"w) == 6); + assert(uni_strlen("你好"w) == 2); + assert(uni_strlen("😊wow!"w) == 5); + assert(uni_strlen(cast(wchar[])surrogates[0..1]) == 1); + assert(uni_strlen(cast(wchar[])surrogates[0..2]) == 2); + assert(uni_strlen(cast(wchar[])surrogates[2..3]) == 1); + assert(uni_strlen(cast(wchar[])surrogates[3..5]) == 2); + assert(uni_strlen("😊wow!"d) == 5); + + // test next_dchar functions + size_t sl; + assert(next_dchar("Hello, World!", sl) == 'H' && sl == 1); + assert(next_dchar("ñowai!", sl) == 'ñ' && sl == 2); + assert(next_dchar("你好", sl) == '你' && sl == 3); + assert(next_dchar("😊wow!", sl) == '😊' && sl == 4); + assert(next_dchar("\xFFHello", sl) == '�' && sl == 1); + assert(next_dchar("\xC2", sl) == '�' && sl == 1); + assert(next_dchar("\xC2Hello", sl) == '�' && sl == 1); + assert(next_dchar("\xE2", sl) == '�' && sl == 1); + assert(next_dchar("\xE2Hello", sl) == '�' && sl == 1); + assert(next_dchar("\xE2\x82", sl) == '�' && sl == 2); + assert(next_dchar("\xE2\x82Hello", sl) == '�' && sl == 2); + assert(next_dchar("\xF0", sl) == '�' && sl == 1); + assert(next_dchar("\xF0Hello", sl) == '�' && sl == 1); + assert(next_dchar("\xF0\x9F", sl) == '�' && sl == 2); + assert(next_dchar("\xF0\x9FHello", sl) == '�' && sl == 2); + assert(next_dchar("\xF0\x9F\x98", sl) == '�' && sl == 3); + assert(next_dchar("\xF0\x9F\x98Hello", sl) == '�' && sl == 3); + assert(next_dchar("Hello, World!"w, sl) == 'H' && sl == 1); + assert(next_dchar("ñowai!"w, sl) == 'ñ' && sl == 1); + assert(next_dchar("你好"w, sl) == '你' && sl == 1); + assert(next_dchar("😊wow!"w, sl) == '😊' && sl == 2); + assert(next_dchar(cast(wchar[])surrogates[0..1], sl) == '�' && sl == 1); + assert(next_dchar(cast(wchar[])surrogates[0..2], sl) == '�' && sl == 1); + assert(next_dchar(cast(wchar[])surrogates[2..3], sl) == '�' && sl == 1); + assert(next_dchar(cast(wchar[])surrogates[3..5], sl) == '�' && sl == 1); + assert(next_dchar("😊wow!"d, sl) == '😊' && sl == 1); + + immutable dstring unicode_test = "Basic ASCII: Hello, World!\n" ~ + "Extended Latin: Café, résumé, naïve, jalapeño\n" ~ "BMP Examples: 你好, مرحبا, שלום, 😊, ☂️\n" ~ "Supplementary Planes: 𐍈, 𝒜, 🀄, 🚀\n" ~ "Surrogate Pair Test: 😀👨‍👩‍👧‍👦\n" ~ @@ -257,20 +891,142 @@ unittest "U+E000–U+FFFF Range:  (U+E000), 豈 (U+F900)" ~ "Control Characters: \u0008 \u001B \u0000\n"; - char[1024] utf8Buffer; - wchar[512] utf16Buffer; - dchar[512] utf32Buffer; + char[1024] utf8_buffer; + wchar[512] utf16_buffer; + dchar[512] utf32_buffer; // test all conversions with characters in every significant value range - size_t utf8Len = uniConvert(unicodeTest, utf8Buffer); // D-C - size_t utf16Len = uniConvert(utf8Buffer[0..utf8Len], utf16Buffer); // C-W - size_t utf32Len = uniConvert(utf16Buffer[0..utf16Len], utf32Buffer); // W-D - utf16Len = uniConvert(utf32Buffer[0..utf32Len], utf16Buffer); // D-W - utf8Len = uniConvert(utf16Buffer[0..utf16Len], utf8Buffer); // W-C - utf32Len = uniConvert(utf8Buffer[0..utf8Len], utf32Buffer); // C-D - assert(unicodeTest[] == utf32Buffer[0..utf32Len]); + size_t utf8_len = uni_convert(unicode_test, utf8_buffer); // D-C + size_t utf16_len = uni_convert(utf8_buffer[0..utf8_len], utf16_buffer); // C-W + size_t utf32_len = uni_convert(utf16_buffer[0..utf16_len], utf32_buffer); // W-D + utf16_len = uni_convert(utf32_buffer[0..utf32_len], utf16_buffer); // D-W + utf8_len = uni_convert(utf16_buffer[0..utf16_len], utf8_buffer); // W-C + utf32_len = uni_convert(utf8_buffer[0..utf8_len], utf32_buffer); // C-D + assert(unicode_test[] == utf32_buffer[0..utf32_len]); // TODO: test all the error cases; invalid characters, buffer overflows, truncated inputs, etc... //... -} + // test uni_to_lower and uni_to_upper + assert(uni_to_lower('A') == 'a'); + assert(uni_to_lower('Z') == 'z'); + assert(uni_to_lower('a') == 'a'); + assert(uni_to_lower('z') == 'z'); + assert(uni_to_lower('À') == 'à'); + assert(uni_to_lower('Ý') == 'ý'); + assert(uni_to_lower('Ÿ') == 'ÿ'); + assert(uni_to_lower('ÿ') == 'ÿ'); + assert(uni_to_lower('ß') == 'ß'); + assert(uni_to_lower('ẞ') == 'ß'); + assert(uni_to_lower('Α') == 'α'); + assert(uni_to_lower('Ω') == 'ω'); + assert(uni_to_lower('α') == 'α'); + assert(uni_to_lower('ω') == 'ω'); + assert(uni_to_lower('Ḁ') == 'ḁ'); + assert(uni_to_lower('ḁ') == 'ḁ'); + assert(uni_to_lower('ẝ') == 'ẝ'); + assert(uni_to_lower('😊') == '😊'); + assert(uni_to_upper('a') == 'A'); + assert(uni_to_upper('z') == 'Z'); + assert(uni_to_upper('A') == 'A'); + assert(uni_to_upper('Z') == 'Z'); + assert(uni_to_upper('à') == 'À'); + assert(uni_to_upper('ý') == 'Ý'); + assert(uni_to_upper('ÿ') == 'Ÿ'); + assert(uni_to_upper('Ÿ') == 'Ÿ'); + assert(uni_to_upper('ß') == 'ẞ'); + assert(uni_to_upper('ẞ') == 'ẞ'); + assert(uni_to_upper('α') == 'Α'); + assert(uni_to_upper('ω') == 'Ω'); + assert(uni_to_upper('Α') == 'Α'); + assert(uni_to_upper('Ω') == 'Ω'); + assert(uni_to_upper('ḁ') == 'Ḁ'); + assert(uni_to_upper('Ḁ') == 'Ḁ'); + assert(uni_to_upper('😊') == '😊'); + assert(uni_to_upper('џ') == 'Џ'); + assert(uni_to_upper('Џ') == 'Џ'); + assert(uni_to_upper('д') == 'Д'); + assert(uni_to_upper('Д') == 'Д'); + assert(uni_to_upper('ѻ') == 'Ѻ'); + assert(uni_to_upper('Ѻ') == 'Ѻ'); + assert(uni_to_upper('ԫ') == 'Ԫ'); + assert(uni_to_upper('Ԫ') == 'Ԫ'); + assert(uni_to_upper('ա') == 'Ա'); + assert(uni_to_upper('Ա') == 'Ա'); + + // test uni_compare + assert(uni_compare("Hello", "Hello") == 0); + assert(uni_compare("Hello", "hello") < 0); + assert(uni_compare("hello", "Hello") > 0); + assert(uni_compare("Hello", "Hello, World!") < 0); + assert(uni_compare("Café", "Café") == 0); + assert(uni_compare("Café", "CafÉ") > 0); + assert(uni_compare("CafÉ", "Café") < 0); + assert(uni_compare("Hello, 世界", "Hello, 世界") == 0); + assert(uni_compare("Hello, 世界", "Hello, 世") > 0); + assert(uni_compare("Hello, 世", "Hello, 世界") < 0); + assert(uni_compare("Hello, 😊", "Hello, 😊") == 0); + assert(uni_compare("Hello, 😊", "Hello, 😢") < 0); + assert(uni_compare("😊A", "😊a") < 0); + + // test uni_compare_i + assert(uni_compare_i("Hello", "Hello") == 0); + assert(uni_compare_i("Hello", "hello") == 0); + assert(uni_compare_i("hello", "Hello") == 0); + assert(uni_compare_i("Hello", "Hello, World!") < 0); + assert(uni_compare_i("hello", "HORLD") < 0); + assert(uni_compare_i("Hello, 世界", "hello, 世界") == 0); + assert(uni_compare_i("Hello, 世界", "hello, 世") > 0); + assert(uni_compare_i("Hello, 世", "hello, 世界") < 0); + assert(uni_compare_i("Hello, 😊", "hello, 😊") == 0); + assert(uni_compare_i("Hello, 😊", "hello, 😢") < 0); + assert(uni_compare_i("😊a", "😊B") < 0); + assert(uni_compare_i("AZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ", "azàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþ") == 0); // basic latin + latin-1 supplement + assert(uni_compare_i("ŸĀĦĬIJĹŁŇŊŒŠŦŶŹŽ", "ÿāħĭijĺłňŋœšŧŷźž") == 0); // more latin extended-a characters + assert(uni_compare_i("ḀṤẔẠỸỺỼỾ", "ḁṥẕạỹỻỽỿ") == 0); // just the extended latin + + // test various language pangrams! + assert(uni_compare_i("The quick brown fox jumps over the lazy dog", "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG") == 0); // english + assert(uni_compare_i("Sævör grét áðan því úlpan var ónýt", "SÆVÖR GRÉT ÁÐAN ÞVÍ ÚLPAN VAR ÓNÝT") == 0); // icelandic + assert(uni_compare_i("Příliš žluťoučký kůň úpěl ďábelské ódy.", "PŘÍLIŠ ŽLUŤOUČKÝ KŮŇ ÚPĚL ĎÁBELSKÉ ÓDY.") == 0); // czech + assert(uni_compare_i("Zażółć gęślą jaźń.", "ZAŻÓŁĆ GĘŚLĄ JAŹŃ.") == 0); // polish + assert(uni_compare_i("Φλεγματικά χρώματα που εξοβελίζουν ψευδαισθήσεις.", "ΦΛΕΓΜΑΤΙΚΆ ΧΡΏΜΑΤΑ ΠΟΥ ΕΞΟΒΕΛΊΖΟΥΝ ΨΕΥΔΑΙΣΘΉΣΕΙΣ.") == 0); // greek + assert(uni_compare_i("Любя, съешь щипцы, - вздохнёт мэр, - Кайф жгуч!", "ЛЮБЯ, СЪЕШЬ ЩИПЦЫ, - ВЗДОХНЁТ МЭР, - КАЙФ ЖГУЧ!") == 0); // russian + assert(uni_compare_i("Բել դղյակի ձախ ժամն օֆ ազգությանը ցպահանջ չճշտած վնաս էր եւ փառք։", "ԲԵԼ ԴՂՅԱԿԻ ՁԱԽ ԺԱՄՆ ՕՖ ԱԶԳՈՒԹՅԱՆԸ ՑՊԱՀԱՆՋ ՉՃՇՏԱԾ ՎՆԱՍ ԷՐ ԵՒ ՓԱՌՔ։") == 0); // armenian + assert(uni_compare_i("აბგად ევზეთ იკალ მანო, პაჟა რასტა უფქა ღაყაშ, ჩაცა ძაწა ჭახა ჯაჰო", "ᲐᲑᲒᲐᲓ ᲔᲕᲖᲔᲗ ᲘᲙᲐᲚ ᲛᲐᲜᲝ, ᲞᲐᲟᲐ ᲠᲐᲡᲢᲐ ᲣᲤᲥᲐ ᲦᲐᲧᲐᲨ, ᲩᲐᲪᲐ ᲫᲐᲬᲐ ᲭᲐᲮᲐ ᲯᲐᲰᲝ") == 0); // georgian modern + assert(uni_compare_i("ⴘⴄⴅ ⴟⴓ ⴠⴡⴢ ⴣⴤⴥ ⴇⴍⴚ ⴞⴐⴈ ⴝⴋⴊⴈ.", "ႸႤႥ ႿႳ ჀჁჂ ჃჄჅ ႧႭႺ ႾႰႨ ႽႫႪႨ.") == 0); // georgian ecclesiastical + assert(uni_compare_i("Ⲁⲛⲟⲕ ⲡⲉ ϣⲏⲙ ⲛ̄ⲕⲏⲙⲉ.", "ⲀⲚⲞⲔ ⲠⲈ ϢⲎⲘ Ⲛ̄ⲔⲎⲘⲈ.") == 0); // coptic + + // test the special-cases around german 'ß' (0xDF) and 'ẞ' (0x1E9E) + // check sort order + assert(uni_compare_i("ß", "sr") > 0); + assert(uni_compare_i("ß", "ss") == 0); + assert(uni_compare_i("ß", "st") < 0); + assert(uni_compare_i("sr", "ß") < 0); + assert(uni_compare_i("ss", "ß") == 0); + assert(uni_compare_i("st", "ß") > 0); + // check truncated comparisons + assert(uni_compare_i("ß", "s") > 0); + assert(uni_compare_i("ß", "r") > 0); + assert(uni_compare_i("ß", "t") < 0); + assert(uni_compare_i("s", "ß") < 0); + assert(uni_compare_i("r", "ß") < 0); + assert(uni_compare_i("t", "ß") > 0); + assert(uni_compare_i("ä", "ß") > 0); + assert(uni_compare_i("sß", "ss") > 0); + assert(uni_compare_i("sß", "ß") > 0); + assert(uni_compare_i("sß", "ßß") < 0); + assert(uni_compare_i("ss", "sß") < 0); + assert(uni_compare_i("ß", "sß") < 0); + assert(uni_compare_i("ßß", "sß") > 0); + // check uneven/recursive comparisons + assert(uni_compare_i("ßẞ", "ẞß") == 0); + assert(uni_compare_i("sß", "ẞs") == 0); + assert(uni_compare_i("ẞs", "sß") == 0); + assert(uni_compare_i("ẞß", "sßs") == 0); + assert(uni_compare_i("sẞs", "ẞß") == 0); + assert(uni_compare_i("sẞsß", "ßsßs") == 0); + assert(uni_compare_i("ẞsßs", "sßsß") == 0); + assert(uni_compare_i("ßßßs", "sßßß") == 0); + assert(uni_compare_i("sßßß", "ßßßs") == 0); +} diff --git a/src/urt/sync/critical.d b/src/urt/sync/critical.d new file mode 100644 index 0000000..3a6596a --- /dev/null +++ b/src/urt/sync/critical.d @@ -0,0 +1,239 @@ +module urt.sync.critical; + +import urt.atomic; + +nothrow @nogc: + + +// Scope-based "nothing else touches the protected state right now" guard. +// Critical sections are SHORT by contract - a handful of instructions. +// Long-held sections will starve other threads/cores; for long sections +// use a Mutex. +// +// Reentrant on every platform. Place a Critical as a field of the object +// it protects (or __gshared if it protects global state). + +struct Critical +{ +nothrow @nogc: + @disable this(this); + + bool init() + { + version (Windows) + InitializeCriticalSection(&_cs); + // POSIX/FreeRTOS/bare-metal: zero-init is the valid initial state. + return true; + } + + void destroy() + { + version (Windows) + DeleteCriticalSection(&_cs); + // other platforms: nothing to release + } + + CriticalGuard acquire() return + { + CriticalGuard g = void; + version (Windows) + { + EnterCriticalSection(&_cs); + g._critical = &this; + } + else version (Posix) + { + auto self = cast(size_t)pthread_self(); + if (atomicLoad(_owner) == self) + { + // already own it -- just bump the recursion count + ++_count; + } + else + { + while (!cas(&_owner, cast(size_t)0, self)) + pause(); + _count = 1; + } + g._critical = &this; + } + else version (FreeRTOS) + { + import urt.internal.sys.freertos : vPortEnterCritical; + vPortEnterCritical(&_mux); + g._critical = &this; + } + else + { + // bare-metal: always disable IRQs for same-core ISR protection. + // On SMP targets, also acquire a per-instance owner-tracked + // spinlock for cross-core protection. + import urt.driver.irq : irq_global_disable, has_smp; + g._prev = irq_global_disable(); + + static if (has_smp) + { + import urt.driver.irq : cpu_id; + uint self = cpu_id() + 1; // +1 so 0 stays "unowned" + if (atomicLoad(_owner) == self) + { + ++_count; + } + else + { + while (!cas(&_owner, cast(uint)0, self)) + pause(); + _count = 1; + } + g._critical = &this; + } + } + return g; + } + +private: + version (Windows) + { + CRITICAL_SECTION _cs; + } + else version (Posix) + { + shared size_t _owner; // current thread id, or 0 when unowned + int _count; // recursion depth (touched only by owner) + } + else version (FreeRTOS) + { + import urt.internal.sys.freertos : portMUX_TYPE; + portMUX_TYPE _mux; + } + else + { + // bare-metal: state only present on SMP targets. + import urt.driver.irq : has_smp; + static if (has_smp) + { + shared uint _owner; // (cpu_id + 1) of owner, or 0 when unowned + uint _count; // recursion depth (touched only by owner) + } + // (single-core: nothing per-instance -- the IRQ-disable is global + // on this core, and there are no other cores to spin against.) + } + + void _leave() + { + version (Windows) + LeaveCriticalSection(&_cs); + else version (Posix) + { + if (--_count == 0) + atomicStore!(MemoryOrder.release)(_owner, cast(size_t)0); + } + else version (FreeRTOS) + { + import urt.internal.sys.freertos : vPortExitCritical; + vPortExitCritical(&_mux); + } + else + { + // bare-metal: drop the spinlock on SMP; the guard destructor + // restores IRQs via _prev. + import urt.driver.irq : has_smp; + static if (has_smp) + { + if (--_count == 0) + atomicStore!(MemoryOrder.release)(_owner, cast(uint)0); + } + } + } +} + + +struct CriticalGuard +{ +nothrow @nogc: + @disable this(); + @disable this(this); + + ~this() + { + version (Windows) _critical._leave(); + else version (Posix) _critical._leave(); + else version (FreeRTOS) _critical._leave(); + else + { + import urt.driver.irq : irq_global_set, has_smp; + static if (has_smp) + _critical._leave(); + irq_global_set(_prev); + } + } + +private: + version (Windows) Critical* _critical; + else version (Posix) Critical* _critical; + else version (FreeRTOS) Critical* _critical; + else + { + import urt.driver.irq : has_smp; + static if (has_smp) + Critical* _critical; + bool _prev; + } +} + + +unittest +{ + Critical c; + assert(c.init()); + + // basic acquire/release + int x; + { + auto g = c.acquire(); + x = 42; + } + assert(x == 42); + + // reentrant: nested acquire on the same thread/core + { + auto g1 = c.acquire(); + { + auto g2 = c.acquire(); + x = 100; + } + // still held by g1 here + x = 101; + } + assert(x == 101); + + // re-acquirable after release + { + auto g = c.acquire(); + x = 7; + } + assert(x == 7); + + c.destroy(); +} + + +private: + +version (Windows) +{ + import urt.internal.sys.windows.winbase : CRITICAL_SECTION; + + // Re-declare with the attribute set we need (winbase declares these + // without nothrow @nogc). Linker resolves to the same Win32 symbols. + extern(Windows) nothrow @nogc: + void InitializeCriticalSection(CRITICAL_SECTION*); + void DeleteCriticalSection(CRITICAL_SECTION*); + void EnterCriticalSection(CRITICAL_SECTION*); + void LeaveCriticalSection(CRITICAL_SECTION*); +} +else version (Posix) +{ + extern(C) nothrow @nogc: + void* pthread_self(); +} diff --git a/src/urt/sync/event.d b/src/urt/sync/event.d new file mode 100644 index 0000000..277dffa --- /dev/null +++ b/src/urt/sync/event.d @@ -0,0 +1,362 @@ +module urt.sync.event; + +import urt.atomic; +import urt.time; + + +// Manual-reset event ("latch"). Holds a single sticky bit: +// - set() flips the bit to true and wakes ALL current waiters. +// - reset() flips the bit back to false. +// - wait() returns immediately if set, otherwise blocks until set. +// Does NOT clear the bit -- subsequent wait()s see it set +// until reset() is called explicitly. + +struct Event +{ +nothrow @nogc: + @disable this(this); + + bool init() + { + version (Windows) + { + _internal = CreateEventA(null, 1, 0, null); // bManualReset=TRUE, initial=FALSE + return _internal !is null; + } + else version (linux) + { + import urt.mem.allocator; + auto p = cast(LinuxEvent*)defaultAllocator().alloc(LinuxEvent.sizeof, LinuxEvent.alignof); + if (!p) + return false; + *p = LinuxEvent.init; + if (pthread_mutex_init(&p.m, null) != 0) + { + defaultAllocator().free(p[0..1]); + return false; + } + if (pthread_cond_init(&p.c, null) != 0) + { + pthread_mutex_destroy(&p.m); + defaultAllocator().free(p[0..1]); + return false; + } + _internal = p; + return true; + } + else version (FreeRTOS) + { + import urt.internal.sys.freertos; + _internal = xEventGroupCreate(); + return _internal !is null; + } + else version (BareMetal) + { + atomicStore(*cast(shared(uint)*)&_internal, 0u); + return true; + } + else + static assert(false, "Event not implemented for this platform"); + } + + void destroy() + { + version (Windows) + { + import urt.internal.sys.windows.winbase : CloseHandle; + if (_internal) + { + CloseHandle(_internal); + _internal = null; + } + } + else version (linux) + { + import urt.mem.allocator; + if (_internal) + { + auto p = cast(LinuxEvent*)_internal; + pthread_cond_destroy(&p.c); + pthread_mutex_destroy(&p.m); + defaultAllocator().free(p[0..1]); + _internal = null; + } + } + else version (FreeRTOS) + { + import urt.internal.sys.freertos; + if (_internal) + { + vEventGroupDelete(_internal); + _internal = null; + } + } + else version (BareMetal) + { + // nothing to free + } + } + + void set() + { + version (Windows) + SetEvent(_internal); + else version (linux) + { + auto p = cast(LinuxEvent*)_internal; + pthread_mutex_lock(&p.m); + p.flag = true; + pthread_cond_broadcast(&p.c); + pthread_mutex_unlock(&p.m); + } + else version (FreeRTOS) + { + import urt.internal.sys.freertos; + xEventGroupSetBits(_internal, 1); + } + else version (BareMetal) + atomicStore!(MemoryOrder.release)(*cast(shared(uint)*)&_internal, 1u); + } + + void reset() + { + version (Windows) + ResetEvent(_internal); + else version (linux) + { + auto p = cast(LinuxEvent*)_internal; + pthread_mutex_lock(&p.m); + p.flag = false; + pthread_mutex_unlock(&p.m); + } + else version (FreeRTOS) + { + import urt.internal.sys.freertos; + xEventGroupClearBits(_internal, 1); + } + else version (BareMetal) + atomicStore!(MemoryOrder.release)(*cast(shared(uint)*)&_internal, 0u); + } + + void wait() + { + version (Windows) + { + import urt.internal.sys.windows.winbase : WaitForSingleObject, INFINITE; + WaitForSingleObject(_internal, INFINITE); + } + else version (linux) + { + auto p = cast(LinuxEvent*)_internal; + pthread_mutex_lock(&p.m); + while (!p.flag) + pthread_cond_wait(&p.c, &p.m); + pthread_mutex_unlock(&p.m); + } + else version (FreeRTOS) + { + import urt.internal.sys.freertos; + xEventGroupWaitBits(_internal, 1, pdFALSE, pdFALSE, portMAX_DELAY); + } + else version (BareMetal) + { + import urt.driver.irq; + while (!try_wait()) + { + static if (has_wait_for_interrupt) + irq_wait(); + } + } + } + + bool wait(Duration timeout) + { + if (timeout <= Duration.zero) + return try_wait(); + + version (Windows) + { + import urt.internal.sys.windows.winbase : WaitForSingleObject, WAIT_OBJECT_0, INFINITE; + long ms = timeout.as!"msecs"; + while (ms >= INFINITE) + { + if (WaitForSingleObject(_internal, INFINITE - 1) == WAIT_OBJECT_0) + return true; + ms -= INFINITE - 1; + } + return WaitForSingleObject(_internal, cast(uint)ms) == WAIT_OBJECT_0; + } + else version (linux) + { + auto p = cast(LinuxEvent*)_internal; + timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + long add_ns = timeout.as!"nsecs"; + ts.tv_sec += add_ns / 1_000_000_000; + ts.tv_nsec += add_ns % 1_000_000_000; + if (ts.tv_nsec >= 1_000_000_000) + { + ts.tv_sec += 1; + ts.tv_nsec -= 1_000_000_000; + } + pthread_mutex_lock(&p.m); + int rc = 0; + while (!p.flag && rc == 0) + rc = pthread_cond_timedwait(&p.c, &p.m, &ts); + bool got = p.flag; + pthread_mutex_unlock(&p.m); + return got; + } + else version (FreeRTOS) + { + import urt.internal.sys.freertos; + long ms = timeout.as!"msecs"; + while (ms >= portMAX_DELAY) + { + if ((xEventGroupWaitBits(_internal, 1, pdFALSE, pdFALSE, portMAX_DELAY - 1) & 1) != 0) + return true; + ms -= portMAX_DELAY - 1; + } + return (xEventGroupWaitBits(_internal, 1, pdFALSE, pdFALSE, cast(TickType_t)ms) & 1) != 0; + } + else version (BareMetal) + { + import urt.driver.timer; + import urt.driver.irq; + static if (has_mtime && has_wait_for_interrupt) + { + ulong deadline = mtime_read() + cast(ulong)timeout.as!"usecs"; + while (!try_wait()) + { + if (mtime_read() >= deadline) + return false; + mtimecmp_write_oneshot(deadline); + irq_wait(); + } + return true; + } + else + { + MonoTime deadline = getTime() + timeout; + while (!try_wait()) + { + if (getTime() >= deadline) + return false; + } + return true; + } + } + } + + bool try_wait() + { + version (Windows) + { + import urt.internal.sys.windows.winbase : WaitForSingleObject, WAIT_OBJECT_0; + return WaitForSingleObject(_internal, 0) == WAIT_OBJECT_0; + } + else version (linux) + { + auto p = cast(LinuxEvent*)_internal; + pthread_mutex_lock(&p.m); + bool got = p.flag; + pthread_mutex_unlock(&p.m); + return got; + } + else version (FreeRTOS) + { + import urt.internal.sys.freertos; + return (xEventGroupGetBits(_internal) & 1) != 0; + } + else version (BareMetal) + return atomicLoad!(MemoryOrder.acquire)(*cast(shared(uint)*)&_internal) != 0; + } + +private: + void* _internal; +} + + +unittest +{ + Event e; + assert(e.init()); + + assert(!e.try_wait()); + e.set(); + assert(e.try_wait()); + + // sticky -- still set after wait() + e.wait(); + assert(e.try_wait()); + + e.reset(); + assert(!e.try_wait()); + + // immediate timeout when unset + assert(!e.wait(Duration.zero)); + + // set + timed wait succeeds + e.set(); + assert(e.wait(seconds(1))); + assert(e.try_wait()); // still set + + e.destroy(); +} + + +private: + +version (Windows) +{ + extern(Windows) nothrow @nogc: + void* CreateEventA(void* lpEventAttributes, int bManualReset, int bInitialState, const(char)* lpName); + int SetEvent(void* hEvent); + int ResetEvent(void* hEvent); +} +else version (linux) +{ + extern(C) nothrow @nogc: + + // pthread_mutex_t / pthread_cond_t -- opaque, platform-sized. + // glibc . + static if (size_t.sizeof == 8) + { + struct pthread_mutex_t { align(8) ubyte[48] _; } // ceiling; arches vary 40..48 + struct pthread_cond_t { align(8) ubyte[48] _; } + } + else + { + struct pthread_mutex_t { align(4) ubyte[32] _; } + struct pthread_cond_t { align(4) ubyte[48] _; } + } + + int pthread_mutex_init(pthread_mutex_t*, const(void)*); + int pthread_mutex_destroy(pthread_mutex_t*); + int pthread_mutex_lock(pthread_mutex_t*); + int pthread_mutex_unlock(pthread_mutex_t*); + + int pthread_cond_init(pthread_cond_t*, const(void)*); + int pthread_cond_destroy(pthread_cond_t*); + int pthread_cond_wait(pthread_cond_t*, pthread_mutex_t*); + int pthread_cond_timedwait(pthread_cond_t*, pthread_mutex_t*, const(timespec)*); + int pthread_cond_broadcast(pthread_cond_t*); + + // Combined storage. Heap-allocated; pointer lives in Event._internal. + struct LinuxEvent + { + pthread_mutex_t m; + pthread_cond_t c; + bool flag; + } + + alias time_t = long; + struct timespec + { + time_t tv_sec; + long tv_nsec; + } + alias clockid_t = int; + enum CLOCK_REALTIME = 0; + int clock_gettime(clockid_t, timespec*); +} diff --git a/src/urt/sync/mpmc.d b/src/urt/sync/mpmc.d new file mode 100644 index 0000000..49f7515 --- /dev/null +++ b/src/urt/sync/mpmc.d @@ -0,0 +1,75 @@ +module urt.sync.mpmc; + +import urt.atomic; + +nothrow @nogc: + + +// Thread-safe FIFO for passing data between threads. +// Uses a CAS spinlock to protect enqueue/dequeue. +// +// NOTE: not ISR-safe. The producer spinlock can deadlock if an ISR-level +// producer is invoked while the lock is held by mainline. For ISR +// producers, use urt.sync.mpsc instead. +struct ThreadSafeQueue(uint capacity = 64, T = void*) +{ +nothrow @nogc: + + // returns false if queue is full (item not enqueued). + bool enqueue(T item) + { + while (!cas(&_lock, false, true)) {} + uint count = _tail >= _head ? _tail - _head : capacity - _head + _tail; + if (count >= capacity) + { + _lock = false; + return false; + } + _queue[_tail] = item; + _tail = (_tail + 1) % capacity; + _lock = false; + return true; + } + + static if (is(T == U*, U) || is(T == void*)) + { + // dequeue a pointer, or null if empty. + T dequeue() + { + while (!cas(&_lock, false, true)) {} + if (_head == _tail) + { + _lock = false; + return null; + } + auto result = _queue[_head]; + _head = (_head + 1) % capacity; + _lock = false; + return result; + } + } + else + { + // dequeue a value type via output parameter. + // returns false if empty. + bool dequeue(T* out_) + { + while (!cas(&_lock, false, true)) {} + if (_head == _tail) + { + _lock = false; + return false; + } + *out_ = _queue[_head]; + _head = (_head + 1) % capacity; + _lock = false; + return true; + } + } + +private: + T[capacity] _queue; + shared uint _head; + shared uint _tail; + shared bool _lock; +} diff --git a/src/urt/sync/mpsc.d b/src/urt/sync/mpsc.d new file mode 100644 index 0000000..e6e3fb7 --- /dev/null +++ b/src/urt/sync/mpsc.d @@ -0,0 +1,145 @@ +module urt.sync.mpsc; + +import urt.atomic; +import urt.util : is_power_of_2; + +nothrow @nogc: + + +// Lock-free bounded MPSC queue (Vyukov sequence-based algorithm). +// +// Many concurrent producers; ONE consumer. +// +// Producers: +// - Thread-safe AND ISR-safe. +// - Wait-free in the no-contention case; one CAS retry under contention. +// - enqueue() returns false if the queue is full. +// +// Consumer: +// - Single-threaded. Calling dequeue() from multiple threads, from an +// ISR, or alongside a thread-context call is undefined behaviour. +// +// Capacity N must be a power of two >= 2. Effective capacity == N (all +// slots usable). +// +// Must call init() before first use -- slot sequences need to be primed +// to [0, 1, ..., N-1] so the first lap of producers see "empty" slots. +struct MpscQueue(T, uint N) +{ + static assert(N >= 2 && is_power_of_2(N), "N must be a power of two >= 2"); + +nothrow @nogc: + + void init() + { + foreach (uint i, ref slot; _slots) + atomicStore!(MemoryOrder.relaxed)(slot.sequence, i); + atomicStore!(MemoryOrder.relaxed)(_tail, cast(uint)0); + _head = 0; + } + + // Try to enqueue. Returns false if full. + // Thread-safe and ISR-safe. + bool enqueue(T item) + { + uint pos = atomicLoad!(MemoryOrder.relaxed)(_tail); + for (;;) + { + Slot* slot = &_slots[pos & mask]; + uint seq = atomicLoad!(MemoryOrder.acquire)(slot.sequence); + int diff = cast(int)(seq - pos); + if (diff == 0) + { + // Slot is available at this lap; try to claim our position. + if (cas(&_tail, pos, pos + 1)) + { + slot.data = item; + atomicStore!(MemoryOrder.release)(slot.sequence, pos + 1); + return true; + } + // Lost the race; reload and retry. + pos = atomicLoad!(MemoryOrder.relaxed)(_tail); + } + else if (diff < 0) + { + // Slot is still occupied from a previous lap -- full. + return false; + } + else + { + // Tail moved ahead between our load and the slot check; reload. + pos = atomicLoad!(MemoryOrder.relaxed)(_tail); + } + } + } + + // Try to dequeue. Returns false if empty. + // Single-consumer ONLY. + bool dequeue(out T item) + { + Slot* slot = &_slots[_head & mask]; + uint seq = atomicLoad!(MemoryOrder.acquire)(slot.sequence); + if (cast(int)(seq - (_head + 1)) < 0) + return false; + item = slot.data; + // Mark this slot ready for the next lap (head + N positions away). + atomicStore!(MemoryOrder.release)(slot.sequence, _head + N); + ++_head; + return true; + } + + // Approximate emptiness check. Safe from the consumer thread only. + // A `false` return is authoritative ("not empty right now"); a `true` + // return may race against a producer that's mid-enqueue. + bool empty() const + { + const(Slot)* slot = &_slots[_head & mask]; + uint seq = atomicLoad!(MemoryOrder.acquire)(slot.sequence); + return cast(int)(seq - (_head + 1)) < 0; + } + +private: + enum uint mask = N - 1; + + struct Slot + { + T data; + shared uint sequence; + } + + Slot[N] _slots; + shared uint _tail; // producer claim cursor + uint _head; // consumer read cursor (single consumer; non-atomic) +} + + +unittest +{ + MpscQueue!(int, 4) q; + q.init(); + + int v; + assert(q.empty); + assert(!q.dequeue(v)); + + // fill capacity + assert(q.enqueue(10)); + assert(q.enqueue(20)); + assert(q.enqueue(30)); + assert(q.enqueue(40)); + assert(!q.enqueue(50)); // full + + assert(q.dequeue(v) && v == 10); + assert(q.dequeue(v) && v == 20); + assert(q.dequeue(v) && v == 30); + assert(q.dequeue(v) && v == 40); + assert(q.empty); + assert(!q.dequeue(v)); + + // wrap-around + assert(q.enqueue(100)); + assert(q.enqueue(200)); + assert(q.dequeue(v) && v == 100); + assert(q.dequeue(v) && v == 200); + assert(q.empty); +} diff --git a/src/urt/sync/mutex.d b/src/urt/sync/mutex.d new file mode 100644 index 0000000..c732515 --- /dev/null +++ b/src/urt/sync/mutex.d @@ -0,0 +1,232 @@ +module urt.sync.mutex; + +import urt.atomic; + + +// Blocking ownership lock. Excludes other threads/tasks from a critical +// section. Has an owner; non-recursive (locking from the holding thread +// is undefined behaviour). +// +// Do NOT use: +// - Between an ISR and same-core mainline - use IrqGuard +// (urt.driver.irq) for that case. +// - For sections that may yield (cooperative-fibre code). A held Mutex +// must be released before yielding; otherwise behaviour is target- +// dependent (block-forever on desktop, race-or-spin on bare-metal). + +struct Mutex +{ +nothrow @nogc: + @disable this(this); + + bool init() + { + version (Windows) + { + InitializeSRWLock(cast(SRWLOCK*)&_internal); + return true; + } + else version (Posix) + { + import urt.mem.allocator; + auto p = cast(pthread_mutex_t*)defaultAllocator().alloc(pthread_mutex_t.sizeof, pthread_mutex_t.alignof); + if (!p) + return false; + if (pthread_mutex_init(p, null) != 0) + { + defaultAllocator().free(p[0..1]); + return false; + } + _internal = p; + return true; + } + else version (FreeRTOS) + { + import urt.internal.sys.freertos; + _internal = xQueueCreateMutex(queueQUEUE_TYPE_MUTEX); + return _internal !is null; + } + else version (BareMetal) + { + atomicStore(*cast(shared(size_t)*)&_internal, cast(size_t)0); + return true; + } + else + static assert(false, "Mutex not implemented for this platform"); + } + + void destroy() + { + version (Windows) + { + // SRWLOCK has no destroy + } + else version (Posix) + { + import urt.mem.allocator; + if (_internal) + { + pthread_mutex_destroy(cast(pthread_mutex_t*)_internal); + defaultAllocator().free(_internal[0..1]); + _internal = null; + } + } + else version (FreeRTOS) + { + import urt.internal.sys.freertos; + if (_internal) + { + vQueueDelete(_internal); + _internal = null; + } + } + else version (BareMetal) + { + // nothing to free + } + } + + void lock() + { + version (Windows) + AcquireSRWLockExclusive(cast(SRWLOCK*)&_internal); + else version (Posix) + pthread_mutex_lock(cast(pthread_mutex_t*)_internal); + else version (FreeRTOS) + { + import urt.internal.sys.freertos; + xQueueSemaphoreTake(_internal, portMAX_DELAY); + } + else version (BareMetal) + { + while (!cas(cast(shared(size_t)*)&_internal, cast(size_t)0, cast(size_t)1)) + pause(); + } + } + + bool try_lock() + { + version (Windows) + return TryAcquireSRWLockExclusive(cast(SRWLOCK*)&_internal) != 0; + else version (Posix) + return pthread_mutex_trylock(cast(pthread_mutex_t*)_internal) == 0; + else version (FreeRTOS) + { + import urt.internal.sys.freertos; + return xQueueSemaphoreTake(_internal, 0) != 0; + } + else version (BareMetal) + return cas(cast(shared(size_t)*)&_internal, cast(size_t)0, cast(size_t)1); + } + + void unlock() + { + version (Windows) + ReleaseSRWLockExclusive(cast(SRWLOCK*)&_internal); + else version (Posix) + pthread_mutex_unlock(cast(pthread_mutex_t*)_internal); + else version (FreeRTOS) + { + import urt.internal.sys.freertos; + xQueueGenericSend(_internal, null, semGIVE_BLOCK_TIME, queueSEND_TO_BACK); + } + else version (BareMetal) + atomicStore!(MemoryOrder.release)(*cast(shared(size_t)*)&_internal, cast(size_t)0); + } + + MutexGuard acquire() return + { + lock(); + return MutexGuard(&this); + } + +private: + void* _internal; +} + + +struct MutexGuard +{ +nothrow @nogc: + @disable this(); + @disable this(this); + + ~this() + { + assert (_mutex); + _mutex.unlock(); + } + +private: + Mutex* _mutex; + + this(Mutex* mutex) + { + _mutex = mutex; + } +} + + +unittest +{ + Mutex m; + assert(m.init()); + + assert(m.try_lock()); + assert(!m.try_lock()); + m.unlock(); + + m.lock(); + assert(!m.try_lock()); + m.unlock(); + assert(m.try_lock()); + m.unlock(); + + m.destroy(); +} + + +private: + +version (Windows) +{ + extern(Windows) nothrow @nogc: + + // SRWLOCK is a single pointer-sized opaque value; zero-init is valid. + struct SRWLOCK { void* Ptr; } + + void InitializeSRWLock(SRWLOCK*); + void AcquireSRWLockExclusive(SRWLOCK*); + ubyte TryAcquireSRWLockExclusive(SRWLOCK*); // returns BOOLEAN + void ReleaseSRWLockExclusive(SRWLOCK*); +} +else version (Posix) +{ + extern(C) nothrow @nogc: + + // pthread_mutex_t -- opaque, platform-sized. + // Sizes from glibc / Darwin . + // Conservative ceilings used where 32-bit/64-bit variants differ between archs. + version (linux) + { + static if (size_t.sizeof == 8) + struct pthread_mutex_t { align(8) ubyte[48] _; } // x86_64=40, aarch64=48, riscv64=40 + else + struct pthread_mutex_t { align(4) ubyte[32] _; } // x86=24, arm=24, riscv32=32 + } + else version (Darwin) + { + static if (size_t.sizeof == 8) + struct pthread_mutex_t { align(8) ubyte[64] _; } // _PTHREAD_MUTEX_SIZE__ + sig + else + struct pthread_mutex_t { align(4) ubyte[44] _; } + } + else + static assert(false, "pthread_mutex_t size not configured for this POSIX target"); + + int pthread_mutex_init(pthread_mutex_t*, const(void)*); + int pthread_mutex_destroy(pthread_mutex_t*); + int pthread_mutex_lock(pthread_mutex_t*); + int pthread_mutex_trylock(pthread_mutex_t*); + int pthread_mutex_unlock(pthread_mutex_t*); +} diff --git a/src/urt/sync/semaphore.d b/src/urt/sync/semaphore.d new file mode 100644 index 0000000..79c5f83 --- /dev/null +++ b/src/urt/sync/semaphore.d @@ -0,0 +1,307 @@ +module urt.sync.semaphore; + +import urt.atomic; +import urt.time; + + +// Counted signalling primitive. +// +// signal() is ISR-safe on bare-metal (single atomic add). On FreeRTOS, +// signal() is task-context only -- ISR producers need a separate ISR +// variant that calls xQueueGiveFromISR + portYIELD_FROM_ISR (TODO; will +// be added alongside the wake module that actually has ISR producers). +struct Semaphore +{ +nothrow @nogc: + @disable this(this); + + bool init(uint initial = 0) + { + version (Windows) + { + import urt.internal.sys.windows.winbase : CreateSemaphoreA; + _internal = CreateSemaphoreA(null, initial, int.max, null); + return _internal !is null; + } + else version (linux) + { + import urt.mem.allocator; + auto p = cast(sem_t*)defaultAllocator().alloc(sem_t.sizeof, sem_t.alignof); + if (!p) + return false; + if (sem_init(p, 0, initial) != 0) + { + defaultAllocator().free(p[0..1]); + return false; + } + _internal = p; + return true; + } + else version (Darwin) + static assert(false, "Semaphore on Darwin requires dispatch_semaphore_t -- TODO"); + else version (FreeRTOS) + { + import urt.internal.sys.freertos; + _internal = xQueueCreateCountingSemaphore(uint.max, initial); + return _internal !is null; + } + else version (BareMetal) + { + atomicStore(*cast(shared(size_t)*)&_internal, cast(size_t)initial); + return true; + } + else + static assert(false, "Semaphore not implemented for this platform"); + } + + void destroy() + { + version (Windows) + { + import urt.internal.sys.windows.winbase : CloseHandle; + if (_internal) + { + CloseHandle(_internal); + _internal = null; + } + } + else version (linux) + { + import urt.mem.allocator; + if (_internal) + { + sem_destroy(cast(sem_t*)_internal); + defaultAllocator().free(_internal[0..1]); + _internal = null; + } + } + else version (FreeRTOS) + { + import urt.internal.sys.freertos; + if (_internal) + { + vQueueDelete(_internal); + _internal = null; + } + } + else version (BareMetal) + { + // counter lives in _internal; nothing to free + } + } + + void signal() + { + version (Windows) + { + import urt.internal.sys.windows.winbase : ReleaseSemaphore; + ReleaseSemaphore(_internal, 1, null); + } + else version (linux) + sem_post(cast(sem_t*)_internal); + else version (FreeRTOS) + { + import urt.internal.sys.freertos; + xQueueGenericSend(_internal, null, semGIVE_BLOCK_TIME, queueSEND_TO_BACK); + } + else version (BareMetal) + atomicFetchAdd(*cast(shared(size_t)*)&_internal, cast(size_t)1); + } + + void wait() + { + version (Windows) + { + import urt.internal.sys.windows.winbase : WaitForSingleObject, INFINITE; + WaitForSingleObject(_internal, INFINITE); + } + else version (linux) + sem_wait(cast(sem_t*)_internal); + else version (FreeRTOS) + { + import urt.internal.sys.freertos; + xQueueSemaphoreTake(_internal, portMAX_DELAY); + } + else version (BareMetal) + { + import urt.driver.irq; + while (!try_wait()) + { + static if (has_wait_for_interrupt) + irq_wait(); + } + } + } + + bool wait(Duration timeout) + { + if (timeout <= Duration.zero) + return try_wait(); + + version (Windows) + { + import urt.internal.sys.windows.winbase : WaitForSingleObject, WAIT_OBJECT_0, INFINITE; + // INFINITE itself means "wait forever", so the largest finite + // wait is INFINITE - 1 ms (~49 days). Chunk if longer. + long ms = timeout.as!"msecs"; + while (ms >= INFINITE) + { + if (WaitForSingleObject(_internal, INFINITE - 1) == WAIT_OBJECT_0) + return true; + ms -= INFINITE - 1; + } + return WaitForSingleObject(_internal, cast(uint)ms) == WAIT_OBJECT_0; + } + else version (linux) + { + timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + long add_ns = timeout.as!"nsecs"; + ts.tv_sec += add_ns / 1_000_000_000; + ts.tv_nsec += add_ns % 1_000_000_000; + if (ts.tv_nsec >= 1_000_000_000) + { + ts.tv_sec += 1; + ts.tv_nsec -= 1_000_000_000; + } + return sem_timedwait(cast(sem_t*)_internal, &ts) == 0; + } + else version (FreeRTOS) + { + import urt.internal.sys.freertos; + // Assumes configTICK_RATE_HZ = 1000 (1ms tick); revisit if a + // target uses a different tick rate. + // portMAX_DELAY itself means "wait forever", so the largest + // finite wait is portMAX_DELAY - 1 ticks. Chunk if longer. + long ms = timeout.as!"msecs"; + while (ms >= portMAX_DELAY) + { + if (xQueueSemaphoreTake(_internal, portMAX_DELAY - 1) != 0) + return true; + ms -= portMAX_DELAY - 1; + } + return xQueueSemaphoreTake(_internal, cast(uint)ms) != 0; + } + else version (BareMetal) + { + import urt.driver.timer; + import urt.driver.irq; + static if (has_mtime && has_wait_for_interrupt) + { + ulong deadline = mtime_read() + cast(ulong)timeout.as!"usecs"; + while (!try_wait()) + { + if (mtime_read() >= deadline) + return false; + mtimecmp_write_oneshot(deadline); + irq_wait(); + } + return true; + } + else + { + // No timer + WFI? Busy-poll until deadline. Not ideal. + MonoTime deadline = getTime() + timeout; + while (!try_wait()) + { + if (getTime() >= deadline) + return false; + } + return true; + } + } + } + + bool try_wait() + { + version (Windows) + { + import urt.internal.sys.windows.winbase : WaitForSingleObject, WAIT_OBJECT_0; + return WaitForSingleObject(_internal, 0) == WAIT_OBJECT_0; + } + else version (linux) + return sem_trywait(cast(sem_t*)_internal) == 0; + else version (FreeRTOS) + { + import urt.internal.sys.freertos; + return xQueueSemaphoreTake(_internal, 0) != 0; + } + else version (BareMetal) + { + auto p = cast(shared(size_t)*)&_internal; + size_t cur = atomicLoad(*p); + for (;;) + { + if (cur == 0) + return false; + if (cas(p, cur, cur - 1)) + return true; + cur = atomicLoad(*p); + } + } + } + +private: + void* _internal; +} + + +unittest +{ + Semaphore s; + assert(s.init(0)); + + assert(!s.try_wait()); + s.signal(); + assert(s.try_wait()); + assert(!s.try_wait()); + + s.signal(); + s.wait(); + assert(!s.try_wait()); + + // immediate timeout + assert(!s.wait(Duration.zero)); + + // signal then timed wait -- should succeed immediately + s.signal(); + assert(s.wait(seconds(1))); + + s.destroy(); +} + + +private: + +version (linux) +{ + extern(C) nothrow @nogc: + + // sem_t -- opaque, platform-sized. + // glibc : __SIZEOF_SEM_T = 32 on x86_64/aarch64/riscv64, + // 16 on x86/arm/riscv32. + static if (size_t.sizeof == 8) + struct sem_t { align(8) ubyte[32] _; } + else + struct sem_t { align(4) ubyte[16] _; } + + int sem_init(sem_t*, int pshared, uint value); + int sem_destroy(sem_t*); + int sem_post(sem_t*); + int sem_wait(sem_t*); + int sem_trywait(sem_t*); + int sem_timedwait(sem_t*, const(timespec)*); + + // timespec + clock_gettime live in ; duplicated here so this + // module is self-contained. Promote to internal/sys/posix on second use. + alias time_t = long; + struct timespec + { + time_t tv_sec; + long tv_nsec; + } + + alias clockid_t = int; + enum CLOCK_REALTIME = 0; + int clock_gettime(clockid_t, timespec*); +} diff --git a/src/urt/sync/spinlock.d b/src/urt/sync/spinlock.d new file mode 100644 index 0000000..855a5bd --- /dev/null +++ b/src/urt/sync/spinlock.d @@ -0,0 +1,90 @@ +module urt.sync.spinlock; + +import urt.atomic; + +nothrow @nogc: + + +// Mutual-exclusion via busy-wait CAS. +// +// Use when: +// - The contended section is very short (a handful of instructions). +// - The contender is another core, or another thread/task that can +// make forward progress independently. +// +// Do NOT use: +// - Between an ISR and same-core mainline -- spinning waiting for an +// ISR-held lock deadlocks; spinning waiting for mainline from an +// ISR deadlocks too. Use IrqGuard (urt.driver.irq) for that case. +// - For long sections -- spinning is pure waste. Use Mutex. +// - On single-core single-threaded targets -- nothing to contend with; +// compiles to a real spinlock anyway since we don't have a reliable +// compile-time "single core" flag yet, but you shouldn't reach for it. +struct Spinlock +{ +nothrow @nogc: + + void lock() + { + while (!try_lock()) + pause(); + } + + bool try_lock() + => cas(&_state, false, true); + + void unlock() + { + atomicStore!(MemoryOrder.release)(_state, false); + } + + SpinlockGuard acquire() return + { + lock(); + return SpinlockGuard(&this); + } + +private: + shared bool _state; +} + + +// RAII guard. Releases the held Spinlock on scope exit. +struct SpinlockGuard +{ +nothrow @nogc: + @disable this(); + @disable this(this); + + ~this() + { + if (_lock) + _lock.unlock(); + } + +private: + Spinlock* _lock; + + this(Spinlock* lock) + { + _lock = lock; + } +} + + +unittest +{ + Spinlock sl; + + assert(sl.try_lock()); + assert(!sl.try_lock()); + sl.unlock(); + assert(sl.try_lock()); + sl.unlock(); + + sl.lock(); + assert(!sl.try_lock()); + sl.unlock(); + assert(sl.try_lock()); + sl.unlock(); +} diff --git a/src/urt/sync/spsc.d b/src/urt/sync/spsc.d new file mode 100644 index 0000000..f2e100a --- /dev/null +++ b/src/urt/sync/spsc.d @@ -0,0 +1,158 @@ +module urt.sync.spsc; + +import urt.atomic; +import urt.util : is_power_of_2; + +nothrow @nogc: + + +// Lock-free single-producer single-consumer ring buffer. +// +// Producer side is staged: reserve() advances an internal uncommitted tail, +// but writes stay invisible to the consumer until commit(). +// +// Consumer side is symmetrical: peek() returns pointers/slices into the +// committed region without advancing, pop(n) discards the oldest n slots +// and invalidates any outstanding peek() pointers. +struct SPSCRing(T, uint N) +{ +nothrow @nogc: + static assert(N >= 2 && is_power_of_2(N), "N must be a power of two >= 2"); + + size_t pending() const + { + uint h = atomicLoad!(MemoryOrder.relaxed)(_head); + uint t = atomicLoad!(MemoryOrder.acquire)(_tail); + return (t - h) & (N - 1); + } + + bool empty() const + { + uint h = atomicLoad!(MemoryOrder.relaxed)(_head); + uint t = atomicLoad!(MemoryOrder.acquire)(_tail); + return h == t; + } + + size_t free_space() const + { + uint h = atomicLoad!(MemoryOrder.acquire)(_head); + return (N - 1) - ((_pending_tail - h) & (N - 1)); + } + + // reserve up to `count` T's and return a contiguous writable slice + // into the ring. may be shorter than count if ring boundary is hit + // or if there isn't enough free space. + T[] reserve(size_t count) + { + if (count == 0) + return null; + uint pt = _pending_tail; + uint h = atomicLoad!(MemoryOrder.acquire)(_head); + size_t free = (N - 1) - ((pt - h) & (N - 1)); + size_t n = count < free ? count : free; + size_t to_end = N - pt; + if (n > to_end) + n = to_end; + if (n == 0) + return null; + T[] r = _buf[pt .. pt + n]; + _pending_tail = cast(uint)((pt + n) & (N - 1)); + return r; + } + + T* reserve() + => reserve(1).ptr; + + void commit() + { + atomicStore!(MemoryOrder.release)(_tail, _pending_tail); + } + + void rollback() + { + _pending_tail = atomicLoad!(MemoryOrder.relaxed)(_tail); + } + + size_t push(const(T)[] src, bool allow_partial = false) + { + if (src.length == 0) + return 0; + uint pt = _pending_tail; + uint h = atomicLoad!(MemoryOrder.acquire)(_head); + size_t free = (N - 1) - ((pt - h) & (N - 1)); + if (!allow_partial && src.length > free) + return 0; + size_t n = src.length < free ? src.length : free; + if (n == 0) + return 0; + size_t to_end = N - pt; + if (n <= to_end) + _buf[pt .. pt + n] = src[0 .. n]; + else + { + _buf[pt .. N] = src[0 .. to_end]; + _buf[0 .. n - to_end] = src[to_end .. n]; + } + _pending_tail = cast(uint)((pt + n) & (N - 1)); + atomicStore!(MemoryOrder.release)(_tail, _pending_tail); + return n; + } + + // peek up to `count` contiguous committed slots starting at the oldest. + // may be shorter than count when wrapping the ring boundary. + // the returned slice is invalidated by the next pop(). + T[] peek(size_t count) + { + if (count == 0) + return null; + uint h = atomicLoad!(MemoryOrder.relaxed)(_head); + uint t = atomicLoad!(MemoryOrder.acquire)(_tail); + size_t filled = (t - h) & (N - 1); + size_t n = count < filled ? count : filled; + size_t to_end = N - h; + if (n > to_end) + n = to_end; + if (n == 0) + return null; + return _buf[h .. h + n]; + } + + T* peek() + => peek(1).ptr; + + // discard the oldest `count` committed slots. + // invalidates pointers returned by prior peeks + void pop(size_t count) + { + uint h = atomicLoad!(MemoryOrder.relaxed)(_head); + atomicStore!(MemoryOrder.release)(_head, cast(uint)((h + count) & (N - 1))); + } + + size_t pop(T[] dst) + { + if (dst.length == 0) + return 0; + uint h = atomicLoad!(MemoryOrder.relaxed)(_head); + uint t = atomicLoad!(MemoryOrder.acquire)(_tail); + size_t filled = (t - h) & (N - 1); + size_t n = dst.length < filled ? dst.length : filled; + if (n == 0) + return 0; + size_t to_end = N - h; + if (n <= to_end) + dst[0 .. n] = _buf[h .. h + n]; + else + { + dst[0 .. to_end] = _buf[h .. N]; + dst[to_end .. n] = _buf[0 .. n - to_end]; + } + atomicStore!(MemoryOrder.release)(_head, cast(uint)((h + n) & (N - 1))); + return n; + } + +private: + T[N] _buf; + shared uint _head; + shared uint _tail; + uint _pending_tail; // producer-only; staging cursor for uncommitted writes +} diff --git a/src/urt/system.d b/src/urt/system.d index 84f97a1..a4ffec6 100644 --- a/src/urt/system.d +++ b/src/urt/system.d @@ -4,13 +4,26 @@ import urt.platform; import urt.processor; import urt.time; +version (Espressif) +{ + enum uint MALLOC_CAP_SPIRAM = 1 << 10; + enum uint MALLOC_CAP_INTERNAL = 1 << 11; + extern(C) nothrow @nogc + { + size_t heap_caps_get_total_size(uint caps); + size_t heap_caps_get_free_size(uint caps); + size_t heap_caps_get_minimum_free_size(uint caps); + size_t heap_caps_get_largest_free_block(uint caps); + } +} + nothrow @nogc: enum IdleParams : ubyte { - SystemRequired = 1, // stop the system from going to sleep - DisplayRequired = 2, // keep the display turned on + system_required = 1, // stop the system from going to sleep + display_required = 2, // keep the display turned on } extern(C) noreturn abort(); @@ -26,39 +39,75 @@ void sleep(Duration duration) version (Windows) { - import core.sys.windows.winbase : Sleep; + import urt.internal.sys.windows.winbase : Sleep; Sleep(cast(uint)duration.as!"msecs"); } - else + else version (Embedded) { - // TODO: use nanosleep; usleep is deprecated! + import urt.driver.timer; + import urt.driver.irq; + static if (has_mtime) + { + ulong deadline = mtime_read() + duration.as!"usecs"; + static if (has_oneshot_timer && has_wait_for_interrupt) + { + mtimecmp_write_oneshot(deadline); + auto was_enabled = enable_irq(IrqClass.timer); + while (mtime_read() < deadline) + wait_for_interrupt(); + if (!was_enabled) + disable_irq(IrqClass.timer); + } + else + { + while (mtime_read() < deadline) {} + } + } + } + else + { usleep(cast(uint)duration.as!"usecs"); } } +struct MemoryPool +{ + string name; // short label ("RAM", "TCM", "SRAM", "PSRAM", ...) + ulong total; // capacity in bytes (0 means slot unused) + ulong used; // currently allocated + ulong peak_used; // high-water mark of used (0 if unavailable) + ulong largest_free; // largest contiguous allocatable block (0 if unknown) +} + +enum MaxMemoryPools = 4; + struct SystemInfo { - string osName; + string os_name; string processor; - ulong totalMemory; - ulong availableMemory; + MemoryPool[MaxMemoryPools] pools; // unused slots have total == 0 Duration uptime; } -SystemInfo getSysInfo() +SystemInfo get_sysinfo() { SystemInfo r; - r.osName = Platform; - r.processor = ProcessorFamily; + r.os_name = Platform; + r.processor = ProcessorName; version (Windows) { + r.pools[0].name = "RAM"; MEMORYSTATUSEX mem; mem.dwLength = MEMORYSTATUSEX.sizeof; if (GlobalMemoryStatusEx(&mem)) + r.pools[0].total = mem.ullTotalPhys; + PROCESS_MEMORY_COUNTERS pmc; + pmc.cb = PROCESS_MEMORY_COUNTERS.sizeof; + if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, pmc.sizeof)) { - r.totalMemory = mem.ullTotalPhys; - r.availableMemory = mem.ullAvailPhys; + r.pools[0].used = pmc.WorkingSetSize; // process resident + r.pools[0].peak_used = pmc.PeakWorkingSetSize; // peak resident } r.uptime = msecs(GetTickCount64()); } @@ -70,61 +119,273 @@ SystemInfo getSysInfo() if (sysinfo(&info) < 0) assert(false, "sysinfo() failed!"); - r.totalMemory = cast(ulong)info.totalram * info.mem_unit; - r.availableMemory = cast(ulong)info.freeram * info.mem_unit; + r.pools[0].name = "RAM"; + r.pools[0].total = info.totalram * cast(ulong)info.mem_unit; + + // mallinfo2 gives heap-precise bytes-in-use; VmHWM is peak resident + // (process-level, includes code/libs/stack but glibc has no peak-heap + // counter so it's the tightest available proxy). + Mallinfo2 mi = mallinfo2(); + r.pools[0].used = mi.uordblks + mi.hblkhd; + r.pools[0].peak_used = read_proc_self_field("VmHWM:"); + r.uptime = seconds(info.uptime); } else version (Posix) { - import core.sys.posix.unistd; + import urt.internal.sys.posix; int pages = sysconf(_SC_PHYS_PAGES); + int avail = sysconf(_SC_AVPHYS_PAGES); int page_size = sysconf(_SC_PAGE_SIZE); assert(pages >= 0 && page_size >= 0, "sysconf() failed!"); - r.totalMemory = cast(ulong)pages * page_size; - static assert(false, "TODO: need `availableMemory`"); + r.pools[0].name = "RAM"; + r.pools[0].total = cast(ulong)pages * page_size; + if (avail >= 0) + r.pools[0].used = r.pools[0].total - cast(ulong)avail * page_size; + } + else version (Espressif) + { + r.pools[0].name = "SRAM"; + r.pools[0].total = heap_caps_get_total_size(MALLOC_CAP_INTERNAL); + if (r.pools[0].total > 0) + { + r.pools[0].used = r.pools[0].total - heap_caps_get_free_size(MALLOC_CAP_INTERNAL); + r.pools[0].peak_used = r.pools[0].total - heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL); + r.pools[0].largest_free = heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL); + } + + r.pools[1].name = "PSRAM"; + r.pools[1].total = heap_caps_get_total_size(MALLOC_CAP_SPIRAM); + if (r.pools[1].total > 0) + { + r.pools[1].used = r.pools[1].total - heap_caps_get_free_size(MALLOC_CAP_SPIRAM); + r.pools[1].peak_used = r.pools[1].total - heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM); + r.pools[1].largest_free = heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM); + } + + r.uptime = getAppTime(); + } + else version (Bouffalo) + { + import urt.driver.bl_common.alloc : num_pools, query_pool_stats, PoolStats; + import urt.string : c_string; + + foreach (i; 0 .. num_pools) + { + PoolStats s; + query_pool_stats(i, s); + r.pools[i].name = s.name.c_string; + r.pools[i].total = s.total; + r.pools[i].used = s.used; + r.pools[i].peak_used = s.peak_used; + r.pools[i].largest_free = s.largest_free; + } + r.uptime = getAppTime(); } return r; } -void setSystemIdleParams(IdleParams params) +void set_system_idle_params(IdleParams params) { version (Windows) { - import core.sys.windows.winbase; + import urt.internal.sys.windows.winbase; enum EXECUTION_STATE ES_SYSTEM_REQUIRED = 0x00000001; enum EXECUTION_STATE ES_DISPLAY_REQUIRED = 0x00000002; enum EXECUTION_STATE ES_CONTINUOUS = 0x80000000; - SetThreadExecutionState(ES_CONTINUOUS | (params.SystemRequired ? ES_SYSTEM_REQUIRED : 0) | (params.DisplayRequired ? ES_DISPLAY_REQUIRED : 0)); + SetThreadExecutionState(ES_CONTINUOUS | ((params & IdleParams.system_required) ? ES_SYSTEM_REQUIRED : 0) | ((params & IdleParams.display_required) ? ES_DISPLAY_REQUIRED : 0)); } else version (Posix) { // TODO: ...we're not likely to run on a POSIX desktop system any time soon... } + else version (FreeStanding) + { + // Bare-metal: no idle state management needed + } else static assert(0, "Not implemented"); } +void count_system_load(MonoTime reference) +{ + MonoTime now = getTime(); + + size_t a = cast(size_t)(reference - MonoTime()).as!"nsecs"; + size_t b = cast(size_t)(now - MonoTime()).as!"nsecs"; + + import urt.util : log2; + enum shift = log2(cpu_bucket_len); + size_t full_intervals = (b >> shift) - (a >> shift); + + if (full_intervals == 0) + g_cpu_time[g_bucket] += b - a; + else + { + enum mask = cpu_counter_buckets - 1; + enum cpu_bucket_mask = cpu_bucket_len - 1; + + if (full_intervals > cpu_counter_buckets) + full_intervals = cpu_counter_buckets; + + g_cpu_time[g_bucket++] += cpu_bucket_len - (a & cpu_bucket_mask); + for (uint i = 1; i < full_intervals; i++) + g_cpu_time[g_bucket++ & mask] = cpu_bucket_len; + g_bucket = g_bucket & mask; + g_cpu_time[g_bucket] = b & cpu_bucket_mask; + } +} + +uint get_cpu_load() +{ + uint idle_time = 0; + for (uint i = 0; i < cpu_counter_buckets; i++) + if (i != g_bucket) + idle_time += g_cpu_time[i]; + enum total_time = cpu_bucket_len*(cpu_counter_buckets - 1); + uint cpu_time = total_time - idle_time; + return cast(uint)(cpu_time*100 / total_time); +} unittest { - SystemInfo info = getSysInfo(); + SystemInfo info = get_sysinfo(); assert(info.uptime > Duration.zero); import urt.io; - writelnf("System info: {0} - {1}, mem: {2}kb ({3}kb)", info.osName, info.processor, info.totalMemory / (1024), info.availableMemory / (1024)); + writelnf("\nSystem: {0} - {1}", info.os_name, info.processor); + foreach (ref p; info.pools) + { + if (p.total == 0) + continue; + writelnf(" {0}: {1}kb used / {2}kb total (peak {3}kb)", + p.name, p.used / 1024, p.total / 1024, p.peak_used / 1024); + } } package: +import urt.attribute : fast_data; + +enum uint cpu_bucket_len = 0x400_0000; // nanosecond buckets of ~67ms +enum cpu_counter_buckets = 16; + +__gshared @fast_data uint[16] g_cpu_time; +__gshared @fast_data ubyte g_bucket = 0; + +version (Bouffalo) +{ + extern(C) extern __gshared { + void* __heap_start; + void* __heap_end; + } + + struct Mallinfo + { + size_t arena; // total space from sbrk + size_t ordblks; // number of free chunks + size_t smblks; // unused + size_t hblks; // unused + size_t hblkhd; // unused + size_t uordblks; // total allocated space + size_t fordblks; // total free space + size_t keepcost; // releasable space + size_t aordblks; // number of allocated chunks + size_t max_total_mem; // max total allocated space + } + extern(C) Mallinfo mallinfo() @nogc nothrow; + + extern(C) void* _sbrk(int incr) @nogc nothrow; + + size_t heap_len() + => cast(size_t)&__heap_end - cast(size_t)&__heap_start; +} + +version (linux) +{ + struct Mallinfo2 + { + size_t arena; // non-mmapped space allocated from system + size_t ordblks; // number of free chunks + size_t smblks; // number of free fastbin blocks + size_t hblks; // number of mmapped regions + size_t hblkhd; // space allocated in mmapped regions + size_t usmblks; // unused (historical) + size_t fsmblks; // space in freed fastbin blocks + size_t uordblks; // total allocated (in-use) space + size_t fordblks; // total free space + size_t keepcost; // top-most releasable space + } + extern(C) Mallinfo2 mallinfo2() nothrow @nogc; + + // Read a field from /proc/self/status, returns value in bytes (field is in kB) + ulong read_proc_self_field(string field) nothrow @nogc + { + import urt.file : File, open, read, close, FileOpenMode; + + File f; + if (!f.open("/proc/self/status", FileOpenMode.ReadExisting)) + return 0; + + char[4096] buf = void; + size_t n; + auto r = f.read(buf, n); + f.close(); + if (!r || n == 0) + return 0; + + auto content = buf[0 .. n]; + // Find field name in content + for (size_t i = 0; i + field.length < content.length; ++i) + { + if (content[i .. i + field.length] == field) + { + // Skip whitespace after field name + size_t j = i + field.length; + while (j < content.length && (content[j] == ' ' || content[j] == '\t')) + ++j; + // Parse number + ulong val = 0; + while (j < content.length && content[j] >= '0' && content[j] <= '9') + { + val = val * 10 + (content[j] - '0'); + ++j; + } + // /proc/self/status reports in kB + return val * 1024; + } + } + return 0; + } +} + version (Windows) { - import core.sys.windows.winbase : GlobalMemoryStatusEx, MEMORYSTATUSEX; + import urt.internal.sys.windows.winbase : GlobalMemoryStatusEx, GetCurrentProcess, MEMORYSTATUSEX; + + struct PROCESS_MEMORY_COUNTERS + { + uint cb; + uint PageFaultCount; + size_t PeakWorkingSetSize; + size_t WorkingSetSize; + size_t QuotaPeakPagedPoolUsage; + size_t QuotaPagedPoolUsage; + size_t QuotaPeakNonPagedPoolUsage; + size_t QuotaNonPagedPoolUsage; + size_t PagefileUsage; + size_t PeakPagefileUsage; + } + + extern(Windows) int GetProcessMemoryInfo(void* Process, PROCESS_MEMORY_COUNTERS* ppsmemCounters, uint cb) nothrow @nogc; + + pragma(lib, "psapi"); extern(Windows) ulong GetTickCount64(); diff --git a/src/urt/thread.d b/src/urt/thread.d new file mode 100644 index 0000000..7152fbf --- /dev/null +++ b/src/urt/thread.d @@ -0,0 +1,186 @@ +module urt.thread; + +import urt.mem.allocator : defaultAllocator; + +nothrow @nogc: + + +version (Windows) enum ThreadsSupported = true; +else version (Posix) enum ThreadsSupported = true; +else version (FreeRTOS) enum ThreadsSupported = true; +else enum ThreadsSupported = false; + + +alias Thread = void*; +alias ThreadEntry = void delegate() nothrow @nogc; + + +// Spawn an OS thread. Returns null on failure. +// stack_size = 0: platform default (Windows: 1MB; POSIX: ~8MB; FreeRTOS: 4096 bytes). +Thread thread_spawn(ThreadEntry entry, size_t stack_size = 0) +{ + auto entry_ptr = defaultAllocator().allocT!ThreadEntry(); + if (!entry_ptr) + return null; + *entry_ptr = entry; + + Thread handle; + version (Windows) + { + import urt.internal.sys.windows.winbase : CreateThread; + handle = CreateThread(null, stack_size, &_win_entry, entry_ptr, 0, null); + } + else version (Posix) + { + pthread_t tid; + int err; + if (stack_size == 0) + { + err = pthread_create(&tid, null, &_posix_entry, entry_ptr); + } + else + { + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setstacksize(&attr, stack_size); + err = pthread_create(&tid, &attr, &_posix_entry, entry_ptr); + pthread_attr_destroy(&attr); + } + handle = (err == 0) ? cast(Thread)tid : null; + } + else version (FreeRTOS) + { + import urt.internal.sys.freertos; + UBaseType_t prio = uxTaskPriorityGet(null); // inherit current task's priority + uint stack = stack_size ? cast(uint)stack_size : 4096; + TaskHandle_t h; + if (xTaskCreate(&_freertos_entry, null, stack, entry_ptr, prio, &h) != pdPASS) + h = null; + handle = h; + } + else + assert(false, "thread_spawn not supported on this target"); + + if (!handle) + { + defaultAllocator().freeT(entry_ptr); + return null; + } + return handle; +} + +void thread_join(Thread t) +{ + if (!t) + return; + version (Windows) + { + import urt.internal.sys.windows.winbase : WaitForSingleObject, CloseHandle, INFINITE; + WaitForSingleObject(t, INFINITE); + CloseHandle(t); + } + else version (Posix) + pthread_join(cast(pthread_t)t, null); + else version (FreeRTOS) + assert(false, "thread_join is not yet implemented on FreeRTOS"); + else + return; +} + + +private: + +version (Windows) +{ + extern(Windows) uint _win_entry(void* arg) nothrow @nogc + { + auto entry_ptr = cast(ThreadEntry*)arg; + ThreadEntry entry = *entry_ptr; + defaultAllocator().freeT(entry_ptr); + entry(); + return 0; + } +} +else version (Posix) +{ + extern(C) void* _posix_entry(void* arg) nothrow @nogc + { + auto entry_ptr = cast(ThreadEntry*)arg; + ThreadEntry entry = *entry_ptr; + defaultAllocator().freeT(entry_ptr); + entry(); + return null; + } +} +else version (FreeRTOS) +{ + extern(C) void _freertos_entry(void* arg) nothrow @nogc + { + import urt.internal.sys.freertos : vTaskDelete; + auto entry_ptr = cast(ThreadEntry*)arg; + ThreadEntry entry = *entry_ptr; + defaultAllocator().freeT(entry_ptr); + entry(); + vTaskDelete(null); + } +} + + +// --- Platform bindings -------------------------------------------------- + +version (Posix) +{ + extern(C) nothrow @nogc: + + // pthread_t -- typedef varies by impl. Linux glibc: unsigned long. + // Darwin: _opaque_pthread_t*. + alias pthread_t = void*; + + // pthread_attr_t -- opaque, platform-sized. + // Linux: 56 bytes (x86_64), 36 (x86). Darwin: 56 (64-bit), 36 (32-bit). + // Conservative ceilings below. + version (linux) + { + static if (size_t.sizeof == 8) + struct pthread_attr_t { align(8) ubyte[64] _; } + else + struct pthread_attr_t { align(4) ubyte[36] _; } + } + else version (Darwin) + { + static if (size_t.sizeof == 8) + struct pthread_attr_t { align(8) ubyte[64] _; } + else + struct pthread_attr_t { align(4) ubyte[40] _; } + } + else + static assert(false, "pthread_attr_t size not configured for this POSIX target"); + + alias PthreadStart = extern(C) void* function(void*) nothrow @nogc; + int pthread_create(pthread_t*, const(pthread_attr_t)*, PthreadStart, void*); + int pthread_join(pthread_t, void**); + int pthread_attr_init(pthread_attr_t*); + int pthread_attr_destroy(pthread_attr_t*); + int pthread_attr_setstacksize(pthread_attr_t*, size_t); +} + + +version (Windows) enum _has_smoke = true; +else version (Posix) enum _has_smoke = true; +else enum _has_smoke = false; + +static if (_has_smoke) +{ + import urt.atomic; + + unittest + { + static shared int _smoke_counter; + + atomicStore(_smoke_counter, 0); + Thread t = thread_spawn(() nothrow @nogc { atomicFetchAdd(_smoke_counter, 1); }); + assert(t !is null); + thread_join(t); + assert(atomicLoad(_smoke_counter) == 1); + } +} diff --git a/src/urt/time.d b/src/urt/time.d index 646af39..dbbba7c 100644 --- a/src/urt/time.d +++ b/src/urt/time.d @@ -1,16 +1,21 @@ module urt.time; -import urt.traits : isSomeFloat; +import urt.array : Array; +import urt.traits : is_some_float; version (Windows) { - import core.sys.windows.windows; + import urt.internal.sys.windows; - extern (Windows) void GetSystemTimePreciseAsFileTime(FILETIME* lpSystemTimeAsFileTime) nothrow @nogc; + extern(Windows) void GetSystemTimePreciseAsFileTime(FILETIME* lpSystemTimeAsFileTime) nothrow @nogc; } else version (Posix) { - import core.sys.posix.time; + import urt.internal.sys.posix; +} +else version (Embedded) +{ + import urt.driver.timer; } nothrow @nogc: @@ -28,7 +33,8 @@ enum Day : ubyte enum Month : ubyte { - January = 1, + Unspecified = 0, + January, February, March, April, @@ -63,10 +69,15 @@ pure nothrow @nogc: T opCast(T)() const if (is(T == Time!c, Clock c) && c != clock) { - static if (clock == Clock.Monotonic && c == Clock.SystemTime) - return SysTime(ticks + ticksSinceBoot); + static if (is(T == Time!c, Clock c) && c != clock) + { + static if (clock == Clock.Monotonic && c == Clock.SystemTime) + return SysTime(ticks + sys_time_offset); + else + return MonoTime(ticks - sys_time_offset); + } else - return MonoTime(ticks - ticksSinceBoot); + static assert(false, "constraint out of sync"); } bool opEquals(Time!clock b) const @@ -82,9 +93,9 @@ pure nothrow @nogc: static if (clock != c) { static if (clock == Clock.Monotonic) - t1 += ticksSinceBoot; + t1 += sys_time_offset; else - t2 += ticksSinceBoot; + t2 += sys_time_offset; } return Duration(t1 - t2); } @@ -100,27 +111,47 @@ pure nothrow @nogc: import urt.string.format : FormatArg; ptrdiff_t toString(char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) const { - long ms = (ticks != 0 ? appTime(this) : Duration()).as!"msecs"; - if (!buffer.ptr) - return 2 + timeToString(ms, null); - if (buffer.length < 2) - return -1; - buffer[0..2] = "T+"; - ptrdiff_t len = timeToString(ms, buffer[2..$]); - return len < 0 ? len : 2 + len; + static if (clock == Clock.SystemTime) + { + DateTime dt = getDateTime(this); + return dt.toString(buffer, format, formatArgs); + } + else + { + long ns = (ticks != 0 ? appTime(this) : Duration()).as!"nsecs"; + if (!buffer.ptr) + return 2 + timeToString(ns, null); + if (buffer.length < 2) + return -1; + buffer[0..2] = "T+"; + ptrdiff_t len = timeToString(ns, buffer[2..$]); + return len < 0 ? len : 2 + len; + } } - auto __debugOverview() const + ptrdiff_t fromString(const(char)[] s) { - debug + static if (clock == Clock.SystemTime) { - import urt.mem.temp; - char[] b = cast(char[])talloc(64); - ptrdiff_t len = toString(b, null, null); - return b[0..len]; + DateTime dt; + ptrdiff_t len = dt.fromString(s); + if (len >= 0) + this = getSysTime(dt); + return len; } else - return appTime(this).as!"msecs"; + { + assert(false, "TODO: ???"); // what is the format we parse? + } + } + + version (Windows) + auto __debugOverview() const + { + import urt.mem; + char[] b = debug_alloc!char(64); + ptrdiff_t len = toString(b, null, null); + return b[0..len]; } } @@ -137,8 +168,8 @@ pure nothrow @nogc: bool opCast(T : bool)() const => ticks != 0; - T opCast(T)() const if (isSomeFloat!T) - => cast(T)ticks / cast(T)ticksPerSecond; + T opCast(T)() const if (is_some_float!T) + => cast(T)ticks / cast(T)ticks_per_second; bool opEquals(Duration b) const => ticks == b.ticks; @@ -161,21 +192,21 @@ pure nothrow @nogc: long as(string base)() const { static if (base == "nsecs") - return ticks*nsecMultiplier; + return ticks*nsec_multiplier; else static if (base == "usecs") - return ticks*nsecMultiplier / 1_000; + return ticks*nsec_multiplier / 1_000; else static if (base == "msecs") - return ticks*nsecMultiplier / 1_000_000; + return ticks*nsec_multiplier / 1_000_000; else static if (base == "seconds") - return ticks*nsecMultiplier / 1_000_000_000; + return ticks*nsec_multiplier / 1_000_000_000; else static if (base == "minutes") - return ticks*nsecMultiplier / 60_000_000_000; + return ticks*nsec_multiplier / 60_000_000_000; else static if (base == "hours") - return ticks*nsecMultiplier / 3_600_000_000_000; + return ticks*nsec_multiplier / 3_600_000_000_000; else static if (base == "days") - return ticks*nsecMultiplier / 86_400_000_000_000; + return ticks*nsec_multiplier / 86_400_000_000_000; else static if (base == "weeks") - return ticks*nsecMultiplier / 604_800_000_000_000; + return ticks*nsec_multiplier / 604_800_000_000_000; else static assert(false, "Invalid base"); } @@ -183,11 +214,105 @@ pure nothrow @nogc: import urt.string.format : FormatArg; ptrdiff_t toString(char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) const { - return timeToString(as!"msecs", buffer); + return timeToString(as!"nsecs", buffer); } - auto __debugOverview() const - => cast(double)this; + ptrdiff_t fromString(const(char)[] s) + { + import urt.conv : parse_int; + import urt.string.ascii : is_alpha, ieq; + + if (s.length == 0) + return -1; + + size_t offset = 0; + long total_nsecs = 0; + ubyte last_unit = 8; + + while (offset < s.length) + { + // Parse number + size_t len; + long value = s[offset..$].parse_int(&len); + if (len == 0) + return last_unit != 8 ? offset : -1; + offset += len; + + if (offset >= s.length) + return -1; + + // Parse unit + size_t unit_start = offset; + while (offset < s.length && s[offset].is_alpha) + offset++; + + if (offset == unit_start) + return -1; + + const(char)[] unit = s[unit_start..offset]; + + // Convert unit to nanoseconds and check for duplicates + ubyte this_unit; + if (unit.ieq("w")) + { + value *= 604_800_000_000_000; + this_unit = 7; + } + else if (unit.ieq("d")) + { + value *= 86_400_000_000_000; + this_unit = 6; + } + else if (unit.ieq("h")) + { + value *= 3_600_000_000_000; + this_unit = 5; + } + else if (unit.ieq("m")) + { + value *= 60_000_000_000; + this_unit = 4; + } + else if (unit.ieq("s")) + { + value *= 1_000_000_000; + this_unit = 3; + } + else if (unit.ieq("ms")) + { + value *= 1_000_000; + this_unit = 2; + } + else if (unit.ieq("us")) + { + value *= 1_000; + this_unit = 1; + } + else if (unit.ieq("ns")) + this_unit = 0; + else + return -1; + + // Check for ordering, duplicates, and only one of ms/us/ns may be present + if (this_unit >= last_unit || (this_unit < 2 && last_unit < 3)) + return -1; + last_unit = this_unit; + + total_nsecs += value; + } + + if (last_unit == 8) + return -1; + + ticks = total_nsecs / nsec_multiplier; + return offset; + } + + version (Windows) + { + auto __debugOverview() const + => cast(double)this; + } } alias Timer = FixedTimer!(); @@ -276,76 +401,514 @@ pure nothrow @nogc: this = mixin("this " ~ op ~ " rhs;"); } + int opCmp(DateTime dt) const + { + int r = year - dt.year; + if (r != 0) return r; + r = month - dt.month; + if (r != 0) return r; + r = day - dt.day; + if (r != 0) return r; + r = hour - dt.hour; + if (r != 0) return r; + r = minute - dt.minute; + if (r != 0) return r; + r = second - dt.second; + if (r != 0) return r; + return ns - dt.ns; + } + import urt.string.format : FormatArg; ptrdiff_t toString(char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) const { - import urt.conv : formatInt; + import urt.conv : format_int, format_uint; - size_t offset = 0; - uint y = year; - if (year <= 0) + ptrdiff_t len; + if (!buffer.ptr) + { + len = 15; // all the fixed chars + len += year.format_int(null); + if (ns) + { + ++len; // the dot + uint nsecs = ns; + uint m = 0; + while (nsecs) + { + ++len; + uint digit = nsecs / digit_multipliers[m]; + nsecs -= digit * digit_multipliers[m++]; + } + } + return len; + } + + len = year.format_int(buffer[]); + if (len < 0 || len + 15 > buffer.length) + return -1; + size_t offset = len; + buffer[offset++] = '-'; + buffer[offset++] = '0' + (month / 10); + buffer[offset++] = '0' + (month % 10); + buffer[offset++] = '-'; + buffer[offset++] = '0' + (day / 10); + buffer[offset++] = '0' + (day % 10); + buffer[offset++] = 'T'; + buffer[offset++] = '0' + (hour / 10); + buffer[offset++] = '0' + (hour % 10); + buffer[offset++] = ':'; + buffer[offset++] = '0' + (minute / 10); + buffer[offset++] = '0' + (minute % 10); + buffer[offset++] = ':'; + buffer[offset++] = '0' + (second / 10); + buffer[offset++] = '0' + (second % 10); + if (ns) { - if (buffer.length < 3) + if (offset == buffer.length) return -1; - y = -year + 1; - buffer[0 .. 3] = "BC "; - offset += 3; + buffer[offset++] = '.'; + uint nsecs = ns; + uint m = 0; + while (nsecs) + { + if (offset == buffer.length) + return -1; + int digit = nsecs / digit_multipliers[m]; + buffer[offset++] = cast(char)('0' + digit); + nsecs -= digit * digit_multipliers[m++]; + } } - ptrdiff_t len = year.formatInt(buffer[offset..$]); - if (len < 0 || len == buffer.length) + // TODO: timezone suffix? + return offset; + } + + ptrdiff_t fromString(const(char)[] s) + { + import urt.conv : parse_int, parse_uint; + import urt.string.ascii : ieq, is_numeric, is_whitespace, to_lower; + + month = Month.Unspecified; + day = 0; + hour = 0; + minute = 0; + second = 0; + ns = 0; + + size_t offset = 0; + + // parse year + if (s.length >= 2 && s[0..2].ieq("bc")) + { + offset = 2; + if (s.length >= 3 && s[2] == ' ') + ++offset; + } + size_t len; + long value = s[offset..$].parse_int(&len); + if (len == 0) return -1; + if (offset > 0) + { + if (value <= 0) + return -1; // no year 0, or negative years BC! + value = -value + 1; + } + if (value < short.min || value > short.max) + return -1; + year = cast(short)value; offset += len; - buffer[offset++] = '-'; - len = month.formatInt(buffer[offset..$]); - if (len < 0 || len == buffer.length) + + if (offset == s.length || (s[offset] != '-' && s[offset] != '/')) + return offset; + + // parse month + value = s[++offset..$].parse_int(&len); + if (len == 0) + { + if (s.length < 3) + return -1; + foreach (i; 0..12) + { + if (s[offset..offset+3].ieq(g_month_names[i])) + { + value = i + 1; + len = 3; + goto got_month; + } + } + return -1; + got_month: + } + else if (value < 1 || value > 12) return -1; + month = cast(Month)value; offset += len; - buffer[offset++] = '-'; - len = day.formatInt(buffer[offset..$]); - if (len < 0 || len == buffer.length) + + if (offset == s.length || (s[offset] != '-' && s[offset] != '/')) + return offset; + + // parse day + value = s[++offset..$].parse_int(&len); + if (len == 0 || value < 1 || value > 31) return -1; + day = cast(ubyte)value; offset += len; - buffer[offset++] = ' '; - len = hour.formatInt(buffer[offset..$], 10, 2, '0'); - if (len < 0 || len == buffer.length) + + if (offset == s.length || (s[offset] != 'T' && s[offset] != ' ')) + return offset; + + // parse hour + value = s[++offset..$].parse_int(&len); + if (len != 2 || value < 0 || value > 23) return -1; + hour = cast(ubyte)value; offset += len; + + if (offset == s.length) + return offset; + + if (s[offset] == ':') + { + // parse minute + value = s[++offset..$].parse_int(&len); + if (len != 2 || value < 0 || value > 59) + return -1; + minute = cast(ubyte)value; + offset += len; + + if (offset == s.length) + return offset; + + if (s[offset] == ':') + { + // parse second + value = s[++offset..$].parse_int(&len); + if (len != 2 || value < 0 || value > 59) + return -1; + second = cast(ubyte)value; + offset += len; + + if (offset < s.length && s[offset] == '.') + { + // parse fractions + ++offset; + uint multiplier = 100_000_000; + while (offset < s.length && multiplier > 0 && s[offset].is_numeric) + { + ns += (s[offset++] - '0') * multiplier; + multiplier /= 10; + } + if (multiplier == 100_000_000) + return offset-1; // no number after the dot + } + } + else if (s[offset] == '.') + { + // fraction of minute + assert(false, "TODO"); + } + } + else if (s[offset] == '.') + { + // fraction of hour + assert(false, "TODO"); + } + + if (offset == s.length) + return offset; + + if (s[offset].to_lower == 'z') + { + // TODO: UTC timezone designator... +// assert(false, "TODO: we need to know our local timezone..."); + + return offset + 1; + } + + size_t tz_offset = offset; + if (s[offset] == ' ') + ++tz_offset; + if (s[tz_offset] != '-' && s[tz_offset] != '+') + return offset; + bool tz_neg = s[tz_offset] == '-'; + tz_offset += 1; + + // parse timezone (00:00) + int tz_hr, tz_min; + + value = s[tz_offset..$].parse_uint(&len); + if (len == 0) + return offset; + + if (len == 4) + { + if (value > 2359) + return -1; + tz_min = cast(int)(value % 100); + if (tz_min > 59) + return -1; + tz_hr = cast(int)(value / 100); + tz_offset += 4; + } + else + { + if (len != 2 || value > 59) + return -1; + + tz_hr = cast(int)value; + tz_offset += 2; + + if (tz_offset < s.length && s[tz_offset] == ':') + { + value = s[tz_offset+1..$].parse_uint(&len); + if (len != 0) + { + if (len != 2 || value > 59) + return -1; + tz_min = cast(int)value; + tz_offset += 3; + } + } + } + + if (tz_neg) + tz_hr = -tz_hr; + +// assert(false, "TODO: we need to know our local timezone..."); + + return tz_offset; + } +} + +struct TimeOfDay +{ +pure nothrow @nogc: + + ubyte hour; + ubyte minute; + ubyte second; + uint ns; + + ushort msec() const => cast(ushort)(ns / 1_000_000); + uint usec() const => ns / 1_000; + + Duration opBinary(string op)(TimeOfDay rhs) const if (op == "-") + { + long lhs_ns = (cast(long)hour*3600 + cast(long)minute*60 + cast(long)second) * 1_000_000_000 + ns; + long rhs_ns = (cast(long)rhs.hour*3600 + cast(long)rhs.minute*60 + cast(long)rhs.second) * 1_000_000_000 + rhs.ns; + return (lhs_ns - rhs_ns).nsecs; + } + + TimeOfDay opBinary(string op)(Duration rhs) const if (op == "+" || op == "-") + { + long tod_ns = (cast(long)hour*3600 + cast(long)minute*60 + cast(long)second) * 1_000_000_000 + ns; + static if (op == "+") + tod_ns += rhs.as!"nsecs"; + else + tod_ns -= rhs.as!"nsecs"; + enum long day_ns = 86_400_000_000_000; + tod_ns = ((tod_ns % day_ns) + day_ns) % day_ns; + TimeOfDay r; + r.ns = cast(uint)(tod_ns % 1_000_000_000); + long sod = tod_ns / 1_000_000_000; + r.second = cast(ubyte)(sod % 60); + r.minute = cast(ubyte)((sod / 60) % 60); + r.hour = cast(ubyte)(sod / 3600); + return r; + } + + void opOpAssign(string op)(Duration rhs) if (op == "+" || op == "-") + { + this = mixin("this " ~ op ~ " rhs;"); + } + + int opCmp(TimeOfDay tod) const + { + int r = hour - tod.hour; + if (r != 0) return r; + r = minute - tod.minute; + if (r != 0) return r; + r = second - tod.second; + if (r != 0) return r; + return cast(int)ns - cast(int)tod.ns; + } + + import urt.string.format : FormatArg; + ptrdiff_t toString(char[] buffer, const(char)[] format, const(FormatArg)[] formatArgs) const + { + if (!buffer.ptr) + { + ptrdiff_t len = 8; + if (ns) + { + ++len; + uint nsecs = ns; + uint m = 0; + while (nsecs) + { + ++len; + uint digit = nsecs / digit_multipliers[m]; + nsecs -= digit * digit_multipliers[m++]; + } + } + return len; + } + + if (buffer.length < 8) + return -1; + size_t offset = 0; + buffer[offset++] = cast(char)('0' + (hour / 10)); + buffer[offset++] = cast(char)('0' + (hour % 10)); buffer[offset++] = ':'; - len = minute.formatInt(buffer[offset..$], 10, 2, '0'); - if (len < 0 || len == buffer.length) + buffer[offset++] = cast(char)('0' + (minute / 10)); + buffer[offset++] = cast(char)('0' + (minute % 10)); + buffer[offset++] = ':'; + buffer[offset++] = cast(char)('0' + (second / 10)); + buffer[offset++] = cast(char)('0' + (second % 10)); + if (ns) + { + if (offset == buffer.length) + return -1; + buffer[offset++] = '.'; + uint nsecs = ns; + uint m = 0; + while (nsecs) + { + if (offset == buffer.length) + return -1; + int digit = nsecs / digit_multipliers[m]; + buffer[offset++] = cast(char)('0' + digit); + nsecs -= digit * digit_multipliers[m++]; + } + } + return offset; + } + + ptrdiff_t fromString(const(char)[] s) + { + import urt.conv : parse_int; + import urt.string.ascii : is_numeric; + + hour = 0; + minute = 0; + second = 0; + ns = 0; + + if (s.length == 0) + return -1; + + size_t offset = 0; + size_t len; + long value = s[offset..$].parse_int(&len); + if (len != 2 || value < 0 || value > 23) return -1; + hour = cast(ubyte)value; offset += len; - buffer[offset++] = ':'; - len = second.formatInt(buffer[offset..$], 10, 2, '0'); - if (len < 0 || len == buffer.length) + + if (offset == s.length || s[offset] != ':') + return offset; + + value = s[++offset..$].parse_int(&len); + if (len != 2 || value < 0 || value > 59) return -1; + minute = cast(ubyte)value; offset += len; - buffer[offset++] = '.'; - len = (ns / 1_000_000).formatInt(buffer[offset..$], 10, 3, '0'); - if (len < 0) - return len; - return offset + len; + + if (offset == s.length || s[offset] != ':') + return offset; + + value = s[++offset..$].parse_int(&len); + if (len != 2 || value < 0 || value > 59) + return -1; + second = cast(ubyte)value; + offset += len; + + if (offset < s.length && s[offset] == '.') + { + ++offset; + uint multiplier = 100_000_000; + while (offset < s.length && multiplier > 0 && s[offset].is_numeric) + { + ns += (s[offset++] - '0') * multiplier; + multiplier /= 10; + } + if (multiplier == 100_000_000) + return offset-1; + } + + return offset; + } + + version (Windows) + auto __debugOverview() const + { + import urt.mem; + char[] b = debug_alloc!char(20); + ptrdiff_t len = toString(b, null, null); + return b[0..len]; } } +TimeOfDay time_of_day(DateTime dt) pure +{ + TimeOfDay t; + t.hour = dt.hour; + t.minute = dt.minute; + t.second = dt.second; + t.ns = dt.ns; + return t; +} + +TimeOfDay time_of_day(SysTime t) pure + => time_of_day(getDateTime(t)); + +SysTime next_occurrence(SysTime now, TimeOfDay tod, ubyte weekday_mask = 0x7F) pure +{ + if ((weekday_mask & 0x7F) == 0) + weekday_mask = 0x7F; + + ulong now_ns = unixTimeNs(now); + enum ulong day_ns = 86_400_000_000_000UL; + ulong day_start = now_ns - now_ns % day_ns; + ulong tod_ns = (cast(ulong)tod.hour*3600 + cast(ulong)tod.minute*60 + cast(ulong)tod.second) * 1_000_000_000UL + tod.ns; + + DateTime dt = getDateTime(now); + ubyte wday = cast(ubyte)dt.wday; + + foreach (_; 0 .. 7) + { + if (weekday_mask & (1 << wday)) + { + ulong candidate = day_start + tod_ns; + if (candidate > now_ns) + return from_unix_time_ns(candidate); + } + day_start += day_ns; + wday = cast(ubyte)((wday + 1) % 7); + } + + return from_unix_time_ns(day_start + tod_ns); +} + + Duration dur(string base)(long value) pure { static if (base == "nsecs") - return Duration(value / nsecMultiplier); + return Duration(value / nsec_multiplier); else static if (base == "usecs") - return Duration(value*1_000 / nsecMultiplier); + return Duration(value*1_000 / nsec_multiplier); else static if (base == "msecs") - return Duration(value*1_000_000 / nsecMultiplier); + return Duration(value*1_000_000 / nsec_multiplier); else static if (base == "seconds") - return Duration(value*1_000_000_000 / nsecMultiplier); + return Duration(value*1_000_000_000 / nsec_multiplier); else static if (base == "minutes") - return Duration(value*60_000_000_000 / nsecMultiplier); + return Duration(value*60_000_000_000 / nsec_multiplier); else static if (base == "hours") - return Duration(value*3_600_000_000_000 / nsecMultiplier); + return Duration(value*3_600_000_000_000 / nsec_multiplier); else static if (base == "days") - return Duration(value*86_400_000_000_000 / nsecMultiplier); + return Duration(value*86_400_000_000_000 / nsec_multiplier); else static if (base == "weeks") - return Duration(value*604_800_000_000_000 / nsecMultiplier); + return Duration(value*604_800_000_000_000 / nsec_multiplier); else static assert(false, "Invalid base"); } @@ -369,6 +932,13 @@ MonoTime getTime() clock_gettime(CLOCK_MONOTONIC, &ts); return MonoTime(ts.tv_sec * 1_000_000_000 + ts.tv_nsec); } + else version (Embedded) + { + static if (has_mtime) + return MonoTime(mtime_read()); + else + static assert(false, "getTime: no monotonic timer for this platform"); + } else { static assert(false, "TODO"); @@ -389,40 +959,32 @@ SysTime getSysTime() clock_gettime(CLOCK_REALTIME, &ts); return SysTime(ts.tv_sec * 1_000_000_000 + ts.tv_nsec); } + else version (Embedded) + { + static if (has_mtime) + return SysTime(mtime_read() + sys_time_offset); + else + static assert(false, "getSysTime: no monotonic timer for this platform"); + } else { static assert(false, "TODO"); } } +SysTime getSysTime(DateTime time) pure +{ + return from_unix_time_ns(datetime_to_unix_ns(time)); +} DateTime getDateTime() { - version (Windows) - return fileTimeToDateTime(getSysTime()); - else version (Posix) - { - timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - return realtimeToDateTime(ts); - } - else - static assert(false, "TODO"); + return getDateTime(getSysTime()); } -DateTime getDateTime(SysTime time) +DateTime getDateTime(SysTime time) pure { - version (Windows) - return fileTimeToDateTime(time); - else version (Posix) - { - timespec ts; - ts.tv_sec = cast(time_t)(time.ticks / 1_000_000_000); - ts.tv_nsec = cast(uint)(time.ticks % 1_000_000_000); - return realtimeToDateTime(ts); - } - else - static assert(false, "TODO"); + return unix_ns_to_datetime(unixTimeNs(time)); } Duration getAppTime() @@ -436,9 +998,23 @@ Duration appTime(SysTime t) pure ulong unixTimeNs(SysTime t) pure { version (Windows) - return (t.ticks - 116444736000000000UL) * 100UL; + return (t.ticks - unix_epoch_as_filetime) * 100UL; else version (Posix) return t.ticks; + else version (Embedded) + return t.ticks * nsec_multiplier; + else + static assert(false, "TODO"); +} + +SysTime from_unix_time_ns(ulong ns) pure +{ + version (Windows) + return SysTime(ns / 100UL + unix_epoch_as_filetime); + else version (Posix) + return SysTime(ns); + else version (Embedded) + return SysTime(ns / nsec_multiplier); else static assert(false, "TODO"); } @@ -446,49 +1022,136 @@ ulong unixTimeNs(SysTime t) pure Duration abs(Duration d) pure => Duration(d.ticks < 0 ? -d.ticks : d.ticks); +bool wall_time_set() +{ + return has_wall_time; +} + +void set_utc_time(ulong unix_ns) +{ + cast()sys_time_offset = unix_ns / nsec_multiplier - getTime().ticks; + has_wall_time = true; + + version (Windows) + { + import urt.internal.sys.windows; + + ulong ft = unix_ns / 100 + unix_epoch_as_filetime; + SYSTEMTIME st; + FileTimeToSystemTime(cast(FILETIME*)&ft, &st); + SetSystemTime(&st); + } + else version (Posix) + { + timespec ts; + ts.tv_sec = cast(time_t)(unix_ns / 1_000_000_000); + ts.tv_nsec = cast(uint)(unix_ns % 1_000_000_000); + clock_settime(CLOCK_REALTIME, &ts); + } + else version (Embedded) + { + static if (has_rtc) + { + auto p = hbn_persist(); + ulong mtime_ticks = unix_ns / nsec_multiplier; + ulong sec = mtime_ticks / mtime_freq_hz; + ulong frac = mtime_ticks % mtime_freq_hz; + ulong hbn_ticks = sec * rtc_freq_hz + frac * rtc_freq_hz / mtime_freq_hz; + p.utc_offset = cast(long)hbn_ticks - cast(long)rtc_read(); + p.magic = HbnPersist.HBN_MAGIC; + } + } + + notify_clock_change(); +} + + +alias ClockChangeHandler = void delegate() nothrow @nogc; + +void subscribe_clock_change(ClockChangeHandler h) +{ + _clock_change_handlers ~= h; +} + +void unsubscribe_clock_change(ClockChangeHandler h) +{ + debug assert(g_iterating_clock_change == false, "must not unsubscribe from a clock_change handler"); + foreach (i, hh; _clock_change_handlers) + { + if (hh is h) + { + _clock_change_handlers.removeSwapLast(i); + return; + } + } +} + +void notify_clock_change() +{ + debug g_iterating_clock_change = true; + foreach (h; _clock_change_handlers) + h(); + debug g_iterating_clock_change = false; +} + +debug __gshared g_iterating_clock_change = false; + private: -immutable MonoTime startTime; +__gshared Array!ClockChangeHandler _clock_change_handlers; + +__gshared immutable MonoTime startTime; + +__gshared immutable string[12] g_month_names = [ "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec" ]; +__gshared immutable uint[9] digit_multipliers = [ 100_000_000, 10_000_000, 1_000_000, 100_000, 10_000, 1_000, 100, 10, 1 ]; version (Windows) { - immutable uint ticksPerSecond; - immutable uint nsecMultiplier; - immutable ulong ticksSinceBoot; + enum ulong unix_epoch_as_filetime = 116_444_736_000_000_000UL; + + enum uint ticks_per_second = 10_000_000; // QPC has been 10mHz for several decades. I don't think it can ever change... + enum uint nsec_multiplier = 100; } else version (Posix) { - enum uint ticksPerSecond = 1_000_000_000; - enum uint nsecMultiplier = 1; - immutable ulong ticksSinceBoot; + enum uint ticks_per_second = 1_000_000_000; + enum uint nsec_multiplier = 1; +} +else version (Embedded) +{ + enum uint ticks_per_second = mtime_freq_hz; + enum uint nsec_multiplier = 1_000_000_000 / mtime_freq_hz; } -package(urt) void initClock() +__gshared immutable ulong sys_time_offset; +__gshared bool has_wall_time; + +package(urt) void init_clock() { cast()startTime = getTime(); version (Windows) { - import core.sys.windows.windows; + import urt.internal.sys.windows; import urt.util : min; LARGE_INTEGER freq; QueryPerformanceFrequency(&freq); - cast()ticksPerSecond = cast(uint)freq.QuadPart; - cast()nsecMultiplier = 1_000_000_000 / ticksPerSecond; + assert(cast(uint)freq.QuadPart == ticks_per_second, "Unexpected QPC frequency! urt needs to be updated..."); // we want the ftime for QPC 0; which should be the boot time // we'll repeat this 100 times and take the minimum, and we should be within probably nanoseconds of the correct value LARGE_INTEGER qpc; - ulong ftime, bootTime = ulong.max; + ulong ftime, boot_time = ulong.max; foreach (i; 0 .. 100) { QueryPerformanceCounter(&qpc); GetSystemTimePreciseAsFileTime(cast(FILETIME*)&ftime); - bootTime = min(bootTime, ftime - qpc.QuadPart); + boot_time = min(boot_time, ftime - qpc.QuadPart); } - cast()ticksSinceBoot = bootTime; + cast()sys_time_offset = boot_time; + has_wall_time = true; } else version (Posix) { @@ -496,35 +1159,67 @@ package(urt) void initClock() // this doesn't really give time since boot, since MONOTIME is not guaranteed to be zero at system startup... timespec mt, rt; - ulong bootTime = ulong.max; + ulong boot_time = ulong.max; foreach (i; 0 .. 100) { clock_gettime(CLOCK_MONOTONIC, &mt); clock_gettime(CLOCK_REALTIME, &rt); - bootTime = min(bootTime, rt.tv_sec*1_000_000_000 + rt.tv_nsec - mt.tv_sec*1_000_000_000 - mt.tv_nsec); + boot_time = min(boot_time, rt.tv_sec*1_000_000_000 + rt.tv_nsec - mt.tv_sec*1_000_000_000 - mt.tv_nsec); + } + cast()sys_time_offset = boot_time; + has_wall_time = true; + } + else version (Embedded) + { + timer_init(); + + static if (has_rtc) + { + rtc_enable(); + recalc_sys_time_offset(); + } + else + { + cast()sys_time_offset = 0; } - cast()ticksSinceBoot = bootTime; } else static assert(false, "TODO"); } -ptrdiff_t timeToString(long ms, char[] buffer) pure +ptrdiff_t timeToString(long ns, char[] buffer) pure { - import urt.conv : formatInt; + import urt.conv : format_int; - long hr = ms / 3_600_000; + int hr = cast(int)(ns / 3_600_000_000_000); + ns = ns < 0 ? -ns % 3_600_000_000_000 : ns % 3_600_000_000_000; + uint remainder = cast(uint)(ns % 1_000_000_000); if (!buffer.ptr) - return hr.formatInt(null, 10, 2, '0') + 10; + { + size_t tail = 6; + if (remainder) + { + ++tail; + uint m = 0; + do + { + ++tail; + uint digit = cast(uint)(remainder / digit_multipliers[m]); + remainder -= digit * digit_multipliers[m++]; + } + while (remainder); + } + return hr.format_int(null, 10, 2, '0') + tail; + } - ptrdiff_t len = hr.formatInt(buffer, 10, 2, '0'); - if (len < 0 || buffer.length < len + 10) + ptrdiff_t len = hr.format_int(buffer, 10, 2, '0'); + if (len < 0 || buffer.length < len + 6) return -1; - ubyte min = cast(ubyte)(ms / 60_000 % 60); - ubyte sec = cast(ubyte)(ms / 1000 % 60); - ms %= 1000; + uint min_sec = cast(uint)(ns / 1_000_000_000); + uint min = min_sec / 60; + uint sec = min_sec % 60; buffer.ptr[len++] = ':'; buffer.ptr[len++] = cast(char)('0' + (min / 10)); @@ -532,10 +1227,22 @@ ptrdiff_t timeToString(long ms, char[] buffer) pure buffer.ptr[len++] = ':'; buffer.ptr[len++] = cast(char)('0' + (sec / 10)); buffer.ptr[len++] = cast(char)('0' + (sec % 10)); - buffer.ptr[len++] = '.'; - buffer.ptr[len++] = cast(char)('0' + (ms / 100)); - buffer.ptr[len++] = cast(char)('0' + ((ms/10) % 10)); - buffer.ptr[len++] = cast(char)('0' + (ms % 10)); + if (remainder) + { + if (buffer.length < len + 2) + return -1; + buffer.ptr[len++] = '.'; + uint i = 0; + while (remainder) + { + if (buffer.length <= len) + return -1; + uint m = digit_multipliers[i++]; + uint digit = cast(uint)(remainder / m); + buffer.ptr[len++] = cast(char)('0' + digit); + remainder -= digit * m; + } + } return len; } @@ -544,55 +1251,256 @@ unittest import urt.mem.temp; assert(tconcat(msecs(3_600_000*3 + 60_000*47 + 1000*34 + 123))[] == "03:47:34.123"); - assert(tconcat(msecs(3_600_000*-123))[] == "-123:00:00.000"); - - assert(getTime().toString(null, null, null) == 14); + assert(tconcat(msecs(3_600_000*-123))[] == "-123:00:00"); + assert(tconcat(usecs(3_600_000_000*-123 + 1))[] == "-122:59:59.999999"); + assert(MonoTime().toString(null, null, null) == 10); assert(tconcat(getTime())[0..2] == "T+"); + + // Test Duration.fromString with compound formats + Duration d; + + // Simple single units + assert(d.fromString("5s") == 2 && d.as!"seconds" == 5); + assert(d.fromString("10m") == 3 && d.as!"minutes" == 10); + + // Compound durations + assert(d.fromString("1h30m") == 5 && d.as!"minutes" == 90); + assert(d.fromString("5m30s") == 5 && d.as!"seconds" == 330); + + // Duplicate units should fail + assert(d.fromString("30m30m") == -1); + assert(d.fromString("1h2h") == -1); + assert(d.fromString("5s10s") == -1); + + // Out-of-order units should fail + assert(d.fromString("30s5m") == -1); // s before m + assert(d.fromString("1m2h") == -1); // m before h + assert(d.fromString("5s10ms5m") == -1); // m after s + assert(d.fromString("5s10ms10ns") == -1); // ms and ns (only one sub-second unit allowed) + + // Improper units should fail + assert(d.fromString("30z") == -1); // not a time denomination + + // Correctly ordered units should work + assert(d.fromString("1d2h30m15s") == 10 && d.as!"seconds" == 86_400 + 7_200 + 1_800 + 15); + + // Test DateTime.fromString + DateTime dt; + assert(dt.fromString("2024-06-15T12:34:56") == 19); + assert(dt.fromString("-100/06/15 12:34:56") == 19); + assert(dt.fromString("BC100-AUG-15 12:34:56.789") == 25); + assert(dt.fromString("BC 10000-AUG-15 12:34:56.789123456") == 34); + assert(dt.fromString("1-1-1 01:01:01") == 14); + assert(dt.fromString("1-1-1 01:01:01.") == 14); + assert(dt.fromString("2025") == 4); + assert(dt.fromString("2025-10") == 7); + assert(dt.fromString("2025-01-01") == 10); + assert(dt.fromString("2025-01-01 00") == 13); + assert(dt.fromString("2025-01-01 00:10") == 16); + assert(dt.fromString("2025-01-01 00:10z") == 17); + assert(dt.fromString("2025-01-01 00+00:00") == 19); + assert(dt.fromString("2025-01-01 00-1030") == 18); + assert(dt.fromString("2025-01-01 00+08") == 16); + + assert(dt.fromString("BC -10") == -1); + assert(dt.fromString("2024-0-15 12:34:56") == -1); + assert(dt.fromString("2024-13-15 12:34:56") == -1); + assert(dt.fromString("2024-1-0 12:34:56") == -1); + assert(dt.fromString("2024-1-32 12:34:56") == -1); + assert(dt.fromString("2024-1-1 24:34:56") == -1); + assert(dt.fromString("2024-1-1 01:60:56") == -1); + assert(dt.fromString("2024-1-1 01:01:60") == -1); + assert(dt.fromString("10000-1-1 1:01:01") == -1); + + // ---- TimeOfDay ---- + + TimeOfDay tod; + assert(tod.fromString("10:30") == 5 && tod.hour == 10 && tod.minute == 30 && tod.second == 0 && tod.ns == 0); + assert(tod.fromString("10:30:45") == 8 && tod.second == 45); + assert(tod.fromString("10:30:45.5") == 10 && tod.ns == 500_000_000); + assert(tod.fromString("23:59:59.999999999") == 18 && tod.ns == 999_999_999); + assert(tod.fromString("00:00:00") == 8); + + assert(tod.fromString("24:00") == -1); + assert(tod.fromString("10:60") == -1); + assert(tod.fromString("10:30:60") == -1); + assert(tod.fromString("1:30") == -1); + assert(tod.fromString("") == -1); + + tod = TimeOfDay(10, 30, 0, 0); + assert(tconcat(tod)[] == "10:30:00"); + tod.ns = 123_000_000; + assert(tconcat(tod)[] == "10:30:00.123"); + + // arithmetic + tod = TimeOfDay(10, 30, 0, 0); + auto tod2 = tod + dur!"minutes"(45); + assert(tod2.hour == 11 && tod2.minute == 15 && tod2.second == 0); + auto tod3 = tod - dur!"hours"(11); + assert(tod3.hour == 23 && tod3.minute == 30); // wrap backwards + auto tod4 = tod + dur!"hours"(25); + assert(tod4.hour == 11 && tod4.minute == 30); // wrap forwards + Duration diff = TimeOfDay(11, 0, 0, 0) - TimeOfDay(10, 30, 0, 0); + assert(diff.as!"minutes" == 30); + + // extract from DateTime / SysTime + dt = DateTime.init; + dt.year = 2025; dt.month = Month.June; dt.day = 15; + dt.hour = 8; dt.minute = 30; dt.second = 45; dt.ns = 123_456_789; + tod = time_of_day(dt); + assert(tod.hour == 8 && tod.minute == 30 && tod.second == 45 && tod.ns == 123_456_789); + + // ---- unix_ns_to_datetime / datetime_to_unix_ns ---- + + // Unix epoch: 1970-01-01 00:00:00 UTC, Thursday + dt = unix_ns_to_datetime(0); + assert(dt.year == 1970 && dt.month == Month.January && dt.day == 1); + assert(dt.hour == 0 && dt.minute == 0 && dt.second == 0 && dt.ns == 0); + assert(dt.wday == Day.Thursday); + + // Round-trip at epoch + assert(datetime_to_unix_ns(dt) == 0); + + // 2000-01-01 00:00:00 UTC = 946684800 seconds, Saturday + dt = unix_ns_to_datetime(946_684_800UL * 1_000_000_000); + assert(dt.year == 2000 && dt.month == Month.January && dt.day == 1); + assert(dt.wday == Day.Saturday); + assert(datetime_to_unix_ns(dt) == 946_684_800UL * 1_000_000_000); + + // 2024-02-29 (leap year) 12:00:00 = 1709208000 seconds, Thursday + dt = unix_ns_to_datetime(1_709_208_000UL * 1_000_000_000); + assert(dt.year == 2024 && dt.month == Month.February && dt.day == 29); + assert(dt.hour == 12 && dt.minute == 0 && dt.second == 0); + assert(dt.wday == Day.Thursday); + assert(datetime_to_unix_ns(dt) == 1_709_208_000UL * 1_000_000_000); + + // 1900-03-01 - 1900 is NOT a leap year (century rule) + // 1900-03-01 00:00:00 = -2203891200 seconds... negative, skip + // Instead test 2100-03-01 (also not a leap year) + // 2100-03-01 00:00:00 = 4107542400 seconds, Monday + dt = unix_ns_to_datetime(4_107_542_400UL * 1_000_000_000); + assert(dt.year == 2100 && dt.month == Month.March && dt.day == 1); + assert(dt.wday == Day.Monday); + + // 2000 IS a leap year (400-year rule), Feb 29 exists + // 2000-02-29 00:00:00 = 951782400 seconds, Tuesday + dt = unix_ns_to_datetime(951_782_400UL * 1_000_000_000); + assert(dt.year == 2000 && dt.month == Month.February && dt.day == 29); + assert(dt.wday == Day.Tuesday); + + // Sub-second precision: 2025-06-15 08:30:45.123456789 + dt.year = 2025; dt.month = Month.June; dt.day = 15; + dt.hour = 8; dt.minute = 30; dt.second = 45; dt.ns = 123_456_789; + ulong ns = datetime_to_unix_ns(dt); + auto dt2 = unix_ns_to_datetime(ns); + assert(dt2.year == 2025 && dt2.month == Month.June && dt2.day == 15); + assert(dt2.hour == 8 && dt2.minute == 30 && dt2.second == 45); + assert(dt2.ns == 123_456_789); + + // Dec 31 ? Jan 1 boundary + dt = unix_ns_to_datetime(1_735_689_599UL * 1_000_000_000); // 2024-12-31 23:59:59 + assert(dt.year == 2024 && dt.month == Month.December && dt.day == 31); + assert(dt.hour == 23 && dt.minute == 59 && dt.second == 59); + dt = unix_ns_to_datetime(1_735_689_600UL * 1_000_000_000); // 2025-01-01 00:00:00 + assert(dt.year == 2025 && dt.month == Month.January && dt.day == 1); + assert(dt.wday == Day.Wednesday); } -version (Windows) +DateTime unix_ns_to_datetime(ulong ns) pure { - DateTime fileTimeToDateTime(SysTime ftime) - { - version (BigEndian) - static assert(false, "Only works in little endian!"); + ulong total_sec = ns / 1_000_000_000; + uint remainder_ns = cast(uint)(ns % 1_000_000_000); + + uint sod = cast(uint)(total_sec % 86_400); + long days = cast(long)(total_sec / 86_400); + + DateTime dt; + dt.hour = cast(ubyte)(sod / 3600); + dt.minute = cast(ubyte)(sod % 3600 / 60); + dt.second = cast(ubyte)(sod % 60); + dt.ns = remainder_ns; + + dt.wday = cast(Day)((days + 4) % 7); + + days += 719_468; + long era = (days >= 0 ? days : days - 146_096) / 146_097; + uint doe = cast(uint)(days - era * 146_097); + uint yoe = (doe - doe / 1460 + doe / 36524 - doe / 146_096) / 365; + long y = yoe + era * 400; + uint doy = doe - (365 * yoe + yoe / 4 - yoe / 100); + uint mp = (5 * doy + 2) / 153; + uint d = doy - (153 * mp + 2) / 5 + 1; + uint m = mp < 10 ? mp + 3 : mp - 9; + if (m <= 2) + ++y; + + dt.year = cast(short)y; + dt.month = cast(Month)m; + dt.day = cast(ubyte)d; + + return dt; +} - SYSTEMTIME stime; - FileTimeToSystemTime(cast(FILETIME*)&ftime.ticks, &stime); +ulong datetime_to_unix_ns(DateTime dt) pure +{ + long y = dt.year; + uint m = dt.month; + uint d = dt.day; - DateTime dt; - dt.year = stime.wYear; - dt.month = cast(Month)stime.wMonth; - dt.wday = cast(Day)stime.wDayOfWeek; - dt.day = cast(ubyte)stime.wDay; - dt.hour = cast(ubyte)stime.wHour; - dt.minute = cast(ubyte)stime.wMinute; - dt.second = cast(ubyte)stime.wSecond; - dt.ns = (ftime.ticks % 10_000_000) * 100; + if (m <= 2) + --y; + long era = (y >= 0 ? y : y - 399) / 400; + uint yoe = cast(uint)(y - era * 400); + uint doy = (153 * (m > 2 ? m - 3 : m + 9) + 2) / 5 + d - 1; + uint doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; + long days = era * 146_097 + doe - 719_468; - debug assert(stime.wMilliseconds == dt.msec); + ulong total_sec = cast(ulong)(days * 86_400 + dt.hour*3600 + dt.minute*60 + dt.second); - return dt; - } + return total_sec * 1_000_000_000 + dt.ns; } -else version (Posix) + +version (Embedded) static if (has_rtc) { - DateTime realtimeToDateTime(timespec ts) + __gshared ulong last_hbn; + + void correct_drift() { - tm t; - gmtime_r(&ts.tv_sec, &t); + auto p = hbn_persist(); + if (p.magic != HbnPersist.HBN_MAGIC) + return; + + ulong now_hbn = rtc_read(); + + // detect 40-bit wrap: counter went backwards since last check + if (now_hbn < last_hbn) + p.utc_offset += ulong(1) << 40; + last_hbn = now_hbn; - DateTime dt; - dt.year = cast(short)(t.tm_year + 1900); - dt.month = cast(Month)(t.tm_mon + 1); - dt.wday = cast(Day)t.tm_wday; - dt.day = cast(ubyte)t.tm_mday; - dt.hour = cast(ubyte)t.tm_hour; - dt.minute = cast(ubyte)t.tm_min; - dt.second = cast(ubyte)t.tm_sec; - dt.ns = cast(uint)ts.tv_nsec; + ulong sys_mtime = mtime_read() + sys_time_offset; - return dt; + // What does HBN + offset think it is (converted to mtime ticks)? + ulong hbn_total = now_hbn + p.utc_offset; + ulong sys_hbn = hbn_total / rtc_freq_hz * mtime_freq_hz + + hbn_total % rtc_freq_hz * mtime_freq_hz / rtc_freq_hz; + + // difference is accumulated drift; fold into utc_offset + long drift_mtime = sys_mtime - sys_hbn; + p.utc_offset += drift_mtime * rtc_freq_hz / mtime_freq_hz; + } + + void recalc_sys_time_offset() + { + auto p = hbn_persist(); + if (p.magic == HbnPersist.HBN_MAGIC) + { + last_hbn = rtc_read(); + long hbn_total = cast(long)(last_hbn + p.utc_offset); + long hbn_unix_mtime = hbn_total / rtc_freq_hz * mtime_freq_hz + + hbn_total % rtc_freq_hz * mtime_freq_hz / rtc_freq_hz; + cast()sys_time_offset = cast(ulong)(hbn_unix_mtime - cast(long)mtime_read()); + has_wall_time = true; + } } } diff --git a/src/urt/traits.d b/src/urt/traits.d index 30ef675..6f8a761 100644 --- a/src/urt/traits.d +++ b/src/urt/traits.d @@ -3,67 +3,67 @@ module urt.traits; import urt.meta; -enum bool isType(alias X) = is(X); +enum bool is_type(alias X) = is(X); -enum bool isBoolean(T) = __traits(isUnsigned, T) && is(T : bool); +enum bool is_boolean(T) = __traits(isUnsigned, T) && is(T : bool); -enum bool isUnsignedInt(T) = is(Unqual!T == ubyte) || is(Unqual!T == ushort) || is(Unqual!T == uint) || is(Unqual!T == ulong); -enum bool isSignedInt(T) = is(Unqual!T == byte) || is(Unqual!T == short) || is(Unqual!T == int) || is(Unqual!T == long); -enum bool isSomeInt(T) = isUnsignedInt!T || isSignedInt!T; -enum bool isUnsignedIntegral(T) = is(Unqual!T == bool) || isUnsignedInt!T || isSomeChar!T; -enum bool isSignedIntegral(T) = isSignedInt!T; -enum bool isIntegral(T) = isUnsignedIntegral!T || isSignedIntegral!T; -enum bool isSomeFloat(T) = is(Unqual!T == float) || is(Unqual!T == double) || is(Unqual!T == real); +enum bool is_unsigned_int(T) = is(Unqual!T == ubyte) || is(Unqual!T == ushort) || is(Unqual!T == uint) || is(Unqual!T == ulong); +enum bool is_signed_int(T) = is(Unqual!T == byte) || is(Unqual!T == short) || is(Unqual!T == int) || is(Unqual!T == long); +enum bool is_some_int(T) = is_unsigned_int!T || is_signed_int!T; +enum bool is_unsigned_integral(T) = is_boolean!T || is_unsigned_int!T || is_some_char!T; +enum bool is_signed_integral(T) = is_signed_int!T; +enum bool is_integral(T) = is_unsigned_integral!T || is_signed_integral!T; +enum bool is_some_float(T) = is(Unqual!T == float) || is(Unqual!T == double) || is(Unqual!T == real); -enum bool isEnum(T) = is(T == enum); -template enumType(T) - if (isEnum!T) +enum bool is_enum(T) = is(T == enum); +template EnumType(T) + if (is_enum!T) { static if (is(T E == enum)) - alias enumType = E; + alias EnumType = E; else static assert(false, "How this?"); } -template isUnsigned(T) +template is_unsigned(T) { static if (!__traits(isUnsigned, T)) - enum isUnsigned = false; + enum is_unsigned = false; else static if (is(T U == enum)) - enum isUnsigned = isUnsigned!U; + enum is_unsigned = is_unsigned!U; else - enum isUnsigned = __traits(isZeroInit, T) // Not char, wchar, or dchar. + enum is_unsigned = __traits(isZeroInit, T) // Not char, wchar, or dchar. && !is(immutable T == immutable bool) && !is(T == __vector); } -enum bool isSigned(T) = __traits(isArithmetic, T) && !__traits(isUnsigned, T) && is(T : real); +enum bool is_signed(T) = __traits(isArithmetic, T) && !__traits(isUnsigned, T) && is(T : real); -template isSomeChar(T) +template is_some_char(T) { static if (!__traits(isUnsigned, T)) - enum isSomeChar = false; + enum is_some_char = false; else static if (is(T U == enum)) - enum isSomeChar = isSomeChar!U; + enum is_some_char = is_some_char!U; else - enum isSomeChar = !__traits(isZeroInit, T); + enum is_some_char = !__traits(isZeroInit, T); } -enum bool isSomeFunction(alias T) = is(T == return) || is(typeof(T) == return) || is(typeof(&T) == return); -enum bool isFunctionPointer(alias T) = is(typeof(*T) == function); -enum bool isDelegate(alias T) = is(typeof(T) == delegate) || is(T == delegate); +enum bool is_some_function(alias T) = is(T == return) || is(typeof(T) == return) || is(typeof(&T) == return); +enum bool is_function_pointer(alias T) = is(typeof(*T) == function); +enum bool is_delegate(alias T) = is(typeof(T) == delegate) || is(T == delegate); -template isCallable(alias callable) +template is_callable(alias callable) { static if (is(typeof(&callable.opCall) == delegate)) - enum bool isCallable = true; + enum bool is_callable = true; else static if (is(typeof(&callable.opCall) V : V*) && is(V == function)) - enum bool isCallable = true; + enum bool is_callable = true; else static if (is(typeof(&callable.opCall!()) TemplateInstanceType)) - enum bool isCallable = isCallable!TemplateInstanceType; + enum bool is_callable = is_callable!TemplateInstanceType; else static if (is(typeof(&callable!()) TemplateInstanceType)) - enum bool isCallable = isCallable!TemplateInstanceType; + enum bool is_callable = is_callable!TemplateInstanceType; else - enum bool isCallable = isSomeFunction!callable; + enum bool is_callable = is_some_function!callable; } @@ -79,7 +79,7 @@ template Unqual(T : const U, U) template Unsigned(T) { - static if (isUnsigned!T) + static if (is_unsigned!T) alias Unsigned = T; else static if (is(T == long)) alias Unsigned = ulong; @@ -113,7 +113,7 @@ template Unsigned(T) template Signed(T) { - static if (isSigned!T) + static if (is_signed!T) alias Unsigned = T; else static if (is(T == ulong)) alias Signed = long; @@ -144,7 +144,7 @@ template Signed(T) } template ReturnType(alias func) - if (isCallable!func) + if (is_callable!func) { static if (is(FunctionTypeOf!func R == return)) alias ReturnType = R; @@ -153,7 +153,7 @@ template ReturnType(alias func) } template Parameters(alias func) - if (isCallable!func) + if (is_callable!func) { static if (is(FunctionTypeOf!func P == function)) alias Parameters = P; @@ -161,26 +161,26 @@ template Parameters(alias func) static assert(0, "argument has no parameters"); } -template ParameterIdentifierTuple(alias func) - if (isCallable!func) +template parameter_identifier_tuple(alias func) + if (is_callable!func) { static if (is(FunctionTypeOf!func PT == __parameters)) { - alias ParameterIdentifierTuple = AliasSeq!(); + alias parameter_identifier_tuple = AliasSeq!(); static foreach (i; 0 .. PT.length) { - static if (!isFunctionPointer!func && !isDelegate!func + static if (!is_function_pointer!func && !is_delegate!func // Unnamed parameters yield CT error. && is(typeof(__traits(identifier, PT[i .. i+1]))) // Filter out unnamed args, which look like (Type) instead of (Type name). && PT[i].stringof != PT[i .. i+1].stringof[1..$-1]) { - ParameterIdentifierTuple = AliasSeq!(ParameterIdentifierTuple, + parameter_identifier_tuple = AliasSeq!(parameter_identifier_tuple, __traits(identifier, PT[i .. i+1])); } else { - ParameterIdentifierTuple = AliasSeq!(ParameterIdentifierTuple, ""); + parameter_identifier_tuple = AliasSeq!(parameter_identifier_tuple, ""); } } } @@ -188,12 +188,12 @@ template ParameterIdentifierTuple(alias func) { static assert(0, func.stringof ~ " is not a function"); // avoid pointless errors - alias ParameterIdentifierTuple = AliasSeq!(); + alias parameter_identifier_tuple = AliasSeq!(); } } template FunctionTypeOf(alias func) - if (isCallable!func) + if (is_callable!func) { static if ((is(typeof(& func) Fsym : Fsym*) && is(Fsym == function)) || is(typeof(& func) Fsym == delegate)) alias FunctionTypeOf = Fsym; // HIT: (nested) function symbol @@ -218,27 +218,29 @@ template FunctionTypeOf(alias func) } // is T a primitive/builtin type? -enum isPrimitive(T) = isIntegral!T || isSomeFloat!T || (isEnum!T && isPrimitive!(enumType!T) || - is(T == P*, P) || is(T == S[], S) || (is(T == A[N], A, size_t N) && isPrimitive!A) || +enum is_primitive(T) = is_integral!T || is_some_float!T || (is_enum!T && is_primitive!(EnumType!T) || + is(T == P*, P) || is(T == S[], S) || (is(T == A[N], A, size_t N) && is_primitive!A) || is(T == R function(Args), R, Args...) || is(T == R delegate(Args), R, Args...)); -enum isDefaultConstructible(T) = isPrimitive!T || (is(T == struct) && __traits(compiles, { T t; })); +enum is_trivial(T) = __traits(isPOD, T); -enum isConstructible(T, Args...) = (isPrimitive!T && (Args.length == 0 || (Args.length == 1 && is(Args[0] : T)))) || +enum is_default_constructible(T) = is_primitive!T || (is(T == struct) && __traits(compiles, { T t; })); + +enum is_constructible(T, Args...) = (is_primitive!T && (Args.length == 0 || (Args.length == 1 && is(Args[0] : T)))) || (is(T == struct) && __traits(compiles, (Args args) { T x = T(args); })); // this probably fails if the struct can't be assigned to x... TODO: use placement new? // TODO: we need to know it's not calling an elaborate constructor... -//enum isTriviallyConstructible(T, Args...) = (isPrimitive!T && (Args.length == 0 || (Args.length == 1 && is(Args[0] : T)))) || -// (is(T == struct) && __traits(compiles, (Args args) { auto x = T(args); })); // this probably fails if the struct can't be assigned to x... TODO: use placement new? +//enum is_trivially_constructible(T, Args...) = (is_primitive!T && (Args.length == 0 || (Args.length == 1 && is(Args[0] : T)))) || +// (is(T == struct) && __traits(compiles, (Args args) { auto x = T(args); })); // this probably fails if the struct can't be assigned to x... TODO: use placement new? -//enum isCopyConstructible(T) = isPrimitive!T || (is(T == struct) && __traits(compiles, { T u = lvalueOf!T; })); -//enum isMoveConstructible(T) = isPrimitive!T || (is(T == struct) && __traits(compiles, { T u = rvalueOf!T; })); +//enum is_copy_constructible(T) = is_primitive!T || (is(T == struct) && __traits(compiles, { T u = lvalue_of!T; })); +//enum is_move_constructible(T) = is_primitive!T || (is(T == struct) && __traits(compiles, { T u = rvalue_of!T; })); -enum isTriviallyDefaultConstructible(T) = isDefaultConstructible!T; // dlang doesn't have elaborate default constructors (YET...) -//enum isTriviallyCopyConstructible(T) = isPrimitive!T; // TODO: somehow find out if there is no copy constructor -//enum isTriviallyMoveConstructible(T) = isPrimitive!T || is(T == struct); // TODO: somehow find out if there is no move constructor +enum is_trivially_default_constructible(T) = is_default_constructible!T; // dlang doesn't have elaborate default constructors (YET...) +//enum is_trivially_copy_constructible(T) = is_primitive!T; // TODO: somehow find out if there is no copy constructor +//enum is_trivially_move_constructible(T) = is_primitive!T || is(T == struct); // TODO: somehow find out if there is no move constructor // helpers to test certain expressions private struct __InoutWorkaroundStruct{} -@property T rvalueOf(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init) pure nothrow @nogc; -@property ref T lvalueOf(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init) pure nothrow @nogc; +@property T rvalue_of(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init) pure nothrow @nogc; +@property ref T lvalue_of(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init) pure nothrow @nogc; diff --git a/src/urt/util.d b/src/urt/util.d index 044f47f..4971ddd 100644 --- a/src/urt/util.d +++ b/src/urt/util.d @@ -30,33 +30,33 @@ pure: auto min(T, U)(auto ref inout T a, auto ref inout U b) { - return a < b ? a : b; + return b < a ? b : a; } auto max(T, U)(auto ref inout T a, auto ref inout U b) { - return a > b ? a : b; + return b > a ? b : a; } template Align(size_t value, size_t alignment = size_t.sizeof) { - static assert(isPowerOf2(alignment), "Alignment must be a power of two: ", alignment); + static assert(is_power_of_2(alignment), "Alignment must be a power of two: ", alignment); enum Align = alignTo(value, alignment); } -enum IsAligned(size_t value) = isAligned(value); -enum IsPowerOf2(size_t value) = isPowerOf2(value); -enum NextPowerOf2(size_t value) = nextPowerOf2(value); +enum IsAligned(size_t value) = is_aligned(value); +enum IsPowerOf2(size_t value) = is_power_of_2(value); +enum NextPowerOf2(size_t value) = next_power_of_2(value); -bool isPowerOf2(T)(T x) - if (isSomeInt!T) +bool is_power_of_2(T)(T x) + if (is_some_int!T) { return (x & (x - 1)) == 0; } -T nextPowerOf2(T)(T x) - if (isSomeInt!T) +T next_power_of_2(T)(T x) + if (is_some_int!T) { x -= 1; x |= x >> 1; @@ -71,43 +71,81 @@ T nextPowerOf2(T)(T x) return cast(T)(x + 1); } -T alignDown(size_t alignment, T)(T value) - if (isSomeInt!T || is(T == U*, U)) +T align_down(size_t alignment, T)(T value) + if (is_some_int!T || is(T == U*, U)) { return cast(T)(cast(size_t)value & ~(alignment - 1)); } -T alignDown(T)(T value, size_t alignment) - if (isSomeInt!T || is(T == U*, U)) +T align_down(T)(T value, size_t alignment) + if (is_some_int!T || is(T == U*, U)) { return cast(T)(cast(size_t)value & ~(alignment - 1)); } -T alignUp(size_t alignment, T)(T value) - if (isSomeInt!T || is(T == U*, U)) +T align_up(size_t alignment, T)(T value) + if (is_some_int!T || is(T == U*, U)) { return cast(T)((cast(size_t)value + (alignment - 1)) & ~(alignment - 1)); } -T alignUp(T)(T value, size_t alignment) - if (isSomeInt!T || is(T == U*, U)) +T align_up(T)(T value, size_t alignment) + if (is_some_int!T || is(T == U*, U)) { return cast(T)((cast(size_t)value + (alignment - 1)) & ~(alignment - 1)); } -bool isAligned(size_t alignment, T)(T value) - if (isSomeInt!T || is(T == U*, U)) +bool is_aligned(size_t alignment, T)(T value) + if (is_some_int!T || is(T == U*, U)) { - static assert(IsPowerOf2!alignment, "Alignment must be a power of two!"); + static assert(IsPowerOf2!alignment, "Alignment must be a power of two"); + static assert(T.sizeof <= size_t.sizeof, "TODO"); return (cast(size_t)value & (alignment - 1)) == 0; } -bool isAligned(T)(T value, size_t alignment) - if (isSomeInt!T || is(T == U*, U)) +bool is_aligned(T)(T value, size_t alignment) + if (is_some_int!T || is(T == U*, U)) { + static assert(T.sizeof <= size_t.sizeof, "TODO"); return (cast(size_t)value & (alignment - 1)) == 0; } +T rol(T)(const T value, const uint count) pure + if (__traits(isIntegral, T) && __traits(isUnsigned, T)) +{ + assert(count < 8 * T.sizeof); + if (count == 0) + return cast(T)value; + return cast(T)((value << count) | (value >> (T.sizeof * 8 - count))); +} + +T ror(T)(const T value, const uint count) pure + if (__traits(isIntegral, T) && __traits(isUnsigned, T)) +{ + assert(count < 8 * T.sizeof); + if (count == 0) + return cast(T)value; + return cast(T)((value >> count) | (value << (T.sizeof * 8 - count))); +} + +T rol(uint count, T)(const T value) pure + if (__traits(isIntegral, T) && __traits(isUnsigned, T)) +{ + static assert(count < 8 * T.sizeof); + static if (count == 0) + return cast(T)value; + return cast(T)((value << count) | (value >> (T.sizeof * 8 - count))); +} + +T ror(uint count, T)(const T value) pure + if (__traits(isIntegral, T) && __traits(isUnsigned, T)) +{ + static assert(count < 8 * T.sizeof); + static if (count == 0) + return cast(T)value; + return cast(T)((value >> count) | (value << (T.sizeof * 8 - count))); +} + /+ ubyte log2(ubyte val) { @@ -140,7 +178,7 @@ ubyte log2(ubyte val) } ubyte log2(T)(T val) - if (isSomeInt!T && T.sizeof > 1) + if (is_some_int!T && T.sizeof > 1) { if (T.sizeof > 4 && val >> 32) { @@ -172,7 +210,7 @@ ubyte log2(T)(T val) +/ ubyte log2(T)(T x) - if (isIntegral!T) + if (is_integral!T) { ubyte result = 0; static if (T.sizeof > 4) @@ -201,7 +239,7 @@ ubyte log2(T)(T x) } ubyte clz(bool nonZero = false, T)(T x) - if (isIntegral!T) + if (is_integral!T) { static if (nonZero) debug assert(x != 0); @@ -270,7 +308,7 @@ ubyte clz(T : bool)(T x) => x ? 7 : 8; ubyte ctz(bool nonZero = false, T)(T x) - if (isIntegral!T) + if (is_integral!T) { static if (nonZero) debug assert(x != 0); @@ -378,7 +416,7 @@ ubyte ctz(T : bool)(T x) => x ? 0 : 8; ubyte popcnt(T)(T x) - if (isIntegral!T) + if (is_integral!T) { if (__ctfe || !IS_LDC_OR_GDC) { @@ -410,9 +448,9 @@ ubyte popcnt(T)(T x) ubyte popcnt(T : bool)(T x) => x ? 1 : 0; -ubyte byteReverse(ubyte v) +ubyte byte_reverse(ubyte v) => v; -ushort byteReverse(ushort v) +ushort byte_reverse(ushort v) { if (__ctfe || !IS_LDC_OR_GDC) return cast(ushort)((v << 8) | (v >> 8)); @@ -421,7 +459,7 @@ ushort byteReverse(ushort v) else assert(false, "Unreachable"); } -uint byteReverse(uint v) +uint byte_reverse(uint v) { if (__ctfe || !IS_LDC_OR_GDC) return cast(uint)((v << 24) | ((v & 0xFF00) << 8) | ((v >> 8) & 0xFF00) | (v >> 24)); @@ -430,7 +468,7 @@ uint byteReverse(uint v) else assert(false, "Unreachable"); } -ulong byteReverse(ulong v) +ulong byte_reverse(ulong v) { if (__ctfe || !IS_LDC_OR_GDC) return cast(ulong)((v << 56) | ((v & 0xFF00) << 40) | ((v & 0xFF0000) << 24) | ((v & 0xFF000000) << 8) | ((v >> 8) & 0xFF000000) | ((v >> 24) & 0xFF0000) | ((v >> 40) & 0xFF00) | (v >> 56)); @@ -439,17 +477,17 @@ ulong byteReverse(ulong v) else assert(false, "Unreachable"); } -pragma(inline, true) T byteReverse(T)(T val) - if (!isIntegral!T) +pragma(inline, true) T byte_reverse(T)(T val) + if (!is_integral!T) { - import urt.meta : intForWidth; - alias U = intForWidth!(T.sizeof*8); - U r = byteReverse(*cast(U*)&val); + import urt.meta : IntForWidth; + alias U = IntForWidth!(T.sizeof*8); + U r = byte_reverse(*cast(U*)&val); return *cast(T*)&r; } -T bitReverse(T)(T x) - if (isSomeInt!T) +T bit_reverse(T)(T x) + if (is_some_int!T) { if (__ctfe || !IS_LDC) { @@ -458,7 +496,7 @@ T bitReverse(T)(T x) // TODO: these may be inferior on platforms where mul is slow... static if (size_t.sizeof == 8) { - // return cast(ubyte)((b*0x0202020202ULL & 0x010884422010ULL) % 1023; // only 3 ops, but uses div! +// return cast(ubyte)((b*0x0202020202ULL & 0x010884422010ULL) % 1023; // only 3 ops, but uses div! return cast(ubyte)(cast(ulong)(x*0x80200802UL & 0x0884422110)*0x0101010101 >> 32); } else @@ -476,7 +514,84 @@ T bitReverse(T)(T x) static if (T.sizeof == 1) return x; else - return byteReverse(x); + return byte_reverse(x); + } + } + else static if (false) // TODO: DMD, x86, 4 or 8 bytes... + { + static if (T.sizeof == 4) + { + asm pure nothrow @nogc { naked; } + + version (D_InlineAsm_X86_64) + { + version (Win64) + asm pure nothrow @nogc { mov EAX, ECX; } + else + asm pure nothrow @nogc { mov EAX, EDI; } + } + + asm pure nothrow @nogc + { + mov EDX, EAX; + shr EAX, 1; + and EDX, 0x5555_5555; + and EAX, 0x5555_5555; + shl EDX, 1; + or EAX, EDX; + mov EDX, EAX; + shr EAX, 2; + and EDX, 0x3333_3333; + and EAX, 0x3333_3333; + shl EDX, 2; + or EAX, EDX; + mov EDX, EAX; + shr EAX, 4; + and EDX, 0x0f0f_0f0f; + and EAX, 0x0f0f_0f0f; + shl EDX, 4; + or EAX, EDX; + bswap EAX; + ret; + } + } + else + { + asm pure nothrow @nogc { naked; } + + version (Win64) + asm pure nothrow @nogc { mov RAX, RCX; } + else + asm pure nothrow @nogc { mov RAX, RDI; } + + asm pure nothrow @nogc + { + mov RDX, RAX; + shr RAX, 1; + mov RCX, 0x5555_5555_5555_5555L; + and RDX, RCX; + and RAX, RCX; + shl RDX, 1; + or RAX, RDX; + + mov RDX, RAX; + shr RAX, 2; + mov RCX, 0x3333_3333_3333_3333L; + and RDX, RCX; + and RAX, RCX; + shl RDX, 2; + or RAX, RDX; + + mov RDX, RAX; + shr RAX, 4; + mov RCX, 0x0f0f_0f0f_0f0f_0f0fL; + and RDX, RCX; + and RAX, RCX; + shl RDX, 4; + or RAX, RDX; + bswap RAX; + ret; + } } } else @@ -531,39 +646,39 @@ unittest assert(x.swap(y) == 10); assert(x.swap(30) == 20); - static assert(isPowerOf2(0) == true); - static assert(isPowerOf2(1) == true); - static assert(isPowerOf2(2) == true); - static assert(isPowerOf2(3) == false); - static assert(isPowerOf2(4) == true); - static assert(isPowerOf2(5) == false); - static assert(isPowerOf2(ulong(uint.max) + 1) == true); - static assert(isPowerOf2(ulong.max) == false); - assert(isPowerOf2(0) == true); - assert(isPowerOf2(1) == true); - assert(isPowerOf2(2) == true); - assert(isPowerOf2(3) == false); - assert(isPowerOf2(4) == true); - assert(isPowerOf2(5) == false); - assert(isPowerOf2(ulong(uint.max) + 1) == true); - assert(isPowerOf2(ulong.max) == false); - - static assert(nextPowerOf2(0) == 0); - static assert(nextPowerOf2(1) == 1); - static assert(nextPowerOf2(2) == 2); - static assert(nextPowerOf2(3) == 4); - static assert(nextPowerOf2(4) == 4); - static assert(nextPowerOf2(5) == 8); - static assert(nextPowerOf2(uint.max) == 0); - static assert(nextPowerOf2(ulong(uint.max)) == ulong(uint.max) + 1); - assert(nextPowerOf2(0) == 0); - assert(nextPowerOf2(1) == 1); - assert(nextPowerOf2(2) == 2); - assert(nextPowerOf2(3) == 4); - assert(nextPowerOf2(4) == 4); - assert(nextPowerOf2(5) == 8); - assert(nextPowerOf2(uint.max) == 0); - assert(nextPowerOf2(ulong(uint.max)) == ulong(uint.max) + 1); + static assert(is_power_of_2(0) == true); + static assert(is_power_of_2(1) == true); + static assert(is_power_of_2(2) == true); + static assert(is_power_of_2(3) == false); + static assert(is_power_of_2(4) == true); + static assert(is_power_of_2(5) == false); + static assert(is_power_of_2(ulong(uint.max) + 1) == true); + static assert(is_power_of_2(ulong.max) == false); + assert(is_power_of_2(0) == true); + assert(is_power_of_2(1) == true); + assert(is_power_of_2(2) == true); + assert(is_power_of_2(3) == false); + assert(is_power_of_2(4) == true); + assert(is_power_of_2(5) == false); + assert(is_power_of_2(ulong(uint.max) + 1) == true); + assert(is_power_of_2(ulong.max) == false); + + static assert(next_power_of_2(0) == 0); + static assert(next_power_of_2(1) == 1); + static assert(next_power_of_2(2) == 2); + static assert(next_power_of_2(3) == 4); + static assert(next_power_of_2(4) == 4); + static assert(next_power_of_2(5) == 8); + static assert(next_power_of_2(uint.max) == 0); + static assert(next_power_of_2(ulong(uint.max)) == ulong(uint.max) + 1); + assert(next_power_of_2(0) == 0); + assert(next_power_of_2(1) == 1); + assert(next_power_of_2(2) == 2); + assert(next_power_of_2(3) == 4); + assert(next_power_of_2(4) == 4); + assert(next_power_of_2(5) == 8); + assert(next_power_of_2(uint.max) == 0); + assert(next_power_of_2(ulong(uint.max)) == ulong(uint.max) + 1); static assert(log2(ubyte(0)) == 0); static assert(log2(ubyte(1)) == 0); @@ -677,50 +792,50 @@ unittest assert(popcnt(true) == 1); assert(popcnt('D') == 2); // 0x44 - static assert(bitReverse(ubyte(0)) == 0); - static assert(bitReverse(ubyte(1)) == 128); - static assert(bitReverse(ubyte(2)) == 64); - static assert(bitReverse(ubyte(3)) == 192); - static assert(bitReverse(ubyte(4)) == 32); - static assert(bitReverse(ubyte(5)) == 160); - static assert(bitReverse(ubyte(6)) == 96); - static assert(bitReverse(ubyte(7)) == 224); - static assert(bitReverse(ubyte(8)) == 16); - static assert(bitReverse(ubyte(255)) == 255); - static assert(bitReverse(ushort(0b1101100010000000)) == 0b0000000100011011); - static assert(bitReverse(uint(0x73810000)) == 0x000081CE); - static assert(bitReverse(ulong(0x7381000000000000)) == 0x00000000000081CE); - assert(bitReverse(ubyte(0)) == 0); - assert(bitReverse(ubyte(1)) == 128); - assert(bitReverse(ubyte(2)) == 64); - assert(bitReverse(ubyte(3)) == 192); - assert(bitReverse(ubyte(4)) == 32); - assert(bitReverse(ubyte(5)) == 160); - assert(bitReverse(ubyte(6)) == 96); - assert(bitReverse(ubyte(7)) == 224); - assert(bitReverse(ubyte(8)) == 16); - assert(bitReverse(ubyte(255)) == 255); - assert(bitReverse(ushort(0b1101100010000000)) == 0b0000000100011011); - assert(bitReverse(uint(0x73810000)) == 0x000081CE); - assert(bitReverse(ulong(0x7381000000000000)) == 0x00000000000081CE); - - static assert(byteReverse(0x12) == 0x12); - static assert(byteReverse(0x1234) == 0x3412); - static assert(byteReverse(0x12345678) == 0x78563412); - static assert(byteReverse(0x123456789ABCDEF0) == 0xF0DEBC9A78563412); - static assert(byteReverse(true) == true); - static assert(byteReverse(char(0x12)) == char(0x12)); - static assert(byteReverse(wchar(0x1234)) == wchar(0x3412)); - static assert(byteReverse(cast(dchar)0x12345678) == cast(dchar)0x78563412); - assert(byteReverse(0x12) == 0x12); - assert(byteReverse(0x1234) == 0x3412); - assert(byteReverse(0x12345678) == 0x78563412); - assert(byteReverse(0x123456789ABCDEF0) == 0xF0DEBC9A78563412); - assert(byteReverse(true) == true); - assert(byteReverse(char(0x12)) == char(0x12)); - assert(byteReverse(wchar(0x1234)) == wchar(0x3412)); - assert(byteReverse(cast(dchar)0x12345678) == cast(dchar)0x78563412); + static assert(bit_reverse(ubyte(0)) == 0); + static assert(bit_reverse(ubyte(1)) == 128); + static assert(bit_reverse(ubyte(2)) == 64); + static assert(bit_reverse(ubyte(3)) == 192); + static assert(bit_reverse(ubyte(4)) == 32); + static assert(bit_reverse(ubyte(5)) == 160); + static assert(bit_reverse(ubyte(6)) == 96); + static assert(bit_reverse(ubyte(7)) == 224); + static assert(bit_reverse(ubyte(8)) == 16); + static assert(bit_reverse(ubyte(255)) == 255); + static assert(bit_reverse(ushort(0b1101100010000000)) == 0b0000000100011011); + static assert(bit_reverse(uint(0x73810000)) == 0x000081CE); + static assert(bit_reverse(ulong(0x7381000000000000)) == 0x00000000000081CE); + assert(bit_reverse(ubyte(0)) == 0); + assert(bit_reverse(ubyte(1)) == 128); + assert(bit_reverse(ubyte(2)) == 64); + assert(bit_reverse(ubyte(3)) == 192); + assert(bit_reverse(ubyte(4)) == 32); + assert(bit_reverse(ubyte(5)) == 160); + assert(bit_reverse(ubyte(6)) == 96); + assert(bit_reverse(ubyte(7)) == 224); + assert(bit_reverse(ubyte(8)) == 16); + assert(bit_reverse(ubyte(255)) == 255); + assert(bit_reverse(ushort(0b1101100010000000)) == 0b0000000100011011); + assert(bit_reverse(uint(0x73810000)) == 0x000081CE); + assert(bit_reverse(ulong(0x7381000000000000)) == 0x00000000000081CE); + + static assert(byte_reverse(0x12) == 0x12); + static assert(byte_reverse(0x1234) == 0x3412); + static assert(byte_reverse(0x12345678) == 0x78563412); + static assert(byte_reverse(0x123456789ABCDEF0) == 0xF0DEBC9A78563412); + static assert(byte_reverse(true) == true); + static assert(byte_reverse(char(0x12)) == char(0x12)); + static assert(byte_reverse(wchar(0x1234)) == wchar(0x3412)); + static assert(byte_reverse(cast(dchar)0x12345678) == cast(dchar)0x78563412); + assert(byte_reverse(0x12) == 0x12); + assert(byte_reverse(0x1234) == 0x3412); + assert(byte_reverse(0x12345678) == 0x78563412); + assert(byte_reverse(0x123456789ABCDEF0) == 0xF0DEBC9A78563412); + assert(byte_reverse(true) == true); + assert(byte_reverse(char(0x12)) == char(0x12)); + assert(byte_reverse(wchar(0x1234)) == wchar(0x3412)); + assert(byte_reverse(cast(dchar)0x12345678) == cast(dchar)0x78563412); float frev; *cast(uint*)&frev = 0x0000803F; - assert(byteReverse(1.0f) is frev); + assert(byte_reverse(1.0f) is frev); } diff --git a/src/urt/uuid.d b/src/urt/uuid.d new file mode 100644 index 0000000..f92967c --- /dev/null +++ b/src/urt/uuid.d @@ -0,0 +1,91 @@ +module urt.uuid; + +import urt.conv : format_uint, parse_uint; +import urt.string.format : FormatArg; + +nothrow @nogc: + +enum GUID UUID(string s) = () { UUID g; ptrdiff_t n = g.fromString(s); assert(n == s.length, "Not a valid GUID/UUID"); return g; }(); + +struct GUID +{ +nothrow @nogc: +align(1): + uint data1; + ushort data2; + ushort data3; + ubyte[8] data4; + + bool opEquals(ref const GUID rh) const pure + => data1 == rh.data1 && data2 == rh.data2 && data3 == rh.data3 && data4 == rh.data4; + + bool opCast(T : bool)() const pure + => data1 != 0 || data2 != 0 || data3 != 0 || data4 != typeof(data4).init; + + // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + ptrdiff_t toString(char[] buf, const(char)[], const(FormatArg)[]) const pure + { + import urt.string.ascii : hex_digits; + if (!buf.ptr) + return 36; + if (buf.length < 36) + return -1; + format_uint(data1, buf[0 .. 8], 16, 8, '0'); + buf[8] = '-'; + format_uint(data2, buf[9 .. 13], 16, 4, '0'); + buf[13] = '-'; + format_uint(data3, buf[14 .. 18], 16, 4, '0'); + buf[18] = '-'; + buf[19] = hex_digits[data4[0] >> 4]; + buf[20] = hex_digits[data4[0] & 0xf]; + buf[21] = hex_digits[data4[1] >> 4]; + buf[22] = hex_digits[data4[1] & 0xf]; + buf[23] = '-'; + buf[24] = hex_digits[data4[2] >> 4]; + buf[25] = hex_digits[data4[2] & 0xf]; + buf[26] = hex_digits[data4[3] >> 4]; + buf[27] = hex_digits[data4[3] & 0xf]; + buf[28] = hex_digits[data4[4] >> 4]; + buf[29] = hex_digits[data4[4] & 0xf]; + buf[30] = hex_digits[data4[5] >> 4]; + buf[31] = hex_digits[data4[5] & 0xf]; + buf[32] = hex_digits[data4[6] >> 4]; + buf[33] = hex_digits[data4[6] & 0xf]; + buf[34] = hex_digits[data4[7] >> 4]; + buf[35] = hex_digits[data4[7] & 0xf]; + return 36; + } + + ptrdiff_t fromString(const(char)[] s) pure + { + if (s.length < 36 || s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-') + return -1; + size_t n; + ulong d1 = s[0 .. 8].parse_uint(&n, 16); if (n != 8) return -1; + ulong d2 = s[9 .. 13].parse_uint(&n, 16); if (n != 4) return -1; + ulong d3 = s[14 .. 18].parse_uint(&n, 16); if (n != 4) return -1; + data1 = cast(uint)d1; + data2 = cast(ushort)d2; + data3 = cast(ushort)d3; + foreach (i; 0 .. 8) + { + size_t off = i < 2 ? 19 + i*2 : 20 + i*2; + ulong b = s[off .. off + 2].parse_uint(&n, 16); + if (n != 2) + return -1; + data4[i] = cast(ubyte)b; + } + return 36; + } + + debug auto __debugOverview() + { + import urt.mem; + char[] buf = debug_alloc!char(36); + toString(buf, null, null); + return buf[0 .. 36]; + } +} + +static assert(GUID.sizeof == 16); +static assert(GUID.alignof == 1); diff --git a/src/urt/variant.d b/src/urt/variant.d index 9f5fe2c..c7e571f 100644 --- a/src/urt/variant.d +++ b/src/urt/variant.d @@ -1,22 +1,34 @@ module urt.variant; +import urt.algorithm : compare; import urt.array; +import urt.attribute : fast_data; +import urt.conv; import urt.kvp; import urt.lifetime; import urt.map; +import urt.mem.allocator; +import urt.meta.enuminfo : enum_info, VoidEnumInfo; import urt.si.quantity; -import urt.si.unit : ScaledUnit; +import urt.si.unit : ScaledUnit, Second, Nanosecond; +import urt.string; +import urt.time; import urt.traits; +import urt.util : swap; nothrow @nogc: enum ValidUserType(T) = (is(T == struct) || is(T == class)) && + is(Unqual!T == T) && !is(T == Variant) && !is(T == VariantKVP) && !is(T == Array!U, U) && !is(T : const(char)[]) && - !is(T == Quantity!(T, U), T, alias U); + !is(T == Quantity!(T, U), T, alias U) && + !is(T == Duration) && + !is(T == String) && + !is(T == MutableString!N, size_t N); alias VariantKVP = KVP!(const(char)[], Variant); @@ -31,14 +43,91 @@ nothrow @nogc: if (rh.type == Type.Map || rh.type == Type.Array) { Array!Variant arr = rh.nodeArray; - takeNodeArray(arr); + take_node_array(arr); + flags = rh.flags; + } + else if ((rh.flags & Flags.NeedDestruction) == 0) + { + __pack = rh.__pack; + } + else if (rh.isString) + { + new(*cast(String*)&value.s) String(*cast(String*)&rh.value.s); + count = rh.count; + flags = rh.flags; + } + else if (rh.isBuffer) + { + ptr = defaultAllocator.alloc(rh.count).ptr; + ptr[0 .. rh.count] = rh.ptr[0 .. rh.count]; + count = rh.count; + flags = rh.flags; + } + else if (rh.isUserType) + { + ref const TypeDetails td = (rh.flags & Flags.Embedded) ? find_type_details(rh.alloc) : g_type_details[rh.alloc]; + assert(td.copy_emplace !is null, "User type has no copy_emplace"); + if (rh.flags & Flags.Embedded) + td.copy_emplace(rh.embed.ptr, embed.ptr, false); + else + { + void* mem = defaultAllocator.alloc(td.size, td.alignment).ptr; + td.copy_emplace(rh.ptr, mem, false); + ptr = mem; + } + count = rh.count; + alloc = rh.alloc; flags = rh.flags; } else + assert(false, "What kind of thing is this?"); + } + + this(ref const Variant rh) inout + { + if (rh.type == Type.Map || rh.type == Type.Array) + { + auto arr = Array!Variant(Reserve, rh.nodeArray.length); + foreach (ref i; rh.nodeArray) + arr.pushBack(i); + flags = rh.flags; + } + else if ((rh.flags & Flags.NeedDestruction) == 0) { - assert((rh.flags & Flags.NeedDestruction) == 0); __pack = rh.__pack; } + else if (rh.isString) + { + new(*cast(String*)&value.s) String(*cast(String*)&rh.value.s); + count = rh.count; + flags = rh.flags; + } + else if (rh.isBuffer) + { + void* mem = defaultAllocator.alloc(rh.count).ptr; + mem[0 .. rh.count] = rh.ptr[0 .. rh.count]; + ptr = cast(inout(void)*)mem; + count = rh.count; + flags = rh.flags; + } + else if (rh.isUserType) + { + ref const TypeDetails td = (rh.flags & Flags.Embedded) ? find_type_details(rh.alloc) : g_type_details[rh.alloc]; + assert(td.copy_emplace !is null, "User type has no copy_emplace"); + if (rh.flags & Flags.Embedded) + td.copy_emplace(cast(void*)rh.embed.ptr, cast(void*)embed.ptr, false); + else + { + void* mem = defaultAllocator.alloc(td.size, td.alignment).ptr; + td.copy_emplace(cast(void*)rh.ptr, mem, false); + ptr = cast(inout(void)*)mem; + } + count = rh.count; + alloc = rh.alloc; + flags = rh.flags; + } + else + assert(false, "What kind of thing is this?"); } version (EnableMoveSemantics) { @@ -65,85 +154,150 @@ nothrow @nogc: } this(I)(I i) - if (is(I == byte) || is(I == short)) - { - flags = Flags.NumberInt; - value.l = i; - if (i >= 0) - flags |= Flags.UintFlag | Flags.Uint64Flag; - } - this(I)(I i) - if (is(I == ubyte) || is(I == ushort)) + if (is_some_int!I) { - flags = cast(Flags)(Flags.NumberUint | Flags.IntFlag); - value.ul = i; + static if (is_signed_int!I) + value.l = i; + else + value.ul = i; + + static if (is(I == ubyte) || is(I == ushort)) + flags = cast(Flags)(Flags.NumberUint | Flags.IntFlag | Flags.Int64Flag); + else static if (is(I == byte) || is(I == short) || is(I == int)) + { + flags = Flags.NumberInt; + if (i >= 0) + flags |= Flags.UintFlag | Flags.Uint64Flag; + } + else static if (is(I == uint)) + { + flags = Flags.NumberUint; + if (i <= int.max) + flags |= Flags.IntFlag; + } + else static if (is(I == long)) + { + flags = Flags.NumberInt64; + if (i >= 0) + { + flags |= Flags.Uint64Flag; + if (i <= int.max) + flags |= Flags.IntFlag | Flags.UintFlag; + else if (i <= uint.max) + flags |= Flags.UintFlag; + } + else if (i >= int.min) + flags |= Flags.IntFlag; + } + else static if (is(I == ulong)) + { + flags = Flags.NumberUint64; + if (i <= int.max) + flags |= Flags.IntFlag | Flags.UintFlag | Flags.Int64Flag; + else if (i <= uint.max) + flags |= Flags.UintFlag | Flags.Int64Flag; + else if (i <= long.max) + flags |= Flags.Int64Flag; + } } - this(int i) + this(F)(F f) + if (is_some_float!F) { - flags = Flags.NumberInt; - value.l = i; - if (i >= 0) - flags |= Flags.UintFlag | Flags.Uint64Flag; + import urt.math : float_is_integer; + + if (int sign = float_is_integer(f, value.ul)) + { + if (sign < 0) + { + flags = Flags.NumberInt64; + if (value.l >= int.min) + flags |= Flags.IntFlag; + } + else + { + flags = Flags.NumberUint64; + if (value.ul <= int.max) + flags |= Flags.IntFlag | Flags.UintFlag | Flags.Int64Flag; + else if (value.ul <= uint.max) + flags |= Flags.UintFlag | Flags.Int64Flag; + else if (value.ul <= long.max) + flags |= Flags.Int64Flag; + } + } + else + { + static if (is(F == float)) + flags = Flags.NumberFloat; + else + flags = Flags.NumberDouble; + value.d = f; + } } - this(uint i) + this(E)(const E e) + if (is(E == enum)) { - flags = Flags.NumberUint; - value.ul = i; - if (i <= int.max) - flags |= Flags.IntFlag; + static if (is(E T == enum)) + this(T(e), enum_info!E.make_void()); } - this(long i) + this(T)(T value, const(VoidEnumInfo)* e) { - flags = Flags.NumberInt64; - value.l = i; - if (i >= 0) + static assert(!is(T == enum), "T should be a numeric type"); + + this(value); + static if (size_t.sizeof == 8) { - flags |= Flags.Uint64Flag; - if (i <= int.max) - flags |= Flags.IntFlag | Flags.UintFlag; - else if (i <= uint.max) - flags |= Flags.UintFlag; + size_t ptr = cast(size_t)e; + assert((ptr >> 48) == 0, "Uh on! High ptr bits set... we must be in the distant future!"); + count = cast(uint)ptr; + alloc = cast(ushort)(ptr >> 32); } - else if (i >= int.min) - flags |= Flags.IntFlag; + else + count = cast(size_t)e; + flags |= Flags.Enum; } - this(ulong i) + this(U, ScaledUnit _U)(Quantity!(U, _U) q) { - flags = Flags.NumberUint64; - value.ul = i; - if (i <= int.max) - flags |= Flags.IntFlag | Flags.UintFlag | Flags.Int64Flag; - else if (i <= uint.max) - flags |= Flags.UintFlag | Flags.Int64Flag; - else if (i <= long.max) - flags |= Flags.Int64Flag; + this(q.value); + count = q.unit.pack; } - this(float f) + this(Duration dur) { - flags = Flags.NumberFloat; - value.d = f; + this(dur.as!"nsecs"); + count = Nanosecond.pack; } - this(double d) + + this(String s) { - flags = Flags.NumberDouble; - value.d = d; + if (s.empty) + { + flags = Flags.Null; + return; + } + flags = Flags.String; + value.s = s.ptr; + count = s.length; + if (s.has_rc()) + flags |= Flags.NeedDestruction; + s.ptr = null; } - this(U, ScaledUnit _U)(Quantity!(U, _U) q) + this(size_t N)(MutableString!N s) { - this(q.value); - flags |= Flags.IsQuantity; - count = q.unit.pack; + this(String(s.move)); } - this(const(char)[] s) // TODO: (S)(S s) -// if (is(S : const(char)[])) + this(const(char)[] s) { + if (s.length == 0) + { + flags = Flags.Null; + return; + } if (s.length < embed.length) { flags = Flags.ShortString; @@ -152,17 +306,43 @@ nothrow @nogc: return; } flags = Flags.String; - value.s = s.ptr; + flags |= Flags.NeedDestruction; + String t = s.makeString(defaultAllocator); + value.s = t.ptr.swap(null); count = cast(uint)s.length; } + this(T)(T[] buffer) + if (is(Unqual!T == void)) + { + if (buffer.length == 0) + { + flags = Flags.Null; + return; + } + if (buffer.length < embed.length) + { + flags = Flags.ShortBuffer; + embed[0 .. buffer.length] = cast(char[])buffer[]; + embed[$-1] = cast(ubyte)buffer.length; + return; + } + flags = Flags.Buffer; + flags |= Flags.NeedDestruction; + void[] mem = defaultAllocator.alloc(buffer.length); + mem[] = buffer[]; + ptr = mem.ptr; + count = cast(uint)buffer.length; + } + this(Variant[] a) { flags = Flags.Array; nodeArray = a[]; } + this(T)(T[] a) - if (!is(T == Variant) && !is(T == VariantKVP) && !is(T : dchar)) + if (!is(T == Variant) && !is(T == VariantKVP) && !is(T : dchar) && !is(Unqual!T == void)) { flags = Flags.Array; nodeArray.reserve(a.length); @@ -172,7 +352,7 @@ nothrow @nogc: this(Array!Variant a) { - takeNodeArray(a); + take_node_array(a); flags = Flags.Array; } @@ -203,25 +383,40 @@ nothrow @nogc: this(T)(auto ref T thing) if (ValidUserType!T) { - alias dummy = MakeTypeDetails!T; - - flags = Flags.User; - static if (is(T == class)) - { - count = UserTypeId!T; - value.p = cast(void*)&thing; - } - else static if (EmbedUserType!T) - { - flags |= Flags.Embedded; - alloc = UserTypeShortId!T; - emplace(cast(T*)embed.ptr, forward!thing); - } + static if (is(Unqual!T == MonoTime)) + this(cast(SysTime)thing); else { -// flags |= Flags.NeedDestruction; // if T has a destructor... - count = UserTypeId!T; - assert(false, "TODO: alloc for the object..."); + alias dummy = MakeTypeDetails!T; + + flags = Flags.User; + static if (is(T == class)) + { + count = UserTypeId!T; + alloc = type_detail_index!T(); + ptr = cast(void*)thing; + } + else static if (EmbedUserType!T) + { + alloc = UserTypeId!T; + flags |= Flags.Embedded; + + if (TypeDetailsFor!T.destroy) // TODO: we should check the same condition that determined if there is a destruct function... + flags |= Flags.NeedDestruction; + + emplace(cast(T*)embed.ptr, forward!thing); + } + else + { + count = UserTypeId!T; + alloc = type_detail_index!T(); + + if (TypeDetailsFor!T.destroy) // TODO: we should check the same condition that determined if there is a destruct function... + flags |= Flags.NeedDestruction; + + ptr = defaultAllocator().alloc(T.sizeof, T.alignof).ptr; + emplace(cast(T*)ptr, forward!thing); + } } } @@ -230,12 +425,35 @@ nothrow @nogc: destroy!false(); } + void opAssign(ref Variant value) + { + if (&this is &value) + return; // TODO: should this be an assert instead of a graceful handler? + destroy!false(); + new(this) Variant(value); + } + + void opAssign(ref const Variant value) + { + if (&this is &value) + return; // TODO: should this be an assert instead of a graceful handler? + destroy!false(); + new(this) Variant(value); + } + + version (EnableMoveSemantics) { + void opAssign(Variant value) + { + destroy!false(); + new(this) Variant(__rvalue(value)); // TODO: value.move + } + } + // TODO: since this is a catch-all, the error messages will be a bit shit // maybe we can find a way to constrain it to valid inputs? void opAssign(T)(auto ref T value) { - destroy!false(); - emplace(&this, forward!value); + this = Variant(value); } // TODO: do we want Variant to support +=, ~=, etc...? @@ -266,6 +484,228 @@ nothrow @nogc: return nodeArray.pushBack(); } + bool opEquals(ref const Variant rhs) const pure + { + return opCmp(rhs) == 0; + } + bool opEquals(T)(auto ref const T rhs) const + if (!is(T == Variant)) + { + // TODO: handle short-cut array/map comparisons? + static if (is(T == typeof(null))) + return type == Type.Null || ((type == Type.String || type == Type.Array || type == Type.Map) && empty()); + else static if (is(T == bool)) + { + if (!isBool) + return false; // do non-zero numbers evaluate true? what about non-zero strings? etc... + return asBool == rhs; + } + else static if (is_some_int!T || is_some_float!T) + { + if (!isNumber || isQuantity) + return false; + static if (is_some_int!T) if (!canFitInt!T) + return false; + return as!T == rhs; + } + else static if (is(T == Quantity!(U, _U), U, ScaledUnit _U)) + { + if (!isNumber) + return false; + return asQuantity!double() == rhs; + } + else static if (is(T E == enum)) + { + // TODO: should we also do string key comparisons? + return opEquals(cast(E)rhs); + } + else static if (is(T : const(char)[]) || is(T : const String) || is(T : const MutableString!N, size_t N)) + return isString && asString() == rhs[]; + else static if (ValidUserType!T) + return isUser!T && asUser!T == rhs; + else + static assert(false, "TODO: variant comparison with '", T.stringof, "' not supported"); + } + + int opCmp(ref const Variant rhs) const pure + { + const(Variant)* a, b; + bool invert = false; + if (this.type <= rhs.type) + a = &this, b = &rhs; + else + a = &rhs, b = &this, invert = true; + + int r = 0; + final switch (a.type) + { + case Type.Null: + if (b.type == Type.Null) + return 0; + else if ((b.type == Type.Buffer || b.type == Type.Array || b.type == Type.Map) && b.empty()) + return 0; + r = -1; // sort null before other things... + break; + + case Type.True: + case Type.False: + // if both sides are bool + if (b.type <= Type.False) + { + r = a.asBool - b.asBool; + break; + } + // TODO: maybe we don't want to accept bool/number comparison? + goto case; // we will compare bools with numbers... + + case Type.Number: + if (b.type <= Type.Number) + { + static double asDoubleWithBool(ref const Variant v) + => v.isBool() ? double(v.asBool()) : v.asDouble(); + + uint aunit = a.count; + uint bunit = b.count; + if (aunit || bunit) + { + // we can't compare different units + if ((aunit & 0xFFFFFF) != (bunit & 0xFFFFFF)) + { + r = (aunit & 0xFFFFFF) - (bunit & 0xFFFFFF); + break; + } + + // matching units, but we'll only do quantity comparison if there is some scaling + if ((aunit >> 24) != (bunit >> 24)) + { + VarQuantity aq = a.isNumber ? a.asQuantity!double() : VarQuantity(double(a.asBool())); + VarQuantity bq = b.isNumber ? b.asQuantity!double() : VarQuantity(double(b.asBool())); + r = aq.opCmp(bq); + break; + } + } + + if (a.flags & Flags.DoubleFlag || b.flags & Flags.DoubleFlag) + { + // float comparison + // TODO: determine if float/bool comparison seems right? is: -1 < false < 0.9 < true < 1.1? + double af = asDoubleWithBool(*a); + double bf = asDoubleWithBool(*b); + r = af < bf ? -1 : af > bf ? 1 : 0; + break; + } + + // TODO: this could be further optimised by comparing the value range flags... + if ((a.flags & (Flags.Int64Flag | Flags.IsBool)) == 0) + { + ulong aul = a.asUlong(); + if ((b.flags & (Flags.Int64Flag | Flags.IsBool)) == 0) + { + ulong bul = b.asUlong(); + r = aul < bul ? -1 : aul > bul ? 1 : 0; + } + else + r = 1; // a is in ulong range, rhs is not; a is larger... + break; + } + if ((b.flags & (Flags.Int64Flag | Flags.IsBool)) == 0) + { + r = -1; // b is in ulong range, lhs is not; b is larger... + break; + } + + long al = a.isBool() ? a.asBool() : a.asLong(); + long bl = b.isBool() ? b.asBool() : b.asLong(); + r = al < bl ? -1 : al > bl ? 1 : 0; + } + else + r = -1; // sort numbers before other things... + break; + + case Type.Buffer: + if (b.type != Type.Buffer) + { + r = -1; + break; + } + r = compare(cast(const(char)[])a.asBuffer(), cast(const(char)[])b.asBuffer()); + break; + + case Type.Array: + if (b.type != Type.Array) + { + r = -1; + break; + } + r = compare(a.asArray()[], b.asArray()[]); + break; + + case Type.Map: + if (b.type != Type.Map) + { + r = -1; + break; + } + assert(false, "TODO"); + break; + + case Type.User: + uint at = a.userType; + uint bt = b.userType; + if (at != bt) + { + r = at < bt ? -1 : at > bt ? 1 : 0; + break; + } + alias PureHack = ref TypeDetails function(uint index) pure nothrow @nogc; + if (flags & Flags.Embedded) + { + ref const TypeDetails td = (cast(PureHack)&find_type_details)(alloc); + r = td.cmp(a.embed.ptr, b.embed.ptr, 0); + } + else + { + ref const TypeDetails td = (cast(PureHack)&get_type_details)(alloc); + r = td.cmp(a.ptr, b.ptr, 0); + } + break; + } + return invert ? -r : r; + } + int opCmp(T)(auto ref const T rhs) const + if (!is(T == Variant)) + { + // TODO: handle short-cut string, array, map comparisons + static if (is(T == typeof(null))) + return type == Type.Null || ((type == Type.String || type == Type.Array || type == Type.Map) && empty()) ? 0 : 1; + else static if (is(T : const(char)[])) + return isString() ? compare(asString(), rhs) : (type < Type.String ? -1 : 1); + static if (ValidUserType!T) + return compare(asUser!T, rhs); + else + return opCmp(Variant(rhs)); + } + + bool opBinary(string op)(ref const Variant rhs) const pure + if (op == "is") + { + // compare that Variant's are identical, not just equivalent! + assert(false, "TODO"); + } + bool opBinary(string op, T)(auto ref const T rhs) const + if (op == "is") + { + // TODO: handle short-cut array/map comparisons? + static if (is(T == typeof(null))) + return type == Type.Null || ((type == Type.String || type == Type.Array || type == Type.Map) && empty()); + else static if (is(T : const(char)[])) + return isString && asString().ptr is rhs.ptr && length() == rhs.length; + else static if (ValidUserType!T) + return asUser!T is rhs; + else + return opBinary!"is"(Variant(rhs)); + } + bool isNull() const pure => flags == Flags.Null; bool isFalse() const pure @@ -289,55 +729,113 @@ nothrow @nogc: bool isDouble() const pure => (flags & Flags.DoubleFlag) != 0; bool isQuantity() const pure - => (flags & Flags.IsQuantity) != 0; + => isNumber && count != 0 && !is_enum; + bool isDuration() const pure + => isNumber && (count & 0xFFFFFF) == Second.pack; + bool is_enum() const pure + => (flags & Flags.Enum) != 0; + bool isBuffer() const pure + => type == Type.Buffer; bool isString() const pure => (flags & Flags.IsString) != 0; bool isArray() const pure => flags == Flags.Array; bool isObject() const pure => flags == Flags.Map; + bool isUserType() const pure + => (flags & Flags.TypeMask) == Type.User; bool isUser(T)() const pure - if (ValidUserType!T) + if (ValidUserType!(Unqual!T)) { + alias U = Unqual!T; if ((flags & Flags.TypeMask) != Type.User) return false; - static if (EmbedUserType!T) - return alloc == UserTypeShortId!T; + static if (EmbedUserType!U) + return alloc == UserTypeId!U; else - return count == UserTypeId!T; + { + if (count == UserTypeId!U) + return true; + static if (is(T == class)) + { + immutable(TypeDetails)* td = &get_type_details(alloc); + while (td.super_type_id) + { + if (td.super_type_id == UserTypeId!U) + return true; + td = &find_type_details(td.super_type_id); + } + } + return false; + } } + bool canFitInt(I)() const pure + if (is_some_int!I) + { + if (!isNumber || isFloat) + return false; + static if (is(I == ulong)) + return isUlong; + else static if (is(I == long)) + return isLong; + else static if (is(I == uint)) + return isUint; + else static if (is(I == int)) + return isInt; + else static if (is_signed_int!I) + { + if (!isInt) + return false; + int i = asInt(); + return i >= I.min && i <= I.max; + } + else + return isUlong && asUlong <= I.max; + } bool asBool() const pure @property { + if (isNull) + return false; assert(isBool()); return flags == Flags.True; } int asInt() const pure @property { - assert(isInt()); + if (isNull) + return 0; + assert(isInt(), "Value out of range for int"); return cast(int)value.l; } uint asUint() const pure @property { - assert(isUint()); + if (isNull) + return 0; + assert(isUint(), "Value out of range for uint"); return cast(uint)value.ul; } long asLong() const pure @property { - assert(isLong()); + if (isNull) + return 0; + assert(isLong(), "Value out of range for long"); return value.l; } ulong asUlong() const pure @property { - assert(isUlong()); + if (isNull) + return 0; + assert(isUlong(), "Value out of range for ulong"); return value.ul; } double asDouble() const pure @property { - assert(isNumber()); + if (isNull) + return 0; + assert(isNumber); if ((flags & Flags.DoubleFlag) != 0) return value.d; if ((flags & Flags.UintFlag) != 0) @@ -349,33 +847,63 @@ nothrow @nogc: return cast(double)cast(long)value.ul; } + float asFloat() const pure @property + { + if (isNull) + return 0; + assert(isNumber); + if ((flags & Flags.DoubleFlag) != 0) + return value.d; + if ((flags & Flags.UintFlag) != 0) + return cast(float)cast(uint)value.ul; + if ((flags & Flags.IntFlag) != 0) + return cast(float)cast(int)cast(long)value.ul; + if ((flags & Flags.Uint64Flag) != 0) + return cast(float)value.ul; + return cast(float)cast(long)value.ul; + } + Quantity!T asQuantity(T = double)() const pure @property + if (is_some_float!T || is_some_int!T) { - assert(isNumber()); + if (isNull) + return Quantity!T(0); + assert(isNumber); + Quantity!T r; + r.value = as!T; + r.unit.pack = count; + return r; + } - Quantity!double r; - static if (is(T == double)) - r.value = asDouble(); -// else static if (is(T == float)) -// r.value = asFloat(); - else static if (is(T == int)) - r.value = asInt(); - else static if (is(T == uint)) - r.value = asUint(); - else static if (is(T == long)) - r.value = asLong(); - else static if (is(T == ulong)) - r.value = asUlong(); + Duration asDuration() const pure @property + { + assert(isDuration); + alias Nanoseconds = Quantity!(long, Nanosecond); + Nanoseconds ns; + if (size_t.sizeof < 8 && isFloat) // TODO: better way to detect if double is NOT supported in hardware? + ns = cast(Nanoseconds)asQuantity!float(); + else if (isDouble) + ns = cast(Nanoseconds)asQuantity!double(); else - assert(false, "Unsupported quantity type!"); - if (isQuantity()) - r.unit.pack = count; - return r; + ns = asQuantity!long(); + return ns.value.dur!"nsecs"; + } + + const(void)[] asBuffer() const pure + { + if (isNull) + return null; + assert(isBuffer); + if (flags & Flags.Embedded) + return embed[0 .. embed[$-1]]; + return ptr[0 .. count]; } const(char)[] asString() const pure { - assert(isString()); + if (isNull) + return null; + assert(isString); if (flags & Flags.Embedded) return embed[0 .. embed[$-1]]; return value.s[0 .. count]; @@ -397,44 +925,194 @@ nothrow @nogc: } ref inout(T) asUser(T)() inout pure - if (ValidUserType!T && UserTypeReturnByRef!T) + if (ValidUserType!(Unqual!T) && UserTypeReturnByRef!T) { - if (!isUser!T) - assert(false, "Variant is not a " ~ T.stringof); - static assert(!is(T == class), "Should be impossible?"); - static if (EmbedUserType!T) + alias U = Unqual!T; + if (!isUser!U) + assert(false, "Variant is not a " ~ U.stringof); + static assert(!is(U == class), "Should be impossible?"); + static if (EmbedUserType!U) return *cast(inout(T)*)embed.ptr; else return *cast(inout(T)*)ptr; } - inout(T) asUser(T)() inout pure - if (ValidUserType!T && !UserTypeReturnByRef!T) + inout(T) asUser(T)() inout + if (ValidUserType!(Unqual!T) && !UserTypeReturnByRef!T) + { + alias U = Unqual!T; + + // some hacks for builtin time types... + static if (is(U == MonoTime)) + return cast(MonoTime)asUser!SysTime; + else static if (is(T == SysTime)) + { + static assert (EmbedUserType!SysTime && EmbedUserType!DateTime); + if (isUser!SysTime) + return *cast(inout(SysTime)*)embed.ptr; + if (isUser!DateTime) + return getSysTime(*cast(DateTime*)embed.ptr); + assert(false, "Variant is not a timestamp"); + } + else static if (is(T == DateTime)) + { + static assert (EmbedUserType!SysTime && EmbedUserType!DateTime); + if (isUser!DateTime) + return *cast(inout(DateTime)*)embed.ptr; + if (isUser!SysTime) + return getDateTime(*cast(SysTime*)embed.ptr); + assert(false, "Variant is not a timestamp"); + } + else + { + if (!isUser!U) + assert(false, "Variant is not a " ~ U.stringof); + static if (is(U == class)) + return cast(inout(T))ptr; + else static if (EmbedUserType!U) + { + // TODO: it would be nice to support trivial types and just cast/copy rather than copy_emplace(...) + + // make a copy on the stack and return by value + U r = void; + TypeDetailsFor!U.copy_emplace(cast(U*)embed.ptr, &r, false); + return r; + } + else + static assert(false, "Should be impossible?"); + } + } + + template as(T) + { + static if (!is(T == Unqual!T)) + alias as = as!(Unqual!T); + else static if (is_boolean!T) + alias as = asBool; + else static if (is(T == long)) + alias as = asLong; + else static if (is(T == int)) + alias as = asInt; + else static if (is(T == ulong)) + alias as = asUlong; + else static if (is(T == uint)) + alias as = asUint; + else static if (is_some_int!T) + { + T as() const pure + { + static if (is_signed_int!T) + { + int i = asInt(); + assert(i >= T.min && i <= T.max, "Value out of range for " ~ T.stringof); + } + else + { + uint i = asUint(); + assert(i <= T.max, "Value out of range for " ~ T.stringof); + } + return cast(T)i; + } + } + else static if (is(T == float)) + alias as = asFloat; + else static if (is(T == double)) + alias as = asDouble; + else static if (is(T == real)) + real as() const pure => asDouble; + else static if (is(T == Quantity!(U, _U), U, ScaledUnit _U)) + alias as = asQuantity!U; + else static if (is(T == Duration)) + alias as = asDuration; + else static if (is(const(char)[] : T)) + alias as = asString; + else static if (is(T == String)) + { + String as() const pure + { + if (isNull) + return String(); + assert(isString); + if (flags & Flags.Embedded) + return embed[0 .. embed[$-1]].makeString(defaultAllocator); + return *cast(String*)&value.s; + } + } + else static if (ValidUserType!(Unqual!T)) + alias as = asUser!T; + else + static assert(false, "TODO!"); + } + + Array!Variant take_array() + { + if (flags == Flags.Null) + return Array!Variant(); + assert(isArray()); + Array!Variant r; + swap(r, nodeArray); + flags = Flags.Null; + return r; + } + + String take_string() + { + if (flags == Flags.Null) + return String(); + assert(isString); + if (flags & Flags.Embedded) + return embed[0 .. embed[$-1]].makeString(defaultAllocator); + String s; + s.ptr = value.s; + value.s = null; + flags = Flags.Null; + return s; + } + + ScaledUnit get_unit() const pure + { + assert(isQuantity()); + return *cast(ScaledUnit*)&count; + } + + const(VoidEnumInfo)* get_enum_info() const pure { - if (!isUser!T) - assert(false, "Variant is not a " ~ T.stringof); - static if (is(T == class)) - return cast(inout(T))ptr; - else static if (EmbedUserType!T) - static assert(false, "TODO: memcpy to a stack local and return that..."); + assert(is_enum); + static if (size_t.sizeof == 8) + return cast(VoidEnumInfo*)(count | (size_t(alloc) << 32)); else - static assert(false, "Should be impossible?"); + return cast(VoidEnumInfo*)count; } size_t length() const pure { if (flags == Flags.Null) return 0; - else if (isString()) + else if (isBuffer()) return (flags & Flags.Embedded) ? embed[$-1] : count; else if (isArray()) return count; else - assert(false); + assert(false, "Variant does not have `length`"); } bool empty() const pure => isObject() ? count == 0 : length() == 0; + Variant* insert(const(char)[] key, Variant value) + { + if (flags == Flags.Null) + flags = Flags.Map; + else + { + assert(isObject()); + if (getMember(key)) + return null; + } + nodeArray.emplaceBack(key); + move(value, nodeArray.pushBack()); + return &nodeArray.back(); + } + inout(Variant)* getMember(const(char)[] member) inout pure { assert(isObject()); @@ -446,6 +1124,12 @@ nothrow @nogc: return null; } + void set_unit(ScaledUnit unit) + { + assert(isNumber()); + count = unit.pack; + } + // TODO: this seems to interfere with UFCS a lot... // ref inout(Variant) opDispatch(string member)() inout pure // { @@ -479,73 +1163,160 @@ nothrow @nogc: { final switch (type) { - case Variant.Type.Null: + case Variant.Type.Null: // assume type == 0 + case Variant.Type.True: // assume type == 1 + case Variant.Type.False: // assume type == 2 + __gshared immutable char** values = [ "null", "true", "false" ]; + size_t len = 4 + (type >> 1); if (!buffer.ptr) - return 4; - if (buffer.length < 4) + return len; + if (buffer.length < len) return -1; - buffer[0 .. 4] = "null"; - return 4; - - case Variant.Type.False: - if (!buffer.ptr) - return 5; - if (buffer.length < 5) - return -1; - buffer[0 .. 5] = "false"; - return 5; - - case Variant.Type.True: - if (!buffer.ptr) - return 4; - if (buffer.length < 4) - return -1; - buffer[0 .. 4] = "true"; - return 4; + buffer[0 .. len] = values[type][0 .. len]; + return len; case Variant.Type.Number: - import urt.conv; - if (isQuantity()) - assert(false, "TODO: implement quantity formatting for JSON"); + return asQuantity().toString(buffer, format, formatArgs); if (isDouble()) - return asDouble().formatFloat(buffer); + return asDouble().format_float(buffer); // TODO: parse args? - //format + assert(!format, "TODO"); if (flags & Flags.Uint64Flag) - return asUlong().formatUint(buffer); - return asLong().formatInt(buffer); + return asUlong().format_uint(buffer); + return asLong().format_int(buffer); - case Variant.Type.String: - const char[] s = asString(); - if (buffer.ptr) + case Variant.Type.Buffer: + if (isString) + { + const char[] s = asString(); + if (buffer.ptr) + { + // TODO: should we write out quotes? + // a string of a number won't be distinguishable from a number without quotes... + if (buffer.length < s.length) + return -1; + buffer[0 .. s.length] = s[]; + } + return s.length; + } + else { - // TODO: should we write out quotes? - // a string of a number won't be distinguishable from a number without quotes... - if (buffer.length < s.length) - return -1; - buffer[0 .. s.length] = s[]; + import urt.string.format : formatValue; + return formatValue(asBuffer(), buffer, format, formatArgs); } - return s.length; case Variant.Type.Map: case Variant.Type.Array: import urt.format.json; // should we just format this like JSON or something? - return writeJson(this, buffer); + return write_json(this, buffer); case Variant.Type.User: if (flags & Flags.Embedded) - return findTypeDetails(alloc).stringify(embed.ptr, buffer); + return find_type_details(alloc).stringify(cast(void*)embed.ptr, buffer, true, format, formatArgs); + else + return g_type_details[alloc].stringify(cast(void*)ptr, buffer, true, format, formatArgs); + } + } + + ptrdiff_t fromString(const(char)[] s) + { + import urt.string.ascii : is_numeric; + + if (s.empty || s == "null") + { + this = null; + return s.length; + } + if (s == "true") + { + this = true; + return 4; + } + if (s == "false") + { + this = false; + return 5; + } + + if (s[0] == '"') + { + for (size_t i = 1; i < s.length; ++i) + { + if (s[i] == '"') + { + assert(i == s.length - 1, "String must end with a quote"); + this = s[1 .. i]; + return i + 1; + } + } + assert(false, "String has no closing quote"); + } + + if (s[0].is_numeric || ((s[0] == '+' || s[0] == '-') && s.length > 1 && s[1].is_numeric)) + { + size_t taken; + ScaledUnit unit; + int e; + long i = s.parse_int_with_exponent(e, &taken, 10); + if (taken < s.length) + { + size_t t2 = unit.fromString(s[taken .. $]); + if (t2 > 0) + taken += t2; + } + if (taken == s.length) + { + if (e != 0) + this = i * 10.0^^e; else - return findTypeDetails(count).stringify(ptr, buffer); + this = i; + count = unit.pack; + return taken; + } } + + align(64) void[256] buffer = void; + this = null; // clear the object since we'll probably use the embed buffer... + foreach (ushort i; 0 .. g_num_type_details) + { + ref immutable TypeDetails td = get_type_details(i); + debug assert(td.alignment <= 64 && td.size <= buffer.sizeof, "Buffer is too small for user type!"); + ptrdiff_t taken = td.stringify(td.embedded ? embed.ptr : buffer.ptr, cast(char[])s, false, null, null); + if (taken > 0) + { + flags = Flags.User; + if (td.destroy) + flags |= Flags.NeedDestruction; + if (td.embedded) + { + flags |= Flags.Embedded; + alloc = cast(ushort)td.type_id; + } + else + { + void* object = defaultAllocator().alloc(td.size, td.alignment).ptr; + td.copy_emplace(buffer.ptr, object, true); + if (td.destroy) + td.destroy(buffer.ptr); + ptr = object; + count = td.type_id; + alloc = i; + } + return taken; + } + } + + // what is this? + assert(false, "Can't parse variant from string"); } + package: union Value { @@ -586,9 +1357,22 @@ package: Type type() const pure => cast(Type)(flags & Flags.TypeMask); + uint userType() const pure + { + if (flags & Flags.Embedded) + return alloc; // short id + return count; // long id + } + inout(void)* user_ptr() inout pure + { + if (flags & Flags.Embedded) + return embed.ptr; + return ptr; + } + ref inout(Array!Variant) nodeArray() @property inout pure => *cast(inout(Array!Variant)*)&value.n; - void takeNodeArray(ref Array!Variant arr) + void take_node_array(ref Array!Variant arr) { value.n = arr[].ptr; count = cast(uint)arr.length; @@ -598,33 +1382,41 @@ package: void destroy(bool reset = true)() { if (flags & Flags.NeedDestruction) - doDestroy(); + do_destroy(); static if (reset) __pack[] = 0; } - private void doDestroy() + private void do_destroy() { Type t = type(); - if ((t == Type.Map || t == Type.Array) && value.n) + if (isBuffer) + { + if (isString) + *cast(String*)&value.s = null; + else + defaultAllocator().free(ptr[0..count]); + } + else if ((t == Type.Map || t == Type.Array) && value.n) nodeArray.destroy!false(); else if (t == Type.User) { - if (flags & Flags.Embedded) - findTypeDetails(alloc).destroy(embed.ptr); - else - findTypeDetails(count).destroy(ptr); + ref const TypeDetails td = (flags & Flags.Embedded) ? find_type_details(alloc) : g_type_details[alloc]; + if (td.destroy) + td.destroy(user_ptr); + if (!(flags & Flags.Embedded)) + defaultAllocator().free(ptr[0..td.size]); } } enum Type : ushort { Null = 0, - False = 1, - True = 2, + True = 1, + False = 2, Number = 3, - String = 4, + Buffer = 4, Array = 5, Map = 6, User = 7 @@ -641,8 +1433,10 @@ package: NumberUint64 = cast(Flags)Type.Number | Flags.IsNumber | Flags.Uint64Flag, NumberFloat = cast(Flags)Type.Number | Flags.IsNumber | Flags.FloatFlag | Flags.DoubleFlag, NumberDouble = cast(Flags)Type.Number | Flags.IsNumber | Flags.DoubleFlag, - String = cast(Flags)Type.String | Flags.IsString, - ShortString = cast(Flags)Type.String | Flags.IsString | Flags.Embedded, + Buffer = cast(Flags)Type.Buffer, + ShortBuffer = cast(Flags)Type.Buffer | Flags.Embedded, + String = cast(Flags)Type.Buffer | Flags.IsString, + ShortString = cast(Flags)Type.Buffer | Flags.IsString | Flags.Embedded, Array = cast(Flags)Type.Array | Flags.NeedDestruction, Map = cast(Flags)Type.Map | Flags.NeedDestruction, User = cast(Flags)Type.User, @@ -656,7 +1450,7 @@ package: Uint64Flag = 1 << (TypeBits + 6), FloatFlag = 1 << (TypeBits + 7), DoubleFlag = 1 << (TypeBits + 8), - IsQuantity = 1 << (TypeBits + 9), + Enum = 1 << (TypeBits + 9), Embedded = 1 << (TypeBits + 10), NeedDestruction = 1 << (TypeBits + 11), // CopyFlag = 1 << (TypeBits + 12), // maybe we want to know if a thing is a copy, or a reference to an external one? @@ -691,15 +1485,22 @@ unittest private: -import urt.hash : fnv1aHash; +import urt.hash : fnv1a; +import urt.string.format : formatValue, FormatArg; static assert(Variant.sizeof == 16); static assert(Variant.Type.max <= Variant.Flags.TypeMask); -enum uint UserTypeId(T) = fnv1aHash(cast(const(ubyte)[])T.stringof); // maybe this isn't a good enough hash? -enum uint UserTypeShortId(T) = cast(ushort)UserTypeId!T ^ (UserTypeId!T >> 16); +template UserTypeId(T) +{ + enum uint Hash = fnv1a(cast(const(ubyte)[])T.stringof); // maybe this isn't a good enough hash? + static if (!EmbedUserType!T) + enum uint UserTypeId = Hash; + else + enum ushort UserTypeId = cast(ushort)Hash ^ (Hash >> 16); +} enum bool EmbedUserType(T) = is(T == struct) && T.sizeof <= Variant.embed.sizeof - 2 && T.alignof <= Variant.alignof; -enum bool UserTypeReturnByRef(T) = is(T == struct); +enum bool UserTypeReturnByRef(T) = is(T == struct) && !EmbedUserType!T; ptrdiff_t newline(char[] buffer, ref ptrdiff_t offset, int level) { @@ -713,46 +1514,177 @@ ptrdiff_t newline(char[] buffer, ref ptrdiff_t offset, int level) template MakeTypeDetails(T) { + static assert(is(Unqual!T == T), "Only instantiate for mutable types"); + +// pragma(msg, "Add user type: ", T.stringof, EmbedUserType!T ? " - embedded" : ""); + // this is a hack which populates an array of user type details when the program starts // TODO: we can probably NOT do this for class types, and just use RTTI instead... shared static this() { - assert(numTypeDetails < typeDetails.length, "Too many user types!"); - - TypeDetails* ty = &typeDetails[numTypeDetails++]; - static if (EmbedUserType!T) - ty.typeId = UserTypeShortId!T; - else - ty.typeId = UserTypeId!T; - // TODO: I'd like to not generate a destroy function if the data is POD - ty.destroy = (void* val) { - static if (!is(T == class)) - destroy!false(*cast(T*)val); - }; - ty.stringify = (const void* val, char[] buffer) { - import urt.string.format : toString; - return toString(*cast(T*)val, buffer); - }; + assert(g_num_type_details < g_type_details.length, "Too many user types!"); + g_type_details[g_num_type_details++] = TypeDetailsFor!T; } alias MakeTypeDetails = void; } +ushort type_detail_index(T)() pure + if (ValidUserType!T) +{ + ushort count = (cast(ushort function() pure nothrow @nogc)&num_type_details)(); + foreach (ushort i; 0 .. count) + if (get_type_details(i).type_id == UserTypeId!T) + return i; + assert(false, "Why wasn't the type registered?"); +} + struct TypeDetails { - uint typeId; + uint type_id; + uint super_type_id; + ushort size; + ubyte alignment; + bool embedded; + void function(void* src, void* dst, bool move) nothrow @nogc copy_emplace; void function(void* val) nothrow @nogc destroy; - ptrdiff_t function(const void* val, char[] buffer) nothrow @nogc stringify; + ptrdiff_t function(void* val, char[] buffer, bool do_format, const(char)[] format_spec, const(FormatArg)[] format_args) nothrow @nogc stringify; + int function(const void* a, const void* b, int type) pure nothrow @nogc cmp; } -TypeDetails[8] typeDetails; -size_t numTypeDetails = 0; +@fast_data __gshared TypeDetails[16] g_type_details; +@fast_data __gshared ushort g_num_type_details = 0; -ref TypeDetails findTypeDetails(uint typeId) +typeof(g_type_details)* type_details() => &g_type_details; +ushort num_type_details() => g_num_type_details; + +ref immutable(TypeDetails) find_type_details(uint type_id) pure { - foreach (i, ref td; typeDetails[0 .. numTypeDetails]) + auto tds = (cast(immutable(typeof(g_type_details)*) function() pure nothrow @nogc)&type_details)(); + ushort count = (cast(ushort function() pure nothrow @nogc)&num_type_details)(); + foreach (i, ref td; (*tds)[0 .. count]) { - if (td.typeId == typeId) + if (td.type_id == type_id) return td; } assert(false, "TypeDetails not found!"); } +ref immutable(TypeDetails) get_type_details(uint index) pure +{ + auto tds = (cast(immutable(typeof(g_type_details)*) function() pure nothrow @nogc)&type_details)(); + debug assert(index < g_num_type_details); + return (*tds)[index]; +} + +public template TypeDetailsFor(T) + if (is(Unqual!T == T) && (is(T == struct) || is(T == class))) +{ + static if (is(T == class) && is(T S == super)) + { + alias Super = Unqual!S; + static if (!is(Super == Object)) + { + alias dummy = MakeTypeDetails!Super; + enum SuperTypeId = UserTypeId!Super; + } + else + enum ushort SuperTypeId = 0; + } + else + enum ushort SuperTypeId = 0; + + static if (!is(T == class)) + { + static void move_emplace_impl(void* src, void* dst, bool move) nothrow @nogc + { + if (move) + moveEmplace(*cast(T*)src, *cast(T*)dst); + else + { + static if (is_trivial!T) + *cast(T*)dst = *cast(T*)src; + else static if (__traits(compiles, new(*cast(T*)dst) T(*cast(T*)src))) + new(*cast(T*)dst) T(*cast(T*)src); + else + assert(false, "Can't copy " ~ T.stringof); + } + } + enum move_emplace = &move_emplace_impl; + } + else + enum move_emplace = null; + + static if (!is_trivial!T && is(typeof(destroy!(false, T)))) + { + static void destroy_impl(void* val) nothrow @nogc + { + destroy!false(*cast(T*)val); + } + enum destroy_fun = &destroy_impl; + } + else + enum destroy_fun = null; + + static ptrdiff_t stringify(void* val, char[] buffer, bool do_format, const(char)[] format_spec, const(FormatArg)[] format_args) nothrow @nogc + { + if (do_format) + { + static if (__traits(compiles, { formatValue(*cast(const T*)val, buffer, format_spec, format_args); })) + return formatValue(*cast(const T*)val, buffer, format_spec, format_args); + else + return -1; + } + else + { + static if (is(typeof(parse!T))) + return buffer.parse!T(*cast(T*)val); + else + return -1; + } + } + + int compare(const void* pa, const void* pb, int type) pure nothrow @nogc + { + ref const T a = *cast(const T*)pa; + ref const T b = *cast(const T*)pb; + switch (type) + { + case 0: + static if (is(T == class) || is(T == U*, U) || is(T == V[], V)) + { + if (pa is pb) + return 0; + } + static if (__traits(compiles, { a.opCmp(b); })) + return a.opCmp(b); + else static if (__traits(compiles, { b.opCmp(a); })) + return -b.opCmp(a); + else static if (is(T == class)) + { + ptrdiff_t r = cast(ptrdiff_t)pa - cast(ptrdiff_t)pb; + return r < 0 ? -1 : r > 0 ? 1 : 0; + } + else + assert(false, "No comparison!"); // TODO: hash or stringify the values and order that way? + case 1: + static if (is(T == class) || is(T == U*, U) || is(T == V[], V)) + { + if (pa is pb) + return 1; + } + static if (__traits(compiles, { a.opEquals(b); })) + return a.opEquals(b); + else static if (__traits(compiles, { b.opEquals(a); })) + return b.opEquals(a); + else static if (!is(T == class) && !is(T == U*, U) && !is(T == V[], V)) + return a == b ? 1 : 0; + else + return 0; + case 2: + return pa is pb ? 1 : 0; + default: + assert(false); + } + } + + enum TypeDetailsFor = TypeDetails(UserTypeId!T, SuperTypeId, T.sizeof, T.alignof, EmbedUserType!T, move_emplace, destroy_fun, &stringify, &compare); +} diff --git a/src/urt/zip.d b/src/urt/zip.d index 4bf2521..45fdd9f 100644 --- a/src/urt/zip.d +++ b/src/urt/zip.d @@ -3,191 +3,188 @@ module urt.zip; import urt.crc; import urt.endian; import urt.hash; +import urt.mem.alloc : MemFlags; import urt.mem.allocator; +import urt.result; -alias zlib_crc = calculateCRC!(Algorithm.CRC32_ISO_HDLC); +alias zlib_crc = calculate_crc!(Algorithm.crc32_iso_hdlc); nothrow @nogc: // this is a port of tinflate (tiny inflate) -enum error_code : int +enum GzipFlag : ubyte { - OK = 0, /**< Success */ - DATA_ERROR = -3, /**< Input error */ - BUF_ERROR = -5 /**< Not enough room for output */ + ftext = 1, + fhcrc = 2, + fextra = 4, + fname = 8, + fcomment = 16 } -enum gzip_flag : ubyte -{ - FTEXT = 1, - FHCRC = 2, - FEXTRA = 4, - FNAME = 8, - FCOMMENT = 16 -} - -error_code zlib_uncompress(const(void)[] source, void[] dest, out size_t destLen) +Result zlib_uncompress(const(void)[] source, void[] dest, out size_t destLen) { const ubyte* src = cast(const ubyte*)source.ptr; uint sourceLen = cast(uint)source.length; if (sourceLen < 6) - return error_code.DATA_ERROR; + return InternalResult.data_error; ubyte cmf = src[0]; ubyte flg = src[1]; // check checksum if ((256 * cmf + flg) % 31) - return error_code.DATA_ERROR; + return InternalResult.data_error; // check method is deflate if ((cmf & 0x0F) != 8) - return error_code.DATA_ERROR; + return InternalResult.data_error; // check window size is valid if ((cmf >> 4) > 7) - return error_code.DATA_ERROR; + return InternalResult.data_error; // check there is no preset dictionary if (flg & 0x20) - return error_code.DATA_ERROR; + return InternalResult.data_error; + + size_t deflateLen; + if (!uncompress((src + 2)[0 .. sourceLen - 2], dest, destLen, &deflateLen)) + return InternalResult.data_error; - if (uncompress((src + 2)[0 .. sourceLen - 6], dest, destLen) != error_code.OK) - return error_code.DATA_ERROR; + const(ubyte)* footer = src + 2 + deflateLen; + if (footer + 4 > src + sourceLen) + return InternalResult.data_error; - if (adler32(dest[0 .. destLen]) != loadBigEndian!uint(cast(uint*)&src[sourceLen - 4])) - return error_code.DATA_ERROR; + if (adler32(dest[0 .. destLen]) != loadBigEndian!uint(cast(uint*)footer)) + return InternalResult.data_error; - return error_code.OK; + return InternalResult.success; } -error_code gzip_uncompressed_length(const(void)[] source, out size_t destLen) +Result gzip_uncompressed_length(const(void)[] source, out size_t destLen) { const ubyte* src = cast(const ubyte*)source.ptr; uint sourceLen = cast(uint)source.length; if (sourceLen < 18) - return error_code.DATA_ERROR; + return InternalResult.data_error; // check id bytes if (src[0] != 0x1F || src[1] != 0x8B) - return error_code.DATA_ERROR; + return InternalResult.data_error; // check method is deflate if (src[2] != 8) - return error_code.DATA_ERROR; + return InternalResult.data_error; ubyte flg = src[3]; // check that reserved bits are zero if (flg & 0xE0) - return error_code.DATA_ERROR; + return InternalResult.data_error; // get decompressed length destLen = loadLittleEndian!uint(cast(uint*)(src + sourceLen - 4)); - return error_code.OK; + return InternalResult.success; } -error_code gzip_uncompress(const(void)[] source, void[] dest, out size_t destLen) +Result gzip_uncompress(const(void)[] source, void[] dest, out size_t destLen) { const ubyte* src = cast(const ubyte*)source.ptr; uint sourceLen = cast(uint)source.length; if (sourceLen < 18) - return error_code.DATA_ERROR; + return InternalResult.data_error; // check id bytes if (src[0] != 0x1F || src[1] != 0x8B) - return error_code.DATA_ERROR; + return InternalResult.data_error; // check method is deflate if (src[2] != 8) - return error_code.DATA_ERROR; + return InternalResult.data_error; ubyte flg = src[3]; // check that reserved bits are zero if (flg & 0xE0) - return error_code.DATA_ERROR; + return InternalResult.data_error; // skip base header of 10 bytes const(ubyte)* start = src + 10; // skip extra data if present - if (flg & gzip_flag.FEXTRA) + if (flg & GzipFlag.fextra) { uint xlen = loadLittleEndian!ushort(cast(ushort*)start); if (xlen > sourceLen - 12) - return error_code.DATA_ERROR; + return InternalResult.data_error; start += xlen + 2; } // skip file name if present - if (flg & gzip_flag.FNAME) + if (flg & GzipFlag.fname) { do { if (start - src >= sourceLen) - return error_code.DATA_ERROR; + return InternalResult.data_error; } while (*start++); } // skip file comment if present - if (flg & gzip_flag.FCOMMENT) + if (flg & GzipFlag.fcomment) { do { if (start - src >= sourceLen) - return error_code.DATA_ERROR; + return InternalResult.data_error; } while (*start++); } // check header crc if present - if (flg & gzip_flag.FHCRC) + if (flg & GzipFlag.fhcrc) { uint hcrc; if (start - src > sourceLen - 2) - return error_code.DATA_ERROR; + return InternalResult.data_error; hcrc = loadLittleEndian!ushort(cast(ushort*)start); if (hcrc != (zlib_crc(src[0 .. start - src]) & 0x0000FFFF)) - return error_code.DATA_ERROR; + return InternalResult.data_error; start += 2; } - // get decompressed length - uint dlen = loadLittleEndian!uint(cast(uint*)(src + sourceLen - 4)); - if (dlen > dest.length) - return error_code.BUF_ERROR; - - if ((src + sourceLen) - start < 8) - return error_code.DATA_ERROR; + size_t deflateLen; + if (!uncompress(start[0 .. (src + sourceLen) - start], dest, destLen, &deflateLen)) + return InternalResult.data_error; - if (uncompress(start[0 .. (src + sourceLen) - start - 8], dest, destLen) != error_code.OK) - return error_code.DATA_ERROR; + const(ubyte)* footer = start + deflateLen; + if (footer + 8 > src + sourceLen) + return InternalResult.data_error; - if (destLen != dlen) - return error_code.DATA_ERROR; + if (zlib_crc(dest[0..destLen]) != loadLittleEndian!uint(cast(uint*)footer)) + return InternalResult.data_error; - // check CRC32 checksum - if (zlib_crc(dest[0..dlen]) != loadLittleEndian!uint(cast(uint*)(src + sourceLen - 8))) - return error_code.DATA_ERROR; + uint isize = loadLittleEndian!uint(cast(uint*)(footer + 4)); + if (isize != destLen) + return InternalResult.data_error; - return error_code.OK; + return InternalResult.success; } -error_code uncompress(const(void)[] source, void[] dest, out size_t destLen) +Result uncompress(const(void)[] source, void[] dest, out size_t destLen, size_t* srcConsumed = null) { data d; @@ -211,7 +208,7 @@ error_code uncompress(const(void)[] source, void[] dest, out size_t destLen) uint btype = getbits(&d, 2); // Decompress block - error_code res; + Result res; switch (btype) { case 0: @@ -227,20 +224,22 @@ error_code uncompress(const(void)[] source, void[] dest, out size_t destLen) res = inflate_dynamic_block(&d); break; default: - res = error_code.DATA_ERROR; + res = InternalResult.data_error; break; } - if (res != error_code.OK) + if (!res) return res; } while (!bfinal); if (d.overflow) - return error_code.DATA_ERROR; + return InternalResult.data_error; destLen = d.dest - d.dest_start; + if (srcConsumed) + *srcConsumed = d.source - cast(const(ubyte)*)source.ptr; - return error_code.OK; + return InternalResult.success; } @@ -264,8 +263,8 @@ ubyte[] zlib_compress(const void[] message, int quality) uint bitbuf=0; int i,j, bitcount=0; ubyte* out_ = null; - ubyte*** hash_table = cast(ubyte***) STBIW_MALLOC(stbiw__ZHASH * ubyte**.sizeof); - if (hash_table == null) + ubyte*** hash_table = cast(ubyte***) STBIW_MALLOC!(MemFlags.fast)(stbiw__ZHASH * (ubyte**).sizeof); + if (hash_table is null) return null; if (quality < 5) quality = 5; @@ -328,7 +327,7 @@ ubyte[] zlib_compress(const void[] message, int quality) memmove(hash_table[h], hash_table[h]+quality, hash_table[h][0].sizeof*quality); stbiw__sbn(hash_table[h]) = quality; } - stbiw__sbpush(hash_table[h], data + i); + stbiw__sbpush!(MemFlags.fast)(hash_table[h], data + i); if (bestloc) { @@ -444,19 +443,73 @@ unittest } +ubyte[] gzip_compress(const void[] message, int quality) +{ + ubyte[] zlib_out = zlib_compress(message, quality); + if (zlib_out.length == 0) + return null; + + // zlib_out layout: [2B CMF/FLG][raw deflate][4B adler32] + // gzip layout: [10B header][raw deflate][4B crc32][4B isize] + size_t total = zlib_out.length; + assert(total >= 6); + + size_t raw_len = total - 6; + size_t out_len = 10 + raw_len + 8; + ubyte[] result = cast(ubyte[])defaultAllocator().alloc(out_len); + if (result.ptr is null) + { + defaultAllocator().free(zlib_out); + return null; + } + + static immutable ubyte[10] gzip_header = [0x1F, 0x8B, 0x08, 0x00, 0, 0, 0, 0, 0, 0xFF]; + result[0 .. 10] = gzip_header[]; + result[10 .. 10 + raw_len] = zlib_out[2 .. $ - 4]; + storeLittleEndian!uint(cast(uint*)(result.ptr + 10 + raw_len), zlib_crc(message)); + storeLittleEndian!uint(cast(uint*)(result.ptr + 10 + raw_len + 4), cast(uint)message.length); + + defaultAllocator().free(zlib_out); + return result; +} + +unittest +{ + enum src = "123456789012345678901234567890"; + ubyte[] result = gzip_compress(src, 9); + assert(result.length >= 18); + assert(result[0] == 0x1F && result[1] == 0x8B && result[2] == 0x08); + + ubyte[256] decompressBuffer = void; + size_t len; + gzip_uncompress(result, decompressBuffer, len); + assert(len == src.length); + assert(decompressBuffer[0 .. len] == src); + + defaultAllocator().free(result); +} + + private: -enum stbiw__ZHASH = 16384; +enum stbiw__ZHASH = 4096; -void* STBIW_MALLOC(size_t size) - => defaultAllocator().alloc(size).ptr; +void* STBIW_MALLOC(MemFlags flags = MemFlags.none)(size_t size) +{ + import urt.mem.alloc : alloc; + return alloc(size, size_t.sizeof, flags).ptr; +} -void* STBIW_REALLOC_SIZED(void* ptr, size_t old_size, size_t new_size) - => defaultAllocator().realloc(ptr[0..old_size], new_size).ptr; +void* STBIW_REALLOC_SIZED(MemFlags flags = MemFlags.none)(void* ptr, size_t old_size, size_t new_size) +{ + import urt.mem.alloc : realloc; + return realloc(ptr[0..old_size], new_size, size_t.sizeof, flags).ptr; +} void STBIW_FREE(void* ptr) { - defaultAllocator().free(ptr[0..0]); + import urt.mem.alloc : free; + free(ptr[0..0]); } ubyte STBIW_UCHAR(T)(T x) @@ -467,14 +520,16 @@ int* stbiw__sbraw(T)(T* a) => cast(int*)a - 2; ref int stbiw__sbm(T)(T* a) => (cast(int*)a - 2)[0]; ref int stbiw__sbn(T)(T* a) => (cast(int*)a - 2)[1]; -bool stbiw__sbneedgrow(T)(T* a, int n) => !a || (stbiw__sbn(a) + n >= stbiw__sbm(a)); -void* stbiw__sbmaybegrow(T)(ref T* a, int n) => stbiw__sbneedgrow(a,n) ? stbiw__sbgrow(a, n) : null; -void* stbiw__sbgrow(T)(ref T* a, int n) => stbiw__sbgrowf(cast(void**)&a, n, T.sizeof); +bool stbiw__sbneedgrow(T)(T* a, int n) => !a || (stbiw__sbn(a) + n >= stbiw__sbm(a)); +void* stbiw__sbmaybegrow(MemFlags flags = MemFlags.none, T)(ref T* a, int n) + => stbiw__sbneedgrow(a, n) ? stbiw__sbgrow!flags(a, n) : null; +void* stbiw__sbgrow(MemFlags flags = MemFlags.none, T)(ref T* a, int n) + => stbiw__sbgrowf!flags(cast(void**)&a, n, T.sizeof); auto stbiw__sbcount(T)(T* a) => a ? stbiw__sbn(a) : 0; -auto stbiw__sbpush(T)(ref T* a, T v) +auto stbiw__sbpush(MemFlags flags = MemFlags.none, T)(ref T* a, T v) { - stbiw__sbmaybegrow(a, 1); + stbiw__sbmaybegrow!flags(a, 1); return (a[stbiw__sbn(a)++] = v); } void stbiw__sbfree(T)(auto ref T a) @@ -483,10 +538,10 @@ void stbiw__sbfree(T)(auto ref T a) STBIW_FREE(cast(int*)a - 2); } -void* stbiw__sbgrowf(void** arr, int increment, int itemsize) +void* stbiw__sbgrowf(MemFlags flags = MemFlags.none)(void** arr, int increment, int itemsize) { int m = *arr ? 2*stbiw__sbm(*arr) + increment : increment + 1; - void* p = STBIW_REALLOC_SIZED(*arr ? stbiw__sbraw(*arr) : null, *arr ? int.sizeof*2 + stbiw__sbm(*arr)*itemsize : 0, int.sizeof*2 + itemsize*m); + void* p = STBIW_REALLOC_SIZED!flags(*arr ? stbiw__sbraw(*arr) : null, *arr ? int.sizeof*2 + stbiw__sbm(*arr)*itemsize : 0, int.sizeof*2 + itemsize*m); assert(p); if (p) { @@ -606,7 +661,7 @@ void build_fixed_trees(tree *lt, tree *dt) } /* Given an array of code lengths, build a tree */ -error_code build_tree(tree *t, const(ubyte)* lengths, ushort num) +Result build_tree(tree *t, const(ubyte)* lengths, ushort num) { ushort[16] offs = void; uint available; @@ -638,7 +693,7 @@ error_code build_tree(tree *t, const(ubyte)* lengths, ushort num) /* Check length contains no more codes than available */ if (used > available) - return error_code.DATA_ERROR; + return InternalResult.data_error; available = 2 * (available - used); offs[i] = num_codes; @@ -650,7 +705,7 @@ error_code build_tree(tree *t, const(ubyte)* lengths, ushort num) * code that it has length 1 */ if ((num_codes > 1 && available > 0) || (num_codes == 1 && t.counts[1] != 1)) - return error_code.DATA_ERROR; + return InternalResult.data_error; /* Fill in symbols sorted by code */ for (i = 0; i < num; ++i) @@ -669,7 +724,7 @@ error_code build_tree(tree *t, const(ubyte)* lengths, ushort num) t.symbols[1] = cast(ushort)(t.max_sym + 1); } - return error_code.OK; + return InternalResult.success; } /* -- Decode functions -- */ @@ -749,7 +804,7 @@ int decode_symbol(data *d, const tree *t) return t.symbols[base + offs]; } -error_code decode_trees(data *d, tree *lt, tree *dt) +Result decode_trees(data *d, tree *lt, tree *dt) { /* Special ordering of code length codes */ __gshared immutable ubyte[19] clcidx = [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]; @@ -776,7 +831,7 @@ error_code decode_trees(data *d, tree *lt, tree *dt) * See also: https://github.com/madler/zlib/issues/82 */ if (hlit > 286 || hdist > 30) - return error_code.DATA_ERROR; + return InternalResult.data_error; for (i = 0; i < 19; ++i) lengths[i] = 0; @@ -791,13 +846,13 @@ error_code decode_trees(data *d, tree *lt, tree *dt) } /* Build code length tree (in literal/length tree to save space) */ - error_code res = build_tree(lt, lengths.ptr, 19); - if (res != error_code.OK) + Result res = build_tree(lt, lengths.ptr, 19); + if (res != InternalResult.success) return res; /* Check code length tree is not empty */ if (lt.max_sym == -1) - return error_code.DATA_ERROR; + return InternalResult.data_error; /* Decode code lengths for the dynamic trees */ for (num = 0; num < hlit + hdist; ) @@ -805,14 +860,14 @@ error_code decode_trees(data *d, tree *lt, tree *dt) int sym = decode_symbol(d, lt); if (sym > lt.max_sym) - return error_code.DATA_ERROR; + return InternalResult.data_error; switch (sym) { case 16: /* Copy previous code length 3-6 times (read 2 bits) */ if (num == 0) { - return error_code.DATA_ERROR; + return InternalResult.data_error; } sym = lengths[num - 1]; length = getbits_base(d, 2, 3); @@ -834,7 +889,7 @@ error_code decode_trees(data *d, tree *lt, tree *dt) } if (length > hlit + hdist - num) - return error_code.DATA_ERROR; + return InternalResult.data_error; while (length--) lengths[num++] = cast(ubyte)sym; @@ -842,26 +897,26 @@ error_code decode_trees(data *d, tree *lt, tree *dt) /* Check EOB symbol is present */ if (lengths[256] == 0) - return error_code.DATA_ERROR; + return InternalResult.data_error; /* Build dynamic trees */ res = build_tree(lt, lengths.ptr, hlit); - if (res != error_code.OK) + if (res != InternalResult.success) return res; res = build_tree(dt, lengths.ptr + hlit, hdist); - if (res != error_code.OK) + if (res != InternalResult.success) return res; - return error_code.OK; + return InternalResult.success; } /* -- Block inflate functions -- */ /* Given a stream and two trees, inflate a block of data */ -error_code inflate_block_data(data *d, tree *lt, tree *dt) +Result inflate_block_data(data *d, tree *lt, tree *dt) { /* Extra bits and base tables for length codes */ __gshared immutable ubyte[30] length_bits = [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 127 ]; @@ -877,12 +932,12 @@ error_code inflate_block_data(data *d, tree *lt, tree *dt) /* Check for overflow in bit reader */ if (d.overflow) - return error_code.DATA_ERROR; + return InternalResult.data_error; if (sym < 256) { if (d.dest == d.dest_end) - return error_code.BUF_ERROR; + return InternalResult.buffer_too_small; *d.dest++ = cast(ubyte)sym; } else @@ -892,11 +947,11 @@ error_code inflate_block_data(data *d, tree *lt, tree *dt) /* Check for end of block */ if (sym == 256) - return error_code.OK; + return InternalResult.success; /* Check sym is within range and distance tree is not empty */ if (sym > lt.max_sym || sym - 257 > 28 || dt.max_sym == -1) - return error_code.DATA_ERROR; + return InternalResult.data_error; sym -= 257; @@ -907,16 +962,16 @@ error_code inflate_block_data(data *d, tree *lt, tree *dt) /* Check dist is within range */ if (dist > dt.max_sym || dist > 29) - return error_code.DATA_ERROR; + return InternalResult.data_error; /* Possibly get more bits from distance code */ offs = getbits_base(d, dist_bits[dist], dist_base[dist]); if (offs > d.dest - d.dest_start) - return error_code.DATA_ERROR; + return InternalResult.data_error; if (d.dest_end - d.dest < length) - return error_code.BUF_ERROR; + return InternalResult.buffer_too_small; /* Copy match */ for (i = 0; i < length; ++i) @@ -928,10 +983,10 @@ error_code inflate_block_data(data *d, tree *lt, tree *dt) } /* Inflate an uncompressed block of data */ -error_code inflate_uncompressed_block(data *d) +Result inflate_uncompressed_block(data *d) { if (d.source_end - d.source < 4) - return error_code.DATA_ERROR; + return InternalResult.data_error; /* Get length */ uint length = loadLittleEndian!ushort(cast(ushort*)d.source); @@ -941,15 +996,15 @@ error_code inflate_uncompressed_block(data *d) /* Check length */ if (length != (~invlength & 0x0000FFFF)) - return error_code.DATA_ERROR; + return InternalResult.data_error; d.source += 4; if (d.source_end - d.source < length) - return error_code.DATA_ERROR; + return InternalResult.data_error; if (d.dest_end - d.dest < length) - return error_code.BUF_ERROR; + return InternalResult.buffer_too_small; /* Copy block */ while (length--) @@ -959,19 +1014,19 @@ error_code inflate_uncompressed_block(data *d) d.tag = 0; d.bitcount = 0; - return error_code.OK; + return InternalResult.success; } -error_code inflate_fixed_block(data *d) +Result inflate_fixed_block(data *d) { build_fixed_trees(&d.ltree, &d.dtree); return inflate_block_data(d, &d.ltree, &d.dtree); } -error_code inflate_dynamic_block(data *d) +Result inflate_dynamic_block(data *d) { - error_code res = decode_trees(d, &d.ltree, &d.dtree); - if (res != error_code.OK) + Result res = decode_trees(d, &d.ltree, &d.dtree); + if (res != InternalResult.success) return res; return inflate_block_data(d, &d.ltree, &d.dtree); } diff --git a/third_party/mbedtls/include/mbedtls/aes.h b/third_party/mbedtls/include/mbedtls/aes.h new file mode 100644 index 0000000..401ac39 --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/aes.h @@ -0,0 +1,689 @@ +/** + * \file aes.h + * + * \brief This file contains AES definitions and functions. + * + * The Advanced Encryption Standard (AES) specifies a FIPS-approved + * cryptographic algorithm that can be used to protect electronic + * data. + * + * The AES algorithm is a symmetric block cipher that can + * encrypt and decrypt information. For more information, see + * FIPS Publication 197: Advanced Encryption Standard and + * ISO/IEC 18033-2:2006: Information technology -- Security + * techniques -- Encryption algorithms -- Part 2: Asymmetric + * ciphers. + * + * The AES-XTS block mode is standardized by NIST SP 800-38E + * + * and described in detail by IEEE P1619 + * . + */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_AES_H +#define MBEDTLS_AES_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif +#include "mbedtls/platform_util.h" + +#include +#include + +/* padlock.c and aesni.c rely on these values! */ +#define MBEDTLS_AES_ENCRYPT 1 /**< AES encryption. */ +#define MBEDTLS_AES_DECRYPT 0 /**< AES decryption. */ + +/* Error codes in range 0x0020-0x0022 */ +/** Invalid key length. */ +#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 +/** Invalid data input length. */ +#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 + +/* Error codes in range 0x0021-0x0025 */ +/** Invalid input data. */ +#define MBEDTLS_ERR_AES_BAD_INPUT_DATA -0x0021 + +/* MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE is deprecated and should not be used. */ +/** Feature not available. For example, an unsupported AES key size. */ +#define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE -0x0023 + +/* MBEDTLS_ERR_AES_HW_ACCEL_FAILED is deprecated and should not be used. */ +/** AES hardware accelerator failed. */ +#define MBEDTLS_ERR_AES_HW_ACCEL_FAILED -0x0025 + +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(MBEDTLS_AES_ALT) +// Regular implementation +// + +/** + * \brief The AES context-type definition. + */ +typedef struct mbedtls_aes_context +{ + int nr; /*!< The number of rounds. */ + uint32_t *rk; /*!< AES round keys. */ + uint32_t buf[68]; /*!< Unaligned data buffer. This buffer can + hold 32 extra Bytes, which can be used for + one of the following purposes: +
  • Alignment if VIA padlock is + used.
  • +
  • Simplifying key expansion in the 256-bit + case by generating an extra round key. +
*/ +} +mbedtls_aes_context; + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +/** + * \brief The AES XTS context-type definition. + */ +typedef struct mbedtls_aes_xts_context +{ + mbedtls_aes_context crypt; /*!< The AES context to use for AES block + encryption or decryption. */ + mbedtls_aes_context tweak; /*!< The AES context used for tweak + computation. */ +} mbedtls_aes_xts_context; +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +#else /* MBEDTLS_AES_ALT */ +#include "aes_alt.h" +#endif /* MBEDTLS_AES_ALT */ + +/** + * \brief This function initializes the specified AES context. + * + * It must be the first API called before using + * the context. + * + * \param ctx The AES context to initialize. This must not be \c NULL. + */ +void mbedtls_aes_init( mbedtls_aes_context *ctx ); + +/** + * \brief This function releases and clears the specified AES context. + * + * \param ctx The AES context to clear. + * If this is \c NULL, this function does nothing. + * Otherwise, the context must have been at least initialized. + */ +void mbedtls_aes_free( mbedtls_aes_context *ctx ); + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +/** + * \brief This function initializes the specified AES XTS context. + * + * It must be the first API called before using + * the context. + * + * \param ctx The AES XTS context to initialize. This must not be \c NULL. + */ +void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx ); + +/** + * \brief This function releases and clears the specified AES XTS context. + * + * \param ctx The AES XTS context to clear. + * If this is \c NULL, this function does nothing. + * Otherwise, the context must have been at least initialized. + */ +void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx ); +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +/** + * \brief This function sets the encryption key. + * + * \param ctx The AES context to which the key should be bound. + * It must be initialized. + * \param key The encryption key. + * This must be a readable buffer of size \p keybits bits. + * \param keybits The size of data passed in bits. Valid options are: + *
  • 128 bits
  • + *
  • 192 bits
  • + *
  • 256 bits
+ * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits ); + +/** + * \brief This function sets the decryption key. + * + * \param ctx The AES context to which the key should be bound. + * It must be initialized. + * \param key The decryption key. + * This must be a readable buffer of size \p keybits bits. + * \param keybits The size of data passed. Valid options are: + *
  • 128 bits
  • + *
  • 192 bits
  • + *
  • 256 bits
+ * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits ); + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +/** + * \brief This function prepares an XTS context for encryption and + * sets the encryption key. + * + * \param ctx The AES XTS context to which the key should be bound. + * It must be initialized. + * \param key The encryption key. This is comprised of the XTS key1 + * concatenated with the XTS key2. + * This must be a readable buffer of size \p keybits bits. + * \param keybits The size of \p key passed in bits. Valid options are: + *
  • 256 bits (each of key1 and key2 is a 128-bit key)
  • + *
  • 512 bits (each of key1 and key2 is a 256-bit key)
+ * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx, + const unsigned char *key, + unsigned int keybits ); + +/** + * \brief This function prepares an XTS context for decryption and + * sets the decryption key. + * + * \param ctx The AES XTS context to which the key should be bound. + * It must be initialized. + * \param key The decryption key. This is comprised of the XTS key1 + * concatenated with the XTS key2. + * This must be a readable buffer of size \p keybits bits. + * \param keybits The size of \p key passed in bits. Valid options are: + *
  • 256 bits (each of key1 and key2 is a 128-bit key)
  • + *
  • 512 bits (each of key1 and key2 is a 256-bit key)
+ * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx, + const unsigned char *key, + unsigned int keybits ); +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +/** + * \brief This function performs an AES single-block encryption or + * decryption operation. + * + * It performs the operation defined in the \p mode parameter + * (encrypt or decrypt), on the input data buffer defined in + * the \p input parameter. + * + * mbedtls_aes_init(), and either mbedtls_aes_setkey_enc() or + * mbedtls_aes_setkey_dec() must be called before the first + * call to this API with the same context. + * + * \param ctx The AES context to use for encryption or decryption. + * It must be initialized and bound to a key. + * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or + * #MBEDTLS_AES_DECRYPT. + * \param input The buffer holding the input data. + * It must be readable and at least \c 16 Bytes long. + * \param output The buffer where the output data will be written. + * It must be writeable and at least \c 16 Bytes long. + + * \return \c 0 on success. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/** + * \brief This function performs an AES-CBC encryption or decryption operation + * on full blocks. + * + * It performs the operation defined in the \p mode + * parameter (encrypt/decrypt), on the input data buffer defined in + * the \p input parameter. + * + * It can be called as many times as needed, until all the input + * data is processed. mbedtls_aes_init(), and either + * mbedtls_aes_setkey_enc() or mbedtls_aes_setkey_dec() must be called + * before the first call to this API with the same context. + * + * \note This function operates on full blocks, that is, the input size + * must be a multiple of the AES block size of \c 16 Bytes. + * + * \note Upon exit, the content of the IV is updated so that you can + * call the same function again on the next + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If you need to retain the contents of the IV, you should + * either save it manually or use the cipher module instead. + * + * + * \param ctx The AES context to use for encryption or decryption. + * It must be initialized and bound to a key. + * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or + * #MBEDTLS_AES_DECRYPT. + * \param length The length of the input data in Bytes. This must be a + * multiple of the block size (\c 16 Bytes). + * \param iv Initialization vector (updated after use). + * It must be a readable and writeable buffer of \c 16 Bytes. + * \param input The buffer holding the input data. + * It must be readable and of size \p length Bytes. + * \param output The buffer holding the output data. + * It must be writeable and of size \p length Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH + * on failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +/** + * \brief This function performs an AES-XTS encryption or decryption + * operation for an entire XTS data unit. + * + * AES-XTS encrypts or decrypts blocks based on their location as + * defined by a data unit number. The data unit number must be + * provided by \p data_unit. + * + * NIST SP 800-38E limits the maximum size of a data unit to 2^20 + * AES blocks. If the data unit is larger than this, this function + * returns #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH. + * + * \param ctx The AES XTS context to use for AES XTS operations. + * It must be initialized and bound to a key. + * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or + * #MBEDTLS_AES_DECRYPT. + * \param length The length of a data unit in Bytes. This can be any + * length between 16 bytes and 2^24 bytes inclusive + * (between 1 and 2^20 block cipher blocks). + * \param data_unit The address of the data unit encoded as an array of 16 + * bytes in little-endian format. For disk encryption, this + * is typically the index of the block device sector that + * contains the data. + * \param input The buffer holding the input data (which is an entire + * data unit). This function reads \p length Bytes from \p + * input. + * \param output The buffer holding the output data (which is an entire + * data unit). This function writes \p length Bytes to \p + * output. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH if \p length is + * smaller than an AES block in size (16 Bytes) or if \p + * length is larger than 2^20 blocks (16 MiB). + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx, + int mode, + size_t length, + const unsigned char data_unit[16], + const unsigned char *input, + unsigned char *output ); +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +/** + * \brief This function performs an AES-CFB128 encryption or decryption + * operation. + * + * It performs the operation defined in the \p mode + * parameter (encrypt or decrypt), on the input data buffer + * defined in the \p input parameter. + * + * For CFB, you must set up the context with mbedtls_aes_setkey_enc(), + * regardless of whether you are performing an encryption or decryption + * operation, that is, regardless of the \p mode parameter. This is + * because CFB mode uses the same key schedule for encryption and + * decryption. + * + * \note Upon exit, the content of the IV is updated so that you can + * call the same function again on the next + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If you need to retain the contents of the + * IV, you must either save it manually or use the cipher + * module instead. + * + * + * \param ctx The AES context to use for encryption or decryption. + * It must be initialized and bound to a key. + * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or + * #MBEDTLS_AES_DECRYPT. + * \param length The length of the input data in Bytes. + * \param iv_off The offset in IV (updated after use). + * It must point to a valid \c size_t. + * \param iv The initialization vector (updated after use). + * It must be a readable and writeable buffer of \c 16 Bytes. + * \param input The buffer holding the input data. + * It must be readable and of size \p length Bytes. + * \param output The buffer holding the output data. + * It must be writeable and of size \p length Bytes. + * + * \return \c 0 on success. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); + +/** + * \brief This function performs an AES-CFB8 encryption or decryption + * operation. + * + * It performs the operation defined in the \p mode + * parameter (encrypt/decrypt), on the input data buffer defined + * in the \p input parameter. + * + * Due to the nature of CFB, you must use the same key schedule for + * both encryption and decryption operations. Therefore, you must + * use the context initialized with mbedtls_aes_setkey_enc() for + * both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT. + * + * \note Upon exit, the content of the IV is updated so that you can + * call the same function again on the next + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * + * \param ctx The AES context to use for encryption or decryption. + * It must be initialized and bound to a key. + * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or + * #MBEDTLS_AES_DECRYPT + * \param length The length of the input data. + * \param iv The initialization vector (updated after use). + * It must be a readable and writeable buffer of \c 16 Bytes. + * \param input The buffer holding the input data. + * It must be readable and of size \p length Bytes. + * \param output The buffer holding the output data. + * It must be writeable and of size \p length Bytes. + * + * \return \c 0 on success. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); +#endif /*MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_OFB) +/** + * \brief This function performs an AES-OFB (Output Feedback Mode) + * encryption or decryption operation. + * + * For OFB, you must set up the context with + * mbedtls_aes_setkey_enc(), regardless of whether you are + * performing an encryption or decryption operation. This is + * because OFB mode uses the same key schedule for encryption and + * decryption. + * + * The OFB operation is identical for encryption or decryption, + * therefore no operation mode needs to be specified. + * + * \note Upon exit, the content of iv, the Initialisation Vector, is + * updated so that you can call the same function again on the next + * block(s) of data and get the same result as if it was encrypted + * in one call. This allows a "streaming" usage, by initialising + * iv_off to 0 before the first call, and preserving its value + * between calls. + * + * For non-streaming use, the iv should be initialised on each call + * to a unique value, and iv_off set to 0 on each call. + * + * If you need to retain the contents of the initialisation vector, + * you must either save it manually or use the cipher module + * instead. + * + * \warning For the OFB mode, the initialisation vector must be unique + * every encryption operation. Reuse of an initialisation vector + * will compromise security. + * + * \param ctx The AES context to use for encryption or decryption. + * It must be initialized and bound to a key. + * \param length The length of the input data. + * \param iv_off The offset in IV (updated after use). + * It must point to a valid \c size_t. + * \param iv The initialization vector (updated after use). + * It must be a readable and writeable buffer of \c 16 Bytes. + * \param input The buffer holding the input data. + * It must be readable and of size \p length Bytes. + * \param output The buffer holding the output data. + * It must be writeable and of size \p length Bytes. + * + * \return \c 0 on success. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); + +#endif /* MBEDTLS_CIPHER_MODE_OFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/** + * \brief This function performs an AES-CTR encryption or decryption + * operation. + * + * Due to the nature of CTR, you must use the same key schedule + * for both encryption and decryption operations. Therefore, you + * must use the context initialized with mbedtls_aes_setkey_enc() + * for both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT. + * + * \warning You must never reuse a nonce value with the same key. Doing so + * would void the encryption for the two messages encrypted with + * the same nonce and key. + * + * There are two common strategies for managing nonces with CTR: + * + * 1. You can handle everything as a single message processed over + * successive calls to this function. In that case, you want to + * set \p nonce_counter and \p nc_off to 0 for the first call, and + * then preserve the values of \p nonce_counter, \p nc_off and \p + * stream_block across calls to this function as they will be + * updated by this function. + * + * With this strategy, you must not encrypt more than 2**128 + * blocks of data with the same key. + * + * 2. You can encrypt separate messages by dividing the \p + * nonce_counter buffer in two areas: the first one used for a + * per-message nonce, handled by yourself, and the second one + * updated by this function internally. + * + * For example, you might reserve the first 12 bytes for the + * per-message nonce, and the last 4 bytes for internal use. In that + * case, before calling this function on a new message you need to + * set the first 12 bytes of \p nonce_counter to your chosen nonce + * value, the last 4 to 0, and \p nc_off to 0 (which will cause \p + * stream_block to be ignored). That way, you can encrypt at most + * 2**96 messages of up to 2**32 blocks each with the same key. + * + * The per-message nonce (or information sufficient to reconstruct + * it) needs to be communicated with the ciphertext and must be unique. + * The recommended way to ensure uniqueness is to use a message + * counter. An alternative is to generate random nonces, but this + * limits the number of messages that can be securely encrypted: + * for example, with 96-bit random nonces, you should not encrypt + * more than 2**32 messages with the same key. + * + * Note that for both strategies, sizes are measured in blocks and + * that an AES block is 16 bytes. + * + * \warning Upon return, \p stream_block contains sensitive data. Its + * content must not be written to insecure storage and should be + * securely discarded as soon as it's no longer needed. + * + * \param ctx The AES context to use for encryption or decryption. + * It must be initialized and bound to a key. + * \param length The length of the input data. + * \param nc_off The offset in the current \p stream_block, for + * resuming within the current cipher stream. The + * offset pointer should be 0 at the start of a stream. + * It must point to a valid \c size_t. + * \param nonce_counter The 128-bit nonce and counter. + * It must be a readable-writeable buffer of \c 16 Bytes. + * \param stream_block The saved stream block for resuming. This is + * overwritten by the function. + * It must be a readable-writeable buffer of \c 16 Bytes. + * \param input The buffer holding the input data. + * It must be readable and of size \p length Bytes. + * \param output The buffer holding the output data. + * It must be writeable and of size \p length Bytes. + * + * \return \c 0 on success. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output ); +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +/** + * \brief Internal AES block encryption function. This is only + * exposed to allow overriding it using + * \c MBEDTLS_AES_ENCRYPT_ALT. + * + * \param ctx The AES context to use for encryption. + * \param input The plaintext block. + * \param output The output (ciphertext) block. + * + * \return \c 0 on success. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ); + +/** + * \brief Internal AES block decryption function. This is only + * exposed to allow overriding it using see + * \c MBEDTLS_AES_DECRYPT_ALT. + * + * \param ctx The AES context to use for decryption. + * \param input The ciphertext block. + * \param output The output (plaintext) block. + * + * \return \c 0 on success. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ); + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif +/** + * \brief Deprecated internal AES block encryption function + * without return value. + * + * \deprecated Superseded by mbedtls_internal_aes_encrypt() + * + * \param ctx The AES context to use for encryption. + * \param input Plaintext block. + * \param output Output (ciphertext) block. + */ +MBEDTLS_DEPRECATED void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ); + +/** + * \brief Deprecated internal AES block decryption function + * without return value. + * + * \deprecated Superseded by mbedtls_internal_aes_decrypt() + * + * \param ctx The AES context to use for decryption. + * \param input Ciphertext block. + * \param output Output (plaintext) block. + */ +MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ); + +#undef MBEDTLS_DEPRECATED +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ + + +#if defined(MBEDTLS_SELF_TEST) +/** + * \brief Checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +MBEDTLS_CHECK_RETURN_CRITICAL +int mbedtls_aes_self_test( int verbose ); + +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + +#endif /* aes.h */ diff --git a/third_party/mbedtls/include/mbedtls/asn1.h b/third_party/mbedtls/include/mbedtls/asn1.h new file mode 100644 index 0000000..5117fc7 --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/asn1.h @@ -0,0 +1,616 @@ +/** + * \file asn1.h + * + * \brief Generic ASN.1 parsing + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBEDTLS_ASN1_H +#define MBEDTLS_ASN1_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include + +#if defined(MBEDTLS_BIGNUM_C) +#include "mbedtls/bignum.h" +#endif + +/** + * \addtogroup asn1_module + * \{ + */ + +/** + * \name ASN1 Error codes + * These error codes are OR'ed to X509 error codes for + * higher error granularity. + * ASN1 is a standard to specify data structures. + * \{ + */ +/** Out of data when parsing an ASN1 data structure. */ +#define MBEDTLS_ERR_ASN1_OUT_OF_DATA -0x0060 +/** ASN1 tag was of an unexpected value. */ +#define MBEDTLS_ERR_ASN1_UNEXPECTED_TAG -0x0062 +/** Error when trying to determine the length or invalid length. */ +#define MBEDTLS_ERR_ASN1_INVALID_LENGTH -0x0064 +/** Actual length differs from expected length. */ +#define MBEDTLS_ERR_ASN1_LENGTH_MISMATCH -0x0066 +/** Data is invalid. */ +#define MBEDTLS_ERR_ASN1_INVALID_DATA -0x0068 +/** Memory allocation failed */ +#define MBEDTLS_ERR_ASN1_ALLOC_FAILED -0x006A +/** Buffer too small when writing ASN.1 data structure. */ +#define MBEDTLS_ERR_ASN1_BUF_TOO_SMALL -0x006C + +/** \} name ASN1 Error codes */ + +/** + * \name DER constants + * These constants comply with the DER encoded ASN.1 type tags. + * DER encoding uses hexadecimal representation. + * An example DER sequence is:\n + * - 0x02 -- tag indicating INTEGER + * - 0x01 -- length in octets + * - 0x05 -- value + * Such sequences are typically read into \c ::mbedtls_x509_buf. + * \{ + */ +#define MBEDTLS_ASN1_BOOLEAN 0x01 +#define MBEDTLS_ASN1_INTEGER 0x02 +#define MBEDTLS_ASN1_BIT_STRING 0x03 +#define MBEDTLS_ASN1_OCTET_STRING 0x04 +#define MBEDTLS_ASN1_NULL 0x05 +#define MBEDTLS_ASN1_OID 0x06 +#define MBEDTLS_ASN1_ENUMERATED 0x0A +#define MBEDTLS_ASN1_UTF8_STRING 0x0C +#define MBEDTLS_ASN1_SEQUENCE 0x10 +#define MBEDTLS_ASN1_SET 0x11 +#define MBEDTLS_ASN1_PRINTABLE_STRING 0x13 +#define MBEDTLS_ASN1_T61_STRING 0x14 +#define MBEDTLS_ASN1_IA5_STRING 0x16 +#define MBEDTLS_ASN1_UTC_TIME 0x17 +#define MBEDTLS_ASN1_GENERALIZED_TIME 0x18 +#define MBEDTLS_ASN1_UNIVERSAL_STRING 0x1C +#define MBEDTLS_ASN1_BMP_STRING 0x1E +#define MBEDTLS_ASN1_PRIMITIVE 0x00 +#define MBEDTLS_ASN1_CONSTRUCTED 0x20 +#define MBEDTLS_ASN1_CONTEXT_SPECIFIC 0x80 + +/* Slightly smaller way to check if tag is a string tag + * compared to canonical implementation. */ +#define MBEDTLS_ASN1_IS_STRING_TAG( tag ) \ + ( ( tag ) < 32u && ( \ + ( ( 1u << ( tag ) ) & ( ( 1u << MBEDTLS_ASN1_BMP_STRING ) | \ + ( 1u << MBEDTLS_ASN1_UTF8_STRING ) | \ + ( 1u << MBEDTLS_ASN1_T61_STRING ) | \ + ( 1u << MBEDTLS_ASN1_IA5_STRING ) | \ + ( 1u << MBEDTLS_ASN1_UNIVERSAL_STRING ) | \ + ( 1u << MBEDTLS_ASN1_PRINTABLE_STRING ) | \ + ( 1u << MBEDTLS_ASN1_BIT_STRING ) ) ) != 0 ) ) + +/* + * Bit masks for each of the components of an ASN.1 tag as specified in + * ITU X.690 (08/2015), section 8.1 "General rules for encoding", + * paragraph 8.1.2.2: + * + * Bit 8 7 6 5 1 + * +-------+-----+------------+ + * | Class | P/C | Tag number | + * +-------+-----+------------+ + */ +#define MBEDTLS_ASN1_TAG_CLASS_MASK 0xC0 +#define MBEDTLS_ASN1_TAG_PC_MASK 0x20 +#define MBEDTLS_ASN1_TAG_VALUE_MASK 0x1F + +/** \} name DER constants */ + +/** Returns the size of the binary string, without the trailing \\0 */ +#define MBEDTLS_OID_SIZE(x) (sizeof(x) - 1) + +/** + * Compares an mbedtls_asn1_buf structure to a reference OID. + * + * Only works for 'defined' oid_str values (MBEDTLS_OID_HMAC_SHA1), you cannot use a + * 'unsigned char *oid' here! + */ +#define MBEDTLS_OID_CMP(oid_str, oid_buf) \ + ( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len ) || \ + memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 ) + +#define MBEDTLS_OID_CMP_RAW(oid_str, oid_buf, oid_buf_len) \ + ( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf_len) ) || \ + memcmp( (oid_str), (oid_buf), (oid_buf_len) ) != 0 ) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name Functions to parse ASN.1 data structures + * \{ + */ + +/** + * Type-length-value structure that allows for ASN1 using DER. + */ +typedef struct mbedtls_asn1_buf +{ + int tag; /**< ASN1 type, e.g. MBEDTLS_ASN1_UTF8_STRING. */ + size_t len; /**< ASN1 length, in octets. */ + unsigned char *p; /**< ASN1 data, e.g. in ASCII. */ +} +mbedtls_asn1_buf; + +/** + * Container for ASN1 bit strings. + */ +typedef struct mbedtls_asn1_bitstring +{ + size_t len; /**< ASN1 length, in octets. */ + unsigned char unused_bits; /**< Number of unused bits at the end of the string */ + unsigned char *p; /**< Raw ASN1 data for the bit string */ +} +mbedtls_asn1_bitstring; + +/** + * Container for a sequence of ASN.1 items + */ +typedef struct mbedtls_asn1_sequence +{ + mbedtls_asn1_buf buf; /**< Buffer containing the given ASN.1 item. */ + struct mbedtls_asn1_sequence *next; /**< The next entry in the sequence. */ +} +mbedtls_asn1_sequence; + +/** + * Container for a sequence or list of 'named' ASN.1 data items + */ +typedef struct mbedtls_asn1_named_data +{ + mbedtls_asn1_buf oid; /**< The object identifier. */ + mbedtls_asn1_buf val; /**< The named value. */ + struct mbedtls_asn1_named_data *next; /**< The next entry in the sequence. */ + unsigned char next_merged; /**< Merge next item into the current one? */ +} +mbedtls_asn1_named_data; + +/** + * \brief Get the length of an ASN.1 element. + * Updates the pointer to immediately behind the length. + * + * \param p On entry, \c *p points to the first byte of the length, + * i.e. immediately after the tag. + * On successful completion, \c *p points to the first byte + * after the length, i.e. the first byte of the content. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param len On successful completion, \c *len contains the length + * read from the ASN.1 input. + * + * \return 0 if successful. + * \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element + * would end beyond \p end. + * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparsable. + */ +int mbedtls_asn1_get_len( unsigned char **p, + const unsigned char *end, + size_t *len ); + +/** + * \brief Get the tag and length of the element. + * Check for the requested tag. + * Updates the pointer to immediately behind the tag and length. + * + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * after the length, i.e. the first byte of the content. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param len On successful completion, \c *len contains the length + * read from the ASN.1 input. + * \param tag The expected tag. + * + * \return 0 if successful. + * \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the data does not start + * with the requested tag. + * \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element + * would end beyond \p end. + * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparsable. + */ +int mbedtls_asn1_get_tag( unsigned char **p, + const unsigned char *end, + size_t *len, int tag ); + +/** + * \brief Retrieve a boolean ASN.1 tag and its value. + * Updates the pointer to immediately behind the full tag. + * + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * beyond the ASN.1 element. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param val On success, the parsed value (\c 0 or \c 1). + * + * \return 0 if successful. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 BOOLEAN. + */ +int mbedtls_asn1_get_bool( unsigned char **p, + const unsigned char *end, + int *val ); + +/** + * \brief Retrieve an integer ASN.1 tag and its value. + * Updates the pointer to immediately behind the full tag. + * + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * beyond the ASN.1 element. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param val On success, the parsed value. + * + * \return 0 if successful. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 INTEGER. + * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does + * not fit in an \c int. + */ +int mbedtls_asn1_get_int( unsigned char **p, + const unsigned char *end, + int *val ); + +/** + * \brief Retrieve an enumerated ASN.1 tag and its value. + * Updates the pointer to immediately behind the full tag. + * + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * beyond the ASN.1 element. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param val On success, the parsed value. + * + * \return 0 if successful. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 ENUMERATED. + * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does + * not fit in an \c int. + */ +int mbedtls_asn1_get_enum( unsigned char **p, + const unsigned char *end, + int *val ); + +/** + * \brief Retrieve a bitstring ASN.1 tag and its value. + * Updates the pointer to immediately behind the full tag. + * + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p is equal to \p end. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param bs On success, ::mbedtls_asn1_bitstring information about + * the parsed value. + * + * \return 0 if successful. + * \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains + * extra data after a valid BIT STRING. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 BIT STRING. + */ +int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end, + mbedtls_asn1_bitstring *bs ); + +/** + * \brief Retrieve a bitstring ASN.1 tag without unused bits and its + * value. + * Updates the pointer to the beginning of the bit/octet string. + * + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * of the content of the BIT STRING. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param len On success, \c *len is the length of the content in bytes. + * + * \return 0 if successful. + * \return #MBEDTLS_ERR_ASN1_INVALID_DATA if the input starts with + * a valid BIT STRING with a nonzero number of unused bits. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 BIT STRING. + */ +int mbedtls_asn1_get_bitstring_null( unsigned char **p, + const unsigned char *end, + size_t *len ); + +/** + * \brief Parses and splits an ASN.1 "SEQUENCE OF ". + * Updates the pointer to immediately behind the full sequence tag. + * + * This function allocates memory for the sequence elements. You can free + * the allocated memory with mbedtls_asn1_sequence_free(). + * + * \note On error, this function may return a partial list in \p cur. + * You must set `cur->next = NULL` before calling this function! + * Otherwise it is impossible to distinguish a previously non-null + * pointer from a pointer to an object allocated by this function. + * + * \note If the sequence is empty, this function does not modify + * \c *cur. If the sequence is valid and non-empty, this + * function sets `cur->buf.tag` to \p tag. This allows + * callers to distinguish between an empty sequence and + * a one-element sequence. + * + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p is equal to \p end. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param cur A ::mbedtls_asn1_sequence which this function fills. + * When this function returns, \c *cur is the head of a linked + * list. Each node in this list is allocated with + * mbedtls_calloc() apart from \p cur itself, and should + * therefore be freed with mbedtls_free(). + * The list describes the content of the sequence. + * The head of the list (i.e. \c *cur itself) describes the + * first element, `*cur->next` describes the second element, etc. + * For each element, `buf.tag == tag`, `buf.len` is the length + * of the content of the content of the element, and `buf.p` + * points to the first byte of the content (i.e. immediately + * past the length of the element). + * Note that list elements may be allocated even on error. + * \param tag Each element of the sequence must have this tag. + * + * \return 0 if successful. + * \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains + * extra data after a valid SEQUENCE OF \p tag. + * \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the input starts with + * an ASN.1 SEQUENCE in which an element has a tag that + * is different from \p tag. + * \return #MBEDTLS_ERR_ASN1_ALLOC_FAILED if a memory allocation failed. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 SEQUENCE. + */ +int mbedtls_asn1_get_sequence_of( unsigned char **p, + const unsigned char *end, + mbedtls_asn1_sequence *cur, + int tag ); +/** + * \brief Free a heap-allocated linked list presentation of + * an ASN.1 sequence, including the first element. + * + * There are two common ways to manage the memory used for the representation + * of a parsed ASN.1 sequence: + * - Allocate a head node `mbedtls_asn1_sequence *head` with mbedtls_calloc(). + * Pass this node as the `cur` argument to mbedtls_asn1_get_sequence_of(). + * When you have finished processing the sequence, + * call mbedtls_asn1_sequence_free() on `head`. + * - Allocate a head node `mbedtls_asn1_sequence *head` in any manner, + * for example on the stack. Make sure that `head->next == NULL`. + * Pass `head` as the `cur` argument to mbedtls_asn1_get_sequence_of(). + * When you have finished processing the sequence, + * call mbedtls_asn1_sequence_free() on `head->cur`, + * then free `head` itself in the appropriate manner. + * + * \param seq The address of the first sequence component. This may + * be \c NULL, in which case this functions returns + * immediately. + */ +void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq ); + +/** + * \brief Traverse an ASN.1 SEQUENCE container and + * call a callback for each entry. + * + * This function checks that the input is a SEQUENCE of elements that + * each have a "must" tag, and calls a callback function on the elements + * that have a "may" tag. + * + * For example, to validate that the input is a SEQUENCE of `tag1` and call + * `cb` on each element, use + * ``` + * mbedtls_asn1_traverse_sequence_of(&p, end, 0xff, tag1, 0, 0, cb, ctx); + * ``` + * + * To validate that the input is a SEQUENCE of ANY and call `cb` on + * each element, use + * ``` + * mbedtls_asn1_traverse_sequence_of(&p, end, 0, 0, 0, 0, cb, ctx); + * ``` + * + * To validate that the input is a SEQUENCE of CHOICE {NULL, OCTET STRING} + * and call `cb` on each element that is an OCTET STRING, use + * ``` + * mbedtls_asn1_traverse_sequence_of(&p, end, 0xfe, 0x04, 0xff, 0x04, cb, ctx); + * ``` + * + * The callback is called on the elements with a "may" tag from left to + * right. If the input is not a valid SEQUENCE of elements with a "must" tag, + * the callback is called on the elements up to the leftmost point where + * the input is invalid. + * + * \warning This function is still experimental and may change + * at any time. + * + * \param p The address of the pointer to the beginning of + * the ASN.1 SEQUENCE header. This is updated to + * point to the end of the ASN.1 SEQUENCE container + * on a successful invocation. + * \param end The end of the ASN.1 SEQUENCE container. + * \param tag_must_mask A mask to be applied to the ASN.1 tags found within + * the SEQUENCE before comparing to \p tag_must_value. + * \param tag_must_val The required value of each ASN.1 tag found in the + * SEQUENCE, after masking with \p tag_must_mask. + * Mismatching tags lead to an error. + * For example, a value of \c 0 for both \p tag_must_mask + * and \p tag_must_val means that every tag is allowed, + * while a value of \c 0xFF for \p tag_must_mask means + * that \p tag_must_val is the only allowed tag. + * \param tag_may_mask A mask to be applied to the ASN.1 tags found within + * the SEQUENCE before comparing to \p tag_may_value. + * \param tag_may_val The desired value of each ASN.1 tag found in the + * SEQUENCE, after masking with \p tag_may_mask. + * Mismatching tags will be silently ignored. + * For example, a value of \c 0 for \p tag_may_mask and + * \p tag_may_val means that any tag will be considered, + * while a value of \c 0xFF for \p tag_may_mask means + * that all tags with value different from \p tag_may_val + * will be ignored. + * \param cb The callback to trigger for each component + * in the ASN.1 SEQUENCE that matches \p tag_may_val. + * The callback function is called with the following + * parameters: + * - \p ctx. + * - The tag of the current element. + * - A pointer to the start of the current element's + * content inside the input. + * - The length of the content of the current element. + * If the callback returns a non-zero value, + * the function stops immediately, + * forwarding the callback's return value. + * \param ctx The context to be passed to the callback \p cb. + * + * \return \c 0 if successful the entire ASN.1 SEQUENCE + * was traversed without parsing or callback errors. + * \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input + * contains extra data after a valid SEQUENCE + * of elements with an accepted tag. + * \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the input starts + * with an ASN.1 SEQUENCE in which an element has a tag + * that is not accepted. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 SEQUENCE. + * \return A non-zero error code forwarded from the callback + * \p cb in case the latter returns a non-zero value. + */ +int mbedtls_asn1_traverse_sequence_of( + unsigned char **p, + const unsigned char *end, + unsigned char tag_must_mask, unsigned char tag_must_val, + unsigned char tag_may_mask, unsigned char tag_may_val, + int (*cb)( void *ctx, int tag, + unsigned char* start, size_t len ), + void *ctx ); + +#if defined(MBEDTLS_BIGNUM_C) +/** + * \brief Retrieve an integer ASN.1 tag and its value. + * Updates the pointer to immediately behind the full tag. + * + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * beyond the ASN.1 element. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param X On success, the parsed value. + * + * \return 0 if successful. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 INTEGER. + * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does + * not fit in an \c int. + * \return An MPI error code if the parsed value is too large. + */ +int mbedtls_asn1_get_mpi( unsigned char **p, + const unsigned char *end, + mbedtls_mpi *X ); +#endif /* MBEDTLS_BIGNUM_C */ + +/** + * \brief Retrieve an AlgorithmIdentifier ASN.1 sequence. + * Updates the pointer to immediately behind the full + * AlgorithmIdentifier. + * + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * beyond the AlgorithmIdentifier element. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param alg The buffer to receive the OID. + * \param params The buffer to receive the parameters. + * This is zeroized if there are no parameters. + * + * \return 0 if successful or a specific ASN.1 or MPI error code. + */ +int mbedtls_asn1_get_alg( unsigned char **p, + const unsigned char *end, + mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params ); + +/** + * \brief Retrieve an AlgorithmIdentifier ASN.1 sequence with NULL or no + * params. + * Updates the pointer to immediately behind the full + * AlgorithmIdentifier. + * + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * beyond the AlgorithmIdentifier element. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param alg The buffer to receive the OID. + * + * \return 0 if successful or a specific ASN.1 or MPI error code. + */ +int mbedtls_asn1_get_alg_null( unsigned char **p, + const unsigned char *end, + mbedtls_asn1_buf *alg ); + +/** + * \brief Find a specific named_data entry in a sequence or list based on + * the OID. + * + * \param list The list to seek through + * \param oid The OID to look for + * \param len Size of the OID + * + * \return NULL if not found, or a pointer to the existing entry. + */ +mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list, + const char *oid, size_t len ); + +/** + * \brief Free a mbedtls_asn1_named_data entry + * + * \param entry The named data entry to free. + * This function calls mbedtls_free() on + * `entry->oid.p` and `entry->val.p`. + */ +void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *entry ); + +/** + * \brief Free all entries in a mbedtls_asn1_named_data list. + * + * \param head Pointer to the head of the list of named data entries to free. + * This function calls mbedtls_asn1_free_named_data() and + * mbedtls_free() on each list element and + * sets \c *head to \c NULL. + */ +void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head ); + +/** \} name Functions to parse ASN.1 data structures */ +/** \} addtogroup asn1_module */ + +#ifdef __cplusplus +} +#endif + +#endif /* asn1.h */ diff --git a/third_party/mbedtls/include/mbedtls/bignum.h b/third_party/mbedtls/include/mbedtls/bignum.h new file mode 100644 index 0000000..dd594c5 --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/bignum.h @@ -0,0 +1,1063 @@ +/** + * \file bignum.h + * + * \brief Multi-precision integer library + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBEDTLS_BIGNUM_H +#define MBEDTLS_BIGNUM_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include +#include + +#if defined(MBEDTLS_FS_IO) +#include +#endif + +/** An error occurred while reading from or writing to a file. */ +#define MBEDTLS_ERR_MPI_FILE_IO_ERROR -0x0002 +/** Bad input parameters to function. */ +#define MBEDTLS_ERR_MPI_BAD_INPUT_DATA -0x0004 +/** There is an invalid character in the digit string. */ +#define MBEDTLS_ERR_MPI_INVALID_CHARACTER -0x0006 +/** The buffer is too small to write to. */ +#define MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL -0x0008 +/** The input arguments are negative or result in illegal output. */ +#define MBEDTLS_ERR_MPI_NEGATIVE_VALUE -0x000A +/** The input argument for division is zero, which is not allowed. */ +#define MBEDTLS_ERR_MPI_DIVISION_BY_ZERO -0x000C +/** The input arguments are not acceptable. */ +#define MBEDTLS_ERR_MPI_NOT_ACCEPTABLE -0x000E +/** Memory allocation failed. */ +#define MBEDTLS_ERR_MPI_ALLOC_FAILED -0x0010 + +#define MBEDTLS_MPI_CHK(f) \ + do \ + { \ + if( ( ret = (f) ) != 0 ) \ + goto cleanup; \ + } while( 0 ) + +/* + * Maximum size MPIs are allowed to grow to in number of limbs. + */ +#define MBEDTLS_MPI_MAX_LIMBS 10000 + +#if !defined(MBEDTLS_MPI_WINDOW_SIZE) +/* + * Maximum window size used for modular exponentiation. Default: 6 + * Minimum value: 1. Maximum value: 6. + * + * Result is an array of ( 2 ** MBEDTLS_MPI_WINDOW_SIZE ) MPIs used + * for the sliding window calculation. (So 64 by default) + * + * Reduction in size, reduces speed. + */ +#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum window size used. */ +#endif /* !MBEDTLS_MPI_WINDOW_SIZE */ + +#if !defined(MBEDTLS_MPI_MAX_SIZE) +/* + * Maximum size of MPIs allowed in bits and bytes for user-MPIs. + * ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits ) + * + * Note: Calculations can temporarily result in larger MPIs. So the number + * of limbs required (MBEDTLS_MPI_MAX_LIMBS) is higher. + */ +#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ +#endif /* !MBEDTLS_MPI_MAX_SIZE */ + +#define MBEDTLS_MPI_MAX_BITS ( 8 * MBEDTLS_MPI_MAX_SIZE ) /**< Maximum number of bits for usable MPIs. */ + +/* + * When reading from files with mbedtls_mpi_read_file() and writing to files with + * mbedtls_mpi_write_file() the buffer should have space + * for a (short) label, the MPI (in the provided radix), the newline + * characters and the '\0'. + * + * By default we assume at least a 10 char label, a minimum radix of 10 + * (decimal) and a maximum of 4096 bit numbers (1234 decimal chars). + * Autosized at compile time for at least a 10 char label, a minimum radix + * of 10 (decimal) for a number of MBEDTLS_MPI_MAX_BITS size. + * + * This used to be statically sized to 1250 for a maximum of 4096 bit + * numbers (1234 decimal chars). + * + * Calculate using the formula: + * MBEDTLS_MPI_RW_BUFFER_SIZE = ceil(MBEDTLS_MPI_MAX_BITS / ln(10) * ln(2)) + + * LabelSize + 6 + */ +#define MBEDTLS_MPI_MAX_BITS_SCALE100 ( 100 * MBEDTLS_MPI_MAX_BITS ) +#define MBEDTLS_LN_2_DIV_LN_10_SCALE100 332 +#define MBEDTLS_MPI_RW_BUFFER_SIZE ( ((MBEDTLS_MPI_MAX_BITS_SCALE100 + MBEDTLS_LN_2_DIV_LN_10_SCALE100 - 1) / MBEDTLS_LN_2_DIV_LN_10_SCALE100) + 10 + 6 ) + +/* + * Define the base integer type, architecture-wise. + * + * 32 or 64-bit integer types can be forced regardless of the underlying + * architecture by defining MBEDTLS_HAVE_INT32 or MBEDTLS_HAVE_INT64 + * respectively and undefining MBEDTLS_HAVE_ASM. + * + * Double-width integers (e.g. 128-bit in 64-bit architectures) can be + * disabled by defining MBEDTLS_NO_UDBL_DIVISION. + */ +#if !defined(MBEDTLS_HAVE_INT32) + #if defined(_MSC_VER) && defined(_M_AMD64) + /* Always choose 64-bit when using MSC */ + #if !defined(MBEDTLS_HAVE_INT64) + #define MBEDTLS_HAVE_INT64 + #endif /* !MBEDTLS_HAVE_INT64 */ + typedef int64_t mbedtls_mpi_sint; + typedef uint64_t mbedtls_mpi_uint; + #elif defined(__GNUC__) && ( \ + defined(__amd64__) || defined(__x86_64__) || \ + defined(__ppc64__) || defined(__powerpc64__) || \ + defined(__ia64__) || defined(__alpha__) || \ + ( defined(__sparc__) && defined(__arch64__) ) || \ + defined(__s390x__) || defined(__mips64) || \ + defined(__aarch64__) ) + #if !defined(MBEDTLS_HAVE_INT64) + #define MBEDTLS_HAVE_INT64 + #endif /* MBEDTLS_HAVE_INT64 */ + typedef int64_t mbedtls_mpi_sint; + typedef uint64_t mbedtls_mpi_uint; + #if !defined(MBEDTLS_NO_UDBL_DIVISION) + /* mbedtls_t_udbl defined as 128-bit unsigned int */ + typedef unsigned int mbedtls_t_udbl __attribute__((mode(TI))); + #define MBEDTLS_HAVE_UDBL + #endif /* !MBEDTLS_NO_UDBL_DIVISION */ + #elif defined(__ARMCC_VERSION) && defined(__aarch64__) + /* + * __ARMCC_VERSION is defined for both armcc and armclang and + * __aarch64__ is only defined by armclang when compiling 64-bit code + */ + #if !defined(MBEDTLS_HAVE_INT64) + #define MBEDTLS_HAVE_INT64 + #endif /* !MBEDTLS_HAVE_INT64 */ + typedef int64_t mbedtls_mpi_sint; + typedef uint64_t mbedtls_mpi_uint; + #if !defined(MBEDTLS_NO_UDBL_DIVISION) + /* mbedtls_t_udbl defined as 128-bit unsigned int */ + typedef __uint128_t mbedtls_t_udbl; + #define MBEDTLS_HAVE_UDBL + #endif /* !MBEDTLS_NO_UDBL_DIVISION */ + #elif defined(MBEDTLS_HAVE_INT64) + /* Force 64-bit integers with unknown compiler */ + typedef int64_t mbedtls_mpi_sint; + typedef uint64_t mbedtls_mpi_uint; + #endif +#endif /* !MBEDTLS_HAVE_INT32 */ + +#if !defined(MBEDTLS_HAVE_INT64) + /* Default to 32-bit compilation */ + #if !defined(MBEDTLS_HAVE_INT32) + #define MBEDTLS_HAVE_INT32 + #endif /* !MBEDTLS_HAVE_INT32 */ + typedef int32_t mbedtls_mpi_sint; + typedef uint32_t mbedtls_mpi_uint; + #if !defined(MBEDTLS_NO_UDBL_DIVISION) + typedef uint64_t mbedtls_t_udbl; + #define MBEDTLS_HAVE_UDBL + #endif /* !MBEDTLS_NO_UDBL_DIVISION */ +#endif /* !MBEDTLS_HAVE_INT64 */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief MPI structure + */ +typedef struct mbedtls_mpi +{ + int s; /*!< Sign: -1 if the mpi is negative, 1 otherwise */ + size_t n; /*!< total # of limbs */ + mbedtls_mpi_uint *p; /*!< pointer to limbs */ +} +mbedtls_mpi; + +/** + * \brief Initialize an MPI context. + * + * This makes the MPI ready to be set or freed, + * but does not define a value for the MPI. + * + * \param X The MPI context to initialize. This must not be \c NULL. + */ +void mbedtls_mpi_init( mbedtls_mpi *X ); + +/** + * \brief This function frees the components of an MPI context. + * + * \param X The MPI context to be cleared. This may be \c NULL, + * in which case this function is a no-op. If it is + * not \c NULL, it must point to an initialized MPI. + */ +void mbedtls_mpi_free( mbedtls_mpi *X ); + +/** + * \brief Enlarge an MPI to the specified number of limbs. + * + * \note This function does nothing if the MPI is + * already large enough. + * + * \param X The MPI to grow. It must be initialized. + * \param nblimbs The target number of limbs. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs ); + +/** + * \brief This function resizes an MPI downwards, keeping at least the + * specified number of limbs. + * + * If \c X is smaller than \c nblimbs, it is resized up + * instead. + * + * \param X The MPI to shrink. This must point to an initialized MPI. + * \param nblimbs The minimum number of limbs to keep. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed + * (this can only happen when resizing up). + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs ); + +/** + * \brief Make a copy of an MPI. + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param Y The source MPI. This must point to an initialized MPI. + * + * \note The limb-buffer in the destination MPI is enlarged + * if necessary to hold the value in the source MPI. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y ); + +/** + * \brief Swap the contents of two MPIs. + * + * \param X The first MPI. It must be initialized. + * \param Y The second MPI. It must be initialized. + */ +void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y ); + +/** + * \brief Perform a safe conditional copy of MPI which doesn't + * reveal whether the condition was true or not. + * + * \param X The MPI to conditionally assign to. This must point + * to an initialized MPI. + * \param Y The MPI to be assigned from. This must point to an + * initialized MPI. + * \param assign The condition deciding whether to perform the + * assignment or not. Possible values: + * * \c 1: Perform the assignment `X = Y`. + * * \c 0: Keep the original value of \p X. + * + * \note This function is equivalent to + * `if( assign ) mbedtls_mpi_copy( X, Y );` + * except that it avoids leaking any information about whether + * the assignment was done or not (the above code may leak + * information through branch prediction and/or memory access + * patterns analysis). + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign ); + +/** + * \brief Perform a safe conditional swap which doesn't + * reveal whether the condition was true or not. + * + * \param X The first MPI. This must be initialized. + * \param Y The second MPI. This must be initialized. + * \param assign The condition deciding whether to perform + * the swap or not. Possible values: + * * \c 1: Swap the values of \p X and \p Y. + * * \c 0: Keep the original values of \p X and \p Y. + * + * \note This function is equivalent to + * if( assign ) mbedtls_mpi_swap( X, Y ); + * except that it avoids leaking any information about whether + * the assignment was done or not (the above code may leak + * information through branch prediction and/or memory access + * patterns analysis). + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return Another negative error code on other kinds of failure. + * + */ +int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char assign ); + +/** + * \brief Store integer value in MPI. + * + * \param X The MPI to set. This must be initialized. + * \param z The value to use. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z ); + +/** + * \brief Get a specific bit from an MPI. + * + * \param X The MPI to query. This must be initialized. + * \param pos Zero-based index of the bit to query. + * + * \return \c 0 or \c 1 on success, depending on whether bit \c pos + * of \c X is unset or set. + * \return A negative error code on failure. + */ +int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos ); + +/** + * \brief Modify a specific bit in an MPI. + * + * \note This function will grow the target MPI if necessary to set a + * bit to \c 1 in a not yet existing limb. It will not grow if + * the bit should be set to \c 0. + * + * \param X The MPI to modify. This must be initialized. + * \param pos Zero-based index of the bit to modify. + * \param val The desired value of bit \c pos: \c 0 or \c 1. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val ); + +/** + * \brief Return the number of bits of value \c 0 before the + * least significant bit of value \c 1. + * + * \note This is the same as the zero-based index of + * the least significant bit of value \c 1. + * + * \param X The MPI to query. + * + * \return The number of bits of value \c 0 before the least significant + * bit of value \c 1 in \p X. + */ +size_t mbedtls_mpi_lsb( const mbedtls_mpi *X ); + +/** + * \brief Return the number of bits up to and including the most + * significant bit of value \c 1. + * + * * \note This is same as the one-based index of the most + * significant bit of value \c 1. + * + * \param X The MPI to query. This must point to an initialized MPI. + * + * \return The number of bits up to and including the most + * significant bit of value \c 1. + */ +size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X ); + +/** + * \brief Return the total size of an MPI value in bytes. + * + * \param X The MPI to use. This must point to an initialized MPI. + * + * \note The value returned by this function may be less than + * the number of bytes used to store \p X internally. + * This happens if and only if there are trailing bytes + * of value zero. + * + * \return The least number of bytes capable of storing + * the absolute value of \p X. + */ +size_t mbedtls_mpi_size( const mbedtls_mpi *X ); + +/** + * \brief Import an MPI from an ASCII string. + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param radix The numeric base of the input string. + * \param s Null-terminated string buffer. + * + * \return \c 0 if successful. + * \return A negative error code on failure. + */ +int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s ); + +/** + * \brief Export an MPI to an ASCII string. + * + * \param X The source MPI. This must point to an initialized MPI. + * \param radix The numeric base of the output string. + * \param buf The buffer to write the string to. This must be writable + * buffer of length \p buflen Bytes. + * \param buflen The available size in Bytes of \p buf. + * \param olen The address at which to store the length of the string + * written, including the final \c NULL byte. This must + * not be \c NULL. + * + * \note You can call this function with `buflen == 0` to obtain the + * minimum required buffer size in `*olen`. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the target buffer \p buf + * is too small to hold the value of \p X in the desired base. + * In this case, `*olen` is nonetheless updated to contain the + * size of \p buf required for a successful call. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix, + char *buf, size_t buflen, size_t *olen ); + +#if defined(MBEDTLS_FS_IO) +/** + * \brief Read an MPI from a line in an opened file. + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param radix The numeric base of the string representation used + * in the source line. + * \param fin The input file handle to use. This must not be \c NULL. + * + * \note On success, this function advances the file stream + * to the end of the current line or to EOF. + * + * The function returns \c 0 on an empty line. + * + * Leading whitespaces are ignored, as is a + * '0x' prefix for radix \c 16. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the file read buffer + * is too small. + * \return Another negative error code on failure. + */ +int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin ); + +/** + * \brief Export an MPI into an opened file. + * + * \param p A string prefix to emit prior to the MPI data. + * For example, this might be a label, or "0x" when + * printing in base \c 16. This may be \c NULL if no prefix + * is needed. + * \param X The source MPI. This must point to an initialized MPI. + * \param radix The numeric base to be used in the emitted string. + * \param fout The output file handle. This may be \c NULL, in which case + * the output is written to \c stdout. + * + * \return \c 0 if successful. + * \return A negative error code on failure. + */ +int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, + int radix, FILE *fout ); +#endif /* MBEDTLS_FS_IO */ + +/** + * \brief Import an MPI from unsigned big endian binary data. + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param buf The input buffer. This must be a readable buffer of length + * \p buflen Bytes. + * \param buflen The length of the input buffer \p p in Bytes. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, + size_t buflen ); + +/** + * \brief Import X from unsigned binary data, little endian + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param buf The input buffer. This must be a readable buffer of length + * \p buflen Bytes. + * \param buflen The length of the input buffer \p p in Bytes. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_read_binary_le( mbedtls_mpi *X, + const unsigned char *buf, size_t buflen ); + +/** + * \brief Export X into unsigned binary data, big endian. + * Always fills the whole buffer, which will start with zeros + * if the number is smaller. + * + * \param X The source MPI. This must point to an initialized MPI. + * \param buf The output buffer. This must be a writable buffer of length + * \p buflen Bytes. + * \param buflen The size of the output buffer \p buf in Bytes. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't + * large enough to hold the value of \p X. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf, + size_t buflen ); + +/** + * \brief Export X into unsigned binary data, little endian. + * Always fills the whole buffer, which will end with zeros + * if the number is smaller. + * + * \param X The source MPI. This must point to an initialized MPI. + * \param buf The output buffer. This must be a writable buffer of length + * \p buflen Bytes. + * \param buflen The size of the output buffer \p buf in Bytes. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't + * large enough to hold the value of \p X. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_write_binary_le( const mbedtls_mpi *X, + unsigned char *buf, size_t buflen ); + +/** + * \brief Perform a left-shift on an MPI: X <<= count + * + * \param X The MPI to shift. This must point to an initialized MPI. + * \param count The number of bits to shift by. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count ); + +/** + * \brief Perform a right-shift on an MPI: X >>= count + * + * \param X The MPI to shift. This must point to an initialized MPI. + * \param count The number of bits to shift by. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count ); + +/** + * \brief Compare the absolute values of two MPIs. + * + * \param X The left-hand MPI. This must point to an initialized MPI. + * \param Y The right-hand MPI. This must point to an initialized MPI. + * + * \return \c 1 if `|X|` is greater than `|Y|`. + * \return \c -1 if `|X|` is lesser than `|Y|`. + * \return \c 0 if `|X|` is equal to `|Y|`. + */ +int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y ); + +/** + * \brief Compare two MPIs. + * + * \param X The left-hand MPI. This must point to an initialized MPI. + * \param Y The right-hand MPI. This must point to an initialized MPI. + * + * \return \c 1 if \p X is greater than \p Y. + * \return \c -1 if \p X is lesser than \p Y. + * \return \c 0 if \p X is equal to \p Y. + */ +int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y ); + +/** + * \brief Check if an MPI is less than the other in constant time. + * + * \param X The left-hand MPI. This must point to an initialized MPI + * with the same allocated length as Y. + * \param Y The right-hand MPI. This must point to an initialized MPI + * with the same allocated length as X. + * \param ret The result of the comparison: + * \c 1 if \p X is less than \p Y. + * \c 0 if \p X is greater than or equal to \p Y. + * + * \return 0 on success. + * \return MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the allocated length of + * the two input MPIs is not the same. + */ +int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y, + unsigned *ret ); + +/** + * \brief Compare an MPI with an integer. + * + * \param X The left-hand MPI. This must point to an initialized MPI. + * \param z The integer value to compare \p X to. + * + * \return \c 1 if \p X is greater than \p z. + * \return \c -1 if \p X is lesser than \p z. + * \return \c 0 if \p X is equal to \p z. + */ +int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z ); + +/** + * \brief Perform an unsigned addition of MPIs: X = |A| + |B| + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param A The first summand. This must point to an initialized MPI. + * \param B The second summand. This must point to an initialized MPI. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *B ); + +/** + * \brief Perform an unsigned subtraction of MPIs: X = |A| - |B| + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param A The minuend. This must point to an initialized MPI. + * \param B The subtrahend. This must point to an initialized MPI. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p B is greater than \p A. + * \return Another negative error code on different kinds of failure. + * + */ +int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *B ); + +/** + * \brief Perform a signed addition of MPIs: X = A + B + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param A The first summand. This must point to an initialized MPI. + * \param B The second summand. This must point to an initialized MPI. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *B ); + +/** + * \brief Perform a signed subtraction of MPIs: X = A - B + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param A The minuend. This must point to an initialized MPI. + * \param B The subtrahend. This must point to an initialized MPI. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *B ); + +/** + * \brief Perform a signed addition of an MPI and an integer: X = A + b + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param A The first summand. This must point to an initialized MPI. + * \param b The second summand. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, + mbedtls_mpi_sint b ); + +/** + * \brief Perform a signed subtraction of an MPI and an integer: + * X = A - b + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param A The minuend. This must point to an initialized MPI. + * \param b The subtrahend. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, + mbedtls_mpi_sint b ); + +/** + * \brief Perform a multiplication of two MPIs: X = A * B + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param A The first factor. This must point to an initialized MPI. + * \param B The second factor. This must point to an initialized MPI. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on different kinds of failure. + * + */ +int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *B ); + +/** + * \brief Perform a multiplication of an MPI with an unsigned integer: + * X = A * b + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param A The first factor. This must point to an initialized MPI. + * \param b The second factor. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on different kinds of failure. + * + */ +int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, + mbedtls_mpi_uint b ); + +/** + * \brief Perform a division with remainder of two MPIs: + * A = Q * B + R + * + * \param Q The destination MPI for the quotient. + * This may be \c NULL if the value of the + * quotient is not needed. + * \param R The destination MPI for the remainder value. + * This may be \c NULL if the value of the + * remainder is not needed. + * \param A The dividend. This must point to an initialized MPi. + * \param B The divisor. This must point to an initialized MPI. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p B equals zero. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, + const mbedtls_mpi *B ); + +/** + * \brief Perform a division with remainder of an MPI by an integer: + * A = Q * b + R + * + * \param Q The destination MPI for the quotient. + * This may be \c NULL if the value of the + * quotient is not needed. + * \param R The destination MPI for the remainder value. + * This may be \c NULL if the value of the + * remainder is not needed. + * \param A The dividend. This must point to an initialized MPi. + * \param b The divisor. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p b equals zero. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, + mbedtls_mpi_sint b ); + +/** + * \brief Perform a modular reduction. R = A mod B + * + * \param R The destination MPI for the residue value. + * This must point to an initialized MPI. + * \param A The MPI to compute the residue of. + * This must point to an initialized MPI. + * \param B The base of the modular reduction. + * This must point to an initialized MPI. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p B equals zero. + * \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p B is negative. + * \return Another negative error code on different kinds of failure. + * + */ +int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, + const mbedtls_mpi *B ); + +/** + * \brief Perform a modular reduction with respect to an integer. + * r = A mod b + * + * \param r The address at which to store the residue. + * This must not be \c NULL. + * \param A The MPI to compute the residue of. + * This must point to an initialized MPi. + * \param b The integer base of the modular reduction. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p b equals zero. + * \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p b is negative. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, + mbedtls_mpi_sint b ); + +/** + * \brief Perform a sliding-window exponentiation: X = A^E mod N + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param A The base of the exponentiation. + * This must point to an initialized MPI. + * \param E The exponent MPI. This must point to an initialized MPI. + * \param N The base for the modular reduction. This must point to an + * initialized MPI. + * \param prec_RR A helper MPI depending solely on \p N which can be used to + * speed-up multiple modular exponentiations for the same value + * of \p N. This may be \c NULL. If it is not \c NULL, it must + * point to an initialized MPI. If it hasn't been used after + * the call to mbedtls_mpi_init(), this function will compute + * the helper value and store it in \p prec_RR for reuse on + * subsequent calls to this function. Otherwise, the function + * will assume that \p prec_RR holds the helper value set by a + * previous call to mbedtls_mpi_exp_mod(), and reuse it. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \c N is negative or + * even, or if \c E is negative. + * \return Another negative error code on different kinds of failures. + * + */ +int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *E, const mbedtls_mpi *N, + mbedtls_mpi *prec_RR ); + +/** + * \brief Fill an MPI with a number of random bytes. + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param size The number of random bytes to generate. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG parameter to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context argument. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on failure. + * + * \note The bytes obtained from the RNG are interpreted + * as a big-endian representation of an MPI; this can + * be relevant in applications like deterministic ECDSA. + */ +int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** Generate a random number uniformly in a range. + * + * This function generates a random number between \p min inclusive and + * \p N exclusive. + * + * The procedure complies with RFC 6979 §3.3 (deterministic ECDSA) + * when the RNG is a suitably parametrized instance of HMAC_DRBG + * and \p min is \c 1. + * + * \note There are `N - min` possible outputs. The lower bound + * \p min can be reached, but the upper bound \p N cannot. + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param min The minimum value to return. + * It must be nonnegative. + * \param N The upper bound of the range, exclusive. + * In other words, this is one plus the maximum value to return. + * \p N must be strictly larger than \p min. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG parameter to be passed to \p f_rng. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p min or \p N is invalid + * or if they are incompatible. + * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if the implementation was + * unable to find a suitable value within a limited number + * of attempts. This has a negligible probability if \p N + * is significantly larger than \p min, which is the case + * for all usual cryptographic applications. + * \return Another negative error code on failure. + */ +int mbedtls_mpi_random( mbedtls_mpi *X, + mbedtls_mpi_sint min, + const mbedtls_mpi *N, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief Compute the greatest common divisor: G = gcd(A, B) + * + * \param G The destination MPI. This must point to an initialized MPI. + * \param A The first operand. This must point to an initialized MPI. + * \param B The second operand. This must point to an initialized MPI. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, + const mbedtls_mpi *B ); + +/** + * \brief Compute the modular inverse: X = A^-1 mod N + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param A The MPI to calculate the modular inverse of. This must point + * to an initialized MPI. + * \param N The base of the modular inversion. This must point to an + * initialized MPI. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p N is less than + * or equal to one. + * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p has no modular inverse + * with respect to \p N. + */ +int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *N ); + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif +/** + * \brief Perform a Miller-Rabin primality test with error + * probability of 2-80. + * + * \deprecated Superseded by mbedtls_mpi_is_prime_ext() which allows + * specifying the number of Miller-Rabin rounds. + * + * \param X The MPI to check for primality. + * This must point to an initialized MPI. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG parameter to be passed to \p f_rng. + * This may be \c NULL if \p f_rng doesn't use a + * context parameter. + * + * \return \c 0 if successful, i.e. \p X is probably prime. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p X is not prime. + * \return Another negative error code on other kinds of failure. + */ +MBEDTLS_DEPRECATED int mbedtls_mpi_is_prime( const mbedtls_mpi *X, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); +#undef MBEDTLS_DEPRECATED +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ + +/** + * \brief Miller-Rabin primality test. + * + * \warning If \p X is potentially generated by an adversary, for example + * when validating cryptographic parameters that you didn't + * generate yourself and that are supposed to be prime, then + * \p rounds should be at least the half of the security + * strength of the cryptographic algorithm. On the other hand, + * if \p X is chosen uniformly or non-adversarially (as is the + * case when mbedtls_mpi_gen_prime calls this function), then + * \p rounds can be much lower. + * + * \param X The MPI to check for primality. + * This must point to an initialized MPI. + * \param rounds The number of bases to perform the Miller-Rabin primality + * test for. The probability of returning 0 on a composite is + * at most 2-2*\p rounds. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG parameter to be passed to \p f_rng. + * This may be \c NULL if \p f_rng doesn't use + * a context parameter. + * + * \return \c 0 if successful, i.e. \p X is probably prime. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p X is not prime. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_mpi_is_prime_ext( const mbedtls_mpi *X, int rounds, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); +/** + * \brief Flags for mbedtls_mpi_gen_prime() + * + * Each of these flags is a constraint on the result X returned by + * mbedtls_mpi_gen_prime(). + */ +typedef enum { + MBEDTLS_MPI_GEN_PRIME_FLAG_DH = 0x0001, /**< (X-1)/2 is prime too */ + MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR = 0x0002, /**< lower error rate from 2-80 to 2-128 */ +} mbedtls_mpi_gen_prime_flag_t; + +/** + * \brief Generate a prime number. + * + * \param X The destination MPI to store the generated prime in. + * This must point to an initialized MPi. + * \param nbits The required size of the destination MPI in bits. + * This must be between \c 3 and #MBEDTLS_MPI_MAX_BITS. + * \param flags A mask of flags of type #mbedtls_mpi_gen_prime_flag_t. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG parameter to be passed to \p f_rng. + * This may be \c NULL if \p f_rng doesn't use + * a context parameter. + * + * \return \c 0 if successful, in which case \p X holds a + * probably prime number. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if `nbits` is not between + * \c 3 and #MBEDTLS_MPI_MAX_BITS. + */ +int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +#if defined(MBEDTLS_SELF_TEST) + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int mbedtls_mpi_self_test( int verbose ); + +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + +#endif /* bignum.h */ diff --git a/third_party/mbedtls/include/mbedtls/check_config.h b/third_party/mbedtls/include/mbedtls/check_config.h new file mode 100644 index 0000000..be5c548 --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/check_config.h @@ -0,0 +1,936 @@ +/** + * \file check_config.h + * + * \brief Consistency checks for configuration options + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * It is recommended to include this file from your config.h + * in order to catch dependency issues early. + */ + +#ifndef MBEDTLS_CHECK_CONFIG_H +#define MBEDTLS_CHECK_CONFIG_H + +/* + * We assume CHAR_BIT is 8 in many places. In practice, this is true on our + * target platforms, so not an issue, but let's just be extra sure. + */ +#include +#if CHAR_BIT != 8 +#error "mbed TLS requires a platform with 8-bit chars" +#endif + +#if defined(_WIN32) +#if !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_C is required on Windows" +#endif + +/* Fix the config here. Not convenient to put an #ifdef _WIN32 in config.h as + * it would confuse config.py. */ +#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \ + !defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) +#define MBEDTLS_PLATFORM_SNPRINTF_ALT +#endif + +#if !defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) && \ + !defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO) +#define MBEDTLS_PLATFORM_VSNPRINTF_ALT +#endif +#endif /* _WIN32 */ + +#if defined(TARGET_LIKE_MBED) && defined(MBEDTLS_NET_C) +#error "The NET module is not available for mbed OS - please use the network functions provided by Mbed OS" +#endif + +#if defined(MBEDTLS_DEPRECATED_WARNING) && \ + !defined(__GNUC__) && !defined(__clang__) +#error "MBEDTLS_DEPRECATED_WARNING only works with GCC and Clang" +#endif + +#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_HAVE_TIME) +#error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense" +#endif + +#if defined(MBEDTLS_AESNI_C) && !defined(MBEDTLS_HAVE_ASM) +#error "MBEDTLS_AESNI_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C) +#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_DHM_C) && !defined(MBEDTLS_BIGNUM_C) +#error "MBEDTLS_DHM_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT) && !defined(MBEDTLS_SSL_TRUNCATED_HMAC) +#error "MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_CMAC_C) && \ + !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_DES_C) +#error "MBEDTLS_CMAC_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_NIST_KW_C) && \ + ( !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_CIPHER_C) ) +#error "MBEDTLS_NIST_KW_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C) +#error "MBEDTLS_ECDH_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECDSA_C) && \ + ( !defined(MBEDTLS_ECP_C) || \ + !( defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) ) || \ + !defined(MBEDTLS_ASN1_PARSE_C) || \ + !defined(MBEDTLS_ASN1_WRITE_C) ) +#error "MBEDTLS_ECDSA_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECJPAKE_C) && \ + ( !defined(MBEDTLS_ECP_C) || !defined(MBEDTLS_MD_C) ) +#error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_RESTARTABLE) && \ + ( defined(MBEDTLS_USE_PSA_CRYPTO) || \ + defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) || \ + defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) || \ + defined(MBEDTLS_ECDSA_SIGN_ALT) || \ + defined(MBEDTLS_ECDSA_VERIFY_ALT) || \ + defined(MBEDTLS_ECDSA_GENKEY_ALT) || \ + defined(MBEDTLS_ECP_INTERNAL_ALT) || \ + defined(MBEDTLS_ECP_ALT) ) +#error "MBEDTLS_ECP_RESTARTABLE defined, but it cannot coexist with an alternative or PSA-based ECP implementation" +#endif + +#if defined(MBEDTLS_ECP_RESTARTABLE) && \ + ! defined(MBEDTLS_ECDH_LEGACY_CONTEXT) +#error "MBEDTLS_ECP_RESTARTABLE defined, but not MBEDTLS_ECDH_LEGACY_CONTEXT" +#endif + +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) && \ + defined(MBEDTLS_ECDH_LEGACY_CONTEXT) +#error "MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED defined, but MBEDTLS_ECDH_LEGACY_CONTEXT not disabled" +#endif + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C) +#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \ + !defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) ) ) +#error "MBEDTLS_ECP_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_C) && !( \ + defined(MBEDTLS_ECP_ALT) || \ + defined(MBEDTLS_CTR_DRBG_C) || \ + defined(MBEDTLS_HMAC_DRBG_C) || \ + defined(MBEDTLS_ECP_NO_INTERNAL_RNG)) +#error "MBEDTLS_ECP_C requires a DRBG module unless MBEDTLS_ECP_NO_INTERNAL_RNG is defined or an alternative implementation is used" +#endif + +#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_ASN1_PARSE_C) +#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PKCS5_C) && !defined(MBEDTLS_MD_C) +#error "MBEDTLS_PKCS5_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ENTROPY_C) && (!defined(MBEDTLS_SHA512_C) && \ + !defined(MBEDTLS_SHA256_C)) +#error "MBEDTLS_ENTROPY_C defined, but not all prerequisites" +#endif +#if defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_SHA512_C) && \ + defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 64) +#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high" +#endif +#if defined(MBEDTLS_ENTROPY_C) && \ + ( !defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_ENTROPY_FORCE_SHA256) ) \ + && defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 32) +#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high" +#endif +#if defined(MBEDTLS_ENTROPY_C) && \ + defined(MBEDTLS_ENTROPY_FORCE_SHA256) && !defined(MBEDTLS_SHA256_C) +#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites" +#endif + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) +#define MBEDTLS_HAS_MEMSAN +#endif +#endif +#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) && !defined(MBEDTLS_HAS_MEMSAN) +#error "MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN requires building with MemorySanitizer" +#endif +#undef MBEDTLS_HAS_MEMSAN + +#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \ + ( !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) ) +#error "MBEDTLS_TEST_NULL_ENTROPY defined, but not all prerequisites" +#endif +#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \ + ( defined(MBEDTLS_ENTROPY_NV_SEED) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT) || \ + defined(MBEDTLS_HAVEGE_C) ) +#error "MBEDTLS_TEST_NULL_ENTROPY defined, but entropy sources too" +#endif + +#if defined(MBEDTLS_CCM_C) && ( \ + !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) && !defined(MBEDTLS_ARIA_C) ) +#error "MBEDTLS_CCM_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_CCM_C) && !defined(MBEDTLS_CIPHER_C) +#error "MBEDTLS_CCM_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_GCM_C) && ( \ + !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) && !defined(MBEDTLS_ARIA_C) ) +#error "MBEDTLS_GCM_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_GCM_C) && !defined(MBEDTLS_CIPHER_C) +#error "MBEDTLS_GCM_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_CHACHAPOLY_C) && !defined(MBEDTLS_CHACHA20_C) +#error "MBEDTLS_CHACHAPOLY_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_CHACHAPOLY_C) && !defined(MBEDTLS_POLY1305_C) +#error "MBEDTLS_CHACHAPOLY_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_RANDOMIZE_JAC_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_ADD_MIXED_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_DOUBLE_JAC_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_NORMALIZE_JAC_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_RANDOMIZE_MXZ_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_NORMALIZE_MXZ_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_NO_FALLBACK) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_NO_FALLBACK defined, but no alternative implementation enabled" +#endif + +#if defined(MBEDTLS_HAVEGE_C) && !defined(MBEDTLS_TIMING_C) +#error "MBEDTLS_HAVEGE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_HKDF_C) && !defined(MBEDTLS_MD_C) +#error "MBEDTLS_HKDF_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_HMAC_DRBG_C) && !defined(MBEDTLS_MD_C) +#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \ + ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) || \ + !defined(MBEDTLS_X509_CRT_PARSE_C) ) +#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ + ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) || \ + !defined(MBEDTLS_X509_CRT_PARSE_C) ) +#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) && !defined(MBEDTLS_DHM_C) +#error "MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \ + !defined(MBEDTLS_ECDH_C) +#error "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + ( !defined(MBEDTLS_DHM_C) || !defined(MBEDTLS_RSA_C) || \ + !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) ) +#error "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) || \ + !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) ) +#error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ + ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) || \ + !defined(MBEDTLS_X509_CRT_PARSE_C) ) +#error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) && \ + ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \ + !defined(MBEDTLS_PKCS1_V15) ) +#error "MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ + ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \ + !defined(MBEDTLS_PKCS1_V15) ) +#error "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ + ( !defined(MBEDTLS_ECJPAKE_C) || !defined(MBEDTLS_SHA256_C) || \ + !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) ) +#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \ + !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) && \ + ( !defined(MBEDTLS_SHA256_C) && \ + !defined(MBEDTLS_SHA512_C) && \ + !defined(MBEDTLS_SHA1_C) ) +#error "!MBEDTLS_SSL_KEEP_PEER_CERTIFICATE requires MBEDTLS_SHA512_C, MBEDTLS_SHA256_C or MBEDTLS_SHA1_C" +#endif + +#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \ + ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) +#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_MEMORY_BACKTRACE) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) +#error "MBEDTLS_MEMORY_BACKTRACE defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_MEMORY_DEBUG) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) +#error "MBEDTLS_MEMORY_DEBUG defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM) +#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PEM_PARSE_C) && !defined(MBEDTLS_BASE64_C) +#error "MBEDTLS_PEM_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PEM_WRITE_C) && !defined(MBEDTLS_BASE64_C) +#error "MBEDTLS_PEM_WRITE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PK_C) && \ + ( !defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_C) ) +#error "MBEDTLS_PK_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_PK_C) +#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PK_WRITE_C) && !defined(MBEDTLS_PK_C) +#error "MBEDTLS_PK_WRITE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PKCS11_C) && !defined(MBEDTLS_PK_C) +#error "MBEDTLS_PKCS11_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PKCS11_C) +#if defined(MBEDTLS_DEPRECATED_REMOVED) +#error "MBEDTLS_PKCS11_C is deprecated and will be removed in a future version of Mbed TLS" +#elif defined(MBEDTLS_DEPRECATED_WARNING) +#warning "MBEDTLS_PKCS11_C is deprecated and will be removed in a future version of Mbed TLS" +#endif +#endif /* MBEDTLS_PKCS11_C */ + +#if defined(MBEDTLS_PLATFORM_EXIT_ALT) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_EXIT_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_EXIT_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_EXIT) ||\ + defined(MBEDTLS_PLATFORM_EXIT_ALT) ) +#error "MBEDTLS_PLATFORM_EXIT_MACRO and MBEDTLS_PLATFORM_STD_EXIT/MBEDTLS_PLATFORM_EXIT_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_ALT) &&\ + ( !defined(MBEDTLS_PLATFORM_C) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_TIME_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\ + ( !defined(MBEDTLS_PLATFORM_C) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_TIME_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\ + ( !defined(MBEDTLS_PLATFORM_C) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_TIME) ||\ + defined(MBEDTLS_PLATFORM_TIME_ALT) ) +#error "MBEDTLS_PLATFORM_TIME_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_TIME) ||\ + defined(MBEDTLS_PLATFORM_TIME_ALT) ) +#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_FPRINTF_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_FPRINTF_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_FPRINTF) ||\ + defined(MBEDTLS_PLATFORM_FPRINTF_ALT) ) +#error "MBEDTLS_PLATFORM_FPRINTF_MACRO and MBEDTLS_PLATFORM_STD_FPRINTF/MBEDTLS_PLATFORM_FPRINTF_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\ + ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) +#error "MBEDTLS_PLATFORM_FREE_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\ + defined(MBEDTLS_PLATFORM_STD_FREE) +#error "MBEDTLS_PLATFORM_FREE_MACRO and MBEDTLS_PLATFORM_STD_FREE cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && !defined(MBEDTLS_PLATFORM_CALLOC_MACRO) +#error "MBEDTLS_PLATFORM_CALLOC_MACRO must be defined if MBEDTLS_PLATFORM_FREE_MACRO is" +#endif + +#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\ + ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) +#error "MBEDTLS_PLATFORM_CALLOC_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\ + defined(MBEDTLS_PLATFORM_STD_CALLOC) +#error "MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_STD_CALLOC cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && !defined(MBEDTLS_PLATFORM_FREE_MACRO) +#error "MBEDTLS_PLATFORM_FREE_MACRO must be defined if MBEDTLS_PLATFORM_CALLOC_MACRO is" +#endif + +#if defined(MBEDTLS_PLATFORM_MEMORY) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_MEMORY defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_PRINTF_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_PRINTF_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_PRINTF) ||\ + defined(MBEDTLS_PLATFORM_PRINTF_ALT) ) +#error "MBEDTLS_PLATFORM_PRINTF_MACRO and MBEDTLS_PLATFORM_STD_PRINTF/MBEDTLS_PLATFORM_PRINTF_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_SNPRINTF_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_SNPRINTF) ||\ + defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) ) +#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO and MBEDTLS_PLATFORM_STD_SNPRINTF/MBEDTLS_PLATFORM_SNPRINTF_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) &&\ + !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) +#error "MBEDTLS_PLATFORM_STD_MEM_HDR defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY) +#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_FREE) && !defined(MBEDTLS_PLATFORM_MEMORY) +#error "MBEDTLS_PLATFORM_STD_FREE defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_EXIT) &&\ + !defined(MBEDTLS_PLATFORM_EXIT_ALT) +#error "MBEDTLS_PLATFORM_STD_EXIT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_TIME) &&\ + ( !defined(MBEDTLS_PLATFORM_TIME_ALT) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_STD_TIME defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_FPRINTF) &&\ + !defined(MBEDTLS_PLATFORM_FPRINTF_ALT) +#error "MBEDTLS_PLATFORM_STD_FPRINTF defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_PRINTF) &&\ + !defined(MBEDTLS_PLATFORM_PRINTF_ALT) +#error "MBEDTLS_PLATFORM_STD_PRINTF defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_SNPRINTF) &&\ + !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) +#error "MBEDTLS_PLATFORM_STD_SNPRINTF defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ENTROPY_NV_SEED) &&\ + ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_ENTROPY_C) ) +#error "MBEDTLS_ENTROPY_NV_SEED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) &&\ + !defined(MBEDTLS_ENTROPY_NV_SEED) +#error "MBEDTLS_PLATFORM_NV_SEED_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) &&\ + !defined(MBEDTLS_PLATFORM_NV_SEED_ALT) +#error "MBEDTLS_PLATFORM_STD_NV_SEED_READ defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) &&\ + !defined(MBEDTLS_PLATFORM_NV_SEED_ALT) +#error "MBEDTLS_PLATFORM_STD_NV_SEED_WRITE defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) ||\ + defined(MBEDTLS_PLATFORM_NV_SEED_ALT) ) +#error "MBEDTLS_PLATFORM_NV_SEED_READ_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_READ cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) ||\ + defined(MBEDTLS_PLATFORM_NV_SEED_ALT) ) +#error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PSA_CRYPTO_C) && \ + !( ( ( defined(MBEDTLS_CTR_DRBG_C) || defined(MBEDTLS_HMAC_DRBG_C) ) && \ + defined(MBEDTLS_ENTROPY_C) ) || \ + defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) ) +#error "MBEDTLS_PSA_CRYPTO_C defined, but not all prerequisites (missing RNG)" +#endif + +#if defined(MBEDTLS_PSA_CRYPTO_SPM) && !defined(MBEDTLS_PSA_CRYPTO_C) +#error "MBEDTLS_PSA_CRYPTO_SPM defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PSA_CRYPTO_SE_C) && \ + ! ( defined(MBEDTLS_PSA_CRYPTO_C) && \ + defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) ) +#error "MBEDTLS_PSA_CRYPTO_SE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) && \ + ! defined(MBEDTLS_PSA_CRYPTO_C) +#error "MBEDTLS_PSA_CRYPTO_STORAGE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \ + !( defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) && \ + defined(MBEDTLS_ENTROPY_NV_SEED) ) +#error "MBEDTLS_PSA_INJECT_ENTROPY defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \ + !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) +#error "MBEDTLS_PSA_INJECT_ENTROPY is not compatible with actual entropy sources" +#endif + +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \ + defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) +#error "MBEDTLS_PSA_INJECT_ENTROPY is not compatible with MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG" +#endif + +#if defined(MBEDTLS_PSA_ITS_FILE_C) && \ + !defined(MBEDTLS_FS_IO) +#error "MBEDTLS_PSA_ITS_FILE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) && \ + defined(MBEDTLS_USE_PSA_CRYPTO) +#error "MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined, but it cannot coexist with MBEDTLS_USE_PSA_CRYPTO." +#endif + +#if defined(MBEDTLS_PK_C) && defined(MBEDTLS_USE_PSA_CRYPTO) && \ + !defined(MBEDTLS_PK_WRITE_C) && defined(MBEDTLS_ECDSA_C) +#error "MBEDTLS_PK_C in configuration with MBEDTLS_USE_PSA_CRYPTO and \ + MBEDTLS_ECDSA_C requires MBEDTLS_PK_WRITE_C to be defined." +#endif + +#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V15) && \ + !defined(MBEDTLS_PK_WRITE_C) && defined(MBEDTLS_PSA_CRYPTO_C) +#error "MBEDTLS_PSA_CRYPTO_C, MBEDTLS_RSA_C and MBEDTLS_PKCS1_V15 defined, \ + but not all prerequisites" +#endif + +#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ + !defined(MBEDTLS_OID_C) ) +#error "MBEDTLS_RSA_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_PKCS1_V21) && \ + !defined(MBEDTLS_PKCS1_V15) ) +#error "MBEDTLS_RSA_C defined, but none of the PKCS1 versions enabled" +#endif + +#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \ + ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_PKCS1_V21) ) +#error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SHA512_NO_SHA384) && !defined(MBEDTLS_SHA512_C) +#error "MBEDTLS_SHA512_NO_SHA384 defined without MBEDTLS_SHA512_C" +#endif + +#if defined(MBEDTLS_SSL_PROTO_SSL3) && ( !defined(MBEDTLS_MD5_C) || \ + !defined(MBEDTLS_SHA1_C) ) +#error "MBEDTLS_SSL_PROTO_SSL3 defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_PROTO_TLS1) && ( !defined(MBEDTLS_MD5_C) || \ + !defined(MBEDTLS_SHA1_C) ) +#error "MBEDTLS_SSL_PROTO_TLS1 defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_PROTO_TLS1_1) && ( !defined(MBEDTLS_MD5_C) || \ + !defined(MBEDTLS_SHA1_C) ) +#error "MBEDTLS_SSL_PROTO_TLS1_1 defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && ( !defined(MBEDTLS_SHA1_C) && \ + !defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA512_C) ) +#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) && ( !defined(MBEDTLS_HKDF_C) && \ + !defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA512_C) ) +#error "MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL defined, but not all prerequisites" +#endif + +#if (defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \ + !(defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) ) +#error "One or more versions of the TLS protocol are enabled " \ + "but no key exchange methods defined with MBEDTLS_KEY_EXCHANGE_xxxx" +#endif + +#if defined(MBEDTLS_SSL_PROTO_DTLS) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_2) +#error "MBEDTLS_SSL_PROTO_DTLS defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_CLI_C) && !defined(MBEDTLS_SSL_TLS_C) +#error "MBEDTLS_SSL_CLI_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_TLS_C) && ( !defined(MBEDTLS_CIPHER_C) || \ + !defined(MBEDTLS_MD_C) ) +#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_TLS_C) +#error "MBEDTLS_SSL_SRV_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_TLS_C) && (!defined(MBEDTLS_SSL_PROTO_SSL3) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1) && !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_2)) +#error "MBEDTLS_SSL_TLS_C defined, but no protocols are active" +#endif + +#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) && !defined(MBEDTLS_SSL_PROTO_TLS1)) +#error "Illegal protocol selection" +#endif + +#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_TLS1) && \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) && !defined(MBEDTLS_SSL_PROTO_TLS1_1)) +#error "Illegal protocol selection" +#endif + +#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) && (!defined(MBEDTLS_SSL_PROTO_TLS1) || \ + !defined(MBEDTLS_SSL_PROTO_TLS1_1))) +#error "Illegal protocol selection" +#endif + +#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && !defined(MBEDTLS_SSL_PROTO_DTLS) +#error "MBEDTLS_SSL_DTLS_HELLO_VERIFY defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \ + !defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) +#error "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ + ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) +#error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ + ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) +#error "MBEDTLS_SSL_DTLS_CONNECTION_ID defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ + defined(MBEDTLS_SSL_CID_IN_LEN_MAX) && \ + MBEDTLS_SSL_CID_IN_LEN_MAX > 255 +#error "MBEDTLS_SSL_CID_IN_LEN_MAX too large (max 255)" +#endif + +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ + defined(MBEDTLS_SSL_CID_OUT_LEN_MAX) && \ + MBEDTLS_SSL_CID_OUT_LEN_MAX > 255 +#error "MBEDTLS_SSL_CID_OUT_LEN_MAX too large (max 255)" +#endif + +#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \ + ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) +#error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_2) +#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_2) +#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_TICKET_C) && !defined(MBEDTLS_CIPHER_C) +#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) && \ + !defined(MBEDTLS_SSL_PROTO_SSL3) && !defined(MBEDTLS_SSL_PROTO_TLS1) +#error "MBEDTLS_SSL_CBC_RECORD_SPLITTING defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \ + !defined(MBEDTLS_X509_CRT_PARSE_C) +#error "MBEDTLS_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_THREADING_PTHREAD) +#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL) +#error "MBEDTLS_THREADING_PTHREAD defined, but not all prerequisites" +#endif +#define MBEDTLS_THREADING_IMPL +#endif + +#if defined(MBEDTLS_THREADING_ALT) +#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL) +#error "MBEDTLS_THREADING_ALT defined, but not all prerequisites" +#endif +#define MBEDTLS_THREADING_IMPL +#endif + +#if defined(MBEDTLS_THREADING_C) && !defined(MBEDTLS_THREADING_IMPL) +#error "MBEDTLS_THREADING_C defined, single threading implementation required" +#endif +#undef MBEDTLS_THREADING_IMPL + +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_PSA_CRYPTO_C) +#error "MBEDTLS_USE_PSA_CRYPTO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_VERSION_FEATURES) && !defined(MBEDTLS_VERSION_C) +#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_USE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ + !defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_PARSE_C) || \ + !defined(MBEDTLS_PK_PARSE_C) ) +#error "MBEDTLS_X509_USE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CREATE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ + !defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_WRITE_C) || \ + !defined(MBEDTLS_PK_WRITE_C) ) +#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_CERTS_C) && !defined(MBEDTLS_X509_USE_C) +#error "MBEDTLS_CERTS_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) +#error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CRL_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) +#error "MBEDTLS_X509_CRL_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CSR_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) +#error "MBEDTLS_X509_CSR_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CRT_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) ) +#error "MBEDTLS_X509_CRT_WRITE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CSR_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) ) +#error "MBEDTLS_X509_CSR_WRITE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_HAVE_INT32) && defined(MBEDTLS_HAVE_INT64) +#error "MBEDTLS_HAVE_INT32 and MBEDTLS_HAVE_INT64 cannot be defined simultaneously" +#endif /* MBEDTLS_HAVE_INT32 && MBEDTLS_HAVE_INT64 */ + +#if ( defined(MBEDTLS_HAVE_INT32) || defined(MBEDTLS_HAVE_INT64) ) && \ + defined(MBEDTLS_HAVE_ASM) +#error "MBEDTLS_HAVE_INT32/MBEDTLS_HAVE_INT64 and MBEDTLS_HAVE_ASM cannot be defined simultaneously" +#endif /* (MBEDTLS_HAVE_INT32 || MBEDTLS_HAVE_INT64) && MBEDTLS_HAVE_ASM */ + +#if defined(MBEDTLS_SSL_PROTO_SSL3) +#if defined(MBEDTLS_DEPRECATED_REMOVED) +#error "MBEDTLS_SSL_PROTO_SSL3 is deprecated and will be removed in a future version of Mbed TLS" +#elif defined(MBEDTLS_DEPRECATED_WARNING) +#warning "MBEDTLS_SSL_PROTO_SSL3 is deprecated and will be removed in a future version of Mbed TLS" +#endif +#endif /* MBEDTLS_SSL_PROTO_SSL3 */ + +#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) +#if defined(MBEDTLS_DEPRECATED_REMOVED) +#error "MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO is deprecated and will be removed in a future version of Mbed TLS" +#elif defined(MBEDTLS_DEPRECATED_WARNING) +#warning "MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO is deprecated and will be removed in a future version of Mbed TLS" +#endif +#endif /* MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */ + +#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) +#if defined(MBEDTLS_DEPRECATED_REMOVED) +#error "MBEDTLS_SSL_HW_RECORD_ACCEL is deprecated and will be removed in a future version of Mbed TLS" +#elif defined(MBEDTLS_DEPRECATED_WARNING) +#warning "MBEDTLS_SSL_HW_RECORD_ACCEL is deprecated and will be removed in a future version of Mbed TLS" +#endif /* MBEDTLS_DEPRECATED_REMOVED */ +#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ + +#if defined(MBEDTLS_SSL_DTLS_SRTP) && ( !defined(MBEDTLS_SSL_PROTO_DTLS) ) +#error "MBEDTLS_SSL_DTLS_SRTP defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) && ( !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) ) +#error "MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH defined, but not all prerequisites" +#endif + +/* + * Avoid warning from -pedantic. This is a convenient place for this + * workaround since this is included by every single file before the + * #if defined(MBEDTLS_xxx_C) that results in empty translation units. + */ +typedef int mbedtls_iso_c_forbids_empty_translation_units; + +#endif /* MBEDTLS_CHECK_CONFIG_H */ diff --git a/third_party/mbedtls/include/mbedtls/cipher.h b/third_party/mbedtls/include/mbedtls/cipher.h new file mode 100644 index 0000000..6d83da8 --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/cipher.h @@ -0,0 +1,1102 @@ +/** + * \file cipher.h + * + * \brief This file contains an abstraction interface for use with the cipher + * primitives provided by the library. It provides a common interface to all of + * the available cipher operations. + * + * \author Adriaan de Jong + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_CIPHER_H +#define MBEDTLS_CIPHER_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include +#include "mbedtls/platform_util.h" + +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C) +#define MBEDTLS_CIPHER_MODE_AEAD +#endif + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#define MBEDTLS_CIPHER_MODE_WITH_PADDING +#endif + +#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \ + defined(MBEDTLS_CHACHA20_C) +#define MBEDTLS_CIPHER_MODE_STREAM +#endif + +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + +/** The selected feature is not available. */ +#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 +/** Bad input parameters. */ +#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA -0x6100 +/** Failed to allocate memory. */ +#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED -0x6180 +/** Input data contains invalid padding and is rejected. */ +#define MBEDTLS_ERR_CIPHER_INVALID_PADDING -0x6200 +/** Decryption of block requires a full block. */ +#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 +/** Authentication failed (for AEAD modes). */ +#define MBEDTLS_ERR_CIPHER_AUTH_FAILED -0x6300 +/** The context is invalid. For example, because it was freed. */ +#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT -0x6380 + +/* MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED is deprecated and should not be used. */ +/** Cipher hardware accelerator failed. */ +#define MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED -0x6400 + +#define MBEDTLS_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length. */ +#define MBEDTLS_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Supported cipher types. + * + * \warning RC4 and DES are considered weak ciphers and their use + * constitutes a security risk. Arm recommends considering stronger + * ciphers instead. + */ +typedef enum { + MBEDTLS_CIPHER_ID_NONE = 0, /**< Placeholder to mark the end of cipher ID lists. */ + MBEDTLS_CIPHER_ID_NULL, /**< The identity cipher, treated as a stream cipher. */ + MBEDTLS_CIPHER_ID_AES, /**< The AES cipher. */ + MBEDTLS_CIPHER_ID_DES, /**< The DES cipher. */ + MBEDTLS_CIPHER_ID_3DES, /**< The Triple DES cipher. */ + MBEDTLS_CIPHER_ID_CAMELLIA, /**< The Camellia cipher. */ + MBEDTLS_CIPHER_ID_BLOWFISH, /**< The Blowfish cipher. */ + MBEDTLS_CIPHER_ID_ARC4, /**< The RC4 cipher. */ + MBEDTLS_CIPHER_ID_ARIA, /**< The Aria cipher. */ + MBEDTLS_CIPHER_ID_CHACHA20, /**< The ChaCha20 cipher. */ +} mbedtls_cipher_id_t; + +/** + * \brief Supported {cipher type, cipher mode} pairs. + * + * \warning RC4 and DES are considered weak ciphers and their use + * constitutes a security risk. Arm recommends considering stronger + * ciphers instead. + */ +typedef enum { + MBEDTLS_CIPHER_NONE = 0, /**< Placeholder to mark the end of cipher-pair lists. */ + MBEDTLS_CIPHER_NULL, /**< The identity stream cipher. */ + MBEDTLS_CIPHER_AES_128_ECB, /**< AES cipher with 128-bit ECB mode. */ + MBEDTLS_CIPHER_AES_192_ECB, /**< AES cipher with 192-bit ECB mode. */ + MBEDTLS_CIPHER_AES_256_ECB, /**< AES cipher with 256-bit ECB mode. */ + MBEDTLS_CIPHER_AES_128_CBC, /**< AES cipher with 128-bit CBC mode. */ + MBEDTLS_CIPHER_AES_192_CBC, /**< AES cipher with 192-bit CBC mode. */ + MBEDTLS_CIPHER_AES_256_CBC, /**< AES cipher with 256-bit CBC mode. */ + MBEDTLS_CIPHER_AES_128_CFB128, /**< AES cipher with 128-bit CFB128 mode. */ + MBEDTLS_CIPHER_AES_192_CFB128, /**< AES cipher with 192-bit CFB128 mode. */ + MBEDTLS_CIPHER_AES_256_CFB128, /**< AES cipher with 256-bit CFB128 mode. */ + MBEDTLS_CIPHER_AES_128_CTR, /**< AES cipher with 128-bit CTR mode. */ + MBEDTLS_CIPHER_AES_192_CTR, /**< AES cipher with 192-bit CTR mode. */ + MBEDTLS_CIPHER_AES_256_CTR, /**< AES cipher with 256-bit CTR mode. */ + MBEDTLS_CIPHER_AES_128_GCM, /**< AES cipher with 128-bit GCM mode. */ + MBEDTLS_CIPHER_AES_192_GCM, /**< AES cipher with 192-bit GCM mode. */ + MBEDTLS_CIPHER_AES_256_GCM, /**< AES cipher with 256-bit GCM mode. */ + MBEDTLS_CIPHER_CAMELLIA_128_ECB, /**< Camellia cipher with 128-bit ECB mode. */ + MBEDTLS_CIPHER_CAMELLIA_192_ECB, /**< Camellia cipher with 192-bit ECB mode. */ + MBEDTLS_CIPHER_CAMELLIA_256_ECB, /**< Camellia cipher with 256-bit ECB mode. */ + MBEDTLS_CIPHER_CAMELLIA_128_CBC, /**< Camellia cipher with 128-bit CBC mode. */ + MBEDTLS_CIPHER_CAMELLIA_192_CBC, /**< Camellia cipher with 192-bit CBC mode. */ + MBEDTLS_CIPHER_CAMELLIA_256_CBC, /**< Camellia cipher with 256-bit CBC mode. */ + MBEDTLS_CIPHER_CAMELLIA_128_CFB128, /**< Camellia cipher with 128-bit CFB128 mode. */ + MBEDTLS_CIPHER_CAMELLIA_192_CFB128, /**< Camellia cipher with 192-bit CFB128 mode. */ + MBEDTLS_CIPHER_CAMELLIA_256_CFB128, /**< Camellia cipher with 256-bit CFB128 mode. */ + MBEDTLS_CIPHER_CAMELLIA_128_CTR, /**< Camellia cipher with 128-bit CTR mode. */ + MBEDTLS_CIPHER_CAMELLIA_192_CTR, /**< Camellia cipher with 192-bit CTR mode. */ + MBEDTLS_CIPHER_CAMELLIA_256_CTR, /**< Camellia cipher with 256-bit CTR mode. */ + MBEDTLS_CIPHER_CAMELLIA_128_GCM, /**< Camellia cipher with 128-bit GCM mode. */ + MBEDTLS_CIPHER_CAMELLIA_192_GCM, /**< Camellia cipher with 192-bit GCM mode. */ + MBEDTLS_CIPHER_CAMELLIA_256_GCM, /**< Camellia cipher with 256-bit GCM mode. */ + MBEDTLS_CIPHER_DES_ECB, /**< DES cipher with ECB mode. */ + MBEDTLS_CIPHER_DES_CBC, /**< DES cipher with CBC mode. */ + MBEDTLS_CIPHER_DES_EDE_ECB, /**< DES cipher with EDE ECB mode. */ + MBEDTLS_CIPHER_DES_EDE_CBC, /**< DES cipher with EDE CBC mode. */ + MBEDTLS_CIPHER_DES_EDE3_ECB, /**< DES cipher with EDE3 ECB mode. */ + MBEDTLS_CIPHER_DES_EDE3_CBC, /**< DES cipher with EDE3 CBC mode. */ + MBEDTLS_CIPHER_BLOWFISH_ECB, /**< Blowfish cipher with ECB mode. */ + MBEDTLS_CIPHER_BLOWFISH_CBC, /**< Blowfish cipher with CBC mode. */ + MBEDTLS_CIPHER_BLOWFISH_CFB64, /**< Blowfish cipher with CFB64 mode. */ + MBEDTLS_CIPHER_BLOWFISH_CTR, /**< Blowfish cipher with CTR mode. */ + MBEDTLS_CIPHER_ARC4_128, /**< RC4 cipher with 128-bit mode. */ + MBEDTLS_CIPHER_AES_128_CCM, /**< AES cipher with 128-bit CCM mode. */ + MBEDTLS_CIPHER_AES_192_CCM, /**< AES cipher with 192-bit CCM mode. */ + MBEDTLS_CIPHER_AES_256_CCM, /**< AES cipher with 256-bit CCM mode. */ + MBEDTLS_CIPHER_CAMELLIA_128_CCM, /**< Camellia cipher with 128-bit CCM mode. */ + MBEDTLS_CIPHER_CAMELLIA_192_CCM, /**< Camellia cipher with 192-bit CCM mode. */ + MBEDTLS_CIPHER_CAMELLIA_256_CCM, /**< Camellia cipher with 256-bit CCM mode. */ + MBEDTLS_CIPHER_ARIA_128_ECB, /**< Aria cipher with 128-bit key and ECB mode. */ + MBEDTLS_CIPHER_ARIA_192_ECB, /**< Aria cipher with 192-bit key and ECB mode. */ + MBEDTLS_CIPHER_ARIA_256_ECB, /**< Aria cipher with 256-bit key and ECB mode. */ + MBEDTLS_CIPHER_ARIA_128_CBC, /**< Aria cipher with 128-bit key and CBC mode. */ + MBEDTLS_CIPHER_ARIA_192_CBC, /**< Aria cipher with 192-bit key and CBC mode. */ + MBEDTLS_CIPHER_ARIA_256_CBC, /**< Aria cipher with 256-bit key and CBC mode. */ + MBEDTLS_CIPHER_ARIA_128_CFB128, /**< Aria cipher with 128-bit key and CFB-128 mode. */ + MBEDTLS_CIPHER_ARIA_192_CFB128, /**< Aria cipher with 192-bit key and CFB-128 mode. */ + MBEDTLS_CIPHER_ARIA_256_CFB128, /**< Aria cipher with 256-bit key and CFB-128 mode. */ + MBEDTLS_CIPHER_ARIA_128_CTR, /**< Aria cipher with 128-bit key and CTR mode. */ + MBEDTLS_CIPHER_ARIA_192_CTR, /**< Aria cipher with 192-bit key and CTR mode. */ + MBEDTLS_CIPHER_ARIA_256_CTR, /**< Aria cipher with 256-bit key and CTR mode. */ + MBEDTLS_CIPHER_ARIA_128_GCM, /**< Aria cipher with 128-bit key and GCM mode. */ + MBEDTLS_CIPHER_ARIA_192_GCM, /**< Aria cipher with 192-bit key and GCM mode. */ + MBEDTLS_CIPHER_ARIA_256_GCM, /**< Aria cipher with 256-bit key and GCM mode. */ + MBEDTLS_CIPHER_ARIA_128_CCM, /**< Aria cipher with 128-bit key and CCM mode. */ + MBEDTLS_CIPHER_ARIA_192_CCM, /**< Aria cipher with 192-bit key and CCM mode. */ + MBEDTLS_CIPHER_ARIA_256_CCM, /**< Aria cipher with 256-bit key and CCM mode. */ + MBEDTLS_CIPHER_AES_128_OFB, /**< AES 128-bit cipher in OFB mode. */ + MBEDTLS_CIPHER_AES_192_OFB, /**< AES 192-bit cipher in OFB mode. */ + MBEDTLS_CIPHER_AES_256_OFB, /**< AES 256-bit cipher in OFB mode. */ + MBEDTLS_CIPHER_AES_128_XTS, /**< AES 128-bit cipher in XTS block mode. */ + MBEDTLS_CIPHER_AES_256_XTS, /**< AES 256-bit cipher in XTS block mode. */ + MBEDTLS_CIPHER_CHACHA20, /**< ChaCha20 stream cipher. */ + MBEDTLS_CIPHER_CHACHA20_POLY1305, /**< ChaCha20-Poly1305 AEAD cipher. */ + MBEDTLS_CIPHER_AES_128_KW, /**< AES cipher with 128-bit NIST KW mode. */ + MBEDTLS_CIPHER_AES_192_KW, /**< AES cipher with 192-bit NIST KW mode. */ + MBEDTLS_CIPHER_AES_256_KW, /**< AES cipher with 256-bit NIST KW mode. */ + MBEDTLS_CIPHER_AES_128_KWP, /**< AES cipher with 128-bit NIST KWP mode. */ + MBEDTLS_CIPHER_AES_192_KWP, /**< AES cipher with 192-bit NIST KWP mode. */ + MBEDTLS_CIPHER_AES_256_KWP, /**< AES cipher with 256-bit NIST KWP mode. */ +} mbedtls_cipher_type_t; + +/** Supported cipher modes. */ +typedef enum { + MBEDTLS_MODE_NONE = 0, /**< None. */ + MBEDTLS_MODE_ECB, /**< The ECB cipher mode. */ + MBEDTLS_MODE_CBC, /**< The CBC cipher mode. */ + MBEDTLS_MODE_CFB, /**< The CFB cipher mode. */ + MBEDTLS_MODE_OFB, /**< The OFB cipher mode. */ + MBEDTLS_MODE_CTR, /**< The CTR cipher mode. */ + MBEDTLS_MODE_GCM, /**< The GCM cipher mode. */ + MBEDTLS_MODE_STREAM, /**< The stream cipher mode. */ + MBEDTLS_MODE_CCM, /**< The CCM cipher mode. */ + MBEDTLS_MODE_XTS, /**< The XTS cipher mode. */ + MBEDTLS_MODE_CHACHAPOLY, /**< The ChaCha-Poly cipher mode. */ + MBEDTLS_MODE_KW, /**< The SP800-38F KW mode */ + MBEDTLS_MODE_KWP, /**< The SP800-38F KWP mode */ +} mbedtls_cipher_mode_t; + +/** Supported cipher padding types. */ +typedef enum { + MBEDTLS_PADDING_PKCS7 = 0, /**< PKCS7 padding (default). */ + MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding. */ + MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding. */ + MBEDTLS_PADDING_ZEROS, /**< Zero padding (not reversible). */ + MBEDTLS_PADDING_NONE, /**< Never pad (full blocks only). */ +} mbedtls_cipher_padding_t; + +/** Type of operation. */ +typedef enum { + MBEDTLS_OPERATION_NONE = -1, + MBEDTLS_DECRYPT = 0, + MBEDTLS_ENCRYPT, +} mbedtls_operation_t; + +enum { + /** Undefined key length. */ + MBEDTLS_KEY_LENGTH_NONE = 0, + /** Key length, in bits (including parity), for DES keys. */ + MBEDTLS_KEY_LENGTH_DES = 64, + /** Key length in bits, including parity, for DES in two-key EDE. */ + MBEDTLS_KEY_LENGTH_DES_EDE = 128, + /** Key length in bits, including parity, for DES in three-key EDE. */ + MBEDTLS_KEY_LENGTH_DES_EDE3 = 192, +}; + +/** Maximum length of any IV, in Bytes. */ +/* This should ideally be derived automatically from list of ciphers. + * This should be kept in sync with MBEDTLS_SSL_MAX_IV_LENGTH defined + * in ssl_internal.h. */ +#define MBEDTLS_MAX_IV_LENGTH 16 + +/** Maximum block size of any cipher, in Bytes. */ +/* This should ideally be derived automatically from list of ciphers. + * This should be kept in sync with MBEDTLS_SSL_MAX_BLOCK_LENGTH defined + * in ssl_internal.h. */ +#define MBEDTLS_MAX_BLOCK_LENGTH 16 + +/** Maximum key length, in Bytes. */ +/* This should ideally be derived automatically from list of ciphers. + * For now, only check whether XTS is enabled which uses 64 Byte keys, + * and use 32 Bytes as an upper bound for the maximum key length otherwise. + * This should be kept in sync with MBEDTLS_SSL_MAX_BLOCK_LENGTH defined + * in ssl_internal.h, which however deliberately ignores the case of XTS + * since the latter isn't used in SSL/TLS. */ +#if defined(MBEDTLS_CIPHER_MODE_XTS) +#define MBEDTLS_MAX_KEY_LENGTH 64 +#else +#define MBEDTLS_MAX_KEY_LENGTH 32 +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +/** + * Base cipher information (opaque struct). + */ +typedef struct mbedtls_cipher_base_t mbedtls_cipher_base_t; + +/** + * CMAC context (opaque struct). + */ +typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t; + +/** + * Cipher information. Allows calling cipher functions + * in a generic way. + */ +typedef struct mbedtls_cipher_info_t +{ + /** Full cipher identifier. For example, + * MBEDTLS_CIPHER_AES_256_CBC. + */ + mbedtls_cipher_type_t type; + + /** The cipher mode. For example, MBEDTLS_MODE_CBC. */ + mbedtls_cipher_mode_t mode; + + /** The cipher key length, in bits. This is the + * default length for variable sized ciphers. + * Includes parity bits for ciphers like DES. + */ + unsigned int key_bitlen; + + /** Name of the cipher. */ + const char * name; + + /** IV or nonce size, in Bytes. + * For ciphers that accept variable IV sizes, + * this is the recommended size. + */ + unsigned int iv_size; + + /** Bitflag comprised of MBEDTLS_CIPHER_VARIABLE_IV_LEN and + * MBEDTLS_CIPHER_VARIABLE_KEY_LEN indicating whether the + * cipher supports variable IV or variable key sizes, respectively. + */ + int flags; + + /** The block size, in Bytes. */ + unsigned int block_size; + + /** Struct for base cipher information and functions. */ + const mbedtls_cipher_base_t *base; + +} mbedtls_cipher_info_t; + +/** + * Generic cipher context. + */ +typedef struct mbedtls_cipher_context_t +{ + /** Information about the associated cipher. */ + const mbedtls_cipher_info_t *cipher_info; + + /** Key length to use. */ + int key_bitlen; + + /** Operation that the key of the context has been + * initialized for. + */ + mbedtls_operation_t operation; + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) + /** Padding functions to use, if relevant for + * the specific cipher mode. + */ + void (*add_padding)( unsigned char *output, size_t olen, size_t data_len ); + int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len ); +#endif + + /** Buffer for input that has not been processed yet. */ + unsigned char unprocessed_data[MBEDTLS_MAX_BLOCK_LENGTH]; + + /** Number of Bytes that have not been processed yet. */ + size_t unprocessed_len; + + /** Current IV or NONCE_COUNTER for CTR-mode, data unit (or sector) number + * for XTS-mode. */ + unsigned char iv[MBEDTLS_MAX_IV_LENGTH]; + + /** IV size in Bytes, for ciphers with variable-length IVs. */ + size_t iv_size; + + /** The cipher-specific context. */ + void *cipher_ctx; + +#if defined(MBEDTLS_CMAC_C) + /** CMAC-specific context. */ + mbedtls_cmac_context_t *cmac_ctx; +#endif + +#if defined(MBEDTLS_USE_PSA_CRYPTO) + /** Indicates whether the cipher operations should be performed + * by Mbed TLS' own crypto library or an external implementation + * of the PSA Crypto API. + * This is unset if the cipher context was established through + * mbedtls_cipher_setup(), and set if it was established through + * mbedtls_cipher_setup_psa(). + */ + unsigned char psa_enabled; +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +} mbedtls_cipher_context_t; + +/** + * \brief This function retrieves the list of ciphers supported + * by the generic cipher module. + * + * For any cipher identifier in the returned list, you can + * obtain the corresponding generic cipher information structure + * via mbedtls_cipher_info_from_type(), which can then be used + * to prepare a cipher context via mbedtls_cipher_setup(). + * + * + * \return A statically-allocated array of cipher identifiers + * of type cipher_type_t. The last entry is zero. + */ +const int *mbedtls_cipher_list( void ); + +/** + * \brief This function retrieves the cipher-information + * structure associated with the given cipher name. + * + * \param cipher_name Name of the cipher to search for. This must not be + * \c NULL. + * + * \return The cipher information structure associated with the + * given \p cipher_name. + * \return \c NULL if the associated cipher information is not found. + */ +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name ); + +/** + * \brief This function retrieves the cipher-information + * structure associated with the given cipher type. + * + * \param cipher_type Type of the cipher to search for. + * + * \return The cipher information structure associated with the + * given \p cipher_type. + * \return \c NULL if the associated cipher information is not found. + */ +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type ); + +/** + * \brief This function retrieves the cipher-information + * structure associated with the given cipher ID, + * key size and mode. + * + * \param cipher_id The ID of the cipher to search for. For example, + * #MBEDTLS_CIPHER_ID_AES. + * \param key_bitlen The length of the key in bits. + * \param mode The cipher mode. For example, #MBEDTLS_MODE_CBC. + * + * \return The cipher information structure associated with the + * given \p cipher_id. + * \return \c NULL if the associated cipher information is not found. + */ +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id, + int key_bitlen, + const mbedtls_cipher_mode_t mode ); + +/** + * \brief This function initializes a \p cipher_context as NONE. + * + * \param ctx The context to be initialized. This must not be \c NULL. + */ +void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ); + +/** + * \brief This function frees and clears the cipher-specific + * context of \p ctx. Freeing \p ctx itself remains the + * responsibility of the caller. + * + * \param ctx The context to be freed. If this is \c NULL, the + * function has no effect, otherwise this must point to an + * initialized context. + */ +void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ); + + +/** + * \brief This function initializes a cipher context for + * use with the given cipher primitive. + * + * \param ctx The context to initialize. This must be initialized. + * \param cipher_info The cipher to use. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the + * cipher-specific context fails. + * + * \internal Currently, the function also clears the structure. + * In future versions, the caller will be required to call + * mbedtls_cipher_init() on the structure first. + */ +int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, + const mbedtls_cipher_info_t *cipher_info ); + +#if defined(MBEDTLS_USE_PSA_CRYPTO) +/** + * \brief This function initializes a cipher context for + * PSA-based use with the given cipher primitive. + * + * \note See #MBEDTLS_USE_PSA_CRYPTO for information on PSA. + * + * \param ctx The context to initialize. May not be \c NULL. + * \param cipher_info The cipher to use. + * \param taglen For AEAD ciphers, the length in bytes of the + * authentication tag to use. Subsequent uses of + * mbedtls_cipher_auth_encrypt() or + * mbedtls_cipher_auth_decrypt() must provide + * the same tag length. + * For non-AEAD ciphers, the value must be \c 0. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the + * cipher-specific context fails. + */ +int mbedtls_cipher_setup_psa( mbedtls_cipher_context_t *ctx, + const mbedtls_cipher_info_t *cipher_info, + size_t taglen ); +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +/** + * \brief This function returns the block size of the given cipher. + * + * \param ctx The context of the cipher. This must be initialized. + * + * \return The block size of the underlying cipher. + * \return \c 0 if \p ctx has not been initialized. + */ +static inline unsigned int mbedtls_cipher_get_block_size( + const mbedtls_cipher_context_t *ctx ) +{ + MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 ); + if( ctx->cipher_info == NULL ) + return 0; + + return ctx->cipher_info->block_size; +} + +/** + * \brief This function returns the mode of operation for + * the cipher. For example, MBEDTLS_MODE_CBC. + * + * \param ctx The context of the cipher. This must be initialized. + * + * \return The mode of operation. + * \return #MBEDTLS_MODE_NONE if \p ctx has not been initialized. + */ +static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode( + const mbedtls_cipher_context_t *ctx ) +{ + MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, MBEDTLS_MODE_NONE ); + if( ctx->cipher_info == NULL ) + return MBEDTLS_MODE_NONE; + + return ctx->cipher_info->mode; +} + +/** + * \brief This function returns the size of the IV or nonce + * of the cipher, in Bytes. + * + * \param ctx The context of the cipher. This must be initialized. + * + * \return The recommended IV size if no IV has been set. + * \return \c 0 for ciphers not using an IV or a nonce. + * \return The actual size if an IV has been set. + */ +static inline int mbedtls_cipher_get_iv_size( + const mbedtls_cipher_context_t *ctx ) +{ + MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 ); + if( ctx->cipher_info == NULL ) + return 0; + + if( ctx->iv_size != 0 ) + return (int) ctx->iv_size; + + return (int) ctx->cipher_info->iv_size; +} + +/** + * \brief This function returns the type of the given cipher. + * + * \param ctx The context of the cipher. This must be initialized. + * + * \return The type of the cipher. + * \return #MBEDTLS_CIPHER_NONE if \p ctx has not been initialized. + */ +static inline mbedtls_cipher_type_t mbedtls_cipher_get_type( + const mbedtls_cipher_context_t *ctx ) +{ + MBEDTLS_INTERNAL_VALIDATE_RET( + ctx != NULL, MBEDTLS_CIPHER_NONE ); + if( ctx->cipher_info == NULL ) + return MBEDTLS_CIPHER_NONE; + + return ctx->cipher_info->type; +} + +/** + * \brief This function returns the name of the given cipher + * as a string. + * + * \param ctx The context of the cipher. This must be initialized. + * + * \return The name of the cipher. + * \return NULL if \p ctx has not been not initialized. + */ +static inline const char *mbedtls_cipher_get_name( + const mbedtls_cipher_context_t *ctx ) +{ + MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 ); + if( ctx->cipher_info == NULL ) + return 0; + + return ctx->cipher_info->name; +} + +/** + * \brief This function returns the key length of the cipher. + * + * \param ctx The context of the cipher. This must be initialized. + * + * \return The key length of the cipher in bits. + * \return #MBEDTLS_KEY_LENGTH_NONE if ctx \p has not been + * initialized. + */ +static inline int mbedtls_cipher_get_key_bitlen( + const mbedtls_cipher_context_t *ctx ) +{ + MBEDTLS_INTERNAL_VALIDATE_RET( + ctx != NULL, MBEDTLS_KEY_LENGTH_NONE ); + if( ctx->cipher_info == NULL ) + return MBEDTLS_KEY_LENGTH_NONE; + + return (int) ctx->cipher_info->key_bitlen; +} + +/** + * \brief This function returns the operation of the given cipher. + * + * \param ctx The context of the cipher. This must be initialized. + * + * \return The type of operation: #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT. + * \return #MBEDTLS_OPERATION_NONE if \p ctx has not been initialized. + */ +static inline mbedtls_operation_t mbedtls_cipher_get_operation( + const mbedtls_cipher_context_t *ctx ) +{ + MBEDTLS_INTERNAL_VALIDATE_RET( + ctx != NULL, MBEDTLS_OPERATION_NONE ); + if( ctx->cipher_info == NULL ) + return MBEDTLS_OPERATION_NONE; + + return ctx->operation; +} + +/** + * \brief This function sets the key to use with the given context. + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a cipher information structure. + * \param key The key to use. This must be a readable buffer of at + * least \p key_bitlen Bits. + * \param key_bitlen The key length to use, in Bits. + * \param operation The operation that the key will be used for: + * #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, + const unsigned char *key, + int key_bitlen, + const mbedtls_operation_t operation ); + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) +/** + * \brief This function sets the padding mode, for cipher modes + * that use padding. + * + * The default passing mode is PKCS7 padding. + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a cipher information structure. + * \param mode The padding mode. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE + * if the selected padding mode is not supported. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode + * does not support padding. + */ +int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, + mbedtls_cipher_padding_t mode ); +#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ + +/** + * \brief This function sets the initialization vector (IV) + * or nonce. + * + * \note Some ciphers do not use IVs nor nonce. For these + * ciphers, this function has no effect. + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a cipher information structure. + * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. This + * must be a readable buffer of at least \p iv_len Bytes. + * \param iv_len The IV length for ciphers with variable-size IV. + * This parameter is discarded by ciphers with fixed-size IV. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + */ +int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, + size_t iv_len ); + +/** + * \brief This function resets the cipher state. + * + * \param ctx The generic cipher context. This must be initialized. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + */ +int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ); + +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) +/** + * \brief This function adds additional data for AEAD ciphers. + * Currently supported with GCM and ChaCha20+Poly1305. + * This must be called exactly once, after + * mbedtls_cipher_reset(). + * + * \param ctx The generic cipher context. This must be initialized. + * \param ad The additional data to use. This must be a readable + * buffer of at least \p ad_len Bytes. + * \param ad_len The length of \p ad in Bytes. + * + * \return \c 0 on success. + * \return A specific error code on failure. + */ +int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, + const unsigned char *ad, size_t ad_len ); +#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ + +/** + * \brief The generic cipher update function. It encrypts or + * decrypts using the given cipher context. Writes as + * many block-sized blocks of data as possible to output. + * Any data that cannot be written immediately is either + * added to the next block, or flushed when + * mbedtls_cipher_finish() is called. + * Exception: For MBEDTLS_MODE_ECB, expects a single block + * in size. For example, 16 Bytes for AES. + * + * \note If the underlying cipher is used in GCM mode, all calls + * to this function, except for the last one before + * mbedtls_cipher_finish(), must have \p ilen as a + * multiple of the block size of the cipher. + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a key. + * \param input The buffer holding the input data. This must be a + * readable buffer of at least \p ilen Bytes. + * \param ilen The length of the input data. + * \param output The buffer for the output data. This must be able to + * hold at least `ilen + block_size`. This must not be the + * same buffer as \p input. + * \param olen The length of the output data, to be updated with the + * actual number of Bytes written. This must not be + * \c NULL. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an + * unsupported mode for a cipher. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, + const unsigned char *input, + size_t ilen, unsigned char *output, + size_t *olen ); + +/** + * \brief The generic cipher finalization function. If data still + * needs to be flushed from an incomplete block, the data + * contained in it is padded to the size of + * the last block, and written to the \p output buffer. + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a key. + * \param output The buffer to write data to. This needs to be a writable + * buffer of at least \p block_size Bytes. + * \param olen The length of the data written to the \p output buffer. + * This may not be \c NULL. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption + * expecting a full block but not receiving one. + * \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding + * while decrypting. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, + unsigned char *output, size_t *olen ); + +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) +/** + * \brief This function writes a tag for AEAD ciphers. + * Currently supported with GCM and ChaCha20+Poly1305. + * This must be called after mbedtls_cipher_finish(). + * + * \param ctx The generic cipher context. This must be initialized, + * bound to a key, and have just completed a cipher + * operation through mbedtls_cipher_finish() the tag for + * which should be written. + * \param tag The buffer to write the tag to. This must be a writable + * buffer of at least \p tag_len Bytes. + * \param tag_len The length of the tag to write. + * + * \return \c 0 on success. + * \return A specific error code on failure. + */ +int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, + unsigned char *tag, size_t tag_len ); + +/** + * \brief This function checks the tag for AEAD ciphers. + * Currently supported with GCM and ChaCha20+Poly1305. + * This must be called after mbedtls_cipher_finish(). + * + * \param ctx The generic cipher context. This must be initialized. + * \param tag The buffer holding the tag. This must be a readable + * buffer of at least \p tag_len Bytes. + * \param tag_len The length of the tag to check. + * + * \return \c 0 on success. + * \return A specific error code on failure. + */ +int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, + const unsigned char *tag, size_t tag_len ); +#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ + +/** + * \brief The generic all-in-one encryption/decryption function, + * for all ciphers except AEAD constructs. + * + * \param ctx The generic cipher context. This must be initialized. + * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. + * This must be a readable buffer of at least \p iv_len + * Bytes. + * \param iv_len The IV length for ciphers with variable-size IV. + * This parameter is discarded by ciphers with fixed-size + * IV. + * \param input The buffer holding the input data. This must be a + * readable buffer of at least \p ilen Bytes. + * \param ilen The length of the input data in Bytes. + * \param output The buffer for the output data. This must be able to + * hold at least `ilen + block_size`. This must not be the + * same buffer as \p input. + * \param olen The length of the output data, to be updated with the + * actual number of Bytes written. This must not be + * \c NULL. + * + * \note Some ciphers do not use IVs nor nonce. For these + * ciphers, use \p iv = NULL and \p iv_len = 0. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption + * expecting a full block but not receiving one. + * \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding + * while decrypting. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen ); + +#if defined(MBEDTLS_CIPHER_MODE_AEAD) +#if ! defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif /* MBEDTLS_DEPRECATED_WARNING */ +/** + * \brief The generic authenticated encryption (AEAD) function. + * + * \deprecated Superseded by mbedtls_cipher_auth_encrypt_ext(). + * + * \note This function only supports AEAD algorithms, not key + * wrapping algorithms such as NIST_KW; for this, see + * mbedtls_cipher_auth_encrypt_ext(). + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a key associated with an AEAD algorithm. + * \param iv The nonce to use. This must be a readable buffer of + * at least \p iv_len Bytes and must not be \c NULL. + * \param iv_len The length of the nonce. This must satisfy the + * constraints imposed by the AEAD cipher used. + * \param ad The additional data to authenticate. This must be a + * readable buffer of at least \p ad_len Bytes, and may + * be \c NULL is \p ad_len is \c 0. + * \param ad_len The length of \p ad. + * \param input The buffer holding the input data. This must be a + * readable buffer of at least \p ilen Bytes, and may be + * \c NULL if \p ilen is \c 0. + * \param ilen The length of the input data. + * \param output The buffer for the output data. This must be a + * writable buffer of at least \p ilen Bytes, and must + * not be \c NULL. + * \param olen This will be filled with the actual number of Bytes + * written to the \p output buffer. This must point to a + * writable object of type \c size_t. + * \param tag The buffer for the authentication tag. This must be a + * writable buffer of at least \p tag_len Bytes. See note + * below regarding restrictions with PSA-based contexts. + * \param tag_len The desired length of the authentication tag. This + * must match the constraints imposed by the AEAD cipher + * used, and in particular must not be \c 0. + * + * \note If the context is based on PSA (that is, it was set up + * with mbedtls_cipher_setup_psa()), then it is required + * that \c tag == output + ilen. That is, the tag must be + * appended to the ciphertext as recommended by RFC 5116. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + unsigned char *tag, size_t tag_len ) + MBEDTLS_DEPRECATED; + +/** + * \brief The generic authenticated decryption (AEAD) function. + * + * \deprecated Superseded by mbedtls_cipher_auth_decrypt_ext(). + * + * \note This function only supports AEAD algorithms, not key + * wrapping algorithms such as NIST_KW; for this, see + * mbedtls_cipher_auth_decrypt_ext(). + * + * \note If the data is not authentic, then the output buffer + * is zeroed out to prevent the unauthentic plaintext being + * used, making this interface safer. + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a key associated with an AEAD algorithm. + * \param iv The nonce to use. This must be a readable buffer of + * at least \p iv_len Bytes and must not be \c NULL. + * \param iv_len The length of the nonce. This must satisfy the + * constraints imposed by the AEAD cipher used. + * \param ad The additional data to authenticate. This must be a + * readable buffer of at least \p ad_len Bytes, and may + * be \c NULL is \p ad_len is \c 0. + * \param ad_len The length of \p ad. + * \param input The buffer holding the input data. This must be a + * readable buffer of at least \p ilen Bytes, and may be + * \c NULL if \p ilen is \c 0. + * \param ilen The length of the input data. + * \param output The buffer for the output data. This must be a + * writable buffer of at least \p ilen Bytes, and must + * not be \c NULL. + * \param olen This will be filled with the actual number of Bytes + * written to the \p output buffer. This must point to a + * writable object of type \c size_t. + * \param tag The buffer for the authentication tag. This must be a + * readable buffer of at least \p tag_len Bytes. See note + * below regarding restrictions with PSA-based contexts. + * \param tag_len The length of the authentication tag. This must match + * the constraints imposed by the AEAD cipher used, and in + * particular must not be \c 0. + * + * \note If the context is based on PSA (that is, it was set up + * with mbedtls_cipher_setup_psa()), then it is required + * that \c tag == input + len. That is, the tag must be + * appended to the ciphertext as recommended by RFC 5116. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + const unsigned char *tag, size_t tag_len ) + MBEDTLS_DEPRECATED; +#undef MBEDTLS_DEPRECATED +#endif /* MBEDTLS_DEPRECATED_REMOVED */ +#endif /* MBEDTLS_CIPHER_MODE_AEAD */ + +#if defined(MBEDTLS_CIPHER_MODE_AEAD) || defined(MBEDTLS_NIST_KW_C) +/** + * \brief The authenticated encryption (AEAD/NIST_KW) function. + * + * \note For AEAD modes, the tag will be appended to the + * ciphertext, as recommended by RFC 5116. + * (NIST_KW doesn't have a separate tag.) + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a key, with an AEAD algorithm or NIST_KW. + * \param iv The nonce to use. This must be a readable buffer of + * at least \p iv_len Bytes and may be \c NULL if \p + * iv_len is \c 0. + * \param iv_len The length of the nonce. For AEAD ciphers, this must + * satisfy the constraints imposed by the cipher used. + * For NIST_KW, this must be \c 0. + * \param ad The additional data to authenticate. This must be a + * readable buffer of at least \p ad_len Bytes, and may + * be \c NULL is \p ad_len is \c 0. + * \param ad_len The length of \p ad. For NIST_KW, this must be \c 0. + * \param input The buffer holding the input data. This must be a + * readable buffer of at least \p ilen Bytes, and may be + * \c NULL if \p ilen is \c 0. + * \param ilen The length of the input data. + * \param output The buffer for the output data. This must be a + * writable buffer of at least \p output_len Bytes, and + * must not be \c NULL. + * \param output_len The length of the \p output buffer in Bytes. For AEAD + * ciphers, this must be at least \p ilen + \p tag_len. + * For NIST_KW, this must be at least \p ilen + 8 + * (rounded up to a multiple of 8 if KWP is used); + * \p ilen + 15 is always a safe value. + * \param olen This will be filled with the actual number of Bytes + * written to the \p output buffer. This must point to a + * writable object of type \c size_t. + * \param tag_len The desired length of the authentication tag. For AEAD + * ciphers, this must match the constraints imposed by + * the cipher used, and in particular must not be \c 0. + * For NIST_KW, this must be \c 0. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_auth_encrypt_ext( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t output_len, + size_t *olen, size_t tag_len ); + +/** + * \brief The authenticated encryption (AEAD/NIST_KW) function. + * + * \note If the data is not authentic, then the output buffer + * is zeroed out to prevent the unauthentic plaintext being + * used, making this interface safer. + * + * \note For AEAD modes, the tag must be appended to the + * ciphertext, as recommended by RFC 5116. + * (NIST_KW doesn't have a separate tag.) + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a key, with an AEAD algorithm or NIST_KW. + * \param iv The nonce to use. This must be a readable buffer of + * at least \p iv_len Bytes and may be \c NULL if \p + * iv_len is \c 0. + * \param iv_len The length of the nonce. For AEAD ciphers, this must + * satisfy the constraints imposed by the cipher used. + * For NIST_KW, this must be \c 0. + * \param ad The additional data to authenticate. This must be a + * readable buffer of at least \p ad_len Bytes, and may + * be \c NULL is \p ad_len is \c 0. + * \param ad_len The length of \p ad. For NIST_KW, this must be \c 0. + * \param input The buffer holding the input data. This must be a + * readable buffer of at least \p ilen Bytes, and may be + * \c NULL if \p ilen is \c 0. + * \param ilen The length of the input data. For AEAD ciphers this + * must be at least \p tag_len. For NIST_KW this must be + * at least \c 8. + * \param output The buffer for the output data. This must be a + * writable buffer of at least \p output_len Bytes, and + * may be \c NULL if \p output_len is \c 0. + * \param output_len The length of the \p output buffer in Bytes. For AEAD + * ciphers, this must be at least \p ilen - \p tag_len. + * For NIST_KW, this must be at least \p ilen - 8. + * \param olen This will be filled with the actual number of Bytes + * written to the \p output buffer. This must point to a + * writable object of type \c size_t. + * \param tag_len The actual length of the authentication tag. For AEAD + * ciphers, this must match the constraints imposed by + * the cipher used, and in particular must not be \c 0. + * For NIST_KW, this must be \c 0. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_auth_decrypt_ext( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t output_len, + size_t *olen, size_t tag_len ); +#endif /* MBEDTLS_CIPHER_MODE_AEAD || MBEDTLS_NIST_KW_C */ +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_CIPHER_H */ diff --git a/third_party/mbedtls/include/mbedtls/ctr_drbg.h b/third_party/mbedtls/include/mbedtls/ctr_drbg.h new file mode 100644 index 0000000..e68237a --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/ctr_drbg.h @@ -0,0 +1,611 @@ +/** + * \file ctr_drbg.h + * + * \brief This file contains definitions and functions for the + * CTR_DRBG pseudorandom generator. + * + * CTR_DRBG is a standardized way of building a PRNG from a block-cipher + * in counter mode operation, as defined in NIST SP 800-90A: + * Recommendation for Random Number Generation Using Deterministic Random + * Bit Generators. + * + * The Mbed TLS implementation of CTR_DRBG uses AES-256 (default) or AES-128 + * (if \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled at compile time) + * as the underlying block cipher, with a derivation function. + * + * The security strength as defined in NIST SP 800-90A is + * 128 bits when AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled) + * and 256 bits otherwise, provided that #MBEDTLS_CTR_DRBG_ENTROPY_LEN is + * kept at its default value (and not overridden in config.h) and that the + * DRBG instance is set up with default parameters. + * See the documentation of mbedtls_ctr_drbg_seed() for more + * information. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_CTR_DRBG_H +#define MBEDTLS_CTR_DRBG_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/aes.h" + +#if defined(MBEDTLS_THREADING_C) +#include "mbedtls/threading.h" +#endif + +/** The entropy source failed. */ +#define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034 +/** The requested random buffer length is too big. */ +#define MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG -0x0036 +/** The input (entropy + additional data) is too large. */ +#define MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG -0x0038 +/** Read or write error in file. */ +#define MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR -0x003A + +#define MBEDTLS_CTR_DRBG_BLOCKSIZE 16 /**< The block size used by the cipher. */ + +#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) +#define MBEDTLS_CTR_DRBG_KEYSIZE 16 +/**< The key size in bytes used by the cipher. + * + * Compile-time choice: 16 bytes (128 bits) + * because #MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled. + */ +#else +#define MBEDTLS_CTR_DRBG_KEYSIZE 32 +/**< The key size in bytes used by the cipher. + * + * Compile-time choice: 32 bytes (256 bits) + * because \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled. + */ +#endif + +#define MBEDTLS_CTR_DRBG_KEYBITS ( MBEDTLS_CTR_DRBG_KEYSIZE * 8 ) /**< The key size for the DRBG operation, in bits. */ +#define MBEDTLS_CTR_DRBG_SEEDLEN ( MBEDTLS_CTR_DRBG_KEYSIZE + MBEDTLS_CTR_DRBG_BLOCKSIZE ) /**< The seed length, calculated as (counter + AES key). */ + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them using the compiler command + * line. + * \{ + */ + +/** \def MBEDTLS_CTR_DRBG_ENTROPY_LEN + * + * \brief The amount of entropy used per seed by default, in bytes. + */ +#if !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) +#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) +/** This is 48 bytes because the entropy module uses SHA-512 + * (\c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled). + */ +#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 + +#else /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */ + +/** This is 32 bytes because the entropy module uses SHA-256 + * (the SHA512 module is disabled or + * \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled). + */ +#if !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) +/** \warning To achieve a 256-bit security strength, you must pass a nonce + * to mbedtls_ctr_drbg_seed(). + */ +#endif /* !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) */ +#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 32 +#endif /* defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) */ +#endif /* !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) */ + +#if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL) +#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 +/**< The interval before reseed is performed by default. */ +#endif + +#if !defined(MBEDTLS_CTR_DRBG_MAX_INPUT) +#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 +/**< The maximum number of additional input Bytes. */ +#endif + +#if !defined(MBEDTLS_CTR_DRBG_MAX_REQUEST) +#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 +/**< The maximum number of requested Bytes per call. */ +#endif + +#if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) +#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 +/**< The maximum size of seed or reseed buffer in bytes. */ +#endif + +/** \} name SECTION: Module settings */ + +#define MBEDTLS_CTR_DRBG_PR_OFF 0 +/**< Prediction resistance is disabled. */ +#define MBEDTLS_CTR_DRBG_PR_ON 1 +/**< Prediction resistance is enabled. */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if MBEDTLS_CTR_DRBG_ENTROPY_LEN >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2 +/** The default length of the nonce read from the entropy source. + * + * This is \c 0 because a single read from the entropy source is sufficient + * to include a nonce. + * See the documentation of mbedtls_ctr_drbg_seed() for more information. + */ +#define MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN 0 +#else +/** The default length of the nonce read from the entropy source. + * + * This is half of the default entropy length because a single read from + * the entropy source does not provide enough material to form a nonce. + * See the documentation of mbedtls_ctr_drbg_seed() for more information. + */ +#define MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN ( MBEDTLS_CTR_DRBG_ENTROPY_LEN + 1 ) / 2 +#endif + +/** + * \brief The CTR_DRBG context structure. + */ +typedef struct mbedtls_ctr_drbg_context +{ + unsigned char counter[16]; /*!< The counter (V). */ + int reseed_counter; /*!< The reseed counter. + * This is the number of requests that have + * been made since the last (re)seeding, + * minus one. + * Before the initial seeding, this field + * contains the amount of entropy in bytes + * to use as a nonce for the initial seeding, + * or -1 if no nonce length has been explicitly + * set (see mbedtls_ctr_drbg_set_nonce_len()). + */ + int prediction_resistance; /*!< This determines whether prediction + resistance is enabled, that is + whether to systematically reseed before + each random generation. */ + size_t entropy_len; /*!< The amount of entropy grabbed on each + seed or reseed operation, in bytes. */ + int reseed_interval; /*!< The reseed interval. + * This is the maximum number of requests + * that can be made between reseedings. */ + + mbedtls_aes_context aes_ctx; /*!< The AES context. */ + + /* + * Callbacks (Entropy) + */ + int (*f_entropy)(void *, unsigned char *, size_t); + /*!< The entropy callback function. */ + + void *p_entropy; /*!< The context for the entropy function. */ + +#if defined(MBEDTLS_THREADING_C) + /* Invariant: the mutex is initialized if and only if f_entropy != NULL. + * This means that the mutex is initialized during the initial seeding + * in mbedtls_ctr_drbg_seed() and freed in mbedtls_ctr_drbg_free(). + * + * Note that this invariant may change without notice. Do not rely on it + * and do not access the mutex directly in application code. + */ + mbedtls_threading_mutex_t mutex; +#endif +} +mbedtls_ctr_drbg_context; + +/** + * \brief This function initializes the CTR_DRBG context, + * and prepares it for mbedtls_ctr_drbg_seed() + * or mbedtls_ctr_drbg_free(). + * + * \note The reseed interval is + * #MBEDTLS_CTR_DRBG_RESEED_INTERVAL by default. + * You can override it by calling + * mbedtls_ctr_drbg_set_reseed_interval(). + * + * \param ctx The CTR_DRBG context to initialize. + */ +void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ); + +/** + * \brief This function seeds and sets up the CTR_DRBG + * entropy source for future reseeds. + * + * A typical choice for the \p f_entropy and \p p_entropy parameters is + * to use the entropy module: + * - \p f_entropy is mbedtls_entropy_func(); + * - \p p_entropy is an instance of ::mbedtls_entropy_context initialized + * with mbedtls_entropy_init() (which registers the platform's default + * entropy sources). + * + * The entropy length is #MBEDTLS_CTR_DRBG_ENTROPY_LEN by default. + * You can override it by calling mbedtls_ctr_drbg_set_entropy_len(). + * + * The entropy nonce length is: + * - \c 0 if the entropy length is at least 3/2 times the entropy length, + * which guarantees that the security strength is the maximum permitted + * by the key size and entropy length according to NIST SP 800-90A §10.2.1; + * - Half the entropy length otherwise. + * You can override it by calling mbedtls_ctr_drbg_set_nonce_len(). + * With the default entropy length, the entropy nonce length is + * #MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN. + * + * You can provide a nonce and personalization string in addition to the + * entropy source, to make this instantiation as unique as possible. + * See SP 800-90A §8.6.7 for more details about nonces. + * + * The _seed_material_ value passed to the derivation function in + * the CTR_DRBG Instantiate Process described in NIST SP 800-90A §10.2.1.3.2 + * is the concatenation of the following strings: + * - A string obtained by calling \p f_entropy function for the entropy + * length. + */ +#if MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN == 0 +/** + * - If mbedtls_ctr_drbg_set_nonce_len() has been called, a string + * obtained by calling \p f_entropy function for the specified length. + */ +#else +/** + * - A string obtained by calling \p f_entropy function for the entropy nonce + * length. If the entropy nonce length is \c 0, this function does not + * make a second call to \p f_entropy. + */ +#endif +#if defined(MBEDTLS_THREADING_C) +/** + * \note When Mbed TLS is built with threading support, + * after this function returns successfully, + * it is safe to call mbedtls_ctr_drbg_random() + * from multiple threads. Other operations, including + * reseeding, are not thread-safe. + */ +#endif /* MBEDTLS_THREADING_C */ +/** + * - The \p custom string. + * + * \note To achieve the nominal security strength permitted + * by CTR_DRBG, the entropy length must be: + * - at least 16 bytes for a 128-bit strength + * (maximum achievable strength when using AES-128); + * - at least 32 bytes for a 256-bit strength + * (maximum achievable strength when using AES-256). + * + * In addition, if you do not pass a nonce in \p custom, + * the sum of the entropy length + * and the entropy nonce length must be: + * - at least 24 bytes for a 128-bit strength + * (maximum achievable strength when using AES-128); + * - at least 48 bytes for a 256-bit strength + * (maximum achievable strength when using AES-256). + * + * \param ctx The CTR_DRBG context to seed. + * It must have been initialized with + * mbedtls_ctr_drbg_init(). + * After a successful call to mbedtls_ctr_drbg_seed(), + * you may not call mbedtls_ctr_drbg_seed() again on + * the same context unless you call + * mbedtls_ctr_drbg_free() and mbedtls_ctr_drbg_init() + * again first. + * After a failed call to mbedtls_ctr_drbg_seed(), + * you must call mbedtls_ctr_drbg_free(). + * \param f_entropy The entropy callback, taking as arguments the + * \p p_entropy context, the buffer to fill, and the + * length of the buffer. + * \p f_entropy is always called with a buffer size + * less than or equal to the entropy length. + * \param p_entropy The entropy context to pass to \p f_entropy. + * \param custom The personalization string. + * This can be \c NULL, in which case the personalization + * string is empty regardless of the value of \p len. + * \param len The length of the personalization string. + * This must be at most + * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + * - #MBEDTLS_CTR_DRBG_ENTROPY_LEN. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure. + */ +int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx, + int (*f_entropy)(void *, unsigned char *, size_t), + void *p_entropy, + const unsigned char *custom, + size_t len ); + +/** + * \brief This function resets CTR_DRBG context to the state immediately + * after initial call of mbedtls_ctr_drbg_init(). + * + * \param ctx The CTR_DRBG context to clear. + */ +void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx ); + +/** + * \brief This function turns prediction resistance on or off. + * The default value is off. + * + * \note If enabled, entropy is gathered at the beginning of + * every call to mbedtls_ctr_drbg_random_with_add() + * or mbedtls_ctr_drbg_random(). + * Only use this if your entropy source has sufficient + * throughput. + * + * \param ctx The CTR_DRBG context. + * \param resistance #MBEDTLS_CTR_DRBG_PR_ON or #MBEDTLS_CTR_DRBG_PR_OFF. + */ +void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, + int resistance ); + +/** + * \brief This function sets the amount of entropy grabbed on each + * seed or reseed. + * + * The default value is #MBEDTLS_CTR_DRBG_ENTROPY_LEN. + * + * \note The security strength of CTR_DRBG is bounded by the + * entropy length. Thus: + * - When using AES-256 + * (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled, + * which is the default), + * \p len must be at least 32 (in bytes) + * to achieve a 256-bit strength. + * - When using AES-128 + * (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled) + * \p len must be at least 16 (in bytes) + * to achieve a 128-bit strength. + * + * \param ctx The CTR_DRBG context. + * \param len The amount of entropy to grab, in bytes. + * This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + * and at most the maximum length accepted by the + * entropy function that is set in the context. + */ +void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, + size_t len ); + +/** + * \brief This function sets the amount of entropy grabbed + * as a nonce for the initial seeding. + * + * Call this function before calling mbedtls_ctr_drbg_seed() to read + * a nonce from the entropy source during the initial seeding. + * + * \param ctx The CTR_DRBG context. + * \param len The amount of entropy to grab for the nonce, in bytes. + * This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + * and at most the maximum length accepted by the + * entropy function that is set in the context. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if \p len is + * more than #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. + * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED + * if the initial seeding has already taken place. + */ +int mbedtls_ctr_drbg_set_nonce_len( mbedtls_ctr_drbg_context *ctx, + size_t len ); + +/** + * \brief This function sets the reseed interval. + * + * The reseed interval is the number of calls to mbedtls_ctr_drbg_random() + * or mbedtls_ctr_drbg_random_with_add() after which the entropy function + * is called again. + * + * The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL. + * + * \param ctx The CTR_DRBG context. + * \param interval The reseed interval. + */ +void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, + int interval ); + +/** + * \brief This function reseeds the CTR_DRBG context, that is + * extracts data from the entropy source. + * + * \note This function is not thread-safe. It is not safe + * to call this function if another thread might be + * concurrently obtaining random numbers from the same + * context or updating or reseeding the same context. + * + * \param ctx The CTR_DRBG context. + * \param additional Additional data to add to the state. Can be \c NULL. + * \param len The length of the additional data. + * This must be less than + * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len + * where \c entropy_len is the entropy length + * configured for the context. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure. + */ +int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, + const unsigned char *additional, size_t len ); + +/** + * \brief This function updates the state of the CTR_DRBG context. + * + * \note This function is not thread-safe. It is not safe + * to call this function if another thread might be + * concurrently obtaining random numbers from the same + * context or updating or reseeding the same context. + * + * \param ctx The CTR_DRBG context. + * \param additional The data to update the state with. This must not be + * \c NULL unless \p add_len is \c 0. + * \param add_len Length of \p additional in bytes. This must be at + * most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if + * \p add_len is more than + * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT. + * \return An error from the underlying AES cipher on failure. + */ +int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx, + const unsigned char *additional, + size_t add_len ); + +/** + * \brief This function updates a CTR_DRBG instance with additional + * data and uses it to generate random data. + * + * This function automatically reseeds if the reseed counter is exceeded + * or prediction resistance is enabled. + * + * \note This function is not thread-safe. It is not safe + * to call this function if another thread might be + * concurrently obtaining random numbers from the same + * context or updating or reseeding the same context. + * + * \param p_rng The CTR_DRBG context. This must be a pointer to a + * #mbedtls_ctr_drbg_context structure. + * \param output The buffer to fill. + * \param output_len The length of the buffer in bytes. + * \param additional Additional data to update. Can be \c NULL, in which + * case the additional data is empty regardless of + * the value of \p add_len. + * \param add_len The length of the additional data + * if \p additional is not \c NULL. + * This must be less than #MBEDTLS_CTR_DRBG_MAX_INPUT + * and less than + * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len + * where \c entropy_len is the entropy length + * configured for the context. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or + * #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure. + */ +int mbedtls_ctr_drbg_random_with_add( void *p_rng, + unsigned char *output, size_t output_len, + const unsigned char *additional, size_t add_len ); + +/** + * \brief This function uses CTR_DRBG to generate random data. + * + * This function automatically reseeds if the reseed counter is exceeded + * or prediction resistance is enabled. + */ +#if defined(MBEDTLS_THREADING_C) +/** + * \note When Mbed TLS is built with threading support, + * it is safe to call mbedtls_ctr_drbg_random() + * from multiple threads. Other operations, including + * reseeding, are not thread-safe. + */ +#endif /* MBEDTLS_THREADING_C */ +/** + * \param p_rng The CTR_DRBG context. This must be a pointer to a + * #mbedtls_ctr_drbg_context structure. + * \param output The buffer to fill. + * \param output_len The length of the buffer in bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or + * #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure. + */ +int mbedtls_ctr_drbg_random( void *p_rng, + unsigned char *output, size_t output_len ); + + +#if ! defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif +/** + * \brief This function updates the state of the CTR_DRBG context. + * + * \deprecated Superseded by mbedtls_ctr_drbg_update_ret() + * in 2.16.0. + * + * \note If \p add_len is greater than + * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT, only the first + * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT Bytes are used. + * The remaining Bytes are silently discarded. + * + * \param ctx The CTR_DRBG context. + * \param additional The data to update the state with. + * \param add_len Length of \p additional data. + */ +MBEDTLS_DEPRECATED void mbedtls_ctr_drbg_update( + mbedtls_ctr_drbg_context *ctx, + const unsigned char *additional, + size_t add_len ); +#undef MBEDTLS_DEPRECATED +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ + +#if defined(MBEDTLS_FS_IO) +/** + * \brief This function writes a seed file. + * + * \param ctx The CTR_DRBG context. + * \param path The name of the file. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error. + * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on reseed + * failure. + */ +int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ); + +/** + * \brief This function reads and updates a seed file. The seed + * is added to this instance. + * + * \param ctx The CTR_DRBG context. + * \param path The name of the file. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error. + * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on + * reseed failure. + * \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if the existing + * seed file is too large. + */ +int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ); +#endif /* MBEDTLS_FS_IO */ + +#if defined(MBEDTLS_SELF_TEST) + +/** + * \brief The CTR_DRBG checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +int mbedtls_ctr_drbg_self_test( int verbose ); + +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + +#endif /* ctr_drbg.h */ diff --git a/third_party/mbedtls/include/mbedtls/dhm.h b/third_party/mbedtls/include/mbedtls/dhm.h new file mode 100644 index 0000000..c4b15a2 --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/dhm.h @@ -0,0 +1,1103 @@ +/** + * \file dhm.h + * + * \brief This file contains Diffie-Hellman-Merkle (DHM) key exchange + * definitions and functions. + * + * Diffie-Hellman-Merkle (DHM) key exchange is defined in + * RFC-2631: Diffie-Hellman Key Agreement Method and + * Public-Key Cryptography Standards (PKCS) #3: Diffie + * Hellman Key Agreement Standard. + * + * RFC-3526: More Modular Exponential (MODP) Diffie-Hellman groups for + * Internet Key Exchange (IKE) defines a number of standardized + * Diffie-Hellman groups for IKE. + * + * RFC-5114: Additional Diffie-Hellman Groups for Use with IETF + * Standards defines a number of standardized Diffie-Hellman + * groups that can be used. + * + * \warning The security of the DHM key exchange relies on the proper choice + * of prime modulus - optimally, it should be a safe prime. The usage + * of non-safe primes both decreases the difficulty of the underlying + * discrete logarithm problem and can lead to small subgroup attacks + * leaking private exponent bits when invalid public keys are used + * and not detected. This is especially relevant if the same DHM + * parameters are reused for multiple key exchanges as in static DHM, + * while the criticality of small-subgroup attacks is lower for + * ephemeral DHM. + * + * \warning For performance reasons, the code does neither perform primality + * nor safe primality tests, nor the expensive checks for invalid + * subgroups. Moreover, even if these were performed, non-standardized + * primes cannot be trusted because of the possibility of backdoors + * that can't be effectively checked for. + * + * \warning Diffie-Hellman-Merkle is therefore a security risk when not using + * standardized primes generated using a trustworthy ("nothing up + * my sleeve") method, such as the RFC 3526 / 7919 primes. In the TLS + * protocol, DH parameters need to be negotiated, so using the default + * primes systematically is not always an option. If possible, use + * Elliptic Curve Diffie-Hellman (ECDH), which has better performance, + * and for which the TLS protocol mandates the use of standard + * parameters. + * + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_DHM_H +#define MBEDTLS_DHM_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif +#include "mbedtls/bignum.h" + +/* + * DHM Error codes + */ +/** Bad input parameters. */ +#define MBEDTLS_ERR_DHM_BAD_INPUT_DATA -0x3080 +/** Reading of the DHM parameters failed. */ +#define MBEDTLS_ERR_DHM_READ_PARAMS_FAILED -0x3100 +/** Making of the DHM parameters failed. */ +#define MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED -0x3180 +/** Reading of the public values failed. */ +#define MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED -0x3200 +/** Making of the public value failed. */ +#define MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED -0x3280 +/** Calculation of the DHM secret failed. */ +#define MBEDTLS_ERR_DHM_CALC_SECRET_FAILED -0x3300 +/** The ASN.1 data is not formatted correctly. */ +#define MBEDTLS_ERR_DHM_INVALID_FORMAT -0x3380 +/** Allocation of memory failed. */ +#define MBEDTLS_ERR_DHM_ALLOC_FAILED -0x3400 +/** Read or write of file failed. */ +#define MBEDTLS_ERR_DHM_FILE_IO_ERROR -0x3480 + +/* MBEDTLS_ERR_DHM_HW_ACCEL_FAILED is deprecated and should not be used. */ +/** DHM hardware accelerator failed. */ +#define MBEDTLS_ERR_DHM_HW_ACCEL_FAILED -0x3500 + +/** Setting the modulus and generator failed. */ +#define MBEDTLS_ERR_DHM_SET_GROUP_FAILED -0x3580 + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(MBEDTLS_DHM_ALT) + +/** + * \brief The DHM context structure. + */ +typedef struct mbedtls_dhm_context +{ + size_t len; /*!< The size of \p P in Bytes. */ + mbedtls_mpi P; /*!< The prime modulus. */ + mbedtls_mpi G; /*!< The generator. */ + mbedtls_mpi X; /*!< Our secret value. */ + mbedtls_mpi GX; /*!< Our public key = \c G^X mod \c P. */ + mbedtls_mpi GY; /*!< The public key of the peer = \c G^Y mod \c P. */ + mbedtls_mpi K; /*!< The shared secret = \c G^(XY) mod \c P. */ + mbedtls_mpi RP; /*!< The cached value = \c R^2 mod \c P. */ + mbedtls_mpi Vi; /*!< The blinding value. */ + mbedtls_mpi Vf; /*!< The unblinding value. */ + mbedtls_mpi pX; /*!< The previous \c X. */ +} +mbedtls_dhm_context; + +#else /* MBEDTLS_DHM_ALT */ +#include "dhm_alt.h" +#endif /* MBEDTLS_DHM_ALT */ + +/** + * \brief This function initializes the DHM context. + * + * \param ctx The DHM context to initialize. + */ +void mbedtls_dhm_init( mbedtls_dhm_context *ctx ); + +/** + * \brief This function parses the DHM parameters in a + * TLS ServerKeyExchange handshake message + * (DHM modulus, generator, and public key). + * + * \note In a TLS handshake, this is the how the client + * sets up its DHM context from the server's public + * DHM key material. + * + * \param ctx The DHM context to use. This must be initialized. + * \param p On input, *p must be the start of the input buffer. + * On output, *p is updated to point to the end of the data + * that has been read. On success, this is the first byte + * past the end of the ServerKeyExchange parameters. + * On error, this is the point at which an error has been + * detected, which is usually not useful except to debug + * failures. + * \param end The end of the input buffer. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. + */ +int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx, + unsigned char **p, + const unsigned char *end ); + +/** + * \brief This function generates a DHM key pair and exports its + * public part together with the DHM parameters in the format + * used in a TLS ServerKeyExchange handshake message. + * + * \note This function assumes that the DHM parameters \c ctx->P + * and \c ctx->G have already been properly set. For that, use + * mbedtls_dhm_set_group() below in conjunction with + * mbedtls_mpi_read_binary() and mbedtls_mpi_read_string(). + * + * \note In a TLS handshake, this is the how the server generates + * and exports its DHM key material. + * + * \param ctx The DHM context to use. This must be initialized + * and have the DHM parameters set. It may or may not + * already have imported the peer's public key. + * \param x_size The private key size in Bytes. + * \param olen The address at which to store the number of Bytes + * written on success. This must not be \c NULL. + * \param output The destination buffer. This must be a writable buffer of + * sufficient size to hold the reduced binary presentation of + * the modulus, the generator and the public key, each wrapped + * with a 2-byte length field. It is the responsibility of the + * caller to ensure that enough space is available. Refer to + * mbedtls_mpi_size() to computing the byte-size of an MPI. + * \param f_rng The RNG function. Must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context parameter. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. + */ +int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size, + unsigned char *output, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief This function sets the prime modulus and generator. + * + * \note This function can be used to set \c ctx->P, \c ctx->G + * in preparation for mbedtls_dhm_make_params(). + * + * \param ctx The DHM context to configure. This must be initialized. + * \param P The MPI holding the DHM prime modulus. This must be + * an initialized MPI. + * \param G The MPI holding the DHM generator. This must be an + * initialized MPI. + * + * \return \c 0 if successful. + * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. + */ +int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx, + const mbedtls_mpi *P, + const mbedtls_mpi *G ); + +/** + * \brief This function imports the raw public value of the peer. + * + * \note In a TLS handshake, this is the how the server imports + * the Client's public DHM key. + * + * \param ctx The DHM context to use. This must be initialized and have + * its DHM parameters set, e.g. via mbedtls_dhm_set_group(). + * It may or may not already have generated its own private key. + * \param input The input buffer containing the \c G^Y value of the peer. + * This must be a readable buffer of size \p ilen Bytes. + * \param ilen The size of the input buffer \p input in Bytes. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. + */ +int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx, + const unsigned char *input, size_t ilen ); + +/** + * \brief This function creates a DHM key pair and exports + * the raw public key in big-endian format. + * + * \note The destination buffer is always fully written + * so as to contain a big-endian representation of G^X mod P. + * If it is larger than \c ctx->len, it is padded accordingly + * with zero-bytes at the beginning. + * + * \param ctx The DHM context to use. This must be initialized and + * have the DHM parameters set. It may or may not already + * have imported the peer's public key. + * \param x_size The private key size in Bytes. + * \param output The destination buffer. This must be a writable buffer of + * size \p olen Bytes. + * \param olen The length of the destination buffer. This must be at least + * equal to `ctx->len` (the size of \c P). + * \param f_rng The RNG function. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL + * if \p f_rng doesn't need a context argument. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. + */ +int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size, + unsigned char *output, size_t olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief This function derives and exports the shared secret + * \c (G^Y)^X mod \c P. + * + * \note If \p f_rng is not \c NULL, it is used to blind the input as + * a countermeasure against timing attacks. Blinding is used + * only if our private key \c X is re-used, and not used + * otherwise. We recommend always passing a non-NULL + * \p f_rng argument. + * + * \param ctx The DHM context to use. This must be initialized + * and have its own private key generated and the peer's + * public key imported. + * \param output The buffer to write the generated shared key to. This + * must be a writable buffer of size \p output_size Bytes. + * \param output_size The size of the destination buffer. This must be at + * least the size of \c ctx->len (the size of \c P). + * \param olen On exit, holds the actual number of Bytes written. + * \param f_rng The RNG function, for blinding purposes. This may + * b \c NULL if blinding isn't needed. + * \param p_rng The RNG context. This may be \c NULL if \p f_rng + * doesn't need a context argument. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_DHM_XXX error code on failure. + */ +int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx, + unsigned char *output, size_t output_size, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief This function frees and clears the components + * of a DHM context. + * + * \param ctx The DHM context to free and clear. This may be \c NULL, + * in which case this function is a no-op. If it is not \c NULL, + * it must point to an initialized DHM context. + */ +void mbedtls_dhm_free( mbedtls_dhm_context *ctx ); + +#if defined(MBEDTLS_ASN1_PARSE_C) +/** + * \brief This function parses DHM parameters in PEM or DER format. + * + * \param dhm The DHM context to import the DHM parameters into. + * This must be initialized. + * \param dhmin The input buffer. This must be a readable buffer of + * length \p dhminlen Bytes. + * \param dhminlen The size of the input buffer \p dhmin, including the + * terminating \c NULL Byte for PEM data. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX error + * code on failure. + */ +int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin, + size_t dhminlen ); + +#if defined(MBEDTLS_FS_IO) +/** + * \brief This function loads and parses DHM parameters from a file. + * + * \param dhm The DHM context to load the parameters to. + * This must be initialized. + * \param path The filename to read the DHM parameters from. + * This must not be \c NULL. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX + * error code on failure. + */ +int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path ); +#endif /* MBEDTLS_FS_IO */ +#endif /* MBEDTLS_ASN1_PARSE_C */ + +#if defined(MBEDTLS_SELF_TEST) + +/** + * \brief The DMH checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +int mbedtls_dhm_self_test( int verbose ); + +#endif /* MBEDTLS_SELF_TEST */ +#ifdef __cplusplus +} +#endif + +/** + * RFC 3526, RFC 5114 and RFC 7919 standardize a number of + * Diffie-Hellman groups, some of which are included here + * for use within the SSL/TLS module and the user's convenience + * when configuring the Diffie-Hellman parameters by hand + * through \c mbedtls_ssl_conf_dh_param. + * + * The following lists the source of the above groups in the standards: + * - RFC 5114 section 2.2: 2048-bit MODP Group with 224-bit Prime Order Subgroup + * - RFC 3526 section 3: 2048-bit MODP Group + * - RFC 3526 section 4: 3072-bit MODP Group + * - RFC 3526 section 5: 4096-bit MODP Group + * - RFC 7919 section A.1: ffdhe2048 + * - RFC 7919 section A.2: ffdhe3072 + * - RFC 7919 section A.3: ffdhe4096 + * - RFC 7919 section A.4: ffdhe6144 + * - RFC 7919 section A.5: ffdhe8192 + * + * The constants with suffix "_p" denote the chosen prime moduli, while + * the constants with suffix "_g" denote the chosen generator + * of the associated prime field. + * + * The constants further suffixed with "_bin" are provided in binary format, + * while all other constants represent null-terminated strings holding the + * hexadecimal presentation of the respective numbers. + * + * The primes from RFC 3526 and RFC 7919 have been generating by the following + * trust-worthy procedure: + * - Fix N in { 2048, 3072, 4096, 6144, 8192 } and consider the N-bit number + * the first and last 64 bits are all 1, and the remaining N - 128 bits of + * which are 0x7ff...ff. + * - Add the smallest multiple of the first N - 129 bits of the binary expansion + * of pi (for RFC 5236) or e (for RFC 7919) to this intermediate bit-string + * such that the resulting integer is a safe-prime. + * - The result is the respective RFC 3526 / 7919 prime, and the corresponding + * generator is always chosen to be 2 (which is a square for these prime, + * hence the corresponding subgroup has order (p-1)/2 and avoids leaking a + * bit in the private exponent). + * + */ + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) + +/** + * \warning The origin of the primes in RFC 5114 is not documented and + * their use therefore constitutes a security risk! + * + * \deprecated The hex-encoded primes from RFC 5114 are deprecated and are + * likely to be removed in a future version of the library without + * replacement. + */ + +/** + * The hexadecimal presentation of the prime underlying the + * 2048-bit MODP Group with 224-bit Prime Order Subgroup, as defined + * in RFC-5114: Additional Diffie-Hellman Groups for Use with + * IETF Standards. + */ +#define MBEDTLS_DHM_RFC5114_MODP_2048_P \ + MBEDTLS_DEPRECATED_STRING_CONSTANT( \ + "AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1" \ + "B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15" \ + "EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC212" \ + "9037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207" \ + "C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708" \ + "B3BF8A317091883681286130BC8985DB1602E714415D9330" \ + "278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486D" \ + "CDF93ACC44328387315D75E198C641A480CD86A1B9E587E8" \ + "BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763" \ + "C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71" \ + "CF9DE5384E71B81C0AC4DFFE0C10E64F" ) + +/** + * The hexadecimal presentation of the chosen generator of the 2048-bit MODP + * Group with 224-bit Prime Order Subgroup, as defined in RFC-5114: + * Additional Diffie-Hellman Groups for Use with IETF Standards. + */ +#define MBEDTLS_DHM_RFC5114_MODP_2048_G \ + MBEDTLS_DEPRECATED_STRING_CONSTANT( \ + "AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF" \ + "74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFA" \ + "AB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7" \ + "C17669101999024AF4D027275AC1348BB8A762D0521BC98A" \ + "E247150422EA1ED409939D54DA7460CDB5F6C6B250717CBE" \ + "F180EB34118E98D119529A45D6F834566E3025E316A330EF" \ + "BB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB" \ + "10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381" \ + "B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269" \ + "EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC0179" \ + "81BC087F2A7065B384B890D3191F2BFA" ) + +/** + * The hexadecimal presentation of the prime underlying the 2048-bit MODP + * Group, as defined in RFC-3526: More Modular Exponential (MODP) + * Diffie-Hellman groups for Internet Key Exchange (IKE). + * + * \deprecated The hex-encoded primes from RFC 3625 are deprecated and + * superseded by the corresponding macros providing them as + * binary constants. Their hex-encoded constants are likely + * to be removed in a future version of the library. + * + */ +#define MBEDTLS_DHM_RFC3526_MODP_2048_P \ + MBEDTLS_DEPRECATED_STRING_CONSTANT( \ + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \ + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \ + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" \ + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \ + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \ + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \ + "15728E5A8AACAA68FFFFFFFFFFFFFFFF" ) + +/** + * The hexadecimal presentation of the chosen generator of the 2048-bit MODP + * Group, as defined in RFC-3526: More Modular Exponential (MODP) + * Diffie-Hellman groups for Internet Key Exchange (IKE). + */ +#define MBEDTLS_DHM_RFC3526_MODP_2048_G \ + MBEDTLS_DEPRECATED_STRING_CONSTANT( "02" ) + +/** + * The hexadecimal presentation of the prime underlying the 3072-bit MODP + * Group, as defined in RFC-3072: More Modular Exponential (MODP) + * Diffie-Hellman groups for Internet Key Exchange (IKE). + */ +#define MBEDTLS_DHM_RFC3526_MODP_3072_P \ + MBEDTLS_DEPRECATED_STRING_CONSTANT( \ + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \ + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \ + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" \ + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \ + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \ + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \ + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" \ + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" \ + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" \ + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" \ + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" \ + "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF" ) + +/** + * The hexadecimal presentation of the chosen generator of the 3072-bit MODP + * Group, as defined in RFC-3526: More Modular Exponential (MODP) + * Diffie-Hellman groups for Internet Key Exchange (IKE). + */ +#define MBEDTLS_DHM_RFC3526_MODP_3072_G \ + MBEDTLS_DEPRECATED_STRING_CONSTANT( "02" ) + +/** + * The hexadecimal presentation of the prime underlying the 4096-bit MODP + * Group, as defined in RFC-3526: More Modular Exponential (MODP) + * Diffie-Hellman groups for Internet Key Exchange (IKE). + */ +#define MBEDTLS_DHM_RFC3526_MODP_4096_P \ + MBEDTLS_DEPRECATED_STRING_CONSTANT( \ + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \ + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \ + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" \ + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \ + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \ + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \ + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" \ + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" \ + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" \ + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" \ + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" \ + "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" \ + "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" \ + "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" \ + "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" \ + "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" \ + "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" \ + "FFFFFFFFFFFFFFFF" ) + +/** + * The hexadecimal presentation of the chosen generator of the 4096-bit MODP + * Group, as defined in RFC-3526: More Modular Exponential (MODP) + * Diffie-Hellman groups for Internet Key Exchange (IKE). + */ +#define MBEDTLS_DHM_RFC3526_MODP_4096_G \ + MBEDTLS_DEPRECATED_STRING_CONSTANT( "02" ) + +#endif /* MBEDTLS_DEPRECATED_REMOVED */ + +/* + * Trustworthy DHM parameters in binary form + */ + +#define MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN { \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, \ + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, \ + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, \ + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, \ + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, \ + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, \ + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, \ + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, \ + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, \ + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, \ + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, \ + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, \ + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, \ + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, \ + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, \ + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, \ + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, \ + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, \ + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, \ + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, \ + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, \ + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, \ + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, \ + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, \ + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, \ + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, \ + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, \ + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, \ + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, \ + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } + +#define MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN { 0x02 } + +#define MBEDTLS_DHM_RFC3526_MODP_3072_P_BIN { \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, \ + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, \ + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, \ + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, \ + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, \ + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, \ + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, \ + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, \ + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, \ + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, \ + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, \ + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, \ + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, \ + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, \ + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, \ + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, \ + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, \ + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, \ + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, \ + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, \ + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, \ + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, \ + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, \ + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, \ + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, \ + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, \ + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, \ + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, \ + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, \ + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, \ + 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, \ + 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, \ + 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, \ + 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, \ + 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, \ + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, \ + 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, \ + 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, \ + 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, \ + 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, \ + 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, \ + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, \ + 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, \ + 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, \ + 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, \ + 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } + +#define MBEDTLS_DHM_RFC3526_MODP_3072_G_BIN { 0x02 } + +#define MBEDTLS_DHM_RFC3526_MODP_4096_P_BIN { \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, \ + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, \ + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, \ + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, \ + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, \ + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, \ + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, \ + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, \ + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, \ + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, \ + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, \ + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, \ + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, \ + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, \ + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, \ + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, \ + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, \ + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, \ + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, \ + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, \ + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, \ + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, \ + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, \ + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, \ + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, \ + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, \ + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, \ + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, \ + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, \ + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, \ + 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, \ + 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, \ + 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, \ + 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, \ + 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, \ + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, \ + 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, \ + 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, \ + 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, \ + 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, \ + 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, \ + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, \ + 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, \ + 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, \ + 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, \ + 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, \ + 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, \ + 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, \ + 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, \ + 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, \ + 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, \ + 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, \ + 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, \ + 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, \ + 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, \ + 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, \ + 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, \ + 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, \ + 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, \ + 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, \ + 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, \ + 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } + +#define MBEDTLS_DHM_RFC3526_MODP_4096_G_BIN { 0x02 } + +#define MBEDTLS_DHM_RFC7919_FFDHE2048_P_BIN { \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ + 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ + 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ + 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ + 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ + 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ + 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ + 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ + 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ + 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ + 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ + 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ + 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ + 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ + 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ + 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ + 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ + 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ + 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ + 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ + 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ + 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ + 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ + 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ + 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ + 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ + 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ + 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ + 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ + 0x88, 0x6B, 0x42, 0x38, 0x61, 0x28, 0x5C, 0x97, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, } + +#define MBEDTLS_DHM_RFC7919_FFDHE2048_G_BIN { 0x02 } + +#define MBEDTLS_DHM_RFC7919_FFDHE3072_P_BIN { \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ + 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ + 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ + 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ + 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ + 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ + 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ + 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ + 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ + 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ + 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ + 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ + 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ + 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ + 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ + 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ + 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ + 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ + 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ + 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ + 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ + 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ + 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ + 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ + 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ + 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ + 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ + 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ + 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ + 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \ + 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \ + 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \ + 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \ + 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \ + 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \ + 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \ + 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \ + 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \ + 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \ + 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \ + 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \ + 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \ + 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \ + 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \ + 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \ + 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0xC6, 0x2E, 0x37, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } + +#define MBEDTLS_DHM_RFC7919_FFDHE3072_G_BIN { 0x02 } + +#define MBEDTLS_DHM_RFC7919_FFDHE4096_P_BIN { \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ + 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ + 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ + 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ + 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ + 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ + 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ + 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ + 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ + 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ + 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ + 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ + 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ + 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ + 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ + 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ + 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ + 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ + 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ + 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ + 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ + 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ + 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ + 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ + 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ + 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ + 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ + 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ + 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ + 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \ + 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \ + 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \ + 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \ + 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \ + 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \ + 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \ + 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \ + 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \ + 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \ + 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \ + 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \ + 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \ + 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \ + 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \ + 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \ + 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, \ + 0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, \ + 0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, \ + 0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, \ + 0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, \ + 0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, \ + 0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, \ + 0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, \ + 0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, \ + 0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, \ + 0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, \ + 0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, \ + 0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, \ + 0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, \ + 0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, \ + 0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, \ + 0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x65, 0x5F, 0x6A, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } + +#define MBEDTLS_DHM_RFC7919_FFDHE4096_G_BIN { 0x02 } + +#define MBEDTLS_DHM_RFC7919_FFDHE6144_P_BIN { \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ + 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ + 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ + 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ + 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ + 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ + 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ + 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ + 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ + 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ + 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ + 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ + 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ + 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ + 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ + 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ + 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ + 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ + 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ + 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ + 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ + 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ + 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ + 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ + 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ + 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ + 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ + 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ + 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ + 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \ + 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \ + 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \ + 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \ + 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \ + 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \ + 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \ + 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \ + 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \ + 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \ + 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \ + 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \ + 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \ + 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \ + 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \ + 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \ + 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, \ + 0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, \ + 0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, \ + 0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, \ + 0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, \ + 0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, \ + 0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, \ + 0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, \ + 0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, \ + 0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, \ + 0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, \ + 0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, \ + 0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, \ + 0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, \ + 0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, \ + 0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, \ + 0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02, \ + 0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A, \ + 0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A, \ + 0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6, \ + 0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8, \ + 0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C, \ + 0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A, \ + 0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71, \ + 0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F, \ + 0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77, \ + 0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10, \ + 0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8, \ + 0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3, \ + 0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E, \ + 0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3, \ + 0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4, \ + 0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1, \ + 0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92, \ + 0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6, \ + 0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82, \ + 0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE, \ + 0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C, \ + 0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E, \ + 0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46, \ + 0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A, \ + 0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17, \ + 0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03, \ + 0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04, \ + 0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6, \ + 0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69, \ + 0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1, \ + 0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4, \ + 0xA4, 0x0E, 0x32, 0x9C, 0xD0, 0xE4, 0x0E, 0x65, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } + +#define MBEDTLS_DHM_RFC7919_FFDHE6144_G_BIN { 0x02 } + +#define MBEDTLS_DHM_RFC7919_FFDHE8192_P_BIN { \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \ + 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \ + 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \ + 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \ + 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \ + 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \ + 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \ + 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \ + 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \ + 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \ + 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \ + 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \ + 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \ + 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \ + 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \ + 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \ + 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \ + 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \ + 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \ + 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \ + 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \ + 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \ + 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \ + 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \ + 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \ + 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \ + 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \ + 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \ + 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \ + 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \ + 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \ + 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \ + 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \ + 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \ + 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \ + 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \ + 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \ + 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \ + 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \ + 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \ + 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \ + 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \ + 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \ + 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \ + 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \ + 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, \ + 0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, \ + 0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, \ + 0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, \ + 0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, \ + 0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, \ + 0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, \ + 0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, \ + 0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, \ + 0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, \ + 0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, \ + 0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, \ + 0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, \ + 0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, \ + 0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, \ + 0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, \ + 0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02, \ + 0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A, \ + 0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A, \ + 0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6, \ + 0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8, \ + 0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C, \ + 0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A, \ + 0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71, \ + 0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F, \ + 0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77, \ + 0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10, \ + 0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8, \ + 0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3, \ + 0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E, \ + 0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3, \ + 0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4, \ + 0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1, \ + 0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92, \ + 0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6, \ + 0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82, \ + 0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE, \ + 0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C, \ + 0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E, \ + 0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46, \ + 0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A, \ + 0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17, \ + 0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03, \ + 0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04, \ + 0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6, \ + 0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69, \ + 0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1, \ + 0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4, \ + 0xA4, 0x0E, 0x32, 0x9C, 0xCF, 0xF4, 0x6A, 0xAA, \ + 0x36, 0xAD, 0x00, 0x4C, 0xF6, 0x00, 0xC8, 0x38, \ + 0x1E, 0x42, 0x5A, 0x31, 0xD9, 0x51, 0xAE, 0x64, \ + 0xFD, 0xB2, 0x3F, 0xCE, 0xC9, 0x50, 0x9D, 0x43, \ + 0x68, 0x7F, 0xEB, 0x69, 0xED, 0xD1, 0xCC, 0x5E, \ + 0x0B, 0x8C, 0xC3, 0xBD, 0xF6, 0x4B, 0x10, 0xEF, \ + 0x86, 0xB6, 0x31, 0x42, 0xA3, 0xAB, 0x88, 0x29, \ + 0x55, 0x5B, 0x2F, 0x74, 0x7C, 0x93, 0x26, 0x65, \ + 0xCB, 0x2C, 0x0F, 0x1C, 0xC0, 0x1B, 0xD7, 0x02, \ + 0x29, 0x38, 0x88, 0x39, 0xD2, 0xAF, 0x05, 0xE4, \ + 0x54, 0x50, 0x4A, 0xC7, 0x8B, 0x75, 0x82, 0x82, \ + 0x28, 0x46, 0xC0, 0xBA, 0x35, 0xC3, 0x5F, 0x5C, \ + 0x59, 0x16, 0x0C, 0xC0, 0x46, 0xFD, 0x82, 0x51, \ + 0x54, 0x1F, 0xC6, 0x8C, 0x9C, 0x86, 0xB0, 0x22, \ + 0xBB, 0x70, 0x99, 0x87, 0x6A, 0x46, 0x0E, 0x74, \ + 0x51, 0xA8, 0xA9, 0x31, 0x09, 0x70, 0x3F, 0xEE, \ + 0x1C, 0x21, 0x7E, 0x6C, 0x38, 0x26, 0xE5, 0x2C, \ + 0x51, 0xAA, 0x69, 0x1E, 0x0E, 0x42, 0x3C, 0xFC, \ + 0x99, 0xE9, 0xE3, 0x16, 0x50, 0xC1, 0x21, 0x7B, \ + 0x62, 0x48, 0x16, 0xCD, 0xAD, 0x9A, 0x95, 0xF9, \ + 0xD5, 0xB8, 0x01, 0x94, 0x88, 0xD9, 0xC0, 0xA0, \ + 0xA1, 0xFE, 0x30, 0x75, 0xA5, 0x77, 0xE2, 0x31, \ + 0x83, 0xF8, 0x1D, 0x4A, 0x3F, 0x2F, 0xA4, 0x57, \ + 0x1E, 0xFC, 0x8C, 0xE0, 0xBA, 0x8A, 0x4F, 0xE8, \ + 0xB6, 0x85, 0x5D, 0xFE, 0x72, 0xB0, 0xA6, 0x6E, \ + 0xDE, 0xD2, 0xFB, 0xAB, 0xFB, 0xE5, 0x8A, 0x30, \ + 0xFA, 0xFA, 0xBE, 0x1C, 0x5D, 0x71, 0xA8, 0x7E, \ + 0x2F, 0x74, 0x1E, 0xF8, 0xC1, 0xFE, 0x86, 0xFE, \ + 0xA6, 0xBB, 0xFD, 0xE5, 0x30, 0x67, 0x7F, 0x0D, \ + 0x97, 0xD1, 0x1D, 0x49, 0xF7, 0xA8, 0x44, 0x3D, \ + 0x08, 0x22, 0xE5, 0x06, 0xA9, 0xF4, 0x61, 0x4E, \ + 0x01, 0x1E, 0x2A, 0x94, 0x83, 0x8F, 0xF8, 0x8C, \ + 0xD6, 0x8C, 0x8B, 0xB7, 0xC5, 0xC6, 0x42, 0x4C, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } + +#define MBEDTLS_DHM_RFC7919_FFDHE8192_G_BIN { 0x02 } + +#endif /* dhm.h */ diff --git a/third_party/mbedtls/include/mbedtls/ecdh.h b/third_party/mbedtls/include/mbedtls/ecdh.h new file mode 100644 index 0000000..05855cd --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/ecdh.h @@ -0,0 +1,446 @@ +/** + * \file ecdh.h + * + * \brief This file contains ECDH definitions and functions. + * + * The Elliptic Curve Diffie-Hellman (ECDH) protocol is an anonymous + * key agreement protocol allowing two parties to establish a shared + * secret over an insecure channel. Each party must have an + * elliptic-curve public–private key pair. + * + * For more information, see NIST SP 800-56A Rev. 2: Recommendation for + * Pair-Wise Key Establishment Schemes Using Discrete Logarithm + * Cryptography. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_ECDH_H +#define MBEDTLS_ECDH_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/ecp.h" + +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) +#undef MBEDTLS_ECDH_LEGACY_CONTEXT +#include "everest/everest.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Defines the source of the imported EC key. + */ +typedef enum +{ + MBEDTLS_ECDH_OURS, /**< Our key. */ + MBEDTLS_ECDH_THEIRS, /**< The key of the peer. */ +} mbedtls_ecdh_side; + +#if !defined(MBEDTLS_ECDH_LEGACY_CONTEXT) +/** + * Defines the ECDH implementation used. + * + * Later versions of the library may add new variants, therefore users should + * not make any assumptions about them. + */ +typedef enum +{ + MBEDTLS_ECDH_VARIANT_NONE = 0, /*!< Implementation not defined. */ + MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0,/*!< The default Mbed TLS implementation */ +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) + MBEDTLS_ECDH_VARIANT_EVEREST /*!< Everest implementation */ +#endif +} mbedtls_ecdh_variant; + +/** + * The context used by the default ECDH implementation. + * + * Later versions might change the structure of this context, therefore users + * should not make any assumptions about the structure of + * mbedtls_ecdh_context_mbed. + */ +typedef struct mbedtls_ecdh_context_mbed +{ + mbedtls_ecp_group grp; /*!< The elliptic curve used. */ + mbedtls_mpi d; /*!< The private key. */ + mbedtls_ecp_point Q; /*!< The public key. */ + mbedtls_ecp_point Qp; /*!< The value of the public key of the peer. */ + mbedtls_mpi z; /*!< The shared secret. */ +#if defined(MBEDTLS_ECP_RESTARTABLE) + mbedtls_ecp_restart_ctx rs; /*!< The restart context for EC computations. */ +#endif +} mbedtls_ecdh_context_mbed; +#endif + +/** + * + * \warning Performing multiple operations concurrently on the same + * ECDSA context is not supported; objects of this type + * should not be shared between multiple threads. + * \brief The ECDH context structure. + */ +typedef struct mbedtls_ecdh_context +{ +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + mbedtls_ecp_group grp; /*!< The elliptic curve used. */ + mbedtls_mpi d; /*!< The private key. */ + mbedtls_ecp_point Q; /*!< The public key. */ + mbedtls_ecp_point Qp; /*!< The value of the public key of the peer. */ + mbedtls_mpi z; /*!< The shared secret. */ + int point_format; /*!< The format of point export in TLS messages. */ + mbedtls_ecp_point Vi; /*!< The blinding value. */ + mbedtls_ecp_point Vf; /*!< The unblinding value. */ + mbedtls_mpi _d; /*!< The previous \p d. */ +#if defined(MBEDTLS_ECP_RESTARTABLE) + int restart_enabled; /*!< The flag for restartable mode. */ + mbedtls_ecp_restart_ctx rs; /*!< The restart context for EC computations. */ +#endif /* MBEDTLS_ECP_RESTARTABLE */ +#else + uint8_t point_format; /*!< The format of point export in TLS messages + as defined in RFC 4492. */ + mbedtls_ecp_group_id grp_id;/*!< The elliptic curve used. */ + mbedtls_ecdh_variant var; /*!< The ECDH implementation/structure used. */ + union + { + mbedtls_ecdh_context_mbed mbed_ecdh; +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) + mbedtls_ecdh_context_everest everest_ecdh; +#endif + } ctx; /*!< Implementation-specific context. The + context in use is specified by the \c var + field. */ +#if defined(MBEDTLS_ECP_RESTARTABLE) + uint8_t restart_enabled; /*!< The flag for restartable mode. Functions of + an alternative implementation not supporting + restartable mode must return + MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED error + if this flag is set. */ +#endif /* MBEDTLS_ECP_RESTARTABLE */ +#endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */ +} +mbedtls_ecdh_context; + +/** + * \brief Check whether a given group can be used for ECDH. + * + * \param gid The ECP group ID to check. + * + * \return \c 1 if the group can be used, \c 0 otherwise + */ +int mbedtls_ecdh_can_do( mbedtls_ecp_group_id gid ); + +/** + * \brief This function generates an ECDH keypair on an elliptic + * curve. + * + * This function performs the first of two core computations + * implemented during the ECDH key exchange. The second core + * computation is performed by mbedtls_ecdh_compute_shared(). + * + * \see ecp.h + * + * \param grp The ECP group to use. This must be initialized and have + * domain parameters loaded, for example through + * mbedtls_ecp_load() or mbedtls_ecp_tls_read_group(). + * \param d The destination MPI (private key). + * This must be initialized. + * \param Q The destination point (public key). + * This must be initialized. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL in case \p f_rng doesn't need a context argument. + * + * \return \c 0 on success. + * \return Another \c MBEDTLS_ERR_ECP_XXX or + * \c MBEDTLS_MPI_XXX error code on failure. + */ +int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief This function computes the shared secret. + * + * This function performs the second of two core computations + * implemented during the ECDH key exchange. The first core + * computation is performed by mbedtls_ecdh_gen_public(). + * + * \see ecp.h + * + * \note If \p f_rng is not NULL, it is used to implement + * countermeasures against side-channel attacks. + * For more information, see mbedtls_ecp_mul(). + * + * \param grp The ECP group to use. This must be initialized and have + * domain parameters loaded, for example through + * mbedtls_ecp_load() or mbedtls_ecp_tls_read_group(). + * \param z The destination MPI (shared secret). + * This must be initialized. + * \param Q The public key from another party. + * This must be initialized. + * \param d Our secret exponent (private key). + * This must be initialized. + * \param f_rng The RNG function. This may be \c NULL if randomization + * of intermediate results during the ECP computations is + * not needed (discouraged). See the documentation of + * mbedtls_ecp_mul() for more. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng is \c NULL or doesn't need a + * context argument. + * + * \return \c 0 on success. + * \return Another \c MBEDTLS_ERR_ECP_XXX or + * \c MBEDTLS_MPI_XXX error code on failure. + */ +int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z, + const mbedtls_ecp_point *Q, const mbedtls_mpi *d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief This function initializes an ECDH context. + * + * \param ctx The ECDH context to initialize. This must not be \c NULL. + */ +void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx ); + +/** + * \brief This function sets up the ECDH context with the information + * given. + * + * This function should be called after mbedtls_ecdh_init() but + * before mbedtls_ecdh_make_params(). There is no need to call + * this function before mbedtls_ecdh_read_params(). + * + * This is the first function used by a TLS server for ECDHE + * ciphersuites. + * + * \param ctx The ECDH context to set up. This must be initialized. + * \param grp_id The group id of the group to set up the context for. + * + * \return \c 0 on success. + */ +int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx, + mbedtls_ecp_group_id grp_id ); + +/** + * \brief This function frees a context. + * + * \param ctx The context to free. This may be \c NULL, in which + * case this function does nothing. If it is not \c NULL, + * it must point to an initialized ECDH context. + */ +void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx ); + +/** + * \brief This function generates an EC key pair and exports its + * in the format used in a TLS ServerKeyExchange handshake + * message. + * + * This is the second function used by a TLS server for ECDHE + * ciphersuites. (It is called after mbedtls_ecdh_setup().) + * + * \see ecp.h + * + * \param ctx The ECDH context to use. This must be initialized + * and bound to a group, for example via mbedtls_ecdh_setup(). + * \param olen The address at which to store the number of Bytes written. + * \param buf The destination buffer. This must be a writable buffer of + * length \p blen Bytes. + * \param blen The length of the destination buffer \p buf in Bytes. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL in case \p f_rng doesn't need a context argument. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. + */ +int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief This function parses the ECDHE parameters in a + * TLS ServerKeyExchange handshake message. + * + * \note In a TLS handshake, this is the how the client + * sets up its ECDHE context from the server's public + * ECDHE key material. + * + * \see ecp.h + * + * \param ctx The ECDHE context to use. This must be initialized. + * \param buf On input, \c *buf must be the start of the input buffer. + * On output, \c *buf is updated to point to the end of the + * data that has been read. On success, this is the first byte + * past the end of the ServerKeyExchange parameters. + * On error, this is the point at which an error has been + * detected, which is usually not useful except to debug + * failures. + * \param end The end of the input buffer. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX error code on failure. + * + */ +int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx, + const unsigned char **buf, + const unsigned char *end ); + +/** + * \brief This function sets up an ECDH context from an EC key. + * + * It is used by clients and servers in place of the + * ServerKeyEchange for static ECDH, and imports ECDH + * parameters from the EC key information of a certificate. + * + * \see ecp.h + * + * \param ctx The ECDH context to set up. This must be initialized. + * \param key The EC key to use. This must be initialized. + * \param side Defines the source of the key. Possible values are: + * - #MBEDTLS_ECDH_OURS: The key is ours. + * - #MBEDTLS_ECDH_THEIRS: The key is that of the peer. + * + * \return \c 0 on success. + * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. + * + */ +int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, + const mbedtls_ecp_keypair *key, + mbedtls_ecdh_side side ); + +/** + * \brief This function generates a public key and exports it + * as a TLS ClientKeyExchange payload. + * + * This is the second function used by a TLS client for ECDH(E) + * ciphersuites. + * + * \see ecp.h + * + * \param ctx The ECDH context to use. This must be initialized + * and bound to a group, the latter usually by + * mbedtls_ecdh_read_params(). + * \param olen The address at which to store the number of Bytes written. + * This must not be \c NULL. + * \param buf The destination buffer. This must be a writable buffer + * of length \p blen Bytes. + * \param blen The size of the destination buffer \p buf in Bytes. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL in case \p f_rng doesn't need a context argument. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. + */ +int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief This function parses and processes the ECDHE payload of a + * TLS ClientKeyExchange message. + * + * This is the third function used by a TLS server for ECDH(E) + * ciphersuites. (It is called after mbedtls_ecdh_setup() and + * mbedtls_ecdh_make_params().) + * + * \see ecp.h + * + * \param ctx The ECDH context to use. This must be initialized + * and bound to a group, for example via mbedtls_ecdh_setup(). + * \param buf The pointer to the ClientKeyExchange payload. This must + * be a readable buffer of length \p blen Bytes. + * \param blen The length of the input buffer \p buf in Bytes. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX error code on failure. + */ +int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx, + const unsigned char *buf, size_t blen ); + +/** + * \brief This function derives and exports the shared secret. + * + * This is the last function used by both TLS client + * and servers. + * + * \note If \p f_rng is not NULL, it is used to implement + * countermeasures against side-channel attacks. + * For more information, see mbedtls_ecp_mul(). + * + * \see ecp.h + + * \param ctx The ECDH context to use. This must be initialized + * and have its own private key generated and the peer's + * public key imported. + * \param olen The address at which to store the total number of + * Bytes written on success. This must not be \c NULL. + * \param buf The buffer to write the generated shared key to. This + * must be a writable buffer of size \p blen Bytes. + * \param blen The length of the destination buffer \p buf in Bytes. + * \param f_rng The RNG function, for blinding purposes. This may + * b \c NULL if blinding isn't needed. + * \param p_rng The RNG context. This may be \c NULL if \p f_rng + * doesn't need a context argument. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. + */ +int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +#if defined(MBEDTLS_ECP_RESTARTABLE) +/** + * \brief This function enables restartable EC computations for this + * context. (Default: disabled.) + * + * \see \c mbedtls_ecp_set_max_ops() + * + * \note It is not possible to safely disable restartable + * computations once enabled, except by free-ing the context, + * which cancels possible in-progress operations. + * + * \param ctx The ECDH context to use. This must be initialized. + */ +void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx ); +#endif /* MBEDTLS_ECP_RESTARTABLE */ + +#ifdef __cplusplus +} +#endif + +#endif /* ecdh.h */ diff --git a/third_party/mbedtls/include/mbedtls/ecdsa.h b/third_party/mbedtls/include/mbedtls/ecdsa.h new file mode 100644 index 0000000..264a638 --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/ecdsa.h @@ -0,0 +1,626 @@ +/** + * \file ecdsa.h + * + * \brief This file contains ECDSA definitions and functions. + * + * The Elliptic Curve Digital Signature Algorithm (ECDSA) is defined in + * Standards for Efficient Cryptography Group (SECG): + * SEC1 Elliptic Curve Cryptography. + * The use of ECDSA for TLS is defined in RFC-4492: Elliptic Curve + * Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS). + * + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_ECDSA_H +#define MBEDTLS_ECDSA_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/ecp.h" +#include "mbedtls/md.h" + +/** + * \brief Maximum ECDSA signature size for a given curve bit size + * + * \param bits Curve size in bits + * \return Maximum signature size in bytes + * + * \note This macro returns a compile-time constant if its argument + * is one. It may evaluate its argument multiple times. + */ +/* + * Ecdsa-Sig-Value ::= SEQUENCE { + * r INTEGER, + * s INTEGER + * } + * + * For each of r and s, the value (V) may include an extra initial "0" bit. + */ +#define MBEDTLS_ECDSA_MAX_SIG_LEN( bits ) \ + ( /*T,L of SEQUENCE*/ ( ( bits ) >= 61 * 8 ? 3 : 2 ) + \ + /*T,L of r,s*/ 2 * ( ( ( bits ) >= 127 * 8 ? 3 : 2 ) + \ + /*V of r,s*/ ( ( bits ) + 8 ) / 8 ) ) + +/** The maximal size of an ECDSA signature in Bytes. */ +#define MBEDTLS_ECDSA_MAX_LEN MBEDTLS_ECDSA_MAX_SIG_LEN( MBEDTLS_ECP_MAX_BITS ) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The ECDSA context structure. + * + * \warning Performing multiple operations concurrently on the same + * ECDSA context is not supported; objects of this type + * should not be shared between multiple threads. + */ +typedef mbedtls_ecp_keypair mbedtls_ecdsa_context; + +#if defined(MBEDTLS_ECP_RESTARTABLE) + +/** + * \brief Internal restart context for ecdsa_verify() + * + * \note Opaque struct, defined in ecdsa.c + */ +typedef struct mbedtls_ecdsa_restart_ver mbedtls_ecdsa_restart_ver_ctx; + +/** + * \brief Internal restart context for ecdsa_sign() + * + * \note Opaque struct, defined in ecdsa.c + */ +typedef struct mbedtls_ecdsa_restart_sig mbedtls_ecdsa_restart_sig_ctx; + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) +/** + * \brief Internal restart context for ecdsa_sign_det() + * + * \note Opaque struct, defined in ecdsa.c + */ +typedef struct mbedtls_ecdsa_restart_det mbedtls_ecdsa_restart_det_ctx; +#endif + +/** + * \brief General context for resuming ECDSA operations + */ +typedef struct +{ + mbedtls_ecp_restart_ctx ecp; /*!< base context for ECP restart and + shared administrative info */ + mbedtls_ecdsa_restart_ver_ctx *ver; /*!< ecdsa_verify() sub-context */ + mbedtls_ecdsa_restart_sig_ctx *sig; /*!< ecdsa_sign() sub-context */ +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) + mbedtls_ecdsa_restart_det_ctx *det; /*!< ecdsa_sign_det() sub-context */ +#endif +} mbedtls_ecdsa_restart_ctx; + +#else /* MBEDTLS_ECP_RESTARTABLE */ + +/* Now we can declare functions that take a pointer to that */ +typedef void mbedtls_ecdsa_restart_ctx; + +#endif /* MBEDTLS_ECP_RESTARTABLE */ + +/** + * \brief This function checks whether a given group can be used + * for ECDSA. + * + * \param gid The ECP group ID to check. + * + * \return \c 1 if the group can be used, \c 0 otherwise + */ +int mbedtls_ecdsa_can_do( mbedtls_ecp_group_id gid ); + +/** + * \brief This function computes the ECDSA signature of a + * previously-hashed message. + * + * \note The deterministic version implemented in + * mbedtls_ecdsa_sign_det() is usually preferred. + * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated + * as defined in Standards for Efficient Cryptography Group + * (SECG): SEC1 Elliptic Curve Cryptography, section + * 4.1.3, step 5. + * + * \see ecp.h + * + * \param grp The context for the elliptic curve to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param r The MPI context in which to store the first part + * the signature. This must be initialized. + * \param s The MPI context in which to store the second part + * the signature. This must be initialized. + * \param d The private signing key. This must be initialized. + * \param buf The content to be signed. This is usually the hash of + * the original data to be signed. This must be a readable + * buffer of length \p blen Bytes. It may be \c NULL if + * \p blen is zero. + * \param blen The length of \p buf in Bytes. + * \param f_rng The RNG function. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context parameter. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX + * or \c MBEDTLS_MPI_XXX error code on failure. + */ +int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, + const mbedtls_mpi *d, const unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) +#if ! defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif +/** + * \brief This function computes the ECDSA signature of a + * previously-hashed message, deterministic version. + * + * For more information, see RFC-6979: Deterministic + * Usage of the Digital Signature Algorithm (DSA) and Elliptic + * Curve Digital Signature Algorithm (ECDSA). + * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * defined in Standards for Efficient Cryptography Group + * (SECG): SEC1 Elliptic Curve Cryptography, section + * 4.1.3, step 5. + * + * \warning Since the output of the internal RNG is always the same for + * the same key and message, this limits the efficiency of + * blinding and leaks information through side channels. For + * secure behavior use mbedtls_ecdsa_sign_det_ext() instead. + * + * (Optimally the blinding is a random value that is different + * on every execution. In this case the blinding is still + * random from the attackers perspective, but is the same on + * each execution. This means that this blinding does not + * prevent attackers from recovering secrets by combining + * several measurement traces, but may prevent some attacks + * that exploit relationships between secret data.) + * + * \see ecp.h + * + * \param grp The context for the elliptic curve to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param r The MPI context in which to store the first part + * the signature. This must be initialized. + * \param s The MPI context in which to store the second part + * the signature. This must be initialized. + * \param d The private signing key. This must be initialized + * and setup, for example through mbedtls_ecp_gen_privkey(). + * \param buf The hashed content to be signed. This must be a readable + * buffer of length \p blen Bytes. It may be \c NULL if + * \p blen is zero. + * \param blen The length of \p buf in Bytes. + * \param md_alg The hash algorithm used to hash the original data. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX + * error code on failure. + */ +int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, + mbedtls_mpi *s, const mbedtls_mpi *d, + const unsigned char *buf, size_t blen, + mbedtls_md_type_t md_alg ) MBEDTLS_DEPRECATED; +#undef MBEDTLS_DEPRECATED +#endif /* MBEDTLS_DEPRECATED_REMOVED */ + +/** + * \brief This function computes the ECDSA signature of a + * previously-hashed message, deterministic version. + * + * For more information, see RFC-6979: Deterministic + * Usage of the Digital Signature Algorithm (DSA) and Elliptic + * Curve Digital Signature Algorithm (ECDSA). + * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * defined in Standards for Efficient Cryptography Group + * (SECG): SEC1 Elliptic Curve Cryptography, section + * 4.1.3, step 5. + * + * \see ecp.h + * + * \param grp The context for the elliptic curve to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param r The MPI context in which to store the first part + * the signature. This must be initialized. + * \param s The MPI context in which to store the second part + * the signature. This must be initialized. + * \param d The private signing key. This must be initialized + * and setup, for example through mbedtls_ecp_gen_privkey(). + * \param buf The hashed content to be signed. This must be a readable + * buffer of length \p blen Bytes. It may be \c NULL if + * \p blen is zero. + * \param blen The length of \p buf in Bytes. + * \param md_alg The hash algorithm used to hash the original data. + * \param f_rng_blind The RNG function used for blinding. This must not be + * \c NULL. + * \param p_rng_blind The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context parameter. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX + * error code on failure. + */ +int mbedtls_ecdsa_sign_det_ext( mbedtls_ecp_group *grp, mbedtls_mpi *r, + mbedtls_mpi *s, const mbedtls_mpi *d, + const unsigned char *buf, size_t blen, + mbedtls_md_type_t md_alg, + int (*f_rng_blind)(void *, unsigned char *, size_t), + void *p_rng_blind ); +#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ + +/** + * \brief This function verifies the ECDSA signature of a + * previously-hashed message. + * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * defined in Standards for Efficient Cryptography Group + * (SECG): SEC1 Elliptic Curve Cryptography, section + * 4.1.4, step 3. + * + * \see ecp.h + * + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param buf The hashed content that was signed. This must be a readable + * buffer of length \p blen Bytes. It may be \c NULL if + * \p blen is zero. + * \param blen The length of \p buf in Bytes. + * \param Q The public key to use for verification. This must be + * initialized and setup. + * \param r The first integer of the signature. + * This must be initialized. + * \param s The second integer of the signature. + * This must be initialized. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the signature + * is invalid. + * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX + * error code on failure for any other reason. + */ +int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp, + const unsigned char *buf, size_t blen, + const mbedtls_ecp_point *Q, const mbedtls_mpi *r, + const mbedtls_mpi *s); + +/** + * \brief This function computes the ECDSA signature and writes it + * to a buffer, serialized as defined in RFC-4492: + * Elliptic Curve Cryptography (ECC) Cipher Suites for + * Transport Layer Security (TLS). + * + * \warning It is not thread-safe to use the same context in + * multiple threads. + * + * \note The deterministic version is used if + * #MBEDTLS_ECDSA_DETERMINISTIC is defined. For more + * information, see RFC-6979: Deterministic Usage + * of the Digital Signature Algorithm (DSA) and Elliptic + * Curve Digital Signature Algorithm (ECDSA). + * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * defined in Standards for Efficient Cryptography Group + * (SECG): SEC1 Elliptic Curve Cryptography, section + * 4.1.3, step 5. + * + * \see ecp.h + * + * \param ctx The ECDSA context to use. This must be initialized + * and have a group and private key bound to it, for example + * via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair(). + * \param md_alg The message digest that was used to hash the message. + * \param hash The message hash to be signed. This must be a readable + * buffer of length \p blen Bytes. + * \param hlen The length of the hash \p hash in Bytes. + * \param sig The buffer to which to write the signature. This must be a + * writable buffer of length at least twice as large as the + * size of the curve used, plus 9. For example, 73 Bytes if + * a 256-bit curve is used. A buffer length of + * #MBEDTLS_ECDSA_MAX_LEN is always safe. + * \param slen The address at which to store the actual length of + * the signature written. Must not be \c NULL. + * \param f_rng The RNG function. This must not be \c NULL if + * #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise, + * it is used only for blinding and may be set to \c NULL, but + * doing so is DEPRECATED. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng is \c NULL or doesn't use a context. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or + * \c MBEDTLS_ERR_ASN1_XXX error code on failure. + */ +int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, + mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t *slen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief This function computes the ECDSA signature and writes it + * to a buffer, in a restartable way. + * + * \see \c mbedtls_ecdsa_write_signature() + * + * \note This function is like \c mbedtls_ecdsa_write_signature() + * but it can return early and restart according to the limit + * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. + * + * \param ctx The ECDSA context to use. This must be initialized + * and have a group and private key bound to it, for example + * via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair(). + * \param md_alg The message digest that was used to hash the message. + * \param hash The message hash to be signed. This must be a readable + * buffer of length \p blen Bytes. + * \param hlen The length of the hash \p hash in Bytes. + * \param sig The buffer to which to write the signature. This must be a + * writable buffer of length at least twice as large as the + * size of the curve used, plus 9. For example, 73 Bytes if + * a 256-bit curve is used. A buffer length of + * #MBEDTLS_ECDSA_MAX_LEN is always safe. + * \param slen The address at which to store the actual length of + * the signature written. Must not be \c NULL. + * \param f_rng The RNG function. This must not be \c NULL if + * #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise, + * it is unused and may be set to \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng is \c NULL or doesn't use a context. + * \param rs_ctx The restart context to use. This may be \c NULL to disable + * restarting. If it is not \c NULL, it must point to an + * initialized restart context. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return Another \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or + * \c MBEDTLS_ERR_ASN1_XXX error code on failure. + */ +int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx, + mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t *slen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_ecdsa_restart_ctx *rs_ctx ); + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) +#if ! defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif +/** + * \brief This function computes an ECDSA signature and writes + * it to a buffer, serialized as defined in RFC-4492: + * Elliptic Curve Cryptography (ECC) Cipher Suites for + * Transport Layer Security (TLS). + * + * The deterministic version is defined in RFC-6979: + * Deterministic Usage of the Digital Signature Algorithm (DSA) + * and Elliptic Curve Digital Signature Algorithm (ECDSA). + * + * \warning It is not thread-safe to use the same context in + * multiple threads. + * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * defined in Standards for Efficient Cryptography Group + * (SECG): SEC1 Elliptic Curve Cryptography, section + * 4.1.3, step 5. + * + * \see ecp.h + * + * \deprecated Superseded by mbedtls_ecdsa_write_signature() in + * Mbed TLS version 2.0 and later. + * + * \param ctx The ECDSA context to use. This must be initialized + * and have a group and private key bound to it, for example + * via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair(). + * \param hash The message hash to be signed. This must be a readable + * buffer of length \p blen Bytes. + * \param hlen The length of the hash \p hash in Bytes. + * \param sig The buffer to which to write the signature. This must be a + * writable buffer of length at least twice as large as the + * size of the curve used, plus 9. For example, 73 Bytes if + * a 256-bit curve is used. A buffer length of + * #MBEDTLS_ECDSA_MAX_LEN is always safe. + * \param slen The address at which to store the actual length of + * the signature written. Must not be \c NULL. + * \param md_alg The message digest that was used to hash the message. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or + * \c MBEDTLS_ERR_ASN1_XXX error code on failure. + */ +int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t *slen, + mbedtls_md_type_t md_alg ) MBEDTLS_DEPRECATED; +#undef MBEDTLS_DEPRECATED +#endif /* MBEDTLS_DEPRECATED_REMOVED */ +#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ + +/** + * \brief This function reads and verifies an ECDSA signature. + * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * defined in Standards for Efficient Cryptography Group + * (SECG): SEC1 Elliptic Curve Cryptography, section + * 4.1.4, step 3. + * + * \see ecp.h + * + * \param ctx The ECDSA context to use. This must be initialized + * and have a group and public key bound to it. + * \param hash The message hash that was signed. This must be a readable + * buffer of length \p size Bytes. + * \param hlen The size of the hash \p hash. + * \param sig The signature to read and verify. This must be a readable + * buffer of length \p slen Bytes. + * \param slen The size of \p sig in Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid. + * \return #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid + * signature in \p sig, but its length is less than \p siglen. + * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX + * error code on failure for any other reason. + */ +int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + const unsigned char *sig, size_t slen ); + +/** + * \brief This function reads and verifies an ECDSA signature, + * in a restartable way. + * + * \see \c mbedtls_ecdsa_read_signature() + * + * \note This function is like \c mbedtls_ecdsa_read_signature() + * but it can return early and restart according to the limit + * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. + * + * \param ctx The ECDSA context to use. This must be initialized + * and have a group and public key bound to it. + * \param hash The message hash that was signed. This must be a readable + * buffer of length \p size Bytes. + * \param hlen The size of the hash \p hash. + * \param sig The signature to read and verify. This must be a readable + * buffer of length \p slen Bytes. + * \param slen The size of \p sig in Bytes. + * \param rs_ctx The restart context to use. This may be \c NULL to disable + * restarting. If it is not \c NULL, it must point to an + * initialized restart context. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid. + * \return #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid + * signature in \p sig, but its length is less than \p siglen. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return Another \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX + * error code on failure for any other reason. + */ +int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + const unsigned char *sig, size_t slen, + mbedtls_ecdsa_restart_ctx *rs_ctx ); + +/** + * \brief This function generates an ECDSA keypair on the given curve. + * + * \see ecp.h + * + * \param ctx The ECDSA context to store the keypair in. + * This must be initialized. + * \param gid The elliptic curve to use. One of the various + * \c MBEDTLS_ECP_DP_XXX macros depending on configuration. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context argument. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX code on failure. + */ +int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + +/** + * \brief This function sets up an ECDSA context from an EC key pair. + * + * \see ecp.h + * + * \param ctx The ECDSA context to setup. This must be initialized. + * \param key The EC key to use. This must be initialized and hold + * a private-public key pair or a public key. In the former + * case, the ECDSA context may be used for signature creation + * and verification after this call. In the latter case, it + * may be used for signature verification. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX code on failure. + */ +int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, + const mbedtls_ecp_keypair *key ); + +/** + * \brief This function initializes an ECDSA context. + * + * \param ctx The ECDSA context to initialize. + * This must not be \c NULL. + */ +void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx ); + +/** + * \brief This function frees an ECDSA context. + * + * \param ctx The ECDSA context to free. This may be \c NULL, + * in which case this function does nothing. If it + * is not \c NULL, it must be initialized. + */ +void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx ); + +#if defined(MBEDTLS_ECP_RESTARTABLE) +/** + * \brief Initialize a restart context. + * + * \param ctx The restart context to initialize. + * This must not be \c NULL. + */ +void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx ); + +/** + * \brief Free the components of a restart context. + * + * \param ctx The restart context to free. This may be \c NULL, + * in which case this function does nothing. If it + * is not \c NULL, it must be initialized. + */ +void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx ); +#endif /* MBEDTLS_ECP_RESTARTABLE */ + +#ifdef __cplusplus +} +#endif + +#endif /* ecdsa.h */ diff --git a/third_party/mbedtls/include/mbedtls/ecp.h b/third_party/mbedtls/include/mbedtls/ecp.h new file mode 100644 index 0000000..64a0bcc --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/ecp.h @@ -0,0 +1,1311 @@ +/** + * \file ecp.h + * + * \brief This file provides an API for Elliptic Curves over GF(P) (ECP). + * + * The use of ECP in cryptography and TLS is defined in + * Standards for Efficient Cryptography Group (SECG): SEC1 + * Elliptic Curve Cryptography and + * RFC-4492: Elliptic Curve Cryptography (ECC) Cipher Suites + * for Transport Layer Security (TLS). + * + * RFC-2409: The Internet Key Exchange (IKE) defines ECP + * group types. + * + */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_ECP_H +#define MBEDTLS_ECP_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/bignum.h" + +/* + * ECP error codes + */ +/** Bad input parameters to function. */ +#define MBEDTLS_ERR_ECP_BAD_INPUT_DATA -0x4F80 +/** The buffer is too small to write to. */ +#define MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL -0x4F00 +/** The requested feature is not available, for example, the requested curve is not supported. */ +#define MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE -0x4E80 +/** The signature is not valid. */ +#define MBEDTLS_ERR_ECP_VERIFY_FAILED -0x4E00 +/** Memory allocation failed. */ +#define MBEDTLS_ERR_ECP_ALLOC_FAILED -0x4D80 +/** Generation of random value, such as ephemeral key, failed. */ +#define MBEDTLS_ERR_ECP_RANDOM_FAILED -0x4D00 +/** Invalid private or public key. */ +#define MBEDTLS_ERR_ECP_INVALID_KEY -0x4C80 +/** The buffer contains a valid signature followed by more data. */ +#define MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH -0x4C00 + +/* MBEDTLS_ERR_ECP_HW_ACCEL_FAILED is deprecated and should not be used. */ +/** The ECP hardware accelerator failed. */ +#define MBEDTLS_ERR_ECP_HW_ACCEL_FAILED -0x4B80 + +/** Operation in progress, call again with the same parameters to continue. */ +#define MBEDTLS_ERR_ECP_IN_PROGRESS -0x4B00 + +/* Flags indicating whether to include code that is specific to certain + * types of curves. These flags are for internal library use only. */ +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) +#define MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED +#endif +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \ + defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) +#define MBEDTLS_ECP_MONTGOMERY_ENABLED +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Domain-parameter identifiers: curve, subgroup, and generator. + * + * \note Only curves over prime fields are supported. + * + * \warning This library does not support validation of arbitrary domain + * parameters. Therefore, only standardized domain parameters from trusted + * sources should be used. See mbedtls_ecp_group_load(). + */ +/* Note: when adding a new curve: + * - Add it at the end of this enum, otherwise you'll break the ABI by + * changing the numerical value for existing curves. + * - Increment MBEDTLS_ECP_DP_MAX below if needed. + * - Update the calculation of MBEDTLS_ECP_MAX_BITS_MIN below. + * - Add the corresponding MBEDTLS_ECP_DP_xxx_ENABLED macro definition to + * config.h. + * - List the curve as a dependency of MBEDTLS_ECP_C and + * MBEDTLS_ECDSA_C if supported in check_config.h. + * - Add the curve to the appropriate curve type macro + * MBEDTLS_ECP_yyy_ENABLED above. + * - Add the necessary definitions to ecp_curves.c. + * - Add the curve to the ecp_supported_curves array in ecp.c. + * - Add the curve to applicable profiles in x509_crt.c if applicable. + */ +typedef enum +{ + MBEDTLS_ECP_DP_NONE = 0, /*!< Curve not defined. */ + MBEDTLS_ECP_DP_SECP192R1, /*!< Domain parameters for the 192-bit curve defined by FIPS 186-4 and SEC1. */ + MBEDTLS_ECP_DP_SECP224R1, /*!< Domain parameters for the 224-bit curve defined by FIPS 186-4 and SEC1. */ + MBEDTLS_ECP_DP_SECP256R1, /*!< Domain parameters for the 256-bit curve defined by FIPS 186-4 and SEC1. */ + MBEDTLS_ECP_DP_SECP384R1, /*!< Domain parameters for the 384-bit curve defined by FIPS 186-4 and SEC1. */ + MBEDTLS_ECP_DP_SECP521R1, /*!< Domain parameters for the 521-bit curve defined by FIPS 186-4 and SEC1. */ + MBEDTLS_ECP_DP_BP256R1, /*!< Domain parameters for 256-bit Brainpool curve. */ + MBEDTLS_ECP_DP_BP384R1, /*!< Domain parameters for 384-bit Brainpool curve. */ + MBEDTLS_ECP_DP_BP512R1, /*!< Domain parameters for 512-bit Brainpool curve. */ + MBEDTLS_ECP_DP_CURVE25519, /*!< Domain parameters for Curve25519. */ + MBEDTLS_ECP_DP_SECP192K1, /*!< Domain parameters for 192-bit "Koblitz" curve. */ + MBEDTLS_ECP_DP_SECP224K1, /*!< Domain parameters for 224-bit "Koblitz" curve. */ + MBEDTLS_ECP_DP_SECP256K1, /*!< Domain parameters for 256-bit "Koblitz" curve. */ + MBEDTLS_ECP_DP_CURVE448, /*!< Domain parameters for Curve448. */ +} mbedtls_ecp_group_id; + +/** + * The number of supported curves, plus one for #MBEDTLS_ECP_DP_NONE. + * + * \note Montgomery curves are currently excluded. + */ +#define MBEDTLS_ECP_DP_MAX 12 + +/* + * Curve types + */ +typedef enum +{ + MBEDTLS_ECP_TYPE_NONE = 0, + MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */ + MBEDTLS_ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */ +} mbedtls_ecp_curve_type; + +/** + * Curve information, for use by other modules. + */ +typedef struct mbedtls_ecp_curve_info +{ + mbedtls_ecp_group_id grp_id; /*!< An internal identifier. */ + uint16_t tls_id; /*!< The TLS NamedCurve identifier. */ + uint16_t bit_size; /*!< The curve size in bits. */ + const char *name; /*!< A human-friendly name. */ +} mbedtls_ecp_curve_info; + +/** + * \brief The ECP point structure, in Jacobian coordinates. + * + * \note All functions expect and return points satisfying + * the following condition: Z == 0 or + * Z == 1. Other values of \p Z are + * used only by internal functions. + * The point is zero, or "at infinity", if Z == 0. + * Otherwise, \p X and \p Y are its standard (affine) + * coordinates. + */ +typedef struct mbedtls_ecp_point +{ + mbedtls_mpi X; /*!< The X coordinate of the ECP point. */ + mbedtls_mpi Y; /*!< The Y coordinate of the ECP point. */ + mbedtls_mpi Z; /*!< The Z coordinate of the ECP point. */ +} +mbedtls_ecp_point; + +/* Determine the minimum safe value of MBEDTLS_ECP_MAX_BITS. */ +#if !defined(MBEDTLS_ECP_C) +#define MBEDTLS_ECP_MAX_BITS_MIN 0 +/* Note: the curves must be listed in DECREASING size! */ +#elif defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) +#define MBEDTLS_ECP_MAX_BITS_MIN 521 +#elif defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) +#define MBEDTLS_ECP_MAX_BITS_MIN 512 +#elif defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) +#define MBEDTLS_ECP_MAX_BITS_MIN 448 +#elif defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) +#define MBEDTLS_ECP_MAX_BITS_MIN 384 +#elif defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) +#define MBEDTLS_ECP_MAX_BITS_MIN 384 +#elif defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) +#define MBEDTLS_ECP_MAX_BITS_MIN 256 +#elif defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) +#define MBEDTLS_ECP_MAX_BITS_MIN 256 +#elif defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) +#define MBEDTLS_ECP_MAX_BITS_MIN 256 +#elif defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) +#define MBEDTLS_ECP_MAX_BITS_MIN 255 +#elif defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) +#define MBEDTLS_ECP_MAX_BITS_MIN 225 // n is slightly above 2^224 +#elif defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) +#define MBEDTLS_ECP_MAX_BITS_MIN 224 +#elif defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) +#define MBEDTLS_ECP_MAX_BITS_MIN 192 +#elif defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) +#define MBEDTLS_ECP_MAX_BITS_MIN 192 +#else +#error "MBEDTLS_ECP_C enabled, but no curve?" +#endif + +#if !defined(MBEDTLS_ECP_ALT) +/* + * default mbed TLS elliptic curve arithmetic implementation + * + * (in case MBEDTLS_ECP_ALT is defined then the developer has to provide an + * alternative implementation for the whole module and it will replace this + * one.) + */ + +/** + * \brief The ECP group structure. + * + * We consider two types of curve equations: + *
  • Short Weierstrass: y^2 = x^3 + A x + B mod P + * (SEC1 + RFC-4492)
  • + *
  • Montgomery: y^2 = x^3 + A x^2 + x mod P (Curve25519, + * Curve448)
+ * In both cases, the generator (\p G) for a prime-order subgroup is fixed. + * + * For Short Weierstrass, this subgroup is the whole curve, and its + * cardinality is denoted by \p N. Our code requires that \p N is an + * odd prime as mbedtls_ecp_mul() requires an odd number, and + * mbedtls_ecdsa_sign() requires that it is prime for blinding purposes. + * + * For Montgomery curves, we do not store \p A, but (A + 2) / 4, + * which is the quantity used in the formulas. Additionally, \p nbits is + * not the size of \p N but the required size for private keys. + * + * If \p modp is NULL, reduction modulo \p P is done using a generic algorithm. + * Otherwise, \p modp must point to a function that takes an \p mbedtls_mpi in the + * range of 0..2^(2*pbits)-1, and transforms it in-place to an integer + * which is congruent mod \p P to the given MPI, and is close enough to \p pbits + * in size, so that it may be efficiently brought in the 0..P-1 range by a few + * additions or subtractions. Therefore, it is only an approximative modular + * reduction. It must return 0 on success and non-zero on failure. + * + * \note Alternative implementations must keep the group IDs distinct. If + * two group structures have the same ID, then they must be + * identical. + * + */ +typedef struct mbedtls_ecp_group +{ + mbedtls_ecp_group_id id; /*!< An internal group identifier. */ + mbedtls_mpi P; /*!< The prime modulus of the base field. */ + mbedtls_mpi A; /*!< For Short Weierstrass: \p A in the equation. For + Montgomery curves: (A + 2) / 4. */ + mbedtls_mpi B; /*!< For Short Weierstrass: \p B in the equation. + For Montgomery curves: unused. */ + mbedtls_ecp_point G; /*!< The generator of the subgroup used. */ + mbedtls_mpi N; /*!< The order of \p G. */ + size_t pbits; /*!< The number of bits in \p P.*/ + size_t nbits; /*!< For Short Weierstrass: The number of bits in \p P. + For Montgomery curves: the number of bits in the + private keys. */ + unsigned int h; /*!< \internal 1 if the constants are static. */ + int (*modp)(mbedtls_mpi *); /*!< The function for fast pseudo-reduction + mod \p P (see above).*/ + int (*t_pre)(mbedtls_ecp_point *, void *); /*!< Unused. */ + int (*t_post)(mbedtls_ecp_point *, void *); /*!< Unused. */ + void *t_data; /*!< Unused. */ + mbedtls_ecp_point *T; /*!< Pre-computed points for ecp_mul_comb(). */ + size_t T_size; /*!< The number of pre-computed points. */ +} +mbedtls_ecp_group; + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h, or define them using the compiler command line. + * \{ + */ + +#if defined(MBEDTLS_ECP_MAX_BITS) + +#if MBEDTLS_ECP_MAX_BITS < MBEDTLS_ECP_MAX_BITS_MIN +#error "MBEDTLS_ECP_MAX_BITS is smaller than the largest supported curve" +#endif + +#elif defined(MBEDTLS_ECP_C) +/** + * The maximum size of the groups, that is, of \c N and \c P. + */ +#define MBEDTLS_ECP_MAX_BITS MBEDTLS_ECP_MAX_BITS_MIN + +#else +/* MBEDTLS_ECP_MAX_BITS is not relevant without MBEDTLS_ECP_C, but set it + * to a nonzero value so that code that unconditionally allocates an array + * of a size based on it keeps working if built without ECC support. */ +#define MBEDTLS_ECP_MAX_BITS 1 +#endif + +#define MBEDTLS_ECP_MAX_BYTES ( ( MBEDTLS_ECP_MAX_BITS + 7 ) / 8 ) +#define MBEDTLS_ECP_MAX_PT_LEN ( 2 * MBEDTLS_ECP_MAX_BYTES + 1 ) + +#if !defined(MBEDTLS_ECP_WINDOW_SIZE) +/* + * Maximum "window" size used for point multiplication. + * Default: a point where higher memory usage yields diminishing performance + * returns. + * Minimum value: 2. Maximum value: 7. + * + * Result is an array of at most ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) ) + * points used for point multiplication. This value is directly tied to EC + * peak memory usage, so decreasing it by one should roughly cut memory usage + * by two (if large curves are in use). + * + * Reduction in size may reduce speed, but larger curves are impacted first. + * Sample performances (in ECDHE handshakes/s, with FIXED_POINT_OPTIM = 1): + * w-size: 6 5 4 3 2 + * 521 145 141 135 120 97 + * 384 214 209 198 177 146 + * 256 320 320 303 262 226 + * 224 475 475 453 398 342 + * 192 640 640 633 587 476 + */ +#define MBEDTLS_ECP_WINDOW_SIZE 4 /**< The maximum window size used. */ +#endif /* MBEDTLS_ECP_WINDOW_SIZE */ + +#if !defined(MBEDTLS_ECP_FIXED_POINT_OPTIM) +/* + * Trade memory for speed on fixed-point multiplication. + * + * This speeds up repeated multiplication of the generator (that is, the + * multiplication in ECDSA signatures, and half of the multiplications in + * ECDSA verification and ECDHE) by a factor roughly 3 to 4. + * + * The cost is increasing EC peak memory usage by a factor roughly 2. + * + * Change this value to 0 to reduce peak memory usage. + */ +#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up. */ +#endif /* MBEDTLS_ECP_FIXED_POINT_OPTIM */ + +/** \} name SECTION: Module settings */ + +#else /* MBEDTLS_ECP_ALT */ +#include "ecp_alt.h" +#endif /* MBEDTLS_ECP_ALT */ + +#if defined(MBEDTLS_ECP_RESTARTABLE) + +/** + * \brief Internal restart context for multiplication + * + * \note Opaque struct + */ +typedef struct mbedtls_ecp_restart_mul mbedtls_ecp_restart_mul_ctx; + +/** + * \brief Internal restart context for ecp_muladd() + * + * \note Opaque struct + */ +typedef struct mbedtls_ecp_restart_muladd mbedtls_ecp_restart_muladd_ctx; + +/** + * \brief General context for resuming ECC operations + */ +typedef struct +{ + unsigned ops_done; /*!< current ops count */ + unsigned depth; /*!< call depth (0 = top-level) */ + mbedtls_ecp_restart_mul_ctx *rsm; /*!< ecp_mul_comb() sub-context */ + mbedtls_ecp_restart_muladd_ctx *ma; /*!< ecp_muladd() sub-context */ +} mbedtls_ecp_restart_ctx; + +/* + * Operation counts for restartable functions + */ +#define MBEDTLS_ECP_OPS_CHK 3 /*!< basic ops count for ecp_check_pubkey() */ +#define MBEDTLS_ECP_OPS_DBL 8 /*!< basic ops count for ecp_double_jac() */ +#define MBEDTLS_ECP_OPS_ADD 11 /*!< basic ops count for see ecp_add_mixed() */ +#define MBEDTLS_ECP_OPS_INV 120 /*!< empirical equivalent for mpi_mod_inv() */ + +/** + * \brief Internal; for restartable functions in other modules. + * Check and update basic ops budget. + * + * \param grp Group structure + * \param rs_ctx Restart context + * \param ops Number of basic ops to do + * + * \return \c 0 if doing \p ops basic ops is still allowed, + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS otherwise. + */ +int mbedtls_ecp_check_budget( const mbedtls_ecp_group *grp, + mbedtls_ecp_restart_ctx *rs_ctx, + unsigned ops ); + +/* Utility macro for checking and updating ops budget */ +#define MBEDTLS_ECP_BUDGET( ops ) \ + MBEDTLS_MPI_CHK( mbedtls_ecp_check_budget( grp, rs_ctx, \ + (unsigned) (ops) ) ); + +#else /* MBEDTLS_ECP_RESTARTABLE */ + +#define MBEDTLS_ECP_BUDGET( ops ) /* no-op; for compatibility */ + +/* We want to declare restartable versions of existing functions anyway */ +typedef void mbedtls_ecp_restart_ctx; + +#endif /* MBEDTLS_ECP_RESTARTABLE */ + +/** + * \brief The ECP key-pair structure. + * + * A generic key-pair that may be used for ECDSA and fixed ECDH, for example. + * + * \note Members are deliberately in the same order as in the + * ::mbedtls_ecdsa_context structure. + */ +typedef struct mbedtls_ecp_keypair +{ + mbedtls_ecp_group grp; /*!< Elliptic curve and base point */ + mbedtls_mpi d; /*!< our secret value */ + mbedtls_ecp_point Q; /*!< our public value */ +} +mbedtls_ecp_keypair; + +/* + * Point formats, from RFC 4492's enum ECPointFormat + */ +#define MBEDTLS_ECP_PF_UNCOMPRESSED 0 /**< Uncompressed point format. */ +#define MBEDTLS_ECP_PF_COMPRESSED 1 /**< Compressed point format. */ + +/* + * Some other constants from RFC 4492 + */ +#define MBEDTLS_ECP_TLS_NAMED_CURVE 3 /**< The named_curve of ECCurveType. */ + +#if defined(MBEDTLS_ECP_RESTARTABLE) +/** + * \brief Set the maximum number of basic operations done in a row. + * + * If more operations are needed to complete a computation, + * #MBEDTLS_ERR_ECP_IN_PROGRESS will be returned by the + * function performing the computation. It is then the + * caller's responsibility to either call again with the same + * parameters until it returns 0 or an error code; or to free + * the restart context if the operation is to be aborted. + * + * It is strictly required that all input parameters and the + * restart context be the same on successive calls for the + * same operation, but output parameters need not be the + * same; they must not be used until the function finally + * returns 0. + * + * This only applies to functions whose documentation + * mentions they may return #MBEDTLS_ERR_ECP_IN_PROGRESS (or + * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS for functions in the + * SSL module). For functions that accept a "restart context" + * argument, passing NULL disables restart and makes the + * function equivalent to the function with the same name + * with \c _restartable removed. For functions in the ECDH + * module, restart is disabled unless the function accepts + * an "ECDH context" argument and + * mbedtls_ecdh_enable_restart() was previously called on + * that context. For function in the SSL module, restart is + * only enabled for specific sides and key exchanges + * (currently only for clients and ECDHE-ECDSA). + * + * \param max_ops Maximum number of basic operations done in a row. + * Default: 0 (unlimited). + * Lower (non-zero) values mean ECC functions will block for + * a lesser maximum amount of time. + * + * \note A "basic operation" is defined as a rough equivalent of a + * multiplication in GF(p) for the NIST P-256 curve. + * As an indication, with default settings, a scalar + * multiplication (full run of \c mbedtls_ecp_mul()) is: + * - about 3300 basic operations for P-256 + * - about 9400 basic operations for P-384 + * + * \note Very low values are not always respected: sometimes + * functions need to block for a minimum number of + * operations, and will do so even if max_ops is set to a + * lower value. That minimum depends on the curve size, and + * can be made lower by decreasing the value of + * \c MBEDTLS_ECP_WINDOW_SIZE. As an indication, here is the + * lowest effective value for various curves and values of + * that parameter (w for short): + * w=6 w=5 w=4 w=3 w=2 + * P-256 208 208 160 136 124 + * P-384 682 416 320 272 248 + * P-521 1364 832 640 544 496 + * + * \note This setting is currently ignored by Curve25519. + */ +void mbedtls_ecp_set_max_ops( unsigned max_ops ); + +/** + * \brief Check if restart is enabled (max_ops != 0) + * + * \return \c 0 if \c max_ops == 0 (restart disabled) + * \return \c 1 otherwise (restart enabled) + */ +int mbedtls_ecp_restart_is_enabled( void ); +#endif /* MBEDTLS_ECP_RESTARTABLE */ + +/* + * Get the type of a curve + */ +mbedtls_ecp_curve_type mbedtls_ecp_get_type( const mbedtls_ecp_group *grp ); + +/** + * \brief This function retrieves the information defined in + * mbedtls_ecp_curve_info() for all supported curves. + * + * \note This function returns information about all curves + * supported by the library. Some curves may not be + * supported for all algorithms. Call mbedtls_ecdh_can_do() + * or mbedtls_ecdsa_can_do() to check if a curve is + * supported for ECDH or ECDSA. + * + * \return A statically allocated array. The last entry is 0. + */ +const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list( void ); + +/** + * \brief This function retrieves the list of internal group + * identifiers of all supported curves in the order of + * preference. + * + * \note This function returns information about all curves + * supported by the library. Some curves may not be + * supported for all algorithms. Call mbedtls_ecdh_can_do() + * or mbedtls_ecdsa_can_do() to check if a curve is + * supported for ECDH or ECDSA. + * + * \return A statically allocated array, + * terminated with MBEDTLS_ECP_DP_NONE. + */ +const mbedtls_ecp_group_id *mbedtls_ecp_grp_id_list( void ); + +/** + * \brief This function retrieves curve information from an internal + * group identifier. + * + * \param grp_id An \c MBEDTLS_ECP_DP_XXX value. + * + * \return The associated curve information on success. + * \return NULL on failure. + */ +const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_grp_id( mbedtls_ecp_group_id grp_id ); + +/** + * \brief This function retrieves curve information from a TLS + * NamedCurve value. + * + * \param tls_id An \c MBEDTLS_ECP_DP_XXX value. + * + * \return The associated curve information on success. + * \return NULL on failure. + */ +const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_tls_id( uint16_t tls_id ); + +/** + * \brief This function retrieves curve information from a + * human-readable name. + * + * \param name The human-readable name. + * + * \return The associated curve information on success. + * \return NULL on failure. + */ +const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name( const char *name ); + +/** + * \brief This function initializes a point as zero. + * + * \param pt The point to initialize. + */ +void mbedtls_ecp_point_init( mbedtls_ecp_point *pt ); + +/** + * \brief This function initializes an ECP group context + * without loading any domain parameters. + * + * \note After this function is called, domain parameters + * for various ECP groups can be loaded through the + * mbedtls_ecp_group_load() or mbedtls_ecp_tls_read_group() + * functions. + */ +void mbedtls_ecp_group_init( mbedtls_ecp_group *grp ); + +/** + * \brief This function initializes a key pair as an invalid one. + * + * \param key The key pair to initialize. + */ +void mbedtls_ecp_keypair_init( mbedtls_ecp_keypair *key ); + +/** + * \brief This function frees the components of a point. + * + * \param pt The point to free. + */ +void mbedtls_ecp_point_free( mbedtls_ecp_point *pt ); + +/** + * \brief This function frees the components of an ECP group. + * + * \param grp The group to free. This may be \c NULL, in which + * case this function returns immediately. If it is not + * \c NULL, it must point to an initialized ECP group. + */ +void mbedtls_ecp_group_free( mbedtls_ecp_group *grp ); + +/** + * \brief This function frees the components of a key pair. + * + * \param key The key pair to free. This may be \c NULL, in which + * case this function returns immediately. If it is not + * \c NULL, it must point to an initialized ECP key pair. + */ +void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key ); + +#if defined(MBEDTLS_ECP_RESTARTABLE) +/** + * \brief Initialize a restart context. + * + * \param ctx The restart context to initialize. This must + * not be \c NULL. + */ +void mbedtls_ecp_restart_init( mbedtls_ecp_restart_ctx *ctx ); + +/** + * \brief Free the components of a restart context. + * + * \param ctx The restart context to free. This may be \c NULL, in which + * case this function returns immediately. If it is not + * \c NULL, it must point to an initialized restart context. + */ +void mbedtls_ecp_restart_free( mbedtls_ecp_restart_ctx *ctx ); +#endif /* MBEDTLS_ECP_RESTARTABLE */ + +/** + * \brief This function copies the contents of point \p Q into + * point \p P. + * + * \param P The destination point. This must be initialized. + * \param Q The source point. This must be initialized. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return Another negative error code for other kinds of failure. + */ +int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ); + +/** + * \brief This function copies the contents of group \p src into + * group \p dst. + * + * \param dst The destination group. This must be initialized. + * \param src The source group. This must be initialized. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, + const mbedtls_ecp_group *src ); + +/** + * \brief This function sets a point to the point at infinity. + * + * \param pt The point to set. This must be initialized. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt ); + +/** + * \brief This function checks if a point is the point at infinity. + * + * \param pt The point to test. This must be initialized. + * + * \return \c 1 if the point is zero. + * \return \c 0 if the point is non-zero. + * \return A negative error code on failure. + */ +int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt ); + +/** + * \brief This function compares two points. + * + * \note This assumes that the points are normalized. Otherwise, + * they may compare as "not equal" even if they are. + * + * \param P The first point to compare. This must be initialized. + * \param Q The second point to compare. This must be initialized. + * + * \return \c 0 if the points are equal. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the points are not equal. + */ +int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P, + const mbedtls_ecp_point *Q ); + +/** + * \brief This function imports a non-zero point from two ASCII + * strings. + * + * \param P The destination point. This must be initialized. + * \param radix The numeric base of the input. + * \param x The first affine coordinate, as a null-terminated string. + * \param y The second affine coordinate, as a null-terminated string. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_MPI_XXX error code on failure. + */ +int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix, + const char *x, const char *y ); + +/** + * \brief This function exports a point into unsigned binary data. + * + * \param grp The group to which the point should belong. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param P The point to export. This must be initialized. + * \param format The point format. This must be either + * #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED. + * (For groups without these formats, this parameter is + * ignored. But it still has to be either of the above + * values.) + * \param olen The address at which to store the length of + * the output in Bytes. This must not be \c NULL. + * \param buf The output buffer. This must be a writable buffer + * of length \p buflen Bytes. + * \param buflen The length of the output buffer \p buf in Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output buffer + * is too small to hold the point. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format + * or the export for the given group is not implemented. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, + const mbedtls_ecp_point *P, + int format, size_t *olen, + unsigned char *buf, size_t buflen ); + +/** + * \brief This function imports a point from unsigned binary data. + * + * \note This function does not check that the point actually + * belongs to the given group, see mbedtls_ecp_check_pubkey() + * for that. + * + * \param grp The group to which the point should belong. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param P The destination context to import the point to. + * This must be initialized. + * \param buf The input buffer. This must be a readable buffer + * of length \p ilen Bytes. + * \param ilen The length of the input buffer \p buf in Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the import for the + * given group is not implemented. + */ +int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, + mbedtls_ecp_point *P, + const unsigned char *buf, size_t ilen ); + +/** + * \brief This function imports a point from a TLS ECPoint record. + * + * \note On function return, \p *buf is updated to point immediately + * after the ECPoint record. + * + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param pt The destination point. + * \param buf The address of the pointer to the start of the input buffer. + * \param len The length of the buffer. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_MPI_XXX error code on initialization + * failure. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid. + */ +int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, + mbedtls_ecp_point *pt, + const unsigned char **buf, size_t len ); + +/** + * \brief This function exports a point as a TLS ECPoint record + * defined in RFC 4492, Section 5.4. + * + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param pt The point to be exported. This must be initialized. + * \param format The point format to use. This must be either + * #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED. + * \param olen The address at which to store the length in Bytes + * of the data written. + * \param buf The target buffer. This must be a writable buffer of + * length \p blen Bytes. + * \param blen The length of the target buffer \p buf in Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid. + * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the target buffer + * is too small to hold the exported point. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, + const mbedtls_ecp_point *pt, + int format, size_t *olen, + unsigned char *buf, size_t blen ); + +/** + * \brief This function sets up an ECP group context + * from a standardized set of domain parameters. + * + * \note The index should be a value of the NamedCurve enum, + * as defined in RFC-4492: Elliptic Curve Cryptography + * (ECC) Cipher Suites for Transport Layer Security (TLS), + * usually in the form of an \c MBEDTLS_ECP_DP_XXX macro. + * + * \param grp The group context to setup. This must be initialized. + * \param id The identifier of the domain parameter set to load. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p id doesn't + * correspond to a known group. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id ); + +/** + * \brief This function sets up an ECP group context from a TLS + * ECParameters record as defined in RFC 4492, Section 5.4. + * + * \note The read pointer \p buf is updated to point right after + * the ECParameters record on exit. + * + * \param grp The group context to setup. This must be initialized. + * \param buf The address of the pointer to the start of the input buffer. + * \param len The length of the input buffer \c *buf in Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the group is not + * recognized. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, + const unsigned char **buf, size_t len ); + +/** + * \brief This function extracts an elliptic curve group ID from a + * TLS ECParameters record as defined in RFC 4492, Section 5.4. + * + * \note The read pointer \p buf is updated to point right after + * the ECParameters record on exit. + * + * \param grp The address at which to store the group id. + * This must not be \c NULL. + * \param buf The address of the pointer to the start of the input buffer. + * \param len The length of the input buffer \c *buf in Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the group is not + * recognized. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_tls_read_group_id( mbedtls_ecp_group_id *grp, + const unsigned char **buf, + size_t len ); +/** + * \brief This function exports an elliptic curve as a TLS + * ECParameters record as defined in RFC 4492, Section 5.4. + * + * \param grp The ECP group to be exported. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param olen The address at which to store the number of Bytes written. + * This must not be \c NULL. + * \param buf The buffer to write to. This must be a writable buffer + * of length \p blen Bytes. + * \param blen The length of the output buffer \p buf in Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output + * buffer is too small to hold the exported group. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, + size_t *olen, + unsigned char *buf, size_t blen ); + +/** + * \brief This function performs a scalar multiplication of a point + * by an integer: \p R = \p m * \p P. + * + * It is not thread-safe to use same group in multiple threads. + * + * \note To prevent timing attacks, this function + * executes the exact same sequence of base-field + * operations for any valid \p m. It avoids any if-branch or + * array index depending on the value of \p m. + * + * \note If \p f_rng is not NULL, it is used to randomize + * intermediate results to prevent potential timing attacks + * targeting these results. We recommend always providing + * a non-NULL \p f_rng. The overhead is negligible. + * Note: unless #MBEDTLS_ECP_NO_INTERNAL_RNG is defined, when + * \p f_rng is NULL, an internal RNG (seeded from the value + * of \p m) will be used instead. + * + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param R The point in which to store the result of the calculation. + * This must be initialized. + * \param m The integer by which to multiply. This must be initialized. + * \param P The point to multiply. This must be initialized. + * \param f_rng The RNG function. This may be \c NULL if randomization + * of intermediate results isn't desired (discouraged). + * \param p_rng The RNG context to be passed to \p p_rng. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m is not a valid private + * key, or \p P is not a valid public key. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + +/** + * \brief This function performs multiplication of a point by + * an integer: \p R = \p m * \p P in a restartable way. + * + * \see mbedtls_ecp_mul() + * + * \note This function does the same as \c mbedtls_ecp_mul(), but + * it can return early and restart according to the limit set + * with \c mbedtls_ecp_set_max_ops() to reduce blocking. + * + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param R The point in which to store the result of the calculation. + * This must be initialized. + * \param m The integer by which to multiply. This must be initialized. + * \param P The point to multiply. This must be initialized. + * \param f_rng The RNG function. This may be \c NULL if randomization + * of intermediate results isn't desired (discouraged). + * \param p_rng The RNG context to be passed to \p p_rng. + * \param rs_ctx The restart context (NULL disables restart). + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m is not a valid private + * key, or \p P is not a valid public key. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, + mbedtls_ecp_restart_ctx *rs_ctx ); + +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) +/** + * \brief This function performs multiplication and addition of two + * points by integers: \p R = \p m * \p P + \p n * \p Q + * + * It is not thread-safe to use same group in multiple threads. + * + * \note In contrast to mbedtls_ecp_mul(), this function does not + * guarantee a constant execution flow and timing. + * + * \note This function is only defined for short Weierstrass curves. + * It may not be included in builds without any short + * Weierstrass curve. + * + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param R The point in which to store the result of the calculation. + * This must be initialized. + * \param m The integer by which to multiply \p P. + * This must be initialized. + * \param P The point to multiply by \p m. This must be initialized. + * \param n The integer by which to multiply \p Q. + * This must be initialized. + * \param Q The point to be multiplied by \p n. + * This must be initialized. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m or \p n are not + * valid private keys, or \p P or \p Q are not valid public + * keys. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p grp does not + * designate a short Weierstrass curve. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + const mbedtls_mpi *n, const mbedtls_ecp_point *Q ); + +/** + * \brief This function performs multiplication and addition of two + * points by integers: \p R = \p m * \p P + \p n * \p Q in a + * restartable way. + * + * \see \c mbedtls_ecp_muladd() + * + * \note This function works the same as \c mbedtls_ecp_muladd(), + * but it can return early and restart according to the limit + * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. + * + * \note This function is only defined for short Weierstrass curves. + * It may not be included in builds without any short + * Weierstrass curve. + * + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param R The point in which to store the result of the calculation. + * This must be initialized. + * \param m The integer by which to multiply \p P. + * This must be initialized. + * \param P The point to multiply by \p m. This must be initialized. + * \param n The integer by which to multiply \p Q. + * This must be initialized. + * \param Q The point to be multiplied by \p n. + * This must be initialized. + * \param rs_ctx The restart context (NULL disables restart). + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m or \p n are not + * valid private keys, or \p P or \p Q are not valid public + * keys. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p grp does not + * designate a short Weierstrass curve. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_muladd_restartable( + mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + const mbedtls_mpi *n, const mbedtls_ecp_point *Q, + mbedtls_ecp_restart_ctx *rs_ctx ); +#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ + +/** + * \brief This function checks that a point is a valid public key + * on this curve. + * + * It only checks that the point is non-zero, has + * valid coordinates and lies on the curve. It does not verify + * that it is indeed a multiple of \p G. This additional + * check is computationally more expensive, is not required + * by standards, and should not be necessary if the group + * used has a small cofactor. In particular, it is useless for + * the NIST groups which all have a cofactor of 1. + * + * \note This function uses bare components rather than an + * ::mbedtls_ecp_keypair structure, to ease use with other + * structures, such as ::mbedtls_ecdh_context or + * ::mbedtls_ecdsa_context. + * + * \param grp The ECP group the point should belong to. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param pt The point to check. This must be initialized. + * + * \return \c 0 if the point is a valid public key. + * \return #MBEDTLS_ERR_ECP_INVALID_KEY if the point is not + * a valid public key for the given curve. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, + const mbedtls_ecp_point *pt ); + +/** + * \brief This function checks that an \p mbedtls_mpi is a + * valid private key for this curve. + * + * \note This function uses bare components rather than an + * ::mbedtls_ecp_keypair structure to ease use with other + * structures, such as ::mbedtls_ecdh_context or + * ::mbedtls_ecdsa_context. + * + * \param grp The ECP group the private key should belong to. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param d The integer to check. This must be initialized. + * + * \return \c 0 if the point is a valid private key. + * \return #MBEDTLS_ERR_ECP_INVALID_KEY if the point is not a valid + * private key for the given curve. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, + const mbedtls_mpi *d ); + +/** + * \brief This function generates a private key. + * + * \param grp The ECP group to generate a private key for. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param d The destination MPI (secret part). This must be initialized. + * \param f_rng The RNG function. This must not be \c NULL. + * \param p_rng The RNG parameter to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context argument. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code + * on failure. + */ +int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp, + mbedtls_mpi *d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief This function generates a keypair with a configurable base + * point. + * + * \note This function uses bare components rather than an + * ::mbedtls_ecp_keypair structure to ease use with other + * structures, such as ::mbedtls_ecdh_context or + * ::mbedtls_ecdsa_context. + * + * \param grp The ECP group to generate a key pair for. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param G The base point to use. This must be initialized + * and belong to \p grp. It replaces the default base + * point \c grp->G used by mbedtls_ecp_gen_keypair(). + * \param d The destination MPI (secret part). + * This must be initialized. + * \param Q The destination point (public part). + * This must be initialized. + * \param f_rng The RNG function. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may + * be \c NULL if \p f_rng doesn't need a context argument. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code + * on failure. + */ +int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp, + const mbedtls_ecp_point *G, + mbedtls_mpi *d, mbedtls_ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief This function generates an ECP keypair. + * + * \note This function uses bare components rather than an + * ::mbedtls_ecp_keypair structure to ease use with other + * structures, such as ::mbedtls_ecdh_context or + * ::mbedtls_ecdsa_context. + * + * \param grp The ECP group to generate a key pair for. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param d The destination MPI (secret part). + * This must be initialized. + * \param Q The destination point (public part). + * This must be initialized. + * \param f_rng The RNG function. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may + * be \c NULL if \p f_rng doesn't need a context argument. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code + * on failure. + */ +int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, mbedtls_mpi *d, + mbedtls_ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief This function generates an ECP key. + * + * \param grp_id The ECP group identifier. + * \param key The destination key. This must be initialized. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may + * be \c NULL if \p f_rng doesn't need a context argument. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code + * on failure. + */ +int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief This function reads an elliptic curve private key. + * + * \param grp_id The ECP group identifier. + * \param key The destination key. + * \param buf The buffer containing the binary representation of the + * key. (Big endian integer for Weierstrass curves, byte + * string for Montgomery curves.) + * \param buflen The length of the buffer in bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_INVALID_KEY error if the key is + * invalid. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the operation for + * the group is not implemented. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_ecp_read_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, + const unsigned char *buf, size_t buflen ); + +/** + * \brief This function exports an elliptic curve private key. + * + * \param key The private key. + * \param buf The output buffer for containing the binary representation + * of the key. (Big endian integer for Weierstrass curves, byte + * string for Montgomery curves.) + * \param buflen The total length of the buffer in bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the \p key + representation is larger than the available space in \p buf. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the operation for + * the group is not implemented. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_ecp_write_key( mbedtls_ecp_keypair *key, + unsigned char *buf, size_t buflen ); + +/** + * \brief This function checks that the keypair objects + * \p pub and \p prv have the same group and the + * same public point, and that the private key in + * \p prv is consistent with the public key. + * + * \param pub The keypair structure holding the public key. This + * must be initialized. If it contains a private key, that + * part is ignored. + * \param prv The keypair structure holding the full keypair. + * This must be initialized. + * + * \return \c 0 on success, meaning that the keys are valid and match. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the keys are invalid or do not match. + * \return An \c MBEDTLS_ERR_ECP_XXX or an \c MBEDTLS_ERR_MPI_XXX + * error code on calculation failure. + */ +int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, + const mbedtls_ecp_keypair *prv ); + +#if defined(MBEDTLS_SELF_TEST) + +/** + * \brief The ECP checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +int mbedtls_ecp_self_test( int verbose ); + +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + +#endif /* ecp.h */ diff --git a/third_party/mbedtls/include/mbedtls/entropy.h b/third_party/mbedtls/include/mbedtls/entropy.h new file mode 100644 index 0000000..40259eb --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/entropy.h @@ -0,0 +1,294 @@ +/** + * \file entropy.h + * + * \brief Entropy accumulator implementation + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBEDTLS_ENTROPY_H +#define MBEDTLS_ENTROPY_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include + +#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) +#include "mbedtls/sha512.h" +#define MBEDTLS_ENTROPY_SHA512_ACCUMULATOR +#else +#if defined(MBEDTLS_SHA256_C) +#define MBEDTLS_ENTROPY_SHA256_ACCUMULATOR +#include "mbedtls/sha256.h" +#endif +#endif + +#if defined(MBEDTLS_THREADING_C) +#include "mbedtls/threading.h" +#endif + +#if defined(MBEDTLS_HAVEGE_C) +#include "mbedtls/havege.h" +#endif + +/** Critical entropy source failure. */ +#define MBEDTLS_ERR_ENTROPY_SOURCE_FAILED -0x003C +/** No more sources can be added. */ +#define MBEDTLS_ERR_ENTROPY_MAX_SOURCES -0x003E +/** No sources have been added to poll. */ +#define MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED -0x0040 +/** No strong sources have been added to poll. */ +#define MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE -0x003D +/** Read/write error in file. */ +#define MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR -0x003F + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(MBEDTLS_ENTROPY_MAX_SOURCES) +#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ +#endif + +#if !defined(MBEDTLS_ENTROPY_MAX_GATHER) +#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ +#endif + +/** \} name SECTION: Module settings */ + +#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) +#define MBEDTLS_ENTROPY_BLOCK_SIZE 64 /**< Block size of entropy accumulator (SHA-512) */ +#else +#define MBEDTLS_ENTROPY_BLOCK_SIZE 32 /**< Block size of entropy accumulator (SHA-256) */ +#endif + +#define MBEDTLS_ENTROPY_MAX_SEED_SIZE 1024 /**< Maximum size of seed we read from seed file */ +#define MBEDTLS_ENTROPY_SOURCE_MANUAL MBEDTLS_ENTROPY_MAX_SOURCES + +#define MBEDTLS_ENTROPY_SOURCE_STRONG 1 /**< Entropy source is strong */ +#define MBEDTLS_ENTROPY_SOURCE_WEAK 0 /**< Entropy source is weak */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Entropy poll callback pointer + * + * \param data Callback-specific data pointer + * \param output Data to fill + * \param len Maximum size to provide + * \param olen The actual amount of bytes put into the buffer (Can be 0) + * + * \return 0 if no critical failures occurred, + * MBEDTLS_ERR_ENTROPY_SOURCE_FAILED otherwise + */ +typedef int (*mbedtls_entropy_f_source_ptr)(void *data, unsigned char *output, size_t len, + size_t *olen); + +/** + * \brief Entropy source state + */ +typedef struct mbedtls_entropy_source_state +{ + mbedtls_entropy_f_source_ptr f_source; /**< The entropy source callback */ + void * p_source; /**< The callback data pointer */ + size_t size; /**< Amount received in bytes */ + size_t threshold; /**< Minimum bytes required before release */ + int strong; /**< Is the source strong? */ +} +mbedtls_entropy_source_state; + +/** + * \brief Entropy context structure + */ +typedef struct mbedtls_entropy_context +{ + int accumulator_started; /* 0 after init. + * 1 after the first update. + * -1 after free. */ +#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) + mbedtls_sha512_context accumulator; +#elif defined(MBEDTLS_ENTROPY_SHA256_ACCUMULATOR) + mbedtls_sha256_context accumulator; +#endif + int source_count; /* Number of entries used in source. */ + mbedtls_entropy_source_state source[MBEDTLS_ENTROPY_MAX_SOURCES]; +#if defined(MBEDTLS_HAVEGE_C) + mbedtls_havege_state havege_data; +#endif +#if defined(MBEDTLS_THREADING_C) + mbedtls_threading_mutex_t mutex; /*!< mutex */ +#endif +#if defined(MBEDTLS_ENTROPY_NV_SEED) + int initial_entropy_run; +#endif +} +mbedtls_entropy_context; + +/** + * \brief Initialize the context + * + * \param ctx Entropy context to initialize + */ +void mbedtls_entropy_init( mbedtls_entropy_context *ctx ); + +/** + * \brief Free the data in the context + * + * \param ctx Entropy context to free + */ +void mbedtls_entropy_free( mbedtls_entropy_context *ctx ); + +/** + * \brief Adds an entropy source to poll + * (Thread-safe if MBEDTLS_THREADING_C is enabled) + * + * \param ctx Entropy context + * \param f_source Entropy function + * \param p_source Function data + * \param threshold Minimum required from source before entropy is released + * ( with mbedtls_entropy_func() ) (in bytes) + * \param strong MBEDTLS_ENTROPY_SOURCE_STRONG or + * MBEDTLS_ENTROPY_SOURCE_WEAK. + * At least one strong source needs to be added. + * Weaker sources (such as the cycle counter) can be used as + * a complement. + * + * \return 0 if successful or MBEDTLS_ERR_ENTROPY_MAX_SOURCES + */ +int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx, + mbedtls_entropy_f_source_ptr f_source, void *p_source, + size_t threshold, int strong ); + +/** + * \brief Trigger an extra gather poll for the accumulator + * (Thread-safe if MBEDTLS_THREADING_C is enabled) + * + * \param ctx Entropy context + * + * \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED + */ +int mbedtls_entropy_gather( mbedtls_entropy_context *ctx ); + +/** + * \brief Retrieve entropy from the accumulator + * (Maximum length: MBEDTLS_ENTROPY_BLOCK_SIZE) + * (Thread-safe if MBEDTLS_THREADING_C is enabled) + * + * \param data Entropy context + * \param output Buffer to fill + * \param len Number of bytes desired, must be at most MBEDTLS_ENTROPY_BLOCK_SIZE + * + * \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED + */ +int mbedtls_entropy_func( void *data, unsigned char *output, size_t len ); + +/** + * \brief Add data to the accumulator manually + * (Thread-safe if MBEDTLS_THREADING_C is enabled) + * + * \param ctx Entropy context + * \param data Data to add + * \param len Length of data + * + * \return 0 if successful + */ +int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx, + const unsigned char *data, size_t len ); + +#if defined(MBEDTLS_ENTROPY_NV_SEED) +/** + * \brief Trigger an update of the seed file in NV by using the + * current entropy pool. + * + * \param ctx Entropy context + * + * \return 0 if successful + */ +int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx ); +#endif /* MBEDTLS_ENTROPY_NV_SEED */ + +#if defined(MBEDTLS_FS_IO) +/** + * \brief Write a seed file + * + * \param ctx Entropy context + * \param path Name of the file + * + * \return 0 if successful, + * MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error, or + * MBEDTLS_ERR_ENTROPY_SOURCE_FAILED + */ +int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path ); + +/** + * \brief Read and update a seed file. Seed is added to this + * instance. No more than MBEDTLS_ENTROPY_MAX_SEED_SIZE bytes are + * read from the seed file. The rest is ignored. + * + * \param ctx Entropy context + * \param path Name of the file + * + * \return 0 if successful, + * MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error, + * MBEDTLS_ERR_ENTROPY_SOURCE_FAILED + */ +int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path ); +#endif /* MBEDTLS_FS_IO */ + +#if defined(MBEDTLS_SELF_TEST) +/** + * \brief Checkup routine + * + * This module self-test also calls the entropy self-test, + * mbedtls_entropy_source_self_test(); + * + * \return 0 if successful, or 1 if a test failed + */ +int mbedtls_entropy_self_test( int verbose ); + +#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) +/** + * \brief Checkup routine + * + * Verifies the integrity of the hardware entropy source + * provided by the function 'mbedtls_hardware_poll()'. + * + * Note this is the only hardware entropy source that is known + * at link time, and other entropy sources configured + * dynamically at runtime by the function + * mbedtls_entropy_add_source() will not be tested. + * + * \return 0 if successful, or 1 if a test failed + */ +int mbedtls_entropy_source_self_test( int verbose ); +#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */ +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + +#endif /* entropy.h */ diff --git a/third_party/mbedtls/include/mbedtls/gcm.h b/third_party/mbedtls/include/mbedtls/gcm.h new file mode 100644 index 0000000..9723a17 --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/gcm.h @@ -0,0 +1,327 @@ +/** + * \file gcm.h + * + * \brief This file contains GCM definitions and functions. + * + * The Galois/Counter Mode (GCM) for 128-bit block ciphers is defined + * in D. McGrew, J. Viega, The Galois/Counter Mode of Operation + * (GCM), Natl. Inst. Stand. Technol. + * + * For more information on GCM, see NIST SP 800-38D: Recommendation for + * Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC. + * + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_GCM_H +#define MBEDTLS_GCM_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/cipher.h" + +#include + +#define MBEDTLS_GCM_ENCRYPT 1 +#define MBEDTLS_GCM_DECRYPT 0 + +/** Authenticated decryption failed. */ +#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 + +/* MBEDTLS_ERR_GCM_HW_ACCEL_FAILED is deprecated and should not be used. */ +/** GCM hardware accelerator failed. */ +#define MBEDTLS_ERR_GCM_HW_ACCEL_FAILED -0x0013 + +/** Bad input parameters to function. */ +#define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014 + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(MBEDTLS_GCM_ALT) + +/** + * \brief The GCM context structure. + */ +typedef struct mbedtls_gcm_context +{ + mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */ + uint64_t HL[16]; /*!< Precalculated HTable low. */ + uint64_t HH[16]; /*!< Precalculated HTable high. */ + uint64_t len; /*!< The total length of the encrypted data. */ + uint64_t add_len; /*!< The total length of the additional data. */ + unsigned char base_ectr[16]; /*!< The first ECTR for tag. */ + unsigned char y[16]; /*!< The Y working value. */ + unsigned char buf[16]; /*!< The buf working value. */ + int mode; /*!< The operation to perform: + #MBEDTLS_GCM_ENCRYPT or + #MBEDTLS_GCM_DECRYPT. */ +} +mbedtls_gcm_context; + +#else /* !MBEDTLS_GCM_ALT */ +#include "gcm_alt.h" +#endif /* !MBEDTLS_GCM_ALT */ + +/** + * \brief This function initializes the specified GCM context, + * to make references valid, and prepares the context + * for mbedtls_gcm_setkey() or mbedtls_gcm_free(). + * + * The function does not bind the GCM context to a particular + * cipher, nor set the key. For this purpose, use + * mbedtls_gcm_setkey(). + * + * \param ctx The GCM context to initialize. This must not be \c NULL. + */ +void mbedtls_gcm_init( mbedtls_gcm_context *ctx ); + +/** + * \brief This function associates a GCM context with a + * cipher algorithm and a key. + * + * \param ctx The GCM context. This must be initialized. + * \param cipher The 128-bit block cipher to use. + * \param key The encryption key. This must be a readable buffer of at + * least \p keybits bits. + * \param keybits The key size in bits. Valid options are: + *
  • 128 bits
  • + *
  • 192 bits
  • + *
  • 256 bits
+ * + * \return \c 0 on success. + * \return A cipher-specific error code on failure. + */ +int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx, + mbedtls_cipher_id_t cipher, + const unsigned char *key, + unsigned int keybits ); + +/** + * \brief This function performs GCM encryption or decryption of a buffer. + * + * \note For encryption, the output buffer can be the same as the + * input buffer. For decryption, the output buffer cannot be + * the same as input buffer. If the buffers overlap, the output + * buffer must trail at least 8 Bytes behind the input buffer. + * + * \warning When this function performs a decryption, it outputs the + * authentication tag and does not verify that the data is + * authentic. You should use this function to perform encryption + * only. For decryption, use mbedtls_gcm_auth_decrypt() instead. + * + * \param ctx The GCM context to use for encryption or decryption. This + * must be initialized. + * \param mode The operation to perform: + * - #MBEDTLS_GCM_ENCRYPT to perform authenticated encryption. + * The ciphertext is written to \p output and the + * authentication tag is written to \p tag. + * - #MBEDTLS_GCM_DECRYPT to perform decryption. + * The plaintext is written to \p output and the + * authentication tag is written to \p tag. + * Note that this mode is not recommended, because it does + * not verify the authenticity of the data. For this reason, + * you should use mbedtls_gcm_auth_decrypt() instead of + * calling this function in decryption mode. + * \param length The length of the input data, which is equal to the length + * of the output data. + * \param iv The initialization vector. This must be a readable buffer of + * at least \p iv_len Bytes. + * \param iv_len The length of the IV. + * \param add The buffer holding the additional data. This must be of at + * least that size in Bytes. + * \param add_len The length of the additional data. + * \param input The buffer holding the input data. If \p length is greater + * than zero, this must be a readable buffer of at least that + * size in Bytes. + * \param output The buffer for holding the output data. If \p length is greater + * than zero, this must be a writable buffer of at least that + * size in Bytes. + * \param tag_len The length of the tag to generate. + * \param tag The buffer for holding the tag. This must be a writable + * buffer of at least \p tag_len Bytes. + * + * \return \c 0 if the encryption or decryption was performed + * successfully. Note that in #MBEDTLS_GCM_DECRYPT mode, + * this does not indicate that the data is authentic. + * \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are + * not valid or a cipher-specific error code if the encryption + * or decryption failed. + */ +int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx, + int mode, + size_t length, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len, + const unsigned char *input, + unsigned char *output, + size_t tag_len, + unsigned char *tag ); + +/** + * \brief This function performs a GCM authenticated decryption of a + * buffer. + * + * \note For decryption, the output buffer cannot be the same as + * input buffer. If the buffers overlap, the output buffer + * must trail at least 8 Bytes behind the input buffer. + * + * \param ctx The GCM context. This must be initialized. + * \param length The length of the ciphertext to decrypt, which is also + * the length of the decrypted plaintext. + * \param iv The initialization vector. This must be a readable buffer + * of at least \p iv_len Bytes. + * \param iv_len The length of the IV. + * \param add The buffer holding the additional data. This must be of at + * least that size in Bytes. + * \param add_len The length of the additional data. + * \param tag The buffer holding the tag to verify. This must be a + * readable buffer of at least \p tag_len Bytes. + * \param tag_len The length of the tag to verify. + * \param input The buffer holding the ciphertext. If \p length is greater + * than zero, this must be a readable buffer of at least that + * size. + * \param output The buffer for holding the decrypted plaintext. If \p length + * is greater than zero, this must be a writable buffer of at + * least that size. + * + * \return \c 0 if successful and authenticated. + * \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match. + * \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are + * not valid or a cipher-specific error code if the decryption + * failed. + */ +int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx, + size_t length, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len, + const unsigned char *tag, + size_t tag_len, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief This function starts a GCM encryption or decryption + * operation. + * + * \param ctx The GCM context. This must be initialized. + * \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or + * #MBEDTLS_GCM_DECRYPT. + * \param iv The initialization vector. This must be a readable buffer of + * at least \p iv_len Bytes. + * \param iv_len The length of the IV. + * \param add The buffer holding the additional data, or \c NULL + * if \p add_len is \c 0. + * \param add_len The length of the additional data. If \c 0, + * \p add may be \c NULL. + * + * \return \c 0 on success. + */ +int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, + int mode, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len ); + +/** + * \brief This function feeds an input buffer into an ongoing GCM + * encryption or decryption operation. + * + * ` The function expects input to be a multiple of 16 + * Bytes. Only the last call before calling + * mbedtls_gcm_finish() can be less than 16 Bytes. + * + * \note For decryption, the output buffer cannot be the same as + * input buffer. If the buffers overlap, the output buffer + * must trail at least 8 Bytes behind the input buffer. + * + * \param ctx The GCM context. This must be initialized. + * \param length The length of the input data. This must be a multiple of + * 16 except in the last call before mbedtls_gcm_finish(). + * \param input The buffer holding the input data. If \p length is greater + * than zero, this must be a readable buffer of at least that + * size in Bytes. + * \param output The buffer for holding the output data. If \p length is + * greater than zero, this must be a writable buffer of at + * least that size in Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure. + */ +int mbedtls_gcm_update( mbedtls_gcm_context *ctx, + size_t length, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief This function finishes the GCM operation and generates + * the authentication tag. + * + * It wraps up the GCM stream, and generates the + * tag. The tag can have a maximum length of 16 Bytes. + * + * \param ctx The GCM context. This must be initialized. + * \param tag The buffer for holding the tag. This must be a writable + * buffer of at least \p tag_len Bytes. + * \param tag_len The length of the tag to generate. This must be at least + * four. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure. + */ +int mbedtls_gcm_finish( mbedtls_gcm_context *ctx, + unsigned char *tag, + size_t tag_len ); + +/** + * \brief This function clears a GCM context and the underlying + * cipher sub-context. + * + * \param ctx The GCM context to clear. If this is \c NULL, the call has + * no effect. Otherwise, this must be initialized. + */ +void mbedtls_gcm_free( mbedtls_gcm_context *ctx ); + +#if defined(MBEDTLS_SELF_TEST) + +/** + * \brief The GCM checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +int mbedtls_gcm_self_test( int verbose ); + +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + + +#endif /* gcm.h */ diff --git a/third_party/mbedtls/include/mbedtls/md.h b/third_party/mbedtls/include/mbedtls/md.h new file mode 100644 index 0000000..84fafd2 --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/md.h @@ -0,0 +1,493 @@ + /** + * \file md.h + * + * \brief This file contains the generic message-digest wrapper. + * + * \author Adriaan de Jong + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_MD_H +#define MBEDTLS_MD_H + +#include + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif +#include "mbedtls/platform_util.h" + +/** The selected feature is not available. */ +#define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080 +/** Bad input parameters to function. */ +#define MBEDTLS_ERR_MD_BAD_INPUT_DATA -0x5100 +/** Failed to allocate memory. */ +#define MBEDTLS_ERR_MD_ALLOC_FAILED -0x5180 +/** Opening or reading of file failed. */ +#define MBEDTLS_ERR_MD_FILE_IO_ERROR -0x5200 + +/* MBEDTLS_ERR_MD_HW_ACCEL_FAILED is deprecated and should not be used. */ +/** MD hardware accelerator failed. */ +#define MBEDTLS_ERR_MD_HW_ACCEL_FAILED -0x5280 + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Supported message digests. + * + * \warning MD2, MD4, MD5 and SHA-1 are considered weak message digests and + * their use constitutes a security risk. We recommend considering + * stronger message digests instead. + * + */ +typedef enum { + MBEDTLS_MD_NONE=0, /**< None. */ + MBEDTLS_MD_MD2, /**< The MD2 message digest. */ + MBEDTLS_MD_MD4, /**< The MD4 message digest. */ + MBEDTLS_MD_MD5, /**< The MD5 message digest. */ + MBEDTLS_MD_SHA1, /**< The SHA-1 message digest. */ + MBEDTLS_MD_SHA224, /**< The SHA-224 message digest. */ + MBEDTLS_MD_SHA256, /**< The SHA-256 message digest. */ + MBEDTLS_MD_SHA384, /**< The SHA-384 message digest. */ + MBEDTLS_MD_SHA512, /**< The SHA-512 message digest. */ + MBEDTLS_MD_RIPEMD160, /**< The RIPEMD-160 message digest. */ +} mbedtls_md_type_t; + +#if defined(MBEDTLS_SHA512_C) +#define MBEDTLS_MD_MAX_SIZE 64 /* longest known is SHA512 */ +#else +#define MBEDTLS_MD_MAX_SIZE 32 /* longest known is SHA256 or less */ +#endif + +#if defined(MBEDTLS_SHA512_C) +#define MBEDTLS_MD_MAX_BLOCK_SIZE 128 +#else +#define MBEDTLS_MD_MAX_BLOCK_SIZE 64 +#endif + +/** + * Opaque struct defined in md_internal.h. + */ +typedef struct mbedtls_md_info_t mbedtls_md_info_t; + +/** + * The generic message-digest context. + */ +typedef struct mbedtls_md_context_t +{ + /** Information about the associated message digest. */ + const mbedtls_md_info_t *md_info; + + /** The digest-specific context. */ + void *md_ctx; + + /** The HMAC part of the context. */ + void *hmac_ctx; +} mbedtls_md_context_t; + +/** + * \brief This function returns the list of digests supported by the + * generic digest module. + * + * \note The list starts with the strongest available hashes. + * + * \return A statically allocated array of digests. Each element + * in the returned list is an integer belonging to the + * message-digest enumeration #mbedtls_md_type_t. + * The last entry is 0. + */ +const int *mbedtls_md_list( void ); + +/** + * \brief This function returns the message-digest information + * associated with the given digest name. + * + * \param md_name The name of the digest to search for. + * + * \return The message-digest information associated with \p md_name. + * \return NULL if the associated message-digest information is not found. + */ +const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name ); + +/** + * \brief This function returns the message-digest information + * associated with the given digest type. + * + * \param md_type The type of digest to search for. + * + * \return The message-digest information associated with \p md_type. + * \return NULL if the associated message-digest information is not found. + */ +const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type ); + +/** + * \brief This function initializes a message-digest context without + * binding it to a particular message-digest algorithm. + * + * This function should always be called first. It prepares the + * context for mbedtls_md_setup() for binding it to a + * message-digest algorithm. + */ +void mbedtls_md_init( mbedtls_md_context_t *ctx ); + +/** + * \brief This function clears the internal structure of \p ctx and + * frees any embedded internal structure, but does not free + * \p ctx itself. + * + * If you have called mbedtls_md_setup() on \p ctx, you must + * call mbedtls_md_free() when you are no longer using the + * context. + * Calling this function if you have previously + * called mbedtls_md_init() and nothing else is optional. + * You must not call this function if you have not called + * mbedtls_md_init(). + */ +void mbedtls_md_free( mbedtls_md_context_t *ctx ); + +#if ! defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif +/** + * \brief This function selects the message digest algorithm to use, + * and allocates internal structures. + * + * It should be called after mbedtls_md_init() or mbedtls_md_free(). + * Makes it necessary to call mbedtls_md_free() later. + * + * \deprecated Superseded by mbedtls_md_setup() in 2.0.0 + * + * \param ctx The context to set up. + * \param md_info The information structure of the message-digest algorithm + * to use. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification + * failure. + * \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure. + */ +int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) MBEDTLS_DEPRECATED; +#undef MBEDTLS_DEPRECATED +#endif /* MBEDTLS_DEPRECATED_REMOVED */ + +/** + * \brief This function selects the message digest algorithm to use, + * and allocates internal structures. + * + * It should be called after mbedtls_md_init() or + * mbedtls_md_free(). Makes it necessary to call + * mbedtls_md_free() later. + * + * \param ctx The context to set up. + * \param md_info The information structure of the message-digest algorithm + * to use. + * \param hmac Defines if HMAC is used. 0: HMAC is not used (saves some memory), + * or non-zero: HMAC is used with this context. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification + * failure. + * \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac ); + +/** + * \brief This function clones the state of an message-digest + * context. + * + * \note You must call mbedtls_md_setup() on \c dst before calling + * this function. + * + * \note The two contexts must have the same type, + * for example, both are SHA-256. + * + * \warning This function clones the message-digest state, not the + * HMAC state. + * + * \param dst The destination context. + * \param src The context to be cloned. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_clone( mbedtls_md_context_t *dst, + const mbedtls_md_context_t *src ); + +/** + * \brief This function extracts the message-digest size from the + * message-digest information structure. + * + * \param md_info The information structure of the message-digest algorithm + * to use. + * + * \return The size of the message-digest output in Bytes. + */ +unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info ); + +/** + * \brief This function extracts the message-digest type from the + * message-digest information structure. + * + * \param md_info The information structure of the message-digest algorithm + * to use. + * + * \return The type of the message digest. + */ +mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info ); + +/** + * \brief This function extracts the message-digest name from the + * message-digest information structure. + * + * \param md_info The information structure of the message-digest algorithm + * to use. + * + * \return The name of the message digest. + */ +const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info ); + +/** + * \brief This function starts a message-digest computation. + * + * You must call this function after setting up the context + * with mbedtls_md_setup(), and before passing data with + * mbedtls_md_update(). + * + * \param ctx The generic message-digest context. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification + * failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_starts( mbedtls_md_context_t *ctx ); + +/** + * \brief This function feeds an input buffer into an ongoing + * message-digest computation. + * + * You must call mbedtls_md_starts() before calling this + * function. You may call this function multiple times. + * Afterwards, call mbedtls_md_finish(). + * + * \param ctx The generic message-digest context. + * \param input The buffer holding the input data. + * \param ilen The length of the input data. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification + * failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ); + +/** + * \brief This function finishes the digest operation, + * and writes the result to the output buffer. + * + * Call this function after a call to mbedtls_md_starts(), + * followed by any number of calls to mbedtls_md_update(). + * Afterwards, you may either clear the context with + * mbedtls_md_free(), or call mbedtls_md_starts() to reuse + * the context for another digest operation with the same + * algorithm. + * + * \param ctx The generic message-digest context. + * \param output The buffer for the generic message-digest checksum result. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification + * failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output ); + +/** + * \brief This function calculates the message-digest of a buffer, + * with respect to a configurable message-digest algorithm + * in a single call. + * + * The result is calculated as + * Output = message_digest(input buffer). + * + * \param md_info The information structure of the message-digest algorithm + * to use. + * \param input The buffer holding the data. + * \param ilen The length of the input data. + * \param output The generic message-digest checksum result. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification + * failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, + unsigned char *output ); + +#if defined(MBEDTLS_FS_IO) +/** + * \brief This function calculates the message-digest checksum + * result of the contents of the provided file. + * + * The result is calculated as + * Output = message_digest(file contents). + * + * \param md_info The information structure of the message-digest algorithm + * to use. + * \param path The input file name. + * \param output The generic message-digest checksum result. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_FILE_IO_ERROR on an I/O error accessing + * the file pointed by \p path. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, + unsigned char *output ); +#endif /* MBEDTLS_FS_IO */ + +/** + * \brief This function sets the HMAC key and prepares to + * authenticate a new message. + * + * Call this function after mbedtls_md_setup(), to use + * the MD context for an HMAC calculation, then call + * mbedtls_md_hmac_update() to provide the input data, and + * mbedtls_md_hmac_finish() to get the HMAC value. + * + * \param ctx The message digest context containing an embedded HMAC + * context. + * \param key The HMAC secret key. + * \param keylen The length of the HMAC key in Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification + * failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, + size_t keylen ); + +/** + * \brief This function feeds an input buffer into an ongoing HMAC + * computation. + * + * Call mbedtls_md_hmac_starts() or mbedtls_md_hmac_reset() + * before calling this function. + * You may call this function multiple times to pass the + * input piecewise. + * Afterwards, call mbedtls_md_hmac_finish(). + * + * \param ctx The message digest context containing an embedded HMAC + * context. + * \param input The buffer holding the input data. + * \param ilen The length of the input data. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification + * failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, + size_t ilen ); + +/** + * \brief This function finishes the HMAC operation, and writes + * the result to the output buffer. + * + * Call this function after mbedtls_md_hmac_starts() and + * mbedtls_md_hmac_update() to get the HMAC value. Afterwards + * you may either call mbedtls_md_free() to clear the context, + * or call mbedtls_md_hmac_reset() to reuse the context with + * the same HMAC key. + * + * \param ctx The message digest context containing an embedded HMAC + * context. + * \param output The generic HMAC checksum result. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification + * failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output); + +/** + * \brief This function prepares to authenticate a new message with + * the same key as the previous HMAC operation. + * + * You may call this function after mbedtls_md_hmac_finish(). + * Afterwards call mbedtls_md_hmac_update() to pass the new + * input. + * + * \param ctx The message digest context containing an embedded HMAC + * context. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification + * failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ); + +/** + * \brief This function calculates the full generic HMAC + * on the input buffer with the provided key. + * + * The function allocates the context, performs the + * calculation, and frees the context. + * + * The HMAC result is calculated as + * output = generic HMAC(hmac key, input buffer). + * + * \param md_info The information structure of the message-digest algorithm + * to use. + * \param key The HMAC secret key. + * \param keylen The length of the HMAC secret key in Bytes. + * \param input The buffer holding the input data. + * \param ilen The length of the input data. + * \param output The generic HMAC result. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification + * failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char *output ); + +/* Internal use */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data ); + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_MD_H */ diff --git a/third_party/mbedtls/include/mbedtls/pk.h b/third_party/mbedtls/include/mbedtls/pk.h new file mode 100644 index 0000000..c9a13f4 --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/pk.h @@ -0,0 +1,918 @@ +/** + * \file pk.h + * + * \brief Public Key abstraction layer + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_PK_H +#define MBEDTLS_PK_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/md.h" + +#if defined(MBEDTLS_RSA_C) +#include "mbedtls/rsa.h" +#endif + +#if defined(MBEDTLS_ECP_C) +#include "mbedtls/ecp.h" +#endif + +#if defined(MBEDTLS_ECDSA_C) +#include "mbedtls/ecdsa.h" +#endif + +#if defined(MBEDTLS_USE_PSA_CRYPTO) +#include "psa/crypto.h" +#endif + +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + +/** Memory allocation failed. */ +#define MBEDTLS_ERR_PK_ALLOC_FAILED -0x3F80 +/** Type mismatch, eg attempt to encrypt with an ECDSA key */ +#define MBEDTLS_ERR_PK_TYPE_MISMATCH -0x3F00 +/** Bad input parameters to function. */ +#define MBEDTLS_ERR_PK_BAD_INPUT_DATA -0x3E80 +/** Read/write of file failed. */ +#define MBEDTLS_ERR_PK_FILE_IO_ERROR -0x3E00 +/** Unsupported key version */ +#define MBEDTLS_ERR_PK_KEY_INVALID_VERSION -0x3D80 +/** Invalid key tag or value. */ +#define MBEDTLS_ERR_PK_KEY_INVALID_FORMAT -0x3D00 +/** Key algorithm is unsupported (only RSA and EC are supported). */ +#define MBEDTLS_ERR_PK_UNKNOWN_PK_ALG -0x3C80 +/** Private key password can't be empty. */ +#define MBEDTLS_ERR_PK_PASSWORD_REQUIRED -0x3C00 +/** Given private key password does not allow for correct decryption. */ +#define MBEDTLS_ERR_PK_PASSWORD_MISMATCH -0x3B80 +/** The pubkey tag or value is invalid (only RSA and EC are supported). */ +#define MBEDTLS_ERR_PK_INVALID_PUBKEY -0x3B00 +/** The algorithm tag or value is invalid. */ +#define MBEDTLS_ERR_PK_INVALID_ALG -0x3A80 +/** Elliptic curve is unsupported (only NIST curves are supported). */ +#define MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE -0x3A00 +/** Unavailable feature, e.g. RSA disabled for RSA key. */ +#define MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE -0x3980 +/** The buffer contains a valid signature followed by more data. */ +#define MBEDTLS_ERR_PK_SIG_LEN_MISMATCH -0x3900 + +/* MBEDTLS_ERR_PK_HW_ACCEL_FAILED is deprecated and should not be used. */ +/** PK hardware accelerator failed. */ +#define MBEDTLS_ERR_PK_HW_ACCEL_FAILED -0x3880 + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Public key types + */ +typedef enum { + MBEDTLS_PK_NONE=0, + MBEDTLS_PK_RSA, + MBEDTLS_PK_ECKEY, + MBEDTLS_PK_ECKEY_DH, + MBEDTLS_PK_ECDSA, + MBEDTLS_PK_RSA_ALT, + MBEDTLS_PK_RSASSA_PSS, + MBEDTLS_PK_OPAQUE, +} mbedtls_pk_type_t; + +/** + * \brief Options for RSASSA-PSS signature verification. + * See \c mbedtls_rsa_rsassa_pss_verify_ext() + */ +typedef struct mbedtls_pk_rsassa_pss_options +{ + mbedtls_md_type_t mgf1_hash_id; + int expected_salt_len; + +} mbedtls_pk_rsassa_pss_options; + +/** + * \brief Maximum size of a signature made by mbedtls_pk_sign(). + */ +/* We need to set MBEDTLS_PK_SIGNATURE_MAX_SIZE to the maximum signature + * size among the supported signature types. Do it by starting at 0, + * then incrementally increasing to be large enough for each supported + * signature mechanism. + * + * The resulting value can be 0, for example if MBEDTLS_ECDH_C is enabled + * (which allows the pk module to be included) but neither MBEDTLS_ECDSA_C + * nor MBEDTLS_RSA_C nor any opaque signature mechanism (PSA or RSA_ALT). + */ +#define MBEDTLS_PK_SIGNATURE_MAX_SIZE 0 + +#if ( defined(MBEDTLS_RSA_C) || defined(MBEDTLS_PK_RSA_ALT_SUPPORT) ) && \ + MBEDTLS_MPI_MAX_SIZE > MBEDTLS_PK_SIGNATURE_MAX_SIZE +/* For RSA, the signature can be as large as the bignum module allows. + * For RSA_ALT, the signature size is not necessarily tied to what the + * bignum module can do, but in the absence of any specific setting, + * we use that (rsa_alt_sign_wrap in pk_wrap will check). */ +#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE +#define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE +#endif + +#if defined(MBEDTLS_ECDSA_C) && \ + MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_PK_SIGNATURE_MAX_SIZE +/* For ECDSA, the ecdsa module exports a constant for the maximum + * signature size. */ +#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE +#define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN +#endif + +#if defined(MBEDTLS_USE_PSA_CRYPTO) +#if PSA_SIGNATURE_MAX_SIZE > MBEDTLS_PK_SIGNATURE_MAX_SIZE +/* PSA_SIGNATURE_MAX_SIZE is the maximum size of a signature made + * through the PSA API in the PSA representation. */ +#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE +#define MBEDTLS_PK_SIGNATURE_MAX_SIZE PSA_SIGNATURE_MAX_SIZE +#endif + +#if PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE + 11 > MBEDTLS_PK_SIGNATURE_MAX_SIZE +/* The Mbed TLS representation is different for ECDSA signatures: + * PSA uses the raw concatenation of r and s, + * whereas Mbed TLS uses the ASN.1 representation (SEQUENCE of two INTEGERs). + * Add the overhead of ASN.1: up to (1+2) + 2 * (1+2+1) for the + * types, lengths (represented by up to 2 bytes), and potential leading + * zeros of the INTEGERs and the SEQUENCE. */ +#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE +#define MBEDTLS_PK_SIGNATURE_MAX_SIZE ( PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE + 11 ) +#endif +#endif /* defined(MBEDTLS_USE_PSA_CRYPTO) */ + +/** + * \brief Types for interfacing with the debug module + */ +typedef enum +{ + MBEDTLS_PK_DEBUG_NONE = 0, + MBEDTLS_PK_DEBUG_MPI, + MBEDTLS_PK_DEBUG_ECP, +} mbedtls_pk_debug_type; + +/** + * \brief Item to send to the debug module + */ +typedef struct mbedtls_pk_debug_item +{ + mbedtls_pk_debug_type type; + const char *name; + void *value; +} mbedtls_pk_debug_item; + +/** Maximum number of item send for debugging, plus 1 */ +#define MBEDTLS_PK_DEBUG_MAX_ITEMS 3 + +/** + * \brief Public key information and operations + */ +typedef struct mbedtls_pk_info_t mbedtls_pk_info_t; + +/** + * \brief Public key container + */ +typedef struct mbedtls_pk_context +{ + const mbedtls_pk_info_t * pk_info; /**< Public key information */ + void * pk_ctx; /**< Underlying public key context */ +} mbedtls_pk_context; + +#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) +/** + * \brief Context for resuming operations + */ +typedef struct +{ + const mbedtls_pk_info_t * pk_info; /**< Public key information */ + void * rs_ctx; /**< Underlying restart context */ +} mbedtls_pk_restart_ctx; +#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ +/* Now we can declare functions that take a pointer to that */ +typedef void mbedtls_pk_restart_ctx; +#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ + +#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) +/** + * \brief Types for RSA-alt abstraction + */ +typedef int (*mbedtls_pk_rsa_alt_decrypt_func)( void *ctx, int mode, size_t *olen, + const unsigned char *input, unsigned char *output, + size_t output_max_len ); +typedef int (*mbedtls_pk_rsa_alt_sign_func)( void *ctx, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, + int mode, mbedtls_md_type_t md_alg, unsigned int hashlen, + const unsigned char *hash, unsigned char *sig ); +typedef size_t (*mbedtls_pk_rsa_alt_key_len_func)( void *ctx ); +#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ + +/** + * \brief Return information associated with the given PK type + * + * \param pk_type PK type to search for. + * + * \return The PK info associated with the type or NULL if not found. + */ +const mbedtls_pk_info_t *mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type ); + +/** + * \brief Initialize a #mbedtls_pk_context (as NONE). + * + * \param ctx The context to initialize. + * This must not be \c NULL. + */ +void mbedtls_pk_init( mbedtls_pk_context *ctx ); + +/** + * \brief Free the components of a #mbedtls_pk_context. + * + * \param ctx The context to clear. It must have been initialized. + * If this is \c NULL, this function does nothing. + * + * \note For contexts that have been set up with + * mbedtls_pk_setup_opaque(), this does not free the underlying + * PSA key and you still need to call psa_destroy_key() + * independently if you want to destroy that key. + */ +void mbedtls_pk_free( mbedtls_pk_context *ctx ); + +#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) +/** + * \brief Initialize a restart context + * + * \param ctx The context to initialize. + * This must not be \c NULL. + */ +void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx ); + +/** + * \brief Free the components of a restart context + * + * \param ctx The context to clear. It must have been initialized. + * If this is \c NULL, this function does nothing. + */ +void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx ); +#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ + +/** + * \brief Initialize a PK context with the information given + * and allocates the type-specific PK subcontext. + * + * \param ctx Context to initialize. It must not have been set + * up yet (type #MBEDTLS_PK_NONE). + * \param info Information to use + * + * \return 0 on success, + * MBEDTLS_ERR_PK_BAD_INPUT_DATA on invalid input, + * MBEDTLS_ERR_PK_ALLOC_FAILED on allocation failure. + * + * \note For contexts holding an RSA-alt key, use + * \c mbedtls_pk_setup_rsa_alt() instead. + */ +int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info ); + +#if defined(MBEDTLS_USE_PSA_CRYPTO) +/** + * \brief Initialize a PK context to wrap a PSA key. + * + * \note This function replaces mbedtls_pk_setup() for contexts + * that wrap a (possibly opaque) PSA key instead of + * storing and manipulating the key material directly. + * + * \param ctx The context to initialize. It must be empty (type NONE). + * \param key The PSA key to wrap, which must hold an ECC key pair + * (see notes below). + * + * \note The wrapped key must remain valid as long as the + * wrapping PK context is in use, that is at least between + * the point this function is called and the point + * mbedtls_pk_free() is called on this context. The wrapped + * key might then be independently used or destroyed. + * + * \note This function is currently only available for ECC key + * pairs (that is, ECC keys containing private key material). + * Support for other key types may be added later. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA on invalid input + * (context already used, invalid key identifier). + * \return #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE if the key is not an + * ECC key pair. + * \return #MBEDTLS_ERR_PK_ALLOC_FAILED on allocation failure. + */ +int mbedtls_pk_setup_opaque( mbedtls_pk_context *ctx, + const psa_key_id_t key ); +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) +/** + * \brief Initialize an RSA-alt context + * + * \param ctx Context to initialize. It must not have been set + * up yet (type #MBEDTLS_PK_NONE). + * \param key RSA key pointer + * \param decrypt_func Decryption function + * \param sign_func Signing function + * \param key_len_func Function returning key length in bytes + * + * \return 0 on success, or MBEDTLS_ERR_PK_BAD_INPUT_DATA if the + * context wasn't already initialized as RSA_ALT. + * + * \note This function replaces \c mbedtls_pk_setup() for RSA-alt. + */ +int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key, + mbedtls_pk_rsa_alt_decrypt_func decrypt_func, + mbedtls_pk_rsa_alt_sign_func sign_func, + mbedtls_pk_rsa_alt_key_len_func key_len_func ); +#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ + +/** + * \brief Get the size in bits of the underlying key + * + * \param ctx The context to query. It must have been initialized. + * + * \return Key size in bits, or 0 on error + */ +size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx ); + +/** + * \brief Get the length in bytes of the underlying key + * + * \param ctx The context to query. It must have been initialized. + * + * \return Key length in bytes, or 0 on error + */ +static inline size_t mbedtls_pk_get_len( const mbedtls_pk_context *ctx ) +{ + return( ( mbedtls_pk_get_bitlen( ctx ) + 7 ) / 8 ); +} + +/** + * \brief Tell if a context can do the operation given by type + * + * \param ctx The context to query. It must have been initialized. + * \param type The desired type. + * + * \return 1 if the context can do operations on the given type. + * \return 0 if the context cannot do the operations on the given + * type. This is always the case for a context that has + * been initialized but not set up, or that has been + * cleared with mbedtls_pk_free(). + */ +int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type ); + +/** + * \brief Verify signature (including padding if relevant). + * + * \param ctx The PK context to use. It must have been set up. + * \param md_alg Hash algorithm used (see notes) + * \param hash Hash of the message to sign + * \param hash_len Hash length or 0 (see notes) + * \param sig Signature to verify + * \param sig_len Signature length + * + * \return 0 on success (signature is valid), + * #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid + * signature in sig but its length is less than \p siglen, + * or a specific error code. + * + * \note For RSA keys, the default padding type is PKCS#1 v1.5. + * Use \c mbedtls_pk_verify_ext( MBEDTLS_PK_RSASSA_PSS, ... ) + * to verify RSASSA_PSS signatures. + * + * \note If hash_len is 0, then the length associated with md_alg + * is used instead, or an error returned if it is invalid. + * + * \note md_alg may be MBEDTLS_MD_NONE, only if hash_len != 0 + */ +int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ); + +/** + * \brief Restartable version of \c mbedtls_pk_verify() + * + * \note Performs the same job as \c mbedtls_pk_verify(), but can + * return early and restart according to the limit set with + * \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC + * operations. For RSA, same as \c mbedtls_pk_verify(). + * + * \param ctx The PK context to use. It must have been set up. + * \param md_alg Hash algorithm used (see notes) + * \param hash Hash of the message to sign + * \param hash_len Hash length or 0 (see notes) + * \param sig Signature to verify + * \param sig_len Signature length + * \param rs_ctx Restart context (NULL to disable restart) + * + * \return See \c mbedtls_pk_verify(), or + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + */ +int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx, + mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len, + mbedtls_pk_restart_ctx *rs_ctx ); + +/** + * \brief Verify signature, with options. + * (Includes verification of the padding depending on type.) + * + * \param type Signature type (inc. possible padding type) to verify + * \param options Pointer to type-specific options, or NULL + * \param ctx The PK context to use. It must have been set up. + * \param md_alg Hash algorithm used (see notes) + * \param hash Hash of the message to sign + * \param hash_len Hash length or 0 (see notes) + * \param sig Signature to verify + * \param sig_len Signature length + * + * \return 0 on success (signature is valid), + * #MBEDTLS_ERR_PK_TYPE_MISMATCH if the PK context can't be + * used for this type of signatures, + * #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid + * signature in sig but its length is less than \p siglen, + * or a specific error code. + * + * \note If hash_len is 0, then the length associated with md_alg + * is used instead, or an error returned if it is invalid. + * + * \note md_alg may be MBEDTLS_MD_NONE, only if hash_len != 0 + * + * \note If type is MBEDTLS_PK_RSASSA_PSS, then options must point + * to a mbedtls_pk_rsassa_pss_options structure, + * otherwise it must be NULL. + */ +int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options, + mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ); + +/** + * \brief Make signature, including padding if relevant. + * + * \param ctx The PK context to use. It must have been set up + * with a private key. + * \param md_alg Hash algorithm used (see notes) + * \param hash Hash of the message to sign + * \param hash_len Hash length or 0 (see notes) + * \param sig Place to write the signature. + * It must have enough room for the signature. + * #MBEDTLS_PK_SIGNATURE_MAX_SIZE is always enough. + * You may use a smaller buffer if it is large enough + * given the key type. + * \param sig_len On successful return, + * the number of bytes written to \p sig. + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \return 0 on success, or a specific error code. + * + * \note For RSA keys, the default padding type is PKCS#1 v1.5. + * There is no interface in the PK module to make RSASSA-PSS + * signatures yet. + * + * \note If hash_len is 0, then the length associated with md_alg + * is used instead, or an error returned if it is invalid. + * + * \note For RSA, md_alg may be MBEDTLS_MD_NONE if hash_len != 0. + * For ECDSA, md_alg may never be MBEDTLS_MD_NONE. + */ +int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + +/** + * \brief Restartable version of \c mbedtls_pk_sign() + * + * \note Performs the same job as \c mbedtls_pk_sign(), but can + * return early and restart according to the limit set with + * \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC + * operations. For RSA, same as \c mbedtls_pk_sign(). + * + * \param ctx The PK context to use. It must have been set up + * with a private key. + * \param md_alg Hash algorithm used (see notes for mbedtls_pk_sign()) + * \param hash Hash of the message to sign + * \param hash_len Hash length or 0 (see notes for mbedtls_pk_sign()) + * \param sig Place to write the signature. + * It must have enough room for the signature. + * #MBEDTLS_PK_SIGNATURE_MAX_SIZE is always enough. + * You may use a smaller buffer if it is large enough + * given the key type. + * \param sig_len On successful return, + * the number of bytes written to \p sig. + * \param f_rng RNG function + * \param p_rng RNG parameter + * \param rs_ctx Restart context (NULL to disable restart) + * + * \return See \c mbedtls_pk_sign(). + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + */ +int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx, + mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, + mbedtls_pk_restart_ctx *rs_ctx ); + +/** + * \brief Decrypt message (including padding if relevant). + * + * \param ctx The PK context to use. It must have been set up + * with a private key. + * \param input Input to decrypt + * \param ilen Input size + * \param output Decrypted output + * \param olen Decrypted message length + * \param osize Size of the output buffer + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \note For RSA keys, the default padding type is PKCS#1 v1.5. + * + * \return 0 on success, or a specific error code. + */ +int mbedtls_pk_decrypt( mbedtls_pk_context *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + +/** + * \brief Encrypt message (including padding if relevant). + * + * \param ctx The PK context to use. It must have been set up. + * \param input Message to encrypt + * \param ilen Message size + * \param output Encrypted output + * \param olen Encrypted output length + * \param osize Size of the output buffer + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \note For RSA keys, the default padding type is PKCS#1 v1.5. + * + * \return 0 on success, or a specific error code. + */ +int mbedtls_pk_encrypt( mbedtls_pk_context *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + +/** + * \brief Check if a public-private pair of keys matches. + * + * \param pub Context holding a public key. + * \param prv Context holding a private (and public) key. + * + * \return \c 0 on success (keys were checked and match each other). + * \return #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE if the keys could not + * be checked - in that case they may or may not match. + * \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA if a context is invalid. + * \return Another non-zero value if the keys do not match. + */ +int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv ); + +/** + * \brief Export debug information + * + * \param ctx The PK context to use. It must have been initialized. + * \param items Place to write debug items + * + * \return 0 on success or MBEDTLS_ERR_PK_BAD_INPUT_DATA + */ +int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items ); + +/** + * \brief Access the type name + * + * \param ctx The PK context to use. It must have been initialized. + * + * \return Type name on success, or "invalid PK" + */ +const char * mbedtls_pk_get_name( const mbedtls_pk_context *ctx ); + +/** + * \brief Get the key type + * + * \param ctx The PK context to use. It must have been initialized. + * + * \return Type on success. + * \return #MBEDTLS_PK_NONE for a context that has not been set up. + */ +mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx ); + +#if defined(MBEDTLS_RSA_C) +/** + * Quick access to an RSA context inside a PK context. + * + * \warning This function can only be used when the type of the context, as + * returned by mbedtls_pk_get_type(), is #MBEDTLS_PK_RSA. + * Ensuring that is the caller's responsibility. + * Alternatively, you can check whether this function returns NULL. + * + * \return The internal RSA context held by the PK context, or NULL. + */ +static inline mbedtls_rsa_context *mbedtls_pk_rsa( const mbedtls_pk_context pk ) +{ + switch( mbedtls_pk_get_type( &pk ) ) + { + case MBEDTLS_PK_RSA: + return( (mbedtls_rsa_context *) (pk).pk_ctx ); + default: + return( NULL ); + } +} +#endif /* MBEDTLS_RSA_C */ + +#if defined(MBEDTLS_ECP_C) +/** + * Quick access to an EC context inside a PK context. + * + * \warning This function can only be used when the type of the context, as + * returned by mbedtls_pk_get_type(), is #MBEDTLS_PK_ECKEY, + * #MBEDTLS_PK_ECKEY_DH, or #MBEDTLS_PK_ECDSA. + * Ensuring that is the caller's responsibility. + * Alternatively, you can check whether this function returns NULL. + * + * \return The internal EC context held by the PK context, or NULL. + */ +static inline mbedtls_ecp_keypair *mbedtls_pk_ec( const mbedtls_pk_context pk ) +{ + switch( mbedtls_pk_get_type( &pk ) ) + { + case MBEDTLS_PK_ECKEY: + case MBEDTLS_PK_ECKEY_DH: + case MBEDTLS_PK_ECDSA: + return( (mbedtls_ecp_keypair *) (pk).pk_ctx ); + default: + return( NULL ); + } +} +#endif /* MBEDTLS_ECP_C */ + +#if defined(MBEDTLS_PK_PARSE_C) +/** \ingroup pk_module */ +/** + * \brief Parse a private key in PEM or DER format + * + * \param ctx The PK context to fill. It must have been initialized + * but not set up. + * \param key Input buffer to parse. + * The buffer must contain the input exactly, with no + * extra trailing material. For PEM, the buffer must + * contain a null-terminated string. + * \param keylen Size of \b key in bytes. + * For PEM data, this includes the terminating null byte, + * so \p keylen must be equal to `strlen(key) + 1`. + * \param pwd Optional password for decryption. + * Pass \c NULL if expecting a non-encrypted key. + * Pass a string of \p pwdlen bytes if expecting an encrypted + * key; a non-encrypted key will also be accepted. + * The empty password is not supported. + * \param pwdlen Size of the password in bytes. + * Ignored if \p pwd is \c NULL. + * + * \note On entry, ctx must be empty, either freshly initialised + * with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a + * specific key type, check the result with mbedtls_pk_can_do(). + * + * \note The key is also checked for correctness. + * + * \return 0 if successful, or a specific PK or PEM error code + */ +int mbedtls_pk_parse_key( mbedtls_pk_context *ctx, + const unsigned char *key, size_t keylen, + const unsigned char *pwd, size_t pwdlen ); + +/** \ingroup pk_module */ +/** + * \brief Parse a public key in PEM or DER format + * + * \param ctx The PK context to fill. It must have been initialized + * but not set up. + * \param key Input buffer to parse. + * The buffer must contain the input exactly, with no + * extra trailing material. For PEM, the buffer must + * contain a null-terminated string. + * \param keylen Size of \b key in bytes. + * For PEM data, this includes the terminating null byte, + * so \p keylen must be equal to `strlen(key) + 1`. + * + * \note On entry, ctx must be empty, either freshly initialised + * with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a + * specific key type, check the result with mbedtls_pk_can_do(). + * + * \note The key is also checked for correctness. + * + * \return 0 if successful, or a specific PK or PEM error code + */ +int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx, + const unsigned char *key, size_t keylen ); + +#if defined(MBEDTLS_FS_IO) +/** \ingroup pk_module */ +/** + * \brief Load and parse a private key + * + * \param ctx The PK context to fill. It must have been initialized + * but not set up. + * \param path filename to read the private key from + * \param password Optional password to decrypt the file. + * Pass \c NULL if expecting a non-encrypted key. + * Pass a null-terminated string if expecting an encrypted + * key; a non-encrypted key will also be accepted. + * The empty password is not supported. + * + * \note On entry, ctx must be empty, either freshly initialised + * with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a + * specific key type, check the result with mbedtls_pk_can_do(). + * + * \note The key is also checked for correctness. + * + * \return 0 if successful, or a specific PK or PEM error code + */ +int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx, + const char *path, const char *password ); + +/** \ingroup pk_module */ +/** + * \brief Load and parse a public key + * + * \param ctx The PK context to fill. It must have been initialized + * but not set up. + * \param path filename to read the public key from + * + * \note On entry, ctx must be empty, either freshly initialised + * with mbedtls_pk_init() or reset with mbedtls_pk_free(). If + * you need a specific key type, check the result with + * mbedtls_pk_can_do(). + * + * \note The key is also checked for correctness. + * + * \return 0 if successful, or a specific PK or PEM error code + */ +int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path ); +#endif /* MBEDTLS_FS_IO */ +#endif /* MBEDTLS_PK_PARSE_C */ + +#if defined(MBEDTLS_PK_WRITE_C) +/** + * \brief Write a private key to a PKCS#1 or SEC1 DER structure + * Note: data is written at the end of the buffer! Use the + * return value to determine where you should start + * using the buffer + * + * \param ctx PK context which must contain a valid private key. + * \param buf buffer to write to + * \param size size of the buffer + * + * \return length of data written if successful, or a specific + * error code + */ +int mbedtls_pk_write_key_der( mbedtls_pk_context *ctx, unsigned char *buf, size_t size ); + +/** + * \brief Write a public key to a SubjectPublicKeyInfo DER structure + * Note: data is written at the end of the buffer! Use the + * return value to determine where you should start + * using the buffer + * + * \param ctx PK context which must contain a valid public or private key. + * \param buf buffer to write to + * \param size size of the buffer + * + * \return length of data written if successful, or a specific + * error code + */ +int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *ctx, unsigned char *buf, size_t size ); + +#if defined(MBEDTLS_PEM_WRITE_C) +/** + * \brief Write a public key to a PEM string + * + * \param ctx PK context which must contain a valid public or private key. + * \param buf Buffer to write to. The output includes a + * terminating null byte. + * \param size Size of the buffer in bytes. + * + * \return 0 if successful, or a specific error code + */ +int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *ctx, unsigned char *buf, size_t size ); + +/** + * \brief Write a private key to a PKCS#1 or SEC1 PEM string + * + * \param ctx PK context which must contain a valid private key. + * \param buf Buffer to write to. The output includes a + * terminating null byte. + * \param size Size of the buffer in bytes. + * + * \return 0 if successful, or a specific error code + */ +int mbedtls_pk_write_key_pem( mbedtls_pk_context *ctx, unsigned char *buf, size_t size ); +#endif /* MBEDTLS_PEM_WRITE_C */ +#endif /* MBEDTLS_PK_WRITE_C */ + +/* + * WARNING: Low-level functions. You probably do not want to use these unless + * you are certain you do ;) + */ + +#if defined(MBEDTLS_PK_PARSE_C) +/** + * \brief Parse a SubjectPublicKeyInfo DER structure + * + * \param p the position in the ASN.1 data + * \param end end of the buffer + * \param pk The PK context to fill. It must have been initialized + * but not set up. + * + * \return 0 if successful, or a specific PK error code + */ +int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end, + mbedtls_pk_context *pk ); +#endif /* MBEDTLS_PK_PARSE_C */ + +#if defined(MBEDTLS_PK_WRITE_C) +/** + * \brief Write a subjectPublicKey to ASN.1 data + * Note: function works backwards in data buffer + * + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param key PK context which must contain a valid public or private key. + * + * \return the length written or a negative error code + */ +int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start, + const mbedtls_pk_context *key ); +#endif /* MBEDTLS_PK_WRITE_C */ + +/* + * Internal module functions. You probably do not want to use these unless you + * know you do. + */ +#if defined(MBEDTLS_FS_IO) +int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n ); +#endif + +#if defined(MBEDTLS_USE_PSA_CRYPTO) +/** + * \brief Turn an EC key into an opaque one. + * + * \warning This is a temporary utility function for tests. It might + * change or be removed at any time without notice. + * + * \note Only ECDSA keys are supported so far. Signing with the + * specified hash is the only allowed use of that key. + * + * \param pk Input: the EC key to import to a PSA key. + * Output: a PK context wrapping that PSA key. + * \param key Output: a PSA key identifier. + * It's the caller's responsibility to call + * psa_destroy_key() on that key identifier after calling + * mbedtls_pk_free() on the PK context. + * \param hash_alg The hash algorithm to allow for use with that key. + * + * \return \c 0 if successful. + * \return An Mbed TLS error code otherwise. + */ +int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk, + psa_key_id_t *key, + psa_algorithm_t hash_alg ); +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_PK_H */ diff --git a/third_party/mbedtls/include/mbedtls/platform_time.h b/third_party/mbedtls/include/mbedtls/platform_time.h new file mode 100644 index 0000000..9405571 --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/platform_time.h @@ -0,0 +1,72 @@ +/** + * \file platform_time.h + * + * \brief mbed TLS Platform time abstraction + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBEDTLS_PLATFORM_TIME_H +#define MBEDTLS_PLATFORM_TIME_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The time_t datatype + */ +#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) +typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t; +#else +/* For time_t */ +#include +typedef time_t mbedtls_time_t; +#endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */ + +/* + * The function pointers for time + */ +#if defined(MBEDTLS_PLATFORM_TIME_ALT) +extern mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* time ); + +/** + * \brief Set your own time function pointer + * + * \param time_func the time function implementation + * + * \return 0 + */ +int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* time ) ); +#else +#if defined(MBEDTLS_PLATFORM_TIME_MACRO) +#define mbedtls_time MBEDTLS_PLATFORM_TIME_MACRO +#else +#define mbedtls_time time +#endif /* MBEDTLS_PLATFORM_TIME_MACRO */ +#endif /* MBEDTLS_PLATFORM_TIME_ALT */ + +#ifdef __cplusplus +} +#endif + +#endif /* platform_time.h */ diff --git a/third_party/mbedtls/include/mbedtls/platform_util.h b/third_party/mbedtls/include/mbedtls/platform_util.h new file mode 100644 index 0000000..cd112ab --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/platform_util.h @@ -0,0 +1,283 @@ +/** + * \file platform_util.h + * + * \brief Common and shared functions used by multiple modules in the Mbed TLS + * library. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBEDTLS_PLATFORM_UTIL_H +#define MBEDTLS_PLATFORM_UTIL_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include +#if defined(MBEDTLS_HAVE_TIME_DATE) +#include "mbedtls/platform_time.h" +#include +#endif /* MBEDTLS_HAVE_TIME_DATE */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(MBEDTLS_CHECK_PARAMS) + +#if defined(MBEDTLS_CHECK_PARAMS_ASSERT) +/* Allow the user to define MBEDTLS_PARAM_FAILED to something like assert + * (which is what our config.h suggests). */ +#include +#endif /* MBEDTLS_CHECK_PARAMS_ASSERT */ + +#if defined(MBEDTLS_PARAM_FAILED) +/** An alternative definition of MBEDTLS_PARAM_FAILED has been set in config.h. + * + * This flag can be used to check whether it is safe to assume that + * MBEDTLS_PARAM_FAILED() will expand to a call to mbedtls_param_failed(). + */ +#define MBEDTLS_PARAM_FAILED_ALT + +#elif defined(MBEDTLS_CHECK_PARAMS_ASSERT) +#define MBEDTLS_PARAM_FAILED( cond ) assert( cond ) +#define MBEDTLS_PARAM_FAILED_ALT + +#else /* MBEDTLS_PARAM_FAILED */ +#define MBEDTLS_PARAM_FAILED( cond ) \ + mbedtls_param_failed( #cond, __FILE__, __LINE__ ) + +/** + * \brief User supplied callback function for parameter validation failure. + * See #MBEDTLS_CHECK_PARAMS for context. + * + * This function will be called unless an alternative treatment + * is defined through the #MBEDTLS_PARAM_FAILED macro. + * + * This function can return, and the operation will be aborted, or + * alternatively, through use of setjmp()/longjmp() can resume + * execution in the application code. + * + * \param failure_condition The assertion that didn't hold. + * \param file The file where the assertion failed. + * \param line The line in the file where the assertion failed. + */ +void mbedtls_param_failed( const char *failure_condition, + const char *file, + int line ); +#endif /* MBEDTLS_PARAM_FAILED */ + +/* Internal macro meant to be called only from within the library. */ +#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) \ + do { \ + if( !(cond) ) \ + { \ + MBEDTLS_PARAM_FAILED( cond ); \ + return( ret ); \ + } \ + } while( 0 ) + +/* Internal macro meant to be called only from within the library. */ +#define MBEDTLS_INTERNAL_VALIDATE( cond ) \ + do { \ + if( !(cond) ) \ + { \ + MBEDTLS_PARAM_FAILED( cond ); \ + return; \ + } \ + } while( 0 ) + +#else /* MBEDTLS_CHECK_PARAMS */ + +/* Internal macros meant to be called only from within the library. */ +#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret ) do { } while( 0 ) +#define MBEDTLS_INTERNAL_VALIDATE( cond ) do { } while( 0 ) + +#endif /* MBEDTLS_CHECK_PARAMS */ + +/* Internal helper macros for deprecating API constants. */ +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +/* Deliberately don't (yet) export MBEDTLS_DEPRECATED here + * to avoid conflict with other headers which define and use + * it, too. We might want to move all these definitions here at + * some point for uniformity. */ +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +MBEDTLS_DEPRECATED typedef char const * mbedtls_deprecated_string_constant_t; +#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) \ + ( (mbedtls_deprecated_string_constant_t) ( VAL ) ) +MBEDTLS_DEPRECATED typedef int mbedtls_deprecated_numeric_constant_t; +#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) \ + ( (mbedtls_deprecated_numeric_constant_t) ( VAL ) ) +#undef MBEDTLS_DEPRECATED +#else /* MBEDTLS_DEPRECATED_WARNING */ +#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) VAL +#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) VAL +#endif /* MBEDTLS_DEPRECATED_WARNING */ +#endif /* MBEDTLS_DEPRECATED_REMOVED */ + +/* Implementation of the check-return facility. + * See the user documentation in config.h. + * + * Do not use this macro directly to annotate function: instead, + * use one of MBEDTLS_CHECK_RETURN_CRITICAL or MBEDTLS_CHECK_RETURN_TYPICAL + * depending on how important it is to check the return value. + */ +#if !defined(MBEDTLS_CHECK_RETURN) +#if defined(__GNUC__) +#define MBEDTLS_CHECK_RETURN __attribute__((__warn_unused_result__)) +#elif defined(_MSC_VER) && _MSC_VER >= 1700 +#include +#define MBEDTLS_CHECK_RETURN _Check_return_ +#else +#define MBEDTLS_CHECK_RETURN +#endif +#endif + +/** Critical-failure function + * + * This macro appearing at the beginning of the declaration of a function + * indicates that its return value should be checked in all applications. + * Omitting the check is very likely to indicate a bug in the application + * and will result in a compile-time warning if #MBEDTLS_CHECK_RETURN + * is implemented for the compiler in use. + * + * \note The use of this macro is a work in progress. + * This macro may be added to more functions in the future. + * Such an extension is not considered an API break, provided that + * there are near-unavoidable circumstances under which the function + * can fail. For example, signature/MAC/AEAD verification functions, + * and functions that require a random generator, are considered + * return-check-critical. + */ +#define MBEDTLS_CHECK_RETURN_CRITICAL MBEDTLS_CHECK_RETURN + +/** Ordinary-failure function + * + * This macro appearing at the beginning of the declaration of a function + * indicates that its return value should be generally be checked in portable + * applications. Omitting the check will result in a compile-time warning if + * #MBEDTLS_CHECK_RETURN is implemented for the compiler in use and + * #MBEDTLS_CHECK_RETURN_WARNING is enabled in the compile-time configuration. + * + * You can use #MBEDTLS_IGNORE_RETURN to explicitly ignore the return value + * of a function that is annotated with #MBEDTLS_CHECK_RETURN. + * + * \note The use of this macro is a work in progress. + * This macro will be added to more functions in the future. + * Eventually this should appear before most functions returning + * an error code (as \c int in the \c mbedtls_xxx API or + * as ::psa_status_t in the \c psa_xxx API). + */ +#if defined(MBEDTLS_CHECK_RETURN_WARNING) +#define MBEDTLS_CHECK_RETURN_TYPICAL MBEDTLS_CHECK_RETURN +#else +#define MBEDTLS_CHECK_RETURN_TYPICAL +#endif + +/** Benign-failure function + * + * This macro appearing at the beginning of the declaration of a function + * indicates that it is rarely useful to check its return value. + * + * This macro has an empty expansion. It exists for documentation purposes: + * a #MBEDTLS_CHECK_RETURN_OPTIONAL annotation indicates that the function + * has been analyzed for return-check usefulness, whereas the lack of + * an annotation indicates that the function has not been analyzed and its + * return-check usefulness is unknown. + */ +#define MBEDTLS_CHECK_RETURN_OPTIONAL + +/** \def MBEDTLS_IGNORE_RETURN + * + * Call this macro with one argument, a function call, to suppress a warning + * from #MBEDTLS_CHECK_RETURN due to that function call. + */ +#if !defined(MBEDTLS_IGNORE_RETURN) +/* GCC doesn't silence the warning with just (void)(result). + * (void)!(result) is known to work up at least up to GCC 10, as well + * as with Clang and MSVC. + * + * https://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Non_002dbugs.html + * https://stackoverflow.com/questions/40576003/ignoring-warning-wunused-result + * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425#c34 + */ +#define MBEDTLS_IGNORE_RETURN(result) ( (void) !( result ) ) +#endif + +/** + * \brief Securely zeroize a buffer + * + * The function is meant to wipe the data contained in a buffer so + * that it can no longer be recovered even if the program memory + * is later compromised. Call this function on sensitive data + * stored on the stack before returning from a function, and on + * sensitive data stored on the heap before freeing the heap + * object. + * + * It is extremely difficult to guarantee that calls to + * mbedtls_platform_zeroize() are not removed by aggressive + * compiler optimizations in a portable way. For this reason, Mbed + * TLS provides the configuration option + * MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure + * mbedtls_platform_zeroize() to use a suitable implementation for + * their platform and needs + * + * \param buf Buffer to be zeroized + * \param len Length of the buffer in bytes + * + */ +void mbedtls_platform_zeroize( void *buf, size_t len ); + +#if defined(MBEDTLS_HAVE_TIME_DATE) +/** + * \brief Platform-specific implementation of gmtime_r() + * + * The function is a thread-safe abstraction that behaves + * similarly to the gmtime_r() function from Unix/POSIX. + * + * Mbed TLS will try to identify the underlying platform and + * make use of an appropriate underlying implementation (e.g. + * gmtime_r() for POSIX and gmtime_s() for Windows). If this is + * not possible, then gmtime() will be used. In this case, calls + * from the library to gmtime() will be guarded by the mutex + * mbedtls_threading_gmtime_mutex if MBEDTLS_THREADING_C is + * enabled. It is recommended that calls from outside the library + * are also guarded by this mutex. + * + * If MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, then Mbed TLS will + * unconditionally use the alternative implementation for + * mbedtls_platform_gmtime_r() supplied by the user at compile time. + * + * \param tt Pointer to an object containing time (in seconds) since the + * epoch to be converted + * \param tm_buf Pointer to an object where the results will be stored + * + * \return Pointer to an object of type struct tm on success, otherwise + * NULL + */ +struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt, + struct tm *tm_buf ); +#endif /* MBEDTLS_HAVE_TIME_DATE */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_PLATFORM_UTIL_H */ diff --git a/third_party/mbedtls/include/mbedtls/rsa.h b/third_party/mbedtls/include/mbedtls/rsa.h new file mode 100644 index 0000000..062df73 --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/rsa.h @@ -0,0 +1,1351 @@ +/** + * \file rsa.h + * + * \brief This file provides an API for the RSA public-key cryptosystem. + * + * The RSA public-key cryptosystem is defined in Public-Key + * Cryptography Standards (PKCS) #1 v1.5: RSA Encryption + * and Public-Key Cryptography Standards (PKCS) #1 v2.1: + * RSA Cryptography Specifications. + * + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBEDTLS_RSA_H +#define MBEDTLS_RSA_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/bignum.h" +#include "mbedtls/md.h" + +#if defined(MBEDTLS_THREADING_C) +#include "mbedtls/threading.h" +#endif + +/* + * RSA Error codes + */ +/** Bad input parameters to function. */ +#define MBEDTLS_ERR_RSA_BAD_INPUT_DATA -0x4080 +/** Input data contains invalid padding and is rejected. */ +#define MBEDTLS_ERR_RSA_INVALID_PADDING -0x4100 +/** Something failed during generation of a key. */ +#define MBEDTLS_ERR_RSA_KEY_GEN_FAILED -0x4180 +/** Key failed to pass the validity check of the library. */ +#define MBEDTLS_ERR_RSA_KEY_CHECK_FAILED -0x4200 +/** The public key operation failed. */ +#define MBEDTLS_ERR_RSA_PUBLIC_FAILED -0x4280 +/** The private key operation failed. */ +#define MBEDTLS_ERR_RSA_PRIVATE_FAILED -0x4300 +/** The PKCS#1 verification failed. */ +#define MBEDTLS_ERR_RSA_VERIFY_FAILED -0x4380 +/** The output buffer for decryption is not large enough. */ +#define MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE -0x4400 +/** The random generator failed to generate non-zeros. */ +#define MBEDTLS_ERR_RSA_RNG_FAILED -0x4480 + +/* MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION is deprecated and should not be used. + */ +/** The implementation does not offer the requested operation, for example, because of security violations or lack of functionality. */ +#define MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION -0x4500 + +/* MBEDTLS_ERR_RSA_HW_ACCEL_FAILED is deprecated and should not be used. */ +/** RSA hardware accelerator failed. */ +#define MBEDTLS_ERR_RSA_HW_ACCEL_FAILED -0x4580 + +/* + * RSA constants + */ +#define MBEDTLS_RSA_PUBLIC 0 /**< Request private key operation. */ +#define MBEDTLS_RSA_PRIVATE 1 /**< Request public key operation. */ + +#define MBEDTLS_RSA_PKCS_V15 0 /**< Use PKCS#1 v1.5 encoding. */ +#define MBEDTLS_RSA_PKCS_V21 1 /**< Use PKCS#1 v2.1 encoding. */ + +#define MBEDTLS_RSA_SIGN 1 /**< Identifier for RSA signature operations. */ +#define MBEDTLS_RSA_CRYPT 2 /**< Identifier for RSA encryption and decryption operations. */ + +#define MBEDTLS_RSA_SALT_LEN_ANY -1 + +/* + * The above constants may be used even if the RSA module is compile out, + * eg for alternative (PKCS#11) RSA implementations in the PK layers. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(MBEDTLS_RSA_ALT) +// Regular implementation +// + +/** + * \brief The RSA context structure. + * + * \note Direct manipulation of the members of this structure + * is deprecated. All manipulation should instead be done through + * the public interface functions. + */ +typedef struct mbedtls_rsa_context +{ + int ver; /*!< Reserved for internal purposes. + * Do not set this field in application + * code. Its meaning might change without + * notice. */ + size_t len; /*!< The size of \p N in Bytes. */ + + mbedtls_mpi N; /*!< The public modulus. */ + mbedtls_mpi E; /*!< The public exponent. */ + + mbedtls_mpi D; /*!< The private exponent. */ + mbedtls_mpi P; /*!< The first prime factor. */ + mbedtls_mpi Q; /*!< The second prime factor. */ + + mbedtls_mpi DP; /*!< D % (P - 1). */ + mbedtls_mpi DQ; /*!< D % (Q - 1). */ + mbedtls_mpi QP; /*!< 1 / (Q % P). */ + + mbedtls_mpi RN; /*!< cached R^2 mod N. */ + + mbedtls_mpi RP; /*!< cached R^2 mod P. */ + mbedtls_mpi RQ; /*!< cached R^2 mod Q. */ + + mbedtls_mpi Vi; /*!< The cached blinding value. */ + mbedtls_mpi Vf; /*!< The cached un-blinding value. */ + + int padding; /*!< Selects padding mode: + #MBEDTLS_RSA_PKCS_V15 for 1.5 padding and + #MBEDTLS_RSA_PKCS_V21 for OAEP or PSS. */ + int hash_id; /*!< Hash identifier of mbedtls_md_type_t type, + as specified in md.h for use in the MGF + mask generating function used in the + EME-OAEP and EMSA-PSS encodings. */ +#if defined(MBEDTLS_THREADING_C) + /* Invariant: the mutex is initialized iff ver != 0. */ + mbedtls_threading_mutex_t mutex; /*!< Thread-safety mutex. */ +#endif +} +mbedtls_rsa_context; + +#else /* MBEDTLS_RSA_ALT */ +#include "rsa_alt.h" +#endif /* MBEDTLS_RSA_ALT */ + +/** + * \brief This function initializes an RSA context. + * + * \note Set padding to #MBEDTLS_RSA_PKCS_V21 for the RSAES-OAEP + * encryption scheme and the RSASSA-PSS signature scheme. + * + * \note The \p hash_id parameter is ignored when using + * #MBEDTLS_RSA_PKCS_V15 padding. + * + * \note The choice of padding mode is strictly enforced for private key + * operations, since there might be security concerns in + * mixing padding modes. For public key operations it is + * a default value, which can be overridden by calling specific + * \c rsa_rsaes_xxx or \c rsa_rsassa_xxx functions. + * + * \note The hash selected in \p hash_id is always used for OEAP + * encryption. For PSS signatures, it is always used for + * making signatures, but can be overridden for verifying them. + * If set to #MBEDTLS_MD_NONE, it is always overridden. + * + * \param ctx The RSA context to initialize. This must not be \c NULL. + * \param padding The padding mode to use. This must be either + * #MBEDTLS_RSA_PKCS_V15 or #MBEDTLS_RSA_PKCS_V21. + * \param hash_id The hash identifier of ::mbedtls_md_type_t type, if + * \p padding is #MBEDTLS_RSA_PKCS_V21. It is unused + * otherwise. + */ +void mbedtls_rsa_init( mbedtls_rsa_context *ctx, + int padding, + int hash_id ); + +/** + * \brief This function imports a set of core parameters into an + * RSA context. + * + * \note This function can be called multiple times for successive + * imports, if the parameters are not simultaneously present. + * + * Any sequence of calls to this function should be followed + * by a call to mbedtls_rsa_complete(), which checks and + * completes the provided information to a ready-for-use + * public or private RSA key. + * + * \note See mbedtls_rsa_complete() for more information on which + * parameters are necessary to set up a private or public + * RSA key. + * + * \note The imported parameters are copied and need not be preserved + * for the lifetime of the RSA context being set up. + * + * \param ctx The initialized RSA context to store the parameters in. + * \param N The RSA modulus. This may be \c NULL. + * \param P The first prime factor of \p N. This may be \c NULL. + * \param Q The second prime factor of \p N. This may be \c NULL. + * \param D The private exponent. This may be \c NULL. + * \param E The public exponent. This may be \c NULL. + * + * \return \c 0 on success. + * \return A non-zero error code on failure. + */ +int mbedtls_rsa_import( mbedtls_rsa_context *ctx, + const mbedtls_mpi *N, + const mbedtls_mpi *P, const mbedtls_mpi *Q, + const mbedtls_mpi *D, const mbedtls_mpi *E ); + +/** + * \brief This function imports core RSA parameters, in raw big-endian + * binary format, into an RSA context. + * + * \note This function can be called multiple times for successive + * imports, if the parameters are not simultaneously present. + * + * Any sequence of calls to this function should be followed + * by a call to mbedtls_rsa_complete(), which checks and + * completes the provided information to a ready-for-use + * public or private RSA key. + * + * \note See mbedtls_rsa_complete() for more information on which + * parameters are necessary to set up a private or public + * RSA key. + * + * \note The imported parameters are copied and need not be preserved + * for the lifetime of the RSA context being set up. + * + * \param ctx The initialized RSA context to store the parameters in. + * \param N The RSA modulus. This may be \c NULL. + * \param N_len The Byte length of \p N; it is ignored if \p N == NULL. + * \param P The first prime factor of \p N. This may be \c NULL. + * \param P_len The Byte length of \p P; it ns ignored if \p P == NULL. + * \param Q The second prime factor of \p N. This may be \c NULL. + * \param Q_len The Byte length of \p Q; it is ignored if \p Q == NULL. + * \param D The private exponent. This may be \c NULL. + * \param D_len The Byte length of \p D; it is ignored if \p D == NULL. + * \param E The public exponent. This may be \c NULL. + * \param E_len The Byte length of \p E; it is ignored if \p E == NULL. + * + * \return \c 0 on success. + * \return A non-zero error code on failure. + */ +int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx, + unsigned char const *N, size_t N_len, + unsigned char const *P, size_t P_len, + unsigned char const *Q, size_t Q_len, + unsigned char const *D, size_t D_len, + unsigned char const *E, size_t E_len ); + +/** + * \brief This function completes an RSA context from + * a set of imported core parameters. + * + * To setup an RSA public key, precisely \p N and \p E + * must have been imported. + * + * To setup an RSA private key, sufficient information must + * be present for the other parameters to be derivable. + * + * The default implementation supports the following: + *
  • Derive \p P, \p Q from \p N, \p D, \p E.
  • + *
  • Derive \p N, \p D from \p P, \p Q, \p E.
+ * Alternative implementations need not support these. + * + * If this function runs successfully, it guarantees that + * the RSA context can be used for RSA operations without + * the risk of failure or crash. + * + * \warning This function need not perform consistency checks + * for the imported parameters. In particular, parameters that + * are not needed by the implementation might be silently + * discarded and left unchecked. To check the consistency + * of the key material, see mbedtls_rsa_check_privkey(). + * + * \param ctx The initialized RSA context holding imported parameters. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_RSA_BAD_INPUT_DATA if the attempted derivations + * failed. + * + */ +int mbedtls_rsa_complete( mbedtls_rsa_context *ctx ); + +/** + * \brief This function exports the core parameters of an RSA key. + * + * If this function runs successfully, the non-NULL buffers + * pointed to by \p N, \p P, \p Q, \p D, and \p E are fully + * written, with additional unused space filled leading by + * zero Bytes. + * + * Possible reasons for returning + * #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:
    + *
  • An alternative RSA implementation is in use, which + * stores the key externally, and either cannot or should + * not export it into RAM.
  • + *
  • A SW or HW implementation might not support a certain + * deduction. For example, \p P, \p Q from \p N, \p D, + * and \p E if the former are not part of the + * implementation.
+ * + * If the function fails due to an unsupported operation, + * the RSA context stays intact and remains usable. + * + * \param ctx The initialized RSA context. + * \param N The MPI to hold the RSA modulus. + * This may be \c NULL if this field need not be exported. + * \param P The MPI to hold the first prime factor of \p N. + * This may be \c NULL if this field need not be exported. + * \param Q The MPI to hold the second prime factor of \p N. + * This may be \c NULL if this field need not be exported. + * \param D The MPI to hold the private exponent. + * This may be \c NULL if this field need not be exported. + * \param E The MPI to hold the public exponent. + * This may be \c NULL if this field need not be exported. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED if exporting the + * requested parameters cannot be done due to missing + * functionality or because of security policies. + * \return A non-zero return code on any other failure. + * + */ +int mbedtls_rsa_export( const mbedtls_rsa_context *ctx, + mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q, + mbedtls_mpi *D, mbedtls_mpi *E ); + +/** + * \brief This function exports core parameters of an RSA key + * in raw big-endian binary format. + * + * If this function runs successfully, the non-NULL buffers + * pointed to by \p N, \p P, \p Q, \p D, and \p E are fully + * written, with additional unused space filled leading by + * zero Bytes. + * + * Possible reasons for returning + * #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:
    + *
  • An alternative RSA implementation is in use, which + * stores the key externally, and either cannot or should + * not export it into RAM.
  • + *
  • A SW or HW implementation might not support a certain + * deduction. For example, \p P, \p Q from \p N, \p D, + * and \p E if the former are not part of the + * implementation.
+ * If the function fails due to an unsupported operation, + * the RSA context stays intact and remains usable. + * + * \note The length parameters are ignored if the corresponding + * buffer pointers are NULL. + * + * \param ctx The initialized RSA context. + * \param N The Byte array to store the RSA modulus, + * or \c NULL if this field need not be exported. + * \param N_len The size of the buffer for the modulus. + * \param P The Byte array to hold the first prime factor of \p N, + * or \c NULL if this field need not be exported. + * \param P_len The size of the buffer for the first prime factor. + * \param Q The Byte array to hold the second prime factor of \p N, + * or \c NULL if this field need not be exported. + * \param Q_len The size of the buffer for the second prime factor. + * \param D The Byte array to hold the private exponent, + * or \c NULL if this field need not be exported. + * \param D_len The size of the buffer for the private exponent. + * \param E The Byte array to hold the public exponent, + * or \c NULL if this field need not be exported. + * \param E_len The size of the buffer for the public exponent. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED if exporting the + * requested parameters cannot be done due to missing + * functionality or because of security policies. + * \return A non-zero return code on any other failure. + */ +int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx, + unsigned char *N, size_t N_len, + unsigned char *P, size_t P_len, + unsigned char *Q, size_t Q_len, + unsigned char *D, size_t D_len, + unsigned char *E, size_t E_len ); + +/** + * \brief This function exports CRT parameters of a private RSA key. + * + * \note Alternative RSA implementations not using CRT-parameters + * internally can implement this function based on + * mbedtls_rsa_deduce_opt(). + * + * \param ctx The initialized RSA context. + * \param DP The MPI to hold \c D modulo `P-1`, + * or \c NULL if it need not be exported. + * \param DQ The MPI to hold \c D modulo `Q-1`, + * or \c NULL if it need not be exported. + * \param QP The MPI to hold modular inverse of \c Q modulo \c P, + * or \c NULL if it need not be exported. + * + * \return \c 0 on success. + * \return A non-zero error code on failure. + * + */ +int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx, + mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP ); + +/** + * \brief This function sets padding for an already initialized RSA + * context. See mbedtls_rsa_init() for details. + * + * \param ctx The initialized RSA context to be configured. + * \param padding The padding mode to use. This must be either + * #MBEDTLS_RSA_PKCS_V15 or #MBEDTLS_RSA_PKCS_V21. + * \param hash_id The #MBEDTLS_RSA_PKCS_V21 hash identifier. + */ +void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, + int hash_id ); + +/** + * \brief This function retrieves the length of RSA modulus in Bytes. + * + * \param ctx The initialized RSA context. + * + * \return The length of the RSA modulus in Bytes. + * + */ +size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx ); + +/** + * \brief This function generates an RSA keypair. + * + * \note mbedtls_rsa_init() must be called before this function, + * to set up the RSA context. + * + * \param ctx The initialized RSA context used to hold the key. + * \param f_rng The RNG function to be used for key generation. + * This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. + * This may be \c NULL if \p f_rng doesn't need a context. + * \param nbits The size of the public key in bits. + * \param exponent The public exponent to use. For example, \c 65537. + * This must be odd and greater than \c 1. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + unsigned int nbits, int exponent ); + +/** + * \brief This function checks if a context contains at least an RSA + * public key. + * + * If the function runs successfully, it is guaranteed that + * enough information is present to perform an RSA public key + * operation using mbedtls_rsa_public(). + * + * \param ctx The initialized RSA context to check. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + * + */ +int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx ); + +/** + * \brief This function checks if a context contains an RSA private key + * and perform basic consistency checks. + * + * \note The consistency checks performed by this function not only + * ensure that mbedtls_rsa_private() can be called successfully + * on the given context, but that the various parameters are + * mutually consistent with high probability, in the sense that + * mbedtls_rsa_public() and mbedtls_rsa_private() are inverses. + * + * \warning This function should catch accidental misconfigurations + * like swapping of parameters, but it cannot establish full + * trust in neither the quality nor the consistency of the key + * material that was used to setup the given RSA context: + *
  • Consistency: Imported parameters that are irrelevant + * for the implementation might be silently dropped. If dropped, + * the current function does not have access to them, + * and therefore cannot check them. See mbedtls_rsa_complete(). + * If you want to check the consistency of the entire + * content of an PKCS1-encoded RSA private key, for example, you + * should use mbedtls_rsa_validate_params() before setting + * up the RSA context. + * Additionally, if the implementation performs empirical checks, + * these checks substantiate but do not guarantee consistency.
  • + *
  • Quality: This function is not expected to perform + * extended quality assessments like checking that the prime + * factors are safe. Additionally, it is the responsibility of the + * user to ensure the trustworthiness of the source of his RSA + * parameters, which goes beyond what is effectively checkable + * by the library.
+ * + * \param ctx The initialized RSA context to check. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx ); + +/** + * \brief This function checks a public-private RSA key pair. + * + * It checks each of the contexts, and makes sure they match. + * + * \param pub The initialized RSA context holding the public key. + * \param prv The initialized RSA context holding the private key. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, + const mbedtls_rsa_context *prv ); + +/** + * \brief This function performs an RSA public key operation. + * + * \param ctx The initialized RSA context to use. + * \param input The input buffer. This must be a readable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * \param output The output buffer. This must be a writable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * + * \note This function does not handle message padding. + * + * \note Make sure to set \p input[0] = 0 or ensure that + * input is smaller than \p N. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_public( mbedtls_rsa_context *ctx, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief This function performs an RSA private key operation. + * + * \note Blinding is used if and only if a PRNG is provided. + * + * \note If blinding is used, both the base of exponentiation + * and the exponent are blinded, providing protection + * against some side-channel attacks. + * + * \warning It is deprecated and a security risk to not provide + * a PRNG here and thereby prevent the use of blinding. + * Future versions of the library may enforce the presence + * of a PRNG. + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG function, used for blinding. It is discouraged + * and deprecated to pass \c NULL here, in which case + * blinding will be omitted. + * \param p_rng The RNG context to pass to \p f_rng. This may be \c NULL + * if \p f_rng is \c NULL or if \p f_rng doesn't need a context. + * \param input The input buffer. This must be a readable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * \param output The output buffer. This must be a writable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + * + */ +int mbedtls_rsa_private( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief This function adds the message padding, then performs an RSA + * operation. + * + * It is the generic wrapper for performing a PKCS#1 encryption + * operation using the \p mode from the context. + * + * \deprecated It is deprecated and discouraged to call this function + * in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library + * are likely to remove the \p mode argument and have it + * implicitly set to #MBEDTLS_RSA_PUBLIC. + * + * \note Alternative implementations of RSA need not support + * mode being set to #MBEDTLS_RSA_PRIVATE and might instead + * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG to use. It is mandatory for PKCS#1 v2.1 padding + * encoding, and for PKCS#1 v1.5 padding encoding when used + * with \p mode set to #MBEDTLS_RSA_PUBLIC. For PKCS#1 v1.5 + * padding encoding and \p mode set to #MBEDTLS_RSA_PRIVATE, + * it is used for blinding and should be provided in this + * case; see mbedtls_rsa_private() for more. + * \param p_rng The RNG context to be passed to \p f_rng. May be + * \c NULL if \p f_rng is \c NULL or if \p f_rng doesn't + * need a context argument. + * \param mode The mode of operation. This must be either + * #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). + * \param ilen The length of the plaintext in Bytes. + * \param input The input data to encrypt. This must be a readable + * buffer of size \p ilen Bytes. It may be \c NULL if + * `ilen == 0`. + * \param output The output buffer. This must be a writable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, size_t ilen, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief This function performs a PKCS#1 v1.5 encryption operation + * (RSAES-PKCS1-v1_5-ENCRYPT). + * + * \deprecated It is deprecated and discouraged to call this function + * in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library + * are likely to remove the \p mode argument and have it + * implicitly set to #MBEDTLS_RSA_PUBLIC. + * + * \note Alternative implementations of RSA need not support + * mode being set to #MBEDTLS_RSA_PRIVATE and might instead + * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG function to use. It is needed for padding generation + * if \p mode is #MBEDTLS_RSA_PUBLIC. If \p mode is + * #MBEDTLS_RSA_PRIVATE (discouraged), it is used for + * blinding and should be provided; see mbedtls_rsa_private(). + * \param p_rng The RNG context to be passed to \p f_rng. This may + * be \c NULL if \p f_rng is \c NULL or if \p f_rng + * doesn't need a context argument. + * \param mode The mode of operation. This must be either + * #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). + * \param ilen The length of the plaintext in Bytes. + * \param input The input data to encrypt. This must be a readable + * buffer of size \p ilen Bytes. It may be \c NULL if + * `ilen == 0`. + * \param output The output buffer. This must be a writable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, size_t ilen, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief This function performs a PKCS#1 v2.1 OAEP encryption + * operation (RSAES-OAEP-ENCRYPT). + * + * \note The output buffer must be as large as the size + * of ctx->N. For example, 128 Bytes if RSA-1024 is used. + * + * \deprecated It is deprecated and discouraged to call this function + * in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library + * are likely to remove the \p mode argument and have it + * implicitly set to #MBEDTLS_RSA_PUBLIC. + * + * \note Alternative implementations of RSA need not support + * mode being set to #MBEDTLS_RSA_PRIVATE and might instead + * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG function to use. This is needed for padding + * generation and must be provided. + * \param p_rng The RNG context to be passed to \p f_rng. This may + * be \c NULL if \p f_rng doesn't need a context argument. + * \param mode The mode of operation. This must be either + * #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). + * \param label The buffer holding the custom label to use. + * This must be a readable buffer of length \p label_len + * Bytes. It may be \c NULL if \p label_len is \c 0. + * \param label_len The length of the label in Bytes. + * \param ilen The length of the plaintext buffer \p input in Bytes. + * \param input The input data to encrypt. This must be a readable + * buffer of size \p ilen Bytes. It may be \c NULL if + * `ilen == 0`. + * \param output The output buffer. This must be a writable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + const unsigned char *label, size_t label_len, + size_t ilen, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief This function performs an RSA operation, then removes the + * message padding. + * + * It is the generic wrapper for performing a PKCS#1 decryption + * operation using the \p mode from the context. + * + * \note The output buffer length \c output_max_len should be + * as large as the size \p ctx->len of \p ctx->N (for example, + * 128 Bytes if RSA-1024 is used) to be able to hold an + * arbitrary decrypted message. If it is not large enough to + * hold the decryption of the particular ciphertext provided, + * the function returns \c MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. + * + * \deprecated It is deprecated and discouraged to call this function + * in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library + * are likely to remove the \p mode argument and have it + * implicitly set to #MBEDTLS_RSA_PRIVATE. + * + * \note Alternative implementations of RSA need not support + * mode being set to #MBEDTLS_RSA_PUBLIC and might instead + * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE, + * this is used for blinding and should be provided; see + * mbedtls_rsa_private() for more. If \p mode is + * #MBEDTLS_RSA_PUBLIC, it is ignored. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng is \c NULL or doesn't need a context. + * \param mode The mode of operation. This must be either + * #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). + * \param olen The address at which to store the length of + * the plaintext. This must not be \c NULL. + * \param input The ciphertext buffer. This must be a readable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * \param output The buffer used to hold the plaintext. This must + * be a writable buffer of length \p output_max_len Bytes. + * \param output_max_len The length in Bytes of the output buffer \p output. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len ); + +/** + * \brief This function performs a PKCS#1 v1.5 decryption + * operation (RSAES-PKCS1-v1_5-DECRYPT). + * + * \note The output buffer length \c output_max_len should be + * as large as the size \p ctx->len of \p ctx->N, for example, + * 128 Bytes if RSA-1024 is used, to be able to hold an + * arbitrary decrypted message. If it is not large enough to + * hold the decryption of the particular ciphertext provided, + * the function returns #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. + * + * \deprecated It is deprecated and discouraged to call this function + * in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library + * are likely to remove the \p mode argument and have it + * implicitly set to #MBEDTLS_RSA_PRIVATE. + * + * \note Alternative implementations of RSA need not support + * mode being set to #MBEDTLS_RSA_PUBLIC and might instead + * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE, + * this is used for blinding and should be provided; see + * mbedtls_rsa_private() for more. If \p mode is + * #MBEDTLS_RSA_PUBLIC, it is ignored. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng is \c NULL or doesn't need a context. + * \param mode The mode of operation. This must be either + * #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). + * \param olen The address at which to store the length of + * the plaintext. This must not be \c NULL. + * \param input The ciphertext buffer. This must be a readable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * \param output The buffer used to hold the plaintext. This must + * be a writable buffer of length \p output_max_len Bytes. + * \param output_max_len The length in Bytes of the output buffer \p output. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + * + */ +int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len ); + +/** + * \brief This function performs a PKCS#1 v2.1 OAEP decryption + * operation (RSAES-OAEP-DECRYPT). + * + * \note The output buffer length \c output_max_len should be + * as large as the size \p ctx->len of \p ctx->N, for + * example, 128 Bytes if RSA-1024 is used, to be able to + * hold an arbitrary decrypted message. If it is not + * large enough to hold the decryption of the particular + * ciphertext provided, the function returns + * #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. + * + * \deprecated It is deprecated and discouraged to call this function + * in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library + * are likely to remove the \p mode argument and have it + * implicitly set to #MBEDTLS_RSA_PRIVATE. + * + * \note Alternative implementations of RSA need not support + * mode being set to #MBEDTLS_RSA_PUBLIC and might instead + * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE, + * this is used for blinding and should be provided; see + * mbedtls_rsa_private() for more. If \p mode is + * #MBEDTLS_RSA_PUBLIC, it is ignored. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng is \c NULL or doesn't need a context. + * \param mode The mode of operation. This must be either + * #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). + * \param label The buffer holding the custom label to use. + * This must be a readable buffer of length \p label_len + * Bytes. It may be \c NULL if \p label_len is \c 0. + * \param label_len The length of the label in Bytes. + * \param olen The address at which to store the length of + * the plaintext. This must not be \c NULL. + * \param input The ciphertext buffer. This must be a readable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * \param output The buffer used to hold the plaintext. This must + * be a writable buffer of length \p output_max_len Bytes. + * \param output_max_len The length in Bytes of the output buffer \p output. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + const unsigned char *label, size_t label_len, + size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len ); + +/** + * \brief This function performs a private RSA operation to sign + * a message digest using PKCS#1. + * + * It is the generic wrapper for performing a PKCS#1 + * signature using the \p mode from the context. + * + * \note The \p sig buffer must be as large as the size + * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. + * + * \note For PKCS#1 v2.1 encoding, see comments on + * mbedtls_rsa_rsassa_pss_sign() for details on + * \p md_alg and \p hash_id. + * + * \deprecated It is deprecated and discouraged to call this function + * in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library + * are likely to remove the \p mode argument and have it + * implicitly set to #MBEDTLS_RSA_PRIVATE. + * + * \note Alternative implementations of RSA need not support + * mode being set to #MBEDTLS_RSA_PUBLIC and might instead + * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG function to use. If the padding mode is PKCS#1 v2.1, + * this must be provided. If the padding mode is PKCS#1 v1.5 and + * \p mode is #MBEDTLS_RSA_PRIVATE, it is used for blinding + * and should be provided; see mbedtls_rsa_private() for more + * more. It is ignored otherwise. + * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL + * if \p f_rng is \c NULL or doesn't need a context argument. + * \param mode The mode of operation. This must be either + * #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest. + * Ths is only used if \p md_alg is #MBEDTLS_MD_NONE. + * \param hash The buffer holding the message digest or raw data. + * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable + * buffer of length \p hashlen Bytes. If \p md_alg is not + * #MBEDTLS_MD_NONE, it must be a readable buffer of length + * the size of the hash corresponding to \p md_alg. + * \param sig The buffer to hold the signature. This must be a writable + * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. A buffer length of + * #MBEDTLS_MPI_MAX_SIZE is always safe. + * + * \return \c 0 if the signing operation was successful. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ); + +/** + * \brief This function performs a PKCS#1 v1.5 signature + * operation (RSASSA-PKCS1-v1_5-SIGN). + * + * \deprecated It is deprecated and discouraged to call this function + * in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library + * are likely to remove the \p mode argument and have it + * implicitly set to #MBEDTLS_RSA_PRIVATE. + * + * \note Alternative implementations of RSA need not support + * mode being set to #MBEDTLS_RSA_PUBLIC and might instead + * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE, + * this is used for blinding and should be provided; see + * mbedtls_rsa_private() for more. If \p mode is + * #MBEDTLS_RSA_PUBLIC, it is ignored. + * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL + * if \p f_rng is \c NULL or doesn't need a context argument. + * \param mode The mode of operation. This must be either + * #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest. + * Ths is only used if \p md_alg is #MBEDTLS_MD_NONE. + * \param hash The buffer holding the message digest or raw data. + * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable + * buffer of length \p hashlen Bytes. If \p md_alg is not + * #MBEDTLS_MD_NONE, it must be a readable buffer of length + * the size of the hash corresponding to \p md_alg. + * \param sig The buffer to hold the signature. This must be a writable + * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. A buffer length of + * #MBEDTLS_MPI_MAX_SIZE is always safe. + * + * \return \c 0 if the signing operation was successful. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ); + +/** + * \brief This function performs a PKCS#1 v2.1 PSS signature + * operation (RSASSA-PSS-SIGN). + * + * \note The \c hash_id set in \p ctx (when calling + * mbedtls_rsa_init() or by calling mbedtls_rsa_set_padding() + * afterwards) selects the hash used for the + * encoding operation and for the mask generation function + * (MGF1). For more details on the encoding operation and the + * mask generation function, consult RFC-3447: Public-Key + * Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography + * Specifications. + * + * \note This function enforces that the provided salt length complies + * with FIPS 186-4 §5.5 (e) and RFC 8017 (PKCS#1 v2.2) §9.1.1 + * step 3. The constraint is that the hash length plus the salt + * length plus 2 bytes must be at most the key length. If this + * constraint is not met, this function returns + * #MBEDTLS_ERR_RSA_BAD_INPUT_DATA. + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG function. It must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL + * if \p f_rng doesn't need a context argument. + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest. + * Ths is only used if \p md_alg is #MBEDTLS_MD_NONE. + * \param hash The buffer holding the message digest or raw data. + * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable + * buffer of length \p hashlen Bytes. If \p md_alg is not + * #MBEDTLS_MD_NONE, it must be a readable buffer of length + * the size of the hash corresponding to \p md_alg. + * \param saltlen The length of the salt that should be used. + * If passed #MBEDTLS_RSA_SALT_LEN_ANY, the function will use + * the largest possible salt length up to the hash length, + * which is the largest permitted by some standards including + * FIPS 186-4 §5.5. + * \param sig The buffer to hold the signature. This must be a writable + * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. A buffer length of + * #MBEDTLS_MPI_MAX_SIZE is always safe. + * + * \return \c 0 if the signing operation was successful. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_rsassa_pss_sign_ext( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + int saltlen, + unsigned char *sig ); + +/** + * \brief This function performs a PKCS#1 v2.1 PSS signature + * operation (RSASSA-PSS-SIGN). + * + * \note The \c hash_id set in \p ctx (when calling + * mbedtls_rsa_init() or by calling mbedtls_rsa_set_padding() + * afterwards) selects the hash used for the + * encoding operation and for the mask generation function + * (MGF1). For more details on the encoding operation and the + * mask generation function, consult RFC-3447: Public-Key + * Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography + * Specifications. + * + * \note This function always uses the maximum possible salt size, + * up to the length of the payload hash. This choice of salt + * size complies with FIPS 186-4 §5.5 (e) and RFC 8017 (PKCS#1 + * v2.2) §9.1.1 step 3. Furthermore this function enforces a + * minimum salt size which is the hash size minus 2 bytes. If + * this minimum size is too large given the key size (the salt + * size, plus the hash size, plus 2 bytes must be no more than + * the key size in bytes), this function returns + * #MBEDTLS_ERR_RSA_BAD_INPUT_DATA. + * + * \deprecated It is deprecated and discouraged to call this function + * in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library + * are likely to remove the \p mode argument and have it + * implicitly set to #MBEDTLS_RSA_PRIVATE. + * + * \note Alternative implementations of RSA need not support + * mode being set to #MBEDTLS_RSA_PUBLIC and might instead + * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG function. It must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL + * if \p f_rng doesn't need a context argument. + * \param mode The mode of operation. This must be either + * #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest. + * This is only used if \p md_alg is #MBEDTLS_MD_NONE. + * \param hash The buffer holding the message digest or raw data. + * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable + * buffer of length \p hashlen Bytes. If \p md_alg is not + * #MBEDTLS_MD_NONE, it must be a readable buffer of length + * the size of the hash corresponding to \p md_alg. + * \param sig The buffer to hold the signature. This must be a writable + * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. A buffer length of + * #MBEDTLS_MPI_MAX_SIZE is always safe. + * + * \return \c 0 if the signing operation was successful. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ); + +/** + * \brief This function performs a public RSA operation and checks + * the message digest. + * + * This is the generic wrapper for performing a PKCS#1 + * verification using the mode from the context. + * + * \note For PKCS#1 v2.1 encoding, see comments on + * mbedtls_rsa_rsassa_pss_verify() about \p md_alg and + * \p hash_id. + * + * \deprecated It is deprecated and discouraged to call this function + * in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library + * are likely to remove the \p mode argument and have it + * set to #MBEDTLS_RSA_PUBLIC. + * + * \note Alternative implementations of RSA need not support + * mode being set to #MBEDTLS_RSA_PRIVATE and might instead + * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * + * \param ctx The initialized RSA public key context to use. + * \param f_rng The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE, + * this is used for blinding and should be provided; see + * mbedtls_rsa_private() for more. Otherwise, it is ignored. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng is \c NULL or doesn't need a context. + * \param mode The mode of operation. This must be either + * #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest. + * This is only used if \p md_alg is #MBEDTLS_MD_NONE. + * \param hash The buffer holding the message digest or raw data. + * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable + * buffer of length \p hashlen Bytes. If \p md_alg is not + * #MBEDTLS_MD_NONE, it must be a readable buffer of length + * the size of the hash corresponding to \p md_alg. + * \param sig The buffer holding the signature. This must be a readable + * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * + * \return \c 0 if the verify operation was successful. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + const unsigned char *sig ); + +/** + * \brief This function performs a PKCS#1 v1.5 verification + * operation (RSASSA-PKCS1-v1_5-VERIFY). + * + * \deprecated It is deprecated and discouraged to call this function + * in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library + * are likely to remove the \p mode argument and have it + * set to #MBEDTLS_RSA_PUBLIC. + * + * \note Alternative implementations of RSA need not support + * mode being set to #MBEDTLS_RSA_PRIVATE and might instead + * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * + * \param ctx The initialized RSA public key context to use. + * \param f_rng The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE, + * this is used for blinding and should be provided; see + * mbedtls_rsa_private() for more. Otherwise, it is ignored. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng is \c NULL or doesn't need a context. + * \param mode The mode of operation. This must be either + * #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest. + * This is only used if \p md_alg is #MBEDTLS_MD_NONE. + * \param hash The buffer holding the message digest or raw data. + * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable + * buffer of length \p hashlen Bytes. If \p md_alg is not + * #MBEDTLS_MD_NONE, it must be a readable buffer of length + * the size of the hash corresponding to \p md_alg. + * \param sig The buffer holding the signature. This must be a readable + * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * + * \return \c 0 if the verify operation was successful. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + const unsigned char *sig ); + +/** + * \brief This function performs a PKCS#1 v2.1 PSS verification + * operation (RSASSA-PSS-VERIFY). + * + * \note The \c hash_id set in \p ctx (when calling + * mbedtls_rsa_init() or by calling mbedtls_rsa_set_padding() + * afterwards) selects the hash used for the + * encoding operation and for the mask generation function + * (MGF1). For more details on the encoding operation and the + * mask generation function, consult RFC-3447: Public-Key + * Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography + * Specifications. If the \c hash_id set in \p ctx is + * #MBEDTLS_MD_NONE, the \p md_alg parameter is used. + * + * \deprecated It is deprecated and discouraged to call this function + * in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library + * are likely to remove the \p mode argument and have it + * implicitly set to #MBEDTLS_RSA_PUBLIC. + * + * \note Alternative implementations of RSA need not support + * mode being set to #MBEDTLS_RSA_PRIVATE and might instead + * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * + * \param ctx The initialized RSA public key context to use. + * \param f_rng The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE, + * this is used for blinding and should be provided; see + * mbedtls_rsa_private() for more. Otherwise, it is ignored. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng is \c NULL or doesn't need a context. + * \param mode The mode of operation. This must be either + * #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated). + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest. + * This is only used if \p md_alg is #MBEDTLS_MD_NONE. + * \param hash The buffer holding the message digest or raw data. + * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable + * buffer of length \p hashlen Bytes. If \p md_alg is not + * #MBEDTLS_MD_NONE, it must be a readable buffer of length + * the size of the hash corresponding to \p md_alg. + * \param sig The buffer holding the signature. This must be a readable + * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * + * \return \c 0 if the verify operation was successful. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + const unsigned char *sig ); + +/** + * \brief This function performs a PKCS#1 v2.1 PSS verification + * operation (RSASSA-PSS-VERIFY). + * + * \note The \p sig buffer must be as large as the size + * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. + * + * \note The \c hash_id set in \p ctx (when calling + * mbedtls_rsa_init() or by calling mbedtls_rsa_set_padding() + * afterwards) is ignored. + * + * \param ctx The initialized RSA public key context to use. + * \param f_rng The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE, + * this is used for blinding and should be provided; see + * mbedtls_rsa_private() for more. Otherwise, it is ignored. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng is \c NULL or doesn't need a context. + * \param mode The mode of operation. This must be either + * #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE. + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest. + * This is only used if \p md_alg is #MBEDTLS_MD_NONE. + * \param hash The buffer holding the message digest or raw data. + * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable + * buffer of length \p hashlen Bytes. If \p md_alg is not + * #MBEDTLS_MD_NONE, it must be a readable buffer of length + * the size of the hash corresponding to \p md_alg. + * \param mgf1_hash_id The message digest algorithm used for the + * verification operation and the mask generation + * function (MGF1). For more details on the encoding + * operation and the mask generation function, consult + * RFC-3447: Public-Key Cryptography Standards + * (PKCS) #1 v2.1: RSA Cryptography + * Specifications. + * \param expected_salt_len The length of the salt used in padding. Use + * #MBEDTLS_RSA_SALT_LEN_ANY to accept any salt length. + * \param sig The buffer holding the signature. This must be a readable + * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * + * \return \c 0 if the verify operation was successful. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + mbedtls_md_type_t mgf1_hash_id, + int expected_salt_len, + const unsigned char *sig ); + +/** + * \brief This function copies the components of an RSA context. + * + * \param dst The destination context. This must be initialized. + * \param src The source context. This must be initialized. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory allocation failure. + */ +int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src ); + +/** + * \brief This function frees the components of an RSA key. + * + * \param ctx The RSA context to free. May be \c NULL, in which case + * this function is a no-op. If it is not \c NULL, it must + * point to an initialized RSA context. + */ +void mbedtls_rsa_free( mbedtls_rsa_context *ctx ); + +#if defined(MBEDTLS_SELF_TEST) + +/** + * \brief The RSA checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +int mbedtls_rsa_self_test( int verbose ); + +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + +#endif /* rsa.h */ diff --git a/third_party/mbedtls/include/mbedtls/sha512.h b/third_party/mbedtls/include/mbedtls/sha512.h new file mode 100644 index 0000000..cca47c2 --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/sha512.h @@ -0,0 +1,316 @@ +/** + * \file sha512.h + * \brief This file contains SHA-384 and SHA-512 definitions and functions. + * + * The Secure Hash Algorithms 384 and 512 (SHA-384 and SHA-512) cryptographic + * hash functions are defined in FIPS 180-4: Secure Hash Standard (SHS). + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBEDTLS_SHA512_H +#define MBEDTLS_SHA512_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include +#include + +/* MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED is deprecated and should not be used. */ +/** SHA-512 hardware accelerator failed */ +#define MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED -0x0039 +/** SHA-512 input data was malformed. */ +#define MBEDTLS_ERR_SHA512_BAD_INPUT_DATA -0x0075 + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(MBEDTLS_SHA512_ALT) +// Regular implementation +// + +/** + * \brief The SHA-512 context structure. + * + * The structure is used both for SHA-384 and for SHA-512 + * checksum calculations. The choice between these two is + * made in the call to mbedtls_sha512_starts_ret(). + */ +typedef struct mbedtls_sha512_context +{ + uint64_t total[2]; /*!< The number of Bytes processed. */ + uint64_t state[8]; /*!< The intermediate digest state. */ + unsigned char buffer[128]; /*!< The data block being processed. */ +#if !defined(MBEDTLS_SHA512_NO_SHA384) + int is384; /*!< Determines which function to use: + 0: Use SHA-512, or 1: Use SHA-384. */ +#endif +} +mbedtls_sha512_context; + +#else /* MBEDTLS_SHA512_ALT */ +#include "sha512_alt.h" +#endif /* MBEDTLS_SHA512_ALT */ + +/** + * \brief This function initializes a SHA-512 context. + * + * \param ctx The SHA-512 context to initialize. This must + * not be \c NULL. + */ +void mbedtls_sha512_init( mbedtls_sha512_context *ctx ); + +/** + * \brief This function clears a SHA-512 context. + * + * \param ctx The SHA-512 context to clear. This may be \c NULL, + * in which case this function does nothing. If it + * is not \c NULL, it must point to an initialized + * SHA-512 context. + */ +void mbedtls_sha512_free( mbedtls_sha512_context *ctx ); + +/** + * \brief This function clones the state of a SHA-512 context. + * + * \param dst The destination context. This must be initialized. + * \param src The context to clone. This must be initialized. + */ +void mbedtls_sha512_clone( mbedtls_sha512_context *dst, + const mbedtls_sha512_context *src ); + +/** + * \brief This function starts a SHA-384 or SHA-512 checksum + * calculation. + * + * \param ctx The SHA-512 context to use. This must be initialized. + * \param is384 Determines which function to use. This must be + * either \c 0 for SHA-512, or \c 1 for SHA-384. + * + * \note When \c MBEDTLS_SHA512_NO_SHA384 is defined, \p is384 must + * be \c 0, or the function will return + * #MBEDTLS_ERR_SHA512_BAD_INPUT_DATA. + * + * \return \c 0 on success. + * \return A negative error code on failure. + */ +int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 ); + +/** + * \brief This function feeds an input buffer into an ongoing + * SHA-512 checksum calculation. + * + * \param ctx The SHA-512 context. This must be initialized + * and have a hash operation started. + * \param input The buffer holding the input data. This must + * be a readable buffer of length \p ilen Bytes. + * \param ilen The length of the input data in Bytes. + * + * \return \c 0 on success. + * \return A negative error code on failure. + */ +int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, + const unsigned char *input, + size_t ilen ); + +/** + * \brief This function finishes the SHA-512 operation, and writes + * the result to the output buffer. + * + * \param ctx The SHA-512 context. This must be initialized + * and have a hash operation started. + * \param output The SHA-384 or SHA-512 checksum result. + * This must be a writable buffer of length \c 64 Bytes. + * + * \return \c 0 on success. + * \return A negative error code on failure. + */ +int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, + unsigned char output[64] ); + +/** + * \brief This function processes a single data block within + * the ongoing SHA-512 computation. + * This function is for internal use only. + * + * \param ctx The SHA-512 context. This must be initialized. + * \param data The buffer holding one block of data. This + * must be a readable buffer of length \c 128 Bytes. + * + * \return \c 0 on success. + * \return A negative error code on failure. + */ +int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, + const unsigned char data[128] ); +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif +/** + * \brief This function starts a SHA-384 or SHA-512 checksum + * calculation. + * + * \deprecated Superseded by mbedtls_sha512_starts_ret() in 2.7.0 + * + * \param ctx The SHA-512 context to use. This must be initialized. + * \param is384 Determines which function to use. This must be either + * \c 0 for SHA-512 or \c 1 for SHA-384. + * + * \note When \c MBEDTLS_SHA512_NO_SHA384 is defined, \p is384 must + * be \c 0, or the function will fail to work. + */ +MBEDTLS_DEPRECATED void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, + int is384 ); + +/** + * \brief This function feeds an input buffer into an ongoing + * SHA-512 checksum calculation. + * + * \deprecated Superseded by mbedtls_sha512_update_ret() in 2.7.0. + * + * \param ctx The SHA-512 context. This must be initialized + * and have a hash operation started. + * \param input The buffer holding the data. This must be a readable + * buffer of length \p ilen Bytes. + * \param ilen The length of the input data in Bytes. + */ +MBEDTLS_DEPRECATED void mbedtls_sha512_update( mbedtls_sha512_context *ctx, + const unsigned char *input, + size_t ilen ); + +/** + * \brief This function finishes the SHA-512 operation, and writes + * the result to the output buffer. + * + * \deprecated Superseded by mbedtls_sha512_finish_ret() in 2.7.0. + * + * \param ctx The SHA-512 context. This must be initialized + * and have a hash operation started. + * \param output The SHA-384 or SHA-512 checksum result. This must + * be a writable buffer of size \c 64 Bytes. + */ +MBEDTLS_DEPRECATED void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, + unsigned char output[64] ); + +/** + * \brief This function processes a single data block within + * the ongoing SHA-512 computation. This function is for + * internal use only. + * + * \deprecated Superseded by mbedtls_internal_sha512_process() in 2.7.0. + * + * \param ctx The SHA-512 context. This must be initialized. + * \param data The buffer holding one block of data. This must be + * a readable buffer of length \c 128 Bytes. + */ +MBEDTLS_DEPRECATED void mbedtls_sha512_process( + mbedtls_sha512_context *ctx, + const unsigned char data[128] ); + +#undef MBEDTLS_DEPRECATED +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ + +/** + * \brief This function calculates the SHA-512 or SHA-384 + * checksum of a buffer. + * + * The function allocates the context, performs the + * calculation, and frees the context. + * + * The SHA-512 result is calculated as + * output = SHA-512(input buffer). + * + * \param input The buffer holding the input data. This must be + * a readable buffer of length \p ilen Bytes. + * \param ilen The length of the input data in Bytes. + * \param output The SHA-384 or SHA-512 checksum result. + * This must be a writable buffer of length \c 64 Bytes. + * \param is384 Determines which function to use. This must be either + * \c 0 for SHA-512, or \c 1 for SHA-384. + * + * \note When \c MBEDTLS_SHA512_NO_SHA384 is defined, \p is384 must + * be \c 0, or the function will return + * #MBEDTLS_ERR_SHA512_BAD_INPUT_DATA. + * + * \return \c 0 on success. + * \return A negative error code on failure. + */ +int mbedtls_sha512_ret( const unsigned char *input, + size_t ilen, + unsigned char output[64], + int is384 ); + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif + +/** + * \brief This function calculates the SHA-512 or SHA-384 + * checksum of a buffer. + * + * The function allocates the context, performs the + * calculation, and frees the context. + * + * The SHA-512 result is calculated as + * output = SHA-512(input buffer). + * + * \deprecated Superseded by mbedtls_sha512_ret() in 2.7.0 + * + * \param input The buffer holding the data. This must be a + * readable buffer of length \p ilen Bytes. + * \param ilen The length of the input data in Bytes. + * \param output The SHA-384 or SHA-512 checksum result. This must + * be a writable buffer of length \c 64 Bytes. + * \param is384 Determines which function to use. This must be either + * \c 0 for SHA-512, or \c 1 for SHA-384. + * + * \note When \c MBEDTLS_SHA512_NO_SHA384 is defined, \p is384 must + * be \c 0, or the function will fail to work. + */ +MBEDTLS_DEPRECATED void mbedtls_sha512( const unsigned char *input, + size_t ilen, + unsigned char output[64], + int is384 ); + +#undef MBEDTLS_DEPRECATED +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ + +#if defined(MBEDTLS_SELF_TEST) + + /** + * \brief The SHA-384 or SHA-512 checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +int mbedtls_sha512_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + +#endif /* mbedtls_sha512.h */ diff --git a/third_party/mbedtls/include/mbedtls/ssl.h b/third_party/mbedtls/include/mbedtls/ssl.h new file mode 100644 index 0000000..5064ec5 --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/ssl.h @@ -0,0 +1,4427 @@ +/** + * \file ssl.h + * + * \brief SSL/TLS functions. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBEDTLS_SSL_H +#define MBEDTLS_SSL_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/bignum.h" +#include "mbedtls/ecp.h" + +#include "mbedtls/ssl_ciphersuites.h" + +#if defined(MBEDTLS_X509_CRT_PARSE_C) +#include "mbedtls/x509_crt.h" +#include "mbedtls/x509_crl.h" +#endif + +#if defined(MBEDTLS_DHM_C) +#include "mbedtls/dhm.h" +#endif + +/* Adding guard for MBEDTLS_ECDSA_C to ensure no compile errors due + * to guards also being in ssl_srv.c and ssl_cli.c. There is a gap + * in functionality that access to ecdh_ctx structure is needed for + * MBEDTLS_ECDSA_C which does not seem correct. + */ +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) +#include "mbedtls/ecdh.h" +#endif + +#if defined(MBEDTLS_ZLIB_SUPPORT) + +#if defined(MBEDTLS_DEPRECATED_WARNING) +#warning "Record compression support via MBEDTLS_ZLIB_SUPPORT is deprecated and will be removed in the next major revision of the library" +#endif + +#if defined(MBEDTLS_DEPRECATED_REMOVED) +#error "Record compression support via MBEDTLS_ZLIB_SUPPORT is deprecated and cannot be used if MBEDTLS_DEPRECATED_REMOVED is set" +#endif + +#include "zlib.h" +#endif + +#if defined(MBEDTLS_HAVE_TIME) +#include "mbedtls/platform_time.h" +#endif + +#if defined(MBEDTLS_USE_PSA_CRYPTO) +#include "psa/crypto.h" +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +/* + * SSL Error codes + */ +/** The requested feature is not available. */ +#define MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE -0x7080 +/** Bad input parameters to function. */ +#define MBEDTLS_ERR_SSL_BAD_INPUT_DATA -0x7100 +/** Verification of the message MAC failed. */ +#define MBEDTLS_ERR_SSL_INVALID_MAC -0x7180 +/** An invalid SSL record was received. */ +#define MBEDTLS_ERR_SSL_INVALID_RECORD -0x7200 +/** The connection indicated an EOF. */ +#define MBEDTLS_ERR_SSL_CONN_EOF -0x7280 +/** An unknown cipher was received. */ +#define MBEDTLS_ERR_SSL_UNKNOWN_CIPHER -0x7300 +/** The server has no ciphersuites in common with the client. */ +#define MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN -0x7380 +/** No RNG was provided to the SSL module. */ +#define MBEDTLS_ERR_SSL_NO_RNG -0x7400 +/** No client certification received from the client, but required by the authentication mode. */ +#define MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE -0x7480 +/** Our own certificate(s) is/are too large to send in an SSL message. */ +#define MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE -0x7500 +/** The own certificate is not set, but needed by the server. */ +#define MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED -0x7580 +/** The own private key or pre-shared key is not set, but needed. */ +#define MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED -0x7600 +/** No CA Chain is set, but required to operate. */ +#define MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED -0x7680 +/** An unexpected message was received from our peer. */ +#define MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE -0x7700 +/** A fatal alert message was received from our peer. */ +#define MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE -0x7780 +/** Verification of our peer failed. */ +#define MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED -0x7800 +/** The peer notified us that the connection is going to be closed. */ +#define MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY -0x7880 +/** Processing of the ClientHello handshake message failed. */ +#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO -0x7900 +/** Processing of the ServerHello handshake message failed. */ +#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO -0x7980 +/** Processing of the Certificate handshake message failed. */ +#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE -0x7A00 +/** Processing of the CertificateRequest handshake message failed. */ +#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST -0x7A80 +/** Processing of the ServerKeyExchange handshake message failed. */ +#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE -0x7B00 +/** Processing of the ServerHelloDone handshake message failed. */ +#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE -0x7B80 +/** Processing of the ClientKeyExchange handshake message failed. */ +#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE -0x7C00 +/** Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public. */ +#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP -0x7C80 +/** Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret. */ +#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS -0x7D00 +/** Processing of the CertificateVerify handshake message failed. */ +#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY -0x7D80 +/** Processing of the ChangeCipherSpec handshake message failed. */ +#define MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC -0x7E00 +/** Processing of the Finished handshake message failed. */ +#define MBEDTLS_ERR_SSL_BAD_HS_FINISHED -0x7E80 +/** Memory allocation failed */ +#define MBEDTLS_ERR_SSL_ALLOC_FAILED -0x7F00 +/** Hardware acceleration function returned with error */ +#define MBEDTLS_ERR_SSL_HW_ACCEL_FAILED -0x7F80 +/** Hardware acceleration function skipped / left alone data */ +#define MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH -0x6F80 +/** Processing of the compression / decompression failed */ +#define MBEDTLS_ERR_SSL_COMPRESSION_FAILED -0x6F00 +/** Handshake protocol not within min/max boundaries */ +#define MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION -0x6E80 +/** Processing of the NewSessionTicket handshake message failed. */ +#define MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET -0x6E00 +/** Session ticket has expired. */ +#define MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED -0x6D80 +/** Public key type mismatch (eg, asked for RSA key exchange and presented EC key) */ +#define MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH -0x6D00 +/** Unknown identity received (eg, PSK identity) */ +#define MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY -0x6C80 +/** Internal error (eg, unexpected failure in lower-level module) */ +#define MBEDTLS_ERR_SSL_INTERNAL_ERROR -0x6C00 +/** A counter would wrap (eg, too many messages exchanged). */ +#define MBEDTLS_ERR_SSL_COUNTER_WRAPPING -0x6B80 +/** Unexpected message at ServerHello in renegotiation. */ +#define MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO -0x6B00 +/** DTLS client must retry for hello verification */ +#define MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED -0x6A80 +/** A buffer is too small to receive or write a message */ +#define MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL -0x6A00 +/** None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages). */ +#define MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE -0x6980 +/** No data of requested type currently available on underlying transport. */ +#define MBEDTLS_ERR_SSL_WANT_READ -0x6900 +/** Connection requires a write call. */ +#define MBEDTLS_ERR_SSL_WANT_WRITE -0x6880 +/** The operation timed out. */ +#define MBEDTLS_ERR_SSL_TIMEOUT -0x6800 +/** The client initiated a reconnect from the same port. */ +#define MBEDTLS_ERR_SSL_CLIENT_RECONNECT -0x6780 +/** Record header looks valid but is not expected. */ +#define MBEDTLS_ERR_SSL_UNEXPECTED_RECORD -0x6700 +/** The alert message received indicates a non-fatal error. */ +#define MBEDTLS_ERR_SSL_NON_FATAL -0x6680 +/** Couldn't set the hash for verifying CertificateVerify */ +#define MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH -0x6600 +/** Internal-only message signaling that further message-processing should be done */ +#define MBEDTLS_ERR_SSL_CONTINUE_PROCESSING -0x6580 +/** The asynchronous operation is not completed yet. */ +#define MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS -0x6500 +/** Internal-only message signaling that a message arrived early. */ +#define MBEDTLS_ERR_SSL_EARLY_MESSAGE -0x6480 +/** An encrypted DTLS-frame with an unexpected CID was received. */ +#define MBEDTLS_ERR_SSL_UNEXPECTED_CID -0x6000 +/** An operation failed due to an unexpected version or configuration. */ +#define MBEDTLS_ERR_SSL_VERSION_MISMATCH -0x5F00 +/** A cryptographic operation is in progress. Try again later. */ +#define MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS -0x7000 +/** Invalid value in SSL config */ +#define MBEDTLS_ERR_SSL_BAD_CONFIG -0x5E80 + +/* + * Various constants + */ +#define MBEDTLS_SSL_MAJOR_VERSION_3 3 +#define MBEDTLS_SSL_MINOR_VERSION_0 0 /*!< SSL v3.0 */ +#define MBEDTLS_SSL_MINOR_VERSION_1 1 /*!< TLS v1.0 */ +#define MBEDTLS_SSL_MINOR_VERSION_2 2 /*!< TLS v1.1 */ +#define MBEDTLS_SSL_MINOR_VERSION_3 3 /*!< TLS v1.2 */ +#define MBEDTLS_SSL_MINOR_VERSION_4 4 /*!< TLS v1.3 (experimental) */ + +#define MBEDTLS_SSL_TRANSPORT_STREAM 0 /*!< TLS */ +#define MBEDTLS_SSL_TRANSPORT_DATAGRAM 1 /*!< DTLS */ + +#define MBEDTLS_SSL_MAX_HOST_NAME_LEN 255 /*!< Maximum host name defined in RFC 1035 */ +#define MBEDTLS_SSL_MAX_ALPN_NAME_LEN 255 /*!< Maximum size in bytes of a protocol name in alpn ext., RFC 7301 */ + +#define MBEDTLS_SSL_MAX_ALPN_LIST_LEN 65535 /*!< Maximum size in bytes of list in alpn ext., RFC 7301 */ + +/* RFC 6066 section 4, see also mfl_code_to_length in ssl_tls.c + * NONE must be zero so that memset()ing structure to zero works */ +#define MBEDTLS_SSL_MAX_FRAG_LEN_NONE 0 /*!< don't use this extension */ +#define MBEDTLS_SSL_MAX_FRAG_LEN_512 1 /*!< MaxFragmentLength 2^9 */ +#define MBEDTLS_SSL_MAX_FRAG_LEN_1024 2 /*!< MaxFragmentLength 2^10 */ +#define MBEDTLS_SSL_MAX_FRAG_LEN_2048 3 /*!< MaxFragmentLength 2^11 */ +#define MBEDTLS_SSL_MAX_FRAG_LEN_4096 4 /*!< MaxFragmentLength 2^12 */ +#define MBEDTLS_SSL_MAX_FRAG_LEN_INVALID 5 /*!< first invalid value */ + +#define MBEDTLS_SSL_IS_CLIENT 0 +#define MBEDTLS_SSL_IS_SERVER 1 + +#define MBEDTLS_SSL_IS_NOT_FALLBACK 0 +#define MBEDTLS_SSL_IS_FALLBACK 1 + +#define MBEDTLS_SSL_EXTENDED_MS_DISABLED 0 +#define MBEDTLS_SSL_EXTENDED_MS_ENABLED 1 + +#define MBEDTLS_SSL_CID_DISABLED 0 +#define MBEDTLS_SSL_CID_ENABLED 1 + +#define MBEDTLS_SSL_ETM_DISABLED 0 +#define MBEDTLS_SSL_ETM_ENABLED 1 + +#define MBEDTLS_SSL_COMPRESS_NULL 0 +#define MBEDTLS_SSL_COMPRESS_DEFLATE 1 + +#define MBEDTLS_SSL_VERIFY_NONE 0 +#define MBEDTLS_SSL_VERIFY_OPTIONAL 1 +#define MBEDTLS_SSL_VERIFY_REQUIRED 2 +#define MBEDTLS_SSL_VERIFY_UNSET 3 /* Used only for sni_authmode */ + +#define MBEDTLS_SSL_LEGACY_RENEGOTIATION 0 +#define MBEDTLS_SSL_SECURE_RENEGOTIATION 1 + +#define MBEDTLS_SSL_RENEGOTIATION_DISABLED 0 +#define MBEDTLS_SSL_RENEGOTIATION_ENABLED 1 + +#define MBEDTLS_SSL_ANTI_REPLAY_DISABLED 0 +#define MBEDTLS_SSL_ANTI_REPLAY_ENABLED 1 + +#define MBEDTLS_SSL_RENEGOTIATION_NOT_ENFORCED -1 +#define MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT 16 + +#define MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION 0 +#define MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION 1 +#define MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE 2 + +#define MBEDTLS_SSL_TRUNC_HMAC_DISABLED 0 +#define MBEDTLS_SSL_TRUNC_HMAC_ENABLED 1 +#define MBEDTLS_SSL_TRUNCATED_HMAC_LEN 10 /* 80 bits, rfc 6066 section 7 */ + +#define MBEDTLS_SSL_SESSION_TICKETS_DISABLED 0 +#define MBEDTLS_SSL_SESSION_TICKETS_ENABLED 1 + +#define MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED 0 +#define MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED 1 + +#define MBEDTLS_SSL_ARC4_ENABLED 0 +#define MBEDTLS_SSL_ARC4_DISABLED 1 + +#define MBEDTLS_SSL_PRESET_DEFAULT 0 +#define MBEDTLS_SSL_PRESET_SUITEB 2 + +#define MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED 1 +#define MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED 0 + +#define MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED 0 +#define MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED 1 + +/* + * Default range for DTLS retransmission timer value, in milliseconds. + * RFC 6347 4.2.4.1 says from 1 second to 60 seconds. + */ +#define MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN 1000 +#define MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX 60000 + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME) +#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ +#endif + +/* + * Maximum fragment length in bytes, + * determines the size of each of the two internal I/O buffers. + * + * Note: the RFC defines the default size of SSL / TLS messages. If you + * change the value here, other clients / servers may not be able to + * communicate with you anymore. Only change this value if you control + * both sides of the connection and have it reduced at both sides, or + * if you're using the Max Fragment Length extension and you know all your + * peers are using it too! + */ +#if !defined(MBEDTLS_SSL_MAX_CONTENT_LEN) +#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 /**< Size of the input / output buffer */ +#endif + +#if !defined(MBEDTLS_SSL_IN_CONTENT_LEN) +#define MBEDTLS_SSL_IN_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN +#endif + +#if !defined(MBEDTLS_SSL_OUT_CONTENT_LEN) +#define MBEDTLS_SSL_OUT_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN +#endif + +/* + * Maximum number of heap-allocated bytes for the purpose of + * DTLS handshake message reassembly and future message buffering. + */ +#if !defined(MBEDTLS_SSL_DTLS_MAX_BUFFERING) +#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768 +#endif + +/* + * Maximum length of CIDs for incoming and outgoing messages. + */ +#if !defined(MBEDTLS_SSL_CID_IN_LEN_MAX) +#define MBEDTLS_SSL_CID_IN_LEN_MAX 32 +#endif + +#if !defined(MBEDTLS_SSL_CID_OUT_LEN_MAX) +#define MBEDTLS_SSL_CID_OUT_LEN_MAX 32 +#endif + +#if !defined(MBEDTLS_SSL_CID_PADDING_GRANULARITY) +#define MBEDTLS_SSL_CID_PADDING_GRANULARITY 16 +#endif + +#if !defined(MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY) +#define MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY 1 +#endif + +/** \} name SECTION: Module settings */ + +/* + * Length of the verify data for secure renegotiation + */ +#if defined(MBEDTLS_SSL_PROTO_SSL3) +#define MBEDTLS_SSL_VERIFY_DATA_MAX_LEN 36 +#else +#define MBEDTLS_SSL_VERIFY_DATA_MAX_LEN 12 +#endif + +/* + * Signaling ciphersuite values (SCSV) + */ +#define MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO 0xFF /**< renegotiation info ext */ +#define MBEDTLS_SSL_FALLBACK_SCSV_VALUE 0x5600 /**< RFC 7507 section 2 */ + +/* + * Supported Signature and Hash algorithms (For TLS 1.2) + * RFC 5246 section 7.4.1.4.1 + */ +#define MBEDTLS_SSL_HASH_NONE 0 +#define MBEDTLS_SSL_HASH_MD5 1 +#define MBEDTLS_SSL_HASH_SHA1 2 +#define MBEDTLS_SSL_HASH_SHA224 3 +#define MBEDTLS_SSL_HASH_SHA256 4 +#define MBEDTLS_SSL_HASH_SHA384 5 +#define MBEDTLS_SSL_HASH_SHA512 6 + +#define MBEDTLS_SSL_SIG_ANON 0 +#define MBEDTLS_SSL_SIG_RSA 1 +#define MBEDTLS_SSL_SIG_ECDSA 3 + +/* + * Client Certificate Types + * RFC 5246 section 7.4.4 plus RFC 4492 section 5.5 + */ +#define MBEDTLS_SSL_CERT_TYPE_RSA_SIGN 1 +#define MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN 64 + +/* + * Message, alert and handshake types + */ +#define MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC 20 +#define MBEDTLS_SSL_MSG_ALERT 21 +#define MBEDTLS_SSL_MSG_HANDSHAKE 22 +#define MBEDTLS_SSL_MSG_APPLICATION_DATA 23 +#define MBEDTLS_SSL_MSG_CID 25 + +#define MBEDTLS_SSL_ALERT_LEVEL_WARNING 1 +#define MBEDTLS_SSL_ALERT_LEVEL_FATAL 2 + +#define MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY 0 /* 0x00 */ +#define MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE 10 /* 0x0A */ +#define MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC 20 /* 0x14 */ +#define MBEDTLS_SSL_ALERT_MSG_DECRYPTION_FAILED 21 /* 0x15 */ +#define MBEDTLS_SSL_ALERT_MSG_RECORD_OVERFLOW 22 /* 0x16 */ +#define MBEDTLS_SSL_ALERT_MSG_DECOMPRESSION_FAILURE 30 /* 0x1E */ +#define MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE 40 /* 0x28 */ +#define MBEDTLS_SSL_ALERT_MSG_NO_CERT 41 /* 0x29 */ +#define MBEDTLS_SSL_ALERT_MSG_BAD_CERT 42 /* 0x2A */ +#define MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT 43 /* 0x2B */ +#define MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED 44 /* 0x2C */ +#define MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED 45 /* 0x2D */ +#define MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN 46 /* 0x2E */ +#define MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER 47 /* 0x2F */ +#define MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA 48 /* 0x30 */ +#define MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED 49 /* 0x31 */ +#define MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR 50 /* 0x32 */ +#define MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR 51 /* 0x33 */ +#define MBEDTLS_SSL_ALERT_MSG_EXPORT_RESTRICTION 60 /* 0x3C */ +#define MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION 70 /* 0x46 */ +#define MBEDTLS_SSL_ALERT_MSG_INSUFFICIENT_SECURITY 71 /* 0x47 */ +#define MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR 80 /* 0x50 */ +#define MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK 86 /* 0x56 */ +#define MBEDTLS_SSL_ALERT_MSG_USER_CANCELED 90 /* 0x5A */ +#define MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION 100 /* 0x64 */ +#define MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT 110 /* 0x6E */ +#define MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME 112 /* 0x70 */ +#define MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY 115 /* 0x73 */ +#define MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL 120 /* 0x78 */ + +#define MBEDTLS_SSL_HS_HELLO_REQUEST 0 +#define MBEDTLS_SSL_HS_CLIENT_HELLO 1 +#define MBEDTLS_SSL_HS_SERVER_HELLO 2 +#define MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST 3 +#define MBEDTLS_SSL_HS_NEW_SESSION_TICKET 4 +#define MBEDTLS_SSL_HS_CERTIFICATE 11 +#define MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE 12 +#define MBEDTLS_SSL_HS_CERTIFICATE_REQUEST 13 +#define MBEDTLS_SSL_HS_SERVER_HELLO_DONE 14 +#define MBEDTLS_SSL_HS_CERTIFICATE_VERIFY 15 +#define MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE 16 +#define MBEDTLS_SSL_HS_FINISHED 20 + +/* + * TLS extensions + */ +#define MBEDTLS_TLS_EXT_SERVERNAME 0 +#define MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME 0 + +#define MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH 1 + +#define MBEDTLS_TLS_EXT_TRUNCATED_HMAC 4 + +#define MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES 10 +#define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS 11 + +#define MBEDTLS_TLS_EXT_SIG_ALG 13 + +#define MBEDTLS_TLS_EXT_USE_SRTP 14 + +#define MBEDTLS_TLS_EXT_ALPN 16 + +#define MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC 22 /* 0x16 */ +#define MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET 0x0017 /* 23 */ + +#define MBEDTLS_TLS_EXT_SESSION_TICKET 35 + +/* The value of the CID extension is still TBD as of + * draft-ietf-tls-dtls-connection-id-05 + * (https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05). + * + * A future minor revision of Mbed TLS may change the default value of + * this option to match evolving standards and usage. + */ +#if !defined(MBEDTLS_TLS_EXT_CID) +#define MBEDTLS_TLS_EXT_CID 254 /* TBD */ +#endif + +#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP 256 /* experimental */ + +#define MBEDTLS_TLS_EXT_RENEGOTIATION_INFO 0xFF01 + +/* + * Size defines + */ +#if !defined(MBEDTLS_PSK_MAX_LEN) +#define MBEDTLS_PSK_MAX_LEN 32 /* 256 bits */ +#endif + +/* Dummy type used only for its size */ +union mbedtls_ssl_premaster_secret +{ +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) + unsigned char _pms_rsa[48]; /* RFC 5246 8.1.1 */ +#endif +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) + unsigned char _pms_dhm[MBEDTLS_MPI_MAX_SIZE]; /* RFC 5246 8.1.2 */ +#endif +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) + unsigned char _pms_ecdh[MBEDTLS_ECP_MAX_BYTES]; /* RFC 4492 5.10 */ +#endif +#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) + unsigned char _pms_psk[4 + 2 * MBEDTLS_PSK_MAX_LEN]; /* RFC 4279 2 */ +#endif +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) + unsigned char _pms_dhe_psk[4 + MBEDTLS_MPI_MAX_SIZE + + MBEDTLS_PSK_MAX_LEN]; /* RFC 4279 3 */ +#endif +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) + unsigned char _pms_rsa_psk[52 + MBEDTLS_PSK_MAX_LEN]; /* RFC 4279 4 */ +#endif +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) + unsigned char _pms_ecdhe_psk[4 + MBEDTLS_ECP_MAX_BYTES + + MBEDTLS_PSK_MAX_LEN]; /* RFC 5489 2 */ +#endif +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + unsigned char _pms_ecjpake[32]; /* Thread spec: SHA-256 output */ +#endif +}; + +#define MBEDTLS_PREMASTER_SIZE sizeof( union mbedtls_ssl_premaster_secret ) + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * SSL state machine + */ +typedef enum +{ + MBEDTLS_SSL_HELLO_REQUEST, + MBEDTLS_SSL_CLIENT_HELLO, + MBEDTLS_SSL_SERVER_HELLO, + MBEDTLS_SSL_SERVER_CERTIFICATE, + MBEDTLS_SSL_SERVER_KEY_EXCHANGE, + MBEDTLS_SSL_CERTIFICATE_REQUEST, + MBEDTLS_SSL_SERVER_HELLO_DONE, + MBEDTLS_SSL_CLIENT_CERTIFICATE, + MBEDTLS_SSL_CLIENT_KEY_EXCHANGE, + MBEDTLS_SSL_CERTIFICATE_VERIFY, + MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC, + MBEDTLS_SSL_CLIENT_FINISHED, + MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC, + MBEDTLS_SSL_SERVER_FINISHED, + MBEDTLS_SSL_FLUSH_BUFFERS, + MBEDTLS_SSL_HANDSHAKE_WRAPUP, + MBEDTLS_SSL_HANDSHAKE_OVER, + MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET, + MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT, +} +mbedtls_ssl_states; + +/* + * The tls_prf function types. + */ +typedef enum +{ + MBEDTLS_SSL_TLS_PRF_NONE, + MBEDTLS_SSL_TLS_PRF_SSL3, + MBEDTLS_SSL_TLS_PRF_TLS1, + MBEDTLS_SSL_TLS_PRF_SHA384, + MBEDTLS_SSL_TLS_PRF_SHA256 +} +mbedtls_tls_prf_types; +/** + * \brief Callback type: send data on the network. + * + * \note That callback may be either blocking or non-blocking. + * + * \param ctx Context for the send callback (typically a file descriptor) + * \param buf Buffer holding the data to send + * \param len Length of the data to send + * + * \return The callback must return the number of bytes sent if any, + * or a non-zero error code. + * If performing non-blocking I/O, \c MBEDTLS_ERR_SSL_WANT_WRITE + * must be returned when the operation would block. + * + * \note The callback is allowed to send fewer bytes than requested. + * It must always return the number of bytes actually sent. + */ +typedef int mbedtls_ssl_send_t( void *ctx, + const unsigned char *buf, + size_t len ); + +/** + * \brief Callback type: receive data from the network. + * + * \note That callback may be either blocking or non-blocking. + * + * \param ctx Context for the receive callback (typically a file + * descriptor) + * \param buf Buffer to write the received data to + * \param len Length of the receive buffer + * + * \returns If data has been received, the positive number of bytes received. + * \returns \c 0 if the connection has been closed. + * \returns If performing non-blocking I/O, \c MBEDTLS_ERR_SSL_WANT_READ + * must be returned when the operation would block. + * \returns Another negative error code on other kinds of failures. + * + * \note The callback may receive fewer bytes than the length of the + * buffer. It must always return the number of bytes actually + * received and written to the buffer. + */ +typedef int mbedtls_ssl_recv_t( void *ctx, + unsigned char *buf, + size_t len ); + +/** + * \brief Callback type: receive data from the network, with timeout + * + * \note That callback must block until data is received, or the + * timeout delay expires, or the operation is interrupted by a + * signal. + * + * \param ctx Context for the receive callback (typically a file descriptor) + * \param buf Buffer to write the received data to + * \param len Length of the receive buffer + * \param timeout Maximum nomber of millisecondes to wait for data + * 0 means no timeout (potentially waiting forever) + * + * \return The callback must return the number of bytes received, + * or a non-zero error code: + * \c MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out, + * \c MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal. + * + * \note The callback may receive fewer bytes than the length of the + * buffer. It must always return the number of bytes actually + * received and written to the buffer. + */ +typedef int mbedtls_ssl_recv_timeout_t( void *ctx, + unsigned char *buf, + size_t len, + uint32_t timeout ); +/** + * \brief Callback type: set a pair of timers/delays to watch + * + * \param ctx Context pointer + * \param int_ms Intermediate delay in milliseconds + * \param fin_ms Final delay in milliseconds + * 0 cancels the current timer. + * + * \note This callback must at least store the necessary information + * for the associated \c mbedtls_ssl_get_timer_t callback to + * return correct information. + * + * \note If using a event-driven style of programming, an event must + * be generated when the final delay is passed. The event must + * cause a call to \c mbedtls_ssl_handshake() with the proper + * SSL context to be scheduled. Care must be taken to ensure + * that at most one such call happens at a time. + * + * \note Only one timer at a time must be running. Calling this + * function while a timer is running must cancel it. Cancelled + * timers must not generate any event. + */ +typedef void mbedtls_ssl_set_timer_t( void * ctx, + uint32_t int_ms, + uint32_t fin_ms ); + +/** + * \brief Callback type: get status of timers/delays + * + * \param ctx Context pointer + * + * \return This callback must return: + * -1 if cancelled (fin_ms == 0), + * 0 if none of the delays have passed, + * 1 if only the intermediate delay has passed, + * 2 if the final delay has passed. + */ +typedef int mbedtls_ssl_get_timer_t( void * ctx ); + +/* Defined below */ +typedef struct mbedtls_ssl_session mbedtls_ssl_session; +typedef struct mbedtls_ssl_context mbedtls_ssl_context; +typedef struct mbedtls_ssl_config mbedtls_ssl_config; + +/* Defined in ssl_internal.h */ +typedef struct mbedtls_ssl_transform mbedtls_ssl_transform; +typedef struct mbedtls_ssl_handshake_params mbedtls_ssl_handshake_params; +typedef struct mbedtls_ssl_sig_hash_set_t mbedtls_ssl_sig_hash_set_t; +#if defined(MBEDTLS_X509_CRT_PARSE_C) +typedef struct mbedtls_ssl_key_cert mbedtls_ssl_key_cert; +#endif +#if defined(MBEDTLS_SSL_PROTO_DTLS) +typedef struct mbedtls_ssl_flight_item mbedtls_ssl_flight_item; +#endif + +#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) +#if defined(MBEDTLS_X509_CRT_PARSE_C) +/** + * \brief Callback type: start external signature operation. + * + * This callback is called during an SSL handshake to start + * a signature decryption operation using an + * external processor. The parameter \p cert contains + * the public key; it is up to the callback function to + * determine how to access the associated private key. + * + * This function typically sends or enqueues a request, and + * does not wait for the operation to complete. This allows + * the handshake step to be non-blocking. + * + * The parameters \p ssl and \p cert are guaranteed to remain + * valid throughout the handshake. On the other hand, this + * function must save the contents of \p hash if the value + * is needed for later processing, because the \p hash buffer + * is no longer valid after this function returns. + * + * This function may call mbedtls_ssl_set_async_operation_data() + * to store an operation context for later retrieval + * by the resume or cancel callback. + * + * \note For RSA signatures, this function must produce output + * that is consistent with PKCS#1 v1.5 in the same way as + * mbedtls_rsa_pkcs1_sign(). Before the private key operation, + * apply the padding steps described in RFC 8017, section 9.2 + * "EMSA-PKCS1-v1_5" as follows. + * - If \p md_alg is #MBEDTLS_MD_NONE, apply the PKCS#1 v1.5 + * encoding, treating \p hash as the DigestInfo to be + * padded. In other words, apply EMSA-PKCS1-v1_5 starting + * from step 3, with `T = hash` and `tLen = hash_len`. + * - If `md_alg != MBEDTLS_MD_NONE`, apply the PKCS#1 v1.5 + * encoding, treating \p hash as the hash to be encoded and + * padded. In other words, apply EMSA-PKCS1-v1_5 starting + * from step 2, with `digestAlgorithm` obtained by calling + * mbedtls_oid_get_oid_by_md() on \p md_alg. + * + * \note For ECDSA signatures, the output format is the DER encoding + * `Ecdsa-Sig-Value` defined in + * [RFC 4492 section 5.4](https://tools.ietf.org/html/rfc4492#section-5.4). + * + * \param ssl The SSL connection instance. It should not be + * modified other than via + * mbedtls_ssl_set_async_operation_data(). + * \param cert Certificate containing the public key. + * In simple cases, this is one of the pointers passed to + * mbedtls_ssl_conf_own_cert() when configuring the SSL + * connection. However, if other callbacks are used, this + * property may not hold. For example, if an SNI callback + * is registered with mbedtls_ssl_conf_sni(), then + * this callback determines what certificate is used. + * \param md_alg Hash algorithm. + * \param hash Buffer containing the hash. This buffer is + * no longer valid when the function returns. + * \param hash_len Size of the \c hash buffer in bytes. + * + * \return 0 if the operation was started successfully and the SSL + * stack should call the resume callback immediately. + * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation + * was started successfully and the SSL stack should return + * immediately without calling the resume callback yet. + * \return #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external + * processor does not support this key. The SSL stack will + * use the private key object instead. + * \return Any other error indicates a fatal failure and is + * propagated up the call chain. The callback should + * use \c MBEDTLS_ERR_PK_xxx error codes, and must not + * use \c MBEDTLS_ERR_SSL_xxx error codes except as + * directed in the documentation of this callback. + */ +typedef int mbedtls_ssl_async_sign_t( mbedtls_ssl_context *ssl, + mbedtls_x509_crt *cert, + mbedtls_md_type_t md_alg, + const unsigned char *hash, + size_t hash_len ); + +/** + * \brief Callback type: start external decryption operation. + * + * This callback is called during an SSL handshake to start + * an RSA decryption operation using an + * external processor. The parameter \p cert contains + * the public key; it is up to the callback function to + * determine how to access the associated private key. + * + * This function typically sends or enqueues a request, and + * does not wait for the operation to complete. This allows + * the handshake step to be non-blocking. + * + * The parameters \p ssl and \p cert are guaranteed to remain + * valid throughout the handshake. On the other hand, this + * function must save the contents of \p input if the value + * is needed for later processing, because the \p input buffer + * is no longer valid after this function returns. + * + * This function may call mbedtls_ssl_set_async_operation_data() + * to store an operation context for later retrieval + * by the resume or cancel callback. + * + * \warning RSA decryption as used in TLS is subject to a potential + * timing side channel attack first discovered by Bleichenbacher + * in 1998. This attack can be remotely exploitable + * in practice. To avoid this attack, you must ensure that + * if the callback performs an RSA decryption, the time it + * takes to execute and return the result does not depend + * on whether the RSA decryption succeeded or reported + * invalid padding. + * + * \param ssl The SSL connection instance. It should not be + * modified other than via + * mbedtls_ssl_set_async_operation_data(). + * \param cert Certificate containing the public key. + * In simple cases, this is one of the pointers passed to + * mbedtls_ssl_conf_own_cert() when configuring the SSL + * connection. However, if other callbacks are used, this + * property may not hold. For example, if an SNI callback + * is registered with mbedtls_ssl_conf_sni(), then + * this callback determines what certificate is used. + * \param input Buffer containing the input ciphertext. This buffer + * is no longer valid when the function returns. + * \param input_len Size of the \p input buffer in bytes. + * + * \return 0 if the operation was started successfully and the SSL + * stack should call the resume callback immediately. + * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation + * was started successfully and the SSL stack should return + * immediately without calling the resume callback yet. + * \return #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external + * processor does not support this key. The SSL stack will + * use the private key object instead. + * \return Any other error indicates a fatal failure and is + * propagated up the call chain. The callback should + * use \c MBEDTLS_ERR_PK_xxx error codes, and must not + * use \c MBEDTLS_ERR_SSL_xxx error codes except as + * directed in the documentation of this callback. + */ +typedef int mbedtls_ssl_async_decrypt_t( mbedtls_ssl_context *ssl, + mbedtls_x509_crt *cert, + const unsigned char *input, + size_t input_len ); +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + +/** + * \brief Callback type: resume external operation. + * + * This callback is called during an SSL handshake to resume + * an external operation started by the + * ::mbedtls_ssl_async_sign_t or + * ::mbedtls_ssl_async_decrypt_t callback. + * + * This function typically checks the status of a pending + * request or causes the request queue to make progress, and + * does not wait for the operation to complete. This allows + * the handshake step to be non-blocking. + * + * This function may call mbedtls_ssl_get_async_operation_data() + * to retrieve an operation context set by the start callback. + * It may call mbedtls_ssl_set_async_operation_data() to modify + * this context. + * + * Note that when this function returns a status other than + * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, it must free any + * resources associated with the operation. + * + * \param ssl The SSL connection instance. It should not be + * modified other than via + * mbedtls_ssl_set_async_operation_data(). + * \param output Buffer containing the output (signature or decrypted + * data) on success. + * \param output_len On success, number of bytes written to \p output. + * \param output_size Size of the \p output buffer in bytes. + * + * \return 0 if output of the operation is available in the + * \p output buffer. + * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation + * is still in progress. Subsequent requests for progress + * on the SSL connection will call the resume callback + * again. + * \return Any other error means that the operation is aborted. + * The SSL handshake is aborted. The callback should + * use \c MBEDTLS_ERR_PK_xxx error codes, and must not + * use \c MBEDTLS_ERR_SSL_xxx error codes except as + * directed in the documentation of this callback. + */ +typedef int mbedtls_ssl_async_resume_t( mbedtls_ssl_context *ssl, + unsigned char *output, + size_t *output_len, + size_t output_size ); + +/** + * \brief Callback type: cancel external operation. + * + * This callback is called if an SSL connection is closed + * while an asynchronous operation is in progress. Note that + * this callback is not called if the + * ::mbedtls_ssl_async_resume_t callback has run and has + * returned a value other than + * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, since in that case + * the asynchronous operation has already completed. + * + * This function may call mbedtls_ssl_get_async_operation_data() + * to retrieve an operation context set by the start callback. + * + * \param ssl The SSL connection instance. It should not be + * modified. + */ +typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl ); +#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ + +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \ + !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) +#define MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN 48 +#if defined(MBEDTLS_SHA256_C) +#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE MBEDTLS_MD_SHA256 +#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN 32 +#elif defined(MBEDTLS_SHA512_C) +#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE MBEDTLS_MD_SHA384 +#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN 48 +#elif defined(MBEDTLS_SHA1_C) +#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE MBEDTLS_MD_SHA1 +#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN 20 +#else +/* This is already checked in check_config.h, but be sure. */ +#error "Bad configuration - need SHA-1, SHA-256 or SHA-512 enabled to compute digest of peer CRT." +#endif +#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED && + !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ + +#if defined(MBEDTLS_SSL_DTLS_SRTP) + +#define MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH 255 +#define MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH 4 +/* + * For code readability use a typedef for DTLS-SRTP profiles + * + * Use_srtp extension protection profiles values as defined in + * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml + * + * Reminder: if this list is expanded mbedtls_ssl_check_srtp_profile_value + * must be updated too. + */ +#define MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80 ( (uint16_t) 0x0001) +#define MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32 ( (uint16_t) 0x0002) +#define MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80 ( (uint16_t) 0x0005) +#define MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32 ( (uint16_t) 0x0006) +/* This one is not iana defined, but for code readability. */ +#define MBEDTLS_TLS_SRTP_UNSET ( (uint16_t) 0x0000) + +typedef uint16_t mbedtls_ssl_srtp_profile; + +typedef struct mbedtls_dtls_srtp_info_t +{ + /*! The SRTP profile that was negotiated. */ + mbedtls_ssl_srtp_profile chosen_dtls_srtp_profile; + /*! The length of mki_value. */ + uint16_t mki_len; + /*! The mki_value used, with max size of 256 bytes. */ + unsigned char mki_value[MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH]; +} +mbedtls_dtls_srtp_info; + +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + +/* + * This structure is used for storing current session data. + * + * Note: when changing this definition, we need to check and update: + * - in tests/suites/test_suite_ssl.function: + * ssl_populate_session() and ssl_serialize_session_save_load() + * - in library/ssl_tls.c: + * mbedtls_ssl_session_init() and mbedtls_ssl_session_free() + * mbedtls_ssl_session_save() and ssl_session_load() + * ssl_session_copy() + */ +struct mbedtls_ssl_session +{ +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) + unsigned char mfl_code; /*!< MaxFragmentLength negotiated by peer */ +#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ + +#if defined(MBEDTLS_HAVE_TIME) + mbedtls_time_t start; /*!< starting time */ +#endif + int ciphersuite; /*!< chosen ciphersuite */ + int compression; /*!< chosen compression */ + size_t id_len; /*!< session id length */ + unsigned char id[32]; /*!< session identifier */ + unsigned char master[48]; /*!< the master secret */ + +#if defined(MBEDTLS_X509_CRT_PARSE_C) +#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) + mbedtls_x509_crt *peer_cert; /*!< peer X.509 cert chain */ +#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ + /*! The digest of the peer's end-CRT. This must be kept to detect CRT + * changes during renegotiation, mitigating the triple handshake attack. */ + unsigned char *peer_cert_digest; + size_t peer_cert_digest_len; + mbedtls_md_type_t peer_cert_digest_type; +#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + uint32_t verify_result; /*!< verification result */ + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) + unsigned char *ticket; /*!< RFC 5077 session ticket */ + size_t ticket_len; /*!< session ticket length */ + uint32_t ticket_lifetime; /*!< ticket lifetime hint */ +#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ + +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) + int trunc_hmac; /*!< flag for truncated hmac activation */ +#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ + +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) + int encrypt_then_mac; /*!< flag for EtM activation */ +#endif +}; + +/** + * SSL/TLS configuration to be shared between mbedtls_ssl_context structures. + */ +struct mbedtls_ssl_config +{ + /* Group items by size and reorder them to maximize usage of immediate offset access. */ + + /* + * Numerical settings (char) + */ + + unsigned char max_major_ver; /*!< max. major version used */ + unsigned char max_minor_ver; /*!< max. minor version used */ + unsigned char min_major_ver; /*!< min. major version used */ + unsigned char min_minor_ver; /*!< min. minor version used */ + + /* + * Flags (could be bit-fields to save RAM, but separate bytes make + * the code smaller on architectures with an instruction for direct + * byte access). + */ + + uint8_t endpoint /*bool*/; /*!< 0: client, 1: server */ + uint8_t transport /*bool*/; /*!< stream (TLS) or datagram (DTLS) */ + uint8_t authmode /*2 bits*/; /*!< MBEDTLS_SSL_VERIFY_XXX */ + /* needed even with renego disabled for LEGACY_BREAK_HANDSHAKE */ + uint8_t allow_legacy_renegotiation /*2 bits*/; /*!< MBEDTLS_LEGACY_XXX */ +#if defined(MBEDTLS_ARC4_C) + uint8_t arc4_disabled /*bool*/; /*!< blacklist RC4 ciphersuites? */ +#endif +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) + uint8_t mfl_code /*3 bits*/; /*!< desired fragment length */ +#endif +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) + uint8_t encrypt_then_mac /*bool*/; /*!< negotiate encrypt-then-mac? */ +#endif +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) + uint8_t extended_ms /*bool*/; /*!< negotiate extended master secret? */ +#endif +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) + uint8_t anti_replay /*bool*/; /*!< detect and prevent replay? */ +#endif +#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) + uint8_t cbc_record_splitting /*bool*/; /*!< do cbc record splitting */ +#endif +#if defined(MBEDTLS_SSL_RENEGOTIATION) + uint8_t disable_renegotiation /*bool*/; /*!< disable renegotiation? */ +#endif +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) + uint8_t trunc_hmac /*bool*/; /*!< negotiate truncated hmac? */ +#endif +#if defined(MBEDTLS_SSL_SESSION_TICKETS) + uint8_t session_tickets /*bool*/; /*!< use session tickets? */ +#endif +#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C) + uint8_t fallback /*bool*/; /*!< is this a fallback? */ +#endif +#if defined(MBEDTLS_SSL_SRV_C) + uint8_t cert_req_ca_list /*bool*/; /*!< enable sending CA list in + Certificate Request messages? */ +#endif +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + uint8_t ignore_unexpected_cid /*bool*/; /*!< Determines whether DTLS + * record with unexpected CID + * should lead to failure. */ +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) + uint8_t dtls_srtp_mki_support /*bool*/; /*!< support having mki_value + in the use_srtp extension? */ +#endif + + /* + * Numerical settings (int or larger) + */ + + uint32_t read_timeout; /*!< timeout for mbedtls_ssl_read (ms) */ + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + uint32_t hs_timeout_min; /*!< initial value of the handshake + retransmission timeout (ms) */ + uint32_t hs_timeout_max; /*!< maximum value of the handshake + retransmission timeout (ms) */ +#endif + +#if defined(MBEDTLS_SSL_RENEGOTIATION) + int renego_max_records; /*!< grace period for renegotiation */ + unsigned char renego_period[8]; /*!< value of the record counters + that triggers renegotiation */ +#endif + +#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) + unsigned int badmac_limit; /*!< limit of records with a bad MAC */ +#endif + +#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) + unsigned int dhm_min_bitlen; /*!< min. bit length of the DHM prime */ +#endif + + /* + * Pointers + */ + + const int *ciphersuite_list[4]; /*!< allowed ciphersuites per version */ + + /** Callback for printing debug output */ + void (*f_dbg)(void *, int, const char *, int, const char *); + void *p_dbg; /*!< context for the debug function */ + + /** Callback for getting (pseudo-)random numbers */ + int (*f_rng)(void *, unsigned char *, size_t); + void *p_rng; /*!< context for the RNG function */ + + /** Callback to retrieve a session from the cache */ + int (*f_get_cache)(void *, mbedtls_ssl_session *); + /** Callback to store a session into the cache */ + int (*f_set_cache)(void *, const mbedtls_ssl_session *); + void *p_cache; /*!< context for cache callbacks */ + +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) + /** Callback for setting cert according to SNI extension */ + int (*f_sni)(void *, mbedtls_ssl_context *, const unsigned char *, size_t); + void *p_sni; /*!< context for SNI callback */ +#endif + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + /** Callback to customize X.509 certificate chain verification */ + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *); + void *p_vrfy; /*!< context for X.509 verify calllback */ +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) + /** Callback to retrieve PSK key from identity */ + int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *, size_t); + void *p_psk; /*!< context for PSK callback */ +#endif + +#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) + /** Callback to create & write a cookie for ClientHello verification */ + int (*f_cookie_write)( void *, unsigned char **, unsigned char *, + const unsigned char *, size_t ); + /** Callback to verify validity of a ClientHello cookie */ + int (*f_cookie_check)( void *, const unsigned char *, size_t, + const unsigned char *, size_t ); + void *p_cookie; /*!< context for the cookie callbacks */ +#endif + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_SRV_C) + /** Callback to create & write a session ticket */ + int (*f_ticket_write)( void *, const mbedtls_ssl_session *, + unsigned char *, const unsigned char *, size_t *, uint32_t * ); + /** Callback to parse a session ticket into a session structure */ + int (*f_ticket_parse)( void *, mbedtls_ssl_session *, unsigned char *, size_t); + void *p_ticket; /*!< context for the ticket callbacks */ +#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */ + +#if defined(MBEDTLS_SSL_EXPORT_KEYS) + /** Callback to export key block and master secret */ + int (*f_export_keys)( void *, const unsigned char *, + const unsigned char *, size_t, size_t, size_t ); + /** Callback to export key block, master secret, + * tls_prf and random bytes. Should replace f_export_keys */ + int (*f_export_keys_ext)( void *, const unsigned char *, + const unsigned char *, size_t, size_t, size_t, + const unsigned char[32], const unsigned char[32], + mbedtls_tls_prf_types ); + void *p_export_keys; /*!< context for key export callback */ +#endif + +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + size_t cid_len; /*!< The length of CIDs for incoming DTLS records. */ +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + const mbedtls_x509_crt_profile *cert_profile; /*!< verification profile */ + mbedtls_ssl_key_cert *key_cert; /*!< own certificate/key pair(s) */ + mbedtls_x509_crt *ca_chain; /*!< trusted CAs */ + mbedtls_x509_crl *ca_crl; /*!< trusted CAs CRLs */ +#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) + mbedtls_x509_crt_ca_cb_t f_ca_cb; + void *p_ca_cb; +#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + +#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) +#if defined(MBEDTLS_X509_CRT_PARSE_C) + mbedtls_ssl_async_sign_t *f_async_sign_start; /*!< start asynchronous signature operation */ + mbedtls_ssl_async_decrypt_t *f_async_decrypt_start; /*!< start asynchronous decryption operation */ +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + mbedtls_ssl_async_resume_t *f_async_resume; /*!< resume asynchronous operation */ + mbedtls_ssl_async_cancel_t *f_async_cancel; /*!< cancel asynchronous operation */ + void *p_async_config_data; /*!< Configuration data set by mbedtls_ssl_conf_async_private_cb(). */ +#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ + +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) + const int *sig_hashes; /*!< allowed signature hashes */ +#endif + +#if defined(MBEDTLS_ECP_C) + const mbedtls_ecp_group_id *curve_list; /*!< allowed curves */ +#endif + +#if defined(MBEDTLS_DHM_C) + mbedtls_mpi dhm_P; /*!< prime modulus for DHM */ + mbedtls_mpi dhm_G; /*!< generator for DHM */ +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) + +#if defined(MBEDTLS_USE_PSA_CRYPTO) + psa_key_id_t psk_opaque; /*!< PSA key slot holding opaque PSK. This field + * should only be set via + * mbedtls_ssl_conf_psk_opaque(). + * If either no PSK or a raw PSK have been + * configured, this has value \c 0. + */ +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + + unsigned char *psk; /*!< The raw pre-shared key. This field should + * only be set via mbedtls_ssl_conf_psk(). + * If either no PSK or an opaque PSK + * have been configured, this has value NULL. */ + size_t psk_len; /*!< The length of the raw pre-shared key. + * This field should only be set via + * mbedtls_ssl_conf_psk(). + * Its value is non-zero if and only if + * \c psk is not \c NULL. */ + + unsigned char *psk_identity; /*!< The PSK identity for PSK negotiation. + * This field should only be set via + * mbedtls_ssl_conf_psk(). + * This is set if and only if either + * \c psk or \c psk_opaque are set. */ + size_t psk_identity_len;/*!< The length of PSK identity. + * This field should only be set via + * mbedtls_ssl_conf_psk(). + * Its value is non-zero if and only if + * \c psk is not \c NULL or \c psk_opaque + * is not \c 0. */ +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ + +#if defined(MBEDTLS_SSL_ALPN) + const char **alpn_list; /*!< ordered list of protocols */ +#endif + +#if defined(MBEDTLS_SSL_DTLS_SRTP) + /*! ordered list of supported srtp profile */ + const mbedtls_ssl_srtp_profile *dtls_srtp_profile_list; + /*! number of supported profiles */ + size_t dtls_srtp_profile_list_len; +#endif /* MBEDTLS_SSL_DTLS_SRTP */ +}; + +struct mbedtls_ssl_context +{ + const mbedtls_ssl_config *conf; /*!< configuration information */ + + /* + * Miscellaneous + */ + int state; /*!< SSL handshake: current state */ +#if defined(MBEDTLS_SSL_RENEGOTIATION) + int renego_status; /*!< Initial, in progress, pending? */ + int renego_records_seen; /*!< Records since renego request, or with DTLS, + number of retransmissions of request if + renego_max_records is < 0 */ +#endif /* MBEDTLS_SSL_RENEGOTIATION */ + + int major_ver; /*!< equal to MBEDTLS_SSL_MAJOR_VERSION_3 */ + int minor_ver; /*!< either 0 (SSL3) or 1 (TLS1.0) */ + +#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) + unsigned badmac_seen; /*!< records with a bad MAC received */ +#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + /** Callback to customize X.509 certificate chain verification */ + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *); + void *p_vrfy; /*!< context for X.509 verify callback */ +#endif + + mbedtls_ssl_send_t *f_send; /*!< Callback for network send */ + mbedtls_ssl_recv_t *f_recv; /*!< Callback for network receive */ + mbedtls_ssl_recv_timeout_t *f_recv_timeout; + /*!< Callback for network receive with timeout */ + + void *p_bio; /*!< context for I/O operations */ + + /* + * Session layer + */ + mbedtls_ssl_session *session_in; /*!< current session data (in) */ + mbedtls_ssl_session *session_out; /*!< current session data (out) */ + mbedtls_ssl_session *session; /*!< negotiated session data */ + mbedtls_ssl_session *session_negotiate; /*!< session data in negotiation */ + + mbedtls_ssl_handshake_params *handshake; /*!< params required only during + the handshake process */ + + /* + * Record layer transformations + */ + mbedtls_ssl_transform *transform_in; /*!< current transform params (in) */ + mbedtls_ssl_transform *transform_out; /*!< current transform params (in) */ + mbedtls_ssl_transform *transform; /*!< negotiated transform params */ + mbedtls_ssl_transform *transform_negotiate; /*!< transform params in negotiation */ + + /* + * Timers + */ + void *p_timer; /*!< context for the timer callbacks */ + + mbedtls_ssl_set_timer_t *f_set_timer; /*!< set timer callback */ + mbedtls_ssl_get_timer_t *f_get_timer; /*!< get timer callback */ + + /* + * Record layer (incoming data) + */ + unsigned char *in_buf; /*!< input buffer */ + unsigned char *in_ctr; /*!< 64-bit incoming message counter + TLS: maintained by us + DTLS: read from peer */ + unsigned char *in_hdr; /*!< start of record header */ +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + unsigned char *in_cid; /*!< The start of the CID; + * (the end is marked by in_len). */ +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + unsigned char *in_len; /*!< two-bytes message length field */ + unsigned char *in_iv; /*!< ivlen-byte IV */ + unsigned char *in_msg; /*!< message contents (in_iv+ivlen) */ + unsigned char *in_offt; /*!< read offset in application data */ + + int in_msgtype; /*!< record header: message type */ + size_t in_msglen; /*!< record header: message length */ + size_t in_left; /*!< amount of data read so far */ +#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) + size_t in_buf_len; /*!< length of input buffer */ +#endif +#if defined(MBEDTLS_SSL_PROTO_DTLS) + uint16_t in_epoch; /*!< DTLS epoch for incoming records */ + size_t next_record_offset; /*!< offset of the next record in datagram + (equal to in_left if none) */ +#endif /* MBEDTLS_SSL_PROTO_DTLS */ +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) + uint64_t in_window_top; /*!< last validated record seq_num */ + uint64_t in_window; /*!< bitmask for replay detection */ +#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ + + size_t in_hslen; /*!< current handshake message length, + including the handshake header */ + int nb_zero; /*!< # of 0-length encrypted messages */ + + int keep_current_message; /*!< drop or reuse current message + on next call to record layer? */ + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + uint8_t disable_datagram_packing; /*!< Disable packing multiple records + * within a single datagram. */ +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + + /* + * Record layer (outgoing data) + */ + unsigned char *out_buf; /*!< output buffer */ + unsigned char *out_ctr; /*!< 64-bit outgoing message counter */ + unsigned char *out_hdr; /*!< start of record header */ +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + unsigned char *out_cid; /*!< The start of the CID; + * (the end is marked by in_len). */ +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + unsigned char *out_len; /*!< two-bytes message length field */ + unsigned char *out_iv; /*!< ivlen-byte IV */ + unsigned char *out_msg; /*!< message contents (out_iv+ivlen) */ + + int out_msgtype; /*!< record header: message type */ + size_t out_msglen; /*!< record header: message length */ + size_t out_left; /*!< amount of data not yet written */ +#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) + size_t out_buf_len; /*!< length of output buffer */ +#endif + + unsigned char cur_out_ctr[8]; /*!< Outgoing record sequence number. */ + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + uint16_t mtu; /*!< path mtu, used to fragment outgoing messages */ +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + +#if defined(MBEDTLS_ZLIB_SUPPORT) + unsigned char *compress_buf; /*!< zlib data buffer */ +#endif /* MBEDTLS_ZLIB_SUPPORT */ +#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) + signed char split_done; /*!< current record already split? */ +#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */ + + /* + * PKI layer + */ + int client_auth; /*!< flag for client auth. */ + + /* + * User settings + */ +#if defined(MBEDTLS_X509_CRT_PARSE_C) + char *hostname; /*!< expected peer CN for verification + (and SNI if available) */ +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + +#if defined(MBEDTLS_SSL_ALPN) + const char *alpn_chosen; /*!< negotiated protocol */ +#endif /* MBEDTLS_SSL_ALPN */ + +#if defined(MBEDTLS_SSL_DTLS_SRTP) + /* + * use_srtp extension + */ + mbedtls_dtls_srtp_info dtls_srtp_info; +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + + /* + * Information for DTLS hello verify + */ +#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) + unsigned char *cli_id; /*!< transport-level ID of the client */ + size_t cli_id_len; /*!< length of cli_id */ +#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */ + + /* + * Secure renegotiation + */ + /* needed to know when to send extension on server */ + int secure_renegotiation; /*!< does peer support legacy or + secure renegotiation */ +#if defined(MBEDTLS_SSL_RENEGOTIATION) + size_t verify_data_len; /*!< length of verify data stored */ + char own_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */ + char peer_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */ +#endif /* MBEDTLS_SSL_RENEGOTIATION */ + +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + /* CID configuration to use in subsequent handshakes. */ + + /*! The next incoming CID, chosen by the user and applying to + * all subsequent handshakes. This may be different from the + * CID currently used in case the user has re-configured the CID + * after an initial handshake. */ + unsigned char own_cid[ MBEDTLS_SSL_CID_IN_LEN_MAX ]; + uint8_t own_cid_len; /*!< The length of \c own_cid. */ + uint8_t negotiate_cid; /*!< This indicates whether the CID extension should + * be negotiated in the next handshake or not. + * Possible values are #MBEDTLS_SSL_CID_ENABLED + * and #MBEDTLS_SSL_CID_DISABLED. */ +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ +}; + +#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) + +#define MBEDTLS_SSL_CHANNEL_OUTBOUND MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( 0 ) +#define MBEDTLS_SSL_CHANNEL_INBOUND MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( 1 ) + +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif /* MBEDTLS_DEPRECATED_WARNING */ + +MBEDTLS_DEPRECATED extern int (*mbedtls_ssl_hw_record_init)( + mbedtls_ssl_context *ssl, + const unsigned char *key_enc, const unsigned char *key_dec, + size_t keylen, + const unsigned char *iv_enc, const unsigned char *iv_dec, + size_t ivlen, + const unsigned char *mac_enc, const unsigned char *mac_dec, + size_t maclen); +MBEDTLS_DEPRECATED extern int (*mbedtls_ssl_hw_record_activate)( + mbedtls_ssl_context *ssl, + int direction ); +MBEDTLS_DEPRECATED extern int (*mbedtls_ssl_hw_record_reset)( + mbedtls_ssl_context *ssl ); +MBEDTLS_DEPRECATED extern int (*mbedtls_ssl_hw_record_write)( + mbedtls_ssl_context *ssl ); +MBEDTLS_DEPRECATED extern int (*mbedtls_ssl_hw_record_read)( + mbedtls_ssl_context *ssl ); +MBEDTLS_DEPRECATED extern int (*mbedtls_ssl_hw_record_finish)( + mbedtls_ssl_context *ssl ); + +#undef MBEDTLS_DEPRECATED +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ + +#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ + +/** + * \brief Return the name of the ciphersuite associated with the + * given ID + * + * \param ciphersuite_id SSL ciphersuite ID + * + * \return a string containing the ciphersuite name + */ +const char *mbedtls_ssl_get_ciphersuite_name( const int ciphersuite_id ); + +/** + * \brief Return the ID of the ciphersuite associated with the + * given name + * + * \param ciphersuite_name SSL ciphersuite name + * + * \return the ID with the ciphersuite or 0 if not found + */ +int mbedtls_ssl_get_ciphersuite_id( const char *ciphersuite_name ); + +/** + * \brief Initialize an SSL context + * Just makes the context ready for mbedtls_ssl_setup() or + * mbedtls_ssl_free() + * + * \param ssl SSL context + */ +void mbedtls_ssl_init( mbedtls_ssl_context *ssl ); + +/** + * \brief Set up an SSL context for use + * + * \note No copy of the configuration context is made, it can be + * shared by many mbedtls_ssl_context structures. + * + * \warning The conf structure will be accessed during the session. + * It must not be modified or freed as long as the session + * is active. + * + * \warning This function must be called exactly once per context. + * Calling mbedtls_ssl_setup again is not supported, even + * if no session is active. + * + * \param ssl SSL context + * \param conf SSL configuration to use + * + * \return 0 if successful, or MBEDTLS_ERR_SSL_ALLOC_FAILED if + * memory allocation failed + */ +int mbedtls_ssl_setup( mbedtls_ssl_context *ssl, + const mbedtls_ssl_config *conf ); + +/** + * \brief Reset an already initialized SSL context for re-use + * while retaining application-set variables, function + * pointers and data. + * + * \param ssl SSL context + * \return 0 if successful, or MBEDTLS_ERR_SSL_ALLOC_FAILED, + MBEDTLS_ERR_SSL_HW_ACCEL_FAILED or + * MBEDTLS_ERR_SSL_COMPRESSION_FAILED + */ +int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl ); + +/** + * \brief Set the current endpoint type + * + * \param conf SSL configuration + * \param endpoint must be MBEDTLS_SSL_IS_CLIENT or MBEDTLS_SSL_IS_SERVER + */ +void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint ); + +/** + * \brief Set the transport type (TLS or DTLS). + * Default: TLS + * + * \note For DTLS, you must either provide a recv callback that + * doesn't block, or one that handles timeouts, see + * \c mbedtls_ssl_set_bio(). You also need to provide timer + * callbacks with \c mbedtls_ssl_set_timer_cb(). + * + * \param conf SSL configuration + * \param transport transport type: + * MBEDTLS_SSL_TRANSPORT_STREAM for TLS, + * MBEDTLS_SSL_TRANSPORT_DATAGRAM for DTLS. + */ +void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport ); + +/** + * \brief Set the certificate verification mode + * Default: NONE on server, REQUIRED on client + * + * \param conf SSL configuration + * \param authmode can be: + * + * MBEDTLS_SSL_VERIFY_NONE: peer certificate is not checked + * (default on server) + * (insecure on client) + * + * MBEDTLS_SSL_VERIFY_OPTIONAL: peer certificate is checked, however the + * handshake continues even if verification failed; + * mbedtls_ssl_get_verify_result() can be called after the + * handshake is complete. + * + * MBEDTLS_SSL_VERIFY_REQUIRED: peer *must* present a valid certificate, + * handshake is aborted if verification failed. + * (default on client) + * + * \note On client, MBEDTLS_SSL_VERIFY_REQUIRED is the recommended mode. + * With MBEDTLS_SSL_VERIFY_OPTIONAL, the user needs to call mbedtls_ssl_get_verify_result() at + * the right time(s), which may not be obvious, while REQUIRED always perform + * the verification as soon as possible. For example, REQUIRED was protecting + * against the "triple handshake" attack even before it was found. + */ +void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode ); + +#if defined(MBEDTLS_X509_CRT_PARSE_C) +/** + * \brief Set the verification callback (Optional). + * + * If set, the provided verify callback is called for each + * certificate in the peer's CRT chain, including the trusted + * root. For more information, please see the documentation of + * \c mbedtls_x509_crt_verify(). + * + * \note For per context callbacks and contexts, please use + * mbedtls_ssl_set_verify() instead. + * + * \param conf The SSL configuration to use. + * \param f_vrfy The verification callback to use during CRT verification. + * \param p_vrfy The opaque context to be passed to the callback. + */ +void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf, + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), + void *p_vrfy ); +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + +/** + * \brief Set the random number generator callback + * + * \param conf SSL configuration + * \param f_rng RNG function + * \param p_rng RNG parameter + */ +void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief Set the debug callback + * + * The callback has the following argument: + * void * opaque context for the callback + * int debug level + * const char * file name + * int line number + * const char * message + * + * \param conf SSL configuration + * \param f_dbg debug function + * \param p_dbg debug parameter + */ +void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf, + void (*f_dbg)(void *, int, const char *, int, const char *), + void *p_dbg ); + +/** + * \brief Set the underlying BIO callbacks for write, read and + * read-with-timeout. + * + * \param ssl SSL context + * \param p_bio parameter (context) shared by BIO callbacks + * \param f_send write callback + * \param f_recv read callback + * \param f_recv_timeout blocking read callback with timeout. + * + * \note One of f_recv or f_recv_timeout can be NULL, in which case + * the other is used. If both are non-NULL, f_recv_timeout is + * used and f_recv is ignored (as if it were NULL). + * + * \note The two most common use cases are: + * - non-blocking I/O, f_recv != NULL, f_recv_timeout == NULL + * - blocking I/O, f_recv == NULL, f_recv_timeout != NULL + * + * \note For DTLS, you need to provide either a non-NULL + * f_recv_timeout callback, or a f_recv that doesn't block. + * + * \note See the documentations of \c mbedtls_ssl_send_t, + * \c mbedtls_ssl_recv_t and \c mbedtls_ssl_recv_timeout_t for + * the conventions those callbacks must follow. + * + * \note On some platforms, net_sockets.c provides + * \c mbedtls_net_send(), \c mbedtls_net_recv() and + * \c mbedtls_net_recv_timeout() that are suitable to be used + * here. + */ +void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl, + void *p_bio, + mbedtls_ssl_send_t *f_send, + mbedtls_ssl_recv_t *f_recv, + mbedtls_ssl_recv_timeout_t *f_recv_timeout ); + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + + +/** + * \brief Configure the use of the Connection ID (CID) + * extension in the next handshake. + * + * Reference: draft-ietf-tls-dtls-connection-id-05 + * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05 + * + * The DTLS CID extension allows the reliable association of + * DTLS records to DTLS connections across changes in the + * underlying transport (changed IP and Port metadata) by + * adding explicit connection identifiers (CIDs) to the + * headers of encrypted DTLS records. The desired CIDs are + * configured by the application layer and are exchanged in + * new `ClientHello` / `ServerHello` extensions during the + * handshake, where each side indicates the CID it wants the + * peer to use when writing encrypted messages. The CIDs are + * put to use once records get encrypted: the stack discards + * any incoming records that don't include the configured CID + * in their header, and adds the peer's requested CID to the + * headers of outgoing messages. + * + * This API enables or disables the use of the CID extension + * in the next handshake and sets the value of the CID to + * be used for incoming messages. + * + * \param ssl The SSL context to configure. This must be initialized. + * \param enable This value determines whether the CID extension should + * be used or not. Possible values are: + * - MBEDTLS_SSL_CID_ENABLED to enable the use of the CID. + * - MBEDTLS_SSL_CID_DISABLED (default) to disable the use + * of the CID. + * \param own_cid The address of the readable buffer holding the CID we want + * the peer to use when sending encrypted messages to us. + * This may be \c NULL if \p own_cid_len is \c 0. + * This parameter is unused if \p enabled is set to + * MBEDTLS_SSL_CID_DISABLED. + * \param own_cid_len The length of \p own_cid. + * This parameter is unused if \p enabled is set to + * MBEDTLS_SSL_CID_DISABLED. + * + * \note The value of \p own_cid_len must match the value of the + * \c len parameter passed to mbedtls_ssl_conf_cid() + * when configuring the ::mbedtls_ssl_config that \p ssl + * is bound to. + * + * \note This CID configuration applies to subsequent handshakes + * performed on the SSL context \p ssl, but does not trigger + * one. You still have to call `mbedtls_ssl_handshake()` + * (for the initial handshake) or `mbedtls_ssl_renegotiate()` + * (for a renegotiation handshake) explicitly after a + * successful call to this function to run the handshake. + * + * \note This call cannot guarantee that the use of the CID + * will be successfully negotiated in the next handshake, + * because the peer might not support it. Specifically: + * - On the Client, enabling the use of the CID through + * this call implies that the `ClientHello` in the next + * handshake will include the CID extension, thereby + * offering the use of the CID to the server. Only if + * the `ServerHello` contains the CID extension, too, + * the CID extension will actually be put to use. + * - On the Server, enabling the use of the CID through + * this call implies that that the server will look for + * the CID extension in a `ClientHello` from the client, + * and, if present, reply with a CID extension in its + * `ServerHello`. + * + * \note To check whether the use of the CID was negotiated + * after the subsequent handshake has completed, please + * use the API mbedtls_ssl_get_peer_cid(). + * + * \warning If the use of the CID extension is enabled in this call + * and the subsequent handshake negotiates its use, Mbed TLS + * will silently drop every packet whose CID does not match + * the CID configured in \p own_cid. It is the responsibility + * of the user to adapt the underlying transport to take care + * of CID-based demultiplexing before handing datagrams to + * Mbed TLS. + * + * \return \c 0 on success. In this case, the CID configuration + * applies to the next handshake. + * \return A negative error code on failure. + */ +int mbedtls_ssl_set_cid( mbedtls_ssl_context *ssl, + int enable, + unsigned char const *own_cid, + size_t own_cid_len ); + +/** + * \brief Get information about the use of the CID extension + * in the current connection. + * + * \param ssl The SSL context to query. + * \param enabled The address at which to store whether the CID extension + * is currently in use or not. If the CID is in use, + * `*enabled` is set to MBEDTLS_SSL_CID_ENABLED; + * otherwise, it is set to MBEDTLS_SSL_CID_DISABLED. + * \param peer_cid The address of the buffer in which to store the CID + * chosen by the peer (if the CID extension is used). + * This may be \c NULL in case the value of peer CID + * isn't needed. If it is not \c NULL, \p peer_cid_len + * must not be \c NULL. + * \param peer_cid_len The address at which to store the size of the CID + * chosen by the peer (if the CID extension is used). + * This is also the number of Bytes in \p peer_cid that + * have been written. + * This may be \c NULL in case the length of the peer CID + * isn't needed. If it is \c NULL, \p peer_cid must be + * \c NULL, too. + * + * \note This applies to the state of the CID negotiated in + * the last complete handshake. If a handshake is in + * progress, this function will attempt to complete + * the handshake first. + * + * \note If CID extensions have been exchanged but both client + * and server chose to use an empty CID, this function + * sets `*enabled` to #MBEDTLS_SSL_CID_DISABLED + * (the rationale for this is that the resulting + * communication is the same as if the CID extensions + * hadn't been used). + * + * \return \c 0 on success. + * \return A negative error code on failure. + */ +int mbedtls_ssl_get_peer_cid( mbedtls_ssl_context *ssl, + int *enabled, + unsigned char peer_cid[ MBEDTLS_SSL_CID_OUT_LEN_MAX ], + size_t *peer_cid_len ); + +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + +/** + * \brief Set the Maximum Transport Unit (MTU). + * Special value: 0 means unset (no limit). + * This represents the maximum size of a datagram payload + * handled by the transport layer (usually UDP) as determined + * by the network link and stack. In practice, this controls + * the maximum size datagram the DTLS layer will pass to the + * \c f_send() callback set using \c mbedtls_ssl_set_bio(). + * + * \note The limit on datagram size is converted to a limit on + * record payload by subtracting the current overhead of + * encapsulation and encryption/authentication if any. + * + * \note This can be called at any point during the connection, for + * example when a Path Maximum Transfer Unit (PMTU) + * estimate becomes available from other sources, + * such as lower (or higher) protocol layers. + * + * \note This setting only controls the size of the packets we send, + * and does not restrict the size of the datagrams we're + * willing to receive. Client-side, you can request the + * server to use smaller records with \c + * mbedtls_ssl_conf_max_frag_len(). + * + * \note If both a MTU and a maximum fragment length have been + * configured (or negotiated with the peer), the resulting + * lower limit on record payload (see first note) is used. + * + * \note This can only be used to decrease the maximum size + * of datagrams (hence records, see first note) sent. It + * cannot be used to increase the maximum size of records over + * the limit set by #MBEDTLS_SSL_OUT_CONTENT_LEN. + * + * \note Values lower than the current record layer expansion will + * result in an error when trying to send data. + * + * \note Using record compression together with a non-zero MTU value + * will result in an error when trying to send data. + * + * \param ssl SSL context + * \param mtu Value of the path MTU in bytes + */ +void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu ); +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + +#if defined(MBEDTLS_X509_CRT_PARSE_C) +/** + * \brief Set a connection-specific verification callback (optional). + * + * If set, the provided verify callback is called for each + * certificate in the peer's CRT chain, including the trusted + * root. For more information, please see the documentation of + * \c mbedtls_x509_crt_verify(). + * + * \note This call is analogous to mbedtls_ssl_conf_verify() but + * binds the verification callback and context to an SSL context + * as opposed to an SSL configuration. + * If mbedtls_ssl_conf_verify() and mbedtls_ssl_set_verify() + * are both used, mbedtls_ssl_set_verify() takes precedence. + * + * \param ssl The SSL context to use. + * \param f_vrfy The verification callback to use during CRT verification. + * \param p_vrfy The opaque context to be passed to the callback. + */ +void mbedtls_ssl_set_verify( mbedtls_ssl_context *ssl, + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), + void *p_vrfy ); +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + +/** + * \brief Set the timeout period for mbedtls_ssl_read() + * (Default: no timeout.) + * + * \param conf SSL configuration context + * \param timeout Timeout value in milliseconds. + * Use 0 for no timeout (default). + * + * \note With blocking I/O, this will only work if a non-NULL + * \c f_recv_timeout was set with \c mbedtls_ssl_set_bio(). + * With non-blocking I/O, this will only work if timer + * callbacks were set with \c mbedtls_ssl_set_timer_cb(). + * + * \note With non-blocking I/O, you may also skip this function + * altogether and handle timeouts at the application layer. + */ +void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ); + +#if defined(MBEDTLS_SSL_RECORD_CHECKING) +/** + * \brief Check whether a buffer contains a valid and authentic record + * that has not been seen before. (DTLS only). + * + * This function does not change the user-visible state + * of the SSL context. Its sole purpose is to provide + * an indication of the legitimacy of an incoming record. + * + * This can be useful e.g. in distributed server environments + * using the DTLS Connection ID feature, in which connections + * might need to be passed between service instances on a change + * of peer address, but where such disruptive operations should + * only happen after the validity of incoming records has been + * confirmed. + * + * \param ssl The SSL context to use. + * \param buf The address of the buffer holding the record to be checked. + * This must be a read/write buffer of length \p buflen Bytes. + * \param buflen The length of \p buf in Bytes. + * + * \note This routine only checks whether the provided buffer begins + * with a valid and authentic record that has not been seen + * before, but does not check potential data following the + * initial record. In particular, it is possible to pass DTLS + * datagrams containing multiple records, in which case only + * the first record is checked. + * + * \note This function modifies the input buffer \p buf. If you need + * to preserve the original record, you have to maintain a copy. + * + * \return \c 0 if the record is valid and authentic and has not been + * seen before. + * \return MBEDTLS_ERR_SSL_INVALID_MAC if the check completed + * successfully but the record was found to be not authentic. + * \return MBEDTLS_ERR_SSL_INVALID_RECORD if the check completed + * successfully but the record was found to be invalid for + * a reason different from authenticity checking. + * \return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD if the check completed + * successfully but the record was found to be unexpected + * in the state of the SSL context, including replayed records. + * \return Another negative error code on different kinds of failure. + * In this case, the SSL context becomes unusable and needs + * to be freed or reset before reuse. + */ +int mbedtls_ssl_check_record( mbedtls_ssl_context const *ssl, + unsigned char *buf, + size_t buflen ); +#endif /* MBEDTLS_SSL_RECORD_CHECKING */ + +/** + * \brief Set the timer callbacks (Mandatory for DTLS.) + * + * \param ssl SSL context + * \param p_timer parameter (context) shared by timer callbacks + * \param f_set_timer set timer callback + * \param f_get_timer get timer callback. Must return: + * + * \note See the documentation of \c mbedtls_ssl_set_timer_t and + * \c mbedtls_ssl_get_timer_t for the conventions this pair of + * callbacks must follow. + * + * \note On some platforms, timing.c provides + * \c mbedtls_timing_set_delay() and + * \c mbedtls_timing_get_delay() that are suitable for using + * here, except if using an event-driven style. + * + * \note See also the "DTLS tutorial" article in our knowledge base. + * https://tls.mbed.org/kb/how-to/dtls-tutorial + */ +void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl, + void *p_timer, + mbedtls_ssl_set_timer_t *f_set_timer, + mbedtls_ssl_get_timer_t *f_get_timer ); + +/** + * \brief Callback type: generate and write session ticket + * + * \note This describes what a callback implementation should do. + * This callback should generate an encrypted and + * authenticated ticket for the session and write it to the + * output buffer. Here, ticket means the opaque ticket part + * of the NewSessionTicket structure of RFC 5077. + * + * \param p_ticket Context for the callback + * \param session SSL session to be written in the ticket + * \param start Start of the output buffer + * \param end End of the output buffer + * \param tlen On exit, holds the length written + * \param lifetime On exit, holds the lifetime of the ticket in seconds + * + * \return 0 if successful, or + * a specific MBEDTLS_ERR_XXX code. + */ +typedef int mbedtls_ssl_ticket_write_t( void *p_ticket, + const mbedtls_ssl_session *session, + unsigned char *start, + const unsigned char *end, + size_t *tlen, + uint32_t *lifetime ); + +#if defined(MBEDTLS_SSL_EXPORT_KEYS) +/** + * \brief Callback type: Export key block and master secret + * + * \note This is required for certain uses of TLS, e.g. EAP-TLS + * (RFC 5216) and Thread. The key pointers are ephemeral and + * therefore must not be stored. The master secret and keys + * should not be used directly except as an input to a key + * derivation function. + * + * \param p_expkey Context for the callback + * \param ms Pointer to master secret (fixed length: 48 bytes) + * \param kb Pointer to key block, see RFC 5246 section 6.3 + * (variable length: 2 * maclen + 2 * keylen + 2 * ivlen). + * \param maclen MAC length + * \param keylen Key length + * \param ivlen IV length + * + * \return 0 if successful, or + * a specific MBEDTLS_ERR_XXX code. + */ +typedef int mbedtls_ssl_export_keys_t( void *p_expkey, + const unsigned char *ms, + const unsigned char *kb, + size_t maclen, + size_t keylen, + size_t ivlen ); + +/** + * \brief Callback type: Export key block, master secret, + * handshake randbytes and the tls_prf function + * used to derive keys. + * + * \note This is required for certain uses of TLS, e.g. EAP-TLS + * (RFC 5216) and Thread. The key pointers are ephemeral and + * therefore must not be stored. The master secret and keys + * should not be used directly except as an input to a key + * derivation function. + * + * \param p_expkey Context for the callback. + * \param ms Pointer to master secret (fixed length: 48 bytes). + * \param kb Pointer to key block, see RFC 5246 section 6.3. + * (variable length: 2 * maclen + 2 * keylen + 2 * ivlen). + * \param maclen MAC length. + * \param keylen Key length. + * \param ivlen IV length. + * \param client_random The client random bytes. + * \param server_random The server random bytes. + * \param tls_prf_type The tls_prf enum type. + * + * \return 0 if successful, or + * a specific MBEDTLS_ERR_XXX code. + */ +typedef int mbedtls_ssl_export_keys_ext_t( void *p_expkey, + const unsigned char *ms, + const unsigned char *kb, + size_t maclen, + size_t keylen, + size_t ivlen, + const unsigned char client_random[32], + const unsigned char server_random[32], + mbedtls_tls_prf_types tls_prf_type ); +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ + +/** + * \brief Callback type: parse and load session ticket + * + * \note This describes what a callback implementation should do. + * This callback should parse a session ticket as generated + * by the corresponding mbedtls_ssl_ticket_write_t function, + * and, if the ticket is authentic and valid, load the + * session. + * + * \note The implementation is allowed to modify the first len + * bytes of the input buffer, eg to use it as a temporary + * area for the decrypted ticket contents. + * + * \param p_ticket Context for the callback + * \param session SSL session to be loaded + * \param buf Start of the buffer containing the ticket + * \param len Length of the ticket. + * + * \return 0 if successful, or + * MBEDTLS_ERR_SSL_INVALID_MAC if not authentic, or + * MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED if expired, or + * any other non-zero code for other failures. + */ +typedef int mbedtls_ssl_ticket_parse_t( void *p_ticket, + mbedtls_ssl_session *session, + unsigned char *buf, + size_t len ); + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_SRV_C) +/** + * \brief Configure SSL session ticket callbacks (server only). + * (Default: none.) + * + * \note On server, session tickets are enabled by providing + * non-NULL callbacks. + * + * \note On client, use \c mbedtls_ssl_conf_session_tickets(). + * + * \param conf SSL configuration context + * \param f_ticket_write Callback for writing a ticket + * \param f_ticket_parse Callback for parsing a ticket + * \param p_ticket Context shared by the two callbacks + */ +void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf, + mbedtls_ssl_ticket_write_t *f_ticket_write, + mbedtls_ssl_ticket_parse_t *f_ticket_parse, + void *p_ticket ); +#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */ + +#if defined(MBEDTLS_SSL_EXPORT_KEYS) +/** + * \brief Configure key export callback. + * (Default: none.) + * + * \note See \c mbedtls_ssl_export_keys_t. + * + * \param conf SSL configuration context + * \param f_export_keys Callback for exporting keys + * \param p_export_keys Context for the callback + */ +void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf, + mbedtls_ssl_export_keys_t *f_export_keys, + void *p_export_keys ); + +/** + * \brief Configure extended key export callback. + * (Default: none.) + * + * \note See \c mbedtls_ssl_export_keys_ext_t. + * \warning Exported key material must not be used for any purpose + * before the (D)TLS handshake is completed + * + * \param conf SSL configuration context + * \param f_export_keys_ext Callback for exporting keys + * \param p_export_keys Context for the callback + */ +void mbedtls_ssl_conf_export_keys_ext_cb( mbedtls_ssl_config *conf, + mbedtls_ssl_export_keys_ext_t *f_export_keys_ext, + void *p_export_keys ); +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ + +#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) +/** + * \brief Configure asynchronous private key operation callbacks. + * + * \param conf SSL configuration context + * \param f_async_sign Callback to start a signature operation. See + * the description of ::mbedtls_ssl_async_sign_t + * for more information. This may be \c NULL if the + * external processor does not support any signature + * operation; in this case the private key object + * associated with the certificate will be used. + * \param f_async_decrypt Callback to start a decryption operation. See + * the description of ::mbedtls_ssl_async_decrypt_t + * for more information. This may be \c NULL if the + * external processor does not support any decryption + * operation; in this case the private key object + * associated with the certificate will be used. + * \param f_async_resume Callback to resume an asynchronous operation. See + * the description of ::mbedtls_ssl_async_resume_t + * for more information. This may not be \c NULL unless + * \p f_async_sign and \p f_async_decrypt are both + * \c NULL. + * \param f_async_cancel Callback to cancel an asynchronous operation. See + * the description of ::mbedtls_ssl_async_cancel_t + * for more information. This may be \c NULL if + * no cleanup is needed. + * \param config_data A pointer to configuration data which can be + * retrieved with + * mbedtls_ssl_conf_get_async_config_data(). The + * library stores this value without dereferencing it. + */ +void mbedtls_ssl_conf_async_private_cb( mbedtls_ssl_config *conf, + mbedtls_ssl_async_sign_t *f_async_sign, + mbedtls_ssl_async_decrypt_t *f_async_decrypt, + mbedtls_ssl_async_resume_t *f_async_resume, + mbedtls_ssl_async_cancel_t *f_async_cancel, + void *config_data ); + +/** + * \brief Retrieve the configuration data set by + * mbedtls_ssl_conf_async_private_cb(). + * + * \param conf SSL configuration context + * \return The configuration data set by + * mbedtls_ssl_conf_async_private_cb(). + */ +void *mbedtls_ssl_conf_get_async_config_data( const mbedtls_ssl_config *conf ); + +/** + * \brief Retrieve the asynchronous operation user context. + * + * \note This function may only be called while a handshake + * is in progress. + * + * \param ssl The SSL context to access. + * + * \return The asynchronous operation user context that was last + * set during the current handshake. If + * mbedtls_ssl_set_async_operation_data() has not yet been + * called during the current handshake, this function returns + * \c NULL. + */ +void *mbedtls_ssl_get_async_operation_data( const mbedtls_ssl_context *ssl ); + +/** + * \brief Retrieve the asynchronous operation user context. + * + * \note This function may only be called while a handshake + * is in progress. + * + * \param ssl The SSL context to access. + * \param ctx The new value of the asynchronous operation user context. + * Call mbedtls_ssl_get_async_operation_data() later during the + * same handshake to retrieve this value. + */ +void mbedtls_ssl_set_async_operation_data( mbedtls_ssl_context *ssl, + void *ctx ); +#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ + +/** + * \brief Callback type: generate a cookie + * + * \param ctx Context for the callback + * \param p Buffer to write to, + * must be updated to point right after the cookie + * \param end Pointer to one past the end of the output buffer + * \param info Client ID info that was passed to + * \c mbedtls_ssl_set_client_transport_id() + * \param ilen Length of info in bytes + * + * \return The callback must return 0 on success, + * or a negative error code. + */ +typedef int mbedtls_ssl_cookie_write_t( void *ctx, + unsigned char **p, unsigned char *end, + const unsigned char *info, size_t ilen ); + +/** + * \brief Callback type: verify a cookie + * + * \param ctx Context for the callback + * \param cookie Cookie to verify + * \param clen Length of cookie + * \param info Client ID info that was passed to + * \c mbedtls_ssl_set_client_transport_id() + * \param ilen Length of info in bytes + * + * \return The callback must return 0 if cookie is valid, + * or a negative error code. + */ +typedef int mbedtls_ssl_cookie_check_t( void *ctx, + const unsigned char *cookie, size_t clen, + const unsigned char *info, size_t ilen ); + +#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) +/** + * \brief Register callbacks for DTLS cookies + * (Server only. DTLS only.) + * + * Default: dummy callbacks that fail, in order to force you to + * register working callbacks (and initialize their context). + * + * To disable HelloVerifyRequest, register NULL callbacks. + * + * \warning Disabling hello verification allows your server to be used + * for amplification in DoS attacks against other hosts. + * Only disable if you known this can't happen in your + * particular environment. + * + * \note See comments on \c mbedtls_ssl_handshake() about handling + * the MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED that is expected + * on the first handshake attempt when this is enabled. + * + * \note This is also necessary to handle client reconnection from + * the same port as described in RFC 6347 section 4.2.8 (only + * the variant with cookies is supported currently). See + * comments on \c mbedtls_ssl_read() for details. + * + * \param conf SSL configuration + * \param f_cookie_write Cookie write callback + * \param f_cookie_check Cookie check callback + * \param p_cookie Context for both callbacks + */ +void mbedtls_ssl_conf_dtls_cookies( mbedtls_ssl_config *conf, + mbedtls_ssl_cookie_write_t *f_cookie_write, + mbedtls_ssl_cookie_check_t *f_cookie_check, + void *p_cookie ); + +/** + * \brief Set client's transport-level identification info. + * (Server only. DTLS only.) + * + * This is usually the IP address (and port), but could be + * anything identify the client depending on the underlying + * network stack. Used for HelloVerifyRequest with DTLS. + * This is *not* used to route the actual packets. + * + * \param ssl SSL context + * \param info Transport-level info identifying the client (eg IP + port) + * \param ilen Length of info in bytes + * + * \note An internal copy is made, so the info buffer can be reused. + * + * \return 0 on success, + * MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used on client, + * MBEDTLS_ERR_SSL_ALLOC_FAILED if out of memory. + */ +int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl, + const unsigned char *info, + size_t ilen ); + +#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */ + +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) +/** + * \brief Enable or disable anti-replay protection for DTLS. + * (DTLS only, no effect on TLS.) + * Default: enabled. + * + * \param conf SSL configuration + * \param mode MBEDTLS_SSL_ANTI_REPLAY_ENABLED or MBEDTLS_SSL_ANTI_REPLAY_DISABLED. + * + * \warning Disabling this is a security risk unless the application + * protocol handles duplicated packets in a safe way. You + * should not disable this without careful consideration. + * However, if your application already detects duplicated + * packets and needs information about them to adjust its + * transmission strategy, then you'll want to disable this. + */ +void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode ); +#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ + +#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) +/** + * \brief Set a limit on the number of records with a bad MAC + * before terminating the connection. + * (DTLS only, no effect on TLS.) + * Default: 0 (disabled). + * + * \param conf SSL configuration + * \param limit Limit, or 0 to disable. + * + * \note If the limit is N, then the connection is terminated when + * the Nth non-authentic record is seen. + * + * \note Records with an invalid header are not counted, only the + * ones going through the authentication-decryption phase. + * + * \note This is a security trade-off related to the fact that it's + * often relatively easy for an active attacker to inject UDP + * datagrams. On one hand, setting a low limit here makes it + * easier for such an attacker to forcibly terminated a + * connection. On the other hand, a high limit or no limit + * might make us waste resources checking authentication on + * many bogus packets. + */ +void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limit ); +#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + +/** + * \brief Allow or disallow packing of multiple handshake records + * within a single datagram. + * + * \param ssl The SSL context to configure. + * \param allow_packing This determines whether datagram packing may + * be used or not. A value of \c 0 means that every + * record will be sent in a separate datagram; a + * value of \c 1 means that, if space permits, + * multiple handshake messages (including CCS) belonging to + * a single flight may be packed within a single datagram. + * + * \note This is enabled by default and should only be disabled + * for test purposes, or if datagram packing causes + * interoperability issues with peers that don't support it. + * + * \note Allowing datagram packing reduces the network load since + * there's less overhead if multiple messages share the same + * datagram. Also, it increases the handshake efficiency + * since messages belonging to a single datagram will not + * be reordered in transit, and so future message buffering + * or flight retransmission (if no buffering is used) as + * means to deal with reordering are needed less frequently. + * + * \note Application records are not affected by this option and + * are currently always sent in separate datagrams. + * + */ +void mbedtls_ssl_set_datagram_packing( mbedtls_ssl_context *ssl, + unsigned allow_packing ); + +/** + * \brief Set retransmit timeout values for the DTLS handshake. + * (DTLS only, no effect on TLS.) + * + * \param conf SSL configuration + * \param min Initial timeout value in milliseconds. + * Default: 1000 (1 second). + * \param max Maximum timeout value in milliseconds. + * Default: 60000 (60 seconds). + * + * \note Default values are from RFC 6347 section 4.2.4.1. + * + * \note The 'min' value should typically be slightly above the + * expected round-trip time to your peer, plus whatever time + * it takes for the peer to process the message. For example, + * if your RTT is about 600ms and you peer needs up to 1s to + * do the cryptographic operations in the handshake, then you + * should set 'min' slightly above 1600. Lower values of 'min' + * might cause spurious resends which waste network resources, + * while larger value of 'min' will increase overall latency + * on unreliable network links. + * + * \note The more unreliable your network connection is, the larger + * your max / min ratio needs to be in order to achieve + * reliable handshakes. + * + * \note Messages are retransmitted up to log2(ceil(max/min)) times. + * For example, if min = 1s and max = 5s, the retransmit plan + * goes: send ... 1s -> resend ... 2s -> resend ... 4s -> + * resend ... 5s -> give up and return a timeout error. + */ +void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, uint32_t min, uint32_t max ); +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + +#if defined(MBEDTLS_SSL_SRV_C) +/** + * \brief Set the session cache callbacks (server-side only) + * If not set, no session resuming is done (except if session + * tickets are enabled too). + * + * The session cache has the responsibility to check for stale + * entries based on timeout. See RFC 5246 for recommendations. + * + * Warning: session.peer_cert is cleared by the SSL/TLS layer on + * connection shutdown, so do not cache the pointer! Either set + * it to NULL or make a full copy of the certificate. + * + * The get callback is called once during the initial handshake + * to enable session resuming. The get function has the + * following parameters: (void *parameter, mbedtls_ssl_session *session) + * If a valid entry is found, it should fill the master of + * the session object with the cached values and return 0, + * return 1 otherwise. Optionally peer_cert can be set as well + * if it is properly present in cache entry. + * + * The set callback is called once during the initial handshake + * to enable session resuming after the entire handshake has + * been finished. The set function has the following parameters: + * (void *parameter, const mbedtls_ssl_session *session). The function + * should create a cache entry for future retrieval based on + * the data in the session structure and should keep in mind + * that the mbedtls_ssl_session object presented (and all its referenced + * data) is cleared by the SSL/TLS layer when the connection is + * terminated. It is recommended to add metadata to determine if + * an entry is still valid in the future. Return 0 if + * successfully cached, return 1 otherwise. + * + * \param conf SSL configuration + * \param p_cache parameter (context) for both callbacks + * \param f_get_cache session get callback + * \param f_set_cache session set callback + */ +void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf, + void *p_cache, + int (*f_get_cache)(void *, mbedtls_ssl_session *), + int (*f_set_cache)(void *, const mbedtls_ssl_session *) ); +#endif /* MBEDTLS_SSL_SRV_C */ + +#if defined(MBEDTLS_SSL_CLI_C) +/** + * \brief Request resumption of session (client-side only) + * Session data is copied from presented session structure. + * + * \param ssl SSL context + * \param session session context + * + * \return 0 if successful, + * MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed, + * MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used server-side or + * arguments are otherwise invalid + * + * \sa mbedtls_ssl_get_session() + */ +int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session ); +#endif /* MBEDTLS_SSL_CLI_C */ + +/** + * \brief Load serialized session data into a session structure. + * On client, this can be used for loading saved sessions + * before resuming them with mbedtls_ssl_set_session(). + * On server, this can be used for alternative implementations + * of session cache or session tickets. + * + * \warning If a peer certificate chain is associated with the session, + * the serialized state will only contain the peer's + * end-entity certificate and the result of the chain + * verification (unless verification was disabled), but not + * the rest of the chain. + * + * \see mbedtls_ssl_session_save() + * \see mbedtls_ssl_set_session() + * + * \param session The session structure to be populated. It must have been + * initialised with mbedtls_ssl_session_init() but not + * populated yet. + * \param buf The buffer holding the serialized session data. It must be a + * readable buffer of at least \p len bytes. + * \param len The size of the serialized data in bytes. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed. + * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if input data is invalid. + * \return #MBEDTLS_ERR_SSL_VERSION_MISMATCH if the serialized data + * was generated in a different version or configuration of + * Mbed TLS. + * \return Another negative value for other kinds of errors (for + * example, unsupported features in the embedded certificate). + */ +int mbedtls_ssl_session_load( mbedtls_ssl_session *session, + const unsigned char *buf, + size_t len ); + +/** + * \brief Save session structure as serialized data in a buffer. + * On client, this can be used for saving session data, + * potentially in non-volatile storage, for resuming later. + * On server, this can be used for alternative implementations + * of session cache or session tickets. + * + * \see mbedtls_ssl_session_load() + * \see mbedtls_ssl_get_session_pointer() + * + * \param session The session structure to be saved. + * \param buf The buffer to write the serialized data to. It must be a + * writeable buffer of at least \p len bytes, or may be \c + * NULL if \p len is \c 0. + * \param buf_len The number of bytes available for writing in \p buf. + * \param olen The size in bytes of the data that has been or would have + * been written. It must point to a valid \c size_t. + * + * \note \p olen is updated to the correct value regardless of + * whether \p buf_len was large enough. This makes it possible + * to determine the necessary size by calling this function + * with \p buf set to \c NULL and \p buf_len to \c 0. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL if \p buf is too small. + */ +int mbedtls_ssl_session_save( const mbedtls_ssl_session *session, + unsigned char *buf, + size_t buf_len, + size_t *olen ); + +/** + * \brief Get a pointer to the current session structure, for example + * to serialize it. + * + * \warning Ownership of the session remains with the SSL context, and + * the returned pointer is only guaranteed to be valid until + * the next API call operating on the same \p ssl context. + * + * \see mbedtls_ssl_session_save() + * + * \param ssl The SSL context. + * + * \return A pointer to the current session if successful. + * \return \c NULL if no session is active. + */ +const mbedtls_ssl_session *mbedtls_ssl_get_session_pointer( const mbedtls_ssl_context *ssl ); + +/** + * \brief Set the list of allowed ciphersuites and the preference + * order. First in the list has the highest preference. + * (Overrides all version-specific lists) + * + * The ciphersuites array is not copied, and must remain + * valid for the lifetime of the ssl_config. + * + * Note: The server uses its own preferences + * over the preference of the client unless + * MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE is defined! + * + * \param conf SSL configuration + * \param ciphersuites 0-terminated list of allowed ciphersuites + */ +void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf, + const int *ciphersuites ); + +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) +#define MBEDTLS_SSL_UNEXPECTED_CID_IGNORE 0 +#define MBEDTLS_SSL_UNEXPECTED_CID_FAIL 1 +/** + * \brief Specify the length of Connection IDs for incoming + * encrypted DTLS records, as well as the behaviour + * on unexpected CIDs. + * + * By default, the CID length is set to \c 0, + * and unexpected CIDs are silently ignored. + * + * \param conf The SSL configuration to modify. + * \param len The length in Bytes of the CID fields in encrypted + * DTLS records using the CID mechanism. This must + * not be larger than #MBEDTLS_SSL_CID_OUT_LEN_MAX. + * \param ignore_other_cids This determines the stack's behaviour when + * receiving a record with an unexpected CID. + * Possible values are: + * - #MBEDTLS_SSL_UNEXPECTED_CID_IGNORE + * In this case, the record is silently ignored. + * - #MBEDTLS_SSL_UNEXPECTED_CID_FAIL + * In this case, the stack fails with the specific + * error code #MBEDTLS_ERR_SSL_UNEXPECTED_CID. + * + * \note The CID specification allows implementations to either + * use a common length for all incoming connection IDs or + * allow variable-length incoming IDs. Mbed TLS currently + * requires a common length for all connections sharing the + * same SSL configuration; this allows simpler parsing of + * record headers. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if \p own_cid_len + * is too large. + */ +int mbedtls_ssl_conf_cid( mbedtls_ssl_config *conf, size_t len, + int ignore_other_cids ); +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + +/** + * \brief Set the list of allowed ciphersuites and the + * preference order for a specific version of the protocol. + * (Only useful on the server side) + * + * The ciphersuites array is not copied, and must remain + * valid for the lifetime of the ssl_config. + * + * \param conf SSL configuration + * \param ciphersuites 0-terminated list of allowed ciphersuites + * \param major Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 + * supported) + * \param minor Minor version number (MBEDTLS_SSL_MINOR_VERSION_0, + * MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2, + * MBEDTLS_SSL_MINOR_VERSION_3 supported) + * + * \note With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 + * and MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2 + */ +void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf, + const int *ciphersuites, + int major, int minor ); + +#if defined(MBEDTLS_X509_CRT_PARSE_C) +/** + * \brief Set the X.509 security profile used for verification + * + * \note The restrictions are enforced for all certificates in the + * chain. However, signatures in the handshake are not covered + * by this setting but by \b mbedtls_ssl_conf_sig_hashes(). + * + * \param conf SSL configuration + * \param profile Profile to use + */ +void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf, + const mbedtls_x509_crt_profile *profile ); + +/** + * \brief Set the data required to verify peer certificate + * + * \note See \c mbedtls_x509_crt_verify() for notes regarding the + * parameters ca_chain (maps to trust_ca for that function) + * and ca_crl. + * + * \param conf SSL configuration + * \param ca_chain trusted CA chain (meaning all fully trusted top-level CAs) + * \param ca_crl trusted CA CRLs + */ +void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf, + mbedtls_x509_crt *ca_chain, + mbedtls_x509_crl *ca_crl ); + +#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) +/** + * \brief Set the trusted certificate callback. + * + * This API allows to register the set of trusted certificates + * through a callback, instead of a linked list as configured + * by mbedtls_ssl_conf_ca_chain(). + * + * This is useful for example in contexts where a large number + * of CAs are used, and the inefficiency of maintaining them + * in a linked list cannot be tolerated. It is also useful when + * the set of trusted CAs needs to be modified frequently. + * + * See the documentation of `mbedtls_x509_crt_ca_cb_t` for + * more information. + * + * \param conf The SSL configuration to register the callback with. + * \param f_ca_cb The trusted certificate callback to use when verifying + * certificate chains. + * \param p_ca_cb The context to be passed to \p f_ca_cb (for example, + * a reference to a trusted CA database). + * + * \note This API is incompatible with mbedtls_ssl_conf_ca_chain(): + * Any call to this function overwrites the values set through + * earlier calls to mbedtls_ssl_conf_ca_chain() or + * mbedtls_ssl_conf_ca_cb(). + * + * \note This API is incompatible with CA indication in + * CertificateRequest messages: A server-side SSL context which + * is bound to an SSL configuration that uses a CA callback + * configured via mbedtls_ssl_conf_ca_cb(), and which requires + * client authentication, will send an empty CA list in the + * corresponding CertificateRequest message. + * + * \note This API is incompatible with mbedtls_ssl_set_hs_ca_chain(): + * If an SSL context is bound to an SSL configuration which uses + * CA callbacks configured via mbedtls_ssl_conf_ca_cb(), then + * calls to mbedtls_ssl_set_hs_ca_chain() have no effect. + * + * \note The use of this API disables the use of restartable ECC + * during X.509 CRT signature verification (but doesn't affect + * other uses). + * + * \warning This API is incompatible with the use of CRLs. Any call to + * mbedtls_ssl_conf_ca_cb() unsets CRLs configured through + * earlier calls to mbedtls_ssl_conf_ca_chain(). + * + * \warning In multi-threaded environments, the callback \p f_ca_cb + * must be thread-safe, and it is the user's responsibility + * to guarantee this (for example through a mutex + * contained in the callback context pointed to by \p p_ca_cb). + */ +void mbedtls_ssl_conf_ca_cb( mbedtls_ssl_config *conf, + mbedtls_x509_crt_ca_cb_t f_ca_cb, + void *p_ca_cb ); +#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ + +/** + * \brief Set own certificate chain and private key + * + * \note own_cert should contain in order from the bottom up your + * certificate chain. The top certificate (self-signed) + * can be omitted. + * + * \note On server, this function can be called multiple times to + * provision more than one cert/key pair (eg one ECDSA, one + * RSA with SHA-256, one RSA with SHA-1). An adequate + * certificate will be selected according to the client's + * advertised capabilities. In case multiple certificates are + * adequate, preference is given to the one set by the first + * call to this function, then second, etc. + * + * \note On client, only the first call has any effect. That is, + * only one client certificate can be provisioned. The + * server's preferences in its CertificateRequest message will + * be ignored and our only cert will be sent regardless of + * whether it matches those preferences - the server can then + * decide what it wants to do with it. + * + * \note The provided \p pk_key needs to match the public key in the + * first certificate in \p own_cert, or all handshakes using + * that certificate will fail. It is your responsibility + * to ensure that; this function will not perform any check. + * You may use mbedtls_pk_check_pair() in order to perform + * this check yourself, but be aware that this function can + * be computationally expensive on some key types. + * + * \param conf SSL configuration + * \param own_cert own public certificate chain + * \param pk_key own private key + * + * \return 0 on success or MBEDTLS_ERR_SSL_ALLOC_FAILED + */ +int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf, + mbedtls_x509_crt *own_cert, + mbedtls_pk_context *pk_key ); +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) +/** + * \brief Configure a pre-shared key (PSK) and identity + * to be used in PSK-based ciphersuites. + * + * \note This is mainly useful for clients. Servers will usually + * want to use \c mbedtls_ssl_conf_psk_cb() instead. + * + * \note A PSK set by \c mbedtls_ssl_set_hs_psk() in the PSK callback + * takes precedence over a PSK configured by this function. + * + * \warning Currently, clients can only register a single pre-shared key. + * Calling this function or mbedtls_ssl_conf_psk_opaque() more + * than once will overwrite values configured in previous calls. + * Support for setting multiple PSKs on clients and selecting + * one based on the identity hint is not a planned feature, + * but feedback is welcomed. + * + * \param conf The SSL configuration to register the PSK with. + * \param psk The pointer to the pre-shared key to use. + * \param psk_len The length of the pre-shared key in bytes. + * \param psk_identity The pointer to the pre-shared key identity. + * \param psk_identity_len The length of the pre-shared key identity + * in bytes. + * + * \note The PSK and its identity are copied internally and + * hence need not be preserved by the caller for the lifetime + * of the SSL configuration. + * + * \return \c 0 if successful. + * \return An \c MBEDTLS_ERR_SSL_XXX error code on failure. + */ +int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf, + const unsigned char *psk, size_t psk_len, + const unsigned char *psk_identity, size_t psk_identity_len ); + +#if defined(MBEDTLS_USE_PSA_CRYPTO) +/** + * \brief Configure an opaque pre-shared key (PSK) and identity + * to be used in PSK-based ciphersuites. + * + * \note This is mainly useful for clients. Servers will usually + * want to use \c mbedtls_ssl_conf_psk_cb() instead. + * + * \note An opaque PSK set by \c mbedtls_ssl_set_hs_psk_opaque() in + * the PSK callback takes precedence over an opaque PSK + * configured by this function. + * + * \warning Currently, clients can only register a single pre-shared key. + * Calling this function or mbedtls_ssl_conf_psk() more than + * once will overwrite values configured in previous calls. + * Support for setting multiple PSKs on clients and selecting + * one based on the identity hint is not a planned feature, + * but feedback is welcomed. + * + * \param conf The SSL configuration to register the PSK with. + * \param psk The identifier of the key slot holding the PSK. + * Until \p conf is destroyed or this function is successfully + * called again, the key slot \p psk must be populated with a + * key of type PSA_ALG_CATEGORY_KEY_DERIVATION whose policy + * allows its use for the key derivation algorithm applied + * in the handshake. + * \param psk_identity The pointer to the pre-shared key identity. + * \param psk_identity_len The length of the pre-shared key identity + * in bytes. + * + * \note The PSK identity hint is copied internally and hence need + * not be preserved by the caller for the lifetime of the + * SSL configuration. + * + * \return \c 0 if successful. + * \return An \c MBEDTLS_ERR_SSL_XXX error code on failure. + */ +int mbedtls_ssl_conf_psk_opaque( mbedtls_ssl_config *conf, + psa_key_id_t psk, + const unsigned char *psk_identity, + size_t psk_identity_len ); +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +/** + * \brief Set the pre-shared Key (PSK) for the current handshake. + * + * \note This should only be called inside the PSK callback, + * i.e. the function passed to \c mbedtls_ssl_conf_psk_cb(). + * + * \note A PSK set by this function takes precedence over a PSK + * configured by \c mbedtls_ssl_conf_psk(). + * + * \param ssl The SSL context to configure a PSK for. + * \param psk The pointer to the pre-shared key. + * \param psk_len The length of the pre-shared key in bytes. + * + * \return \c 0 if successful. + * \return An \c MBEDTLS_ERR_SSL_XXX error code on failure. + */ +int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl, + const unsigned char *psk, size_t psk_len ); + +#if defined(MBEDTLS_USE_PSA_CRYPTO) +/** + * \brief Set an opaque pre-shared Key (PSK) for the current handshake. + * + * \note This should only be called inside the PSK callback, + * i.e. the function passed to \c mbedtls_ssl_conf_psk_cb(). + * + * \note An opaque PSK set by this function takes precedence over an + * opaque PSK configured by \c mbedtls_ssl_conf_psk_opaque(). + * + * \param ssl The SSL context to configure a PSK for. + * \param psk The identifier of the key slot holding the PSK. + * For the duration of the current handshake, the key slot + * must be populated with a key of type + * PSA_ALG_CATEGORY_KEY_DERIVATION whose policy allows its + * use for the key derivation algorithm + * applied in the handshake. + * + * \return \c 0 if successful. + * \return An \c MBEDTLS_ERR_SSL_XXX error code on failure. + */ +int mbedtls_ssl_set_hs_psk_opaque( mbedtls_ssl_context *ssl, + psa_key_id_t psk ); +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +/** + * \brief Set the PSK callback (server-side only). + * + * If set, the PSK callback is called for each + * handshake where a PSK-based ciphersuite was negotiated. + * The caller provides the identity received and wants to + * receive the actual PSK data and length. + * + * The callback has the following parameters: + * - \c void*: The opaque pointer \p p_psk. + * - \c mbedtls_ssl_context*: The SSL context to which + * the operation applies. + * - \c const unsigned char*: The PSK identity + * selected by the client. + * - \c size_t: The length of the PSK identity + * selected by the client. + * + * If a valid PSK identity is found, the callback should use + * \c mbedtls_ssl_set_hs_psk() or + * \c mbedtls_ssl_set_hs_psk_opaque() + * on the SSL context to set the correct PSK and return \c 0. + * Any other return value will result in a denied PSK identity. + * + * \note A dynamic PSK (i.e. set by the PSK callback) takes + * precedence over a static PSK (i.e. set by + * \c mbedtls_ssl_conf_psk() or + * \c mbedtls_ssl_conf_psk_opaque()). + * This means that if you set a PSK callback using this + * function, you don't need to set a PSK using + * \c mbedtls_ssl_conf_psk() or + * \c mbedtls_ssl_conf_psk_opaque()). + * + * \param conf The SSL configuration to register the callback with. + * \param f_psk The callback for selecting and setting the PSK based + * in the PSK identity chosen by the client. + * \param p_psk A pointer to an opaque structure to be passed to + * the callback, for example a PSK store. + */ +void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf, + int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *, + size_t), + void *p_psk ); +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ + +#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) + +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif + +/** + * \brief Set the Diffie-Hellman public P and G values, + * read as hexadecimal strings (server-side only) + * (Default values: MBEDTLS_DHM_RFC3526_MODP_2048_[PG]) + * + * \param conf SSL configuration + * \param dhm_P Diffie-Hellman-Merkle modulus + * \param dhm_G Diffie-Hellman-Merkle generator + * + * \deprecated Superseded by \c mbedtls_ssl_conf_dh_param_bin. + * + * \return 0 if successful + */ +MBEDTLS_DEPRECATED int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf, + const char *dhm_P, + const char *dhm_G ); + +#endif /* MBEDTLS_DEPRECATED_REMOVED */ + +/** + * \brief Set the Diffie-Hellman public P and G values + * from big-endian binary presentations. + * (Default values: MBEDTLS_DHM_RFC3526_MODP_2048_[PG]_BIN) + * + * \param conf SSL configuration + * \param dhm_P Diffie-Hellman-Merkle modulus in big-endian binary form + * \param P_len Length of DHM modulus + * \param dhm_G Diffie-Hellman-Merkle generator in big-endian binary form + * \param G_len Length of DHM generator + * + * \return 0 if successful + */ +int mbedtls_ssl_conf_dh_param_bin( mbedtls_ssl_config *conf, + const unsigned char *dhm_P, size_t P_len, + const unsigned char *dhm_G, size_t G_len ); + +/** + * \brief Set the Diffie-Hellman public P and G values, + * read from existing context (server-side only) + * + * \param conf SSL configuration + * \param dhm_ctx Diffie-Hellman-Merkle context + * + * \return 0 if successful + */ +int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx ); +#endif /* MBEDTLS_DHM_C && defined(MBEDTLS_SSL_SRV_C) */ + +#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) +/** + * \brief Set the minimum length for Diffie-Hellman parameters. + * (Client-side only.) + * (Default: 1024 bits.) + * + * \param conf SSL configuration + * \param bitlen Minimum bit length of the DHM prime + */ +void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, + unsigned int bitlen ); +#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */ + +#if defined(MBEDTLS_ECP_C) +/** + * \brief Set the allowed curves in order of preference. + * (Default: all defined curves in order of decreasing size, + * except that Montgomery curves come last. This order + * is likely to change in a future version.) + * + * On server: this only affects selection of the ECDHE curve; + * the curves used for ECDH and ECDSA are determined by the + * list of available certificates instead. + * + * On client: this affects the list of curves offered for any + * use. The server can override our preference order. + * + * Both sides: limits the set of curves accepted for use in + * ECDHE and in the peer's end-entity certificate. + * + * \note This has no influence on which curves are allowed inside the + * certificate chains, see \c mbedtls_ssl_conf_cert_profile() + * for that. For the end-entity certificate however, the key + * will be accepted only if it is allowed both by this list + * and by the cert profile. + * + * \note This list should be ordered by decreasing preference + * (preferred curve first). + * + * \param conf SSL configuration + * \param curves Ordered list of allowed curves, + * terminated by MBEDTLS_ECP_DP_NONE. + */ +void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf, + const mbedtls_ecp_group_id *curves ); +#endif /* MBEDTLS_ECP_C */ + +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) +/** + * \brief Set the allowed hashes for signatures during the handshake. + * (Default: all SHA-2 hashes, largest first. Also SHA-1 if + * the compile-time option + * `MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE` is enabled.) + * + * \note This only affects which hashes are offered and can be used + * for signatures during the handshake. Hashes for message + * authentication and the TLS PRF are controlled by the + * ciphersuite, see \c mbedtls_ssl_conf_ciphersuites(). Hashes + * used for certificate signature are controlled by the + * verification profile, see \c mbedtls_ssl_conf_cert_profile(). + * + * \note This list should be ordered by decreasing preference + * (preferred hash first). + * + * \param conf SSL configuration + * \param hashes Ordered list of allowed signature hashes, + * terminated by \c MBEDTLS_MD_NONE. + */ +void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf, + const int *hashes ); +#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ + +#if defined(MBEDTLS_X509_CRT_PARSE_C) +/** + * \brief Set or reset the hostname to check against the received + * server certificate. It sets the ServerName TLS extension, + * too, if that extension is enabled. (client-side only) + * + * \param ssl SSL context + * \param hostname the server hostname, may be NULL to clear hostname + + * \note Maximum hostname length MBEDTLS_SSL_MAX_HOST_NAME_LEN. + * + * \return 0 if successful, MBEDTLS_ERR_SSL_ALLOC_FAILED on + * allocation failure, MBEDTLS_ERR_SSL_BAD_INPUT_DATA on + * too long input hostname. + * + * Hostname set to the one provided on success (cleared + * when NULL). On allocation failure hostname is cleared. + * On too long input failure, old hostname is unchanged. + */ +int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname ); +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) +/** + * \brief Set own certificate and key for the current handshake + * + * \note Same as \c mbedtls_ssl_conf_own_cert() but for use within + * the SNI callback. + * + * \param ssl SSL context + * \param own_cert own public certificate chain + * \param pk_key own private key + * + * \return 0 on success or MBEDTLS_ERR_SSL_ALLOC_FAILED + */ +int mbedtls_ssl_set_hs_own_cert( mbedtls_ssl_context *ssl, + mbedtls_x509_crt *own_cert, + mbedtls_pk_context *pk_key ); + +/** + * \brief Set the data required to verify peer certificate for the + * current handshake + * + * \note Same as \c mbedtls_ssl_conf_ca_chain() but for use within + * the SNI callback. + * + * \param ssl SSL context + * \param ca_chain trusted CA chain (meaning all fully trusted top-level CAs) + * \param ca_crl trusted CA CRLs + */ +void mbedtls_ssl_set_hs_ca_chain( mbedtls_ssl_context *ssl, + mbedtls_x509_crt *ca_chain, + mbedtls_x509_crl *ca_crl ); + +/** + * \brief Set authmode for the current handshake. + * + * \note Same as \c mbedtls_ssl_conf_authmode() but for use within + * the SNI callback. + * + * \param ssl SSL context + * \param authmode MBEDTLS_SSL_VERIFY_NONE, MBEDTLS_SSL_VERIFY_OPTIONAL or + * MBEDTLS_SSL_VERIFY_REQUIRED + */ +void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl, + int authmode ); + +/** + * \brief Set server side ServerName TLS extension callback + * (optional, server-side only). + * + * If set, the ServerName callback is called whenever the + * server receives a ServerName TLS extension from the client + * during a handshake. The ServerName callback has the + * following parameters: (void *parameter, mbedtls_ssl_context *ssl, + * const unsigned char *hostname, size_t len). If a suitable + * certificate is found, the callback must set the + * certificate(s) and key(s) to use with \c + * mbedtls_ssl_set_hs_own_cert() (can be called repeatedly), + * and may optionally adjust the CA and associated CRL with \c + * mbedtls_ssl_set_hs_ca_chain() as well as the client + * authentication mode with \c mbedtls_ssl_set_hs_authmode(), + * then must return 0. If no matching name is found, the + * callback must either set a default cert, or + * return non-zero to abort the handshake at this point. + * + * \param conf SSL configuration + * \param f_sni verification function + * \param p_sni verification parameter + */ +void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf, + int (*f_sni)(void *, mbedtls_ssl_context *, const unsigned char *, + size_t), + void *p_sni ); +#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +/** + * \brief Set the EC J-PAKE password for current handshake. + * + * \note An internal copy is made, and destroyed as soon as the + * handshake is completed, or when the SSL context is reset or + * freed. + * + * \note The SSL context needs to be already set up. The right place + * to call this function is between \c mbedtls_ssl_setup() or + * \c mbedtls_ssl_reset() and \c mbedtls_ssl_handshake(). + * + * \param ssl SSL context + * \param pw EC J-PAKE password (pre-shared secret) + * \param pw_len length of pw in bytes + * + * \return 0 on success, or a negative error code. + */ +int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, + const unsigned char *pw, + size_t pw_len ); +#endif /*MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ + +#if defined(MBEDTLS_SSL_ALPN) +/** + * \brief Set the supported Application Layer Protocols. + * + * \param conf SSL configuration + * \param protos Pointer to a NULL-terminated list of supported protocols, + * in decreasing preference order. The pointer to the list is + * recorded by the library for later reference as required, so + * the lifetime of the table must be at least as long as the + * lifetime of the SSL configuration structure. + * + * \return 0 on success, or MBEDTLS_ERR_SSL_BAD_INPUT_DATA. + */ +int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **protos ); + +/** + * \brief Get the name of the negotiated Application Layer Protocol. + * This function should be called after the handshake is + * completed. + * + * \param ssl SSL context + * + * \return Protocol name, or NULL if no protocol was negotiated. + */ +const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl ); +#endif /* MBEDTLS_SSL_ALPN */ + +#if defined(MBEDTLS_SSL_DTLS_SRTP) +#if defined(MBEDTLS_DEBUG_C) +static inline const char *mbedtls_ssl_get_srtp_profile_as_string( mbedtls_ssl_srtp_profile profile ) +{ + switch( profile ) + { + case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80: + return( "MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80" ); + case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32: + return( "MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" ); + case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80: + return( "MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80" ); + case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32: + return( "MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32" ); + default: break; + } + return( "" ); +} +#endif /* MBEDTLS_DEBUG_C */ +/** + * \brief Manage support for mki(master key id) value + * in use_srtp extension. + * MKI is an optional part of SRTP used for key management + * and re-keying. See RFC3711 section 3.1 for details. + * The default value is + * #MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED. + * + * \param conf The SSL configuration to manage mki support. + * \param support_mki_value Enable or disable mki usage. Values are + * #MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED + * or #MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED. + */ +void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf, + int support_mki_value ); + +/** + * \brief Set the supported DTLS-SRTP protection profiles. + * + * \param conf SSL configuration + * \param profiles Pointer to a List of MBEDTLS_TLS_SRTP_UNSET terminated + * supported protection profiles + * in decreasing preference order. + * The pointer to the list is recorded by the library + * for later reference as required, so the lifetime + * of the table must be at least as long as the lifetime + * of the SSL configuration structure. + * The list must not hold more than + * MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH elements + * (excluding the terminating MBEDTLS_TLS_SRTP_UNSET). + * + * \return 0 on success + * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA when the list of + * protection profiles is incorrect. + */ +int mbedtls_ssl_conf_dtls_srtp_protection_profiles + ( mbedtls_ssl_config *conf, + const mbedtls_ssl_srtp_profile *profiles ); + +/** + * \brief Set the mki_value for the current DTLS-SRTP session. + * + * \param ssl SSL context to use. + * \param mki_value The MKI value to set. + * \param mki_len The length of the MKI value. + * + * \note This function is relevant on client side only. + * The server discovers the mki value during handshake. + * A mki value set on server side using this function + * is ignored. + * + * \return 0 on success + * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA + * \return #MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE + */ +int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl, + unsigned char *mki_value, + uint16_t mki_len ); +/** + * \brief Get the negotiated DTLS-SRTP information: + * Protection profile and MKI value. + * + * \warning This function must be called after the handshake is + * completed. The value returned by this function must + * not be trusted or acted upon before the handshake completes. + * + * \param ssl The SSL context to query. + * \param dtls_srtp_info The negotiated DTLS-SRTP information: + * - Protection profile in use. + * A direct mapping of the iana defined value for protection + * profile on an uint16_t. + http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml + * #MBEDTLS_TLS_SRTP_UNSET if the use of SRTP was not negotiated + * or peer's Hello packet was not parsed yet. + * - mki size and value( if size is > 0 ). + */ +void mbedtls_ssl_get_dtls_srtp_negotiation_result( const mbedtls_ssl_context *ssl, + mbedtls_dtls_srtp_info *dtls_srtp_info ); +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + +/** + * \brief Set the maximum supported version sent from the client side + * and/or accepted at the server side + * (Default: MBEDTLS_SSL_MAX_MAJOR_VERSION, MBEDTLS_SSL_MAX_MINOR_VERSION) + * + * \note This ignores ciphersuites from higher versions. + * + * \note With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 and + * MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2 + * + * \param conf SSL configuration + * \param major Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 supported) + * \param minor Minor version number (MBEDTLS_SSL_MINOR_VERSION_0, + * MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2, + * MBEDTLS_SSL_MINOR_VERSION_3 supported) + */ +void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor ); + +/** + * \brief Set the minimum accepted SSL/TLS protocol version + * (Default: TLS 1.0) + * + * \note Input outside of the SSL_MAX_XXXXX_VERSION and + * SSL_MIN_XXXXX_VERSION range is ignored. + * + * \note MBEDTLS_SSL_MINOR_VERSION_0 (SSL v3) should be avoided. + * + * \note With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 and + * MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2 + * + * \param conf SSL configuration + * \param major Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 supported) + * \param minor Minor version number (MBEDTLS_SSL_MINOR_VERSION_0, + * MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2, + * MBEDTLS_SSL_MINOR_VERSION_3 supported) + */ +void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor ); + +#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C) +/** + * \brief Set the fallback flag (client-side only). + * (Default: MBEDTLS_SSL_IS_NOT_FALLBACK). + * + * \note Set to MBEDTLS_SSL_IS_FALLBACK when preparing a fallback + * connection, that is a connection with max_version set to a + * lower value than the value you're willing to use. Such + * fallback connections are not recommended but are sometimes + * necessary to interoperate with buggy (version-intolerant) + * servers. + * + * \warning You should NOT set this to MBEDTLS_SSL_IS_FALLBACK for + * non-fallback connections! This would appear to work for a + * while, then cause failures when the server is upgraded to + * support a newer TLS version. + * + * \param conf SSL configuration + * \param fallback MBEDTLS_SSL_IS_NOT_FALLBACK or MBEDTLS_SSL_IS_FALLBACK + */ +void mbedtls_ssl_conf_fallback( mbedtls_ssl_config *conf, char fallback ); +#endif /* MBEDTLS_SSL_FALLBACK_SCSV && MBEDTLS_SSL_CLI_C */ + +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) +/** + * \brief Enable or disable Encrypt-then-MAC + * (Default: MBEDTLS_SSL_ETM_ENABLED) + * + * \note This should always be enabled, it is a security + * improvement, and should not cause any interoperability + * issue (used only if the peer supports it too). + * + * \param conf SSL configuration + * \param etm MBEDTLS_SSL_ETM_ENABLED or MBEDTLS_SSL_ETM_DISABLED + */ +void mbedtls_ssl_conf_encrypt_then_mac( mbedtls_ssl_config *conf, char etm ); +#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ + +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) +/** + * \brief Enable or disable Extended Master Secret negotiation. + * (Default: MBEDTLS_SSL_EXTENDED_MS_ENABLED) + * + * \note This should always be enabled, it is a security fix to the + * protocol, and should not cause any interoperability issue + * (used only if the peer supports it too). + * + * \param conf SSL configuration + * \param ems MBEDTLS_SSL_EXTENDED_MS_ENABLED or MBEDTLS_SSL_EXTENDED_MS_DISABLED + */ +void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems ); +#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ + +#if defined(MBEDTLS_ARC4_C) +/** + * \brief Disable or enable support for RC4 + * (Default: MBEDTLS_SSL_ARC4_DISABLED) + * + * \warning Use of RC4 in DTLS/TLS has been prohibited by RFC 7465 + * for security reasons. Use at your own risk. + * + * \note This function is deprecated and will be removed in + * a future version of the library. + * RC4 is disabled by default at compile time and needs to be + * actively enabled for use with legacy systems. + * + * \param conf SSL configuration + * \param arc4 MBEDTLS_SSL_ARC4_ENABLED or MBEDTLS_SSL_ARC4_DISABLED + */ +void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 ); +#endif /* MBEDTLS_ARC4_C */ + +#if defined(MBEDTLS_SSL_SRV_C) +/** + * \brief Whether to send a list of acceptable CAs in + * CertificateRequest messages. + * (Default: do send) + * + * \param conf SSL configuration + * \param cert_req_ca_list MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED or + * MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED + */ +void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf, + char cert_req_ca_list ); +#endif /* MBEDTLS_SSL_SRV_C */ + +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) +/** + * \brief Set the maximum fragment length to emit and/or negotiate. + * (Typical: the smaller of #MBEDTLS_SSL_IN_CONTENT_LEN and + * #MBEDTLS_SSL_OUT_CONTENT_LEN, usually `2^14` bytes) + * (Server: set maximum fragment length to emit, + * usually negotiated by the client during handshake) + * (Client: set maximum fragment length to emit *and* + * negotiate with the server during handshake) + * (Default: #MBEDTLS_SSL_MAX_FRAG_LEN_NONE) + * + * \note On the client side, the maximum fragment length extension + * *will not* be used, unless the maximum fragment length has + * been set via this function to a value different than + * #MBEDTLS_SSL_MAX_FRAG_LEN_NONE. + * + * \note With TLS, this currently only affects ApplicationData (sent + * with \c mbedtls_ssl_read()), not handshake messages. + * With DTLS, this affects both ApplicationData and handshake. + * + * \note This sets the maximum length for a record's payload, + * excluding record overhead that will be added to it, see + * \c mbedtls_ssl_get_record_expansion(). + * + * \note For DTLS, it is also possible to set a limit for the total + * size of datagrams passed to the transport layer, including + * record overhead, see \c mbedtls_ssl_set_mtu(). + * + * \param conf SSL configuration + * \param mfl_code Code for maximum fragment length (allowed values: + * MBEDTLS_SSL_MAX_FRAG_LEN_512, MBEDTLS_SSL_MAX_FRAG_LEN_1024, + * MBEDTLS_SSL_MAX_FRAG_LEN_2048, MBEDTLS_SSL_MAX_FRAG_LEN_4096) + * + * \return 0 if successful or MBEDTLS_ERR_SSL_BAD_INPUT_DATA + */ +int mbedtls_ssl_conf_max_frag_len( mbedtls_ssl_config *conf, unsigned char mfl_code ); +#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ + +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) +/** + * \brief Activate negotiation of truncated HMAC + * (Default: MBEDTLS_SSL_TRUNC_HMAC_DISABLED) + * + * \param conf SSL configuration + * \param truncate Enable or disable (MBEDTLS_SSL_TRUNC_HMAC_ENABLED or + * MBEDTLS_SSL_TRUNC_HMAC_DISABLED) + */ +void mbedtls_ssl_conf_truncated_hmac( mbedtls_ssl_config *conf, int truncate ); +#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ + +#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) +/** + * \brief Enable / Disable 1/n-1 record splitting + * (Default: MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED) + * + * \note Only affects SSLv3 and TLS 1.0, not higher versions. + * Does not affect non-CBC ciphersuites in any version. + * + * \param conf SSL configuration + * \param split MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED or + * MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED + */ +void mbedtls_ssl_conf_cbc_record_splitting( mbedtls_ssl_config *conf, char split ); +#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */ + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) +/** + * \brief Enable / Disable session tickets (client only). + * (Default: MBEDTLS_SSL_SESSION_TICKETS_ENABLED.) + * + * \note On server, use \c mbedtls_ssl_conf_session_tickets_cb(). + * + * \param conf SSL configuration + * \param use_tickets Enable or disable (MBEDTLS_SSL_SESSION_TICKETS_ENABLED or + * MBEDTLS_SSL_SESSION_TICKETS_DISABLED) + */ +void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets ); +#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ + +#if defined(MBEDTLS_SSL_RENEGOTIATION) +/** + * \brief Enable / Disable renegotiation support for connection when + * initiated by peer + * (Default: MBEDTLS_SSL_RENEGOTIATION_DISABLED) + * + * \warning It is recommended to always disable renegotiation unless you + * know you need it and you know what you're doing. In the + * past, there have been several issues associated with + * renegotiation or a poor understanding of its properties. + * + * \note Server-side, enabling renegotiation also makes the server + * susceptible to a resource DoS by a malicious client. + * + * \param conf SSL configuration + * \param renegotiation Enable or disable (MBEDTLS_SSL_RENEGOTIATION_ENABLED or + * MBEDTLS_SSL_RENEGOTIATION_DISABLED) + */ +void mbedtls_ssl_conf_renegotiation( mbedtls_ssl_config *conf, int renegotiation ); +#endif /* MBEDTLS_SSL_RENEGOTIATION */ + +/** + * \brief Prevent or allow legacy renegotiation. + * (Default: MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION) + * + * MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION allows connections to + * be established even if the peer does not support + * secure renegotiation, but does not allow renegotiation + * to take place if not secure. + * (Interoperable and secure option) + * + * MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION allows renegotiations + * with non-upgraded peers. Allowing legacy renegotiation + * makes the connection vulnerable to specific man in the + * middle attacks. (See RFC 5746) + * (Most interoperable and least secure option) + * + * MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE breaks off connections + * if peer does not support secure renegotiation. Results + * in interoperability issues with non-upgraded peers + * that do not support renegotiation altogether. + * (Most secure option, interoperability issues) + * + * \param conf SSL configuration + * \param allow_legacy Prevent or allow (SSL_NO_LEGACY_RENEGOTIATION, + * SSL_ALLOW_LEGACY_RENEGOTIATION or + * MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE) + */ +void mbedtls_ssl_conf_legacy_renegotiation( mbedtls_ssl_config *conf, int allow_legacy ); + +#if defined(MBEDTLS_SSL_RENEGOTIATION) +/** + * \brief Enforce renegotiation requests. + * (Default: enforced, max_records = 16) + * + * When we request a renegotiation, the peer can comply or + * ignore the request. This function allows us to decide + * whether to enforce our renegotiation requests by closing + * the connection if the peer doesn't comply. + * + * However, records could already be in transit from the peer + * when the request is emitted. In order to increase + * reliability, we can accept a number of records before the + * expected handshake records. + * + * The optimal value is highly dependent on the specific usage + * scenario. + * + * \note With DTLS and server-initiated renegotiation, the + * HelloRequest is retransmitted every time mbedtls_ssl_read() times + * out or receives Application Data, until: + * - max_records records have beens seen, if it is >= 0, or + * - the number of retransmits that would happen during an + * actual handshake has been reached. + * Please remember the request might be lost a few times + * if you consider setting max_records to a really low value. + * + * \warning On client, the grace period can only happen during + * mbedtls_ssl_read(), as opposed to mbedtls_ssl_write() and mbedtls_ssl_renegotiate() + * which always behave as if max_record was 0. The reason is, + * if we receive application data from the server, we need a + * place to write it, which only happens during mbedtls_ssl_read(). + * + * \param conf SSL configuration + * \param max_records Use MBEDTLS_SSL_RENEGOTIATION_NOT_ENFORCED if you don't want to + * enforce renegotiation, or a non-negative value to enforce + * it but allow for a grace period of max_records records. + */ +void mbedtls_ssl_conf_renegotiation_enforced( mbedtls_ssl_config *conf, int max_records ); + +/** + * \brief Set record counter threshold for periodic renegotiation. + * (Default: 2^48 - 1) + * + * Renegotiation is automatically triggered when a record + * counter (outgoing or incoming) crosses the defined + * threshold. The default value is meant to prevent the + * connection from being closed when the counter is about to + * reached its maximal value (it is not allowed to wrap). + * + * Lower values can be used to enforce policies such as "keys + * must be refreshed every N packets with cipher X". + * + * The renegotiation period can be disabled by setting + * conf->disable_renegotiation to + * MBEDTLS_SSL_RENEGOTIATION_DISABLED. + * + * \note When the configured transport is + * MBEDTLS_SSL_TRANSPORT_DATAGRAM the maximum renegotiation + * period is 2^48 - 1, and for MBEDTLS_SSL_TRANSPORT_STREAM, + * the maximum renegotiation period is 2^64 - 1. + * + * \param conf SSL configuration + * \param period The threshold value: a big-endian 64-bit number. + */ +void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf, + const unsigned char period[8] ); +#endif /* MBEDTLS_SSL_RENEGOTIATION */ + +/** + * \brief Check if there is data already read from the + * underlying transport but not yet processed. + * + * \param ssl SSL context + * + * \return 0 if nothing's pending, 1 otherwise. + * + * \note This is different in purpose and behaviour from + * \c mbedtls_ssl_get_bytes_avail in that it considers + * any kind of unprocessed data, not only unread + * application data. If \c mbedtls_ssl_get_bytes + * returns a non-zero value, this function will + * also signal pending data, but the converse does + * not hold. For example, in DTLS there might be + * further records waiting to be processed from + * the current underlying transport's datagram. + * + * \note If this function returns 1 (data pending), this + * does not imply that a subsequent call to + * \c mbedtls_ssl_read will provide any data; + * e.g., the unprocessed data might turn out + * to be an alert or a handshake message. + * + * \note This function is useful in the following situation: + * If the SSL/TLS module successfully returns from an + * operation - e.g. a handshake or an application record + * read - and you're awaiting incoming data next, you + * must not immediately idle on the underlying transport + * to have data ready, but you need to check the value + * of this function first. The reason is that the desired + * data might already be read but not yet processed. + * If, in contrast, a previous call to the SSL/TLS module + * returned MBEDTLS_ERR_SSL_WANT_READ, it is not necessary + * to call this function, as the latter error code entails + * that all internal data has been processed. + * + */ +int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl ); + +/** + * \brief Return the number of application data bytes + * remaining to be read from the current record. + * + * \param ssl SSL context + * + * \return How many bytes are available in the application + * data record read buffer. + * + * \note When working over a datagram transport, this is + * useful to detect the current datagram's boundary + * in case \c mbedtls_ssl_read has written the maximal + * amount of data fitting into the input buffer. + * + */ +size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl ); + +/** + * \brief Return the result of the certificate verification + * + * \param ssl The SSL context to use. + * + * \return \c 0 if the certificate verification was successful. + * \return \c -1u if the result is not available. This may happen + * e.g. if the handshake aborts early, or a verification + * callback returned a fatal error. + * \return A bitwise combination of \c MBEDTLS_X509_BADCERT_XXX + * and \c MBEDTLS_X509_BADCRL_XXX failure flags; see x509.h. + */ +uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl ); + +/** + * \brief Return the name of the current ciphersuite + * + * \param ssl SSL context + * + * \return a string containing the ciphersuite name + */ +const char *mbedtls_ssl_get_ciphersuite( const mbedtls_ssl_context *ssl ); + +/** + * \brief Return the current SSL version (SSLv3/TLSv1/etc) + * + * \param ssl SSL context + * + * \return a string containing the SSL version + */ +const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl ); + +/** + * \brief Return the (maximum) number of bytes added by the record + * layer: header + encryption/MAC overhead (inc. padding) + * + * \note This function is not available (always returns an error) + * when record compression is enabled. + * + * \param ssl SSL context + * + * \return Current maximum record expansion in bytes, or + * MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE if compression is + * enabled, which makes expansion much less predictable + */ +int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl ); + +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) +/** + * \brief Return the maximum fragment length (payload, in bytes) for + * the output buffer. For the client, this is the configured + * value. For the server, it is the minimum of two - the + * configured value and the negotiated one. + * + * \sa mbedtls_ssl_conf_max_frag_len() + * \sa mbedtls_ssl_get_max_record_payload() + * + * \param ssl SSL context + * + * \return Current maximum fragment length for the output buffer. + */ +size_t mbedtls_ssl_get_output_max_frag_len( const mbedtls_ssl_context *ssl ); + +/** + * \brief Return the maximum fragment length (payload, in bytes) for + * the input buffer. This is the negotiated maximum fragment + * length, or, if there is none, MBEDTLS_SSL_MAX_CONTENT_LEN. + * If it is not defined either, the value is 2^14. This function + * works as its predecessor, \c mbedtls_ssl_get_max_frag_len(). + * + * \sa mbedtls_ssl_conf_max_frag_len() + * \sa mbedtls_ssl_get_max_record_payload() + * + * \param ssl SSL context + * + * \return Current maximum fragment length for the output buffer. + */ +size_t mbedtls_ssl_get_input_max_frag_len( const mbedtls_ssl_context *ssl ); + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) + +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif + +/** + * \brief This function is a deprecated approach to getting the max + * fragment length. Its an alias for + * \c mbedtls_ssl_get_output_max_frag_len(), as the behaviour + * is the same. See \c mbedtls_ssl_get_output_max_frag_len() for + * more detail. + * + * \sa mbedtls_ssl_get_input_max_frag_len() + * \sa mbedtls_ssl_get_output_max_frag_len() + * + * \param ssl SSL context + * + * \return Current maximum fragment length for the output buffer. + */ +MBEDTLS_DEPRECATED size_t mbedtls_ssl_get_max_frag_len( + const mbedtls_ssl_context *ssl ); +#endif /* MBEDTLS_DEPRECATED_REMOVED */ +#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ + +/** + * \brief Return the current maximum outgoing record payload in bytes. + * This takes into account the config.h setting \c + * MBEDTLS_SSL_OUT_CONTENT_LEN, the configured and negotiated + * max fragment length extension if used, and for DTLS the + * path MTU as configured and current record expansion. + * + * \note With DTLS, \c mbedtls_ssl_write() will return an error if + * called with a larger length value. + * With TLS, \c mbedtls_ssl_write() will fragment the input if + * necessary and return the number of bytes written; it is up + * to the caller to call \c mbedtls_ssl_write() again in + * order to send the remaining bytes if any. + * + * \note This function is not available (always returns an error) + * when record compression is enabled. + * + * \sa mbedtls_ssl_set_mtu() + * \sa mbedtls_ssl_get_output_max_frag_len() + * \sa mbedtls_ssl_get_input_max_frag_len() + * \sa mbedtls_ssl_get_record_expansion() + * + * \param ssl SSL context + * + * \return Current maximum payload for an outgoing record, + * or a negative error code. + */ +int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl ); + +#if defined(MBEDTLS_X509_CRT_PARSE_C) +/** + * \brief Return the peer certificate from the current connection. + * + * \param ssl The SSL context to use. This must be initialized and setup. + * + * \return The current peer certificate, if available. + * The returned certificate is owned by the SSL context and + * is valid only until the next call to the SSL API. + * \return \c NULL if no peer certificate is available. This might + * be because the chosen ciphersuite doesn't use CRTs + * (PSK-based ciphersuites, for example), or because + * #MBEDTLS_SSL_KEEP_PEER_CERTIFICATE has been disabled, + * allowing the stack to free the peer's CRT to save memory. + * + * \note For one-time inspection of the peer's certificate during + * the handshake, consider registering an X.509 CRT verification + * callback through mbedtls_ssl_conf_verify() instead of calling + * this function. Using mbedtls_ssl_conf_verify() also comes at + * the benefit of allowing you to influence the verification + * process, for example by masking expected and tolerated + * verification failures. + * + * \warning You must not use the pointer returned by this function + * after any further call to the SSL API, including + * mbedtls_ssl_read() and mbedtls_ssl_write(); this is + * because the pointer might change during renegotiation, + * which happens transparently to the user. + * If you want to use the certificate across API calls, + * you must make a copy. + */ +const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ssl ); +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + +#if defined(MBEDTLS_SSL_CLI_C) +/** + * \brief Save session in order to resume it later (client-side only) + * Session data is copied to presented session structure. + * + * + * \param ssl SSL context + * \param session session context + * + * \return 0 if successful, + * MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed, + * MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used server-side or + * arguments are otherwise invalid. + * + * \note Only the server certificate is copied, and not the full chain, + * so you should not attempt to validate the certificate again + * by calling \c mbedtls_x509_crt_verify() on it. + * Instead, you should use the results from the verification + * in the original handshake by calling \c mbedtls_ssl_get_verify_result() + * after loading the session again into a new SSL context + * using \c mbedtls_ssl_set_session(). + * + * \note Once the session object is not needed anymore, you should + * free it by calling \c mbedtls_ssl_session_free(). + * + * \sa mbedtls_ssl_set_session() + */ +int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session *session ); +#endif /* MBEDTLS_SSL_CLI_C */ + +/** + * \brief Perform the SSL handshake + * + * \param ssl SSL context + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE + * if the handshake is incomplete and waiting for data to + * be available for reading from or writing to the underlying + * transport - in this case you must call this function again + * when the underlying transport is ready for the operation. + * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous + * operation is in progress (see + * mbedtls_ssl_conf_async_private_cb()) - in this case you + * must call this function again when the operation is ready. + * \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic + * operation is in progress (see mbedtls_ecp_set_max_ops()) - + * in this case you must call this function again to complete + * the handshake when you're done attending other tasks. + * \return #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED if DTLS is in use + * and the client did not demonstrate reachability yet - in + * this case you must stop using the context (see below). + * \return Another SSL error code - in this case you must stop using + * the context (see below). + * + * \warning If this function returns something other than + * \c 0, + * #MBEDTLS_ERR_SSL_WANT_READ, + * #MBEDTLS_ERR_SSL_WANT_WRITE, + * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or + * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, + * you must stop using the SSL context for reading or writing, + * and either free it or call \c mbedtls_ssl_session_reset() + * on it before re-using it for a new connection; the current + * connection must be closed. + * + * \note If DTLS is in use, then you may choose to handle + * #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED specially for logging + * purposes, as it is an expected return value rather than an + * actual error, but you still need to reset/free the context. + * + * \note Remarks regarding event-driven DTLS: + * If the function returns #MBEDTLS_ERR_SSL_WANT_READ, no datagram + * from the underlying transport layer is currently being processed, + * and it is safe to idle until the timer or the underlying transport + * signal a new event. This is not true for a successful handshake, + * in which case the datagram of the underlying transport that is + * currently being processed might or might not contain further + * DTLS records. + */ +int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl ); + +/** + * \brief Perform a single step of the SSL handshake + * + * \note The state of the context (ssl->state) will be at + * the next state after this function returns \c 0. Do not + * call this function if state is MBEDTLS_SSL_HANDSHAKE_OVER. + * + * \param ssl SSL context + * + * \return See mbedtls_ssl_handshake(). + * + * \warning If this function returns something other than \c 0, + * #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE, + * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or + * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, you must stop using + * the SSL context for reading or writing, and either free it + * or call \c mbedtls_ssl_session_reset() on it before + * re-using it for a new connection; the current connection + * must be closed. + */ +int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl ); + +#if defined(MBEDTLS_SSL_RENEGOTIATION) +/** + * \brief Initiate an SSL renegotiation on the running connection. + * Client: perform the renegotiation right now. + * Server: request renegotiation, which will be performed + * during the next call to mbedtls_ssl_read() if honored by + * client. + * + * \param ssl SSL context + * + * \return 0 if successful, or any mbedtls_ssl_handshake() return + * value except #MBEDTLS_ERR_SSL_CLIENT_RECONNECT that can't + * happen during a renegotiation. + * + * \warning If this function returns something other than \c 0, + * #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE, + * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or + * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, you must stop using + * the SSL context for reading or writing, and either free it + * or call \c mbedtls_ssl_session_reset() on it before + * re-using it for a new connection; the current connection + * must be closed. + * + */ +int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl ); +#endif /* MBEDTLS_SSL_RENEGOTIATION */ + +/** + * \brief Read at most 'len' application data bytes + * + * \param ssl SSL context + * \param buf buffer that will hold the data + * \param len maximum number of bytes to read + * + * \return The (positive) number of bytes read if successful. + * \return \c 0 if the read end of the underlying transport was closed + * without sending a CloseNotify beforehand, which might happen + * because of various reasons (internal error of an underlying + * stack, non-conformant peer not sending a CloseNotify and + * such) - in this case you must stop using the context + * (see below). + * \return #MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY if the underlying + * transport is still functional, but the peer has + * acknowledged to not send anything anymore. + * \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE + * if the handshake is incomplete and waiting for data to + * be available for reading from or writing to the underlying + * transport - in this case you must call this function again + * when the underlying transport is ready for the operation. + * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous + * operation is in progress (see + * mbedtls_ssl_conf_async_private_cb()) - in this case you + * must call this function again when the operation is ready. + * \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic + * operation is in progress (see mbedtls_ecp_set_max_ops()) - + * in this case you must call this function again to complete + * the handshake when you're done attending other tasks. + * \return #MBEDTLS_ERR_SSL_CLIENT_RECONNECT if we're at the server + * side of a DTLS connection and the client is initiating a + * new connection using the same source port. See below. + * \return Another SSL error code - in this case you must stop using + * the context (see below). + * + * \warning If this function returns something other than + * a positive value, + * #MBEDTLS_ERR_SSL_WANT_READ, + * #MBEDTLS_ERR_SSL_WANT_WRITE, + * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, + * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or + * #MBEDTLS_ERR_SSL_CLIENT_RECONNECT, + * you must stop using the SSL context for reading or writing, + * and either free it or call \c mbedtls_ssl_session_reset() + * on it before re-using it for a new connection; the current + * connection must be closed. + * + * \note When this function returns #MBEDTLS_ERR_SSL_CLIENT_RECONNECT + * (which can only happen server-side), it means that a client + * is initiating a new connection using the same source port. + * You can either treat that as a connection close and wait + * for the client to resend a ClientHello, or directly + * continue with \c mbedtls_ssl_handshake() with the same + * context (as it has been reset internally). Either way, you + * must make sure this is seen by the application as a new + * connection: application state, if any, should be reset, and + * most importantly the identity of the client must be checked + * again. WARNING: not validating the identity of the client + * again, or not transmitting the new identity to the + * application layer, would allow authentication bypass! + * + * \note Remarks regarding event-driven DTLS: + * - If the function returns #MBEDTLS_ERR_SSL_WANT_READ, no datagram + * from the underlying transport layer is currently being processed, + * and it is safe to idle until the timer or the underlying transport + * signal a new event. + * - This function may return MBEDTLS_ERR_SSL_WANT_READ even if data was + * initially available on the underlying transport, as this data may have + * been only e.g. duplicated messages or a renegotiation request. + * Therefore, you must be prepared to receive MBEDTLS_ERR_SSL_WANT_READ even + * when reacting to an incoming-data event from the underlying transport. + * - On success, the datagram of the underlying transport that is currently + * being processed may contain further DTLS records. You should call + * \c mbedtls_ssl_check_pending to check for remaining records. + * + */ +int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ); + +/** + * \brief Try to write exactly 'len' application data bytes + * + * \warning This function will do partial writes in some cases. If the + * return value is non-negative but less than length, the + * function must be called again with updated arguments: + * buf + ret, len - ret (if ret is the return value) until + * it returns a value equal to the last 'len' argument. + * + * \param ssl SSL context + * \param buf buffer holding the data + * \param len how many bytes must be written + * + * \return The (non-negative) number of bytes actually written if + * successful (may be less than \p len). + * \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE + * if the handshake is incomplete and waiting for data to + * be available for reading from or writing to the underlying + * transport - in this case you must call this function again + * when the underlying transport is ready for the operation. + * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous + * operation is in progress (see + * mbedtls_ssl_conf_async_private_cb()) - in this case you + * must call this function again when the operation is ready. + * \return #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic + * operation is in progress (see mbedtls_ecp_set_max_ops()) - + * in this case you must call this function again to complete + * the handshake when you're done attending other tasks. + * \return Another SSL error code - in this case you must stop using + * the context (see below). + * + * \warning If this function returns something other than + * a non-negative value, + * #MBEDTLS_ERR_SSL_WANT_READ, + * #MBEDTLS_ERR_SSL_WANT_WRITE, + * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or + * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, + * you must stop using the SSL context for reading or writing, + * and either free it or call \c mbedtls_ssl_session_reset() + * on it before re-using it for a new connection; the current + * connection must be closed. + * + * \note When this function returns #MBEDTLS_ERR_SSL_WANT_WRITE/READ, + * it must be called later with the *same* arguments, + * until it returns a value greater that or equal to 0. When + * the function returns #MBEDTLS_ERR_SSL_WANT_WRITE there may be + * some partial data in the output buffer, however this is not + * yet sent. + * + * \note If the requested length is greater than the maximum + * fragment length (either the built-in limit or the one set + * or negotiated with the peer), then: + * - with TLS, less bytes than requested are written. + * - with DTLS, MBEDTLS_ERR_SSL_BAD_INPUT_DATA is returned. + * \c mbedtls_ssl_get_output_max_frag_len() may be used to + * query the active maximum fragment length. + * + * \note Attempting to write 0 bytes will result in an empty TLS + * application record being sent. + */ +int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ); + +/** + * \brief Send an alert message + * + * \param ssl SSL context + * \param level The alert level of the message + * (MBEDTLS_SSL_ALERT_LEVEL_WARNING or MBEDTLS_SSL_ALERT_LEVEL_FATAL) + * \param message The alert message (SSL_ALERT_MSG_*) + * + * \return 0 if successful, or a specific SSL error code. + * + * \note If this function returns something other than 0 or + * MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using + * the SSL context for reading or writing, and either free it or + * call \c mbedtls_ssl_session_reset() on it before re-using it + * for a new connection; the current connection must be closed. + */ +int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl, + unsigned char level, + unsigned char message ); +/** + * \brief Notify the peer that the connection is being closed + * + * \param ssl SSL context + * + * \return 0 if successful, or a specific SSL error code. + * + * \note If this function returns something other than 0 or + * MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using + * the SSL context for reading or writing, and either free it or + * call \c mbedtls_ssl_session_reset() on it before re-using it + * for a new connection; the current connection must be closed. + */ +int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl ); + +/** + * \brief Free referenced items in an SSL context and clear memory + * + * \param ssl SSL context + */ +void mbedtls_ssl_free( mbedtls_ssl_context *ssl ); + +#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) +/** + * \brief Save an active connection as serialized data in a buffer. + * This allows the freeing or re-using of the SSL context + * while still picking up the connection later in a way that + * it entirely transparent to the peer. + * + * \see mbedtls_ssl_context_load() + * + * \note This feature is currently only available under certain + * conditions, see the documentation of the return value + * #MBEDTLS_ERR_SSL_BAD_INPUT_DATA for details. + * + * \note When this function succeeds, it calls + * mbedtls_ssl_session_reset() on \p ssl which as a result is + * no longer associated with the connection that has been + * serialized. This avoids creating copies of the connection + * state. You're then free to either re-use the context + * structure for a different connection, or call + * mbedtls_ssl_free() on it. See the documentation of + * mbedtls_ssl_session_reset() for more details. + * + * \param ssl The SSL context to save. On success, it is no longer + * associated with the connection that has been serialized. + * \param buf The buffer to write the serialized data to. It must be a + * writeable buffer of at least \p buf_len bytes, or may be \c + * NULL if \p buf_len is \c 0. + * \param buf_len The number of bytes available for writing in \p buf. + * \param olen The size in bytes of the data that has been or would have + * been written. It must point to a valid \c size_t. + * + * \note \p olen is updated to the correct value regardless of + * whether \p buf_len was large enough. This makes it possible + * to determine the necessary size by calling this function + * with \p buf set to \c NULL and \p buf_len to \c 0. However, + * the value of \p olen is only guaranteed to be correct when + * the function returns #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL or + * \c 0. If the return value is different, then the value of + * \p olen is undefined. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL if \p buf is too small. + * \return #MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed + * while resetting the context. + * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if a handshake is in + * progress, or there is pending data for reading or sending, + * or the connection does not use DTLS 1.2 with an AEAD + * ciphersuite, or renegotiation is enabled. + */ +int mbedtls_ssl_context_save( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t buf_len, + size_t *olen ); + +/** + * \brief Load serialized connection data to an SSL context. + * + * \see mbedtls_ssl_context_save() + * + * \warning The same serialized data must never be loaded into more + * that one context. In order to ensure that, after + * successfully loading serialized data to an SSL context, you + * should immediately destroy or invalidate all copies of the + * serialized data that was loaded. Loading the same data in + * more than one context would cause severe security failures + * including but not limited to loss of confidentiality. + * + * \note Before calling this function, the SSL context must be + * prepared in one of the two following ways. The first way is + * to take a context freshly initialised with + * mbedtls_ssl_init() and call mbedtls_ssl_setup() on it with + * the same ::mbedtls_ssl_config structure that was used in + * the original connection. The second way is to + * call mbedtls_ssl_session_reset() on a context that was + * previously prepared as above but used in the meantime. + * Either way, you must not use the context to perform a + * handshake between calling mbedtls_ssl_setup() or + * mbedtls_ssl_session_reset() and calling this function. You + * may however call other setter functions in that time frame + * as indicated in the note below. + * + * \note Before or after calling this function successfully, you + * also need to configure some connection-specific callbacks + * and settings before you can use the connection again + * (unless they were already set before calling + * mbedtls_ssl_session_reset() and the values are suitable for + * the present connection). Specifically, you want to call + * at least mbedtls_ssl_set_bio() and + * mbedtls_ssl_set_timer_cb(). All other SSL setter functions + * are not necessary to call, either because they're only used + * in handshakes, or because the setting is already saved. You + * might choose to call them anyway, for example in order to + * share code between the cases of establishing a new + * connection and the case of loading an already-established + * connection. + * + * \note If you have new information about the path MTU, you want to + * call mbedtls_ssl_set_mtu() after calling this function, as + * otherwise this function would overwrite your + * newly-configured value with the value that was active when + * the context was saved. + * + * \note When this function returns an error code, it calls + * mbedtls_ssl_free() on \p ssl. In this case, you need to + * prepare the context with the usual sequence starting with a + * call to mbedtls_ssl_init() if you want to use it again. + * + * \param ssl The SSL context structure to be populated. It must have + * been prepared as described in the note above. + * \param buf The buffer holding the serialized connection data. It must + * be a readable buffer of at least \p len bytes. + * \param len The size of the serialized data in bytes. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed. + * \return #MBEDTLS_ERR_SSL_VERSION_MISMATCH if the serialized data + * comes from a different Mbed TLS version or build. + * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if input data is invalid. + */ +int mbedtls_ssl_context_load( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ); +#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */ + +/** + * \brief Initialize an SSL configuration context + * Just makes the context ready for + * mbedtls_ssl_config_defaults() or mbedtls_ssl_config_free(). + * + * \note You need to call mbedtls_ssl_config_defaults() unless you + * manually set all of the relevant fields yourself. + * + * \param conf SSL configuration context + */ +void mbedtls_ssl_config_init( mbedtls_ssl_config *conf ); + +/** + * \brief Load reasonable default SSL configuration values. + * (You need to call mbedtls_ssl_config_init() first.) + * + * \param conf SSL configuration context + * \param endpoint MBEDTLS_SSL_IS_CLIENT or MBEDTLS_SSL_IS_SERVER + * \param transport MBEDTLS_SSL_TRANSPORT_STREAM for TLS, or + * MBEDTLS_SSL_TRANSPORT_DATAGRAM for DTLS + * \param preset a MBEDTLS_SSL_PRESET_XXX value + * + * \note See \c mbedtls_ssl_conf_transport() for notes on DTLS. + * + * \return 0 if successful, or + * MBEDTLS_ERR_XXX_ALLOC_FAILED on memory allocation error. + */ +int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, + int endpoint, int transport, int preset ); + +/** + * \brief Free an SSL configuration context + * + * \param conf SSL configuration context + */ +void mbedtls_ssl_config_free( mbedtls_ssl_config *conf ); + +/** + * \brief Initialize SSL session structure + * + * \param session SSL session + */ +void mbedtls_ssl_session_init( mbedtls_ssl_session *session ); + +/** + * \brief Free referenced items in an SSL session including the + * peer certificate and clear memory + * + * \note A session object can be freed even if the SSL context + * that was used to retrieve the session is still in use. + * + * \param session SSL session + */ +void mbedtls_ssl_session_free( mbedtls_ssl_session *session ); + +/** + * \brief TLS-PRF function for key derivation. + * + * \param prf The tls_prf type function type to be used. + * \param secret Secret for the key derivation function. + * \param slen Length of the secret. + * \param label String label for the key derivation function, + * terminated with null character. + * \param random Random bytes. + * \param rlen Length of the random bytes buffer. + * \param dstbuf The buffer holding the derived key. + * \param dlen Length of the output buffer. + * + * \return 0 on success. An SSL specific error on failure. + */ +int mbedtls_ssl_tls_prf( const mbedtls_tls_prf_types prf, + const unsigned char *secret, size_t slen, + const char *label, + const unsigned char *random, size_t rlen, + unsigned char *dstbuf, size_t dlen ); + +#ifdef __cplusplus +} +#endif + +#endif /* ssl.h */ diff --git a/third_party/mbedtls/include/mbedtls/ssl_ciphersuites.h b/third_party/mbedtls/include/mbedtls/ssl_ciphersuites.h new file mode 100644 index 0000000..93c32a5 --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/ssl_ciphersuites.h @@ -0,0 +1,556 @@ +/** + * \file ssl_ciphersuites.h + * + * \brief SSL Ciphersuites for mbed TLS + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBEDTLS_SSL_CIPHERSUITES_H +#define MBEDTLS_SSL_CIPHERSUITES_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/pk.h" +#include "mbedtls/cipher.h" +#include "mbedtls/md.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Supported ciphersuites (Official IANA names) + */ +#define MBEDTLS_TLS_RSA_WITH_NULL_MD5 0x01 /**< Weak! */ +#define MBEDTLS_TLS_RSA_WITH_NULL_SHA 0x02 /**< Weak! */ + +#define MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 0x04 +#define MBEDTLS_TLS_RSA_WITH_RC4_128_SHA 0x05 +#define MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA 0x09 /**< Weak! Not in TLS 1.2 */ + +#define MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA 0x0A + +#define MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA 0x15 /**< Weak! Not in TLS 1.2 */ +#define MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x16 + +#define MBEDTLS_TLS_PSK_WITH_NULL_SHA 0x2C /**< Weak! */ +#define MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA 0x2D /**< Weak! */ +#define MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA 0x2E /**< Weak! */ +#define MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA 0x2F + +#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x33 +#define MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA 0x35 +#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x39 + +#define MBEDTLS_TLS_RSA_WITH_NULL_SHA256 0x3B /**< Weak! */ +#define MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 0x3C /**< TLS 1.2 */ +#define MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 0x3D /**< TLS 1.2 */ + +#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA 0x41 +#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x45 + +#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x67 /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x6B /**< TLS 1.2 */ + +#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA 0x84 +#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x88 + +#define MBEDTLS_TLS_PSK_WITH_RC4_128_SHA 0x8A +#define MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA 0x8B +#define MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA 0x8C +#define MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA 0x8D + +#define MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA 0x8E +#define MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA 0x8F +#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA 0x90 +#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA 0x91 + +#define MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA 0x92 +#define MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA 0x93 +#define MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA 0x94 +#define MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA 0x95 + +#define MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 0x9C /**< TLS 1.2 */ +#define MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 0x9D /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x9E /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x9F /**< TLS 1.2 */ + +#define MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 0xA8 /**< TLS 1.2 */ +#define MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 0xA9 /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 0xAA /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 0xAB /**< TLS 1.2 */ +#define MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 0xAC /**< TLS 1.2 */ +#define MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 0xAD /**< TLS 1.2 */ + +#define MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 0xAE +#define MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 0xAF +#define MBEDTLS_TLS_PSK_WITH_NULL_SHA256 0xB0 /**< Weak! */ +#define MBEDTLS_TLS_PSK_WITH_NULL_SHA384 0xB1 /**< Weak! */ + +#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 0xB2 +#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 0xB3 +#define MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256 0xB4 /**< Weak! */ +#define MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384 0xB5 /**< Weak! */ + +#define MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 0xB6 +#define MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 0xB7 +#define MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256 0xB8 /**< Weak! */ +#define MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384 0xB9 /**< Weak! */ + +#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBA /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBE /**< TLS 1.2 */ + +#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC0 /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC4 /**< TLS 1.2 */ + +#define MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA 0xC001 /**< Weak! */ +#define MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA 0xC002 /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC003 /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0xC004 /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0xC005 /**< Not in SSL3! */ + +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA 0xC006 /**< Weak! */ +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA 0xC007 /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC008 /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC009 /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A /**< Not in SSL3! */ + +#define MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA 0xC00B /**< Weak! */ +#define MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA 0xC00C /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA 0xC00D /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0xC00E /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0xC00F /**< Not in SSL3! */ + +#define MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA 0xC010 /**< Weak! */ +#define MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA 0xC011 /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC012 /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC013 /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014 /**< Not in SSL3! */ + +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC024 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 0xC025 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 0xC026 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC028 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 0xC029 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 0xC02A /**< TLS 1.2 */ + +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC02C /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0xC02D /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0xC02E /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC030 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 /**< TLS 1.2 */ + +#define MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA 0xC033 /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA 0xC034 /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA 0xC035 /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA 0xC036 /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 0xC037 /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 0xC038 /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA 0xC039 /**< Weak! No SSL3! */ +#define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256 0xC03A /**< Weak! No SSL3! */ +#define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384 0xC03B /**< Weak! No SSL3! */ + +#define MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256 0xC03C /**< TLS 1.2 */ +#define MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384 0xC03D /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 0xC044 /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 0xC045 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 0xC048 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 0xC049 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 0xC04A /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 0xC04B /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 0xC04C /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 0xC04D /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 0xC04E /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 0xC04F /**< TLS 1.2 */ +#define MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256 0xC050 /**< TLS 1.2 */ +#define MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384 0xC051 /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 0xC052 /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 0xC053 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 0xC05C /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 0xC05D /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 0xC05E /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 0xC05F /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 0xC060 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 0xC061 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 0xC062 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 0xC063 /**< TLS 1.2 */ +#define MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256 0xC064 /**< TLS 1.2 */ +#define MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384 0xC065 /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 0xC066 /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 0xC067 /**< TLS 1.2 */ +#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 0xC068 /**< TLS 1.2 */ +#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 0xC069 /**< TLS 1.2 */ +#define MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256 0xC06A /**< TLS 1.2 */ +#define MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384 0xC06B /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 0xC06C /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 0xC06D /**< TLS 1.2 */ +#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 0xC06E /**< TLS 1.2 */ +#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 0xC06F /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 0xC070 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 0xC071 /**< TLS 1.2 */ + +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC072 /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC073 /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC074 /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC075 /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xC076 /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 0xC077 /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xC078 /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 0xC079 /**< Not in SSL3! */ + +#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC07A /**< TLS 1.2 */ +#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC07B /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC07C /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC07D /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 0xC086 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 0xC087 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 0xC088 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 0xC089 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC08A /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC08B /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC08C /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC08D /**< TLS 1.2 */ + +#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC08E /**< TLS 1.2 */ +#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC08F /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC090 /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC091 /**< TLS 1.2 */ +#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC092 /**< TLS 1.2 */ +#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC093 /**< TLS 1.2 */ + +#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC094 +#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC095 +#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC096 +#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC097 +#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC098 +#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC099 +#define MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC09A /**< Not in SSL3! */ +#define MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC09B /**< Not in SSL3! */ + +#define MBEDTLS_TLS_RSA_WITH_AES_128_CCM 0xC09C /**< TLS 1.2 */ +#define MBEDTLS_TLS_RSA_WITH_AES_256_CCM 0xC09D /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM 0xC09E /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM 0xC09F /**< TLS 1.2 */ +#define MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8 0xC0A0 /**< TLS 1.2 */ +#define MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8 0xC0A1 /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8 0xC0A2 /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8 0xC0A3 /**< TLS 1.2 */ +#define MBEDTLS_TLS_PSK_WITH_AES_128_CCM 0xC0A4 /**< TLS 1.2 */ +#define MBEDTLS_TLS_PSK_WITH_AES_256_CCM 0xC0A5 /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM 0xC0A6 /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM 0xC0A7 /**< TLS 1.2 */ +#define MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8 0xC0A8 /**< TLS 1.2 */ +#define MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8 0xC0A9 /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8 0xC0AA /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8 0xC0AB /**< TLS 1.2 */ +/* The last two are named with PSK_DHE in the RFC, which looks like a typo */ + +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM 0xC0AC /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM 0xC0AD /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 0xC0AF /**< TLS 1.2 */ + +#define MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 0xC0FF /**< experimental */ + +/* RFC 7905 */ +#define MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA8 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA9 /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCAA /**< TLS 1.2 */ +#define MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAB /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAC /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAD /**< TLS 1.2 */ +#define MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAE /**< TLS 1.2 */ + +/* Reminder: update mbedtls_ssl_premaster_secret when adding a new key exchange. + * Reminder: update MBEDTLS_KEY_EXCHANGE__xxx below + */ +typedef enum { + MBEDTLS_KEY_EXCHANGE_NONE = 0, + MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_KEY_EXCHANGE_ECJPAKE, +} mbedtls_key_exchange_type_t; + +/* Key exchanges using a certificate */ +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) +#define MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED +#endif + +/* Key exchanges allowing client certificate requests */ +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +#define MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED +#endif + +/* Key exchanges involving server signature in ServerKeyExchange */ +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +#define MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED +#endif + +/* Key exchanges using ECDH */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) +#define MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED +#endif + +/* Key exchanges that don't involve ephemeral keys */ +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED) +#define MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED +#endif + +/* Key exchanges that involve ephemeral keys */ +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +#define MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED +#endif + +/* Key exchanges using a PSK */ +#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) +#define MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED +#endif + +/* Key exchanges using DHE */ +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) +#define MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED +#endif + +/* Key exchanges using ECDHE */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) +#define MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED +#endif + +typedef struct mbedtls_ssl_ciphersuite_t mbedtls_ssl_ciphersuite_t; + +#define MBEDTLS_CIPHERSUITE_WEAK 0x01 /**< Weak ciphersuite flag */ +#define MBEDTLS_CIPHERSUITE_SHORT_TAG 0x02 /**< Short authentication tag, + eg for CCM_8 */ +#define MBEDTLS_CIPHERSUITE_NODTLS 0x04 /**< Can't be used with DTLS */ + +/** + * \brief This structure is used for storing ciphersuite information + */ +struct mbedtls_ssl_ciphersuite_t +{ + int id; + const char * name; + + mbedtls_cipher_type_t cipher; + mbedtls_md_type_t mac; + mbedtls_key_exchange_type_t key_exchange; + + int min_major_ver; + int min_minor_ver; + int max_major_ver; + int max_minor_ver; + + unsigned char flags; +}; + +const int *mbedtls_ssl_list_ciphersuites( void ); + +const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_string( const char *ciphersuite_name ); +const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_id( int ciphersuite_id ); + +#if defined(MBEDTLS_PK_C) +mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg( const mbedtls_ssl_ciphersuite_t *info ); +mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg( const mbedtls_ssl_ciphersuite_t *info ); +#endif + +int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info ); +int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info ); + +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED) +static inline int mbedtls_ssl_ciphersuite_has_pfs( const mbedtls_ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_DHE_RSA: + case MBEDTLS_KEY_EXCHANGE_DHE_PSK: + case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: + case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: + case MBEDTLS_KEY_EXCHANGE_ECJPAKE: + return( 1 ); + + default: + return( 0 ); + } +} +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED) +static inline int mbedtls_ssl_ciphersuite_no_pfs( const mbedtls_ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: + case MBEDTLS_KEY_EXCHANGE_RSA: + case MBEDTLS_KEY_EXCHANGE_PSK: + case MBEDTLS_KEY_EXCHANGE_RSA_PSK: + return( 1 ); + + default: + return( 0 ); + } +} +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED) +static inline int mbedtls_ssl_ciphersuite_uses_ecdh( const mbedtls_ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: + return( 1 ); + + default: + return( 0 ); + } +} +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED */ + +static inline int mbedtls_ssl_ciphersuite_cert_req_allowed( const mbedtls_ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_RSA: + case MBEDTLS_KEY_EXCHANGE_DHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: + return( 1 ); + + default: + return( 0 ); + } +} + +static inline int mbedtls_ssl_ciphersuite_uses_srv_cert( const mbedtls_ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_RSA: + case MBEDTLS_KEY_EXCHANGE_RSA_PSK: + case MBEDTLS_KEY_EXCHANGE_DHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: + return( 1 ); + + default: + return( 0 ); + } +} + +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED) +static inline int mbedtls_ssl_ciphersuite_uses_dhe( const mbedtls_ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_DHE_RSA: + case MBEDTLS_KEY_EXCHANGE_DHE_PSK: + return( 1 ); + + default: + return( 0 ); + } +} +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED) */ + +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED) +static inline int mbedtls_ssl_ciphersuite_uses_ecdhe( const mbedtls_ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: + return( 1 ); + + default: + return( 0 ); + } +} +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED) */ + +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) +static inline int mbedtls_ssl_ciphersuite_uses_server_signature( const mbedtls_ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_DHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: + return( 1 ); + + default: + return( 0 ); + } +} +#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */ + +#ifdef __cplusplus +} +#endif + +#endif /* ssl_ciphersuites.h */ diff --git a/third_party/mbedtls/include/mbedtls/version.h b/third_party/mbedtls/include/mbedtls/version.h new file mode 100644 index 0000000..44adcbf --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/version.h @@ -0,0 +1,110 @@ +/** + * \file version.h + * + * \brief Run-time version information + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * This set of compile-time defines and run-time variables can be used to + * determine the version number of the mbed TLS library used. + */ +#ifndef MBEDTLS_VERSION_H +#define MBEDTLS_VERSION_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +/** + * The version number x.y.z is split into three parts. + * Major, Minor, Patchlevel + */ +#define MBEDTLS_VERSION_MAJOR 2 +#define MBEDTLS_VERSION_MINOR 28 +#define MBEDTLS_VERSION_PATCH 1 + +/** + * The single version number has the following structure: + * MMNNPP00 + * Major version | Minor version | Patch version + */ +#define MBEDTLS_VERSION_NUMBER 0x021C0100 +#define MBEDTLS_VERSION_STRING "2.28.1" +#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.28.1" + +#if defined(MBEDTLS_VERSION_C) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Get the version number. + * + * \return The constructed version number in the format + * MMNNPP00 (Major, Minor, Patch). + */ +unsigned int mbedtls_version_get_number( void ); + +/** + * Get the version string ("x.y.z"). + * + * \param string The string that will receive the value. + * (Should be at least 9 bytes in size) + */ +void mbedtls_version_get_string( char *string ); + +/** + * Get the full version string ("mbed TLS x.y.z"). + * + * \param string The string that will receive the value. The mbed TLS version + * string will use 18 bytes AT MOST including a terminating + * null byte. + * (So the buffer should be at least 18 bytes to receive this + * version string). + */ +void mbedtls_version_get_string_full( char *string ); + +/** + * \brief Check if support for a feature was compiled into this + * mbed TLS binary. This allows you to see at runtime if the + * library was for instance compiled with or without + * Multi-threading support. + * + * \note only checks against defines in the sections "System + * support", "mbed TLS modules" and "mbed TLS feature + * support" in config.h + * + * \param feature The string for the define to check (e.g. "MBEDTLS_AES_C") + * + * \return 0 if the feature is present, + * -1 if the feature is not present and + * -2 if support for feature checking as a whole was not + * compiled in. + */ +int mbedtls_version_check_feature( const char *feature ); + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_VERSION_C */ + +#endif /* version.h */ diff --git a/third_party/mbedtls/include/mbedtls/x509.h b/third_party/mbedtls/include/mbedtls/x509.h new file mode 100644 index 0000000..31b78df --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/x509.h @@ -0,0 +1,380 @@ +/** + * \file x509.h + * + * \brief X.509 generic defines and structures + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBEDTLS_X509_H +#define MBEDTLS_X509_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/asn1.h" +#include "mbedtls/pk.h" + +#if defined(MBEDTLS_RSA_C) +#include "mbedtls/rsa.h" +#endif + +/** + * \addtogroup x509_module + * \{ + */ + +#if !defined(MBEDTLS_X509_MAX_INTERMEDIATE_CA) +/** + * Maximum number of intermediate CAs in a verification chain. + * That is, maximum length of the chain, excluding the end-entity certificate + * and the trusted root certificate. + * + * Set this to a low value to prevent an adversary from making you waste + * resources verifying an overlong certificate chain. + */ +#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 +#endif + +/** + * \name X509 Error codes + * \{ + */ +/** Unavailable feature, e.g. RSA hashing/encryption combination. */ +#define MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE -0x2080 +/** Requested OID is unknown. */ +#define MBEDTLS_ERR_X509_UNKNOWN_OID -0x2100 +/** The CRT/CRL/CSR format is invalid, e.g. different type expected. */ +#define MBEDTLS_ERR_X509_INVALID_FORMAT -0x2180 +/** The CRT/CRL/CSR version element is invalid. */ +#define MBEDTLS_ERR_X509_INVALID_VERSION -0x2200 +/** The serial tag or value is invalid. */ +#define MBEDTLS_ERR_X509_INVALID_SERIAL -0x2280 +/** The algorithm tag or value is invalid. */ +#define MBEDTLS_ERR_X509_INVALID_ALG -0x2300 +/** The name tag or value is invalid. */ +#define MBEDTLS_ERR_X509_INVALID_NAME -0x2380 +/** The date tag or value is invalid. */ +#define MBEDTLS_ERR_X509_INVALID_DATE -0x2400 +/** The signature tag or value invalid. */ +#define MBEDTLS_ERR_X509_INVALID_SIGNATURE -0x2480 +/** The extension tag or value is invalid. */ +#define MBEDTLS_ERR_X509_INVALID_EXTENSIONS -0x2500 +/** CRT/CRL/CSR has an unsupported version number. */ +#define MBEDTLS_ERR_X509_UNKNOWN_VERSION -0x2580 +/** Signature algorithm (oid) is unsupported. */ +#define MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG -0x2600 +/** Signature algorithms do not match. (see \c ::mbedtls_x509_crt sig_oid) */ +#define MBEDTLS_ERR_X509_SIG_MISMATCH -0x2680 +/** Certificate verification failed, e.g. CRL, CA or signature check failed. */ +#define MBEDTLS_ERR_X509_CERT_VERIFY_FAILED -0x2700 +/** Format not recognized as DER or PEM. */ +#define MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT -0x2780 +/** Input invalid. */ +#define MBEDTLS_ERR_X509_BAD_INPUT_DATA -0x2800 +/** Allocation of memory failed. */ +#define MBEDTLS_ERR_X509_ALLOC_FAILED -0x2880 +/** Read/write of file failed. */ +#define MBEDTLS_ERR_X509_FILE_IO_ERROR -0x2900 +/** Destination buffer is too small. */ +#define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL -0x2980 +/** A fatal error occurred, eg the chain is too long or the vrfy callback failed. */ +#define MBEDTLS_ERR_X509_FATAL_ERROR -0x3000 +/** \} name X509 Error codes */ + +/** + * \name X509 Verify codes + * \{ + */ +/* Reminder: update x509_crt_verify_strings[] in library/x509_crt.c */ +#define MBEDTLS_X509_BADCERT_EXPIRED 0x01 /**< The certificate validity has expired. */ +#define MBEDTLS_X509_BADCERT_REVOKED 0x02 /**< The certificate has been revoked (is on a CRL). */ +#define MBEDTLS_X509_BADCERT_CN_MISMATCH 0x04 /**< The certificate Common Name (CN) does not match with the expected CN. */ +#define MBEDTLS_X509_BADCERT_NOT_TRUSTED 0x08 /**< The certificate is not correctly signed by the trusted CA. */ +#define MBEDTLS_X509_BADCRL_NOT_TRUSTED 0x10 /**< The CRL is not correctly signed by the trusted CA. */ +#define MBEDTLS_X509_BADCRL_EXPIRED 0x20 /**< The CRL is expired. */ +#define MBEDTLS_X509_BADCERT_MISSING 0x40 /**< Certificate was missing. */ +#define MBEDTLS_X509_BADCERT_SKIP_VERIFY 0x80 /**< Certificate verification was skipped. */ +#define MBEDTLS_X509_BADCERT_OTHER 0x0100 /**< Other reason (can be used by verify callback) */ +#define MBEDTLS_X509_BADCERT_FUTURE 0x0200 /**< The certificate validity starts in the future. */ +#define MBEDTLS_X509_BADCRL_FUTURE 0x0400 /**< The CRL is from the future */ +#define MBEDTLS_X509_BADCERT_KEY_USAGE 0x0800 /**< Usage does not match the keyUsage extension. */ +#define MBEDTLS_X509_BADCERT_EXT_KEY_USAGE 0x1000 /**< Usage does not match the extendedKeyUsage extension. */ +#define MBEDTLS_X509_BADCERT_NS_CERT_TYPE 0x2000 /**< Usage does not match the nsCertType extension. */ +#define MBEDTLS_X509_BADCERT_BAD_MD 0x4000 /**< The certificate is signed with an unacceptable hash. */ +#define MBEDTLS_X509_BADCERT_BAD_PK 0x8000 /**< The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA). */ +#define MBEDTLS_X509_BADCERT_BAD_KEY 0x010000 /**< The certificate is signed with an unacceptable key (eg bad curve, RSA too short). */ +#define MBEDTLS_X509_BADCRL_BAD_MD 0x020000 /**< The CRL is signed with an unacceptable hash. */ +#define MBEDTLS_X509_BADCRL_BAD_PK 0x040000 /**< The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA). */ +#define MBEDTLS_X509_BADCRL_BAD_KEY 0x080000 /**< The CRL is signed with an unacceptable key (eg bad curve, RSA too short). */ + +/** \} name X509 Verify codes */ +/** \} addtogroup x509_module */ + +/* + * X.509 v3 Subject Alternative Name types. + * otherName [0] OtherName, + * rfc822Name [1] IA5String, + * dNSName [2] IA5String, + * x400Address [3] ORAddress, + * directoryName [4] Name, + * ediPartyName [5] EDIPartyName, + * uniformResourceIdentifier [6] IA5String, + * iPAddress [7] OCTET STRING, + * registeredID [8] OBJECT IDENTIFIER + */ +#define MBEDTLS_X509_SAN_OTHER_NAME 0 +#define MBEDTLS_X509_SAN_RFC822_NAME 1 +#define MBEDTLS_X509_SAN_DNS_NAME 2 +#define MBEDTLS_X509_SAN_X400_ADDRESS_NAME 3 +#define MBEDTLS_X509_SAN_DIRECTORY_NAME 4 +#define MBEDTLS_X509_SAN_EDI_PARTY_NAME 5 +#define MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER 6 +#define MBEDTLS_X509_SAN_IP_ADDRESS 7 +#define MBEDTLS_X509_SAN_REGISTERED_ID 8 + +/* + * X.509 v3 Key Usage Extension flags + * Reminder: update x509_info_key_usage() when adding new flags. + */ +#define MBEDTLS_X509_KU_DIGITAL_SIGNATURE (0x80) /* bit 0 */ +#define MBEDTLS_X509_KU_NON_REPUDIATION (0x40) /* bit 1 */ +#define MBEDTLS_X509_KU_KEY_ENCIPHERMENT (0x20) /* bit 2 */ +#define MBEDTLS_X509_KU_DATA_ENCIPHERMENT (0x10) /* bit 3 */ +#define MBEDTLS_X509_KU_KEY_AGREEMENT (0x08) /* bit 4 */ +#define MBEDTLS_X509_KU_KEY_CERT_SIGN (0x04) /* bit 5 */ +#define MBEDTLS_X509_KU_CRL_SIGN (0x02) /* bit 6 */ +#define MBEDTLS_X509_KU_ENCIPHER_ONLY (0x01) /* bit 7 */ +#define MBEDTLS_X509_KU_DECIPHER_ONLY (0x8000) /* bit 8 */ + +/* + * Netscape certificate types + * (http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn3.html) + */ + +#define MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT (0x80) /* bit 0 */ +#define MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER (0x40) /* bit 1 */ +#define MBEDTLS_X509_NS_CERT_TYPE_EMAIL (0x20) /* bit 2 */ +#define MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING (0x10) /* bit 3 */ +#define MBEDTLS_X509_NS_CERT_TYPE_RESERVED (0x08) /* bit 4 */ +#define MBEDTLS_X509_NS_CERT_TYPE_SSL_CA (0x04) /* bit 5 */ +#define MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA (0x02) /* bit 6 */ +#define MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA (0x01) /* bit 7 */ + +/* + * X.509 extension types + * + * Comments refer to the status for using certificates. Status can be + * different for writing certificates or reading CRLs or CSRs. + * + * Those are defined in oid.h as oid.c needs them in a data structure. Since + * these were previously defined here, let's have aliases for compatibility. + */ +#define MBEDTLS_X509_EXT_AUTHORITY_KEY_IDENTIFIER MBEDTLS_OID_X509_EXT_AUTHORITY_KEY_IDENTIFIER +#define MBEDTLS_X509_EXT_SUBJECT_KEY_IDENTIFIER MBEDTLS_OID_X509_EXT_SUBJECT_KEY_IDENTIFIER +#define MBEDTLS_X509_EXT_KEY_USAGE MBEDTLS_OID_X509_EXT_KEY_USAGE +#define MBEDTLS_X509_EXT_CERTIFICATE_POLICIES MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES +#define MBEDTLS_X509_EXT_POLICY_MAPPINGS MBEDTLS_OID_X509_EXT_POLICY_MAPPINGS +#define MBEDTLS_X509_EXT_SUBJECT_ALT_NAME MBEDTLS_OID_X509_EXT_SUBJECT_ALT_NAME /* Supported (DNS) */ +#define MBEDTLS_X509_EXT_ISSUER_ALT_NAME MBEDTLS_OID_X509_EXT_ISSUER_ALT_NAME +#define MBEDTLS_X509_EXT_SUBJECT_DIRECTORY_ATTRS MBEDTLS_OID_X509_EXT_SUBJECT_DIRECTORY_ATTRS +#define MBEDTLS_X509_EXT_BASIC_CONSTRAINTS MBEDTLS_OID_X509_EXT_BASIC_CONSTRAINTS /* Supported */ +#define MBEDTLS_X509_EXT_NAME_CONSTRAINTS MBEDTLS_OID_X509_EXT_NAME_CONSTRAINTS +#define MBEDTLS_X509_EXT_POLICY_CONSTRAINTS MBEDTLS_OID_X509_EXT_POLICY_CONSTRAINTS +#define MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE MBEDTLS_OID_X509_EXT_EXTENDED_KEY_USAGE +#define MBEDTLS_X509_EXT_CRL_DISTRIBUTION_POINTS MBEDTLS_OID_X509_EXT_CRL_DISTRIBUTION_POINTS +#define MBEDTLS_X509_EXT_INIHIBIT_ANYPOLICY MBEDTLS_OID_X509_EXT_INIHIBIT_ANYPOLICY +#define MBEDTLS_X509_EXT_FRESHEST_CRL MBEDTLS_OID_X509_EXT_FRESHEST_CRL +#define MBEDTLS_X509_EXT_NS_CERT_TYPE MBEDTLS_OID_X509_EXT_NS_CERT_TYPE + +/* + * Storage format identifiers + * Recognized formats: PEM and DER + */ +#define MBEDTLS_X509_FORMAT_DER 1 +#define MBEDTLS_X509_FORMAT_PEM 2 + +#define MBEDTLS_X509_MAX_DN_NAME_SIZE 256 /**< Maximum value size of a DN entry */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup x509_module + * \{ */ + +/** + * \name Structures for parsing X.509 certificates, CRLs and CSRs + * \{ + */ + +/** + * Type-length-value structure that allows for ASN1 using DER. + */ +typedef mbedtls_asn1_buf mbedtls_x509_buf; + +/** + * Container for ASN1 bit strings. + */ +typedef mbedtls_asn1_bitstring mbedtls_x509_bitstring; + +/** + * Container for ASN1 named information objects. + * It allows for Relative Distinguished Names (e.g. cn=localhost,ou=code,etc.). + */ +typedef mbedtls_asn1_named_data mbedtls_x509_name; + +/** + * Container for a sequence of ASN.1 items + */ +typedef mbedtls_asn1_sequence mbedtls_x509_sequence; + +/** Container for date and time (precision in seconds). */ +typedef struct mbedtls_x509_time +{ + int year, mon, day; /**< Date. */ + int hour, min, sec; /**< Time. */ +} +mbedtls_x509_time; + +/** \} name Structures for parsing X.509 certificates, CRLs and CSRs */ + +/** + * \brief Store the certificate DN in printable form into buf; + * no more than size characters will be written. + * + * \param buf Buffer to write to + * \param size Maximum size of buffer + * \param dn The X509 name to represent + * + * \return The length of the string written (not including the + * terminated nul byte), or a negative error code. + */ +int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn ); + +/** + * \brief Store the certificate serial in printable form into buf; + * no more than size characters will be written. + * + * \param buf Buffer to write to + * \param size Maximum size of buffer + * \param serial The X509 serial to represent + * + * \return The length of the string written (not including the + * terminated nul byte), or a negative error code. + */ +int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial ); + +/** + * \brief Check a given mbedtls_x509_time against the system time + * and tell if it's in the past. + * + * \note Intended usage is "if( is_past( valid_to ) ) ERROR". + * Hence the return value of 1 if on internal errors. + * + * \param to mbedtls_x509_time to check + * + * \return 1 if the given time is in the past or an error occurred, + * 0 otherwise. + */ +int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ); + +/** + * \brief Check a given mbedtls_x509_time against the system time + * and tell if it's in the future. + * + * \note Intended usage is "if( is_future( valid_from ) ) ERROR". + * Hence the return value of 1 if on internal errors. + * + * \param from mbedtls_x509_time to check + * + * \return 1 if the given time is in the future or an error occurred, + * 0 otherwise. + */ +int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ); + +/** \} addtogroup x509_module */ + +#if defined(MBEDTLS_SELF_TEST) + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int mbedtls_x509_self_test( int verbose ); + +#endif /* MBEDTLS_SELF_TEST */ + +/* + * Internal module functions. You probably do not want to use these unless you + * know you do. + */ +int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end, + mbedtls_x509_name *cur ); +int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end, + mbedtls_x509_buf *alg ); +int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end, + mbedtls_x509_buf *alg, mbedtls_x509_buf *params ); +#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) +int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params, + mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md, + int *salt_len ); +#endif +int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig ); +int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, + mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, + void **sig_opts ); +int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end, + mbedtls_x509_time *t ); +int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end, + mbedtls_x509_buf *serial ); +int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end, + mbedtls_x509_buf *ext, int tag ); +int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid, + mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, + const void *sig_opts ); +int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name ); +int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name ); +int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len, + int critical, const unsigned char *val, + size_t val_len ); +int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start, + mbedtls_asn1_named_data *first ); +int mbedtls_x509_write_names( unsigned char **p, unsigned char *start, + mbedtls_asn1_named_data *first ); +int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start, + const char *oid, size_t oid_len, + unsigned char *sig, size_t size ); + +#define MBEDTLS_X509_SAFE_SNPRINTF \ + do { \ + if( ret < 0 || (size_t) ret >= n ) \ + return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL ); \ + \ + n -= (size_t) ret; \ + p += (size_t) ret; \ + } while( 0 ) + +#ifdef __cplusplus +} +#endif + +#endif /* x509.h */ diff --git a/third_party/mbedtls/include/mbedtls/x509_crl.h b/third_party/mbedtls/include/mbedtls/x509_crl.h new file mode 100644 index 0000000..9222009 --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/x509_crl.h @@ -0,0 +1,172 @@ +/** + * \file x509_crl.h + * + * \brief X.509 certificate revocation list parsing + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBEDTLS_X509_CRL_H +#define MBEDTLS_X509_CRL_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/x509.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup x509_module + * \{ */ + +/** + * \name Structures and functions for parsing CRLs + * \{ + */ + +/** + * Certificate revocation list entry. + * Contains the CA-specific serial numbers and revocation dates. + */ +typedef struct mbedtls_x509_crl_entry +{ + mbedtls_x509_buf raw; + + mbedtls_x509_buf serial; + + mbedtls_x509_time revocation_date; + + mbedtls_x509_buf entry_ext; + + struct mbedtls_x509_crl_entry *next; +} +mbedtls_x509_crl_entry; + +/** + * Certificate revocation list structure. + * Every CRL may have multiple entries. + */ +typedef struct mbedtls_x509_crl +{ + mbedtls_x509_buf raw; /**< The raw certificate data (DER). */ + mbedtls_x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */ + + int version; /**< CRL version (1=v1, 2=v2) */ + mbedtls_x509_buf sig_oid; /**< CRL signature type identifier */ + + mbedtls_x509_buf issuer_raw; /**< The raw issuer data (DER). */ + + mbedtls_x509_name issuer; /**< The parsed issuer data (named information object). */ + + mbedtls_x509_time this_update; + mbedtls_x509_time next_update; + + mbedtls_x509_crl_entry entry; /**< The CRL entries containing the certificate revocation times for this CA. */ + + mbedtls_x509_buf crl_ext; + + mbedtls_x509_buf sig_oid2; + mbedtls_x509_buf sig; + mbedtls_md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */ + mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */ + void *sig_opts; /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */ + + struct mbedtls_x509_crl *next; +} +mbedtls_x509_crl; + +/** + * \brief Parse a DER-encoded CRL and append it to the chained list + * + * \param chain points to the start of the chain + * \param buf buffer holding the CRL data in DER format + * \param buflen size of the buffer + * (including the terminating null byte for PEM data) + * + * \return 0 if successful, or a specific X509 or PEM error code + */ +int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain, + const unsigned char *buf, size_t buflen ); +/** + * \brief Parse one or more CRLs and append them to the chained list + * + * \note Multiple CRLs are accepted only if using PEM format + * + * \param chain points to the start of the chain + * \param buf buffer holding the CRL data in PEM or DER format + * \param buflen size of the buffer + * (including the terminating null byte for PEM data) + * + * \return 0 if successful, or a specific X509 or PEM error code + */ +int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen ); + +#if defined(MBEDTLS_FS_IO) +/** + * \brief Load one or more CRLs and append them to the chained list + * + * \note Multiple CRLs are accepted only if using PEM format + * + * \param chain points to the start of the chain + * \param path filename to read the CRLs from (in PEM or DER encoding) + * + * \return 0 if successful, or a specific X509 or PEM error code + */ +int mbedtls_x509_crl_parse_file( mbedtls_x509_crl *chain, const char *path ); +#endif /* MBEDTLS_FS_IO */ + +/** + * \brief Returns an informational string about the CRL. + * + * \param buf Buffer to write to + * \param size Maximum size of buffer + * \param prefix A line prefix + * \param crl The X509 CRL to represent + * + * \return The length of the string written (not including the + * terminated nul byte), or a negative error code. + */ +int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix, + const mbedtls_x509_crl *crl ); + +/** + * \brief Initialize a CRL (chain) + * + * \param crl CRL chain to initialize + */ +void mbedtls_x509_crl_init( mbedtls_x509_crl *crl ); + +/** + * \brief Unallocate all CRL data + * + * \param crl CRL chain to free + */ +void mbedtls_x509_crl_free( mbedtls_x509_crl *crl ); + +/** \} name Structures and functions for parsing CRLs */ +/** \} addtogroup x509_module */ + +#ifdef __cplusplus +} +#endif + +#endif /* mbedtls_x509_crl.h */ diff --git a/third_party/mbedtls/include/mbedtls/x509_crt.h b/third_party/mbedtls/include/mbedtls/x509_crt.h new file mode 100644 index 0000000..0f2885a --- /dev/null +++ b/third_party/mbedtls/include/mbedtls/x509_crt.h @@ -0,0 +1,1097 @@ +/** + * \file x509_crt.h + * + * \brief X.509 certificate parsing and writing + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBEDTLS_X509_CRT_H +#define MBEDTLS_X509_CRT_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/x509.h" +#include "mbedtls/x509_crl.h" +#include "mbedtls/bignum.h" + +/** + * \addtogroup x509_module + * \{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name Structures and functions for parsing and writing X.509 certificates + * \{ + */ + +/** + * Container for an X.509 certificate. The certificate may be chained. + */ +typedef struct mbedtls_x509_crt +{ + int own_buffer; /**< Indicates if \c raw is owned + * by the structure or not. */ + mbedtls_x509_buf raw; /**< The raw certificate data (DER). */ + mbedtls_x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */ + + int version; /**< The X.509 version. (1=v1, 2=v2, 3=v3) */ + mbedtls_x509_buf serial; /**< Unique id for certificate issued by a specific CA. */ + mbedtls_x509_buf sig_oid; /**< Signature algorithm, e.g. sha1RSA */ + + mbedtls_x509_buf issuer_raw; /**< The raw issuer data (DER). Used for quick comparison. */ + mbedtls_x509_buf subject_raw; /**< The raw subject data (DER). Used for quick comparison. */ + + mbedtls_x509_name issuer; /**< The parsed issuer data (named information object). */ + mbedtls_x509_name subject; /**< The parsed subject data (named information object). */ + + mbedtls_x509_time valid_from; /**< Start time of certificate validity. */ + mbedtls_x509_time valid_to; /**< End time of certificate validity. */ + + mbedtls_x509_buf pk_raw; + mbedtls_pk_context pk; /**< Container for the public key context. */ + + mbedtls_x509_buf issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */ + mbedtls_x509_buf subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */ + mbedtls_x509_buf v3_ext; /**< Optional X.509 v3 extensions. */ + mbedtls_x509_sequence subject_alt_names; /**< Optional list of raw entries of Subject Alternative Names extension (currently only dNSName and OtherName are listed). */ + + mbedtls_x509_sequence certificate_policies; /**< Optional list of certificate policies (Only anyPolicy is printed and enforced, however the rest of the policies are still listed). */ + + int ext_types; /**< Bit string containing detected and parsed extensions */ + int ca_istrue; /**< Optional Basic Constraint extension value: 1 if this certificate belongs to a CA, 0 otherwise. */ + int max_pathlen; /**< Optional Basic Constraint extension value: The maximum path length to the root certificate. Path length is 1 higher than RFC 5280 'meaning', so 1+ */ + + unsigned int key_usage; /**< Optional key usage extension value: See the values in x509.h */ + + mbedtls_x509_sequence ext_key_usage; /**< Optional list of extended key usage OIDs. */ + + unsigned char ns_cert_type; /**< Optional Netscape certificate type extension value: See the values in x509.h */ + + mbedtls_x509_buf sig; /**< Signature: hash of the tbs part signed with the private key. */ + mbedtls_md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */ + mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */ + void *sig_opts; /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */ + + struct mbedtls_x509_crt *next; /**< Next certificate in the CA-chain. */ +} +mbedtls_x509_crt; + +/** + * From RFC 5280 section 4.2.1.6: + * OtherName ::= SEQUENCE { + * type-id OBJECT IDENTIFIER, + * value [0] EXPLICIT ANY DEFINED BY type-id } + */ +typedef struct mbedtls_x509_san_other_name +{ + /** + * The type_id is an OID as defined in RFC 5280. + * To check the value of the type id, you should use + * \p MBEDTLS_OID_CMP with a known OID mbedtls_x509_buf. + */ + mbedtls_x509_buf type_id; /**< The type id. */ + union + { + /** + * From RFC 4108 section 5: + * HardwareModuleName ::= SEQUENCE { + * hwType OBJECT IDENTIFIER, + * hwSerialNum OCTET STRING } + */ + struct + { + mbedtls_x509_buf oid; /**< The object identifier. */ + mbedtls_x509_buf val; /**< The named value. */ + } + hardware_module_name; + } + value; +} +mbedtls_x509_san_other_name; + +/** + * A structure for holding the parsed Subject Alternative Name, according to type + */ +typedef struct mbedtls_x509_subject_alternative_name +{ + int type; /**< The SAN type, value of MBEDTLS_X509_SAN_XXX. */ + union { + mbedtls_x509_san_other_name other_name; /**< The otherName supported type. */ + mbedtls_x509_buf unstructured_name; /**< The buffer for the un constructed types. Only dnsName currently supported */ + } + san; /**< A union of the supported SAN types */ +} +mbedtls_x509_subject_alternative_name; + +/** + * Build flag from an algorithm/curve identifier (pk, md, ecp) + * Since 0 is always XXX_NONE, ignore it. + */ +#define MBEDTLS_X509_ID_FLAG( id ) ( 1 << ( (id) - 1 ) ) + +/** + * Security profile for certificate verification. + * + * All lists are bitfields, built by ORing flags from MBEDTLS_X509_ID_FLAG(). + */ +typedef struct mbedtls_x509_crt_profile +{ + uint32_t allowed_mds; /**< MDs for signatures */ + uint32_t allowed_pks; /**< PK algs for public keys; + * this applies to all certificates + * in the provided chain. */ + uint32_t allowed_curves; /**< Elliptic curves for ECDSA */ + uint32_t rsa_min_bitlen; /**< Minimum size for RSA keys */ +} +mbedtls_x509_crt_profile; + +#define MBEDTLS_X509_CRT_VERSION_1 0 +#define MBEDTLS_X509_CRT_VERSION_2 1 +#define MBEDTLS_X509_CRT_VERSION_3 2 + +#define MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN 32 +#define MBEDTLS_X509_RFC5280_UTC_TIME_LEN 15 + +#if !defined( MBEDTLS_X509_MAX_FILE_PATH_LEN ) +#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 +#endif + +/** + * Container for writing a certificate (CRT) + */ +typedef struct mbedtls_x509write_cert +{ + int version; + mbedtls_mpi serial; + mbedtls_pk_context *subject_key; + mbedtls_pk_context *issuer_key; + mbedtls_asn1_named_data *subject; + mbedtls_asn1_named_data *issuer; + mbedtls_md_type_t md_alg; + char not_before[MBEDTLS_X509_RFC5280_UTC_TIME_LEN + 1]; + char not_after[MBEDTLS_X509_RFC5280_UTC_TIME_LEN + 1]; + mbedtls_asn1_named_data *extensions; +} +mbedtls_x509write_cert; + +/** + * Item in a verification chain: cert and flags for it + */ +typedef struct { + mbedtls_x509_crt *crt; + uint32_t flags; +} mbedtls_x509_crt_verify_chain_item; + +/** + * Max size of verification chain: end-entity + intermediates + trusted root + */ +#define MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE ( MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2 ) + +/** + * Verification chain as built by \c mbedtls_crt_verify_chain() + */ +typedef struct +{ + mbedtls_x509_crt_verify_chain_item items[MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE]; + unsigned len; + +#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) + /* This stores the list of potential trusted signers obtained from + * the CA callback used for the CRT verification, if configured. + * We must track it somewhere because the callback passes its + * ownership to the caller. */ + mbedtls_x509_crt *trust_ca_cb_result; +#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ +} mbedtls_x509_crt_verify_chain; + +#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) + +/** + * \brief Context for resuming X.509 verify operations + */ +typedef struct +{ + /* for check_signature() */ + mbedtls_pk_restart_ctx pk; + + /* for find_parent_in() */ + mbedtls_x509_crt *parent; /* non-null iff parent_in in progress */ + mbedtls_x509_crt *fallback_parent; + int fallback_signature_is_good; + + /* for find_parent() */ + int parent_is_trusted; /* -1 if find_parent is not in progress */ + + /* for verify_chain() */ + enum { + x509_crt_rs_none, + x509_crt_rs_find_parent, + } in_progress; /* none if no operation is in progress */ + int self_cnt; + mbedtls_x509_crt_verify_chain ver_chain; + +} mbedtls_x509_crt_restart_ctx; + +#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ + +/* Now we can declare functions that take a pointer to that */ +typedef void mbedtls_x509_crt_restart_ctx; + +#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ + +#if defined(MBEDTLS_X509_CRT_PARSE_C) +/** + * Default security profile. Should provide a good balance between security + * and compatibility with current deployments. + * + * This profile permits: + * - SHA2 hashes. + * - All supported elliptic curves. + * - RSA with 2048 bits and above. + * + * New minor versions of Mbed TLS may extend this profile, for example if + * new curves are added to the library. New minor versions of Mbed TLS will + * not reduce this profile unless serious security concerns require it. + */ +extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default; + +/** + * Expected next default profile. Recommended for new deployments. + * Currently targets a 128-bit security level, except for allowing RSA-2048. + */ +extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next; + +/** + * NSA Suite B profile. + */ +extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb; + +/** + * \brief Parse a single DER formatted certificate and add it + * to the end of the provided chained list. + * + * \param chain The pointer to the start of the CRT chain to attach to. + * When parsing the first CRT in a chain, this should point + * to an instance of ::mbedtls_x509_crt initialized through + * mbedtls_x509_crt_init(). + * \param buf The buffer holding the DER encoded certificate. + * \param buflen The size in Bytes of \p buf. + * + * \note This function makes an internal copy of the CRT buffer + * \p buf. In particular, \p buf may be destroyed or reused + * after this call returns. To avoid duplicating the CRT + * buffer (at the cost of stricter lifetime constraints), + * use mbedtls_x509_crt_parse_der_nocopy() instead. + * + * \return \c 0 if successful. + * \return A negative error code on failure. + */ +int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, + const unsigned char *buf, + size_t buflen ); + +/** + * \brief The type of certificate extension callbacks. + * + * Callbacks of this type are passed to and used by the + * mbedtls_x509_crt_parse_der_with_ext_cb() routine when + * it encounters either an unsupported extension or a + * "certificate policies" extension containing any + * unsupported certificate policies. + * Future versions of the library may invoke the callback + * in other cases, if and when the need arises. + * + * \param p_ctx An opaque context passed to the callback. + * \param crt The certificate being parsed. + * \param oid The OID of the extension. + * \param critical Whether the extension is critical. + * \param p Pointer to the start of the extension value + * (the content of the OCTET STRING). + * \param end End of extension value. + * + * \note The callback must fail and return a negative error code + * if it can not parse or does not support the extension. + * When the callback fails to parse a critical extension + * mbedtls_x509_crt_parse_der_with_ext_cb() also fails. + * When the callback fails to parse a non critical extension + * mbedtls_x509_crt_parse_der_with_ext_cb() simply skips + * the extension and continues parsing. + * + * \return \c 0 on success. + * \return A negative error code on failure. + */ +typedef int (*mbedtls_x509_crt_ext_cb_t)( void *p_ctx, + mbedtls_x509_crt const *crt, + mbedtls_x509_buf const *oid, + int critical, + const unsigned char *p, + const unsigned char *end ); + +/** + * \brief Parse a single DER formatted certificate and add it + * to the end of the provided chained list. + * + * \param chain The pointer to the start of the CRT chain to attach to. + * When parsing the first CRT in a chain, this should point + * to an instance of ::mbedtls_x509_crt initialized through + * mbedtls_x509_crt_init(). + * \param buf The buffer holding the DER encoded certificate. + * \param buflen The size in Bytes of \p buf. + * \param make_copy When not zero this function makes an internal copy of the + * CRT buffer \p buf. In particular, \p buf may be destroyed + * or reused after this call returns. + * When zero this function avoids duplicating the CRT buffer + * by taking temporary ownership thereof until the CRT + * is destroyed (like mbedtls_x509_crt_parse_der_nocopy()) + * \param cb A callback invoked for every unsupported certificate + * extension. + * \param p_ctx An opaque context passed to the callback. + * + * \note This call is functionally equivalent to + * mbedtls_x509_crt_parse_der(), and/or + * mbedtls_x509_crt_parse_der_nocopy() + * but it calls the callback with every unsupported + * certificate extension and additionally the + * "certificate policies" extension if it contains any + * unsupported certificate policies. + * The callback must return a negative error code if it + * does not know how to handle such an extension. + * When the callback fails to parse a critical extension + * mbedtls_x509_crt_parse_der_with_ext_cb() also fails. + * When the callback fails to parse a non critical extension + * mbedtls_x509_crt_parse_der_with_ext_cb() simply skips + * the extension and continues parsing. + * Future versions of the library may invoke the callback + * in other cases, if and when the need arises. + * + * \return \c 0 if successful. + * \return A negative error code on failure. + */ +int mbedtls_x509_crt_parse_der_with_ext_cb( mbedtls_x509_crt *chain, + const unsigned char *buf, + size_t buflen, + int make_copy, + mbedtls_x509_crt_ext_cb_t cb, + void *p_ctx ); + +/** + * \brief Parse a single DER formatted certificate and add it + * to the end of the provided chained list. This is a + * variant of mbedtls_x509_crt_parse_der() which takes + * temporary ownership of the CRT buffer until the CRT + * is destroyed. + * + * \param chain The pointer to the start of the CRT chain to attach to. + * When parsing the first CRT in a chain, this should point + * to an instance of ::mbedtls_x509_crt initialized through + * mbedtls_x509_crt_init(). + * \param buf The address of the readable buffer holding the DER encoded + * certificate to use. On success, this buffer must be + * retained and not be changed for the liftetime of the + * CRT chain \p chain, that is, until \p chain is destroyed + * through a call to mbedtls_x509_crt_free(). + * \param buflen The size in Bytes of \p buf. + * + * \note This call is functionally equivalent to + * mbedtls_x509_crt_parse_der(), but it avoids creating a + * copy of the input buffer at the cost of stronger lifetime + * constraints. This is useful in constrained environments + * where duplication of the CRT cannot be tolerated. + * + * \return \c 0 if successful. + * \return A negative error code on failure. + */ +int mbedtls_x509_crt_parse_der_nocopy( mbedtls_x509_crt *chain, + const unsigned char *buf, + size_t buflen ); + +/** + * \brief Parse one DER-encoded or one or more concatenated PEM-encoded + * certificates and add them to the chained list. + * + * For CRTs in PEM encoding, the function parses permissively: + * if at least one certificate can be parsed, the function + * returns the number of certificates for which parsing failed + * (hence \c 0 if all certificates were parsed successfully). + * If no certificate could be parsed, the function returns + * the first (negative) error encountered during parsing. + * + * PEM encoded certificates may be interleaved by other data + * such as human readable descriptions of their content, as + * long as the certificates are enclosed in the PEM specific + * '-----{BEGIN/END} CERTIFICATE-----' delimiters. + * + * \param chain The chain to which to add the parsed certificates. + * \param buf The buffer holding the certificate data in PEM or DER format. + * For certificates in PEM encoding, this may be a concatenation + * of multiple certificates; for DER encoding, the buffer must + * comprise exactly one certificate. + * \param buflen The size of \p buf, including the terminating \c NULL byte + * in case of PEM encoded data. + * + * \return \c 0 if all certificates were parsed successfully. + * \return The (positive) number of certificates that couldn't + * be parsed if parsing was partly successful (see above). + * \return A negative X509 or PEM error code otherwise. + * + */ +int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen ); + +#if defined(MBEDTLS_FS_IO) +/** + * \brief Load one or more certificates and add them + * to the chained list. Parses permissively. If some + * certificates can be parsed, the result is the number + * of failed certificates it encountered. If none complete + * correctly, the first error is returned. + * + * \param chain points to the start of the chain + * \param path filename to read the certificates from + * + * \return 0 if all certificates parsed successfully, a positive number + * if partly successful or a specific X509 or PEM error code + */ +int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path ); + +/** + * \brief Load one or more certificate files from a path and add them + * to the chained list. Parses permissively. If some + * certificates can be parsed, the result is the number + * of failed certificates it encountered. If none complete + * correctly, the first error is returned. + * + * \param chain points to the start of the chain + * \param path directory / folder to read the certificate files from + * + * \return 0 if all certificates parsed successfully, a positive number + * if partly successful or a specific X509 or PEM error code + */ +int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ); + +#endif /* MBEDTLS_FS_IO */ +/** + * \brief This function parses an item in the SubjectAlternativeNames + * extension. + * + * \param san_buf The buffer holding the raw data item of the subject + * alternative name. + * \param san The target structure to populate with the parsed presentation + * of the subject alternative name encoded in \p san_raw. + * + * \note Only "dnsName" and "otherName" of type hardware_module_name + * as defined in RFC 4180 is supported. + * + * \note This function should be called on a single raw data of + * subject alternative name. For example, after successful + * certificate parsing, one must iterate on every item in the + * \p crt->subject_alt_names sequence, and pass it to + * this function. + * + * \warning The target structure contains pointers to the raw data of the + * parsed certificate, and its lifetime is restricted by the + * lifetime of the certificate. + * + * \return \c 0 on success + * \return #MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE for an unsupported + * SAN type. + * \return Another negative value for any other failure. + */ +int mbedtls_x509_parse_subject_alt_name( const mbedtls_x509_buf *san_buf, + mbedtls_x509_subject_alternative_name *san ); +/** + * \brief Returns an informational string about the + * certificate. + * + * \param buf Buffer to write to + * \param size Maximum size of buffer + * \param prefix A line prefix + * \param crt The X509 certificate to represent + * + * \return The length of the string written (not including the + * terminated nul byte), or a negative error code. + */ +int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix, + const mbedtls_x509_crt *crt ); + +/** + * \brief Returns an informational string about the + * verification status of a certificate. + * + * \param buf Buffer to write to + * \param size Maximum size of buffer + * \param prefix A line prefix + * \param flags Verification flags created by mbedtls_x509_crt_verify() + * + * \return The length of the string written (not including the + * terminated nul byte), or a negative error code. + */ +int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix, + uint32_t flags ); + +/** + * \brief Verify a chain of certificates. + * + * The verify callback is a user-supplied callback that + * can clear / modify / add flags for a certificate. If set, + * the verification callback is called for each + * certificate in the chain (from the trust-ca down to the + * presented crt). The parameters for the callback are: + * (void *parameter, mbedtls_x509_crt *crt, int certificate_depth, + * int *flags). With the flags representing current flags for + * that specific certificate and the certificate depth from + * the bottom (Peer cert depth = 0). + * + * All flags left after returning from the callback + * are also returned to the application. The function should + * return 0 for anything (including invalid certificates) + * other than fatal error, as a non-zero return code + * immediately aborts the verification process. For fatal + * errors, a specific error code should be used (different + * from MBEDTLS_ERR_X509_CERT_VERIFY_FAILED which should not + * be returned at this point), or MBEDTLS_ERR_X509_FATAL_ERROR + * can be used if no better code is available. + * + * \note In case verification failed, the results can be displayed + * using \c mbedtls_x509_crt_verify_info() + * + * \note Same as \c mbedtls_x509_crt_verify_with_profile() with the + * default security profile. + * + * \note It is your responsibility to provide up-to-date CRLs for + * all trusted CAs. If no CRL is provided for the CA that was + * used to sign the certificate, CRL verification is skipped + * silently, that is *without* setting any flag. + * + * \note The \c trust_ca list can contain two types of certificates: + * (1) those of trusted root CAs, so that certificates + * chaining up to those CAs will be trusted, and (2) + * self-signed end-entity certificates to be trusted (for + * specific peers you know) - in that case, the self-signed + * certificate doesn't need to have the CA bit set. + * + * \param crt The certificate chain to be verified. + * \param trust_ca The list of trusted CAs. + * \param ca_crl The list of CRLs for trusted CAs. + * \param cn The expected Common Name. This will be checked to be + * present in the certificate's subjectAltNames extension or, + * if this extension is absent, as a CN component in its + * Subject name. Currently only DNS names are supported. This + * may be \c NULL if the CN need not be verified. + * \param flags The address at which to store the result of the verification. + * If the verification couldn't be completed, the flag value is + * set to (uint32_t) -1. + * \param f_vrfy The verification callback to use. See the documentation + * of mbedtls_x509_crt_verify() for more information. + * \param p_vrfy The context to be passed to \p f_vrfy. + * + * \return \c 0 if the chain is valid with respect to the + * passed CN, CAs, CRLs and security profile. + * \return #MBEDTLS_ERR_X509_CERT_VERIFY_FAILED in case the + * certificate chain verification failed. In this case, + * \c *flags will have one or more + * \c MBEDTLS_X509_BADCERT_XXX or \c MBEDTLS_X509_BADCRL_XXX + * flags set. + * \return Another negative error code in case of a fatal error + * encountered during the verification process. + */ +int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt, + mbedtls_x509_crt *trust_ca, + mbedtls_x509_crl *ca_crl, + const char *cn, uint32_t *flags, + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), + void *p_vrfy ); + +/** + * \brief Verify a chain of certificates with respect to + * a configurable security profile. + * + * \note Same as \c mbedtls_x509_crt_verify(), but with explicit + * security profile. + * + * \note The restrictions on keys (RSA minimum size, allowed curves + * for ECDSA) apply to all certificates: trusted root, + * intermediate CAs if any, and end entity certificate. + * + * \param crt The certificate chain to be verified. + * \param trust_ca The list of trusted CAs. + * \param ca_crl The list of CRLs for trusted CAs. + * \param profile The security profile to use for the verification. + * \param cn The expected Common Name. This may be \c NULL if the + * CN need not be verified. + * \param flags The address at which to store the result of the verification. + * If the verification couldn't be completed, the flag value is + * set to (uint32_t) -1. + * \param f_vrfy The verification callback to use. See the documentation + * of mbedtls_x509_crt_verify() for more information. + * \param p_vrfy The context to be passed to \p f_vrfy. + * + * \return \c 0 if the chain is valid with respect to the + * passed CN, CAs, CRLs and security profile. + * \return #MBEDTLS_ERR_X509_CERT_VERIFY_FAILED in case the + * certificate chain verification failed. In this case, + * \c *flags will have one or more + * \c MBEDTLS_X509_BADCERT_XXX or \c MBEDTLS_X509_BADCRL_XXX + * flags set. + * \return Another negative error code in case of a fatal error + * encountered during the verification process. + */ +int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt, + mbedtls_x509_crt *trust_ca, + mbedtls_x509_crl *ca_crl, + const mbedtls_x509_crt_profile *profile, + const char *cn, uint32_t *flags, + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), + void *p_vrfy ); + +/** + * \brief Restartable version of \c mbedtls_crt_verify_with_profile() + * + * \note Performs the same job as \c mbedtls_crt_verify_with_profile() + * but can return early and restart according to the limit + * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. + * + * \param crt The certificate chain to be verified. + * \param trust_ca The list of trusted CAs. + * \param ca_crl The list of CRLs for trusted CAs. + * \param profile The security profile to use for the verification. + * \param cn The expected Common Name. This may be \c NULL if the + * CN need not be verified. + * \param flags The address at which to store the result of the verification. + * If the verification couldn't be completed, the flag value is + * set to (uint32_t) -1. + * \param f_vrfy The verification callback to use. See the documentation + * of mbedtls_x509_crt_verify() for more information. + * \param p_vrfy The context to be passed to \p f_vrfy. + * \param rs_ctx The restart context to use. This may be set to \c NULL + * to disable restartable ECC. + * + * \return See \c mbedtls_crt_verify_with_profile(), or + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + */ +int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt, + mbedtls_x509_crt *trust_ca, + mbedtls_x509_crl *ca_crl, + const mbedtls_x509_crt_profile *profile, + const char *cn, uint32_t *flags, + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), + void *p_vrfy, + mbedtls_x509_crt_restart_ctx *rs_ctx ); + +/** + * \brief The type of trusted certificate callbacks. + * + * Callbacks of this type are passed to and used by the CRT + * verification routine mbedtls_x509_crt_verify_with_ca_cb() + * when looking for trusted signers of a given certificate. + * + * On success, the callback returns a list of trusted + * certificates to be considered as potential signers + * for the input certificate. + * + * \param p_ctx An opaque context passed to the callback. + * \param child The certificate for which to search a potential signer. + * This will point to a readable certificate. + * \param candidate_cas The address at which to store the address of the first + * entry in the generated linked list of candidate signers. + * This will not be \c NULL. + * + * \note The callback must only return a non-zero value on a + * fatal error. If, in contrast, the search for a potential + * signer completes without a single candidate, the + * callback must return \c 0 and set \c *candidate_cas + * to \c NULL. + * + * \return \c 0 on success. In this case, \c *candidate_cas points + * to a heap-allocated linked list of instances of + * ::mbedtls_x509_crt, and ownership of this list is passed + * to the caller. + * \return A negative error code on failure. + */ +typedef int (*mbedtls_x509_crt_ca_cb_t)( void *p_ctx, + mbedtls_x509_crt const *child, + mbedtls_x509_crt **candidate_cas ); + +#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) +/** + * \brief Version of \c mbedtls_x509_crt_verify_with_profile() which + * uses a callback to acquire the list of trusted CA + * certificates. + * + * \param crt The certificate chain to be verified. + * \param f_ca_cb The callback to be used to query for potential signers + * of a given child certificate. See the documentation of + * ::mbedtls_x509_crt_ca_cb_t for more information. + * \param p_ca_cb The opaque context to be passed to \p f_ca_cb. + * \param profile The security profile for the verification. + * \param cn The expected Common Name. This may be \c NULL if the + * CN need not be verified. + * \param flags The address at which to store the result of the verification. + * If the verification couldn't be completed, the flag value is + * set to (uint32_t) -1. + * \param f_vrfy The verification callback to use. See the documentation + * of mbedtls_x509_crt_verify() for more information. + * \param p_vrfy The context to be passed to \p f_vrfy. + * + * \return See \c mbedtls_crt_verify_with_profile(). + */ +int mbedtls_x509_crt_verify_with_ca_cb( mbedtls_x509_crt *crt, + mbedtls_x509_crt_ca_cb_t f_ca_cb, + void *p_ca_cb, + const mbedtls_x509_crt_profile *profile, + const char *cn, uint32_t *flags, + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), + void *p_vrfy ); + +#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */ + +#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) +/** + * \brief Check usage of certificate against keyUsage extension. + * + * \param crt Leaf certificate used. + * \param usage Intended usage(s) (eg MBEDTLS_X509_KU_KEY_ENCIPHERMENT + * before using the certificate to perform an RSA key + * exchange). + * + * \note Except for decipherOnly and encipherOnly, a bit set in the + * usage argument means this bit MUST be set in the + * certificate. For decipherOnly and encipherOnly, it means + * that bit MAY be set. + * + * \return 0 is these uses of the certificate are allowed, + * MBEDTLS_ERR_X509_BAD_INPUT_DATA if the keyUsage extension + * is present but does not match the usage argument. + * + * \note You should only call this function on leaf certificates, on + * (intermediate) CAs the keyUsage extension is automatically + * checked by \c mbedtls_x509_crt_verify(). + */ +int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt, + unsigned int usage ); +#endif /* MBEDTLS_X509_CHECK_KEY_USAGE) */ + +#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) +/** + * \brief Check usage of certificate against extendedKeyUsage. + * + * \param crt Leaf certificate used. + * \param usage_oid Intended usage (eg MBEDTLS_OID_SERVER_AUTH or + * MBEDTLS_OID_CLIENT_AUTH). + * \param usage_len Length of usage_oid (eg given by MBEDTLS_OID_SIZE()). + * + * \return 0 if this use of the certificate is allowed, + * MBEDTLS_ERR_X509_BAD_INPUT_DATA if not. + * + * \note Usually only makes sense on leaf certificates. + */ +int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt, + const char *usage_oid, + size_t usage_len ); +#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */ + +#if defined(MBEDTLS_X509_CRL_PARSE_C) +/** + * \brief Verify the certificate revocation status + * + * \param crt a certificate to be verified + * \param crl the CRL to verify against + * + * \return 1 if the certificate is revoked, 0 otherwise + * + */ +int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl ); +#endif /* MBEDTLS_X509_CRL_PARSE_C */ + +/** + * \brief Initialize a certificate (chain) + * + * \param crt Certificate chain to initialize + */ +void mbedtls_x509_crt_init( mbedtls_x509_crt *crt ); + +/** + * \brief Unallocate all certificate data + * + * \param crt Certificate chain to free + */ +void mbedtls_x509_crt_free( mbedtls_x509_crt *crt ); + +#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) +/** + * \brief Initialize a restart context + */ +void mbedtls_x509_crt_restart_init( mbedtls_x509_crt_restart_ctx *ctx ); + +/** + * \brief Free the components of a restart context + */ +void mbedtls_x509_crt_restart_free( mbedtls_x509_crt_restart_ctx *ctx ); +#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + +/** \} name Structures and functions for parsing and writing X.509 certificates */ + +#if defined(MBEDTLS_X509_CRT_WRITE_C) +/** + * \brief Initialize a CRT writing context + * + * \param ctx CRT context to initialize + */ +void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx ); + +/** + * \brief Set the version for a Certificate + * Default: MBEDTLS_X509_CRT_VERSION_3 + * + * \param ctx CRT context to use + * \param version version to set (MBEDTLS_X509_CRT_VERSION_1, MBEDTLS_X509_CRT_VERSION_2 or + * MBEDTLS_X509_CRT_VERSION_3) + */ +void mbedtls_x509write_crt_set_version( mbedtls_x509write_cert *ctx, int version ); + +/** + * \brief Set the serial number for a Certificate. + * + * \param ctx CRT context to use + * \param serial serial number to set + * + * \return 0 if successful + */ +int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx, const mbedtls_mpi *serial ); + +/** + * \brief Set the validity period for a Certificate + * Timestamps should be in string format for UTC timezone + * i.e. "YYYYMMDDhhmmss" + * e.g. "20131231235959" for December 31st 2013 + * at 23:59:59 + * + * \param ctx CRT context to use + * \param not_before not_before timestamp + * \param not_after not_after timestamp + * + * \return 0 if timestamp was parsed successfully, or + * a specific error code + */ +int mbedtls_x509write_crt_set_validity( mbedtls_x509write_cert *ctx, const char *not_before, + const char *not_after ); + +/** + * \brief Set the issuer name for a Certificate + * Issuer names should contain a comma-separated list + * of OID types and values: + * e.g. "C=UK,O=ARM,CN=mbed TLS CA" + * + * \param ctx CRT context to use + * \param issuer_name issuer name to set + * + * \return 0 if issuer name was parsed successfully, or + * a specific error code + */ +int mbedtls_x509write_crt_set_issuer_name( mbedtls_x509write_cert *ctx, + const char *issuer_name ); + +/** + * \brief Set the subject name for a Certificate + * Subject names should contain a comma-separated list + * of OID types and values: + * e.g. "C=UK,O=ARM,CN=mbed TLS Server 1" + * + * \param ctx CRT context to use + * \param subject_name subject name to set + * + * \return 0 if subject name was parsed successfully, or + * a specific error code + */ +int mbedtls_x509write_crt_set_subject_name( mbedtls_x509write_cert *ctx, + const char *subject_name ); + +/** + * \brief Set the subject public key for the certificate + * + * \param ctx CRT context to use + * \param key public key to include + */ +void mbedtls_x509write_crt_set_subject_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key ); + +/** + * \brief Set the issuer key used for signing the certificate + * + * \param ctx CRT context to use + * \param key private key to sign with + */ +void mbedtls_x509write_crt_set_issuer_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key ); + +/** + * \brief Set the MD algorithm to use for the signature + * (e.g. MBEDTLS_MD_SHA1) + * + * \param ctx CRT context to use + * \param md_alg MD algorithm to use + */ +void mbedtls_x509write_crt_set_md_alg( mbedtls_x509write_cert *ctx, mbedtls_md_type_t md_alg ); + +/** + * \brief Generic function to add to or replace an extension in the + * CRT + * + * \param ctx CRT context to use + * \param oid OID of the extension + * \param oid_len length of the OID + * \param critical if the extension is critical (per the RFC's definition) + * \param val value of the extension OCTET STRING + * \param val_len length of the value data + * + * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED + */ +int mbedtls_x509write_crt_set_extension( mbedtls_x509write_cert *ctx, + const char *oid, size_t oid_len, + int critical, + const unsigned char *val, size_t val_len ); + +/** + * \brief Set the basicConstraints extension for a CRT + * + * \param ctx CRT context to use + * \param is_ca is this a CA certificate + * \param max_pathlen maximum length of certificate chains below this + * certificate (only for CA certificates, -1 is + * unlimited) + * + * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED + */ +int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx, + int is_ca, int max_pathlen ); + +#if defined(MBEDTLS_SHA1_C) +/** + * \brief Set the subjectKeyIdentifier extension for a CRT + * Requires that mbedtls_x509write_crt_set_subject_key() has been + * called before + * + * \param ctx CRT context to use + * + * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED + */ +int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ctx ); + +/** + * \brief Set the authorityKeyIdentifier extension for a CRT + * Requires that mbedtls_x509write_crt_set_issuer_key() has been + * called before + * + * \param ctx CRT context to use + * + * \return 0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED + */ +int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *ctx ); +#endif /* MBEDTLS_SHA1_C */ + +/** + * \brief Set the Key Usage Extension flags + * (e.g. MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_KEY_CERT_SIGN) + * + * \param ctx CRT context to use + * \param key_usage key usage flags to set + * + * \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED + */ +int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx, + unsigned int key_usage ); + +/** + * \brief Set the Netscape Cert Type flags + * (e.g. MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT | MBEDTLS_X509_NS_CERT_TYPE_EMAIL) + * + * \param ctx CRT context to use + * \param ns_cert_type Netscape Cert Type flags to set + * + * \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED + */ +int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx, + unsigned char ns_cert_type ); + +/** + * \brief Free the contents of a CRT write context + * + * \param ctx CRT context to free + */ +void mbedtls_x509write_crt_free( mbedtls_x509write_cert *ctx ); + +/** + * \brief Write a built up certificate to a X509 DER structure + * Note: data is written at the end of the buffer! Use the + * return value to determine where you should start + * using the buffer + * + * \param ctx certificate to write away + * \param buf buffer to write to + * \param size size of the buffer + * \param f_rng RNG function (for signature, see note) + * \param p_rng RNG parameter + * + * \return length of data written if successful, or a specific + * error code + * + * \note f_rng may be NULL if RSA is used for signature and the + * signature is made offline (otherwise f_rng is desirable + * for countermeasures against timing attacks). + * ECDSA signatures always require a non-NULL f_rng. + */ +int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +#if defined(MBEDTLS_PEM_WRITE_C) +/** + * \brief Write a built up certificate to a X509 PEM string + * + * \param ctx certificate to write away + * \param buf buffer to write to + * \param size size of the buffer + * \param f_rng RNG function (for signature, see note) + * \param p_rng RNG parameter + * + * \return 0 if successful, or a specific error code + * + * \note f_rng may be NULL if RSA is used for signature and the + * signature is made offline (otherwise f_rng is desirable + * for countermeasures against timing attacks). + * ECDSA signatures always require a non-NULL f_rng. + */ +int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); +#endif /* MBEDTLS_PEM_WRITE_C */ +#endif /* MBEDTLS_X509_CRT_WRITE_C */ + +/** \} addtogroup x509_module */ + +#ifdef __cplusplus +} +#endif + +#endif /* mbedtls_x509_crt.h */ diff --git a/third_party/mbedtls/include/mbedtls_config_openwatt.h b/third_party/mbedtls/include/mbedtls_config_openwatt.h new file mode 100644 index 0000000..b79eb4f --- /dev/null +++ b/third_party/mbedtls/include/mbedtls_config_openwatt.h @@ -0,0 +1,192 @@ +/* + * OpenWatt mbedtls 2.28.1 config for Bouffalo BL808 (D0 + M0) and BL618. + * + * Built against: mbedtls 2.28.1 (upstream tag, see third_party/mbedtls_bl808/ + * upstream/mbedtls-2.28.1.tar.gz). The 24 headers in this directory are the + * gcc-computed transitive closure of urt/internal/mbedtls.c's includes under + * this config; libmbedtls.a in platforms/{bl808,bl618}/lib/ is the prebuilt + * library matched to this header set. When bumping mbedtls, rebuild the .a + * and re-run the closure computation to keep the two in sync. + * + * Scope: TLS 1.2 + 1.3 (client+server), X.509 validation, RSA + ECDSA P-256/P-384, + * ECDH P-256/Curve25519, AES (all modes), ChaCha20-Poly1305, SHA-1/256/384/512, + * HMAC + HKDF + PBKDF2, CTR-DRBG. Sized to cover today's TLS/Tesla-BLE consumers + * plus the listed future ones (SSH, WPA supplicant, Zigbee/Thread association) + * without re-rolling the .a. + * + * Trimmed off: DTLS, deprecated ciphers (ARC4/3DES/DES/Blowfish/Camellia/ARIA/ + * XTEA), MD2/MD4/MD5-as-primary, RIPEMD-160, debug/test machinery. + * + * Build-time platform extension hooks (xSemaphore/pvPortMalloc/etc.) are + * declared in shim/include/ and resolved at link-time by OpenWatt. + */ +#ifndef MBEDTLS_CONFIG_OPENWATT_H +#define MBEDTLS_CONFIG_OPENWATT_H + +/* ---------------- Platform ---------------- */ +#define MBEDTLS_PLATFORM_C +#define MBEDTLS_PLATFORM_MEMORY +/* Note: NOT setting MBEDTLS_PLATFORM_NO_STD_FUNCTIONS - lets mbedtls call + * snprintf/printf via the integrator's libc/shim. OpenWatt link-time + * supplies a minimal snprintf (X.509 / OID / error formatting only). */ +#define MBEDTLS_NO_PLATFORM_ENTROPY +#define MBEDTLS_HAVE_ASM +#define MBEDTLS_HAVE_TIME + +/* Threading: vendor port uses bl_sec_*_mutex_take/give around SEC engine. + * No mbedtls-level threading wrapper needed - we serialise at the HW seam. */ + +/* ---------------- Symmetric ciphers ---------------- */ +#define MBEDTLS_AES_C +#define MBEDTLS_AES_ROM_TABLES +#define MBEDTLS_CIPHER_C +#define MBEDTLS_CIPHER_MODE_CBC +#define MBEDTLS_CIPHER_MODE_CFB +#define MBEDTLS_CIPHER_MODE_CTR +#define MBEDTLS_CIPHER_MODE_OFB +#define MBEDTLS_CIPHER_MODE_XTS +#define MBEDTLS_CIPHER_PADDING_PKCS7 +#define MBEDTLS_CIPHER_PADDING_ZEROS +#define MBEDTLS_CCM_C +#define MBEDTLS_GCM_C +#define MBEDTLS_CMAC_C +#define MBEDTLS_NIST_KW_C +#define MBEDTLS_CHACHA20_C +#define MBEDTLS_CHACHAPOLY_C +#define MBEDTLS_POLY1305_C + +/* Strip legacy/deprecated symmetric primitives */ +#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES +#define MBEDTLS_REMOVE_3DES_CIPHERSUITES + +/* ---------------- Hashes ---------------- */ +#define MBEDTLS_MD_C +#define MBEDTLS_SHA1_C /* WPA PRF, TLS legacy cipher suites, X.509 legacy */ +#define MBEDTLS_SHA256_C +#define MBEDTLS_SHA512_C /* covers SHA-384 also */ +#define MBEDTLS_MD5_C /* TLS 1.2 PRF, PEM PBE - not as primary hash */ +#define MBEDTLS_HKDF_C +#define MBEDTLS_PKCS5_C /* PBKDF2 (WPA-PSK, PEM password) */ + +/* ---------------- Public key ---------------- */ +#define MBEDTLS_PK_C +#define MBEDTLS_PK_PARSE_C +#define MBEDTLS_PK_WRITE_C +#define MBEDTLS_RSA_C +#define MBEDTLS_PKCS1_V15 +#define MBEDTLS_PKCS1_V21 +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_OID_C +#define MBEDTLS_ASN1_PARSE_C +#define MBEDTLS_ASN1_WRITE_C +#define MBEDTLS_BASE64_C + +/* ECC */ +#define MBEDTLS_ECP_C +#define MBEDTLS_ECP_NIST_OPTIM +#define MBEDTLS_ECDH_C +#define MBEDTLS_ECDSA_C +#define MBEDTLS_ECDSA_DETERMINISTIC +#define MBEDTLS_ECJPAKE_C /* Thread commissioning */ + +/* Curves enabled */ +#define MBEDTLS_ECP_DP_SECP256R1_ENABLED /* TLS, Tesla BLE, modern X.509 */ +#define MBEDTLS_ECP_DP_SECP384R1_ENABLED /* TLS, X.509 CA chains */ +#define MBEDTLS_ECP_DP_CURVE25519_ENABLED /* SSH, modern TLS 1.3, WireGuard-ish */ + +/* ---------------- X.509 ---------------- */ +#define MBEDTLS_X509_USE_C +#define MBEDTLS_X509_CRT_PARSE_C +#define MBEDTLS_X509_CRL_PARSE_C +#define MBEDTLS_X509_CSR_PARSE_C +#define MBEDTLS_X509_CREATE_C +#define MBEDTLS_X509_CRT_WRITE_C +#define MBEDTLS_X509_CSR_WRITE_C +#define MBEDTLS_PEM_PARSE_C +#define MBEDTLS_PEM_WRITE_C + +/* ---------------- RNG ---------------- */ +#define MBEDTLS_CTR_DRBG_C +#define MBEDTLS_HMAC_DRBG_C +#define MBEDTLS_ENTROPY_C +/* Entropy source: register at runtime via mbedtls_entropy_add_source() from + * OpenWatt init code. Our HW TRNG is accessed via D-side driver, not via + * the MBEDTLS_ENTROPY_HARDWARE_ALT hook (which would force a hard external + * symbol). Runtime registration is the standard mbedtls idiom and keeps + * the .a self-contained. */ + +/* ---------------- SSL/TLS ---------------- */ +#define MBEDTLS_SSL_TLS_C +#define MBEDTLS_SSL_CLI_C +#define MBEDTLS_SSL_SRV_C +#define MBEDTLS_SSL_PROTO_TLS1_2 +#define MBEDTLS_SSL_PROTO_TLS1_3 /* 2.28 has experimental 1.3 support */ +#define MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE +#define MBEDTLS_SSL_ALPN +#define MBEDTLS_SSL_SERVER_NAME_INDICATION +#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH +#define MBEDTLS_SSL_ENCRYPT_THEN_MAC +#define MBEDTLS_SSL_EXTENDED_MASTER_SECRET +#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE +#define MBEDTLS_SSL_RENEGOTIATION +#define MBEDTLS_SSL_SESSION_TICKETS +#define MBEDTLS_SSL_TICKET_C +#define MBEDTLS_SSL_CACHE_C +#define MBEDTLS_SSL_COOKIE_C +#define MBEDTLS_SSL_CONTEXT_SERIALIZATION + +/* TLS key-exchange modes - enable all we plausibly need */ +#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED +#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED +#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED +#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED +#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED +#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED +#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED /* WPA-PSK style, EAP-PSK */ +#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED +#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED +#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED +#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED /* Thread */ + +#define MBEDTLS_DHM_C + +/* ---------------- HW accel: weak-symbol overrides --------------------- + * + * We do NOT define MBEDTLS_*_ALT here. mbedtls compiles its own software + * implementations into the .a as normal. After build, the Makefile runs + * objcopy --weaken-symbol on the per-block primitives below, marking + * them weak in the archive. + * + * Effect at link time: + * - With no HW shim: weak SW symbols selected. .a is self-contained. + * - With HW shim: strong HW symbols in OpenWatt override the weak + * SW ones. No .a rebuild needed. + * + * Functions weakened (see Makefile): + * mbedtls_internal_aes_encrypt/_decrypt + * mbedtls_aes_setkey_enc/_dec + * mbedtls_internal_sha1_process / _sha256_process + * + * Entropy: NOT using MBEDTLS_ENTROPY_HARDWARE_ALT (would force a hard + * external symbol). Register our HW TRNG via mbedtls_entropy_add_source() + * at runtime from OpenWatt init. + * + * Bignum (RSA/ECDH/ECDSA) acceleration: deferred. mbedtls 2.28 has no + * fine-grained bignum hooks, and coarse MBEDTLS_BIGNUM_ALT would inflate + * the mpi context surface. Asymmetric ops stay software. Revisit if + * handshake latency becomes a problem in measurement. + */ + +/* ---------------- Hardening / size ---------------- */ +#define MBEDTLS_AES_FEWER_TABLES /* save ~6KB rodata */ +#define MBEDTLS_ECP_WINDOW_SIZE 4 /* small RAM footprint */ +#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0 + +/* No debug/test glue in the .a */ +/* #define MBEDTLS_SELF_TEST */ +/* #define MBEDTLS_DEBUG_C */ + +/* The standard sanity-check header. Must be last. */ +#include "mbedtls/check_config.h" + +#endif /* MBEDTLS_CONFIG_OPENWATT_H */ diff --git a/third_party/tlsf/README.md b/third_party/tlsf/README.md new file mode 100644 index 0000000..982919f --- /dev/null +++ b/third_party/tlsf/README.md @@ -0,0 +1,92 @@ +# tlsf +Two-Level Segregated Fit memory allocator implementation. +Written by Matthew Conte (matt@baisoku.org). +Released under the BSD license. + +Features +-------- + * O(1) cost for malloc, free, realloc, memalign + * Extremely low overhead per allocation (4 bytes) + * Low overhead per TLSF management of pools (~3kB) + * Low fragmentation + * Compiles to only a few kB of code and data + * Support for adding and removing memory pool regions on the fly + +Caveats +------- + * Currently, assumes architecture can make 4-byte aligned accesses + * Not designed to be thread safe; the user must provide this + +Notes +----- +This code was based on the TLSF 1.4 spec and documentation found at: + + http://www.gii.upv.es/tlsf/main/docs + +It also leverages the TLSF 2.0 improvement to shrink the per-block overhead from 8 to 4 bytes. + +History +------- +2016/04/10 - v3.1 + * Code moved to github + * tlsfbits.h rolled into tlsf.c + * License changed to BSD + +2014/02/08 - v3.0 + * This version is based on improvements from 3DInteractive GmbH + * Interface changed to allow more than one memory pool + * Separated pool handling from control structure (adding, removing, debugging) + * Control structure and pools can still be constructed in the same memory block + * Memory blocks for control structure and pools are checked for alignment + * Added functions to retrieve control structure size, alignment size, min and max block size, overhead of pool structure, and overhead of a single allocation + * Minimal Pool size is tlsf_block_size_min() + tlsf_pool_overhead() + * Pool must be empty when it is removed, in order to allow O(1) removal + +2011/10/20 - v2.0 + * 64-bit support + * More compiler intrinsics for ffs/fls + * ffs/fls verification during TLSF creation in debug builds + +2008/04/04 - v1.9 + * Add tlsf_heap_check, a heap integrity check + * Support a predefined tlsf_assert macro + * Fix realloc case where block should shrink; if adjacent block is in use, execution would go down the slow path + +2007/02/08 - v1.8 + * Fix for unnecessary reallocation in tlsf_realloc + +2007/02/03 - v1.7 + * tlsf_heap_walk takes a callback + * tlsf_realloc now returns NULL on failure + * tlsf_memalign optimization for 4-byte alignment + * Usage of size_t where appropriate + +2006/11/21 - v1.6 + * ffs/fls broken out into tlsfbits.h + * tlsf_overhead queries per-pool overhead + +2006/11/07 - v1.5 + * Smart realloc implementation + * Smart memalign implementation + +2006/10/11 - v1.4 + * Add some ffs/fls implementations + * Minor code footprint reduction + +2006/09/14 - v1.3 + * Profiling indicates heavy use of blocks of size 1-128, so implement small block handling + * Reduce pool overhead by about 1kb + * Reduce minimum block size from 32 to 12 bytes + * Realloc bug fix + +2006/09/09 - v1.2 + * Add tlsf_block_size + * Static assertion mechanism for invariants + * Minor bugfixes + +2006/09/01 - v1.1 + * Add tlsf_realloc + * Add tlsf_walk_heap + +2006/08/25 - v1.0 + * First release diff --git a/third_party/tlsf/tlsf.c b/third_party/tlsf/tlsf.c new file mode 100644 index 0000000..951466e --- /dev/null +++ b/third_party/tlsf/tlsf.c @@ -0,0 +1,1264 @@ +#include +#include +#include +#include +#include +#include + +#include "tlsf.h" + +#if defined(__cplusplus) +#define tlsf_decl inline +#else +#define tlsf_decl static +#endif + +/* +** Architecture-specific bit manipulation routines. +** +** TLSF achieves O(1) cost for malloc and free operations by limiting +** the search for a free block to a free list of guaranteed size +** adequate to fulfill the request, combined with efficient free list +** queries using bitmasks and architecture-specific bit-manipulation +** routines. +** +** Most modern processors provide instructions to count leading zeroes +** in a word, find the lowest and highest set bit, etc. These +** specific implementations will be used when available, falling back +** to a reasonably efficient generic implementation. +** +** NOTE: TLSF spec relies on ffs/fls returning value 0..31. +** ffs/fls return 1-32 by default, returning 0 for error. +*/ + +/* +** Detect whether or not we are building for a 32- or 64-bit (LP/LLP) +** architecture. There is no reliable portable method at compile-time. +*/ +#if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) \ + || defined (_WIN64) || defined (__LP64__) || defined (__LLP64__) +#define TLSF_64BIT +#endif + +/* +** gcc 3.4 and above have builtin support, specialized for architecture. +** Some compilers masquerade as gcc; patchlevel test filters them out. +*/ +#if defined (__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) \ + && defined (__GNUC_PATCHLEVEL__) + +#if defined (__SNC__) +/* SNC for Playstation 3. */ + +tlsf_decl int tlsf_ffs(unsigned int word) +{ + const unsigned int reverse = word & (~word + 1); + const int bit = 32 - __builtin_clz(reverse); + return bit - 1; +} + +#else + +tlsf_decl int tlsf_ffs(unsigned int word) +{ + return __builtin_ffs(word) - 1; +} + +#endif + +tlsf_decl int tlsf_fls(unsigned int word) +{ + const int bit = word ? 32 - __builtin_clz(word) : 0; + return bit - 1; +} + +#elif defined (_MSC_VER) && (_MSC_VER >= 1400) && (defined (_M_IX86) || defined (_M_X64)) +/* Microsoft Visual C++ support on x86/X64 architectures. */ + +#include + +#pragma intrinsic(_BitScanReverse) +#pragma intrinsic(_BitScanForward) + +tlsf_decl int tlsf_fls(unsigned int word) +{ + unsigned long index; + return _BitScanReverse(&index, word) ? index : -1; +} + +tlsf_decl int tlsf_ffs(unsigned int word) +{ + unsigned long index; + return _BitScanForward(&index, word) ? index : -1; +} + +#elif defined (_MSC_VER) && defined (_M_PPC) +/* Microsoft Visual C++ support on PowerPC architectures. */ + +#include + +tlsf_decl int tlsf_fls(unsigned int word) +{ + const int bit = 32 - _CountLeadingZeros(word); + return bit - 1; +} + +tlsf_decl int tlsf_ffs(unsigned int word) +{ + const unsigned int reverse = word & (~word + 1); + const int bit = 32 - _CountLeadingZeros(reverse); + return bit - 1; +} + +#elif defined (__ARMCC_VERSION) +/* RealView Compilation Tools for ARM */ + +tlsf_decl int tlsf_ffs(unsigned int word) +{ + const unsigned int reverse = word & (~word + 1); + const int bit = 32 - __clz(reverse); + return bit - 1; +} + +tlsf_decl int tlsf_fls(unsigned int word) +{ + const int bit = word ? 32 - __clz(word) : 0; + return bit - 1; +} + +#elif defined (__ghs__) +/* Green Hills support for PowerPC */ + +#include + +tlsf_decl int tlsf_ffs(unsigned int word) +{ + const unsigned int reverse = word & (~word + 1); + const int bit = 32 - __CLZ32(reverse); + return bit - 1; +} + +tlsf_decl int tlsf_fls(unsigned int word) +{ + const int bit = word ? 32 - __CLZ32(word) : 0; + return bit - 1; +} + +#else +/* Fall back to generic implementation. */ + +tlsf_decl int tlsf_fls_generic(unsigned int word) +{ + int bit = 32; + + if (!word) bit -= 1; + if (!(word & 0xffff0000)) { word <<= 16; bit -= 16; } + if (!(word & 0xff000000)) { word <<= 8; bit -= 8; } + if (!(word & 0xf0000000)) { word <<= 4; bit -= 4; } + if (!(word & 0xc0000000)) { word <<= 2; bit -= 2; } + if (!(word & 0x80000000)) { word <<= 1; bit -= 1; } + + return bit; +} + +/* Implement ffs in terms of fls. */ +tlsf_decl int tlsf_ffs(unsigned int word) +{ + return tlsf_fls_generic(word & (~word + 1)) - 1; +} + +tlsf_decl int tlsf_fls(unsigned int word) +{ + return tlsf_fls_generic(word) - 1; +} + +#endif + +/* Possibly 64-bit version of tlsf_fls. */ +#if defined (TLSF_64BIT) +tlsf_decl int tlsf_fls_sizet(size_t size) +{ + int high = (int)(size >> 32); + int bits = 0; + if (high) + { + bits = 32 + tlsf_fls(high); + } + else + { + bits = tlsf_fls((int)size & 0xffffffff); + + } + return bits; +} +#else +#define tlsf_fls_sizet tlsf_fls +#endif + +#undef tlsf_decl + +/* +** Constants. +*/ + +/* Public constants: may be modified. */ +enum tlsf_public +{ + /* log2 of number of linear subdivisions of block sizes. Larger + ** values require more memory in the control structure. Values of + ** 4 or 5 are typical. + */ + SL_INDEX_COUNT_LOG2 = 5, +}; + +/* Private constants: do not modify. */ +enum tlsf_private +{ +#if defined (TLSF_64BIT) + /* All allocation sizes and addresses are aligned to 8 bytes. */ + ALIGN_SIZE_LOG2 = 3, +#else + /* All allocation sizes and addresses are aligned to 4 bytes. */ + ALIGN_SIZE_LOG2 = 2, +#endif + ALIGN_SIZE = (1 << ALIGN_SIZE_LOG2), + + /* + ** We support allocations of sizes up to (1 << FL_INDEX_MAX) bits. + ** However, because we linearly subdivide the second-level lists, and + ** our minimum size granularity is 4 bytes, it doesn't make sense to + ** create first-level lists for sizes smaller than SL_INDEX_COUNT * 4, + ** or (1 << (SL_INDEX_COUNT_LOG2 + 2)) bytes, as there we will be + ** trying to split size ranges into more slots than we have available. + ** Instead, we calculate the minimum threshold size, and place all + ** blocks below that size into the 0th first-level list. + */ + +#if defined (TLSF_64BIT) + /* + ** TODO: We can increase this to support larger sizes, at the expense + ** of more overhead in the TLSF structure. + */ + FL_INDEX_MAX = 32, +#else + FL_INDEX_MAX = 30, +#endif + SL_INDEX_COUNT = (1 << SL_INDEX_COUNT_LOG2), + FL_INDEX_SHIFT = (SL_INDEX_COUNT_LOG2 + ALIGN_SIZE_LOG2), + FL_INDEX_COUNT = (FL_INDEX_MAX - FL_INDEX_SHIFT + 1), + + SMALL_BLOCK_SIZE = (1 << FL_INDEX_SHIFT), +}; + +/* +** Cast and min/max macros. +*/ + +#define tlsf_cast(t, exp) ((t) (exp)) +#define tlsf_min(a, b) ((a) < (b) ? (a) : (b)) +#define tlsf_max(a, b) ((a) > (b) ? (a) : (b)) + +/* +** Set assert macro, if it has not been provided by the user. +*/ +#if !defined (tlsf_assert) +#define tlsf_assert assert +#endif + +/* +** Static assertion mechanism. +*/ + +#define _tlsf_glue2(x, y) x ## y +#define _tlsf_glue(x, y) _tlsf_glue2(x, y) +#define tlsf_static_assert(exp) \ + typedef char _tlsf_glue(static_assert, __LINE__) [(exp) ? 1 : -1] + +/* This code has been tested on 32- and 64-bit (LP/LLP) architectures. */ +tlsf_static_assert(sizeof(int) * CHAR_BIT == 32); +tlsf_static_assert(sizeof(size_t) * CHAR_BIT >= 32); +tlsf_static_assert(sizeof(size_t) * CHAR_BIT <= 64); + +/* SL_INDEX_COUNT must be <= number of bits in sl_bitmap's storage type. */ +tlsf_static_assert(sizeof(unsigned int) * CHAR_BIT >= SL_INDEX_COUNT); + +/* Ensure we've properly tuned our sizes. */ +tlsf_static_assert(ALIGN_SIZE == SMALL_BLOCK_SIZE / SL_INDEX_COUNT); + +/* +** Data structures and associated constants. +*/ + +/* +** Block header structure. +** +** There are several implementation subtleties involved: +** - The prev_phys_block field is only valid if the previous block is free. +** - The prev_phys_block field is actually stored at the end of the +** previous block. It appears at the beginning of this structure only to +** simplify the implementation. +** - The next_free / prev_free fields are only valid if the block is free. +*/ +typedef struct block_header_t +{ + /* Points to the previous physical block. */ + struct block_header_t* prev_phys_block; + + /* The size of this block, excluding the block header. */ + size_t size; + + /* Next and previous free blocks. */ + struct block_header_t* next_free; + struct block_header_t* prev_free; +} block_header_t; + +/* +** Since block sizes are always at least a multiple of 4, the two least +** significant bits of the size field are used to store the block status: +** - bit 0: whether block is busy or free +** - bit 1: whether previous block is busy or free +*/ +static const size_t block_header_free_bit = 1 << 0; +static const size_t block_header_prev_free_bit = 1 << 1; + +/* +** The size of the block header exposed to used blocks is the size field. +** The prev_phys_block field is stored *inside* the previous free block. +*/ +static const size_t block_header_overhead = sizeof(size_t); + +/* User data starts directly after the size field in a used block. */ +static const size_t block_start_offset = + offsetof(block_header_t, size) + sizeof(size_t); + +/* +** A free block must be large enough to store its header minus the size of +** the prev_phys_block field, and no larger than the number of addressable +** bits for FL_INDEX. +*/ +static const size_t block_size_min = + sizeof(block_header_t) - sizeof(block_header_t*); +static const size_t block_size_max = tlsf_cast(size_t, 1) << FL_INDEX_MAX; + + +/* The TLSF control structure. */ +typedef struct control_t +{ + /* Empty lists point at this block to indicate they are free. */ + block_header_t block_null; + + /* Bitmaps for free lists. */ + unsigned int fl_bitmap; + unsigned int sl_bitmap[FL_INDEX_COUNT]; + + /* Head of free lists. */ + block_header_t* blocks[FL_INDEX_COUNT][SL_INDEX_COUNT]; +} control_t; + +/* A type used for casting when doing pointer arithmetic. */ +typedef ptrdiff_t tlsfptr_t; + +/* +** block_header_t member functions. +*/ + +static size_t block_size(const block_header_t* block) +{ + return block->size & ~(block_header_free_bit | block_header_prev_free_bit); +} + +static void block_set_size(block_header_t* block, size_t size) +{ + const size_t oldsize = block->size; + block->size = size | (oldsize & (block_header_free_bit | block_header_prev_free_bit)); +} + +static int block_is_last(const block_header_t* block) +{ + return block_size(block) == 0; +} + +static int block_is_free(const block_header_t* block) +{ + return tlsf_cast(int, block->size & block_header_free_bit); +} + +static void block_set_free(block_header_t* block) +{ + block->size |= block_header_free_bit; +} + +static void block_set_used(block_header_t* block) +{ + block->size &= ~block_header_free_bit; +} + +static int block_is_prev_free(const block_header_t* block) +{ + return tlsf_cast(int, block->size & block_header_prev_free_bit); +} + +static void block_set_prev_free(block_header_t* block) +{ + block->size |= block_header_prev_free_bit; +} + +static void block_set_prev_used(block_header_t* block) +{ + block->size &= ~block_header_prev_free_bit; +} + +static block_header_t* block_from_ptr(const void* ptr) +{ + return tlsf_cast(block_header_t*, + tlsf_cast(unsigned char*, ptr) - block_start_offset); +} + +static void* block_to_ptr(const block_header_t* block) +{ + return tlsf_cast(void*, + tlsf_cast(unsigned char*, block) + block_start_offset); +} + +/* Return location of next block after block of given size. */ +static block_header_t* offset_to_block(const void* ptr, size_t size) +{ + return tlsf_cast(block_header_t*, tlsf_cast(tlsfptr_t, ptr) + size); +} + +/* Return location of previous block. */ +static block_header_t* block_prev(const block_header_t* block) +{ + tlsf_assert(block_is_prev_free(block) && "previous block must be free"); + return block->prev_phys_block; +} + +/* Return location of next existing block. */ +static block_header_t* block_next(const block_header_t* block) +{ + block_header_t* next = offset_to_block(block_to_ptr(block), + block_size(block) - block_header_overhead); + tlsf_assert(!block_is_last(block)); + return next; +} + +/* Link a new block with its physical neighbor, return the neighbor. */ +static block_header_t* block_link_next(block_header_t* block) +{ + block_header_t* next = block_next(block); + next->prev_phys_block = block; + return next; +} + +static void block_mark_as_free(block_header_t* block) +{ + /* Link the block to the next block, first. */ + block_header_t* next = block_link_next(block); + block_set_prev_free(next); + block_set_free(block); +} + +static void block_mark_as_used(block_header_t* block) +{ + block_header_t* next = block_next(block); + block_set_prev_used(next); + block_set_used(block); +} + +static size_t align_up(size_t x, size_t align) +{ + tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two"); + return (x + (align - 1)) & ~(align - 1); +} + +static size_t align_down(size_t x, size_t align) +{ + tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two"); + return x - (x & (align - 1)); +} + +static void* align_ptr(const void* ptr, size_t align) +{ + const tlsfptr_t aligned = + (tlsf_cast(tlsfptr_t, ptr) + (align - 1)) & ~(align - 1); + tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two"); + return tlsf_cast(void*, aligned); +} + +/* +** Adjust an allocation size to be aligned to word size, and no smaller +** than internal minimum. +*/ +static size_t adjust_request_size(size_t size, size_t align) +{ + size_t adjust = 0; + if (size) + { + const size_t aligned = align_up(size, align); + + /* aligned sized must not exceed block_size_max or we'll go out of bounds on sl_bitmap */ + if (aligned < block_size_max) + { + adjust = tlsf_max(aligned, block_size_min); + } + } + return adjust; +} + +/* +** TLSF utility functions. In most cases, these are direct translations of +** the documentation found in the white paper. +*/ + +static void mapping_insert(size_t size, int* fli, int* sli) +{ + int fl, sl; + if (size < SMALL_BLOCK_SIZE) + { + /* Store small blocks in first list. */ + fl = 0; + sl = tlsf_cast(int, size) / (SMALL_BLOCK_SIZE / SL_INDEX_COUNT); + } + else + { + fl = tlsf_fls_sizet(size); + sl = tlsf_cast(int, size >> (fl - SL_INDEX_COUNT_LOG2)) ^ (1 << SL_INDEX_COUNT_LOG2); + fl -= (FL_INDEX_SHIFT - 1); + } + *fli = fl; + *sli = sl; +} + +/* This version rounds up to the next block size (for allocations) */ +static void mapping_search(size_t size, int* fli, int* sli) +{ + if (size >= SMALL_BLOCK_SIZE) + { + const size_t round = (1 << (tlsf_fls_sizet(size) - SL_INDEX_COUNT_LOG2)) - 1; + size += round; + } + mapping_insert(size, fli, sli); +} + +static block_header_t* search_suitable_block(control_t* control, int* fli, int* sli) +{ + int fl = *fli; + int sl = *sli; + + /* + ** First, search for a block in the list associated with the given + ** fl/sl index. + */ + unsigned int sl_map = control->sl_bitmap[fl] & (~0U << sl); + if (!sl_map) + { + /* No block exists. Search in the next largest first-level list. */ + const unsigned int fl_map = control->fl_bitmap & (~0U << (fl + 1)); + if (!fl_map) + { + /* No free blocks available, memory has been exhausted. */ + return 0; + } + + fl = tlsf_ffs(fl_map); + *fli = fl; + sl_map = control->sl_bitmap[fl]; + } + tlsf_assert(sl_map && "internal error - second level bitmap is null"); + sl = tlsf_ffs(sl_map); + *sli = sl; + + /* Return the first block in the free list. */ + return control->blocks[fl][sl]; +} + +/* Remove a free block from the free list.*/ +static void remove_free_block(control_t* control, block_header_t* block, int fl, int sl) +{ + block_header_t* prev = block->prev_free; + block_header_t* next = block->next_free; + tlsf_assert(prev && "prev_free field can not be null"); + tlsf_assert(next && "next_free field can not be null"); + next->prev_free = prev; + prev->next_free = next; + + /* If this block is the head of the free list, set new head. */ + if (control->blocks[fl][sl] == block) + { + control->blocks[fl][sl] = next; + + /* If the new head is null, clear the bitmap. */ + if (next == &control->block_null) + { + control->sl_bitmap[fl] &= ~(1U << sl); + + /* If the second bitmap is now empty, clear the fl bitmap. */ + if (!control->sl_bitmap[fl]) + { + control->fl_bitmap &= ~(1U << fl); + } + } + } +} + +/* Insert a free block into the free block list. */ +static void insert_free_block(control_t* control, block_header_t* block, int fl, int sl) +{ + block_header_t* current = control->blocks[fl][sl]; + tlsf_assert(current && "free list cannot have a null entry"); + tlsf_assert(block && "cannot insert a null entry into the free list"); + block->next_free = current; + block->prev_free = &control->block_null; + current->prev_free = block; + + tlsf_assert(block_to_ptr(block) == align_ptr(block_to_ptr(block), ALIGN_SIZE) + && "block not aligned properly"); + /* + ** Insert the new block at the head of the list, and mark the first- + ** and second-level bitmaps appropriately. + */ + control->blocks[fl][sl] = block; + control->fl_bitmap |= (1U << fl); + control->sl_bitmap[fl] |= (1U << sl); +} + +/* Remove a given block from the free list. */ +static void block_remove(control_t* control, block_header_t* block) +{ + int fl, sl; + mapping_insert(block_size(block), &fl, &sl); + remove_free_block(control, block, fl, sl); +} + +/* Insert a given block into the free list. */ +static void block_insert(control_t* control, block_header_t* block) +{ + int fl, sl; + mapping_insert(block_size(block), &fl, &sl); + insert_free_block(control, block, fl, sl); +} + +static int block_can_split(block_header_t* block, size_t size) +{ + return block_size(block) >= sizeof(block_header_t) + size; +} + +/* Split a block into two, the second of which is free. */ +static block_header_t* block_split(block_header_t* block, size_t size) +{ + /* Calculate the amount of space left in the remaining block. */ + block_header_t* remaining = + offset_to_block(block_to_ptr(block), size - block_header_overhead); + + const size_t remain_size = block_size(block) - (size + block_header_overhead); + + tlsf_assert(block_to_ptr(remaining) == align_ptr(block_to_ptr(remaining), ALIGN_SIZE) + && "remaining block not aligned properly"); + + tlsf_assert(block_size(block) == remain_size + size + block_header_overhead); + block_set_size(remaining, remain_size); + tlsf_assert(block_size(remaining) >= block_size_min && "block split with invalid size"); + + block_set_size(block, size); + block_mark_as_free(remaining); + + return remaining; +} + +/* Absorb a free block's storage into an adjacent previous free block. */ +static block_header_t* block_absorb(block_header_t* prev, block_header_t* block) +{ + tlsf_assert(!block_is_last(prev) && "previous block can't be last"); + /* Note: Leaves flags untouched. */ + prev->size += block_size(block) + block_header_overhead; + block_link_next(prev); + return prev; +} + +/* Merge a just-freed block with an adjacent previous free block. */ +static block_header_t* block_merge_prev(control_t* control, block_header_t* block) +{ + if (block_is_prev_free(block)) + { + block_header_t* prev = block_prev(block); + tlsf_assert(prev && "prev physical block can't be null"); + tlsf_assert(block_is_free(prev) && "prev block is not free though marked as such"); + block_remove(control, prev); + block = block_absorb(prev, block); + } + + return block; +} + +/* Merge a just-freed block with an adjacent free block. */ +static block_header_t* block_merge_next(control_t* control, block_header_t* block) +{ + block_header_t* next = block_next(block); + tlsf_assert(next && "next physical block can't be null"); + + if (block_is_free(next)) + { + tlsf_assert(!block_is_last(block) && "previous block can't be last"); + block_remove(control, next); + block = block_absorb(block, next); + } + + return block; +} + +/* Trim any trailing block space off the end of a block, return to pool. */ +static void block_trim_free(control_t* control, block_header_t* block, size_t size) +{ + tlsf_assert(block_is_free(block) && "block must be free"); + if (block_can_split(block, size)) + { + block_header_t* remaining_block = block_split(block, size); + block_link_next(block); + block_set_prev_free(remaining_block); + block_insert(control, remaining_block); + } +} + +/* Trim any trailing block space off the end of a used block, return to pool. */ +static void block_trim_used(control_t* control, block_header_t* block, size_t size) +{ + tlsf_assert(!block_is_free(block) && "block must be used"); + if (block_can_split(block, size)) + { + /* If the next block is free, we must coalesce. */ + block_header_t* remaining_block = block_split(block, size); + block_set_prev_used(remaining_block); + + remaining_block = block_merge_next(control, remaining_block); + block_insert(control, remaining_block); + } +} + +static block_header_t* block_trim_free_leading(control_t* control, block_header_t* block, size_t size) +{ + block_header_t* remaining_block = block; + if (block_can_split(block, size)) + { + /* We want the 2nd block. */ + remaining_block = block_split(block, size - block_header_overhead); + block_set_prev_free(remaining_block); + + block_link_next(block); + block_insert(control, block); + } + + return remaining_block; +} + +static block_header_t* block_locate_free(control_t* control, size_t size) +{ + int fl = 0, sl = 0; + block_header_t* block = 0; + + if (size) + { + mapping_search(size, &fl, &sl); + + /* + ** mapping_search can futz with the size, so for excessively large sizes it can sometimes wind up + ** with indices that are off the end of the block array. + ** So, we protect against that here, since this is the only callsite of mapping_search. + ** Note that we don't need to check sl, since it comes from a modulo operation that guarantees it's always in range. + */ + if (fl < FL_INDEX_COUNT) + { + block = search_suitable_block(control, &fl, &sl); + } + } + + if (block) + { + tlsf_assert(block_size(block) >= size); + remove_free_block(control, block, fl, sl); + } + + return block; +} + +static void* block_prepare_used(control_t* control, block_header_t* block, size_t size) +{ + void* p = 0; + if (block) + { + tlsf_assert(size && "size must be non-zero"); + block_trim_free(control, block, size); + block_mark_as_used(block); + p = block_to_ptr(block); + } + return p; +} + +/* Clear structure and point all empty lists at the null block. */ +static void control_construct(control_t* control) +{ + int i, j; + + control->block_null.next_free = &control->block_null; + control->block_null.prev_free = &control->block_null; + + control->fl_bitmap = 0; + for (i = 0; i < FL_INDEX_COUNT; ++i) + { + control->sl_bitmap[i] = 0; + for (j = 0; j < SL_INDEX_COUNT; ++j) + { + control->blocks[i][j] = &control->block_null; + } + } +} + +/* +** Debugging utilities. +*/ + +typedef struct integrity_t +{ + int prev_status; + int status; +} integrity_t; + +#define tlsf_insist(x) { tlsf_assert(x); if (!(x)) { status--; } } + +static void integrity_walker(void* ptr, size_t size, int used, void* user) +{ + block_header_t* block = block_from_ptr(ptr); + integrity_t* integ = tlsf_cast(integrity_t*, user); + const int this_prev_status = block_is_prev_free(block) ? 1 : 0; + const int this_status = block_is_free(block) ? 1 : 0; + const size_t this_block_size = block_size(block); + + int status = 0; + (void)used; + tlsf_insist(integ->prev_status == this_prev_status && "prev status incorrect"); + tlsf_insist(size == this_block_size && "block size incorrect"); + + integ->prev_status = this_status; + integ->status += status; +} + +int tlsf_check(tlsf_t tlsf) +{ + int i, j; + + control_t* control = tlsf_cast(control_t*, tlsf); + int status = 0; + + /* Check that the free lists and bitmaps are accurate. */ + for (i = 0; i < FL_INDEX_COUNT; ++i) + { + for (j = 0; j < SL_INDEX_COUNT; ++j) + { + const int fl_map = control->fl_bitmap & (1U << i); + const int sl_list = control->sl_bitmap[i]; + const int sl_map = sl_list & (1U << j); + const block_header_t* block = control->blocks[i][j]; + + /* Check that first- and second-level lists agree. */ + if (!fl_map) + { + tlsf_insist(!sl_map && "second-level map must be null"); + } + + if (!sl_map) + { + tlsf_insist(block == &control->block_null && "block list must be null"); + continue; + } + + /* Check that there is at least one free block. */ + tlsf_insist(sl_list && "no free blocks in second-level map"); + tlsf_insist(block != &control->block_null && "block should not be null"); + + while (block != &control->block_null) + { + int fli, sli; + tlsf_insist(block_is_free(block) && "block should be free"); + tlsf_insist(!block_is_prev_free(block) && "blocks should have coalesced"); + tlsf_insist(!block_is_free(block_next(block)) && "blocks should have coalesced"); + tlsf_insist(block_is_prev_free(block_next(block)) && "block should be free"); + tlsf_insist(block_size(block) >= block_size_min && "block not minimum size"); + + mapping_insert(block_size(block), &fli, &sli); + tlsf_insist(fli == i && sli == j && "block size indexed in wrong list"); + block = block->next_free; + } + } + } + + return status; +} + +#undef tlsf_insist + +static void default_walker(void* ptr, size_t size, int used, void* user) +{ + (void)user; + printf("\t%p %s size: %x (%p)\n", ptr, used ? "used" : "free", (unsigned int)size, block_from_ptr(ptr)); +} + +void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void* user) +{ + tlsf_walker pool_walker = walker ? walker : default_walker; + block_header_t* block = + offset_to_block(pool, -(int)block_header_overhead); + + while (block && !block_is_last(block)) + { + pool_walker( + block_to_ptr(block), + block_size(block), + !block_is_free(block), + user); + block = block_next(block); + } +} + +size_t tlsf_block_size(void* ptr) +{ + size_t size = 0; + if (ptr) + { + const block_header_t* block = block_from_ptr(ptr); + size = block_size(block); + } + return size; +} + +int tlsf_check_pool(pool_t pool) +{ + /* Check that the blocks are physically correct. */ + integrity_t integ = { 0, 0 }; + tlsf_walk_pool(pool, integrity_walker, &integ); + + return integ.status; +} + +/* +** Size of the TLSF structures in a given memory block passed to +** tlsf_create, equal to the size of a control_t +*/ +size_t tlsf_size(void) +{ + return sizeof(control_t); +} + +size_t tlsf_align_size(void) +{ + return ALIGN_SIZE; +} + +size_t tlsf_block_size_min(void) +{ + return block_size_min; +} + +size_t tlsf_block_size_max(void) +{ + return block_size_max; +} + +/* +** Overhead of the TLSF structures in a given memory block passed to +** tlsf_add_pool, equal to the overhead of a free block and the +** sentinel block. +*/ +size_t tlsf_pool_overhead(void) +{ + return 2 * block_header_overhead; +} + +size_t tlsf_alloc_overhead(void) +{ + return block_header_overhead; +} + +pool_t tlsf_add_pool(tlsf_t tlsf, void* mem, size_t bytes) +{ + block_header_t* block; + block_header_t* next; + + const size_t pool_overhead = tlsf_pool_overhead(); + const size_t pool_bytes = align_down(bytes - pool_overhead, ALIGN_SIZE); + + if (((ptrdiff_t)mem % ALIGN_SIZE) != 0) + { + printf("tlsf_add_pool: Memory must be aligned by %u bytes.\n", + (unsigned int)ALIGN_SIZE); + return 0; + } + + if (pool_bytes < block_size_min || pool_bytes > block_size_max) + { +#if defined (TLSF_64BIT) + printf("tlsf_add_pool: Memory size must be between 0x%x and 0x%x00 bytes.\n", + (unsigned int)(pool_overhead + block_size_min), + (unsigned int)((pool_overhead + block_size_max) / 256)); +#else + printf("tlsf_add_pool: Memory size must be between %u and %u bytes.\n", + (unsigned int)(pool_overhead + block_size_min), + (unsigned int)(pool_overhead + block_size_max)); +#endif + return 0; + } + + /* + ** Create the main free block. Offset the start of the block slightly + ** so that the prev_phys_block field falls outside of the pool - + ** it will never be used. + */ + block = offset_to_block(mem, -(tlsfptr_t)block_header_overhead); + block_set_size(block, pool_bytes); + block_set_free(block); + block_set_prev_used(block); + block_insert(tlsf_cast(control_t*, tlsf), block); + + /* Split the block to create a zero-size sentinel block. */ + next = block_link_next(block); + block_set_size(next, 0); + block_set_used(next); + block_set_prev_free(next); + + return mem; +} + +void tlsf_remove_pool(tlsf_t tlsf, pool_t pool) +{ + control_t* control = tlsf_cast(control_t*, tlsf); + block_header_t* block = offset_to_block(pool, -(int)block_header_overhead); + + int fl = 0, sl = 0; + + tlsf_assert(block_is_free(block) && "block should be free"); + tlsf_assert(!block_is_free(block_next(block)) && "next block should not be free"); + tlsf_assert(block_size(block_next(block)) == 0 && "next block size should be zero"); + + mapping_insert(block_size(block), &fl, &sl); + remove_free_block(control, block, fl, sl); +} + +/* +** TLSF main interface. +*/ + +#if _DEBUG +int test_ffs_fls() +{ + /* Verify ffs/fls work properly. */ + int rv = 0; + rv += (tlsf_ffs(0) == -1) ? 0 : 0x1; + rv += (tlsf_fls(0) == -1) ? 0 : 0x2; + rv += (tlsf_ffs(1) == 0) ? 0 : 0x4; + rv += (tlsf_fls(1) == 0) ? 0 : 0x8; + rv += (tlsf_ffs(0x80000000) == 31) ? 0 : 0x10; + rv += (tlsf_ffs(0x80008000) == 15) ? 0 : 0x20; + rv += (tlsf_fls(0x80000008) == 31) ? 0 : 0x40; + rv += (tlsf_fls(0x7FFFFFFF) == 30) ? 0 : 0x80; + +#if defined (TLSF_64BIT) + rv += (tlsf_fls_sizet(0x80000000) == 31) ? 0 : 0x100; + rv += (tlsf_fls_sizet(0x100000000) == 32) ? 0 : 0x200; + rv += (tlsf_fls_sizet(0xffffffffffffffff) == 63) ? 0 : 0x400; +#endif + + if (rv) + { + printf("test_ffs_fls: %x ffs/fls tests failed.\n", rv); + } + return rv; +} +#endif + +tlsf_t tlsf_create(void* mem) +{ +#if _DEBUG + if (test_ffs_fls()) + { + return 0; + } +#endif + + if (((tlsfptr_t)mem % ALIGN_SIZE) != 0) + { + printf("tlsf_create: Memory must be aligned to %u bytes.\n", + (unsigned int)ALIGN_SIZE); + return 0; + } + + control_construct(tlsf_cast(control_t*, mem)); + + return tlsf_cast(tlsf_t, mem); +} + +tlsf_t tlsf_create_with_pool(void* mem, size_t bytes) +{ + tlsf_t tlsf = tlsf_create(mem); + tlsf_add_pool(tlsf, (char*)mem + tlsf_size(), bytes - tlsf_size()); + return tlsf; +} + +void tlsf_destroy(tlsf_t tlsf) +{ + /* Nothing to do. */ + (void)tlsf; +} + +pool_t tlsf_get_pool(tlsf_t tlsf) +{ + return tlsf_cast(pool_t, (char*)tlsf + tlsf_size()); +} + +void* tlsf_malloc(tlsf_t tlsf, size_t size) +{ + control_t* control = tlsf_cast(control_t*, tlsf); + const size_t adjust = adjust_request_size(size, ALIGN_SIZE); + block_header_t* block = block_locate_free(control, adjust); + return block_prepare_used(control, block, adjust); +} + +void* tlsf_memalign(tlsf_t tlsf, size_t align, size_t size) +{ + control_t* control = tlsf_cast(control_t*, tlsf); + const size_t adjust = adjust_request_size(size, ALIGN_SIZE); + + /* + ** We must allocate an additional minimum block size bytes so that if + ** our free block will leave an alignment gap which is smaller, we can + ** trim a leading free block and release it back to the pool. We must + ** do this because the previous physical block is in use, therefore + ** the prev_phys_block field is not valid, and we can't simply adjust + ** the size of that block. + */ + const size_t gap_minimum = sizeof(block_header_t); + const size_t size_with_gap = adjust_request_size(adjust + align + gap_minimum, align); + + /* + ** If alignment is less than or equals base alignment, we're done. + ** If we requested 0 bytes, return null, as tlsf_malloc(0) does. + */ + const size_t aligned_size = (adjust && align > ALIGN_SIZE) ? size_with_gap : adjust; + + block_header_t* block = block_locate_free(control, aligned_size); + + /* This can't be a static assert. */ + tlsf_assert(sizeof(block_header_t) == block_size_min + block_header_overhead); + + if (block) + { + void* ptr = block_to_ptr(block); + void* aligned = align_ptr(ptr, align); + size_t gap = tlsf_cast(size_t, + tlsf_cast(tlsfptr_t, aligned) - tlsf_cast(tlsfptr_t, ptr)); + + /* If gap size is too small, offset to next aligned boundary. */ + if (gap && gap < gap_minimum) + { + const size_t gap_remain = gap_minimum - gap; + const size_t offset = tlsf_max(gap_remain, align); + const void* next_aligned = tlsf_cast(void*, + tlsf_cast(tlsfptr_t, aligned) + offset); + + aligned = align_ptr(next_aligned, align); + gap = tlsf_cast(size_t, + tlsf_cast(tlsfptr_t, aligned) - tlsf_cast(tlsfptr_t, ptr)); + } + + if (gap) + { + tlsf_assert(gap >= gap_minimum && "gap size too small"); + block = block_trim_free_leading(control, block, gap); + } + } + + return block_prepare_used(control, block, adjust); +} + +void tlsf_free(tlsf_t tlsf, void* ptr) +{ + /* Don't attempt to free a NULL pointer. */ + if (ptr) + { + control_t* control = tlsf_cast(control_t*, tlsf); + block_header_t* block = block_from_ptr(ptr); + tlsf_assert(!block_is_free(block) && "block already marked as free"); + block_mark_as_free(block); + block = block_merge_prev(control, block); + block = block_merge_next(control, block); + block_insert(control, block); + } +} + +/* +** The TLSF block information provides us with enough information to +** provide a reasonably intelligent implementation of realloc, growing or +** shrinking the currently allocated block as required. +** +** This routine handles the somewhat esoteric edge cases of realloc: +** - a non-zero size with a null pointer will behave like malloc +** - a zero size with a non-null pointer will behave like free +** - a request that cannot be satisfied will leave the original buffer +** untouched +** - an extended buffer size will leave the newly-allocated area with +** contents undefined +*/ +void* tlsf_realloc(tlsf_t tlsf, void* ptr, size_t size) +{ + control_t* control = tlsf_cast(control_t*, tlsf); + void* p = 0; + + /* Zero-size requests are treated as free. */ + if (ptr && size == 0) + { + tlsf_free(tlsf, ptr); + } + /* Requests with NULL pointers are treated as malloc. */ + else if (!ptr) + { + p = tlsf_malloc(tlsf, size); + } + else + { + block_header_t* block = block_from_ptr(ptr); + block_header_t* next = block_next(block); + + const size_t cursize = block_size(block); + const size_t combined = cursize + block_size(next) + block_header_overhead; + const size_t adjust = adjust_request_size(size, ALIGN_SIZE); + + tlsf_assert(!block_is_free(block) && "block already marked as free"); + + /* + ** If the next block is used, or when combined with the current + ** block, does not offer enough space, we must reallocate and copy. + */ + if (adjust > cursize && (!block_is_free(next) || adjust > combined)) + { + p = tlsf_malloc(tlsf, size); + if (p) + { + const size_t minsize = tlsf_min(cursize, size); + memcpy(p, ptr, minsize); + tlsf_free(tlsf, ptr); + } + } + else + { + /* Do we need to expand to the next block? */ + if (adjust > cursize) + { + block_merge_next(control, block); + block_mark_as_used(block); + } + + /* Trim the resulting block and return the original pointer. */ + block_trim_used(control, block, adjust); + p = ptr; + } + } + + return p; +} diff --git a/third_party/tlsf/tlsf.h b/third_party/tlsf/tlsf.h new file mode 100644 index 0000000..e6b39f7 --- /dev/null +++ b/third_party/tlsf/tlsf.h @@ -0,0 +1,90 @@ +#ifndef INCLUDED_tlsf +#define INCLUDED_tlsf + +/* +** Two Level Segregated Fit memory allocator, version 3.1. +** Written by Matthew Conte +** http://tlsf.baisoku.org +** +** Based on the original documentation by Miguel Masmano: +** http://www.gii.upv.es/tlsf/main/docs +** +** This implementation was written to the specification +** of the document, therefore no GPL restrictions apply. +** +** Copyright (c) 2006-2016, Matthew Conte +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** * Neither the name of the copyright holder nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL MATTHEW CONTE BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/* tlsf_t: a TLSF structure. Can contain 1 to N pools. */ +/* pool_t: a block of memory that TLSF can manage. */ +typedef void* tlsf_t; +typedef void* pool_t; + +/* Create/destroy a memory pool. */ +tlsf_t tlsf_create(void* mem); +tlsf_t tlsf_create_with_pool(void* mem, size_t bytes); +void tlsf_destroy(tlsf_t tlsf); +pool_t tlsf_get_pool(tlsf_t tlsf); + +/* Add/remove memory pools. */ +pool_t tlsf_add_pool(tlsf_t tlsf, void* mem, size_t bytes); +void tlsf_remove_pool(tlsf_t tlsf, pool_t pool); + +/* malloc/memalign/realloc/free replacements. */ +void* tlsf_malloc(tlsf_t tlsf, size_t bytes); +void* tlsf_memalign(tlsf_t tlsf, size_t align, size_t bytes); +void* tlsf_realloc(tlsf_t tlsf, void* ptr, size_t size); +void tlsf_free(tlsf_t tlsf, void* ptr); + +/* Returns internal block size, not original request size */ +size_t tlsf_block_size(void* ptr); + +/* Overheads/limits of internal structures. */ +size_t tlsf_size(void); +size_t tlsf_align_size(void); +size_t tlsf_block_size_min(void); +size_t tlsf_block_size_max(void); +size_t tlsf_pool_overhead(void); +size_t tlsf_alloc_overhead(void); + +/* Debugging. */ +typedef void (*tlsf_walker)(void* ptr, size_t size, int used, void* user); +void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void* user); +/* Returns nonzero if any internal consistency check fails. */ +int tlsf_check(tlsf_t tlsf); +int tlsf_check_pool(pool_t pool); + +#if defined(__cplusplus) +}; +#endif + +#endif diff --git a/third_party/tlsf/tlsf_silent.h b/third_party/tlsf/tlsf_silent.h new file mode 100644 index 0000000..807a387 --- /dev/null +++ b/third_party/tlsf/tlsf_silent.h @@ -0,0 +1,12 @@ +// Force-included via -include when compiling tlsf.c on M0. +// TLSF's only printf calls are unreachable in our use (bad-arg validation +// in tlsf_create/tlsf_add_pool, and the debug walker callback) -- we +// control the args and never call the walker. Silencing them at compile +// time keeps picolibc's printf and stdio FILE machinery out of the link. +#ifndef TLSF_SILENT_H +#define TLSF_SILENT_H + +static inline int tlsf_silent_printf(const char *fmt, ...) { (void)fmt; return 0; } +#define printf tlsf_silent_printf + +#endif diff --git a/vendor.mk b/vendor.mk new file mode 100644 index 0000000..f910fc5 --- /dev/null +++ b/vendor.mk @@ -0,0 +1,93 @@ +# Bouffalo vendor C deps (tlsf, mbedtls, BL808 M0 wifi/psram). Included via +# platforms.mk so consumers inherit the paths, object lists, compile rules and +# -L/-I without duplicating them. URT_ROOT resolves the trees whether make runs +# from the URT root or a consumer root. OBJDIR comes from the consumer, hence +# the deferred (=) object lists. + +ifneq ($(filter bl808 bl618,$(PLATFORM)),) + +BL_TLSF_DIR := $(URT_ROOT)third_party/tlsf +BL_TLSF_SRCS := $(BL_TLSF_DIR)/tlsf.c + +# rv32 cores (BL618 + BL808 M0) share the BL618 .a; rv64 D0 uses its own. Key +# on ARCH so a defaulted PROCESSOR can't pick the wrong-width archive. +ifeq ($(USE_MBEDTLS),1) + MBEDTLS_INC := $(URT_ROOT)third_party/mbedtls/include + ifeq ($(ARCH),riscv) + MBEDTLS_LIB := $(URT_ROOT)platforms/bl618/lib/libmbedtls.a + else + MBEDTLS_LIB := $(URT_ROOT)platforms/bl808/lib/libmbedtls.a + endif + DFLAGS := $(DFLAGS) -L$(MBEDTLS_LIB) +endif + +ifeq ($(BUILDNAME),bl808-m0) + BL_WIFI_DIR := $(URT_ROOT)platforms/bl808_m0/vendor/wifi + BL_WIFI_INC := $(BL_WIFI_DIR)/include + BL_WIFI_SRCS := $(wildcard $(BL_WIFI_DIR)/src/*.c) + BL_WIFI_LIBS := $(BL_WIFI_DIR)/lib/libwifi.a $(BL_WIFI_DIR)/lib/libbl606p_phyrf.a + DFLAGS := $(DFLAGS) $(addprefix -L,$(BL_WIFI_LIBS)) + + BL_PSRAM_DIR := $(URT_ROOT)platforms/bl808_m0/vendor/psram + BL_PSRAM_INC := $(BL_PSRAM_DIR)/include + BL_PSRAM_SRCS := $(wildcard $(BL_PSRAM_DIR)/src/*.c) +endif + +# BAREMETAL_SPECS routes a bare cross-gcc to picolibc's hosted headers. +ifdef BL_TLSF_DIR + BL_TLSF_OBJS = $(patsubst $(BL_TLSF_DIR)/%.c,$(OBJDIR)/bl_tlsf/%.o,$(BL_TLSF_SRCS)) + BL_TLSF_CFLAGS := $(BAREMETAL_CFLAGS) $(BAREMETAL_SPECS) -ffreestanding -Os -DNDEBUG -fcommon -include $(BL_TLSF_DIR)/tlsf_silent.h +endif + +ifdef BL_WIFI_DIR + BL_WIFI_OBJS = $(patsubst $(BL_WIFI_DIR)/src/%.c,$(OBJDIR)/bl_wifi/%.o,$(BL_WIFI_SRCS)) + # -fshort-enums: libwifi.a uses packed enums; lmac_msg's header is 8 bytes + # only with it -- otherwise the blob reads dest/src at the wrong offsets. + BL_WIFI_CFLAGS := $(BAREMETAL_CFLAGS) $(BAREMETAL_SPECS) -ffreestanding -Os \ + -I$(BL_WIFI_INC) -I$(BL_WIFI_INC)/bl_os_adapter \ + -DCFG_CHIP_BL808 -DCFG_TXDESC=4 -DCFG_STA_MAX=5 \ + -fcommon -fshort-enums +endif + +ifdef BL_PSRAM_DIR + BL_PSRAM_OBJS = $(patsubst $(BL_PSRAM_DIR)/src/%.c,$(OBJDIR)/bl_psram/%.o,$(BL_PSRAM_SRCS)) + BL_PSRAM_CFLAGS := $(BAREMETAL_CFLAGS) $(BAREMETAL_SPECS) -ffreestanding -Os \ + -I$(BL_PSRAM_INC) -DBL808 -DARCH_RISCV -fcommon +endif + +ifdef MBEDTLS_LIB + MBEDTLS_SHIM_SRC := $(URT_SRCDIR)/urt/internal/mbedtls.c + MBEDTLS_OBJS = $(OBJDIR)/mbedtls/$(notdir $(MBEDTLS_SHIM_SRC:.c=.o)) + MBEDTLS_CFLAGS := $(BAREMETAL_CFLAGS) $(BAREMETAL_SPECS) -ffreestanding -Oz \ + -ffunction-sections -fdata-sections \ + -I$(MBEDTLS_INC) -DMBEDTLS_CONFIG_FILE='"mbedtls_config_openwatt.h"' -fcommon +endif + +ifdef BL_TLSF_DIR +$(OBJDIR)/bl_tlsf/%.o: $(BL_TLSF_DIR)/%.c + @mkdir -p $(OBJDIR)/bl_tlsf + $(BAREMETAL_GCC) $(BL_TLSF_CFLAGS) -c -o $@ $< +endif + +ifdef BL_WIFI_DIR +$(OBJDIR)/bl_wifi/%.o: $(BL_WIFI_DIR)/src/%.c + @mkdir -p $(OBJDIR)/bl_wifi + $(BAREMETAL_GCC) $(BL_WIFI_CFLAGS) -c -o $@ $< +endif + +ifdef BL_PSRAM_DIR +$(OBJDIR)/bl_psram/%.o: $(BL_PSRAM_DIR)/src/%.c + @mkdir -p $(OBJDIR)/bl_psram + $(BAREMETAL_GCC) $(BL_PSRAM_CFLAGS) -c -o $@ $< +endif + +ifdef MBEDTLS_LIB +$(OBJDIR)/mbedtls/%.o: $(dir $(MBEDTLS_SHIM_SRC))%.c + @mkdir -p $(OBJDIR)/mbedtls + $(BAREMETAL_GCC) $(MBEDTLS_CFLAGS) -c -o $@ $< +endif + +# Single aggregate for consumers to link; the per-blob lists above are private. +VENDOR_OBJS = $(BL_TLSF_OBJS) $(BL_WIFI_OBJS) $(BL_PSRAM_OBJS) $(MBEDTLS_OBJS) + +endif