dccloader/tools/emulator/shared/dcc_protocol.py
2026-07-21 19:58:13 +07:00

124 lines
No EOL
5.2 KiB
Python

from dataclasses import dataclass
from construct import (
Int32ul,
Int16ul,
Int8ul,
Const,
Hex,
this,
If,
IfThenElse,
Computed,
Rebuild,
Aligned,
PascalString
)
from construct_typed import csfield
from shared.construct_mixins import EnhancedDataclassMixin
@dataclass
class DCCLoaderInfoPacket(EnhancedDataclassMixin):
# Used when the storage device failed to initialize
@dataclass
class Error(EnhancedDataclassMixin):
error_code: int = csfield(Hex(Int32ul))
# Read/Write max buffer size
@dataclass
class BufferInfo(EnhancedDataclassMixin):
read_buffer_size: int = csfield(Int32ul)
write_buffer_size: int = csfield(IfThenElse(this._.dev_type & 0x100, Int32ul, Computed(this.read_buffer_size)))
# Flash decvice info
@dataclass
class MemoryInfo(EnhancedDataclassMixin):
@dataclass
class ExtendParams(EnhancedDataclassMixin):
emmc_num_sectors: int | None = csfield(If(this._._dev_type & 0x10, Int32ul)) # A sector is a 512-bytes block
device_name: str | None = csfield(If(this._._dev_type & 0x80, Aligned(4, PascalString(Int8ul, "ascii"))))
extend_flags: int = csfield(Hex(Rebuild(Int8ul, this._._dev_type & 0xff)))
page_size_log2: int = csfield(Hex(Int8ul))
block_size_log2: int = csfield(Hex(Int8ul))
size_mb_log2: int = csfield(Hex(Int8ul))
_dev_type: int = csfield(Computed(this._.dev_type)) # pyright: ignore[reportAny]
manufacturer_id: int = csfield(Hex(Int16ul))
device_id: int = csfield(Hex(Int16ul))
extend_params: ExtendParams | None = csfield(If((this._dev_type & 3) == 3, ExtendParams.format()))
have_oob: bool = csfield(Computed(lambda x: (x._dev_type & 0xb) in [0x0, 0x3])) # pyright: ignore[reportAny]
dev_magic: bytes = csfield(Const(b"OK"))
dev_type: int = csfield(Hex(Int16ul))
data: Error | BufferInfo | MemoryInfo = csfield(IfThenElse(this.dev_type == 0xffff, Error.format(), IfThenElse(this.dev_type & 4, BufferInfo.format(), MemoryInfo.format())))
@dataclass
class NANDDeviceInfo:
page_size: int
flash_size: int
block_size: int
bits: int
NAND_DEV_IDS = {
0x6e: NANDDeviceInfo(0x100, 0x100000, 0x800, 8),
0x64: NANDDeviceInfo(0x100, 0x200000, 0x800, 8),
0xe8: NANDDeviceInfo(0x100, 0x100000, 0x800, 8),
0xec: NANDDeviceInfo(0x100, 0x100000, 0x800, 8),
0xea: NANDDeviceInfo(0x100, 0x200000, 0x800, 8),
0x6b: NANDDeviceInfo(0x200, 0x400000, 0x2000, 8),
0xe3: NANDDeviceInfo(0x200, 0x400000, 0x2000, 8),
0xe5: NANDDeviceInfo(0x200, 0x400000, 0x2000, 8),
0xd6: NANDDeviceInfo(0x200, 0x800000, 0x2000, 8),
0x39: NANDDeviceInfo(0x200, 0x8000000, 0x4000, 8),
0xe6: NANDDeviceInfo(0x200, 0x800000, 0x2000, 8),
0x49: NANDDeviceInfo(0x200, 0x8000000, 0x4000, 16),
0x59: NANDDeviceInfo(0x200, 0x8000000, 0x4000, 16),
0x33: NANDDeviceInfo(0x200, 0x1000000, 0x4000, 8),
0x73: NANDDeviceInfo(0x200, 0x1000000, 0x4000, 8),
0x43: NANDDeviceInfo(0x200, 0x1000000, 0x4000, 16),
0x53: NANDDeviceInfo(0x200, 0x1000000, 0x4000, 16),
0x35: NANDDeviceInfo(0x200, 0x2000000, 0x4000, 8),
0x75: NANDDeviceInfo(0x200, 0x2000000, 0x4000, 8),
0x45: NANDDeviceInfo(0x200, 0x2000000, 0x4000, 16),
0x55: NANDDeviceInfo(0x200, 0x2000000, 0x4000, 16),
0x36: NANDDeviceInfo(0x200, 0x4000000, 0x4000, 8),
0x76: NANDDeviceInfo(0x200, 0x4000000, 0x4000, 8),
0x46: NANDDeviceInfo(0x200, 0x4000000, 0x4000, 16),
0x56: NANDDeviceInfo(0x200, 0x4000000, 0x4000, 16),
0x78: NANDDeviceInfo(0x200, 0x8000000, 0x4000, 8),
0x79: NANDDeviceInfo(0x200, 0x8000000, 0x4000, 8),
0x72: NANDDeviceInfo(0x200, 0x8000000, 0x4000, 16),
0x74: NANDDeviceInfo(0x200, 0x8000000, 0x4000, 16),
0x71: NANDDeviceInfo(0x200, 0x10000000, 0x4000, 8),
0xa2: NANDDeviceInfo(0x00, 0x4000000, 0x00, 8),
0xb2: NANDDeviceInfo(0x00, 0x4000000, 0x00, 16),
0xc2: NANDDeviceInfo(0x00, 0x4000000, 0x00, 16),
0xf2: NANDDeviceInfo(0x00, 0x4000000, 0x00, 8),
0xa1: NANDDeviceInfo(0x00, 0x8000000, 0x00, 8),
0xb1: NANDDeviceInfo(0x00, 0x8000000, 0x00, 16),
0xc1: NANDDeviceInfo(0x00, 0x8000000, 0x00, 16),
0xf1: NANDDeviceInfo(0x00, 0x8000000, 0x00, 8),
0xaa: NANDDeviceInfo(0x00, 0x10000000, 0x00, 8),
0xba: NANDDeviceInfo(0x00, 0x10000000, 0x00, 16),
0xca: NANDDeviceInfo(0x00, 0x10000000, 0x00, 16),
0xda: NANDDeviceInfo(0x00, 0x10000000, 0x00, 8),
0xac: NANDDeviceInfo(0x00, 0x20000000, 0x00, 8),
0xbc: NANDDeviceInfo(0x00, 0x20000000, 0x00, 16),
0xcc: NANDDeviceInfo(0x00, 0x20000000, 0x00, 16),
0xdc: NANDDeviceInfo(0x00, 0x20000000, 0x00, 8),
0xa3: NANDDeviceInfo(0x00, 0x40000000, 0x00, 8),
0xb3: NANDDeviceInfo(0x00, 0x40000000, 0x00, 16),
0xc3: NANDDeviceInfo(0x00, 0x40000000, 0x00, 16),
0xd3: NANDDeviceInfo(0x00, 0x40000000, 0x00, 8),
0xa5: NANDDeviceInfo(0x00, 0x80000000, 0x00, 8),
0xb5: NANDDeviceInfo(0x00, 0x80000000, 0x00, 16),
0xc5: NANDDeviceInfo(0x00, 0x80000000, 0x00, 16),
0xd5: NANDDeviceInfo(0x00, 0x80000000, 0x00, 8),
0x00: NANDDeviceInfo(0x200, 0x2000000, 0x4000, 8), # Fallback
}
COMP_TYPES = {
"rle": 0x00,
"none": 0x40,
"lz4": 0x80,
"zlib": 0xc0
}